From 692036ce6e8dbdd62e557744683a855a365180e3 Mon Sep 17 00:00:00 2001 From: Muhammad Mahad Date: Mon, 25 Aug 2025 16:45:36 +0500 Subject: [PATCH] Add `rustc-1.49.0` ui test cases Converted the rustc ui testcases with rusttest-to-dg tool into dejagnu format gcc/testsuite/ChangeLog: * rust/rustc/ui/abi/abi-sysv64-arg-passing.rs: New test. * rust/rustc/ui/abi/abi-sysv64-register-usage.rs: New test. * rust/rustc/ui/abi/anon-extern-mod.rs: New test. * rust/rustc/ui/abi/auxiliary/anon-extern-mod-cross-crate-1.rs: New test. * rust/rustc/ui/abi/auxiliary/foreign_lib.rs: New test. * rust/rustc/ui/abi/c-stack-as-value.rs: New test. * rust/rustc/ui/abi/cabi-int-widening.rs: New test. * rust/rustc/ui/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs: New test. * rust/rustc/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs: New test. * rust/rustc/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs: New test. * rust/rustc/ui/abi/duplicated-external-mods.rs: New test. * rust/rustc/ui/abi/extern/auxiliary/extern-crosscrate-source.rs: New test. * rust/rustc/ui/abi/extern/extern-call-deep.rs: New test. * rust/rustc/ui/abi/extern/extern-call-deep2.rs: New test. * rust/rustc/ui/abi/extern/extern-call-direct.rs: New test. * rust/rustc/ui/abi/extern/extern-call-indirect.rs: New test. * rust/rustc/ui/abi/extern/extern-call-scrub.rs: New test. * rust/rustc/ui/abi/extern/extern-crosscrate.rs: New test. * rust/rustc/ui/abi/extern/extern-pass-TwoU16s.rs: New test. * rust/rustc/ui/abi/extern/extern-pass-TwoU32s.rs: New test. * rust/rustc/ui/abi/extern/extern-pass-TwoU64s.rs: New test. * rust/rustc/ui/abi/extern/extern-pass-TwoU8s.rs: New test. * rust/rustc/ui/abi/extern/extern-pass-char.rs: New test. * rust/rustc/ui/abi/extern/extern-pass-double.rs: New test. * rust/rustc/ui/abi/extern/extern-pass-empty.rs: New test. * rust/rustc/ui/abi/extern/extern-pass-u32.rs: New test. * rust/rustc/ui/abi/extern/extern-pass-u64.rs: New test. * rust/rustc/ui/abi/extern/extern-return-TwoU16s.rs: New test. * rust/rustc/ui/abi/extern/extern-return-TwoU32s.rs: New test. * rust/rustc/ui/abi/extern/extern-return-TwoU64s.rs: New test. * rust/rustc/ui/abi/extern/extern-return-TwoU8s.rs: New test. * rust/rustc/ui/abi/foreign/auxiliary/foreign_lib.rs: New test. * rust/rustc/ui/abi/foreign/foreign-call-no-runtime.rs: New test. * rust/rustc/ui/abi/foreign/foreign-dupe.rs: New test. * rust/rustc/ui/abi/foreign/foreign-fn-with-byval.rs: New test. * rust/rustc/ui/abi/foreign/foreign-no-abi.rs: New test. * rust/rustc/ui/abi/invoke-external-foreign.rs: New test. * rust/rustc/ui/abi/issues/issue-62350-sysv-neg-reg-counts.rs: New test. * rust/rustc/ui/abi/lib-defaults.rs: New test. * rust/rustc/ui/abi/mir/mir_codegen_calls_variadic.rs: New test. * rust/rustc/ui/abi/numbers-arithmetic/i128-ffi.rs: New test. * rust/rustc/ui/abi/segfault-no-out-of-stack.rs: New test. * rust/rustc/ui/abi/stack-probes-lto.rs: New test. * rust/rustc/ui/abi/stack-probes.rs: New test. * rust/rustc/ui/abi/statics/static-mut-foreign.rs: New test. * rust/rustc/ui/abi/struct-enums/struct-return.rs: New test. * rust/rustc/ui/abi/union/union-c-interop.rs: New test. * rust/rustc/ui/abi/variadic-ffi.rs: New test. * rust/rustc/ui/absolute-paths-in-nested-use-groups.rs: New test. * rust/rustc/ui/access-mode-in-closures.rs: New test. * rust/rustc/ui/alias-uninit-value.rs: New test. * rust/rustc/ui/align-with-extern-c-fn.rs: New test. * rust/rustc/ui/alignment-gep-tup-like-1.rs: New test. * rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-1.rs: New test. * rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-2.rs: New test. * rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-3.rs: New test. * rust/rustc/ui/alloca-from-derived-tydesc.rs: New test. * rust/rustc/ui/allocator/allocator-args.rs: New test. * rust/rustc/ui/allocator/auxiliary/custom-as-global.rs: New test. * rust/rustc/ui/allocator/auxiliary/custom.rs: New test. * rust/rustc/ui/allocator/auxiliary/helper.rs: New test. * rust/rustc/ui/allocator/auxiliary/system-allocator.rs: New test. * rust/rustc/ui/allocator/auxiliary/system-allocator2.rs: New test. * rust/rustc/ui/allocator/custom-in-block.rs: New test. * rust/rustc/ui/allocator/custom-in-submodule.rs: New test. * rust/rustc/ui/allocator/custom.rs: New test. * rust/rustc/ui/allocator/function-allocator.rs: New test. * rust/rustc/ui/allocator/hygiene.rs: New test. * rust/rustc/ui/allocator/no_std-alloc-error-handler-custom.rs: New test. * rust/rustc/ui/allocator/no_std-alloc-error-handler-default.rs: New test. * rust/rustc/ui/allocator/not-an-allocator.rs: New test. * rust/rustc/ui/allocator/two-allocators.rs: New test. * rust/rustc/ui/allocator/two-allocators2.rs: New test. * rust/rustc/ui/allocator/two-allocators3.rs: New test. * rust/rustc/ui/allocator/xcrate-use.rs: New test. * rust/rustc/ui/allocator/xcrate-use2.rs: New test. * rust/rustc/ui/annotate-snippet/auxiliary/multispan.rs: New test. * rust/rustc/ui/annotate-snippet/missing-type.rs: New test. * rust/rustc/ui/annotate-snippet/multispan.rs: New test. * rust/rustc/ui/anon-params/anon-params-denied-2018.rs: New test. * rust/rustc/ui/anon-params/anon-params-deprecated.rs: New test. * rust/rustc/ui/anon-params/anon-params-edition-hygiene.rs: New test. * rust/rustc/ui/anon-params/auxiliary/anon-params-edition-hygiene.rs: New test. * rust/rustc/ui/anonymous-higher-ranked-lifetime.rs: New test. * rust/rustc/ui/arg-count-mismatch.rs: New test. * rust/rustc/ui/arg-type-mismatch.rs: New test. * rust/rustc/ui/argument-passing.rs: New test. * rust/rustc/ui/array-break-length.rs: New test. * rust/rustc/ui/array-not-vector.rs: New test. * rust/rustc/ui/array-slice-vec/array_const_index-1.rs: New test. * rust/rustc/ui/array-slice-vec/bounds-check-no-overflow.rs: New test. * rust/rustc/ui/array-slice-vec/box-of-array-of-drop-1.rs: New test. * rust/rustc/ui/array-slice-vec/box-of-array-of-drop-2.rs: New test. * rust/rustc/ui/array-slice-vec/cast-in-array-size.rs: New test. * rust/rustc/ui/array-slice-vec/check-static-mut-slices.rs: New test. * rust/rustc/ui/array-slice-vec/check-static-slice.rs: New test. * rust/rustc/ui/array-slice-vec/copy-out-of-array-1.rs: New test. * rust/rustc/ui/array-slice-vec/destructure-array-1.rs: New test. * rust/rustc/ui/array-slice-vec/dst-raw-slice.rs: New test. * rust/rustc/ui/array-slice-vec/empty-mutable-vec.rs: New test. * rust/rustc/ui/array-slice-vec/estr-slice.rs: New test. * rust/rustc/ui/array-slice-vec/evec-slice.rs: New test. * rust/rustc/ui/array-slice-vec/fixed_length_copy.rs: New test. * rust/rustc/ui/array-slice-vec/huge-largest-array.rs: New test. * rust/rustc/ui/array-slice-vec/infer_array_len.rs: New test. * rust/rustc/ui/array-slice-vec/issue-69103-extra-binding-subslice.rs: New test. * rust/rustc/ui/array-slice-vec/ivec-pass-by-value.rs: New test. * rust/rustc/ui/array-slice-vec/match_arr_unknown_len.rs: New test. * rust/rustc/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs: New test. * rust/rustc/ui/array-slice-vec/mutable-alias-vec.rs: New test. * rust/rustc/ui/array-slice-vec/nested-vec-1.rs: New test. * rust/rustc/ui/array-slice-vec/nested-vec-2.rs: New test. * rust/rustc/ui/array-slice-vec/nested-vec-3.rs: New test. * rust/rustc/ui/array-slice-vec/new-style-fixed-length-vec.rs: New test. * rust/rustc/ui/array-slice-vec/rcvr-borrowed-to-slice.rs: New test. * rust/rustc/ui/array-slice-vec/repeated-vector-syntax.rs: New test. * rust/rustc/ui/array-slice-vec/show-boxed-slice.rs: New test. * rust/rustc/ui/array-slice-vec/slice-of-zero-size-elements.rs: New test. * rust/rustc/ui/array-slice-vec/slice-panic-1.rs: New test. * rust/rustc/ui/array-slice-vec/slice-panic-2.rs: New test. * rust/rustc/ui/array-slice-vec/slice-pat-type-mismatches.rs: New test. * rust/rustc/ui/array-slice-vec/slice.rs: New test. * rust/rustc/ui/array-slice-vec/slice_binary_search.rs: New test. * rust/rustc/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs: New test. * rust/rustc/ui/array-slice-vec/subslice-patterns-const-eval-match.rs: New test. * rust/rustc/ui/array-slice-vec/subslice-patterns-const-eval.rs: New test. * rust/rustc/ui/array-slice-vec/variance-vec-covariant.rs: New test. * rust/rustc/ui/array-slice-vec/vec-dst.rs: New test. * rust/rustc/ui/array-slice-vec/vec-fixed-length.rs: New test. * rust/rustc/ui/array-slice-vec/vec-late-init.rs: New test. * rust/rustc/ui/array-slice-vec/vec-macro-no-std.rs: New test. * rust/rustc/ui/array-slice-vec/vec-macro-rvalue-scope.rs: New test. * rust/rustc/ui/array-slice-vec/vec-macro-with-brackets.rs: New test. * rust/rustc/ui/array-slice-vec/vec-macro-with-trailing-comma.rs: New test. * rust/rustc/ui/array-slice-vec/vec-matching-autoslice.rs: New test. * rust/rustc/ui/array-slice-vec/vec-matching-fixed.rs: New test. * rust/rustc/ui/array-slice-vec/vec-matching-fold.rs: New test. * rust/rustc/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs: New test. * rust/rustc/ui/array-slice-vec/vec-matching.rs: New test. * rust/rustc/ui/array-slice-vec/vec-repeat-with-cast.rs: New test. * rust/rustc/ui/array-slice-vec/vec-tail-matching.rs: New test. * rust/rustc/ui/array-slice-vec/vector-no-ann-2.rs: New test. * rust/rustc/ui/array_const_index-0.rs: New test. * rust/rustc/ui/array_const_index-1.rs: New test. * rust/rustc/ui/artificial-block.rs: New test. * rust/rustc/ui/as-precedence.rs: New test. * rust/rustc/ui/asm/bad-arch.rs: New test. * rust/rustc/ui/asm/bad-options.rs: New test. * rust/rustc/ui/asm/bad-reg.rs: New test. * rust/rustc/ui/asm/bad-template.rs: New test. * rust/rustc/ui/asm/const.rs: New test. * rust/rustc/ui/asm/duplicate-options.rs: New test. * rust/rustc/ui/asm/interpolated-idents.rs: New test. * rust/rustc/ui/asm/issue-72570.rs: New test. * rust/rustc/ui/asm/noreturn.rs: New test. * rust/rustc/ui/asm/parse-error.rs: New test. * rust/rustc/ui/asm/rustfix-asm.rs: New test. * rust/rustc/ui/asm/srcloc.rs: New test. * rust/rustc/ui/asm/sym.rs: New test. * rust/rustc/ui/asm/type-check-1.rs: New test. * rust/rustc/ui/asm/type-check-2.rs: New test. * rust/rustc/ui/asm/type-check-3.rs: New test. * rust/rustc/ui/asm/type-check-4.rs: New test. * rust/rustc/ui/assert-eq-trailing-comma.rs: New test. * rust/rustc/ui/assert-escape.rs: New test. * rust/rustc/ui/assert-ne-trailing-comma.rs: New test. * rust/rustc/ui/assign-assign.rs: New test. * rust/rustc/ui/assign-imm-local-twice.rs: New test. * rust/rustc/ui/assignment-operator-unimplemented.rs: New test. * rust/rustc/ui/assoc-inherent.rs: New test. * rust/rustc/ui/assoc-lang-items.rs: New test. * rust/rustc/ui/assoc-oddities-3.rs: New test. * rust/rustc/ui/associated-consts/associated-const-ambiguity-report.rs: New test. * rust/rustc/ui/associated-consts/associated-const-array-len.rs: New test. * rust/rustc/ui/associated-consts/associated-const-const-eval.rs: New test. * rust/rustc/ui/associated-consts/associated-const-cross-crate-const-eval.rs: New test. * rust/rustc/ui/associated-consts/associated-const-cross-crate-defaults.rs: New test. * rust/rustc/ui/associated-consts/associated-const-cross-crate.rs: New test. * rust/rustc/ui/associated-consts/associated-const-dead-code.rs: New test. * rust/rustc/ui/associated-consts/associated-const-generic-obligations.rs: New test. * rust/rustc/ui/associated-consts/associated-const-impl-wrong-lifetime.rs: New test. * rust/rustc/ui/associated-consts/associated-const-impl-wrong-type.rs: New test. * rust/rustc/ui/associated-consts/associated-const-in-global-const.rs: New test. * rust/rustc/ui/associated-consts/associated-const-in-trait.rs: New test. * rust/rustc/ui/associated-consts/associated-const-inherent-impl.rs: New test. * rust/rustc/ui/associated-consts/associated-const-marks-live-code.rs: New test. * rust/rustc/ui/associated-consts/associated-const-match-patterns.rs: New test. * rust/rustc/ui/associated-consts/associated-const-no-item.rs: New test. * rust/rustc/ui/associated-consts/associated-const-outer-ty-refs.rs: New test. * rust/rustc/ui/associated-consts/associated-const-overwrite-default.rs: New test. * rust/rustc/ui/associated-consts/associated-const-private-impl.rs: New test. * rust/rustc/ui/associated-consts/associated-const-public-impl.rs: New test. * rust/rustc/ui/associated-consts/associated-const-range-match-patterns.rs: New test. * rust/rustc/ui/associated-consts/associated-const-resolution-order.rs: New test. * rust/rustc/ui/associated-consts/associated-const-self-type.rs: New test. * rust/rustc/ui/associated-consts/associated-const-trait-bound.rs: New test. * rust/rustc/ui/associated-consts/associated-const-type-parameter-arms.rs: New test. * rust/rustc/ui/associated-consts/associated-const-type-parameter-arrays-2.rs: New test. * rust/rustc/ui/associated-consts/associated-const-type-parameter-arrays.rs: New test. * rust/rustc/ui/associated-consts/associated-const-type-parameters.rs: New test. * rust/rustc/ui/associated-consts/associated-const-ufcs-infer-trait.rs: New test. * rust/rustc/ui/associated-consts/associated-const-use-default.rs: New test. * rust/rustc/ui/associated-consts/associated-const-use-impl-of-same-trait.rs: New test. * rust/rustc/ui/associated-consts/associated-const.rs: New test. * rust/rustc/ui/associated-consts/auxiliary/associated-const-cc-lib.rs: New test. * rust/rustc/ui/associated-consts/auxiliary/empty-struct.rs: New test. * rust/rustc/ui/associated-consts/defaults-cyclic-fail.rs: New test. * rust/rustc/ui/associated-consts/defaults-cyclic-pass.rs: New test. * rust/rustc/ui/associated-consts/defaults-not-assumed-fail.rs: New test. * rust/rustc/ui/associated-consts/defaults-not-assumed-pass.rs: New test. * rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.rs: New test. * rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.rs: New test. * rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.rs: New test. * rust/rustc/ui/associated-consts/issue-63496.rs: New test. * rust/rustc/ui/associated-consts/issue-69020-assoc-const-arith-overflow.rs: New test. * rust/rustc/ui/associated-item-long-paths.rs: New test. * rust/rustc/ui/associated-item/associated-item-duplicate-bounds.rs: New test. * rust/rustc/ui/associated-item/associated-item-duplicate-names-2.rs: New test. * rust/rustc/ui/associated-item/associated-item-duplicate-names-3.rs: New test. * rust/rustc/ui/associated-item/associated-item-duplicate-names.rs: New test. * rust/rustc/ui/associated-item/associated-item-enum.rs: New test. * rust/rustc/ui/associated-item/issue-48027.rs: New test. * rust/rustc/ui/associated-path-shl.rs: New test. * rust/rustc/ui/associated-type-bounds/ambiguous-associated-type.rs: New test. * rust/rustc/ui/associated-type-bounds/assoc-type-bound-through-where-clause.rs: New test. * rust/rustc/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs: New test. * rust/rustc/ui/associated-type-bounds/auxiliary/fn-aux.rs: New test. * rust/rustc/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs: New test. * rust/rustc/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs: New test. * rust/rustc/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs: New test. * rust/rustc/ui/associated-type-bounds/duplicate.rs: New test. * rust/rustc/ui/associated-type-bounds/dyn-impl-trait-type.rs: New test. * rust/rustc/ui/associated-type-bounds/dyn-lcsit.rs: New test. * rust/rustc/ui/associated-type-bounds/dyn-rpit-and-let.rs: New test. * rust/rustc/ui/associated-type-bounds/entails-sized-object-safety.rs: New test. * rust/rustc/ui/associated-type-bounds/enum-bounds.rs: New test. * rust/rustc/ui/associated-type-bounds/fn-apit.rs: New test. * rust/rustc/ui/associated-type-bounds/fn-aux.rs: New test. * rust/rustc/ui/associated-type-bounds/fn-dyn-apit.rs: New test. * rust/rustc/ui/associated-type-bounds/fn-inline.rs: New test. * rust/rustc/ui/associated-type-bounds/fn-where.rs: New test. * rust/rustc/ui/associated-type-bounds/fn-wrap-apit.rs: New test. * rust/rustc/ui/associated-type-bounds/implied-region-constraints.rs: New test. * rust/rustc/ui/associated-type-bounds/inside-adt.rs: New test. * rust/rustc/ui/associated-type-bounds/issue-61752.rs: New test. * rust/rustc/ui/associated-type-bounds/issue-70292.rs: New test. * rust/rustc/ui/associated-type-bounds/issue-71443-1.rs: New test. * rust/rustc/ui/associated-type-bounds/issue-71443-2.rs: New test. * rust/rustc/ui/associated-type-bounds/issue-73818.rs: New test. * rust/rustc/ui/associated-type-bounds/lcsit.rs: New test. * rust/rustc/ui/associated-type-bounds/rpit.rs: New test. * rust/rustc/ui/associated-type-bounds/struct-bounds.rs: New test. * rust/rustc/ui/associated-type-bounds/trait-alias-impl-trait.rs: New test. * rust/rustc/ui/associated-type-bounds/trait-params.rs: New test. * rust/rustc/ui/associated-type-bounds/type-alias.rs: New test. * rust/rustc/ui/associated-type-bounds/union-bounds.rs: New test. * rust/rustc/ui/associated-types/associate-type-bound-normalization.rs: New test. * rust/rustc/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.rs: New test. * rust/rustc/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs: New test. * rust/rustc/ui/associated-types/associated-type-projection-from-supertrait.rs: New test. * rust/rustc/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs: New test. * rust/rustc/ui/associated-types/associated-types-basic.rs: New test. * rust/rustc/ui/associated-types/associated-types-binding-in-trait.rs: New test. * rust/rustc/ui/associated-types/associated-types-binding-in-where-clause.rs: New test. * rust/rustc/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs: New test. * rust/rustc/ui/associated-types/associated-types-bound-ambiguity.rs: New test. * rust/rustc/ui/associated-types/associated-types-bound-failure.rs: New test. * rust/rustc/ui/associated-types/associated-types-bound.rs: New test. * rust/rustc/ui/associated-types/associated-types-cc.rs: New test. * rust/rustc/ui/associated-types/associated-types-coherence-failure.rs: New test. * rust/rustc/ui/associated-types/associated-types-conditional-dispatch.rs: New test. * rust/rustc/ui/associated-types/associated-types-constant-type.rs: New test. * rust/rustc/ui/associated-types/associated-types-doubleendediterator-object.rs: New test. * rust/rustc/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs: New test. * rust/rustc/ui/associated-types/associated-types-duplicate-binding-in-env.rs: New test. * rust/rustc/ui/associated-types/associated-types-enum-field-named.rs: New test. * rust/rustc/ui/associated-types/associated-types-enum-field-numbered.rs: New test. * rust/rustc/ui/associated-types/associated-types-eq-1.rs: New test. * rust/rustc/ui/associated-types/associated-types-eq-2.rs: New test. * rust/rustc/ui/associated-types/associated-types-eq-3.rs: New test. * rust/rustc/ui/associated-types/associated-types-eq-expr-path.rs: New test. * rust/rustc/ui/associated-types/associated-types-eq-hr.rs: New test. * rust/rustc/ui/associated-types/associated-types-eq-obj.rs: New test. * rust/rustc/ui/associated-types/associated-types-for-unimpl-trait.rs: New test. * rust/rustc/ui/associated-types/associated-types-from-supertrait.rs: New test. * rust/rustc/ui/associated-types/associated-types-impl-redirect.rs: New test. * rust/rustc/ui/associated-types/associated-types-in-ambiguous-context.rs: New test. * rust/rustc/ui/associated-types/associated-types-in-bound-type-arg.rs: New test. * rust/rustc/ui/associated-types/associated-types-in-default-method.rs: New test. * rust/rustc/ui/associated-types/associated-types-in-fn.rs: New test. * rust/rustc/ui/associated-types/associated-types-in-impl-generics.rs: New test. * rust/rustc/ui/associated-types/associated-types-in-inherent-method.rs: New test. * rust/rustc/ui/associated-types/associated-types-incomplete-object.rs: New test. * rust/rustc/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs: New test. * rust/rustc/ui/associated-types/associated-types-issue-17359.rs: New test. * rust/rustc/ui/associated-types/associated-types-issue-20220.rs: New test. * rust/rustc/ui/associated-types/associated-types-issue-20346.rs: New test. * rust/rustc/ui/associated-types/associated-types-issue-20371.rs: New test. * rust/rustc/ui/associated-types/associated-types-issue-21212.rs: New test. * rust/rustc/ui/associated-types/associated-types-iterator-binding.rs: New test. * rust/rustc/ui/associated-types/associated-types-method.rs: New test. * rust/rustc/ui/associated-types/associated-types-multiple-types-one-trait.rs: New test. * rust/rustc/ui/associated-types/associated-types-nested-projections.rs: New test. * rust/rustc/ui/associated-types/associated-types-no-suitable-bound.rs: New test. * rust/rustc/ui/associated-types/associated-types-no-suitable-supertrait-2.rs: New test. * rust/rustc/ui/associated-types/associated-types-no-suitable-supertrait.rs: New test. * rust/rustc/ui/associated-types/associated-types-normalize-in-bounds-binding.rs: New test. * rust/rustc/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs: New test. * rust/rustc/ui/associated-types/associated-types-normalize-in-bounds.rs: New test. * rust/rustc/ui/associated-types/associated-types-normalize-unifield-struct.rs: New test. * rust/rustc/ui/associated-types/associated-types-outlives.rs: New test. * rust/rustc/ui/associated-types/associated-types-overridden-binding-2.rs: New test. * rust/rustc/ui/associated-types/associated-types-overridden-binding.rs: New test. * rust/rustc/ui/associated-types/associated-types-overridden-default.rs: New test. * rust/rustc/ui/associated-types/associated-types-path-1.rs: New test. * rust/rustc/ui/associated-types/associated-types-path-2.rs: New test. * rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.rs: New test. * rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs: New test. * rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs: New test. * rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs: New test. * rust/rustc/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs: New test. * rust/rustc/ui/associated-types/associated-types-projection-bound-ambiguity.rs: New test. * rust/rustc/ui/associated-types/associated-types-projection-bound-in-supertraits.rs: New test. * rust/rustc/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs: New test. * rust/rustc/ui/associated-types/associated-types-projection-in-object-type.rs: New test. * rust/rustc/ui/associated-types/associated-types-projection-in-supertrait.rs: New test. * rust/rustc/ui/associated-types/associated-types-projection-in-where-clause.rs: New test. * rust/rustc/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs: New test. * rust/rustc/ui/associated-types/associated-types-projection-to-unrelated-trait.rs: New test. * rust/rustc/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs: New test. * rust/rustc/ui/associated-types/associated-types-ref-from-struct.rs: New test. * rust/rustc/ui/associated-types/associated-types-ref-in-struct-literal.rs: New test. * rust/rustc/ui/associated-types/associated-types-region-erasure-issue-20582.rs: New test. * rust/rustc/ui/associated-types/associated-types-resolve-lifetime.rs: New test. * rust/rustc/ui/associated-types/associated-types-return.rs: New test. * rust/rustc/ui/associated-types/associated-types-simple.rs: New test. * rust/rustc/ui/associated-types/associated-types-stream.rs: New test. * rust/rustc/ui/associated-types/associated-types-struct-field-named.rs: New test. * rust/rustc/ui/associated-types/associated-types-struct-field-numbered.rs: New test. * rust/rustc/ui/associated-types/associated-types-subtyping-1.rs: New test. * rust/rustc/ui/associated-types/associated-types-sugar-path.rs: New test. * rust/rustc/ui/associated-types/associated-types-unconstrained.rs: New test. * rust/rustc/ui/associated-types/associated-types-unsized.rs: New test. * rust/rustc/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs: New test. * rust/rustc/ui/associated-types/auxiliary/associated-types-cc-lib.rs: New test. * rust/rustc/ui/associated-types/bound-lifetime-constrained.rs: New test. * rust/rustc/ui/associated-types/bound-lifetime-in-binding-only.rs: New test. * rust/rustc/ui/associated-types/bound-lifetime-in-return-only.rs: New test. * rust/rustc/ui/associated-types/cache/chrono-scan.rs: New test. * rust/rustc/ui/associated-types/cache/elision.rs: New test. * rust/rustc/ui/associated-types/cache/project-fn-ret-contravariant.rs: New test. * rust/rustc/ui/associated-types/cache/project-fn-ret-invariant.rs: New test. * rust/rustc/ui/associated-types/defaults-cyclic-fail-1.rs: New test. * rust/rustc/ui/associated-types/defaults-cyclic-fail-2.rs: New test. * rust/rustc/ui/associated-types/defaults-cyclic-pass-1.rs: New test. * rust/rustc/ui/associated-types/defaults-cyclic-pass-2.rs: New test. * rust/rustc/ui/associated-types/defaults-in-other-trait-items-pass.rs: New test. * rust/rustc/ui/associated-types/defaults-in-other-trait-items.rs: New test. * rust/rustc/ui/associated-types/defaults-mixed.rs: New test. * rust/rustc/ui/associated-types/defaults-specialization.rs: New test. * rust/rustc/ui/associated-types/defaults-suitability.rs: New test. * rust/rustc/ui/associated-types/defaults-unsound-62211-1.rs: New test. * rust/rustc/ui/associated-types/defaults-unsound-62211-2.rs: New test. * rust/rustc/ui/associated-types/defaults-wf.rs: New test. * rust/rustc/ui/associated-types/higher-ranked-projection.rs: New test. * rust/rustc/ui/associated-types/hr-associated-type-bound-1.rs: New test. * rust/rustc/ui/associated-types/hr-associated-type-bound-2.rs: New test. * rust/rustc/ui/associated-types/hr-associated-type-bound-object.rs: New test. * rust/rustc/ui/associated-types/hr-associated-type-bound-param-1.rs: New test. * rust/rustc/ui/associated-types/hr-associated-type-bound-param-2.rs: New test. * rust/rustc/ui/associated-types/hr-associated-type-bound-param-3.rs: New test. * rust/rustc/ui/associated-types/hr-associated-type-bound-param-4.rs: New test. * rust/rustc/ui/associated-types/hr-associated-type-bound-param-5.rs: New test. * rust/rustc/ui/associated-types/hr-associated-type-bound-param-6.rs: New test. * rust/rustc/ui/associated-types/hr-associated-type-projection-1.rs: New test. * rust/rustc/ui/associated-types/impl-trait-return-missing-constraint.rs: New test. * rust/rustc/ui/associated-types/impl-wf-cycle-1.rs: New test. * rust/rustc/ui/associated-types/impl-wf-cycle-2.rs: New test. * rust/rustc/ui/associated-types/issue-26681.rs: New test. * rust/rustc/ui/associated-types/issue-32350.rs: New test. * rust/rustc/ui/associated-types/issue-36499.rs: New test. * rust/rustc/ui/associated-types/issue-41868.rs: New test. * rust/rustc/ui/associated-types/issue-43924.rs: New test. * rust/rustc/ui/associated-types/issue-44153.rs: New test. * rust/rustc/ui/associated-types/issue-47385.rs: New test. * rust/rustc/ui/associated-types/issue-48010.rs: New test. * rust/rustc/ui/associated-types/issue-54108.rs: New test. * rust/rustc/ui/associated-types/issue-54182-1.rs: New test. * rust/rustc/ui/associated-types/issue-54182-2.rs: New test. * rust/rustc/ui/associated-types/issue-62200.rs: New test. * rust/rustc/ui/associated-types/issue-63593.rs: New test. * rust/rustc/ui/associated-types/issue-64848.rs: New test. * rust/rustc/ui/associated-types/issue-64855-2.rs: New test. * rust/rustc/ui/associated-types/issue-64855.rs: New test. * rust/rustc/ui/associated-types/issue-65774-1.rs: New test. * rust/rustc/ui/associated-types/issue-65774-2.rs: New test. * rust/rustc/ui/associated-types/issue-65934.rs: New test. * rust/rustc/ui/associated-types/issue-72806.rs: New test. * rust/rustc/ui/associated-types/missing-associated-types.rs: New test. * rust/rustc/ui/associated-types/normalization-probe-cycle.rs: New test. * rust/rustc/ui/associated-types/normalize-cycle-in-eval-no-region.rs: New test. * rust/rustc/ui/associated-types/normalize-cycle-in-eval.rs: New test. * rust/rustc/ui/associated-types/object-normalization.rs: New test. * rust/rustc/ui/associated-types/param-env-normalize-cycle.rs: New test. * rust/rustc/ui/associated-types/point-at-type-on-obligation-failure-2.rs: New test. * rust/rustc/ui/associated-types/point-at-type-on-obligation-failure.rs: New test. * rust/rustc/ui/associated-types/trait-with-supertraits-needing-sized-self.rs: New test. * rust/rustc/ui/associated-types/wf-cycle-2.rs: New test. * rust/rustc/ui/associated-types/wf-cycle.rs: New test. * rust/rustc/ui/ast-json/ast-json-ice.rs: New test. * rust/rustc/ui/ast-json/ast-json-noexpand-output.rs: New test. * rust/rustc/ui/ast-json/ast-json-output.rs: New test. * rust/rustc/ui/async-await/argument-patterns.rs: New test. * rust/rustc/ui/async-await/async-assoc-fn-anon-lifetimes.rs: New test. * rust/rustc/ui/async-await/async-await.rs: New test. * rust/rustc/ui/async-await/async-block-control-flow-static-semantics.rs: New test. * rust/rustc/ui/async-await/async-borrowck-escaping-block-error.rs: New test. * rust/rustc/ui/async-await/async-borrowck-escaping-closure-error.rs: New test. * rust/rustc/ui/async-await/async-closure-matches-expr.rs: New test. * rust/rustc/ui/async-await/async-closure.rs: New test. * rust/rustc/ui/async-await/async-error-span.rs: New test. * rust/rustc/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs: New test. * rust/rustc/ui/async-await/async-fn-nonsend.rs: New test. * rust/rustc/ui/async-await/async-fn-path-elision.rs: New test. * rust/rustc/ui/async-await/async-fn-send-uses-nonsend.rs: New test. * rust/rustc/ui/async-await/async-fn-size-moved-locals.rs: New test. * rust/rustc/ui/async-await/async-fn-size-uninit-locals.rs: New test. * rust/rustc/ui/async-await/async-fn-size.rs: New test. * rust/rustc/ui/async-await/async-matches-expr.rs: New test. * rust/rustc/ui/async-await/async-trait-fn.rs: New test. * rust/rustc/ui/async-await/async-unsafe-fn-call-in-safe.rs: New test. * rust/rustc/ui/async-await/async-with-closure.rs: New test. * rust/rustc/ui/async-await/auxiliary/arc_wake.rs: New test. * rust/rustc/ui/async-await/await-keyword/2015-edition-error-various-positions.rs: New test. * rust/rustc/ui/async-await/await-keyword/2015-edition-warning.rs: New test. * rust/rustc/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs: New test. * rust/rustc/ui/async-await/await-keyword/2018-edition-error.rs: New test. * rust/rustc/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs: New test. * rust/rustc/ui/async-await/await-keyword/post_expansion_error.rs: New test. * rust/rustc/ui/async-await/await-unsize.rs: New test. * rust/rustc/ui/async-await/bound-normalization.rs: New test. * rust/rustc/ui/async-await/conditional-and-guaranteed-initialization.rs: New test. * rust/rustc/ui/async-await/dont-print-desugared-async.rs: New test. * rust/rustc/ui/async-await/dont-suggest-missing-await.rs: New test. * rust/rustc/ui/async-await/drop-order/auxiliary/arc_wake.rs: New test. * rust/rustc/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs: New test. * rust/rustc/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs: New test. * rust/rustc/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs: New test. * rust/rustc/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs: New test. * rust/rustc/ui/async-await/drop-order/drop-order-locals-are-hidden.rs: New test. * rust/rustc/ui/async-await/drop-order/drop-order-when-cancelled.rs: New test. * rust/rustc/ui/async-await/edition-deny-async-fns-2015.rs: New test. * rust/rustc/ui/async-await/expansion-in-attrs.rs: New test. * rust/rustc/ui/async-await/feature-async-closure.rs: New test. * rust/rustc/ui/async-await/futures-api.rs: New test. * rust/rustc/ui/async-await/generics-and-bounds.rs: New test. * rust/rustc/ui/async-await/issue-54239-private-type-triggers-lint.rs: New test. * rust/rustc/ui/async-await/issue-60709.rs: New test. * rust/rustc/ui/async-await/issue-61076.rs: New test. * rust/rustc/ui/async-await/issue-61452.rs: New test. * rust/rustc/ui/async-await/issue-61793.rs: New test. * rust/rustc/ui/async-await/issue-61949-self-return-type.rs: New test. * rust/rustc/ui/async-await/issue-62658.rs: New test. * rust/rustc/ui/async-await/issue-63832-await-short-temporary-lifetime-1.rs: New test. * rust/rustc/ui/async-await/issue-63832-await-short-temporary-lifetime.rs: New test. * rust/rustc/ui/async-await/issue-64130-1-sync.rs: New test. * rust/rustc/ui/async-await/issue-64130-2-send.rs: New test. * rust/rustc/ui/async-await/issue-64130-3-other.rs: New test. * rust/rustc/ui/async-await/issue-64130-4-async-move.rs: New test. * rust/rustc/ui/async-await/issue-64130-non-send-future-diags.rs: New test. * rust/rustc/ui/async-await/issue-64391.rs: New test. * rust/rustc/ui/async-await/issue-66312.rs: New test. * rust/rustc/ui/async-await/issue-66387-if-without-else.rs: New test. * rust/rustc/ui/async-await/issue-67252-unnamed-future.rs: New test. * rust/rustc/ui/async-await/issue-67651.rs: New test. * rust/rustc/ui/async-await/issue-67765-async-diagnostic.rs: New test. * rust/rustc/ui/async-await/issue-68112.rs: New test. * rust/rustc/ui/async-await/issue-68523-start.rs: New test. * rust/rustc/ui/async-await/issue-68523.rs: New test. * rust/rustc/ui/async-await/issue-69446-fnmut-capture.rs: New test. * rust/rustc/ui/async-await/issue-70594.rs: New test. * rust/rustc/ui/async-await/issue-70818.rs: New test. * rust/rustc/ui/async-await/issue-70935-complex-spans.rs: New test. * rust/rustc/ui/async-await/issue-71137.rs: New test. * rust/rustc/ui/async-await/issue-72442.rs: New test. * rust/rustc/ui/async-await/issue-72590-type-error-sized.rs: New test. * rust/rustc/ui/async-await/issue-73050.rs: New test. * rust/rustc/ui/async-await/issue-73137.rs: New test. * rust/rustc/ui/async-await/issue-74072-lifetime-name-annotations.rs: New test. * rust/rustc/ui/async-await/issue-74497-lifetime-in-opaque.rs: New test. * rust/rustc/ui/async-await/issues/auxiliary/issue-60674.rs: New test. * rust/rustc/ui/async-await/issues/auxiliary/issue_67893.rs: New test. * rust/rustc/ui/async-await/issues/issue-51719.rs: New test. * rust/rustc/ui/async-await/issues/issue-51751.rs: New test. * rust/rustc/ui/async-await/issues/issue-53249.rs: New test. * rust/rustc/ui/async-await/issues/issue-54752-async-block.rs: New test. * rust/rustc/ui/async-await/issues/issue-54974.rs: New test. * rust/rustc/ui/async-await/issues/issue-55324.rs: New test. * rust/rustc/ui/async-await/issues/issue-55809.rs: New test. * rust/rustc/ui/async-await/issues/issue-58885.rs: New test. * rust/rustc/ui/async-await/issues/issue-59001.rs: New test. * rust/rustc/ui/async-await/issues/issue-59972.rs: New test. * rust/rustc/ui/async-await/issues/issue-60518.rs: New test. * rust/rustc/ui/async-await/issues/issue-60655-latebound-regions.rs: New test. * rust/rustc/ui/async-await/issues/issue-60674.rs: New test. * rust/rustc/ui/async-await/issues/issue-61187.rs: New test. * rust/rustc/ui/async-await/issues/issue-61986.rs: New test. * rust/rustc/ui/async-await/issues/issue-62009-1.rs: New test. * rust/rustc/ui/async-await/issues/issue-62009-2.rs: New test. * rust/rustc/ui/async-await/issues/issue-62097.rs: New test. * rust/rustc/ui/async-await/issues/issue-62517-1.rs: New test. * rust/rustc/ui/async-await/issues/issue-62517-2.rs: New test. * rust/rustc/ui/async-await/issues/issue-63388-1.rs: New test. * rust/rustc/ui/async-await/issues/issue-63388-2.rs: New test. * rust/rustc/ui/async-await/issues/issue-63388-3.rs: New test. * rust/rustc/ui/async-await/issues/issue-63388-4.rs: New test. * rust/rustc/ui/async-await/issues/issue-64391-2.rs: New test. * rust/rustc/ui/async-await/issues/issue-64433.rs: New test. * rust/rustc/ui/async-await/issues/issue-64477-2.rs: New test. * rust/rustc/ui/async-await/issues/issue-64477.rs: New test. * rust/rustc/ui/async-await/issues/issue-64964.rs: New test. * rust/rustc/ui/async-await/issues/issue-65159.rs: New test. * rust/rustc/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs: New test. * rust/rustc/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs: New test. * rust/rustc/ui/async-await/issues/issue-65419/issue-65419-generator-resume-after-completion.rs: New test. * rust/rustc/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs: New test. * rust/rustc/ui/async-await/issues/issue-66695-static-refs.rs: New test. * rust/rustc/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs: New test. * rust/rustc/ui/async-await/issues/issue-67611-static-mut-refs.rs: New test. * rust/rustc/ui/async-await/issues/issue-67893.rs: New test. * rust/rustc/ui/async-await/issues/issue-69307-nested.rs: New test. * rust/rustc/ui/async-await/issues/issue-69307.rs: New test. * rust/rustc/ui/async-await/issues/issue-78654.rs: New test. * rust/rustc/ui/async-await/issues/non-async-enclosing-span.rs: New test. * rust/rustc/ui/async-await/move-part-await-return-rest-struct.rs: New test. * rust/rustc/ui/async-await/move-part-await-return-rest-tuple.rs: New test. * rust/rustc/ui/async-await/multiple-lifetimes/elided.rs: New test. * rust/rustc/ui/async-await/multiple-lifetimes/fn-ptr.rs: New test. * rust/rustc/ui/async-await/multiple-lifetimes/hrtb.rs: New test. * rust/rustc/ui/async-await/multiple-lifetimes/named.rs: New test. * rust/rustc/ui/async-await/multiple-lifetimes/partial-relation.rs: New test. * rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs: New test. * rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs: New test. * rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs: New test. * rust/rustc/ui/async-await/multiple-lifetimes/ret-ref.rs: New test. * rust/rustc/ui/async-await/multiple-lifetimes/variance.rs: New test. * rust/rustc/ui/async-await/mutually-recursive-async-impl-trait-type.rs: New test. * rust/rustc/ui/async-await/nested-in-impl.rs: New test. * rust/rustc/ui/async-await/no-async-const.rs: New test. * rust/rustc/ui/async-await/no-const-async.rs: New test. * rust/rustc/ui/async-await/no-move-across-await-struct.rs: New test. * rust/rustc/ui/async-await/no-move-across-await-tuple.rs: New test. * rust/rustc/ui/async-await/no-non-guaranteed-initialization.rs: New test. * rust/rustc/ui/async-await/no-params-non-move-async-closure.rs: New test. * rust/rustc/ui/async-await/no-std.rs: New test. * rust/rustc/ui/async-await/no-unsafe-async.rs: New test. * rust/rustc/ui/async-await/partial-initialization-across-await.rs: New test. * rust/rustc/ui/async-await/recursive-async-impl-trait-type.rs: New test. * rust/rustc/ui/async-await/return-ty-raw-ptr-coercion.rs: New test. * rust/rustc/ui/async-await/return-ty-unsize-coercion.rs: New test. * rust/rustc/ui/async-await/suggest-missing-await-closure.rs: New test. * rust/rustc/ui/async-await/suggest-missing-await.rs: New test. * rust/rustc/ui/async-await/suggest-switching-edition-on-await.rs: New test. * rust/rustc/ui/async-await/try-on-option-in-async.rs: New test. * rust/rustc/ui/async-await/unreachable-lint-1.rs: New test. * rust/rustc/ui/async-await/unreachable-lint.rs: New test. * rust/rustc/ui/async-await/unresolved_type_param.rs: New test. * rust/rustc/ui/async-await/unused-lifetime.rs: New test. * rust/rustc/ui/atomic-access-bool.rs: New test. * rust/rustc/ui/atomic-alignment.rs: New test. * rust/rustc/ui/atomic-compare_exchange.rs: New test. * rust/rustc/ui/atomic-from-mut-not-available.rs: New test. * rust/rustc/ui/atomic-print.rs: New test. * rust/rustc/ui/attempted-access-non-fatal.rs: New test. * rust/rustc/ui/attr-eq-token-tree.rs: New test. * rust/rustc/ui/attr-main-2.rs: New test. * rust/rustc/ui/attr-main.rs: New test. * rust/rustc/ui/attr-shebang.rs: New test. * rust/rustc/ui/attr-start.rs: New test. * rust/rustc/ui/attr-usage-inline.rs: New test. * rust/rustc/ui/attr-usage-repr.rs: New test. * rust/rustc/ui/attr.rs: New test. * rust/rustc/ui/attribute-with-no-generics-in-parameter-list.rs: New test. * rust/rustc/ui/attributes/attr-before-view-item.rs: New test. * rust/rustc/ui/attributes/attr-before-view-item2.rs: New test. * rust/rustc/ui/attributes/attr-mix-new.rs: New test. * rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-1.rs: New test. * rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-2.rs: New test. * rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-3.rs: New test. * rust/rustc/ui/attributes/auxiliary/key-value-expansion.rs: New test. * rust/rustc/ui/attributes/class-attributes-1.rs: New test. * rust/rustc/ui/attributes/class-attributes-2.rs: New test. * rust/rustc/ui/attributes/field-attributes-vis-unresolved.rs: New test. * rust/rustc/ui/attributes/item-attributes.rs: New test. * rust/rustc/ui/attributes/key-value-expansion.rs: New test. * rust/rustc/ui/attributes/method-attributes.rs: New test. * rust/rustc/ui/attributes/multiple-invalid.rs: New test. * rust/rustc/ui/attributes/nonterminal-expansion.rs: New test. * rust/rustc/ui/attributes/obsolete-attr.rs: New test. * rust/rustc/ui/attributes/register-attr-tool-fail.rs: New test. * rust/rustc/ui/attributes/register-attr-tool-import.rs: New test. * rust/rustc/ui/attributes/register-attr-tool-prelude.rs: New test. * rust/rustc/ui/attributes/register-attr-tool-unused.rs: New test. * rust/rustc/ui/attributes/register-attr-tool.rs: New test. * rust/rustc/ui/attributes/unknown-attr.rs: New test. * rust/rustc/ui/attributes/unnamed-field-attributes-dup.rs: New test. * rust/rustc/ui/attributes/unnamed-field-attributes-vis.rs: New test. * rust/rustc/ui/attributes/unnamed-field-attributes.rs: New test. * rust/rustc/ui/attributes/variant-attributes.rs: New test. * rust/rustc/ui/attrs-resolution-errors.rs: New test. * rust/rustc/ui/attrs-resolution.rs: New test. * rust/rustc/ui/augmented-assignments-feature-gate-cross.rs: New test. * rust/rustc/ui/augmented-assignments-feature-gate.rs: New test. * rust/rustc/ui/augmented-assignments-rpass.rs: New test. * rust/rustc/ui/augmented-assignments.rs: New test. * rust/rustc/ui/auto-instantiate.rs: New test. * rust/rustc/ui/auto-ref-slice-plus-ref.rs: New test. * rust/rustc/ui/auto-traits/auto-is-contextual.rs: New test. * rust/rustc/ui/auto-traits/auto-trait-projection-recursion.rs: New test. * rust/rustc/ui/auto-traits/auto-trait-validation.rs: New test. * rust/rustc/ui/auto-traits/auto-traits.rs: New test. * rust/rustc/ui/auto-traits/issue-23080-2.rs: New test. * rust/rustc/ui/auto-traits/issue-23080.rs: New test. * rust/rustc/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs: New test. * rust/rustc/ui/auto-traits/typeck-auto-trait-no-supertraits.rs: New test. * rust/rustc/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.rs: New test. * rust/rustc/ui/auto-traits/typeck-default-trait-impl-constituent-types.rs: New test. * rust/rustc/ui/auto-traits/typeck-default-trait-impl-negation.rs: New test. * rust/rustc/ui/auto-traits/typeck-default-trait-impl-precedence.rs: New test. * rust/rustc/ui/autobind.rs: New test. * rust/rustc/ui/autoderef-full-lval.rs: New test. * rust/rustc/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs: New test. * rust/rustc/ui/autoref-autoderef/auto-ref-sliceable.rs: New test. * rust/rustc/ui/autoref-autoderef/auto-ref.rs: New test. * rust/rustc/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs: New test. * rust/rustc/ui/autoref-autoderef/autoderef-method-on-trait.rs: New test. * rust/rustc/ui/autoref-autoderef/autoderef-method-priority.rs: New test. * rust/rustc/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs: New test. * rust/rustc/ui/autoref-autoderef/autoderef-method-twice.rs: New test. * rust/rustc/ui/autoref-autoderef/autoderef-method.rs: New test. * rust/rustc/ui/autoref-autoderef/autoderef-privacy.rs: New test. * rust/rustc/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs: New test. * rust/rustc/ui/auxiliary/augmented_assignments.rs: New test. * rust/rustc/ui/auxiliary/blind-item-mixed-crate-use-item-foo.rs: New test. * rust/rustc/ui/auxiliary/blind-item-mixed-crate-use-item-foo2.rs: New test. * rust/rustc/ui/auxiliary/changing-crates-a1.rs: New test. * rust/rustc/ui/auxiliary/changing-crates-a2.rs: New test. * rust/rustc/ui/auxiliary/changing-crates-b.rs: New test. * rust/rustc/ui/auxiliary/check_static_recursion_foreign_helper.rs: New test. * rust/rustc/ui/auxiliary/cond_plugin.rs: New test. * rust/rustc/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs: New test. * rust/rustc/ui/auxiliary/debuginfo-lto-aux.rs: New test. * rust/rustc/ui/auxiliary/default-ty-param-cross-crate-crate.rs: New test. * rust/rustc/ui/auxiliary/define-macro.rs: New test. * rust/rustc/ui/auxiliary/edition-kw-macro-2015.rs: New test. * rust/rustc/ui/auxiliary/edition-kw-macro-2018.rs: New test. * rust/rustc/ui/auxiliary/empty-struct.rs: New test. * rust/rustc/ui/auxiliary/extern-prelude-vec.rs: New test. * rust/rustc/ui/auxiliary/extern-prelude.rs: New test. * rust/rustc/ui/auxiliary/extern-statics.rs: New test. * rust/rustc/ui/auxiliary/hello_macro.rs: New test. * rust/rustc/ui/auxiliary/impl_privacy_xc_1.rs: New test. * rust/rustc/ui/auxiliary/impl_privacy_xc_2.rs: New test. * rust/rustc/ui/auxiliary/inline_dtor.rs: New test. * rust/rustc/ui/auxiliary/inner_static.rs: New test. * rust/rustc/ui/auxiliary/issue-72470-lib.rs: New test. * rust/rustc/ui/auxiliary/issue-76387.rs: New test. * rust/rustc/ui/auxiliary/kinds_in_metadata.rs: New test. * rust/rustc/ui/auxiliary/link-cfg-works-transitive-dylib.rs: New test. * rust/rustc/ui/auxiliary/link-cfg-works-transitive-rlib.rs: New test. * rust/rustc/ui/auxiliary/linkage1.rs: New test. * rust/rustc/ui/auxiliary/llvm_pr32379.rs: New test. * rust/rustc/ui/auxiliary/lto-duplicate-symbols1.rs: New test. * rust/rustc/ui/auxiliary/lto-duplicate-symbols2.rs: New test. * rust/rustc/ui/auxiliary/lto-rustc-loads-linker-plugin.rs: New test. * rust/rustc/ui/auxiliary/msvc-data-only-lib.rs: New test. * rust/rustc/ui/auxiliary/nested_item.rs: New test. * rust/rustc/ui/auxiliary/noexporttypelib.rs: New test. * rust/rustc/ui/auxiliary/orphan-check-diagnostics.rs: New test. * rust/rustc/ui/auxiliary/proc_macro_def.rs: New test. * rust/rustc/ui/auxiliary/pub-and-stability.rs: New test. * rust/rustc/ui/auxiliary/reachable-unnameable-items.rs: New test. * rust/rustc/ui/auxiliary/reexport-should-still-link.rs: New test. * rust/rustc/ui/auxiliary/removing-extern-crate.rs: New test. * rust/rustc/ui/auxiliary/rmeta-meta.rs: New test. * rust/rustc/ui/auxiliary/rmeta-rlib-rpass.rs: New test. * rust/rustc/ui/auxiliary/rmeta-rlib.rs: New test. * rust/rustc/ui/auxiliary/rmeta-rmeta.rs: New test. * rust/rustc/ui/auxiliary/rustc-rust-log-aux.rs: New test. * rust/rustc/ui/auxiliary/stability-cfg2.rs: New test. * rust/rustc/ui/auxiliary/svh-a-base.rs: New test. * rust/rustc/ui/auxiliary/svh-b.rs: New test. * rust/rustc/ui/auxiliary/trait_superkinds_in_metadata.rs: New test. * rust/rustc/ui/auxiliary/typeid-intrinsic-aux1.rs: New test. * rust/rustc/ui/auxiliary/typeid-intrinsic-aux2.rs: New test. * rust/rustc/ui/auxiliary/using-target-feature-unstable.rs: New test. * rust/rustc/ui/auxiliary/weak-lang-items.rs: New test. * rust/rustc/ui/auxiliary/xc-private-method-lib.rs: New test. * rust/rustc/ui/backtrace-debuginfo-aux.rs: New test. * rust/rustc/ui/backtrace-debuginfo.rs: New test. * rust/rustc/ui/backtrace.rs: New test. * rust/rustc/ui/bad/bad-const-type.rs: New test. * rust/rustc/ui/bad/bad-crate-name.rs: New test. * rust/rustc/ui/bad/bad-env-capture.rs: New test. * rust/rustc/ui/bad/bad-env-capture2.rs: New test. * rust/rustc/ui/bad/bad-env-capture3.rs: New test. * rust/rustc/ui/bad/bad-expr-lhs.rs: New test. * rust/rustc/ui/bad/bad-expr-path.rs: New test. * rust/rustc/ui/bad/bad-expr-path2.rs: New test. * rust/rustc/ui/bad/bad-extern-link-attrs.rs: New test. * rust/rustc/ui/bad/bad-intrinsic-monomorphization.rs: New test. * rust/rustc/ui/bad/bad-lint-cap.rs: New test. * rust/rustc/ui/bad/bad-lint-cap2.rs: New test. * rust/rustc/ui/bad/bad-lint-cap3.rs: New test. * rust/rustc/ui/bad/bad-main.rs: New test. * rust/rustc/ui/bad/bad-method-typaram-kind.rs: New test. * rust/rustc/ui/bad/bad-mid-path-type-params.rs: New test. * rust/rustc/ui/bad/bad-module.rs: New test. * rust/rustc/ui/bad/bad-sized.rs: New test. * rust/rustc/ui/bad/bad-type-env-capture.rs: New test. * rust/rustc/ui/bare-fn-implements-fn-mut.rs: New test. * rust/rustc/ui/bare-static-string.rs: New test. * rust/rustc/ui/bastion-of-the-turbofish.rs: New test. * rust/rustc/ui/bench/issue-32062.rs: New test. * rust/rustc/ui/big-literals.rs: New test. * rust/rustc/ui/binary-minus-without-space.rs: New test. * rust/rustc/ui/binary-op-on-double-ref.rs: New test. * rust/rustc/ui/bind-by-move.rs: New test. * rust/rustc/ui/binding/ambiguity-item.rs: New test. * rust/rustc/ui/binding/bind-field-short-with-modifiers.rs: New test. * rust/rustc/ui/binding/borrowed-ptr-pattern-2.rs: New test. * rust/rustc/ui/binding/borrowed-ptr-pattern-3.rs: New test. * rust/rustc/ui/binding/borrowed-ptr-pattern-infallible.rs: New test. * rust/rustc/ui/binding/borrowed-ptr-pattern-option.rs: New test. * rust/rustc/ui/binding/borrowed-ptr-pattern.rs: New test. * rust/rustc/ui/binding/const-param.rs: New test. * rust/rustc/ui/binding/empty-types-in-patterns.rs: New test. * rust/rustc/ui/binding/exhaustive-bool-match-sanity.rs: New test. * rust/rustc/ui/binding/expr-match-generic-unique1.rs: New test. * rust/rustc/ui/binding/expr-match-generic-unique2.rs: New test. * rust/rustc/ui/binding/expr-match-generic.rs: New test. * rust/rustc/ui/binding/expr-match-panic-all.rs: New test. * rust/rustc/ui/binding/expr-match-panic.rs: New test. * rust/rustc/ui/binding/expr-match-unique.rs: New test. * rust/rustc/ui/binding/expr-match.rs: New test. * rust/rustc/ui/binding/fat-arrow-match.rs: New test. * rust/rustc/ui/binding/fn-arg-incomplete-pattern-drop-order.rs: New test. * rust/rustc/ui/binding/fn-pattern-expected-type-2.rs: New test. * rust/rustc/ui/binding/fn-pattern-expected-type.rs: New test. * rust/rustc/ui/binding/func-arg-incomplete-pattern.rs: New test. * rust/rustc/ui/binding/func-arg-ref-pattern.rs: New test. * rust/rustc/ui/binding/func-arg-wild-pattern.rs: New test. * rust/rustc/ui/binding/if-let.rs: New test. * rust/rustc/ui/binding/inconsistent-lifetime-mismatch.rs: New test. * rust/rustc/ui/binding/inferred-suffix-in-pattern-range.rs: New test. * rust/rustc/ui/binding/irrefutable-slice-patterns.rs: New test. * rust/rustc/ui/binding/issue-53114-borrow-checks.rs: New test. * rust/rustc/ui/binding/issue-53114-safety-checks.rs: New test. * rust/rustc/ui/binding/let-assignability.rs: New test. * rust/rustc/ui/binding/let-destruct-ref.rs: New test. * rust/rustc/ui/binding/let-var-hygiene.rs: New test. * rust/rustc/ui/binding/match-arm-statics.rs: New test. * rust/rustc/ui/binding/match-beginning-vert.rs: New test. * rust/rustc/ui/binding/match-borrowed_str.rs: New test. * rust/rustc/ui/binding/match-bot-2.rs: New test. * rust/rustc/ui/binding/match-bot.rs: New test. * rust/rustc/ui/binding/match-byte-array-patterns.rs: New test. * rust/rustc/ui/binding/match-enum-struct-0.rs: New test. * rust/rustc/ui/binding/match-enum-struct-1.rs: New test. * rust/rustc/ui/binding/match-implicit-copy-unique.rs: New test. * rust/rustc/ui/binding/match-in-macro.rs: New test. * rust/rustc/ui/binding/match-join.rs: New test. * rust/rustc/ui/binding/match-larger-const.rs: New test. * rust/rustc/ui/binding/match-naked-record-expr.rs: New test. * rust/rustc/ui/binding/match-naked-record.rs: New test. * rust/rustc/ui/binding/match-path.rs: New test. * rust/rustc/ui/binding/match-pattern-bindings.rs: New test. * rust/rustc/ui/binding/match-pattern-lit.rs: New test. * rust/rustc/ui/binding/match-pattern-no-type-params.rs: New test. * rust/rustc/ui/binding/match-pattern-simple.rs: New test. * rust/rustc/ui/binding/match-phi.rs: New test. * rust/rustc/ui/binding/match-pipe-binding.rs: New test. * rust/rustc/ui/binding/match-range-infer.rs: New test. * rust/rustc/ui/binding/match-range-static.rs: New test. * rust/rustc/ui/binding/match-range.rs: New test. * rust/rustc/ui/binding/match-reassign.rs: New test. * rust/rustc/ui/binding/match-ref-binding-in-guard-3256.rs: New test. * rust/rustc/ui/binding/match-ref-binding-mut-option.rs: New test. * rust/rustc/ui/binding/match-ref-binding-mut.rs: New test. * rust/rustc/ui/binding/match-ref-binding.rs: New test. * rust/rustc/ui/binding/match-ref-unsized.rs: New test. * rust/rustc/ui/binding/match-str.rs: New test. * rust/rustc/ui/binding/match-struct-0.rs: New test. * rust/rustc/ui/binding/match-tag.rs: New test. * rust/rustc/ui/binding/match-unique-bind.rs: New test. * rust/rustc/ui/binding/match-unsized.rs: New test. * rust/rustc/ui/binding/match-value-binding-in-guard-3291.rs: New test. * rust/rustc/ui/binding/match-var-hygiene.rs: New test. * rust/rustc/ui/binding/match-vec-alternatives.rs: New test. * rust/rustc/ui/binding/match-vec-rvalue.rs: New test. * rust/rustc/ui/binding/match-with-ret-arm.rs: New test. * rust/rustc/ui/binding/multi-let.rs: New test. * rust/rustc/ui/binding/mut-in-ident-patterns.rs: New test. * rust/rustc/ui/binding/nested-matchs.rs: New test. * rust/rustc/ui/binding/nested-pattern.rs: New test. * rust/rustc/ui/binding/nil-pattern.rs: New test. * rust/rustc/ui/binding/nullary-or-pattern.rs: New test. * rust/rustc/ui/binding/optional_comma_in_match_arm.rs: New test. * rust/rustc/ui/binding/or-pattern.rs: New test. * rust/rustc/ui/binding/order-drop-with-match.rs: New test. * rust/rustc/ui/binding/pat-ranges.rs: New test. * rust/rustc/ui/binding/pat-tuple-1.rs: New test. * rust/rustc/ui/binding/pat-tuple-2.rs: New test. * rust/rustc/ui/binding/pat-tuple-3.rs: New test. * rust/rustc/ui/binding/pat-tuple-4.rs: New test. * rust/rustc/ui/binding/pat-tuple-5.rs: New test. * rust/rustc/ui/binding/pat-tuple-6.rs: New test. * rust/rustc/ui/binding/pat-tuple-7.rs: New test. * rust/rustc/ui/binding/pattern-bound-var-in-for-each.rs: New test. * rust/rustc/ui/binding/pattern-in-closure.rs: New test. * rust/rustc/ui/binding/range-inclusive-pattern-precedence.rs: New test. * rust/rustc/ui/binding/simple-generic-match.rs: New test. * rust/rustc/ui/binding/use-uninit-match.rs: New test. * rust/rustc/ui/binding/use-uninit-match2.rs: New test. * rust/rustc/ui/binding/zero_sized_subslice_match.rs: New test. * rust/rustc/ui/binop/binop-bitxor-str.rs: New test. * rust/rustc/ui/binop/binop-consume-args.rs: New test. * rust/rustc/ui/binop/binop-fail-3.rs: New test. * rust/rustc/ui/binop/binop-logic-float.rs: New test. * rust/rustc/ui/binop/binop-logic-int.rs: New test. * rust/rustc/ui/binop/binop-move-semantics.rs: New test. * rust/rustc/ui/binop/binop-mul-bool.rs: New test. * rust/rustc/ui/binop/binop-mul-i32-f32.rs: New test. * rust/rustc/ui/binop/binop-panic.rs: New test. * rust/rustc/ui/binop/binop-typeck.rs: New test. * rust/rustc/ui/binops-issue-22743.rs: New test. * rust/rustc/ui/binops.rs: New test. * rust/rustc/ui/bitwise.rs: New test. * rust/rustc/ui/blind-item-local-shadow.rs: New test. * rust/rustc/ui/blind-item-mixed-crate-use-item.rs: New test. * rust/rustc/ui/blind-item-mixed-use-item.rs: New test. * rust/rustc/ui/blind/blind-item-block-item-shadow.rs: New test. * rust/rustc/ui/blind/blind-item-block-middle.rs: New test. * rust/rustc/ui/blind/blind-item-item-shadow.rs: New test. * rust/rustc/ui/block-arg-call-as.rs: New test. * rust/rustc/ui/block-arg.rs: New test. * rust/rustc/ui/block-explicit-types.rs: New test. * rust/rustc/ui/block-expr-precedence.rs: New test. * rust/rustc/ui/block-expression-remove-semicolon.rs: New test. * rust/rustc/ui/block-fn-coerce.rs: New test. * rust/rustc/ui/block-iter-1.rs: New test. * rust/rustc/ui/block-iter-2.rs: New test. * rust/rustc/ui/block-result/block-must-not-have-result-do.rs: New test. * rust/rustc/ui/block-result/block-must-not-have-result-res.rs: New test. * rust/rustc/ui/block-result/block-must-not-have-result-while.rs: New test. * rust/rustc/ui/block-result/consider-removing-last-semi.rs: New test. * rust/rustc/ui/block-result/issue-11714.rs: New test. * rust/rustc/ui/block-result/issue-13428.rs: New test. * rust/rustc/ui/block-result/issue-13624.rs: New test. * rust/rustc/ui/block-result/issue-20862.rs: New test. * rust/rustc/ui/block-result/issue-22645.rs: New test. * rust/rustc/ui/block-result/issue-3563.rs: New test. * rust/rustc/ui/block-result/issue-5500.rs: New test. * rust/rustc/ui/block-result/unexpected-return-on-unit.rs: New test. * rust/rustc/ui/bogus-tag.rs: New test. * rust/rustc/ui/bool-not.rs: New test. * rust/rustc/ui/bool.rs: New test. * rust/rustc/ui/borrow-by-val-method-receiver.rs: New test. * rust/rustc/ui/borrowck/assign-never-type.rs: New test. * rust/rustc/ui/borrowck/assign_mutable_fields.rs: New test. * rust/rustc/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs: New test. * rust/rustc/ui/borrowck/borrow-immutable-upvar-mutation-impl-trait.rs: New test. * rust/rustc/ui/borrowck/borrow-immutable-upvar-mutation.rs: New test. * rust/rustc/ui/borrowck/borrow-raw-address-of-borrowed.rs: New test. * rust/rustc/ui/borrowck/borrow-raw-address-of-deref-mutability-ok.rs: New test. * rust/rustc/ui/borrowck/borrow-raw-address-of-deref-mutability.rs: New test. * rust/rustc/ui/borrowck/borrow-raw-address-of-mutability-ok.rs: New test. * rust/rustc/ui/borrowck/borrow-raw-address-of-mutability.rs: New test. * rust/rustc/ui/borrowck/borrow-tuple-fields.rs: New test. * rust/rustc/ui/borrowck/borrowck-access-permissions.rs: New test. * rust/rustc/ui/borrowck/borrowck-and-init.rs: New test. * rust/rustc/ui/borrowck/borrowck-anon-fields-struct.rs: New test. * rust/rustc/ui/borrowck/borrowck-anon-fields-tuple.rs: New test. * rust/rustc/ui/borrowck/borrowck-anon-fields-variant.rs: New test. * rust/rustc/ui/borrowck/borrowck-argument.rs: New test. * rust/rustc/ui/borrowck/borrowck-asm.rs: New test. * rust/rustc/ui/borrowck/borrowck-assign-comp-idx.rs: New test. * rust/rustc/ui/borrowck/borrowck-assign-comp.rs: New test. * rust/rustc/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.rs: New test. * rust/rustc/ui/borrowck/borrowck-assign-to-andmut-in-borrowed-loc.rs: New test. * rust/rustc/ui/borrowck/borrowck-assign-to-constants.rs: New test. * rust/rustc/ui/borrowck/borrowck-assign-to-subfield.rs: New test. * rust/rustc/ui/borrowck/borrowck-assignment-to-static-mut.rs: New test. * rust/rustc/ui/borrowck/borrowck-auto-mut-ref-to-immut-var.rs: New test. * rust/rustc/ui/borrowck/borrowck-autoref-3261.rs: New test. * rust/rustc/ui/borrowck/borrowck-bad-nested-calls-free.rs: New test. * rust/rustc/ui/borrowck/borrowck-bad-nested-calls-move.rs: New test. * rust/rustc/ui/borrowck/borrowck-binding-mutbl.rs: New test. * rust/rustc/ui/borrowck/borrowck-block-unint.rs: New test. * rust/rustc/ui/borrowck/borrowck-borrow-from-expr-block.rs: New test. * rust/rustc/ui/borrowck/borrowck-borrow-from-owned-ptr.rs: New test. * rust/rustc/ui/borrowck/borrowck-borrow-from-stack-variable.rs: New test. * rust/rustc/ui/borrowck/borrowck-borrow-from-temporary.rs: New test. * rust/rustc/ui/borrowck/borrowck-borrow-immut-deref-of-box-as-mut.rs: New test. * rust/rustc/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs: New test. * rust/rustc/ui/borrowck/borrowck-borrow-mut-object-twice.rs: New test. * rust/rustc/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs: New test. * rust/rustc/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs: New test. * rust/rustc/ui/borrowck/borrowck-borrow-overloaded-deref.rs: New test. * rust/rustc/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.rs: New test. * rust/rustc/ui/borrowck/borrowck-borrowed-uniq-rvalue.rs: New test. * rust/rustc/ui/borrowck/borrowck-box-sensitivity.rs: New test. * rust/rustc/ui/borrowck/borrowck-break-uninit-2.rs: New test. * rust/rustc/ui/borrowck/borrowck-break-uninit.rs: New test. * rust/rustc/ui/borrowck/borrowck-closures-mut-and-imm.rs: New test. * rust/rustc/ui/borrowck/borrowck-closures-mut-of-imm.rs: New test. * rust/rustc/ui/borrowck/borrowck-closures-mut-of-mut.rs: New test. * rust/rustc/ui/borrowck/borrowck-closures-slice-patterns-ok.rs: New test. * rust/rustc/ui/borrowck/borrowck-closures-slice-patterns.rs: New test. * rust/rustc/ui/borrowck/borrowck-closures-two-imm.rs: New test. * rust/rustc/ui/borrowck/borrowck-closures-two-mut-fail.rs: New test. * rust/rustc/ui/borrowck/borrowck-closures-two-mut.rs: New test. * rust/rustc/ui/borrowck/borrowck-closures-unique-imm.rs: New test. * rust/rustc/ui/borrowck/borrowck-closures-unique.rs: New test. * rust/rustc/ui/borrowck/borrowck-closures-use-after-free.rs: New test. * rust/rustc/ui/borrowck/borrowck-consume-unsize-vec.rs: New test. * rust/rustc/ui/borrowck/borrowck-consume-upcast-box.rs: New test. * rust/rustc/ui/borrowck/borrowck-describe-lvalue.rs: New test. * rust/rustc/ui/borrowck/borrowck-drop-from-guard.rs: New test. * rust/rustc/ui/borrowck/borrowck-escaping-closure-error-1.rs: New test. * rust/rustc/ui/borrowck/borrowck-escaping-closure-error-2.rs: New test. * rust/rustc/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs: New test. * rust/rustc/ui/borrowck/borrowck-field-sensitivity-rpass.rs: New test. * rust/rustc/ui/borrowck/borrowck-field-sensitivity.rs: New test. * rust/rustc/ui/borrowck/borrowck-fixed-length-vecs.rs: New test. * rust/rustc/ui/borrowck/borrowck-fn-in-const-a.rs: New test. * rust/rustc/ui/borrowck/borrowck-fn-in-const-c.rs: New test. * rust/rustc/ui/borrowck/borrowck-for-loop-correct-cmt-for-pattern.rs: New test. * rust/rustc/ui/borrowck/borrowck-for-loop-head-linkage.rs: New test. * rust/rustc/ui/borrowck/borrowck-freeze-frozen-mut.rs: New test. * rust/rustc/ui/borrowck/borrowck-if-no-else.rs: New test. * rust/rustc/ui/borrowck/borrowck-if-with-else.rs: New test. * rust/rustc/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs: New test. * rust/rustc/ui/borrowck/borrowck-in-static.rs: New test. * rust/rustc/ui/borrowck/borrowck-init-in-called-fn-expr.rs: New test. * rust/rustc/ui/borrowck/borrowck-init-in-fn-expr.rs: New test. * rust/rustc/ui/borrowck/borrowck-init-in-fru.rs: New test. * rust/rustc/ui/borrowck/borrowck-init-op-equal.rs: New test. * rust/rustc/ui/borrowck/borrowck-init-plus-equal.rs: New test. * rust/rustc/ui/borrowck/borrowck-insert-during-each.rs: New test. * rust/rustc/ui/borrowck/borrowck-issue-14498.rs: New test. * rust/rustc/ui/borrowck/borrowck-issue-2657-1.rs: New test. * rust/rustc/ui/borrowck/borrowck-issue-2657-2.rs: New test. * rust/rustc/ui/borrowck/borrowck-issue-48962.rs: New test. * rust/rustc/ui/borrowck/borrowck-lend-args.rs: New test. * rust/rustc/ui/borrowck/borrowck-lend-flow-if.rs: New test. * rust/rustc/ui/borrowck/borrowck-lend-flow-loop.rs: New test. * rust/rustc/ui/borrowck/borrowck-lend-flow-match.rs: New test. * rust/rustc/ui/borrowck/borrowck-lend-flow.rs: New test. * rust/rustc/ui/borrowck/borrowck-loan-blocks-move-cc.rs: New test. * rust/rustc/ui/borrowck/borrowck-loan-blocks-move.rs: New test. * rust/rustc/ui/borrowck/borrowck-loan-blocks-mut-uniq.rs: New test. * rust/rustc/ui/borrowck/borrowck-loan-in-overloaded-op.rs: New test. * rust/rustc/ui/borrowck/borrowck-loan-of-static-data-issue-27616.rs: New test. * rust/rustc/ui/borrowck/borrowck-loan-rcvr-overloaded-op.rs: New test. * rust/rustc/ui/borrowck/borrowck-loan-rcvr.rs: New test. * rust/rustc/ui/borrowck/borrowck-loan-vec-content.rs: New test. * rust/rustc/ui/borrowck/borrowck-local-borrow-outlives-fn.rs: New test. * rust/rustc/ui/borrowck/borrowck-local-borrow-with-panic-outlives-fn.rs: New test. * rust/rustc/ui/borrowck/borrowck-local-borrow.rs: New test. * rust/rustc/ui/borrowck/borrowck-macro-interaction-issue-6304.rs: New test. * rust/rustc/ui/borrowck/borrowck-match-already-borrowed.rs: New test. * rust/rustc/ui/borrowck/borrowck-match-binding-is-assignment.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-by-capture-ok.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-by-capture.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-error-with-note.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-from-unsafe-ptr.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-in-irrefut-pat.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-moved-value-into-closure.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-mut-base-ptr.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-from-array-match.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-match.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-from-array-use.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-from-array.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-of-overloaded-deref.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-of-static-item.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-of-struct-with-dtor.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-of-tuple-struct-with-dtor.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-out-of-vec-tail.rs: New test. * rust/rustc/ui/borrowck/borrowck-move-subcomponent.rs: New test. * rust/rustc/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs: New test. * rust/rustc/ui/borrowck/borrowck-multiple-captures.rs: New test. * rust/rustc/ui/borrowck/borrowck-mut-addr-of-imm-var.rs: New test. * rust/rustc/ui/borrowck/borrowck-mut-borrow-linear-errors.rs: New test. * rust/rustc/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs: New test. * rust/rustc/ui/borrowck/borrowck-mut-slice-of-imm-vec.rs: New test. * rust/rustc/ui/borrowck/borrowck-mut-uniq.rs: New test. * rust/rustc/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs: New test. * rust/rustc/ui/borrowck/borrowck-mutate-in-guard.rs: New test. * rust/rustc/ui/borrowck/borrowck-no-cycle-in-exchange-heap.rs: New test. * rust/rustc/ui/borrowck/borrowck-object-lifetime.rs: New test. * rust/rustc/ui/borrowck/borrowck-or-init.rs: New test. * rust/rustc/ui/borrowck/borrowck-overloaded-call.rs: New test. * rust/rustc/ui/borrowck/borrowck-overloaded-index-and-overloaded-deref.rs: New test. * rust/rustc/ui/borrowck/borrowck-overloaded-index-autoderef.rs: New test. * rust/rustc/ui/borrowck/borrowck-overloaded-index-move-from-vec.rs: New test. * rust/rustc/ui/borrowck/borrowck-overloaded-index-move-index.rs: New test. * rust/rustc/ui/borrowck/borrowck-overloaded-index-ref-index.rs: New test. * rust/rustc/ui/borrowck/borrowck-partial-reinit-1.rs: New test. * rust/rustc/ui/borrowck/borrowck-partial-reinit-2.rs: New test. * rust/rustc/ui/borrowck/borrowck-partial-reinit-3.rs: New test. * rust/rustc/ui/borrowck/borrowck-partial-reinit-4.rs: New test. * rust/rustc/ui/borrowck/borrowck-pat-enum.rs: New test. * rust/rustc/ui/borrowck/borrowck-pat-reassign-binding.rs: New test. * rust/rustc/ui/borrowck/borrowck-pat-reassign-no-binding.rs: New test. * rust/rustc/ui/borrowck/borrowck-reborrow-from-mut.rs: New test. * rust/rustc/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.rs: New test. * rust/rustc/ui/borrowck/borrowck-ref-mut-of-imm.rs: New test. * rust/rustc/ui/borrowck/borrowck-reinit.rs: New test. * rust/rustc/ui/borrowck/borrowck-report-with-custom-diagnostic.rs: New test. * rust/rustc/ui/borrowck/borrowck-return-variable-on-stack-via-clone.rs: New test. * rust/rustc/ui/borrowck/borrowck-return.rs: New test. * rust/rustc/ui/borrowck/borrowck-rvalues-mutable.rs: New test. * rust/rustc/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs: New test. * rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs: New test. * rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs: New test. * rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs: New test. * rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs: New test. * rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs: New test. * rust/rustc/ui/borrowck/borrowck-static-item-in-fn.rs: New test. * rust/rustc/ui/borrowck/borrowck-storage-dead.rs: New test. * rust/rustc/ui/borrowck/borrowck-struct-update-with-dtor.rs: New test. * rust/rustc/ui/borrowck/borrowck-swap-mut-base-ptr.rs: New test. * rust/rustc/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.rs: New test. * rust/rustc/ui/borrowck/borrowck-trait-lifetime.rs: New test. * rust/rustc/ui/borrowck/borrowck-unary-move.rs: New test. * rust/rustc/ui/borrowck/borrowck-unboxed-closures.rs: New test. * rust/rustc/ui/borrowck/borrowck-uninit-after-item.rs: New test. * rust/rustc/ui/borrowck/borrowck-uninit-field-access.rs: New test. * rust/rustc/ui/borrowck/borrowck-uninit-in-assignop.rs: New test. * rust/rustc/ui/borrowck/borrowck-uninit-ref-chain.rs: New test. * rust/rustc/ui/borrowck/borrowck-uninit.rs: New test. * rust/rustc/ui/borrowck/borrowck-union-borrow-nested.rs: New test. * rust/rustc/ui/borrowck/borrowck-union-borrow.rs: New test. * rust/rustc/ui/borrowck/borrowck-union-move-assign.rs: New test. * rust/rustc/ui/borrowck/borrowck-union-move.rs: New test. * rust/rustc/ui/borrowck/borrowck-union-uninitialized.rs: New test. * rust/rustc/ui/borrowck/borrowck-uniq-via-lend.rs: New test. * rust/rustc/ui/borrowck/borrowck-uniq-via-ref.rs: New test. * rust/rustc/ui/borrowck/borrowck-univariant-enum.rs: New test. * rust/rustc/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs: New test. * rust/rustc/ui/borrowck/borrowck-unused-mut-locals.rs: New test. * rust/rustc/ui/borrowck/borrowck-use-in-index-lvalue.rs: New test. * rust/rustc/ui/borrowck/borrowck-use-mut-borrow-rpass.rs: New test. * rust/rustc/ui/borrowck/borrowck-use-mut-borrow.rs: New test. * rust/rustc/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.rs: New test. * rust/rustc/ui/borrowck/borrowck-use-uninitialized-in-cast.rs: New test. * rust/rustc/ui/borrowck/borrowck-vec-pattern-element-loan.rs: New test. * rust/rustc/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs: New test. * rust/rustc/ui/borrowck/borrowck-vec-pattern-move-tail.rs: New test. * rust/rustc/ui/borrowck/borrowck-vec-pattern-nesting.rs: New test. * rust/rustc/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs: New test. * rust/rustc/ui/borrowck/borrowck-while-break.rs: New test. * rust/rustc/ui/borrowck/borrowck-while-cond.rs: New test. * rust/rustc/ui/borrowck/borrowck-while.rs: New test. * rust/rustc/ui/borrowck/disallow-possibly-uninitialized.rs: New test. * rust/rustc/ui/borrowck/immutable-arg.rs: New test. * rust/rustc/ui/borrowck/index-mut-help-with-impl.rs: New test. * rust/rustc/ui/borrowck/index-mut-help.rs: New test. * rust/rustc/ui/borrowck/issue-10876.rs: New test. * rust/rustc/ui/borrowck/issue-27282-mutation-in-guard.rs: New test. * rust/rustc/ui/borrowck/issue-31287-drop-in-guard.rs: New test. * rust/rustc/ui/borrowck/issue-41962.rs: New test. * rust/rustc/ui/borrowck/issue-45983.rs: New test. * rust/rustc/ui/borrowck/issue-47215-ice-from-drop-elab.rs: New test. * rust/rustc/ui/borrowck/issue-51117.rs: New test. * rust/rustc/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs: New test. * rust/rustc/ui/borrowck/issue-51415.rs: New test. * rust/rustc/ui/borrowck/issue-52713-bug.rs: New test. * rust/rustc/ui/borrowck/issue-52967-edition-2018-needs-two-phase-borrows.rs: New test. * rust/rustc/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.rs: New test. * rust/rustc/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs: New test. * rust/rustc/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs: New test. * rust/rustc/ui/borrowck/issue-54499-field-mutation-of-moved-out.rs: New test. * rust/rustc/ui/borrowck/issue-54499-field-mutation-of-never-init.rs: New test. * rust/rustc/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs: New test. * rust/rustc/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs: New test. * rust/rustc/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs: New test. * rust/rustc/ui/borrowck/issue-58776-borrowck-scans-children.rs: New test. * rust/rustc/ui/borrowck/issue-62007-assign-box.rs: New test. * rust/rustc/ui/borrowck/issue-62007-assign-field.rs: New test. * rust/rustc/ui/borrowck/issue-62107-match-arm-scopes.rs: New test. * rust/rustc/ui/borrowck/issue-64453.rs: New test. * rust/rustc/ui/borrowck/issue-69789-iterator-mut-suggestion.rs: New test. * rust/rustc/ui/borrowck/issue-7573.rs: New test. * rust/rustc/ui/borrowck/move-error-in-promoted-2.rs: New test. * rust/rustc/ui/borrowck/move-error-in-promoted.rs: New test. * rust/rustc/ui/borrowck/move-error-snippets-ext.rs: New test. * rust/rustc/ui/borrowck/move-error-snippets.rs: New test. * rust/rustc/ui/borrowck/move-from-union-field-issue-66500.rs: New test. * rust/rustc/ui/borrowck/move-in-pattern-mut.rs: New test. * rust/rustc/ui/borrowck/move-in-pattern.rs: New test. * rust/rustc/ui/borrowck/move-in-static-initializer-issue-38520.rs: New test. * rust/rustc/ui/borrowck/mut-borrow-in-loop-2.rs: New test. * rust/rustc/ui/borrowck/mut-borrow-in-loop.rs: New test. * rust/rustc/ui/borrowck/mut-borrow-of-mut-ref.rs: New test. * rust/rustc/ui/borrowck/mut-borrow-outside-loop.rs: New test. * rust/rustc/ui/borrowck/mutability-errors.rs: New test. * rust/rustc/ui/borrowck/or-patterns.rs: New test. * rust/rustc/ui/borrowck/promote-ref-mut-in-let-issue-46557.rs: New test. * rust/rustc/ui/borrowck/reassignment_immutable_fields.rs: New test. * rust/rustc/ui/borrowck/reassignment_immutable_fields_overlapping.rs: New test. * rust/rustc/ui/borrowck/reassignment_immutable_fields_twice.rs: New test. * rust/rustc/ui/borrowck/regions-bound-missing-bound-in-impl.rs: New test. * rust/rustc/ui/borrowck/regions-escape-bound-fn-2.rs: New test. * rust/rustc/ui/borrowck/regions-escape-bound-fn.rs: New test. * rust/rustc/ui/borrowck/regions-escape-unboxed-closure.rs: New test. * rust/rustc/ui/borrowck/return-local-binding-from-desugaring.rs: New test. * rust/rustc/ui/borrowck/slice-index-bounds-check-invalidation.rs: New test. * rust/rustc/ui/borrowck/two-phase-across-loop.rs: New test. * rust/rustc/ui/borrowck/two-phase-activation-sharing-interference.rs: New test. * rust/rustc/ui/borrowck/two-phase-allow-access-during-reservation.rs: New test. * rust/rustc/ui/borrowck/two-phase-baseline.rs: New test. * rust/rustc/ui/borrowck/two-phase-bin-ops.rs: New test. * rust/rustc/ui/borrowck/two-phase-cannot-nest-mut-self-calls.rs: New test. * rust/rustc/ui/borrowck/two-phase-control-flow-split-before-activation.rs: New test. * rust/rustc/ui/borrowck/two-phase-method-receivers.rs: New test. * rust/rustc/ui/borrowck/two-phase-multi-mut.rs: New test. * rust/rustc/ui/borrowck/two-phase-multiple-activations.rs: New test. * rust/rustc/ui/borrowck/two-phase-nonrecv-autoref.rs: New test. * rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference-2.rs: New test. * rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.rs: New test. * rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference.rs: New test. * rust/rustc/ui/borrowck/two-phase-sneaky.rs: New test. * rust/rustc/ui/borrowck/two-phase-surprise-no-conflict.rs: New test. * rust/rustc/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs: New test. * rust/rustc/ui/bound-suggestions.rs: New test. * rust/rustc/ui/bounds-lifetime.rs: New test. * rust/rustc/ui/box/alloc-unstable-fail.rs: New test. * rust/rustc/ui/box/alloc-unstable.rs: New test. * rust/rustc/ui/box/into-boxed-slice-fail.rs: New test. * rust/rustc/ui/box/into-boxed-slice.rs: New test. * rust/rustc/ui/box/leak-alloc.rs: New test. * rust/rustc/ui/box/new.rs: New test. * rust/rustc/ui/break-diverging-value.rs: New test. * rust/rustc/ui/break-outside-loop.rs: New test. * rust/rustc/ui/break-while-condition.rs: New test. * rust/rustc/ui/btreemap/btreemap_into_iterator_lifetime.rs: New test. * rust/rustc/ui/bug-7183-generics.rs: New test. * rust/rustc/ui/bug-7295.rs: New test. * rust/rustc/ui/builtin-clone-unwind.rs: New test. * rust/rustc/ui/builtin-clone.rs: New test. * rust/rustc/ui/builtin-superkinds-capabilities-transitive.rs: New test. * rust/rustc/ui/builtin-superkinds-capabilities-xc.rs: New test. * rust/rustc/ui/builtin-superkinds-capabilities.rs: New test. * rust/rustc/ui/builtin-superkinds-in-metadata.rs: New test. * rust/rustc/ui/builtin-superkinds-phantom-typaram.rs: New test. * rust/rustc/ui/builtin-superkinds-simple.rs: New test. * rust/rustc/ui/builtin-superkinds-typaram.rs: New test. * rust/rustc/ui/builtin-superkinds/auxiliary/trait_superkinds_in_metadata.rs: New test. * rust/rustc/ui/builtin-superkinds/builtin-superkinds-double-superkind.rs: New test. * rust/rustc/ui/builtin-superkinds/builtin-superkinds-in-metadata.rs: New test. * rust/rustc/ui/builtin-superkinds/builtin-superkinds-self-type.rs: New test. * rust/rustc/ui/builtin-superkinds/builtin-superkinds-simple.rs: New test. * rust/rustc/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.rs: New test. * rust/rustc/ui/by-move-pattern-binding.rs: New test. * rust/rustc/ui/byte-literals.rs: New test. * rust/rustc/ui/c-stack-returning-int64.rs: New test. * rust/rustc/ui/c-variadic/variadic-ffi-1.rs: New test. * rust/rustc/ui/c-variadic/variadic-ffi-2.rs: New test. * rust/rustc/ui/c-variadic/variadic-ffi-4.rs: New test. * rust/rustc/ui/c-variadic/variadic-ffi-6.rs: New test. * rust/rustc/ui/c-variadic/variadic-ffi-no-fixed-args.rs: New test. * rust/rustc/ui/can-begin-expr-check.rs: New test. * rust/rustc/ui/can-copy-pod.rs: New test. * rust/rustc/ui/cancel-clean-via-immediate-rvalue-ref.rs: New test. * rust/rustc/ui/cannot-mutate-captured-non-mut-var.rs: New test. * rust/rustc/ui/capture1.rs: New test. * rust/rustc/ui/cast-char.rs: New test. * rust/rustc/ui/cast-does-fallback.rs: New test. * rust/rustc/ui/cast-region-to-uint.rs: New test. * rust/rustc/ui/cast-rfc0401-vtable-kinds.rs: New test. * rust/rustc/ui/cast-rfc0401.rs: New test. * rust/rustc/ui/cast-to-infer-ty.rs: New test. * rust/rustc/ui/cast.rs: New test. * rust/rustc/ui/cast/cast-as-bool.rs: New test. * rust/rustc/ui/cast/cast-errors-issue-43825.rs: New test. * rust/rustc/ui/cast/cast-from-nil.rs: New test. * rust/rustc/ui/cast/cast-ptr-to-int-const.rs: New test. * rust/rustc/ui/cast/cast-rfc0401-2.rs: New test. * rust/rustc/ui/cast/cast-to-bare-fn.rs: New test. * rust/rustc/ui/cast/cast-to-nil.rs: New test. * rust/rustc/ui/cast/cast-to-unsized-trait-object-suggestion.rs: New test. * rust/rustc/ui/casts-differing-anon.rs: New test. * rust/rustc/ui/casts-issue-46365.rs: New test. * rust/rustc/ui/catch-unwind-bang.rs: New test. * rust/rustc/ui/cenum_impl_drop_cast.rs: New test. * rust/rustc/ui/cfg-rustdoc.rs: New test. * rust/rustc/ui/cfg/auxiliary/cfg_inner_static.rs: New test. * rust/rustc/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs: New test. * rust/rustc/ui/cfg/cfg-attr-cfg.rs: New test. * rust/rustc/ui/cfg/cfg-attr-crate.rs: New test. * rust/rustc/ui/cfg/cfg-family.rs: New test. * rust/rustc/ui/cfg/cfg-in-crate-1.rs: New test. * rust/rustc/ui/cfg/cfg-macros-foo.rs: New test. * rust/rustc/ui/cfg/cfg-macros-notfoo.rs: New test. * rust/rustc/ui/cfg/cfg-match-arm.rs: New test. * rust/rustc/ui/cfg/cfg-panic-abort.rs: New test. * rust/rustc/ui/cfg/cfg-panic.rs: New test. * rust/rustc/ui/cfg/cfg-target-family.rs: New test. * rust/rustc/ui/cfg/cfg-target-vendor.rs: New test. * rust/rustc/ui/cfg/cfg_attr.rs: New test. * rust/rustc/ui/cfg/cfg_inner_static.rs: New test. * rust/rustc/ui/cfg/cfg_stmt_expr.rs: New test. * rust/rustc/ui/cfg/cfgs-on-items.rs: New test. * rust/rustc/ui/cfg/conditional-compile-arch.rs: New test. * rust/rustc/ui/cfg/conditional-compile.rs: New test. * rust/rustc/ui/cfg/crate-attributes-using-cfg_attr.rs: New test. * rust/rustc/ui/cfguard-run.rs: New test. * rust/rustc/ui/chalkify/arithmetic.rs: New test. * rust/rustc/ui/chalkify/basic.rs: New test. * rust/rustc/ui/chalkify/builtin-copy-clone.rs: New test. * rust/rustc/ui/chalkify/chalk_initial_program.rs: New test. * rust/rustc/ui/chalkify/closure.rs: New test. * rust/rustc/ui/chalkify/generic_impls.rs: New test. * rust/rustc/ui/chalkify/impl_wf.rs: New test. * rust/rustc/ui/chalkify/impl_wf_2.rs: New test. * rust/rustc/ui/chalkify/inherent_impl.rs: New test. * rust/rustc/ui/chalkify/inherent_impl_min.rs: New test. * rust/rustc/ui/chalkify/lower_env1.rs: New test. * rust/rustc/ui/chalkify/lower_env2.rs: New test. * rust/rustc/ui/chalkify/lower_env3.rs: New test. * rust/rustc/ui/chalkify/lower_impl.rs: New test. * rust/rustc/ui/chalkify/lower_struct.rs: New test. * rust/rustc/ui/chalkify/lower_trait.rs: New test. * rust/rustc/ui/chalkify/lower_trait_higher_rank.rs: New test. * rust/rustc/ui/chalkify/lower_trait_where_clause.rs: New test. * rust/rustc/ui/chalkify/println.rs: New test. * rust/rustc/ui/chalkify/projection.rs: New test. * rust/rustc/ui/chalkify/recursive_where_clause_on_type.rs: New test. * rust/rustc/ui/chalkify/super_trait.rs: New test. * rust/rustc/ui/chalkify/trait-objects.rs: New test. * rust/rustc/ui/chalkify/trait_implied_bound.rs: New test. * rust/rustc/ui/chalkify/type_implied_bound.rs: New test. * rust/rustc/ui/chalkify/type_inference.rs: New test. * rust/rustc/ui/chalkify/type_wf.rs: New test. * rust/rustc/ui/changing-crates.rs: New test. * rust/rustc/ui/char.rs: New test. * rust/rustc/ui/char_unicode.rs: New test. * rust/rustc/ui/check-doc-alias-attr-location.rs: New test. * rust/rustc/ui/check-doc-alias-attr.rs: New test. * rust/rustc/ui/check-static-immutable-mut-slices.rs: New test. * rust/rustc/ui/check-static-recursion-foreign.rs: New test. * rust/rustc/ui/check-static-values-constraints.rs: New test. * rust/rustc/ui/check_const-feature-gated.rs: New test. * rust/rustc/ui/child-outlives-parent.rs: New test. * rust/rustc/ui/class-cast-to-trait.rs: New test. * rust/rustc/ui/class-method-missing.rs: New test. * rust/rustc/ui/class-missing-self.rs: New test. * rust/rustc/ui/cleanup-arm-conditional.rs: New test. * rust/rustc/ui/cleanup-rvalue-during-if-and-while.rs: New test. * rust/rustc/ui/cleanup-rvalue-for-scope.rs: New test. * rust/rustc/ui/cleanup-rvalue-scopes-cf.rs: New test. * rust/rustc/ui/cleanup-rvalue-scopes.rs: New test. * rust/rustc/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs: New test. * rust/rustc/ui/cleanup-shortcircuit.rs: New test. * rust/rustc/ui/clone-with-exterior.rs: New test. * rust/rustc/ui/close-over-big-then-small-data.rs: New test. * rust/rustc/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs: New test. * rust/rustc/ui/closure-expected-type/expect-fn-supply-fn.rs: New test. * rust/rustc/ui/closure-expected-type/expect-infer-var-appearing-twice.rs: New test. * rust/rustc/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs: New test. * rust/rustc/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs: New test. * rust/rustc/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.rs: New test. * rust/rustc/ui/closure-expected-type/issue-24421.rs: New test. * rust/rustc/ui/closure-expected.rs: New test. * rust/rustc/ui/closure_context/issue-26046-fn-mut.rs: New test. * rust/rustc/ui/closure_context/issue-26046-fn-once.rs: New test. * rust/rustc/ui/closure_context/issue-42065.rs: New test. * rust/rustc/ui/closure_promotion.rs: New test. * rust/rustc/ui/closures/closure-array-break-length.rs: New test. * rust/rustc/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs: New test. * rust/rustc/ui/closures/closure-bounds-static-cant-capture-borrowed.rs: New test. * rust/rustc/ui/closures/closure-bounds-subtype.rs: New test. * rust/rustc/ui/closures/closure-expected-type/expect-region-supply-region-2.rs: New test. * rust/rustc/ui/closures/closure-expected-type/expect-region-supply-region.rs: New test. * rust/rustc/ui/closures/closure-immutable-outer-variable.rs: New test. * rust/rustc/ui/closures/closure-move-sync.rs: New test. * rust/rustc/ui/closures/closure-no-fn-1.rs: New test. * rust/rustc/ui/closures/closure-no-fn-2.rs: New test. * rust/rustc/ui/closures/closure-no-fn-3.rs: New test. * rust/rustc/ui/closures/closure-referencing-itself-issue-25954.rs: New test. * rust/rustc/ui/closures/closure-reform-bad.rs: New test. * rust/rustc/ui/closures/closure-return-type-mismatch.rs: New test. * rust/rustc/ui/closures/closure-wrong-kind.rs: New test. * rust/rustc/ui/closures/closure_cap_coerce_many_fail.rs: New test. * rust/rustc/ui/closures/closure_no_cap_coerce_many_check_pass.rs: New test. * rust/rustc/ui/closures/closure_no_cap_coerce_many_run_pass.rs: New test. * rust/rustc/ui/closures/closure_no_cap_coerce_many_unsafe_0.rs: New test. * rust/rustc/ui/closures/closure_no_cap_coerce_many_unsafe_1.rs: New test. * rust/rustc/ui/closures/deeply-nested_closures.rs: New test. * rust/rustc/ui/closures/diverging-closure.rs: New test. * rust/rustc/ui/closures/issue-41366.rs: New test. * rust/rustc/ui/closures/issue-46742.rs: New test. * rust/rustc/ui/closures/issue-48109.rs: New test. * rust/rustc/ui/closures/issue-52437.rs: New test. * rust/rustc/ui/closures/issue-67123.rs: New test. * rust/rustc/ui/closures/issue-68025.rs: New test. * rust/rustc/ui/closures/issue-72408-nested-closures-exponential.rs: New test. * rust/rustc/ui/closures/print/closure-print-generic-1.rs: New test. * rust/rustc/ui/closures/print/closure-print-generic-2.rs: New test. * rust/rustc/ui/closures/print/closure-print-generic-trim-off-verbose-2.rs: New test. * rust/rustc/ui/closures/print/closure-print-generic-verbose-1.rs: New test. * rust/rustc/ui/closures/print/closure-print-generic-verbose-2.rs: New test. * rust/rustc/ui/closures/print/closure-print-verbose.rs: New test. * rust/rustc/ui/cmp-default.rs: New test. * rust/rustc/ui/cmse-nonsecure-entry/gate_test.rs: New test. * rust/rustc/ui/cmse-nonsecure-entry/params-on-registers.rs: New test. * rust/rustc/ui/cmse-nonsecure-entry/params-on-stack.rs: New test. * rust/rustc/ui/cmse-nonsecure-entry/trustzone-only.rs: New test. * rust/rustc/ui/cmse-nonsecure-entry/wrong-abi.rs: New test. * rust/rustc/ui/codegen-object-shim.rs: New test. * rust/rustc/ui/codemap_tests/bad-format-args.rs: New test. * rust/rustc/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs: New test. * rust/rustc/ui/codemap_tests/empty_span.rs: New test. * rust/rustc/ui/codemap_tests/huge_multispan_highlight.rs: New test. * rust/rustc/ui/codemap_tests/issue-11715.rs: New test. * rust/rustc/ui/codemap_tests/issue-28308.rs: New test. * rust/rustc/ui/codemap_tests/one_line.rs: New test. * rust/rustc/ui/codemap_tests/overlapping_inherent_impls.rs: New test. * rust/rustc/ui/codemap_tests/tab.rs: New test. * rust/rustc/ui/codemap_tests/tab_2.rs: New test. * rust/rustc/ui/codemap_tests/tab_3.rs: New test. * rust/rustc/ui/codemap_tests/two_files.rs: New test. * rust/rustc/ui/codemap_tests/two_files_data.rs: New test. * rust/rustc/ui/codemap_tests/unicode.rs: New test. * rust/rustc/ui/codemap_tests/unicode_2.rs: New test. * rust/rustc/ui/codemap_tests/unicode_3.rs: New test. * rust/rustc/ui/coercion/coerce-expect-unsized-ascribed.rs: New test. * rust/rustc/ui/coercion/coerce-expect-unsized.rs: New test. * rust/rustc/ui/coercion/coerce-issue-49593-box-never.rs: New test. * rust/rustc/ui/coercion/coerce-mut.rs: New test. * rust/rustc/ui/coercion/coerce-overloaded-autoderef-fail.rs: New test. * rust/rustc/ui/coercion/coerce-overloaded-autoderef.rs: New test. * rust/rustc/ui/coercion/coerce-reborrow-imm-ptr-arg.rs: New test. * rust/rustc/ui/coercion/coerce-reborrow-imm-ptr-rcvr.rs: New test. * rust/rustc/ui/coercion/coerce-reborrow-imm-vec-arg.rs: New test. * rust/rustc/ui/coercion/coerce-reborrow-imm-vec-rcvr.rs: New test. * rust/rustc/ui/coercion/coerce-reborrow-multi-arg-fail.rs: New test. * rust/rustc/ui/coercion/coerce-reborrow-multi-arg.rs: New test. * rust/rustc/ui/coercion/coerce-reborrow-mut-ptr-arg.rs: New test. * rust/rustc/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs: New test. * rust/rustc/ui/coercion/coerce-reborrow-mut-vec-arg.rs: New test. * rust/rustc/ui/coercion/coerce-reborrow-mut-vec-rcvr.rs: New test. * rust/rustc/ui/coercion/coerce-to-bang-cast.rs: New test. * rust/rustc/ui/coercion/coerce-to-bang.rs: New test. * rust/rustc/ui/coercion/coerce-unify-return.rs: New test. * rust/rustc/ui/coercion/coerce-unify.rs: New test. * rust/rustc/ui/coercion/coerce-unsize-subtype.rs: New test. * rust/rustc/ui/coercion/coercion-missing-tail-expected-type.rs: New test. * rust/rustc/ui/coercion/coercion-slice.rs: New test. * rust/rustc/ui/coherence/auxiliary/coherence_copy_like_lib.rs: New test. * rust/rustc/ui/coherence/auxiliary/coherence_fundamental_trait_lib.rs: New test. * rust/rustc/ui/coherence/auxiliary/coherence_inherent_cc_lib.rs: New test. * rust/rustc/ui/coherence/auxiliary/coherence_lib.rs: New test. * rust/rustc/ui/coherence/auxiliary/coherence_orphan_lib.rs: New test. * rust/rustc/ui/coherence/auxiliary/go_trait.rs: New test. * rust/rustc/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs: New test. * rust/rustc/ui/coherence/auxiliary/re_rebalance_coherence_lib.rs: New test. * rust/rustc/ui/coherence/auxiliary/trait_impl_conflict.rs: New test. * rust/rustc/ui/coherence/coherence-all-remote.rs: New test. * rust/rustc/ui/coherence/coherence-bigint-int.rs: New test. * rust/rustc/ui/coherence/coherence-bigint-param.rs: New test. * rust/rustc/ui/coherence/coherence-bigint-vecint.rs: New test. * rust/rustc/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs: New test. * rust/rustc/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs: New test. * rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs: New test. * rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs: New test. * rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs: New test. * rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific.rs: New test. * rust/rustc/ui/coherence/coherence-blanket.rs: New test. * rust/rustc/ui/coherence/coherence-conflicting-negative-trait-impl.rs: New test. * rust/rustc/ui/coherence/coherence-covered-type-parameter.rs: New test. * rust/rustc/ui/coherence/coherence-cow.rs: New test. * rust/rustc/ui/coherence/coherence-cross-crate-conflict.rs: New test. * rust/rustc/ui/coherence/coherence-default-trait-impl.rs: New test. * rust/rustc/ui/coherence/coherence-error-suppression.rs: New test. * rust/rustc/ui/coherence/coherence-fn-covariant-bound-vs-static.rs: New test. * rust/rustc/ui/coherence/coherence-fn-implied-bounds.rs: New test. * rust/rustc/ui/coherence/coherence-fn-inputs.rs: New test. * rust/rustc/ui/coherence/coherence-free-vs-bound-region.rs: New test. * rust/rustc/ui/coherence/coherence-fundamental-trait-objects.rs: New test. * rust/rustc/ui/coherence/coherence-impl-in-fn.rs: New test. * rust/rustc/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs: New test. * rust/rustc/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs: New test. * rust/rustc/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs: New test. * rust/rustc/ui/coherence/coherence-impl-trait-for-trait.rs: New test. * rust/rustc/ui/coherence/coherence-impls-copy.rs: New test. * rust/rustc/ui/coherence/coherence-impls-send.rs: New test. * rust/rustc/ui/coherence/coherence-impls-sized.rs: New test. * rust/rustc/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs: New test. * rust/rustc/ui/coherence/coherence-inherited-subtyping.rs: New test. * rust/rustc/ui/coherence/coherence-iterator-vec-any-elem.rs: New test. * rust/rustc/ui/coherence/coherence-iterator-vec.rs: New test. * rust/rustc/ui/coherence/coherence-lone-type-parameter.rs: New test. * rust/rustc/ui/coherence/coherence-multidispatch-tuple.rs: New test. * rust/rustc/ui/coherence/coherence-negative-impls-safe-rpass.rs: New test. * rust/rustc/ui/coherence/coherence-negative-impls-safe.rs: New test. * rust/rustc/ui/coherence/coherence-no-direct-lifetime-dispatch.rs: New test. * rust/rustc/ui/coherence/coherence-orphan.rs: New test. * rust/rustc/ui/coherence/coherence-overlap-all-t-and-tuple.rs: New test. * rust/rustc/ui/coherence/coherence-overlap-downstream-inherent.rs: New test. * rust/rustc/ui/coherence/coherence-overlap-downstream.rs: New test. * rust/rustc/ui/coherence/coherence-overlap-issue-23516-inherent.rs: New test. * rust/rustc/ui/coherence/coherence-overlap-issue-23516.rs: New test. * rust/rustc/ui/coherence/coherence-overlap-messages.rs: New test. * rust/rustc/ui/coherence/coherence-overlap-upstream-inherent.rs: New test. * rust/rustc/ui/coherence/coherence-overlap-upstream.rs: New test. * rust/rustc/ui/coherence/coherence-overlapping-pairs.rs: New test. * rust/rustc/ui/coherence/coherence-pair-covered-uncovered-1.rs: New test. * rust/rustc/ui/coherence/coherence-pair-covered-uncovered.rs: New test. * rust/rustc/ui/coherence/coherence-projection-conflict-orphan.rs: New test. * rust/rustc/ui/coherence/coherence-projection-conflict-ty-param.rs: New test. * rust/rustc/ui/coherence/coherence-projection-conflict.rs: New test. * rust/rustc/ui/coherence/coherence-projection-ok-orphan.rs: New test. * rust/rustc/ui/coherence/coherence-projection-ok.rs: New test. * rust/rustc/ui/coherence/coherence-rfc447-constrained.rs: New test. * rust/rustc/ui/coherence/coherence-subtyping.rs: New test. * rust/rustc/ui/coherence/coherence-tuple-conflict.rs: New test. * rust/rustc/ui/coherence/coherence-unsafe-trait-object-impl.rs: New test. * rust/rustc/ui/coherence/coherence-vec-local-2.rs: New test. * rust/rustc/ui/coherence/coherence-vec-local.rs: New test. * rust/rustc/ui/coherence/coherence-wasm-bindgen.rs: New test. * rust/rustc/ui/coherence/coherence-where-clause.rs: New test. * rust/rustc/ui/coherence/coherence_copy_like.rs: New test. * rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct.rs: New test. * rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs: New test. * rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs: New test. * rust/rustc/ui/coherence/coherence_copy_like_err_struct.rs: New test. * rust/rustc/ui/coherence/coherence_copy_like_err_tuple.rs: New test. * rust/rustc/ui/coherence/coherence_inherent.rs: New test. * rust/rustc/ui/coherence/coherence_inherent_cc.rs: New test. * rust/rustc/ui/coherence/coherence_local.rs: New test. * rust/rustc/ui/coherence/coherence_local_err_struct.rs: New test. * rust/rustc/ui/coherence/coherence_local_err_tuple.rs: New test. * rust/rustc/ui/coherence/coherence_local_ref.rs: New test. * rust/rustc/ui/coherence/conflicting-impl-with-err.rs: New test. * rust/rustc/ui/coherence/impl-foreign-for-foreign.rs: New test. * rust/rustc/ui/coherence/impl-foreign-for-foreign[foreign].rs: New test. * rust/rustc/ui/coherence/impl-foreign-for-foreign[local].rs: New test. * rust/rustc/ui/coherence/impl-foreign-for-fundamental[foreign].rs: New test. * rust/rustc/ui/coherence/impl-foreign-for-fundamental[local].rs: New test. * rust/rustc/ui/coherence/impl-foreign-for-local.rs: New test. * rust/rustc/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs: New test. * rust/rustc/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs: New test. * rust/rustc/ui/coherence/impl-foreign[foreign]-for-foreign.rs: New test. * rust/rustc/ui/coherence/impl-foreign[foreign]-for-local.rs: New test. * rust/rustc/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs: New test. * rust/rustc/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign-for-foreign[t].rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign-for-fundamental[t].rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[foreign]-for-t.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[local]-for-foreign.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[local]-for-local.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[local]-for-t.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[t]-for-foreign.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[t]-for-local.rs: New test. * rust/rustc/ui/coherence/impl[t]-foreign[t]-for-t.rs: New test. * rust/rustc/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs: New test. * rust/rustc/ui/coherence/re-rebalance-coherence.rs: New test. * rust/rustc/ui/collections-const-new.rs: New test. * rust/rustc/ui/command-line-diagnostics.rs: New test. * rust/rustc/ui/command/command-argv0-debug.rs: New test. * rust/rustc/ui/command/command-argv0.rs: New test. * rust/rustc/ui/command/command-exec.rs: New test. * rust/rustc/ui/command/command-pre-exec.rs: New test. * rust/rustc/ui/command/command-uid-gid.rs: New test. * rust/rustc/ui/commandline-argfile-badutf8.rs: New test. * rust/rustc/ui/commandline-argfile-missing.rs: New test. * rust/rustc/ui/commandline-argfile.rs: New test. * rust/rustc/ui/compare-method/proj-outlives-region.rs: New test. * rust/rustc/ui/compare-method/region-extra-2.rs: New test. * rust/rustc/ui/compare-method/region-extra.rs: New test. * rust/rustc/ui/compare-method/region-unrelated.rs: New test. * rust/rustc/ui/compare-method/reordered-type-param.rs: New test. * rust/rustc/ui/compare-method/trait-bound-on-type-parameter.rs: New test. * rust/rustc/ui/compare-method/traits-misc-mismatch-1.rs: New test. * rust/rustc/ui/compare-method/traits-misc-mismatch-2.rs: New test. * rust/rustc/ui/compile_error_macro.rs: New test. * rust/rustc/ui/complex.rs: New test. * rust/rustc/ui/concat-rpass.rs: New test. * rust/rustc/ui/concat.rs: New test. * rust/rustc/ui/conditional-compilation/auxiliary/namespaced_enums.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-arg-invalid-1.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-arg-invalid-2.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-arg-invalid-3.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-arg-invalid-4.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-arg-invalid-5.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-arg-invalid-6.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-attr-cfg-2.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-attr-crate-2.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-attr-empty-is-unused.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-attr-invalid-predicate.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-attr-multi-false.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-attr-multi-true.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-attr-parse.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-attr-syntax-validation.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-empty-codemap.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-generic-params.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-in-crate-1.rs: New test. * rust/rustc/ui/conditional-compilation/cfg-non-opt-expr.rs: New test. * rust/rustc/ui/conditional-compilation/cfg_accessible-input-validation.rs: New test. * rust/rustc/ui/conditional-compilation/cfg_accessible-stuck.rs: New test. * rust/rustc/ui/conditional-compilation/cfg_accessible-unstable.rs: New test. * rust/rustc/ui/conditional-compilation/cfg_accessible.rs: New test. * rust/rustc/ui/conditional-compilation/cfg_attr_path.rs: New test. * rust/rustc/ui/conflicting-repr-hints.rs: New test. * rust/rustc/ui/confuse-field-and-method/issue-18343.rs: New test. * rust/rustc/ui/confuse-field-and-method/issue-2392.rs: New test. * rust/rustc/ui/confuse-field-and-method/issue-32128.rs: New test. * rust/rustc/ui/confuse-field-and-method/issue-33784.rs: New test. * rust/rustc/ui/confuse-field-and-method/private-field.rs: New test. * rust/rustc/ui/conservative_impl_trait.rs: New test. * rust/rustc/ui/const-generics/apit-with-const-param.rs: New test. * rust/rustc/ui/const-generics/argument_order.rs: New test. * rust/rustc/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs: New test. * rust/rustc/ui/const-generics/array-impls/alloc-traits-impls-length-33.rs: New test. * rust/rustc/ui/const-generics/array-impls/alloc-types-impls-length-33.rs: New test. * rust/rustc/ui/const-generics/array-impls/core-traits-impls-length-32.rs: New test. * rust/rustc/ui/const-generics/array-impls/core-traits-impls-length-33.rs: New test. * rust/rustc/ui/const-generics/array-impls/into-iter-impls-length-32.rs: New test. * rust/rustc/ui/const-generics/array-impls/into-iter-impls-length-33.rs: New test. * rust/rustc/ui/const-generics/array-size-in-generic-struct-param.rs: New test. * rust/rustc/ui/const-generics/array-wrapper-struct-ctor.rs: New test. * rust/rustc/ui/const-generics/associated-type-bound-fail.rs: New test. * rust/rustc/ui/const-generics/associated-type-bound.rs: New test. * rust/rustc/ui/const-generics/auxiliary/const_generic_lib.rs: New test. * rust/rustc/ui/const-generics/auxiliary/crayte.rs: New test. * rust/rustc/ui/const-generics/auxiliary/impl-const.rs: New test. * rust/rustc/ui/const-generics/broken-mir-1.rs: New test. * rust/rustc/ui/const-generics/broken-mir-2.rs: New test. * rust/rustc/ui/const-generics/cannot-infer-type-for-const-param.rs: New test. * rust/rustc/ui/const-generics/closing-args-token.rs: New test. * rust/rustc/ui/const-generics/coerce_unsized_array.rs: New test. * rust/rustc/ui/const-generics/concrete-const-as-fn-arg.rs: New test. * rust/rustc/ui/const-generics/concrete-const-impl-method.rs: New test. * rust/rustc/ui/const-generics/condition-in-trait-const-arg.rs: New test. * rust/rustc/ui/const-generics/const-arg-in-const-arg.rs: New test. * rust/rustc/ui/const-generics/const-arg-in-fn.rs: New test. * rust/rustc/ui/const-generics/const-arg-type-arg-misordered.rs: New test. * rust/rustc/ui/const-generics/const-argument-cross-crate-mismatch.rs: New test. * rust/rustc/ui/const-generics/const-argument-cross-crate.rs: New test. * rust/rustc/ui/const-generics/const-argument-if-length.rs: New test. * rust/rustc/ui/const-generics/const-argument-non-static-lifetime.rs: New test. * rust/rustc/ui/const-generics/const-expression-parameter.rs: New test. * rust/rustc/ui/const-generics/const-fn-with-const-param.rs: New test. * rust/rustc/ui/const-generics/const-generic-array-wrapper.rs: New test. * rust/rustc/ui/const-generics/const-generic-type_name.rs: New test. * rust/rustc/ui/const-generics/const-param-after-const-literal-arg.rs: New test. * rust/rustc/ui/const-generics/const-param-before-other-params.rs: New test. * rust/rustc/ui/const-generics/const-param-elided-lifetime.rs: New test. * rust/rustc/ui/const-generics/const-param-from-outer-fn.rs: New test. * rust/rustc/ui/const-generics/const-param-hygiene.rs: New test. * rust/rustc/ui/const-generics/const-param-in-async.rs: New test. * rust/rustc/ui/const-generics/const-param-in-trait-ungated.rs: New test. * rust/rustc/ui/const-generics/const-param-in-trait.rs: New test. * rust/rustc/ui/const-generics/const-param-type-depends-on-const-param.rs: New test. * rust/rustc/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs: New test. * rust/rustc/ui/const-generics/const-param-type-depends-on-type-param.rs: New test. * rust/rustc/ui/const-generics/const-parameter-uppercase-lint.rs: New test. * rust/rustc/ui/const-generics/const-types.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/associated-consts.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/auxiliary/const_evaluatable_lib.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/closures.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/cross_crate.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/different-fn.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/division.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/fn_call.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/from-sig.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/impl-bounds.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/infer-too-generic.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/less_than.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/let-bindings.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-err-where-bounds.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-ok-infer-err.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-ok.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/simple.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/simple_fail.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/unop.rs: New test. * rust/rustc/ui/const-generics/const_evaluatable_checked/unused_expr.rs: New test. * rust/rustc/ui/const-generics/core-types.rs: New test. * rust/rustc/ui/const-generics/cross_crate_complex.rs: New test. * rust/rustc/ui/const-generics/defaults/complex-unord-param.rs: New test. * rust/rustc/ui/const-generics/defaults/intermixed-lifetime.rs: New test. * rust/rustc/ui/const-generics/defaults/needs-feature.rs: New test. * rust/rustc/ui/const-generics/defaults/simple-defaults.rs: New test. * rust/rustc/ui/const-generics/defaults/wrong-order.rs: New test. * rust/rustc/ui/const-generics/derive-debug-array-wrapper.rs: New test. * rust/rustc/ui/const-generics/different_byref.rs: New test. * rust/rustc/ui/const-generics/different_byref_simple.rs: New test. * rust/rustc/ui/const-generics/dyn-supertraits.rs: New test. * rust/rustc/ui/const-generics/exhaustive-value.rs: New test. * rust/rustc/ui/const-generics/fn-const-param-call.rs: New test. * rust/rustc/ui/const-generics/fn-const-param-infer.rs: New test. * rust/rustc/ui/const-generics/fn-taking-const-generic-array.rs: New test. * rust/rustc/ui/const-generics/forbid-non-structural_match-types.rs: New test. * rust/rustc/ui/const-generics/foreign-item-const-parameter.rs: New test. * rust/rustc/ui/const-generics/generic-function-call-in-array-length.rs: New test. * rust/rustc/ui/const-generics/generic-param-mismatch.rs: New test. * rust/rustc/ui/const-generics/generic-sum-in-array-length.rs: New test. * rust/rustc/ui/const-generics/impl-const-generic-struct.rs: New test. * rust/rustc/ui/const-generics/impl-trait-with-const-arguments.rs: New test. * rust/rustc/ui/const-generics/incorrect-number-of-const-args.rs: New test. * rust/rustc/ui/const-generics/infer/cannot-infer-const-args.rs: New test. * rust/rustc/ui/const-generics/infer/issue-77092.rs: New test. * rust/rustc/ui/const-generics/infer/method-chain.rs: New test. * rust/rustc/ui/const-generics/infer/uninferred-consts.rs: New test. * rust/rustc/ui/const-generics/infer_arg_from_pat.rs: New test. * rust/rustc/ui/const-generics/infer_arr_len_from_pat.rs: New test. * rust/rustc/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs: New test. * rust/rustc/ui/const-generics/intrinsics-type_name-as-const-argument.rs: New test. * rust/rustc/ui/const-generics/invalid-const-arg-for-type-param.rs: New test. * rust/rustc/ui/const-generics/invalid-constant-in-args.rs: New test. * rust/rustc/ui/const-generics/invalid-enum.rs: New test. * rust/rustc/ui/const-generics/issue-61522-array-len-succ.rs: New test. * rust/rustc/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs: New test. * rust/rustc/ui/const-generics/issue-67375.rs: New test. * rust/rustc/ui/const-generics/issue-67945-1.rs: New test. * rust/rustc/ui/const-generics/issue-67945-2.rs: New test. * rust/rustc/ui/const-generics/issue-67945-3.rs: New test. * rust/rustc/ui/const-generics/issue-68104-print-stack-overflow.rs: New test. * rust/rustc/ui/const-generics/issue-70180-1-stalled_on.rs: New test. * rust/rustc/ui/const-generics/issue-70180-2-stalled_on.rs: New test. * rust/rustc/ui/const-generics/issue-71986.rs: New test. * rust/rustc/ui/const-generics/issue-74906.rs: New test. * rust/rustc/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs: New test. * rust/rustc/ui/const-generics/issues/issue-56445.rs: New test. * rust/rustc/ui/const-generics/issues/issue-60263.rs: New test. * rust/rustc/ui/const-generics/issues/issue-60818-struct-constructors.rs: New test. * rust/rustc/ui/const-generics/issues/issue-61336-1.rs: New test. * rust/rustc/ui/const-generics/issues/issue-61336-2.rs: New test. * rust/rustc/ui/const-generics/issues/issue-61336.rs: New test. * rust/rustc/ui/const-generics/issues/issue-61422.rs: New test. * rust/rustc/ui/const-generics/issues/issue-61432.rs: New test. * rust/rustc/ui/const-generics/issues/issue-61747.rs: New test. * rust/rustc/ui/const-generics/issues/issue-61935.rs: New test. * rust/rustc/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs: New test. * rust/rustc/ui/const-generics/issues/issue-62220.rs: New test. * rust/rustc/ui/const-generics/issues/issue-62456.rs: New test. * rust/rustc/ui/const-generics/issues/issue-62504.rs: New test. * rust/rustc/ui/const-generics/issues/issue-62579-no-match.rs: New test. * rust/rustc/ui/const-generics/issues/issue-62878.rs: New test. * rust/rustc/ui/const-generics/issues/issue-63322-forbid-dyn.rs: New test. * rust/rustc/ui/const-generics/issues/issue-64494.rs: New test. * rust/rustc/ui/const-generics/issues/issue-64519.rs: New test. * rust/rustc/ui/const-generics/issues/issue-66205.rs: New test. * rust/rustc/ui/const-generics/issues/issue-66906.rs: New test. * rust/rustc/ui/const-generics/issues/issue-67185-1.rs: New test. * rust/rustc/ui/const-generics/issues/issue-67185-2.rs: New test. * rust/rustc/ui/const-generics/issues/issue-67739.rs: New test. * rust/rustc/ui/const-generics/issues/issue-68366.rs: New test. * rust/rustc/ui/const-generics/issues/issue-68596.rs: New test. * rust/rustc/ui/const-generics/issues/issue-68615-adt.rs: New test. * rust/rustc/ui/const-generics/issues/issue-68615-array.rs: New test. * rust/rustc/ui/const-generics/issues/issue-68977.rs: New test. * rust/rustc/ui/const-generics/issues/issue-69654-run-pass.rs: New test. * rust/rustc/ui/const-generics/issues/issue-69654.rs: New test. * rust/rustc/ui/const-generics/issues/issue-70125-1.rs: New test. * rust/rustc/ui/const-generics/issues/issue-70125-2.rs: New test. * rust/rustc/ui/const-generics/issues/issue-70167.rs: New test. * rust/rustc/ui/const-generics/issues/issue-70225.rs: New test. * rust/rustc/ui/const-generics/issues/issue-71169.rs: New test. * rust/rustc/ui/const-generics/issues/issue-71381.rs: New test. * rust/rustc/ui/const-generics/issues/issue-71382.rs: New test. * rust/rustc/ui/const-generics/issues/issue-71611.rs: New test. * rust/rustc/ui/const-generics/issues/issue-72352.rs: New test. * rust/rustc/ui/const-generics/issues/issue-72787.rs: New test. * rust/rustc/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs: New test. * rust/rustc/ui/const-generics/issues/issue-73120.rs: New test. * rust/rustc/ui/const-generics/issues/issue-73260.rs: New test. * rust/rustc/ui/const-generics/issues/issue-73491.rs: New test. * rust/rustc/ui/const-generics/issues/issue-73508.rs: New test. * rust/rustc/ui/const-generics/issues/issue-74101.rs: New test. * rust/rustc/ui/const-generics/issues/issue-74255.rs: New test. * rust/rustc/ui/const-generics/issues/issue-74634.rs: New test. * rust/rustc/ui/const-generics/issues/issue-74950.rs: New test. * rust/rustc/ui/const-generics/issues/issue-75047.rs: New test. * rust/rustc/ui/const-generics/issues/issue-75299.rs: New test. * rust/rustc/ui/const-generics/issues/issue-76595.rs: New test. * rust/rustc/ui/const-generics/issues/issue-76701-ty-param-in-const.rs: New test. * rust/rustc/ui/const-generics/issues/issue70273-assoc-fn.rs: New test. * rust/rustc/ui/const-generics/macro_rules-braces.rs: New test. * rust/rustc/ui/const-generics/min-and-full-same-time.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/assoc_const.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/complex-expression.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/complex-types.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/const_fn_in_generics.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/default_function_param.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/default_trait_param.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/feature-gate-min_const_generics.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/invalid-patterns.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/macro-fail.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/macro.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/self-ty-in-const-1.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/self-ty-in-const-2.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/static-reference-array-const-param.rs: New test. * rust/rustc/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs: New test. * rust/rustc/ui/const-generics/mut-ref-const-param-array.rs: New test. * rust/rustc/ui/const-generics/nested-type.rs: New test. * rust/rustc/ui/const-generics/occurs-check/bind-param.rs: New test. * rust/rustc/ui/const-generics/occurs-check/unify-fixpoint.rs: New test. * rust/rustc/ui/const-generics/occurs-check/unify-n-nplusone.rs: New test. * rust/rustc/ui/const-generics/occurs-check/unused-substs-1.rs: New test. * rust/rustc/ui/const-generics/occurs-check/unused-substs-2.rs: New test. * rust/rustc/ui/const-generics/occurs-check/unused-substs-3.rs: New test. * rust/rustc/ui/const-generics/occurs-check/unused-substs-4.rs: New test. * rust/rustc/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs: New test. * rust/rustc/ui/const-generics/raw-ptr-const-param-deref.rs: New test. * rust/rustc/ui/const-generics/raw-ptr-const-param.rs: New test. * rust/rustc/ui/const-generics/slice-const-param-mismatch.rs: New test. * rust/rustc/ui/const-generics/slice-const-param.rs: New test. * rust/rustc/ui/const-generics/std/const-generics-range.rs: New test. * rust/rustc/ui/const-generics/struct-with-invalid-const-param.rs: New test. * rust/rustc/ui/const-generics/trait-const-args.rs: New test. * rust/rustc/ui/const-generics/transparent-maybeunit-array-wrapper.rs: New test. * rust/rustc/ui/const-generics/type-after-const-ok.rs: New test. * rust/rustc/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs: New test. * rust/rustc/ui/const-generics/type-dependent/const-arg-in-const-arg.rs: New test. * rust/rustc/ui/const-generics/type-dependent/issue-61936.rs: New test. * rust/rustc/ui/const-generics/type-dependent/issue-63695.rs: New test. * rust/rustc/ui/const-generics/type-dependent/issue-67144-1.rs: New test. * rust/rustc/ui/const-generics/type-dependent/issue-67144-2.rs: New test. * rust/rustc/ui/const-generics/type-dependent/issue-69816.rs: New test. * rust/rustc/ui/const-generics/type-dependent/issue-70217.rs: New test. * rust/rustc/ui/const-generics/type-dependent/issue-70507.rs: New test. * rust/rustc/ui/const-generics/type-dependent/issue-70586.rs: New test. * rust/rustc/ui/const-generics/type-dependent/issue-71348.rs: New test. * rust/rustc/ui/const-generics/type-dependent/issue-71382.rs: New test. * rust/rustc/ui/const-generics/type-dependent/issue-71805.rs: New test. * rust/rustc/ui/const-generics/type-dependent/issue-73730.rs: New test. * rust/rustc/ui/const-generics/type-dependent/non-local.rs: New test. * rust/rustc/ui/const-generics/type-dependent/qpath.rs: New test. * rust/rustc/ui/const-generics/type-dependent/simple.rs: New test. * rust/rustc/ui/const-generics/type-dependent/type-mismatch.rs: New test. * rust/rustc/ui/const-generics/type_of_anon_const.rs: New test. * rust/rustc/ui/const-generics/types-mismatch-const-args.rs: New test. * rust/rustc/ui/const-generics/uninferred-consts-during-codegen-1.rs: New test. * rust/rustc/ui/const-generics/uninferred-consts-during-codegen-2.rs: New test. * rust/rustc/ui/const-generics/unknown_adt.rs: New test. * rust/rustc/ui/const-generics/unused-const-param.rs: New test. * rust/rustc/ui/const-generics/unused_braces.rs: New test. * rust/rustc/ui/const-generics/wf-misc.rs: New test. * rust/rustc/ui/const-generics/where-clauses.rs: New test. * rust/rustc/ui/const-suggest-feature.rs: New test. * rust/rustc/ui/const_evaluatable/associated-const.rs: New test. * rust/rustc/ui/const_evaluatable/function-call.rs: New test. * rust/rustc/ui/const_prop/ice-assert-fail-div-by-zero.rs: New test. * rust/rustc/ui/const_prop/inline_spans.rs: New test. * rust/rustc/ui/constructor-lifetime-args.rs: New test. * rust/rustc/ui/consts/array-literal-index-oob.rs: New test. * rust/rustc/ui/consts/array-to-slice-cast.rs: New test. * rust/rustc/ui/consts/ascii_ctype.rs: New test. * rust/rustc/ui/consts/assoc-const.rs: New test. * rust/rustc/ui/consts/assoc_const_generic_impl.rs: New test. * rust/rustc/ui/consts/associated_const_generic.rs: New test. * rust/rustc/ui/consts/async-block.rs: New test. * rust/rustc/ui/consts/auxiliary/cci_borrow_lib.rs: New test. * rust/rustc/ui/consts/auxiliary/cci_const.rs: New test. * rust/rustc/ui/consts/auxiliary/cci_const_block.rs: New test. * rust/rustc/ui/consts/auxiliary/const_fn_lib.rs: New test. * rust/rustc/ui/consts/auxiliary/external_macro.rs: New test. * rust/rustc/ui/consts/auxiliary/issue-63226.rs: New test. * rust/rustc/ui/consts/auxiliary/promotable_const_fn_lib.rs: New test. * rust/rustc/ui/consts/bswap-const.rs: New test. * rust/rustc/ui/consts/cast-discriminant-zst-enum.rs: New test. * rust/rustc/ui/consts/chained-constants-stackoverflow.rs: New test. * rust/rustc/ui/consts/const-address-of-interior-mut.rs: New test. * rust/rustc/ui/consts/const-address-of-mut.rs: New test. * rust/rustc/ui/consts/const-address-of.rs: New test. * rust/rustc/ui/consts/const-adt-align-mismatch.rs: New test. * rust/rustc/ui/consts/const-array-oob-arith.rs: New test. * rust/rustc/ui/consts/const-array-oob.rs: New test. * rust/rustc/ui/consts/const-autoderef.rs: New test. * rust/rustc/ui/consts/const-big-enum.rs: New test. * rust/rustc/ui/consts/const-binops.rs: New test. * rust/rustc/ui/consts/const-bitshift-rhs-inference.rs: New test. * rust/rustc/ui/consts/const-block-cross-crate-fn.rs: New test. * rust/rustc/ui/consts/const-block-item-macro-codegen.rs: New test. * rust/rustc/ui/consts/const-block-item.rs: New test. * rust/rustc/ui/consts/const-block-non-item-statement-3.rs: New test. * rust/rustc/ui/consts/const-block-non-item-statement-rpass.rs: New test. * rust/rustc/ui/consts/const-block-non-item-statement.rs: New test. * rust/rustc/ui/consts/const-block.rs: New test. * rust/rustc/ui/consts/const-bound.rs: New test. * rust/rustc/ui/consts/const-byte-str-cast.rs: New test. * rust/rustc/ui/consts/const-call.rs: New test. * rust/rustc/ui/consts/const-cast-different-types.rs: New test. * rust/rustc/ui/consts/const-cast-ptr-int.rs: New test. * rust/rustc/ui/consts/const-cast-wrong-type.rs: New test. * rust/rustc/ui/consts/const-cast.rs: New test. * rust/rustc/ui/consts/const-const.rs: New test. * rust/rustc/ui/consts/const-contents.rs: New test. * rust/rustc/ui/consts/const-cross-crate-const.rs: New test. * rust/rustc/ui/consts/const-cross-crate-extern.rs: New test. * rust/rustc/ui/consts/const-deref-ptr.rs: New test. * rust/rustc/ui/consts/const-deref.rs: New test. * rust/rustc/ui/consts/const-endianess.rs: New test. * rust/rustc/ui/consts/const-enum-byref-self.rs: New test. * rust/rustc/ui/consts/const-enum-byref.rs: New test. * rust/rustc/ui/consts/const-enum-cast.rs: New test. * rust/rustc/ui/consts/const-enum-ptr.rs: New test. * rust/rustc/ui/consts/const-enum-struct.rs: New test. * rust/rustc/ui/consts/const-enum-struct2.rs: New test. * rust/rustc/ui/consts/const-enum-structlike.rs: New test. * rust/rustc/ui/consts/const-enum-tuple.rs: New test. * rust/rustc/ui/consts/const-enum-tuple2.rs: New test. * rust/rustc/ui/consts/const-enum-tuplestruct.rs: New test. * rust/rustc/ui/consts/const-enum-tuplestruct2.rs: New test. * rust/rustc/ui/consts/const-enum-vec-index.rs: New test. * rust/rustc/ui/consts/const-enum-vec-ptr.rs: New test. * rust/rustc/ui/consts/const-enum-vector.rs: New test. * rust/rustc/ui/consts/const-err-early.rs: New test. * rust/rustc/ui/consts/const-err-multi.rs: New test. * rust/rustc/ui/consts/const-err-rpass.rs: New test. * rust/rustc/ui/consts/const-err.rs: New test. * rust/rustc/ui/consts/const-err2.rs: New test. * rust/rustc/ui/consts/const-err4.rs: New test. * rust/rustc/ui/consts/const-eval/assign-to-static-within-other-static-2.rs: New test. * rust/rustc/ui/consts/const-eval/assign-to-static-within-other-static.rs: New test. * rust/rustc/ui/consts/const-eval/auxiliary/stability.rs: New test. * rust/rustc/ui/consts/const-eval/conditional_array_execution.rs: New test. * rust/rustc/ui/consts/const-eval/const-eval-intrinsic-promotion.rs: New test. * rust/rustc/ui/consts/const-eval/const-eval-overflow-2.rs: New test. * rust/rustc/ui/consts/const-eval/const-eval-overflow-3.rs: New test. * rust/rustc/ui/consts/const-eval/const-eval-overflow-3b.rs: New test. * rust/rustc/ui/consts/const-eval/const-eval-overflow-4.rs: New test. * rust/rustc/ui/consts/const-eval/const-eval-overflow-4b.rs: New test. * rust/rustc/ui/consts/const-eval/const-eval-overflow2.rs: New test. * rust/rustc/ui/consts/const-eval/const-eval-overflow2b.rs: New test. * rust/rustc/ui/consts/const-eval/const-eval-overflow2c.rs: New test. * rust/rustc/ui/consts/const-eval/const-eval-query-stack.rs: New test. * rust/rustc/ui/consts/const-eval/const-eval-span.rs: New test. * rust/rustc/ui/consts/const-eval/const-pointer-values-in-various-types.rs: New test. * rust/rustc/ui/consts/const-eval/const_fn_ptr.rs: New test. * rust/rustc/ui/consts/const-eval/const_fn_ptr_fail.rs: New test. * rust/rustc/ui/consts/const-eval/const_fn_ptr_fail2.rs: New test. * rust/rustc/ui/consts/const-eval/const_let.rs: New test. * rust/rustc/ui/consts/const-eval/const_panic.rs: New test. * rust/rustc/ui/consts/const-eval/const_panic_libcore_bin.rs: New test. * rust/rustc/ui/consts/const-eval/const_prop_errors.rs: New test. * rust/rustc/ui/consts/const-eval/const_raw_ptr_ops.rs: New test. * rust/rustc/ui/consts/const-eval/const_raw_ptr_ops2.rs: New test. * rust/rustc/ui/consts/const-eval/const_signed_pat.rs: New test. * rust/rustc/ui/consts/const-eval/const_transmute.rs: New test. * rust/rustc/ui/consts/const-eval/dangling.rs: New test. * rust/rustc/ui/consts/const-eval/dont_promote_unstable_const_fn.rs: New test. * rust/rustc/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs: New test. * rust/rustc/ui/consts/const-eval/double_check.rs: New test. * rust/rustc/ui/consts/const-eval/double_check2.rs: New test. * rust/rustc/ui/consts/const-eval/double_promotion.rs: New test. * rust/rustc/ui/consts/const-eval/duration_conversion.rs: New test. * rust/rustc/ui/consts/const-eval/enum_discr.rs: New test. * rust/rustc/ui/consts/const-eval/erroneous-const.rs: New test. * rust/rustc/ui/consts/const-eval/extern_fat_pointer.rs: New test. * rust/rustc/ui/consts/const-eval/feature-gate-const_fn_union.rs: New test. * rust/rustc/ui/consts/const-eval/feature-gate-const_panic.rs: New test. * rust/rustc/ui/consts/const-eval/generic-slice.rs: New test. * rust/rustc/ui/consts/const-eval/ice-generic-assoc-const.rs: New test. * rust/rustc/ui/consts/const-eval/ice-packed.rs: New test. * rust/rustc/ui/consts/const-eval/index-out-of-bounds-never-type.rs: New test. * rust/rustc/ui/consts/const-eval/index_out_of_bounds.rs: New test. * rust/rustc/ui/consts/const-eval/index_out_of_bounds_propagated.rs: New test. * rust/rustc/ui/consts/const-eval/infinite_loop.rs: New test. * rust/rustc/ui/consts/const-eval/issue-43197.rs: New test. * rust/rustc/ui/consts/const-eval/issue-44578.rs: New test. * rust/rustc/ui/consts/const-eval/issue-47971.rs: New test. * rust/rustc/ui/consts/const-eval/issue-49296.rs: New test. * rust/rustc/ui/consts/const-eval/issue-50706.rs: New test. * rust/rustc/ui/consts/const-eval/issue-50814-2.rs: New test. * rust/rustc/ui/consts/const-eval/issue-50814.rs: New test. * rust/rustc/ui/consts/const-eval/issue-51300.rs: New test. * rust/rustc/ui/consts/const-eval/issue-52442.rs: New test. * rust/rustc/ui/consts/const-eval/issue-52475.rs: New test. * rust/rustc/ui/consts/const-eval/issue-53157.rs: New test. * rust/rustc/ui/consts/const-eval/issue-53401.rs: New test. * rust/rustc/ui/consts/const-eval/issue-55541.rs: New test. * rust/rustc/ui/consts/const-eval/issue-64908.rs: New test. * rust/rustc/ui/consts/const-eval/issue-64970.rs: New test. * rust/rustc/ui/consts/const-eval/issue-65394.rs: New test. * rust/rustc/ui/consts/const-eval/issue-70723.rs: New test. * rust/rustc/ui/consts/const-eval/issue-70804-fn-subtyping.rs: New test. * rust/rustc/ui/consts/const-eval/livedrop.rs: New test. * rust/rustc/ui/consts/const-eval/match-test-ptr-null.rs: New test. * rust/rustc/ui/consts/const-eval/mod-static-with-const-fn.rs: New test. * rust/rustc/ui/consts/const-eval/no_lint_for_statically_known_error.rs: New test. * rust/rustc/ui/consts/const-eval/nrvo.rs: New test. * rust/rustc/ui/consts/const-eval/panic-assoc-never-type.rs: New test. * rust/rustc/ui/consts/const-eval/panic-never-type.rs: New test. * rust/rustc/ui/consts/const-eval/promote-static.rs: New test. * rust/rustc/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs: New test. * rust/rustc/ui/consts/const-eval/promoted_const_fn_fail.rs: New test. * rust/rustc/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs: New test. * rust/rustc/ui/consts/const-eval/promoted_errors.rs: New test. * rust/rustc/ui/consts/const-eval/promoted_raw_ptr_ops.rs: New test. * rust/rustc/ui/consts/const-eval/pub_const_err.rs: New test. * rust/rustc/ui/consts/const-eval/pub_const_err_bin.rs: New test. * rust/rustc/ui/consts/const-eval/ref_to_int_match.rs: New test. * rust/rustc/ui/consts/const-eval/shift_overflow.rs: New test. * rust/rustc/ui/consts/const-eval/simd/insert_extract.rs: New test. * rust/rustc/ui/consts/const-eval/simple_with_undef.rs: New test. * rust/rustc/ui/consts/const-eval/strlen.rs: New test. * rust/rustc/ui/consts/const-eval/transmute-const-promotion.rs: New test. * rust/rustc/ui/consts/const-eval/transmute-const.rs: New test. * rust/rustc/ui/consts/const-eval/ub-enum.rs: New test. * rust/rustc/ui/consts/const-eval/ub-int-array.rs: New test. * rust/rustc/ui/consts/const-eval/ub-nonnull.rs: New test. * rust/rustc/ui/consts/const-eval/ub-ref.rs: New test. * rust/rustc/ui/consts/const-eval/ub-uninhabit.rs: New test. * rust/rustc/ui/consts/const-eval/ub-upvars.rs: New test. * rust/rustc/ui/consts/const-eval/ub-wide-ptr.rs: New test. * rust/rustc/ui/consts/const-eval/union-const-eval-field.rs: New test. * rust/rustc/ui/consts/const-eval/union-ice.rs: New test. * rust/rustc/ui/consts/const-eval/union-ub.rs: New test. * rust/rustc/ui/consts/const-eval/union_promotion.rs: New test. * rust/rustc/ui/consts/const-eval/unused-broken-const.rs: New test. * rust/rustc/ui/consts/const-eval/unwind-abort.rs: New test. * rust/rustc/ui/consts/const-eval/valid-const.rs: New test. * rust/rustc/ui/consts/const-eval/validate_uninhabited_zsts.rs: New test. * rust/rustc/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs: New test. * rust/rustc/ui/consts/const-eval/zst_operand_eval.rs: New test. * rust/rustc/ui/consts/const-expr-addr-operator.rs: New test. * rust/rustc/ui/consts/const-expr-in-fixed-length-vec.rs: New test. * rust/rustc/ui/consts/const-expr-in-vec-repeat.rs: New test. * rust/rustc/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.rs: New test. * rust/rustc/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs: New test. * rust/rustc/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs: New test. * rust/rustc/ui/consts/const-extern-fn/const-extern-fn.rs: New test. * rust/rustc/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs: New test. * rust/rustc/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs: New test. * rust/rustc/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs: New test. * rust/rustc/ui/consts/const-extern-function.rs: New test. * rust/rustc/ui/consts/const-external-macro-const-err.rs: New test. * rust/rustc/ui/consts/const-fields-and-indexing.rs: New test. * rust/rustc/ui/consts/const-float-bits-conv.rs: New test. * rust/rustc/ui/consts/const-float-classify.rs: New test. * rust/rustc/ui/consts/const-fn-const-eval.rs: New test. * rust/rustc/ui/consts/const-fn-destructuring-arg.rs: New test. * rust/rustc/ui/consts/const-fn-feature-flags.rs: New test. * rust/rustc/ui/consts/const-fn-method.rs: New test. * rust/rustc/ui/consts/const-fn-mismatch.rs: New test. * rust/rustc/ui/consts/const-fn-nested.rs: New test. * rust/rustc/ui/consts/const-fn-not-in-trait.rs: New test. * rust/rustc/ui/consts/const-fn-not-safe-for-const.rs: New test. * rust/rustc/ui/consts/const-fn-stability-calls-3.rs: New test. * rust/rustc/ui/consts/const-fn-stability-calls.rs: New test. * rust/rustc/ui/consts/const-fn-type-name-any.rs: New test. * rust/rustc/ui/consts/const-fn-type-name.rs: New test. * rust/rustc/ui/consts/const-fn-val.rs: New test. * rust/rustc/ui/consts/const-fn-zst-args.rs: New test. * rust/rustc/ui/consts/const-fn.rs: New test. * rust/rustc/ui/consts/const-index-feature-gate.rs: New test. * rust/rustc/ui/consts/const-int-arithmetic-overflow.rs: New test. * rust/rustc/ui/consts/const-int-arithmetic.rs: New test. * rust/rustc/ui/consts/const-int-conversion-rpass.rs: New test. * rust/rustc/ui/consts/const-int-conversion.rs: New test. * rust/rustc/ui/consts/const-int-overflowing-rpass.rs: New test. * rust/rustc/ui/consts/const-int-overflowing.rs: New test. * rust/rustc/ui/consts/const-int-pow-rpass.rs: New test. * rust/rustc/ui/consts/const-int-rotate-rpass.rs: New test. * rust/rustc/ui/consts/const-int-rotate.rs: New test. * rust/rustc/ui/consts/const-int-saturating-arith.rs: New test. * rust/rustc/ui/consts/const-int-sign-rpass.rs: New test. * rust/rustc/ui/consts/const-int-sign.rs: New test. * rust/rustc/ui/consts/const-int-unchecked.rs: New test. * rust/rustc/ui/consts/const-int-wrapping-rpass.rs: New test. * rust/rustc/ui/consts/const-int-wrapping.rs: New test. * rust/rustc/ui/consts/const-integer-bool-ops.rs: New test. * rust/rustc/ui/consts/const-labeled-break.rs: New test. * rust/rustc/ui/consts/const-len-underflow-separate-spans.rs: New test. * rust/rustc/ui/consts/const-len-underflow-subspans.rs: New test. * rust/rustc/ui/consts/const-match-check.rs: New test. * rust/rustc/ui/consts/const-match-pattern-arm.rs: New test. * rust/rustc/ui/consts/const-meth-pattern.rs: New test. * rust/rustc/ui/consts/const-multi-ref.rs: New test. * rust/rustc/ui/consts/const-mut-refs/const_mut_address_of.rs: New test. * rust/rustc/ui/consts/const-mut-refs/const_mut_refs.rs: New test. * rust/rustc/ui/consts/const-mut-refs/feature-gate-const_mut_refs.rs: New test. * rust/rustc/ui/consts/const-needs_drop.rs: New test. * rust/rustc/ui/consts/const-negation.rs: New test. * rust/rustc/ui/consts/const-negative.rs: New test. * rust/rustc/ui/consts/const-nullary-enum.rs: New test. * rust/rustc/ui/consts/const-nullary-univariant-enum.rs: New test. * rust/rustc/ui/consts/const-pattern-irrefutable.rs: New test. * rust/rustc/ui/consts/const-pattern-not-const-evaluable.rs: New test. * rust/rustc/ui/consts/const-pattern-variant.rs: New test. * rust/rustc/ui/consts/const-points-to-static.rs: New test. * rust/rustc/ui/consts/const-prop-ice.rs: New test. * rust/rustc/ui/consts/const-prop-ice2.rs: New test. * rust/rustc/ui/consts/const-prop-ice3.rs: New test. * rust/rustc/ui/consts/const-prop-overflowing-casts.rs: New test. * rust/rustc/ui/consts/const-prop-read-static-in-const.rs: New test. * rust/rustc/ui/consts/const-ptr-nonnull-rpass.rs: New test. * rust/rustc/ui/consts/const-ptr-nonnull.rs: New test. * rust/rustc/ui/consts/const-ptr-unique-rpass.rs: New test. * rust/rustc/ui/consts/const-ptr-unique.rs: New test. * rust/rustc/ui/consts/const-rec-and-tup.rs: New test. * rust/rustc/ui/consts/const-region-ptrs-noncopy.rs: New test. * rust/rustc/ui/consts/const-region-ptrs.rs: New test. * rust/rustc/ui/consts/const-repeated-values.rs: New test. * rust/rustc/ui/consts/const-size_of-align_of.rs: New test. * rust/rustc/ui/consts/const-size_of-cycle.rs: New test. * rust/rustc/ui/consts/const-size_of_val-align_of_val-extern-type.rs: New test. * rust/rustc/ui/consts/const-size_of_val-align_of_val.rs: New test. * rust/rustc/ui/consts/const-slice-oob.rs: New test. * rust/rustc/ui/consts/const-str-ptr.rs: New test. * rust/rustc/ui/consts/const-struct-offsets.rs: New test. * rust/rustc/ui/consts/const-struct.rs: New test. * rust/rustc/ui/consts/const-trait-to-trait.rs: New test. * rust/rustc/ui/consts/const-tup-index-span.rs: New test. * rust/rustc/ui/consts/const-tuple-struct.rs: New test. * rust/rustc/ui/consts/const-type-mismatch.rs: New test. * rust/rustc/ui/consts/const-typeid-of-rpass.rs: New test. * rust/rustc/ui/consts/const-unit-struct.rs: New test. * rust/rustc/ui/consts/const-unsafe-fn.rs: New test. * rust/rustc/ui/consts/const-unsized.rs: New test. * rust/rustc/ui/consts/const-unwrap.rs: New test. * rust/rustc/ui/consts/const-validation-fail-55455.rs: New test. * rust/rustc/ui/consts/const-variant-count.rs: New test. * rust/rustc/ui/consts/const-vec-of-fns.rs: New test. * rust/rustc/ui/consts/const-vec-syntax.rs: New test. * rust/rustc/ui/consts/const-vecs-and-slices.rs: New test. * rust/rustc/ui/consts/const.rs: New test. * rust/rustc/ui/consts/const_arg_local.rs: New test. * rust/rustc/ui/consts/const_arg_promotable.rs: New test. * rust/rustc/ui/consts/const_arg_promotable2.rs: New test. * rust/rustc/ui/consts/const_arg_wrapper.rs: New test. * rust/rustc/ui/consts/const_constructor/const-construct-call.rs: New test. * rust/rustc/ui/consts/const_constructor/const_constructor_qpath.rs: New test. * rust/rustc/ui/consts/const_discriminant.rs: New test. * rust/rustc/ui/consts/const_fn_floating_point_arithmetic.rs: New test. * rust/rustc/ui/consts/const_fn_return_nested_fn_ptr.rs: New test. * rust/rustc/ui/consts/const_forget.rs: New test. * rust/rustc/ui/consts/const_in_pattern/accept_structural.rs: New test. * rust/rustc/ui/consts/const_in_pattern/auxiliary/consts.rs: New test. * rust/rustc/ui/consts/const_in_pattern/cross-crate-fail.rs: New test. * rust/rustc/ui/consts/const_in_pattern/cross-crate-pass.rs: New test. * rust/rustc/ui/consts/const_in_pattern/custom-eq-branch-pass.rs: New test. * rust/rustc/ui/consts/const_in_pattern/custom-eq-branch-warn.rs: New test. * rust/rustc/ui/consts/const_in_pattern/issue-44333.rs: New test. * rust/rustc/ui/consts/const_in_pattern/issue-53708.rs: New test. * rust/rustc/ui/consts/const_in_pattern/issue-62614.rs: New test. * rust/rustc/ui/consts/const_in_pattern/issue-65466.rs: New test. * rust/rustc/ui/consts/const_in_pattern/issue-73431.rs: New test. * rust/rustc/ui/consts/const_in_pattern/issue-78057.rs: New test. * rust/rustc/ui/consts/const_in_pattern/no-eq-branch-fail.rs: New test. * rust/rustc/ui/consts/const_in_pattern/reject_non_partial_eq.rs: New test. * rust/rustc/ui/consts/const_in_pattern/reject_non_structural.rs: New test. * rust/rustc/ui/consts/const_in_pattern/warn_corner_cases.rs: New test. * rust/rustc/ui/consts/const_let_assign.rs: New test. * rust/rustc/ui/consts/const_let_assign2.rs: New test. * rust/rustc/ui/consts/const_let_assign3.rs: New test. * rust/rustc/ui/consts/const_let_eq.rs: New test. * rust/rustc/ui/consts/const_let_eq_float.rs: New test. * rust/rustc/ui/consts/const_let_irrefutable.rs: New test. * rust/rustc/ui/consts/const_let_promote.rs: New test. * rust/rustc/ui/consts/const_let_refutable.rs: New test. * rust/rustc/ui/consts/const_limit/const_eval_limit_not_reached.rs: New test. * rust/rustc/ui/consts/const_limit/const_eval_limit_overflow.rs: New test. * rust/rustc/ui/consts/const_limit/const_eval_limit_reached.rs: New test. * rust/rustc/ui/consts/const_limit/feature-gate-const_eval_limit.rs: New test. * rust/rustc/ui/consts/const_prop_slice_pat_ice.rs: New test. * rust/rustc/ui/consts/const_short_circuit.rs: New test. * rust/rustc/ui/consts/const_unsafe_unreachable.rs: New test. * rust/rustc/ui/consts/const_unsafe_unreachable_ub.rs: New test. * rust/rustc/ui/consts/consts-in-patterns.rs: New test. * rust/rustc/ui/consts/control-flow/assert.rs: New test. * rust/rustc/ui/consts/control-flow/basics.rs: New test. * rust/rustc/ui/consts/control-flow/drop-fail.rs: New test. * rust/rustc/ui/consts/control-flow/drop-pass.rs: New test. * rust/rustc/ui/consts/control-flow/drop-precise.rs: New test. * rust/rustc/ui/consts/control-flow/exhaustive-c-like-enum-match.rs: New test. * rust/rustc/ui/consts/control-flow/feature-gate-const-if-match.rs: New test. * rust/rustc/ui/consts/control-flow/interior-mutability.rs: New test. * rust/rustc/ui/consts/control-flow/issue-46843.rs: New test. * rust/rustc/ui/consts/control-flow/issue-50577.rs: New test. * rust/rustc/ui/consts/control-flow/loop.rs: New test. * rust/rustc/ui/consts/control-flow/short-circuit-let.rs: New test. * rust/rustc/ui/consts/control-flow/short-circuit.rs: New test. * rust/rustc/ui/consts/control-flow/single_variant_match_ice.rs: New test. * rust/rustc/ui/consts/control-flow/try.rs: New test. * rust/rustc/ui/consts/dangling-alloc-id-ice.rs: New test. * rust/rustc/ui/consts/dangling_raw_ptr.rs: New test. * rust/rustc/ui/consts/deref_in_pattern.rs: New test. * rust/rustc/ui/consts/drop_none.rs: New test. * rust/rustc/ui/consts/enum-discr-type-err.rs: New test. * rust/rustc/ui/consts/huge-values.rs: New test. * rust/rustc/ui/consts/ice-48279.rs: New test. * rust/rustc/ui/consts/ice-zst-static-access.rs: New test. * rust/rustc/ui/consts/inline_asm.rs: New test. * rust/rustc/ui/consts/int_ptr_for_zst_slices.rs: New test. * rust/rustc/ui/consts/invalid_promotion.rs: New test. * rust/rustc/ui/consts/issue-37550.rs: New test. * rust/rustc/ui/consts/issue-51559.rs: New test. * rust/rustc/ui/consts/issue-52432.rs: New test. * rust/rustc/ui/consts/issue-54224.rs: New test. * rust/rustc/ui/consts/issue-56164.rs: New test. * rust/rustc/ui/consts/issue-62045.rs: New test. * rust/rustc/ui/consts/issue-63226.rs: New test. * rust/rustc/ui/consts/issue-63952.rs: New test. * rust/rustc/ui/consts/issue-64059.rs: New test. * rust/rustc/ui/consts/issue-64506.rs: New test. * rust/rustc/ui/consts/issue-64662.rs: New test. * rust/rustc/ui/consts/issue-65348.rs: New test. * rust/rustc/ui/consts/issue-66342.rs: New test. * rust/rustc/ui/consts/issue-66345.rs: New test. * rust/rustc/ui/consts/issue-66397.rs: New test. * rust/rustc/ui/consts/issue-66787.rs: New test. * rust/rustc/ui/consts/issue-67529.rs: New test. * rust/rustc/ui/consts/issue-67640.rs: New test. * rust/rustc/ui/consts/issue-67641.rs: New test. * rust/rustc/ui/consts/issue-67696-const-prop-ice.rs: New test. * rust/rustc/ui/consts/issue-67862.rs: New test. * rust/rustc/ui/consts/issue-68264-overflow.rs: New test. * rust/rustc/ui/consts/issue-68542-closure-in-array-len.rs: New test. * rust/rustc/ui/consts/issue-68684.rs: New test. * rust/rustc/ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs: New test. * rust/rustc/ui/consts/issue-69310-array-size-lit-wrong-ty.rs: New test. * rust/rustc/ui/consts/issue-69312.rs: New test. * rust/rustc/ui/consts/issue-70773-mir-typeck-lt-norm.rs: New test. * rust/rustc/ui/consts/issue-70942-trait-vs-impl-mismatch.rs: New test. * rust/rustc/ui/consts/issue-73976-monomorphic.rs: New test. * rust/rustc/ui/consts/issue-73976-polymorphic.rs: New test. * rust/rustc/ui/consts/issue-77062-large-zst-array.rs: New test. * rust/rustc/ui/consts/issue-78655.rs: New test. * rust/rustc/ui/consts/issue-broken-mir.rs: New test. * rust/rustc/ui/consts/locals-in-const-fn.rs: New test. * rust/rustc/ui/consts/match-const-fn-structs.rs: New test. * rust/rustc/ui/consts/match_ice.rs: New test. * rust/rustc/ui/consts/min_const_fn/address_of.rs: New test. * rust/rustc/ui/consts/min_const_fn/address_of_const.rs: New test. * rust/rustc/ui/consts/min_const_fn/allow_const_fn_ptr.rs: New test. * rust/rustc/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs: New test. * rust/rustc/ui/consts/min_const_fn/allow_raw_ptr_dereference_const_fn.rs: New test. * rust/rustc/ui/consts/min_const_fn/bad_const_fn_body_ice.rs: New test. * rust/rustc/ui/consts/min_const_fn/cast_errors.rs: New test. * rust/rustc/ui/consts/min_const_fn/cmp_fn_pointers.rs: New test. * rust/rustc/ui/consts/min_const_fn/min_const_fn.rs: New test. * rust/rustc/ui/consts/min_const_fn/min_const_fn_dyn.rs: New test. * rust/rustc/ui/consts/min_const_fn/min_const_fn_fn_ptr.rs: New test. * rust/rustc/ui/consts/min_const_fn/min_const_fn_impl_trait.rs: New test. * rust/rustc/ui/consts/min_const_fn/min_const_fn_libstd.rs: New test. * rust/rustc/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs: New test. * rust/rustc/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs: New test. * rust/rustc/ui/consts/min_const_fn/min_const_fn_unsafe_ok.rs: New test. * rust/rustc/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs: New test. * rust/rustc/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs: New test. * rust/rustc/ui/consts/min_const_fn/mutable_borrow.rs: New test. * rust/rustc/ui/consts/min_const_fn/promotion.rs: New test. * rust/rustc/ui/consts/miri_unleashed/abi-mismatch.rs: New test. * rust/rustc/ui/consts/miri_unleashed/assoc_const.rs: New test. * rust/rustc/ui/consts/miri_unleashed/assoc_const_2.rs: New test. * rust/rustc/ui/consts/miri_unleashed/auxiliary/static_cross_crate.rs: New test. * rust/rustc/ui/consts/miri_unleashed/box.rs: New test. * rust/rustc/ui/consts/miri_unleashed/const_refers_to_static.rs: New test. * rust/rustc/ui/consts/miri_unleashed/const_refers_to_static2.rs: New test. * rust/rustc/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs: New test. * rust/rustc/ui/consts/miri_unleashed/drop.rs: New test. * rust/rustc/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs: New test. * rust/rustc/ui/consts/miri_unleashed/inline_asm.rs: New test. * rust/rustc/ui/consts/miri_unleashed/mutable_references.rs: New test. * rust/rustc/ui/consts/miri_unleashed/mutable_references_err.rs: New test. * rust/rustc/ui/consts/miri_unleashed/mutating_global.rs: New test. * rust/rustc/ui/consts/miri_unleashed/non_const_fn.rs: New test. * rust/rustc/ui/consts/miri_unleashed/ptr_arith.rs: New test. * rust/rustc/ui/consts/miri_unleashed/raw_mutable_const.rs: New test. * rust/rustc/ui/consts/miri_unleashed/slice_eq.rs: New test. * rust/rustc/ui/consts/miri_unleashed/tls.rs: New test. * rust/rustc/ui/consts/mozjs-error.rs: New test. * rust/rustc/ui/consts/non-scalar-cast.rs: New test. * rust/rustc/ui/consts/offset.rs: New test. * rust/rustc/ui/consts/offset_from.rs: New test. * rust/rustc/ui/consts/offset_from_ub.rs: New test. * rust/rustc/ui/consts/offset_ub.rs: New test. * rust/rustc/ui/consts/packed_pattern.rs: New test. * rust/rustc/ui/consts/packed_pattern2.rs: New test. * rust/rustc/ui/consts/partial_qualif.rs: New test. * rust/rustc/ui/consts/projection_qualif.rs: New test. * rust/rustc/ui/consts/promote-not.rs: New test. * rust/rustc/ui/consts/promote_borrowed_field.rs: New test. * rust/rustc/ui/consts/promote_const_let.rs: New test. * rust/rustc/ui/consts/promote_evaluation_unused_result.rs: New test. * rust/rustc/ui/consts/promote_fn_calls.rs: New test. * rust/rustc/ui/consts/promote_fn_calls_std.rs: New test. * rust/rustc/ui/consts/promoted-validation-55454.rs: New test. * rust/rustc/ui/consts/promoted_div_by_zero.rs: New test. * rust/rustc/ui/consts/promoted_regression.rs: New test. * rust/rustc/ui/consts/promotion-mutable-ref.rs: New test. * rust/rustc/ui/consts/promotion.rs: New test. * rust/rustc/ui/consts/ptr_comparisons.rs: New test. * rust/rustc/ui/consts/ptr_is_null.rs: New test. * rust/rustc/ui/consts/qualif_overwrite.rs: New test. * rust/rustc/ui/consts/qualif_overwrite_2.rs: New test. * rust/rustc/ui/consts/raw-ptr-const.rs: New test. * rust/rustc/ui/consts/raw_pointer_promoted.rs: New test. * rust/rustc/ui/consts/read_from_static_mut_ref.rs: New test. * rust/rustc/ui/consts/recursive-zst-static.rs: New test. * rust/rustc/ui/consts/references.rs: New test. * rust/rustc/ui/consts/repeat_match.rs: New test. * rust/rustc/ui/consts/return-in-const-fn.rs: New test. * rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/fn-call-in-const.rs: New test. * rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/fn-call-in-non-const.rs: New test. * rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.rs: New test. * rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-pass.rs: New test. * rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.rs: New test. * rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/nll-pass.rs: New test. * rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/run-pass.rs: New test. * rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.rs: New test. * rust/rustc/ui/consts/self_normalization.rs: New test. * rust/rustc/ui/consts/self_normalization2.rs: New test. * rust/rustc/ui/consts/signed_enum_discr.rs: New test. * rust/rustc/ui/consts/stable-precise-live-drops-in-libcore.rs: New test. * rust/rustc/ui/consts/static-cycle-error.rs: New test. * rust/rustc/ui/consts/static-raw-pointer-interning.rs: New test. * rust/rustc/ui/consts/static-raw-pointer-interning2.rs: New test. * rust/rustc/ui/consts/static_mut_containing_mut_ref.rs: New test. * rust/rustc/ui/consts/static_mut_containing_mut_ref2.rs: New test. * rust/rustc/ui/consts/static_mut_containing_mut_ref3.rs: New test. * rust/rustc/ui/consts/std/alloc.rs: New test. * rust/rustc/ui/consts/std/cell.rs: New test. * rust/rustc/ui/consts/std/iter.rs: New test. * rust/rustc/ui/consts/std/slice.rs: New test. * rust/rustc/ui/consts/too_generic_eval_ice.rs: New test. * rust/rustc/ui/consts/trait_specialization.rs: New test. * rust/rustc/ui/consts/transmute-const.rs: New test. * rust/rustc/ui/consts/transmute-size-mismatch-before-typeck.rs: New test. * rust/rustc/ui/consts/tuple-struct-constructors.rs: New test. * rust/rustc/ui/consts/underscore_const_names.rs: New test. * rust/rustc/ui/consts/uninhabited-const-issue-61744.rs: New test. * rust/rustc/ui/consts/union_constant.rs: New test. * rust/rustc/ui/consts/unsizing-cast-non-null.rs: New test. * rust/rustc/ui/consts/unstable-const-fn-in-libcore.rs: New test. * rust/rustc/ui/consts/unstable-precise-live-drops-in-libcore.rs: New test. * rust/rustc/ui/consts/unwind-abort.rs: New test. * rust/rustc/ui/consts/validate_never_arrays.rs: New test. * rust/rustc/ui/consts/zst_no_llvm_alloc.rs: New test. * rust/rustc/ui/continue-after-missing-main.rs: New test. * rust/rustc/ui/conversion-methods.rs: New test. * rust/rustc/ui/copy-a-resource.rs: New test. * rust/rustc/ui/core-run-destroy.rs: New test. * rust/rustc/ui/crate-in-paths.rs: New test. * rust/rustc/ui/crate-leading-sep.rs: New test. * rust/rustc/ui/crate-method-reexport-grrrrrrr.rs: New test. * rust/rustc/ui/crate-name-attr-used.rs: New test. * rust/rustc/ui/crate-name-mismatch.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/anon_trait_static_method_lib.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/cci_borrow_lib.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/cci_capture_clause.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/cci_const.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/cci_impl_lib.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/cci_iter_lib.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/cci_nested_lib.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/cci_no_inline_lib.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/moves_based_on_type_lib.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/newtype_struct_xc.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/pub_static_array.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/reexported_static_methods.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/xcrate_address_insignificant.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/xcrate_associated_type_defaults.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/xcrate_static_addresses.rs: New test. * rust/rustc/ui/cross-crate/auxiliary/xcrate_unit_struct.rs: New test. * rust/rustc/ui/cross-crate/cci_borrow.rs: New test. * rust/rustc/ui/cross-crate/cci_capture_clause.rs: New test. * rust/rustc/ui/cross-crate/cci_impl_exe.rs: New test. * rust/rustc/ui/cross-crate/cci_iter_exe.rs: New test. * rust/rustc/ui/cross-crate/cci_nested_exe.rs: New test. * rust/rustc/ui/cross-crate/cci_no_inline_exe.rs: New test. * rust/rustc/ui/cross-crate/cross-crate-const-pat.rs: New test. * rust/rustc/ui/cross-crate/cross-crate-newtype-struct-pat.rs: New test. * rust/rustc/ui/cross-crate/issue-64872/auxiliary/a_def_obj.rs: New test. * rust/rustc/ui/cross-crate/issue-64872/auxiliary/b_reexport_obj.rs: New test. * rust/rustc/ui/cross-crate/issue-64872/auxiliary/c_another_vtable_for_obj.rs: New test. * rust/rustc/ui/cross-crate/issue-64872/auxiliary/d_chain_of_rlibs_and_dylibs.rs: New test. * rust/rustc/ui/cross-crate/issue-64872/issue-64872.rs: New test. * rust/rustc/ui/cross-crate/moves-based-on-type-cross-crate.rs: New test. * rust/rustc/ui/cross-crate/reexported-static-methods-cross-crate.rs: New test. * rust/rustc/ui/cross-crate/static-array-across-crate.rs: New test. * rust/rustc/ui/cross-crate/xcrate-address-insignificant.rs: New test. * rust/rustc/ui/cross-crate/xcrate-associated-type-defaults.rs: New test. * rust/rustc/ui/cross-crate/xcrate-static-addresses.rs: New test. * rust/rustc/ui/cross-crate/xcrate-trait-lifetime-param.rs: New test. * rust/rustc/ui/cross-crate/xcrate-unit-struct.rs: New test. * rust/rustc/ui/cross-crate/xcrate_generic_fn_nested_return.rs: New test. * rust/rustc/ui/cross/cross-borrow-trait.rs: New test. * rust/rustc/ui/cross/cross-crate-macro-backtrace/auxiliary/extern_macro_crate.rs: New test. * rust/rustc/ui/cross/cross-crate-macro-backtrace/main.rs: New test. * rust/rustc/ui/cross/cross-file-errors/main.rs: New test. * rust/rustc/ui/cross/cross-file-errors/underscore.rs: New test. * rust/rustc/ui/cross/cross-fn-cache-hole.rs: New test. * rust/rustc/ui/crt-static-off-works.rs: New test. * rust/rustc/ui/crt-static-on-works.rs: New test. * rust/rustc/ui/custom-attribute-multisegment.rs: New test. * rust/rustc/ui/custom-test-frameworks-simple.rs: New test. * rust/rustc/ui/custom_attribute.rs: New test. * rust/rustc/ui/custom_test_frameworks/auxiliary/dynamic_runner.rs: New test. * rust/rustc/ui/custom_test_frameworks/auxiliary/example_runner.rs: New test. * rust/rustc/ui/custom_test_frameworks/dynamic.rs: New test. * rust/rustc/ui/custom_test_frameworks/full.rs: New test. * rust/rustc/ui/custom_test_frameworks/mismatch.rs: New test. * rust/rustc/ui/cycle-generic-bound.rs: New test. * rust/rustc/ui/cycle-projection-based-on-where-clause.rs: New test. * rust/rustc/ui/cycle-trait/cycle-trait-default-type-trait.rs: New test. * rust/rustc/ui/cycle-trait/cycle-trait-supertrait-direct.rs: New test. * rust/rustc/ui/cycle-trait/cycle-trait-supertrait-indirect.rs: New test. * rust/rustc/ui/debuginfo-lto.rs: New test. * rust/rustc/ui/deduplicate-diagnostics-2.rs: New test. * rust/rustc/ui/deduplicate-diagnostics.rs: New test. * rust/rustc/ui/deep.rs: New test. * rust/rustc/ui/default-alloc-error-hook.rs: New test. * rust/rustc/ui/default-associated-types.rs: New test. * rust/rustc/ui/default-method-parsing.rs: New test. * rust/rustc/ui/default-method-simple.rs: New test. * rust/rustc/ui/defaults-well-formedness.rs: New test. * rust/rustc/ui/definition-reachable/auxiliary/field-method-macro.rs: New test. * rust/rustc/ui/definition-reachable/auxiliary/nested-fn-macro.rs: New test. * rust/rustc/ui/definition-reachable/auxiliary/private-use-macro.rs: New test. * rust/rustc/ui/definition-reachable/field-method.rs: New test. * rust/rustc/ui/definition-reachable/nested-fn.rs: New test. * rust/rustc/ui/definition-reachable/private-non-types.rs: New test. * rust/rustc/ui/definition-reachable/private-types.rs: New test. * rust/rustc/ui/definition-reachable/private-use.rs: New test. * rust/rustc/ui/dep-graph/dep-graph-assoc-type-codegen.rs: New test. * rust/rustc/ui/dep-graph/dep-graph-caller-callee.rs: New test. * rust/rustc/ui/dep-graph/dep-graph-struct-signature.rs: New test. * rust/rustc/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs: New test. * rust/rustc/ui/dep-graph/dep-graph-trait-impl-two-traits.rs: New test. * rust/rustc/ui/dep-graph/dep-graph-trait-impl.rs: New test. * rust/rustc/ui/dep-graph/dep-graph-type-alias.rs: New test. * rust/rustc/ui/dep-graph/dep-graph-variance-alias.rs: New test. * rust/rustc/ui/deprecation-in-force-unstable.rs: New test. * rust/rustc/ui/deprecation/atomic_initializers.rs: New test. * rust/rustc/ui/deprecation/auxiliary/deprecation-lint.rs: New test. * rust/rustc/ui/deprecation/deprecated-macro_escape-inner.rs: New test. * rust/rustc/ui/deprecation/deprecated-macro_escape.rs: New test. * rust/rustc/ui/deprecation/deprecated_no_stack_check.rs: New test. * rust/rustc/ui/deprecation/deprecation-in-future.rs: New test. * rust/rustc/ui/deprecation/deprecation-in-staged-api.rs: New test. * rust/rustc/ui/deprecation/deprecation-lint-2.rs: New test. * rust/rustc/ui/deprecation/deprecation-lint-3.rs: New test. * rust/rustc/ui/deprecation/deprecation-lint-nested.rs: New test. * rust/rustc/ui/deprecation/deprecation-lint.rs: New test. * rust/rustc/ui/deprecation/deprecation-sanity.rs: New test. * rust/rustc/ui/deprecation/derive_on_deprecated.rs: New test. * rust/rustc/ui/deprecation/derive_on_deprecated_forbidden.rs: New test. * rust/rustc/ui/deprecation/invalid-literal.rs: New test. * rust/rustc/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs: New test. * rust/rustc/ui/deprecation/rustc_deprecation-in-future.rs: New test. * rust/rustc/ui/deprecation/suggestion.rs: New test. * rust/rustc/ui/deref-mut-on-ref.rs: New test. * rust/rustc/ui/deref-non-pointer.rs: New test. * rust/rustc/ui/deref-on-ref.rs: New test. * rust/rustc/ui/deref-rc.rs: New test. * rust/rustc/ui/deref-suggestion.rs: New test. * rust/rustc/ui/deref.rs: New test. * rust/rustc/ui/derive-uninhabited-enum-38885.rs: New test. * rust/rustc/ui/derived-errors/issue-30580.rs: New test. * rust/rustc/ui/derived-errors/issue-31997-1.rs: New test. * rust/rustc/ui/derived-errors/issue-31997.rs: New test. * rust/rustc/ui/derives/auxiliary/derive-marker-tricky.rs: New test. * rust/rustc/ui/derives/derive-assoc-type-not-impl.rs: New test. * rust/rustc/ui/derives/derive-hygiene.rs: New test. * rust/rustc/ui/derives/derive-marker-tricky.rs: New test. * rust/rustc/ui/derives/derive-on-trait-item-or-impl-item.rs: New test. * rust/rustc/ui/derives/derives-span-Clone-enum-struct-variant.rs: New test. * rust/rustc/ui/derives/derives-span-Clone-enum.rs: New test. * rust/rustc/ui/derives/derives-span-Clone-struct.rs: New test. * rust/rustc/ui/derives/derives-span-Clone-tuple-struct.rs: New test. * rust/rustc/ui/derives/derives-span-Debug-enum-struct-variant.rs: New test. * rust/rustc/ui/derives/derives-span-Debug-enum.rs: New test. * rust/rustc/ui/derives/derives-span-Debug-struct.rs: New test. * rust/rustc/ui/derives/derives-span-Debug-tuple-struct.rs: New test. * rust/rustc/ui/derives/derives-span-Default-struct.rs: New test. * rust/rustc/ui/derives/derives-span-Default-tuple-struct.rs: New test. * rust/rustc/ui/derives/derives-span-Eq-enum-struct-variant.rs: New test. * rust/rustc/ui/derives/derives-span-Eq-enum.rs: New test. * rust/rustc/ui/derives/derives-span-Eq-struct.rs: New test. * rust/rustc/ui/derives/derives-span-Eq-tuple-struct.rs: New test. * rust/rustc/ui/derives/derives-span-Hash-enum-struct-variant.rs: New test. * rust/rustc/ui/derives/derives-span-Hash-enum.rs: New test. * rust/rustc/ui/derives/derives-span-Hash-struct.rs: New test. * rust/rustc/ui/derives/derives-span-Hash-tuple-struct.rs: New test. * rust/rustc/ui/derives/derives-span-Ord-enum-struct-variant.rs: New test. * rust/rustc/ui/derives/derives-span-Ord-enum.rs: New test. * rust/rustc/ui/derives/derives-span-Ord-struct.rs: New test. * rust/rustc/ui/derives/derives-span-Ord-tuple-struct.rs: New test. * rust/rustc/ui/derives/derives-span-PartialEq-enum-struct-variant.rs: New test. * rust/rustc/ui/derives/derives-span-PartialEq-enum.rs: New test. * rust/rustc/ui/derives/derives-span-PartialEq-struct.rs: New test. * rust/rustc/ui/derives/derives-span-PartialEq-tuple-struct.rs: New test. * rust/rustc/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs: New test. * rust/rustc/ui/derives/derives-span-PartialOrd-enum.rs: New test. * rust/rustc/ui/derives/derives-span-PartialOrd-struct.rs: New test. * rust/rustc/ui/derives/derives-span-PartialOrd-tuple-struct.rs: New test. * rust/rustc/ui/derives/deriving-bounds.rs: New test. * rust/rustc/ui/derives/deriving-copyclone.rs: New test. * rust/rustc/ui/derives/deriving-meta-empty-trait-list.rs: New test. * rust/rustc/ui/derives/deriving-meta-unknown-trait.rs: New test. * rust/rustc/ui/derives/deriving-no-inner-impl-error-message.rs: New test. * rust/rustc/ui/derives/deriving-non-type.rs: New test. * rust/rustc/ui/derives/deriving-primitive.rs: New test. * rust/rustc/ui/derives/deriving-with-repr-packed.rs: New test. * rust/rustc/ui/deriving/auxiliary/derive-no-std.rs: New test. * rust/rustc/ui/deriving/derive-no-std.rs: New test. * rust/rustc/ui/deriving/derive-partialord-correctness.rs: New test. * rust/rustc/ui/deriving/deriving-associated-types.rs: New test. * rust/rustc/ui/deriving/deriving-bounds.rs: New test. * rust/rustc/ui/deriving/deriving-clone-array.rs: New test. * rust/rustc/ui/deriving/deriving-clone-enum.rs: New test. * rust/rustc/ui/deriving/deriving-clone-generic-enum.rs: New test. * rust/rustc/ui/deriving/deriving-clone-generic-struct.rs: New test. * rust/rustc/ui/deriving/deriving-clone-generic-tuple-struct.rs: New test. * rust/rustc/ui/deriving/deriving-clone-struct.rs: New test. * rust/rustc/ui/deriving/deriving-clone-tuple-struct.rs: New test. * rust/rustc/ui/deriving/deriving-cmp-generic-enum.rs: New test. * rust/rustc/ui/deriving/deriving-cmp-generic-struct-enum.rs: New test. * rust/rustc/ui/deriving/deriving-cmp-generic-struct.rs: New test. * rust/rustc/ui/deriving/deriving-cmp-generic-tuple-struct.rs: New test. * rust/rustc/ui/deriving/deriving-cmp-shortcircuit.rs: New test. * rust/rustc/ui/deriving/deriving-copyclone.rs: New test. * rust/rustc/ui/deriving/deriving-default-box.rs: New test. * rust/rustc/ui/deriving/deriving-enum-single-variant.rs: New test. * rust/rustc/ui/deriving/deriving-eq-ord-boxed-slice.rs: New test. * rust/rustc/ui/deriving/deriving-hash.rs: New test. * rust/rustc/ui/deriving/deriving-in-fn.rs: New test. * rust/rustc/ui/deriving/deriving-in-macro.rs: New test. * rust/rustc/ui/deriving/deriving-meta-multiple.rs: New test. * rust/rustc/ui/deriving/deriving-meta.rs: New test. * rust/rustc/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs: New test. * rust/rustc/ui/deriving/deriving-show-2.rs: New test. * rust/rustc/ui/deriving/deriving-show.rs: New test. * rust/rustc/ui/deriving/deriving-via-extension-c-enum.rs: New test. * rust/rustc/ui/deriving/deriving-via-extension-enum.rs: New test. * rust/rustc/ui/deriving/deriving-via-extension-hash-enum.rs: New test. * rust/rustc/ui/deriving/deriving-via-extension-hash-struct.rs: New test. * rust/rustc/ui/deriving/deriving-via-extension-struct-empty.rs: New test. * rust/rustc/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs: New test. * rust/rustc/ui/deriving/deriving-via-extension-struct-tuple.rs: New test. * rust/rustc/ui/deriving/deriving-via-extension-struct.rs: New test. * rust/rustc/ui/deriving/deriving-via-extension-type-params.rs: New test. * rust/rustc/ui/deriving/deriving-with-repr-packed.rs: New test. * rust/rustc/ui/dest-prop/skeptic-miscompile.rs: New test. * rust/rustc/ui/destructure-trait-ref.rs: New test. * rust/rustc/ui/destructuring-assignment/default-match-bindings-forbidden.rs: New test. * rust/rustc/ui/destructuring-assignment/nested_destructure.rs: New test. * rust/rustc/ui/destructuring-assignment/note-unsupported.rs: New test. * rust/rustc/ui/destructuring-assignment/slice_destructure.rs: New test. * rust/rustc/ui/destructuring-assignment/slice_destructure_fail.rs: New test. * rust/rustc/ui/destructuring-assignment/struct_destructure.rs: New test. * rust/rustc/ui/destructuring-assignment/struct_destructure_fail.rs: New test. * rust/rustc/ui/destructuring-assignment/tuple_destructure.rs: New test. * rust/rustc/ui/destructuring-assignment/tuple_destructure_fail.rs: New test. * rust/rustc/ui/destructuring-assignment/tuple_struct_destructure.rs: New test. * rust/rustc/ui/destructuring-assignment/tuple_struct_destructure_fail.rs: New test. * rust/rustc/ui/destructuring-assignment/underscore-range-expr-gating.rs: New test. * rust/rustc/ui/destructuring-assignment/warn-unused-duplication.rs: New test. * rust/rustc/ui/did_you_mean/E0178.rs: New test. * rust/rustc/ui/did_you_mean/bad-assoc-expr.rs: New test. * rust/rustc/ui/did_you_mean/bad-assoc-pat.rs: New test. * rust/rustc/ui/did_you_mean/bad-assoc-ty.rs: New test. * rust/rustc/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs: New test. * rust/rustc/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs: New test. * rust/rustc/ui/did_you_mean/issue-31424.rs: New test. * rust/rustc/ui/did_you_mean/issue-34126.rs: New test. * rust/rustc/ui/did_you_mean/issue-34337.rs: New test. * rust/rustc/ui/did_you_mean/issue-35937.rs: New test. * rust/rustc/ui/did_you_mean/issue-36798.rs: New test. * rust/rustc/ui/did_you_mean/issue-36798_unknown_field.rs: New test. * rust/rustc/ui/did_you_mean/issue-37139.rs: New test. * rust/rustc/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs: New test. * rust/rustc/ui/did_you_mean/issue-38147-1.rs: New test. * rust/rustc/ui/did_you_mean/issue-38147-2.rs: New test. * rust/rustc/ui/did_you_mean/issue-38147-3.rs: New test. * rust/rustc/ui/did_you_mean/issue-38147-4.rs: New test. * rust/rustc/ui/did_you_mean/issue-39544.rs: New test. * rust/rustc/ui/did_you_mean/issue-39802-show-5-trait-impls.rs: New test. * rust/rustc/ui/did_you_mean/issue-40006.rs: New test. * rust/rustc/ui/did_you_mean/issue-40396.rs: New test. * rust/rustc/ui/did_you_mean/issue-40823.rs: New test. * rust/rustc/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs: New test. * rust/rustc/ui/did_you_mean/issue-42599_available_fields_note.rs: New test. * rust/rustc/ui/did_you_mean/issue-42764.rs: New test. * rust/rustc/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs: New test. * rust/rustc/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.rs: New test. * rust/rustc/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.rs: New test. * rust/rustc/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.rs: New test. * rust/rustc/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs: New test. * rust/rustc/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.rs: New test. * rust/rustc/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs: New test. * rust/rustc/ui/did_you_mean/issue-54109-without-witness.rs: New test. * rust/rustc/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs: New test. * rust/rustc/ui/did_you_mean/pub-macro-rules.rs: New test. * rust/rustc/ui/did_you_mean/recursion_limit.rs: New test. * rust/rustc/ui/did_you_mean/recursion_limit_deref.rs: New test. * rust/rustc/ui/did_you_mean/recursion_limit_macro.rs: New test. * rust/rustc/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs: New test. * rust/rustc/ui/directory_ownership/foo/mod_file_not_owning/aux2.rs: New test. * rust/rustc/ui/directory_ownership/foo/mod_file_not_owning_aux2.rs: New test. * rust/rustc/ui/directory_ownership/macro-expanded-mod.rs: New test. * rust/rustc/ui/directory_ownership/macro_expanded_mod_helper/foo/bar.rs: New test. * rust/rustc/ui/directory_ownership/macro_expanded_mod_helper/foo/mod.rs: New test. * rust/rustc/ui/directory_ownership/mod_file_not_owning_aux1.rs: New test. * rust/rustc/ui/directory_ownership/mod_file_not_owning_aux1/mod_file_not_owning_aux2.rs: New test. * rust/rustc/ui/directory_ownership/mod_file_not_owning_aux2.rs: New test. * rust/rustc/ui/directory_ownership/mod_file_not_owning_aux3.rs: New test. * rust/rustc/ui/directory_ownership/non-inline-mod-restriction.rs: New test. * rust/rustc/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-let.rs: New test. * rust/rustc/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-match.rs: New test. * rust/rustc/ui/disambiguate-identical-names.rs: New test. * rust/rustc/ui/discrim/discrim-ill-typed.rs: New test. * rust/rustc/ui/discrim/discrim-overflow-2.rs: New test. * rust/rustc/ui/discrim/discrim-overflow.rs: New test. * rust/rustc/ui/diverging-fallback-method-chain.rs: New test. * rust/rustc/ui/diverging-fallback-option.rs: New test. * rust/rustc/ui/diverging-fn-tail-35849.rs: New test. * rust/rustc/ui/diverging-tuple-parts-39485.rs: New test. * rust/rustc/ui/doc-alias-crate-level.rs: New test. * rust/rustc/ui/does-nothing.rs: New test. * rust/rustc/ui/dollar-crate/dollar-crate-is-keyword-2.rs: New test. * rust/rustc/ui/dollar-crate/dollar-crate-is-keyword.rs: New test. * rust/rustc/ui/dont-suggest-private-trait-method.rs: New test. * rust/rustc/ui/dotdotdot-expr.rs: New test. * rust/rustc/ui/double-import.rs: New test. * rust/rustc/ui/double-ref.rs: New test. * rust/rustc/ui/double-type-import.rs: New test. * rust/rustc/ui/drop-bounds/drop-bounds-impl-drop.rs: New test. * rust/rustc/ui/drop-bounds/drop-bounds.rs: New test. * rust/rustc/ui/drop/auxiliary/dropck_eyepatch_extern_crate.rs: New test. * rust/rustc/ui/drop/drop-on-empty-block-exit.rs: New test. * rust/rustc/ui/drop/drop-on-ret.rs: New test. * rust/rustc/ui/drop/drop-struct-as-object.rs: New test. * rust/rustc/ui/drop/drop-trait-enum.rs: New test. * rust/rustc/ui/drop/drop-trait-generic.rs: New test. * rust/rustc/ui/drop/drop-trait.rs: New test. * rust/rustc/ui/drop/drop-uninhabited-enum.rs: New test. * rust/rustc/ui/drop/drop-with-type-ascription-1.rs: New test. * rust/rustc/ui/drop/drop-with-type-ascription-2.rs: New test. * rust/rustc/ui/drop/dropck-eyepatch-extern-crate.rs: New test. * rust/rustc/ui/drop/dropck-eyepatch-reorder.rs: New test. * rust/rustc/ui/drop/dropck-eyepatch.rs: New test. * rust/rustc/ui/drop/dropck_legal_cycles.rs: New test. * rust/rustc/ui/drop/dynamic-drop-async.rs: New test. * rust/rustc/ui/drop/dynamic-drop.rs: New test. * rust/rustc/ui/drop/no-drop-flag-size.rs: New test. * rust/rustc/ui/drop/nondrop-cycle.rs: New test. * rust/rustc/ui/dropck/auxiliary/dropck_eyepatch_extern_crate.rs: New test. * rust/rustc/ui/dropck/drop-on-non-struct.rs: New test. * rust/rustc/ui/dropck/drop-with-active-borrows-1.rs: New test. * rust/rustc/ui/dropck/drop-with-active-borrows-2.rs: New test. * rust/rustc/ui/dropck/dropck-eyepatch-extern-crate.rs: New test. * rust/rustc/ui/dropck/dropck-eyepatch-implies-unsafe-impl.rs: New test. * rust/rustc/ui/dropck/dropck-eyepatch-reorder.rs: New test. * rust/rustc/ui/dropck/dropck-eyepatch.rs: New test. * rust/rustc/ui/dropck/dropck-union.rs: New test. * rust/rustc/ui/dropck/dropck_fn_type.rs: New test. * rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_1.rs: New test. * rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_2.rs: New test. * rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_3.rs: New test. * rust/rustc/ui/dropck/dropck_trait_cycle_checked.rs: New test. * rust/rustc/ui/dropck/dropck_traits.rs: New test. * rust/rustc/ui/dst/dst-bad-assign-2.rs: New test. * rust/rustc/ui/dst/dst-bad-assign-3.rs: New test. * rust/rustc/ui/dst/dst-bad-assign.rs: New test. * rust/rustc/ui/dst/dst-bad-coerce1.rs: New test. * rust/rustc/ui/dst/dst-bad-coerce2.rs: New test. * rust/rustc/ui/dst/dst-bad-coerce3.rs: New test. * rust/rustc/ui/dst/dst-bad-coerce4.rs: New test. * rust/rustc/ui/dst/dst-bad-coercions.rs: New test. * rust/rustc/ui/dst/dst-bad-deep-2.rs: New test. * rust/rustc/ui/dst/dst-bad-deep.rs: New test. * rust/rustc/ui/dst/dst-index.rs: New test. * rust/rustc/ui/dst/dst-object-from-unsized-type.rs: New test. * rust/rustc/ui/dst/dst-rvalue.rs: New test. * rust/rustc/ui/dst/dst-sized-trait-param.rs: New test. * rust/rustc/ui/duplicate/dupe-symbols-1.rs: New test. * rust/rustc/ui/duplicate/dupe-symbols-2.rs: New test. * rust/rustc/ui/duplicate/dupe-symbols-3.rs: New test. * rust/rustc/ui/duplicate/dupe-symbols-4.rs: New test. * rust/rustc/ui/duplicate/dupe-symbols-5.rs: New test. * rust/rustc/ui/duplicate/dupe-symbols-6.rs: New test. * rust/rustc/ui/duplicate/dupe-symbols-7.rs: New test. * rust/rustc/ui/duplicate/dupe-symbols-8.rs: New test. * rust/rustc/ui/duplicate/duplicate-check-macro-exports.rs: New test. * rust/rustc/ui/duplicate/duplicate-parameter.rs: New test. * rust/rustc/ui/duplicate/duplicate-type-parameter.rs: New test. * rust/rustc/ui/duplicate_entry_error.rs: New test. * rust/rustc/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs: New test. * rust/rustc/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs: New test. * rust/rustc/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs: New test. * rust/rustc/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs: New test. * rust/rustc/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs: New test. * rust/rustc/ui/dyn-trait-compatibility.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-coerce-custom.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-coerce-rc.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-coercions.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-deref-mut.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-deref.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-field-align.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-index.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-irrefutable-bind.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-raw.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-struct-sole.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-struct.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-trait-tuple.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-trait.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-tuple-no-reorder.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-tuple-sole.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs: New test. * rust/rustc/ui/dynamically-sized-types/dst-tuple.rs: New test. * rust/rustc/ui/early-ret-binop-add.rs: New test. * rust/rustc/ui/early-vtbl-resolution.rs: New test. * rust/rustc/ui/edition-keywords-2015-2015.rs: New test. * rust/rustc/ui/edition-keywords-2015-2018.rs: New test. * rust/rustc/ui/edition-keywords-2018-2015.rs: New test. * rust/rustc/ui/edition-keywords-2018-2018.rs: New test. * rust/rustc/ui/editions/async-block-2015.rs: New test. * rust/rustc/ui/editions/auxiliary/absolute.rs: New test. * rust/rustc/ui/editions/auxiliary/edition-extern-crate-allowed.rs: New test. * rust/rustc/ui/editions/auxiliary/edition-imports-2015.rs: New test. * rust/rustc/ui/editions/auxiliary/edition-imports-2018.rs: New test. * rust/rustc/ui/editions/auxiliary/edition-kw-macro-2015.rs: New test. * rust/rustc/ui/editions/auxiliary/edition-kw-macro-2018.rs: New test. * rust/rustc/ui/editions/edition-extern-crate-allowed.rs: New test. * rust/rustc/ui/editions/edition-feature-ok.rs: New test. * rust/rustc/ui/editions/edition-feature-redundant.rs: New test. * rust/rustc/ui/editions/edition-imports-2015.rs: New test. * rust/rustc/ui/editions/edition-imports-2018.rs: New test. * rust/rustc/ui/editions/edition-imports-virtual-2015-ambiguity.rs: New test. * rust/rustc/ui/editions/edition-imports-virtual-2015-gated.rs: New test. * rust/rustc/ui/editions/edition-keywords-2015-2015-expansion.rs: New test. * rust/rustc/ui/editions/edition-keywords-2015-2015-parsing.rs: New test. * rust/rustc/ui/editions/edition-keywords-2015-2018-expansion.rs: New test. * rust/rustc/ui/editions/edition-keywords-2015-2018-parsing.rs: New test. * rust/rustc/ui/editions/edition-keywords-2018-2015-expansion.rs: New test. * rust/rustc/ui/editions/edition-keywords-2018-2015-parsing.rs: New test. * rust/rustc/ui/editions/edition-keywords-2018-2018-expansion.rs: New test. * rust/rustc/ui/editions/edition-keywords-2018-2018-parsing.rs: New test. * rust/rustc/ui/editions/edition-raw-pointer-method-2015.rs: New test. * rust/rustc/ui/editions/edition-raw-pointer-method-2018.rs: New test. * rust/rustc/ui/elide-errors-on-mismatched-tuple.rs: New test. * rust/rustc/ui/elided-test.rs: New test. * rust/rustc/ui/else-if.rs: New test. * rust/rustc/ui/emit-artifact-notifications.rs: New test. * rust/rustc/ui/empty-allocation-non-null.rs: New test. * rust/rustc/ui/empty-allocation-rvalue-non-null.rs: New test. * rust/rustc/ui/empty-type-parameter-list.rs: New test. * rust/rustc/ui/empty/auxiliary/empty-struct.rs: New test. * rust/rustc/ui/empty/auxiliary/two_macros.rs: New test. * rust/rustc/ui/empty/empty-comment.rs: New test. * rust/rustc/ui/empty/empty-linkname.rs: New test. * rust/rustc/ui/empty/empty-macro-use.rs: New test. * rust/rustc/ui/empty/empty-never-array.rs: New test. * rust/rustc/ui/empty/empty-struct-braces-expr.rs: New test. * rust/rustc/ui/empty/empty-struct-braces-pat-1.rs: New test. * rust/rustc/ui/empty/empty-struct-braces-pat-2.rs: New test. * rust/rustc/ui/empty/empty-struct-braces-pat-3.rs: New test. * rust/rustc/ui/empty/empty-struct-tuple-pat.rs: New test. * rust/rustc/ui/empty/empty-struct-unit-expr.rs: New test. * rust/rustc/ui/empty/empty-struct-unit-pat.rs: New test. * rust/rustc/ui/empty_global_asm.rs: New test. * rust/rustc/ui/enable-unstable-lib-feature.rs: New test. * rust/rustc/ui/enum-discriminant/actually_not_an_enum-discriminant.rs: New test. * rust/rustc/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs: New test. * rust/rustc/ui/enum-discriminant/arbitrary_enum_discriminant.rs: New test. * rust/rustc/ui/enum-discriminant/discriminant_size.rs: New test. * rust/rustc/ui/enum-discriminant/discriminant_value-wrapper.rs: New test. * rust/rustc/ui/enum-discriminant/discriminant_value.rs: New test. * rust/rustc/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.rs: New test. * rust/rustc/ui/enum-discriminant/forbidden-discriminant-kind-impl.rs: New test. * rust/rustc/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs: New test. * rust/rustc/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs: New test. * rust/rustc/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs: New test. * rust/rustc/ui/enum-discriminant/issue-70509-partial_eq.rs: New test. * rust/rustc/ui/enum-discriminant/niche.rs: New test. * rust/rustc/ui/enum-discriminant/repr128.rs: New test. * rust/rustc/ui/enum/enum-and-module-in-same-scope.rs: New test. * rust/rustc/ui/enum/enum-discrim-autosizing.rs: New test. * rust/rustc/ui/enum/enum-discrim-too-small.rs: New test. * rust/rustc/ui/enum/enum-discrim-too-small2.rs: New test. * rust/rustc/ui/enum/enum-in-scope.rs: New test. * rust/rustc/ui/enum/enum-size-variance.rs: New test. * rust/rustc/ui/enum/enum-to-float-cast-2.rs: New test. * rust/rustc/ui/enum/enum-to-float-cast.rs: New test. * rust/rustc/ui/enum/enum-variant-type-2.rs: New test. * rust/rustc/ui/enum/issue-67945-1.rs: New test. * rust/rustc/ui/enum/issue-67945-2.rs: New test. * rust/rustc/ui/enum/nested-enum.rs: New test. * rust/rustc/ui/enum/union-in-enum.rs: New test. * rust/rustc/ui/enums-pats-not-idents.rs: New test. * rust/rustc/ui/env-args-reverse-iterator.rs: New test. * rust/rustc/ui/env-funky-keys.rs: New test. * rust/rustc/ui/env-home-dir.rs: New test. * rust/rustc/ui/env-null-vars.rs: New test. * rust/rustc/ui/env-vars.rs: New test. * rust/rustc/ui/epoch-gate-feature.rs: New test. * rust/rustc/ui/eprint-on-tls-drop.rs: New test. * rust/rustc/ui/eq-multidispatch.rs: New test. * rust/rustc/ui/error-codes/E0001.rs: New test. * rust/rustc/ui/error-codes/E0004-2.rs: New test. * rust/rustc/ui/error-codes/E0004.rs: New test. * rust/rustc/ui/error-codes/E0005.rs: New test. * rust/rustc/ui/error-codes/E0010-teach.rs: New test. * rust/rustc/ui/error-codes/E0010.rs: New test. * rust/rustc/ui/error-codes/E0017.rs: New test. * rust/rustc/ui/error-codes/E0023.rs: New test. * rust/rustc/ui/error-codes/E0025.rs: New test. * rust/rustc/ui/error-codes/E0026-teach.rs: New test. * rust/rustc/ui/error-codes/E0026.rs: New test. * rust/rustc/ui/error-codes/E0027.rs: New test. * rust/rustc/ui/error-codes/E0029-teach.rs: New test. * rust/rustc/ui/error-codes/E0029.rs: New test. * rust/rustc/ui/error-codes/E0030-teach.rs: New test. * rust/rustc/ui/error-codes/E0030.rs: New test. * rust/rustc/ui/error-codes/E0033-teach.rs: New test. * rust/rustc/ui/error-codes/E0033.rs: New test. * rust/rustc/ui/error-codes/E0034.rs: New test. * rust/rustc/ui/error-codes/E0038.rs: New test. * rust/rustc/ui/error-codes/E0040.rs: New test. * rust/rustc/ui/error-codes/E0044.rs: New test. * rust/rustc/ui/error-codes/E0045.rs: New test. * rust/rustc/ui/error-codes/E0049.rs: New test. * rust/rustc/ui/error-codes/E0050.rs: New test. * rust/rustc/ui/error-codes/E0054.rs: New test. * rust/rustc/ui/error-codes/E0055.rs: New test. * rust/rustc/ui/error-codes/E0057.rs: New test. * rust/rustc/ui/error-codes/E0059.rs: New test. * rust/rustc/ui/error-codes/E0060.rs: New test. * rust/rustc/ui/error-codes/E0061.rs: New test. * rust/rustc/ui/error-codes/E0062.rs: New test. * rust/rustc/ui/error-codes/E0063.rs: New test. * rust/rustc/ui/error-codes/E0067.rs: New test. * rust/rustc/ui/error-codes/E0069.rs: New test. * rust/rustc/ui/error-codes/E0070.rs: New test. * rust/rustc/ui/error-codes/E0071.rs: New test. * rust/rustc/ui/error-codes/E0075.rs: New test. * rust/rustc/ui/error-codes/E0076.rs: New test. * rust/rustc/ui/error-codes/E0077.rs: New test. * rust/rustc/ui/error-codes/E0080.rs: New test. * rust/rustc/ui/error-codes/E0081.rs: New test. * rust/rustc/ui/error-codes/E0084.rs: New test. * rust/rustc/ui/error-codes/E0091.rs: New test. * rust/rustc/ui/error-codes/E0092.rs: New test. * rust/rustc/ui/error-codes/E0093.rs: New test. * rust/rustc/ui/error-codes/E0094.rs: New test. * rust/rustc/ui/error-codes/E0106.rs: New test. * rust/rustc/ui/error-codes/E0107.rs: New test. * rust/rustc/ui/error-codes/E0109.rs: New test. * rust/rustc/ui/error-codes/E0110.rs: New test. * rust/rustc/ui/error-codes/E0116.rs: New test. * rust/rustc/ui/error-codes/E0117.rs: New test. * rust/rustc/ui/error-codes/E0118-2.rs: New test. * rust/rustc/ui/error-codes/E0118.rs: New test. * rust/rustc/ui/error-codes/E0119.rs: New test. * rust/rustc/ui/error-codes/E0120.rs: New test. * rust/rustc/ui/error-codes/E0121.rs: New test. * rust/rustc/ui/error-codes/E0124.rs: New test. * rust/rustc/ui/error-codes/E0128.rs: New test. * rust/rustc/ui/error-codes/E0130.rs: New test. * rust/rustc/ui/error-codes/E0131.rs: New test. * rust/rustc/ui/error-codes/E0132.rs: New test. * rust/rustc/ui/error-codes/E0133.rs: New test. * rust/rustc/ui/error-codes/E0137.rs: New test. * rust/rustc/ui/error-codes/E0138.rs: New test. * rust/rustc/ui/error-codes/E0152.rs: New test. * rust/rustc/ui/error-codes/E0161.rs: New test. * rust/rustc/ui/error-codes/E0164.rs: New test. * rust/rustc/ui/error-codes/E0184.rs: New test. * rust/rustc/ui/error-codes/E0185.rs: New test. * rust/rustc/ui/error-codes/E0186.rs: New test. * rust/rustc/ui/error-codes/E0191.rs: New test. * rust/rustc/ui/error-codes/E0194.rs: New test. * rust/rustc/ui/error-codes/E0195.rs: New test. * rust/rustc/ui/error-codes/E0197.rs: New test. * rust/rustc/ui/error-codes/E0198.rs: New test. * rust/rustc/ui/error-codes/E0199.rs: New test. * rust/rustc/ui/error-codes/E0200.rs: New test. * rust/rustc/ui/error-codes/E0201.rs: New test. * rust/rustc/ui/error-codes/E0206.rs: New test. * rust/rustc/ui/error-codes/E0207.rs: New test. * rust/rustc/ui/error-codes/E0214.rs: New test. * rust/rustc/ui/error-codes/E0220.rs: New test. * rust/rustc/ui/error-codes/E0221.rs: New test. * rust/rustc/ui/error-codes/E0223.rs: New test. * rust/rustc/ui/error-codes/E0225.rs: New test. * rust/rustc/ui/error-codes/E0229.rs: New test. * rust/rustc/ui/error-codes/E0252.rs: New test. * rust/rustc/ui/error-codes/E0253.rs: New test. * rust/rustc/ui/error-codes/E0254.rs: New test. * rust/rustc/ui/error-codes/E0255.rs: New test. * rust/rustc/ui/error-codes/E0259.rs: New test. * rust/rustc/ui/error-codes/E0260.rs: New test. * rust/rustc/ui/error-codes/E0261.rs: New test. * rust/rustc/ui/error-codes/E0262.rs: New test. * rust/rustc/ui/error-codes/E0263.rs: New test. * rust/rustc/ui/error-codes/E0264.rs: New test. * rust/rustc/ui/error-codes/E0267.rs: New test. * rust/rustc/ui/error-codes/E0268.rs: New test. * rust/rustc/ui/error-codes/E0271.rs: New test. * rust/rustc/ui/error-codes/E0275.rs: New test. * rust/rustc/ui/error-codes/E0276.rs: New test. * rust/rustc/ui/error-codes/E0277-2.rs: New test. * rust/rustc/ui/error-codes/E0277.rs: New test. * rust/rustc/ui/error-codes/E0282.rs: New test. * rust/rustc/ui/error-codes/E0283.rs: New test. * rust/rustc/ui/error-codes/E0297.rs: New test. * rust/rustc/ui/error-codes/E0308-2.rs: New test. * rust/rustc/ui/error-codes/E0308-4.rs: New test. * rust/rustc/ui/error-codes/E0308.rs: New test. * rust/rustc/ui/error-codes/E0328.rs: New test. * rust/rustc/ui/error-codes/E0365.rs: New test. * rust/rustc/ui/error-codes/E0370.rs: New test. * rust/rustc/ui/error-codes/E0374.rs: New test. * rust/rustc/ui/error-codes/E0375.rs: New test. * rust/rustc/ui/error-codes/E0376.rs: New test. * rust/rustc/ui/error-codes/E0388.rs: New test. * rust/rustc/ui/error-codes/E0389.rs: New test. * rust/rustc/ui/error-codes/E0390.rs: New test. * rust/rustc/ui/error-codes/E0392.rs: New test. * rust/rustc/ui/error-codes/E0393.rs: New test. * rust/rustc/ui/error-codes/E0395.rs: New test. * rust/rustc/ui/error-codes/E0396-fixed.rs: New test. * rust/rustc/ui/error-codes/E0396.rs: New test. * rust/rustc/ui/error-codes/E0401.rs: New test. * rust/rustc/ui/error-codes/E0403.rs: New test. * rust/rustc/ui/error-codes/E0404.rs: New test. * rust/rustc/ui/error-codes/E0405.rs: New test. * rust/rustc/ui/error-codes/E0407.rs: New test. * rust/rustc/ui/error-codes/E0408.rs: New test. * rust/rustc/ui/error-codes/E0411.rs: New test. * rust/rustc/ui/error-codes/E0412.rs: New test. * rust/rustc/ui/error-codes/E0415.rs: New test. * rust/rustc/ui/error-codes/E0416.rs: New test. * rust/rustc/ui/error-codes/E0423.rs: New test. * rust/rustc/ui/error-codes/E0424.rs: New test. * rust/rustc/ui/error-codes/E0425.rs: New test. * rust/rustc/ui/error-codes/E0426.rs: New test. * rust/rustc/ui/error-codes/E0428.rs: New test. * rust/rustc/ui/error-codes/E0429.rs: New test. * rust/rustc/ui/error-codes/E0430.rs: New test. * rust/rustc/ui/error-codes/E0431.rs: New test. * rust/rustc/ui/error-codes/E0432.rs: New test. * rust/rustc/ui/error-codes/E0433.rs: New test. * rust/rustc/ui/error-codes/E0434.rs: New test. * rust/rustc/ui/error-codes/E0435.rs: New test. * rust/rustc/ui/error-codes/E0437.rs: New test. * rust/rustc/ui/error-codes/E0438.rs: New test. * rust/rustc/ui/error-codes/E0439.rs: New test. * rust/rustc/ui/error-codes/E0445.rs: New test. * rust/rustc/ui/error-codes/E0446.rs: New test. * rust/rustc/ui/error-codes/E0449.rs: New test. * rust/rustc/ui/error-codes/E0451.rs: New test. * rust/rustc/ui/error-codes/E0452.rs: New test. * rust/rustc/ui/error-codes/E0453.rs: New test. * rust/rustc/ui/error-codes/E0454.rs: New test. * rust/rustc/ui/error-codes/E0458.rs: New test. * rust/rustc/ui/error-codes/E0459.rs: New test. * rust/rustc/ui/error-codes/E0463.rs: New test. * rust/rustc/ui/error-codes/E0478.rs: New test. * rust/rustc/ui/error-codes/E0490.rs: New test. * rust/rustc/ui/error-codes/E0492.rs: New test. * rust/rustc/ui/error-codes/E0496.rs: New test. * rust/rustc/ui/error-codes/E0499.rs: New test. * rust/rustc/ui/error-codes/E0501.rs: New test. * rust/rustc/ui/error-codes/E0502.rs: New test. * rust/rustc/ui/error-codes/E0503.rs: New test. * rust/rustc/ui/error-codes/E0504.rs: New test. * rust/rustc/ui/error-codes/E0505.rs: New test. * rust/rustc/ui/error-codes/E0506.rs: New test. * rust/rustc/ui/error-codes/E0507.rs: New test. * rust/rustc/ui/error-codes/E0508-fail.rs: New test. * rust/rustc/ui/error-codes/E0508.rs: New test. * rust/rustc/ui/error-codes/E0509.rs: New test. * rust/rustc/ui/error-codes/E0511.rs: New test. * rust/rustc/ui/error-codes/E0512.rs: New test. * rust/rustc/ui/error-codes/E0516.rs: New test. * rust/rustc/ui/error-codes/E0517.rs: New test. * rust/rustc/ui/error-codes/E0518.rs: New test. * rust/rustc/ui/error-codes/E0520.rs: New test. * rust/rustc/ui/error-codes/E0522.rs: New test. * rust/rustc/ui/error-codes/E0527.rs: New test. * rust/rustc/ui/error-codes/E0528.rs: New test. * rust/rustc/ui/error-codes/E0529.rs: New test. * rust/rustc/ui/error-codes/E0530.rs: New test. * rust/rustc/ui/error-codes/E0532.rs: New test. * rust/rustc/ui/error-codes/E0534.rs: New test. * rust/rustc/ui/error-codes/E0559.rs: New test. * rust/rustc/ui/error-codes/E0560.rs: New test. * rust/rustc/ui/error-codes/E0565-1.rs: New test. * rust/rustc/ui/error-codes/E0565-2.rs: New test. * rust/rustc/ui/error-codes/E0565.rs: New test. * rust/rustc/ui/error-codes/E0572.rs: New test. * rust/rustc/ui/error-codes/E0582.rs: New test. * rust/rustc/ui/error-codes/E0583.rs: New test. * rust/rustc/ui/error-codes/E0585.rs: New test. * rust/rustc/ui/error-codes/E0586.rs: New test. * rust/rustc/ui/error-codes/E0594.rs: New test. * rust/rustc/ui/error-codes/E0596.rs: New test. * rust/rustc/ui/error-codes/E0597.rs: New test. * rust/rustc/ui/error-codes/E0599.rs: New test. * rust/rustc/ui/error-codes/E0600.rs: New test. * rust/rustc/ui/error-codes/E0601.rs: New test. * rust/rustc/ui/error-codes/E0602.rs: New test. * rust/rustc/ui/error-codes/E0603.rs: New test. * rust/rustc/ui/error-codes/E0604.rs: New test. * rust/rustc/ui/error-codes/E0605.rs: New test. * rust/rustc/ui/error-codes/E0606.rs: New test. * rust/rustc/ui/error-codes/E0607.rs: New test. * rust/rustc/ui/error-codes/E0608.rs: New test. * rust/rustc/ui/error-codes/E0609.rs: New test. * rust/rustc/ui/error-codes/E0610.rs: New test. * rust/rustc/ui/error-codes/E0614.rs: New test. * rust/rustc/ui/error-codes/E0615.rs: New test. * rust/rustc/ui/error-codes/E0616.rs: New test. * rust/rustc/ui/error-codes/E0617.rs: New test. * rust/rustc/ui/error-codes/E0618.rs: New test. * rust/rustc/ui/error-codes/E0620.rs: New test. * rust/rustc/ui/error-codes/E0621-does-not-trigger-for-closures.rs: New test. * rust/rustc/ui/error-codes/E0622.rs: New test. * rust/rustc/ui/error-codes/E0624.rs: New test. * rust/rustc/ui/error-codes/E0637.rs: New test. * rust/rustc/ui/error-codes/E0642.rs: New test. * rust/rustc/ui/error-codes/E0646.rs: New test. * rust/rustc/ui/error-codes/E0647.rs: New test. * rust/rustc/ui/error-codes/E0648.rs: New test. * rust/rustc/ui/error-codes/E0657.rs: New test. * rust/rustc/ui/error-codes/E0658.rs: New test. * rust/rustc/ui/error-codes/E0659.rs: New test. * rust/rustc/ui/error-codes/E0660.rs: New test. * rust/rustc/ui/error-codes/E0661.rs: New test. * rust/rustc/ui/error-codes/E0662.rs: New test. * rust/rustc/ui/error-codes/E0663.rs: New test. * rust/rustc/ui/error-codes/E0664.rs: New test. * rust/rustc/ui/error-codes/E0665.rs: New test. * rust/rustc/ui/error-codes/E0705.rs: New test. * rust/rustc/ui/error-codes/E0718.rs: New test. * rust/rustc/ui/error-codes/E0719.rs: New test. * rust/rustc/ui/error-codes/E0730.rs: New test. * rust/rustc/ui/error-codes/E0746.rs: New test. * rust/rustc/ui/error-codes/E0767.rs: New test. * rust/rustc/ui/error-codes/E0771.rs: New test. * rust/rustc/ui/error-codes/E0777.rs: New test. * rust/rustc/ui/error-codes/E0778.rs: New test. * rust/rustc/ui/error-codes/E0779.rs: New test. * rust/rustc/ui/error-codes/e0119/auxiliary/complex_impl_support.rs: New test. * rust/rustc/ui/error-codes/e0119/auxiliary/issue-23563-a.rs: New test. * rust/rustc/ui/error-codes/e0119/complex-impl.rs: New test. * rust/rustc/ui/error-codes/e0119/conflict-with-std.rs: New test. * rust/rustc/ui/error-codes/e0119/issue-23563.rs: New test. * rust/rustc/ui/error-codes/e0119/issue-27403.rs: New test. * rust/rustc/ui/error-codes/e0119/issue-28981.rs: New test. * rust/rustc/ui/error-codes/e0119/so-37347311.rs: New test. * rust/rustc/ui/error-codes/ex-E0611.rs: New test. * rust/rustc/ui/error-codes/ex-E0612.rs: New test. * rust/rustc/ui/error-festival.rs: New test. * rust/rustc/ui/error-should-say-copy-not-pod.rs: New test. * rust/rustc/ui/estr-subtyping.rs: New test. * rust/rustc/ui/estr-uniq.rs: New test. * rust/rustc/ui/eval-enum.rs: New test. * rust/rustc/ui/exclusive-drop-and-copy.rs: New test. * rust/rustc/ui/exec-env.rs: New test. * rust/rustc/ui/expanded-cfg.rs: New test. * rust/rustc/ui/explain.rs: New test. * rust/rustc/ui/explicit-i-suffix.rs: New test. * rust/rustc/ui/explicit/explicit-call-to-dtor.rs: New test. * rust/rustc/ui/explicit/explicit-call-to-supertrait-dtor.rs: New test. * rust/rustc/ui/explicit/explicit-self-lifetime-mismatch.rs: New test. * rust/rustc/ui/explore-issue-38412.rs: New test. * rust/rustc/ui/export-fully-qualified.rs: New test. * rust/rustc/ui/export-glob-imports-target.rs: New test. * rust/rustc/ui/export-import.rs: New test. * rust/rustc/ui/export-multi.rs: New test. * rust/rustc/ui/export-non-interference2.rs: New test. * rust/rustc/ui/export-non-interference3.rs: New test. * rust/rustc/ui/export-tag-variant.rs: New test. * rust/rustc/ui/export.rs: New test. * rust/rustc/ui/export2.rs: New test. * rust/rustc/ui/expr-block-fn.rs: New test. * rust/rustc/ui/expr-block-generic-unique1.rs: New test. * rust/rustc/ui/expr-block-generic-unique2.rs: New test. * rust/rustc/ui/expr-block-generic.rs: New test. * rust/rustc/ui/expr-block-slot.rs: New test. * rust/rustc/ui/expr-block-unique.rs: New test. * rust/rustc/ui/expr-block.rs: New test. * rust/rustc/ui/expr-copy.rs: New test. * rust/rustc/ui/expr-empty-ret.rs: New test. * rust/rustc/ui/expr-fn.rs: New test. * rust/rustc/ui/expr-if-generic.rs: New test. * rust/rustc/ui/expr-if-panic-all.rs: New test. * rust/rustc/ui/expr-if-panic.rs: New test. * rust/rustc/ui/expr-if-unique.rs: New test. * rust/rustc/ui/expr-if.rs: New test. * rust/rustc/ui/expr-scope.rs: New test. * rust/rustc/ui/expr_attr_paren_order.rs: New test. * rust/rustc/ui/ext-expand-inner-exprs.rs: New test. * rust/rustc/ui/ext-nonexistent.rs: New test. * rust/rustc/ui/extend-for-unit.rs: New test. * rust/rustc/ui/extenv/extenv-arg-2-not-string-literal.rs: New test. * rust/rustc/ui/extenv/extenv-no-args.rs: New test. * rust/rustc/ui/extenv/extenv-not-defined-custom.rs: New test. * rust/rustc/ui/extenv/extenv-not-defined-default.rs: New test. * rust/rustc/ui/extenv/extenv-not-string-literal.rs: New test. * rust/rustc/ui/extenv/extenv-too-many-args.rs: New test. * rust/rustc/ui/extenv/issue-55897.rs: New test. * rust/rustc/ui/extern-flag/auxiliary/somedep.rs: New test. * rust/rustc/ui/extern-flag/multiple-opts.rs: New test. * rust/rustc/ui/extern-flag/noprelude-and-prelude.rs: New test. * rust/rustc/ui/extern-flag/noprelude-resolves.rs: New test. * rust/rustc/ui/extern-flag/noprelude.rs: New test. * rust/rustc/ui/extern-flag/public-and-private.rs: New test. * rust/rustc/ui/extern-prelude-fail.rs: New test. * rust/rustc/ui/extern-prelude.rs: New test. * rust/rustc/ui/extern/auxiliary/extern-take-value.rs: New test. * rust/rustc/ui/extern/auxiliary/extern-types-inherent-impl.rs: New test. * rust/rustc/ui/extern/auxiliary/extern_calling_convention.rs: New test. * rust/rustc/ui/extern/auxiliary/extern_mod_ordering_lib.rs: New test. * rust/rustc/ui/extern/auxiliary/fat_drop.rs: New test. * rust/rustc/ui/extern/auxiliary/m1.rs: New test. * rust/rustc/ui/extern/auxiliary/m2.rs: New test. * rust/rustc/ui/extern/extern-1.rs: New test. * rust/rustc/ui/extern/extern-calling-convention-test.rs: New test. * rust/rustc/ui/extern/extern-compare-with-return-type.rs: New test. * rust/rustc/ui/extern/extern-const.rs: New test. * rust/rustc/ui/extern/extern-crate-rename.rs: New test. * rust/rustc/ui/extern/extern-crate-visibility.rs: New test. * rust/rustc/ui/extern/extern-ffi-fn-with-body.rs: New test. * rust/rustc/ui/extern/extern-foreign-crate.rs: New test. * rust/rustc/ui/extern/extern-macro.rs: New test. * rust/rustc/ui/extern/extern-main-fn.rs: New test. * rust/rustc/ui/extern/extern-methods.rs: New test. * rust/rustc/ui/extern/extern-mod-abi.rs: New test. * rust/rustc/ui/extern/extern-mod-ordering-exe.rs: New test. * rust/rustc/ui/extern/extern-prelude-core.rs: New test. * rust/rustc/ui/extern/extern-prelude-no-speculative.rs: New test. * rust/rustc/ui/extern/extern-prelude-std.rs: New test. * rust/rustc/ui/extern/extern-pub.rs: New test. * rust/rustc/ui/extern/extern-rust.rs: New test. * rust/rustc/ui/extern/extern-take-value.rs: New test. * rust/rustc/ui/extern/extern-thiscall.rs: New test. * rust/rustc/ui/extern/extern-types-distinct-types.rs: New test. * rust/rustc/ui/extern/extern-types-inherent-impl.rs: New test. * rust/rustc/ui/extern/extern-types-manual-sync-send.rs: New test. * rust/rustc/ui/extern/extern-types-not-sync-send.rs: New test. * rust/rustc/ui/extern/extern-types-pointer-cast.rs: New test. * rust/rustc/ui/extern/extern-types-size_of_val.rs: New test. * rust/rustc/ui/extern/extern-types-thin-pointer.rs: New test. * rust/rustc/ui/extern/extern-types-trait-impl.rs: New test. * rust/rustc/ui/extern/extern-types-unsized.rs: New test. * rust/rustc/ui/extern/extern-vectorcall.rs: New test. * rust/rustc/ui/extern/extern-with-type-bounds.rs: New test. * rust/rustc/ui/extern/extern-wrong-value-type.rs: New test. * rust/rustc/ui/extern/extern_fat_drop.rs: New test. * rust/rustc/ui/extern/external-doc-error.rs: New test. * rust/rustc/ui/extern/issue-36122-accessing-externed-dst.rs: New test. * rust/rustc/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs: New test. * rust/rustc/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs: New test. * rust/rustc/ui/extoption_env-no-args.rs: New test. * rust/rustc/ui/extoption_env-not-defined.rs: New test. * rust/rustc/ui/extoption_env-not-string-literal.rs: New test. * rust/rustc/ui/extoption_env-too-many-args.rs: New test. * rust/rustc/ui/fact.rs: New test. * rust/rustc/ui/fail-simple.rs: New test. * rust/rustc/ui/fat-lto.rs: New test. * rust/rustc/ui/fat-ptr-cast-rpass.rs: New test. * rust/rustc/ui/fat-ptr-cast.rs: New test. * rust/rustc/ui/fds-are-cloexec.rs: New test. * rust/rustc/ui/feature-gate-inline_const.rs: New test. * rust/rustc/ui/feature-gate-isa_attribute.rs: New test. * rust/rustc/ui/feature-gate-optimize_attribute.rs: New test. * rust/rustc/ui/feature-gate/allow-features-empty.rs: New test. * rust/rustc/ui/feature-gate/allow-features.rs: New test. * rust/rustc/ui/feature-gate/duplicate-features.rs: New test. * rust/rustc/ui/feature-gate/feature-gate-c_variadic.rs: New test. * rust/rustc/ui/feature-gate/feature-gate-static-nobundle-2.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-bench.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-deprecated.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-derive-2.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-derive.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-macro_escape.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-macro_use.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-stable.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-test.rs: New test. * rust/rustc/ui/feature-gate/issue-43106-gating-of-unstable.rs: New test. * rust/rustc/ui/feature-gate/issue-49983-see-issue-0.rs: New test. * rust/rustc/ui/feature-gate/rustc-private.rs: New test. * rust/rustc/ui/feature-gate/stability-attribute-consistency.rs: New test. * rust/rustc/ui/feature-gate/unknown-feature.rs: New test. * rust/rustc/ui/feature-gate/unstable-attribute-allow-issue-0.rs: New test. * rust/rustc/ui/feature-gated-feature-in-macro-arg.rs: New test. * rust/rustc/ui/feature-gates/auxiliary/cfg-target-thread-local.rs: New test. * rust/rustc/ui/feature-gates/auxiliary/pub_dep.rs: New test. * rust/rustc/ui/feature-gates/auxiliary/re_rebalance_coherence_lib.rs: New test. * rust/rustc/ui/feature-gates/bench.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-abi-avr-interrupt.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-abi.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-abi_unadjusted.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-alloc-error-handler.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-allocator_internals.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable-struct.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-allow_fail.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-arbitrary-self-types.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-asm.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-asm2.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-assoc-type-defaults.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-associated_type_bounds.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-box-expr.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-box_patterns.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-box_syntax.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-cfg-panic.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-cfg-target-has-atomic.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-cfg-target-thread-local.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-cfg-version.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-cfg_sanitize.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-compiler-builtins.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-concat_idents.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-concat_idents2.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-concat_idents3.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-const-indexing.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-const_fn.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-const_fn_transmute.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-const_generics-ptr.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-const_generics.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-crate_visibility_modifier.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-custom_attribute.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-custom_attribute2.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-custom_test_frameworks.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-decl_macro.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-default_type_parameter_fallback.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-destructuring_assignment.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-doc_cfg.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-doc_keyword.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-doc_masked.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-doc_spotlight.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-exclusive-range-pattern.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-exhaustive-patterns.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-extern_absolute_paths.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-extern_prelude.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-extern_types.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-external_doc.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-feature-gate.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-ffi_const.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-ffi_pure.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-ffi_returns_twice.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-format_args_nl.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-fundamental.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-generators.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-generic_associated_types.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-global_asm.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-impl_trait_in_bindings.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-in_band_lifetimes.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-infer_static_outlives_requirements.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-intrinsics.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-is_sorted.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-label_break_value.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-lang-items.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-link_args.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-link_cfg.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-link_llvm_intrinsics.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-linkage.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-lint-reasons.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-log_syntax.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-log_syntax2.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-main.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-marker_trait_attr.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-may-dangle.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-member-constraints.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-min_const_fn.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-naked_functions.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-needs-allocator.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-negate-unsigned.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-never_type.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-nll.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-no_core.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-no_sanitize.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-non_ascii_idents.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-optin-builtin-traits.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-overlapping_marker_traits.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-plugin_registrar.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-prelude_import.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-profiler-runtime.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-public_private_dependencies.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-register_attr.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-register_tool.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-repr-simd.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-repr128.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-rustc-attrs-1.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-rustc-attrs.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-rustc_const_unstable.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-simd-ffi.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-simd.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-staged_api.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-start.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-static-nobundle.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-stmt_expr_attributes.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-thread_local.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-trace_macros.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-trait-alias.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-transparent_unions.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-trivial_bounds-lint.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-trivial_bounds.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-try_blocks.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-try_reserve.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-type_alias_impl_trait.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-type_ascription.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-method-calls.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-ufcs-calls.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-unboxed-closures.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-unsafe_block_in_unsafe_fn.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-unsized_fn_params.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-unsized_locals.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-untagged_unions.rs: New test. * rust/rustc/ui/feature-gates/feature-gate-unwind-attributes.rs: New test. * rust/rustc/ui/ffi_const.rs: New test. * rust/rustc/ui/ffi_const2.rs: New test. * rust/rustc/ui/ffi_pure.rs: New test. * rust/rustc/ui/ffi_returns_twice.rs: New test. * rust/rustc/ui/filter-block-view-items.rs: New test. * rust/rustc/ui/fixup-deref-mut.rs: New test. * rust/rustc/ui/float-literal-inference-restrictions.rs: New test. * rust/rustc/ui/fmt/feature-gate-format-args-capture.rs: New test. * rust/rustc/ui/fmt/format-args-capture-macro-hygiene.rs: New test. * rust/rustc/ui/fmt/format-args-capture-missing-variables.rs: New test. * rust/rustc/ui/fmt/format-args-capture.rs: New test. * rust/rustc/ui/fmt/format-string-error-2.rs: New test. * rust/rustc/ui/fmt/format-string-error.rs: New test. * rust/rustc/ui/fmt/incorrect-separator.rs: New test. * rust/rustc/ui/fmt/send-sync.rs: New test. * rust/rustc/ui/fn-in-pat.rs: New test. * rust/rustc/ui/fn/dyn-fn-alignment.rs: New test. * rust/rustc/ui/fn/expr-fn-panic.rs: New test. * rust/rustc/ui/fn/fn-bad-block-type.rs: New test. * rust/rustc/ui/fn/fn-closure-mutable-capture.rs: New test. * rust/rustc/ui/fn/fn-compare-mismatch.rs: New test. * rust/rustc/ui/fn/fn-item-type.rs: New test. * rust/rustc/ui/fn/fn-trait-formatting.rs: New test. * rust/rustc/ui/fn_must_use.rs: New test. * rust/rustc/ui/for-loop-while/auto-loop.rs: New test. * rust/rustc/ui/for-loop-while/break-value.rs: New test. * rust/rustc/ui/for-loop-while/break.rs: New test. * rust/rustc/ui/for-loop-while/for-destruct.rs: New test. * rust/rustc/ui/for-loop-while/for-loop-goofiness.rs: New test. * rust/rustc/ui/for-loop-while/for-loop-has-unit-body.rs: New test. * rust/rustc/ui/for-loop-while/for-loop-into-iterator.rs: New test. * rust/rustc/ui/for-loop-while/for-loop-lifetime-of-unbound-values.rs: New test. * rust/rustc/ui/for-loop-while/for-loop-macro.rs: New test. * rust/rustc/ui/for-loop-while/for-loop-mut-ref-element.rs: New test. * rust/rustc/ui/for-loop-while/for-loop-no-std.rs: New test. * rust/rustc/ui/for-loop-while/for-loop-panic.rs: New test. * rust/rustc/ui/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs: New test. * rust/rustc/ui/for-loop-while/foreach-external-iterators-break.rs: New test. * rust/rustc/ui/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs: New test. * rust/rustc/ui/for-loop-while/foreach-external-iterators-hashmap.rs: New test. * rust/rustc/ui/for-loop-while/foreach-external-iterators-loop.rs: New test. * rust/rustc/ui/for-loop-while/foreach-external-iterators-nested.rs: New test. * rust/rustc/ui/for-loop-while/foreach-external-iterators.rs: New test. * rust/rustc/ui/for-loop-while/foreach-nested.rs: New test. * rust/rustc/ui/for-loop-while/foreach-put-structured.rs: New test. * rust/rustc/ui/for-loop-while/foreach-simple-outer-slot.rs: New test. * rust/rustc/ui/for-loop-while/label_break_value.rs: New test. * rust/rustc/ui/for-loop-while/labeled-break.rs: New test. * rust/rustc/ui/for-loop-while/linear-for-loop.rs: New test. * rust/rustc/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs: New test. * rust/rustc/ui/for-loop-while/liveness-loop-break.rs: New test. * rust/rustc/ui/for-loop-while/liveness-move-in-loop.rs: New test. * rust/rustc/ui/for-loop-while/loop-break-cont-1.rs: New test. * rust/rustc/ui/for-loop-while/loop-break-cont.rs: New test. * rust/rustc/ui/for-loop-while/loop-break-value.rs: New test. * rust/rustc/ui/for-loop-while/loop-diverges.rs: New test. * rust/rustc/ui/for-loop-while/loop-label-shadowing.rs: New test. * rust/rustc/ui/for-loop-while/loop-labeled-break-value.rs: New test. * rust/rustc/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs: New test. * rust/rustc/ui/for-loop-while/loop-scope.rs: New test. * rust/rustc/ui/for-loop-while/while-cont.rs: New test. * rust/rustc/ui/for-loop-while/while-flow-graph.rs: New test. * rust/rustc/ui/for-loop-while/while-label.rs: New test. * rust/rustc/ui/for-loop-while/while-let.rs: New test. * rust/rustc/ui/for-loop-while/while-loop-constraints-2.rs: New test. * rust/rustc/ui/for-loop-while/while-prelude-drop.rs: New test. * rust/rustc/ui/for-loop-while/while-with-break.rs: New test. * rust/rustc/ui/for-loop-while/while.rs: New test. * rust/rustc/ui/for/for-c-in-str.rs: New test. * rust/rustc/ui/for/for-expn.rs: New test. * rust/rustc/ui/for/for-loop-bogosity.rs: New test. * rust/rustc/ui/for/for-loop-refutable-pattern-error-message.rs: New test. * rust/rustc/ui/for/for-loop-type-error.rs: New test. * rust/rustc/ui/for/for-loop-unconstrained-element-type.rs: New test. * rust/rustc/ui/foreign-fn-return-lifetime.rs: New test. * rust/rustc/ui/foreign-unsafe-fn-called.rs: New test. * rust/rustc/ui/foreign/auxiliary/fn-abi.rs: New test. * rust/rustc/ui/foreign/foreign-fn-linkname.rs: New test. * rust/rustc/ui/foreign/foreign-int-types.rs: New test. * rust/rustc/ui/foreign/foreign-mod-src/inner.rs: New test. * rust/rustc/ui/foreign/foreign-mod-unused-const.rs: New test. * rust/rustc/ui/foreign/foreign-src/foreign.rs: New test. * rust/rustc/ui/foreign/foreign-truncated-arguments.rs: New test. * rust/rustc/ui/foreign/foreign2.rs: New test. * rust/rustc/ui/foreign/issue-74120-lowering-of-ffi-block-bodies.rs: New test. * rust/rustc/ui/format-no-std.rs: New test. * rust/rustc/ui/fsu-moves-and-copies.rs: New test. * rust/rustc/ui/fully-qualified-type/fully-qualified-type-name1.rs: New test. * rust/rustc/ui/fully-qualified-type/fully-qualified-type-name2.rs: New test. * rust/rustc/ui/fully-qualified-type/fully-qualified-type-name4.rs: New test. * rust/rustc/ui/fun-call-variants.rs: New test. * rust/rustc/ui/fun-indirect-call.rs: New test. * rust/rustc/ui/functional-struct-update/functional-struct-update-noncopyable.rs: New test. * rust/rustc/ui/functional-struct-update/functional-struct-update-respects-privacy.rs: New test. * rust/rustc/ui/functions-closures/auxiliary/fn-abi.rs: New test. * rust/rustc/ui/functions-closures/call-closure-from-overloaded-op.rs: New test. * rust/rustc/ui/functions-closures/capture-clauses-boxed-closures.rs: New test. * rust/rustc/ui/functions-closures/capture-clauses-unboxed-closures.rs: New test. * rust/rustc/ui/functions-closures/clone-closure.rs: New test. * rust/rustc/ui/functions-closures/closure-bounds-can-capture-chan.rs: New test. * rust/rustc/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs: New test. * rust/rustc/ui/functions-closures/closure-expected-type/issue-38714.rs: New test. * rust/rustc/ui/functions-closures/closure-expected-type/supply-just-return-type.rs: New test. * rust/rustc/ui/functions-closures/closure-expected-type/supply-nothing.rs: New test. * rust/rustc/ui/functions-closures/closure-immediate.rs: New test. * rust/rustc/ui/functions-closures/closure-inference.rs: New test. * rust/rustc/ui/functions-closures/closure-inference2.rs: New test. * rust/rustc/ui/functions-closures/closure-reform.rs: New test. * rust/rustc/ui/functions-closures/closure-returning-closure.rs: New test. * rust/rustc/ui/functions-closures/closure-to-fn-coercion.rs: New test. * rust/rustc/ui/functions-closures/closure_to_fn_coercion-expected-types.rs: New test. * rust/rustc/ui/functions-closures/copy-closure.rs: New test. * rust/rustc/ui/functions-closures/fn-abi.rs: New test. * rust/rustc/ui/functions-closures/fn-bare-assign.rs: New test. * rust/rustc/ui/functions-closures/fn-bare-coerce-to-block.rs: New test. * rust/rustc/ui/functions-closures/fn-bare-item.rs: New test. * rust/rustc/ui/functions-closures/fn-bare-size.rs: New test. * rust/rustc/ui/functions-closures/fn-bare-spawn.rs: New test. * rust/rustc/ui/functions-closures/fn-coerce-field.rs: New test. * rust/rustc/ui/functions-closures/fn-item-type-cast.rs: New test. * rust/rustc/ui/functions-closures/fn-item-type-coerce.rs: New test. * rust/rustc/ui/functions-closures/fn-item-type-zero-sized.rs: New test. * rust/rustc/ui/functions-closures/fn-lval.rs: New test. * rust/rustc/ui/functions-closures/fn-type-infer.rs: New test. * rust/rustc/ui/functions-closures/implied-bounds-closure-arg-outlives.rs: New test. * rust/rustc/ui/functions-closures/nullable-pointer-opt-closures.rs: New test. * rust/rustc/ui/functions-closures/parallel-codegen-closures.rs: New test. * rust/rustc/ui/functions-closures/return-from-closure.rs: New test. * rust/rustc/ui/future-incompatible-lint-group.rs: New test. * rust/rustc/ui/gated-bad-feature.rs: New test. * rust/rustc/ui/generator/addassign-yield.rs: New test. * rust/rustc/ui/generator/async-generator-issue-67158.rs: New test. * rust/rustc/ui/generator/auto-trait-regions.rs: New test. * rust/rustc/ui/generator/auxiliary/xcrate-reachable.rs: New test. * rust/rustc/ui/generator/auxiliary/xcrate.rs: New test. * rust/rustc/ui/generator/borrow-in-tail-expr.rs: New test. * rust/rustc/ui/generator/borrowing.rs: New test. * rust/rustc/ui/generator/conditional-drop.rs: New test. * rust/rustc/ui/generator/control-flow.rs: New test. * rust/rustc/ui/generator/discriminant.rs: New test. * rust/rustc/ui/generator/drop-and-replace.rs: New test. * rust/rustc/ui/generator/drop-env.rs: New test. * rust/rustc/ui/generator/dropck-resume.rs: New test. * rust/rustc/ui/generator/dropck.rs: New test. * rust/rustc/ui/generator/generator-region-requirements.rs: New test. * rust/rustc/ui/generator/generator-resume-after-panic.rs: New test. * rust/rustc/ui/generator/generator-with-nll.rs: New test. * rust/rustc/ui/generator/generator-yielding-or-returning-itself.rs: New test. * rust/rustc/ui/generator/issue-44197.rs: New test. * rust/rustc/ui/generator/issue-48048.rs: New test. * rust/rustc/ui/generator/issue-52398.rs: New test. * rust/rustc/ui/generator/issue-53548-1.rs: New test. * rust/rustc/ui/generator/issue-53548.rs: New test. * rust/rustc/ui/generator/issue-57084.rs: New test. * rust/rustc/ui/generator/issue-58888.rs: New test. * rust/rustc/ui/generator/issue-61442-stmt-expr-with-drop.rs: New test. * rust/rustc/ui/generator/issue-62506-two_awaits.rs: New test. * rust/rustc/ui/generator/issue-64620-yield-array-element.rs: New test. * rust/rustc/ui/generator/issue-68112.rs: New test. * rust/rustc/ui/generator/issue-69017.rs: New test. * rust/rustc/ui/generator/issue-69039.rs: New test. * rust/rustc/ui/generator/iterator-count.rs: New test. * rust/rustc/ui/generator/live-upvar-across-yield.rs: New test. * rust/rustc/ui/generator/match-bindings.rs: New test. * rust/rustc/ui/generator/nested_generators.rs: New test. * rust/rustc/ui/generator/niche-in-generator.rs: New test. * rust/rustc/ui/generator/non-static-is-unpin.rs: New test. * rust/rustc/ui/generator/not-send-sync.rs: New test. * rust/rustc/ui/generator/overlap-locals.rs: New test. * rust/rustc/ui/generator/panic-drops-resume.rs: New test. * rust/rustc/ui/generator/panic-drops.rs: New test. * rust/rustc/ui/generator/panic-safe.rs: New test. * rust/rustc/ui/generator/partial-initialization-across-yield.rs: New test. * rust/rustc/ui/generator/pattern-borrow.rs: New test. * rust/rustc/ui/generator/pin-box-generator.rs: New test. * rust/rustc/ui/generator/print/generator-print-verbose-1.rs: New test. * rust/rustc/ui/generator/print/generator-print-verbose-2.rs: New test. * rust/rustc/ui/generator/print/generator-print-verbose-3.rs: New test. * rust/rustc/ui/generator/reborrow-mut-upvar.rs: New test. * rust/rustc/ui/generator/ref-escapes-but-not-over-yield.rs: New test. * rust/rustc/ui/generator/resume-after-return.rs: New test. * rust/rustc/ui/generator/resume-arg-late-bound.rs: New test. * rust/rustc/ui/generator/resume-arg-size.rs: New test. * rust/rustc/ui/generator/resume-live-across-yield.rs: New test. * rust/rustc/ui/generator/retain-resume-ref.rs: New test. * rust/rustc/ui/generator/size-moved-locals.rs: New test. * rust/rustc/ui/generator/sized-yield.rs: New test. * rust/rustc/ui/generator/smoke-resume-args.rs: New test. * rust/rustc/ui/generator/smoke.rs: New test. * rust/rustc/ui/generator/static-generators.rs: New test. * rust/rustc/ui/generator/static-mut-reference-across-yield.rs: New test. * rust/rustc/ui/generator/static-not-unpin.rs: New test. * rust/rustc/ui/generator/static-reference-across-yield.rs: New test. * rust/rustc/ui/generator/too-live-local-in-immovable-gen.rs: New test. * rust/rustc/ui/generator/too-many-parameters.rs: New test. * rust/rustc/ui/generator/type-mismatch-error.rs: New test. * rust/rustc/ui/generator/type-mismatch-signature-deduction.rs: New test. * rust/rustc/ui/generator/xcrate-reachable.rs: New test. * rust/rustc/ui/generator/xcrate.rs: New test. * rust/rustc/ui/generator/yield-in-args-rev.rs: New test. * rust/rustc/ui/generator/yield-in-args.rs: New test. * rust/rustc/ui/generator/yield-in-box.rs: New test. * rust/rustc/ui/generator/yield-in-const.rs: New test. * rust/rustc/ui/generator/yield-in-function.rs: New test. * rust/rustc/ui/generator/yield-in-initializer.rs: New test. * rust/rustc/ui/generator/yield-in-static.rs: New test. * rust/rustc/ui/generator/yield-subtype.rs: New test. * rust/rustc/ui/generator/yield-while-iterating.rs: New test. * rust/rustc/ui/generator/yield-while-local-borrowed.rs: New test. * rust/rustc/ui/generator/yield-while-ref-reborrowed.rs: New test. * rust/rustc/ui/generator/yielding-in-match-guards.rs: New test. * rust/rustc/ui/generic-associated-types/auxiliary/foo_defn.rs: New test. * rust/rustc/ui/generic-associated-types/collections-project-default.rs: New test. * rust/rustc/ui/generic-associated-types/collections.rs: New test. * rust/rustc/ui/generic-associated-types/construct_with_other_type.rs: New test. * rust/rustc/ui/generic-associated-types/cross-crate-bounds.rs: New test. * rust/rustc/ui/generic-associated-types/empty_generics.rs: New test. * rust/rustc/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs: New test. * rust/rustc/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs: New test. * rust/rustc/ui/generic-associated-types/gat-incomplete-warning.rs: New test. * rust/rustc/ui/generic-associated-types/generic-associated-types-where.rs: New test. * rust/rustc/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs: New test. * rust/rustc/ui/generic-associated-types/impl_bounds.rs: New test. * rust/rustc/ui/generic-associated-types/impl_bounds_ok.rs: New test. * rust/rustc/ui/generic-associated-types/issue-47206-where-clause.rs: New test. * rust/rustc/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs: New test. * rust/rustc/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs: New test. * rust/rustc/ui/generic-associated-types/issue-67424.rs: New test. * rust/rustc/ui/generic-associated-types/issue-68641-check-gat-bounds.rs: New test. * rust/rustc/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs: New test. * rust/rustc/ui/generic-associated-types/issue-68643-broken-mir.rs: New test. * rust/rustc/ui/generic-associated-types/issue-68644-codegen-selection.rs: New test. * rust/rustc/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs: New test. * rust/rustc/ui/generic-associated-types/issue-68653.rs: New test. * rust/rustc/ui/generic-associated-types/issue-68656-unsized-values.rs: New test. * rust/rustc/ui/generic-associated-types/issue-74816.rs: New test. * rust/rustc/ui/generic-associated-types/iterable.rs: New test. * rust/rustc/ui/generic-associated-types/missing-bounds.rs: New test. * rust/rustc/ui/generic-associated-types/parameter_number_and_kind.rs: New test. * rust/rustc/ui/generic-associated-types/parameter_number_and_kind_impl.rs: New test. * rust/rustc/ui/generic-associated-types/parse/in-trait-impl.rs: New test. * rust/rustc/ui/generic-associated-types/parse/in-trait.rs: New test. * rust/rustc/ui/generic-associated-types/pointer_family.rs: New test. * rust/rustc/ui/generic-associated-types/projection-bound-cycle-generic.rs: New test. * rust/rustc/ui/generic-associated-types/projection-bound-cycle.rs: New test. * rust/rustc/ui/generic-associated-types/shadowing.rs: New test. * rust/rustc/ui/generic-associated-types/streaming_iterator.rs: New test. * rust/rustc/ui/generic-associated-types/unsatisfied-outlives-bound.rs: New test. * rust/rustc/ui/generics/auxiliary/default_type_params_xc.rs: New test. * rust/rustc/ui/generics/generic-alias-unique.rs: New test. * rust/rustc/ui/generics/generic-arg-mismatch-recover.rs: New test. * rust/rustc/ui/generics/generic-default-type-params-cross-crate.rs: New test. * rust/rustc/ui/generics/generic-default-type-params.rs: New test. * rust/rustc/ui/generics/generic-derived-type.rs: New test. * rust/rustc/ui/generics/generic-exterior-unique.rs: New test. * rust/rustc/ui/generics/generic-extern-lifetime.rs: New test. * rust/rustc/ui/generics/generic-extern-mangle.rs: New test. * rust/rustc/ui/generics/generic-extern.rs: New test. * rust/rustc/ui/generics/generic-fn-infer.rs: New test. * rust/rustc/ui/generics/generic-fn-twice.rs: New test. * rust/rustc/ui/generics/generic-fn-unique.rs: New test. * rust/rustc/ui/generics/generic-fn.rs: New test. * rust/rustc/ui/generics/generic-impl-less-params-with-defaults.rs: New test. * rust/rustc/ui/generics/generic-impl-more-params-with-defaults.rs: New test. * rust/rustc/ui/generics/generic-ivec-leak.rs: New test. * rust/rustc/ui/generics/generic-lifetime-trait-impl.rs: New test. * rust/rustc/ui/generics/generic-newtype-struct.rs: New test. * rust/rustc/ui/generics/generic-no-mangle.rs: New test. * rust/rustc/ui/generics/generic-non-trailing-defaults.rs: New test. * rust/rustc/ui/generics/generic-object.rs: New test. * rust/rustc/ui/generics/generic-param-attrs.rs: New test. * rust/rustc/ui/generics/generic-recursive-tag.rs: New test. * rust/rustc/ui/generics/generic-static-methods.rs: New test. * rust/rustc/ui/generics/generic-tag-corruption.rs: New test. * rust/rustc/ui/generics/generic-tag-local.rs: New test. * rust/rustc/ui/generics/generic-tag-match.rs: New test. * rust/rustc/ui/generics/generic-tag-values.rs: New test. * rust/rustc/ui/generics/generic-tag.rs: New test. * rust/rustc/ui/generics/generic-temporary.rs: New test. * rust/rustc/ui/generics/generic-tup.rs: New test. * rust/rustc/ui/generics/generic-type-less-params-with-defaults.rs: New test. * rust/rustc/ui/generics/generic-type-more-params-with-defaults.rs: New test. * rust/rustc/ui/generics/generic-type-params-forward-mention.rs: New test. * rust/rustc/ui/generics/generic-type-params-name-repr.rs: New test. * rust/rustc/ui/generics/generic-type-synonym.rs: New test. * rust/rustc/ui/generics/generic-type.rs: New test. * rust/rustc/ui/generics/generic-unique.rs: New test. * rust/rustc/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.rs: New test. * rust/rustc/ui/generics/issue-61631-default-type-param-cannot-reference-self.rs: New test. * rust/rustc/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs: New test. * rust/rustc/ui/generics/param-in-ct-in-ty-param-default.rs: New test. * rust/rustc/ui/glob-cycles.rs: New test. * rust/rustc/ui/glob-resolve1.rs: New test. * rust/rustc/ui/global-scope.rs: New test. * rust/rustc/ui/guards.rs: New test. * rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs: New test. * rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs: New test. * rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs: New test. * rust/rustc/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs: New test. * rust/rustc/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs: New test. * rust/rustc/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs: New test. * rust/rustc/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs: New test. * rust/rustc/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs: New test. * rust/rustc/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs: New test. * rust/rustc/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs: New test. * rust/rustc/ui/half-open-range-patterns/half-open-range-pats-semantics.rs: New test. * rust/rustc/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs: New test. * rust/rustc/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs: New test. * rust/rustc/ui/half-open-range-patterns/pat-tuple-4.rs: New test. * rust/rustc/ui/half-open-range-patterns/pat-tuple-5.rs: New test. * rust/rustc/ui/hashmap/hashmap-capacity-overflow.rs: New test. * rust/rustc/ui/hashmap/hashmap-iter-value-lifetime.rs: New test. * rust/rustc/ui/hashmap/hashmap-lifetimes.rs: New test. * rust/rustc/ui/hashmap/hashmap-memory.rs: New test. * rust/rustc/ui/hello.rs: New test. * rust/rustc/ui/hello_world/main.rs: New test. * rust/rustc/ui/hidden-rt-injection.rs: New test. * rust/rustc/ui/hidden-rt-injection2.rs: New test. * rust/rustc/ui/higher-lifetime-bounds.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-parse.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs: New test. * rust/rustc/ui/higher-rank-trait-bounds/issue-59311.rs: New test. * rust/rustc/ui/hr-subtype/hr-subtype.rs: New test. * rust/rustc/ui/hr-subtype/return-static.rs: New test. * rust/rustc/ui/hrtb/due-to-where-clause.rs: New test. * rust/rustc/ui/hrtb/hrtb-cache-issue-54302.rs: New test. * rust/rustc/ui/hrtb/hrtb-conflate-regions.rs: New test. * rust/rustc/ui/hrtb/hrtb-debruijn-in-receiver.rs: New test. * rust/rustc/ui/hrtb/hrtb-exists-forall-fn.rs: New test. * rust/rustc/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs: New test. * rust/rustc/ui/hrtb/hrtb-exists-forall-trait-covariant.rs: New test. * rust/rustc/ui/hrtb/hrtb-exists-forall-trait-invariant.rs: New test. * rust/rustc/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.rs: New test. * rust/rustc/ui/hrtb/hrtb-higher-ranker-supertraits.rs: New test. * rust/rustc/ui/hrtb/hrtb-identity-fn-borrows.rs: New test. * rust/rustc/ui/hrtb/hrtb-just-for-static.rs: New test. * rust/rustc/ui/hrtb/hrtb-perfect-forwarding.rs: New test. * rust/rustc/ui/hrtb/issue-30786.rs: New test. * rust/rustc/ui/hrtb/issue-46989.rs: New test. * rust/rustc/ui/hrtb/issue-57639.rs: New test. * rust/rustc/ui/hrtb/issue-58451.rs: New test. * rust/rustc/ui/hrtb/issue-62203-hrtb-ice.rs: New test. * rust/rustc/ui/html-literals.rs: New test. * rust/rustc/ui/huge-array-simple-32.rs: New test. * rust/rustc/ui/huge-array-simple-64.rs: New test. * rust/rustc/ui/huge-array.rs: New test. * rust/rustc/ui/huge-enum.rs: New test. * rust/rustc/ui/huge-struct.rs: New test. * rust/rustc/ui/hygiene/arguments.rs: New test. * rust/rustc/ui/hygiene/assoc_item_ctxt.rs: New test. * rust/rustc/ui/hygiene/assoc_ty_bindings.rs: New test. * rust/rustc/ui/hygiene/auxiliary/codegen-attrs.rs: New test. * rust/rustc/ui/hygiene/auxiliary/def-site-async-await.rs: New test. * rust/rustc/ui/hygiene/auxiliary/intercrate.rs: New test. * rust/rustc/ui/hygiene/auxiliary/legacy_interaction.rs: New test. * rust/rustc/ui/hygiene/auxiliary/local_inner_macros.rs: New test. * rust/rustc/ui/hygiene/auxiliary/my_crate.rs: New test. * rust/rustc/ui/hygiene/auxiliary/needs_hygiene.rs: New test. * rust/rustc/ui/hygiene/auxiliary/nested-dollar-crate.rs: New test. * rust/rustc/ui/hygiene/auxiliary/not-libstd.rs: New test. * rust/rustc/ui/hygiene/auxiliary/opaque-hygiene.rs: New test. * rust/rustc/ui/hygiene/auxiliary/stdlib-prelude.rs: New test. * rust/rustc/ui/hygiene/auxiliary/transparent-basic.rs: New test. * rust/rustc/ui/hygiene/auxiliary/unhygienic_example.rs: New test. * rust/rustc/ui/hygiene/auxiliary/xcrate.rs: New test. * rust/rustc/ui/hygiene/cross-crate-codegen-attrs.rs: New test. * rust/rustc/ui/hygiene/cross_crate_hygiene.rs: New test. * rust/rustc/ui/hygiene/dollar-crate-modern.rs: New test. * rust/rustc/ui/hygiene/duplicate_lifetimes.rs: New test. * rust/rustc/ui/hygiene/eager-from-opaque-2.rs: New test. * rust/rustc/ui/hygiene/eager-from-opaque.rs: New test. * rust/rustc/ui/hygiene/expansion-info-reset.rs: New test. * rust/rustc/ui/hygiene/extern-prelude-from-opaque-fail.rs: New test. * rust/rustc/ui/hygiene/fields-definition.rs: New test. * rust/rustc/ui/hygiene/fields-move.rs: New test. * rust/rustc/ui/hygiene/fields-numeric-borrowck.rs: New test. * rust/rustc/ui/hygiene/fields.rs: New test. * rust/rustc/ui/hygiene/for-loop.rs: New test. * rust/rustc/ui/hygiene/format-args.rs: New test. * rust/rustc/ui/hygiene/generate-mod.rs: New test. * rust/rustc/ui/hygiene/generic_params.rs: New test. * rust/rustc/ui/hygiene/globs.rs: New test. * rust/rustc/ui/hygiene/hir-res-hygiene.rs: New test. * rust/rustc/ui/hygiene/hygiene-dodging-1.rs: New test. * rust/rustc/ui/hygiene/hygiene.rs: New test. * rust/rustc/ui/hygiene/hygienic-label-1.rs: New test. * rust/rustc/ui/hygiene/hygienic-label-2.rs: New test. * rust/rustc/ui/hygiene/hygienic-label-3.rs: New test. * rust/rustc/ui/hygiene/hygienic-label-4.rs: New test. * rust/rustc/ui/hygiene/hygienic-labels-in-let.rs: New test. * rust/rustc/ui/hygiene/hygienic-labels.rs: New test. * rust/rustc/ui/hygiene/impl_items.rs: New test. * rust/rustc/ui/hygiene/intercrate.rs: New test. * rust/rustc/ui/hygiene/issue-44128.rs: New test. * rust/rustc/ui/hygiene/issue-47311.rs: New test. * rust/rustc/ui/hygiene/issue-47312.rs: New test. * rust/rustc/ui/hygiene/issue-61574-const-parameters.rs: New test. * rust/rustc/ui/hygiene/issue-77523-def-site-async-await.rs: New test. * rust/rustc/ui/hygiene/items.rs: New test. * rust/rustc/ui/hygiene/legacy_interaction.rs: New test. * rust/rustc/ui/hygiene/lexical.rs: New test. * rust/rustc/ui/hygiene/local_inner_macros.rs: New test. * rust/rustc/ui/hygiene/macro-metavars-legacy.rs: New test. * rust/rustc/ui/hygiene/macro-metavars-transparent.rs: New test. * rust/rustc/ui/hygiene/missing-self-diag.rs: New test. * rust/rustc/ui/hygiene/nested-dollar-crate.rs: New test. * rust/rustc/ui/hygiene/nested_macro_privacy.rs: New test. * rust/rustc/ui/hygiene/no_implicit_prelude-2018.rs: New test. * rust/rustc/ui/hygiene/no_implicit_prelude.rs: New test. * rust/rustc/ui/hygiene/panic-location.rs: New test. * rust/rustc/ui/hygiene/pattern-macro.rs: New test. * rust/rustc/ui/hygiene/prelude-import-hygiene.rs: New test. * rust/rustc/ui/hygiene/privacy-early.rs: New test. * rust/rustc/ui/hygiene/privacy.rs: New test. * rust/rustc/ui/hygiene/rustc-macro-transparency.rs: New test. * rust/rustc/ui/hygiene/specialization.rs: New test. * rust/rustc/ui/hygiene/stdlib-prelude-from-opaque-early.rs: New test. * rust/rustc/ui/hygiene/stdlib-prelude-from-opaque-late.rs: New test. * rust/rustc/ui/hygiene/trait_items-2.rs: New test. * rust/rustc/ui/hygiene/trait_items.rs: New test. * rust/rustc/ui/hygiene/transparent-basic.rs: New test. * rust/rustc/ui/hygiene/unpretty-debug.rs: New test. * rust/rustc/ui/hygiene/wrap_unhygienic_example.rs: New test. * rust/rustc/ui/hygiene/xcrate.rs: New test. * rust/rustc/ui/if-attrs/bad-cfg.rs: New test. * rust/rustc/ui/if-attrs/builtin-if-attr.rs: New test. * rust/rustc/ui/if-attrs/cfg-false-if-attr.rs: New test. * rust/rustc/ui/if-attrs/else-attrs.rs: New test. * rust/rustc/ui/if-attrs/gate-whole-expr.rs: New test. * rust/rustc/ui/if-attrs/let-chains-attr.rs: New test. * rust/rustc/ui/if-attrs/stmt-expr-gated.rs: New test. * rust/rustc/ui/if-bot.rs: New test. * rust/rustc/ui/if-check.rs: New test. * rust/rustc/ui/if-else-type-mismatch.rs: New test. * rust/rustc/ui/if-ret.rs: New test. * rust/rustc/ui/if/expr-if-panic-fn.rs: New test. * rust/rustc/ui/if/expr-if-panic.rs: New test. * rust/rustc/ui/if/if-branch-types.rs: New test. * rust/rustc/ui/if/if-check-panic.rs: New test. * rust/rustc/ui/if/if-cond-bot.rs: New test. * rust/rustc/ui/if/if-let-arm-types.rs: New test. * rust/rustc/ui/if/if-let.rs: New test. * rust/rustc/ui/if/if-loop.rs: New test. * rust/rustc/ui/if/if-no-match-bindings.rs: New test. * rust/rustc/ui/if/if-typeck.rs: New test. * rust/rustc/ui/if/if-without-block.rs: New test. * rust/rustc/ui/if/if-without-else-as-fn-expr.rs: New test. * rust/rustc/ui/if/if-without-else-result.rs: New test. * rust/rustc/ui/if/ifmt-bad-arg.rs: New test. * rust/rustc/ui/if/ifmt-bad-format-args.rs: New test. * rust/rustc/ui/if/ifmt-unimpl.rs: New test. * rust/rustc/ui/if/ifmt-unknown-trait.rs: New test. * rust/rustc/ui/ignore-all-the-things.rs: New test. * rust/rustc/ui/illegal-ufcs-drop.rs: New test. * rust/rustc/ui/immut-function-arguments.rs: New test. * rust/rustc/ui/impl-bounds-checking.rs: New test. * rust/rustc/ui/impl-duplicate-methods.rs: New test. * rust/rustc/ui/impl-header-lifetime-elision/assoc-type.rs: New test. * rust/rustc/ui/impl-header-lifetime-elision/dyn-trait.rs: New test. * rust/rustc/ui/impl-header-lifetime-elision/explicit-and-elided-same-header.rs: New test. * rust/rustc/ui/impl-header-lifetime-elision/inherent-impl.rs: New test. * rust/rustc/ui/impl-header-lifetime-elision/path-elided.rs: New test. * rust/rustc/ui/impl-header-lifetime-elision/path-underscore.rs: New test. * rust/rustc/ui/impl-header-lifetime-elision/ref-underscore.rs: New test. * rust/rustc/ui/impl-header-lifetime-elision/trait-elided.rs: New test. * rust/rustc/ui/impl-header-lifetime-elision/trait-underscore.rs: New test. * rust/rustc/ui/impl-inherent-non-conflict.rs: New test. * rust/rustc/ui/impl-not-adjacent-to-type.rs: New test. * rust/rustc/ui/impl-privacy-xc-1.rs: New test. * rust/rustc/ui/impl-privacy-xc-2.rs: New test. * rust/rustc/ui/impl-trait-in-bindings-issue-73003.rs: New test. * rust/rustc/ui/impl-trait-in-bindings.rs: New test. * rust/rustc/ui/impl-trait/associated-impl-trait-type-generic-trait.rs: New test. * rust/rustc/ui/impl-trait/associated-impl-trait-type-trivial.rs: New test. * rust/rustc/ui/impl-trait/associated-impl-trait-type.rs: New test. * rust/rustc/ui/impl-trait/auto-trait-leak-rpass.rs: New test. * rust/rustc/ui/impl-trait/auto-trait-leak.rs: New test. * rust/rustc/ui/impl-trait/auto-trait-leak2.rs: New test. * rust/rustc/ui/impl-trait/auto-trait.rs: New test. * rust/rustc/ui/impl-trait/auxiliary/extra-item.rs: New test. * rust/rustc/ui/impl-trait/auxiliary/no_method_suggested_traits.rs: New test. * rust/rustc/ui/impl-trait/auxiliary/xcrate.rs: New test. * rust/rustc/ui/impl-trait/binding-without-value.rs: New test. * rust/rustc/ui/impl-trait/bindings-opaque.rs: New test. * rust/rustc/ui/impl-trait/bindings.rs: New test. * rust/rustc/ui/impl-trait/bound-normalization-fail.rs: New test. * rust/rustc/ui/impl-trait/bound-normalization-pass.rs: New test. * rust/rustc/ui/impl-trait/bounds_regression.rs: New test. * rust/rustc/ui/impl-trait/can-return-unconstrained-closure.rs: New test. * rust/rustc/ui/impl-trait/closure-calling-parent-fn.rs: New test. * rust/rustc/ui/impl-trait/closure-in-impl-trait-arg.rs: New test. * rust/rustc/ui/impl-trait/closure-in-impl-trait.rs: New test. * rust/rustc/ui/impl-trait/deprecated_annotation.rs: New test. * rust/rustc/ui/impl-trait/does-not-live-long-enough.rs: New test. * rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-assoc.rs: New test. * rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-param.rs: New test. * rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs: New test. * rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-ref-param.rs: New test. * rust/rustc/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs: New test. * rust/rustc/ui/impl-trait/equal-hidden-lifetimes.rs: New test. * rust/rustc/ui/impl-trait/equality-rpass.rs: New test. * rust/rustc/ui/impl-trait/equality.rs: New test. * rust/rustc/ui/impl-trait/equality2.rs: New test. * rust/rustc/ui/impl-trait/example-calendar.rs: New test. * rust/rustc/ui/impl-trait/example-st.rs: New test. * rust/rustc/ui/impl-trait/extra-item.rs: New test. * rust/rustc/ui/impl-trait/hidden-lifetimes.rs: New test. * rust/rustc/ui/impl-trait/impl-generic-mismatch-ab.rs: New test. * rust/rustc/ui/impl-trait/impl-generic-mismatch.rs: New test. * rust/rustc/ui/impl-trait/impl-trait-plus-priority.rs: New test. * rust/rustc/ui/impl-trait/impl_trait_projections.rs: New test. * rust/rustc/ui/impl-trait/issue-55872-1.rs: New test. * rust/rustc/ui/impl-trait/issue-55872-2.rs: New test. * rust/rustc/ui/impl-trait/issue-55872.rs: New test. * rust/rustc/ui/impl-trait/issue-56445.rs: New test. * rust/rustc/ui/impl-trait/issue-57200.rs: New test. * rust/rustc/ui/impl-trait/issue-57201.rs: New test. * rust/rustc/ui/impl-trait/issue-60473.rs: New test. * rust/rustc/ui/impl-trait/issue-67166.rs: New test. * rust/rustc/ui/impl-trait/issue-68532.rs: New test. * rust/rustc/ui/impl-trait/issue-69840.rs: New test. * rust/rustc/ui/impl-trait/issue-72911.rs: New test. * rust/rustc/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs: New test. * rust/rustc/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.rs: New test. * rust/rustc/ui/impl-trait/issues/issue-42479.rs: New test. * rust/rustc/ui/impl-trait/issues/issue-49376.rs: New test. * rust/rustc/ui/impl-trait/issues/issue-52128.rs: New test. * rust/rustc/ui/impl-trait/issues/issue-53457.rs: New test. * rust/rustc/ui/impl-trait/issues/issue-55608-captures-empty-region.rs: New test. * rust/rustc/ui/impl-trait/issues/issue-57464-unexpected-regions.rs: New test. * rust/rustc/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs: New test. * rust/rustc/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs: New test. * rust/rustc/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs: New test. * rust/rustc/ui/impl-trait/issues/issue-65581.rs: New test. * rust/rustc/ui/impl-trait/issues/issue-70877.rs: New test. * rust/rustc/ui/impl-trait/issues/universal-issue-48703.rs: New test. * rust/rustc/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs: New test. * rust/rustc/ui/impl-trait/lifetimes.rs: New test. * rust/rustc/ui/impl-trait/method-suggestion-no-duplication.rs: New test. * rust/rustc/ui/impl-trait/multiple-lifetimes.rs: New test. * rust/rustc/ui/impl-trait/multiple-lifetimes/error-handling-2.rs: New test. * rust/rustc/ui/impl-trait/multiple-lifetimes/error-handling.rs: New test. * rust/rustc/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs: New test. * rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs: New test. * rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs: New test. * rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs: New test. * rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs: New test. * rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs: New test. * rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs: New test. * rust/rustc/ui/impl-trait/must_outlive_least_region_or_bound.rs: New test. * rust/rustc/ui/impl-trait/needs_least_region_or_bound.rs: New test. * rust/rustc/ui/impl-trait/negative-reasoning.rs: New test. * rust/rustc/ui/impl-trait/nested-return-type.rs: New test. * rust/rustc/ui/impl-trait/nesting.rs: New test. * rust/rustc/ui/impl-trait/no-method-suggested-traits.rs: New test. * rust/rustc/ui/impl-trait/no-trait.rs: New test. * rust/rustc/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs: New test. * rust/rustc/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs: New test. * rust/rustc/ui/impl-trait/recursive-impl-trait-type-direct.rs: New test. * rust/rustc/ui/impl-trait/recursive-impl-trait-type-indirect.rs: New test. * rust/rustc/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs: New test. * rust/rustc/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs: New test. * rust/rustc/ui/impl-trait/region-escape-via-bound-contravariant.rs: New test. * rust/rustc/ui/impl-trait/region-escape-via-bound.rs: New test. * rust/rustc/ui/impl-trait/return-position-impl-trait-minimal.rs: New test. * rust/rustc/ui/impl-trait/static-return-lifetime-infered.rs: New test. * rust/rustc/ui/impl-trait/trait_type.rs: New test. * rust/rustc/ui/impl-trait/type-alias-generic-param.rs: New test. * rust/rustc/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs: New test. * rust/rustc/ui/impl-trait/type_parameters_captured.rs: New test. * rust/rustc/ui/impl-trait/universal-mismatched-type.rs: New test. * rust/rustc/ui/impl-trait/universal-two-impl-traits.rs: New test. * rust/rustc/ui/impl-trait/universal_hrtb_anon.rs: New test. * rust/rustc/ui/impl-trait/universal_hrtb_named.rs: New test. * rust/rustc/ui/impl-trait/universal_in_adt_in_parameters.rs: New test. * rust/rustc/ui/impl-trait/universal_in_impl_trait_in_parameters.rs: New test. * rust/rustc/ui/impl-trait/universal_in_trait_defn_parameters.rs: New test. * rust/rustc/ui/impl-trait/universal_multiple_bounds.rs: New test. * rust/rustc/ui/impl-trait/universal_wrong_bounds.rs: New test. * rust/rustc/ui/impl-trait/unsafety-checking-cycle.rs: New test. * rust/rustc/ui/impl-trait/wf-eval-order.rs: New test. * rust/rustc/ui/impl-trait/where-allowed-2.rs: New test. * rust/rustc/ui/impl-trait/where-allowed.rs: New test. * rust/rustc/ui/impl-trait/xcrate.rs: New test. * rust/rustc/ui/impl-trait/xcrate_simple.rs: New test. * rust/rustc/ui/impl-unused-rps-in-assoc-type.rs: New test. * rust/rustc/ui/impl-unused-tps-inherent.rs: New test. * rust/rustc/ui/impl-unused-tps.rs: New test. * rust/rustc/ui/implicit-method-bind.rs: New test. * rust/rustc/ui/import.rs: New test. * rust/rustc/ui/import2.rs: New test. * rust/rustc/ui/import3.rs: New test. * rust/rustc/ui/import4.rs: New test. * rust/rustc/ui/imports/auxiliary/gensymed.rs: New test. * rust/rustc/ui/imports/auxiliary/glob-conflict.rs: New test. * rust/rustc/ui/imports/auxiliary/import_crate_var.rs: New test. * rust/rustc/ui/imports/auxiliary/issue-55811.rs: New test. * rust/rustc/ui/imports/auxiliary/issue-56125.rs: New test. * rust/rustc/ui/imports/auxiliary/two_macros.rs: New test. * rust/rustc/ui/imports/duplicate.rs: New test. * rust/rustc/ui/imports/extern-crate-self/extern-crate-self-fail.rs: New test. * rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-alias.rs: New test. * rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs: New test. * rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-self.rs: New test. * rust/rustc/ui/imports/extern-crate-self/extern-crate-self-pass.rs: New test. * rust/rustc/ui/imports/extern-crate-used.rs: New test. * rust/rustc/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs: New test. * rust/rustc/ui/imports/extern-prelude-extern-crate-cfg.rs: New test. * rust/rustc/ui/imports/extern-prelude-extern-crate-fail.rs: New test. * rust/rustc/ui/imports/extern-prelude-extern-crate-pass.rs: New test. * rust/rustc/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs: New test. * rust/rustc/ui/imports/extern-prelude-extern-crate-shadowing.rs: New test. * rust/rustc/ui/imports/gensymed.rs: New test. * rust/rustc/ui/imports/glob-conflict-cross-crate.rs: New test. * rust/rustc/ui/imports/glob-shadowing.rs: New test. * rust/rustc/ui/imports/glob-use-std.rs: New test. * rust/rustc/ui/imports/import-crate-var.rs: New test. * rust/rustc/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs: New test. * rust/rustc/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs: New test. * rust/rustc/ui/imports/import-crate-with-invalid-spans/main.rs: New test. * rust/rustc/ui/imports/import-from-missing.rs: New test. * rust/rustc/ui/imports/import-from.rs: New test. * rust/rustc/ui/imports/import-glob-0-rpass.rs: New test. * rust/rustc/ui/imports/import-glob-0.rs: New test. * rust/rustc/ui/imports/import-glob-1.rs: New test. * rust/rustc/ui/imports/import-glob-circular.rs: New test. * rust/rustc/ui/imports/import-glob-crate.rs: New test. * rust/rustc/ui/imports/import-in-block.rs: New test. * rust/rustc/ui/imports/import-loop-2.rs: New test. * rust/rustc/ui/imports/import-loop.rs: New test. * rust/rustc/ui/imports/import-prefix-macro-1.rs: New test. * rust/rustc/ui/imports/import-prefix-macro-2.rs: New test. * rust/rustc/ui/imports/import-prefix-macro.rs: New test. * rust/rustc/ui/imports/import-rename.rs: New test. * rust/rustc/ui/imports/import-trailing-comma.rs: New test. * rust/rustc/ui/imports/import-trait-method.rs: New test. * rust/rustc/ui/imports/import.rs: New test. * rust/rustc/ui/imports/import2.rs: New test. * rust/rustc/ui/imports/import3.rs: New test. * rust/rustc/ui/imports/import4.rs: New test. * rust/rustc/ui/imports/import5.rs: New test. * rust/rustc/ui/imports/import6.rs: New test. * rust/rustc/ui/imports/import7.rs: New test. * rust/rustc/ui/imports/import8.rs: New test. * rust/rustc/ui/imports/imports.rs: New test. * rust/rustc/ui/imports/issue-53140.rs: New test. * rust/rustc/ui/imports/issue-53269.rs: New test. * rust/rustc/ui/imports/issue-53512.rs: New test. * rust/rustc/ui/imports/issue-55457.rs: New test. * rust/rustc/ui/imports/issue-55811.rs: New test. * rust/rustc/ui/imports/issue-55884-1.rs: New test. * rust/rustc/ui/imports/issue-55884-2.rs: New test. * rust/rustc/ui/imports/issue-56125.rs: New test. * rust/rustc/ui/imports/issue-56263.rs: New test. * rust/rustc/ui/imports/issue-57015.rs: New test. * rust/rustc/ui/imports/issue-57539.rs: New test. * rust/rustc/ui/imports/issue-62767.rs: New test. * rust/rustc/ui/imports/local-modularized-tricky-fail-1.rs: New test. * rust/rustc/ui/imports/local-modularized-tricky-fail-2.rs: New test. * rust/rustc/ui/imports/local-modularized-tricky-fail-3.rs: New test. * rust/rustc/ui/imports/local-modularized-tricky-pass.rs: New test. * rust/rustc/ui/imports/local-modularized.rs: New test. * rust/rustc/ui/imports/macro-paths.rs: New test. * rust/rustc/ui/imports/macros.rs: New test. * rust/rustc/ui/imports/reexports.rs: New test. * rust/rustc/ui/imports/rfc-1560-warning-cycle.rs: New test. * rust/rustc/ui/imports/shadow_builtin_macros.rs: New test. * rust/rustc/ui/imports/unresolved-imports-used.rs: New test. * rust/rustc/ui/imports/unused-macro-use.rs: New test. * rust/rustc/ui/imports/unused.rs: New test. * rust/rustc/ui/impossible_range.rs: New test. * rust/rustc/ui/in-band-lifetimes.rs: New test. * rust/rustc/ui/in-band-lifetimes/E0687.rs: New test. * rust/rustc/ui/in-band-lifetimes/E0687_where.rs: New test. * rust/rustc/ui/in-band-lifetimes/E0688.rs: New test. * rust/rustc/ui/in-band-lifetimes/elided-lifetimes.rs: New test. * rust/rustc/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.rs: New test. * rust/rustc/ui/in-band-lifetimes/mismatched.rs: New test. * rust/rustc/ui/in-band-lifetimes/mismatched_trait.rs: New test. * rust/rustc/ui/in-band-lifetimes/mismatched_trait_impl-2.rs: New test. * rust/rustc/ui/in-band-lifetimes/mismatched_trait_impl.rs: New test. * rust/rustc/ui/in-band-lifetimes/mut_while_borrow.rs: New test. * rust/rustc/ui/in-band-lifetimes/nested-items.rs: New test. * rust/rustc/ui/in-band-lifetimes/no_in_band_in_struct.rs: New test. * rust/rustc/ui/in-band-lifetimes/no_introducing_in_band_in_locals.rs: New test. * rust/rustc/ui/in-band-lifetimes/shadow.rs: New test. * rust/rustc/ui/inc-range-pat.rs: New test. * rust/rustc/ui/include-macros/mismatched-types.rs: New test. * rust/rustc/ui/include-macros/normalization.rs: New test. * rust/rustc/ui/include-single-expr-helper-1.rs: New test. * rust/rustc/ui/include-single-expr-helper.rs: New test. * rust/rustc/ui/include-single-expr.rs: New test. * rust/rustc/ui/index-bot.rs: New test. * rust/rustc/ui/index-help.rs: New test. * rust/rustc/ui/index_message.rs: New test. * rust/rustc/ui/indexing-requires-a-uint.rs: New test. * rust/rustc/ui/infer-fn-tail-expr.rs: New test. * rust/rustc/ui/inference/auxiliary/inference_unstable_iterator.rs: New test. * rust/rustc/ui/inference/auxiliary/inference_unstable_itertools.rs: New test. * rust/rustc/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs: New test. * rust/rustc/ui/inference/cannot-infer-async.rs: New test. * rust/rustc/ui/inference/cannot-infer-closure.rs: New test. * rust/rustc/ui/inference/infer-binary-operand-behind-reference.rs: New test. * rust/rustc/ui/inference/inference-variable-behind-raw-pointer.rs: New test. * rust/rustc/ui/inference/inference_unstable.rs: New test. * rust/rustc/ui/inference/inference_unstable_featured.rs: New test. * rust/rustc/ui/inference/inference_unstable_forced.rs: New test. * rust/rustc/ui/inference/issue-71732.rs: New test. * rust/rustc/ui/inference/issue-72616.rs: New test. * rust/rustc/ui/infinite/infinite-autoderef.rs: New test. * rust/rustc/ui/infinite/infinite-instantiation.rs: New test. * rust/rustc/ui/infinite/infinite-macro-expansion.rs: New test. * rust/rustc/ui/infinite/infinite-recursion-const-fn.rs: New test. * rust/rustc/ui/infinite/infinite-tag-type-recursion.rs: New test. * rust/rustc/ui/infinite/infinite-vec-type-recursion.rs: New test. * rust/rustc/ui/inherit-env.rs: New test. * rust/rustc/ui/init-large-type.rs: New test. * rust/rustc/ui/init-res-into-things.rs: New test. * rust/rustc/ui/inline-asm-bad-constraint.rs: New test. * rust/rustc/ui/inline-asm-bad-operand.rs: New test. * rust/rustc/ui/inline-const/const-expr-array-init.rs: New test. * rust/rustc/ui/inline-const/const-expr-basic.rs: New test. * rust/rustc/ui/inline-const/const-expr-macro.rs: New test. * rust/rustc/ui/inline-const/const-expr-reference.rs: New test. * rust/rustc/ui/inline-const/const-match-pat-range.rs: New test. * rust/rustc/ui/inline-const/const-match-pat.rs: New test. * rust/rustc/ui/inline-const/macro-with-const.rs: New test. * rust/rustc/ui/inline-disallow-on-variant.rs: New test. * rust/rustc/ui/inlined-main.rs: New test. * rust/rustc/ui/inner-attrs-on-impl.rs: New test. * rust/rustc/ui/inner-module.rs: New test. * rust/rustc/ui/inner-static-type-parameter.rs: New test. * rust/rustc/ui/inner-static.rs: New test. * rust/rustc/ui/instantiable.rs: New test. * rust/rustc/ui/integer-literal-suffix-inference.rs: New test. * rust/rustc/ui/integral-indexing.rs: New test. * rust/rustc/ui/integral-variable-unification-error.rs: New test. * rust/rustc/ui/interior-mutability/interior-mutability.rs: New test. * rust/rustc/ui/internal/auxiliary/internal_unstable.rs: New test. * rust/rustc/ui/internal/internal-unstable-const.rs: New test. * rust/rustc/ui/internal/internal-unstable-noallow.rs: New test. * rust/rustc/ui/internal/internal-unstable-thread-local.rs: New test. * rust/rustc/ui/internal/internal-unstable.rs: New test. * rust/rustc/ui/intrinsics-always-extern.rs: New test. * rust/rustc/ui/intrinsics/auxiliary/cci_intrinsic.rs: New test. * rust/rustc/ui/intrinsics/intrinsic-alignment.rs: New test. * rust/rustc/ui/intrinsics/intrinsic-assume.rs: New test. * rust/rustc/ui/intrinsics/intrinsic-atomics-cc.rs: New test. * rust/rustc/ui/intrinsics/intrinsic-atomics.rs: New test. * rust/rustc/ui/intrinsics/intrinsic-move-val-cleanups.rs: New test. * rust/rustc/ui/intrinsics/intrinsic-move-val.rs: New test. * rust/rustc/ui/intrinsics/intrinsic-nearby.rs: New test. * rust/rustc/ui/intrinsics/intrinsic-unreachable.rs: New test. * rust/rustc/ui/intrinsics/intrinsic-volatile.rs: New test. * rust/rustc/ui/intrinsics/intrinsics-integer.rs: New test. * rust/rustc/ui/intrinsics/intrinsics-math.rs: New test. * rust/rustc/ui/intrinsics/issue-28575.rs: New test. * rust/rustc/ui/intrinsics/panic-uninitialized-zeroed.rs: New test. * rust/rustc/ui/intrinsics/unchecked_math_unsafe.rs: New test. * rust/rustc/ui/intrinsics/unchecked_math_unstable.rs: New test. * rust/rustc/ui/invalid-module-declaration/auxiliary/foo/bar.rs: New test. * rust/rustc/ui/invalid-module-declaration/auxiliary/foo/mod.rs: New test. * rust/rustc/ui/invalid-module-declaration/invalid-module-declaration.rs: New test. * rust/rustc/ui/invalid-rustc_args_required_const-arguments.rs: New test. * rust/rustc/ui/invalid-self-argument/bare-fn-start.rs: New test. * rust/rustc/ui/invalid-self-argument/bare-fn.rs: New test. * rust/rustc/ui/invalid-self-argument/trait-fn.rs: New test. * rust/rustc/ui/invalid/invalid-crate-type.rs: New test. * rust/rustc/ui/invalid/invalid-inline.rs: New test. * rust/rustc/ui/invalid/invalid-macro-matcher.rs: New test. * rust/rustc/ui/invalid/invalid-no-sanitize.rs: New test. * rust/rustc/ui/invalid/invalid-path-in-const.rs: New test. * rust/rustc/ui/invalid/invalid-plugin-attr.rs: New test. * rust/rustc/ui/invalid_crate_type_syntax.rs: New test. * rust/rustc/ui/invalid_dispatch_from_dyn_impls.rs: New test. * rust/rustc/ui/issue-72470-llvm-dominate.rs: New test. * rust/rustc/ui/issue-73914.rs: New test. * rust/rustc/ui/issue-74047.rs: New test. * rust/rustc/ui/issue-76387-llvm-miscompile.rs: New test. * rust/rustc/ui/issue-76597.rs: New test. * rust/rustc/ui/issues-71798.rs: New test. * rust/rustc/ui/issues/auxiliary/cgu_test.rs: New test. * rust/rustc/ui/issues/auxiliary/cgu_test_a.rs: New test. * rust/rustc/ui/issues/auxiliary/cgu_test_b.rs: New test. * rust/rustc/ui/issues/auxiliary/empty-struct.rs: New test. * rust/rustc/ui/issues/auxiliary/i8.rs: New test. * rust/rustc/ui/issues/auxiliary/iss.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-10028.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-10031-aux.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-11224.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-11225-1.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-11225-2.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-11225-3.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-11508.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-11529.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-11680.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-12133-dylib.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-12133-dylib2.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-12133-rlib.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-12612-1.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-12612-2.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-12660-aux.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-13507.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-13620-1.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-13620-2.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-13872-1.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-13872-2.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-13872-3.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-14344-1.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-14344-2.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-14421.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-14422.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-15562.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-16643.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-16725.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-17662.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-17718-aux.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-17718-const-privacy.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-18501.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-18514.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-18711.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-18913-1.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-18913-2.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-19163.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-1920.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-19293.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-19340-1.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-20389.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-21146-inc.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-21202.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-2170-lib.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-2316-a.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-2316-b.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-2380.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-2414-a.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-2414-b.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-2472-b.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-25185-1.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-25185-2.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-2526.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-25467.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-2631-a.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-2723-a.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-29181.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-29265.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-29485.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-3012-1.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-30123-aux.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-30535.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-3136-a.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-31702-1.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-31702-2.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-34796-aux.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-36708.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-36881-aux.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-36954.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-38190.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-38226-aux.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-3979-traits.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-39823.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-40469.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-41053.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-41394.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-41549.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-42007-s.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-4208-cc.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-4545.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-48984-aux.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-49544.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-51798.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-52489.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-52891.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-5518.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-5521.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-56943.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-57271-lib.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-5844-aux.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-59764.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-69725.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-7178.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-73112.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-75907.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-7899.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-8044.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-8259.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-8401.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-9123.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-9155.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-9188.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-9906.rs: New test. * rust/rustc/ui/issues/auxiliary/issue-9968.rs: New test. * rust/rustc/ui/issues/auxiliary/lint-stability.rs: New test. * rust/rustc/ui/issues/auxiliary/private-trait-xc.rs: New test. * rust/rustc/ui/issues/auxiliary/reexported-trait.rs: New test. * rust/rustc/ui/issues/auxiliary/xcrate-issue-43189-a.rs: New test. * rust/rustc/ui/issues/auxiliary/xcrate-issue-43189-b.rs: New test. * rust/rustc/ui/issues/auxiliary/xcrate-issue-46112-rexport-core.rs: New test. * rust/rustc/ui/issues/auxiliary/xcrate-issue-61711-b.rs: New test. * rust/rustc/ui/issues/issue-10025.rs: New test. * rust/rustc/ui/issues/issue-10028.rs: New test. * rust/rustc/ui/issues/issue-10031.rs: New test. * rust/rustc/ui/issues/issue-10176.rs: New test. * rust/rustc/ui/issues/issue-10200.rs: New test. * rust/rustc/ui/issues/issue-10228.rs: New test. * rust/rustc/ui/issues/issue-10291.rs: New test. * rust/rustc/ui/issues/issue-10392.rs: New test. * rust/rustc/ui/issues/issue-10396.rs: New test. * rust/rustc/ui/issues/issue-10398.rs: New test. * rust/rustc/ui/issues/issue-10401.rs: New test. * rust/rustc/ui/issues/issue-10412.rs: New test. * rust/rustc/ui/issues/issue-10436.rs: New test. * rust/rustc/ui/issues/issue-10456.rs: New test. * rust/rustc/ui/issues/issue-10465.rs: New test. * rust/rustc/ui/issues/issue-10536.rs: New test. * rust/rustc/ui/issues/issue-10545.rs: New test. * rust/rustc/ui/issues/issue-10626.rs: New test. * rust/rustc/ui/issues/issue-10638.rs: New test. * rust/rustc/ui/issues/issue-10656.rs: New test. * rust/rustc/ui/issues/issue-10682.rs: New test. * rust/rustc/ui/issues/issue-10683.rs: New test. * rust/rustc/ui/issues/issue-10718.rs: New test. * rust/rustc/ui/issues/issue-10734.rs: New test. * rust/rustc/ui/issues/issue-10763.rs: New test. * rust/rustc/ui/issues/issue-10764-rpass.rs: New test. * rust/rustc/ui/issues/issue-10764.rs: New test. * rust/rustc/ui/issues/issue-10767.rs: New test. * rust/rustc/ui/issues/issue-10802.rs: New test. * rust/rustc/ui/issues/issue-10806.rs: New test. * rust/rustc/ui/issues/issue-10853.rs: New test. * rust/rustc/ui/issues/issue-10877.rs: New test. * rust/rustc/ui/issues/issue-10902.rs: New test. * rust/rustc/ui/issues/issue-10969.rs: New test. * rust/rustc/ui/issues/issue-10991.rs: New test. * rust/rustc/ui/issues/issue-11004.rs: New test. * rust/rustc/ui/issues/issue-11047.rs: New test. * rust/rustc/ui/issues/issue-11085.rs: New test. * rust/rustc/ui/issues/issue-1112.rs: New test. * rust/rustc/ui/issues/issue-11154.rs: New test. * rust/rustc/ui/issues/issue-11192.rs: New test. * rust/rustc/ui/issues/issue-11205.rs: New test. * rust/rustc/ui/issues/issue-11224.rs: New test. * rust/rustc/ui/issues/issue-11225-1.rs: New test. * rust/rustc/ui/issues/issue-11225-2.rs: New test. * rust/rustc/ui/issues/issue-11225-3.rs: New test. * rust/rustc/ui/issues/issue-11267.rs: New test. * rust/rustc/ui/issues/issue-11319.rs: New test. * rust/rustc/ui/issues/issue-11374.rs: New test. * rust/rustc/ui/issues/issue-11382.rs: New test. * rust/rustc/ui/issues/issue-11384.rs: New test. * rust/rustc/ui/issues/issue-11493.rs: New test. * rust/rustc/ui/issues/issue-11508.rs: New test. * rust/rustc/ui/issues/issue-11515.rs: New test. * rust/rustc/ui/issues/issue-11529.rs: New test. * rust/rustc/ui/issues/issue-11552.rs: New test. * rust/rustc/ui/issues/issue-11577.rs: New test. * rust/rustc/ui/issues/issue-11592.rs: New test. * rust/rustc/ui/issues/issue-11593.rs: New test. * rust/rustc/ui/issues/issue-11612.rs: New test. * rust/rustc/ui/issues/issue-11677.rs: New test. * rust/rustc/ui/issues/issue-11680.rs: New test. * rust/rustc/ui/issues/issue-11681.rs: New test. * rust/rustc/ui/issues/issue-11692-1.rs: New test. * rust/rustc/ui/issues/issue-11692-2.rs: New test. * rust/rustc/ui/issues/issue-11709.rs: New test. * rust/rustc/ui/issues/issue-11740.rs: New test. * rust/rustc/ui/issues/issue-11771.rs: New test. * rust/rustc/ui/issues/issue-11820.rs: New test. * rust/rustc/ui/issues/issue-11844.rs: New test. * rust/rustc/ui/issues/issue-11869.rs: New test. * rust/rustc/ui/issues/issue-11873.rs: New test. * rust/rustc/ui/issues/issue-11940.rs: New test. * rust/rustc/ui/issues/issue-11958.rs: New test. * rust/rustc/ui/issues/issue-12028.rs: New test. * rust/rustc/ui/issues/issue-12033.rs: New test. * rust/rustc/ui/issues/issue-12041.rs: New test. * rust/rustc/ui/issues/issue-12116.rs: New test. * rust/rustc/ui/issues/issue-12127.rs: New test. * rust/rustc/ui/issues/issue-12133-1.rs: New test. * rust/rustc/ui/issues/issue-12133-2.rs: New test. * rust/rustc/ui/issues/issue-12133-3.rs: New test. * rust/rustc/ui/issues/issue-12187-1.rs: New test. * rust/rustc/ui/issues/issue-12187-2.rs: New test. * rust/rustc/ui/issues/issue-12285.rs: New test. * rust/rustc/ui/issues/issue-12369.rs: New test. * rust/rustc/ui/issues/issue-12470.rs: New test. * rust/rustc/ui/issues/issue-1251.rs: New test. * rust/rustc/ui/issues/issue-12511.rs: New test. * rust/rustc/ui/issues/issue-12552.rs: New test. * rust/rustc/ui/issues/issue-12567.rs: New test. * rust/rustc/ui/issues/issue-1257.rs: New test. * rust/rustc/ui/issues/issue-12582.rs: New test. * rust/rustc/ui/issues/issue-12612.rs: New test. * rust/rustc/ui/issues/issue-12660.rs: New test. * rust/rustc/ui/issues/issue-12677.rs: New test. * rust/rustc/ui/issues/issue-12699.rs: New test. * rust/rustc/ui/issues/issue-12729.rs: New test. * rust/rustc/ui/issues/issue-12744.rs: New test. * rust/rustc/ui/issues/issue-12796.rs: New test. * rust/rustc/ui/issues/issue-12860.rs: New test. * rust/rustc/ui/issues/issue-12863.rs: New test. * rust/rustc/ui/issues/issue-12909.rs: New test. * rust/rustc/ui/issues/issue-12920.rs: New test. * rust/rustc/ui/issues/issue-12997-1.rs: New test. * rust/rustc/ui/issues/issue-12997-2.rs: New test. * rust/rustc/ui/issues/issue-13027.rs: New test. * rust/rustc/ui/issues/issue-13033.rs: New test. * rust/rustc/ui/issues/issue-13058.rs: New test. * rust/rustc/ui/issues/issue-13105.rs: New test. * rust/rustc/ui/issues/issue-13167.rs: New test. * rust/rustc/ui/issues/issue-13202.rs: New test. * rust/rustc/ui/issues/issue-13204.rs: New test. * rust/rustc/ui/issues/issue-13214.rs: New test. * rust/rustc/ui/issues/issue-13259-windows-tcb-trash.rs: New test. * rust/rustc/ui/issues/issue-13264.rs: New test. * rust/rustc/ui/issues/issue-13304.rs: New test. * rust/rustc/ui/issues/issue-13323.rs: New test. * rust/rustc/ui/issues/issue-13359.rs: New test. * rust/rustc/ui/issues/issue-13404.rs: New test. * rust/rustc/ui/issues/issue-13405.rs: New test. * rust/rustc/ui/issues/issue-13407.rs: New test. * rust/rustc/ui/issues/issue-13434.rs: New test. * rust/rustc/ui/issues/issue-13446.rs: New test. * rust/rustc/ui/issues/issue-13466.rs: New test. * rust/rustc/ui/issues/issue-13482-2.rs: New test. * rust/rustc/ui/issues/issue-13482.rs: New test. * rust/rustc/ui/issues/issue-13483.rs: New test. * rust/rustc/ui/issues/issue-13497-2.rs: New test. * rust/rustc/ui/issues/issue-13497.rs: New test. * rust/rustc/ui/issues/issue-13507-2.rs: New test. * rust/rustc/ui/issues/issue-1362.rs: New test. * rust/rustc/ui/issues/issue-13620.rs: New test. * rust/rustc/ui/issues/issue-13641.rs: New test. * rust/rustc/ui/issues/issue-13655.rs: New test. * rust/rustc/ui/issues/issue-13665.rs: New test. * rust/rustc/ui/issues/issue-13703.rs: New test. * rust/rustc/ui/issues/issue-13727.rs: New test. * rust/rustc/ui/issues/issue-13763.rs: New test. * rust/rustc/ui/issues/issue-13775.rs: New test. * rust/rustc/ui/issues/issue-13808.rs: New test. * rust/rustc/ui/issues/issue-13837.rs: New test. * rust/rustc/ui/issues/issue-13847.rs: New test. * rust/rustc/ui/issues/issue-13853-2.rs: New test. * rust/rustc/ui/issues/issue-13853-5.rs: New test. * rust/rustc/ui/issues/issue-13853.rs: New test. * rust/rustc/ui/issues/issue-13867.rs: New test. * rust/rustc/ui/issues/issue-13872.rs: New test. * rust/rustc/ui/issues/issue-13902.rs: New test. * rust/rustc/ui/issues/issue-14082.rs: New test. * rust/rustc/ui/issues/issue-14091-2.rs: New test. * rust/rustc/ui/issues/issue-14091.rs: New test. * rust/rustc/ui/issues/issue-14092.rs: New test. * rust/rustc/ui/issues/issue-14221.rs: New test. * rust/rustc/ui/issues/issue-14227.rs: New test. * rust/rustc/ui/issues/issue-14229.rs: New test. * rust/rustc/ui/issues/issue-14254.rs: New test. * rust/rustc/ui/issues/issue-14285.rs: New test. * rust/rustc/ui/issues/issue-14308.rs: New test. * rust/rustc/ui/issues/issue-14309.rs: New test. * rust/rustc/ui/issues/issue-14330.rs: New test. * rust/rustc/ui/issues/issue-14344.rs: New test. * rust/rustc/ui/issues/issue-14366.rs: New test. * rust/rustc/ui/issues/issue-14382.rs: New test. * rust/rustc/ui/issues/issue-14393.rs: New test. * rust/rustc/ui/issues/issue-14399.rs: New test. * rust/rustc/ui/issues/issue-14421.rs: New test. * rust/rustc/ui/issues/issue-14422.rs: New test. * rust/rustc/ui/issues/issue-14456.rs: New test. * rust/rustc/ui/issues/issue-1448-2.rs: New test. * rust/rustc/ui/issues/issue-1451.rs: New test. * rust/rustc/ui/issues/issue-14541.rs: New test. * rust/rustc/ui/issues/issue-14589.rs: New test. * rust/rustc/ui/issues/issue-1460.rs: New test. * rust/rustc/ui/issues/issue-14721.rs: New test. * rust/rustc/ui/issues/issue-1476.rs: New test. * rust/rustc/ui/issues/issue-14772.rs: New test. * rust/rustc/ui/issues/issue-14821.rs: New test. * rust/rustc/ui/issues/issue-14837.rs: New test. * rust/rustc/ui/issues/issue-14845.rs: New test. * rust/rustc/ui/issues/issue-14853.rs: New test. * rust/rustc/ui/issues/issue-14865.rs: New test. * rust/rustc/ui/issues/issue-14875.rs: New test. * rust/rustc/ui/issues/issue-14901.rs: New test. * rust/rustc/ui/issues/issue-14915.rs: New test. * rust/rustc/ui/issues/issue-14919.rs: New test. * rust/rustc/ui/issues/issue-14933.rs: New test. * rust/rustc/ui/issues/issue-14936.rs: New test. * rust/rustc/ui/issues/issue-14940.rs: New test. * rust/rustc/ui/issues/issue-14958.rs: New test. * rust/rustc/ui/issues/issue-14959.rs: New test. * rust/rustc/ui/issues/issue-15034.rs: New test. * rust/rustc/ui/issues/issue-15043.rs: New test. * rust/rustc/ui/issues/issue-15063.rs: New test. * rust/rustc/ui/issues/issue-15080.rs: New test. * rust/rustc/ui/issues/issue-15094.rs: New test. * rust/rustc/ui/issues/issue-15104.rs: New test. * rust/rustc/ui/issues/issue-15129-rpass.rs: New test. * rust/rustc/ui/issues/issue-15129.rs: New test. * rust/rustc/ui/issues/issue-15155.rs: New test. * rust/rustc/ui/issues/issue-15167.rs: New test. * rust/rustc/ui/issues/issue-15189.rs: New test. * rust/rustc/ui/issues/issue-15207.rs: New test. * rust/rustc/ui/issues/issue-15221.rs: New test. * rust/rustc/ui/issues/issue-15260.rs: New test. * rust/rustc/ui/issues/issue-15261.rs: New test. * rust/rustc/ui/issues/issue-15381.rs: New test. * rust/rustc/ui/issues/issue-15444.rs: New test. * rust/rustc/ui/issues/issue-15487.rs: New test. * rust/rustc/ui/issues/issue-15523-big.rs: New test. * rust/rustc/ui/issues/issue-15523.rs: New test. * rust/rustc/ui/issues/issue-15524.rs: New test. * rust/rustc/ui/issues/issue-15562.rs: New test. * rust/rustc/ui/issues/issue-15571.rs: New test. * rust/rustc/ui/issues/issue-15673.rs: New test. * rust/rustc/ui/issues/issue-15689-1.rs: New test. * rust/rustc/ui/issues/issue-15689-2.rs: New test. * rust/rustc/ui/issues/issue-15730.rs: New test. * rust/rustc/ui/issues/issue-15734.rs: New test. * rust/rustc/ui/issues/issue-15735.rs: New test. * rust/rustc/ui/issues/issue-15756.rs: New test. * rust/rustc/ui/issues/issue-15763.rs: New test. * rust/rustc/ui/issues/issue-15774.rs: New test. * rust/rustc/ui/issues/issue-15783.rs: New test. * rust/rustc/ui/issues/issue-15793.rs: New test. * rust/rustc/ui/issues/issue-15858.rs: New test. * rust/rustc/ui/issues/issue-15881-model-lexer-dotdotdot.rs: New test. * rust/rustc/ui/issues/issue-15896.rs: New test. * rust/rustc/ui/issues/issue-15919-32.rs: New test. * rust/rustc/ui/issues/issue-15919-64.rs: New test. * rust/rustc/ui/issues/issue-15965.rs: New test. * rust/rustc/ui/issues/issue-16048.rs: New test. * rust/rustc/ui/issues/issue-16098.rs: New test. * rust/rustc/ui/issues/issue-16149.rs: New test. * rust/rustc/ui/issues/issue-16151.rs: New test. * rust/rustc/ui/issues/issue-16250.rs: New test. * rust/rustc/ui/issues/issue-16256.rs: New test. * rust/rustc/ui/issues/issue-16272.rs: New test. * rust/rustc/ui/issues/issue-16278.rs: New test. * rust/rustc/ui/issues/issue-16338.rs: New test. * rust/rustc/ui/issues/issue-16401.rs: New test. * rust/rustc/ui/issues/issue-16441.rs: New test. * rust/rustc/ui/issues/issue-16452.rs: New test. * rust/rustc/ui/issues/issue-16492.rs: New test. * rust/rustc/ui/issues/issue-16530.rs: New test. * rust/rustc/ui/issues/issue-16538.rs: New test. * rust/rustc/ui/issues/issue-16560.rs: New test. * rust/rustc/ui/issues/issue-16562.rs: New test. * rust/rustc/ui/issues/issue-16596.rs: New test. * rust/rustc/ui/issues/issue-16597-empty.rs: New test. * rust/rustc/ui/issues/issue-16597.rs: New test. * rust/rustc/ui/issues/issue-1660.rs: New test. * rust/rustc/ui/issues/issue-16602-1.rs: New test. * rust/rustc/ui/issues/issue-16602-2.rs: New test. * rust/rustc/ui/issues/issue-16602-3.rs: New test. * rust/rustc/ui/issues/issue-16643.rs: New test. * rust/rustc/ui/issues/issue-16648.rs: New test. * rust/rustc/ui/issues/issue-16668.rs: New test. * rust/rustc/ui/issues/issue-16671.rs: New test. * rust/rustc/ui/issues/issue-16683.rs: New test. * rust/rustc/ui/issues/issue-16725.rs: New test. * rust/rustc/ui/issues/issue-16739.rs: New test. * rust/rustc/ui/issues/issue-16745.rs: New test. * rust/rustc/ui/issues/issue-16774.rs: New test. * rust/rustc/ui/issues/issue-16783.rs: New test. * rust/rustc/ui/issues/issue-16819.rs: New test. * rust/rustc/ui/issues/issue-16922-rpass.rs: New test. * rust/rustc/ui/issues/issue-16922.rs: New test. * rust/rustc/ui/issues/issue-16939.rs: New test. * rust/rustc/ui/issues/issue-1696.rs: New test. * rust/rustc/ui/issues/issue-16966.rs: New test. * rust/rustc/ui/issues/issue-1697.rs: New test. * rust/rustc/ui/issues/issue-16994.rs: New test. * rust/rustc/ui/issues/issue-17001.rs: New test. * rust/rustc/ui/issues/issue-1701.rs: New test. * rust/rustc/ui/issues/issue-17033.rs: New test. * rust/rustc/ui/issues/issue-17068.rs: New test. * rust/rustc/ui/issues/issue-17074.rs: New test. * rust/rustc/ui/issues/issue-17121.rs: New test. * rust/rustc/ui/issues/issue-17170.rs: New test. * rust/rustc/ui/issues/issue-17216.rs: New test. * rust/rustc/ui/issues/issue-17233.rs: New test. * rust/rustc/ui/issues/issue-17252.rs: New test. * rust/rustc/ui/issues/issue-17263.rs: New test. * rust/rustc/ui/issues/issue-17302.rs: New test. * rust/rustc/ui/issues/issue-17322.rs: New test. * rust/rustc/ui/issues/issue-17336.rs: New test. * rust/rustc/ui/issues/issue-17337.rs: New test. * rust/rustc/ui/issues/issue-17351.rs: New test. * rust/rustc/ui/issues/issue-17361.rs: New test. * rust/rustc/ui/issues/issue-17373.rs: New test. * rust/rustc/ui/issues/issue-17385.rs: New test. * rust/rustc/ui/issues/issue-17405.rs: New test. * rust/rustc/ui/issues/issue-17431-1.rs: New test. * rust/rustc/ui/issues/issue-17431-2.rs: New test. * rust/rustc/ui/issues/issue-17431-3.rs: New test. * rust/rustc/ui/issues/issue-17431-4.rs: New test. * rust/rustc/ui/issues/issue-17431-5.rs: New test. * rust/rustc/ui/issues/issue-17431-6.rs: New test. * rust/rustc/ui/issues/issue-17431-7.rs: New test. * rust/rustc/ui/issues/issue-17441.rs: New test. * rust/rustc/ui/issues/issue-17444.rs: New test. * rust/rustc/ui/issues/issue-17450.rs: New test. * rust/rustc/ui/issues/issue-17458.rs: New test. * rust/rustc/ui/issues/issue-17503.rs: New test. * rust/rustc/ui/issues/issue-17545.rs: New test. * rust/rustc/ui/issues/issue-17546.rs: New test. * rust/rustc/ui/issues/issue-17551.rs: New test. * rust/rustc/ui/issues/issue-17651.rs: New test. * rust/rustc/ui/issues/issue-17662.rs: New test. * rust/rustc/ui/issues/issue-17718-borrow-interior.rs: New test. * rust/rustc/ui/issues/issue-17718-const-bad-values.rs: New test. * rust/rustc/ui/issues/issue-17718-const-borrow.rs: New test. * rust/rustc/ui/issues/issue-17718-const-destructors.rs: New test. * rust/rustc/ui/issues/issue-17718-const-naming.rs: New test. * rust/rustc/ui/issues/issue-17718-const-privacy.rs: New test. * rust/rustc/ui/issues/issue-17718-constants-not-static.rs: New test. * rust/rustc/ui/issues/issue-17718-parse-const.rs: New test. * rust/rustc/ui/issues/issue-17718-patterns.rs: New test. * rust/rustc/ui/issues/issue-17718-references.rs: New test. * rust/rustc/ui/issues/issue-17718-static-move.rs: New test. * rust/rustc/ui/issues/issue-17718-static-sync.rs: New test. * rust/rustc/ui/issues/issue-17718-static-unsafe-interior.rs: New test. * rust/rustc/ui/issues/issue-17718.rs: New test. * rust/rustc/ui/issues/issue-17728.rs: New test. * rust/rustc/ui/issues/issue-17732.rs: New test. * rust/rustc/ui/issues/issue-17734.rs: New test. * rust/rustc/ui/issues/issue-17740.rs: New test. * rust/rustc/ui/issues/issue-17746.rs: New test. * rust/rustc/ui/issues/issue-17756.rs: New test. * rust/rustc/ui/issues/issue-17758.rs: New test. * rust/rustc/ui/issues/issue-17771.rs: New test. * rust/rustc/ui/issues/issue-17800.rs: New test. * rust/rustc/ui/issues/issue-17816.rs: New test. * rust/rustc/ui/issues/issue-17877.rs: New test. * rust/rustc/ui/issues/issue-17897.rs: New test. * rust/rustc/ui/issues/issue-17904-2.rs: New test. * rust/rustc/ui/issues/issue-17904.rs: New test. * rust/rustc/ui/issues/issue-17905-2.rs: New test. * rust/rustc/ui/issues/issue-17905.rs: New test. * rust/rustc/ui/issues/issue-17913.rs: New test. * rust/rustc/ui/issues/issue-17933.rs: New test. * rust/rustc/ui/issues/issue-17954.rs: New test. * rust/rustc/ui/issues/issue-17959.rs: New test. * rust/rustc/ui/issues/issue-17994.rs: New test. * rust/rustc/ui/issues/issue-17999.rs: New test. * rust/rustc/ui/issues/issue-18058.rs: New test. * rust/rustc/ui/issues/issue-18060.rs: New test. * rust/rustc/ui/issues/issue-18083.rs: New test. * rust/rustc/ui/issues/issue-18088.rs: New test. * rust/rustc/ui/issues/issue-18107.rs: New test. * rust/rustc/ui/issues/issue-18110.rs: New test. * rust/rustc/ui/issues/issue-18118-2.rs: New test. * rust/rustc/ui/issues/issue-18118.rs: New test. * rust/rustc/ui/issues/issue-18119.rs: New test. * rust/rustc/ui/issues/issue-18159.rs: New test. * rust/rustc/ui/issues/issue-18173.rs: New test. * rust/rustc/ui/issues/issue-18183.rs: New test. * rust/rustc/ui/issues/issue-18188.rs: New test. * rust/rustc/ui/issues/issue-1821.rs: New test. * rust/rustc/ui/issues/issue-18232.rs: New test. * rust/rustc/ui/issues/issue-18294.rs: New test. * rust/rustc/ui/issues/issue-18352.rs: New test. * rust/rustc/ui/issues/issue-18353.rs: New test. * rust/rustc/ui/issues/issue-18389.rs: New test. * rust/rustc/ui/issues/issue-18400.rs: New test. * rust/rustc/ui/issues/issue-18412.rs: New test. * rust/rustc/ui/issues/issue-18423.rs: New test. * rust/rustc/ui/issues/issue-18425.rs: New test. * rust/rustc/ui/issues/issue-18446-2.rs: New test. * rust/rustc/ui/issues/issue-18446.rs: New test. * rust/rustc/ui/issues/issue-18464.rs: New test. * rust/rustc/ui/issues/issue-18501.rs: New test. * rust/rustc/ui/issues/issue-18514.rs: New test. * rust/rustc/ui/issues/issue-18532.rs: New test. * rust/rustc/ui/issues/issue-18539.rs: New test. * rust/rustc/ui/issues/issue-18566.rs: New test. * rust/rustc/ui/issues/issue-18576.rs: New test. * rust/rustc/ui/issues/issue-18611.rs: New test. * rust/rustc/ui/issues/issue-18652.rs: New test. * rust/rustc/ui/issues/issue-18655.rs: New test. * rust/rustc/ui/issues/issue-1866.rs: New test. * rust/rustc/ui/issues/issue-18661.rs: New test. * rust/rustc/ui/issues/issue-18685.rs: New test. * rust/rustc/ui/issues/issue-1871.rs: New test. * rust/rustc/ui/issues/issue-18711.rs: New test. * rust/rustc/ui/issues/issue-18738.rs: New test. * rust/rustc/ui/issues/issue-18767.rs: New test. * rust/rustc/ui/issues/issue-18783.rs: New test. * rust/rustc/ui/issues/issue-18804/auxiliary/lib.rs: New test. * rust/rustc/ui/issues/issue-18804/main.rs: New test. * rust/rustc/ui/issues/issue-18809.rs: New test. * rust/rustc/ui/issues/issue-18819.rs: New test. * rust/rustc/ui/issues/issue-18845.rs: New test. * rust/rustc/ui/issues/issue-18859.rs: New test. * rust/rustc/ui/issues/issue-18906.rs: New test. * rust/rustc/ui/issues/issue-18913.rs: New test. * rust/rustc/ui/issues/issue-18919.rs: New test. * rust/rustc/ui/issues/issue-18937-1.rs: New test. * rust/rustc/ui/issues/issue-18937.rs: New test. * rust/rustc/ui/issues/issue-18952.rs: New test. * rust/rustc/ui/issues/issue-18959.rs: New test. * rust/rustc/ui/issues/issue-18988.rs: New test. * rust/rustc/ui/issues/issue-1900.rs: New test. * rust/rustc/ui/issues/issue-19001.rs: New test. * rust/rustc/ui/issues/issue-19037.rs: New test. * rust/rustc/ui/issues/issue-19081.rs: New test. * rust/rustc/ui/issues/issue-19086.rs: New test. * rust/rustc/ui/issues/issue-19097.rs: New test. * rust/rustc/ui/issues/issue-19098.rs: New test. * rust/rustc/ui/issues/issue-19100.rs: New test. * rust/rustc/ui/issues/issue-19102.rs: New test. * rust/rustc/ui/issues/issue-19127.rs: New test. * rust/rustc/ui/issues/issue-19129-1.rs: New test. * rust/rustc/ui/issues/issue-19129-2.rs: New test. * rust/rustc/ui/issues/issue-19135.rs: New test. * rust/rustc/ui/issues/issue-19163.rs: New test. * rust/rustc/ui/issues/issue-1920-1.rs: New test. * rust/rustc/ui/issues/issue-1920-2.rs: New test. * rust/rustc/ui/issues/issue-1920-3.rs: New test. * rust/rustc/ui/issues/issue-19244-1.rs: New test. * rust/rustc/ui/issues/issue-19244-2.rs: New test. * rust/rustc/ui/issues/issue-19244.rs: New test. * rust/rustc/ui/issues/issue-19293.rs: New test. * rust/rustc/ui/issues/issue-19340-1.rs: New test. * rust/rustc/ui/issues/issue-19340-2.rs: New test. * rust/rustc/ui/issues/issue-19358.rs: New test. * rust/rustc/ui/issues/issue-19367.rs: New test. * rust/rustc/ui/issues/issue-19380.rs: New test. * rust/rustc/ui/issues/issue-19398.rs: New test. * rust/rustc/ui/issues/issue-19404.rs: New test. * rust/rustc/ui/issues/issue-19479.rs: New test. * rust/rustc/ui/issues/issue-19482.rs: New test. * rust/rustc/ui/issues/issue-19498.rs: New test. * rust/rustc/ui/issues/issue-19499.rs: New test. * rust/rustc/ui/issues/issue-19521.rs: New test. * rust/rustc/ui/issues/issue-19538.rs: New test. * rust/rustc/ui/issues/issue-19601.rs: New test. * rust/rustc/ui/issues/issue-1962.rs: New test. * rust/rustc/ui/issues/issue-19631.rs: New test. * rust/rustc/ui/issues/issue-19632.rs: New test. * rust/rustc/ui/issues/issue-19660.rs: New test. * rust/rustc/ui/issues/issue-19692.rs: New test. * rust/rustc/ui/issues/issue-19707.rs: New test. * rust/rustc/ui/issues/issue-19734.rs: New test. * rust/rustc/ui/issues/issue-1974.rs: New test. * rust/rustc/ui/issues/issue-19811-escape-unicode.rs: New test. * rust/rustc/ui/issues/issue-19850.rs: New test. * rust/rustc/ui/issues/issue-19883.rs: New test. * rust/rustc/ui/issues/issue-19922.rs: New test. * rust/rustc/ui/issues/issue-19982.rs: New test. * rust/rustc/ui/issues/issue-19991.rs: New test. * rust/rustc/ui/issues/issue-20005.rs: New test. * rust/rustc/ui/issues/issue-20009.rs: New test. * rust/rustc/ui/issues/issue-20055-box-trait.rs: New test. * rust/rustc/ui/issues/issue-20055-box-unsized-array.rs: New test. * rust/rustc/ui/issues/issue-20091.rs: New test. * rust/rustc/ui/issues/issue-20162.rs: New test. * rust/rustc/ui/issues/issue-20174.rs: New test. * rust/rustc/ui/issues/issue-20186.rs: New test. * rust/rustc/ui/issues/issue-20225.rs: New test. * rust/rustc/ui/issues/issue-20261.rs: New test. * rust/rustc/ui/issues/issue-20313-rpass.rs: New test. * rust/rustc/ui/issues/issue-20313.rs: New test. * rust/rustc/ui/issues/issue-20343.rs: New test. * rust/rustc/ui/issues/issue-20389.rs: New test. * rust/rustc/ui/issues/issue-20396.rs: New test. * rust/rustc/ui/issues/issue-20413.rs: New test. * rust/rustc/ui/issues/issue-20414.rs: New test. * rust/rustc/ui/issues/issue-20427.rs: New test. * rust/rustc/ui/issues/issue-20433.rs: New test. * rust/rustc/ui/issues/issue-20454.rs: New test. * rust/rustc/ui/issues/issue-20544.rs: New test. * rust/rustc/ui/issues/issue-20575.rs: New test. * rust/rustc/ui/issues/issue-20605.rs: New test. * rust/rustc/ui/issues/issue-20616-1.rs: New test. * rust/rustc/ui/issues/issue-20616-2.rs: New test. * rust/rustc/ui/issues/issue-20616-3.rs: New test. * rust/rustc/ui/issues/issue-20616-4.rs: New test. * rust/rustc/ui/issues/issue-20616-5.rs: New test. * rust/rustc/ui/issues/issue-20616-6.rs: New test. * rust/rustc/ui/issues/issue-20616-7.rs: New test. * rust/rustc/ui/issues/issue-20616-8.rs: New test. * rust/rustc/ui/issues/issue-20616-9.rs: New test. * rust/rustc/ui/issues/issue-20616.rs: New test. * rust/rustc/ui/issues/issue-2063-resource.rs: New test. * rust/rustc/ui/issues/issue-2063.rs: New test. * rust/rustc/ui/issues/issue-20644.rs: New test. * rust/rustc/ui/issues/issue-20676.rs: New test. * rust/rustc/ui/issues/issue-20692.rs: New test. * rust/rustc/ui/issues/issue-20714.rs: New test. * rust/rustc/ui/issues/issue-2074.rs: New test. * rust/rustc/ui/issues/issue-20763-1.rs: New test. * rust/rustc/ui/issues/issue-20763-2.rs: New test. * rust/rustc/ui/issues/issue-20772.rs: New test. * rust/rustc/ui/issues/issue-20797.rs: New test. * rust/rustc/ui/issues/issue-20801.rs: New test. * rust/rustc/ui/issues/issue-20803.rs: New test. * rust/rustc/ui/issues/issue-20823.rs: New test. * rust/rustc/ui/issues/issue-20825-2.rs: New test. * rust/rustc/ui/issues/issue-20825.rs: New test. * rust/rustc/ui/issues/issue-20831-debruijn.rs: New test. * rust/rustc/ui/issues/issue-20847.rs: New test. * rust/rustc/ui/issues/issue-20939.rs: New test. * rust/rustc/ui/issues/issue-20953.rs: New test. * rust/rustc/ui/issues/issue-20971.rs: New test. * rust/rustc/ui/issues/issue-21033.rs: New test. * rust/rustc/ui/issues/issue-21058.rs: New test. * rust/rustc/ui/issues/issue-2111.rs: New test. * rust/rustc/ui/issues/issue-21140.rs: New test. * rust/rustc/ui/issues/issue-21146.rs: New test. * rust/rustc/ui/issues/issue-21160.rs: New test. * rust/rustc/ui/issues/issue-21174-2.rs: New test. * rust/rustc/ui/issues/issue-21174.rs: New test. * rust/rustc/ui/issues/issue-21177.rs: New test. * rust/rustc/ui/issues/issue-21202.rs: New test. * rust/rustc/ui/issues/issue-21245.rs: New test. * rust/rustc/ui/issues/issue-21291.rs: New test. * rust/rustc/ui/issues/issue-21306.rs: New test. * rust/rustc/ui/issues/issue-21332.rs: New test. * rust/rustc/ui/issues/issue-21356.rs: New test. * rust/rustc/ui/issues/issue-21361.rs: New test. * rust/rustc/ui/issues/issue-21363.rs: New test. * rust/rustc/ui/issues/issue-21384.rs: New test. * rust/rustc/ui/issues/issue-21400.rs: New test. * rust/rustc/ui/issues/issue-21402.rs: New test. * rust/rustc/ui/issues/issue-21449.rs: New test. * rust/rustc/ui/issues/issue-21475.rs: New test. * rust/rustc/ui/issues/issue-21486.rs: New test. * rust/rustc/ui/issues/issue-2150.rs: New test. * rust/rustc/ui/issues/issue-2151.rs: New test. * rust/rustc/ui/issues/issue-21520.rs: New test. * rust/rustc/ui/issues/issue-21546.rs: New test. * rust/rustc/ui/issues/issue-21554.rs: New test. * rust/rustc/ui/issues/issue-21562.rs: New test. * rust/rustc/ui/issues/issue-21596.rs: New test. * rust/rustc/ui/issues/issue-21600.rs: New test. * rust/rustc/ui/issues/issue-21622.rs: New test. * rust/rustc/ui/issues/issue-21634.rs: New test. * rust/rustc/ui/issues/issue-21655.rs: New test. * rust/rustc/ui/issues/issue-2170-exe.rs: New test. * rust/rustc/ui/issues/issue-21701.rs: New test. * rust/rustc/ui/issues/issue-21721.rs: New test. * rust/rustc/ui/issues/issue-21726.rs: New test. * rust/rustc/ui/issues/issue-21763.rs: New test. * rust/rustc/ui/issues/issue-21837.rs: New test. * rust/rustc/ui/issues/issue-21891.rs: New test. * rust/rustc/ui/issues/issue-2190-1.rs: New test. * rust/rustc/ui/issues/issue-21909.rs: New test. * rust/rustc/ui/issues/issue-21922.rs: New test. * rust/rustc/ui/issues/issue-21946.rs: New test. * rust/rustc/ui/issues/issue-21950.rs: New test. * rust/rustc/ui/issues/issue-21974.rs: New test. * rust/rustc/ui/issues/issue-22008.rs: New test. * rust/rustc/ui/issues/issue-22034.rs: New test. * rust/rustc/ui/issues/issue-22036.rs: New test. * rust/rustc/ui/issues/issue-22037.rs: New test. * rust/rustc/ui/issues/issue-22066.rs: New test. * rust/rustc/ui/issues/issue-2214.rs: New test. * rust/rustc/ui/issues/issue-2216.rs: New test. * rust/rustc/ui/issues/issue-22258.rs: New test. * rust/rustc/ui/issues/issue-22289.rs: New test. * rust/rustc/ui/issues/issue-22312.rs: New test. * rust/rustc/ui/issues/issue-22346.rs: New test. * rust/rustc/ui/issues/issue-22356.rs: New test. * rust/rustc/ui/issues/issue-22370.rs: New test. * rust/rustc/ui/issues/issue-22375.rs: New test. * rust/rustc/ui/issues/issue-22384.rs: New test. * rust/rustc/ui/issues/issue-22403.rs: New test. * rust/rustc/ui/issues/issue-22426.rs: New test. * rust/rustc/ui/issues/issue-22434.rs: New test. * rust/rustc/ui/issues/issue-22463.rs: New test. * rust/rustc/ui/issues/issue-22468.rs: New test. * rust/rustc/ui/issues/issue-22471.rs: New test. * rust/rustc/ui/issues/issue-22536-copy-mustnt-zero.rs: New test. * rust/rustc/ui/issues/issue-22546.rs: New test. * rust/rustc/ui/issues/issue-22560.rs: New test. * rust/rustc/ui/issues/issue-22577.rs: New test. * rust/rustc/ui/issues/issue-22599.rs: New test. * rust/rustc/ui/issues/issue-22603.rs: New test. * rust/rustc/ui/issues/issue-22629.rs: New test. * rust/rustc/ui/issues/issue-22638.rs: New test. * rust/rustc/ui/issues/issue-22644.rs: New test. * rust/rustc/ui/issues/issue-22673.rs: New test. * rust/rustc/ui/issues/issue-22684.rs: New test. * rust/rustc/ui/issues/issue-22706.rs: New test. * rust/rustc/ui/issues/issue-22777.rs: New test. * rust/rustc/ui/issues/issue-22781.rs: New test. * rust/rustc/ui/issues/issue-22789.rs: New test. * rust/rustc/ui/issues/issue-2281-part1.rs: New test. * rust/rustc/ui/issues/issue-22814.rs: New test. * rust/rustc/ui/issues/issue-22828.rs: New test. * rust/rustc/ui/issues/issue-2284.rs: New test. * rust/rustc/ui/issues/issue-22864-1.rs: New test. * rust/rustc/ui/issues/issue-22864-2.rs: New test. * rust/rustc/ui/issues/issue-22872.rs: New test. * rust/rustc/ui/issues/issue-22874.rs: New test. * rust/rustc/ui/issues/issue-2288.rs: New test. * rust/rustc/ui/issues/issue-22886.rs: New test. * rust/rustc/ui/issues/issue-22894.rs: New test. * rust/rustc/ui/issues/issue-22933-1.rs: New test. * rust/rustc/ui/issues/issue-22933-2.rs: New test. * rust/rustc/ui/issues/issue-22992-2.rs: New test. * rust/rustc/ui/issues/issue-22992.rs: New test. * rust/rustc/ui/issues/issue-23024.rs: New test. * rust/rustc/ui/issues/issue-23036.rs: New test. * rust/rustc/ui/issues/issue-23041.rs: New test. * rust/rustc/ui/issues/issue-23046.rs: New test. * rust/rustc/ui/issues/issue-23073.rs: New test. * rust/rustc/ui/issues/issue-2311-2.rs: New test. * rust/rustc/ui/issues/issue-2311.rs: New test. * rust/rustc/ui/issues/issue-2312.rs: New test. * rust/rustc/ui/issues/issue-23122-1.rs: New test. * rust/rustc/ui/issues/issue-23122-2.rs: New test. * rust/rustc/ui/issues/issue-2316-c.rs: New test. * rust/rustc/ui/issues/issue-23173.rs: New test. * rust/rustc/ui/issues/issue-23189.rs: New test. * rust/rustc/ui/issues/issue-23208.rs: New test. * rust/rustc/ui/issues/issue-23217.rs: New test. * rust/rustc/ui/issues/issue-23253.rs: New test. * rust/rustc/ui/issues/issue-23261.rs: New test. * rust/rustc/ui/issues/issue-23281.rs: New test. * rust/rustc/ui/issues/issue-2330.rs: New test. * rust/rustc/ui/issues/issue-23302-1.rs: New test. * rust/rustc/ui/issues/issue-23302-2.rs: New test. * rust/rustc/ui/issues/issue-23302-3.rs: New test. * rust/rustc/ui/issues/issue-23304-1.rs: New test. * rust/rustc/ui/issues/issue-23304-2.rs: New test. * rust/rustc/ui/issues/issue-23311.rs: New test. * rust/rustc/ui/issues/issue-23336.rs: New test. * rust/rustc/ui/issues/issue-23338-ensure-param-drop-order.rs: New test. * rust/rustc/ui/issues/issue-23338-params-outlive-temps-of-body.rs: New test. * rust/rustc/ui/issues/issue-23354-2.rs: New test. * rust/rustc/ui/issues/issue-23354.rs: New test. * rust/rustc/ui/issues/issue-23406.rs: New test. * rust/rustc/ui/issues/issue-23433.rs: New test. * rust/rustc/ui/issues/issue-23442.rs: New test. * rust/rustc/ui/issues/issue-23458.rs: New test. * rust/rustc/ui/issues/issue-23477.rs: New test. * rust/rustc/ui/issues/issue-23485.rs: New test. * rust/rustc/ui/issues/issue-23491.rs: New test. * rust/rustc/ui/issues/issue-23543.rs: New test. * rust/rustc/ui/issues/issue-23544.rs: New test. * rust/rustc/ui/issues/issue-23550.rs: New test. * rust/rustc/ui/issues/issue-23589.rs: New test. * rust/rustc/ui/issues/issue-23595-2.rs: New test. * rust/rustc/ui/issues/issue-23611-enum-swap-in-drop.rs: New test. * rust/rustc/ui/issues/issue-23649-1.rs: New test. * rust/rustc/ui/issues/issue-23649-2.rs: New test. * rust/rustc/ui/issues/issue-23649-3.rs: New test. * rust/rustc/ui/issues/issue-23699.rs: New test. * rust/rustc/ui/issues/issue-23716.rs: New test. * rust/rustc/ui/issues/issue-23781.rs: New test. * rust/rustc/ui/issues/issue-2380-b.rs: New test. * rust/rustc/ui/issues/issue-23808.rs: New test. * rust/rustc/ui/issues/issue-23825.rs: New test. * rust/rustc/ui/issues/issue-2383.rs: New test. * rust/rustc/ui/issues/issue-23833.rs: New test. * rust/rustc/ui/issues/issue-23891.rs: New test. * rust/rustc/ui/issues/issue-23898.rs: New test. * rust/rustc/ui/issues/issue-23958.rs: New test. * rust/rustc/ui/issues/issue-23966.rs: New test. * rust/rustc/ui/issues/issue-23968-const-not-overflow.rs: New test. * rust/rustc/ui/issues/issue-23992.rs: New test. * rust/rustc/ui/issues/issue-24010.rs: New test. * rust/rustc/ui/issues/issue-24013.rs: New test. * rust/rustc/ui/issues/issue-24036.rs: New test. * rust/rustc/ui/issues/issue-24081.rs: New test. * rust/rustc/ui/issues/issue-24085.rs: New test. * rust/rustc/ui/issues/issue-24086.rs: New test. * rust/rustc/ui/issues/issue-2414-c.rs: New test. * rust/rustc/ui/issues/issue-24161.rs: New test. * rust/rustc/ui/issues/issue-24204.rs: New test. * rust/rustc/ui/issues/issue-24227.rs: New test. * rust/rustc/ui/issues/issue-24267-flow-exit.rs: New test. * rust/rustc/ui/issues/issue-2428.rs: New test. * rust/rustc/ui/issues/issue-24308.rs: New test. * rust/rustc/ui/issues/issue-24313.rs: New test. * rust/rustc/ui/issues/issue-24322.rs: New test. * rust/rustc/ui/issues/issue-24338.rs: New test. * rust/rustc/ui/issues/issue-24352.rs: New test. * rust/rustc/ui/issues/issue-24353.rs: New test. * rust/rustc/ui/issues/issue-24357.rs: New test. * rust/rustc/ui/issues/issue-24363.rs: New test. * rust/rustc/ui/issues/issue-24365.rs: New test. * rust/rustc/ui/issues/issue-24389.rs: New test. * rust/rustc/ui/issues/issue-24424.rs: New test. * rust/rustc/ui/issues/issue-24434.rs: New test. * rust/rustc/ui/issues/issue-2444.rs: New test. * rust/rustc/ui/issues/issue-24446.rs: New test. * rust/rustc/ui/issues/issue-2445-b.rs: New test. * rust/rustc/ui/issues/issue-2445.rs: New test. * rust/rustc/ui/issues/issue-24533.rs: New test. * rust/rustc/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs: New test. * rust/rustc/ui/issues/issue-24589.rs: New test. * rust/rustc/ui/issues/issue-2463.rs: New test. * rust/rustc/ui/issues/issue-24682.rs: New test. * rust/rustc/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs: New test. * rust/rustc/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs: New test. * rust/rustc/ui/issues/issue-24687-embed-debuginfo/main.rs: New test. * rust/rustc/ui/issues/issue-2470-bounds-check-overflow.rs: New test. * rust/rustc/ui/issues/issue-2472.rs: New test. * rust/rustc/ui/issues/issue-24779.rs: New test. * rust/rustc/ui/issues/issue-24805-dropck-itemless.rs: New test. * rust/rustc/ui/issues/issue-24819.rs: New test. * rust/rustc/ui/issues/issue-2487-a.rs: New test. * rust/rustc/ui/issues/issue-24883.rs: New test. * rust/rustc/ui/issues/issue-24945-repeat-dash-opts.rs: New test. * rust/rustc/ui/issues/issue-24947.rs: New test. * rust/rustc/ui/issues/issue-24954.rs: New test. * rust/rustc/ui/issues/issue-2502.rs: New test. * rust/rustc/ui/issues/issue-25076.rs: New test. * rust/rustc/ui/issues/issue-25089.rs: New test. * rust/rustc/ui/issues/issue-25145.rs: New test. * rust/rustc/ui/issues/issue-25180.rs: New test. * rust/rustc/ui/issues/issue-25185.rs: New test. * rust/rustc/ui/issues/issue-2526-a.rs: New test. * rust/rustc/ui/issues/issue-25279.rs: New test. * rust/rustc/ui/issues/issue-25339.rs: New test. * rust/rustc/ui/issues/issue-25343.rs: New test. * rust/rustc/ui/issues/issue-25368.rs: New test. * rust/rustc/ui/issues/issue-25385.rs: New test. * rust/rustc/ui/issues/issue-25386.rs: New test. * rust/rustc/ui/issues/issue-25394.rs: New test. * rust/rustc/ui/issues/issue-25396.rs: New test. * rust/rustc/ui/issues/issue-25439.rs: New test. * rust/rustc/ui/issues/issue-25467.rs: New test. * rust/rustc/ui/issues/issue-25497.rs: New test. * rust/rustc/ui/issues/issue-2550.rs: New test. * rust/rustc/ui/issues/issue-25515.rs: New test. * rust/rustc/ui/issues/issue-25549-multiple-drop.rs: New test. * rust/rustc/ui/issues/issue-25579.rs: New test. * rust/rustc/ui/issues/issue-25679.rs: New test. * rust/rustc/ui/issues/issue-25693.rs: New test. * rust/rustc/ui/issues/issue-25700-1.rs: New test. * rust/rustc/ui/issues/issue-25700-2.rs: New test. * rust/rustc/ui/issues/issue-25700.rs: New test. * rust/rustc/ui/issues/issue-25746-bool-transmute.rs: New test. * rust/rustc/ui/issues/issue-25757.rs: New test. * rust/rustc/ui/issues/issue-25793.rs: New test. * rust/rustc/ui/issues/issue-25810.rs: New test. * rust/rustc/ui/issues/issue-25826.rs: New test. * rust/rustc/ui/issues/issue-2590.rs: New test. * rust/rustc/ui/issues/issue-25901.rs: New test. * rust/rustc/ui/issues/issue-25916.rs: New test. * rust/rustc/ui/issues/issue-26056.rs: New test. * rust/rustc/ui/issues/issue-26093.rs: New test. * rust/rustc/ui/issues/issue-26094.rs: New test. * rust/rustc/ui/issues/issue-26095.rs: New test. * rust/rustc/ui/issues/issue-2611-3.rs: New test. * rust/rustc/ui/issues/issue-26127.rs: New test. * rust/rustc/ui/issues/issue-26205.rs: New test. * rust/rustc/ui/issues/issue-26217.rs: New test. * rust/rustc/ui/issues/issue-26237.rs: New test. * rust/rustc/ui/issues/issue-26251.rs: New test. * rust/rustc/ui/issues/issue-26262.rs: New test. * rust/rustc/ui/issues/issue-2631-b.rs: New test. * rust/rustc/ui/issues/issue-26322.rs: New test. * rust/rustc/ui/issues/issue-2633-2.rs: New test. * rust/rustc/ui/issues/issue-2633.rs: New test. * rust/rustc/ui/issues/issue-2642.rs: New test. * rust/rustc/ui/issues/issue-26448-1.rs: New test. * rust/rustc/ui/issues/issue-26448-2.rs: New test. * rust/rustc/ui/issues/issue-26448-3.rs: New test. * rust/rustc/ui/issues/issue-26459.rs: New test. * rust/rustc/ui/issues/issue-26468.rs: New test. * rust/rustc/ui/issues/issue-26472.rs: New test. * rust/rustc/ui/issues/issue-26484.rs: New test. * rust/rustc/ui/issues/issue-26545.rs: New test. * rust/rustc/ui/issues/issue-26614.rs: New test. * rust/rustc/ui/issues/issue-26619.rs: New test. * rust/rustc/ui/issues/issue-26638.rs: New test. * rust/rustc/ui/issues/issue-26641.rs: New test. * rust/rustc/ui/issues/issue-26646.rs: New test. * rust/rustc/ui/issues/issue-26655.rs: New test. * rust/rustc/ui/issues/issue-26709.rs: New test. * rust/rustc/ui/issues/issue-26802.rs: New test. * rust/rustc/ui/issues/issue-26805.rs: New test. * rust/rustc/ui/issues/issue-26812.rs: New test. * rust/rustc/ui/issues/issue-26873-multifile.rs: New test. * rust/rustc/ui/issues/issue-26873-multifile/A/B.rs: New test. * rust/rustc/ui/issues/issue-26873-multifile/A/C.rs: New test. * rust/rustc/ui/issues/issue-26873-multifile/A/mod.rs: New test. * rust/rustc/ui/issues/issue-26873-multifile/mod.rs: New test. * rust/rustc/ui/issues/issue-26873-onefile.rs: New test. * rust/rustc/ui/issues/issue-26886.rs: New test. * rust/rustc/ui/issues/issue-26905-rpass.rs: New test. * rust/rustc/ui/issues/issue-26905.rs: New test. * rust/rustc/ui/issues/issue-26930.rs: New test. * rust/rustc/ui/issues/issue-26948.rs: New test. * rust/rustc/ui/issues/issue-26996.rs: New test. * rust/rustc/ui/issues/issue-26997.rs: New test. * rust/rustc/ui/issues/issue-27008.rs: New test. * rust/rustc/ui/issues/issue-27021.rs: New test. * rust/rustc/ui/issues/issue-27033.rs: New test. * rust/rustc/ui/issues/issue-27042.rs: New test. * rust/rustc/ui/issues/issue-27054-primitive-binary-ops.rs: New test. * rust/rustc/ui/issues/issue-27060-2.rs: New test. * rust/rustc/ui/issues/issue-27060-rpass.rs: New test. * rust/rustc/ui/issues/issue-27060.rs: New test. * rust/rustc/ui/issues/issue-27078.rs: New test. * rust/rustc/ui/issues/issue-2708.rs: New test. * rust/rustc/ui/issues/issue-27105.rs: New test. * rust/rustc/ui/issues/issue-2718-a.rs: New test. * rust/rustc/ui/issues/issue-2718.rs: New test. * rust/rustc/ui/issues/issue-2723-b.rs: New test. * rust/rustc/ui/issues/issue-27240.rs: New test. * rust/rustc/ui/issues/issue-27268.rs: New test. * rust/rustc/ui/issues/issue-27281.rs: New test. * rust/rustc/ui/issues/issue-27282-move-match-input-into-guard.rs: New test. * rust/rustc/ui/issues/issue-27282-move-ref-mut-into-guard.rs: New test. * rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-1.rs: New test. * rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-2.rs: New test. * rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-3.rs: New test. * rust/rustc/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs: New test. * rust/rustc/ui/issues/issue-27320.rs: New test. * rust/rustc/ui/issues/issue-2734.rs: New test. * rust/rustc/ui/issues/issue-27340.rs: New test. * rust/rustc/ui/issues/issue-2735-2.rs: New test. * rust/rustc/ui/issues/issue-2735-3.rs: New test. * rust/rustc/ui/issues/issue-2735.rs: New test. * rust/rustc/ui/issues/issue-27401-dropflag-reinit.rs: New test. * rust/rustc/ui/issues/issue-27433.rs: New test. * rust/rustc/ui/issues/issue-2748-a.rs: New test. * rust/rustc/ui/issues/issue-2748-b.rs: New test. * rust/rustc/ui/issues/issue-27583.rs: New test. * rust/rustc/ui/issues/issue-27592.rs: New test. * rust/rustc/ui/issues/issue-2761.rs: New test. * rust/rustc/ui/issues/issue-27639.rs: New test. * rust/rustc/ui/issues/issue-27697.rs: New test. * rust/rustc/ui/issues/issue-27815.rs: New test. * rust/rustc/ui/issues/issue-27842.rs: New test. * rust/rustc/ui/issues/issue-27859.rs: New test. * rust/rustc/ui/issues/issue-27889.rs: New test. * rust/rustc/ui/issues/issue-27890.rs: New test. * rust/rustc/ui/issues/issue-27895.rs: New test. * rust/rustc/ui/issues/issue-27901.rs: New test. * rust/rustc/ui/issues/issue-27942.rs: New test. * rust/rustc/ui/issues/issue-27949.rs: New test. * rust/rustc/ui/issues/issue-27997.rs: New test. * rust/rustc/ui/issues/issue-2804-2.rs: New test. * rust/rustc/ui/issues/issue-28075.rs: New test. * rust/rustc/ui/issues/issue-28098.rs: New test. * rust/rustc/ui/issues/issue-28105.rs: New test. * rust/rustc/ui/issues/issue-28109.rs: New test. * rust/rustc/ui/issues/issue-28113.rs: New test. * rust/rustc/ui/issues/issue-28134.rs: New test. * rust/rustc/ui/issues/issue-28181.rs: New test. * rust/rustc/ui/issues/issue-2823.rs: New test. * rust/rustc/ui/issues/issue-28279.rs: New test. * rust/rustc/ui/issues/issue-28324.rs: New test. * rust/rustc/ui/issues/issue-28344.rs: New test. * rust/rustc/ui/issues/issue-28388-1.rs: New test. * rust/rustc/ui/issues/issue-28388-2.rs: New test. * rust/rustc/ui/issues/issue-28388-3.rs: New test. * rust/rustc/ui/issues/issue-28433.rs: New test. * rust/rustc/ui/issues/issue-28472.rs: New test. * rust/rustc/ui/issues/issue-2848.rs: New test. * rust/rustc/ui/issues/issue-2849.rs: New test. * rust/rustc/ui/issues/issue-28498-must-work-ex1.rs: New test. * rust/rustc/ui/issues/issue-28498-must-work-ex2.rs: New test. * rust/rustc/ui/issues/issue-28498-ugeh-ex1.rs: New test. * rust/rustc/ui/issues/issue-28498-ugeh-with-lifetime-param.rs: New test. * rust/rustc/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs: New test. * rust/rustc/ui/issues/issue-28498-ugeh-with-trait-bound.rs: New test. * rust/rustc/ui/issues/issue-28550.rs: New test. * rust/rustc/ui/issues/issue-28561.rs: New test. * rust/rustc/ui/issues/issue-28568.rs: New test. * rust/rustc/ui/issues/issue-28576.rs: New test. * rust/rustc/ui/issues/issue-28586.rs: New test. * rust/rustc/ui/issues/issue-28600.rs: New test. * rust/rustc/ui/issues/issue-28625.rs: New test. * rust/rustc/ui/issues/issue-28676.rs: New test. * rust/rustc/ui/issues/issue-28776.rs: New test. * rust/rustc/ui/issues/issue-28777.rs: New test. * rust/rustc/ui/issues/issue-28822.rs: New test. * rust/rustc/ui/issues/issue-28828.rs: New test. * rust/rustc/ui/issues/issue-28837.rs: New test. * rust/rustc/ui/issues/issue-28839.rs: New test. * rust/rustc/ui/issues/issue-28848.rs: New test. * rust/rustc/ui/issues/issue-28871.rs: New test. * rust/rustc/ui/issues/issue-28934.rs: New test. * rust/rustc/ui/issues/issue-28936.rs: New test. * rust/rustc/ui/issues/issue-2895.rs: New test. * rust/rustc/ui/issues/issue-28950.rs: New test. * rust/rustc/ui/issues/issue-28971.rs: New test. * rust/rustc/ui/issues/issue-28983.rs: New test. * rust/rustc/ui/issues/issue-28992-empty.rs: New test. * rust/rustc/ui/issues/issue-28999.rs: New test. * rust/rustc/ui/issues/issue-29030.rs: New test. * rust/rustc/ui/issues/issue-29037.rs: New test. * rust/rustc/ui/issues/issue-2904.rs: New test. * rust/rustc/ui/issues/issue-29048.rs: New test. * rust/rustc/ui/issues/issue-29053.rs: New test. * rust/rustc/ui/issues/issue-29071-2.rs: New test. * rust/rustc/ui/issues/issue-29071.rs: New test. * rust/rustc/ui/issues/issue-29084.rs: New test. * rust/rustc/ui/issues/issue-29092.rs: New test. * rust/rustc/ui/issues/issue-29124.rs: New test. * rust/rustc/ui/issues/issue-29147-rpass.rs: New test. * rust/rustc/ui/issues/issue-29147.rs: New test. * rust/rustc/ui/issues/issue-29161.rs: New test. * rust/rustc/ui/issues/issue-29166.rs: New test. * rust/rustc/ui/issues/issue-29181.rs: New test. * rust/rustc/ui/issues/issue-29184.rs: New test. * rust/rustc/ui/issues/issue-29227.rs: New test. * rust/rustc/ui/issues/issue-29265.rs: New test. * rust/rustc/ui/issues/issue-29276.rs: New test. * rust/rustc/ui/issues/issue-2935.rs: New test. * rust/rustc/ui/issues/issue-2936.rs: New test. * rust/rustc/ui/issues/issue-2937.rs: New test. * rust/rustc/ui/issues/issue-29466.rs: New test. * rust/rustc/ui/issues/issue-29485.rs: New test. * rust/rustc/ui/issues/issue-29488.rs: New test. * rust/rustc/ui/issues/issue-2951.rs: New test. * rust/rustc/ui/issues/issue-29516.rs: New test. * rust/rustc/ui/issues/issue-29522.rs: New test. * rust/rustc/ui/issues/issue-29540.rs: New test. * rust/rustc/ui/issues/issue-29663.rs: New test. * rust/rustc/ui/issues/issue-29668.rs: New test. * rust/rustc/ui/issues/issue-29710.rs: New test. * rust/rustc/ui/issues/issue-29723.rs: New test. * rust/rustc/ui/issues/issue-29740.rs: New test. * rust/rustc/ui/issues/issue-29743.rs: New test. * rust/rustc/ui/issues/issue-29746.rs: New test. * rust/rustc/ui/issues/issue-29798.rs: New test. * rust/rustc/ui/issues/issue-29844.rs: New test. * rust/rustc/ui/issues/issue-29857.rs: New test. * rust/rustc/ui/issues/issue-29861.rs: New test. * rust/rustc/ui/issues/issue-2989.rs: New test. * rust/rustc/ui/issues/issue-29914-2.rs: New test. * rust/rustc/ui/issues/issue-29914-3.rs: New test. * rust/rustc/ui/issues/issue-29914.rs: New test. * rust/rustc/ui/issues/issue-29927-1.rs: New test. * rust/rustc/ui/issues/issue-29927.rs: New test. * rust/rustc/ui/issues/issue-29948.rs: New test. * rust/rustc/ui/issues/issue-2995.rs: New test. * rust/rustc/ui/issues/issue-30007.rs: New test. * rust/rustc/ui/issues/issue-30018-nopanic.rs: New test. * rust/rustc/ui/issues/issue-30018-panic.rs: New test. * rust/rustc/ui/issues/issue-30079.rs: New test. * rust/rustc/ui/issues/issue-3008-1.rs: New test. * rust/rustc/ui/issues/issue-3008-2.rs: New test. * rust/rustc/ui/issues/issue-3008-3.rs: New test. * rust/rustc/ui/issues/issue-30081.rs: New test. * rust/rustc/ui/issues/issue-3012-2.rs: New test. * rust/rustc/ui/issues/issue-30123.rs: New test. * rust/rustc/ui/issues/issue-3021-b.rs: New test. * rust/rustc/ui/issues/issue-3021-c.rs: New test. * rust/rustc/ui/issues/issue-3021-d.rs: New test. * rust/rustc/ui/issues/issue-3021.rs: New test. * rust/rustc/ui/issues/issue-30225.rs: New test. * rust/rustc/ui/issues/issue-30236.rs: New test. * rust/rustc/ui/issues/issue-30240-b.rs: New test. * rust/rustc/ui/issues/issue-30240-rpass.rs: New test. * rust/rustc/ui/issues/issue-30240.rs: New test. * rust/rustc/ui/issues/issue-30255.rs: New test. * rust/rustc/ui/issues/issue-3026.rs: New test. * rust/rustc/ui/issues/issue-3029.rs: New test. * rust/rustc/ui/issues/issue-30302.rs: New test. * rust/rustc/ui/issues/issue-30355.rs: New test. * rust/rustc/ui/issues/issue-3037.rs: New test. * rust/rustc/ui/issues/issue-30371.rs: New test. * rust/rustc/ui/issues/issue-3038.rs: New test. * rust/rustc/ui/issues/issue-30380.rs: New test. * rust/rustc/ui/issues/issue-30438-a.rs: New test. * rust/rustc/ui/issues/issue-30438-b.rs: New test. * rust/rustc/ui/issues/issue-30438-c.rs: New test. * rust/rustc/ui/issues/issue-3044.rs: New test. * rust/rustc/ui/issues/issue-30490.rs: New test. * rust/rustc/ui/issues/issue-3052.rs: New test. * rust/rustc/ui/issues/issue-30530.rs: New test. * rust/rustc/ui/issues/issue-30535.rs: New test. * rust/rustc/ui/issues/issue-30560.rs: New test. * rust/rustc/ui/issues/issue-30589.rs: New test. * rust/rustc/ui/issues/issue-30615.rs: New test. * rust/rustc/ui/issues/issue-30730.rs: New test. * rust/rustc/ui/issues/issue-30756.rs: New test. * rust/rustc/ui/issues/issue-3080.rs: New test. * rust/rustc/ui/issues/issue-30891.rs: New test. * rust/rustc/ui/issues/issue-3091.rs: New test. * rust/rustc/ui/issues/issue-3096-1.rs: New test. * rust/rustc/ui/issues/issue-3096-2.rs: New test. * rust/rustc/ui/issues/issue-3099-a.rs: New test. * rust/rustc/ui/issues/issue-3099-b.rs: New test. * rust/rustc/ui/issues/issue-3099.rs: New test. * rust/rustc/ui/issues/issue-31011.rs: New test. * rust/rustc/ui/issues/issue-31076.rs: New test. * rust/rustc/ui/issues/issue-3109.rs: New test. * rust/rustc/ui/issues/issue-31109.rs: New test. * rust/rustc/ui/issues/issue-31173.rs: New test. * rust/rustc/ui/issues/issue-3121.rs: New test. * rust/rustc/ui/issues/issue-31212.rs: New test. * rust/rustc/ui/issues/issue-31221.rs: New test. * rust/rustc/ui/issues/issue-31260.rs: New test. * rust/rustc/ui/issues/issue-31267-additional.rs: New test. * rust/rustc/ui/issues/issue-31267.rs: New test. * rust/rustc/ui/issues/issue-31299.rs: New test. * rust/rustc/ui/issues/issue-3136-b.rs: New test. * rust/rustc/ui/issues/issue-3149.rs: New test. * rust/rustc/ui/issues/issue-31511.rs: New test. * rust/rustc/ui/issues/issue-3154.rs: New test. * rust/rustc/ui/issues/issue-31561.rs: New test. * rust/rustc/ui/issues/issue-31597.rs: New test. * rust/rustc/ui/issues/issue-31702.rs: New test. * rust/rustc/ui/issues/issue-31769.rs: New test. * rust/rustc/ui/issues/issue-31776.rs: New test. * rust/rustc/ui/issues/issue-31804.rs: New test. * rust/rustc/ui/issues/issue-31845.rs: New test. * rust/rustc/ui/issues/issue-31910.rs: New test. * rust/rustc/ui/issues/issue-31924-non-snake-ffi.rs: New test. * rust/rustc/ui/issues/issue-32004.rs: New test. * rust/rustc/ui/issues/issue-32008.rs: New test. * rust/rustc/ui/issues/issue-32086.rs: New test. * rust/rustc/ui/issues/issue-3211.rs: New test. * rust/rustc/ui/issues/issue-32119.rs: New test. * rust/rustc/ui/issues/issue-32122-1.rs: New test. * rust/rustc/ui/issues/issue-32122-2.rs: New test. * rust/rustc/ui/issues/issue-3214.rs: New test. * rust/rustc/ui/issues/issue-3220.rs: New test. * rust/rustc/ui/issues/issue-32201.rs: New test. * rust/rustc/ui/issues/issue-32222.rs: New test. * rust/rustc/ui/issues/issue-32292.rs: New test. * rust/rustc/ui/issues/issue-32323.rs: New test. * rust/rustc/ui/issues/issue-32324.rs: New test. * rust/rustc/ui/issues/issue-32326.rs: New test. * rust/rustc/ui/issues/issue-32354-suggest-import-rename.rs: New test. * rust/rustc/ui/issues/issue-32377.rs: New test. * rust/rustc/ui/issues/issue-32389.rs: New test. * rust/rustc/ui/issues/issue-32518.rs: New test. * rust/rustc/ui/issues/issue-32655.rs: New test. * rust/rustc/ui/issues/issue-32709.rs: New test. * rust/rustc/ui/issues/issue-32782.rs: New test. * rust/rustc/ui/issues/issue-32797.rs: New test. * rust/rustc/ui/issues/issue-32805.rs: New test. * rust/rustc/ui/issues/issue-32829-2.rs: New test. * rust/rustc/ui/issues/issue-32829.rs: New test. * rust/rustc/ui/issues/issue-32833.rs: New test. * rust/rustc/ui/issues/issue-3290.rs: New test. * rust/rustc/ui/issues/issue-32922.rs: New test. * rust/rustc/ui/issues/issue-32947.rs: New test. * rust/rustc/ui/issues/issue-32950.rs: New test. * rust/rustc/ui/issues/issue-32963.rs: New test. * rust/rustc/ui/issues/issue-32995-2.rs: New test. * rust/rustc/ui/issues/issue-32995.rs: New test. * rust/rustc/ui/issues/issue-33096.rs: New test. * rust/rustc/ui/issues/issue-33140-hack-boundaries.rs: New test. * rust/rustc/ui/issues/issue-33140-traitobject-crate.rs: New test. * rust/rustc/ui/issues/issue-33140.rs: New test. * rust/rustc/ui/issues/issue-33185.rs: New test. * rust/rustc/ui/issues/issue-33187.rs: New test. * rust/rustc/ui/issues/issue-33202.rs: New test. * rust/rustc/ui/issues/issue-33241.rs: New test. * rust/rustc/ui/issues/issue-33264.rs: New test. * rust/rustc/ui/issues/issue-33287.rs: New test. * rust/rustc/ui/issues/issue-33293.rs: New test. * rust/rustc/ui/issues/issue-333.rs: New test. * rust/rustc/ui/issues/issue-33387.rs: New test. * rust/rustc/ui/issues/issue-3344.rs: New test. * rust/rustc/ui/issues/issue-33461.rs: New test. * rust/rustc/ui/issues/issue-33464.rs: New test. * rust/rustc/ui/issues/issue-33498.rs: New test. * rust/rustc/ui/issues/issue-33504.rs: New test. * rust/rustc/ui/issues/issue-33525.rs: New test. * rust/rustc/ui/issues/issue-33537.rs: New test. * rust/rustc/ui/issues/issue-33571.rs: New test. * rust/rustc/ui/issues/issue-33575.rs: New test. * rust/rustc/ui/issues/issue-33687.rs: New test. * rust/rustc/ui/issues/issue-33770.rs: New test. * rust/rustc/ui/issues/issue-33819.rs: New test. * rust/rustc/ui/issues/issue-3389.rs: New test. * rust/rustc/ui/issues/issue-33903.rs: New test. * rust/rustc/ui/issues/issue-33941.rs: New test. * rust/rustc/ui/issues/issue-33992.rs: New test. * rust/rustc/ui/issues/issue-34028.rs: New test. * rust/rustc/ui/issues/issue-34047.rs: New test. * rust/rustc/ui/issues/issue-34053.rs: New test. * rust/rustc/ui/issues/issue-34074.rs: New test. * rust/rustc/ui/issues/issue-34171.rs: New test. * rust/rustc/ui/issues/issue-34194.rs: New test. * rust/rustc/ui/issues/issue-34209.rs: New test. * rust/rustc/ui/issues/issue-34222-1.rs: New test. * rust/rustc/ui/issues/issue-34229.rs: New test. * rust/rustc/ui/issues/issue-3424.rs: New test. * rust/rustc/ui/issues/issue-34255-1.rs: New test. * rust/rustc/ui/issues/issue-3429.rs: New test. * rust/rustc/ui/issues/issue-34334.rs: New test. * rust/rustc/ui/issues/issue-34349.rs: New test. * rust/rustc/ui/issues/issue-34373.rs: New test. * rust/rustc/ui/issues/issue-34418.rs: New test. * rust/rustc/ui/issues/issue-34427.rs: New test. * rust/rustc/ui/issues/issue-3447.rs: New test. * rust/rustc/ui/issues/issue-34503.rs: New test. * rust/rustc/ui/issues/issue-34569.rs: New test. * rust/rustc/ui/issues/issue-34571.rs: New test. * rust/rustc/ui/issues/issue-34721.rs: New test. * rust/rustc/ui/issues/issue-34751.rs: New test. * rust/rustc/ui/issues/issue-3477.rs: New test. * rust/rustc/ui/issues/issue-34780.rs: New test. * rust/rustc/ui/issues/issue-34784.rs: New test. * rust/rustc/ui/issues/issue-34796.rs: New test. * rust/rustc/ui/issues/issue-34798.rs: New test. * rust/rustc/ui/issues/issue-34839.rs: New test. * rust/rustc/ui/issues/issue-34932.rs: New test. * rust/rustc/ui/issues/issue-3500.rs: New test. * rust/rustc/ui/issues/issue-35075.rs: New test. * rust/rustc/ui/issues/issue-35139.rs: New test. * rust/rustc/ui/issues/issue-3521-2.rs: New test. * rust/rustc/ui/issues/issue-3521.rs: New test. * rust/rustc/ui/issues/issue-35241.rs: New test. * rust/rustc/ui/issues/issue-35376.rs: New test. * rust/rustc/ui/issues/issue-35423.rs: New test. * rust/rustc/ui/issues/issue-35450.rs: New test. * rust/rustc/ui/issues/issue-35546.rs: New test. * rust/rustc/ui/issues/issue-3556.rs: New test. * rust/rustc/ui/issues/issue-35570.rs: New test. * rust/rustc/ui/issues/issue-3559.rs: New test. * rust/rustc/ui/issues/issue-35600.rs: New test. * rust/rustc/ui/issues/issue-3563-2.rs: New test. * rust/rustc/ui/issues/issue-3563-3.rs: New test. * rust/rustc/ui/issues/issue-35668.rs: New test. * rust/rustc/ui/issues/issue-35675.rs: New test. * rust/rustc/ui/issues/issue-35677.rs: New test. * rust/rustc/ui/issues/issue-3574.rs: New test. * rust/rustc/ui/issues/issue-35815.rs: New test. * rust/rustc/ui/issues/issue-35869.rs: New test. * rust/rustc/ui/issues/issue-35976.rs: New test. * rust/rustc/ui/issues/issue-35988.rs: New test. * rust/rustc/ui/issues/issue-3601.rs: New test. * rust/rustc/ui/issues/issue-36023.rs: New test. * rust/rustc/ui/issues/issue-36036-associated-type-layout.rs: New test. * rust/rustc/ui/issues/issue-36053.rs: New test. * rust/rustc/ui/issues/issue-36075.rs: New test. * rust/rustc/ui/issues/issue-36082.rs: New test. * rust/rustc/ui/issues/issue-3609.rs: New test. * rust/rustc/ui/issues/issue-36116.rs: New test. * rust/rustc/ui/issues/issue-36139-normalize-closure-sig.rs: New test. * rust/rustc/ui/issues/issue-36163.rs: New test. * rust/rustc/ui/issues/issue-36260.rs: New test. * rust/rustc/ui/issues/issue-36278-prefix-nesting.rs: New test. * rust/rustc/ui/issues/issue-36299.rs: New test. * rust/rustc/ui/issues/issue-36379.rs: New test. * rust/rustc/ui/issues/issue-36381.rs: New test. * rust/rustc/ui/issues/issue-36400.rs: New test. * rust/rustc/ui/issues/issue-36401.rs: New test. * rust/rustc/ui/issues/issue-36474.rs: New test. * rust/rustc/ui/issues/issue-3656.rs: New test. * rust/rustc/ui/issues/issue-36617.rs: New test. * rust/rustc/ui/issues/issue-36638.rs: New test. * rust/rustc/ui/issues/issue-3668-2.rs: New test. * rust/rustc/ui/issues/issue-3668.rs: New test. * rust/rustc/ui/issues/issue-36708.rs: New test. * rust/rustc/ui/issues/issue-36744-bitcast-args-if-needed.rs: New test. * rust/rustc/ui/issues/issue-36744-without-calls.rs: New test. * rust/rustc/ui/issues/issue-36768.rs: New test. * rust/rustc/ui/issues/issue-36786-resolve-call.rs: New test. * rust/rustc/ui/issues/issue-36792.rs: New test. * rust/rustc/ui/issues/issue-3680.rs: New test. * rust/rustc/ui/issues/issue-36816.rs: New test. * rust/rustc/ui/issues/issue-3683.rs: New test. * rust/rustc/ui/issues/issue-36836.rs: New test. * rust/rustc/ui/issues/issue-36839.rs: New test. * rust/rustc/ui/issues/issue-36856.rs: New test. * rust/rustc/ui/issues/issue-36881.rs: New test. * rust/rustc/ui/issues/issue-36936.rs: New test. * rust/rustc/ui/issues/issue-36954.rs: New test. * rust/rustc/ui/issues/issue-3702-2.rs: New test. * rust/rustc/ui/issues/issue-3702.rs: New test. * rust/rustc/ui/issues/issue-37026.rs: New test. * rust/rustc/ui/issues/issue-37051.rs: New test. * rust/rustc/ui/issues/issue-3707.rs: New test. * rust/rustc/ui/issues/issue-37109.rs: New test. * rust/rustc/ui/issues/issue-37131.rs: New test. * rust/rustc/ui/issues/issue-37175.rs: New test. * rust/rustc/ui/issues/issue-37222.rs: New test. * rust/rustc/ui/issues/issue-37291/auxiliary/lib.rs: New test. * rust/rustc/ui/issues/issue-37291/main.rs: New test. * rust/rustc/ui/issues/issue-37311-type-length-limit/issue-37311.rs: New test. * rust/rustc/ui/issues/issue-37323.rs: New test. * rust/rustc/ui/issues/issue-37366.rs: New test. * rust/rustc/ui/issues/issue-3743.rs: New test. * rust/rustc/ui/issues/issue-37433.rs: New test. * rust/rustc/ui/issues/issue-37510.rs: New test. * rust/rustc/ui/issues/issue-37515.rs: New test. * rust/rustc/ui/issues/issue-3753.rs: New test. * rust/rustc/ui/issues/issue-37534.rs: New test. * rust/rustc/ui/issues/issue-37550.rs: New test. * rust/rustc/ui/issues/issue-37576.rs: New test. * rust/rustc/ui/issues/issue-37598.rs: New test. * rust/rustc/ui/issues/issue-3763.rs: New test. * rust/rustc/ui/issues/issue-37655.rs: New test. * rust/rustc/ui/issues/issue-37665.rs: New test. * rust/rustc/ui/issues/issue-37686.rs: New test. * rust/rustc/ui/issues/issue-37725.rs: New test. * rust/rustc/ui/issues/issue-37733.rs: New test. * rust/rustc/ui/issues/issue-3779.rs: New test. * rust/rustc/ui/issues/issue-37884.rs: New test. * rust/rustc/ui/issues/issue-37887.rs: New test. * rust/rustc/ui/issues/issue-3794.rs: New test. * rust/rustc/ui/issues/issue-37991.rs: New test. * rust/rustc/ui/issues/issue-38002.rs: New test. * rust/rustc/ui/issues/issue-38033.rs: New test. * rust/rustc/ui/issues/issue-38074.rs: New test. * rust/rustc/ui/issues/issue-38160.rs: New test. * rust/rustc/ui/issues/issue-38190.rs: New test. * rust/rustc/ui/issues/issue-3820.rs: New test. * rust/rustc/ui/issues/issue-38226.rs: New test. * rust/rustc/ui/issues/issue-38293.rs: New test. * rust/rustc/ui/issues/issue-38381.rs: New test. * rust/rustc/ui/issues/issue-38404.rs: New test. * rust/rustc/ui/issues/issue-38412.rs: New test. * rust/rustc/ui/issues/issue-38437.rs: New test. * rust/rustc/ui/issues/issue-38458.rs: New test. * rust/rustc/ui/issues/issue-3847.rs: New test. * rust/rustc/ui/issues/issue-38556.rs: New test. * rust/rustc/ui/issues/issue-38604.rs: New test. * rust/rustc/ui/issues/issue-38715.rs: New test. * rust/rustc/ui/issues/issue-38727.rs: New test. * rust/rustc/ui/issues/issue-3874.rs: New test. * rust/rustc/ui/issues/issue-38763.rs: New test. * rust/rustc/ui/issues/issue-3878.rs: New test. * rust/rustc/ui/issues/issue-38821.rs: New test. * rust/rustc/ui/issues/issue-38857.rs: New test. * rust/rustc/ui/issues/issue-38868.rs: New test. * rust/rustc/ui/issues/issue-38875/auxiliary/issue-38875-b.rs: New test. * rust/rustc/ui/issues/issue-38875/issue-38875.rs: New test. * rust/rustc/ui/issues/issue-3888-2.rs: New test. * rust/rustc/ui/issues/issue-38919.rs: New test. * rust/rustc/ui/issues/issue-38940.rs: New test. * rust/rustc/ui/issues/issue-38942.rs: New test. * rust/rustc/ui/issues/issue-3895.rs: New test. * rust/rustc/ui/issues/issue-38954.rs: New test. * rust/rustc/ui/issues/issue-38987.rs: New test. * rust/rustc/ui/issues/issue-3904.rs: New test. * rust/rustc/ui/issues/issue-39089.rs: New test. * rust/rustc/ui/issues/issue-39175.rs: New test. * rust/rustc/ui/issues/issue-39211.rs: New test. * rust/rustc/ui/issues/issue-39292.rs: New test. * rust/rustc/ui/issues/issue-3935.rs: New test. * rust/rustc/ui/issues/issue-39362.rs: New test. * rust/rustc/ui/issues/issue-39367.rs: New test. * rust/rustc/ui/issues/issue-39388.rs: New test. * rust/rustc/ui/issues/issue-39467.rs: New test. * rust/rustc/ui/issues/issue-39548.rs: New test. * rust/rustc/ui/issues/issue-39559-2.rs: New test. * rust/rustc/ui/issues/issue-39559.rs: New test. * rust/rustc/ui/issues/issue-39616.rs: New test. * rust/rustc/ui/issues/issue-39687.rs: New test. * rust/rustc/ui/issues/issue-39709.rs: New test. * rust/rustc/ui/issues/issue-39720.rs: New test. * rust/rustc/ui/issues/issue-3973.rs: New test. * rust/rustc/ui/issues/issue-3979-2.rs: New test. * rust/rustc/ui/issues/issue-3979-generics.rs: New test. * rust/rustc/ui/issues/issue-3979-xcrate.rs: New test. * rust/rustc/ui/issues/issue-3979.rs: New test. * rust/rustc/ui/issues/issue-39808.rs: New test. * rust/rustc/ui/issues/issue-39823.rs: New test. * rust/rustc/ui/issues/issue-39827.rs: New test. * rust/rustc/ui/issues/issue-39848.rs: New test. * rust/rustc/ui/issues/issue-3991.rs: New test. * rust/rustc/ui/issues/issue-3993.rs: New test. * rust/rustc/ui/issues/issue-39970.rs: New test. * rust/rustc/ui/issues/issue-39974.rs: New test. * rust/rustc/ui/issues/issue-39984.rs: New test. * rust/rustc/ui/issues/issue-40000.rs: New test. * rust/rustc/ui/issues/issue-40003.rs: New test. * rust/rustc/ui/issues/issue-40085.rs: New test. * rust/rustc/ui/issues/issue-40136.rs: New test. * rust/rustc/ui/issues/issue-40231-1.rs: New test. * rust/rustc/ui/issues/issue-40231-2.rs: New test. * rust/rustc/ui/issues/issue-40235.rs: New test. * rust/rustc/ui/issues/issue-4025.rs: New test. * rust/rustc/ui/issues/issue-40288-2.rs: New test. * rust/rustc/ui/issues/issue-40288.rs: New test. * rust/rustc/ui/issues/issue-40350.rs: New test. * rust/rustc/ui/issues/issue-40402-ref-hints/issue-40402-1.rs: New test. * rust/rustc/ui/issues/issue-40402-ref-hints/issue-40402-2.rs: New test. * rust/rustc/ui/issues/issue-40408.rs: New test. * rust/rustc/ui/issues/issue-40469.rs: New test. * rust/rustc/ui/issues/issue-40510-1.rs: New test. * rust/rustc/ui/issues/issue-40510-2.rs: New test. * rust/rustc/ui/issues/issue-40510-3.rs: New test. * rust/rustc/ui/issues/issue-40510-4.rs: New test. * rust/rustc/ui/issues/issue-40610.rs: New test. * rust/rustc/ui/issues/issue-40749.rs: New test. * rust/rustc/ui/issues/issue-40770.rs: New test. * rust/rustc/ui/issues/issue-40782.rs: New test. * rust/rustc/ui/issues/issue-40827.rs: New test. * rust/rustc/ui/issues/issue-40845.rs: New test. * rust/rustc/ui/issues/issue-40847.rs: New test. * rust/rustc/ui/issues/issue-40861.rs: New test. * rust/rustc/ui/issues/issue-40883.rs: New test. * rust/rustc/ui/issues/issue-40951.rs: New test. * rust/rustc/ui/issues/issue-40962.rs: New test. * rust/rustc/ui/issues/issue-41053.rs: New test. * rust/rustc/ui/issues/issue-4107.rs: New test. * rust/rustc/ui/issues/issue-41139.rs: New test. * rust/rustc/ui/issues/issue-41213.rs: New test. * rust/rustc/ui/issues/issue-41229-ref-str.rs: New test. * rust/rustc/ui/issues/issue-41255.rs: New test. * rust/rustc/ui/issues/issue-41272.rs: New test. * rust/rustc/ui/issues/issue-41298.rs: New test. * rust/rustc/ui/issues/issue-41394-rpass.rs: New test. * rust/rustc/ui/issues/issue-41394.rs: New test. * rust/rustc/ui/issues/issue-41479.rs: New test. * rust/rustc/ui/issues/issue-41498.rs: New test. * rust/rustc/ui/issues/issue-41549.rs: New test. * rust/rustc/ui/issues/issue-41604.rs: New test. * rust/rustc/ui/issues/issue-41628.rs: New test. * rust/rustc/ui/issues/issue-41652/auxiliary/issue-41652-b.rs: New test. * rust/rustc/ui/issues/issue-41652/issue-41652.rs: New test. * rust/rustc/ui/issues/issue-41677.rs: New test. * rust/rustc/ui/issues/issue-41696.rs: New test. * rust/rustc/ui/issues/issue-41726.rs: New test. * rust/rustc/ui/issues/issue-41742.rs: New test. * rust/rustc/ui/issues/issue-41744.rs: New test. * rust/rustc/ui/issues/issue-41776.rs: New test. * rust/rustc/ui/issues/issue-41803.rs: New test. * rust/rustc/ui/issues/issue-41849-variance-req.rs: New test. * rust/rustc/ui/issues/issue-41880.rs: New test. * rust/rustc/ui/issues/issue-41888.rs: New test. * rust/rustc/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs: New test. * rust/rustc/ui/issues/issue-41974.rs: New test. * rust/rustc/ui/issues/issue-41998.rs: New test. * rust/rustc/ui/issues/issue-42007.rs: New test. * rust/rustc/ui/issues/issue-4201.rs: New test. * rust/rustc/ui/issues/issue-42060.rs: New test. * rust/rustc/ui/issues/issue-4208.rs: New test. * rust/rustc/ui/issues/issue-42106.rs: New test. * rust/rustc/ui/issues/issue-42148.rs: New test. * rust/rustc/ui/issues/issue-42210.rs: New test. * rust/rustc/ui/issues/issue-4228.rs: New test. * rust/rustc/ui/issues/issue-42312.rs: New test. * rust/rustc/ui/issues/issue-42344.rs: New test. * rust/rustc/ui/issues/issue-42453.rs: New test. * rust/rustc/ui/issues/issue-42463.rs: New test. * rust/rustc/ui/issues/issue-42467.rs: New test. * rust/rustc/ui/issues/issue-4252.rs: New test. * rust/rustc/ui/issues/issue-42552.rs: New test. * rust/rustc/ui/issues/issue-4265.rs: New test. * rust/rustc/ui/issues/issue-42679.rs: New test. * rust/rustc/ui/issues/issue-42747.rs: New test. * rust/rustc/ui/issues/issue-42755.rs: New test. * rust/rustc/ui/issues/issue-42796.rs: New test. * rust/rustc/ui/issues/issue-42880.rs: New test. * rust/rustc/ui/issues/issue-42944.rs: New test. * rust/rustc/ui/issues/issue-42954.rs: New test. * rust/rustc/ui/issues/issue-42956.rs: New test. * rust/rustc/ui/issues/issue-43023.rs: New test. * rust/rustc/ui/issues/issue-43057.rs: New test. * rust/rustc/ui/issues/issue-43105.rs: New test. * rust/rustc/ui/issues/issue-43132.rs: New test. * rust/rustc/ui/issues/issue-43162.rs: New test. * rust/rustc/ui/issues/issue-43189.rs: New test. * rust/rustc/ui/issues/issue-43196.rs: New test. * rust/rustc/ui/issues/issue-43205.rs: New test. * rust/rustc/ui/issues/issue-4321.rs: New test. * rust/rustc/ui/issues/issue-43250.rs: New test. * rust/rustc/ui/issues/issue-43291.rs: New test. * rust/rustc/ui/issues/issue-4333.rs: New test. * rust/rustc/ui/issues/issue-4335.rs: New test. * rust/rustc/ui/issues/issue-43355.rs: New test. * rust/rustc/ui/issues/issue-43357.rs: New test. * rust/rustc/ui/issues/issue-43398.rs: New test. * rust/rustc/ui/issues/issue-43420-no-over-suggest.rs: New test. * rust/rustc/ui/issues/issue-43424.rs: New test. * rust/rustc/ui/issues/issue-43431.rs: New test. * rust/rustc/ui/issues/issue-43483.rs: New test. * rust/rustc/ui/issues/issue-43623.rs: New test. * rust/rustc/ui/issues/issue-4366-2.rs: New test. * rust/rustc/ui/issues/issue-4366.rs: New test. * rust/rustc/ui/issues/issue-43692.rs: New test. * rust/rustc/ui/issues/issue-43733.rs: New test. * rust/rustc/ui/issues/issue-43784-associated-type.rs: New test. * rust/rustc/ui/issues/issue-43784-supertrait.rs: New test. * rust/rustc/ui/issues/issue-43806.rs: New test. * rust/rustc/ui/issues/issue-43853.rs: New test. * rust/rustc/ui/issues/issue-4387.rs: New test. * rust/rustc/ui/issues/issue-43910.rs: New test. * rust/rustc/ui/issues/issue-43923.rs: New test. * rust/rustc/ui/issues/issue-43925.rs: New test. * rust/rustc/ui/issues/issue-43926.rs: New test. * rust/rustc/ui/issues/issue-43988.rs: New test. * rust/rustc/ui/issues/issue-44005.rs: New test. * rust/rustc/ui/issues/issue-4401.rs: New test. * rust/rustc/ui/issues/issue-44021.rs: New test. * rust/rustc/ui/issues/issue-44023.rs: New test. * rust/rustc/ui/issues/issue-44056.rs: New test. * rust/rustc/ui/issues/issue-44078.rs: New test. * rust/rustc/ui/issues/issue-44127.rs: New test. * rust/rustc/ui/issues/issue-44216-add-instant.rs: New test. * rust/rustc/ui/issues/issue-44216-add-system-time.rs: New test. * rust/rustc/ui/issues/issue-44216-sub-instant.rs: New test. * rust/rustc/ui/issues/issue-44216-sub-system-time.rs: New test. * rust/rustc/ui/issues/issue-44239.rs: New test. * rust/rustc/ui/issues/issue-44247.rs: New test. * rust/rustc/ui/issues/issue-44255.rs: New test. * rust/rustc/ui/issues/issue-44373-2.rs: New test. * rust/rustc/ui/issues/issue-44373.rs: New test. * rust/rustc/ui/issues/issue-44405.rs: New test. * rust/rustc/ui/issues/issue-44406.rs: New test. * rust/rustc/ui/issues/issue-4446.rs: New test. * rust/rustc/ui/issues/issue-4448.rs: New test. * rust/rustc/ui/issues/issue-4464.rs: New test. * rust/rustc/ui/issues/issue-44730.rs: New test. * rust/rustc/ui/issues/issue-44851.rs: New test. * rust/rustc/ui/issues/issue-45087-unreachable-unsafe.rs: New test. * rust/rustc/ui/issues/issue-45107-unnecessary-unsafe-in-closure.rs: New test. * rust/rustc/ui/issues/issue-45124.rs: New test. * rust/rustc/ui/issues/issue-45152.rs: New test. * rust/rustc/ui/issues/issue-45157.rs: New test. * rust/rustc/ui/issues/issue-4517.rs: New test. * rust/rustc/ui/issues/issue-45199.rs: New test. * rust/rustc/ui/issues/issue-45296.rs: New test. * rust/rustc/ui/issues/issue-4541.rs: New test. * rust/rustc/ui/issues/issue-4542.rs: New test. * rust/rustc/ui/issues/issue-45425.rs: New test. * rust/rustc/ui/issues/issue-4545.rs: New test. * rust/rustc/ui/issues/issue-45510.rs: New test. * rust/rustc/ui/issues/issue-45562.rs: New test. * rust/rustc/ui/issues/issue-45696-long-live-borrows-in-boxes.rs: New test. * rust/rustc/ui/issues/issue-45696-no-variant-box-recur.rs: New test. * rust/rustc/ui/issues/issue-45696-scribble-on-boxed-borrow.rs: New test. * rust/rustc/ui/issues/issue-45697-1.rs: New test. * rust/rustc/ui/issues/issue-45697.rs: New test. * rust/rustc/ui/issues/issue-45729-unsafe-in-generator.rs: New test. * rust/rustc/ui/issues/issue-45730.rs: New test. * rust/rustc/ui/issues/issue-45731.rs: New test. * rust/rustc/ui/issues/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs: New test. * rust/rustc/ui/issues/issue-45801.rs: New test. * rust/rustc/ui/issues/issue-45829/auxiliary/issue-45829-a.rs: New test. * rust/rustc/ui/issues/issue-45829/auxiliary/issue-45829-b.rs: New test. * rust/rustc/ui/issues/issue-45829/import-self.rs: New test. * rust/rustc/ui/issues/issue-45829/import-twice.rs: New test. * rust/rustc/ui/issues/issue-45829/issue-45829.rs: New test. * rust/rustc/ui/issues/issue-45829/rename-extern-vs-use.rs: New test. * rust/rustc/ui/issues/issue-45829/rename-extern-with-tab.rs: New test. * rust/rustc/ui/issues/issue-45829/rename-extern.rs: New test. * rust/rustc/ui/issues/issue-45829/rename-use-vs-extern.rs: New test. * rust/rustc/ui/issues/issue-45829/rename-use-with-tabs.rs: New test. * rust/rustc/ui/issues/issue-45829/rename-with-path.rs: New test. * rust/rustc/ui/issues/issue-45829/rename.rs: New test. * rust/rustc/ui/issues/issue-45965.rs: New test. * rust/rustc/ui/issues/issue-46023.rs: New test. * rust/rustc/ui/issues/issue-46036.rs: New test. * rust/rustc/ui/issues/issue-46069.rs: New test. * rust/rustc/ui/issues/issue-46095.rs: New test. * rust/rustc/ui/issues/issue-46101.rs: New test. * rust/rustc/ui/issues/issue-46112.rs: New test. * rust/rustc/ui/issues/issue-46186.rs: New test. * rust/rustc/ui/issues/issue-46302.rs: New test. * rust/rustc/ui/issues/issue-46311.rs: New test. * rust/rustc/ui/issues/issue-46332.rs: New test. * rust/rustc/ui/issues/issue-46438.rs: New test. * rust/rustc/ui/issues/issue-46471-1.rs: New test. * rust/rustc/ui/issues/issue-46471.rs: New test. * rust/rustc/ui/issues/issue-46472.rs: New test. * rust/rustc/ui/issues/issue-46519.rs: New test. * rust/rustc/ui/issues/issue-46553.rs: New test. * rust/rustc/ui/issues/issue-46576.rs: New test. * rust/rustc/ui/issues/issue-46604.rs: New test. * rust/rustc/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.rs: New test. * rust/rustc/ui/issues/issue-46771.rs: New test. * rust/rustc/ui/issues/issue-46845.rs: New test. * rust/rustc/ui/issues/issue-46855.rs: New test. * rust/rustc/ui/issues/issue-46920-byte-array-patterns.rs: New test. * rust/rustc/ui/issues/issue-46959.rs: New test. * rust/rustc/ui/issues/issue-46964.rs: New test. * rust/rustc/ui/issues/issue-46983.rs: New test. * rust/rustc/ui/issues/issue-47073-zero-padded-tuple-struct-indices.rs: New test. * rust/rustc/ui/issues/issue-47094.rs: New test. * rust/rustc/ui/issues/issue-47139-1.rs: New test. * rust/rustc/ui/issues/issue-47139-2.rs: New test. * rust/rustc/ui/issues/issue-47184.rs: New test. * rust/rustc/ui/issues/issue-47309.rs: New test. * rust/rustc/ui/issues/issue-4734.rs: New test. * rust/rustc/ui/issues/issue-4735.rs: New test. * rust/rustc/ui/issues/issue-4736.rs: New test. * rust/rustc/ui/issues/issue-47364.rs: New test. * rust/rustc/ui/issues/issue-47377.rs: New test. * rust/rustc/ui/issues/issue-47380.rs: New test. * rust/rustc/ui/issues/issue-47412.rs: New test. * rust/rustc/ui/issues/issue-47486.rs: New test. * rust/rustc/ui/issues/issue-47511.rs: New test. * rust/rustc/ui/issues/issue-4759-1.rs: New test. * rust/rustc/ui/issues/issue-4759.rs: New test. * rust/rustc/ui/issues/issue-47623.rs: New test. * rust/rustc/ui/issues/issue-47638.rs: New test. * rust/rustc/ui/issues/issue-47646.rs: New test. * rust/rustc/ui/issues/issue-47673.rs: New test. * rust/rustc/ui/issues/issue-47703-1.rs: New test. * rust/rustc/ui/issues/issue-47703-tuple.rs: New test. * rust/rustc/ui/issues/issue-47703.rs: New test. * rust/rustc/ui/issues/issue-47706-trait.rs: New test. * rust/rustc/ui/issues/issue-47706.rs: New test. * rust/rustc/ui/issues/issue-47715.rs: New test. * rust/rustc/ui/issues/issue-47722.rs: New test. * rust/rustc/ui/issues/issue-47725.rs: New test. * rust/rustc/ui/issues/issue-47789.rs: New test. * rust/rustc/ui/issues/issue-48006.rs: New test. * rust/rustc/ui/issues/issue-48131.rs: New test. * rust/rustc/ui/issues/issue-48132.rs: New test. * rust/rustc/ui/issues/issue-48159.rs: New test. * rust/rustc/ui/issues/issue-48179.rs: New test. * rust/rustc/ui/issues/issue-48276.rs: New test. * rust/rustc/ui/issues/issue-4830.rs: New test. * rust/rustc/ui/issues/issue-48364.rs: New test. * rust/rustc/ui/issues/issue-48508-aux.rs: New test. * rust/rustc/ui/issues/issue-48508.rs: New test. * rust/rustc/ui/issues/issue-48551.rs: New test. * rust/rustc/ui/issues/issue-48636.rs: New test. * rust/rustc/ui/issues/issue-4865-1.rs: New test. * rust/rustc/ui/issues/issue-4865-2.rs: New test. * rust/rustc/ui/issues/issue-4865-3.rs: New test. * rust/rustc/ui/issues/issue-48728.rs: New test. * rust/rustc/ui/issues/issue-4875.rs: New test. * rust/rustc/ui/issues/issue-48803.rs: New test. * rust/rustc/ui/issues/issue-48838.rs: New test. * rust/rustc/ui/issues/issue-48962.rs: New test. * rust/rustc/ui/issues/issue-48984.rs: New test. * rust/rustc/ui/issues/issue-49040.rs: New test. * rust/rustc/ui/issues/issue-49074.rs: New test. * rust/rustc/ui/issues/issue-49257.rs: New test. * rust/rustc/ui/issues/issue-49298.rs: New test. * rust/rustc/ui/issues/issue-4935.rs: New test. * rust/rustc/ui/issues/issue-49544.rs: New test. * rust/rustc/ui/issues/issue-49556.rs: New test. * rust/rustc/ui/issues/issue-49579.rs: New test. * rust/rustc/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs: New test. * rust/rustc/ui/issues/issue-49632.rs: New test. * rust/rustc/ui/issues/issue-4968.rs: New test. * rust/rustc/ui/issues/issue-49685.rs: New test. * rust/rustc/ui/issues/issue-4972.rs: New test. * rust/rustc/ui/issues/issue-49824.rs: New test. * rust/rustc/ui/issues/issue-49851/compiler-builtins-error.rs: New test. * rust/rustc/ui/issues/issue-49854.rs: New test. * rust/rustc/ui/issues/issue-49919.rs: New test. * rust/rustc/ui/issues/issue-49934-errors.rs: New test. * rust/rustc/ui/issues/issue-49934.rs: New test. * rust/rustc/ui/issues/issue-49955-2.rs: New test. * rust/rustc/ui/issues/issue-49955.rs: New test. * rust/rustc/ui/issues/issue-49973.rs: New test. * rust/rustc/ui/issues/issue-5008-borrowed-traitobject-method-call.rs: New test. * rust/rustc/ui/issues/issue-50187.rs: New test. * rust/rustc/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs: New test. * rust/rustc/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs: New test. * rust/rustc/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs: New test. * rust/rustc/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs: New test. * rust/rustc/ui/issues/issue-50301.rs: New test. * rust/rustc/ui/issues/issue-50403.rs: New test. * rust/rustc/ui/issues/issue-50411.rs: New test. * rust/rustc/ui/issues/issue-50415.rs: New test. * rust/rustc/ui/issues/issue-50442.rs: New test. * rust/rustc/ui/issues/issue-50471.rs: New test. * rust/rustc/ui/issues/issue-50480.rs: New test. * rust/rustc/ui/issues/issue-50518.rs: New test. * rust/rustc/ui/issues/issue-50571.rs: New test. * rust/rustc/ui/issues/issue-50576.rs: New test. * rust/rustc/ui/issues/issue-50581.rs: New test. * rust/rustc/ui/issues/issue-50582.rs: New test. * rust/rustc/ui/issues/issue-50585.rs: New test. * rust/rustc/ui/issues/issue-50599.rs: New test. * rust/rustc/ui/issues/issue-5060.rs: New test. * rust/rustc/ui/issues/issue-50600.rs: New test. * rust/rustc/ui/issues/issue-50618.rs: New test. * rust/rustc/ui/issues/issue-5062.rs: New test. * rust/rustc/ui/issues/issue-5067.rs: New test. * rust/rustc/ui/issues/issue-50687-ice-on-borrow.rs: New test. * rust/rustc/ui/issues/issue-50688.rs: New test. * rust/rustc/ui/issues/issue-50689.rs: New test. * rust/rustc/ui/issues/issue-50714-1.rs: New test. * rust/rustc/ui/issues/issue-50714.rs: New test. * rust/rustc/ui/issues/issue-50731.rs: New test. * rust/rustc/ui/issues/issue-50761.rs: New test. * rust/rustc/ui/issues/issue-50781.rs: New test. * rust/rustc/ui/issues/issue-50802.rs: New test. * rust/rustc/ui/issues/issue-50811.rs: New test. * rust/rustc/ui/issues/issue-50825-1.rs: New test. * rust/rustc/ui/issues/issue-50825.rs: New test. * rust/rustc/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs: New test. * rust/rustc/ui/issues/issue-50865-private-impl-trait/main.rs: New test. * rust/rustc/ui/issues/issue-5099.rs: New test. * rust/rustc/ui/issues/issue-50993.rs: New test. * rust/rustc/ui/issues/issue-5100.rs: New test. * rust/rustc/ui/issues/issue-51022.rs: New test. * rust/rustc/ui/issues/issue-51044.rs: New test. * rust/rustc/ui/issues/issue-51102.rs: New test. * rust/rustc/ui/issues/issue-51116.rs: New test. * rust/rustc/ui/issues/issue-51154.rs: New test. * rust/rustc/ui/issues/issue-51185.rs: New test. * rust/rustc/ui/issues/issue-51244.rs: New test. * rust/rustc/ui/issues/issue-51301.rs: New test. * rust/rustc/ui/issues/issue-51345-2.rs: New test. * rust/rustc/ui/issues/issue-51345.rs: New test. * rust/rustc/ui/issues/issue-51515.rs: New test. * rust/rustc/ui/issues/issue-5153.rs: New test. * rust/rustc/ui/issues/issue-51582.rs: New test. * rust/rustc/ui/issues/issue-51602.rs: New test. * rust/rustc/ui/issues/issue-51632-try-desugar-incompatible-types.rs: New test. * rust/rustc/ui/issues/issue-51655.rs: New test. * rust/rustc/ui/issues/issue-51714.rs: New test. * rust/rustc/ui/issues/issue-51770.rs: New test. * rust/rustc/ui/issues/issue-51798.rs: New test. * rust/rustc/ui/issues/issue-51848.rs: New test. * rust/rustc/ui/issues/issue-51874.rs: New test. * rust/rustc/ui/issues/issue-51907.rs: New test. * rust/rustc/ui/issues/issue-5192.rs: New test. * rust/rustc/ui/issues/issue-51947.rs: New test. * rust/rustc/ui/issues/issue-52023-array-size-pointer-cast.rs: New test. * rust/rustc/ui/issues/issue-52049.rs: New test. * rust/rustc/ui/issues/issue-52057.rs: New test. * rust/rustc/ui/issues/issue-52060.rs: New test. * rust/rustc/ui/issues/issue-52126-assign-op-invariance.rs: New test. * rust/rustc/ui/issues/issue-52140/auxiliary/some_crate.rs: New test. * rust/rustc/ui/issues/issue-52140/main.rs: New test. * rust/rustc/ui/issues/issue-52141/auxiliary/some_crate.rs: New test. * rust/rustc/ui/issues/issue-52141/main.rs: New test. * rust/rustc/ui/issues/issue-5216.rs: New test. * rust/rustc/ui/issues/issue-52169.rs: New test. * rust/rustc/ui/issues/issue-52213.rs: New test. * rust/rustc/ui/issues/issue-52240.rs: New test. * rust/rustc/ui/issues/issue-52262.rs: New test. * rust/rustc/ui/issues/issue-5239-1.rs: New test. * rust/rustc/ui/issues/issue-5239-2.rs: New test. * rust/rustc/ui/issues/issue-5243.rs: New test. * rust/rustc/ui/issues/issue-52489.rs: New test. * rust/rustc/ui/issues/issue-52496.rs: New test. * rust/rustc/ui/issues/issue-52533-1.rs: New test. * rust/rustc/ui/issues/issue-52533.rs: New test. * rust/rustc/ui/issues/issue-52557.rs: New test. * rust/rustc/ui/issues/issue-52705/auxiliary/png2.rs: New test. * rust/rustc/ui/issues/issue-52705/main.rs: New test. * rust/rustc/ui/issues/issue-52717.rs: New test. * rust/rustc/ui/issues/issue-5280.rs: New test. * rust/rustc/ui/issues/issue-52891.rs: New test. * rust/rustc/ui/issues/issue-52992.rs: New test. * rust/rustc/ui/issues/issue-5315.rs: New test. * rust/rustc/ui/issues/issue-5321-immediates-with-bare-self.rs: New test. * rust/rustc/ui/issues/issue-53251.rs: New test. * rust/rustc/ui/issues/issue-53275.rs: New test. * rust/rustc/ui/issues/issue-53300.rs: New test. * rust/rustc/ui/issues/issue-53333.rs: New test. * rust/rustc/ui/issues/issue-53348.rs: New test. * rust/rustc/ui/issues/issue-53419.rs: New test. * rust/rustc/ui/issues/issue-53498.rs: New test. * rust/rustc/ui/issues/issue-5353.rs: New test. * rust/rustc/ui/issues/issue-53565.rs: New test. * rust/rustc/ui/issues/issue-53568.rs: New test. * rust/rustc/ui/issues/issue-5358-1.rs: New test. * rust/rustc/ui/issues/issue-53675-a-test-called-panic.rs: New test. * rust/rustc/ui/issues/issue-53692.rs: New test. * rust/rustc/ui/issues/issue-53712.rs: New test. * rust/rustc/ui/issues/issue-53728.rs: New test. * rust/rustc/ui/issues/issue-53787-inline-assembler-macro.rs: New test. * rust/rustc/ui/issues/issue-53843.rs: New test. * rust/rustc/ui/issues/issue-53912.rs: New test. * rust/rustc/ui/issues/issue-54044.rs: New test. * rust/rustc/ui/issues/issue-54062.rs: New test. * rust/rustc/ui/issues/issue-54094.rs: New test. * rust/rustc/ui/issues/issue-54189.rs: New test. * rust/rustc/ui/issues/issue-54302-cases.rs: New test. * rust/rustc/ui/issues/issue-54302.rs: New test. * rust/rustc/ui/issues/issue-54348.rs: New test. * rust/rustc/ui/issues/issue-54387.rs: New test. * rust/rustc/ui/issues/issue-5439.rs: New test. * rust/rustc/ui/issues/issue-54410.rs: New test. * rust/rustc/ui/issues/issue-54462-mutable-noalias-correctness.rs: New test. * rust/rustc/ui/issues/issue-54467.rs: New test. * rust/rustc/ui/issues/issue-54477-reduced-2.rs: New test. * rust/rustc/ui/issues/issue-54521-1.rs: New test. * rust/rustc/ui/issues/issue-54521-2.rs: New test. * rust/rustc/ui/issues/issue-54521.rs: New test. * rust/rustc/ui/issues/issue-54582.rs: New test. * rust/rustc/ui/issues/issue-54696.rs: New test. * rust/rustc/ui/issues/issue-54943-1.rs: New test. * rust/rustc/ui/issues/issue-54943-2.rs: New test. * rust/rustc/ui/issues/issue-54943-3.rs: New test. * rust/rustc/ui/issues/issue-54943.rs: New test. * rust/rustc/ui/issues/issue-54954.rs: New test. * rust/rustc/ui/issues/issue-54966.rs: New test. * rust/rustc/ui/issues/issue-5500-1.rs: New test. * rust/rustc/ui/issues/issue-5518.rs: New test. * rust/rustc/ui/issues/issue-5521.rs: New test. * rust/rustc/ui/issues/issue-5530.rs: New test. * rust/rustc/ui/issues/issue-55376.rs: New test. * rust/rustc/ui/issues/issue-55380.rs: New test. * rust/rustc/ui/issues/issue-5550.rs: New test. * rust/rustc/ui/issues/issue-55511.rs: New test. * rust/rustc/ui/issues/issue-5554.rs: New test. * rust/rustc/ui/issues/issue-55587.rs: New test. * rust/rustc/ui/issues/issue-5572.rs: New test. * rust/rustc/ui/issues/issue-55731.rs: New test. * rust/rustc/ui/issues/issue-55796.rs: New test. * rust/rustc/ui/issues/issue-55846.rs: New test. * rust/rustc/ui/issues/issue-56031.rs: New test. * rust/rustc/ui/issues/issue-56128.rs: New test. * rust/rustc/ui/issues/issue-56175.rs: New test. * rust/rustc/ui/issues/issue-56199.rs: New test. * rust/rustc/ui/issues/issue-56202.rs: New test. * rust/rustc/ui/issues/issue-56229.rs: New test. * rust/rustc/ui/issues/issue-56237.rs: New test. * rust/rustc/ui/issues/issue-56411-aux.rs: New test. * rust/rustc/ui/issues/issue-56411.rs: New test. * rust/rustc/ui/issues/issue-56488.rs: New test. * rust/rustc/ui/issues/issue-5666.rs: New test. * rust/rustc/ui/issues/issue-56685.rs: New test. * rust/rustc/ui/issues/issue-56762.rs: New test. * rust/rustc/ui/issues/issue-56806.rs: New test. * rust/rustc/ui/issues/issue-56835.rs: New test. * rust/rustc/ui/issues/issue-56870.rs: New test. * rust/rustc/ui/issues/issue-5688.rs: New test. * rust/rustc/ui/issues/issue-56943.rs: New test. * rust/rustc/ui/issues/issue-5708.rs: New test. * rust/rustc/ui/issues/issue-57156.rs: New test. * rust/rustc/ui/issues/issue-57162.rs: New test. * rust/rustc/ui/issues/issue-5718.rs: New test. * rust/rustc/ui/issues/issue-57198-pass.rs: New test. * rust/rustc/ui/issues/issue-57198.rs: New test. * rust/rustc/ui/issues/issue-57271.rs: New test. * rust/rustc/ui/issues/issue-57362-1.rs: New test. * rust/rustc/ui/issues/issue-57362-2.rs: New test. * rust/rustc/ui/issues/issue-57399-self-return-impl-trait.rs: New test. * rust/rustc/ui/issues/issue-5741.rs: New test. * rust/rustc/ui/issues/issue-57410-1.rs: New test. * rust/rustc/ui/issues/issue-57410.rs: New test. * rust/rustc/ui/issues/issue-57472.rs: New test. * rust/rustc/ui/issues/issue-5754.rs: New test. * rust/rustc/ui/issues/issue-57597.rs: New test. * rust/rustc/ui/issues/issue-57684.rs: New test. * rust/rustc/ui/issues/issue-57741-1.rs: New test. * rust/rustc/ui/issues/issue-57741.rs: New test. * rust/rustc/ui/issues/issue-57781.rs: New test. * rust/rustc/ui/issues/issue-57819.rs: New test. * rust/rustc/ui/issues/issue-57843.rs: New test. * rust/rustc/ui/issues/issue-5791.rs: New test. * rust/rustc/ui/issues/issue-57924.rs: New test. * rust/rustc/ui/issues/issue-58022.rs: New test. * rust/rustc/ui/issues/issue-58212.rs: New test. * rust/rustc/ui/issues/issue-58319.rs: New test. * rust/rustc/ui/issues/issue-58344.rs: New test. * rust/rustc/ui/issues/issue-58375-monomorphize-default-impls.rs: New test. * rust/rustc/ui/issues/issue-58435-ice-with-assoc-const.rs: New test. * rust/rustc/ui/issues/issue-5844.rs: New test. * rust/rustc/ui/issues/issue-58463.rs: New test. * rust/rustc/ui/issues/issue-58712.rs: New test. * rust/rustc/ui/issues/issue-58734.rs: New test. * rust/rustc/ui/issues/issue-5883.rs: New test. * rust/rustc/ui/issues/issue-5884.rs: New test. * rust/rustc/ui/issues/issue-58856-1.rs: New test. * rust/rustc/ui/issues/issue-58856-2.rs: New test. * rust/rustc/ui/issues/issue-58857.rs: New test. * rust/rustc/ui/issues/issue-5900.rs: New test. * rust/rustc/ui/issues/issue-59020.rs: New test. * rust/rustc/ui/issues/issue-59029-1.rs: New test. * rust/rustc/ui/issues/issue-59029-2.rs: New test. * rust/rustc/ui/issues/issue-5917.rs: New test. * rust/rustc/ui/issues/issue-5927.rs: New test. * rust/rustc/ui/issues/issue-59326.rs: New test. * rust/rustc/ui/issues/issue-59488.rs: New test. * rust/rustc/ui/issues/issue-59494.rs: New test. * rust/rustc/ui/issues/issue-5950.rs: New test. * rust/rustc/ui/issues/issue-59508-1.rs: New test. * rust/rustc/ui/issues/issue-59508.rs: New test. * rust/rustc/ui/issues/issue-59756.rs: New test. * rust/rustc/ui/issues/issue-59764.rs: New test. * rust/rustc/ui/issues/issue-5988.rs: New test. * rust/rustc/ui/issues/issue-59896.rs: New test. * rust/rustc/ui/issues/issue-5997-enum.rs: New test. * rust/rustc/ui/issues/issue-5997-struct.rs: New test. * rust/rustc/ui/issues/issue-5997.rs: New test. * rust/rustc/ui/issues/issue-60057.rs: New test. * rust/rustc/ui/issues/issue-60075.rs: New test. * rust/rustc/ui/issues/issue-60218.rs: New test. * rust/rustc/ui/issues/issue-60283.rs: New test. * rust/rustc/ui/issues/issue-60622.rs: New test. * rust/rustc/ui/issues/issue-60662.rs: New test. * rust/rustc/ui/issues/issue-60989.rs: New test. * rust/rustc/ui/issues/issue-61106.rs: New test. * rust/rustc/ui/issues/issue-61108.rs: New test. * rust/rustc/ui/issues/issue-6117.rs: New test. * rust/rustc/ui/issues/issue-6128.rs: New test. * rust/rustc/ui/issues/issue-6130.rs: New test. * rust/rustc/ui/issues/issue-61475.rs: New test. * rust/rustc/ui/issues/issue-6153.rs: New test. * rust/rustc/ui/issues/issue-6157.rs: New test. * rust/rustc/ui/issues/issue-61623.rs: New test. * rust/rustc/ui/issues/issue-61696.rs: New test. * rust/rustc/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs: New test. * rust/rustc/ui/issues/issue-61858.rs: New test. * rust/rustc/ui/issues/issue-61882-2.rs: New test. * rust/rustc/ui/issues/issue-61882.rs: New test. * rust/rustc/ui/issues/issue-61894.rs: New test. * rust/rustc/ui/issues/issue-62375.rs: New test. * rust/rustc/ui/issues/issue-62480.rs: New test. * rust/rustc/ui/issues/issue-62554.rs: New test. * rust/rustc/ui/issues/issue-6318.rs: New test. * rust/rustc/ui/issues/issue-6334.rs: New test. * rust/rustc/ui/issues/issue-63364.rs: New test. * rust/rustc/ui/issues/issue-6341.rs: New test. * rust/rustc/ui/issues/issue-6344-let.rs: New test. * rust/rustc/ui/issues/issue-6344-match.rs: New test. * rust/rustc/ui/issues/issue-63983.rs: New test. * rust/rustc/ui/issues/issue-64430.rs: New test. * rust/rustc/ui/issues/issue-6449.rs: New test. * rust/rustc/ui/issues/issue-64559.rs: New test. * rust/rustc/ui/issues/issue-6458-1.rs: New test. * rust/rustc/ui/issues/issue-6458-2.rs: New test. * rust/rustc/ui/issues/issue-6458-3.rs: New test. * rust/rustc/ui/issues/issue-6458-4.rs: New test. * rust/rustc/ui/issues/issue-6458.rs: New test. * rust/rustc/ui/issues/issue-64593.rs: New test. * rust/rustc/ui/issues/issue-64620.rs: New test. * rust/rustc/ui/issues/issue-6470.rs: New test. * rust/rustc/ui/issues/issue-64732.rs: New test. * rust/rustc/ui/issues/issue-64792-bad-unicode-ctor.rs: New test. * rust/rustc/ui/issues/issue-65131.rs: New test. * rust/rustc/ui/issues/issue-65284-suggest-generic-trait-bound.rs: New test. * rust/rustc/ui/issues/issue-65462.rs: New test. * rust/rustc/ui/issues/issue-6557.rs: New test. * rust/rustc/ui/issues/issue-65611.rs: New test. * rust/rustc/ui/issues/issue-65634-raw-ident-suggestion.rs: New test. * rust/rustc/ui/issues/issue-65673.rs: New test. * rust/rustc/ui/issues/issue-6596-1.rs: New test. * rust/rustc/ui/issues/issue-6596-2.rs: New test. * rust/rustc/ui/issues/issue-66308.rs: New test. * rust/rustc/ui/issues/issue-66353.rs: New test. * rust/rustc/ui/issues/issue-6642.rs: New test. * rust/rustc/ui/issues/issue-66473.rs: New test. * rust/rustc/ui/issues/issue-66667-function-cmp-cycle.rs: New test. * rust/rustc/ui/issues/issue-66702-break-outside-loop-val.rs: New test. * rust/rustc/ui/issues/issue-66706.rs: New test. * rust/rustc/ui/issues/issue-66768.rs: New test. * rust/rustc/ui/issues/issue-66851.rs: New test. * rust/rustc/ui/issues/issue-66923-show-error-for-correct-call.rs: New test. * rust/rustc/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs: New test. * rust/rustc/ui/issues/issue-67039-unsound-pin-partialeq.rs: New test. * rust/rustc/ui/issues/issue-6738.rs: New test. * rust/rustc/ui/issues/issue-67552.rs: New test. * rust/rustc/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs: New test. * rust/rustc/ui/issues/issue-6801.rs: New test. * rust/rustc/ui/issues/issue-68010-large-zst-consts.rs: New test. * rust/rustc/ui/issues/issue-6804.rs: New test. * rust/rustc/ui/issues/issue-68091-unicode-ident-after-if.rs: New test. * rust/rustc/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs: New test. * rust/rustc/ui/issues/issue-68103.rs: New test. * rust/rustc/ui/issues/issue-68696-catch-during-unwind.rs: New test. * rust/rustc/ui/issues/issue-6892.rs: New test. * rust/rustc/ui/issues/issue-68951.rs: New test. * rust/rustc/ui/issues/issue-6898.rs: New test. * rust/rustc/ui/issues/issue-69130.rs: New test. * rust/rustc/ui/issues/issue-6919.rs: New test. * rust/rustc/ui/issues/issue-69225-SCEVAddExpr-wrap-flag.rs: New test. * rust/rustc/ui/issues/issue-69225-layout-repeated-checked-add.rs: New test. * rust/rustc/ui/issues/issue-69306.rs: New test. * rust/rustc/ui/issues/issue-6936.rs: New test. * rust/rustc/ui/issues/issue-69396-const-no-type-in-macro.rs: New test. * rust/rustc/ui/issues/issue-69455.rs: New test. * rust/rustc/ui/issues/issue-69532.rs: New test. * rust/rustc/ui/issues/issue-69602-type-err-during-codegen-ice.rs: New test. * rust/rustc/ui/issues/issue-69683.rs: New test. * rust/rustc/ui/issues/issue-69725.rs: New test. * rust/rustc/ui/issues/issue-69841.rs: New test. * rust/rustc/ui/issues/issue-6991.rs: New test. * rust/rustc/ui/issues/issue-70041.rs: New test. * rust/rustc/ui/issues/issue-70093.rs: New test. * rust/rustc/ui/issues/issue-7012.rs: New test. * rust/rustc/ui/issues/issue-7013.rs: New test. * rust/rustc/ui/issues/issue-70381.rs: New test. * rust/rustc/ui/issues/issue-7044.rs: New test. * rust/rustc/ui/issues/issue-7061.rs: New test. * rust/rustc/ui/issues/issue-70673.rs: New test. * rust/rustc/ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs: New test. * rust/rustc/ui/issues/issue-70746.rs: New test. * rust/rustc/ui/issues/issue-7092.rs: New test. * rust/rustc/ui/issues/issue-71036.rs: New test. * rust/rustc/ui/issues/issue-71406.rs: New test. * rust/rustc/ui/issues/issue-71584.rs: New test. * rust/rustc/ui/issues/issue-71676-1.rs: New test. * rust/rustc/ui/issues/issue-71676-2.rs: New test. * rust/rustc/ui/issues/issue-7178.rs: New test. * rust/rustc/ui/issues/issue-72002.rs: New test. * rust/rustc/ui/issues/issue-72076.rs: New test. * rust/rustc/ui/issues/issue-7222.rs: New test. * rust/rustc/ui/issues/issue-72253.rs: New test. * rust/rustc/ui/issues/issue-72278.rs: New test. * rust/rustc/ui/issues/issue-72373.rs: New test. * rust/rustc/ui/issues/issue-72455.rs: New test. * rust/rustc/ui/issues/issue-7246.rs: New test. * rust/rustc/ui/issues/issue-72554.rs: New test. * rust/rustc/ui/issues/issue-72574-1.rs: New test. * rust/rustc/ui/issues/issue-72574-2.rs: New test. * rust/rustc/ui/issues/issue-7268.rs: New test. * rust/rustc/ui/issues/issue-72690.rs: New test. * rust/rustc/ui/issues/issue-72839-error-overflow.rs: New test. * rust/rustc/ui/issues/issue-72933-match-stack-overflow.rs: New test. * rust/rustc/ui/issues/issue-73112.rs: New test. * rust/rustc/ui/issues/issue-73229.rs: New test. * rust/rustc/ui/issues/issue-73427.rs: New test. * rust/rustc/ui/issues/issue-7344.rs: New test. * rust/rustc/ui/issues/issue-73541-1.rs: New test. * rust/rustc/ui/issues/issue-73541-2.rs: New test. * rust/rustc/ui/issues/issue-73541-3.rs: New test. * rust/rustc/ui/issues/issue-73541.rs: New test. * rust/rustc/ui/issues/issue-7364.rs: New test. * rust/rustc/ui/issues/issue-73886.rs: New test. * rust/rustc/ui/issues/issue-74082.rs: New test. * rust/rustc/ui/issues/issue-74086.rs: New test. * rust/rustc/ui/issues/issue-74236/auxiliary/dep.rs: New test. * rust/rustc/ui/issues/issue-74236/main.rs: New test. * rust/rustc/ui/issues/issue-74564-if-expr-stack-overflow.rs: New test. * rust/rustc/ui/issues/issue-74614.rs: New test. * rust/rustc/ui/issues/issue-74739.rs: New test. * rust/rustc/ui/issues/issue-7519-match-unit-in-arg.rs: New test. * rust/rustc/ui/issues/issue-75283.rs: New test. * rust/rustc/ui/issues/issue-75307.rs: New test. * rust/rustc/ui/issues/issue-75599.rs: New test. * rust/rustc/ui/issues/issue-7563.rs: New test. * rust/rustc/ui/issues/issue-75704.rs: New test. * rust/rustc/ui/issues/issue-7575.rs: New test. * rust/rustc/ui/issues/issue-75763.rs: New test. * rust/rustc/ui/issues/issue-75777.rs: New test. * rust/rustc/ui/issues/issue-75906.rs: New test. * rust/rustc/ui/issues/issue-75907.rs: New test. * rust/rustc/ui/issues/issue-75907_b.rs: New test. * rust/rustc/ui/issues/issue-7607-1.rs: New test. * rust/rustc/ui/issues/issue-7607-2.rs: New test. * rust/rustc/ui/issues/issue-76077-1.rs: New test. * rust/rustc/ui/issues/issue-76077.rs: New test. * rust/rustc/ui/issues/issue-76179.rs: New test. * rust/rustc/ui/issues/issue-76191.rs: New test. * rust/rustc/ui/issues/issue-76547.rs: New test. * rust/rustc/ui/issues/issue-7660.rs: New test. * rust/rustc/ui/issues/issue-7663.rs: New test. * rust/rustc/ui/issues/issue-7673-cast-generically-implemented-trait.rs: New test. * rust/rustc/ui/issues/issue-77002.rs: New test. * rust/rustc/ui/issues/issue-77218.rs: New test. * rust/rustc/ui/issues/issue-7784.rs: New test. * rust/rustc/ui/issues/issue-77919.rs: New test. * rust/rustc/ui/issues/issue-77993-1.rs: New test. * rust/rustc/ui/issues/issue-77993-2.rs: New test. * rust/rustc/ui/issues/issue-78115.rs: New test. * rust/rustc/ui/issues/issue-7813.rs: New test. * rust/rustc/ui/issues/issue-78192.rs: New test. * rust/rustc/ui/issues/issue-78372.rs: New test. * rust/rustc/ui/issues/issue-78622.rs: New test. * rust/rustc/ui/issues/issue-7867.rs: New test. * rust/rustc/ui/issues/issue-7899.rs: New test. * rust/rustc/ui/issues/issue-7911.rs: New test. * rust/rustc/ui/issues/issue-7950.rs: New test. * rust/rustc/ui/issues/issue-7970a.rs: New test. * rust/rustc/ui/issues/issue-7970b.rs: New test. * rust/rustc/ui/issues/issue-8044.rs: New test. * rust/rustc/ui/issues/issue-811.rs: New test. * rust/rustc/ui/issues/issue-8153.rs: New test. * rust/rustc/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs: New test. * rust/rustc/ui/issues/issue-8208.rs: New test. * rust/rustc/ui/issues/issue-8248.rs: New test. * rust/rustc/ui/issues/issue-8249.rs: New test. * rust/rustc/ui/issues/issue-8259.rs: New test. * rust/rustc/ui/issues/issue-8351-1.rs: New test. * rust/rustc/ui/issues/issue-8351-2.rs: New test. * rust/rustc/ui/issues/issue-8391.rs: New test. * rust/rustc/ui/issues/issue-8398.rs: New test. * rust/rustc/ui/issues/issue-8401.rs: New test. * rust/rustc/ui/issues/issue-8460-const.rs: New test. * rust/rustc/ui/issues/issue-8460.rs: New test. * rust/rustc/ui/issues/issue-8498.rs: New test. * rust/rustc/ui/issues/issue-8506.rs: New test. * rust/rustc/ui/issues/issue-8521.rs: New test. * rust/rustc/ui/issues/issue-8578.rs: New test. * rust/rustc/ui/issues/issue-8640.rs: New test. * rust/rustc/ui/issues/issue-868.rs: New test. * rust/rustc/ui/issues/issue-8709.rs: New test. * rust/rustc/ui/issues/issue-8727.rs: New test. * rust/rustc/ui/issues/issue-8761.rs: New test. * rust/rustc/ui/issues/issue-8767.rs: New test. * rust/rustc/ui/issues/issue-8783.rs: New test. * rust/rustc/ui/issues/issue-8827.rs: New test. * rust/rustc/ui/issues/issue-8851.rs: New test. * rust/rustc/ui/issues/issue-8860.rs: New test. * rust/rustc/ui/issues/issue-8898.rs: New test. * rust/rustc/ui/issues/issue-9047.rs: New test. * rust/rustc/ui/issues/issue-9110.rs: New test. * rust/rustc/ui/issues/issue-9123.rs: New test. * rust/rustc/ui/issues/issue-9129.rs: New test. * rust/rustc/ui/issues/issue-9155.rs: New test. * rust/rustc/ui/issues/issue-9188.rs: New test. * rust/rustc/ui/issues/issue-9243.rs: New test. * rust/rustc/ui/issues/issue-9249.rs: New test. * rust/rustc/ui/issues/issue-9259.rs: New test. * rust/rustc/ui/issues/issue-9382.rs: New test. * rust/rustc/ui/issues/issue-9394-inherited-trait-calls.rs: New test. * rust/rustc/ui/issues/issue-9396.rs: New test. * rust/rustc/ui/issues/issue-9446.rs: New test. * rust/rustc/ui/issues/issue-948.rs: New test. * rust/rustc/ui/issues/issue-9575.rs: New test. * rust/rustc/ui/issues/issue-9719.rs: New test. * rust/rustc/ui/issues/issue-9725.rs: New test. * rust/rustc/ui/issues/issue-9737.rs: New test. * rust/rustc/ui/issues/issue-979.rs: New test. * rust/rustc/ui/issues/issue-9814.rs: New test. * rust/rustc/ui/issues/issue-9837.rs: New test. * rust/rustc/ui/issues/issue-9906.rs: New test. * rust/rustc/ui/issues/issue-9918.rs: New test. * rust/rustc/ui/issues/issue-9942.rs: New test. * rust/rustc/ui/issues/issue-9951.rs: New test. * rust/rustc/ui/issues/issue-9968.rs: New test. * rust/rustc/ui/issues/issue-pr29383.rs: New test. * rust/rustc/ui/issues/type-arg-mismatch-due-to-impl-trait.rs: New test. * rust/rustc/ui/istr.rs: New test. * rust/rustc/ui/item-name-overload.rs: New test. * rust/rustc/ui/iterators/array-of-ranges.rs: New test. * rust/rustc/ui/iterators/array.rs: New test. * rust/rustc/ui/iterators/bound.rs: New test. * rust/rustc/ui/iterators/integral.rs: New test. * rust/rustc/ui/iterators/into-iter-on-arrays-lint.rs: New test. * rust/rustc/ui/iterators/into-iterator-type-inference-shift.rs: New test. * rust/rustc/ui/iterators/issue-58952-filter-type-length.rs: New test. * rust/rustc/ui/iterators/iter-cloned-type-inference.rs: New test. * rust/rustc/ui/iterators/iter-count-overflow-debug.rs: New test. * rust/rustc/ui/iterators/iter-count-overflow-ndebug.rs: New test. * rust/rustc/ui/iterators/iter-map-fold-type-length.rs: New test. * rust/rustc/ui/iterators/iter-position-overflow-debug.rs: New test. * rust/rustc/ui/iterators/iter-position-overflow-ndebug.rs: New test. * rust/rustc/ui/iterators/iter-range.rs: New test. * rust/rustc/ui/iterators/iter-step-overflow-debug.rs: New test. * rust/rustc/ui/iterators/iter-step-overflow-ndebug.rs: New test. * rust/rustc/ui/iterators/iter-sum-overflow-debug.rs: New test. * rust/rustc/ui/iterators/iter-sum-overflow-ndebug.rs: New test. * rust/rustc/ui/iterators/iter-sum-overflow-overflow-checks.rs: New test. * rust/rustc/ui/iterators/ranges.rs: New test. * rust/rustc/ui/iterators/skip-count-overflow.rs: New test. * rust/rustc/ui/iterators/string.rs: New test. * rust/rustc/ui/json-and-color.rs: New test. * rust/rustc/ui/json-and-error-format.rs: New test. * rust/rustc/ui/json-bom-plus-crlf-multifile-aux.rs: New test. * rust/rustc/ui/json-bom-plus-crlf-multifile.rs: New test. * rust/rustc/ui/json-bom-plus-crlf.rs: New test. * rust/rustc/ui/json-invalid.rs: New test. * rust/rustc/ui/json-multiple.rs: New test. * rust/rustc/ui/json-options.rs: New test. * rust/rustc/ui/json-short.rs: New test. * rust/rustc/ui/keyword-changes-2012-07-31.rs: New test. * rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-expr.rs: New test. * rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-pat.rs: New test. * rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-type.rs: New test. * rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-use.rs: New test. * rust/rustc/ui/keyword/keyword-false-as-identifier.rs: New test. * rust/rustc/ui/keyword/keyword-self-as-identifier.rs: New test. * rust/rustc/ui/keyword/keyword-super-as-identifier.rs: New test. * rust/rustc/ui/keyword/keyword-super.rs: New test. * rust/rustc/ui/keyword/keyword-true-as-identifier.rs: New test. * rust/rustc/ui/kindck-implicit-close-over-mut-var.rs: New test. * rust/rustc/ui/kindck/kindck-copy.rs: New test. * rust/rustc/ui/kindck/kindck-impl-type-params-2.rs: New test. * rust/rustc/ui/kindck/kindck-impl-type-params.rs: New test. * rust/rustc/ui/kindck/kindck-inherited-copy-bound.rs: New test. * rust/rustc/ui/kindck/kindck-nonsendable-1.rs: New test. * rust/rustc/ui/kindck/kindck-send-object.rs: New test. * rust/rustc/ui/kindck/kindck-send-object1.rs: New test. * rust/rustc/ui/kindck/kindck-send-object2.rs: New test. * rust/rustc/ui/kindck/kindck-send-owned.rs: New test. * rust/rustc/ui/kindck/kindck-send-unsafe.rs: New test. * rust/rustc/ui/kinds-in-metadata.rs: New test. * rust/rustc/ui/label/label-beginning-with-underscore.rs: New test. * rust/rustc/ui/label/label-static.rs: New test. * rust/rustc/ui/label/label-underscore.rs: New test. * rust/rustc/ui/label/label_break_value_continue.rs: New test. * rust/rustc/ui/label/label_break_value_desugared_break.rs: New test. * rust/rustc/ui/label/label_break_value_illegal_uses.rs: New test. * rust/rustc/ui/label/label_break_value_unlabeled_break.rs: New test. * rust/rustc/ui/lambda-infer-unresolved.rs: New test. * rust/rustc/ui/lambda-var-hygiene.rs: New test. * rust/rustc/ui/lang-item-missing-generator.rs: New test. * rust/rustc/ui/lang-item-missing.rs: New test. * rust/rustc/ui/large-records.rs: New test. * rust/rustc/ui/last-use-in-block.rs: New test. * rust/rustc/ui/last-use-in-cap-clause.rs: New test. * rust/rustc/ui/last-use-is-capture.rs: New test. * rust/rustc/ui/layout/debug.rs: New test. * rust/rustc/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs: New test. * rust/rustc/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs: New test. * rust/rustc/ui/layout/issue-60431-unsized-tail-behind-projection.rs: New test. * rust/rustc/ui/layout/unsafe-cell-hides-niche.rs: New test. * rust/rustc/ui/layout/zero-sized-array-union.rs: New test. * rust/rustc/ui/lazy-and-or.rs: New test. * rust/rustc/ui/lazy-init.rs: New test. * rust/rustc/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs: New test. * rust/rustc/ui/lazy_normalization_consts/issue-47814.rs: New test. * rust/rustc/ui/lazy_normalization_consts/issue-57739.rs: New test. * rust/rustc/ui/lazy_normalization_consts/issue-73980.rs: New test. * rust/rustc/ui/lazy_normalization_consts/trait-resolution-breakage.rs: New test. * rust/rustc/ui/lazy_normalization_consts/unevaluated-consts.rs: New test. * rust/rustc/ui/leak-unique-as-tydesc.rs: New test. * rust/rustc/ui/lex-bare-cr-nondoc-comment.rs: New test. * rust/rustc/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs: New test. * rust/rustc/ui/lexical-scopes.rs: New test. * rust/rustc/ui/lexical-scoping.rs: New test. * rust/rustc/ui/lifetime-before-type-params.rs: New test. * rust/rustc/ui/lifetime_starts_expressions.rs: New test. * rust/rustc/ui/lifetimes/auxiliary/lifetime_bound_will_change_warning_lib.rs: New test. * rust/rustc/ui/lifetimes/borrowck-let-suggestion.rs: New test. * rust/rustc/ui/lifetimes/issue-34979.rs: New test. * rust/rustc/ui/lifetimes/issue-70917-lifetimes-in-fn-def.rs: New test. * rust/rustc/ui/lifetimes/lifetime-bound-will-change-warning.rs: New test. * rust/rustc/ui/lifetimes/lifetime-doesnt-live-long-enough.rs: New test. * rust/rustc/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs: New test. * rust/rustc/ui/lifetimes/lifetime-elision-return-type-trait.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs: New test. * rust/rustc/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs: New test. * rust/rustc/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs: New test. * rust/rustc/ui/lifetimes/lifetime-no-keyword.rs: New test. * rust/rustc/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs: New test. * rust/rustc/ui/link-cfg-works.rs: New test. * rust/rustc/ui/link-section.rs: New test. * rust/rustc/ui/linkage-attr/auxiliary/def_colliding_external.rs: New test. * rust/rustc/ui/linkage-attr/auxiliary/def_illtyped_external.rs: New test. * rust/rustc/ui/linkage-attr/linkage-detect-extern-generated-name-collision.rs: New test. * rust/rustc/ui/linkage-attr/linkage-detect-local-generated-name-collision.rs: New test. * rust/rustc/ui/linkage-attr/linkage-requires-raw-ptr.rs: New test. * rust/rustc/ui/linkage-attr/linkage2.rs: New test. * rust/rustc/ui/linkage-attr/linkage3.rs: New test. * rust/rustc/ui/linkage-attr/linkage4.rs: New test. * rust/rustc/ui/linkage1.rs: New test. * rust/rustc/ui/lint-cap.rs: New test. * rust/rustc/ui/lint-expr-stmt-attrs-for-early-lints.rs: New test. * rust/rustc/ui/lint-unknown-lints-at-crate-level.rs: New test. * rust/rustc/ui/lint/auxiliary/external_extern_fn.rs: New test. * rust/rustc/ui/lint/auxiliary/inherited_stability.rs: New test. * rust/rustc/ui/lint/auxiliary/lint_output_format.rs: New test. * rust/rustc/ui/lint/auxiliary/lint_stability.rs: New test. * rust/rustc/ui/lint/auxiliary/lint_stability_fields.rs: New test. * rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate.rs: New test. * rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate2.rs: New test. * rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate3.rs: New test. * rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate4.rs: New test. * rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate5.rs: New test. * rust/rustc/ui/lint/auxiliary/lints-in-foreign-macros.rs: New test. * rust/rustc/ui/lint/auxiliary/stability-cfg2.rs: New test. * rust/rustc/ui/lint/auxiliary/stability_cfg1.rs: New test. * rust/rustc/ui/lint/auxiliary/stability_cfg2.rs: New test. * rust/rustc/ui/lint/clashing-extern-fn-recursion.rs: New test. * rust/rustc/ui/lint/clashing-extern-fn.rs: New test. * rust/rustc/ui/lint/command-line-lint-group-allow.rs: New test. * rust/rustc/ui/lint/command-line-lint-group-deny.rs: New test. * rust/rustc/ui/lint/command-line-lint-group-forbid.rs: New test. * rust/rustc/ui/lint/command-line-lint-group-warn.rs: New test. * rust/rustc/ui/lint/crate_level_only_lint.rs: New test. * rust/rustc/ui/lint/dead-code/alias-in-pat.rs: New test. * rust/rustc/ui/lint/dead-code/associated-type.rs: New test. * rust/rustc/ui/lint/dead-code/basic.rs: New test. * rust/rustc/ui/lint/dead-code/closure-bang.rs: New test. * rust/rustc/ui/lint/dead-code/const-and-self.rs: New test. * rust/rustc/ui/lint/dead-code/empty-unused-enum.rs: New test. * rust/rustc/ui/lint/dead-code/empty-unused-public-enum.rs: New test. * rust/rustc/ui/lint/dead-code/enum-variants.rs: New test. * rust/rustc/ui/lint/dead-code/impl-trait.rs: New test. * rust/rustc/ui/lint/dead-code/leading-underscore.rs: New test. * rust/rustc/ui/lint/dead-code/lint-dead-code-1.rs: New test. * rust/rustc/ui/lint/dead-code/lint-dead-code-2.rs: New test. * rust/rustc/ui/lint/dead-code/lint-dead-code-3.rs: New test. * rust/rustc/ui/lint/dead-code/lint-dead-code-4.rs: New test. * rust/rustc/ui/lint/dead-code/lint-dead-code-5.rs: New test. * rust/rustc/ui/lint/dead-code/lint-dead-code-6.rs: New test. * rust/rustc/ui/lint/dead-code/newline-span.rs: New test. * rust/rustc/ui/lint/dead-code/trait-impl.rs: New test. * rust/rustc/ui/lint/dead-code/tuple-struct-field.rs: New test. * rust/rustc/ui/lint/dead-code/type-alias.rs: New test. * rust/rustc/ui/lint/dead-code/unused-enum.rs: New test. * rust/rustc/ui/lint/dead-code/unused-struct-variant.rs: New test. * rust/rustc/ui/lint/dead-code/unused-variant-pub.rs: New test. * rust/rustc/ui/lint/dead-code/unused-variant.rs: New test. * rust/rustc/ui/lint/dead-code/with-core-crate.rs: New test. * rust/rustc/ui/lint/dead-code/with-impl.rs: New test. * rust/rustc/ui/lint/deny-overflowing-literals.rs: New test. * rust/rustc/ui/lint/empty-lint-attributes.rs: New test. * rust/rustc/ui/lint/expansion-time-include.rs: New test. * rust/rustc/ui/lint/expansion-time.rs: New test. * rust/rustc/ui/lint/function-item-references.rs: New test. * rust/rustc/ui/lint/inclusive-range-pattern-syntax.rs: New test. * rust/rustc/ui/lint/inline-trait-and-foreign-items.rs: New test. * rust/rustc/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs: New test. * rust/rustc/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs: New test. * rust/rustc/ui/lint/issue-54099-camel-case-underscore-types.rs: New test. * rust/rustc/ui/lint/issue-54180-unused-ref-field.rs: New test. * rust/rustc/ui/lint/issue-54538-unused-parens-lint.rs: New test. * rust/rustc/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs: New test. * rust/rustc/ui/lint/issue-67691-unused-field-in-or-pattern.rs: New test. * rust/rustc/ui/lint/issue-69485-var-size-diffs-too-large.rs: New test. * rust/rustc/ui/lint/issue-71290-unused-paren-binop.rs: New test. * rust/rustc/ui/lint/issue-74883-unused-paren-baren-yield.rs: New test. * rust/rustc/ui/lint/issue-78660-cap-lints-future-compat.rs: New test. * rust/rustc/ui/lint/lint-attr-non-item-node.rs: New test. * rust/rustc/ui/lint/lint-change-warnings.rs: New test. * rust/rustc/ui/lint/lint-const-item-mutation.rs: New test. * rust/rustc/ui/lint/lint-ctypes-66202.rs: New test. * rust/rustc/ui/lint/lint-ctypes-73249-1.rs: New test. * rust/rustc/ui/lint/lint-ctypes-73249-2.rs: New test. * rust/rustc/ui/lint/lint-ctypes-73249-3.rs: New test. * rust/rustc/ui/lint/lint-ctypes-73249-4.rs: New test. * rust/rustc/ui/lint/lint-ctypes-73249-5.rs: New test. * rust/rustc/ui/lint/lint-ctypes-73249.rs: New test. * rust/rustc/ui/lint/lint-ctypes-73251-1.rs: New test. * rust/rustc/ui/lint/lint-ctypes-73251-2.rs: New test. * rust/rustc/ui/lint/lint-ctypes-73251.rs: New test. * rust/rustc/ui/lint/lint-ctypes-73747.rs: New test. * rust/rustc/ui/lint/lint-ctypes-enum.rs: New test. * rust/rustc/ui/lint/lint-ctypes-fn.rs: New test. * rust/rustc/ui/lint/lint-ctypes.rs: New test. * rust/rustc/ui/lint/lint-directives-on-use-items-issue-10534.rs: New test. * rust/rustc/ui/lint/lint-exceeding-bitshifts.rs: New test. * rust/rustc/ui/lint/lint-forbid-attr.rs: New test. * rust/rustc/ui/lint/lint-forbid-cmdline.rs: New test. * rust/rustc/ui/lint/lint-forbid-internal-unsafe.rs: New test. * rust/rustc/ui/lint/lint-group-nonstandard-style.rs: New test. * rust/rustc/ui/lint/lint-impl-fn.rs: New test. * rust/rustc/ui/lint/lint-incoherent-auto-trait-objects.rs: New test. * rust/rustc/ui/lint/lint-lowercase-static-const-pattern-rename.rs: New test. * rust/rustc/ui/lint/lint-lowercase-static-const-pattern.rs: New test. * rust/rustc/ui/lint/lint-malformed.rs: New test. * rust/rustc/ui/lint/lint-match-arms.rs: New test. * rust/rustc/ui/lint/lint-misplaced-attr.rs: New test. * rust/rustc/ui/lint/lint-missing-copy-implementations.rs: New test. * rust/rustc/ui/lint/lint-missing-doc.rs: New test. * rust/rustc/ui/lint/lint-non-camel-case-types.rs: New test. * rust/rustc/ui/lint/lint-non-camel-case-variant.rs: New test. * rust/rustc/ui/lint/lint-non-camel-case-with-trailing-underscores.rs: New test. * rust/rustc/ui/lint/lint-non-snake-case-crate-2.rs: New test. * rust/rustc/ui/lint/lint-non-snake-case-crate.rs: New test. * rust/rustc/ui/lint/lint-non-snake-case-functions.rs: New test. * rust/rustc/ui/lint/lint-non-snake-case-lifetimes.rs: New test. * rust/rustc/ui/lint/lint-non-snake-case-modules.rs: New test. * rust/rustc/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs: New test. * rust/rustc/ui/lint/lint-non-uppercase-associated-const.rs: New test. * rust/rustc/ui/lint/lint-non-uppercase-statics.rs: New test. * rust/rustc/ui/lint/lint-nonstandard-style-unicode-1.rs: New test. * rust/rustc/ui/lint/lint-nonstandard-style-unicode-2.rs: New test. * rust/rustc/ui/lint/lint-nonstandard-style-unicode-3.rs: New test. * rust/rustc/ui/lint/lint-output-format-2.rs: New test. * rust/rustc/ui/lint/lint-output-format.rs: New test. * rust/rustc/ui/lint/lint-owned-heap-memory.rs: New test. * rust/rustc/ui/lint/lint-pre-expansion-extern-module.rs: New test. * rust/rustc/ui/lint/lint-qualification.rs: New test. * rust/rustc/ui/lint/lint-range-endpoint-overflow.rs: New test. * rust/rustc/ui/lint/lint-removed-allow.rs: New test. * rust/rustc/ui/lint/lint-removed-cmdline.rs: New test. * rust/rustc/ui/lint/lint-removed.rs: New test. * rust/rustc/ui/lint/lint-renamed-allow.rs: New test. * rust/rustc/ui/lint/lint-renamed-cmdline.rs: New test. * rust/rustc/ui/lint/lint-renamed.rs: New test. * rust/rustc/ui/lint/lint-shorthand-field.rs: New test. * rust/rustc/ui/lint/lint-stability-2.rs: New test. * rust/rustc/ui/lint/lint-stability-deprecated.rs: New test. * rust/rustc/ui/lint/lint-stability-fields-deprecated.rs: New test. * rust/rustc/ui/lint/lint-stability-fields.rs: New test. * rust/rustc/ui/lint/lint-stability.rs: New test. * rust/rustc/ui/lint/lint-stability2.rs: New test. * rust/rustc/ui/lint/lint-stability3.rs: New test. * rust/rustc/ui/lint/lint-temporary-cstring-as-param.rs: New test. * rust/rustc/ui/lint/lint-temporary-cstring-as-ptr.rs: New test. * rust/rustc/ui/lint/lint-type-limits.rs: New test. * rust/rustc/ui/lint/lint-type-limits2.rs: New test. * rust/rustc/ui/lint/lint-type-limits3.rs: New test. * rust/rustc/ui/lint/lint-type-overflow.rs: New test. * rust/rustc/ui/lint/lint-type-overflow2.rs: New test. * rust/rustc/ui/lint/lint-unconditional-recursion.rs: New test. * rust/rustc/ui/lint/lint-unexported-no-mangle.rs: New test. * rust/rustc/ui/lint/lint-unknown-feature-default.rs: New test. * rust/rustc/ui/lint/lint-unknown-feature.rs: New test. * rust/rustc/ui/lint/lint-unknown-lint-cmdline.rs: New test. * rust/rustc/ui/lint/lint-unknown-lint.rs: New test. * rust/rustc/ui/lint/lint-unnecessary-import-braces.rs: New test. * rust/rustc/ui/lint/lint-unnecessary-parens.rs: New test. * rust/rustc/ui/lint/lint-unsafe-code.rs: New test. * rust/rustc/ui/lint/lint-unused-extern-crate.rs: New test. * rust/rustc/ui/lint/lint-unused-imports.rs: New test. * rust/rustc/ui/lint/lint-unused-mut-self.rs: New test. * rust/rustc/ui/lint/lint-unused-mut-variables.rs: New test. * rust/rustc/ui/lint/lint-unused-variables.rs: New test. * rust/rustc/ui/lint/lint-uppercase-variables.rs: New test. * rust/rustc/ui/lint/lint_pre_expansion_extern_module_aux.rs: New test. * rust/rustc/ui/lint/lints-in-foreign-macros.rs: New test. * rust/rustc/ui/lint/must-use-ops.rs: New test. * rust/rustc/ui/lint/must_use-array.rs: New test. * rust/rustc/ui/lint/must_use-trait.rs: New test. * rust/rustc/ui/lint/must_use-tuple.rs: New test. * rust/rustc/ui/lint/must_use-unit.rs: New test. * rust/rustc/ui/lint/no-unused-parens-return-block.rs: New test. * rust/rustc/ui/lint/not_found.rs: New test. * rust/rustc/ui/lint/opaque-ty-ffi-unsafe.rs: New test. * rust/rustc/ui/lint/outer-forbid.rs: New test. * rust/rustc/ui/lint/reasons-erroneous.rs: New test. * rust/rustc/ui/lint/reasons-forbidden.rs: New test. * rust/rustc/ui/lint/reasons.rs: New test. * rust/rustc/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs: New test. * rust/rustc/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs: New test. * rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs: New test. * rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables-2.rs: New test. * rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.rs: New test. * rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs: New test. * rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs: New test. * rust/rustc/ui/lint/suggestions.rs: New test. * rust/rustc/ui/lint/test-inner-fn.rs: New test. * rust/rustc/ui/lint/trivial-casts-featuring-type-ascription.rs: New test. * rust/rustc/ui/lint/trivial-casts.rs: New test. * rust/rustc/ui/lint/type-overflow.rs: New test. * rust/rustc/ui/lint/unaligned_references.rs: New test. * rust/rustc/ui/lint/uninitialized-zeroed.rs: New test. * rust/rustc/ui/lint/unreachable-async-fn.rs: New test. * rust/rustc/ui/lint/unreachable_pub-pub_crate.rs: New test. * rust/rustc/ui/lint/unreachable_pub.rs: New test. * rust/rustc/ui/lint/unused-braces-while-let-with-mutable-value.rs: New test. * rust/rustc/ui/lint/unused_braces.rs: New test. * rust/rustc/ui/lint/unused_braces_borrow.rs: New test. * rust/rustc/ui/lint/unused_import_warning_issue_45268.rs: New test. * rust/rustc/ui/lint/unused_labels.rs: New test. * rust/rustc/ui/lint/unused_parens_json_suggestion.rs: New test. * rust/rustc/ui/lint/unused_parens_remove_json_suggestion.rs: New test. * rust/rustc/ui/lint/use-redundant.rs: New test. * rust/rustc/ui/lint/use_suggestion_json.rs: New test. * rust/rustc/ui/lint/warn-unused-inline-on-fn-prototypes.rs: New test. * rust/rustc/ui/list.rs: New test. * rust/rustc/ui/liveness-assign-imm-local-after-ret.rs: New test. * rust/rustc/ui/liveness/liveness-asm.rs: New test. * rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs: New test. * rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs: New test. * rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs: New test. * rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs: New test. * rust/rustc/ui/liveness/liveness-closure-require-ret.rs: New test. * rust/rustc/ui/liveness/liveness-consts.rs: New test. * rust/rustc/ui/liveness/liveness-dead.rs: New test. * rust/rustc/ui/liveness/liveness-derive.rs: New test. * rust/rustc/ui/liveness/liveness-forgot-ret.rs: New test. * rust/rustc/ui/liveness/liveness-issue-2163.rs: New test. * rust/rustc/ui/liveness/liveness-missing-ret2.rs: New test. * rust/rustc/ui/liveness/liveness-move-call-arg.rs: New test. * rust/rustc/ui/liveness/liveness-move-in-loop.rs: New test. * rust/rustc/ui/liveness/liveness-move-in-while.rs: New test. * rust/rustc/ui/liveness/liveness-return-last-stmt-semi.rs: New test. * rust/rustc/ui/liveness/liveness-unused.rs: New test. * rust/rustc/ui/liveness/liveness-upvars.rs: New test. * rust/rustc/ui/liveness/liveness-use-after-move.rs: New test. * rust/rustc/ui/liveness/liveness-use-after-send.rs: New test. * rust/rustc/ui/llvm-asm/issue-51431.rs: New test. * rust/rustc/ui/llvm-asm/issue-54067.rs: New test. * rust/rustc/ui/llvm-asm/issue-62046.rs: New test. * rust/rustc/ui/llvm-asm/issue-69092.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-bad-clobber.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-concat-src.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-in-bad-modifier.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-in-moved.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-in-out-operand.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-indirect-memory.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-literal-escaping.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-misplaced-option.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-out-assign-imm.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-out-assign.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-out-no-modifier.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-out-read-uninit.rs: New test. * rust/rustc/ui/llvm-asm/llvm-asm-parse-errors.rs: New test. * rust/rustc/ui/llvm-pr32379.rs: New test. * rust/rustc/ui/log-err-phi.rs: New test. * rust/rustc/ui/log-knows-the-names-of-variants-in-std.rs: New test. * rust/rustc/ui/log-knows-the-names-of-variants.rs: New test. * rust/rustc/ui/log-poly.rs: New test. * rust/rustc/ui/logging-only-prints-once.rs: New test. * rust/rustc/ui/long-while.rs: New test. * rust/rustc/ui/loops/for-each-loop-panic.rs: New test. * rust/rustc/ui/loops/loop-break-unsize.rs: New test. * rust/rustc/ui/loops/loop-break-value-no-repeat.rs: New test. * rust/rustc/ui/loops/loop-break-value.rs: New test. * rust/rustc/ui/loops/loop-labeled-break-value.rs: New test. * rust/rustc/ui/loops/loop-proper-liveness.rs: New test. * rust/rustc/ui/loops/loop-properly-diverging-2.rs: New test. * rust/rustc/ui/loops/loops-reject-duplicate-labels-2.rs: New test. * rust/rustc/ui/loops/loops-reject-duplicate-labels.rs: New test. * rust/rustc/ui/loops/loops-reject-labels-shadowing-lifetimes.rs: New test. * rust/rustc/ui/loops/loops-reject-lifetime-shadowing-label.rs: New test. * rust/rustc/ui/loud_ui.rs: New test. * rust/rustc/ui/lto-and-no-bitcode-in-rlib.rs: New test. * rust/rustc/ui/lto-duplicate-symbols.rs: New test. * rust/rustc/ui/lto-many-codegen-units.rs: New test. * rust/rustc/ui/lto-opt-level-s.rs: New test. * rust/rustc/ui/lto-opt-level-z.rs: New test. * rust/rustc/ui/lto-rustc-loads-linker-plugin.rs: New test. * rust/rustc/ui/lto-still-runs-thread-dtors.rs: New test. * rust/rustc/ui/lto-thin-rustc-loads-linker-plugin.rs: New test. * rust/rustc/ui/lub-glb-with-unbound-infer-var.rs: New test. * rust/rustc/ui/lub-glb/old-lub-glb-hr-eq.rs: New test. * rust/rustc/ui/lub-glb/old-lub-glb-hr-noteq1.rs: New test. * rust/rustc/ui/lub-glb/old-lub-glb-hr-noteq2.rs: New test. * rust/rustc/ui/lub-glb/old-lub-glb-object.rs: New test. * rust/rustc/ui/lub-if.rs: New test. * rust/rustc/ui/lub-match.rs: New test. * rust/rustc/ui/macro-quote-cond.rs: New test. * rust/rustc/ui/macro-quote-test.rs: New test. * rust/rustc/ui/macro_backtrace/auxiliary/ping.rs: New test. * rust/rustc/ui/macro_backtrace/main.rs: New test. * rust/rustc/ui/macros/ambiguity-legacy-vs-modern.rs: New test. * rust/rustc/ui/macros/assert-as-macro.rs: New test. * rust/rustc/ui/macros/assert-eq-macro-panic.rs: New test. * rust/rustc/ui/macros/assert-eq-macro-success.rs: New test. * rust/rustc/ui/macros/assert-eq-macro-unsized.rs: New test. * rust/rustc/ui/macros/assert-macro-explicit.rs: New test. * rust/rustc/ui/macros/assert-macro-fmt.rs: New test. * rust/rustc/ui/macros/assert-macro-owned.rs: New test. * rust/rustc/ui/macros/assert-macro-static.rs: New test. * rust/rustc/ui/macros/assert-ne-macro-panic.rs: New test. * rust/rustc/ui/macros/assert-ne-macro-success.rs: New test. * rust/rustc/ui/macros/assert-ne-macro-unsized.rs: New test. * rust/rustc/ui/macros/assert-trailing-junk.rs: New test. * rust/rustc/ui/macros/assert.rs: New test. * rust/rustc/ui/macros/auxiliary/deprecated-macros.rs: New test. * rust/rustc/ui/macros/auxiliary/dollar-crate-nested-encoding.rs: New test. * rust/rustc/ui/macros/auxiliary/issue-75982.rs: New test. * rust/rustc/ui/macros/auxiliary/macro-comma-support.rs: New test. * rust/rustc/ui/macros/auxiliary/macro-in-other-crate.rs: New test. * rust/rustc/ui/macros/auxiliary/macro-include-items-expr.rs: New test. * rust/rustc/ui/macros/auxiliary/macro-include-items-item.rs: New test. * rust/rustc/ui/macros/auxiliary/macro_crate_def_only.rs: New test. * rust/rustc/ui/macros/auxiliary/macro_crate_nonterminal.rs: New test. * rust/rustc/ui/macros/auxiliary/macro_export_inner_module.rs: New test. * rust/rustc/ui/macros/auxiliary/macro_with_super_1.rs: New test. * rust/rustc/ui/macros/auxiliary/proc_macro_sequence.rs: New test. * rust/rustc/ui/macros/auxiliary/two_macros-rpass.rs: New test. * rust/rustc/ui/macros/auxiliary/two_macros.rs: New test. * rust/rustc/ui/macros/auxiliary/unstable-macros.rs: New test. * rust/rustc/ui/macros/auxiliary/use-macro-self.rs: New test. * rust/rustc/ui/macros/bad-concat.rs: New test. * rust/rustc/ui/macros/bad_hello.rs: New test. * rust/rustc/ui/macros/builtin-prelude-no-accidents.rs: New test. * rust/rustc/ui/macros/builtin-std-paths-fail.rs: New test. * rust/rustc/ui/macros/builtin-std-paths.rs: New test. * rust/rustc/ui/macros/cfg.rs: New test. * rust/rustc/ui/macros/colorful-write-macros.rs: New test. * rust/rustc/ui/macros/conditional-debug-macro-on.rs: New test. * rust/rustc/ui/macros/derive-in-eager-expansion-hang.rs: New test. * rust/rustc/ui/macros/die-macro-2.rs: New test. * rust/rustc/ui/macros/die-macro-expr.rs: New test. * rust/rustc/ui/macros/die-macro-pure.rs: New test. * rust/rustc/ui/macros/die-macro.rs: New test. * rust/rustc/ui/macros/doc-comment.rs: New test. * rust/rustc/ui/macros/dollar-crate-nested-encoding.rs: New test. * rust/rustc/ui/macros/duplicate-builtin.rs: New test. * rust/rustc/ui/macros/empty-trailing-stmt.rs: New test. * rust/rustc/ui/macros/format-foreign.rs: New test. * rust/rustc/ui/macros/format-parse-errors.rs: New test. * rust/rustc/ui/macros/format-unused-lables.rs: New test. * rust/rustc/ui/macros/global-asm.rs: New test. * rust/rustc/ui/macros/issue-25274.rs: New test. * rust/rustc/ui/macros/issue-30143.rs: New test. * rust/rustc/ui/macros/issue-34421-mac-expr-bad-stmt-good-add-semi.rs: New test. * rust/rustc/ui/macros/issue-39404.rs: New test. * rust/rustc/ui/macros/issue-54441.rs: New test. * rust/rustc/ui/macros/issue-58490.rs: New test. * rust/rustc/ui/macros/issue-61033-1.rs: New test. * rust/rustc/ui/macros/issue-61033-2.rs: New test. * rust/rustc/ui/macros/issue-61053-different-kleene.rs: New test. * rust/rustc/ui/macros/issue-61053-duplicate-binder.rs: New test. * rust/rustc/ui/macros/issue-61053-missing-repetition.rs: New test. * rust/rustc/ui/macros/issue-61053-unbound.rs: New test. * rust/rustc/ui/macros/issue-63102.rs: New test. * rust/rustc/ui/macros/issue-68058.rs: New test. * rust/rustc/ui/macros/issue-68060.rs: New test. * rust/rustc/ui/macros/issue-69838-dir/bar.rs: New test. * rust/rustc/ui/macros/issue-69838-dir/included.rs: New test. * rust/rustc/ui/macros/issue-69838-mods-relative-to-included-path.rs: New test. * rust/rustc/ui/macros/issue-70446.rs: New test. * rust/rustc/ui/macros/issue-75982-foreign-macro-weird-mod.rs: New test. * rust/rustc/ui/macros/issue-77475.rs: New test. * rust/rustc/ui/macros/issue-78325-inconsistent-resolution.rs: New test. * rust/rustc/ui/macros/issue-78892-substitution-in-statement-attr.rs: New test. * rust/rustc/ui/macros/local-ambiguity-multiple-parsing-options.rs: New test. * rust/rustc/ui/macros/log_syntax-trace_macros-macro-locations.rs: New test. * rust/rustc/ui/macros/macro-2.rs: New test. * rust/rustc/ui/macros/macro-as-fn-body.rs: New test. * rust/rustc/ui/macros/macro-at-most-once-rep-2015-rpass.rs: New test. * rust/rustc/ui/macros/macro-at-most-once-rep-2015.rs: New test. * rust/rustc/ui/macros/macro-at-most-once-rep-2018-rpass.rs: New test. * rust/rustc/ui/macros/macro-at-most-once-rep-2018.rs: New test. * rust/rustc/ui/macros/macro-attribute-expansion.rs: New test. * rust/rustc/ui/macros/macro-attribute.rs: New test. * rust/rustc/ui/macros/macro-attributes.rs: New test. * rust/rustc/ui/macros/macro-backtrace-invalid-internals.rs: New test. * rust/rustc/ui/macros/macro-backtrace-nested.rs: New test. * rust/rustc/ui/macros/macro-backtrace-println.rs: New test. * rust/rustc/ui/macros/macro-block-nonterminal.rs: New test. * rust/rustc/ui/macros/macro-comma-behavior-rpass.rs: New test. * rust/rustc/ui/macros/macro-comma-behavior.rs: New test. * rust/rustc/ui/macros/macro-comma-support-rpass.rs: New test. * rust/rustc/ui/macros/macro-comma-support.rs: New test. * rust/rustc/ui/macros/macro-context.rs: New test. * rust/rustc/ui/macros/macro-crate-def-only.rs: New test. * rust/rustc/ui/macros/macro-crate-nonterminal-non-root.rs: New test. * rust/rustc/ui/macros/macro-crate-nonterminal-renamed.rs: New test. * rust/rustc/ui/macros/macro-crate-nonterminal.rs: New test. * rust/rustc/ui/macros/macro-crate-use.rs: New test. * rust/rustc/ui/macros/macro-deep_expansion.rs: New test. * rust/rustc/ui/macros/macro-delimiter-significance.rs: New test. * rust/rustc/ui/macros/macro-deprecation.rs: New test. * rust/rustc/ui/macros/macro-doc-comments.rs: New test. * rust/rustc/ui/macros/macro-doc-escapes.rs: New test. * rust/rustc/ui/macros/macro-doc-raw-str-hashes.rs: New test. * rust/rustc/ui/macros/macro-error.rs: New test. * rust/rustc/ui/macros/macro-expanded-include/foo/mod.rs: New test. * rust/rustc/ui/macros/macro-expanded-include/test.rs: New test. * rust/rustc/ui/macros/macro-expansion-tests.rs: New test. * rust/rustc/ui/macros/macro-export-inner-module.rs: New test. * rust/rustc/ui/macros/macro-first-set.rs: New test. * rust/rustc/ui/macros/macro-follow-rpass.rs: New test. * rust/rustc/ui/macros/macro-follow.rs: New test. * rust/rustc/ui/macros/macro-followed-by-seq-bad.rs: New test. * rust/rustc/ui/macros/macro-followed-by-seq.rs: New test. * rust/rustc/ui/macros/macro-in-expression-context-2.rs: New test. * rust/rustc/ui/macros/macro-in-expression-context.rs: New test. * rust/rustc/ui/macros/macro-in-fn.rs: New test. * rust/rustc/ui/macros/macro-include-items.rs: New test. * rust/rustc/ui/macros/macro-inner-attributes.rs: New test. * rust/rustc/ui/macros/macro-input-future-proofing.rs: New test. * rust/rustc/ui/macros/macro-interpolation.rs: New test. * rust/rustc/ui/macros/macro-invalid-fragment-spec.rs: New test. * rust/rustc/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs: New test. * rust/rustc/ui/macros/macro-lifetime-used-with-bound.rs: New test. * rust/rustc/ui/macros/macro-lifetime-used-with-labels.rs: New test. * rust/rustc/ui/macros/macro-lifetime-used-with-static.rs: New test. * rust/rustc/ui/macros/macro-lifetime.rs: New test. * rust/rustc/ui/macros/macro-literal.rs: New test. * rust/rustc/ui/macros/macro-local-data-key-priv.rs: New test. * rust/rustc/ui/macros/macro-match-nonterminal.rs: New test. * rust/rustc/ui/macros/macro-meta-items-modern.rs: New test. * rust/rustc/ui/macros/macro-meta-items.rs: New test. * rust/rustc/ui/macros/macro-method-issue-4621.rs: New test. * rust/rustc/ui/macros/macro-missing-delimiters.rs: New test. * rust/rustc/ui/macros/macro-missing-fragment.rs: New test. * rust/rustc/ui/macros/macro-multiple-items.rs: New test. * rust/rustc/ui/macros/macro-multiple-matcher-bindings.rs: New test. * rust/rustc/ui/macros/macro-name-typo.rs: New test. * rust/rustc/ui/macros/macro-named-default.rs: New test. * rust/rustc/ui/macros/macro-nested_definition_issue-31946.rs: New test. * rust/rustc/ui/macros/macro-nested_expr.rs: New test. * rust/rustc/ui/macros/macro-nested_stmt_macros.rs: New test. * rust/rustc/ui/macros/macro-non-lifetime.rs: New test. * rust/rustc/ui/macros/macro-nt-list.rs: New test. * rust/rustc/ui/macros/macro-of-higher-order.rs: New test. * rust/rustc/ui/macros/macro-outer-attributes.rs: New test. * rust/rustc/ui/macros/macro-parameter-span.rs: New test. * rust/rustc/ui/macros/macro-pat-follow.rs: New test. * rust/rustc/ui/macros/macro-pat-neg-lit.rs: New test. * rust/rustc/ui/macros/macro-pat.rs: New test. * rust/rustc/ui/macros/macro-path-prelude-fail-1.rs: New test. * rust/rustc/ui/macros/macro-path-prelude-fail-2.rs: New test. * rust/rustc/ui/macros/macro-path-prelude-fail-3.rs: New test. * rust/rustc/ui/macros/macro-path-prelude-fail-4.rs: New test. * rust/rustc/ui/macros/macro-path-prelude-pass.rs: New test. * rust/rustc/ui/macros/macro-path-prelude-shadowing.rs: New test. * rust/rustc/ui/macros/macro-path.rs: New test. * rust/rustc/ui/macros/macro-pub-matcher.rs: New test. * rust/rustc/ui/macros/macro-reexport-removed.rs: New test. * rust/rustc/ui/macros/macro-seq-followed-by-seq.rs: New test. * rust/rustc/ui/macros/macro-shadowing-relaxed.rs: New test. * rust/rustc/ui/macros/macro-shadowing.rs: New test. * rust/rustc/ui/macros/macro-stability-rpass.rs: New test. * rust/rustc/ui/macros/macro-stability.rs: New test. * rust/rustc/ui/macros/macro-stmt-matchers.rs: New test. * rust/rustc/ui/macros/macro-stmt.rs: New test. * rust/rustc/ui/macros/macro-stmt_macro_in_expr_macro.rs: New test. * rust/rustc/ui/macros/macro-tt-followed-by-seq.rs: New test. * rust/rustc/ui/macros/macro-tt-matchers.rs: New test. * rust/rustc/ui/macros/macro-use-all-and-none.rs: New test. * rust/rustc/ui/macros/macro-use-all.rs: New test. * rust/rustc/ui/macros/macro-use-bad-args-1.rs: New test. * rust/rustc/ui/macros/macro-use-bad-args-2.rs: New test. * rust/rustc/ui/macros/macro-use-both.rs: New test. * rust/rustc/ui/macros/macro-use-one.rs: New test. * rust/rustc/ui/macros/macro-use-scope.rs: New test. * rust/rustc/ui/macros/macro-use-undef.rs: New test. * rust/rustc/ui/macros/macro-use-wrong-name.rs: New test. * rust/rustc/ui/macros/macro-with-attrs1.rs: New test. * rust/rustc/ui/macros/macro-with-attrs2.rs: New test. * rust/rustc/ui/macros/macro-with-braces-in-expr-position.rs: New test. * rust/rustc/ui/macros/macro_path_as_generic_bound.rs: New test. * rust/rustc/ui/macros/macro_undefined.rs: New test. * rust/rustc/ui/macros/macro_with_super_2.rs: New test. * rust/rustc/ui/macros/macros-in-extern.rs: New test. * rust/rustc/ui/macros/macros-nonfatal-errors.rs: New test. * rust/rustc/ui/macros/meta-item-absolute-path.rs: New test. * rust/rustc/ui/macros/meta-variable-misuse.rs: New test. * rust/rustc/ui/macros/missing-comma.rs: New test. * rust/rustc/ui/macros/must-use-in-macro-55516.rs: New test. * rust/rustc/ui/macros/nonterminal-matching.rs: New test. * rust/rustc/ui/macros/parse-complex-macro-invoc-op.rs: New test. * rust/rustc/ui/macros/paths-in-macro-invocations.rs: New test. * rust/rustc/ui/macros/pub-item-inside-macro.rs: New test. * rust/rustc/ui/macros/pub-method-inside-macro.rs: New test. * rust/rustc/ui/macros/restricted-shadowing-legacy.rs: New test. * rust/rustc/ui/macros/restricted-shadowing-modern.rs: New test. * rust/rustc/ui/macros/same-sequence-span.rs: New test. * rust/rustc/ui/macros/semi-after-macro-ty.rs: New test. * rust/rustc/ui/macros/span-covering-argument-1.rs: New test. * rust/rustc/ui/macros/stmt_expr_attr_macro_parse.rs: New test. * rust/rustc/ui/macros/syntax-extension-cfg.rs: New test. * rust/rustc/ui/macros/syntax-extension-source-utils.rs: New test. * rust/rustc/ui/macros/trace-macro.rs: New test. * rust/rustc/ui/macros/trace_faulty_macros.rs: New test. * rust/rustc/ui/macros/try-macro.rs: New test. * rust/rustc/ui/macros/two-macro-use.rs: New test. * rust/rustc/ui/macros/type-macros-hlist.rs: New test. * rust/rustc/ui/macros/type-macros-simple.rs: New test. * rust/rustc/ui/macros/typeck-macro-interaction-issue-8852.rs: New test. * rust/rustc/ui/macros/unimplemented-macro-panic.rs: New test. * rust/rustc/ui/macros/unknown-builtin.rs: New test. * rust/rustc/ui/macros/unreachable-fmt-msg.rs: New test. * rust/rustc/ui/macros/unreachable-macro-panic.rs: New test. * rust/rustc/ui/macros/unreachable-static-msg.rs: New test. * rust/rustc/ui/macros/unreachable.rs: New test. * rust/rustc/ui/macros/use-macro-self.rs: New test. * rust/rustc/ui/main-wrong-location.rs: New test. * rust/rustc/ui/main-wrong-type.rs: New test. * rust/rustc/ui/malformed/issue-69341-malformed-derive-inert.rs: New test. * rust/rustc/ui/malformed/malformed-derive-entry.rs: New test. * rust/rustc/ui/malformed/malformed-interpolated.rs: New test. * rust/rustc/ui/malformed/malformed-meta-delim.rs: New test. * rust/rustc/ui/malformed/malformed-plugin-1.rs: New test. * rust/rustc/ui/malformed/malformed-plugin-2.rs: New test. * rust/rustc/ui/malformed/malformed-plugin-3.rs: New test. * rust/rustc/ui/malformed/malformed-regressions.rs: New test. * rust/rustc/ui/malformed/malformed-special-attrs.rs: New test. * rust/rustc/ui/malformed/malformed-unwind-1.rs: New test. * rust/rustc/ui/malformed/malformed-unwind-2.rs: New test. * rust/rustc/ui/malformed_macro_lhs.rs: New test. * rust/rustc/ui/manual/manual-link-bad-form.rs: New test. * rust/rustc/ui/manual/manual-link-bad-kind.rs: New test. * rust/rustc/ui/manual/manual-link-bad-search-path.rs: New test. * rust/rustc/ui/manual/manual-link-framework.rs: New test. * rust/rustc/ui/map-types.rs: New test. * rust/rustc/ui/marker_trait_attr/issue-61651-type-mismatch.rs: New test. * rust/rustc/ui/marker_trait_attr/marker-attribute-on-non-trait.rs: New test. * rust/rustc/ui/marker_trait_attr/marker-attribute-with-values.rs: New test. * rust/rustc/ui/marker_trait_attr/marker-trait-with-associated-items.rs: New test. * rust/rustc/ui/marker_trait_attr/overlap-marker-trait.rs: New test. * rust/rustc/ui/marker_trait_attr/override-item-on-marker-trait.rs: New test. * rust/rustc/ui/match-on-negative-integer-ranges.rs: New test. * rust/rustc/ui/match/const_non_normal_zst_ref_pattern.rs: New test. * rust/rustc/ui/match/expr-match-panic-fn.rs: New test. * rust/rustc/ui/match/expr-match-panic.rs: New test. * rust/rustc/ui/match/issue-50900.rs: New test. * rust/rustc/ui/match/issue-70972-dyn-trait.rs: New test. * rust/rustc/ui/match/issue-72896.rs: New test. * rust/rustc/ui/match/issue-74050-end-span.rs: New test. * rust/rustc/ui/match/match-arm-resolving-to-never.rs: New test. * rust/rustc/ui/match/match-bot-panic.rs: New test. * rust/rustc/ui/match/match-disc-bot.rs: New test. * rust/rustc/ui/match/match-fn-call.rs: New test. * rust/rustc/ui/match/match-ill-type2.rs: New test. * rust/rustc/ui/match/match-incompat-type-semi.rs: New test. * rust/rustc/ui/match/match-join.rs: New test. * rust/rustc/ui/match/match-no-arms-unreachable-after.rs: New test. * rust/rustc/ui/match/match-pattern-field-mismatch-2.rs: New test. * rust/rustc/ui/match/match-pattern-field-mismatch.rs: New test. * rust/rustc/ui/match/match-range-fail-2.rs: New test. * rust/rustc/ui/match/match-range-fail.rs: New test. * rust/rustc/ui/match/match-ref-mut-invariance.rs: New test. * rust/rustc/ui/match/match-ref-mut-let-invariance.rs: New test. * rust/rustc/ui/match/match-ref-mut-stability.rs: New test. * rust/rustc/ui/match/match-struct.rs: New test. * rust/rustc/ui/match/match-tag-nullary.rs: New test. * rust/rustc/ui/match/match-tag-unary.rs: New test. * rust/rustc/ui/match/match-type-err-first-arm.rs: New test. * rust/rustc/ui/match/match-unresolved-one-arm.rs: New test. * rust/rustc/ui/match/match-vec-mismatch-2.rs: New test. * rust/rustc/ui/match/match-wildcards.rs: New test. * rust/rustc/ui/match/pattern-deref-miscompile.rs: New test. * rust/rustc/ui/match/type_polymorphic_byte_str_literals.rs: New test. * rust/rustc/ui/max-min-classes.rs: New test. * rust/rustc/ui/maybe-bounds-where-cpass.rs: New test. * rust/rustc/ui/maybe-bounds-where.rs: New test. * rust/rustc/ui/maybe-bounds.rs: New test. * rust/rustc/ui/meta/auxiliary/env.rs: New test. * rust/rustc/ui/meta/expected-error-correct-rev.rs: New test. * rust/rustc/ui/meta/revision-bad.rs: New test. * rust/rustc/ui/meta/revision-ok.rs: New test. * rust/rustc/ui/meta/rustc-env.rs: New test. * rust/rustc/ui/methods/assign-to-method.rs: New test. * rust/rustc/ui/methods/auxiliary/ambig_impl_2_lib.rs: New test. * rust/rustc/ui/methods/auxiliary/macro-in-other-crate.rs: New test. * rust/rustc/ui/methods/auxiliary/method_self_arg1.rs: New test. * rust/rustc/ui/methods/auxiliary/method_self_arg2.rs: New test. * rust/rustc/ui/methods/method-ambig-one-trait-unknown-int-type.rs: New test. * rust/rustc/ui/methods/method-ambig-two-traits-cross-crate.rs: New test. * rust/rustc/ui/methods/method-ambig-two-traits-from-bounds.rs: New test. * rust/rustc/ui/methods/method-ambig-two-traits-from-impls.rs: New test. * rust/rustc/ui/methods/method-ambig-two-traits-from-impls2.rs: New test. * rust/rustc/ui/methods/method-ambig-two-traits-with-default-method.rs: New test. * rust/rustc/ui/methods/method-argument-inference-associated-type.rs: New test. * rust/rustc/ui/methods/method-call-err-msg.rs: New test. * rust/rustc/ui/methods/method-call-lifetime-args-fail.rs: New test. * rust/rustc/ui/methods/method-call-lifetime-args-lint-fail.rs: New test. * rust/rustc/ui/methods/method-call-lifetime-args-lint.rs: New test. * rust/rustc/ui/methods/method-call-lifetime-args-subst-index.rs: New test. * rust/rustc/ui/methods/method-call-lifetime-args-unresolved.rs: New test. * rust/rustc/ui/methods/method-call-lifetime-args.rs: New test. * rust/rustc/ui/methods/method-call-type-binding.rs: New test. * rust/rustc/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs: New test. * rust/rustc/ui/methods/method-early-bound-lifetimes-on-self.rs: New test. * rust/rustc/ui/methods/method-macro-backtrace.rs: New test. * rust/rustc/ui/methods/method-missing-call.rs: New test. * rust/rustc/ui/methods/method-mut-self-modifies-mut-slice-lvalue.rs: New test. * rust/rustc/ui/methods/method-normalize-bounds-issue-20604.rs: New test. * rust/rustc/ui/methods/method-on-ambiguous-numeric-type.rs: New test. * rust/rustc/ui/methods/method-path-in-pattern.rs: New test. * rust/rustc/ui/methods/method-probe-no-guessing-dyn-trait.rs: New test. * rust/rustc/ui/methods/method-projection.rs: New test. * rust/rustc/ui/methods/method-recursive-blanket-impl.rs: New test. * rust/rustc/ui/methods/method-resolvable-path-in-pattern.rs: New test. * rust/rustc/ui/methods/method-self-arg-1.rs: New test. * rust/rustc/ui/methods/method-self-arg-2.rs: New test. * rust/rustc/ui/methods/method-self-arg-aux1.rs: New test. * rust/rustc/ui/methods/method-self-arg-aux2.rs: New test. * rust/rustc/ui/methods/method-self-arg-trait.rs: New test. * rust/rustc/ui/methods/method-self-arg.rs: New test. * rust/rustc/ui/methods/method-trait-object-with-hrtb.rs: New test. * rust/rustc/ui/methods/method-two-trait-defer-resolution-1.rs: New test. * rust/rustc/ui/methods/method-two-trait-defer-resolution-2.rs: New test. * rust/rustc/ui/methods/method-two-traits-distinguished-via-where-clause.rs: New test. * rust/rustc/ui/methods/method-where-clause.rs: New test. * rust/rustc/ui/mid-path-type-params.rs: New test. * rust/rustc/ui/minmax-stability-issue-23687.rs: New test. * rust/rustc/ui/minus-string.rs: New test. * rust/rustc/ui/mir-dataflow/def-inits-1.rs: New test. * rust/rustc/ui/mir-dataflow/indirect-mutation-offset.rs: New test. * rust/rustc/ui/mir-dataflow/inits-1.rs: New test. * rust/rustc/ui/mir-dataflow/liveness-projection.rs: New test. * rust/rustc/ui/mir-dataflow/liveness-ptr.rs: New test. * rust/rustc/ui/mir-dataflow/uninits-1.rs: New test. * rust/rustc/ui/mir-dataflow/uninits-2.rs: New test. * rust/rustc/ui/mir-unpretty.rs: New test. * rust/rustc/ui/mir/auxiliary/issue_76375_aux.rs: New test. * rust/rustc/ui/mir/auxiliary/mir_external_refs.rs: New test. * rust/rustc/ui/mir/issue-60390.rs: New test. * rust/rustc/ui/mir/issue-66930.rs: New test. * rust/rustc/ui/mir/issue-67639-normalization-ice.rs: New test. * rust/rustc/ui/mir/issue-67710-inline-projection.rs: New test. * rust/rustc/ui/mir/issue-67947.rs: New test. * rust/rustc/ui/mir/issue-68841.rs: New test. * rust/rustc/ui/mir/issue-71793-inline-args-storage.rs: New test. * rust/rustc/ui/mir/issue-75053.rs: New test. * rust/rustc/ui/mir/issue-75419-validation-impl-trait.rs: New test. * rust/rustc/ui/mir/issue-76248.rs: New test. * rust/rustc/ui/mir/issue-76375.rs: New test. * rust/rustc/ui/mir/issue-76740-copy-propagation.rs: New test. * rust/rustc/ui/mir/issue-76803-branches-not-same.rs: New test. * rust/rustc/ui/mir/issue-77359-simplify-arm-identity.rs: New test. * rust/rustc/ui/mir/issue-77911.rs: New test. * rust/rustc/ui/mir/issue66339.rs: New test. * rust/rustc/ui/mir/mir-inlining/ice-issue-45493.rs: New test. * rust/rustc/ui/mir/mir-inlining/ice-issue-45885.rs: New test. * rust/rustc/ui/mir/mir-inlining/ice-issue-68347.rs: New test. * rust/rustc/ui/mir/mir-inlining/ice-issue-77306-1.rs: New test. * rust/rustc/ui/mir/mir-inlining/ice-issue-77306-2.rs: New test. * rust/rustc/ui/mir/mir-inlining/ice-issue-77564.rs: New test. * rust/rustc/ui/mir/mir-inlining/no-trait-method-issue-40473.rs: New test. * rust/rustc/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs: New test. * rust/rustc/ui/mir/mir-typeck-normalize-fn-sig.rs: New test. * rust/rustc/ui/mir/mir_adt_construction.rs: New test. * rust/rustc/ui/mir/mir_ascription_coercion.rs: New test. * rust/rustc/ui/mir/mir_assign_eval_order.rs: New test. * rust/rustc/ui/mir/mir_augmented_assignments.rs: New test. * rust/rustc/ui/mir/mir_autoderef.rs: New test. * rust/rustc/ui/mir/mir_boxing.rs: New test. * rust/rustc/ui/mir/mir_build_match_comparisons.rs: New test. * rust/rustc/ui/mir/mir_call_with_associated_type.rs: New test. * rust/rustc/ui/mir/mir_calls_to_shims.rs: New test. * rust/rustc/ui/mir/mir_cast_fn_ret.rs: New test. * rust/rustc/ui/mir/mir_codegen_array.rs: New test. * rust/rustc/ui/mir/mir_codegen_array_2.rs: New test. * rust/rustc/ui/mir/mir_codegen_call_converging.rs: New test. * rust/rustc/ui/mir/mir_codegen_calls.rs: New test. * rust/rustc/ui/mir/mir_codegen_calls_converging_drops.rs: New test. * rust/rustc/ui/mir/mir_codegen_calls_converging_drops_2.rs: New test. * rust/rustc/ui/mir/mir_codegen_calls_diverging.rs: New test. * rust/rustc/ui/mir/mir_codegen_calls_diverging_drops.rs: New test. * rust/rustc/ui/mir/mir_codegen_critical_edge.rs: New test. * rust/rustc/ui/mir/mir_codegen_spike1.rs: New test. * rust/rustc/ui/mir/mir_codegen_switch.rs: New test. * rust/rustc/ui/mir/mir_codegen_switchint.rs: New test. * rust/rustc/ui/mir/mir_coercion_casts.rs: New test. * rust/rustc/ui/mir/mir_coercions.rs: New test. * rust/rustc/ui/mir/mir_const_prop_tuple_field_reorder.rs: New test. * rust/rustc/ui/mir/mir_constval_adts.rs: New test. * rust/rustc/ui/mir/mir_detects_invalid_ops.rs: New test. * rust/rustc/ui/mir/mir_drop_order.rs: New test. * rust/rustc/ui/mir/mir_drop_panics.rs: New test. * rust/rustc/ui/mir/mir_dynamic_drops_1.rs: New test. * rust/rustc/ui/mir/mir_dynamic_drops_2.rs: New test. * rust/rustc/ui/mir/mir_dynamic_drops_3.rs: New test. * rust/rustc/ui/mir/mir_early_return_scope.rs: New test. * rust/rustc/ui/mir/mir_fat_ptr.rs: New test. * rust/rustc/ui/mir/mir_fat_ptr_drop.rs: New test. * rust/rustc/ui/mir/mir_heavy_promoted.rs: New test. * rust/rustc/ui/mir/mir_indexing_oob_1.rs: New test. * rust/rustc/ui/mir/mir_indexing_oob_2.rs: New test. * rust/rustc/ui/mir/mir_indexing_oob_3.rs: New test. * rust/rustc/ui/mir/mir_match_arm_guard.rs: New test. * rust/rustc/ui/mir/mir_match_test.rs: New test. * rust/rustc/ui/mir/mir_misc_casts.rs: New test. * rust/rustc/ui/mir/mir_overflow_off.rs: New test. * rust/rustc/ui/mir/mir_raw_fat_ptr.rs: New test. * rust/rustc/ui/mir/mir_refs_correct.rs: New test. * rust/rustc/ui/mir/mir_small_agg_arg.rs: New test. * rust/rustc/ui/mir/mir_static_subtype.rs: New test. * rust/rustc/ui/mir/mir_struct_with_assoc_ty.rs: New test. * rust/rustc/ui/mir/mir_temp_promotions.rs: New test. * rust/rustc/ui/mir/mir_void_return.rs: New test. * rust/rustc/ui/mir/mir_void_return_2.rs: New test. * rust/rustc/ui/mir/simplify-branch-same.rs: New test. * rust/rustc/ui/mir_check_nonconst.rs: New test. * rust/rustc/ui/mismatched_types/E0053.rs: New test. * rust/rustc/ui/mismatched_types/E0409.rs: New test. * rust/rustc/ui/mismatched_types/E0631.rs: New test. * rust/rustc/ui/mismatched_types/abridged.rs: New test. * rust/rustc/ui/mismatched_types/binops.rs: New test. * rust/rustc/ui/mismatched_types/cast-rfc0401.rs: New test. * rust/rustc/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.rs: New test. * rust/rustc/ui/mismatched_types/closure-arg-count.rs: New test. * rust/rustc/ui/mismatched_types/closure-arg-type-mismatch.rs: New test. * rust/rustc/ui/mismatched_types/closure-mismatch.rs: New test. * rust/rustc/ui/mismatched_types/const-fn-in-trait.rs: New test. * rust/rustc/ui/mismatched_types/fn-variance-1.rs: New test. * rust/rustc/ui/mismatched_types/for-loop-has-unit-body.rs: New test. * rust/rustc/ui/mismatched_types/issue-19109.rs: New test. * rust/rustc/ui/mismatched_types/issue-26480.rs: New test. * rust/rustc/ui/mismatched_types/issue-35030.rs: New test. * rust/rustc/ui/mismatched_types/issue-36053-2.rs: New test. * rust/rustc/ui/mismatched_types/issue-38371.rs: New test. * rust/rustc/ui/mismatched_types/issue-74918-missing-lifetime.rs: New test. * rust/rustc/ui/mismatched_types/issue-75361-mismatched-impl.rs: New test. * rust/rustc/ui/mismatched_types/main.rs: New test. * rust/rustc/ui/mismatched_types/method-help-unsatisfied-bound.rs: New test. * rust/rustc/ui/mismatched_types/numeric-literal-cast.rs: New test. * rust/rustc/ui/mismatched_types/overloaded-calls-bad.rs: New test. * rust/rustc/ui/mismatched_types/recovered-block.rs: New test. * rust/rustc/ui/mismatched_types/trait-bounds-cant-coerce.rs: New test. * rust/rustc/ui/mismatched_types/trait-impl-fn-incompatibility.rs: New test. * rust/rustc/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs: New test. * rust/rustc/ui/missing/auxiliary/two_macros.rs: New test. * rust/rustc/ui/missing/missing-alloc_error_handler.rs: New test. * rust/rustc/ui/missing/missing-allocator.rs: New test. * rust/rustc/ui/missing/missing-block-hint.rs: New test. * rust/rustc/ui/missing/missing-comma-in-match.rs: New test. * rust/rustc/ui/missing/missing-derivable-attr.rs: New test. * rust/rustc/ui/missing/missing-fields-in-struct-pattern.rs: New test. * rust/rustc/ui/missing/missing-items/auxiliary/m1.rs: New test. * rust/rustc/ui/missing/missing-items/issue-40221.rs: New test. * rust/rustc/ui/missing/missing-items/m2.rs: New test. * rust/rustc/ui/missing/missing-items/missing-type-parameter.rs: New test. * rust/rustc/ui/missing/missing-macro-use.rs: New test. * rust/rustc/ui/missing/missing-main.rs: New test. * rust/rustc/ui/missing/missing-return.rs: New test. * rust/rustc/ui/missing/missing-stability.rs: New test. * rust/rustc/ui/missing_debug_impls.rs: New test. * rust/rustc/ui/missing_non_modrs_mod/foo.rs: New test. * rust/rustc/ui/missing_non_modrs_mod/foo_inline.rs: New test. * rust/rustc/ui/missing_non_modrs_mod/missing_non_modrs_mod.rs: New test. * rust/rustc/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.rs: New test. * rust/rustc/ui/mod-subitem-as-enum-variant.rs: New test. * rust/rustc/ui/module-macro_use-arguments.rs: New test. * rust/rustc/ui/modules/auxiliary/two_macros_2.rs: New test. * rust/rustc/ui/modules/mod-inside-fn.rs: New test. * rust/rustc/ui/modules/mod-view-items.rs: New test. * rust/rustc/ui/modules/mod_dir_implicit.rs: New test. * rust/rustc/ui/modules/mod_dir_implicit_aux/mod.rs: New test. * rust/rustc/ui/modules/mod_dir_path.rs: New test. * rust/rustc/ui/modules/mod_dir_path2.rs: New test. * rust/rustc/ui/modules/mod_dir_path3.rs: New test. * rust/rustc/ui/modules/mod_dir_path_multi.rs: New test. * rust/rustc/ui/modules/mod_dir_recursive.rs: New test. * rust/rustc/ui/modules/mod_dir_simple.rs: New test. * rust/rustc/ui/modules/mod_dir_simple/load_another_mod.rs: New test. * rust/rustc/ui/modules/mod_dir_simple/test.rs: New test. * rust/rustc/ui/modules/mod_file.rs: New test. * rust/rustc/ui/modules/mod_file_aux.rs: New test. * rust/rustc/ui/modules/mod_file_with_path_attr.rs: New test. * rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_f32.rs: New test. * rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_f64.rs: New test. * rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_float.rs: New test. * rust/rustc/ui/modules_and_files_visibility/mod_file_aux.rs: New test. * rust/rustc/ui/modules_and_files_visibility/mod_file_correct_spans.rs: New test. * rust/rustc/ui/modules_and_files_visibility/mod_file_disambig.rs: New test. * rust/rustc/ui/modules_and_files_visibility/mod_file_disambig_aux.rs: New test. * rust/rustc/ui/modules_and_files_visibility/mod_file_disambig_aux/mod.rs: New test. * rust/rustc/ui/monad.rs: New test. * rust/rustc/ui/monomorphize-abi-alignment.rs: New test. * rust/rustc/ui/monomorphized-callees-with-ty-params-3314.rs: New test. * rust/rustc/ui/moves/issue-46099-move-in-macro.rs: New test. * rust/rustc/ui/moves/issue-75904-move-closure-loop.rs: New test. * rust/rustc/ui/moves/move-1-unique.rs: New test. * rust/rustc/ui/moves/move-2-unique.rs: New test. * rust/rustc/ui/moves/move-2.rs: New test. * rust/rustc/ui/moves/move-3-unique.rs: New test. * rust/rustc/ui/moves/move-4-unique.rs: New test. * rust/rustc/ui/moves/move-4.rs: New test. * rust/rustc/ui/moves/move-arg-2-unique.rs: New test. * rust/rustc/ui/moves/move-arg-2.rs: New test. * rust/rustc/ui/moves/move-arg.rs: New test. * rust/rustc/ui/moves/move-deref-coercion.rs: New test. * rust/rustc/ui/moves/move-fn-self-receiver.rs: New test. * rust/rustc/ui/moves/move-guard-same-consts.rs: New test. * rust/rustc/ui/moves/move-in-guard-1.rs: New test. * rust/rustc/ui/moves/move-in-guard-2.rs: New test. * rust/rustc/ui/moves/move-into-dead-array-1.rs: New test. * rust/rustc/ui/moves/move-into-dead-array-2.rs: New test. * rust/rustc/ui/moves/move-nullary-fn.rs: New test. * rust/rustc/ui/moves/move-out-of-array-1.rs: New test. * rust/rustc/ui/moves/move-out-of-array-ref.rs: New test. * rust/rustc/ui/moves/move-out-of-field.rs: New test. * rust/rustc/ui/moves/move-out-of-slice-1.rs: New test. * rust/rustc/ui/moves/move-out-of-slice-2.rs: New test. * rust/rustc/ui/moves/move-out-of-tuple-field.rs: New test. * rust/rustc/ui/moves/move-scalar.rs: New test. * rust/rustc/ui/moves/moves-based-on-type-access-to-field.rs: New test. * rust/rustc/ui/moves/moves-based-on-type-block-bad.rs: New test. * rust/rustc/ui/moves/moves-based-on-type-capture-clause-bad.rs: New test. * rust/rustc/ui/moves/moves-based-on-type-capture-clause.rs: New test. * rust/rustc/ui/moves/moves-based-on-type-cyclic-types-issue-4821.rs: New test. * rust/rustc/ui/moves/moves-based-on-type-distribute-copy-over-paren.rs: New test. * rust/rustc/ui/moves/moves-based-on-type-exprs.rs: New test. * rust/rustc/ui/moves/moves-based-on-type-match-bindings.rs: New test. * rust/rustc/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs: New test. * rust/rustc/ui/moves/moves-based-on-type-no-recursive-stack-closure.rs: New test. * rust/rustc/ui/moves/moves-based-on-type-tuple.rs: New test. * rust/rustc/ui/moves/moves-sru-moved-field.rs: New test. * rust/rustc/ui/mpsc_stress.rs: New test. * rust/rustc/ui/msvc-data-only.rs: New test. * rust/rustc/ui/multi-panic.rs: New test. * rust/rustc/ui/multibyte.rs: New test. * rust/rustc/ui/multidispatch-conditional-impl-not-considered.rs: New test. * rust/rustc/ui/multidispatch1.rs: New test. * rust/rustc/ui/multidispatch2.rs: New test. * rust/rustc/ui/multiline-comment.rs: New test. * rust/rustc/ui/multiple-main-2.rs: New test. * rust/rustc/ui/multiple-main-3.rs: New test. * rust/rustc/ui/multiple-plugin-registrars.rs: New test. * rust/rustc/ui/multiple-reprs.rs: New test. * rust/rustc/ui/mut-function-arguments.rs: New test. * rust/rustc/ui/mut-vstore-expr.rs: New test. * rust/rustc/ui/mut/mut-cant-alias.rs: New test. * rust/rustc/ui/mut/mut-cross-borrowing.rs: New test. * rust/rustc/ui/mut/mut-pattern-internal-mutability.rs: New test. * rust/rustc/ui/mut/mut-pattern-mismatched.rs: New test. * rust/rustc/ui/mut/mut-ref.rs: New test. * rust/rustc/ui/mut/mut-suggestion.rs: New test. * rust/rustc/ui/mut/mutable-class-fields-2.rs: New test. * rust/rustc/ui/mut/mutable-class-fields.rs: New test. * rust/rustc/ui/mut/mutable-enum-indirect.rs: New test. * rust/rustc/ui/mut/no-mut-lint-for-desugared-mut.rs: New test. * rust/rustc/ui/mutexguard-sync.rs: New test. * rust/rustc/ui/mutual-recursion-group.rs: New test. * rust/rustc/ui/namespace/auxiliary/namespace-mix.rs: New test. * rust/rustc/ui/namespace/auxiliary/namespaced_enums.rs: New test. * rust/rustc/ui/namespace/namespace-mix.rs: New test. * rust/rustc/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.rs: New test. * rust/rustc/ui/namespace/namespaced-enum-glob-import-no-impls.rs: New test. * rust/rustc/ui/native-print-no-runtime.rs: New test. * rust/rustc/ui/negative.rs: New test. * rust/rustc/ui/nested-block-comment.rs: New test. * rust/rustc/ui/nested-cfg-attrs.rs: New test. * rust/rustc/ui/nested-class.rs: New test. * rust/rustc/ui/nested-function-names-issue-8587.rs: New test. * rust/rustc/ui/nested-ty-params.rs: New test. * rust/rustc/ui/nested_impl_trait.rs: New test. * rust/rustc/ui/nested_item_main.rs: New test. * rust/rustc/ui/never_type/adjust_never.rs: New test. * rust/rustc/ui/never_type/auto-traits.rs: New test. * rust/rustc/ui/never_type/call-fn-never-arg-wrong-type.rs: New test. * rust/rustc/ui/never_type/call-fn-never-arg.rs: New test. * rust/rustc/ui/never_type/cast-never.rs: New test. * rust/rustc/ui/never_type/defaulted-never-note.rs: New test. * rust/rustc/ui/never_type/dispatch_from_dyn_zst.rs: New test. * rust/rustc/ui/never_type/diverging-fallback-control-flow.rs: New test. * rust/rustc/ui/never_type/feature-gate-never_type_fallback.rs: New test. * rust/rustc/ui/never_type/impl-for-never.rs: New test. * rust/rustc/ui/never_type/issue-13352.rs: New test. * rust/rustc/ui/never_type/issue-2149.rs: New test. * rust/rustc/ui/never_type/issue-44402.rs: New test. * rust/rustc/ui/never_type/issue-51506.rs: New test. * rust/rustc/ui/never_type/never-assign-dead-code.rs: New test. * rust/rustc/ui/never_type/never-assign-wrong-type.rs: New test. * rust/rustc/ui/never_type/never-associated-type.rs: New test. * rust/rustc/ui/never_type/never-from-impl-is-reserved.rs: New test. * rust/rustc/ui/never_type/never-result.rs: New test. * rust/rustc/ui/never_type/never-type-arg.rs: New test. * rust/rustc/ui/never_type/never-type-rvalues.rs: New test. * rust/rustc/ui/never_type/never-value-fallback-issue-66757.rs: New test. * rust/rustc/ui/never_type/never_coercions.rs: New test. * rust/rustc/ui/never_type/never_transmute_never.rs: New test. * rust/rustc/ui/never_type/return-never-coerce.rs: New test. * rust/rustc/ui/never_type/try_from.rs: New test. * rust/rustc/ui/new-box-syntax.rs: New test. * rust/rustc/ui/new-box.rs: New test. * rust/rustc/ui/new-impl-syntax.rs: New test. * rust/rustc/ui/new-import-syntax.rs: New test. * rust/rustc/ui/new-style-constants.rs: New test. * rust/rustc/ui/new-unicode-escapes.rs: New test. * rust/rustc/ui/new-unsafe-pointers.rs: New test. * rust/rustc/ui/newlambdas-ret-infer.rs: New test. * rust/rustc/ui/newlambdas-ret-infer2.rs: New test. * rust/rustc/ui/newlambdas.rs: New test. * rust/rustc/ui/newtype-polymorphic.rs: New test. * rust/rustc/ui/newtype-temporary.rs: New test. * rust/rustc/ui/newtype.rs: New test. * rust/rustc/ui/nil-decl-in-foreign.rs: New test. * rust/rustc/ui/nll/assign-while-to-immutable.rs: New test. * rust/rustc/ui/nll/borrow-use-issue-46875.rs: New test. * rust/rustc/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs: New test. * rust/rustc/ui/nll/borrowed-local-error.rs: New test. * rust/rustc/ui/nll/borrowed-match-issue-45045.rs: New test. * rust/rustc/ui/nll/borrowed-referent-issue-38899.rs: New test. * rust/rustc/ui/nll/borrowed-temporary-error.rs: New test. * rust/rustc/ui/nll/borrowed-universal-error-2.rs: New test. * rust/rustc/ui/nll/borrowed-universal-error.rs: New test. * rust/rustc/ui/nll/cannot-move-block-spans.rs: New test. * rust/rustc/ui/nll/capture-mut-ref.rs: New test. * rust/rustc/ui/nll/capture-ref-in-struct.rs: New test. * rust/rustc/ui/nll/closure-access-spans.rs: New test. * rust/rustc/ui/nll/closure-borrow-spans.rs: New test. * rust/rustc/ui/nll/closure-captures.rs: New test. * rust/rustc/ui/nll/closure-move-spans.rs: New test. * rust/rustc/ui/nll/closure-requirements/escape-argument-callee.rs: New test. * rust/rustc/ui/nll/closure-requirements/escape-argument.rs: New test. * rust/rustc/ui/nll/closure-requirements/escape-upvar-nested.rs: New test. * rust/rustc/ui/nll/closure-requirements/escape-upvar-ref.rs: New test. * rust/rustc/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs: New test. * rust/rustc/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs: New test. * rust/rustc/ui/nll/closure-requirements/propagate-approximated-ref.rs: New test. * rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs: New test. * rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs: New test. * rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs: New test. * rust/rustc/ui/nll/closure-requirements/propagate-approximated-val.rs: New test. * rust/rustc/ui/nll/closure-requirements/propagate-despite-same-free-region.rs: New test. * rust/rustc/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs: New test. * rust/rustc/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs: New test. * rust/rustc/ui/nll/closure-requirements/propagate-from-trait-match.rs: New test. * rust/rustc/ui/nll/closure-requirements/propagate-multiple-requirements.rs: New test. * rust/rustc/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs: New test. * rust/rustc/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs: New test. * rust/rustc/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs: New test. * rust/rustc/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs: New test. * rust/rustc/ui/nll/closure-requirements/return-wrong-bound-region.rs: New test. * rust/rustc/ui/nll/closure-use-spans.rs: New test. * rust/rustc/ui/nll/closures-in-loops.rs: New test. * rust/rustc/ui/nll/constant-thread-locals-issue-47053.rs: New test. * rust/rustc/ui/nll/constant.rs: New test. * rust/rustc/ui/nll/decl-macro-illegal-copy.rs: New test. * rust/rustc/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.rs: New test. * rust/rustc/ui/nll/do-not-ignore-lifetime-bounds-in-copy.rs: New test. * rust/rustc/ui/nll/dont-print-desugared.rs: New test. * rust/rustc/ui/nll/drop-may-dangle.rs: New test. * rust/rustc/ui/nll/drop-no-may-dangle.rs: New test. * rust/rustc/ui/nll/empty-type-predicate-2.rs: New test. * rust/rustc/ui/nll/empty-type-predicate.rs: New test. * rust/rustc/ui/nll/enum-drop-access.rs: New test. * rust/rustc/ui/nll/extra-unused-mut.rs: New test. * rust/rustc/ui/nll/generator-distinct-lifetime.rs: New test. * rust/rustc/ui/nll/generator-upvar-mutability.rs: New test. * rust/rustc/ui/nll/get_default.rs: New test. * rust/rustc/ui/nll/guarantor-issue-46974.rs: New test. * rust/rustc/ui/nll/issue-16223.rs: New test. * rust/rustc/ui/nll/issue-21114-ebfull.rs: New test. * rust/rustc/ui/nll/issue-21114-kixunil.rs: New test. * rust/rustc/ui/nll/issue-21232-partial-init-and-erroneous-use.rs: New test. * rust/rustc/ui/nll/issue-21232-partial-init-and-use.rs: New test. * rust/rustc/ui/nll/issue-22323-temp-destruction.rs: New test. * rust/rustc/ui/nll/issue-27868.rs: New test. * rust/rustc/ui/nll/issue-30104.rs: New test. * rust/rustc/ui/nll/issue-31567.rs: New test. * rust/rustc/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs: New test. * rust/rustc/ui/nll/issue-42574-diagnostic-in-nested-closure.rs: New test. * rust/rustc/ui/nll/issue-43058.rs: New test. * rust/rustc/ui/nll/issue-46589.rs: New test. * rust/rustc/ui/nll/issue-47022.rs: New test. * rust/rustc/ui/nll/issue-47153-generic-const.rs: New test. * rust/rustc/ui/nll/issue-47388.rs: New test. * rust/rustc/ui/nll/issue-47470.rs: New test. * rust/rustc/ui/nll/issue-47589.rs: New test. * rust/rustc/ui/nll/issue-48070.rs: New test. * rust/rustc/ui/nll/issue-48238.rs: New test. * rust/rustc/ui/nll/issue-48623-closure.rs: New test. * rust/rustc/ui/nll/issue-48623-generator.rs: New test. * rust/rustc/ui/nll/issue-48697.rs: New test. * rust/rustc/ui/nll/issue-50343.rs: New test. * rust/rustc/ui/nll/issue-50461-used-mut-from-moves.rs: New test. * rust/rustc/ui/nll/issue-50716-1.rs: New test. * rust/rustc/ui/nll/issue-50716.rs: New test. * rust/rustc/ui/nll/issue-51191.rs: New test. * rust/rustc/ui/nll/issue-51244.rs: New test. * rust/rustc/ui/nll/issue-51268.rs: New test. * rust/rustc/ui/nll/issue-51351.rs: New test. * rust/rustc/ui/nll/issue-51512.rs: New test. * rust/rustc/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs: New test. * rust/rustc/ui/nll/issue-52078.rs: New test. * rust/rustc/ui/nll/issue-52086.rs: New test. * rust/rustc/ui/nll/issue-52113.rs: New test. * rust/rustc/ui/nll/issue-52534-1.rs: New test. * rust/rustc/ui/nll/issue-52534-2.rs: New test. * rust/rustc/ui/nll/issue-52534.rs: New test. * rust/rustc/ui/nll/issue-52663-span-decl-captured-variable.rs: New test. * rust/rustc/ui/nll/issue-52663-trait-object.rs: New test. * rust/rustc/ui/nll/issue-52669.rs: New test. * rust/rustc/ui/nll/issue-52742.rs: New test. * rust/rustc/ui/nll/issue-53040.rs: New test. * rust/rustc/ui/nll/issue-53119.rs: New test. * rust/rustc/ui/nll/issue-53123-raw-pointer-cast.rs: New test. * rust/rustc/ui/nll/issue-53570.rs: New test. * rust/rustc/ui/nll/issue-53773.rs: New test. * rust/rustc/ui/nll/issue-53807.rs: New test. * rust/rustc/ui/nll/issue-54382-use-span-of-tail-of-block.rs: New test. * rust/rustc/ui/nll/issue-54556-niconii.rs: New test. * rust/rustc/ui/nll/issue-54556-stephaneyfx.rs: New test. * rust/rustc/ui/nll/issue-54556-temps-in-tail-diagnostic.rs: New test. * rust/rustc/ui/nll/issue-54556-used-vs-unused-tails.rs: New test. * rust/rustc/ui/nll/issue-54556-wrap-it-up.rs: New test. * rust/rustc/ui/nll/issue-55288.rs: New test. * rust/rustc/ui/nll/issue-55344.rs: New test. * rust/rustc/ui/nll/issue-55394.rs: New test. * rust/rustc/ui/nll/issue-55401.rs: New test. * rust/rustc/ui/nll/issue-55651.rs: New test. * rust/rustc/ui/nll/issue-55850.rs: New test. * rust/rustc/ui/nll/issue-57100.rs: New test. * rust/rustc/ui/nll/issue-57265-return-type-wf-check.rs: New test. * rust/rustc/ui/nll/issue-57280-1.rs: New test. * rust/rustc/ui/nll/issue-57280.rs: New test. * rust/rustc/ui/nll/issue-57642-higher-ranked-subtype.rs: New test. * rust/rustc/ui/nll/issue-57960.rs: New test. * rust/rustc/ui/nll/issue-57989.rs: New test. * rust/rustc/ui/nll/issue-58053.rs: New test. * rust/rustc/ui/nll/issue-58299.rs: New test. * rust/rustc/ui/nll/issue-61311-normalize.rs: New test. * rust/rustc/ui/nll/issue-61320-normalize.rs: New test. * rust/rustc/ui/nll/issue-61424.rs: New test. * rust/rustc/ui/nll/issue-62007-assign-const-index.rs: New test. * rust/rustc/ui/nll/issue-62007-assign-differing-fields.rs: New test. * rust/rustc/ui/nll/issue-63154-normalize.rs: New test. * rust/rustc/ui/nll/issue-68550.rs: New test. * rust/rustc/ui/nll/issue-69114-static-mut-ty.rs: New test. * rust/rustc/ui/nll/issue-69114-static-ty.rs: New test. * rust/rustc/ui/nll/loan_ends_mid_block_pair.rs: New test. * rust/rustc/ui/nll/loan_ends_mid_block_vec.rs: New test. * rust/rustc/ui/nll/local-outlives-static-via-hrtb.rs: New test. * rust/rustc/ui/nll/match-cfg-fake-edges.rs: New test. * rust/rustc/ui/nll/match-cfg-fake-edges2.rs: New test. * rust/rustc/ui/nll/match-guards-always-borrow.rs: New test. * rust/rustc/ui/nll/match-guards-partially-borrow.rs: New test. * rust/rustc/ui/nll/match-on-borrowed.rs: New test. * rust/rustc/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs: New test. * rust/rustc/ui/nll/maybe-initialized-drop-uninitialized.rs: New test. * rust/rustc/ui/nll/maybe-initialized-drop-with-fragment.rs: New test. * rust/rustc/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs: New test. * rust/rustc/ui/nll/maybe-initialized-drop.rs: New test. * rust/rustc/ui/nll/mir_check_cast_closure.rs: New test. * rust/rustc/ui/nll/mir_check_cast_reify.rs: New test. * rust/rustc/ui/nll/mir_check_cast_unsafe_fn.rs: New test. * rust/rustc/ui/nll/mir_check_cast_unsize.rs: New test. * rust/rustc/ui/nll/move-errors.rs: New test. * rust/rustc/ui/nll/move-subpaths-moves-root.rs: New test. * rust/rustc/ui/nll/mutating_references.rs: New test. * rust/rustc/ui/nll/normalization-bounds-error.rs: New test. * rust/rustc/ui/nll/normalization-bounds.rs: New test. * rust/rustc/ui/nll/outlives-suggestion-more.rs: New test. * rust/rustc/ui/nll/outlives-suggestion-simple.rs: New test. * rust/rustc/ui/nll/polonius/assignment-kills-loans.rs: New test. * rust/rustc/ui/nll/polonius/assignment-to-differing-field.rs: New test. * rust/rustc/ui/nll/polonius/call-kills-loans.rs: New test. * rust/rustc/ui/nll/polonius/issue-46589.rs: New test. * rust/rustc/ui/nll/polonius/polonius-smoke-test.rs: New test. * rust/rustc/ui/nll/polonius/storagedead-kills-loans.rs: New test. * rust/rustc/ui/nll/polonius/subset-relations.rs: New test. * rust/rustc/ui/nll/process_or_insert_default.rs: New test. * rust/rustc/ui/nll/projection-return.rs: New test. * rust/rustc/ui/nll/promotable-mutable-zst-doesnt-conflict.rs: New test. * rust/rustc/ui/nll/promoted-bounds.rs: New test. * rust/rustc/ui/nll/promoted-closure-pair.rs: New test. * rust/rustc/ui/nll/promoted-liveness.rs: New test. * rust/rustc/ui/nll/rc-loop.rs: New test. * rust/rustc/ui/nll/reference-carried-through-struct-field.rs: New test. * rust/rustc/ui/nll/region-ends-after-if-condition.rs: New test. * rust/rustc/ui/nll/relate_tys/fn-subtype.rs: New test. * rust/rustc/ui/nll/relate_tys/hr-fn-aaa-as-aba.rs: New test. * rust/rustc/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs: New test. * rust/rustc/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs: New test. * rust/rustc/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs: New test. * rust/rustc/ui/nll/relate_tys/issue-48071.rs: New test. * rust/rustc/ui/nll/relate_tys/trait-hrtb.rs: New test. * rust/rustc/ui/nll/relate_tys/universe-violation.rs: New test. * rust/rustc/ui/nll/relate_tys/var-appears-twice.rs: New test. * rust/rustc/ui/nll/return-ref-mut-issue-46557.rs: New test. * rust/rustc/ui/nll/return_from_loop.rs: New test. * rust/rustc/ui/nll/self-assign-ref-mut.rs: New test. * rust/rustc/ui/nll/trait-associated-constant.rs: New test. * rust/rustc/ui/nll/ty-outlives/impl-trait-captures.rs: New test. * rust/rustc/ui/nll/ty-outlives/impl-trait-outlives.rs: New test. * rust/rustc/ui/nll/ty-outlives/issue-53789-1.rs: New test. * rust/rustc/ui/nll/ty-outlives/issue-53789-2.rs: New test. * rust/rustc/ui/nll/ty-outlives/issue-55756.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-body.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-implied-bounds.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-no-regions-closure.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-no-regions-fn.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-one-region-closure.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-where-clause-env.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-where-clause-none.rs: New test. * rust/rustc/ui/nll/ty-outlives/projection-where-clause-trait.rs: New test. * rust/rustc/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs: New test. * rust/rustc/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs: New test. * rust/rustc/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs: New test. * rust/rustc/ui/nll/ty-outlives/ty-param-fn-body.rs: New test. * rust/rustc/ui/nll/ty-outlives/ty-param-fn.rs: New test. * rust/rustc/ui/nll/ty-outlives/ty-param-implied-bounds.rs: New test. * rust/rustc/ui/nll/ty-outlives/wf-unreachable.rs: New test. * rust/rustc/ui/nll/type-alias-free-regions.rs: New test. * rust/rustc/ui/nll/type-check-pointer-coercions.rs: New test. * rust/rustc/ui/nll/type-check-pointer-comparisons.rs: New test. * rust/rustc/ui/nll/unused-mut-issue-50343.rs: New test. * rust/rustc/ui/nll/user-annotations/adt-brace-enums.rs: New test. * rust/rustc/ui/nll/user-annotations/adt-brace-structs.rs: New test. * rust/rustc/ui/nll/user-annotations/adt-nullary-enums.rs: New test. * rust/rustc/ui/nll/user-annotations/adt-tuple-enums.rs: New test. * rust/rustc/ui/nll/user-annotations/adt-tuple-struct-calls.rs: New test. * rust/rustc/ui/nll/user-annotations/adt-tuple-struct.rs: New test. * rust/rustc/ui/nll/user-annotations/cast_static_lifetime.rs: New test. * rust/rustc/ui/nll/user-annotations/closure-substs.rs: New test. * rust/rustc/ui/nll/user-annotations/constant-in-expr-inherent-1.rs: New test. * rust/rustc/ui/nll/user-annotations/constant-in-expr-inherent-2.rs: New test. * rust/rustc/ui/nll/user-annotations/constant-in-expr-normalize.rs: New test. * rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs: New test. * rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs: New test. * rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs: New test. * rust/rustc/ui/nll/user-annotations/downcast-infer.rs: New test. * rust/rustc/ui/nll/user-annotations/dump-adt-brace-struct.rs: New test. * rust/rustc/ui/nll/user-annotations/dump-fn-method.rs: New test. * rust/rustc/ui/nll/user-annotations/fns.rs: New test. * rust/rustc/ui/nll/user-annotations/inherent-associated-constants.rs: New test. * rust/rustc/ui/nll/user-annotations/issue-54124.rs: New test. * rust/rustc/ui/nll/user-annotations/issue-54570-bootstrapping.rs: New test. * rust/rustc/ui/nll/user-annotations/issue-55219.rs: New test. * rust/rustc/ui/nll/user-annotations/issue-55241.rs: New test. * rust/rustc/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs: New test. * rust/rustc/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs: New test. * rust/rustc/ui/nll/user-annotations/method-call.rs: New test. * rust/rustc/ui/nll/user-annotations/method-ufcs-1.rs: New test. * rust/rustc/ui/nll/user-annotations/method-ufcs-2.rs: New test. * rust/rustc/ui/nll/user-annotations/method-ufcs-3.rs: New test. * rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-1.rs: New test. * rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-2.rs: New test. * rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-3.rs: New test. * rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-4.rs: New test. * rust/rustc/ui/nll/user-annotations/normalization.rs: New test. * rust/rustc/ui/nll/user-annotations/normalize-self-ty.rs: New test. * rust/rustc/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs: New test. * rust/rustc/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs: New test. * rust/rustc/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs: New test. * rust/rustc/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs: New test. * rust/rustc/ui/nll/user-annotations/patterns.rs: New test. * rust/rustc/ui/nll/user-annotations/promoted-annotation.rs: New test. * rust/rustc/ui/nll/user-annotations/type-annotation-with-hrtb.rs: New test. * rust/rustc/ui/nll/user-annotations/type_ascription_static_lifetime.rs: New test. * rust/rustc/ui/nll/user-annotations/wf-self-type.rs: New test. * rust/rustc/ui/nll/where_clauses_in_functions.rs: New test. * rust/rustc/ui/nll/where_clauses_in_structs.rs: New test. * rust/rustc/ui/no-capture-arc.rs: New test. * rust/rustc/ui/no-core-1.rs: New test. * rust/rustc/ui/no-core-2.rs: New test. * rust/rustc/ui/no-implicit-prelude-nested.rs: New test. * rust/rustc/ui/no-implicit-prelude.rs: New test. * rust/rustc/ui/no-link-unknown-crate.rs: New test. * rust/rustc/ui/no-link.rs: New test. * rust/rustc/ui/no-patterns-in-args-2.rs: New test. * rust/rustc/ui/no-patterns-in-args-macro.rs: New test. * rust/rustc/ui/no-patterns-in-args.rs: New test. * rust/rustc/ui/no-reuse-move-arc.rs: New test. * rust/rustc/ui/no-send-res-ports.rs: New test. * rust/rustc/ui/no-std-1.rs: New test. * rust/rustc/ui/no-std-2.rs: New test. * rust/rustc/ui/no-std-3.rs: New test. * rust/rustc/ui/no-std-inject.rs: New test. * rust/rustc/ui/no-stdio.rs: New test. * rust/rustc/ui/no-type-for-node-ice.rs: New test. * rust/rustc/ui/no-warn-on-field-replace-issue-34101.rs: New test. * rust/rustc/ui/no_crate_type.rs: New test. * rust/rustc/ui/no_owned_box_lang_item.rs: New test. * rust/rustc/ui/no_send-enum.rs: New test. * rust/rustc/ui/no_send-rc.rs: New test. * rust/rustc/ui/no_send-struct.rs: New test. * rust/rustc/ui/no_share-enum.rs: New test. * rust/rustc/ui/no_share-struct.rs: New test. * rust/rustc/ui/noexporttypeexe.rs: New test. * rust/rustc/ui/non-built-in-quote.rs: New test. * rust/rustc/ui/non-constant-expr-for-arr-len.rs: New test. * rust/rustc/ui/non-constant-in-const-path.rs: New test. * rust/rustc/ui/non-copyable-void.rs: New test. * rust/rustc/ui/non-ice-error-on-worker-io-fail.rs: New test. * rust/rustc/ui/non-integer-atomic.rs: New test. * rust/rustc/ui/non-legacy-modes.rs: New test. * rust/rustc/ui/non_modrs_mods/foors_mod.rs: New test. * rust/rustc/ui/non_modrs_mods/foors_mod/inline/somename.rs: New test. * rust/rustc/ui/non_modrs_mods/foors_mod/inner_foors_mod.rs: New test. * rust/rustc/ui/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs: New test. * rust/rustc/ui/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs: New test. * rust/rustc/ui/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs: New test. * rust/rustc/ui/non_modrs_mods/modrs_mod/inline/somename.rs: New test. * rust/rustc/ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs: New test. * rust/rustc/ui/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs: New test. * rust/rustc/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs: New test. * rust/rustc/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs: New test. * rust/rustc/ui/non_modrs_mods/modrs_mod/mod.rs: New test. * rust/rustc/ui/non_modrs_mods/non_modrs_mods.rs: New test. * rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs: New test. * rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs: New test. * rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs: New test. * rust/rustc/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs: New test. * rust/rustc/ui/non_modrs_mods_and_inline_mods/x.rs: New test. * rust/rustc/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs: New test. * rust/rustc/ui/noncopyable-class.rs: New test. * rust/rustc/ui/nonscalar-cast.rs: New test. * rust/rustc/ui/not-clone-closure.rs: New test. * rust/rustc/ui/not-copy-closure.rs: New test. * rust/rustc/ui/not-enough-arguments.rs: New test. * rust/rustc/ui/not-panic/not-panic-safe-2.rs: New test. * rust/rustc/ui/not-panic/not-panic-safe-3.rs: New test. * rust/rustc/ui/not-panic/not-panic-safe-4.rs: New test. * rust/rustc/ui/not-panic/not-panic-safe-5.rs: New test. * rust/rustc/ui/not-panic/not-panic-safe-6.rs: New test. * rust/rustc/ui/not-panic/not-panic-safe.rs: New test. * rust/rustc/ui/not-sync.rs: New test. * rust/rustc/ui/nul-characters.rs: New test. * rust/rustc/ui/nullable-pointer-ffi-compat.rs: New test. * rust/rustc/ui/nullable-pointer-iotareduction.rs: New test. * rust/rustc/ui/nullable-pointer-size.rs: New test. * rust/rustc/ui/numbers-arithmetic/arith-unsigned.rs: New test. * rust/rustc/ui/numbers-arithmetic/div-mod.rs: New test. * rust/rustc/ui/numbers-arithmetic/divide-by-zero.rs: New test. * rust/rustc/ui/numbers-arithmetic/float-int-invalid-const-cast.rs: New test. * rust/rustc/ui/numbers-arithmetic/float-literal-inference.rs: New test. * rust/rustc/ui/numbers-arithmetic/float-nan.rs: New test. * rust/rustc/ui/numbers-arithmetic/float-signature.rs: New test. * rust/rustc/ui/numbers-arithmetic/float.rs: New test. * rust/rustc/ui/numbers-arithmetic/float2.rs: New test. * rust/rustc/ui/numbers-arithmetic/float_math.rs: New test. * rust/rustc/ui/numbers-arithmetic/floatlits.rs: New test. * rust/rustc/ui/numbers-arithmetic/i128.rs: New test. * rust/rustc/ui/numbers-arithmetic/i32-sub.rs: New test. * rust/rustc/ui/numbers-arithmetic/i8-incr.rs: New test. * rust/rustc/ui/numbers-arithmetic/int-abs-overflow.rs: New test. * rust/rustc/ui/numbers-arithmetic/int.rs: New test. * rust/rustc/ui/numbers-arithmetic/integer-literal-radix.rs: New test. * rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs: New test. * rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs: New test. * rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference.rs: New test. * rust/rustc/ui/numbers-arithmetic/mod-zero.rs: New test. * rust/rustc/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs: New test. * rust/rustc/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs: New test. * rust/rustc/ui/numbers-arithmetic/num-wrapping.rs: New test. * rust/rustc/ui/numbers-arithmetic/numeric-method-autoexport.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-add.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-lsh-1.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-lsh-2.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-lsh-3.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-lsh-4.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-mul.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-neg.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-pow-signed.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-pow-unsigned.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-rsh-1.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-rsh-2.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-rsh-3.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-rsh-4.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-rsh-5.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-rsh-6.rs: New test. * rust/rustc/ui/numbers-arithmetic/overflowing-sub.rs: New test. * rust/rustc/ui/numbers-arithmetic/promoted_overflow.rs: New test. * rust/rustc/ui/numbers-arithmetic/promoted_overflow_opt.rs: New test. * rust/rustc/ui/numbers-arithmetic/saturating-float-casts-impl.rs: New test. * rust/rustc/ui/numbers-arithmetic/saturating-float-casts-wasm.rs: New test. * rust/rustc/ui/numbers-arithmetic/saturating-float-casts.rs: New test. * rust/rustc/ui/numbers-arithmetic/shift-near-oflo.rs: New test. * rust/rustc/ui/numbers-arithmetic/shift-various-types.rs: New test. * rust/rustc/ui/numbers-arithmetic/shift.rs: New test. * rust/rustc/ui/numbers-arithmetic/signed-shift-const-eval.rs: New test. * rust/rustc/ui/numbers-arithmetic/u128-as-f32.rs: New test. * rust/rustc/ui/numbers-arithmetic/u128.rs: New test. * rust/rustc/ui/numbers-arithmetic/u32-decr.rs: New test. * rust/rustc/ui/numbers-arithmetic/u8-incr-decr.rs: New test. * rust/rustc/ui/numbers-arithmetic/u8-incr.rs: New test. * rust/rustc/ui/numbers-arithmetic/uint.rs: New test. * rust/rustc/ui/numeric/const-scope.rs: New test. * rust/rustc/ui/numeric/len.rs: New test. * rust/rustc/ui/numeric/numeric-cast-2.rs: New test. * rust/rustc/ui/numeric/numeric-cast-binop.rs: New test. * rust/rustc/ui/numeric/numeric-cast-no-fix.rs: New test. * rust/rustc/ui/numeric/numeric-cast-without-suggestion.rs: New test. * rust/rustc/ui/numeric/numeric-cast.rs: New test. * rust/rustc/ui/numeric/numeric-fields.rs: New test. * rust/rustc/ui/numeric/numeric-suffix.rs: New test. * rust/rustc/ui/object-does-not-impl-trait.rs: New test. * rust/rustc/ui/object-lifetime-default-default-to-static.rs: New test. * rust/rustc/ui/object-lifetime-default-from-rptr-box.rs: New test. * rust/rustc/ui/object-lifetime-default-from-rptr-mut.rs: New test. * rust/rustc/ui/object-lifetime-default-from-rptr.rs: New test. * rust/rustc/ui/object-lifetime/object-lifetime-default-ambiguous.rs: New test. * rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs: New test. * rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs: New test. * rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs: New test. * rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-static.rs: New test. * rust/rustc/ui/object-lifetime/object-lifetime-default-elision.rs: New test. * rust/rustc/ui/object-lifetime/object-lifetime-default-from-box-error.rs: New test. * rust/rustc/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.rs: New test. * rust/rustc/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.rs: New test. * rust/rustc/ui/object-lifetime/object-lifetime-default-mybox.rs: New test. * rust/rustc/ui/object-lifetime/object-lifetime-default.rs: New test. * rust/rustc/ui/object-method-numbering.rs: New test. * rust/rustc/ui/object-pointer-types.rs: New test. * rust/rustc/ui/object-safety/object-safety-associated-consts.rs: New test. * rust/rustc/ui/object-safety/object-safety-bounds.rs: New test. * rust/rustc/ui/object-safety/object-safety-by-value-self-use.rs: New test. * rust/rustc/ui/object-safety/object-safety-by-value-self.rs: New test. * rust/rustc/ui/object-safety/object-safety-generics.rs: New test. * rust/rustc/ui/object-safety/object-safety-issue-22040.rs: New test. * rust/rustc/ui/object-safety/object-safety-mentions-Self.rs: New test. * rust/rustc/ui/object-safety/object-safety-no-static.rs: New test. * rust/rustc/ui/object-safety/object-safety-phantom-fn.rs: New test. * rust/rustc/ui/object-safety/object-safety-sized-2.rs: New test. * rust/rustc/ui/object-safety/object-safety-sized.rs: New test. * rust/rustc/ui/object-safety/object-safety-supertrait-mentions-Self.rs: New test. * rust/rustc/ui/objects-coerce-freeze-borrored.rs: New test. * rust/rustc/ui/objects-owned-object-borrowed-method-headerless.rs: New test. * rust/rustc/ui/objects-owned-object-owned-method.rs: New test. * rust/rustc/ui/obsolete-in-place/bad.rs: New test. * rust/rustc/ui/obsolete-syntax-impl-for-dotdot.rs: New test. * rust/rustc/ui/occurs-check-2.rs: New test. * rust/rustc/ui/occurs-check-3.rs: New test. * rust/rustc/ui/occurs-check.rs: New test. * rust/rustc/ui/offset_from.rs: New test. * rust/rustc/ui/old-suffixes-are-really-forbidden.rs: New test. * rust/rustc/ui/on-unimplemented/auxiliary/no_debug.rs: New test. * rust/rustc/ui/on-unimplemented/bad-annotation.rs: New test. * rust/rustc/ui/on-unimplemented/enclosing-scope.rs: New test. * rust/rustc/ui/on-unimplemented/expected-comma-found-token.rs: New test. * rust/rustc/ui/on-unimplemented/feature-gate-on-unimplemented.rs: New test. * rust/rustc/ui/on-unimplemented/multiple-impls.rs: New test. * rust/rustc/ui/on-unimplemented/no-debug.rs: New test. * rust/rustc/ui/on-unimplemented/on-impl.rs: New test. * rust/rustc/ui/on-unimplemented/on-trait.rs: New test. * rust/rustc/ui/on-unimplemented/slice-index.rs: New test. * rust/rustc/ui/once-cant-call-twice-on-heap.rs: New test. * rust/rustc/ui/once-move-out-on-heap.rs: New test. * rust/rustc/ui/one-tuple.rs: New test. * rust/rustc/ui/op-assign-builtins-by-ref.rs: New test. * rust/rustc/ui/opeq.rs: New test. * rust/rustc/ui/operator-associativity.rs: New test. * rust/rustc/ui/operator-multidispatch.rs: New test. * rust/rustc/ui/operator-overloading.rs: New test. * rust/rustc/ui/opt-in-copy.rs: New test. * rust/rustc/ui/optimization-fuel-0.rs: New test. * rust/rustc/ui/optimization-fuel-1.rs: New test. * rust/rustc/ui/option-ext.rs: New test. * rust/rustc/ui/option-to-result.rs: New test. * rust/rustc/ui/or-patterns/already-bound-name.rs: New test. * rust/rustc/ui/or-patterns/basic-switch.rs: New test. * rust/rustc/ui/or-patterns/basic-switchint.rs: New test. * rust/rustc/ui/or-patterns/bindings-runpass-1.rs: New test. * rust/rustc/ui/or-patterns/bindings-runpass-2.rs: New test. * rust/rustc/ui/or-patterns/box-patterns.rs: New test. * rust/rustc/ui/or-patterns/consistent-bindings.rs: New test. * rust/rustc/ui/or-patterns/const-fn.rs: New test. * rust/rustc/ui/or-patterns/exhaustiveness-non-exhaustive.rs: New test. * rust/rustc/ui/or-patterns/exhaustiveness-pass.rs: New test. * rust/rustc/ui/or-patterns/exhaustiveness-unreachable-pattern.rs: New test. * rust/rustc/ui/or-patterns/feature-gate-or_patterns-leading-for.rs: New test. * rust/rustc/ui/or-patterns/feature-gate-or_patterns-leading-let.rs: New test. * rust/rustc/ui/or-patterns/feature-gate-or_patterns.rs: New test. * rust/rustc/ui/or-patterns/fn-param-wrap-parens.rs: New test. * rust/rustc/ui/or-patterns/for-loop.rs: New test. * rust/rustc/ui/or-patterns/if-let-while-let.rs: New test. * rust/rustc/ui/or-patterns/inconsistent-modes.rs: New test. * rust/rustc/ui/or-patterns/issue-64879-trailing-before-guard.rs: New test. * rust/rustc/ui/or-patterns/issue-67514-irrefutable-param.rs: New test. * rust/rustc/ui/or-patterns/issue-68785-irrefutable-param-with-at.rs: New test. * rust/rustc/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs: New test. * rust/rustc/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs: New test. * rust/rustc/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs: New test. * rust/rustc/ui/or-patterns/let-pattern.rs: New test. * rust/rustc/ui/or-patterns/mismatched-bindings-async-fn.rs: New test. * rust/rustc/ui/or-patterns/missing-bindings.rs: New test. * rust/rustc/ui/or-patterns/mix-with-wild.rs: New test. * rust/rustc/ui/or-patterns/multiple-pattern-typo.rs: New test. * rust/rustc/ui/or-patterns/or-patterns-binding-type-mismatch.rs: New test. * rust/rustc/ui/or-patterns/or-patterns-default-binding-modes.rs: New test. * rust/rustc/ui/or-patterns/or-patterns-syntactic-fail.rs: New test. * rust/rustc/ui/or-patterns/or-patterns-syntactic-pass.rs: New test. * rust/rustc/ui/or-patterns/remove-leading-vert.rs: New test. * rust/rustc/ui/or-patterns/search-via-bindings.rs: New test. * rust/rustc/ui/or-patterns/slice-patterns.rs: New test. * rust/rustc/ui/or-patterns/struct-like.rs: New test. * rust/rustc/ui/or-patterns/while-parsing-this-or-pattern.rs: New test. * rust/rustc/ui/order-dependent-cast-inference.rs: New test. * rust/rustc/ui/orphan-check-diagnostics.rs: New test. * rust/rustc/ui/osx-frameworks.rs: New test. * rust/rustc/ui/out-of-order-shadowing.rs: New test. * rust/rustc/ui/out-of-stack.rs: New test. * rust/rustc/ui/out-pointer-aliasing.rs: New test. * rust/rustc/ui/output-slot-variants.rs: New test. * rust/rustc/ui/output-type-mismatch.rs: New test. * rust/rustc/ui/over-constrained-vregs.rs: New test. * rust/rustc/ui/overlap-doesnt-conflict-with-specialization.rs: New test. * rust/rustc/ui/overlap-permitted-for-annotated-marker-traits.rs: New test. * rust/rustc/ui/overloaded-calls-nontuple.rs: New test. * rust/rustc/ui/overloaded/auxiliary/overloaded_autoderef_xc.rs: New test. * rust/rustc/ui/overloaded/overloaded-autoderef-count.rs: New test. * rust/rustc/ui/overloaded/overloaded-autoderef-indexing.rs: New test. * rust/rustc/ui/overloaded/overloaded-autoderef-order.rs: New test. * rust/rustc/ui/overloaded/overloaded-autoderef-vtable.rs: New test. * rust/rustc/ui/overloaded/overloaded-autoderef-xcrate.rs: New test. * rust/rustc/ui/overloaded/overloaded-autoderef.rs: New test. * rust/rustc/ui/overloaded/overloaded-calls-object-one-arg.rs: New test. * rust/rustc/ui/overloaded/overloaded-calls-object-two-args.rs: New test. * rust/rustc/ui/overloaded/overloaded-calls-object-zero-args.rs: New test. * rust/rustc/ui/overloaded/overloaded-calls-param-vtables.rs: New test. * rust/rustc/ui/overloaded/overloaded-calls-simple.rs: New test. * rust/rustc/ui/overloaded/overloaded-calls-zero-args.rs: New test. * rust/rustc/ui/overloaded/overloaded-deref-count.rs: New test. * rust/rustc/ui/overloaded/overloaded-deref.rs: New test. * rust/rustc/ui/overloaded/overloaded-index-assoc-list.rs: New test. * rust/rustc/ui/overloaded/overloaded-index-autoderef.rs: New test. * rust/rustc/ui/overloaded/overloaded-index-in-field.rs: New test. * rust/rustc/ui/overloaded/overloaded-index.rs: New test. * rust/rustc/ui/overloaded/overloaded_deref_with_ref_pattern.rs: New test. * rust/rustc/ui/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs: New test. * rust/rustc/ui/owned-implies-static.rs: New test. * rust/rustc/ui/packed-struct/packed-struct-generic-transmute.rs: New test. * rust/rustc/ui/packed-struct/packed-struct-transmute.rs: New test. * rust/rustc/ui/packed/auxiliary/packed.rs: New test. * rust/rustc/ui/packed/packed-struct-address-of-element.rs: New test. * rust/rustc/ui/packed/packed-struct-borrow-element.rs: New test. * rust/rustc/ui/packed/packed-struct-drop-aligned.rs: New test. * rust/rustc/ui/packed/packed-struct-generic-layout.rs: New test. * rust/rustc/ui/packed/packed-struct-generic-size.rs: New test. * rust/rustc/ui/packed/packed-struct-layout.rs: New test. * rust/rustc/ui/packed/packed-struct-match.rs: New test. * rust/rustc/ui/packed/packed-struct-optimized-enum.rs: New test. * rust/rustc/ui/packed/packed-struct-size-xc.rs: New test. * rust/rustc/ui/packed/packed-struct-size.rs: New test. * rust/rustc/ui/packed/packed-struct-vec.rs: New test. * rust/rustc/ui/packed/packed-tuple-struct-layout.rs: New test. * rust/rustc/ui/packed/packed-tuple-struct-size.rs: New test. * rust/rustc/ui/packed/packed-with-inference-vars-issue-61402.rs: New test. * rust/rustc/ui/panic-handler/auxiliary/some-panic-impl.rs: New test. * rust/rustc/ui/panic-handler/panic-handler-bad-signature-1.rs: New test. * rust/rustc/ui/panic-handler/panic-handler-bad-signature-2.rs: New test. * rust/rustc/ui/panic-handler/panic-handler-bad-signature-3.rs: New test. * rust/rustc/ui/panic-handler/panic-handler-bad-signature-4.rs: New test. * rust/rustc/ui/panic-handler/panic-handler-duplicate.rs: New test. * rust/rustc/ui/panic-handler/panic-handler-requires-panic-info.rs: New test. * rust/rustc/ui/panic-handler/panic-handler-std.rs: New test. * rust/rustc/ui/panic-handler/panic-handler-wrong-location.rs: New test. * rust/rustc/ui/panic-runtime/abort-link-to-unwind-dylib.rs: New test. * rust/rustc/ui/panic-runtime/abort-link-to-unwinding-crates.rs: New test. * rust/rustc/ui/panic-runtime/abort.rs: New test. * rust/rustc/ui/panic-runtime/auxiliary/exit-success-if-unwind.rs: New test. * rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-abort.rs: New test. * rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs: New test. * rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-unwind.rs: New test. * rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-unwind2.rs: New test. * rust/rustc/ui/panic-runtime/auxiliary/wants-panic-runtime-abort.rs: New test. * rust/rustc/ui/panic-runtime/auxiliary/wants-panic-runtime-unwind.rs: New test. * rust/rustc/ui/panic-runtime/bad-panic-flag1.rs: New test. * rust/rustc/ui/panic-runtime/bad-panic-flag2.rs: New test. * rust/rustc/ui/panic-runtime/link-to-abort.rs: New test. * rust/rustc/ui/panic-runtime/link-to-unwind.rs: New test. * rust/rustc/ui/panic-runtime/lto-abort.rs: New test. * rust/rustc/ui/panic-runtime/lto-unwind.rs: New test. * rust/rustc/ui/panic-runtime/needs-gate.rs: New test. * rust/rustc/ui/panic-runtime/transitive-link-a-bunch.rs: New test. * rust/rustc/ui/panic-runtime/unwind-interleaved.rs: New test. * rust/rustc/ui/panic-runtime/unwind-rec.rs: New test. * rust/rustc/ui/panic-runtime/unwind-rec2.rs: New test. * rust/rustc/ui/panic-runtime/unwind-unique.rs: New test. * rust/rustc/ui/panic-runtime/want-unwind-got-abort.rs: New test. * rust/rustc/ui/panic-runtime/want-unwind-got-abort2.rs: New test. * rust/rustc/ui/panic-while-printing.rs: New test. * rust/rustc/ui/panic_implementation-closures.rs: New test. * rust/rustc/ui/panics/abort-on-panic.rs: New test. * rust/rustc/ui/panics/args-panic.rs: New test. * rust/rustc/ui/panics/doublepanic.rs: New test. * rust/rustc/ui/panics/explicit-panic-msg.rs: New test. * rust/rustc/ui/panics/explicit-panic.rs: New test. * rust/rustc/ui/panics/fmt-panic.rs: New test. * rust/rustc/ui/panics/issue-47429-short-backtraces.rs: New test. * rust/rustc/ui/panics/main-panic.rs: New test. * rust/rustc/ui/panics/panic-arg.rs: New test. * rust/rustc/ui/panics/panic-handler-chain.rs: New test. * rust/rustc/ui/panics/panic-handler-flail-wildly.rs: New test. * rust/rustc/ui/panics/panic-handler-set-twice.rs: New test. * rust/rustc/ui/panics/panic-in-dtor-drops-fields.rs: New test. * rust/rustc/ui/panics/panic-macro-any-wrapped.rs: New test. * rust/rustc/ui/panics/panic-macro-any.rs: New test. * rust/rustc/ui/panics/panic-macro-explicit.rs: New test. * rust/rustc/ui/panics/panic-macro-fmt.rs: New test. * rust/rustc/ui/panics/panic-macro-owned.rs: New test. * rust/rustc/ui/panics/panic-macro-static.rs: New test. * rust/rustc/ui/panics/panic-main.rs: New test. * rust/rustc/ui/panics/panic-parens.rs: New test. * rust/rustc/ui/panics/panic-recover-propagate.rs: New test. * rust/rustc/ui/panics/panic-set-handler.rs: New test. * rust/rustc/ui/panics/panic-set-unset-handler.rs: New test. * rust/rustc/ui/panics/panic-take-handler-nop.rs: New test. * rust/rustc/ui/panics/panic-task-name-none.rs: New test. * rust/rustc/ui/panics/panic-task-name-owned.rs: New test. * rust/rustc/ui/panics/panic.rs: New test. * rust/rustc/ui/panics/result-get-panic.rs: New test. * rust/rustc/ui/panics/test-panic.rs: New test. * rust/rustc/ui/panics/test-should-fail-bad-message.rs: New test. * rust/rustc/ui/panics/test-should-panic-bad-message.rs: New test. * rust/rustc/ui/panics/test-should-panic-no-message.rs: New test. * rust/rustc/ui/panics/unique-panic.rs: New test. * rust/rustc/ui/panics/while-body-panics.rs: New test. * rust/rustc/ui/panics/while-panic.rs: New test. * rust/rustc/ui/paren-free.rs: New test. * rust/rustc/ui/paren-span.rs: New test. * rust/rustc/ui/parenthesized-deref-suggestion.rs: New test. * rust/rustc/ui/parse-assoc-type-lt.rs: New test. * rust/rustc/ui/parse-error-correct.rs: New test. * rust/rustc/ui/parse-panic.rs: New test. * rust/rustc/ui/parser-recovery-1.rs: New test. * rust/rustc/ui/parser-recovery-2.rs: New test. * rust/rustc/ui/parser-unicode-whitespace.rs: New test. * rust/rustc/ui/parser/ascii-only-character-escape.rs: New test. * rust/rustc/ui/parser/assoc-const-underscore-semantic-fail.rs: New test. * rust/rustc/ui/parser/assoc-const-underscore-syntactic-pass.rs: New test. * rust/rustc/ui/parser/assoc-oddities-1.rs: New test. * rust/rustc/ui/parser/assoc-oddities-2.rs: New test. * rust/rustc/ui/parser/assoc-static-semantic-fail.rs: New test. * rust/rustc/ui/parser/assoc-static-syntactic-fail.rs: New test. * rust/rustc/ui/parser/assoc-type-in-type-arg.rs: New test. * rust/rustc/ui/parser/associated-types-project-from-hrtb-explicit.rs: New test. * rust/rustc/ui/parser/attr-bad-meta-2.rs: New test. * rust/rustc/ui/parser/attr-bad-meta-3.rs: New test. * rust/rustc/ui/parser/attr-bad-meta.rs: New test. * rust/rustc/ui/parser/attr-before-eof.rs: New test. * rust/rustc/ui/parser/attr-dangling-in-fn.rs: New test. * rust/rustc/ui/parser/attr-dangling-in-mod.rs: New test. * rust/rustc/ui/parser/attr-stmt-expr-attr-bad.rs: New test. * rust/rustc/ui/parser/attr.rs: New test. * rust/rustc/ui/parser/attrs-after-extern-mod.rs: New test. * rust/rustc/ui/parser/bad-char-literals.rs: New test. * rust/rustc/ui/parser/bad-fn-ptr-qualifier.rs: New test. * rust/rustc/ui/parser/bad-interpolated-block.rs: New test. * rust/rustc/ui/parser/bad-lit-suffixes.rs: New test. * rust/rustc/ui/parser/bad-match.rs: New test. * rust/rustc/ui/parser/bad-name.rs: New test. * rust/rustc/ui/parser/bad-pointer-type.rs: New test. * rust/rustc/ui/parser/bad-value-ident-false.rs: New test. * rust/rustc/ui/parser/bad-value-ident-true.rs: New test. * rust/rustc/ui/parser/bare-struct-body.rs: New test. * rust/rustc/ui/parser/better-expected.rs: New test. * rust/rustc/ui/parser/bind-struct-early-modifiers.rs: New test. * rust/rustc/ui/parser/block-no-opening-brace.rs: New test. * rust/rustc/ui/parser/bound-single-question-mark.rs: New test. * rust/rustc/ui/parser/bounds-lifetime-1.rs: New test. * rust/rustc/ui/parser/bounds-lifetime-2.rs: New test. * rust/rustc/ui/parser/bounds-lifetime-where-1.rs: New test. * rust/rustc/ui/parser/bounds-lifetime-where.rs: New test. * rust/rustc/ui/parser/bounds-lifetime.rs: New test. * rust/rustc/ui/parser/bounds-obj-parens.rs: New test. * rust/rustc/ui/parser/bounds-type-where.rs: New test. * rust/rustc/ui/parser/bounds-type.rs: New test. * rust/rustc/ui/parser/brace-after-qualified-path-in-match.rs: New test. * rust/rustc/ui/parser/byte-literals.rs: New test. * rust/rustc/ui/parser/byte-string-literals.rs: New test. * rust/rustc/ui/parser/chained-comparison-suggestion.rs: New test. * rust/rustc/ui/parser/circular_modules_hello.rs: New test. * rust/rustc/ui/parser/circular_modules_main.rs: New test. * rust/rustc/ui/parser/class-implements-bad-trait.rs: New test. * rust/rustc/ui/parser/closure-return-syntax.rs: New test. * rust/rustc/ui/parser/column-offset-1-based.rs: New test. * rust/rustc/ui/parser/constraints-before-generic-args-syntactic-pass.rs: New test. * rust/rustc/ui/parser/default-on-wrong-item-kind.rs: New test. * rust/rustc/ui/parser/default-unmatched-assoc.rs: New test. * rust/rustc/ui/parser/default-unmatched-extern.rs: New test. * rust/rustc/ui/parser/default-unmatched.rs: New test. * rust/rustc/ui/parser/default.rs: New test. * rust/rustc/ui/parser/do-catch-suggests-try.rs: New test. * rust/rustc/ui/parser/doc-after-struct-field.rs: New test. * rust/rustc/ui/parser/doc-before-attr.rs: New test. * rust/rustc/ui/parser/doc-before-eof.rs: New test. * rust/rustc/ui/parser/doc-before-extern-rbrace.rs: New test. * rust/rustc/ui/parser/doc-before-fn-rbrace.rs: New test. * rust/rustc/ui/parser/doc-before-identifier.rs: New test. * rust/rustc/ui/parser/doc-before-mod-rbrace.rs: New test. * rust/rustc/ui/parser/doc-before-rbrace.rs: New test. * rust/rustc/ui/parser/doc-before-semi.rs: New test. * rust/rustc/ui/parser/doc-before-struct-rbrace-1.rs: New test. * rust/rustc/ui/parser/doc-before-struct-rbrace-2.rs: New test. * rust/rustc/ui/parser/doc-comment-in-if-statement.rs: New test. * rust/rustc/ui/parser/doc-comment-in-stmt.rs: New test. * rust/rustc/ui/parser/doc-inside-trait-item.rs: New test. * rust/rustc/ui/parser/duplicate-visibility.rs: New test. * rust/rustc/ui/parser/empty-impl-semicolon.rs: New test. * rust/rustc/ui/parser/expr-as-stmt-2.rs: New test. * rust/rustc/ui/parser/expr-as-stmt.rs: New test. * rust/rustc/ui/parser/extern-abi-from-mac-literal-frag.rs: New test. * rust/rustc/ui/parser/extern-abi-raw-strings.rs: New test. * rust/rustc/ui/parser/extern-abi-string-escaping.rs: New test. * rust/rustc/ui/parser/extern-abi-syntactic.rs: New test. * rust/rustc/ui/parser/extern-crate-async.rs: New test. * rust/rustc/ui/parser/extern-crate-unexpected-token.rs: New test. * rust/rustc/ui/parser/extern-expected-fn-or-brace.rs: New test. * rust/rustc/ui/parser/extern-foreign-crate.rs: New test. * rust/rustc/ui/parser/extern-no-fn.rs: New test. * rust/rustc/ui/parser/float-field-interpolated.rs: New test. * rust/rustc/ui/parser/float-field.rs: New test. * rust/rustc/ui/parser/fn-arg-doc-comment.rs: New test. * rust/rustc/ui/parser/fn-body-eq-expr-semi.rs: New test. * rust/rustc/ui/parser/fn-body-optional-semantic-fail.rs: New test. * rust/rustc/ui/parser/fn-body-optional-syntactic-pass.rs: New test. * rust/rustc/ui/parser/fn-colon-return-type.rs: New test. * rust/rustc/ui/parser/fn-header-semantic-fail.rs: New test. * rust/rustc/ui/parser/fn-header-syntactic-pass.rs: New test. * rust/rustc/ui/parser/fn-returns-fn-pointer.rs: New test. * rust/rustc/ui/parser/foreign-const-semantic-fail.rs: New test. * rust/rustc/ui/parser/foreign-const-syntactic-fail.rs: New test. * rust/rustc/ui/parser/foreign-static-semantic-fail.rs: New test. * rust/rustc/ui/parser/foreign-static-syntactic-pass.rs: New test. * rust/rustc/ui/parser/foreign-ty-semantic-fail.rs: New test. * rust/rustc/ui/parser/foreign-ty-syntactic-pass.rs: New test. * rust/rustc/ui/parser/if-in-in.rs: New test. * rust/rustc/ui/parser/impl-item-const-pass.rs: New test. * rust/rustc/ui/parser/impl-item-const-semantic-fail.rs: New test. * rust/rustc/ui/parser/impl-item-fn-no-body-pass.rs: New test. * rust/rustc/ui/parser/impl-item-fn-no-body-semantic-fail.rs: New test. * rust/rustc/ui/parser/impl-item-type-no-body-pass.rs: New test. * rust/rustc/ui/parser/impl-item-type-no-body-semantic-fail.rs: New test. * rust/rustc/ui/parser/impl-parsing.rs: New test. * rust/rustc/ui/parser/impl-qpath.rs: New test. * rust/rustc/ui/parser/import-from-path.rs: New test. * rust/rustc/ui/parser/import-from-rename.rs: New test. * rust/rustc/ui/parser/import-glob-path.rs: New test. * rust/rustc/ui/parser/import-glob-rename.rs: New test. * rust/rustc/ui/parser/inner-attr-after-doc-comment.rs: New test. * rust/rustc/ui/parser/inner-attr-in-trait-def.rs: New test. * rust/rustc/ui/parser/inner-attr.rs: New test. * rust/rustc/ui/parser/int-literal-too-large-span.rs: New test. * rust/rustc/ui/parser/intersection-patterns.rs: New test. * rust/rustc/ui/parser/inverted-parameters.rs: New test. * rust/rustc/ui/parser/issue-10392-2.rs: New test. * rust/rustc/ui/parser/issue-10392.rs: New test. * rust/rustc/ui/parser/issue-10636-1.rs: New test. * rust/rustc/ui/parser/issue-10636-2.rs: New test. * rust/rustc/ui/parser/issue-14303-enum.rs: New test. * rust/rustc/ui/parser/issue-14303-fn-def.rs: New test. * rust/rustc/ui/parser/issue-14303-fncall.rs: New test. * rust/rustc/ui/parser/issue-14303-impl.rs: New test. * rust/rustc/ui/parser/issue-14303-path.rs: New test. * rust/rustc/ui/parser/issue-14303-struct.rs: New test. * rust/rustc/ui/parser/issue-14303-trait.rs: New test. * rust/rustc/ui/parser/issue-15914.rs: New test. * rust/rustc/ui/parser/issue-15980.rs: New test. * rust/rustc/ui/parser/issue-1655.rs: New test. * rust/rustc/ui/parser/issue-17383.rs: New test. * rust/rustc/ui/parser/issue-17718-const-mut.rs: New test. * rust/rustc/ui/parser/issue-17904-2.rs: New test. * rust/rustc/ui/parser/issue-17904.rs: New test. * rust/rustc/ui/parser/issue-1802-1.rs: New test. * rust/rustc/ui/parser/issue-1802-2.rs: New test. * rust/rustc/ui/parser/issue-19096.rs: New test. * rust/rustc/ui/parser/issue-19398.rs: New test. * rust/rustc/ui/parser/issue-20711-2.rs: New test. * rust/rustc/ui/parser/issue-20711.rs: New test. * rust/rustc/ui/parser/issue-21153.rs: New test. * rust/rustc/ui/parser/issue-22647.rs: New test. * rust/rustc/ui/parser/issue-22712.rs: New test. * rust/rustc/ui/parser/issue-2354-1.rs: New test. * rust/rustc/ui/parser/issue-2354.rs: New test. * rust/rustc/ui/parser/issue-23620-invalid-escapes.rs: New test. * rust/rustc/ui/parser/issue-24197.rs: New test. * rust/rustc/ui/parser/issue-24375.rs: New test. * rust/rustc/ui/parser/issue-24780.rs: New test. * rust/rustc/ui/parser/issue-27255.rs: New test. * rust/rustc/ui/parser/issue-30318.rs: New test. * rust/rustc/ui/parser/issue-3036.rs: New test. * rust/rustc/ui/parser/issue-32214.rs: New test. * rust/rustc/ui/parser/issue-32446.rs: New test. * rust/rustc/ui/parser/issue-32501.rs: New test. * rust/rustc/ui/parser/issue-32505.rs: New test. * rust/rustc/ui/parser/issue-33262.rs: New test. * rust/rustc/ui/parser/issue-33413.rs: New test. * rust/rustc/ui/parser/issue-33418.rs: New test. * rust/rustc/ui/parser/issue-33455.rs: New test. * rust/rustc/ui/parser/issue-35813-postfix-after-cast.rs: New test. * rust/rustc/ui/parser/issue-41155.rs: New test. * rust/rustc/ui/parser/issue-43692.rs: New test. * rust/rustc/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs: New test. * rust/rustc/ui/parser/issue-48137-macros-cannot-interpolate-impl-items.rs: New test. * rust/rustc/ui/parser/issue-5544-a.rs: New test. * rust/rustc/ui/parser/issue-5544-b.rs: New test. * rust/rustc/ui/parser/issue-5806.rs: New test. * rust/rustc/ui/parser/issue-58094-missing-right-square-bracket.rs: New test. * rust/rustc/ui/parser/issue-59418.rs: New test. * rust/rustc/ui/parser/issue-62524.rs: New test. * rust/rustc/ui/parser/issue-62546.rs: New test. * rust/rustc/ui/parser/issue-62660.rs: New test. * rust/rustc/ui/parser/issue-62881.rs: New test. * rust/rustc/ui/parser/issue-62894.rs: New test. * rust/rustc/ui/parser/issue-62895.rs: New test. * rust/rustc/ui/parser/issue-62913.rs: New test. * rust/rustc/ui/parser/issue-62973.rs: New test. * rust/rustc/ui/parser/issue-63115-range-pat-interpolated.rs: New test. * rust/rustc/ui/parser/issue-63116.rs: New test. * rust/rustc/ui/parser/issue-63135.rs: New test. * rust/rustc/ui/parser/issue-65041-empty-vis-matcher-in-enum.rs: New test. * rust/rustc/ui/parser/issue-65041-empty-vis-matcher-in-trait.rs: New test. * rust/rustc/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs: New test. * rust/rustc/ui/parser/issue-65257-invalid-var-decl-recovery.rs: New test. * rust/rustc/ui/parser/issue-65846-rollback-gating-failing-matcher.rs: New test. * rust/rustc/ui/parser/issue-6610.rs: New test. * rust/rustc/ui/parser/issue-66357-unexpected-unreachable.rs: New test. * rust/rustc/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.rs: New test. * rust/rustc/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs: New test. * rust/rustc/ui/parser/issue-68629.rs: New test. * rust/rustc/ui/parser/issue-68730.rs: New test. * rust/rustc/ui/parser/issue-68788-in-trait-item-propagation.rs: New test. * rust/rustc/ui/parser/issue-68890-2.rs: New test. * rust/rustc/ui/parser/issue-68890.rs: New test. * rust/rustc/ui/parser/issue-70050-ntliteral-accepts-negated-lit.rs: New test. * rust/rustc/ui/parser/issue-70388-recover-dotdotdot-rest-pat.rs: New test. * rust/rustc/ui/parser/issue-70388-without-witness.rs: New test. * rust/rustc/ui/parser/issue-70549-resolve-after-recovered-self-ctor.rs: New test. * rust/rustc/ui/parser/issue-70552-ascription-in-parens-after-call.rs: New test. * rust/rustc/ui/parser/issue-70583-block-is-empty-1.rs: New test. * rust/rustc/ui/parser/issue-70583-block-is-empty-2.rs: New test. * rust/rustc/ui/parser/issue-73568-lifetime-after-mut.rs: New test. * rust/rustc/ui/parser/issue-8537.rs: New test. * rust/rustc/ui/parser/item-free-const-no-body-semantic-fail.rs: New test. * rust/rustc/ui/parser/item-free-const-no-body-syntactic-pass.rs: New test. * rust/rustc/ui/parser/item-free-static-no-body-semantic-fail.rs: New test. * rust/rustc/ui/parser/item-free-static-no-body-syntactic-pass.rs: New test. * rust/rustc/ui/parser/item-free-type-bounds-semantic-fail.rs: New test. * rust/rustc/ui/parser/item-free-type-bounds-syntactic-pass.rs: New test. * rust/rustc/ui/parser/keyword-abstract.rs: New test. * rust/rustc/ui/parser/keyword-as-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-box-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-break-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-const-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-continue-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-else-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-enum-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-final.rs: New test. * rust/rustc/ui/parser/keyword-fn-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-for-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-if-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-impl-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-in-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-let-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-loop-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-match-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-mod-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-move-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-mut-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-override.rs: New test. * rust/rustc/ui/parser/keyword-pub-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-ref-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-return-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-static-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-struct-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-trait-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-try-as-identifier-edition2018.rs: New test. * rust/rustc/ui/parser/keyword-type-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-typeof.rs: New test. * rust/rustc/ui/parser/keyword-unsafe-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-use-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-where-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword-while-as-identifier.rs: New test. * rust/rustc/ui/parser/keyword.rs: New test. * rust/rustc/ui/parser/keywords-followed-by-double-colon.rs: New test. * rust/rustc/ui/parser/labeled-no-colon-expr.rs: New test. * rust/rustc/ui/parser/let-binop.rs: New test. * rust/rustc/ui/parser/lex-bad-binary-literal.rs: New test. * rust/rustc/ui/parser/lex-bad-char-literals-1.rs: New test. * rust/rustc/ui/parser/lex-bad-char-literals-2.rs: New test. * rust/rustc/ui/parser/lex-bad-char-literals-3.rs: New test. * rust/rustc/ui/parser/lex-bad-char-literals-4.rs: New test. * rust/rustc/ui/parser/lex-bad-char-literals-5.rs: New test. * rust/rustc/ui/parser/lex-bad-char-literals-6.rs: New test. * rust/rustc/ui/parser/lex-bad-char-literals-7.rs: New test. * rust/rustc/ui/parser/lex-bad-numeric-literals.rs: New test. * rust/rustc/ui/parser/lex-bad-octal-literal.rs: New test. * rust/rustc/ui/parser/lex-bad-token.rs: New test. * rust/rustc/ui/parser/lex-bare-cr-string-literal-doc-comment.rs: New test. * rust/rustc/ui/parser/lex-stray-backslash.rs: New test. * rust/rustc/ui/parser/lifetime-in-pattern-recover.rs: New test. * rust/rustc/ui/parser/lifetime-in-pattern.rs: New test. * rust/rustc/ui/parser/lifetime-semicolon.rs: New test. * rust/rustc/ui/parser/macro-bad-delimiter-ident.rs: New test. * rust/rustc/ui/parser/macro-keyword.rs: New test. * rust/rustc/ui/parser/macro-mismatched-delim-brace-paren.rs: New test. * rust/rustc/ui/parser/macro-mismatched-delim-paren-brace.rs: New test. * rust/rustc/ui/parser/macro/bad-macro-argument.rs: New test. * rust/rustc/ui/parser/macro/issue-33569.rs: New test. * rust/rustc/ui/parser/macro/issue-37113.rs: New test. * rust/rustc/ui/parser/macro/issue-37234.rs: New test. * rust/rustc/ui/parser/macro/literals-are-validated-before-expansion.rs: New test. * rust/rustc/ui/parser/macro/macro-doc-comments-1.rs: New test. * rust/rustc/ui/parser/macro/macro-doc-comments-2.rs: New test. * rust/rustc/ui/parser/macro/macro-incomplete-parse.rs: New test. * rust/rustc/ui/parser/macro/macro-repeat.rs: New test. * rust/rustc/ui/parser/macro/pub-item-macro.rs: New test. * rust/rustc/ui/parser/macro/trait-non-item-macros.rs: New test. * rust/rustc/ui/parser/macro/trait-object-macro-matcher.rs: New test. * rust/rustc/ui/parser/macros-no-semicolon-items.rs: New test. * rust/rustc/ui/parser/macros-no-semicolon.rs: New test. * rust/rustc/ui/parser/match-arrows-block-then-binop.rs: New test. * rust/rustc/ui/parser/match-refactor-to-expr.rs: New test. * rust/rustc/ui/parser/mbe_missing_right_paren.rs: New test. * rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs: New test. * rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs: New test. * rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs: New test. * rust/rustc/ui/parser/mismatched-delim-brace-empty-block.rs: New test. * rust/rustc/ui/parser/missing-semicolon.rs: New test. * rust/rustc/ui/parser/missing_right_paren.rs: New test. * rust/rustc/ui/parser/mod_file_not_exist.rs: New test. * rust/rustc/ui/parser/mod_file_not_exist_windows.rs: New test. * rust/rustc/ui/parser/mod_file_with_path_attr.rs: New test. * rust/rustc/ui/parser/multiline-comment-line-tracking.rs: New test. * rust/rustc/ui/parser/multitrait.rs: New test. * rust/rustc/ui/parser/mut-patterns.rs: New test. * rust/rustc/ui/parser/new-unicode-escapes-1.rs: New test. * rust/rustc/ui/parser/new-unicode-escapes-2.rs: New test. * rust/rustc/ui/parser/new-unicode-escapes-3.rs: New test. * rust/rustc/ui/parser/new-unicode-escapes-4.rs: New test. * rust/rustc/ui/parser/no-binary-float-literal.rs: New test. * rust/rustc/ui/parser/no-const-fn-in-extern-block.rs: New test. * rust/rustc/ui/parser/no-hex-float-literal.rs: New test. * rust/rustc/ui/parser/no-unsafe-self.rs: New test. * rust/rustc/ui/parser/not-a-pred.rs: New test. * rust/rustc/ui/parser/nt-parsing-has-recovery.rs: New test. * rust/rustc/ui/parser/numeric-lifetime.rs: New test. * rust/rustc/ui/parser/omitted-arg-in-item-fn.rs: New test. * rust/rustc/ui/parser/paamayim-nekudotayim.rs: New test. * rust/rustc/ui/parser/paren-after-qualified-path-in-match.rs: New test. * rust/rustc/ui/parser/pat-lt-bracket-1.rs: New test. * rust/rustc/ui/parser/pat-lt-bracket-2.rs: New test. * rust/rustc/ui/parser/pat-lt-bracket-3.rs: New test. * rust/rustc/ui/parser/pat-lt-bracket-4.rs: New test. * rust/rustc/ui/parser/pat-lt-bracket-5.rs: New test. * rust/rustc/ui/parser/pat-lt-bracket-6.rs: New test. * rust/rustc/ui/parser/pat-lt-bracket-7.rs: New test. * rust/rustc/ui/parser/pat-ranges-1.rs: New test. * rust/rustc/ui/parser/pat-ranges-2.rs: New test. * rust/rustc/ui/parser/pat-ranges-3.rs: New test. * rust/rustc/ui/parser/pat-ranges-4.rs: New test. * rust/rustc/ui/parser/pat-ref-enum.rs: New test. * rust/rustc/ui/parser/pat-tuple-1.rs: New test. * rust/rustc/ui/parser/pat-tuple-2.rs: New test. * rust/rustc/ui/parser/pat-tuple-3.rs: New test. * rust/rustc/ui/parser/pub-method-macro.rs: New test. * rust/rustc/ui/parser/qualified-path-in-turbofish.rs: New test. * rust/rustc/ui/parser/range-3.rs: New test. * rust/rustc/ui/parser/range-4.rs: New test. * rust/rustc/ui/parser/range_inclusive.rs: New test. * rust/rustc/ui/parser/range_inclusive_dotdotdot.rs: New test. * rust/rustc/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs: New test. * rust/rustc/ui/parser/raw/raw-byte-string-eof.rs: New test. * rust/rustc/ui/parser/raw/raw-byte-string-literals.rs: New test. * rust/rustc/ui/parser/raw/raw-literal-keywords.rs: New test. * rust/rustc/ui/parser/raw/raw-literal-self.rs: New test. * rust/rustc/ui/parser/raw/raw-literal-underscore.rs: New test. * rust/rustc/ui/parser/raw/raw-str-delim.rs: New test. * rust/rustc/ui/parser/raw/raw-str-in-macro-call.rs: New test. * rust/rustc/ui/parser/raw/raw-str-unbalanced.rs: New test. * rust/rustc/ui/parser/raw/raw-str-unterminated.rs: New test. * rust/rustc/ui/parser/raw/raw-string-2.rs: New test. * rust/rustc/ui/parser/raw/raw-string.rs: New test. * rust/rustc/ui/parser/recover-assoc-const-constraint.rs: New test. * rust/rustc/ui/parser/recover-assoc-eq-missing-term.rs: New test. * rust/rustc/ui/parser/recover-assoc-lifetime-constraint.rs: New test. * rust/rustc/ui/parser/recover-const-async-fn-ptr.rs: New test. * rust/rustc/ui/parser/recover-enum.rs: New test. * rust/rustc/ui/parser/recover-enum2.rs: New test. * rust/rustc/ui/parser/recover-field-extra-angle-brackets.rs: New test. * rust/rustc/ui/parser/recover-for-loop-parens-around-head.rs: New test. * rust/rustc/ui/parser/recover-from-bad-variant.rs: New test. * rust/rustc/ui/parser/recover-from-homoglyph.rs: New test. * rust/rustc/ui/parser/recover-labeled-non-block-expr.rs: New test. * rust/rustc/ui/parser/recover-missing-semi.rs: New test. * rust/rustc/ui/parser/recover-quantified-closure.rs: New test. * rust/rustc/ui/parser/recover-range-pats.rs: New test. * rust/rustc/ui/parser/recover-struct.rs: New test. * rust/rustc/ui/parser/recover-tuple-pat.rs: New test. * rust/rustc/ui/parser/recover-tuple.rs: New test. * rust/rustc/ui/parser/recovered-struct-variant.rs: New test. * rust/rustc/ui/parser/regions-out-of-scope-slice.rs: New test. * rust/rustc/ui/parser/removed-syntax-closure-lifetime.rs: New test. * rust/rustc/ui/parser/removed-syntax-enum-newtype.rs: New test. * rust/rustc/ui/parser/removed-syntax-field-let.rs: New test. * rust/rustc/ui/parser/removed-syntax-field-semicolon.rs: New test. * rust/rustc/ui/parser/removed-syntax-fixed-vec.rs: New test. * rust/rustc/ui/parser/removed-syntax-fn-sigil.rs: New test. * rust/rustc/ui/parser/removed-syntax-mode.rs: New test. * rust/rustc/ui/parser/removed-syntax-mut-vec-expr.rs: New test. * rust/rustc/ui/parser/removed-syntax-mut-vec-ty.rs: New test. * rust/rustc/ui/parser/removed-syntax-ptr-lifetime.rs: New test. * rust/rustc/ui/parser/removed-syntax-record.rs: New test. * rust/rustc/ui/parser/removed-syntax-static-fn.rs: New test. * rust/rustc/ui/parser/removed-syntax-uniq-mut-expr.rs: New test. * rust/rustc/ui/parser/removed-syntax-uniq-mut-ty.rs: New test. * rust/rustc/ui/parser/removed-syntax-with-1.rs: New test. * rust/rustc/ui/parser/removed-syntax-with-2.rs: New test. * rust/rustc/ui/parser/require-parens-for-chained-comparison.rs: New test. * rust/rustc/ui/parser/self-in-function-arg.rs: New test. * rust/rustc/ui/parser/self-param-semantic-fail.rs: New test. * rust/rustc/ui/parser/self-param-syntactic-pass.rs: New test. * rust/rustc/ui/parser/several-carriage-returns-in-doc-comment.rs: New test. * rust/rustc/ui/parser/shebang/issue-71471-ignore-tidy.rs: New test. * rust/rustc/ui/parser/shebang/multiline-attrib.rs: New test. * rust/rustc/ui/parser/shebang/regular-attrib.rs: New test. * rust/rustc/ui/parser/shebang/shebang-and-attrib.rs: New test. * rust/rustc/ui/parser/shebang/shebang-comment.rs: New test. * rust/rustc/ui/parser/shebang/shebang-doc-comment.rs: New test. * rust/rustc/ui/parser/shebang/shebang-empty.rs: New test. * rust/rustc/ui/parser/shebang/shebang-must-start-file.rs: New test. * rust/rustc/ui/parser/shebang/shebang-space.rs: New test. * rust/rustc/ui/parser/shebang/sneaky-attrib.rs: New test. * rust/rustc/ui/parser/shebang/valid-shebang.rs: New test. * rust/rustc/ui/parser/stmt_expr_attrs_placement.rs: New test. * rust/rustc/ui/parser/stripped-nested-outline-mod-pass.rs: New test. * rust/rustc/ui/parser/struct-field-numeric-shorthand.rs: New test. * rust/rustc/ui/parser/struct-literal-in-for.rs: New test. * rust/rustc/ui/parser/struct-literal-in-if.rs: New test. * rust/rustc/ui/parser/struct-literal-in-match-discriminant.rs: New test. * rust/rustc/ui/parser/struct-literal-in-match-guard.rs: New test. * rust/rustc/ui/parser/struct-literal-in-while.rs: New test. * rust/rustc/ui/parser/struct-literal-restrictions-in-lamda.rs: New test. * rust/rustc/ui/parser/tag-variant-disr-non-nullary.rs: New test. * rust/rustc/ui/parser/trailing-carriage-return-in-string.rs: New test. * rust/rustc/ui/parser/trailing-plus-in-bounds.rs: New test. * rust/rustc/ui/parser/trait-bounds-not-on-impl.rs: New test. * rust/rustc/ui/parser/trait-item-with-defaultness-fail-semantic.rs: New test. * rust/rustc/ui/parser/trait-item-with-defaultness-pass.rs: New test. * rust/rustc/ui/parser/trait-object-bad-parens.rs: New test. * rust/rustc/ui/parser/trait-object-lifetime-parens.rs: New test. * rust/rustc/ui/parser/trait-object-polytrait-priority.rs: New test. * rust/rustc/ui/parser/trait-object-trait-parens.rs: New test. * rust/rustc/ui/parser/trait-plusequal-splitting.rs: New test. * rust/rustc/ui/parser/trait-pub-assoc-const.rs: New test. * rust/rustc/ui/parser/trait-pub-assoc-ty.rs: New test. * rust/rustc/ui/parser/trait-pub-method.rs: New test. * rust/rustc/ui/parser/type-parameters-in-field-exprs.rs: New test. * rust/rustc/ui/parser/unbalanced-doublequote.rs: New test. * rust/rustc/ui/parser/unclosed-braces.rs: New test. * rust/rustc/ui/parser/unclosed-delimiter-in-dep.rs: New test. * rust/rustc/ui/parser/unclosed_delim_mod.rs: New test. * rust/rustc/ui/parser/underscore-suffix-for-float.rs: New test. * rust/rustc/ui/parser/underscore-suffix-for-string.rs: New test. * rust/rustc/ui/parser/underscore_item_not_const.rs: New test. * rust/rustc/ui/parser/unicode-chars.rs: New test. * rust/rustc/ui/parser/unicode-quote-chars.rs: New test. * rust/rustc/ui/parser/unmatched-delimiter-at-end-of-file.rs: New test. * rust/rustc/ui/parser/unsafe-foreign-mod.rs: New test. * rust/rustc/ui/parser/unsafe-mod.rs: New test. * rust/rustc/ui/parser/unsized.rs: New test. * rust/rustc/ui/parser/unsized2.rs: New test. * rust/rustc/ui/parser/use-as-where-use-ends-with-mod-sep.rs: New test. * rust/rustc/ui/parser/use-ends-with-mod-sep.rs: New test. * rust/rustc/ui/parser/variadic-ffi-nested-syntactic-fail.rs: New test. * rust/rustc/ui/parser/variadic-ffi-semantic-restrictions.rs: New test. * rust/rustc/ui/parser/variadic-ffi-syntactic-pass.rs: New test. * rust/rustc/ui/parser/virtual-structs.rs: New test. * rust/rustc/ui/parser/where-clauses-no-bounds-or-predicates.rs: New test. * rust/rustc/ui/parser/where_with_bound.rs: New test. * rust/rustc/ui/parser/wrong-escape-of-curly-braces.rs: New test. * rust/rustc/ui/partialeq_help.rs: New test. * rust/rustc/ui/path-lookahead.rs: New test. * rust/rustc/ui/path.rs: New test. * rust/rustc/ui/pathless-extern-ok.rs: New test. * rust/rustc/ui/paths-containing-nul.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/bind-by-copy.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/borrowck-move-and-move.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/box-patterns.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/copy-and-move-mixed.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/nested-binding-mode-lint.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/nested-binding-modes-mut.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/nested-binding-modes-ref.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/nested-patterns.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/or-patterns-box-patterns.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/or-patterns.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/pat-at-same-name-both.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/slice-patterns.rs: New test. * rust/rustc/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.rs: New test. * rust/rustc/ui/pattern/const-pat-ice.rs: New test. * rust/rustc/ui/pattern/deny-irrefutable-let-patterns.rs: New test. * rust/rustc/ui/pattern/irrefutable-let-patterns.rs: New test. * rust/rustc/ui/pattern/issue-66270-pat-struct-parser-recovery.rs: New test. * rust/rustc/ui/pattern/issue-66501.rs: New test. * rust/rustc/ui/pattern/issue-67776-match-same-name-enum-variant-refs.rs: New test. * rust/rustc/ui/pattern/issue-68393-let-pat-assoc-constant.rs: New test. * rust/rustc/ui/pattern/issue-68394-let-pat-runtime-value.rs: New test. * rust/rustc/ui/pattern/issue-68396-let-float-bug.rs: New test. * rust/rustc/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs: New test. * rust/rustc/ui/pattern/issue-72565.rs: New test. * rust/rustc/ui/pattern/issue-74539.rs: New test. * rust/rustc/ui/pattern/issue-74702.rs: New test. * rust/rustc/ui/pattern/issue-74954.rs: New test. * rust/rustc/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs: New test. * rust/rustc/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs: New test. * rust/rustc/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs: New test. * rust/rustc/ui/pattern/move-ref-patterns/issue-53840.rs: New test. * rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs: New test. * rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs: New test. * rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs: New test. * rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs: New test. * rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs: New test. * rust/rustc/ui/pattern/pat-shadow-in-nested-binding.rs: New test. * rust/rustc/ui/pattern/pat-struct-field-expr-has-type.rs: New test. * rust/rustc/ui/pattern/pat-tuple-bad-type.rs: New test. * rust/rustc/ui/pattern/pat-tuple-overfield.rs: New test. * rust/rustc/ui/pattern/pat-type-err-formal-param.rs: New test. * rust/rustc/ui/pattern/pat-type-err-let-stmt.rs: New test. * rust/rustc/ui/pattern/patkind-litrange-no-expr.rs: New test. * rust/rustc/ui/pattern/pattern-binding-disambiguation.rs: New test. * rust/rustc/ui/pattern/pattern-error-continue.rs: New test. * rust/rustc/ui/pattern/pattern-ident-path-generics.rs: New test. * rust/rustc/ui/pattern/pattern-tyvar-2.rs: New test. * rust/rustc/ui/pattern/pattern-tyvar.rs: New test. * rust/rustc/ui/pattern/rest-pat-semantic-disallowed.rs: New test. * rust/rustc/ui/pattern/rest-pat-syntactic.rs: New test. * rust/rustc/ui/pattern/usefulness/always-inhabited-union-ref.rs: New test. * rust/rustc/ui/pattern/usefulness/consts-opaque.rs: New test. * rust/rustc/ui/pattern/usefulness/exhaustive_integer_patterns.rs: New test. * rust/rustc/ui/pattern/usefulness/guards-not-exhaustive.rs: New test. * rust/rustc/ui/pattern/usefulness/irrefutable-exhaustive-integer-binding.rs: New test. * rust/rustc/ui/pattern/usefulness/irrefutable-unit.rs: New test. * rust/rustc/ui/pattern/usefulness/issue-35609.rs: New test. * rust/rustc/ui/pattern/usefulness/issue-43253.rs: New test. * rust/rustc/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs: New test. * rust/rustc/ui/pattern/usefulness/issue-65413-constants-and-slices-exhaustiveness.rs: New test. * rust/rustc/ui/pattern/usefulness/issue-71930-type-of-match-scrutinee.rs: New test. * rust/rustc/ui/pattern/usefulness/issue-72476-associated-type.rs: New test. * rust/rustc/ui/pattern/usefulness/issue-78549-ref-pat-and-str.rs: New test. * rust/rustc/ui/pattern/usefulness/match-arm-statics-2.rs: New test. * rust/rustc/ui/pattern/usefulness/match-arm-statics.rs: New test. * rust/rustc/ui/pattern/usefulness/match-byte-array-patterns-2.rs: New test. * rust/rustc/ui/pattern/usefulness/match-byte-array-patterns.rs: New test. * rust/rustc/ui/pattern/usefulness/match-empty-exhaustive_patterns.rs: New test. * rust/rustc/ui/pattern/usefulness/match-empty.rs: New test. * rust/rustc/ui/pattern/usefulness/match-non-exhaustive.rs: New test. * rust/rustc/ui/pattern/usefulness/match-privately-empty.rs: New test. * rust/rustc/ui/pattern/usefulness/match-range-fail-dominate.rs: New test. * rust/rustc/ui/pattern/usefulness/match-ref-ice.rs: New test. * rust/rustc/ui/pattern/usefulness/match-slice-patterns.rs: New test. * rust/rustc/ui/pattern/usefulness/match-vec-fixed.rs: New test. * rust/rustc/ui/pattern/usefulness/match-vec-unreachable.rs: New test. * rust/rustc/ui/pattern/usefulness/nested-exhaustive-match.rs: New test. * rust/rustc/ui/pattern/usefulness/non-exhaustive-defined-here.rs: New test. * rust/rustc/ui/pattern/usefulness/non-exhaustive-float-range-match.rs: New test. * rust/rustc/ui/pattern/usefulness/non-exhaustive-match-nested.rs: New test. * rust/rustc/ui/pattern/usefulness/non-exhaustive-match.rs: New test. * rust/rustc/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.rs: New test. * rust/rustc/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs: New test. * rust/rustc/ui/pattern/usefulness/refutable-pattern-errors.rs: New test. * rust/rustc/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs: New test. * rust/rustc/ui/pattern/usefulness/slice-pattern-const-2.rs: New test. * rust/rustc/ui/pattern/usefulness/slice-pattern-const-3.rs: New test. * rust/rustc/ui/pattern/usefulness/slice-pattern-const.rs: New test. * rust/rustc/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs: New test. * rust/rustc/ui/pattern/usefulness/slice-patterns-irrefutable.rs: New test. * rust/rustc/ui/pattern/usefulness/slice-patterns-reachability.rs: New test. * rust/rustc/ui/pattern/usefulness/struct-like-enum-nonexhaustive.rs: New test. * rust/rustc/ui/pattern/usefulness/struct-pattern-match-useless.rs: New test. * rust/rustc/ui/pattern/usefulness/top-level-alternation.rs: New test. * rust/rustc/ui/pattern/usefulness/tuple-struct-nonexhaustive.rs: New test. * rust/rustc/ui/phantom-oibit.rs: New test. * rust/rustc/ui/placement-syntax.rs: New test. * rust/rustc/ui/point-to-type-err-cause-on-impl-trait-return-2.rs: New test. * rust/rustc/ui/point-to-type-err-cause-on-impl-trait-return.rs: New test. * rust/rustc/ui/polymorphization/closure_in_upvar/fn.rs: New test. * rust/rustc/ui/polymorphization/closure_in_upvar/fnmut.rs: New test. * rust/rustc/ui/polymorphization/closure_in_upvar/fnonce.rs: New test. * rust/rustc/ui/polymorphization/closure_in_upvar/other.rs: New test. * rust/rustc/ui/polymorphization/const_parameters/closures.rs: New test. * rust/rustc/ui/polymorphization/const_parameters/functions.rs: New test. * rust/rustc/ui/polymorphization/drop_shims/simple.rs: New test. * rust/rustc/ui/polymorphization/drop_shims/transitive.rs: New test. * rust/rustc/ui/polymorphization/generators.rs: New test. * rust/rustc/ui/polymorphization/issue-74636.rs: New test. * rust/rustc/ui/polymorphization/lifetimes.rs: New test. * rust/rustc/ui/polymorphization/normalized_sig_types.rs: New test. * rust/rustc/ui/polymorphization/predicates.rs: New test. * rust/rustc/ui/polymorphization/promoted-function-1.rs: New test. * rust/rustc/ui/polymorphization/promoted-function-2.rs: New test. * rust/rustc/ui/polymorphization/promoted-function-3.rs: New test. * rust/rustc/ui/polymorphization/promoted-function.rs: New test. * rust/rustc/ui/polymorphization/symbol-ambiguity.rs: New test. * rust/rustc/ui/polymorphization/too-many-generic-params.rs: New test. * rust/rustc/ui/polymorphization/type_parameters/closures.rs: New test. * rust/rustc/ui/polymorphization/type_parameters/functions.rs: New test. * rust/rustc/ui/polymorphization/unsized_cast.rs: New test. * rust/rustc/ui/pptypedef.rs: New test. * rust/rustc/ui/precise_pointer_size_matching.rs: New test. * rust/rustc/ui/prim-with-args.rs: New test. * rust/rustc/ui/primitive-binop-lhs-mut.rs: New test. * rust/rustc/ui/print-fuel/print-fuel.rs: New test. * rust/rustc/ui/print-stdout-eprint-stderr.rs: New test. * rust/rustc/ui/print_type_sizes/anonymous.rs: New test. * rust/rustc/ui/print_type_sizes/generics.rs: New test. * rust/rustc/ui/print_type_sizes/multiple_types.rs: New test. * rust/rustc/ui/print_type_sizes/niche-filling.rs: New test. * rust/rustc/ui/print_type_sizes/no_duplicates.rs: New test. * rust/rustc/ui/print_type_sizes/packed.rs: New test. * rust/rustc/ui/print_type_sizes/padding.rs: New test. * rust/rustc/ui/print_type_sizes/repr-align.rs: New test. * rust/rustc/ui/print_type_sizes/repr_int_c.rs: New test. * rust/rustc/ui/print_type_sizes/uninhabited.rs: New test. * rust/rustc/ui/print_type_sizes/variants.rs: New test. * rust/rustc/ui/print_type_sizes/zero-sized-fields.rs: New test. * rust/rustc/ui/priv-in-bad-locations.rs: New test. * rust/rustc/ui/privacy/associated-item-privacy-inherent.rs: New test. * rust/rustc/ui/privacy/associated-item-privacy-trait.rs: New test. * rust/rustc/ui/privacy/associated-item-privacy-type-binding.rs: New test. * rust/rustc/ui/privacy/auxiliary/cci_class.rs: New test. * rust/rustc/ui/privacy/auxiliary/cci_class_5.rs: New test. * rust/rustc/ui/privacy/auxiliary/issue-57264-1.rs: New test. * rust/rustc/ui/privacy/auxiliary/issue-57264-2.rs: New test. * rust/rustc/ui/privacy/auxiliary/priv-impl-prim-ty.rs: New test. * rust/rustc/ui/privacy/auxiliary/privacy_reexport.rs: New test. * rust/rustc/ui/privacy/auxiliary/privacy_tuple_struct.rs: New test. * rust/rustc/ui/privacy/auxiliary/private-inferred-type.rs: New test. * rust/rustc/ui/privacy/auxiliary/pub_use_mods_xcrate.rs: New test. * rust/rustc/ui/privacy/auxiliary/pub_use_xcrate1.rs: New test. * rust/rustc/ui/privacy/auxiliary/pub_use_xcrate2.rs: New test. * rust/rustc/ui/privacy/decl-macro.rs: New test. * rust/rustc/ui/privacy/issue-57264-1.rs: New test. * rust/rustc/ui/privacy/issue-57264-2.rs: New test. * rust/rustc/ui/privacy/issue-75062-fieldless-tuple-struct.rs: New test. * rust/rustc/ui/privacy/legacy-ctor-visibility.rs: New test. * rust/rustc/ui/privacy/priv-impl-prim-ty.rs: New test. * rust/rustc/ui/privacy/privacy-in-paths.rs: New test. * rust/rustc/ui/privacy/privacy-ns.rs: New test. * rust/rustc/ui/privacy/privacy-ns1.rs: New test. * rust/rustc/ui/privacy/privacy-ns2.rs: New test. * rust/rustc/ui/privacy/privacy-reexport.rs: New test. * rust/rustc/ui/privacy/privacy-sanity.rs: New test. * rust/rustc/ui/privacy/privacy-ufcs.rs: New test. * rust/rustc/ui/privacy/privacy1-rpass.rs: New test. * rust/rustc/ui/privacy/privacy1.rs: New test. * rust/rustc/ui/privacy/privacy2.rs: New test. * rust/rustc/ui/privacy/privacy3.rs: New test. * rust/rustc/ui/privacy/privacy4.rs: New test. * rust/rustc/ui/privacy/privacy5.rs: New test. * rust/rustc/ui/privacy/private-class-field.rs: New test. * rust/rustc/ui/privacy/private-impl-method.rs: New test. * rust/rustc/ui/privacy/private-in-public-assoc-ty.rs: New test. * rust/rustc/ui/privacy/private-in-public-expr-pat.rs: New test. * rust/rustc/ui/privacy/private-in-public-ill-formed.rs: New test. * rust/rustc/ui/privacy/private-in-public-lint.rs: New test. * rust/rustc/ui/privacy/private-in-public-non-principal-2.rs: New test. * rust/rustc/ui/privacy/private-in-public-non-principal.rs: New test. * rust/rustc/ui/privacy/private-in-public-type-alias-impl-trait.rs: New test. * rust/rustc/ui/privacy/private-in-public-warn.rs: New test. * rust/rustc/ui/privacy/private-in-public.rs: New test. * rust/rustc/ui/privacy/private-inferred-type-1.rs: New test. * rust/rustc/ui/privacy/private-inferred-type-2.rs: New test. * rust/rustc/ui/privacy/private-inferred-type-3.rs: New test. * rust/rustc/ui/privacy/private-inferred-type.rs: New test. * rust/rustc/ui/privacy/private-item-simple.rs: New test. * rust/rustc/ui/privacy/private-method-cross-crate.rs: New test. * rust/rustc/ui/privacy/private-method-inherited.rs: New test. * rust/rustc/ui/privacy/private-method-rpass.rs: New test. * rust/rustc/ui/privacy/private-method.rs: New test. * rust/rustc/ui/privacy/private-struct-field-cross-crate.rs: New test. * rust/rustc/ui/privacy/private-struct-field-ctor.rs: New test. * rust/rustc/ui/privacy/private-struct-field-pattern.rs: New test. * rust/rustc/ui/privacy/private-struct-field.rs: New test. * rust/rustc/ui/privacy/private-type-in-interface.rs: New test. * rust/rustc/ui/privacy/private-variant-reexport.rs: New test. * rust/rustc/ui/privacy/pub-extern-privacy.rs: New test. * rust/rustc/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs: New test. * rust/rustc/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs: New test. * rust/rustc/ui/privacy/pub-priv-dep/pub-priv1.rs: New test. * rust/rustc/ui/privacy/pub-priv-dep/std-pub.rs: New test. * rust/rustc/ui/privacy/pub-use-xcrate.rs: New test. * rust/rustc/ui/privacy/pub_use_mods_xcrate_exe.rs: New test. * rust/rustc/ui/privacy/restricted/auxiliary/pub_restricted.rs: New test. * rust/rustc/ui/privacy/restricted/lookup-ignores-private.rs: New test. * rust/rustc/ui/privacy/restricted/private-in-public.rs: New test. * rust/rustc/ui/privacy/restricted/relative-2018.rs: New test. * rust/rustc/ui/privacy/restricted/struct-literal-field.rs: New test. * rust/rustc/ui/privacy/restricted/test.rs: New test. * rust/rustc/ui/privacy/union-field-privacy-1.rs: New test. * rust/rustc/ui/privacy/union-field-privacy-2.rs: New test. * rust/rustc/ui/proc-macro/add-impl.rs: New test. * rust/rustc/ui/proc-macro/ambiguous-builtin-attrs-test.rs: New test. * rust/rustc/ui/proc-macro/ambiguous-builtin-attrs.rs: New test. * rust/rustc/ui/proc-macro/append-impl.rs: New test. * rust/rustc/ui/proc-macro/attr-args.rs: New test. * rust/rustc/ui/proc-macro/attr-cfg.rs: New test. * rust/rustc/ui/proc-macro/attr-invalid-exprs.rs: New test. * rust/rustc/ui/proc-macro/attr-on-trait.rs: New test. * rust/rustc/ui/proc-macro/attr-stmt-expr-rpass.rs: New test. * rust/rustc/ui/proc-macro/attr-stmt-expr.rs: New test. * rust/rustc/ui/proc-macro/attribute-order-restricted.rs: New test. * rust/rustc/ui/proc-macro/attribute-spans-preserved.rs: New test. * rust/rustc/ui/proc-macro/attribute-with-error.rs: New test. * rust/rustc/ui/proc-macro/attribute.rs: New test. * rust/rustc/ui/proc-macro/attributes-included.rs: New test. * rust/rustc/ui/proc-macro/attributes-on-definitions.rs: New test. * rust/rustc/ui/proc-macro/attributes-on-modules-fail.rs: New test. * rust/rustc/ui/proc-macro/attributes-on-modules.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/add-impl.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/append-impl.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/attr-args.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/attr-cfg.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/attr-on-trait.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/attr-stmt-expr.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/attribute-spans-preserved.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/attributes-included.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/attributes-on-definitions.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/bang-macro.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/bang_proc_macro2.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/builtin-attrs.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/call-site.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/count_compound_ops.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-a.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-atob.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-attr-cfg.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-b-rpass.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-b.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-bad.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-clona.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-ctod.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-foo.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowed-2.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowing.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-nothing.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-same-struct.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-two-attrs.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-union.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-unstable-2.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/derive-unstable.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/dollar-crate-external.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/double.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/duplicate.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/edition-imports-2015.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/empty-crate.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/expand-with-a-macro.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/external-crate-var.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/first-second.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/gen-lifetime-token.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/gen-macro-rules-hygiene.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/gen-macro-rules.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/generate-dollar-ident.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/generate-mod.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/hygiene_example.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/hygiene_example_codegen.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/invalid-punct-ident.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/is-available.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/issue-38586.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/issue-39889.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/issue-42708.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/issue-50061.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/issue-50493.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/issue-59191.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/lifetimes-rpass.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/lifetimes.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/macro-only-syntax.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/make-macro.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/meta-delim.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/meta-macro.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/mixed-site-span.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/modify-ast.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/multispan.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/negative-token.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/nested-macro-rules.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/not-joint.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/parent-source-spans.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/raw-ident.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/recollect.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/resolved-located-at.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/span-api-tests.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/span-test-macros.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/subspan.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/test-macros.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/three-equals.rs: New test. * rust/rustc/ui/proc-macro/auxiliary/weird-hygiene.rs: New test. * rust/rustc/ui/proc-macro/bang-macro.rs: New test. * rust/rustc/ui/proc-macro/break-token-spans.rs: New test. * rust/rustc/ui/proc-macro/call-site.rs: New test. * rust/rustc/ui/proc-macro/capture-macro-rules-invoke.rs: New test. * rust/rustc/ui/proc-macro/count_compound_ops.rs: New test. * rust/rustc/ui/proc-macro/crate-var.rs: New test. * rust/rustc/ui/proc-macro/crt-static.rs: New test. * rust/rustc/ui/proc-macro/custom-attr-only-one-derive.rs: New test. * rust/rustc/ui/proc-macro/debug/auxiliary/macro-dump-debug.rs: New test. * rust/rustc/ui/proc-macro/debug/dump-debug-span-debug.rs: New test. * rust/rustc/ui/proc-macro/debug/dump-debug.rs: New test. * rust/rustc/ui/proc-macro/define-two.rs: New test. * rust/rustc/ui/proc-macro/derive-attr-cfg.rs: New test. * rust/rustc/ui/proc-macro/derive-b.rs: New test. * rust/rustc/ui/proc-macro/derive-bad.rs: New test. * rust/rustc/ui/proc-macro/derive-helper-configured.rs: New test. * rust/rustc/ui/proc-macro/derive-helper-shadowed.rs: New test. * rust/rustc/ui/proc-macro/derive-helper-shadowing-2.rs: New test. * rust/rustc/ui/proc-macro/derive-helper-shadowing.rs: New test. * rust/rustc/ui/proc-macro/derive-in-mod.rs: New test. * rust/rustc/ui/proc-macro/derive-same-struct.rs: New test. * rust/rustc/ui/proc-macro/derive-still-gated.rs: New test. * rust/rustc/ui/proc-macro/derive-test.rs: New test. * rust/rustc/ui/proc-macro/derive-two-attrs.rs: New test. * rust/rustc/ui/proc-macro/derive-union.rs: New test. * rust/rustc/ui/proc-macro/disappearing-resolution.rs: New test. * rust/rustc/ui/proc-macro/doc-comment-preserved.rs: New test. * rust/rustc/ui/proc-macro/dollar-crate-issue-57089.rs: New test. * rust/rustc/ui/proc-macro/dollar-crate-issue-62325.rs: New test. * rust/rustc/ui/proc-macro/dollar-crate.rs: New test. * rust/rustc/ui/proc-macro/edition-imports-2018.rs: New test. * rust/rustc/ui/proc-macro/empty-crate.rs: New test. * rust/rustc/ui/proc-macro/empty-where-clause.rs: New test. * rust/rustc/ui/proc-macro/expand-to-unstable-2.rs: New test. * rust/rustc/ui/proc-macro/expand-to-unstable.rs: New test. * rust/rustc/ui/proc-macro/expand-with-a-macro.rs: New test. * rust/rustc/ui/proc-macro/export-macro.rs: New test. * rust/rustc/ui/proc-macro/exports.rs: New test. * rust/rustc/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs: New test. * rust/rustc/ui/proc-macro/gen-lifetime-token.rs: New test. * rust/rustc/ui/proc-macro/gen-macro-rules-hygiene.rs: New test. * rust/rustc/ui/proc-macro/gen-macro-rules.rs: New test. * rust/rustc/ui/proc-macro/generate-dollar-ident.rs: New test. * rust/rustc/ui/proc-macro/generate-mod.rs: New test. * rust/rustc/ui/proc-macro/group-compat-hack/actix-web-2.0.0/src/extract.rs: New test. * rust/rustc/ui/proc-macro/group-compat-hack/actix-web/src/extract.rs: New test. * rust/rustc/ui/proc-macro/group-compat-hack/actori-web-2.0.0/src/extract.rs: New test. * rust/rustc/ui/proc-macro/group-compat-hack/actori-web/src/extract.rs: New test. * rust/rustc/ui/proc-macro/group-compat-hack/auxiliary/group-compat-hack.rs: New test. * rust/rustc/ui/proc-macro/group-compat-hack/group-compat-hack.rs: New test. * rust/rustc/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs: New test. * rust/rustc/ui/proc-macro/group-compat-hack/js-sys/src/lib.rs: New test. * rust/rustc/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs: New test. * rust/rustc/ui/proc-macro/group-compat-hack/time-macros-impl/src/lib.rs: New test. * rust/rustc/ui/proc-macro/helper-attr-blocked-by-import-ambig.rs: New test. * rust/rustc/ui/proc-macro/helper-attr-blocked-by-import.rs: New test. * rust/rustc/ui/proc-macro/hygiene_example.rs: New test. * rust/rustc/ui/proc-macro/illegal-proc-macro-derive-use.rs: New test. * rust/rustc/ui/proc-macro/import.rs: New test. * rust/rustc/ui/proc-macro/input-interpolated.rs: New test. * rust/rustc/ui/proc-macro/invalid-attributes.rs: New test. * rust/rustc/ui/proc-macro/invalid-punct-ident-1.rs: New test. * rust/rustc/ui/proc-macro/invalid-punct-ident-2.rs: New test. * rust/rustc/ui/proc-macro/invalid-punct-ident-3.rs: New test. * rust/rustc/ui/proc-macro/invalid-punct-ident-4.rs: New test. * rust/rustc/ui/proc-macro/is-available.rs: New test. * rust/rustc/ui/proc-macro/issue-36935.rs: New test. * rust/rustc/ui/proc-macro/issue-37788.rs: New test. * rust/rustc/ui/proc-macro/issue-38586.rs: New test. * rust/rustc/ui/proc-macro/issue-39889.rs: New test. * rust/rustc/ui/proc-macro/issue-41211.rs: New test. * rust/rustc/ui/proc-macro/issue-42708.rs: New test. * rust/rustc/ui/proc-macro/issue-50061.rs: New test. * rust/rustc/ui/proc-macro/issue-50493.rs: New test. * rust/rustc/ui/proc-macro/issue-53481.rs: New test. * rust/rustc/ui/proc-macro/issue-59191-replace-root-with-fn.rs: New test. * rust/rustc/ui/proc-macro/issue-75734-pp-paren.rs: New test. * rust/rustc/ui/proc-macro/issue-75930-derive-cfg.rs: New test. * rust/rustc/ui/proc-macro/issue-76182-leading-vert-pat.rs: New test. * rust/rustc/ui/proc-macro/issue-78675-captured-inner-attrs.rs: New test. * rust/rustc/ui/proc-macro/item-error.rs: New test. * rust/rustc/ui/proc-macro/keep-expr-tokens.rs: New test. * rust/rustc/ui/proc-macro/lifetimes-rpass.rs: New test. * rust/rustc/ui/proc-macro/lifetimes.rs: New test. * rust/rustc/ui/proc-macro/lints_in_proc_macros.rs: New test. * rust/rustc/ui/proc-macro/load-panic-backtrace.rs: New test. * rust/rustc/ui/proc-macro/load-panic.rs: New test. * rust/rustc/ui/proc-macro/load-two.rs: New test. * rust/rustc/ui/proc-macro/macro-brackets.rs: New test. * rust/rustc/ui/proc-macro/macro-crate-multi-decorator.rs: New test. * rust/rustc/ui/proc-macro/macro-namespace-reserved-2.rs: New test. * rust/rustc/ui/proc-macro/macro-namespace-reserved.rs: New test. * rust/rustc/ui/proc-macro/macro-rules-derive.rs: New test. * rust/rustc/ui/proc-macro/macro-use-attr.rs: New test. * rust/rustc/ui/proc-macro/macro-use-bang.rs: New test. * rust/rustc/ui/proc-macro/macros-in-extern-derive.rs: New test. * rust/rustc/ui/proc-macro/macros-in-extern.rs: New test. * rust/rustc/ui/proc-macro/macros-in-type.rs: New test. * rust/rustc/ui/proc-macro/meta-delim.rs: New test. * rust/rustc/ui/proc-macro/meta-macro-hygiene.rs: New test. * rust/rustc/ui/proc-macro/meta-macro.rs: New test. * rust/rustc/ui/proc-macro/mixed-site-span.rs: New test. * rust/rustc/ui/proc-macro/modify-ast.rs: New test. * rust/rustc/ui/proc-macro/module.rs: New test. * rust/rustc/ui/proc-macro/multispan.rs: New test. * rust/rustc/ui/proc-macro/negative-token.rs: New test. * rust/rustc/ui/proc-macro/nested-item-spans.rs: New test. * rust/rustc/ui/proc-macro/nested-macro-rules.rs: New test. * rust/rustc/ui/proc-macro/nested-nonterminal-tokens.rs: New test. * rust/rustc/ui/proc-macro/no-macro-use-attr.rs: New test. * rust/rustc/ui/proc-macro/no-missing-docs.rs: New test. * rust/rustc/ui/proc-macro/nodelim-groups.rs: New test. * rust/rustc/ui/proc-macro/non-root.rs: New test. * rust/rustc/ui/proc-macro/nonterminal-expansion.rs: New test. * rust/rustc/ui/proc-macro/nonterminal-token-hygiene.rs: New test. * rust/rustc/ui/proc-macro/not-joint.rs: New test. * rust/rustc/ui/proc-macro/out-of-line-mod.rs: New test. * rust/rustc/ui/proc-macro/outer/inner.rs: New test. * rust/rustc/ui/proc-macro/parent-source-spans.rs: New test. * rust/rustc/ui/proc-macro/proc-macro-attributes.rs: New test. * rust/rustc/ui/proc-macro/proc-macro-deprecated-attr.rs: New test. * rust/rustc/ui/proc-macro/proc-macro-gates.rs: New test. * rust/rustc/ui/proc-macro/proc-macro-gates2.rs: New test. * rust/rustc/ui/proc-macro/pub-at-crate-root.rs: New test. * rust/rustc/ui/proc-macro/raw-ident.rs: New test. * rust/rustc/ui/proc-macro/reserved-macro-names.rs: New test. * rust/rustc/ui/proc-macro/resolve-error.rs: New test. * rust/rustc/ui/proc-macro/resolved-located-at.rs: New test. * rust/rustc/ui/proc-macro/shadow.rs: New test. * rust/rustc/ui/proc-macro/signature.rs: New test. * rust/rustc/ui/proc-macro/smoke.rs: New test. * rust/rustc/ui/proc-macro/span-api-tests.rs: New test. * rust/rustc/ui/proc-macro/span-preservation.rs: New test. * rust/rustc/ui/proc-macro/struct-field-macro.rs: New test. * rust/rustc/ui/proc-macro/subspan.rs: New test. * rust/rustc/ui/proc-macro/three-equals.rs: New test. * rust/rustc/ui/proc-macro/trailing-plus.rs: New test. * rust/rustc/ui/proc-macro/trait-fn-args-2015.rs: New test. * rust/rustc/ui/proc-macro/two-crate-types-1.rs: New test. * rust/rustc/ui/proc-macro/two-crate-types-2.rs: New test. * rust/rustc/ui/proc-macro/unsafe-foreign-mod.rs: New test. * rust/rustc/ui/proc-macro/unsafe-mod.rs: New test. * rust/rustc/ui/proc-macro/visibility-path.rs: New test. * rust/rustc/ui/proc-macro/weird-hygiene.rs: New test. * rust/rustc/ui/proc_macro.rs: New test. * rust/rustc/ui/process-termination/process-termination-blocking-io.rs: New test. * rust/rustc/ui/process-termination/process-termination-simple.rs: New test. * rust/rustc/ui/process/process-envs.rs: New test. * rust/rustc/ui/process/process-exit.rs: New test. * rust/rustc/ui/process/process-remove-from-env.rs: New test. * rust/rustc/ui/process/process-sigpipe.rs: New test. * rust/rustc/ui/process/process-spawn-nonexistent.rs: New test. * rust/rustc/ui/process/process-spawn-with-unicode-params.rs: New test. * rust/rustc/ui/process/process-status-inherits-stdin.rs: New test. * rust/rustc/ui/process/tls-exit-status.rs: New test. * rust/rustc/ui/project-cache-issue-31849.rs: New test. * rust/rustc/ui/project-cache-issue-37154.rs: New test. * rust/rustc/ui/project-defer-unification.rs: New test. * rust/rustc/ui/ptr-coercion-rpass.rs: New test. * rust/rustc/ui/ptr-coercion.rs: New test. * rust/rustc/ui/pub/issue-33174-restricted-type-in-public-interface.rs: New test. * rust/rustc/ui/pub/pub-ident-fn-2.rs: New test. * rust/rustc/ui/pub/pub-ident-fn-3.rs: New test. * rust/rustc/ui/pub/pub-ident-fn-or-struct-2.rs: New test. * rust/rustc/ui/pub/pub-ident-fn-or-struct.rs: New test. * rust/rustc/ui/pub/pub-ident-fn-with-lifetime-2.rs: New test. * rust/rustc/ui/pub/pub-ident-fn-with-lifetime.rs: New test. * rust/rustc/ui/pub/pub-ident-fn.rs: New test. * rust/rustc/ui/pub/pub-ident-struct-with-lifetime.rs: New test. * rust/rustc/ui/pub/pub-ident-struct.rs: New test. * rust/rustc/ui/pub/pub-ident-with-lifetime-incomplete.rs: New test. * rust/rustc/ui/pub/pub-reexport-priv-extern-crate.rs: New test. * rust/rustc/ui/pub/pub-restricted-error-fn.rs: New test. * rust/rustc/ui/pub/pub-restricted-error.rs: New test. * rust/rustc/ui/pub/pub-restricted-non-path.rs: New test. * rust/rustc/ui/pub/pub-restricted.rs: New test. * rust/rustc/ui/pure-sum.rs: New test. * rust/rustc/ui/purity-infer.rs: New test. * rust/rustc/ui/qualified/qualified-path-params-2.rs: New test. * rust/rustc/ui/qualified/qualified-path-params.rs: New test. * rust/rustc/ui/question-mark-type-infer.rs: New test. * rust/rustc/ui/range-type-infer.rs: New test. * rust/rustc/ui/range/issue-54505-no-literals.rs: New test. * rust/rustc/ui/range/issue-54505-no-std.rs: New test. * rust/rustc/ui/range/issue-54505.rs: New test. * rust/rustc/ui/range/issue-73553-misinterp-range-literal.rs: New test. * rust/rustc/ui/range/range-1.rs: New test. * rust/rustc/ui/range/range-inclusive-pattern-precedence.rs: New test. * rust/rustc/ui/range/range-inclusive-pattern-precedence2.rs: New test. * rust/rustc/ui/range/range_traits-1.rs: New test. * rust/rustc/ui/range/range_traits-2.rs: New test. * rust/rustc/ui/range/range_traits-3.rs: New test. * rust/rustc/ui/range/range_traits-4.rs: New test. * rust/rustc/ui/range/range_traits-5.rs: New test. * rust/rustc/ui/range/range_traits-6.rs: New test. * rust/rustc/ui/range/range_traits-7.rs: New test. * rust/rustc/ui/range_inclusive.rs: New test. * rust/rustc/ui/range_inclusive_gate.rs: New test. * rust/rustc/ui/ranges-precedence.rs: New test. * rust/rustc/ui/raw-fat-ptr.rs: New test. * rust/rustc/ui/raw-ref-op/feature-raw-ref-op.rs: New test. * rust/rustc/ui/raw-ref-op/raw-ref-op.rs: New test. * rust/rustc/ui/raw-ref-op/raw-ref-temp-deref.rs: New test. * rust/rustc/ui/raw-ref-op/raw-ref-temp.rs: New test. * rust/rustc/ui/raw-ref-op/unusual_locations.rs: New test. * rust/rustc/ui/raw-str.rs: New test. * rust/rustc/ui/rcvr-borrowed-to-region.rs: New test. * rust/rustc/ui/reachable-unnameable-items.rs: New test. * rust/rustc/ui/reachable-unnameable-type-alias.rs: New test. * rust/rustc/ui/reachable/auxiliary/unreachable_variant.rs: New test. * rust/rustc/ui/reachable/expr_add.rs: New test. * rust/rustc/ui/reachable/expr_again.rs: New test. * rust/rustc/ui/reachable/expr_andand.rs: New test. * rust/rustc/ui/reachable/expr_array.rs: New test. * rust/rustc/ui/reachable/expr_assign.rs: New test. * rust/rustc/ui/reachable/expr_block.rs: New test. * rust/rustc/ui/reachable/expr_box.rs: New test. * rust/rustc/ui/reachable/expr_call.rs: New test. * rust/rustc/ui/reachable/expr_cast.rs: New test. * rust/rustc/ui/reachable/expr_if.rs: New test. * rust/rustc/ui/reachable/expr_loop.rs: New test. * rust/rustc/ui/reachable/expr_match.rs: New test. * rust/rustc/ui/reachable/expr_method.rs: New test. * rust/rustc/ui/reachable/expr_oror.rs: New test. * rust/rustc/ui/reachable/expr_repeat.rs: New test. * rust/rustc/ui/reachable/expr_return.rs: New test. * rust/rustc/ui/reachable/expr_return_in_macro.rs: New test. * rust/rustc/ui/reachable/expr_struct.rs: New test. * rust/rustc/ui/reachable/expr_tup.rs: New test. * rust/rustc/ui/reachable/expr_type.rs: New test. * rust/rustc/ui/reachable/expr_unary.rs: New test. * rust/rustc/ui/reachable/expr_while.rs: New test. * rust/rustc/ui/reachable/unreachable-arm.rs: New test. * rust/rustc/ui/reachable/unreachable-code.rs: New test. * rust/rustc/ui/reachable/unreachable-in-call.rs: New test. * rust/rustc/ui/reachable/unreachable-loop-patterns.rs: New test. * rust/rustc/ui/reachable/unreachable-try-pattern.rs: New test. * rust/rustc/ui/reachable/unreachable-variant.rs: New test. * rust/rustc/ui/reachable/unwarned-match-on-never.rs: New test. * rust/rustc/ui/readalias.rs: New test. * rust/rustc/ui/realloc-16687.rs: New test. * rust/rustc/ui/reassign-ref-mut.rs: New test. * rust/rustc/ui/recursion/auxiliary/recursive_reexports.rs: New test. * rust/rustc/ui/recursion/issue-26548-recursion-via-normalize.rs: New test. * rust/rustc/ui/recursion/issue-38591-non-regular-dropck-recursion.rs: New test. * rust/rustc/ui/recursion/recursion.rs: New test. * rust/rustc/ui/recursion/recursive-enum.rs: New test. * rust/rustc/ui/recursion/recursive-reexports.rs: New test. * rust/rustc/ui/recursion/recursive-requirements.rs: New test. * rust/rustc/ui/recursion/recursive-static-definition.rs: New test. * rust/rustc/ui/recursion/recursive-types-are-not-uninhabited.rs: New test. * rust/rustc/ui/recursion_limit/empty.rs: New test. * rust/rustc/ui/recursion_limit/invalid_digit.rs: New test. * rust/rustc/ui/recursion_limit/overflow.rs: New test. * rust/rustc/ui/recursion_limit/zero.rs: New test. * rust/rustc/ui/reexport-should-still-link.rs: New test. * rust/rustc/ui/reexport-star.rs: New test. * rust/rustc/ui/reexport-test-harness-main.rs: New test. * rust/rustc/ui/ref-suggestion.rs: New test. * rust/rustc/ui/refer-to-other-statics-by-value.rs: New test. * rust/rustc/ui/regions-fn-subtyping-return-static-fail.rs: New test. * rust/rustc/ui/regions/auxiliary/rbmtp_cross_crate_lib.rs: New test. * rust/rustc/ui/regions/issue-56537-closure-uses-region-from-container.rs: New test. * rust/rustc/ui/regions/issue-72051-member-region-hang.rs: New test. * rust/rustc/ui/regions/issue-78262.rs: New test. * rust/rustc/ui/regions/region-borrow-params-issue-29793-big.rs: New test. * rust/rustc/ui/regions/region-borrow-params-issue-29793-small.rs: New test. * rust/rustc/ui/regions/region-bound-extra-bound-in-inherent-impl.rs: New test. * rust/rustc/ui/regions/region-bound-on-closure-outlives-call.rs: New test. * rust/rustc/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs: New test. * rust/rustc/ui/regions/region-bounds-on-objects-and-type-parameters.rs: New test. * rust/rustc/ui/regions/region-invariant-static-error-reporting.rs: New test. * rust/rustc/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs: New test. * rust/rustc/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs: New test. * rust/rustc/ui/regions/region-object-lifetime-1.rs: New test. * rust/rustc/ui/regions/region-object-lifetime-2.rs: New test. * rust/rustc/ui/regions/region-object-lifetime-3.rs: New test. * rust/rustc/ui/regions/region-object-lifetime-4.rs: New test. * rust/rustc/ui/regions/region-object-lifetime-5.rs: New test. * rust/rustc/ui/regions/region-object-lifetime-in-coercion.rs: New test. * rust/rustc/ui/regions/regions-addr-of-arg.rs: New test. * rust/rustc/ui/regions/regions-addr-of-interior-of-unique-box.rs: New test. * rust/rustc/ui/regions/regions-addr-of-ret.rs: New test. * rust/rustc/ui/regions/regions-addr-of-self.rs: New test. * rust/rustc/ui/regions/regions-addr-of-upvar-self.rs: New test. * rust/rustc/ui/regions/regions-adjusted-lvalue-op.rs: New test. * rust/rustc/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs: New test. * rust/rustc/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.rs: New test. * rust/rustc/ui/regions/regions-assoc-type-region-bound.rs: New test. * rust/rustc/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.rs: New test. * rust/rustc/ui/regions/regions-assoc-type-static-bound.rs: New test. * rust/rustc/ui/regions/regions-borrow-at.rs: New test. * rust/rustc/ui/regions/regions-borrow-evec-fixed.rs: New test. * rust/rustc/ui/regions/regions-borrow-evec-uniq.rs: New test. * rust/rustc/ui/regions/regions-borrow-uniq.rs: New test. * rust/rustc/ui/regions/regions-bot.rs: New test. * rust/rustc/ui/regions/regions-bound-lists-feature-gate-2.rs: New test. * rust/rustc/ui/regions/regions-bound-lists-feature-gate.rs: New test. * rust/rustc/ui/regions/regions-bounded-by-trait-requiring-static.rs: New test. * rust/rustc/ui/regions/regions-bounded-method-type-parameters-cross-crate.rs: New test. * rust/rustc/ui/regions/regions-bounded-method-type-parameters-trait-bound.rs: New test. * rust/rustc/ui/regions/regions-bounded-method-type-parameters.rs: New test. * rust/rustc/ui/regions/regions-bounds.rs: New test. * rust/rustc/ui/regions/regions-close-associated-type-into-object.rs: New test. * rust/rustc/ui/regions/regions-close-object-into-object-1.rs: New test. * rust/rustc/ui/regions/regions-close-object-into-object-2.rs: New test. * rust/rustc/ui/regions/regions-close-object-into-object-3.rs: New test. * rust/rustc/ui/regions/regions-close-object-into-object-4.rs: New test. * rust/rustc/ui/regions/regions-close-object-into-object-5.rs: New test. * rust/rustc/ui/regions/regions-close-over-type-parameter-1.rs: New test. * rust/rustc/ui/regions/regions-close-over-type-parameter-multiple.rs: New test. * rust/rustc/ui/regions/regions-close-over-type-parameter-successfully.rs: New test. * rust/rustc/ui/regions/regions-close-param-into-object.rs: New test. * rust/rustc/ui/regions/regions-copy-closure.rs: New test. * rust/rustc/ui/regions/regions-creating-enums.rs: New test. * rust/rustc/ui/regions/regions-creating-enums2.rs: New test. * rust/rustc/ui/regions/regions-creating-enums3.rs: New test. * rust/rustc/ui/regions/regions-creating-enums4.rs: New test. * rust/rustc/ui/regions/regions-creating-enums5.rs: New test. * rust/rustc/ui/regions/regions-debruijn-of-object.rs: New test. * rust/rustc/ui/regions/regions-dependent-addr-of.rs: New test. * rust/rustc/ui/regions/regions-dependent-autofn.rs: New test. * rust/rustc/ui/regions/regions-dependent-autoslice.rs: New test. * rust/rustc/ui/regions/regions-dependent-let-ref.rs: New test. * rust/rustc/ui/regions/regions-early-bound-error-method.rs: New test. * rust/rustc/ui/regions/regions-early-bound-error.rs: New test. * rust/rustc/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs: New test. * rust/rustc/ui/regions/regions-early-bound-trait-param.rs: New test. * rust/rustc/ui/regions/regions-early-bound-used-in-bound-method.rs: New test. * rust/rustc/ui/regions/regions-early-bound-used-in-bound.rs: New test. * rust/rustc/ui/regions/regions-early-bound-used-in-type-param.rs: New test. * rust/rustc/ui/regions/regions-enum-not-wf.rs: New test. * rust/rustc/ui/regions/regions-escape-into-other-fn.rs: New test. * rust/rustc/ui/regions/regions-escape-method.rs: New test. * rust/rustc/ui/regions/regions-escape-via-trait-or-not.rs: New test. * rust/rustc/ui/regions/regions-expl-self.rs: New test. * rust/rustc/ui/regions/regions-fn-subtyping-2.rs: New test. * rust/rustc/ui/regions/regions-fn-subtyping-return-static.rs: New test. * rust/rustc/ui/regions/regions-fn-subtyping.rs: New test. * rust/rustc/ui/regions/regions-free-region-ordering-callee-4.rs: New test. * rust/rustc/ui/regions/regions-free-region-ordering-callee.rs: New test. * rust/rustc/ui/regions/regions-free-region-ordering-caller.rs: New test. * rust/rustc/ui/regions/regions-free-region-ordering-caller1.rs: New test. * rust/rustc/ui/regions/regions-free-region-ordering-incorrect.rs: New test. * rust/rustc/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs: New test. * rust/rustc/ui/regions/regions-glb-free-free.rs: New test. * rust/rustc/ui/regions/regions-implied-bounds-projection-gap-1.rs: New test. * rust/rustc/ui/regions/regions-implied-bounds-projection-gap-2.rs: New test. * rust/rustc/ui/regions/regions-implied-bounds-projection-gap-3.rs: New test. * rust/rustc/ui/regions/regions-implied-bounds-projection-gap-4.rs: New test. * rust/rustc/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs: New test. * rust/rustc/ui/regions/regions-in-enums-anon.rs: New test. * rust/rustc/ui/regions/regions-in-enums.rs: New test. * rust/rustc/ui/regions/regions-in-structs-anon.rs: New test. * rust/rustc/ui/regions/regions-in-structs.rs: New test. * rust/rustc/ui/regions/regions-infer-at-fn-not-param.rs: New test. * rust/rustc/ui/regions/regions-infer-borrow-scope-addr-of.rs: New test. * rust/rustc/ui/regions/regions-infer-borrow-scope-too-big.rs: New test. * rust/rustc/ui/regions/regions-infer-borrow-scope-view.rs: New test. * rust/rustc/ui/regions/regions-infer-borrow-scope-within-loop-ok.rs: New test. * rust/rustc/ui/regions/regions-infer-borrow-scope.rs: New test. * rust/rustc/ui/regions/regions-infer-bound-from-trait-self.rs: New test. * rust/rustc/ui/regions/regions-infer-bound-from-trait.rs: New test. * rust/rustc/ui/regions/regions-infer-call-2.rs: New test. * rust/rustc/ui/regions/regions-infer-call-3.rs: New test. * rust/rustc/ui/regions/regions-infer-call.rs: New test. * rust/rustc/ui/regions/regions-infer-contravariance-due-to-decl.rs: New test. * rust/rustc/ui/regions/regions-infer-contravariance-due-to-ret.rs: New test. * rust/rustc/ui/regions/regions-infer-covariance-due-to-decl.rs: New test. * rust/rustc/ui/regions/regions-infer-invariance-due-to-decl.rs: New test. * rust/rustc/ui/regions/regions-infer-invariance-due-to-mutability-3.rs: New test. * rust/rustc/ui/regions/regions-infer-invariance-due-to-mutability-4.rs: New test. * rust/rustc/ui/regions/regions-infer-not-param.rs: New test. * rust/rustc/ui/regions/regions-infer-paramd-indirect.rs: New test. * rust/rustc/ui/regions/regions-infer-proc-static-upvar.rs: New test. * rust/rustc/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs: New test. * rust/rustc/ui/regions/regions-infer-region-in-fn-but-not-type.rs: New test. * rust/rustc/ui/regions/regions-infer-static-from-proc.rs: New test. * rust/rustc/ui/regions/regions-issue-21422.rs: New test. * rust/rustc/ui/regions/regions-issue-22246.rs: New test. * rust/rustc/ui/regions/regions-lifetime-bounds-on-fns.rs: New test. * rust/rustc/ui/regions/regions-lifetime-nonfree-late-bound.rs: New test. * rust/rustc/ui/regions/regions-lifetime-of-struct-or-enum-variant.rs: New test. * rust/rustc/ui/regions/regions-lifetime-static-items-enclosing-scopes.rs: New test. * rust/rustc/ui/regions/regions-link-fn-args.rs: New test. * rust/rustc/ui/regions/regions-lub-ref-ref-rc.rs: New test. * rust/rustc/ui/regions/regions-mock-codegen.rs: New test. * rust/rustc/ui/regions/regions-name-duplicated.rs: New test. * rust/rustc/ui/regions/regions-name-static.rs: New test. * rust/rustc/ui/regions/regions-name-undeclared.rs: New test. * rust/rustc/ui/regions/regions-nested-fns-2.rs: New test. * rust/rustc/ui/regions/regions-nested-fns.rs: New test. * rust/rustc/ui/regions/regions-no-bound-in-argument-cleanup.rs: New test. * rust/rustc/ui/regions/regions-no-variance-from-fn-generics.rs: New test. * rust/rustc/ui/regions/regions-normalize-in-where-clause-list.rs: New test. * rust/rustc/ui/regions/regions-nullary-variant.rs: New test. * rust/rustc/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs: New test. * rust/rustc/ui/regions/regions-outlives-nominal-type-enum-region.rs: New test. * rust/rustc/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs: New test. * rust/rustc/ui/regions/regions-outlives-nominal-type-enum-type.rs: New test. * rust/rustc/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs: New test. * rust/rustc/ui/regions/regions-outlives-nominal-type-struct-region.rs: New test. * rust/rustc/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs: New test. * rust/rustc/ui/regions/regions-outlives-nominal-type-struct-type.rs: New test. * rust/rustc/ui/regions/regions-outlives-projection-container-hrtb.rs: New test. * rust/rustc/ui/regions/regions-outlives-projection-container-wc.rs: New test. * rust/rustc/ui/regions/regions-outlives-projection-container.rs: New test. * rust/rustc/ui/regions/regions-outlives-projection-hrtype.rs: New test. * rust/rustc/ui/regions/regions-outlives-projection-trait-def.rs: New test. * rust/rustc/ui/regions/regions-outlives-scalar.rs: New test. * rust/rustc/ui/regions/regions-params.rs: New test. * rust/rustc/ui/regions/regions-pattern-typing-issue-19552.rs: New test. * rust/rustc/ui/regions/regions-pattern-typing-issue-19997.rs: New test. * rust/rustc/ui/regions/regions-proc-bound-capture.rs: New test. * rust/rustc/ui/regions/regions-reassign-let-bound-pointer.rs: New test. * rust/rustc/ui/regions/regions-reassign-match-bound-pointer.rs: New test. * rust/rustc/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.rs: New test. * rust/rustc/ui/regions/regions-reborrow-from-shorter-mut-ref.rs: New test. * rust/rustc/ui/regions/regions-ref-in-fn-arg.rs: New test. * rust/rustc/ui/regions/regions-refcell.rs: New test. * rust/rustc/ui/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs: New test. * rust/rustc/ui/regions/regions-ret-borrowed-1.rs: New test. * rust/rustc/ui/regions/regions-ret-borrowed.rs: New test. * rust/rustc/ui/regions/regions-ret.rs: New test. * rust/rustc/ui/regions/regions-return-interior-of-option.rs: New test. * rust/rustc/ui/regions/regions-return-ref-to-upvar-issue-17403.rs: New test. * rust/rustc/ui/regions/regions-return-stack-allocated-vec.rs: New test. * rust/rustc/ui/regions/regions-scope-chain-example.rs: New test. * rust/rustc/ui/regions/regions-self-impls.rs: New test. * rust/rustc/ui/regions/regions-self-in-enums.rs: New test. * rust/rustc/ui/regions/regions-simple.rs: New test. * rust/rustc/ui/regions/regions-static-bound-rpass.rs: New test. * rust/rustc/ui/regions/regions-static-bound.rs: New test. * rust/rustc/ui/regions/regions-static-closure.rs: New test. * rust/rustc/ui/regions/regions-steal-closure.rs: New test. * rust/rustc/ui/regions/regions-trait-1.rs: New test. * rust/rustc/ui/regions/regions-trait-object-1.rs: New test. * rust/rustc/ui/regions/regions-trait-object-subtyping.rs: New test. * rust/rustc/ui/regions/regions-trait-variance.rs: New test. * rust/rustc/ui/regions/regions-undeclared.rs: New test. * rust/rustc/ui/regions/regions-var-type-out-of-scope.rs: New test. * rust/rustc/ui/regions/regions-variance-contravariant-use-contravariant.rs: New test. * rust/rustc/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.rs: New test. * rust/rustc/ui/regions/regions-variance-contravariant-use-covariant.rs: New test. * rust/rustc/ui/regions/regions-variance-covariant-use-contravariant.rs: New test. * rust/rustc/ui/regions/regions-variance-covariant-use-covariant.rs: New test. * rust/rustc/ui/regions/regions-variance-invariant-use-contravariant.rs: New test. * rust/rustc/ui/regions/regions-variance-invariant-use-covariant.rs: New test. * rust/rustc/ui/regions/regions-wf-trait-object.rs: New test. * rust/rustc/ui/regions/type-param-outlives-reempty-issue-74429-2.rs: New test. * rust/rustc/ui/regions/type-param-outlives-reempty-issue-74429.rs: New test. * rust/rustc/ui/reify-intrinsic.rs: New test. * rust/rustc/ui/reject-specialized-drops-8142.rs: New test. * rust/rustc/ui/removing-extern-crate.rs: New test. * rust/rustc/ui/repeat-expr-in-static.rs: New test. * rust/rustc/ui/repeat-to-run-dtor-twice.rs: New test. * rust/rustc/ui/repeat_count.rs: New test. * rust/rustc/ui/repeat_count_const_in_async_fn.rs: New test. * rust/rustc/ui/repr.rs: New test. * rust/rustc/ui/repr/feature-gate-no-niche.rs: New test. * rust/rustc/ui/repr/repr-align-assign.rs: New test. * rust/rustc/ui/repr/repr-align.rs: New test. * rust/rustc/ui/repr/repr-disallow-on-variant.rs: New test. * rust/rustc/ui/repr/repr-no-niche-inapplicable-to-unions.rs: New test. * rust/rustc/ui/repr/repr-no-niche.rs: New test. * rust/rustc/ui/repr/repr-packed-contains-align.rs: New test. * rust/rustc/ui/repr/repr-transparent-other-items.rs: New test. * rust/rustc/ui/repr/repr-transparent-other-reprs.rs: New test. * rust/rustc/ui/repr/repr-transparent.rs: New test. * rust/rustc/ui/repr_c_int_align.rs: New test. * rust/rustc/ui/required-lang-item.rs: New test. * rust/rustc/ui/reserved/reserved-attr-on-macro.rs: New test. * rust/rustc/ui/reserved/reserved-become.rs: New test. * rust/rustc/ui/resolve-issue-2428.rs: New test. * rust/rustc/ui/resolve-pseudo-shadowing.rs: New test. * rust/rustc/ui/resolve/associated-fn-called-as-fn.rs: New test. * rust/rustc/ui/resolve/auxiliary/issue-19452-aux.rs: New test. * rust/rustc/ui/resolve/auxiliary/issue-21221-3.rs: New test. * rust/rustc/ui/resolve/auxiliary/issue-21221-4.rs: New test. * rust/rustc/ui/resolve/auxiliary/issue-3907.rs: New test. * rust/rustc/ui/resolve/auxiliary/namespaced_enums.rs: New test. * rust/rustc/ui/resolve/auxiliary/privacy-struct-ctor.rs: New test. * rust/rustc/ui/resolve/block-with-trait-parent.rs: New test. * rust/rustc/ui/resolve/enums-are-namespaced-xc.rs: New test. * rust/rustc/ui/resolve/impl-items-vis-unresolved.rs: New test. * rust/rustc/ui/resolve/issue-14254.rs: New test. * rust/rustc/ui/resolve/issue-16058.rs: New test. * rust/rustc/ui/resolve/issue-17518.rs: New test. * rust/rustc/ui/resolve/issue-18252.rs: New test. * rust/rustc/ui/resolve/issue-19452.rs: New test. * rust/rustc/ui/resolve/issue-21221-1.rs: New test. * rust/rustc/ui/resolve/issue-21221-2.rs: New test. * rust/rustc/ui/resolve/issue-21221-3.rs: New test. * rust/rustc/ui/resolve/issue-21221-4.rs: New test. * rust/rustc/ui/resolve/issue-22692.rs: New test. * rust/rustc/ui/resolve/issue-23305.rs: New test. * rust/rustc/ui/resolve/issue-2356.rs: New test. * rust/rustc/ui/resolve/issue-24968.rs: New test. * rust/rustc/ui/resolve/issue-33876.rs: New test. * rust/rustc/ui/resolve/issue-3907-2.rs: New test. * rust/rustc/ui/resolve/issue-3907.rs: New test. * rust/rustc/ui/resolve/issue-39226.rs: New test. * rust/rustc/ui/resolve/issue-5035-2.rs: New test. * rust/rustc/ui/resolve/issue-5035.rs: New test. * rust/rustc/ui/resolve/issue-54379.rs: New test. * rust/rustc/ui/resolve/issue-57523.rs: New test. * rust/rustc/ui/resolve/issue-65025-extern-static-parent-generics.rs: New test. * rust/rustc/ui/resolve/issue-65035-static-with-parent-generics.rs: New test. * rust/rustc/ui/resolve/issue-6702.rs: New test. * rust/rustc/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs: New test. * rust/rustc/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs: New test. * rust/rustc/ui/resolve/levenshtein.rs: New test. * rust/rustc/ui/resolve/name-clash-nullary.rs: New test. * rust/rustc/ui/resolve/privacy-enum-ctor.rs: New test. * rust/rustc/ui/resolve/privacy-struct-ctor.rs: New test. * rust/rustc/ui/resolve/raw-ident-in-path.rs: New test. * rust/rustc/ui/resolve/resolve-assoc-suggestions.rs: New test. * rust/rustc/ui/resolve/resolve-bad-import-prefix.rs: New test. * rust/rustc/ui/resolve/resolve-bad-visibility.rs: New test. * rust/rustc/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs: New test. * rust/rustc/ui/resolve/resolve-conflict-import-vs-extern-crate.rs: New test. * rust/rustc/ui/resolve/resolve-conflict-import-vs-import.rs: New test. * rust/rustc/ui/resolve/resolve-conflict-item-vs-extern-crate.rs: New test. * rust/rustc/ui/resolve/resolve-conflict-item-vs-import.rs: New test. * rust/rustc/ui/resolve/resolve-conflict-type-vs-import.rs: New test. * rust/rustc/ui/resolve/resolve-hint-macro.rs: New test. * rust/rustc/ui/resolve/resolve-inconsistent-binding-mode.rs: New test. * rust/rustc/ui/resolve/resolve-inconsistent-names.rs: New test. * rust/rustc/ui/resolve/resolve-label.rs: New test. * rust/rustc/ui/resolve/resolve-primitive-fallback.rs: New test. * rust/rustc/ui/resolve/resolve-self-in-impl-2.rs: New test. * rust/rustc/ui/resolve/resolve-self-in-impl.rs: New test. * rust/rustc/ui/resolve/resolve-speculative-adjustment.rs: New test. * rust/rustc/ui/resolve/resolve-type-param-in-item-in-trait.rs: New test. * rust/rustc/ui/resolve/resolve-unknown-trait.rs: New test. * rust/rustc/ui/resolve/resolve-variant-assoc-item.rs: New test. * rust/rustc/ui/resolve/suggest-path-instead-of-mod-dot-item.rs: New test. * rust/rustc/ui/resolve/token-error-correct-2.rs: New test. * rust/rustc/ui/resolve/token-error-correct-3.rs: New test. * rust/rustc/ui/resolve/token-error-correct-4.rs: New test. * rust/rustc/ui/resolve/token-error-correct.rs: New test. * rust/rustc/ui/resolve/tuple-struct-alias.rs: New test. * rust/rustc/ui/resolve/typo-suggestion-named-underscore.rs: New test. * rust/rustc/ui/resolve/unboxed-closure-sugar-nonexistent-trait.rs: New test. * rust/rustc/ui/resolve/unresolved_static_type_field.rs: New test. * rust/rustc/ui/resolve/use_suggestion.rs: New test. * rust/rustc/ui/resolve/use_suggestion_placement.rs: New test. * rust/rustc/ui/resolve/visibility-indeterminate.rs: New test. * rust/rustc/ui/resolve_self_super_hint.rs: New test. * rust/rustc/ui/resource-assign-is-not-copy.rs: New test. * rust/rustc/ui/resource-destruct.rs: New test. * rust/rustc/ui/result-opt-conversions.rs: New test. * rust/rustc/ui/ret-bang.rs: New test. * rust/rustc/ui/ret-non-nil.rs: New test. * rust/rustc/ui/ret-none.rs: New test. * rust/rustc/ui/retslot-cast.rs: New test. * rust/rustc/ui/return-disjoint-regions.rs: New test. * rust/rustc/ui/return-nil.rs: New test. * rust/rustc/ui/return/return-from-diverging.rs: New test. * rust/rustc/ui/return/return-match-array-const.rs: New test. * rust/rustc/ui/return/return-type.rs: New test. * rust/rustc/ui/return/return-unit-from-diverging.rs: New test. * rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs: New test. * rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/former-E0008-now-pass.rs: New test. * rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs: New test. * rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs: New test. * rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-use-behind-cousin-variant.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/feature-gate.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-empty-array-allowed-without-eq-issue-62336.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs: New test. * rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/phantom-data-is-structurally-matchable.rs: New test. * rust/rustc/ui/rfc-1717-dllimport/missing-link-attr.rs: New test. * rust/rustc/ui/rfc-1717-dllimport/multiple-renames.rs: New test. * rust/rustc/ui/rfc-1717-dllimport/rename-to-empty.rs: New test. * rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs: New test. * rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-never.rs: New test. * rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs: New test. * rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-str.rs: New test. * rust/rustc/ui/rfc-1937-termination-trait/termination-trait-impl-trait.rs: New test. * rust/rustc/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs: New test. * rust/rustc/ui/rfc-1937-termination-trait/termination-trait-in-test.rs: New test. * rust/rustc/ui/rfc-1937-termination-trait/termination-trait-main-i32.rs: New test. * rust/rustc/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs: New test. * rust/rustc/ui/rfc-1937-termination-trait/termination-trait-not-satisfied.rs: New test. * rust/rustc/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs: New test. * rust/rustc/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.rs: New test. * rust/rustc/ui/rfc-2005-default-binding-mode/const.rs: New test. * rust/rustc/ui/rfc-2005-default-binding-mode/enum.rs: New test. * rust/rustc/ui/rfc-2005-default-binding-mode/explicit-mut.rs: New test. * rust/rustc/ui/rfc-2005-default-binding-mode/for.rs: New test. * rust/rustc/ui/rfc-2005-default-binding-mode/issue-44912-or.rs: New test. * rust/rustc/ui/rfc-2005-default-binding-mode/lit.rs: New test. * rust/rustc/ui/rfc-2005-default-binding-mode/no-double-error.rs: New test. * rust/rustc/ui/rfc-2005-default-binding-mode/slice.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/enums.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/structs.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/variants.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/enum.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/enum_same_crate.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/auxiliary/types.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/same_crate_proper.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/invalid-attribute.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/struct.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/structs_same_crate.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/variant.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs: New test. * rust/rustc/ui/rfc-2008-non-exhaustive/variants_same_crate.rs: New test. * rust/rustc/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs: New test. * rust/rustc/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs: New test. * rust/rustc/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/call-chain.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/caller-location-intrinsic.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/const-caller-location.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/diverging-caller-location.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/error-odd-syntax.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/error-with-invalid-abi.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/error-with-main.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/error-with-naked.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/error-with-start.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/intrinsic-wrapper.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/only-for-fns.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/pass.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/std-panic-locations.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/track-caller-attribute.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/track-caller-ffi.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/tracked-fn-ptr.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/tracked-trait-impls.rs: New test. * rust/rustc/ui/rfc-2091-track-caller/tracked-trait-obj.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/cross-crate.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/dont-infer-static.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/enum.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/explicit-dyn.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/explicit-enum.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/explicit-projection.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/explicit-struct.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/explicit-union.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/infer-static.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/issue-54467.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/nested-enum.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/nested-regions.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/nested-structs.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/nested-union.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/privacy.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/projection.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/reference.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/regions-struct-not-wf.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/self-dyn.rs: New test. * rust/rustc/ui/rfc-2093-infer-outlives/self-structs.rs: New test. * rust/rustc/ui/rfc-2126-crate-paths/crate-path-non-absolute.rs: New test. * rust/rustc/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.rs: New test. * rust/rustc/ui/rfc-2126-extern-absolute-paths/auxiliary/xcrate.rs: New test. * rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-1.rs: New test. * rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-2.rs: New test. * rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-3.rs: New test. * rust/rustc/ui/rfc-2126-extern-absolute-paths/not-allowed.rs: New test. * rust/rustc/ui/rfc-2126-extern-absolute-paths/single-segment.rs: New test. * rust/rustc/ui/rfc-2294-if-let-guard/feature-gate.rs: New test. * rust/rustc/ui/rfc-2306/convert-id-const-with-gate.rs: New test. * rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs: New test. * rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.rs: New test. * rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.rs: New test. * rust/rustc/ui/rfc-2457/auxiliary/mod_file_nonascii_with_path_allowed-aux.rs: New test. * rust/rustc/ui/rfc-2457/crate_name_nonascii_forbidden-1.rs: New test. * rust/rustc/ui/rfc-2457/crate_name_nonascii_forbidden-2.rs: New test. * rust/rustc/ui/rfc-2457/idents-normalized.rs: New test. * rust/rustc/ui/rfc-2457/mod_file_nonascii_forbidden.rs: New test. * rust/rustc/ui/rfc-2457/mod_file_nonascii_with_path_allowed.rs: New test. * rust/rustc/ui/rfc-2457/mod_inline_nonascii_allowed.rs: New test. * rust/rustc/ui/rfc-2457/no_mangle_nonascii_forbidden.rs: New test. * rust/rustc/ui/rfc-2497-if-let-chains/ast-pretty-check.rs: New test. * rust/rustc/ui/rfc-2497-if-let-chains/disallowed-positions.rs: New test. * rust/rustc/ui/rfc-2497-if-let-chains/feature-gate.rs: New test. * rust/rustc/ui/rfc-2497-if-let-chains/protect-precedences.rs: New test. * rust/rustc/ui/rfc-2565-param-attrs/attr-without-param.rs: New test. * rust/rustc/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs: New test. * rust/rustc/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs: New test. * rust/rustc/ui/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs: New test. * rust/rustc/ui/rfc-2565-param-attrs/param-attrs-2018.rs: New test. * rust/rustc/ui/rfc-2565-param-attrs/param-attrs-allowed.rs: New test. * rust/rustc/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs: New test. * rust/rustc/ui/rfc-2565-param-attrs/param-attrs-cfg.rs: New test. * rust/rustc/ui/rfc-2565-param-attrs/param-attrs-pretty.rs: New test. * rust/rustc/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs: New test. * rust/rustc/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib-2.rs: New test. * rust/rustc/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib.rs: New test. * rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs: New test. * rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs: New test. * rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/assoc-type.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/syntax.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/feature-gate.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/generic-bound.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/hir-const-check.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/inherent-impl.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/stability.rs: New test. * rust/rustc/ui/rfc-2632-const-trait-impl/syntax.rs: New test. * rust/rustc/ui/rfc1623-2.rs: New test. * rust/rustc/ui/rfc1623.rs: New test. * rust/rustc/ui/rfcs/rfc-1014-2.rs: New test. * rust/rustc/ui/rfcs/rfc-1014.rs: New test. * rust/rustc/ui/rfcs/rfc-1789-as-cell/from-mut.rs: New test. * rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs: New test. * rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs: New test. * rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs: New test. * rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs: New test. * rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs: New test. * rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs: New test. * rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/box.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/constref.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/enum.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/for.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/general.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/lit.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/range.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/slice.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/struct.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs: New test. * rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs: New test. * rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/attr.rs: New test. * rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/basic.rs: New test. * rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/items.rs: New test. * rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/macros.rs: New test. * rust/rustc/ui/rfcs/rfc-2175-or-if-while-let/basic.rs: New test. * rust/rustc/ui/rfcs/rfc-2302-self-struct-ctor.rs: New test. * rust/rustc/ui/rfcs/rfc-2396-target_feature-11/check-pass.rs: New test. * rust/rustc/ui/rfcs/rfc-2396-target_feature-11/closures-inherit-target_feature.rs: New test. * rust/rustc/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.rs: New test. * rust/rustc/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs: New test. * rust/rustc/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs: New test. * rust/rustc/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs: New test. * rust/rustc/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs: New test. * rust/rustc/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs: New test. * rust/rustc/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs: New test. * rust/rustc/ui/rfcs/rfc1445/eq-allows-match.rs: New test. * rust/rustc/ui/rfcs/rfc1623.rs: New test. * rust/rustc/ui/rfcs/rfc1717/library-override.rs: New test. * rust/rustc/ui/rfcs/rfc1857-drop-order.rs: New test. * rust/rustc/ui/rmeta-lib-pass.rs: New test. * rust/rustc/ui/rmeta-pass.rs: New test. * rust/rustc/ui/rmeta-priv-warn.rs: New test. * rust/rustc/ui/rmeta-rpass.rs: New test. * rust/rustc/ui/rmeta.rs: New test. * rust/rustc/ui/rmeta_lib.rs: New test. * rust/rustc/ui/rmeta_meta_main.rs: New test. * rust/rustc/ui/running-with-no-runtime.rs: New test. * rust/rustc/ui/rust-2018/async-ident-allowed.rs: New test. * rust/rustc/ui/rust-2018/async-ident.rs: New test. * rust/rustc/ui/rust-2018/auxiliary/baz.rs: New test. * rust/rustc/ui/rust-2018/auxiliary/edition-lint-paths.rs: New test. * rust/rustc/ui/rust-2018/auxiliary/macro-use-warned-against.rs: New test. * rust/rustc/ui/rust-2018/auxiliary/macro-use-warned-against2.rs: New test. * rust/rustc/ui/rust-2018/auxiliary/remove-extern-crate.rs: New test. * rust/rustc/ui/rust-2018/auxiliary/suggestions-not-always-applicable.rs: New test. * rust/rustc/ui/rust-2018/auxiliary/trait-import-suggestions.rs: New test. * rust/rustc/ui/rust-2018/dyn-keyword.rs: New test. * rust/rustc/ui/rust-2018/dyn-trait-compatibility.rs: New test. * rust/rustc/ui/rust-2018/edition-lint-fully-qualified-paths.rs: New test. * rust/rustc/ui/rust-2018/edition-lint-infer-outlives-multispan.rs: New test. * rust/rustc/ui/rust-2018/edition-lint-infer-outlives.rs: New test. * rust/rustc/ui/rust-2018/edition-lint-nested-empty-paths.rs: New test. * rust/rustc/ui/rust-2018/edition-lint-nested-paths.rs: New test. * rust/rustc/ui/rust-2018/edition-lint-paths-2018.rs: New test. * rust/rustc/ui/rust-2018/edition-lint-paths.rs: New test. * rust/rustc/ui/rust-2018/edition-lint-uninferable-outlives.rs: New test. * rust/rustc/ui/rust-2018/extern-crate-idiomatic-in-2018.rs: New test. * rust/rustc/ui/rust-2018/extern-crate-idiomatic.rs: New test. * rust/rustc/ui/rust-2018/extern-crate-referenced-by-self-path.rs: New test. * rust/rustc/ui/rust-2018/extern-crate-rename.rs: New test. * rust/rustc/ui/rust-2018/extern-crate-submod.rs: New test. * rust/rustc/ui/rust-2018/future-proofing-locals.rs: New test. * rust/rustc/ui/rust-2018/issue-51008-1.rs: New test. * rust/rustc/ui/rust-2018/issue-51008.rs: New test. * rust/rustc/ui/rust-2018/issue-52202-use-suggestions.rs: New test. * rust/rustc/ui/rust-2018/issue-54006.rs: New test. * rust/rustc/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs: New test. * rust/rustc/ui/rust-2018/local-path-suggestions-2015.rs: New test. * rust/rustc/ui/rust-2018/local-path-suggestions-2018.rs: New test. * rust/rustc/ui/rust-2018/macro-use-warned-against.rs: New test. * rust/rustc/ui/rust-2018/proc-macro-crate-in-paths.rs: New test. * rust/rustc/ui/rust-2018/remove-extern-crate.rs: New test. * rust/rustc/ui/rust-2018/suggestions-not-always-applicable.rs: New test. * rust/rustc/ui/rust-2018/trait-import-suggestions.rs: New test. * rust/rustc/ui/rust-2018/try-ident.rs: New test. * rust/rustc/ui/rust-2018/try-macro.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/ambiguity-macros-nested.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/ambiguity-macros.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/ambiguity-nested.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/ambiguity.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/auxiliary/issue-56596-2.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/auxiliary/issue-56596.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/block-scoped-shadow.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/cross-crate.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/deadlock.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/fn-local-enum.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/from-decl-macro.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/issue-54253.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/issue-56596-2.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/issue-56596.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/macro-rules.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/prelude-fail-2.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/prelude-fail.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/prelude.rs: New test. * rust/rustc/ui/rust-2018/uniform-paths/redundant.rs: New test. * rust/rustc/ui/rustc-args-required-const.rs: New test. * rust/rustc/ui/rustc-args-required-const2.rs: New test. * rust/rustc/ui/rustc-error.rs: New test. * rust/rustc/ui/rustc-rust-log.rs: New test. * rust/rustc/ui/rvalue-static-promotion.rs: New test. * rust/rustc/ui/safe-extern-statics-mut.rs: New test. * rust/rustc/ui/safe-extern-statics.rs: New test. * rust/rustc/ui/sanitize/address.rs: New test. * rust/rustc/ui/sanitize/badfree.rs: New test. * rust/rustc/ui/sanitize/cfg.rs: New test. * rust/rustc/ui/sanitize/incompatible.rs: New test. * rust/rustc/ui/sanitize/inline-always.rs: New test. * rust/rustc/ui/sanitize/issue-72154-lifetime-markers.rs: New test. * rust/rustc/ui/sanitize/leak.rs: New test. * rust/rustc/ui/sanitize/memory.rs: New test. * rust/rustc/ui/sanitize/new-llvm-pass-manager-thin-lto.rs: New test. * rust/rustc/ui/sanitize/thread.rs: New test. * rust/rustc/ui/sanitize/unsupported-target.rs: New test. * rust/rustc/ui/sanitize/use-after-scope.rs: New test. * rust/rustc/ui/save-analysis/emit-notifications.rs: New test. * rust/rustc/ui/save-analysis/issue-59134-0.rs: New test. * rust/rustc/ui/save-analysis/issue-59134-1.rs: New test. * rust/rustc/ui/save-analysis/issue-63663.rs: New test. * rust/rustc/ui/save-analysis/issue-64659.rs: New test. * rust/rustc/ui/save-analysis/issue-65411.rs: New test. * rust/rustc/ui/save-analysis/issue-65590.rs: New test. * rust/rustc/ui/save-analysis/issue-68621.rs: New test. * rust/rustc/ui/save-analysis/issue-72267.rs: New test. * rust/rustc/ui/save-analysis/issue-73020.rs: New test. * rust/rustc/ui/save-analysis/issue-73022.rs: New test. * rust/rustc/ui/self/arbitrary-self-types-not-object-safe.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_nested.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_pin_lifetime-async.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_pin_lifetime.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_pointers_and_wrappers.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_raw_pointer_struct.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_raw_pointer_trait.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_silly.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_stdlib_pointers.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_struct.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_trait.rs: New test. * rust/rustc/ui/self/arbitrary_self_types_unsized_struct.rs: New test. * rust/rustc/ui/self/auxiliary/explicit_self_xcrate.rs: New test. * rust/rustc/ui/self/builtin-superkinds-self-type.rs: New test. * rust/rustc/ui/self/by-value-self-in-mut-slot.rs: New test. * rust/rustc/ui/self/elision/alias-async.rs: New test. * rust/rustc/ui/self/elision/alias.rs: New test. * rust/rustc/ui/self/elision/assoc-async.rs: New test. * rust/rustc/ui/self/elision/assoc.rs: New test. * rust/rustc/ui/self/elision/lt-alias-async.rs: New test. * rust/rustc/ui/self/elision/lt-alias.rs: New test. * rust/rustc/ui/self/elision/lt-assoc-async.rs: New test. * rust/rustc/ui/self/elision/lt-assoc.rs: New test. * rust/rustc/ui/self/elision/lt-ref-self-async.rs: New test. * rust/rustc/ui/self/elision/lt-ref-self.rs: New test. * rust/rustc/ui/self/elision/lt-self-async.rs: New test. * rust/rustc/ui/self/elision/lt-self.rs: New test. * rust/rustc/ui/self/elision/lt-struct-async.rs: New test. * rust/rustc/ui/self/elision/lt-struct.rs: New test. * rust/rustc/ui/self/elision/multiple-ref-self-async.rs: New test. * rust/rustc/ui/self/elision/multiple-ref-self.rs: New test. * rust/rustc/ui/self/elision/ref-alias-async.rs: New test. * rust/rustc/ui/self/elision/ref-alias.rs: New test. * rust/rustc/ui/self/elision/ref-assoc-async.rs: New test. * rust/rustc/ui/self/elision/ref-assoc.rs: New test. * rust/rustc/ui/self/elision/ref-mut-alias-async.rs: New test. * rust/rustc/ui/self/elision/ref-mut-alias.rs: New test. * rust/rustc/ui/self/elision/ref-mut-self-async.rs: New test. * rust/rustc/ui/self/elision/ref-mut-self.rs: New test. * rust/rustc/ui/self/elision/ref-mut-struct-async.rs: New test. * rust/rustc/ui/self/elision/ref-mut-struct.rs: New test. * rust/rustc/ui/self/elision/ref-self-async.rs: New test. * rust/rustc/ui/self/elision/ref-self.rs: New test. * rust/rustc/ui/self/elision/ref-struct-async.rs: New test. * rust/rustc/ui/self/elision/ref-struct.rs: New test. * rust/rustc/ui/self/elision/self-async.rs: New test. * rust/rustc/ui/self/elision/self.rs: New test. * rust/rustc/ui/self/elision/struct-async.rs: New test. * rust/rustc/ui/self/elision/struct.rs: New test. * rust/rustc/ui/self/explicit-self-closures.rs: New test. * rust/rustc/ui/self/explicit-self-generic.rs: New test. * rust/rustc/ui/self/explicit-self-objects-uniq.rs: New test. * rust/rustc/ui/self/explicit-self.rs: New test. * rust/rustc/ui/self/explicit_self_xcrate_exe.rs: New test. * rust/rustc/ui/self/move-self.rs: New test. * rust/rustc/ui/self/object-safety-sized-self-by-value-self.rs: New test. * rust/rustc/ui/self/object-safety-sized-self-generic-method.rs: New test. * rust/rustc/ui/self/object-safety-sized-self-return-Self.rs: New test. * rust/rustc/ui/self/point-at-arbitrary-self-type-method.rs: New test. * rust/rustc/ui/self/point-at-arbitrary-self-type-trait-method.rs: New test. * rust/rustc/ui/self/self-impl-2.rs: New test. * rust/rustc/ui/self/self-impl.rs: New test. * rust/rustc/ui/self/self-in-mut-slot-default-method.rs: New test. * rust/rustc/ui/self/self-in-mut-slot-immediate-value.rs: New test. * rust/rustc/ui/self/self-in-typedefs.rs: New test. * rust/rustc/ui/self/self-infer.rs: New test. * rust/rustc/ui/self/self-re-assign.rs: New test. * rust/rustc/ui/self/self-shadowing-import.rs: New test. * rust/rustc/ui/self/self-type-param.rs: New test. * rust/rustc/ui/self/self-vs-path-ambiguity.rs: New test. * rust/rustc/ui/self/self_lifetime-async.rs: New test. * rust/rustc/ui/self/self_lifetime.rs: New test. * rust/rustc/ui/self/self_type_keyword-2.rs: New test. * rust/rustc/ui/self/self_type_keyword.rs: New test. * rust/rustc/ui/self/string-self-append.rs: New test. * rust/rustc/ui/self/suggest-self-2.rs: New test. * rust/rustc/ui/self/suggest-self.rs: New test. * rust/rustc/ui/self/ufcs-explicit-self.rs: New test. * rust/rustc/ui/self/uniq-self-in-mut-slot.rs: New test. * rust/rustc/ui/self/where-for-self.rs: New test. * rust/rustc/ui/semistatement-in-lambda.rs: New test. * rust/rustc/ui/sepcomp/auxiliary/sepcomp-extern-lib.rs: New test. * rust/rustc/ui/sepcomp/auxiliary/sepcomp_cci_lib.rs: New test. * rust/rustc/ui/sepcomp/auxiliary/sepcomp_lib.rs: New test. * rust/rustc/ui/sepcomp/sepcomp-cci.rs: New test. * rust/rustc/ui/sepcomp/sepcomp-extern.rs: New test. * rust/rustc/ui/sepcomp/sepcomp-fns-backwards.rs: New test. * rust/rustc/ui/sepcomp/sepcomp-fns.rs: New test. * rust/rustc/ui/sepcomp/sepcomp-lib-lto.rs: New test. * rust/rustc/ui/sepcomp/sepcomp-lib.rs: New test. * rust/rustc/ui/sepcomp/sepcomp-statics.rs: New test. * rust/rustc/ui/sepcomp/sepcomp-unwind.rs: New test. * rust/rustc/ui/seq-args.rs: New test. * rust/rustc/ui/seq-compare.rs: New test. * rust/rustc/ui/shadow-bool.rs: New test. * rust/rustc/ui/shadow.rs: New test. * rust/rustc/ui/shadowed-use-visibility.rs: New test. * rust/rustc/ui/shadowed/shadowed-lifetime.rs: New test. * rust/rustc/ui/shadowed/shadowed-trait-methods.rs: New test. * rust/rustc/ui/shadowed/shadowed-type-parameter.rs: New test. * rust/rustc/ui/shadowed/shadowed-use-visibility.rs: New test. * rust/rustc/ui/shadowed/shadowing-in-the-same-pattern.rs: New test. * rust/rustc/ui/shift-various-bad-types.rs: New test. * rust/rustc/ui/short-error-format.rs: New test. * rust/rustc/ui/signal-alternate-stack-cleanup.rs: New test. * rust/rustc/ui/signal-exit-status.rs: New test. * rust/rustc/ui/sigpipe-should-be-ignored.rs: New test. * rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs: New test. * rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.rs: New test. * rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs: New test. * rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-cast.rs: New test. * rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-comparison.rs: New test. * rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-elements.rs: New test. * rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs: New test. * rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-select.rs: New test. * rust/rustc/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs: New test. * rust/rustc/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs: New test. * rust/rustc/ui/simd-type-generic-monomorphisation.rs: New test. * rust/rustc/ui/simd-type.rs: New test. * rust/rustc/ui/simd/shuffle-not-out-of-bounds.rs: New test. * rust/rustc/ui/simd/simd-generics.rs: New test. * rust/rustc/ui/simd/simd-intrinsic-float-math.rs: New test. * rust/rustc/ui/simd/simd-intrinsic-float-minmax.rs: New test. * rust/rustc/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs: New test. * rust/rustc/ui/simd/simd-intrinsic-generic-arithmetic.rs: New test. * rust/rustc/ui/simd/simd-intrinsic-generic-bitmask.rs: New test. * rust/rustc/ui/simd/simd-intrinsic-generic-cast.rs: New test. * rust/rustc/ui/simd/simd-intrinsic-generic-comparison.rs: New test. * rust/rustc/ui/simd/simd-intrinsic-generic-elements.rs: New test. * rust/rustc/ui/simd/simd-intrinsic-generic-gather.rs: New test. * rust/rustc/ui/simd/simd-intrinsic-generic-reduction.rs: New test. * rust/rustc/ui/simd/simd-intrinsic-generic-select.rs: New test. * rust/rustc/ui/simd/simd-size-align.rs: New test. * rust/rustc/ui/simd/simd-target-feature-mixup.rs: New test. * rust/rustc/ui/simd/simd-type.rs: New test. * rust/rustc/ui/similar-tokens.rs: New test. * rust/rustc/ui/simple-infer.rs: New test. * rust/rustc/ui/simple_global_asm.rs: New test. * rust/rustc/ui/single-primitive-inherent-impl.rs: New test. * rust/rustc/ui/single-use-lifetime/fn-types.rs: New test. * rust/rustc/ui/single-use-lifetime/one-use-in-fn-argument-in-band.rs: New test. * rust/rustc/ui/single-use-lifetime/one-use-in-fn-argument.rs: New test. * rust/rustc/ui/single-use-lifetime/one-use-in-fn-return.rs: New test. * rust/rustc/ui/single-use-lifetime/one-use-in-inherent-impl-header.rs: New test. * rust/rustc/ui/single-use-lifetime/one-use-in-inherent-method-argument.rs: New test. * rust/rustc/ui/single-use-lifetime/one-use-in-inherent-method-return.rs: New test. * rust/rustc/ui/single-use-lifetime/one-use-in-struct.rs: New test. * rust/rustc/ui/single-use-lifetime/one-use-in-trait-method-argument.rs: New test. * rust/rustc/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs: New test. * rust/rustc/ui/single-use-lifetime/two-uses-in-fn-arguments.rs: New test. * rust/rustc/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs: New test. * rust/rustc/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.rs: New test. * rust/rustc/ui/single-use-lifetime/two-uses-in-trait-impl.rs: New test. * rust/rustc/ui/single-use-lifetime/zero-uses-in-fn.rs: New test. * rust/rustc/ui/single-use-lifetime/zero-uses-in-impl.rs: New test. * rust/rustc/ui/size-and-align.rs: New test. * rust/rustc/ui/sized-borrowed-pointer.rs: New test. * rust/rustc/ui/sized-cycle-note.rs: New test. * rust/rustc/ui/sized-owned-pointer.rs: New test. * rust/rustc/ui/sleep.rs: New test. * rust/rustc/ui/slice-2.rs: New test. * rust/rustc/ui/slice-mut-2.rs: New test. * rust/rustc/ui/slice-mut.rs: New test. * rust/rustc/ui/slice-to-vec-comparison.rs: New test. * rust/rustc/ui/slightly-nice-generic-literal-messages.rs: New test. * rust/rustc/ui/slowparse-bstring.rs: New test. * rust/rustc/ui/slowparse-string.rs: New test. * rust/rustc/ui/span/E0046.rs: New test. * rust/rustc/ui/span/E0057.rs: New test. * rust/rustc/ui/span/E0072.rs: New test. * rust/rustc/ui/span/E0204.rs: New test. * rust/rustc/ui/span/E0493.rs: New test. * rust/rustc/ui/span/E0535.rs: New test. * rust/rustc/ui/span/E0536.rs: New test. * rust/rustc/ui/span/E0537.rs: New test. * rust/rustc/ui/span/auxiliary/transitive_dep_three.rs: New test. * rust/rustc/ui/span/auxiliary/transitive_dep_two.rs: New test. * rust/rustc/ui/span/borrowck-borrow-overloaded-auto-deref-mut.rs: New test. * rust/rustc/ui/span/borrowck-borrow-overloaded-deref-mut.rs: New test. * rust/rustc/ui/span/borrowck-call-is-borrow-issue-12224.rs: New test. * rust/rustc/ui/span/borrowck-call-method-from-mut-aliasable.rs: New test. * rust/rustc/ui/span/borrowck-fn-in-const-b.rs: New test. * rust/rustc/ui/span/borrowck-let-suggestion-suffixes.rs: New test. * rust/rustc/ui/span/borrowck-object-mutability.rs: New test. * rust/rustc/ui/span/borrowck-ref-into-rvalue.rs: New test. * rust/rustc/ui/span/coerce-suggestions.rs: New test. * rust/rustc/ui/span/destructor-restrictions.rs: New test. * rust/rustc/ui/span/dropck-object-cycle.rs: New test. * rust/rustc/ui/span/dropck_arr_cycle_checked.rs: New test. * rust/rustc/ui/span/dropck_direct_cycle_with_drop.rs: New test. * rust/rustc/ui/span/dropck_misc_variants.rs: New test. * rust/rustc/ui/span/dropck_vec_cycle_checked.rs: New test. * rust/rustc/ui/span/gated-features-attr-spans.rs: New test. * rust/rustc/ui/span/impl-wrong-item-for-trait.rs: New test. * rust/rustc/ui/span/import-ty-params.rs: New test. * rust/rustc/ui/span/issue-11925.rs: New test. * rust/rustc/ui/span/issue-15480.rs: New test. * rust/rustc/ui/span/issue-23338-locals-die-before-temps-of-body.rs: New test. * rust/rustc/ui/span/issue-23729.rs: New test. * rust/rustc/ui/span/issue-23827.rs: New test. * rust/rustc/ui/span/issue-24356.rs: New test. * rust/rustc/ui/span/issue-24690.rs: New test. * rust/rustc/ui/span/issue-24805-dropck-child-has-items-via-parent.rs: New test. * rust/rustc/ui/span/issue-24805-dropck-trait-has-items.rs: New test. * rust/rustc/ui/span/issue-24895-copy-clone-dropck.rs: New test. * rust/rustc/ui/span/issue-25199.rs: New test. * rust/rustc/ui/span/issue-26656.rs: New test. * rust/rustc/ui/span/issue-27522.rs: New test. * rust/rustc/ui/span/issue-29106.rs: New test. * rust/rustc/ui/span/issue-29595.rs: New test. * rust/rustc/ui/span/issue-33884.rs: New test. * rust/rustc/ui/span/issue-34264.rs: New test. * rust/rustc/ui/span/issue-35987.rs: New test. * rust/rustc/ui/span/issue-36530.rs: New test. * rust/rustc/ui/span/issue-36537.rs: New test. * rust/rustc/ui/span/issue-37767.rs: New test. * rust/rustc/ui/span/issue-39018.rs: New test. * rust/rustc/ui/span/issue-39698.rs: New test. * rust/rustc/ui/span/issue-40157.rs: New test. * rust/rustc/ui/span/issue-42234-unknown-receiver-type.rs: New test. * rust/rustc/ui/span/issue-43927-non-ADT-derive.rs: New test. * rust/rustc/ui/span/issue-7575.rs: New test. * rust/rustc/ui/span/issue28498-reject-ex1.rs: New test. * rust/rustc/ui/span/issue28498-reject-lifetime-param.rs: New test. * rust/rustc/ui/span/issue28498-reject-passed-to-fn.rs: New test. * rust/rustc/ui/span/issue28498-reject-trait-bound.rs: New test. * rust/rustc/ui/span/lint-unused-unsafe.rs: New test. * rust/rustc/ui/span/macro-span-replacement.rs: New test. * rust/rustc/ui/span/macro-ty-params.rs: New test. * rust/rustc/ui/span/method-and-field-eager-resolution.rs: New test. * rust/rustc/ui/span/missing-unit-argument.rs: New test. * rust/rustc/ui/span/move-closure.rs: New test. * rust/rustc/ui/span/multiline-span-E0072.rs: New test. * rust/rustc/ui/span/multiline-span-simple.rs: New test. * rust/rustc/ui/span/multispan-import-lint.rs: New test. * rust/rustc/ui/span/mut-arg-hint.rs: New test. * rust/rustc/ui/span/mut-ptr-cant-outlive-ref.rs: New test. * rust/rustc/ui/span/non-existing-module-import.rs: New test. * rust/rustc/ui/span/pub-struct-field.rs: New test. * rust/rustc/ui/span/range-2.rs: New test. * rust/rustc/ui/span/recursive-type-field.rs: New test. * rust/rustc/ui/span/regionck-unboxed-closure-lifetimes.rs: New test. * rust/rustc/ui/span/regions-close-over-borrowed-ref-in-obj.rs: New test. * rust/rustc/ui/span/regions-close-over-type-parameter-2.rs: New test. * rust/rustc/ui/span/regions-escape-loop-via-variable.rs: New test. * rust/rustc/ui/span/regions-escape-loop-via-vec.rs: New test. * rust/rustc/ui/span/regions-infer-borrow-scope-within-loop.rs: New test. * rust/rustc/ui/span/send-is-not-static-ensures-scoping.rs: New test. * rust/rustc/ui/span/send-is-not-static-std-sync-2.rs: New test. * rust/rustc/ui/span/send-is-not-static-std-sync.rs: New test. * rust/rustc/ui/span/slice-borrow.rs: New test. * rust/rustc/ui/span/suggestion-non-ascii.rs: New test. * rust/rustc/ui/span/transitive-dep-span.rs: New test. * rust/rustc/ui/span/type-annotations-needed-expr.rs: New test. * rust/rustc/ui/span/type-binding.rs: New test. * rust/rustc/ui/span/typo-suggestion.rs: New test. * rust/rustc/ui/span/unused-warning-point-at-identifier.rs: New test. * rust/rustc/ui/span/vec-must-not-hide-type-from-dropck.rs: New test. * rust/rustc/ui/span/vec_refs_data_with_early_death.rs: New test. * rust/rustc/ui/span/visibility-ty-params.rs: New test. * rust/rustc/ui/span/wf-method-late-bound-regions.rs: New test. * rust/rustc/ui/specialization/assoc-ty-graph-cycle.rs: New test. * rust/rustc/ui/specialization/auxiliary/cross_crates_defaults.rs: New test. * rust/rustc/ui/specialization/auxiliary/go_trait.rs: New test. * rust/rustc/ui/specialization/auxiliary/specialization_cross_crate.rs: New test. * rust/rustc/ui/specialization/cross-crate-defaults.rs: New test. * rust/rustc/ui/specialization/deafult-associated-type-bound-1.rs: New test. * rust/rustc/ui/specialization/deafult-associated-type-bound-2.rs: New test. * rust/rustc/ui/specialization/deafult-generic-associated-type-bound.rs: New test. * rust/rustc/ui/specialization/defaultimpl/allowed-cross-crate.rs: New test. * rust/rustc/ui/specialization/defaultimpl/auxiliary/go_trait.rs: New test. * rust/rustc/ui/specialization/defaultimpl/out-of-order.rs: New test. * rust/rustc/ui/specialization/defaultimpl/overlap-projection.rs: New test. * rust/rustc/ui/specialization/defaultimpl/projection.rs: New test. * rust/rustc/ui/specialization/defaultimpl/specialization-feature-gate-default.rs: New test. * rust/rustc/ui/specialization/defaultimpl/specialization-no-default.rs: New test. * rust/rustc/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs: New test. * rust/rustc/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs: New test. * rust/rustc/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs: New test. * rust/rustc/ui/specialization/defaultimpl/specialization-wfcheck.rs: New test. * rust/rustc/ui/specialization/defaultimpl/validation.rs: New test. * rust/rustc/ui/specialization/issue-36804.rs: New test. * rust/rustc/ui/specialization/issue-38091-2.rs: New test. * rust/rustc/ui/specialization/issue-38091.rs: New test. * rust/rustc/ui/specialization/issue-39448.rs: New test. * rust/rustc/ui/specialization/issue-39618.rs: New test. * rust/rustc/ui/specialization/issue-44861.rs: New test. * rust/rustc/ui/specialization/issue-50452.rs: New test. * rust/rustc/ui/specialization/issue-52050.rs: New test. * rust/rustc/ui/specialization/issue-59435.rs: New test. * rust/rustc/ui/specialization/issue-63716-parse-async.rs: New test. * rust/rustc/ui/specialization/issue-70442.rs: New test. * rust/rustc/ui/specialization/min_specialization/auxiliary/specialization-trait.rs: New test. * rust/rustc/ui/specialization/min_specialization/dyn-trait-assoc-types.rs: New test. * rust/rustc/ui/specialization/min_specialization/impl-on-nonexisting.rs: New test. * rust/rustc/ui/specialization/min_specialization/impl_specialization_trait.rs: New test. * rust/rustc/ui/specialization/min_specialization/implcit-well-formed-bounds.rs: New test. * rust/rustc/ui/specialization/min_specialization/repeated_projection_type.rs: New test. * rust/rustc/ui/specialization/min_specialization/repeating_lifetimes.rs: New test. * rust/rustc/ui/specialization/min_specialization/repeating_param.rs: New test. * rust/rustc/ui/specialization/min_specialization/spec-iter.rs: New test. * rust/rustc/ui/specialization/min_specialization/spec-reference.rs: New test. * rust/rustc/ui/specialization/min_specialization/specialization_marker.rs: New test. * rust/rustc/ui/specialization/min_specialization/specialization_super_trait.rs: New test. * rust/rustc/ui/specialization/min_specialization/specialization_trait.rs: New test. * rust/rustc/ui/specialization/min_specialization/specialize_on_marker.rs: New test. * rust/rustc/ui/specialization/min_specialization/specialize_on_spec_trait.rs: New test. * rust/rustc/ui/specialization/min_specialization/specialize_on_static.rs: New test. * rust/rustc/ui/specialization/min_specialization/specialize_on_trait.rs: New test. * rust/rustc/ui/specialization/non-defaulted-item-fail.rs: New test. * rust/rustc/ui/specialization/soundness/partial_eq_range_inclusive.rs: New test. * rust/rustc/ui/specialization/soundness/partial_ord_slice.rs: New test. * rust/rustc/ui/specialization/specialization-allowed-cross-crate.rs: New test. * rust/rustc/ui/specialization/specialization-assoc-fns.rs: New test. * rust/rustc/ui/specialization/specialization-basics.rs: New test. * rust/rustc/ui/specialization/specialization-cross-crate-no-gate.rs: New test. * rust/rustc/ui/specialization/specialization-cross-crate.rs: New test. * rust/rustc/ui/specialization/specialization-default-methods.rs: New test. * rust/rustc/ui/specialization/specialization-default-projection.rs: New test. * rust/rustc/ui/specialization/specialization-default-types.rs: New test. * rust/rustc/ui/specialization/specialization-feature-gate-default.rs: New test. * rust/rustc/ui/specialization/specialization-feature-gate-overlap.rs: New test. * rust/rustc/ui/specialization/specialization-no-default.rs: New test. * rust/rustc/ui/specialization/specialization-on-projection.rs: New test. * rust/rustc/ui/specialization/specialization-out-of-order.rs: New test. * rust/rustc/ui/specialization/specialization-overlap-hygiene.rs: New test. * rust/rustc/ui/specialization/specialization-overlap-negative.rs: New test. * rust/rustc/ui/specialization/specialization-overlap-projection.rs: New test. * rust/rustc/ui/specialization/specialization-overlap.rs: New test. * rust/rustc/ui/specialization/specialization-polarity.rs: New test. * rust/rustc/ui/specialization/specialization-projection-alias.rs: New test. * rust/rustc/ui/specialization/specialization-projection.rs: New test. * rust/rustc/ui/specialization/specialization-super-traits.rs: New test. * rust/rustc/ui/specialization/specialization-translate-projections-with-lifetimes.rs: New test. * rust/rustc/ui/specialization/specialization-translate-projections-with-params.rs: New test. * rust/rustc/ui/specialization/specialization-translate-projections.rs: New test. * rust/rustc/ui/sse2.rs: New test. * rust/rustc/ui/stability-attribute/auxiliary/stability_attribute_issue.rs: New test. * rust/rustc/ui/stability-attribute/auxiliary/unstable_generic_param.rs: New test. * rust/rustc/ui/stability-attribute/generics-default-stability-where.rs: New test. * rust/rustc/ui/stability-attribute/generics-default-stability.rs: New test. * rust/rustc/ui/stability-attribute/missing-const-stability.rs: New test. * rust/rustc/ui/stability-attribute/missing-stability-attr-at-top-level.rs: New test. * rust/rustc/ui/stability-attribute/stability-attribute-issue-43027.rs: New test. * rust/rustc/ui/stability-attribute/stability-attribute-issue.rs: New test. * rust/rustc/ui/stability-attribute/stability-attribute-non-staged-force-unstable.rs: New test. * rust/rustc/ui/stability-attribute/stability-attribute-non-staged.rs: New test. * rust/rustc/ui/stability-attribute/stability-attribute-sanity-2.rs: New test. * rust/rustc/ui/stability-attribute/stability-attribute-sanity-3.rs: New test. * rust/rustc/ui/stability-attribute/stability-attribute-sanity-4.rs: New test. * rust/rustc/ui/stability-attribute/stability-attribute-sanity.rs: New test. * rust/rustc/ui/stability-attribute/stability-attribute-trait-impl.rs: New test. * rust/rustc/ui/stability-in-private-module.rs: New test. * rust/rustc/ui/stable-addr-of.rs: New test. * rust/rustc/ui/stable-features.rs: New test. * rust/rustc/ui/static/auxiliary/issue_24843.rs: New test. * rust/rustc/ui/static/auxiliary/static-priv-by-default.rs: New test. * rust/rustc/ui/static/auxiliary/static_priv_by_default.rs: New test. * rust/rustc/ui/static/issue-24843.rs: New test. * rust/rustc/ui/static/static-closures.rs: New test. * rust/rustc/ui/static/static-drop-scope.rs: New test. * rust/rustc/ui/static/static-extern-type.rs: New test. * rust/rustc/ui/static/static-items-cant-move.rs: New test. * rust/rustc/ui/static/static-lifetime-bound.rs: New test. * rust/rustc/ui/static/static-lifetime.rs: New test. * rust/rustc/ui/static/static-method-privacy.rs: New test. * rust/rustc/ui/static/static-mut-bad-types.rs: New test. * rust/rustc/ui/static/static-mut-foreign-requires-unsafe.rs: New test. * rust/rustc/ui/static/static-mut-not-constant.rs: New test. * rust/rustc/ui/static/static-mut-not-pat.rs: New test. * rust/rustc/ui/static/static-mut-requires-unsafe.rs: New test. * rust/rustc/ui/static/static-priv-by-default2.rs: New test. * rust/rustc/ui/static/static-reference-to-fn-1.rs: New test. * rust/rustc/ui/static/static-reference-to-fn-2.rs: New test. * rust/rustc/ui/static/static-region-bound.rs: New test. * rust/rustc/ui/static/static-vec-repeat-not-constant.rs: New test. * rust/rustc/ui/static_sized_requirement.rs: New test. * rust/rustc/ui/staticness-mismatch.rs: New test. * rust/rustc/ui/statics/auxiliary/static-function-pointer-aux.rs: New test. * rust/rustc/ui/statics/auxiliary/static-methods-crate.rs: New test. * rust/rustc/ui/statics/auxiliary/static_fn_inline_xc_aux.rs: New test. * rust/rustc/ui/statics/auxiliary/static_fn_trait_xc_aux.rs: New test. * rust/rustc/ui/statics/auxiliary/static_mut_xc.rs: New test. * rust/rustc/ui/statics/static-fn-inline-xc.rs: New test. * rust/rustc/ui/statics/static-fn-trait-xc.rs: New test. * rust/rustc/ui/statics/static-function-pointer-xc.rs: New test. * rust/rustc/ui/statics/static-function-pointer.rs: New test. * rust/rustc/ui/statics/static-impl.rs: New test. * rust/rustc/ui/statics/static-method-in-trait-with-tps-intracrate.rs: New test. * rust/rustc/ui/statics/static-method-xcrate.rs: New test. * rust/rustc/ui/statics/static-methods-in-traits.rs: New test. * rust/rustc/ui/statics/static-methods-in-traits2.rs: New test. * rust/rustc/ui/statics/static-mut-xc.rs: New test. * rust/rustc/ui/statics/static-promotion.rs: New test. * rust/rustc/ui/statics/static-recursive.rs: New test. * rust/rustc/ui/statics/uninhabited-static.rs: New test. * rust/rustc/ui/std-backtrace.rs: New test. * rust/rustc/ui/std-uncopyable-atomics.rs: New test. * rust/rustc/ui/stdio-is-blocking.rs: New test. * rust/rustc/ui/stdout-during-shutdown.rs: New test. * rust/rustc/ui/stmt_expr_attrs_no_feature.rs: New test. * rust/rustc/ui/str/str-array-assignment.rs: New test. * rust/rustc/ui/str/str-as-char.rs: New test. * rust/rustc/ui/str/str-concat-on-double-ref.rs: New test. * rust/rustc/ui/str/str-idx.rs: New test. * rust/rustc/ui/str/str-lit-type-mismatch.rs: New test. * rust/rustc/ui/str/str-mut-idx.rs: New test. * rust/rustc/ui/str/str-overrun.rs: New test. * rust/rustc/ui/string-box-error.rs: New test. * rust/rustc/ui/struct-ctor-mangling.rs: New test. * rust/rustc/ui/struct-literal-variant-in-if.rs: New test. * rust/rustc/ui/structs-enums/align-enum.rs: New test. * rust/rustc/ui/structs-enums/align-struct.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/cci_class.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/cci_class_2.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/cci_class_3.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/cci_class_4.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/cci_class_6.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/cci_class_cast.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/cci_class_trait.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/empty-struct.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/namespaced_enums.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/newtype_struct_xc.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/struct_destructuring_cross_crate.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/struct_variant_xc_aux.rs: New test. * rust/rustc/ui/structs-enums/auxiliary/xcrate_struct_aliases.rs: New test. * rust/rustc/ui/structs-enums/borrow-tuple-fields.rs: New test. * rust/rustc/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs: New test. * rust/rustc/ui/structs-enums/class-cast-to-trait-multiple-types.rs: New test. * rust/rustc/ui/structs-enums/class-cast-to-trait.rs: New test. * rust/rustc/ui/structs-enums/class-dtor.rs: New test. * rust/rustc/ui/structs-enums/class-exports.rs: New test. * rust/rustc/ui/structs-enums/class-impl-very-parameterized-trait.rs: New test. * rust/rustc/ui/structs-enums/class-implement-trait-cross-crate.rs: New test. * rust/rustc/ui/structs-enums/class-implement-traits.rs: New test. * rust/rustc/ui/structs-enums/class-method-cross-crate.rs: New test. * rust/rustc/ui/structs-enums/class-methods-cross-crate.rs: New test. * rust/rustc/ui/structs-enums/class-methods.rs: New test. * rust/rustc/ui/structs-enums/class-poly-methods-cross-crate.rs: New test. * rust/rustc/ui/structs-enums/class-poly-methods.rs: New test. * rust/rustc/ui/structs-enums/class-separate-impl.rs: New test. * rust/rustc/ui/structs-enums/class-str-field.rs: New test. * rust/rustc/ui/structs-enums/class-typarams.rs: New test. * rust/rustc/ui/structs-enums/classes-cross-crate.rs: New test. * rust/rustc/ui/structs-enums/classes-self-referential.rs: New test. * rust/rustc/ui/structs-enums/classes-simple-cross-crate.rs: New test. * rust/rustc/ui/structs-enums/classes-simple-method.rs: New test. * rust/rustc/ui/structs-enums/classes-simple.rs: New test. * rust/rustc/ui/structs-enums/classes.rs: New test. * rust/rustc/ui/structs-enums/codegen-tag-static-padding.rs: New test. * rust/rustc/ui/structs-enums/compare-generic-enums.rs: New test. * rust/rustc/ui/structs-enums/discrim-explicit-23030.rs: New test. * rust/rustc/ui/structs-enums/empty-struct-braces.rs: New test. * rust/rustc/ui/structs-enums/empty-tag.rs: New test. * rust/rustc/ui/structs-enums/enum-alignment.rs: New test. * rust/rustc/ui/structs-enums/enum-clike-ffi-as-int.rs: New test. * rust/rustc/ui/structs-enums/enum-discr.rs: New test. * rust/rustc/ui/structs-enums/enum-discrim-autosizing.rs: New test. * rust/rustc/ui/structs-enums/enum-discrim-manual-sizing.rs: New test. * rust/rustc/ui/structs-enums/enum-discrim-range-overflow.rs: New test. * rust/rustc/ui/structs-enums/enum-discrim-width-stuff.rs: New test. * rust/rustc/ui/structs-enums/enum-disr-val-pretty.rs: New test. * rust/rustc/ui/structs-enums/enum-export-inheritance.rs: New test. * rust/rustc/ui/structs-enums/enum-layout-optimization.rs: New test. * rust/rustc/ui/structs-enums/enum-non-c-like-repr-c-and-int.rs: New test. * rust/rustc/ui/structs-enums/enum-non-c-like-repr-c.rs: New test. * rust/rustc/ui/structs-enums/enum-non-c-like-repr-int.rs: New test. * rust/rustc/ui/structs-enums/enum-null-pointer-opt.rs: New test. * rust/rustc/ui/structs-enums/enum-nullable-const-null-with-fields.rs: New test. * rust/rustc/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs: New test. * rust/rustc/ui/structs-enums/enum-univariant-repr.rs: New test. * rust/rustc/ui/structs-enums/enum-variants.rs: New test. * rust/rustc/ui/structs-enums/enum-vec-initializer.rs: New test. * rust/rustc/ui/structs-enums/export-abstract-tag.rs: New test. * rust/rustc/ui/structs-enums/export-tag-variant.rs: New test. * rust/rustc/ui/structs-enums/expr-if-struct.rs: New test. * rust/rustc/ui/structs-enums/expr-match-struct.rs: New test. * rust/rustc/ui/structs-enums/field-destruction-order.rs: New test. * rust/rustc/ui/structs-enums/foreign-struct.rs: New test. * rust/rustc/ui/structs-enums/functional-struct-upd.rs: New test. * rust/rustc/ui/structs-enums/ivec-tag.rs: New test. * rust/rustc/ui/structs-enums/module-qualified-struct-destructure.rs: New test. * rust/rustc/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs: New test. * rust/rustc/ui/structs-enums/namespaced-enum-emulate-flat.rs: New test. * rust/rustc/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs: New test. * rust/rustc/ui/structs-enums/namespaced-enum-glob-import.rs: New test. * rust/rustc/ui/structs-enums/namespaced-enums-xcrate.rs: New test. * rust/rustc/ui/structs-enums/namespaced-enums.rs: New test. * rust/rustc/ui/structs-enums/nested-enum-same-names.rs: New test. * rust/rustc/ui/structs-enums/newtype-struct-drop-run.rs: New test. * rust/rustc/ui/structs-enums/newtype-struct-with-dtor.rs: New test. * rust/rustc/ui/structs-enums/newtype-struct-xc-2.rs: New test. * rust/rustc/ui/structs-enums/newtype-struct-xc.rs: New test. * rust/rustc/ui/structs-enums/nonzero-enum.rs: New test. * rust/rustc/ui/structs-enums/numeric-fields.rs: New test. * rust/rustc/ui/structs-enums/object-lifetime-default-from-ref-struct.rs: New test. * rust/rustc/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs: New test. * rust/rustc/ui/structs-enums/rec-align-u32.rs: New test. * rust/rustc/ui/structs-enums/rec-align-u64.rs: New test. * rust/rustc/ui/structs-enums/rec-auto.rs: New test. * rust/rustc/ui/structs-enums/rec-extend.rs: New test. * rust/rustc/ui/structs-enums/rec-tup.rs: New test. * rust/rustc/ui/structs-enums/rec.rs: New test. * rust/rustc/ui/structs-enums/record-pat.rs: New test. * rust/rustc/ui/structs-enums/resource-in-struct.rs: New test. * rust/rustc/ui/structs-enums/simple-generic-tag.rs: New test. * rust/rustc/ui/structs-enums/simple-match-generic-tag.rs: New test. * rust/rustc/ui/structs-enums/small-enum-range-edge.rs: New test. * rust/rustc/ui/structs-enums/small-enums-with-fields.rs: New test. * rust/rustc/ui/structs-enums/struct-aliases-xcrate.rs: New test. * rust/rustc/ui/structs-enums/struct-aliases.rs: New test. * rust/rustc/ui/structs-enums/struct-destructuring-cross-crate.rs: New test. * rust/rustc/ui/structs-enums/struct-field-shorthand.rs: New test. * rust/rustc/ui/structs-enums/struct-like-variant-construct.rs: New test. * rust/rustc/ui/structs-enums/struct-like-variant-match.rs: New test. * rust/rustc/ui/structs-enums/struct-lit-functional-no-fields.rs: New test. * rust/rustc/ui/structs-enums/struct-literal-dtor.rs: New test. * rust/rustc/ui/structs-enums/struct-new-as-field-name.rs: New test. * rust/rustc/ui/structs-enums/struct-order-of-eval-1.rs: New test. * rust/rustc/ui/structs-enums/struct-order-of-eval-2.rs: New test. * rust/rustc/ui/structs-enums/struct-order-of-eval-3.rs: New test. * rust/rustc/ui/structs-enums/struct-order-of-eval-4.rs: New test. * rust/rustc/ui/structs-enums/struct-partial-move-1.rs: New test. * rust/rustc/ui/structs-enums/struct-partial-move-2.rs: New test. * rust/rustc/ui/structs-enums/struct-path-associated-type.rs: New test. * rust/rustc/ui/structs-enums/struct-path-self.rs: New test. * rust/rustc/ui/structs-enums/struct-pattern-matching.rs: New test. * rust/rustc/ui/structs-enums/struct-variant-field-visibility.rs: New test. * rust/rustc/ui/structs-enums/struct_variant_xc.rs: New test. * rust/rustc/ui/structs-enums/struct_variant_xc_match.rs: New test. * rust/rustc/ui/structs-enums/tag-align-dyn-u64.rs: New test. * rust/rustc/ui/structs-enums/tag-align-dyn-variants.rs: New test. * rust/rustc/ui/structs-enums/tag-align-shape.rs: New test. * rust/rustc/ui/structs-enums/tag-align-u64.rs: New test. * rust/rustc/ui/structs-enums/tag-disr-val-shape.rs: New test. * rust/rustc/ui/structs-enums/tag-exports.rs: New test. * rust/rustc/ui/structs-enums/tag-in-block.rs: New test. * rust/rustc/ui/structs-enums/tag-variant-disr-type-mismatch.rs: New test. * rust/rustc/ui/structs-enums/tag-variant-disr-val.rs: New test. * rust/rustc/ui/structs-enums/tag.rs: New test. * rust/rustc/ui/structs-enums/tuple-struct-construct.rs: New test. * rust/rustc/ui/structs-enums/tuple-struct-constructor-pointer.rs: New test. * rust/rustc/ui/structs-enums/tuple-struct-destructuring.rs: New test. * rust/rustc/ui/structs-enums/tuple-struct-matching.rs: New test. * rust/rustc/ui/structs-enums/tuple-struct-trivial.rs: New test. * rust/rustc/ui/structs-enums/uninstantiable-struct.rs: New test. * rust/rustc/ui/structs-enums/unit-like-struct-drop-run.rs: New test. * rust/rustc/ui/structs-enums/unit-like-struct.rs: New test. * rust/rustc/ui/structs-enums/variant-structs-trivial.rs: New test. * rust/rustc/ui/structs/auxiliary/struct_field_privacy.rs: New test. * rust/rustc/ui/structs/auxiliary/struct_variant_privacy.rs: New test. * rust/rustc/ui/structs/rhs-type.rs: New test. * rust/rustc/ui/structs/struct-base-wrong-type.rs: New test. * rust/rustc/ui/structs/struct-duplicate-comma.rs: New test. * rust/rustc/ui/structs/struct-field-cfg.rs: New test. * rust/rustc/ui/structs/struct-field-init-syntax.rs: New test. * rust/rustc/ui/structs/struct-field-privacy.rs: New test. * rust/rustc/ui/structs/struct-fields-decl-dupe.rs: New test. * rust/rustc/ui/structs/struct-fields-dupe.rs: New test. * rust/rustc/ui/structs/struct-fields-hints-no-dupe.rs: New test. * rust/rustc/ui/structs/struct-fields-hints.rs: New test. * rust/rustc/ui/structs/struct-fields-missing.rs: New test. * rust/rustc/ui/structs/struct-fields-shorthand-unresolved.rs: New test. * rust/rustc/ui/structs/struct-fields-shorthand.rs: New test. * rust/rustc/ui/structs/struct-fields-too-many.rs: New test. * rust/rustc/ui/structs/struct-fields-typo.rs: New test. * rust/rustc/ui/structs/struct-missing-comma.rs: New test. * rust/rustc/ui/structs/struct-pat-derived-error.rs: New test. * rust/rustc/ui/structs/struct-path-alias-bounds.rs: New test. * rust/rustc/ui/structs/struct-path-associated-type.rs: New test. * rust/rustc/ui/structs/struct-path-self-type-mismatch.rs: New test. * rust/rustc/ui/structs/struct-path-self.rs: New test. * rust/rustc/ui/structs/struct-variant-privacy-xc.rs: New test. * rust/rustc/ui/structs/struct-variant-privacy.rs: New test. * rust/rustc/ui/structs/structure-constructor-type-mismatch.rs: New test. * rust/rustc/ui/structured-compare.rs: New test. * rust/rustc/ui/substs-ppaux.rs: New test. * rust/rustc/ui/suffixed-literal-meta.rs: New test. * rust/rustc/ui/suggestions/adt-param-with-implicit-sized-bound.rs: New test. * rust/rustc/ui/suggestions/as-ref.rs: New test. * rust/rustc/ui/suggestions/assoc-const-as-field.rs: New test. * rust/rustc/ui/suggestions/assoc-type-in-method-return.rs: New test. * rust/rustc/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs: New test. * rust/rustc/ui/suggestions/attribute-typos.rs: New test. * rust/rustc/ui/suggestions/auxiliary/foo.rs: New test. * rust/rustc/ui/suggestions/auxiliary/issue-61963-1.rs: New test. * rust/rustc/ui/suggestions/auxiliary/issue-61963.rs: New test. * rust/rustc/ui/suggestions/auxiliary/struct_field_privacy.rs: New test. * rust/rustc/ui/suggestions/borrow-for-loop-head.rs: New test. * rust/rustc/ui/suggestions/chain-method-call-mutation-in-place.rs: New test. * rust/rustc/ui/suggestions/const-in-struct-pat.rs: New test. * rust/rustc/ui/suggestions/const-no-type.rs: New test. * rust/rustc/ui/suggestions/const-pat-non-exaustive-let-new-var.rs: New test. * rust/rustc/ui/suggestions/constrain-trait.rs: New test. * rust/rustc/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.rs: New test. * rust/rustc/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs: New test. * rust/rustc/ui/suggestions/dont-suggest-ref/move-into-closure.rs: New test. * rust/rustc/ui/suggestions/dont-suggest-ref/simple.rs: New test. * rust/rustc/ui/suggestions/dont-suggest-try_into-in-macros.rs: New test. * rust/rustc/ui/suggestions/expected-boxed-future-isnt-pinned.rs: New test. * rust/rustc/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs: New test. * rust/rustc/ui/suggestions/fn-missing-lifetime-in-item.rs: New test. * rust/rustc/ui/suggestions/fn-needing-specified-return-type-param.rs: New test. * rust/rustc/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs: New test. * rust/rustc/ui/suggestions/fn-or-tuple-struct-without-args.rs: New test. * rust/rustc/ui/suggestions/fn-trait-notation.rs: New test. * rust/rustc/ui/suggestions/for-i-in-vec.rs: New test. * rust/rustc/ui/suggestions/format-borrow.rs: New test. * rust/rustc/ui/suggestions/if-let-typo.rs: New test. * rust/rustc/ui/suggestions/imm-ref-trait-object-literal-bound-regions.rs: New test. * rust/rustc/ui/suggestions/imm-ref-trait-object-literal.rs: New test. * rust/rustc/ui/suggestions/imm-ref-trait-object.rs: New test. * rust/rustc/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs: New test. * rust/rustc/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs: New test. * rust/rustc/ui/suggestions/impl-trait-missing-lifetime.rs: New test. * rust/rustc/ui/suggestions/impl-trait-return-trailing-semicolon.rs: New test. * rust/rustc/ui/suggestions/impl-trait-with-missing-bounds.rs: New test. * rust/rustc/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.rs: New test. * rust/rustc/ui/suggestions/into-str.rs: New test. * rust/rustc/ui/suggestions/invalid-bin-op.rs: New test. * rust/rustc/ui/suggestions/issue-21673.rs: New test. * rust/rustc/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.rs: New test. * rust/rustc/ui/suggestions/issue-52820.rs: New test. * rust/rustc/ui/suggestions/issue-57672.rs: New test. * rust/rustc/ui/suggestions/issue-59819.rs: New test. * rust/rustc/ui/suggestions/issue-61226.rs: New test. * rust/rustc/ui/suggestions/issue-61963.rs: New test. * rust/rustc/ui/suggestions/issue-62843.rs: New test. * rust/rustc/ui/suggestions/issue-64252-self-type.rs: New test. * rust/rustc/ui/suggestions/issue-66968-suggest-sorted-words.rs: New test. * rust/rustc/ui/suggestions/issue-71394-no-from-impl.rs: New test. * rust/rustc/ui/suggestions/issue-72766.rs: New test. * rust/rustc/ui/suggestions/js-style-comparison-op-separate-eq-token.rs: New test. * rust/rustc/ui/suggestions/js-style-comparison-op.rs: New test. * rust/rustc/ui/suggestions/let-binding-init-expr-as-ty.rs: New test. * rust/rustc/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs: New test. * rust/rustc/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs: New test. * rust/rustc/ui/suggestions/match-ergonomics.rs: New test. * rust/rustc/ui/suggestions/match-needing-semi.rs: New test. * rust/rustc/ui/suggestions/match-prev-arm-needing-semi.rs: New test. * rust/rustc/ui/suggestions/method-missing-parentheses.rs: New test. * rust/rustc/ui/suggestions/mismatched-types-numeric-from.rs: New test. * rust/rustc/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs: New test. * rust/rustc/ui/suggestions/missing-assoc-fn.rs: New test. * rust/rustc/ui/suggestions/missing-assoc-type-bound-restriction.rs: New test. * rust/rustc/ui/suggestions/missing-lifetime-in-assoc-const-type.rs: New test. * rust/rustc/ui/suggestions/missing-lifetime-specifier.rs: New test. * rust/rustc/ui/suggestions/missing-lt-for-hrtb.rs: New test. * rust/rustc/ui/suggestions/missing-trait-bound-for-op.rs: New test. * rust/rustc/ui/suggestions/missing-trait-bounds-for-method-call.rs: New test. * rust/rustc/ui/suggestions/missing-trait-item.rs: New test. * rust/rustc/ui/suggestions/mut-borrow-needed-by-trait.rs: New test. * rust/rustc/ui/suggestions/mut-ref-reassignment.rs: New test. * rust/rustc/ui/suggestions/no-extern-crate-in-type.rs: New test. * rust/rustc/ui/suggestions/object-unsafe-trait-references-self.rs: New test. * rust/rustc/ui/suggestions/object-unsafe-trait-should-use-self.rs: New test. * rust/rustc/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs: New test. * rust/rustc/ui/suggestions/opaque-type-error.rs: New test. * rust/rustc/ui/suggestions/option-content-move.rs: New test. * rust/rustc/ui/suggestions/option-content-move2.rs: New test. * rust/rustc/ui/suggestions/path-by-value.rs: New test. * rust/rustc/ui/suggestions/path-display.rs: New test. * rust/rustc/ui/suggestions/raw-name-use-suggestion.rs: New test. * rust/rustc/ui/suggestions/recover-from-semicolon-trailing-item.rs: New test. * rust/rustc/ui/suggestions/recover-invalid-float.rs: New test. * rust/rustc/ui/suggestions/recover-missing-turbofish-surrounding-angle-braket.rs: New test. * rust/rustc/ui/suggestions/remove-as_str.rs: New test. * rust/rustc/ui/suggestions/restrict-type-argument.rs: New test. * rust/rustc/ui/suggestions/return-without-lifetime.rs: New test. * rust/rustc/ui/suggestions/struct-initializer-comma.rs: New test. * rust/rustc/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs: New test. * rust/rustc/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs: New test. * rust/rustc/ui/suggestions/suggest-box.rs: New test. * rust/rustc/ui/suggestions/suggest-closure-return-type-1.rs: New test. * rust/rustc/ui/suggestions/suggest-closure-return-type-2.rs: New test. * rust/rustc/ui/suggestions/suggest-closure-return-type-3.rs: New test. * rust/rustc/ui/suggestions/suggest-impl-trait-lifetime.rs: New test. * rust/rustc/ui/suggestions/suggest-labels.rs: New test. * rust/rustc/ui/suggestions/suggest-methods.rs: New test. * rust/rustc/ui/suggestions/suggest-move-lifetimes.rs: New test. * rust/rustc/ui/suggestions/suggest-move-types.rs: New test. * rust/rustc/ui/suggestions/suggest-on-bare-closure-call.rs: New test. * rust/rustc/ui/suggestions/suggest-private-fields.rs: New test. * rust/rustc/ui/suggestions/suggest-ref-mut.rs: New test. * rust/rustc/ui/suggestions/suggest-remove-refs-1.rs: New test. * rust/rustc/ui/suggestions/suggest-remove-refs-2.rs: New test. * rust/rustc/ui/suggestions/suggest-remove-refs-3.rs: New test. * rust/rustc/ui/suggestions/suggest-split-at-mut.rs: New test. * rust/rustc/ui/suggestions/suggest-std-when-using-type.rs: New test. * rust/rustc/ui/suggestions/suggest-variants.rs: New test. * rust/rustc/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.rs: New test. * rust/rustc/ui/suggestions/trait-with-missing-associated-type-restriction.rs: New test. * rust/rustc/ui/suggestions/type-ascription-instead-of-let.rs: New test. * rust/rustc/ui/suggestions/type-ascription-instead-of-method.rs: New test. * rust/rustc/ui/suggestions/type-ascription-instead-of-path-2.rs: New test. * rust/rustc/ui/suggestions/type-ascription-instead-of-path.rs: New test. * rust/rustc/ui/suggestions/type-ascription-instead-of-variant.rs: New test. * rust/rustc/ui/suggestions/type-mismatch-struct-field-shorthand-2.rs: New test. * rust/rustc/ui/suggestions/type-mismatch-struct-field-shorthand.rs: New test. * rust/rustc/ui/suggestions/type-not-found-in-adt-field.rs: New test. * rust/rustc/ui/suggestions/unused-closure-argument.rs: New test. * rust/rustc/ui/suggestions/use-type-argument-instead-of-assoc-type.rs: New test. * rust/rustc/ui/suggestions/vec-macro-in-pattern.rs: New test. * rust/rustc/ui/super-at-top-level.rs: New test. * rust/rustc/ui/super-fast-paren-parsing.rs: New test. * rust/rustc/ui/super.rs: New test. * rust/rustc/ui/supported-cast.rs: New test. * rust/rustc/ui/suppressed-error.rs: New test. * rust/rustc/ui/svh-add-nothing.rs: New test. * rust/rustc/ui/svh/auxiliary/svh-a-base.rs: New test. * rust/rustc/ui/svh/auxiliary/svh-a-change-lit.rs: New test. * rust/rustc/ui/svh/auxiliary/svh-a-change-significant-cfg.rs: New test. * rust/rustc/ui/svh/auxiliary/svh-a-change-trait-bound.rs: New test. * rust/rustc/ui/svh/auxiliary/svh-a-change-type-arg.rs: New test. * rust/rustc/ui/svh/auxiliary/svh-a-change-type-ret.rs: New test. * rust/rustc/ui/svh/auxiliary/svh-a-change-type-static.rs: New test. * rust/rustc/ui/svh/auxiliary/svh-b.rs: New test. * rust/rustc/ui/svh/auxiliary/svh-uta-base.rs: New test. * rust/rustc/ui/svh/auxiliary/svh-uta-change-use-trait.rs: New test. * rust/rustc/ui/svh/auxiliary/svh-utb.rs: New test. * rust/rustc/ui/svh/svh-change-lit.rs: New test. * rust/rustc/ui/svh/svh-change-significant-cfg.rs: New test. * rust/rustc/ui/svh/svh-change-trait-bound.rs: New test. * rust/rustc/ui/svh/svh-change-type-arg.rs: New test. * rust/rustc/ui/svh/svh-change-type-ret.rs: New test. * rust/rustc/ui/svh/svh-change-type-static.rs: New test. * rust/rustc/ui/svh/svh-use-trait.rs: New test. * rust/rustc/ui/swap-1.rs: New test. * rust/rustc/ui/swap-overlapping.rs: New test. * rust/rustc/ui/switched-expectations.rs: New test. * rust/rustc/ui/symbol-names/basic.rs: New test. * rust/rustc/ui/symbol-names/const-generics-demangling.rs: New test. * rust/rustc/ui/symbol-names/const-generics.rs: New test. * rust/rustc/ui/symbol-names/impl1.rs: New test. * rust/rustc/ui/symbol-names/impl2.rs: New test. * rust/rustc/ui/symbol-names/issue-60925.rs: New test. * rust/rustc/ui/symbol-names/issue-75326.rs: New test. * rust/rustc/ui/symbol-names/issue-76365.rs: New test. * rust/rustc/ui/syntax-extension-minor.rs: New test. * rust/rustc/ui/syntax-trait-polarity-feature-gate.rs: New test. * rust/rustc/ui/syntax-trait-polarity.rs: New test. * rust/rustc/ui/synthetic-param.rs: New test. * rust/rustc/ui/tag-that-dare-not-speak-its-name.rs: New test. * rust/rustc/ui/tag-type-args.rs: New test. * rust/rustc/ui/tag-variant-cast-non-nullary.rs: New test. * rust/rustc/ui/tag-variant-disr-dup.rs: New test. * rust/rustc/ui/tail-call-arg-leak.rs: New test. * rust/rustc/ui/tail-cps.rs: New test. * rust/rustc/ui/tail-direct.rs: New test. * rust/rustc/ui/tail-typeck.rs: New test. * rust/rustc/ui/target-feature/gate.rs: New test. * rust/rustc/ui/target-feature/invalid-attribute.rs: New test. * rust/rustc/ui/tcp-stress.rs: New test. * rust/rustc/ui/terminal-width/flag-human.rs: New test. * rust/rustc/ui/terminal-width/flag-json.rs: New test. * rust/rustc/ui/terminal-width/non-1-width-unicode-multiline-label.rs: New test. * rust/rustc/ui/terminal-width/non-whitespace-trimming-2.rs: New test. * rust/rustc/ui/terminal-width/non-whitespace-trimming-unicode.rs: New test. * rust/rustc/ui/terminal-width/non-whitespace-trimming.rs: New test. * rust/rustc/ui/terminal-width/whitespace-trimming-2.rs: New test. * rust/rustc/ui/terminal-width/whitespace-trimming.rs: New test. * rust/rustc/ui/terminate-in-initializer.rs: New test. * rust/rustc/ui/terr-in-field.rs: New test. * rust/rustc/ui/terr-sorts.rs: New test. * rust/rustc/ui/test-allow-dead-extern-static-no-warning.rs: New test. * rust/rustc/ui/test-attrs/auxiliary/test_macro.rs: New test. * rust/rustc/ui/test-attrs/decl-macro-test.rs: New test. * rust/rustc/ui/test-attrs/inaccessible-test-modules.rs: New test. * rust/rustc/ui/test-attrs/run-unexported-tests.rs: New test. * rust/rustc/ui/test-attrs/test-allow-fail-attr.rs: New test. * rust/rustc/ui/test-attrs/test-attr-non-associated-functions.rs: New test. * rust/rustc/ui/test-attrs/test-cant-be-shadowed.rs: New test. * rust/rustc/ui/test-attrs/test-fn-signature-verification-for-explicit-return-type.rs: New test. * rust/rustc/ui/test-attrs/test-main-not-dead-attr.rs: New test. * rust/rustc/ui/test-attrs/test-main-not-dead.rs: New test. * rust/rustc/ui/test-attrs/test-on-macro.rs: New test. * rust/rustc/ui/test-attrs/test-runner-hides-buried-main.rs: New test. * rust/rustc/ui/test-attrs/test-runner-hides-main.rs: New test. * rust/rustc/ui/test-attrs/test-runner-hides-start.rs: New test. * rust/rustc/ui/test-attrs/test-should-fail-good-message.rs: New test. * rust/rustc/ui/test-attrs/test-should-panic-attr.rs: New test. * rust/rustc/ui/test-attrs/test-vs-cfg-test.rs: New test. * rust/rustc/ui/test-attrs/test-warns-dead-code.rs: New test. * rust/rustc/ui/test-cfg.rs: New test. * rust/rustc/ui/test-panic-abort-disabled.rs: New test. * rust/rustc/ui/test-panic-abort-nocapture.rs: New test. * rust/rustc/ui/test-panic-abort.rs: New test. * rust/rustc/ui/test-panic-while-printing.rs: New test. * rust/rustc/ui/test-thread-capture.rs: New test. * rust/rustc/ui/test-thread-nocapture.rs: New test. * rust/rustc/ui/thin-lto-global-allocator.rs: New test. * rust/rustc/ui/thinlto/all-crates.rs: New test. * rust/rustc/ui/thinlto/auxiliary/dylib.rs: New test. * rust/rustc/ui/thinlto/auxiliary/msvc-imp-present.rs: New test. * rust/rustc/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs: New test. * rust/rustc/ui/thinlto/dylib-works.rs: New test. * rust/rustc/ui/thinlto/msvc-imp-present.rs: New test. * rust/rustc/ui/thinlto/thin-lto-inlines.rs: New test. * rust/rustc/ui/thinlto/thin-lto-inlines2.rs: New test. * rust/rustc/ui/thinlto/weak-works.rs: New test. * rust/rustc/ui/thread-local-in-ctfe.rs: New test. * rust/rustc/ui/thread-local-mutation.rs: New test. * rust/rustc/ui/thread-local-not-in-prelude.rs: New test. * rust/rustc/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs: New test. * rust/rustc/ui/threads-sendsync/comm.rs: New test. * rust/rustc/ui/threads-sendsync/send-is-not-static-par-for.rs: New test. * rust/rustc/ui/threads-sendsync/send-resource.rs: New test. * rust/rustc/ui/threads-sendsync/send-type-inference.rs: New test. * rust/rustc/ui/threads-sendsync/send_str_hashmap.rs: New test. * rust/rustc/ui/threads-sendsync/send_str_treemap.rs: New test. * rust/rustc/ui/threads-sendsync/sendable-class.rs: New test. * rust/rustc/ui/threads-sendsync/sendfn-is-a-block.rs: New test. * rust/rustc/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs: New test. * rust/rustc/ui/threads-sendsync/spawn-fn.rs: New test. * rust/rustc/ui/threads-sendsync/spawn-types.rs: New test. * rust/rustc/ui/threads-sendsync/spawn.rs: New test. * rust/rustc/ui/threads-sendsync/spawn2.rs: New test. * rust/rustc/ui/threads-sendsync/spawning-with-debug.rs: New test. * rust/rustc/ui/threads-sendsync/std-sync-right-kind-impls.rs: New test. * rust/rustc/ui/threads-sendsync/sync-send-atomics.rs: New test. * rust/rustc/ui/threads-sendsync/sync-send-in-std.rs: New test. * rust/rustc/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs: New test. * rust/rustc/ui/threads-sendsync/sync-send-iterators-in-libcore.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-0.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-1.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-10.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-11.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-12.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-13.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-14.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-15.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-16.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-17.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-3.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-4.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-5.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-6.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-7.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-9.rs: New test. * rust/rustc/ui/threads-sendsync/task-comm-chan-nil.rs: New test. * rust/rustc/ui/threads-sendsync/task-life-0.rs: New test. * rust/rustc/ui/threads-sendsync/task-spawn-barefn.rs: New test. * rust/rustc/ui/threads-sendsync/task-spawn-move-and-copy.rs: New test. * rust/rustc/ui/threads-sendsync/task-stderr.rs: New test. * rust/rustc/ui/threads-sendsync/test-tasks-invalid-value.rs: New test. * rust/rustc/ui/threads-sendsync/thread-local-extern-static.rs: New test. * rust/rustc/ui/threads-sendsync/thread-local-syntax.rs: New test. * rust/rustc/ui/threads-sendsync/threads.rs: New test. * rust/rustc/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs: New test. * rust/rustc/ui/threads-sendsync/tls-init-on-init.rs: New test. * rust/rustc/ui/threads-sendsync/tls-try-with.rs: New test. * rust/rustc/ui/tls.rs: New test. * rust/rustc/ui/tool-attributes/diagnostic_item.rs: New test. * rust/rustc/ui/tool-attributes/diagnostic_item2.rs: New test. * rust/rustc/ui/tool-attributes/diagnostic_item3.rs: New test. * rust/rustc/ui/tool-attributes/tool-attributes-misplaced-1.rs: New test. * rust/rustc/ui/tool-attributes/tool-attributes-misplaced-2.rs: New test. * rust/rustc/ui/tool-attributes/tool-attributes-shadowing.rs: New test. * rust/rustc/ui/tool_attributes.rs: New test. * rust/rustc/ui/tool_lints-fail.rs: New test. * rust/rustc/ui/tool_lints-rpass.rs: New test. * rust/rustc/ui/tool_lints.rs: New test. * rust/rustc/ui/tool_lints_2018_preview.rs: New test. * rust/rustc/ui/trace_macros-format.rs: New test. * rust/rustc/ui/trace_macros-gate.rs: New test. * rust/rustc/ui/trailing-comma.rs: New test. * rust/rustc/ui/trait-impl-bound-suggestions.rs: New test. * rust/rustc/ui/trait-method-number-parameters.rs: New test. * rust/rustc/ui/traits/anon-trait-static-method.rs: New test. * rust/rustc/ui/traits/anon_trait_static_method_exe.rs: New test. * rust/rustc/ui/traits/assignability-trait.rs: New test. * rust/rustc/ui/traits/assoc_type_bound_with_struct.rs: New test. * rust/rustc/ui/traits/astconv-cycle-between-trait-and-type.rs: New test. * rust/rustc/ui/traits/augmented-assignments-trait.rs: New test. * rust/rustc/ui/traits/auxiliary/anon_trait_static_method_lib.rs: New test. * rust/rustc/ui/traits/auxiliary/crate_a1.rs: New test. * rust/rustc/ui/traits/auxiliary/crate_a2.rs: New test. * rust/rustc/ui/traits/auxiliary/go_trait.rs: New test. * rust/rustc/ui/traits/auxiliary/trait_alias.rs: New test. * rust/rustc/ui/traits/auxiliary/trait_bounds_on_structs_and_enums_xc.rs: New test. * rust/rustc/ui/traits/auxiliary/trait_default_method_xc_aux.rs: New test. * rust/rustc/ui/traits/auxiliary/trait_default_method_xc_aux_2.rs: New test. * rust/rustc/ui/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs: New test. * rust/rustc/ui/traits/auxiliary/trait_inheritance_auto_xc_aux.rs: New test. * rust/rustc/ui/traits/auxiliary/trait_inheritance_overloading_xc.rs: New test. * rust/rustc/ui/traits/auxiliary/trait_safety_lib.rs: New test. * rust/rustc/ui/traits/auxiliary/trait_xc_call_aux.rs: New test. * rust/rustc/ui/traits/auxiliary/traitimpl.rs: New test. * rust/rustc/ui/traits/check-trait-object-bounds-1.rs: New test. * rust/rustc/ui/traits/check-trait-object-bounds-2-ok.rs: New test. * rust/rustc/ui/traits/check-trait-object-bounds-2.rs: New test. * rust/rustc/ui/traits/check-trait-object-bounds-3.rs: New test. * rust/rustc/ui/traits/check-trait-object-bounds-4.rs: New test. * rust/rustc/ui/traits/check-trait-object-bounds-5.rs: New test. * rust/rustc/ui/traits/check-trait-object-bounds-6.rs: New test. * rust/rustc/ui/traits/conservative_impl_trait.rs: New test. * rust/rustc/ui/traits/cycle-cache-err-60010.rs: New test. * rust/rustc/ui/traits/cycle-trait-type-trait.rs: New test. * rust/rustc/ui/traits/default-method-supertrait-vtable.rs: New test. * rust/rustc/ui/traits/dyn-trait.rs: New test. * rust/rustc/ui/traits/fmt-pointer-trait.rs: New test. * rust/rustc/ui/traits/impl-evaluation-order.rs: New test. * rust/rustc/ui/traits/impl-implicit-trait.rs: New test. * rust/rustc/ui/traits/impl-inherent-prefer-over-trait.rs: New test. * rust/rustc/ui/traits/impl_trait_as_trait_return_position.rs: New test. * rust/rustc/ui/traits/infer-from-object-trait-issue-26952.rs: New test. * rust/rustc/ui/traits/inherent-trait-method-order.rs: New test. * rust/rustc/ui/traits/issue-70944.rs: New test. * rust/rustc/ui/traits/issue-72410.rs: New test. * rust/rustc/ui/traits/issue-75627.rs: New test. * rust/rustc/ui/traits/issue-77982.rs: New test. * rust/rustc/ui/traits/kindck-owned-trait-contains-1.rs: New test. * rust/rustc/ui/traits/multiple-trait-bounds.rs: New test. * rust/rustc/ui/traits/negative-impls/auxiliary/foreign_trait.rs: New test. * rust/rustc/ui/traits/negative-impls/feature-gate-negative_impls.rs: New test. * rust/rustc/ui/traits/negative-impls/negated-auto-traits-error.rs: New test. * rust/rustc/ui/traits/negative-impls/negated-auto-traits-rpass.rs: New test. * rust/rustc/ui/traits/negative-impls/negative-default-impls.rs: New test. * rust/rustc/ui/traits/negative-impls/negative-impls-basic.rs: New test. * rust/rustc/ui/traits/negative-impls/negative-specializes-negative.rs: New test. * rust/rustc/ui/traits/negative-impls/negative-specializes-positive-item.rs: New test. * rust/rustc/ui/traits/negative-impls/negative-specializes-positive.rs: New test. * rust/rustc/ui/traits/negative-impls/no-items.rs: New test. * rust/rustc/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs: New test. * rust/rustc/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs: New test. * rust/rustc/ui/traits/negative-impls/positive-specializes-negative.rs: New test. * rust/rustc/ui/traits/negative-impls/rely-on-negative-impl-in-coherence.rs: New test. * rust/rustc/ui/traits/normalize-super-trait.rs: New test. * rust/rustc/ui/traits/object-one-type-two-traits.rs: New test. * rust/rustc/ui/traits/overlap-not-permitted-for-builtin-trait.rs: New test. * rust/rustc/ui/traits/overlap-permitted-for-marker-traits.rs: New test. * rust/rustc/ui/traits/parameterized-trait-with-bounds.rs: New test. * rust/rustc/ui/traits/principal-less-trait-objects.rs: New test. * rust/rustc/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs: New test. * rust/rustc/ui/traits/reservation-impls/reservation-impl-no-use.rs: New test. * rust/rustc/ui/traits/reservation-impls/reservation-impl-non-lattice-ok.rs: New test. * rust/rustc/ui/traits/reservation-impls/reservation-impl-ok.rs: New test. * rust/rustc/ui/traits/self-without-lifetime-constraint.rs: New test. * rust/rustc/ui/traits/supertrait-default-generics.rs: New test. * rust/rustc/ui/traits/syntax-trait-polarity.rs: New test. * rust/rustc/ui/traits/trait-alias-ambiguous.rs: New test. * rust/rustc/ui/traits/trait-alias-import-cross-crate.rs: New test. * rust/rustc/ui/traits/trait-alias-import.rs: New test. * rust/rustc/ui/traits/trait-alias/auxiliary/trait_alias.rs: New test. * rust/rustc/ui/traits/trait-alias/issue-60021-assoc-method-resolve.rs: New test. * rust/rustc/ui/traits/trait-alias/issue-72415-assoc-const-resolve.rs: New test. * rust/rustc/ui/traits/trait-alias/issue-75983.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-bounds.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-cross-crate.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-impl.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-maybe-bound.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-no-duplicates.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-no-extra-traits.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-object-fail.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-object-wf.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-object.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-only-maybe-bound.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-syntax-fail.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-syntax.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias-wf.rs: New test. * rust/rustc/ui/traits/trait-alias/trait-alias.rs: New test. * rust/rustc/ui/traits/trait-as-struct-constructor.rs: New test. * rust/rustc/ui/traits/trait-bounds-basic.rs: New test. * rust/rustc/ui/traits/trait-bounds-impl-comparison-duplicates.rs: New test. * rust/rustc/ui/traits/trait-bounds-in-arc.rs: New test. * rust/rustc/ui/traits/trait-bounds-not-on-bare-trait.rs: New test. * rust/rustc/ui/traits/trait-bounds-not-on-struct.rs: New test. * rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-in-fns.rs: New test. * rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-in-impls.rs: New test. * rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-locals.rs: New test. * rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-rpass.rs: New test. * rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-static.rs: New test. * rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-xc.rs: New test. * rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-xc1.rs: New test. * rust/rustc/ui/traits/trait-bounds-on-structs-and-enums.rs: New test. * rust/rustc/ui/traits/trait-bounds-recursion.rs: New test. * rust/rustc/ui/traits/trait-bounds-same-crate-name.rs: New test. * rust/rustc/ui/traits/trait-bounds-sugar.rs: New test. * rust/rustc/ui/traits/trait-bounds.rs: New test. * rust/rustc/ui/traits/trait-cache-issue-18209.rs: New test. * rust/rustc/ui/traits/trait-coercion-generic-bad.rs: New test. * rust/rustc/ui/traits/trait-coercion-generic-regions.rs: New test. * rust/rustc/ui/traits/trait-coercion-generic.rs: New test. * rust/rustc/ui/traits/trait-coercion.rs: New test. * rust/rustc/ui/traits/trait-composition-trivial.rs: New test. * rust/rustc/ui/traits/trait-copy-guessing.rs: New test. * rust/rustc/ui/traits/trait-default-method-bound-subst.rs: New test. * rust/rustc/ui/traits/trait-default-method-bound-subst2.rs: New test. * rust/rustc/ui/traits/trait-default-method-bound-subst3.rs: New test. * rust/rustc/ui/traits/trait-default-method-bound-subst4.rs: New test. * rust/rustc/ui/traits/trait-default-method-bound.rs: New test. * rust/rustc/ui/traits/trait-default-method-xc-2.rs: New test. * rust/rustc/ui/traits/trait-default-method-xc.rs: New test. * rust/rustc/ui/traits/trait-duplicate-methods.rs: New test. * rust/rustc/ui/traits/trait-false-ambiguity-where-clause-builtin-bound.rs: New test. * rust/rustc/ui/traits/trait-generic.rs: New test. * rust/rustc/ui/traits/trait-impl-1.rs: New test. * rust/rustc/ui/traits/trait-impl-2.rs: New test. * rust/rustc/ui/traits/trait-impl-can-not-have-untraitful-items.rs: New test. * rust/rustc/ui/traits/trait-impl-different-num-params.rs: New test. * rust/rustc/ui/traits/trait-impl-for-module.rs: New test. * rust/rustc/ui/traits/trait-impl-method-mismatch.rs: New test. * rust/rustc/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.rs: New test. * rust/rustc/ui/traits/trait-impl.rs: New test. * rust/rustc/ui/traits/trait-inheritance-auto-xc-2.rs: New test. * rust/rustc/ui/traits/trait-inheritance-auto-xc.rs: New test. * rust/rustc/ui/traits/trait-inheritance-auto.rs: New test. * rust/rustc/ui/traits/trait-inheritance-call-bound-inherited.rs: New test. * rust/rustc/ui/traits/trait-inheritance-call-bound-inherited2.rs: New test. * rust/rustc/ui/traits/trait-inheritance-cast-without-call-to-supertrait.rs: New test. * rust/rustc/ui/traits/trait-inheritance-cast.rs: New test. * rust/rustc/ui/traits/trait-inheritance-cross-trait-call-xc.rs: New test. * rust/rustc/ui/traits/trait-inheritance-cross-trait-call.rs: New test. * rust/rustc/ui/traits/trait-inheritance-diamond.rs: New test. * rust/rustc/ui/traits/trait-inheritance-multiple-inheritors.rs: New test. * rust/rustc/ui/traits/trait-inheritance-multiple-params.rs: New test. * rust/rustc/ui/traits/trait-inheritance-num.rs: New test. * rust/rustc/ui/traits/trait-inheritance-num0.rs: New test. * rust/rustc/ui/traits/trait-inheritance-num1.rs: New test. * rust/rustc/ui/traits/trait-inheritance-num2.rs: New test. * rust/rustc/ui/traits/trait-inheritance-num3.rs: New test. * rust/rustc/ui/traits/trait-inheritance-num5.rs: New test. * rust/rustc/ui/traits/trait-inheritance-overloading-simple.rs: New test. * rust/rustc/ui/traits/trait-inheritance-overloading-xc-exe.rs: New test. * rust/rustc/ui/traits/trait-inheritance-overloading.rs: New test. * rust/rustc/ui/traits/trait-inheritance-self-in-supertype.rs: New test. * rust/rustc/ui/traits/trait-inheritance-self.rs: New test. * rust/rustc/ui/traits/trait-inheritance-simple.rs: New test. * rust/rustc/ui/traits/trait-inheritance-static.rs: New test. * rust/rustc/ui/traits/trait-inheritance-static2.rs: New test. * rust/rustc/ui/traits/trait-inheritance-subst.rs: New test. * rust/rustc/ui/traits/trait-inheritance-subst2.rs: New test. * rust/rustc/ui/traits/trait-inheritance-visibility.rs: New test. * rust/rustc/ui/traits/trait-inheritance2.rs: New test. * rust/rustc/ui/traits/trait-item-inside-macro.rs: New test. * rust/rustc/ui/traits/trait-item-privacy.rs: New test. * rust/rustc/ui/traits/trait-matching-lifetimes.rs: New test. * rust/rustc/ui/traits/trait-method-private.rs: New test. * rust/rustc/ui/traits/trait-object-auto-dedup-in-impl.rs: New test. * rust/rustc/ui/traits/trait-object-auto-dedup.rs: New test. * rust/rustc/ui/traits/trait-object-bounds-cycle-1.rs: New test. * rust/rustc/ui/traits/trait-object-bounds-cycle-2.rs: New test. * rust/rustc/ui/traits/trait-object-bounds-cycle-3.rs: New test. * rust/rustc/ui/traits/trait-object-bounds-cycle-4.rs: New test. * rust/rustc/ui/traits/trait-object-exclusion.rs: New test. * rust/rustc/ui/traits/trait-object-generics.rs: New test. * rust/rustc/ui/traits/trait-object-lifetime-first.rs: New test. * rust/rustc/ui/traits/trait-object-macro-matcher.rs: New test. * rust/rustc/ui/traits/trait-object-safety.rs: New test. * rust/rustc/ui/traits/trait-object-supertrait-lifetime-bound.rs: New test. * rust/rustc/ui/traits/trait-object-vs-lifetime-2.rs: New test. * rust/rustc/ui/traits/trait-object-vs-lifetime.rs: New test. * rust/rustc/ui/traits/trait-object-with-lifetime-bound.rs: New test. * rust/rustc/ui/traits/trait-object-with-self-in-projection-output-bad.rs: New test. * rust/rustc/ui/traits/trait-object-with-self-in-projection-output-good.rs: New test. * rust/rustc/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs: New test. * rust/rustc/ui/traits/trait-or-new-type-instead.rs: New test. * rust/rustc/ui/traits/trait-param-without-lifetime-constraint.rs: New test. * rust/rustc/ui/traits/trait-privacy.rs: New test. * rust/rustc/ui/traits/trait-region-pointer-simple.rs: New test. * rust/rustc/ui/traits/trait-resolution-in-overloaded-op.rs: New test. * rust/rustc/ui/traits/trait-safety-fn-body.rs: New test. * rust/rustc/ui/traits/trait-safety-inherent-impl.rs: New test. * rust/rustc/ui/traits/trait-safety-ok-cc.rs: New test. * rust/rustc/ui/traits/trait-safety-ok.rs: New test. * rust/rustc/ui/traits/trait-safety-trait-impl-cc.rs: New test. * rust/rustc/ui/traits/trait-safety-trait-impl.rs: New test. * rust/rustc/ui/traits/trait-static-method-generic-inference.rs: New test. * rust/rustc/ui/traits/trait-static-method-overwriting.rs: New test. * rust/rustc/ui/traits/trait-suggest-deferences-issue-39029.rs: New test. * rust/rustc/ui/traits/trait-suggest-deferences-issue-62530.rs: New test. * rust/rustc/ui/traits/trait-suggest-deferences-multiple-0.rs: New test. * rust/rustc/ui/traits/trait-suggest-deferences-multiple-1.rs: New test. * rust/rustc/ui/traits/trait-suggest-where-clause.rs: New test. * rust/rustc/ui/traits/trait-test-2.rs: New test. * rust/rustc/ui/traits/trait-test.rs: New test. * rust/rustc/ui/traits/trait-to-str.rs: New test. * rust/rustc/ui/traits/trait-where-clause-vs-impl.rs: New test. * rust/rustc/ui/traits/trait-with-bounds-default.rs: New test. * rust/rustc/ui/traits/trait-with-dst.rs: New test. * rust/rustc/ui/traits/traits-assoc-type-in-supertrait-bad.rs: New test. * rust/rustc/ui/traits/traits-assoc-type-in-supertrait.rs: New test. * rust/rustc/ui/traits/traits-conditional-dispatch.rs: New test. * rust/rustc/ui/traits/traits-conditional-model-fn.rs: New test. * rust/rustc/ui/traits/traits-default-method-macro.rs: New test. * rust/rustc/ui/traits/traits-default-method-mut.rs: New test. * rust/rustc/ui/traits/traits-default-method-self.rs: New test. * rust/rustc/ui/traits/traits-default-method-trivial.rs: New test. * rust/rustc/ui/traits/traits-elaborate-type-region.rs: New test. * rust/rustc/ui/traits/traits-impl-object-overlap-issue-23853.rs: New test. * rust/rustc/ui/traits/traits-inductive-overflow-lifetime.rs: New test. * rust/rustc/ui/traits/traits-inductive-overflow-simultaneous.rs: New test. * rust/rustc/ui/traits/traits-inductive-overflow-supertrait-oibit.rs: New test. * rust/rustc/ui/traits/traits-inductive-overflow-supertrait.rs: New test. * rust/rustc/ui/traits/traits-inductive-overflow-two-traits.rs: New test. * rust/rustc/ui/traits/traits-issue-22019.rs: New test. * rust/rustc/ui/traits/traits-issue-22110.rs: New test. * rust/rustc/ui/traits/traits-issue-22655.rs: New test. * rust/rustc/ui/traits/traits-issue-23003-overflow.rs: New test. * rust/rustc/ui/traits/traits-issue-23003.rs: New test. * rust/rustc/ui/traits/traits-issue-26339.rs: New test. * rust/rustc/ui/traits/traits-issue-71136.rs: New test. * rust/rustc/ui/traits/traits-multidispatch-bad.rs: New test. * rust/rustc/ui/traits/traits-multidispatch-convert-ambig-dest.rs: New test. * rust/rustc/ui/traits/traits-multidispatch-infer-convert-target.rs: New test. * rust/rustc/ui/traits/traits-repeated-supertrait-ambig.rs: New test. * rust/rustc/ui/traits/traits-repeated-supertrait.rs: New test. * rust/rustc/ui/traits/traits-static-outlives-a-where-clause.rs: New test. * rust/rustc/ui/traits/ufcs-trait-object.rs: New test. * rust/rustc/ui/traits/use-trait-before-def.rs: New test. * rust/rustc/ui/traits/wf-trait-object-maybe-bound.rs: New test. * rust/rustc/ui/traits/wf-trait-object-no-duplicates.rs: New test. * rust/rustc/ui/traits/wf-trait-object-only-maybe-bound.rs: New test. * rust/rustc/ui/traits/wf-trait-object-reverse-order.rs: New test. * rust/rustc/ui/transmute-equal-assoc-types.rs: New test. * rust/rustc/ui/transmute-non-immediate-to-immediate.rs: New test. * rust/rustc/ui/transmute-specialization.rs: New test. * rust/rustc/ui/transmute/main.rs: New test. * rust/rustc/ui/transmute/transmute-different-sizes.rs: New test. * rust/rustc/ui/transmute/transmute-fat-pointers.rs: New test. * rust/rustc/ui/transmute/transmute-from-fn-item-types-error.rs: New test. * rust/rustc/ui/transmute/transmute-impl.rs: New test. * rust/rustc/ui/transmute/transmute-imut-to-mut.rs: New test. * rust/rustc/ui/transmute/transmute-type-parameters.rs: New test. * rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs: New test. * rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.rs: New test. * rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs: New test. * rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.rs: New test. * rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs: New test. * rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs: New test. * rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs: New test. * rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent.rs: New test. * rust/rustc/ui/trivial-bounds/trivial-bounds-leak-copy.rs: New test. * rust/rustc/ui/trivial-bounds/trivial-bounds-leak.rs: New test. * rust/rustc/ui/trivial-bounds/trivial-bounds-lint.rs: New test. * rust/rustc/ui/trivial-bounds/trivial-bounds-object.rs: New test. * rust/rustc/ui/trivial-message.rs: New test. * rust/rustc/ui/trivial_casts-rpass.rs: New test. * rust/rustc/ui/trivial_casts.rs: New test. * rust/rustc/ui/try-block.rs: New test. * rust/rustc/ui/try-block/try-block-bad-lifetime.rs: New test. * rust/rustc/ui/try-block/try-block-bad-type.rs: New test. * rust/rustc/ui/try-block/try-block-catch.rs: New test. * rust/rustc/ui/try-block/try-block-in-edition2015.rs: New test. * rust/rustc/ui/try-block/try-block-in-match.rs: New test. * rust/rustc/ui/try-block/try-block-in-return.rs: New test. * rust/rustc/ui/try-block/try-block-in-while.rs: New test. * rust/rustc/ui/try-block/try-block-maybe-bad-lifetime.rs: New test. * rust/rustc/ui/try-block/try-block-opt-init.rs: New test. * rust/rustc/ui/try-block/try-block-type-error.rs: New test. * rust/rustc/ui/try-block/try-block-unreachable-code-lint.rs: New test. * rust/rustc/ui/try-block/try-block-unused-delims.rs: New test. * rust/rustc/ui/try-from-int-error-partial-eq.rs: New test. * rust/rustc/ui/try-is-identifier-edition2015.rs: New test. * rust/rustc/ui/try-macro-suggestion.rs: New test. * rust/rustc/ui/try-on-option-diagnostics.rs: New test. * rust/rustc/ui/try-on-option.rs: New test. * rust/rustc/ui/try-operator-custom.rs: New test. * rust/rustc/ui/try-operator-hygiene.rs: New test. * rust/rustc/ui/try-operator-on-main.rs: New test. * rust/rustc/ui/try-operator.rs: New test. * rust/rustc/ui/try-poll.rs: New test. * rust/rustc/ui/try-wait.rs: New test. * rust/rustc/ui/tup.rs: New test. * rust/rustc/ui/tuple-index-fat-types.rs: New test. * rust/rustc/ui/tuple-index.rs: New test. * rust/rustc/ui/tuple/index-float.rs: New test. * rust/rustc/ui/tuple/index-invalid.rs: New test. * rust/rustc/ui/tuple/indexing-in-macro.rs: New test. * rust/rustc/ui/tuple/nested-index.rs: New test. * rust/rustc/ui/tuple/tuple-arity-mismatch.rs: New test. * rust/rustc/ui/tuple/tuple-index-not-tuple.rs: New test. * rust/rustc/ui/tuple/tuple-index-out-of-bounds.rs: New test. * rust/rustc/ui/tuple/tuple-struct-fields/test.rs: New test. * rust/rustc/ui/tuple/tuple-struct-fields/test2.rs: New test. * rust/rustc/ui/tuple/tuple-struct-fields/test3.rs: New test. * rust/rustc/ui/tutorial-suffix-inference-test.rs: New test. * rust/rustc/ui/tydesc-name.rs: New test. * rust/rustc/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs: New test. * rust/rustc/ui/type-alias-enum-variants/enum-variant-generic-args.rs: New test. * rust/rustc/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs: New test. * rust/rustc/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs: New test. * rust/rustc/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs: New test. * rust/rustc/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs: New test. * rust/rustc/ui/type-alias-enum-variants/issue-57866.rs: New test. * rust/rustc/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs: New test. * rust/rustc/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs: New test. * rust/rustc/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs: New test. * rust/rustc/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs: New test. * rust/rustc/ui/type-alias-enum-variants/self-in-enum-definition.rs: New test. * rust/rustc/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs: New test. * rust/rustc/ui/type-alias-impl-trait/assoc-type-const.rs: New test. * rust/rustc/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs: New test. * rust/rustc/ui/type-alias-impl-trait/assoc-type-lifetime.rs: New test. * rust/rustc/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs: New test. * rust/rustc/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs: New test. * rust/rustc/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs: New test. * rust/rustc/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs: New test. * rust/rustc/ui/type-alias-impl-trait/bound_reduction.rs: New test. * rust/rustc/ui/type-alias-impl-trait/bound_reduction2.rs: New test. * rust/rustc/ui/type-alias-impl-trait/bounds-are-checked-2.rs: New test. * rust/rustc/ui/type-alias-impl-trait/bounds-are-checked.rs: New test. * rust/rustc/ui/type-alias-impl-trait/coherence.rs: New test. * rust/rustc/ui/type-alias-impl-trait/cross_crate_ice.rs: New test. * rust/rustc/ui/type-alias-impl-trait/cross_crate_ice2.rs: New test. * rust/rustc/ui/type-alias-impl-trait/declared_but_never_defined.rs: New test. * rust/rustc/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs: New test. * rust/rustc/ui/type-alias-impl-trait/different_defining_uses.rs: New test. * rust/rustc/ui/type-alias-impl-trait/different_defining_uses_never_type.rs: New test. * rust/rustc/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs: New test. * rust/rustc/ui/type-alias-impl-trait/fallback.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_different_defining_uses.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_lifetime_param.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_nondefining_use.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_not_used.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_underconstrained.rs: New test. * rust/rustc/ui/type-alias-impl-trait/generic_underconstrained2.rs: New test. * rust/rustc/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs: New test. * rust/rustc/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-52843.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-53096.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-53598.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-57611-trait-alias.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-57700.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-57807-associated-type.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-58887.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-58951.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-60371.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-60407.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-60564.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-63263-closure-return.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-63279.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-65918.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-70121.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-74244.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-74761.rs: New test. * rust/rustc/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs: New test. * rust/rustc/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs: New test. * rust/rustc/ui/type-alias-impl-trait/never_reveal_concrete_type.rs: New test. * rust/rustc/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs: New test. * rust/rustc/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs: New test. * rust/rustc/ui/type-alias-impl-trait/not_a_defining_use.rs: New test. * rust/rustc/ui/type-alias-impl-trait/not_well_formed.rs: New test. * rust/rustc/ui/type-alias-impl-trait/private_unused.rs: New test. * rust/rustc/ui/type-alias-impl-trait/structural-match-no-leak.rs: New test. * rust/rustc/ui/type-alias-impl-trait/structural-match.rs: New test. * rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs: New test. * rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs: New test. * rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs: New test. * rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs: New test. * rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs: New test. * rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs: New test. * rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs: New test. * rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs: New test. * rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait.rs: New test. * rust/rustc/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs: New test. * rust/rustc/ui/type-alias-impl-trait/unused_generic_param.rs: New test. * rust/rustc/ui/type-alias/issue-62263-self-in-atb.rs: New test. * rust/rustc/ui/type-alias/issue-62305-self-assoc-ty.rs: New test. * rust/rustc/ui/type-alias/issue-62364-self-ty-arg.rs: New test. * rust/rustc/ui/type-ascription.rs: New test. * rust/rustc/ui/type-id-higher-rank-2.rs: New test. * rust/rustc/ui/type-id-higher-rank.rs: New test. * rust/rustc/ui/type-in-nested-module.rs: New test. * rust/rustc/ui/type-infer-generalize-ty-var.rs: New test. * rust/rustc/ui/type-inference/or_else-multiple-type-params.rs: New test. * rust/rustc/ui/type-inference/sort_by_key.rs: New test. * rust/rustc/ui/type-inference/unbounded-associated-type.rs: New test. * rust/rustc/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.rs: New test. * rust/rustc/ui/type-inference/unbounded-type-param-in-fn.rs: New test. * rust/rustc/ui/type-namespace.rs: New test. * rust/rustc/ui/type-param-constraints.rs: New test. * rust/rustc/ui/type-param.rs: New test. * rust/rustc/ui/type-params-in-for-each.rs: New test. * rust/rustc/ui/type-ptr.rs: New test. * rust/rustc/ui/type-sizes.rs: New test. * rust/rustc/ui/type-use-i1-versus-i8.rs: New test. * rust/rustc/ui/type/ascription/issue-34255-1.rs: New test. * rust/rustc/ui/type/ascription/issue-47666.rs: New test. * rust/rustc/ui/type/ascription/issue-54516.rs: New test. * rust/rustc/ui/type/ascription/issue-60933.rs: New test. * rust/rustc/ui/type/auxiliary/crate_a1.rs: New test. * rust/rustc/ui/type/auxiliary/crate_a2.rs: New test. * rust/rustc/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs: New test. * rust/rustc/ui/type/type-alias-bounds.rs: New test. * rust/rustc/ui/type/type-annotation-needed.rs: New test. * rust/rustc/ui/type/type-arg-out-of-scope.rs: New test. * rust/rustc/ui/type/type-ascription-instead-of-initializer.rs: New test. * rust/rustc/ui/type/type-ascription-instead-of-statement-end.rs: New test. * rust/rustc/ui/type/type-ascription-precedence.rs: New test. * rust/rustc/ui/type/type-ascription-soundness.rs: New test. * rust/rustc/ui/type/type-ascription-with-fn-call.rs: New test. * rust/rustc/ui/type/type-check-defaults.rs: New test. * rust/rustc/ui/type/type-check/assignment-expected-bool.rs: New test. * rust/rustc/ui/type/type-check/assignment-in-if.rs: New test. * rust/rustc/ui/type/type-check/cannot_infer_local_or_array.rs: New test. * rust/rustc/ui/type/type-check/cannot_infer_local_or_vec.rs: New test. * rust/rustc/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.rs: New test. * rust/rustc/ui/type/type-check/issue-22897.rs: New test. * rust/rustc/ui/type/type-check/issue-40294.rs: New test. * rust/rustc/ui/type/type-check/issue-41314.rs: New test. * rust/rustc/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs: New test. * rust/rustc/ui/type/type-check/missing_trait_impl.rs: New test. * rust/rustc/ui/type/type-check/unknown_type_for_closure.rs: New test. * rust/rustc/ui/type/type-dependent-def-issue-49241.rs: New test. * rust/rustc/ui/type/type-error-break-tail.rs: New test. * rust/rustc/ui/type/type-mismatch-multiple.rs: New test. * rust/rustc/ui/type/type-mismatch-same-crate-name.rs: New test. * rust/rustc/ui/type/type-mismatch.rs: New test. * rust/rustc/ui/type/type-parameter-defaults-referencing-Self-ppaux.rs: New test. * rust/rustc/ui/type/type-parameter-defaults-referencing-Self.rs: New test. * rust/rustc/ui/type/type-parameter-names.rs: New test. * rust/rustc/ui/type/type-params-in-different-spaces-1.rs: New test. * rust/rustc/ui/type/type-params-in-different-spaces-2.rs: New test. * rust/rustc/ui/type/type-params-in-different-spaces-3.rs: New test. * rust/rustc/ui/type/type-path-err-node-types.rs: New test. * rust/rustc/ui/type/type-recursive.rs: New test. * rust/rustc/ui/type/type-shadow.rs: New test. * rust/rustc/ui/type_length_limit.rs: New test. * rust/rustc/ui/typeck-closure-to-unsafe-fn-ptr.rs: New test. * rust/rustc/ui/typeck-fn-to-unsafe-fn-ptr.rs: New test. * rust/rustc/ui/typeck/auxiliary/tdticc_coherence_lib.rs: New test. * rust/rustc/ui/typeck/issue-52082-type-param-shadows-existing-type.rs: New test. * rust/rustc/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs: New test. * rust/rustc/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.rs: New test. * rust/rustc/ui/typeck/issue-67971.rs: New test. * rust/rustc/ui/typeck/issue-68590-reborrow-through-derefmut.rs: New test. * rust/rustc/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.rs: New test. * rust/rustc/ui/typeck/issue-72225-call-fnmut-through-derefmut.rs: New test. * rust/rustc/ui/typeck/issue-73592-borrow_mut-through-deref.rs: New test. * rust/rustc/ui/typeck/issue-74933.rs: New test. * rust/rustc/ui/typeck/typeck-builtin-bound-type-parameters.rs: New test. * rust/rustc/ui/typeck/typeck-cast-pointer-to-float.rs: New test. * rust/rustc/ui/typeck/typeck-default-trait-impl-assoc-type.rs: New test. * rust/rustc/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs: New test. * rust/rustc/ui/typeck/typeck-default-trait-impl-negation-send.rs: New test. * rust/rustc/ui/typeck/typeck-default-trait-impl-negation-sync.rs: New test. * rust/rustc/ui/typeck/typeck-default-trait-impl-send-param.rs: New test. * rust/rustc/ui/typeck/typeck-unsafe-always-share.rs: New test. * rust/rustc/ui/typeck/typeck_type_placeholder_item.rs: New test. * rust/rustc/ui/typeck/typeck_type_placeholder_item_help.rs: New test. * rust/rustc/ui/typeck/typeck_type_placeholder_lifetime_1.rs: New test. * rust/rustc/ui/typeck/typeck_type_placeholder_lifetime_2.rs: New test. * rust/rustc/ui/typeck/typeck_type_placeholder_mismatch.rs: New test. * rust/rustc/ui/typeck_type_placeholder_1.rs: New test. * rust/rustc/ui/typeclasses-eq-example-static.rs: New test. * rust/rustc/ui/typeclasses-eq-example.rs: New test. * rust/rustc/ui/typeid-intrinsic.rs: New test. * rust/rustc/ui/typestate-cfg-nesting.rs: New test. * rust/rustc/ui/typestate-multi-decl.rs: New test. * rust/rustc/ui/ufcs-polymorphic-paths.rs: New test. * rust/rustc/ui/ufcs-type-params.rs: New test. * rust/rustc/ui/ufcs/ufcs-explicit-self-bad.rs: New test. * rust/rustc/ui/ufcs/ufcs-partially-resolved.rs: New test. * rust/rustc/ui/ufcs/ufcs-qpath-missing-params.rs: New test. * rust/rustc/ui/ufcs/ufcs-qpath-self-mismatch.rs: New test. * rust/rustc/ui/ui-testing-optout.rs: New test. * rust/rustc/ui/unary-minus-suffix-inference.rs: New test. * rust/rustc/ui/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs: New test. * rust/rustc/ui/unboxed-closures/issue-30906.rs: New test. * rust/rustc/ui/unboxed-closures/issue-53448.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-feature-gate.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-illegal-move.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-immutable-capture.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-region.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-default.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-equiv.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-region.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-1.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-all-traits.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-blanket-fn.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-borrow-conflict.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-boxed.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-by-ref.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-call-fn-autoderef.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-object.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-cross-crate.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-drop.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-extern-fn-hr.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-extern-fn.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-generic.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-move.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-call-twice.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-move-call-twice.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-move.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-kind.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-recursive-fn.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-infer-upvar.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-manual-impl.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-monomorphization.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-move-mutable.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-prelude.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-recursive-fn-using-fn-mut.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-simple.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-single-word-env.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-sugar-object.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-type-mismatch.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-unique-type-id.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-wrong-abi.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs: New test. * rust/rustc/ui/unboxed-closures/unboxed-closures-zero-args.rs: New test. * rust/rustc/ui/unconstrained-none.rs: New test. * rust/rustc/ui/unconstrained-ref.rs: New test. * rust/rustc/ui/underscore-ident-matcher.rs: New test. * rust/rustc/ui/underscore-imports/auxiliary/duplicate.rs: New test. * rust/rustc/ui/underscore-imports/auxiliary/underscore-imports.rs: New test. * rust/rustc/ui/underscore-imports/basic.rs: New test. * rust/rustc/ui/underscore-imports/cycle.rs: New test. * rust/rustc/ui/underscore-imports/duplicate.rs: New test. * rust/rustc/ui/underscore-imports/hygiene-2.rs: New test. * rust/rustc/ui/underscore-imports/hygiene.rs: New test. * rust/rustc/ui/underscore-imports/intercrate.rs: New test. * rust/rustc/ui/underscore-imports/macro-expanded.rs: New test. * rust/rustc/ui/underscore-imports/shadow.rs: New test. * rust/rustc/ui/underscore-imports/unused-2018.rs: New test. * rust/rustc/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs: New test. * rust/rustc/ui/underscore-lifetime/dyn-trait-underscore.rs: New test. * rust/rustc/ui/underscore-lifetime/in-binder.rs: New test. * rust/rustc/ui/underscore-lifetime/in-fn-return-illegal.rs: New test. * rust/rustc/ui/underscore-lifetime/in-struct.rs: New test. * rust/rustc/ui/underscore-lifetime/underscore-lifetime-binders.rs: New test. * rust/rustc/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.rs: New test. * rust/rustc/ui/underscore-lifetime/underscore-outlives-bounds.rs: New test. * rust/rustc/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rs: New test. * rust/rustc/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs: New test. * rust/rustc/ui/underscore-lifetime/where-clause-trait-impl-region.rs: New test. * rust/rustc/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs: New test. * rust/rustc/ui/underscore-lifetime/where-clauses.rs: New test. * rust/rustc/ui/underscore-lifetimes.rs: New test. * rust/rustc/ui/underscore-method-after-integer.rs: New test. * rust/rustc/ui/unevaluated_fixed_size_array_len.rs: New test. * rust/rustc/ui/uniform-paths/auxiliary/issue-53691.rs: New test. * rust/rustc/ui/uniform-paths/basic-nested.rs: New test. * rust/rustc/ui/uniform-paths/basic.rs: New test. * rust/rustc/ui/uniform-paths/issue-53691.rs: New test. * rust/rustc/ui/uniform-paths/macros-nested.rs: New test. * rust/rustc/ui/uniform-paths/macros.rs: New test. * rust/rustc/ui/uniform-paths/same-crate.rs: New test. * rust/rustc/ui/unify-return-ty.rs: New test. * rust/rustc/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs: New test. * rust/rustc/ui/uninhabited/privately-uninhabited-dead-code.rs: New test. * rust/rustc/ui/uninhabited/uninhabited-enum-cast.rs: New test. * rust/rustc/ui/uninhabited/uninhabited-irrefutable.rs: New test. * rust/rustc/ui/uninhabited/uninhabited-matches-feature-gated.rs: New test. * rust/rustc/ui/uninhabited/uninhabited-patterns.rs: New test. * rust/rustc/ui/uninit-empty-types.rs: New test. * rust/rustc/ui/union/auxiliary/union.rs: New test. * rust/rustc/ui/union/issue-41073.rs: New test. * rust/rustc/ui/union/union-align.rs: New test. * rust/rustc/ui/union/union-backcomp.rs: New test. * rust/rustc/ui/union/union-basic.rs: New test. * rust/rustc/ui/union/union-borrow-move-parent-sibling.rs: New test. * rust/rustc/ui/union/union-const-codegen.rs: New test. * rust/rustc/ui/union/union-const-eval-field.rs: New test. * rust/rustc/ui/union/union-const-eval.rs: New test. * rust/rustc/ui/union/union-const-pat.rs: New test. * rust/rustc/ui/union/union-copy.rs: New test. * rust/rustc/ui/union/union-custom-drop.rs: New test. * rust/rustc/ui/union/union-deref.rs: New test. * rust/rustc/ui/union/union-derive-clone.rs: New test. * rust/rustc/ui/union/union-derive-eq.rs: New test. * rust/rustc/ui/union/union-derive-rpass.rs: New test. * rust/rustc/ui/union/union-derive.rs: New test. * rust/rustc/ui/union/union-drop-assign.rs: New test. * rust/rustc/ui/union/union-drop.rs: New test. * rust/rustc/ui/union/union-empty.rs: New test. * rust/rustc/ui/union/union-fields-1.rs: New test. * rust/rustc/ui/union/union-fields-2.rs: New test. * rust/rustc/ui/union/union-generic-rpass.rs: New test. * rust/rustc/ui/union/union-generic.rs: New test. * rust/rustc/ui/union/union-inherent-method.rs: New test. * rust/rustc/ui/union/union-lint-dead-code.rs: New test. * rust/rustc/ui/union/union-macro.rs: New test. * rust/rustc/ui/union/union-manuallydrop-rpass.rs: New test. * rust/rustc/ui/union/union-move.rs: New test. * rust/rustc/ui/union/union-nodrop.rs: New test. * rust/rustc/ui/union/union-nonrepresentable.rs: New test. * rust/rustc/ui/union/union-nonzero.rs: New test. * rust/rustc/ui/union/union-overwrite.rs: New test. * rust/rustc/ui/union/union-packed.rs: New test. * rust/rustc/ui/union/union-pat-refutability.rs: New test. * rust/rustc/ui/union/union-repr-c.rs: New test. * rust/rustc/ui/union/union-sized-field.rs: New test. * rust/rustc/ui/union/union-suggest-field.rs: New test. * rust/rustc/ui/union/union-trait-impl.rs: New test. * rust/rustc/ui/union/union-transmute.rs: New test. * rust/rustc/ui/union/union-unsafe.rs: New test. * rust/rustc/ui/union/union-unsized.rs: New test. * rust/rustc/ui/union/union-with-drop-fields.rs: New test. * rust/rustc/ui/unique-object-noncopyable.rs: New test. * rust/rustc/ui/unique-pinned-nocopy.rs: New test. * rust/rustc/ui/unique/unique-assign-copy.rs: New test. * rust/rustc/ui/unique/unique-assign-drop.rs: New test. * rust/rustc/ui/unique/unique-assign-generic.rs: New test. * rust/rustc/ui/unique/unique-assign.rs: New test. * rust/rustc/ui/unique/unique-autoderef-field.rs: New test. * rust/rustc/ui/unique/unique-autoderef-index.rs: New test. * rust/rustc/ui/unique/unique-cmp.rs: New test. * rust/rustc/ui/unique/unique-containing-tag.rs: New test. * rust/rustc/ui/unique/unique-create.rs: New test. * rust/rustc/ui/unique/unique-decl-init-copy.rs: New test. * rust/rustc/ui/unique/unique-decl-init.rs: New test. * rust/rustc/ui/unique/unique-decl-move.rs: New test. * rust/rustc/ui/unique/unique-decl.rs: New test. * rust/rustc/ui/unique/unique-deref.rs: New test. * rust/rustc/ui/unique/unique-destructure.rs: New test. * rust/rustc/ui/unique/unique-drop-complex.rs: New test. * rust/rustc/ui/unique/unique-ffi-symbols.rs: New test. * rust/rustc/ui/unique/unique-fn-arg-move.rs: New test. * rust/rustc/ui/unique/unique-fn-arg-mut.rs: New test. * rust/rustc/ui/unique/unique-fn-arg.rs: New test. * rust/rustc/ui/unique/unique-fn-ret.rs: New test. * rust/rustc/ui/unique/unique-generic-assign.rs: New test. * rust/rustc/ui/unique/unique-in-tag.rs: New test. * rust/rustc/ui/unique/unique-in-vec-copy.rs: New test. * rust/rustc/ui/unique/unique-in-vec.rs: New test. * rust/rustc/ui/unique/unique-init.rs: New test. * rust/rustc/ui/unique/unique-kinds.rs: New test. * rust/rustc/ui/unique/unique-log.rs: New test. * rust/rustc/ui/unique/unique-match-discrim.rs: New test. * rust/rustc/ui/unique/unique-move-drop.rs: New test. * rust/rustc/ui/unique/unique-move-temp.rs: New test. * rust/rustc/ui/unique/unique-move.rs: New test. * rust/rustc/ui/unique/unique-mutable.rs: New test. * rust/rustc/ui/unique/unique-object-move.rs: New test. * rust/rustc/ui/unique/unique-pat-2.rs: New test. * rust/rustc/ui/unique/unique-pat-3.rs: New test. * rust/rustc/ui/unique/unique-pat.rs: New test. * rust/rustc/ui/unique/unique-rec.rs: New test. * rust/rustc/ui/unique/unique-send-2.rs: New test. * rust/rustc/ui/unique/unique-send.rs: New test. * rust/rustc/ui/unique/unique-swap.rs: New test. * rust/rustc/ui/unit.rs: New test. * rust/rustc/ui/unknown-language-item.rs: New test. * rust/rustc/ui/unknown-lint-tool-name.rs: New test. * rust/rustc/ui/unknown-llvm-arg.rs: New test. * rust/rustc/ui/unknown-tool-name.rs: New test. * rust/rustc/ui/unnamed_argument_mode.rs: New test. * rust/rustc/ui/unnecessary-extern-crate.rs: New test. * rust/rustc/ui/unop-move-semantics.rs: New test. * rust/rustc/ui/unop-neg-bool.rs: New test. * rust/rustc/ui/unreachable-code-1.rs: New test. * rust/rustc/ui/unreachable-code-ret.rs: New test. * rust/rustc/ui/unreachable-code.rs: New test. * rust/rustc/ui/unresolved/unresolved-extern-mod-suggestion.rs: New test. * rust/rustc/ui/unresolved/unresolved-import-recovery.rs: New test. * rust/rustc/ui/unresolved/unresolved-import.rs: New test. * rust/rustc/ui/unrestricted-attribute-tokens.rs: New test. * rust/rustc/ui/unsafe-coercion.rs: New test. * rust/rustc/ui/unsafe-fn-called-from-unsafe-blk.rs: New test. * rust/rustc/ui/unsafe-fn-called-from-unsafe-fn.rs: New test. * rust/rustc/ui/unsafe-pointer-assignability.rs: New test. * rust/rustc/ui/unsafe/ranged_ints.rs: New test. * rust/rustc/ui/unsafe/ranged_ints2.rs: New test. * rust/rustc/ui/unsafe/ranged_ints2_const.rs: New test. * rust/rustc/ui/unsafe/ranged_ints3.rs: New test. * rust/rustc/ui/unsafe/ranged_ints3_const.rs: New test. * rust/rustc/ui/unsafe/ranged_ints4.rs: New test. * rust/rustc/ui/unsafe/ranged_ints4_const.rs: New test. * rust/rustc/ui/unsafe/ranged_ints_const.rs: New test. * rust/rustc/ui/unsafe/ranged_ints_macro.rs: New test. * rust/rustc/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs: New test. * rust/rustc/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs: New test. * rust/rustc/ui/unsafe/unsafe-around-compiler-generated-unsafe.rs: New test. * rust/rustc/ui/unsafe/unsafe-block-without-braces.rs: New test. * rust/rustc/ui/unsafe/unsafe-const-fn.rs: New test. * rust/rustc/ui/unsafe/unsafe-fn-assign-deref-ptr.rs: New test. * rust/rustc/ui/unsafe/unsafe-fn-autoderef.rs: New test. * rust/rustc/ui/unsafe/unsafe-fn-called-from-safe.rs: New test. * rust/rustc/ui/unsafe/unsafe-fn-deref-ptr.rs: New test. * rust/rustc/ui/unsafe/unsafe-fn-used-as-value.rs: New test. * rust/rustc/ui/unsafe/unsafe-move-val-init.rs: New test. * rust/rustc/ui/unsafe/unsafe-subtyping.rs: New test. * rust/rustc/ui/unsafe/unsafe-trait-impl.rs: New test. * rust/rustc/ui/unsafe/unsafe-unstable-const-fn.rs: New test. * rust/rustc/ui/unsigned-literal-negation.rs: New test. * rust/rustc/ui/unsized-locals/autoderef.rs: New test. * rust/rustc/ui/unsized-locals/auxiliary/ufuncs.rs: New test. * rust/rustc/ui/unsized-locals/borrow-after-move.rs: New test. * rust/rustc/ui/unsized-locals/box-fnonce.rs: New test. * rust/rustc/ui/unsized-locals/by-value-trait-object-safety-rpass.rs: New test. * rust/rustc/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs: New test. * rust/rustc/ui/unsized-locals/by-value-trait-object-safety.rs: New test. * rust/rustc/ui/unsized-locals/double-move.rs: New test. * rust/rustc/ui/unsized-locals/issue-30276-feature-flagged.rs: New test. * rust/rustc/ui/unsized-locals/issue-30276.rs: New test. * rust/rustc/ui/unsized-locals/issue-50940-with-feature.rs: New test. * rust/rustc/ui/unsized-locals/issue-50940.rs: New test. * rust/rustc/ui/unsized-locals/reference-unsized-locals.rs: New test. * rust/rustc/ui/unsized-locals/simple-unsized-locals.rs: New test. * rust/rustc/ui/unsized-locals/unsized-exprs-rpass.rs: New test. * rust/rustc/ui/unsized-locals/unsized-exprs.rs: New test. * rust/rustc/ui/unsized-locals/unsized-exprs2.rs: New test. * rust/rustc/ui/unsized-locals/unsized-exprs3.rs: New test. * rust/rustc/ui/unsized-locals/unsized-index.rs: New test. * rust/rustc/ui/unsized-locals/unsized-locals-using-unsized-fn-params.rs: New test. * rust/rustc/ui/unsized-locals/unsized-parameters.rs: New test. * rust/rustc/ui/unsized-tuple-impls.rs: New test. * rust/rustc/ui/unsized.rs: New test. * rust/rustc/ui/unsized/issue-71659.rs: New test. * rust/rustc/ui/unsized/issue-75707.rs: New test. * rust/rustc/ui/unsized/return-unsized-from-trait-method.rs: New test. * rust/rustc/ui/unsized/unsized-bare-typaram.rs: New test. * rust/rustc/ui/unsized/unsized-enum.rs: New test. * rust/rustc/ui/unsized/unsized-enum2.rs: New test. * rust/rustc/ui/unsized/unsized-fn-param.rs: New test. * rust/rustc/ui/unsized/unsized-inherent-impl-self-type.rs: New test. * rust/rustc/ui/unsized/unsized-struct.rs: New test. * rust/rustc/ui/unsized/unsized-trait-impl-self-type.rs: New test. * rust/rustc/ui/unsized/unsized-trait-impl-trait-arg.rs: New test. * rust/rustc/ui/unsized2.rs: New test. * rust/rustc/ui/unsized3-rpass.rs: New test. * rust/rustc/ui/unsized3.rs: New test. * rust/rustc/ui/unsized5.rs: New test. * rust/rustc/ui/unsized6.rs: New test. * rust/rustc/ui/unsized7.rs: New test. * rust/rustc/ui/unspecified-self-in-trait-ref.rs: New test. * rust/rustc/ui/unsupported-cast.rs: New test. * rust/rustc/ui/unterminated-comment.rs: New test. * rust/rustc/ui/unterminated-doc-comment.rs: New test. * rust/rustc/ui/unused-crate-deps/auxiliary/bar.rs: New test. * rust/rustc/ui/unused-crate-deps/auxiliary/foo.rs: New test. * rust/rustc/ui/unused-crate-deps/ignore-pathless-extern.rs: New test. * rust/rustc/ui/unused-crate-deps/libfib.rs: New test. * rust/rustc/ui/unused-crate-deps/lint-group.rs: New test. * rust/rustc/ui/unused-crate-deps/suppress.rs: New test. * rust/rustc/ui/unused-crate-deps/test-use-ok.rs: New test. * rust/rustc/ui/unused-crate-deps/unused-aliases.rs: New test. * rust/rustc/ui/unused-crate-deps/use_extern_crate_2015.rs: New test. * rust/rustc/ui/unused-crate-deps/warn-attr.rs: New test. * rust/rustc/ui/unused-crate-deps/warn-cmdline-static.rs: New test. * rust/rustc/ui/unused-crate-deps/warn-cmdline.rs: New test. * rust/rustc/ui/unused-move-capture.rs: New test. * rust/rustc/ui/unused-move.rs: New test. * rust/rustc/ui/unused/unused-attr.rs: New test. * rust/rustc/ui/unused/unused-closure.rs: New test. * rust/rustc/ui/unused/unused-macro-rules.rs: New test. * rust/rustc/ui/unused/unused-macro-with-bad-frag-spec.rs: New test. * rust/rustc/ui/unused/unused-macro-with-follow-violation.rs: New test. * rust/rustc/ui/unused/unused-macro.rs: New test. * rust/rustc/ui/unused/unused-mut-warning-captured-var.rs: New test. * rust/rustc/ui/unused/unused-result.rs: New test. * rust/rustc/ui/unwind-resource.rs: New test. * rust/rustc/ui/unwind-unique.rs: New test. * rust/rustc/ui/use-crate-name-alias.rs: New test. * rust/rustc/ui/use-import-export.rs: New test. * rust/rustc/ui/use-keyword-2.rs: New test. * rust/rustc/ui/use-mod.rs: New test. * rust/rustc/ui/use-module-level-int-consts.rs: New test. * rust/rustc/ui/use-nested-groups.rs: New test. * rust/rustc/ui/use-self-in-inner-fn.rs: New test. * rust/rustc/ui/use.rs: New test. * rust/rustc/ui/use/auxiliary/extern-use-primitive-type-lib.rs: New test. * rust/rustc/ui/use/auxiliary/use-from-trait-xc.rs: New test. * rust/rustc/ui/use/issue-18986.rs: New test. * rust/rustc/ui/use/issue-60976-extern-use-primitive-type.rs: New test. * rust/rustc/ui/use/use-after-move-based-on-type.rs: New test. * rust/rustc/ui/use/use-after-move-implicity-coerced-object.rs: New test. * rust/rustc/ui/use/use-after-move-self-based-on-type.rs: New test. * rust/rustc/ui/use/use-after-move-self.rs: New test. * rust/rustc/ui/use/use-associated-const.rs: New test. * rust/rustc/ui/use/use-from-trait-xc.rs: New test. * rust/rustc/ui/use/use-from-trait.rs: New test. * rust/rustc/ui/use/use-keyword.rs: New test. * rust/rustc/ui/use/use-meta-mismatch.rs: New test. * rust/rustc/ui/use/use-mod.rs: New test. * rust/rustc/ui/use/use-mod/use-mod-2.rs: New test. * rust/rustc/ui/use/use-mod/use-mod-3.rs: New test. * rust/rustc/ui/use/use-mod/use-mod-4.rs: New test. * rust/rustc/ui/use/use-mod/use-mod-5.rs: New test. * rust/rustc/ui/use/use-mod/use-mod-6.rs: New test. * rust/rustc/ui/use/use-nested-groups-error.rs: New test. * rust/rustc/ui/use/use-nested-groups-unused-imports.rs: New test. * rust/rustc/ui/use/use-paths-as-items.rs: New test. * rust/rustc/ui/use/use-self-type.rs: New test. * rust/rustc/ui/use/use-super-global-path.rs: New test. * rust/rustc/ui/use_inline_dtor.rs: New test. * rust/rustc/ui/used.rs: New test. * rust/rustc/ui/useless-comment.rs: New test. * rust/rustc/ui/useless-pub.rs: New test. * rust/rustc/ui/user-defined-macro-rules.rs: New test. * rust/rustc/ui/using-target-feature-unstable.rs: New test. * rust/rustc/ui/usize-generic-argument-parent.rs: New test. * rust/rustc/ui/utf8-bom.rs: New test. * rust/rustc/ui/utf8.rs: New test. * rust/rustc/ui/utf8_chars.rs: New test. * rust/rustc/ui/utf8_idents-rpass.rs: New test. * rust/rustc/ui/utf8_idents.rs: New test. * rust/rustc/ui/variance-intersection-of-ref-and-opt-ref.rs: New test. * rust/rustc/ui/variance-iterators-in-libcore.rs: New test. * rust/rustc/ui/variance/variance-associated-types.rs: New test. * rust/rustc/ui/variance/variance-associated-types2.rs: New test. * rust/rustc/ui/variance/variance-btree-invariant-types.rs: New test. * rust/rustc/ui/variance/variance-cell-is-invariant.rs: New test. * rust/rustc/ui/variance/variance-contravariant-arg-object.rs: New test. * rust/rustc/ui/variance/variance-contravariant-arg-trait-match.rs: New test. * rust/rustc/ui/variance/variance-contravariant-self-trait-match.rs: New test. * rust/rustc/ui/variance/variance-covariant-arg-object.rs: New test. * rust/rustc/ui/variance/variance-covariant-arg-trait-match.rs: New test. * rust/rustc/ui/variance/variance-covariant-self-trait-match.rs: New test. * rust/rustc/ui/variance/variance-invariant-arg-object.rs: New test. * rust/rustc/ui/variance/variance-invariant-arg-trait-match.rs: New test. * rust/rustc/ui/variance/variance-invariant-self-trait-match.rs: New test. * rust/rustc/ui/variance/variance-issue-20533.rs: New test. * rust/rustc/ui/variance/variance-object-types.rs: New test. * rust/rustc/ui/variance/variance-regions-direct.rs: New test. * rust/rustc/ui/variance/variance-regions-indirect.rs: New test. * rust/rustc/ui/variance/variance-regions-unused-direct.rs: New test. * rust/rustc/ui/variance/variance-regions-unused-indirect.rs: New test. * rust/rustc/ui/variance/variance-trait-bounds.rs: New test. * rust/rustc/ui/variance/variance-trait-matching.rs: New test. * rust/rustc/ui/variance/variance-trait-object-bound.rs: New test. * rust/rustc/ui/variance/variance-types-bounds.rs: New test. * rust/rustc/ui/variance/variance-types.rs: New test. * rust/rustc/ui/variance/variance-unused-region-param.rs: New test. * rust/rustc/ui/variance/variance-unused-type-param.rs: New test. * rust/rustc/ui/variance/variance-use-contravariant-struct-1.rs: New test. * rust/rustc/ui/variance/variance-use-contravariant-struct-2.rs: New test. * rust/rustc/ui/variance/variance-use-covariant-struct-1.rs: New test. * rust/rustc/ui/variance/variance-use-covariant-struct-2.rs: New test. * rust/rustc/ui/variance/variance-use-invariant-struct-1.rs: New test. * rust/rustc/ui/variants/auxiliary/variant-namespacing.rs: New test. * rust/rustc/ui/variants/variant-namespacing.rs: New test. * rust/rustc/ui/variants/variant-size-differences.rs: New test. * rust/rustc/ui/variants/variant-used-as-type.rs: New test. * rust/rustc/ui/vec/vec-macro-with-comma-only.rs: New test. * rust/rustc/ui/vec/vec-mut-iter-borrow.rs: New test. * rust/rustc/ui/vec/vec-overrun.rs: New test. * rust/rustc/ui/vec/vec-res-add.rs: New test. * rust/rustc/ui/vector-cast-weirdness.rs: New test. * rust/rustc/ui/vector-no-ann.rs: New test. * rust/rustc/ui/volatile-fat-ptr.rs: New test. * rust/rustc/ui/vtable-res-trait-param.rs: New test. * rust/rustc/ui/wait-forked-but-failed-child.rs: New test. * rust/rustc/ui/walk-struct-literal-with.rs: New test. * rust/rustc/ui/warn-ctypes-inhibit.rs: New test. * rust/rustc/ui/warn-path-statement.rs: New test. * rust/rustc/ui/wasm-custom-section-relocations.rs: New test. * rust/rustc/ui/wasm-import-module.rs: New test. * rust/rustc/ui/weak-lang-item.rs: New test. * rust/rustc/ui/weak-new-uninhabited-issue-48493.rs: New test. * rust/rustc/ui/weird-exit-code.rs: New test. * rust/rustc/ui/weird-exprs.rs: New test. * rust/rustc/ui/wf-bound-region-in-object-type.rs: New test. * rust/rustc/ui/wf/issue-48638.rs: New test. * rust/rustc/ui/wf/wf-array-elem-sized.rs: New test. * rust/rustc/ui/wf/wf-const-type.rs: New test. * rust/rustc/ui/wf/wf-convert-unsafe-trait-obj-box.rs: New test. * rust/rustc/ui/wf/wf-convert-unsafe-trait-obj.rs: New test. * rust/rustc/ui/wf/wf-enum-bound.rs: New test. * rust/rustc/ui/wf/wf-enum-fields-struct-variant.rs: New test. * rust/rustc/ui/wf/wf-enum-fields.rs: New test. * rust/rustc/ui/wf/wf-fn-where-clause.rs: New test. * rust/rustc/ui/wf/wf-foreign-fn-decl-ret.rs: New test. * rust/rustc/ui/wf/wf-impl-associated-type-region.rs: New test. * rust/rustc/ui/wf/wf-impl-associated-type-trait.rs: New test. * rust/rustc/ui/wf/wf-impl-self-type.rs: New test. * rust/rustc/ui/wf/wf-in-fn-arg.rs: New test. * rust/rustc/ui/wf/wf-in-fn-ret.rs: New test. * rust/rustc/ui/wf/wf-in-fn-type-arg.rs: New test. * rust/rustc/ui/wf/wf-in-fn-type-ret.rs: New test. * rust/rustc/ui/wf/wf-in-fn-type-static.rs: New test. * rust/rustc/ui/wf/wf-in-fn-where-clause.rs: New test. * rust/rustc/ui/wf/wf-in-obj-type-static.rs: New test. * rust/rustc/ui/wf/wf-in-obj-type-trait.rs: New test. * rust/rustc/ui/wf/wf-inherent-impl-method-where-clause.rs: New test. * rust/rustc/ui/wf/wf-inherent-impl-where-clause.rs: New test. * rust/rustc/ui/wf/wf-misc-methods-issue-28609.rs: New test. * rust/rustc/ui/wf/wf-object-safe.rs: New test. * rust/rustc/ui/wf/wf-outlives-ty-in-fn-or-trait.rs: New test. * rust/rustc/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.rs: New test. * rust/rustc/ui/wf/wf-static-method.rs: New test. * rust/rustc/ui/wf/wf-static-type.rs: New test. * rust/rustc/ui/wf/wf-struct-bound.rs: New test. * rust/rustc/ui/wf/wf-struct-field.rs: New test. * rust/rustc/ui/wf/wf-trait-associated-type-bound.rs: New test. * rust/rustc/ui/wf/wf-trait-associated-type-region.rs: New test. * rust/rustc/ui/wf/wf-trait-associated-type-trait.rs: New test. * rust/rustc/ui/wf/wf-trait-bound.rs: New test. * rust/rustc/ui/wf/wf-trait-default-fn-arg.rs: New test. * rust/rustc/ui/wf/wf-trait-default-fn-ret.rs: New test. * rust/rustc/ui/wf/wf-trait-default-fn-where-clause.rs: New test. * rust/rustc/ui/wf/wf-trait-fn-arg.rs: New test. * rust/rustc/ui/wf/wf-trait-fn-ret.rs: New test. * rust/rustc/ui/wf/wf-trait-fn-where-clause.rs: New test. * rust/rustc/ui/wf/wf-trait-superbound.rs: New test. * rust/rustc/ui/wf/wf-unsafe-trait-obj-match.rs: New test. * rust/rustc/ui/where-clauses/auxiliary/where_clauses_xc.rs: New test. * rust/rustc/ui/where-clauses/where-clause-bounds-inconsistency.rs: New test. * rust/rustc/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.rs: New test. * rust/rustc/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.rs: New test. * rust/rustc/ui/where-clauses/where-clause-early-bound-lifetimes.rs: New test. * rust/rustc/ui/where-clauses/where-clause-method-substituion-rpass.rs: New test. * rust/rustc/ui/where-clauses/where-clause-method-substituion.rs: New test. * rust/rustc/ui/where-clauses/where-clause-region-outlives.rs: New test. * rust/rustc/ui/where-clauses/where-clauses-cross-crate.rs: New test. * rust/rustc/ui/where-clauses/where-clauses-lifetimes.rs: New test. * rust/rustc/ui/where-clauses/where-clauses-method-unsatisfied.rs: New test. * rust/rustc/ui/where-clauses/where-clauses-method.rs: New test. * rust/rustc/ui/where-clauses/where-clauses-unboxed-closures.rs: New test. * rust/rustc/ui/where-clauses/where-clauses-unsatisfied.rs: New test. * rust/rustc/ui/where-clauses/where-clauses.rs: New test. * rust/rustc/ui/where-clauses/where-equality-constraints.rs: New test. * rust/rustc/ui/where-clauses/where-for-self-2.rs: New test. * rust/rustc/ui/where-clauses/where-for-self.rs: New test. * rust/rustc/ui/where-clauses/where-lifetime-resolution.rs: New test. * rust/rustc/ui/while-let.rs: New test. * rust/rustc/ui/while-type-error.rs: New test. * rust/rustc/ui/windows-subsystem-invalid.rs: New test. * rust/rustc/ui/wrapping-int-api.rs: New test. * rust/rustc/ui/write-fmt-errors.rs: New test. * rust/rustc/ui/write-to-static-mut-in-static.rs: New test. * rust/rustc/ui/writealias.rs: New test. * rust/rustc/ui/writing-to-immutable-vec.rs: New test. * rust/rustc/ui/wrong-hashset-issue-42918.rs: New test. * rust/rustc/ui/wrong-mul-method-signature.rs: New test. * rust/rustc/ui/wrong-ret-type.rs: New test. * rust/rustc/ui/x86stdcall.rs: New test. * rust/rustc/ui/x86stdcall2.rs: New test. * rust/rustc/ui/xc-private-method.rs: New test. * rust/rustc/ui/xc-private-method2.rs: New test. * rust/rustc/ui/xcrate/auxiliary/static_priv_by_default.rs: New test. * rust/rustc/ui/xcrate/auxiliary/xcrate_unit_struct.rs: New test. * rust/rustc/ui/xcrate/xcrate-private-by-default.rs: New test. * rust/rustc/ui/xcrate/xcrate-unit-struct.rs: New test. * rust/rustc/ui/yield.rs: New test. * rust/rustc/ui/yield1.rs: New test. * rust/rustc/ui/yield2.rs: New test. * rust/rustc/ui/z-crate-attr.rs: New test. * rust/rustc/ui/zero-sized/zero-size-type-destructors.rs: New test. * rust/rustc/ui/zero-sized/zero-sized-binary-heap-push.rs: New test. * rust/rustc/ui/zero-sized/zero-sized-btreemap-insert.rs: New test. * rust/rustc/ui/zero-sized/zero-sized-linkedlist-push.rs: New test. * rust/rustc/ui/zero-sized/zero-sized-tuple-struct.rs: New test. Signed-off-by: Muhammad Mahad --- .../rustc/ui/abi/abi-sysv64-arg-passing.rs | 449 + .../rustc/ui/abi/abi-sysv64-register-usage.rs | 98 + .../rust/rustc/ui/abi/anon-extern-mod.rs | 19 + .../anon-extern-mod-cross-crate-1.rs | 10 + .../rustc/ui/abi/auxiliary/foreign_lib.rs | 39 + .../rust/rustc/ui/abi/c-stack-as-value.rs | 19 + .../rust/rustc/ui/abi/cabi-int-widening.rs | 16 + .../anon-extern-mod-cross-crate-1.rs | 10 + .../anon-extern-mod-cross-crate-2.rs | 15 + .../anon-extern-mod-cross-crate-1.rs | 10 + .../rustc/ui/abi/duplicated-external-mods.rs | 10 + .../auxiliary/extern-crosscrate-source.rs | 32 + .../rustc/ui/abi/extern/extern-call-deep.rs | 40 + .../rustc/ui/abi/extern/extern-call-deep2.rs | 45 + .../rustc/ui/abi/extern/extern-call-direct.rs | 11 + .../ui/abi/extern/extern-call-indirect.rs | 39 + .../rustc/ui/abi/extern/extern-call-scrub.rs | 49 + .../rustc/ui/abi/extern/extern-crosscrate.rs | 22 + .../ui/abi/extern/extern-pass-TwoU16s.rs | 26 + .../ui/abi/extern/extern-pass-TwoU32s.rs | 26 + .../ui/abi/extern/extern-pass-TwoU64s.rs | 26 + .../rustc/ui/abi/extern/extern-pass-TwoU8s.rs | 26 + .../rustc/ui/abi/extern/extern-pass-char.rs | 17 + .../rustc/ui/abi/extern/extern-pass-double.rs | 14 + .../rustc/ui/abi/extern/extern-pass-empty.rs | 56 + .../rustc/ui/abi/extern/extern-pass-u32.rs | 17 + .../rustc/ui/abi/extern/extern-pass-u64.rs | 17 + .../ui/abi/extern/extern-return-TwoU16s.rs | 22 + .../ui/abi/extern/extern-return-TwoU32s.rs | 22 + .../ui/abi/extern/extern-return-TwoU64s.rs | 22 + .../ui/abi/extern/extern-return-TwoU8s.rs | 22 + .../ui/abi/foreign/auxiliary/foreign_lib.rs | 39 + .../ui/abi/foreign/foreign-call-no-runtime.rs | 56 + .../rust/rustc/ui/abi/foreign/foreign-dupe.rs | 18 + .../ui/abi/foreign/foreign-fn-with-byval.rs | 33 + .../rustc/ui/abi/foreign/foreign-no-abi.rs | 23 + .../rustc/ui/abi/invoke-external-foreign.rs | 18 + .../issues/issue-62350-sysv-neg-reg-counts.rs | 47 + .../rust/rustc/ui/abi/lib-defaults.rs | 18 + .../ui/abi/mir/mir_codegen_calls_variadic.rs | 23 + .../ui/abi/numbers-arithmetic/i128-ffi.rs | 32 + .../rustc/ui/abi/segfault-no-out-of-stack.rs | 51 + .../rust/rustc/ui/abi/stack-probes-lto.rs | 20 + .../rust/rustc/ui/abi/stack-probes.rs | 69 + .../ui/abi/statics/static-mut-foreign.rs | 42 + .../ui/abi/struct-enums/struct-return.rs | 115 + .../rustc/ui/abi/union/union-c-interop.rs | 38 + .../rust/rustc/ui/abi/variadic-ffi.rs | 85 + .../ui/absolute-paths-in-nested-use-groups.rs | 12 + .../rust/rustc/ui/access-mode-in-closures.rs | 11 + .../rust/rustc/ui/alias-uninit-value.rs | 21 + .../rust/rustc/ui/align-with-extern-c-fn.rs | 19 + .../rust/rustc/ui/alignment-gep-tup-like-1.rs | 40 + .../alloc-error-handler-bad-signature-1.rs | 19 + .../alloc-error-handler-bad-signature-2.rs | 18 + .../alloc-error-handler-bad-signature-3.rs | 16 + .../rustc/ui/alloca-from-derived-tydesc.rs | 16 + .../rust/rustc/ui/allocator/allocator-args.rs | 14 + .../allocator/auxiliary/custom-as-global.rs | 17 + .../rustc/ui/allocator/auxiliary/custom.rs | 22 + .../rustc/ui/allocator/auxiliary/helper.rs | 12 + .../allocator/auxiliary/system-allocator.rs | 9 + .../allocator/auxiliary/system-allocator2.rs | 9 + .../rustc/ui/allocator/custom-in-block.rs | 23 + .../rustc/ui/allocator/custom-in-submodule.rs | 27 + .../rust/rustc/ui/allocator/custom.rs | 61 + .../rustc/ui/allocator/function-allocator.rs | 5 + .../rust/rustc/ui/allocator/hygiene.rs | 32 + .../no_std-alloc-error-handler-custom.rs | 98 + .../no_std-alloc-error-handler-default.rs | 85 + .../rustc/ui/allocator/not-an-allocator.rs | 9 + .../rust/rustc/ui/allocator/two-allocators.rs | 10 + .../rustc/ui/allocator/two-allocators2.rs | 13 + .../rustc/ui/allocator/two-allocators3.rs | 11 + .../rust/rustc/ui/allocator/xcrate-use.rs | 37 + .../rust/rustc/ui/allocator/xcrate-use2.rs | 48 + .../annotate-snippet/auxiliary/multispan.rs | 38 + .../rustc/ui/annotate-snippet/missing-type.rs | 6 + .../rustc/ui/annotate-snippet/multispan.rs | 29 + .../ui/anon-params/anon-params-denied-2018.rs | 19 + .../ui/anon-params/anon-params-deprecated.rs | 20 + .../anon-params-edition-hygiene.rs | 11 + .../auxiliary/anon-params-edition-hygiene.rs | 13 + .../ui/anonymous-higher-ranked-lifetime.rs | 31 + .../rust/rustc/ui/arg-count-mismatch.rs | 6 + .../rust/rustc/ui/arg-type-mismatch.rs | 6 + .../rust/rustc/ui/argument-passing.rs | 26 + .../rust/rustc/ui/array-break-length.rs | 10 + .../rust/rustc/ui/array-not-vector.rs | 13 + .../ui/array-slice-vec/array_const_index-1.rs | 13 + .../bounds-check-no-overflow.rs | 12 + .../array-slice-vec/box-of-array-of-drop-1.rs | 48 + .../array-slice-vec/box-of-array-of-drop-2.rs | 48 + .../ui/array-slice-vec/cast-in-array-size.rs | 15 + .../check-static-mut-slices.rs | 16 + .../ui/array-slice-vec/check-static-slice.rs | 37 + .../ui/array-slice-vec/copy-out-of-array-1.rs | 20 + .../ui/array-slice-vec/destructure-array-1.rs | 28 + .../rustc/ui/array-slice-vec/dst-raw-slice.rs | 14 + .../ui/array-slice-vec/empty-mutable-vec.rs | 9 + .../rustc/ui/array-slice-vec/estr-slice.rs | 51 + .../rustc/ui/array-slice-vec/evec-slice.rs | 48 + .../ui/array-slice-vec/fixed_length_copy.rs | 10 + .../ui/array-slice-vec/huge-largest-array.rs | 15 + .../ui/array-slice-vec/infer_array_len.rs | 22 + .../issue-69103-extra-binding-subslice.rs | 19 + .../ui/array-slice-vec/ivec-pass-by-value.rs | 5 + .../array-slice-vec/match_arr_unknown_len.rs | 12 + ...ility-inherits-through-fixed-length-vec.rs | 20 + .../ui/array-slice-vec/mutable-alias-vec.rs | 16 + .../rustc/ui/array-slice-vec/nested-vec-1.rs | 9 + .../rustc/ui/array-slice-vec/nested-vec-2.rs | 16 + .../rustc/ui/array-slice-vec/nested-vec-3.rs | 55 + .../new-style-fixed-length-vec.rs | 8 + .../array-slice-vec/rcvr-borrowed-to-slice.rs | 34 + .../array-slice-vec/repeated-vector-syntax.rs | 14 + .../ui/array-slice-vec/show-boxed-slice.rs | 9 + .../slice-of-zero-size-elements.rs | 54 + .../rustc/ui/array-slice-vec/slice-panic-1.rs | 27 + .../rustc/ui/array-slice-vec/slice-panic-2.rs | 31 + .../slice-pat-type-mismatches.rs | 37 + .../rust/rustc/ui/array-slice-vec/slice.rs | 82 + .../ui/array-slice-vec/slice_binary_search.rs | 22 + ...subslice-only-once-semantic-restriction.rs | 12 + .../subslice-patterns-const-eval-match.rs | 99 + .../subslice-patterns-const-eval.rs | 96 + .../array-slice-vec/variance-vec-covariant.rs | 21 + .../rust/rustc/ui/array-slice-vec/vec-dst.rs | 27 + .../ui/array-slice-vec/vec-fixed-length.rs | 25 + .../rustc/ui/array-slice-vec/vec-late-init.rs | 10 + .../ui/array-slice-vec/vec-macro-no-std.rs | 28 + .../array-slice-vec/vec-macro-rvalue-scope.rs | 12 + .../vec-macro-with-brackets.rs | 17 + .../vec-macro-with-trailing-comma.rs | 9 + .../array-slice-vec/vec-matching-autoslice.rs | 24 + .../ui/array-slice-vec/vec-matching-fixed.rs | 31 + .../ui/array-slice-vec/vec-matching-fold.rs | 47 + .../vec-matching-legal-tail-element-borrow.rs | 16 + .../rustc/ui/array-slice-vec/vec-matching.rs | 143 + .../array-slice-vec/vec-repeat-with-cast.rs | 6 + .../ui/array-slice-vec/vec-tail-matching.rs | 35 + .../ui/array-slice-vec/vector-no-ann-2.rs | 8 + .../rust/rustc/ui/array_const_index-0.rs | 9 + .../rust/rustc/ui/array_const_index-1.rs | 9 + .../rust/rustc/ui/artificial-block.rs | 6 + gcc/testsuite/rust/rustc/ui/as-precedence.rs | 11 + gcc/testsuite/rust/rustc/ui/asm/bad-arch.rs | 20 + .../rust/rustc/ui/asm/bad-options.rs | 19 + gcc/testsuite/rust/rustc/ui/asm/bad-reg.rs | 56 + .../rust/rustc/ui/asm/bad-template.rs | 29 + gcc/testsuite/rust/rustc/ui/asm/const.rs | 57 + .../rust/rustc/ui/asm/duplicate-options.rs | 27 + .../rust/rustc/ui/asm/interpolated-idents.rs | 25 + .../rust/rustc/ui/asm/issue-72570.rs | 13 + gcc/testsuite/rust/rustc/ui/asm/noreturn.rs | 18 + .../rust/rustc/ui/asm/parse-error.rs | 60 + .../rust/rustc/ui/asm/rustfix-asm.rs | 17 + gcc/testsuite/rust/rustc/ui/asm/srcloc.rs | 125 + gcc/testsuite/rust/rustc/ui/asm/sym.rs | 81 + .../rust/rustc/ui/asm/type-check-1.rs | 26 + .../rust/rustc/ui/asm/type-check-2.rs | 105 + .../rust/rustc/ui/asm/type-check-3.rs | 72 + .../rust/rustc/ui/asm/type-check-4.rs | 24 + .../rust/rustc/ui/assert-eq-trailing-comma.rs | 6 + gcc/testsuite/rust/rustc/ui/assert-escape.rs | 6 + .../rust/rustc/ui/assert-ne-trailing-comma.rs | 6 + gcc/testsuite/rust/rustc/ui/assign-assign.rs | 31 + .../rust/rustc/ui/assign-imm-local-twice.rs | 14 + .../ui/assignment-operator-unimplemented.rs | 8 + gcc/testsuite/rust/rustc/ui/assoc-inherent.rs | 10 + .../rust/rustc/ui/assoc-lang-items.rs | 22 + .../rust/rustc/ui/assoc-oddities-3.rs | 14 + .../associated-const-ambiguity-report.rs | 22 + .../associated-const-array-len.rs | 11 + .../associated-const-const-eval.rs | 21 + ...associated-const-cross-crate-const-eval.rs | 29 + .../associated-const-cross-crate-defaults.rs | 23 + .../associated-const-cross-crate.rs | 18 + .../associated-const-dead-code.rs | 13 + .../associated-const-generic-obligations.rs | 19 + .../associated-const-impl-wrong-lifetime.rs | 12 + .../associated-const-impl-wrong-type.rs | 13 + .../associated-const-in-global-const.rs | 14 + .../associated-const-in-trait.rs | 15 + .../associated-const-inherent-impl.rs | 12 + .../associated-const-marks-live-code.rs | 16 + .../associated-const-match-patterns.rs | 69 + .../associated-const-no-item.rs | 11 + .../associated-const-outer-ty-refs.rs | 11 + .../associated-const-overwrite-default.rs | 14 + .../associated-const-private-impl.rs | 16 + .../associated-const-public-impl.rs | 17 + .../associated-const-range-match-patterns.rs | 41 + .../associated-const-resolution-order.rs | 26 + .../associated-const-self-type.rs | 14 + .../associated-const-trait-bound.rs | 22 + .../associated-const-type-parameter-arms.rs | 30 + ...ssociated-const-type-parameter-arrays-2.rs | 22 + .../associated-const-type-parameter-arrays.rs | 22 + .../associated-const-type-parameters.rs | 45 + .../associated-const-ufcs-infer-trait.rs | 14 + .../associated-const-use-default.rs | 12 + ...associated-const-use-impl-of-same-trait.rs | 26 + .../ui/associated-consts/associated-const.rs | 14 + .../auxiliary/associated-const-cc-lib.rs | 35 + .../auxiliary/empty-struct.rs | 10 + .../associated-consts/defaults-cyclic-fail.rs | 18 + .../associated-consts/defaults-cyclic-pass.rs | 37 + .../defaults-not-assumed-fail.rs | 46 + .../defaults-not-assumed-pass.rs | 43 + ...24949-assoc-const-static-recursion-impl.rs | 16 + ...oc-const-static-recursion-trait-default.rs | 18 + ...4949-assoc-const-static-recursion-trait.rs | 16 + .../rustc/ui/associated-consts/issue-63496.rs | 10 + .../issue-69020-assoc-const-arith-overflow.rs | 49 + .../rustc/ui/associated-item-long-paths.rs | 48 + .../associated-item-duplicate-bounds.rs | 12 + .../associated-item-duplicate-names-2.rs | 9 + .../associated-item-duplicate-names-3.rs | 20 + .../associated-item-duplicate-names.rs | 20 + .../associated-item/associated-item-enum.rs | 21 + .../rustc/ui/associated-item/issue-48027.rs | 9 + .../rust/rustc/ui/associated-path-shl.rs | 10 + .../ambiguous-associated-type.rs | 13 + .../assoc-type-bound-through-where-clause.rs | 17 + .../assoc-type-eq-with-dyn-atb-fail.rs | 38 + .../auxiliary/fn-aux.rs | 178 + .../auxiliary/fn-dyn-aux.rs | 183 + .../bad-bounds-on-assoc-in-trait.rs | 69 + .../bounds-on-assoc-in-trait.rs | 55 + .../ui/associated-type-bounds/duplicate.rs | 160 + .../dyn-impl-trait-type.rs | 67 + .../ui/associated-type-bounds/dyn-lcsit.rs | 70 + .../dyn-rpit-and-let.rs | 74 + .../entails-sized-object-safety.rs | 27 + .../ui/associated-type-bounds/enum-bounds.rs | 123 + .../ui/associated-type-bounds/fn-apit.rs | 60 + .../rustc/ui/associated-type-bounds/fn-aux.rs | 13 + .../ui/associated-type-bounds/fn-dyn-apit.rs | 62 + .../ui/associated-type-bounds/fn-inline.rs | 64 + .../ui/associated-type-bounds/fn-where.rs | 80 + .../ui/associated-type-bounds/fn-wrap-apit.rs | 66 + .../implied-region-constraints.rs | 46 + .../ui/associated-type-bounds/inside-adt.rs | 30 + .../ui/associated-type-bounds/issue-61752.rs | 25 + .../ui/associated-type-bounds/issue-70292.rs | 22 + .../associated-type-bounds/issue-71443-1.rs | 10 + .../associated-type-bounds/issue-71443-2.rs | 12 + .../ui/associated-type-bounds/issue-73818.rs | 26 + .../rustc/ui/associated-type-bounds/lcsit.rs | 79 + .../rustc/ui/associated-type-bounds/rpit.rs | 65 + .../associated-type-bounds/struct-bounds.rs | 117 + .../trait-alias-impl-trait.rs | 68 + .../ui/associated-type-bounds/trait-params.rs | 118 + .../ui/associated-type-bounds/type-alias.rs | 20 + .../ui/associated-type-bounds/union-bounds.rs | 126 + .../associate-type-bound-normalization.rs | 26 + ...on-ambig-between-bound-and-where-clause.rs | 43 + ...pe-projection-from-multiple-supertraits.rs | 44 + ...ociated-type-projection-from-supertrait.rs | 37 + ...ed-types-ICE-when-projecting-out-of-err.rs | 26 + .../associated-types-basic.rs | 15 + .../associated-types-binding-in-trait.rs | 37 + ...ssociated-types-binding-in-where-clause.rs | 39 + ...s-binding-to-type-defined-in-supertrait.rs | 36 + .../associated-types-bound-ambiguity.rs | 24 + .../associated-types-bound-failure.rs | 30 + .../associated-types-bound.rs | 44 + .../associated-types/associated-types-cc.rs | 19 + .../associated-types-coherence-failure.rs | 50 + .../associated-types-conditional-dispatch.rs | 67 + .../associated-types-constant-type.rs | 32 + ...ciated-types-doubleendediterator-object.rs | 21 + ...ted-types-duplicate-binding-in-env-hrtb.rs | 18 + ...sociated-types-duplicate-binding-in-env.rs | 22 + .../associated-types-enum-field-named.rs | 36 + .../associated-types-enum-field-numbered.rs | 36 + .../associated-types/associated-types-eq-1.rs | 14 + .../associated-types/associated-types-eq-2.rs | 20 + .../associated-types/associated-types-eq-3.rs | 45 + .../associated-types-eq-expr-path.rs | 17 + .../associated-types-eq-hr.rs | 117 + .../associated-types-eq-obj.rs | 26 + .../associated-types-for-unimpl-trait.rs | 16 + .../associated-types-from-supertrait.rs | 9 + .../associated-types-impl-redirect.rs | 52 + .../associated-types-in-ambiguous-context.rs | 30 + .../associated-types-in-bound-type-arg.rs | 18 + .../associated-types-in-default-method.rs | 28 + .../associated-types-in-fn.rs | 29 + .../associated-types-in-impl-generics.rs | 37 + .../associated-types-in-inherent-method.rs | 31 + .../associated-types-incomplete-object.rs | 32 + ...ted-types-invalid-trait-ref-issue-18865.rs | 15 + .../associated-types-issue-17359.rs | 11 + .../associated-types-issue-20220.rs | 29 + .../associated-types-issue-20346.rs | 36 + .../associated-types-issue-20371.rs | 10 + .../associated-types-issue-21212.rs | 23 + .../associated-types-iterator-binding.rs | 20 + .../associated-types-method.rs | 28 + ...sociated-types-multiple-types-one-trait.rs | 47 + .../associated-types-nested-projections.rs | 45 + .../associated-types-no-suitable-bound.rs | 17 + ...sociated-types-no-suitable-supertrait-2.rs | 22 + ...associated-types-no-suitable-supertrait.rs | 27 + ...iated-types-normalize-in-bounds-binding.rs | 39 + ...sociated-types-normalize-in-bounds-ufcs.rs | 36 + .../associated-types-normalize-in-bounds.rs | 36 + ...ociated-types-normalize-unifield-struct.rs | 25 + .../associated-types-outlives.rs | 29 + .../associated-types-overridden-binding-2.rs | 9 + .../associated-types-overridden-binding.rs | 12 + .../associated-types-overridden-default.rs | 23 + .../associated-types-path-1.rs | 14 + .../associated-types-path-2.rs | 47 + ...ated-types-project-from-hrtb-in-fn-body.rs | 27 + ...ssociated-types-project-from-hrtb-in-fn.rs | 38 + ...iated-types-project-from-hrtb-in-struct.rs | 40 + ...types-project-from-hrtb-in-trait-method.rs | 39 + ...ject-from-type-param-via-bound-in-where.rs | 99 + ...ciated-types-projection-bound-ambiguity.rs | 17 + ...d-types-projection-bound-in-supertraits.rs | 24 + ...ypes-projection-from-known-type-in-impl.rs | 39 + ...ociated-types-projection-in-object-type.rs | 41 + ...sociated-types-projection-in-supertrait.rs | 46 + ...ciated-types-projection-in-where-clause.rs | 32 + ...related-trait-in-method-without-default.rs | 31 + ...ted-types-projection-to-unrelated-trait.rs | 36 + ...ed-path-with-trait-with-type-parameters.rs | 10 + .../associated-types-ref-from-struct.rs | 52 + .../associated-types-ref-in-struct-literal.rs | 24 + ...ciated-types-region-erasure-issue-20582.rs | 22 + .../associated-types-resolve-lifetime.rs | 16 + .../associated-types-return.rs | 47 + .../associated-types-simple.rs | 25 + .../associated-types-stream.rs | 41 + .../associated-types-struct-field-named.rs | 36 + .../associated-types-struct-field-numbered.rs | 33 + .../associated-types-subtyping-1.rs | 48 + .../associated-types-sugar-path.rs | 42 + .../associated-types-unconstrained.rs | 17 + .../associated-types-unsized.rs | 15 + ...iated-types-where-clause-impl-ambiguity.rs | 47 + .../auxiliary/associated-types-cc-lib.rs | 17 + .../bound-lifetime-constrained.rs | 49 + .../bound-lifetime-in-binding-only.rs | 72 + .../bound-lifetime-in-return-only.rs | 50 + .../ui/associated-types/cache/chrono-scan.rs | 31 + .../ui/associated-types/cache/elision.rs | 24 + .../cache/project-fn-ret-contravariant.rs | 51 + .../cache/project-fn-ret-invariant.rs | 62 + .../defaults-cyclic-fail-1.rs | 41 + .../defaults-cyclic-fail-2.rs | 42 + .../defaults-cyclic-pass-1.rs | 57 + .../defaults-cyclic-pass-2.rs | 57 + .../defaults-in-other-trait-items-pass.rs | 38 + .../defaults-in-other-trait-items.rs | 47 + .../ui/associated-types/defaults-mixed.rs | 35 + .../defaults-specialization.rs | 97 + .../associated-types/defaults-suitability.rs | 102 + .../defaults-unsound-62211-1.rs | 55 + .../defaults-unsound-62211-2.rs | 55 + .../rustc/ui/associated-types/defaults-wf.rs | 12 + .../higher-ranked-projection.rs | 28 + .../hr-associated-type-bound-1.rs | 19 + .../hr-associated-type-bound-2.rs | 22 + .../hr-associated-type-bound-object.rs | 15 + .../hr-associated-type-bound-param-1.rs | 21 + .../hr-associated-type-bound-param-2.rs | 23 + .../hr-associated-type-bound-param-3.rs | 20 + .../hr-associated-type-bound-param-4.rs | 20 + .../hr-associated-type-bound-param-5.rs | 41 + .../hr-associated-type-bound-param-6.rs | 21 + .../hr-associated-type-projection-1.rs | 22 + .../impl-trait-return-missing-constraint.rs | 33 + .../ui/associated-types/impl-wf-cycle-1.rs | 30 + .../ui/associated-types/impl-wf-cycle-2.rs | 17 + .../rustc/ui/associated-types/issue-26681.rs | 21 + .../rustc/ui/associated-types/issue-32350.rs | 30 + .../rustc/ui/associated-types/issue-36499.rs | 6 + .../rustc/ui/associated-types/issue-41868.rs | 24 + .../rustc/ui/associated-types/issue-43924.rs | 17 + .../rustc/ui/associated-types/issue-44153.rs | 20 + .../rustc/ui/associated-types/issue-47385.rs | 17 + .../rustc/ui/associated-types/issue-48010.rs | 24 + .../rustc/ui/associated-types/issue-54108.rs | 42 + .../ui/associated-types/issue-54182-1.rs | 93 + .../ui/associated-types/issue-54182-2.rs | 20 + .../rustc/ui/associated-types/issue-62200.rs | 16 + .../rustc/ui/associated-types/issue-63593.rs | 14 + .../rustc/ui/associated-types/issue-64848.rs | 30 + .../ui/associated-types/issue-64855-2.rs | 6 + .../rustc/ui/associated-types/issue-64855.rs | 9 + .../ui/associated-types/issue-65774-1.rs | 59 + .../ui/associated-types/issue-65774-2.rs | 59 + .../rustc/ui/associated-types/issue-65934.rs | 18 + .../rustc/ui/associated-types/issue-72806.rs | 22 + .../missing-associated-types.rs | 28 + .../normalization-probe-cycle.rs | 26 + .../normalize-cycle-in-eval-no-region.rs | 21 + .../normalize-cycle-in-eval.rs | 44 + .../associated-types/object-normalization.rs | 27 + .../param-env-normalize-cycle.rs | 40 + .../point-at-type-on-obligation-failure-2.rs | 34 + .../point-at-type-on-obligation-failure.rs | 22 + ...ait-with-supertraits-needing-sized-self.rs | 12 + .../rustc/ui/associated-types/wf-cycle-2.rs | 19 + .../rustc/ui/associated-types/wf-cycle.rs | 14 + .../rust/rustc/ui/ast-json/ast-json-ice.rs | 65 + .../ui/ast-json/ast-json-noexpand-output.rs | 11 + .../rust/rustc/ui/ast-json/ast-json-output.rs | 11 + .../rustc/ui/async-await/argument-patterns.rs | 29 + .../async-assoc-fn-anon-lifetimes.rs | 24 + .../rust/rustc/ui/async-await/async-await.rs | 219 + ...ync-block-control-flow-static-semantics.rs | 64 + .../async-borrowck-escaping-block-error.rs | 19 + .../async-borrowck-escaping-closure-error.rs | 11 + .../async-await/async-closure-matches-expr.rs | 13 + .../rustc/ui/async-await/async-closure.rs | 101 + .../rustc/ui/async-await/async-error-span.rs | 18 + ...async-fn-elided-impl-lifetime-parameter.rs | 16 + .../rustc/ui/async-await/async-fn-nonsend.rs | 56 + .../ui/async-await/async-fn-path-elision.rs | 14 + .../async-await/async-fn-send-uses-nonsend.rs | 58 + .../async-await/async-fn-size-moved-locals.rs | 119 + .../async-fn-size-uninit-locals.rs | 104 + .../rustc/ui/async-await/async-fn-size.rs | 106 + .../ui/async-await/async-matches-expr.rs | 11 + .../rustc/ui/async-await/async-trait-fn.rs | 8 + .../async-unsafe-fn-call-in-safe.rs | 20 + .../ui/async-await/async-with-closure.rs | 25 + .../ui/async-await/auxiliary/arc_wake.rs | 65 + .../2015-edition-error-various-positions.rs | 39 + .../await-keyword/2015-edition-warning.rs | 28 + ...018-edition-error-in-non-macro-position.rs | 25 + .../await-keyword/2018-edition-error.rs | 17 + .../incorrect-syntax-suggestions.rs | 133 + .../await-keyword/post_expansion_error.rs | 11 + .../rust/rustc/ui/async-await/await-unsize.rs | 15 + .../ui/async-await/bound-normalization.rs | 15 + ...nditional-and-guaranteed-initialization.rs | 17 + .../async-await/dont-print-desugared-async.rs | 9 + .../async-await/dont-suggest-missing-await.rs | 20 + .../drop-order/auxiliary/arc_wake.rs | 65 + ...-for-async-fn-parameters-by-ref-binding.rs | 271 + .../drop-order-for-async-fn-parameters.rs | 266 + .../drop-order-for-locals-when-cancelled.rs | 177 + ...order-for-temporary-in-tail-return-expr.rs | 99 + .../drop-order-locals-are-hidden.rs | 14 + .../drop-order/drop-order-when-cancelled.rs | 310 + .../edition-deny-async-fns-2015.rs | 39 + .../ui/async-await/expansion-in-attrs.rs | 14 + .../ui/async-await/feature-async-closure.rs | 9 + .../rust/rustc/ui/async-await/futures-api.rs | 62 + .../ui/async-await/generics-and-bounds.rs | 89 + .../issue-54239-private-type-triggers-lint.rs | 18 + .../rust/rustc/ui/async-await/issue-60709.rs | 29 + .../rust/rustc/ui/async-await/issue-61076.rs | 99 + .../rust/rustc/ui/async-await/issue-61452.rs | 14 + .../rust/rustc/ui/async-await/issue-61793.rs | 17 + .../issue-61949-self-return-type.rs | 28 + .../rust/rustc/ui/async-await/issue-62658.rs | 28 + ...-63832-await-short-temporary-lifetime-1.rs | 20 + ...ue-63832-await-short-temporary-lifetime.rs | 13 + .../ui/async-await/issue-64130-1-sync.rs | 24 + .../ui/async-await/issue-64130-2-send.rs | 24 + .../ui/async-await/issue-64130-3-other.rs | 27 + .../async-await/issue-64130-4-async-move.rs | 29 + .../issue-64130-non-send-future-diags.rs | 24 + .../rust/rustc/ui/async-await/issue-64391.rs | 15 + .../rust/rustc/ui/async-await/issue-66312.rs | 15 + .../issue-66387-if-without-else.rs | 11 + .../async-await/issue-67252-unnamed-future.rs | 25 + .../rust/rustc/ui/async-await/issue-67651.rs | 21 + .../issue-67765-async-diagnostic.rs | 17 + .../rust/rustc/ui/async-await/issue-68112.rs | 65 + .../rustc/ui/async-await/issue-68523-start.rs | 10 + .../rust/rustc/ui/async-await/issue-68523.rs | 8 + .../async-await/issue-69446-fnmut-capture.rs | 23 + .../rust/rustc/ui/async-await/issue-70594.rs | 12 + .../rust/rustc/ui/async-await/issue-70818.rs | 10 + .../async-await/issue-70935-complex-spans.rs | 26 + .../rust/rustc/ui/async-await/issue-71137.rs | 22 + .../rust/rustc/ui/async-await/issue-72442.rs | 27 + .../issue-72590-type-error-sized.rs | 23 + .../rust/rustc/ui/async-await/issue-73050.rs | 13 + .../rust/rustc/ui/async-await/issue-73137.rs | 43 + .../issue-74072-lifetime-name-annotations.rs | 38 + .../issue-74497-lifetime-in-opaque.rs | 20 + .../issues/auxiliary/issue-60674.rs | 13 + .../issues/auxiliary/issue_67893.rs | 11 + .../ui/async-await/issues/issue-51719.rs | 13 + .../ui/async-await/issues/issue-51751.rs | 12 + .../ui/async-await/issues/issue-53249.rs | 48 + .../issues/issue-54752-async-block.rs | 8 + .../ui/async-await/issues/issue-54974.rs | 15 + .../ui/async-await/issues/issue-55324.rs | 12 + .../ui/async-await/issues/issue-55809.rs | 29 + .../ui/async-await/issues/issue-58885.rs | 20 + .../ui/async-await/issues/issue-59001.rs | 15 + .../ui/async-await/issues/issue-59972.rs | 35 + .../ui/async-await/issues/issue-60518.rs | 11 + .../issues/issue-60655-latebound-regions.rs | 31 + .../ui/async-await/issues/issue-60674.rs | 20 + .../ui/async-await/issues/issue-61187.rs | 8 + .../ui/async-await/issues/issue-61986.rs | 20 + .../ui/async-await/issues/issue-62009-1.rs | 16 + .../ui/async-await/issues/issue-62009-2.rs | 11 + .../ui/async-await/issues/issue-62097.rs | 20 + .../ui/async-await/issues/issue-62517-1.rs | 22 + .../ui/async-await/issues/issue-62517-2.rs | 17 + .../ui/async-await/issues/issue-63388-1.rs | 19 + .../ui/async-await/issues/issue-63388-2.rs | 19 + .../ui/async-await/issues/issue-63388-3.rs | 18 + .../ui/async-await/issues/issue-63388-4.rs | 11 + .../ui/async-await/issues/issue-64391-2.rs | 21 + .../ui/async-await/issues/issue-64433.rs | 31 + .../ui/async-await/issues/issue-64477-2.rs | 23 + .../ui/async-await/issues/issue-64477.rs | 21 + .../ui/async-await/issues/issue-64964.rs | 23 + .../ui/async-await/issues/issue-65159.rs | 12 + ...-65419-async-fn-resume-after-completion.rs | 47 + ...issue-65419-async-fn-resume-after-panic.rs | 53 + ...65419-generator-resume-after-completion.rs | 26 + .../issues/issue-65436-raw-ptr-not-send.rs | 17 + .../issues/issue-66695-static-refs.rs | 25 + .../issue-66958-non-copy-infered-type-arg.rs | 16 + .../issues/issue-67611-static-mut-refs.rs | 34 + .../ui/async-await/issues/issue-67893.rs | 12 + .../async-await/issues/issue-69307-nested.rs | 31 + .../ui/async-await/issues/issue-69307.rs | 24 + .../ui/async-await/issues/issue-78654.rs | 17 + .../issues/non-async-enclosing-span.rs | 12 + .../move-part-await-return-rest-struct.rs | 19 + .../move-part-await-return-rest-tuple.rs | 13 + .../async-await/multiple-lifetimes/elided.rs | 11 + .../async-await/multiple-lifetimes/fn-ptr.rs | 13 + .../ui/async-await/multiple-lifetimes/hrtb.rs | 15 + .../async-await/multiple-lifetimes/named.rs | 11 + .../multiple-lifetimes/partial-relation.rs | 14 + .../multiple-lifetimes/ret-impl-trait-fg.rs | 19 + .../ret-impl-trait-no-fg.rs | 21 + .../multiple-lifetimes/ret-impl-trait-one.rs | 28 + .../async-await/multiple-lifetimes/ret-ref.rs | 45 + .../multiple-lifetimes/variance.rs | 16 + ...utually-recursive-async-impl-trait-type.rs | 14 + .../rustc/ui/async-await/nested-in-impl.rs | 16 + .../rustc/ui/async-await/no-async-const.rs | 6 + .../rustc/ui/async-await/no-const-async.rs | 6 + .../no-move-across-await-struct.rs | 17 + .../async-await/no-move-across-await-tuple.rs | 13 + .../no-non-guaranteed-initialization.rs | 14 + .../no-params-non-move-async-closure.rs | 9 + .../rust/rustc/ui/async-await/no-std.rs | 14 + .../rustc/ui/async-await/no-unsafe-async.rs | 12 + .../partial-initialization-across-await.rs | 43 + .../recursive-async-impl-trait-type.rs | 10 + .../async-await/return-ty-raw-ptr-coercion.rs | 26 + .../async-await/return-ty-unsize-coercion.rs | 46 + .../suggest-missing-await-closure.rs | 24 + .../ui/async-await/suggest-missing-await.rs | 30 + .../suggest-switching-edition-on-await.rs | 46 + .../ui/async-await/try-on-option-in-async.rs | 29 + .../ui/async-await/unreachable-lint-1.rs | 13 + .../rustc/ui/async-await/unreachable-lint.rs | 14 + .../ui/async-await/unresolved_type_param.rs | 24 + .../rustc/ui/async-await/unused-lifetime.rs | 43 + .../rust/rustc/ui/atomic-access-bool.rs | 25 + .../rust/rustc/ui/atomic-alignment.rs | 39 + .../rust/rustc/ui/atomic-compare_exchange.rs | 32 + .../rustc/ui/atomic-from-mut-not-available.rs | 8 + gcc/testsuite/rust/rustc/ui/atomic-print.rs | 47 + .../rustc/ui/attempted-access-non-fatal.rs | 7 + .../rust/rustc/ui/attr-eq-token-tree.rs | 3 + gcc/testsuite/rust/rustc/ui/attr-main-2.rs | 12 + gcc/testsuite/rust/rustc/ui/attr-main.rs | 9 + gcc/testsuite/rust/rustc/ui/attr-shebang.rs | 6 + gcc/testsuite/rust/rustc/ui/attr-start.rs | 10 + .../rust/rustc/ui/attr-usage-inline.rs | 10 + .../rust/rustc/ui/attr-usage-repr.rs | 34 + gcc/testsuite/rust/rustc/ui/attr.rs | 9 + ...bute-with-no-generics-in-parameter-list.rs | 4 + .../ui/attributes/attr-before-view-item.rs | 11 + .../ui/attributes/attr-before-view-item2.rs | 13 + .../rust/rustc/ui/attributes/attr-mix-new.rs | 12 + .../attrs-with-no-formal-in-generics-1.rs | 14 + .../attrs-with-no-formal-in-generics-2.rs | 13 + .../attrs-with-no-formal-in-generics-3.rs | 13 + .../auxiliary/key-value-expansion.rs | 13 + .../rustc/ui/attributes/class-attributes-1.rs | 20 + .../rustc/ui/attributes/class-attributes-2.rs | 32 + .../field-attributes-vis-unresolved.rs | 26 + .../rustc/ui/attributes/item-attributes.rs | 180 + .../ui/attributes/key-value-expansion.rs | 56 + .../rustc/ui/attributes/method-attributes.rs | 29 + .../rustc/ui/attributes/multiple-invalid.rs | 11 + .../ui/attributes/nonterminal-expansion.rs | 18 + .../rust/rustc/ui/attributes/obsolete-attr.rs | 10 + .../ui/attributes/register-attr-tool-fail.rs | 14 + .../attributes/register-attr-tool-import.rs | 18 + .../attributes/register-attr-tool-prelude.rs | 15 + .../attributes/register-attr-tool-unused.rs | 11 + .../rustc/ui/attributes/register-attr-tool.rs | 20 + .../rust/rustc/ui/attributes/unknown-attr.rs | 13 + .../unnamed-field-attributes-dup.rs | 12 + .../unnamed-field-attributes-vis.rs | 12 + .../ui/attributes/unnamed-field-attributes.rs | 10 + .../rustc/ui/attributes/variant-attributes.rs | 38 + .../rust/rustc/ui/attrs-resolution-errors.rs | 41 + .../rust/rustc/ui/attrs-resolution.rs | 38 + ...ugmented-assignments-feature-gate-cross.rs | 12 + .../ui/augmented-assignments-feature-gate.rs | 16 + .../rustc/ui/augmented-assignments-rpass.rs | 173 + .../rust/rustc/ui/augmented-assignments.rs | 28 + .../rust/rustc/ui/auto-instantiate.rs | 14 + .../rust/rustc/ui/auto-ref-slice-plus-ref.rs | 28 + .../ui/auto-traits/auto-is-contextual.rs | 19 + .../auto-trait-projection-recursion.rs | 35 + .../ui/auto-traits/auto-trait-validation.rs | 10 + .../rust/rustc/ui/auto-traits/auto-traits.rs | 33 + .../rustc/ui/auto-traits/issue-23080-2.rs | 14 + .../rust/rustc/ui/auto-traits/issue-23080.rs | 18 + .../typeck-auto-trait-no-supertraits-2.rs | 16 + .../typeck-auto-trait-no-supertraits.rs | 40 + ...-default-trait-impl-constituent-types-2.rs | 20 + ...ck-default-trait-impl-constituent-types.rs | 24 + .../typeck-default-trait-impl-negation.rs | 30 + .../typeck-default-trait-impl-precedence.rs | 22 + gcc/testsuite/rust/rustc/ui/autobind.rs | 13 + .../rust/rustc/ui/autoderef-full-lval.rs | 26 + .../auto-ref-bounded-ty-param.rs | 30 + .../autoref-autoderef/auto-ref-sliceable.rs | 20 + .../rustc/ui/autoref-autoderef/auto-ref.rs | 20 + .../autoderef-and-borrow-method-receiver.rs | 19 + .../autoderef-method-on-trait.rs | 17 + .../autoderef-method-priority.rs | 21 + .../autoderef-method-twice-but-not-thrice.rs | 17 + .../autoderef-method-twice.rs | 17 + .../ui/autoref-autoderef/autoderef-method.rs | 17 + .../ui/autoref-autoderef/autoderef-privacy.rs | 52 + .../autoref-intermediate-types-issue-3585.rs | 24 + .../ui/auxiliary/augmented_assignments.rs | 9 + .../blind-item-mixed-crate-use-item-foo.rs | 4 + .../blind-item-mixed-crate-use-item-foo2.rs | 4 + .../rustc/ui/auxiliary/changing-crates-a1.rs | 4 + .../rustc/ui/auxiliary/changing-crates-a2.rs | 4 + .../rustc/ui/auxiliary/changing-crates-b.rs | 6 + .../check_static_recursion_foreign_helper.rs | 12 + .../rust/rustc/ui/auxiliary/cond_plugin.rs | 39 + .../crate-method-reexport-grrrrrrr2.rs | 32 + .../rustc/ui/auxiliary/debuginfo-lto-aux.rs | 30 + .../default-ty-param-cross-crate-crate.rs | 10 + .../rust/rustc/ui/auxiliary/define-macro.rs | 7 + .../ui/auxiliary/edition-kw-macro-2015.rs | 27 + .../ui/auxiliary/edition-kw-macro-2018.rs | 27 + .../rust/rustc/ui/auxiliary/empty-struct.rs | 10 + .../rustc/ui/auxiliary/extern-prelude-vec.rs | 4 + .../rust/rustc/ui/auxiliary/extern-prelude.rs | 6 + .../rust/rustc/ui/auxiliary/extern-statics.rs | 5 + .../rust/rustc/ui/auxiliary/hello_macro.rs | 22 + .../rustc/ui/auxiliary/impl_privacy_xc_1.rs | 10 + .../rustc/ui/auxiliary/impl_privacy_xc_2.rs | 14 + .../rust/rustc/ui/auxiliary/inline_dtor.rs | 9 + .../rust/rustc/ui/auxiliary/inner_static.rs | 52 + .../rustc/ui/auxiliary/issue-72470-lib.rs | 176 + .../rust/rustc/ui/auxiliary/issue-76387.rs | 30 + .../rustc/ui/auxiliary/kinds_in_metadata.rs | 9 + .../link-cfg-works-transitive-dylib.rs | 5 + .../link-cfg-works-transitive-rlib.rs | 8 + .../rust/rustc/ui/auxiliary/linkage1.rs | 5 + .../rust/rustc/ui/auxiliary/llvm_pr32379.rs | 6 + .../ui/auxiliary/lto-duplicate-symbols1.rs | 7 + .../ui/auxiliary/lto-duplicate-symbols2.rs | 7 + .../lto-rustc-loads-linker-plugin.rs | 7 + .../rustc/ui/auxiliary/msvc-data-only-lib.rs | 6 + .../rust/rustc/ui/auxiliary/nested_item.rs | 31 + .../rustc/ui/auxiliary/noexporttypelib.rs | 3 + .../ui/auxiliary/orphan-check-diagnostics.rs | 2 + .../rust/rustc/ui/auxiliary/proc_macro_def.rs | 36 + .../rustc/ui/auxiliary/pub-and-stability.rs | 134 + .../auxiliary/reachable-unnameable-items.rs | 107 + .../auxiliary/reexport-should-still-link.rs | 6 + .../ui/auxiliary/removing-extern-crate.rs | 2 + .../rust/rustc/ui/auxiliary/rmeta-meta.rs | 9 + .../rustc/ui/auxiliary/rmeta-rlib-rpass.rs | 9 + .../rust/rustc/ui/auxiliary/rmeta-rlib.rs | 6 + .../rust/rustc/ui/auxiliary/rmeta-rmeta.rs | 10 + .../rustc/ui/auxiliary/rustc-rust-log-aux.rs | 2 + .../rust/rustc/ui/auxiliary/stability-cfg2.rs | 6 + .../rust/rustc/ui/auxiliary/svh-a-base.rs | 26 + .../rust/rustc/ui/auxiliary/svh-b.rs | 14 + .../auxiliary/trait_superkinds_in_metadata.rs | 9 + .../ui/auxiliary/typeid-intrinsic-aux1.rs | 30 + .../ui/auxiliary/typeid-intrinsic-aux2.rs | 30 + .../using-target-feature-unstable.rs | 6 + .../rustc/ui/auxiliary/weak-lang-items.rs | 23 + .../ui/auxiliary/xc-private-method-lib.rs | 34 + .../rust/rustc/ui/backtrace-debuginfo-aux.rs | 15 + .../rust/rustc/ui/backtrace-debuginfo.rs | 195 + gcc/testsuite/rust/rustc/ui/backtrace.rs | 126 + .../rust/rustc/ui/bad/bad-const-type.rs | 5 + .../rust/rustc/ui/bad/bad-crate-name.rs | 6 + .../rust/rustc/ui/bad/bad-env-capture.rs | 7 + .../rust/rustc/ui/bad/bad-env-capture2.rs | 6 + .../rust/rustc/ui/bad/bad-env-capture3.rs | 9 + .../rust/rustc/ui/bad/bad-expr-lhs.rs | 13 + .../rust/rustc/ui/bad/bad-expr-path.rs | 9 + .../rust/rustc/ui/bad/bad-expr-path2.rs | 11 + .../rustc/ui/bad/bad-extern-link-attrs.rs | 8 + .../ui/bad/bad-intrinsic-monomorphization.rs | 33 + .../rust/rustc/ui/bad/bad-lint-cap.rs | 5 + .../rust/rustc/ui/bad/bad-lint-cap2.rs | 9 + .../rust/rustc/ui/bad/bad-lint-cap3.rs | 10 + gcc/testsuite/rust/rustc/ui/bad/bad-main.rs | 2 + .../rustc/ui/bad/bad-method-typaram-kind.rs | 15 + .../rustc/ui/bad/bad-mid-path-type-params.rs | 44 + gcc/testsuite/rust/rustc/ui/bad/bad-module.rs | 8 + gcc/testsuite/rust/rustc/ui/bad/bad-sized.rs | 9 + .../rust/rustc/ui/bad/bad-type-env-capture.rs | 5 + .../rustc/ui/bare-fn-implements-fn-mut.rs | 28 + .../rust/rustc/ui/bare-static-string.rs | 7 + .../rust/rustc/ui/bastion-of-the-turbofish.rs | 37 + .../rust/rustc/ui/bench/issue-32062.rs | 51 + gcc/testsuite/rust/rustc/ui/big-literals.rs | 18 + .../rustc/ui/binary-minus-without-space.rs | 9 + .../rust/rustc/ui/binary-op-on-double-ref.rs | 10 + gcc/testsuite/rust/rustc/ui/bind-by-move.rs | 14 + .../rust/rustc/ui/binding/ambiguity-item.rs | 20 + .../bind-field-short-with-modifiers.rs | 27 + .../ui/binding/borrowed-ptr-pattern-2.rs | 14 + .../ui/binding/borrowed-ptr-pattern-3.rs | 14 + .../borrowed-ptr-pattern-infallible.rs | 9 + .../ui/binding/borrowed-ptr-pattern-option.rs | 16 + .../rustc/ui/binding/borrowed-ptr-pattern.rs | 13 + .../rust/rustc/ui/binding/const-param.rs | 13 + .../ui/binding/empty-types-in-patterns.rs | 60 + .../binding/exhaustive-bool-match-sanity.rs | 23 + .../ui/binding/expr-match-generic-unique1.rs | 20 + .../ui/binding/expr-match-generic-unique2.rs | 18 + .../rustc/ui/binding/expr-match-generic.rs | 30 + .../rustc/ui/binding/expr-match-panic-all.rs | 15 + .../rust/rustc/ui/binding/expr-match-panic.rs | 15 + .../rustc/ui/binding/expr-match-unique.rs | 11 + .../rust/rustc/ui/binding/expr-match.rs | 46 + .../rust/rustc/ui/binding/fat-arrow-match.rs | 18 + .../fn-arg-incomplete-pattern-drop-order.rs | 70 + .../ui/binding/fn-pattern-expected-type-2.rs | 9 + .../ui/binding/fn-pattern-expected-type.rs | 10 + .../ui/binding/func-arg-incomplete-pattern.rs | 25 + .../rustc/ui/binding/func-arg-ref-pattern.rs | 28 + .../rustc/ui/binding/func-arg-wild-pattern.rs | 13 + gcc/testsuite/rust/rustc/ui/binding/if-let.rs | 61 + .../binding/inconsistent-lifetime-mismatch.rs | 16 + .../inferred-suffix-in-pattern-range.rs | 25 + .../ui/binding/irrefutable-slice-patterns.rs | 15 + .../ui/binding/issue-53114-borrow-checks.rs | 85 + .../ui/binding/issue-53114-safety-checks.rs | 52 + .../rustc/ui/binding/let-assignability.rs | 13 + .../rust/rustc/ui/binding/let-destruct-ref.rs | 8 + .../rust/rustc/ui/binding/let-var-hygiene.rs | 12 + .../rustc/ui/binding/match-arm-statics.rs | 166 + .../rustc/ui/binding/match-beginning-vert.rs | 20 + .../rustc/ui/binding/match-borrowed_str.rs | 49 + .../rust/rustc/ui/binding/match-bot-2.rs | 7 + .../rust/rustc/ui/binding/match-bot.rs | 8 + .../ui/binding/match-byte-array-patterns.rs | 45 + .../rustc/ui/binding/match-enum-struct-0.rs | 18 + .../rustc/ui/binding/match-enum-struct-1.rs | 20 + .../ui/binding/match-implicit-copy-unique.rs | 18 + .../rust/rustc/ui/binding/match-in-macro.rs | 18 + .../rust/rustc/ui/binding/match-join.rs | 21 + .../rustc/ui/binding/match-larger-const.rs | 13 + .../ui/binding/match-naked-record-expr.rs | 13 + .../rustc/ui/binding/match-naked-record.rs | 14 + .../rust/rustc/ui/binding/match-path.rs | 15 + .../ui/binding/match-pattern-bindings.rs | 22 + .../rustc/ui/binding/match-pattern-lit.rs | 16 + .../binding/match-pattern-no-type-params.rs | 15 + .../rustc/ui/binding/match-pattern-simple.rs | 10 + .../rust/rustc/ui/binding/match-phi.rs | 20 + .../rustc/ui/binding/match-pipe-binding.rs | 61 + .../rustc/ui/binding/match-range-infer.rs | 18 + .../rustc/ui/binding/match-range-static.rs | 14 + .../rust/rustc/ui/binding/match-range.rs | 52 + .../rust/rustc/ui/binding/match-reassign.rs | 22 + .../match-ref-binding-in-guard-3256.rs | 14 + .../binding/match-ref-binding-mut-option.rs | 11 + .../rustc/ui/binding/match-ref-binding-mut.rs | 19 + .../rustc/ui/binding/match-ref-binding.rs | 13 + .../rustc/ui/binding/match-ref-unsized.rs | 12 + .../rust/rustc/ui/binding/match-str.rs | 26 + .../rust/rustc/ui/binding/match-struct-0.rs | 22 + .../rust/rustc/ui/binding/match-tag.rs | 31 + .../rustc/ui/binding/match-unique-bind.rs | 13 + .../rust/rustc/ui/binding/match-unsized.rs | 10 + .../match-value-binding-in-guard-3291.rs | 20 + .../rustc/ui/binding/match-var-hygiene.rs | 12 + .../ui/binding/match-vec-alternatives.rs | 81 + .../rust/rustc/ui/binding/match-vec-rvalue.rs | 16 + .../rustc/ui/binding/match-with-ret-arm.rs | 13 + .../rust/rustc/ui/binding/multi-let.rs | 8 + .../rustc/ui/binding/mut-in-ident-patterns.rs | 77 + .../rust/rustc/ui/binding/nested-matchs.rs | 17 + .../rust/rustc/ui/binding/nested-pattern.rs | 17 + .../rust/rustc/ui/binding/nil-pattern.rs | 5 + .../rustc/ui/binding/nullary-or-pattern.rs | 14 + .../ui/binding/optional_comma_in_match_arm.rs | 41 + .../rust/rustc/ui/binding/or-pattern.rs | 15 + .../rustc/ui/binding/order-drop-with-match.rs | 58 + .../rust/rustc/ui/binding/pat-ranges.rs | 21 + .../rust/rustc/ui/binding/pat-tuple-1.rs | 94 + .../rust/rustc/ui/binding/pat-tuple-2.rs | 24 + .../rust/rustc/ui/binding/pat-tuple-3.rs | 30 + .../rust/rustc/ui/binding/pat-tuple-4.rs | 58 + .../rust/rustc/ui/binding/pat-tuple-5.rs | 30 + .../rust/rustc/ui/binding/pat-tuple-6.rs | 46 + .../rust/rustc/ui/binding/pat-tuple-7.rs | 9 + .../binding/pattern-bound-var-in-for-each.rs | 21 + .../rustc/ui/binding/pattern-in-closure.rs | 15 + .../range-inclusive-pattern-precedence.rs | 24 + .../rustc/ui/binding/simple-generic-match.rs | 9 + .../rust/rustc/ui/binding/use-uninit-match.rs | 18 + .../rustc/ui/binding/use-uninit-match2.rs | 19 + .../ui/binding/zero_sized_subslice_match.rs | 12 + .../rust/rustc/ui/binop/binop-bitxor-str.rs | 4 + .../rust/rustc/ui/binop/binop-consume-args.rs | 66 + .../rust/rustc/ui/binop/binop-fail-3.rs | 12 + .../rust/rustc/ui/binop/binop-logic-float.rs | 4 + .../rust/rustc/ui/binop/binop-logic-int.rs | 4 + .../rustc/ui/binop/binop-move-semantics.rs | 69 + .../rust/rustc/ui/binop/binop-mul-bool.rs | 4 + .../rust/rustc/ui/binop/binop-mul-i32-f32.rs | 6 + .../rust/rustc/ui/binop/binop-panic.rs | 13 + .../rust/rustc/ui/binop/binop-typeck.rs | 9 + .../rust/rustc/ui/binops-issue-22743.rs | 25 + gcc/testsuite/rust/rustc/ui/binops.rs | 90 + gcc/testsuite/rust/rustc/ui/bitwise.rs | 35 + .../rust/rustc/ui/blind-item-local-shadow.rs | 14 + .../ui/blind-item-mixed-crate-use-item.rs | 27 + .../rustc/ui/blind-item-mixed-use-item.rs | 21 + .../ui/blind/blind-item-block-item-shadow.rs | 10 + .../rustc/ui/blind/blind-item-block-middle.rs | 10 + .../rustc/ui/blind/blind-item-item-shadow.rs | 8 + .../rust/rustc/ui/block-arg-call-as.rs | 13 + gcc/testsuite/rust/rustc/ui/block-arg.rs | 12 + .../rust/rustc/ui/block-explicit-types.rs | 7 + .../rust/rustc/ui/block-expr-precedence.rs | 63 + .../ui/block-expression-remove-semicolon.rs | 13 + .../rust/rustc/ui/block-fn-coerce.rs | 12 + gcc/testsuite/rust/rustc/ui/block-iter-1.rs | 16 + gcc/testsuite/rust/rustc/ui/block-iter-2.rs | 16 + .../block-must-not-have-result-do.rs | 6 + .../block-must-not-have-result-res.rs | 11 + .../block-must-not-have-result-while.rs | 7 + .../consider-removing-last-semi.rs | 14 + .../rust/rustc/ui/block-result/issue-11714.rs | 8 + .../rust/rustc/ui/block-result/issue-13428.rs | 17 + .../rust/rustc/ui/block-result/issue-13624.rs | 30 + .../rust/rustc/ui/block-result/issue-20862.rs | 10 + .../rust/rustc/ui/block-result/issue-22645.rs | 18 + .../rust/rustc/ui/block-result/issue-3563.rs | 8 + .../rust/rustc/ui/block-result/issue-5500.rs | 8 + .../block-result/unexpected-return-on-unit.rs | 15 + gcc/testsuite/rust/rustc/ui/bogus-tag.rs | 11 + gcc/testsuite/rust/rustc/ui/bool-not.rs | 7 + gcc/testsuite/rust/rustc/ui/bool.rs | 73 + .../rustc/ui/borrow-by-val-method-receiver.rs | 15 + .../rustc/ui/borrowck/assign-never-type.rs | 15 + .../ui/borrowck/assign_mutable_fields.rs | 23 + ...or-patterns-slice-patterns-box-patterns.rs | 223 + ...row-immutable-upvar-mutation-impl-trait.rs | 15 + .../borrow-immutable-upvar-mutation.rs | 57 + .../borrow-raw-address-of-borrowed.rs | 23 + ...rrow-raw-address-of-deref-mutability-ok.rs | 24 + .../borrow-raw-address-of-deref-mutability.rs | 18 + .../borrow-raw-address-of-mutability-ok.rs | 45 + .../borrow-raw-address-of-mutability.rs | 43 + .../rustc/ui/borrowck/borrow-tuple-fields.rs | 44 + .../borrowck/borrowck-access-permissions.rs | 51 + .../rustc/ui/borrowck/borrowck-and-init.rs | 7 + .../borrowck/borrowck-anon-fields-struct.rs | 38 + .../ui/borrowck/borrowck-anon-fields-tuple.rs | 36 + .../borrowck/borrowck-anon-fields-variant.rs | 46 + .../rustc/ui/borrowck/borrowck-argument.rs | 35 + .../rust/rustc/ui/borrowck/borrowck-asm.rs | 83 + .../ui/borrowck/borrowck-assign-comp-idx.rs | 40 + .../rustc/ui/borrowck/borrowck-assign-comp.rs | 37 + ...rowck-assign-to-andmut-in-aliasable-loc.rs | 21 + ...rrowck-assign-to-andmut-in-borrowed-loc.rs | 24 + .../borrowck/borrowck-assign-to-constants.rs | 7 + .../borrowck/borrowck-assign-to-subfield.rs | 24 + .../borrowck-assignment-to-static-mut.rs | 12 + .../borrowck-auto-mut-ref-to-immut-var.rs | 17 + .../ui/borrowck/borrowck-autoref-3261.rs | 25 + .../borrowck-bad-nested-calls-free.rs | 36 + .../borrowck-bad-nested-calls-move.rs | 36 + .../ui/borrowck/borrowck-binding-mutbl.rs | 17 + .../rustc/ui/borrowck/borrowck-block-unint.rs | 8 + .../borrowck-borrow-from-expr-block.rs | 19 + .../borrowck-borrow-from-owned-ptr.rs | 135 + .../borrowck-borrow-from-stack-variable.rs | 132 + .../borrowck-borrow-from-temporary.rs | 15 + ...rrowck-borrow-immut-deref-of-box-as-mut.rs | 15 + ...ck-borrow-mut-base-ptr-in-aliasable-loc.rs | 25 + .../borrowck-borrow-mut-object-twice.rs | 21 + .../borrowck-borrow-of-mut-base-ptr-safe.rs | 22 + .../borrowck-borrow-overloaded-auto-deref.rs | 104 + .../borrowck-borrow-overloaded-deref.rs | 44 + .../borrowck-borrowed-uniq-rvalue-2.rs | 23 + .../borrowck/borrowck-borrowed-uniq-rvalue.rs | 16 + .../ui/borrowck/borrowck-box-sensitivity.rs | 151 + .../ui/borrowck/borrowck-break-uninit-2.rs | 15 + .../ui/borrowck/borrowck-break-uninit.rs | 15 + .../borrowck/borrowck-closures-mut-and-imm.rs | 88 + .../borrowck/borrowck-closures-mut-of-imm.rs | 19 + .../borrowck/borrowck-closures-mut-of-mut.rs | 21 + .../borrowck-closures-slice-patterns-ok.rs | 118 + .../borrowck-closures-slice-patterns.rs | 83 + .../ui/borrowck/borrowck-closures-two-imm.rs | 42 + .../borrowck-closures-two-mut-fail.rs | 60 + .../ui/borrowck/borrowck-closures-two-mut.rs | 56 + .../borrowck/borrowck-closures-unique-imm.rs | 19 + .../ui/borrowck/borrowck-closures-unique.rs | 55 + .../borrowck-closures-use-after-free.rs | 24 + .../borrowck/borrowck-consume-unsize-vec.rs | 13 + .../borrowck/borrowck-consume-upcast-box.rs | 15 + .../ui/borrowck/borrowck-describe-lvalue.rs | 282 + .../ui/borrowck/borrowck-drop-from-guard.rs | 14 + .../borrowck-escaping-closure-error-1.rs | 16 + .../borrowck-escaping-closure-error-2.rs | 16 + .../borrowck-feature-nll-overrides-migrate.rs | 31 + .../borrowck-field-sensitivity-rpass.rs | 267 + .../ui/borrowck/borrowck-field-sensitivity.rs | 117 + .../ui/borrowck/borrowck-fixed-length-vecs.rs | 8 + .../ui/borrowck/borrowck-fn-in-const-a.rs | 13 + .../ui/borrowck/borrowck-fn-in-const-c.rs | 24 + ...rrowck-for-loop-correct-cmt-for-pattern.rs | 25 + .../borrowck-for-loop-head-linkage.rs | 11 + .../ui/borrowck/borrowck-freeze-frozen-mut.rs | 29 + .../rustc/ui/borrowck/borrowck-if-no-else.rs | 7 + .../ui/borrowck/borrowck-if-with-else.rs | 12 + ...k-imm-ref-to-mut-rec-field-issue-3162-c.rs | 11 + .../rustc/ui/borrowck/borrowck-in-static.rs | 13 + .../borrowck-init-in-called-fn-expr.rs | 8 + .../ui/borrowck/borrowck-init-in-fn-expr.rs | 8 + .../rustc/ui/borrowck/borrowck-init-in-fru.rs | 13 + .../ui/borrowck/borrowck-init-op-equal.rs | 9 + .../ui/borrowck/borrowck-init-plus-equal.rs | 9 + .../borrowck/borrowck-insert-during-each.rs | 27 + .../rustc/ui/borrowck/borrowck-issue-14498.rs | 111 + .../ui/borrowck/borrowck-issue-2657-1.rs | 18 + .../ui/borrowck/borrowck-issue-2657-2.rs | 12 + .../rustc/ui/borrowck/borrowck-issue-48962.rs | 27 + .../rustc/ui/borrowck/borrowck-lend-args.rs | 22 + .../ui/borrowck/borrowck-lend-flow-if.rs | 52 + .../ui/borrowck/borrowck-lend-flow-loop.rs | 133 + .../ui/borrowck/borrowck-lend-flow-match.rs | 19 + .../rustc/ui/borrowck/borrowck-lend-flow.rs | 40 + .../borrowck/borrowck-loan-blocks-move-cc.rs | 36 + .../ui/borrowck/borrowck-loan-blocks-move.rs | 20 + .../borrowck/borrowck-loan-blocks-mut-uniq.rs | 19 + .../borrowck-loan-in-overloaded-op.rs | 24 + ...orrowck-loan-of-static-data-issue-27616.rs | 25 + .../borrowck-loan-rcvr-overloaded-op.rs | 47 + .../rustc/ui/borrowck/borrowck-loan-rcvr.rs | 41 + .../ui/borrowck/borrowck-loan-vec-content.rs | 25 + .../borrowck-local-borrow-outlives-fn.rs | 7 + ...wck-local-borrow-with-panic-outlives-fn.rs | 11 + .../ui/borrowck/borrowck-local-borrow.rs | 13 + .../borrowck-macro-interaction-issue-6304.rs | 39 + .../borrowck-match-already-borrowed.rs | 27 + .../borrowck-match-binding-is-assignment.rs | 42 + .../borrowck/borrowck-move-by-capture-ok.rs | 9 + .../ui/borrowck/borrowck-move-by-capture.rs | 12 + .../borrowck/borrowck-move-error-with-note.rs | 55 + ...owck-move-from-subpath-of-borrowed-path.rs | 18 + .../borrowck/borrowck-move-from-unsafe-ptr.rs | 8 + .../borrowck/borrowck-move-in-irrefut-pat.rs | 17 + .../borrowck-move-moved-value-into-closure.rs | 13 + .../ui/borrowck/borrowck-move-mut-base-ptr.rs | 20 + .../borrowck-move-out-from-array-match.rs | 117 + ...ck-move-out-from-array-no-overlap-match.rs | 116 + ...borrowck-move-out-from-array-no-overlap.rs | 68 + .../borrowck-move-out-from-array-use-match.rs | 151 + ...ove-out-from-array-use-no-overlap-match.rs | 116 + ...owck-move-out-from-array-use-no-overlap.rs | 68 + .../borrowck-move-out-from-array-use.rs | 98 + .../borrowck/borrowck-move-out-from-array.rs | 72 + ...rowck-move-out-of-overloaded-auto-deref.rs | 7 + .../borrowck-move-out-of-overloaded-deref.rs | 7 + .../borrowck-move-out-of-static-item.rs | 17 + .../borrowck-move-out-of-struct-with-dtor.rs | 23 + ...owck-move-out-of-tuple-struct-with-dtor.rs | 23 + .../borrowck/borrowck-move-out-of-vec-tail.rs | 34 + .../ui/borrowck/borrowck-move-subcomponent.rs | 18 + ...orrowck-multiple-borrows-interior-boxes.rs | 21 + .../ui/borrowck/borrowck-multiple-captures.rs | 62 + .../borrowck/borrowck-mut-addr-of-imm-var.rs | 7 + .../borrowck-mut-borrow-linear-errors.rs | 16 + .../borrowck-mut-borrow-of-mut-base-ptr.rs | 29 + .../borrowck/borrowck-mut-slice-of-imm-vec.rs | 9 + .../rustc/ui/borrowck/borrowck-mut-uniq.rs | 34 + .../borrowck/borrowck-mut-vec-as-imm-slice.rs | 17 + .../ui/borrowck/borrowck-mutate-in-guard.rs | 22 + .../borrowck-no-cycle-in-exchange-heap.rs | 21 + .../ui/borrowck/borrowck-object-lifetime.rs | 41 + .../rustc/ui/borrowck/borrowck-or-init.rs | 7 + .../ui/borrowck/borrowck-overloaded-call.rs | 81 + ...k-overloaded-index-and-overloaded-deref.rs | 37 + .../borrowck-overloaded-index-autoderef.rs | 98 + ...borrowck-overloaded-index-move-from-vec.rs | 23 + .../borrowck-overloaded-index-move-index.rs | 69 + .../borrowck-overloaded-index-ref-index.rs | 60 + .../ui/borrowck/borrowck-partial-reinit-1.rs | 40 + .../ui/borrowck/borrowck-partial-reinit-2.rs | 24 + .../ui/borrowck/borrowck-partial-reinit-3.rs | 14 + .../ui/borrowck/borrowck-partial-reinit-4.rs | 24 + .../rustc/ui/borrowck/borrowck-pat-enum.rs | 40 + .../borrowck/borrowck-pat-reassign-binding.rs | 16 + .../borrowck-pat-reassign-no-binding.rs | 15 + .../ui/borrowck/borrowck-reborrow-from-mut.rs | 100 + ...owck-reborrow-from-shorter-lived-andmut.rs | 23 + .../ui/borrowck/borrowck-ref-mut-of-imm.rs | 11 + .../rust/rustc/ui/borrowck/borrowck-reinit.rs | 8 + .../borrowck-report-with-custom-diagnostic.rs | 45 + ...owck-return-variable-on-stack-via-clone.rs | 11 + .../rust/rustc/ui/borrowck/borrowck-return.rs | 7 + .../ui/borrowck/borrowck-rvalues-mutable.rs | 35 + .../borrowck-scope-of-deref-issue-4666.rs | 43 + ...e-pattern-element-loan-array-no-overlap.rs | 65 + ...rrowck-slice-pattern-element-loan-array.rs | 59 + ...rrowck-slice-pattern-element-loan-rpass.rs | 22 + ...e-pattern-element-loan-slice-no-overlap.rs | 60 + ...rrowck-slice-pattern-element-loan-slice.rs | 80 + .../ui/borrowck/borrowck-static-item-in-fn.rs | 10 + .../ui/borrowck/borrowck-storage-dead.rs | 25 + .../borrowck-struct-update-with-dtor.rs | 22 + .../ui/borrowck/borrowck-swap-mut-base-ptr.rs | 23 + ...-thread-local-static-borrow-outlives-fn.rs | 10 + .../ui/borrowck/borrowck-trait-lifetime.rs | 19 + .../rustc/ui/borrowck/borrowck-unary-move.rs | 12 + .../ui/borrowck/borrowck-unboxed-closures.rs | 18 + .../ui/borrowck/borrowck-uninit-after-item.rs | 6 + .../borrowck/borrowck-uninit-field-access.rs | 31 + .../borrowck/borrowck-uninit-in-assignop.rs | 35 + .../ui/borrowck/borrowck-uninit-ref-chain.rs | 34 + .../rust/rustc/ui/borrowck/borrowck-uninit.rs | 7 + .../borrowck/borrowck-union-borrow-nested.rs | 32 + .../ui/borrowck/borrowck-union-borrow.rs | 99 + .../ui/borrowck/borrowck-union-move-assign.rs | 33 + .../rustc/ui/borrowck/borrowck-union-move.rs | 87 + .../borrowck/borrowck-union-uninitialized.rs | 19 + .../ui/borrowck/borrowck-uniq-via-lend.rs | 62 + .../ui/borrowck/borrowck-uniq-via-ref.rs | 50 + .../ui/borrowck/borrowck-univariant-enum.rs | 26 + .../borrowck-unsafe-static-mutable-borrows.rs | 21 + .../ui/borrowck/borrowck-unused-mut-locals.rs | 47 + .../borrowck/borrowck-use-in-index-lvalue.rs | 10 + .../borrowck/borrowck-use-mut-borrow-rpass.rs | 52 + .../ui/borrowck/borrowck-use-mut-borrow.rs | 87 + ...orrowck-use-uninitialized-in-cast-trait.rs | 11 + .../borrowck-use-uninitialized-in-cast.rs | 9 + .../borrowck-vec-pattern-element-loan.rs | 32 + .../borrowck-vec-pattern-loan-from-mut.rs | 13 + .../borrowck-vec-pattern-move-tail.rs | 12 + .../borrowck/borrowck-vec-pattern-nesting.rs | 95 + .../borrowck-vec-pattern-tail-element-loan.rs | 15 + .../rustc/ui/borrowck/borrowck-while-break.rs | 13 + .../rustc/ui/borrowck/borrowck-while-cond.rs | 5 + .../rust/rustc/ui/borrowck/borrowck-while.rs | 8 + .../disallow-possibly-uninitialized.rs | 23 + .../rust/rustc/ui/borrowck/immutable-arg.rs | 7 + .../ui/borrowck/index-mut-help-with-impl.rs | 11 + .../rust/rustc/ui/borrowck/index-mut-help.rs | 15 + .../rust/rustc/ui/borrowck/issue-10876.rs | 18 + .../borrowck/issue-27282-mutation-in-guard.rs | 14 + .../ui/borrowck/issue-31287-drop-in-guard.rs | 9 + .../rust/rustc/ui/borrowck/issue-41962.rs | 10 + .../rust/rustc/ui/borrowck/issue-45983.rs | 13 + .../issue-47215-ice-from-drop-elab.rs | 21 + .../rust/rustc/ui/borrowck/issue-51117.rs | 16 + .../issue-51348-multi-ref-mut-in-guard.rs | 22 + .../rust/rustc/ui/borrowck/issue-51415.rs | 12 + .../rust/rustc/ui/borrowck/issue-52713-bug.rs | 18 + ...67-edition-2018-needs-two-phase-borrows.rs | 22 + ...-nested-closure-outlives-borrowed-value.rs | 8 + ...-54499-field-mutation-marks-mut-as-used.rs | 34 + ...99-field-mutation-of-moved-out-with-mut.rs | 37 + ...issue-54499-field-mutation-of-moved-out.rs | 43 + ...ssue-54499-field-mutation-of-never-init.rs | 34 + ...54597-reject-move-out-of-borrow-via-pat.rs | 21 + ...ue-55492-borrowck-migrate-scans-parents.rs | 72 + ...-ascribe-wildcard-to-structured-pattern.rs | 32 + .../issue-58776-borrowck-scans-children.rs | 12 + .../ui/borrowck/issue-62007-assign-box.rs | 28 + .../ui/borrowck/issue-62007-assign-field.rs | 27 + .../borrowck/issue-62107-match-arm-scopes.rs | 13 + .../rust/rustc/ui/borrowck/issue-64453.rs | 24 + .../issue-69789-iterator-mut-suggestion.rs | 12 + .../rust/rustc/ui/borrowck/issue-7573.rs | 42 + .../ui/borrowck/move-error-in-promoted-2.rs | 11 + .../ui/borrowck/move-error-in-promoted.rs | 18 + .../ui/borrowck/move-error-snippets-ext.rs | 8 + .../rustc/ui/borrowck/move-error-snippets.rs | 24 + .../move-from-union-field-issue-66500.rs | 31 + .../rustc/ui/borrowck/move-in-pattern-mut.rs | 24 + .../rust/rustc/ui/borrowck/move-in-pattern.rs | 25 + .../move-in-static-initializer-issue-38520.rs | 17 + .../rustc/ui/borrowck/mut-borrow-in-loop-2.rs | 36 + .../rustc/ui/borrowck/mut-borrow-in-loop.rs | 30 + .../ui/borrowck/mut-borrow-of-mut-ref.rs | 12 + .../ui/borrowck/mut-borrow-outside-loop.rs | 23 + .../rustc/ui/borrowck/mutability-errors.rs | 83 + .../rust/rustc/ui/borrowck/or-patterns.rs | 65 + .../promote-ref-mut-in-let-issue-46557.rs | 32 + .../borrowck/reassignment_immutable_fields.rs | 21 + ...assignment_immutable_fields_overlapping.rs | 17 + .../reassignment_immutable_fields_twice.rs | 18 + .../regions-bound-missing-bound-in-impl.rs | 55 + .../ui/borrowck/regions-escape-bound-fn-2.rs | 14 + .../ui/borrowck/regions-escape-bound-fn.rs | 14 + .../regions-escape-unboxed-closure.rs | 8 + .../return-local-binding-from-desugaring.rs | 34 + .../slice-index-bounds-check-invalidation.rs | 83 + .../ui/borrowck/two-phase-across-loop.rs | 23 + ...o-phase-activation-sharing-interference.rs | 68 + ...o-phase-allow-access-during-reservation.rs | 42 + .../rustc/ui/borrowck/two-phase-baseline.rs | 10 + .../rustc/ui/borrowck/two-phase-bin-ops.rs | 36 + .../two-phase-cannot-nest-mut-self-calls.rs | 22 + ...se-control-flow-split-before-activation.rs | 16 + .../ui/borrowck/two-phase-method-receivers.rs | 18 + .../rustc/ui/borrowck/two-phase-multi-mut.rs | 15 + .../two-phase-multiple-activations.rs | 24 + .../ui/borrowck/two-phase-nonrecv-autoref.rs | 171 + ...hase-reservation-sharing-interference-2.rs | 51 + ...sharing-interference-future-compat-lint.rs | 44 + ...-phase-reservation-sharing-interference.rs | 50 + .../rustc/ui/borrowck/two-phase-sneaky.rs | 18 + .../two-phase-surprise-no-conflict.rs | 168 + ...es-move-upvar-from-non-once-ref-closure.rs | 15 + .../rust/rustc/ui/bound-suggestions.rs | 44 + .../rust/rustc/ui/bounds-lifetime.rs | 8 + .../rust/rustc/ui/box/alloc-unstable-fail.rs | 7 + .../rust/rustc/ui/box/alloc-unstable.rs | 9 + .../rustc/ui/box/into-boxed-slice-fail.rs | 15 + .../rust/rustc/ui/box/into-boxed-slice.rs | 12 + gcc/testsuite/rust/rustc/ui/box/leak-alloc.rs | 30 + gcc/testsuite/rust/rustc/ui/box/new.rs | 7 + .../rust/rustc/ui/break-diverging-value.rs | 38 + .../rust/rustc/ui/break-outside-loop.rs | 36 + .../rust/rustc/ui/break-while-condition.rs | 30 + .../btreemap_into_iterator_lifetime.rs | 24 + .../rust/rustc/ui/bug-7183-generics.rs | 37 + gcc/testsuite/rust/rustc/ui/bug-7295.rs | 15 + .../rust/rustc/ui/builtin-clone-unwind.rs | 62 + gcc/testsuite/rust/rustc/ui/builtin-clone.rs | 46 + ...ltin-superkinds-capabilities-transitive.rs | 26 + .../ui/builtin-superkinds-capabilities-xc.rs | 28 + .../ui/builtin-superkinds-capabilities.rs | 22 + .../ui/builtin-superkinds-in-metadata.rs | 24 + .../ui/builtin-superkinds-phantom-typaram.rs | 19 + .../rustc/ui/builtin-superkinds-simple.rs | 11 + .../rustc/ui/builtin-superkinds-typaram.rs | 12 + .../auxiliary/trait_superkinds_in_metadata.rs | 9 + .../builtin-superkinds-double-superkind.rs | 15 + .../builtin-superkinds-in-metadata.rs | 17 + .../builtin-superkinds-self-type.rs | 18 + .../builtin-superkinds-simple.rs | 10 + .../builtin-superkinds-typaram-not-send.rs | 9 + .../rust/rustc/ui/by-move-pattern-binding.rs | 23 + gcc/testsuite/rust/rustc/ui/byte-literals.rs | 68 + .../rust/rustc/ui/c-stack-returning-int64.rs | 35 + .../rustc/ui/c-variadic/variadic-ffi-1.rs | 31 + .../rustc/ui/c-variadic/variadic-ffi-2.rs | 9 + .../rustc/ui/c-variadic/variadic-ffi-4.rs | 39 + .../rustc/ui/c-variadic/variadic-ffi-6.rs | 14 + .../c-variadic/variadic-ffi-no-fixed-args.rs | 7 + .../rust/rustc/ui/can-begin-expr-check.rs | 21 + gcc/testsuite/rust/rustc/ui/can-copy-pod.rs | 17 + .../cancel-clean-via-immediate-rvalue-ref.rs | 13 + .../ui/cannot-mutate-captured-non-mut-var.rs | 16 + gcc/testsuite/rust/rustc/ui/capture1.rs | 7 + gcc/testsuite/rust/rustc/ui/cast-char.rs | 11 + .../rust/rustc/ui/cast-does-fallback.rs | 13 + .../rust/rustc/ui/cast-region-to-uint.rs | 7 + .../rustc/ui/cast-rfc0401-vtable-kinds.rs | 63 + gcc/testsuite/rust/rustc/ui/cast-rfc0401.rs | 174 + .../rust/rustc/ui/cast-to-infer-ty.rs | 9 + gcc/testsuite/rust/rustc/ui/cast.rs | 22 + .../rust/rustc/ui/cast/cast-as-bool.rs | 10 + .../rustc/ui/cast/cast-errors-issue-43825.rs | 8 + .../rust/rustc/ui/cast/cast-from-nil.rs | 3 + .../rustc/ui/cast/cast-ptr-to-int-const.rs | 12 + .../rust/rustc/ui/cast/cast-rfc0401-2.rs | 9 + .../rust/rustc/ui/cast/cast-to-bare-fn.rs | 11 + .../rust/rustc/ui/cast/cast-to-nil.rs | 3 + ...cast-to-unsized-trait-object-suggestion.rs | 5 + .../rust/rustc/ui/casts-differing-anon.rs | 23 + .../rust/rustc/ui/casts-issue-46365.rs | 8 + .../rust/rustc/ui/catch-unwind-bang.rs | 11 + .../rust/rustc/ui/cenum_impl_drop_cast.rs | 19 + gcc/testsuite/rust/rustc/ui/cfg-rustdoc.rs | 7 + .../ui/cfg/auxiliary/cfg_inner_static.rs | 8 + .../crate-attributes-using-cfg_attr.rs | 7 + .../rust/rustc/ui/cfg/cfg-attr-cfg.rs | 9 + .../rust/rustc/ui/cfg/cfg-attr-crate.rs | 9 + gcc/testsuite/rust/rustc/ui/cfg/cfg-family.rs | 14 + .../rust/rustc/ui/cfg/cfg-in-crate-1.rs | 6 + .../rust/rustc/ui/cfg/cfg-macros-foo.rs | 27 + .../rust/rustc/ui/cfg/cfg-macros-notfoo.rs | 27 + .../rust/rustc/ui/cfg/cfg-match-arm.rs | 21 + .../rust/rustc/ui/cfg/cfg-panic-abort.rs | 17 + gcc/testsuite/rust/rustc/ui/cfg/cfg-panic.rs | 19 + .../rust/rustc/ui/cfg/cfg-target-family.rs | 15 + .../rust/rustc/ui/cfg/cfg-target-vendor.rs | 9 + gcc/testsuite/rust/rustc/ui/cfg/cfg_attr.rs | 51 + .../rust/rustc/ui/cfg/cfg_inner_static.rs | 11 + .../rust/rustc/ui/cfg/cfg_stmt_expr.rs | 93 + .../rust/rustc/ui/cfg/cfgs-on-items.rs | 30 + .../rustc/ui/cfg/conditional-compile-arch.rs | 42 + .../rust/rustc/ui/cfg/conditional-compile.rs | 150 + .../ui/cfg/crate-attributes-using-cfg_attr.rs | 7 + gcc/testsuite/rust/rustc/ui/cfguard-run.rs | 7 + .../rust/rustc/ui/chalkify/arithmetic.rs | 21 + gcc/testsuite/rust/rustc/ui/chalkify/basic.rs | 13 + .../rustc/ui/chalkify/builtin-copy-clone.rs | 45 + .../ui/chalkify/chalk_initial_program.rs | 17 + .../rust/rustc/ui/chalkify/closure.rs | 40 + .../rust/rustc/ui/chalkify/generic_impls.rs | 19 + .../rust/rustc/ui/chalkify/impl_wf.rs | 27 + .../rust/rustc/ui/chalkify/impl_wf_2.rs | 34 + .../rust/rustc/ui/chalkify/inherent_impl.rs | 43 + .../rustc/ui/chalkify/inherent_impl_min.rs | 28 + .../rust/rustc/ui/chalkify/lower_env1.rs | 15 + .../rust/rustc/ui/chalkify/lower_env2.rs | 17 + .../rust/rustc/ui/chalkify/lower_env3.rs | 17 + .../rust/rustc/ui/chalkify/lower_impl.rs | 18 + .../rust/rustc/ui/chalkify/lower_struct.rs | 9 + .../rust/rustc/ui/chalkify/lower_trait.rs | 12 + .../ui/chalkify/lower_trait_higher_rank.rs | 10 + .../ui/chalkify/lower_trait_where_clause.rs | 17 + .../rust/rustc/ui/chalkify/println.rs | 8 + .../rust/rustc/ui/chalkify/projection.rs | 26 + .../recursive_where_clause_on_type.rs | 31 + .../rust/rustc/ui/chalkify/super_trait.rs | 20 + .../rust/rustc/ui/chalkify/trait-objects.rs | 14 + .../rustc/ui/chalkify/trait_implied_bound.rs | 19 + .../rustc/ui/chalkify/type_implied_bound.rs | 30 + .../rust/rustc/ui/chalkify/type_inference.rs | 29 + .../rust/rustc/ui/chalkify/type_wf.rs | 26 + .../rust/rustc/ui/changing-crates.rs | 13 + gcc/testsuite/rust/rustc/ui/char.rs | 14 + gcc/testsuite/rust/rustc/ui/char_unicode.rs | 11 + .../rustc/ui/check-doc-alias-attr-location.rs | 25 + .../rust/rustc/ui/check-doc-alias-attr.rs | 18 + .../ui/check-static-immutable-mut-slices.rs | 7 + .../ui/check-static-recursion-foreign.rs | 24 + .../ui/check-static-values-constraints.rs | 114 + .../rustc/ui/check_const-feature-gated.rs | 8 + .../rust/rustc/ui/child-outlives-parent.rs | 14 + .../rust/rustc/ui/class-cast-to-trait.rs | 55 + .../rust/rustc/ui/class-method-missing.rs | 22 + .../rust/rustc/ui/class-missing-self.rs | 17 + .../rust/rustc/ui/cleanup-arm-conditional.rs | 40 + .../ui/cleanup-rvalue-during-if-and-while.rs | 44 + .../rust/rustc/ui/cleanup-rvalue-for-scope.rs | 64 + .../rust/rustc/ui/cleanup-rvalue-scopes-cf.rs | 36 + .../rust/rustc/ui/cleanup-rvalue-scopes.rs | 132 + ...nup-rvalue-temp-during-incomplete-alloc.rs | 49 + .../rust/rustc/ui/cleanup-shortcircuit.rs | 23 + .../rust/rustc/ui/clone-with-exterior.rs | 23 + .../ui/close-over-big-then-small-data.rs | 42 + .../expect-fn-supply-fn-multiple.rs | 39 + .../expect-fn-supply-fn.rs | 61 + .../expect-infer-var-appearing-twice.rs | 26 + ...t-infer-var-supply-ty-with-bound-region.rs | 20 + ...ct-infer-var-supply-ty-with-free-region.rs | 20 + ...-infer-vars-supply-ty-with-bound-region.rs | 20 + .../ui/closure-expected-type/issue-24421.rs | 11 + .../rust/rustc/ui/closure-expected.rs | 6 + .../ui/closure_context/issue-26046-fn-mut.rs | 12 + .../ui/closure_context/issue-26046-fn-once.rs | 12 + .../rustc/ui/closure_context/issue-42065.rs | 14 + .../rust/rustc/ui/closure_promotion.rs | 8 + .../ui/closures/closure-array-break-length.rs | 8 + ...bounds-cant-promote-superkind-in-struct.rs | 12 + ...ure-bounds-static-cant-capture-borrowed.rs | 13 + .../ui/closures/closure-bounds-subtype.rs | 17 + .../expect-region-supply-region-2.rs | 25 + .../expect-region-supply-region.rs | 58 + .../closure-immutable-outer-variable.rs | 14 + .../rustc/ui/closures/closure-move-sync.rs | 23 + .../rust/rustc/ui/closures/closure-no-fn-1.rs | 9 + .../rust/rustc/ui/closures/closure-no-fn-2.rs | 9 + .../rust/rustc/ui/closures/closure-no-fn-3.rs | 9 + .../closure-referencing-itself-issue-25954.rs | 19 + .../rustc/ui/closures/closure-reform-bad.rs | 13 + .../closures/closure-return-type-mismatch.rs | 18 + .../rustc/ui/closures/closure-wrong-kind.rs | 13 + .../closures/closure_cap_coerce_many_fail.rs | 40 + .../closure_no_cap_coerce_many_check_pass.rs | 167 + .../closure_no_cap_coerce_many_run_pass.rs | 60 + .../closure_no_cap_coerce_many_unsafe_0.rs | 23 + .../closure_no_cap_coerce_many_unsafe_1.rs | 24 + .../ui/closures/deeply-nested_closures.rs | 24 + .../rustc/ui/closures/diverging-closure.rs | 11 + .../rust/rustc/ui/closures/issue-41366.rs | 14 + .../rust/rustc/ui/closures/issue-46742.rs | 10 + .../rust/rustc/ui/closures/issue-48109.rs | 15 + .../rust/rustc/ui/closures/issue-52437.rs | 7 + .../rust/rustc/ui/closures/issue-67123.rs | 6 + .../rust/rustc/ui/closures/issue-68025.rs | 13 + ...issue-72408-nested-closures-exponential.rs | 60 + .../closures/print/closure-print-generic-1.rs | 24 + .../closures/print/closure-print-generic-2.rs | 14 + ...losure-print-generic-trim-off-verbose-2.rs | 17 + .../print/closure-print-generic-verbose-1.rs | 25 + .../print/closure-print-generic-verbose-2.rs | 17 + .../closures/print/closure-print-verbose.rs | 13 + gcc/testsuite/rust/rustc/ui/cmp-default.rs | 74 + .../ui/cmse-nonsecure-entry/gate_test.rs | 12 + .../params-on-registers.rs | 12 + .../cmse-nonsecure-entry/params-on-stack.rs | 11 + .../ui/cmse-nonsecure-entry/trustzone-only.rs | 11 + .../ui/cmse-nonsecure-entry/wrong-abi.rs | 11 + .../rust/rustc/ui/codegen-object-shim.rs | 7 + .../rustc/ui/codemap_tests/bad-format-args.rs | 6 + ...herence-overlapping-inherent-impl-trait.rs | 7 + .../rust/rustc/ui/codemap_tests/empty_span.rs | 9 + .../codemap_tests/huge_multispan_highlight.rs | 92 + .../rustc/ui/codemap_tests/issue-11715.rs | 12 + .../rustc/ui/codemap_tests/issue-28308.rs | 5 + .../rust/rustc/ui/codemap_tests/one_line.rs | 5 + .../overlapping_inherent_impls.rs | 37 + .../rust/rustc/ui/codemap_tests/tab.rs | 10 + .../rust/rustc/ui/codemap_tests/tab_2.rs | 6 + .../rust/rustc/ui/codemap_tests/tab_3.rs | 10 + .../rust/rustc/ui/codemap_tests/two_files.rs | 8 + .../rustc/ui/codemap_tests/two_files_data.rs | 6 + .../rust/rustc/ui/codemap_tests/unicode.rs | 4 + .../rust/rustc/ui/codemap_tests/unicode_2.rs | 8 + .../rust/rustc/ui/codemap_tests/unicode_3.rs | 7 + .../coerce-expect-unsized-ascribed.rs | 33 + .../ui/coercion/coerce-expect-unsized.rs | 45 + .../coercion/coerce-issue-49593-box-never.rs | 52 + .../rust/rustc/ui/coercion/coerce-mut.rs | 11 + .../coerce-overloaded-autoderef-fail.rs | 33 + .../coercion/coerce-overloaded-autoderef.rs | 69 + .../coercion/coerce-reborrow-imm-ptr-arg.rs | 18 + .../coercion/coerce-reborrow-imm-ptr-rcvr.rs | 19 + .../coercion/coerce-reborrow-imm-vec-arg.rs | 20 + .../coercion/coerce-reborrow-imm-vec-rcvr.rs | 17 + .../coerce-reborrow-multi-arg-fail.rs | 7 + .../ui/coercion/coerce-reborrow-multi-arg.rs | 10 + .../coercion/coerce-reborrow-mut-ptr-arg.rs | 26 + .../coercion/coerce-reborrow-mut-ptr-rcvr.rs | 28 + .../coercion/coerce-reborrow-mut-vec-arg.rs | 19 + .../coercion/coerce-reborrow-mut-vec-rcvr.rs | 15 + .../rustc/ui/coercion/coerce-to-bang-cast.rs | 13 + .../rust/rustc/ui/coercion/coerce-to-bang.rs | 80 + .../rustc/ui/coercion/coerce-unify-return.rs | 20 + .../rust/rustc/ui/coercion/coerce-unify.rs | 69 + .../ui/coercion/coerce-unsize-subtype.rs | 41 + .../coercion-missing-tail-expected-type.rs | 17 + .../rust/rustc/ui/coercion/coercion-slice.rs | 8 + .../auxiliary/coherence_copy_like_lib.rs | 11 + .../coherence_fundamental_trait_lib.rs | 8 + .../auxiliary/coherence_inherent_cc_lib.rs | 12 + .../ui/coherence/auxiliary/coherence_lib.rs | 16 + .../auxiliary/coherence_orphan_lib.rs | 4 + .../rustc/ui/coherence/auxiliary/go_trait.rs | 44 + .../re_rebalance_coherence_lib-rpass.rs | 32 + .../auxiliary/re_rebalance_coherence_lib.rs | 23 + .../auxiliary/trait_impl_conflict.rs | 7 + .../ui/coherence/coherence-all-remote.rs | 10 + .../ui/coherence/coherence-bigint-int.rs | 14 + .../ui/coherence/coherence-bigint-param.rs | 12 + .../ui/coherence/coherence-bigint-vecint.rs | 14 + ...nket-conflicts-with-blanket-implemented.rs | 31 + ...et-conflicts-with-blanket-unimplemented.rs | 26 + ...ket-conflicts-with-specific-cross-crate.rs | 21 + ...t-conflicts-with-specific-multidispatch.rs | 28 + ...e-blanket-conflicts-with-specific-trait.rs | 30 + ...herence-blanket-conflicts-with-specific.rs | 25 + .../rustc/ui/coherence/coherence-blanket.rs | 17 + ...herence-conflicting-negative-trait-impl.rs | 18 + .../coherence-covered-type-parameter.rs | 15 + .../rust/rustc/ui/coherence/coherence-cow.rs | 30 + .../coherence-cross-crate-conflict.rs | 16 + .../coherence/coherence-default-trait-impl.rs | 17 + .../coherence/coherence-error-suppression.rs | 17 + .../coherence-fn-covariant-bound-vs-static.rs | 27 + .../coherence/coherence-fn-implied-bounds.rs | 27 + .../rustc/ui/coherence/coherence-fn-inputs.rs | 26 + .../coherence-free-vs-bound-region.rs | 22 + .../coherence-fundamental-trait-objects.rs | 16 + .../ui/coherence/coherence-impl-in-fn.rs | 15 + ...ce-impl-trait-for-marker-trait-negative.rs | 31 + ...ce-impl-trait-for-marker-trait-positive.rs | 31 + ...erence-impl-trait-for-trait-object-safe.rs | 11 + .../coherence-impl-trait-for-trait.rs | 21 + .../ui/coherence/coherence-impls-copy.rs | 39 + .../ui/coherence/coherence-impls-send.rs | 30 + .../ui/coherence/coherence-impls-sized.rs | 37 + .../coherence-inherited-assoc-ty-cycle-err.rs | 25 + .../coherence-inherited-subtyping.rs | 22 + .../coherence-iterator-vec-any-elem.rs | 15 + .../ui/coherence/coherence-iterator-vec.rs | 15 + .../coherence-lone-type-parameter.rs | 11 + .../coherence-multidispatch-tuple.rs | 25 + .../coherence-negative-impls-safe-rpass.rs | 14 + .../coherence-negative-impls-safe.rs | 11 + .../coherence-no-direct-lifetime-dispatch.rs | 10 + .../rustc/ui/coherence/coherence-orphan.rs | 21 + .../coherence-overlap-all-t-and-tuple.rs | 21 + .../coherence-overlap-downstream-inherent.rs | 18 + .../coherence/coherence-overlap-downstream.rs | 18 + .../coherence-overlap-issue-23516-inherent.rs | 14 + .../coherence-overlap-issue-23516.rs | 12 + .../coherence/coherence-overlap-messages.rs | 29 + .../coherence-overlap-upstream-inherent.rs | 17 + .../coherence/coherence-overlap-upstream.rs | 17 + .../coherence/coherence-overlapping-pairs.rs | 12 + .../coherence-pair-covered-uncovered-1.rs | 16 + .../coherence-pair-covered-uncovered.rs | 12 + .../coherence-projection-conflict-orphan.rs | 20 + .../coherence-projection-conflict-ty-param.rs | 14 + .../coherence-projection-conflict.rs | 19 + .../coherence-projection-ok-orphan.rs | 18 + .../ui/coherence/coherence-projection-ok.rs | 18 + .../coherence/coherence-rfc447-constrained.rs | 23 + .../rustc/ui/coherence/coherence-subtyping.rs | 21 + .../ui/coherence/coherence-tuple-conflict.rs | 21 + .../coherence-unsafe-trait-object-impl.rs | 19 + .../ui/coherence/coherence-vec-local-2.rs | 15 + .../rustc/ui/coherence/coherence-vec-local.rs | 15 + .../ui/coherence/coherence-wasm-bindgen.rs | 38 + .../ui/coherence/coherence-where-clause.rs | 39 + .../rustc/ui/coherence/coherence_copy_like.rs | 20 + ...erence_copy_like_err_fundamental_struct.rs | 25 + ...ce_copy_like_err_fundamental_struct_ref.rs | 22 + ..._copy_like_err_fundamental_struct_tuple.rs | 21 + .../coherence_copy_like_err_struct.rs | 23 + .../coherence_copy_like_err_tuple.rs | 22 + .../rustc/ui/coherence/coherence_inherent.rs | 37 + .../ui/coherence/coherence_inherent_cc.rs | 29 + .../rustc/ui/coherence/coherence_local.rs | 21 + .../coherence/coherence_local_err_struct.rs | 19 + .../ui/coherence/coherence_local_err_tuple.rs | 19 + .../rustc/ui/coherence/coherence_local_ref.rs | 15 + .../ui/coherence/conflicting-impl-with-err.rs | 17 + .../ui/coherence/impl-foreign-for-foreign.rs | 16 + .../impl-foreign-for-foreign[foreign].rs | 24 + .../impl-foreign-for-foreign[local].rs | 15 + .../impl-foreign-for-fundamental[foreign].rs | 20 + .../impl-foreign-for-fundamental[local].rs | 16 + .../ui/coherence/impl-foreign-for-local.rs | 14 + ...foreign-for-locally-defined-fundamental.rs | 16 + ...or-locally-defined-fundamental[foreign].rs | 16 + .../impl-foreign[foreign]-for-foreign.rs | 16 + .../impl-foreign[foreign]-for-local.rs | 15 + ...reign[fundemental[foreign]]-for-foreign.rs | 25 + ...foreign[fundemental[local]]-for-foreign.rs | 17 + .../impl[t]-foreign-for-foreign[t].rs | 22 + .../impl[t]-foreign-for-fundamental[t].rs | 16 + ...]-foreign[foreign[t]_local]-for-foreign.rs | 13 + ...[t]-foreign[foreign]-for-fundamental[t].rs | 19 + .../impl[t]-foreign[foreign]-for-t.rs | 15 + ...[t]-foreign[fundamental[t]]-for-foreign.rs | 19 + ...eign[fundamental[t]]-for-fundamental[t].rs | 18 + ...pl[t]-foreign[fundamental[t]]-for-local.rs | 16 + .../impl[t]-foreign[fundamental[t]]-for-t.rs | 18 + ...reign[fundamental[t]_local]-for-foreign.rs | 19 + ...eign[fundemental[local]]-for-foreign[t].rs | 16 + .../impl[t]-foreign[local]-for-foreign.rs | 15 + .../impl[t]-foreign[local]-for-foreign[t].rs | 16 + ...eign[local]-for-fundamental[foreign[t]].rs | 18 + ...pl[t]-foreign[local]-for-fundamental[t].rs | 19 + .../impl[t]-foreign[local]-for-local.rs | 14 + .../coherence/impl[t]-foreign[local]-for-t.rs | 15 + ...reign[local_fundamental[t]]-for-foreign.rs | 18 + .../impl[t]-foreign[t]-for-foreign.rs | 15 + .../impl[t]-foreign[t]-for-fundamental.rs | 19 + .../coherence/impl[t]-foreign[t]-for-local.rs | 14 + .../ui/coherence/impl[t]-foreign[t]-for-t.rs | 15 + ...herence-default-generic-associated-type.rs | 27 + .../ui/coherence/re-rebalance-coherence.rs | 12 + .../rust/rustc/ui/collections-const-new.rs | 21 + .../rust/rustc/ui/command-line-diagnostics.rs | 8 + .../rustc/ui/command/command-argv0-debug.rs | 23 + .../rust/rustc/ui/command/command-argv0.rs | 32 + .../rust/rustc/ui/command/command-exec.rs | 105 + .../rust/rustc/ui/command/command-pre-exec.rs | 119 + .../rust/rustc/ui/command/command-uid-gid.rs | 33 + .../rustc/ui/commandline-argfile-badutf8.rs | 13 + .../rustc/ui/commandline-argfile-missing.rs | 16 + .../rust/rustc/ui/commandline-argfile.rs | 14 + .../ui/compare-method/proj-outlives-region.rs | 15 + .../rustc/ui/compare-method/region-extra-2.rs | 16 + .../rustc/ui/compare-method/region-extra.rs | 15 + .../ui/compare-method/region-unrelated.rs | 16 + .../ui/compare-method/reordered-type-param.rs | 20 + .../trait-bound-on-type-parameter.rs | 19 + .../compare-method/traits-misc-mismatch-1.rs | 72 + .../compare-method/traits-misc-mismatch-2.rs | 24 + .../rust/rustc/ui/compile_error_macro.rs | 4 + gcc/testsuite/rust/rustc/ui/complex.rs | 39 + gcc/testsuite/rust/rustc/ui/concat-rpass.rs | 19 + gcc/testsuite/rust/rustc/ui/concat.rs | 7 + .../auxiliary/namespaced_enums.rs | 11 + .../cfg-arg-invalid-1.rs | 4 + .../cfg-arg-invalid-2.rs | 4 + .../cfg-arg-invalid-3.rs | 4 + .../cfg-arg-invalid-4.rs | 4 + .../cfg-arg-invalid-5.rs | 4 + .../cfg-arg-invalid-6.rs | 4 + .../conditional-compilation/cfg-attr-cfg-2.rs | 10 + .../cfg-attr-crate-2.rs | 9 + .../cfg-attr-empty-is-unused.rs | 14 + .../cfg-attr-invalid-predicate.rs | 5 + .../cfg-attr-multi-false.rs | 20 + .../cfg-attr-multi-invalid-1.rs | 8 + .../cfg-attr-multi-invalid-2.rs | 8 + .../cfg-attr-multi-true.rs | 22 + .../conditional-compilation/cfg-attr-parse.rs | 56 + .../cfg-attr-syntax-validation.rs | 40 + ...-attr-unknown-attribute-macro-expansion.rs | 12 + .../cfg-empty-codemap.rs | 9 + .../cfg-generic-params.rs | 41 + .../conditional-compilation/cfg-in-crate-1.rs | 4 + .../cfg-non-opt-expr.rs | 12 + .../cfg_accessible-input-validation.rs | 25 + .../cfg_accessible-stuck.rs | 10 + .../cfg_accessible-unstable.rs | 3 + .../conditional-compilation/cfg_accessible.rs | 44 + .../conditional-compilation/cfg_attr_path.rs | 14 + .../rust/rustc/ui/conflicting-repr-hints.rs | 70 + .../confuse-field-and-method/issue-18343.rs | 10 + .../ui/confuse-field-and-method/issue-2392.rs | 70 + .../confuse-field-and-method/issue-32128.rs | 16 + .../confuse-field-and-method/issue-33784.rs | 34 + .../confuse-field-and-method/private-field.rs | 20 + .../rust/rustc/ui/conservative_impl_trait.rs | 8 + .../const-generics/apit-with-const-param.rs | 13 + .../rustc/ui/const-generics/argument_order.rs | 23 + .../alloc-traits-impls-length-32.rs | 49 + .../alloc-traits-impls-length-33.rs | 41 + .../alloc-types-impls-length-33.rs | 26 + .../core-traits-impls-length-32.rs | 67 + .../core-traits-impls-length-33.rs | 67 + .../array-impls/into-iter-impls-length-32.rs | 42 + .../array-impls/into-iter-impls-length-33.rs | 42 + .../array-size-in-generic-struct-param.rs | 31 + .../array-wrapper-struct-ctor.rs | 19 + .../associated-type-bound-fail.rs | 18 + .../const-generics/associated-type-bound.rs | 25 + .../auxiliary/const_generic_lib.rs | 12 + .../ui/const-generics/auxiliary/crayte.rs | 20 + .../ui/const-generics/auxiliary/impl-const.rs | 12 + .../rustc/ui/const-generics/broken-mir-1.rs | 20 + .../rustc/ui/const-generics/broken-mir-2.rs | 14 + .../cannot-infer-type-for-const-param.rs | 15 + .../ui/const-generics/closing-args-token.rs | 33 + .../ui/const-generics/coerce_unsized_array.rs | 15 + .../concrete-const-as-fn-arg.rs | 17 + .../concrete-const-impl-method.rs | 27 + .../condition-in-trait-const-arg.rs | 16 + .../const-generics/const-arg-in-const-arg.rs | 45 + .../ui/const-generics/const-arg-in-fn.rs | 16 + .../const-arg-type-arg-misordered.rs | 14 + .../const-argument-cross-crate-mismatch.rs | 12 + .../const-argument-cross-crate.rs | 14 + .../const-argument-if-length.rs | 25 + .../const-argument-non-static-lifetime.rs | 20 + .../const-expression-parameter.rs | 26 + .../const-fn-with-const-param.rs | 16 + .../const-generic-array-wrapper.rs | 21 + .../const-generics/const-generic-type_name.rs | 14 + .../const-param-after-const-literal-arg.rs | 13 + .../const-param-before-other-params.rs | 16 + .../const-param-elided-lifetime.rs | 33 + .../const-param-from-outer-fn.rs | 14 + .../ui/const-generics/const-param-hygiene.rs | 23 + .../ui/const-generics/const-param-in-async.rs | 36 + .../const-param-in-trait-ungated.rs | 4 + .../ui/const-generics/const-param-in-trait.rs | 13 + ...const-param-type-depends-on-const-param.rs | 21 + ...aram-type-depends-on-type-param-ungated.rs | 10 + .../const-param-type-depends-on-type-param.rs | 17 + .../const-parameter-uppercase-lint.rs | 14 + .../rustc/ui/const-generics/const-types.rs | 20 + .../associated-consts.rs | 32 + .../auxiliary/const_evaluatable_lib.rs | 10 + .../const_evaluatable_checked/closures.rs | 7 + .../const_evaluatable_checked/cross_crate.rs | 16 + .../cross_crate_predicate.rs | 15 + .../const_evaluatable_checked/different-fn.rs | 17 + .../const_evaluatable_checked/division.rs | 12 + .../feature-gate-const_evaluatable_checked.rs | 18 + .../const_evaluatable_checked/fn_call.rs | 31 + .../from-sig-fail.rs | 12 + .../const_evaluatable_checked/from-sig.rs | 15 + .../const_evaluatable_checked/impl-bounds.rs | 26 + .../infer-too-generic.rs | 25 + .../const_evaluatable_checked/less_than.rs | 15 + .../const_evaluatable_checked/let-bindings.rs | 16 + .../object-safety-err-ret.rs | 22 + .../object-safety-err-where-bounds.rs | 23 + .../object-safety-ok-infer-err.rs | 23 + .../object-safety-ok.rs | 22 + .../const_evaluatable_checked/simple.rs | 18 + .../const_evaluatable_checked/simple_fail.rs | 17 + .../const_evaluatable_checked/unop.rs | 15 + .../const_evaluatable_checked/unused_expr.rs | 26 + .../rustc/ui/const-generics/core-types.rs | 52 + .../ui/const-generics/cross_crate_complex.rs | 29 + .../defaults/complex-unord-param.rs | 23 + .../defaults/intermixed-lifetime.rs | 17 + .../const-generics/defaults/needs-feature.rs | 18 + .../defaults/simple-defaults.rs | 19 + .../ui/const-generics/defaults/wrong-order.rs | 11 + .../derive-debug-array-wrapper.rs | 15 + .../ui/const-generics/different_byref.rs | 16 + .../const-generics/different_byref_simple.rs | 15 + .../ui/const-generics/dyn-supertraits.rs | 86 + .../ui/const-generics/exhaustive-value.rs | 273 + .../ui/const-generics/fn-const-param-call.rs | 24 + .../ui/const-generics/fn-const-param-infer.rs | 31 + .../fn-taking-const-generic-array.rs | 19 + .../forbid-non-structural_match-types.rs | 19 + .../foreign-item-const-parameter.rs | 14 + .../generic-function-call-in-array-length.rs | 17 + .../const-generics/generic-param-mismatch.rs | 11 + .../generic-sum-in-array-length.rs | 13 + .../impl-const-generic-struct.rs | 19 + .../impl-trait-with-const-arguments.rs | 27 + .../incorrect-number-of-const-args.rs | 15 + .../infer/cannot-infer-const-args.rs | 14 + .../ui/const-generics/infer/issue-77092.rs | 17 + .../ui/const-generics/infer/method-chain.rs | 23 + .../const-generics/infer/uninferred-consts.rs | 17 + .../ui/const-generics/infer_arg_from_pat.rs | 31 + .../const-generics/infer_arr_len_from_pat.rs | 17 + ...ger-literal-generic-arg-in-where-clause.rs | 24 + .../intrinsics-type_name-as-const-argument.rs | 23 + .../invalid-const-arg-for-type-param.rs | 10 + .../invalid-constant-in-args.rs | 4 + .../rustc/ui/const-generics/invalid-enum.rs | 40 + .../issue-61522-array-len-succ.rs | 20 + ...ssue-66596-impl-trait-for-str-const-arg.rs | 21 + .../rustc/ui/const-generics/issue-67375.rs | 16 + .../rustc/ui/const-generics/issue-67945-1.rs | 24 + .../rustc/ui/const-generics/issue-67945-2.rs | 22 + .../rustc/ui/const-generics/issue-67945-3.rs | 18 + .../issue-68104-print-stack-overflow.rs | 17 + .../issue-70180-1-stalled_on.rs | 39 + .../issue-70180-2-stalled_on.rs | 39 + .../rustc/ui/const-generics/issue-71986.rs | 12 + .../rustc/ui/const-generics/issue-74906.rs | 26 + .../auxiliary/const_generic_issues_lib.rs | 17 + .../ui/const-generics/issues/issue-56445.rs | 13 + .../ui/const-generics/issues/issue-60263.rs | 10 + .../issues/issue-60818-struct-constructors.rs | 11 + .../ui/const-generics/issues/issue-61336-1.rs | 14 + .../ui/const-generics/issues/issue-61336-2.rs | 18 + .../ui/const-generics/issues/issue-61336.rs | 18 + .../ui/const-generics/issues/issue-61422.rs | 29 + .../ui/const-generics/issues/issue-61432.rs | 18 + .../ui/const-generics/issues/issue-61747.rs | 18 + .../ui/const-generics/issues/issue-61935.rs | 27 + ...sue-62187-encountered-polymorphic-const.rs | 19 + .../ui/const-generics/issues/issue-62220.rs | 26 + .../ui/const-generics/issues/issue-62456.rs | 13 + .../ui/const-generics/issues/issue-62504.rs | 28 + .../issues/issue-62579-no-match.rs | 18 + .../ui/const-generics/issues/issue-62878.rs | 16 + .../issues/issue-63322-forbid-dyn.rs | 19 + .../ui/const-generics/issues/issue-64494.rs | 25 + .../ui/const-generics/issues/issue-64519.rs | 23 + .../ui/const-generics/issues/issue-66205.rs | 14 + .../ui/const-generics/issues/issue-66906.rs | 14 + .../ui/const-generics/issues/issue-67185-1.rs | 34 + .../ui/const-generics/issues/issue-67185-2.rs | 38 + .../ui/const-generics/issues/issue-67739.rs | 19 + .../ui/const-generics/issues/issue-68366.rs | 22 + .../ui/const-generics/issues/issue-68596.rs | 21 + .../const-generics/issues/issue-68615-adt.rs | 15 + .../issues/issue-68615-array.rs | 15 + .../ui/const-generics/issues/issue-68977.rs | 45 + .../issues/issue-69654-run-pass.rs | 19 + .../ui/const-generics/issues/issue-69654.rs | 19 + .../ui/const-generics/issues/issue-70125-1.rs | 22 + .../ui/const-generics/issues/issue-70125-2.rs | 18 + .../ui/const-generics/issues/issue-70167.rs | 12 + .../ui/const-generics/issues/issue-70225.rs | 22 + .../ui/const-generics/issues/issue-71169.rs | 14 + .../ui/const-generics/issues/issue-71381.rs | 38 + .../ui/const-generics/issues/issue-71382.rs | 27 + .../ui/const-generics/issues/issue-71611.rs | 13 + .../ui/const-generics/issues/issue-72352.rs | 24 + .../ui/const-generics/issues/issue-72787.rs | 41 + .../issue-72819-generic-in-const-eval.rs | 24 + .../ui/const-generics/issues/issue-73120.rs | 10 + .../ui/const-generics/issues/issue-73260.rs | 21 + .../ui/const-generics/issues/issue-73491.rs | 13 + .../ui/const-generics/issues/issue-73508.rs | 10 + .../ui/const-generics/issues/issue-74101.rs | 14 + .../ui/const-generics/issues/issue-74255.rs | 22 + .../ui/const-generics/issues/issue-74634.rs | 28 + .../ui/const-generics/issues/issue-74950.rs | 26 + .../ui/const-generics/issues/issue-75047.rs | 19 + .../ui/const-generics/issues/issue-75299.rs | 12 + .../ui/const-generics/issues/issue-76595.rs | 18 + .../issues/issue-76701-ty-param-in-const.rs | 19 + .../issues/issue70273-assoc-fn.rs | 19 + .../ui/const-generics/macro_rules-braces.rs | 44 + .../const-generics/min-and-full-same-time.rs | 8 + .../min_const_generics/assoc_const.rs | 19 + .../min_const_generics/complex-expression.rs | 50 + .../min_const_generics/complex-types.rs | 29 + .../const-evaluatable-unchecked.rs | 36 + ...uggest-missing-braces-without-turbofish.rs | 50 + ...const-expression-suggest-missing-braces.rs | 56 + .../const_fn_in_generics.rs | 18 + .../default_function_param.rs | 7 + .../min_const_generics/default_trait_param.rs | 7 + .../feature-gate-min_const_generics.rs | 5 + .../forbid-non-static-lifetimes.rs | 28 + .../min_const_generics/invalid-patterns.rs | 46 + .../min_const_generics/macro-fail.rs | 49 + .../min_const_generics/macro.rs | 58 + .../min_const_generics/self-ty-in-const-1.rs | 28 + .../min_const_generics/self-ty-in-const-2.rs | 22 + .../static-reference-array-const-param.rs | 9 + .../transmute-const-param-static-reference.rs | 13 + .../mut-ref-const-param-array.rs | 23 + .../rustc/ui/const-generics/nested-type.rs | 22 + .../const-generics/occurs-check/bind-param.rs | 18 + .../occurs-check/unify-fixpoint.rs | 19 + .../occurs-check/unify-n-nplusone.rs | 18 + .../occurs-check/unused-substs-1.rs | 15 + .../occurs-check/unused-substs-2.rs | 28 + .../occurs-check/unused-substs-3.rs | 19 + .../occurs-check/unused-substs-4.rs | 13 + .../params-in-ct-in-ty-param-lazy-norm.rs | 17 + .../raw-ptr-const-param-deref.rs | 23 + .../ui/const-generics/raw-ptr-const-param.rs | 13 + .../slice-const-param-mismatch.rs | 21 + .../ui/const-generics/slice-const-param.rs | 24 + .../std/const-generics-range.rs | 39 + .../struct-with-invalid-const-param.rs | 11 + .../ui/const-generics/trait-const-args.rs | 33 + .../transparent-maybeunit-array-wrapper.rs | 14 + .../ui/const-generics/type-after-const-ok.rs | 13 + .../auxiliary/type_dependent_lib.rs | 38 + .../type-dependent/const-arg-in-const-arg.rs | 28 + .../type-dependent/issue-61936.rs | 52 + .../type-dependent/issue-63695.rs | 20 + .../type-dependent/issue-67144-1.rs | 31 + .../type-dependent/issue-67144-2.rs | 25 + .../type-dependent/issue-69816.rs | 23 + .../type-dependent/issue-70217.rs | 20 + .../type-dependent/issue-70507.rs | 50 + .../type-dependent/issue-70586.rs | 36 + .../type-dependent/issue-71348.rs | 40 + .../type-dependent/issue-71382.rs | 27 + .../type-dependent/issue-71805.rs | 44 + .../type-dependent/issue-73730.rs | 20 + .../type-dependent/non-local.rs | 27 + .../ui/const-generics/type-dependent/qpath.rs | 15 + .../const-generics/type-dependent/simple.rs | 15 + .../type-dependent/type-mismatch.rs | 15 + .../ui/const-generics/type_of_anon_const.rs | 24 + .../types-mismatch-const-args.rs | 22 + .../uninferred-consts-during-codegen-1.rs | 20 + .../uninferred-consts-during-codegen-2.rs | 20 + .../rustc/ui/const-generics/unknown_adt.rs | 11 + .../ui/const-generics/unused-const-param.rs | 11 + .../rustc/ui/const-generics/unused_braces.rs | 18 + .../rust/rustc/ui/const-generics/wf-misc.rs | 23 + .../rustc/ui/const-generics/where-clauses.rs | 36 + .../rust/rustc/ui/const-suggest-feature.rs | 8 + .../ui/const_evaluatable/associated-const.rs | 12 + .../ui/const_evaluatable/function-call.rs | 20 + .../const_prop/ice-assert-fail-div-by-zero.rs | 13 + .../rust/rustc/ui/const_prop/inline_spans.rs | 15 + .../rustc/ui/constructor-lifetime-args.rs | 27 + .../ui/consts/array-literal-index-oob.rs | 12 + .../rustc/ui/consts/array-to-slice-cast.rs | 14 + .../rust/rustc/ui/consts/ascii_ctype.rs | 54 + .../rust/rustc/ui/consts/assoc-const.rs | 22 + .../ui/consts/assoc_const_generic_impl.rs | 22 + .../ui/consts/associated_const_generic.rs | 26 + .../rust/rustc/ui/consts/async-block.rs | 9 + .../ui/consts/auxiliary/cci_borrow_lib.rs | 4 + .../rustc/ui/consts/auxiliary/cci_const.rs | 7 + .../ui/consts/auxiliary/cci_const_block.rs | 7 + .../rustc/ui/consts/auxiliary/const_fn_lib.rs | 24 + .../ui/consts/auxiliary/external_macro.rs | 15 + .../rustc/ui/consts/auxiliary/issue-63226.rs | 15 + .../auxiliary/promotable_const_fn_lib.rs | 24 + .../rust/rustc/ui/consts/bswap-const.rs | 16 + .../ui/consts/cast-discriminant-zst-enum.rs | 47 + .../consts/chained-constants-stackoverflow.rs | 357 + .../consts/const-address-of-interior-mut.rs | 17 + .../rustc/ui/consts/const-address-of-mut.rs | 15 + .../rust/rustc/ui/consts/const-address-of.rs | 20 + .../ui/consts/const-adt-align-mismatch.rs | 23 + .../rustc/ui/consts/const-array-oob-arith.rs | 17 + .../rust/rustc/ui/consts/const-array-oob.rs | 13 + .../rust/rustc/ui/consts/const-autoderef.rs | 12 + .../rust/rustc/ui/consts/const-big-enum.rs | 31 + .../rust/rustc/ui/consts/const-binops.rs | 127 + .../ui/consts/const-bitshift-rhs-inference.rs | 25 + .../ui/consts/const-block-cross-crate-fn.rs | 10 + .../consts/const-block-item-macro-codegen.rs | 41 + .../rust/rustc/ui/consts/const-block-item.rs | 42 + .../const-block-non-item-statement-3.rs | 9 + .../const-block-non-item-statement-rpass.rs | 12 + .../consts/const-block-non-item-statement.rs | 24 + .../rust/rustc/ui/consts/const-block.rs | 46 + .../rust/rustc/ui/consts/const-bound.rs | 21 + .../rustc/ui/consts/const-byte-str-cast.rs | 10 + .../rust/rustc/ui/consts/const-call.rs | 10 + .../ui/consts/const-cast-different-types.rs | 7 + .../rustc/ui/consts/const-cast-ptr-int.rs | 17 + .../rustc/ui/consts/const-cast-wrong-type.rs | 6 + .../rust/rustc/ui/consts/const-cast.rs | 17 + .../rust/rustc/ui/consts/const-const.rs | 10 + .../rust/rustc/ui/consts/const-contents.rs | 20 + .../ui/consts/const-cross-crate-const.rs | 17 + .../ui/consts/const-cross-crate-extern.rs | 12 + .../rust/rustc/ui/consts/const-deref-ptr.rs | 8 + .../rust/rustc/ui/consts/const-deref.rs | 9 + .../rust/rustc/ui/consts/const-endianess.rs | 22 + .../rustc/ui/consts/const-enum-byref-self.rs | 19 + .../rust/rustc/ui/consts/const-enum-byref.rs | 17 + .../rust/rustc/ui/consts/const-enum-cast.rs | 27 + .../rust/rustc/ui/consts/const-enum-ptr.rs | 13 + .../rust/rustc/ui/consts/const-enum-struct.rs | 13 + .../rustc/ui/consts/const-enum-struct2.rs | 13 + .../rustc/ui/consts/const-enum-structlike.rs | 17 + .../rust/rustc/ui/consts/const-enum-tuple.rs | 12 + .../rust/rustc/ui/consts/const-enum-tuple2.rs | 12 + .../rustc/ui/consts/const-enum-tuplestruct.rs | 13 + .../ui/consts/const-enum-tuplestruct2.rs | 13 + .../rustc/ui/consts/const-enum-vec-index.rs | 31 + .../rustc/ui/consts/const-enum-vec-ptr.rs | 16 + .../rust/rustc/ui/consts/const-enum-vector.rs | 16 + .../rust/rustc/ui/consts/const-err-early.rs | 17 + .../rust/rustc/ui/consts/const-err-multi.rs | 15 + .../rust/rustc/ui/consts/const-err-rpass.rs | 21 + .../rust/rustc/ui/consts/const-err.rs | 19 + .../rust/rustc/ui/consts/const-err2.rs | 40 + .../rust/rustc/ui/consts/const-err4.rs | 15 + .../assign-to-static-within-other-static-2.rs | 20 + .../assign-to-static-within-other-static.rs | 15 + .../consts/const-eval/auxiliary/stability.rs | 12 + .../const-eval/conditional_array_execution.rs | 15 + .../const-eval-intrinsic-promotion.rs | 7 + .../const-eval/const-eval-overflow-2.rs | 21 + .../const-eval/const-eval-overflow-3.rs | 30 + .../const-eval/const-eval-overflow-3b.rs | 29 + .../const-eval/const-eval-overflow-4.rs | 24 + .../const-eval/const-eval-overflow-4b.rs | 30 + .../consts/const-eval/const-eval-overflow2.rs | 74 + .../const-eval/const-eval-overflow2b.rs | 74 + .../const-eval/const-eval-overflow2c.rs | 74 + .../const-eval/const-eval-query-stack.rs | 23 + .../ui/consts/const-eval/const-eval-span.rs | 15 + .../const-pointer-values-in-various-types.rs | 112 + .../ui/consts/const-eval/const_fn_ptr.rs | 38 + .../ui/consts/const-eval/const_fn_ptr_fail.rs | 14 + .../consts/const-eval/const_fn_ptr_fail2.rs | 25 + .../rustc/ui/consts/const-eval/const_let.rs | 30 + .../rustc/ui/consts/const-eval/const_panic.rs | 35 + .../const-eval/const_panic_libcore_bin.rs | 27 + .../ui/consts/const-eval/const_prop_errors.rs | 15 + .../ui/consts/const-eval/const_raw_ptr_ops.rs | 7 + .../consts/const-eval/const_raw_ptr_ops2.rs | 14 + .../ui/consts/const-eval/const_signed_pat.rs | 10 + .../ui/consts/const-eval/const_transmute.rs | 56 + .../rustc/ui/consts/const-eval/dangling.rs | 14 + .../dont_promote_unstable_const_fn.rs | 26 + ...t_promote_unstable_const_fn_cross_crate.rs | 11 + .../ui/consts/const-eval/double_check.rs | 26 + .../ui/consts/const-eval/double_check2.rs | 33 + .../ui/consts/const-eval/double_promotion.rs | 18 + .../consts/const-eval/duration_conversion.rs | 17 + .../rustc/ui/consts/const-eval/enum_discr.rs | 26 + .../ui/consts/const-eval/erroneous-const.rs | 21 + .../consts/const-eval/extern_fat_pointer.rs | 14 + .../const-eval/feature-gate-const_fn_union.rs | 14 + .../const-eval/feature-gate-const_panic.rs | 11 + .../ui/consts/const-eval/generic-slice.rs | 32 + .../const-eval/ice-generic-assoc-const.rs | 17 + .../rustc/ui/consts/const-eval/ice-packed.rs | 22 + .../index-out-of-bounds-never-type.rs | 23 + .../consts/const-eval/index_out_of_bounds.rs | 5 + .../index_out_of_bounds_propagated.rs | 7 + .../ui/consts/const-eval/infinite_loop.rs | 13 + .../rustc/ui/consts/const-eval/issue-43197.rs | 20 + .../rustc/ui/consts/const-eval/issue-44578.rs | 30 + .../rustc/ui/consts/const-eval/issue-47971.rs | 10 + .../rustc/ui/consts/const-eval/issue-49296.rs | 25 + .../rustc/ui/consts/const-eval/issue-50706.rs | 38 + .../ui/consts/const-eval/issue-50814-2.rs | 35 + .../rustc/ui/consts/const-eval/issue-50814.rs | 27 + .../rustc/ui/consts/const-eval/issue-51300.rs | 32 + .../rustc/ui/consts/const-eval/issue-52442.rs | 6 + .../rustc/ui/consts/const-eval/issue-52475.rs | 12 + .../rustc/ui/consts/const-eval/issue-53157.rs | 14 + .../rustc/ui/consts/const-eval/issue-53401.rs | 12 + .../rustc/ui/consts/const-eval/issue-55541.rs | 28 + .../rustc/ui/consts/const-eval/issue-64908.rs | 21 + .../rustc/ui/consts/const-eval/issue-64970.rs | 16 + .../rustc/ui/consts/const-eval/issue-65394.rs | 14 + .../rustc/ui/consts/const-eval/issue-70723.rs | 4 + .../const-eval/issue-70804-fn-subtyping.rs | 11 + .../rustc/ui/consts/const-eval/livedrop.rs | 18 + .../consts/const-eval/match-test-ptr-null.rs | 14 + .../const-eval/mod-static-with-const-fn.rs | 23 + .../no_lint_for_statically_known_error.rs | 19 + .../rust/rustc/ui/consts/const-eval/nrvo.rs | 27 + .../const-eval/panic-assoc-never-type.rs | 19 + .../ui/consts/const-eval/panic-never-type.rs | 15 + .../ui/consts/const-eval/promote-static.rs | 15 + .../promote_mutable_zst_mir_borrowck.rs | 6 + .../const-eval/promoted_const_fn_fail.rs | 25 + .../promoted_const_fn_fail_deny_const_err.rs | 27 + .../ui/consts/const-eval/promoted_errors.rs | 29 + .../consts/const-eval/promoted_raw_ptr_ops.rs | 13 + .../ui/consts/const-eval/pub_const_err.rs | 10 + .../ui/consts/const-eval/pub_const_err_bin.rs | 10 + .../ui/consts/const-eval/ref_to_int_match.rs | 26 + .../ui/consts/const-eval/shift_overflow.rs | 10 + .../consts/const-eval/simd/insert_extract.rs | 58 + .../ui/consts/const-eval/simple_with_undef.rs | 7 + .../rust/rustc/ui/consts/const-eval/strlen.rs | 32 + .../const-eval/transmute-const-promotion.rs | 9 + .../ui/consts/const-eval/transmute-const.rs | 7 + .../rustc/ui/consts/const-eval/ub-enum.rs | 99 + .../ui/consts/const-eval/ub-int-array.rs | 65 + .../rustc/ui/consts/const-eval/ub-nonnull.rs | 50 + .../rust/rustc/ui/consts/const-eval/ub-ref.rs | 39 + .../ui/consts/const-eval/ub-uninhabit.rs | 24 + .../rustc/ui/consts/const-eval/ub-upvars.rs | 12 + .../rustc/ui/consts/const-eval/ub-wide-ptr.rs | 137 + .../const-eval/union-const-eval-field.rs | 38 + .../rustc/ui/consts/const-eval/union-ice.rs | 43 + .../rustc/ui/consts/const-eval/union-ub.rs | 43 + .../ui/consts/const-eval/union_promotion.rs | 14 + .../consts/const-eval/unused-broken-const.rs | 9 + .../ui/consts/const-eval/unwind-abort.rs | 14 + .../rustc/ui/consts/const-eval/valid-const.rs | 19 + .../const-eval/validate_uninhabited_zsts.rs | 25 + .../write-to-uninhabited-enum-variant.rs | 29 + .../ui/consts/const-eval/zst_operand_eval.rs | 6 + .../ui/consts/const-expr-addr-operator.rs | 12 + .../consts/const-expr-in-fixed-length-vec.rs | 13 + .../ui/consts/const-expr-in-vec-repeat.rs | 12 + .../const-extern-fn-call-extern-fn.rs | 24 + .../const-extern-fn-min-const-fn.rs | 14 + .../const-extern-fn-requires-unsafe.rs | 11 + .../consts/const-extern-fn/const-extern-fn.rs | 36 + .../feature-gate-const_extern_fn.rs | 11 + ...nst-extern-fns-dont-need-fn-specifier-2.rs | 8 + ...const-extern-fns-dont-need-fn-specifier.rs | 8 + .../rustc/ui/consts/const-extern-function.rs | 17 + .../consts/const-external-macro-const-err.rs | 14 + .../ui/consts/const-fields-and-indexing.rs | 29 + .../rustc/ui/consts/const-float-bits-conv.rs | 94 + .../rustc/ui/consts/const-float-classify.rs | 78 + .../rustc/ui/consts/const-fn-const-eval.rs | 11 + .../ui/consts/const-fn-destructuring-arg.rs | 8 + .../rustc/ui/consts/const-fn-feature-flags.rs | 14 + .../rust/rustc/ui/consts/const-fn-method.rs | 17 + .../rust/rustc/ui/consts/const-fn-mismatch.rs | 20 + .../rust/rustc/ui/consts/const-fn-nested.rs | 13 + .../rustc/ui/consts/const-fn-not-in-trait.rs | 16 + .../ui/consts/const-fn-not-safe-for-const.rs | 36 + .../ui/consts/const-fn-stability-calls-3.rs | 13 + .../ui/consts/const-fn-stability-calls.rs | 28 + .../rustc/ui/consts/const-fn-type-name-any.rs | 30 + .../rustc/ui/consts/const-fn-type-name.rs | 39 + .../rust/rustc/ui/consts/const-fn-val.rs | 16 + .../rust/rustc/ui/consts/const-fn-zst-args.rs | 15 + .../rust/rustc/ui/consts/const-fn.rs | 43 + .../ui/consts/const-index-feature-gate.rs | 8 + .../consts/const-int-arithmetic-overflow.rs | 27 + .../rustc/ui/consts/const-int-arithmetic.rs | 146 + .../ui/consts/const-int-conversion-rpass.rs | 20 + .../rustc/ui/consts/const-int-conversion.rs | 17 + .../ui/consts/const-int-overflowing-rpass.rs | 48 + .../rustc/ui/consts/const-int-overflowing.rs | 9 + .../rustc/ui/consts/const-int-pow-rpass.rs | 49 + .../rustc/ui/consts/const-int-rotate-rpass.rs | 44 + .../rust/rustc/ui/consts/const-int-rotate.rs | 7 + .../ui/consts/const-int-saturating-arith.rs | 34 + .../rustc/ui/consts/const-int-sign-rpass.rs | 28 + .../rust/rustc/ui/consts/const-int-sign.rs | 7 + .../rustc/ui/consts/const-int-unchecked.rs | 143 + .../ui/consts/const-int-wrapping-rpass.rs | 48 + .../rustc/ui/consts/const-int-wrapping.rs | 13 + .../rustc/ui/consts/const-integer-bool-ops.rs | 76 + .../rustc/ui/consts/const-labeled-break.rs | 12 + .../const-len-underflow-separate-spans.rs | 14 + .../ui/consts/const-len-underflow-subspans.rs | 12 + .../rust/rustc/ui/consts/const-match-check.rs | 34 + .../ui/consts/const-match-pattern-arm.rs | 16 + .../rustc/ui/consts/const-meth-pattern.rs | 19 + .../rust/rustc/ui/consts/const-multi-ref.rs | 25 + .../const-mut-refs/const_mut_address_of.rs | 31 + .../consts/const-mut-refs/const_mut_refs.rs | 38 + .../feature-gate-const_mut_refs.rs | 9 + .../rust/rustc/ui/consts/const-needs_drop.rs | 30 + .../rust/rustc/ui/consts/const-negation.rs | 36 + .../rust/rustc/ui/consts/const-negative.rs | 10 + .../rustc/ui/consts/const-nullary-enum.rs | 24 + .../consts/const-nullary-univariant-enum.rs | 16 + .../ui/consts/const-pattern-irrefutable.rs | 17 + .../const-pattern-not-const-evaluable.rs | 31 + .../rustc/ui/consts/const-pattern-variant.rs | 30 + .../rustc/ui/consts/const-points-to-static.rs | 14 + .../rust/rustc/ui/consts/const-prop-ice.rs | 6 + .../rust/rustc/ui/consts/const-prop-ice2.rs | 8 + .../rust/rustc/ui/consts/const-prop-ice3.rs | 8 + .../ui/consts/const-prop-overflowing-casts.rs | 16 + .../consts/const-prop-read-static-in-const.rs | 11 + .../ui/consts/const-ptr-nonnull-rpass.rs | 18 + .../rust/rustc/ui/consts/const-ptr-nonnull.rs | 12 + .../rustc/ui/consts/const-ptr-unique-rpass.rs | 17 + .../rust/rustc/ui/consts/const-ptr-unique.rs | 11 + .../rust/rustc/ui/consts/const-rec-and-tup.rs | 21 + .../ui/consts/const-region-ptrs-noncopy.rs | 13 + .../rust/rustc/ui/consts/const-region-ptrs.rs | 16 + .../rustc/ui/consts/const-repeated-values.rs | 11 + .../rustc/ui/consts/const-size_of-align_of.rs | 52 + .../rustc/ui/consts/const-size_of-cycle.rs | 8 + ...st-size_of_val-align_of_val-extern-type.rs | 15 + .../consts/const-size_of_val-align_of_val.rs | 46 + .../rust/rustc/ui/consts/const-slice-oob.rs | 11 + .../rust/rustc/ui/consts/const-str-ptr.rs | 18 + .../rustc/ui/consts/const-struct-offsets.rs | 19 + .../rust/rustc/ui/consts/const-struct.rs | 33 + .../rustc/ui/consts/const-trait-to-trait.rs | 25 + .../rustc/ui/consts/const-tup-index-span.rs | 10 + .../rustc/ui/consts/const-tuple-struct.rs | 15 + .../rustc/ui/consts/const-type-mismatch.rs | 12 + .../rustc/ui/consts/const-typeid-of-rpass.rs | 35 + .../rust/rustc/ui/consts/const-unit-struct.rs | 13 + .../rust/rustc/ui/consts/const-unsafe-fn.rs | 22 + .../rust/rustc/ui/consts/const-unsized.rs | 18 + .../rust/rustc/ui/consts/const-unwrap.rs | 15 + .../ui/consts/const-validation-fail-55455.rs | 10 + .../rustc/ui/consts/const-variant-count.rs | 48 + .../rust/rustc/ui/consts/const-vec-of-fns.rs | 26 + .../rust/rustc/ui/consts/const-vec-syntax.rs | 10 + .../rustc/ui/consts/const-vecs-and-slices.rs | 24 + gcc/testsuite/rust/rustc/ui/consts/const.rs | 7 + .../rust/rustc/ui/consts/const_arg_local.rs | 14 + .../rustc/ui/consts/const_arg_promotable.rs | 13 + .../rustc/ui/consts/const_arg_promotable2.rs | 19 + .../rust/rustc/ui/consts/const_arg_wrapper.rs | 13 + .../const_constructor/const-construct-call.rs | 115 + .../const_constructor_qpath.rs | 41 + .../rustc/ui/consts/const_discriminant.rs | 37 + .../const_fn_floating_point_arithmetic.rs | 21 + .../consts/const_fn_return_nested_fn_ptr.rs | 11 + .../rust/rustc/ui/consts/const_forget.rs | 21 + .../const_in_pattern/accept_structural.rs | 67 + .../const_in_pattern/auxiliary/consts.rs | 17 + .../const_in_pattern/cross-crate-fail.rs | 26 + .../const_in_pattern/cross-crate-pass.rs | 24 + .../const_in_pattern/custom-eq-branch-pass.rs | 33 + .../const_in_pattern/custom-eq-branch-warn.rs | 37 + .../ui/consts/const_in_pattern/issue-44333.rs | 26 + .../ui/consts/const_in_pattern/issue-53708.rs | 12 + .../ui/consts/const_in_pattern/issue-62614.rs | 25 + .../ui/consts/const_in_pattern/issue-65466.rs | 22 + .../ui/consts/const_in_pattern/issue-73431.rs | 30 + .../ui/consts/const_in_pattern/issue-78057.rs | 18 + .../const_in_pattern/no-eq-branch-fail.rs | 26 + .../const_in_pattern/reject_non_partial_eq.rs | 33 + .../const_in_pattern/reject_non_structural.rs | 84 + .../const_in_pattern/warn_corner_cases.rs | 42 + .../rust/rustc/ui/consts/const_let_assign.rs | 11 + .../rust/rustc/ui/consts/const_let_assign2.rs | 23 + .../rust/rustc/ui/consts/const_let_assign3.rs | 30 + .../rust/rustc/ui/consts/const_let_eq.rs | 470 + .../rustc/ui/consts/const_let_eq_float.rs | 281 + .../rustc/ui/consts/const_let_irrefutable.rs | 12 + .../rust/rustc/ui/consts/const_let_promote.rs | 18 + .../rustc/ui/consts/const_let_refutable.rs | 7 + .../const_eval_limit_not_reached.rs | 21 + .../const_limit/const_eval_limit_overflow.rs | 16 + .../const_limit/const_eval_limit_reached.rs | 17 + .../feature-gate-const_eval_limit.rs | 15 + .../ui/consts/const_prop_slice_pat_ice.rs | 9 + .../rustc/ui/consts/const_short_circuit.rs | 15 + .../ui/consts/const_unsafe_unreachable.rs | 18 + .../ui/consts/const_unsafe_unreachable_ub.rs | 21 + .../rustc/ui/consts/consts-in-patterns.rs | 29 + .../rustc/ui/consts/control-flow/assert.rs | 15 + .../rustc/ui/consts/control-flow/basics.rs | 86 + .../rustc/ui/consts/control-flow/drop-fail.rs | 63 + .../rustc/ui/consts/control-flow/drop-pass.rs | 47 + .../ui/consts/control-flow/drop-precise.rs | 19 + .../exhaustive-c-like-enum-match.rs | 30 + .../feature-gate-const-if-match.rs | 97 + .../control-flow/interior-mutability.rs | 44 + .../ui/consts/control-flow/issue-46843.rs | 17 + .../ui/consts/control-flow/issue-50577.rs | 7 + .../rust/rustc/ui/consts/control-flow/loop.rs | 90 + .../consts/control-flow/short-circuit-let.rs | 39 + .../ui/consts/control-flow/short-circuit.rs | 15 + .../control-flow/single_variant_match_ice.rs | 26 + .../rust/rustc/ui/consts/control-flow/try.rs | 11 + .../rustc/ui/consts/dangling-alloc-id-ice.rs | 16 + .../rust/rustc/ui/consts/dangling_raw_ptr.rs | 9 + .../rust/rustc/ui/consts/deref_in_pattern.rs | 13 + .../rust/rustc/ui/consts/drop_none.rs | 14 + .../rustc/ui/consts/enum-discr-type-err.rs | 31 + .../rust/rustc/ui/consts/huge-values.rs | 18 + .../rust/rustc/ui/consts/ice-48279.rs | 27 + .../rustc/ui/consts/ice-zst-static-access.rs | 33 + .../rust/rustc/ui/consts/inline_asm.rs | 7 + .../rustc/ui/consts/int_ptr_for_zst_slices.rs | 8 + .../rust/rustc/ui/consts/invalid_promotion.rs | 19 + .../rust/rustc/ui/consts/issue-37550.rs | 13 + .../rust/rustc/ui/consts/issue-51559.rs | 8 + .../rust/rustc/ui/consts/issue-52432.rs | 11 + .../rust/rustc/ui/consts/issue-54224.rs | 13 + .../rust/rustc/ui/consts/issue-56164.rs | 13 + .../rust/rustc/ui/consts/issue-62045.rs | 6 + .../rust/rustc/ui/consts/issue-63226.rs | 13 + .../rust/rustc/ui/consts/issue-63952.rs | 29 + .../rust/rustc/ui/consts/issue-64059.rs | 11 + .../rust/rustc/ui/consts/issue-64506.rs | 21 + .../rust/rustc/ui/consts/issue-64662.rs | 11 + .../rust/rustc/ui/consts/issue-65348.rs | 24 + .../rust/rustc/ui/consts/issue-66342.rs | 13 + .../rust/rustc/ui/consts/issue-66345.rs | 25 + .../rust/rustc/ui/consts/issue-66397.rs | 9 + .../rust/rustc/ui/consts/issue-66787.rs | 40 + .../rust/rustc/ui/consts/issue-67529.rs | 12 + .../rust/rustc/ui/consts/issue-67640.rs | 25 + .../rust/rustc/ui/consts/issue-67641.rs | 25 + .../ui/consts/issue-67696-const-prop-ice.rs | 21 + .../rust/rustc/ui/consts/issue-67862.rs | 19 + .../rustc/ui/consts/issue-68264-overflow.rs | 44 + .../issue-68542-closure-in-array-len.rs | 11 + .../rust/rustc/ui/consts/issue-68684.rs | 16 + ...sue-69191-ice-on-uninhabited-enum-field.rs | 92 + .../issue-69310-array-size-lit-wrong-ty.rs | 12 + .../rust/rustc/ui/consts/issue-69312.rs | 11 + .../consts/issue-70773-mir-typeck-lt-norm.rs | 17 + .../issue-70942-trait-vs-impl-mismatch.rs | 15 + .../ui/consts/issue-73976-monomorphic.rs | 37 + .../ui/consts/issue-73976-polymorphic.rs | 41 + .../ui/consts/issue-77062-large-zst-array.rs | 6 + .../rust/rustc/ui/consts/issue-78655.rs | 11 + .../rust/rustc/ui/consts/issue-broken-mir.rs | 11 + .../rustc/ui/consts/locals-in-const-fn.rs | 36 + .../rustc/ui/consts/match-const-fn-structs.rs | 23 + .../rust/rustc/ui/consts/match_ice.rs | 19 + .../ui/consts/min_const_fn/address_of.rs | 18 + .../consts/min_const_fn/address_of_const.rs | 20 + .../consts/min_const_fn/allow_const_fn_ptr.rs | 15 + .../allow_const_fn_ptr_run_pass.rs | 22 + .../allow_raw_ptr_dereference_const_fn.rs | 12 + .../min_const_fn/bad_const_fn_body_ice.rs | 8 + .../ui/consts/min_const_fn/cast_errors.rs | 18 + .../ui/consts/min_const_fn/cmp_fn_pointers.rs | 9 + .../ui/consts/min_const_fn/min_const_fn.rs | 149 + .../consts/min_const_fn/min_const_fn_dyn.rs | 16 + .../min_const_fn/min_const_fn_fn_ptr.rs | 20 + .../min_const_fn/min_const_fn_impl_trait.rs | 11 + .../min_const_fn/min_const_fn_libstd.rs | 27 + .../min_const_fn_libstd_stability.rs | 42 + .../min_const_fn/min_const_fn_unsafe_bad.rs | 17 + .../min_const_fn/min_const_fn_unsafe_ok.rs | 45 + .../min_const_unsafe_fn_libstd_stability.rs | 43 + .../min_const_unsafe_fn_libstd_stability2.rs | 36 + .../ui/consts/min_const_fn/mutable_borrow.rs | 18 + .../rustc/ui/consts/min_const_fn/promotion.rs | 18 + .../ui/consts/miri_unleashed/abi-mismatch.rs | 20 + .../ui/consts/miri_unleashed/assoc_const.rs | 33 + .../ui/consts/miri_unleashed/assoc_const_2.rs | 31 + .../auxiliary/static_cross_crate.rs | 4 + .../rustc/ui/consts/miri_unleashed/box.rs | 14 + .../miri_unleashed/const_refers_to_static.rs | 32 + .../miri_unleashed/const_refers_to_static2.rs | 26 + .../const_refers_to_static_cross_crate.rs | 82 + .../rustc/ui/consts/miri_unleashed/drop.rs | 19 + ...ure-gate-unleash_the_miri_inside_of_you.rs | 29 + .../ui/consts/miri_unleashed/inline_asm.rs | 23 + .../miri_unleashed/mutable_references.rs | 38 + .../miri_unleashed/mutable_references_err.rs | 38 + .../consts/miri_unleashed/mutating_global.rs | 17 + .../ui/consts/miri_unleashed/non_const_fn.rs | 14 + .../ui/consts/miri_unleashed/ptr_arith.rs | 22 + .../miri_unleashed/raw_mutable_const.rs | 11 + .../ui/consts/miri_unleashed/slice_eq.rs | 18 + .../rustc/ui/consts/miri_unleashed/tls.rs | 25 + .../rust/rustc/ui/consts/mozjs-error.rs | 32 + .../rust/rustc/ui/consts/non-scalar-cast.rs | 10 + gcc/testsuite/rust/rustc/ui/consts/offset.rs | 115 + .../rust/rustc/ui/consts/offset_from.rs | 53 + .../rust/rustc/ui/consts/offset_from_ub.rs | 47 + .../rust/rustc/ui/consts/offset_ub.rs | 26 + .../rust/rustc/ui/consts/packed_pattern.rs | 20 + .../rust/rustc/ui/consts/packed_pattern2.rs | 28 + .../rust/rustc/ui/consts/partial_qualif.rs | 10 + .../rust/rustc/ui/consts/projection_qualif.rs | 17 + .../rust/rustc/ui/consts/promote-not.rs | 36 + .../rustc/ui/consts/promote_borrowed_field.rs | 13 + .../rust/rustc/ui/consts/promote_const_let.rs | 11 + .../promote_evaluation_unused_result.rs | 7 + .../rust/rustc/ui/consts/promote_fn_calls.rs | 12 + .../rustc/ui/consts/promote_fn_calls_std.rs | 29 + .../ui/consts/promoted-validation-55454.rs | 10 + .../rustc/ui/consts/promoted_div_by_zero.rs | 10 + .../rustc/ui/consts/promoted_regression.rs | 10 + .../rustc/ui/consts/promotion-mutable-ref.rs | 18 + .../rust/rustc/ui/consts/promotion.rs | 18 + .../rust/rustc/ui/consts/ptr_comparisons.rs | 79 + .../rust/rustc/ui/consts/ptr_is_null.rs | 17 + .../rust/rustc/ui/consts/qualif_overwrite.rs | 14 + .../rustc/ui/consts/qualif_overwrite_2.rs | 12 + .../rust/rustc/ui/consts/raw-ptr-const.rs | 11 + .../rustc/ui/consts/raw_pointer_promoted.rs | 6 + .../ui/consts/read_from_static_mut_ref.rs | 10 + .../rustc/ui/consts/recursive-zst-static.rs | 15 + .../rust/rustc/ui/consts/references.rs | 28 + .../rust/rustc/ui/consts/repeat_match.rs | 13 + .../rustc/ui/consts/return-in-const-fn.rs | 11 + .../fn-call-in-const.rs | 24 + .../fn-call-in-non-const.rs | 19 + .../migrate-fail.rs | 26 + .../migrate-pass.rs | 129 + .../nll-fail.rs | 25 + .../nll-pass.rs | 128 + .../run-pass.rs | 13 + .../trait-error.rs | 10 + .../rustc/ui/consts/self_normalization.rs | 17 + .../rustc/ui/consts/self_normalization2.rs | 22 + .../rust/rustc/ui/consts/signed_enum_discr.rs | 20 + .../stable-precise-live-drops-in-libcore.rs | 23 + .../rustc/ui/consts/static-cycle-error.rs | 12 + .../ui/consts/static-raw-pointer-interning.rs | 16 + .../consts/static-raw-pointer-interning2.rs | 16 + .../consts/static_mut_containing_mut_ref.rs | 8 + .../consts/static_mut_containing_mut_ref2.rs | 11 + .../consts/static_mut_containing_mut_ref3.rs | 7 + .../rust/rustc/ui/consts/std/alloc.rs | 11 + .../rust/rustc/ui/consts/std/cell.rs | 31 + .../rust/rustc/ui/consts/std/iter.rs | 10 + .../rust/rustc/ui/consts/std/slice.rs | 11 + .../rustc/ui/consts/too_generic_eval_ice.rs | 15 + .../rustc/ui/consts/trait_specialization.rs | 66 + .../rust/rustc/ui/consts/transmute-const.rs | 13 + .../transmute-size-mismatch-before-typeck.rs | 21 + .../ui/consts/tuple-struct-constructors.rs | 11 + .../rustc/ui/consts/underscore_const_names.rs | 32 + .../consts/uninhabited-const-issue-61744.rs | 20 + .../rust/rustc/ui/consts/union_constant.rs | 12 + .../rustc/ui/consts/unsizing-cast-non-null.rs | 11 + .../ui/consts/unstable-const-fn-in-libcore.rs | 30 + .../unstable-precise-live-drops-in-libcore.rs | 24 + .../rust/rustc/ui/consts/unwind-abort.rs | 18 + .../rustc/ui/consts/validate_never_arrays.rs | 10 + .../rust/rustc/ui/consts/zst_no_llvm_alloc.rs | 22 + .../rustc/ui/continue-after-missing-main.rs | 31 + .../rust/rustc/ui/conversion-methods.rs | 14 + .../rust/rustc/ui/copy-a-resource.rs | 22 + .../rust/rustc/ui/core-run-destroy.rs | 89 + gcc/testsuite/rust/rustc/ui/crate-in-paths.rs | 13 + .../rust/rustc/ui/crate-leading-sep.rs | 8 + .../ui/crate-method-reexport-grrrrrrr.rs | 22 + .../rust/rustc/ui/crate-name-attr-used.rs | 9 + .../rust/rustc/ui/crate-name-mismatch.rs | 7 + .../auxiliary/anon_trait_static_method_lib.rs | 10 + .../cross-crate/auxiliary/cci_borrow_lib.rs | 4 + .../auxiliary/cci_capture_clause.rs | 11 + .../ui/cross-crate/auxiliary/cci_const.rs | 7 + .../ui/cross-crate/auxiliary/cci_impl_lib.rs | 17 + .../ui/cross-crate/auxiliary/cci_iter_lib.rs | 12 + .../cross-crate/auxiliary/cci_nested_lib.rs | 53 + .../auxiliary/cci_no_inline_lib.rs | 13 + .../auxiliary/moves_based_on_type_lib.rs | 18 + .../auxiliary/newtype_struct_xc.rs | 4 + .../cross-crate/auxiliary/pub_static_array.rs | 2 + .../auxiliary/reexported_static_methods.rs | 44 + .../auxiliary/xcrate-trait-lifetime-param.rs | 4 + .../auxiliary/xcrate_address_insignificant.rs | 9 + .../xcrate_associated_type_defaults.rs | 13 + .../xcrate_generic_fn_nested_return.rs | 17 + .../auxiliary/xcrate_static_addresses.rs | 18 + .../auxiliary/xcrate_unit_struct.rs | 29 + .../rust/rustc/ui/cross-crate/cci_borrow.rs | 15 + .../ui/cross-crate/cci_capture_clause.rs | 15 + .../rust/rustc/ui/cross-crate/cci_impl_exe.rs | 19 + .../rust/rustc/ui/cross-crate/cci_iter_exe.rs | 14 + .../rustc/ui/cross-crate/cci_nested_exe.rs | 21 + .../rustc/ui/cross-crate/cci_no_inline_exe.rs | 24 + .../ui/cross-crate/cross-crate-const-pat.rs | 15 + .../cross-crate-newtype-struct-pat.rs | 13 + .../issue-64872/auxiliary/a_def_obj.rs | 17 + .../issue-64872/auxiliary/b_reexport_obj.rs | 8 + .../auxiliary/c_another_vtable_for_obj.rs | 13 + .../auxiliary/d_chain_of_rlibs_and_dylibs.rs | 10 + .../ui/cross-crate/issue-64872/issue-64872.rs | 18 + .../moves-based-on-type-cross-crate.rs | 12 + .../reexported-static-methods-cross-crate.rs | 17 + .../cross-crate/static-array-across-crate.rs | 14 + .../xcrate-address-insignificant.rs | 10 + .../xcrate-associated-type-defaults.rs | 30 + .../ui/cross-crate/xcrate-static-addresses.rs | 14 + .../xcrate-trait-lifetime-param.rs | 20 + .../ui/cross-crate/xcrate-unit-struct.rs | 31 + .../xcrate_generic_fn_nested_return.rs | 9 + .../rust/rustc/ui/cross/cross-borrow-trait.rs | 14 + .../auxiliary/extern_macro_crate.rs | 14 + .../cross/cross-crate-macro-backtrace/main.rs | 9 + .../rustc/ui/cross/cross-file-errors/main.rs | 8 + .../ui/cross/cross-file-errors/underscore.rs | 11 + .../rustc/ui/cross/cross-fn-cache-hole.rs | 32 + .../rust/rustc/ui/crt-static-off-works.rs | 11 + .../rust/rustc/ui/crt-static-on-works.rs | 7 + .../rustc/ui/custom-attribute-multisegment.rs | 7 + .../rustc/ui/custom-test-frameworks-simple.rs | 23 + .../rust/rustc/ui/custom_attribute.rs | 10 + .../auxiliary/dynamic_runner.rs | 36 + .../auxiliary/example_runner.rs | 11 + .../ui/custom_test_frameworks/dynamic.rs | 36 + .../rustc/ui/custom_test_frameworks/full.rs | 29 + .../ui/custom_test_frameworks/mismatch.rs | 11 + .../rust/rustc/ui/cycle-generic-bound.rs | 12 + .../cycle-projection-based-on-where-clause.rs | 25 + .../cycle-trait-default-type-trait.rs | 10 + .../cycle-trait-supertrait-direct.rs | 8 + .../cycle-trait-supertrait-indirect.rs | 14 + gcc/testsuite/rust/rustc/ui/debuginfo-lto.rs | 26 + .../rustc/ui/deduplicate-diagnostics-2.rs | 18 + .../rust/rustc/ui/deduplicate-diagnostics.rs | 12 + gcc/testsuite/rust/rustc/ui/deep.rs | 9 + .../rust/rustc/ui/default-alloc-error-hook.rs | 21 + .../rust/rustc/ui/default-associated-types.rs | 24 + .../rust/rustc/ui/default-method-parsing.rs | 9 + .../rust/rustc/ui/default-method-simple.rs | 27 + .../rust/rustc/ui/defaults-well-formedness.rs | 28 + .../auxiliary/field-method-macro.rs | 24 + .../auxiliary/nested-fn-macro.rs | 12 + .../auxiliary/private-use-macro.rs | 12 + .../ui/definition-reachable/field-method.rs | 12 + .../ui/definition-reachable/nested-fn.rs | 12 + .../definition-reachable/private-non-types.rs | 22 + .../ui/definition-reachable/private-types.rs | 20 + .../ui/definition-reachable/private-use.rs | 11 + .../dep-graph/dep-graph-assoc-type-codegen.rs | 38 + .../ui/dep-graph/dep-graph-caller-callee.rs | 36 + .../dep-graph/dep-graph-struct-signature.rs | 87 + ...graph-trait-impl-two-traits-same-method.rs | 46 + .../dep-graph-trait-impl-two-traits.rs | 45 + .../ui/dep-graph/dep-graph-trait-impl.rs | 61 + .../ui/dep-graph/dep-graph-type-alias.rs | 56 + .../ui/dep-graph/dep-graph-variance-alias.rs | 22 + .../rustc/ui/deprecation-in-force-unstable.rs | 6 + .../ui/deprecation/atomic_initializers.rs | 12 + .../deprecation/auxiliary/deprecation-lint.rs | 99 + .../deprecated-macro_escape-inner.rs | 9 + .../ui/deprecation/deprecated-macro_escape.rs | 7 + .../deprecation/deprecated_no_stack_check.rs | 7 + .../ui/deprecation/deprecation-in-future.rs | 14 + .../deprecation/deprecation-in-staged-api.rs | 9 + .../ui/deprecation/deprecation-lint-2.rs | 14 + .../ui/deprecation/deprecation-lint-3.rs | 15 + .../ui/deprecation/deprecation-lint-nested.rs | 72 + .../rustc/ui/deprecation/deprecation-lint.rs | 437 + .../ui/deprecation/deprecation-sanity.rs | 43 + .../ui/deprecation/derive_on_deprecated.rs | 16 + .../derive_on_deprecated_forbidden.rs | 10 + .../rustc/ui/deprecation/invalid-literal.rs | 5 + ...-66340-deprecated-attr-non-meta-grammar.rs | 12 + .../rustc_deprecation-in-future.rs | 16 + .../rust/rustc/ui/deprecation/suggestion.rs | 29 + .../rust/rustc/ui/deref-mut-on-ref.rs | 16 + .../rust/rustc/ui/deref-non-pointer.rs | 6 + gcc/testsuite/rust/rustc/ui/deref-on-ref.rs | 20 + gcc/testsuite/rust/rustc/ui/deref-rc.rs | 9 + .../rust/rustc/ui/deref-suggestion.rs | 49 + gcc/testsuite/rust/rustc/ui/deref.rs | 10 + .../rustc/ui/derive-uninhabited-enum-38885.rs | 20 + .../rustc/ui/derived-errors/issue-30580.rs | 18 + .../rustc/ui/derived-errors/issue-31997-1.rs | 57 + .../rustc/ui/derived-errors/issue-31997.rs | 19 + .../derives/auxiliary/derive-marker-tricky.rs | 16 + .../ui/derives/derive-assoc-type-not-impl.rs | 20 + .../rust/rustc/ui/derives/derive-hygiene.rs | 122 + .../rustc/ui/derives/derive-marker-tricky.rs | 17 + .../derive-on-trait-item-or-impl-item.rs | 16 + .../derives-span-Clone-enum-struct-variant.rs | 14 + .../ui/derives/derives-span-Clone-enum.rs | 14 + .../ui/derives/derives-span-Clone-struct.rs | 12 + .../derives-span-Clone-tuple-struct.rs | 12 + .../derives-span-Debug-enum-struct-variant.rs | 14 + .../ui/derives/derives-span-Debug-enum.rs | 14 + .../ui/derives/derives-span-Debug-struct.rs | 12 + .../derives-span-Debug-tuple-struct.rs | 12 + .../ui/derives/derives-span-Default-struct.rs | 12 + .../derives-span-Default-tuple-struct.rs | 12 + .../derives-span-Eq-enum-struct-variant.rs | 14 + .../rustc/ui/derives/derives-span-Eq-enum.rs | 14 + .../ui/derives/derives-span-Eq-struct.rs | 12 + .../derives/derives-span-Eq-tuple-struct.rs | 12 + .../derives-span-Hash-enum-struct-variant.rs | 14 + .../ui/derives/derives-span-Hash-enum.rs | 13 + .../ui/derives/derives-span-Hash-struct.rs | 12 + .../derives/derives-span-Hash-tuple-struct.rs | 12 + .../derives-span-Ord-enum-struct-variant.rs | 14 + .../rustc/ui/derives/derives-span-Ord-enum.rs | 14 + .../ui/derives/derives-span-Ord-struct.rs | 12 + .../derives/derives-span-Ord-tuple-struct.rs | 12 + ...ives-span-PartialEq-enum-struct-variant.rs | 15 + .../ui/derives/derives-span-PartialEq-enum.rs | 15 + .../derives/derives-span-PartialEq-struct.rs | 13 + .../derives-span-PartialEq-tuple-struct.rs | 13 + ...ves-span-PartialOrd-enum-struct-variant.rs | 18 + .../derives/derives-span-PartialOrd-enum.rs | 18 + .../derives/derives-span-PartialOrd-struct.rs | 16 + .../derives-span-PartialOrd-tuple-struct.rs | 16 + .../rust/rustc/ui/derives/deriving-bounds.rs | 12 + .../rustc/ui/derives/deriving-copyclone.rs | 38 + .../derives/deriving-meta-empty-trait-list.rs | 7 + .../ui/derives/deriving-meta-unknown-trait.rs | 7 + .../deriving-no-inner-impl-error-message.rs | 16 + .../rustc/ui/derives/deriving-non-type.rs | 31 + .../rustc/ui/derives/deriving-primitive.rs | 6 + .../ui/derives/deriving-with-repr-packed.rs | 32 + .../ui/deriving/auxiliary/derive-no-std.rs | 30 + .../rust/rustc/ui/deriving/derive-no-std.rs | 13 + .../deriving/derive-partialord-correctness.rs | 10 + .../ui/deriving/deriving-associated-types.rs | 201 + .../rust/rustc/ui/deriving/deriving-bounds.rs | 6 + .../rustc/ui/deriving/deriving-clone-array.rs | 11 + .../rustc/ui/deriving/deriving-clone-enum.rs | 15 + .../deriving/deriving-clone-generic-enum.rs | 15 + .../deriving/deriving-clone-generic-struct.rs | 14 + .../deriving-clone-generic-tuple-struct.rs | 10 + .../ui/deriving/deriving-clone-struct.rs | 27 + .../deriving/deriving-clone-tuple-struct.rs | 8 + .../ui/deriving/deriving-cmp-generic-enum.rs | 45 + .../deriving-cmp-generic-struct-enum.rs | 49 + .../deriving/deriving-cmp-generic-struct.rs | 41 + .../deriving-cmp-generic-tuple-struct.rs | 39 + .../ui/deriving/deriving-cmp-shortcircuit.rs | 38 + .../rustc/ui/deriving/deriving-copyclone.rs | 39 + .../rustc/ui/deriving/deriving-default-box.rs | 16 + .../deriving/deriving-enum-single-variant.rs | 13 + .../deriving/deriving-eq-ord-boxed-slice.rs | 16 + .../rust/rustc/ui/deriving/deriving-hash.rs | 77 + .../rust/rustc/ui/deriving/deriving-in-fn.rs | 11 + .../rustc/ui/deriving/deriving-in-macro.rs | 17 + .../ui/deriving/deriving-meta-multiple.rs | 27 + .../rust/rustc/ui/deriving/deriving-meta.rs | 24 + ...deriving-self-lifetime-totalord-totaleq.rs | 17 + .../rust/rustc/ui/deriving/deriving-show-2.rs | 55 + .../rust/rustc/ui/deriving/deriving-show.rs | 36 + .../deriving/deriving-via-extension-c-enum.rs | 18 + .../deriving/deriving-via-extension-enum.rs | 17 + .../deriving-via-extension-hash-enum.rs | 18 + .../deriving-via-extension-hash-struct.rs | 13 + .../deriving-via-extension-struct-empty.rs | 9 + ...-via-extension-struct-like-enum-variant.rs | 14 + .../deriving-via-extension-struct-tuple.rs | 18 + .../deriving/deriving-via-extension-struct.rs | 17 + .../deriving-via-extension-type-params.rs | 17 + .../ui/deriving/deriving-with-repr-packed.rs | 37 + .../rustc/ui/dest-prop/skeptic-miscompile.rs | 25 + .../rust/rustc/ui/destructure-trait-ref.rs | 45 + .../default-match-bindings-forbidden.rs | 8 + .../nested_destructure.rs | 18 + .../note-unsupported.rs | 28 + .../slice_destructure.rs | 16 + .../slice_destructure_fail.rs | 8 + .../struct_destructure.rs | 20 + .../struct_destructure_fail.rs | 16 + .../tuple_destructure.rs | 38 + .../tuple_destructure_fail.rs | 11 + .../tuple_struct_destructure.rs | 35 + .../tuple_struct_destructure_fail.rs | 43 + .../underscore-range-expr-gating.rs | 9 + .../warn-unused-duplication.rs | 24 + .../rust/rustc/ui/did_you_mean/E0178.rs | 14 + .../rustc/ui/did_you_mean/bad-assoc-expr.rs | 37 + .../rustc/ui/did_you_mean/bad-assoc-pat.rs | 37 + .../rustc/ui/did_you_mean/bad-assoc-ty.rs | 84 + ...issue-21659-show-relevant-trait-impls-1.rs | 27 + ...issue-21659-show-relevant-trait-impls-2.rs | 31 + .../rust/rustc/ui/did_you_mean/issue-31424.rs | 19 + .../rust/rustc/ui/did_you_mean/issue-34126.rs | 15 + .../rust/rustc/ui/did_you_mean/issue-34337.rs | 8 + .../rust/rustc/ui/did_you_mean/issue-35937.rs | 22 + .../rust/rustc/ui/did_you_mean/issue-36798.rs | 9 + .../did_you_mean/issue-36798_unknown_field.rs | 9 + .../rust/rustc/ui/did_you_mean/issue-37139.rs | 16 + ...ssue-38054-do-not-show-unresolved-names.rs | 6 + .../rustc/ui/did_you_mean/issue-38147-1.rs | 22 + .../rustc/ui/did_you_mean/issue-38147-2.rs | 13 + .../rustc/ui/did_you_mean/issue-38147-3.rs | 13 + .../rustc/ui/did_you_mean/issue-38147-4.rs | 10 + .../rust/rustc/ui/did_you_mean/issue-39544.rs | 51 + .../issue-39802-show-5-trait-impls.rs | 28 + .../rust/rustc/ui/did_you_mean/issue-40006.rs | 40 + .../rust/rustc/ui/did_you_mean/issue-40396.rs | 30 + .../rust/rustc/ui/did_you_mean/issue-40823.rs | 5 + ...ue-41679-tilde-bitwise-negation-attempt.rs | 6 + .../issue-42599_available_fields_note.rs | 38 + .../rust/rustc/ui/did_you_mean/issue-42764.rs | 30 + .../issue-43871-enum-instead-of-variant.rs | 37 + .../issue-46718-struct-pattern-dotdotdot.rs | 18 + ...6836-identifier-not-instead-of-negation.rs | 35 + ...-48492-tuple-destructure-missing-parens.rs | 88 + ...nicode-confusable-in-float-literal-expt.rs | 7 + ...80-expected-float-found-integer-literal.rs | 20 + .../issue-54109-and_instead_of_ampersands.rs | 58 + .../issue-54109-without-witness.rs | 62 + .../issue-56028-there-is-an-enum-variant.rs | 16 + .../rustc/ui/did_you_mean/pub-macro-rules.rs | 17 + .../rustc/ui/did_you_mean/recursion_limit.rs | 36 + .../ui/did_you_mean/recursion_limit_deref.rs | 53 + .../ui/did_you_mean/recursion_limit_macro.rs | 16 + ...ect-reference-without-parens-suggestion.rs | 8 + .../foo/mod_file_not_owning/aux2.rs | 2 + .../foo/mod_file_not_owning_aux2.rs | 2 + .../directory_ownership/macro-expanded-mod.rs | 16 + .../macro_expanded_mod_helper/foo/bar.rs | 2 + .../macro_expanded_mod_helper/foo/mod.rs | 4 + .../mod_file_not_owning_aux1.rs | 7 + .../mod_file_not_owning_aux2.rs | 2 + .../mod_file_not_owning_aux2.rs | 2 + .../mod_file_not_owning_aux3.rs | 4 + .../non-inline-mod-restriction.rs | 6 + ...d-deconstructing-destructing-struct-let.rs | 21 + ...deconstructing-destructing-struct-match.rs | 19 + .../rustc/ui/disambiguate-identical-names.rs | 16 + .../rustc/ui/discrim/discrim-ill-typed.rs | 117 + .../rustc/ui/discrim/discrim-overflow-2.rs | 83 + .../rust/rustc/ui/discrim/discrim-overflow.rs | 102 + .../ui/diverging-fallback-method-chain.rs | 21 + .../rustc/ui/diverging-fallback-option.rs | 15 + .../rust/rustc/ui/diverging-fn-tail-35849.rs | 9 + .../rustc/ui/diverging-tuple-parts-39485.rs | 16 + .../rust/rustc/ui/doc-alias-crate-level.rs | 8 + gcc/testsuite/rust/rustc/ui/does-nothing.rs | 3 + .../dollar-crate/dollar-crate-is-keyword-2.rs | 14 + .../dollar-crate/dollar-crate-is-keyword.rs | 18 + .../ui/dont-suggest-private-trait-method.rs | 7 + gcc/testsuite/rust/rustc/ui/dotdotdot-expr.rs | 5 + gcc/testsuite/rust/rustc/ui/double-import.rs | 16 + gcc/testsuite/rust/rustc/ui/double-ref.rs | 37 + .../rust/rustc/ui/double-type-import.rs | 14 + .../ui/drop-bounds/drop-bounds-impl-drop.rs | 15 + .../rust/rustc/ui/drop-bounds/drop-bounds.rs | 20 + .../auxiliary/dropck_eyepatch_extern_crate.rs | 51 + .../rustc/ui/drop/drop-on-empty-block-exit.rs | 13 + .../rust/rustc/ui/drop/drop-on-ret.rs | 16 + .../rustc/ui/drop/drop-struct-as-object.rs | 39 + .../rust/rustc/ui/drop/drop-trait-enum.rs | 96 + .../rust/rustc/ui/drop/drop-trait-generic.rs | 16 + .../rust/rustc/ui/drop/drop-trait.rs | 16 + .../rustc/ui/drop/drop-uninhabited-enum.rs | 15 + .../ui/drop/drop-with-type-ascription-1.rs | 9 + .../ui/drop/drop-with-type-ascription-2.rs | 9 + .../ui/drop/dropck-eyepatch-extern-crate.rs | 40 + .../rustc/ui/drop/dropck-eyepatch-reorder.rs | 80 + .../rust/rustc/ui/drop/dropck-eyepatch.rs | 103 + .../rust/rustc/ui/drop/dropck_legal_cycles.rs | 1184 ++ .../rust/rustc/ui/drop/dynamic-drop-async.rs | 334 + .../rust/rustc/ui/drop/dynamic-drop.rs | 523 + .../rust/rustc/ui/drop/no-drop-flag-size.rs | 16 + .../rust/rustc/ui/drop/nondrop-cycle.rs | 32 + .../auxiliary/dropck_eyepatch_extern_crate.rs | 38 + .../rustc/ui/dropck/drop-on-non-struct.rs | 16 + .../ui/dropck/drop-with-active-borrows-1.rs | 9 + .../ui/dropck/drop-with-active-borrows-2.rs | 10 + .../ui/dropck/dropck-eyepatch-extern-crate.rs | 83 + .../dropck-eyepatch-implies-unsafe-impl.rs | 36 + .../ui/dropck/dropck-eyepatch-reorder.rs | 101 + .../rust/rustc/ui/dropck/dropck-eyepatch.rs | 124 + .../rust/rustc/ui/dropck/dropck-union.rs | 39 + .../rust/rustc/ui/dropck/dropck_fn_type.rs | 21 + .../dropck_no_diverge_on_nonregular_1.rs | 28 + .../dropck_no_diverge_on_nonregular_2.rs | 27 + .../dropck_no_diverge_on_nonregular_3.rs | 37 + .../ui/dropck/dropck_trait_cycle_checked.rs | 122 + .../rust/rustc/ui/dropck/dropck_traits.rs | 69 + .../rust/rustc/ui/dst/dst-bad-assign-2.rs | 39 + .../rust/rustc/ui/dst/dst-bad-assign-3.rs | 40 + .../rust/rustc/ui/dst/dst-bad-assign.rs | 42 + .../rust/rustc/ui/dst/dst-bad-coerce1.rs | 37 + .../rust/rustc/ui/dst/dst-bad-coerce2.rs | 32 + .../rust/rustc/ui/dst/dst-bad-coerce3.rs | 38 + .../rust/rustc/ui/dst/dst-bad-coerce4.rs | 26 + .../rust/rustc/ui/dst/dst-bad-coercions.rs | 27 + .../rust/rustc/ui/dst/dst-bad-deep-2.rs | 14 + .../rust/rustc/ui/dst/dst-bad-deep.rs | 16 + gcc/testsuite/rust/rustc/ui/dst/dst-index.rs | 38 + .../ui/dst/dst-object-from-unsized-type.rs | 28 + gcc/testsuite/rust/rustc/ui/dst/dst-rvalue.rs | 15 + .../rustc/ui/dst/dst-sized-trait-param.rs | 14 + .../rust/rustc/ui/duplicate/dupe-symbols-1.rs | 15 + .../rust/rustc/ui/duplicate/dupe-symbols-2.rs | 19 + .../rust/rustc/ui/duplicate/dupe-symbols-3.rs | 15 + .../rust/rustc/ui/duplicate/dupe-symbols-4.rs | 25 + .../rust/rustc/ui/duplicate/dupe-symbols-5.rs | 14 + .../rust/rustc/ui/duplicate/dupe-symbols-6.rs | 12 + .../rust/rustc/ui/duplicate/dupe-symbols-7.rs | 13 + .../rust/rustc/ui/duplicate/dupe-symbols-8.rs | 13 + .../duplicate-check-macro-exports.rs | 7 + .../rustc/ui/duplicate/duplicate-parameter.rs | 6 + .../ui/duplicate/duplicate-type-parameter.rs | 30 + .../rust/rustc/ui/duplicate_entry_error.rs | 17 + .../dyn-2015-edition-keyword-ident-lint.rs | 82 + ...dyn-2015-idents-in-decl-macros-unlinted.rs | 52 + .../dyn-2015-idents-in-macros-unlinted.rs | 57 + .../dyn-2015-no-warnings-without-lints.rs | 28 + .../issue-56327-dyn-trait-in-macro-is-okay.rs | 26 + .../rust/rustc/ui/dyn-trait-compatibility.rs | 15 + .../dst-coerce-custom.rs | 44 + .../dynamically-sized-types/dst-coerce-rc.rs | 43 + .../dynamically-sized-types/dst-coercions.rs | 29 + .../dynamically-sized-types/dst-deref-mut.rs | 36 + .../ui/dynamically-sized-types/dst-deref.rs | 31 + .../dst-field-align.rs | 68 + .../ui/dynamically-sized-types/dst-index.rs | 35 + .../dst-irrefutable-bind.rs | 28 + .../ui/dynamically-sized-types/dst-raw.rs | 139 + .../dst-struct-sole.rs | 77 + .../ui/dynamically-sized-types/dst-struct.rs | 123 + .../dst-trait-tuple.rs | 104 + .../ui/dynamically-sized-types/dst-trait.rs | 106 + .../dst-tuple-no-reorder.rs | 27 + .../dynamically-sized-types/dst-tuple-sole.rs | 80 + .../dst-tuple-zst-offsets.rs | 23 + .../ui/dynamically-sized-types/dst-tuple.rs | 121 + .../rust/rustc/ui/early-ret-binop-add.rs | 12 + .../rust/rustc/ui/early-vtbl-resolution.rs | 20 + .../rustc/ui/edition-keywords-2015-2015.rs | 37 + .../rustc/ui/edition-keywords-2015-2018.rs | 37 + .../rustc/ui/edition-keywords-2018-2015.rs | 35 + .../rustc/ui/edition-keywords-2018-2018.rs | 35 + .../rustc/ui/editions/async-block-2015.rs | 31 + .../rustc/ui/editions/auxiliary/absolute.rs | 2 + .../auxiliary/edition-extern-crate-allowed.rs | 2 + .../auxiliary/edition-imports-2015.rs | 32 + .../auxiliary/edition-imports-2018.rs | 18 + .../auxiliary/edition-kw-macro-2015.rs | 29 + .../auxiliary/edition-kw-macro-2018.rs | 29 + .../editions/edition-extern-crate-allowed.rs | 11 + .../rustc/ui/editions/edition-feature-ok.rs | 6 + .../ui/editions/edition-feature-redundant.rs | 8 + .../rustc/ui/editions/edition-imports-2015.rs | 27 + .../rustc/ui/editions/edition-imports-2018.rs | 28 + .../edition-imports-virtual-2015-ambiguity.rs | 21 + .../edition-imports-virtual-2015-gated.rs | 12 + .../edition-keywords-2015-2015-expansion.rs | 18 + .../edition-keywords-2015-2015-parsing.rs | 27 + .../edition-keywords-2015-2018-expansion.rs | 15 + .../edition-keywords-2015-2018-parsing.rs | 27 + .../edition-keywords-2018-2015-expansion.rs | 18 + .../edition-keywords-2018-2015-parsing.rs | 31 + .../edition-keywords-2018-2018-expansion.rs | 15 + .../edition-keywords-2018-2018-parsing.rs | 31 + .../edition-raw-pointer-method-2015.rs | 13 + .../edition-raw-pointer-method-2018.rs | 12 + .../ui/elide-errors-on-mismatched-tuple.rs | 19 + gcc/testsuite/rust/rustc/ui/elided-test.rs | 8 + gcc/testsuite/rust/rustc/ui/else-if.rs | 21 + .../rustc/ui/emit-artifact-notifications.rs | 9 + .../rustc/ui/empty-allocation-non-null.rs | 15 + .../ui/empty-allocation-rvalue-non-null.rs | 9 + .../rustc/ui/empty-type-parameter-list.rs | 25 + .../rustc/ui/empty/auxiliary/empty-struct.rs | 10 + .../rustc/ui/empty/auxiliary/two_macros.rs | 6 + .../rust/rustc/ui/empty/empty-comment.rs | 12 + .../rust/rustc/ui/empty/empty-linkname.rs | 6 + .../rust/rustc/ui/empty/empty-macro-use.rs | 10 + .../rust/rustc/ui/empty/empty-never-array.rs | 18 + .../ui/empty/empty-struct-braces-expr.rs | 30 + .../ui/empty/empty-struct-braces-pat-1.rs | 35 + .../ui/empty/empty-struct-braces-pat-2.rs | 27 + .../ui/empty/empty-struct-braces-pat-3.rs | 33 + .../rustc/ui/empty/empty-struct-tuple-pat.rs | 38 + .../rustc/ui/empty/empty-struct-unit-expr.rs | 22 + .../rustc/ui/empty/empty-struct-unit-pat.rs | 55 + .../rust/rustc/ui/empty_global_asm.rs | 21 + .../rustc/ui/enable-unstable-lib-feature.rs | 14 + .../actually_not_an_enum-discriminant.rs | 50 + .../arbitrary_enum_discriminant-no-repr.rs | 10 + .../arbitrary_enum_discriminant.rs | 57 + .../ui/enum-discriminant/discriminant_size.rs | 55 + .../discriminant_value-wrapper.rs | 17 + .../enum-discriminant/discriminant_value.rs | 82 + ...eature-gate-arbitrary_enum_discriminant.rs | 11 + .../forbidden-discriminant-kind-impl.rs | 15 + .../issue-70453-generics-in-discr-ice-2.rs | 17 + .../issue-70453-generics-in-discr-ice.rs | 18 + .../issue-70453-polymorphic-ctfe.rs | 19 + .../issue-70509-partial_eq.rs | 19 + .../rust/rustc/ui/enum-discriminant/niche.rs | 112 + .../rustc/ui/enum-discriminant/repr128.rs | 46 + .../ui/enum/enum-and-module-in-same-scope.rs | 11 + .../rustc/ui/enum/enum-discrim-autosizing.rs | 12 + .../rustc/ui/enum/enum-discrim-too-small.rs | 39 + .../rustc/ui/enum/enum-discrim-too-small2.rs | 38 + .../rust/rustc/ui/enum/enum-in-scope.rs | 8 + .../rust/rustc/ui/enum/enum-size-variance.rs | 36 + .../rustc/ui/enum/enum-to-float-cast-2.rs | 19 + .../rust/rustc/ui/enum/enum-to-float-cast.rs | 22 + .../rust/rustc/ui/enum/enum-variant-type-2.rs | 10 + .../rust/rustc/ui/enum/issue-67945-1.rs | 9 + .../rust/rustc/ui/enum/issue-67945-2.rs | 10 + .../rust/rustc/ui/enum/nested-enum.rs | 9 + .../rust/rustc/ui/enum/union-in-enum.rs | 14 + .../rust/rustc/ui/enums-pats-not-idents.rs | 4 + .../rustc/ui/env-args-reverse-iterator.rs | 40 + gcc/testsuite/rust/rustc/ui/env-funky-keys.rs | 44 + gcc/testsuite/rust/rustc/ui/env-home-dir.rs | 52 + gcc/testsuite/rust/rustc/ui/env-null-vars.rs | 24 + gcc/testsuite/rust/rustc/ui/env-vars.rs | 14 + .../rust/rustc/ui/epoch-gate-feature.rs | 16 + .../rust/rustc/ui/eprint-on-tls-drop.rs | 50 + .../rust/rustc/ui/eq-multidispatch.rs | 31 + .../rust/rustc/ui/error-codes/E0001.rs | 11 + .../rust/rustc/ui/error-codes/E0004-2.rs | 6 + .../rust/rustc/ui/error-codes/E0004.rs | 13 + .../rust/rustc/ui/error-codes/E0005.rs | 5 + .../rust/rustc/ui/error-codes/E0010-teach.rs | 9 + .../rust/rustc/ui/error-codes/E0010.rs | 7 + .../rust/rustc/ui/error-codes/E0017.rs | 14 + .../rust/rustc/ui/error-codes/E0023.rs | 18 + .../rust/rustc/ui/error-codes/E0025.rs | 11 + .../rust/rustc/ui/error-codes/E0026-teach.rs | 15 + .../rust/rustc/ui/error-codes/E0026.rs | 13 + .../rust/rustc/ui/error-codes/E0027.rs | 16 + .../rust/rustc/ui/error-codes/E0029-teach.rs | 12 + .../rust/rustc/ui/error-codes/E0029.rs | 10 + .../rust/rustc/ui/error-codes/E0030-teach.rs | 10 + .../rust/rustc/ui/error-codes/E0030.rs | 8 + .../rust/rustc/ui/error-codes/E0033-teach.rs | 15 + .../rust/rustc/ui/error-codes/E0033.rs | 13 + .../rust/rustc/ui/error-codes/E0034.rs | 22 + .../rust/rustc/ui/error-codes/E0038.rs | 12 + .../rust/rustc/ui/error-codes/E0040.rs | 16 + .../rust/rustc/ui/error-codes/E0044.rs | 10 + .../rust/rustc/ui/error-codes/E0045.rs | 5 + .../rust/rustc/ui/error-codes/E0049.rs | 23 + .../rust/rustc/ui/error-codes/E0050.rs | 17 + .../rust/rustc/ui/error-codes/E0054.rs | 5 + .../rust/rustc/ui/error-codes/E0055.rs | 14 + .../rust/rustc/ui/error-codes/E0057.rs | 7 + .../rust/rustc/ui/error-codes/E0059.rs | 7 + .../rust/rustc/ui/error-codes/E0060.rs | 10 + .../rust/rustc/ui/error-codes/E0061.rs | 14 + .../rust/rustc/ui/error-codes/E0062.rs | 12 + .../rust/rustc/ui/error-codes/E0063.rs | 41 + .../rust/rustc/ui/error-codes/E0067.rs | 7 + .../rust/rustc/ui/error-codes/E0069.rs | 8 + .../rust/rustc/ui/error-codes/E0070.rs | 14 + .../rust/rustc/ui/error-codes/E0071.rs | 8 + .../rust/rustc/ui/error-codes/E0075.rs | 8 + .../rust/rustc/ui/error-codes/E0076.rs | 9 + .../rust/rustc/ui/error-codes/E0077.rs | 8 + .../rust/rustc/ui/error-codes/E0080.rs | 9 + .../rust/rustc/ui/error-codes/E0081.rs | 10 + .../rust/rustc/ui/error-codes/E0084.rs | 6 + .../rust/rustc/ui/error-codes/E0091.rs | 6 + .../rust/rustc/ui/error-codes/E0092.rs | 8 + .../rust/rustc/ui/error-codes/E0093.rs | 9 + .../rust/rustc/ui/error-codes/E0094.rs | 8 + .../rust/rustc/ui/error-codes/E0106.rs | 27 + .../rust/rustc/ui/error-codes/E0107.rs | 24 + .../rust/rustc/ui/error-codes/E0109.rs | 5 + .../rust/rustc/ui/error-codes/E0110.rs | 4 + .../rust/rustc/ui/error-codes/E0116.rs | 6 + .../rust/rustc/ui/error-codes/E0117.rs | 6 + .../rust/rustc/ui/error-codes/E0118-2.rs | 9 + .../rust/rustc/ui/error-codes/E0118.rs | 9 + .../rust/rustc/ui/error-codes/E0119.rs | 19 + .../rust/rustc/ui/error-codes/E0120.rs | 10 + .../rust/rustc/ui/error-codes/E0121.rs | 7 + .../rust/rustc/ui/error-codes/E0124.rs | 9 + .../rust/rustc/ui/error-codes/E0128.rs | 8 + .../rust/rustc/ui/error-codes/E0130.rs | 8 + .../rust/rustc/ui/error-codes/E0131.rs | 4 + .../rust/rustc/ui/error-codes/E0132.rs | 8 + .../rust/rustc/ui/error-codes/E0133.rs | 7 + .../rust/rustc/ui/error-codes/E0137.rs | 9 + .../rust/rustc/ui/error-codes/E0138.rs | 9 + .../rust/rustc/ui/error-codes/E0152.rs | 9 + .../rust/rustc/ui/error-codes/E0161.rs | 28 + .../rust/rustc/ui/error-codes/E0164.rs | 15 + .../rust/rustc/ui/error-codes/E0184.rs | 11 + .../rust/rustc/ui/error-codes/E0185.rs | 16 + .../rust/rustc/ui/error-codes/E0186.rs | 14 + .../rust/rustc/ui/error-codes/E0191.rs | 8 + .../rust/rustc/ui/error-codes/E0194.rs | 9 + .../rust/rustc/ui/error-codes/E0195.rs | 16 + .../rust/rustc/ui/error-codes/E0197.rs | 7 + .../rust/rustc/ui/error-codes/E0198.rs | 9 + .../rust/rustc/ui/error-codes/E0199.rs | 10 + .../rust/rustc/ui/error-codes/E0200.rs | 9 + .../rust/rustc/ui/error-codes/E0201.rs | 23 + .../rust/rustc/ui/error-codes/E0206.rs | 15 + .../rust/rustc/ui/error-codes/E0207.rs | 11 + .../rust/rustc/ui/error-codes/E0214.rs | 5 + .../rust/rustc/ui/error-codes/E0220.rs | 9 + .../rust/rustc/ui/error-codes/E0221.rs | 28 + .../rust/rustc/ui/error-codes/E0223.rs | 7 + .../rust/rustc/ui/error-codes/E0225.rs | 11 + .../rust/rustc/ui/error-codes/E0229.rs | 18 + .../rust/rustc/ui/error-codes/E0252.rs | 16 + .../rust/rustc/ui/error-codes/E0253.rs | 11 + .../rust/rustc/ui/error-codes/E0254.rs | 15 + .../rust/rustc/ui/error-codes/E0255.rs | 10 + .../rust/rustc/ui/error-codes/E0259.rs | 9 + .../rust/rustc/ui/error-codes/E0260.rs | 11 + .../rust/rustc/ui/error-codes/E0261.rs | 10 + .../rust/rustc/ui/error-codes/E0262.rs | 5 + .../rust/rustc/ui/error-codes/E0263.rs | 6 + .../rust/rustc/ui/error-codes/E0264.rs | 9 + .../rust/rustc/ui/error-codes/E0267.rs | 4 + .../rust/rustc/ui/error-codes/E0268.rs | 4 + .../rust/rustc/ui/error-codes/E0271.rs | 12 + .../rust/rustc/ui/error-codes/E0275.rs | 9 + .../rust/rustc/ui/error-codes/E0276.rs | 11 + .../rust/rustc/ui/error-codes/E0277-2.rs | 19 + .../rust/rustc/ui/error-codes/E0277.rs | 20 + .../rust/rustc/ui/error-codes/E0282.rs | 4 + .../rust/rustc/ui/error-codes/E0283.rs | 20 + .../rust/rustc/ui/error-codes/E0297.rs | 7 + .../rust/rustc/ui/error-codes/E0308-2.rs | 13 + .../rust/rustc/ui/error-codes/E0308-4.rs | 8 + .../rust/rustc/ui/error-codes/E0308.rs | 9 + .../rust/rustc/ui/error-codes/E0328.rs | 11 + .../rust/rustc/ui/error-codes/E0365.rs | 9 + .../rust/rustc/ui/error-codes/E0370.rs | 11 + .../rust/rustc/ui/error-codes/E0374.rs | 12 + .../rust/rustc/ui/error-codes/E0375.rs | 14 + .../rust/rustc/ui/error-codes/E0376.rs | 11 + .../rust/rustc/ui/error-codes/E0388.rs | 13 + .../rust/rustc/ui/error-codes/E0389.rs | 11 + .../rust/rustc/ui/error-codes/E0390.rs | 9 + .../rust/rustc/ui/error-codes/E0392.rs | 5 + .../rust/rustc/ui/error-codes/E0393.rs | 8 + .../rust/rustc/ui/error-codes/E0395.rs | 9 + .../rust/rustc/ui/error-codes/E0396-fixed.rs | 10 + .../rust/rustc/ui/error-codes/E0396.rs | 10 + .../rust/rustc/ui/error-codes/E0401.rs | 31 + .../rust/rustc/ui/error-codes/E0403.rs | 5 + .../rust/rustc/ui/error-codes/E0404.rs | 9 + .../rust/rustc/ui/error-codes/E0405.rs | 7 + .../rust/rustc/ui/error-codes/E0407.rs | 15 + .../rust/rustc/ui/error-codes/E0408.rs | 9 + .../rust/rustc/ui/error-codes/E0411.rs | 4 + .../rust/rustc/ui/error-codes/E0412.rs | 5 + .../rust/rustc/ui/error-codes/E0415.rs | 5 + .../rust/rustc/ui/error-codes/E0416.rs | 6 + .../rust/rustc/ui/error-codes/E0423.rs | 23 + .../rust/rustc/ui/error-codes/E0424.rs | 22 + .../rust/rustc/ui/error-codes/E0425.rs | 9 + .../rust/rustc/ui/error-codes/E0426.rs | 7 + .../rust/rustc/ui/error-codes/E0428.rs | 6 + .../rust/rustc/ui/error-codes/E0429.rs | 5 + .../rust/rustc/ui/error-codes/E0430.rs | 6 + .../rust/rustc/ui/error-codes/E0431.rs | 5 + .../rust/rustc/ui/error-codes/E0432.rs | 5 + .../rust/rustc/ui/error-codes/E0433.rs | 4 + .../rust/rustc/ui/error-codes/E0434.rs | 10 + .../rust/rustc/ui/error-codes/E0435.rs | 5 + .../rust/rustc/ui/error-codes/E0437.rs | 9 + .../rust/rustc/ui/error-codes/E0438.rs | 9 + .../rust/rustc/ui/error-codes/E0439.rs | 9 + .../rust/rustc/ui/error-codes/E0445.rs | 13 + .../rust/rustc/ui/error-codes/E0446.rs | 10 + .../rust/rustc/ui/error-codes/E0449.rs | 15 + .../rust/rustc/ui/error-codes/E0451.rs | 20 + .../rust/rustc/ui/error-codes/E0452.rs | 9 + .../rust/rustc/ui/error-codes/E0453.rs | 9 + .../rust/rustc/ui/error-codes/E0454.rs | 6 + .../rust/rustc/ui/error-codes/E0458.rs | 6 + .../rust/rustc/ui/error-codes/E0459.rs | 5 + .../rust/rustc/ui/error-codes/E0463.rs | 8 + .../rust/rustc/ui/error-codes/E0478.rs | 9 + .../rust/rustc/ui/error-codes/E0490.rs | 9 + .../rust/rustc/ui/error-codes/E0492.rs | 8 + .../rust/rustc/ui/error-codes/E0496.rs | 12 + .../rust/rustc/ui/error-codes/E0499.rs | 11 + .../rust/rustc/ui/error-codes/E0501.rs | 25 + .../rust/rustc/ui/error-codes/E0502.rs | 13 + .../rust/rustc/ui/error-codes/E0503.rs | 10 + .../rust/rustc/ui/error-codes/E0504.rs | 16 + .../rust/rustc/ui/error-codes/E0505.rs | 16 + .../rust/rustc/ui/error-codes/E0506.rs | 12 + .../rust/rustc/ui/error-codes/E0507.rs | 14 + .../rust/rustc/ui/error-codes/E0508-fail.rs | 7 + .../rust/rustc/ui/error-codes/E0508.rs | 7 + .../rust/rustc/ui/error-codes/E0509.rs | 19 + .../rust/rustc/ui/error-codes/E0511.rs | 12 + .../rust/rustc/ui/error-codes/E0512.rs | 6 + .../rust/rustc/ui/error-codes/E0516.rs | 5 + .../rust/rustc/ui/error-codes/E0517.rs | 16 + .../rust/rustc/ui/error-codes/E0518.rs | 10 + .../rust/rustc/ui/error-codes/E0520.rs | 23 + .../rust/rustc/ui/error-codes/E0522.rs | 10 + .../rust/rustc/ui/error-codes/E0527.rs | 10 + .../rust/rustc/ui/error-codes/E0528.rs | 9 + .../rust/rustc/ui/error-codes/E0529.rs | 9 + .../rust/rustc/ui/error-codes/E0530.rs | 9 + .../rust/rustc/ui/error-codes/E0532.rs | 15 + .../rust/rustc/ui/error-codes/E0534.rs | 7 + .../rust/rustc/ui/error-codes/E0559.rs | 9 + .../rust/rustc/ui/error-codes/E0560.rs | 9 + .../rust/rustc/ui/error-codes/E0565-1.rs | 6 + .../rust/rustc/ui/error-codes/E0565-2.rs | 6 + .../rust/rustc/ui/error-codes/E0565.rs | 7 + .../rust/rustc/ui/error-codes/E0572.rs | 4 + .../rust/rustc/ui/error-codes/E0582.rs | 43 + .../rust/rustc/ui/error-codes/E0583.rs | 5 + .../rust/rustc/ui/error-codes/E0585.rs | 5 + .../rust/rustc/ui/error-codes/E0586.rs | 5 + .../rust/rustc/ui/error-codes/E0594.rs | 6 + .../rust/rustc/ui/error-codes/E0596.rs | 5 + .../rust/rustc/ui/error-codes/E0597.rs | 13 + .../rust/rustc/ui/error-codes/E0599.rs | 6 + .../rust/rustc/ui/error-codes/E0600.rs | 4 + .../rust/rustc/ui/error-codes/E0601.rs | 2 + .../rust/rustc/ui/error-codes/E0602.rs | 7 + .../rust/rustc/ui/error-codes/E0603.rs | 8 + .../rust/rustc/ui/error-codes/E0604.rs | 4 + .../rust/rustc/ui/error-codes/E0605.rs | 8 + .../rust/rustc/ui/error-codes/E0606.rs | 4 + .../rust/rustc/ui/error-codes/E0607.rs | 5 + .../rust/rustc/ui/error-codes/E0608.rs | 4 + .../rust/rustc/ui/error-codes/E0609.rs | 13 + .../rust/rustc/ui/error-codes/E0610.rs | 5 + .../rust/rustc/ui/error-codes/E0614.rs | 5 + .../rust/rustc/ui/error-codes/E0615.rs | 13 + .../rust/rustc/ui/error-codes/E0616.rs | 15 + .../rust/rustc/ui/error-codes/E0617.rs | 27 + .../rust/rustc/ui/error-codes/E0618.rs | 12 + .../rust/rustc/ui/error-codes/E0620.rs | 4 + .../E0621-does-not-trigger-for-closures.rs | 17 + .../rust/rustc/ui/error-codes/E0622.rs | 7 + .../rust/rustc/ui/error-codes/E0624.rs | 13 + .../rust/rustc/ui/error-codes/E0637.rs | 10 + .../rust/rustc/ui/error-codes/E0642.rs | 21 + .../rust/rustc/ui/error-codes/E0646.rs | 2 + .../rust/rustc/ui/error-codes/E0647.rs | 10 + .../rust/rustc/ui/error-codes/E0648.rs | 5 + .../rust/rustc/ui/error-codes/E0657.rs | 27 + .../rust/rustc/ui/error-codes/E0658.rs | 7 + .../rust/rustc/ui/error-codes/E0659.rs | 17 + .../rust/rustc/ui/error-codes/E0660.rs | 10 + .../rust/rustc/ui/error-codes/E0661.rs | 10 + .../rust/rustc/ui/error-codes/E0662.rs | 11 + .../rust/rustc/ui/error-codes/E0663.rs | 11 + .../rust/rustc/ui/error-codes/E0664.rs | 12 + .../rust/rustc/ui/error-codes/E0665.rs | 9 + .../rust/rustc/ui/error-codes/E0705.rs | 11 + .../rust/rustc/ui/error-codes/E0718.rs | 8 + .../rust/rustc/ui/error-codes/E0719.rs | 15 + .../rust/rustc/ui/error-codes/E0730.rs | 12 + .../rust/rustc/ui/error-codes/E0746.rs | 19 + .../rust/rustc/ui/error-codes/E0767.rs | 8 + .../rust/rustc/ui/error-codes/E0771.rs | 9 + .../rust/rustc/ui/error-codes/E0777.rs | 8 + .../rust/rustc/ui/error-codes/E0778.rs | 9 + .../rust/rustc/ui/error-codes/E0779.rs | 7 + .../e0119/auxiliary/complex_impl_support.rs | 23 + .../e0119/auxiliary/issue-23563-a.rs | 26 + .../ui/error-codes/e0119/complex-impl.rs | 13 + .../ui/error-codes/e0119/conflict-with-std.rs | 27 + .../rustc/ui/error-codes/e0119/issue-23563.rs | 30 + .../rustc/ui/error-codes/e0119/issue-27403.rs | 12 + .../rustc/ui/error-codes/e0119/issue-28981.rs | 9 + .../rustc/ui/error-codes/e0119/so-37347311.rs | 18 + .../rust/rustc/ui/error-codes/ex-E0611.rs | 13 + .../rust/rustc/ui/error-codes/ex-E0612.rs | 7 + gcc/testsuite/rust/rustc/ui/error-festival.rs | 44 + .../rustc/ui/error-should-say-copy-not-pod.rs | 8 + gcc/testsuite/rust/rustc/ui/estr-subtyping.rs | 16 + gcc/testsuite/rust/rustc/ui/estr-uniq.rs | 16 + gcc/testsuite/rust/rustc/ui/eval-enum.rs | 11 + .../rust/rustc/ui/exclusive-drop-and-copy.rs | 18 + gcc/testsuite/rust/rustc/ui/exec-env.rs | 12 + gcc/testsuite/rust/rustc/ui/expanded-cfg.rs | 22 + gcc/testsuite/rust/rustc/ui/explain.rs | 3 + .../rust/rustc/ui/explicit-i-suffix.rs | 15 + .../ui/explicit/explicit-call-to-dtor.rs | 15 + .../explicit-call-to-supertrait-dtor.rs | 24 + .../explicit-self-lifetime-mismatch.rs | 21 + .../rust/rustc/ui/explore-issue-38412.rs | 67 + .../rust/rustc/ui/export-fully-qualified.rs | 14 + .../rustc/ui/export-glob-imports-target.rs | 23 + gcc/testsuite/rust/rustc/ui/export-import.rs | 12 + gcc/testsuite/rust/rustc/ui/export-multi.rs | 13 + .../rust/rustc/ui/export-non-interference2.rs | 12 + .../rust/rustc/ui/export-non-interference3.rs | 12 + .../rust/rustc/ui/export-tag-variant.rs | 8 + gcc/testsuite/rust/rustc/ui/export.rs | 11 + gcc/testsuite/rust/rustc/ui/export2.rs | 12 + gcc/testsuite/rust/rustc/ui/expr-block-fn.rs | 10 + .../rustc/ui/expr-block-generic-unique1.rs | 20 + .../rustc/ui/expr-block-generic-unique2.rs | 16 + .../rust/rustc/ui/expr-block-generic.rs | 28 + .../rust/rustc/ui/expr-block-slot.rs | 14 + .../rust/rustc/ui/expr-block-unique.rs | 6 + gcc/testsuite/rust/rustc/ui/expr-block.rs | 19 + gcc/testsuite/rust/rustc/ui/expr-copy.rs | 19 + gcc/testsuite/rust/rustc/ui/expr-empty-ret.rs | 16 + gcc/testsuite/rust/rustc/ui/expr-fn.rs | 63 + .../rust/rustc/ui/expr-if-generic.rs | 30 + .../rust/rustc/ui/expr-if-panic-all.rs | 12 + gcc/testsuite/rust/rustc/ui/expr-if-panic.rs | 19 + gcc/testsuite/rust/rustc/ui/expr-if-unique.rs | 12 + gcc/testsuite/rust/rustc/ui/expr-if.rs | 53 + gcc/testsuite/rust/rustc/ui/expr-scope.rs | 8 + .../rust/rustc/ui/expr_attr_paren_order.rs | 25 + .../rust/rustc/ui/ext-expand-inner-exprs.rs | 8 + .../rust/rustc/ui/ext-nonexistent.rs | 3 + .../rust/rustc/ui/extend-for-unit.rs | 13 + .../extenv/extenv-arg-2-not-string-literal.rs | 2 + .../rust/rustc/ui/extenv/extenv-no-args.rs | 2 + .../ui/extenv/extenv-not-defined-custom.rs | 2 + .../ui/extenv/extenv-not-defined-default.rs | 5 + .../ui/extenv/extenv-not-string-literal.rs | 2 + .../rustc/ui/extenv/extenv-too-many-args.rs | 2 + .../rust/rustc/ui/extenv/issue-55897.rs | 21 + .../rustc/ui/extern-flag/auxiliary/somedep.rs | 4 + .../rustc/ui/extern-flag/multiple-opts.rs | 21 + .../ui/extern-flag/noprelude-and-prelude.rs | 11 + .../ui/extern-flag/noprelude-resolves.rs | 12 + .../rust/rustc/ui/extern-flag/noprelude.rs | 8 + .../ui/extern-flag/public-and-private.rs | 14 + .../rust/rustc/ui/extern-prelude-fail.rs | 10 + gcc/testsuite/rust/rustc/ui/extern-prelude.rs | 32 + .../ui/extern/auxiliary/extern-take-value.rs | 6 + .../auxiliary/extern-types-inherent-impl.rs | 10 + .../auxiliary/extern_calling_convention.rs | 27 + .../auxiliary/extern_mod_ordering_lib.rs | 6 + .../rustc/ui/extern/auxiliary/fat_drop.rs | 14 + .../rust/rustc/ui/extern/auxiliary/m1.rs | 2 + .../rust/rustc/ui/extern/auxiliary/m2.rs | 2 + .../rust/rustc/ui/extern/extern-1.rs | 10 + .../extern/extern-calling-convention-test.rs | 13 + .../extern/extern-compare-with-return-type.rs | 26 + .../rust/rustc/ui/extern/extern-const.rs | 27 + .../rustc/ui/extern/extern-crate-rename.rs | 9 + .../ui/extern/extern-crate-visibility.rs | 25 + .../ui/extern/extern-ffi-fn-with-body.rs | 12 + .../rustc/ui/extern/extern-foreign-crate.rs | 7 + .../rust/rustc/ui/extern/extern-macro.rs | 7 + .../rust/rustc/ui/extern/extern-main-fn.rs | 2 + .../rust/rustc/ui/extern/extern-methods.rs | 32 + .../rust/rustc/ui/extern/extern-mod-abi.rs | 10 + .../ui/extern/extern-mod-ordering-exe.rs | 13 + .../rustc/ui/extern/extern-prelude-core.rs | 19 + .../extern/extern-prelude-no-speculative.rs | 14 + .../rustc/ui/extern/extern-prelude-std.rs | 13 + .../rust/rustc/ui/extern/extern-pub.rs | 10 + .../rust/rustc/ui/extern/extern-rust.rs | 13 + .../rust/rustc/ui/extern/extern-take-value.rs | 14 + .../rust/rustc/ui/extern/extern-thiscall.rs | 28 + .../ui/extern/extern-types-distinct-types.rs | 13 + .../ui/extern/extern-types-inherent-impl.rs | 27 + .../extern/extern-types-manual-sync-send.rs | 20 + .../ui/extern/extern-types-not-sync-send.rs | 19 + .../ui/extern/extern-types-pointer-cast.rs | 33 + .../ui/extern/extern-types-size_of_val.rs | 18 + .../ui/extern/extern-types-thin-pointer.rs | 44 + .../ui/extern/extern-types-trait-impl.rs | 28 + .../rustc/ui/extern/extern-types-unsized.rs | 34 + .../rust/rustc/ui/extern/extern-vectorcall.rs | 28 + .../ui/extern/extern-with-type-bounds.rs | 21 + .../ui/extern/extern-wrong-value-type.rs | 12 + .../rust/rustc/ui/extern/extern_fat_drop.rs | 14 + .../rustc/ui/extern/external-doc-error.rs | 32 + .../issue-36122-accessing-externed-dst.rs | 7 + ...llow-unwind-when-calling-panic-directly.rs | 65 + ...sue-64655-extern-rust-must-allow-unwind.rs | 84 + .../rust/rustc/ui/extoption_env-no-args.rs | 2 + .../rustc/ui/extoption_env-not-defined.rs | 6 + .../ui/extoption_env-not-string-literal.rs | 2 + .../rustc/ui/extoption_env-too-many-args.rs | 2 + gcc/testsuite/rust/rustc/ui/fact.rs | 27 + gcc/testsuite/rust/rustc/ui/fail-simple.rs | 4 + gcc/testsuite/rust/rustc/ui/fat-lto.rs | 8 + .../rust/rustc/ui/fat-ptr-cast-rpass.rs | 42 + gcc/testsuite/rust/rustc/ui/fat-ptr-cast.rs | 25 + .../rust/rustc/ui/fds-are-cloexec.rs | 84 + .../rustc/ui/feature-gate-inline_const.rs | 7 + .../rustc/ui/feature-gate-isa_attribute.rs | 7 + .../ui/feature-gate-optimize_attribute.rs | 19 + .../ui/feature-gate/allow-features-empty.rs | 9 + .../rustc/ui/feature-gate/allow-features.rs | 9 + .../ui/feature-gate/duplicate-features.rs | 10 + .../feature-gate/feature-gate-c_variadic.rs | 5 + .../feature-gate-static-nobundle-2.rs | 7 + .../issue-43106-gating-of-bench.rs | 11 + ...sue-43106-gating-of-builtin-attrs-error.rs | 147 + .../issue-43106-gating-of-builtin-attrs.rs | 824 ++ .../issue-43106-gating-of-deprecated.rs | 13 + .../issue-43106-gating-of-derive-2.rs | 21 + .../issue-43106-gating-of-derive.rs | 33 + .../issue-43106-gating-of-macro_escape.rs | 12 + .../issue-43106-gating-of-macro_use.rs | 26 + ...issue-43106-gating-of-proc_macro_derive.rs | 35 + .../issue-43106-gating-of-rustc_deprecated.rs | 31 + .../issue-43106-gating-of-stable.rs | 31 + .../issue-43106-gating-of-test.rs | 7 + .../issue-43106-gating-of-unstable.rs | 31 + .../feature-gate/issue-49983-see-issue-0.rs | 7 + .../rustc/ui/feature-gate/rustc-private.rs | 6 + .../stability-attribute-consistency.rs | 17 + .../rustc/ui/feature-gate/unknown-feature.rs | 4 + .../unstable-attribute-allow-issue-0.rs | 14 + .../ui/feature-gated-feature-in-macro-arg.rs | 15 + .../auxiliary/cfg-target-thread-local.rs | 8 + .../ui/feature-gates/auxiliary/pub_dep.rs | 2 + .../auxiliary/re_rebalance_coherence_lib.rs | 23 + .../rust/rustc/ui/feature-gates/bench.rs | 10 + .../feature-gate-abi-avr-interrupt.rs | 10 + .../feature-gate-abi-msp430-interrupt.rs | 12 + .../ui/feature-gates/feature-gate-abi.rs | 110 + .../feature-gate-abi_unadjusted.rs | 8 + .../feature-gate-alloc-error-handler.rs | 15 + .../feature-gate-allocator_internals.rs | 4 + ...gate-allow-internal-unsafe-nested-macro.rs | 18 + ...te-allow-internal-unstable-nested-macro.rs | 18 + ...ure-gate-allow-internal-unstable-struct.rs | 9 + .../feature-gate-allow-internal-unstable.rs | 9 + .../feature-gates/feature-gate-allow_fail.rs | 9 + .../feature-gate-arbitrary-self-types.rs | 30 + ...e-gate-arbitrary_self_types-raw-pointer.rs | 19 + .../ui/feature-gates/feature-gate-asm.rs | 11 + .../ui/feature-gates/feature-gate-asm2.rs | 11 + .../feature-gate-assoc-type-defaults.rs | 8 + .../feature-gate-associated_type_bounds.rs | 77 + .../ui/feature-gates/feature-gate-box-expr.rs | 15 + .../feature-gate-box_patterns.rs | 5 + .../feature-gates/feature-gate-box_syntax.rs | 7 + .../feature-gates/feature-gate-cfg-panic.rs | 12 + .../feature-gate-cfg-target-has-atomic.rs | 119 + .../feature-gate-cfg-target-thread-local.rs | 18 + .../feature-gates/feature-gate-cfg-version.rs | 42 + .../feature-gate-cfg_sanitize.rs | 4 + .../feature-gate-compiler-builtins.rs | 4 + .../feature-gate-concat_idents.rs | 10 + .../feature-gate-concat_idents2.rs | 5 + .../feature-gate-concat_idents3.rs | 8 + .../feature-gate-const-indexing.rs | 9 + .../ui/feature-gates/feature-gate-const_fn.rs | 38 + .../feature-gate-const_fn_transmute.rs | 39 + .../feature-gate-const_generics-ptr.rs | 10 + .../feature-gate-const_generics.rs | 6 + ...-gate-const_in_array_repeat_expressions.rs | 18 + .../feature-gate-crate_visibility_modifier.rs | 9 + .../feature-gate-custom_attribute.rs | 19 + .../feature-gate-custom_attribute2.rs | 59 + .../feature-gate-custom_test_frameworks.rs | 7 + .../feature-gates/feature-gate-decl_macro.rs | 6 + ...re-gate-default_type_parameter_fallback.rs | 13 + .../feature-gate-destructuring_assignment.rs | 5 + .../ui/feature-gates/feature-gate-doc_cfg.rs | 3 + .../feature-gates/feature-gate-doc_keyword.rs | 6 + .../feature-gates/feature-gate-doc_masked.rs | 5 + .../feature-gate-doc_spotlight.rs | 5 + .../feature-gate-exclusive-range-pattern.rs | 7 + .../feature-gate-exhaustive-patterns.rs | 10 + .../feature-gate-extern_absolute_paths.rs | 6 + .../feature-gate-extern_prelude.rs | 2 + .../feature-gate-extern_types.rs | 6 + .../feature-gate-external_doc.rs | 4 + .../feature-gate-feature-gate.rs | 5 + .../feature-gates/feature-gate-ffi_const.rs | 7 + .../ui/feature-gates/feature-gate-ffi_pure.rs | 7 + .../feature-gate-ffi_returns_twice.rs | 7 + .../feature-gate-format_args_nl.rs | 4 + .../feature-gates/feature-gate-fundamental.rs | 5 + .../feature-gates/feature-gate-generators.rs | 11 + .../feature-gate-generic_associated_types.rs | 32 + .../feature-gates/feature-gate-global_asm.rs | 4 + .../feature-gate-impl_trait_in_bindings.rs | 12 + .../feature-gate-in_band_lifetimes.rs | 63 + ...gate-infer_static_outlives_requirements.rs | 13 + .../feature-gates/feature-gate-intrinsics.rs | 9 + .../feature-gates/feature-gate-is_sorted.rs | 14 + .../feature-gate-label_break_value.rs | 6 + .../feature-gates/feature-gate-lang-items.rs | 6 + .../feature-gates/feature-gate-link_args.rs | 19 + .../ui/feature-gates/feature-gate-link_cfg.rs | 6 + .../feature-gate-link_llvm_intrinsics.rs | 9 + .../ui/feature-gates/feature-gate-linkage.rs | 7 + .../feature-gate-lint-reasons.rs | 7 + .../feature-gates/feature-gate-log_syntax.rs | 4 + .../feature-gates/feature-gate-log_syntax2.rs | 4 + .../ui/feature-gates/feature-gate-main.rs | 3 + .../feature-gate-marker_trait_attr.rs | 10 + .../feature-gates/feature-gate-may-dangle.rs | 12 + .../feature-gate-member-constraints.rs | 11 + .../feature-gate-min_const_fn.rs | 38 + .../feature-gate-naked_functions.rs | 12 + .../feature-gate-needs-allocator.rs | 4 + .../feature-gate-negate-unsigned.rs | 19 + .../feature-gates/feature-gate-never_type.rs | 18 + .../ui/feature-gates/feature-gate-nll.rs | 19 + .../ui/feature-gates/feature-gate-no_core.rs | 6 + .../feature-gates/feature-gate-no_sanitize.rs | 5 + .../feature-gate-non_ascii_idents.rs | 34 + .../feature-gate-object_safe_for_dispatch.rs | 42 + ...re-gate-omit-gdb-pretty-printer-section.rs | 3 + .../feature-gate-optin-builtin-traits.rs | 13 + .../feature-gate-overlapping_marker_traits.rs | 10 + .../feature-gate-plugin_registrar.rs | 12 + ...ture-gate-precise_pointer_size_matching.rs | 15 + .../feature-gate-prelude_import.rs | 5 + .../feature-gate-profiler-runtime.rs | 4 + ...eature-gate-public_private_dependencies.rs | 21 + .../feature-gate-register_attr.rs | 4 + .../feature-gate-register_tool.rs | 4 + .../feature-gates/feature-gate-repr-simd.rs | 10 + .../ui/feature-gates/feature-gate-repr128.rs | 7 + ...ture-gate-rustc-allow-const-fn-unstable.rs | 7 + .../feature-gate-rustc-attrs-1.rs | 10 + .../feature-gates/feature-gate-rustc-attrs.rs | 24 + .../feature-gate-rustc_const_unstable.rs | 10 + .../ui/feature-gates/feature-gate-simd-ffi.rs | 14 + .../ui/feature-gates/feature-gate-simd.rs | 12 + .../feature-gates/feature-gate-staged_api.rs | 15 + .../ui/feature-gates/feature-gate-start.rs | 4 + .../feature-gate-static-nobundle.rs | 6 + .../feature-gate-stmt_expr_attributes.rs | 5 + .../feature-gate-thread_local.rs | 12 + .../feature-gate-trace_macros.rs | 4 + .../feature-gates/feature-gate-trait-alias.rs | 5 + .../feature-gate-transparent_unions.rs | 8 + .../feature-gate-trivial_bounds-lint.rs | 9 + .../feature-gate-trivial_bounds.rs | 70 + .../feature-gates/feature-gate-try_blocks.rs | 10 + .../feature-gates/feature-gate-try_reserve.rs | 5 + .../feature-gate-type_alias_impl_trait.rs | 51 + .../feature-gate-type_ascription.rs | 6 + ...ture-gate-unboxed-closures-manual-impls.rs | 38 + ...ture-gate-unboxed-closures-method-calls.rs | 10 + ...eature-gate-unboxed-closures-ufcs-calls.rs | 10 + .../feature-gate-unboxed-closures.rs | 19 + .../feature-gate-unsafe_block_in_unsafe_fn.rs | 7 + .../feature-gate-unsized_fn_params.rs | 27 + .../feature-gate-unsized_locals.rs | 6 + .../feature-gate-unsized_tuple_coercion.rs | 5 + .../feature-gate-untagged_unions.rs | 36 + .../feature-gate-unwind-attributes.rs | 20 + gcc/testsuite/rust/rustc/ui/ffi_const.rs | 6 + gcc/testsuite/rust/rustc/ui/ffi_const2.rs | 12 + gcc/testsuite/rust/rustc/ui/ffi_pure.rs | 6 + .../rust/rustc/ui/ffi_returns_twice.rs | 6 + .../rust/rustc/ui/filter-block-view-items.rs | 9 + .../rust/rustc/ui/fixup-deref-mut.rs | 51 + .../float-literal-inference-restrictions.rs | 5 + .../fmt/feature-gate-format-args-capture.rs | 7 + .../fmt/format-args-capture-macro-hygiene.rs | 7 + .../format-args-capture-missing-variables.rs | 23 + .../rust/rustc/ui/fmt/format-args-capture.rs | 70 + .../rustc/ui/fmt/format-string-error-2.rs | 87 + .../rust/rustc/ui/fmt/format-string-error.rs | 56 + .../rust/rustc/ui/fmt/incorrect-separator.rs | 30 + gcc/testsuite/rust/rustc/ui/fmt/send-sync.rs | 11 + gcc/testsuite/rust/rustc/ui/fn-in-pat.rs | 17 + .../rust/rustc/ui/fn/dyn-fn-alignment.rs | 24 + .../rust/rustc/ui/fn/expr-fn-panic.rs | 12 + .../rust/rustc/ui/fn/fn-bad-block-type.rs | 6 + .../rustc/ui/fn/fn-closure-mutable-capture.rs | 12 + .../rust/rustc/ui/fn/fn-compare-mismatch.rs | 8 + .../rust/rustc/ui/fn/fn-item-type.rs | 56 + .../rust/rustc/ui/fn/fn-trait-formatting.rs | 22 + gcc/testsuite/rust/rustc/ui/fn_must_use.rs | 77 + .../rust/rustc/ui/for-loop-while/auto-loop.rs | 11 + .../rustc/ui/for-loop-while/break-value.rs | 8 + .../rust/rustc/ui/for-loop-while/break.rs | 26 + .../rustc/ui/for-loop-while/for-destruct.rs | 10 + .../ui/for-loop-while/for-loop-goofiness.rs | 17 + .../for-loop-while/for-loop-has-unit-body.rs | 14 + .../for-loop-while/for-loop-into-iterator.rs | 20 + .../for-loop-lifetime-of-unbound-values.rs | 35 + .../rustc/ui/for-loop-while/for-loop-macro.rs | 12 + .../for-loop-mut-ref-element.rs | 7 + .../ui/for-loop-while/for-loop-no-std.rs | 15 + .../rustc/ui/for-loop-while/for-loop-panic.rs | 5 + ...unconstrained-element-type-i32-fallback.rs | 12 + .../foreach-external-iterators-break.rs | 14 + ...xternal-iterators-hashmap-break-restart.rs | 34 + .../foreach-external-iterators-hashmap.rs | 20 + .../foreach-external-iterators-loop.rs | 14 + .../foreach-external-iterators-nested.rs | 16 + .../foreach-external-iterators.rs | 11 + .../rustc/ui/for-loop-while/foreach-nested.rs | 17 + .../for-loop-while/foreach-put-structured.rs | 23 + .../foreach-simple-outer-slot.rs | 17 + .../ui/for-loop-while/label_break_value.rs | 117 + .../rustc/ui/for-loop-while/labeled-break.rs | 23 + .../ui/for-loop-while/linear-for-loop.rs | 24 + .../liveness-assign-imm-local-after-loop.rs | 19 + .../ui/for-loop-while/liveness-loop-break.rs | 14 + .../for-loop-while/liveness-move-in-loop.rs | 21 + .../ui/for-loop-while/loop-break-cont-1.rs | 10 + .../ui/for-loop-while/loop-break-cont.rs | 40 + .../ui/for-loop-while/loop-break-value.rs | 140 + .../rustc/ui/for-loop-while/loop-diverges.rs | 15 + .../ui/for-loop-while/loop-label-shadowing.rs | 13 + .../loop-labeled-break-value.rs | 12 + .../loop-no-reinit-needed-post-bot.rs | 35 + .../rustc/ui/for-loop-while/loop-scope.rs | 9 + .../rustc/ui/for-loop-while/while-cont.rs | 12 + .../ui/for-loop-while/while-flow-graph.rs | 7 + .../rustc/ui/for-loop-while/while-label.rs | 16 + .../rust/rustc/ui/for-loop-while/while-let.rs | 47 + .../while-loop-constraints-2.rs | 16 + .../ui/for-loop-while/while-prelude-drop.rs | 25 + .../ui/for-loop-while/while-with-break.rs | 18 + .../rust/rustc/ui/for-loop-while/while.rs | 14 + .../rust/rustc/ui/for/for-c-in-str.rs | 17 + gcc/testsuite/rust/rustc/ui/for/for-expn.rs | 10 + .../rust/rustc/ui/for/for-loop-bogosity.rs | 22 + ...or-loop-refutable-pattern-error-message.rs | 4 + .../rust/rustc/ui/for/for-loop-type-error.rs | 7 + .../for-loop-unconstrained-element-type.rs | 10 + .../rustc/ui/foreign-fn-return-lifetime.rs | 9 + .../rust/rustc/ui/foreign-unsafe-fn-called.rs | 11 + .../rust/rustc/ui/foreign/auxiliary/fn-abi.rs | 3 + .../rustc/ui/foreign/foreign-fn-linkname.rs | 31 + .../rustc/ui/foreign/foreign-int-types.rs | 14 + .../rustc/ui/foreign/foreign-mod-src/inner.rs | 15 + .../ui/foreign/foreign-mod-unused-const.rs | 13 + .../rustc/ui/foreign/foreign-src/foreign.rs | 10 + .../ui/foreign/foreign-truncated-arguments.rs | 21 + .../rust/rustc/ui/foreign/foreign2.rs | 31 + ...ssue-74120-lowering-of-ffi-block-bodies.rs | 12 + gcc/testsuite/rust/rustc/ui/format-no-std.rs | 29 + .../rust/rustc/ui/fsu-moves-and-copies.rs | 96 + .../fully-qualified-type-name1.rs | 11 + .../fully-qualified-type-name2.rs | 19 + .../fully-qualified-type-name4.rs | 15 + .../rust/rustc/ui/fun-call-variants.rs | 13 + .../rust/rustc/ui/fun-indirect-call.rs | 10 + .../functional-struct-update-noncopyable.rs | 15 + ...nctional-struct-update-respects-privacy.rs | 33 + .../ui/functions-closures/auxiliary/fn-abi.rs | 3 + .../call-closure-from-overloaded-op.rs | 10 + .../capture-clauses-boxed-closures.rs | 15 + .../capture-clauses-unboxed-closures.rs | 14 + .../ui/functions-closures/clone-closure.rs | 19 + .../closure-bounds-can-capture-chan.rs | 17 + .../expect-infer-supply-two-infers.rs | 20 + .../closure-expected-type/issue-38714.rs | 20 + .../supply-just-return-type.rs | 27 + .../closure-expected-type/supply-nothing.rs | 12 + .../functions-closures/closure-immediate.rs | 14 + .../functions-closures/closure-inference.rs | 12 + .../functions-closures/closure-inference2.rs | 10 + .../ui/functions-closures/closure-reform.rs | 57 + .../closure-returning-closure.rs | 6 + .../closure-to-fn-coercion.rs | 36 + .../closure_to_fn_coercion-expected-types.rs | 10 + .../ui/functions-closures/copy-closure.rs | 17 + .../rustc/ui/functions-closures/fn-abi.rs | 19 + .../ui/functions-closures/fn-bare-assign.rs | 18 + .../fn-bare-coerce-to-block.rs | 11 + .../ui/functions-closures/fn-bare-item.rs | 9 + .../ui/functions-closures/fn-bare-size.rs | 9 + .../ui/functions-closures/fn-bare-spawn.rs | 16 + .../ui/functions-closures/fn-coerce-field.rs | 14 + .../functions-closures/fn-item-type-cast.rs | 23 + .../functions-closures/fn-item-type-coerce.rs | 18 + .../fn-item-type-zero-sized.rs | 14 + .../rustc/ui/functions-closures/fn-lval.rs | 12 + .../ui/functions-closures/fn-type-infer.rs | 12 + .../implied-bounds-closure-arg-outlives.rs | 36 + .../nullable-pointer-opt-closures.rs | 35 + .../parallel-codegen-closures.rs | 29 + .../functions-closures/return-from-closure.rs | 34 + .../ui/future-incompatible-lint-group.rs | 9 + .../rust/rustc/ui/gated-bad-feature.rs | 11 + .../rustc/ui/generator/addassign-yield.rs | 36 + .../generator/async-generator-issue-67158.rs | 7 + .../rustc/ui/generator/auto-trait-regions.rs | 54 + .../generator/auxiliary/xcrate-reachable.rs | 15 + .../rustc/ui/generator/auxiliary/xcrate.rs | 19 + .../rustc/ui/generator/borrow-in-tail-expr.rs | 12 + .../rust/rustc/ui/generator/borrowing.rs | 21 + .../rustc/ui/generator/conditional-drop.rs | 62 + .../rust/rustc/ui/generator/control-flow.rs | 54 + .../rust/rustc/ui/generator/discriminant.rs | 138 + .../rustc/ui/generator/drop-and-replace.rs | 46 + .../rust/rustc/ui/generator/drop-env.rs | 67 + .../rust/rustc/ui/generator/dropck-resume.rs | 34 + .../rust/rustc/ui/generator/dropck.rs | 21 + .../generator-region-requirements.rs | 20 + .../generator/generator-resume-after-panic.rs | 25 + .../rustc/ui/generator/generator-with-nll.rs | 13 + .../generator-yielding-or-returning-itself.rs | 36 + .../rust/rustc/ui/generator/issue-44197.rs | 37 + .../rust/rustc/ui/generator/issue-48048.rs | 14 + .../rust/rustc/ui/generator/issue-52398.rs | 29 + .../rust/rustc/ui/generator/issue-53548-1.rs | 21 + .../rust/rustc/ui/generator/issue-53548.rs | 39 + .../rust/rustc/ui/generator/issue-57084.rs | 29 + .../rust/rustc/ui/generator/issue-58888.rs | 29 + .../issue-61442-stmt-expr-with-drop.rs | 33 + .../ui/generator/issue-62506-two_awaits.rs | 18 + .../issue-64620-yield-array-element.rs | 10 + .../rust/rustc/ui/generator/issue-68112.rs | 57 + .../rust/rustc/ui/generator/issue-69017.rs | 19 + .../rust/rustc/ui/generator/issue-69039.rs | 35 + .../rust/rustc/ui/generator/iterator-count.rs | 45 + .../ui/generator/live-upvar-across-yield.rs | 15 + .../rust/rustc/ui/generator/match-bindings.rs | 24 + .../rustc/ui/generator/nested_generators.rs | 22 + .../rustc/ui/generator/niche-in-generator.rs | 20 + .../rustc/ui/generator/non-static-is-unpin.rs | 19 + .../rust/rustc/ui/generator/not-send-sync.rs | 22 + .../rust/rustc/ui/generator/overlap-locals.rs | 30 + .../rustc/ui/generator/panic-drops-resume.rs | 38 + .../rust/rustc/ui/generator/panic-drops.rs | 58 + .../rust/rustc/ui/generator/panic-safe.rs | 31 + .../partial-initialization-across-yield.rs | 47 + .../rust/rustc/ui/generator/pattern-borrow.rs | 18 + .../rustc/ui/generator/pin-box-generator.rs | 14 + .../print/generator-print-verbose-1.rs | 61 + .../print/generator-print-verbose-2.rs | 25 + .../print/generator-print-verbose-3.rs | 13 + .../rustc/ui/generator/reborrow-mut-upvar.rs | 17 + .../ref-escapes-but-not-over-yield.rs | 17 + .../rustc/ui/generator/resume-after-return.rs | 29 + .../ui/generator/resume-arg-late-bound.rs | 19 + .../rustc/ui/generator/resume-arg-size.rs | 29 + .../ui/generator/resume-live-across-yield.rs | 46 + .../rustc/ui/generator/retain-resume-ref.rs | 26 + .../rustc/ui/generator/size-moved-locals.rs | 78 + .../rust/rustc/ui/generator/sized-yield.rs | 15 + .../rustc/ui/generator/smoke-resume-args.rs | 101 + .../rust/rustc/ui/generator/smoke.rs | 178 + .../rustc/ui/generator/static-generators.rs | 21 + .../static-mut-reference-across-yield.rs | 30 + .../rustc/ui/generator/static-not-unpin.rs | 16 + .../static-reference-across-yield.rs | 17 + .../too-live-local-in-immovable-gen.rs | 22 + .../rustc/ui/generator/too-many-parameters.rs | 9 + .../rustc/ui/generator/type-mismatch-error.rs | 23 + .../type-mismatch-signature-deduction.rs | 18 + .../rustc/ui/generator/xcrate-reachable.rs | 15 + .../rust/rustc/ui/generator/xcrate.rs | 31 + .../rustc/ui/generator/yield-in-args-rev.rs | 20 + .../rust/rustc/ui/generator/yield-in-args.rs | 11 + .../rust/rustc/ui/generator/yield-in-box.rs | 19 + .../rust/rustc/ui/generator/yield-in-const.rs | 7 + .../rustc/ui/generator/yield-in-function.rs | 5 + .../ui/generator/yield-in-initializer.rs | 18 + .../rustc/ui/generator/yield-in-static.rs | 7 + .../rust/rustc/ui/generator/yield-subtype.rs | 18 + .../ui/generator/yield-while-iterating.rs | 76 + .../generator/yield-while-local-borrowed.rs | 50 + .../generator/yield-while-ref-reborrowed.rs | 41 + .../ui/generator/yielding-in-match-guards.rs | 44 + .../auxiliary/foo_defn.rs | 9 + .../collections-project-default.rs | 73 + .../generic-associated-types/collections.rs | 72 + .../construct_with_other_type.rs | 26 + .../cross-crate-bounds.rs | 33 + .../empty_generics.rs | 10 + .../gat-dont-ice-on-absent-feature-2.rs | 17 + .../gat-dont-ice-on-absent-feature.rs | 17 + .../gat-incomplete-warning.rs | 7 + .../generic-associated-types-where.rs | 30 + ...ic_associated_type_undeclared_lifetimes.rs | 17 + .../generic-associated-types/impl_bounds.rs | 25 + .../impl_bounds_ok.rs | 32 + .../issue-47206-where-clause.rs | 18 + .../issue-58694-parameter-out-of-range.rs | 11 + .../issue-62326-parameter-out-of-range.rs | 15 + .../generic-associated-types/issue-67424.rs | 13 + .../issue-68641-check-gat-bounds.rs | 33 + .../issue-68642-broken-llvm-ir.rs | 22 + .../issue-68643-broken-mir.rs | 22 + .../issue-68644-codegen-selection.rs | 22 + .../issue-68645-codegen-fulfillment.rs | 22 + .../generic-associated-types/issue-68653.rs | 17 + .../issue-68656-unsized-values.rs | 23 + .../generic-associated-types/issue-74816.rs | 24 + .../ui/generic-associated-types/iterable.rs | 48 + .../missing-bounds.rs | 46 + .../parameter_number_and_kind.rs | 21 + .../parameter_number_and_kind_impl.rs | 36 + .../parse/in-trait-impl.rs | 11 + .../parse/in-trait.rs | 25 + .../pointer_family.rs | 38 + .../projection-bound-cycle-generic.rs | 63 + .../projection-bound-cycle.rs | 65 + .../ui/generic-associated-types/shadowing.rs | 33 + .../streaming_iterator.rs | 78 + .../unsatisfied-outlives-bound.rs | 23 + .../auxiliary/default_type_params_xc.rs | 6 + .../rustc/ui/generics/generic-alias-unique.rs | 12 + .../generics/generic-arg-mismatch-recover.rs | 11 + ...generic-default-type-params-cross-crate.rs | 18 + .../generics/generic-default-type-params.rs | 54 + .../rustc/ui/generics/generic-derived-type.rs | 22 + .../ui/generics/generic-exterior-unique.rs | 13 + .../ui/generics/generic-extern-lifetime.rs | 16 + .../ui/generics/generic-extern-mangle.rs | 10 + .../rust/rustc/ui/generics/generic-extern.rs | 8 + .../rustc/ui/generics/generic-fn-infer.rs | 11 + .../rustc/ui/generics/generic-fn-twice.rs | 12 + .../rustc/ui/generics/generic-fn-unique.rs | 7 + .../rust/rustc/ui/generics/generic-fn.rs | 29 + .../generic-impl-less-params-with-defaults.rs | 14 + .../generic-impl-more-params-with-defaults.rs | 16 + .../rustc/ui/generics/generic-ivec-leak.rs | 6 + .../generics/generic-lifetime-trait-impl.rs | 24 + .../ui/generics/generic-newtype-struct.rs | 9 + .../rustc/ui/generics/generic-no-mangle.rs | 18 + .../generics/generic-non-trailing-defaults.rs | 11 + .../rust/rustc/ui/generics/generic-object.rs | 23 + .../rustc/ui/generics/generic-param-attrs.rs | 39 + .../ui/generics/generic-recursive-tag.rs | 14 + .../ui/generics/generic-static-methods.rs | 22 + .../ui/generics/generic-tag-corruption.rs | 11 + .../rustc/ui/generics/generic-tag-local.rs | 9 + .../rustc/ui/generics/generic-tag-match.rs | 14 + .../rustc/ui/generics/generic-tag-values.rs | 21 + .../rust/rustc/ui/generics/generic-tag.rs | 16 + .../rustc/ui/generics/generic-temporary.rs | 17 + .../rust/rustc/ui/generics/generic-tup.rs | 9 + .../generic-type-less-params-with-defaults.rs | 12 + .../generic-type-more-params-with-defaults.rs | 12 + .../generic-type-params-forward-mention.rs | 7 + .../generics/generic-type-params-name-repr.rs | 52 + .../rustc/ui/generics/generic-type-synonym.rs | 16 + .../rust/rustc/ui/generics/generic-type.rs | 12 + .../rust/rustc/ui/generics/generic-unique.rs | 13 + ...-type-param-can-reference-self-in-trait.rs | 21 + ...efault-type-param-cannot-reference-self.rs | 46 + ...incorrect-explicit-lifetime-name-needed.rs | 15 + .../param-in-ct-in-ty-param-default.rs | 5 + gcc/testsuite/rust/rustc/ui/glob-cycles.rs | 19 + gcc/testsuite/rust/rustc/ui/glob-resolve1.rs | 36 + gcc/testsuite/rust/rustc/ui/global-scope.rs | 14 + gcc/testsuite/rust/rustc/ui/guards.rs | 21 + ...xclusive_range_pattern_syntax_collision.rs | 11 + ...clusive_range_pattern_syntax_collision2.rs | 12 + ...clusive_range_pattern_syntax_collision3.rs | 13 + .../feature-gate-half-open-range-patterns.rs | 23 + .../half-open-range-pats-bad-types.rs | 9 + .../half-open-range-pats-exhaustive-fail.rs | 169 + .../half-open-range-pats-exhaustive-pass.rs | 50 + ...nge-pats-inclusive-dotdotdot-bad-syntax.rs | 33 + .../half-open-range-pats-inclusive-no-end.rs | 27 + ...lf-open-range-pats-ref-ambiguous-interp.rs | 27 + .../half-open-range-pats-semantics.rs | 161 + .../half-open-range-pats-syntactic-pass.rs | 31 + .../half-open-range-pats-thir-lower-empty.rs | 55 + .../half-open-range-patterns/pat-tuple-4.rs | 14 + .../half-open-range-patterns/pat-tuple-5.rs | 11 + .../ui/hashmap/hashmap-capacity-overflow.rs | 14 + .../ui/hashmap/hashmap-iter-value-lifetime.rs | 11 + .../rustc/ui/hashmap/hashmap-lifetimes.rs | 9 + .../rust/rustc/ui/hashmap/hashmap-memory.rs | 95 + gcc/testsuite/rust/rustc/ui/hello.rs | 6 + .../rust/rustc/ui/hello_world/main.rs | 8 + .../rust/rustc/ui/hidden-rt-injection.rs | 9 + .../rust/rustc/ui/hidden-rt-injection2.rs | 9 + .../rust/rustc/ui/higher-lifetime-bounds.rs | 70 + .../hrtb-binder-levels-in-object-types.rs | 30 + .../hrtb-debruijn-object-types-in-closures.rs | 17 + .../hrtb-fn-like-trait-object.rs | 28 + .../hrtb-fn-like-trait.rs | 28 + .../hrtb-opt-in-copy.rs | 29 + .../ui/higher-rank-trait-bounds/hrtb-parse.rs | 37 + .../hrtb-precedence-of-plus-where-clause.rs | 26 + .../hrtb-precedence-of-plus.rs | 14 + .../hrtb-resolve-lifetime.rs | 15 + .../hrtb-trait-object-paren-notation.rs | 27 + .../hrtb-trait-object-passed-to-closure.rs | 26 + .../hrtb-type-outlives.rs | 47 + .../hrtb-unboxed-closure-trait.rs | 12 + .../higher-rank-trait-bounds/issue-59311.rs | 21 + .../rust/rustc/ui/hr-subtype/hr-subtype.rs | 113 + .../rust/rustc/ui/hr-subtype/return-static.rs | 14 + .../rust/rustc/ui/hrtb/due-to-where-clause.rs | 14 + .../rustc/ui/hrtb/hrtb-cache-issue-54302.rs | 25 + .../rustc/ui/hrtb/hrtb-conflate-regions.rs | 30 + .../ui/hrtb/hrtb-debruijn-in-receiver.rs | 19 + .../rustc/ui/hrtb/hrtb-exists-forall-fn.rs | 19 + .../hrtb-exists-forall-trait-contravariant.rs | 37 + .../hrtb-exists-forall-trait-covariant.rs | 38 + .../hrtb-exists-forall-trait-invariant.rs | 30 + ...tb-higher-ranker-supertraits-transitive.rs | 51 + .../ui/hrtb/hrtb-higher-ranker-supertraits.rs | 49 + .../rustc/ui/hrtb/hrtb-identity-fn-borrows.rs | 27 + .../rustc/ui/hrtb/hrtb-just-for-static.rs | 34 + .../rustc/ui/hrtb/hrtb-perfect-forwarding.rs | 58 + .../rust/rustc/ui/hrtb/issue-30786.rs | 147 + .../rust/rustc/ui/hrtb/issue-46989.rs | 41 + .../rust/rustc/ui/hrtb/issue-57639.rs | 30 + .../rust/rustc/ui/hrtb/issue-58451.rs | 14 + .../rustc/ui/hrtb/issue-62203-hrtb-ice.rs | 51 + gcc/testsuite/rust/rustc/ui/html-literals.rs | 95 + .../rust/rustc/ui/huge-array-simple-32.rs | 13 + .../rust/rustc/ui/huge-array-simple-64.rs | 13 + gcc/testsuite/rust/rustc/ui/huge-array.rs | 16 + gcc/testsuite/rust/rustc/ui/huge-enum.rs | 19 + gcc/testsuite/rust/rustc/ui/huge-struct.rs | 54 + .../rust/rustc/ui/hygiene/arguments.rs | 18 + .../rust/rustc/ui/hygiene/assoc_item_ctxt.rs | 43 + .../rustc/ui/hygiene/assoc_ty_bindings.rs | 39 + .../ui/hygiene/auxiliary/codegen-attrs.rs | 11 + .../hygiene/auxiliary/def-site-async-await.rs | 8 + .../rustc/ui/hygiene/auxiliary/intercrate.rs | 47 + .../hygiene/auxiliary/legacy_interaction.rs | 10 + .../hygiene/auxiliary/local_inner_macros.rs | 20 + .../rustc/ui/hygiene/auxiliary/my_crate.rs | 2 + .../ui/hygiene/auxiliary/needs_hygiene.rs | 6 + .../hygiene/auxiliary/nested-dollar-crate.rs | 15 + .../rustc/ui/hygiene/auxiliary/not-libstd.rs | 2 + .../ui/hygiene/auxiliary/opaque-hygiene.rs | 22 + .../ui/hygiene/auxiliary/stdlib-prelude.rs | 4 + .../ui/hygiene/auxiliary/transparent-basic.rs | 7 + .../hygiene/auxiliary/unhygienic_example.rs | 28 + .../rust/rustc/ui/hygiene/auxiliary/xcrate.rs | 29 + .../ui/hygiene/cross-crate-codegen-attrs.rs | 13 + .../rustc/ui/hygiene/cross_crate_hygiene.rs | 9 + .../rustc/ui/hygiene/dollar-crate-modern.rs | 26 + .../rustc/ui/hygiene/duplicate_lifetimes.rs | 20 + .../rustc/ui/hygiene/eager-from-opaque-2.rs | 23 + .../rustc/ui/hygiene/eager-from-opaque.rs | 21 + .../rustc/ui/hygiene/expansion-info-reset.rs | 5 + .../extern-prelude-from-opaque-fail.rs | 29 + .../rustc/ui/hygiene/fields-definition.rs | 23 + .../rust/rustc/ui/hygiene/fields-move.rs | 31 + .../ui/hygiene/fields-numeric-borrowck.rs | 14 + gcc/testsuite/rust/rustc/ui/hygiene/fields.rs | 31 + .../rust/rustc/ui/hygiene/for-loop.rs | 9 + .../rust/rustc/ui/hygiene/format-args.rs | 13 + .../rust/rustc/ui/hygiene/generate-mod.rs | 50 + .../rust/rustc/ui/hygiene/generic_params.rs | 106 + gcc/testsuite/rust/rustc/ui/hygiene/globs.rs | 73 + .../rust/rustc/ui/hygiene/hir-res-hygiene.rs | 19 + .../rustc/ui/hygiene/hygiene-dodging-1.rs | 15 + .../rust/rustc/ui/hygiene/hygiene.rs | 115 + .../rust/rustc/ui/hygiene/hygienic-label-1.rs | 8 + .../rust/rustc/ui/hygiene/hygienic-label-2.rs | 8 + .../rust/rustc/ui/hygiene/hygienic-label-3.rs | 10 + .../rust/rustc/ui/hygiene/hygienic-label-4.rs | 8 + .../ui/hygiene/hygienic-labels-in-let.rs | 105 + .../rust/rustc/ui/hygiene/hygienic-labels.rs | 86 + .../rust/rustc/ui/hygiene/impl_items.rs | 35 + .../rust/rustc/ui/hygiene/intercrate.rs | 13 + .../rust/rustc/ui/hygiene/issue-44128.rs | 18 + .../rust/rustc/ui/hygiene/issue-47311.rs | 18 + .../rust/rustc/ui/hygiene/issue-47312.rs | 22 + .../hygiene/issue-61574-const-parameters.rs | 33 + .../issue-77523-def-site-async-await.rs | 20 + gcc/testsuite/rust/rustc/ui/hygiene/items.rs | 28 + .../rustc/ui/hygiene/legacy_interaction.rs | 43 + .../rust/rustc/ui/hygiene/lexical.rs | 25 + .../rustc/ui/hygiene/local_inner_macros.rs | 20 + .../rustc/ui/hygiene/macro-metavars-legacy.rs | 30 + .../ui/hygiene/macro-metavars-transparent.rs | 25 + .../rustc/ui/hygiene/missing-self-diag.rs | 24 + .../rustc/ui/hygiene/nested-dollar-crate.rs | 10 + .../rustc/ui/hygiene/nested_macro_privacy.rs | 18 + .../ui/hygiene/no_implicit_prelude-2018.rs | 12 + .../rustc/ui/hygiene/no_implicit_prelude.rs | 21 + .../rust/rustc/ui/hygiene/panic-location.rs | 11 + .../rust/rustc/ui/hygiene/pattern-macro.rs | 7 + .../ui/hygiene/prelude-import-hygiene.rs | 30 + .../rust/rustc/ui/hygiene/privacy-early.rs | 18 + .../rust/rustc/ui/hygiene/privacy.rs | 19 + .../ui/hygiene/rustc-macro-transparency.rs | 32 + .../rust/rustc/ui/hygiene/specialization.rs | 26 + .../stdlib-prelude-from-opaque-early.rs | 22 + .../stdlib-prelude-from-opaque-late.rs | 17 + .../rust/rustc/ui/hygiene/trait_items-2.rs | 21 + .../rust/rustc/ui/hygiene/trait_items.rs | 22 + .../rustc/ui/hygiene/transparent-basic.rs | 44 + .../rust/rustc/ui/hygiene/unpretty-debug.rs | 21 + .../ui/hygiene/wrap_unhygienic_example.rs | 35 + gcc/testsuite/rust/rustc/ui/hygiene/xcrate.rs | 13 + .../rust/rustc/ui/if-attrs/bad-cfg.rs | 6 + .../rust/rustc/ui/if-attrs/builtin-if-attr.rs | 13 + .../rustc/ui/if-attrs/cfg-false-if-attr.rs | 44 + .../rust/rustc/ui/if-attrs/else-attrs.rs | 26 + .../rust/rustc/ui/if-attrs/gate-whole-expr.rs | 16 + .../rust/rustc/ui/if-attrs/let-chains-attr.rs | 14 + .../rust/rustc/ui/if-attrs/stmt-expr-gated.rs | 7 + gcc/testsuite/rust/rustc/ui/if-bot.rs | 7 + gcc/testsuite/rust/rustc/ui/if-check.rs | 18 + .../rust/rustc/ui/if-else-type-mismatch.rs | 47 + gcc/testsuite/rust/rustc/ui/if-ret.rs | 9 + .../rust/rustc/ui/if/expr-if-panic-fn.rs | 21 + .../rust/rustc/ui/if/expr-if-panic.rs | 14 + .../rust/rustc/ui/if/if-branch-types.rs | 6 + .../rust/rustc/ui/if/if-check-panic.rs | 26 + gcc/testsuite/rust/rustc/ui/if/if-cond-bot.rs | 14 + .../rust/rustc/ui/if/if-let-arm-types.rs | 12 + gcc/testsuite/rust/rustc/ui/if/if-let.rs | 50 + gcc/testsuite/rust/rustc/ui/if/if-loop.rs | 9 + .../rust/rustc/ui/if/if-no-match-bindings.rs | 29 + gcc/testsuite/rust/rustc/ui/if/if-typeck.rs | 11 + .../rust/rustc/ui/if/if-without-block.rs | 10 + .../rustc/ui/if/if-without-else-as-fn-expr.rs | 50 + .../rustc/ui/if/if-without-else-result.rs | 7 + .../rust/rustc/ui/if/ifmt-bad-arg.rs | 95 + .../rust/rustc/ui/if/ifmt-bad-format-args.rs | 5 + gcc/testsuite/rust/rustc/ui/if/ifmt-unimpl.rs | 5 + .../rust/rustc/ui/if/ifmt-unknown-trait.rs | 5 + .../rust/rustc/ui/ignore-all-the-things.rs | 45 + .../rust/rustc/ui/illegal-ufcs-drop.rs | 10 + .../rust/rustc/ui/immut-function-arguments.rs | 10 + .../rust/rustc/ui/impl-bounds-checking.rs | 15 + .../rust/rustc/ui/impl-duplicate-methods.rs | 10 + .../assoc-type.rs | 26 + .../impl-header-lifetime-elision/dyn-trait.rs | 32 + .../explicit-and-elided-same-header.rs | 14 + .../inherent-impl.rs | 10 + .../path-elided.rs | 12 + .../path-underscore.rs | 35 + .../ref-underscore.rs | 31 + .../trait-elided.rs | 10 + .../trait-underscore.rs | 36 + .../rustc/ui/impl-inherent-non-conflict.rs | 24 + .../rustc/ui/impl-not-adjacent-to-type.rs | 17 + .../rust/rustc/ui/impl-privacy-xc-1.rs | 12 + .../rust/rustc/ui/impl-privacy-xc-2.rs | 11 + .../ui/impl-trait-in-bindings-issue-73003.rs | 9 + .../rust/rustc/ui/impl-trait-in-bindings.rs | 50 + ...ssociated-impl-trait-type-generic-trait.rs | 31 + .../associated-impl-trait-type-trivial.rs | 21 + .../impl-trait/associated-impl-trait-type.rs | 25 + .../ui/impl-trait/auto-trait-leak-rpass.rs | 22 + .../rustc/ui/impl-trait/auto-trait-leak.rs | 25 + .../rustc/ui/impl-trait/auto-trait-leak2.rs | 26 + .../rust/rustc/ui/impl-trait/auto-trait.rs | 26 + .../ui/impl-trait/auxiliary/extra-item.rs | 2 + .../auxiliary/no_method_suggested_traits.rs | 37 + .../rustc/ui/impl-trait/auxiliary/xcrate.rs | 24 + .../ui/impl-trait/binding-without-value.rs | 10 + .../rustc/ui/impl-trait/bindings-opaque.rs | 18 + .../rust/rustc/ui/impl-trait/bindings.rs | 31 + .../ui/impl-trait/bound-normalization-fail.rs | 51 + .../ui/impl-trait/bound-normalization-pass.rs | 108 + .../rustc/ui/impl-trait/bounds_regression.rs | 25 + .../can-return-unconstrained-closure.rs | 24 + .../impl-trait/closure-calling-parent-fn.rs | 13 + .../impl-trait/closure-in-impl-trait-arg.rs | 8 + .../ui/impl-trait/closure-in-impl-trait.rs | 15 + .../ui/impl-trait/deprecated_annotation.rs | 20 + .../impl-trait/does-not-live-long-enough.rs | 12 + .../dyn-trait-elided-two-inputs-assoc.rs | 17 + .../dyn-trait-elided-two-inputs-param.rs | 12 + .../dyn-trait-elided-two-inputs-ref-assoc.rs | 28 + .../dyn-trait-elided-two-inputs-ref-param.rs | 24 + .../dyn-trait-return-should-be-impl-trait.rs | 75 + .../ui/impl-trait/equal-hidden-lifetimes.rs | 50 + .../rustc/ui/impl-trait/equality-rpass.rs | 49 + .../rust/rustc/ui/impl-trait/equality.rs | 44 + .../rust/rustc/ui/impl-trait/equality2.rs | 45 + .../rustc/ui/impl-trait/example-calendar.rs | 843 ++ .../rust/rustc/ui/impl-trait/example-st.rs | 31 + .../rust/rustc/ui/impl-trait/extra-item.rs | 11 + .../rustc/ui/impl-trait/hidden-lifetimes.rs | 64 + .../ui/impl-trait/impl-generic-mismatch-ab.rs | 13 + .../ui/impl-trait/impl-generic-mismatch.rs | 33 + .../ui/impl-trait/impl-trait-plus-priority.rs | 50 + .../ui/impl-trait/impl_trait_projections.rs | 40 + .../rust/rustc/ui/impl-trait/issue-55872-1.rs | 23 + .../rust/rustc/ui/impl-trait/issue-55872-2.rs | 23 + .../rust/rustc/ui/impl-trait/issue-55872.rs | 21 + .../rust/rustc/ui/impl-trait/issue-56445.rs | 26 + .../rust/rustc/ui/impl-trait/issue-57200.rs | 16 + .../rust/rustc/ui/impl-trait/issue-57201.rs | 16 + .../rust/rustc/ui/impl-trait/issue-60473.rs | 16 + .../rust/rustc/ui/impl-trait/issue-67166.rs | 12 + .../rust/rustc/ui/impl-trait/issue-68532.rs | 14 + .../rust/rustc/ui/impl-trait/issue-69840.rs | 17 + .../rust/rustc/ui/impl-trait/issue-72911.rs | 23 + .../issues/infinite-impl-trait-issue-38064.rs | 26 + ...issue-21659-show-relevant-trait-impls-3.rs | 23 + .../rustc/ui/impl-trait/issues/issue-42479.rs | 18 + .../rustc/ui/impl-trait/issues/issue-49376.rs | 24 + .../rustc/ui/impl-trait/issues/issue-52128.rs | 26 + .../rustc/ui/impl-trait/issues/issue-53457.rs | 16 + .../issue-55608-captures-empty-region.rs | 23 + .../issues/issue-57464-unexpected-regions.rs | 30 + ...-deeply-nested-impl-trait-in-assoc-proj.rs | 18 + .../issues/issue-57979-impl-trait-in-path.rs | 13 + ...e-57979-nested-impl-trait-in-assoc-proj.rs | 13 + .../rustc/ui/impl-trait/issues/issue-65581.rs | 34 + .../rustc/ui/impl-trait/issues/issue-70877.rs | 39 + .../issues/universal-issue-48703.rs | 10 + ...iversal-turbofish-in-method-issue-50950.rs | 18 + .../rust/rustc/ui/impl-trait/lifetimes.rs | 124 + .../method-suggestion-no-duplication.rs | 10 + .../rustc/ui/impl-trait/multiple-lifetimes.rs | 13 + .../multiple-lifetimes/error-handling-2.rs | 30 + .../multiple-lifetimes/error-handling.rs | 30 + .../multiple-lifetimes/inverse-bounds.rs | 55 + .../ordinary-bounds-pick-original-elided.rs | 30 + ...nds-pick-original-type-alias-impl-trait.rs | 33 + .../ordinary-bounds-pick-original.rs | 30 + .../ordinary-bounds-pick-other.rs | 47 + .../ordinary-bounds-unrelated.rs | 39 + .../ordinary-bounds-unsuited.rs | 42 + .../must_outlive_least_region_or_bound.rs | 43 + .../impl-trait/needs_least_region_or_bound.rs | 24 + .../rustc/ui/impl-trait/negative-reasoning.rs | 24 + .../rustc/ui/impl-trait/nested-return-type.rs | 17 + .../rust/rustc/ui/impl-trait/nesting.rs | 16 + .../impl-trait/no-method-suggested-traits.rs | 78 + .../rust/rustc/ui/impl-trait/no-trait.rs | 4 + ...safe-trait-in-return-position-dyn-trait.rs | 36 + ...afe-trait-in-return-position-impl-trait.rs | 47 + .../recursive-impl-trait-type-direct.rs | 11 + .../recursive-impl-trait-type-indirect.rs | 97 + ...e-impl-trait-type-through-non-recursive.rs | 26 + ...-escape-via-bound-contravariant-closure.rs | 20 + .../region-escape-via-bound-contravariant.rs | 24 + .../ui/impl-trait/region-escape-via-bound.rs | 23 + .../return-position-impl-trait-minimal.rs | 6 + .../static-return-lifetime-infered.rs | 15 + .../rust/rustc/ui/impl-trait/trait_type.rs | 25 + .../ui/impl-trait/type-alias-generic-param.rs | 23 + .../type-alias-impl-trait-in-fn-body.rs | 13 + .../ui/impl-trait/type_parameters_captured.rs | 13 + .../impl-trait/universal-mismatched-type.rs | 8 + .../impl-trait/universal-two-impl-traits.rs | 10 + .../ui/impl-trait/universal_hrtb_anon.rs | 11 + .../ui/impl-trait/universal_hrtb_named.rs | 11 + .../universal_in_adt_in_parameters.rs | 23 + .../universal_in_impl_trait_in_parameters.rs | 31 + .../universal_in_trait_defn_parameters.rs | 19 + .../impl-trait/universal_multiple_bounds.rs | 14 + .../ui/impl-trait/universal_wrong_bounds.rs | 14 + .../ui/impl-trait/unsafety-checking-cycle.rs | 33 + .../rust/rustc/ui/impl-trait/wf-eval-order.rs | 40 + .../rustc/ui/impl-trait/where-allowed-2.rs | 9 + .../rust/rustc/ui/impl-trait/where-allowed.rs | 227 + .../rust/rustc/ui/impl-trait/xcrate.rs | 12 + .../rust/rustc/ui/impl-trait/xcrate_simple.rs | 10 + .../rustc/ui/impl-unused-rps-in-assoc-type.rs | 19 + .../rust/rustc/ui/impl-unused-tps-inherent.rs | 26 + .../rust/rustc/ui/impl-unused-tps.rs | 63 + .../rust/rustc/ui/implicit-method-bind.rs | 4 + gcc/testsuite/rust/rustc/ui/import.rs | 18 + gcc/testsuite/rust/rustc/ui/import2.rs | 11 + gcc/testsuite/rust/rustc/ui/import3.rs | 5 + gcc/testsuite/rust/rustc/ui/import4.rs | 8 + .../rustc/ui/imports/auxiliary/gensymed.rs | 4 + .../ui/imports/auxiliary/glob-conflict.rs | 14 + .../ui/imports/auxiliary/import_crate_var.rs | 8 + .../rustc/ui/imports/auxiliary/issue-55811.rs | 6 + .../rustc/ui/imports/auxiliary/issue-56125.rs | 12 + .../rustc/ui/imports/auxiliary/two_macros.rs | 6 + .../rust/rustc/ui/imports/duplicate.rs | 52 + .../extern-crate-self-fail.rs | 7 + .../extern-crate-self-macro-alias.rs | 17 + .../extern-crate-self-macro-item.rs | 13 + .../extern-crate-self-macro-self.rs | 17 + .../extern-crate-self-pass.rs | 14 + .../rustc/ui/imports/extern-crate-used.rs | 33 + ...-prelude-extern-crate-absolute-expanded.rs | 17 + .../extern-prelude-extern-crate-cfg.rs | 17 + .../extern-prelude-extern-crate-fail.rs | 25 + .../extern-prelude-extern-crate-pass.rs | 13 + ...elude-extern-crate-restricted-shadowing.rs | 27 + .../extern-prelude-extern-crate-shadowing.rs | 13 + .../rust/rustc/ui/imports/gensymed.rs | 10 + .../ui/imports/glob-conflict-cross-crate.rs | 9 + .../rust/rustc/ui/imports/glob-shadowing.rs | 35 + .../rust/rustc/ui/imports/glob-use-std.rs | 12 + .../rust/rustc/ui/imports/import-crate-var.rs | 9 + .../auxiliary/crate_with_invalid_spans.rs | 21 + .../crate_with_invalid_spans_macros.rs | 8 + .../import-crate-with-invalid-spans/main.rs | 14 + .../rustc/ui/imports/import-from-missing.rs | 13 + .../rust/rustc/ui/imports/import-from.rs | 12 + .../rustc/ui/imports/import-glob-0-rpass.rs | 30 + .../rust/rustc/ui/imports/import-glob-0.rs | 17 + .../rust/rustc/ui/imports/import-glob-1.rs | 28 + .../rustc/ui/imports/import-glob-circular.rs | 20 + .../rustc/ui/imports/import-glob-crate.rs | 20 + .../rust/rustc/ui/imports/import-in-block.rs | 14 + .../rust/rustc/ui/imports/import-loop-2.rs | 14 + .../rust/rustc/ui/imports/import-loop.rs | 10 + .../rustc/ui/imports/import-prefix-macro-1.rs | 17 + .../rustc/ui/imports/import-prefix-macro-2.rs | 17 + .../rustc/ui/imports/import-prefix-macro.rs | 28 + .../rust/rustc/ui/imports/import-rename.rs | 14 + .../rustc/ui/imports/import-trailing-comma.rs | 14 + .../rustc/ui/imports/import-trait-method.rs | 8 + gcc/testsuite/rust/rustc/ui/imports/import.rs | 13 + .../rust/rustc/ui/imports/import2.rs | 10 + .../rust/rustc/ui/imports/import3.rs | 14 + .../rust/rustc/ui/imports/import4.rs | 10 + .../rust/rustc/ui/imports/import5.rs | 11 + .../rust/rustc/ui/imports/import6.rs | 16 + .../rust/rustc/ui/imports/import7.rs | 19 + .../rust/rustc/ui/imports/import8.rs | 11 + .../rust/rustc/ui/imports/imports.rs | 67 + .../rust/rustc/ui/imports/issue-53140.rs | 12 + .../rust/rustc/ui/imports/issue-53269.rs | 12 + .../rust/rustc/ui/imports/issue-53512.rs | 9 + .../rust/rustc/ui/imports/issue-55457.rs | 11 + .../rust/rustc/ui/imports/issue-55811.rs | 7 + .../rust/rustc/ui/imports/issue-55884-1.rs | 22 + .../rust/rustc/ui/imports/issue-55884-2.rs | 15 + .../rust/rustc/ui/imports/issue-56125.rs | 22 + .../rust/rustc/ui/imports/issue-56263.rs | 9 + .../rust/rustc/ui/imports/issue-57015.rs | 14 + .../rust/rustc/ui/imports/issue-57539.rs | 9 + .../rust/rustc/ui/imports/issue-62767.rs | 31 + .../local-modularized-tricky-fail-1.rs | 48 + .../local-modularized-tricky-fail-2.rs | 49 + .../local-modularized-tricky-fail-3.rs | 23 + .../imports/local-modularized-tricky-pass.rs | 20 + .../rustc/ui/imports/local-modularized.rs | 36 + .../rust/rustc/ui/imports/macro-paths.rs | 29 + gcc/testsuite/rust/rustc/ui/imports/macros.rs | 43 + .../rust/rustc/ui/imports/reexports.rs | 38 + .../ui/imports/rfc-1560-warning-cycle.rs | 14 + .../rustc/ui/imports/shadow_builtin_macros.rs | 53 + .../ui/imports/unresolved-imports-used.rs | 19 + .../rust/rustc/ui/imports/unused-macro-use.rs | 12 + gcc/testsuite/rust/rustc/ui/imports/unused.rs | 28 + .../rust/rustc/ui/impossible_range.rs | 21 + .../rust/rustc/ui/in-band-lifetimes.rs | 97 + .../rust/rustc/ui/in-band-lifetimes/E0687.rs | 17 + .../rustc/ui/in-band-lifetimes/E0687_where.rs | 9 + .../rust/rustc/ui/in-band-lifetimes/E0688.rs | 17 + .../ui/in-band-lifetimes/elided-lifetimes.rs | 88 + ...124-anon-lifetime-in-struct-declaration.rs | 11 + .../rustc/ui/in-band-lifetimes/mismatched.rs | 9 + .../ui/in-band-lifetimes/mismatched_trait.rs | 11 + .../mismatched_trait_impl-2.rs | 15 + .../mismatched_trait_impl.rs | 15 + .../ui/in-band-lifetimes/mut_while_borrow.rs | 12 + .../ui/in-band-lifetimes/nested-items.rs | 21 + .../in-band-lifetimes/no_in_band_in_struct.rs | 13 + .../no_introducing_in_band_in_locals.rs | 14 + .../rust/rustc/ui/in-band-lifetimes/shadow.rs | 12 + gcc/testsuite/rust/rustc/ui/inc-range-pat.rs | 13 + .../ui/include-macros/mismatched-types.rs | 5 + .../rustc/ui/include-macros/normalization.rs | 13 + .../rustc/ui/include-single-expr-helper-1.rs | 6 + .../rustc/ui/include-single-expr-helper.rs | 6 + .../rust/rustc/ui/include-single-expr.rs | 7 + gcc/testsuite/rust/rustc/ui/index-bot.rs | 4 + gcc/testsuite/rust/rustc/ui/index-help.rs | 5 + gcc/testsuite/rust/rustc/ui/index_message.rs | 5 + .../rust/rustc/ui/indexing-requires-a-uint.rs | 15 + .../rust/rustc/ui/infer-fn-tail-expr.rs | 12 + .../auxiliary/inference_unstable_iterator.rs | 15 + .../auxiliary/inference_unstable_itertools.rs | 8 + ...infer-async-enabled-impl-trait-bindings.rs | 18 + .../rustc/ui/inference/cannot-infer-async.rs | 16 + .../ui/inference/cannot-infer-closure.rs | 7 + .../infer-binary-operand-behind-reference.rs | 31 + .../inference-variable-behind-raw-pointer.rs | 12 + .../rustc/ui/inference/inference_unstable.rs | 20 + .../inference/inference_unstable_featured.rs | 18 + .../ui/inference/inference_unstable_forced.rs | 13 + .../rust/rustc/ui/inference/issue-71732.rs | 24 + .../rust/rustc/ui/inference/issue-72616.rs | 30 + .../rustc/ui/infinite/infinite-autoderef.rs | 28 + .../ui/infinite/infinite-instantiation.rs | 30 + .../ui/infinite/infinite-macro-expansion.rs | 8 + .../infinite/infinite-recursion-const-fn.rs | 13 + .../infinite/infinite-tag-type-recursion.rs | 6 + .../infinite/infinite-vec-type-recursion.rs | 5 + gcc/testsuite/rust/rustc/ui/inherit-env.rs | 27 + .../rust/rustc/ui/init-large-type.rs | 24 + .../rust/rustc/ui/init-res-into-things.rs | 83 + .../rustc/ui/inline-asm-bad-constraint.rs | 41 + .../rust/rustc/ui/inline-asm-bad-operand.rs | 60 + .../ui/inline-const/const-expr-array-init.rs | 11 + .../rustc/ui/inline-const/const-expr-basic.rs | 15 + .../rustc/ui/inline-const/const-expr-macro.rs | 13 + .../ui/inline-const/const-expr-reference.rs | 16 + .../ui/inline-const/const-match-pat-range.rs | 39 + .../rustc/ui/inline-const/const-match-pat.rs | 22 + .../rustc/ui/inline-const/macro-with-const.rs | 21 + .../rustc/ui/inline-disallow-on-variant.rs | 8 + gcc/testsuite/rust/rustc/ui/inlined-main.rs | 5 + .../rust/rustc/ui/inner-attrs-on-impl.rs | 25 + gcc/testsuite/rust/rustc/ui/inner-module.rs | 11 + .../rustc/ui/inner-static-type-parameter.rs | 12 + gcc/testsuite/rust/rustc/ui/inner-static.rs | 15 + gcc/testsuite/rust/rustc/ui/instantiable.rs | 18 + .../ui/integer-literal-suffix-inference.rs | 221 + .../rust/rustc/ui/integral-indexing.rs | 17 + .../ui/integral-variable-unification-error.rs | 7 + .../interior-mutability.rs | 8 + .../internal/auxiliary/internal_unstable.rs | 102 + .../ui/internal/internal-unstable-const.rs | 15 + .../ui/internal/internal-unstable-noallow.rs | 24 + .../internal-unstable-thread-local.rs | 12 + .../rustc/ui/internal/internal-unstable.rs | 44 + .../rust/rustc/ui/intrinsics-always-extern.rs | 17 + .../ui/intrinsics/auxiliary/cci_intrinsic.rs | 15 + .../ui/intrinsics/intrinsic-alignment.rs | 66 + .../rustc/ui/intrinsics/intrinsic-assume.rs | 18 + .../ui/intrinsics/intrinsic-atomics-cc.rs | 13 + .../rustc/ui/intrinsics/intrinsic-atomics.rs | 104 + .../intrinsics/intrinsic-move-val-cleanups.rs | 192 + .../rustc/ui/intrinsics/intrinsic-move-val.rs | 82 + .../rustc/ui/intrinsics/intrinsic-nearby.rs | 12 + .../ui/intrinsics/intrinsic-unreachable.rs | 18 + .../rustc/ui/intrinsics/intrinsic-volatile.rs | 45 + .../rustc/ui/intrinsics/intrinsics-integer.rs | 172 + .../rustc/ui/intrinsics/intrinsics-math.rs | 61 + .../rust/rustc/ui/intrinsics/issue-28575.rs | 10 + .../intrinsics/panic-uninitialized-zeroed.rs | 207 + .../ui/intrinsics/unchecked_math_unsafe.rs | 9 + .../ui/intrinsics/unchecked_math_unstable.rs | 9 + .../auxiliary/foo/bar.rs | 2 + .../auxiliary/foo/mod.rs | 2 + .../invalid-module-declaration.rs | 6 + ...lid-rustc_args_required_const-arguments.rs | 27 + .../ui/invalid-self-argument/bare-fn-start.rs | 7 + .../rustc/ui/invalid-self-argument/bare-fn.rs | 6 + .../ui/invalid-self-argument/trait-fn.rs | 12 + .../rustc/ui/invalid/invalid-crate-type.rs | 49 + .../rust/rustc/ui/invalid/invalid-inline.rs | 20 + .../rustc/ui/invalid/invalid-macro-matcher.rs | 9 + .../rustc/ui/invalid/invalid-no-sanitize.rs | 6 + .../rustc/ui/invalid/invalid-path-in-const.rs | 5 + .../rustc/ui/invalid/invalid-plugin-attr.rs | 9 + .../rustc/ui/invalid_crate_type_syntax.rs | 7 + .../ui/invalid_dispatch_from_dyn_impls.rs | 52 + .../rustc/ui/issue-72470-llvm-dominate.rs | 67 + gcc/testsuite/rust/rustc/ui/issue-73914.rs | 31 + gcc/testsuite/rust/rustc/ui/issue-74047.rs | 18 + .../rustc/ui/issue-76387-llvm-miscompile.rs | 23 + gcc/testsuite/rust/rustc/ui/issue-76597.rs | 12 + gcc/testsuite/rust/rustc/ui/issues-71798.rs | 8 + .../rustc/ui/issues/auxiliary/cgu_test.rs | 7 + .../rustc/ui/issues/auxiliary/cgu_test_a.rs | 16 + .../rustc/ui/issues/auxiliary/cgu_test_b.rs | 16 + .../rustc/ui/issues/auxiliary/empty-struct.rs | 10 + .../rust/rustc/ui/issues/auxiliary/i8.rs | 4 + .../rust/rustc/ui/issues/auxiliary/iss.rs | 13 + .../rustc/ui/issues/auxiliary/issue-10028.rs | 10 + .../ui/issues/auxiliary/issue-10031-aux.rs | 2 + .../rustc/ui/issues/auxiliary/issue-11224.rs | 17 + .../ui/issues/auxiliary/issue-11225-1.rs | 19 + .../ui/issues/auxiliary/issue-11225-2.rs | 29 + .../ui/issues/auxiliary/issue-11225-3.rs | 29 + .../rustc/ui/issues/auxiliary/issue-11508.rs | 11 + .../rustc/ui/issues/auxiliary/issue-11529.rs | 2 + .../rustc/ui/issues/auxiliary/issue-11680.rs | 10 + .../ui/issues/auxiliary/issue-12133-dylib.rs | 2 + .../ui/issues/auxiliary/issue-12133-dylib2.rs | 7 + .../ui/issues/auxiliary/issue-12133-rlib.rs | 4 + .../ui/issues/auxiliary/issue-12612-1.rs | 4 + .../ui/issues/auxiliary/issue-12612-2.rs | 2 + .../ui/issues/auxiliary/issue-12660-aux.rs | 12 + .../rustc/ui/issues/auxiliary/issue-13507.rs | 88 + .../ui/issues/auxiliary/issue-13620-1.rs | 10 + .../ui/issues/auxiliary/issue-13620-2.rs | 4 + .../ui/issues/auxiliary/issue-13872-1.rs | 2 + .../ui/issues/auxiliary/issue-13872-2.rs | 4 + .../ui/issues/auxiliary/issue-13872-3.rs | 10 + .../ui/issues/auxiliary/issue-14344-1.rs | 6 + .../ui/issues/auxiliary/issue-14344-2.rs | 4 + .../rustc/ui/issues/auxiliary/issue-14421.rs | 26 + .../rustc/ui/issues/auxiliary/issue-14422.rs | 26 + .../rustc/ui/issues/auxiliary/issue-15562.rs | 6 + .../rustc/ui/issues/auxiliary/issue-16643.rs | 20 + .../rustc/ui/issues/auxiliary/issue-16725.rs | 4 + .../rustc/ui/issues/auxiliary/issue-17662.rs | 13 + .../ui/issues/auxiliary/issue-17718-aux.rs | 11 + .../auxiliary/issue-17718-const-privacy.rs | 9 + .../rustc/ui/issues/auxiliary/issue-18501.rs | 18 + .../rustc/ui/issues/auxiliary/issue-18514.rs | 18 + .../rustc/ui/issues/auxiliary/issue-18711.rs | 6 + .../ui/issues/auxiliary/issue-18913-1.rs | 7 + .../ui/issues/auxiliary/issue-18913-2.rs | 7 + .../rustc/ui/issues/auxiliary/issue-19163.rs | 7 + .../rustc/ui/issues/auxiliary/issue-1920.rs | 5 + .../rustc/ui/issues/auxiliary/issue-19293.rs | 5 + .../ui/issues/auxiliary/issue-19340-1.rs | 4 + .../rustc/ui/issues/auxiliary/issue-20389.rs | 5 + .../ui/issues/auxiliary/issue-21146-inc.rs | 4 + .../rustc/ui/issues/auxiliary/issue-21202.rs | 7 + .../ui/issues/auxiliary/issue-2170-lib.rs | 19 + .../rustc/ui/issues/auxiliary/issue-2316-a.rs | 4 + .../rustc/ui/issues/auxiliary/issue-2316-b.rs | 12 + .../rustc/ui/issues/auxiliary/issue-2380.rs | 16 + .../rustc/ui/issues/auxiliary/issue-2414-a.rs | 13 + .../rustc/ui/issues/auxiliary/issue-2414-b.rs | 5 + .../rustc/ui/issues/auxiliary/issue-2472-b.rs | 14 + .../ui/issues/auxiliary/issue-25185-1.rs | 9 + .../ui/issues/auxiliary/issue-25185-2.rs | 4 + .../rustc/ui/issues/auxiliary/issue-2526.rs | 45 + .../rustc/ui/issues/auxiliary/issue-25467.rs | 11 + .../rustc/ui/issues/auxiliary/issue-2631-a.rs | 15 + .../rustc/ui/issues/auxiliary/issue-2723-a.rs | 4 + .../rustc/ui/issues/auxiliary/issue-29181.rs | 6 + .../rustc/ui/issues/auxiliary/issue-29265.rs | 10 + .../rustc/ui/issues/auxiliary/issue-29485.rs | 17 + .../rustc/ui/issues/auxiliary/issue-3012-1.rs | 21 + .../ui/issues/auxiliary/issue-30123-aux.rs | 24 + .../rustc/ui/issues/auxiliary/issue-30535.rs | 6 + .../rustc/ui/issues/auxiliary/issue-3136-a.rs | 15 + .../ui/issues/auxiliary/issue-31702-1.rs | 17 + .../ui/issues/auxiliary/issue-31702-2.rs | 21 + .../ui/issues/auxiliary/issue-34796-aux.rs | 21 + .../rustc/ui/issues/auxiliary/issue-36708.rs | 6 + .../ui/issues/auxiliary/issue-36881-aux.rs | 2 + .../rustc/ui/issues/auxiliary/issue-36954.rs | 8 + .../rustc/ui/issues/auxiliary/issue-38190.rs | 3 + .../ui/issues/auxiliary/issue-38226-aux.rs | 24 + .../ui/issues/auxiliary/issue-3979-traits.rs | 16 + .../rustc/ui/issues/auxiliary/issue-39823.rs | 8 + .../rustc/ui/issues/auxiliary/issue-40469.rs | 2 + .../rustc/ui/issues/auxiliary/issue-41053.rs | 2 + .../rustc/ui/issues/auxiliary/issue-41394.rs | 17 + .../rustc/ui/issues/auxiliary/issue-41549.rs | 4 + .../ui/issues/auxiliary/issue-42007-s.rs | 5 + .../ui/issues/auxiliary/issue-4208-cc.rs | 11 + .../rustc/ui/issues/auxiliary/issue-4545.rs | 3 + .../ui/issues/auxiliary/issue-48984-aux.rs | 7 + .../rustc/ui/issues/auxiliary/issue-49544.rs | 8 + .../rustc/ui/issues/auxiliary/issue-51798.rs | 4 + .../rustc/ui/issues/auxiliary/issue-52489.rs | 4 + .../rustc/ui/issues/auxiliary/issue-52891.rs | 34 + .../rustc/ui/issues/auxiliary/issue-5518.rs | 5 + .../rustc/ui/issues/auxiliary/issue-5521.rs | 4 + .../rustc/ui/issues/auxiliary/issue-56943.rs | 4 + .../ui/issues/auxiliary/issue-57271-lib.rs | 12 + .../ui/issues/auxiliary/issue-5844-aux.rs | 4 + .../rustc/ui/issues/auxiliary/issue-59764.rs | 19 + .../rustc/ui/issues/auxiliary/issue-69725.rs | 9 + .../rustc/ui/issues/auxiliary/issue-7178.rs | 8 + .../rustc/ui/issues/auxiliary/issue-73112.rs | 11 + .../rustc/ui/issues/auxiliary/issue-75907.rs | 6 + .../rustc/ui/issues/auxiliary/issue-7899.rs | 2 + .../rustc/ui/issues/auxiliary/issue-8044.rs | 16 + .../rustc/ui/issues/auxiliary/issue-8259.rs | 5 + .../rustc/ui/issues/auxiliary/issue-8401.rs | 17 + .../rustc/ui/issues/auxiliary/issue-9123.rs | 10 + .../rustc/ui/issues/auxiliary/issue-9155.rs | 8 + .../rustc/ui/issues/auxiliary/issue-9188.rs | 14 + .../rustc/ui/issues/auxiliary/issue-9906.rs | 16 + .../rustc/ui/issues/auxiliary/issue-9968.rs | 23 + .../ui/issues/auxiliary/lint-stability.rs | 189 + .../ui/issues/auxiliary/private-trait-xc.rs | 2 + .../ui/issues/auxiliary/reexported-trait.rs | 18 + .../issues/auxiliary/xcrate-issue-43189-a.rs | 8 + .../issues/auxiliary/xcrate-issue-43189-b.rs | 4 + .../xcrate-issue-46112-rexport-core.rs | 4 + .../issues/auxiliary/xcrate-issue-61711-b.rs | 6 + .../rust/rustc/ui/issues/issue-10025.rs | 12 + .../rust/rustc/ui/issues/issue-10028.rs | 22 + .../rust/rustc/ui/issues/issue-10031.rs | 10 + .../rust/rustc/ui/issues/issue-10176.rs | 10 + .../rust/rustc/ui/issues/issue-10200.rs | 10 + .../rust/rustc/ui/issues/issue-10228.rs | 21 + .../rust/rustc/ui/issues/issue-10291.rs | 8 + .../rust/rustc/ui/issues/issue-10392.rs | 31 + .../rust/rustc/ui/issues/issue-10396.rs | 15 + .../rust/rustc/ui/issues/issue-10398.rs | 12 + .../rust/rustc/ui/issues/issue-10401.rs | 6 + .../rust/rustc/ui/issues/issue-10412.rs | 24 + .../rust/rustc/ui/issues/issue-10436.rs | 12 + .../rust/rustc/ui/issues/issue-10456.rs | 26 + .../rust/rustc/ui/issues/issue-10465.rs | 24 + .../rust/rustc/ui/issues/issue-10536.rs | 20 + .../rust/rustc/ui/issues/issue-10545.rs | 10 + .../rust/rustc/ui/issues/issue-10626.rs | 28 + .../rust/rustc/ui/issues/issue-10638.rs | 12 + .../rust/rustc/ui/issues/issue-10656.rs | 4 + .../rust/rustc/ui/issues/issue-10682.rs | 16 + .../rust/rustc/ui/issues/issue-10683.rs | 12 + .../rust/rustc/ui/issues/issue-10718.rs | 12 + .../rust/rustc/ui/issues/issue-10734.rs | 37 + .../rust/rustc/ui/issues/issue-10763.rs | 8 + .../rust/rustc/ui/issues/issue-10764-rpass.rs | 5 + .../rust/rustc/ui/issues/issue-10764.rs | 6 + .../rust/rustc/ui/issues/issue-10767.rs | 11 + .../rust/rustc/ui/issues/issue-10802.rs | 47 + .../rust/rustc/ui/issues/issue-10806.rs | 39 + .../rust/rustc/ui/issues/issue-10853.rs | 16 + .../rust/rustc/ui/issues/issue-10877.rs | 15 + .../rust/rustc/ui/issues/issue-10902.rs | 22 + .../rust/rustc/ui/issues/issue-10969.rs | 8 + .../rust/rustc/ui/issues/issue-10991.rs | 5 + .../rust/rustc/ui/issues/issue-11004.rs | 28 + .../rust/rustc/ui/issues/issue-11047.rs | 27 + .../rust/rustc/ui/issues/issue-11085.rs | 47 + .../rust/rustc/ui/issues/issue-1112.rs | 38 + .../rust/rustc/ui/issues/issue-11154.rs | 7 + .../rust/rustc/ui/issues/issue-11192.rs | 23 + .../rust/rustc/ui/issues/issue-11205.rs | 86 + .../rust/rustc/ui/issues/issue-11224.rs | 9 + .../rust/rustc/ui/issues/issue-11225-1.rs | 12 + .../rust/rustc/ui/issues/issue-11225-2.rs | 12 + .../rust/rustc/ui/issues/issue-11225-3.rs | 12 + .../rust/rustc/ui/issues/issue-11267.rs | 20 + .../rust/rustc/ui/issues/issue-11319.rs | 14 + .../rust/rustc/ui/issues/issue-11374.rs | 28 + .../rust/rustc/ui/issues/issue-11382.rs | 5 + .../rust/rustc/ui/issues/issue-11384.rs | 11 + .../rust/rustc/ui/issues/issue-11493.rs | 8 + .../rust/rustc/ui/issues/issue-11508.rs | 12 + .../rust/rustc/ui/issues/issue-11515.rs | 11 + .../rust/rustc/ui/issues/issue-11529.rs | 12 + .../rust/rustc/ui/issues/issue-11552.rs | 23 + .../rust/rustc/ui/issues/issue-11577.rs | 19 + .../rust/rustc/ui/issues/issue-11592.rs | 12 + .../rust/rustc/ui/issues/issue-11593.rs | 11 + .../rust/rustc/ui/issues/issue-11612.rs | 25 + .../rust/rustc/ui/issues/issue-11677.rs | 24 + .../rust/rustc/ui/issues/issue-11680.rs | 12 + .../rust/rustc/ui/issues/issue-11681.rs | 20 + .../rust/rustc/ui/issues/issue-11692-1.rs | 4 + .../rust/rustc/ui/issues/issue-11692-2.rs | 4 + .../rust/rustc/ui/issues/issue-11709.rs | 39 + .../rust/rustc/ui/issues/issue-11740.rs | 27 + .../rust/rustc/ui/issues/issue-11771.rs | 12 + .../rust/rustc/ui/issues/issue-11820.rs | 13 + .../rust/rustc/ui/issues/issue-11844.rs | 11 + .../rust/rustc/ui/issues/issue-11869.rs | 18 + .../rust/rustc/ui/issues/issue-11873.rs | 8 + .../rust/rustc/ui/issues/issue-11940.rs | 12 + .../rust/rustc/ui/issues/issue-11958.rs | 12 + .../rust/rustc/ui/issues/issue-12028.rs | 39 + .../rust/rustc/ui/issues/issue-12033.rs | 8 + .../rust/rustc/ui/issues/issue-12041.rs | 14 + .../rust/rustc/ui/issues/issue-12116.rs | 22 + .../rust/rustc/ui/issues/issue-12127.rs | 15 + .../rust/rustc/ui/issues/issue-12133-1.rs | 11 + .../rust/rustc/ui/issues/issue-12133-2.rs | 12 + .../rust/rustc/ui/issues/issue-12133-3.rs | 15 + .../rust/rustc/ui/issues/issue-12187-1.rs | 9 + .../rust/rustc/ui/issues/issue-12187-2.rs | 9 + .../rust/rustc/ui/issues/issue-12285.rs | 15 + .../rust/rustc/ui/issues/issue-12369.rs | 12 + .../rust/rustc/ui/issues/issue-12470.rs | 35 + .../rust/rustc/ui/issues/issue-1251.rs | 18 + .../rust/rustc/ui/issues/issue-12511.rs | 9 + .../rust/rustc/ui/issues/issue-12552.rs | 12 + .../rust/rustc/ui/issues/issue-12567.rs | 14 + .../rust/rustc/ui/issues/issue-1257.rs | 12 + .../rust/rustc/ui/issues/issue-12582.rs | 22 + .../rust/rustc/ui/issues/issue-12612.rs | 16 + .../rust/rustc/ui/issues/issue-12660.rs | 15 + .../rust/rustc/ui/issues/issue-12677.rs | 10 + .../rust/rustc/ui/issues/issue-12699.rs | 11 + .../rust/rustc/ui/issues/issue-12729.rs | 15 + .../rust/rustc/ui/issues/issue-12744.rs | 6 + .../rust/rustc/ui/issues/issue-12796.rs | 10 + .../rust/rustc/ui/issues/issue-12860.rs | 50 + .../rust/rustc/ui/issues/issue-12863.rs | 9 + .../rust/rustc/ui/issues/issue-12909.rs | 21 + .../rust/rustc/ui/issues/issue-12920.rs | 9 + .../rust/rustc/ui/issues/issue-12997-1.rs | 12 + .../rust/rustc/ui/issues/issue-12997-2.rs | 10 + .../rust/rustc/ui/issues/issue-13027.rs | 179 + .../rust/rustc/ui/issues/issue-13033.rs | 15 + .../rust/rustc/ui/issues/issue-13058.rs | 28 + .../rust/rustc/ui/issues/issue-13105.rs | 10 + .../rust/rustc/ui/issues/issue-13167.rs | 23 + .../rust/rustc/ui/issues/issue-13202.rs | 8 + .../rust/rustc/ui/issues/issue-13204.rs | 26 + .../rust/rustc/ui/issues/issue-13214.rs | 24 + .../issues/issue-13259-windows-tcb-trash.rs | 43 + .../rust/rustc/ui/issues/issue-13264.rs | 75 + .../rust/rustc/ui/issues/issue-13304.rs | 41 + .../rust/rustc/ui/issues/issue-13323.rs | 60 + .../rust/rustc/ui/issues/issue-13359.rs | 14 + .../rust/rustc/ui/issues/issue-13404.rs | 11 + .../rust/rustc/ui/issues/issue-13405.rs | 21 + .../rust/rustc/ui/issues/issue-13407.rs | 11 + .../rust/rustc/ui/issues/issue-13434.rs | 22 + .../rust/rustc/ui/issues/issue-13446.rs | 7 + .../rust/rustc/ui/issues/issue-13466.rs | 21 + .../rust/rustc/ui/issues/issue-13482-2.rs | 10 + .../rust/rustc/ui/issues/issue-13482.rs | 8 + .../rust/rustc/ui/issues/issue-13483.rs | 18 + .../rust/rustc/ui/issues/issue-13497-2.rs | 8 + .../rust/rustc/ui/issues/issue-13497.rs | 9 + .../rust/rustc/ui/issues/issue-13507-2.rs | 37 + .../rust/rustc/ui/issues/issue-1362.rs | 9 + .../rust/rustc/ui/issues/issue-13620.rs | 12 + .../rust/rustc/ui/issues/issue-13641.rs | 14 + .../rust/rustc/ui/issues/issue-13655.rs | 33 + .../rust/rustc/ui/issues/issue-13665.rs | 16 + .../rust/rustc/ui/issues/issue-13703.rs | 7 + .../rust/rustc/ui/issues/issue-13727.rs | 16 + .../rust/rustc/ui/issues/issue-13763.rs | 16 + .../rust/rustc/ui/issues/issue-13775.rs | 10 + .../rust/rustc/ui/issues/issue-13808.rs | 19 + .../rust/rustc/ui/issues/issue-13837.rs | 14 + .../rust/rustc/ui/issues/issue-13847.rs | 4 + .../rust/rustc/ui/issues/issue-13853-2.rs | 7 + .../rust/rustc/ui/issues/issue-13853-5.rs | 14 + .../rust/rustc/ui/issues/issue-13853.rs | 39 + .../rust/rustc/ui/issues/issue-13867.rs | 49 + .../rust/rustc/ui/issues/issue-13872.rs | 13 + .../rust/rustc/ui/issues/issue-13902.rs | 17 + .../rust/rustc/ui/issues/issue-14082.rs | 21 + .../rust/rustc/ui/issues/issue-14091-2.rs | 18 + .../rust/rustc/ui/issues/issue-14091.rs | 5 + .../rust/rustc/ui/issues/issue-14092.rs | 5 + .../rust/rustc/ui/issues/issue-14221.rs | 22 + .../rust/rustc/ui/issues/issue-14227.rs | 8 + .../rust/rustc/ui/issues/issue-14229.rs | 22 + .../rust/rustc/ui/issues/issue-14254.rs | 94 + .../rust/rustc/ui/issues/issue-14285.rs | 18 + .../rust/rustc/ui/issues/issue-14308.rs | 16 + .../rust/rustc/ui/issues/issue-14309.rs | 40 + .../rust/rustc/ui/issues/issue-14330.rs | 8 + .../rust/rustc/ui/issues/issue-14344.rs | 12 + .../rust/rustc/ui/issues/issue-14366.rs | 5 + .../rust/rustc/ui/issues/issue-14382.rs | 16 + .../rust/rustc/ui/issues/issue-14393.rs | 11 + .../rust/rustc/ui/issues/issue-14399.rs | 21 + .../rust/rustc/ui/issues/issue-14421.rs | 17 + .../rust/rustc/ui/issues/issue-14422.rs | 17 + .../rust/rustc/ui/issues/issue-14456.rs | 39 + .../rust/rustc/ui/issues/issue-1448-2.rs | 8 + .../rust/rustc/ui/issues/issue-1451.rs | 28 + .../rust/rustc/ui/issues/issue-14541.rs | 11 + .../rust/rustc/ui/issues/issue-14589.rs | 25 + .../rust/rustc/ui/issues/issue-1460.rs | 8 + .../rust/rustc/ui/issues/issue-14721.rs | 5 + .../rust/rustc/ui/issues/issue-1476.rs | 4 + .../rust/rustc/ui/issues/issue-14772.rs | 7 + .../rust/rustc/ui/issues/issue-14821.rs | 22 + .../rust/rustc/ui/issues/issue-14837.rs | 12 + .../rust/rustc/ui/issues/issue-14845.rs | 12 + .../rust/rustc/ui/issues/issue-14853.rs | 21 + .../rust/rustc/ui/issues/issue-14865.rs | 24 + .../rust/rustc/ui/issues/issue-14875.rs | 36 + .../rust/rustc/ui/issues/issue-14901.rs | 19 + .../rust/rustc/ui/issues/issue-14915.rs | 9 + .../rust/rustc/ui/issues/issue-14919.rs | 56 + .../rust/rustc/ui/issues/issue-14933.rs | 7 + .../rust/rustc/ui/issues/issue-14936.rs | 49 + .../rust/rustc/ui/issues/issue-14940.rs | 21 + .../rust/rustc/ui/issues/issue-14958.rs | 32 + .../rust/rustc/ui/issues/issue-14959.rs | 56 + .../rust/rustc/ui/issues/issue-15034.rs | 23 + .../rust/rustc/ui/issues/issue-15043.rs | 15 + .../rust/rustc/ui/issues/issue-15063.rs | 13 + .../rust/rustc/ui/issues/issue-15080.rs | 23 + .../rust/rustc/ui/issues/issue-15094.rs | 27 + .../rust/rustc/ui/issues/issue-15104.rs | 14 + .../rust/rustc/ui/issues/issue-15129-rpass.rs | 26 + .../rust/rustc/ui/issues/issue-15129.rs | 18 + .../rust/rustc/ui/issues/issue-15155.rs | 22 + .../rust/rustc/ui/issues/issue-15167.rs | 27 + .../rust/rustc/ui/issues/issue-15189.rs | 11 + .../rust/rustc/ui/issues/issue-15207.rs | 7 + .../rust/rustc/ui/issues/issue-15221.rs | 17 + .../rust/rustc/ui/issues/issue-15260.rs | 26 + .../rust/rustc/ui/issues/issue-15261.rs | 12 + .../rust/rustc/ui/issues/issue-15381.rs | 9 + .../rust/rustc/ui/issues/issue-15444.rs | 24 + .../rust/rustc/ui/issues/issue-15487.rs | 15 + .../rust/rustc/ui/issues/issue-15523-big.rs | 40 + .../rust/rustc/ui/issues/issue-15523.rs | 43 + .../rust/rustc/ui/issues/issue-15524.rs | 17 + .../rust/rustc/ui/issues/issue-15562.rs | 20 + .../rust/rustc/ui/issues/issue-15571.rs | 59 + .../rust/rustc/ui/issues/issue-15673.rs | 10 + .../rust/rustc/ui/issues/issue-15689-1.rs | 11 + .../rust/rustc/ui/issues/issue-15689-2.rs | 11 + .../rust/rustc/ui/issues/issue-15730.rs | 10 + .../rust/rustc/ui/issues/issue-15734.rs | 59 + .../rust/rustc/ui/issues/issue-15735.rs | 18 + .../rust/rustc/ui/issues/issue-15756.rs | 15 + .../rust/rustc/ui/issues/issue-15763.rs | 90 + .../rust/rustc/ui/issues/issue-15774.rs | 26 + .../rust/rustc/ui/issues/issue-15783.rs | 15 + .../rust/rustc/ui/issues/issue-15793.rs | 28 + .../rust/rustc/ui/issues/issue-15858.rs | 34 + .../issue-15881-model-lexer-dotdotdot.rs | 39 + .../rust/rustc/ui/issues/issue-15896.rs | 16 + .../rust/rustc/ui/issues/issue-15919-32.rs | 14 + .../rust/rustc/ui/issues/issue-15919-64.rs | 14 + .../rust/rustc/ui/issues/issue-15965.rs | 8 + .../rust/rustc/ui/issues/issue-16048.rs | 31 + .../rust/rustc/ui/issues/issue-16098.rs | 17 + .../rust/rustc/ui/issues/issue-16149.rs | 12 + .../rust/rustc/ui/issues/issue-16151.rs | 30 + .../rust/rustc/ui/issues/issue-16250.rs | 11 + .../rust/rustc/ui/issues/issue-16256.rs | 8 + .../rust/rustc/ui/issues/issue-16272.rs | 25 + .../rust/rustc/ui/issues/issue-16278.rs | 11 + .../rust/rustc/ui/issues/issue-16338.rs | 11 + .../rust/rustc/ui/issues/issue-16401.rs | 16 + .../rust/rustc/ui/issues/issue-16441.rs | 13 + .../rust/rustc/ui/issues/issue-16452.rs | 11 + .../rust/rustc/ui/issues/issue-16492.rs | 68 + .../rust/rustc/ui/issues/issue-16530.rs | 16 + .../rust/rustc/ui/issues/issue-16538.rs | 17 + .../rust/rustc/ui/issues/issue-16560.rs | 19 + .../rust/rustc/ui/issues/issue-16562.rs | 18 + .../rust/rustc/ui/issues/issue-16596.rs | 23 + .../rust/rustc/ui/issues/issue-16597-empty.rs | 6 + .../rust/rustc/ui/issues/issue-16597.rs | 11 + .../rust/rustc/ui/issues/issue-1660.rs | 9 + .../rust/rustc/ui/issues/issue-16602-1.rs | 7 + .../rust/rustc/ui/issues/issue-16602-2.rs | 13 + .../rust/rustc/ui/issues/issue-16602-3.rs | 28 + .../rust/rustc/ui/issues/issue-16643.rs | 11 + .../rust/rustc/ui/issues/issue-16648.rs | 12 + .../rust/rustc/ui/issues/issue-16668.rs | 21 + .../rust/rustc/ui/issues/issue-16671.rs | 13 + .../rust/rustc/ui/issues/issue-16683.rs | 9 + .../rust/rustc/ui/issues/issue-16725.rs | 9 + .../rust/rustc/ui/issues/issue-16739.rs | 47 + .../rust/rustc/ui/issues/issue-16745.rs | 12 + .../rust/rustc/ui/issues/issue-16774.rs | 47 + .../rust/rustc/ui/issues/issue-16783.rs | 9 + .../rust/rustc/ui/issues/issue-16819.rs | 13 + .../rust/rustc/ui/issues/issue-16922-rpass.rs | 12 + .../rust/rustc/ui/issues/issue-16922.rs | 10 + .../rust/rustc/ui/issues/issue-16939.rs | 9 + .../rust/rustc/ui/issues/issue-1696.rs | 9 + .../rust/rustc/ui/issues/issue-16966.rs | 5 + .../rust/rustc/ui/issues/issue-1697.rs | 7 + .../rust/rustc/ui/issues/issue-16994.rs | 10 + .../rust/rustc/ui/issues/issue-17001.rs | 6 + .../rust/rustc/ui/issues/issue-1701.rs | 27 + .../rust/rustc/ui/issues/issue-17033.rs | 7 + .../rust/rustc/ui/issues/issue-17068.rs | 13 + .../rust/rustc/ui/issues/issue-17074.rs | 16 + .../rust/rustc/ui/issues/issue-17121.rs | 33 + .../rust/rustc/ui/issues/issue-17170.rs | 12 + .../rust/rustc/ui/issues/issue-17216.rs | 22 + .../rust/rustc/ui/issues/issue-17233.rs | 18 + .../rust/rustc/ui/issues/issue-17252.rs | 11 + .../rust/rustc/ui/issues/issue-17263.rs | 26 + .../rust/rustc/ui/issues/issue-17302.rs | 27 + .../rust/rustc/ui/issues/issue-17322.rs | 16 + .../rust/rustc/ui/issues/issue-17336.rs | 10 + .../rust/rustc/ui/issues/issue-17337.rs | 18 + .../rust/rustc/ui/issues/issue-17351.rs | 11 + .../rust/rustc/ui/issues/issue-17361.rs | 10 + .../rust/rustc/ui/issues/issue-17373.rs | 5 + .../rust/rustc/ui/issues/issue-17385.rs | 30 + .../rust/rustc/ui/issues/issue-17405.rs | 10 + .../rust/rustc/ui/issues/issue-17431-1.rs | 7 + .../rust/rustc/ui/issues/issue-17431-2.rs | 10 + .../rust/rustc/ui/issues/issue-17431-3.rs | 9 + .../rust/rustc/ui/issues/issue-17431-4.rs | 9 + .../rust/rustc/ui/issues/issue-17431-5.rs | 12 + .../rust/rustc/ui/issues/issue-17431-6.rs | 9 + .../rust/rustc/ui/issues/issue-17431-7.rs | 7 + .../rust/rustc/ui/issues/issue-17441.rs | 14 + .../rust/rustc/ui/issues/issue-17444.rs | 9 + .../rust/rustc/ui/issues/issue-17450.rs | 8 + .../rust/rustc/ui/issues/issue-17458.rs | 7 + .../rust/rustc/ui/issues/issue-17503.rs | 11 + .../rust/rustc/ui/issues/issue-17545.rs | 11 + .../rust/rustc/ui/issues/issue-17546.rs | 43 + .../rust/rustc/ui/issues/issue-17551.rs | 9 + .../rust/rustc/ui/issues/issue-17651.rs | 9 + .../rust/rustc/ui/issues/issue-17662.rs | 18 + .../ui/issues/issue-17718-borrow-interior.rs | 20 + .../ui/issues/issue-17718-const-bad-values.rs | 11 + .../ui/issues/issue-17718-const-borrow.rs | 15 + .../issues/issue-17718-const-destructors.rs | 11 + .../ui/issues/issue-17718-const-naming.rs | 9 + .../ui/issues/issue-17718-const-privacy.rs | 17 + .../issue-17718-constants-not-static.rs | 10 + .../ui/issues/issue-17718-parse-const.rs | 8 + .../rustc/ui/issues/issue-17718-patterns.rs | 13 + .../rustc/ui/issues/issue-17718-references.rs | 25 + .../ui/issues/issue-17718-static-move.rs | 8 + .../ui/issues/issue-17718-static-sync.rs | 13 + .../issue-17718-static-unsafe-interior.rs | 53 + .../rust/rustc/ui/issues/issue-17718.rs | 76 + .../rust/rustc/ui/issues/issue-17728.rs | 124 + .../rust/rustc/ui/issues/issue-17732.rs | 14 + .../rust/rustc/ui/issues/issue-17734.rs | 16 + .../rust/rustc/ui/issues/issue-17740.rs | 19 + .../rust/rustc/ui/issues/issue-17746.rs | 26 + .../rust/rustc/ui/issues/issue-17756.rs | 9 + .../rust/rustc/ui/issues/issue-17758.rs | 13 + .../rust/rustc/ui/issues/issue-17771.rs | 22 + .../rust/rustc/ui/issues/issue-17800.rs | 13 + .../rust/rustc/ui/issues/issue-17816.rs | 11 + .../rust/rustc/ui/issues/issue-17877.rs | 14 + .../rust/rustc/ui/issues/issue-17897.rs | 9 + .../rust/rustc/ui/issues/issue-17904-2.rs | 7 + .../rust/rustc/ui/issues/issue-17904.rs | 15 + .../rust/rustc/ui/issues/issue-17905-2.rs | 19 + .../rust/rustc/ui/issues/issue-17905.rs | 19 + .../rust/rustc/ui/issues/issue-17913.rs | 24 + .../rust/rustc/ui/issues/issue-17933.rs | 10 + .../rust/rustc/ui/issues/issue-17954.rs | 16 + .../rust/rustc/ui/issues/issue-17959.rs | 22 + .../rust/rustc/ui/issues/issue-17994.rs | 4 + .../rust/rustc/ui/issues/issue-17999.rs | 11 + .../rust/rustc/ui/issues/issue-18058.rs | 5 + .../rust/rustc/ui/issues/issue-18060.rs | 9 + .../rust/rustc/ui/issues/issue-18083.rs | 26 + .../rust/rustc/ui/issues/issue-18088.rs | 9 + .../rust/rustc/ui/issues/issue-18107.rs | 14 + .../rust/rustc/ui/issues/issue-18110.rs | 8 + .../rust/rustc/ui/issues/issue-18118-2.rs | 7 + .../rust/rustc/ui/issues/issue-18118.rs | 7 + .../rust/rustc/ui/issues/issue-18119.rs | 13 + .../rust/rustc/ui/issues/issue-18159.rs | 4 + .../rust/rustc/ui/issues/issue-18173.rs | 13 + .../rust/rustc/ui/issues/issue-18183.rs | 4 + .../rust/rustc/ui/issues/issue-18188.rs | 23 + .../rust/rustc/ui/issues/issue-1821.rs | 14 + .../rust/rustc/ui/issues/issue-18232.rs | 23 + .../rust/rustc/ui/issues/issue-18294.rs | 6 + .../rust/rustc/ui/issues/issue-18352.rs | 15 + .../rust/rustc/ui/issues/issue-18353.rs | 16 + .../rust/rustc/ui/issues/issue-18389.rs | 19 + .../rust/rustc/ui/issues/issue-18400.rs | 27 + .../rust/rustc/ui/issues/issue-18412.rs | 27 + .../rust/rustc/ui/issues/issue-18423.rs | 9 + .../rust/rustc/ui/issues/issue-18425.rs | 10 + .../rust/rustc/ui/issues/issue-18446-2.rs | 14 + .../rust/rustc/ui/issues/issue-18446.rs | 20 + .../rust/rustc/ui/issues/issue-18464.rs | 13 + .../rust/rustc/ui/issues/issue-18501.rs | 14 + .../rust/rustc/ui/issues/issue-18514.rs | 17 + .../rust/rustc/ui/issues/issue-18532.rs | 8 + .../rust/rustc/ui/issues/issue-18539.rs | 17 + .../rust/rustc/ui/issues/issue-18566.rs | 26 + .../rust/rustc/ui/issues/issue-18576.rs | 17 + .../rust/rustc/ui/issues/issue-18611.rs | 10 + .../rust/rustc/ui/issues/issue-18652.rs | 11 + .../rust/rustc/ui/issues/issue-18655.rs | 23 + .../rust/rustc/ui/issues/issue-1866.rs | 30 + .../rust/rustc/ui/issues/issue-18661.rs | 20 + .../rust/rustc/ui/issues/issue-18685.rs | 22 + .../rust/rustc/ui/issues/issue-1871.rs | 13 + .../rust/rustc/ui/issues/issue-18711.rs | 13 + .../rust/rustc/ui/issues/issue-18738.rs | 18 + .../rust/rustc/ui/issues/issue-18767.rs | 11 + .../rust/rustc/ui/issues/issue-18783.rs | 29 + .../ui/issues/issue-18804/auxiliary/lib.rs | 11 + .../rust/rustc/ui/issues/issue-18804/main.rs | 20 + .../rust/rustc/ui/issues/issue-18809.rs | 13 + .../rust/rustc/ui/issues/issue-18819.rs | 19 + .../rust/rustc/ui/issues/issue-18845.rs | 17 + .../rust/rustc/ui/issues/issue-18859.rs | 17 + .../rust/rustc/ui/issues/issue-18906.rs | 31 + .../rust/rustc/ui/issues/issue-18913.rs | 10 + .../rust/rustc/ui/issues/issue-18919.rs | 13 + .../rust/rustc/ui/issues/issue-18937-1.rs | 22 + .../rust/rustc/ui/issues/issue-18937.rs | 41 + .../rust/rustc/ui/issues/issue-18952.rs | 57 + .../rust/rustc/ui/issues/issue-18959.rs | 21 + .../rust/rustc/ui/issues/issue-18988.rs | 12 + .../rust/rustc/ui/issues/issue-1900.rs | 3 + .../rust/rustc/ui/issues/issue-19001.rs | 12 + .../rust/rustc/ui/issues/issue-19037.rs | 21 + .../rust/rustc/ui/issues/issue-19081.rs | 15 + .../rust/rustc/ui/issues/issue-19086.rs | 14 + .../rust/rustc/ui/issues/issue-19097.rs | 15 + .../rust/rustc/ui/issues/issue-19098.rs | 13 + .../rust/rustc/ui/issues/issue-19100.rs | 31 + .../rust/rustc/ui/issues/issue-19102.rs | 13 + .../rust/rustc/ui/issues/issue-19127.rs | 11 + .../rust/rustc/ui/issues/issue-19129-1.rs | 17 + .../rust/rustc/ui/issues/issue-19129-2.rs | 12 + .../rust/rustc/ui/issues/issue-19135.rs | 14 + .../rust/rustc/ui/issues/issue-19163.rs | 12 + .../rust/rustc/ui/issues/issue-1920-1.rs | 15 + .../rust/rustc/ui/issues/issue-1920-2.rs | 13 + .../rust/rustc/ui/issues/issue-1920-3.rs | 17 + .../rust/rustc/ui/issues/issue-19244-1.rs | 7 + .../rust/rustc/ui/issues/issue-19244-2.rs | 8 + .../rust/rustc/ui/issues/issue-19244.rs | 35 + .../rust/rustc/ui/issues/issue-19293.rs | 11 + .../rust/rustc/ui/issues/issue-19340-1.rs | 18 + .../rust/rustc/ui/issues/issue-19340-2.rs | 25 + .../rust/rustc/ui/issues/issue-19358.rs | 21 + .../rust/rustc/ui/issues/issue-19367.rs | 33 + .../rust/rustc/ui/issues/issue-19380.rs | 19 + .../rust/rustc/ui/issues/issue-19398.rs | 13 + .../rust/rustc/ui/issues/issue-19404.rs | 38 + .../rust/rustc/ui/issues/issue-19479.rs | 20 + .../rust/rustc/ui/issues/issue-19482.rs | 14 + .../rust/rustc/ui/issues/issue-19498.rs | 14 + .../rust/rustc/ui/issues/issue-19499.rs | 16 + .../rust/rustc/ui/issues/issue-19521.rs | 4 + .../rust/rustc/ui/issues/issue-19538.rs | 21 + .../rust/rustc/ui/issues/issue-19601.rs | 7 + .../rust/rustc/ui/issues/issue-1962.rs | 11 + .../rust/rustc/ui/issues/issue-19631.rs | 17 + .../rust/rustc/ui/issues/issue-19632.rs | 15 + .../rust/rustc/ui/issues/issue-19660.rs | 16 + .../rust/rustc/ui/issues/issue-19692.rs | 9 + .../rust/rustc/ui/issues/issue-19707.rs | 8 + .../rust/rustc/ui/issues/issue-19734.rs | 9 + .../rust/rustc/ui/issues/issue-1974.rs | 12 + .../ui/issues/issue-19811-escape-unicode.rs | 10 + .../rust/rustc/ui/issues/issue-19850.rs | 23 + .../rust/rustc/ui/issues/issue-19883.rs | 17 + .../rust/rustc/ui/issues/issue-19922.rs | 9 + .../rust/rustc/ui/issues/issue-19982.rs | 23 + .../rust/rustc/ui/issues/issue-19991.rs | 10 + .../rust/rustc/ui/issues/issue-20005.rs | 16 + .../rust/rustc/ui/issues/issue-20009.rs | 14 + .../rustc/ui/issues/issue-20055-box-trait.rs | 42 + .../issues/issue-20055-box-unsized-array.rs | 30 + .../rust/rustc/ui/issues/issue-20091.rs | 26 + .../rust/rustc/ui/issues/issue-20162.rs | 8 + .../rust/rustc/ui/issues/issue-20174.rs | 8 + .../rust/rustc/ui/issues/issue-20186.rs | 17 + .../rust/rustc/ui/issues/issue-20225.rs | 23 + .../rust/rustc/ui/issues/issue-20261.rs | 8 + .../rust/rustc/ui/issues/issue-20313-rpass.rs | 14 + .../rust/rustc/ui/issues/issue-20313.rs | 8 + .../rust/rustc/ui/issues/issue-20343.rs | 33 + .../rust/rustc/ui/issues/issue-20389.rs | 16 + .../rust/rustc/ui/issues/issue-20396.rs | 17 + .../rust/rustc/ui/issues/issue-20413.rs | 17 + .../rust/rustc/ui/issues/issue-20414.rs | 22 + .../rust/rustc/ui/issues/issue-20427.rs | 89 + .../rust/rustc/ui/issues/issue-20433.rs | 9 + .../rust/rustc/ui/issues/issue-20454.rs | 14 + .../rust/rustc/ui/issues/issue-20544.rs | 19 + .../rust/rustc/ui/issues/issue-20575.rs | 11 + .../rust/rustc/ui/issues/issue-20605.rs | 7 + .../rust/rustc/ui/issues/issue-20616-1.rs | 37 + .../rust/rustc/ui/issues/issue-20616-2.rs | 37 + .../rust/rustc/ui/issues/issue-20616-3.rs | 36 + .../rust/rustc/ui/issues/issue-20616-4.rs | 36 + .../rust/rustc/ui/issues/issue-20616-5.rs | 36 + .../rust/rustc/ui/issues/issue-20616-6.rs | 36 + .../rust/rustc/ui/issues/issue-20616-7.rs | 36 + .../rust/rustc/ui/issues/issue-20616-8.rs | 36 + .../rust/rustc/ui/issues/issue-20616-9.rs | 36 + .../rust/rustc/ui/issues/issue-20616.rs | 45 + .../rustc/ui/issues/issue-2063-resource.rs | 15 + .../rust/rustc/ui/issues/issue-2063.rs | 23 + .../rust/rustc/ui/issues/issue-20644.rs | 36 + .../rust/rustc/ui/issues/issue-20676.rs | 13 + .../rust/rustc/ui/issues/issue-20692.rs | 12 + .../rust/rustc/ui/issues/issue-20714.rs | 6 + .../rust/rustc/ui/issues/issue-2074.rs | 17 + .../rust/rustc/ui/issues/issue-20763-1.rs | 30 + .../rust/rustc/ui/issues/issue-20763-2.rs | 25 + .../rust/rustc/ui/issues/issue-20772.rs | 6 + .../rust/rustc/ui/issues/issue-20797.rs | 95 + .../rust/rustc/ui/issues/issue-20801.rs | 38 + .../rust/rustc/ui/issues/issue-20803.rs | 11 + .../rust/rustc/ui/issues/issue-20823.rs | 6 + .../rust/rustc/ui/issues/issue-20825-2.rs | 11 + .../rust/rustc/ui/issues/issue-20825.rs | 11 + .../rustc/ui/issues/issue-20831-debruijn.rs | 40 + .../rust/rustc/ui/issues/issue-20847.rs | 13 + .../rust/rustc/ui/issues/issue-20939.rs | 7 + .../rust/rustc/ui/issues/issue-20953.rs | 13 + .../rust/rustc/ui/issues/issue-20971.rs | 24 + .../rust/rustc/ui/issues/issue-21033.rs | 50 + .../rust/rustc/ui/issues/issue-21058.rs | 65 + .../rust/rustc/ui/issues/issue-2111.rs | 13 + .../rust/rustc/ui/issues/issue-21140.rs | 7 + .../rust/rustc/ui/issues/issue-21146.rs | 4 + .../rust/rustc/ui/issues/issue-21160.rs | 12 + .../rust/rustc/ui/issues/issue-21174-2.rs | 14 + .../rust/rustc/ui/issues/issue-21174.rs | 12 + .../rust/rustc/ui/issues/issue-21177.rs | 10 + .../rust/rustc/ui/issues/issue-21202.rs | 16 + .../rust/rustc/ui/issues/issue-21245.rs | 57 + .../rust/rustc/ui/issues/issue-21291.rs | 11 + .../rust/rustc/ui/issues/issue-21306.rs | 10 + .../rust/rustc/ui/issues/issue-21332.rs | 11 + .../rust/rustc/ui/issues/issue-21356.rs | 7 + .../rust/rustc/ui/issues/issue-21361.rs | 12 + .../rust/rustc/ui/issues/issue-21363.rs | 16 + .../rust/rustc/ui/issues/issue-21384.rs | 22 + .../rust/rustc/ui/issues/issue-21400.rs | 57 + .../rust/rustc/ui/issues/issue-21402.rs | 13 + .../rust/rustc/ui/issues/issue-21449.rs | 7 + .../rust/rustc/ui/issues/issue-21475.rs | 20 + .../rust/rustc/ui/issues/issue-21486.rs | 78 + .../rust/rustc/ui/issues/issue-2150.rs | 13 + .../rust/rustc/ui/issues/issue-2151.rs | 5 + .../rust/rustc/ui/issues/issue-21520.rs | 23 + .../rust/rustc/ui/issues/issue-21546.rs | 50 + .../rust/rustc/ui/issues/issue-21554.rs | 7 + .../rust/rustc/ui/issues/issue-21562.rs | 20 + .../rust/rustc/ui/issues/issue-21596.rs | 6 + .../rust/rustc/ui/issues/issue-21600.rs | 19 + .../rust/rustc/ui/issues/issue-21622.rs | 22 + .../rust/rustc/ui/issues/issue-21634.rs | 21 + .../rust/rustc/ui/issues/issue-21655.rs | 13 + .../rust/rustc/ui/issues/issue-2170-exe.rs | 10 + .../rust/rustc/ui/issues/issue-21701.rs | 16 + .../rust/rustc/ui/issues/issue-21721.rs | 10 + .../rust/rustc/ui/issues/issue-21726.rs | 39 + .../rust/rustc/ui/issues/issue-21763.rs | 12 + .../rust/rustc/ui/issues/issue-21837.rs | 11 + .../rust/rustc/ui/issues/issue-21891.rs | 13 + .../rust/rustc/ui/issues/issue-2190-1.rs | 27 + .../rust/rustc/ui/issues/issue-21909.rs | 16 + .../rust/rustc/ui/issues/issue-21922.rs | 18 + .../rust/rustc/ui/issues/issue-21946.rs | 13 + .../rust/rustc/ui/issues/issue-21950.rs | 14 + .../rust/rustc/ui/issues/issue-21974.rs | 19 + .../rust/rustc/ui/issues/issue-22008.rs | 10 + .../rust/rustc/ui/issues/issue-22034.rs | 12 + .../rust/rustc/ui/issues/issue-22036.rs | 26 + .../rust/rustc/ui/issues/issue-22037.rs | 18 + .../rust/rustc/ui/issues/issue-22066.rs | 13 + .../rust/rustc/ui/issues/issue-2214.rs | 44 + .../rust/rustc/ui/issues/issue-2216.rs | 25 + .../rust/rustc/ui/issues/issue-22258.rs | 11 + .../rust/rustc/ui/issues/issue-22289.rs | 4 + .../rust/rustc/ui/issues/issue-22312.rs | 18 + .../rust/rustc/ui/issues/issue-22346.rs | 12 + .../rust/rustc/ui/issues/issue-22356.rs | 35 + .../rust/rustc/ui/issues/issue-22370.rs | 7 + .../rust/rustc/ui/issues/issue-22375.rs | 5 + .../rust/rustc/ui/issues/issue-22384.rs | 9 + .../rust/rustc/ui/issues/issue-22403.rs | 7 + .../rust/rustc/ui/issues/issue-22426.rs | 10 + .../rust/rustc/ui/issues/issue-22434.rs | 9 + .../rust/rustc/ui/issues/issue-22463.rs | 21 + .../rust/rustc/ui/issues/issue-22468.rs | 10 + .../rust/rustc/ui/issues/issue-22471.rs | 8 + .../ui/issues/issue-22536-copy-mustnt-zero.rs | 29 + .../rust/rustc/ui/issues/issue-22546.rs | 53 + .../rust/rustc/ui/issues/issue-22560.rs | 16 + .../rust/rustc/ui/issues/issue-22577.rs | 28 + .../rust/rustc/ui/issues/issue-22599.rs | 11 + .../rust/rustc/ui/issues/issue-22603.rs | 16 + .../rust/rustc/ui/issues/issue-22629.rs | 15 + .../rust/rustc/ui/issues/issue-22638.rs | 64 + .../rust/rustc/ui/issues/issue-22644.rs | 36 + .../rust/rustc/ui/issues/issue-22673.rs | 7 + .../rust/rustc/ui/issues/issue-22684.rs | 19 + .../rust/rustc/ui/issues/issue-22706.rs | 4 + .../rust/rustc/ui/issues/issue-22777.rs | 49 + .../rust/rustc/ui/issues/issue-22781.rs | 16 + .../rust/rustc/ui/issues/issue-22789.rs | 9 + .../rust/rustc/ui/issues/issue-2281-part1.rs | 2 + .../rust/rustc/ui/issues/issue-22814.rs | 14 + .../rust/rustc/ui/issues/issue-22828.rs | 24 + .../rust/rustc/ui/issues/issue-2284.rs | 15 + .../rust/rustc/ui/issues/issue-22864-1.rs | 8 + .../rust/rustc/ui/issues/issue-22864-2.rs | 8 + .../rust/rustc/ui/issues/issue-22872.rs | 25 + .../rust/rustc/ui/issues/issue-22874.rs | 11 + .../rust/rustc/ui/issues/issue-2288.rs | 36 + .../rust/rustc/ui/issues/issue-22886.rs | 22 + .../rust/rustc/ui/issues/issue-22894.rs | 5 + .../rust/rustc/ui/issues/issue-22933-1.rs | 24 + .../rust/rustc/ui/issues/issue-22933-2.rs | 9 + .../rust/rustc/ui/issues/issue-22992-2.rs | 19 + .../rust/rustc/ui/issues/issue-22992.rs | 77 + .../rust/rustc/ui/issues/issue-23024.rs | 14 + .../rust/rustc/ui/issues/issue-23036.rs | 12 + .../rust/rustc/ui/issues/issue-23041.rs | 8 + .../rust/rustc/ui/issues/issue-23046.rs | 21 + .../rust/rustc/ui/issues/issue-23073.rs | 10 + .../rust/rustc/ui/issues/issue-2311-2.rs | 27 + .../rust/rustc/ui/issues/issue-2311.rs | 12 + .../rust/rustc/ui/issues/issue-2312.rs | 17 + .../rust/rustc/ui/issues/issue-23122-1.rs | 15 + .../rust/rustc/ui/issues/issue-23122-2.rs | 14 + .../rust/rustc/ui/issues/issue-2316-c.rs | 13 + .../rust/rustc/ui/issues/issue-23173.rs | 14 + .../rust/rustc/ui/issues/issue-23189.rs | 6 + .../rust/rustc/ui/issues/issue-23208.rs | 27 + .../rust/rustc/ui/issues/issue-23217.rs | 6 + .../rust/rustc/ui/issues/issue-23253.rs | 7 + .../rust/rustc/ui/issues/issue-23261.rs | 62 + .../rust/rustc/ui/issues/issue-23281.rs | 13 + .../rust/rustc/ui/issues/issue-2330.rs | 14 + .../rust/rustc/ui/issues/issue-23302-1.rs | 8 + .../rust/rustc/ui/issues/issue-23302-2.rs | 9 + .../rust/rustc/ui/issues/issue-23302-3.rs | 6 + .../rust/rustc/ui/issues/issue-23304-1.rs | 26 + .../rust/rustc/ui/issues/issue-23304-2.rs | 14 + .../rust/rustc/ui/issues/issue-23311.rs | 12 + .../rust/rustc/ui/issues/issue-23336.rs | 12 + .../issue-23338-ensure-param-drop-order.rs | 165 + ...ssue-23338-params-outlive-temps-of-body.rs | 31 + .../rust/rustc/ui/issues/issue-23354-2.rs | 10 + .../rust/rustc/ui/issues/issue-23354.rs | 9 + .../rust/rustc/ui/issues/issue-23406.rs | 16 + .../rust/rustc/ui/issues/issue-23433.rs | 14 + .../rust/rustc/ui/issues/issue-23442.rs | 24 + .../rust/rustc/ui/issues/issue-23458.rs | 12 + .../rust/rustc/ui/issues/issue-23477.rs | 17 + .../rust/rustc/ui/issues/issue-23485.rs | 51 + .../rust/rustc/ui/issues/issue-23491.rs | 10 + .../rust/rustc/ui/issues/issue-23543.rs | 12 + .../rust/rustc/ui/issues/issue-23544.rs | 10 + .../rust/rustc/ui/issues/issue-23550.rs | 23 + .../rust/rustc/ui/issues/issue-23589.rs | 6 + .../rust/rustc/ui/issues/issue-23595-2.rs | 11 + .../issues/issue-23611-enum-swap-in-drop.rs | 260 + .../rust/rustc/ui/issues/issue-23649-1.rs | 13 + .../rust/rustc/ui/issues/issue-23649-2.rs | 12 + .../rust/rustc/ui/issues/issue-23649-3.rs | 6 + .../rust/rustc/ui/issues/issue-23699.rs | 15 + .../rust/rustc/ui/issues/issue-23716.rs | 18 + .../rust/rustc/ui/issues/issue-23781.rs | 30 + .../rust/rustc/ui/issues/issue-2380-b.rs | 11 + .../rust/rustc/ui/issues/issue-23808.rs | 60 + .../rust/rustc/ui/issues/issue-23825.rs | 22 + .../rust/rustc/ui/issues/issue-2383.rs | 10 + .../rust/rustc/ui/issues/issue-23833.rs | 18 + .../rust/rustc/ui/issues/issue-23891.rs | 12 + .../rust/rustc/ui/issues/issue-23898.rs | 12 + .../rust/rustc/ui/issues/issue-23958.rs | 14 + .../rust/rustc/ui/issues/issue-23966.rs | 5 + .../issues/issue-23968-const-not-overflow.rs | 13 + .../rust/rustc/ui/issues/issue-23992.rs | 20 + .../rust/rustc/ui/issues/issue-24010.rs | 15 + .../rust/rustc/ui/issues/issue-24013.rs | 8 + .../rust/rustc/ui/issues/issue-24036.rs | 17 + .../rust/rustc/ui/issues/issue-24081.rs | 19 + .../rust/rustc/ui/issues/issue-24085.rs | 20 + .../rust/rustc/ui/issues/issue-24086.rs | 24 + .../rust/rustc/ui/issues/issue-2414-c.rs | 10 + .../rust/rustc/ui/issues/issue-24161.rs | 12 + .../rust/rustc/ui/issues/issue-24204.rs | 26 + .../rust/rustc/ui/issues/issue-24227.rs | 19 + .../rustc/ui/issues/issue-24267-flow-exit.rs | 20 + .../rust/rustc/ui/issues/issue-2428.rs | 15 + .../rust/rustc/ui/issues/issue-24308.rs | 18 + .../rust/rustc/ui/issues/issue-24313.rs | 34 + .../rust/rustc/ui/issues/issue-24322.rs | 10 + .../rust/rustc/ui/issues/issue-24338.rs | 22 + .../rust/rustc/ui/issues/issue-24352.rs | 5 + .../rust/rustc/ui/issues/issue-24353.rs | 9 + .../rust/rustc/ui/issues/issue-24357.rs | 12 + .../rust/rustc/ui/issues/issue-24363.rs | 7 + .../rust/rustc/ui/issues/issue-24365.rs | 20 + .../rust/rustc/ui/issues/issue-24389.rs | 12 + .../rust/rustc/ui/issues/issue-24424.rs | 8 + .../rust/rustc/ui/issues/issue-24434.rs | 8 + .../rust/rustc/ui/issues/issue-2444.rs | 18 + .../rust/rustc/ui/issues/issue-24446.rs | 7 + .../rust/rustc/ui/issues/issue-2445-b.rs | 32 + .../rust/rustc/ui/issues/issue-2445.rs | 30 + .../rust/rustc/ui/issues/issue-24533.rs | 25 + ...535-allow-mutable-borrow-in-match-guard.rs | 56 + .../rust/rustc/ui/issues/issue-24589.rs | 18 + .../rust/rustc/ui/issues/issue-2463.rs | 26 + .../rust/rustc/ui/issues/issue-24682.rs | 22 + .../auxiliary/issue-24687-lib.rs | 11 + .../auxiliary/issue-24687-mbcs-in-comments.rs | 28 + .../issue-24687-embed-debuginfo/main.rs | 15 + .../issue-2470-bounds-check-overflow.rs | 28 + .../rust/rustc/ui/issues/issue-2472.rs | 15 + .../rust/rustc/ui/issues/issue-24779.rs | 5 + .../ui/issues/issue-24805-dropck-itemless.rs | 78 + .../rust/rustc/ui/issues/issue-24819.rs | 12 + .../rust/rustc/ui/issues/issue-2487-a.rs | 33 + .../rust/rustc/ui/issues/issue-24883.rs | 18 + .../ui/issues/issue-24945-repeat-dash-opts.rs | 11 + .../rust/rustc/ui/issues/issue-24947.rs | 26 + .../rust/rustc/ui/issues/issue-24954.rs | 14 + .../rust/rustc/ui/issues/issue-2502.rs | 25 + .../rust/rustc/ui/issues/issue-25076.rs | 12 + .../rust/rustc/ui/issues/issue-25089.rs | 34 + .../rust/rustc/ui/issues/issue-25145.rs | 14 + .../rust/rustc/ui/issues/issue-25180.rs | 8 + .../rust/rustc/ui/issues/issue-25185.rs | 14 + .../rust/rustc/ui/issues/issue-2526-a.rs | 12 + .../rust/rustc/ui/issues/issue-25279.rs | 17 + .../rust/rustc/ui/issues/issue-25339.rs | 32 + .../rust/rustc/ui/issues/issue-25343.rs | 23 + .../rust/rustc/ui/issues/issue-25368.rs | 14 + .../rust/rustc/ui/issues/issue-25385.rs | 13 + .../rust/rustc/ui/issues/issue-25386.rs | 29 + .../rust/rustc/ui/issues/issue-25394.rs | 7 + .../rust/rustc/ui/issues/issue-25396.rs | 30 + .../rust/rustc/ui/issues/issue-25439.rs | 10 + .../rust/rustc/ui/issues/issue-25467.rs | 13 + .../rust/rustc/ui/issues/issue-25497.rs | 20 + .../rust/rustc/ui/issues/issue-2550.rs | 23 + .../rust/rustc/ui/issues/issue-25515.rs | 21 + .../ui/issues/issue-25549-multiple-drop.rs | 34 + .../rust/rustc/ui/issues/issue-25579.rs | 21 + .../rust/rustc/ui/issues/issue-25679.rs | 20 + .../rust/rustc/ui/issues/issue-25693.rs | 23 + .../rust/rustc/ui/issues/issue-25700-1.rs | 14 + .../rust/rustc/ui/issues/issue-25700-2.rs | 23 + .../rust/rustc/ui/issues/issue-25700.rs | 15 + .../ui/issues/issue-25746-bool-transmute.rs | 12 + .../rust/rustc/ui/issues/issue-25757.rs | 19 + .../rust/rustc/ui/issues/issue-25793.rs | 27 + .../rust/rustc/ui/issues/issue-25810.rs | 29 + .../rust/rustc/ui/issues/issue-25826.rs | 7 + .../rust/rustc/ui/issues/issue-2590.rs | 16 + .../rust/rustc/ui/issues/issue-25901.rs | 15 + .../rust/rustc/ui/issues/issue-25916.rs | 29 + .../rust/rustc/ui/issues/issue-26056.rs | 23 + .../rust/rustc/ui/issues/issue-26093.rs | 13 + .../rust/rustc/ui/issues/issue-26094.rs | 14 + .../rust/rustc/ui/issues/issue-26095.rs | 24 + .../rust/rustc/ui/issues/issue-2611-3.rs | 20 + .../rust/rustc/ui/issues/issue-26127.rs | 13 + .../rust/rustc/ui/issues/issue-26205.rs | 32 + .../rust/rustc/ui/issues/issue-26217.rs | 11 + .../rust/rustc/ui/issues/issue-26237.rs | 13 + .../rust/rustc/ui/issues/issue-26251.rs | 16 + .../rust/rustc/ui/issues/issue-26262.rs | 23 + .../rust/rustc/ui/issues/issue-2631-b.rs | 18 + .../rust/rustc/ui/issues/issue-26322.rs | 31 + .../rust/rustc/ui/issues/issue-2633-2.rs | 15 + .../rust/rustc/ui/issues/issue-2633.rs | 32 + .../rust/rustc/ui/issues/issue-2642.rs | 11 + .../rust/rustc/ui/issues/issue-26448-1.rs | 14 + .../rust/rustc/ui/issues/issue-26448-2.rs | 22 + .../rust/rustc/ui/issues/issue-26448-3.rs | 26 + .../rust/rustc/ui/issues/issue-26459.rs | 9 + .../rust/rustc/ui/issues/issue-26468.rs | 30 + .../rust/rustc/ui/issues/issue-26472.rs | 14 + .../rust/rustc/ui/issues/issue-26484.rs | 13 + .../rust/rustc/ui/issues/issue-26545.rs | 13 + .../rust/rustc/ui/issues/issue-26614.rs | 15 + .../rust/rustc/ui/issues/issue-26619.rs | 23 + .../rust/rustc/ui/issues/issue-26638.rs | 11 + .../rust/rustc/ui/issues/issue-26641.rs | 7 + .../rust/rustc/ui/issues/issue-26646.rs | 13 + .../rust/rustc/ui/issues/issue-26655.rs | 26 + .../rust/rustc/ui/issues/issue-26709.rs | 18 + .../rust/rustc/ui/issues/issue-26802.rs | 15 + .../rust/rustc/ui/issues/issue-26805.rs | 7 + .../rust/rustc/ui/issues/issue-26812.rs | 7 + .../rustc/ui/issues/issue-26873-multifile.rs | 12 + .../ui/issues/issue-26873-multifile/A/B.rs | 5 + .../ui/issues/issue-26873-multifile/A/C.rs | 7 + .../ui/issues/issue-26873-multifile/A/mod.rs | 6 + .../ui/issues/issue-26873-multifile/mod.rs | 5 + .../rustc/ui/issues/issue-26873-onefile.rs | 26 + .../rust/rustc/ui/issues/issue-26886.rs | 9 + .../rust/rustc/ui/issues/issue-26905-rpass.rs | 22 + .../rust/rustc/ui/issues/issue-26905.rs | 24 + .../rust/rustc/ui/issues/issue-26930.rs | 9 + .../rust/rustc/ui/issues/issue-26948.rs | 7 + .../rust/rustc/ui/issues/issue-26996.rs | 25 + .../rust/rustc/ui/issues/issue-26997.rs | 16 + .../rust/rustc/ui/issues/issue-27008.rs | 8 + .../rust/rustc/ui/issues/issue-27021.rs | 29 + .../rust/rustc/ui/issues/issue-27033.rs | 13 + .../rust/rustc/ui/issues/issue-27042.rs | 18 + .../issue-27054-primitive-binary-ops.rs | 6 + .../rust/rustc/ui/issues/issue-27060-2.rs | 7 + .../rust/rustc/ui/issues/issue-27060-rpass.rs | 26 + .../rust/rustc/ui/issues/issue-27060.rs | 29 + .../rust/rustc/ui/issues/issue-27078.rs | 12 + .../rust/rustc/ui/issues/issue-2708.rs | 31 + .../rust/rustc/ui/issues/issue-27105.rs | 16 + .../rust/rustc/ui/issues/issue-2718-a.rs | 13 + .../rust/rustc/ui/issues/issue-2718.rs | 328 + .../rust/rustc/ui/issues/issue-2723-b.rs | 12 + .../rust/rustc/ui/issues/issue-27240.rs | 27 + .../rust/rustc/ui/issues/issue-27268.rs | 5 + .../rust/rustc/ui/issues/issue-27281.rs | 18 + ...issue-27282-move-match-input-into-guard.rs | 21 + .../issue-27282-move-ref-mut-into-guard.rs | 14 + ...sue-27282-mutate-before-diverging-arm-1.rs | 32 + ...sue-27282-mutate-before-diverging-arm-2.rs | 41 + ...sue-27282-mutate-before-diverging-arm-3.rs | 31 + .../issue-27282-reborrow-ref-mut-in-guard.rs | 19 + .../rust/rustc/ui/issues/issue-27320.rs | 16 + .../rust/rustc/ui/issues/issue-2734.rs | 25 + .../rust/rustc/ui/issues/issue-27340.rs | 7 + .../rust/rustc/ui/issues/issue-2735-2.rs | 28 + .../rust/rustc/ui/issues/issue-2735-3.rs | 28 + .../rust/rustc/ui/issues/issue-2735.rs | 25 + .../ui/issues/issue-27401-dropflag-reinit.rs | 28 + .../rust/rustc/ui/issues/issue-27433.rs | 6 + .../rust/rustc/ui/issues/issue-2748-a.rs | 18 + .../rust/rustc/ui/issues/issue-2748-b.rs | 12 + .../rust/rustc/ui/issues/issue-27583.rs | 48 + .../rust/rustc/ui/issues/issue-27592.rs | 20 + .../rust/rustc/ui/issues/issue-2761.rs | 8 + .../rust/rustc/ui/issues/issue-27639.rs | 12 + .../rust/rustc/ui/issues/issue-27697.rs | 22 + .../rust/rustc/ui/issues/issue-27815.rs | 13 + .../rust/rustc/ui/issues/issue-27842.rs | 12 + .../rust/rustc/ui/issues/issue-27859.rs | 22 + .../rust/rustc/ui/issues/issue-27889.rs | 24 + .../rust/rustc/ui/issues/issue-27890.rs | 8 + .../rust/rustc/ui/issues/issue-27895.rs | 11 + .../rust/rustc/ui/issues/issue-27901.rs | 12 + .../rust/rustc/ui/issues/issue-27942.rs | 15 + .../rust/rustc/ui/issues/issue-27949.rs | 42 + .../rust/rustc/ui/issues/issue-27997.rs | 38 + .../rust/rustc/ui/issues/issue-2804-2.rs | 13 + .../rust/rustc/ui/issues/issue-28075.rs | 14 + .../rust/rustc/ui/issues/issue-28098.rs | 28 + .../rust/rustc/ui/issues/issue-28105.rs | 9 + .../rust/rustc/ui/issues/issue-28109.rs | 13 + .../rust/rustc/ui/issues/issue-28113.rs | 9 + .../rust/rustc/ui/issues/issue-28134.rs | 4 + .../rust/rustc/ui/issues/issue-28181.rs | 7 + .../rust/rustc/ui/issues/issue-2823.rs | 15 + .../rust/rustc/ui/issues/issue-28279.rs | 22 + .../rust/rustc/ui/issues/issue-28324.rs | 9 + .../rust/rustc/ui/issues/issue-28344.rs | 12 + .../rust/rustc/ui/issues/issue-28388-1.rs | 6 + .../rust/rustc/ui/issues/issue-28388-2.rs | 11 + .../rust/rustc/ui/issues/issue-28388-3.rs | 12 + .../rust/rustc/ui/issues/issue-28433.rs | 13 + .../rust/rustc/ui/issues/issue-28472.rs | 15 + .../rust/rustc/ui/issues/issue-2848.rs | 18 + .../rust/rustc/ui/issues/issue-2849.rs | 9 + .../ui/issues/issue-28498-must-work-ex1.rs | 19 + .../ui/issues/issue-28498-must-work-ex2.rs | 21 + .../rustc/ui/issues/issue-28498-ugeh-ex1.rs | 28 + .../issue-28498-ugeh-with-lifetime-param.rs | 39 + .../issue-28498-ugeh-with-passed-to-fn.rs | 47 + .../issue-28498-ugeh-with-trait-bound.rs | 42 + .../rust/rustc/ui/issues/issue-28550.rs | 17 + .../rust/rustc/ui/issues/issue-28561.rs | 113 + .../rust/rustc/ui/issues/issue-28568.rs | 13 + .../rust/rustc/ui/issues/issue-28576.rs | 13 + .../rust/rustc/ui/issues/issue-28586.rs | 8 + .../rust/rustc/ui/issues/issue-28600.rs | 16 + .../rust/rustc/ui/issues/issue-28625.rs | 23 + .../rust/rustc/ui/issues/issue-28676.rs | 36 + .../rust/rustc/ui/issues/issue-28776.rs | 7 + .../rust/rustc/ui/issues/issue-28777.rs | 23 + .../rust/rustc/ui/issues/issue-28822.rs | 8 + .../rust/rustc/ui/issues/issue-28828.rs | 19 + .../rust/rustc/ui/issues/issue-28837.rs | 36 + .../rust/rustc/ui/issues/issue-28839.rs | 16 + .../rust/rustc/ui/issues/issue-28848.rs | 14 + .../rust/rustc/ui/issues/issue-28871.rs | 25 + .../rust/rustc/ui/issues/issue-28934.rs | 26 + .../rust/rustc/ui/issues/issue-28936.rs | 28 + .../rust/rustc/ui/issues/issue-2895.rs | 29 + .../rust/rustc/ui/issues/issue-28950.rs | 23 + .../rust/rustc/ui/issues/issue-28971.rs | 17 + .../rust/rustc/ui/issues/issue-28983.rs | 23 + .../rust/rustc/ui/issues/issue-28992-empty.rs | 17 + .../rust/rustc/ui/issues/issue-28999.rs | 12 + .../rust/rustc/ui/issues/issue-29030.rs | 10 + .../rust/rustc/ui/issues/issue-29037.rs | 25 + .../rust/rustc/ui/issues/issue-2904.rs | 80 + .../rust/rustc/ui/issues/issue-29048.rs | 13 + .../rust/rustc/ui/issues/issue-29053.rs | 13 + .../rust/rustc/ui/issues/issue-29071-2.rs | 33 + .../rust/rustc/ui/issues/issue-29071.rs | 17 + .../rust/rustc/ui/issues/issue-29084.rs | 14 + .../rust/rustc/ui/issues/issue-29092.rs | 27 + .../rust/rustc/ui/issues/issue-29124.rs | 20 + .../rust/rustc/ui/issues/issue-29147-rpass.rs | 28 + .../rust/rustc/ui/issues/issue-29147.rs | 23 + .../rust/rustc/ui/issues/issue-29161.rs | 16 + .../rust/rustc/ui/issues/issue-29166.rs | 22 + .../rust/rustc/ui/issues/issue-29181.rs | 10 + .../rust/rustc/ui/issues/issue-29184.rs | 4 + .../rust/rustc/ui/issues/issue-29227.rs | 143 + .../rust/rustc/ui/issues/issue-29265.rs | 11 + .../rust/rustc/ui/issues/issue-29276.rs | 6 + .../rust/rustc/ui/issues/issue-2935.rs | 30 + .../rust/rustc/ui/issues/issue-2936.rs | 32 + .../rust/rustc/ui/issues/issue-2937.rs | 7 + .../rust/rustc/ui/issues/issue-29466.rs | 3604 ++++++ .../rust/rustc/ui/issues/issue-29485.rs | 19 + .../rust/rustc/ui/issues/issue-29488.rs | 24 + .../rust/rustc/ui/issues/issue-2951.rs | 12 + .../rust/rustc/ui/issues/issue-29516.rs | 21 + .../rust/rustc/ui/issues/issue-29522.rs | 18 + .../rust/rustc/ui/issues/issue-29540.rs | 493 + .../rust/rustc/ui/issues/issue-29663.rs | 57 + .../rust/rustc/ui/issues/issue-29668.rs | 17 + .../rust/rustc/ui/issues/issue-29710.rs | 12 + .../rust/rustc/ui/issues/issue-29723.rs | 15 + .../rust/rustc/ui/issues/issue-29740.rs | 318 + .../rust/rustc/ui/issues/issue-29743.rs | 8 + .../rust/rustc/ui/issues/issue-29746.rs | 37 + .../rust/rustc/ui/issues/issue-29798.rs | 12 + .../rust/rustc/ui/issues/issue-29844.rs | 25 + .../rust/rustc/ui/issues/issue-29857.rs | 20 + .../rust/rustc/ui/issues/issue-29861.rs | 21 + .../rust/rustc/ui/issues/issue-2989.rs | 37 + .../rust/rustc/ui/issues/issue-29914-2.rs | 7 + .../rust/rustc/ui/issues/issue-29914-3.rs | 8 + .../rust/rustc/ui/issues/issue-29914.rs | 11 + .../rust/rustc/ui/issues/issue-29927-1.rs | 12 + .../rust/rustc/ui/issues/issue-29927.rs | 12 + .../rust/rustc/ui/issues/issue-29948.rs | 41 + .../rust/rustc/ui/issues/issue-2995.rs | 6 + .../rust/rustc/ui/issues/issue-30007.rs | 8 + .../rustc/ui/issues/issue-30018-nopanic.rs | 104 + .../rust/rustc/ui/issues/issue-30018-panic.rs | 26 + .../rust/rustc/ui/issues/issue-30079.rs | 40 + .../rust/rustc/ui/issues/issue-3008-1.rs | 13 + .../rust/rustc/ui/issues/issue-3008-2.rs | 7 + .../rust/rustc/ui/issues/issue-3008-3.rs | 11 + .../rust/rustc/ui/issues/issue-30081.rs | 16 + .../rust/rustc/ui/issues/issue-3012-2.rs | 14 + .../rust/rustc/ui/issues/issue-30123.rs | 10 + .../rust/rustc/ui/issues/issue-3021-b.rs | 15 + .../rust/rustc/ui/issues/issue-3021-c.rs | 10 + .../rust/rustc/ui/issues/issue-3021-d.rs | 29 + .../rust/rustc/ui/issues/issue-3021.rs | 19 + .../rust/rustc/ui/issues/issue-30225.rs | 39 + .../rust/rustc/ui/issues/issue-30236.rs | 8 + .../rust/rustc/ui/issues/issue-30240-b.rs | 16 + .../rust/rustc/ui/issues/issue-30240-rpass.rs | 15 + .../rust/rustc/ui/issues/issue-30240.rs | 11 + .../rust/rustc/ui/issues/issue-30255.rs | 25 + .../rust/rustc/ui/issues/issue-3026.rs | 14 + .../rust/rustc/ui/issues/issue-3029.rs | 15 + .../rust/rustc/ui/issues/issue-30302.rs | 21 + .../rust/rustc/ui/issues/issue-30355.rs | 10 + .../rust/rustc/ui/issues/issue-3037.rs | 17 + .../rust/rustc/ui/issues/issue-30371.rs | 11 + .../rust/rustc/ui/issues/issue-3038.rs | 27 + .../rust/rustc/ui/issues/issue-30380.rs | 37 + .../rust/rustc/ui/issues/issue-30438-a.rs | 24 + .../rust/rustc/ui/issues/issue-30438-b.rs | 25 + .../rust/rustc/ui/issues/issue-30438-c.rs | 21 + .../rust/rustc/ui/issues/issue-3044.rs | 7 + .../rust/rustc/ui/issues/issue-30490.rs | 103 + .../rust/rustc/ui/issues/issue-3052.rs | 14 + .../rust/rustc/ui/issues/issue-30530.rs | 29 + .../rust/rustc/ui/issues/issue-30535.rs | 10 + .../rust/rustc/ui/issues/issue-30560.rs | 10 + .../rust/rustc/ui/issues/issue-30589.rs | 10 + .../rust/rustc/ui/issues/issue-30615.rs | 6 + .../rust/rustc/ui/issues/issue-30730.rs | 6 + .../rust/rustc/ui/issues/issue-30756.rs | 8 + .../rust/rustc/ui/issues/issue-3080.rs | 9 + .../rust/rustc/ui/issues/issue-30891.rs | 11 + .../rust/rustc/ui/issues/issue-3091.rs | 8 + .../rust/rustc/ui/issues/issue-3096-1.rs | 4 + .../rust/rustc/ui/issues/issue-3096-2.rs | 7 + .../rust/rustc/ui/issues/issue-3099-a.rs | 6 + .../rust/rustc/ui/issues/issue-3099-b.rs | 6 + .../rust/rustc/ui/issues/issue-3099.rs | 12 + .../rust/rustc/ui/issues/issue-31011.rs | 30 + .../rust/rustc/ui/issues/issue-31076.rs | 18 + .../rust/rustc/ui/issues/issue-3109.rs | 5 + .../rust/rustc/ui/issues/issue-31109.rs | 7 + .../rust/rustc/ui/issues/issue-31173.rs | 18 + .../rust/rustc/ui/issues/issue-3121.rs | 26 + .../rust/rustc/ui/issues/issue-31212.rs | 11 + .../rust/rustc/ui/issues/issue-31221.rs | 35 + .../rust/rustc/ui/issues/issue-31260.rs | 16 + .../rustc/ui/issues/issue-31267-additional.rs | 21 + .../rust/rustc/ui/issues/issue-31267.rs | 15 + .../rust/rustc/ui/issues/issue-31299.rs | 35 + .../rust/rustc/ui/issues/issue-3136-b.rs | 9 + .../rust/rustc/ui/issues/issue-3149.rs | 27 + .../rust/rustc/ui/issues/issue-31511.rs | 7 + .../rust/rustc/ui/issues/issue-3154.rs | 12 + .../rust/rustc/ui/issues/issue-31561.rs | 11 + .../rust/rustc/ui/issues/issue-31597.rs | 30 + .../rust/rustc/ui/issues/issue-31702.rs | 11 + .../rust/rustc/ui/issues/issue-31769.rs | 5 + .../rust/rustc/ui/issues/issue-31776.rs | 56 + .../rust/rustc/ui/issues/issue-31804.rs | 7 + .../rust/rustc/ui/issues/issue-31845.rs | 13 + .../rust/rustc/ui/issues/issue-31910.rs | 12 + .../ui/issues/issue-31924-non-snake-ffi.rs | 9 + .../rust/rustc/ui/issues/issue-32004.rs | 20 + .../rust/rustc/ui/issues/issue-32008.rs | 29 + .../rust/rustc/ui/issues/issue-32086.rs | 8 + .../rust/rustc/ui/issues/issue-3211.rs | 8 + .../rust/rustc/ui/issues/issue-32119.rs | 18 + .../rust/rustc/ui/issues/issue-32122-1.rs | 18 + .../rust/rustc/ui/issues/issue-32122-2.rs | 29 + .../rust/rustc/ui/issues/issue-3214.rs | 15 + .../rust/rustc/ui/issues/issue-3220.rs | 26 + .../rust/rustc/ui/issues/issue-32201.rs | 14 + .../rust/rustc/ui/issues/issue-32222.rs | 23 + .../rust/rustc/ui/issues/issue-32292.rs | 10 + .../rust/rustc/ui/issues/issue-32323.rs | 9 + .../rust/rustc/ui/issues/issue-32324.rs | 25 + .../rust/rustc/ui/issues/issue-32326.rs | 11 + .../issue-32354-suggest-import-rename.rs | 17 + .../rust/rustc/ui/issues/issue-32377.rs | 20 + .../rust/rustc/ui/issues/issue-32389.rs | 12 + .../rust/rustc/ui/issues/issue-32518.rs | 14 + .../rust/rustc/ui/issues/issue-32655.rs | 20 + .../rust/rustc/ui/issues/issue-32709.rs | 9 + .../rust/rustc/ui/issues/issue-32782.rs | 14 + .../rust/rustc/ui/issues/issue-32797.rs | 14 + .../rust/rustc/ui/issues/issue-32805.rs | 11 + .../rust/rustc/ui/issues/issue-32829-2.rs | 74 + .../rust/rustc/ui/issues/issue-32829.rs | 7 + .../rust/rustc/ui/issues/issue-32833.rs | 8 + .../rust/rustc/ui/issues/issue-3290.rs | 9 + .../rust/rustc/ui/issues/issue-32922.rs | 30 + .../rust/rustc/ui/issues/issue-32947.rs | 25 + .../rust/rustc/ui/issues/issue-32950.rs | 10 + .../rust/rustc/ui/issues/issue-32963.rs | 13 + .../rust/rustc/ui/issues/issue-32995-2.rs | 14 + .../rust/rustc/ui/issues/issue-32995.rs | 25 + .../rust/rustc/ui/issues/issue-33096.rs | 20 + .../ui/issues/issue-33140-hack-boundaries.rs | 71 + .../issues/issue-33140-traitobject-crate.rs | 108 + .../rust/rustc/ui/issues/issue-33140.rs | 48 + .../rust/rustc/ui/issues/issue-33185.rs | 18 + .../rust/rustc/ui/issues/issue-33187.rs | 20 + .../rust/rustc/ui/issues/issue-33202.rs | 10 + .../rust/rustc/ui/issues/issue-33241.rs | 13 + .../rust/rustc/ui/issues/issue-33264.rs | 30 + .../rust/rustc/ui/issues/issue-33287.rs | 11 + .../rust/rustc/ui/issues/issue-33293.rs | 7 + .../rust/rustc/ui/issues/issue-333.rs | 8 + .../rust/rustc/ui/issues/issue-33387.rs | 33 + .../rust/rustc/ui/issues/issue-3344.rs | 8 + .../rust/rustc/ui/issues/issue-33461.rs | 29 + .../rust/rustc/ui/issues/issue-33464.rs | 11 + .../rust/rustc/ui/issues/issue-33498.rs | 12 + .../rust/rustc/ui/issues/issue-33504.rs | 10 + .../rust/rustc/ui/issues/issue-33525.rs | 6 + .../rust/rustc/ui/issues/issue-33537.rs | 15 + .../rust/rustc/ui/issues/issue-33571.rs | 8 + .../rust/rustc/ui/issues/issue-33575.rs | 5 + .../rust/rustc/ui/issues/issue-33687.rs | 18 + .../rust/rustc/ui/issues/issue-33770.rs | 96 + .../rust/rustc/ui/issues/issue-33819.rs | 9 + .../rust/rustc/ui/issues/issue-3389.rs | 27 + .../rust/rustc/ui/issues/issue-33903.rs | 11 + .../rust/rustc/ui/issues/issue-33941.rs | 8 + .../rust/rustc/ui/issues/issue-33992.rs | 33 + .../rust/rustc/ui/issues/issue-34028.rs | 11 + .../rust/rustc/ui/issues/issue-34047.rs | 9 + .../rust/rustc/ui/issues/issue-34053.rs | 31 + .../rust/rustc/ui/issues/issue-34074.rs | 11 + .../rust/rustc/ui/issues/issue-34171.rs | 11 + .../rust/rustc/ui/issues/issue-34194.rs | 12 + .../rust/rustc/ui/issues/issue-34209.rs | 12 + .../rust/rustc/ui/issues/issue-34222-1.rs | 4 + .../rust/rustc/ui/issues/issue-34229.rs | 10 + .../rust/rustc/ui/issues/issue-3424.rs | 21 + .../rust/rustc/ui/issues/issue-34255-1.rs | 11 + .../rust/rustc/ui/issues/issue-3429.rs | 9 + .../rust/rustc/ui/issues/issue-34334.rs | 7 + .../rust/rustc/ui/issues/issue-34349.rs | 23 + .../rust/rustc/ui/issues/issue-34373.rs | 12 + .../rust/rustc/ui/issues/issue-34418.rs | 20 + .../rust/rustc/ui/issues/issue-34427.rs | 18 + .../rust/rustc/ui/issues/issue-3447.rs | 34 + .../rust/rustc/ui/issues/issue-34503.rs | 12 + .../rust/rustc/ui/issues/issue-34569.rs | 19 + .../rust/rustc/ui/issues/issue-34571.rs | 12 + .../rust/rustc/ui/issues/issue-34721.rs | 35 + .../rust/rustc/ui/issues/issue-34751.rs | 12 + .../rust/rustc/ui/issues/issue-3477.rs | 6 + .../rust/rustc/ui/issues/issue-34780.rs | 12 + .../rust/rustc/ui/issues/issue-34784.rs | 22 + .../rust/rustc/ui/issues/issue-34796.rs | 29 + .../rust/rustc/ui/issues/issue-34798.rs | 26 + .../rust/rustc/ui/issues/issue-34839.rs | 20 + .../rust/rustc/ui/issues/issue-34932.rs | 12 + .../rust/rustc/ui/issues/issue-3500.rs | 11 + .../rust/rustc/ui/issues/issue-35075.rs | 10 + .../rust/rustc/ui/issues/issue-35139.rs | 27 + .../rust/rustc/ui/issues/issue-3521-2.rs | 9 + .../rust/rustc/ui/issues/issue-3521.rs | 12 + .../rust/rustc/ui/issues/issue-35241.rs | 6 + .../rust/rustc/ui/issues/issue-35376.rs | 44 + .../rust/rustc/ui/issues/issue-35423.rs | 10 + .../rust/rustc/ui/issues/issue-35450.rs | 6 + .../rust/rustc/ui/issues/issue-35546.rs | 21 + .../rust/rustc/ui/issues/issue-3556.rs | 37 + .../rust/rustc/ui/issues/issue-35570.rs | 30 + .../rust/rustc/ui/issues/issue-3559.rs | 19 + .../rust/rustc/ui/issues/issue-35600.rs | 19 + .../rust/rustc/ui/issues/issue-3563-2.rs | 15 + .../rust/rustc/ui/issues/issue-3563-3.rs | 181 + .../rust/rustc/ui/issues/issue-35668.rs | 13 + .../rust/rustc/ui/issues/issue-35675.rs | 43 + .../rust/rustc/ui/issues/issue-35677.rs | 9 + .../rust/rustc/ui/issues/issue-3574.rs | 15 + .../rust/rustc/ui/issues/issue-35815.rs | 16 + .../rust/rustc/ui/issues/issue-35869.rs | 22 + .../rust/rustc/ui/issues/issue-35976.rs | 21 + .../rust/rustc/ui/issues/issue-35988.rs | 7 + .../rust/rustc/ui/issues/issue-3601.rs | 35 + .../rust/rustc/ui/issues/issue-36023.rs | 25 + .../issue-36036-associated-type-layout.rs | 28 + .../rust/rustc/ui/issues/issue-36053.rs | 23 + .../rust/rustc/ui/issues/issue-36075.rs | 15 + .../rust/rustc/ui/issues/issue-36082.rs | 16 + .../rust/rustc/ui/issues/issue-3609.rs | 31 + .../rust/rustc/ui/issues/issue-36116.rs | 26 + .../issue-36139-normalize-closure-sig.rs | 20 + .../rust/rustc/ui/issues/issue-36163.rs | 8 + .../rust/rustc/ui/issues/issue-36260.rs | 14 + .../ui/issues/issue-36278-prefix-nesting.rs | 20 + .../rust/rustc/ui/issues/issue-36299.rs | 6 + .../rust/rustc/ui/issues/issue-36379.rs | 6 + .../rust/rustc/ui/issues/issue-36381.rs | 26 + .../rust/rustc/ui/issues/issue-36400.rs | 7 + .../rust/rustc/ui/issues/issue-36401.rs | 17 + .../rust/rustc/ui/issues/issue-36474.rs | 32 + .../rust/rustc/ui/issues/issue-3656.rs | 31 + .../rust/rustc/ui/issues/issue-36617.rs | 6 + .../rust/rustc/ui/issues/issue-36638.rs | 9 + .../rust/rustc/ui/issues/issue-3668-2.rs | 7 + .../rust/rustc/ui/issues/issue-3668.rs | 15 + .../rust/rustc/ui/issues/issue-36708.rs | 13 + .../issue-36744-bitcast-args-if-needed.rs | 24 + .../ui/issues/issue-36744-without-calls.rs | 14 + .../rust/rustc/ui/issues/issue-36768.rs | 10 + .../ui/issues/issue-36786-resolve-call.rs | 9 + .../rust/rustc/ui/issues/issue-36792.rs | 8 + .../rust/rustc/ui/issues/issue-3680.rs | 10 + .../rust/rustc/ui/issues/issue-36816.rs | 8 + .../rust/rustc/ui/issues/issue-3683.rs | 19 + .../rust/rustc/ui/issues/issue-36836.rs | 16 + .../rust/rustc/ui/issues/issue-36839.rs | 22 + .../rust/rustc/ui/issues/issue-36856.rs | 17 + .../rust/rustc/ui/issues/issue-36881.rs | 7 + .../rust/rustc/ui/issues/issue-36936.rs | 27 + .../rust/rustc/ui/issues/issue-36954.rs | 9 + .../rust/rustc/ui/issues/issue-3702-2.rs | 21 + .../rust/rustc/ui/issues/issue-3702.rs | 14 + .../rust/rustc/ui/issues/issue-37026.rs | 9 + .../rust/rustc/ui/issues/issue-37051.rs | 20 + .../rust/rustc/ui/issues/issue-3707.rs | 19 + .../rust/rustc/ui/issues/issue-37109.rs | 17 + .../rust/rustc/ui/issues/issue-37131.rs | 10 + .../rust/rustc/ui/issues/issue-37175.rs | 6 + .../rust/rustc/ui/issues/issue-37222.rs | 18 + .../ui/issues/issue-37291/auxiliary/lib.rs | 43 + .../rust/rustc/ui/issues/issue-37291/main.rs | 22 + .../issue-37311.rs | 24 + .../rust/rustc/ui/issues/issue-37323.rs | 21 + .../rust/rustc/ui/issues/issue-37366.rs | 16 + .../rust/rustc/ui/issues/issue-3743.rs | 56 + .../rust/rustc/ui/issues/issue-37433.rs | 12 + .../rust/rustc/ui/issues/issue-37510.rs | 15 + .../rust/rustc/ui/issues/issue-37515.rs | 9 + .../rust/rustc/ui/issues/issue-3753.rs | 33 + .../rust/rustc/ui/issues/issue-37534.rs | 7 + .../rust/rustc/ui/issues/issue-37550.rs | 7 + .../rust/rustc/ui/issues/issue-37576.rs | 46 + .../rust/rustc/ui/issues/issue-37598.rs | 12 + .../rust/rustc/ui/issues/issue-3763.rs | 30 + .../rust/rustc/ui/issues/issue-37655.rs | 38 + .../rust/rustc/ui/issues/issue-37665.rs | 12 + .../rust/rustc/ui/issues/issue-37686.rs | 8 + .../rust/rustc/ui/issues/issue-37725.rs | 11 + .../rust/rustc/ui/issues/issue-37733.rs | 8 + .../rust/rustc/ui/issues/issue-3779.rs | 9 + .../rust/rustc/ui/issues/issue-37884.rs | 15 + .../rust/rustc/ui/issues/issue-37887.rs | 5 + .../rust/rustc/ui/issues/issue-3794.rs | 33 + .../rust/rustc/ui/issues/issue-37991.rs | 18 + .../rust/rustc/ui/issues/issue-38002.rs | 36 + .../rust/rustc/ui/issues/issue-38033.rs | 80 + .../rust/rustc/ui/issues/issue-38074.rs | 21 + .../rust/rustc/ui/issues/issue-38160.rs | 20 + .../rust/rustc/ui/issues/issue-38190.rs | 16 + .../rust/rustc/ui/issues/issue-3820.rs | 16 + .../rust/rustc/ui/issues/issue-38226.rs | 16 + .../rust/rustc/ui/issues/issue-38293.rs | 17 + .../rust/rustc/ui/issues/issue-38381.rs | 8 + .../rust/rustc/ui/issues/issue-38404.rs | 7 + .../rust/rustc/ui/issues/issue-38412.rs | 11 + .../rust/rustc/ui/issues/issue-38437.rs | 47 + .../rust/rustc/ui/issues/issue-38458.rs | 6 + .../rust/rustc/ui/issues/issue-3847.rs | 14 + .../rust/rustc/ui/issues/issue-38556.rs | 14 + .../rust/rustc/ui/issues/issue-38604.rs | 17 + .../rust/rustc/ui/issues/issue-38715.rs | 8 + .../rust/rustc/ui/issues/issue-38727.rs | 14 + .../rust/rustc/ui/issues/issue-3874.rs | 13 + .../rust/rustc/ui/issues/issue-38763.rs | 14 + .../rust/rustc/ui/issues/issue-3878.rs | 11 + .../rust/rustc/ui/issues/issue-38821.rs | 34 + .../rust/rustc/ui/issues/issue-38857.rs | 6 + .../rust/rustc/ui/issues/issue-38868.rs | 14 + .../issue-38875/auxiliary/issue-38875-b.rs | 2 + .../ui/issues/issue-38875/issue-38875.rs | 9 + .../rust/rustc/ui/issues/issue-3888-2.rs | 10 + .../rust/rustc/ui/issues/issue-38919.rs | 6 + .../rust/rustc/ui/issues/issue-38940.rs | 47 + .../rust/rustc/ui/issues/issue-38942.rs | 18 + .../rust/rustc/ui/issues/issue-3895.rs | 12 + .../rust/rustc/ui/issues/issue-38954.rs | 5 + .../rust/rustc/ui/issues/issue-38987.rs | 5 + .../rust/rustc/ui/issues/issue-3904.rs | 26 + .../rust/rustc/ui/issues/issue-39089.rs | 6 + .../rust/rustc/ui/issues/issue-39175.rs | 18 + .../rust/rustc/ui/issues/issue-39211.rs | 16 + .../rust/rustc/ui/issues/issue-39292.rs | 18 + .../rust/rustc/ui/issues/issue-3935.rs | 14 + .../rust/rustc/ui/issues/issue-39362.rs | 19 + .../rust/rustc/ui/issues/issue-39367.rs | 40 + .../rust/rustc/ui/issues/issue-39388.rs | 10 + .../rust/rustc/ui/issues/issue-39467.rs | 12 + .../rust/rustc/ui/issues/issue-39548.rs | 7 + .../rust/rustc/ui/issues/issue-39559-2.rs | 21 + .../rust/rustc/ui/issues/issue-39559.rs | 20 + .../rust/rustc/ui/issues/issue-39616.rs | 4 + .../rust/rustc/ui/issues/issue-39687.rs | 7 + .../rust/rustc/ui/issues/issue-39709.rs | 6 + .../rust/rustc/ui/issues/issue-39720.rs | 23 + .../rust/rustc/ui/issues/issue-3973.rs | 26 + .../rust/rustc/ui/issues/issue-3979-2.rs | 19 + .../rustc/ui/issues/issue-3979-generics.rs | 37 + .../rust/rustc/ui/issues/issue-3979-xcrate.rs | 26 + .../rust/rustc/ui/issues/issue-3979.rs | 35 + .../rust/rustc/ui/issues/issue-39808.rs | 18 + .../rust/rustc/ui/issues/issue-39823.rs | 26 + .../rust/rustc/ui/issues/issue-39827.rs | 35 + .../rust/rustc/ui/issues/issue-39848.rs | 10 + .../rust/rustc/ui/issues/issue-3991.rs | 17 + .../rust/rustc/ui/issues/issue-3993.rs | 11 + .../rust/rustc/ui/issues/issue-39970.rs | 22 + .../rust/rustc/ui/issues/issue-39974.rs | 12 + .../rust/rustc/ui/issues/issue-39984.rs | 15 + .../rust/rustc/ui/issues/issue-40000.rs | 8 + .../rust/rustc/ui/issues/issue-40003.rs | 179 + .../rust/rustc/ui/issues/issue-40085.rs | 14 + .../rust/rustc/ui/issues/issue-40136.rs | 16 + .../rust/rustc/ui/issues/issue-40231-1.rs | 55 + .../rust/rustc/ui/issues/issue-40231-2.rs | 55 + .../rust/rustc/ui/issues/issue-40235.rs | 9 + .../rust/rustc/ui/issues/issue-4025.rs | 26 + .../rust/rustc/ui/issues/issue-40288-2.rs | 32 + .../rust/rustc/ui/issues/issue-40288.rs | 21 + .../rust/rustc/ui/issues/issue-40350.rs | 11 + .../issue-40402-ref-hints/issue-40402-1.rs | 11 + .../issue-40402-ref-hints/issue-40402-2.rs | 7 + .../rust/rustc/ui/issues/issue-40408.rs | 8 + .../rust/rustc/ui/issues/issue-40469.rs | 10 + .../rust/rustc/ui/issues/issue-40510-1.rs | 13 + .../rust/rustc/ui/issues/issue-40510-2.rs | 14 + .../rust/rustc/ui/issues/issue-40510-3.rs | 15 + .../rust/rustc/ui/issues/issue-40510-4.rs | 16 + .../rust/rustc/ui/issues/issue-40610.rs | 7 + .../rust/rustc/ui/issues/issue-40749.rs | 7 + .../rust/rustc/ui/issues/issue-40770.rs | 12 + .../rust/rustc/ui/issues/issue-40782.rs | 9 + .../rust/rustc/ui/issues/issue-40827.rs | 18 + .../rust/rustc/ui/issues/issue-40845.rs | 7 + .../rust/rustc/ui/issues/issue-40847.rs | 18 + .../rust/rustc/ui/issues/issue-40861.rs | 7 + .../rust/rustc/ui/issues/issue-40883.rs | 95 + .../rust/rustc/ui/issues/issue-40951.rs | 13 + .../rust/rustc/ui/issues/issue-40962.rs | 12 + .../rust/rustc/ui/issues/issue-41053.rs | 22 + .../rust/rustc/ui/issues/issue-4107.rs | 27 + .../rust/rustc/ui/issues/issue-41139.rs | 13 + .../rust/rustc/ui/issues/issue-41213.rs | 25 + .../rustc/ui/issues/issue-41229-ref-str.rs | 5 + .../rust/rustc/ui/issues/issue-41255.rs | 76 + .../rust/rustc/ui/issues/issue-41272.rs | 22 + .../rust/rustc/ui/issues/issue-41298.rs | 9 + .../rust/rustc/ui/issues/issue-41394-rpass.rs | 9 + .../rust/rustc/ui/issues/issue-41394.rs | 11 + .../rust/rustc/ui/issues/issue-41479.rs | 10 + .../rust/rustc/ui/issues/issue-41498.rs | 18 + .../rust/rustc/ui/issues/issue-41549.rs | 13 + .../rust/rustc/ui/issues/issue-41604.rs | 12 + .../rust/rustc/ui/issues/issue-41628.rs | 8 + .../issue-41652/auxiliary/issue-41652-b.rs | 7 + .../ui/issues/issue-41652/issue-41652.rs | 15 + .../rust/rustc/ui/issues/issue-41677.rs | 29 + .../rust/rustc/ui/issues/issue-41696.rs | 55 + .../rust/rustc/ui/issues/issue-41726.rs | 8 + .../rust/rustc/ui/issues/issue-41742.rs | 26 + .../rust/rustc/ui/issues/issue-41744.rs | 8 + .../rust/rustc/ui/issues/issue-41776.rs | 4 + .../rust/rustc/ui/issues/issue-41803.rs | 22 + .../ui/issues/issue-41849-variance-req.rs | 36 + .../rust/rustc/ui/issues/issue-41880.rs | 30 + .../rust/rustc/ui/issues/issue-41888.rs | 35 + ...sue-41936-variance-coerce-unsized-cycle.rs | 31 + .../rust/rustc/ui/issues/issue-41974.rs | 15 + .../rust/rustc/ui/issues/issue-41998.rs | 11 + .../rust/rustc/ui/issues/issue-42007.rs | 12 + .../rust/rustc/ui/issues/issue-4201.rs | 10 + .../rust/rustc/ui/issues/issue-42060.rs | 12 + .../rust/rustc/ui/issues/issue-4208.rs | 13 + .../rust/rustc/ui/issues/issue-42106.rs | 11 + .../rust/rustc/ui/issues/issue-42148.rs | 7 + .../rust/rustc/ui/issues/issue-42210.rs | 22 + .../rust/rustc/ui/issues/issue-4228.rs | 17 + .../rust/rustc/ui/issues/issue-42312.rs | 12 + .../rust/rustc/ui/issues/issue-42344.rs | 9 + .../rust/rustc/ui/issues/issue-42453.rs | 11 + .../rust/rustc/ui/issues/issue-42463.rs | 33 + .../rust/rustc/ui/issues/issue-42467.rs | 25 + .../rust/rustc/ui/issues/issue-4252.rs | 34 + .../rust/rustc/ui/issues/issue-42552.rs | 32 + .../rust/rustc/ui/issues/issue-4265.rs | 15 + .../rust/rustc/ui/issues/issue-42679.rs | 23 + .../rust/rustc/ui/issues/issue-42747.rs | 47 + .../rust/rustc/ui/issues/issue-42755.rs | 8 + .../rust/rustc/ui/issues/issue-42796.rs | 20 + .../rust/rustc/ui/issues/issue-42880.rs | 9 + .../rust/rustc/ui/issues/issue-42944.rs | 22 + .../rust/rustc/ui/issues/issue-42954.rs | 15 + .../rust/rustc/ui/issues/issue-42956.rs | 27 + .../rust/rustc/ui/issues/issue-43023.rs | 21 + .../rust/rustc/ui/issues/issue-43057.rs | 15 + .../rust/rustc/ui/issues/issue-43105.rs | 15 + .../rust/rustc/ui/issues/issue-43132.rs | 66 + .../rust/rustc/ui/issues/issue-43162.rs | 9 + .../rust/rustc/ui/issues/issue-43189.rs | 13 + .../rust/rustc/ui/issues/issue-43196.rs | 7 + .../rust/rustc/ui/issues/issue-43205.rs | 6 + .../rust/rustc/ui/issues/issue-4321.rs | 9 + .../rust/rustc/ui/issues/issue-43250.rs | 14 + .../rust/rustc/ui/issues/issue-43291.rs | 10 + .../rust/rustc/ui/issues/issue-4333.rs | 11 + .../rust/rustc/ui/issues/issue-4335.rs | 14 + .../rust/rustc/ui/issues/issue-43355.rs | 20 + .../rust/rustc/ui/issues/issue-43357.rs | 12 + .../rust/rustc/ui/issues/issue-43398.rs | 15 + .../ui/issues/issue-43420-no-over-suggest.rs | 10 + .../rust/rustc/ui/issues/issue-43424.rs | 13 + .../rust/rustc/ui/issues/issue-43431.rs | 15 + .../rust/rustc/ui/issues/issue-43483.rs | 17 + .../rust/rustc/ui/issues/issue-43623.rs | 21 + .../rust/rustc/ui/issues/issue-4366-2.rs | 27 + .../rust/rustc/ui/issues/issue-4366.rs | 27 + .../rust/rustc/ui/issues/issue-43692.rs | 6 + .../rust/rustc/ui/issues/issue-43733.rs | 32 + .../ui/issues/issue-43784-associated-type.rs | 18 + .../rustc/ui/issues/issue-43784-supertrait.rs | 11 + .../rust/rustc/ui/issues/issue-43806.rs | 24 + .../rust/rustc/ui/issues/issue-43853.rs | 18 + .../rust/rustc/ui/issues/issue-4387.rs | 7 + .../rust/rustc/ui/issues/issue-43910.rs | 8 + .../rust/rustc/ui/issues/issue-43923.rs | 13 + .../rust/rustc/ui/issues/issue-43925.rs | 5 + .../rust/rustc/ui/issues/issue-43926.rs | 5 + .../rust/rustc/ui/issues/issue-43988.rs | 37 + .../rust/rustc/ui/issues/issue-44005.rs | 30 + .../rust/rustc/ui/issues/issue-4401.rs | 8 + .../rust/rustc/ui/issues/issue-44021.rs | 7 + .../rust/rustc/ui/issues/issue-44023.rs | 7 + .../rust/rustc/ui/issues/issue-44056.rs | 7 + .../rust/rustc/ui/issues/issue-44078.rs | 4 + .../rust/rustc/ui/issues/issue-44127.rs | 18 + .../ui/issues/issue-44216-add-instant.rs | 11 + .../ui/issues/issue-44216-add-system-time.rs | 11 + .../ui/issues/issue-44216-sub-instant.rs | 11 + .../ui/issues/issue-44216-sub-system-time.rs | 11 + .../rust/rustc/ui/issues/issue-44239.rs | 10 + .../rust/rustc/ui/issues/issue-44247.rs | 20 + .../rust/rustc/ui/issues/issue-44255.rs | 30 + .../rust/rustc/ui/issues/issue-44373-2.rs | 12 + .../rust/rustc/ui/issues/issue-44373.rs | 6 + .../rust/rustc/ui/issues/issue-44405.rs | 23 + .../rust/rustc/ui/issues/issue-44406.rs | 11 + .../rust/rustc/ui/issues/issue-4446.rs | 16 + .../rust/rustc/ui/issues/issue-4448.rs | 17 + .../rust/rustc/ui/issues/issue-4464.rs | 8 + .../rust/rustc/ui/issues/issue-44730.rs | 16 + .../rust/rustc/ui/issues/issue-44851.rs | 16 + .../issues/issue-45087-unreachable-unsafe.rs | 6 + ...sue-45107-unnecessary-unsafe-in-closure.rs | 26 + .../rust/rustc/ui/issues/issue-45124.rs | 19 + .../rust/rustc/ui/issues/issue-45152.rs | 25 + .../rust/rustc/ui/issues/issue-45157.rs | 33 + .../rust/rustc/ui/issues/issue-4517.rs | 9 + .../rust/rustc/ui/issues/issue-45199.rs | 25 + .../rust/rustc/ui/issues/issue-45296.rs | 6 + .../rust/rustc/ui/issues/issue-4541.rs | 24 + .../rust/rustc/ui/issues/issue-4542.rs | 14 + .../rust/rustc/ui/issues/issue-45425.rs | 13 + .../rust/rustc/ui/issues/issue-4545.rs | 8 + .../rust/rustc/ui/issues/issue-45510.rs | 33 + .../rust/rustc/ui/issues/issue-45562.rs | 7 + .../issue-45696-long-live-borrows-in-boxes.rs | 115 + .../issue-45696-no-variant-box-recur.rs | 51 + .../issue-45696-scribble-on-boxed-borrow.rs | 68 + .../rust/rustc/ui/issues/issue-45697-1.rs | 26 + .../rust/rustc/ui/issues/issue-45697.rs | 26 + .../issues/issue-45729-unsafe-in-generator.rs | 10 + .../rust/rustc/ui/issues/issue-45730.rs | 10 + .../rust/rustc/ui/issues/issue-45731.rs | 28 + ...tern-crate-rename-suggestion-formatting.rs | 6 + .../rust/rustc/ui/issues/issue-45801.rs | 26 + .../issue-45829/auxiliary/issue-45829-a.rs | 2 + .../issue-45829/auxiliary/issue-45829-b.rs | 2 + .../ui/issues/issue-45829/import-self.rs | 20 + .../ui/issues/issue-45829/import-twice.rs | 10 + .../ui/issues/issue-45829/issue-45829.rs | 10 + .../issue-45829/rename-extern-vs-use.rs | 12 + .../issue-45829/rename-extern-with-tab.rs | 9 + .../ui/issues/issue-45829/rename-extern.rs | 9 + .../issue-45829/rename-use-vs-extern.rs | 8 + .../issue-45829/rename-use-with-tabs.rs | 13 + .../ui/issues/issue-45829/rename-with-path.rs | 5 + .../rustc/ui/issues/issue-45829/rename.rs | 8 + .../rust/rustc/ui/issues/issue-45965.rs | 5 + .../rust/rustc/ui/issues/issue-46023.rs | 9 + .../rust/rustc/ui/issues/issue-46036.rs | 13 + .../rust/rustc/ui/issues/issue-46069.rs | 24 + .../rust/rustc/ui/issues/issue-46095.rs | 31 + .../rust/rustc/ui/issues/issue-46101.rs | 8 + .../rust/rustc/ui/issues/issue-46112.rs | 11 + .../rust/rustc/ui/issues/issue-46186.rs | 9 + .../rust/rustc/ui/issues/issue-46302.rs | 10 + .../rust/rustc/ui/issues/issue-46311.rs | 5 + .../rust/rustc/ui/issues/issue-46332.rs | 12 + .../rust/rustc/ui/issues/issue-46438.rs | 14 + .../rust/rustc/ui/issues/issue-46471-1.rs | 9 + .../rust/rustc/ui/issues/issue-46471.rs | 8 + .../rust/rustc/ui/issues/issue-46472.rs | 7 + .../rust/rustc/ui/issues/issue-46519.rs | 31 + .../rust/rustc/ui/issues/issue-46553.rs | 24 + .../rust/rustc/ui/issues/issue-46576.rs | 24 + .../rust/rustc/ui/issues/issue-46604.rs | 8 + ...6756-consider-borrowing-cast-or-binexpr.rs | 17 + .../rust/rustc/ui/issues/issue-46771.rs | 5 + .../rust/rustc/ui/issues/issue-46845.rs | 33 + .../rust/rustc/ui/issues/issue-46855.rs | 25 + .../issues/issue-46920-byte-array-patterns.rs | 29 + .../rust/rustc/ui/issues/issue-46959.rs | 10 + .../rust/rustc/ui/issues/issue-46964.rs | 20 + .../rust/rustc/ui/issues/issue-46983.rs | 7 + ...-47073-zero-padded-tuple-struct-indices.rs | 13 + .../rust/rustc/ui/issues/issue-47094.rs | 17 + .../rust/rustc/ui/issues/issue-47139-1.rs | 79 + .../rust/rustc/ui/issues/issue-47139-2.rs | 67 + .../rust/rustc/ui/issues/issue-47184.rs | 5 + .../rust/rustc/ui/issues/issue-47309.rs | 22 + .../rust/rustc/ui/issues/issue-4734.rs | 38 + .../rust/rustc/ui/issues/issue-4735.rs | 20 + .../rust/rustc/ui/issues/issue-4736.rs | 6 + .../rust/rustc/ui/issues/issue-47364.rs | 60 + .../rust/rustc/ui/issues/issue-47377.rs | 7 + .../rust/rustc/ui/issues/issue-47380.rs | 6 + .../rust/rustc/ui/issues/issue-47412.rs | 22 + .../rust/rustc/ui/issues/issue-47486.rs | 5 + .../rust/rustc/ui/issues/issue-47511.rs | 26 + .../rust/rustc/ui/issues/issue-4759-1.rs | 5 + .../rust/rustc/ui/issues/issue-4759.rs | 21 + .../rust/rustc/ui/issues/issue-47623.rs | 4 + .../rust/rustc/ui/issues/issue-47638.rs | 11 + .../rust/rustc/ui/issues/issue-47646.rs | 14 + .../rust/rustc/ui/issues/issue-47673.rs | 7 + .../rust/rustc/ui/issues/issue-47703-1.rs | 24 + .../rust/rustc/ui/issues/issue-47703-tuple.rs | 12 + .../rust/rustc/ui/issues/issue-47703.rs | 19 + .../rust/rustc/ui/issues/issue-47706-trait.rs | 9 + .../rust/rustc/ui/issues/issue-47706.rs | 30 + .../rust/rustc/ui/issues/issue-47715.rs | 29 + .../rust/rustc/ui/issues/issue-47722.rs | 18 + .../rust/rustc/ui/issues/issue-47725.rs | 30 + .../rust/rustc/ui/issues/issue-47789.rs | 11 + .../rust/rustc/ui/issues/issue-48006.rs | 16 + .../rust/rustc/ui/issues/issue-48131.rs | 31 + .../rust/rustc/ui/issues/issue-48132.rs | 32 + .../rust/rustc/ui/issues/issue-48159.rs | 28 + .../rust/rustc/ui/issues/issue-48179.rs | 39 + .../rust/rustc/ui/issues/issue-48276.rs | 34 + .../rust/rustc/ui/issues/issue-4830.rs | 12 + .../rust/rustc/ui/issues/issue-48364.rs | 7 + .../rust/rustc/ui/issues/issue-48508-aux.rs | 8 + .../rust/rustc/ui/issues/issue-48508.rs | 22 + .../rust/rustc/ui/issues/issue-48551.rs | 35 + .../rust/rustc/ui/issues/issue-48636.rs | 13 + .../rust/rustc/ui/issues/issue-4865-1.rs | 34 + .../rust/rustc/ui/issues/issue-4865-2.rs | 25 + .../rust/rustc/ui/issues/issue-4865-3.rs | 18 + .../rust/rustc/ui/issues/issue-48728.rs | 14 + .../rust/rustc/ui/issues/issue-4875.rs | 16 + .../rust/rustc/ui/issues/issue-48803.rs | 14 + .../rust/rustc/ui/issues/issue-48838.rs | 6 + .../rust/rustc/ui/issues/issue-48962.rs | 35 + .../rust/rustc/ui/issues/issue-48984.rs | 10 + .../rust/rustc/ui/issues/issue-49040.rs | 4 + .../rust/rustc/ui/issues/issue-49074.rs | 14 + .../rust/rustc/ui/issues/issue-49257.rs | 15 + .../rust/rustc/ui/issues/issue-49298.rs | 43 + .../rust/rustc/ui/issues/issue-4935.rs | 7 + .../rust/rustc/ui/issues/issue-49544.rs | 10 + .../rust/rustc/ui/issues/issue-49556.rs | 14 + .../rust/rustc/ui/issues/issue-49579.rs | 15 + ...orthand-field-patterns-in-pattern-macro.rs | 17 + .../rust/rustc/ui/issues/issue-49632.rs | 9 + .../rust/rustc/ui/issues/issue-4968.rs | 11 + .../rust/rustc/ui/issues/issue-49685.rs | 14 + .../rust/rustc/ui/issues/issue-4972.rs | 19 + .../rust/rustc/ui/issues/issue-49824.rs | 10 + .../issue-49851/compiler-builtins-error.rs | 10 + .../rust/rustc/ui/issues/issue-49854.rs | 10 + .../rust/rustc/ui/issues/issue-49919.rs | 8 + .../rustc/ui/issues/issue-49934-errors.rs | 14 + .../rust/rustc/ui/issues/issue-49934.rs | 36 + .../rust/rustc/ui/issues/issue-49955-2.rs | 20 + .../rust/rustc/ui/issues/issue-49955.rs | 21 + .../rust/rustc/ui/issues/issue-49973.rs | 12 + ...e-5008-borrowed-traitobject-method-call.rs | 35 + .../rust/rustc/ui/issues/issue-50187.rs | 40 + .../option-as_deref.rs | 5 + .../option-as_deref_mut.rs | 5 + .../result-as_deref.rs | 5 + .../result-as_deref_mut.rs | 5 + .../rust/rustc/ui/issues/issue-50301.rs | 33 + .../rust/rustc/ui/issues/issue-50403.rs | 6 + .../rust/rustc/ui/issues/issue-50411.rs | 12 + .../rust/rustc/ui/issues/issue-50415.rs | 17 + .../rust/rustc/ui/issues/issue-50442.rs | 14 + .../rust/rustc/ui/issues/issue-50471.rs | 10 + .../rust/rustc/ui/issues/issue-50480.rs | 9 + .../rust/rustc/ui/issues/issue-50518.rs | 41 + .../rust/rustc/ui/issues/issue-50571.rs | 9 + .../rust/rustc/ui/issues/issue-50576.rs | 7 + .../rust/rustc/ui/issues/issue-50581.rs | 4 + .../rust/rustc/ui/issues/issue-50582.rs | 6 + .../rust/rustc/ui/issues/issue-50585.rs | 6 + .../rust/rustc/ui/issues/issue-50599.rs | 6 + .../rust/rustc/ui/issues/issue-5060.rs | 17 + .../rust/rustc/ui/issues/issue-50600.rs | 6 + .../rust/rustc/ui/issues/issue-50618.rs | 20 + .../rust/rustc/ui/issues/issue-5062.rs | 3 + .../rust/rustc/ui/issues/issue-5067.rs | 76 + .../ui/issues/issue-50687-ice-on-borrow.rs | 42 + .../rust/rustc/ui/issues/issue-50688.rs | 4 + .../rust/rustc/ui/issues/issue-50689.rs | 10 + .../rust/rustc/ui/issues/issue-50714-1.rs | 12 + .../rust/rustc/ui/issues/issue-50714.rs | 4 + .../rust/rustc/ui/issues/issue-50731.rs | 7 + .../rust/rustc/ui/issues/issue-50761.rs | 24 + .../rust/rustc/ui/issues/issue-50781.rs | 20 + .../rust/rustc/ui/issues/issue-50802.rs | 9 + .../rust/rustc/ui/issues/issue-50811.rs | 57 + .../rust/rustc/ui/issues/issue-50825-1.rs | 23 + .../rust/rustc/ui/issues/issue-50825.rs | 16 + .../auxiliary/lib.rs | 19 + .../issue-50865-private-impl-trait/main.rs | 17 + .../rust/rustc/ui/issues/issue-5099.rs | 14 + .../rust/rustc/ui/issues/issue-50993.rs | 10 + .../rust/rustc/ui/issues/issue-5100.rs | 58 + .../rust/rustc/ui/issues/issue-51022.rs | 3 + .../rust/rustc/ui/issues/issue-51044.rs | 31 + .../rust/rustc/ui/issues/issue-51102.rs | 39 + .../rust/rustc/ui/issues/issue-51116.rs | 15 + .../rust/rustc/ui/issues/issue-51154.rs | 7 + .../rust/rustc/ui/issues/issue-51185.rs | 9 + .../rust/rustc/ui/issues/issue-51244.rs | 5 + .../rust/rustc/ui/issues/issue-51301.rs | 36 + .../rust/rustc/ui/issues/issue-51345-2.rs | 9 + .../rust/rustc/ui/issues/issue-51345.rs | 9 + .../rust/rustc/ui/issues/issue-51515.rs | 13 + .../rust/rustc/ui/issues/issue-5153.rs | 13 + .../rust/rustc/ui/issues/issue-51582.rs | 19 + .../rust/rustc/ui/issues/issue-51602.rs | 7 + ...ue-51632-try-desugar-incompatible-types.rs | 13 + .../rust/rustc/ui/issues/issue-51655.rs | 15 + .../rust/rustc/ui/issues/issue-51714.rs | 14 + .../rust/rustc/ui/issues/issue-51770.rs | 21 + .../rust/rustc/ui/issues/issue-51798.rs | 15 + .../rust/rustc/ui/issues/issue-51848.rs | 21 + .../rust/rustc/ui/issues/issue-51874.rs | 4 + .../rust/rustc/ui/issues/issue-51907.rs | 20 + .../rust/rustc/ui/issues/issue-5192.rs | 42 + .../rust/rustc/ui/issues/issue-51947.rs | 18 + .../issue-52023-array-size-pointer-cast.rs | 5 + .../rust/rustc/ui/issues/issue-52049.rs | 9 + .../rust/rustc/ui/issues/issue-52057.rs | 23 + .../rust/rustc/ui/issues/issue-52060.rs | 9 + .../issue-52126-assign-op-invariance.rs | 50 + .../issue-52140/auxiliary/some_crate.rs | 6 + .../rust/rustc/ui/issues/issue-52140/main.rs | 14 + .../issue-52141/auxiliary/some_crate.rs | 6 + .../rust/rustc/ui/issues/issue-52141/main.rs | 17 + .../rust/rustc/ui/issues/issue-5216.rs | 11 + .../rust/rustc/ui/issues/issue-52169.rs | 15 + .../rust/rustc/ui/issues/issue-52213.rs | 15 + .../rust/rustc/ui/issues/issue-52240.rs | 17 + .../rust/rustc/ui/issues/issue-52262.rs | 26 + .../rust/rustc/ui/issues/issue-5239-1.rs | 7 + .../rust/rustc/ui/issues/issue-5239-2.rs | 10 + .../rust/rustc/ui/issues/issue-5243.rs | 18 + .../rust/rustc/ui/issues/issue-52489.rs | 9 + .../rust/rustc/ui/issues/issue-52496.rs | 13 + .../rust/rustc/ui/issues/issue-52533-1.rs | 12 + .../rust/rustc/ui/issues/issue-52533.rs | 8 + .../rust/rustc/ui/issues/issue-52557.rs | 31 + .../ui/issues/issue-52705/auxiliary/png2.rs | 4 + .../rust/rustc/ui/issues/issue-52705/main.rs | 16 + .../rust/rustc/ui/issues/issue-52717.rs | 14 + .../rust/rustc/ui/issues/issue-5280.rs | 19 + .../rust/rustc/ui/issues/issue-52891.rs | 39 + .../rust/rustc/ui/issues/issue-52992.rs | 26 + .../rust/rustc/ui/issues/issue-5315.rs | 10 + .../issue-5321-immediates-with-bare-self.rs | 16 + .../rust/rustc/ui/issues/issue-53251.rs | 22 + .../rust/rustc/ui/issues/issue-53275.rs | 10 + .../rust/rustc/ui/issues/issue-53300.rs | 13 + .../rust/rustc/ui/issues/issue-53333.rs | 10 + .../rust/rustc/ui/issues/issue-53348.rs | 16 + .../rust/rustc/ui/issues/issue-53419.rs | 9 + .../rust/rustc/ui/issues/issue-53498.rs | 18 + .../rust/rustc/ui/issues/issue-5353.rs | 19 + .../rust/rustc/ui/issues/issue-53565.rs | 8 + .../rust/rustc/ui/issues/issue-53568.rs | 48 + .../rust/rustc/ui/issues/issue-5358-1.rs | 14 + .../issues/issue-53675-a-test-called-panic.rs | 37 + .../rust/rustc/ui/issues/issue-53692.rs | 18 + .../rust/rustc/ui/issues/issue-53712.rs | 10 + .../rust/rustc/ui/issues/issue-53728.rs | 20 + .../issue-53787-inline-assembler-macro.rs | 27 + .../rust/rustc/ui/issues/issue-53843.rs | 27 + .../rust/rustc/ui/issues/issue-53912.rs | 38 + .../rust/rustc/ui/issues/issue-54044.rs | 15 + .../rust/rustc/ui/issues/issue-54062.rs | 13 + .../rust/rustc/ui/issues/issue-54094.rs | 15 + .../rust/rustc/ui/issues/issue-54189.rs | 7 + .../rust/rustc/ui/issues/issue-54302-cases.rs | 86 + .../rust/rustc/ui/issues/issue-54302.rs | 20 + .../rust/rustc/ui/issues/issue-54348.rs | 8 + .../rust/rustc/ui/issues/issue-54387.rs | 13 + .../rust/rustc/ui/issues/issue-5439.rs | 22 + .../rust/rustc/ui/issues/issue-54410.rs | 9 + ...issue-54462-mutable-noalias-correctness.rs | 26 + .../rust/rustc/ui/issues/issue-54467.rs | 47 + .../rustc/ui/issues/issue-54477-reduced-2.rs | 27 + .../rust/rustc/ui/issues/issue-54521-1.rs | 17 + .../rust/rustc/ui/issues/issue-54521-2.rs | 23 + .../rust/rustc/ui/issues/issue-54521.rs | 23 + .../rust/rustc/ui/issues/issue-54582.rs | 17 + .../rust/rustc/ui/issues/issue-54696.rs | 9 + .../rust/rustc/ui/issues/issue-54943-1.rs | 14 + .../rust/rustc/ui/issues/issue-54943-2.rs | 17 + .../rust/rustc/ui/issues/issue-54943-3.rs | 21 + .../rust/rustc/ui/issues/issue-54943.rs | 11 + .../rust/rustc/ui/issues/issue-54954.rs | 20 + .../rust/rustc/ui/issues/issue-54966.rs | 7 + .../rust/rustc/ui/issues/issue-5500-1.rs | 16 + .../rust/rustc/ui/issues/issue-5518.rs | 9 + .../rust/rustc/ui/issues/issue-5521.rs | 18 + .../rust/rustc/ui/issues/issue-5530.rs | 41 + .../rust/rustc/ui/issues/issue-55376.rs | 17 + .../rust/rustc/ui/issues/issue-55380.rs | 29 + .../rust/rustc/ui/issues/issue-5550.rs | 10 + .../rust/rustc/ui/issues/issue-55511.rs | 20 + .../rust/rustc/ui/issues/issue-5554.rs | 30 + .../rust/rustc/ui/issues/issue-55587.rs | 6 + .../rust/rustc/ui/issues/issue-5572.rs | 8 + .../rust/rustc/ui/issues/issue-55731.rs | 53 + .../rust/rustc/ui/issues/issue-55796.rs | 29 + .../rust/rustc/ui/issues/issue-55846.rs | 40 + .../rust/rustc/ui/issues/issue-56031.rs | 7 + .../rust/rustc/ui/issues/issue-56128.rs | 16 + .../rust/rustc/ui/issues/issue-56175.rs | 10 + .../rust/rustc/ui/issues/issue-56199.rs | 23 + .../rust/rustc/ui/issues/issue-56202.rs | 18 + .../rust/rustc/ui/issues/issue-56229.rs | 36 + .../rust/rustc/ui/issues/issue-56237.rs | 14 + .../rust/rustc/ui/issues/issue-56411-aux.rs | 6 + .../rust/rustc/ui/issues/issue-56411.rs | 19 + .../rust/rustc/ui/issues/issue-56488.rs | 14 + .../rust/rustc/ui/issues/issue-5666.rs | 28 + .../rust/rustc/ui/issues/issue-56685.rs | 45 + .../rust/rustc/ui/issues/issue-56762.rs | 25 + .../rust/rustc/ui/issues/issue-56806.rs | 7 + .../rust/rustc/ui/issues/issue-56835.rs | 10 + .../rust/rustc/ui/issues/issue-56870.rs | 39 + .../rust/rustc/ui/issues/issue-5688.rs | 21 + .../rust/rustc/ui/issues/issue-56943.rs | 9 + .../rust/rustc/ui/issues/issue-5708.rs | 56 + .../rust/rustc/ui/issues/issue-57156.rs | 24 + .../rust/rustc/ui/issues/issue-57162.rs | 8 + .../rust/rustc/ui/issues/issue-5718.rs | 27 + .../rust/rustc/ui/issues/issue-57198-pass.rs | 10 + .../rust/rustc/ui/issues/issue-57198.rs | 9 + .../rust/rustc/ui/issues/issue-57271.rs | 25 + .../rust/rustc/ui/issues/issue-57362-1.rs | 24 + .../rust/rustc/ui/issues/issue-57362-2.rs | 26 + .../issue-57399-self-return-impl-trait.rs | 23 + .../rust/rustc/ui/issues/issue-5741.rs | 10 + .../rust/rustc/ui/issues/issue-57410-1.rs | 19 + .../rust/rustc/ui/issues/issue-57410.rs | 18 + .../rust/rustc/ui/issues/issue-57472.rs | 36 + .../rust/rustc/ui/issues/issue-5754.rs | 17 + .../rust/rustc/ui/issues/issue-57597.rs | 81 + .../rust/rustc/ui/issues/issue-57684.rs | 38 + .../rust/rustc/ui/issues/issue-57741-1.rs | 19 + .../rust/rustc/ui/issues/issue-57741.rs | 32 + .../rust/rustc/ui/issues/issue-57781.rs | 21 + .../rust/rustc/ui/issues/issue-57819.rs | 48 + .../rust/rustc/ui/issues/issue-57843.rs | 25 + .../rust/rustc/ui/issues/issue-5791.rs | 15 + .../rust/rustc/ui/issues/issue-57924.rs | 11 + .../rust/rustc/ui/issues/issue-58022.rs | 20 + .../rust/rustc/ui/issues/issue-58212.rs | 16 + .../rust/rustc/ui/issues/issue-58319.rs | 622 + .../rust/rustc/ui/issues/issue-58344.rs | 51 + .../issue-58375-monomorphize-default-impls.rs | 25 + .../issue-58435-ice-with-assoc-const.rs | 19 + .../rust/rustc/ui/issues/issue-5844.rs | 8 + .../rust/rustc/ui/issues/issue-58463.rs | 11 + .../rust/rustc/ui/issues/issue-58712.rs | 15 + .../rust/rustc/ui/issues/issue-58734.rs | 23 + .../rust/rustc/ui/issues/issue-5883.rs | 14 + .../rust/rustc/ui/issues/issue-5884.rs | 21 + .../rust/rustc/ui/issues/issue-58856-1.rs | 9 + .../rust/rustc/ui/issues/issue-58856-2.rs | 15 + .../rust/rustc/ui/issues/issue-58857.rs | 8 + .../rust/rustc/ui/issues/issue-5900.rs | 16 + .../rust/rustc/ui/issues/issue-59020.rs | 28 + .../rust/rustc/ui/issues/issue-59029-1.rs | 10 + .../rust/rustc/ui/issues/issue-59029-2.rs | 9 + .../rust/rustc/ui/issues/issue-5917.rs | 10 + .../rust/rustc/ui/issues/issue-5927.rs | 8 + .../rust/rustc/ui/issues/issue-59326.rs | 27 + .../rust/rustc/ui/issues/issue-59488.rs | 35 + .../rust/rustc/ui/issues/issue-59494.rs | 24 + .../rust/rustc/ui/issues/issue-5950.rs | 10 + .../rust/rustc/ui/issues/issue-59508-1.rs | 19 + .../rust/rustc/ui/issues/issue-59508.rs | 17 + .../rust/rustc/ui/issues/issue-59756.rs | 22 + .../rust/rustc/ui/issues/issue-59764.rs | 137 + .../rust/rustc/ui/issues/issue-5988.rs | 25 + .../rust/rustc/ui/issues/issue-59896.rs | 10 + .../rust/rustc/ui/issues/issue-5997-enum.rs | 11 + .../rust/rustc/ui/issues/issue-5997-struct.rs | 11 + .../rust/rustc/ui/issues/issue-5997.rs | 16 + .../rust/rustc/ui/issues/issue-60057.rs | 20 + .../rust/rustc/ui/issues/issue-60075.rs | 12 + .../rust/rustc/ui/issues/issue-60218.rs | 20 + .../rust/rustc/ui/issues/issue-60283.rs | 21 + .../rust/rustc/ui/issues/issue-60622.rs | 19 + .../rust/rustc/ui/issues/issue-60662.rs | 12 + .../rust/rustc/ui/issues/issue-60989.rs | 19 + .../rust/rustc/ui/issues/issue-61106.rs | 7 + .../rust/rustc/ui/issues/issue-61108.rs | 8 + .../rust/rustc/ui/issues/issue-6117.rs | 13 + .../rust/rustc/ui/issues/issue-6128.rs | 25 + .../rust/rustc/ui/issues/issue-6130.rs | 11 + .../rust/rustc/ui/issues/issue-61475.rs | 16 + .../rust/rustc/ui/issues/issue-6153.rs | 14 + .../rust/rustc/ui/issues/issue-6157.rs | 24 + .../rust/rustc/ui/issues/issue-61623.rs | 12 + .../rust/rustc/ui/issues/issue-61696.rs | 67 + .../issue-61711-once-caused-rustc-inf-loop.rs | 12 + .../rust/rustc/ui/issues/issue-61858.rs | 4 + .../rust/rustc/ui/issues/issue-61882-2.rs | 12 + .../rust/rustc/ui/issues/issue-61882.rs | 10 + .../rust/rustc/ui/issues/issue-61894.rs | 22 + .../rust/rustc/ui/issues/issue-62375.rs | 10 + .../rust/rustc/ui/issues/issue-62480.rs | 13 + .../rust/rustc/ui/issues/issue-62554.rs | 7 + .../rust/rustc/ui/issues/issue-6318.rs | 23 + .../rust/rustc/ui/issues/issue-6334.rs | 47 + .../rust/rustc/ui/issues/issue-63364.rs | 11 + .../rust/rustc/ui/issues/issue-6341.rs | 12 + .../rust/rustc/ui/issues/issue-6344-let.rs | 16 + .../rust/rustc/ui/issues/issue-6344-match.rs | 19 + .../rust/rustc/ui/issues/issue-63983.rs | 16 + .../rust/rustc/ui/issues/issue-64430.rs | 15 + .../rust/rustc/ui/issues/issue-6449.rs | 45 + .../rust/rustc/ui/issues/issue-64559.rs | 7 + .../rust/rustc/ui/issues/issue-6458-1.rs | 9 + .../rust/rustc/ui/issues/issue-6458-2.rs | 6 + .../rust/rustc/ui/issues/issue-6458-3.rs | 7 + .../rust/rustc/ui/issues/issue-6458-4.rs | 8 + .../rust/rustc/ui/issues/issue-6458.rs | 15 + .../rust/rustc/ui/issues/issue-64593.rs | 13 + .../rust/rustc/ui/issues/issue-64620.rs | 6 + .../rust/rustc/ui/issues/issue-6470.rs | 19 + .../rust/rustc/ui/issues/issue-64732.rs | 10 + .../ui/issues/issue-64792-bad-unicode-ctor.rs | 6 + .../rust/rustc/ui/issues/issue-65131.rs | 19 + ...issue-65284-suggest-generic-trait-bound.rs | 12 + .../rust/rustc/ui/issues/issue-65462.rs | 16 + .../rust/rustc/ui/issues/issue-6557.rs | 11 + .../rust/rustc/ui/issues/issue-65611.rs | 64 + .../issue-65634-raw-ident-suggestion.rs | 23 + .../rust/rustc/ui/issues/issue-65673.rs | 13 + .../rust/rustc/ui/issues/issue-6596-1.rs | 11 + .../rust/rustc/ui/issues/issue-6596-2.rs | 14 + .../rust/rustc/ui/issues/issue-66308.rs | 9 + .../rust/rustc/ui/issues/issue-66353.rs | 16 + .../rust/rustc/ui/issues/issue-6642.rs | 10 + .../rust/rustc/ui/issues/issue-66473.rs | Bin 0 -> 128 bytes .../issues/issue-66667-function-cmp-cycle.rs | 17 + .../issue-66702-break-outside-loop-val.rs | 10 + .../rust/rustc/ui/issues/issue-66706.rs | 26 + .../rust/rustc/ui/issues/issue-66768.rs | 206 + .../rust/rustc/ui/issues/issue-66851.rs | 21 + ...issue-66923-show-error-for-correct-call.rs | 16 + ...67037-pat-tup-scrut-ty-diff-less-fields.rs | 22 + .../issue-67039-unsound-pin-partialeq.rs | 28 + .../rust/rustc/ui/issues/issue-6738.rs | 11 + .../rust/rustc/ui/issues/issue-67552.rs | 32 + ...68000-unicode-ident-after-missing-comma.rs | 7 + .../rust/rustc/ui/issues/issue-6801.rs | 22 + .../ui/issues/issue-68010-large-zst-consts.rs | 6 + .../rust/rustc/ui/issues/issue-6804.rs | 26 + .../issue-68091-unicode-ident-after-if.rs | 10 + ...092-unicode-ident-after-incomplete-expr.rs | 10 + .../rust/rustc/ui/issues/issue-68103.rs | 7 + .../issues/issue-68696-catch-during-unwind.rs | 27 + .../rust/rustc/ui/issues/issue-6892.rs | 59 + .../rust/rustc/ui/issues/issue-68951.rs | 10 + .../rust/rustc/ui/issues/issue-6898.rs | 34 + .../rust/rustc/ui/issues/issue-69130.rs | 8 + .../rust/rustc/ui/issues/issue-6919.rs | 12 + .../issue-69225-SCEVAddExpr-wrap-flag.rs | 34 + ...issue-69225-layout-repeated-checked-add.rs | 32 + .../rust/rustc/ui/issues/issue-69306.rs | 46 + .../rust/rustc/ui/issues/issue-6936.rs | 35 + .../issue-69396-const-no-type-in-macro.rs | 18 + .../rust/rustc/ui/issues/issue-69455.rs | 31 + .../rust/rustc/ui/issues/issue-69532.rs | 25 + ...issue-69602-type-err-during-codegen-ice.rs | 23 + .../rust/rustc/ui/issues/issue-69683.rs | 33 + .../rust/rustc/ui/issues/issue-69725.rs | 12 + .../rust/rustc/ui/issues/issue-69841.rs | 32 + .../rust/rustc/ui/issues/issue-6991.rs | 9 + .../rust/rustc/ui/issues/issue-70041.rs | 14 + .../rust/rustc/ui/issues/issue-70093.rs | 9 + .../rust/rustc/ui/issues/issue-7012.rs | 23 + .../rust/rustc/ui/issues/issue-7013.rs | 29 + .../rust/rustc/ui/issues/issue-70381.rs | 7 + .../rust/rustc/ui/issues/issue-7044.rs | 5 + .../rust/rustc/ui/issues/issue-7061.rs | 11 + .../rust/rustc/ui/issues/issue-70673.rs | 13 + ...sue-70724-add_type_neq_err_label-unwrap.rs | 11 + .../rust/rustc/ui/issues/issue-70746.rs | 30 + .../rust/rustc/ui/issues/issue-7092.rs | 16 + .../rust/rustc/ui/issues/issue-71036.rs | 18 + .../rust/rustc/ui/issues/issue-71406.rs | 7 + .../rust/rustc/ui/issues/issue-71584.rs | 6 + .../rust/rustc/ui/issues/issue-71676-1.rs | 54 + .../rust/rustc/ui/issues/issue-71676-2.rs | 43 + .../rust/rustc/ui/issues/issue-7178.rs | 11 + .../rust/rustc/ui/issues/issue-72002.rs | 30 + .../rust/rustc/ui/issues/issue-72076.rs | 7 + .../rust/rustc/ui/issues/issue-7222.rs | 13 + .../rust/rustc/ui/issues/issue-72253.rs | 7 + .../rust/rustc/ui/issues/issue-72278.rs | 20 + .../rust/rustc/ui/issues/issue-72373.rs | 10 + .../rust/rustc/ui/issues/issue-72455.rs | 28 + .../rust/rustc/ui/issues/issue-7246.rs | 11 + .../rust/rustc/ui/issues/issue-72554.rs | 21 + .../rust/rustc/ui/issues/issue-72574-1.rs | 11 + .../rust/rustc/ui/issues/issue-72574-2.rs | 13 + .../rust/rustc/ui/issues/issue-7268.rs | 11 + .../rust/rustc/ui/issues/issue-72690.rs | 63 + .../ui/issues/issue-72839-error-overflow.rs | 20 + .../issue-72933-match-stack-overflow.rs | 5209 ++++++++ .../rust/rustc/ui/issues/issue-73112.rs | 14 + .../rust/rustc/ui/issues/issue-73229.rs | 34 + .../rust/rustc/ui/issues/issue-73427.rs | 45 + .../rust/rustc/ui/issues/issue-7344.rs | 23 + .../rust/rustc/ui/issues/issue-73541-1.rs | 13 + .../rust/rustc/ui/issues/issue-73541-2.rs | 21 + .../rust/rustc/ui/issues/issue-73541-3.rs | 10 + .../rust/rustc/ui/issues/issue-73541.rs | 10 + .../rust/rustc/ui/issues/issue-7364.rs | 11 + .../rust/rustc/ui/issues/issue-73886.rs | 7 + .../rust/rustc/ui/issues/issue-74082.rs | 10 + .../rust/rustc/ui/issues/issue-74086.rs | 5 + .../ui/issues/issue-74236/auxiliary/dep.rs | 9 + .../rust/rustc/ui/issues/issue-74236/main.rs | 10 + .../issue-74564-if-expr-stack-overflow.rs | 10421 ++++++++++++++++ .../rust/rustc/ui/issues/issue-74614.rs | 19 + .../rust/rustc/ui/issues/issue-74739.rs | 15 + .../ui/issues/issue-7519-match-unit-in-arg.rs | 13 + .../rust/rustc/ui/issues/issue-75283.rs | 7 + .../rust/rustc/ui/issues/issue-75307.rs | 4 + .../rust/rustc/ui/issues/issue-75599.rs | 25 + .../rust/rustc/ui/issues/issue-7563.rs | 29 + .../rust/rustc/ui/issues/issue-75704.rs | 8 + .../rust/rustc/ui/issues/issue-7575.rs | 18 + .../rust/rustc/ui/issues/issue-75763.rs | 16 + .../rust/rustc/ui/issues/issue-75777.rs | 18 + .../rust/rustc/ui/issues/issue-75906.rs | 14 + .../rust/rustc/ui/issues/issue-75907.rs | 19 + .../rust/rustc/ui/issues/issue-75907_b.rs | 12 + .../rust/rustc/ui/issues/issue-7607-1.rs | 10 + .../rust/rustc/ui/issues/issue-7607-2.rs | 17 + .../rust/rustc/ui/issues/issue-76077-1.rs | 19 + .../rust/rustc/ui/issues/issue-76077.rs | 11 + .../rust/rustc/ui/issues/issue-76179.rs | 20 + .../rust/rustc/ui/issues/issue-76191.rs | 20 + .../rust/rustc/ui/issues/issue-76547.rs | 39 + .../rust/rustc/ui/issues/issue-7660.rs | 19 + .../rust/rustc/ui/issues/issue-7663.rs | 33 + ...7673-cast-generically-implemented-trait.rs | 23 + .../rust/rustc/ui/issues/issue-77002.rs | 17 + .../rust/rustc/ui/issues/issue-77218.rs | 12 + .../rust/rustc/ui/issues/issue-7784.rs | 31 + .../rust/rustc/ui/issues/issue-77919.rs | 14 + .../rust/rustc/ui/issues/issue-77993-1.rs | 13 + .../rust/rustc/ui/issues/issue-77993-2.rs | 10 + .../rust/rustc/ui/issues/issue-78115.rs | 20 + .../rust/rustc/ui/issues/issue-7813.rs | 5 + .../rust/rustc/ui/issues/issue-78192.rs | 18 + .../rust/rustc/ui/issues/issue-78372.rs | 15 + .../rust/rustc/ui/issues/issue-78622.rs | 8 + .../rust/rustc/ui/issues/issue-7867.rs | 15 + .../rust/rustc/ui/issues/issue-7899.rs | 12 + .../rust/rustc/ui/issues/issue-7911.rs | 38 + .../rust/rustc/ui/issues/issue-7950.rs | 9 + .../rust/rustc/ui/issues/issue-7970a.rs | 9 + .../rust/rustc/ui/issues/issue-7970b.rs | 5 + .../rust/rustc/ui/issues/issue-8044.rs | 12 + .../rust/rustc/ui/issues/issue-811.rs | 27 + .../rust/rustc/ui/issues/issue-8153.rs | 17 + ...fault-method-self-inherit-builtin-trait.rs | 20 + .../rust/rustc/ui/issues/issue-8208.rs | 18 + .../rust/rustc/ui/issues/issue-8248.rs | 16 + .../rust/rustc/ui/issues/issue-8249.rs | 21 + .../rust/rustc/ui/issues/issue-8259.rs | 13 + .../rust/rustc/ui/issues/issue-8351-1.rs | 17 + .../rust/rustc/ui/issues/issue-8351-2.rs | 17 + .../rust/rustc/ui/issues/issue-8391.rs | 10 + .../rust/rustc/ui/issues/issue-8398.rs | 14 + .../rust/rustc/ui/issues/issue-8401.rs | 9 + .../rust/rustc/ui/issues/issue-8460-const.rs | 63 + .../rust/rustc/ui/issues/issue-8460.rs | 52 + .../rust/rustc/ui/issues/issue-8498.rs | 28 + .../rust/rustc/ui/issues/issue-8506.rs | 15 + .../rust/rustc/ui/issues/issue-8521.rs | 26 + .../rust/rustc/ui/issues/issue-8578.rs | 21 + .../rust/rustc/ui/issues/issue-8640.rs | 11 + .../rust/rustc/ui/issues/issue-868.rs | 19 + .../rust/rustc/ui/issues/issue-8709.rs | 15 + .../rust/rustc/ui/issues/issue-8727.rs | 17 + .../rust/rustc/ui/issues/issue-8761.rs | 11 + .../rust/rustc/ui/issues/issue-8767.rs | 6 + .../rust/rustc/ui/issues/issue-8783.rs | 25 + .../rust/rustc/ui/issues/issue-8827.rs | 54 + .../rust/rustc/ui/issues/issue-8851.rs | 31 + .../rust/rustc/ui/issues/issue-8860.rs | 50 + .../rust/rustc/ui/issues/issue-8898.rs | 19 + .../rust/rustc/ui/issues/issue-9047.rs | 15 + .../rust/rustc/ui/issues/issue-9110.rs | 18 + .../rust/rustc/ui/issues/issue-9123.rs | 9 + .../rust/rustc/ui/issues/issue-9129.rs | 36 + .../rust/rustc/ui/issues/issue-9155.rs | 13 + .../rust/rustc/ui/issues/issue-9188.rs | 12 + .../rust/rustc/ui/issues/issue-9243.rs | 17 + .../rust/rustc/ui/issues/issue-9249.rs | 7 + .../rust/rustc/ui/issues/issue-9259.rs | 17 + .../rust/rustc/ui/issues/issue-9382.rs | 42 + .../issue-9394-inherited-trait-calls.rs | 63 + .../rust/rustc/ui/issues/issue-9396.rs | 24 + .../rust/rustc/ui/issues/issue-9446.rs | 31 + .../rust/rustc/ui/issues/issue-948.rs | 16 + .../rust/rustc/ui/issues/issue-9575.rs | 8 + .../rust/rustc/ui/issues/issue-9719.rs | 42 + .../rust/rustc/ui/issues/issue-9725.rs | 8 + .../rust/rustc/ui/issues/issue-9737.rs | 11 + .../rust/rustc/ui/issues/issue-979.rs | 30 + .../rust/rustc/ui/issues/issue-9814.rs | 9 + .../rust/rustc/ui/issues/issue-9837.rs | 12 + .../rust/rustc/ui/issues/issue-9906.rs | 12 + .../rust/rustc/ui/issues/issue-9918.rs | 6 + .../rust/rustc/ui/issues/issue-9942.rs | 7 + .../rust/rustc/ui/issues/issue-9951.rs | 22 + .../rust/rustc/ui/issues/issue-9968.rs | 14 + .../rust/rustc/ui/issues/issue-pr29383.rs | 15 + .../type-arg-mismatch-due-to-impl-trait.rs | 17 + gcc/testsuite/rust/rustc/ui/istr.rs | 54 + .../rust/rustc/ui/item-name-overload.rs | 18 + .../rustc/ui/iterators/array-of-ranges.rs | 24 + .../rust/rustc/ui/iterators/array.rs | 10 + .../rust/rustc/ui/iterators/bound.rs | 5 + .../rust/rustc/ui/iterators/integral.rs | 27 + .../ui/iterators/into-iter-on-arrays-lint.rs | 62 + .../into-iterator-type-inference-shift.rs | 37 + .../issue-58952-filter-type-length.rs | 33 + .../iterators/iter-cloned-type-inference.rs | 17 + .../ui/iterators/iter-count-overflow-debug.rs | 17 + .../iterators/iter-count-overflow-ndebug.rs | 12 + .../ui/iterators/iter-map-fold-type-length.rs | 39 + .../iterators/iter-position-overflow-debug.rs | 23 + .../iter-position-overflow-ndebug.rs | 14 + .../rust/rustc/ui/iterators/iter-range.rs | 15 + .../ui/iterators/iter-step-overflow-debug.rs | 22 + .../ui/iterators/iter-step-overflow-ndebug.rs | 13 + .../ui/iterators/iter-sum-overflow-debug.rs | 28 + .../ui/iterators/iter-sum-overflow-ndebug.rs | 15 + .../iter-sum-overflow-overflow-checks.rs | 28 + .../rust/rustc/ui/iterators/ranges.rs | 10 + .../rustc/ui/iterators/skip-count-overflow.rs | 9 + .../rust/rustc/ui/iterators/string.rs | 7 + gcc/testsuite/rust/rustc/ui/json-and-color.rs | 4 + .../rust/rustc/ui/json-and-error-format.rs | 4 + .../ui/json-bom-plus-crlf-multifile-aux.rs | 28 + .../rustc/ui/json-bom-plus-crlf-multifile.rs | 12 + .../rust/rustc/ui/json-bom-plus-crlf.rs | 27 + gcc/testsuite/rust/rustc/ui/json-invalid.rs | 4 + gcc/testsuite/rust/rustc/ui/json-multiple.rs | 6 + gcc/testsuite/rust/rustc/ui/json-options.rs | 6 + gcc/testsuite/rust/rustc/ui/json-short.rs | 2 + .../rustc/ui/keyword-changes-2012-07-31.rs | 21 + .../keyword-extern-as-identifier-expr.rs | 4 + .../keyword-extern-as-identifier-pat.rs | 4 + .../keyword-extern-as-identifier-type.rs | 4 + .../keyword-extern-as-identifier-use.rs | 5 + .../ui/keyword/keyword-false-as-identifier.rs | 4 + .../ui/keyword/keyword-self-as-identifier.rs | 4 + .../ui/keyword/keyword-super-as-identifier.rs | 4 + .../rust/rustc/ui/keyword/keyword-super.rs | 4 + .../ui/keyword/keyword-true-as-identifier.rs | 4 + .../ui/kindck-implicit-close-over-mut-var.rs | 50 + .../rust/rustc/ui/kindck/kindck-copy.rs | 72 + .../ui/kindck/kindck-impl-type-params-2.rs | 16 + .../ui/kindck/kindck-impl-type-params.rs | 51 + .../ui/kindck/kindck-inherited-copy-bound.rs | 35 + .../rustc/ui/kindck/kindck-nonsendable-1.rs | 12 + .../rustc/ui/kindck/kindck-send-object.rs | 27 + .../rustc/ui/kindck/kindck-send-object1.rs | 34 + .../rustc/ui/kindck/kindck-send-object2.rs | 25 + .../rust/rustc/ui/kindck/kindck-send-owned.rs | 17 + .../rustc/ui/kindck/kindck-send-unsafe.rs | 12 + .../rust/rustc/ui/kinds-in-metadata.rs | 18 + .../label/label-beginning-with-underscore.rs | 11 + .../rust/rustc/ui/label/label-static.rs | 6 + .../rust/rustc/ui/label/label-underscore.rs | 6 + .../ui/label/label_break_value_continue.rs | 28 + .../label_break_value_desugared_break.rs | 13 + .../label/label_break_value_illegal_uses.rs | 22 + .../label_break_value_unlabeled_break.rs | 21 + .../rust/rustc/ui/lambda-infer-unresolved.rs | 16 + .../rust/rustc/ui/lambda-var-hygiene.rs | 13 + .../rustc/ui/lang-item-missing-generator.rs | 20 + .../rust/rustc/ui/lang-item-missing.rs | 13 + gcc/testsuite/rust/rustc/ui/large-records.rs | 39 + .../rust/rustc/ui/last-use-in-block.rs | 22 + .../rust/rustc/ui/last-use-in-cap-clause.rs | 18 + .../rust/rustc/ui/last-use-is-capture.rs | 16 + gcc/testsuite/rust/rustc/ui/layout/debug.rs | 23 + .../homogeneous-aggr-zero-sized-c-struct.rs | 37 + .../homogeneous-aggr-zero-sized-repr-rust.rs | 74 + ...ue-60431-unsized-tail-behind-projection.rs | 36 + .../ui/layout/unsafe-cell-hides-niche.rs | 33 + .../rustc/ui/layout/zero-sized-array-union.rs | 96 + gcc/testsuite/rust/rustc/ui/lazy-and-or.rs | 13 + gcc/testsuite/rust/rustc/ui/lazy-init.rs | 9 + .../feature-gate-lazy_normalization_consts.rs | 11 + .../lazy_normalization_consts/issue-47814.rs | 17 + .../lazy_normalization_consts/issue-57739.rs | 18 + .../lazy_normalization_consts/issue-73980.rs | 17 + .../trait-resolution-breakage.rs | 19 + .../unevaluated-consts.rs | 19 + .../rust/rustc/ui/leak-unique-as-tydesc.rs | 9 + .../rustc/ui/lex-bare-cr-nondoc-comment.rs | 10 + ...line-endings-string-literal-doc-comment.rs | 39 + gcc/testsuite/rust/rustc/ui/lexical-scopes.rs | 14 + .../rust/rustc/ui/lexical-scoping.rs | 20 + .../rustc/ui/lifetime-before-type-params.rs | 12 + .../rustc/ui/lifetime_starts_expressions.rs | 14 + .../lifetime_bound_will_change_warning_lib.rs | 12 + .../ui/lifetimes/borrowck-let-suggestion.rs | 13 + .../rust/rustc/ui/lifetimes/issue-34979.rs | 10 + .../issue-70917-lifetimes-in-fn-def.rs | 14 + .../lifetime-bound-will-change-warning.rs | 55 + .../lifetime-doesnt-live-long-enough.rs | 50 + ...-return-type-requires-explicit-lifetime.rs | 46 + .../lifetime-elision-return-type-trait.rs | 14 + .../42701_one_named_and_one_anonymous.rs | 15 + ...one-existing-name-early-bound-in-struct.rs | 21 + .../ex1-return-one-existing-name-if-else-2.rs | 6 + .../ex1-return-one-existing-name-if-else-3.rs | 6 + ...-one-existing-name-if-else-using-impl-2.rs | 9 + ...-one-existing-name-if-else-using-impl-3.rs | 15 + ...rn-one-existing-name-if-else-using-impl.rs | 18 + .../ex1-return-one-existing-name-if-else.rs | 6 + ...n-one-existing-name-return-type-is-anon.rs | 15 + ...1-return-one-existing-name-self-is-anon.rs | 14 + .../ex1b-return-no-names-if-else.rs | 6 + .../ex2a-push-one-existing-name-2.rs | 10 + ...ex2a-push-one-existing-name-early-bound.rs | 12 + .../ex2a-push-one-existing-name.rs | 10 + .../ex2b-push-no-existing-names.rs | 10 + .../ex2c-push-inference-variable.rs | 11 + .../ex2d-push-inference-variable-2.rs | 12 + .../ex2e-push-inference-variable-3.rs | 12 + .../ex3-both-anon-regions-2.rs | 6 + .../ex3-both-anon-regions-3.rs | 7 + ...x3-both-anon-regions-both-are-structs-2.rs | 11 + ...x3-both-anon-regions-both-are-structs-3.rs | 11 + ...ons-both-are-structs-earlybound-regions.rs | 13 + ...ions-both-are-structs-latebound-regions.rs | 10 + .../ex3-both-anon-regions-both-are-structs.rs | 10 + ...ex3-both-anon-regions-latebound-regions.rs | 6 + .../ex3-both-anon-regions-one-is-struct-2.rs | 8 + .../ex3-both-anon-regions-one-is-struct-3.rs | 8 + .../ex3-both-anon-regions-one-is-struct-4.rs | 8 + .../ex3-both-anon-regions-one-is-struct.rs | 11 + ...3-both-anon-regions-return-type-is-anon.rs | 12 + .../ex3-both-anon-regions-self-is-anon.rs | 12 + .../ex3-both-anon-regions-using-fn-items.rs | 6 + .../ex3-both-anon-regions-using-impl-items.rs | 10 + ...3-both-anon-regions-using-trait-objects.rs | 6 + .../lifetime-errors/ex3-both-anon-regions.rs | 6 + .../liveness-assign-imm-local-notes.rs | 38 + ...ifetime-mismatch-between-trait-and-impl.rs | 13 + .../rustc/ui/lifetimes/lifetime-no-keyword.rs | 8 + ...ure-doesnt-life-long-enough-issue-67634.rs | 4 + gcc/testsuite/rust/rustc/ui/link-cfg-works.rs | 14 + gcc/testsuite/rust/rustc/ui/link-section.rs | 38 + .../auxiliary/def_colliding_external.rs | 8 + .../auxiliary/def_illtyped_external.rs | 6 + ...-detect-extern-generated-name-collision.rs | 23 + ...e-detect-local-generated-name-collision.rs | 26 + .../linkage-attr/linkage-requires-raw-ptr.rs | 12 + .../rust/rustc/ui/linkage-attr/linkage2.rs | 18 + .../rust/rustc/ui/linkage-attr/linkage3.rs | 17 + .../rust/rustc/ui/linkage-attr/linkage4.rs | 6 + gcc/testsuite/rust/rustc/ui/linkage1.rs | 33 + gcc/testsuite/rust/rustc/ui/lint-cap.rs | 9 + .../lint-expr-stmt-attrs-for-early-lints.rs | 15 + .../ui/lint-unknown-lints-at-crate-level.rs | 8 + .../ui/lint/auxiliary/external_extern_fn.rs | 4 + .../ui/lint/auxiliary/inherited_stability.rs | 48 + .../ui/lint/auxiliary/lint_output_format.rs | 21 + .../rustc/ui/lint/auxiliary/lint_stability.rs | 189 + .../lint/auxiliary/lint_stability_fields.rs | 52 + .../auxiliary/lint_unused_extern_crate.rs | 2 + .../auxiliary/lint_unused_extern_crate2.rs | 2 + .../auxiliary/lint_unused_extern_crate3.rs | 2 + .../auxiliary/lint_unused_extern_crate4.rs | 2 + .../auxiliary/lint_unused_extern_crate5.rs | 2 + .../lint/auxiliary/lints-in-foreign-macros.rs | 15 + .../rustc/ui/lint/auxiliary/stability-cfg2.rs | 6 + .../rustc/ui/lint/auxiliary/stability_cfg1.rs | 4 + .../rustc/ui/lint/auxiliary/stability_cfg2.rs | 6 + .../ui/lint/clashing-extern-fn-recursion.rs | 120 + .../rust/rustc/ui/lint/clashing-extern-fn.rs | 386 + .../ui/lint/command-line-lint-group-allow.rs | 7 + .../ui/lint/command-line-lint-group-deny.rs | 6 + .../ui/lint/command-line-lint-group-forbid.rs | 6 + .../ui/lint/command-line-lint-group-warn.rs | 8 + .../rustc/ui/lint/crate_level_only_lint.rs | 23 + .../rustc/ui/lint/dead-code/alias-in-pat.rs | 11 + .../ui/lint/dead-code/associated-type.rs | 20 + .../rust/rustc/ui/lint/dead-code/basic.rs | 16 + .../rustc/ui/lint/dead-code/closure-bang.rs | 10 + .../rustc/ui/lint/dead-code/const-and-self.rs | 36 + .../ui/lint/dead-code/empty-unused-enum.rs | 6 + .../dead-code/empty-unused-public-enum.rs | 7 + .../rustc/ui/lint/dead-code/enum-variants.rs | 15 + .../rustc/ui/lint/dead-code/impl-trait.rs | 19 + .../ui/lint/dead-code/leading-underscore.rs | 32 + .../ui/lint/dead-code/lint-dead-code-1.rs | 111 + .../ui/lint/dead-code/lint-dead-code-2.rs | 42 + .../ui/lint/dead-code/lint-dead-code-3.rs | 80 + .../ui/lint/dead-code/lint-dead-code-4.rs | 84 + .../ui/lint/dead-code/lint-dead-code-5.rs | 51 + .../ui/lint/dead-code/lint-dead-code-6.rs | 21 + .../rustc/ui/lint/dead-code/newline-span.rs | 20 + .../rustc/ui/lint/dead-code/trait-impl.rs | 20 + .../ui/lint/dead-code/tuple-struct-field.rs | 13 + .../rustc/ui/lint/dead-code/type-alias.rs | 11 + .../rustc/ui/lint/dead-code/unused-enum.rs | 12 + .../lint/dead-code/unused-struct-variant.rs | 14 + .../ui/lint/dead-code/unused-variant-pub.rs | 15 + .../rustc/ui/lint/dead-code/unused-variant.rs | 13 + .../ui/lint/dead-code/with-core-crate.rs | 19 + .../rust/rustc/ui/lint/dead-code/with-impl.rs | 18 + .../ui/lint/deny-overflowing-literals.rs | 8 + .../rustc/ui/lint/empty-lint-attributes.rs | 18 + .../rustc/ui/lint/expansion-time-include.rs | 5 + .../rust/rustc/ui/lint/expansion-time.rs | 24 + .../rustc/ui/lint/function-item-references.rs | 170 + .../ui/lint/inclusive-range-pattern-syntax.rs | 20 + .../ui/lint/inline-trait-and-foreign-items.rs | 38 + ...47390-unused-variable-in-struct-pattern.rs | 89 + ...775-nested-macro-unnecessary-parens-arg.rs | 28 + ...issue-54099-camel-case-underscore-types.rs | 15 + .../ui/lint/issue-54180-unused-ref-field.rs | 35 + .../ui/lint/issue-54538-unused-parens-lint.rs | 108 + ...62-no-snake-case-warning-for-field-puns.rs | 30 + .../issue-67691-unused-field-in-or-pattern.rs | 87 + .../issue-69485-var-size-diffs-too-large.rs | 12 + .../ui/lint/issue-71290-unused-paren-binop.rs | 24 + .../issue-74883-unused-paren-baren-yield.rs | 27 + .../issue-78660-cap-lints-future-compat.rs | 11 + .../rustc/ui/lint/lint-attr-non-item-node.rs | 10 + .../rustc/ui/lint/lint-change-warnings.rs | 22 + .../rustc/ui/lint/lint-const-item-mutation.rs | 59 + .../rust/rustc/ui/lint/lint-ctypes-66202.rs | 18 + .../rust/rustc/ui/lint/lint-ctypes-73249-1.rs | 22 + .../rust/rustc/ui/lint/lint-ctypes-73249-2.rs | 30 + .../rust/rustc/ui/lint/lint-ctypes-73249-3.rs | 22 + .../rust/rustc/ui/lint/lint-ctypes-73249-4.rs | 25 + .../rust/rustc/ui/lint/lint-ctypes-73249-5.rs | 22 + .../rust/rustc/ui/lint/lint-ctypes-73249.rs | 22 + .../rust/rustc/ui/lint/lint-ctypes-73251-1.rs | 25 + .../rust/rustc/ui/lint/lint-ctypes-73251-2.rs | 33 + .../rust/rustc/ui/lint/lint-ctypes-73251.rs | 23 + .../rust/rustc/ui/lint/lint-ctypes-73747.rs | 15 + .../rust/rustc/ui/lint/lint-ctypes-enum.rs | 73 + .../rust/rustc/ui/lint/lint-ctypes-fn.rs | 182 + .../rust/rustc/ui/lint/lint-ctypes.rs | 111 + ...int-directives-on-use-items-issue-10534.rs | 25 + .../rustc/ui/lint/lint-exceeding-bitshifts.rs | 80 + .../rust/rustc/ui/lint/lint-forbid-attr.rs | 9 + .../rust/rustc/ui/lint/lint-forbid-cmdline.rs | 8 + .../ui/lint/lint-forbid-internal-unsafe.rs | 17 + .../ui/lint/lint-group-nonstandard-style.rs | 27 + .../rust/rustc/ui/lint/lint-impl-fn.rs | 34 + .../lint-incoherent-auto-trait-objects.rs | 20 + ...t-lowercase-static-const-pattern-rename.rs | 64 + .../lint-lowercase-static-const-pattern.rs | 52 + .../rust/rustc/ui/lint/lint-malformed.rs | 9 + .../rust/rustc/ui/lint/lint-match-arms.rs | 19 + .../rust/rustc/ui/lint/lint-misplaced-attr.rs | 13 + .../lint/lint-missing-copy-implementations.rs | 16 + .../rust/rustc/ui/lint/lint-missing-doc.rs | 204 + .../ui/lint/lint-non-camel-case-types.rs | 38 + .../ui/lint/lint-non-camel-case-variant.rs | 11 + ...on-camel-case-with-trailing-underscores.rs | 12 + .../ui/lint/lint-non-snake-case-crate-2.rs | 7 + .../ui/lint/lint-non-snake-case-crate.rs | 6 + .../ui/lint/lint-non-snake-case-functions.rs | 45 + .../ui/lint/lint-non-snake-case-lifetimes.rs | 9 + .../ui/lint/lint-non-snake-case-modules.rs | 11 + ...-non-snake-case-no-lowercase-equivalent.rs | 13 + .../lint-non-uppercase-associated-const.rs | 12 + .../ui/lint/lint-non-uppercase-statics.rs | 12 + .../lint/lint-nonstandard-style-unicode-1.rs | 51 + .../lint/lint-nonstandard-style-unicode-2.rs | 31 + .../lint/lint-nonstandard-style-unicode-3.rs | 26 + .../rustc/ui/lint/lint-output-format-2.rs | 16 + .../rust/rustc/ui/lint/lint-output-format.rs | 13 + .../rustc/ui/lint/lint-owned-heap-memory.rs | 13 + .../lint/lint-pre-expansion-extern-module.rs | 8 + .../rust/rustc/ui/lint/lint-qualification.rs | 21 + .../ui/lint/lint-range-endpoint-overflow.rs | 18 + .../rust/rustc/ui/lint/lint-removed-allow.rs | 9 + .../rustc/ui/lint/lint-removed-cmdline.rs | 13 + .../rust/rustc/ui/lint/lint-removed.rs | 9 + .../rust/rustc/ui/lint/lint-renamed-allow.rs | 9 + .../rustc/ui/lint/lint-renamed-cmdline.rs | 9 + .../rust/rustc/ui/lint/lint-renamed.rs | 5 + .../rustc/ui/lint/lint-shorthand-field.rs | 71 + .../rust/rustc/ui/lint/lint-stability-2.rs | 414 + .../ui/lint/lint-stability-deprecated.rs | 466 + .../lint/lint-stability-fields-deprecated.rs | 340 + .../rustc/ui/lint/lint-stability-fields.rs | 284 + .../rust/rustc/ui/lint/lint-stability.rs | 455 + .../rust/rustc/ui/lint/lint-stability2.rs | 14 + .../rust/rustc/ui/lint/lint-stability3.rs | 15 + .../lint/lint-temporary-cstring-as-param.rs | 12 + .../ui/lint/lint-temporary-cstring-as-ptr.rs | 10 + .../rust/rustc/ui/lint/lint-type-limits.rs | 28 + .../rust/rustc/ui/lint/lint-type-limits2.rs | 16 + .../rust/rustc/ui/lint/lint-type-limits3.rs | 14 + .../rust/rustc/ui/lint/lint-type-overflow.rs | 46 + .../rust/rustc/ui/lint/lint-type-overflow2.rs | 14 + .../ui/lint/lint-unconditional-recursion.rs | 153 + .../ui/lint/lint-unexported-no-mangle.rs | 30 + .../ui/lint/lint-unknown-feature-default.rs | 11 + .../rustc/ui/lint/lint-unknown-feature.rs | 11 + .../ui/lint/lint-unknown-lint-cmdline.rs | 10 + .../rust/rustc/ui/lint/lint-unknown-lint.rs | 10 + .../ui/lint/lint-unnecessary-import-braces.rs | 12 + .../rustc/ui/lint/lint-unnecessary-parens.rs | 82 + .../rust/rustc/ui/lint/lint-unsafe-code.rs | 90 + .../rustc/ui/lint/lint-unused-extern-crate.rs | 36 + .../rust/rustc/ui/lint/lint-unused-imports.rs | 91 + .../rustc/ui/lint/lint-unused-mut-self.rs | 15 + .../ui/lint/lint-unused-mut-variables.rs | 208 + .../rustc/ui/lint/lint-unused-variables.rs | 80 + .../rustc/ui/lint/lint-uppercase-variables.rs | 42 + .../lint_pre_expansion_extern_module_aux.rs | 4 + .../rustc/ui/lint/lints-in-foreign-macros.rs | 22 + .../rust/rustc/ui/lint/must-use-ops.rs | 42 + .../rust/rustc/ui/lint/must_use-array.rs | 48 + .../rust/rustc/ui/lint/must_use-trait.rs | 40 + .../rust/rustc/ui/lint/must_use-tuple.rs | 18 + .../rust/rustc/ui/lint/must_use-unit.rs | 17 + .../ui/lint/no-unused-parens-return-block.rs | 10 + gcc/testsuite/rust/rustc/ui/lint/not_found.rs | 22 + .../rustc/ui/lint/opaque-ty-ffi-unsafe.rs | 16 + .../rust/rustc/ui/lint/outer-forbid.rs | 25 + .../rust/rustc/ui/lint/reasons-erroneous.rs | 75 + .../rust/rustc/ui/lint/reasons-forbidden.rs | 42 + gcc/testsuite/rust/rustc/ui/lint/reasons.rs | 36 + .../redundant-semi-proc-macro-def.rs | 13 + .../redundant-semi-proc-macro.rs | 20 + .../lint-confusable-idents.rs | 18 + .../lint-mixed-script-confusables-2.rs | 21 + .../lint-mixed-script-confusables.rs | 16 + .../lint-non-ascii-idents.rs | 14 + .../lint-uncommon-codepoints.rs | 14 + .../rust/rustc/ui/lint/suggestions.rs | 68 + .../rust/rustc/ui/lint/test-inner-fn.rs | 20 + ...trivial-casts-featuring-type-ascription.rs | 11 + .../rust/rustc/ui/lint/trivial-casts.rs | 10 + .../rust/rustc/ui/lint/type-overflow.rs | 23 + .../rustc/ui/lint/unaligned_references.rs | 30 + .../rustc/ui/lint/uninitialized-zeroed.rs | 120 + .../rustc/ui/lint/unreachable-async-fn.rs | 10 + .../ui/lint/unreachable_pub-pub_crate.rs | 68 + .../rust/rustc/ui/lint/unreachable_pub.rs | 64 + ...sed-braces-while-let-with-mutable-value.rs | 13 + .../rust/rustc/ui/lint/unused_braces.rs | 54 + .../rustc/ui/lint/unused_braces_borrow.rs | 27 + .../lint/unused_import_warning_issue_45268.rs | 50 + .../rust/rustc/ui/lint/unused_labels.rs | 87 + .../ui/lint/unused_parens_json_suggestion.rs | 27 + .../unused_parens_remove_json_suggestion.rs | 62 + .../rust/rustc/ui/lint/use-redundant.rs | 28 + .../rust/rustc/ui/lint/use_suggestion_json.rs | 15 + .../warn-unused-inline-on-fn-prototypes.rs | 14 + gcc/testsuite/rust/rustc/ui/list.rs | 11 + .../ui/liveness-assign-imm-local-after-ret.rs | 17 + .../rust/rustc/ui/liveness/liveness-asm.rs | 45 + .../liveness-assign-imm-local-in-loop.rs | 13 + .../liveness-assign-imm-local-in-op-eq.rs | 13 + .../liveness-assign-imm-local-with-drop.rs | 13 + .../liveness-assign-imm-local-with-init.rs | 13 + .../liveness/liveness-closure-require-ret.rs | 3 + .../rust/rustc/ui/liveness/liveness-consts.rs | 64 + .../rust/rustc/ui/liveness/liveness-dead.rs | 40 + .../rust/rustc/ui/liveness/liveness-derive.rs | 39 + .../rustc/ui/liveness/liveness-forgot-ret.rs | 7 + .../rustc/ui/liveness/liveness-issue-2163.rs | 9 + .../ui/liveness/liveness-missing-ret2.rs | 8 + .../ui/liveness/liveness-move-call-arg.rs | 12 + .../ui/liveness/liveness-move-in-loop.rs | 18 + .../ui/liveness/liveness-move-in-while.rs | 14 + .../liveness-return-last-stmt-semi.rs | 20 + .../rust/rustc/ui/liveness/liveness-unused.rs | 142 + .../rust/rustc/ui/liveness/liveness-upvars.rs | 109 + .../ui/liveness/liveness-use-after-move.rs | 9 + .../ui/liveness/liveness-use-after-send.rs | 20 + .../rust/rustc/ui/llvm-asm/issue-51431.rs | 12 + .../rust/rustc/ui/llvm-asm/issue-54067.rs | 13 + .../rust/rustc/ui/llvm-asm/issue-62046.rs | 12 + .../rust/rustc/ui/llvm-asm/issue-69092.rs | 11 + .../rustc/ui/llvm-asm/llvm-asm-bad-clobber.rs | 27 + .../rustc/ui/llvm-asm/llvm-asm-concat-src.rs | 10 + .../ui/llvm-asm/llvm-asm-in-bad-modifier.rs | 36 + .../rustc/ui/llvm-asm/llvm-asm-in-moved.rs | 32 + .../ui/llvm-asm/llvm-asm-in-out-operand.rs | 57 + .../ui/llvm-asm/llvm-asm-indirect-memory.rs | 44 + .../ui/llvm-asm/llvm-asm-literal-escaping.rs | 13 + .../ui/llvm-asm/llvm-asm-misplaced-option.rs | 37 + .../ui/llvm-asm/llvm-asm-out-assign-imm.rs | 36 + .../rustc/ui/llvm-asm/llvm-asm-out-assign.rs | 26 + .../ui/llvm-asm/llvm-asm-out-no-modifier.rs | 33 + .../ui/llvm-asm/llvm-asm-out-read-uninit.rs | 34 + .../ui/llvm-asm/llvm-asm-parse-errors.rs | 16 + gcc/testsuite/rust/rustc/ui/llvm-pr32379.rs | 15 + gcc/testsuite/rust/rustc/ui/log-err-phi.rs | 8 + .../log-knows-the-names-of-variants-in-std.rs | 28 + .../ui/log-knows-the-names-of-variants.rs | 22 + gcc/testsuite/rust/rustc/ui/log-poly.rs | 14 + .../rust/rustc/ui/logging-only-prints-once.rs | 31 + gcc/testsuite/rust/rustc/ui/long-while.rs | 13 + .../rustc/ui/loops/for-each-loop-panic.rs | 10 + .../rust/rustc/ui/loops/loop-break-unsize.rs | 9 + .../ui/loops/loop-break-value-no-repeat.rs | 15 + .../rust/rustc/ui/loops/loop-break-value.rs | 94 + .../ui/loops/loop-labeled-break-value.rs | 12 + .../rustc/ui/loops/loop-proper-liveness.rs | 33 + .../ui/loops/loop-properly-diverging-2.rs | 7 + .../loops/loops-reject-duplicate-labels-2.rs | 36 + .../ui/loops/loops-reject-duplicate-labels.rs | 46 + ...loops-reject-labels-shadowing-lifetimes.rs | 110 + .../loops-reject-lifetime-shadowing-label.rs | 32 + gcc/testsuite/rust/rustc/ui/loud_ui.rs | 7 + .../rustc/ui/lto-and-no-bitcode-in-rlib.rs | 4 + .../rust/rustc/ui/lto-duplicate-symbols.rs | 12 + .../rust/rustc/ui/lto-many-codegen-units.rs | 7 + .../rust/rustc/ui/lto-opt-level-s.rs | 8 + .../rust/rustc/ui/lto-opt-level-z.rs | 8 + .../rustc/ui/lto-rustc-loads-linker-plugin.rs | 18 + .../rustc/ui/lto-still-runs-thread-dtors.rs | 33 + .../ui/lto-thin-rustc-loads-linker-plugin.rs | 14 + .../ui/lub-glb-with-unbound-infer-var.rs | 16 + .../rustc/ui/lub-glb/old-lub-glb-hr-eq.rs | 28 + .../rustc/ui/lub-glb/old-lub-glb-hr-noteq1.rs | 25 + .../rustc/ui/lub-glb/old-lub-glb-hr-noteq2.rs | 34 + .../rustc/ui/lub-glb/old-lub-glb-object.rs | 23 + gcc/testsuite/rust/rustc/ui/lub-if.rs | 43 + gcc/testsuite/rust/rustc/ui/lub-match.rs | 46 + .../rust/rustc/ui/macro-quote-cond.rs | 47 + .../rust/rustc/ui/macro-quote-test.rs | 11 + .../ui/macro_backtrace/auxiliary/ping.rs | 31 + .../rust/rustc/ui/macro_backtrace/main.rs | 24 + .../ui/macros/ambiguity-legacy-vs-modern.rs | 47 + .../rust/rustc/ui/macros/assert-as-macro.rs | 8 + .../rustc/ui/macros/assert-eq-macro-panic.rs | 10 + .../ui/macros/assert-eq-macro-success.rs | 14 + .../ui/macros/assert-eq-macro-unsized.rs | 5 + .../rustc/ui/macros/assert-macro-explicit.rs | 8 + .../rust/rustc/ui/macros/assert-macro-fmt.rs | 8 + .../rustc/ui/macros/assert-macro-owned.rs | 8 + .../rustc/ui/macros/assert-macro-static.rs | 8 + .../rustc/ui/macros/assert-ne-macro-panic.rs | 10 + .../ui/macros/assert-ne-macro-success.rs | 14 + .../ui/macros/assert-ne-macro-unsized.rs | 5 + .../rustc/ui/macros/assert-trailing-junk.rs | 25 + gcc/testsuite/rust/rustc/ui/macros/assert.rs | 7 + .../ui/macros/auxiliary/deprecated-macros.rs | 4 + .../auxiliary/dollar-crate-nested-encoding.rs | 11 + .../rustc/ui/macros/auxiliary/issue-75982.rs | 13 + .../macros/auxiliary/macro-comma-support.rs | 2 + .../macros/auxiliary/macro-in-other-crate.rs | 15 + .../auxiliary/macro-include-items-expr.rs | 4 + .../auxiliary/macro-include-items-item.rs | 4 + .../macros/auxiliary/macro_crate_def_only.rs | 5 + .../auxiliary/macro_crate_nonterminal.rs | 13 + .../auxiliary/macro_export_inner_module.rs | 7 + .../ui/macros/auxiliary/macro_with_super_1.rs | 17 + .../macros/auxiliary/proc_macro_sequence.rs | 47 + .../ui/macros/auxiliary/two_macros-rpass.rs | 6 + .../rustc/ui/macros/auxiliary/two_macros.rs | 6 + .../ui/macros/auxiliary/unstable-macros.rs | 17 + .../ui/macros/auxiliary/use-macro-self.rs | 7 + .../rust/rustc/ui/macros/bad-concat.rs | 9 + .../rust/rustc/ui/macros/bad_hello.rs | 7 + .../ui/macros/builtin-prelude-no-accidents.rs | 9 + .../rustc/ui/macros/builtin-std-paths-fail.rs | 26 + .../rust/rustc/ui/macros/builtin-std-paths.rs | 33 + gcc/testsuite/rust/rustc/ui/macros/cfg.rs | 6 + .../rustc/ui/macros/colorful-write-macros.rs | 35 + .../ui/macros/conditional-debug-macro-on.rs | 9 + .../macros/derive-in-eager-expansion-hang.rs | 15 + .../rust/rustc/ui/macros/die-macro-2.rs | 8 + .../rust/rustc/ui/macros/die-macro-expr.rs | 8 + .../rust/rustc/ui/macros/die-macro-pure.rs | 12 + .../rust/rustc/ui/macros/die-macro.rs | 17 + .../rust/rustc/ui/macros/doc-comment.rs | 26 + .../ui/macros/dollar-crate-nested-encoding.rs | 9 + .../rust/rustc/ui/macros/duplicate-builtin.rs | 18 + .../rustc/ui/macros/empty-trailing-stmt.rs | 11 + .../rust/rustc/ui/macros/format-foreign.rs | 18 + .../rustc/ui/macros/format-parse-errors.rs | 18 + .../rustc/ui/macros/format-unused-lables.rs | 19 + .../rust/rustc/ui/macros/global-asm.rs | 8 + .../rust/rustc/ui/macros/issue-25274.rs | 19 + .../rust/rustc/ui/macros/issue-30143.rs | 12 + ...e-34421-mac-expr-bad-stmt-good-add-semi.rs | 16 + .../rust/rustc/ui/macros/issue-39404.rs | 8 + .../rust/rustc/ui/macros/issue-54441.rs | 12 + .../rust/rustc/ui/macros/issue-58490.rs | 27 + .../rust/rustc/ui/macros/issue-61033-1.rs | 11 + .../rust/rustc/ui/macros/issue-61033-2.rs | 26 + .../ui/macros/issue-61053-different-kleene.rs | 31 + .../ui/macros/issue-61053-duplicate-binder.rs | 15 + .../macros/issue-61053-missing-repetition.rs | 29 + .../rustc/ui/macros/issue-61053-unbound.rs | 29 + .../rust/rustc/ui/macros/issue-63102.rs | 9 + .../rust/rustc/ui/macros/issue-68058.rs | 15 + .../rust/rustc/ui/macros/issue-68060.rs | 12 + .../rustc/ui/macros/issue-69838-dir/bar.rs | 4 + .../ui/macros/issue-69838-dir/included.rs | 4 + ...ue-69838-mods-relative-to-included-path.rs | 8 + .../rust/rustc/ui/macros/issue-70446.rs | 14 + .../issue-75982-foreign-macro-weird-mod.rs | 14 + .../rust/rustc/ui/macros/issue-77475.rs | 11 + .../issue-78325-inconsistent-resolution.rs | 13 + ...ue-78892-substitution-in-statement-attr.rs | 15 + ...ocal-ambiguity-multiple-parsing-options.rs | 9 + ...log_syntax-trace_macros-macro-locations.rs | 23 + gcc/testsuite/rust/rustc/ui/macros/macro-2.rs | 13 + .../rust/rustc/ui/macros/macro-as-fn-body.rs | 34 + .../macro-at-most-once-rep-2015-rpass.rs | 51 + .../ui/macros/macro-at-most-once-rep-2015.rs | 43 + .../macro-at-most-once-rep-2018-rpass.rs | 51 + .../ui/macros/macro-at-most-once-rep-2018.rs | 43 + .../ui/macros/macro-attribute-expansion.rs | 17 + .../rust/rustc/ui/macros/macro-attribute.rs | 3 + .../rust/rustc/ui/macros/macro-attributes.rs | 24 + .../macro-backtrace-invalid-internals.rs | 62 + .../rustc/ui/macros/macro-backtrace-nested.rs | 21 + .../ui/macros/macro-backtrace-println.rs | 20 + .../ui/macros/macro-block-nonterminal.rs | 12 + .../ui/macros/macro-comma-behavior-rpass.rs | 93 + .../rustc/ui/macros/macro-comma-behavior.rs | 96 + .../ui/macros/macro-comma-support-rpass.rs | 350 + .../rustc/ui/macros/macro-comma-support.rs | 11 + .../rust/rustc/ui/macros/macro-context.rs | 20 + .../rustc/ui/macros/macro-crate-def-only.rs | 11 + .../macro-crate-nonterminal-non-root.rs | 10 + .../macros/macro-crate-nonterminal-renamed.rs | 11 + .../ui/macros/macro-crate-nonterminal.rs | 11 + .../rust/rustc/ui/macros/macro-crate-use.rs | 18 + .../rustc/ui/macros/macro-deep_expansion.rs | 18 + .../ui/macros/macro-delimiter-significance.rs | 5 + .../rust/rustc/ui/macros/macro-deprecation.rs | 14 + .../rustc/ui/macros/macro-doc-comments.rs | 27 + .../rust/rustc/ui/macros/macro-doc-escapes.rs | 17 + .../ui/macros/macro-doc-raw-str-hashes.rs | 31 + .../rust/rustc/ui/macros/macro-error.rs | 10 + .../macros/macro-expanded-include/foo/mod.rs | 10 + .../ui/macros/macro-expanded-include/test.rs | 14 + .../rustc/ui/macros/macro-expansion-tests.rs | 41 + .../ui/macros/macro-export-inner-module.rs | 10 + .../rust/rustc/ui/macros/macro-first-set.rs | 272 + .../rustc/ui/macros/macro-follow-rpass.rs | 184 + .../rust/rustc/ui/macros/macro-follow.rs | 115 + .../ui/macros/macro-followed-by-seq-bad.rs | 12 + .../rustc/ui/macros/macro-followed-by-seq.rs | 15 + .../macros/macro-in-expression-context-2.rs | 9 + .../ui/macros/macro-in-expression-context.rs | 16 + .../rust/rustc/ui/macros/macro-in-fn.rs | 9 + .../rustc/ui/macros/macro-include-items.rs | 14 + .../rustc/ui/macros/macro-inner-attributes.rs | 21 + .../ui/macros/macro-input-future-proofing.rs | 24 + .../rustc/ui/macros/macro-interpolation.rs | 22 + .../ui/macros/macro-invalid-fragment-spec.rs | 9 + ...vocation-in-count-expr-fixed-array-type.rs | 11 + .../macros/macro-lifetime-used-with-bound.rs | 16 + .../macros/macro-lifetime-used-with-labels.rs | 37 + .../macros/macro-lifetime-used-with-static.rs | 15 + .../rust/rustc/ui/macros/macro-lifetime.rs | 15 + .../rust/rustc/ui/macros/macro-literal.rs | 134 + .../ui/macros/macro-local-data-key-priv.rs | 11 + .../ui/macros/macro-match-nonterminal.rs | 13 + .../ui/macros/macro-meta-items-modern.rs | 12 + .../rust/rustc/ui/macros/macro-meta-items.rs | 32 + .../ui/macros/macro-method-issue-4621.rs | 11 + .../ui/macros/macro-missing-delimiters.rs | 8 + .../rustc/ui/macros/macro-missing-fragment.rs | 8 + .../rustc/ui/macros/macro-multiple-items.rs | 17 + .../macros/macro-multiple-matcher-bindings.rs | 22 + .../rust/rustc/ui/macros/macro-name-typo.rs | 4 + .../rustc/ui/macros/macro-named-default.rs | 19 + .../macro-nested_definition_issue-31946.rs | 10 + .../rust/rustc/ui/macros/macro-nested_expr.rs | 23 + .../ui/macros/macro-nested_stmt_macros.rs | 24 + .../rustc/ui/macros/macro-non-lifetime.rs | 11 + .../rust/rustc/ui/macros/macro-nt-list.rs | 22 + .../rustc/ui/macros/macro-of-higher-order.rs | 23 + .../rustc/ui/macros/macro-outer-attributes.rs | 21 + .../rustc/ui/macros/macro-parameter-span.rs | 14 + .../rust/rustc/ui/macros/macro-pat-follow.rs | 32 + .../rust/rustc/ui/macros/macro-pat-neg-lit.rs | 26 + .../rust/rustc/ui/macros/macro-pat.rs | 66 + .../ui/macros/macro-path-prelude-fail-1.rs | 11 + .../ui/macros/macro-path-prelude-fail-2.rs | 8 + .../ui/macros/macro-path-prelude-fail-3.rs | 4 + .../ui/macros/macro-path-prelude-fail-4.rs | 5 + .../ui/macros/macro-path-prelude-pass.rs | 10 + .../ui/macros/macro-path-prelude-shadowing.rs | 34 + .../rust/rustc/ui/macros/macro-path.rs | 19 + .../rust/rustc/ui/macros/macro-pub-matcher.rs | 119 + .../rustc/ui/macros/macro-reexport-removed.rs | 9 + .../ui/macros/macro-seq-followed-by-seq.rs | 18 + .../ui/macros/macro-shadowing-relaxed.rs | 26 + .../rust/rustc/ui/macros/macro-shadowing.rs | 27 + .../rustc/ui/macros/macro-stability-rpass.rs | 15 + .../rust/rustc/ui/macros/macro-stability.rs | 29 + .../rustc/ui/macros/macro-stmt-matchers.rs | 8 + .../rust/rustc/ui/macros/macro-stmt.rs | 32 + .../macros/macro-stmt_macro_in_expr_macro.rs | 22 + .../ui/macros/macro-tt-followed-by-seq.rs | 28 + .../rust/rustc/ui/macros/macro-tt-matchers.rs | 12 + .../rustc/ui/macros/macro-use-all-and-none.rs | 14 + .../rust/rustc/ui/macros/macro-use-all.rs | 11 + .../rustc/ui/macros/macro-use-bad-args-1.rs | 7 + .../rustc/ui/macros/macro-use-bad-args-2.rs | 7 + .../rust/rustc/ui/macros/macro-use-both.rs | 11 + .../rust/rustc/ui/macros/macro-use-one.rs | 10 + .../rust/rustc/ui/macros/macro-use-scope.rs | 23 + .../rust/rustc/ui/macros/macro-use-undef.rs | 9 + .../rustc/ui/macros/macro-use-wrong-name.rs | 10 + .../rust/rustc/ui/macros/macro-with-attrs1.rs | 14 + .../rust/rustc/ui/macros/macro-with-attrs2.rs | 12 + .../macro-with-braces-in-expr-position.rs | 23 + .../ui/macros/macro_path_as_generic_bound.rs | 10 + .../rust/rustc/ui/macros/macro_undefined.rs | 14 + .../rustc/ui/macros/macro_with_super_2.rs | 14 + .../rust/rustc/ui/macros/macros-in-extern.rs | 46 + .../rustc/ui/macros/macros-nonfatal-errors.rs | 34 + .../ui/macros/meta-item-absolute-path.rs | 6 + .../rustc/ui/macros/meta-variable-misuse.rs | 35 + .../rust/rustc/ui/macros/missing-comma.rs | 35 + .../ui/macros/must-use-in-macro-55516.rs | 11 + .../rustc/ui/macros/nonterminal-matching.rs | 27 + .../ui/macros/parse-complex-macro-invoc-op.rs | 43 + .../ui/macros/paths-in-macro-invocations.rs | 37 + .../rustc/ui/macros/pub-item-inside-macro.rs | 19 + .../ui/macros/pub-method-inside-macro.rs | 23 + .../ui/macros/restricted-shadowing-legacy.rs | 290 + .../ui/macros/restricted-shadowing-modern.rs | 242 + .../rustc/ui/macros/same-sequence-span.rs | 23 + .../rustc/ui/macros/semi-after-macro-ty.rs | 9 + .../ui/macros/span-covering-argument-1.rs | 14 + .../ui/macros/stmt_expr_attr_macro_parse.rs | 24 + .../rustc/ui/macros/syntax-extension-cfg.rs | 25 + .../macros/syntax-extension-source-utils.rs | 38 + .../rust/rustc/ui/macros/trace-macro.rs | 7 + .../rustc/ui/macros/trace_faulty_macros.rs | 44 + .../rust/rustc/ui/macros/try-macro.rs | 50 + .../rust/rustc/ui/macros/two-macro-use.rs | 12 + .../rust/rustc/ui/macros/type-macros-hlist.rs | 79 + .../rustc/ui/macros/type-macros-simple.rs | 31 + .../typeck-macro-interaction-issue-8852.rs | 31 + .../ui/macros/unimplemented-macro-panic.rs | 8 + .../rust/rustc/ui/macros/unknown-builtin.rs | 15 + .../rustc/ui/macros/unreachable-fmt-msg.rs | 8 + .../ui/macros/unreachable-macro-panic.rs | 8 + .../rustc/ui/macros/unreachable-static-msg.rs | 8 + .../rust/rustc/ui/macros/unreachable.rs | 8 + .../rust/rustc/ui/macros/use-macro-self.rs | 13 + .../rust/rustc/ui/main-wrong-location.rs | 7 + .../rust/rustc/ui/main-wrong-type.rs | 9 + .../issue-69341-malformed-derive-inert.rs | 11 + .../ui/malformed/malformed-derive-entry.rs | 15 + .../ui/malformed/malformed-interpolated.rs | 18 + .../ui/malformed/malformed-meta-delim.rs | 12 + .../rustc/ui/malformed/malformed-plugin-1.rs | 6 + .../rustc/ui/malformed/malformed-plugin-2.rs | 6 + .../rustc/ui/malformed/malformed-plugin-3.rs | 6 + .../ui/malformed/malformed-regressions.rs | 13 + .../ui/malformed/malformed-special-attrs.rs | 14 + .../rustc/ui/malformed/malformed-unwind-1.rs | 10 + .../rustc/ui/malformed/malformed-unwind-2.rs | 12 + .../rust/rustc/ui/malformed_macro_lhs.rs | 8 + .../rustc/ui/manual/manual-link-bad-form.rs | 6 + .../rustc/ui/manual/manual-link-bad-kind.rs | 6 + .../ui/manual/manual-link-bad-search-path.rs | 6 + .../rustc/ui/manual/manual-link-framework.rs | 8 + gcc/testsuite/rust/rustc/ui/map-types.rs | 20 + .../issue-61651-type-mismatch.rs | 18 + .../marker-attribute-on-non-trait.rs | 24 + .../marker-attribute-with-values.rs | 13 + .../marker-trait-with-associated-items.rs | 41 + .../marker_trait_attr/overlap-marker-trait.rs | 29 + .../override-item-on-marker-trait.rs | 24 + .../ui/match-on-negative-integer-ranges.rs | 8 + .../match/const_non_normal_zst_ref_pattern.rs | 10 + .../rustc/ui/match/expr-match-panic-fn.rs | 20 + .../rust/rustc/ui/match/expr-match-panic.rs | 11 + .../rust/rustc/ui/match/issue-50900.rs | 20 + .../rustc/ui/match/issue-70972-dyn-trait.rs | 11 + .../rust/rustc/ui/match/issue-72896.rs | 24 + .../rustc/ui/match/issue-74050-end-span.rs | 14 + .../ui/match/match-arm-resolving-to-never.rs | 20 + .../rust/rustc/ui/match/match-bot-panic.rs | 17 + .../rust/rustc/ui/match/match-disc-bot.rs | 17 + .../rust/rustc/ui/match/match-fn-call.rs | 13 + .../rust/rustc/ui/match/match-ill-type2.rs | 8 + .../ui/match/match-incompat-type-semi.rs | 53 + .../rust/rustc/ui/match/match-join.rs | 12 + .../match/match-no-arms-unreachable-after.rs | 13 + .../match/match-pattern-field-mismatch-2.rs | 17 + .../ui/match/match-pattern-field-mismatch.rs | 17 + .../rust/rustc/ui/match/match-range-fail-2.rs | 25 + .../rust/rustc/ui/match/match-range-fail.rs | 23 + .../ui/match/match-ref-mut-invariance.rs | 15 + .../ui/match/match-ref-mut-let-invariance.rs | 16 + .../rustc/ui/match/match-ref-mut-stability.rs | 38 + .../rust/rustc/ui/match/match-struct.rs | 12 + .../rust/rustc/ui/match/match-tag-nullary.rs | 5 + .../rust/rustc/ui/match/match-tag-unary.rs | 5 + .../ui/match/match-type-err-first-arm.rs | 51 + .../ui/match/match-unresolved-one-arm.rs | 8 + .../rustc/ui/match/match-vec-mismatch-2.rs | 7 + .../rust/rustc/ui/match/match-wildcards.rs | 22 + .../ui/match/pattern-deref-miscompile.rs | 47 + .../type_polymorphic_byte_str_literals.rs | 37 + .../rust/rustc/ui/max-min-classes.rs | 33 + .../rust/rustc/ui/maybe-bounds-where-cpass.rs | 10 + .../rust/rustc/ui/maybe-bounds-where.rs | 28 + gcc/testsuite/rust/rustc/ui/maybe-bounds.rs | 10 + .../rust/rustc/ui/meta/auxiliary/env.rs | 10 + .../ui/meta/expected-error-correct-rev.rs | 11 + .../rust/rustc/ui/meta/revision-bad.rs | 22 + .../rust/rustc/ui/meta/revision-ok.rs | 22 + gcc/testsuite/rust/rustc/ui/meta/rustc-env.rs | 19 + .../rust/rustc/ui/methods/assign-to-method.rs | 25 + .../ui/methods/auxiliary/ambig_impl_2_lib.rs | 5 + .../methods/auxiliary/macro-in-other-crate.rs | 10 + .../ui/methods/auxiliary/method_self_arg1.rs | 38 + .../ui/methods/auxiliary/method_self_arg2.rs | 55 + ...method-ambig-one-trait-unknown-int-type.rs | 37 + .../method-ambig-two-traits-cross-crate.rs | 12 + .../method-ambig-two-traits-from-bounds.rs | 9 + .../method-ambig-two-traits-from-impls.rs | 17 + .../method-ambig-two-traits-from-impls2.rs | 17 + ...od-ambig-two-traits-with-default-method.rs | 14 + ...thod-argument-inference-associated-type.rs | 29 + .../rustc/ui/methods/method-call-err-msg.rs | 23 + .../methods/method-call-lifetime-args-fail.rs | 73 + .../method-call-lifetime-args-lint-fail.rs | 88 + .../methods/method-call-lifetime-args-lint.rs | 22 + .../method-call-lifetime-args-subst-index.rs | 16 + .../method-call-lifetime-args-unresolved.rs | 4 + .../ui/methods/method-call-lifetime-args.rs | 16 + .../ui/methods/method-call-type-binding.rs | 4 + ...-same-trait-object-with-separate-params.rs | 180 + .../method-early-bound-lifetimes-on-self.rs | 32 + .../ui/methods/method-macro-backtrace.rs | 26 + .../rustc/ui/methods/method-missing-call.rs | 31 + ...thod-mut-self-modifies-mut-slice-lvalue.rs | 45 + .../method-normalize-bounds-issue-20604.rs | 62 + .../method-on-ambiguous-numeric-type.rs | 33 + .../ui/methods/method-path-in-pattern.rs | 33 + .../method-probe-no-guessing-dyn-trait.rs | 61 + .../rustc/ui/methods/method-projection.rs | 62 + .../methods/method-recursive-blanket-impl.rs | 42 + .../method-resolvable-path-in-pattern.rs | 15 + .../rustc/ui/methods/method-self-arg-1.rs | 18 + .../rustc/ui/methods/method-self-arg-2.rs | 26 + .../rustc/ui/methods/method-self-arg-aux1.rs | 21 + .../rustc/ui/methods/method-self-arg-aux2.rs | 25 + .../rustc/ui/methods/method-self-arg-trait.rs | 70 + .../rust/rustc/ui/methods/method-self-arg.rs | 49 + .../methods/method-trait-object-with-hrtb.rs | 42 + .../method-two-trait-defer-resolution-1.rs | 38 + .../method-two-trait-defer-resolution-2.rs | 49 + ...o-traits-distinguished-via-where-clause.rs | 28 + .../rustc/ui/methods/method-where-clause.rs | 35 + .../rust/rustc/ui/mid-path-type-params.rs | 38 + .../rustc/ui/minmax-stability-issue-23687.rs | 65 + gcc/testsuite/rust/rustc/ui/minus-string.rs | 4 + .../rust/rustc/ui/mir-dataflow/def-inits-1.rs | 52 + .../mir-dataflow/indirect-mutation-offset.rs | 49 + .../rust/rustc/ui/mir-dataflow/inits-1.rs | 54 + .../ui/mir-dataflow/liveness-projection.rs | 33 + .../rustc/ui/mir-dataflow/liveness-ptr.rs | 29 + .../rust/rustc/ui/mir-dataflow/uninits-1.rs | 52 + .../rust/rustc/ui/mir-dataflow/uninits-2.rs | 25 + gcc/testsuite/rust/rustc/ui/mir-unpretty.rs | 6 + .../rustc/ui/mir/auxiliary/issue_76375_aux.rs | 15 + .../ui/mir/auxiliary/mir_external_refs.rs | 18 + .../rust/rustc/ui/mir/issue-60390.rs | 9 + .../rust/rustc/ui/mir/issue-66930.rs | 12 + .../ui/mir/issue-67639-normalization-ice.rs | 35 + .../ui/mir/issue-67710-inline-projection.rs | 18 + .../rust/rustc/ui/mir/issue-67947.rs | 8 + .../rust/rustc/ui/mir/issue-68841.rs | 16 + .../ui/mir/issue-71793-inline-args-storage.rs | 17 + .../rust/rustc/ui/mir/issue-75053.rs | 49 + .../mir/issue-75419-validation-impl-trait.rs | 14 + .../rust/rustc/ui/mir/issue-76248.rs | 30 + .../rust/rustc/ui/mir/issue-76375.rs | 16 + .../ui/mir/issue-76740-copy-propagation.rs | 31 + .../ui/mir/issue-76803-branches-not-same.rs | 20 + .../mir/issue-77359-simplify-arm-identity.rs | 36 + .../rust/rustc/ui/mir/issue-77911.rs | 17 + gcc/testsuite/rust/rustc/ui/mir/issue66339.rs | 14 + .../ui/mir/mir-inlining/ice-issue-45493.rs | 18 + .../ui/mir/mir-inlining/ice-issue-45885.rs | 30 + .../ui/mir/mir-inlining/ice-issue-68347.rs | 29 + .../ui/mir/mir-inlining/ice-issue-77306-1.rs | 18 + .../ui/mir/mir-inlining/ice-issue-77306-2.rs | 33 + .../ui/mir/mir-inlining/ice-issue-77564.rs | 39 + .../no-trait-method-issue-40473.rs | 17 + .../mir-inlining/var-debuginfo-issue-67586.rs | 12 + .../ui/mir/mir-typeck-normalize-fn-sig.rs | 31 + .../rust/rustc/ui/mir/mir_adt_construction.rs | 93 + .../rustc/ui/mir/mir_ascription_coercion.rs | 11 + .../rustc/ui/mir/mir_assign_eval_order.rs | 68 + .../rustc/ui/mir/mir_augmented_assignments.rs | 161 + .../rust/rustc/ui/mir/mir_autoderef.rs | 29 + gcc/testsuite/rust/rustc/ui/mir/mir_boxing.rs | 11 + .../ui/mir/mir_build_match_comparisons.rs | 60 + .../ui/mir/mir_call_with_associated_type.rs | 17 + .../rust/rustc/ui/mir/mir_calls_to_shims.rs | 50 + .../rust/rustc/ui/mir/mir_cast_fn_ret.rs | 24 + .../rust/rustc/ui/mir/mir_codegen_array.rs | 12 + .../rust/rustc/ui/mir/mir_codegen_array_2.rs | 10 + .../ui/mir/mir_codegen_call_converging.rs | 18 + .../rust/rustc/ui/mir/mir_codegen_calls.rs | 193 + .../mir/mir_codegen_calls_converging_drops.rs | 27 + .../mir_codegen_calls_converging_drops_2.rs | 31 + .../ui/mir/mir_codegen_calls_diverging.rs | 16 + .../mir/mir_codegen_calls_diverging_drops.rs | 25 + .../rustc/ui/mir/mir_codegen_critical_edge.rs | 45 + .../rust/rustc/ui/mir/mir_codegen_spike1.rs | 13 + .../rust/rustc/ui/mir/mir_codegen_switch.rs | 36 + .../rustc/ui/mir/mir_codegen_switchint.rs | 13 + .../rust/rustc/ui/mir/mir_coercion_casts.rs | 11 + .../rust/rustc/ui/mir/mir_coercions.rs | 72 + .../mir/mir_const_prop_tuple_field_reorder.rs | 28 + .../rust/rustc/ui/mir/mir_constval_adts.rs | 35 + .../rustc/ui/mir/mir_detects_invalid_ops.rs | 25 + .../rust/rustc/ui/mir/mir_drop_order.rs | 49 + .../rust/rustc/ui/mir/mir_drop_panics.rs | 25 + .../rust/rustc/ui/mir/mir_dynamic_drops_1.rs | 33 + .../rust/rustc/ui/mir/mir_dynamic_drops_2.rs | 31 + .../rust/rustc/ui/mir/mir_dynamic_drops_3.rs | 36 + .../rustc/ui/mir/mir_early_return_scope.rs | 30 + .../rust/rustc/ui/mir/mir_fat_ptr.rs | 53 + .../rust/rustc/ui/mir/mir_fat_ptr_drop.rs | 33 + .../rust/rustc/ui/mir/mir_heavy_promoted.rs | 12 + .../rust/rustc/ui/mir/mir_indexing_oob_1.rs | 15 + .../rust/rustc/ui/mir/mir_indexing_oob_2.rs | 15 + .../rust/rustc/ui/mir/mir_indexing_oob_3.rs | 15 + .../rust/rustc/ui/mir/mir_match_arm_guard.rs | 17 + .../rust/rustc/ui/mir/mir_match_test.rs | 84 + .../rust/rustc/ui/mir/mir_misc_casts.rs | 321 + .../rust/rustc/ui/mir/mir_overflow_off.rs | 18 + .../rust/rustc/ui/mir/mir_raw_fat_ptr.rs | 216 + .../rust/rustc/ui/mir/mir_refs_correct.rs | 210 + .../rust/rustc/ui/mir/mir_small_agg_arg.rs | 9 + .../rust/rustc/ui/mir/mir_static_subtype.rs | 10 + .../rustc/ui/mir/mir_struct_with_assoc_ty.rs | 30 + .../rust/rustc/ui/mir/mir_temp_promotions.rs | 11 + .../rust/rustc/ui/mir/mir_void_return.rs | 13 + .../rust/rustc/ui/mir/mir_void_return_2.rs | 11 + .../rust/rustc/ui/mir/simplify-branch-same.rs | 22 + .../rust/rustc/ui/mir_check_nonconst.rs | 12 + .../rust/rustc/ui/mismatched_types/E0053.rs | 17 + .../rust/rustc/ui/mismatched_types/E0409.rs | 10 + .../rust/rustc/ui/mismatched_types/E0631.rs | 12 + .../rustc/ui/mismatched_types/abridged.rs | 63 + .../rust/rustc/ui/mismatched_types/binops.rs | 9 + .../rustc/ui/mismatched_types/cast-rfc0401.rs | 73 + ...ure-arg-count-expected-type-issue-47244.rs | 21 + .../ui/mismatched_types/closure-arg-count.rs | 44 + .../closure-arg-type-mismatch.rs | 16 + .../ui/mismatched_types/closure-mismatch.rs | 10 + .../ui/mismatched_types/const-fn-in-trait.rs | 14 + .../ui/mismatched_types/fn-variance-1.rs | 18 + .../for-loop-has-unit-body.rs | 6 + .../rustc/ui/mismatched_types/issue-19109.rs | 9 + .../rustc/ui/mismatched_types/issue-26480.rs | 30 + .../rustc/ui/mismatched_types/issue-35030.rs | 16 + .../ui/mismatched_types/issue-36053-2.rs | 11 + .../rustc/ui/mismatched_types/issue-38371.rs | 28 + .../issue-74918-missing-lifetime.rs | 29 + .../issue-75361-mismatched-impl.rs | 25 + .../rust/rustc/ui/mismatched_types/main.rs | 5 + .../method-help-unsatisfied-bound.rs | 8 + .../mismatched_types/numeric-literal-cast.rs | 13 + .../mismatched_types/overloaded-calls-bad.rs | 34 + .../ui/mismatched_types/recovered-block.rs | 24 + .../trait-bounds-cant-coerce.rs | 17 + .../trait-impl-fn-incompatibility.rs | 15 + .../unboxed-closures-vtable-mismatch.rs | 20 + .../rustc/ui/missing/auxiliary/two_macros.rs | 6 + .../ui/missing/missing-alloc_error_handler.rs | 24 + .../rustc/ui/missing/missing-allocator.rs | 19 + .../rustc/ui/missing/missing-block-hint.rs | 10 + .../ui/missing/missing-comma-in-match.rs | 12 + .../ui/missing/missing-derivable-attr.rs | 17 + .../missing-fields-in-struct-pattern.rs | 9 + .../ui/missing/missing-items/auxiliary/m1.rs | 10 + .../ui/missing/missing-items/issue-40221.rs | 17 + .../rust/rustc/ui/missing/missing-items/m2.rs | 13 + .../missing-items/missing-type-parameter.rs | 6 + .../rustc/ui/missing/missing-macro-use.rs | 9 + .../rust/rustc/ui/missing/missing-main.rs | 3 + .../rust/rustc/ui/missing/missing-return.rs | 6 + .../rustc/ui/missing/missing-stability.rs | 25 + .../rust/rustc/ui/missing_debug_impls.rs | 39 + .../rustc/ui/missing_non_modrs_mod/foo.rs | 5 + .../ui/missing_non_modrs_mod/foo_inline.rs | 6 + .../missing_non_modrs_mod.rs | 3 + .../missing_non_modrs_mod_inline.rs | 3 + .../rustc/ui/mod-subitem-as-enum-variant.rs | 10 + .../rustc/ui/module-macro_use-arguments.rs | 7 + .../ui/modules/auxiliary/two_macros_2.rs | 4 + .../rust/rustc/ui/modules/mod-inside-fn.rs | 14 + .../rust/rustc/ui/modules/mod-view-items.rs | 15 + .../rust/rustc/ui/modules/mod_dir_implicit.rs | 9 + .../ui/modules/mod_dir_implicit_aux/mod.rs | 3 + .../rust/rustc/ui/modules/mod_dir_path.rs | 24 + .../rust/rustc/ui/modules/mod_dir_path2.rs | 13 + .../rust/rustc/ui/modules/mod_dir_path3.rs | 12 + .../rustc/ui/modules/mod_dir_path_multi.rs | 18 + .../rustc/ui/modules/mod_dir_recursive.rs | 15 + .../rust/rustc/ui/modules/mod_dir_simple.rs | 11 + .../mod_dir_simple/load_another_mod.rs | 4 + .../rustc/ui/modules/mod_dir_simple/test.rs | 3 + .../rust/rustc/ui/modules/mod_file.rs | 11 + .../rust/rustc/ui/modules/mod_file_aux.rs | 5 + .../ui/modules/mod_file_with_path_attr.rs | 12 + .../float-template/inst_f32.rs | 4 + .../float-template/inst_f64.rs | 4 + .../float-template/inst_float.rs | 4 + .../mod_file_aux.rs | 4 + .../mod_file_correct_spans.rs | 9 + .../mod_file_disambig.rs | 7 + .../mod_file_disambig_aux.rs | 2 + .../mod_file_disambig_aux/mod.rs | 2 + gcc/testsuite/rust/rustc/ui/monad.rs | 49 + .../rustc/ui/monomorphize-abi-alignment.rs | 35 + ...nomorphized-callees-with-ty-params-3314.rs | 33 + .../ui/moves/issue-46099-move-in-macro.rs | 16 + .../ui/moves/issue-75904-move-closure-loop.rs | 16 + .../rust/rustc/ui/moves/move-1-unique.rs | 26 + .../rust/rustc/ui/moves/move-2-unique.rs | 12 + gcc/testsuite/rust/rustc/ui/moves/move-2.rs | 8 + .../rust/rustc/ui/moves/move-3-unique.rs | 26 + .../rust/rustc/ui/moves/move-4-unique.rs | 20 + gcc/testsuite/rust/rustc/ui/moves/move-4.rs | 20 + .../rust/rustc/ui/moves/move-arg-2-unique.rs | 14 + .../rust/rustc/ui/moves/move-arg-2.rs | 14 + gcc/testsuite/rust/rustc/ui/moves/move-arg.rs | 6 + .../rustc/ui/moves/move-deref-coercion.rs | 34 + .../rustc/ui/moves/move-fn-self-receiver.rs | 75 + .../rustc/ui/moves/move-guard-same-consts.rs | 26 + .../rust/rustc/ui/moves/move-in-guard-1.rs | 16 + .../rust/rustc/ui/moves/move-in-guard-2.rs | 16 + .../rustc/ui/moves/move-into-dead-array-1.rs | 16 + .../rustc/ui/moves/move-into-dead-array-2.rs | 16 + .../rust/rustc/ui/moves/move-nullary-fn.rs | 14 + .../rustc/ui/moves/move-out-of-array-1.rs | 19 + .../rustc/ui/moves/move-out-of-array-ref.rs | 35 + .../rust/rustc/ui/moves/move-out-of-field.rs | 28 + .../rustc/ui/moves/move-out-of-slice-1.rs | 12 + .../rustc/ui/moves/move-out-of-slice-2.rs | 36 + .../rustc/ui/moves/move-out-of-tuple-field.rs | 14 + .../rust/rustc/ui/moves/move-scalar.rs | 11 + .../moves-based-on-type-access-to-field.rs | 15 + .../ui/moves/moves-based-on-type-block-bad.rs | 30 + .../moves-based-on-type-capture-clause-bad.rs | 10 + .../moves-based-on-type-capture-clause.rs | 13 + ...s-based-on-type-cyclic-types-issue-4821.rs | 21 + ...ased-on-type-distribute-copy-over-paren.rs | 50 + .../ui/moves/moves-based-on-type-exprs.rs | 94 + .../moves-based-on-type-match-bindings.rs | 22 + ...type-move-out-of-closure-env-issue-1965.rs | 13 + ...ased-on-type-no-recursive-stack-closure.rs | 36 + .../ui/moves/moves-based-on-type-tuple.rs | 11 + .../rustc/ui/moves/moves-sru-moved-field.rs | 24 + gcc/testsuite/rust/rustc/ui/mpsc_stress.rs | 166 + gcc/testsuite/rust/rustc/ui/msvc-data-only.rs | 9 + gcc/testsuite/rust/rustc/ui/multi-panic.rs | 39 + gcc/testsuite/rust/rustc/ui/multibyte.rs | 8 + ...ispatch-conditional-impl-not-considered.rs | 25 + gcc/testsuite/rust/rustc/ui/multidispatch1.rs | 34 + gcc/testsuite/rust/rustc/ui/multidispatch2.rs | 40 + .../rust/rustc/ui/multiline-comment.rs | 8 + .../rust/rustc/ui/multiple-main-2.rs | 10 + .../rust/rustc/ui/multiple-main-3.rs | 12 + .../rustc/ui/multiple-plugin-registrars.rs | 13 + gcc/testsuite/rust/rustc/ui/multiple-reprs.rs | 83 + .../rust/rustc/ui/mut-function-arguments.rs | 22 + .../rust/rustc/ui/mut-vstore-expr.rs | 7 + .../rust/rustc/ui/mut/mut-cant-alias.rs | 15 + .../rust/rustc/ui/mut/mut-cross-borrowing.rs | 9 + .../ui/mut/mut-pattern-internal-mutability.rs | 16 + .../rustc/ui/mut/mut-pattern-mismatched.rs | 21 + gcc/testsuite/rust/rustc/ui/mut/mut-ref.rs | 5 + .../rust/rustc/ui/mut/mut-suggestion.rs | 23 + .../rustc/ui/mut/mutable-class-fields-2.rs | 25 + .../rust/rustc/ui/mut/mutable-class-fields.rs | 17 + .../rustc/ui/mut/mutable-enum-indirect.rs | 20 + .../ui/mut/no-mut-lint-for-desugared-mut.rs | 9 + .../rust/rustc/ui/mutexguard-sync.rs | 14 + .../rust/rustc/ui/mutual-recursion-group.rs | 17 + .../ui/namespace/auxiliary/namespace-mix.rs | 67 + .../namespace/auxiliary/namespaced_enums.rs | 11 + .../rust/rustc/ui/namespace/namespace-mix.rs | 156 + ...spaced-enum-glob-import-no-impls-xcrate.rs | 16 + .../namespaced-enum-glob-import-no-impls.rs | 26 + .../rust/rustc/ui/native-print-no-runtime.rs | 10 + gcc/testsuite/rust/rustc/ui/negative.rs | 9 + .../rust/rustc/ui/nested-block-comment.rs | 13 + .../rust/rustc/ui/nested-cfg-attrs.rs | 5 + gcc/testsuite/rust/rustc/ui/nested-class.rs | 26 + .../ui/nested-function-names-issue-8587.rs | 43 + .../rust/rustc/ui/nested-ty-params.rs | 9 + .../rust/rustc/ui/nested_impl_trait.rs | 31 + .../rust/rustc/ui/nested_item_main.rs | 11 + .../rust/rustc/ui/never_type/adjust_never.rs | 11 + .../rust/rustc/ui/never_type/auto-traits.rs | 19 + .../call-fn-never-arg-wrong-type.rs | 12 + .../rustc/ui/never_type/call-fn-never-arg.rs | 15 + .../rust/rustc/ui/never_type/cast-never.rs | 11 + .../ui/never_type/defaulted-never-note.rs | 35 + .../ui/never_type/dispatch_from_dyn_zst.rs | 52 + .../diverging-fallback-control-flow.rs | 103 + .../feature-gate-never_type_fallback.rs | 13 + .../rustc/ui/never_type/impl-for-never.rs | 28 + .../rust/rustc/ui/never_type/issue-13352.rs | 12 + .../rust/rustc/ui/never_type/issue-2149.rs | 16 + .../rust/rustc/ui/never_type/issue-44402.rs | 34 + .../rust/rustc/ui/never_type/issue-51506.rs | 42 + .../ui/never_type/never-assign-dead-code.rs | 13 + .../ui/never_type/never-assign-wrong-type.rs | 9 + .../ui/never_type/never-associated-type.rs | 24 + .../never_type/never-from-impl-is-reserved.rs | 13 + .../rust/rustc/ui/never_type/never-result.rs | 22 + .../rustc/ui/never_type/never-type-arg.rs | 18 + .../rustc/ui/never_type/never-type-rvalues.rs | 39 + .../never-value-fallback-issue-66757.rs | 30 + .../rustc/ui/never_type/never_coercions.rs | 13 + .../ui/never_type/never_transmute_never.rs | 24 + .../ui/never_type/return-never-coerce.rs | 19 + .../rust/rustc/ui/never_type/try_from.rs | 38 + gcc/testsuite/rust/rustc/ui/new-box-syntax.rs | 29 + gcc/testsuite/rust/rustc/ui/new-box.rs | 33 + .../rust/rustc/ui/new-impl-syntax.rs | 30 + .../rust/rustc/ui/new-import-syntax.rs | 6 + .../rust/rustc/ui/new-style-constants.rs | 8 + .../rust/rustc/ui/new-unicode-escapes.rs | 15 + .../rust/rustc/ui/new-unsafe-pointers.rs | 8 + .../rust/rustc/ui/newlambdas-ret-infer.rs | 13 + .../rust/rustc/ui/newlambdas-ret-infer2.rs | 13 + gcc/testsuite/rust/rustc/ui/newlambdas.rs | 15 + .../rust/rustc/ui/newtype-polymorphic.rs | 28 + .../rust/rustc/ui/newtype-temporary.rs | 13 + gcc/testsuite/rust/rustc/ui/newtype.rs | 24 + .../rust/rustc/ui/nil-decl-in-foreign.rs | 15 + .../rustc/ui/nll/assign-while-to-immutable.rs | 12 + .../rustc/ui/nll/borrow-use-issue-46875.rs | 19 + ...ead-local-static-mut-borrow-outlives-fn.rs | 26 + .../rust/rustc/ui/nll/borrowed-local-error.rs | 13 + .../ui/nll/borrowed-match-issue-45045.rs | 19 + .../ui/nll/borrowed-referent-issue-38899.rs | 18 + .../rustc/ui/nll/borrowed-temporary-error.rs | 13 + .../ui/nll/borrowed-universal-error-2.rs | 8 + .../rustc/ui/nll/borrowed-universal-error.rs | 12 + .../rustc/ui/nll/cannot-move-block-spans.rs | 23 + .../rust/rustc/ui/nll/capture-mut-ref.rs | 17 + .../rustc/ui/nll/capture-ref-in-struct.rs | 37 + .../rust/rustc/ui/nll/closure-access-spans.rs | 57 + .../rust/rustc/ui/nll/closure-borrow-spans.rs | 101 + .../rust/rustc/ui/nll/closure-captures.rs | 56 + .../rust/rustc/ui/nll/closure-move-spans.rs | 22 + .../escape-argument-callee.rs | 43 + .../closure-requirements/escape-argument.rs | 43 + .../escape-upvar-nested.rs | 34 + .../closure-requirements/escape-upvar-ref.rs | 34 + .../issue-58127-mutliple-requirements.rs | 37 + .../propagate-approximated-fail-no-postdom.rs | 52 + .../propagate-approximated-ref.rs | 51 + ...horter-to-static-comparing-against-free.rs | 41 + ...approximated-shorter-to-static-no-bound.rs | 41 + ...roximated-shorter-to-static-wrong-bound.rs | 44 + .../propagate-approximated-val.rs | 44 + .../propagate-despite-same-free-region.rs | 51 + ...te-fail-to-approximate-longer-no-bounds.rs | 43 + ...fail-to-approximate-longer-wrong-bounds.rs | 47 + .../propagate-from-trait-match.rs | 50 + .../propagate-multiple-requirements.rs | 24 + ...region-lbr-anon-does-not-outlive-static.rs | 14 + ...egion-lbr-named-does-not-outlive-static.rs | 14 + .../region-lbr1-does-not-outlive-ebr2.rs | 14 + ...does-outlive-lbr2-because-implied-bound.rs | 12 + .../return-wrong-bound-region.rs | 24 + .../rust/rustc/ui/nll/closure-use-spans.rs | 22 + .../rust/rustc/ui/nll/closures-in-loops.rs | 25 + .../nll/constant-thread-locals-issue-47053.rs | 11 + gcc/testsuite/rust/rustc/ui/nll/constant.rs | 12 + .../rustc/ui/nll/decl-macro-illegal-copy.rs | 29 + ...not-ignore-lifetime-bounds-in-copy-proj.rs | 13 + .../do-not-ignore-lifetime-bounds-in-copy.rs | 12 + .../rust/rustc/ui/nll/dont-print-desugared.rs | 22 + .../rust/rustc/ui/nll/drop-may-dangle.rs | 36 + .../rust/rustc/ui/nll/drop-no-may-dangle.rs | 33 + .../rustc/ui/nll/empty-type-predicate-2.rs | 19 + .../rust/rustc/ui/nll/empty-type-predicate.rs | 12 + .../rust/rustc/ui/nll/enum-drop-access.rs | 50 + .../rust/rustc/ui/nll/extra-unused-mut.rs | 67 + .../ui/nll/generator-distinct-lifetime.rs | 26 + .../ui/nll/generator-upvar-mutability.rs | 15 + .../rust/rustc/ui/nll/get_default.rs | 45 + .../rustc/ui/nll/guarantor-issue-46974.rs | 22 + .../rust/rustc/ui/nll/issue-16223.rs | 53 + .../rust/rustc/ui/nll/issue-21114-ebfull.rs | 19 + .../rust/rustc/ui/nll/issue-21114-kixunil.rs | 18 + ...ue-21232-partial-init-and-erroneous-use.rs | 65 + .../nll/issue-21232-partial-init-and-use.rs | 310 + .../ui/nll/issue-22323-temp-destruction.rs | 31 + .../rust/rustc/ui/nll/issue-27868.rs | 29 + .../rust/rustc/ui/nll/issue-30104.rs | 41 + .../rust/rustc/ui/nll/issue-31567.rs | 26 + ...ue-32382-index-assoc-type-with-lifetime.rs | 42 + ...ssue-42574-diagnostic-in-nested-closure.rs | 14 + .../rust/rustc/ui/nll/issue-43058.rs | 27 + .../rust/rustc/ui/nll/issue-46589.rs | 32 + .../rust/rustc/ui/nll/issue-47022.rs | 34 + .../rustc/ui/nll/issue-47153-generic-const.rs | 19 + .../rust/rustc/ui/nll/issue-47388.rs | 11 + .../rust/rustc/ui/nll/issue-47470.rs | 23 + .../rust/rustc/ui/nll/issue-47589.rs | 24 + .../rust/rustc/ui/nll/issue-48070.rs | 24 + .../rust/rustc/ui/nll/issue-48238.rs | 11 + .../rust/rustc/ui/nll/issue-48623-closure.rs | 17 + .../rustc/ui/nll/issue-48623-generator.rs | 19 + .../rust/rustc/ui/nll/issue-48697.rs | 11 + .../rust/rustc/ui/nll/issue-50343.rs | 9 + .../ui/nll/issue-50461-used-mut-from-moves.rs | 17 + .../rust/rustc/ui/nll/issue-50716-1.rs | 11 + .../rust/rustc/ui/nll/issue-50716.rs | 18 + .../rust/rustc/ui/nll/issue-51191.rs | 32 + .../rust/rustc/ui/nll/issue-51244.rs | 6 + .../rust/rustc/ui/nll/issue-51268.rs | 24 + .../rust/rustc/ui/nll/issue-51351.rs | 22 + .../rust/rustc/ui/nll/issue-51512.rs | 7 + ...59-report-when-borrow-and-drop-conflict.rs | 31 + .../rust/rustc/ui/nll/issue-52078.rs | 25 + .../rust/rustc/ui/nll/issue-52086.rs | 15 + .../rust/rustc/ui/nll/issue-52113.rs | 38 + .../rust/rustc/ui/nll/issue-52534-1.rs | 49 + .../rust/rustc/ui/nll/issue-52534-2.rs | 15 + .../rust/rustc/ui/nll/issue-52534.rs | 20 + ...issue-52663-span-decl-captured-variable.rs | 12 + .../rustc/ui/nll/issue-52663-trait-object.rs | 17 + .../rust/rustc/ui/nll/issue-52669.rs | 18 + .../rust/rustc/ui/nll/issue-52742.rs | 20 + .../rust/rustc/ui/nll/issue-53040.rs | 6 + .../rust/rustc/ui/nll/issue-53119.rs | 24 + .../ui/nll/issue-53123-raw-pointer-cast.rs | 27 + .../rust/rustc/ui/nll/issue-53570.rs | 33 + .../rust/rustc/ui/nll/issue-53773.rs | 48 + .../rust/rustc/ui/nll/issue-53807.rs | 9 + .../issue-54382-use-span-of-tail-of-block.rs | 30 + .../rust/rustc/ui/nll/issue-54556-niconii.rs | 32 + .../rustc/ui/nll/issue-54556-stephaneyfx.rs | 36 + .../issue-54556-temps-in-tail-diagnostic.rs | 24 + .../nll/issue-54556-used-vs-unused-tails.rs | 57 + .../rustc/ui/nll/issue-54556-wrap-it-up.rs | 29 + .../rust/rustc/ui/nll/issue-55288.rs | 10 + .../rust/rustc/ui/nll/issue-55344.rs | 15 + .../rust/rustc/ui/nll/issue-55394.rs | 14 + .../rust/rustc/ui/nll/issue-55401.rs | 7 + .../rust/rustc/ui/nll/issue-55651.rs | 29 + .../rust/rustc/ui/nll/issue-55850.rs | 36 + .../rust/rustc/ui/nll/issue-57100.rs | 69 + .../nll/issue-57265-return-type-wf-check.rs | 25 + .../rust/rustc/ui/nll/issue-57280-1.rs | 20 + .../rust/rustc/ui/nll/issue-57280.rs | 21 + .../nll/issue-57642-higher-ranked-subtype.rs | 42 + .../rust/rustc/ui/nll/issue-57960.rs | 39 + .../rust/rustc/ui/nll/issue-57989.rs | 11 + .../rust/rustc/ui/nll/issue-58053.rs | 14 + .../rust/rustc/ui/nll/issue-58299.rs | 30 + .../rustc/ui/nll/issue-61311-normalize.rs | 35 + .../rustc/ui/nll/issue-61320-normalize.rs | 161 + .../rust/rustc/ui/nll/issue-61424.rs | 10 + .../ui/nll/issue-62007-assign-const-index.rs | 33 + .../issue-62007-assign-differing-fields.rs | 26 + .../rustc/ui/nll/issue-63154-normalize.rs | 35 + .../rust/rustc/ui/nll/issue-68550.rs | 16 + .../rustc/ui/nll/issue-69114-static-mut-ty.rs | 31 + .../rustc/ui/nll/issue-69114-static-ty.rs | 10 + .../rustc/ui/nll/loan_ends_mid_block_pair.rs | 30 + .../rustc/ui/nll/loan_ends_mid_block_vec.rs | 31 + .../ui/nll/local-outlives-static-via-hrtb.rs | 27 + .../rust/rustc/ui/nll/match-cfg-fake-edges.rs | 43 + .../rustc/ui/nll/match-cfg-fake-edges2.rs | 21 + .../ui/nll/match-guards-always-borrow.rs | 42 + .../ui/nll/match-guards-partially-borrow.rs | 170 + .../rust/rustc/ui/nll/match-on-borrowed.rs | 94 + ...initialized-drop-implicit-fragment-drop.rs | 20 + .../maybe-initialized-drop-uninitialized.rs | 20 + .../maybe-initialized-drop-with-fragment.rs | 23 + ...lized-drop-with-uninitialized-fragments.rs | 25 + .../rustc/ui/nll/maybe-initialized-drop.rs | 18 + .../rustc/ui/nll/mir_check_cast_closure.rs | 12 + .../rust/rustc/ui/nll/mir_check_cast_reify.rs | 42 + .../rustc/ui/nll/mir_check_cast_unsafe_fn.rs | 14 + .../rustc/ui/nll/mir_check_cast_unsize.rs | 13 + .../rust/rustc/ui/nll/move-errors.rs | 118 + .../rustc/ui/nll/move-subpaths-moves-root.rs | 6 + .../rust/rustc/ui/nll/mutating_references.rs | 25 + .../ui/nll/normalization-bounds-error.rs | 16 + .../rust/rustc/ui/nll/normalization-bounds.rs | 16 + .../rustc/ui/nll/outlives-suggestion-more.rs | 29 + .../ui/nll/outlives-suggestion-simple.rs | 78 + .../ui/nll/polonius/assignment-kills-loans.rs | 89 + .../polonius/assignment-to-differing-field.rs | 51 + .../rustc/ui/nll/polonius/call-kills-loans.rs | 25 + .../rust/rustc/ui/nll/polonius/issue-46589.rs | 33 + .../ui/nll/polonius/polonius-smoke-test.rs | 48 + .../nll/polonius/storagedead-kills-loans.rs | 30 + .../rustc/ui/nll/polonius/subset-relations.rs | 31 + .../rustc/ui/nll/process_or_insert_default.rs | 28 + .../rust/rustc/ui/nll/projection-return.rs | 19 + .../promotable-mutable-zst-doesnt-conflict.rs | 12 + .../rust/rustc/ui/nll/promoted-bounds.rs | 26 + .../rustc/ui/nll/promoted-closure-pair.rs | 11 + .../rust/rustc/ui/nll/promoted-liveness.rs | 9 + gcc/testsuite/rust/rustc/ui/nll/rc-loop.rs | 29 + .../reference-carried-through-struct-field.rs | 11 + .../ui/nll/region-ends-after-if-condition.rs | 33 + .../rustc/ui/nll/relate_tys/fn-subtype.rs | 11 + .../ui/nll/relate_tys/hr-fn-aaa-as-aba.rs | 27 + .../ui/nll/relate_tys/hr-fn-aau-eq-abu.rs | 26 + .../ui/nll/relate_tys/hr-fn-aba-as-aaa.rs | 18 + .../impl-fn-ignore-binder-via-bottom.rs | 36 + .../rustc/ui/nll/relate_tys/issue-48071.rs | 25 + .../rustc/ui/nll/relate_tys/trait-hrtb.rs | 17 + .../ui/nll/relate_tys/universe-violation.rs | 18 + .../ui/nll/relate_tys/var-appears-twice.rs | 26 + .../ui/nll/return-ref-mut-issue-46557.rs | 9 + .../rust/rustc/ui/nll/return_from_loop.rs | 36 + .../rust/rustc/ui/nll/self-assign-ref-mut.rs | 21 + .../rustc/ui/nll/trait-associated-constant.rs | 32 + .../ui/nll/ty-outlives/impl-trait-captures.rs | 16 + .../ui/nll/ty-outlives/impl-trait-outlives.rs | 39 + .../rustc/ui/nll/ty-outlives/issue-53789-1.rs | 88 + .../rustc/ui/nll/ty-outlives/issue-53789-2.rs | 249 + .../rustc/ui/nll/ty-outlives/issue-55756.rs | 38 + .../ui/nll/ty-outlives/projection-body.rs | 28 + .../ty-outlives/projection-implied-bounds.rs | 41 + .../projection-no-regions-closure.rs | 56 + .../ty-outlives/projection-no-regions-fn.rs | 41 + .../projection-one-region-closure.rs | 84 + ...ojection-one-region-trait-bound-closure.rs | 85 + ...n-one-region-trait-bound-static-closure.rs | 89 + ...ojection-two-region-trait-bound-closure.rs | 113 + ...projection-where-clause-env-wrong-bound.rs | 35 + ...jection-where-clause-env-wrong-lifetime.rs | 26 + .../projection-where-clause-env.rs | 29 + .../projection-where-clause-none.rs | 27 + .../projection-where-clause-trait.rs | 28 + ...y-param-closure-approximate-lower-bound.rs | 40 + ...param-closure-outlives-from-return-type.rs | 54 + ...aram-closure-outlives-from-where-clause.rs | 84 + .../ui/nll/ty-outlives/ty-param-fn-body.rs | 30 + .../rustc/ui/nll/ty-outlives/ty-param-fn.rs | 39 + .../ty-outlives/ty-param-implied-bounds.rs | 29 + .../ui/nll/ty-outlives/wf-unreachable.rs | 55 + .../rustc/ui/nll/type-alias-free-regions.rs | 32 + .../ui/nll/type-check-pointer-coercions.rs | 40 + .../ui/nll/type-check-pointer-comparisons.rs | 34 + .../rustc/ui/nll/unused-mut-issue-50343.rs | 10 + .../nll/user-annotations/adt-brace-enums.rs | 51 + .../nll/user-annotations/adt-brace-structs.rs | 49 + .../nll/user-annotations/adt-nullary-enums.rs | 70 + .../nll/user-annotations/adt-tuple-enums.rs | 54 + .../adt-tuple-struct-calls.rs | 72 + .../nll/user-annotations/adt-tuple-struct.rs | 49 + .../user-annotations/cast_static_lifetime.rs | 7 + .../ui/nll/user-annotations/closure-substs.rs | 34 + .../constant-in-expr-inherent-1.rs | 13 + .../constant-in-expr-inherent-2.rs | 28 + .../constant-in-expr-normalize.rs | 23 + .../constant-in-expr-trait-item-1.rs | 15 + .../constant-in-expr-trait-item-2.rs | 15 + .../constant-in-expr-trait-item-3.rs | 15 + .../ui/nll/user-annotations/downcast-infer.rs | 12 + .../user-annotations/dump-adt-brace-struct.rs | 22 + .../ui/nll/user-annotations/dump-fn-method.rs | 59 + .../rust/rustc/ui/nll/user-annotations/fns.rs | 49 + .../inherent-associated-constants.rs | 18 + .../ui/nll/user-annotations/issue-54124.rs | 11 + .../issue-54570-bootstrapping.rs | 31 + .../ui/nll/user-annotations/issue-55219.rs | 19 + .../ui/nll/user-annotations/issue-55241.rs | 27 + ...ssue-55748-pat-types-constrain-bindings.rs | 71 + .../issue-57731-ascibed-coupled-types.rs | 41 + .../ui/nll/user-annotations/method-call.rs | 70 + .../ui/nll/user-annotations/method-ufcs-1.rs | 64 + .../ui/nll/user-annotations/method-ufcs-2.rs | 64 + .../ui/nll/user-annotations/method-ufcs-3.rs | 70 + .../method-ufcs-inherent-1.rs | 21 + .../method-ufcs-inherent-2.rs | 20 + .../method-ufcs-inherent-3.rs | 21 + .../method-ufcs-inherent-4.rs | 21 + .../ui/nll/user-annotations/normalization.rs | 11 + .../nll/user-annotations/normalize-self-ty.rs | 24 + .../pattern_substs_on_brace_enum_variant.rs | 23 + .../pattern_substs_on_brace_struct.rs | 21 + .../pattern_substs_on_tuple_enum_variant.rs | 23 + .../pattern_substs_on_tuple_struct.rs | 21 + .../rustc/ui/nll/user-annotations/patterns.rs | 139 + .../user-annotations/promoted-annotation.rs | 11 + .../type-annotation-with-hrtb.rs | 34 + .../type_ascription_static_lifetime.rs | 8 + .../ui/nll/user-annotations/wf-self-type.rs | 16 + .../ui/nll/where_clauses_in_functions.rs | 18 + .../rustc/ui/nll/where_clauses_in_structs.rs | 18 + gcc/testsuite/rust/rustc/ui/no-capture-arc.rs | 18 + gcc/testsuite/rust/rustc/ui/no-core-1.rs | 16 + gcc/testsuite/rust/rustc/ui/no-core-2.rs | 21 + .../rustc/ui/no-implicit-prelude-nested.rs | 55 + .../rust/rustc/ui/no-implicit-prelude.rs | 19 + .../rust/rustc/ui/no-link-unknown-crate.rs | 5 + gcc/testsuite/rust/rustc/ui/no-link.rs | 9 + .../rust/rustc/ui/no-patterns-in-args-2.rs | 14 + .../rustc/ui/no-patterns-in-args-macro.rs | 27 + .../rust/rustc/ui/no-patterns-in-args.rs | 17 + .../rust/rustc/ui/no-reuse-move-arc.rs | 16 + .../rust/rustc/ui/no-send-res-ports.rs | 31 + gcc/testsuite/rust/rustc/ui/no-std-1.rs | 11 + gcc/testsuite/rust/rustc/ui/no-std-2.rs | 11 + gcc/testsuite/rust/rustc/ui/no-std-3.rs | 18 + gcc/testsuite/rust/rustc/ui/no-std-inject.rs | 7 + gcc/testsuite/rust/rustc/ui/no-stdio.rs | 139 + .../rust/rustc/ui/no-type-for-node-ice.rs | 6 + .../no-warn-on-field-replace-issue-34101.rs | 47 + gcc/testsuite/rust/rustc/ui/no_crate_type.rs | 7 + .../rust/rustc/ui/no_owned_box_lang_item.rs | 17 + gcc/testsuite/rust/rustc/ui/no_send-enum.rs | 19 + gcc/testsuite/rust/rustc/ui/no_send-rc.rs | 10 + gcc/testsuite/rust/rustc/ui/no_send-struct.rs | 18 + gcc/testsuite/rust/rustc/ui/no_share-enum.rs | 17 + .../rust/rustc/ui/no_share-struct.rs | 15 + .../rust/rustc/ui/noexporttypeexe.rs | 16 + .../rust/rustc/ui/non-built-in-quote.rs | 9 + .../rustc/ui/non-constant-expr-for-arr-len.rs | 9 + .../rustc/ui/non-constant-in-const-path.rs | 8 + .../rust/rustc/ui/non-copyable-void.rs | 15 + .../ui/non-ice-error-on-worker-io-fail.rs | 42 + .../rust/rustc/ui/non-integer-atomic.rs | 93 + .../rust/rustc/ui/non-legacy-modes.rs | 23 + .../rust/rustc/ui/non_modrs_mods/foors_mod.rs | 11 + .../foors_mod/inline/somename.rs | 4 + .../foors_mod/inner_foors_mod.rs | 4 + .../foors_mod/inner_foors_mod/innest.rs | 4 + .../foors_mod/inner_modrs_mod/innest.rs | 4 + .../foors_mod/inner_modrs_mod/mod.rs | 4 + .../modrs_mod/inline/somename.rs | 4 + .../modrs_mod/inner_foors_mod.rs | 4 + .../modrs_mod/inner_foors_mod/innest.rs | 4 + .../modrs_mod/inner_modrs_mod/innest.rs | 4 + .../modrs_mod/inner_modrs_mod/mod.rs | 4 + .../rustc/ui/non_modrs_mods/modrs_mod/mod.rs | 9 + .../rustc/ui/non_modrs_mods/non_modrs_mods.rs | 17 + .../some_crazy_attr_mod_dir/arbitrary_name.rs | 4 + .../inner_modrs_mod/innest.rs | 4 + .../inner_modrs_mod/mod.rs | 4 + .../non_modrs_mods_and_inline_mods.rs | 6 + .../ui/non_modrs_mods_and_inline_mods/x.rs | 6 + .../x/y/z/mod.rs | 2 + .../rust/rustc/ui/noncopyable-class.rs | 37 + gcc/testsuite/rust/rustc/ui/nonscalar-cast.rs | 17 + .../rust/rustc/ui/not-clone-closure.rs | 13 + .../rust/rustc/ui/not-copy-closure.rs | 12 + .../rust/rustc/ui/not-enough-arguments.rs | 32 + .../rustc/ui/not-panic/not-panic-safe-2.rs | 14 + .../rustc/ui/not-panic/not-panic-safe-3.rs | 14 + .../rustc/ui/not-panic/not-panic-safe-4.rs | 13 + .../rustc/ui/not-panic/not-panic-safe-5.rs | 11 + .../rustc/ui/not-panic/not-panic-safe-6.rs | 13 + .../rust/rustc/ui/not-panic/not-panic-safe.rs | 12 + gcc/testsuite/rust/rustc/ui/not-sync.rs | 23 + gcc/testsuite/rust/rustc/ui/nul-characters.rs | 37 + .../rustc/ui/nullable-pointer-ffi-compat.rs | 29 + .../ui/nullable-pointer-iotareduction.rs | 74 + .../rust/rustc/ui/nullable-pointer-size.rs | 36 + .../ui/numbers-arithmetic/arith-unsigned.rs | 27 + .../rustc/ui/numbers-arithmetic/div-mod.rs | 20 + .../ui/numbers-arithmetic/divide-by-zero.rs | 10 + .../float-int-invalid-const-cast.rs | 53 + .../float-literal-inference.rs | 14 + .../rustc/ui/numbers-arithmetic/float-nan.rs | 84 + .../ui/numbers-arithmetic/float-signature.rs | 10 + .../rust/rustc/ui/numbers-arithmetic/float.rs | 10 + .../rustc/ui/numbers-arithmetic/float2.rs | 27 + .../rustc/ui/numbers-arithmetic/float_math.rs | 22 + .../rustc/ui/numbers-arithmetic/floatlits.rs | 13 + .../rust/rustc/ui/numbers-arithmetic/i128.rs | 108 + .../rustc/ui/numbers-arithmetic/i32-sub.rs | 7 + .../rustc/ui/numbers-arithmetic/i8-incr.rs | 13 + .../ui/numbers-arithmetic/int-abs-overflow.rs | 14 + .../rust/rustc/ui/numbers-arithmetic/int.rs | 8 + .../integer-literal-radix.rs | 20 + .../integer-literal-suffix-inference-2.rs | 10 + .../integer-literal-suffix-inference-3.rs | 5 + .../integer-literal-suffix-inference.rs | 61 + .../rustc/ui/numbers-arithmetic/mod-zero.rs | 10 + .../next-power-of-two-overflow-debug.rs | 28 + .../next-power-of-two-overflow-ndebug.rs | 15 + .../ui/numbers-arithmetic/num-wrapping.rs | 448 + .../numeric-method-autoexport.rs | 26 + .../ui/numbers-arithmetic/overflowing-add.rs | 11 + .../numbers-arithmetic/overflowing-lsh-1.rs | 10 + .../numbers-arithmetic/overflowing-lsh-2.rs | 10 + .../numbers-arithmetic/overflowing-lsh-3.rs | 10 + .../numbers-arithmetic/overflowing-lsh-4.rs | 25 + .../ui/numbers-arithmetic/overflowing-mul.rs | 11 + .../ui/numbers-arithmetic/overflowing-neg.rs | 11 + .../overflowing-pow-signed.rs | 9 + .../overflowing-pow-unsigned.rs | 9 + .../numbers-arithmetic/overflowing-rsh-1.rs | 10 + .../numbers-arithmetic/overflowing-rsh-2.rs | 10 + .../numbers-arithmetic/overflowing-rsh-3.rs | 10 + .../numbers-arithmetic/overflowing-rsh-4.rs | 25 + .../numbers-arithmetic/overflowing-rsh-5.rs | 10 + .../numbers-arithmetic/overflowing-rsh-6.rs | 10 + .../ui/numbers-arithmetic/overflowing-sub.rs | 11 + .../numbers-arithmetic/promoted_overflow.rs | 10 + .../promoted_overflow_opt.rs | 10 + .../saturating-float-casts-impl.rs | 508 + .../saturating-float-casts-wasm.rs | 14 + .../saturating-float-casts.rs | 13 + .../ui/numbers-arithmetic/shift-near-oflo.rs | 101 + .../numbers-arithmetic/shift-various-types.rs | 49 + .../rust/rustc/ui/numbers-arithmetic/shift.rs | 77 + .../signed-shift-const-eval.rs | 9 + .../ui/numbers-arithmetic/u128-as-f32.rs | 49 + .../rust/rustc/ui/numbers-arithmetic/u128.rs | 120 + .../rustc/ui/numbers-arithmetic/u32-decr.rs | 11 + .../ui/numbers-arithmetic/u8-incr-decr.rs | 20 + .../rustc/ui/numbers-arithmetic/u8-incr.rs | 16 + .../rust/rustc/ui/numbers-arithmetic/uint.rs | 8 + .../rust/rustc/ui/numeric/const-scope.rs | 13 + gcc/testsuite/rust/rustc/ui/numeric/len.rs | 9 + .../rust/rustc/ui/numeric/numeric-cast-2.rs | 12 + .../rustc/ui/numeric/numeric-cast-binop.rs | 321 + .../rustc/ui/numeric/numeric-cast-no-fix.rs | 88 + .../numeric-cast-without-suggestion.rs | 39 + .../rust/rustc/ui/numeric/numeric-cast.rs | 294 + .../rust/rustc/ui/numeric/numeric-fields.rs | 11 + .../rust/rustc/ui/numeric/numeric-suffix.rs | 299 + .../rustc/ui/object-does-not-impl-trait.rs | 9 + ...ject-lifetime-default-default-to-static.rs | 36 + .../object-lifetime-default-from-rptr-box.rs | 34 + .../object-lifetime-default-from-rptr-mut.rs | 37 + .../ui/object-lifetime-default-from-rptr.rs | 43 + .../object-lifetime-default-ambiguous.rs | 49 + ...lifetime-default-dyn-binding-nonstatic1.rs | 28 + ...lifetime-default-dyn-binding-nonstatic2.rs | 31 + ...lifetime-default-dyn-binding-nonstatic3.rs | 24 + ...ect-lifetime-default-dyn-binding-static.rs | 29 + .../object-lifetime-default-elision.rs | 78 + .../object-lifetime-default-from-box-error.rs | 36 + ...ct-lifetime-default-from-rptr-box-error.rs | 20 + ...lifetime-default-from-rptr-struct-error.rs | 26 + .../object-lifetime-default-mybox.rs | 36 + .../object-lifetime-default.rs | 27 + .../rust/rustc/ui/object-method-numbering.rs | 29 + .../rust/rustc/ui/object-pointer-types.rs | 31 + .../object-safety-associated-consts.rs | 20 + .../ui/object-safety/object-safety-bounds.rs | 13 + .../object-safety-by-value-self-use.rs | 19 + .../object-safety-by-value-self.rs | 47 + .../object-safety/object-safety-generics.rs | 40 + .../object-safety-issue-22040.rs | 43 + .../object-safety-mentions-Self.rs | 43 + .../object-safety/object-safety-no-static.rs | 25 + .../object-safety/object-safety-phantom-fn.rs | 23 + .../ui/object-safety/object-safety-sized-2.rs | 22 + .../ui/object-safety/object-safety-sized.rs | 20 + .../object-safety-supertrait-mentions-Self.rs | 22 + .../ui/objects-coerce-freeze-borrored.rs | 41 + ...owned-object-borrowed-method-headerless.rs | 34 + .../ui/objects-owned-object-owned-method.rs | 26 + .../rust/rustc/ui/obsolete-in-place/bad.rs | 12 + .../ui/obsolete-syntax-impl-for-dotdot.rs | 10 + gcc/testsuite/rust/rustc/ui/occurs-check-2.rs | 11 + gcc/testsuite/rust/rustc/ui/occurs-check-3.rs | 6 + gcc/testsuite/rust/rustc/ui/occurs-check.rs | 9 + gcc/testsuite/rust/rustc/ui/offset_from.rs | 14 + .../ui/old-suffixes-are-really-forbidden.rs | 5 + .../ui/on-unimplemented/auxiliary/no_debug.rs | 4 + .../ui/on-unimplemented/bad-annotation.rs | 65 + .../ui/on-unimplemented/enclosing-scope.rs | 28 + .../expected-comma-found-token.rs | 14 + .../feature-gate-on-unimplemented.rs | 9 + .../ui/on-unimplemented/multiple-impls.rs | 43 + .../rustc/ui/on-unimplemented/no-debug.rs | 17 + .../rust/rustc/ui/on-unimplemented/on-impl.rs | 26 + .../rustc/ui/on-unimplemented/on-trait.rs | 33 + .../rustc/ui/on-unimplemented/slice-index.rs | 11 + .../rustc/ui/once-cant-call-twice-on-heap.rs | 19 + .../rust/rustc/ui/once-move-out-on-heap.rs | 19 + gcc/testsuite/rust/rustc/ui/one-tuple.rs | 16 + .../rustc/ui/op-assign-builtins-by-ref.rs | 77 + gcc/testsuite/rust/rustc/ui/opeq.rs | 18 + .../rust/rustc/ui/operator-associativity.rs | 5 + .../rust/rustc/ui/operator-multidispatch.rs | 37 + .../rust/rustc/ui/operator-overloading.rs | 82 + gcc/testsuite/rust/rustc/ui/opt-in-copy.rs | 23 + .../rust/rustc/ui/optimization-fuel-0.rs | 16 + .../rust/rustc/ui/optimization-fuel-1.rs | 17 + gcc/testsuite/rust/rustc/ui/option-ext.rs | 11 + .../rust/rustc/ui/option-to-result.rs | 14 + .../ui/or-patterns/already-bound-name.rs | 46 + .../rust/rustc/ui/or-patterns/basic-switch.rs | 34 + .../rustc/ui/or-patterns/basic-switchint.rs | 55 + .../ui/or-patterns/bindings-runpass-1.rs | 26 + .../ui/or-patterns/bindings-runpass-2.rs | 33 + .../rust/rustc/ui/or-patterns/box-patterns.rs | 38 + .../ui/or-patterns/consistent-bindings.rs | 42 + .../rust/rustc/ui/or-patterns/const-fn.rs | 31 + .../exhaustiveness-non-exhaustive.rs | 19 + .../ui/or-patterns/exhaustiveness-pass.rs | 40 + .../exhaustiveness-unreachable-pattern.rs | 106 + .../feature-gate-or_patterns-leading-for.rs | 9 + .../feature-gate-or_patterns-leading-let.rs | 9 + .../or-patterns/feature-gate-or_patterns.rs | 53 + .../ui/or-patterns/fn-param-wrap-parens.rs | 15 + .../rust/rustc/ui/or-patterns/for-loop.rs | 19 + .../rustc/ui/or-patterns/if-let-while-let.rs | 23 + .../ui/or-patterns/inconsistent-modes.rs | 27 + .../issue-64879-trailing-before-guard.rs | 16 + .../issue-67514-irrefutable-param.rs | 12 + .../issue-68785-irrefutable-param-with-at.rs | 15 + ...ve-been-expanded-earlier-non-exhaustive.rs | 10 + ...69875-should-have-been-expanded-earlier.rs | 10 + ...ssue-70413-no-unreachable-pat-and-guard.rs | 23 + .../rust/rustc/ui/or-patterns/let-pattern.rs | 20 + .../mismatched-bindings-async-fn.rs | 17 + .../rustc/ui/or-patterns/missing-bindings.rs | 83 + .../rustc/ui/or-patterns/mix-with-wild.rs | 20 + .../ui/or-patterns/multiple-pattern-typo.rs | 45 + .../or-patterns-binding-type-mismatch.rs | 69 + .../or-patterns-default-binding-modes.rs | 133 + .../or-patterns/or-patterns-syntactic-fail.rs | 53 + .../or-patterns/or-patterns-syntactic-pass.rs | 79 + .../ui/or-patterns/remove-leading-vert.rs | 47 + .../ui/or-patterns/search-via-bindings.rs | 66 + .../rustc/ui/or-patterns/slice-patterns.rs | 54 + .../rust/rustc/ui/or-patterns/struct-like.rs | 43 + .../while-parsing-this-or-pattern.rs | 10 + .../ui/order-dependent-cast-inference.rs | 9 + .../rust/rustc/ui/orphan-check-diagnostics.rs | 15 + gcc/testsuite/rust/rustc/ui/osx-frameworks.rs | 9 + .../rust/rustc/ui/out-of-order-shadowing.rs | 11 + gcc/testsuite/rust/rustc/ui/out-of-stack.rs | 90 + .../rust/rustc/ui/out-pointer-aliasing.rs | 24 + .../rust/rustc/ui/output-slot-variants.rs | 71 + .../rust/rustc/ui/output-type-mismatch.rs | 6 + .../rust/rustc/ui/over-constrained-vregs.rs | 13 + ...lap-doesnt-conflict-with-specialization.rs | 21 + ...p-permitted-for-annotated-marker-traits.rs | 27 + .../rustc/ui/overloaded-calls-nontuple.rs | 28 + .../auxiliary/overloaded_autoderef_xc.rs | 31 + .../overloaded/overloaded-autoderef-count.rs | 75 + .../overloaded-autoderef-indexing.rs | 21 + .../overloaded/overloaded-autoderef-order.rs | 72 + .../overloaded/overloaded-autoderef-vtable.rs | 40 + .../overloaded/overloaded-autoderef-xcrate.rs | 10 + .../ui/overloaded/overloaded-autoderef.rs | 46 + .../overloaded-calls-object-one-arg.rs | 14 + .../overloaded-calls-object-two-args.rs | 14 + .../overloaded-calls-object-zero-args.rs | 14 + .../overloaded-calls-param-vtables.rs | 33 + .../ui/overloaded/overloaded-calls-simple.rs | 79 + .../overloaded/overloaded-calls-zero-args.rs | 31 + .../ui/overloaded/overloaded-deref-count.rs | 79 + .../rustc/ui/overloaded/overloaded-deref.rs | 44 + .../overloaded/overloaded-index-assoc-list.rs | 49 + .../overloaded/overloaded-index-autoderef.rs | 78 + .../overloaded/overloaded-index-in-field.rs | 47 + .../rustc/ui/overloaded/overloaded-index.rs | 65 + .../overloaded_deref_with_ref_pattern.rs | 96 + ...oaded_deref_with_ref_pattern_issue15609.rs | 38 + .../rust/rustc/ui/owned-implies-static.rs | 9 + .../packed-struct-generic-transmute.rs | 28 + .../packed-struct/packed-struct-transmute.rs | 30 + .../rust/rustc/ui/packed/auxiliary/packed.rs | 20 + .../packed-struct-address-of-element.rs | 38 + .../ui/packed/packed-struct-borrow-element.rs | 36 + .../ui/packed/packed-struct-drop-aligned.rs | 34 + .../ui/packed/packed-struct-generic-layout.rs | 33 + .../ui/packed/packed-struct-generic-size.rs | 45 + .../rustc/ui/packed/packed-struct-layout.rs | 29 + .../rustc/ui/packed/packed-struct-match.rs | 46 + .../ui/packed/packed-struct-optimized-enum.rs | 37 + .../rustc/ui/packed/packed-struct-size-xc.rs | 21 + .../rustc/ui/packed/packed-struct-size.rs | 158 + .../rust/rustc/ui/packed/packed-struct-vec.rs | 121 + .../ui/packed/packed-tuple-struct-layout.rs | 22 + .../ui/packed/packed-tuple-struct-size.rs | 80 + .../packed-with-inference-vars-issue-61402.rs | 23 + .../auxiliary/some-panic-impl.rs | 12 + .../panic-handler-bad-signature-1.rs | 14 + .../panic-handler-bad-signature-2.rs | 15 + .../panic-handler-bad-signature-3.rs | 12 + .../panic-handler-bad-signature-4.rs | 13 + .../panic-handler/panic-handler-duplicate.rs | 18 + .../panic-handler-requires-panic-info.rs | 16 + .../ui/panic-handler/panic-handler-std.rs | 13 + .../panic-handler-wrong-location.rs | 9 + .../abort-link-to-unwind-dylib.rs | 19 + .../abort-link-to-unwinding-crates.rs | 42 + .../rust/rustc/ui/panic-runtime/abort.rs | 45 + .../auxiliary/exit-success-if-unwind.rs | 17 + .../auxiliary/panic-runtime-abort.rs | 18 + .../auxiliary/panic-runtime-lang-items.rs | 16 + .../auxiliary/panic-runtime-unwind.rs | 18 + .../auxiliary/panic-runtime-unwind2.rs | 18 + .../auxiliary/wants-panic-runtime-abort.rs | 8 + .../auxiliary/wants-panic-runtime-unwind.rs | 7 + .../rustc/ui/panic-runtime/bad-panic-flag1.rs | 5 + .../rustc/ui/panic-runtime/bad-panic-flag2.rs | 5 + .../rustc/ui/panic-runtime/link-to-abort.rs | 12 + .../rustc/ui/panic-runtime/link-to-unwind.rs | 11 + .../rust/rustc/ui/panic-runtime/lto-abort.rs | 35 + .../rust/rustc/ui/panic-runtime/lto-unwind.rs | 38 + .../rust/rustc/ui/panic-runtime/needs-gate.rs | 8 + .../panic-runtime/transitive-link-a-bunch.rs | 16 + .../ui/panic-runtime/unwind-interleaved.rs | 17 + .../rust/rustc/ui/panic-runtime/unwind-rec.rs | 16 + .../rustc/ui/panic-runtime/unwind-rec2.rs | 24 + .../rustc/ui/panic-runtime/unwind-unique.rs | 13 + .../ui/panic-runtime/want-unwind-got-abort.rs | 12 + .../panic-runtime/want-unwind-got-abort2.rs | 13 + .../rust/rustc/ui/panic-while-printing.rs | 40 + .../rustc/ui/panic_implementation-closures.rs | 11 + .../rust/rustc/ui/panics/abort-on-panic.rs | 65 + .../rust/rustc/ui/panics/args-panic.rs | 14 + .../rust/rustc/ui/panics/doublepanic.rs | 11 + .../rustc/ui/panics/explicit-panic-msg.rs | 15 + .../rust/rustc/ui/panics/explicit-panic.rs | 8 + .../rust/rustc/ui/panics/fmt-panic.rs | 9 + .../ui/panics/issue-47429-short-backtraces.rs | 19 + .../rust/rustc/ui/panics/main-panic.rs | 8 + .../rust/rustc/ui/panics/panic-arg.rs | 12 + .../rustc/ui/panics/panic-handler-chain.rs | 30 + .../ui/panics/panic-handler-flail-wildly.rs | 56 + .../ui/panics/panic-handler-set-twice.rs | 25 + .../ui/panics/panic-in-dtor-drops-fields.rs | 38 + .../ui/panics/panic-macro-any-wrapped.rs | 8 + .../rust/rustc/ui/panics/panic-macro-any.rs | 10 + .../rustc/ui/panics/panic-macro-explicit.rs | 8 + .../rust/rustc/ui/panics/panic-macro-fmt.rs | 8 + .../rust/rustc/ui/panics/panic-macro-owned.rs | 8 + .../rustc/ui/panics/panic-macro-static.rs | 8 + .../rust/rustc/ui/panics/panic-main.rs | 8 + .../rust/rustc/ui/panics/panic-parens.rs | 21 + .../ui/panics/panic-recover-propagate.rs | 27 + .../rust/rustc/ui/panics/panic-set-handler.rs | 13 + .../ui/panics/panic-set-unset-handler.rs | 14 + .../rustc/ui/panics/panic-take-handler-nop.rs | 11 + .../rustc/ui/panics/panic-task-name-none.rs | 14 + .../rustc/ui/panics/panic-task-name-owned.rs | 19 + gcc/testsuite/rust/rustc/ui/panics/panic.rs | 8 + .../rust/rustc/ui/panics/result-get-panic.rs | 10 + .../rust/rustc/ui/panics/test-panic.rs | 10 + .../ui/panics/test-should-fail-bad-message.rs | 11 + .../panics/test-should-panic-bad-message.rs | 11 + .../ui/panics/test-should-panic-no-message.rs | 11 + .../rust/rustc/ui/panics/unique-panic.rs | 7 + .../rust/rustc/ui/panics/while-body-panics.rs | 15 + .../rust/rustc/ui/panics/while-panic.rs | 15 + gcc/testsuite/rust/rustc/ui/paren-free.rs | 8 + gcc/testsuite/rust/rustc/ui/paren-span.rs | 22 + .../ui/parenthesized-deref-suggestion.rs | 12 + .../rust/rustc/ui/parse-assoc-type-lt.rs | 10 + .../rust/rustc/ui/parse-error-correct.rs | 11 + gcc/testsuite/rust/rustc/ui/parse-panic.rs | 9 + .../rust/rustc/ui/parser-recovery-1.rs | 14 + .../rust/rustc/ui/parser-recovery-2.rs | 13 + .../rustc/ui/parser-unicode-whitespace.rs | 13 + .../ui/parser/ascii-only-character-escape.rs | 7 + .../assoc-const-underscore-semantic-fail.rs | 18 + .../assoc-const-underscore-syntactic-pass.rs | 19 + .../rust/rustc/ui/parser/assoc-oddities-1.rs | 12 + .../rust/rustc/ui/parser/assoc-oddities-2.rs | 7 + .../ui/parser/assoc-static-semantic-fail.rs | 53 + .../ui/parser/assoc-static-syntactic-fail.rs | 34 + .../rustc/ui/parser/assoc-type-in-type-arg.rs | 12 + ...ciated-types-project-from-hrtb-explicit.rs | 17 + .../rust/rustc/ui/parser/attr-bad-meta-2.rs | 3 + .../rust/rustc/ui/parser/attr-bad-meta-3.rs | 3 + .../rust/rustc/ui/parser/attr-bad-meta.rs | 3 + .../rust/rustc/ui/parser/attr-before-eof.rs | 4 + .../rustc/ui/parser/attr-dangling-in-fn.rs | 9 + .../rustc/ui/parser/attr-dangling-in-mod.rs | 7 + .../ui/parser/attr-stmt-expr-attr-bad.rs | 112 + gcc/testsuite/rust/rustc/ui/parser/attr.rs | 8 + .../rustc/ui/parser/attrs-after-extern-mod.rs | 8 + .../rust/rustc/ui/parser/bad-char-literals.rs | 21 + .../rustc/ui/parser/bad-fn-ptr-qualifier.rs | 27 + .../rustc/ui/parser/bad-interpolated-block.rs | 16 + .../rust/rustc/ui/parser/bad-lit-suffixes.rs | 27 + .../rust/rustc/ui/parser/bad-match.rs | 5 + .../rust/rustc/ui/parser/bad-name.rs | 6 + .../rust/rustc/ui/parser/bad-pointer-type.rs | 6 + .../rustc/ui/parser/bad-value-ident-false.rs | 3 + .../rustc/ui/parser/bad-value-ident-true.rs | 3 + .../rust/rustc/ui/parser/bare-struct-body.rs | 16 + .../rust/rustc/ui/parser/better-expected.rs | 4 + .../ui/parser/bind-struct-early-modifiers.rs | 8 + .../rustc/ui/parser/block-no-opening-brace.rs | 32 + .../ui/parser/bound-single-question-mark.rs | 2 + .../rust/rustc/ui/parser/bounds-lifetime-1.rs | 4 + .../rust/rustc/ui/parser/bounds-lifetime-2.rs | 4 + .../ui/parser/bounds-lifetime-where-1.rs | 4 + .../rustc/ui/parser/bounds-lifetime-where.rs | 11 + .../rust/rustc/ui/parser/bounds-lifetime.rs | 12 + .../rust/rustc/ui/parser/bounds-obj-parens.rs | 8 + .../rust/rustc/ui/parser/bounds-type-where.rs | 12 + .../rust/rustc/ui/parser/bounds-type.rs | 19 + .../brace-after-qualified-path-in-match.rs | 8 + .../rust/rustc/ui/parser/byte-literals.rs | 13 + .../rustc/ui/parser/byte-string-literals.rs | 9 + .../parser/chained-comparison-suggestion.rs | 54 + .../rustc/ui/parser/circular_modules_hello.rs | 9 + .../rustc/ui/parser/circular_modules_main.rs | 11 + .../ui/parser/class-implements-bad-trait.rs | 10 + .../rustc/ui/parser/closure-return-syntax.rs | 8 + .../rustc/ui/parser/column-offset-1-based.rs | 2 + ...ints-before-generic-args-syntactic-pass.rs | 10 + .../ui/parser/default-on-wrong-item-kind.rs | 141 + .../ui/parser/default-unmatched-assoc.rs | 17 + .../ui/parser/default-unmatched-extern.rs | 9 + .../rust/rustc/ui/parser/default-unmatched.rs | 7 + gcc/testsuite/rust/rustc/ui/parser/default.rs | 29 + .../rustc/ui/parser/do-catch-suggests-try.rs | 11 + .../rustc/ui/parser/doc-after-struct-field.rs | 17 + .../rust/rustc/ui/parser/doc-before-attr.rs | 5 + .../rust/rustc/ui/parser/doc-before-eof.rs | 4 + .../ui/parser/doc-before-extern-rbrace.rs | 7 + .../rustc/ui/parser/doc-before-fn-rbrace.rs | 6 + .../rustc/ui/parser/doc-before-identifier.rs | 8 + .../rustc/ui/parser/doc-before-mod-rbrace.rs | 7 + .../rust/rustc/ui/parser/doc-before-rbrace.rs | 6 + .../rust/rustc/ui/parser/doc-before-semi.rs | 7 + .../ui/parser/doc-before-struct-rbrace-1.rs | 11 + .../ui/parser/doc-before-struct-rbrace-2.rs | 10 + .../ui/parser/doc-comment-in-if-statement.rs | 6 + .../rustc/ui/parser/doc-comment-in-stmt.rs | 21 + .../rustc/ui/parser/doc-inside-trait-item.rs | 7 + .../rustc/ui/parser/duplicate-visibility.rs | 8 + .../rustc/ui/parser/empty-impl-semicolon.rs | 2 + .../rust/rustc/ui/parser/expr-as-stmt-2.rs | 11 + .../rust/rustc/ui/parser/expr-as-stmt.rs | 35 + .../extern-abi-from-mac-literal-frag.rs | 48 + .../rustc/ui/parser/extern-abi-raw-strings.rs | 14 + .../ui/parser/extern-abi-string-escaping.rs | 14 + .../rustc/ui/parser/extern-abi-syntactic.rs | 18 + .../rustc/ui/parser/extern-crate-async.rs | 13 + .../parser/extern-crate-unexpected-token.rs | 2 + .../ui/parser/extern-expected-fn-or-brace.rs | 4 + .../rustc/ui/parser/extern-foreign-crate.rs | 5 + .../rust/rustc/ui/parser/extern-no-fn.rs | 7 + .../ui/parser/float-field-interpolated.rs | 18 + .../rust/rustc/ui/parser/float-field.rs | 63 + .../rustc/ui/parser/fn-arg-doc-comment.rs | 27 + .../rustc/ui/parser/fn-body-eq-expr-semi.rs | 24 + .../parser/fn-body-optional-semantic-fail.rs | 28 + .../parser/fn-body-optional-syntactic-pass.rs | 32 + .../rustc/ui/parser/fn-colon-return-type.rs | 6 + .../ui/parser/fn-header-semantic-fail.rs | 59 + .../ui/parser/fn-header-syntactic-pass.rs | 48 + .../rustc/ui/parser/fn-returns-fn-pointer.rs | 7 + .../ui/parser/foreign-const-semantic-fail.rs | 10 + .../ui/parser/foreign-const-syntactic-fail.rs | 10 + .../ui/parser/foreign-static-semantic-fail.rs | 9 + .../parser/foreign-static-syntactic-pass.rs | 12 + .../ui/parser/foreign-ty-semantic-fail.rs | 19 + .../ui/parser/foreign-ty-syntactic-pass.rs | 13 + .../rust/rustc/ui/parser/if-in-in.rs | 8 + .../rustc/ui/parser/impl-item-const-pass.rs | 9 + .../parser/impl-item-const-semantic-fail.rs | 8 + .../ui/parser/impl-item-fn-no-body-pass.rs | 9 + .../impl-item-fn-no-body-semantic-fail.rs | 8 + .../ui/parser/impl-item-type-no-body-pass.rs | 12 + .../impl-item-type-no-body-semantic-fail.rs | 24 + .../rust/rustc/ui/parser/impl-parsing.rs | 11 + .../rust/rustc/ui/parser/impl-qpath.rs | 8 + .../rust/rustc/ui/parser/import-from-path.rs | 3 + .../rustc/ui/parser/import-from-rename.rs | 11 + .../rust/rustc/ui/parser/import-glob-path.rs | 3 + .../rustc/ui/parser/import-glob-rename.rs | 11 + .../ui/parser/inner-attr-after-doc-comment.rs | 9 + .../ui/parser/inner-attr-in-trait-def.rs | 10 + .../rust/rustc/ui/parser/inner-attr.rs | 5 + .../ui/parser/int-literal-too-large-span.rs | 8 + .../rustc/ui/parser/intersection-patterns.rs | 41 + .../rustc/ui/parser/inverted-parameters.rs | 33 + .../rust/rustc/ui/parser/issue-10392-2.rs | 10 + .../rust/rustc/ui/parser/issue-10392.rs | 8 + .../rust/rustc/ui/parser/issue-10636-1.rs | 9 + .../rust/rustc/ui/parser/issue-10636-2.rs | 12 + .../rust/rustc/ui/parser/issue-14303-enum.rs | 7 + .../rustc/ui/parser/issue-14303-fn-def.rs | 5 + .../rustc/ui/parser/issue-14303-fncall.rs | 18 + .../rust/rustc/ui/parser/issue-14303-impl.rs | 7 + .../rust/rustc/ui/parser/issue-14303-path.rs | 14 + .../rustc/ui/parser/issue-14303-struct.rs | 7 + .../rust/rustc/ui/parser/issue-14303-trait.rs | 5 + .../rust/rustc/ui/parser/issue-15914.rs | 5 + .../rust/rustc/ui/parser/issue-15980.rs | 18 + .../rust/rustc/ui/parser/issue-1655.rs | 11 + .../rust/rustc/ui/parser/issue-17383.rs | 8 + .../rustc/ui/parser/issue-17718-const-mut.rs | 8 + .../rust/rustc/ui/parser/issue-17904-2.rs | 4 + .../rust/rustc/ui/parser/issue-17904.rs | 7 + .../rust/rustc/ui/parser/issue-1802-1.rs | 8 + .../rust/rustc/ui/parser/issue-1802-2.rs | 8 + .../rust/rustc/ui/parser/issue-19096.rs | 11 + .../rust/rustc/ui/parser/issue-19398.rs | 7 + .../rust/rustc/ui/parser/issue-20711-2.rs | 11 + .../rust/rustc/ui/parser/issue-20711.rs | 9 + .../rust/rustc/ui/parser/issue-21153.rs | 7 + .../rust/rustc/ui/parser/issue-22647.rs | 16 + .../rust/rustc/ui/parser/issue-22712.rs | 10 + .../rust/rustc/ui/parser/issue-2354-1.rs | 2 + .../rust/rustc/ui/parser/issue-2354.rs | 16 + .../ui/parser/issue-23620-invalid-escapes.rs | 35 + .../rust/rustc/ui/parser/issue-24197.rs | 4 + .../rust/rustc/ui/parser/issue-24375.rs | 10 + .../rust/rustc/ui/parser/issue-24780.rs | 10 + .../rust/rustc/ui/parser/issue-27255.rs | 11 + .../rust/rustc/ui/parser/issue-30318.rs | 8 + .../rust/rustc/ui/parser/issue-3036.rs | 8 + .../rust/rustc/ui/parser/issue-32214.rs | 7 + .../rust/rustc/ui/parser/issue-32446.rs | 5 + .../rust/rustc/ui/parser/issue-32501.rs | 10 + .../rust/rustc/ui/parser/issue-32505.rs | 6 + .../rust/rustc/ui/parser/issue-33262.rs | 7 + .../rust/rustc/ui/parser/issue-33413.rs | 10 + .../rust/rustc/ui/parser/issue-33418.rs | 22 + .../rust/rustc/ui/parser/issue-33455.rs | 2 + .../parser/issue-35813-postfix-after-cast.rs | 172 + .../rust/rustc/ui/parser/issue-41155.rs | 8 + .../rust/rustc/ui/parser/issue-43692.rs | 4 + ...not-interpolate-impl-items-bad-variants.rs | 45 + ...37-macros-cannot-interpolate-impl-items.rs | 35 + .../rust/rustc/ui/parser/issue-5544-a.rs | 5 + .../rust/rustc/ui/parser/issue-5544-b.rs | 5 + .../rust/rustc/ui/parser/issue-5806.rs | 8 + ...ssue-58094-missing-right-square-bracket.rs | 5 + .../rust/rustc/ui/parser/issue-59418.rs | 19 + .../rust/rustc/ui/parser/issue-62524.rs | 7 + .../rust/rustc/ui/parser/issue-62546.rs | 4 + .../rust/rustc/ui/parser/issue-62660.rs | 12 + .../rust/rustc/ui/parser/issue-62881.rs | 7 + .../rust/rustc/ui/parser/issue-62894.rs | 8 + .../rust/rustc/ui/parser/issue-62895.rs | 12 + .../rust/rustc/ui/parser/issue-62913.rs | 5 + .../rust/rustc/ui/parser/issue-62973.rs | 9 + .../issue-63115-range-pat-interpolated.rs | 23 + .../rust/rustc/ui/parser/issue-63116.rs | 4 + .../rust/rustc/ui/parser/issue-63135.rs | 4 + .../issue-65041-empty-vis-matcher-in-enum.rs | 29 + .../issue-65041-empty-vis-matcher-in-trait.rs | 29 + .../issue-65122-mac-invoc-in-mut-patterns.rs | 27 + .../issue-65257-invalid-var-decl-recovery.rs | 22 + ...e-65846-rollback-gating-failing-matcher.rs | 15 + .../rust/rustc/ui/parser/issue-6610.rs | 4 + .../issue-66357-unexpected-unreachable.rs | 17 + ...-negative-outlives-bound-syntactic-fail.rs | 15 + ...377-invalid-syntax-in-enum-discriminant.rs | 36 + .../rust/rustc/ui/parser/issue-68629.rs | Bin 0 -> 338 bytes .../rust/rustc/ui/parser/issue-68730.rs | Bin 0 -> 177 bytes .../issue-68788-in-trait-item-propagation.rs | 22 + .../rust/rustc/ui/parser/issue-68890-2.rs | 7 + .../rust/rustc/ui/parser/issue-68890.rs | 5 + ...sue-70050-ntliteral-accepts-negated-lit.rs | 17 + .../issue-70388-recover-dotdotdot-rest-pat.rs | 8 + .../ui/parser/issue-70388-without-witness.rs | 10 + ...70549-resolve-after-recovered-self-ctor.rs | 19 + ...e-70552-ascription-in-parens-after-call.rs | 4 + .../ui/parser/issue-70583-block-is-empty-1.rs | 21 + .../ui/parser/issue-70583-block-is-empty-2.rs | 15 + .../parser/issue-73568-lifetime-after-mut.rs | 22 + .../rust/rustc/ui/parser/issue-8537.rs | 6 + .../item-free-const-no-body-semantic-fail.rs | 8 + .../item-free-const-no-body-syntactic-pass.rs | 9 + .../item-free-static-no-body-semantic-fail.rs | 12 + ...item-free-static-no-body-syntactic-pass.rs | 9 + .../item-free-type-bounds-semantic-fail.rs | 21 + .../item-free-type-bounds-syntactic-pass.rs | 14 + .../rust/rustc/ui/parser/keyword-abstract.rs | 4 + .../ui/parser/keyword-as-as-identifier.rs | 6 + .../ui/parser/keyword-box-as-identifier.rs | 4 + .../ui/parser/keyword-break-as-identifier.rs | 6 + .../ui/parser/keyword-const-as-identifier.rs | 6 + .../parser/keyword-continue-as-identifier.rs | 6 + .../ui/parser/keyword-else-as-identifier.rs | 6 + .../ui/parser/keyword-enum-as-identifier.rs | 6 + .../rust/rustc/ui/parser/keyword-final.rs | 4 + .../ui/parser/keyword-fn-as-identifier.rs | 6 + .../ui/parser/keyword-for-as-identifier.rs | 6 + .../ui/parser/keyword-if-as-identifier.rs | 6 + .../ui/parser/keyword-impl-as-identifier.rs | 6 + .../ui/parser/keyword-in-as-identifier.rs | 6 + .../ui/parser/keyword-let-as-identifier.rs | 6 + .../ui/parser/keyword-loop-as-identifier.rs | 6 + .../ui/parser/keyword-match-as-identifier.rs | 6 + .../ui/parser/keyword-mod-as-identifier.rs | 6 + .../ui/parser/keyword-move-as-identifier.rs | 6 + .../ui/parser/keyword-mut-as-identifier.rs | 4 + .../rust/rustc/ui/parser/keyword-override.rs | 4 + .../ui/parser/keyword-pub-as-identifier.rs | 6 + .../ui/parser/keyword-ref-as-identifier.rs | 4 + .../ui/parser/keyword-return-as-identifier.rs | 6 + .../ui/parser/keyword-static-as-identifier.rs | 6 + .../ui/parser/keyword-struct-as-identifier.rs | 6 + .../ui/parser/keyword-trait-as-identifier.rs | 6 + .../keyword-try-as-identifier-edition2018.rs | 6 + .../ui/parser/keyword-type-as-identifier.rs | 6 + .../rust/rustc/ui/parser/keyword-typeof.rs | 4 + .../ui/parser/keyword-unsafe-as-identifier.rs | 6 + .../ui/parser/keyword-use-as-identifier.rs | 6 + .../ui/parser/keyword-where-as-identifier.rs | 6 + .../ui/parser/keyword-while-as-identifier.rs | 6 + gcc/testsuite/rust/rustc/ui/parser/keyword.rs | 6 + .../keywords-followed-by-double-colon.rs | 9 + .../rustc/ui/parser/labeled-no-colon-expr.rs | 18 + .../rust/rustc/ui/parser/let-binop.rs | 11 + .../rustc/ui/parser/lex-bad-binary-literal.rs | 12 + .../ui/parser/lex-bad-char-literals-1.rs | 18 + .../ui/parser/lex-bad-char-literals-2.rs | 7 + .../ui/parser/lex-bad-char-literals-3.rs | 8 + .../ui/parser/lex-bad-char-literals-4.rs | 6 + .../ui/parser/lex-bad-char-literals-5.rs | 8 + .../ui/parser/lex-bad-char-literals-6.rs | 18 + .../ui/parser/lex-bad-char-literals-7.rs | 14 + .../ui/parser/lex-bad-numeric-literals.rs | 28 + .../rustc/ui/parser/lex-bad-octal-literal.rs | 5 + .../rust/rustc/ui/parser/lex-bad-token.rs | 4 + .../lex-bare-cr-string-literal-doc-comment.rs | 27 + .../rustc/ui/parser/lex-stray-backslash.rs | 4 + .../ui/parser/lifetime-in-pattern-recover.rs | 7 + .../rustc/ui/parser/lifetime-in-pattern.rs | 8 + .../rustc/ui/parser/lifetime-semicolon.rs | 9 + .../ui/parser/macro-bad-delimiter-ident.rs | 4 + .../rust/rustc/ui/parser/macro-keyword.rs | 6 + .../macro-mismatched-delim-brace-paren.rs | 8 + .../macro-mismatched-delim-paren-brace.rs | 6 + .../ui/parser/macro/bad-macro-argument.rs | 5 + .../rust/rustc/ui/parser/macro/issue-33569.rs | 11 + .../rust/rustc/ui/parser/macro/issue-37113.rs | 12 + .../rust/rustc/ui/parser/macro/issue-37234.rs | 10 + ...literals-are-validated-before-expansion.rs | 11 + .../ui/parser/macro/macro-doc-comments-1.rs | 10 + .../ui/parser/macro/macro-doc-comments-2.rs | 10 + .../ui/parser/macro/macro-incomplete-parse.rs | 28 + .../rustc/ui/parser/macro/macro-repeat.rs | 13 + .../rustc/ui/parser/macro/pub-item-macro.rs | 22 + .../ui/parser/macro/trait-non-item-macros.rs | 14 + .../macro/trait-object-macro-matcher.rs | 16 + .../ui/parser/macros-no-semicolon-items.rs | 16 + .../rustc/ui/parser/macros-no-semicolon.rs | 6 + .../parser/match-arrows-block-then-binop.rs | 8 + .../rustc/ui/parser/match-refactor-to-expr.rs | 13 + .../ui/parser/mbe_missing_right_paren.rs | 4 + .../missing-close-brace-in-impl-trait.rs | 14 + .../missing-close-brace-in-struct.rs | 14 + .../missing-close-brace-in-trait.rs | 13 + .../mismatched-delim-brace-empty-block.rs | 6 + .../rust/rustc/ui/parser/missing-semicolon.rs | 9 + .../rustc/ui/parser/missing_right_paren.rs | 4 + .../rustc/ui/parser/mod_file_not_exist.rs | 10 + .../ui/parser/mod_file_not_exist_windows.rs | 10 + .../ui/parser/mod_file_with_path_attr.rs | 9 + .../parser/multiline-comment-line-tracking.rs | 10 + .../rust/rustc/ui/parser/multitrait.rs | 10 + .../rust/rustc/ui/parser/mut-patterns.rs | 49 + .../rustc/ui/parser/new-unicode-escapes-1.rs | 4 + .../rustc/ui/parser/new-unicode-escapes-2.rs | 4 + .../rustc/ui/parser/new-unicode-escapes-3.rs | 5 + .../rustc/ui/parser/new-unicode-escapes-4.rs | 5 + .../ui/parser/no-binary-float-literal.rs | 9 + .../ui/parser/no-const-fn-in-extern-block.rs | 9 + .../rustc/ui/parser/no-hex-float-literal.rs | 10 + .../rust/rustc/ui/parser/no-unsafe-self.rs | 15 + .../rust/rustc/ui/parser/not-a-pred.rs | 7 + .../ui/parser/nt-parsing-has-recovery.rs | 11 + .../rust/rustc/ui/parser/numeric-lifetime.rs | 9 + .../rustc/ui/parser/omitted-arg-in-item-fn.rs | 5 + .../rustc/ui/parser/paamayim-nekudotayim.rs | 6 + .../paren-after-qualified-path-in-match.rs | 8 + .../rust/rustc/ui/parser/pat-lt-bracket-1.rs | 8 + .../rust/rustc/ui/parser/pat-lt-bracket-2.rs | 5 + .../rust/rustc/ui/parser/pat-lt-bracket-3.rs | 15 + .../rust/rustc/ui/parser/pat-lt-bracket-4.rs | 12 + .../rust/rustc/ui/parser/pat-lt-bracket-5.rs | 4 + .../rust/rustc/ui/parser/pat-lt-bracket-6.rs | 10 + .../rust/rustc/ui/parser/pat-lt-bracket-7.rs | 10 + .../rust/rustc/ui/parser/pat-ranges-1.rs | 6 + .../rust/rustc/ui/parser/pat-ranges-2.rs | 6 + .../rust/rustc/ui/parser/pat-ranges-3.rs | 6 + .../rust/rustc/ui/parser/pat-ranges-4.rs | 7 + .../rust/rustc/ui/parser/pat-ref-enum.rs | 9 + .../rust/rustc/ui/parser/pat-tuple-1.rs | 6 + .../rust/rustc/ui/parser/pat-tuple-2.rs | 8 + .../rust/rustc/ui/parser/pat-tuple-3.rs | 7 + .../rust/rustc/ui/parser/pub-method-macro.rs | 24 + .../ui/parser/qualified-path-in-turbofish.rs | 20 + gcc/testsuite/rust/rustc/ui/parser/range-3.rs | 7 + gcc/testsuite/rust/rustc/ui/parser/range-4.rs | 7 + .../rust/rustc/ui/parser/range_inclusive.rs | 8 + .../ui/parser/range_inclusive_dotdotdot.rs | 24 + ...77-panic-on-unterminated-raw-str-at-eof.rs | 6 + .../ui/parser/raw/raw-byte-string-eof.rs | 4 + .../ui/parser/raw/raw-byte-string-literals.rs | 8 + .../ui/parser/raw/raw-literal-keywords.rs | 26 + .../rustc/ui/parser/raw/raw-literal-self.rs | 5 + .../ui/parser/raw/raw-literal-underscore.rs | 5 + .../rust/rustc/ui/parser/raw/raw-str-delim.rs | 4 + .../ui/parser/raw/raw-str-in-macro-call.rs | 15 + .../rustc/ui/parser/raw/raw-str-unbalanced.rs | 5 + .../ui/parser/raw/raw-str-unterminated.rs | 5 + .../rust/rustc/ui/parser/raw/raw-string-2.rs | 5 + .../rust/rustc/ui/parser/raw/raw-string.rs | 5 + .../parser/recover-assoc-const-constraint.rs | 8 + .../parser/recover-assoc-eq-missing-term.rs | 7 + .../recover-assoc-lifetime-constraint.rs | 7 + .../ui/parser/recover-const-async-fn-ptr.rs | 26 + .../rust/rustc/ui/parser/recover-enum.rs | 12 + .../rust/rustc/ui/parser/recover-enum2.rs | 29 + .../recover-field-extra-angle-brackets.rs | 15 + .../recover-for-loop-parens-around-head.rs | 16 + .../ui/parser/recover-from-bad-variant.rs | 16 + .../rustc/ui/parser/recover-from-homoglyph.rs | 5 + .../parser/recover-labeled-non-block-expr.rs | 6 + .../rustc/ui/parser/recover-missing-semi.rs | 14 + .../ui/parser/recover-quantified-closure.rs | 11 + .../rustc/ui/parser/recover-range-pats.rs | 148 + .../rust/rustc/ui/parser/recover-struct.rs | 8 + .../rust/rustc/ui/parser/recover-tuple-pat.rs | 13 + .../rust/rustc/ui/parser/recover-tuple.rs | 12 + .../ui/parser/recovered-struct-variant.rs | 14 + .../ui/parser/regions-out-of-scope-slice.rs | 12 + .../parser/removed-syntax-closure-lifetime.rs | 3 + .../ui/parser/removed-syntax-enum-newtype.rs | 2 + .../ui/parser/removed-syntax-field-let.rs | 7 + .../parser/removed-syntax-field-semicolon.rs | 7 + .../ui/parser/removed-syntax-fixed-vec.rs | 2 + .../ui/parser/removed-syntax-fn-sigil.rs | 4 + .../rustc/ui/parser/removed-syntax-mode.rs | 5 + .../ui/parser/removed-syntax-mut-vec-expr.rs | 4 + .../ui/parser/removed-syntax-mut-vec-ty.rs | 2 + .../ui/parser/removed-syntax-ptr-lifetime.rs | 2 + .../rustc/ui/parser/removed-syntax-record.rs | 2 + .../ui/parser/removed-syntax-static-fn.rs | 11 + .../ui/parser/removed-syntax-uniq-mut-expr.rs | 4 + .../ui/parser/removed-syntax-uniq-mut-ty.rs | 3 + .../rustc/ui/parser/removed-syntax-with-1.rs | 11 + .../rustc/ui/parser/removed-syntax-with-2.rs | 12 + .../require-parens-for-chained-comparison.rs | 27 + .../rustc/ui/parser/self-in-function-arg.rs | 4 + .../ui/parser/self-param-semantic-fail.rs | 65 + .../ui/parser/self-param-syntactic-pass.rs | 67 + ...several-carriage-returns-in-doc-comment.rs | 11 + .../parser/shebang/issue-71471-ignore-tidy.rs | 3 + .../ui/parser/shebang/multiline-attrib.rs | 8 + .../rustc/ui/parser/shebang/regular-attrib.rs | 6 + .../ui/parser/shebang/shebang-and-attrib.rs | 10 + .../ui/parser/shebang/shebang-comment.rs | 7 + .../ui/parser/shebang/shebang-doc-comment.rs | 4 + .../rustc/ui/parser/shebang/shebang-empty.rs | 5 + .../parser/shebang/shebang-must-start-file.rs | 7 + .../rustc/ui/parser/shebang/shebang-space.rs | 6 + .../rustc/ui/parser/shebang/sneaky-attrib.rs | 17 + .../rustc/ui/parser/shebang/valid-shebang.rs | 7 + .../ui/parser/stmt_expr_attrs_placement.rs | 23 + .../stripped-nested-outline-mod-pass.rs | 14 + .../parser/struct-field-numeric-shorthand.rs | 10 + .../rustc/ui/parser/struct-literal-in-for.rs | 18 + .../rustc/ui/parser/struct-literal-in-if.rs | 18 + .../struct-literal-in-match-discriminant.rs | 14 + .../parser/struct-literal-in-match-guard.rs | 19 + .../ui/parser/struct-literal-in-while.rs | 18 + .../struct-literal-restrictions-in-lamda.rs | 18 + .../ui/parser/tag-variant-disr-non-nullary.rs | 13 + .../trailing-carriage-return-in-string.rs | 15 + .../ui/parser/trailing-plus-in-bounds.rs | 11 + .../ui/parser/trait-bounds-not-on-impl.rs | 8 + ...ait-item-with-defaultness-fail-semantic.rs | 13 + .../trait-item-with-defaultness-pass.rs | 14 + .../ui/parser/trait-object-bad-parens.rs | 17 + .../ui/parser/trait-object-lifetime-parens.rs | 14 + .../parser/trait-object-polytrait-priority.rs | 11 + .../ui/parser/trait-object-trait-parens.rs | 21 + .../ui/parser/trait-plusequal-splitting.rs | 9 + .../rustc/ui/parser/trait-pub-assoc-const.rs | 7 + .../rustc/ui/parser/trait-pub-assoc-ty.rs | 7 + .../rust/rustc/ui/parser/trait-pub-method.rs | 7 + .../parser/type-parameters-in-field-exprs.rs | 18 + .../rustc/ui/parser/unbalanced-doublequote.rs | 7 + .../rust/rustc/ui/parser/unclosed-braces.rs | 23 + .../ui/parser/unclosed-delimiter-in-dep.rs | 7 + .../rustc/ui/parser/unclosed_delim_mod.rs | 9 + .../ui/parser/underscore-suffix-for-float.rs | 5 + .../ui/parser/underscore-suffix-for-string.rs | 9 + .../ui/parser/underscore_item_not_const.rs | 17 + .../rust/rustc/ui/parser/unicode-chars.rs | 6 + .../rustc/ui/parser/unicode-quote-chars.rs | 11 + .../unmatched-delimiter-at-end-of-file.rs | 12 + .../rustc/ui/parser/unsafe-foreign-mod.rs | 10 + .../rust/rustc/ui/parser/unsafe-mod.rs | 10 + gcc/testsuite/rust/rustc/ui/parser/unsized.rs | 8 + .../rust/rustc/ui/parser/unsized2.rs | 8 + .../use-as-where-use-ends-with-mod-sep.rs | 3 + .../rustc/ui/parser/use-ends-with-mod-sep.rs | 2 + .../variadic-ffi-nested-syntactic-fail.rs | 10 + .../variadic-ffi-semantic-restrictions.rs | 77 + .../ui/parser/variadic-ffi-syntactic-pass.rs | 54 + .../rust/rustc/ui/parser/virtual-structs.rs | 11 + .../where-clauses-no-bounds-or-predicates.rs | 16 + .../rust/rustc/ui/parser/where_with_bound.rs | 6 + .../ui/parser/wrong-escape-of-curly-braces.rs | 9 + gcc/testsuite/rust/rustc/ui/partialeq_help.rs | 8 + gcc/testsuite/rust/rustc/ui/path-lookahead.rs | 18 + gcc/testsuite/rust/rustc/ui/path.rs | 9 + .../rust/rustc/ui/pathless-extern-ok.rs | 10 + .../rust/rustc/ui/paths-containing-nul.rs | 51 + .../pattern/bindings-after-at/bind-by-copy.rs | 50 + ...her-can-live-while-the-other-survives-1.rs | 40 + .../bind-by-move-no-subbindings-fun-param.rs | 14 + .../borrowck-move-and-move.rs | 34 + .../borrowck-pat-at-and-box-pass.rs | 86 + .../borrowck-pat-at-and-box.rs | 71 + .../borrowck-pat-by-copy-bindings-in-at.rs | 52 + ...k-pat-by-move-and-ref-inverse-promotion.rs | 10 + .../borrowck-pat-by-move-and-ref-inverse.rs | 83 + .../borrowck-pat-by-move-and-ref.rs | 85 + .../borrowck-pat-ref-both-sides.rs | 48 + .../borrowck-pat-ref-mut-and-ref.rs | 139 + .../borrowck-pat-ref-mut-twice.rs | 112 + .../pattern/bindings-after-at/box-patterns.rs | 37 + .../bindings-after-at/copy-and-move-mixed.rs | 17 + ...lt-binding-modes-both-sides-independent.rs | 50 + .../feature-gate-bindings_after_at.rs | 4 + .../nested-binding-mode-lint.rs | 14 + .../nested-binding-modes-mut.rs | 14 + .../nested-binding-modes-ref.rs | 14 + .../bindings-after-at/nested-patterns.rs | 16 + ...d-type-ascription-syntactically-invalid.rs | 35 + .../or-patterns-box-patterns.rs | 46 + .../or-patterns-slice-patterns.rs | 57 + .../pattern/bindings-after-at/or-patterns.rs | 41 + .../pat-at-same-name-both.rs | 32 + .../bindings-after-at/slice-patterns.rs | 41 + .../wild-before-at-syntactically-rejected.rs | 17 + .../rust/rustc/ui/pattern/const-pat-ice.rs | 12 + .../pattern/deny-irrefutable-let-patterns.rs | 10 + .../ui/pattern/irrefutable-let-patterns.rs | 12 + .../issue-66270-pat-struct-parser-recovery.rs | 15 + .../rust/rustc/ui/pattern/issue-66501.rs | 13 + ...67776-match-same-name-enum-variant-refs.rs | 43 + .../issue-68393-let-pat-assoc-constant.rs | 27 + .../issue-68394-let-pat-runtime-value.rs | 6 + .../ui/pattern/issue-68396-let-float-bug.rs | 8 + ...opaquely-typed-constant-used-in-pattern.rs | 11 + .../rust/rustc/ui/pattern/issue-72565.rs | 9 + .../rust/rustc/ui/pattern/issue-74539.rs | 16 + .../rust/rustc/ui/pattern/issue-74702.rs | 8 + .../rust/rustc/ui/pattern/issue-74954.rs | 8 + .../borrowck-move-ref-pattern-pass.rs | 30 + .../borrowck-move-ref-pattern.rs | 49 + .../by-move-sub-pat-unreachable.rs | 15 + .../pattern/move-ref-patterns/issue-53840.rs | 21 + ...ve-ref-patterns-closure-captures-inside.rs | 121 + ...move-ref-patterns-closure-captures-pass.rs | 29 + .../move-ref-patterns-closure-captures.rs | 33 + ...move-ref-patterns-default-binding-modes.rs | 15 + .../move-ref-patterns-dynamic-semantics.rs | 80 + .../pattern/pat-shadow-in-nested-binding.rs | 7 + .../pattern/pat-struct-field-expr-has-type.rs | 10 + .../rustc/ui/pattern/pat-tuple-bad-type.rs | 16 + .../rustc/ui/pattern/pat-tuple-overfield.rs | 17 + .../ui/pattern/pat-type-err-formal-param.rs | 9 + .../rustc/ui/pattern/pat-type-err-let-stmt.rs | 17 + .../ui/pattern/patkind-litrange-no-expr.rs | 26 + .../pattern/pattern-binding-disambiguation.rs | 58 + .../ui/pattern/pattern-error-continue.rs | 36 + .../ui/pattern/pattern-ident-path-generics.rs | 7 + .../rust/rustc/ui/pattern/pattern-tyvar-2.rs | 7 + .../rust/rustc/ui/pattern/pattern-tyvar.rs | 13 + .../pattern/rest-pat-semantic-disallowed.rs | 84 + .../rustc/ui/pattern/rest-pat-syntactic.rs | 71 + .../usefulness/always-inhabited-union-ref.rs | 33 + .../ui/pattern/usefulness/consts-opaque.rs | 115 + .../usefulness/exhaustive_integer_patterns.rs | 173 + .../usefulness/guards-not-exhaustive.rs | 19 + .../irrefutable-exhaustive-integer-binding.rs | 9 + .../ui/pattern/usefulness/irrefutable-unit.rs | 7 + .../ui/pattern/usefulness/issue-35609.rs | 44 + .../ui/pattern/usefulness/issue-43253.rs | 48 + .../issue-53820-slice-pattern-large-array.rs | 12 + ...413-constants-and-slices-exhaustiveness.rs | 16 + .../issue-71930-type-of-match-scrutinee.rs | 23 + .../usefulness/issue-72476-associated-type.rs | 23 + .../usefulness/issue-78549-ref-pat-and-str.rs | 26 + .../pattern/usefulness/match-arm-statics-2.rs | 63 + .../pattern/usefulness/match-arm-statics.rs | 70 + .../usefulness/match-byte-array-patterns-2.rs | 14 + .../usefulness/match-byte-array-patterns.rs | 56 + .../match-empty-exhaustive_patterns.rs | 94 + .../ui/pattern/usefulness/match-empty.rs | 93 + .../usefulness/match-non-exhaustive.rs | 5 + .../usefulness/match-privately-empty.rs | 22 + .../usefulness/match-range-fail-dominate.rs | 50 + .../ui/pattern/usefulness/match-ref-ice.rs | 17 + .../usefulness/match-slice-patterns.rs | 13 + .../ui/pattern/usefulness/match-vec-fixed.rs | 19 + .../usefulness/match-vec-unreachable.rs | 30 + .../usefulness/nested-exhaustive-match.rs | 15 + .../usefulness/non-exhaustive-defined-here.rs | 73 + .../non-exhaustive-float-range-match.rs | 14 + .../usefulness/non-exhaustive-match-nested.rs | 20 + .../usefulness/non-exhaustive-match.rs | 64 + ...non-exhaustive-pattern-pointer-size-int.rs | 24 + .../non-exhaustive-pattern-witness.rs | 90 + .../usefulness/refutable-pattern-errors.rs | 10 + .../usefulness/refutable-pattern-in-fn-arg.rs | 6 + .../usefulness/slice-pattern-const-2.rs | 32 + .../usefulness/slice-pattern-const-3.rs | 32 + .../pattern/usefulness/slice-pattern-const.rs | 55 + .../slice-patterns-exhaustiveness.rs | 130 + .../usefulness/slice-patterns-irrefutable.rs | 27 + .../usefulness/slice-patterns-reachability.rs | 26 + .../struct-like-enum-nonexhaustive.rs | 13 + .../struct-pattern-match-useless.rs | 16 + .../usefulness/top-level-alternation.rs | 57 + .../usefulness/tuple-struct-nonexhaustive.rs | 10 + gcc/testsuite/rust/rustc/ui/phantom-oibit.rs | 31 + .../rust/rustc/ui/placement-syntax.rs | 7 + ...o-type-err-cause-on-impl-trait-return-2.rs | 18 + ...-to-type-err-cause-on-impl-trait-return.rs | 102 + .../polymorphization/closure_in_upvar/fn.rs | 30 + .../closure_in_upvar/fnmut.rs | 35 + .../closure_in_upvar/fnonce.rs | 35 + .../closure_in_upvar/other.rs | 39 + .../const_parameters/closures.rs | 68 + .../const_parameters/functions.rs | 38 + .../ui/polymorphization/drop_shims/simple.rs | 23 + .../polymorphization/drop_shims/transitive.rs | 28 + .../rustc/ui/polymorphization/generators.rs | 95 + .../rustc/ui/polymorphization/issue-74636.rs | 17 + .../rustc/ui/polymorphization/lifetimes.rs | 26 + .../polymorphization/normalized_sig_types.rs | 27 + .../rustc/ui/polymorphization/predicates.rs | 90 + .../polymorphization/promoted-function-1.rs | 13 + .../polymorphization/promoted-function-2.rs | 17 + .../polymorphization/promoted-function-3.rs | 15 + .../ui/polymorphization/promoted-function.rs | 16 + .../ui/polymorphization/symbol-ambiguity.rs | 23 + .../too-many-generic-params.rs | 86 + .../type_parameters/closures.rs | 162 + .../type_parameters/functions.rs | 97 + .../rustc/ui/polymorphization/unsized_cast.rs | 31 + gcc/testsuite/rust/rustc/ui/pptypedef.rs | 12 + .../rustc/ui/precise_pointer_size_matching.rs | 34 + gcc/testsuite/rust/rustc/ui/prim-with-args.rs | 28 + .../rust/rustc/ui/primitive-binop-lhs-mut.rs | 7 + .../rust/rustc/ui/print-fuel/print-fuel.rs | 14 + .../rustc/ui/print-stdout-eprint-stderr.rs | 34 + .../rustc/ui/print_type_sizes/anonymous.rs | 24 + .../rustc/ui/print_type_sizes/generics.rs | 72 + .../ui/print_type_sizes/multiple_types.rs | 24 + .../ui/print_type_sizes/niche-filling.rs | 94 + .../ui/print_type_sizes/no_duplicates.rs | 24 + .../rust/rustc/ui/print_type_sizes/packed.rs | 70 + .../rust/rustc/ui/print_type_sizes/padding.rs | 35 + .../rustc/ui/print_type_sizes/repr-align.rs | 39 + .../rustc/ui/print_type_sizes/repr_int_c.rs | 26 + .../rustc/ui/print_type_sizes/uninhabited.rs | 16 + .../rustc/ui/print_type_sizes/variants.rs | 27 + .../ui/print_type_sizes/zero-sized-fields.rs | 48 + .../rust/rustc/ui/priv-in-bad-locations.rs | 18 + .../associated-item-privacy-inherent.rs | 113 + .../privacy/associated-item-privacy-trait.rs | 137 + .../associated-item-privacy-type-binding.rs | 65 + .../rustc/ui/privacy/auxiliary/cci_class.rs | 15 + .../rustc/ui/privacy/auxiliary/cci_class_5.rs | 18 + .../ui/privacy/auxiliary/issue-57264-1.rs | 10 + .../ui/privacy/auxiliary/issue-57264-2.rs | 11 + .../ui/privacy/auxiliary/priv-impl-prim-ty.rs | 10 + .../ui/privacy/auxiliary/privacy_reexport.rs | 7 + .../privacy/auxiliary/privacy_tuple_struct.rs | 5 + .../auxiliary/private-inferred-type.rs | 37 + .../privacy/auxiliary/pub_use_mods_xcrate.rs | 11 + .../ui/privacy/auxiliary/pub_use_xcrate1.rs | 4 + .../ui/privacy/auxiliary/pub_use_xcrate2.rs | 4 + .../rust/rustc/ui/privacy/decl-macro.rs | 10 + .../rust/rustc/ui/privacy/issue-57264-1.rs | 9 + .../rust/rustc/ui/privacy/issue-57264-2.rs | 11 + .../issue-75062-fieldless-tuple-struct.rs | 11 + .../ui/privacy/legacy-ctor-visibility.rs | 16 + .../rustc/ui/privacy/priv-impl-prim-ty.rs | 12 + .../rust/rustc/ui/privacy/privacy-in-paths.rs | 31 + .../rust/rustc/ui/privacy/privacy-ns.rs | 115 + .../rust/rustc/ui/privacy/privacy-ns1.rs | 57 + .../rust/rustc/ui/privacy/privacy-ns2.rs | 82 + .../rust/rustc/ui/privacy/privacy-reexport.rs | 14 + .../rust/rustc/ui/privacy/privacy-sanity.rs | 83 + .../rust/rustc/ui/privacy/privacy-ufcs.rs | 14 + .../rust/rustc/ui/privacy/privacy1-rpass.rs | 24 + .../rust/rustc/ui/privacy/privacy1.rs | 177 + .../rust/rustc/ui/privacy/privacy2.rs | 28 + .../rust/rustc/ui/privacy/privacy3.rs | 28 + .../rust/rustc/ui/privacy/privacy4.rs | 26 + .../rust/rustc/ui/privacy/privacy5.rs | 129 + .../rustc/ui/privacy/private-class-field.rs | 27 + .../rustc/ui/privacy/private-impl-method.rs | 22 + .../ui/privacy/private-in-public-assoc-ty.rs | 53 + .../ui/privacy/private-in-public-expr-pat.rs | 14 + .../privacy/private-in-public-ill-formed.rs | 38 + .../ui/privacy/private-in-public-lint.rs | 20 + .../private-in-public-non-principal-2.rs | 15 + .../private-in-public-non-principal.rs | 22 + ...private-in-public-type-alias-impl-trait.rs | 26 + .../ui/privacy/private-in-public-warn.rs | 284 + .../rustc/ui/privacy/private-in-public.rs | 149 + .../ui/privacy/private-inferred-type-1.rs | 19 + .../ui/privacy/private-inferred-type-2.rs | 20 + .../ui/privacy/private-inferred-type-3.rs | 18 + .../rustc/ui/privacy/private-inferred-type.rs | 134 + .../rustc/ui/privacy/private-item-simple.rs | 8 + .../ui/privacy/private-method-cross-crate.rs | 9 + .../ui/privacy/private-method-inherited.rs | 15 + .../rustc/ui/privacy/private-method-rpass.rs | 35 + .../rust/rustc/ui/privacy/private-method.rs | 24 + .../private-struct-field-cross-crate.rs | 10 + .../ui/privacy/private-struct-field-ctor.rs | 10 + .../privacy/private-struct-field-pattern.rs | 18 + .../rustc/ui/privacy/private-struct-field.rs | 15 + .../ui/privacy/private-type-in-interface.rs | 31 + .../ui/privacy/private-variant-reexport.rs | 20 + .../rustc/ui/privacy/pub-extern-privacy.rs | 19 + .../pub-priv-dep/auxiliary/priv_dep.rs | 3 + .../privacy/pub-priv-dep/auxiliary/pub_dep.rs | 2 + .../ui/privacy/pub-priv-dep/pub-priv1.rs | 44 + .../rustc/ui/privacy/pub-priv-dep/std-pub.rs | 13 + .../rust/rustc/ui/privacy/pub-use-xcrate.rs | 16 + .../ui/privacy/pub_use_mods_xcrate_exe.rs | 12 + .../restricted/auxiliary/pub_restricted.rs | 17 + .../restricted/lookup-ignores-private.rs | 35 + .../privacy/restricted/private-in-public.rs | 14 + .../ui/privacy/restricted/relative-2018.rs | 14 + .../restricted/struct-literal-field.rs | 20 + .../rust/rustc/ui/privacy/restricted/test.rs | 53 + .../rustc/ui/privacy/union-field-privacy-1.rs | 18 + .../rustc/ui/privacy/union-field-privacy-2.rs | 16 + .../rust/rustc/ui/proc-macro/add-impl.rs | 15 + .../ambiguous-builtin-attrs-test.rs | 21 + .../ui/proc-macro/ambiguous-builtin-attrs.rs | 32 + .../rust/rustc/ui/proc-macro/append-impl.rs | 23 + .../rust/rustc/ui/proc-macro/attr-args.rs | 14 + .../rust/rustc/ui/proc-macro/attr-cfg.rs | 28 + .../rustc/ui/proc-macro/attr-invalid-exprs.rs | 29 + .../rust/rustc/ui/proc-macro/attr-on-trait.rs | 20 + .../ui/proc-macro/attr-stmt-expr-rpass.rs | 37 + .../rustc/ui/proc-macro/attr-stmt-expr.rs | 28 + .../proc-macro/attribute-order-restricted.rs | 15 + .../proc-macro/attribute-spans-preserved.rs | 11 + .../ui/proc-macro/attribute-with-error.rs | 43 + .../rust/rustc/ui/proc-macro/attribute.rs | 74 + .../ui/proc-macro/attributes-included.rs | 23 + .../proc-macro/attributes-on-definitions.rs | 13 + .../proc-macro/attributes-on-modules-fail.rs | 47 + .../ui/proc-macro/attributes-on-modules.rs | 20 + .../rustc/ui/proc-macro/auxiliary/add-impl.rs | 22 + .../ui/proc-macro/auxiliary/append-impl.rs | 17 + .../ui/proc-macro/auxiliary/attr-args.rs | 29 + .../rustc/ui/proc-macro/auxiliary/attr-cfg.rs | 22 + .../ui/proc-macro/auxiliary/attr-on-trait.rs | 16 + .../auxiliary/attr-stmt-expr-rpass.rs | 52 + .../ui/proc-macro/auxiliary/attr-stmt-expr.rs | 50 + .../auxiliary/attribute-spans-preserved.rs | 36 + .../auxiliary/attributes-included.rs | 151 + .../auxiliary/attributes-on-definitions.rs | 24 + .../ui/proc-macro/auxiliary/bang-macro.rs | 18 + .../proc-macro/auxiliary/bang_proc_macro2.rs | 14 + .../ui/proc-macro/auxiliary/builtin-attrs.rs | 28 + .../ui/proc-macro/auxiliary/call-site.rs | 28 + .../auxiliary/count_compound_ops.rs | 33 + .../auxiliary/custom-attr-only-one-derive.rs | 19 + .../rustc/ui/proc-macro/auxiliary/derive-a.rs | 16 + .../ui/proc-macro/auxiliary/derive-atob.rs | 16 + .../proc-macro/auxiliary/derive-attr-cfg.rs | 15 + .../ui/proc-macro/auxiliary/derive-b-rpass.rs | 18 + .../rustc/ui/proc-macro/auxiliary/derive-b.rs | 14 + .../ui/proc-macro/auxiliary/derive-bad.rs | 14 + .../ui/proc-macro/auxiliary/derive-clona.rs | 14 + .../ui/proc-macro/auxiliary/derive-ctod.rs | 16 + .../ui/proc-macro/auxiliary/derive-foo.rs | 14 + .../auxiliary/derive-helper-shadowed-2.rs | 3 + .../auxiliary/derive-helper-shadowing-2.rs | 13 + .../auxiliary/derive-helper-shadowing.rs | 16 + .../ui/proc-macro/auxiliary/derive-nothing.rs | 14 + .../auxiliary/derive-same-struct.rs | 22 + .../proc-macro/auxiliary/derive-two-attrs.rs | 14 + .../ui/proc-macro/auxiliary/derive-union.rs | 19 + .../proc-macro/auxiliary/derive-unstable-2.rs | 18 + .../proc-macro/auxiliary/derive-unstable.rs | 15 + .../auxiliary/dollar-crate-external.rs | 23 + .../rustc/ui/proc-macro/auxiliary/double.rs | 17 + .../ui/proc-macro/auxiliary/duplicate.rs | 33 + .../auxiliary/edition-imports-2015.rs | 21 + .../ui/proc-macro/auxiliary/empty-crate.rs | 6 + .../auxiliary/expand-with-a-macro.rs | 23 + .../auxiliary/external-crate-var.rs | 41 + .../ui/proc-macro/auxiliary/first-second.rs | 21 + .../auxiliary/gen-lifetime-token.rs | 26 + .../auxiliary/gen-macro-rules-hygiene.rs | 24 + .../proc-macro/auxiliary/gen-macro-rules.rs | 13 + .../auxiliary/generate-dollar-ident.rs | 17 + .../ui/proc-macro/auxiliary/generate-mod.rs | 59 + .../proc-macro/auxiliary/hygiene_example.rs | 8 + .../auxiliary/hygiene_example_codegen.rs | 28 + .../auxiliary/invalid-punct-ident.rs | 29 + .../ui/proc-macro/auxiliary/is-available.rs | 15 + .../ui/proc-macro/auxiliary/issue-38586.rs | 12 + .../ui/proc-macro/auxiliary/issue-39889.rs | 18 + .../ui/proc-macro/auxiliary/issue-42708.rs | 19 + .../ui/proc-macro/auxiliary/issue-50061.rs | 13 + .../ui/proc-macro/auxiliary/issue-50493.rs | 22 + .../ui/proc-macro/auxiliary/issue-59191.rs | 17 + .../proc-macro/auxiliary/lifetimes-rpass.rs | 27 + .../ui/proc-macro/auxiliary/lifetimes.rs | 21 + .../proc-macro/auxiliary/macro-only-syntax.rs | 90 + .../ui/proc-macro/auxiliary/make-macro.rs | 19 + .../ui/proc-macro/auxiliary/meta-delim.rs | 13 + .../ui/proc-macro/auxiliary/meta-macro.rs | 16 + .../proc-macro/auxiliary/mixed-site-span.rs | 41 + .../ui/proc-macro/auxiliary/modify-ast.rs | 48 + .../ui/proc-macro/auxiliary/multispan.rs | 38 + .../ui/proc-macro/auxiliary/negative-token.rs | 19 + .../auxiliary/nested-macro-rules.rs | 16 + .../ui/proc-macro/auxiliary/not-joint.rs | 31 + .../auxiliary/parent-source-spans.rs | 44 + .../ui/proc-macro/auxiliary/raw-ident.rs | 36 + .../ui/proc-macro/auxiliary/recollect.rs | 13 + .../auxiliary/resolved-located-at.rs | 32 + .../ui/proc-macro/auxiliary/span-api-tests.rs | 46 + .../proc-macro/auxiliary/span-test-macros.rs | 10 + .../rustc/ui/proc-macro/auxiliary/subspan.rs | 39 + .../ui/proc-macro/auxiliary/test-macros.rs | 126 + .../ui/proc-macro/auxiliary/three-equals.rs | 50 + .../ui/proc-macro/auxiliary/weird-hygiene.rs | 49 + .../rust/rustc/ui/proc-macro/bang-macro.rs | 10 + .../rustc/ui/proc-macro/break-token-spans.rs | 17 + .../rust/rustc/ui/proc-macro/call-site.rs | 11 + .../proc-macro/capture-macro-rules-invoke.rs | 58 + .../rustc/ui/proc-macro/count_compound_ops.rs | 10 + .../rust/rustc/ui/proc-macro/crate-var.rs | 62 + .../rust/rustc/ui/proc-macro/crt-static.rs | 18 + .../proc-macro/custom-attr-only-one-derive.rs | 17 + .../debug/auxiliary/macro-dump-debug.rs | 16 + .../proc-macro/debug/dump-debug-span-debug.rs | 42 + .../rustc/ui/proc-macro/debug/dump-debug.rs | 41 + .../rust/rustc/ui/proc-macro/define-two.rs | 19 + .../rustc/ui/proc-macro/derive-attr-cfg.rs | 18 + .../rust/rustc/ui/proc-macro/derive-b.rs | 20 + .../rust/rustc/ui/proc-macro/derive-bad.rs | 12 + .../ui/proc-macro/derive-helper-configured.rs | 19 + .../ui/proc-macro/derive-helper-shadowed.rs | 17 + .../proc-macro/derive-helper-shadowing-2.rs | 17 + .../ui/proc-macro/derive-helper-shadowing.rs | 55 + .../rust/rustc/ui/proc-macro/derive-in-mod.rs | 14 + .../rustc/ui/proc-macro/derive-same-struct.rs | 16 + .../rustc/ui/proc-macro/derive-still-gated.rs | 10 + .../rust/rustc/ui/proc-macro/derive-test.rs | 23 + .../rustc/ui/proc-macro/derive-two-attrs.rs | 16 + .../rust/rustc/ui/proc-macro/derive-union.rs | 18 + .../ui/proc-macro/disappearing-resolution.rs | 23 + .../ui/proc-macro/doc-comment-preserved.rs | 25 + .../ui/proc-macro/dollar-crate-issue-57089.rs | 28 + .../ui/proc-macro/dollar-crate-issue-62325.rs | 27 + .../rust/rustc/ui/proc-macro/dollar-crate.rs | 41 + .../ui/proc-macro/edition-imports-2018.rs | 25 + .../rust/rustc/ui/proc-macro/empty-crate.rs | 10 + .../rustc/ui/proc-macro/empty-where-clause.rs | 19 + .../ui/proc-macro/expand-to-unstable-2.rs | 18 + .../rustc/ui/proc-macro/expand-to-unstable.rs | 15 + .../ui/proc-macro/expand-with-a-macro.rs | 21 + .../rust/rustc/ui/proc-macro/export-macro.rs | 12 + .../rust/rustc/ui/proc-macro/exports.rs | 16 + .../extern-prelude-extern-crate-proc-macro.rs | 8 + .../rustc/ui/proc-macro/gen-lifetime-token.rs | 12 + .../ui/proc-macro/gen-macro-rules-hygiene.rs | 24 + .../rustc/ui/proc-macro/gen-macro-rules.rs | 14 + .../ui/proc-macro/generate-dollar-ident.rs | 19 + .../rust/rustc/ui/proc-macro/generate-mod.rs | 34 + .../actix-web-2.0.0/src/extract.rs | 8 + .../actix-web/src/extract.rs | 8 + .../actori-web-2.0.0/src/extract.rs | 8 + .../actori-web/src/extract.rs | 8 + .../auxiliary/group-compat-hack.rs | 14 + .../group-compat-hack/group-compat-hack.rs | 78 + .../js-sys-0.3.17/src/lib.rs | 8 + .../group-compat-hack/js-sys/src/lib.rs | 8 + .../time-macros-impl-0.1.0/src/lib.rs | 8 + .../time-macros-impl/src/lib.rs | 8 + .../helper-attr-blocked-by-import-ambig.rs | 12 + .../helper-attr-blocked-by-import.rs | 29 + .../rustc/ui/proc-macro/hygiene_example.rs | 17 + .../illegal-proc-macro-derive-use.rs | 16 + .../rust/rustc/ui/proc-macro/import.rs | 9 + .../rustc/ui/proc-macro/input-interpolated.rs | 30 + .../rustc/ui/proc-macro/invalid-attributes.rs | 27 + .../ui/proc-macro/invalid-punct-ident-1.rs | 22 + .../ui/proc-macro/invalid-punct-ident-2.rs | 22 + .../ui/proc-macro/invalid-punct-ident-3.rs | 22 + .../ui/proc-macro/invalid-punct-ident-4.rs | 13 + .../rust/rustc/ui/proc-macro/is-available.rs | 18 + .../rust/rustc/ui/proc-macro/issue-36935.rs | 14 + .../rust/rustc/ui/proc-macro/issue-37788.rs | 10 + .../rust/rustc/ui/proc-macro/issue-38586.rs | 10 + .../rust/rustc/ui/proc-macro/issue-39889.rs | 13 + .../rust/rustc/ui/proc-macro/issue-41211.rs | 17 + .../rust/rustc/ui/proc-macro/issue-42708.rs | 27 + .../rust/rustc/ui/proc-macro/issue-50061.rs | 24 + .../rust/rustc/ui/proc-macro/issue-50493.rs | 14 + .../rust/rustc/ui/proc-macro/issue-53481.rs | 23 + .../issue-59191-replace-root-with-fn.rs | 9 + .../ui/proc-macro/issue-75734-pp-paren.rs | 27 + .../ui/proc-macro/issue-75930-derive-cfg.rs | 67 + .../issue-76182-leading-vert-pat.rs | 17 + .../issue-78675-captured-inner-attrs.rs | 33 + .../rust/rustc/ui/proc-macro/item-error.rs | 16 + .../rustc/ui/proc-macro/keep-expr-tokens.rs | 16 + .../rustc/ui/proc-macro/lifetimes-rpass.rs | 27 + .../rust/rustc/ui/proc-macro/lifetimes.rs | 10 + .../ui/proc-macro/lints_in_proc_macros.rs | 15 + .../ui/proc-macro/load-panic-backtrace.rs | 25 + .../rust/rustc/ui/proc-macro/load-panic.rs | 11 + .../rust/rustc/ui/proc-macro/load-two.rs | 24 + .../rustc/ui/proc-macro/macro-brackets.rs | 15 + .../proc-macro/macro-crate-multi-decorator.rs | 42 + .../proc-macro/macro-namespace-reserved-2.rs | 58 + .../ui/proc-macro/macro-namespace-reserved.rs | 39 + .../rustc/ui/proc-macro/macro-rules-derive.rs | 20 + .../rustc/ui/proc-macro/macro-use-attr.rs | 13 + .../rustc/ui/proc-macro/macro-use-bang.rs | 10 + .../ui/proc-macro/macros-in-extern-derive.rs | 7 + .../rustc/ui/proc-macro/macros-in-extern.rs | 23 + .../rustc/ui/proc-macro/macros-in-type.rs | 12 + .../rust/rustc/ui/proc-macro/meta-delim.rs | 13 + .../rustc/ui/proc-macro/meta-macro-hygiene.rs | 31 + .../rust/rustc/ui/proc-macro/meta-macro.rs | 15 + .../rustc/ui/proc-macro/mixed-site-span.rs | 25 + .../rust/rustc/ui/proc-macro/modify-ast.rs | 27 + .../rust/rustc/ui/proc-macro/module.rs | 2 + .../rust/rustc/ui/proc-macro/multispan.rs | 26 + .../rustc/ui/proc-macro/negative-token.rs | 12 + .../rustc/ui/proc-macro/nested-item-spans.rs | 24 + .../rustc/ui/proc-macro/nested-macro-rules.rs | 24 + .../proc-macro/nested-nonterminal-tokens.rs | 27 + .../rustc/ui/proc-macro/no-macro-use-attr.rs | 11 + .../rustc/ui/proc-macro/no-missing-docs.rs | 17 + .../rustc/ui/proc-macro/nodelim-groups.rs | 23 + .../rust/rustc/ui/proc-macro/non-root.rs | 16 + .../ui/proc-macro/nonterminal-expansion.rs | 38 + .../proc-macro/nonterminal-token-hygiene.rs | 34 + .../rust/rustc/ui/proc-macro/not-joint.rs | 25 + .../rustc/ui/proc-macro/out-of-line-mod.rs | 14 + .../rust/rustc/ui/proc-macro/outer/inner.rs | 2 + .../ui/proc-macro/parent-source-spans.rs | 54 + .../ui/proc-macro/proc-macro-attributes.rs | 15 + .../proc-macro/proc-macro-deprecated-attr.rs | 17 + .../rustc/ui/proc-macro/proc-macro-gates.rs | 49 + .../rustc/ui/proc-macro/proc-macro-gates2.rs | 25 + .../rustc/ui/proc-macro/pub-at-crate-root.rs | 23 + .../rust/rustc/ui/proc-macro/raw-ident.rs | 17 + .../ui/proc-macro/reserved-macro-names.rs | 26 + .../rust/rustc/ui/proc-macro/resolve-error.rs | 63 + .../ui/proc-macro/resolved-located-at.rs | 11 + .../rust/rustc/ui/proc-macro/shadow.rs | 9 + .../rust/rustc/ui/proc-macro/signature.rs | 14 + .../rust/rustc/ui/proc-macro/smoke.rs | 21 + .../rustc/ui/proc-macro/span-api-tests.rs | 62 + .../rustc/ui/proc-macro/span-preservation.rs | 58 + .../rustc/ui/proc-macro/struct-field-macro.rs | 19 + .../rust/rustc/ui/proc-macro/subspan.rs | 27 + .../rust/rustc/ui/proc-macro/three-equals.rs | 26 + .../rust/rustc/ui/proc-macro/trailing-plus.rs | 15 + .../rustc/ui/proc-macro/trait-fn-args-2015.rs | 15 + .../rustc/ui/proc-macro/two-crate-types-1.rs | 8 + .../rustc/ui/proc-macro/two-crate-types-2.rs | 4 + .../rustc/ui/proc-macro/unsafe-foreign-mod.rs | 15 + .../rust/rustc/ui/proc-macro/unsafe-mod.rs | 14 + .../rustc/ui/proc-macro/visibility-path.rs | 26 + .../rust/rustc/ui/proc-macro/weird-hygiene.rs | 47 + gcc/testsuite/rust/rustc/ui/proc_macro.rs | 38 + .../process-termination-blocking-io.rs | 20 + .../process-termination-simple.rs | 14 + .../rust/rustc/ui/process/process-envs.rs | 55 + .../rust/rustc/ui/process/process-exit.rs | 28 + .../ui/process/process-remove-from-env.rs | 49 + .../rust/rustc/ui/process/process-sigpipe.rs | 38 + .../ui/process/process-spawn-nonexistent.rs | 16 + .../process-spawn-with-unicode-params.rs | 78 + .../process/process-status-inherits-stdin.rs | 37 + .../rust/rustc/ui/process/tls-exit-status.rs | 13 + .../rustc/ui/project-cache-issue-31849.rs | 66 + .../rustc/ui/project-cache-issue-37154.rs | 22 + .../rustc/ui/project-defer-unification.rs | 105 + .../rust/rustc/ui/ptr-coercion-rpass.rs | 31 + gcc/testsuite/rust/rustc/ui/ptr-coercion.rs | 24 + ...174-restricted-type-in-public-interface.rs | 29 + .../rust/rustc/ui/pub/pub-ident-fn-2.rs | 11 + .../rust/rustc/ui/pub/pub-ident-fn-3.rs | 9 + .../rustc/ui/pub/pub-ident-fn-or-struct-2.rs | 5 + .../rustc/ui/pub/pub-ident-fn-or-struct.rs | 5 + .../ui/pub/pub-ident-fn-with-lifetime-2.rs | 7 + .../ui/pub/pub-ident-fn-with-lifetime.rs | 9 + .../rust/rustc/ui/pub/pub-ident-fn.rs | 9 + .../ui/pub/pub-ident-struct-with-lifetime.rs | 5 + .../rust/rustc/ui/pub/pub-ident-struct.rs | 7 + .../pub/pub-ident-with-lifetime-incomplete.rs | 6 + .../ui/pub/pub-reexport-priv-extern-crate.rs | 25 + .../rustc/ui/pub/pub-restricted-error-fn.rs | 3 + .../rust/rustc/ui/pub/pub-restricted-error.rs | 10 + .../rustc/ui/pub/pub-restricted-non-path.rs | 6 + .../rust/rustc/ui/pub/pub-restricted.rs | 34 + gcc/testsuite/rust/rustc/ui/pure-sum.rs | 54 + gcc/testsuite/rust/rustc/ui/purity-infer.rs | 7 + .../ui/qualified/qualified-path-params-2.rs | 22 + .../ui/qualified/qualified-path-params.rs | 26 + .../rust/rustc/ui/question-mark-type-infer.rs | 18 + .../rust/rustc/ui/range-type-infer.rs | 23 + .../rustc/ui/range/issue-54505-no-literals.rs | 76 + .../rust/rustc/ui/range/issue-54505-no-std.rs | 57 + .../rust/rustc/ui/range/issue-54505.rs | 44 + .../issue-73553-misinterp-range-literal.rs | 17 + gcc/testsuite/rust/rustc/ui/range/range-1.rs | 17 + .../range-inclusive-pattern-precedence.rs | 21 + .../range-inclusive-pattern-precedence2.rs | 20 + .../rust/rustc/ui/range/range_traits-1.rs | 50 + .../rust/rustc/ui/range/range_traits-2.rs | 7 + .../rust/rustc/ui/range/range_traits-3.rs | 7 + .../rust/rustc/ui/range/range_traits-4.rs | 10 + .../rust/rustc/ui/range/range_traits-5.rs | 10 + .../rust/rustc/ui/range/range_traits-6.rs | 7 + .../rust/rustc/ui/range/range_traits-7.rs | 10 + .../rust/rustc/ui/range_inclusive.rs | 122 + .../rust/rustc/ui/range_inclusive_gate.rs | 15 + .../rust/rustc/ui/ranges-precedence.rs | 53 + gcc/testsuite/rust/rustc/ui/raw-fat-ptr.rs | 119 + .../rustc/ui/raw-ref-op/feature-raw-ref-op.rs | 22 + .../rust/rustc/ui/raw-ref-op/raw-ref-op.rs | 14 + .../rustc/ui/raw-ref-op/raw-ref-temp-deref.rs | 25 + .../rust/rustc/ui/raw-ref-op/raw-ref-temp.rs | 32 + .../rustc/ui/raw-ref-op/unusual_locations.rs | 23 + gcc/testsuite/rust/rustc/ui/raw-str.rs | Bin 0 -> 848 bytes .../rust/rustc/ui/rcvr-borrowed-to-region.rs | 30 + .../rustc/ui/reachable-unnameable-items.rs | 32 + .../ui/reachable-unnameable-type-alias.rs | 17 + .../auxiliary/unreachable_variant.rs | 6 + .../rust/rustc/ui/reachable/expr_add.rs | 19 + .../rust/rustc/ui/reachable/expr_again.rs | 12 + .../rust/rustc/ui/reachable/expr_andand.rs | 14 + .../rust/rustc/ui/reachable/expr_array.rs | 18 + .../rust/rustc/ui/reachable/expr_assign.rs | 30 + .../rust/rustc/ui/reachable/expr_block.rs | 32 + .../rust/rustc/ui/reachable/expr_box.rs | 9 + .../rust/rustc/ui/reachable/expr_call.rs | 22 + .../rust/rustc/ui/reachable/expr_cast.rs | 13 + .../rust/rustc/ui/reachable/expr_if.rs | 32 + .../rust/rustc/ui/reachable/expr_loop.rs | 37 + .../rust/rustc/ui/reachable/expr_match.rs | 40 + .../rust/rustc/ui/reachable/expr_method.rs | 25 + .../rust/rustc/ui/reachable/expr_oror.rs | 13 + .../rust/rustc/ui/reachable/expr_repeat.rs | 13 + .../rust/rustc/ui/reachable/expr_return.rs | 14 + .../ui/reachable/expr_return_in_macro.rs | 16 + .../rust/rustc/ui/reachable/expr_struct.rs | 33 + .../rust/rustc/ui/reachable/expr_tup.rs | 18 + .../rust/rustc/ui/reachable/expr_type.rs | 13 + .../rust/rustc/ui/reachable/expr_unary.rs | 13 + .../rust/rustc/ui/reachable/expr_while.rs | 30 + .../rustc/ui/reachable/unreachable-arm.rs | 15 + .../rustc/ui/reachable/unreachable-code.rs | 9 + .../rustc/ui/reachable/unreachable-in-call.rs | 23 + .../ui/reachable/unreachable-loop-patterns.rs | 22 + .../ui/reachable/unreachable-try-pattern.rs | 42 + .../rustc/ui/reachable/unreachable-variant.rs | 8 + .../ui/reachable/unwarned-match-on-never.rs | 25 + gcc/testsuite/rust/rustc/ui/readalias.rs | 13 + gcc/testsuite/rust/rustc/ui/realloc-16687.rs | 189 + .../rust/rustc/ui/reassign-ref-mut.rs | 17 + .../auxiliary/recursive_reexports.rs | 4 + .../issue-26548-recursion-via-normalize.rs | 19 + ...ssue-38591-non-regular-dropck-recursion.rs | 21 + .../rust/rustc/ui/recursion/recursion.rs | 26 + .../rust/rustc/ui/recursion/recursive-enum.rs | 5 + .../rustc/ui/recursion/recursive-reexports.rs | 8 + .../ui/recursion/recursive-requirements.rs | 20 + .../recursion/recursive-static-definition.rs | 5 + .../recursive-types-are-not-uninhabited.rs | 14 + .../rust/rustc/ui/recursion_limit/empty.rs | 7 + .../rustc/ui/recursion_limit/invalid_digit.rs | 7 + .../rust/rustc/ui/recursion_limit/overflow.rs | 8 + .../rust/rustc/ui/recursion_limit/zero.rs | 13 + .../rustc/ui/reexport-should-still-link.rs | 11 + gcc/testsuite/rust/rustc/ui/reexport-star.rs | 17 + .../rustc/ui/reexport-test-harness-main.rs | 12 + gcc/testsuite/rust/rustc/ui/ref-suggestion.rs | 18 + .../ui/refer-to-other-statics-by-value.rs | 9 + ...regions-fn-subtyping-return-static-fail.rs | 52 + .../auxiliary/rbmtp_cross_crate_lib.rs | 33 + ...6537-closure-uses-region-from-container.rs | 68 + .../regions/issue-72051-member-region-hang.rs | 8 + .../rust/rustc/ui/regions/issue-78262.rs | 15 + .../region-borrow-params-issue-29793-big.rs | 75 + .../region-borrow-params-issue-29793-small.rs | 213 + ...gion-bound-extra-bound-in-inherent-impl.rs | 17 + .../region-bound-on-closure-outlives-call.rs | 7 + ...ion-bound-same-bounds-in-trait-and-impl.rs | 18 + ...n-bounds-on-objects-and-type-parameters.rs | 37 + ...region-invariant-static-error-reporting.rs | 23 + ...ion-lifetime-bounds-on-fns-where-clause.rs | 30 + ...ple-lifetime-bounds-on-fns-where-clause.rs | 32 + .../ui/regions/region-object-lifetime-1.rs | 19 + .../ui/regions/region-object-lifetime-2.rs | 14 + .../ui/regions/region-object-lifetime-3.rs | 19 + .../ui/regions/region-object-lifetime-4.rs | 16 + .../ui/regions/region-object-lifetime-5.rs | 15 + .../region-object-lifetime-in-coercion.rs | 31 + .../rustc/ui/regions/regions-addr-of-arg.rs | 18 + .../regions-addr-of-interior-of-unique-box.rs | 24 + .../rustc/ui/regions/regions-addr-of-ret.rs | 10 + .../rustc/ui/regions/regions-addr-of-self.rs | 28 + .../ui/regions/regions-addr-of-upvar-self.rs | 18 + .../ui/regions/regions-adjusted-lvalue-op.rs | 17 + ...c-type-in-supertrait-outlives-container.rs | 46 + ...ssoc-type-region-bound-in-trait-not-met.rs | 25 + .../regions-assoc-type-region-bound.rs | 23 + ...ssoc-type-static-bound-in-trait-not-met.rs | 20 + .../regions-assoc-type-static-bound.rs | 20 + .../rustc/ui/regions/regions-borrow-at.rs | 14 + .../ui/regions/regions-borrow-evec-fixed.rs | 11 + .../ui/regions/regions-borrow-evec-uniq.rs | 17 + .../rustc/ui/regions/regions-borrow-uniq.rs | 13 + .../rust/rustc/ui/regions/regions-bot.rs | 12 + .../regions-bound-lists-feature-gate-2.rs | 15 + .../regions-bound-lists-feature-gate.rs | 19 + ...gions-bounded-by-trait-requiring-static.rs | 64 + ...nded-method-type-parameters-cross-crate.rs | 24 + ...nded-method-type-parameters-trait-bound.rs | 29 + .../regions-bounded-method-type-parameters.rs | 17 + .../rust/rustc/ui/regions/regions-bounds.rs | 17 + ...gions-close-associated-type-into-object.rs | 72 + .../regions-close-object-into-object-1.rs | 16 + .../regions-close-object-into-object-2.rs | 14 + .../regions-close-object-into-object-3.rs | 15 + .../regions-close-object-into-object-4.rs | 14 + .../regions-close-object-into-object-5.rs | 27 + .../regions-close-over-type-parameter-1.rs | 26 + ...ions-close-over-type-parameter-multiple.rs | 25 + ...-close-over-type-parameter-successfully.rs | 24 + .../regions-close-param-into-object.rs | 28 + .../rustc/ui/regions/regions-copy-closure.rs | 22 + .../ui/regions/regions-creating-enums.rs | 34 + .../ui/regions/regions-creating-enums2.rs | 18 + .../ui/regions/regions-creating-enums3.rs | 12 + .../ui/regions/regions-creating-enums4.rs | 12 + .../ui/regions/regions-creating-enums5.rs | 18 + .../ui/regions/regions-debruijn-of-object.rs | 23 + .../ui/regions/regions-dependent-addr-of.rs | 114 + .../ui/regions/regions-dependent-autofn.rs | 16 + .../ui/regions/regions-dependent-autoslice.rs | 15 + .../ui/regions/regions-dependent-let-ref.rs | 13 + .../regions-early-bound-error-method.rs | 27 + .../ui/regions/regions-early-bound-error.rs | 25 + ...egions-early-bound-lifetime-in-assoc-fn.rs | 36 + .../regions-early-bound-trait-param.rs | 135 + ...egions-early-bound-used-in-bound-method.rs | 31 + .../regions-early-bound-used-in-bound.rs | 29 + .../regions-early-bound-used-in-type-param.rs | 29 + .../rustc/ui/regions/regions-enum-not-wf.rs | 42 + .../regions/regions-escape-into-other-fn.rs | 11 + .../rustc/ui/regions/regions-escape-method.rs | 17 + .../regions-escape-via-trait-or-not.rs | 23 + .../rustc/ui/regions/regions-expl-self.rs | 16 + .../ui/regions/regions-fn-subtyping-2.rs | 21 + .../regions-fn-subtyping-return-static.rs | 49 + .../rustc/ui/regions/regions-fn-subtyping.rs | 31 + .../regions-free-region-ordering-callee-4.rs | 12 + .../regions-free-region-ordering-callee.rs | 30 + .../regions-free-region-ordering-caller.rs | 27 + .../regions-free-region-ordering-caller1.rs | 15 + .../regions-free-region-ordering-incorrect.rs | 23 + ...on-outlives-static-outlives-free-region.rs | 18 + .../rustc/ui/regions/regions-glb-free-free.rs | 30 + ...regions-implied-bounds-projection-gap-1.rs | 31 + ...regions-implied-bounds-projection-gap-2.rs | 24 + ...regions-implied-bounds-projection-gap-3.rs | 24 + ...regions-implied-bounds-projection-gap-4.rs | 24 + ...ions-implied-bounds-projection-gap-hr-1.rs | 27 + .../rustc/ui/regions/regions-in-enums-anon.rs | 8 + .../rust/rustc/ui/regions/regions-in-enums.rs | 21 + .../ui/regions/regions-in-structs-anon.rs | 8 + .../rustc/ui/regions/regions-in-structs.rs | 16 + .../regions/regions-infer-at-fn-not-param.rs | 20 + .../regions-infer-borrow-scope-addr-of.rs | 24 + .../regions-infer-borrow-scope-too-big.rs | 17 + .../regions-infer-borrow-scope-view.rs | 12 + ...gions-infer-borrow-scope-within-loop-ok.rs | 14 + .../ui/regions/regions-infer-borrow-scope.rs | 16 + .../regions-infer-bound-from-trait-self.rs | 52 + .../regions/regions-infer-bound-from-trait.rs | 41 + .../rustc/ui/regions/regions-infer-call-2.rs | 16 + .../rustc/ui/regions/regions-infer-call-3.rs | 15 + .../rustc/ui/regions/regions-infer-call.rs | 12 + ...egions-infer-contravariance-due-to-decl.rs | 29 + ...regions-infer-contravariance-due-to-ret.rs | 23 + .../regions-infer-covariance-due-to-decl.rs | 26 + .../regions-infer-invariance-due-to-decl.rs | 17 + ...ns-infer-invariance-due-to-mutability-3.rs | 15 + ...ns-infer-invariance-due-to-mutability-4.rs | 15 + .../ui/regions/regions-infer-not-param.rs | 27 + .../regions/regions-infer-paramd-indirect.rs | 31 + .../regions-infer-proc-static-upvar.rs | 25 + .../regions-infer-reborrow-ref-mut-recurse.rs | 19 + ...regions-infer-region-in-fn-but-not-type.rs | 20 + .../regions/regions-infer-static-from-proc.rs | 19 + .../rustc/ui/regions/regions-issue-21422.rs | 19 + .../rustc/ui/regions/regions-issue-22246.rs | 30 + .../regions/regions-lifetime-bounds-on-fns.rs | 30 + .../regions-lifetime-nonfree-late-bound.rs | 36 + ...ions-lifetime-of-struct-or-enum-variant.rs | 27 + ...-lifetime-static-items-enclosing-scopes.rs | 21 + .../rustc/ui/regions/regions-link-fn-args.rs | 16 + .../ui/regions/regions-lub-ref-ref-rc.rs | 29 + .../rustc/ui/regions/regions-mock-codegen.rs | 55 + .../ui/regions/regions-name-duplicated.rs | 6 + .../rustc/ui/regions/regions-name-static.rs | 6 + .../ui/regions/regions-name-undeclared.rs | 59 + .../rustc/ui/regions/regions-nested-fns-2.rs | 13 + .../rustc/ui/regions/regions-nested-fns.rs | 21 + .../regions-no-bound-in-argument-cleanup.rs | 25 + .../regions-no-variance-from-fn-generics.rs | 45 + .../regions-normalize-in-where-clause-list.rs | 33 + .../ui/regions/regions-nullary-variant.rs | 16 + ...s-outlives-nominal-type-enum-region-rev.rs | 21 + ...gions-outlives-nominal-type-enum-region.rs | 21 + ...ons-outlives-nominal-type-enum-type-rev.rs | 21 + ...regions-outlives-nominal-type-enum-type.rs | 21 + ...outlives-nominal-type-struct-region-rev.rs | 21 + ...ons-outlives-nominal-type-struct-region.rs | 21 + ...s-outlives-nominal-type-struct-type-rev.rs | 21 + ...gions-outlives-nominal-type-struct-type.rs | 21 + ...ions-outlives-projection-container-hrtb.rs | 58 + ...egions-outlives-projection-container-wc.rs | 40 + .../regions-outlives-projection-container.rs | 77 + .../regions-outlives-projection-hrtype.rs | 27 + .../regions-outlives-projection-trait-def.rs | 22 + .../ui/regions/regions-outlives-scalar.rs | 14 + .../rust/rustc/ui/regions/regions-params.rs | 20 + .../regions-pattern-typing-issue-19552.rs | 9 + .../regions-pattern-typing-issue-19997.rs | 12 + .../ui/regions/regions-proc-bound-capture.rs | 13 + .../regions-reassign-let-bound-pointer.rs | 19 + .../regions-reassign-match-bound-pointer.rs | 22 + ...s-reborrow-from-shorter-mut-ref-mut-ref.rs | 9 + .../regions-reborrow-from-shorter-mut-ref.rs | 16 + .../rustc/ui/regions/regions-ref-in-fn-arg.rs | 15 + .../rust/rustc/ui/regions/regions-refcell.rs | 46 + ...ions-on-closures-to-inference-variables.rs | 60 + .../ui/regions/regions-ret-borrowed-1.rs | 18 + .../rustc/ui/regions/regions-ret-borrowed.rs | 21 + .../rust/rustc/ui/regions/regions-ret.rs | 9 + .../regions-return-interior-of-option.rs | 25 + ...regions-return-ref-to-upvar-issue-17403.rs | 12 + .../regions-return-stack-allocated-vec.rs | 11 + .../ui/regions/regions-scope-chain-example.rs | 44 + .../rustc/ui/regions/regions-self-impls.rs | 21 + .../rustc/ui/regions/regions-self-in-enums.rs | 18 + .../rust/rustc/ui/regions/regions-simple.rs | 8 + .../ui/regions/regions-static-bound-rpass.rs | 20 + .../rustc/ui/regions/regions-static-bound.rs | 21 + .../ui/regions/regions-static-closure.rs | 20 + .../rustc/ui/regions/regions-steal-closure.rs | 18 + .../rust/rustc/ui/regions/regions-trait-1.rs | 34 + .../ui/regions/regions-trait-object-1.rs | 36 + .../regions/regions-trait-object-subtyping.rs | 26 + .../ui/regions/regions-trait-variance.rs | 45 + .../rustc/ui/regions/regions-undeclared.rs | 14 + .../regions/regions-var-type-out-of-scope.rs | 15 + ...ariance-contravariant-use-contravariant.rs | 28 + ...ariant-use-covariant-in-second-position.rs | 29 + ...ns-variance-contravariant-use-covariant.rs | 27 + ...ns-variance-covariant-use-contravariant.rs | 27 + ...egions-variance-covariant-use-covariant.rs | 24 + ...ns-variance-invariant-use-contravariant.rs | 24 + ...egions-variance-invariant-use-covariant.rs | 21 + .../ui/regions/regions-wf-trait-object.rs | 11 + ...pe-param-outlives-reempty-issue-74429-2.rs | 67 + ...type-param-outlives-reempty-issue-74429.rs | 36 + .../rust/rustc/ui/reify-intrinsic.rs | 16 + .../rustc/ui/reject-specialized-drops-8142.rs | 71 + .../rust/rustc/ui/removing-extern-crate.rs | 17 + .../rust/rustc/ui/repeat-expr-in-static.rs | 9 + .../rust/rustc/ui/repeat-to-run-dtor-twice.rs | 20 + gcc/testsuite/rust/rustc/ui/repeat_count.rs | 35 + .../ui/repeat_count_const_in_async_fn.rs | 11 + gcc/testsuite/rust/rustc/ui/repr.rs | 14 + .../rustc/ui/repr/feature-gate-no-niche.rs | 21 + .../rust/rustc/ui/repr/repr-align-assign.rs | 14 + .../rust/rustc/ui/repr/repr-align.rs | 34 + .../rustc/ui/repr/repr-disallow-on-variant.rs | 10 + .../repr-no-niche-inapplicable-to-unions.rs | 15 + .../rust/rustc/ui/repr/repr-no-niche.rs | 330 + .../ui/repr/repr-packed-contains-align.rs | 51 + .../ui/repr/repr-transparent-other-items.rs | 10 + .../ui/repr/repr-transparent-other-reprs.rs | 21 + .../rust/rustc/ui/repr/repr-transparent.rs | 85 + .../rust/rustc/ui/repr_c_int_align.rs | 47 + .../rust/rustc/ui/required-lang-item.rs | 12 + .../ui/reserved/reserved-attr-on-macro.rs | 12 + .../rust/rustc/ui/reserved/reserved-become.rs | 5 + .../rust/rustc/ui/resolve-issue-2428.rs | 9 + .../rust/rustc/ui/resolve-pseudo-shadowing.rs | 12 + .../ui/resolve/associated-fn-called-as-fn.rs | 33 + .../ui/resolve/auxiliary/issue-19452-aux.rs | 4 + .../ui/resolve/auxiliary/issue-21221-3.rs | 20 + .../ui/resolve/auxiliary/issue-21221-4.rs | 13 + .../rustc/ui/resolve/auxiliary/issue-3907.rs | 4 + .../ui/resolve/auxiliary/namespaced_enums.rs | 11 + .../resolve/auxiliary/privacy-struct-ctor.rs | 10 + .../ui/resolve/block-with-trait-parent.rs | 15 + .../ui/resolve/enums-are-namespaced-xc.rs | 12 + .../ui/resolve/impl-items-vis-unresolved.rs | 27 + .../rust/rustc/ui/resolve/issue-14254.rs | 106 + .../rust/rustc/ui/resolve/issue-16058.rs | 19 + .../rust/rustc/ui/resolve/issue-17518.rs | 8 + .../rust/rustc/ui/resolve/issue-18252.rs | 9 + .../rust/rustc/ui/resolve/issue-19452.rs | 16 + .../rust/rustc/ui/resolve/issue-21221-1.rs | 76 + .../rust/rustc/ui/resolve/issue-21221-2.rs | 22 + .../rust/rustc/ui/resolve/issue-21221-3.rs | 20 + .../rust/rustc/ui/resolve/issue-21221-4.rs | 16 + .../rust/rustc/ui/resolve/issue-22692.rs | 4 + .../rust/rustc/ui/resolve/issue-23305.rs | 9 + .../rust/rustc/ui/resolve/issue-2356.rs | 95 + .../rust/rustc/ui/resolve/issue-24968.rs | 6 + .../rust/rustc/ui/resolve/issue-33876.rs | 13 + .../rust/rustc/ui/resolve/issue-3907-2.rs | 15 + .../rust/rustc/ui/resolve/issue-3907.rs | 21 + .../rust/rustc/ui/resolve/issue-39226.rs | 15 + .../rust/rustc/ui/resolve/issue-5035-2.rs | 8 + .../rust/rustc/ui/resolve/issue-5035.rs | 10 + .../rust/rustc/ui/resolve/issue-54379.rs | 15 + .../rust/rustc/ui/resolve/issue-57523.rs | 22 + ...sue-65025-extern-static-parent-generics.rs | 11 + ...issue-65035-static-with-parent-generics.rs | 30 + .../rust/rustc/ui/resolve/issue-6702.rs | 10 + .../issue-69401-trait-fn-no-body-ty-local.rs | 7 + ...ue-70736-async-fn-no-body-def-collector.rs | 21 + .../rust/rustc/ui/resolve/levenshtein.rs | 32 + .../rustc/ui/resolve/name-clash-nullary.rs | 4 + .../rustc/ui/resolve/privacy-enum-ctor.rs | 72 + .../rustc/ui/resolve/privacy-struct-ctor.rs | 48 + .../rustc/ui/resolve/raw-ident-in-path.rs | 6 + .../ui/resolve/resolve-assoc-suggestions.rs | 40 + .../ui/resolve/resolve-bad-import-prefix.rs | 15 + .../ui/resolve/resolve-bad-visibility.rs | 16 + ...e-conflict-extern-crate-vs-extern-crate.rs | 5 + ...resolve-conflict-import-vs-extern-crate.rs | 5 + .../resolve-conflict-import-vs-import.rs | 10 + .../resolve-conflict-item-vs-extern-crate.rs | 6 + .../resolve-conflict-item-vs-import.rs | 9 + .../resolve-conflict-type-vs-import.rs | 8 + .../rustc/ui/resolve/resolve-hint-macro.rs | 5 + .../resolve-inconsistent-binding-mode.rs | 42 + .../ui/resolve/resolve-inconsistent-names.rs | 37 + .../rust/rustc/ui/resolve/resolve-label.rs | 14 + .../ui/resolve/resolve-primitive-fallback.rs | 11 + .../ui/resolve/resolve-self-in-impl-2.rs | 8 + .../rustc/ui/resolve/resolve-self-in-impl.rs | 21 + .../resolve/resolve-speculative-adjustment.rs | 31 + .../resolve-type-param-in-item-in-trait.rs | 36 + .../rustc/ui/resolve/resolve-unknown-trait.rs | 11 + .../ui/resolve/resolve-variant-assoc-item.rs | 8 + .../suggest-path-instead-of-mod-dot-item.rs | 60 + .../rustc/ui/resolve/token-error-correct-2.rs | 8 + .../rustc/ui/resolve/token-error-correct-3.rs | 28 + .../rustc/ui/resolve/token-error-correct-4.rs | 11 + .../rustc/ui/resolve/token-error-correct.rs | 10 + .../rustc/ui/resolve/tuple-struct-alias.rs | 10 + .../typo-suggestion-named-underscore.rs | 15 + ...unboxed-closure-sugar-nonexistent-trait.rs | 10 + .../resolve/unresolved_static_type_field.rs | 15 + .../rust/rustc/ui/resolve/use_suggestion.rs | 8 + .../ui/resolve/use_suggestion_placement.rs | 29 + .../ui/resolve/visibility-indeterminate.rs | 8 + .../rust/rustc/ui/resolve_self_super_hint.rs | 28 + .../rustc/ui/resource-assign-is-not-copy.rs | 34 + .../rust/rustc/ui/resource-destruct.rs | 32 + .../rust/rustc/ui/result-opt-conversions.rs | 48 + gcc/testsuite/rust/rustc/ui/ret-bang.rs | 14 + gcc/testsuite/rust/rustc/ui/ret-non-nil.rs | 8 + gcc/testsuite/rust/rustc/ui/ret-none.rs | 14 + gcc/testsuite/rust/rustc/ui/retslot-cast.rs | 23 + .../rust/rustc/ui/return-disjoint-regions.rs | 8 + gcc/testsuite/rust/rustc/ui/return-nil.rs | 7 + .../rustc/ui/return/return-from-diverging.rs | 9 + .../ui/return/return-match-array-const.rs | 11 + .../rust/rustc/ui/return/return-type.rs | 15 + .../ui/return/return-unit-from-diverging.rs | 10 + .../bind-by-move-no-guards.rs | 20 + .../former-E0008-now-pass.rs | 12 + .../rfc-basic-examples.rs | 44 + .../rfc-reject-double-move-across-arms.rs | 14 + .../rfc-reject-double-move-in-first-arm.rs | 15 + ...-hide-behind-direct-unsafe-ptr-embedded.rs | 27 + ...low-hide-behind-direct-unsafe-ptr-param.rs | 27 + ...ide-behind-indirect-unsafe-ptr-embedded.rs | 27 + ...w-hide-behind-indirect-unsafe-ptr-param.rs | 27 + .../allow-use-behind-cousin-variant.rs | 60 + ...cant-hide-behind-direct-struct-embedded.rs | 27 + .../cant-hide-behind-direct-struct-param.rs | 27 + ...nt-hide-behind-doubly-indirect-embedded.rs | 30 + .../cant-hide-behind-doubly-indirect-param.rs | 30 + ...nt-hide-behind-indirect-struct-embedded.rs | 30 + .../cant-hide-behind-indirect-struct-param.rs | 30 + .../feature-gate.rs | 40 + .../fn-ptr-is-structurally-matchable.rs | 136 + ...-61188-match-slice-forbidden-without-eq.rs | 20 + ...2307-match-ref-ref-forbidden-without-eq.rs | 44 + .../issue-63479-match-fnptr.rs | 41 + ...ty-array-allowed-without-eq-issue-62336.rs | 18 + .../match-forbidden-without-eq.rs | 28 + ...tch-nonempty-array-forbidden-without-eq.rs | 20 + .../match-requires-both-partialeq-and-eq.rs | 22 + .../phantom-data-is-structurally-matchable.rs | 54 + .../rfc-1717-dllimport/missing-link-attr.rs | 5 + .../ui/rfc-1717-dllimport/multiple-renames.rs | 8 + .../ui/rfc-1717-dllimport/rename-to-empty.rs | 8 + .../termination-trait-for-box-dyn-error.rs | 12 + .../termination-trait-for-never.rs | 8 + ...mination-trait-for-result-box-error_err.rs | 11 + .../termination-trait-for-str.rs | 9 + .../termination-trait-impl-trait.rs | 4 + .../termination-trait-in-test-should-panic.rs | 16 + .../termination-trait-in-test.rs | 29 + .../termination-trait-main-i32.rs | 7 + .../termination-trait-main-wrong-type.rs | 4 + .../termination-trait-not-satisfied.rs | 6 + .../termination-trait-test-wrong-type.rs | 9 + .../borrowck-issue-49631.rs | 25 + .../ui/rfc-2005-default-binding-mode/const.rs | 18 + .../ui/rfc-2005-default-binding-mode/enum.rs | 23 + .../explicit-mut.rs | 29 + .../ui/rfc-2005-default-binding-mode/for.rs | 10 + .../issue-44912-or.rs | 11 + .../ui/rfc-2005-default-binding-mode/lit.rs | 25 + .../no-double-error.rs | 12 + .../ui/rfc-2005-default-binding-mode/slice.rs | 8 + .../auxiliary/enums.rs | 12 + .../auxiliary/monovariants.rs | 9 + .../auxiliary/structs.rs | 26 + .../auxiliary/variants.rs | 8 + .../borrowck-exhaustive.rs | 43 + .../borrowck-non-exhaustive.rs | 19 + .../rustc/ui/rfc-2008-non-exhaustive/enum.rs | 70 + .../enum_same_crate.rs | 19 + .../enum_same_crate_empty_match.rs | 38 + .../improper_ctypes/auxiliary/types.rs | 30 + .../improper_ctypes/extern_crate_improper.rs | 25 + .../improper_ctypes/same_crate_proper.rs | 46 + .../invalid-attribute.rs | 17 + .../ui/rfc-2008-non-exhaustive/struct.rs | 50 + .../structs_same_crate.rs | 33 + .../uninhabited/auxiliary/uninhabited.rs | 33 + .../uninhabited/coercions.rs | 39 + .../uninhabited/coercions_same_crate.rs | 46 + .../uninhabited/indirect_match.rs | 37 + .../uninhabited/indirect_match_same_crate.rs | 52 + ...indirect_match_with_exhaustive_patterns.rs | 41 + ...tch_with_exhaustive_patterns_same_crate.rs | 58 + .../issue-65157-repeated-match-arm.rs | 22 + .../uninhabited/match.rs | 35 + .../uninhabited/match_same_crate.rs | 42 + .../match_with_exhaustive_patterns.rs | 38 + ...tch_with_exhaustive_patterns_same_crate.rs | 48 + .../uninhabited/patterns.rs | 60 + .../uninhabited/patterns_same_crate.rs | 71 + .../ui/rfc-2008-non-exhaustive/variant.rs | 34 + .../variants_fictive_visibility.rs | 13 + .../variants_same_crate.rs | 19 + .../downcast-unsafe-trait-objects.rs | 24 + .../manual-self-impl-for-unsafe-obj.rs | 67 + .../static-dispatch-unsafe-object.rs | 38 + .../ui/rfc-2091-track-caller/call-chain.rs | 27 + .../caller-location-fnptr-rt-ctfe-equiv.rs | 33 + .../caller-location-intrinsic.rs | 28 + .../const-caller-location.rs | 44 + .../diverging-caller-location.rs | 18 + .../rfc-2091-track-caller/error-odd-syntax.rs | 6 + .../error-with-invalid-abi.rs | 12 + .../rfc-2091-track-caller/error-with-main.rs | 5 + .../rfc-2091-track-caller/error-with-naked.rs | 22 + .../rfc-2091-track-caller/error-with-start.rs | 8 + .../intrinsic-wrapper.rs | 22 + .../ui/rfc-2091-track-caller/only-for-fns.rs | 6 + .../rustc/ui/rfc-2091-track-caller/pass.rs | 11 + .../std-panic-locations.rs | 70 + .../track-caller-attribute.rs | 41 + .../rfc-2091-track-caller/track-caller-ffi.rs | 49 + .../tracked-fn-ptr-with-arg.rs | 63 + .../rfc-2091-track-caller/tracked-fn-ptr.rs | 63 + .../tracked-trait-impls.rs | 78 + .../tracked-trait-obj.rs | 24 + .../ui/rfc-2093-infer-outlives/cross-crate.rs | 9 + .../dont-infer-static.rs | 15 + .../rustc/ui/rfc-2093-infer-outlives/enum.rs | 28 + .../rfc-2093-infer-outlives/explicit-dyn.rs | 14 + .../rfc-2093-infer-outlives/explicit-enum.rs | 14 + .../explicit-projection.rs | 14 + .../explicit-struct.rs | 14 + .../rfc-2093-infer-outlives/explicit-union.rs | 15 + .../rfc-2093-infer-outlives/infer-static.rs | 13 + .../ui/rfc-2093-infer-outlives/issue-54467.rs | 18 + .../ui/rfc-2093-infer-outlives/nested-enum.rs | 14 + .../rfc-2093-infer-outlives/nested-regions.rs | 9 + .../rfc-2093-infer-outlives/nested-structs.rs | 13 + .../rfc-2093-infer-outlives/nested-union.rs | 15 + .../ui/rfc-2093-infer-outlives/privacy.rs | 21 + .../ui/rfc-2093-infer-outlives/projection.rs | 9 + .../ui/rfc-2093-infer-outlives/reference.rs | 9 + .../regions-enum-not-wf.rs | 42 + ...egions-outlives-nominal-type-region-rev.rs | 23 + .../regions-outlives-nominal-type-region.rs | 23 + .../regions-outlives-nominal-type-type-rev.rs | 23 + .../regions-outlives-nominal-type-type.rs | 23 + .../regions-struct-not-wf.rs | 29 + .../ui/rfc-2093-infer-outlives/self-dyn.rs | 15 + .../rfc-2093-infer-outlives/self-structs.rs | 14 + .../crate-path-non-absolute.rs | 14 + .../keyword-crate-as-identifier.rs | 7 + .../auxiliary/xcrate.rs | 6 + .../non-existent-1.rs | 6 + .../non-existent-2.rs | 7 + .../non-existent-3.rs | 6 + .../not-allowed.rs | 10 + .../single-segment.rs | 12 + .../ui/rfc-2294-if-let-guard/feature-gate.rs | 86 + .../ui/rfc-2306/convert-id-const-with-gate.rs | 8 + .../dbg-macro-expected-behavior.rs | 68 + .../dbg-macro-move-semantics.rs | 11 + .../dbg-macro-requires-debug.rs | 8 + ...mod_file_nonascii_with_path_allowed-aux.rs | 2 + .../crate_name_nonascii_forbidden-1.rs | 6 + .../crate_name_nonascii_forbidden-2.rs | 8 + .../rustc/ui/rfc-2457/idents-normalized.rs | 9 + .../rfc-2457/mod_file_nonascii_forbidden.rs | 7 + .../mod_file_nonascii_with_path_allowed.rs | 8 + .../rfc-2457/mod_inline_nonascii_allowed.rs | 9 + .../rfc-2457/no_mangle_nonascii_forbidden.rs | 7 + .../ast-pretty-check.rs | 7 + .../disallowed-positions.rs | 241 + .../ui/rfc-2497-if-let-chains/feature-gate.rs | 139 + .../protect-precedences.rs | 17 + .../attr-without-param.rs | 17 + .../auxiliary/ident-mac.rs | 12 + .../auxiliary/param-attrs.rs | 44 + ...-64682-dropping-first-attrs-in-impl-fns.rs | 22 + .../rfc-2565-param-attrs/param-attrs-2018.rs | 7 + .../param-attrs-allowed.rs | 102 + .../param-attrs-builtin-attrs.rs | 175 + .../rfc-2565-param-attrs/param-attrs-cfg.rs | 122 + .../param-attrs-pretty.rs | 62 + .../proc-macro-cannot-be-used.rs | 66 + .../feature-gate-raw-dylib-2.rs | 9 + .../feature-gate-raw-dylib.rs | 6 + .../link-ordinal-and-name.rs | 13 + .../link-ordinal-invalid-format.rs | 12 + .../link-ordinal-too-large.rs | 12 + .../rfc-2632-const-trait-impl/assoc-type.rs | 29 + .../call-const-trait-method-fail.rs | 31 + .../call-const-trait-method-pass.rs | 42 + .../const-and-non-const-impl.rs | 34 + .../const-check-fns-in-const-impl.rs | 17 + .../const-trait-bound-opt-out/feature-gate.rs | 18 + .../in-impl-trait.rs | 22 + .../in-trait-bounds.rs | 9 + .../in-trait-object.rs | 20 + .../opt-out-twice.rs | 9 + .../const-trait-bound-opt-out/syntax.rs | 11 + .../with-maybe-sized.rs | 8 + .../without-question-mark.rs | 8 + .../rfc-2632-const-trait-impl/feature-gate.rs | 15 + .../generic-bound.rs | 33 + .../hir-const-check.rs | 18 + .../impl-opt-out-trait.rs | 12 + .../inherent-impl.rs | 16 + .../ui/rfc-2632-const-trait-impl/stability.rs | 44 + .../ui/rfc-2632-const-trait-impl/syntax.rs | 10 + gcc/testsuite/rust/rustc/ui/rfc1623-2.rs | 14 + gcc/testsuite/rust/rustc/ui/rfc1623.rs | 93 + .../rust/rustc/ui/rfcs/rfc-1014-2.rs | 32 + gcc/testsuite/rust/rustc/ui/rfcs/rfc-1014.rs | 36 + .../ui/rfcs/rfc-1789-as-cell/from-mut.rs | 12 + .../termination-trait-for-box-dyn-error.rs | 7 + .../termination-trait-for-empty.rs | 3 + .../termination-trait-for-exitcode.rs | 9 + .../termination-trait-for-impl-termination.rs | 5 + ...rmination-trait-for-result-box-error_ok.rs | 7 + .../termination-trait-for-result.rs | 7 + .../termination-trait-for-str.rs | 5 + .../rfcs/rfc-2005-default-binding-mode/box.rs | 19 + .../rfc-2005-default-binding-mode/constref.rs | 41 + .../rfc-2005-default-binding-mode/enum.rs | 46 + .../rfcs/rfc-2005-default-binding-mode/for.rs | 21 + .../rfc-2005-default-binding-mode/general.rs | 250 + .../rfcs/rfc-2005-default-binding-mode/lit.rs | 35 + .../rfc-2005-default-binding-mode/range.rs | 10 + .../ref-region.rs | 17 + .../reset-mode.rs | 15 + .../rfc-2005-default-binding-mode/slice.rs | 26 + .../rfc-2005-default-binding-mode/struct.rs | 23 + .../tuple-struct.rs | 20 + .../rfc-2005-default-binding-mode/tuple.rs | 13 + .../ui/rfcs/rfc-2151-raw-identifiers/attr.rs | 16 + .../ui/rfcs/rfc-2151-raw-identifiers/basic.rs | 21 + .../ui/rfcs/rfc-2151-raw-identifiers/items.rs | 33 + .../rfcs/rfc-2151-raw-identifiers/macros.rs | 39 + .../ui/rfcs/rfc-2175-or-if-while-let/basic.rs | 34 + .../ui/rfcs/rfc-2302-self-struct-ctor.rs | 128 + .../rfc-2396-target_feature-11/check-pass.rs | 51 + .../closures-inherit-target_feature.rs | 19 + .../feature-gate-target_feature_11.rs | 7 + .../rfcs/rfc-2396-target_feature-11/fn-ptr.rs | 11 + .../rfc-2396-target_feature-11/fn-traits.rs | 35 + .../rfc-2396-target_feature-11/safe-calls.rs | 48 + .../rfc-2396-target_feature-11/trait-impl.rs | 22 + ...-unreserve-pure-offsetof-sizeof-alignof.rs | 16 + .../rfc1445/eq-allows-match-on-ty-in-macro.rs | 24 + .../rustc/ui/rfcs/rfc1445/eq-allows-match.rs | 18 + gcc/testsuite/rust/rustc/ui/rfcs/rfc1623.rs | 76 + .../rustc/ui/rfcs/rfc1717/library-override.rs | 15 + .../rust/rustc/ui/rfcs/rfc1857-drop-order.rs | 225 + gcc/testsuite/rust/rustc/ui/rmeta-lib-pass.rs | 15 + gcc/testsuite/rust/rustc/ui/rmeta-pass.rs | 16 + .../rust/rustc/ui/rmeta-priv-warn.rs | 12 + gcc/testsuite/rust/rustc/ui/rmeta-rpass.rs | 19 + gcc/testsuite/rust/rustc/ui/rmeta.rs | 9 + gcc/testsuite/rust/rustc/ui/rmeta_lib.rs | 15 + .../rust/rustc/ui/rmeta_meta_main.rs | 15 + .../rust/rustc/ui/running-with-no-runtime.rs | 52 + .../rustc/ui/rust-2018/async-ident-allowed.rs | 12 + .../rust/rustc/ui/rust-2018/async-ident.rs | 80 + .../rust/rustc/ui/rust-2018/auxiliary/baz.rs | 6 + .../rust-2018/auxiliary/edition-lint-paths.rs | 13 + .../auxiliary/macro-use-warned-against.rs | 3 + .../auxiliary/macro-use-warned-against2.rs | 2 + .../auxiliary/remove-extern-crate.rs | 10 + .../suggestions-not-always-applicable.rs | 14 + .../auxiliary/trait-import-suggestions.rs | 6 + .../rust/rustc/ui/rust-2018/dyn-keyword.rs | 11 + .../ui/rust-2018/dyn-trait-compatibility.rs | 9 + .../edition-lint-fully-qualified-paths.rs | 28 + .../edition-lint-infer-outlives-multispan.rs | 369 + .../rust-2018/edition-lint-infer-outlives.rs | 796 ++ .../edition-lint-nested-empty-paths.rs | 31 + .../ui/rust-2018/edition-lint-nested-paths.rs | 28 + .../ui/rust-2018/edition-lint-paths-2018.rs | 11 + .../rustc/ui/rust-2018/edition-lint-paths.rs | 72 + .../edition-lint-uninferable-outlives.rs | 31 + .../extern-crate-idiomatic-in-2018.rs | 29 + .../ui/rust-2018/extern-crate-idiomatic.rs | 19 + .../extern-crate-referenced-by-self-path.rs | 18 + .../rustc/ui/rust-2018/extern-crate-rename.rs | 19 + .../rustc/ui/rust-2018/extern-crate-submod.rs | 26 + .../ui/rust-2018/future-proofing-locals.rs | 51 + .../rust/rustc/ui/rust-2018/issue-51008-1.rs | 16 + .../rust/rustc/ui/rust-2018/issue-51008.rs | 16 + .../rust-2018/issue-52202-use-suggestions.rs | 14 + .../rust/rustc/ui/rust-2018/issue-54006.rs | 14 + ...sue-54400-unused-extern-crate-attr-span.rs | 16 + .../rust-2018/local-path-suggestions-2015.rs | 27 + .../rust-2018/local-path-suggestions-2018.rs | 22 + .../ui/rust-2018/macro-use-warned-against.rs | 15 + .../ui/rust-2018/proc-macro-crate-in-paths.rs | 17 + .../rustc/ui/rust-2018/remove-extern-crate.rs | 40 + .../suggestions-not-always-applicable.rs | 28 + .../ui/rust-2018/trait-import-suggestions.rs | 32 + .../rust/rustc/ui/rust-2018/try-ident.rs | 16 + .../rust/rustc/ui/rust-2018/try-macro.rs | 19 + .../uniform-paths/ambiguity-macros-nested.rs | 22 + .../uniform-paths/ambiguity-macros.rs | 20 + .../uniform-paths/ambiguity-nested.rs | 17 + .../ui/rust-2018/uniform-paths/ambiguity.rs | 13 + .../uniform-paths/auxiliary/cross-crate.rs | 6 + .../uniform-paths/auxiliary/issue-56596-2.rs | 2 + .../uniform-paths/auxiliary/issue-56596.rs | 2 + .../block-scoped-shadow-nested.rs | 21 + .../uniform-paths/block-scoped-shadow.rs | 22 + .../ui/rust-2018/uniform-paths/cross-crate.rs | 13 + .../ui/rust-2018/uniform-paths/deadlock.rs | 8 + .../rust-2018/uniform-paths/fn-local-enum.rs | 14 + .../uniform-paths/from-decl-macro.rs | 13 + .../ui/rust-2018/uniform-paths/issue-54253.rs | 18 + .../rust-2018/uniform-paths/issue-56596-2.rs | 12 + .../ui/rust-2018/uniform-paths/issue-56596.rs | 15 + .../ui/rust-2018/uniform-paths/macro-rules.rs | 44 + .../rust-2018/uniform-paths/prelude-fail-2.rs | 22 + .../rust-2018/uniform-paths/prelude-fail.rs | 7 + .../ui/rust-2018/uniform-paths/prelude.rs | 23 + .../ui/rust-2018/uniform-paths/redundant.rs | 21 + .../rustc/ui/rustc-args-required-const.rs | 28 + .../rustc/ui/rustc-args-required-const2.rs | 11 + gcc/testsuite/rust/rustc/ui/rustc-error.rs | 7 + gcc/testsuite/rust/rustc/ui/rustc-rust-log.rs | 15 + .../rust/rustc/ui/rvalue-static-promotion.rs | 20 + .../rust/rustc/ui/safe-extern-statics-mut.rs | 16 + .../rust/rustc/ui/safe-extern-statics.rs | 16 + .../rust/rustc/ui/sanitize/address.rs | 21 + .../rust/rustc/ui/sanitize/badfree.rs | 20 + gcc/testsuite/rust/rustc/ui/sanitize/cfg.rs | 29 + .../rust/rustc/ui/sanitize/incompatible.rs | 7 + .../rust/rustc/ui/sanitize/inline-always.rs | 16 + .../sanitize/issue-72154-lifetime-markers.rs | 32 + gcc/testsuite/rust/rustc/ui/sanitize/leak.rs | 22 + .../rust/rustc/ui/sanitize/memory.rs | 44 + .../new-llvm-pass-manager-thin-lto.rs | 28 + .../rust/rustc/ui/sanitize/thread.rs | 58 + .../rustc/ui/sanitize/unsupported-target.rs | 7 + .../rust/rustc/ui/sanitize/use-after-scope.rs | 19 + .../ui/save-analysis/emit-notifications.rs | 8 + .../rustc/ui/save-analysis/issue-59134-0.rs | 13 + .../rustc/ui/save-analysis/issue-59134-1.rs | 13 + .../rustc/ui/save-analysis/issue-63663.rs | 29 + .../rustc/ui/save-analysis/issue-64659.rs | 11 + .../rustc/ui/save-analysis/issue-65411.rs | 16 + .../rustc/ui/save-analysis/issue-65590.rs | 22 + .../rustc/ui/save-analysis/issue-68621.rs | 18 + .../rustc/ui/save-analysis/issue-72267.rs | 8 + .../rustc/ui/save-analysis/issue-73020.rs | 6 + .../rustc/ui/save-analysis/issue-73022.rs | 14 + .../arbitrary-self-types-not-object-safe.rs | 45 + .../ui/self/arbitrary_self_types_nested.rs | 37 + ...arbitrary_self_types_pin_lifetime-async.rs | 36 + .../self/arbitrary_self_types_pin_lifetime.rs | 61 + ...elf_types_pin_lifetime_impl_trait-async.rs | 15 + ...rary_self_types_pin_lifetime_impl_trait.rs | 12 + ..._self_types_pin_lifetime_mismatch-async.rs | 21 + ...itrary_self_types_pin_lifetime_mismatch.rs | 17 + ...itrary_self_types_pointers_and_wrappers.rs | 69 + ...arbitrary_self_types_raw_pointer_struct.rs | 29 + .../arbitrary_self_types_raw_pointer_trait.rs | 62 + .../ui/self/arbitrary_self_types_silly.rs | 22 + .../arbitrary_self_types_stdlib_pointers.rs | 55 + .../ui/self/arbitrary_self_types_struct.rs | 25 + .../ui/self/arbitrary_self_types_trait.rs | 20 + .../arbitrary_self_types_unsized_struct.rs | 17 + .../ui/self/auxiliary/explicit_self_xcrate.rs | 16 + .../ui/self/builtin-superkinds-self-type.rs | 21 + .../ui/self/by-value-self-in-mut-slot.rs | 23 + .../rust/rustc/ui/self/elision/alias-async.rs | 37 + .../rust/rustc/ui/self/elision/alias.rs | 36 + .../rust/rustc/ui/self/elision/assoc-async.rs | 41 + .../rust/rustc/ui/self/elision/assoc.rs | 40 + .../rustc/ui/self/elision/lt-alias-async.rs | 39 + .../rust/rustc/ui/self/elision/lt-alias.rs | 38 + .../rustc/ui/self/elision/lt-assoc-async.rs | 51 + .../rust/rustc/ui/self/elision/lt-assoc.rs | 44 + .../ui/self/elision/lt-ref-self-async.rs | 40 + .../rust/rustc/ui/self/elision/lt-ref-self.rs | 38 + .../rustc/ui/self/elision/lt-self-async.rs | 50 + .../rust/rustc/ui/self/elision/lt-self.rs | 49 + .../rustc/ui/self/elision/lt-struct-async.rs | 37 + .../rust/rustc/ui/self/elision/lt-struct.rs | 36 + .../self/elision/multiple-ref-self-async.rs | 45 + .../ui/self/elision/multiple-ref-self.rs | 44 + .../rustc/ui/self/elision/ref-alias-async.rs | 40 + .../rust/rustc/ui/self/elision/ref-alias.rs | 39 + .../rustc/ui/self/elision/ref-assoc-async.rs | 41 + .../rust/rustc/ui/self/elision/ref-assoc.rs | 40 + .../ui/self/elision/ref-mut-alias-async.rs | 37 + .../rustc/ui/self/elision/ref-mut-alias.rs | 36 + .../ui/self/elision/ref-mut-self-async.rs | 40 + .../rustc/ui/self/elision/ref-mut-self.rs | 38 + .../ui/self/elision/ref-mut-struct-async.rs | 34 + .../rustc/ui/self/elision/ref-mut-struct.rs | 32 + .../rustc/ui/self/elision/ref-self-async.rs | 54 + .../rust/rustc/ui/self/elision/ref-self.rs | 52 + .../rustc/ui/self/elision/ref-struct-async.rs | 34 + .../rust/rustc/ui/self/elision/ref-struct.rs | 32 + .../rust/rustc/ui/self/elision/self-async.rs | 37 + .../rust/rustc/ui/self/elision/self.rs | 36 + .../rustc/ui/self/elision/struct-async.rs | 33 + .../rust/rustc/ui/self/elision/struct.rs | 32 + .../rustc/ui/self/explicit-self-closures.rs | 18 + .../rustc/ui/self/explicit-self-generic.rs | 30 + .../ui/self/explicit-self-objects-uniq.rs | 23 + .../rust/rustc/ui/self/explicit-self.rs | 74 + .../rustc/ui/self/explicit_self_xcrate_exe.rs | 13 + gcc/testsuite/rust/rustc/ui/self/move-self.rs | 20 + .../object-safety-sized-self-by-value-self.rs | 40 + ...object-safety-sized-self-generic-method.rs | 40 + .../object-safety-sized-self-return-Self.rs | 40 + .../point-at-arbitrary-self-type-method.rs | 10 + ...int-at-arbitrary-self-type-trait-method.rs | 11 + .../rust/rustc/ui/self/self-impl-2.rs | 71 + gcc/testsuite/rust/rustc/ui/self/self-impl.rs | 31 + .../self/self-in-mut-slot-default-method.rs | 37 + .../self/self-in-mut-slot-immediate-value.rs | 24 + .../rust/rustc/ui/self/self-in-typedefs.rs | 39 + .../rust/rustc/ui/self/self-infer.rs | 9 + .../rust/rustc/ui/self/self-re-assign.rs | 18 + .../rustc/ui/self/self-shadowing-import.rs | 17 + .../rust/rustc/ui/self/self-type-param.rs | 20 + .../rustc/ui/self/self-vs-path-ambiguity.rs | 13 + .../rust/rustc/ui/self/self_lifetime-async.rs | 15 + .../rust/rustc/ui/self/self_lifetime.rs | 16 + .../rust/rustc/ui/self/self_type_keyword-2.rs | 14 + .../rust/rustc/ui/self/self_type_keyword.rs | 42 + .../rust/rustc/ui/self/string-self-append.rs | 15 + .../rust/rustc/ui/self/suggest-self-2.rs | 26 + .../rust/rustc/ui/self/suggest-self.rs | 42 + .../rust/rustc/ui/self/ufcs-explicit-self.rs | 50 + .../rustc/ui/self/uniq-self-in-mut-slot.rs | 24 + .../rust/rustc/ui/self/where-for-self.rs | 52 + .../rust/rustc/ui/semistatement-in-lambda.rs | 13 + .../sepcomp/auxiliary/sepcomp-extern-lib.rs | 5 + .../ui/sepcomp/auxiliary/sepcomp_cci_lib.rs | 7 + .../rustc/ui/sepcomp/auxiliary/sepcomp_lib.rs | 22 + .../rust/rustc/ui/sepcomp/sepcomp-cci.rs | 34 + .../rust/rustc/ui/sepcomp/sepcomp-extern.rs | 34 + .../rustc/ui/sepcomp/sepcomp-fns-backwards.rs | 34 + .../rust/rustc/ui/sepcomp/sepcomp-fns.rs | 31 + .../rust/rustc/ui/sepcomp/sepcomp-lib-lto.rs | 20 + .../rust/rustc/ui/sepcomp/sepcomp-lib.rs | 17 + .../rust/rustc/ui/sepcomp/sepcomp-statics.rs | 32 + .../rust/rustc/ui/sepcomp/sepcomp-unwind.rs | 35 + gcc/testsuite/rust/rustc/ui/seq-args.rs | 12 + gcc/testsuite/rust/rustc/ui/seq-compare.rs | 17 + gcc/testsuite/rust/rustc/ui/shadow-bool.rs | 19 + gcc/testsuite/rust/rustc/ui/shadow.rs | 25 + .../rust/rustc/ui/shadowed-use-visibility.rs | 14 + .../rustc/ui/shadowed/shadowed-lifetime.rs | 25 + .../ui/shadowed/shadowed-trait-methods.rs | 15 + .../ui/shadowed/shadowed-type-parameter.rs | 31 + .../ui/shadowed/shadowed-use-visibility.rs | 17 + .../shadowed/shadowing-in-the-same-pattern.rs | 8 + .../rust/rustc/ui/shift-various-bad-types.rs | 32 + .../rust/rustc/ui/short-error-format.rs | 10 + .../ui/signal-alternate-stack-cleanup.rs | 39 + .../rust/rustc/ui/signal-exit-status.rs | 20 + .../rustc/ui/sigpipe-should-be-ignored.rs | 35 + ...intrinsic-generic-arithmetic-saturating.rs | 40 + .../simd-intrinsic-generic-arithmetic.rs | 96 + .../simd-intrinsic-generic-bitmask.rs | 93 + .../simd-intrinsic-generic-cast.rs | 44 + .../simd-intrinsic-generic-comparison.rs | 68 + .../simd-intrinsic-generic-elements.rs | 90 + .../simd-intrinsic-generic-reduction.rs | 59 + .../simd-intrinsic-generic-select.rs | 65 + .../simd-intrinsic-inlining-issue67557-ice.rs | 26 + .../simd-intrinsic-inlining-issue67557.rs | 41 + .../ui/simd-type-generic-monomorphisation.rs | 14 + gcc/testsuite/rust/rustc/ui/simd-type.rs | 11 + .../ui/simd/shuffle-not-out-of-bounds.rs | 192 + .../rust/rustc/ui/simd/simd-generics.rs | 40 + .../ui/simd/simd-intrinsic-float-math.rs | 104 + .../ui/simd/simd-intrinsic-float-minmax.rs | 53 + ...intrinsic-generic-arithmetic-saturating.rs | 92 + .../simd/simd-intrinsic-generic-arithmetic.rs | 121 + .../ui/simd/simd-intrinsic-generic-bitmask.rs | 63 + .../ui/simd/simd-intrinsic-generic-cast.rs | 122 + .../simd/simd-intrinsic-generic-comparison.rs | 107 + .../simd/simd-intrinsic-generic-elements.rs | 126 + .../ui/simd/simd-intrinsic-generic-gather.rs | 142 + .../simd/simd-intrinsic-generic-reduction.rs | 166 + .../ui/simd/simd-intrinsic-generic-select.rs | 196 + .../rust/rustc/ui/simd/simd-size-align.rs | 97 + .../ui/simd/simd-target-feature-mixup.rs | 186 + gcc/testsuite/rust/rustc/ui/simd/simd-type.rs | 17 + gcc/testsuite/rust/rustc/ui/similar-tokens.rs | 14 + gcc/testsuite/rust/rustc/ui/simple-infer.rs | 7 + .../rust/rustc/ui/simple_global_asm.rs | 25 + .../ui/single-primitive-inherent-impl.rs | 14 + .../rustc/ui/single-use-lifetime/fn-types.rs | 17 + .../one-use-in-fn-argument-in-band.rs | 19 + .../one-use-in-fn-argument.rs | 23 + .../one-use-in-fn-return.rs | 18 + .../one-use-in-inherent-impl-header.rs | 23 + .../one-use-in-inherent-method-argument.rs | 18 + .../one-use-in-inherent-method-return.rs | 19 + .../single-use-lifetime/one-use-in-struct.rs | 28 + .../one-use-in-trait-method-argument.rs | 22 + .../two-uses-in-fn-argument-and-return.rs | 16 + .../two-uses-in-fn-arguments.rs | 17 + .../two-uses-in-inherent-impl-header.rs | 18 + ...-in-inherent-method-argument-and-return.rs | 19 + .../two-uses-in-trait-impl.rs | 23 + .../ui/single-use-lifetime/zero-uses-in-fn.rs | 25 + .../single-use-lifetime/zero-uses-in-impl.rs | 11 + gcc/testsuite/rust/rustc/ui/size-and-align.rs | 21 + .../rust/rustc/ui/sized-borrowed-pointer.rs | 11 + .../rust/rustc/ui/sized-cycle-note.rs | 17 + .../rust/rustc/ui/sized-owned-pointer.rs | 12 + gcc/testsuite/rust/rustc/ui/sleep.rs | 19 + gcc/testsuite/rust/rustc/ui/slice-2.rs | 12 + gcc/testsuite/rust/rustc/ui/slice-mut-2.rs | 9 + gcc/testsuite/rust/rustc/ui/slice-mut.rs | 13 + .../rust/rustc/ui/slice-to-vec-comparison.rs | 7 + .../slightly-nice-generic-literal-messages.rs | 15 + .../rust/rustc/ui/slowparse-bstring.rs | 7 + .../rust/rustc/ui/slowparse-string.rs | 7 + gcc/testsuite/rust/rustc/ui/span/E0046.rs | 12 + gcc/testsuite/rust/rustc/ui/span/E0057.rs | 7 + gcc/testsuite/rust/rustc/ui/span/E0072.rs | 8 + gcc/testsuite/rust/rustc/ui/span/E0204.rs | 27 + gcc/testsuite/rust/rustc/ui/span/E0493.rs | 22 + gcc/testsuite/rust/rustc/ui/span/E0535.rs | 7 + gcc/testsuite/rust/rustc/ui/span/E0536.rs | 5 + gcc/testsuite/rust/rustc/ui/span/E0537.rs | 5 + .../ui/span/auxiliary/transitive_dep_three.rs | 10 + .../ui/span/auxiliary/transitive_dep_two.rs | 4 + ...rrowck-borrow-overloaded-auto-deref-mut.rs | 143 + .../borrowck-borrow-overloaded-deref-mut.rs | 61 + .../borrowck-call-is-borrow-issue-12224.rs | 63 + ...borrowck-call-method-from-mut-aliasable.rs | 22 + .../rustc/ui/span/borrowck-fn-in-const-b.rs | 15 + .../span/borrowck-let-suggestion-suffixes.rs | 60 + .../ui/span/borrowck-object-mutability.rs | 27 + .../rustc/ui/span/borrowck-ref-into-rvalue.rs | 12 + .../rust/rustc/ui/span/coerce-suggestions.rs | 24 + .../rustc/ui/span/destructor-restrictions.rs | 12 + .../rust/rustc/ui/span/dropck-object-cycle.rs | 48 + .../rustc/ui/span/dropck_arr_cycle_checked.rs | 107 + .../ui/span/dropck_direct_cycle_with_drop.rs | 45 + .../rustc/ui/span/dropck_misc_variants.rs | 38 + .../rustc/ui/span/dropck_vec_cycle_checked.rs | 112 + .../ui/span/gated-features-attr-spans.rs | 8 + .../ui/span/impl-wrong-item-for-trait.rs | 41 + .../rust/rustc/ui/span/import-ty-params.rs | 21 + .../rust/rustc/ui/span/issue-11925.rs | 14 + .../rust/rustc/ui/span/issue-15480.rs | 13 + ...e-23338-locals-die-before-temps-of-body.rs | 29 + .../rust/rustc/ui/span/issue-23729.rs | 34 + .../rust/rustc/ui/span/issue-23827.rs | 34 + .../rust/rustc/ui/span/issue-24356.rs | 28 + .../rust/rustc/ui/span/issue-24690.rs | 17 + ...24805-dropck-child-has-items-via-parent.rs | 38 + .../issue-24805-dropck-trait-has-items.rs | 58 + .../ui/span/issue-24895-copy-clone-dropck.rs | 30 + .../rust/rustc/ui/span/issue-25199.rs | 75 + .../rust/rustc/ui/span/issue-26656.rs | 43 + .../rust/rustc/ui/span/issue-27522.rs | 10 + .../rust/rustc/ui/span/issue-29106.rs | 27 + .../rust/rustc/ui/span/issue-29595.rs | 8 + .../rust/rustc/ui/span/issue-33884.rs | 21 + .../rust/rustc/ui/span/issue-34264.rs | 12 + .../rust/rustc/ui/span/issue-35987.rs | 15 + .../rust/rustc/ui/span/issue-36530.rs | 13 + .../rust/rustc/ui/span/issue-36537.rs | 15 + .../rust/rustc/ui/span/issue-37767.rs | 42 + .../rust/rustc/ui/span/issue-39018.rs | 39 + .../rust/rustc/ui/span/issue-39698.rs | 17 + .../rust/rustc/ui/span/issue-40157.rs | 5 + .../span/issue-42234-unknown-receiver-type.rs | 18 + .../ui/span/issue-43927-non-ADT-derive.rs | 14 + .../rust/rustc/ui/span/issue-7575.rs | 76 + .../rustc/ui/span/issue28498-reject-ex1.rs | 38 + .../span/issue28498-reject-lifetime-param.rs | 37 + .../ui/span/issue28498-reject-passed-to-fn.rs | 39 + .../ui/span/issue28498-reject-trait-bound.rs | 39 + .../rust/rustc/ui/span/lint-unused-unsafe.rs | 57 + .../rustc/ui/span/macro-span-replacement.rs | 14 + .../rust/rustc/ui/span/macro-ty-params.rs | 14 + .../span/method-and-field-eager-resolution.rs | 16 + .../rustc/ui/span/missing-unit-argument.rs | 18 + .../rust/rustc/ui/span/move-closure.rs | 7 + .../rustc/ui/span/multiline-span-E0072.rs | 11 + .../rustc/ui/span/multiline-span-simple.rs | 21 + .../rustc/ui/span/multispan-import-lint.rs | 11 + .../rust/rustc/ui/span/mut-arg-hint.rs | 23 + .../rustc/ui/span/mut-ptr-cant-outlive-ref.rs | 16 + .../ui/span/non-existing-module-import.rs | 4 + .../rust/rustc/ui/span/pub-struct-field.rs | 11 + gcc/testsuite/rust/rustc/ui/span/range-2.rs | 16 + .../rustc/ui/span/recursive-type-field.rs | 19 + .../regionck-unboxed-closure-lifetimes.rs | 17 + .../regions-close-over-borrowed-ref-in-obj.rs | 17 + .../regions-close-over-type-parameter-2.rs | 28 + .../span/regions-escape-loop-via-variable.rs | 15 + .../ui/span/regions-escape-loop-via-vec.rs | 14 + .../regions-infer-borrow-scope-within-loop.rs | 23 + .../send-is-not-static-ensures-scoping.rs | 27 + .../ui/span/send-is-not-static-std-sync-2.rs | 40 + .../ui/span/send-is-not-static-std-sync.rs | 56 + .../rust/rustc/ui/span/slice-borrow.rs | 15 + .../rustc/ui/span/suggestion-non-ascii.rs | 5 + .../rust/rustc/ui/span/transitive-dep-span.rs | 16 + .../ui/span/type-annotations-needed-expr.rs | 4 + .../rust/rustc/ui/span/type-binding.rs | 10 + .../rust/rustc/ui/span/typo-suggestion.rs | 10 + .../unused-warning-point-at-identifier.rs | 31 + .../vec-must-not-hide-type-from-dropck.rs | 126 + .../ui/span/vec_refs_data_with_early_death.rs | 34 + .../rustc/ui/span/visibility-ty-params.rs | 14 + .../ui/span/wf-method-late-bound-regions.rs | 25 + .../ui/specialization/assoc-ty-graph-cycle.rs | 26 + .../auxiliary/cross_crates_defaults.rs | 41 + .../ui/specialization/auxiliary/go_trait.rs | 44 + .../auxiliary/specialization_cross_crate.rs | 73 + .../ui/specialization/cross-crate-defaults.rs | 42 + .../deafult-associated-type-bound-1.rs | 26 + .../deafult-associated-type-bound-2.rs | 23 + .../deafult-generic-associated-type-bound.rs | 28 + .../defaultimpl/allowed-cross-crate.rs | 27 + .../defaultimpl/auxiliary/go_trait.rs | 44 + .../defaultimpl/out-of-order.rs | 20 + .../defaultimpl/overlap-projection.rs | 26 + .../specialization/defaultimpl/projection.rs | 43 + .../specialization-feature-gate-default.rs | 12 + .../defaultimpl/specialization-no-default.rs | 78 + ...zation-trait-item-not-implemented-rpass.rs | 35 + ...ecialization-trait-item-not-implemented.rs | 24 + .../specialization-trait-not-implemented.rs | 25 + .../defaultimpl/specialization-wfcheck.rs | 11 + .../specialization/defaultimpl/validation.rs | 17 + .../rustc/ui/specialization/issue-36804.rs | 36 + .../rustc/ui/specialization/issue-38091-2.rs | 29 + .../rustc/ui/specialization/issue-38091.rs | 25 + .../rustc/ui/specialization/issue-39448.rs | 51 + .../rustc/ui/specialization/issue-39618.rs | 28 + .../rustc/ui/specialization/issue-44861.rs | 41 + .../rustc/ui/specialization/issue-50452.rs | 20 + .../rustc/ui/specialization/issue-52050.rs | 33 + .../rustc/ui/specialization/issue-59435.rs | 18 + .../specialization/issue-63716-parse-async.rs | 15 + .../rustc/ui/specialization/issue-70442.rs | 24 + .../auxiliary/specialization-trait.rs | 7 + .../dyn-trait-assoc-types.rs | 33 + .../min_specialization/impl-on-nonexisting.rs | 8 + .../impl_specialization_trait.rs | 17 + .../implcit-well-formed-bounds.rs | 31 + .../repeated_projection_type.rs | 25 + .../min_specialization/repeating_lifetimes.rs | 20 + .../min_specialization/repeating_param.rs | 18 + .../min_specialization/spec-iter.rs | 21 + .../min_specialization/spec-reference.rs | 20 + .../specialization_marker.rs | 18 + .../specialization_super_trait.rs | 19 + .../specialization_trait.rs | 27 + .../specialize_on_marker.rs | 25 + .../specialize_on_spec_trait.rs | 28 + .../specialize_on_static.rs | 19 + .../min_specialization/specialize_on_trait.rs | 21 + .../specialization/non-defaulted-item-fail.rs | 55 + .../soundness/partial_eq_range_inclusive.rs | 36 + .../soundness/partial_ord_slice.rs | 43 + .../specialization-allowed-cross-crate.rs | 27 + .../specialization-assoc-fns.rs | 30 + .../specialization/specialization-basics.rs | 99 + .../specialization-cross-crate-no-gate.rs | 22 + .../specialization-cross-crate.rs | 51 + .../specialization-default-methods.rs | 88 + .../specialization-default-projection.rs | 37 + .../specialization-default-types.rs | 36 + .../specialization-feature-gate-default.rs | 14 + .../specialization-feature-gate-overlap.rs | 18 + .../specialization-no-default.rs | 78 + .../specialization-on-projection.rs | 25 + .../specialization-out-of-order.rs | 20 + .../specialization-overlap-hygiene.rs | 24 + .../specialization-overlap-negative.rs | 12 + .../specialization-overlap-projection.rs | 26 + .../specialization/specialization-overlap.rs | 20 + .../specialization/specialization-polarity.rs | 18 + .../specialization-projection-alias.rs | 27 + .../specialization-projection.rs | 43 + .../specialization-super-traits.rs | 18 + ...on-translate-projections-with-lifetimes.rs | 34 + ...ation-translate-projections-with-params.rs | 33 + .../specialization-translate-projections.rs | 34 + gcc/testsuite/rust/rustc/ui/sse2.rs | 27 + .../auxiliary/stability_attribute_issue.rs | 10 + .../auxiliary/unstable_generic_param.rs | 230 + .../generics-default-stability-where.rs | 13 + .../generics-default-stability.rs | 265 + .../missing-const-stability.rs | 13 + .../missing-stability-attr-at-top-level.rs | 5 + .../stability-attribute-issue-43027.rs | 11 + .../stability-attribute-issue.rs | 13 + ...ity-attribute-non-staged-force-unstable.rs | 7 + .../stability-attribute-non-staged.rs | 5 + .../stability-attribute-sanity-2.rs | 18 + .../stability-attribute-sanity-3.rs | 13 + .../stability-attribute-sanity-4.rs | 30 + .../stability-attribute-sanity.rs | 73 + .../stability-attribute-trait-impl.rs | 29 + .../rustc/ui/stability-in-private-module.rs | 5 + gcc/testsuite/rust/rustc/ui/stable-addr-of.rs | 9 + .../rust/rustc/ui/stable-features.rs | 15 + .../rustc/ui/static/auxiliary/issue_24843.rs | 2 + .../auxiliary/static-priv-by-default.rs | 28 + .../auxiliary/static_priv_by_default.rs | 52 + .../rust/rustc/ui/static/issue-24843.rs | 9 + .../rust/rustc/ui/static/static-closures.rs | 5 + .../rust/rustc/ui/static/static-drop-scope.rs | 40 + .../rustc/ui/static/static-extern-type.rs | 28 + .../rustc/ui/static/static-items-cant-move.rs | 20 + .../rustc/ui/static/static-lifetime-bound.rs | 7 + .../rust/rustc/ui/static/static-lifetime.rs | 7 + .../rustc/ui/static/static-method-privacy.rs | 11 + .../rustc/ui/static/static-mut-bad-types.rs | 8 + .../static-mut-foreign-requires-unsafe.rs | 10 + .../ui/static/static-mut-not-constant.rs | 7 + .../rustc/ui/static/static-mut-not-pat.rs | 44 + .../ui/static/static-mut-requires-unsafe.rs | 8 + .../ui/static/static-priv-by-default2.rs | 31 + .../ui/static/static-reference-to-fn-1.rs | 25 + .../ui/static/static-reference-to-fn-2.rs | 55 + .../rustc/ui/static/static-region-bound.rs | 13 + .../static/static-vec-repeat-not-constant.rs | 7 + .../rust/rustc/ui/static_sized_requirement.rs | 13 + .../rust/rustc/ui/staticness-mismatch.rs | 12 + .../auxiliary/static-function-pointer-aux.rs | 5 + .../statics/auxiliary/static-methods-crate.rs | 30 + .../auxiliary/static_fn_inline_xc_aux.rs | 13 + .../auxiliary/static_fn_trait_xc_aux.rs | 12 + .../ui/statics/auxiliary/static_mut_xc.rs | 2 + .../rustc/ui/statics/static-fn-inline-xc.rs | 13 + .../rustc/ui/statics/static-fn-trait-xc.rs | 13 + .../ui/statics/static-function-pointer-xc.rs | 18 + .../ui/statics/static-function-pointer.rs | 17 + .../rust/rustc/ui/statics/static-impl.rs | 67 + ...tic-method-in-trait-with-tps-intracrate.rs | 29 + .../rustc/ui/statics/static-method-xcrate.rs | 14 + .../ui/statics/static-methods-in-traits.rs | 27 + .../ui/statics/static-methods-in-traits2.rs | 23 + .../rust/rustc/ui/statics/static-mut-xc.rs | 40 + .../rust/rustc/ui/statics/static-promotion.rs | 35 + .../rust/rustc/ui/statics/static-recursive.rs | 37 + .../rustc/ui/statics/uninhabited-static.rs | 18 + gcc/testsuite/rust/rustc/ui/std-backtrace.rs | 76 + .../rust/rustc/ui/std-uncopyable-atomics.rs | 17 + .../rust/rustc/ui/stdio-is-blocking.rs | 86 + .../rust/rustc/ui/stdout-during-shutdown.rs | 20 + .../rustc/ui/stmt_expr_attrs_no_feature.rs | 142 + .../rust/rustc/ui/str/str-array-assignment.rs | 12 + .../rust/rustc/ui/str/str-as-char.rs | 6 + .../rustc/ui/str/str-concat-on-double-ref.rs | 8 + gcc/testsuite/rust/rustc/ui/str/str-idx.rs | 8 + .../rustc/ui/str/str-lit-type-mismatch.rs | 6 + .../rust/rustc/ui/str/str-mut-idx.rs | 18 + .../rust/rustc/ui/str/str-overrun.rs | 11 + .../rust/rustc/ui/string-box-error.rs | 13 + .../rust/rustc/ui/struct-ctor-mangling.rs | 15 + .../rustc/ui/struct-literal-variant-in-if.rs | 26 + .../rust/rustc/ui/structs-enums/align-enum.rs | 55 + .../rustc/ui/structs-enums/align-struct.rs | 246 + .../ui/structs-enums/auxiliary/cci_class.rs | 15 + .../ui/structs-enums/auxiliary/cci_class_2.rs | 20 + .../ui/structs-enums/auxiliary/cci_class_3.rs | 20 + .../ui/structs-enums/auxiliary/cci_class_4.rs | 42 + .../ui/structs-enums/auxiliary/cci_class_6.rs | 26 + .../structs-enums/auxiliary/cci_class_cast.rs | 51 + .../auxiliary/cci_class_trait.rs | 6 + .../structs-enums/auxiliary/empty-struct.rs | 10 + .../auxiliary/namespaced_enum_emulate_flat.rs | 26 + .../auxiliary/namespaced_enums.rs | 11 + .../auxiliary/newtype_struct_xc.rs | 4 + .../struct_destructuring_cross_crate.rs | 7 + .../auxiliary/struct_variant_xc_aux.rs | 9 + .../auxiliary/xcrate_struct_aliases.rs | 7 + .../ui/structs-enums/borrow-tuple-fields.rs | 39 + .../class-cast-to-trait-cross-crate-2.rs | 21 + .../class-cast-to-trait-multiple-types.rs | 94 + .../ui/structs-enums/class-cast-to-trait.rs | 61 + .../rust/rustc/ui/structs-enums/class-dtor.rs | 26 + .../rustc/ui/structs-enums/class-exports.rs | 32 + .../class-impl-very-parameterized-trait.rs | 108 + .../class-implement-trait-cross-crate.rs | 60 + .../structs-enums/class-implement-traits.rs | 64 + .../structs-enums/class-method-cross-crate.rs | 14 + .../class-methods-cross-crate.rs | 15 + .../rustc/ui/structs-enums/class-methods.rs | 31 + .../class-poly-methods-cross-crate.rs | 17 + .../ui/structs-enums/class-poly-methods.rs | 38 + .../ui/structs-enums/class-separate-impl.rs | 66 + .../rustc/ui/structs-enums/class-str-field.rs | 22 + .../rustc/ui/structs-enums/class-typarams.rs | 33 + .../ui/structs-enums/classes-cross-crate.rs | 14 + .../structs-enums/classes-self-referential.rs | 21 + .../classes-simple-cross-crate.rs | 13 + .../ui/structs-enums/classes-simple-method.rs | 29 + .../rustc/ui/structs-enums/classes-simple.rs | 24 + .../rust/rustc/ui/structs-enums/classes.rs | 52 + .../codegen-tag-static-padding.rs | 60 + .../ui/structs-enums/compare-generic-enums.rs | 17 + .../structs-enums/discrim-explicit-23030.rs | 148 + .../ui/structs-enums/empty-struct-braces.rs | 214 + .../rust/rustc/ui/structs-enums/empty-tag.rs | 23 + .../rustc/ui/structs-enums/enum-alignment.rs | 25 + .../ui/structs-enums/enum-clike-ffi-as-int.rs | 34 + .../rust/rustc/ui/structs-enums/enum-discr.rs | 24 + .../structs-enums/enum-discrim-autosizing.rs | 54 + .../enum-discrim-manual-sizing.rs | 112 + .../enum-discrim-range-overflow.rs | 27 + .../structs-enums/enum-discrim-width-stuff.rs | 45 + .../ui/structs-enums/enum-disr-val-pretty.rs | 18 + .../structs-enums/enum-export-inheritance.rs | 16 + .../structs-enums/enum-layout-optimization.rs | 51 + .../enum-non-c-like-repr-c-and-int.rs | 174 + .../structs-enums/enum-non-c-like-repr-c.rs | 175 + .../structs-enums/enum-non-c-like-repr-int.rs | 170 + .../ui/structs-enums/enum-null-pointer-opt.rs | 75 + .../enum-nullable-const-null-with-fields.rs | 14 + .../enum-nullable-simplifycfg-misopt.rs | 18 + .../ui/structs-enums/enum-univariant-repr.rs | 52 + .../rustc/ui/structs-enums/enum-variants.rs | 19 + .../ui/structs-enums/enum-vec-initializer.rs | 18 + .../ui/structs-enums/export-abstract-tag.rs | 16 + .../ui/structs-enums/export-tag-variant.rs | 10 + .../rustc/ui/structs-enums/expr-if-struct.rs | 33 + .../ui/structs-enums/expr-match-struct.rs | 32 + .../structs-enums/field-destruction-order.rs | 48 + .../rustc/ui/structs-enums/foreign-struct.rs | 20 + .../ui/structs-enums/functional-struct-upd.rs | 13 + .../rust/rustc/ui/structs-enums/ivec-tag.rs | 23 + .../module-qualified-struct-destructure.rs | 15 + .../namespaced-enum-emulate-flat-xc.rs | 26 + .../namespaced-enum-emulate-flat.rs | 45 + .../namespaced-enum-glob-import-xcrate.rs | 27 + .../namespaced-enum-glob-import.rs | 36 + .../structs-enums/namespaced-enums-xcrate.rs | 17 + .../ui/structs-enums/namespaced-enums.rs | 18 + .../structs-enums/nested-enum-same-names.rs | 28 + .../structs-enums/newtype-struct-drop-run.rs | 22 + .../structs-enums/newtype-struct-with-dtor.rs | 21 + .../ui/structs-enums/newtype-struct-xc-2.rs | 16 + .../ui/structs-enums/newtype-struct-xc.rs | 11 + .../rustc/ui/structs-enums/nonzero-enum.rs | 31 + .../rustc/ui/structs-enums/numeric-fields.rs | 13 + ...object-lifetime-default-from-ref-struct.rs | 59 + ...bject-lifetime-default-from-rptr-struct.rs | 38 + .../rustc/ui/structs-enums/rec-align-u32.rs | 57 + .../rustc/ui/structs-enums/rec-align-u64.rs | 96 + .../rust/rustc/ui/structs-enums/rec-auto.rs | 15 + .../rust/rustc/ui/structs-enums/rec-extend.rs | 19 + .../rust/rustc/ui/structs-enums/rec-tup.rs | 32 + .../rust/rustc/ui/structs-enums/rec.rs | 25 + .../rust/rustc/ui/structs-enums/record-pat.rs | 20 + .../ui/structs-enums/resource-in-struct.rs | 38 + .../ui/structs-enums/simple-generic-tag.rs | 12 + .../structs-enums/simple-match-generic-tag.rs | 14 + .../ui/structs-enums/small-enum-range-edge.rs | 28 + .../structs-enums/small-enums-with-fields.rs | 34 + .../ui/structs-enums/struct-aliases-xcrate.rs | 26 + .../rustc/ui/structs-enums/struct-aliases.rs | 65 + .../struct-destructuring-cross-crate.rs | 13 + .../structs-enums/struct-field-shorthand.rs | 27 + .../struct-like-variant-construct.rs | 19 + .../struct-like-variant-match.rs | 34 + .../struct-lit-functional-no-fields.rs | 27 + .../ui/structs-enums/struct-literal-dtor.rs | 19 + .../structs-enums/struct-new-as-field-name.rs | 11 + .../structs-enums/struct-order-of-eval-1.rs | 17 + .../structs-enums/struct-order-of-eval-2.rs | 17 + .../structs-enums/struct-order-of-eval-3.rs | 38 + .../structs-enums/struct-order-of-eval-4.rs | 35 + .../ui/structs-enums/struct-partial-move-1.rs | 22 + .../ui/structs-enums/struct-partial-move-2.rs | 29 + .../struct-path-associated-type.rs | 28 + .../ui/structs-enums/struct-path-self.rs | 46 + .../structs-enums/struct-pattern-matching.rs | 19 + .../struct-variant-field-visibility.rs | 18 + .../ui/structs-enums/struct_variant_xc.rs | 12 + .../structs-enums/struct_variant_xc_match.rs | 15 + .../ui/structs-enums/tag-align-dyn-u64.rs | 30 + .../structs-enums/tag-align-dyn-variants.rs | 68 + .../rustc/ui/structs-enums/tag-align-shape.rs | 21 + .../rustc/ui/structs-enums/tag-align-u64.rs | 30 + .../ui/structs-enums/tag-disr-val-shape.rs | 21 + .../rustc/ui/structs-enums/tag-exports.rs | 22 + .../rustc/ui/structs-enums/tag-in-block.rs | 16 + .../tag-variant-disr-type-mismatch.rs | 13 + .../ui/structs-enums/tag-variant-disr-val.rs | 67 + .../rust/rustc/ui/structs-enums/tag.rs | 31 + .../structs-enums/tuple-struct-construct.rs | 9 + .../tuple-struct-constructor-pointer.rs | 13 + .../tuple-struct-destructuring.rs | 11 + .../ui/structs-enums/tuple-struct-matching.rs | 14 + .../ui/structs-enums/tuple-struct-trivial.rs | 9 + .../ui/structs-enums/uninstantiable-struct.rs | 5 + .../unit-like-struct-drop-run.rs | 24 + .../ui/structs-enums/unit-like-struct.rs | 10 + .../structs-enums/variant-structs-trivial.rs | 11 + .../structs/auxiliary/struct_field_privacy.rs | 10 + .../auxiliary/struct_variant_privacy.rs | 4 + .../rust/rustc/ui/structs/rhs-type.rs | 19 + .../ui/structs/struct-base-wrong-type.rs | 15 + .../ui/structs/struct-duplicate-comma.rs | 16 + .../rust/rustc/ui/structs/struct-field-cfg.rs | 19 + .../ui/structs/struct-field-init-syntax.rs | 21 + .../rustc/ui/structs/struct-field-privacy.rs | 39 + .../ui/structs/struct-fields-decl-dupe.rs | 9 + .../rustc/ui/structs/struct-fields-dupe.rs | 11 + .../ui/structs/struct-fields-hints-no-dupe.rs | 15 + .../rustc/ui/structs/struct-fields-hints.rs | 14 + .../rustc/ui/structs/struct-fields-missing.rs | 11 + .../struct-fields-shorthand-unresolved.rs | 13 + .../ui/structs/struct-fields-shorthand.rs | 12 + .../ui/structs/struct-fields-too-many.rs | 12 + .../rustc/ui/structs/struct-fields-typo.rs | 16 + .../rustc/ui/structs/struct-missing-comma.rs | 13 + .../ui/structs/struct-pat-derived-error.rs | 15 + .../ui/structs/struct-path-alias-bounds.rs | 12 + .../ui/structs/struct-path-associated-type.rs | 38 + .../structs/struct-path-self-type-mismatch.rs | 22 + .../rust/rustc/ui/structs/struct-path-self.rs | 38 + .../ui/structs/struct-variant-privacy-xc.rs | 11 + .../ui/structs/struct-variant-privacy.rs | 14 + .../structure-constructor-type-mismatch.rs | 74 + .../rust/rustc/ui/structured-compare.rs | 31 + gcc/testsuite/rust/rustc/ui/substs-ppaux.rs | 53 + .../rust/rustc/ui/suffixed-literal-meta.rs | 28 + .../adt-param-with-implicit-sized-bound.rs | 29 + .../rust/rustc/ui/suggestions/as-ref.rs | 26 + .../ui/suggestions/assoc-const-as-field.rs | 14 + .../assoc-type-in-method-return.rs | 8 + ...as-arg-where-it-should-have-been-called.rs | 14 + .../rustc/ui/suggestions/attribute-typos.rs | 12 + .../rustc/ui/suggestions/auxiliary/foo.rs | 4 + .../ui/suggestions/auxiliary/issue-61963-1.rs | 41 + .../ui/suggestions/auxiliary/issue-61963.rs | 42 + .../auxiliary/struct_field_privacy.rs | 10 + .../ui/suggestions/borrow-for-loop-head.rs | 11 + .../chain-method-call-mutation-in-place.rs | 5 + .../ui/suggestions/const-in-struct-pat.rs | 12 + .../rustc/ui/suggestions/const-no-type.rs | 52 + .../const-pat-non-exaustive-let-new-var.rs | 11 + .../rustc/ui/suggestions/constrain-trait.rs | 48 + ...-suggest-deref-inside-macro-issue-58298.rs | 15 + .../dont-suggest-ref/duplicate-suggestions.rs | 151 + .../dont-suggest-ref/move-into-closure.rs | 160 + .../ui/suggestions/dont-suggest-ref/simple.rs | 365 + .../dont-suggest-try_into-in-macros.rs | 4 + .../expected-boxed-future-isnt-pinned.rs | 37 + ...as-arg-where-it-should-have-been-called.rs | 21 + .../fn-missing-lifetime-in-item.rs | 9 + .../fn-needing-specified-return-type-param.rs | 6 + ...fn-or-tuple-struct-with-underscore-args.rs | 20 + .../fn-or-tuple-struct-without-args.rs | 48 + .../rustc/ui/suggestions/fn-trait-notation.rs | 20 + .../rust/rustc/ui/suggestions/for-i-in-vec.rs | 16 + .../rustc/ui/suggestions/format-borrow.rs | 7 + .../rust/rustc/ui/suggestions/if-let-typo.rs | 14 + ...-ref-trait-object-literal-bound-regions.rs | 19 + .../imm-ref-trait-object-literal.rs | 15 + .../ui/suggestions/imm-ref-trait-object.rs | 9 + ...t-static-bound-needing-more-suggestions.rs | 114 + ...on-dyn-trait-with-implicit-static-bound.rs | 113 + .../impl-trait-missing-lifetime.rs | 3 + .../impl-trait-return-trailing-semicolon.rs | 8 + .../impl-trait-with-missing-bounds.rs | 45 + ...-trait-with-missing-trait-bounds-in-arg.rs | 21 + .../rust/rustc/ui/suggestions/into-str.rs | 7 + .../rustc/ui/suggestions/invalid-bin-op.rs | 8 + .../rust/rustc/ui/suggestions/issue-21673.rs | 14 + ...issing-semicolon-between-call-and-tuple.rs | 9 + .../rust/rustc/ui/suggestions/issue-52820.rs | 13 + .../rust/rustc/ui/suggestions/issue-57672.rs | 15 + .../rust/rustc/ui/suggestions/issue-59819.rs | 36 + .../rust/rustc/ui/suggestions/issue-61226.rs | 7 + .../rust/rustc/ui/suggestions/issue-61963.rs | 26 + .../rust/rustc/ui/suggestions/issue-62843.rs | 6 + .../ui/suggestions/issue-64252-self-type.rs | 15 + .../issue-66968-suggest-sorted-words.rs | 5 + .../suggestions/issue-71394-no-from-impl.rs | 6 + .../rust/rustc/ui/suggestions/issue-72766.rs | 21 + ...s-style-comparison-op-separate-eq-token.rs | 6 + .../ui/suggestions/js-style-comparison-op.rs | 9 + .../let-binding-init-expr-as-ty.rs | 12 + .../missing-lifetimes-in-signature.rs | 111 + .../trait-object-nested-in-impl-trait.rs | 69 + .../rustc/ui/suggestions/match-ergonomics.rs | 42 + .../ui/suggestions/match-needing-semi.rs | 19 + .../match-prev-arm-needing-semi.rs | 58 + .../suggestions/method-missing-parentheses.rs | 6 + .../mismatched-types-numeric-from.rs | 4 + ...missing-assoc-fn-applicable-suggestions.rs | 19 + .../rustc/ui/suggestions/missing-assoc-fn.rs | 23 + .../missing-assoc-type-bound-restriction.rs | 22 + .../missing-lifetime-in-assoc-const-type.rs | 17 + .../suggestions/missing-lifetime-specifier.rs | 60 + .../ui/suggestions/missing-lt-for-hrtb.rs | 16 + .../suggestions/missing-trait-bound-for-op.rs | 8 + .../missing-trait-bounds-for-method-call.rs | 32 + .../ui/suggestions/missing-trait-item.rs | 17 + .../suggestions/mut-borrow-needed-by-trait.rs | 24 + .../ui/suggestions/mut-ref-reassignment.rs | 18 + .../ui/suggestions/no-extern-crate-in-type.rs | 8 + .../object-unsafe-trait-references-self.rs | 13 + .../object-unsafe-trait-should-use-self.rs | 17 + ...ect-unsafe-trait-should-use-where-sized.rs | 14 + .../rustc/ui/suggestions/opaque-type-error.rs | 25 + .../ui/suggestions/option-content-move.rs | 40 + .../ui/suggestions/option-content-move2.rs | 17 + .../rustc/ui/suggestions/path-by-value.rs | 7 + .../rust/rustc/ui/suggestions/path-display.rs | 8 + .../ui/suggestions/raw-name-use-suggestion.rs | 10 + .../recover-from-semicolon-trailing-item.rs | 17 + .../ui/suggestions/recover-invalid-float.rs | 11 + ...sing-turbofish-surrounding-angle-braket.rs | 11 + .../rustc/ui/suggestions/remove-as_str.rs | 22 + .../ui/suggestions/restrict-type-argument.rs | 32 + .../ui/suggestions/return-without-lifetime.rs | 11 + .../suggestions/struct-initializer-comma.rs | 16 + ...oc-fn-call-with-turbofish-through-deref.rs | 14 + .../suggest-assoc-fn-call-with-turbofish.rs | 12 + .../rust/rustc/ui/suggestions/suggest-box.rs | 9 + .../suggest-closure-return-type-1.rs | 4 + .../suggest-closure-return-type-2.rs | 4 + .../suggest-closure-return-type-3.rs | 4 + .../suggest-impl-trait-lifetime.rs | 19 + .../rustc/ui/suggestions/suggest-labels.rs | 17 + .../rustc/ui/suggestions/suggest-methods.rs | 31 + .../ui/suggestions/suggest-move-lifetimes.rs | 22 + .../ui/suggestions/suggest-move-types.rs | 92 + .../suggest-on-bare-closure-call.rs | 5 + .../ui/suggestions/suggest-private-fields.rs | 28 + .../rustc/ui/suggestions/suggest-ref-mut.rs | 31 + .../ui/suggestions/suggest-remove-refs-1.rs | 11 + .../ui/suggestions/suggest-remove-refs-2.rs | 11 + .../ui/suggestions/suggest-remove-refs-3.rs | 14 + .../ui/suggestions/suggest-split-at-mut.rs | 9 + .../suggest-std-when-using-type.rs | 8 + .../rustc/ui/suggestions/suggest-variants.rs | 19 + ...ing-associated-type-restriction-fixable.rs | 44 + ...ith-missing-associated-type-restriction.rs | 45 + .../type-ascription-instead-of-let.rs | 11 + .../type-ascription-instead-of-method.rs | 6 + .../type-ascription-instead-of-path-2.rs | 7 + .../type-ascription-instead-of-path.rs | 6 + .../type-ascription-instead-of-variant.rs | 6 + .../type-mismatch-struct-field-shorthand-2.rs | 10 + .../type-mismatch-struct-field-shorthand.rs | 13 + .../type-not-found-in-adt-field.rs | 10 + .../ui/suggestions/unused-closure-argument.rs | 21 + ...use-type-argument-instead-of-assoc-type.rs | 14 + .../ui/suggestions/vec-macro-in-pattern.rs | 9 + .../rust/rustc/ui/super-at-top-level.rs | 5 + .../rust/rustc/ui/super-fast-paren-parsing.rs | 26 + gcc/testsuite/rust/rustc/ui/super.rs | 17 + gcc/testsuite/rust/rustc/ui/supported-cast.rs | 207 + .../rust/rustc/ui/suppressed-error.rs | 9 + .../rust/rustc/ui/svh-add-nothing.rs | 15 + .../rust/rustc/ui/svh/auxiliary/svh-a-base.rs | 26 + .../ui/svh/auxiliary/svh-a-change-lit.rs | 26 + .../auxiliary/svh-a-change-significant-cfg.rs | 28 + .../svh/auxiliary/svh-a-change-trait-bound.rs | 26 + .../ui/svh/auxiliary/svh-a-change-type-arg.rs | 26 + .../ui/svh/auxiliary/svh-a-change-type-ret.rs | 26 + .../svh/auxiliary/svh-a-change-type-static.rs | 26 + .../rust/rustc/ui/svh/auxiliary/svh-b.rs | 14 + .../rustc/ui/svh/auxiliary/svh-uta-base.rs | 23 + .../svh/auxiliary/svh-uta-change-use-trait.rs | 23 + .../rust/rustc/ui/svh/auxiliary/svh-utb.rs | 13 + .../rust/rustc/ui/svh/svh-change-lit.rs | 15 + .../ui/svh/svh-change-significant-cfg.rs | 15 + .../rustc/ui/svh/svh-change-trait-bound.rs | 15 + .../rust/rustc/ui/svh/svh-change-type-arg.rs | 15 + .../rust/rustc/ui/svh/svh-change-type-ret.rs | 15 + .../rustc/ui/svh/svh-change-type-static.rs | 15 + .../rust/rustc/ui/svh/svh-use-trait.rs | 20 + gcc/testsuite/rust/rustc/ui/swap-1.rs | 11 + .../rust/rustc/ui/swap-overlapping.rs | 45 + .../rust/rustc/ui/switched-expectations.rs | 5 + .../rust/rustc/ui/symbol-names/basic.rs | 20 + .../symbol-names/const-generics-demangling.rs | 39 + .../rustc/ui/symbol-names/const-generics.rs | 88 + .../rust/rustc/ui/symbol-names/impl1.rs | 78 + .../rust/rustc/ui/symbol-names/impl2.rs | 17 + .../rust/rustc/ui/symbol-names/issue-60925.rs | 51 + .../rust/rustc/ui/symbol-names/issue-75326.rs | 59 + .../rust/rustc/ui/symbol-names/issue-76365.rs | 19 + .../rust/rustc/ui/syntax-extension-minor.rs | 15 + .../ui/syntax-trait-polarity-feature-gate.rs | 11 + .../rust/rustc/ui/syntax-trait-polarity.rs | 26 + .../rust/rustc/ui/synthetic-param.rs | 29 + .../ui/tag-that-dare-not-speak-its-name.rs | 17 + gcc/testsuite/rust/rustc/ui/tag-type-args.rs | 6 + .../rustc/ui/tag-variant-cast-non-nullary.rs | 21 + .../rust/rustc/ui/tag-variant-disr-dup.rs | 12 + .../rust/rustc/ui/tail-call-arg-leak.rs | 10 + gcc/testsuite/rust/rustc/ui/tail-cps.rs | 18 + gcc/testsuite/rust/rustc/ui/tail-direct.rs | 8 + gcc/testsuite/rust/rustc/ui/tail-typeck.rs | 8 + .../rust/rustc/ui/target-feature/gate.rs | 36 + .../ui/target-feature/invalid-attribute.rs | 99 + gcc/testsuite/rust/rustc/ui/tcp-stress.rs | 66 + .../rustc/ui/terminal-width/flag-human.rs | 10 + .../rust/rustc/ui/terminal-width/flag-json.rs | 10 + .../non-1-width-unicode-multiline-label.rs | 8 + .../non-whitespace-trimming-2.rs | 7 + .../non-whitespace-trimming-unicode.rs | 7 + .../terminal-width/non-whitespace-trimming.rs | 7 + .../terminal-width/whitespace-trimming-2.rs | 9 + .../ui/terminal-width/whitespace-trimming.rs | 7 + .../rust/rustc/ui/terminate-in-initializer.rs | 34 + gcc/testsuite/rust/rustc/ui/terr-in-field.rs | 18 + gcc/testsuite/rust/rustc/ui/terr-sorts.rs | 16 + ...est-allow-dead-extern-static-no-warning.rs | 12 + .../ui/test-attrs/auxiliary/test_macro.rs | 5 + .../rustc/ui/test-attrs/decl-macro-test.rs | 23 + .../test-attrs/inaccessible-test-modules.rs | 10 + .../ui/test-attrs/run-unexported-tests.rs | 13 + .../ui/test-attrs/test-allow-fail-attr.rs | 18 + .../test-attr-non-associated-functions.rs | 26 + .../ui/test-attrs/test-cant-be-shadowed.rs | 14 + ...e-verification-for-explicit-return-type.rs | 13 + .../ui/test-attrs/test-main-not-dead-attr.rs | 10 + .../rustc/ui/test-attrs/test-main-not-dead.rs | 7 + .../rust/rustc/ui/test-attrs/test-on-macro.rs | 14 + .../test-runner-hides-buried-main.rs | 16 + .../ui/test-attrs/test-runner-hides-main.rs | 6 + .../ui/test-attrs/test-runner-hides-start.rs | 8 + .../test-should-fail-good-message.rs | 15 + .../ui/test-attrs/test-should-panic-attr.rs | 37 + .../rustc/ui/test-attrs/test-vs-cfg-test.rs | 10 + .../ui/test-attrs/test-warns-dead-code.rs | 8 + gcc/testsuite/rust/rustc/ui/test-cfg.rs | 9 + .../rustc/ui/test-panic-abort-disabled.rs | 21 + .../rustc/ui/test-panic-abort-nocapture.rs | 41 + .../rust/rustc/ui/test-panic-abort.rs | 50 + .../rustc/ui/test-panic-while-printing.rs | 25 + .../rust/rustc/ui/test-thread-capture.rs | 32 + .../rust/rustc/ui/test-thread-nocapture.rs | 32 + .../rustc/ui/thin-lto-global-allocator.rs | 8 + .../rust/rustc/ui/thinlto/all-crates.rs | 9 + .../rust/rustc/ui/thinlto/auxiliary/dylib.rs | 7 + .../ui/thinlto/auxiliary/msvc-imp-present.rs | 12 + .../thinlto/auxiliary/thin-lto-inlines-aux.rs | 8 + .../rust/rustc/ui/thinlto/dylib-works.rs | 10 + .../rust/rustc/ui/thinlto/msvc-imp-present.rs | 23 + .../rust/rustc/ui/thinlto/thin-lto-inlines.rs | 31 + .../rustc/ui/thinlto/thin-lto-inlines2.rs | 29 + .../rust/rustc/ui/thinlto/weak-works.rs | 29 + .../rust/rustc/ui/thread-local-in-ctfe.rs | 24 + .../rust/rustc/ui/thread-local-mutation.rs | 19 + .../rustc/ui/thread-local-not-in-prelude.rs | 10 + .../auxiliary/thread-local-extern-static.rs | 11 + .../rust/rustc/ui/threads-sendsync/comm.rs | 23 + .../send-is-not-static-par-for.rs | 35 + .../ui/threads-sendsync/send-resource.rs | 40 + .../threads-sendsync/send-type-inference.rs | 20 + .../ui/threads-sendsync/send_str_hashmap.rs | 54 + .../ui/threads-sendsync/send_str_treemap.rs | 59 + .../ui/threads-sendsync/sendable-class.rs | 29 + .../ui/threads-sendsync/sendfn-is-a-block.rs | 12 + .../sendfn-spawn-with-fn-arg.rs | 24 + .../rustc/ui/threads-sendsync/spawn-fn.rs | 26 + .../rustc/ui/threads-sendsync/spawn-types.rs | 26 + .../rust/rustc/ui/threads-sendsync/spawn.rs | 11 + .../rust/rustc/ui/threads-sendsync/spawn2.rs | 32 + .../threads-sendsync/spawning-with-debug.rs | 16 + .../std-sync-right-kind-impls.rs | 17 + .../ui/threads-sendsync/sync-send-atomics.rs | 15 + .../ui/threads-sendsync/sync-send-in-std.rs | 26 + .../sync-send-iterators-in-libcollections.rs | 72 + .../sync-send-iterators-in-libcore.rs | 106 + .../rustc/ui/threads-sendsync/task-comm-0.rs | 31 + .../rustc/ui/threads-sendsync/task-comm-1.rs | 15 + .../rustc/ui/threads-sendsync/task-comm-10.rs | 34 + .../rustc/ui/threads-sendsync/task-comm-11.rs | 22 + .../rustc/ui/threads-sendsync/task-comm-12.rs | 30 + .../rustc/ui/threads-sendsync/task-comm-13.rs | 19 + .../rustc/ui/threads-sendsync/task-comm-14.rs | 37 + .../rustc/ui/threads-sendsync/task-comm-15.rs | 29 + .../rustc/ui/threads-sendsync/task-comm-16.rs | 112 + .../rustc/ui/threads-sendsync/task-comm-17.rs | 18 + .../rustc/ui/threads-sendsync/task-comm-3.rs | 64 + .../rustc/ui/threads-sendsync/task-comm-4.rs | 46 + .../rustc/ui/threads-sendsync/task-comm-5.rs | 18 + .../rustc/ui/threads-sendsync/task-comm-6.rs | 43 + .../rustc/ui/threads-sendsync/task-comm-7.rs | 60 + .../rustc/ui/threads-sendsync/task-comm-9.rs | 36 + .../ui/threads-sendsync/task-comm-chan-nil.rs | 14 + .../rustc/ui/threads-sendsync/task-life-0.rs | 15 + .../ui/threads-sendsync/task-spawn-barefn.rs | 19 + .../task-spawn-move-and-copy.rs | 26 + .../rustc/ui/threads-sendsync/task-stderr.rs | 38 + .../test-tasks-invalid-value.rs | 12 + .../thread-local-extern-static.rs | 28 + .../threads-sendsync/thread-local-syntax.rs | 23 + .../rust/rustc/ui/threads-sendsync/threads.rs | 17 + .../tls-dtors-are-run-in-a-static-binary.rs | 23 + .../ui/threads-sendsync/tls-init-on-init.rs | 45 + .../rustc/ui/threads-sendsync/tls-try-with.rs | 31 + gcc/testsuite/rust/rustc/ui/tls.rs | 15 + .../ui/tool-attributes/diagnostic_item.rs | 4 + .../ui/tool-attributes/diagnostic_item2.rs | 7 + .../ui/tool-attributes/diagnostic_item3.rs | 8 + .../tool-attributes-misplaced-1.rs | 19 + .../tool-attributes-misplaced-2.rs | 7 + .../tool-attributes-shadowing.rs | 5 + .../rust/rustc/ui/tool_attributes.rs | 14 + .../rust/rustc/ui/tool_lints-fail.rs | 9 + .../rust/rustc/ui/tool_lints-rpass.rs | 7 + gcc/testsuite/rust/rustc/ui/tool_lints.rs | 6 + .../rust/rustc/ui/tool_lints_2018_preview.rs | 8 + .../rust/rustc/ui/trace_macros-format.rs | 19 + .../rust/rustc/ui/trace_macros-gate.rs | 15 + gcc/testsuite/rust/rustc/ui/trailing-comma.rs | 36 + .../rustc/ui/trait-impl-bound-suggestions.rs | 21 + .../ui/trait-method-number-parameters.rs | 14 + .../ui/traits/anon-trait-static-method.rs | 16 + .../ui/traits/anon_trait_static_method_exe.rs | 13 + .../rustc/ui/traits/assignability-trait.rs | 48 + .../ui/traits/assoc_type_bound_with_struct.rs | 20 + .../astconv-cycle-between-trait-and-type.rs | 30 + .../ui/traits/augmented-assignments-trait.rs | 13 + .../auxiliary/anon_trait_static_method_lib.rs | 10 + .../rustc/ui/traits/auxiliary/crate_a1.rs | 10 + .../rustc/ui/traits/auxiliary/crate_a2.rs | 14 + .../rustc/ui/traits/auxiliary/go_trait.rs | 44 + .../rustc/ui/traits/auxiliary/trait_alias.rs | 14 + .../trait_bounds_on_structs_and_enums_xc.rs | 14 + .../auxiliary/trait_default_method_xc_aux.rs | 41 + .../trait_default_method_xc_aux_2.rs | 18 + .../trait_inheritance_auto_xc_2_aux.rs | 10 + .../trait_inheritance_auto_xc_aux.rs | 8 + .../trait_inheritance_overloading_xc.rs | 39 + .../ui/traits/auxiliary/trait_safety_lib.rs | 10 + .../ui/traits/auxiliary/trait_xc_call_aux.rs | 12 + .../rustc/ui/traits/auxiliary/traitimpl.rs | 8 + .../ui/traits/check-trait-object-bounds-1.rs | 15 + .../traits/check-trait-object-bounds-2-ok.rs | 16 + .../ui/traits/check-trait-object-bounds-2.rs | 16 + .../ui/traits/check-trait-object-bounds-3.rs | 21 + .../ui/traits/check-trait-object-bounds-4.rs | 18 + .../ui/traits/check-trait-object-bounds-5.rs | 28 + .../ui/traits/check-trait-object-bounds-6.rs | 25 + .../ui/traits/conservative_impl_trait.rs | 9 + .../rustc/ui/traits/cycle-cache-err-60010.rs | 75 + .../rustc/ui/traits/cycle-trait-type-trait.rs | 26 + .../default-method-supertrait-vtable.rs | 29 + .../rust/rustc/ui/traits/dyn-trait.rs | 18 + .../rust/rustc/ui/traits/fmt-pointer-trait.rs | 25 + .../rustc/ui/traits/impl-evaluation-order.rs | 40 + .../rustc/ui/traits/impl-implicit-trait.rs | 27 + .../traits/impl-inherent-prefer-over-trait.rs | 31 + .../impl_trait_as_trait_return_position.rs | 18 + .../infer-from-object-trait-issue-26952.rs | 27 + .../ui/traits/inherent-trait-method-order.rs | 26 + .../rust/rustc/ui/traits/issue-70944.rs | 24 + .../rust/rustc/ui/traits/issue-72410.rs | 19 + .../rust/rustc/ui/traits/issue-75627.rs | 7 + .../rust/rustc/ui/traits/issue-77982.rs | 41 + .../traits/kindck-owned-trait-contains-1.rs | 24 + .../rustc/ui/traits/multiple-trait-bounds.rs | 10 + .../negative-impls/auxiliary/foreign_trait.rs | 7 + .../feature-gate-negative_impls.rs | 4 + .../negated-auto-traits-error.rs | 69 + .../negated-auto-traits-rpass.rs | 22 + .../negative-impls/negative-default-impls.rs | 12 + .../negative-impls/negative-impls-basic.rs | 18 + .../negative-specializes-negative.rs | 14 + .../negative-specializes-positive-item.rs | 14 + .../negative-specializes-positive.rs | 15 + .../ui/traits/negative-impls/no-items.rs | 12 + .../pin-unsound-issue-66544-clone.rs | 27 + .../pin-unsound-issue-66544-derefmut.rs | 34 + .../positive-specializes-negative.rs | 10 + .../rely-on-negative-impl-in-coherence.rs | 22 + .../rustc/ui/traits/normalize-super-trait.rs | 38 + .../ui/traits/object-one-type-two-traits.rs | 34 + ...overlap-not-permitted-for-builtin-trait.rs | 11 + .../overlap-permitted-for-marker-traits.rs | 29 + .../traits/parameterized-trait-with-bounds.rs | 22 + .../ui/traits/principal-less-trait-objects.rs | 43 + .../reservation-impl-coherence-conflict.rs | 15 + .../reservation-impl-no-use.rs | 13 + .../reservation-impl-non-lattice-ok.rs | 60 + .../reservation-impls/reservation-impl-ok.rs | 29 + .../self-without-lifetime-constraint.rs | 54 + .../ui/traits/supertrait-default-generics.rs | 40 + .../rustc/ui/traits/syntax-trait-polarity.rs | 22 + .../rustc/ui/traits/trait-alias-ambiguous.rs | 25 + .../traits/trait-alias-import-cross-crate.rs | 15 + .../rustc/ui/traits/trait-alias-import.rs | 41 + .../trait-alias/auxiliary/trait_alias.rs | 4 + .../issue-60021-assoc-method-resolve.rs | 20 + .../issue-72415-assoc-const-resolve.rs | 15 + .../ui/traits/trait-alias/issue-75983.rs | 18 + .../traits/trait-alias/trait-alias-bounds.rs | 58 + .../trait-alias/trait-alias-cross-crate.rs | 18 + .../ui/traits/trait-alias/trait-alias-impl.rs | 8 + .../trait-alias/trait-alias-maybe-bound.rs | 30 + .../trait-alias/trait-alias-no-duplicates.rs | 127 + .../trait-alias-no-extra-traits.rs | 122 + .../trait-alias/trait-alias-object-fail.rs | 12 + .../trait-alias/trait-alias-object-wf.rs | 86 + .../traits/trait-alias/trait-alias-object.rs | 19 + .../trait-alias-only-maybe-bound.rs | 23 + .../trait-alias/trait-alias-syntax-fail.rs | 11 + .../traits/trait-alias/trait-alias-syntax.rs | 25 + .../ui/traits/trait-alias/trait-alias-wf.rs | 8 + .../ui/traits/trait-alias/trait-alias.rs | 9 + .../ui/traits/trait-as-struct-constructor.rs | 7 + .../rustc/ui/traits/trait-bounds-basic.rs | 26 + ...trait-bounds-impl-comparison-duplicates.rs | 17 + .../rustc/ui/traits/trait-bounds-in-arc.rs | 110 + .../traits/trait-bounds-not-on-bare-trait.rs | 13 + .../ui/traits/trait-bounds-not-on-struct.rs | 39 + ...rait-bounds-on-structs-and-enums-in-fns.rs | 21 + ...it-bounds-on-structs-and-enums-in-impls.rs | 26 + ...rait-bounds-on-structs-and-enums-locals.rs | 18 + ...trait-bounds-on-structs-and-enums-rpass.rs | 22 + ...rait-bounds-on-structs-and-enums-static.rs | 16 + .../trait-bounds-on-structs-and-enums-xc.rs | 15 + .../trait-bounds-on-structs-and-enums-xc1.rs | 16 + .../trait-bounds-on-structs-and-enums.rs | 44 + .../rustc/ui/traits/trait-bounds-recursion.rs | 21 + .../ui/traits/trait-bounds-same-crate-name.rs | 56 + .../rustc/ui/traits/trait-bounds-sugar.rs | 20 + .../rust/rustc/ui/traits/trait-bounds.rs | 31 + .../ui/traits/trait-cache-issue-18209.rs | 21 + .../ui/traits/trait-coercion-generic-bad.rs | 20 + .../traits/trait-coercion-generic-regions.rs | 20 + .../rustc/ui/traits/trait-coercion-generic.rs | 26 + .../rust/rustc/ui/traits/trait-coercion.rs | 37 + .../ui/traits/trait-composition-trivial.rs | 13 + .../rustc/ui/traits/trait-copy-guessing.rs | 39 + .../trait-default-method-bound-subst.rs | 19 + .../trait-default-method-bound-subst2.rs | 17 + .../trait-default-method-bound-subst3.rs | 18 + .../trait-default-method-bound-subst4.rs | 20 + .../ui/traits/trait-default-method-bound.rs | 17 + .../ui/traits/trait-default-method-xc-2.rs | 27 + .../ui/traits/trait-default-method-xc.rs | 82 + .../ui/traits/trait-duplicate-methods.rs | 7 + ...se-ambiguity-where-clause-builtin-bound.rs | 17 + .../rust/rustc/ui/traits/trait-generic.rs | 46 + .../rust/rustc/ui/traits/trait-impl-1.rs | 17 + .../rust/rustc/ui/traits/trait-impl-2.rs | 20 + ...rait-impl-can-not-have-untraitful-items.rs | 10 + .../traits/trait-impl-different-num-params.rs | 13 + .../rustc/ui/traits/trait-impl-for-module.rs | 12 + .../ui/traits/trait-impl-method-mismatch.rs | 14 + ...upertrait-has-wrong-lifetime-parameters.rs | 32 + .../rust/rustc/ui/traits/trait-impl.rs | 42 + .../ui/traits/trait-inheritance-auto-xc-2.rs | 24 + .../ui/traits/trait-inheritance-auto-xc.rs | 26 + .../rustc/ui/traits/trait-inheritance-auto.rs | 30 + .../trait-inheritance-call-bound-inherited.rs | 21 + ...trait-inheritance-call-bound-inherited2.rs | 24 + ...ritance-cast-without-call-to-supertrait.rs | 34 + .../rustc/ui/traits/trait-inheritance-cast.rs | 34 + .../trait-inheritance-cross-trait-call-xc.rs | 21 + .../trait-inheritance-cross-trait-call.rs | 20 + .../ui/traits/trait-inheritance-diamond.rs | 29 + .../trait-inheritance-multiple-inheritors.rs | 24 + .../trait-inheritance-multiple-params.rs | 27 + .../rustc/ui/traits/trait-inheritance-num.rs | 14 + .../rustc/ui/traits/trait-inheritance-num0.rs | 25 + .../rustc/ui/traits/trait-inheritance-num1.rs | 16 + .../rustc/ui/traits/trait-inheritance-num2.rs | 87 + .../rustc/ui/traits/trait-inheritance-num3.rs | 20 + .../rustc/ui/traits/trait-inheritance-num5.rs | 27 + .../trait-inheritance-overloading-simple.rs | 28 + .../trait-inheritance-overloading-xc-exe.rs | 21 + .../traits/trait-inheritance-overloading.rs | 48 + .../trait-inheritance-self-in-supertype.rs | 63 + .../rustc/ui/traits/trait-inheritance-self.rs | 30 + .../ui/traits/trait-inheritance-simple.rs | 25 + .../ui/traits/trait-inheritance-static.rs | 27 + .../ui/traits/trait-inheritance-static2.rs | 30 + .../ui/traits/trait-inheritance-subst.rs | 28 + .../ui/traits/trait-inheritance-subst2.rs | 38 + .../ui/traits/trait-inheritance-visibility.rs | 21 + .../rustc/ui/traits/trait-inheritance2.rs | 27 + .../ui/traits/trait-item-inside-macro.rs | 31 + .../rustc/ui/traits/trait-item-privacy.rs | 135 + .../ui/traits/trait-matching-lifetimes.rs | 21 + .../rustc/ui/traits/trait-method-private.rs | 21 + .../traits/trait-object-auto-dedup-in-impl.rs | 20 + .../ui/traits/trait-object-auto-dedup.rs | 47 + .../ui/traits/trait-object-bounds-cycle-1.rs | 25 + .../ui/traits/trait-object-bounds-cycle-2.rs | 29 + .../ui/traits/trait-object-bounds-cycle-3.rs | 26 + .../ui/traits/trait-object-bounds-cycle-4.rs | 26 + .../rustc/ui/traits/trait-object-exclusion.rs | 20 + .../rustc/ui/traits/trait-object-generics.rs | 44 + .../ui/traits/trait-object-lifetime-first.rs | 14 + .../ui/traits/trait-object-macro-matcher.rs | 13 + .../rustc/ui/traits/trait-object-safety.rs | 18 + .../trait-object-supertrait-lifetime-bound.rs | 17 + .../ui/traits/trait-object-vs-lifetime-2.rs | 12 + .../ui/traits/trait-object-vs-lifetime.rs | 18 + .../trait-object-with-lifetime-bound.rs | 35 + ...ject-with-self-in-projection-output-bad.rs | 51 + ...ect-with-self-in-projection-output-good.rs | 29 + ...n-projection-output-repeated-supertrait.rs | 52 + .../ui/traits/trait-or-new-type-instead.rs | 7 + ...trait-param-without-lifetime-constraint.rs | 21 + .../rust/rustc/ui/traits/trait-privacy.rs | 25 + .../ui/traits/trait-region-pointer-simple.rs | 22 + .../trait-resolution-in-overloaded-op.rs | 12 + .../rustc/ui/traits/trait-safety-fn-body.rs | 17 + .../ui/traits/trait-safety-inherent-impl.rs | 10 + .../rustc/ui/traits/trait-safety-ok-cc.rs | 25 + .../rust/rustc/ui/traits/trait-safety-ok.rs | 19 + .../ui/traits/trait-safety-trait-impl-cc.rs | 16 + .../ui/traits/trait-safety-trait-impl.rs | 19 + .../trait-static-method-generic-inference.rs | 29 + .../traits/trait-static-method-overwriting.rs | 35 + .../trait-suggest-deferences-issue-39029.rs | 19 + .../trait-suggest-deferences-issue-62530.rs | 16 + .../trait-suggest-deferences-multiple-0.rs | 37 + .../trait-suggest-deferences-multiple-1.rs | 55 + .../ui/traits/trait-suggest-where-clause.rs | 37 + .../rust/rustc/ui/traits/trait-test-2.rs | 15 + .../rust/rustc/ui/traits/trait-test.rs | 7 + .../rust/rustc/ui/traits/trait-to-str.rs | 37 + .../ui/traits/trait-where-clause-vs-impl.rs | 46 + .../ui/traits/trait-with-bounds-default.rs | 33 + .../rust/rustc/ui/traits/trait-with-dst.rs | 23 + .../traits-assoc-type-in-supertrait-bad.rs | 17 + .../traits/traits-assoc-type-in-supertrait.rs | 24 + .../ui/traits/traits-conditional-dispatch.rs | 36 + .../ui/traits/traits-conditional-model-fn.rs | 54 + .../ui/traits/traits-default-method-macro.rs | 21 + .../ui/traits/traits-default-method-mut.rs | 12 + .../ui/traits/traits-default-method-self.rs | 19 + .../traits/traits-default-method-trivial.rs | 22 + .../ui/traits/traits-elaborate-type-region.rs | 50 + .../traits-impl-object-overlap-issue-23853.rs | 19 + .../traits-inductive-overflow-lifetime.rs | 31 + .../traits-inductive-overflow-simultaneous.rs | 21 + ...its-inductive-overflow-supertrait-oibit.rs | 19 + .../traits-inductive-overflow-supertrait.rs | 16 + .../traits-inductive-overflow-two-traits.rs | 23 + .../rustc/ui/traits/traits-issue-22019.rs | 35 + .../rustc/ui/traits/traits-issue-22110.rs | 28 + .../rustc/ui/traits/traits-issue-22655.rs | 24 + .../ui/traits/traits-issue-23003-overflow.rs | 30 + .../rustc/ui/traits/traits-issue-23003.rs | 33 + .../rustc/ui/traits/traits-issue-26339.rs | 32 + .../rustc/ui/traits/traits-issue-71136.rs | 9 + .../ui/traits/traits-multidispatch-bad.rs | 23 + ...traits-multidispatch-convert-ambig-dest.rs | 31 + ...aits-multidispatch-infer-convert-target.rs | 37 + .../traits-repeated-supertrait-ambig.rs | 44 + .../ui/traits/traits-repeated-supertrait.rs | 49 + .../traits-static-outlives-a-where-clause.rs | 24 + .../rust/rustc/ui/traits/ufcs-trait-object.rs | 18 + .../rustc/ui/traits/use-trait-before-def.rs | 11 + .../ui/traits/wf-trait-object-maybe-bound.rs | 19 + .../traits/wf-trait-object-no-duplicates.rs | 34 + .../wf-trait-object-only-maybe-bound.rs | 8 + .../traits/wf-trait-object-reverse-order.rs | 16 + .../rustc/ui/transmute-equal-assoc-types.rs | 10 + .../transmute-non-immediate-to-immediate.rs | 12 + .../rust/rustc/ui/transmute-specialization.rs | 16 + gcc/testsuite/rust/rustc/ui/transmute/main.rs | 30 + .../ui/transmute/transmute-different-sizes.rs | 32 + .../ui/transmute/transmute-fat-pointers.rs | 34 + .../transmute-from-fn-item-types-error.rs | 61 + .../rust/rustc/ui/transmute/transmute-impl.rs | 26 + .../ui/transmute/transmute-imut-to-mut.rs | 9 + .../ui/transmute/transmute-type-parameters.rs | 45 + ...ounds-inconsistent-associated-functions.rs | 24 + ...ivial-bounds-inconsistent-copy-reborrow.rs | 14 + .../trivial-bounds-inconsistent-copy.rs | 34 + ...al-bounds-inconsistent-projection-error.rs | 24 + .../trivial-bounds-inconsistent-projection.rs | 59 + .../trivial-bounds-inconsistent-sized.rs | 28 + ...trivial-bounds-inconsistent-well-formed.rs | 15 + .../trivial-bounds-inconsistent.rs | 75 + .../trivial-bounds-leak-copy.rs | 13 + .../ui/trivial-bounds/trivial-bounds-leak.rs | 32 + .../ui/trivial-bounds/trivial-bounds-lint.rs | 41 + .../trivial-bounds/trivial-bounds-object.rs | 19 + .../rust/rustc/ui/trivial-message.rs | 17 + .../rust/rustc/ui/trivial_casts-rpass.rs | 63 + gcc/testsuite/rust/rustc/ui/trivial_casts.rs | 86 + gcc/testsuite/rust/rustc/ui/try-block.rs | 76 + .../ui/try-block/try-block-bad-lifetime.rs | 38 + .../rustc/ui/try-block/try-block-bad-type.rs | 23 + .../rustc/ui/try-block/try-block-catch.rs | 11 + .../ui/try-block/try-block-in-edition2015.rs | 11 + .../rustc/ui/try-block/try-block-in-match.rs | 12 + .../rustc/ui/try-block/try-block-in-return.rs | 13 + .../rustc/ui/try-block/try-block-in-while.rs | 9 + .../try-block/try-block-maybe-bad-lifetime.rs | 45 + .../rustc/ui/try-block/try-block-opt-init.rs | 17 + .../ui/try-block/try-block-type-error.rs | 19 + .../try-block-unreachable-code-lint.rs | 77 + .../ui/try-block/try-block-unused-delims.rs | 30 + .../rustc/ui/try-from-int-error-partial-eq.rs | 13 + .../rustc/ui/try-is-identifier-edition2015.rs | 12 + .../rust/rustc/ui/try-macro-suggestion.rs | 10 + .../rustc/ui/try-on-option-diagnostics.rs | 48 + gcc/testsuite/rust/rustc/ui/try-on-option.rs | 16 + .../rust/rustc/ui/try-operator-custom.rs | 64 + .../rust/rustc/ui/try-operator-hygiene.rs | 27 + .../rust/rustc/ui/try-operator-on-main.rs | 26 + gcc/testsuite/rust/rustc/ui/try-operator.rs | 194 + gcc/testsuite/rust/rustc/ui/try-poll.rs | 51 + gcc/testsuite/rust/rustc/ui/try-wait.rs | 62 + gcc/testsuite/rust/rustc/ui/tup.rs | 22 + .../rust/rustc/ui/tuple-index-fat-types.rs | 14 + gcc/testsuite/rust/rustc/ui/tuple-index.rs | 33 + .../rust/rustc/ui/tuple/index-float.rs | 11 + .../rust/rustc/ui/tuple/index-invalid.rs | 8 + .../rust/rustc/ui/tuple/indexing-in-macro.rs | 10 + .../rust/rustc/ui/tuple/nested-index.rs | 13 + .../rustc/ui/tuple/tuple-arity-mismatch.rs | 18 + .../rustc/ui/tuple/tuple-index-not-tuple.rs | 11 + .../ui/tuple/tuple-index-out-of-bounds.rs | 15 + .../ui/tuple/tuple-struct-fields/test.rs | 10 + .../ui/tuple/tuple-struct-fields/test2.rs | 16 + .../ui/tuple/tuple-struct-fields/test3.rs | 16 + .../ui/tutorial-suffix-inference-test.rs | 25 + gcc/testsuite/rust/rustc/ui/tydesc-name.rs | 15 + .../enum-variant-generic-args-pass.rs | 60 + .../enum-variant-generic-args.rs | 106 + ...ant-priority-higher-than-other-inherent.rs | 24 + ...riority-lint-ambiguous_associated_items.rs | 39 + ...t-variant-form-through-Self-issue-58006.rs | 15 + ...rrect-variant-form-through-alias-caught.rs | 22 + .../type-alias-enum-variants/issue-57866.rs | 25 + .../issue-61801-path-pattern-can-infer.rs | 29 + ...63151-dead-code-lint-fields-in-patterns.rs | 27 + ...ype-application-on-aliased-enum-variant.rs | 15 + ...num-variant-in-type-namespace-and-error.rs | 12 + .../self-in-enum-definition.rs | 9 + .../type-alias-enum-variants-pass.rs | 70 + .../type-alias-impl-trait/assoc-type-const.rs | 35 + .../assoc-type-lifetime-unconstrained.rs | 27 + .../assoc-type-lifetime.rs | 27 + .../associated-type-alias-impl-trait.rs | 27 + .../auxiliary/cross_crate_ice.rs | 12 + .../auxiliary/cross_crate_ice2.rs | 22 + .../auxiliary/foreign-crate.rs | 3 + .../type-alias-impl-trait/bound_reduction.rs | 21 + .../type-alias-impl-trait/bound_reduction2.rs | 19 + .../bounds-are-checked-2.rs | 20 + .../bounds-are-checked.rs | 26 + .../ui/type-alias-impl-trait/coherence.rs | 18 + .../type-alias-impl-trait/cross_crate_ice.rs | 17 + .../type-alias-impl-trait/cross_crate_ice2.rs | 12 + .../declared_but_never_defined.rs | 7 + .../declared_but_not_defined_in_scope.rs | 14 + .../different_defining_uses.rs | 15 + .../different_defining_uses_never_type.rs | 19 + .../different_defining_uses_never_type2.rs | 45 + .../ui/type-alias-impl-trait/fallback.rs | 29 + .../generic_different_defining_uses.rs | 14 + .../generic_duplicate_lifetime_param.rs | 10 + .../generic_duplicate_param_use.rs | 27 + .../generic_duplicate_param_use10.rs | 13 + .../generic_duplicate_param_use2.rs | 18 + .../generic_duplicate_param_use3.rs | 22 + .../generic_duplicate_param_use4.rs | 18 + .../generic_duplicate_param_use5.rs | 20 + .../generic_duplicate_param_use6.rs | 19 + .../generic_duplicate_param_use7.rs | 25 + .../generic_duplicate_param_use8.rs | 18 + .../generic_duplicate_param_use9.rs | 24 + .../generic_lifetime_param.rs | 12 + .../generic_nondefining_use.rs | 28 + .../type-alias-impl-trait/generic_not_used.rs | 12 + .../generic_type_does_not_live_long_enough.rs | 17 + .../generic_underconstrained.rs | 14 + .../generic_underconstrained2.rs | 22 + .../impl-with-unconstrained-param.rs | 18 + .../incoherent-assoc-imp-trait.rs | 17 + .../issue-52843-closure-constrain.rs | 14 + .../ui/type-alias-impl-trait/issue-52843.rs | 16 + .../ui/type-alias-impl-trait/issue-53096.rs | 10 + .../ui/type-alias-impl-trait/issue-53598.rs | 30 + .../issue-53678-generator-and-const-fn.rs | 20 + .../issue-55099-lifetime-inference.rs | 29 + .../issue-57188-associate-impl-capture.rs | 25 + .../issue-57611-trait-alias.rs | 32 + .../ui/type-alias-impl-trait/issue-57700.rs | 24 + .../issue-57807-associated-type.rs | 32 + .../ui/type-alias-impl-trait/issue-58887.rs | 23 + .../ui/type-alias-impl-trait/issue-58951.rs | 14 + .../ui/type-alias-impl-trait/issue-60371.rs | 18 + .../ui/type-alias-impl-trait/issue-60407.rs | 16 + .../ui/type-alias-impl-trait/issue-60564.rs | 26 + ...ue-62000-associate-impl-trait-lifetimes.rs | 39 + .../issue-63263-closure-return.rs | 14 + .../ui/type-alias-impl-trait/issue-63279.rs | 12 + .../issue-63677-type-alias-coherence.rs | 22 + ...sue-65679-inst-opaque-ty-from-val-twice.rs | 19 + .../ui/type-alias-impl-trait/issue-65918.rs | 52 + .../issue-66580-closure-coherence.rs | 20 + .../issue-67844-nested-opaque.rs | 33 + .../issue-68368-non-defining-use.rs | 14 + ...ssue-69136-inner-lifetime-resolve-error.rs | 23 + .../issue-69136-inner-lifetime-resolve-ok.rs | 24 + .../ui/type-alias-impl-trait/issue-70121.rs | 24 + .../ui/type-alias-impl-trait/issue-74244.rs | 21 + .../ui/type-alias-impl-trait/issue-74761.rs | 17 + .../issue-76202-trait-impl-for-tait.rs | 24 + .../nested_type_alias_impl_trait.rs | 21 + .../never_reveal_concrete_type.rs | 16 + .../no_inferrable_concrete_type.rs | 14 + .../no_revealing_outside_defining_module.rs | 25 + .../not_a_defining_use.rs | 39 + .../type-alias-impl-trait/not_well_formed.rs | 19 + .../type-alias-impl-trait/private_unused.rs | 14 + .../structural-match-no-leak.rs | 21 + .../type-alias-impl-trait/structural-match.rs | 22 + .../type-alias-impl-trait-const.rs | 21 + .../type-alias-impl-trait-fns.rs | 28 + .../type-alias-impl-trait-sized.rs | 18 + .../type-alias-impl-trait-tuple.rs | 34 + ...alias-impl-trait-unconstrained-lifetime.rs | 19 + .../type-alias-impl-trait-with-cycle-error.rs | 13 + ...type-alias-impl-trait-with-cycle-error2.rs | 17 + .../type-alias-impl-trait-with-no-traits.rs | 15 + .../type-alias-impl-trait.rs | 90 + .../type-alias-nested-impl-trait.rs | 15 + .../unused_generic_param.rs | 23 + .../ui/type-alias/issue-62263-self-in-atb.rs | 9 + .../type-alias/issue-62305-self-assoc-ty.rs | 5 + .../ui/type-alias/issue-62364-self-ty-arg.rs | 9 + .../rust/rustc/ui/type-ascription.rs | 40 + .../rust/rustc/ui/type-id-higher-rank-2.rs | 32 + .../rust/rustc/ui/type-id-higher-rank.rs | 73 + .../rust/rustc/ui/type-in-nested-module.rs | 18 + .../rustc/ui/type-infer-generalize-ty-var.rs | 57 + .../or_else-multiple-type-params.rs | 11 + .../rustc/ui/type-inference/sort_by_key.rs | 6 + .../unbounded-associated-type.rs | 17 + ...ounded-type-param-in-fn-with-assoc-type.rs | 10 + .../unbounded-type-param-in-fn.rs | 8 + gcc/testsuite/rust/rustc/ui/type-namespace.rs | 8 + .../rust/rustc/ui/type-param-constraints.rs | 40 + gcc/testsuite/rust/rustc/ui/type-param.rs | 12 + .../rust/rustc/ui/type-params-in-for-each.rs | 24 + gcc/testsuite/rust/rustc/ui/type-ptr.rs | 11 + gcc/testsuite/rust/rustc/ui/type-sizes.rs | 174 + .../rust/rustc/ui/type-use-i1-versus-i8.rs | 13 + .../rustc/ui/type/ascription/issue-34255-1.rs | 16 + .../rustc/ui/type/ascription/issue-47666.rs | 5 + .../rustc/ui/type/ascription/issue-54516.rs | 8 + .../rustc/ui/type/ascription/issue-60933.rs | 6 + .../rust/rustc/ui/type/auxiliary/crate_a1.rs | 12 + .../rust/rustc/ui/type/auxiliary/crate_a2.rs | 8 + ...67690-type-alias-bound-diagnostic-crash.rs | 9 + .../rust/rustc/ui/type/type-alias-bounds.rs | 60 + .../rustc/ui/type/type-annotation-needed.rs | 10 + .../rustc/ui/type/type-arg-out-of-scope.rs | 6 + .../type-ascription-instead-of-initializer.rs | 5 + ...ype-ascription-instead-of-statement-end.rs | 11 + .../ui/type/type-ascription-precedence.rs | 55 + .../ui/type/type-ascription-soundness.rs | 14 + .../ui/type/type-ascription-with-fn-call.rs | 10 + .../rust/rustc/ui/type/type-check-defaults.rs | 28 + .../type-check/assignment-expected-bool.rs | 35 + .../ui/type/type-check/assignment-in-if.rs | 44 + .../type-check/cannot_infer_local_or_array.rs | 4 + .../type-check/cannot_infer_local_or_vec.rs | 5 + .../cannot_infer_local_or_vec_in_tuples.rs | 5 + .../rustc/ui/type/type-check/issue-22897.rs | 6 + .../rustc/ui/type/type-check/issue-40294.rs | 14 + .../rustc/ui/type/type-check/issue-41314.rs | 11 + ...ment-match-prior-arm-bool-expected-unit.rs | 28 + .../ui/type/type-check/missing_trait_impl.rs | 11 + .../type-check/unknown_type_for_closure.rs | 4 + .../ui/type/type-dependent-def-issue-49241.rs | 6 + .../rustc/ui/type/type-error-break-tail.rs | 9 + .../rustc/ui/type/type-mismatch-multiple.rs | 8 + .../ui/type/type-mismatch-same-crate-name.rs | 28 + .../rust/rustc/ui/type/type-mismatch.rs | 79 + ...rameter-defaults-referencing-Self-ppaux.rs | 18 + ...ype-parameter-defaults-referencing-Self.rs | 14 + .../rustc/ui/type/type-parameter-names.rs | 13 + .../type/type-params-in-different-spaces-1.rs | 19 + .../type/type-params-in-different-spaces-2.rs | 22 + .../type/type-params-in-different-spaces-3.rs | 8 + .../rustc/ui/type/type-path-err-node-types.rs | 27 + .../rust/rustc/ui/type/type-recursive.rs | 7 + .../rust/rustc/ui/type/type-shadow.rs | 9 + .../rust/rustc/ui/type_length_limit.rs | 28 + .../ui/typeck-closure-to-unsafe-fn-ptr.rs | 10 + .../rustc/ui/typeck-fn-to-unsafe-fn-ptr.rs | 13 + .../typeck/auxiliary/tdticc_coherence_lib.rs | 7 + ...-52082-type-param-shadows-existing-type.rs | 55 + ...10-must-typeck-match-pats-before-guards.rs | 24 + ...issue-57673-ice-on-deref-of-boxed-trait.rs | 8 + .../rust/rustc/ui/typeck/issue-67971.rs | 10 + .../issue-68590-reborrow-through-derefmut.rs | 26 + ...ice-on-invalid-type-node-after-recovery.rs | 10 + ...issue-72225-call-fnmut-through-derefmut.rs | 22 + .../issue-73592-borrow_mut-through-deref.rs | 60 + .../rust/rustc/ui/typeck/issue-74933.rs | 39 + .../typeck-builtin-bound-type-parameters.rs | 20 + .../ui/typeck/typeck-cast-pointer-to-float.rs | 6 + .../typeck-default-trait-impl-assoc-type.rs | 18 + ...efault-trait-impl-cross-crate-coherence.rs | 25 + ...typeck-default-trait-impl-negation-send.rs | 22 + ...typeck-default-trait-impl-negation-sync.rs | 42 + .../typeck-default-trait-impl-send-param.rs | 12 + .../ui/typeck/typeck-unsafe-always-share.rs | 33 + .../ui/typeck/typeck_type_placeholder_item.rs | 211 + .../typeck_type_placeholder_item_help.rs | 30 + .../typeck_type_placeholder_lifetime_1.rs | 12 + .../typeck_type_placeholder_lifetime_2.rs | 12 + .../typeck_type_placeholder_mismatch.rs | 28 + .../rustc/ui/typeck_type_placeholder_1.rs | 33 + .../rustc/ui/typeclasses-eq-example-static.rs | 70 + .../rust/rustc/ui/typeclasses-eq-example.rs | 66 + .../rust/rustc/ui/typeid-intrinsic.rs | 98 + .../rust/rustc/ui/typestate-cfg-nesting.rs | 21 + .../rust/rustc/ui/typestate-multi-decl.rs | 8 + .../rust/rustc/ui/ufcs-polymorphic-paths.rs | 155 + .../rust/rustc/ui/ufcs-type-params.rs | 16 + .../rustc/ui/ufcs/ufcs-explicit-self-bad.rs | 60 + .../rustc/ui/ufcs/ufcs-partially-resolved.rs | 57 + .../ui/ufcs/ufcs-qpath-missing-params.rs | 17 + .../rustc/ui/ufcs/ufcs-qpath-self-mismatch.rs | 11 + .../rust/rustc/ui/ui-testing-optout.rs | 95 + .../rustc/ui/unary-minus-suffix-inference.rs | 24 + .../auxiliary/unboxed-closures-cross-crate.rs | 17 + .../rustc/ui/unboxed-closures/issue-30906.rs | 19 + .../rustc/ui/unboxed-closures/issue-53448.rs | 16 + .../unboxed-closure-feature-gate.rs | 21 + .../unboxed-closure-illegal-move.rs | 39 + .../unboxed-closure-immutable-capture.rs | 18 + .../unboxed-closure-no-cyclic-sig.rs | 10 + .../unboxed-closure-region.rs | 12 + .../unboxed-closure-sugar-default.rs | 29 + .../unboxed-closure-sugar-equiv.rs | 49 + .../unboxed-closure-sugar-lifetime-elision.rs | 28 + .../unboxed-closure-sugar-not-used-on-fn.rs | 12 + .../unboxed-closure-sugar-region.rs | 37 + .../unboxed-closure-sugar-used-on-struct-1.rs | 14 + .../unboxed-closure-sugar-used-on-struct-3.rs | 19 + .../unboxed-closure-sugar-used-on-struct.rs | 13 + ...r-wrong-number-number-type-parameters-1.rs | 9 + ...r-wrong-number-number-type-parameters-3.rs | 11 + ...gar-wrong-number-number-type-parameters.rs | 11 + .../unboxed-closure-sugar-wrong-trait.rs | 10 + .../unboxed-closures-all-traits.rs | 22 + .../unboxed-closures-blanket-fn-mut.rs | 28 + .../unboxed-closures-blanket-fn.rs | 28 + .../unboxed-closures-borrow-conflict.rs | 12 + .../unboxed-closures-boxed.rs | 17 + .../unboxed-closures-by-ref.rs | 25 + .../unboxed-closures-call-fn-autoderef.rs | 19 + .../unboxed-closures-call-sugar-autoderef.rs | 16 + ...ed-closures-call-sugar-object-autoderef.rs | 16 + .../unboxed-closures-call-sugar-object.rs | 14 + .../unboxed-closures-counter-not-moved.rs | 29 + .../unboxed-closures-cross-crate.rs | 15 + .../unboxed-closures-direct-sugary-call.rs | 9 + .../unboxed-closures/unboxed-closures-drop.rs | 118 + .../unboxed-closures-extern-fn-hr.rs | 32 + .../unboxed-closures-extern-fn.rs | 28 + .../unboxed-closures-failed-recursive-fn-1.rs | 38 + .../unboxed-closures-failed-recursive-fn-2.rs | 30 + ...unboxed-closures-fn-as-fnmut-and-fnonce.rs | 45 + .../unboxed-closures-fnmut-as-fn.rs | 31 + .../unboxed-closures-fnmut-as-fnonce.rs | 34 + .../unboxed-closures-generic.rs | 14 + ...res-infer-arg-types-from-expected-bound.rs | 24 + ...fer-arg-types-from-expected-object-type.rs | 20 + ...-types-w-bound-regs-from-expected-bound.rs | 24 + ...nfer-argument-types-two-region-pointers.rs | 20 + ...oxed-closures-infer-explicit-call-early.rs | 9 + ...ures-infer-fn-once-move-from-projection.rs | 17 + ...osures-infer-fnmut-calling-fnmut-no-mut.rs | 21 + ...oxed-closures-infer-fnmut-calling-fnmut.rs | 20 + ...nboxed-closures-infer-fnmut-missing-mut.rs | 9 + ...d-closures-infer-fnmut-move-missing-mut.rs | 9 + .../unboxed-closures-infer-fnmut-move.rs | 17 + .../unboxed-closures-infer-fnmut.rs | 16 + ...nboxed-closures-infer-fnonce-call-twice.rs | 12 + ...d-closures-infer-fnonce-move-call-twice.rs | 12 + .../unboxed-closures-infer-fnonce-move.rs | 26 + .../unboxed-closures-infer-fnonce.rs | 26 + .../unboxed-closures-infer-kind.rs | 28 + .../unboxed-closures-infer-recursive-fn.rs | 46 + .../unboxed-closures-infer-upvar.rs | 14 + .../unboxed-closures-manual-impl.rs | 32 + .../unboxed-closures-monomorphization.rs | 27 + ...osures-move-from-projection-issue-30046.rs | 27 + .../unboxed-closures-move-mutable.rs | 32 + ...ures-move-some-upvars-in-by-ref-closure.rs | 24 + .../unboxed-closures-mutate-upvar.rs | 58 + ...-closures-mutated-upvar-from-fn-closure.rs | 15 + .../unboxed-closures-prelude.rs | 19 + ...oxed-closures-recursive-fn-using-fn-mut.rs | 44 + .../unboxed-closures-simple.rs | 11 + .../unboxed-closures-single-word-env.rs | 23 + .../unboxed-closures-static-call-fn-once.rs | 8 + ...nboxed-closures-static-call-wrong-trait.rs | 9 + .../unboxed-closures-sugar-object.rs | 26 + .../unboxed-closures-type-mismatch.rs | 8 + .../unboxed-closures-unique-type-id.rs | 27 + .../unboxed-closures-unsafe-extern-fn.rs | 35 + .../unboxed-closures-wrong-abi.rs | 35 + ...boxed-closures-wrong-arg-type-extern-fn.rs | 36 + .../unboxed-closures-zero-args.rs | 9 + .../rust/rustc/ui/unconstrained-none.rs | 6 + .../rust/rustc/ui/unconstrained-ref.rs | 8 + .../rust/rustc/ui/underscore-ident-matcher.rs | 10 + .../underscore-imports/auxiliary/duplicate.rs | 15 + .../auxiliary/underscore-imports.rs | 21 + .../rust/rustc/ui/underscore-imports/basic.rs | 63 + .../rust/rustc/ui/underscore-imports/cycle.rs | 19 + .../rustc/ui/underscore-imports/duplicate.rs | 16 + .../rustc/ui/underscore-imports/hygiene-2.rs | 34 + .../rustc/ui/underscore-imports/hygiene.rs | 41 + .../rustc/ui/underscore-imports/intercrate.rs | 12 + .../ui/underscore-imports/macro-expanded.rs | 46 + .../rustc/ui/underscore-imports/shadow.rs | 24 + .../ui/underscore-imports/unused-2018.rs | 18 + .../dyn-trait-underscore-in-struct.rs | 14 + .../dyn-trait-underscore.rs | 20 + .../rustc/ui/underscore-lifetime/in-binder.rs | 36 + .../in-fn-return-illegal.rs | 8 + .../rustc/ui/underscore-lifetime/in-struct.rs | 14 + .../underscore-lifetime-binders.rs | 23 + .../underscore-lifetime-elison-mismatch.rs | 4 + .../underscore-outlives-bounds.rs | 9 + .../where-clause-inherent-impl-ampersand.rs | 19 + .../where-clause-inherent-impl-underscore.rs | 18 + .../where-clause-trait-impl-region.rs | 16 + .../where-clause-trait-impl-underscore.rs | 16 + .../ui/underscore-lifetime/where-clauses.rs | 8 + .../rust/rustc/ui/underscore-lifetimes.rs | 39 + .../ui/underscore-method-after-integer.rs | 12 + .../ui/unevaluated_fixed_size_array_len.rs | 14 + .../ui/uniform-paths/auxiliary/issue-53691.rs | 8 + .../rustc/ui/uniform-paths/basic-nested.rs | 62 + .../rust/rustc/ui/uniform-paths/basic.rs | 34 + .../rustc/ui/uniform-paths/issue-53691.rs | 10 + .../rustc/ui/uniform-paths/macros-nested.rs | 54 + .../rust/rustc/ui/uniform-paths/macros.rs | 37 + .../rust/rustc/ui/uniform-paths/same-crate.rs | 99 + .../rust/rustc/ui/unify-return-ty.rs | 17 + .../exhaustive-wo-nevertype-issue-51221.rs | 10 + .../privately-uninhabited-dead-code.rs | 21 + .../ui/uninhabited/uninhabited-enum-cast.rs | 10 + .../ui/uninhabited/uninhabited-irrefutable.rs | 29 + .../uninhabited-matches-feature-gated.rs | 40 + .../ui/uninhabited/uninhabited-patterns.rs | 48 + .../rust/rustc/ui/uninit-empty-types.rs | 20 + .../rust/rustc/ui/union/auxiliary/union.rs | 5 + .../rust/rustc/ui/union/issue-41073.rs | 25 + .../rust/rustc/ui/union/union-align.rs | 63 + .../rust/rustc/ui/union/union-backcomp.rs | 26 + .../rust/rustc/ui/union/union-basic.rs | 60 + .../union/union-borrow-move-parent-sibling.rs | 92 + .../rustc/ui/union/union-const-codegen.rs | 18 + .../rustc/ui/union/union-const-eval-field.rs | 46 + .../rust/rustc/ui/union/union-const-eval.rs | 15 + .../rust/rustc/ui/union/union-const-pat.rs | 14 + .../rust/rustc/ui/union/union-copy.rs | 15 + .../rust/rustc/ui/union/union-custom-drop.rs | 20 + .../rust/rustc/ui/union/union-deref.rs | 29 + .../rust/rustc/ui/union/union-derive-clone.rs | 37 + .../rust/rustc/ui/union/union-derive-eq.rs | 19 + .../rust/rustc/ui/union/union-derive-rpass.rs | 40 + .../rust/rustc/ui/union/union-derive.rs | 17 + .../rust/rustc/ui/union/union-drop-assign.rs | 38 + .../rust/rustc/ui/union/union-drop.rs | 58 + .../rust/rustc/ui/union/union-empty.rs | 4 + .../rust/rustc/ui/union/union-fields-1.rs | 33 + .../rust/rustc/ui/union/union-fields-2.rs | 24 + .../rustc/ui/union/union-generic-rpass.rs | 32 + .../rust/rustc/ui/union/union-generic.rs | 13 + .../rustc/ui/union/union-inherent-method.rs | 15 + .../rustc/ui/union/union-lint-dead-code.rs | 16 + .../rust/rustc/ui/union/union-macro.rs | 25 + .../ui/union/union-manuallydrop-rpass.rs | 42 + .../rust/rustc/ui/union/union-move.rs | 54 + .../rust/rustc/ui/union/union-nodrop.rs | 61 + .../rustc/ui/union/union-nonrepresentable.rs | 9 + .../rust/rustc/ui/union/union-nonzero.rs | 52 + .../rust/rustc/ui/union/union-overwrite.rs | 79 + .../rust/rustc/ui/union/union-packed.rs | 171 + .../rustc/ui/union/union-pat-refutability.rs | 55 + .../rust/rustc/ui/union/union-repr-c.rs | 19 + .../rust/rustc/ui/union/union-sized-field.rs | 20 + .../rustc/ui/union/union-suggest-field.rs | 22 + .../rust/rustc/ui/union/union-trait-impl.rs | 18 + .../rust/rustc/ui/union/union-transmute.rs | 29 + .../rust/rustc/ui/union/union-unsafe.rs | 55 + .../rust/rustc/ui/union/union-unsized.rs | 17 + .../rustc/ui/union/union-with-drop-fields.rs | 30 + .../rustc/ui/unique-object-noncopyable.rs | 26 + .../rust/rustc/ui/unique-pinned-nocopy.rs | 15 + .../rustc/ui/unique/unique-assign-copy.rs | 14 + .../rustc/ui/unique/unique-assign-drop.rs | 13 + .../rustc/ui/unique/unique-assign-generic.rs | 13 + .../rust/rustc/ui/unique/unique-assign.rs | 10 + .../rustc/ui/unique/unique-autoderef-field.rs | 12 + .../rustc/ui/unique/unique-autoderef-index.rs | 8 + .../rust/rustc/ui/unique/unique-cmp.rs | 13 + .../rustc/ui/unique/unique-containing-tag.rs | 28 + .../rust/rustc/ui/unique/unique-create.rs | 14 + .../rustc/ui/unique/unique-decl-init-copy.rs | 13 + .../rust/rustc/ui/unique/unique-decl-init.rs | 9 + .../rust/rustc/ui/unique/unique-decl-move.rs | 9 + .../rust/rustc/ui/unique/unique-decl.rs | 12 + .../rust/rustc/ui/unique/unique-deref.rs | 8 + .../rustc/ui/unique/unique-destructure.rs | 11 + .../rustc/ui/unique/unique-drop-complex.rs | 9 + .../rustc/ui/unique/unique-ffi-symbols.rs | 17 + .../rustc/ui/unique/unique-fn-arg-move.rs | 12 + .../rust/rustc/ui/unique/unique-fn-arg-mut.rs | 13 + .../rust/rustc/ui/unique/unique-fn-arg.rs | 13 + .../rust/rustc/ui/unique/unique-fn-ret.rs | 11 + .../rustc/ui/unique/unique-generic-assign.rs | 12 + .../rust/rustc/ui/unique/unique-in-tag.rs | 23 + .../rustc/ui/unique/unique-in-vec-copy.rs | 17 + .../rust/rustc/ui/unique/unique-in-vec.rs | 8 + .../rust/rustc/ui/unique/unique-init.rs | 9 + .../rust/rustc/ui/unique/unique-kinds.rs | 66 + .../rust/rustc/ui/unique/unique-log.rs | 8 + .../rustc/ui/unique/unique-match-discrim.rs | 13 + .../rust/rustc/ui/unique/unique-move-drop.rs | 12 + .../rust/rustc/ui/unique/unique-move-temp.rs | 10 + .../rust/rustc/ui/unique/unique-move.rs | 11 + .../rust/rustc/ui/unique/unique-mutable.rs | 9 + .../rustc/ui/unique/unique-object-move.rs | 21 + .../rust/rustc/ui/unique/unique-pat-2.rs | 19 + .../rust/rustc/ui/unique/unique-pat-3.rs | 18 + .../rust/rustc/ui/unique/unique-pat.rs | 16 + .../rust/rustc/ui/unique/unique-rec.rs | 11 + .../rust/rustc/ui/unique/unique-send-2.rs | 36 + .../rust/rustc/ui/unique/unique-send.rs | 12 + .../rust/rustc/ui/unique/unique-swap.rs | 13 + gcc/testsuite/rust/rustc/ui/unit.rs | 18 + .../rust/rustc/ui/unknown-language-item.rs | 11 + .../rust/rustc/ui/unknown-lint-tool-name.rs | 9 + .../rust/rustc/ui/unknown-llvm-arg.rs | 23 + .../rust/rustc/ui/unknown-tool-name.rs | 3 + .../rust/rustc/ui/unnamed_argument_mode.rs | 15 + .../rust/rustc/ui/unnecessary-extern-crate.rs | 72 + .../rust/rustc/ui/unop-move-semantics.rs | 33 + gcc/testsuite/rust/rustc/ui/unop-neg-bool.rs | 4 + .../rust/rustc/ui/unreachable-code-1.rs | 20 + .../rust/rustc/ui/unreachable-code-ret.rs | 9 + .../rust/rustc/ui/unreachable-code.rs | 29 + .../unresolved-extern-mod-suggestion.rs | 6 + .../unresolved/unresolved-import-recovery.rs | 18 + .../rustc/ui/unresolved/unresolved-import.rs | 56 + .../rustc/ui/unrestricted-attribute-tokens.rs | 9 + .../rust/rustc/ui/unsafe-coercion.rs | 18 + .../ui/unsafe-fn-called-from-unsafe-blk.rs | 19 + .../ui/unsafe-fn-called-from-unsafe-fn.rs | 18 + .../rustc/ui/unsafe-pointer-assignability.rs | 12 + .../rust/rustc/ui/unsafe/ranged_ints.rs | 9 + .../rust/rustc/ui/unsafe/ranged_ints2.rs | 10 + .../rustc/ui/unsafe/ranged_ints2_const.rs | 21 + .../rust/rustc/ui/unsafe/ranged_ints3.rs | 12 + .../rustc/ui/unsafe/ranged_ints3_const.rs | 22 + .../rust/rustc/ui/unsafe/ranged_ints4.rs | 10 + .../rustc/ui/unsafe/ranged_ints4_const.rs | 20 + .../rust/rustc/ui/unsafe/ranged_ints_const.rs | 12 + .../rust/rustc/ui/unsafe/ranged_ints_macro.rs | 17 + ...c-2585-safe_packed_borrows-in-unsafe-fn.rs | 68 + .../unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs | 77 + ...unsafe-around-compiler-generated-unsafe.rs | 8 + .../ui/unsafe/unsafe-block-without-braces.rs | 7 + .../rust/rustc/ui/unsafe/unsafe-const-fn.rs | 13 + .../ui/unsafe/unsafe-fn-assign-deref-ptr.rs | 8 + .../rustc/ui/unsafe/unsafe-fn-autoderef.rs | 24 + .../ui/unsafe/unsafe-fn-called-from-safe.rs | 6 + .../rustc/ui/unsafe/unsafe-fn-deref-ptr.rs | 7 + .../ui/unsafe/unsafe-fn-used-as-value.rs | 7 + .../rustc/ui/unsafe/unsafe-move-val-init.rs | 11 + .../rust/rustc/ui/unsafe/unsafe-subtyping.rs | 12 + .../rust/rustc/ui/unsafe/unsafe-trait-impl.rs | 15 + .../ui/unsafe/unsafe-unstable-const-fn.rs | 14 + .../rustc/ui/unsigned-literal-negation.rs | 6 + .../rust/rustc/ui/unsized-locals/autoderef.rs | 50 + .../ui/unsized-locals/auxiliary/ufuncs.rs | 4 + .../ui/unsized-locals/borrow-after-move.rs | 44 + .../rustc/ui/unsized-locals/box-fnonce.rs | 11 + .../by-value-trait-object-safety-rpass.rs | 26 + ...y-value-trait-object-safety-withdefault.rs | 24 + .../by-value-trait-object-safety.rs | 23 + .../rustc/ui/unsized-locals/double-move.rs | 55 + .../issue-30276-feature-flagged.rs | 9 + .../rustc/ui/unsized-locals/issue-30276.rs | 6 + .../issue-50940-with-feature.rs | 9 + .../rustc/ui/unsized-locals/issue-50940.rs | 6 + .../reference-unsized-locals.rs | 11 + .../unsized-locals/simple-unsized-locals.rs | 10 + .../ui/unsized-locals/unsized-exprs-rpass.rs | 34 + .../rustc/ui/unsized-locals/unsized-exprs.rs | 29 + .../rustc/ui/unsized-locals/unsized-exprs2.rs | 25 + .../rustc/ui/unsized-locals/unsized-exprs3.rs | 11 + .../rustc/ui/unsized-locals/unsized-index.rs | 28 + .../unsized-locals-using-unsized-fn-params.rs | 16 + .../ui/unsized-locals/unsized-parameters.rs | 14 + .../rust/rustc/ui/unsized-tuple-impls.rs | 22 + gcc/testsuite/rust/rustc/ui/unsized.rs | 26 + .../rust/rustc/ui/unsized/issue-71659.rs | 33 + .../rust/rustc/ui/unsized/issue-75707.rs | 18 + .../return-unsized-from-trait-method.rs | 17 + .../rustc/ui/unsized/unsized-bare-typaram.rs | 5 + .../rust/rustc/ui/unsized/unsized-enum.rs | 12 + .../rust/rustc/ui/unsized/unsized-enum2.rs | 75 + .../rust/rustc/ui/unsized/unsized-fn-param.rs | 21 + .../unsized-inherent-impl-self-type.rs | 12 + .../rust/rustc/ui/unsized/unsized-struct.rs | 19 + .../unsized/unsized-trait-impl-self-type.rs | 15 + .../unsized/unsized-trait-impl-trait-arg.rs | 13 + gcc/testsuite/rust/rustc/ui/unsized2.rs | 98 + gcc/testsuite/rust/rustc/ui/unsized3-rpass.rs | 97 + gcc/testsuite/rust/rustc/ui/unsized3.rs | 52 + gcc/testsuite/rust/rustc/ui/unsized5.rs | 35 + gcc/testsuite/rust/rustc/ui/unsized6.rs | 45 + gcc/testsuite/rust/rustc/ui/unsized7.rs | 17 + .../rustc/ui/unspecified-self-in-trait-ref.rs | 21 + .../rust/rustc/ui/unsupported-cast.rs | 8 + .../rust/rustc/ui/unterminated-comment.rs | 2 + .../rust/rustc/ui/unterminated-doc-comment.rs | 2 + .../ui/unused-crate-deps/auxiliary/bar.rs | 2 + .../ui/unused-crate-deps/auxiliary/foo.rs | 6 + .../ignore-pathless-extern.rs | 13 + .../rust/rustc/ui/unused-crate-deps/libfib.rs | 22 + .../rustc/ui/unused-crate-deps/lint-group.rs | 10 + .../rustc/ui/unused-crate-deps/suppress.rs | 12 + .../rustc/ui/unused-crate-deps/test-use-ok.rs | 16 + .../ui/unused-crate-deps/unused-aliases.rs | 14 + .../use_extern_crate_2015.rs | 14 + .../rustc/ui/unused-crate-deps/warn-attr.rs | 11 + .../unused-crate-deps/warn-cmdline-static.rs | 11 + .../ui/unused-crate-deps/warn-cmdline.rs | 10 + .../rust/rustc/ui/unused-move-capture.rs | 11 + gcc/testsuite/rust/rustc/ui/unused-move.rs | 16 + .../rust/rustc/ui/unused/unused-attr.rs | 50 + .../rust/rustc/ui/unused/unused-closure.rs | 41 + .../rustc/ui/unused/unused-macro-rules.rs | 30 + .../unused/unused-macro-with-bad-frag-spec.rs | 10 + .../unused-macro-with-follow-violation.rs | 8 + .../rust/rustc/ui/unused/unused-macro.rs | 27 + .../unused/unused-mut-warning-captured-var.rs | 10 + .../rust/rustc/ui/unused/unused-result.rs | 43 + .../rust/rustc/ui/unwind-resource.rs | 40 + gcc/testsuite/rust/rustc/ui/unwind-unique.rs | 17 + .../rust/rustc/ui/use-crate-name-alias.rs | 8 + .../rust/rustc/ui/use-import-export.rs | 13 + gcc/testsuite/rust/rustc/ui/use-keyword-2.rs | 24 + gcc/testsuite/rust/rustc/ui/use-mod.rs | 34 + .../rustc/ui/use-module-level-int-consts.rs | 12 + .../rust/rustc/ui/use-nested-groups.rs | 33 + .../rust/rustc/ui/use-self-in-inner-fn.rs | 15 + gcc/testsuite/rust/rustc/ui/use.rs | 24 + .../extern-use-primitive-type-lib.rs | 4 + .../ui/use/auxiliary/use-from-trait-xc.rs | 30 + .../rust/rustc/ui/use/issue-18986.rs | 11 + .../issue-60976-extern-use-primitive-type.rs | 8 + .../ui/use/use-after-move-based-on-type.rs | 6 + ...use-after-move-implicity-coerced-object.rs | 31 + .../use/use-after-move-self-based-on-type.rs | 22 + .../rust/rustc/ui/use/use-after-move-self.rs | 20 + .../rust/rustc/ui/use/use-associated-const.rs | 14 + .../rust/rustc/ui/use/use-from-trait-xc.rs | 27 + .../rust/rustc/ui/use/use-from-trait.rs | 23 + .../rust/rustc/ui/use/use-keyword.rs | 18 + .../rust/rustc/ui/use/use-meta-mismatch.rs | 6 + gcc/testsuite/rust/rustc/ui/use/use-mod.rs | 20 + .../rust/rustc/ui/use/use-mod/use-mod-2.rs | 12 + .../rust/rustc/ui/use/use-mod/use-mod-3.rs | 13 + .../rust/rustc/ui/use/use-mod/use-mod-4.rs | 8 + .../rust/rustc/ui/use/use-mod/use-mod-5.rs | 14 + .../rust/rustc/ui/use/use-mod/use-mod-6.rs | 14 + .../rustc/ui/use/use-nested-groups-error.rs | 16 + .../use/use-nested-groups-unused-imports.rs | 26 + .../rust/rustc/ui/use/use-paths-as-items.rs | 10 + .../rust/rustc/ui/use/use-self-type.rs | 12 + .../rustc/ui/use/use-super-global-path.rs | 17 + .../rust/rustc/ui/use_inline_dtor.rs | 11 + gcc/testsuite/rust/rustc/ui/used.rs | 17 + .../rust/rustc/ui/useless-comment.rs | 46 + gcc/testsuite/rust/rustc/ui/useless-pub.rs | 17 + .../rust/rustc/ui/user-defined-macro-rules.rs | 10 + .../rustc/ui/using-target-feature-unstable.rs | 12 + .../rustc/ui/usize-generic-argument-parent.rs | 6 + gcc/testsuite/rust/rustc/ui/utf8-bom.rs | 7 + gcc/testsuite/rust/rustc/ui/utf8.rs | 51 + gcc/testsuite/rust/rustc/ui/utf8_chars.rs | 32 + .../rust/rustc/ui/utf8_idents-rpass.rs | 42 + gcc/testsuite/rust/rustc/ui/utf8_idents.rs | 16 + ...ariance-intersection-of-ref-and-opt-ref.rs | 26 + .../rustc/ui/variance-iterators-in-libcore.rs | 11 + .../ui/variance/variance-associated-types.rs | 23 + .../ui/variance/variance-associated-types2.rs | 18 + .../variance-btree-invariant-types.rs | 52 + .../ui/variance/variance-cell-is-invariant.rs | 19 + .../variance-contravariant-arg-object.rs | 26 + .../variance-contravariant-arg-trait-match.rs | 27 + ...variance-contravariant-self-trait-match.rs | 28 + .../variance/variance-covariant-arg-object.rs | 26 + .../variance-covariant-arg-trait-match.rs | 26 + .../variance-covariant-self-trait-match.rs | 26 + .../variance/variance-invariant-arg-object.rs | 22 + .../variance-invariant-arg-trait-match.rs | 22 + .../variance-invariant-self-trait-match.rs | 22 + .../rustc/ui/variance/variance-issue-20533.rs | 44 + .../ui/variance/variance-object-types.rs | 17 + .../ui/variance/variance-regions-direct.rs | 66 + .../ui/variance/variance-regions-indirect.rs | 35 + .../variance-regions-unused-direct.rs | 16 + .../variance-regions-unused-indirect.rs | 12 + .../ui/variance/variance-trait-bounds.rs | 36 + .../ui/variance/variance-trait-matching.rs | 39 + .../variance/variance-trait-object-bound.rs | 19 + .../ui/variance/variance-types-bounds.rs | 44 + .../rust/rustc/ui/variance/variance-types.rs | 42 + .../variance/variance-unused-region-param.rs | 8 + .../ui/variance/variance-unused-type-param.rs | 20 + .../variance-use-contravariant-struct-1.rs | 17 + .../variance-use-contravariant-struct-2.rs | 18 + .../variance-use-covariant-struct-1.rs | 14 + .../variance-use-covariant-struct-2.rs | 17 + .../variance-use-invariant-struct-1.rs | 24 + .../variants/auxiliary/variant-namespacing.rs | 6 + .../rustc/ui/variants/variant-namespacing.rs | 34 + .../ui/variants/variant-size-differences.rs | 9 + .../rustc/ui/variants/variant-used-as-type.rs | 21 + .../rustc/ui/vec/vec-macro-with-comma-only.rs | 4 + .../rust/rustc/ui/vec/vec-mut-iter-borrow.rs | 8 + .../rust/rustc/ui/vec/vec-overrun.rs | 13 + .../rust/rustc/ui/vec/vec-res-add.rs | 20 + .../rust/rustc/ui/vector-cast-weirdness.rs | 25 + gcc/testsuite/rust/rustc/ui/vector-no-ann.rs | 5 + .../rust/rustc/ui/volatile-fat-ptr.rs | 16 + .../rust/rustc/ui/vtable-res-trait-param.rs | 24 + .../rustc/ui/wait-forked-but-failed-child.rs | 64 + .../rust/rustc/ui/walk-struct-literal-with.rs | 18 + .../rust/rustc/ui/warn-ctypes-inhibit.rs | 18 + .../rust/rustc/ui/warn-path-statement.rs | 18 + .../ui/wasm-custom-section-relocations.rs | 16 + .../rust/rustc/ui/wasm-import-module.rs | 11 + gcc/testsuite/rust/rustc/ui/weak-lang-item.rs | 16 + .../ui/weak-new-uninhabited-issue-48493.rs | 8 + .../rust/rustc/ui/weird-exit-code.rs | 29 + gcc/testsuite/rust/rustc/ui/weird-exprs.rs | 181 + .../ui/wf-bound-region-in-object-type.rs | 23 + gcc/testsuite/rust/rustc/ui/wf/issue-48638.rs | 22 + .../rust/rustc/ui/wf/wf-array-elem-sized.rs | 12 + .../rust/rustc/ui/wf/wf-const-type.rs | 15 + .../ui/wf/wf-convert-unsafe-trait-obj-box.rs | 19 + .../ui/wf/wf-convert-unsafe-trait-obj.rs | 19 + .../rust/rustc/ui/wf/wf-enum-bound.rs | 17 + .../ui/wf/wf-enum-fields-struct-variant.rs | 19 + .../rust/rustc/ui/wf/wf-enum-fields.rs | 17 + .../rust/rustc/ui/wf/wf-fn-where-clause.rs | 21 + .../rustc/ui/wf/wf-foreign-fn-decl-ret.rs | 19 + .../ui/wf/wf-impl-associated-type-region.rs | 15 + .../ui/wf/wf-impl-associated-type-trait.rs | 23 + .../rust/rustc/ui/wf/wf-impl-self-type.rs | 8 + .../rust/rustc/ui/wf/wf-in-fn-arg.rs | 15 + .../rust/rustc/ui/wf/wf-in-fn-ret.rs | 15 + .../rust/rustc/ui/wf/wf-in-fn-type-arg.rs | 13 + .../rust/rustc/ui/wf/wf-in-fn-type-ret.rs | 13 + .../rust/rustc/ui/wf/wf-in-fn-type-static.rs | 23 + .../rust/rustc/ui/wf/wf-in-fn-where-clause.rs | 16 + .../rust/rustc/ui/wf/wf-in-obj-type-static.rs | 19 + .../rust/rustc/ui/wf/wf-in-obj-type-trait.rs | 15 + .../wf-inherent-impl-method-where-clause.rs | 18 + .../ui/wf/wf-inherent-impl-where-clause.rs | 17 + .../ui/wf/wf-misc-methods-issue-28609.rs | 75 + .../rust/rustc/ui/wf/wf-object-safe.rs | 11 + .../ui/wf/wf-outlives-ty-in-fn-or-trait.rs | 23 + ...-packed-on-proj-of-type-as-unimpl-trait.rs | 32 + .../rust/rustc/ui/wf/wf-static-method.rs | 55 + .../rust/rustc/ui/wf/wf-static-type.rs | 15 + .../rust/rustc/ui/wf/wf-struct-bound.rs | 17 + .../rust/rustc/ui/wf/wf-struct-field.rs | 17 + .../ui/wf/wf-trait-associated-type-bound.rs | 15 + .../ui/wf/wf-trait-associated-type-region.rs | 15 + .../ui/wf/wf-trait-associated-type-trait.rs | 17 + .../rust/rustc/ui/wf/wf-trait-bound.rs | 16 + .../rustc/ui/wf/wf-trait-default-fn-arg.rs | 20 + .../rustc/ui/wf/wf-trait-default-fn-ret.rs | 20 + .../ui/wf/wf-trait-default-fn-where-clause.rs | 20 + .../rust/rustc/ui/wf/wf-trait-fn-arg.rs | 17 + .../rust/rustc/ui/wf/wf-trait-fn-ret.rs | 17 + .../rustc/ui/wf/wf-trait-fn-where-clause.rs | 18 + .../rust/rustc/ui/wf/wf-trait-superbound.rs | 13 + .../rustc/ui/wf/wf-unsafe-trait-obj-match.rs | 30 + .../auxiliary/where_clauses_xc.rs | 20 + .../where-clause-bounds-inconsistency.rs | 24 + ...constraints-are-local-for-inherent-impl.rs | 19 + ...se-constraints-are-local-for-trait-impl.rs | 24 + .../where-clause-early-bound-lifetimes.rs | 19 + .../where-clause-method-substituion-rpass.rs | 24 + .../where-clause-method-substituion.rs | 23 + .../where-clause-region-outlives.rs | 13 + .../where-clauses-cross-crate.rs | 14 + .../where-clauses/where-clauses-lifetimes.rs | 11 + .../where-clauses-method-unsatisfied.rs | 21 + .../ui/where-clauses/where-clauses-method.rs | 21 + .../where-clauses-unboxed-closures.rs | 18 + .../where-clauses-unsatisfied.rs | 9 + .../rustc/ui/where-clauses/where-clauses.rs | 28 + .../where-equality-constraints.rs | 7 + .../ui/where-clauses/where-for-self-2.rs | 25 + .../rustc/ui/where-clauses/where-for-self.rs | 20 + .../where-lifetime-resolution.rs | 13 + gcc/testsuite/rust/rustc/ui/while-let.rs | 32 + .../rust/rustc/ui/while-type-error.rs | 4 + .../rustc/ui/windows-subsystem-invalid.rs | 6 + .../rust/rustc/ui/wrapping-int-api.rs | 229 + .../rust/rustc/ui/write-fmt-errors.rs | 47 + .../rustc/ui/write-to-static-mut-in-static.rs | 11 + gcc/testsuite/rust/rustc/ui/writealias.rs | 20 + .../rust/rustc/ui/writing-to-immutable-vec.rs | 5 + .../rustc/ui/wrong-hashset-issue-42918.rs | 32 + .../rustc/ui/wrong-mul-method-signature.rs | 69 + gcc/testsuite/rust/rustc/ui/wrong-ret-type.rs | 4 + gcc/testsuite/rust/rustc/ui/x86stdcall.rs | 38 + gcc/testsuite/rust/rustc/ui/x86stdcall2.rs | 34 + .../rust/rustc/ui/xc-private-method.rs | 12 + .../rust/rustc/ui/xc-private-method2.rs | 12 + .../auxiliary/static_priv_by_default.rs | 52 + .../ui/xcrate/auxiliary/xcrate_unit_struct.rs | 29 + .../ui/xcrate/xcrate-private-by-default.rs | 46 + .../rustc/ui/xcrate/xcrate-unit-struct.rs | 13 + gcc/testsuite/rust/rustc/ui/yield.rs | 22 + gcc/testsuite/rust/rustc/ui/yield1.rs | 17 + gcc/testsuite/rust/rustc/ui/yield2.rs | 9 + gcc/testsuite/rust/rustc/ui/z-crate-attr.rs | 13 + .../zero-sized/zero-size-type-destructors.rs | 22 + .../zero-sized/zero-sized-binary-heap-push.rs | 21 + .../zero-sized/zero-sized-btreemap-insert.rs | 26 + .../zero-sized/zero-sized-linkedlist-push.rs | 30 + .../ui/zero-sized/zero-sized-tuple-struct.rs | 14 + 11419 files changed, 310725 insertions(+) create mode 100644 gcc/testsuite/rust/rustc/ui/abi/abi-sysv64-arg-passing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/abi-sysv64-register-usage.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/anon-extern-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/auxiliary/anon-extern-mod-cross-crate-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/auxiliary/foreign_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/c-stack-as-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/cabi-int-widening.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/duplicated-external-mods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/auxiliary/extern-crosscrate-source.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-deep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-deep2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-direct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-indirect.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-scrub.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-crosscrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU16s.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU32s.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU64s.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU8s.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-char.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-double.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-u32.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-u64.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU16s.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU32s.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU64s.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU8s.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/foreign/auxiliary/foreign_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-call-no-runtime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-dupe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-fn-with-byval.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-no-abi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/invoke-external-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/issues/issue-62350-sysv-neg-reg-counts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/lib-defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/mir/mir_codegen_calls_variadic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/numbers-arithmetic/i128-ffi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/segfault-no-out-of-stack.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/stack-probes-lto.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/stack-probes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/statics/static-mut-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/struct-enums/struct-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/union/union-c-interop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/abi/variadic-ffi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/absolute-paths-in-nested-use-groups.rs create mode 100644 gcc/testsuite/rust/rustc/ui/access-mode-in-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/alias-uninit-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/align-with-extern-c-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/alignment-gep-tup-like-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/alloca-from-derived-tydesc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/allocator-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/auxiliary/custom-as-global.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/auxiliary/custom.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/auxiliary/helper.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/auxiliary/system-allocator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/auxiliary/system-allocator2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/custom-in-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/custom-in-submodule.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/custom.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/function-allocator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/no_std-alloc-error-handler-custom.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/no_std-alloc-error-handler-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/not-an-allocator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/two-allocators.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/two-allocators2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/two-allocators3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/xcrate-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/allocator/xcrate-use2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/annotate-snippet/auxiliary/multispan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/annotate-snippet/missing-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/annotate-snippet/multispan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/anon-params/anon-params-denied-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/anon-params/anon-params-deprecated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/anon-params/anon-params-edition-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/anon-params/auxiliary/anon-params-edition-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/anonymous-higher-ranked-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/arg-count-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/arg-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/argument-passing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-break-length.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-not-vector.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/array_const_index-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/bounds-check-no-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/box-of-array-of-drop-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/box-of-array-of-drop-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/cast-in-array-size.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/check-static-mut-slices.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/check-static-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/copy-out-of-array-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/destructure-array-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/dst-raw-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/empty-mutable-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/estr-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/evec-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/fixed_length_copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/huge-largest-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/infer_array_len.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/issue-69103-extra-binding-subslice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/ivec-pass-by-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/match_arr_unknown_len.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/mutable-alias-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/nested-vec-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/nested-vec-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/nested-vec-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/new-style-fixed-length-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/rcvr-borrowed-to-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/repeated-vector-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/show-boxed-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-of-zero-size-elements.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-panic-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-panic-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-pat-type-mismatches.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/slice_binary_search.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/subslice-patterns-const-eval-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/subslice-patterns-const-eval.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/variance-vec-covariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-dst.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-fixed-length.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-late-init.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-no-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-rvalue-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-with-brackets.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-with-trailing-comma.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-autoslice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-fixed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-fold.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-repeat-with-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-tail-matching.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array-slice-vec/vector-no-ann-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array_const_index-0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/array_const_index-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/artificial-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/as-precedence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/bad-arch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/bad-options.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/bad-reg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/bad-template.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/duplicate-options.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/interpolated-idents.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/issue-72570.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/noreturn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/parse-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/rustfix-asm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/srcloc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/sym.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/type-check-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/type-check-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/type-check-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/asm/type-check-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/assert-eq-trailing-comma.rs create mode 100644 gcc/testsuite/rust/rustc/ui/assert-escape.rs create mode 100644 gcc/testsuite/rust/rustc/ui/assert-ne-trailing-comma.rs create mode 100644 gcc/testsuite/rust/rustc/ui/assign-assign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/assign-imm-local-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/assignment-operator-unimplemented.rs create mode 100644 gcc/testsuite/rust/rustc/ui/assoc-inherent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/assoc-lang-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/assoc-oddities-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-ambiguity-report.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-array-len.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-const-eval.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-cross-crate-const-eval.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-cross-crate-defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-dead-code.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-generic-obligations.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-impl-wrong-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-impl-wrong-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-in-global-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-in-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-inherent-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-marks-live-code.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-match-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-no-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-outer-ty-refs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-overwrite-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-private-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-public-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-range-match-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-resolution-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-self-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-trait-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameter-arms.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameter-arrays-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameter-arrays.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-ufcs-infer-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-use-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-use-impl-of-same-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/associated-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/auxiliary/associated-const-cc-lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/auxiliary/empty-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/defaults-cyclic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/defaults-cyclic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/defaults-not-assumed-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/defaults-not-assumed-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/issue-63496.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-consts/issue-69020-assoc-const-arith-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-item-long-paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-names-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-names-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-names.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-item/associated-item-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-item/issue-48027.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-path-shl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/ambiguous-associated-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/assoc-type-bound-through-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/auxiliary/fn-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/duplicate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/dyn-impl-trait-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/dyn-lcsit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/dyn-rpit-and-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/entails-sized-object-safety.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/enum-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-apit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-dyn-apit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-inline.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-where.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-wrap-apit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/implied-region-constraints.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/inside-adt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-61752.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-70292.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-71443-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-71443-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-73818.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/lcsit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/rpit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/struct-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/trait-alias-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/trait-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/type-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-type-bounds/union-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associate-type-bound-normalization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-type-projection-from-supertrait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-binding-in-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-binding-in-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-bound-ambiguity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-bound-failure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-cc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-coherence-failure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-conditional-dispatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-constant-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-doubleendediterator-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-duplicate-binding-in-env.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-enum-field-named.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-enum-field-numbered.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-expr-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-hr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-obj.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-for-unimpl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-from-supertrait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-impl-redirect.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-ambiguous-context.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-bound-type-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-default-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-impl-generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-inherent-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-incomplete-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-17359.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-20220.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-20346.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-20371.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-21212.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-iterator-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-multiple-types-one-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-nested-projections.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-no-suitable-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-no-suitable-supertrait-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-no-suitable-supertrait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-in-bounds-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-in-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-unifield-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-outlives.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-overridden-binding-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-overridden-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-overridden-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-path-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-path-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-bound-ambiguity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-bound-in-supertraits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-in-object-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-in-supertrait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-in-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-to-unrelated-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-ref-from-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-ref-in-struct-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-region-erasure-issue-20582.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-resolve-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-stream.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-struct-field-named.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-struct-field-numbered.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-subtyping-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-sugar-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-unconstrained.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-unsized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/auxiliary/associated-types-cc-lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/bound-lifetime-constrained.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/bound-lifetime-in-binding-only.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/bound-lifetime-in-return-only.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/cache/chrono-scan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/cache/elision.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/cache/project-fn-ret-contravariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/cache/project-fn-ret-invariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-fail-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-fail-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-pass-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-pass-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/defaults-in-other-trait-items-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/defaults-in-other-trait-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/defaults-mixed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/defaults-specialization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/defaults-suitability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/defaults-unsound-62211-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/defaults-unsound-62211-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/defaults-wf.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/higher-ranked-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-projection-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/impl-trait-return-missing-constraint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/impl-wf-cycle-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/impl-wf-cycle-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-26681.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-32350.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-36499.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-41868.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-43924.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-44153.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-47385.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-48010.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-54108.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-54182-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-54182-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-62200.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-63593.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-64848.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-64855-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-64855.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-65774-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-65774-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-65934.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/issue-72806.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/missing-associated-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/normalization-probe-cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/normalize-cycle-in-eval-no-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/normalize-cycle-in-eval.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/object-normalization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/param-env-normalize-cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/point-at-type-on-obligation-failure-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/point-at-type-on-obligation-failure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/trait-with-supertraits-needing-sized-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/wf-cycle-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/associated-types/wf-cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ast-json/ast-json-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ast-json/ast-json-noexpand-output.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ast-json/ast-json-output.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/argument-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-assoc-fn-anon-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-await.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-block-control-flow-static-semantics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-borrowck-escaping-block-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-borrowck-escaping-closure-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-closure-matches-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-error-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-fn-nonsend.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-fn-path-elision.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-fn-send-uses-nonsend.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-fn-size-moved-locals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-fn-size-uninit-locals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-fn-size.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-matches-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-trait-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-unsafe-fn-call-in-safe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/async-with-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/auxiliary/arc_wake.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2015-edition-error-various-positions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2015-edition-warning.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2018-edition-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/await-keyword/post_expansion_error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/await-unsize.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/bound-normalization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/conditional-and-guaranteed-initialization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/dont-print-desugared-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/dont-suggest-missing-await.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/drop-order/auxiliary/arc_wake.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-locals-are-hidden.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-when-cancelled.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/edition-deny-async-fns-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/expansion-in-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/feature-async-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/futures-api.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/generics-and-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-54239-private-type-triggers-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-60709.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-61076.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-61452.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-61793.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-61949-self-return-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-62658.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-63832-await-short-temporary-lifetime-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-63832-await-short-temporary-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-64130-1-sync.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-64130-2-send.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-64130-3-other.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-64130-4-async-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-64130-non-send-future-diags.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-64391.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-66312.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-66387-if-without-else.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-67252-unnamed-future.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-67651.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-67765-async-diagnostic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-68112.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-68523-start.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-68523.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-69446-fnmut-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-70594.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-70818.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-70935-complex-spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-71137.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-72442.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-72590-type-error-sized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-73050.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-73137.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-74072-lifetime-name-annotations.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issue-74497-lifetime-in-opaque.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/auxiliary/issue-60674.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/auxiliary/issue_67893.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-51719.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-51751.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-53249.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-54752-async-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-54974.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-55324.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-55809.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-58885.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-59001.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-59972.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-60518.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-60655-latebound-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-60674.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-61187.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-61986.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62009-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62009-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62097.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62517-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62517-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64391-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64433.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64477-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64477.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64964.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65159.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65419/issue-65419-generator-resume-after-completion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-66695-static-refs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-67611-static-mut-refs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-67893.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-69307-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-69307.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/issue-78654.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/issues/non-async-enclosing-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/move-part-await-return-rest-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/move-part-await-return-rest-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/elided.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/fn-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/hrtb.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/named.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/partial-relation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/variance.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/mutually-recursive-async-impl-trait-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/nested-in-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/no-async-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/no-const-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/no-move-across-await-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/no-move-across-await-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/no-non-guaranteed-initialization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/no-params-non-move-async-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/no-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/no-unsafe-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/partial-initialization-across-await.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/recursive-async-impl-trait-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/return-ty-raw-ptr-coercion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/return-ty-unsize-coercion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/suggest-missing-await-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/suggest-missing-await.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/suggest-switching-edition-on-await.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/try-on-option-in-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/unreachable-lint-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/unreachable-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/unresolved_type_param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/async-await/unused-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/atomic-access-bool.rs create mode 100644 gcc/testsuite/rust/rustc/ui/atomic-alignment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/atomic-compare_exchange.rs create mode 100644 gcc/testsuite/rust/rustc/ui/atomic-from-mut-not-available.rs create mode 100644 gcc/testsuite/rust/rustc/ui/atomic-print.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attempted-access-non-fatal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attr-eq-token-tree.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attr-main-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attr-main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attr-shebang.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attr-start.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attr-usage-inline.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attr-usage-repr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attribute-with-no-generics-in-parameter-list.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/attr-before-view-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/attr-before-view-item2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/attr-mix-new.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/auxiliary/key-value-expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/class-attributes-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/class-attributes-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/field-attributes-vis-unresolved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/item-attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/key-value-expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/method-attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/multiple-invalid.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/nonterminal-expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/obsolete-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-prelude.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-unused.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/unknown-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/unnamed-field-attributes-dup.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/unnamed-field-attributes-vis.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/unnamed-field-attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attributes/variant-attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attrs-resolution-errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/attrs-resolution.rs create mode 100644 gcc/testsuite/rust/rustc/ui/augmented-assignments-feature-gate-cross.rs create mode 100644 gcc/testsuite/rust/rustc/ui/augmented-assignments-feature-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/augmented-assignments-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/augmented-assignments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-instantiate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-ref-slice-plus-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-traits/auto-is-contextual.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-traits/auto-trait-projection-recursion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-traits/auto-trait-validation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-traits/auto-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-traits/issue-23080-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-traits/issue-23080.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-traits/typeck-auto-trait-no-supertraits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-constituent-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-negation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-precedence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autobind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autoderef-full-lval.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autoref-autoderef/auto-ref-sliceable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autoref-autoderef/auto-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-on-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-priority.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/augmented_assignments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/blind-item-mixed-crate-use-item-foo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/blind-item-mixed-crate-use-item-foo2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/changing-crates-a1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/changing-crates-a2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/changing-crates-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/check_static_recursion_foreign_helper.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/cond_plugin.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/debuginfo-lto-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/default-ty-param-cross-crate-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/define-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/edition-kw-macro-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/edition-kw-macro-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/empty-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/extern-prelude-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/extern-prelude.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/extern-statics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/hello_macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/impl_privacy_xc_1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/impl_privacy_xc_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/inline_dtor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/inner_static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/issue-72470-lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/issue-76387.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/kinds_in_metadata.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/link-cfg-works-transitive-dylib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/link-cfg-works-transitive-rlib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/linkage1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/llvm_pr32379.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/lto-duplicate-symbols1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/lto-duplicate-symbols2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/lto-rustc-loads-linker-plugin.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/msvc-data-only-lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/nested_item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/noexporttypelib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/orphan-check-diagnostics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/proc_macro_def.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/pub-and-stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/reachable-unnameable-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/reexport-should-still-link.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/removing-extern-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-meta.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-rlib-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-rlib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-rmeta.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/rustc-rust-log-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/stability-cfg2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/svh-a-base.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/svh-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/trait_superkinds_in_metadata.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/typeid-intrinsic-aux1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/typeid-intrinsic-aux2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/using-target-feature-unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/weak-lang-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/auxiliary/xc-private-method-lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/backtrace-debuginfo-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/backtrace-debuginfo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/backtrace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-const-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-crate-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-env-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-env-capture2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-env-capture3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-expr-lhs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-expr-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-expr-path2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-extern-link-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-intrinsic-monomorphization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-lint-cap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-lint-cap2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-lint-cap3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-method-typaram-kind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-mid-path-type-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-module.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-sized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bad/bad-type-env-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bare-fn-implements-fn-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bare-static-string.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bastion-of-the-turbofish.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bench/issue-32062.rs create mode 100644 gcc/testsuite/rust/rustc/ui/big-literals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binary-minus-without-space.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binary-op-on-double-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bind-by-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/ambiguity-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/bind-field-short-with-modifiers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-infallible.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-option.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/const-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/empty-types-in-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/exhaustive-bool-match-sanity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/expr-match-generic-unique1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/expr-match-generic-unique2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/expr-match-generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/expr-match-panic-all.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/expr-match-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/expr-match-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/expr-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/fat-arrow-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/fn-arg-incomplete-pattern-drop-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/fn-pattern-expected-type-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/fn-pattern-expected-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/func-arg-incomplete-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/func-arg-ref-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/func-arg-wild-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/if-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/inconsistent-lifetime-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/inferred-suffix-in-pattern-range.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/irrefutable-slice-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/issue-53114-borrow-checks.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/issue-53114-safety-checks.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/let-assignability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/let-destruct-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/let-var-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-arm-statics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-beginning-vert.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-borrowed_str.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-bot-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-bot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-byte-array-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-enum-struct-0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-enum-struct-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-implicit-copy-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-in-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-join.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-larger-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-naked-record-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-naked-record.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-pattern-bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-pattern-lit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-pattern-no-type-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-pattern-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-phi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-pipe-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-range-infer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-range-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-range.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-reassign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-ref-binding-in-guard-3256.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-ref-binding-mut-option.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-ref-binding-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-ref-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-ref-unsized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-str.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-struct-0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-tag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-unique-bind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-unsized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-value-binding-in-guard-3291.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-var-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-vec-alternatives.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-vec-rvalue.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/match-with-ret-arm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/multi-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/mut-in-ident-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/nested-matchs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/nested-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/nil-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/nullary-or-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/optional_comma_in_match_arm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/or-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/order-drop-with-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/pat-ranges.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/pat-tuple-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/pat-tuple-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/pat-tuple-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/pat-tuple-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/pat-tuple-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/pat-tuple-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/pat-tuple-7.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/pattern-bound-var-in-for-each.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/pattern-in-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/range-inclusive-pattern-precedence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/simple-generic-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/use-uninit-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/use-uninit-match2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binding/zero_sized_subslice_match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binop/binop-bitxor-str.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binop/binop-consume-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binop/binop-fail-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binop/binop-logic-float.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binop/binop-logic-int.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binop/binop-move-semantics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binop/binop-mul-bool.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binop/binop-mul-i32-f32.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binop/binop-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binop/binop-typeck.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binops-issue-22743.rs create mode 100644 gcc/testsuite/rust/rustc/ui/binops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bitwise.rs create mode 100644 gcc/testsuite/rust/rustc/ui/blind-item-local-shadow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/blind-item-mixed-crate-use-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/blind-item-mixed-use-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/blind/blind-item-block-item-shadow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/blind/blind-item-block-middle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/blind/blind-item-item-shadow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-arg-call-as.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-explicit-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-expr-precedence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-expression-remove-semicolon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-fn-coerce.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-iter-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-iter-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-result/block-must-not-have-result-do.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-result/block-must-not-have-result-res.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-result/block-must-not-have-result-while.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-result/consider-removing-last-semi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-result/issue-11714.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-result/issue-13428.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-result/issue-13624.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-result/issue-20862.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-result/issue-22645.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-result/issue-3563.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-result/issue-5500.rs create mode 100644 gcc/testsuite/rust/rustc/ui/block-result/unexpected-return-on-unit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bogus-tag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bool-not.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bool.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrow-by-val-method-receiver.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/assign-never-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/assign_mutable_fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrow-immutable-upvar-mutation-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrow-immutable-upvar-mutation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-borrowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-deref-mutability-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-deref-mutability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-mutability-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-mutability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrow-tuple-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-access-permissions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-and-init.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-anon-fields-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-anon-fields-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-anon-fields-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-argument.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-asm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-comp-idx.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-comp.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-andmut-in-borrowed-loc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-constants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-subfield.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assignment-to-static-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-auto-mut-ref-to-immut-var.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-autoref-3261.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-bad-nested-calls-free.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-bad-nested-calls-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-binding-mutbl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-block-unint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-expr-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-owned-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-stack-variable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-temporary.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-immut-deref-of-box-as-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-mut-object-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-overloaded-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrowed-uniq-rvalue.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-box-sensitivity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-break-uninit-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-break-uninit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-mut-and-imm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-mut-of-imm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-mut-of-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-slice-patterns-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-slice-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-two-imm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-two-mut-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-two-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-unique-imm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-use-after-free.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-consume-unsize-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-consume-upcast-box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-describe-lvalue.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-drop-from-guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-escaping-closure-error-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-escaping-closure-error-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-field-sensitivity-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-field-sensitivity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-fixed-length-vecs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-fn-in-const-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-fn-in-const-c.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-for-loop-correct-cmt-for-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-for-loop-head-linkage.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-freeze-frozen-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-if-no-else.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-if-with-else.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-in-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-in-called-fn-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-in-fn-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-in-fru.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-op-equal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-plus-equal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-insert-during-each.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-14498.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-2657-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-2657-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-48962.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow-if.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-blocks-move-cc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-blocks-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-blocks-mut-uniq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-in-overloaded-op.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-of-static-data-issue-27616.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-rcvr-overloaded-op.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-rcvr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-vec-content.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-local-borrow-outlives-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-local-borrow-with-panic-outlives-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-local-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-macro-interaction-issue-6304.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-match-already-borrowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-match-binding-is-assignment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-by-capture-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-by-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-error-with-note.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-from-unsafe-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-in-irrefut-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-moved-value-into-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-mut-base-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-overloaded-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-static-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-struct-with-dtor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-tuple-struct-with-dtor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-vec-tail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-subcomponent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-multiple-captures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-addr-of-imm-var.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-borrow-linear-errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-slice-of-imm-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-uniq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mutate-in-guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-no-cycle-in-exchange-heap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-object-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-or-init.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-and-overloaded-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-autoderef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-move-from-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-move-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-ref-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-pat-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-pat-reassign-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-pat-reassign-no-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-reborrow-from-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-ref-mut-of-imm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-reinit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-report-with-custom-diagnostic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-return-variable-on-stack-via-clone.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-rvalues-mutable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-static-item-in-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-storage-dead.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-struct-update-with-dtor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-swap-mut-base-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-trait-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unary-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unboxed-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-after-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-field-access.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-in-assignop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-ref-chain.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-borrow-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-move-assign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-uninitialized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uniq-via-lend.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uniq-via-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-univariant-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unused-mut-locals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-in-index-lvalue.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-mut-borrow-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-mut-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-uninitialized-in-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-element-loan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-move-tail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-nesting.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-while-break.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-while-cond.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/borrowck-while.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/disallow-possibly-uninitialized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/immutable-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/index-mut-help-with-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/index-mut-help.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-10876.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-27282-mutation-in-guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-31287-drop-in-guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-41962.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-45983.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-47215-ice-from-drop-elab.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-51117.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-51415.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-52713-bug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-52967-edition-2018-needs-two-phase-borrows.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-of-moved-out.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-of-never-init.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-58776-borrowck-scans-children.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-62007-assign-box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-62007-assign-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-62107-match-arm-scopes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-64453.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-69789-iterator-mut-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/issue-7573.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/move-error-in-promoted-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/move-error-in-promoted.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/move-error-snippets-ext.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/move-error-snippets.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/move-from-union-field-issue-66500.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/move-in-pattern-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/move-in-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/move-in-static-initializer-issue-38520.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-in-loop-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-in-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-of-mut-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-outside-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/mutability-errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/or-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/promote-ref-mut-in-let-issue-46557.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/reassignment_immutable_fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/reassignment_immutable_fields_overlapping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/reassignment_immutable_fields_twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/regions-bound-missing-bound-in-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/regions-escape-bound-fn-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/regions-escape-bound-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/regions-escape-unboxed-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/return-local-binding-from-desugaring.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/slice-index-bounds-check-invalidation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-across-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-activation-sharing-interference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-allow-access-during-reservation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-baseline.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-bin-ops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-cannot-nest-mut-self-calls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-control-flow-split-before-activation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-method-receivers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-multi-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-multiple-activations.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-nonrecv-autoref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-sneaky.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/two-phase-surprise-no-conflict.rs create mode 100644 gcc/testsuite/rust/rustc/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bound-suggestions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bounds-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/box/alloc-unstable-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/box/alloc-unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/box/into-boxed-slice-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/box/into-boxed-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/box/leak-alloc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/box/new.rs create mode 100644 gcc/testsuite/rust/rustc/ui/break-diverging-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/break-outside-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/break-while-condition.rs create mode 100644 gcc/testsuite/rust/rustc/ui/btreemap/btreemap_into_iterator_lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bug-7183-generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/bug-7295.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-clone-unwind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-clone.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds-capabilities-transitive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds-capabilities-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds-capabilities.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds-in-metadata.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds-phantom-typaram.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds-typaram.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds/auxiliary/trait_superkinds_in_metadata.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-double-superkind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-in-metadata.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-self-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.rs create mode 100644 gcc/testsuite/rust/rustc/ui/by-move-pattern-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/byte-literals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/c-stack-returning-int64.rs create mode 100644 gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-no-fixed-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/can-begin-expr-check.rs create mode 100644 gcc/testsuite/rust/rustc/ui/can-copy-pod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cancel-clean-via-immediate-rvalue-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cannot-mutate-captured-non-mut-var.rs create mode 100644 gcc/testsuite/rust/rustc/ui/capture1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast-char.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast-does-fallback.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast-region-to-uint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast-rfc0401-vtable-kinds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast-rfc0401.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast-to-infer-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast/cast-as-bool.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast/cast-errors-issue-43825.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast/cast-from-nil.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast/cast-ptr-to-int-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast/cast-rfc0401-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast/cast-to-bare-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast/cast-to-nil.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cast/cast-to-unsized-trait-object-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/casts-differing-anon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/casts-issue-46365.rs create mode 100644 gcc/testsuite/rust/rustc/ui/catch-unwind-bang.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cenum_impl_drop_cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg-rustdoc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/auxiliary/cfg_inner_static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg-attr-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg-attr-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg-family.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg-in-crate-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg-macros-foo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg-macros-notfoo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg-match-arm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg-panic-abort.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg-target-family.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg-target-vendor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg_attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg_inner_static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfg_stmt_expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/cfgs-on-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/conditional-compile-arch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/conditional-compile.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfg/crate-attributes-using-cfg_attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cfguard-run.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/arithmetic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/builtin-copy-clone.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/chalk_initial_program.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/generic_impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/impl_wf.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/impl_wf_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/inherent_impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/inherent_impl_min.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/lower_env1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/lower_env2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/lower_env3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/lower_impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/lower_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/lower_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/lower_trait_higher_rank.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/lower_trait_where_clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/println.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/recursive_where_clause_on_type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/super_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/trait-objects.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/trait_implied_bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/type_implied_bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/type_inference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/chalkify/type_wf.rs create mode 100644 gcc/testsuite/rust/rustc/ui/changing-crates.rs create mode 100644 gcc/testsuite/rust/rustc/ui/char.rs create mode 100644 gcc/testsuite/rust/rustc/ui/char_unicode.rs create mode 100644 gcc/testsuite/rust/rustc/ui/check-doc-alias-attr-location.rs create mode 100644 gcc/testsuite/rust/rustc/ui/check-doc-alias-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/check-static-immutable-mut-slices.rs create mode 100644 gcc/testsuite/rust/rustc/ui/check-static-recursion-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/check-static-values-constraints.rs create mode 100644 gcc/testsuite/rust/rustc/ui/check_const-feature-gated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/child-outlives-parent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/class-cast-to-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/class-method-missing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/class-missing-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cleanup-arm-conditional.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cleanup-rvalue-during-if-and-while.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cleanup-rvalue-for-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cleanup-rvalue-scopes-cf.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cleanup-rvalue-scopes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cleanup-shortcircuit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/clone-with-exterior.rs create mode 100644 gcc/testsuite/rust/rustc/ui/close-over-big-then-small-data.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-fn-supply-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-infer-var-appearing-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closure-expected-type/issue-24421.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closure-expected.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closure_context/issue-26046-fn-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closure_context/issue-26046-fn-once.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closure_context/issue-42065.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closure_promotion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-array-break-length.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-bounds-static-cant-capture-borrowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-bounds-subtype.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-expected-type/expect-region-supply-region-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-expected-type/expect-region-supply-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-immutable-outer-variable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-move-sync.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-no-fn-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-no-fn-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-no-fn-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-referencing-itself-issue-25954.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-reform-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-return-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure-wrong-kind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure_cap_coerce_many_fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_check_pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_run_pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_unsafe_0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_unsafe_1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/deeply-nested_closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/diverging-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/issue-41366.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/issue-46742.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/issue-48109.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/issue-52437.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/issue-67123.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/issue-68025.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/issue-72408-nested-closures-exponential.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-trim-off-verbose-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-verbose-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-verbose-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/closures/print/closure-print-verbose.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cmp-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/gate_test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/params-on-registers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/params-on-stack.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/trustzone-only.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/wrong-abi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codegen-object-shim.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/bad-format-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/empty_span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/huge_multispan_highlight.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/issue-11715.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/issue-28308.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/one_line.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/overlapping_inherent_impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/tab.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/tab_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/tab_3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/two_files.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/two_files_data.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/unicode.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/unicode_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/codemap_tests/unicode_3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-expect-unsized-ascribed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-expect-unsized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-issue-49593-box-never.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-overloaded-autoderef-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-overloaded-autoderef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-ptr-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-ptr-rcvr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-vec-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-vec-rcvr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-multi-arg-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-multi-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-ptr-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-vec-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-vec-rcvr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-to-bang-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-to-bang.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-unify-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-unify.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coerce-unsize-subtype.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coercion-missing-tail-expected-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coercion/coercion-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_copy_like_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_fundamental_trait_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_inherent_cc_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_orphan_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/auxiliary/go_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/auxiliary/re_rebalance_coherence_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/auxiliary/trait_impl_conflict.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-all-remote.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-bigint-int.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-bigint-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-bigint-vecint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-conflicting-negative-trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-covered-type-parameter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-cow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-cross-crate-conflict.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-default-trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-error-suppression.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-fn-covariant-bound-vs-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-fn-implied-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-fn-inputs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-free-vs-bound-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-fundamental-trait-objects.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-in-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-impls-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-impls-send.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-impls-sized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-inherited-subtyping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-iterator-vec-any-elem.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-iterator-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-lone-type-parameter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-multidispatch-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-negative-impls-safe-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-negative-impls-safe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-no-direct-lifetime-dispatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-orphan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-all-t-and-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-downstream-inherent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-downstream.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-issue-23516-inherent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-issue-23516.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-messages.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-upstream-inherent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-upstream.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-overlapping-pairs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-pair-covered-uncovered-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-pair-covered-uncovered.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-conflict-orphan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-conflict-ty-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-conflict.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-ok-orphan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-rfc447-constrained.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-subtyping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-tuple-conflict.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-unsafe-trait-object-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-vec-local-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-vec-local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-wasm-bindgen.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence_inherent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence_inherent_cc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence_local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence_local_err_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence_local_err_tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/coherence_local_ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/conflicting-impl-with-err.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-foreign[foreign].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-foreign[local].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-fundamental[foreign].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-fundamental[local].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[foreign]-for-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[foreign]-for-local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign-for-foreign[t].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign-for-fundamental[t].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[foreign]-for-t.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-t.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-t.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/coherence/re-rebalance-coherence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/collections-const-new.rs create mode 100644 gcc/testsuite/rust/rustc/ui/command-line-diagnostics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/command/command-argv0-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/command/command-argv0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/command/command-exec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/command/command-pre-exec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/command/command-uid-gid.rs create mode 100644 gcc/testsuite/rust/rustc/ui/commandline-argfile-badutf8.rs create mode 100644 gcc/testsuite/rust/rustc/ui/commandline-argfile-missing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/commandline-argfile.rs create mode 100644 gcc/testsuite/rust/rustc/ui/compare-method/proj-outlives-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/compare-method/region-extra-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/compare-method/region-extra.rs create mode 100644 gcc/testsuite/rust/rustc/ui/compare-method/region-unrelated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/compare-method/reordered-type-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/compare-method/trait-bound-on-type-parameter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/compare-method/traits-misc-mismatch-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/compare-method/traits-misc-mismatch-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/compile_error_macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/complex.rs create mode 100644 gcc/testsuite/rust/rustc/ui/concat-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/concat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/auxiliary/namespaced_enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-cfg-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-crate-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-empty-is-unused.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-invalid-predicate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-false.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-true.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-parse.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-syntax-validation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-empty-codemap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-generic-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-in-crate-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-non-opt-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible-input-validation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible-stuck.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible-unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_attr_path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conflicting-repr-hints.rs create mode 100644 gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-18343.rs create mode 100644 gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-2392.rs create mode 100644 gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-32128.rs create mode 100644 gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-33784.rs create mode 100644 gcc/testsuite/rust/rustc/ui/confuse-field-and-method/private-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conservative_impl_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/apit-with-const-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/argument_order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/array-impls/alloc-traits-impls-length-33.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/array-impls/alloc-types-impls-length-33.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/array-impls/core-traits-impls-length-32.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/array-impls/core-traits-impls-length-33.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/array-impls/into-iter-impls-length-32.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/array-impls/into-iter-impls-length-33.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/array-size-in-generic-struct-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/array-wrapper-struct-ctor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/associated-type-bound-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/associated-type-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/auxiliary/const_generic_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/auxiliary/crayte.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/auxiliary/impl-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/broken-mir-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/broken-mir-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/cannot-infer-type-for-const-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/closing-args-token.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/coerce_unsized_array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/concrete-const-as-fn-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/concrete-const-impl-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/condition-in-trait-const-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-arg-in-const-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-arg-in-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-arg-type-arg-misordered.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-argument-cross-crate-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-argument-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-argument-if-length.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-argument-non-static-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-expression-parameter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-fn-with-const-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-generic-array-wrapper.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-generic-type_name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-param-after-const-literal-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-param-before-other-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-param-elided-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-param-from-outer-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-param-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-param-in-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-param-in-trait-ungated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-param-in-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-param-type-depends-on-const-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-param-type-depends-on-type-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-parameter-uppercase-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/associated-consts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/auxiliary/const_evaluatable_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/cross_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/different-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/division.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/fn_call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/from-sig.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/impl-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/infer-too-generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/less_than.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/let-bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-err-where-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-ok-infer-err.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/simple_fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/unop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/unused_expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/core-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/cross_crate_complex.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/defaults/complex-unord-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/defaults/intermixed-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/defaults/needs-feature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/defaults/simple-defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/defaults/wrong-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/derive-debug-array-wrapper.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/different_byref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/different_byref_simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/dyn-supertraits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/exhaustive-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/fn-const-param-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/fn-const-param-infer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/fn-taking-const-generic-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/forbid-non-structural_match-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/foreign-item-const-parameter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/generic-function-call-in-array-length.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/generic-param-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/generic-sum-in-array-length.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/impl-const-generic-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/impl-trait-with-const-arguments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/incorrect-number-of-const-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/infer/cannot-infer-const-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/infer/issue-77092.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/infer/method-chain.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/infer/uninferred-consts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/infer_arg_from_pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/infer_arr_len_from_pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/intrinsics-type_name-as-const-argument.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/invalid-const-arg-for-type-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/invalid-constant-in-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/invalid-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issue-61522-array-len-succ.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issue-67375.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issue-67945-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issue-67945-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issue-67945-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issue-68104-print-stack-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issue-70180-1-stalled_on.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issue-70180-2-stalled_on.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issue-71986.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issue-74906.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-56445.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-60263.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-60818-struct-constructors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61336-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61336-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61336.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61422.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61432.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61747.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61935.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62220.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62456.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62504.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62579-no-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62878.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-63322-forbid-dyn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-64494.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-64519.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-66205.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-66906.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-67185-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-67185-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-67739.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68366.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68596.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68615-adt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68615-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68977.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-69654-run-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-69654.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70125-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70125-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70167.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70225.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71169.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71381.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71382.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71611.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-72352.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-72787.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73120.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73260.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73491.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73508.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74101.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74255.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74634.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74950.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-75047.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-75299.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-76595.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-76701-ty-param-in-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/issues/issue70273-assoc-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/macro_rules-braces.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min-and-full-same-time.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/assoc_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/complex-expression.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/complex-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const_fn_in_generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/default_function_param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/default_trait_param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/feature-gate-min_const_generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/invalid-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/macro-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/self-ty-in-const-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/self-ty-in-const-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/static-reference-array-const-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/mut-ref-const-param-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/nested-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/bind-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unify-fixpoint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unify-n-nplusone.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/raw-ptr-const-param-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/raw-ptr-const-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/slice-const-param-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/slice-const-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/std/const-generics-range.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/struct-with-invalid-const-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/trait-const-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/transparent-maybeunit-array-wrapper.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-after-const-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/const-arg-in-const-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-61936.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-63695.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-67144-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-67144-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-69816.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-70217.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-70507.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-70586.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-71348.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-71382.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-71805.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-73730.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/non-local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/qpath.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/type_of_anon_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/types-mismatch-const-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/uninferred-consts-during-codegen-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/uninferred-consts-during-codegen-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/unknown_adt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/unused-const-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/unused_braces.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/wf-misc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-generics/where-clauses.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const-suggest-feature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const_evaluatable/associated-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const_evaluatable/function-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const_prop/ice-assert-fail-div-by-zero.rs create mode 100644 gcc/testsuite/rust/rustc/ui/const_prop/inline_spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/constructor-lifetime-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/array-literal-index-oob.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/array-to-slice-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/ascii_ctype.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/assoc-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/assoc_const_generic_impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/associated_const_generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/async-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/auxiliary/cci_borrow_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/auxiliary/cci_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/auxiliary/cci_const_block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/auxiliary/const_fn_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/auxiliary/external_macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/auxiliary/issue-63226.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/auxiliary/promotable_const_fn_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/bswap-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/cast-discriminant-zst-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/chained-constants-stackoverflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-address-of-interior-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-address-of-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-address-of.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-adt-align-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-array-oob-arith.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-array-oob.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-autoderef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-big-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-binops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-bitshift-rhs-inference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-block-cross-crate-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-block-item-macro-codegen.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-block-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-block-non-item-statement-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-block-non-item-statement-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-block-non-item-statement.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-byte-str-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-cast-different-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-cast-ptr-int.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-cast-wrong-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-contents.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-cross-crate-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-cross-crate-extern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-deref-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-endianess.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-byref-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-byref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-struct2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-structlike.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-tuple2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-tuplestruct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-tuplestruct2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-vec-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-vec-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-enum-vector.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-err-early.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-err-multi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-err-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-err.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-err2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-err4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/assign-to-static-within-other-static-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/assign-to-static-within-other-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/auxiliary/stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/conditional_array_execution.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-intrinsic-promotion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-3b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-4b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow2b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow2c.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-query-stack.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const-pointer-values-in-various-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const_fn_ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const_fn_ptr_fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const_fn_ptr_fail2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const_let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const_panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const_panic_libcore_bin.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const_prop_errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const_raw_ptr_ops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const_raw_ptr_ops2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const_signed_pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/const_transmute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/dangling.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/dont_promote_unstable_const_fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/double_check.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/double_check2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/double_promotion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/duration_conversion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/enum_discr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/erroneous-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/extern_fat_pointer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/feature-gate-const_fn_union.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/feature-gate-const_panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/generic-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/ice-generic-assoc-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/ice-packed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/index-out-of-bounds-never-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/index_out_of_bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/index_out_of_bounds_propagated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/infinite_loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-43197.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-44578.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-47971.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-49296.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-50706.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-50814-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-50814.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-51300.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-52442.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-52475.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-53157.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-53401.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-55541.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-64908.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-64970.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-65394.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-70723.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-70804-fn-subtyping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/livedrop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/match-test-ptr-null.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/mod-static-with-const-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/no_lint_for_statically_known_error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/nrvo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/panic-assoc-never-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/panic-never-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/promote-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_const_fn_fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_raw_ptr_ops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/pub_const_err.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/pub_const_err_bin.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/ref_to_int_match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/shift_overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/simd/insert_extract.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/simple_with_undef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/strlen.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/transmute-const-promotion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/transmute-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-int-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-nonnull.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-uninhabit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-upvars.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-wide-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/union-const-eval-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/union-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/union-ub.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/union_promotion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/unused-broken-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/unwind-abort.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/valid-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/validate_uninhabited_zsts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-eval/zst_operand_eval.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-expr-addr-operator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-expr-in-fixed-length-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-expr-in-vec-repeat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-extern-function.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-external-macro-const-err.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fields-and-indexing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-float-bits-conv.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-float-classify.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-const-eval.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-destructuring-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-feature-flags.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-not-in-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-not-safe-for-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-stability-calls-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-stability-calls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-type-name-any.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-type-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-val.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn-zst-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-index-feature-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-arithmetic-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-arithmetic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-conversion-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-conversion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-overflowing-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-overflowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-pow-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-rotate-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-rotate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-saturating-arith.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-sign-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-sign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-unchecked.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-wrapping-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-int-wrapping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-integer-bool-ops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-labeled-break.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-len-underflow-separate-spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-len-underflow-subspans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-match-check.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-match-pattern-arm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-meth-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-multi-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-mut-refs/const_mut_address_of.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-mut-refs/const_mut_refs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-mut-refs/feature-gate-const_mut_refs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-needs_drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-negation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-negative.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-nullary-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-nullary-univariant-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-pattern-irrefutable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-pattern-not-const-evaluable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-pattern-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-points-to-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-prop-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-prop-ice2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-prop-ice3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-prop-overflowing-casts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-prop-read-static-in-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-ptr-nonnull-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-ptr-nonnull.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-ptr-unique-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-ptr-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-rec-and-tup.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-region-ptrs-noncopy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-region-ptrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-repeated-values.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-size_of-align_of.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-size_of-cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-size_of_val-align_of_val-extern-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-size_of_val-align_of_val.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-slice-oob.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-str-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-struct-offsets.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-trait-to-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-tup-index-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-typeid-of-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-unit-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-unsafe-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-unsized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-unwrap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-validation-fail-55455.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-variant-count.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-vec-of-fns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-vec-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const-vecs-and-slices.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_arg_local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_arg_promotable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_arg_promotable2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_arg_wrapper.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_constructor/const-construct-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_constructor/const_constructor_qpath.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_discriminant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_fn_floating_point_arithmetic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_fn_return_nested_fn_ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_forget.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/accept_structural.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/auxiliary/consts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/cross-crate-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/cross-crate-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/custom-eq-branch-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/custom-eq-branch-warn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-44333.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-53708.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-62614.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-65466.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-73431.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-78057.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/no-eq-branch-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/reject_non_partial_eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/reject_non_structural.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/warn_corner_cases.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_let_assign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_let_assign2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_let_assign3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_let_eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_let_eq_float.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_let_irrefutable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_let_promote.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_let_refutable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_limit/const_eval_limit_not_reached.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_limit/const_eval_limit_overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_limit/const_eval_limit_reached.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_limit/feature-gate-const_eval_limit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_prop_slice_pat_ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_short_circuit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_unsafe_unreachable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/const_unsafe_unreachable_ub.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/consts-in-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/assert.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/basics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/drop-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/drop-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/drop-precise.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/exhaustive-c-like-enum-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/feature-gate-const-if-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/interior-mutability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/issue-46843.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/issue-50577.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/short-circuit-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/short-circuit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/single_variant_match_ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/control-flow/try.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/dangling-alloc-id-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/dangling_raw_ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/deref_in_pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/drop_none.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/enum-discr-type-err.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/huge-values.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/ice-48279.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/ice-zst-static-access.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/inline_asm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/int_ptr_for_zst_slices.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/invalid_promotion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-37550.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-51559.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-52432.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-54224.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-56164.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-62045.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-63226.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-63952.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-64059.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-64506.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-64662.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-65348.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-66342.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-66345.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-66397.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-66787.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-67529.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-67640.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-67641.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-67696-const-prop-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-67862.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-68264-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-68542-closure-in-array-len.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-68684.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-69310-array-size-lit-wrong-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-69312.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-70773-mir-typeck-lt-norm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-70942-trait-vs-impl-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-73976-monomorphic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-73976-polymorphic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-77062-large-zst-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-78655.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/issue-broken-mir.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/locals-in-const-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/match-const-fn-structs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/match_ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/address_of.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/address_of_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/allow_const_fn_ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/allow_raw_ptr_dereference_const_fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/bad_const_fn_body_ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/cast_errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/cmp_fn_pointers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_dyn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_fn_ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_impl_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_libstd.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_unsafe_ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/mutable_borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/min_const_fn/promotion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/abi-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/assoc_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/assoc_const_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/auxiliary/static_cross_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/const_refers_to_static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/const_refers_to_static2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/inline_asm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/mutable_references.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/mutable_references_err.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/mutating_global.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/non_const_fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/ptr_arith.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/raw_mutable_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/slice_eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/tls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/mozjs-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/non-scalar-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/offset.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/offset_from.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/offset_from_ub.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/offset_ub.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/packed_pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/packed_pattern2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/partial_qualif.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/projection_qualif.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/promote-not.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/promote_borrowed_field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/promote_const_let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/promote_evaluation_unused_result.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/promote_fn_calls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/promote_fn_calls_std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/promoted-validation-55454.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/promoted_div_by_zero.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/promoted_regression.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/promotion-mutable-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/promotion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/ptr_comparisons.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/ptr_is_null.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/qualif_overwrite.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/qualif_overwrite_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/raw-ptr-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/raw_pointer_promoted.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/read_from_static_mut_ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/recursive-zst-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/references.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/repeat_match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/return-in-const-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/fn-call-in-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/fn-call-in-non-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/nll-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/run-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/self_normalization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/self_normalization2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/signed_enum_discr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/stable-precise-live-drops-in-libcore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/static-cycle-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/static-raw-pointer-interning.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/static-raw-pointer-interning2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/static_mut_containing_mut_ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/static_mut_containing_mut_ref2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/static_mut_containing_mut_ref3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/std/alloc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/std/cell.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/std/iter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/std/slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/too_generic_eval_ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/trait_specialization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/transmute-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/transmute-size-mismatch-before-typeck.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/tuple-struct-constructors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/underscore_const_names.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/uninhabited-const-issue-61744.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/union_constant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/unsizing-cast-non-null.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/unstable-const-fn-in-libcore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/unstable-precise-live-drops-in-libcore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/unwind-abort.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/validate_never_arrays.rs create mode 100644 gcc/testsuite/rust/rustc/ui/consts/zst_no_llvm_alloc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/continue-after-missing-main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/conversion-methods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/copy-a-resource.rs create mode 100644 gcc/testsuite/rust/rustc/ui/core-run-destroy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/crate-in-paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/crate-leading-sep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/crate-method-reexport-grrrrrrr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/crate-name-attr-used.rs create mode 100644 gcc/testsuite/rust/rustc/ui/crate-name-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/anon_trait_static_method_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_borrow_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_capture_clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_impl_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_iter_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_nested_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_no_inline_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/moves_based_on_type_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/newtype_struct_xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/pub_static_array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/reexported_static_methods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_address_insignificant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_associated_type_defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_static_addresses.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_unit_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/cci_borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/cci_capture_clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/cci_impl_exe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/cci_iter_exe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/cci_nested_exe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/cci_no_inline_exe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/cross-crate-const-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/cross-crate-newtype-struct-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/a_def_obj.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/b_reexport_obj.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/c_another_vtable_for_obj.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/d_chain_of_rlibs_and_dylibs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/issue-64872.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/moves-based-on-type-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/reexported-static-methods-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/static-array-across-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-address-insignificant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-associated-type-defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-static-addresses.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-trait-lifetime-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-unit-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross-crate/xcrate_generic_fn_nested_return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross/cross-borrow-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross/cross-crate-macro-backtrace/auxiliary/extern_macro_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross/cross-crate-macro-backtrace/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross/cross-file-errors/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross/cross-file-errors/underscore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cross/cross-fn-cache-hole.rs create mode 100644 gcc/testsuite/rust/rustc/ui/crt-static-off-works.rs create mode 100644 gcc/testsuite/rust/rustc/ui/crt-static-on-works.rs create mode 100644 gcc/testsuite/rust/rustc/ui/custom-attribute-multisegment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/custom-test-frameworks-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/custom_attribute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/custom_test_frameworks/auxiliary/dynamic_runner.rs create mode 100644 gcc/testsuite/rust/rustc/ui/custom_test_frameworks/auxiliary/example_runner.rs create mode 100644 gcc/testsuite/rust/rustc/ui/custom_test_frameworks/dynamic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/custom_test_frameworks/full.rs create mode 100644 gcc/testsuite/rust/rustc/ui/custom_test_frameworks/mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cycle-generic-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cycle-projection-based-on-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cycle-trait/cycle-trait-default-type-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cycle-trait/cycle-trait-supertrait-direct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/cycle-trait/cycle-trait-supertrait-indirect.rs create mode 100644 gcc/testsuite/rust/rustc/ui/debuginfo-lto.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deduplicate-diagnostics-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deduplicate-diagnostics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/default-alloc-error-hook.rs create mode 100644 gcc/testsuite/rust/rustc/ui/default-associated-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/default-method-parsing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/default-method-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/defaults-well-formedness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/definition-reachable/auxiliary/field-method-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/definition-reachable/auxiliary/nested-fn-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/definition-reachable/auxiliary/private-use-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/definition-reachable/field-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/definition-reachable/nested-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/definition-reachable/private-non-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/definition-reachable/private-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/definition-reachable/private-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-assoc-type-codegen.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-caller-callee.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-struct-signature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-trait-impl-two-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-type-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-variance-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation-in-force-unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/atomic_initializers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/auxiliary/deprecation-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/deprecated-macro_escape-inner.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/deprecated-macro_escape.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/deprecated_no_stack_check.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/deprecation-in-future.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/deprecation-in-staged-api.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/deprecation-sanity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/derive_on_deprecated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/derive_on_deprecated_forbidden.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/invalid-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/rustc_deprecation-in-future.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deprecation/suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deref-mut-on-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deref-non-pointer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deref-on-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deref-rc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deref-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derive-uninhabited-enum-38885.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derived-errors/issue-30580.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derived-errors/issue-31997-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derived-errors/issue-31997.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/auxiliary/derive-marker-tricky.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derive-assoc-type-not-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derive-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derive-marker-tricky.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derive-on-trait-item-or-impl-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-enum-struct-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-enum-struct-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Default-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Default-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-enum-struct-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-enum-struct-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-enum-struct-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-enum-struct-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/deriving-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/deriving-copyclone.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/deriving-meta-empty-trait-list.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/deriving-meta-unknown-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/deriving-no-inner-impl-error-message.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/deriving-non-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/deriving-primitive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/derives/deriving-with-repr-packed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/auxiliary/derive-no-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/derive-no-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/derive-partialord-correctness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-associated-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-generic-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-generic-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-generic-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-struct-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-shortcircuit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-copyclone.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-default-box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-enum-single-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-eq-ord-boxed-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-hash.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-in-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-in-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-meta-multiple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-meta.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-show-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-show.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-c-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-hash-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-hash-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct-empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-type-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/deriving/deriving-with-repr-packed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dest-prop/skeptic-miscompile.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructure-trait-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/default-match-bindings-forbidden.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/nested_destructure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/note-unsupported.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/slice_destructure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/slice_destructure_fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/struct_destructure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/struct_destructure_fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_destructure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_destructure_fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_struct_destructure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_struct_destructure_fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/underscore-range-expr-gating.rs create mode 100644 gcc/testsuite/rust/rustc/ui/destructuring-assignment/warn-unused-duplication.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/E0178.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/bad-assoc-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/bad-assoc-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/bad-assoc-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-31424.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-34126.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-34337.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-35937.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-36798.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-36798_unknown_field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-37139.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-39544.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-39802-show-5-trait-impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-40006.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-40396.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-40823.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-42599_available_fields_note.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-42764.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-54109-without-witness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/pub-macro-rules.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/recursion_limit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/recursion_limit_deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/recursion_limit_macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/directory_ownership/foo/mod_file_not_owning/aux2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/directory_ownership/foo/mod_file_not_owning_aux2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/directory_ownership/macro-expanded-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/directory_ownership/macro_expanded_mod_helper/foo/bar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/directory_ownership/macro_expanded_mod_helper/foo/mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux1/mod_file_not_owning_aux2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/directory_ownership/non-inline-mod-restriction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/disambiguate-identical-names.rs create mode 100644 gcc/testsuite/rust/rustc/ui/discrim/discrim-ill-typed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/discrim/discrim-overflow-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/discrim/discrim-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/diverging-fallback-method-chain.rs create mode 100644 gcc/testsuite/rust/rustc/ui/diverging-fallback-option.rs create mode 100644 gcc/testsuite/rust/rustc/ui/diverging-fn-tail-35849.rs create mode 100644 gcc/testsuite/rust/rustc/ui/diverging-tuple-parts-39485.rs create mode 100644 gcc/testsuite/rust/rustc/ui/doc-alias-crate-level.rs create mode 100644 gcc/testsuite/rust/rustc/ui/does-nothing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dollar-crate/dollar-crate-is-keyword-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dollar-crate/dollar-crate-is-keyword.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dont-suggest-private-trait-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dotdotdot-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/double-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/double-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/double-type-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop-bounds/drop-bounds-impl-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop-bounds/drop-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/auxiliary/dropck_eyepatch_extern_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/drop-on-empty-block-exit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/drop-on-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/drop-struct-as-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/drop-trait-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/drop-trait-generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/drop-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/drop-uninhabited-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/drop-with-type-ascription-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/drop-with-type-ascription-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/dropck-eyepatch-extern-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/dropck-eyepatch-reorder.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/dropck-eyepatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/dropck_legal_cycles.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/dynamic-drop-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/dynamic-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/no-drop-flag-size.rs create mode 100644 gcc/testsuite/rust/rustc/ui/drop/nondrop-cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/auxiliary/dropck_eyepatch_extern_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/drop-on-non-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/drop-with-active-borrows-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/drop-with-active-borrows-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch-extern-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch-implies-unsafe-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch-reorder.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/dropck-union.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/dropck_fn_type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/dropck_trait_cycle_checked.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dropck/dropck_traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-bad-assign-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-bad-assign-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-bad-assign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-bad-coercions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-bad-deep-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-bad-deep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-object-from-unsized-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-rvalue.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dst/dst-sized-trait-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-7.rs create mode 100644 gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-8.rs create mode 100644 gcc/testsuite/rust/rustc/ui/duplicate/duplicate-check-macro-exports.rs create mode 100644 gcc/testsuite/rust/rustc/ui/duplicate/duplicate-parameter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/duplicate/duplicate-type-parameter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/duplicate_entry_error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dyn-trait-compatibility.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-coerce-custom.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-coerce-rc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-coercions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-deref-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-field-align.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-irrefutable-bind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-raw.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-struct-sole.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-trait-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple-no-reorder.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple-sole.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs create mode 100644 gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/early-ret-binop-add.rs create mode 100644 gcc/testsuite/rust/rustc/ui/early-vtbl-resolution.rs create mode 100644 gcc/testsuite/rust/rustc/ui/edition-keywords-2015-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/edition-keywords-2015-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/edition-keywords-2018-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/edition-keywords-2018-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/async-block-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/auxiliary/absolute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-extern-crate-allowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-imports-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-imports-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-kw-macro-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-kw-macro-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-extern-crate-allowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-feature-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-feature-redundant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-imports-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-imports-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-imports-virtual-2015-ambiguity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-imports-virtual-2015-gated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2015-expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2015-parsing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2018-expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2018-parsing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2015-expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2015-parsing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2018-expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2018-parsing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-raw-pointer-method-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/editions/edition-raw-pointer-method-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/elide-errors-on-mismatched-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/elided-test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/else-if.rs create mode 100644 gcc/testsuite/rust/rustc/ui/emit-artifact-notifications.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty-allocation-non-null.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty-allocation-rvalue-non-null.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty-type-parameter-list.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/auxiliary/empty-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/auxiliary/two_macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/empty-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/empty-linkname.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/empty-macro-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/empty-never-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-pat-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-pat-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-pat-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/empty-struct-tuple-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/empty-struct-unit-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty/empty-struct-unit-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/empty_global_asm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enable-unstable-lib-feature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/actually_not_an_enum-discriminant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/arbitrary_enum_discriminant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/discriminant_size.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/discriminant_value-wrapper.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/discriminant_value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/forbidden-discriminant-kind-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70509-partial_eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/niche.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum-discriminant/repr128.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/enum-and-module-in-same-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/enum-discrim-autosizing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/enum-discrim-too-small.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/enum-discrim-too-small2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/enum-in-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/enum-size-variance.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/enum-to-float-cast-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/enum-to-float-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/enum-variant-type-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/issue-67945-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/issue-67945-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/nested-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enum/union-in-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/enums-pats-not-idents.rs create mode 100644 gcc/testsuite/rust/rustc/ui/env-args-reverse-iterator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/env-funky-keys.rs create mode 100644 gcc/testsuite/rust/rustc/ui/env-home-dir.rs create mode 100644 gcc/testsuite/rust/rustc/ui/env-null-vars.rs create mode 100644 gcc/testsuite/rust/rustc/ui/env-vars.rs create mode 100644 gcc/testsuite/rust/rustc/ui/epoch-gate-feature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/eprint-on-tls-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/eq-multidispatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0001.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0004-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0004.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0005.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0010-teach.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0010.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0017.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0023.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0025.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0026-teach.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0026.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0027.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0029-teach.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0029.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0030-teach.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0030.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0033-teach.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0033.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0034.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0038.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0040.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0044.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0045.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0049.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0050.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0054.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0055.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0057.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0059.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0060.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0061.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0062.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0063.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0067.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0069.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0070.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0071.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0075.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0076.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0077.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0080.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0081.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0084.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0091.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0092.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0093.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0094.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0106.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0107.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0109.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0110.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0116.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0117.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0118-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0118.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0119.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0120.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0121.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0124.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0128.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0130.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0131.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0132.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0133.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0137.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0138.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0152.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0161.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0164.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0184.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0185.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0186.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0191.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0194.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0195.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0197.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0198.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0199.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0200.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0201.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0206.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0207.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0214.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0220.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0221.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0223.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0225.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0229.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0252.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0253.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0254.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0255.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0259.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0260.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0261.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0262.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0263.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0264.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0267.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0268.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0271.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0275.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0276.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0277-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0277.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0282.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0283.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0297.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0308-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0308-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0308.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0328.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0365.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0370.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0374.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0375.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0376.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0388.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0389.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0390.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0392.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0393.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0395.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0396-fixed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0396.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0401.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0403.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0404.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0405.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0407.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0408.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0411.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0412.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0415.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0416.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0423.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0424.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0425.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0426.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0428.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0429.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0430.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0431.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0432.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0433.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0434.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0435.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0437.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0438.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0439.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0445.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0446.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0449.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0451.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0452.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0453.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0454.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0458.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0459.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0463.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0478.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0490.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0492.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0496.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0499.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0501.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0502.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0503.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0504.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0505.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0506.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0507.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0508-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0508.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0509.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0511.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0512.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0516.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0517.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0518.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0520.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0522.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0527.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0528.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0529.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0530.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0532.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0534.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0559.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0560.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0565-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0565-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0565.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0572.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0582.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0583.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0585.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0586.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0594.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0596.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0597.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0599.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0600.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0601.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0602.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0603.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0604.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0605.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0606.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0607.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0608.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0609.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0610.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0614.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0615.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0616.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0617.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0618.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0620.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0621-does-not-trigger-for-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0622.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0624.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0637.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0642.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0646.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0647.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0648.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0657.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0658.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0659.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0660.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0661.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0662.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0663.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0664.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0665.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0705.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0718.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0719.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0730.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0746.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0767.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0771.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0777.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0778.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/E0779.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/e0119/auxiliary/complex_impl_support.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/e0119/auxiliary/issue-23563-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/e0119/complex-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/e0119/conflict-with-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/e0119/issue-23563.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/e0119/issue-27403.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/e0119/issue-28981.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/e0119/so-37347311.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/ex-E0611.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-codes/ex-E0612.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-festival.rs create mode 100644 gcc/testsuite/rust/rustc/ui/error-should-say-copy-not-pod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/estr-subtyping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/estr-uniq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/eval-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/exclusive-drop-and-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/exec-env.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expanded-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/explain.rs create mode 100644 gcc/testsuite/rust/rustc/ui/explicit-i-suffix.rs create mode 100644 gcc/testsuite/rust/rustc/ui/explicit/explicit-call-to-dtor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/explicit/explicit-call-to-supertrait-dtor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/explicit/explicit-self-lifetime-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/explore-issue-38412.rs create mode 100644 gcc/testsuite/rust/rustc/ui/export-fully-qualified.rs create mode 100644 gcc/testsuite/rust/rustc/ui/export-glob-imports-target.rs create mode 100644 gcc/testsuite/rust/rustc/ui/export-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/export-multi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/export-non-interference2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/export-non-interference3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/export-tag-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/export.rs create mode 100644 gcc/testsuite/rust/rustc/ui/export2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-block-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-block-generic-unique1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-block-generic-unique2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-block-generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-block-slot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-block-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-empty-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-if-generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-if-panic-all.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-if-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-if-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-if.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/expr_attr_paren_order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ext-expand-inner-exprs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ext-nonexistent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extend-for-unit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extenv/extenv-arg-2-not-string-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extenv/extenv-no-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extenv/extenv-not-defined-custom.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extenv/extenv-not-defined-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extenv/extenv-not-string-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extenv/extenv-too-many-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extenv/issue-55897.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern-flag/auxiliary/somedep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern-flag/multiple-opts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern-flag/noprelude-and-prelude.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern-flag/noprelude-resolves.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern-flag/noprelude.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern-flag/public-and-private.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern-prelude-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern-prelude.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern-take-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern-types-inherent-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern_calling_convention.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern_mod_ordering_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/auxiliary/fat_drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/auxiliary/m1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/auxiliary/m2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-calling-convention-test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-compare-with-return-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-crate-rename.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-crate-visibility.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-ffi-fn-with-body.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-foreign-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-main-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-methods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-mod-abi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-mod-ordering-exe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-prelude-core.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-prelude-no-speculative.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-prelude-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-pub.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-rust.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-take-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-thiscall.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-types-distinct-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-types-inherent-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-types-manual-sync-send.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-types-not-sync-send.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-types-pointer-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-types-size_of_val.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-types-thin-pointer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-types-trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-types-unsized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-vectorcall.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-with-type-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern-wrong-value-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/extern_fat_drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/external-doc-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/issue-36122-accessing-externed-dst.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extoption_env-no-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extoption_env-not-defined.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extoption_env-not-string-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/extoption_env-too-many-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fact.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fail-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fat-lto.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fat-ptr-cast-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fat-ptr-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fds-are-cloexec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate-inline_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate-isa_attribute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate-optimize_attribute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/allow-features-empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/allow-features.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/duplicate-features.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/feature-gate-c_variadic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/feature-gate-static-nobundle-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-bench.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-deprecated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-derive-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-derive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-macro_escape.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-macro_use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-stable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/issue-49983-see-issue-0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/rustc-private.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/stability-attribute-consistency.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/unknown-feature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gate/unstable-attribute-allow-issue-0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gated-feature-in-macro-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/auxiliary/cfg-target-thread-local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/auxiliary/pub_dep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/auxiliary/re_rebalance_coherence_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/bench.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi-avr-interrupt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi_unadjusted.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-alloc-error-handler.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allocator_internals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow_fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-arbitrary-self-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-asm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-asm2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-assoc-type-defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-associated_type_bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-box-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-box_patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-box_syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-target-has-atomic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-target-thread-local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-version.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg_sanitize.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-compiler-builtins.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-concat_idents.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-concat_idents2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-concat_idents3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const-indexing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_fn_transmute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_generics-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-crate_visibility_modifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-custom_attribute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-custom_attribute2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-custom_test_frameworks.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-decl_macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-default_type_parameter_fallback.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-destructuring_assignment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_keyword.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_masked.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_spotlight.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-exclusive-range-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-exhaustive-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-extern_absolute_paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-extern_prelude.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-extern_types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-external_doc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-feature-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-ffi_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-ffi_pure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-ffi_returns_twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-format_args_nl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-fundamental.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-generators.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-generic_associated_types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-global_asm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-impl_trait_in_bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-in_band_lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-infer_static_outlives_requirements.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-intrinsics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-is_sorted.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-label_break_value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-lang-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-link_args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-link_cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-link_llvm_intrinsics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-linkage.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-lint-reasons.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-log_syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-log_syntax2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-marker_trait_attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-may-dangle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-member-constraints.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-min_const_fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-naked_functions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-needs-allocator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-negate-unsigned.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-never_type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-nll.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-no_core.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-no_sanitize.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-non_ascii_idents.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-optin-builtin-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-overlapping_marker_traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-plugin_registrar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-prelude_import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-profiler-runtime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-public_private_dependencies.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-register_attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-register_tool.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-repr-simd.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-repr128.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc-attrs-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc_const_unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-simd-ffi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-simd.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-staged_api.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-start.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-static-nobundle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-stmt_expr_attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-thread_local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trace_macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trait-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-transparent_unions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trivial_bounds-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trivial_bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-try_blocks.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-try_reserve.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-type_alias_impl_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-type_ascription.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-method-calls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-ufcs-calls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsafe_block_in_unsafe_fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsized_fn_params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsized_locals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-untagged_unions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unwind-attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ffi_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ffi_const2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ffi_pure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ffi_returns_twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/filter-block-view-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fixup-deref-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/float-literal-inference-restrictions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fmt/feature-gate-format-args-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fmt/format-args-capture-macro-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fmt/format-args-capture-missing-variables.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fmt/format-args-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fmt/format-string-error-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fmt/format-string-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fmt/incorrect-separator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fmt/send-sync.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fn-in-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fn/dyn-fn-alignment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fn/expr-fn-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fn/fn-bad-block-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fn/fn-closure-mutable-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fn/fn-compare-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fn/fn-item-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fn/fn-trait-formatting.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fn_must_use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/auto-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/break-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/break.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/for-destruct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-goofiness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-has-unit-body.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-into-iterator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-lifetime-of-unbound-values.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-mut-ref-element.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-no-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-break.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-hashmap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-put-structured.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-simple-outer-slot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/label_break_value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/labeled-break.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/linear-for-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/liveness-loop-break.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/liveness-move-in-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/loop-break-cont-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/loop-break-cont.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/loop-break-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/loop-diverges.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/loop-label-shadowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/loop-labeled-break-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/loop-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/while-cont.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/while-flow-graph.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/while-label.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/while-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/while-loop-constraints-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/while-prelude-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/while-with-break.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for-loop-while/while.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for/for-c-in-str.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for/for-expn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for/for-loop-bogosity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for/for-loop-refutable-pattern-error-message.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for/for-loop-type-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/for/for-loop-unconstrained-element-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/foreign-fn-return-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/foreign-unsafe-fn-called.rs create mode 100644 gcc/testsuite/rust/rustc/ui/foreign/auxiliary/fn-abi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/foreign/foreign-fn-linkname.rs create mode 100644 gcc/testsuite/rust/rustc/ui/foreign/foreign-int-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/foreign/foreign-mod-src/inner.rs create mode 100644 gcc/testsuite/rust/rustc/ui/foreign/foreign-mod-unused-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/foreign/foreign-src/foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/foreign/foreign-truncated-arguments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/foreign/foreign2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/foreign/issue-74120-lowering-of-ffi-block-bodies.rs create mode 100644 gcc/testsuite/rust/rustc/ui/format-no-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fsu-moves-and-copies.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fully-qualified-type/fully-qualified-type-name1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fully-qualified-type/fully-qualified-type-name2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fully-qualified-type/fully-qualified-type-name4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fun-call-variants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/fun-indirect-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functional-struct-update/functional-struct-update-noncopyable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functional-struct-update/functional-struct-update-respects-privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/auxiliary/fn-abi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/call-closure-from-overloaded-op.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/capture-clauses-boxed-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/capture-clauses-unboxed-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/clone-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/closure-bounds-can-capture-chan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/issue-38714.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/supply-just-return-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/supply-nothing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/closure-immediate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/closure-inference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/closure-inference2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/closure-reform.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/closure-returning-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/closure-to-fn-coercion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/closure_to_fn_coercion-expected-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/copy-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/fn-abi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-assign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-coerce-to-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-size.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-spawn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/fn-coerce-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/fn-item-type-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/fn-item-type-coerce.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/fn-item-type-zero-sized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/fn-lval.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/fn-type-infer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/implied-bounds-closure-arg-outlives.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/nullable-pointer-opt-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/parallel-codegen-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/functions-closures/return-from-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/future-incompatible-lint-group.rs create mode 100644 gcc/testsuite/rust/rustc/ui/gated-bad-feature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/addassign-yield.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/async-generator-issue-67158.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/auto-trait-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/auxiliary/xcrate-reachable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/auxiliary/xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/borrow-in-tail-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/borrowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/conditional-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/control-flow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/discriminant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/drop-and-replace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/drop-env.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/dropck-resume.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/dropck.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/generator-region-requirements.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/generator-resume-after-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/generator-with-nll.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/generator-yielding-or-returning-itself.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-44197.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-48048.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-52398.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-53548-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-53548.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-57084.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-58888.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-61442-stmt-expr-with-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-62506-two_awaits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-64620-yield-array-element.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-68112.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-69017.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/issue-69039.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/iterator-count.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/live-upvar-across-yield.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/match-bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/nested_generators.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/niche-in-generator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/non-static-is-unpin.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/not-send-sync.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/overlap-locals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/panic-drops-resume.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/panic-drops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/panic-safe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/partial-initialization-across-yield.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/pattern-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/pin-box-generator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/print/generator-print-verbose-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/print/generator-print-verbose-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/print/generator-print-verbose-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/reborrow-mut-upvar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/ref-escapes-but-not-over-yield.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/resume-after-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/resume-arg-late-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/resume-arg-size.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/resume-live-across-yield.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/retain-resume-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/size-moved-locals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/sized-yield.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/smoke-resume-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/smoke.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/static-generators.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/static-mut-reference-across-yield.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/static-not-unpin.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/static-reference-across-yield.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/too-live-local-in-immovable-gen.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/too-many-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/type-mismatch-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/type-mismatch-signature-deduction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/xcrate-reachable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/yield-in-args-rev.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/yield-in-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/yield-in-box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/yield-in-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/yield-in-function.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/yield-in-initializer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/yield-in-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/yield-subtype.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/yield-while-iterating.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/yield-while-local-borrowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/yield-while-ref-reborrowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generator/yielding-in-match-guards.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/auxiliary/foo_defn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/collections-project-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/collections.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/construct_with_other_type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/cross-crate-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/empty_generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/gat-incomplete-warning.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/generic-associated-types-where.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/impl_bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/impl_bounds_ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-47206-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-67424.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68641-check-gat-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68643-broken-mir.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68644-codegen-selection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68653.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68656-unsized-values.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-74816.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/iterable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/missing-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/parameter_number_and_kind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/parameter_number_and_kind_impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/parse/in-trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/parse/in-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/pointer_family.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/projection-bound-cycle-generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/projection-bound-cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/shadowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/streaming_iterator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generic-associated-types/unsatisfied-outlives-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/auxiliary/default_type_params_xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-alias-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-arg-mismatch-recover.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-default-type-params-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-default-type-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-derived-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-exterior-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-extern-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-extern-mangle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-extern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-fn-infer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-fn-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-fn-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-impl-less-params-with-defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-impl-more-params-with-defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-ivec-leak.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-lifetime-trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-newtype-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-no-mangle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-non-trailing-defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-param-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-recursive-tag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-static-methods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-tag-corruption.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-tag-local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-tag-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-tag-values.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-tag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-temporary.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-tup.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-type-less-params-with-defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-type-more-params-with-defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-type-params-forward-mention.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-type-params-name-repr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-type-synonym.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/generic-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/issue-61631-default-type-param-cannot-reference-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/generics/param-in-ct-in-ty-param-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/glob-cycles.rs create mode 100644 gcc/testsuite/rust/rustc/ui/glob-resolve1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/global-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/guards.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-semantics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/pat-tuple-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/half-open-range-patterns/pat-tuple-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hashmap/hashmap-capacity-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hashmap/hashmap-iter-value-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hashmap/hashmap-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hashmap/hashmap-memory.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hello.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hello_world/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hidden-rt-injection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hidden-rt-injection2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-lifetime-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-parse.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/issue-59311.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hr-subtype/hr-subtype.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hr-subtype/return-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/due-to-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/hrtb-cache-issue-54302.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/hrtb-conflate-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/hrtb-debruijn-in-receiver.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-trait-covariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-trait-invariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/hrtb-higher-ranker-supertraits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/hrtb-identity-fn-borrows.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/hrtb-just-for-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/hrtb-perfect-forwarding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/issue-30786.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/issue-46989.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/issue-57639.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/issue-58451.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hrtb/issue-62203-hrtb-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/html-literals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/huge-array-simple-32.rs create mode 100644 gcc/testsuite/rust/rustc/ui/huge-array-simple-64.rs create mode 100644 gcc/testsuite/rust/rustc/ui/huge-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/huge-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/huge-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/arguments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/assoc_item_ctxt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/assoc_ty_bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/codegen-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/def-site-async-await.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/intercrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/legacy_interaction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/local_inner_macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/my_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/needs_hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/nested-dollar-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/not-libstd.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/opaque-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/stdlib-prelude.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/transparent-basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/unhygienic_example.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/cross-crate-codegen-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/cross_crate_hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/dollar-crate-modern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/duplicate_lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/eager-from-opaque-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/eager-from-opaque.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/expansion-info-reset.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/extern-prelude-from-opaque-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/fields-definition.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/fields-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/fields-numeric-borrowck.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/for-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/format-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/generate-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/generic_params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/globs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/hir-res-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/hygiene-dodging-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/hygienic-labels-in-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/hygienic-labels.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/impl_items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/intercrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/issue-44128.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/issue-47311.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/issue-47312.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/issue-61574-const-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/issue-77523-def-site-async-await.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/legacy_interaction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/lexical.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/local_inner_macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/macro-metavars-legacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/macro-metavars-transparent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/missing-self-diag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/nested-dollar-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/nested_macro_privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/no_implicit_prelude-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/no_implicit_prelude.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/panic-location.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/pattern-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/prelude-import-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/privacy-early.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/rustc-macro-transparency.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/specialization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/stdlib-prelude-from-opaque-early.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/stdlib-prelude-from-opaque-late.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/trait_items-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/trait_items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/transparent-basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/unpretty-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/wrap_unhygienic_example.rs create mode 100644 gcc/testsuite/rust/rustc/ui/hygiene/xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if-attrs/bad-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if-attrs/builtin-if-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if-attrs/cfg-false-if-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if-attrs/else-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if-attrs/gate-whole-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if-attrs/let-chains-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if-attrs/stmt-expr-gated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if-bot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if-check.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if-else-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/expr-if-panic-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/expr-if-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/if-branch-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/if-check-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/if-cond-bot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/if-let-arm-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/if-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/if-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/if-no-match-bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/if-typeck.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/if-without-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/if-without-else-as-fn-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/if-without-else-result.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/ifmt-bad-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/ifmt-bad-format-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/ifmt-unimpl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/if/ifmt-unknown-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ignore-all-the-things.rs create mode 100644 gcc/testsuite/rust/rustc/ui/illegal-ufcs-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/immut-function-arguments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-bounds-checking.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-duplicate-methods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/assoc-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/dyn-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/explicit-and-elided-same-header.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/inherent-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/path-elided.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/path-underscore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/ref-underscore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/trait-elided.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/trait-underscore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-inherent-non-conflict.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-not-adjacent-to-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-privacy-xc-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-privacy-xc-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait-in-bindings-issue-73003.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait-in-bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/associated-impl-trait-type-generic-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/associated-impl-trait-type-trivial.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/associated-impl-trait-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait-leak-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait-leak.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait-leak2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/auxiliary/extra-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/auxiliary/no_method_suggested_traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/auxiliary/xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/binding-without-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/bindings-opaque.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/bound-normalization-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/bound-normalization-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/bounds_regression.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/can-return-unconstrained-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/closure-calling-parent-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/closure-in-impl-trait-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/closure-in-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/deprecated_annotation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/does-not-live-long-enough.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-assoc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-ref-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/equal-hidden-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/equality-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/equality.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/equality2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/example-calendar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/example-st.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/extra-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/hidden-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/impl-generic-mismatch-ab.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/impl-generic-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/impl-trait-plus-priority.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/impl_trait_projections.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issue-55872-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issue-55872-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issue-55872.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issue-56445.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issue-57200.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issue-57201.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issue-60473.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issue-67166.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issue-68532.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issue-69840.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issue-72911.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-42479.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-49376.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-52128.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-53457.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-55608-captures-empty-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57464-unexpected-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-65581.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-70877.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/universal-issue-48703.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/method-suggestion-no-duplication.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/error-handling-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/error-handling.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/must_outlive_least_region_or_bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/needs_least_region_or_bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/negative-reasoning.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/nested-return-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/nesting.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/no-method-suggested-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/no-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/recursive-impl-trait-type-direct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/recursive-impl-trait-type-indirect.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/region-escape-via-bound-contravariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/region-escape-via-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/return-position-impl-trait-minimal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/static-return-lifetime-infered.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/trait_type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/type-alias-generic-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/type_parameters_captured.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/universal-mismatched-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/universal-two-impl-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/universal_hrtb_anon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/universal_hrtb_named.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/universal_in_adt_in_parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/universal_in_impl_trait_in_parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/universal_in_trait_defn_parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/universal_multiple_bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/universal_wrong_bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/unsafety-checking-cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/wf-eval-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/where-allowed-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/where-allowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-trait/xcrate_simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-unused-rps-in-assoc-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-unused-tps-inherent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impl-unused-tps.rs create mode 100644 gcc/testsuite/rust/rustc/ui/implicit-method-bind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/import2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/import3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/import4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/auxiliary/gensymed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/auxiliary/glob-conflict.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/auxiliary/import_crate_var.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/auxiliary/issue-55811.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/auxiliary/issue-56125.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/auxiliary/two_macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/duplicate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/extern-crate-used.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-shadowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/gensymed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/glob-conflict-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/glob-shadowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/glob-use-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-crate-var.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-crate-with-invalid-spans/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-from-missing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-from.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-glob-0-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-glob-0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-glob-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-glob-circular.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-glob-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-in-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-loop-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-prefix-macro-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-prefix-macro-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-prefix-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-rename.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-trailing-comma.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import-trait-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import7.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/import8.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/imports.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/issue-53140.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/issue-53269.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/issue-53512.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/issue-55457.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/issue-55811.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/issue-55884-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/issue-55884-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/issue-56125.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/issue-56263.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/issue-57015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/issue-57539.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/issue-62767.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-fail-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-fail-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-fail-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/local-modularized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/macro-paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/reexports.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/rfc-1560-warning-cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/shadow_builtin_macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/unresolved-imports-used.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/unused-macro-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/imports/unused.rs create mode 100644 gcc/testsuite/rust/rustc/ui/impossible_range.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/E0687.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/E0687_where.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/E0688.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/elided-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched_trait_impl-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched_trait_impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mut_while_borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/nested-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/no_in_band_in_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/no_introducing_in_band_in_locals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/in-band-lifetimes/shadow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inc-range-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/include-macros/mismatched-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/include-macros/normalization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/include-single-expr-helper-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/include-single-expr-helper.rs create mode 100644 gcc/testsuite/rust/rustc/ui/include-single-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/index-bot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/index-help.rs create mode 100644 gcc/testsuite/rust/rustc/ui/index_message.rs create mode 100644 gcc/testsuite/rust/rustc/ui/indexing-requires-a-uint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/infer-fn-tail-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inference/auxiliary/inference_unstable_iterator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inference/auxiliary/inference_unstable_itertools.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inference/cannot-infer-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inference/cannot-infer-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inference/infer-binary-operand-behind-reference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inference/inference-variable-behind-raw-pointer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inference/inference_unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inference/inference_unstable_featured.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inference/inference_unstable_forced.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inference/issue-71732.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inference/issue-72616.rs create mode 100644 gcc/testsuite/rust/rustc/ui/infinite/infinite-autoderef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/infinite/infinite-instantiation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/infinite/infinite-macro-expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/infinite/infinite-recursion-const-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/infinite/infinite-tag-type-recursion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/infinite/infinite-vec-type-recursion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inherit-env.rs create mode 100644 gcc/testsuite/rust/rustc/ui/init-large-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/init-res-into-things.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inline-asm-bad-constraint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inline-asm-bad-operand.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inline-const/const-expr-array-init.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inline-const/const-expr-basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inline-const/const-expr-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inline-const/const-expr-reference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inline-const/const-match-pat-range.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inline-const/const-match-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inline-const/macro-with-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inline-disallow-on-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inlined-main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inner-attrs-on-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inner-module.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inner-static-type-parameter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/inner-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/instantiable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/integer-literal-suffix-inference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/integral-indexing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/integral-variable-unification-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/interior-mutability/interior-mutability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/internal/auxiliary/internal_unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/internal/internal-unstable-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/internal/internal-unstable-noallow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/internal/internal-unstable-thread-local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/internal/internal-unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics-always-extern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/auxiliary/cci_intrinsic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-alignment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-assume.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-atomics-cc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-atomics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-move-val-cleanups.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-move-val.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-nearby.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-unreachable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-volatile.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/intrinsics-integer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/intrinsics-math.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/issue-28575.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/panic-uninitialized-zeroed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/unchecked_math_unsafe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/intrinsics/unchecked_math_unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid-module-declaration/auxiliary/foo/bar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid-module-declaration/auxiliary/foo/mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid-module-declaration/invalid-module-declaration.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid-rustc_args_required_const-arguments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid-self-argument/bare-fn-start.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid-self-argument/bare-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid-self-argument/trait-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid/invalid-crate-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid/invalid-inline.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid/invalid-macro-matcher.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid/invalid-no-sanitize.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid/invalid-path-in-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid/invalid-plugin-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid_crate_type_syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/invalid_dispatch_from_dyn_impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issue-72470-llvm-dominate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issue-73914.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issue-74047.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issue-76387-llvm-miscompile.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issue-76597.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues-71798.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/cgu_test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/cgu_test_a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/cgu_test_b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/empty-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/i8.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/iss.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-10028.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-10031-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11224.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11225-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11225-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11225-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11508.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11529.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11680.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12133-dylib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12133-dylib2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12133-rlib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12612-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12612-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12660-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13507.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13620-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13620-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13872-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13872-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13872-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14344-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14344-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14421.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14422.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-15562.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-16643.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-16725.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-17662.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-17718-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-17718-const-privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18501.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18514.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18711.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18913-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18913-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-19163.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-1920.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-19293.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-19340-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-20389.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-21146-inc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-21202.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2170-lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2316-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2316-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2380.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2414-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2414-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2472-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-25185-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-25185-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2526.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-25467.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2631-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2723-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-29181.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-29265.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-29485.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-3012-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-30123-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-30535.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-3136-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-31702-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-31702-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-34796-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-36708.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-36881-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-36954.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-38190.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-38226-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-3979-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-39823.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-40469.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-41053.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-41394.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-41549.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-42007-s.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-4208-cc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-4545.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-48984-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-49544.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-51798.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-52489.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-52891.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-5518.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-5521.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-56943.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-57271-lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-5844-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-59764.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-69725.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-7178.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-73112.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-75907.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-7899.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-8044.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-8259.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-8401.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9123.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9155.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9188.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9906.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9968.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/lint-stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/private-trait-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/reexported-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-43189-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-43189-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-46112-rexport-core.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-61711-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10025.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10028.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10031.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10176.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10200.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10228.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10291.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10392.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10396.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10398.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10401.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10412.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10436.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10456.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10465.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10536.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10545.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10626.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10638.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10656.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10682.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10683.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10718.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10734.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10763.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10764-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10764.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10767.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10802.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10806.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10853.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10877.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10902.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10969.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-10991.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11004.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11047.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11085.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1112.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11154.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11192.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11205.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11224.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11225-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11225-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11225-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11267.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11319.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11374.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11382.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11384.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11493.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11508.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11515.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11529.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11552.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11577.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11592.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11593.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11612.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11677.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11680.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11681.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11692-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11692-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11709.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11740.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11771.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11820.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11844.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11869.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11873.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11940.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-11958.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12028.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12033.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12041.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12116.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12127.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12133-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12133-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12133-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12187-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12187-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12285.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12369.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12470.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1251.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12511.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12552.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12567.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1257.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12582.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12612.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12660.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12677.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12699.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12729.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12744.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12796.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12860.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12863.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12909.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12920.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12997-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-12997-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13027.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13033.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13058.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13105.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13167.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13202.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13204.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13214.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13259-windows-tcb-trash.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13264.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13304.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13323.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13359.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13404.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13405.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13407.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13434.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13446.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13466.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13482-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13482.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13483.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13497-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13497.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13507-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1362.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13620.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13641.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13655.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13665.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13703.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13727.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13763.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13775.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13808.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13837.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13847.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13853-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13853-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13853.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13867.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13872.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-13902.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14082.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14091-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14091.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14092.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14221.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14227.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14229.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14254.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14285.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14308.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14309.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14330.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14344.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14366.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14382.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14393.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14399.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14421.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14422.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14456.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1448-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1451.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14541.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14589.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1460.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14721.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1476.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14772.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14821.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14837.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14845.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14853.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14865.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14875.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14901.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14915.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14919.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14933.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14936.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14940.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14958.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-14959.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15034.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15043.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15063.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15080.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15094.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15104.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15129-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15129.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15155.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15167.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15189.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15207.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15221.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15260.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15261.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15381.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15444.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15487.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15523-big.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15523.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15524.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15562.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15571.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15673.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15689-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15689-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15730.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15734.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15735.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15756.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15763.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15774.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15783.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15793.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15858.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15881-model-lexer-dotdotdot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15896.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15919-32.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15919-64.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-15965.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16048.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16098.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16149.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16151.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16250.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16256.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16272.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16278.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16338.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16401.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16441.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16452.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16492.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16530.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16538.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16560.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16562.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16596.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16597-empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16597.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1660.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16602-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16602-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16602-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16643.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16648.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16668.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16671.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16683.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16725.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16739.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16745.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16774.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16783.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16819.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16922-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16922.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16939.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1696.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16966.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1697.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-16994.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17001.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1701.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17033.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17068.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17074.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17121.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17170.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17216.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17233.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17252.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17263.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17302.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17322.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17336.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17337.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17351.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17361.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17373.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17385.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17405.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17431-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17431-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17431-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17431-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17431-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17431-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17431-7.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17441.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17444.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17450.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17458.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17503.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17545.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17546.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17551.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17651.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17662.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-borrow-interior.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-bad-values.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-destructors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-naming.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-constants-not-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-parse-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-references.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-static-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-static-sync.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718-static-unsafe-interior.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17718.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17728.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17732.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17734.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17740.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17746.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17756.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17758.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17771.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17800.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17816.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17877.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17897.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17904-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17904.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17905-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17905.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17913.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17933.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17954.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17959.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17994.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-17999.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18058.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18060.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18083.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18088.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18107.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18110.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18118-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18118.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18119.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18159.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18173.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18183.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18188.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1821.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18232.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18294.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18352.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18353.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18389.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18400.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18412.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18423.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18425.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18446-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18446.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18464.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18501.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18514.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18532.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18539.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18566.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18576.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18611.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18652.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18655.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1866.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18661.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18685.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1871.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18711.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18738.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18767.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18783.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18804/auxiliary/lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18804/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18809.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18819.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18845.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18859.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18906.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18913.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18919.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18937-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18937.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18952.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18959.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-18988.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1900.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19001.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19037.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19081.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19086.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19097.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19098.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19100.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19102.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19127.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19129-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19129-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19135.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19163.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1920-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1920-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1920-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19244-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19244-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19244.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19293.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19340-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19340-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19358.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19367.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19380.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19398.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19404.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19479.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19482.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19498.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19499.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19521.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19538.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19601.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1962.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19631.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19632.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19660.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19692.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19707.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19734.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-1974.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19811-escape-unicode.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19850.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19883.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19922.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19982.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-19991.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20005.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20009.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20055-box-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20055-box-unsized-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20091.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20162.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20174.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20186.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20225.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20261.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20313-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20313.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20343.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20389.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20396.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20413.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20414.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20427.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20433.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20454.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20544.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20575.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20605.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20616-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20616-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20616-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20616-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20616-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20616-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20616-7.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20616-8.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20616-9.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20616.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2063-resource.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2063.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20644.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20676.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20692.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20714.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2074.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20763-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20763-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20772.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20797.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20801.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20803.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20823.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20825-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20825.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20831-debruijn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20847.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20939.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20953.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-20971.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21033.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21058.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2111.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21140.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21146.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21160.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21174-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21174.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21177.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21202.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21245.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21291.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21306.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21332.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21356.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21361.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21363.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21384.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21400.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21402.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21449.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21475.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21486.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2150.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2151.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21520.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21546.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21554.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21562.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21596.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21600.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21622.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21634.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21655.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2170-exe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21701.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21721.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21726.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21763.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21837.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21891.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2190-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21909.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21922.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21946.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21950.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-21974.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22008.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22034.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22036.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22037.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22066.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2214.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2216.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22258.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22289.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22312.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22346.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22356.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22370.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22375.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22384.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22403.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22426.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22434.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22463.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22468.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22471.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22536-copy-mustnt-zero.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22546.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22560.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22577.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22599.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22603.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22629.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22638.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22644.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22673.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22684.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22706.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22777.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22781.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22789.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2281-part1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22814.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22828.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2284.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22864-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22864-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22872.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22874.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2288.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22886.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22894.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22933-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22933-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22992-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-22992.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23024.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23036.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23041.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23046.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23073.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2311-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2311.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2312.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23122-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23122-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2316-c.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23173.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23189.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23208.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23217.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23253.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23261.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23281.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2330.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23302-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23302-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23302-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23304-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23304-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23311.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23336.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23338-ensure-param-drop-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23338-params-outlive-temps-of-body.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23354-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23354.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23406.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23433.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23442.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23458.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23477.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23485.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23491.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23543.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23544.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23550.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23589.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23595-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23611-enum-swap-in-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23649-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23649-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23649-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23699.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23716.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23781.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2380-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23808.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23825.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2383.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23833.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23891.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23898.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23958.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23966.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23968-const-not-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-23992.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24010.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24013.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24036.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24081.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24085.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24086.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2414-c.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24161.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24204.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24227.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24267-flow-exit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2428.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24308.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24313.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24322.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24338.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24352.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24353.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24357.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24363.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24365.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24389.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24424.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24434.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2444.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24446.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2445-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2445.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24533.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24589.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2463.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24682.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24687-embed-debuginfo/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2470-bounds-check-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2472.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24779.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24805-dropck-itemless.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24819.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2487-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24883.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24945-repeat-dash-opts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24947.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-24954.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2502.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25076.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25089.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25145.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25180.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25185.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2526-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25279.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25339.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25343.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25368.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25385.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25386.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25394.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25396.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25439.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25467.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25497.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2550.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25515.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25549-multiple-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25579.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25679.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25693.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25700-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25700-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25700.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25746-bool-transmute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25757.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25793.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25810.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25826.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2590.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25901.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-25916.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26056.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26093.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26094.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26095.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2611-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26127.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26205.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26217.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26237.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26251.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26262.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2631-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26322.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2633-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2633.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2642.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26448-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26448-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26448-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26459.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26468.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26472.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26484.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26545.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26614.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26619.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26638.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26641.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26646.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26655.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26709.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26802.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26805.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26812.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/A/B.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/A/C.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/A/mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26873-onefile.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26886.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26905-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26905.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26930.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26948.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26996.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-26997.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27008.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27021.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27033.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27042.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27054-primitive-binary-ops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27060-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27060-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27060.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27078.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2708.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27105.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2718-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2718.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2723-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27240.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27268.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27281.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27282-move-match-input-into-guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27282-move-ref-mut-into-guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27320.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2734.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27340.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2735-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2735-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2735.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27401-dropflag-reinit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27433.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2748-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2748-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27583.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27592.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2761.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27639.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27697.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27815.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27842.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27859.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27889.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27890.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27895.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27901.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27942.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27949.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-27997.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2804-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28075.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28098.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28105.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28109.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28113.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28134.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28181.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2823.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28279.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28324.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28344.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28388-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28388-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28388-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28433.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28472.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2848.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2849.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28498-must-work-ex1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28498-must-work-ex2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-ex1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-with-lifetime-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-with-trait-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28550.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28561.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28568.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28576.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28586.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28600.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28625.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28676.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28776.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28777.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28822.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28828.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28837.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28839.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28848.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28871.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28934.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28936.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2895.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28950.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28971.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28983.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28992-empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-28999.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29030.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29037.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2904.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29048.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29053.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29071-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29071.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29084.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29092.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29124.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29147-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29147.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29161.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29166.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29181.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29184.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29227.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29265.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29276.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2935.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2936.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2937.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29466.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29485.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29488.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2951.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29516.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29522.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29540.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29663.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29668.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29710.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29723.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29740.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29743.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29746.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29798.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29844.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29857.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29861.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2989.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29914-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29914-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29914.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29927-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29927.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-29948.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-2995.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30007.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30018-nopanic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30018-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30079.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3008-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3008-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3008-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30081.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3012-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30123.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3021-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3021-c.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3021-d.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3021.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30225.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30236.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30240-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30240-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30240.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30255.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3026.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3029.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30302.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30355.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3037.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30371.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3038.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30380.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30438-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30438-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30438-c.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3044.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30490.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3052.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30530.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30535.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30560.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30589.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30615.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30730.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30756.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3080.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-30891.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3091.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3096-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3096-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3099-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3099-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3099.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31011.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31076.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3109.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31109.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31173.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3121.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31212.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31221.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31260.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31267-additional.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31267.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31299.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3136-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3149.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31511.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3154.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31561.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31597.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31702.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31769.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31776.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31804.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31845.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31910.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-31924-non-snake-ffi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32004.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32008.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32086.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3211.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32119.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32122-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32122-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3214.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3220.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32201.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32222.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32292.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32323.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32324.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32326.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32354-suggest-import-rename.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32377.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32389.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32518.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32655.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32709.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32782.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32797.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32805.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32829-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32829.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32833.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3290.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32922.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32947.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32950.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32963.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32995-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-32995.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33096.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33140-hack-boundaries.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33140-traitobject-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33140.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33185.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33187.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33202.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33241.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33264.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33287.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33293.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-333.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33387.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3344.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33461.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33464.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33498.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33504.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33525.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33537.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33571.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33575.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33687.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33770.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33819.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3389.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33903.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33941.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-33992.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34028.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34047.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34053.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34074.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34171.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34194.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34209.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34222-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34229.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3424.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34255-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3429.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34334.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34349.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34373.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34418.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34427.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3447.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34503.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34569.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34571.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34721.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34751.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3477.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34780.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34784.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34796.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34798.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34839.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-34932.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3500.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35075.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35139.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3521-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3521.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35241.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35376.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35423.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35450.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35546.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3556.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35570.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3559.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35600.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3563-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3563-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35668.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35675.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35677.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3574.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35815.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35869.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35976.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-35988.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3601.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36023.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36036-associated-type-layout.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36053.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36075.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36082.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3609.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36116.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36139-normalize-closure-sig.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36163.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36260.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36278-prefix-nesting.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36299.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36379.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36381.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36400.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36401.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36474.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3656.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36617.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36638.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3668-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3668.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36708.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36744-bitcast-args-if-needed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36744-without-calls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36768.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36786-resolve-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36792.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3680.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36816.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3683.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36836.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36839.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36856.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36881.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36936.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-36954.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3702-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3702.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37026.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37051.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3707.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37109.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37131.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37175.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37222.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37291/auxiliary/lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37291/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37311-type-length-limit/issue-37311.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37323.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37366.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3743.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37433.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37510.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37515.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3753.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37534.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37550.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37576.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37598.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3763.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37655.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37665.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37686.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37725.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37733.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3779.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37884.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37887.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3794.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-37991.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38002.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38033.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38074.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38160.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38190.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3820.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38226.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38293.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38381.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38404.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38412.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38437.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38458.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3847.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38556.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38604.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38715.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38727.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3874.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38763.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3878.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38821.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38857.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38868.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38875/auxiliary/issue-38875-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38875/issue-38875.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3888-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38919.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38940.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38942.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3895.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38954.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-38987.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3904.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39089.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39175.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39211.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39292.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3935.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39362.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39367.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39388.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39467.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39548.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39559-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39559.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39616.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39687.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39709.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39720.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3973.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3979-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3979-generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3979-xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3979.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39808.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39823.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39827.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39848.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3991.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-3993.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39970.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39974.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-39984.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40000.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40003.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40085.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40136.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40231-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40231-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40235.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4025.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40288-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40288.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40350.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40402-ref-hints/issue-40402-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40402-ref-hints/issue-40402-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40408.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40469.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40510-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40510-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40510-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40510-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40610.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40749.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40770.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40782.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40827.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40845.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40847.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40861.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40883.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40951.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-40962.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41053.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4107.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41139.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41213.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41229-ref-str.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41255.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41272.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41298.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41394-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41394.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41479.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41498.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41549.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41604.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41628.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41652/auxiliary/issue-41652-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41652/issue-41652.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41677.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41696.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41726.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41742.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41744.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41776.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41803.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41849-variance-req.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41880.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41888.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41974.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-41998.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42007.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4201.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42060.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4208.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42106.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42148.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42210.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4228.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42312.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42344.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42453.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42463.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42467.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4252.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42552.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4265.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42679.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42747.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42755.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42796.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42880.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42944.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42954.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-42956.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43023.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43057.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43105.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43132.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43162.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43189.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43196.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43205.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4321.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43250.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43291.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4333.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4335.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43355.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43357.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43398.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43420-no-over-suggest.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43424.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43431.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43483.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43623.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4366-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4366.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43692.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43733.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43784-associated-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43784-supertrait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43806.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43853.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4387.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43910.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43923.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43925.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43926.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-43988.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44005.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4401.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44021.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44023.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44056.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44078.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44127.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44216-add-instant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44216-add-system-time.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44216-sub-instant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44216-sub-system-time.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44239.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44247.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44255.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44373-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44373.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44405.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44406.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4446.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4448.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4464.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44730.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-44851.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45087-unreachable-unsafe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45107-unnecessary-unsafe-in-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45124.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45152.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45157.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4517.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45199.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45296.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4541.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4542.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45425.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4545.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45510.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45562.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45696-long-live-borrows-in-boxes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45696-no-variant-box-recur.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45696-scribble-on-boxed-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45697-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45697.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45729-unsafe-in-generator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45730.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45731.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45801.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45829/auxiliary/issue-45829-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45829/auxiliary/issue-45829-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45829/import-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45829/import-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45829/issue-45829.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-extern-vs-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-extern-with-tab.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-extern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-use-vs-extern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-use-with-tabs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-with-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-45965.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46023.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46036.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46069.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46095.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46101.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46112.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46186.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46302.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46311.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46332.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46438.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46471-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46471.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46472.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46519.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46553.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46576.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46604.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46771.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46845.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46855.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46920-byte-array-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46959.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46964.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-46983.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47073-zero-padded-tuple-struct-indices.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47094.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47139-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47139-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47184.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47309.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4734.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4735.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4736.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47364.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47377.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47380.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47412.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47486.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47511.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4759-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4759.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47623.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47638.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47646.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47673.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47703-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47703-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47703.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47706-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47706.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47715.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47722.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47725.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-47789.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48006.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48131.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48132.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48159.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48179.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48276.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4830.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48364.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48508-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48508.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48551.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48636.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4865-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4865-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4865-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48728.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4875.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48803.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48838.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48962.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-48984.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49040.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49074.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49257.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49298.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4935.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49544.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49556.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49579.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49632.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4968.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49685.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-4972.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49824.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49851/compiler-builtins-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49854.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49919.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49934-errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49934.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49955-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49955.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-49973.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5008-borrowed-traitobject-method-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50187.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50301.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50403.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50411.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50415.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50442.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50471.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50480.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50518.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50571.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50576.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50581.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50582.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50585.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50599.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5060.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50600.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50618.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5062.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5067.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50687-ice-on-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50688.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50689.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50714-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50714.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50731.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50761.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50781.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50802.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50811.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50825-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50825.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50865-private-impl-trait/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5099.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-50993.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5100.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51022.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51044.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51102.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51116.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51154.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51185.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51244.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51301.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51345-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51345.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51515.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5153.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51582.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51602.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51632-try-desugar-incompatible-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51655.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51714.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51770.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51798.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51848.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51874.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51907.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5192.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-51947.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52023-array-size-pointer-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52049.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52057.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52060.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52126-assign-op-invariance.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52140/auxiliary/some_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52140/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52141/auxiliary/some_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52141/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5216.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52169.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52213.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52240.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52262.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5239-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5239-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5243.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52489.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52496.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52533-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52533.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52557.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52705/auxiliary/png2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52705/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52717.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5280.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52891.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-52992.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5315.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5321-immediates-with-bare-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53251.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53275.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53300.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53333.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53348.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53419.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53498.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5353.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53565.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53568.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5358-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53675-a-test-called-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53692.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53712.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53728.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53787-inline-assembler-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53843.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-53912.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54044.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54062.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54094.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54189.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54302-cases.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54302.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54348.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54387.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5439.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54410.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54462-mutable-noalias-correctness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54467.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54477-reduced-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54521-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54521-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54521.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54582.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54696.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54943-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54943-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54943-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54943.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54954.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-54966.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5500-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5518.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5521.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5530.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-55376.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-55380.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5550.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-55511.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5554.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-55587.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5572.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-55731.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-55796.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-55846.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56031.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56128.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56175.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56199.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56202.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56229.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56237.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56411-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56411.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56488.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5666.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56685.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56762.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56806.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56835.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56870.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5688.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-56943.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5708.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57156.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57162.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5718.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57198-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57198.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57271.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57362-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57362-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57399-self-return-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5741.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57410-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57410.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57472.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5754.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57597.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57684.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57741-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57741.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57781.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57819.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57843.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5791.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-57924.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-58022.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-58212.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-58319.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-58344.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-58375-monomorphize-default-impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-58435-ice-with-assoc-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5844.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-58463.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-58712.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-58734.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5883.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5884.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-58856-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-58856-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-58857.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5900.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-59020.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-59029-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-59029-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5917.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5927.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-59326.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-59488.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-59494.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5950.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-59508-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-59508.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-59756.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-59764.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5988.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-59896.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5997-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5997-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-5997.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-60057.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-60075.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-60218.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-60283.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-60622.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-60662.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-60989.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-61106.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-61108.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6117.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6128.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6130.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-61475.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6153.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6157.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-61623.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-61696.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-61858.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-61882-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-61882.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-61894.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-62375.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-62480.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-62554.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6318.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6334.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-63364.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6341.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6344-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6344-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-63983.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-64430.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6449.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-64559.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6458-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6458-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6458-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6458-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6458.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-64593.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-64620.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6470.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-64732.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-64792-bad-unicode-ctor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-65131.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-65284-suggest-generic-trait-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-65462.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6557.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-65611.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-65634-raw-ident-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-65673.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6596-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6596-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-66308.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-66353.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6642.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-66473.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-66667-function-cmp-cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-66702-break-outside-loop-val.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-66706.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-66768.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-66851.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-66923-show-error-for-correct-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-67039-unsound-pin-partialeq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6738.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-67552.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6801.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-68010-large-zst-consts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6804.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-68091-unicode-ident-after-if.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-68103.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-68696-catch-during-unwind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6892.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-68951.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6898.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-69130.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6919.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-69225-SCEVAddExpr-wrap-flag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-69225-layout-repeated-checked-add.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-69306.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6936.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-69396-const-no-type-in-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-69455.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-69532.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-69602-type-err-during-codegen-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-69683.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-69725.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-69841.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-6991.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-70041.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-70093.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7012.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7013.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-70381.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7044.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7061.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-70673.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-70746.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7092.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-71036.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-71406.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-71584.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-71676-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-71676-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7178.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-72002.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-72076.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7222.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-72253.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-72278.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-72373.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-72455.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7246.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-72554.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-72574-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-72574-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7268.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-72690.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-72839-error-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-72933-match-stack-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-73112.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-73229.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-73427.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7344.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-73541-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-73541-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-73541-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-73541.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7364.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-73886.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-74082.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-74086.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-74236/auxiliary/dep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-74236/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-74564-if-expr-stack-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-74614.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-74739.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7519-match-unit-in-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-75283.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-75307.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-75599.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7563.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-75704.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7575.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-75763.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-75777.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-75906.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-75907.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-75907_b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7607-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7607-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-76077-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-76077.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-76179.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-76191.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-76547.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7660.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7663.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7673-cast-generically-implemented-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-77002.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-77218.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7784.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-77919.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-77993-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-77993-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-78115.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7813.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-78192.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-78372.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-78622.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7867.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7899.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7911.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7950.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7970a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-7970b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8044.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-811.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8153.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8208.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8248.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8249.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8259.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8351-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8351-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8391.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8398.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8401.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8460-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8460.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8498.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8506.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8521.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8578.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8640.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-868.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8709.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8727.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8761.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8767.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8783.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8827.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8851.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8860.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-8898.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9047.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9110.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9123.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9129.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9155.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9188.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9243.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9249.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9259.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9382.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9394-inherited-trait-calls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9396.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9446.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-948.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9575.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9719.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9725.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9737.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-979.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9814.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9837.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9906.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9918.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9942.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9951.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-9968.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/issue-pr29383.rs create mode 100644 gcc/testsuite/rust/rustc/ui/issues/type-arg-mismatch-due-to-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/istr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/item-name-overload.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/array-of-ranges.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/integral.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/into-iter-on-arrays-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/into-iterator-type-inference-shift.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/issue-58952-filter-type-length.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/iter-cloned-type-inference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/iter-count-overflow-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/iter-count-overflow-ndebug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/iter-map-fold-type-length.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/iter-position-overflow-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/iter-position-overflow-ndebug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/iter-range.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/iter-step-overflow-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/iter-step-overflow-ndebug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/iter-sum-overflow-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/iter-sum-overflow-ndebug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/iter-sum-overflow-overflow-checks.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/ranges.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/skip-count-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/iterators/string.rs create mode 100644 gcc/testsuite/rust/rustc/ui/json-and-color.rs create mode 100644 gcc/testsuite/rust/rustc/ui/json-and-error-format.rs create mode 100644 gcc/testsuite/rust/rustc/ui/json-bom-plus-crlf-multifile-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/json-bom-plus-crlf-multifile.rs create mode 100644 gcc/testsuite/rust/rustc/ui/json-bom-plus-crlf.rs create mode 100644 gcc/testsuite/rust/rustc/ui/json-invalid.rs create mode 100644 gcc/testsuite/rust/rustc/ui/json-multiple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/json-options.rs create mode 100644 gcc/testsuite/rust/rustc/ui/json-short.rs create mode 100644 gcc/testsuite/rust/rustc/ui/keyword-changes-2012-07-31.rs create mode 100644 gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/keyword/keyword-false-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/keyword/keyword-self-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/keyword/keyword-super-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/keyword/keyword-super.rs create mode 100644 gcc/testsuite/rust/rustc/ui/keyword/keyword-true-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/kindck-implicit-close-over-mut-var.rs create mode 100644 gcc/testsuite/rust/rustc/ui/kindck/kindck-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/kindck/kindck-impl-type-params-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/kindck/kindck-impl-type-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/kindck/kindck-inherited-copy-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/kindck/kindck-nonsendable-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/kindck/kindck-send-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/kindck/kindck-send-object1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/kindck/kindck-send-object2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/kindck/kindck-send-owned.rs create mode 100644 gcc/testsuite/rust/rustc/ui/kindck/kindck-send-unsafe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/kinds-in-metadata.rs create mode 100644 gcc/testsuite/rust/rustc/ui/label/label-beginning-with-underscore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/label/label-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/label/label-underscore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/label/label_break_value_continue.rs create mode 100644 gcc/testsuite/rust/rustc/ui/label/label_break_value_desugared_break.rs create mode 100644 gcc/testsuite/rust/rustc/ui/label/label_break_value_illegal_uses.rs create mode 100644 gcc/testsuite/rust/rustc/ui/label/label_break_value_unlabeled_break.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lambda-infer-unresolved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lambda-var-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lang-item-missing-generator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lang-item-missing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/large-records.rs create mode 100644 gcc/testsuite/rust/rustc/ui/last-use-in-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/last-use-in-cap-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/last-use-is-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/layout/debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs create mode 100644 gcc/testsuite/rust/rustc/ui/layout/issue-60431-unsized-tail-behind-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/layout/unsafe-cell-hides-niche.rs create mode 100644 gcc/testsuite/rust/rustc/ui/layout/zero-sized-array-union.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lazy-and-or.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lazy-init.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/issue-47814.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/issue-57739.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/issue-73980.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/trait-resolution-breakage.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/unevaluated-consts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/leak-unique-as-tydesc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lex-bare-cr-nondoc-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lexical-scopes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lexical-scoping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetime-before-type-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetime_starts_expressions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/auxiliary/lifetime_bound_will_change_warning_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/borrowck-let-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/issue-34979.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/issue-70917-lifetimes-in-fn-def.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-bound-will-change-warning.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-doesnt-live-long-enough.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-elision-return-type-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-no-keyword.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs create mode 100644 gcc/testsuite/rust/rustc/ui/link-cfg-works.rs create mode 100644 gcc/testsuite/rust/rustc/ui/link-section.rs create mode 100644 gcc/testsuite/rust/rustc/ui/linkage-attr/auxiliary/def_colliding_external.rs create mode 100644 gcc/testsuite/rust/rustc/ui/linkage-attr/auxiliary/def_illtyped_external.rs create mode 100644 gcc/testsuite/rust/rustc/ui/linkage-attr/linkage-detect-extern-generated-name-collision.rs create mode 100644 gcc/testsuite/rust/rustc/ui/linkage-attr/linkage-detect-local-generated-name-collision.rs create mode 100644 gcc/testsuite/rust/rustc/ui/linkage-attr/linkage-requires-raw-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/linkage-attr/linkage2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/linkage-attr/linkage3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/linkage-attr/linkage4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/linkage1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint-cap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint-expr-stmt-attrs-for-early-lints.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint-unknown-lints-at-crate-level.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/external_extern_fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/inherited_stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_output_format.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_stability_fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/lints-in-foreign-macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/stability-cfg2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/stability_cfg1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/auxiliary/stability_cfg2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/clashing-extern-fn-recursion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/clashing-extern-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-allow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-deny.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-forbid.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-warn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/crate_level_only_lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/alias-in-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/associated-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/closure-bang.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/const-and-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/empty-unused-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/empty-unused-public-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/enum-variants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/leading-underscore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/newline-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/tuple-struct-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/type-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-struct-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-variant-pub.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/with-core-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/dead-code/with-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/deny-overflowing-literals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/empty-lint-attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/expansion-time-include.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/expansion-time.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/function-item-references.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/inclusive-range-pattern-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/inline-trait-and-foreign-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/issue-54099-camel-case-underscore-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/issue-54180-unused-ref-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/issue-54538-unused-parens-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/issue-67691-unused-field-in-or-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/issue-69485-var-size-diffs-too-large.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/issue-71290-unused-paren-binop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/issue-74883-unused-paren-baren-yield.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/issue-78660-cap-lints-future-compat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-attr-non-item-node.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-change-warnings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-const-item-mutation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-66202.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73251-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73251-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73251.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73747.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-ctypes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-directives-on-use-items-issue-10534.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-exceeding-bitshifts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-forbid-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-forbid-cmdline.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-forbid-internal-unsafe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-group-nonstandard-style.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-impl-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-incoherent-auto-trait-objects.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-lowercase-static-const-pattern-rename.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-lowercase-static-const-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-malformed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-match-arms.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-misplaced-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-missing-copy-implementations.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-missing-doc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-non-camel-case-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-non-camel-case-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-non-camel-case-with-trailing-underscores.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-crate-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-functions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-modules.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-non-uppercase-associated-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-non-uppercase-statics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-nonstandard-style-unicode-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-nonstandard-style-unicode-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-nonstandard-style-unicode-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-output-format-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-output-format.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-owned-heap-memory.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-pre-expansion-extern-module.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-qualification.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-range-endpoint-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-removed-allow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-removed-cmdline.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-removed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-renamed-allow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-renamed-cmdline.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-renamed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-shorthand-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-stability-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-stability-deprecated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-stability-fields-deprecated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-stability-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-stability2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-stability3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-temporary-cstring-as-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-temporary-cstring-as-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-type-limits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-type-limits2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-type-limits3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-type-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-type-overflow2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unconditional-recursion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unexported-no-mangle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unknown-feature-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unknown-feature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unknown-lint-cmdline.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unknown-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unnecessary-import-braces.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unnecessary-parens.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unsafe-code.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unused-extern-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unused-imports.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unused-mut-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unused-mut-variables.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-unused-variables.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint-uppercase-variables.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lint_pre_expansion_extern_module_aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/lints-in-foreign-macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/must-use-ops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/must_use-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/must_use-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/must_use-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/must_use-unit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/no-unused-parens-return-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/not_found.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/opaque-ty-ffi-unsafe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/outer-forbid.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/reasons-erroneous.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/reasons-forbidden.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/reasons.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/suggestions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/test-inner-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/trivial-casts-featuring-type-ascription.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/trivial-casts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/type-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/unaligned_references.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/uninitialized-zeroed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/unreachable-async-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/unreachable_pub-pub_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/unreachable_pub.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/unused-braces-while-let-with-mutable-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/unused_braces.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/unused_braces_borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/unused_import_warning_issue_45268.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/unused_labels.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/unused_parens_json_suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/unused_parens_remove_json_suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/use-redundant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/use_suggestion_json.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lint/warn-unused-inline-on-fn-prototypes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/list.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness-assign-imm-local-after-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-asm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-closure-require-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-consts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-dead.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-derive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-forgot-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-issue-2163.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-missing-ret2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-move-call-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-move-in-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-move-in-while.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-return-last-stmt-semi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-unused.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-upvars.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-use-after-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/liveness/liveness-use-after-send.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/issue-51431.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/issue-54067.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/issue-62046.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/issue-69092.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-bad-clobber.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-concat-src.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-in-bad-modifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-in-moved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-in-out-operand.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-indirect-memory.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-literal-escaping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-misplaced-option.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-assign-imm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-assign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-no-modifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-read-uninit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-parse-errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/llvm-pr32379.rs create mode 100644 gcc/testsuite/rust/rustc/ui/log-err-phi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/log-knows-the-names-of-variants-in-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/log-knows-the-names-of-variants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/log-poly.rs create mode 100644 gcc/testsuite/rust/rustc/ui/logging-only-prints-once.rs create mode 100644 gcc/testsuite/rust/rustc/ui/long-while.rs create mode 100644 gcc/testsuite/rust/rustc/ui/loops/for-each-loop-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/loops/loop-break-unsize.rs create mode 100644 gcc/testsuite/rust/rustc/ui/loops/loop-break-value-no-repeat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/loops/loop-break-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/loops/loop-labeled-break-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/loops/loop-proper-liveness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/loops/loop-properly-diverging-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/loops/loops-reject-duplicate-labels-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/loops/loops-reject-duplicate-labels.rs create mode 100644 gcc/testsuite/rust/rustc/ui/loops/loops-reject-labels-shadowing-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/loops/loops-reject-lifetime-shadowing-label.rs create mode 100644 gcc/testsuite/rust/rustc/ui/loud_ui.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lto-and-no-bitcode-in-rlib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lto-duplicate-symbols.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lto-many-codegen-units.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lto-opt-level-s.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lto-opt-level-z.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lto-rustc-loads-linker-plugin.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lto-still-runs-thread-dtors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lto-thin-rustc-loads-linker-plugin.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lub-glb-with-unbound-infer-var.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-hr-eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-hr-noteq1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-hr-noteq2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lub-if.rs create mode 100644 gcc/testsuite/rust/rustc/ui/lub-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macro-quote-cond.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macro-quote-test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macro_backtrace/auxiliary/ping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macro_backtrace/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/ambiguity-legacy-vs-modern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert-as-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert-eq-macro-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert-eq-macro-success.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert-eq-macro-unsized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert-macro-explicit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert-macro-fmt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert-macro-owned.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert-macro-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert-ne-macro-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert-ne-macro-success.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert-ne-macro-unsized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert-trailing-junk.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/assert.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/deprecated-macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/dollar-crate-nested-encoding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/issue-75982.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-comma-support.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-in-other-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-include-items-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-include-items-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_crate_def_only.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_crate_nonterminal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_export_inner_module.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_with_super_1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/proc_macro_sequence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/two_macros-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/two_macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/unstable-macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/auxiliary/use-macro-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/bad-concat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/bad_hello.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/builtin-prelude-no-accidents.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/builtin-std-paths-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/builtin-std-paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/colorful-write-macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/conditional-debug-macro-on.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/derive-in-eager-expansion-hang.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/die-macro-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/die-macro-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/die-macro-pure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/die-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/doc-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/dollar-crate-nested-encoding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/duplicate-builtin.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/empty-trailing-stmt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/format-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/format-parse-errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/format-unused-lables.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/global-asm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-25274.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-30143.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-34421-mac-expr-bad-stmt-good-add-semi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-39404.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-54441.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-58490.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-61033-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-61033-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-61053-different-kleene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-61053-duplicate-binder.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-61053-missing-repetition.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-61053-unbound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-63102.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-68058.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-68060.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-69838-dir/bar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-69838-dir/included.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-69838-mods-relative-to-included-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-70446.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-75982-foreign-macro-weird-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-77475.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-78325-inconsistent-resolution.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/issue-78892-substitution-in-statement-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/local-ambiguity-multiple-parsing-options.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/log_syntax-trace_macros-macro-locations.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-as-fn-body.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2015-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2018-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-attribute-expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-attribute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-backtrace-invalid-internals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-backtrace-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-backtrace-println.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-block-nonterminal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-comma-behavior-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-comma-behavior.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-comma-support-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-comma-support.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-context.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-crate-def-only.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-crate-nonterminal-non-root.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-crate-nonterminal-renamed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-crate-nonterminal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-crate-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-deep_expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-delimiter-significance.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-deprecation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-doc-comments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-doc-escapes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-doc-raw-str-hashes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-expanded-include/foo/mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-expanded-include/test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-expansion-tests.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-export-inner-module.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-first-set.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-follow-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-follow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-followed-by-seq-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-followed-by-seq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-in-expression-context-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-in-expression-context.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-in-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-include-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-inner-attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-input-future-proofing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-interpolation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-invalid-fragment-spec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-lifetime-used-with-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-lifetime-used-with-labels.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-lifetime-used-with-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-local-data-key-priv.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-match-nonterminal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-meta-items-modern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-meta-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-method-issue-4621.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-missing-delimiters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-missing-fragment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-multiple-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-multiple-matcher-bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-name-typo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-named-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-nested_definition_issue-31946.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-nested_expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-nested_stmt_macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-non-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-nt-list.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-of-higher-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-outer-attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-parameter-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-pat-follow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-pat-neg-lit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-shadowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-pub-matcher.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-reexport-removed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-seq-followed-by-seq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-shadowing-relaxed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-shadowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-stability-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-stmt-matchers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-stmt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-stmt_macro_in_expr_macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-tt-followed-by-seq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-tt-matchers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-use-all-and-none.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-use-all.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-use-bad-args-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-use-bad-args-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-use-both.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-use-one.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-use-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-use-undef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-use-wrong-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-with-attrs1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-with-attrs2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro-with-braces-in-expr-position.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro_path_as_generic_bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro_undefined.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macro_with_super_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macros-in-extern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/macros-nonfatal-errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/meta-item-absolute-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/meta-variable-misuse.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/missing-comma.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/must-use-in-macro-55516.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/nonterminal-matching.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/parse-complex-macro-invoc-op.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/paths-in-macro-invocations.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/pub-item-inside-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/pub-method-inside-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/restricted-shadowing-legacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/restricted-shadowing-modern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/same-sequence-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/semi-after-macro-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/span-covering-argument-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/stmt_expr_attr_macro_parse.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/syntax-extension-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/syntax-extension-source-utils.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/trace-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/trace_faulty_macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/try-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/two-macro-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/type-macros-hlist.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/type-macros-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/typeck-macro-interaction-issue-8852.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/unimplemented-macro-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/unknown-builtin.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/unreachable-fmt-msg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/unreachable-macro-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/unreachable-static-msg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/unreachable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/macros/use-macro-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/main-wrong-location.rs create mode 100644 gcc/testsuite/rust/rustc/ui/main-wrong-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/malformed/issue-69341-malformed-derive-inert.rs create mode 100644 gcc/testsuite/rust/rustc/ui/malformed/malformed-derive-entry.rs create mode 100644 gcc/testsuite/rust/rustc/ui/malformed/malformed-interpolated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/malformed/malformed-meta-delim.rs create mode 100644 gcc/testsuite/rust/rustc/ui/malformed/malformed-plugin-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/malformed/malformed-plugin-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/malformed/malformed-plugin-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/malformed/malformed-regressions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/malformed/malformed-special-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/malformed/malformed-unwind-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/malformed/malformed-unwind-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/malformed_macro_lhs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/manual/manual-link-bad-form.rs create mode 100644 gcc/testsuite/rust/rustc/ui/manual/manual-link-bad-kind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/manual/manual-link-bad-search-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/manual/manual-link-framework.rs create mode 100644 gcc/testsuite/rust/rustc/ui/map-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/marker_trait_attr/issue-61651-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/marker_trait_attr/marker-attribute-on-non-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/marker_trait_attr/marker-attribute-with-values.rs create mode 100644 gcc/testsuite/rust/rustc/ui/marker_trait_attr/marker-trait-with-associated-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/marker_trait_attr/overlap-marker-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/marker_trait_attr/override-item-on-marker-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match-on-negative-integer-ranges.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/const_non_normal_zst_ref_pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/expr-match-panic-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/expr-match-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/issue-50900.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/issue-70972-dyn-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/issue-72896.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/issue-74050-end-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-arm-resolving-to-never.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-bot-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-disc-bot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-fn-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-ill-type2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-incompat-type-semi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-join.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-no-arms-unreachable-after.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-pattern-field-mismatch-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-pattern-field-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-range-fail-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-range-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-ref-mut-invariance.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-ref-mut-let-invariance.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-ref-mut-stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-tag-nullary.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-tag-unary.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-type-err-first-arm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-unresolved-one-arm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-vec-mismatch-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/match-wildcards.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/pattern-deref-miscompile.rs create mode 100644 gcc/testsuite/rust/rustc/ui/match/type_polymorphic_byte_str_literals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/max-min-classes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/maybe-bounds-where-cpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/maybe-bounds-where.rs create mode 100644 gcc/testsuite/rust/rustc/ui/maybe-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/meta/auxiliary/env.rs create mode 100644 gcc/testsuite/rust/rustc/ui/meta/expected-error-correct-rev.rs create mode 100644 gcc/testsuite/rust/rustc/ui/meta/revision-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/meta/revision-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/meta/rustc-env.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/assign-to-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/auxiliary/ambig_impl_2_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/auxiliary/macro-in-other-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/auxiliary/method_self_arg1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/auxiliary/method_self_arg2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-ambig-one-trait-unknown-int-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-from-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-from-impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-from-impls2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-with-default-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-argument-inference-associated-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-call-err-msg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-lint-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-subst-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-unresolved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-call-type-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-early-bound-lifetimes-on-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-macro-backtrace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-missing-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-mut-self-modifies-mut-slice-lvalue.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-normalize-bounds-issue-20604.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-on-ambiguous-numeric-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-path-in-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-probe-no-guessing-dyn-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-recursive-blanket-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-resolvable-path-in-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-self-arg-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-self-arg-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-self-arg-aux1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-self-arg-aux2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-self-arg-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-self-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-trait-object-with-hrtb.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-two-trait-defer-resolution-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-two-trait-defer-resolution-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-two-traits-distinguished-via-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/methods/method-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mid-path-type-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/minmax-stability-issue-23687.rs create mode 100644 gcc/testsuite/rust/rustc/ui/minus-string.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir-dataflow/def-inits-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir-dataflow/indirect-mutation-offset.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir-dataflow/inits-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir-dataflow/liveness-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir-dataflow/liveness-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir-dataflow/uninits-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir-dataflow/uninits-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir-unpretty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/auxiliary/issue_76375_aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/auxiliary/mir_external_refs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-60390.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-66930.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-67639-normalization-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-67710-inline-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-67947.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-68841.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-71793-inline-args-storage.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-75053.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-75419-validation-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-76248.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-76375.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-76740-copy-propagation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-76803-branches-not-same.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-77359-simplify-arm-identity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue-77911.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/issue66339.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-45493.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-45885.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-68347.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-77306-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-77306-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-77564.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir-inlining/no-trait-method-issue-40473.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir-typeck-normalize-fn-sig.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_adt_construction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_ascription_coercion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_assign_eval_order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_augmented_assignments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_autoderef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_boxing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_build_match_comparisons.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_call_with_associated_type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_calls_to_shims.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_cast_fn_ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_codegen_array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_codegen_array_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_codegen_call_converging.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_converging_drops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_converging_drops_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_diverging.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_diverging_drops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_codegen_critical_edge.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_codegen_spike1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_codegen_switch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_codegen_switchint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_coercion_casts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_coercions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_const_prop_tuple_field_reorder.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_constval_adts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_detects_invalid_ops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_drop_order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_drop_panics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_dynamic_drops_1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_dynamic_drops_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_dynamic_drops_3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_early_return_scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_fat_ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_fat_ptr_drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_heavy_promoted.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_indexing_oob_1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_indexing_oob_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_indexing_oob_3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_match_arm_guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_match_test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_misc_casts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_overflow_off.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_raw_fat_ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_refs_correct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_small_agg_arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_static_subtype.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_struct_with_assoc_ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_temp_promotions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_void_return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/mir_void_return_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir/simplify-branch-same.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mir_check_nonconst.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/E0053.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/E0409.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/E0631.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/abridged.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/binops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/cast-rfc0401.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/closure-arg-count.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/closure-arg-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/closure-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/const-fn-in-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/fn-variance-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/for-loop-has-unit-body.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/issue-19109.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/issue-26480.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/issue-35030.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/issue-36053-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/issue-38371.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/issue-74918-missing-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/issue-75361-mismatched-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/method-help-unsatisfied-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/numeric-literal-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/overloaded-calls-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/recovered-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/trait-bounds-cant-coerce.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/trait-impl-fn-incompatibility.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/auxiliary/two_macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-alloc_error_handler.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-allocator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-block-hint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-comma-in-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-derivable-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-fields-in-struct-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-items/auxiliary/m1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-items/issue-40221.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-items/m2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-items/missing-type-parameter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-macro-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing/missing-stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing_debug_impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/foo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/foo_inline.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/missing_non_modrs_mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mod-subitem-as-enum-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/module-macro_use-arguments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/auxiliary/two_macros_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod-inside-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod-view-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_dir_implicit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_dir_implicit_aux/mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_dir_path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_dir_path2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_dir_path3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_dir_path_multi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_dir_recursive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_dir_simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_dir_simple/load_another_mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_dir_simple/test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_file.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_file_aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/mod_file_with_path_attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_f32.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_f64.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_float.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_correct_spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_disambig.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_disambig_aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_disambig_aux/mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/monad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/monomorphize-abi-alignment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/monomorphized-callees-with-ty-params-3314.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/issue-46099-move-in-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/issue-75904-move-closure-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-1-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-2-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-3-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-4-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-arg-2-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-arg-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-deref-coercion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-fn-self-receiver.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-guard-same-consts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-in-guard-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-in-guard-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-into-dead-array-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-into-dead-array-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-nullary-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-out-of-array-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-out-of-array-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-out-of-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-out-of-slice-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-out-of-slice-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-out-of-tuple-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/move-scalar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-access-to-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-block-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-capture-clause-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-capture-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-cyclic-types-issue-4821.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-distribute-copy-over-paren.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-exprs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-match-bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-no-recursive-stack-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/moves/moves-sru-moved-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mpsc_stress.rs create mode 100644 gcc/testsuite/rust/rustc/ui/msvc-data-only.rs create mode 100644 gcc/testsuite/rust/rustc/ui/multi-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/multibyte.rs create mode 100644 gcc/testsuite/rust/rustc/ui/multidispatch-conditional-impl-not-considered.rs create mode 100644 gcc/testsuite/rust/rustc/ui/multidispatch1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/multidispatch2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/multiline-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/multiple-main-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/multiple-main-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/multiple-plugin-registrars.rs create mode 100644 gcc/testsuite/rust/rustc/ui/multiple-reprs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mut-function-arguments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mut-vstore-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mut/mut-cant-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mut/mut-cross-borrowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mut/mut-pattern-internal-mutability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mut/mut-pattern-mismatched.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mut/mut-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mut/mut-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mut/mutable-class-fields-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mut/mutable-class-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mut/mutable-enum-indirect.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mut/no-mut-lint-for-desugared-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mutexguard-sync.rs create mode 100644 gcc/testsuite/rust/rustc/ui/mutual-recursion-group.rs create mode 100644 gcc/testsuite/rust/rustc/ui/namespace/auxiliary/namespace-mix.rs create mode 100644 gcc/testsuite/rust/rustc/ui/namespace/auxiliary/namespaced_enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/namespace/namespace-mix.rs create mode 100644 gcc/testsuite/rust/rustc/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/namespace/namespaced-enum-glob-import-no-impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/native-print-no-runtime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/negative.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nested-block-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nested-cfg-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nested-class.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nested-function-names-issue-8587.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nested-ty-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nested_impl_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nested_item_main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/adjust_never.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/auto-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/call-fn-never-arg-wrong-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/call-fn-never-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/cast-never.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/defaulted-never-note.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/dispatch_from_dyn_zst.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/diverging-fallback-control-flow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/feature-gate-never_type_fallback.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/impl-for-never.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/issue-13352.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/issue-2149.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/issue-44402.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/issue-51506.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/never-assign-dead-code.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/never-assign-wrong-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/never-associated-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/never-from-impl-is-reserved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/never-result.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/never-type-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/never-type-rvalues.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/never-value-fallback-issue-66757.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/never_coercions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/never_transmute_never.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/return-never-coerce.rs create mode 100644 gcc/testsuite/rust/rustc/ui/never_type/try_from.rs create mode 100644 gcc/testsuite/rust/rustc/ui/new-box-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/new-box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/new-impl-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/new-import-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/new-style-constants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/new-unicode-escapes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/new-unsafe-pointers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/newlambdas-ret-infer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/newlambdas-ret-infer2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/newlambdas.rs create mode 100644 gcc/testsuite/rust/rustc/ui/newtype-polymorphic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/newtype-temporary.rs create mode 100644 gcc/testsuite/rust/rustc/ui/newtype.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nil-decl-in-foreign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/assign-while-to-immutable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/borrow-use-issue-46875.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/borrowed-local-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/borrowed-match-issue-45045.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/borrowed-referent-issue-38899.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/borrowed-temporary-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/borrowed-universal-error-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/borrowed-universal-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/cannot-move-block-spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/capture-mut-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/capture-ref-in-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-access-spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-borrow-spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-captures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-move-spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-argument-callee.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-argument.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-upvar-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-upvar-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-val.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-despite-same-free-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-from-trait-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-multiple-requirements.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-requirements/return-wrong-bound-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closure-use-spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/closures-in-loops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/constant-thread-locals-issue-47053.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/constant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/decl-macro-illegal-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/do-not-ignore-lifetime-bounds-in-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/dont-print-desugared.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/drop-may-dangle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/drop-no-may-dangle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/empty-type-predicate-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/empty-type-predicate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/enum-drop-access.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/extra-unused-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/generator-distinct-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/generator-upvar-mutability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/get_default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/guarantor-issue-46974.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-16223.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-21114-ebfull.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-21114-kixunil.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-21232-partial-init-and-erroneous-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-21232-partial-init-and-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-22323-temp-destruction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-27868.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-30104.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-31567.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-42574-diagnostic-in-nested-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-43058.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-46589.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-47022.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-47153-generic-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-47388.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-47470.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-47589.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-48070.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-48238.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-48623-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-48623-generator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-48697.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-50343.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-50461-used-mut-from-moves.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-50716-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-50716.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-51191.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-51244.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-51268.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-51351.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-51512.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-52078.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-52086.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-52113.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-52534-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-52534-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-52534.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-52663-span-decl-captured-variable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-52663-trait-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-52669.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-52742.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-53040.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-53119.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-53123-raw-pointer-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-53570.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-53773.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-53807.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-54382-use-span-of-tail-of-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-54556-niconii.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-54556-stephaneyfx.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-54556-temps-in-tail-diagnostic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-54556-used-vs-unused-tails.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-54556-wrap-it-up.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-55288.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-55344.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-55394.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-55401.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-55651.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-55850.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-57100.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-57265-return-type-wf-check.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-57280-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-57280.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-57642-higher-ranked-subtype.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-57960.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-57989.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-58053.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-58299.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-61311-normalize.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-61320-normalize.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-61424.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-62007-assign-const-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-62007-assign-differing-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-63154-normalize.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-68550.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-69114-static-mut-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/issue-69114-static-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/loan_ends_mid_block_pair.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/loan_ends_mid_block_vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/local-outlives-static-via-hrtb.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/match-cfg-fake-edges.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/match-cfg-fake-edges2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/match-guards-always-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/match-guards-partially-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/match-on-borrowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-uninitialized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-with-fragment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_reify.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_unsafe_fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_unsize.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/move-errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/move-subpaths-moves-root.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/mutating_references.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/normalization-bounds-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/normalization-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/outlives-suggestion-more.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/outlives-suggestion-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/polonius/assignment-kills-loans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/polonius/assignment-to-differing-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/polonius/call-kills-loans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/polonius/issue-46589.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/polonius/polonius-smoke-test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/polonius/storagedead-kills-loans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/polonius/subset-relations.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/process_or_insert_default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/projection-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/promotable-mutable-zst-doesnt-conflict.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/promoted-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/promoted-closure-pair.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/promoted-liveness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/rc-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/reference-carried-through-struct-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/region-ends-after-if-condition.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/relate_tys/fn-subtype.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/relate_tys/hr-fn-aaa-as-aba.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/relate_tys/issue-48071.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/relate_tys/trait-hrtb.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/relate_tys/universe-violation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/relate_tys/var-appears-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/return-ref-mut-issue-46557.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/return_from_loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/self-assign-ref-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/trait-associated-constant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/impl-trait-captures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/impl-trait-outlives.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/issue-53789-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/issue-53789-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/issue-55756.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-body.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-implied-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-no-regions-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-no-regions-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-one-region-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-env.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-none.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-fn-body.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-implied-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/ty-outlives/wf-unreachable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/type-alias-free-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/type-check-pointer-coercions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/type-check-pointer-comparisons.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/unused-mut-issue-50343.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-brace-enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-brace-structs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-nullary-enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-tuple-enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-tuple-struct-calls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/cast_static_lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/closure-substs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-inherent-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-inherent-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-normalize.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/downcast-infer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/dump-adt-brace-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/dump-fn-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/fns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/inherent-associated-constants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-54124.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-54570-bootstrapping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-55219.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-55241.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/normalization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/normalize-self-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/promoted-annotation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/type-annotation-with-hrtb.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/type_ascription_static_lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/user-annotations/wf-self-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/where_clauses_in_functions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nll/where_clauses_in_structs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-capture-arc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-core-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-core-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-implicit-prelude-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-implicit-prelude.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-link-unknown-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-link.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-patterns-in-args-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-patterns-in-args-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-patterns-in-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-reuse-move-arc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-send-res-ports.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-std-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-std-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-std-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-std-inject.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-stdio.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-type-for-node-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no-warn-on-field-replace-issue-34101.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no_crate_type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no_owned_box_lang_item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no_send-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no_send-rc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no_send-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no_share-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/no_share-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/noexporttypeexe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non-built-in-quote.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non-constant-expr-for-arr-len.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non-constant-in-const-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non-copyable-void.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non-ice-error-on-worker-io-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non-integer-atomic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non-legacy-modes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inline/somename.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_foors_mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inline/somename.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/non_modrs_mods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods_and_inline_mods/x.rs create mode 100644 gcc/testsuite/rust/rustc/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/noncopyable-class.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nonscalar-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/not-clone-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/not-copy-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/not-enough-arguments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/not-sync.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nul-characters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nullable-pointer-ffi-compat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nullable-pointer-iotareduction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/nullable-pointer-size.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/arith-unsigned.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/div-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/divide-by-zero.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-int-invalid-const-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-literal-inference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-nan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-signature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float_math.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/floatlits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/i128.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/i32-sub.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/i8-incr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/int-abs-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/int.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-radix.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/mod-zero.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/num-wrapping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/numeric-method-autoexport.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-add.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-mul.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-neg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-pow-signed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-pow-unsigned.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-sub.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/promoted_overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/promoted_overflow_opt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/saturating-float-casts-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/saturating-float-casts-wasm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/saturating-float-casts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/shift-near-oflo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/shift-various-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/shift.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/signed-shift-const-eval.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u128-as-f32.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u128.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u32-decr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u8-incr-decr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u8-incr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numbers-arithmetic/uint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numeric/const-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numeric/len.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-binop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-no-fix.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-without-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numeric/numeric-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numeric/numeric-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/numeric/numeric-suffix.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-does-not-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime-default-default-to-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime-default-from-rptr-box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime-default-from-rptr-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime-default-from-rptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-ambiguous.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-elision.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-from-box-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-mybox.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-method-numbering.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-pointer-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-safety/object-safety-associated-consts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-safety/object-safety-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-safety/object-safety-by-value-self-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-safety/object-safety-by-value-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-safety/object-safety-generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-safety/object-safety-issue-22040.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-safety/object-safety-mentions-Self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-safety/object-safety-no-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-safety/object-safety-phantom-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-safety/object-safety-sized-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-safety/object-safety-sized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/object-safety/object-safety-supertrait-mentions-Self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/objects-coerce-freeze-borrored.rs create mode 100644 gcc/testsuite/rust/rustc/ui/objects-owned-object-borrowed-method-headerless.rs create mode 100644 gcc/testsuite/rust/rustc/ui/objects-owned-object-owned-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/obsolete-in-place/bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/obsolete-syntax-impl-for-dotdot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/occurs-check-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/occurs-check-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/occurs-check.rs create mode 100644 gcc/testsuite/rust/rustc/ui/offset_from.rs create mode 100644 gcc/testsuite/rust/rustc/ui/old-suffixes-are-really-forbidden.rs create mode 100644 gcc/testsuite/rust/rustc/ui/on-unimplemented/auxiliary/no_debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/on-unimplemented/bad-annotation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/on-unimplemented/enclosing-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/on-unimplemented/expected-comma-found-token.rs create mode 100644 gcc/testsuite/rust/rustc/ui/on-unimplemented/feature-gate-on-unimplemented.rs create mode 100644 gcc/testsuite/rust/rustc/ui/on-unimplemented/multiple-impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/on-unimplemented/no-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/on-unimplemented/on-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/on-unimplemented/on-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/on-unimplemented/slice-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/once-cant-call-twice-on-heap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/once-move-out-on-heap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/one-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/op-assign-builtins-by-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/opeq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/operator-associativity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/operator-multidispatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/operator-overloading.rs create mode 100644 gcc/testsuite/rust/rustc/ui/opt-in-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/optimization-fuel-0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/optimization-fuel-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/option-ext.rs create mode 100644 gcc/testsuite/rust/rustc/ui/option-to-result.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/already-bound-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/basic-switch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/basic-switchint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/bindings-runpass-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/bindings-runpass-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/box-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/consistent-bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/const-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/exhaustiveness-non-exhaustive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/exhaustiveness-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/exhaustiveness-unreachable-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/feature-gate-or_patterns-leading-for.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/feature-gate-or_patterns-leading-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/feature-gate-or_patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/fn-param-wrap-parens.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/for-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/if-let-while-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/inconsistent-modes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/issue-64879-trailing-before-guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/issue-67514-irrefutable-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/issue-68785-irrefutable-param-with-at.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/let-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/mismatched-bindings-async-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/missing-bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/mix-with-wild.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/multiple-pattern-typo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-binding-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-default-binding-modes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-syntactic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/remove-leading-vert.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/search-via-bindings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/slice-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/struct-like.rs create mode 100644 gcc/testsuite/rust/rustc/ui/or-patterns/while-parsing-this-or-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/order-dependent-cast-inference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/orphan-check-diagnostics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/osx-frameworks.rs create mode 100644 gcc/testsuite/rust/rustc/ui/out-of-order-shadowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/out-of-stack.rs create mode 100644 gcc/testsuite/rust/rustc/ui/out-pointer-aliasing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/output-slot-variants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/output-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/over-constrained-vregs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overlap-doesnt-conflict-with-specialization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overlap-permitted-for-annotated-marker-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded-calls-nontuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/auxiliary/overloaded_autoderef_xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-count.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-indexing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-vtable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-object-one-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-object-two-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-object-zero-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-param-vtables.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-zero-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-deref-count.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index-assoc-list.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index-autoderef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index-in-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded_deref_with_ref_pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs create mode 100644 gcc/testsuite/rust/rustc/ui/owned-implies-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed-struct/packed-struct-generic-transmute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed-struct/packed-struct-transmute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/auxiliary/packed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-struct-address-of-element.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-struct-borrow-element.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-struct-drop-aligned.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-struct-generic-layout.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-struct-generic-size.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-struct-layout.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-struct-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-struct-optimized-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-struct-size-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-struct-size.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-struct-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-tuple-struct-layout.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-tuple-struct-size.rs create mode 100644 gcc/testsuite/rust/rustc/ui/packed/packed-with-inference-vars-issue-61402.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-handler/auxiliary/some-panic-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-duplicate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-requires-panic-info.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-wrong-location.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/abort-link-to-unwind-dylib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/abort-link-to-unwinding-crates.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/abort.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/exit-success-if-unwind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-abort.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-unwind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-unwind2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/wants-panic-runtime-abort.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/wants-panic-runtime-unwind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/bad-panic-flag1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/bad-panic-flag2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/link-to-abort.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/link-to-unwind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/lto-abort.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/lto-unwind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/needs-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/transitive-link-a-bunch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-interleaved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-rec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-rec2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/want-unwind-got-abort.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-runtime/want-unwind-got-abort2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic-while-printing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panic_implementation-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/abort-on-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/args-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/doublepanic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/explicit-panic-msg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/explicit-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/fmt-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/issue-47429-short-backtraces.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/main-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-handler-chain.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-handler-flail-wildly.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-handler-set-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-in-dtor-drops-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-macro-any-wrapped.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-macro-any.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-macro-explicit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-macro-fmt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-macro-owned.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-macro-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-parens.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-recover-propagate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-set-handler.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-set-unset-handler.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-take-handler-nop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-task-name-none.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic-task-name-owned.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/result-get-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/test-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/test-should-fail-bad-message.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/test-should-panic-bad-message.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/test-should-panic-no-message.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/unique-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/while-body-panics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/panics/while-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/paren-free.rs create mode 100644 gcc/testsuite/rust/rustc/ui/paren-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parenthesized-deref-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parse-assoc-type-lt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parse-error-correct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parse-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser-recovery-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser-recovery-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser-unicode-whitespace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/ascii-only-character-escape.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/assoc-const-underscore-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/assoc-const-underscore-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/assoc-oddities-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/assoc-oddities-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/assoc-static-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/assoc-static-syntactic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/assoc-type-in-type-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/associated-types-project-from-hrtb-explicit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/attr-bad-meta-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/attr-bad-meta-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/attr-bad-meta.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/attr-before-eof.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/attr-dangling-in-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/attr-dangling-in-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/attr-stmt-expr-attr-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/attrs-after-extern-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bad-char-literals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bad-fn-ptr-qualifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bad-interpolated-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bad-lit-suffixes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bad-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bad-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bad-pointer-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bad-value-ident-false.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bad-value-ident-true.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bare-struct-body.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/better-expected.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bind-struct-early-modifiers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/block-no-opening-brace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bound-single-question-mark.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-where-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-where.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bounds-obj-parens.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bounds-type-where.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/bounds-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/brace-after-qualified-path-in-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/byte-literals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/byte-string-literals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/chained-comparison-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/circular_modules_hello.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/circular_modules_main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/class-implements-bad-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/closure-return-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/column-offset-1-based.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/constraints-before-generic-args-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/default-on-wrong-item-kind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/default-unmatched-assoc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/default-unmatched-extern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/default-unmatched.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/do-catch-suggests-try.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-after-struct-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-before-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-before-eof.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-before-extern-rbrace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-before-fn-rbrace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-before-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-before-mod-rbrace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-before-rbrace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-before-semi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-before-struct-rbrace-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-before-struct-rbrace-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-comment-in-if-statement.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-comment-in-stmt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/doc-inside-trait-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/duplicate-visibility.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/empty-impl-semicolon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/expr-as-stmt-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/expr-as-stmt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/extern-abi-from-mac-literal-frag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/extern-abi-raw-strings.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/extern-abi-string-escaping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/extern-abi-syntactic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/extern-crate-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/extern-crate-unexpected-token.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/extern-expected-fn-or-brace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/extern-foreign-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/extern-no-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/float-field-interpolated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/float-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/fn-arg-doc-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/fn-body-eq-expr-semi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/fn-body-optional-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/fn-body-optional-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/fn-colon-return-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/fn-header-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/fn-header-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/fn-returns-fn-pointer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/foreign-const-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/foreign-const-syntactic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/foreign-static-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/foreign-static-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/foreign-ty-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/foreign-ty-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/if-in-in.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/impl-item-const-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/impl-item-const-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/impl-item-fn-no-body-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/impl-item-fn-no-body-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/impl-item-type-no-body-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/impl-item-type-no-body-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/impl-parsing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/impl-qpath.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/import-from-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/import-from-rename.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/import-glob-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/import-glob-rename.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/inner-attr-after-doc-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/inner-attr-in-trait-def.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/inner-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/int-literal-too-large-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/intersection-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/inverted-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-10392-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-10392.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-10636-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-10636-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-14303-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-14303-fn-def.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-14303-fncall.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-14303-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-14303-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-14303-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-14303-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-15914.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-15980.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-1655.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-17383.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-17718-const-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-17904-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-17904.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-1802-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-1802-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-19096.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-19398.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-20711-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-20711.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-21153.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-22647.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-22712.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-2354-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-2354.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-23620-invalid-escapes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-24197.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-24375.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-24780.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-27255.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-30318.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-3036.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-32214.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-32446.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-32501.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-32505.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-33262.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-33413.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-33418.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-33455.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-35813-postfix-after-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-41155.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-43692.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-48137-macros-cannot-interpolate-impl-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-5544-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-5544-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-5806.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-58094-missing-right-square-bracket.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-59418.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-62524.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-62546.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-62660.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-62881.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-62894.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-62895.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-62913.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-62973.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-63115-range-pat-interpolated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-63116.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-63135.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-65041-empty-vis-matcher-in-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-65041-empty-vis-matcher-in-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-65257-invalid-var-decl-recovery.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-65846-rollback-gating-failing-matcher.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-6610.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-66357-unexpected-unreachable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-68629.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-68730.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-68788-in-trait-item-propagation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-68890-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-68890.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-70050-ntliteral-accepts-negated-lit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-70388-recover-dotdotdot-rest-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-70388-without-witness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-70549-resolve-after-recovered-self-ctor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-70552-ascription-in-parens-after-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-70583-block-is-empty-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-70583-block-is-empty-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-73568-lifetime-after-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/issue-8537.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/item-free-const-no-body-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/item-free-const-no-body-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/item-free-static-no-body-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/item-free-static-no-body-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/item-free-type-bounds-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/item-free-type-bounds-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-abstract.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-as-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-box-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-break-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-const-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-continue-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-else-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-enum-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-final.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-fn-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-for-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-if-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-impl-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-in-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-let-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-loop-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-match-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-mod-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-move-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-mut-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-override.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-pub-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-ref-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-return-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-static-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-struct-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-trait-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-try-as-identifier-edition2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-type-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-typeof.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-unsafe-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-use-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-where-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword-while-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keyword.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/keywords-followed-by-double-colon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/labeled-no-colon-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/let-binop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-bad-binary-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-7.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-bad-numeric-literals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-bad-octal-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-bad-token.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-bare-cr-string-literal-doc-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lex-stray-backslash.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lifetime-in-pattern-recover.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lifetime-in-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/lifetime-semicolon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro-bad-delimiter-ident.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro-keyword.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro-mismatched-delim-brace-paren.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro-mismatched-delim-paren-brace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro/bad-macro-argument.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro/issue-33569.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro/issue-37113.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro/issue-37234.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro/literals-are-validated-before-expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro/macro-doc-comments-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro/macro-doc-comments-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro/macro-incomplete-parse.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro/macro-repeat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro/pub-item-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro/trait-non-item-macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macro/trait-object-macro-matcher.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macros-no-semicolon-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/macros-no-semicolon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/match-arrows-block-then-binop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/match-refactor-to-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/mbe_missing_right_paren.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/mismatched-delim-brace-empty-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/missing-semicolon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/missing_right_paren.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/mod_file_not_exist.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/mod_file_not_exist_windows.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/mod_file_with_path_attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/multiline-comment-line-tracking.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/multitrait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/mut-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/no-binary-float-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/no-const-fn-in-extern-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/no-hex-float-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/no-unsafe-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/not-a-pred.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/nt-parsing-has-recovery.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/numeric-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/omitted-arg-in-item-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/paamayim-nekudotayim.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/paren-after-qualified-path-in-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-7.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-ranges-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-ranges-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-ranges-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-ranges-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-ref-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-tuple-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-tuple-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pat-tuple-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/pub-method-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/qualified-path-in-turbofish.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/range-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/range-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/range_inclusive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/range_inclusive_dotdotdot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/raw/raw-byte-string-eof.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/raw/raw-byte-string-literals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/raw/raw-literal-keywords.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/raw/raw-literal-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/raw/raw-literal-underscore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-delim.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-in-macro-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-unbalanced.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-unterminated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/raw/raw-string-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/raw/raw-string.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-assoc-const-constraint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-assoc-eq-missing-term.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-assoc-lifetime-constraint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-const-async-fn-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-enum2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-field-extra-angle-brackets.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-for-loop-parens-around-head.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-from-bad-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-from-homoglyph.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-labeled-non-block-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-missing-semi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-quantified-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-range-pats.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-tuple-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recover-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/recovered-struct-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/regions-out-of-scope-slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-closure-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-enum-newtype.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-field-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-field-semicolon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-fixed-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-fn-sigil.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-mode.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-mut-vec-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-mut-vec-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-ptr-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-record.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-static-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-uniq-mut-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-uniq-mut-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-with-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/removed-syntax-with-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/require-parens-for-chained-comparison.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/self-in-function-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/self-param-semantic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/self-param-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/several-carriage-returns-in-doc-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/shebang/issue-71471-ignore-tidy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/shebang/multiline-attrib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/shebang/regular-attrib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-and-attrib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-doc-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-must-start-file.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-space.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/shebang/sneaky-attrib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/shebang/valid-shebang.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/stmt_expr_attrs_placement.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/stripped-nested-outline-mod-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/struct-field-numeric-shorthand.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-for.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-if.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-match-discriminant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-match-guard.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-while.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/struct-literal-restrictions-in-lamda.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/tag-variant-disr-non-nullary.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trailing-carriage-return-in-string.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trailing-plus-in-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trait-bounds-not-on-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trait-item-with-defaultness-fail-semantic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trait-item-with-defaultness-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trait-object-bad-parens.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trait-object-lifetime-parens.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trait-object-polytrait-priority.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trait-object-trait-parens.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trait-plusequal-splitting.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trait-pub-assoc-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trait-pub-assoc-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/trait-pub-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/type-parameters-in-field-exprs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/unbalanced-doublequote.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/unclosed-braces.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/unclosed-delimiter-in-dep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/unclosed_delim_mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/underscore-suffix-for-float.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/underscore-suffix-for-string.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/underscore_item_not_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/unicode-chars.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/unicode-quote-chars.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/unmatched-delimiter-at-end-of-file.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/unsafe-foreign-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/unsafe-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/unsized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/unsized2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/use-as-where-use-ends-with-mod-sep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/use-ends-with-mod-sep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/variadic-ffi-nested-syntactic-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/variadic-ffi-semantic-restrictions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/variadic-ffi-syntactic-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/virtual-structs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/where-clauses-no-bounds-or-predicates.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/where_with_bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/parser/wrong-escape-of-curly-braces.rs create mode 100644 gcc/testsuite/rust/rustc/ui/partialeq_help.rs create mode 100644 gcc/testsuite/rust/rustc/ui/path-lookahead.rs create mode 100644 gcc/testsuite/rust/rustc/ui/path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pathless-extern-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/paths-containing-nul.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/bind-by-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-move-and-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/box-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/copy-and-move-mixed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-binding-mode-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-binding-modes-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-binding-modes-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/or-patterns-box-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/or-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/pat-at-same-name-both.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/slice-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/const-pat-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/deny-irrefutable-let-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/irrefutable-let-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/issue-66270-pat-struct-parser-recovery.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/issue-66501.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/issue-67776-match-same-name-enum-variant-refs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/issue-68393-let-pat-assoc-constant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/issue-68394-let-pat-runtime-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/issue-68396-let-float-bug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/issue-72565.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/issue-74539.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/issue-74702.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/issue-74954.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/issue-53840.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/pat-shadow-in-nested-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/pat-struct-field-expr-has-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/pat-tuple-bad-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/pat-tuple-overfield.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/pat-type-err-formal-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/pat-type-err-let-stmt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/patkind-litrange-no-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/pattern-binding-disambiguation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/pattern-error-continue.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/pattern-ident-path-generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/pattern-tyvar-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/pattern-tyvar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/rest-pat-semantic-disallowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/rest-pat-syntactic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/always-inhabited-union-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/consts-opaque.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/exhaustive_integer_patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/guards-not-exhaustive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/irrefutable-exhaustive-integer-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/irrefutable-unit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-35609.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-43253.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-65413-constants-and-slices-exhaustiveness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-71930-type-of-match-scrutinee.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-72476-associated-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-78549-ref-pat-and-str.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-arm-statics-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-arm-statics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-byte-array-patterns-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-byte-array-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-empty-exhaustive_patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-non-exhaustive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-privately-empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-range-fail-dominate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-ref-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-slice-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-vec-fixed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-vec-unreachable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/nested-exhaustive-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-defined-here.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-float-range-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-match-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/refutable-pattern-errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-pattern-const-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-pattern-const-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-pattern-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-patterns-irrefutable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-patterns-reachability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/struct-like-enum-nonexhaustive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/struct-pattern-match-useless.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/top-level-alternation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pattern/usefulness/tuple-struct-nonexhaustive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/phantom-oibit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/placement-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/point-to-type-err-cause-on-impl-trait-return-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/point-to-type-err-cause-on-impl-trait-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/fnmut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/fnonce.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/other.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/const_parameters/closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/const_parameters/functions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/drop_shims/simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/drop_shims/transitive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/generators.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/issue-74636.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/normalized_sig_types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/predicates.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/symbol-ambiguity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/too-many-generic-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/type_parameters/closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/type_parameters/functions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/polymorphization/unsized_cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pptypedef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/precise_pointer_size_matching.rs create mode 100644 gcc/testsuite/rust/rustc/ui/prim-with-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/primitive-binop-lhs-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print-fuel/print-fuel.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print-stdout-eprint-stderr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print_type_sizes/anonymous.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print_type_sizes/generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print_type_sizes/multiple_types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print_type_sizes/niche-filling.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print_type_sizes/no_duplicates.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print_type_sizes/packed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print_type_sizes/padding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print_type_sizes/repr-align.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print_type_sizes/repr_int_c.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print_type_sizes/uninhabited.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print_type_sizes/variants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/print_type_sizes/zero-sized-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/priv-in-bad-locations.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/associated-item-privacy-inherent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/associated-item-privacy-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/associated-item-privacy-type-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/auxiliary/cci_class.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/auxiliary/cci_class_5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/auxiliary/issue-57264-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/auxiliary/issue-57264-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/auxiliary/priv-impl-prim-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/auxiliary/privacy_reexport.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/auxiliary/privacy_tuple_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/auxiliary/private-inferred-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/auxiliary/pub_use_mods_xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/auxiliary/pub_use_xcrate1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/auxiliary/pub_use_xcrate2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/decl-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/issue-57264-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/issue-57264-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/issue-75062-fieldless-tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/legacy-ctor-visibility.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/priv-impl-prim-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy-in-paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy-ns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy-ns1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy-ns2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy-reexport.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy-sanity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy-ufcs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy1-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/privacy5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-class-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-impl-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-in-public-assoc-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-in-public-expr-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-in-public-ill-formed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-in-public-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-in-public-non-principal-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-in-public-non-principal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-in-public-type-alias-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-in-public-warn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-in-public.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-item-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-method-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-method-inherited.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-method-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-struct-field-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-struct-field-ctor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-struct-field-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-struct-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-type-in-interface.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/private-variant-reexport.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/pub-extern-privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/pub-priv1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/std-pub.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/pub-use-xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/pub_use_mods_xcrate_exe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/restricted/auxiliary/pub_restricted.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/restricted/lookup-ignores-private.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/restricted/private-in-public.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/restricted/relative-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/restricted/struct-literal-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/restricted/test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/union-field-privacy-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/privacy/union-field-privacy-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/add-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/ambiguous-builtin-attrs-test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/ambiguous-builtin-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/append-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attr-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attr-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attr-invalid-exprs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attr-on-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attr-stmt-expr-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attr-stmt-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attribute-order-restricted.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attribute-spans-preserved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attribute-with-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attribute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attributes-included.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attributes-on-definitions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attributes-on-modules-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/attributes-on-modules.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/add-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/append-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-on-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-stmt-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attribute-spans-preserved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attributes-included.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attributes-on-definitions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/bang-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/bang_proc_macro2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/builtin-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/call-site.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/count_compound_ops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-a.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-atob.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-attr-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-b-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-clona.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-ctod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-foo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowed-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-nothing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-same-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-two-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-union.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-unstable-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/dollar-crate-external.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/double.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/duplicate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/edition-imports-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/empty-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/expand-with-a-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/external-crate-var.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/first-second.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/gen-lifetime-token.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/gen-macro-rules-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/gen-macro-rules.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/generate-dollar-ident.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/generate-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/hygiene_example.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/hygiene_example_codegen.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/invalid-punct-ident.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/is-available.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-38586.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-39889.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-42708.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-50061.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-50493.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-59191.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/lifetimes-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/macro-only-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/make-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/meta-delim.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/meta-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/mixed-site-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/modify-ast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/multispan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/negative-token.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/nested-macro-rules.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/not-joint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/parent-source-spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/raw-ident.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/recollect.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/resolved-located-at.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/span-api-tests.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/span-test-macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/subspan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/test-macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/three-equals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/weird-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/bang-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/break-token-spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/call-site.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/capture-macro-rules-invoke.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/count_compound_ops.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/crate-var.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/crt-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/custom-attr-only-one-derive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/debug/auxiliary/macro-dump-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/debug/dump-debug-span-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/debug/dump-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/define-two.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-attr-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-configured.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-shadowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-shadowing-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-shadowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-in-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-same-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-still-gated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-two-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/derive-union.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/disappearing-resolution.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/doc-comment-preserved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/dollar-crate-issue-57089.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/dollar-crate-issue-62325.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/dollar-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/edition-imports-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/empty-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/empty-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/expand-to-unstable-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/expand-to-unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/expand-with-a-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/export-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/exports.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/gen-lifetime-token.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/gen-macro-rules-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/gen-macro-rules.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/generate-dollar-ident.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/generate-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actix-web-2.0.0/src/extract.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actix-web/src/extract.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actori-web-2.0.0/src/extract.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actori-web/src/extract.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/auxiliary/group-compat-hack.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/group-compat-hack.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/js-sys/src/lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/time-macros-impl/src/lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/helper-attr-blocked-by-import-ambig.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/helper-attr-blocked-by-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/hygiene_example.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/illegal-proc-macro-derive-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/input-interpolated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/invalid-attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/is-available.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-36935.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-37788.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-38586.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-39889.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-41211.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-42708.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-50061.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-50493.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-53481.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-59191-replace-root-with-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-75734-pp-paren.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-75930-derive-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-76182-leading-vert-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/issue-78675-captured-inner-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/item-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/keep-expr-tokens.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/lifetimes-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/lints_in_proc_macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/load-panic-backtrace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/load-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/load-two.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/macro-brackets.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/macro-crate-multi-decorator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/macro-namespace-reserved-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/macro-namespace-reserved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/macro-rules-derive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/macro-use-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/macro-use-bang.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/macros-in-extern-derive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/macros-in-extern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/macros-in-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/meta-delim.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/meta-macro-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/meta-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/mixed-site-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/modify-ast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/module.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/multispan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/negative-token.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/nested-item-spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/nested-macro-rules.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/nested-nonterminal-tokens.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/no-macro-use-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/no-missing-docs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/nodelim-groups.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/non-root.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/nonterminal-expansion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/nonterminal-token-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/not-joint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/out-of-line-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/outer/inner.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/parent-source-spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-deprecated-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-gates.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-gates2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/pub-at-crate-root.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/raw-ident.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/reserved-macro-names.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/resolve-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/resolved-located-at.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/shadow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/signature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/smoke.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/span-api-tests.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/span-preservation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/struct-field-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/subspan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/three-equals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/trailing-plus.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/trait-fn-args-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/two-crate-types-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/two-crate-types-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/unsafe-foreign-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/unsafe-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/visibility-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc-macro/weird-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/proc_macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/process-termination/process-termination-blocking-io.rs create mode 100644 gcc/testsuite/rust/rustc/ui/process-termination/process-termination-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/process/process-envs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/process/process-exit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/process/process-remove-from-env.rs create mode 100644 gcc/testsuite/rust/rustc/ui/process/process-sigpipe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/process/process-spawn-nonexistent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/process/process-spawn-with-unicode-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/process/process-status-inherits-stdin.rs create mode 100644 gcc/testsuite/rust/rustc/ui/process/tls-exit-status.rs create mode 100644 gcc/testsuite/rust/rustc/ui/project-cache-issue-31849.rs create mode 100644 gcc/testsuite/rust/rustc/ui/project-cache-issue-37154.rs create mode 100644 gcc/testsuite/rust/rustc/ui/project-defer-unification.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ptr-coercion-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ptr-coercion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/issue-33174-restricted-type-in-public-interface.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-or-struct-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-or-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-with-lifetime-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-with-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-ident-struct-with-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-ident-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-ident-with-lifetime-incomplete.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-reexport-priv-extern-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-restricted-error-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-restricted-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-restricted-non-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pub/pub-restricted.rs create mode 100644 gcc/testsuite/rust/rustc/ui/pure-sum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/purity-infer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/qualified/qualified-path-params-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/qualified/qualified-path-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/question-mark-type-infer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range-type-infer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/issue-54505-no-literals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/issue-54505-no-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/issue-54505.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/issue-73553-misinterp-range-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/range-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/range-inclusive-pattern-precedence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/range-inclusive-pattern-precedence2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/range_traits-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/range_traits-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/range_traits-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/range_traits-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/range_traits-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/range_traits-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range/range_traits-7.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range_inclusive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/range_inclusive_gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ranges-precedence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/raw-fat-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/raw-ref-op/feature-raw-ref-op.rs create mode 100644 gcc/testsuite/rust/rustc/ui/raw-ref-op/raw-ref-op.rs create mode 100644 gcc/testsuite/rust/rustc/ui/raw-ref-op/raw-ref-temp-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/raw-ref-op/raw-ref-temp.rs create mode 100644 gcc/testsuite/rust/rustc/ui/raw-ref-op/unusual_locations.rs create mode 100644 gcc/testsuite/rust/rustc/ui/raw-str.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rcvr-borrowed-to-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable-unnameable-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable-unnameable-type-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/auxiliary/unreachable_variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_add.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_again.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_andand.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_assign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_if.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_oror.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_repeat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_return_in_macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_tup.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_unary.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/expr_while.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/unreachable-arm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/unreachable-code.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/unreachable-in-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/unreachable-loop-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/unreachable-try-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/unreachable-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reachable/unwarned-match-on-never.rs create mode 100644 gcc/testsuite/rust/rustc/ui/readalias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/realloc-16687.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reassign-ref-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion/auxiliary/recursive_reexports.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion/issue-26548-recursion-via-normalize.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion/issue-38591-non-regular-dropck-recursion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion/recursion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion/recursive-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion/recursive-reexports.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion/recursive-requirements.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion/recursive-static-definition.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion/recursive-types-are-not-uninhabited.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion_limit/empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion_limit/invalid_digit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion_limit/overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/recursion_limit/zero.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reexport-should-still-link.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reexport-star.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reexport-test-harness-main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ref-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/refer-to-other-statics-by-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions-fn-subtyping-return-static-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/auxiliary/rbmtp_cross_crate_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/issue-56537-closure-uses-region-from-container.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/issue-72051-member-region-hang.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/issue-78262.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-borrow-params-issue-29793-big.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-borrow-params-issue-29793-small.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-bound-extra-bound-in-inherent-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-bound-on-closure-outlives-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-bounds-on-objects-and-type-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-invariant-static-error-reporting.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-in-coercion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-interior-of-unique-box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-upvar-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-adjusted-lvalue-op.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-region-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-static-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-borrow-at.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-borrow-evec-fixed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-borrow-evec-uniq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-borrow-uniq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-bot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-bound-lists-feature-gate-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-bound-lists-feature-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-bounded-by-trait-requiring-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-bounded-method-type-parameters-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-bounded-method-type-parameters-trait-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-bounded-method-type-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-close-associated-type-into-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-close-over-type-parameter-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-close-over-type-parameter-multiple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-close-over-type-parameter-successfully.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-close-param-into-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-copy-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-debruijn-of-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-dependent-addr-of.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-dependent-autofn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-dependent-autoslice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-dependent-let-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-error-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-trait-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-used-in-bound-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-used-in-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-used-in-type-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-enum-not-wf.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-escape-into-other-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-escape-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-escape-via-trait-or-not.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-expl-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-fn-subtyping-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-fn-subtyping-return-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-fn-subtyping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-callee-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-callee.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-caller.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-caller1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-incorrect.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-glb-free-free.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-in-enums-anon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-in-enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-in-structs-anon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-in-structs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-at-fn-not-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-addr-of.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-too-big.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-view.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-within-loop-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-bound-from-trait-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-bound-from-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-call-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-call-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-contravariance-due-to-decl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-contravariance-due-to-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-covariance-due-to-decl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-invariance-due-to-decl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-invariance-due-to-mutability-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-invariance-due-to-mutability-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-not-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-paramd-indirect.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-proc-static-upvar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-region-in-fn-but-not-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-infer-static-from-proc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-issue-21422.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-issue-22246.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-bounds-on-fns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-nonfree-late-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-of-struct-or-enum-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-static-items-enclosing-scopes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-link-fn-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-lub-ref-ref-rc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-mock-codegen.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-name-duplicated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-name-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-name-undeclared.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-nested-fns-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-nested-fns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-no-bound-in-argument-cleanup.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-no-variance-from-fn-generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-normalize-in-where-clause-list.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-nullary-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-container-hrtb.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-container-wc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-container.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-hrtype.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-trait-def.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-outlives-scalar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-pattern-typing-issue-19552.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-pattern-typing-issue-19997.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-proc-bound-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-reassign-let-bound-pointer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-reassign-match-bound-pointer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-reborrow-from-shorter-mut-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-ref-in-fn-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-refcell.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-ret-borrowed-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-ret-borrowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-return-interior-of-option.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-return-ref-to-upvar-issue-17403.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-return-stack-allocated-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-scope-chain-example.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-self-impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-self-in-enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-static-bound-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-static-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-static-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-steal-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-trait-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-trait-object-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-trait-object-subtyping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-trait-variance.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-undeclared.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-var-type-out-of-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-variance-contravariant-use-contravariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-variance-contravariant-use-covariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-variance-covariant-use-contravariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-variance-covariant-use-covariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-variance-invariant-use-contravariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-variance-invariant-use-covariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/regions-wf-trait-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/type-param-outlives-reempty-issue-74429-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/regions/type-param-outlives-reempty-issue-74429.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reify-intrinsic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reject-specialized-drops-8142.rs create mode 100644 gcc/testsuite/rust/rustc/ui/removing-extern-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repeat-expr-in-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repeat-to-run-dtor-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repeat_count.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repeat_count_const_in_async_fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repr/feature-gate-no-niche.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repr/repr-align-assign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repr/repr-align.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repr/repr-disallow-on-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repr/repr-no-niche-inapplicable-to-unions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repr/repr-no-niche.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repr/repr-packed-contains-align.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repr/repr-transparent-other-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repr/repr-transparent-other-reprs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repr/repr-transparent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/repr_c_int_align.rs create mode 100644 gcc/testsuite/rust/rustc/ui/required-lang-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reserved/reserved-attr-on-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/reserved/reserved-become.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve-issue-2428.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve-pseudo-shadowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/associated-fn-called-as-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-19452-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-21221-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-21221-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-3907.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/auxiliary/namespaced_enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/auxiliary/privacy-struct-ctor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/block-with-trait-parent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/enums-are-namespaced-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/impl-items-vis-unresolved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-14254.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-16058.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-17518.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-18252.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-19452.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-21221-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-21221-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-21221-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-21221-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-22692.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-23305.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-2356.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-24968.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-33876.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-3907-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-3907.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-39226.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-5035-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-5035.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-54379.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-57523.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-65025-extern-static-parent-generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-65035-static-with-parent-generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-6702.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/levenshtein.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/name-clash-nullary.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/privacy-enum-ctor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/privacy-struct-ctor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/raw-ident-in-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-assoc-suggestions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-bad-import-prefix.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-bad-visibility.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-import-vs-extern-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-import-vs-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-item-vs-extern-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-item-vs-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-type-vs-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-hint-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-inconsistent-binding-mode.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-inconsistent-names.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-label.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-primitive-fallback.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-self-in-impl-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-self-in-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-speculative-adjustment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-type-param-in-item-in-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-unknown-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/resolve-variant-assoc-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/suggest-path-instead-of-mod-dot-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/token-error-correct-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/token-error-correct-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/token-error-correct-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/token-error-correct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/tuple-struct-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/typo-suggestion-named-underscore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/unboxed-closure-sugar-nonexistent-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/unresolved_static_type_field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/use_suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/use_suggestion_placement.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve/visibility-indeterminate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resolve_self_super_hint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resource-assign-is-not-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/resource-destruct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/result-opt-conversions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ret-bang.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ret-non-nil.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ret-none.rs create mode 100644 gcc/testsuite/rust/rustc/ui/retslot-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/return-disjoint-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/return-nil.rs create mode 100644 gcc/testsuite/rust/rustc/ui/return/return-from-diverging.rs create mode 100644 gcc/testsuite/rust/rustc/ui/return/return-match-array-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/return/return-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/return/return-unit-from-diverging.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/former-E0008-now-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-use-behind-cousin-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/feature-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-empty-array-allowed-without-eq-issue-62336.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/phantom-data-is-structurally-matchable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1717-dllimport/missing-link-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1717-dllimport/multiple-renames.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1717-dllimport/rename-to-empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-never.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-str.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-in-test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-main-i32.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-not-satisfied.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/explicit-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/for.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/issue-44912-or.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/lit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/no-double-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/structs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/variants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/enum_same_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/auxiliary/types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/same_crate_proper.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/invalid-attribute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/structs_same_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/variants_same_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/call-chain.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/caller-location-intrinsic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/const-caller-location.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/diverging-caller-location.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-odd-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-invalid-abi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-naked.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-start.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/intrinsic-wrapper.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/only-for-fns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/std-panic-locations.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/track-caller-attribute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/track-caller-ffi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-fn-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-trait-impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-trait-obj.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/dont-infer-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-dyn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-union.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/infer-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/issue-54467.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-structs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-union.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/reference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-struct-not-wf.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/self-dyn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/self-structs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2126-crate-paths/crate-path-non-absolute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/auxiliary/xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/not-allowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/single-segment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2294-if-let-guard/feature-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2306/convert-id-const-with-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2457/auxiliary/mod_file_nonascii_with_path_allowed-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2457/crate_name_nonascii_forbidden-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2457/crate_name_nonascii_forbidden-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2457/idents-normalized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2457/mod_file_nonascii_forbidden.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2457/mod_file_nonascii_with_path_allowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2457/mod_inline_nonascii_allowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2457/no_mangle_nonascii_forbidden.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/ast-pretty-check.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/disallowed-positions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/feature-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/protect-precedences.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/attr-without-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-allowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-pretty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/assoc-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/feature-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/generic-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/hir-const-check.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/inherent-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc1623-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfc1623.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-1014-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-1014.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-1789-as-cell/from-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/constref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/for.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/general.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/lit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/range.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2175-or-if-while-let/basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2302-self-struct-ctor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/check-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/closures-inherit-target_feature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc1445/eq-allows-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc1623.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc1717/library-override.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rfcs/rfc1857-drop-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rmeta-lib-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rmeta-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rmeta-priv-warn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rmeta-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rmeta.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rmeta_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rmeta_meta_main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/running-with-no-runtime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/async-ident-allowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/async-ident.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/baz.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/edition-lint-paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/macro-use-warned-against.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/macro-use-warned-against2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/remove-extern-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/suggestions-not-always-applicable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/trait-import-suggestions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/dyn-keyword.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/dyn-trait-compatibility.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-fully-qualified-paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-infer-outlives-multispan.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-infer-outlives.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-nested-empty-paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-nested-paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-paths-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-uninferable-outlives.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-idiomatic-in-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-idiomatic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-referenced-by-self-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-rename.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-submod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/future-proofing-locals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/issue-51008-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/issue-51008.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/issue-52202-use-suggestions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/issue-54006.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/local-path-suggestions-2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/local-path-suggestions-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/macro-use-warned-against.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/proc-macro-crate-in-paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/remove-extern-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/suggestions-not-always-applicable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/trait-import-suggestions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/try-ident.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/try-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity-macros-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity-macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/auxiliary/issue-56596-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/auxiliary/issue-56596.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/block-scoped-shadow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/deadlock.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/fn-local-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/from-decl-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/issue-54253.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/issue-56596-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/issue-56596.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/macro-rules.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/prelude-fail-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/prelude-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/prelude.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/redundant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rustc-args-required-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rustc-args-required-const2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rustc-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rustc-rust-log.rs create mode 100644 gcc/testsuite/rust/rustc/ui/rvalue-static-promotion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/safe-extern-statics-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/safe-extern-statics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sanitize/address.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sanitize/badfree.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sanitize/cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sanitize/incompatible.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sanitize/inline-always.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sanitize/issue-72154-lifetime-markers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sanitize/leak.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sanitize/memory.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sanitize/new-llvm-pass-manager-thin-lto.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sanitize/thread.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sanitize/unsupported-target.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sanitize/use-after-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/save-analysis/emit-notifications.rs create mode 100644 gcc/testsuite/rust/rustc/ui/save-analysis/issue-59134-0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/save-analysis/issue-59134-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/save-analysis/issue-63663.rs create mode 100644 gcc/testsuite/rust/rustc/ui/save-analysis/issue-64659.rs create mode 100644 gcc/testsuite/rust/rustc/ui/save-analysis/issue-65411.rs create mode 100644 gcc/testsuite/rust/rustc/ui/save-analysis/issue-65590.rs create mode 100644 gcc/testsuite/rust/rustc/ui/save-analysis/issue-68621.rs create mode 100644 gcc/testsuite/rust/rustc/ui/save-analysis/issue-72267.rs create mode 100644 gcc/testsuite/rust/rustc/ui/save-analysis/issue-73020.rs create mode 100644 gcc/testsuite/rust/rustc/ui/save-analysis/issue-73022.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary-self-types-not-object-safe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pointers_and_wrappers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_raw_pointer_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_raw_pointer_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_silly.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_stdlib_pointers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_unsized_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/auxiliary/explicit_self_xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/builtin-superkinds-self-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/by-value-self-in-mut-slot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/alias-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/assoc-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/assoc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/lt-alias-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/lt-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/lt-assoc-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/lt-assoc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/lt-ref-self-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/lt-ref-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/lt-self-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/lt-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/lt-struct-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/lt-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/multiple-ref-self-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/multiple-ref-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-alias-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-assoc-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-assoc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-alias-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-self-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-struct-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-self-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-struct-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/ref-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/self-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/struct-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/elision/struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/explicit-self-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/explicit-self-generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/explicit-self-objects-uniq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/explicit-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/explicit_self_xcrate_exe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/move-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/object-safety-sized-self-by-value-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/object-safety-sized-self-generic-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/object-safety-sized-self-return-Self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/point-at-arbitrary-self-type-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/point-at-arbitrary-self-type-trait-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self-impl-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self-in-mut-slot-default-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self-in-mut-slot-immediate-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self-in-typedefs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self-infer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self-re-assign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self-shadowing-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self-type-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self-vs-path-ambiguity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self_lifetime-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self_lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self_type_keyword-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/self_type_keyword.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/string-self-append.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/suggest-self-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/suggest-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/ufcs-explicit-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/uniq-self-in-mut-slot.rs create mode 100644 gcc/testsuite/rust/rustc/ui/self/where-for-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/semistatement-in-lambda.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sepcomp/auxiliary/sepcomp-extern-lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sepcomp/auxiliary/sepcomp_cci_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sepcomp/auxiliary/sepcomp_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-cci.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-extern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-fns-backwards.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-fns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-lib-lto.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-statics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-unwind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/seq-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/seq-compare.rs create mode 100644 gcc/testsuite/rust/rustc/ui/shadow-bool.rs create mode 100644 gcc/testsuite/rust/rustc/ui/shadow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/shadowed-use-visibility.rs create mode 100644 gcc/testsuite/rust/rustc/ui/shadowed/shadowed-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/shadowed/shadowed-trait-methods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/shadowed/shadowed-type-parameter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/shadowed/shadowed-use-visibility.rs create mode 100644 gcc/testsuite/rust/rustc/ui/shadowed/shadowing-in-the-same-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/shift-various-bad-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/short-error-format.rs create mode 100644 gcc/testsuite/rust/rustc/ui/signal-alternate-stack-cleanup.rs create mode 100644 gcc/testsuite/rust/rustc/ui/signal-exit-status.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sigpipe-should-be-ignored.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-comparison.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-elements.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-select.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd-type-generic-monomorphisation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/shuffle-not-out-of-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-float-math.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-float-minmax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-arithmetic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-bitmask.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-comparison.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-elements.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-gather.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-reduction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-select.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-size-align.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-target-feature-mixup.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simd/simd-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/similar-tokens.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simple-infer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/simple_global_asm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-primitive-inherent-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/fn-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-fn-argument-in-band.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-fn-argument.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-fn-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-inherent-impl-header.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-inherent-method-argument.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-inherent-method-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-trait-method-argument.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-fn-arguments.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/zero-uses-in-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/single-use-lifetime/zero-uses-in-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/size-and-align.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sized-borrowed-pointer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sized-cycle-note.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sized-owned-pointer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sleep.rs create mode 100644 gcc/testsuite/rust/rustc/ui/slice-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/slice-mut-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/slice-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/slice-to-vec-comparison.rs create mode 100644 gcc/testsuite/rust/rustc/ui/slightly-nice-generic-literal-messages.rs create mode 100644 gcc/testsuite/rust/rustc/ui/slowparse-bstring.rs create mode 100644 gcc/testsuite/rust/rustc/ui/slowparse-string.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/E0046.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/E0057.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/E0072.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/E0204.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/E0493.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/E0535.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/E0536.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/E0537.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/auxiliary/transitive_dep_three.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/auxiliary/transitive_dep_two.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/borrowck-borrow-overloaded-auto-deref-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/borrowck-borrow-overloaded-deref-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/borrowck-call-is-borrow-issue-12224.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/borrowck-call-method-from-mut-aliasable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/borrowck-fn-in-const-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/borrowck-let-suggestion-suffixes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/borrowck-object-mutability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/borrowck-ref-into-rvalue.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/coerce-suggestions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/destructor-restrictions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/dropck-object-cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/dropck_arr_cycle_checked.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/dropck_direct_cycle_with_drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/dropck_misc_variants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/dropck_vec_cycle_checked.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/gated-features-attr-spans.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/impl-wrong-item-for-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/import-ty-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-11925.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-15480.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-23338-locals-die-before-temps-of-body.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-23729.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-23827.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-24356.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-24690.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-24805-dropck-child-has-items-via-parent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-24805-dropck-trait-has-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-24895-copy-clone-dropck.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-25199.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-26656.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-27522.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-29106.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-29595.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-33884.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-34264.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-35987.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-36530.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-36537.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-37767.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-39018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-39698.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-40157.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-42234-unknown-receiver-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-43927-non-ADT-derive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue-7575.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue28498-reject-ex1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue28498-reject-lifetime-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue28498-reject-passed-to-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/issue28498-reject-trait-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/lint-unused-unsafe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/macro-span-replacement.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/macro-ty-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/method-and-field-eager-resolution.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/missing-unit-argument.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/move-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/multiline-span-E0072.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/multiline-span-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/multispan-import-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/mut-arg-hint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/mut-ptr-cant-outlive-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/non-existing-module-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/pub-struct-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/range-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/recursive-type-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/regionck-unboxed-closure-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/regions-close-over-borrowed-ref-in-obj.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/regions-close-over-type-parameter-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/regions-escape-loop-via-variable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/regions-escape-loop-via-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/regions-infer-borrow-scope-within-loop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/send-is-not-static-ensures-scoping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/send-is-not-static-std-sync-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/send-is-not-static-std-sync.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/slice-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/suggestion-non-ascii.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/transitive-dep-span.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/type-annotations-needed-expr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/type-binding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/typo-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/unused-warning-point-at-identifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/vec-must-not-hide-type-from-dropck.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/vec_refs_data_with_early_death.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/visibility-ty-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/span/wf-method-late-bound-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/assoc-ty-graph-cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/auxiliary/cross_crates_defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/auxiliary/go_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/auxiliary/specialization_cross_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/cross-crate-defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/deafult-associated-type-bound-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/deafult-associated-type-bound-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/deafult-generic-associated-type-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/allowed-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/auxiliary/go_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/out-of-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/overlap-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-feature-gate-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-no-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-wfcheck.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/validation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/issue-36804.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/issue-38091-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/issue-38091.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/issue-39448.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/issue-39618.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/issue-44861.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/issue-50452.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/issue-52050.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/issue-59435.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/issue-63716-parse-async.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/issue-70442.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/auxiliary/specialization-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/dyn-trait-assoc-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/impl-on-nonexisting.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/impl_specialization_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/implcit-well-formed-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/repeated_projection_type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/repeating_lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/repeating_param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/spec-iter.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/spec-reference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialization_marker.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialization_super_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialization_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_marker.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_spec_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/non-defaulted-item-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/soundness/partial_eq_range_inclusive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/soundness/partial_ord_slice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-allowed-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-assoc-fns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-basics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-cross-crate-no-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-default-methods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-default-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-default-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-feature-gate-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-feature-gate-overlap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-no-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-on-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-out-of-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap-negative.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-polarity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-projection-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-super-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-translate-projections-with-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-translate-projections-with-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/specialization/specialization-translate-projections.rs create mode 100644 gcc/testsuite/rust/rustc/ui/sse2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/auxiliary/stability_attribute_issue.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/auxiliary/unstable_generic_param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/generics-default-stability-where.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/generics-default-stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/missing-const-stability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/missing-stability-attr-at-top-level.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-issue-43027.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-issue.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-non-staged-force-unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-non-staged.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stability-in-private-module.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stable-addr-of.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stable-features.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/auxiliary/issue_24843.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/auxiliary/static-priv-by-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/auxiliary/static_priv_by_default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/issue-24843.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-drop-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-extern-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-items-cant-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-lifetime-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-method-privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-mut-bad-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-mut-foreign-requires-unsafe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-mut-not-constant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-mut-not-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-mut-requires-unsafe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-priv-by-default2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-reference-to-fn-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-reference-to-fn-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-region-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static/static-vec-repeat-not-constant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/static_sized_requirement.rs create mode 100644 gcc/testsuite/rust/rustc/ui/staticness-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/auxiliary/static-function-pointer-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/auxiliary/static-methods-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/auxiliary/static_fn_inline_xc_aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/auxiliary/static_fn_trait_xc_aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/auxiliary/static_mut_xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/static-fn-inline-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/static-fn-trait-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/static-function-pointer-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/static-function-pointer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/static-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/static-method-in-trait-with-tps-intracrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/static-method-xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/static-methods-in-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/static-methods-in-traits2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/static-mut-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/static-promotion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/static-recursive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/statics/uninhabited-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/std-backtrace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/std-uncopyable-atomics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stdio-is-blocking.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stdout-during-shutdown.rs create mode 100644 gcc/testsuite/rust/rustc/ui/stmt_expr_attrs_no_feature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/str/str-array-assignment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/str/str-as-char.rs create mode 100644 gcc/testsuite/rust/rustc/ui/str/str-concat-on-double-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/str/str-idx.rs create mode 100644 gcc/testsuite/rust/rustc/ui/str/str-lit-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/str/str-mut-idx.rs create mode 100644 gcc/testsuite/rust/rustc/ui/str/str-overrun.rs create mode 100644 gcc/testsuite/rust/rustc/ui/string-box-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/struct-ctor-mangling.rs create mode 100644 gcc/testsuite/rust/rustc/ui/struct-literal-variant-in-if.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/align-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/align-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/empty-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/namespaced_enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/newtype_struct_xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/struct_destructuring_cross_crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/struct_variant_xc_aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/xcrate_struct_aliases.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/borrow-tuple-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-cast-to-trait-multiple-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-cast-to-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-dtor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-exports.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-impl-very-parameterized-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-implement-trait-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-implement-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-method-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-methods-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-methods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-poly-methods-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-poly-methods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-separate-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-str-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/class-typarams.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/classes-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/classes-self-referential.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/classes-simple-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/classes-simple-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/classes-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/classes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/codegen-tag-static-padding.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/compare-generic-enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/discrim-explicit-23030.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/empty-struct-braces.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/empty-tag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-alignment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-clike-ffi-as-int.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-discr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-autosizing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-manual-sizing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-range-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-width-stuff.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-disr-val-pretty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-export-inheritance.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-layout-optimization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-non-c-like-repr-c-and-int.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-non-c-like-repr-c.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-non-c-like-repr-int.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-null-pointer-opt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-nullable-const-null-with-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-univariant-repr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-variants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/enum-vec-initializer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/export-abstract-tag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/export-tag-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/expr-if-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/expr-match-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/field-destruction-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/foreign-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/functional-struct-upd.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/ivec-tag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/module-qualified-struct-destructure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-emulate-flat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-glob-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enums-xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/nested-enum-same-names.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-drop-run.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-with-dtor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-xc-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/nonzero-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/numeric-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/object-lifetime-default-from-ref-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/rec-align-u32.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/rec-align-u64.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/rec-auto.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/rec-extend.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/rec-tup.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/rec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/record-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/resource-in-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/simple-generic-tag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/simple-match-generic-tag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/small-enum-range-edge.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/small-enums-with-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-aliases-xcrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-aliases.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-destructuring-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-field-shorthand.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-like-variant-construct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-like-variant-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-lit-functional-no-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-literal-dtor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-new-as-field-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-partial-move-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-partial-move-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-path-associated-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-path-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-pattern-matching.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct-variant-field-visibility.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct_variant_xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/struct_variant_xc_match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-dyn-u64.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-dyn-variants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-shape.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-u64.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tag-disr-val-shape.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tag-exports.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tag-in-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tag-variant-disr-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tag-variant-disr-val.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-construct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-constructor-pointer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-destructuring.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-matching.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-trivial.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/uninstantiable-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/unit-like-struct-drop-run.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/unit-like-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs-enums/variant-structs-trivial.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/auxiliary/struct_field_privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/auxiliary/struct_variant_privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/rhs-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-base-wrong-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-duplicate-comma.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-field-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-field-init-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-field-privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-fields-decl-dupe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-fields-dupe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-fields-hints-no-dupe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-fields-hints.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-fields-missing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-fields-shorthand-unresolved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-fields-shorthand.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-fields-too-many.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-fields-typo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-missing-comma.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-pat-derived-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-path-alias-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-path-associated-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-path-self-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-path-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-variant-privacy-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/struct-variant-privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structs/structure-constructor-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/structured-compare.rs create mode 100644 gcc/testsuite/rust/rustc/ui/substs-ppaux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suffixed-literal-meta.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/adt-param-with-implicit-sized-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/as-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/assoc-const-as-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/assoc-type-in-method-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/attribute-typos.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/foo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/issue-61963-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/issue-61963.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/struct_field_privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/borrow-for-loop-head.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/chain-method-call-mutation-in-place.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/const-in-struct-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/const-no-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/const-pat-non-exaustive-let-new-var.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/constrain-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-ref/move-into-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-ref/simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-try_into-in-macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/expected-boxed-future-isnt-pinned.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/fn-missing-lifetime-in-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/fn-needing-specified-return-type-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/fn-or-tuple-struct-without-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/fn-trait-notation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/for-i-in-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/format-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/if-let-typo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/imm-ref-trait-object-literal-bound-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/imm-ref-trait-object-literal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/imm-ref-trait-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-missing-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-return-trailing-semicolon.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-with-missing-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/into-str.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/invalid-bin-op.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/issue-21673.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/issue-52820.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/issue-57672.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/issue-59819.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/issue-61226.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/issue-61963.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/issue-62843.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/issue-64252-self-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/issue-66968-suggest-sorted-words.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/issue-71394-no-from-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/issue-72766.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/js-style-comparison-op-separate-eq-token.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/js-style-comparison-op.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/let-binding-init-expr-as-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/match-ergonomics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/match-needing-semi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/match-prev-arm-needing-semi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/method-missing-parentheses.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/mismatched-types-numeric-from.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/missing-assoc-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/missing-assoc-type-bound-restriction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/missing-lifetime-in-assoc-const-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/missing-lifetime-specifier.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/missing-lt-for-hrtb.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/missing-trait-bound-for-op.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/missing-trait-bounds-for-method-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/missing-trait-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/mut-borrow-needed-by-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/mut-ref-reassignment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/no-extern-crate-in-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/object-unsafe-trait-references-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/object-unsafe-trait-should-use-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/opaque-type-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/option-content-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/option-content-move2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/path-by-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/path-display.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/raw-name-use-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/recover-from-semicolon-trailing-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/recover-invalid-float.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/recover-missing-turbofish-surrounding-angle-braket.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/remove-as_str.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/restrict-type-argument.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/return-without-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/struct-initializer-comma.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-closure-return-type-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-closure-return-type-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-closure-return-type-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-impl-trait-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-labels.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-methods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-move-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-move-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-on-bare-closure-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-private-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-ref-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-remove-refs-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-remove-refs-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-remove-refs-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-split-at-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-std-when-using-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/suggest-variants.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/trait-with-missing-associated-type-restriction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-path-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/type-mismatch-struct-field-shorthand-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/type-mismatch-struct-field-shorthand.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/type-not-found-in-adt-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/unused-closure-argument.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/use-type-argument-instead-of-assoc-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suggestions/vec-macro-in-pattern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/super-at-top-level.rs create mode 100644 gcc/testsuite/rust/rustc/ui/super-fast-paren-parsing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/super.rs create mode 100644 gcc/testsuite/rust/rustc/ui/supported-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/suppressed-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh-add-nothing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-base.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-lit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-significant-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-trait-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-type-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-type-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-type-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-b.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-uta-base.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-uta-change-use-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-utb.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/svh-change-lit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/svh-change-significant-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/svh-change-trait-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/svh-change-type-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/svh-change-type-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/svh-change-type-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/svh/svh-use-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/swap-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/swap-overlapping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/switched-expectations.rs create mode 100644 gcc/testsuite/rust/rustc/ui/symbol-names/basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/symbol-names/const-generics-demangling.rs create mode 100644 gcc/testsuite/rust/rustc/ui/symbol-names/const-generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/symbol-names/impl1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/symbol-names/impl2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/symbol-names/issue-60925.rs create mode 100644 gcc/testsuite/rust/rustc/ui/symbol-names/issue-75326.rs create mode 100644 gcc/testsuite/rust/rustc/ui/symbol-names/issue-76365.rs create mode 100644 gcc/testsuite/rust/rustc/ui/syntax-extension-minor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/syntax-trait-polarity-feature-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/syntax-trait-polarity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/synthetic-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tag-that-dare-not-speak-its-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tag-type-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tag-variant-cast-non-nullary.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tag-variant-disr-dup.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tail-call-arg-leak.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tail-cps.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tail-direct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tail-typeck.rs create mode 100644 gcc/testsuite/rust/rustc/ui/target-feature/gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/target-feature/invalid-attribute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tcp-stress.rs create mode 100644 gcc/testsuite/rust/rustc/ui/terminal-width/flag-human.rs create mode 100644 gcc/testsuite/rust/rustc/ui/terminal-width/flag-json.rs create mode 100644 gcc/testsuite/rust/rustc/ui/terminal-width/non-1-width-unicode-multiline-label.rs create mode 100644 gcc/testsuite/rust/rustc/ui/terminal-width/non-whitespace-trimming-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/terminal-width/non-whitespace-trimming-unicode.rs create mode 100644 gcc/testsuite/rust/rustc/ui/terminal-width/non-whitespace-trimming.rs create mode 100644 gcc/testsuite/rust/rustc/ui/terminal-width/whitespace-trimming-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/terminal-width/whitespace-trimming.rs create mode 100644 gcc/testsuite/rust/rustc/ui/terminate-in-initializer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/terr-in-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/terr-sorts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-allow-dead-extern-static-no-warning.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/auxiliary/test_macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/decl-macro-test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/inaccessible-test-modules.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/run-unexported-tests.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-allow-fail-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-attr-non-associated-functions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-cant-be-shadowed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-fn-signature-verification-for-explicit-return-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-main-not-dead-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-main-not-dead.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-on-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-runner-hides-buried-main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-runner-hides-main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-runner-hides-start.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-should-fail-good-message.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-should-panic-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-vs-cfg-test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-attrs/test-warns-dead-code.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-cfg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-panic-abort-disabled.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-panic-abort-nocapture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-panic-abort.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-panic-while-printing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-thread-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/test-thread-nocapture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thin-lto-global-allocator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thinlto/all-crates.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thinlto/auxiliary/dylib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thinlto/auxiliary/msvc-imp-present.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thinlto/dylib-works.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thinlto/msvc-imp-present.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thinlto/thin-lto-inlines.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thinlto/thin-lto-inlines2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thinlto/weak-works.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thread-local-in-ctfe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thread-local-mutation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/thread-local-not-in-prelude.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/comm.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/send-is-not-static-par-for.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/send-resource.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/send-type-inference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/send_str_hashmap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/send_str_treemap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/sendable-class.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/sendfn-is-a-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/spawning-with-debug.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/std-sync-right-kind-impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-atomics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-in-std.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-iterators-in-libcore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-10.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-11.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-12.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-13.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-14.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-15.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-16.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-17.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-7.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-9.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-chan-nil.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-life-0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-spawn-barefn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-spawn-move-and-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/task-stderr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/test-tasks-invalid-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/thread-local-extern-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/thread-local-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/threads.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/tls-init-on-init.rs create mode 100644 gcc/testsuite/rust/rustc/ui/threads-sendsync/tls-try-with.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tool-attributes/diagnostic_item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tool-attributes/diagnostic_item2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tool-attributes/diagnostic_item3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tool-attributes/tool-attributes-misplaced-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tool-attributes/tool-attributes-misplaced-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tool-attributes/tool-attributes-shadowing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tool_attributes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tool_lints-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tool_lints-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tool_lints.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tool_lints_2018_preview.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trace_macros-format.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trace_macros-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trailing-comma.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trait-impl-bound-suggestions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trait-method-number-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/anon-trait-static-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/anon_trait_static_method_exe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/assignability-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/assoc_type_bound_with_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/astconv-cycle-between-trait-and-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/augmented-assignments-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/anon_trait_static_method_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/crate_a1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/crate_a2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/go_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_bounds_on_structs_and_enums_xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_default_method_xc_aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_default_method_xc_aux_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_inheritance_auto_xc_aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_inheritance_overloading_xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_safety_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_xc_call_aux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/auxiliary/traitimpl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-2-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/conservative_impl_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/cycle-cache-err-60010.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/cycle-trait-type-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/default-method-supertrait-vtable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/dyn-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/fmt-pointer-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/impl-evaluation-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/impl-implicit-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/impl-inherent-prefer-over-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/impl_trait_as_trait_return_position.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/infer-from-object-trait-issue-26952.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/inherent-trait-method-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/issue-70944.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/issue-72410.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/issue-75627.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/issue-77982.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/kindck-owned-trait-contains-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/multiple-trait-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/auxiliary/foreign_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/feature-gate-negative_impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/negated-auto-traits-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/negated-auto-traits-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-default-impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-impls-basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-specializes-negative.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-specializes-positive-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-specializes-positive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/no-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/positive-specializes-negative.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/negative-impls/rely-on-negative-impl-in-coherence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/normalize-super-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/object-one-type-two-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/overlap-not-permitted-for-builtin-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/overlap-permitted-for-marker-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/parameterized-trait-with-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/principal-less-trait-objects.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-no-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-non-lattice-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/self-without-lifetime-constraint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/supertrait-default-generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/syntax-trait-polarity.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias-ambiguous.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias-import-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/auxiliary/trait_alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/issue-60021-assoc-method-resolve.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/issue-72415-assoc-const-resolve.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/issue-75983.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-maybe-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-no-duplicates.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-no-extra-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-object-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-object-wf.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-only-maybe-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-syntax-fail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-syntax.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-wf.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-as-struct-constructor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-impl-comparison-duplicates.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-in-arc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-not-on-bare-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-not-on-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-in-fns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-in-impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-locals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-xc1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-recursion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-same-crate-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds-sugar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-cache-issue-18209.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-coercion-generic-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-coercion-generic-regions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-coercion-generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-coercion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-composition-trivial.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-copy-guessing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-default-method-xc-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-default-method-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-duplicate-methods.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-false-ambiguity-where-clause-builtin-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-impl-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-impl-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-impl-can-not-have-untraitful-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-impl-different-num-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-impl-for-module.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-impl-method-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-auto-xc-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-auto-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-auto.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-call-bound-inherited.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-call-bound-inherited2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cast-without-call-to-supertrait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cross-trait-call-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cross-trait-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-diamond.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-multiple-inheritors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-multiple-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-overloading-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-overloading-xc-exe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-overloading.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-self-in-supertype.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-static2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-subst.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-subst2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-visibility.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-inheritance2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-item-inside-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-item-privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-matching-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-method-private.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-auto-dedup-in-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-auto-dedup.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-exclusion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-generics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-lifetime-first.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-macro-matcher.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-safety.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-supertrait-lifetime-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-vs-lifetime-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-vs-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-with-lifetime-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-with-self-in-projection-output-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-with-self-in-projection-output-good.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-or-new-type-instead.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-param-without-lifetime-constraint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-privacy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-region-pointer-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-resolution-in-overloaded-op.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-safety-fn-body.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-safety-inherent-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-safety-ok-cc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-safety-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-safety-trait-impl-cc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-safety-trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-static-method-generic-inference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-static-method-overwriting.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-issue-39029.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-issue-62530.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-multiple-0.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-multiple-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-suggest-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-test-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-to-str.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-where-clause-vs-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-with-bounds-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/trait-with-dst.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-assoc-type-in-supertrait-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-assoc-type-in-supertrait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-conditional-dispatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-conditional-model-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-default-method-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-default-method-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-default-method-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-default-method-trivial.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-elaborate-type-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-impl-object-overlap-issue-23853.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-simultaneous.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-supertrait-oibit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-supertrait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-two-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-issue-22019.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-issue-22110.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-issue-22655.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-issue-23003-overflow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-issue-23003.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-issue-26339.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-issue-71136.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-multidispatch-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-multidispatch-convert-ambig-dest.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-multidispatch-infer-convert-target.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-repeated-supertrait-ambig.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-repeated-supertrait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/traits-static-outlives-a-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/ufcs-trait-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/use-trait-before-def.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-maybe-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-no-duplicates.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-only-maybe-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-reverse-order.rs create mode 100644 gcc/testsuite/rust/rustc/ui/transmute-equal-assoc-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/transmute-non-immediate-to-immediate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/transmute-specialization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/transmute/main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/transmute/transmute-different-sizes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/transmute/transmute-fat-pointers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/transmute/transmute-from-fn-item-types-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/transmute/transmute-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/transmute/transmute-imut-to-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/transmute/transmute-type-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-leak-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-leak.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial-message.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial_casts-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/trivial_casts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block/try-block-bad-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block/try-block-bad-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block/try-block-catch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block/try-block-in-edition2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block/try-block-in-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block/try-block-in-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block/try-block-in-while.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block/try-block-maybe-bad-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block/try-block-opt-init.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block/try-block-type-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block/try-block-unreachable-code-lint.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-block/try-block-unused-delims.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-from-int-error-partial-eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-is-identifier-edition2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-macro-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-on-option-diagnostics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-on-option.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-operator-custom.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-operator-hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-operator-on-main.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-operator.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-poll.rs create mode 100644 gcc/testsuite/rust/rustc/ui/try-wait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tup.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tuple-index-fat-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tuple-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tuple/index-float.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tuple/index-invalid.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tuple/indexing-in-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tuple/nested-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tuple/tuple-arity-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tuple/tuple-index-not-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tuple/tuple-index-out-of-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tuple/tuple-struct-fields/test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tuple/tuple-struct-fields/test2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tuple/tuple-struct-fields/test3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tutorial-suffix-inference-test.rs create mode 100644 gcc/testsuite/rust/rustc/ui/tydesc-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-generic-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/issue-57866.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/self-in-enum-definition.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/assoc-type-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/assoc-type-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bound_reduction.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bound_reduction2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bounds-are-checked-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bounds-are-checked.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/coherence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/cross_crate_ice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/cross_crate_ice2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/declared_but_never_defined.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/different_defining_uses.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/different_defining_uses_never_type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/fallback.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_different_defining_uses.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_lifetime_param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_nondefining_use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_not_used.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_underconstrained.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_underconstrained2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-52843.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-53096.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-53598.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57611-trait-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57700.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57807-associated-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-58887.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-58951.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-60371.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-60407.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-60564.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-63263-closure-return.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-63279.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-65918.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-70121.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-74244.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-74761.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/never_reveal_concrete_type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/not_a_defining_use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/not_well_formed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/private_unused.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/structural-match-no-leak.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/structural-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/unused_generic_param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias/issue-62263-self-in-atb.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias/issue-62305-self-assoc-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-alias/issue-62364-self-ty-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-ascription.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-id-higher-rank-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-id-higher-rank.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-in-nested-module.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-infer-generalize-ty-var.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-inference/or_else-multiple-type-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-inference/sort_by_key.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-inference/unbounded-associated-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-inference/unbounded-type-param-in-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-namespace.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-param-constraints.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-params-in-for-each.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-sizes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type-use-i1-versus-i8.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/ascription/issue-34255-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/ascription/issue-47666.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/ascription/issue-54516.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/ascription/issue-60933.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/auxiliary/crate_a1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/auxiliary/crate_a2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-alias-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-annotation-needed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-arg-out-of-scope.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-ascription-instead-of-initializer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-ascription-instead-of-statement-end.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-ascription-precedence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-ascription-soundness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-ascription-with-fn-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-check-defaults.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-check/assignment-expected-bool.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-check/assignment-in-if.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-check/cannot_infer_local_or_array.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-check/cannot_infer_local_or_vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-check/issue-22897.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-check/issue-40294.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-check/issue-41314.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-check/missing_trait_impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-check/unknown_type_for_closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-dependent-def-issue-49241.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-error-break-tail.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-mismatch-multiple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-mismatch-same-crate-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-parameter-defaults-referencing-Self-ppaux.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-parameter-defaults-referencing-Self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-parameter-names.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-params-in-different-spaces-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-params-in-different-spaces-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-params-in-different-spaces-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-path-err-node-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-recursive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type/type-shadow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/type_length_limit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck-closure-to-unsafe-fn-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck-fn-to-unsafe-fn-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/auxiliary/tdticc_coherence_lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/issue-52082-type-param-shadows-existing-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/issue-67971.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/issue-68590-reborrow-through-derefmut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/issue-72225-call-fnmut-through-derefmut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/issue-73592-borrow_mut-through-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/issue-74933.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck-builtin-bound-type-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck-cast-pointer-to-float.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-assoc-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-negation-send.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-negation-sync.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-send-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck-unsafe-always-share.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_item_help.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_lifetime_1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_lifetime_2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeck_type_placeholder_1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeclasses-eq-example-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeclasses-eq-example.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typeid-intrinsic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typestate-cfg-nesting.rs create mode 100644 gcc/testsuite/rust/rustc/ui/typestate-multi-decl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ufcs-polymorphic-paths.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ufcs-type-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ufcs/ufcs-explicit-self-bad.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ufcs/ufcs-partially-resolved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ufcs/ufcs-qpath-missing-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ufcs/ufcs-qpath-self-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/ui-testing-optout.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unary-minus-suffix-inference.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/issue-30906.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/issue-53448.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-feature-gate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-illegal-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-immutable-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-equiv.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-all-traits.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-blanket-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-borrow-conflict.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-boxed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-by-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-fn-autoderef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-extern-fn-hr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-extern-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-call-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-move-call-twice.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-kind.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-recursive-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-upvar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-manual-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-monomorphization.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-move-mutable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-prelude.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-recursive-fn-using-fn-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-simple.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-single-word-env.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-sugar-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-type-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-unique-type-id.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-wrong-abi.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-zero-args.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unconstrained-none.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unconstrained-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-ident-matcher.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-imports/auxiliary/duplicate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-imports/auxiliary/underscore-imports.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-imports/basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-imports/cycle.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-imports/duplicate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-imports/hygiene-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-imports/hygiene.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-imports/intercrate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-imports/macro-expanded.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-imports/shadow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-imports/unused-2018.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/dyn-trait-underscore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/in-binder.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/in-fn-return-illegal.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/in-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/underscore-lifetime-binders.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/underscore-outlives-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-trait-impl-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clauses.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/underscore-method-after-integer.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unevaluated_fixed_size_array_len.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uniform-paths/auxiliary/issue-53691.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uniform-paths/basic-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uniform-paths/basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uniform-paths/issue-53691.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uniform-paths/macros-nested.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uniform-paths/macros.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uniform-paths/same-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unify-return-ty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uninhabited/privately-uninhabited-dead-code.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-enum-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-irrefutable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-matches-feature-gated.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-patterns.rs create mode 100644 gcc/testsuite/rust/rustc/ui/uninit-empty-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/auxiliary/union.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/issue-41073.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-align.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-backcomp.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-basic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-borrow-move-parent-sibling.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-const-codegen.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-const-eval-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-const-eval.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-const-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-custom-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-derive-clone.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-derive-eq.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-derive-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-derive.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-drop-assign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-empty.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-fields-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-fields-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-generic-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-inherent-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-lint-dead-code.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-manuallydrop-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-nodrop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-nonrepresentable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-nonzero.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-overwrite.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-packed.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-pat-refutability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-repr-c.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-sized-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-suggest-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-transmute.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-unsafe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-unsized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/union/union-with-drop-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique-object-noncopyable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique-pinned-nocopy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-assign-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-assign-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-assign-generic.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-assign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-autoderef-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-autoderef-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-cmp.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-containing-tag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-create.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-decl-init-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-decl-init.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-decl-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-decl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-deref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-destructure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-drop-complex.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-ffi-symbols.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-fn-arg-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-fn-arg-mut.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-fn-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-fn-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-generic-assign.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-in-tag.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-in-vec-copy.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-in-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-init.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-kinds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-log.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-match-discrim.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-move-drop.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-move-temp.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-mutable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-object-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-pat-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-pat-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-pat.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-rec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-send-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-send.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unique/unique-swap.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unknown-language-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unknown-lint-tool-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unknown-llvm-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unknown-tool-name.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unnamed_argument_mode.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unnecessary-extern-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unop-move-semantics.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unop-neg-bool.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unreachable-code-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unreachable-code-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unreachable-code.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unresolved/unresolved-extern-mod-suggestion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unresolved/unresolved-import-recovery.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unresolved/unresolved-import.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unrestricted-attribute-tokens.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe-coercion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe-fn-called-from-unsafe-blk.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe-fn-called-from-unsafe-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe-pointer-assignability.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints2_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints3_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints4_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints_const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints_macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/unsafe-around-compiler-generated-unsafe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/unsafe-block-without-braces.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/unsafe-const-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-assign-deref-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-autoderef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-called-from-safe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-deref-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-used-as-value.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/unsafe-move-val-init.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/unsafe-subtyping.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/unsafe-trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsafe/unsafe-unstable-const-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsigned-literal-negation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/autoderef.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/auxiliary/ufuncs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/borrow-after-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/box-fnonce.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/by-value-trait-object-safety-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/by-value-trait-object-safety.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/double-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/issue-30276-feature-flagged.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/issue-30276.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/issue-50940-with-feature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/issue-50940.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/reference-unsized-locals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/simple-unsized-locals.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-index.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-locals-using-unsized-fn-params.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-parameters.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized-tuple-impls.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized/issue-71659.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized/issue-75707.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized/return-unsized-from-trait-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized/unsized-bare-typaram.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized/unsized-enum.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized/unsized-enum2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized/unsized-fn-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized/unsized-inherent-impl-self-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized/unsized-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized/unsized-trait-impl-self-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized/unsized-trait-impl-trait-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized3-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsized7.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unspecified-self-in-trait-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unsupported-cast.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unterminated-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unterminated-doc-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-crate-deps/auxiliary/bar.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-crate-deps/auxiliary/foo.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-crate-deps/ignore-pathless-extern.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-crate-deps/libfib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-crate-deps/lint-group.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-crate-deps/suppress.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-crate-deps/test-use-ok.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-crate-deps/unused-aliases.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-crate-deps/use_extern_crate_2015.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-crate-deps/warn-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-crate-deps/warn-cmdline-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-crate-deps/warn-cmdline.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-move-capture.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused-move.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused/unused-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused/unused-closure.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused/unused-macro-rules.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused/unused-macro-with-bad-frag-spec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused/unused-macro-with-follow-violation.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused/unused-macro.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused/unused-mut-warning-captured-var.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unused/unused-result.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unwind-resource.rs create mode 100644 gcc/testsuite/rust/rustc/ui/unwind-unique.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use-crate-name-alias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use-import-export.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use-keyword-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use-module-level-int-consts.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use-nested-groups.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use-self-in-inner-fn.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/auxiliary/extern-use-primitive-type-lib.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/auxiliary/use-from-trait-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/issue-18986.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/issue-60976-extern-use-primitive-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-after-move-based-on-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-after-move-implicity-coerced-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-after-move-self-based-on-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-after-move-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-associated-const.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-from-trait-xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-from-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-keyword.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-meta-mismatch.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-mod.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-3.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-4.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-5.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-6.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-nested-groups-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-nested-groups-unused-imports.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-paths-as-items.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-self-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use/use-super-global-path.rs create mode 100644 gcc/testsuite/rust/rustc/ui/use_inline_dtor.rs create mode 100644 gcc/testsuite/rust/rustc/ui/used.rs create mode 100644 gcc/testsuite/rust/rustc/ui/useless-comment.rs create mode 100644 gcc/testsuite/rust/rustc/ui/useless-pub.rs create mode 100644 gcc/testsuite/rust/rustc/ui/user-defined-macro-rules.rs create mode 100644 gcc/testsuite/rust/rustc/ui/using-target-feature-unstable.rs create mode 100644 gcc/testsuite/rust/rustc/ui/usize-generic-argument-parent.rs create mode 100644 gcc/testsuite/rust/rustc/ui/utf8-bom.rs create mode 100644 gcc/testsuite/rust/rustc/ui/utf8.rs create mode 100644 gcc/testsuite/rust/rustc/ui/utf8_chars.rs create mode 100644 gcc/testsuite/rust/rustc/ui/utf8_idents-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/utf8_idents.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance-intersection-of-ref-and-opt-ref.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance-iterators-in-libcore.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-associated-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-associated-types2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-btree-invariant-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-cell-is-invariant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-contravariant-arg-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-contravariant-arg-trait-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-contravariant-self-trait-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-covariant-arg-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-covariant-arg-trait-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-covariant-self-trait-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-invariant-arg-object.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-invariant-arg-trait-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-invariant-self-trait-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-issue-20533.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-object-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-regions-direct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-regions-indirect.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-regions-unused-direct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-regions-unused-indirect.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-trait-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-trait-matching.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-trait-object-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-types-bounds.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-types.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-unused-region-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-unused-type-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-use-contravariant-struct-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-use-contravariant-struct-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-use-covariant-struct-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-use-covariant-struct-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variance/variance-use-invariant-struct-1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variants/auxiliary/variant-namespacing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variants/variant-namespacing.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variants/variant-size-differences.rs create mode 100644 gcc/testsuite/rust/rustc/ui/variants/variant-used-as-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/vec/vec-macro-with-comma-only.rs create mode 100644 gcc/testsuite/rust/rustc/ui/vec/vec-mut-iter-borrow.rs create mode 100644 gcc/testsuite/rust/rustc/ui/vec/vec-overrun.rs create mode 100644 gcc/testsuite/rust/rustc/ui/vec/vec-res-add.rs create mode 100644 gcc/testsuite/rust/rustc/ui/vector-cast-weirdness.rs create mode 100644 gcc/testsuite/rust/rustc/ui/vector-no-ann.rs create mode 100644 gcc/testsuite/rust/rustc/ui/volatile-fat-ptr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/vtable-res-trait-param.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wait-forked-but-failed-child.rs create mode 100644 gcc/testsuite/rust/rustc/ui/walk-struct-literal-with.rs create mode 100644 gcc/testsuite/rust/rustc/ui/warn-ctypes-inhibit.rs create mode 100644 gcc/testsuite/rust/rustc/ui/warn-path-statement.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wasm-custom-section-relocations.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wasm-import-module.rs create mode 100644 gcc/testsuite/rust/rustc/ui/weak-lang-item.rs create mode 100644 gcc/testsuite/rust/rustc/ui/weak-new-uninhabited-issue-48493.rs create mode 100644 gcc/testsuite/rust/rustc/ui/weird-exit-code.rs create mode 100644 gcc/testsuite/rust/rustc/ui/weird-exprs.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf-bound-region-in-object-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/issue-48638.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-array-elem-sized.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-const-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-convert-unsafe-trait-obj-box.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-convert-unsafe-trait-obj.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-enum-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-enum-fields-struct-variant.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-enum-fields.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-fn-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-foreign-fn-decl-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-impl-associated-type-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-impl-associated-type-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-impl-self-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-type-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-type-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-type-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-in-obj-type-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-in-obj-type-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-inherent-impl-method-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-inherent-impl-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-misc-methods-issue-28609.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-object-safe.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-outlives-ty-in-fn-or-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-static-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-static-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-struct-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-struct-field.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-trait-associated-type-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-trait-associated-type-region.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-trait-associated-type-trait.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-trait-bound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-trait-default-fn-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-trait-default-fn-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-trait-default-fn-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-trait-fn-arg.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-trait-fn-ret.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-trait-fn-where-clause.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-trait-superbound.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wf/wf-unsafe-trait-obj-match.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/auxiliary/where_clauses_xc.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-bounds-inconsistency.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-early-bound-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-method-substituion-rpass.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-method-substituion.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-region-outlives.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-cross-crate.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-lifetimes.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-method-unsatisfied.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-unboxed-closures.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-unsatisfied.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-equality-constraints.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-for-self-2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-for-self.rs create mode 100644 gcc/testsuite/rust/rustc/ui/where-clauses/where-lifetime-resolution.rs create mode 100644 gcc/testsuite/rust/rustc/ui/while-let.rs create mode 100644 gcc/testsuite/rust/rustc/ui/while-type-error.rs create mode 100644 gcc/testsuite/rust/rustc/ui/windows-subsystem-invalid.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wrapping-int-api.rs create mode 100644 gcc/testsuite/rust/rustc/ui/write-fmt-errors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/write-to-static-mut-in-static.rs create mode 100644 gcc/testsuite/rust/rustc/ui/writealias.rs create mode 100644 gcc/testsuite/rust/rustc/ui/writing-to-immutable-vec.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wrong-hashset-issue-42918.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wrong-mul-method-signature.rs create mode 100644 gcc/testsuite/rust/rustc/ui/wrong-ret-type.rs create mode 100644 gcc/testsuite/rust/rustc/ui/x86stdcall.rs create mode 100644 gcc/testsuite/rust/rustc/ui/x86stdcall2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/xc-private-method.rs create mode 100644 gcc/testsuite/rust/rustc/ui/xc-private-method2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/xcrate/auxiliary/static_priv_by_default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/xcrate/auxiliary/xcrate_unit_struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/xcrate/xcrate-private-by-default.rs create mode 100644 gcc/testsuite/rust/rustc/ui/xcrate/xcrate-unit-struct.rs create mode 100644 gcc/testsuite/rust/rustc/ui/yield.rs create mode 100644 gcc/testsuite/rust/rustc/ui/yield1.rs create mode 100644 gcc/testsuite/rust/rustc/ui/yield2.rs create mode 100644 gcc/testsuite/rust/rustc/ui/z-crate-attr.rs create mode 100644 gcc/testsuite/rust/rustc/ui/zero-sized/zero-size-type-destructors.rs create mode 100644 gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-binary-heap-push.rs create mode 100644 gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-btreemap-insert.rs create mode 100644 gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-linkedlist-push.rs create mode 100644 gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-tuple-struct.rs diff --git a/gcc/testsuite/rust/rustc/ui/abi/abi-sysv64-arg-passing.rs b/gcc/testsuite/rust/rustc/ui/abi/abi-sysv64-arg-passing.rs new file mode 100644 index 000000000000..00cba8f31606 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/abi-sysv64-arg-passing.rs @@ -0,0 +1,449 @@ +// run-pass +// Checks if the "sysv64" calling convention behaves the same as the +// "C" calling convention on platforms where both should be the same + +// This file contains versions of the following run-pass tests with +// the calling convention changed to "sysv64" + +// cabi-int-widening +// extern-pass-char +// extern-pass-u32 +// extern-pass-u64 +// extern-pass-double +// extern-pass-empty +// extern-pass-TwoU8s +// extern-pass-TwoU16s +// extern-pass-TwoU32s +// extern-pass-TwoU64s +// extern-return-TwoU8s +// extern-return-TwoU16s +// extern-return-TwoU32s +// extern-return-TwoU64s +// foreign-fn-with-byval +// issue-28676 +// issue-62350-sysv-neg-reg-counts +// struct-return + +// ignore-android +// ignore-arm +// ignore-aarch64 +// ignore-windows + +// note: windows is ignored as rust_test_helpers does not have the sysv64 abi on windows + +#[allow(dead_code)] +#[allow(improper_ctypes)] + +#[cfg(target_arch = "x86_64")] +mod tests { + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct TwoU8s { + one: u8, two: u8 + } + + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct TwoU16s { + one: u16, two: u16 + } + + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct TwoU32s { + one: u32, two: u32 + } + + #[repr(C)] + #[derive(Copy, Clone, PartialEq, Debug)] + pub struct TwoU64s { + one: u64, two: u64 + } + + #[repr(C)] + pub struct ManyInts { + arg1: i8, + arg2: i16, + arg3: i32, + arg4: i16, + arg5: i8, + arg6: TwoU8s, + } + + #[repr(C)] + pub struct Empty; + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct S { + x: u64, + y: u64, + z: u64, + } + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct Quad { a: u64, b: u64, c: u64, d: u64 } + + #[derive(Copy, Clone)] + pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 } + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct Floats { a: f64, b: u8, c: f64 } + + #[repr(C, u8)] + pub enum U8TaggedEnumOptionU64U64 { + None, + Some(u64,u64), + } + + #[repr(C, u8)] + pub enum U8TaggedEnumOptionU64 { + None, + Some(u64), + } + + #[link(name = "rust_test_helpers", kind = "static")] + extern "sysv64" { + pub fn rust_int8_to_int32(_: i8) -> i32; + pub fn rust_dbg_extern_identity_u8(v: u8) -> u8; + pub fn rust_dbg_extern_identity_u32(v: u32) -> u32; + pub fn rust_dbg_extern_identity_u64(v: u64) -> u64; + pub fn rust_dbg_extern_identity_double(v: f64) -> f64; + pub fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts); + pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s; + pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s; + pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s; + pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s; + pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s; + pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s; + pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s; + pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s; + pub fn get_x(x: S) -> u64; + pub fn get_y(x: S) -> u64; + pub fn get_z(x: S) -> u64; + pub fn get_c_many_params(_: *const (), _: *const (), + _: *const (), _: *const (), f: Quad) -> u64; + pub fn get_c_exhaust_sysv64_ints( + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + h: QuadFloats, + ) -> f32; + pub fn rust_dbg_abi_1(q: Quad) -> Quad; + pub fn rust_dbg_abi_2(f: Floats) -> Floats; + pub fn rust_dbg_new_some_u64u64(a: u64, b: u64) -> U8TaggedEnumOptionU64U64; + pub fn rust_dbg_new_none_u64u64() -> U8TaggedEnumOptionU64U64; + pub fn rust_dbg_unpack_option_u64u64( + o: U8TaggedEnumOptionU64U64, + a: *mut u64, + b: *mut u64, + ) -> i32; + pub fn rust_dbg_new_some_u64(some: u64) -> U8TaggedEnumOptionU64; + pub fn rust_dbg_new_none_u64() -> U8TaggedEnumOptionU64; + pub fn rust_dbg_unpack_option_u64(o: U8TaggedEnumOptionU64, v: *mut u64) -> i32; + } + + pub fn cabi_int_widening() { + let x = unsafe { + rust_int8_to_int32(-1) + }; + + assert!(x == -1); + } + + pub fn extern_pass_char() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u8(22)); + } + } + + pub fn extern_pass_u32() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u32(22)); + } + } + + pub fn extern_pass_u64() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u64(22)); + } + } + + pub fn extern_pass_double() { + unsafe { + assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64)); + } + } + + pub fn extern_pass_empty() { + unsafe { + let x = ManyInts { + arg1: 2, + arg2: 3, + arg3: 4, + arg4: 5, + arg5: 6, + arg6: TwoU8s { one: 7, two: 8, } + }; + let y = ManyInts { + arg1: 1, + arg2: 2, + arg3: 3, + arg4: 4, + arg5: 5, + arg6: TwoU8s { one: 6, two: 7, } + }; + let empty = Empty; + rust_dbg_extern_empty_struct(x, empty, y); + } + } + + pub fn extern_pass_twou8s() { + unsafe { + let x = TwoU8s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU8s(x); + assert_eq!(x, y); + } + } + + pub fn extern_pass_twou16s() { + unsafe { + let x = TwoU16s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU16s(x); + assert_eq!(x, y); + } + } + + pub fn extern_pass_twou32s() { + unsafe { + let x = TwoU32s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU32s(x); + assert_eq!(x, y); + } + } + + pub fn extern_pass_twou64s() { + unsafe { + let x = TwoU64s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU64s(x); + assert_eq!(x, y); + } + } + + pub fn extern_return_twou8s() { + unsafe { + let y = rust_dbg_extern_return_TwoU8s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } + } + + pub fn extern_return_twou16s() { + unsafe { + let y = rust_dbg_extern_return_TwoU16s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } + } + + pub fn extern_return_twou32s() { + unsafe { + let y = rust_dbg_extern_return_TwoU32s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } + } + + pub fn extern_return_twou64s() { + unsafe { + let y = rust_dbg_extern_return_TwoU64s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } + } + + #[inline(never)] + fn indirect_call(func: unsafe extern "sysv64" fn(s: S) -> u64, s: S) -> u64 { + unsafe { + func(s) + } + } + + pub fn foreign_fn_with_byval() { + let s = S { x: 1, y: 2, z: 3 }; + assert_eq!(s.x, indirect_call(get_x, s)); + assert_eq!(s.y, indirect_call(get_y, s)); + assert_eq!(s.z, indirect_call(get_z, s)); + } + + fn test() { + use std::ptr; + unsafe { + let null = ptr::null(); + let q = Quad { + a: 1, + b: 2, + c: 3, + d: 4 + }; + assert_eq!(get_c_many_params(null, null, null, null, q), q.c); + } + } + + pub fn issue_28676() { + test(); + } + + fn test_62350() { + use std::ptr; + unsafe { + let null = ptr::null(); + let q = QuadFloats { + a: 10.2, + b: 20.3, + c: 30.4, + d: 40.5 + }; + assert_eq!( + get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q), + q.c, + ); + } + } + + pub fn issue_62350() { + test_62350(); + } + + fn test1() { + unsafe { + let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa, + b: 0xbbbb_bbbb_bbbb_bbbb, + c: 0xcccc_cccc_cccc_cccc, + d: 0xdddd_dddd_dddd_dddd }; + let qq = rust_dbg_abi_1(q); + println!("a: {:x}", qq.a as usize); + println!("b: {:x}", qq.b as usize); + println!("c: {:x}", qq.c as usize); + println!("d: {:x}", qq.d as usize); + assert_eq!(qq.a, q.c + 1); + assert_eq!(qq.b, q.d - 1); + assert_eq!(qq.c, q.a + 1); + assert_eq!(qq.d, q.b - 1); + } + } + + fn test2() { + unsafe { + let f = Floats { a: 1.234567890e-15_f64, + b: 0b_1010_1010, + c: 1.0987654321e-15_f64 }; + let ff = rust_dbg_abi_2(f); + println!("a: {}", ff.a as f64); + println!("b: {}", ff.b as usize); + println!("c: {}", ff.c as f64); + assert_eq!(ff.a, f.c + 1.0f64); + assert_eq!(ff.b, 0xff); + assert_eq!(ff.c, f.a - 1.0f64); + } + } + + pub fn struct_return() { + test1(); + test2(); + } + + pub fn enum_passing_and_return_pair() { + let some_u64u64 = unsafe { rust_dbg_new_some_u64u64(10, 20) }; + if let U8TaggedEnumOptionU64U64::Some(a, b) = some_u64u64 { + assert_eq!(10, a); + assert_eq!(20, b); + } else { + panic!("unexpected none"); + } + + let none_u64u64 = unsafe { rust_dbg_new_none_u64u64() }; + if let U8TaggedEnumOptionU64U64::Some(_,_) = none_u64u64 { + panic!("unexpected some"); + } + + let mut a: u64 = 0; + let mut b: u64 = 0; + let r = unsafe { + rust_dbg_unpack_option_u64u64(some_u64u64, &mut a as *mut _, &mut b as *mut _) + }; + assert_eq!(1, r); + assert_eq!(10, a); + assert_eq!(20, b); + + let mut a: u64 = 0; + let mut b: u64 = 0; + let r = unsafe { + rust_dbg_unpack_option_u64u64(none_u64u64, &mut a as *mut _, &mut b as *mut _) + }; + assert_eq!(0, r); + assert_eq!(0, a); + assert_eq!(0, b); + } + + pub fn enum_passing_and_return() { + let some_u64 = unsafe { rust_dbg_new_some_u64(10) }; + if let U8TaggedEnumOptionU64::Some(v) = some_u64 { + assert_eq!(10, v); + } else { + panic!("unexpected none"); + } + + let none_u64 = unsafe { rust_dbg_new_none_u64() }; + if let U8TaggedEnumOptionU64::Some(_) = none_u64 { + panic!("unexpected some"); + } + + let mut target: u64 = 0; + let r = unsafe { rust_dbg_unpack_option_u64(some_u64, &mut target as *mut _) }; + assert_eq!(1, r); + assert_eq!(10, target); + + let mut target: u64 = 0; + let r = unsafe { rust_dbg_unpack_option_u64(none_u64, &mut target as *mut _) }; + assert_eq!(0, r); + assert_eq!(0, target); + } +} + +#[cfg(target_arch = "x86_64")] +fn main() { + use tests::*; + cabi_int_widening(); + extern_pass_char(); + extern_pass_u32(); + extern_pass_u64(); + extern_pass_double(); + extern_pass_empty(); + extern_pass_twou8s(); + extern_pass_twou16s(); + extern_pass_twou32s(); + extern_pass_twou64s(); + extern_return_twou8s(); + extern_return_twou16s(); + extern_return_twou32s(); + extern_return_twou64s(); + foreign_fn_with_byval(); + issue_28676(); + issue_62350(); + struct_return(); + enum_passing_and_return_pair(); + enum_passing_and_return(); +} + +#[cfg(not(target_arch = "x86_64"))] +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/abi-sysv64-register-usage.rs b/gcc/testsuite/rust/rustc/ui/abi/abi-sysv64-register-usage.rs new file mode 100644 index 000000000000..235b952387a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/abi-sysv64-register-usage.rs @@ -0,0 +1,98 @@ +// run-pass +// Checks if the correct registers are being used to pass arguments +// when the sysv64 ABI is specified. + +// ignore-android +// ignore-arm +// ignore-aarch64 + +#![feature(llvm_asm)] + +#[cfg(target_arch = "x86_64")] +pub extern "sysv64" fn all_the_registers(rdi: i64, rsi: i64, rdx: i64, + rcx: i64, r8 : i64, r9 : i64, + xmm0: f32, xmm1: f32, xmm2: f32, + xmm3: f32, xmm4: f32, xmm5: f32, + xmm6: f32, xmm7: f32) -> i64 { + assert_eq!(rdi, 1); + assert_eq!(rsi, 2); + assert_eq!(rdx, 3); + assert_eq!(rcx, 4); + assert_eq!(r8, 5); + assert_eq!(r9, 6); + assert_eq!(xmm0, 1.0f32); + assert_eq!(xmm1, 2.0f32); + assert_eq!(xmm2, 4.0f32); + assert_eq!(xmm3, 8.0f32); + assert_eq!(xmm4, 16.0f32); + assert_eq!(xmm5, 32.0f32); + assert_eq!(xmm6, 64.0f32); + assert_eq!(xmm7, 128.0f32); + 42 +} + +// this struct contains 8 i64's, while only 6 can be passed in registers. +#[cfg(target_arch = "x86_64")] +#[derive(PartialEq, Eq, Debug)] +pub struct LargeStruct(i64, i64, i64, i64, i64, i64, i64, i64); + +#[cfg(target_arch = "x86_64")] +#[inline(never)] +#[allow(improper_ctypes_definitions)] +pub extern "sysv64" fn large_struct_by_val(mut foo: LargeStruct) -> LargeStruct { + foo.0 *= 1; + foo.1 *= 2; + foo.2 *= 3; + foo.3 *= 4; + foo.4 *= 5; + foo.5 *= 6; + foo.6 *= 7; + foo.7 *= 8; + foo +} + +#[cfg(target_arch = "x86_64")] +pub fn main() { + let result: i64; + unsafe { + llvm_asm!("mov rdi, 1; + mov rsi, 2; + mov rdx, 3; + mov rcx, 4; + mov r8, 5; + mov r9, 6; + mov eax, 0x3F800000; + movd xmm0, eax; + mov eax, 0x40000000; + movd xmm1, eax; + mov eax, 0x40800000; + movd xmm2, eax; + mov eax, 0x41000000; + movd xmm3, eax; + mov eax, 0x41800000; + movd xmm4, eax; + mov eax, 0x42000000; + movd xmm5, eax; + mov eax, 0x42800000; + movd xmm6, eax; + mov eax, 0x43000000; + movd xmm7, eax; + call r10 + " + : "={rax}"(result) + : "{r10}"(all_the_registers as usize) + : "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11", "cc", "memory" + : "intel", "alignstack" + ) + } + assert_eq!(result, 42); + + assert_eq!( + large_struct_by_val(LargeStruct(1, 2, 3, 4, 5, 6, 7, 8)), + LargeStruct(1, 4, 9, 16, 25, 36, 49, 64) + ); +} + +#[cfg(not(target_arch = "x86_64"))] +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/anon-extern-mod.rs b/gcc/testsuite/rust/rustc/ui/abi/anon-extern-mod.rs new file mode 100644 index 000000000000..72097af9ac9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/anon-extern-mod.rs @@ -0,0 +1,19 @@ +// run-pass +// pretty-expanded FIXME #23616 +// ignore-wasm32-bare no libc to test ffi with + +#![feature(rustc_private)] + +extern crate libc; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_get_test_int() -> libc::intptr_t; +} + +pub fn main() { + unsafe { + let _ = rust_get_test_int(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/auxiliary/anon-extern-mod-cross-crate-1.rs b/gcc/testsuite/rust/rustc/ui/abi/auxiliary/anon-extern-mod-cross-crate-1.rs new file mode 100644 index 000000000000..efd5f0e7879f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/auxiliary/anon-extern-mod-cross-crate-1.rs @@ -0,0 +1,10 @@ +#![crate_name="anonexternmod"] +#![feature(rustc_private)] + +extern crate libc; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_get_test_int() -> libc::intptr_t; +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/auxiliary/foreign_lib.rs b/gcc/testsuite/rust/rustc/ui/abi/auxiliary/foreign_lib.rs new file mode 100644 index 000000000000..a0a25db14daf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/auxiliary/foreign_lib.rs @@ -0,0 +1,39 @@ +#![crate_name="foreign_lib"] + +#![feature(rustc_private)] + +pub mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub mod rustrt2 { + extern crate libc; + + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub mod rustrt3 { + // Different type, but same ABI (on all supported platforms). + // Ensures that we don't ICE or trigger LLVM asserts when + // importing the same symbol under different types. + // See https://github.com/rust-lang/rust/issues/32740. + extern { + pub fn rust_get_test_int() -> *const u8; + } +} + +pub fn local_uses() { + unsafe { + let x = rustrt::rust_get_test_int(); + assert_eq!(x, rustrt2::rust_get_test_int()); + assert_eq!(x as *const _, rustrt3::rust_get_test_int()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/c-stack-as-value.rs b/gcc/testsuite/rust/rustc/ui/abi/c-stack-as-value.rs new file mode 100644 index 000000000000..32d6335bd284 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/c-stack-as-value.rs @@ -0,0 +1,19 @@ +// run-pass +// pretty-expanded FIXME #23616 +// ignore-wasm32-bare no libc to test ffi with + +#![feature(rustc_private)] + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub fn main() { + let _foo = rustrt::rust_get_test_int; +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/cabi-int-widening.rs b/gcc/testsuite/rust/rustc/ui/abi/cabi-int-widening.rs new file mode 100644 index 000000000000..02b8ec057941 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/cabi-int-widening.rs @@ -0,0 +1,16 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_int8_to_int32(_: i8) -> i32; +} + +fn main() { + let x = unsafe { + rust_int8_to_int32(-1) + }; + + assert!(x == -1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs b/gcc/testsuite/rust/rustc/ui/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs new file mode 100644 index 000000000000..efd5f0e7879f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs @@ -0,0 +1,10 @@ +#![crate_name="anonexternmod"] +#![feature(rustc_private)] + +extern crate libc; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_get_test_int() -> libc::intptr_t; +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs b/gcc/testsuite/rust/rustc/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs new file mode 100644 index 000000000000..ab6954b6d193 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:anon-extern-mod-cross-crate-1.rs +// pretty-expanded FIXME #23616 +// ignore-wasm32-bare no libc to test ffi with + +extern crate anonexternmod; + +use anonexternmod::rust_get_test_int; + +pub fn main() { + unsafe { + rust_get_test_int(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/gcc/testsuite/rust/rustc/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs new file mode 100644 index 000000000000..efd5f0e7879f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs @@ -0,0 +1,10 @@ +#![crate_name="anonexternmod"] +#![feature(rustc_private)] + +extern crate libc; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_get_test_int() -> libc::intptr_t; +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/duplicated-external-mods.rs b/gcc/testsuite/rust/rustc/ui/abi/duplicated-external-mods.rs new file mode 100644 index 000000000000..00308bc8ef33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/duplicated-external-mods.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:anon-extern-mod-cross-crate-1.rs +// aux-build:anon-extern-mod-cross-crate-1.rs +// pretty-expanded FIXME #23616 +// ignore-wasm32-bare no libc to test ffi with + +extern crate anonexternmod; + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/auxiliary/extern-crosscrate-source.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/auxiliary/extern-crosscrate-source.rs new file mode 100644 index 000000000000..4594e26edec6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/auxiliary/extern-crosscrate-source.rs @@ -0,0 +1,32 @@ +#![crate_name="externcallback"] +#![crate_type = "lib"] +#![feature(rustc_private)] + +extern crate libc; + +pub mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; + } +} + +pub fn fact(n: libc::uintptr_t) -> libc::uintptr_t { + unsafe { + println!("n = {}", n); + rustrt::rust_dbg_call(cb, n) + } +} + +pub extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { + if data == 1 { + data + } else { + fact(data - 1) * data + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-deep.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-deep.rs new file mode 100644 index 000000000000..5375c4f9eec5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-deep.rs @@ -0,0 +1,40 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with +// ignore-emscripten blows the JS stack + +#![feature(rustc_private)] + +extern crate libc; + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; + } +} + +extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { + if data == 1 { + data + } else { + count(data - 1) + 1 + } +} + +fn count(n: libc::uintptr_t) -> libc::uintptr_t { + unsafe { + println!("n = {}", n); + rustrt::rust_dbg_call(cb, n) + } +} + +pub fn main() { + let result = count(1000); + println!("result = {}", result); + assert_eq!(result, 1000); +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-deep2.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-deep2.rs new file mode 100644 index 000000000000..4f8c38ab3ce9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-deep2.rs @@ -0,0 +1,45 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +#![feature(rustc_private)] + +extern crate libc; +use std::thread; + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; + } +} + +extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { + if data == 1 { + data + } else { + count(data - 1) + 1 + } +} + +fn count(n: libc::uintptr_t) -> libc::uintptr_t { + unsafe { + println!("n = {}", n); + rustrt::rust_dbg_call(cb, n) + } +} + +pub fn main() { + // Make sure we're on a thread with small Rust stacks (main currently + // has a large stack) + thread::spawn(move|| { + let result = count(1000); + println!("result = {}", result); + assert_eq!(result, 1000); + }).join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-direct.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-direct.rs new file mode 100644 index 000000000000..22bbbbaba529 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-direct.rs @@ -0,0 +1,11 @@ +// run-pass +// Test direct calls to extern fns. + + +extern fn f(x: usize) -> usize { x * 2 } + +pub fn main() { + let x = f(22); + assert_eq!(x, 44); +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-indirect.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-indirect.rs new file mode 100644 index 000000000000..6ce21aafde37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-indirect.rs @@ -0,0 +1,39 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with + +#![feature(rustc_private)] + +extern crate libc; + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; + } +} + +extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { + if data == 1 { + data + } else { + fact(data - 1) * data + } +} + +fn fact(n: libc::uintptr_t) -> libc::uintptr_t { + unsafe { + println!("n = {}", n); + rustrt::rust_dbg_call(cb, n) + } +} + +pub fn main() { + let result = fact(10); + println!("result = {}", result); + assert_eq!(result, 3628800); +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-scrub.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-scrub.rs new file mode 100644 index 000000000000..f3884e549eca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-call-scrub.rs @@ -0,0 +1,49 @@ +// run-pass +#![allow(unused_must_use)] +// This time we're testing repeatedly going up and down both stacks to +// make sure the stack pointers are maintained properly in both +// directions + +// ignore-emscripten no threads support + +#![feature(rustc_private)] + +extern crate libc; +use std::thread; + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, + data: libc::uintptr_t) + -> libc::uintptr_t; + } +} + +extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t { + if data == 1 { + data + } else { + count(data - 1) + count(data - 1) + } +} + +fn count(n: libc::uintptr_t) -> libc::uintptr_t { + unsafe { + println!("n = {}", n); + rustrt::rust_dbg_call(cb, n) + } +} + +pub fn main() { + // Make sure we're on a thread with small Rust stacks (main currently + // has a large stack) + thread::spawn(move|| { + let result = count(12); + println!("result = {}", result); + assert_eq!(result, 2048); + }).join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-crosscrate.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-crosscrate.rs new file mode 100644 index 000000000000..e7784f5336bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-crosscrate.rs @@ -0,0 +1,22 @@ +// run-pass +// aux-build:extern-crosscrate-source.rs +// ignore-wasm32-bare no libc to test ffi with + +#![feature(rustc_private)] + +extern crate externcallback; +extern crate libc; + +fn fact(n: libc::uintptr_t) -> libc::uintptr_t { + unsafe { + println!("n = {}", n); + externcallback::rustrt::rust_dbg_call(externcallback::cb, n) + } +} + +pub fn main() { + let result = fact(10); + println!("result = {}", result); + assert_eq!(result, 3628800); +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU16s.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU16s.rs new file mode 100644 index 000000000000..54049e6ba0f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU16s.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc for ffi testing + +// Test a foreign function that accepts and returns a struct +// by value. + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct TwoU16s { + one: u16, two: u16 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s; +} + +pub fn main() { + unsafe { + let x = TwoU16s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU16s(x); + assert_eq!(x, y); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU32s.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU32s.rs new file mode 100644 index 000000000000..54e8a668760c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU32s.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc for ffi testing + +// Test a foreign function that accepts and returns a struct +// by value. + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct TwoU32s { + one: u32, two: u32 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s; +} + +pub fn main() { + unsafe { + let x = TwoU32s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU32s(x); + assert_eq!(x, y); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU64s.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU64s.rs new file mode 100644 index 000000000000..1b50326df676 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU64s.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc for ffi testing + +// Test a foreign function that accepts and returns a struct +// by value. + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct TwoU64s { + one: u64, two: u64 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s; +} + +pub fn main() { + unsafe { + let x = TwoU64s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU64s(x); + assert_eq!(x, y); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU8s.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU8s.rs new file mode 100644 index 000000000000..ee5449d7757b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-TwoU8s.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc for ffi testing + +// Test a foreign function that accepts and returns a struct +// by value. + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct TwoU8s { + one: u8, two: u8 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s; +} + +pub fn main() { + unsafe { + let x = TwoU8s {one: 22, two: 23}; + let y = rust_dbg_extern_identity_TwoU8s(x); + assert_eq!(x, y); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-char.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-char.rs new file mode 100644 index 000000000000..ff84ce294797 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-char.rs @@ -0,0 +1,17 @@ +// run-pass +// ignore-wasm32-bare no libc for ffi testing + +// Test a function that takes/returns a u8. + + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_u8(v: u8) -> u8; +} + +pub fn main() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u8(22)); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-double.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-double.rs new file mode 100644 index 000000000000..01575ee081c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-double.rs @@ -0,0 +1,14 @@ +// run-pass +// ignore-wasm32-bare no libc for ffi testing + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_double(v: f64) -> f64; +} + +pub fn main() { + unsafe { + assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64)); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-empty.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-empty.rs new file mode 100644 index 000000000000..f88e0d758e95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-empty.rs @@ -0,0 +1,56 @@ +// run-pass +#![allow(improper_ctypes)] // FIXME: this test is inherently not FFI-safe. + +// Test a foreign function that accepts empty struct. + +// pretty-expanded FIXME #23616 +// ignore-msvc +// ignore-emscripten emcc asserts on an empty struct as an argument + +#[repr(C)] +struct TwoU8s { + one: u8, + two: u8, +} + +#[repr(C)] +struct ManyInts { + arg1: i8, + arg2: i16, + arg3: i32, + arg4: i16, + arg5: i8, + arg6: TwoU8s, +} + +#[repr(C)] +struct Empty; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts); +} + +pub fn main() { + unsafe { + let x = ManyInts { + arg1: 2, + arg2: 3, + arg3: 4, + arg4: 5, + arg5: 6, + arg6: TwoU8s { one: 7, two: 8, } + }; + let y = ManyInts { + arg1: 1, + arg2: 2, + arg3: 3, + arg4: 4, + arg5: 5, + arg6: TwoU8s { one: 6, two: 7, } + }; + let empty = Empty; + rust_dbg_extern_empty_struct(x, empty, y); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-u32.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-u32.rs new file mode 100644 index 000000000000..22d85c13029e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-u32.rs @@ -0,0 +1,17 @@ +// run-pass +// ignore-wasm32-bare no libc for ffi testing + +// Test a function that takes/returns a u32. + + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_u32(v: u32) -> u32; +} + +pub fn main() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u32(22)); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-u64.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-u64.rs new file mode 100644 index 000000000000..19c093d13f8a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-pass-u64.rs @@ -0,0 +1,17 @@ +// run-pass +// ignore-wasm32-bare no libc for ffi testing + +// Test a call to a function that takes/returns a u64. + + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_u64(v: u64) -> u64; +} + +pub fn main() { + unsafe { + assert_eq!(22, rust_dbg_extern_identity_u64(22)); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU16s.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU16s.rs new file mode 100644 index 000000000000..e807a893b98a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU16s.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +pub struct TwoU16s { + one: u16, two: u16 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s; +} + +pub fn main() { + unsafe { + let y = rust_dbg_extern_return_TwoU16s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU32s.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU32s.rs new file mode 100644 index 000000000000..1e4bc375b4f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU32s.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +pub struct TwoU32s { + one: u32, two: u32 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s; +} + +pub fn main() { + unsafe { + let y = rust_dbg_extern_return_TwoU32s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU64s.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU64s.rs new file mode 100644 index 000000000000..6433b92a4814 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU64s.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +pub struct TwoU64s { + one: u64, two: u64 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s; +} + +pub fn main() { + unsafe { + let y = rust_dbg_extern_return_TwoU64s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU8s.rs b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU8s.rs new file mode 100644 index 000000000000..a43fe419a82b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/extern/extern-return-TwoU8s.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +pub struct TwoU8s { + one: u8, two: u8 +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s; +} + +pub fn main() { + unsafe { + let y = rust_dbg_extern_return_TwoU8s(); + assert_eq!(y.one, 10); + assert_eq!(y.two, 20); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/foreign/auxiliary/foreign_lib.rs b/gcc/testsuite/rust/rustc/ui/abi/foreign/auxiliary/foreign_lib.rs new file mode 100644 index 000000000000..a0a25db14daf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/foreign/auxiliary/foreign_lib.rs @@ -0,0 +1,39 @@ +#![crate_name="foreign_lib"] + +#![feature(rustc_private)] + +pub mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub mod rustrt2 { + extern crate libc; + + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub mod rustrt3 { + // Different type, but same ABI (on all supported platforms). + // Ensures that we don't ICE or trigger LLVM asserts when + // importing the same symbol under different types. + // See https://github.com/rust-lang/rust/issues/32740. + extern { + pub fn rust_get_test_int() -> *const u8; + } +} + +pub fn local_uses() { + unsafe { + let x = rustrt::rust_get_test_int(); + assert_eq!(x, rustrt2::rust_get_test_int()); + assert_eq!(x as *const _, rustrt3::rust_get_test_int()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-call-no-runtime.rs b/gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-call-no-runtime.rs new file mode 100644 index 000000000000..baddf439a368 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-call-no-runtime.rs @@ -0,0 +1,56 @@ +// run-pass +// ignore-emscripten no threads support + +#![feature(rustc_private)] + +extern crate libc; + +use std::mem; +use std::thread; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t), + data: libc::uintptr_t) -> libc::uintptr_t; +} + +pub fn main() { + unsafe { + thread::spawn(move|| { + let i: isize = 100; + rust_dbg_call(callback_isize, mem::transmute(&i)); + }).join().unwrap(); + + thread::spawn(move|| { + let i: i32 = 100; + rust_dbg_call(callback_i32, mem::transmute(&i)); + }).join().unwrap(); + + thread::spawn(move|| { + let i: i64 = 100; + rust_dbg_call(callback_i64, mem::transmute(&i)); + }).join().unwrap(); + } +} + +extern fn callback_isize(data: libc::uintptr_t) { + unsafe { + let data: *const isize = mem::transmute(data); + assert_eq!(*data, 100); + } +} + +extern fn callback_i64(data: libc::uintptr_t) { + unsafe { + let data: *const i64 = mem::transmute(data); + assert_eq!(*data, 100); + } +} + +extern fn callback_i32(data: libc::uintptr_t) { + unsafe { + let data: *const i32 = mem::transmute(data); + assert_eq!(*data, 100); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-dupe.rs b/gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-dupe.rs new file mode 100644 index 000000000000..01255017c482 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-dupe.rs @@ -0,0 +1,18 @@ +// run-pass +// aux-build:foreign_lib.rs +// ignore-wasm32-bare no libc to test ffi with + +// Check that we can still call duplicated extern (imported) functions +// which were declared in another crate. See issues #32740 and #32783. + + +extern crate foreign_lib; + +pub fn main() { + unsafe { + let x = foreign_lib::rustrt::rust_get_test_int(); + assert_eq!(x, foreign_lib::rustrt2::rust_get_test_int()); + assert_eq!(x as *const _, foreign_lib::rustrt3::rust_get_test_int()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-fn-with-byval.rs b/gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-fn-with-byval.rs new file mode 100644 index 000000000000..cee879942c96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-fn-with-byval.rs @@ -0,0 +1,33 @@ +// run-pass +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +#[derive(Copy, Clone)] +pub struct S { + x: u64, + y: u64, + z: u64, +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn get_x(x: S) -> u64; + pub fn get_y(x: S) -> u64; + pub fn get_z(x: S) -> u64; +} + +#[inline(never)] +fn indirect_call(func: unsafe extern fn(s: S) -> u64, s: S) -> u64 { + unsafe { + func(s) + } +} + +fn main() { + let s = S { x: 1, y: 2, z: 3 }; + assert_eq!(s.x, indirect_call(get_x, s)); + assert_eq!(s.y, indirect_call(get_y, s)); + assert_eq!(s.z, indirect_call(get_z, s)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-no-abi.rs b/gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-no-abi.rs new file mode 100644 index 000000000000..16cbc57244a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/foreign/foreign-no-abi.rs @@ -0,0 +1,23 @@ +// run-pass +// ABI is cdecl by default + +// ignore-wasm32-bare no libc to test ffi with +// pretty-expanded FIXME #23616 + +#![feature(rustc_private)] + +mod rustrt { + extern crate libc; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub fn main() { + unsafe { + rustrt::rust_get_test_int(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/invoke-external-foreign.rs b/gcc/testsuite/rust/rustc/ui/abi/invoke-external-foreign.rs new file mode 100644 index 000000000000..03f7e4fbd133 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/invoke-external-foreign.rs @@ -0,0 +1,18 @@ +// run-pass +// aux-build:foreign_lib.rs +// ignore-wasm32-bare no libc to test ffi with + +// The purpose of this test is to check that we can +// successfully (and safely) invoke external, cdecl +// functions from outside the crate. + +// pretty-expanded FIXME #23616 + +extern crate foreign_lib; + +pub fn main() { + unsafe { + let _foo = foreign_lib::rustrt::rust_get_test_int(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/issues/issue-62350-sysv-neg-reg-counts.rs b/gcc/testsuite/rust/rustc/ui/abi/issues/issue-62350-sysv-neg-reg-counts.rs new file mode 100644 index 000000000000..6e82f5335044 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/issues/issue-62350-sysv-neg-reg-counts.rs @@ -0,0 +1,47 @@ +// run-pass +#![allow(dead_code)] +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +#[derive(Copy, Clone)] +pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 } + +mod rustrt { + use super::QuadFloats; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn get_c_exhaust_sysv64_ints( + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + h: QuadFloats, + ) -> f32; + } +} + +fn test() { + unsafe { + let null = std::ptr::null(); + let q = QuadFloats { + a: 10.2, + b: 20.3, + c: 30.4, + d: 40.5 + }; + assert_eq!( + rustrt::get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q), + q.c, + ); + } +} + +pub fn main() { + test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/lib-defaults.rs b/gcc/testsuite/rust/rustc/ui/abi/lib-defaults.rs new file mode 100644 index 000000000000..3b4d6b639ca0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/lib-defaults.rs @@ -0,0 +1,18 @@ +// run-pass +// dont-check-compiler-stderr (rust-lang/rust#54222) + +// ignore-wasm32-bare no libc to test ffi with + +// compile-flags: -lrust_test_helpers + +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_extern_identity_u32(x: u32) -> u32; +} + +fn main() { + unsafe { + rust_dbg_extern_identity_u32(42); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/mir/mir_codegen_calls_variadic.rs b/gcc/testsuite/rust/rustc/ui/abi/mir/mir_codegen_calls_variadic.rs new file mode 100644 index 000000000000..7c822eebd116 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/mir/mir_codegen_calls_variadic.rs @@ -0,0 +1,23 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_interesting_average(_: i64, ...) -> f64; +} + +fn test(a: i64, b: i64, c: i64, d: i64, e: i64, f: T, g: U) -> i64 { + unsafe { + rust_interesting_average(6, a, a as f64, + b, b as f64, + c, c as f64, + d, d as f64, + e, e as f64, + f, g) as i64 + } +} + +fn main(){ + assert_eq!(test(10, 20, 30, 40, 50, 60_i64, 60.0_f64), 70); +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/numbers-arithmetic/i128-ffi.rs b/gcc/testsuite/rust/rustc/ui/abi/numbers-arithmetic/i128-ffi.rs new file mode 100644 index 000000000000..47b3b306bf79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/numbers-arithmetic/i128-ffi.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(improper_ctypes)] + +// MSVC doesn't support 128 bit integers, and other Windows +// C compilers have very inconsistent views on how the ABI +// should look like. + +// ignore-windows +// ignore-32bit + +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + fn identity(f: u128) -> u128; + fn square(f: i128) -> i128; + fn sub(f: i128, f: i128) -> i128; +} + +fn main() { + unsafe { + let a = 0x734C_C2F2_A521; + let b = 0x33EE_0E2A_54E2_59DA_A0E7_8E41; + let b_out = identity(b); + assert_eq!(b, b_out); + let a_square = square(a); + assert_eq!(b, a_square as u128); + let k = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210; + let k_d = 0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420; + let k_out = sub(k_d, k); + assert_eq!(k, k_out); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/segfault-no-out-of-stack.rs b/gcc/testsuite/rust/rustc/ui/abi/segfault-no-out-of-stack.rs new file mode 100644 index 000000000000..36e432d6a4bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/segfault-no-out-of-stack.rs @@ -0,0 +1,51 @@ +// run-pass + +#![allow(unused_imports)] +// ignore-cloudabi can't run commands +// ignore-emscripten can't run commands +// ignore-sgx no processes + +#![feature(rustc_private)] + +extern crate libc; + +use std::process::{Command, ExitStatus}; +use std::env; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_get_null_ptr() -> *mut ::libc::c_char; +} + +#[cfg(unix)] +fn check_status(status: std::process::ExitStatus) +{ + use libc; + use std::os::unix::process::ExitStatusExt; + + assert!(status.signal() == Some(libc::SIGSEGV) + || status.signal() == Some(libc::SIGBUS)); +} + +#[cfg(not(unix))] +fn check_status(status: std::process::ExitStatus) +{ + assert!(!status.success()); +} + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "segfault" { + unsafe { *rust_get_null_ptr() = 1; }; // trigger a segfault + } else { + let segfault = Command::new(&args[0]).arg("segfault").output().unwrap(); + let stderr = String::from_utf8_lossy(&segfault.stderr); + let stdout = String::from_utf8_lossy(&segfault.stdout); + println!("stdout: {}", stdout); + println!("stderr: {}", stderr); + println!("status: {}", segfault.status); + check_status(segfault.status); + assert!(!stderr.contains("has overflowed its stack")); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/stack-probes-lto.rs b/gcc/testsuite/rust/rustc/ui/abi/stack-probes-lto.rs new file mode 100644 index 000000000000..23cc85810846 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/stack-probes-lto.rs @@ -0,0 +1,20 @@ +// run-pass +// ignore-arm +// ignore-aarch64 +// ignore-mips +// ignore-mips64 +// ignore-powerpc +// ignore-s390x +// ignore-sparc +// ignore-sparc64 +// ignore-wasm +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +// ignore-musl FIXME #31506 +// ignore-pretty +// compile-flags: -C lto +// no-prefer-dynamic + +include!("stack-probes.rs"); + diff --git a/gcc/testsuite/rust/rustc/ui/abi/stack-probes.rs b/gcc/testsuite/rust/rustc/ui/abi/stack-probes.rs new file mode 100644 index 000000000000..2ffb397aa332 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/stack-probes.rs @@ -0,0 +1,69 @@ +// run-pass +// ignore-arm +// ignore-aarch64 +// ignore-mips +// ignore-mips64 +// ignore-powerpc +// ignore-s390x +// ignore-sparc +// ignore-sparc64 +// ignore-wasm +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::mem::MaybeUninit; +use std::process::Command; +use std::thread; +use std::env; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + #[link_name = "rust_dbg_extern_identity_u64"] + fn black_box(u: u64); +} + +fn main() { + let args = env::args().skip(1).collect::>(); + if args.len() > 0 { + match &args[0][..] { + "main-thread" => recurse(&MaybeUninit::uninit()), + "child-thread" => thread::spawn(|| recurse(&MaybeUninit::uninit())).join().unwrap(), + _ => panic!(), + } + return + } + + let me = env::current_exe().unwrap(); + + // The linux kernel has some different behavior for the main thread because + // the main thread's stack can typically grow. We can't always guarantee + // that we report stack overflow on the main thread, see #43052 for some + // details + if cfg!(not(target_os = "linux")) { + assert_overflow(Command::new(&me).arg("main-thread")); + } + assert_overflow(Command::new(&me).arg("child-thread")); +} + +#[allow(unconditional_recursion)] +fn recurse(array: &MaybeUninit<[u64; 1024]>) { + unsafe { + black_box(array.as_ptr() as u64); + } + let local: MaybeUninit<[u64; 1024]> = MaybeUninit::uninit(); + recurse(&local); +} + +fn assert_overflow(cmd: &mut Command) { + let output = cmd.output().unwrap(); + assert!(!output.status.success()); + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); + println!("status: {}", output.status); + println!("stdout: {}", stdout); + println!("stderr: {}", stderr); + assert!(stdout.is_empty()); + assert!(stderr.contains("has overflowed its stack\n")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/statics/static-mut-foreign.rs b/gcc/testsuite/rust/rustc/ui/abi/statics/static-mut-foreign.rs new file mode 100644 index 000000000000..c36a14387451 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/statics/static-mut-foreign.rs @@ -0,0 +1,42 @@ +// run-pass +// Constants (static variables) can be used to match in patterns, but mutable +// statics cannot. This ensures that there's some form of error if this is +// attempted. + +// ignore-wasm32-bare no libc to test ffi with + +#![feature(rustc_private)] + +extern crate libc; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + static mut rust_dbg_static_mut: libc::c_int; + pub fn rust_dbg_static_mut_check_four(); +} + +unsafe fn static_bound(_: &'static libc::c_int) {} + +fn static_bound_set(a: &'static mut libc::c_int) { + *a = 3; +} + +unsafe fn run() { + assert_eq!(rust_dbg_static_mut, 3); + rust_dbg_static_mut = 4; + assert_eq!(rust_dbg_static_mut, 4); + rust_dbg_static_mut_check_four(); + rust_dbg_static_mut += 1; + assert_eq!(rust_dbg_static_mut, 5); + rust_dbg_static_mut *= 3; + assert_eq!(rust_dbg_static_mut, 15); + rust_dbg_static_mut = -3; + assert_eq!(rust_dbg_static_mut, -3); + static_bound(&rust_dbg_static_mut); + static_bound_set(&mut rust_dbg_static_mut); +} + +pub fn main() { + unsafe { run() } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/struct-enums/struct-return.rs b/gcc/testsuite/rust/rustc/ui/abi/struct-enums/struct-return.rs new file mode 100644 index 000000000000..bbf22b28344a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/struct-enums/struct-return.rs @@ -0,0 +1,115 @@ +// run-pass +#![allow(dead_code)] +// ignore-wasm32-bare no libc to test ffi with + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Quad { a: u64, b: u64, c: u64, d: u64 } + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Floats { a: f64, b: u8, c: f64 } + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CharCharDouble { a: u8, b: u8, c: f64 } + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CharCharFloat { a: u8, b: u8, c: f32 } + +mod rustrt { + use super::{Floats, Quad, CharCharDouble, CharCharFloat}; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn rust_dbg_abi_1(q: Quad) -> Quad; + pub fn rust_dbg_abi_2(f: Floats) -> Floats; + pub fn rust_dbg_abi_3(a: CharCharDouble) -> CharCharDouble; + pub fn rust_dbg_abi_4(a: CharCharFloat) -> CharCharFloat; + } +} + +fn test1() { + unsafe { + let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa, + b: 0xbbbb_bbbb_bbbb_bbbb, + c: 0xcccc_cccc_cccc_cccc, + d: 0xdddd_dddd_dddd_dddd }; + let qq = rustrt::rust_dbg_abi_1(q); + println!("a: {:x}", qq.a as usize); + println!("b: {:x}", qq.b as usize); + println!("c: {:x}", qq.c as usize); + println!("d: {:x}", qq.d as usize); + assert_eq!(qq.a, q.c + 1); + assert_eq!(qq.b, q.d - 1); + assert_eq!(qq.c, q.a + 1); + assert_eq!(qq.d, q.b - 1); + } +} + +#[cfg(target_pointer_width = "64")] +fn test2() { + unsafe { + let f = Floats { a: 1.234567890e-15_f64, + b: 0b_1010_1010, + c: 1.0987654321e-15_f64 }; + let ff = rustrt::rust_dbg_abi_2(f); + println!("a: {}", ff.a as f64); + println!("b: {}", ff.b as usize); + println!("c: {}", ff.c as f64); + assert_eq!(ff.a, f.c + 1.0f64); + assert_eq!(ff.b, 0xff); + assert_eq!(ff.c, f.a - 1.0f64); + } +} + +#[cfg(target_pointer_width = "32")] +fn test2() { +} + +#[cfg(target_pointer_width = "64")] +fn test3() { + unsafe { + let a = CharCharDouble { + a: 1, + b: 2, + c: 3., + }; + let b = rustrt::rust_dbg_abi_3(a); + println!("a: {}", b.a); + println!("b: {}", b.b); + println!("c: {}", b.c); + assert_eq!(b.a, a.a + 1); + assert_eq!(b.b, a.b - 1); + assert_eq!(b.c, a.c + 1.0); + } +} + +#[cfg(target_pointer_width = "32")] +fn test3() {} + +fn test4() { + unsafe { + let a = CharCharFloat { + a: 1, + b: 2, + c: 3., + }; + let b = rustrt::rust_dbg_abi_4(a); + println!("a: {}", b.a); + println!("b: {}", b.b); + println!("c: {}", b.c); + assert_eq!(b.a, a.a + 1); + assert_eq!(b.b, a.b - 1); + assert_eq!(b.c, a.c + 1.0); + } +} + +pub fn main() { + test1(); + test2(); + test3(); + test4(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/union/union-c-interop.rs b/gcc/testsuite/rust/rustc/ui/abi/union/union-c-interop.rs new file mode 100644 index 000000000000..d129000c0b1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/union/union-c-interop.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(non_snake_case)] + +// ignore-wasm32-bare no libc to test ffi with + +#[derive(Clone, Copy)] +#[repr(C)] +struct LARGE_INTEGER_U { + LowPart: u32, + HighPart: u32, +} + +#[derive(Clone, Copy)] +#[repr(C)] +union LARGE_INTEGER { + __unnamed__: LARGE_INTEGER_U, + u: LARGE_INTEGER_U, + QuadPart: u64, +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + fn increment_all_parts(_: LARGE_INTEGER) -> LARGE_INTEGER; +} + +fn main() { + unsafe { + let mut li = LARGE_INTEGER { QuadPart: 0 }; + let li_c = increment_all_parts(li); + li.__unnamed__.LowPart += 1; + li.__unnamed__.HighPart += 1; + li.u.LowPart += 1; + li.u.HighPart += 1; + li.QuadPart += 1; + assert_eq!(li.QuadPart, li_c.QuadPart); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/abi/variadic-ffi.rs b/gcc/testsuite/rust/rustc/ui/abi/variadic-ffi.rs new file mode 100644 index 000000000000..9c8958ee3178 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/abi/variadic-ffi.rs @@ -0,0 +1,85 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with +#![feature(c_variadic)] + +use std::ffi::VaList; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + fn rust_interesting_average(_: u64, ...) -> f64; + + // FIXME: we need to disable this lint for `VaList`, + // since it contains a `MaybeUninit` on the asmjs target, + // and this type isn't FFI-safe. This is OK for now, + // since the type is layout-compatible with `i32`. + #[cfg_attr(target_arch = "asmjs", allow(improper_ctypes))] + fn rust_valist_interesting_average(_: u64, _: VaList) -> f64; +} + +pub unsafe extern "C" fn test_valist_forward(n: u64, mut ap: ...) -> f64 { + rust_valist_interesting_average(n, ap.as_va_list()) +} + +pub unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) { + let mut ap2 = ap.clone(); + assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 30); + + // Advance one pair in the copy before checking + let mut ap2 = ap.clone(); + let _ = ap2.arg::(); + let _ = ap2.arg::(); + assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50); + + // Advance one pair in the original + let _ = ap.arg::(); + let _ = ap.arg::(); + + let mut ap2 = ap.clone(); + assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50); + + let mut ap2 = ap.clone(); + let _ = ap2.arg::(); + let _ = ap2.arg::(); + assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 70); +} + +pub fn main() { + // Call without variadic arguments + unsafe { + assert!(rust_interesting_average(0).is_nan()); + } + + // Call with direct arguments + unsafe { + assert_eq!(rust_interesting_average(1, 10i64, 10.0f64) as i64, 20); + } + + // Call with named arguments, variable number of them + let (x1, x2, x3, x4) = (10i64, 10.0f64, 20i64, 20.0f64); + unsafe { + assert_eq!(rust_interesting_average(2, x1, x2, x3, x4) as i64, 30); + } + + // A function that takes a function pointer + unsafe fn call(fp: unsafe extern fn(u64, ...) -> f64) { + let (x1, x2, x3, x4) = (10i64, 10.0f64, 20i64, 20.0f64); + assert_eq!(fp(2, x1, x2, x3, x4) as i64, 30); + } + + unsafe { + call(rust_interesting_average); + + // Make a function pointer, pass indirectly + let x: unsafe extern fn(u64, ...) -> f64 = rust_interesting_average; + call(x); + } + + unsafe { + assert_eq!(test_valist_forward(2, 10i64, 10f64, 20i64, 20f64) as i64, 30); + } + + unsafe { + test_va_copy(4, 10i64, 10f64, 20i64, 20f64, 30i64, 30f64, 40i64, 40f64); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/absolute-paths-in-nested-use-groups.rs b/gcc/testsuite/rust/rustc/ui/absolute-paths-in-nested-use-groups.rs new file mode 100644 index 000000000000..bc1423e58411 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/absolute-paths-in-nested-use-groups.rs @@ -0,0 +1,12 @@ +#![allow(unused_imports)] + +mod foo {} + +use foo::{ + ::bar, // { dg-error ".E0433." "" { target *-*-* } } + super::bar, // { dg-error ".E0433." "" { target *-*-* } } + self::bar, // { dg-error ".E0433." "" { target *-*-* } } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/access-mode-in-closures.rs b/gcc/testsuite/rust/rustc/ui/access-mode-in-closures.rs new file mode 100644 index 000000000000..6bd40ea3e818 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/access-mode-in-closures.rs @@ -0,0 +1,11 @@ +struct S(Vec); + +fn unpack(_unpack: F) where F: FnOnce(&S) -> Vec {} + +fn main() { + let _foo = unpack(|s| { + // Test that `s` is moved here. + match *s { S(v) => v } // { dg-error ".E0507." "" { target *-*-* } } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/alias-uninit-value.rs b/gcc/testsuite/rust/rustc/ui/alias-uninit-value.rs new file mode 100644 index 000000000000..857780b95197 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/alias-uninit-value.rs @@ -0,0 +1,21 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] + + + +// Regression test for issue #374 + +// pretty-expanded FIXME #23616 + +enum sty { ty_nil, } + +struct RawT {struct_: sty, cname: Option, hash: usize} + +fn mk_raw_ty(st: sty, cname: Option) -> RawT { + return RawT {struct_: st, cname: cname, hash: 0}; +} + +pub fn main() { mk_raw_ty(sty::ty_nil, None::); } + diff --git a/gcc/testsuite/rust/rustc/ui/align-with-extern-c-fn.rs b/gcc/testsuite/rust/rustc/ui/align-with-extern-c-fn.rs new file mode 100644 index 000000000000..f73594e31c1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/align-with-extern-c-fn.rs @@ -0,0 +1,19 @@ +// run-pass + +#![allow(stable_features)] +#![allow(unused_variables)] + +// #45662 + +#![feature(repr_align)] + +#[repr(align(16))] +pub struct A(i64); + +#[allow(improper_ctypes_definitions)] +pub extern "C" fn foo(x: A) {} + +fn main() { + foo(A(0)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/alignment-gep-tup-like-1.rs b/gcc/testsuite/rust/rustc/ui/alignment-gep-tup-like-1.rs new file mode 100644 index 000000000000..1ffe37491495 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/alignment-gep-tup-like-1.rs @@ -0,0 +1,40 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] + +#![feature(box_syntax)] + +struct pair { + a: A, b: B +} + +trait Invokable { + fn f(&self) -> (A, u16); +} + +struct Invoker { + a: A, + b: u16, +} + +impl Invokable for Invoker { + fn f(&self) -> (A, u16) { + (self.a.clone(), self.b) + } +} + +fn f(a: A, b: u16) -> Box+'static> { + box Invoker { + a: a, + b: b, + } as Box+'static> +} + +pub fn main() { + let (a, b) = f(22_u64, 44u16).f(); + println!("a={} b={}", a, b); + assert_eq!(a, 22u64); + assert_eq!(b, 44u16); +} + diff --git a/gcc/testsuite/rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-1.rs b/gcc/testsuite/rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-1.rs new file mode 100644 index 000000000000..dca072a8d8b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-1.rs @@ -0,0 +1,19 @@ +// compile-flags:-C panic=abort + +#![feature(alloc_error_handler, panic_handler)] +#![no_std] +#![no_main] + +use core::alloc::Layout; + +#[alloc_error_handler] +fn oom( + info: &Layout, // { dg-error "" "" { target *-*-* } } +) -> () // { dg-error "" "" { target *-*-* } } +{ + loop {} +} + +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } + diff --git a/gcc/testsuite/rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-2.rs b/gcc/testsuite/rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-2.rs new file mode 100644 index 000000000000..5a01234dc57f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-2.rs @@ -0,0 +1,18 @@ +// compile-flags:-C panic=abort + +#![feature(alloc_error_handler, panic_handler)] +#![no_std] +#![no_main] + +struct Layout; + +#[alloc_error_handler] +fn oom( + info: Layout, // { dg-error "" "" { target *-*-* } } +) { // { dg-error "" "" { target *-*-* } } + loop {} +} + +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } + diff --git a/gcc/testsuite/rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-3.rs b/gcc/testsuite/rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-3.rs new file mode 100644 index 000000000000..da75a393c0a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/alloc-error/alloc-error-handler-bad-signature-3.rs @@ -0,0 +1,16 @@ +// compile-flags:-C panic=abort + +#![feature(alloc_error_handler, panic_handler)] +#![no_std] +#![no_main] + +struct Layout; + +#[alloc_error_handler] +fn oom() -> ! { // { dg-error "" "" { target *-*-* } } + loop {} +} + +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } + diff --git a/gcc/testsuite/rust/rustc/ui/alloca-from-derived-tydesc.rs b/gcc/testsuite/rust/rustc/ui/alloca-from-derived-tydesc.rs new file mode 100644 index 000000000000..c03f59ff1fe6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/alloca-from-derived-tydesc.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] + + +// pretty-expanded FIXME #23616 + +enum option { some(T), none, } + +struct R {v: Vec> } + +fn f() -> Vec { return Vec::new(); } + +pub fn main() { let mut r: R = R {v: Vec::new()}; r.v = f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/allocator-args.rs b/gcc/testsuite/rust/rustc/ui/allocator/allocator-args.rs new file mode 100644 index 000000000000..2877ed63f0df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/allocator-args.rs @@ -0,0 +1,14 @@ +use std::alloc::{GlobalAlloc, Layout}; + +struct A; + +unsafe impl GlobalAlloc for A { + unsafe fn alloc(&self, _: Layout) -> *mut u8 { panic!() } + unsafe fn dealloc(&self, _: *mut u8, _: Layout) { panic!() } +} + +#[global_allocator(malloc)] // { dg-error "" "" { target *-*-* } } +static S: A = A; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/custom-as-global.rs b/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/custom-as-global.rs new file mode 100644 index 000000000000..ebdd286e33c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/custom-as-global.rs @@ -0,0 +1,17 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +extern crate custom; + +use std::sync::atomic::{AtomicUsize, Ordering}; + +use custom::A; + +#[global_allocator] +static ALLOCATOR: A = A(AtomicUsize::new(0)); + +pub fn get() -> usize { + ALLOCATOR.0.load(Ordering::SeqCst) +} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/custom.rs b/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/custom.rs new file mode 100644 index 000000000000..e9b085ef35b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/custom.rs @@ -0,0 +1,22 @@ +// no-prefer-dynamic + +#![feature(allocator_api)] +#![crate_type = "rlib"] + +use std::alloc::{GlobalAlloc, System, Layout}; +use std::sync::atomic::{AtomicUsize, Ordering}; + +pub struct A(pub AtomicUsize); + +unsafe impl GlobalAlloc for A { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + self.0.fetch_add(1, Ordering::SeqCst); + System.alloc(layout) + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + self.0.fetch_add(1, Ordering::SeqCst); + System.dealloc(ptr, layout) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/helper.rs b/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/helper.rs new file mode 100644 index 000000000000..30a6208a3ab0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/helper.rs @@ -0,0 +1,12 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] +#![no_std] + +extern crate alloc; +use alloc::fmt; + +pub fn work_with(p: &fmt::Debug) { + drop(p); +} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/system-allocator.rs b/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/system-allocator.rs new file mode 100644 index 000000000000..78899413599c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/system-allocator.rs @@ -0,0 +1,9 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +use std::alloc::System; + +#[global_allocator] +static A: System = System; + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/system-allocator2.rs b/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/system-allocator2.rs new file mode 100644 index 000000000000..78899413599c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/auxiliary/system-allocator2.rs @@ -0,0 +1,9 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +use std::alloc::System; + +#[global_allocator] +static A: System = System; + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/custom-in-block.rs b/gcc/testsuite/rust/rustc/ui/allocator/custom-in-block.rs new file mode 100644 index 000000000000..ca7a2783f811 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/custom-in-block.rs @@ -0,0 +1,23 @@ +// run-pass +// no-prefer-dynamic +// aux-build:custom.rs +// aux-build:helper.rs + +extern crate custom; +extern crate helper; + +use custom::A; +use std::sync::atomic::{AtomicUsize, Ordering}; + +fn main() { + #[global_allocator] + pub static GLOBAL: A = A(AtomicUsize::new(0)); + + let n = GLOBAL.0.load(Ordering::SeqCst); + let s = Box::new(0); + helper::work_with(&s); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1); + drop(s); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/custom-in-submodule.rs b/gcc/testsuite/rust/rustc/ui/allocator/custom-in-submodule.rs new file mode 100644 index 000000000000..5b073feef0f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/custom-in-submodule.rs @@ -0,0 +1,27 @@ +// run-pass +// no-prefer-dynamic +// aux-build:custom.rs +// aux-build:helper.rs + +extern crate custom; +extern crate helper; + +use custom::A; +use std::sync::atomic::{AtomicUsize, Ordering}; + +mod submodule { + use super::*; + + #[global_allocator] + pub static GLOBAL: A = A(AtomicUsize::new(0)); +} + +fn main() { + let n = submodule::GLOBAL.0.load(Ordering::SeqCst); + let s = Box::new(0); + helper::work_with(&s); + assert_eq!(submodule::GLOBAL.0.load(Ordering::SeqCst), n + 1); + drop(s); + assert_eq!(submodule::GLOBAL.0.load(Ordering::SeqCst), n + 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/custom.rs b/gcc/testsuite/rust/rustc/ui/allocator/custom.rs new file mode 100644 index 000000000000..17bba19b3b59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/custom.rs @@ -0,0 +1,61 @@ +// run-pass + +// aux-build:helper.rs +// no-prefer-dynamic + +#![feature(allocator_api)] +#![feature(slice_ptr_get)] + +extern crate helper; + +use std::alloc::{self, AllocRef, Global, Layout, System}; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::ptr::NonNull; + +static HITS: AtomicUsize = AtomicUsize::new(0); + +struct A; + +unsafe impl alloc::GlobalAlloc for A { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + HITS.fetch_add(1, Ordering::SeqCst); + alloc::GlobalAlloc::alloc(&System, layout) + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + HITS.fetch_add(1, Ordering::SeqCst); + AllocRef::dealloc(&System, NonNull::new(ptr).unwrap(), layout) + } +} + +#[global_allocator] +static GLOBAL: A = A; + +fn main() { + println!("hello!"); + + let n = HITS.load(Ordering::SeqCst); + assert!(n > 0); + unsafe { + let layout = Layout::from_size_align(4, 2).unwrap(); + + let memory = Global.alloc(layout.clone()).unwrap(); + helper::work_with(&memory); + assert_eq!(HITS.load(Ordering::SeqCst), n + 1); + Global.dealloc(memory.as_non_null_ptr(), layout); + assert_eq!(HITS.load(Ordering::SeqCst), n + 2); + + let s = String::with_capacity(10); + helper::work_with(&s); + assert_eq!(HITS.load(Ordering::SeqCst), n + 3); + drop(s); + assert_eq!(HITS.load(Ordering::SeqCst), n + 4); + + let memory = System.alloc(layout.clone()).unwrap(); + assert_eq!(HITS.load(Ordering::SeqCst), n + 4); + helper::work_with(&memory); + System.dealloc(memory.as_non_null_ptr(), layout); + assert_eq!(HITS.load(Ordering::SeqCst), n + 4); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/function-allocator.rs b/gcc/testsuite/rust/rustc/ui/allocator/function-allocator.rs new file mode 100644 index 000000000000..f731ec59fb5a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/function-allocator.rs @@ -0,0 +1,5 @@ +#[global_allocator] +fn foo() {} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/hygiene.rs b/gcc/testsuite/rust/rustc/ui/allocator/hygiene.rs new file mode 100644 index 000000000000..4575aa2242c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/hygiene.rs @@ -0,0 +1,32 @@ +// run-pass +// no-prefer-dynamic +// aux-build:custom.rs +// aux-build:helper.rs + +#![allow(nonstandard_style)] + +extern crate custom; +extern crate helper; + +use custom::A; +use std::sync::atomic::{AtomicUsize, Ordering}; + +#[allow(dead_code)] +struct u8; +#[allow(dead_code)] +struct usize; +#[allow(dead_code)] +static arg0: () = (); + +#[global_allocator] +pub static GLOBAL: A = A(AtomicUsize::new(0)); + +fn main() { + let n = GLOBAL.0.load(Ordering::SeqCst); + let s = Box::new(0); + helper::work_with(&s); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1); + drop(s); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/no_std-alloc-error-handler-custom.rs b/gcc/testsuite/rust/rustc/ui/allocator/no_std-alloc-error-handler-custom.rs new file mode 100644 index 000000000000..2fed30ea66c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/no_std-alloc-error-handler-custom.rs @@ -0,0 +1,98 @@ +// run-pass +// ignore-android no libc +// ignore-cloudabi no libc +// ignore-emscripten no libc +// ignore-sgx no libc +// ignore-wasm32 no libc +// only-linux +// compile-flags:-C panic=abort +// aux-build:helper.rs + +#![feature(start, rustc_private, new_uninit, panic_info_message)] +#![feature(alloc_error_handler)] +#![no_std] + +extern crate alloc; +extern crate libc; + +// ARM targets need these symbols +#[no_mangle] +pub fn __aeabi_unwind_cpp_pr0() {} + +#[no_mangle] +pub fn __aeabi_unwind_cpp_pr1() {} + +use core::ptr::null_mut; +use core::alloc::{GlobalAlloc, Layout}; +use alloc::boxed::Box; + +extern crate helper; + +struct MyAllocator; + +#[alloc_error_handler] +fn my_oom(layout: Layout) -> ! +{ + use alloc::fmt::write; + unsafe { + let size = layout.size(); + let mut s = alloc::string::String::new(); + write(&mut s, format_args!("My OOM: failed to allocate {} bytes!\n", size)).unwrap(); + let s = s.as_str(); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::exit(0) + } +} + +unsafe impl GlobalAlloc for MyAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + if layout.size() < 4096 { + libc::malloc(layout.size()) as _ + } else { + null_mut() + } + } + unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} +} + +#[global_allocator] +static A: MyAllocator = MyAllocator; + +#[panic_handler] +fn panic(panic_info: &core::panic::PanicInfo) -> ! { + unsafe { + if let Some(s) = panic_info.payload().downcast_ref::<&str>() { + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); + } + if let Some(args) = panic_info.message() { + let mut s = alloc::string::String::new(); + alloc::fmt::write(&mut s, *args).unwrap(); + let s = s.as_str(); + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); + } else { + const PSTR: &str = "panic occurred\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + } + libc::exit(1) + } +} + +#[derive(Debug)] +struct Page([[u64; 32]; 16]); + +#[start] +pub fn main(_argc: isize, _argv: *const *const u8) -> isize { + let zero = Box::::new_zeroed(); + let zero = unsafe { zero.assume_init() }; + helper::work_with(&zero); + 1 +} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/no_std-alloc-error-handler-default.rs b/gcc/testsuite/rust/rustc/ui/allocator/no_std-alloc-error-handler-default.rs new file mode 100644 index 000000000000..7907d93b4f79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/no_std-alloc-error-handler-default.rs @@ -0,0 +1,85 @@ +// run-pass +// ignore-android no libc +// ignore-cloudabi no libc +// ignore-emscripten no libc +// ignore-sgx no libc +// ignore-wasm32 no libc +// only-linux +// compile-flags:-C panic=abort +// aux-build:helper.rs +// gate-test-default_alloc_error_handler + +#![feature(start, rustc_private, new_uninit, panic_info_message)] +#![feature(default_alloc_error_handler)] +#![no_std] + +extern crate alloc; +extern crate libc; + +// ARM targets need these symbols +#[no_mangle] +pub fn __aeabi_unwind_cpp_pr0() {} + +#[no_mangle] +pub fn __aeabi_unwind_cpp_pr1() {} + +use alloc::boxed::Box; +use core::alloc::{GlobalAlloc, Layout}; +use core::ptr::null_mut; + +extern crate helper; + +struct MyAllocator; + +unsafe impl GlobalAlloc for MyAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + if layout.size() < 4096 { + libc::malloc(layout.size()) as _ + } else { + null_mut() + } + } + unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} +} + +#[global_allocator] +static A: MyAllocator = MyAllocator; + +#[panic_handler] +fn panic(panic_info: &core::panic::PanicInfo) -> ! { + unsafe { + if let Some(s) = panic_info.payload().downcast_ref::<&str>() { + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); + } + if let Some(args) = panic_info.message() { + let mut s = alloc::string::String::new(); + alloc::fmt::write(&mut s, *args).unwrap(); + let s = s.as_str(); + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); + } else { + const PSTR: &str = "panic occurred\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + } + libc::exit(0) + } +} + +#[derive(Debug)] +struct Page([[u64; 32]; 16]); + +#[start] +pub fn main(_argc: isize, _argv: *const *const u8) -> isize { + let zero = Box::::new_zeroed(); + let zero = unsafe { zero.assume_init() }; + helper::work_with(&zero); + 1 +} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/not-an-allocator.rs b/gcc/testsuite/rust/rustc/ui/allocator/not-an-allocator.rs new file mode 100644 index 000000000000..95022ec16df8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/not-an-allocator.rs @@ -0,0 +1,9 @@ +#[global_allocator] +static A: usize = 0; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/two-allocators.rs b/gcc/testsuite/rust/rustc/ui/allocator/two-allocators.rs new file mode 100644 index 000000000000..42769b0f5092 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/two-allocators.rs @@ -0,0 +1,10 @@ +use std::alloc::System; + +#[global_allocator] +static A: System = System; +#[global_allocator] +static B: System = System; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/two-allocators2.rs b/gcc/testsuite/rust/rustc/ui/allocator/two-allocators2.rs new file mode 100644 index 000000000000..85bbb6b73fe2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/two-allocators2.rs @@ -0,0 +1,13 @@ +// aux-build:system-allocator.rs +// no-prefer-dynamic +// error-pattern: the `#[global_allocator]` in + +extern crate system_allocator; + +use std::alloc::System; + +#[global_allocator] +static A: System = System; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/two-allocators3.rs b/gcc/testsuite/rust/rustc/ui/allocator/two-allocators3.rs new file mode 100644 index 000000000000..2d134bf3417a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/two-allocators3.rs @@ -0,0 +1,11 @@ +// aux-build:system-allocator.rs +// aux-build:system-allocator2.rs +// no-prefer-dynamic +// error-pattern: the `#[global_allocator]` in + + +extern crate system_allocator; +extern crate system_allocator2; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/xcrate-use.rs b/gcc/testsuite/rust/rustc/ui/allocator/xcrate-use.rs new file mode 100644 index 000000000000..32edf0d793f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/xcrate-use.rs @@ -0,0 +1,37 @@ +// run-pass + +// aux-build:custom.rs +// aux-build:helper.rs +// no-prefer-dynamic + +#![feature(allocator_api)] +#![feature(slice_ptr_get)] + +extern crate custom; +extern crate helper; + +use std::alloc::{AllocRef, Global, Layout, System}; +use std::sync::atomic::{AtomicUsize, Ordering}; + +#[global_allocator] +static GLOBAL: custom::A = custom::A(AtomicUsize::new(0)); + +fn main() { + unsafe { + let n = GLOBAL.0.load(Ordering::SeqCst); + let layout = Layout::from_size_align(4, 2).unwrap(); + + let memory = Global.alloc(layout.clone()).unwrap(); + helper::work_with(&memory); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1); + Global.dealloc(memory.as_non_null_ptr(), layout); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); + + let memory = System.alloc(layout.clone()).unwrap(); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); + helper::work_with(&memory); + System.dealloc(memory.as_non_null_ptr(), layout); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/allocator/xcrate-use2.rs b/gcc/testsuite/rust/rustc/ui/allocator/xcrate-use2.rs new file mode 100644 index 000000000000..6e97c65f6fad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/allocator/xcrate-use2.rs @@ -0,0 +1,48 @@ +// run-pass + +// aux-build:custom.rs +// aux-build:custom-as-global.rs +// aux-build:helper.rs +// no-prefer-dynamic + +#![feature(allocator_api)] + +extern crate custom; +extern crate custom_as_global; +extern crate helper; + +use std::alloc::{alloc, dealloc, GlobalAlloc, System, Layout}; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static GLOBAL: custom::A = custom::A(AtomicUsize::new(0)); + +fn main() { + unsafe { + let n = custom_as_global::get(); + let layout = Layout::from_size_align(4, 2).unwrap(); + + // Global allocator routes to the `custom_as_global` global + let ptr = alloc(layout.clone()); + helper::work_with(&ptr); + assert_eq!(custom_as_global::get(), n + 1); + dealloc(ptr, layout.clone()); + assert_eq!(custom_as_global::get(), n + 2); + + // Usage of the system allocator avoids all globals + let ptr = System.alloc(layout.clone()); + helper::work_with(&ptr); + assert_eq!(custom_as_global::get(), n + 2); + System.dealloc(ptr, layout.clone()); + assert_eq!(custom_as_global::get(), n + 2); + + // Usage of our personal allocator doesn't affect other instances + let ptr = GLOBAL.alloc(layout.clone()); + helper::work_with(&ptr); + assert_eq!(custom_as_global::get(), n + 2); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 1); + GLOBAL.dealloc(ptr, layout); + assert_eq!(custom_as_global::get(), n + 2); + assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 2); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/annotate-snippet/auxiliary/multispan.rs b/gcc/testsuite/rust/rustc/ui/annotate-snippet/auxiliary/multispan.rs new file mode 100644 index 000000000000..7a8970cdcef2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/annotate-snippet/auxiliary/multispan.rs @@ -0,0 +1,38 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_diagnostic, proc_macro_span, proc_macro_def_site)] + +extern crate proc_macro; + +use proc_macro::{TokenStream, TokenTree, Span, Diagnostic}; + +fn parse(input: TokenStream) -> Result<(), Diagnostic> { + let mut hi_spans = vec![]; + for tree in input { + if let TokenTree::Ident(ref ident) = tree { + if ident.to_string() == "hi" { + hi_spans.push(ident.span()); + } + } + } + + if !hi_spans.is_empty() { + return Err(Span::def_site() + .error("hello to you, too!") + .span_note(hi_spans, "found these 'hi's")); + } + + Ok(()) +} + +#[proc_macro] +pub fn hello(input: TokenStream) -> TokenStream { + if let Err(diag) = parse(input) { + diag.emit(); + } + + TokenStream::new() +} + diff --git a/gcc/testsuite/rust/rustc/ui/annotate-snippet/missing-type.rs b/gcc/testsuite/rust/rustc/ui/annotate-snippet/missing-type.rs new file mode 100644 index 000000000000..9f233b82f888 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/annotate-snippet/missing-type.rs @@ -0,0 +1,6 @@ +// compile-flags: --error-format human-annotate-rs + +pub fn main() { + let x: Iter; // { dg-error ".E0412." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/annotate-snippet/multispan.rs b/gcc/testsuite/rust/rustc/ui/annotate-snippet/multispan.rs new file mode 100644 index 000000000000..0471c1a032ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/annotate-snippet/multispan.rs @@ -0,0 +1,29 @@ +// aux-build:multispan.rs +// compile-flags: --error-format human-annotate-rs + +#![feature(proc_macro_hygiene)] + +extern crate multispan; + +use multispan::hello; + +fn main() { + // This one emits no error. + hello!(); + + // Exactly one 'hi'. + hello!(hi); // { dg-error "" "" { target *-*-* } } + + // Now two, back to back. + hello!(hi hi); // { dg-error "" "" { target *-*-* } } + + // Now three, back to back. + hello!(hi hi hi); // { dg-error "" "" { target *-*-* } } + + // Now several, with spacing. + hello!(hi hey hi yo hi beep beep hi hi); // { dg-error "" "" { target *-*-* } } + hello!(hi there, hi how are you? hi... hi.); // { dg-error "" "" { target *-*-* } } + hello!(whoah. hi di hi di ho); // { dg-error "" "" { target *-*-* } } + hello!(hi good hi and good bye); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/anon-params/anon-params-denied-2018.rs b/gcc/testsuite/rust/rustc/ui/anon-params/anon-params-denied-2018.rs new file mode 100644 index 000000000000..77c0de9a7031 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/anon-params/anon-params-denied-2018.rs @@ -0,0 +1,19 @@ +// Tests that anonymous parameters are a hard error in edition 2018. + +// edition:2018 + +trait T { + fn foo(i32); // { dg-error "" "" { target *-*-* } } + + fn bar_with_default_impl(String, String) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + // do not complain about missing `b` + fn baz(a:usize, b, c: usize) -> usize { // { dg-error "" "" { target *-*-* } } + a + b + c + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/anon-params/anon-params-deprecated.rs b/gcc/testsuite/rust/rustc/ui/anon-params/anon-params-deprecated.rs new file mode 100644 index 000000000000..eaa04028d351 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/anon-params/anon-params-deprecated.rs @@ -0,0 +1,20 @@ +#![warn(anonymous_parameters)] +// Test for the anonymous_parameters deprecation lint (RFC 1685) + +// check-pass +// edition:2015 +// run-rustfix + +trait T { + fn foo(i32); // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + + fn bar_with_default_impl(String, String) {} +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/anon-params/anon-params-edition-hygiene.rs b/gcc/testsuite/rust/rustc/ui/anon-params/anon-params-edition-hygiene.rs new file mode 100644 index 000000000000..05130d177c65 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/anon-params/anon-params-edition-hygiene.rs @@ -0,0 +1,11 @@ +// check-pass +// edition:2018 +// aux-build:anon-params-edition-hygiene.rs + +#[macro_use] +extern crate anon_params_edition_hygiene; + +generate_trait_2015!(u8); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/anon-params/auxiliary/anon-params-edition-hygiene.rs b/gcc/testsuite/rust/rustc/ui/anon-params/auxiliary/anon-params-edition-hygiene.rs new file mode 100644 index 000000000000..d6bed2651ac7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/anon-params/auxiliary/anon-params-edition-hygiene.rs @@ -0,0 +1,13 @@ +// edition:2015 + +#[macro_export] +macro_rules! generate_trait_2015 { + ($Type: ident) => { + trait Trait { + fn method($Type) {} + } + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/anonymous-higher-ranked-lifetime.rs b/gcc/testsuite/rust/rustc/ui/anonymous-higher-ranked-lifetime.rs new file mode 100644 index 000000000000..430dedc8e399 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/anonymous-higher-ranked-lifetime.rs @@ -0,0 +1,31 @@ +fn main() { + f1(|_: (), _: ()| {}); // { dg-error ".E0631." "" { target *-*-* } } + f2(|_: (), _: ()| {}); // { dg-error ".E0631." "" { target *-*-* } } + f3(|_: (), _: ()| {}); // { dg-error ".E0631." "" { target *-*-* } } + f4(|_: (), _: ()| {}); // { dg-error ".E0631." "" { target *-*-* } } + f5(|_: (), _: ()| {}); // { dg-error ".E0631." "" { target *-*-* } } + g1(|_: (), _: ()| {}); // { dg-error ".E0631." "" { target *-*-* } } + g2(|_: (), _: ()| {}); // { dg-error ".E0631." "" { target *-*-* } } + g3(|_: (), _: ()| {}); // { dg-error ".E0631." "" { target *-*-* } } + g4(|_: (), _: ()| {}); // { dg-error ".E0631." "" { target *-*-* } } + h1(|_: (), _: (), _: (), _: ()| {}); // { dg-error ".E0631." "" { target *-*-* } } + h2(|_: (), _: (), _: (), _: ()| {}); // { dg-error ".E0631." "" { target *-*-* } } +} + +// Basic +fn f1(_: F) where F: Fn(&(), &()) {} +fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} +fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {} +fn f4(_: F) where F: for<'r> Fn(&(), &'r ()) {} +fn f5(_: F) where F: for<'r> Fn(&'r (), &'r ()) {} + +// Nested +fn g1(_: F) where F: Fn(&(), Box) {} +fn g2(_: F) where F: Fn(&(), fn(&())) {} +fn g3(_: F) where F: for<'s> Fn(&'s (), Box) {} +fn g4(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {} + +// Mixed +fn h1(_: F) where F: Fn(&(), Box, &(), fn(&(), &())) {} +fn h2(_: F) where F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &())) {} + diff --git a/gcc/testsuite/rust/rustc/ui/arg-count-mismatch.rs b/gcc/testsuite/rust/rustc/ui/arg-count-mismatch.rs new file mode 100644 index 000000000000..054647f12f31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/arg-count-mismatch.rs @@ -0,0 +1,6 @@ +// error-pattern: arguments were supplied + +fn f(x: isize) { } + +fn main() { let i: (); i = f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/arg-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/arg-type-mismatch.rs new file mode 100644 index 000000000000..4db0ceca3172 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/arg-type-mismatch.rs @@ -0,0 +1,6 @@ +// error-pattern: mismatched types + +fn f(x: isize) { } + +fn main() { let i: (); i = f(()); } + diff --git a/gcc/testsuite/rust/rustc/ui/argument-passing.rs b/gcc/testsuite/rust/rustc/ui/argument-passing.rs new file mode 100644 index 000000000000..411a0d943e88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/argument-passing.rs @@ -0,0 +1,26 @@ +// run-pass + +struct X { + x: isize +} + +fn f1(a: &mut X, b: &mut isize, c: isize) -> isize { + let r = a.x + *b + c; + a.x = 0; + *b = 10; + return r; +} + +fn f2(a: isize, f: F) -> isize where F: FnOnce(isize) { f(1); return a; } + +pub fn main() { + let mut a = X {x: 1}; + let mut b = 2; + let c = 3; + assert_eq!(f1(&mut a, &mut b, c), 6); + assert_eq!(a.x, 0); + assert_eq!(b, 10); + assert_eq!(f2(a.x, |_| a.x = 50), 0); + assert_eq!(a.x, 50); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-break-length.rs b/gcc/testsuite/rust/rustc/ui/array-break-length.rs new file mode 100644 index 000000000000..701e4347deab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-break-length.rs @@ -0,0 +1,10 @@ +fn main() { + loop { + |_: [_; break]| {} // { dg-error ".E0268." "" { target *-*-* } } + } + + loop { + |_: [_; continue]| {} // { dg-error ".E0268." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-not-vector.rs b/gcc/testsuite/rust/rustc/ui/array-not-vector.rs new file mode 100644 index 000000000000..08fcfe1c596a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-not-vector.rs @@ -0,0 +1,13 @@ +fn main() { + let _x: i32 = [1, 2, 3]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + let x: &[i32] = &[1, 2, 3]; + let _y: &i32 = x; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/array_const_index-1.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/array_const_index-1.rs new file mode 100644 index 000000000000..67196b884631 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/array_const_index-1.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +#![allow(stable_features)] + +#![feature(const_indexing)] + +fn main() { + const ARR: [i32; 6] = [42, 43, 44, 45, 46, 47]; + const IDX: usize = 3; + const VAL: i32 = ARR[IDX]; + const BLUB: [i32; (ARR[0] - 41) as usize] = [5]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/bounds-check-no-overflow.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/bounds-check-no-overflow.rs new file mode 100644 index 000000000000..f7ab06ae1f01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/bounds-check-no-overflow.rs @@ -0,0 +1,12 @@ +// run-fail +// error-pattern:index out of bounds +// ignore-emscripten no processes + +use std::usize; +use std::mem::size_of; + +fn main() { + let xs = [1, 2, 3]; + xs[usize::MAX / size_of::() + 1]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/box-of-array-of-drop-1.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/box-of-array-of-drop-1.rs new file mode 100644 index 000000000000..aa448cf880fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/box-of-array-of-drop-1.rs @@ -0,0 +1,48 @@ +// run-pass +#![allow(overflowing_literals)] + +// Test that we cleanup a fixed size Box<[D; k]> properly when D has a +// destructor. + +// ignore-emscripten no threads support + +use std::thread; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static LOG: AtomicUsize = AtomicUsize::new(0); + +struct D(u8); + +impl Drop for D { + fn drop(&mut self) { + println!("Dropping {}", self.0); + let old = LOG.load(Ordering::SeqCst); + LOG.compare_and_swap(old, old << 4 | self.0 as usize, Ordering::SeqCst); + } +} + +fn main() { + fn die() -> D { panic!("Oh no"); } + let g = thread::spawn(|| { + let _b1: Box<[D; 4]> = Box::new([D( 1), D( 2), D( 3), D( 4)]); + let _b2: Box<[D; 4]> = Box::new([D( 5), D( 6), D( 7), D( 8)]); + let _b3: Box<[D; 4]> = Box::new([D( 9), D(10), die(), D(12)]); + let _b4: Box<[D; 4]> = Box::new([D(13), D(14), D(15), D(16)]); + }); + assert!(g.join().is_err()); + + // When the panic occurs, we will be in the midst of constructing + // the input to `_b3`. Therefore, we drop the elements of the + // partially filled array first, before we get around to dropping + // the elements of `_b1` and _b2`. + + // Issue 23222: The order in which the elements actually get + // dropped is a little funky. See similar notes in nested-vec-3; + // in essence, I would not be surprised if we change the ordering + // given in `expect` in the future. + + let expect = 0x__A_9__5_6_7_8__1_2_3_4; + let actual = LOG.load(Ordering::SeqCst); + assert!(actual == expect, "expect: 0x{:x} actual: 0x{:x}", expect, actual); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/box-of-array-of-drop-2.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/box-of-array-of-drop-2.rs new file mode 100644 index 000000000000..a2bb7d0b2f1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/box-of-array-of-drop-2.rs @@ -0,0 +1,48 @@ +// run-pass +#![allow(overflowing_literals)] + +// Test that we cleanup dynamic sized Box<[D]> properly when D has a +// destructor. + +// ignore-emscripten no threads support + +use std::thread; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static LOG: AtomicUsize = AtomicUsize::new(0); + +struct D(u8); + +impl Drop for D { + fn drop(&mut self) { + println!("Dropping {}", self.0); + let old = LOG.load(Ordering::SeqCst); + LOG.compare_and_swap(old, old << 4 | self.0 as usize, Ordering::SeqCst); + } +} + +fn main() { + fn die() -> D { panic!("Oh no"); } + let g = thread::spawn(|| { + let _b1: Box<[D; 4]> = Box::new([D( 1), D( 2), D( 3), D( 4)]); + let _b2: Box<[D; 4]> = Box::new([D( 5), D( 6), D( 7), D( 8)]); + let _b3: Box<[D; 4]> = Box::new([D( 9), D(10), die(), D(12)]); + let _b4: Box<[D; 4]> = Box::new([D(13), D(14), D(15), D(16)]); + }); + assert!(g.join().is_err()); + + // When the panic occurs, we will be in the midst of constructing + // the input to `_b3`. Therefore, we drop the elements of the + // partially filled array first, before we get around to dropping + // the elements of `_b1` and _b2`. + + // Issue 23222: The order in which the elements actually get + // dropped is a little funky. See similar notes in nested-vec-3; + // in essence, I would not be surprised if we change the ordering + // given in `expect` in the future. + + let expect = 0x__A_9__5_6_7_8__1_2_3_4; + let actual = LOG.load(Ordering::SeqCst); + assert!(actual == expect, "expect: 0x{:x} actual: 0x{:x}", expect, actual); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/cast-in-array-size.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/cast-in-array-size.rs new file mode 100644 index 000000000000..7e942e69463c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/cast-in-array-size.rs @@ -0,0 +1,15 @@ +// run-pass + + +// issues #10618 and #16382 +// pretty-expanded FIXME #23616 + +const SIZE: isize = 25; + +fn main() { + let _a: [bool; 1 as usize]; + let _b: [isize; SIZE as usize] = [1; SIZE as usize]; + let _c: [bool; '\n' as usize] = [true; '\n' as usize]; + let _d: [bool; true as usize] = [true; true as usize]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/check-static-mut-slices.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/check-static-mut-slices.rs new file mode 100644 index 000000000000..c41e70c06aa2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/check-static-mut-slices.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] + +// Checks that mutable static items can have mutable slices + + +static mut TEST: &'static mut [isize] = &mut [1]; +static mut EMPTY: &'static mut [isize] = &mut []; + +pub fn main() { + unsafe { + TEST[0] += 1; + assert_eq!(TEST[0], 2); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/check-static-slice.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/check-static-slice.rs new file mode 100644 index 000000000000..9d3c8dc3bf26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/check-static-slice.rs @@ -0,0 +1,37 @@ +// run-pass + +// Check that the various ways of getting to a reference to a vec (both sized +// and unsized) work properly. + + +const AA: [isize; 3] = [1, 2, 3]; +const AB: &'static [isize; 3] = &AA; +const AC: &'static [isize] = AB; +const AD: &'static [isize] = &AA; +const AE: &'static [isize; 3] = &[1, 2, 3]; +const AF: &'static [isize] = &[1, 2, 3]; + +static CA: isize = AA[0]; +static CB: isize = AB[1]; +static CC: isize = AC[2]; +static CD: isize = AD[0]; +static CE: isize = AE[1]; +static CF: isize = AF[2]; + +static AG: &'static isize = &AA[2]; + +fn main () { + let b: &[isize] = &[1, 2, 3]; + assert_eq!(AC, b); + assert_eq!(AD, b); + assert_eq!(AF, b); + assert_eq!(*AG, 3); + + assert_eq!(CA, 1); + assert_eq!(CB, 2); + assert_eq!(CC, 3); + assert_eq!(CD, 1); + assert_eq!(CE, 2); + assert_eq!(CF, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/copy-out-of-array-1.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/copy-out-of-array-1.rs new file mode 100644 index 000000000000..507d302241ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/copy-out-of-array-1.rs @@ -0,0 +1,20 @@ +// run-pass + +// Ensure that we can copy out of a fixed-size array. +// +// (Compare with compile-fail/move-out-of-array-1.rs) + +#[derive(Copy, Clone)] +struct C { _x: u8 } + +fn main() { + fn d() -> C { C { _x: 0 } } + + let _d1 = foo([d(), d(), d(), d()], 1); + let _d3 = foo([d(), d(), d(), d()], 3); +} + +fn foo(a: [C; 4], i: usize) -> C { + a[i] +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/destructure-array-1.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/destructure-array-1.rs new file mode 100644 index 000000000000..a6d10b9e1371 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/destructure-array-1.rs @@ -0,0 +1,28 @@ +// run-pass + +// Ensure that we can do a destructuring bind of a fixed-size array, +// even when the element type has a destructor. + +struct D { x: u8 } + +impl Drop for D { fn drop(&mut self) { } } + +fn main() { + fn d(x: u8) -> D { D { x: x } } + + let d1 = foo([d(1), d(2), d(3), d(4)], 1); + let d3 = foo([d(5), d(6), d(7), d(8)], 3); + assert_eq!(d1.x, 2); + assert_eq!(d3.x, 8); +} + +fn foo([a, b, c, d]: [D; 4], i: usize) -> D { + match i { + 0 => a, + 1 => b, + 2 => c, + 3 => d, + _ => panic!("unmatched"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/dst-raw-slice.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/dst-raw-slice.rs new file mode 100644 index 000000000000..2e154152ce01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/dst-raw-slice.rs @@ -0,0 +1,14 @@ +// Test bounds checking for DST raw slices + +// run-fail +// error-pattern:index out of bounds +// ignore-emscripten no processes + +#[allow(unconditional_panic)] +fn main() { + let a: *const [_] = &[1, 2, 3]; + unsafe { + let _b = (*a)[3]; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/empty-mutable-vec.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/empty-mutable-vec.rs new file mode 100644 index 000000000000..d6fe7b64019f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/empty-mutable-vec.rs @@ -0,0 +1,9 @@ +// run-pass + +// pretty-expanded FIXME #23616 + +#![allow(unused_mut)] + + +pub fn main() { let mut _v: Vec = Vec::new(); } + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/estr-slice.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/estr-slice.rs new file mode 100644 index 000000000000..0ee56be6152b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/estr-slice.rs @@ -0,0 +1,51 @@ +// run-pass + + +pub fn main() { + let x = "hello"; + let v = "hello"; + let y : &str = "there"; + + println!("{}", x); + println!("{}", y); + + assert_eq!(x.as_bytes()[0], 'h' as u8); + assert_eq!(x.as_bytes()[4], 'o' as u8); + + let z : &str = "thing"; + assert_eq!(v, x); + assert_ne!(x, z); + + let a = "aaaa"; + let b = "bbbb"; + + let c = "cccc"; + let cc = "ccccc"; + + println!("{}", a); + + assert!(a < b); + assert!(a <= b); + assert_ne!(a, b); + assert!(b >= a); + assert!(b > a); + + println!("{}", b); + + assert!(a < c); + assert!(a <= c); + assert_ne!(a, c); + assert!(c >= a); + assert!(c > a); + + println!("{}", c); + + assert!(c < cc); + assert!(c <= cc); + assert_ne!(c, cc); + assert!(cc >= c); + assert!(cc > c); + + println!("{}", cc); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/evec-slice.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/evec-slice.rs new file mode 100644 index 000000000000..48102967a6e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/evec-slice.rs @@ -0,0 +1,48 @@ +// run-pass +#![allow(unused_assignments)] + +pub fn main() { + let x : &[isize] = &[1,2,3,4,5]; + let mut z : &[isize] = &[1,2,3,4,5]; + z = x; + assert_eq!(z[0], 1); + assert_eq!(z[4], 5); + + let a : &[isize] = &[1,1,1,1,1]; + let b : &[isize] = &[2,2,2,2,2]; + let c : &[isize] = &[2,2,2,2,3]; + let cc : &[isize] = &[2,2,2,2,2,2]; + + println!("{:?}", a); + + assert!(a < b); + assert!(a <= b); + assert!(a != b); + assert!(b >= a); + assert!(b > a); + + println!("{:?}", b); + + assert!(b < c); + assert!(b <= c); + assert!(b != c); + assert!(c >= b); + assert!(c > b); + + assert!(a < c); + assert!(a <= c); + assert!(a != c); + assert!(c >= a); + assert!(c > a); + + println!("{:?}", c); + + assert!(a < cc); + assert!(a <= cc); + assert!(a != cc); + assert!(cc >= a); + assert!(cc > a); + + println!("{:?}", cc); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/fixed_length_copy.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/fixed_length_copy.rs new file mode 100644 index 000000000000..e30f8ac72724 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/fixed_length_copy.rs @@ -0,0 +1,10 @@ +// run-pass + + +pub fn main() { + let arr = [1,2,3]; + let arr2 = arr; + assert_eq!(arr[1], 2); + assert_eq!(arr2[2], 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/huge-largest-array.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/huge-largest-array.rs new file mode 100644 index 000000000000..b750b23a936d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/huge-largest-array.rs @@ -0,0 +1,15 @@ +// run-pass + + +use std::mem::size_of; + +#[cfg(target_pointer_width = "32")] +pub fn main() { + assert_eq!(size_of::<[u8; (1 << 31) - 1]>(), (1 << 31) - 1); +} + +#[cfg(target_pointer_width = "64")] +pub fn main() { + assert_eq!(size_of::<[u8; (1 << 47) - 1]>(), (1 << 47) - 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/infer_array_len.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/infer_array_len.rs new file mode 100644 index 000000000000..35f2e42b634f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/infer_array_len.rs @@ -0,0 +1,22 @@ +// see issue #70529 +struct A; + +impl From for [u8; 2] { + fn from(a: A) -> Self { + [0; 2] + } +} + +impl From for [u8; 3] { + fn from(a: A) -> Self { + [0; 3] + } +} + + +fn main() { + let a = A; + let [_, _] = a.into(); +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/issue-69103-extra-binding-subslice.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/issue-69103-extra-binding-subslice.rs new file mode 100644 index 000000000000..237955271879 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/issue-69103-extra-binding-subslice.rs @@ -0,0 +1,19 @@ +// We used to not lower the extra `b @ ..` into `b @ _` which meant that no type +// was registered for the binding `b` although it passed through resolve. +// This resulted in an ICE (#69103). + +fn main() { + let [a @ .., b @ ..] = &mut [1, 2]; +// { dg-error "" "" { target *-*-* } .-1 } + b; + + let [.., c @ ..] = [1, 2]; +// { dg-error "" "" { target *-*-* } .-1 } + c; + + // This never ICEd, but let's make sure it won't regress either. + let (.., d @ ..) = (1, 2); +// { dg-error "" "" { target *-*-* } .-1 } + d; +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/ivec-pass-by-value.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/ivec-pass-by-value.rs new file mode 100644 index 000000000000..4c4c40953f5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/ivec-pass-by-value.rs @@ -0,0 +1,5 @@ +// run-pass + +fn f(_a: Vec ) { } +pub fn main() { f(vec![1, 2, 3, 4, 5]); } + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/match_arr_unknown_len.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/match_arr_unknown_len.rs new file mode 100644 index 000000000000..80421f0ec155 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/match_arr_unknown_len.rs @@ -0,0 +1,12 @@ +#![feature(const_generics)] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn is_123(x: [u32; N]) -> bool { + match x { + [1, 2] => true, // { dg-error ".E0308." "" { target *-*-* } } + _ => false + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs new file mode 100644 index 000000000000..19fc0f741d2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/mutability-inherits-through-fixed-length-vec.rs @@ -0,0 +1,20 @@ +// run-pass + + +fn test1() { + let mut ints = [0; 32]; + ints[0] += 1; + assert_eq!(ints[0], 1); +} + +fn test2() { + let mut ints = [0; 32]; + for i in &mut ints { *i += 22; } + for i in &ints { assert_eq!(*i, 22); } +} + +pub fn main() { + test1(); + test2(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/mutable-alias-vec.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/mutable-alias-vec.rs new file mode 100644 index 000000000000..65bae7f044c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/mutable-alias-vec.rs @@ -0,0 +1,16 @@ +// run-pass + +fn grow(v: &mut Vec ) { + v.push(1); +} + +pub fn main() { + let mut v: Vec = Vec::new(); + grow(&mut v); + grow(&mut v); + grow(&mut v); + let len = v.len(); + println!("{}", len); + assert_eq!(len, 3 as usize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/nested-vec-1.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/nested-vec-1.rs new file mode 100644 index 000000000000..471e0b22ccf2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/nested-vec-1.rs @@ -0,0 +1,9 @@ +// run-pass + +// Test that using the `vec!` macro nested within itself works + +fn main() { + let nested = vec![vec![1u32, 2u32, 3u32]]; + assert_eq!(nested[0][1], 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/nested-vec-2.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/nested-vec-2.rs new file mode 100644 index 000000000000..dc745c0a53e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/nested-vec-2.rs @@ -0,0 +1,16 @@ +// run-pass + +// Test that using the `vec!` macro nested within itself works +// when the contents implement Drop + +struct D(u32); + +impl Drop for D { + fn drop(&mut self) { println!("Dropping {}", self.0); } +} + +fn main() { + let nested = vec![vec![D(1u32), D(2u32), D(3u32)]]; + assert_eq!(nested[0][1].0, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/nested-vec-3.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/nested-vec-3.rs new file mode 100644 index 000000000000..397a063f97ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/nested-vec-3.rs @@ -0,0 +1,55 @@ +// run-pass +#![allow(overflowing_literals)] + +// ignore-emscripten no threads support + +// Test that using the `vec!` macro nested within itself works when +// the contents implement Drop and we hit a panic in the middle of +// construction. + +use std::thread; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static LOG: AtomicUsize = AtomicUsize::new(0); + +struct D(u8); + +impl Drop for D { + fn drop(&mut self) { + println!("Dropping {}", self.0); + let old = LOG.load(Ordering::SeqCst); + LOG.compare_and_swap(old, old << 4 | self.0 as usize, Ordering::SeqCst); + } +} + +fn main() { + fn die() -> D { panic!("Oh no"); } + let g = thread::spawn(|| { + let _nested = vec![vec![D( 1), D( 2), D( 3), D( 4)], + vec![D( 5), D( 6), D( 7), D( 8)], + vec![D( 9), D(10), die(), D(12)], + vec![D(13), D(14), D(15), D(16)]]; + }); + assert!(g.join().is_err()); + + // When the panic occurs, we will be in the midst of constructing the + // second inner vector. Therefore, we drop the elements of the + // partially filled vector first, before we get around to dropping + // the elements of the filled vector. + + // Issue 23222: The order in which the elements actually get + // dropped is a little funky: as noted above, we'll drop the 9+10 + // first, but due to #23222, they get dropped in reverse + // order. Likewise, again due to #23222, we will drop the second + // filled vec before the first filled vec. + // + // If Issue 23222 is "fixed", then presumably the corrected + // expected order of events will be 0x__9_A__1_2_3_4__5_6_7_8; + // that is, we would still drop 9+10 first, since they belong to + // the more deeply nested expression when the panic occurs. + + let expect = 0x__A_9__5_6_7_8__1_2_3_4; + let actual = LOG.load(Ordering::SeqCst); + assert!(actual == expect, "expect: 0x{:x} actual: 0x{:x}", expect, actual); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/new-style-fixed-length-vec.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/new-style-fixed-length-vec.rs new file mode 100644 index 000000000000..db153ffa5b80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/new-style-fixed-length-vec.rs @@ -0,0 +1,8 @@ +// run-pass + +static FOO: [isize; 3] = [1, 2, 3]; + +pub fn main() { + println!("{} {} {}", FOO[0], FOO[1], FOO[2]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/rcvr-borrowed-to-slice.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/rcvr-borrowed-to-slice.rs new file mode 100644 index 000000000000..1eae312206bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/rcvr-borrowed-to-slice.rs @@ -0,0 +1,34 @@ +// run-pass + +#![allow(non_camel_case_types)] + +trait sum { + fn sum_(self) -> isize; +} + +// Note: impl on a slice +impl<'a> sum for &'a [isize] { + fn sum_(self) -> isize { + self.iter().fold(0, |a, &b| a + b) + } +} + +fn call_sum(x: &[isize]) -> isize { x.sum_() } + +pub fn main() { + let x = vec![1, 2, 3]; + let y = call_sum(&x); + println!("y=={}", y); + assert_eq!(y, 6); + + let x = vec![1, 2, 3]; + let y = x.sum_(); + println!("y=={}", y); + assert_eq!(y, 6); + + let x = vec![1, 2, 3]; + let y = x.sum_(); + println!("y=={}", y); + assert_eq!(y, 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/repeated-vector-syntax.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/repeated-vector-syntax.rs new file mode 100644 index 000000000000..87ddae906cc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/repeated-vector-syntax.rs @@ -0,0 +1,14 @@ +// run-pass + +pub fn main() { + let x = [ [true]; 512 ]; + let y = [ 0; 1 ]; + + print!("["); + for xi in &x[..] { + print!("{:?}, ", &xi[..]); + } + println!("]"); + println!("{:?}", &y[..]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/show-boxed-slice.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/show-boxed-slice.rs new file mode 100644 index 000000000000..5cf236b44f07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/show-boxed-slice.rs @@ -0,0 +1,9 @@ +// run-pass + +#[derive(Debug)] +struct Foo(Box<[u8]>); + +pub fn main() { + println!("{:?}", Foo(Box::new([0, 1, 2]))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-of-zero-size-elements.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-of-zero-size-elements.rs new file mode 100644 index 000000000000..3d4b42d4bbd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-of-zero-size-elements.rs @@ -0,0 +1,54 @@ +// run-pass +#![allow(stable_features)] + +// compile-flags: -C debug-assertions + +#![feature(iter_to_slice)] + +use std::slice; + +fn foo(v: &[T]) -> Option<&[T]> { + let mut it = v.iter(); + for _ in 0..5 { + let _ = it.next(); + } + Some(it.as_slice()) +} + +fn foo_mut(v: &mut [T]) -> Option<&mut [T]> { + let mut it = v.iter_mut(); + for _ in 0..5 { + let _ = it.next(); + } + Some(it.into_slice()) +} + +pub fn main() { + // In a slice of zero-size elements the pointer is meaningless. + // Ensure iteration still works even if the pointer is at the end of the address space. + let slice: &[()] = unsafe { slice::from_raw_parts(-5isize as *const (), 10) }; + assert_eq!(slice.len(), 10); + assert_eq!(slice.iter().count(), 10); + + // .nth() on the iterator should also behave correctly + let mut it = slice.iter(); + assert!(it.nth(5).is_some()); + assert_eq!(it.count(), 4); + + // Converting Iter to a slice should never have a null pointer + assert!(foo(slice).is_some()); + + // Test mutable iterators as well + let slice: &mut [()] = unsafe { slice::from_raw_parts_mut(-5isize as *mut (), 10) }; + assert_eq!(slice.len(), 10); + assert_eq!(slice.iter_mut().count(), 10); + + { + let mut it = slice.iter_mut(); + assert!(it.nth(5).is_some()); + assert_eq!(it.count(), 4); + } + + assert!(foo_mut(slice).is_some()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-panic-1.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-panic-1.rs new file mode 100644 index 000000000000..70ee2786387d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-panic-1.rs @@ -0,0 +1,27 @@ +// run-pass + +// ignore-emscripten no threads support + +// Test that if a slicing expr[..] fails, the correct cleanups happen. + + +use std::thread; + +struct Foo; + +static mut DTOR_COUNT: isize = 0; + +impl Drop for Foo { + fn drop(&mut self) { unsafe { DTOR_COUNT += 1; } } +} + +fn foo() { + let x: &[_] = &[Foo, Foo]; + &x[3..4]; +} + +fn main() { + let _ = thread::spawn(move|| foo()).join(); + unsafe { assert_eq!(DTOR_COUNT, 2); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-panic-2.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-panic-2.rs new file mode 100644 index 000000000000..8f97c4121f5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-panic-2.rs @@ -0,0 +1,31 @@ +// run-pass + +// ignore-emscripten no threads support + +// Test that if a slicing expr[..] fails, the correct cleanups happen. + + +use std::thread; + +struct Foo; + +static mut DTOR_COUNT: isize = 0; + +impl Drop for Foo { + fn drop(&mut self) { unsafe { DTOR_COUNT += 1; } } +} + +fn bar() -> usize { + panic!(); +} + +fn foo() { + let x: &[_] = &[Foo, Foo]; + &x[3..bar()]; +} + +fn main() { + let _ = thread::spawn(move|| foo()).join(); + unsafe { assert_eq!(DTOR_COUNT, 2); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-pat-type-mismatches.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-pat-type-mismatches.rs new file mode 100644 index 000000000000..a07464e46310 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice-pat-type-mismatches.rs @@ -0,0 +1,37 @@ +fn main() { + match "foo".to_string() { + ['f', 'o', ..] => {} +// { dg-error ".E0529." "" { target *-*-* } .-1 } + _ => { } + }; + + // Note that this one works with default binding modes. + match &[0, 1, 2] { + [..] => {} + }; + + match &[0, 1, 2] { + &[..] => {} // ok + }; + + match [0, 1, 2] { + [0] => {}, // { dg-error ".E0527." "" { target *-*-* } } + + [0, 1, x @ ..] => { + let a: [_; 1] = x; + } + [0, 1, 2, 3, x @ ..] => {} // { dg-error ".E0528." "" { target *-*-* } } + }; + + match does_not_exist { // { dg-error ".E0425." "" { target *-*-* } } + [] => {} + }; +} + +fn another_fn_to_avoid_suppression() { + match Default::default() + { + [] => {} // { dg-error ".E0282." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice.rs new file mode 100644 index 000000000000..de8f073aa084 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice.rs @@ -0,0 +1,82 @@ +// run-pass +#![allow(unused_variables)] + +// Test slicing sugar. + +extern crate core; +use core::ops::{Index, IndexMut, Range, RangeTo, RangeFrom, RangeFull}; + +static mut COUNT: usize = 0; + +struct Foo; + +impl Index> for Foo { + type Output = Foo; + fn index(&self, index: Range) -> &Foo { + unsafe { COUNT += 1; } + self + } +} +impl Index> for Foo { + type Output = Foo; + fn index(&self, index: RangeTo) -> &Foo { + unsafe { COUNT += 1; } + self + } +} +impl Index> for Foo { + type Output = Foo; + fn index(&self, index: RangeFrom) -> &Foo { + unsafe { COUNT += 1; } + self + } +} +impl Index for Foo { + type Output = Foo; + fn index(&self, _index: RangeFull) -> &Foo { + unsafe { COUNT += 1; } + self + } +} + +impl IndexMut> for Foo { + fn index_mut(&mut self, index: Range) -> &mut Foo { + unsafe { COUNT += 1; } + self + } +} +impl IndexMut> for Foo { + fn index_mut(&mut self, index: RangeTo) -> &mut Foo { + unsafe { COUNT += 1; } + self + } +} +impl IndexMut> for Foo { + fn index_mut(&mut self, index: RangeFrom) -> &mut Foo { + unsafe { COUNT += 1; } + self + } +} +impl IndexMut for Foo { + fn index_mut(&mut self, _index: RangeFull) -> &mut Foo { + unsafe { COUNT += 1; } + self + } +} + + +fn main() { + let mut x = Foo; + &x[..]; + &x[Foo..]; + &x[..Foo]; + &x[Foo..Foo]; + &mut x[..]; + &mut x[Foo..]; + &mut x[..Foo]; + &mut x[Foo..Foo]; + unsafe { + assert_eq!(COUNT, 8); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice_binary_search.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice_binary_search.rs new file mode 100644 index 000000000000..f25ac4db430b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/slice_binary_search.rs @@ -0,0 +1,22 @@ +// run-pass + +// Test binary_search_by_key lifetime. Issue #34683 + +#[derive(Debug)] +struct Assignment { + topic: String, + partition: i32, +} + +fn main() { + let xs = vec![ + Assignment { topic: "abc".into(), partition: 1 }, + Assignment { topic: "def".into(), partition: 2 }, + Assignment { topic: "ghi".into(), partition: 3 }, + ]; + + let key: &str = "def"; + let r = xs.binary_search_by_key(&key, |e| &e.topic); + assert_eq!(Ok(1), r.map(|i| i)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs new file mode 100644 index 000000000000..8bcc50003f1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs @@ -0,0 +1,12 @@ +fn main() { + let a: &[u8] = &[]; + match a { + [1, tail @ .., tail @ ..] => {}, +// { dg-error ".E0416." "" { target *-*-* } .-1 } +// { dg-error ".E0416." "" { target *-*-* } .-2 } + _ => () + } +} + +const RECOVERY_WITNESS: () = 0; // { dg-error ".E0308." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/subslice-patterns-const-eval-match.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/subslice-patterns-const-eval-match.rs new file mode 100644 index 000000000000..8b9707daaf11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/subslice-patterns-const-eval-match.rs @@ -0,0 +1,99 @@ +// Test that slice subslice patterns are correctly handled in const evaluation. + +// run-pass + +#![feature(const_fn)] + +#[derive(PartialEq, Debug, Clone)] +struct N(u8); + +#[derive(PartialEq, Debug, Clone)] +struct Z; + +macro_rules! n { + ($($e:expr),* $(,)?) => { + [$(N($e)),*] + } +} + +// This macro has an unused variable so that it can be repeated base on the +// number of times a repeated variable (`$e` in `z`) occurs. +macro_rules! zed { + ($e:expr) => { Z } +} + +macro_rules! z { + ($($e:expr),* $(,)?) => { + [$(zed!($e)),*] + } +} + +// Compare constant evaluation and runtime evaluation of a given expression. +macro_rules! compare_evaluation_inner { + ($e:expr, $t:ty $(,)?) => {{ + const CONST_EVAL: $t = $e; + const fn const_eval() -> $t { $e } + static CONST_EVAL2: $t = const_eval(); + let runtime_eval = $e; + assert_eq!(CONST_EVAL, runtime_eval); + assert_eq!(CONST_EVAL2, runtime_eval); + }} +} + +// Compare the result of matching `$e` against `$p` using both `if let` and +// `match`. +macro_rules! compare_evaluation { + ($p:pat, $e:expr, $matches:expr, $t:ty $(,)?) => {{ + compare_evaluation_inner!(if let $p = $e as &[_] { $matches } else { None }, $t); + compare_evaluation_inner!(match $e as &[_] { $p => $matches, _ => None }, $t); + }} +} + +// Repeat `$test`, substituting the given macro variables with the given +// identifiers. +// +// For example: +// +// repeat! { +// ($name); X; Y: +// struct $name; +// } +// +// Expands to: +// +// struct X; struct Y; +// +// This is used to repeat the tests using both the `N` and `Z` +// types. +macro_rules! repeat { + (($($dollar:tt $placeholder:ident)*); $($($values:ident),+);*: $($test:tt)*) => { + macro_rules! single { + ($($dollar $placeholder:ident),*) => { $($test)* } + } + $(single!($($values),+);)* + } +} + +fn main() { + repeat! { + ($arr $Ty); n, N; z, Z: + compare_evaluation!([_, x @ .., _], &$arr!(1, 2, 3, 4), Some(x), Option<&'static [$Ty]>); + compare_evaluation!([x, .., _], &$arr!(1, 2, 3, 4), Some(x), Option<&'static $Ty>); + compare_evaluation!([_, .., x], &$arr!(1, 2, 3, 4), Some(x), Option<&'static $Ty>); + + compare_evaluation!([_, x @ .., _], &$arr!(1, 2), Some(x), Option<&'static [$Ty]>); + compare_evaluation!([x, .., _], &$arr!(1, 2), Some(x), Option<&'static $Ty>); + compare_evaluation!([_, .., x], &$arr!(1, 2), Some(x), Option<&'static $Ty>); + + compare_evaluation!([_, x @ .., _], &$arr!(1), Some(x), Option<&'static [$Ty]>); + compare_evaluation!([x, .., _], &$arr!(1), Some(x), Option<&'static $Ty>); + compare_evaluation!([_, .., x], &$arr!(1), Some(x), Option<&'static $Ty>); + } + + compare_evaluation!([N(x), .., _], &n!(1, 2, 3, 4), Some(x), Option<&'static u8>); + compare_evaluation!([_, .., N(x)], &n!(1, 2, 3, 4), Some(x), Option<&'static u8>); + + compare_evaluation!([N(x), .., _], &n!(1, 2), Some(x), Option<&'static u8>); + compare_evaluation!([_, .., N(x)], &n!(1, 2), Some(x), Option<&'static u8>); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/subslice-patterns-const-eval.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/subslice-patterns-const-eval.rs new file mode 100644 index 000000000000..c97ac305dad3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/subslice-patterns-const-eval.rs @@ -0,0 +1,96 @@ +// Test that array subslice patterns are correctly handled in const evaluation. + +// run-pass + +#[derive(PartialEq, Debug, Clone)] +struct N(u8); + +#[derive(PartialEq, Debug, Clone)] +struct Z; + +macro_rules! n { + ($($e:expr),* $(,)?) => { + [$(N($e)),*] + } +} + +// This macro has an unused variable so that it can be repeated base on the +// number of times a repeated variable (`$e` in `z`) occurs. +macro_rules! zed { + ($e:expr) => { Z } +} + +macro_rules! z { + ($($e:expr),* $(,)?) => { + [$(zed!($e)),*] + } +} + +// Compare constant evaluation and runtime evaluation of a given expression. +macro_rules! compare_evaluation { + ($e:expr, $t:ty $(,)?) => {{ + const CONST_EVAL: $t = $e; + const fn const_eval() -> $t { $e } + static CONST_EVAL2: $t = const_eval(); + let runtime_eval = $e; + assert_eq!(CONST_EVAL, runtime_eval); + assert_eq!(CONST_EVAL2, runtime_eval); + }} +} + +// Repeat `$test`, substituting the given macro variables with the given +// identifiers. +// +// For example: +// +// repeat! { +// ($name); X; Y: +// struct $name; +// } +// +// Expands to: +// +// struct X; struct Y; +// +// This is used to repeat the tests using both the `N` and `Z` +// types. +macro_rules! repeat { + (($($dollar:tt $placeholder:ident)*); $($($values:ident),+);*: $($test:tt)*) => { + macro_rules! single { + ($($dollar $placeholder:ident),*) => { $($test)* } + } + $(single!($($values),+);)* + } +} + +fn main() { + repeat! { + ($arr $Ty); n, N; z, Z: + compare_evaluation!({ let [_, x @ .., _] = $arr!(1, 2, 3, 4); x }, [$Ty; 2]); + compare_evaluation!({ let [_, ref x @ .., _] = $arr!(1, 2, 3, 4); x }, &'static [$Ty; 2]); + compare_evaluation!({ let [_, x @ .., _] = &$arr!(1, 2, 3, 4); x }, &'static [$Ty; 2]); + + compare_evaluation!({ let [_, _, x @ .., _, _] = $arr!(1, 2, 3, 4); x }, [$Ty; 0]); + compare_evaluation!( + { let [_, _, ref x @ .., _, _] = $arr!(1, 2, 3, 4); x }, + &'static [$Ty; 0], + ); + compare_evaluation!( + { let [_, _, x @ .., _, _] = &$arr!(1, 2, 3, 4); x }, + &'static [$Ty; 0], + ); + + compare_evaluation!({ let [_, .., x] = $arr!(1, 2, 3, 4); x }, $Ty); + compare_evaluation!({ let [_, .., ref x] = $arr!(1, 2, 3, 4); x }, &'static $Ty); + compare_evaluation!({ let [_, _y @ .., x] = &$arr!(1, 2, 3, 4); x }, &'static $Ty); + } + + compare_evaluation!({ let [_, .., N(x)] = n!(1, 2, 3, 4); x }, u8); + compare_evaluation!({ let [_, .., N(ref x)] = n!(1, 2, 3, 4); x }, &'static u8); + compare_evaluation!({ let [_, .., N(x)] = &n!(1, 2, 3, 4); x }, &'static u8); + + compare_evaluation!({ let [N(x), .., _] = n!(1, 2, 3, 4); x }, u8); + compare_evaluation!({ let [N(ref x), .., _] = n!(1, 2, 3, 4); x }, &'static u8); + compare_evaluation!({ let [N(x), .., _] = &n!(1, 2, 3, 4); x }, &'static u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/variance-vec-covariant.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/variance-vec-covariant.rs new file mode 100644 index 000000000000..fc4028c37488 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/variance-vec-covariant.rs @@ -0,0 +1,21 @@ +// run-pass + +// Test that vec is now covariant in its argument type. + +#![allow(dead_code)] + +fn foo<'a,'b>(v1: Vec<&'a i32>, v2: Vec<&'b i32>) -> i32 { + bar(v1, v2).cloned().unwrap_or(0) // only type checks if we can intersect 'a and 'b +} + +fn bar<'c>(v1: Vec<&'c i32>, v2: Vec<&'c i32>) -> Option<&'c i32> { + v1.get(0).cloned().or_else(|| v2.get(0).cloned()) +} + +fn main() { + let x = 22; + let y = 44; + assert_eq!(foo(vec![&x], vec![&y]), 22); + assert_eq!(foo(vec![&y], vec![&x]), 44); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-dst.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-dst.rs new file mode 100644 index 000000000000..12a3ad724ab2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-dst.rs @@ -0,0 +1,27 @@ +// run-pass + +#![feature(box_syntax)] + +pub fn main() { + // Tests for indexing into box/& [T; n] + let x: [isize; 3] = [1, 2, 3]; + let mut x: Box<[isize; 3]> = box x; + assert_eq!(x[0], 1); + assert_eq!(x[1], 2); + assert_eq!(x[2], 3); + x[1] = 45; + assert_eq!(x[0], 1); + assert_eq!(x[1], 45); + assert_eq!(x[2], 3); + + let mut x: [isize; 3] = [1, 2, 3]; + let x: &mut [isize; 3] = &mut x; + assert_eq!(x[0], 1); + assert_eq!(x[1], 2); + assert_eq!(x[2], 3); + x[1] = 45; + assert_eq!(x[0], 1); + assert_eq!(x[1], 45); + assert_eq!(x[2], 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-fixed-length.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-fixed-length.rs new file mode 100644 index 000000000000..71f26b0d70ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-fixed-length.rs @@ -0,0 +1,25 @@ +// run-pass + + +use std::mem::size_of; + +#[cfg(not(target_pointer_width = "64"))] +fn test_big_vec() {} + +#[cfg(target_pointer_width = "64")] +fn test_big_vec() +{ + assert_eq!(size_of::<[u8; 1 << 32]>(), (1 << 32)); +} + +fn main() { + let x: [isize; 4] = [1, 2, 3, 4]; + assert_eq!(x[0], 1); + assert_eq!(x[1], 2); + assert_eq!(x[2], 3); + assert_eq!(x[3], 4); + + assert_eq!(size_of::<[u8; 4]>(), 4); + test_big_vec(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-late-init.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-late-init.rs new file mode 100644 index 000000000000..41f416f811ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-late-init.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(unused_mut)] + + +pub fn main() { + let mut later: Vec ; + if true { later = vec![1]; } else { later = vec![2]; } + println!("{}", later[0]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-no-std.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-no-std.rs new file mode 100644 index 000000000000..4498a8976605 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-no-std.rs @@ -0,0 +1,28 @@ +// run-pass + +// ignore-emscripten no no_std executables + +#![feature(lang_items, start, rustc_private)] +#![no_std] + +extern crate std as other; + +extern crate libc; + +#[macro_use] +extern crate alloc; + +use alloc::vec::Vec; + +// Issue #16806 + +#[start] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + let x: Vec = vec![0, 1, 2]; + match x.last() { + Some(&2) => (), + _ => panic!(), + } + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-rvalue-scope.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-rvalue-scope.rs new file mode 100644 index 000000000000..2d6df0b160f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-rvalue-scope.rs @@ -0,0 +1,12 @@ +// run-pass + + +fn one() -> i32 { 1 } + +// Make sure the vec![...] macro doesn't introduce hidden rvalue +// scopes (such as blocks) around the element expressions. +pub fn main() { + assert_eq!(vec![&one(), &one(), &2], vec![&1, &1, &(one()+one())]); + assert_eq!(vec![&one(); 2], vec![&1, &one()]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-with-brackets.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-with-brackets.rs new file mode 100644 index 000000000000..3b51642843ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-with-brackets.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(unused_variables)] + +// pretty-expanded FIXME #23616 + +macro_rules! vec [ + ($($e:expr),*) => ({ + let mut _temp = ::std::vec::Vec::new(); + $(_temp.push($e);)* + _temp + }) +]; + +pub fn main() { + let my_vec = vec![1, 2, 3, 4, 5]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-with-trailing-comma.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-with-trailing-comma.rs new file mode 100644 index 000000000000..b06114b04fc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-macro-with-trailing-comma.rs @@ -0,0 +1,9 @@ +// run-pass + + + +pub fn main() { + assert_eq!(vec![1], vec![1,]); + assert_eq!(vec![1, 2, 3], vec![1, 2, 3,]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-autoslice.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-autoslice.rs new file mode 100644 index 000000000000..1a50d642196c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-autoslice.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(illegal_floating_point_literal_pattern)] // FIXME #41620 + +pub fn main() { + let x = [1, 2, 3]; + match x { + [2, _, _] => panic!(), + [1, a, b] => { + assert_eq!([a, b], [2, 3]); + } + [_, _, _] => panic!(), + } + + let y = ([(1, true), (2, false)], 0.5f64); + match y { + ([(1, a), (b, false)], _) => { + assert_eq!(a, true); + assert_eq!(b, 2); + } + ([_, _], 0.5) => panic!(), + ([_, _], _) => panic!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-fixed.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-fixed.rs new file mode 100644 index 000000000000..41cd49fd8867 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-fixed.rs @@ -0,0 +1,31 @@ +// run-pass + +fn a() { + let x = [1, 2, 3]; + match x { + [1, 2, 4] => unreachable!(), + [0, 2, 3, ..] => unreachable!(), + [0, .., 3] => unreachable!(), + [0, ..] => unreachable!(), + [1, 2, 3] => (), + [_, _, _] => unreachable!(), + } + match x { + [..] => (), + } + match x { + [_, _, _, ..] => (), + } + match x { + [a, b, c] => { + assert_eq!(1, a); + assert_eq!(2, b); + assert_eq!(3, c); + } + } +} + +pub fn main() { + a(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-fold.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-fold.rs new file mode 100644 index 000000000000..49ff1db253fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-fold.rs @@ -0,0 +1,47 @@ +// run-pass + +use std::fmt::Debug; + +fn foldl(values: &[T], + initial: U, + mut function: F) + -> U where + U: Clone+Debug, T:Debug, + F: FnMut(U, &T) -> U, +{ match values { + &[ref head, ref tail @ ..] => + foldl(tail, function(initial, head), function), + &[] => { + // FIXME: call guards + let res = initial.clone(); res + } + } +} + +fn foldr(values: &[T], + initial: U, + mut function: F) + -> U where + U: Clone, + F: FnMut(&T, U) -> U, +{ + match values { + &[ref head @ .., ref tail] => + foldr(head, function(tail, initial), function), + &[] => { + // FIXME: call guards + let res = initial.clone(); res + } + } +} + +pub fn main() { + let x = &[1, 2, 3, 4, 5]; + + let product = foldl(x, 1, |a, b| a * *b); + assert_eq!(product, 120); + + let sum = foldr(x, 0, |a, b| *a + b); + assert_eq!(sum, 15); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs new file mode 100644 index 000000000000..ba6e177074c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(unused_variables)] + +pub fn main() { + let x = &[1, 2, 3, 4, 5]; + let x: &[isize] = &[1, 2, 3, 4, 5]; + if !x.is_empty() { + let el = match x { + &[1, ref tail @ ..] => &tail[0], + _ => unreachable!() + }; + println!("{}", *el); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching.rs new file mode 100644 index 000000000000..3eddf873300e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-matching.rs @@ -0,0 +1,143 @@ +// run-pass + +fn a() { + let x = [1]; + match x { + [a] => { + assert_eq!(a, 1); + } + } +} + +fn b() { + let x = [1, 2, 3]; + match x { + [a, b, c @ ..] => { + assert_eq!(a, 1); + assert_eq!(b, 2); + let expected: &[_] = &[3]; + assert_eq!(c, expected); + } + } + match x { + [a @ .., b, c] => { + let expected: &[_] = &[1]; + assert_eq!(a, expected); + assert_eq!(b, 2); + assert_eq!(c, 3); + } + } + match x { + [a, b @ .., c] => { + assert_eq!(a, 1); + let expected: &[_] = &[2]; + assert_eq!(b, expected); + assert_eq!(c, 3); + } + } + match x { + [a, b, c] => { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + } + } +} + + +fn b_slice() { + let x : &[_] = &[1, 2, 3]; + match x { + &[a, b, ref c @ ..] => { + assert_eq!(a, 1); + assert_eq!(b, 2); + let expected: &[_] = &[3]; + assert_eq!(c, expected); + } + _ => unreachable!() + } + match x { + &[ref a @ .., b, c] => { + let expected: &[_] = &[1]; + assert_eq!(a, expected); + assert_eq!(b, 2); + assert_eq!(c, 3); + } + _ => unreachable!() + } + match x { + &[a, ref b @ .., c] => { + assert_eq!(a, 1); + let expected: &[_] = &[2]; + assert_eq!(b, expected); + assert_eq!(c, 3); + } + _ => unreachable!() + } + match x { + &[a, b, c] => { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + } + _ => unreachable!() + } +} + +fn c() { + let x = [1]; + match x { + [2, ..] => panic!(), + [..] => () + } +} + +fn d() { + let x = [1, 2, 3]; + let branch = match x { + [1, 1, ..] => 0, + [1, 2, 3, ..] => 1, + [1, 2, ..] => 2, + _ => 3 + }; + assert_eq!(branch, 1); +} + +fn e() { + let x: &[isize] = &[1, 2, 3]; + let a = match *x { + [1, 2] => 0, + [..] => 1, + }; + + assert_eq!(a, 1); + + let b = match *x { + [2, ..] => 0, + [1, 2, ..] => 1, + [_] => 2, + [..] => 3 + }; + + assert_eq!(b, 1); + + + let c = match *x { + [_, _, _, _, ..] => 0, + [1, 2, ..] => 1, + [_] => 2, + [..] => 3 + }; + + assert_eq!(c, 1); +} + +pub fn main() { + a(); + b(); + b_slice(); + c(); + d(); + e(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-repeat-with-cast.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-repeat-with-cast.rs new file mode 100644 index 000000000000..45d69c28116a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-repeat-with-cast.rs @@ -0,0 +1,6 @@ +// run-pass + +// pretty-expanded FIXME #23616 + +pub fn main() { let _a = [0; 1 as usize]; } + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-tail-matching.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-tail-matching.rs new file mode 100644 index 000000000000..95a031b6196a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vec-tail-matching.rs @@ -0,0 +1,35 @@ +// run-pass + +struct Foo { + string: &'static str +} + +pub fn main() { + let x = [ + Foo { string: "foo" }, + Foo { string: "bar" }, + Foo { string: "baz" } + ]; + match x { + [ref first, ref tail @ ..] => { + assert_eq!(first.string, "foo"); + assert_eq!(tail.len(), 2); + assert_eq!(tail[0].string, "bar"); + assert_eq!(tail[1].string, "baz"); + + match *(tail as &[_]) { + [Foo { .. }, _, Foo { .. }, ref _tail @ ..] => { + unreachable!(); + } + [Foo { string: ref a }, Foo { string: ref b }] => { + assert_eq!("bar", &a[0..a.len()]); + assert_eq!("baz", &b[0..b.len()]); + } + _ => { + unreachable!(); + } + } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/array-slice-vec/vector-no-ann-2.rs b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vector-no-ann-2.rs new file mode 100644 index 000000000000..4d794b0be142 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array-slice-vec/vector-no-ann-2.rs @@ -0,0 +1,8 @@ +// run-pass + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { let _quux: Box> = box Vec::new(); } + diff --git a/gcc/testsuite/rust/rustc/ui/array_const_index-0.rs b/gcc/testsuite/rust/rustc/ui/array_const_index-0.rs new file mode 100644 index 000000000000..50cb4739489f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array_const_index-0.rs @@ -0,0 +1,9 @@ +const A: &'static [i32] = &[]; +const B: i32 = (&A)[1]; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { + let _ = B; +} + diff --git a/gcc/testsuite/rust/rustc/ui/array_const_index-1.rs b/gcc/testsuite/rust/rustc/ui/array_const_index-1.rs new file mode 100644 index 000000000000..1b2914c5f472 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/array_const_index-1.rs @@ -0,0 +1,9 @@ +const A: [i32; 0] = []; +const B: i32 = A[1]; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { + let _ = B; +} + diff --git a/gcc/testsuite/rust/rustc/ui/artificial-block.rs b/gcc/testsuite/rust/rustc/ui/artificial-block.rs new file mode 100644 index 000000000000..2e419a67facd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/artificial-block.rs @@ -0,0 +1,6 @@ +// run-pass + +fn f() -> isize { { return 3; } } + +pub fn main() { assert_eq!(f(), 3); } + diff --git a/gcc/testsuite/rust/rustc/ui/as-precedence.rs b/gcc/testsuite/rust/rustc/ui/as-precedence.rs new file mode 100644 index 000000000000..0b19bb5bc848 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/as-precedence.rs @@ -0,0 +1,11 @@ +// run-pass + +#[allow(unused_parens)] +fn main() { + assert_eq!(3 as usize * 3, 9); + assert_eq!(3 as (usize) * 3, 9); + assert_eq!(3 as (usize) / 3, 1); + assert_eq!(3 as usize + 3, 6); + assert_eq!(3 as (usize) + 3, 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/bad-arch.rs b/gcc/testsuite/rust/rustc/ui/asm/bad-arch.rs new file mode 100644 index 000000000000..f0ea2725f0d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/bad-arch.rs @@ -0,0 +1,20 @@ +// compile-flags: --target wasm32-unknown-unknown +// needs-llvm-components: webassembly + +#![feature(no_core, lang_items, rustc_attrs)] +#![no_core] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} +#[lang = "sized"] +trait Sized {} + +fn main() { + unsafe { + asm!(""); +// { dg-error ".E0472." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/bad-options.rs b/gcc/testsuite/rust/rustc/ui/asm/bad-options.rs new file mode 100644 index 000000000000..a8d5edfd49cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/bad-options.rs @@ -0,0 +1,19 @@ +// only-x86_64 + +#![feature(asm)] + +fn main() { + let mut foo = 0; + unsafe { + asm!("", options(nomem, readonly)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", options(pure, nomem, noreturn)); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + asm!("{}", in(reg) foo, options(pure, nomem)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", out(reg) foo, options(noreturn)); +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/bad-reg.rs b/gcc/testsuite/rust/rustc/ui/asm/bad-reg.rs new file mode 100644 index 000000000000..8e066385c268 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/bad-reg.rs @@ -0,0 +1,56 @@ +// only-x86_64 +// compile-flags: -C target-feature=+avx2 + +#![feature(asm)] + +fn main() { + let mut foo = 0; + let mut bar = 0; + unsafe { + // Bad register/register class + + asm!("{}", in(foo) foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in("foo") foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{:z}", in(reg) foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{:r}", in(xmm_reg) foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{:a}", const 0); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{:a}", sym main); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(zmm_reg) foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in("zmm0") foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in("ebp") foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in("rsp") foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in("ip") foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in("st(2)") foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in("mm0") foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in("k0") foo); +// { dg-error "" "" { target *-*-* } .-1 } + + // Explicit register conflicts + // (except in/lateout which don't conflict) + + asm!("", in("eax") foo, in("al") bar); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in("rax") foo, out("rax") bar); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in("al") foo, lateout("al") bar); + asm!("", in("xmm0") foo, in("ymm0") bar); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in("xmm0") foo, out("ymm0") bar); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in("xmm0") foo, lateout("ymm0") bar); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/bad-template.rs b/gcc/testsuite/rust/rustc/ui/asm/bad-template.rs new file mode 100644 index 000000000000..a9ea45124167 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/bad-template.rs @@ -0,0 +1,29 @@ +// only-x86_64 + +#![feature(asm)] + +fn main() { + let mut foo = 0; + unsafe { + asm!("{}"); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{1}", in(reg) foo); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + asm!("{a}"); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", a = in(reg) foo); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + asm!("{1}", a = in(reg) foo); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + asm!("{}", in("eax") foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{:foo}", in(reg) foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", in(reg) 0, in(reg) 1); +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/const.rs b/gcc/testsuite/rust/rustc/ui/asm/const.rs new file mode 100644 index 000000000000..a18cb77c7712 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/const.rs @@ -0,0 +1,57 @@ +// no-system-llvm +// only-x86_64 +// run-pass + +#![feature(asm)] + +use std::mem::size_of; + +trait Proj { + const C: usize; +} +impl Proj for i8 { + const C: usize = 8; +} +impl Proj for i16 { + const C: usize = 16; +} + +const fn constfn(x: usize) -> usize { + x +} + +fn generic() { + unsafe { + let a: usize; + asm!("mov {}, {}", out(reg) a, const size_of::()); + assert_eq!(a, size_of::()); + + let b: usize; + asm!("mov {}, {}", out(reg) b, const size_of::() + constfn(5)); + assert_eq!(b, size_of::() + 5); + + let c: usize; + asm!("mov {}, {}", out(reg) c, const T::C); + assert_eq!(c, T::C); + } +} + +fn main() { + unsafe { + let a: usize; + asm!("mov {}, {}", out(reg) a, const 5); + assert_eq!(a, 5); + + let b: usize; + asm!("mov {}, {}", out(reg) b, const constfn(5)); + assert_eq!(b, 5); + + let c: usize; + asm!("mov {}, {}", out(reg) c, const constfn(5) + constfn(5)); + assert_eq!(c, 10); + } + + generic::(); + generic::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/duplicate-options.rs b/gcc/testsuite/rust/rustc/ui/asm/duplicate-options.rs new file mode 100644 index 000000000000..aa58762960c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/duplicate-options.rs @@ -0,0 +1,27 @@ +// only-x86_64 +// run-rustfix + +#![feature(asm)] + +fn main() { + unsafe { + asm!("", options(nomem, nomem)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", options(att_syntax, att_syntax)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", options(nostack, att_syntax), options(nostack)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", options(nostack, nostack), options(nostack), options(nostack)); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + asm!( + "", + options(nomem, noreturn), + options(att_syntax, noreturn), // { dg-error "" "" { target *-*-* } } + options(nomem, nostack), // { dg-error "" "" { target *-*-* } } + options(noreturn), // { dg-error "" "" { target *-*-* } } + ); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/interpolated-idents.rs b/gcc/testsuite/rust/rustc/ui/asm/interpolated-idents.rs new file mode 100644 index 000000000000..cbf5c243d861 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/interpolated-idents.rs @@ -0,0 +1,25 @@ +// only-x86_64 + +#![feature(asm)] + +macro_rules! m { + ($in:ident $out:ident $lateout:ident $inout:ident $inlateout:ident $const:ident $sym:ident + $pure:ident $nomem:ident $readonly:ident $preserves_flags:ident + $noreturn:ident $nostack:ident $att_syntax:ident $options:ident) => { + unsafe { + asm!("", $in(x) x, $out(x) x, $lateout(x) x, $inout(x) x, $inlateout(x) x, +// { dg-error "" "" { target *-*-* } .-1 } + const x, sym x, + $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack, $att_syntax)); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + } + }; +} + +fn main() { + m!(in out lateout inout inlateout const sym + pure nomem readonly preserves_flags + noreturn nostack att_syntax options); +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/issue-72570.rs b/gcc/testsuite/rust/rustc/ui/asm/issue-72570.rs new file mode 100644 index 000000000000..5c1fcfd54a0b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/issue-72570.rs @@ -0,0 +1,13 @@ +// compile-flags: -Zsave-analysis +// only-x86_64 +// Also test for #72960 + +#![feature(asm)] + +fn main() { + unsafe { + asm!("", in("invalid") "".len()); +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/noreturn.rs b/gcc/testsuite/rust/rustc/ui/asm/noreturn.rs new file mode 100644 index 000000000000..38d732ba9125 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/noreturn.rs @@ -0,0 +1,18 @@ +// only-x86_64 +// check-pass + +#![feature(asm, never_type)] +#![crate_type = "rlib"] + +pub unsafe fn asm1() { + let _: () = asm!(""); +} + +pub unsafe fn asm2() { + let _: ! = asm!("", options(noreturn)); +} + +pub unsafe fn asm3() -> ! { + asm!("", options(noreturn)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/parse-error.rs b/gcc/testsuite/rust/rustc/ui/asm/parse-error.rs new file mode 100644 index 000000000000..1a3dff72fcaf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/parse-error.rs @@ -0,0 +1,60 @@ +// only-x86_64 + +#![feature(asm)] + +fn main() { + let mut foo = 0; + let mut bar = 0; + unsafe { + asm!(); +// { dg-error "" "" { target *-*-* } .-1 } + asm!(foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}" foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(reg foo)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(reg)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", inout(=) foo => bar); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", inout(reg) foo =>); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(reg) foo => bar); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", sym foo + bar); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", options(foo)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", options(nomem foo)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", options(nomem, foo)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", options(), const foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{a}", a = const foo, a = const bar); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + asm!("", a = in("eax") foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{a}", in("eax") foo, a = const bar); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{a}", in("eax") foo, a = const bar); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{1}", in("eax") foo, const bar); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("", options(), ""); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(reg) foo, "{}", out(reg) foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!(format!("{{{}}}", 0), in(reg) foo); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/rustfix-asm.rs b/gcc/testsuite/rust/rustc/ui/asm/rustfix-asm.rs new file mode 100644 index 000000000000..515ab96fb4a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/rustfix-asm.rs @@ -0,0 +1,17 @@ +// run-rustfix +// only-x86_64 + +#![feature(asm, llvm_asm)] + +fn main() { + unsafe { + let x = 1; + let y: i32; + asm!("" :: "r" (x)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("" : "=r" (y)); +// { dg-error "" "" { target *-*-* } .-1 } + let _ = y; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/srcloc.rs b/gcc/testsuite/rust/rustc/ui/asm/srcloc.rs new file mode 100644 index 000000000000..cde0bb10ad47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/srcloc.rs @@ -0,0 +1,125 @@ +// no-system-llvm +// only-x86_64 +// build-fail + +#![feature(asm)] + +// Checks that inline asm errors are mapped to the correct line in the source code. + +fn main() { + unsafe { + asm!("invalid_instruction"); +// { dg-error "" "" { target *-*-* } .-1 } + + asm!(" + invalid_instruction + "); +// { dg-error "" "" { target *-*-* } .-2 } + + asm!(r#" + invalid_instruction + "#); +// { dg-error "" "" { target *-*-* } .-2 } + + asm!(" + mov eax, eax + invalid_instruction + mov eax, eax + "); +// { dg-error "" "" { target *-*-* } .-3 } + + asm!(r#" + mov eax, eax + invalid_instruction + mov eax, eax + "#); +// { dg-error "" "" { target *-*-* } .-3 } + + asm!(concat!("invalid", "_", "instruction")); +// { dg-error "" "" { target *-*-* } .-1 } + + asm!("movaps %xmm3, (%esi, 2)", options(att_syntax)); +// { dg-warning "" "" { target *-*-* } .-1 } + + asm!( + "invalid_instruction", + ); +// { dg-error "" "" { target *-*-* } .-2 } + + asm!( + "mov eax, eax", + "invalid_instruction", + "mov eax, eax", + ); +// { dg-error "" "" { target *-*-* } .-3 } + + asm!( + "mov eax, eax\n", + "invalid_instruction", + "mov eax, eax", + ); +// { dg-error "" "" { target *-*-* } .-3 } + + asm!( + "mov eax, eax", + concat!("invalid", "_", "instruction"), + "mov eax, eax", + ); +// { dg-error "" "" { target *-*-* } .-3 } + + asm!( + concat!("mov eax", ", ", "eax"), + concat!("invalid", "_", "instruction"), + concat!("mov eax", ", ", "eax"), + ); +// { dg-error "" "" { target *-*-* } .-3 } + + // Make sure template strings get separated + asm!( + "invalid_instruction1", + "invalid_instruction2", + ); +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-3 } + + asm!( + concat!( + "invalid", "_", "instruction1", "\n", + "invalid", "_", "instruction2", + ), + ); +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-error "" "" { target *-*-* } .-6 } + + asm!( + concat!( + "invalid", "_", "instruction1", "\n", + "invalid", "_", "instruction2", + ), + concat!( + "invalid", "_", "instruction3", "\n", + "invalid", "_", "instruction4", + ), + ); +// { dg-error "" "" { target *-*-* } .-9 } +// { dg-error "" "" { target *-*-* } .-10 } +// { dg-error "" "" { target *-*-* } .-7 } +// { dg-error "" "" { target *-*-* } .-8 } + + asm!( + concat!( + "invalid", "_", "instruction1", "\n", + "invalid", "_", "instruction2", "\n", + ), + concat!( + "invalid", "_", "instruction3", "\n", + "invalid", "_", "instruction4", "\n", + ), + ); +// { dg-error "" "" { target *-*-* } .-9 } +// { dg-error "" "" { target *-*-* } .-10 } +// { dg-error "" "" { target *-*-* } .-7 } +// { dg-error "" "" { target *-*-* } .-8 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/sym.rs b/gcc/testsuite/rust/rustc/ui/asm/sym.rs new file mode 100644 index 000000000000..18b55e19adc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/sym.rs @@ -0,0 +1,81 @@ +// no-system-llvm +// only-x86_64 +// only-linux +// run-pass + +#![feature(asm, thread_local)] + +extern "C" fn f1() -> i32 { + 111 +} + +// The compiler will generate a shim to hide the caller location parameter. +#[track_caller] +fn f2() -> i32 { + 222 +} + +macro_rules! call { + ($func:path) => { + unsafe { + let result: i32; + asm!("call {}", sym $func, + out("rax") result, + out("rcx") _, out("rdx") _, out("rdi") _, out("rsi") _, + out("r8") _, out("r9") _, out("r10") _, out("r11") _, + out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _, + out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _, + out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _, + out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _, + ); + result + } + } +} + +macro_rules! static_addr { + ($s:expr) => { + unsafe { + let result: *const u32; + // LEA performs a RIP-relative address calculation and returns the address + asm!("lea {}, [rip + {}]", out(reg) result, sym $s); + result + } + } +} +macro_rules! static_tls_addr { + ($s:expr) => { + unsafe { + let result: *const u32; + asm!( + " + # Load TLS base address + mov {out}, qword ptr fs:[0] + # Calculate the address of sym in the TLS block. The @tpoff + # relocation gives the offset of the symbol from the start + # of the TLS block. + lea {out}, [{out} + {sym}@tpoff] + ", + out = out(reg) result, + sym = sym $s + ); + result + } + } +} + +static S1: u32 = 111; +#[thread_local] +static S2: u32 = 222; + +fn main() { + assert_eq!(call!(f1), 111); + assert_eq!(call!(f2), 222); + assert_eq!(static_addr!(S1), &S1 as *const u32); + assert_eq!(static_tls_addr!(S2), &S2 as *const u32); + std::thread::spawn(|| { + assert_eq!(static_addr!(S1), &S1 as *const u32); + assert_eq!(static_tls_addr!(S2), &S2 as *const u32); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/type-check-1.rs b/gcc/testsuite/rust/rustc/ui/asm/type-check-1.rs new file mode 100644 index 000000000000..831cc8551086 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/type-check-1.rs @@ -0,0 +1,26 @@ +// only-x86_64 + +#![feature(asm)] + +fn main() { + unsafe { + // Outputs must be place expressions + + asm!("{}", in(reg) 1 + 2); + asm!("{}", out(reg) 1 + 2); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", inout(reg) 1 + 2); +// { dg-error "" "" { target *-*-* } .-1 } + + // Operands must be sized + + let v: [u64; 3] = [0, 1, 2]; + asm!("{}", in(reg) v[..]); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + asm!("{}", out(reg) v[..]); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + asm!("{}", inout(reg) v[..]); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/type-check-2.rs b/gcc/testsuite/rust/rustc/ui/asm/type-check-2.rs new file mode 100644 index 000000000000..351c595edb7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/type-check-2.rs @@ -0,0 +1,105 @@ +// only-x86_64 + +#![feature(asm, repr_simd, never_type)] + +#[repr(simd)] +struct SimdNonCopy(f32, f32, f32, f32); + +fn main() { + unsafe { + // Inputs must be initialized + + let x: u64; + asm!("{}", in(reg) x); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + let mut y: u64; + asm!("{}", inout(reg) y); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + let _ = y; + + // Outputs require mutable places + + let v: Vec = vec![0, 1, 2]; + asm!("{}", in(reg) v[0]); + asm!("{}", out(reg) v[0]); +// { dg-error ".E0596." "" { target *-*-* } .-1 } + asm!("{}", inout(reg) v[0]); +// { dg-error ".E0596." "" { target *-*-* } .-1 } + + // Const operands must be integer or floats, and must be constants. + + let x = 0; + const C: i32 = 0; + const fn const_foo(x: i32) -> i32 { + x + } + const fn const_bar(x: T) -> T { + x + } + asm!("{}", const 0i32); + asm!("{}", const 0f32); + asm!("{}", const 0 as *mut u8); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", const &0); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", const x); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", const const_foo(0)); + asm!("{}", const const_foo(x)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", const const_bar(0)); + asm!("{}", const const_bar(x)); +// { dg-error "" "" { target *-*-* } .-1 } + + // Sym operands must point to a function or static + + static S: i32 = 0; + asm!("{}", sym S); + asm!("{}", sym main); + asm!("{}", sym C); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", sym x); +// { dg-error "" "" { target *-*-* } .-1 } + + // Register operands must be Copy + + asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0)); +// { dg-error "" "" { target *-*-* } .-1 } + + // Register operands must be integers, floats, SIMD vectors, pointers or + // function pointers. + + asm!("{}", in(reg) 0i64); + asm!("{}", in(reg) 0f64); + asm!("{}", in(xmm_reg) std::arch::x86_64::_mm_setzero_ps()); + asm!("{}", in(reg) 0 as *const u8); + asm!("{}", in(reg) 0 as *mut u8); + asm!("{}", in(reg) main as fn()); + asm!("{}", in(reg) |x: i32| x); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(reg) vec![0]); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(reg) (1, 2, 3)); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(reg) [1, 2, 3]); +// { dg-error "" "" { target *-*-* } .-1 } + + // Register inputs (but not outputs) allow references and function types + + let mut f = main; + let mut r = &mut 0; + asm!("{}", in(reg) f); + asm!("{}", inout(reg) f); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(reg) r); + asm!("{}", inout(reg) r); +// { dg-error "" "" { target *-*-* } .-1 } + let _ = (f, r); + + // Type checks ignore never type + + let u: ! = unreachable!(); + asm!("{}", in(reg) u); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/type-check-3.rs b/gcc/testsuite/rust/rustc/ui/asm/type-check-3.rs new file mode 100644 index 000000000000..9f3d9b59f74d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/type-check-3.rs @@ -0,0 +1,72 @@ +// only-x86_64 +// compile-flags: -C target-feature=+avx512f + +#![feature(asm)] + +use std::arch::x86_64::{_mm256_setzero_ps, _mm_setzero_ps}; + +fn main() { + unsafe { + // Types must be listed in the register class. + + asm!("{}", in(reg) 0i128); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(reg) _mm_setzero_ps()); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(reg) _mm256_setzero_ps()); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(xmm_reg) 0u8); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{:e}", in(reg) 0i32); + asm!("{}", in(xmm_reg) 0i32); + asm!("{:e}", in(reg) 0f32); + asm!("{}", in(xmm_reg) 0f32); + asm!("{}", in(xmm_reg) _mm_setzero_ps()); + asm!("{:x}", in(ymm_reg) _mm_setzero_ps()); + asm!("{}", in(kreg) 0u16); + asm!("{}", in(kreg) 0u64); +// { dg-error "" "" { target *-*-* } .-1 } + + // Template modifier suggestions for sub-registers + + asm!("{0} {0}", in(reg) 0i16); +// { dg-warning "" "" { target *-*-* } .-1 } + asm!("{0} {0:x}", in(reg) 0i16); +// { dg-warning "" "" { target *-*-* } .-1 } + asm!("{}", in(reg) 0i32); +// { dg-warning "" "" { target *-*-* } .-1 } + asm!("{}", in(reg) 0i64); + asm!("{}", in(ymm_reg) 0i64); +// { dg-warning "" "" { target *-*-* } .-1 } + asm!("{}", in(ymm_reg) _mm256_setzero_ps()); + asm!("{:l}", in(reg) 0i16); + asm!("{:l}", in(reg) 0i32); + asm!("{:l}", in(reg) 0i64); + asm!("{:x}", in(ymm_reg) 0i64); + asm!("{:x}", in(ymm_reg) _mm256_setzero_ps()); + + // Suggest different register class for type + + asm!("{}", in(reg) 0i8); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{}", in(reg_byte) 0i8); + + // Split inout operands must have compatible types + + let mut val_i16: i16; + let mut val_f32: f32; + let mut val_u32: u32; + let mut val_u64: u64; + let mut val_ptr: *mut u8; + asm!("{:r}", inout(reg) 0u16 => val_i16); + asm!("{:r}", inout(reg) 0u32 => val_f32); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{:r}", inout(reg) 0u32 => val_ptr); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{:r}", inout(reg) main => val_u32); +// { dg-error "" "" { target *-*-* } .-1 } + asm!("{:r}", inout(reg) 0u64 => val_ptr); + asm!("{:r}", inout(reg) main => val_u64); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/asm/type-check-4.rs b/gcc/testsuite/rust/rustc/ui/asm/type-check-4.rs new file mode 100644 index 000000000000..21a9b6e0fbac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/asm/type-check-4.rs @@ -0,0 +1,24 @@ +// only-x86_64 + +#![feature(asm)] + +fn main() { + unsafe { + // Can't output to borrowed values. + + let mut a = 0isize; + let p = &a; + asm!("{}", out(reg) a); +// { dg-error ".E0506." "" { target *-*-* } .-1 } + println!("{}", p); + + // Can't read from mutable borrowed values. + + let mut a = 0isize; + let p = &mut a; + asm!("{}", in(reg) a); +// { dg-error ".E0503." "" { target *-*-* } .-1 } + println!("{}", p); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/assert-eq-trailing-comma.rs b/gcc/testsuite/rust/rustc/ui/assert-eq-trailing-comma.rs new file mode 100644 index 000000000000..0d76d3209f84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/assert-eq-trailing-comma.rs @@ -0,0 +1,6 @@ +// run-pass + +fn main() { + assert_eq!(1, 1,); +} + diff --git a/gcc/testsuite/rust/rustc/ui/assert-escape.rs b/gcc/testsuite/rust/rustc/ui/assert-escape.rs new file mode 100644 index 000000000000..307fe24312ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/assert-escape.rs @@ -0,0 +1,6 @@ +// run-pass + +fn main() { + assert!(r#"☃\backslash"#.contains("\\")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/assert-ne-trailing-comma.rs b/gcc/testsuite/rust/rustc/ui/assert-ne-trailing-comma.rs new file mode 100644 index 000000000000..ea183bee15a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/assert-ne-trailing-comma.rs @@ -0,0 +1,6 @@ +// run-pass + +fn main() { + assert_ne!(1, 2,); +} + diff --git a/gcc/testsuite/rust/rustc/ui/assign-assign.rs b/gcc/testsuite/rust/rustc/ui/assign-assign.rs new file mode 100644 index 000000000000..27fa3ea0ad6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/assign-assign.rs @@ -0,0 +1,31 @@ +// run-pass +// Issue 483 - Assignment expressions result in nil + +fn test_assign() { + let mut x: isize; + let y: () = x = 10; + assert_eq!(x, 10); + assert_eq!(y, ()); + let mut z = x = 11; + assert_eq!(x, 11); + assert_eq!(z, ()); + z = x = 12; + assert_eq!(x, 12); + assert_eq!(z, ()); +} + +fn test_assign_op() { + let mut x: isize = 0; + let y: () = x += 10; + assert_eq!(x, 10); + assert_eq!(y, ()); + let mut z = x += 11; + assert_eq!(x, 21); + assert_eq!(z, ()); + z = x += 12; + assert_eq!(x, 33); + assert_eq!(z, ()); +} + +pub fn main() { test_assign(); test_assign_op(); } + diff --git a/gcc/testsuite/rust/rustc/ui/assign-imm-local-twice.rs b/gcc/testsuite/rust/rustc/ui/assign-imm-local-twice.rs new file mode 100644 index 000000000000..a7a1f9d52415 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/assign-imm-local-twice.rs @@ -0,0 +1,14 @@ +fn test() { + let v: isize; +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + v = 1; // { dg-note "" "" { target *-*-* } } + println!("v={}", v); + v = 2; // { dg-error ".E0384." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } + println!("v={}", v); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/assignment-operator-unimplemented.rs b/gcc/testsuite/rust/rustc/ui/assignment-operator-unimplemented.rs new file mode 100644 index 000000000000..ccdc6282a343 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/assignment-operator-unimplemented.rs @@ -0,0 +1,8 @@ +struct Foo; + +fn main() { + let mut a = Foo; + let ref b = Foo; + a += *b; // { dg-error ".E0368." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/assoc-inherent.rs b/gcc/testsuite/rust/rustc/ui/assoc-inherent.rs new file mode 100644 index 000000000000..3239e34c80fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/assoc-inherent.rs @@ -0,0 +1,10 @@ +// Test associated types are, until #8995 is implemented, forbidden in inherent impls. + +struct Foo; + +impl Foo { + type Bar = isize; // { dg-error ".E0202." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/assoc-lang-items.rs b/gcc/testsuite/rust/rustc/ui/assoc-lang-items.rs new file mode 100644 index 000000000000..b56a43779e25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/assoc-lang-items.rs @@ -0,0 +1,22 @@ +#![feature(lang_items)] + +trait Foo { + #[lang = "dummy_lang_item_1"] // { dg-error ".E0522." "" { target *-*-* } } + fn foo() {} + + #[lang = "dummy_lang_item_2"] // { dg-error ".E0522." "" { target *-*-* } } + fn bar(); + + #[lang = "dummy_lang_item_3"] // { dg-error ".E0522." "" { target *-*-* } } + type MyType; +} + +struct Bar; + +impl Bar { + #[lang = "dummy_lang_item_4"] // { dg-error ".E0522." "" { target *-*-* } } + fn test() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/assoc-oddities-3.rs b/gcc/testsuite/rust/rustc/ui/assoc-oddities-3.rs new file mode 100644 index 000000000000..acb5a33e7662 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/assoc-oddities-3.rs @@ -0,0 +1,14 @@ +// run-pass + +fn that_odd_parse(c: bool, n: usize) -> u32 { + let x = 2; + let a = [1, 2, 3, 4]; + let b = [5, 6, 7, 7]; + x + if c { a } else { b }[n] +} + +fn main() { + assert_eq!(4, that_odd_parse(true, 1)); + assert_eq!(8, that_odd_parse(false, 1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-ambiguity-report.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-ambiguity-report.rs new file mode 100644 index 000000000000..1819a90eb8a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-ambiguity-report.rs @@ -0,0 +1,22 @@ +trait Foo { + const ID: i32; +} + +trait Bar { + const ID: i32; +} + +impl Foo for i32 { + const ID: i32 = 1; +} + +impl Bar for i32 { + const ID: i32 = 3; +} + +const X: i32 = ::ID; // { dg-error ".E0034." "" { target *-*-* } } + +fn main() { + assert_eq!(1, X); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-array-len.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-array-len.rs new file mode 100644 index 000000000000..ab202f223703 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-array-len.rs @@ -0,0 +1,11 @@ +trait Foo { + const ID: usize; +} + +const X: [i32; ::ID] = [0, 1, 2]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { + assert_eq!(1, X); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-const-eval.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-const-eval.rs new file mode 100644 index 000000000000..0dff4d87d680 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-const-eval.rs @@ -0,0 +1,21 @@ +// run-pass + +trait Foo { + const NUM: usize; +} + +impl Foo for i32 { + const NUM: usize = 1; +} + +const FOO: usize = ::NUM; + +fn main() { + assert_eq!(1, FOO); + + match 1 { + ::NUM => {}, + _ => assert!(false) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-cross-crate-const-eval.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-cross-crate-const-eval.rs new file mode 100644 index 000000000000..393db7c2ff7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-cross-crate-const-eval.rs @@ -0,0 +1,29 @@ +// run-pass +// aux-build:associated-const-cc-lib.rs + + +extern crate associated_const_cc_lib as foolib; + +pub struct LocalFoo; + +impl foolib::Foo for LocalFoo { + const BAR: usize = 1; +} + +const FOO_1: usize = ::BAR; +const FOO_2: usize = ::BAR; +const FOO_3: usize = foolib::InherentBar::BAR; + +fn main() { + assert_eq!(0, FOO_1); + assert_eq!(1, FOO_2); + assert_eq!(3, FOO_3); + + match 0 { + ::BAR => {}, + ::BAR => assert!(false), + foolib::InherentBar::BAR => assert!(false), + _ => assert!(false) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-cross-crate-defaults.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-cross-crate-defaults.rs new file mode 100644 index 000000000000..795863e5ece8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-cross-crate-defaults.rs @@ -0,0 +1,23 @@ +// run-pass +// aux-build:associated-const-cc-lib.rs + + +extern crate associated_const_cc_lib as foolib; + +pub struct LocalFooUseDefault; + +impl foolib::FooDefault for LocalFooUseDefault {} + +pub struct LocalFooOverwriteDefault; + +impl foolib::FooDefault for LocalFooOverwriteDefault { + const BAR: usize = 4; +} + +fn main() { + assert_eq!(1, ::BAR); + assert_eq!(2, ::BAR); + assert_eq!(1, ::BAR); + assert_eq!(4, ::BAR); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-cross-crate.rs new file mode 100644 index 000000000000..db2a7f11e56b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-cross-crate.rs @@ -0,0 +1,18 @@ +// run-pass +// aux-build:associated-const-cc-lib.rs + + +extern crate associated_const_cc_lib as foolib; + +pub struct LocalFoo; + +impl foolib::Foo for LocalFoo { + const BAR: usize = 1; +} + +fn main() { + assert_eq!(0, ::BAR); + assert_eq!(1, ::BAR); + assert_eq!(3, foolib::InherentBar::BAR); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-dead-code.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-dead-code.rs new file mode 100644 index 000000000000..7d853a20b98f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-dead-code.rs @@ -0,0 +1,13 @@ +#![deny(dead_code)] + +struct MyFoo; + +impl MyFoo { + const BAR: u32 = 1; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + let _: MyFoo = MyFoo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-generic-obligations.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-generic-obligations.rs new file mode 100644 index 000000000000..376e520d26de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-generic-obligations.rs @@ -0,0 +1,19 @@ +trait Foo { + type Out: Sized; +} + +impl Foo for String { + type Out = String; +} + +trait Bar: Foo { + const FROM: Self::Out; +} + +impl Bar for T { + const FROM: &'static str = "foo"; +// { dg-error ".E0326." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-impl-wrong-lifetime.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-impl-wrong-lifetime.rs new file mode 100644 index 000000000000..539c44b422dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-impl-wrong-lifetime.rs @@ -0,0 +1,12 @@ +trait Foo { + const NAME: &'static str; +} + + +impl<'a> Foo for &'a () { + const NAME: &'a str = "unit"; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-impl-wrong-type.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-impl-wrong-type.rs new file mode 100644 index 000000000000..12b596647e9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-impl-wrong-type.rs @@ -0,0 +1,13 @@ +trait Foo { + const BAR: u32; +} + +struct SignedBar; + +impl Foo for SignedBar { + const BAR: i32 = -1; +// { dg-error ".E0326." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-in-global-const.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-in-global-const.rs new file mode 100644 index 000000000000..524824b77e2e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-in-global-const.rs @@ -0,0 +1,14 @@ +// run-pass + +struct Foo; + +impl Foo { + const BAR: f32 = 1.5; +} + +const FOOBAR: f32 = ::BAR; + +fn main() { + assert_eq!(1.5f32, FOOBAR); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-in-trait.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-in-trait.rs new file mode 100644 index 000000000000..8a1bbff91284 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-in-trait.rs @@ -0,0 +1,15 @@ +// #29924 + +#![feature(const_fn, associated_consts)] + +trait Trait { + const N: usize; +} + +impl dyn Trait { +// { dg-error ".E0038." "" { target *-*-* } .-1 } + const fn n() -> usize { Self::N } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-inherent-impl.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-inherent-impl.rs new file mode 100644 index 000000000000..bc92712843f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-inherent-impl.rs @@ -0,0 +1,12 @@ +// run-pass + +struct Foo; + +impl Foo { + const ID: i32 = 1; +} + +fn main() { + assert_eq!(1, Foo::ID); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-marks-live-code.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-marks-live-code.rs new file mode 100644 index 000000000000..da71dfc1cfa7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-marks-live-code.rs @@ -0,0 +1,16 @@ +// run-pass + +#![deny(dead_code)] + +const GLOBAL_BAR: u32 = 1; + +struct Foo; + +impl Foo { + const BAR: u32 = GLOBAL_BAR; +} + +pub fn main() { + let _: u32 = Foo::BAR; +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-match-patterns.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-match-patterns.rs new file mode 100644 index 000000000000..ae194a65f569 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-match-patterns.rs @@ -0,0 +1,69 @@ +// run-pass +// aux-build:empty-struct.rs + + +extern crate empty_struct; +use empty_struct::XEmpty2 as XFoo; + +struct Foo; + +#[derive(PartialEq, Eq)] +enum Bar { + Var1, + Var2, +} + +// Use inherent and trait impls to test UFCS syntax. +impl Foo { + const MYBAR: Bar = Bar::Var2; +} + +trait HasBar { + const THEBAR: Bar; +} + +impl HasBar for Foo { + const THEBAR: Bar = Bar::Var1; +} + +impl HasBar for XFoo { + const THEBAR: Bar = Bar::Var1; +} + +fn main() { + // Inherent impl + assert!(match Bar::Var2 { + Foo::MYBAR => true, + _ => false, + }); + assert!(match Bar::Var2 { + ::MYBAR => true, + _ => false, + }); + // Trait impl + assert!(match Bar::Var1 { + Foo::THEBAR => true, + _ => false, + }); + assert!(match Bar::Var1 { + ::THEBAR => true, + _ => false, + }); + assert!(match Bar::Var1 { + ::THEBAR => true, + _ => false, + }); + assert!(match Bar::Var1 { + XFoo::THEBAR => true, + _ => false, + }); + assert!(match Bar::Var1 { + ::THEBAR => true, + _ => false, + }); + assert!(match Bar::Var1 { + ::THEBAR => true, + _ => false, + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-no-item.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-no-item.rs new file mode 100644 index 000000000000..114978772a70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-no-item.rs @@ -0,0 +1,11 @@ +trait Foo { + const ID: i32; +} + +const X: i32 = ::ID; +// { dg-error ".E0599." "" { target *-*-* } .-1 } + +fn main() { + assert_eq!(1, X); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-outer-ty-refs.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-outer-ty-refs.rs new file mode 100644 index 000000000000..5c124369b226 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-outer-ty-refs.rs @@ -0,0 +1,11 @@ +// run-pass +trait Lattice { + const BOTTOM: Self; +} + +impl Lattice for Option { + const BOTTOM: Option = None; +} + +fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-overwrite-default.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-overwrite-default.rs new file mode 100644 index 000000000000..2897b873d41a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-overwrite-default.rs @@ -0,0 +1,14 @@ +// run-pass + +trait Foo { + const ID: i32 = 2; +} + +impl Foo for i32 { + const ID: i32 = 1; +} + +fn main() { + assert_eq!(1, ::ID); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-private-impl.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-private-impl.rs new file mode 100644 index 000000000000..86cbf6dab413 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-private-impl.rs @@ -0,0 +1,16 @@ +mod bar1 { + pub use self::bar2::Foo; + mod bar2 { + pub struct Foo; + + impl Foo { + const ID: i32 = 1; + } + } +} + +fn main() { + assert_eq!(1, bar1::Foo::ID); +// { dg-error ".E0624." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-public-impl.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-public-impl.rs new file mode 100644 index 000000000000..9627697ea7aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-public-impl.rs @@ -0,0 +1,17 @@ +// run-pass + +mod bar1 { + pub use self::bar2::Foo; + mod bar2 { + pub struct Foo; + + impl Foo { + pub const ID: i32 = 1; + } + } +} + +fn main() { + assert_eq!(1, bar1::Foo::ID); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-range-match-patterns.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-range-match-patterns.rs new file mode 100644 index 000000000000..c85d1a56122f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-range-match-patterns.rs @@ -0,0 +1,41 @@ +// run-pass +#![allow(dead_code, unreachable_patterns)] +#![allow(ellipsis_inclusive_range_patterns)] + +struct Foo; + +trait HasNum { + const NUM: isize; +} +impl HasNum for Foo { + const NUM: isize = 1; +} + +fn main() { + assert!(match 2 { + Foo::NUM ... 3 => true, + _ => false, + }); + assert!(match 0 { + -1 ... ::NUM => true, + _ => false, + }); + assert!(match 1 { + ::NUM ... ::NUM => true, + _ => false, + }); + + assert!(match 2 { + Foo::NUM ..= 3 => true, + _ => false, + }); + assert!(match 0 { + -1 ..= ::NUM => true, + _ => false, + }); + assert!(match 1 { + ::NUM ..= ::NUM => true, + _ => false, + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-resolution-order.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-resolution-order.rs new file mode 100644 index 000000000000..d2898a393a8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-resolution-order.rs @@ -0,0 +1,26 @@ +// run-pass + +struct MyType; + +impl MyType { + const IMPL_IS_INHERENT: bool = true; +} + +trait MyTrait { + const IMPL_IS_INHERENT: bool; + const IMPL_IS_ON_TRAIT: bool; +} + +impl MyTrait for MyType { + const IMPL_IS_INHERENT: bool = false; + const IMPL_IS_ON_TRAIT: bool = true; +} + +fn main() { + // Check that the inherent impl is used before the trait, but that the trait + // can still be accessed. + assert!(::IMPL_IS_INHERENT); + assert!(!::IMPL_IS_INHERENT); + assert!(::IMPL_IS_ON_TRAIT); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-self-type.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-self-type.rs new file mode 100644 index 000000000000..91dd38677cd8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-self-type.rs @@ -0,0 +1,14 @@ +// run-pass + +trait MyInt { + const ONE: Self; +} + +impl MyInt for i32 { + const ONE: i32 = 1; +} + +fn main() { + assert_eq!(1, ::ONE); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-trait-bound.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-trait-bound.rs new file mode 100644 index 000000000000..bba90380146b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-trait-bound.rs @@ -0,0 +1,22 @@ +// build-pass (FIXME(62277): could be check-pass?) + +trait ConstDefault { + const DEFAULT: Self; +} + +trait Foo: Sized {} + +trait FooExt: Foo { + type T: ConstDefault; +} + +trait Bar { + const T: F::T; +} + +impl Bar for () { + const T: F::T = ::DEFAULT; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameter-arms.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameter-arms.rs new file mode 100644 index 000000000000..fe07d56f9ddc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameter-arms.rs @@ -0,0 +1,30 @@ +pub enum EFoo { A, B, C, D } + +pub trait Foo { + const X: EFoo; +} + +struct Abc; + +impl Foo for Abc { + const X: EFoo = EFoo::B; +} + +struct Def; +impl Foo for Def { + const X: EFoo = EFoo::D; +} + +pub fn test(arg: EFoo) { + match arg { + A::X => println!("A::X"), +// { dg-error ".E0158." "" { target *-*-* } .-1 } + B::X => println!("B::X"), +// { dg-error ".E0158." "" { target *-*-* } .-1 } + _ => (), + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameter-arrays-2.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameter-arrays-2.rs new file mode 100644 index 000000000000..729b62dfa82a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameter-arrays-2.rs @@ -0,0 +1,22 @@ +pub trait Foo { + const Y: usize; +} + +struct Abc; +impl Foo for Abc { + const Y: usize = 8; +} + +struct Def; +impl Foo for Def { + const Y: usize = 33; +} + +pub fn test() { + let _array = [4; ::Y]; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameter-arrays.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameter-arrays.rs new file mode 100644 index 000000000000..f62adb47c947 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameter-arrays.rs @@ -0,0 +1,22 @@ +pub trait Foo { + const Y: usize; +} + +struct Abc; +impl Foo for Abc { + const Y: usize = 8; +} + +struct Def; +impl Foo for Def { + const Y: usize = 33; +} + +pub fn test() { + let _array: [u32; ::Y]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameters.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameters.rs new file mode 100644 index 000000000000..0cbc8470eded --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-type-parameters.rs @@ -0,0 +1,45 @@ +// run-pass + +trait Foo { + const X: i32; + fn get_x() -> i32 { + Self::X + } +} + +struct Abc; +impl Foo for Abc { + const X: i32 = 11; +} + +struct Def; +impl Foo for Def { + const X: i32 = 97; +} + +struct Proxy(T); + +impl Foo for Proxy { + const X: i32 = T::X; +} + +fn sub() -> i32 { + A::X - B::X +} + +trait Bar: Foo { + const Y: i32 = Self::X; +} + +fn main() { + assert_eq!(11, Abc::X); + assert_eq!(97, Def::X); + assert_eq!(11, Abc::get_x()); + assert_eq!(97, Def::get_x()); + assert_eq!(-86, sub::()); + assert_eq!(86, sub::()); + assert_eq!(-86, sub::, Def>()); + assert_eq!(-86, sub::>()); + assert_eq!(86, sub::, Proxy>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-ufcs-infer-trait.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-ufcs-infer-trait.rs new file mode 100644 index 000000000000..155a857be512 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-ufcs-infer-trait.rs @@ -0,0 +1,14 @@ +// run-pass + +trait Foo { + const ID: i32; +} + +impl Foo for i32 { + const ID: i32 = 1; +} + +fn main() { + assert_eq!(1, ::ID); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-use-default.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-use-default.rs new file mode 100644 index 000000000000..1c6e9359c4fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-use-default.rs @@ -0,0 +1,12 @@ +// run-pass + +trait Foo { + const ID: i32 = 1; +} + +impl Foo for i32 {} + +fn main() { + assert_eq!(1, ::ID); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-use-impl-of-same-trait.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-use-impl-of-same-trait.rs new file mode 100644 index 000000000000..ebfcc33eb4e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const-use-impl-of-same-trait.rs @@ -0,0 +1,26 @@ +// run-pass + +// The main purpose of this test is to ensure that different impls of the same +// trait can refer to each other without setting off the static recursion check +// (as long as there's no actual recursion). + +trait Foo { + const BAR: u32; +} + +struct IsFoo1; + +impl Foo for IsFoo1 { + const BAR: u32 = 1; +} + +struct IsFoo2; + +impl Foo for IsFoo2 { + const BAR: u32 = ::BAR; +} + +fn main() { + assert_eq!(::BAR, ::BAR); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const.rs new file mode 100644 index 000000000000..e6307d46cb92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/associated-const.rs @@ -0,0 +1,14 @@ +// run-pass + +trait Foo { + const ID: i32; +} + +impl Foo for i32 { + const ID: i32 = 1; +} + +fn main() { + assert_eq!(1, ::ID); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/auxiliary/associated-const-cc-lib.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/auxiliary/associated-const-cc-lib.rs new file mode 100644 index 000000000000..d1acbb53f34e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/auxiliary/associated-const-cc-lib.rs @@ -0,0 +1,35 @@ +#![crate_type="lib"] + +// These items are for testing that associated consts work cross-crate. +pub trait Foo { + const BAR: usize; +} + +pub struct FooNoDefault; + +impl Foo for FooNoDefault { + const BAR: usize = 0; +} + +// These test that defaults and default resolution work cross-crate. +pub trait FooDefault { + const BAR: usize = 1; +} + +pub struct FooOverwriteDefault; + +impl FooDefault for FooOverwriteDefault { + const BAR: usize = 2; +} + +pub struct FooUseDefault; + +impl FooDefault for FooUseDefault {} + +// Test inherent impls. +pub struct InherentBar; + +impl InherentBar { + pub const BAR: usize = 3; +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/auxiliary/empty-struct.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/auxiliary/empty-struct.rs new file mode 100644 index 000000000000..020e55569330 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/auxiliary/empty-struct.rs @@ -0,0 +1,10 @@ +pub struct XEmpty1 {} +pub struct XEmpty2; +pub struct XEmpty7(); + +pub enum XE { + XEmpty3 {}, + XEmpty4, + XEmpty6(), +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/defaults-cyclic-fail.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/defaults-cyclic-fail.rs new file mode 100644 index 000000000000..9b3e79d11c15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/defaults-cyclic-fail.rs @@ -0,0 +1,18 @@ +// build-fail +// { dg-error "" "" { target *-*-* } .-1 } + +// Cyclic assoc. const defaults don't error unless *used* +trait Tr { + const A: u8 = Self::B; + + const B: u8 = Self::A; +} + +// This impl is *allowed* unless its assoc. consts are used +impl Tr for () {} + +fn main() { + // This triggers the cycle error + assert_eq!(<() as Tr>::A, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/defaults-cyclic-pass.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/defaults-cyclic-pass.rs new file mode 100644 index 000000000000..e309fba58005 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/defaults-cyclic-pass.rs @@ -0,0 +1,37 @@ +// run-pass + +// Cyclic assoc. const defaults don't error unless *used* +trait Tr { + const A: u8 = Self::B; + const B: u8 = Self::A; +} + +// This impl is *allowed* unless its assoc. consts are used, matching the +// behavior without defaults. +impl Tr for () {} + +// Overriding either constant breaks the cycle +impl Tr for u8 { + const A: u8 = 42; +} + +impl Tr for u16 { + const B: u8 = 0; +} + +impl Tr for u32 { + const A: u8 = 100; + const B: u8 = 123; +} + +fn main() { + assert_eq!(::A, 42); + assert_eq!(::B, 42); + + assert_eq!(::A, 0); + assert_eq!(::B, 0); + + assert_eq!(::A, 100); + assert_eq!(::B, 123); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/defaults-not-assumed-fail.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/defaults-not-assumed-fail.rs new file mode 100644 index 000000000000..7002c2555bb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/defaults-not-assumed-fail.rs @@ -0,0 +1,46 @@ +// build-fail + +trait Tr { + const A: u8 = 255; + + // This should not be a constant evaluation error (overflow). The value of + // `Self::A` must not be assumed to hold inside the trait. + const B: u8 = Self::A + 1; +// { dg-error "" "" { target *-*-* } .-1 } +} + +// An impl that doesn't override any constant will NOT cause a const eval error +// just because it's defined, but only if the bad constant is used anywhere. +// This matches the behavior without defaults. +impl Tr for () {} + +// An impl that overrides either constant with a suitable value will be fine. +impl Tr for u8 { + const A: u8 = 254; +} + +impl Tr for u16 { + const B: u8 = 0; +} + +impl Tr for u32 { + const A: u8 = 254; + const B: u8 = 0; +} + +fn main() { + assert_eq!(<() as Tr>::A, 255); + assert_eq!(<() as Tr>::B, 0); // causes the error above +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } + + assert_eq!(::A, 254); + assert_eq!(::B, 255); + + assert_eq!(::A, 255); + assert_eq!(::B, 0); + + assert_eq!(::A, 254); + assert_eq!(::B, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/defaults-not-assumed-pass.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/defaults-not-assumed-pass.rs new file mode 100644 index 000000000000..2a5c0cf07e2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/defaults-not-assumed-pass.rs @@ -0,0 +1,43 @@ +// run-pass + +trait Tr { + const A: u8 = 255; + + // This should not be a constant evaluation error (overflow). The value of + // `Self::A` must not be assumed to hold inside the trait. + const B: u8 = Self::A + 1; +} + +// An impl that doesn't override any constant will NOT cause a const eval error +// just because it's defined, but only if the bad constant is used anywhere. +// This matches the behavior without defaults. +impl Tr for () {} + +// An impl that overrides either constant with a suitable value will be fine. +impl Tr for u8 { + const A: u8 = 254; +} + +impl Tr for u16 { + const B: u8 = 0; +} + +impl Tr for u32 { + const A: u8 = 254; + const B: u8 = 0; +} + +fn main() { + assert_eq!(<() as Tr>::A, 255); + //assert_eq!(<() as Tr>::B, 0); // using this is an error + + assert_eq!(::A, 254); + assert_eq!(::B, 255); + + assert_eq!(::A, 255); + assert_eq!(::B, 0); + + assert_eq!(::A, 254); + assert_eq!(::B, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.rs new file mode 100644 index 000000000000..0e3afbd78ccc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-impl.rs @@ -0,0 +1,16 @@ +// Check for recursion involving references to impl-associated const. + +trait Foo { + const BAR: u32; +} + +const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; // { dg-error ".E0391." "" { target *-*-* } } + +struct GlobalImplRef; + +impl GlobalImplRef { + const BAR: u32 = IMPL_REF_BAR; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.rs new file mode 100644 index 000000000000..45aaf02669cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait-default.rs @@ -0,0 +1,18 @@ +// Check for recursion involving references to trait-associated const default. + +trait Foo { + const BAR: u32; +} + +trait FooDefault { + const BAR: u32 = DEFAULT_REF_BAR; +} + +const DEFAULT_REF_BAR: u32 = ::BAR; // { dg-error ".E0391." "" { target *-*-* } } + +struct GlobalDefaultRef; + +impl FooDefault for GlobalDefaultRef {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.rs new file mode 100644 index 000000000000..9eb4961edc8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/issue-24949-assoc-const-static-recursion-trait.rs @@ -0,0 +1,16 @@ +// Check for recursion involving references to trait-associated const. + +trait Foo { + const BAR: u32; +} + +const TRAIT_REF_BAR: u32 = ::BAR; // { dg-error ".E0391." "" { target *-*-* } } + +struct GlobalTraitRef; + +impl Foo for GlobalTraitRef { + const BAR: u32 = TRAIT_REF_BAR; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/issue-63496.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/issue-63496.rs new file mode 100644 index 000000000000..44907d460ca0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/issue-63496.rs @@ -0,0 +1,10 @@ +trait A { + const C: usize; + + fn f() -> ([u8; A::C], [u8; A::C]); +// { dg-error ".E0283." "" { target *-*-* } .-1 } +// { dg-error ".E0283." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-consts/issue-69020-assoc-const-arith-overflow.rs b/gcc/testsuite/rust/rustc/ui/associated-consts/issue-69020-assoc-const-arith-overflow.rs new file mode 100644 index 000000000000..28175a01cce3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-consts/issue-69020-assoc-const-arith-overflow.rs @@ -0,0 +1,49 @@ +// revisions: noopt opt opt_with_overflow_checks +//[noopt]compile-flags: -C opt-level=0 +//[opt]compile-flags: -O +//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O + +#![crate_type="lib"] + +use std::i32; + +pub trait Foo { + const NEG: i32; + const NEG_REV: i32; + + const ADD: i32; + const ADD_REV: i32; + + const DIV: i32; + const DIV_REV: i32; + + const OOB: i32; + const OOB_REV: i32; +} + +// These constants cannot be evaluated already (they depend on `T::N`), so they can just be linted +// like normal run-time code. But codegen works a bit different in const context, so this test +// makes sure that we still catch overflow. Also make sure we emit the same lints if we reverse the +// operands (so that the generic operand comes first). +impl Foo for Vec { + const NEG: i32 = -i32::MIN + T::NEG; +// { dg-error "" "" { target *-*-* } .-1 } + const NEG_REV: i32 = T::NEG + (-i32::MIN); +// { dg-error "" "" { target *-*-* } .-1 } + + const ADD: i32 = (i32::MAX+1) + T::ADD; +// { dg-error "" "" { target *-*-* } .-1 } + const ADD_REV: i32 = T::ADD + (i32::MAX+1); +// { dg-error "" "" { target *-*-* } .-1 } + + const DIV: i32 = (1/0) + T::DIV; +// { dg-error "" "" { target *-*-* } .-1 } + const DIV_REV: i32 = T::DIV + (1/0); +// { dg-error "" "" { target *-*-* } .-1 } + + const OOB: i32 = [1][1] + T::OOB; +// { dg-error "" "" { target *-*-* } .-1 } + const OOB_REV: i32 = T::OOB + [1][1]; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-item-long-paths.rs b/gcc/testsuite/rust/rustc/ui/associated-item-long-paths.rs new file mode 100644 index 000000000000..ea13cb01bd85 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-item-long-paths.rs @@ -0,0 +1,48 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-bounds.rs b/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-bounds.rs new file mode 100644 index 000000000000..496953734e5a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-bounds.rs @@ -0,0 +1,12 @@ +trait Adapter { + const LINKS: usize; +} + +struct Foo { + adapter: A, + links: [u32; A::LINKS], // Shouldn't suggest bounds already there. +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-names-2.rs b/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-names-2.rs new file mode 100644 index 000000000000..e0d6657dba2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-names-2.rs @@ -0,0 +1,9 @@ +struct Foo; + +impl Foo { + const bar: bool = true; + fn bar() {} // { dg-error ".E0201." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-names-3.rs b/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-names-3.rs new file mode 100644 index 000000000000..8a3d3e693288 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-names-3.rs @@ -0,0 +1,20 @@ +// +// Before the introduction of the "duplicate associated type" error, the +// program below used to result in the "ambiguous associated type" error E0223, +// which is unexpected. + +trait Foo { + type Bar; +} + +struct Baz; + +impl Foo for Baz { + type Bar = i16; + type Bar = u16; // { dg-error ".E0201." "" { target *-*-* } } +} + +fn main() { + let x: Baz::Bar = 5; +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-names.rs b/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-names.rs new file mode 100644 index 000000000000..8c42536640a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-duplicate-names.rs @@ -0,0 +1,20 @@ +// Test for issue #23969 + + +trait Foo { + type Ty; + const BAR: u32; +} + +impl Foo for () { + type Ty = (); + type Ty = usize; // { dg-error ".E0201." "" { target *-*-* } } + const BAR: u32 = 7; + const BAR: u32 = 8; // { dg-error ".E0201." "" { target *-*-* } } +} + +fn main() { + let _: <() as Foo>::Ty = (); + let _: u32 = <() as Foo>::BAR; +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-enum.rs b/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-enum.rs new file mode 100644 index 000000000000..f7e9855cd036 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-item/associated-item-enum.rs @@ -0,0 +1,21 @@ +enum Enum { Variant } + +impl Enum { + const MISSPELLABLE: i32 = 0; + fn misspellable() {} +} + +trait Trait { + fn misspellable_trait() {} +} + +impl Trait for Enum { + fn misspellable_trait() {} +} + +fn main() { + Enum::mispellable(); // { dg-error ".E0599." "" { target *-*-* } } + Enum::mispellable_trait(); // { dg-error ".E0599." "" { target *-*-* } } + Enum::MISPELLABLE; // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-item/issue-48027.rs b/gcc/testsuite/rust/rustc/ui/associated-item/issue-48027.rs new file mode 100644 index 000000000000..652bbbdaec05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-item/issue-48027.rs @@ -0,0 +1,9 @@ +trait Bar { + const X: usize; + fn return_n(&self) -> [u8; Bar::X]; // { dg-error ".E0283." "" { target *-*-* } } +} + +impl dyn Bar {} // { dg-error ".E0038." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-path-shl.rs b/gcc/testsuite/rust/rustc/ui/associated-path-shl.rs new file mode 100644 index 000000000000..fa60ff67bc4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-path-shl.rs @@ -0,0 +1,10 @@ +// Check that associated paths starting with `<<` are successfully parsed. + +fn main() { + let _: <::B>::C; // { dg-error ".E0412." "" { target *-*-* } } + let _ = <::B>::C; // { dg-error ".E0412." "" { target *-*-* } } + let <::B>::C; // { dg-error ".E0412." "" { target *-*-* } } + let 0 ..= <::B>::C; // { dg-error ".E0412." "" { target *-*-* } } + <::B>::C; // { dg-error ".E0412." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/ambiguous-associated-type.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/ambiguous-associated-type.rs new file mode 100644 index 000000000000..5c4c71927bc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/ambiguous-associated-type.rs @@ -0,0 +1,13 @@ +// check-pass + +#![feature(associated_type_bounds)] + +pub struct Flatten +where + I: Iterator, +{ + inner: ::IntoIter, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/assoc-type-bound-through-where-clause.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/assoc-type-bound-through-where-clause.rs new file mode 100644 index 000000000000..34805f1a804d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/assoc-type-bound-through-where-clause.rs @@ -0,0 +1,17 @@ +// Check that `where Self::Output: Copy` is turned into a bound on `Op::Output`. + +//check-pass + +trait Op +where + Self::Output: Copy, +{ + type Output; +} + +fn duplicate(x: T::Output) -> (T::Output, T::Output) { + (x, x) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs new file mode 100644 index 000000000000..6e58c7819bad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs @@ -0,0 +1,38 @@ +// This test documents that `type Out = Box>;` +// is allowed and will correctly reject an opaque `type Out` which +// does not satisfy the bound `::Assoc: Copy`. +// +// FIXME(rust-lang/lang): I think this behavior is logical if we want to allow +// `dyn Trait` but we should decide if we want that. // Centril +// +// Additionally, as reported in https://github.com/rust-lang/rust/issues/63594, +// we check that the spans for the error message are sane here. + +#![feature(associated_type_bounds)] + +fn main() {} + +trait Bar { + type Assoc; +} + +trait Thing { + type Out; + fn func() -> Self::Out; +} + +struct AssocNoCopy; +impl Bar for AssocNoCopy { + type Assoc = String; +} + +impl Thing for AssocNoCopy { + type Out = Box>; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + + fn func() -> Self::Out { + Box::new(AssocNoCopy) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/auxiliary/fn-aux.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/auxiliary/fn-aux.rs new file mode 100644 index 000000000000..8e47d101d20a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/auxiliary/fn-aux.rs @@ -0,0 +1,178 @@ +// Traits: + +pub trait Alpha { + fn alpha(self) -> usize; +} + +pub trait Beta { + type Gamma; + fn gamma(self) -> Self::Gamma; +} + +pub trait Delta { + fn delta(self) -> usize; +} + +pub trait Epsilon<'a> { + type Zeta; + fn zeta(&'a self) -> Self::Zeta; + + fn epsilon(&'a self) -> usize; +} + +pub trait Eta { + fn eta(self) -> usize; +} + +// Assertions: + +pub fn assert_alpha(x: T) -> usize { x.alpha() } +pub fn assert_static(_: T) -> usize { 24 } +pub fn assert_delta(x: T) -> usize { x.delta() } +pub fn assert_epsilon_specific<'a, T: 'a + Epsilon<'a>>(x: &'a T) -> usize { x.epsilon() } +pub fn assert_epsilon_forall Epsilon<'a>>() {} +pub fn assert_forall_epsilon_zeta_satisfies_eta(x: T) -> usize +where + T: for<'a> Epsilon<'a>, + for<'a> >::Zeta: Eta, +{ + x.epsilon() + x.zeta().eta() +} + +// Implementations and types: + +#[derive(Copy, Clone)] +pub struct BetaType; + +#[derive(Copy, Clone)] +pub struct GammaType; + +#[derive(Copy, Clone)] +pub struct ZetaType; + +impl Beta for BetaType { + type Gamma = GammaType; + fn gamma(self) -> Self::Gamma { GammaType } +} + +impl<'a> Beta for &'a BetaType { + type Gamma = GammaType; + fn gamma(self) -> Self::Gamma { GammaType } +} + +impl Beta for GammaType { + type Gamma = Self; + fn gamma(self) -> Self::Gamma { self } +} + +impl Alpha for GammaType { + fn alpha(self) -> usize { 42 } +} + +impl Delta for GammaType { + fn delta(self) -> usize { 1337 } +} + +impl<'a> Epsilon<'a> for GammaType { + type Zeta = ZetaType; + fn zeta(&'a self) -> Self::Zeta { ZetaType } + + fn epsilon(&'a self) -> usize { 7331 } +} + +impl Eta for ZetaType { + fn eta(self) -> usize { 7 } +} + +// Desugared forms to check against: + +pub fn desugared_bound(beta: B) -> usize +where + B: Beta, + B::Gamma: Alpha +{ + let gamma: B::Gamma = beta.gamma(); + assert_alpha::(gamma) +} + +pub fn desugared_bound_region(beta: B) -> usize +where + B: Beta, + B::Gamma: 'static, +{ + assert_static::(beta.gamma()) +} + +pub fn desugared_bound_multi(beta: B) -> usize +where + B: Copy + Beta, + B::Gamma: Alpha + 'static + Delta, +{ + assert_alpha::(beta.gamma()) + + assert_static::(beta.gamma()) + + assert_delta::(beta.gamma()) +} + +pub fn desugared_bound_region_specific<'a, B>(gamma: &'a B::Gamma) -> usize +where + B: Beta, + B::Gamma: 'a + Epsilon<'a>, +{ + assert_epsilon_specific::(gamma) +} + +pub fn desugared_bound_region_forall(beta: B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, +{ + assert_epsilon_forall::(); + let g1: B::Gamma = beta.gamma(); + let g2: B::Gamma = g1; + assert_epsilon_specific::(&g1) + + assert_epsilon_specific::(&g2) +} + +pub fn desugared_bound_region_forall2(beta: B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, + for<'a> >::Zeta: Eta, +{ + let gamma = beta.gamma(); + assert_forall_epsilon_zeta_satisfies_eta::(gamma) +} + +pub fn desugared_contraint_region_forall(beta: B) -> usize +where + for<'a> &'a B: Beta, + for<'a> <&'a B as Beta>::Gamma: Alpha, +{ + let g1 = beta.gamma(); + let g2 = beta.gamma(); + assert_alpha(g1) + assert_alpha(g2) +} + +pub fn desugared_bound_nested(beta: B) -> usize +where + B: Beta, + B::Gamma: Copy + Alpha + Beta, + ::Gamma: Delta, +{ + let go = beta.gamma(); + let gi = go.gamma(); + go.alpha() + gi.delta() +} + +pub fn desugared() { + let beta = BetaType; + let gamma = beta.gamma(); + + assert_eq!(42, desugared_bound(beta)); + assert_eq!(24, desugared_bound_region(beta)); + assert_eq!(42 + 24 + 1337, desugared_bound_multi(beta)); + assert_eq!(7331, desugared_bound_region_specific::(&gamma)); + assert_eq!(7331 * 2, desugared_bound_region_forall(beta)); + assert_eq!(42 + 1337, desugared_bound_nested(beta)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs new file mode 100644 index 000000000000..1ac7f0bc18ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs @@ -0,0 +1,183 @@ +// Traits: + +pub trait Alpha { + fn alpha(self) -> usize; +} + +pub trait Beta { + type Gamma; + fn gamma(&self) -> Self::Gamma; +} + +pub trait Delta { + fn delta(self) -> usize; +} + +pub trait Epsilon<'a> { + type Zeta; + fn zeta(&'a self) -> Self::Zeta; + + fn epsilon(&'a self) -> usize; +} + +pub trait Eta { + fn eta(self) -> usize; +} + +// Assertions: + +pub fn assert_alpha(x: T) -> usize { x.alpha() } +pub fn assert_static(_: T) -> usize { 24 } +pub fn assert_delta(x: T) -> usize { x.delta() } +pub fn assert_epsilon_specific<'a, T: 'a + Epsilon<'a>>(x: &'a T) -> usize { x.epsilon() } +pub fn assert_epsilon_forall Epsilon<'a>>() {} +pub fn assert_forall_epsilon_zeta_satisfies_eta(x: T) -> usize +where + T: for<'a> Epsilon<'a>, + for<'a> >::Zeta: Eta, +{ + x.epsilon() + x.zeta().eta() +} + +// Implementations and types: + +#[derive(Copy, Clone)] +pub struct BetaType; + +#[derive(Copy, Clone)] +pub struct GammaType; + +#[derive(Copy, Clone)] +pub struct ZetaType; + +impl Beta for &(dyn Beta + Send) { + type Gamma = T; + fn gamma(&self) -> Self::Gamma { (*self).gamma() } +} + +impl Beta for BetaType { + type Gamma = GammaType; + fn gamma(&self) -> Self::Gamma { GammaType } +} + +impl<'a> Beta for &'a BetaType { + type Gamma = GammaType; + fn gamma(&self) -> Self::Gamma { GammaType } +} + +impl Beta for GammaType { + type Gamma = Self; + fn gamma(&self) -> Self::Gamma { Self } +} + +impl Alpha for GammaType { + fn alpha(self) -> usize { 42 } +} + +impl Delta for GammaType { + fn delta(self) -> usize { 1337 } +} + +impl<'a> Epsilon<'a> for GammaType { + type Zeta = ZetaType; + fn zeta(&'a self) -> Self::Zeta { ZetaType } + + fn epsilon(&'a self) -> usize { 7331 } +} + +impl Eta for ZetaType { + fn eta(self) -> usize { 7 } +} + +// Desugared forms to check against: + +pub fn desugared_bound(beta: &B) -> usize +where + B: Beta, + B::Gamma: Alpha +{ + let gamma: B::Gamma = beta.gamma(); + assert_alpha::(gamma) +} + +pub fn desugared_bound_region(beta: &B) -> usize +where + B: Beta, + B::Gamma: 'static, +{ + assert_static::(beta.gamma()) +} + +pub fn desugared_bound_multi(beta: B) -> usize +where + B: Copy + Beta, + B::Gamma: Alpha + 'static + Delta, +{ + assert_alpha::(beta.gamma()) + + assert_static::(beta.gamma()) + + assert_delta::(beta.gamma()) +} + +pub fn desugared_bound_region_specific<'a, B: ?Sized>(gamma: &'a B::Gamma) -> usize +where + B: Beta, + B::Gamma: 'a + Epsilon<'a>, +{ + assert_epsilon_specific::(gamma) +} + +pub fn desugared_bound_region_forall(beta: &B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, +{ + assert_epsilon_forall::(); + let g1: B::Gamma = beta.gamma(); + let g2: B::Gamma = g1; + assert_epsilon_specific::(&g1) + + assert_epsilon_specific::(&g2) +} + +pub fn desugared_bound_region_forall2(beta: &B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, + for<'a> >::Zeta: Eta, +{ + let gamma = beta.gamma(); + assert_forall_epsilon_zeta_satisfies_eta::(gamma) +} + +pub fn desugared_contraint_region_forall(beta: &B) -> usize +where + for<'a> &'a B: Beta, + for<'a> <&'a B as Beta>::Gamma: Alpha, +{ + let g1 = beta.gamma(); + let g2 = beta.gamma(); + assert_alpha(g1) + assert_alpha(g2) +} + +pub fn desugared_bound_nested(beta: &B) -> usize +where + B: Beta, + B::Gamma: Copy + Alpha + Beta, + ::Gamma: Delta, +{ + let go = beta.gamma(); + let gi = go.gamma(); + go.alpha() + gi.delta() +} + +pub fn desugared() { + let beta = BetaType; + let gamma = beta.gamma(); + + assert_eq!(42, desugared_bound(&beta)); + assert_eq!(24, desugared_bound_region(&beta)); + assert_eq!(42 + 24 + 1337, desugared_bound_multi(beta)); + assert_eq!(7331, desugared_bound_region_specific::(&gamma)); + assert_eq!(7331 * 2, desugared_bound_region_forall(&beta)); + assert_eq!(42 + 1337, desugared_bound_nested(&beta)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs new file mode 100644 index 000000000000..7d587ac8b381 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs @@ -0,0 +1,69 @@ +// NOTE: rustc cannot currently handle bounds of the form `for<'a> >::Assoc: Baz`. +// This should hopefully be fixed with Chalk. +// ignore-compare-mode-chalk + +#![feature(associated_type_bounds)] + +use std::fmt::Debug; +use std::iter::Once; + +trait Lam { + type App; +} + +#[derive(Clone)] +struct L1; +impl<'a> Lam<&'a u8> for L1 { + type App = u8; +} + +#[derive(Clone)] +struct L2; +impl<'a, 'b> Lam<&'a &'b u8> for L2 { + type App = u8; +} + +trait Case1 { + type C: Clone + Iterator Lam<&'a u8, App: Debug>> + Sync>; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +} + +pub struct S1; +impl Case1 for S1 { + type C = Once>; +} + +fn assume_case1() { + fn assert_a<_0, A>() + where + A: Iterator, + _0: Debug, + { + } + assert_a::<_, T::A>(); + + fn assert_b<_0, B>() + where + B: Iterator, + _0: 'static, + { + } + assert_b::<_, T::B>(); + + fn assert_c<_0, _1, _2, C>() + where + C: Clone + Iterator, + _2: Send + Iterator, + _1: for<'a> Lam<&'a u8, App = _0>, + _0: Debug, + { + } + assert_c::<_, _, _, T::C>(); +} + +fn main() { + assume_case1(S1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs new file mode 100644 index 000000000000..ecf43b477623 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs @@ -0,0 +1,55 @@ +#![feature(associated_type_bounds)] + +use std::fmt::Debug; +use std::iter::Empty; +use std::ops::Range; + +trait Lam { type App; } + +#[derive(Clone)] +struct L1; +impl<'a> Lam<&'a u8> for L1 { type App = u8; } + +#[derive(Clone)] +struct L2; +impl<'a, 'b> Lam<&'a &'b u8> for L2 { type App = u8; } + +trait Case1 { + type A: Iterator; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + type B: Iterator; +} + +pub struct S1; +impl Case1 for S1 { + type A = Empty; + type B = Range; +} + +// Ensure we don't have opaque `impl Trait` desugaring: + +// What is this supposed to mean? Rustc currently lowers `: Default` in the +// bounds of `Out`, but trait selection can't find the bound since it applies +// to a type other than `Self::Out`. +pub trait Foo { type Out: Baz; } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +pub trait Baz { type Assoc; } + +#[derive(Default)] +struct S2; +#[derive(Default)] +struct S3; +struct S4; +struct S5; +struct S6; +struct S7; + +impl Foo for S6 { type Out = S4; } +impl Foo for S7 { type Out = S5; } + +impl Baz for S4 { type Assoc = S2; } +impl Baz for S5 { type Assoc = S3; } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/duplicate.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/duplicate.rs new file mode 100644 index 000000000000..66580514eabd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/duplicate.rs @@ -0,0 +1,160 @@ +// ignore-tidy-linelength + +#![feature(associated_type_bounds)] +#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_bindings)] // { dg-warning "" "" { target *-*-* } } +#![feature(untagged_unions)] + +use std::iter; + +struct SI1> { f: T } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +struct SI2> { f: T } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +struct SI3> { f: T } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +struct SW1 where T: Iterator { f: T } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +struct SW2 where T: Iterator { f: T } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +struct SW3 where T: Iterator { f: T } +// { dg-error ".E0719." "" { target *-*-* } .-1 } + +enum EI1> { V(T) } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +enum EI2> { V(T) } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +enum EI3> { V(T) } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +enum EW1 where T: Iterator { V(T) } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +enum EW2 where T: Iterator { V(T) } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +enum EW3 where T: Iterator { V(T) } +// { dg-error ".E0719." "" { target *-*-* } .-1 } + +union UI1> { f: T } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +union UI2> { f: T } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +union UI3> { f: T } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +union UW1 where T: Iterator { f: T } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +union UW2 where T: Iterator { f: T } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +union UW3 where T: Iterator { f: T } +// { dg-error ".E0719." "" { target *-*-* } .-1 } + +fn FI1>() {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +fn FI2>() {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +fn FI3>() {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +fn FW1() where T: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +fn FW2() where T: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +fn FW3() where T: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } + +fn FRPIT1() -> impl Iterator { iter::empty() } +fn FRPIT2() -> impl Iterator { iter::empty() } +fn FRPIT3() -> impl Iterator { iter::empty() } +fn FAPIT1(_: impl Iterator) {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +fn FAPIT2(_: impl Iterator) {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +fn FAPIT3(_: impl Iterator) {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } + +const CIT1: impl Iterator = iter::empty(); +// { dg-error ".E0719." "" { target *-*-* } .-1 } +const CIT2: impl Iterator = iter::empty(); +// { dg-error ".E0719." "" { target *-*-* } .-1 } +const CIT3: impl Iterator = iter::empty(); +// { dg-error ".E0719." "" { target *-*-* } .-1 } +static SIT1: impl Iterator = iter::empty(); +// { dg-error ".E0719." "" { target *-*-* } .-1 } +static SIT2: impl Iterator = iter::empty(); +// { dg-error ".E0719." "" { target *-*-* } .-1 } +static SIT3: impl Iterator = iter::empty(); +// { dg-error ".E0719." "" { target *-*-* } .-1 } + +fn lit1() { let _: impl Iterator = iter::empty(); } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +fn lit2() { let _: impl Iterator = iter::empty(); } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +fn lit3() { let _: impl Iterator = iter::empty(); } +// { dg-error ".E0719." "" { target *-*-* } .-1 } + +type TAI1> = T; +// { dg-error ".E0719." "" { target *-*-* } .-1 } +type TAI2> = T; +// { dg-error ".E0719." "" { target *-*-* } .-1 } +type TAI3> = T; +// { dg-error ".E0719." "" { target *-*-* } .-1 } +type TAW1 where T: Iterator = T; +// { dg-error ".E0719." "" { target *-*-* } .-1 } +type TAW2 where T: Iterator = T; +// { dg-error ".E0719." "" { target *-*-* } .-1 } +type TAW3 where T: Iterator = T; +// { dg-error ".E0719." "" { target *-*-* } .-1 } + +type ETAI1> = impl Copy; +// { dg-error ".E0719." "" { target *-*-* } .-1 } +type ETAI2> = impl Copy; +// { dg-error ".E0719." "" { target *-*-* } .-1 } +type ETAI3> = impl Copy; +// { dg-error ".E0719." "" { target *-*-* } .-1 } +type ETAI4 = impl Iterator; +// { dg-error ".E0719." "" { target *-*-* } .-1 } +type ETAI5 = impl Iterator; +// { dg-error ".E0719." "" { target *-*-* } .-1 } +type ETAI6 = impl Iterator; +// { dg-error ".E0719." "" { target *-*-* } .-1 } + +trait TRI1> {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +trait TRI2> {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +trait TRI3> {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +trait TRS1: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +trait TRS2: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +trait TRS3: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +trait TRW1 where T: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +trait TRW2 where T: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +trait TRW3 where T: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +trait TRSW1 where Self: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +// { dg-error ".E0719." "" { target *-*-* } .-2 } +trait TRSW2 where Self: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +// { dg-error ".E0719." "" { target *-*-* } .-2 } +trait TRSW3 where Self: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } +// { dg-error ".E0719." "" { target *-*-* } .-2 } +trait TRA1 { type A: Iterator; } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +trait TRA2 { type A: Iterator; } +// { dg-error ".E0719." "" { target *-*-* } .-1 } +trait TRA3 { type A: Iterator; } +// { dg-error ".E0719." "" { target *-*-* } .-1 } + +type TADyn1 = dyn Iterator; +// { dg-error ".E0719." "" { target *-*-* } .-1 } +type TADyn2 = Box>; +// { dg-error ".E0719." "" { target *-*-* } .-1 } +type TADyn3 = dyn Iterator; +// { dg-error ".E0719." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/dyn-impl-trait-type.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/dyn-impl-trait-type.rs new file mode 100644 index 000000000000..ac5000b3001c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/dyn-impl-trait-type.rs @@ -0,0 +1,67 @@ +// run-pass + +#![feature(associated_type_bounds)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +type Et1 = Box>; +fn def_et1() -> Et1 { Box::new(S1) } +pub fn use_et1() { assert_copy(def_et1().mk()); } + +type Et2 = Box>; +fn def_et2() -> Et2 { Box::new(S1) } +pub fn use_et2() { assert_static(def_et2().mk()); } + +type Et3 = Box>>>>; +fn def_et3() -> Et3 { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(&self) -> Self::As1 { 0..10 } + }; + Box::new(A) +} +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +type Et4 = Box Tr2<'a>>>; +fn def_et4() -> Et4 { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + Box::new(A) +} +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/dyn-lcsit.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/dyn-lcsit.rs new file mode 100644 index 000000000000..0c26eaccb7d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/dyn-lcsit.rs @@ -0,0 +1,70 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(impl_trait_in_bindings)] +// { dg-warning "" "" { target *-*-* } .-1 } +#![allow(non_upper_case_globals)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +#[derive(Copy, Clone)] +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +const cdef_et1: &dyn Tr1 = &S1; +const sdef_et1: &dyn Tr1 = &S1; +pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); } + +const cdef_et2: &(dyn Tr1 + Sync) = &S1; +static sdef_et2: &(dyn Tr1 + Sync) = &S1; +pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); } + +const cdef_et3: &dyn Tr1>>> = { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(&self) -> Self::As1 { 0..10 } + }; + &A +}; +pub fn use_et3() { + let _0 = cdef_et3.mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +const cdef_et4: &(dyn Tr1 Tr2<'a>> + Sync) = { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + &A +}; +static sdef_et4: &(dyn Tr1 Tr2<'a>> + Sync) = cdef_et4; +pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/dyn-rpit-and-let.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/dyn-rpit-and-let.rs new file mode 100644 index 000000000000..3318591f3009 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/dyn-rpit-and-let.rs @@ -0,0 +1,74 @@ +// run-pass + +// FIXME: uncomment let binding types below when `impl_trait_in_bindings` feature is fixed. + +#![feature(associated_type_bounds)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +fn def_et1() -> Box> { + let x /* : Box> */ = Box::new(S1); + x +} +pub fn use_et1() { assert_copy(def_et1().mk()); } + +fn def_et2() -> Box> { + let x /* : Box> */ = Box::new(S1); + x +} +pub fn use_et2() { assert_static(def_et2().mk()); } + +fn def_et3() -> Box>>>> { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(&self) -> Self::As1 { 0..10 } + }; + let x /* : Box>>>> */ + = Box::new(A); + x +} +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +fn def_et4() -> Box Tr2<'a>>> { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + let x /* : Box Tr2<'a>>> */ = Box::new(A); + x +} +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/entails-sized-object-safety.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/entails-sized-object-safety.rs new file mode 100644 index 000000000000..2e868776b808 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/entails-sized-object-safety.rs @@ -0,0 +1,27 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(associated_type_bounds)] + +trait Tr1: Sized { type As1; } +trait Tr2<'a>: Sized { type As2; } + +trait ObjTr1 { fn foo() -> Self where Self: Tr1; } +fn _assert_obj_safe_1(_: Box) {} + +trait ObjTr2 { fn foo() -> Self where Self: Tr1; } +fn _assert_obj_safe_2(_: Box) {} + +trait ObjTr3 { fn foo() -> Self where Self: Tr1 + 'static + Copy>; } +fn _assert_obj_safe_3(_: Box) {} + +trait ObjTr4 { fn foo() -> Self where Self: Tr1 Tr2<'a>>; } +fn _assert_obj_safe_4(_: Box) {} + +trait ObjTr5 { fn foo() -> Self where for<'a> Self: Tr1>; } +fn _assert_obj_safe_5(_: Box) {} + +trait ObjTr6 { fn foo() -> Self where Self: for<'a> Tr1 Tr2<'b>>>; } +fn _assert_obj_safe_6(_: Box) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/enum-bounds.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/enum-bounds.rs new file mode 100644 index 000000000000..8d8cb97ea85c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/enum-bounds.rs @@ -0,0 +1,123 @@ +// run-pass + +#![feature(associated_type_bounds)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } +trait Tr3 { type As3; } +trait Tr4<'a> { type As4; } +trait Tr5 { type As5; } + +impl Tr1 for &str { type As1 = bool; } +impl Tr2 for bool { type As2 = u8; } +impl Tr3 for u8 { type As3 = fn() -> u8; } +impl Tr1 for () { type As1 = (usize,); } +impl<'a> Tr4<'a> for (usize,) { type As4 = u8; } +impl Tr5 for bool { type As5 = u16; } + +enum En1> { + Outest(T), + Outer(T::As1), + Inner(::As2), +} + +fn wrap_en1_1(x: T) -> En1 where T: Tr1, T::As1: Tr2 { + En1::Outest(x) +} + +fn wrap_en1_2(x: T::As1) -> En1 where T: Tr1, T::As1: Tr2 { + En1::Outer(x) +} + +fn wrap_en1_3(x: ::As2) -> En1 where T: Tr1, T::As1: Tr2 { + En1::Inner(x) +} + +enum En2>> { + V0(T), + V1(T::As1), + V2(::As2), + V3(<::As2 as Tr3>::As3), +} + +enum En3> { + V0(T), + V1(&'static T::As1), +} + +enum En4<'x1, 'x2, T: Tr1 Tr4<'l>>> { + V0(&'x1 >::As4), + V1(&'x2 >::As4), +} + +enum _En5<'x1, 'x2, T: Tr1 Tr4<'l, As4: Copy>>> { + _V0(&'x1 >::As4), + _V1(&'x2 >::As4), +} + +enum En6 +where + T: Tr1, +{ + V0(T), + V1(::As2), + V2(&'static T::As1), + V3(::As5), +} + +enum _En7<'a, 'b, T> // `::As2: 'a` is implied. +where + T: Tr1, +{ + V0(&'a T), + V1(&'b ::As2), +} + +fn _make_en7<'a, 'b, T>(x: _En7<'a, 'b, T>) +where + T: Tr1, +{ + match x { + _En7::V0(x) => { + let _: &'a T = &x; + }, + _En7::V1(_) => {}, + } +} + +enum EnSelf where Self: Tr1 { + V0(T), + V1(::As1), + V2(<::As1 as Tr2>::As2), +} + +impl Tr1 for EnSelf<&'static str> { type As1 = bool; } + +fn main() { + if let En1::Outest("foo") = wrap_en1_1::<_>("foo") {} else { panic!() }; + if let En1::Outer(true) = wrap_en1_2::<&str>(true) {} else { panic!() }; + if let En1::Inner(24u8) = wrap_en1_3::<&str>(24u8) {} else { panic!() }; + + let _ = En2::<_>::V0("151571"); + let _ = En2::<&str>::V1(false); + let _ = En2::<&str>::V2(42u8); + let _ = En2::<&str>::V3(|| 12u8); + + let _ = En3::<_>::V0("deadbeef"); + let _ = En3::<&str>::V1(&true); + + let f1 = (1,); + let f2 = (2,); + let _ = En4::<()>::V0(&f1.0); + let _ = En4::<()>::V1(&f2.0); + + let _ = En6::<_>::V0("bar"); + let _ = En6::<&str>::V1(24u8); + let _ = En6::<&str>::V2(&false); + let _ = En6::<&str>::V3(12u16); + + let _ = EnSelf::<_>::V0("foo"); + let _ = EnSelf::<&'static str>::V1(true); + let _ = EnSelf::<&'static str>::V2(24u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-apit.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-apit.rs new file mode 100644 index 000000000000..080b67fdbdc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-apit.rs @@ -0,0 +1,60 @@ +// run-pass +// aux-build:fn-aux.rs + +#![allow(unused)] +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +fn apit_bound(beta: impl Beta) -> usize { + desugared_bound(beta) +} + +fn apit_bound_region(beta: impl Beta) -> usize { + desugared_bound_region(beta) +} + +fn apit_bound_multi( + beta: impl Copy + Beta +) -> usize { + desugared_bound_multi(beta) +} + +fn apit_bound_region_forall( + beta: impl Beta Epsilon<'a>> +) -> usize { + desugared_bound_region_forall(beta) +} + +fn apit_bound_region_forall2( + beta: impl Beta Epsilon<'a, Zeta: Eta>> +) -> usize { + desugared_bound_region_forall2(beta) +} + +fn apit_bound_nested( + beta: impl Beta> +) -> usize { + desugared_bound_nested(beta) +} + +fn apit_bound_nested2( + beta: impl Beta> +) -> usize { + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let _gamma = beta.gamma(); + + assert_eq!(42, apit_bound(beta)); + assert_eq!(24, apit_bound_region(beta)); + assert_eq!(42 + 24 + 1337, apit_bound_multi(beta)); + assert_eq!(7331 * 2, apit_bound_region_forall(beta)); + assert_eq!(42 + 1337, apit_bound_nested(beta)); + assert_eq!(42 + 1337, apit_bound_nested2(beta)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-aux.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-aux.rs new file mode 100644 index 000000000000..6f5377ec8c33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-aux.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +fn main() { + desugared(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-dyn-apit.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-dyn-apit.rs new file mode 100644 index 000000000000..69af7f948726 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-dyn-apit.rs @@ -0,0 +1,62 @@ +// run-pass +// aux-build:fn-dyn-aux.rs + +#![allow(unused)] +#![feature(associated_type_bounds)] + +extern crate fn_dyn_aux; + +use fn_dyn_aux::*; + +// ATB, APIT (dyn trait): + +fn dyn_apit_bound(beta: &dyn Beta) -> usize { + desugared_bound(beta) +} + +fn dyn_apit_bound_region(beta: &dyn Beta) -> usize { + desugared_bound_region(beta) +} + +fn dyn_apit_bound_multi( + beta: &(dyn Beta + Send) +) -> usize { + desugared_bound_multi(beta) +} + +fn dyn_apit_bound_region_forall( + beta: &dyn Beta Epsilon<'a>> +) -> usize { + desugared_bound_region_forall(beta) +} + +fn dyn_apit_bound_region_forall2( + beta: &dyn Beta Epsilon<'a, Zeta: Eta>> +) -> usize { + desugared_bound_region_forall2(beta) +} + +fn dyn_apit_bound_nested( + beta: &dyn Beta> +) -> usize { + desugared_bound_nested(beta) +} + +fn dyn_apit_bound_nested2( + beta: &dyn Beta> +) -> usize { + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let _gamma = beta.gamma(); + + assert_eq!(42, dyn_apit_bound(&beta)); + assert_eq!(24, dyn_apit_bound_region(&beta)); + assert_eq!(42 + 24 + 1337, dyn_apit_bound_multi(&beta)); + assert_eq!(7331 * 2, dyn_apit_bound_region_forall(&beta)); + assert_eq!(42 + 1337, dyn_apit_bound_nested(&beta)); + assert_eq!(42 + 1337, dyn_apit_bound_nested2(&beta)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-inline.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-inline.rs new file mode 100644 index 000000000000..e1453d5d1dab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-inline.rs @@ -0,0 +1,64 @@ +// run-pass +// aux-build:fn-aux.rs + +#![allow(unused)] +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +// ATB, Type parameters, Inline bounds: + +fn inline_bound>(beta: B) -> usize { + desugared_bound(beta) +} + +fn inline_bound_region>(beta: B) -> usize { + desugared_bound_region(beta) +} + +fn inline_bound_multi>( + beta: B +) -> usize { + desugared_bound_multi(beta) +} + +fn inline_bound_region_specific<'a, B: Beta>>( + gamma: &'a B::Gamma +) -> usize { + desugared_bound_region_specific::(gamma) +} + +fn inline_bound_region_forall Epsilon<'a>>>( + beta: B +) -> usize { + desugared_bound_region_forall(beta) +} + +fn inline_bound_region_forall2 Epsilon<'a, Zeta: Eta>>>( + beta: B +) -> usize { + desugared_bound_region_forall2(beta) +} + +fn inline_bound_nested>>( + beta: B +) -> usize { + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let gamma = beta.gamma(); + + assert_eq!(42, inline_bound(beta)); + assert_eq!(24, inline_bound_region(beta)); + assert_eq!(42 + 24 + 1337, inline_bound_multi(beta)); + assert_eq!(7331, inline_bound_region_specific::(&gamma)); + assert_eq!(7331 * 2, inline_bound_region_forall(beta)); + // FIXME: requires lazy normalization. + // assert_eq!(7331 * 2, inline_bound_region_forall2(beta)); + assert_eq!(42 + 1337, inline_bound_nested(beta)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-where.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-where.rs new file mode 100644 index 000000000000..d1f17194dc33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-where.rs @@ -0,0 +1,80 @@ +// run-pass +// aux-build:fn-aux.rs + +#![allow(unused)] +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +// ATB, Type parameters, Where-clauses: + +fn where_bound(beta: B) -> usize +where + B: Beta +{ + desugared_bound(beta) +} + +fn where_bound_region(beta: B) -> usize +where + B: Beta +{ + desugared_bound_region(beta) +} + +fn where_bound_multi(beta: B) -> usize +where + B: Copy + Beta, +{ + desugared_bound_multi(beta) +} + +fn where_bound_region_specific<'a, B>(gamma: &'a B::Gamma) -> usize +where + B: Beta>, +{ + desugared_bound_region_specific::(gamma) +} + +fn where_bound_region_forall(beta: B) -> usize +where + B: Beta Epsilon<'a>>, +{ + desugared_bound_region_forall(beta) +} + +fn where_bound_region_forall2(beta: B) -> usize +where + B: Beta Epsilon<'a, Zeta: Eta>>, +{ + desugared_bound_region_forall2(beta) +} + +fn where_contraint_region_forall(beta: B) -> usize +where + for<'a> &'a B: Beta, +{ + desugared_contraint_region_forall(beta) +} + +fn where_bound_nested(beta: B) -> usize +where + B: Beta>, +{ + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let gamma = beta.gamma(); + + assert_eq!(42, where_bound(beta)); + assert_eq!(24, where_bound_region(beta)); + assert_eq!(42 + 24 + 1337, where_bound_multi(beta)); + assert_eq!(7331, where_bound_region_specific::(&gamma)); + assert_eq!(7331 * 2, where_bound_region_forall::(beta)); + assert_eq!(42 + 1337, where_bound_nested::(beta)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-wrap-apit.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-wrap-apit.rs new file mode 100644 index 000000000000..96edaa934460 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/fn-wrap-apit.rs @@ -0,0 +1,66 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] +#![allow(dead_code)] + +extern crate fn_aux; + +use fn_aux::*; + +// ATB, APIT + Wrap: + +struct Wrap(T); + +fn wrap_apit_bound(beta: Wrap>) -> usize { + desugared_bound(beta.0) +} + +fn wrap_apit_bound_region(beta: Wrap>) -> usize { + desugared_bound_region(beta.0) +} + +fn wrap_apit_bound_multi( + beta: Wrap> +) -> usize { + desugared_bound_multi(beta.0) +} + +fn wrap_apit_bound_region_forall( + beta: Wrap Epsilon<'a>>> +) -> usize { + desugared_bound_region_forall(beta.0) +} + +fn wrap_apit_bound_region_forall2( + beta: Wrap Epsilon<'a, Zeta: Eta>>> +) -> usize { + desugared_bound_region_forall2(beta.0) +} + +fn wrap_apit_bound_nested( + beta: Wrap>> +) -> usize { + desugared_bound_nested(beta.0) +} + +fn wrap_apit_bound_nested2( + beta: Wrap>> +) -> usize { + desugared_bound_nested(beta.0) +} + +fn main() { + let beta = BetaType; + let _gamma = beta.gamma(); + + assert_eq!(42, wrap_apit_bound(Wrap(beta))); + assert_eq!(24, wrap_apit_bound_region(Wrap(beta))); + assert_eq!(42 + 24 + 1337, wrap_apit_bound_multi(Wrap(beta))); + assert_eq!(7331 * 2, wrap_apit_bound_region_forall(Wrap(beta))); + // FIXME: requires lazy normalization. + // assert_eq!(7331 * 2, wrap_apit_bound_region_forall2(Wrap(beta))); + assert_eq!(42 + 1337, wrap_apit_bound_nested(Wrap(beta))); + assert_eq!(42 + 1337, wrap_apit_bound_nested2(Wrap(beta))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/implied-region-constraints.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/implied-region-constraints.rs new file mode 100644 index 000000000000..96b7c1ce7500 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/implied-region-constraints.rs @@ -0,0 +1,46 @@ +#![feature(associated_type_bounds)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } + +struct St<'a, 'b, T: Tr1> { // `T: 'b` is *not* implied! + f0: &'a T, // `T: 'a` is implied. + f1: &'b ::As2, // `::As2: 'a` is implied. +} + +fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + // This should fail because `T: 'b` is not implied from `WF(St<'a, 'b, T>)`. + let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0; +// { dg-error ".E0623." "" { target *-*-* } .-1 } +} + +enum En7<'a, 'b, T> // `::As2: 'a` is implied. +where + T: Tr1, + T::As1: Tr2, +{ + V0(&'a T), + V1(&'b ::As2), +} + +fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + match x { + En7::V0(x) => { + // Also fails for the same reason as above: + let _failure_proves_not_implied_outlives_region_b: &'b T = &x; +// { dg-error ".E0623." "" { target *-*-* } .-1 } + }, + En7::V1(_) => {}, + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/inside-adt.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/inside-adt.rs new file mode 100644 index 000000000000..f557f6f65e21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/inside-adt.rs @@ -0,0 +1,30 @@ +#![feature(associated_type_bounds)] +#![feature(untagged_unions)] + +struct S1 { f: dyn Iterator } +// { dg-error "" "" { target *-*-* } .-1 } +struct S2 { f: Box> } +// { dg-error "" "" { target *-*-* } .-1 } +struct S3 { f: dyn Iterator } +// { dg-error "" "" { target *-*-* } .-1 } + +enum E1 { V(dyn Iterator) } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +enum E2 { V(Box>) } +// { dg-error "" "" { target *-*-* } .-1 } +enum E3 { V(dyn Iterator) } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + +union U1 { f: dyn Iterator } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +union U2 { f: Box> } +// { dg-error "" "" { target *-*-* } .-1 } +union U3 { f: dyn Iterator } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-61752.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-61752.rs new file mode 100644 index 000000000000..e5de9ad4872e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-61752.rs @@ -0,0 +1,25 @@ +// check-pass + +#![feature(associated_type_bounds)] + +trait Foo { + type Bar; +} + +impl Foo for () { + type Bar = (); +} + +fn a() where F::Bar: Copy {} + +fn b() where ::Bar: Copy {} + +// This used to complain about ambiguous associated types. +fn c>() where F::Bar: Copy {} + +fn main() { + a::<()>(); + b::<()>(); + c::<()>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-70292.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-70292.rs new file mode 100644 index 000000000000..01e3525060d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-70292.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(associated_type_bounds)] + +fn foo(_: F) +where + F: for<'a> Trait, +{ +} + +trait Trait { + type Output; +} + +impl Trait for T { + type Output = (); +} + +fn main() { + foo(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-71443-1.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-71443-1.rs new file mode 100644 index 000000000000..8c98589bc976 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-71443-1.rs @@ -0,0 +1,10 @@ +#![feature(associated_type_bounds)] + +struct Incorrect; + +fn hello Iterator>() { + Incorrect // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-71443-2.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-71443-2.rs new file mode 100644 index 000000000000..9a7cf813145c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-71443-2.rs @@ -0,0 +1,12 @@ +// check-pass + +#![feature(associated_type_bounds)] + +fn hello<'b, F>() +where + for<'a> F: Iterator + 'b, +{ +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-73818.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-73818.rs new file mode 100644 index 000000000000..2f9f439b5611 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/issue-73818.rs @@ -0,0 +1,26 @@ +// Test that associated type bounds are correctly normalized when checking +// default associated type values. +// check-pass + +#![allow(incomplete_features)] +#![feature(specialization)] + +#[derive(PartialEq)] +enum Never {} +trait Foo { + type Assoc: PartialEq; // PartialEq<::Assoc> +} +impl Foo for T { + default type Assoc = Never; +} + +trait Trait1 { + type Selection: PartialEq; +} +trait Trait2: PartialEq {} +impl Trait1 for T { + default type Selection = T; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/lcsit.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/lcsit.rs new file mode 100644 index 000000000000..f5b78dd7b97a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/lcsit.rs @@ -0,0 +1,79 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(impl_trait_in_bindings)] +// { dg-warning "" "" { target *-*-* } .-1 } +#![allow(non_upper_case_globals)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +#[derive(Copy, Clone)] +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +const cdef_et1: impl Copy + Tr1 = { + let x: impl Copy + Tr1 = S1; + x +}; +static sdef_et1: impl Copy + Tr1 = cdef_et1; +pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); } + +const cdef_et2: impl Tr1 = { + let x: impl Tr1 = S1; + x +}; +static sdef_et2: impl Tr1 = cdef_et2; +pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); } + +const cdef_et3: impl Tr1>>> = { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(&self) -> Self::As1 { 0..10 } + }; + let x: impl Tr1>>> = A; + x +}; +pub fn use_et3() { + let _0 = cdef_et3.mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +const cdef_et4: impl Copy + Tr1 Tr2<'a>> = { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + let x: impl Copy + Tr1 Tr2<'a>> = A; + x +}; + +static sdef_et4: impl Copy + Tr1 Tr2<'a>> = cdef_et4; +pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/rpit.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/rpit.rs new file mode 100644 index 000000000000..4ae959bc76fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/rpit.rs @@ -0,0 +1,65 @@ +// run-pass + +#![feature(associated_type_bounds)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(self) -> Self::As1 { S2 } } + +fn def_et1() -> impl Tr1 { S1 } +pub fn use_et1() { assert_copy(def_et1().mk()); } + +fn def_et2() -> impl Tr1 { S1 } +pub fn use_et2() { assert_static(def_et2().mk()); } + +fn def_et3() -> impl Tr1>>> { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(self) -> Self::As1 { 0..10 } + }; + A +} + +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +fn def_et4() -> impl Tr1 Tr2<'a>> { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + A +} + +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/struct-bounds.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/struct-bounds.rs new file mode 100644 index 000000000000..a729614d4ff8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/struct-bounds.rs @@ -0,0 +1,117 @@ +// run-pass + +#![allow(unused)] +#![feature(associated_type_bounds)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } +trait Tr3 {} +trait Tr4<'a> { type As4; } +trait Tr5 { type As5; } + +impl Tr1 for &str { type As1 = bool; } +impl Tr2 for bool { type As2 = u8; } +impl Tr3 for u8 {} +impl Tr1 for () { type As1 = (usize,); } +impl<'a> Tr4<'a> for (usize,) { type As4 = u8; } +impl Tr5 for bool { type As5 = u16; } + +struct St1> { + outest: T, + outer: T::As1, + inner: ::As2, +} + +fn unwrap_1_st1>(x: St1) -> (T, T::As1, ::As2) { + (x.outest, x.outer, x.inner) +} + +fn unwrap_2_st1(x: St1) -> (T, T::As1, ::As2) +where + T: Tr1, + T::As1: Tr2, +{ + unwrap_1_st1(x) +} + +struct St2>> { + outest: T, + outer: T::As1, + inner: ::As2, +} + +struct St3> { + outest: T, + outer: &'static T::As1, +} + +struct St4<'x1, 'x2, T: Tr1 Tr4<'l>>> { + f1: &'x1 >::As4, + f2: &'x2 >::As4, +} + +struct St5<'x1, 'x2, T: Tr1 Tr4<'l, As4: Copy>>> { + f1: &'x1 >::As4, + f2: &'x2 >::As4, +} + +struct St6 +where + T: Tr1, +{ + f0: T, + f1: ::As2, + f2: &'static T::As1, + f3: ::As5, +} + +struct St7<'a, 'b, T> // `::As2: 'a` is implied. +where + T: Tr1, +{ + f0: &'a T, + f1: &'b ::As2, +} + +fn _use_st7<'a, 'b, T>(x: St7<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + let _: &'a T = &x.f0; +} + +struct StSelf where Self: Tr1 { + f2: <::As1 as Tr2>::As2, +} + +impl Tr1 for StSelf<&'static str> { type As1 = bool; } + +fn main() { + let st1 = St1 { outest: "foo", outer: true, inner: 42u8 }; + assert_eq!(("foo", true, 42), unwrap_1_st1(st1)); + + let _ = St2 { outest: "foo", outer: true, inner: 42u8 }; + + let _ = St3 { outest: "foo", outer: &true }; + + let f1 = (1,); + let f2 = (2,); + let st4 = St4::<()> { f1: &f1.0, f2: &f2.0, }; + assert_eq!((&1, &2), (st4.f1, st4.f2)); + + // FIXME: requires lazy normalization. + /* + let f1 = (1,); + let f2 = (2,); + let st5 = St5::<()> { f1: &f1.0, f2: &f2.0, }; + assert_eq!((&1, &2), (st5.f1, st5.f2)); + */ + + let st6 = St6 { f0: "bar", f1: 24u8, f2: &true, f3: 12u16, }; + assert_eq!(("bar", 24, &true, 12), (st6.f0, st6.f1, st6.f2, st6.f3)); + + let stself = StSelf::<&'static str> { f2: 42u8 }; + assert_eq!(stself.f2, 42u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/trait-alias-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/trait-alias-impl-trait.rs new file mode 100644 index 000000000000..45489533db92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/trait-alias-impl-trait.rs @@ -0,0 +1,68 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(type_alias_impl_trait)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(self) -> Self::As1 { S2 } } + +type Et1 = impl Tr1; +fn def_et1() -> Et1 { S1 } +pub fn use_et1() { assert_copy(def_et1().mk()); } + +type Et2 = impl Tr1; +fn def_et2() -> Et2 { S1 } +pub fn use_et2() { assert_static(def_et2().mk()); } + +type Et3 = impl Tr1>>>; +fn def_et3() -> Et3 { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(self) -> Self::As1 { 0..10 } + }; + A +} +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +type Et4 = impl Tr1 Tr2<'a>>; +fn def_et4() -> Et4 { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + A +} +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/trait-params.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/trait-params.rs new file mode 100644 index 000000000000..0b9f4c24215f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/trait-params.rs @@ -0,0 +1,118 @@ +// build-pass (FIXME(62277): could be check-pass?) +// ignore-compare-mode-chalk + +#![feature(associated_type_bounds)] + +use std::iter::Once; +use std::ops::Range; + +pub trait Three { type A; type B; type C; } +pub fn assert_three() {} +pub fn assert_iterator() {} +pub fn assert_copy() {} +pub fn assert_static() {} +pub fn assert_send() {} +pub fn assert_forall_into Into<&'a u8>>() {} + +struct A; struct B; +impl<'a> Into<&'a u8> for A { fn into(self) -> &'a u8 { &0 } } +impl Three for B { type A = Range; type B = Range; type C = Range; } + +trait Case1 +where + A: Iterator, + B: Iterator, + C: Iterator, + D: Iterator Into<&'a u8>>, + E: Three, B: Iterator, C: Iterator>, + Self: Three, +{ + fn _a() { + assert_iterator::(); + assert_copy::(); + } + fn _b() { + assert_iterator::(); + assert_static::(); + } + fn _c() { + assert_iterator::(); + assert_copy::(); + assert_static::(); + assert_send::(); + } + fn _d() { + assert_iterator::(); + assert_forall_into::(); + } + fn _e() { + assert_three::(); + assert_iterator::(); + assert_iterator::(); + assert_iterator::(); + assert_copy::<::Item>(); + assert_copy::<::Item>(); + assert_copy::<::Item>(); + } + fn _self() { + assert_three::(); + assert_copy::(); + assert_static::(); + assert_send::(); + } +} + +struct DataCase1; +impl Three for DataCase1 { type A = u8; type B = u8; type C = u8; } +impl Case1, Range, Range, Once, B> for DataCase1 {} + +trait Case2< + A: Iterator, + B: Iterator, + C: Iterator, + D: Iterator Into<&'a u8>>, + E: Three, B: Iterator, C: Iterator>, +>: + Three +{ + fn _a() { + assert_iterator::(); + assert_copy::(); + } + fn _b() { + assert_iterator::(); + assert_static::(); + } + fn _c() { + assert_iterator::(); + assert_copy::(); + assert_static::(); + assert_send::(); + } + fn _d() { + assert_iterator::(); + assert_forall_into::(); + } + fn _e() { + assert_three::(); + assert_iterator::(); + assert_iterator::(); + assert_iterator::(); + assert_copy::<::Item>(); + assert_copy::<::Item>(); + assert_copy::<::Item>(); + } + fn _self() { + assert_three::(); + assert_copy::(); + assert_static::(); + assert_send::(); + } +} + +struct DataCase2; +impl Three for DataCase2 { type A = u8; type B = u8; type C = u8; } +impl Case2, Range, Range, Once, B> for DataCase2 {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/type-alias.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/type-alias.rs new file mode 100644 index 000000000000..c2f8bcce56df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/type-alias.rs @@ -0,0 +1,20 @@ +// check-pass + +#![feature(associated_type_bounds)] + +type _TaWhere1 where T: Iterator = T; // { dg-warning "" "" { target *-*-* } } +type _TaWhere2 where T: Iterator = T; // { dg-warning "" "" { target *-*-* } } +type _TaWhere3 where T: Iterator = T; // { dg-warning "" "" { target *-*-* } } +type _TaWhere4 where T: Iterator = T; // { dg-warning "" "" { target *-*-* } } +type _TaWhere5 where T: Iterator Into<&'a u8>> = T; // { dg-warning "" "" { target *-*-* } } +type _TaWhere6 where T: Iterator> = T; // { dg-warning "" "" { target *-*-* } } + +type _TaInline1> = T; // { dg-warning "" "" { target *-*-* } } +type _TaInline2> = T; // { dg-warning "" "" { target *-*-* } } +type _TaInline3> = T; // { dg-warning "" "" { target *-*-* } } +type _TaInline4> = T; // { dg-warning "" "" { target *-*-* } } +type _TaInline5 Into<&'a u8>>> = T; // { dg-warning "" "" { target *-*-* } } +type _TaInline6>> = T; // { dg-warning "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-type-bounds/union-bounds.rs b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/union-bounds.rs new file mode 100644 index 000000000000..5bc0eda0770a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-type-bounds/union-bounds.rs @@ -0,0 +1,126 @@ +// run-pass +// ignore-compare-mode-chalk + +#![feature(associated_type_bounds)] +#![feature(untagged_unions)] + +#![allow(unused_assignments)] + +trait Tr1: Copy { type As1: Copy; } +trait Tr2: Copy { type As2: Copy; } +trait Tr3: Copy { type As3: Copy; } +trait Tr4<'a>: Copy { type As4: Copy; } +trait Tr5: Copy { type As5: Copy; } + +impl Tr1 for &str { type As1 = bool; } +impl Tr2 for bool { type As2 = u8; } +impl Tr3 for u8 { type As3 = fn() -> u8; } +impl Tr1 for () { type As1 = (usize,); } +impl<'a> Tr4<'a> for (usize,) { type As4 = u8; } +impl Tr5 for bool { type As5 = u16; } + +union Un1> { + outest: T, + outer: T::As1, + inner: ::As2, +} + +union Un2>> { + outest: T, + outer: T::As1, + inner: ::As2, +} + +union Un3> { + outest: T, + outer: &'static T::As1, +} + +union Un4<'x1, 'x2, T: Tr1 Tr4<'l>>> { + f1: &'x1 >::As4, + f2: &'x2 >::As4, +} + +union _Un5<'x1, 'x2, T: Tr1 Tr4<'l, As4: Copy>>> { + f1: &'x1 >::As4, + f2: &'x2 >::As4, +} + +union Un6 +where + T: Tr1, +{ + f0: T, + f1: ::As2, + f2: &'static T::As1, + f3: ::As5, +} + +union _Un7<'a, 'b, T> // `::As2: 'a` is implied. +where + T: Tr1, +{ + f0: &'a T, + f1: &'b ::As2, +} + +unsafe fn _use_un7<'a, 'b, T>(x: _Un7<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + let _: &'a T = &x.f0; +} + +#[derive(Copy, Clone)] +union UnSelf where Self: Tr1, T: Copy { + f0: T, + f1: ::As1, + f2: <::As1 as Tr2>::As2, +} + +impl Tr1 for UnSelf<&'static str> { type As1 = bool; } + +fn main() { + let mut un1 = Un1 { outest: "foo" }; + un1 = Un1 { outer: true }; + assert_eq!(unsafe { un1.outer }, true); + un1 = Un1 { inner: 42u8 }; + assert_eq!(unsafe { un1.inner }, 42u8); + + let mut un2 = Un2 { outest: "bar" }; + assert_eq!(unsafe { un2.outest }, "bar"); + un2 = Un2 { outer: true }; + assert_eq!(unsafe { un2.outer }, true); + un2 = Un2 { inner: 42u8 }; + assert_eq!(unsafe { un2.inner }, 42u8); + + let mut un3 = Un3 { outest: "baz" }; + assert_eq!(unsafe { un3.outest }, "baz"); + un3 = Un3 { outer: &true }; + assert_eq!(unsafe { *un3.outer }, true); + + let f1 = (1,); + let f2 = (2,); + let mut un4 = Un4::<()> { f1: &f1.0 }; + assert_eq!(1, unsafe { *un4.f1 }); + un4 = Un4 { f2: &f2.0 }; + assert_eq!(2, unsafe { *un4.f2 }); + + let mut un6 = Un6 { f0: "bar" }; + assert_eq!(unsafe { un6.f0 }, "bar"); + un6 = Un6 { f1: 24u8 }; + assert_eq!(unsafe { un6.f1 }, 24u8); + un6 = Un6 { f2: &true }; + assert_eq!(unsafe { un6.f2 }, &true); + un6 = Un6 { f3: 12u16 }; + assert_eq!(unsafe { un6.f3 }, 12u16); + + let mut unself = UnSelf::<_> { f0: "selfish" }; + assert_eq!(unsafe { unself.f0 }, "selfish"); + unself = UnSelf { f1: true }; + assert_eq!(unsafe { unself.f1 }, true); + unself = UnSelf { f2: 24u8 }; + assert_eq!(unsafe { unself.f2 }, 24u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associate-type-bound-normalization.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associate-type-bound-normalization.rs new file mode 100644 index 000000000000..4cd40bdc7cb5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associate-type-bound-normalization.rs @@ -0,0 +1,26 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.rs new file mode 100644 index 000000000000..2c8bceb934db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.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) { } +} + +fn a(_: C::Color) { +// { dg-error ".E0221." "" { target *-*-* } .-1 } +} + +fn b(_: C::Color) where C : Vehicle+Box { +// { dg-error ".E0221." "" { target *-*-* } .-1 } +} + +fn c(_: C::Color) where C : Vehicle, C : Box { +// { dg-error ".E0221." "" { target *-*-* } .-1 } +} + +struct D; +impl D where X : Vehicle { + fn d(&self, _: X::Color) where X : Box { } +// { dg-error ".E0221." "" { target *-*-* } .-1 } +} + +trait E { + fn e(&self, _: X::Color) where X : Box; +// { dg-error ".E0221." "" { target *-*-* } .-1 } + + fn f(&self, _: X::Color) where X : Box { } +// { dg-error ".E0221." "" { target *-*-* } .-1 } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs new file mode 100644 index 000000000000..f852de38908b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs @@ -0,0 +1,44 @@ +// 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) { +// { dg-error ".E0221." "" { target *-*-* } .-1 } +} + +fn dent_object(c: dyn BoxCar) { +// { dg-error ".E0191." "" { target *-*-* } .-1 } +// { dg-error ".E0191." "" { target *-*-* } .-2 } +} + +fn paint(c: C, d: C::Color) { +// { dg-error ".E0221." "" { target *-*-* } .-1 } +} + +fn dent_object_2(c: dyn BoxCar) where ::Color = COLOR { +// { dg-error ".E0191." "" { target *-*-* } .-1 } +// { dg-error ".E0191." "" { target *-*-* } .-2 } +} + +fn dent_object_3(c: X) +where X: BoxCar, + X: Vehicle, + X: Box +{} // OK! + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-type-projection-from-supertrait.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-type-projection-from-supertrait.rs new file mode 100644 index 000000000000..82360efbe420 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-type-projection-from-supertrait.rs @@ -0,0 +1,37 @@ +// 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); } // { dg-error ".E0308." "" { target *-*-* } } +fn c() { dent(ModelU, Black); } // { dg-error ".E0308." "" { target *-*-* } } +fn d() { dent(ModelU, Blue); } + +fn e() { ModelT.chip_paint(Black); } +fn f() { ModelT.chip_paint(Blue); } // { dg-error ".E0308." "" { target *-*-* } } +fn g() { ModelU.chip_paint(Black); } // { dg-error ".E0308." "" { target *-*-* } } +fn h() { ModelU.chip_paint(Blue); } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs new file mode 100644 index 000000000000..e023d09e4b86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs @@ -0,0 +1,26 @@ +// 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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-basic.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-basic.rs new file mode 100644 index 000000000000..a647e91d50a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-basic.rs @@ -0,0 +1,15 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-binding-in-trait.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-binding-in-trait.rs new file mode 100644 index 000000000000..4ade68909a22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-binding-in-trait.rs @@ -0,0 +1,37 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-binding-in-where-clause.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-binding-in-where-clause.rs new file mode 100644 index 000000000000..9bd7bb69232f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-binding-in-where-clause.rs @@ -0,0 +1,39 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs new file mode 100644 index 000000000000..f6bcc4a546b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-binding-to-type-defined-in-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) { } +} + +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); } // { dg-error ".E0271." "" { target *-*-* } } +fn c() { black_car(ModelU); } // { dg-error ".E0271." "" { target *-*-* } } +fn d() { blue_car(ModelU); } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-bound-ambiguity.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-bound-ambiguity.rs new file mode 100644 index 000000000000..e0544b3f93c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-bound-ambiguity.rs @@ -0,0 +1,24 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-bound-failure.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-bound-failure.rs new file mode 100644 index 000000000000..230eb362c08c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-bound-failure.rs @@ -0,0 +1,30 @@ +// 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()) // { dg-error ".E0277." "" { target *-*-* } } +} + +fn bar(g: G) -> isize + where G::R : ToInt +{ + ToInt::to_int(&g.get()) // OK +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-bound.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-bound.rs new file mode 100644 index 000000000000..3a8281c45287 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-bound.rs @@ -0,0 +1,44 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-cc.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-cc.rs new file mode 100644 index 000000000000..2a195b23605c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-cc.rs @@ -0,0 +1,19 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-coherence-failure.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-coherence-failure.rs new file mode 100644 index 000000000000..207cfefbfe4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-coherence-failure.rs @@ -0,0 +1,50 @@ +// 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 { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + fn into_cow(self) -> Cow<'a, B> { + self + } +} + +impl<'a, B: ?Sized> IntoCow<'a, B> for &'a B where B: ToOwned { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-conditional-dispatch.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-conditional-dispatch.rs new file mode 100644 index 000000000000..7131d639e43c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-conditional-dispatch.rs @@ -0,0 +1,67 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-constant-type.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-constant-type.rs new file mode 100644 index 000000000000..9baa36f85e1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-constant-type.rs @@ -0,0 +1,32 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-doubleendediterator-object.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-doubleendediterator-object.rs new file mode 100644 index 000000000000..5aa7d0734569 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-doubleendediterator-object.rs @@ -0,0 +1,21 @@ +// run-pass +#![feature(box_syntax)] + +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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs new file mode 100644 index 000000000000..8781bca59375 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs @@ -0,0 +1,18 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-duplicate-binding-in-env.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-duplicate-binding-in-env.rs new file mode 100644 index 000000000000..877cb9c7f76f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-duplicate-binding-in-env.rs @@ -0,0 +1,22 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-enum-field-named.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-enum-field-named.rs new file mode 100644 index 000000000000..f044f49b7390 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-enum-field-named.rs @@ -0,0 +1,36 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-enum-field-numbered.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-enum-field-numbered.rs new file mode 100644 index 000000000000..0bdec3147c01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-enum-field-numbered.rs @@ -0,0 +1,36 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-1.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-1.rs new file mode 100644 index 000000000000..9c95025f00a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-1.rs @@ -0,0 +1,14 @@ +// 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(); // { dg-error ".E0412." "" { target *-*-* } } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-2.rs new file mode 100644 index 000000000000..0736a0ae240b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-2.rs @@ -0,0 +1,20 @@ +// 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) {} +// { dg-error ".E0229." "" { target *-*-* } .-1 } + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-3.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-3.rs new file mode 100644 index 000000000000..54ff34c8024c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-3.rs @@ -0,0 +1,45 @@ +// 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(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + + +pub fn baz(x: &dyn Foo) { + let _: Bar = x.boo(); +} + + +pub fn main() { + let a = 42; + foo1(a); +// { dg-error ".E0271." "" { target *-*-* } .-1 } +// { dg-error ".E0271." "" { target *-*-* } .-2 } + baz(&a); +// { dg-error ".E0271." "" { target *-*-* } .-1 } +// { dg-error ".E0271." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-expr-path.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-expr-path.rs new file mode 100644 index 000000000000..5574a37a4623 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-expr-path.rs @@ -0,0 +1,17 @@ +// 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(); +// { dg-error ".E0229." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-hr.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-hr.rs new file mode 100644 index 000000000000..eec8c371489a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-hr.rs @@ -0,0 +1,117 @@ +// 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::(); // { dg-error ".E0271." "" { target *-*-* } } +} + +pub fn call_bar() { + bar::(); // { dg-error ".E0271." "" { target *-*-* } } + bar::(); +} + +pub fn call_tuple_one() { + tuple_one::(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +pub fn call_tuple_two() { + tuple_two::(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +pub fn call_tuple_three() { + tuple_three::(); +} + +pub fn call_tuple_four() { + tuple_four::(); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-obj.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-obj.rs new file mode 100644 index 000000000000..44aaa189c887 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-eq-obj.rs @@ -0,0 +1,26 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-for-unimpl-trait.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-for-unimpl-trait.rs new file mode 100644 index 000000000000..2d475bdc967b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-for-unimpl-trait.rs @@ -0,0 +1,16 @@ +// run-rustfix +#![allow(unused_variables)] + +trait Get { + type Value; + fn get(&self) -> ::Value; +} + +trait Other { + fn uhoh(&self, foo: U, bar: ::Value) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-from-supertrait.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-from-supertrait.rs new file mode 100644 index 000000000000..4369b708023a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-from-supertrait.rs @@ -0,0 +1,9 @@ +// run-pass + +trait Foo: Iterator {} +trait Bar: Foo {} + +fn main() { + let _: &dyn Bar; +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-impl-redirect.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-impl-redirect.rs new file mode 100644 index 000000000000..7550bdc051cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-impl-redirect.rs @@ -0,0 +1,52 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-ambiguous-context.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-ambiguous-context.rs new file mode 100644 index 000000000000..99f34a119a02 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-ambiguous-context.rs @@ -0,0 +1,30 @@ +trait Get { + type Value; + fn get(&self) -> ::Value; +} + +fn get(x: T, y: U) -> Get::Value {} +// { dg-error ".E0223." "" { target *-*-* } .-1 } + +trait Grab { + type Value; + fn grab(&self) -> Grab::Value; +// { dg-error ".E0223." "" { target *-*-* } .-1 } + + fn get(&self) -> Get::Value; +// { dg-error ".E0223." "" { target *-*-* } .-1 } +} + +trait Bar {} + +trait Foo where Foo::Assoc: Bar { +// { dg-error ".E0223." "" { target *-*-* } .-1 } + type Assoc; +} + +type X = std::ops::Deref::Target; +// { dg-error ".E0223." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-bound-type-arg.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-bound-type-arg.rs new file mode 100644 index 000000000000..00280cc5b99f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-bound-type-arg.rs @@ -0,0 +1,18 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-default-method.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-default-method.rs new file mode 100644 index 000000000000..1e7345a43989 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-default-method.rs @@ -0,0 +1,28 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-fn.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-fn.rs new file mode 100644 index 000000000000..344af080935b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-fn.rs @@ -0,0 +1,29 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-impl-generics.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-impl-generics.rs new file mode 100644 index 000000000000..45b69adf615d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-impl-generics.rs @@ -0,0 +1,37 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-inherent-method.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-inherent-method.rs new file mode 100644 index 000000000000..00ed40cd2e49 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-in-inherent-method.rs @@ -0,0 +1,31 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-incomplete-object.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-incomplete-object.rs new file mode 100644 index 000000000000..d9456d05783c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-incomplete-object.rs @@ -0,0 +1,32 @@ +// 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; +// { dg-error ".E0191." "" { target *-*-* } .-1 } + + let c = &42isize as &dyn Foo; +// { dg-error ".E0191." "" { target *-*-* } .-1 } + + let d = &42isize as &dyn Foo; +// { dg-error ".E0191." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs new file mode 100644 index 000000000000..c4def0206260 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs @@ -0,0 +1,15 @@ +// 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(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-17359.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-17359.rs new file mode 100644 index 000000000000..e7c79318b2cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-17359.rs @@ -0,0 +1,11 @@ +// 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 {} // { dg-error ".E0046." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-20220.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-20220.rs new file mode 100644 index 000000000000..197e69467a35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-20220.rs @@ -0,0 +1,29 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-20346.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-20346.rs new file mode 100644 index 000000000000..b5462c0d7950 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-20346.rs @@ -0,0 +1,36 @@ +// 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); // { dg-error ".E0271." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-20371.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-20371.rs new file mode 100644 index 000000000000..b2f96426d409 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-20371.rs @@ -0,0 +1,10 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-21212.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-21212.rs new file mode 100644 index 000000000000..696386abb473 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-issue-21212.rs @@ -0,0 +1,23 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-in-bounds.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-in-bounds.rs new file mode 100644 index 000000000000..f852cf7e505f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-in-bounds.rs @@ -0,0 +1,36 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-unifield-struct.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-unifield-struct.rs new file mode 100644 index 000000000000..b04378247baa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-unifield-struct.rs @@ -0,0 +1,25 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-outlives.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-outlives.rs new file mode 100644 index 000000000000..7cbb40c749fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-outlives.rs @@ -0,0 +1,29 @@ +// 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); // { dg-error ".E0505." "" { target *-*-* } } + return f(y); + } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-overridden-binding-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-overridden-binding-2.rs new file mode 100644 index 000000000000..c86475cdf259 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-overridden-binding-2.rs @@ -0,0 +1,9 @@ +#![feature(trait_alias)] + +trait I32Iterator = Iterator; + +fn main() { + let _: &dyn I32Iterator = &vec![42].into_iter(); +// { dg-error ".E0271." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-overridden-binding.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-overridden-binding.rs new file mode 100644 index 000000000000..52e334bde3d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-overridden-binding.rs @@ -0,0 +1,12 @@ +#![feature(trait_alias)] + +trait Foo: Iterator {} +trait Bar: Foo {} // { dg-error ".E0284." "" { target *-*-* } } + +trait I32Iterator = Iterator; +trait U32Iterator = I32Iterator; // { dg-error ".E0284." "" { target *-*-* } } + +fn main() { + let _: &dyn I32Iterator; +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-overridden-default.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-overridden-default.rs new file mode 100644 index 000000000000..cae7604f4be2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-overridden-default.rs @@ -0,0 +1,23 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-path-1.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-path-1.rs new file mode 100644 index 000000000000..9b248e5be140 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-path-1.rs @@ -0,0 +1,14 @@ +// 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) {} // { dg-error ".E0220." "" { target *-*-* } } +pub fn f2(a: T, x: T::A) {} // { dg-error ".E0221." "" { target *-*-* } } + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-path-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-path-2.rs new file mode 100644 index 000000000000..0c65b14a8dcc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-path-2.rs @@ -0,0 +1,47 @@ +// 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); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +pub fn f1_int_uint() { + f1(2i32, 4u32); +} + +pub fn f1_uint_uint() { + f1(2u32, 4u32); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + +pub fn f1_uint_int() { + f1(2u32, 4i32); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + +pub fn f2_int() { + let _: i32 = f2(2i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.rs new file mode 100644 index 000000000000..ad0d8992155a --- /dev/null +++ b/gcc/testsuite/rust/rustc/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 }; +// { dg-error ".E0623." "" { target *-*-* } .-1 } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs new file mode 100644 index 000000000000..c126256e0793 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs @@ -0,0 +1,38 @@ +#![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) +// { dg-error ".E0212." "" { target *-*-* } .-1 } +{ + // 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs new file mode 100644 index 000000000000..2bc9cc46879d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs @@ -0,0 +1,40 @@ +// 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 +// { dg-error ".E0212." "" { target *-*-* } .-1 } +} + +enum SomeEnum<'b, I: for<'a> Foo<&'a isize>> { + TupleVariant(I::A), +// { dg-error ".E0212." "" { target *-*-* } .-1 } + StructVariant { field: I::A }, +// { dg-error ".E0212." "" { target *-*-* } .-1 } + 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, +// { dg-error ".E0212." "" { target *-*-* } .-1 } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs new file mode 100644 index 000000000000..db25e6ced8db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs @@ -0,0 +1,39 @@ +#![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); +// { dg-error ".E0212." "" { target *-*-* } .-1 } +} + +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 { +// { dg-error ".E0212." "" { target *-*-* } .-1 } + Default::default() + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs new file mode 100644 index 000000000000..dba2b12ed4ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs @@ -0,0 +1,99 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-bound-ambiguity.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-bound-ambiguity.rs new file mode 100644 index 000000000000..41ceaf3c04ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-bound-ambiguity.rs @@ -0,0 +1,17 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-bound-in-supertraits.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-bound-in-supertraits.rs new file mode 100644 index 000000000000..ea22daa2b925 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-bound-in-supertraits.rs @@ -0,0 +1,24 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs new file mode 100644 index 000000000000..2866c7fc6bd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs @@ -0,0 +1,39 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-in-object-type.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-in-object-type.rs new file mode 100644 index 000000000000..dbe6633dc29f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-in-object-type.rs @@ -0,0 +1,41 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-in-supertrait.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-in-supertrait.rs new file mode 100644 index 000000000000..2ff40252cdd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-in-supertrait.rs @@ -0,0 +1,46 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-in-where-clause.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-in-where-clause.rs new file mode 100644 index 000000000000..1233deaf1381 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-in-where-clause.rs @@ -0,0 +1,32 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs new file mode 100644 index 000000000000..7ddf438ec4b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs @@ -0,0 +1,31 @@ +// 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); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-to-unrelated-trait.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-to-unrelated-trait.rs new file mode 100644 index 000000000000..cfe62d956916 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-projection-to-unrelated-trait.rs @@ -0,0 +1,36 @@ +// 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 compile-fail 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs new file mode 100644 index 000000000000..7ce2b66623f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Foo { + type Bar; + fn get_bar() -> >::Bar; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-ref-from-struct.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-ref-from-struct.rs new file mode 100644 index 000000000000..460a7f2ef467 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-ref-from-struct.rs @@ -0,0 +1,52 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-ref-in-struct-literal.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-ref-in-struct-literal.rs new file mode 100644 index 000000000000..d730f04c7bdb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-ref-in-struct-literal.rs @@ -0,0 +1,24 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-region-erasure-issue-20582.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-region-erasure-issue-20582.rs new file mode 100644 index 000000000000..518b5bfca794 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-region-erasure-issue-20582.rs @@ -0,0 +1,22 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-resolve-lifetime.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-resolve-lifetime.rs new file mode 100644 index 000000000000..0c7a7b95cc24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-resolve-lifetime.rs @@ -0,0 +1,16 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-return.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-return.rs new file mode 100644 index 000000000000..5a12aefc5567 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-return.rs @@ -0,0 +1,47 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-simple.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-simple.rs new file mode 100644 index 000000000000..c0bdde8da12b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-simple.rs @@ -0,0 +1,25 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-stream.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-stream.rs new file mode 100644 index 000000000000..f1e7939045c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-stream.rs @@ -0,0 +1,41 @@ +// run-pass +// Test references to the trait `Stream` in the bounds for associated +// types defined on `Stream`. Issue #20551. +// ignore-compare-mode-chalk + + +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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-struct-field-named.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-struct-field-named.rs new file mode 100644 index 000000000000..180d92d0dbfa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-struct-field-named.rs @@ -0,0 +1,36 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-struct-field-numbered.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-struct-field-numbered.rs new file mode 100644 index 000000000000..b42a1c1e1111 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-struct-field-numbered.rs @@ -0,0 +1,33 @@ +// run-pass +// Test that we correctly normalize the type of a struct field +// which has an associated type. + + +pub trait UnifyKey { + type Value; + + fn dummy(&self) { } +} + +pub struct Node(K, 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-subtyping-1.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-subtyping-1.rs new file mode 100644 index 000000000000..70855f17c9fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-subtyping-1.rs @@ -0,0 +1,48 @@ +#![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(); + let b: >::Type = make_any(); + let _c: >::Type = a; // { dg-error ".E0623." "" { target *-*-* } } +} + +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; // { dg-error ".E0623." "" { target *-*-* } } +} + +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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-sugar-path.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-sugar-path.rs new file mode 100644 index 000000000000..381df3138a3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-sugar-path.rs @@ -0,0 +1,42 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-unconstrained.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-unconstrained.rs new file mode 100644 index 000000000000..cf080a8de659 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-unconstrained.rs @@ -0,0 +1,17 @@ +// 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(); +// { dg-error ".E0283." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-unsized.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-unsized.rs new file mode 100644 index 000000000000..e7c551194da0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-unsized.rs @@ -0,0 +1,15 @@ +// run-rustfix +#![allow(dead_code, unused_variables)] + +trait Get { + type Value: ?Sized; + fn get(&self) -> ::Value; +} + +fn foo(t: T) { + let x = t.get(); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs new file mode 100644 index 000000000000..986b72239e23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs @@ -0,0 +1,47 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/auxiliary/associated-types-cc-lib.rs b/gcc/testsuite/rust/rustc/ui/associated-types/auxiliary/associated-types-cc-lib.rs new file mode 100644 index 000000000000..fcf503af00fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/auxiliary/associated-types-cc-lib.rs @@ -0,0 +1,17 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/bound-lifetime-constrained.rs b/gcc/testsuite/rust/rustc/ui/associated-types/bound-lifetime-constrained.rs new file mode 100644 index 000000000000..be68040e6912 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/bound-lifetime-constrained.rs @@ -0,0 +1,49 @@ +// 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) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +// 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) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(object)] +fn object1(_: Box Fn(<() as Foo<'a>>::Item) -> &'a i32>) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(object)] +fn object2(_: Box Fn() -> <() as Foo<'a>>::Item>) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(clause)] +fn clause1() where T: for<'a> Fn(<() as Foo<'a>>::Item) -> &'a i32 { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(clause)] +fn clause2() where T: for<'a> Fn() -> <() as Foo<'a>>::Item { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[rustc_error] +fn main() { } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/bound-lifetime-in-binding-only.rs b/gcc/testsuite/rust/rustc/ui/associated-types/bound-lifetime-in-binding-only.rs new file mode 100644 index 000000000000..99cb33debe46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/bound-lifetime-in-binding-only.rs @@ -0,0 +1,72 @@ +// revisions: angle paren ok elision + +#![allow(dead_code)] +#![feature(rustc_attrs)] +#![feature(unboxed_closures)] + +trait Foo { + type Item; +} + +#[cfg(angle)] +fn angle Foo>() { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(angle)] +fn angle1() where T: for<'a> Foo { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(angle)] +fn angle2() where for<'a> T: Foo { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(angle)] +fn angle3(_: &dyn for<'a> Foo) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(paren)] +fn paren Fn() -> &'a i32>() { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(paren)] +fn paren1() where T: for<'a> Fn() -> &'a i32 { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(paren)] +fn paren2() where for<'a> T: Fn() -> &'a i32 { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(paren)] +fn paren3(_: &dyn for<'a> Fn() -> &'a i32) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(elision)] +fn elision &i32>() { +// { dg-error "" "" { target *-*-* } .-1 } +} + +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() { } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/bound-lifetime-in-return-only.rs b/gcc/testsuite/rust/rustc/ui/associated-types/bound-lifetime-in-return-only.rs new file mode 100644 index 000000000000..a12b6fdfbec8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/bound-lifetime-in-return-only.rs @@ -0,0 +1,50 @@ +// 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) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(sig)] +fn sig2(_: for<'a, 'b> fn(&'b i32) -> &'a i32) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(local)] +fn local1() { + let _: for<'a> fn() -> &'a i32 = loop { }; +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(structure)] +struct Struct1 { + x: for<'a> fn() -> &'a i32 +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(elision)] +fn elision(_: fn() -> &i32) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +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() { } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/cache/chrono-scan.rs b/gcc/testsuite/rust/rustc/ui/associated-types/cache/chrono-scan.rs new file mode 100644 index 000000000000..831f091fe136 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/cache/chrono-scan.rs @@ -0,0 +1,31 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/cache/elision.rs b/gcc/testsuite/rust/rustc/ui/associated-types/cache/elision.rs new file mode 100644 index 000000000000..b6f79751be09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/cache/elision.rs @@ -0,0 +1,24 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/cache/project-fn-ret-contravariant.rs b/gcc/testsuite/rust/rustc/ui/associated-types/cache/project-fn-ret-contravariant.rs new file mode 100644 index 000000000000..6047edf295d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/cache/project-fn-ret-contravariant.rs @@ -0,0 +1,51 @@ +#![feature(unboxed_closures)] +#![feature(rustc_attrs)] + +// 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 + +#![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) // { dg-error "" "" { target *-*-* } } +} + +#[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) // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[rustc_error] +fn main() { } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/cache/project-fn-ret-invariant.rs b/gcc/testsuite/rust/rustc/ui/associated-types/cache/project-fn-ret-invariant.rs new file mode 100644 index 000000000000..929ebc2a8df1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/cache/project-fn-ret-invariant.rs @@ -0,0 +1,62 @@ +#![feature(unboxed_closures)] +#![feature(rustc_attrs)] +// 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 +#![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); + let b = bar(f, y); // { dg-error "" "" { target *-*-* } } + (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) // { dg-error "" "" { target *-*-* } } +} + +#[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); // { dg-error "" "" { target *-*-* } } + let b = bar(foo, x); + (a, b) // { dg-error "" "" { target *-*-* } } +} + +#[rustc_error] +fn main() {} +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-fail-1.rs b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-fail-1.rs new file mode 100644 index 000000000000..3be89319bb3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-fail-1.rs @@ -0,0 +1,41 @@ +#![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; +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} +// (the error is shown twice for some reason) + +impl Tr for usize { + type B = &'static Self::A; +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} + +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/gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-fail-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-fail-2.rs new file mode 100644 index 000000000000..cdc54265ef98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-fail-2.rs @@ -0,0 +1,42 @@ +#![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; +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} +// (the error is shown twice for some reason) + +impl Tr for usize { + type B = &'static Self::A; +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} + +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/gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-pass-1.rs b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-pass-1.rs new file mode 100644 index 000000000000..87b17e8ac401 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-pass-1.rs @@ -0,0 +1,57 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-pass-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-pass-2.rs new file mode 100644 index 000000000000..91a53a36d4cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-cyclic-pass-2.rs @@ -0,0 +1,57 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/defaults-in-other-trait-items-pass.rs b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-in-other-trait-items-pass.rs new file mode 100644 index 000000000000..9a629cc1ef92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-in-other-trait-items-pass.rs @@ -0,0 +1,38 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/defaults-in-other-trait-items.rs b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-in-other-trait-items.rs new file mode 100644 index 000000000000..15b89c0c22e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/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 = (); // { dg-note "" "" { target *-*-* } } + + fn f(p: Self::A) { + let () = p; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } +// { dg-note ".E0308." "" { target *-*-* } .-3 } + } +} + +// 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; // { dg-note "" "" { target *-*-* } } + + // Assoc. consts also cannot assume that default types hold + const C: Self::Ty = 0u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } +// { dg-note ".E0308." "" { target *-*-* } .-3 } +} + +// An impl can, however +impl AssocConst for () { + const C: Self::Ty = 0u8; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/defaults-mixed.rs b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-mixed.rs new file mode 100644 index 000000000000..dbd264e6628e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-mixed.rs @@ -0,0 +1,35 @@ +#![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 () {} +// { dg-error ".E0046." "" { target *-*-* } .-1 } + +impl Trait for bool { +// { dg-error ".E0046." "" { target *-*-* } .-1 } + 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/gcc/testsuite/rust/rustc/ui/associated-types/defaults-specialization.rs b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-specialization.rs new file mode 100644 index 000000000000..7d68e2616497 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-specialization.rs @@ -0,0 +1,97 @@ +//! Tests the interaction of associated type defaults and specialization. + +#![feature(associated_type_defaults, specialization)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait Tr { + type Ty = u8; + + fn make() -> Self::Ty { + 0u8 +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } +} + +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 } +// { dg-error ".E0053." "" { target *-*-* } .-1 } +} + +struct A2(T); +// ...same, but in the method body +default impl Tr for A2 { + fn make() -> Self::Ty { 0u8 } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +struct B(T); +// Explicitly defaulting the type does the same. +impl Tr for B { + default type Ty = bool; + + fn make() -> bool { true } +// { dg-error ".E0053." "" { target *-*-* } .-1 } +} + +struct B2(T); +// ...same, but in the method body +impl Tr for B2 { + default type Ty = bool; + + fn make() -> Self::Ty { true } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +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; // { dg-error ".E0308." "" { target *-*-* } } + let _: as Tr>::Ty = true; // { dg-error ".E0308." "" { target *-*-* } } + let _: as Tr>::Ty = 0u8; // { dg-error ".E0308." "" { target *-*-* } } + let _: as Tr>::Ty = true; // { dg-error ".E0308." "" { target *-*-* } } + + let _: as Tr>::Ty = true; + + let _: as Tr>::Ty = 0u8; + let _: as Tr>::Ty = 0u8; +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/defaults-suitability.rs b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-suitability.rs new file mode 100644 index 000000000000..1c12fb26927b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-suitability.rs @@ -0,0 +1,102 @@ +//! 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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +// Where-clauses defined on the trait must also be considered +trait Tr2 +where + Self::Ty: Clone, +{ + type Ty = NotClone; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +// Involved type parameters must fulfill all bounds required by defaults that mention them +trait Foo { + type Bar: Clone = Vec; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +trait Bar: Sized { + // `(): Foo` might hold for some possible impls but not all. + type Assoc: Foo = (); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +// 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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + 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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + 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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +// 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/gcc/testsuite/rust/rustc/ui/associated-types/defaults-unsound-62211-1.rs b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-unsound-62211-1.rs new file mode 100644 index 000000000000..617a1b762dd4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-unsound-62211-1.rs @@ -0,0 +1,55 @@ +//! 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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } + + // 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/gcc/testsuite/rust/rustc/ui/associated-types/defaults-unsound-62211-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-unsound-62211-2.rs new file mode 100644 index 000000000000..e046ca49c169 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-unsound-62211-2.rs @@ -0,0 +1,55 @@ +//! 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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } + + // 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/gcc/testsuite/rust/rustc/ui/associated-types/defaults-wf.rs b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-wf.rs new file mode 100644 index 000000000000..05038e169e94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/defaults-wf.rs @@ -0,0 +1,12 @@ +// Check that associated type defaults are wf checked. + +#![feature(associated_type_defaults)] + +// Default types must always be wf +trait Tr3 { + type Ty = Vec<[u8]>; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/higher-ranked-projection.rs b/gcc/testsuite/rust/rustc/ui/associated-types/higher-ranked-projection.rs new file mode 100644 index 000000000000..c76bb64c13ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/higher-ranked-projection.rs @@ -0,0 +1,28 @@ +#![feature(rustc_attrs)] + +// revisions: good bad + +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 +{} + +#[rustc_error] +fn main() { // { dg-error "" "" { target *-*-* } } + foo(()); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-1.rs b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-1.rs new file mode 100644 index 000000000000..531623b038bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-1.rs @@ -0,0 +1,19 @@ +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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { + 1i32.f("abc"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-2.rs new file mode 100644 index 000000000000..2cfda7d692eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-2.rs @@ -0,0 +1,22 @@ +trait X<'a> +where + for<'b> >::U: Clone, +{ + type U: ?Sized; + fn f(&self, x: &Self::U) { + ::clone(x); + } +} + +impl X<'_> for u32 +where + for<'b> >::U: Clone, +{ + type U = str; +} + +fn main() { + 1u32.f("abc"); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-object.rs b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-object.rs new file mode 100644 index 000000000000..1bcdd70e7fb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-object.rs @@ -0,0 +1,15 @@ +trait X<'a> +where + for<'b> >::U: Clone, +{ + type U: ?Sized; +} +fn f<'a, T: X<'a> + ?Sized>(x: &>::U) { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + <>::U>::clone(x); +} + +pub fn main() { + f::>("abc"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-1.rs b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-1.rs new file mode 100644 index 000000000000..1126844004d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-1.rs @@ -0,0 +1,21 @@ +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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { + 1u8.g("abc"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-2.rs new file mode 100644 index 000000000000..1f833ed2f882 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-2.rs @@ -0,0 +1,23 @@ +// ignore-compare-mode-chalk +trait Z<'a, T: ?Sized> +where + T: Z<'a, u16>, +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + 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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { + 1u16.h("abc"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-3.rs b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-3.rs new file mode 100644 index 000000000000..d573ad665d20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-3.rs @@ -0,0 +1,20 @@ +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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +pub fn main() { + <(i32,) as X<(i32,)>>::f("abc"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-4.rs b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-4.rs new file mode 100644 index 000000000000..486503451ce5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-4.rs @@ -0,0 +1,20 @@ +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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +pub fn main() { + <(i32,) as X>::f("abc"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-5.rs b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-5.rs new file mode 100644 index 000000000000..969fbb8686a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-5.rs @@ -0,0 +1,41 @@ +// ignore-compare-mode-chalk +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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + +impl X<'_, Box> for S { + type U = str; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + +pub fn main() { + >>::f("abc"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-6.rs b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-6.rs new file mode 100644 index 000000000000..c39f8432a8e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-bound-param-6.rs @@ -0,0 +1,21 @@ +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,) { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + type U = str; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +pub fn main() { + <(i32,) as X>::f("abc"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-projection-1.rs b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-projection-1.rs new file mode 100644 index 000000000000..0d0130624fba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/hr-associated-type-projection-1.rs @@ -0,0 +1,22 @@ +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 { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + type Item = T; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +pub fn main() { + <&'static str>::bug(&""); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/impl-trait-return-missing-constraint.rs b/gcc/testsuite/rust/rustc/ui/associated-types/impl-trait-return-missing-constraint.rs new file mode 100644 index 000000000000..2f25c4f4cac4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/impl-trait-return-missing-constraint.rs @@ -0,0 +1,33 @@ +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 { +// { dg-error ".E0271." "" { target *-*-* } .-1 } + bar() +} + +fn main() { + let _ = baz(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/impl-wf-cycle-1.rs b/gcc/testsuite/rust/rustc/ui/associated-types/impl-wf-cycle-1.rs new file mode 100644 index 000000000000..e599a8da6896 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/impl-wf-cycle-1.rs @@ -0,0 +1,30 @@ +// 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,) +where + Self::A: Baz, + Self::B: Fiz, +{ + type A = (); +// { dg-error ".E0275." "" { target *-*-* } .-1 } + type B = bool; +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} +// { dg-error ".E0275." "" { target *-*-* } .-10 } + +fn main() { + let x: <(_,) as Grault>::A = (); +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/impl-wf-cycle-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/impl-wf-cycle-2.rs new file mode 100644 index 000000000000..b08afa33a855 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/impl-wf-cycle-2.rs @@ -0,0 +1,17 @@ +// Regression test for #79714 + +trait Grault { + type A; +} + +impl Grault for (T,) +where + Self::A: Copy, +{ + type A = (); +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} +// { dg-error ".E0275." "" { target *-*-* } .-7 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/issue-26681.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-26681.rs new file mode 100644 index 000000000000..791ea1ab59da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-26681.rs @@ -0,0 +1,21 @@ +#![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; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/issue-32350.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-32350.rs new file mode 100644 index 000000000000..bc7fca64660c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-32350.rs @@ -0,0 +1,30 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/issue-36499.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-36499.rs new file mode 100644 index 000000000000..d948737d8287 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-36499.rs @@ -0,0 +1,6 @@ +// error-pattern: aborting due to previous error + +fn main() { + 2 + +2; +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/issue-41868.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-41868.rs new file mode 100644 index 000000000000..6c34560daaf2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-41868.rs @@ -0,0 +1,24 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/issue-43924.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-43924.rs new file mode 100644 index 000000000000..55480aab44e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-43924.rs @@ -0,0 +1,17 @@ +#![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; // { dg-error ".E0277." "" { target *-*-* } } +} + +impl Foo for () {} +impl Foo for () {} + +fn main() { + assert_eq!(<() as Foo>::Out::default().to_string(), "false"); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/issue-44153.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-44153.rs new file mode 100644 index 000000000000..42abe87e9ff9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-44153.rs @@ -0,0 +1,20 @@ +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(); // { dg-error ".E0271." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/issue-47385.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-47385.rs new file mode 100644 index 000000000000..1937a001314a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-47385.rs @@ -0,0 +1,17 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/issue-48010.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-48010.rs new file mode 100644 index 000000000000..33d6b9061b1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-48010.rs @@ -0,0 +1,24 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/issue-54108.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-54108.rs new file mode 100644 index 000000000000..ef6496ae36ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-54108.rs @@ -0,0 +1,42 @@ +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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + 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/gcc/testsuite/rust/rustc/ui/associated-types/issue-54182-1.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-54182-1.rs new file mode 100644 index 000000000000..9017ec77f91f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-54182-1.rs @@ -0,0 +1,93 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/issue-54182-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-54182-2.rs new file mode 100644 index 000000000000..27627eed60f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-54182-2.rs @@ -0,0 +1,20 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/issue-62200.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-62200.rs new file mode 100644 index 000000000000..545cfee5aa1e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-62200.rs @@ -0,0 +1,16 @@ +struct S {} + +trait T<'a> { + type A; +} + +impl T<'_> for S { + type A = u32; +} + +fn foo(x: impl Fn(>::A) -> >::A) {} +// { dg-error ".E0582." "" { target *-*-* } .-1 } +// { dg-note ".E0582." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/issue-63593.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-63593.rs new file mode 100644 index 000000000000..d981fc39265d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-63593.rs @@ -0,0 +1,14 @@ +#![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; // { dg-error ".E0277." "" { target *-*-* } } + fn something>(i: I); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/issue-64848.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-64848.rs new file mode 100644 index 000000000000..9e23e232daf9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-64848.rs @@ -0,0 +1,30 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/issue-64855-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-64855-2.rs new file mode 100644 index 000000000000..d2e75ea4a283 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-64855-2.rs @@ -0,0 +1,6 @@ +// check-pass + +pub struct Bar<'a>(&'a Self) where Self: ; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/issue-64855.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-64855.rs new file mode 100644 index 000000000000..5b1efda927dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-64855.rs @@ -0,0 +1,9 @@ +pub trait Foo { + type Type; +} + +pub struct Bar(::Type) where Self: ; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/issue-65774-1.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-65774-1.rs new file mode 100644 index 000000000000..62d2c332454b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-65774-1.rs @@ -0,0 +1,59 @@ +#![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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +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); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + 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/gcc/testsuite/rust/rustc/ui/associated-types/issue-65774-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-65774-2.rs new file mode 100644 index 000000000000..af95d531945c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-65774-2.rs @@ -0,0 +1,59 @@ +#![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; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +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) +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // 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/gcc/testsuite/rust/rustc/ui/associated-types/issue-65934.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-65934.rs new file mode 100644 index 000000000000..b3fe472a535a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-65934.rs @@ -0,0 +1,18 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/issue-72806.rs b/gcc/testsuite/rust/rustc/ui/associated-types/issue-72806.rs new file mode 100644 index 000000000000..92c06fd17a0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/issue-72806.rs @@ -0,0 +1,22 @@ +trait Bar { + type Ok; + type Sibling: Bar2; +} +trait Bar2 { + type Ok; +} + +struct Foo; +struct Foo2; + +impl Bar for Foo { + type Ok = (); + type Sibling = Foo2; +// { dg-error ".E0271." "" { target *-*-* } .-1 } +} +impl Bar2 for Foo2 { + type Ok = u32; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/missing-associated-types.rs b/gcc/testsuite/rust/rustc/ui/associated-types/missing-associated-types.rs new file mode 100644 index 000000000000..7e2b705b5d70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/missing-associated-types.rs @@ -0,0 +1,28 @@ +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; +// { dg-error ".E0225." "" { target *-*-* } .-1 } +// { dg-error ".E0191." "" { target *-*-* } .-2 } +type Bar = dyn Add + Sub + X + Z; +// { dg-error ".E0225." "" { target *-*-* } .-1 } +// { dg-error ".E0191." "" { target *-*-* } .-2 } +type Baz = dyn Add + Sub + Y; +// { dg-error ".E0225." "" { target *-*-* } .-1 } +// { dg-error ".E0191." "" { target *-*-* } .-2 } +type Bat = dyn Add + Sub + Fine; +// { dg-error ".E0191." "" { target *-*-* } .-1 } +// { dg-error ".E0191." "" { target *-*-* } .-2 } +type Bal = dyn X; +// { dg-error ".E0191." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/normalization-probe-cycle.rs b/gcc/testsuite/rust/rustc/ui/associated-types/normalization-probe-cycle.rs new file mode 100644 index 000000000000..70f651f30f4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/normalization-probe-cycle.rs @@ -0,0 +1,26 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/normalize-cycle-in-eval-no-region.rs b/gcc/testsuite/rust/rustc/ui/associated-types/normalize-cycle-in-eval-no-region.rs new file mode 100644 index 000000000000..69a4e03a85da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/normalize-cycle-in-eval-no-region.rs @@ -0,0 +1,21 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/normalize-cycle-in-eval.rs b/gcc/testsuite/rust/rustc/ui/associated-types/normalize-cycle-in-eval.rs new file mode 100644 index 000000000000..718d3d1d2a50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/normalize-cycle-in-eval.rs @@ -0,0 +1,44 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/object-normalization.rs b/gcc/testsuite/rust/rustc/ui/associated-types/object-normalization.rs new file mode 100644 index 000000000000..14410030159c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/object-normalization.rs @@ -0,0 +1,27 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/param-env-normalize-cycle.rs b/gcc/testsuite/rust/rustc/ui/associated-types/param-env-normalize-cycle.rs new file mode 100644 index 000000000000..45a9bd85f7ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/param-env-normalize-cycle.rs @@ -0,0 +1,40 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/point-at-type-on-obligation-failure-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/point-at-type-on-obligation-failure-2.rs new file mode 100644 index 000000000000..5f8429c6a593 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/point-at-type-on-obligation-failure-2.rs @@ -0,0 +1,34 @@ +trait Bar {} + +trait Foo { + type Assoc: Bar; +} + +impl Foo for () { + type Assoc = bool; // { dg-error ".E0277." "" { target *-*-* } } +} + +trait Baz +where + Self::Assoc: Bar, +{ + type Assoc; +} + +impl Baz for () { + type Assoc = bool; // { dg-error ".E0277." "" { target *-*-* } } +} + +trait Bat +where + ::Assoc: Bar, +{ + type Assoc; +} + +impl Bat for () { + type Assoc = bool; // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/point-at-type-on-obligation-failure.rs b/gcc/testsuite/rust/rustc/ui/associated-types/point-at-type-on-obligation-failure.rs new file mode 100644 index 000000000000..ef465ca23e2e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/point-at-type-on-obligation-failure.rs @@ -0,0 +1,22 @@ +trait Bar { + type Ok; + type Sibling: Bar2; +} +trait Bar2 { + type Ok; +} + +struct Foo; +struct Foo2; + +impl Bar for Foo { + type Ok = (); + type Sibling = Foo2; +// { dg-error ".E0271." "" { target *-*-* } .-1 } +} +impl Bar2 for Foo2 { + type Ok = u32; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/trait-with-supertraits-needing-sized-self.rs b/gcc/testsuite/rust/rustc/ui/associated-types/trait-with-supertraits-needing-sized-self.rs new file mode 100644 index 000000000000..f8114a1807c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/trait-with-supertraits-needing-sized-self.rs @@ -0,0 +1,12 @@ +use std::ops::{Add, Sub, Mul, Div}; + +trait ArithmeticOps: Add + Sub + Mul + Div {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +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/gcc/testsuite/rust/rustc/ui/associated-types/wf-cycle-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/wf-cycle-2.rs new file mode 100644 index 000000000000..7869d29f5be1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/wf-cycle-2.rs @@ -0,0 +1,19 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/wf-cycle.rs b/gcc/testsuite/rust/rustc/ui/associated-types/wf-cycle.rs new file mode 100644 index 000000000000..5a2ee0f0c038 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/wf-cycle.rs @@ -0,0 +1,14 @@ +// check-pass + +trait A { + type U: Copy; +} + +trait B where + ::U: Copy, +{ + type V: A; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/ast-json/ast-json-ice.rs b/gcc/testsuite/rust/rustc/ui/ast-json/ast-json-ice.rs new file mode 100644 index 000000000000..701b46ef9022 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ast-json/ast-json-ice.rs @@ -0,0 +1,65 @@ +// Test that AST json serialization doesn't ICE (#63728). + +// revisions: expand noexpand + +//[expand] compile-flags: -Zast-json +//[noexpand] compile-flags: -Zast-json-noexpand + +// check-pass +// dont-check-compiler-stdout - don't check for any AST change. + +#![feature(llvm_asm)] + +enum V { + A(i32), + B { f: [i64; 3 + 4] } +} + +trait X { + type Output; + fn read(&self) -> Self::Output; + fn write(&mut self, _: Self::Output); +} + +macro_rules! call_println { + ($y:ident) => { println!("{}", $y) } +} + +fn main() { + #[cfg(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64"))] + unsafe { llvm_asm!(""::::); } + + let x: (i32) = 35; + let y = x as i64<> + 5; + + call_println!(y); + + struct A; +} + +// Regressions tests for issues #78398 and #78510 (captured tokens in associated and foreign items) + +struct S; + +macro_rules! mac_extern { + ($i:item) => { + extern "C" { $i } + } +} +macro_rules! mac_assoc { + ($i:item) => { + impl S { $i } + trait Bar { $i } + } +} + +mac_extern! { + fn foo(); +} +mac_assoc! { + fn foo() {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/ast-json/ast-json-noexpand-output.rs b/gcc/testsuite/rust/rustc/ui/ast-json/ast-json-noexpand-output.rs new file mode 100644 index 000000000000..b4ee13aadfda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ast-json/ast-json-noexpand-output.rs @@ -0,0 +1,11 @@ +// Check that AST json printing works. +#![crate_type = "lib"] + +// check-pass +// compile-flags: -Zast-json-noexpand +// normalize-stdout-test ":\d+" -> ":0" + +// Only include a single item to reduce how often the test output needs +// updating. +extern crate core; + diff --git a/gcc/testsuite/rust/rustc/ui/ast-json/ast-json-output.rs b/gcc/testsuite/rust/rustc/ui/ast-json/ast-json-output.rs new file mode 100644 index 000000000000..a59e3afbde6b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ast-json/ast-json-output.rs @@ -0,0 +1,11 @@ +// Check that AST json printing works. +#![crate_type = "lib"] + +// check-pass +// compile-flags: -Zast-json +// normalize-stdout-test ":\d+" -> ":0" + +// Only include a single item to reduce how often the test output needs +// updating. +extern crate core; + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/argument-patterns.rs b/gcc/testsuite/rust/rustc/ui/async-await/argument-patterns.rs new file mode 100644 index 000000000000..0b27c6ea7556 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/argument-patterns.rs @@ -0,0 +1,29 @@ +// edition:2018 +// check-pass + +#![deny(unused_mut)] + +type A = Vec; + +async fn a(n: u32, mut vec: A) { + vec.push(n); +} + +async fn b(n: u32, ref mut vec: A) { + vec.push(n); +} + +async fn c(ref vec: A) { + vec.contains(&0); +} + +async fn d((a, mut b): (A, A)) { + b.push(1); +} + +async fn f((ref mut a, ref b): (A, A)) {} + +async fn g(((ref a, ref mut b), (ref mut c, ref d)): ((A, A), (A, A))) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-assoc-fn-anon-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-assoc-fn-anon-lifetimes.rs new file mode 100644 index 000000000000..8c194c065d97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-assoc-fn-anon-lifetimes.rs @@ -0,0 +1,24 @@ +// check-pass +// Check that the anonymous lifetimes used here aren't considered to shadow one +// another. Note that `async fn` is different to `fn` here because the lifetimes +// are numbered by HIR lowering, rather than lifetime resolution. + +// edition:2018 + +struct A<'a, 'b>(&'a &'b i32); +struct B<'a>(&'a i32); + +impl A<'_, '_> { + async fn assoc(x: &u32, y: B<'_>) { + async fn nested(x: &u32, y: A<'_, '_>) {} + } + + async fn assoc2(x: &u32, y: A<'_, '_>) { + impl A<'_, '_> { + async fn nested_assoc(x: &u32, y: B<'_>) {} + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-await.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-await.rs new file mode 100644 index 000000000000..02d3b57b9197 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-await.rs @@ -0,0 +1,219 @@ +// run-pass + +// revisions: default nomiropt +//[nomiropt]compile-flags: -Z mir-opt-level=0 + +#![allow(unused)] + +// edition:2018 +// aux-build:arc_wake.rs + +extern crate arc_wake; + +use std::pin::Pin; +use std::future::Future; +use std::sync::{ + Arc, + atomic::{self, AtomicUsize}, +}; +use std::task::{Context, Poll}; +use arc_wake::ArcWake; + +struct Counter { + wakes: AtomicUsize, +} + +impl ArcWake for Counter { + fn wake(self: Arc) { + Self::wake_by_ref(&self) + } + fn wake_by_ref(arc_self: &Arc) { + arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst); + } +} + +struct WakeOnceThenComplete(bool); + +fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) } + +impl Future for WakeOnceThenComplete { + type Output = (); + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { + if self.0 { + Poll::Ready(()) + } else { + cx.waker().wake_by_ref(); + self.0 = true; + Poll::Pending + } + } +} + +fn async_block(x: u8) -> impl Future { + async move { + wake_and_yield_once().await; + x + } +} + +fn async_block_with_borrow_named_lifetime<'a>(x: &'a u8) -> impl Future + 'a { + async move { + wake_and_yield_once().await; + *x + } +} + +fn async_nonmove_block(x: u8) -> impl Future { + async move { + let future = async { + wake_and_yield_once().await; + x + }; + future.await + } +} + +// see async-closure.rs for async_closure + async_closure_in_unsafe_block + +async fn async_fn(x: u8) -> u8 { + wake_and_yield_once().await; + x +} + +async fn generic_async_fn(x: T) -> T { + wake_and_yield_once().await; + x +} + +async fn async_fn_with_borrow(x: &u8) -> u8 { + wake_and_yield_once().await; + *x +} + +async fn async_fn_with_borrow_named_lifetime<'a>(x: &'a u8) -> u8 { + wake_and_yield_once().await; + *x +} + +fn async_fn_with_impl_future_named_lifetime<'a>(x: &'a u8) -> impl Future + 'a { + async move { + wake_and_yield_once().await; + *x + } +} + +async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 { + wake_and_yield_once().await; + *x +} + +async fn async_fn_multiple_args_named_lifetime<'a>(x: &'a u8, _y: &'a u8) -> u8 { + wake_and_yield_once().await; + *x +} + +fn async_fn_with_internal_borrow(y: u8) -> impl Future { + async move { + async_fn_with_borrow_named_lifetime(&y).await + } +} + +async unsafe fn unsafe_async_fn(x: u8) -> u8 { + wake_and_yield_once().await; + x +} + +unsafe fn unsafe_fn(x: u8) -> u8 { + x +} + +fn async_block_in_unsafe_block(x: u8) -> impl Future { + unsafe { + async move { + unsafe_fn(unsafe_async_fn(x).await) + } + } +} + +struct Foo; + +trait Bar { + fn foo() {} +} + +impl Foo { + async fn async_assoc_item(x: u8) -> u8 { + unsafe { + unsafe_async_fn(x).await + } + } + + async unsafe fn async_unsafe_assoc_item(x: u8) -> u8 { + unsafe_async_fn(x).await + } +} + +fn test_future_yields_once_then_returns(f: F) +where + F: FnOnce(u8) -> Fut, + Fut: Future, +{ + let mut fut = Box::pin(f(9)); + let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) }); + let waker = ArcWake::into_waker(counter.clone()); + let mut cx = Context::from_waker(&waker); + assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst)); + assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx)); + assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst)); + assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx)); +} + +fn main() { + macro_rules! test { + ($($fn_name:expr,)*) => { $( + test_future_yields_once_then_returns($fn_name); + )* } + } + + macro_rules! test_with_borrow { + ($($fn_name:expr,)*) => { $( + test_future_yields_once_then_returns(|x| { + async move { + $fn_name(&x).await + } + }); + )* } + } + + test! { + async_block, + async_nonmove_block, + async_fn, + generic_async_fn, + async_fn_with_internal_borrow, + async_block_in_unsafe_block, + Foo::async_assoc_item, + |x| { + async move { + unsafe { unsafe_async_fn(x).await } + } + }, + |x| { + async move { + unsafe { Foo::async_unsafe_assoc_item(x).await } + } + }, + } + test_with_borrow! { + async_block_with_borrow_named_lifetime, + async_fn_with_borrow, + async_fn_with_borrow_named_lifetime, + async_fn_with_impl_future_named_lifetime, + |x| { + async move { + async_fn_multiple_args_named_lifetime(x, x).await + } + }, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-block-control-flow-static-semantics.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-block-control-flow-static-semantics.rs new file mode 100644 index 000000000000..d9753562d6a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-block-control-flow-static-semantics.rs @@ -0,0 +1,64 @@ +// Test that `async { .. }` blocks: +// 1. do not allow `break` expressions. +// 2. get targeted by `return` and not the parent function. +// 3. get targeted by `?` and not the parent function. +// +// edition:2018 + +fn main() {} + +use core::future::Future; + +fn return_targets_async_block_not_fn() -> u8 { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let block = async { + return 0u8; + }; + let _: &dyn Future = █ +// { dg-error ".E0271." "" { target *-*-* } .-1 } +} + +async fn return_targets_async_block_not_async_fn() -> u8 { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let block = async { + return 0u8; + }; + let _: &dyn Future = █ +// { dg-error ".E0271." "" { target *-*-* } .-1 } +} + +fn no_break_in_async_block() { + async { + break 0u8; // { dg-error ".E0267." "" { target *-*-* } } + }; +} + +fn no_break_in_async_block_even_with_outer_loop() { + loop { + async { + break 0u8; // { dg-error ".E0267." "" { target *-*-* } } + }; + } +} + +struct MyErr; +fn err() -> Result { Err(MyErr) } + +fn rethrow_targets_async_block_not_fn() -> Result { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let block = async { + err()?; + Ok(()) + }; + let _: &dyn Future> = █ +} + +fn rethrow_targets_async_block_not_async_fn() -> Result { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let block = async { + err()?; + Ok(()) + }; + let _: &dyn Future> = █ +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-borrowck-escaping-block-error.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-borrowck-escaping-block-error.rs new file mode 100644 index 000000000000..bb625c8ffabf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-borrowck-escaping-block-error.rs @@ -0,0 +1,19 @@ +// edition:2018 +// run-rustfix + +fn test_boxed() -> Box> { + let x = 0u32; + Box::new(async { x } ) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +} + +fn test_ref(x: &u32) -> impl std::future::Future + '_ { + async { *x } +// { dg-error ".E0373." "" { target *-*-* } .-1 } +} + +fn main() { + let _ = test_boxed(); + let _ = test_ref(&0u32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-borrowck-escaping-closure-error.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-borrowck-escaping-closure-error.rs new file mode 100644 index 000000000000..3c22cc4547e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-borrowck-escaping-closure-error.rs @@ -0,0 +1,11 @@ +// edition:2018 +#![feature(async_closure)] +fn foo() -> Box> { + let x = 0u32; + Box::new((async || x)()) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-closure-matches-expr.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-closure-matches-expr.rs new file mode 100644 index 000000000000..92914716fa1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-closure-matches-expr.rs @@ -0,0 +1,13 @@ +// build-pass +// edition:2018 + +#![feature(async_closure)] + +macro_rules! match_expr { + ($x:expr) => {} +} + +fn main() { + match_expr!(async || {}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-closure.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-closure.rs new file mode 100644 index 000000000000..c7624bebfdf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-closure.rs @@ -0,0 +1,101 @@ +// run-pass + +// revisions: default nomiropt +//[nomiropt]compile-flags: -Z mir-opt-level=0 + +// edition:2018 +// aux-build:arc_wake.rs + +#![feature(async_closure)] + +extern crate arc_wake; + +use std::pin::Pin; +use std::future::Future; +use std::sync::{ + Arc, + atomic::{self, AtomicUsize}, +}; +use std::task::{Context, Poll}; +use arc_wake::ArcWake; + +struct Counter { + wakes: AtomicUsize, +} + +impl ArcWake for Counter { + fn wake(self: Arc) { + Self::wake_by_ref(&self) + } + fn wake_by_ref(arc_self: &Arc) { + arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst); + } +} + +struct WakeOnceThenComplete(bool); + +fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) } + +impl Future for WakeOnceThenComplete { + type Output = (); + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { + if self.0 { + Poll::Ready(()) + } else { + cx.waker().wake_by_ref(); + self.0 = true; + Poll::Pending + } + } +} + +fn async_closure(x: u8) -> impl Future { + (async move |x: u8| -> u8 { + wake_and_yield_once().await; + x + })(x) +} + +fn async_closure_in_unsafe_block(x: u8) -> impl Future { + (unsafe { + async move |x: u8| unsafe_fn(unsafe_async_fn(x).await) + })(x) +} + +async unsafe fn unsafe_async_fn(x: u8) -> u8 { + wake_and_yield_once().await; + x +} + +unsafe fn unsafe_fn(x: u8) -> u8 { + x +} + +fn test_future_yields_once_then_returns(f: F) +where + F: FnOnce(u8) -> Fut, + Fut: Future, +{ + let mut fut = Box::pin(f(9)); + let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) }); + let waker = ArcWake::into_waker(counter.clone()); + let mut cx = Context::from_waker(&waker); + assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst)); + assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx)); + assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst)); + assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx)); +} + +fn main() { + macro_rules! test { + ($($fn_name:expr,)*) => { $( + test_future_yields_once_then_returns($fn_name); + )* } + } + + test! { + async_closure, + async_closure_in_unsafe_block, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-error-span.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-error-span.rs new file mode 100644 index 000000000000..57d79c9b5b4d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-error-span.rs @@ -0,0 +1,18 @@ +// edition:2018 + +// Regression test for issue #62382. + +use std::future::Future; + +fn get_future() -> impl Future { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + panic!() +} + +async fn foo() { + let a; // { dg-error ".E0698." "" { target *-*-* } } + get_future().await; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs new file mode 100644 index 000000000000..344f876c9317 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs @@ -0,0 +1,16 @@ +// Check that `async fn` inside of an impl with `'_` +// in the header compiles correctly. +// +// Regression test for #63500. +// +// check-pass +// edition:2018 + +struct Foo<'a>(&'a u8); + +impl Foo<'_> { + async fn bar() {} +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-fn-nonsend.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-nonsend.rs new file mode 100644 index 000000000000..1e06ac0a3576 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-nonsend.rs @@ -0,0 +1,56 @@ +// edition:2018 +// compile-flags: --crate-type lib + +use std::{cell::RefCell, fmt::Debug, rc::Rc}; + +fn non_sync() -> impl Debug { + RefCell::new(()) +} + +fn non_send() -> impl Debug { + Rc::new(()) +} + +fn take_ref(_: &T) {} + +async fn fut() {} + +async fn fut_arg(_: T) {} + +async fn local_dropped_before_await() { + // FIXME: it'd be nice for this to be allowed in a `Send` `async fn` + let x = non_send(); + drop(x); + fut().await; +} + +async fn non_send_temporary_in_match() { + // We could theoretically make this work as well (produce a `Send` future) + // for scrutinees / temporaries that can or will + // be dropped prior to the match body + // (e.g. `Copy` types). + match Some(non_send()) { + Some(_) => fut().await, + None => {} + } +} + +async fn non_sync_with_method_call() { + // FIXME: it'd be nice for this to work. + let f: &mut std::fmt::Formatter = panic!(); + if non_sync().fmt(f).unwrap() == () { + fut().await; + } +} + +fn assert_send(_: impl Send) {} + +pub fn pass_assert() { + assert_send(local_dropped_before_await()); +// { dg-error "" "" { target *-*-* } .-1 } + assert_send(non_send_temporary_in_match()); +// { dg-error "" "" { target *-*-* } .-1 } + assert_send(non_sync_with_method_call()); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-fn-path-elision.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-path-elision.rs new file mode 100644 index 000000000000..0acb89deb2eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-path-elision.rs @@ -0,0 +1,14 @@ +// edition:2018 + +struct HasLifetime<'a>(&'a bool); + +async fn error(lt: HasLifetime) { // { dg-error ".E0726." "" { target *-*-* } } + if *lt.0 {} +} + +fn no_error(lt: HasLifetime) { + if *lt.0 {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-fn-send-uses-nonsend.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-send-uses-nonsend.rs new file mode 100644 index 000000000000..8a6ca01914d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-send-uses-nonsend.rs @@ -0,0 +1,58 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 +// compile-flags: --crate-type lib + +use std::{ + cell::RefCell, + fmt::Debug, + rc::Rc, +}; + +fn non_sync() -> impl Debug { RefCell::new(()) } + +fn non_send() -> impl Debug { Rc::new(()) } + +fn take_ref(_: &T) {} + +async fn fut() {} + +async fn fut_arg(_: T) {} + +async fn still_send() { + fut().await; + println!("{:?} {:?}", non_send(), non_sync()); + fut().await; + drop(non_send()); + drop(non_sync()); + fut().await; + fut_arg(non_sync()).await; + + // Note: all temporaries in `if let` and `match` scrutinee + // are dropped at the *end* of the blocks, so using `non_send()` + // in either of those positions with an await in the middle will + // cause a `!Send` future. It might be nice in the future to allow + // this for `Copy` types, since they can be "dropped" early without + // affecting the end user. + if let Some(_) = Some(non_sync()) { + fut().await; + } + match Some(non_sync()) { + Some(_) => fut().await, + None => fut().await, + } + + let _ = non_send(); + fut().await; + + { + let _x = non_send(); + } + fut().await; +} + +fn assert_send(_: impl Send) {} + +pub fn pass_assert() { + assert_send(still_send()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-fn-size-moved-locals.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-size-moved-locals.rs new file mode 100644 index 000000000000..71ba6af157e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-size-moved-locals.rs @@ -0,0 +1,119 @@ +// Test that we don't duplicate storage for futures moved around in .await, and +// for futures moved into other futures. +// +// The exact sizes can change by a few bytes (we'd like to know when they do). +// What we don't want to see is the wrong multiple of 1024 (the size of BigFut) +// being reflected in the size. +// +// See issue #59123 for a full explanation. + +// ignore-emscripten (sizes don't match) +// run-pass + +// edition:2018 + +use std::future::Future; +use std::pin::Pin; +use std::task::{Context, Poll}; + +const BIG_FUT_SIZE: usize = 1024; +struct BigFut([u8; BIG_FUT_SIZE]); + +impl BigFut { + fn new() -> Self { + BigFut([0; BIG_FUT_SIZE]) + } +} + +impl Drop for BigFut { + fn drop(&mut self) {} +} + +impl Future for BigFut { + type Output = (); + + fn poll(self: Pin<&mut Self>, _ctx: &mut Context<'_>) -> Poll { + Poll::Ready(()) + } +} + +#[allow(dead_code)] +struct Joiner { + a: Option, + b: Option, + c: Option, +} + +impl Future for Joiner { + type Output = (); + + fn poll(self: Pin<&mut Self>, _ctx: &mut Context<'_>) -> Poll { + Poll::Ready(()) + } +} + +fn noop() {} + +async fn single() { + let x = BigFut::new(); + x.await; +} + +async fn single_with_noop() { + let x = BigFut::new(); + noop(); + x.await; +} + +async fn joined() { + let a = BigFut::new(); + let b = BigFut::new(); + let c = BigFut::new(); + + let joiner = Joiner { + a: Some(a), + b: Some(b), + c: Some(c), + }; + joiner.await +} + +async fn joined_with_noop() { + let a = BigFut::new(); + let b = BigFut::new(); + let c = BigFut::new(); + + let joiner = Joiner { + a: Some(a), + b: Some(b), + c: Some(c), + }; + noop(); + joiner.await +} + +async fn mixed_sizes() { + let a = BigFut::new(); + let b = BigFut::new(); + let c = BigFut::new(); + let d = BigFut::new(); + let e = BigFut::new(); + let joiner = Joiner { + a: Some(a), + b: Some(b), + c: Some(c), + }; + + d.await; + e.await; + joiner.await; +} + +fn main() { + assert_eq!(1025, std::mem::size_of_val(&single())); + assert_eq!(1026, std::mem::size_of_val(&single_with_noop())); + assert_eq!(3078, std::mem::size_of_val(&joined())); + assert_eq!(3079, std::mem::size_of_val(&joined_with_noop())); + assert_eq!(7181, std::mem::size_of_val(&mixed_sizes())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-fn-size-uninit-locals.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-size-uninit-locals.rs new file mode 100644 index 000000000000..4f7f54ece029 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-size-uninit-locals.rs @@ -0,0 +1,104 @@ +// Test that we don't store uninitialized locals in futures from `async fn`. +// +// The exact sizes can change by a few bytes (we'd like to know when they do). +// What we don't want to see is the wrong multiple of 1024 (the size of `Big`) +// being reflected in the size. + +// ignore-emscripten (sizes don't match) +// run-pass + +// edition:2018 + +#![allow(unused_variables, unused_assignments)] + +use std::future::Future; +use std::pin::Pin; +use std::task::{Context, Poll}; + +const BIG_FUT_SIZE: usize = 1024; +struct Big([u8; BIG_FUT_SIZE]); + +impl Big { + fn new() -> Self { + Big([0; BIG_FUT_SIZE]) + } +} + +impl Drop for Big { + fn drop(&mut self) {} +} + +#[allow(dead_code)] +struct Joiner { + a: Option, + b: Option, + c: Option, +} + +impl Future for Joiner { + type Output = (); + + fn poll(self: Pin<&mut Self>, _ctx: &mut Context<'_>) -> Poll { + Poll::Ready(()) + } +} + +fn noop() {} +async fn fut() {} + +async fn single() { + let x; + fut().await; + x = Big::new(); +} + +async fn single_with_noop() { + let x; + fut().await; + noop(); + x = Big::new(); + noop(); +} + +async fn joined() { + let joiner; + let a = Big::new(); + let b = Big::new(); + let c = Big::new(); + + fut().await; + noop(); + joiner = Joiner { a: Some(a), b: Some(b), c: Some(c) }; + noop(); +} + +async fn joined_with_noop() { + let joiner; + let a = Big::new(); + let b = Big::new(); + let c = Big::new(); + + fut().await; + noop(); + joiner = Joiner { a: Some(a), b: Some(b), c: Some(c) }; + noop(); +} + +async fn join_retval() -> Joiner { + let a = Big::new(); + let b = Big::new(); + let c = Big::new(); + + fut().await; + noop(); + Joiner { a: Some(a), b: Some(b), c: Some(c) } +} + +fn main() { + assert_eq!(2, std::mem::size_of_val(&single())); + assert_eq!(3, std::mem::size_of_val(&single_with_noop())); + assert_eq!(3078, std::mem::size_of_val(&joined())); + assert_eq!(3078, std::mem::size_of_val(&joined_with_noop())); + assert_eq!(3074, std::mem::size_of_val(&join_retval())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-fn-size.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-size.rs new file mode 100644 index 000000000000..757bcae0fe50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-fn-size.rs @@ -0,0 +1,106 @@ +// run-pass +// aux-build:arc_wake.rs +// edition:2018 + +extern crate arc_wake; + +use std::pin::Pin; +use std::future::Future; +use std::sync::{ + Arc, + atomic::{self, AtomicUsize}, +}; +use std::task::{Context, Poll}; +use arc_wake::ArcWake; + +struct Counter { + wakes: AtomicUsize, +} + +impl ArcWake for Counter { + fn wake(self: Arc) { + Self::wake_by_ref(&self) + } + fn wake_by_ref(arc_self: &Arc) { + arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst); + } +} + +struct WakeOnceThenComplete(bool, u8); + +impl Future for WakeOnceThenComplete { + type Output = u8; + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + if self.0 { + Poll::Ready(self.1) + } else { + cx.waker().wake_by_ref(); + self.0 = true; + Poll::Pending + } + } +} + +fn wait(fut: impl Future) -> u8 { + let mut fut = Box::pin(fut); + let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) }); + let waker = ArcWake::into_waker(counter.clone()); + let mut cx = Context::from_waker(&waker); + loop { + match fut.as_mut().poll(&mut cx) { + Poll::Ready(out) => return out, + Poll::Pending => (), + } + } +} + +fn base() -> WakeOnceThenComplete { WakeOnceThenComplete(false, 1) } + +async fn await1_level1() -> u8 { + base().await +} + +async fn await2_level1() -> u8 { + base().await + base().await +} + +async fn await3_level1() -> u8 { + base().await + base().await + base().await +} + +async fn await3_level2() -> u8 { + await3_level1().await + await3_level1().await + await3_level1().await +} + +async fn await3_level3() -> u8 { + await3_level2().await + await3_level2().await + await3_level2().await +} + +async fn await3_level4() -> u8 { + await3_level3().await + await3_level3().await + await3_level3().await +} + +async fn await3_level5() -> u8 { + await3_level4().await + await3_level4().await + await3_level4().await +} + +fn main() { + assert_eq!(2, std::mem::size_of_val(&base())); + assert_eq!(3, std::mem::size_of_val(&await1_level1())); + assert_eq!(4, std::mem::size_of_val(&await2_level1())); + assert_eq!(5, std::mem::size_of_val(&await3_level1())); + assert_eq!(8, std::mem::size_of_val(&await3_level2())); + assert_eq!(11, std::mem::size_of_val(&await3_level3())); + assert_eq!(14, std::mem::size_of_val(&await3_level4())); + assert_eq!(17, std::mem::size_of_val(&await3_level5())); + + assert_eq!(1, wait(base())); + assert_eq!(1, wait(await1_level1())); + assert_eq!(2, wait(await2_level1())); + assert_eq!(3, wait(await3_level1())); + assert_eq!(9, wait(await3_level2())); + assert_eq!(27, wait(await3_level3())); + assert_eq!(81, wait(await3_level4())); + assert_eq!(243, wait(await3_level5())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-matches-expr.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-matches-expr.rs new file mode 100644 index 000000000000..d41dfec7c951 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-matches-expr.rs @@ -0,0 +1,11 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 + +macro_rules! match_expr { + ($x:expr) => {} +} + +fn main() { + match_expr!(async {}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-trait-fn.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-trait-fn.rs new file mode 100644 index 000000000000..b39e6ba344d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-trait-fn.rs @@ -0,0 +1,8 @@ +// edition:2018 +trait T { + async fn foo() {} // { dg-error ".E0706." "" { target *-*-* } } + async fn bar(&self) {} // { dg-error ".E0706." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-unsafe-fn-call-in-safe.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-unsafe-fn-call-in-safe.rs new file mode 100644 index 000000000000..7fb0327cc6a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-unsafe-fn-call-in-safe.rs @@ -0,0 +1,20 @@ +// edition:2018 + +struct S; + +impl S { + async unsafe fn f() {} +} + +async unsafe fn f() {} + +async fn g() { + S::f(); // { dg-error ".E0133." "" { target *-*-* } } + f(); // { dg-error ".E0133." "" { target *-*-* } } +} + +fn main() { + S::f(); // { dg-error ".E0133." "" { target *-*-* } } + f(); // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/async-with-closure.rs b/gcc/testsuite/rust/rustc/ui/async-await/async-with-closure.rs new file mode 100644 index 000000000000..9fa9e2ab8ca9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/async-with-closure.rs @@ -0,0 +1,25 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 + +trait MyClosure { + type Args; +} + +impl MyClosure for dyn FnMut() -> R +where R: 'static { + type Args = (); +} + +struct MyStream { + x: C::Args, +} + +async fn get_future(_stream: MyStream) {} + +async fn f() { + let messages: MyStream = unimplemented!(); + get_future(messages).await; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/auxiliary/arc_wake.rs b/gcc/testsuite/rust/rustc/ui/async-await/auxiliary/arc_wake.rs new file mode 100644 index 000000000000..5ce7894c9658 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/auxiliary/arc_wake.rs @@ -0,0 +1,65 @@ +// edition:2018 + +use std::sync::Arc; +use std::task::{ + Waker, RawWaker, RawWakerVTable, +}; + +macro_rules! waker_vtable { + ($ty:ident) => { + &RawWakerVTable::new( + clone_arc_raw::<$ty>, + wake_arc_raw::<$ty>, + wake_by_ref_arc_raw::<$ty>, + drop_arc_raw::<$ty>, + ) + }; +} + +pub trait ArcWake { + fn wake(self: Arc); + + fn wake_by_ref(arc_self: &Arc) { + arc_self.clone().wake() + } + + fn into_waker(wake: Arc) -> Waker where Self: Sized + { + let ptr = Arc::into_raw(wake) as *const (); + + unsafe { + Waker::from_raw(RawWaker::new(ptr, waker_vtable!(Self))) + } + } +} + +unsafe fn increase_refcount(data: *const ()) { + // Retain Arc by creating a copy + let arc: Arc = Arc::from_raw(data as *const T); + let arc_clone = arc.clone(); + // Forget the Arcs again, so that the refcount isn't decrased + let _ = Arc::into_raw(arc); + let _ = Arc::into_raw(arc_clone); +} + +unsafe fn clone_arc_raw(data: *const ()) -> RawWaker { + increase_refcount::(data); + RawWaker::new(data, waker_vtable!(T)) +} + +unsafe fn drop_arc_raw(data: *const ()) { + // Drop Arc + let _: Arc = Arc::from_raw(data as *const T); +} + +unsafe fn wake_arc_raw(data: *const ()) { + let arc: Arc = Arc::from_raw(data as *const T); + ArcWake::wake(arc); +} + +unsafe fn wake_by_ref_arc_raw(data: *const ()) { + let arc: Arc = Arc::from_raw(data as *const T); + ArcWake::wake_by_ref(&arc); + let _ = Arc::into_raw(arc); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2015-edition-error-various-positions.rs b/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2015-edition-error-various-positions.rs new file mode 100644 index 000000000000..5c5131f64dd8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2015-edition-error-various-positions.rs @@ -0,0 +1,39 @@ +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod await { // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + pub struct await; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + } +} +use outer_mod::await::await; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + +struct Foo { await: () } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +impl Foo { fn await() {} } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +macro_rules! await { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + () => {} +} + +fn main() { + await!(); // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + + match await { await => {} } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2015-edition-warning.rs b/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2015-edition-warning.rs new file mode 100644 index 000000000000..0d9ac5e512eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2015-edition-warning.rs @@ -0,0 +1,28 @@ +// run-rustfix + +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod await { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + pub struct await; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + } +} +use outer_mod::await::await; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + +fn main() { + match await { await => {} } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs b/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs new file mode 100644 index 000000000000..ad6e64944830 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs @@ -0,0 +1,25 @@ +// edition:2018 + +#![allow(non_camel_case_types)] + +mod outer_mod { + pub mod await { // { dg-error "" "" { target *-*-* } } + pub struct await; // { dg-error "" "" { target *-*-* } } + } +} +use self::outer_mod::await::await; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + +struct Foo { await: () } +// { dg-error "" "" { target *-*-* } .-1 } + +impl Foo { fn await() {} } +// { dg-error "" "" { target *-*-* } .-1 } + +macro_rules! await { +// { dg-error "" "" { target *-*-* } .-1 } + () => {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2018-edition-error.rs b/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2018-edition-error.rs new file mode 100644 index 000000000000..9ee2d1309b7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/2018-edition-error.rs @@ -0,0 +1,17 @@ +// edition:2018 +#![allow(non_camel_case_types)] + +mod outer_mod { + pub mod await { // { dg-error "" "" { target *-*-* } } + pub struct await; // { dg-error "" "" { target *-*-* } } + } +} +use self::outer_mod::await::await; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + +macro_rules! await { () => {}; } // { dg-error "" "" { target *-*-* } } + +fn main() { + await!(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs b/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs new file mode 100644 index 000000000000..1b274113a547 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs @@ -0,0 +1,133 @@ +// edition:2018 + +async fn bar() -> Result<(), ()> { + Ok(()) +} + +async fn foo1() -> Result<(), ()> { + let _ = await bar(); // { dg-error "" "" { target *-*-* } } + Ok(()) +} +async fn foo2() -> Result<(), ()> { + let _ = await? bar(); // { dg-error "" "" { target *-*-* } } + Ok(()) +} +async fn foo3() -> Result<(), ()> { + let _ = await bar()?; // { dg-error "" "" { target *-*-* } } + Ok(()) +} +async fn foo21() -> Result<(), ()> { + let _ = await { bar() }; // { dg-error "" "" { target *-*-* } } + Ok(()) +} +async fn foo22() -> Result<(), ()> { + let _ = await(bar()); // { dg-error "" "" { target *-*-* } } + Ok(()) +} +async fn foo23() -> Result<(), ()> { + let _ = await { bar() }?; // { dg-error "" "" { target *-*-* } } + Ok(()) +} +async fn foo4() -> Result<(), ()> { + let _ = (await bar())?; // { dg-error "" "" { target *-*-* } } + Ok(()) +} +async fn foo5() -> Result<(), ()> { + let _ = bar().await(); // { dg-error "" "" { target *-*-* } } + Ok(()) +} +async fn foo6() -> Result<(), ()> { + let _ = bar().await()?; // { dg-error "" "" { target *-*-* } } + Ok(()) +} +async fn foo7() -> Result<(), ()> { + let _ = bar().await; // OK + Ok(()) +} +async fn foo8() -> Result<(), ()> { + let _ = bar().await?; // OK + Ok(()) +} +fn foo9() -> Result<(), ()> { + let _ = await bar(); // { dg-error ".E0728." "" { target *-*-* } } +// { dg-error ".E0728." "" { target *-*-* } .-1 } + Ok(()) +} +fn foo10() -> Result<(), ()> { + let _ = await? bar(); // { dg-error ".E0728." "" { target *-*-* } } +// { dg-error ".E0728." "" { target *-*-* } .-1 } + Ok(()) +} +fn foo11() -> Result<(), ()> { + let _ = await bar()?; // { dg-error "" "" { target *-*-* } } + Ok(()) +} +fn foo12() -> Result<(), ()> { + let _ = (await bar())?; // { dg-error ".E0728." "" { target *-*-* } } +// { dg-error ".E0728." "" { target *-*-* } .-1 } + Ok(()) +} +fn foo13() -> Result<(), ()> { + let _ = bar().await(); // { dg-error ".E0728." "" { target *-*-* } } +// { dg-error ".E0728." "" { target *-*-* } .-1 } + Ok(()) +} +fn foo14() -> Result<(), ()> { + let _ = bar().await()?; // { dg-error ".E0728." "" { target *-*-* } } +// { dg-error ".E0728." "" { target *-*-* } .-1 } + Ok(()) +} +fn foo15() -> Result<(), ()> { + let _ = bar().await; // { dg-error ".E0728." "" { target *-*-* } } + Ok(()) +} +fn foo16() -> Result<(), ()> { + let _ = bar().await?; // { dg-error ".E0728." "" { target *-*-* } } + Ok(()) +} +fn foo24() -> Result<(), ()> { + fn foo() -> Result<(), ()> { + let _ = bar().await?; // { dg-error ".E0728." "" { target *-*-* } } + Ok(()) + } + foo() +} +fn foo25() -> Result<(), ()> { + let foo = || { + let _ = bar().await?; // { dg-error ".E0728." "" { target *-*-* } } + Ok(()) + }; + foo() +} + +async fn foo26() -> Result<(), ()> { + let _ = await!(bar()); // { dg-error "" "" { target *-*-* } } + Ok(()) +} +async fn foo27() -> Result<(), ()> { + let _ = await!(bar())?; // { dg-error "" "" { target *-*-* } } + Ok(()) +} +fn foo28() -> Result<(), ()> { + fn foo() -> Result<(), ()> { + let _ = await!(bar())?; // { dg-error ".E0728." "" { target *-*-* } } +// { dg-error ".E0728." "" { target *-*-* } .-1 } + Ok(()) + } + foo() +} +fn foo29() -> Result<(), ()> { + let foo = || { + let _ = await!(bar())?; // { dg-error ".E0728." "" { target *-*-* } } +// { dg-error ".E0728." "" { target *-*-* } .-1 } + Ok(()) + }; + foo() +} + +fn main() { + match await { await => () } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/post_expansion_error.rs b/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/post_expansion_error.rs new file mode 100644 index 000000000000..8e3d203545d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/await-keyword/post_expansion_error.rs @@ -0,0 +1,11 @@ +// edition:2018 + +macro_rules! r#await { + () => { println!("Hello, world!") } +} + +fn main() { + await!() +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/await-unsize.rs b/gcc/testsuite/rust/rustc/ui/async-await/await-unsize.rs new file mode 100644 index 000000000000..a739ac09f93c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/await-unsize.rs @@ -0,0 +1,15 @@ +// Regression test for #62312 + +// check-pass +// edition:2018 + +async fn make_boxed_object() -> Box { + Box::new(()) as _ +} + +async fn await_object() { + let _ = make_boxed_object().await; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/bound-normalization.rs b/gcc/testsuite/rust/rustc/ui/async-await/bound-normalization.rs new file mode 100644 index 000000000000..72a61d116b3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/bound-normalization.rs @@ -0,0 +1,15 @@ +// check-pass +// edition:2018 + +// See issue 60414 + +trait Trait { + type Assoc; +} + +async fn foo>() -> T::Assoc { + () +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/conditional-and-guaranteed-initialization.rs b/gcc/testsuite/rust/rustc/ui/async-await/conditional-and-guaranteed-initialization.rs new file mode 100644 index 000000000000..721ab77e1cbe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/conditional-and-guaranteed-initialization.rs @@ -0,0 +1,17 @@ +// check-pass +// edition:2018 +// compile-flags: --crate-type lib + +async fn conditional_and_guaranteed_initialization(x: usize) -> usize { + let y; + if x > 5 { + y = echo(10).await; + } else { + y = get_something().await; + } + y +} + +async fn echo(x: usize) -> usize { x } +async fn get_something() -> usize { 10 } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/dont-print-desugared-async.rs b/gcc/testsuite/rust/rustc/ui/async-await/dont-print-desugared-async.rs new file mode 100644 index 000000000000..cd514716a879 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/dont-print-desugared-async.rs @@ -0,0 +1,9 @@ +// Test that we don't show variables with from async fn desugaring + +// edition:2018 + +async fn async_fn(&ref mut s: &[i32]) {} +// { dg-error ".E0596." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/dont-suggest-missing-await.rs b/gcc/testsuite/rust/rustc/ui/async-await/dont-suggest-missing-await.rs new file mode 100644 index 000000000000..0578f7ce48a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/dont-suggest-missing-await.rs @@ -0,0 +1,20 @@ +// edition:2018 + +// This test ensures we don't make the suggestion in bodies that aren't `async`. + +fn take_u32(x: u32) {} + +async fn make_u32() -> u32 { + 22 +} + +async fn dont_suggest_await_in_closure() { + || { + let x = make_u32(); + take_u32(x) +// { dg-error ".E0308." "" { target *-*-* } .-1 } + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/drop-order/auxiliary/arc_wake.rs b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/auxiliary/arc_wake.rs new file mode 100644 index 000000000000..5ce7894c9658 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/auxiliary/arc_wake.rs @@ -0,0 +1,65 @@ +// edition:2018 + +use std::sync::Arc; +use std::task::{ + Waker, RawWaker, RawWakerVTable, +}; + +macro_rules! waker_vtable { + ($ty:ident) => { + &RawWakerVTable::new( + clone_arc_raw::<$ty>, + wake_arc_raw::<$ty>, + wake_by_ref_arc_raw::<$ty>, + drop_arc_raw::<$ty>, + ) + }; +} + +pub trait ArcWake { + fn wake(self: Arc); + + fn wake_by_ref(arc_self: &Arc) { + arc_self.clone().wake() + } + + fn into_waker(wake: Arc) -> Waker where Self: Sized + { + let ptr = Arc::into_raw(wake) as *const (); + + unsafe { + Waker::from_raw(RawWaker::new(ptr, waker_vtable!(Self))) + } + } +} + +unsafe fn increase_refcount(data: *const ()) { + // Retain Arc by creating a copy + let arc: Arc = Arc::from_raw(data as *const T); + let arc_clone = arc.clone(); + // Forget the Arcs again, so that the refcount isn't decrased + let _ = Arc::into_raw(arc); + let _ = Arc::into_raw(arc_clone); +} + +unsafe fn clone_arc_raw(data: *const ()) -> RawWaker { + increase_refcount::(data); + RawWaker::new(data, waker_vtable!(T)) +} + +unsafe fn drop_arc_raw(data: *const ()) { + // Drop Arc + let _: Arc = Arc::from_raw(data as *const T); +} + +unsafe fn wake_arc_raw(data: *const ()) { + let arc: Arc = Arc::from_raw(data as *const T); + ArcWake::wake(arc); +} + +unsafe fn wake_by_ref_arc_raw(data: *const ()) { + let arc: Arc = Arc::from_raw(data as *const T); + ArcWake::wake_by_ref(&arc); + let _ = Arc::into_raw(arc); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs new file mode 100644 index 000000000000..276c2eb80fc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs @@ -0,0 +1,271 @@ +// aux-build:arc_wake.rs +// edition:2018 +// run-pass + +#![allow(unused_variables)] + +// Test that the drop order for parameters in a fn and async fn matches up. Also test that +// parameters (used or unused) are not dropped until the async fn completes execution. +// See also #54716. + +extern crate arc_wake; + +use arc_wake::ArcWake; +use std::cell::RefCell; +use std::future::Future; +use std::marker::PhantomData; +use std::sync::Arc; +use std::rc::Rc; +use std::task::Context; + +struct EmptyWaker; + +impl ArcWake for EmptyWaker { + fn wake(self: Arc) {} +} + +#[derive(Debug, Eq, PartialEq)] +enum DropOrder { + Function, + Val(&'static str), +} + +type DropOrderListPtr = Rc>>; + +struct D(&'static str, DropOrderListPtr); + +impl Drop for D { + fn drop(&mut self) { + self.1.borrow_mut().push(DropOrder::Val(self.0)); + } +} + +/// Check that unused bindings are dropped after the function is polled. +async fn foo_async(ref mut x: D, ref mut _y: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +fn foo_sync(ref mut x: D, ref mut _y: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +/// Check that underscore patterns are dropped after the function is polled. +async fn bar_async(ref mut x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +fn bar_sync(ref mut x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +/// Check that underscore patterns within more complex patterns are dropped after the function +/// is polled. +async fn baz_async((ref mut x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); +} + +fn baz_sync((ref mut x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); +} + +/// Check that underscore and unused bindings within and outwith more complex patterns are dropped +/// after the function is polled. +async fn foobar_async(ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +fn foobar_sync(ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +struct Foo; + +impl Foo { + /// Check that unused bindings are dropped after the method is polled. + async fn foo_async(ref mut x: D, ref mut _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn foo_sync(ref mut x: D, ref mut _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns are dropped after the method is polled. + async fn bar_async(ref mut x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn bar_sync(ref mut x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns within more complex patterns are dropped after the method + /// is polled. + async fn baz_async((ref mut x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn baz_sync((ref mut x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore and unused bindings within and outwith more complex patterns are + /// dropped after the method is polled. + async fn foobar_async( + ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D, + ) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn foobar_sync( + ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D, + ) { + x.1.borrow_mut().push(DropOrder::Function); + } +} + +struct Bar<'a>(PhantomData<&'a ()>); + +impl<'a> Bar<'a> { + /// Check that unused bindings are dropped after the method with self is polled. + async fn foo_async(&'a self, ref mut x: D, ref mut _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn foo_sync(&'a self, ref mut x: D, ref mut _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns are dropped after the method with self is polled. + async fn bar_async(&'a self, ref mut x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn bar_sync(&'a self, ref mut x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns within more complex patterns are dropped after the method + /// with self is polled. + async fn baz_async(&'a self, (ref mut x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn baz_sync(&'a self, (ref mut x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore and unused bindings within and outwith more complex patterns are + /// dropped after the method with self is polled. + async fn foobar_async( + &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D, + ) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn foobar_sync( + &'a self, ref mut x: D, (ref mut a, _, ref mut _c): (D, D, D), _: D, ref mut _y: D, + ) { + x.1.borrow_mut().push(DropOrder::Function); + } +} + +fn assert_drop_order_after_poll>( + f: impl FnOnce(DropOrderListPtr) -> Fut, + g: impl FnOnce(DropOrderListPtr), +) { + let empty = Arc::new(EmptyWaker); + let waker = ArcWake::into_waker(empty); + let mut cx = Context::from_waker(&waker); + + let actual_order = Rc::new(RefCell::new(Vec::new())); + let mut fut = Box::pin(f(actual_order.clone())); + let _ = fut.as_mut().poll(&mut cx); + + let expected_order = Rc::new(RefCell::new(Vec::new())); + g(expected_order.clone()); + + assert_eq!(*actual_order.borrow(), *expected_order.borrow()); +} + +fn main() { + // Free functions (see doc comment on function for what it tests). + assert_drop_order_after_poll(|l| foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| foo_sync(D("x", l.clone()), D("_y", l.clone()))); + assert_drop_order_after_poll(|l| bar_async(D("x", l.clone()), D("_", l.clone())), + |l| bar_sync(D("x", l.clone()), D("_", l.clone()))); + assert_drop_order_after_poll(|l| baz_async((D("x", l.clone()), D("_", l.clone()))), + |l| baz_sync((D("x", l.clone()), D("_", l.clone())))); + assert_drop_order_after_poll( + |l| { + foobar_async( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + |l| { + foobar_sync( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + ); + + // Methods w/out self (see doc comment on function for what it tests). + assert_drop_order_after_poll(|l| Foo::foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| Foo::foo_sync(D("x", l.clone()), D("_y", l.clone()))); + assert_drop_order_after_poll(|l| Foo::bar_async(D("x", l.clone()), D("_", l.clone())), + |l| Foo::bar_sync(D("x", l.clone()), D("_", l.clone()))); + assert_drop_order_after_poll(|l| Foo::baz_async((D("x", l.clone()), D("_", l.clone()))), + |l| Foo::baz_sync((D("x", l.clone()), D("_", l.clone())))); + assert_drop_order_after_poll( + |l| { + Foo::foobar_async( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + |l| { + Foo::foobar_sync( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + ); + + // Methods (see doc comment on function for what it tests). + let b = Bar(Default::default()); + assert_drop_order_after_poll(|l| b.foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| b.foo_sync(D("x", l.clone()), D("_y", l.clone()))); + assert_drop_order_after_poll(|l| b.bar_async(D("x", l.clone()), D("_", l.clone())), + |l| b.bar_sync(D("x", l.clone()), D("_", l.clone()))); + assert_drop_order_after_poll(|l| b.baz_async((D("x", l.clone()), D("_", l.clone()))), + |l| b.baz_sync((D("x", l.clone()), D("_", l.clone())))); + assert_drop_order_after_poll( + |l| { + b.foobar_async( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + |l| { + b.foobar_sync( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs new file mode 100644 index 000000000000..c6f336277880 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs @@ -0,0 +1,266 @@ +// aux-build:arc_wake.rs +// edition:2018 +// run-pass + +// revisions: default nomiropt +//[nomiropt]compile-flags: -Z mir-opt-level=0 + +#![allow(unused_variables)] + +// Test that the drop order for parameters in a fn and async fn matches up. Also test that +// parameters (used or unused) are not dropped until the async fn completes execution. +// See also #54716. + +extern crate arc_wake; + +use arc_wake::ArcWake; +use std::cell::RefCell; +use std::future::Future; +use std::marker::PhantomData; +use std::sync::Arc; +use std::rc::Rc; +use std::task::Context; + +struct EmptyWaker; + +impl ArcWake for EmptyWaker { + fn wake(self: Arc) {} +} + +#[derive(Debug, Eq, PartialEq)] +enum DropOrder { + Function, + Val(&'static str), +} + +type DropOrderListPtr = Rc>>; + +struct D(&'static str, DropOrderListPtr); + +impl Drop for D { + fn drop(&mut self) { + self.1.borrow_mut().push(DropOrder::Val(self.0)); + } +} + +/// Check that unused bindings are dropped after the function is polled. +async fn foo_async(x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +fn foo_sync(x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +/// Check that underscore patterns are dropped after the function is polled. +async fn bar_async(x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +fn bar_sync(x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +/// Check that underscore patterns within more complex patterns are dropped after the function +/// is polled. +async fn baz_async((x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); +} + +fn baz_sync((x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); +} + +/// Check that underscore and unused bindings within and outwith more complex patterns are dropped +/// after the function is polled. +async fn foobar_async(x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +fn foobar_sync(x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +struct Foo; + +impl Foo { + /// Check that unused bindings are dropped after the method is polled. + async fn foo_async(x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn foo_sync(x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns are dropped after the method is polled. + async fn bar_async(x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn bar_sync(x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns within more complex patterns are dropped after the method + /// is polled. + async fn baz_async((x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn baz_sync((x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore and unused bindings within and outwith more complex patterns are + /// dropped after the method is polled. + async fn foobar_async(x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn foobar_sync(x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } +} + +struct Bar<'a>(PhantomData<&'a ()>); + +impl<'a> Bar<'a> { + /// Check that unused bindings are dropped after the method with self is polled. + async fn foo_async(&'a self, x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn foo_sync(&'a self, x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns are dropped after the method with self is polled. + async fn bar_async(&'a self, x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn bar_sync(&'a self, x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns within more complex patterns are dropped after the method + /// with self is polled. + async fn baz_async(&'a self, (x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn baz_sync(&'a self, (x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore and unused bindings within and outwith more complex patterns are + /// dropped after the method with self is polled. + async fn foobar_async(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + fn foobar_sync(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } +} + +fn assert_drop_order_after_poll>( + f: impl FnOnce(DropOrderListPtr) -> Fut, + g: impl FnOnce(DropOrderListPtr), +) { + let empty = Arc::new(EmptyWaker); + let waker = ArcWake::into_waker(empty); + let mut cx = Context::from_waker(&waker); + + let actual_order = Rc::new(RefCell::new(Vec::new())); + let mut fut = Box::pin(f(actual_order.clone())); + let _ = fut.as_mut().poll(&mut cx); + + let expected_order = Rc::new(RefCell::new(Vec::new())); + g(expected_order.clone()); + + assert_eq!(*actual_order.borrow(), *expected_order.borrow()); +} + +fn main() { + // Free functions (see doc comment on function for what it tests). + assert_drop_order_after_poll(|l| foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| foo_sync(D("x", l.clone()), D("_y", l.clone()))); + assert_drop_order_after_poll(|l| bar_async(D("x", l.clone()), D("_", l.clone())), + |l| bar_sync(D("x", l.clone()), D("_", l.clone()))); + assert_drop_order_after_poll(|l| baz_async((D("x", l.clone()), D("_", l.clone()))), + |l| baz_sync((D("x", l.clone()), D("_", l.clone())))); + assert_drop_order_after_poll( + |l| { + foobar_async( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + |l| { + foobar_sync( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + ); + + // Methods w/out self (see doc comment on function for what it tests). + assert_drop_order_after_poll(|l| Foo::foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| Foo::foo_sync(D("x", l.clone()), D("_y", l.clone()))); + assert_drop_order_after_poll(|l| Foo::bar_async(D("x", l.clone()), D("_", l.clone())), + |l| Foo::bar_sync(D("x", l.clone()), D("_", l.clone()))); + assert_drop_order_after_poll(|l| Foo::baz_async((D("x", l.clone()), D("_", l.clone()))), + |l| Foo::baz_sync((D("x", l.clone()), D("_", l.clone())))); + assert_drop_order_after_poll( + |l| { + Foo::foobar_async( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + |l| { + Foo::foobar_sync( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + ); + + // Methods (see doc comment on function for what it tests). + let b = Bar(Default::default()); + assert_drop_order_after_poll(|l| b.foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| b.foo_sync(D("x", l.clone()), D("_y", l.clone()))); + assert_drop_order_after_poll(|l| b.bar_async(D("x", l.clone()), D("_", l.clone())), + |l| b.bar_sync(D("x", l.clone()), D("_", l.clone()))); + assert_drop_order_after_poll(|l| b.baz_async((D("x", l.clone()), D("_", l.clone()))), + |l| b.baz_sync((D("x", l.clone()), D("_", l.clone())))); + assert_drop_order_after_poll( + |l| { + b.foobar_async( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + |l| { + b.foobar_sync( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs new file mode 100644 index 000000000000..5360573abdec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs @@ -0,0 +1,177 @@ +// aux-build:arc_wake.rs +// edition:2018 +// run-pass + +#![deny(dead_code)] +#![allow(unused_variables)] +#![allow(unused_must_use)] +#![allow(path_statements)] + +// Test that the drop order for locals in a fn and async fn matches up. +extern crate arc_wake; + +use arc_wake::ArcWake; +use std::cell::RefCell; +use std::future::Future; +use std::pin::Pin; +use std::rc::Rc; +use std::sync::Arc; +use std::task::{Context, Poll}; + +struct EmptyWaker; + +impl ArcWake for EmptyWaker { + fn wake(self: Arc) {} +} + +#[derive(Debug, Eq, PartialEq)] +enum DropOrder { + Function, + Val(&'static str), +} + +type DropOrderListPtr = Rc>>; + +struct D(&'static str, DropOrderListPtr); + +impl Drop for D { + fn drop(&mut self) { + self.1.borrow_mut().push(DropOrder::Val(self.0)); + } +} + +struct NeverReady; + +impl Future for NeverReady { + type Output = (); + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { + Poll::Pending + } +} + +async fn simple_variable_declaration_async(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); + NeverReady.await; +} + +fn simple_variable_declaration_sync(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); +} + +async fn varable_completely_contained_within_block_async(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + async { + let x = D("x", l.clone()); + } + .await; + let y = D("y", l.clone()); + NeverReady.await; +} + +fn varable_completely_contained_within_block_sync(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + { + let x = D("x", l.clone()); + } + let y = D("y", l.clone()); +} + +async fn variables_moved_into_separate_blocks_async(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); + async move { x }.await; + async move { y }.await; + NeverReady.await; +} + +fn variables_moved_into_separate_blocks_sync(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); + { + x + }; + { + y + }; +} + +async fn variables_moved_into_same_block_async(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); + async move { + x; + y; + }; + NeverReady.await; +} + +fn variables_moved_into_same_block_sync(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); + { + x; + y; + }; + return; +} + +async fn move_after_current_await_doesnt_affect_order(l: DropOrderListPtr) { + l.borrow_mut().push(DropOrder::Function); + let x = D("x", l.clone()); + let y = D("y", l.clone()); + NeverReady.await; + async move { + x; + y; + }; +} + +fn assert_drop_order_after_cancel>( + f: impl FnOnce(DropOrderListPtr) -> Fut, + g: impl FnOnce(DropOrderListPtr), +) { + let empty = Arc::new(EmptyWaker); + let waker = ArcWake::into_waker(empty); + let mut cx = Context::from_waker(&waker); + + let actual_order = Rc::new(RefCell::new(Vec::new())); + let mut fut = Box::pin(f(actual_order.clone())); + let _ = fut.as_mut().poll(&mut cx); + drop(fut); + + let expected_order = Rc::new(RefCell::new(Vec::new())); + g(expected_order.clone()); + assert_eq!(*actual_order.borrow(), *expected_order.borrow()); +} + +fn main() { + assert_drop_order_after_cancel( + simple_variable_declaration_async, + simple_variable_declaration_sync, + ); + assert_drop_order_after_cancel( + varable_completely_contained_within_block_async, + varable_completely_contained_within_block_sync, + ); + assert_drop_order_after_cancel( + variables_moved_into_separate_blocks_async, + variables_moved_into_separate_blocks_sync, + ); + assert_drop_order_after_cancel( + variables_moved_into_same_block_async, + variables_moved_into_same_block_sync, + ); + assert_drop_order_after_cancel( + move_after_current_await_doesnt_affect_order, + simple_variable_declaration_sync, + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs new file mode 100644 index 000000000000..1e57bf3cd93b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs @@ -0,0 +1,99 @@ +// aux-build:arc_wake.rs +// edition:2018 +// run-pass + +// revisions: default nomiropt +//[nomiropt]compile-flags: -Z mir-opt-level=0 + +#![allow(unused_variables)] + +// Test the drop order for parameters relative to local variables and +// temporaries created in the tail return expression of the function +// body. In particular, check that this drop order is the same between +// a `async fn` and an ordinary `fn`. See #64512. + +extern crate arc_wake; + +use arc_wake::ArcWake; +use std::cell::RefCell; +use std::future::Future; +use std::sync::Arc; +use std::rc::Rc; +use std::task::Context; + +struct EmptyWaker; + +impl ArcWake for EmptyWaker { + fn wake(self: Arc) {} +} + +#[derive(Debug, Eq, PartialEq)] +enum DropOrder { + Function, + Val(&'static str), +} + +type DropOrderListPtr = Rc>>; + +struct D(&'static str, DropOrderListPtr); + +impl Drop for D { + fn drop(&mut self) { + self.1.borrow_mut().push(DropOrder::Val(self.0)); + } +} + +/// Check drop order of temporary "temp" as compared to `x`, `y`, and `z`. +/// +/// Expected order: +/// - `z` +/// - temp +/// - `y` +/// - `x` +async fn foo_async(x: D, _y: D) { + let l = x.1.clone(); + let z = D("z", l.clone()); + l.borrow_mut().push(DropOrder::Function); + helper_async(&D("temp", l)).await +} + +async fn helper_async(v: &D) { } + +fn foo_sync(x: D, _y: D) { + let l = x.1.clone(); + let z = D("z", l.clone()); + l.borrow_mut().push(DropOrder::Function); + helper_sync(&D("temp", l)) +} + +fn helper_sync(v: &D) { } + +fn assert_drop_order_after_poll>( + f: impl FnOnce(DropOrderListPtr) -> Fut, + g: impl FnOnce(DropOrderListPtr), +) { + let empty = Arc::new(EmptyWaker); + let waker = ArcWake::into_waker(empty); + let mut cx = Context::from_waker(&waker); + + let actual_order = Rc::new(RefCell::new(Vec::new())); + let mut fut = Box::pin(f(actual_order.clone())); + let r = fut.as_mut().poll(&mut cx); + + assert!(match r { + std::task::Poll::Ready(()) => true, + _ => false, + }); + + let expected_order = Rc::new(RefCell::new(Vec::new())); + g(expected_order.clone()); + + assert_eq!(*actual_order.borrow(), *expected_order.borrow()); +} + +fn main() { + // Free functions (see doc comment on function for what it tests). + assert_drop_order_after_poll(|l| foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| foo_sync(D("x", l.clone()), D("_y", l.clone()))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-locals-are-hidden.rs b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-locals-are-hidden.rs new file mode 100644 index 000000000000..abcc63eae2b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-locals-are-hidden.rs @@ -0,0 +1,14 @@ +// edition:2018 + +async fn foobar_async(x: u32, (a, _, _c): (u32, u32, u32), _: u32, _y: u32) { + assert_eq!(__arg1, (1, 2, 3)); // { dg-error ".E0425." "" { target *-*-* } } + assert_eq!(__arg2, 4); // { dg-error ".E0425." "" { target *-*-* } } +} + +async fn baz_async(ref mut x: u32, ref y: u32) { + assert_eq!(__arg0, 1); // { dg-error ".E0425." "" { target *-*-* } } + assert_eq!(__arg1, 2); // { dg-error ".E0425." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-when-cancelled.rs b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-when-cancelled.rs new file mode 100644 index 000000000000..36aa4ced19d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/drop-order/drop-order-when-cancelled.rs @@ -0,0 +1,310 @@ +// aux-build:arc_wake.rs +// edition:2018 +// run-pass + +// revisions: default nomiropt +//[nomiropt]compile-flags: -Z mir-opt-level=0 + +// Test that the drop order for parameters in a fn and async fn matches up. Also test that +// parameters (used or unused) are not dropped until the async fn is cancelled. +// This file is mostly copy-pasted from drop-order-for-async-fn-parameters.rs + +#![allow(unused_variables)] + +extern crate arc_wake; + +use arc_wake::ArcWake; +use std::cell::RefCell; +use std::future::Future; +use std::marker::PhantomData; +use std::pin::Pin; +use std::rc::Rc; +use std::sync::Arc; +use std::task::{Context, Poll}; + +struct EmptyWaker; + +impl ArcWake for EmptyWaker { + fn wake(self: Arc) {} +} + +#[derive(Debug, Eq, PartialEq)] +enum DropOrder { + Function, + Val(&'static str), +} + +type DropOrderListPtr = Rc>>; + +struct D(&'static str, DropOrderListPtr); + +impl Drop for D { + fn drop(&mut self) { + self.1.borrow_mut().push(DropOrder::Val(self.0)); + } +} + +struct NeverReady; + +impl Future for NeverReady { + type Output = (); + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { + Poll::Pending + } +} + +/// Check that unused bindings are dropped after the function is polled. +async fn foo_async(x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; +} + +fn foo_sync(x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +/// Check that underscore patterns are dropped after the function is polled. +async fn bar_async(x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; +} + +fn bar_sync(x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +/// Check that underscore patterns within more complex patterns are dropped after the function +/// is polled. +async fn baz_async((x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; +} + +fn baz_sync((x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); +} + +/// Check that underscore and unused bindings within and outwith more complex patterns are dropped +/// after the function is polled. +async fn foobar_async(x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; +} + +fn foobar_sync(x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); +} + +struct Foo; + +impl Foo { + /// Check that unused bindings are dropped after the method is polled. + async fn foo_async(x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn foo_sync(x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns are dropped after the method is polled. + async fn bar_async(x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn bar_sync(x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns within more complex patterns are dropped after the method + /// is polled. + async fn baz_async((x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn baz_sync((x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore and unused bindings within and outwith more complex patterns are + /// dropped after the method is polled. + async fn foobar_async(x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn foobar_sync(x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } +} + +struct Bar<'a>(PhantomData<&'a ()>); + +impl<'a> Bar<'a> { + /// Check that unused bindings are dropped after the method with self is polled. + async fn foo_async(&'a self, x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn foo_sync(&'a self, x: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns are dropped after the method with self is polled. + async fn bar_async(&'a self, x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn bar_sync(&'a self, x: D, _: D) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore patterns within more complex patterns are dropped after the method + /// with self is polled. + async fn baz_async(&'a self, (x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn baz_sync(&'a self, (x, _): (D, D)) { + x.1.borrow_mut().push(DropOrder::Function); + } + + /// Check that underscore and unused bindings within and outwith more complex patterns are + /// dropped after the method with self is polled. + async fn foobar_async(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + NeverReady.await; + } + + fn foobar_sync(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) { + x.1.borrow_mut().push(DropOrder::Function); + } +} + +fn assert_drop_order_after_cancel>( + f: impl FnOnce(DropOrderListPtr) -> Fut, + g: impl FnOnce(DropOrderListPtr), +) { + let empty = Arc::new(EmptyWaker); + let waker = ArcWake::into_waker(empty); + let mut cx = Context::from_waker(&waker); + + let actual_order = Rc::new(RefCell::new(Vec::new())); + let mut fut = Box::pin(f(actual_order.clone())); + let _ = fut.as_mut().poll(&mut cx); + + // Parameters are never dropped until the future completes. + assert_eq!(*actual_order.borrow(), vec![DropOrder::Function]); + + drop(fut); + + let expected_order = Rc::new(RefCell::new(Vec::new())); + g(expected_order.clone()); + assert_eq!(*actual_order.borrow(), *expected_order.borrow()); +} + +fn main() { + // Free functions (see doc comment on function for what it tests). + assert_drop_order_after_cancel( + |l| foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| foo_sync(D("x", l.clone()), D("_y", l.clone())), + ); + assert_drop_order_after_cancel( + |l| bar_async(D("x", l.clone()), D("_", l.clone())), + |l| bar_sync(D("x", l.clone()), D("_", l.clone())), + ); + assert_drop_order_after_cancel( + |l| baz_async((D("x", l.clone()), D("_", l.clone()))), + |l| baz_sync((D("x", l.clone()), D("_", l.clone()))), + ); + assert_drop_order_after_cancel( + |l| { + foobar_async( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + |l| { + foobar_sync( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + ); + + // Methods w/out self (see doc comment on function for what it tests). + assert_drop_order_after_cancel( + |l| Foo::foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| Foo::foo_sync(D("x", l.clone()), D("_y", l.clone())), + ); + assert_drop_order_after_cancel( + |l| Foo::bar_async(D("x", l.clone()), D("_", l.clone())), + |l| Foo::bar_sync(D("x", l.clone()), D("_", l.clone())), + ); + assert_drop_order_after_cancel( + |l| Foo::baz_async((D("x", l.clone()), D("_", l.clone()))), + |l| Foo::baz_sync((D("x", l.clone()), D("_", l.clone()))), + ); + assert_drop_order_after_cancel( + |l| { + Foo::foobar_async( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + |l| { + Foo::foobar_sync( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + ); + + // Methods (see doc comment on function for what it tests). + let b = Bar(Default::default()); + assert_drop_order_after_cancel( + |l| b.foo_async(D("x", l.clone()), D("_y", l.clone())), + |l| b.foo_sync(D("x", l.clone()), D("_y", l.clone())), + ); + assert_drop_order_after_cancel( + |l| b.bar_async(D("x", l.clone()), D("_", l.clone())), + |l| b.bar_sync(D("x", l.clone()), D("_", l.clone())), + ); + assert_drop_order_after_cancel( + |l| b.baz_async((D("x", l.clone()), D("_", l.clone()))), + |l| b.baz_sync((D("x", l.clone()), D("_", l.clone()))), + ); + assert_drop_order_after_cancel( + |l| { + b.foobar_async( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + |l| { + b.foobar_sync( + D("x", l.clone()), + (D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())), + D("_", l.clone()), + D("_y", l.clone()), + ) + }, + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/edition-deny-async-fns-2015.rs b/gcc/testsuite/rust/rustc/ui/async-await/edition-deny-async-fns-2015.rs new file mode 100644 index 000000000000..f2a7a9463581 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/edition-deny-async-fns-2015.rs @@ -0,0 +1,39 @@ +// edition:2015 + +async fn foo() {} // { dg-error ".E0670." "" { target *-*-* } } + +fn baz() { async fn foo() {} } // { dg-error ".E0670." "" { target *-*-* } } + +async fn async_baz() { // { dg-error ".E0670." "" { target *-*-* } } + async fn bar() {} // { dg-error ".E0670." "" { target *-*-* } } +} + +struct Foo {} + +impl Foo { + async fn foo() {} // { dg-error ".E0670." "" { target *-*-* } } +} + +trait Bar { + async fn foo() {} // { dg-error ".E0706." "" { target *-*-* } } +// { dg-error ".E0706." "" { target *-*-* } .-1 } +} + +fn main() { + macro_rules! accept_item { ($x:item) => {} } + + accept_item! { + async fn foo() {} // { dg-error ".E0670." "" { target *-*-* } } + } + + accept_item! { + impl Foo { + async fn bar() {} // { dg-error ".E0670." "" { target *-*-* } } + } + } + + let inside_closure = || { + async fn bar() {} // { dg-error ".E0670." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/expansion-in-attrs.rs b/gcc/testsuite/rust/rustc/ui/async-await/expansion-in-attrs.rs new file mode 100644 index 000000000000..55d221938041 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/expansion-in-attrs.rs @@ -0,0 +1,14 @@ +// check-pass +// edition:2018 + +macro_rules! with_doc { + ($doc: expr) => { + #[doc = $doc] + async fn f() {} + }; +} + +with_doc!(concat!("")); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/feature-async-closure.rs b/gcc/testsuite/rust/rustc/ui/async-await/feature-async-closure.rs new file mode 100644 index 000000000000..5b94c80153a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/feature-async-closure.rs @@ -0,0 +1,9 @@ +// edition:2018 +// gate-test-async_closure + +fn f() { + let _ = async || {}; // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/futures-api.rs b/gcc/testsuite/rust/rustc/ui/async-await/futures-api.rs new file mode 100644 index 000000000000..0d2ac818b66e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/futures-api.rs @@ -0,0 +1,62 @@ +// run-pass + +// aux-build:arc_wake.rs + +extern crate arc_wake; + +use std::future::Future; +use std::pin::Pin; +use std::sync::{ + Arc, + atomic::{self, AtomicUsize}, +}; +use std::task::{ + Context, Poll, +}; +use arc_wake::ArcWake; + +struct Counter { + wakes: AtomicUsize, +} + +impl ArcWake for Counter { + fn wake(self: Arc) { + Self::wake_by_ref(&self) + } + fn wake_by_ref(arc_self: &Arc) { + arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst); + } +} + +struct MyFuture; + +impl Future for MyFuture { + type Output = (); + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + // Wake twice + let waker = cx.waker(); + waker.wake_by_ref(); + waker.wake_by_ref(); + Poll::Ready(()) + } +} + +fn test_waker() { + let counter = Arc::new(Counter { + wakes: AtomicUsize::new(0), + }); + let waker = ArcWake::into_waker(counter.clone()); + assert_eq!(2, Arc::strong_count(&counter)); + { + let mut context = Context::from_waker(&waker); + assert_eq!(Poll::Ready(()), Pin::new(&mut MyFuture).poll(&mut context)); + assert_eq!(2, counter.wakes.load(atomic::Ordering::SeqCst)); + } + drop(waker); + assert_eq!(1, Arc::strong_count(&counter)); +} + +fn main() { + test_waker(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/generics-and-bounds.rs b/gcc/testsuite/rust/rustc/ui/async-await/generics-and-bounds.rs new file mode 100644 index 000000000000..93667b03d675 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/generics-and-bounds.rs @@ -0,0 +1,89 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 +// compile-flags: --crate-type lib + +use std::future::Future; + +pub async fn simple_generic() {} + +pub trait Foo { + fn foo(&self) {} +} + +struct FooType; +impl Foo for FooType {} + +pub async fn call_generic_bound(f: F) { + f.foo() +} + +pub async fn call_where_clause(f: F) +where + F: Foo, +{ + f.foo() +} + +pub async fn call_impl_trait(f: impl Foo) { + f.foo() +} + +pub async fn call_with_ref(f: &impl Foo) { + f.foo() +} + +pub fn async_fn_with_same_generic_params_unifies() { + let mut a = call_generic_bound(FooType); + a = call_generic_bound(FooType); + + let mut b = call_where_clause(FooType); + b = call_where_clause(FooType); + + let mut c = call_impl_trait(FooType); + c = call_impl_trait(FooType); + + let f_one = FooType; + let f_two = FooType; + let mut d = call_with_ref(&f_one); + d = call_with_ref(&f_two); +} + +pub fn simple_generic_block() -> impl Future { + async move {} +} + +pub fn call_generic_bound_block(f: F) -> impl Future { + async move { f.foo() } +} + +pub fn call_where_clause_block(f: F) -> impl Future +where + F: Foo, +{ + async move { f.foo() } +} + +pub fn call_impl_trait_block(f: impl Foo) -> impl Future { + async move { f.foo() } +} + +pub fn call_with_ref_block<'a>(f: &'a (impl Foo + 'a)) -> impl Future + 'a { + async move { f.foo() } +} + +pub fn async_block_with_same_generic_params_unifies() { + let mut a = call_generic_bound_block(FooType); + a = call_generic_bound_block(FooType); + + let mut b = call_where_clause_block(FooType); + b = call_where_clause_block(FooType); + + let mut c = call_impl_trait_block(FooType); + c = call_impl_trait_block(FooType); + + let f_one = FooType; + let f_two = FooType; + let mut d = call_with_ref_block(&f_one); + d = call_with_ref_block(&f_two); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-54239-private-type-triggers-lint.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-54239-private-type-triggers-lint.rs new file mode 100644 index 000000000000..bf3d398aef0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-54239-private-type-triggers-lint.rs @@ -0,0 +1,18 @@ +// Regression test for #54239, shouldn't trigger lint. +// check-pass +// edition:2018 + +#![deny(missing_debug_implementations)] + +struct DontLookAtMe(i32); + +async fn secret() -> DontLookAtMe { + DontLookAtMe(41) +} + +pub async fn looking() -> i32 { // Shouldn't trigger lint here. + secret().await.0 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-60709.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-60709.rs new file mode 100644 index 000000000000..57c77e44d1a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-60709.rs @@ -0,0 +1,29 @@ +// This used to compile the future down to ud2, due to uninhabited types being +// handled incorrectly in generators. +// compile-flags: -Copt-level=z -Cdebuginfo=2 --edition=2018 + +// run-pass +// ignore-asmjs wasm2js does not support source maps yet + +use std::future::Future; +use std::task::Poll; +use std::task::Context; +use std::pin::Pin; +use std::rc::Rc; + +struct Never(); +impl Future for Never { + type Output = (); + fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { + Poll::Pending + } +} + +fn main() { + let fut = async { + let _rc = Rc::new(()); // Also crashes with Arc + Never().await; + }; + let _bla = fut; // Moving the future is required. +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-61076.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-61076.rs new file mode 100644 index 000000000000..33ec5f831dc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-61076.rs @@ -0,0 +1,99 @@ +// edition:2018 + +use core::future::Future; +use core::pin::Pin; +use core::task::{Context, Poll}; + +struct T; + +struct Tuple(i32); + +struct Struct { + a: i32 +} + +impl Struct { + fn method(&self) {} +} + +impl Future for Struct { + type Output = Struct; + fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { Poll::Pending } +} + +impl Future for Tuple { + type Output = Tuple; + fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { Poll::Pending } +} + +impl Future for T { + type Output = Result<(), ()>; + + fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { + Poll::Pending + } +} + +async fn foo() -> Result<(), ()> { + Ok(()) +} + +async fn bar() -> Result<(), ()> { + foo()?; // { dg-error ".E0277." "" { target *-*-* } } +// { dg-note ".E0277." "" { target *-*-* } .-1 } +// { help ".E0277." "" { target *-*-* } .-2 } +// { dg-note ".E0277." "" { target *-*-* } .-3 } +// { help ".E0277." "" { target *-*-* } .-4 } +// { dg-note ".E0277." "" { target *-*-* } .-5 } +// { dg-note ".E0277." "" { target *-*-* } .-6 } +// { dg-note ".E0277." "" { target *-*-* } .-7 } +// { dg-note ".E0277." "" { target *-*-* } .-8 } + Ok(()) +} + +async fn struct_() -> Struct { + Struct { a: 1 } +} + +async fn tuple() -> Tuple { +// { dg-note "" "" { target *-*-* } .-1 } + Tuple(1i32) +} + +async fn baz() -> Result<(), ()> { + let t = T; + t?; // { dg-error ".E0277." "" { target *-*-* } } +// { dg-note ".E0277." "" { target *-*-* } .-1 } +// { help ".E0277." "" { target *-*-* } .-2 } +// { dg-note ".E0277." "" { target *-*-* } .-3 } +// { help ".E0277." "" { target *-*-* } .-4 } +// { dg-note ".E0277." "" { target *-*-* } .-5 } +// { dg-note ".E0277." "" { target *-*-* } .-6 } +// { dg-note ".E0277." "" { target *-*-* } .-7 } +// { dg-note ".E0277." "" { target *-*-* } .-8 } + + + let _: i32 = tuple().0; // { dg-error ".E0609." "" { target *-*-* } } +// { help ".E0609." "" { target *-*-* } .-1 } +// { dg-note ".E0609." "" { target *-*-* } .-2 } + + let _: i32 = struct_().a; // { dg-error ".E0609." "" { target *-*-* } } +// { help ".E0609." "" { target *-*-* } .-1 } +// { dg-note ".E0609." "" { target *-*-* } .-2 } + + struct_().method(); // { dg-error ".E0599." "" { target *-*-* } } +// { dg-note ".E0599." "" { target *-*-* } .-1 } +// { help ".E0599." "" { target *-*-* } .-2 } + Ok(()) +} + +async fn match_() { + match tuple() { // { help "" "" { target *-*-* } } + Tuple(_) => {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-note ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-61452.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-61452.rs new file mode 100644 index 000000000000..c05c8d7c242b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-61452.rs @@ -0,0 +1,14 @@ +// edition:2018 + +pub async fn f(x: Option) { + x.take(); +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + +pub async fn g(x: usize) { + x += 1; +// { dg-error ".E0384." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-61793.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-61793.rs new file mode 100644 index 000000000000..2fb562819c85 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-61793.rs @@ -0,0 +1,17 @@ +// This testcase used to ICE in codegen due to inconsistent field reordering +// in the generator state, claiming a ZST field was after a non-ZST field, +// while those two fields were at the same offset (which is impossible). +// That is, memory ordering of `(X, ())`, but offsets of `((), X)`. + +// build-pass +// edition:2018 + +async fn foo(_: &(), _: F) {} + +fn main() { + foo(&(), || {}); + async { + foo(&(), || {}).await; + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-61949-self-return-type.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-61949-self-return-type.rs new file mode 100644 index 000000000000..1892038c347e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-61949-self-return-type.rs @@ -0,0 +1,28 @@ +// ignore-tidy-linelength +// edition:2018 + +// This test checks that `Self` is prohibited as a return type. See #61949 for context. + +pub struct Foo<'a> { + pub bar: &'a i32, +} + +impl<'a> Foo<'a> { + pub async fn new(_bar: &'a i32) -> Self { +// { dg-error ".E0760." "" { target *-*-* } .-1 } + Foo { + bar: &22 + } + } +} + +async fn foo() { + let x = { + let bar = 22; + Foo::new(&bar).await + }; + drop(x); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-62658.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-62658.rs new file mode 100644 index 000000000000..bab369ba486c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-62658.rs @@ -0,0 +1,28 @@ +// This test created a generator whose size was not rounded to a multiple of its +// alignment. This caused an assertion error in codegen. + +// build-pass +// edition:2018 + +async fn noop() {} + +async fn foo() { + // This suspend should be the largest variant. + { + let x = [0u8; 17]; + noop().await; + println!("{:?}", x); + } + + // Add one variant that's aligned to 8 bytes. + { + let x = 0u64; + noop().await; + println!("{:?}", x); + } +} + +fn main() { + let _ = foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-63832-await-short-temporary-lifetime-1.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-63832-await-short-temporary-lifetime-1.rs new file mode 100644 index 000000000000..4eb3e55d0800 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-63832-await-short-temporary-lifetime-1.rs @@ -0,0 +1,20 @@ +// check-pass +// edition:2018 + +struct Test(String); + +impl Test { + async fn borrow_async(&self) {} + + fn with(&mut self, s: &str) -> &mut Self { + self.0 = s.into(); + self + } +} + +async fn test() { + Test("".to_string()).with("123").borrow_async().await; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-63832-await-short-temporary-lifetime.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-63832-await-short-temporary-lifetime.rs new file mode 100644 index 000000000000..270dae650e9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-63832-await-short-temporary-lifetime.rs @@ -0,0 +1,13 @@ +// check-pass +// edition:2018 + +async fn foo(x: &[Vec]) -> u32 { + 0 +} + +async fn bar() { + foo(&[vec![123]]).await; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-1-sync.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-1-sync.rs new file mode 100644 index 000000000000..3426766280f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-1-sync.rs @@ -0,0 +1,24 @@ +#![feature(negative_impls)] +// edition:2018 + +// This tests the the specialized async-await-specific error when futures don't implement an +// auto trait (which is specifically Sync) due to some type that was captured. + +struct Foo; + +impl !Sync for Foo {} + +fn is_sync(t: T) { } + +async fn bar() { + let x = Foo; + baz().await; +} + +async fn baz() { } + +fn main() { + is_sync(bar()); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-2-send.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-2-send.rs new file mode 100644 index 000000000000..875842639af4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-2-send.rs @@ -0,0 +1,24 @@ +#![feature(negative_impls)] +// edition:2018 + +// This tests the the specialized async-await-specific error when futures don't implement an +// auto trait (which is specifically Send) due to some type that was captured. + +struct Foo; + +impl !Send for Foo {} + +fn is_send(t: T) { } + +async fn bar() { + let x = Foo; + baz().await; +} + +async fn baz() { } + +fn main() { + is_send(bar()); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-3-other.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-3-other.rs new file mode 100644 index 000000000000..04f3476b15b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-3-other.rs @@ -0,0 +1,27 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] +// edition:2018 + +// This tests the the unspecialized async-await-specific error when futures don't implement an +// auto trait (which is not Send or Sync) due to some type that was captured. + +auto trait Qux { } + +struct Foo; + +impl !Qux for Foo {} + +fn is_qux(t: T) { } + +async fn bar() { + let x = Foo; + baz().await; +} + +async fn baz() { } + +fn main() { + is_qux(bar()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-4-async-move.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-4-async-move.rs new file mode 100644 index 000000000000..a3f4ddfa8380 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-4-async-move.rs @@ -0,0 +1,29 @@ +// edition:2018 +use std::any::Any; +use std::future::Future; + +struct Client(Box); + +impl Client { + fn status(&self) -> u16 { + 200 + } +} + +async fn get() { } + +pub fn foo() -> impl Future + Send { +// { dg-error "" "" { target *-*-* } .-1 } + let client = Client(Box::new(true)); + async move { + match client.status() { + 200 => { + let _x = get().await; + }, + _ => (), + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-non-send-future-diags.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-non-send-future-diags.rs new file mode 100644 index 000000000000..d24eded3bb14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-64130-non-send-future-diags.rs @@ -0,0 +1,24 @@ +// edition:2018 + +// This tests the basic example case for the async-await-specific error. + +use std::sync::Mutex; + +fn is_send(t: T) { } + +async fn foo() { + bar(&Mutex::new(22)).await; +} + +async fn bar(x: &Mutex) { + let g = x.lock().unwrap(); + baz().await; +} + +async fn baz() { } + +fn main() { + is_send(foo()); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-64391.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-64391.rs new file mode 100644 index 000000000000..26a57686b060 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-64391.rs @@ -0,0 +1,15 @@ +// Regression test for Issue #64391. The goal here is that this +// function compiles. In the past, due to incorrect drop order for +// temporaries in the tail expression, we failed to compile this +// example. The drop order itself is directly tested in +// `drop-order/drop-order-for-temporary-in-tail-return-expr.rs`. +// +// check-pass +// edition:2018 + +async fn add(x: u32, y: u32) -> u32 { + async { x + y }.await +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-66312.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-66312.rs new file mode 100644 index 000000000000..ca9418f4b186 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-66312.rs @@ -0,0 +1,15 @@ +// edition:2018 + +trait Test { + fn is_some(self: T); // { dg-error ".E0307." "" { target *-*-* } } +} + +async fn f() { + let x = Some(2); + if x.is_some() { + println!("Some"); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-66387-if-without-else.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-66387-if-without-else.rs new file mode 100644 index 000000000000..85df0b2fb1d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-66387-if-without-else.rs @@ -0,0 +1,11 @@ +// edition:2018 +async fn f() -> i32 { + if true { // { dg-error ".E0317." "" { target *-*-* } } + return 0; + } + // An `if` block without `else` causes the type table not to have a type for this expr. + // Check that we do not unconditionally access the type table and we don't ICE. +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-67252-unnamed-future.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-67252-unnamed-future.rs new file mode 100644 index 000000000000..fc8401b522da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-67252-unnamed-future.rs @@ -0,0 +1,25 @@ +// edition:2018 +use std::future::Future; +use std::pin::Pin; +use std::task::{Context, Poll}; + +fn spawn(_: T) {} + +pub struct AFuture; +impl Future for AFuture{ + type Output = (); + + fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<()> { + unimplemented!() + } +} + +async fn foo() { + spawn(async { // { dg-error "" "" { target *-*-* } } + let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send` + AFuture.await; + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-67651.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-67651.rs new file mode 100644 index 000000000000..f4e0682165bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-67651.rs @@ -0,0 +1,21 @@ +// edition:2018 + +trait From { + fn from(); +} + +impl From for () { + fn from() {} +} + +impl From for () { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + fn from() {} +} + +fn bar() -> impl core::future::Future { + async move { From::from() } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-67765-async-diagnostic.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-67765-async-diagnostic.rs new file mode 100644 index 000000000000..a3a69d94575e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-67765-async-diagnostic.rs @@ -0,0 +1,17 @@ +// edition:2018 +// +// Regression test for issue #67765 +// Tests that we point at the proper location when giving +// a lifetime error. +fn main() {} + +async fn func<'a>() -> Result<(), &'a str> { + let s = String::new(); + + let b = &s[..]; + + Err(b)?; // { dg-error ".E0515." "" { target *-*-* } } + + Ok(()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-68112.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-68112.rs new file mode 100644 index 000000000000..a3780d8de687 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-68112.rs @@ -0,0 +1,65 @@ +// edition:2018 + +use std::{ + future::Future, + cell::RefCell, + sync::Arc, + pin::Pin, + task::{Context, Poll}, +}; + +fn require_send(_: impl Send) {} + +struct Ready(Option); +impl Future for Ready { + type Output = T; + fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { + Poll::Ready(self.0.take().unwrap()) + } +} +fn ready(t: T) -> Ready { + Ready(Some(t)) +} + +fn make_non_send_future1() -> impl Future>> { + ready(Arc::new(RefCell::new(0))) +} + +fn test1() { + let send_fut = async { + let non_send_fut = make_non_send_future1(); + let _ = non_send_fut.await; + ready(0).await; + }; + require_send(send_fut); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn test1_no_let() { + let send_fut = async { + let _ = make_non_send_future1().await; + ready(0).await; + }; + require_send(send_fut); +// { dg-error "" "" { target *-*-* } .-1 } +} + +async fn ready2(t: T) -> T { t } +fn make_non_send_future2() -> impl Future>> { + ready2(Arc::new(RefCell::new(0))) +} + +// Ideally this test would have diagnostics similar to the test above, but right +// now it doesn't. +fn test2() { + let send_fut = async { + let non_send_fut = make_non_send_future2(); + let _ = non_send_fut.await; + ready(0).await; + }; + require_send(send_fut); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-68523-start.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-68523-start.rs new file mode 100644 index 000000000000..de8c676b174c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-68523-start.rs @@ -0,0 +1,10 @@ +// edition:2018 + +#![feature(start)] + +#[start] +pub async fn start(_: isize, _: *const *const u8) -> isize { +// { dg-error ".E0752." "" { target *-*-* } .-1 } + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-68523.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-68523.rs new file mode 100644 index 000000000000..29f4414ead79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-68523.rs @@ -0,0 +1,8 @@ +// edition:2018 + +async fn main() -> Result { +// { dg-error ".E0752." "" { target *-*-* } .-1 } +// { dg-error ".E0752." "" { target *-*-* } .-2 } + Ok(1) +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-69446-fnmut-capture.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-69446-fnmut-capture.rs new file mode 100644 index 000000000000..74d19634d48a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-69446-fnmut-capture.rs @@ -0,0 +1,23 @@ +// Regression test for issue #69446 - we should display +// which variable is captured +// edition:2018 + +use core::future::Future; + +struct Foo; +impl Foo { + fn foo(&mut self) {} +} + +async fn bar(_: impl FnMut() -> T) +where + T: Future, +{} + +fn main() { + let mut x = Foo; + bar(move || async { // { dg-error "" "" { target *-*-* } } + x.foo(); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-70594.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-70594.rs new file mode 100644 index 000000000000..1fb3dafadf7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-70594.rs @@ -0,0 +1,12 @@ +// edition:2018 + +async fn fun() { + [1; ().await]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-70818.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-70818.rs new file mode 100644 index 000000000000..8ff04cedc24c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-70818.rs @@ -0,0 +1,10 @@ +// edition:2018 + +use std::future::Future; +fn foo(ty: T, ty1: U) -> impl Future + Send { +// { dg-error "" "" { target *-*-* } .-1 } + async { (ty, ty1) } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-70935-complex-spans.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-70935-complex-spans.rs new file mode 100644 index 000000000000..dc677c68c185 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-70935-complex-spans.rs @@ -0,0 +1,26 @@ +// edition:2018 +// #70935: Check if we do not emit snippet +// with newlines which lead complex diagnostics. + +use std::future::Future; + +async fn baz(_c: impl FnMut() -> T) where T: Future { +} + +fn foo(tx: std::sync::mpsc::Sender) -> impl Future + Send { +// { dg-error "" "" { target *-*-* } .-1 } + async move { + baz(|| async{ + foo(tx.clone()); + }).await; + } +} + +fn bar(_s: impl Future + Send) { +} + +fn main() { + let (tx, _rx) = std::sync::mpsc::channel(); + bar(foo(tx)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-71137.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-71137.rs new file mode 100644 index 000000000000..85b8a8fb70dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-71137.rs @@ -0,0 +1,22 @@ +// edition:2018 + +use std::future::Future; +use std::sync::Mutex; + +fn fake_spawn(f: F) { } + +async fn wrong_mutex() { + let m = Mutex::new(1); + { + let mut guard = m.lock().unwrap(); + (async { "right"; }).await; + *guard += 1; + } + + (async { "wrong"; }).await; +} + +fn main() { + fake_spawn(wrong_mutex()); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-72442.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-72442.rs new file mode 100644 index 000000000000..634354077220 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-72442.rs @@ -0,0 +1,27 @@ +// edition:2018 +// compile-flags:-Cincremental=tmp/issue-72442 + +use std::fs::File; +use std::future::Future; +use std::io::prelude::*; + +fn main() -> Result<(), Box> { + block_on(async { + { + let path = std::path::Path::new("."); + let mut f = File::open(path.to_str())?; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let mut src = String::new(); + f.read_to_string(&mut src)?; + Ok(()) + } + }) +} + +fn block_on(f: F) -> F::Output +where + F: Future>>, +{ + Ok(()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-72590-type-error-sized.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-72590-type-error-sized.rs new file mode 100644 index 000000000000..514a3391c376 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-72590-type-error-sized.rs @@ -0,0 +1,23 @@ +// Regression test for issue #72590 +// Tests that we don't emit a spurious "size cannot be statically determined" error +// edition:2018 + +struct Foo { + foo: Nonexistent, // { dg-error ".E0412." "" { target *-*-* } } + other: str +} + +struct Bar { + test: Missing // { dg-error ".E0412." "" { target *-*-* } } +} + +impl Foo { + async fn frob(self) {} // { dg-error ".E0277." "" { target *-*-* } } +} + +impl Bar { + async fn myfn(self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-73050.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-73050.rs new file mode 100644 index 000000000000..de9dc9c5c5e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-73050.rs @@ -0,0 +1,13 @@ +// check-pass +// edition:2018 + +#[allow(unused)] +async fn foo<'a>() { + let _data = &mut [0u8; { 1 + 4 }]; + bar().await +} + +async fn bar() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-73137.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-73137.rs new file mode 100644 index 000000000000..026637e5f244 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-73137.rs @@ -0,0 +1,43 @@ +// Regression test for + +// run-pass +// edition:2018 + +#![allow(dead_code)] +#![feature(wake_trait)] +use std::future::Future; +use std::task::{Waker, Wake, Context}; +use std::sync::Arc; + +struct DummyWaker; +impl Wake for DummyWaker { + fn wake(self: Arc) {} +} + +struct Foo { + a: usize, + b: &'static u32, +} + +#[inline(never)] +fn nop(_: T) {} + +fn main() { + let mut fut = Box::pin(async { + let action = Foo { + b: &42, + a: async { 0 }.await, + }; + + // An error in the generator transform caused `b` to be overwritten with `a` when `b` was + // borrowed. + nop(&action.b); + assert_ne!(0usize, unsafe { std::mem::transmute(action.b) }); + + async {}.await; + }); + let waker = Waker::from(Arc::new(DummyWaker)); + let mut cx = Context::from_waker(&waker); + let _ = fut.as_mut().poll(&mut cx); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-74072-lifetime-name-annotations.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-74072-lifetime-name-annotations.rs new file mode 100644 index 000000000000..d7afdac72484 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-74072-lifetime-name-annotations.rs @@ -0,0 +1,38 @@ +// edition:2018 +#![feature(async_closure)] +use std::future::Future; + +// test the quality of annotations giving lifetimes names (`'1`) when async constructs are involved + +pub async fn async_fn(x: &mut i32) -> &i32 { + let y = &*x; + *x += 1; // { dg-error ".E0506." "" { target *-*-* } } + y +} + +pub fn async_closure(x: &mut i32) -> impl Future { + (async move || { + let y = &*x; + *x += 1; // { dg-error ".E0506." "" { target *-*-* } } + y + })() +} + +pub fn async_closure_explicit_return_type(x: &mut i32) -> impl Future { + (async move || -> &i32 { + let y = &*x; + *x += 1; // { dg-error ".E0506." "" { target *-*-* } } + y + })() +} + +pub fn async_block(x: &mut i32) -> impl Future { + async move { + let y = &*x; + *x += 1; // { dg-error ".E0506." "" { target *-*-* } } + y + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issue-74497-lifetime-in-opaque.rs b/gcc/testsuite/rust/rustc/ui/async-await/issue-74497-lifetime-in-opaque.rs new file mode 100644 index 000000000000..0348d1f31443 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issue-74497-lifetime-in-opaque.rs @@ -0,0 +1,20 @@ +// edition:2018 + +// test that names give to anonymous lifetimes in opaque types like `impl Future` are correctly +// introduced in error messages + +use std::future::Future; + +pub async fn foo(_: F) +where + F: Fn(&u8) -> T, + T: Future, +{ +} + +pub async fn bar(_: &u8) {} + +fn main() { + let _ = foo(|x| bar(x)); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/auxiliary/issue-60674.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/auxiliary/issue-60674.rs new file mode 100644 index 000000000000..2d4eed7d9ef9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/auxiliary/issue-60674.rs @@ -0,0 +1,13 @@ +// force-host +// no-prefer-dynamic +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn attr(_args: TokenStream, input: TokenStream) -> TokenStream { + println!("{}", input); + TokenStream::new() +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/auxiliary/issue_67893.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/auxiliary/issue_67893.rs new file mode 100644 index 000000000000..0900dff3659e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/auxiliary/issue_67893.rs @@ -0,0 +1,11 @@ +// edition:2018 + +use std::sync::{Arc, Mutex}; + +pub async fn f(_: ()) {} + +pub async fn run() { + let x: Arc> = unimplemented!(); + f(*x.lock().unwrap()).await; +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-51719.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-51719.rs new file mode 100644 index 000000000000..41d9d7e72750 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-51719.rs @@ -0,0 +1,13 @@ +// edition:2018 +// +// Tests that the .await syntax can't be used to make a generator + +async fn foo() {} + +fn make_generator() { + let _gen = || foo().await; +// { dg-error ".E0728." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-51751.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-51751.rs new file mode 100644 index 000000000000..2a3a5d750a8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-51751.rs @@ -0,0 +1,12 @@ +// edition:2018 + +async fn inc(limit: i64) -> i64 { + limit + 1 +} + +fn main() { + let result = inc(10000); + let finished = result.await; +// { dg-error ".E0728." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-53249.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-53249.rs new file mode 100644 index 000000000000..b83e3dc0d820 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-53249.rs @@ -0,0 +1,48 @@ +// check-pass +// edition:2018 + +#![feature(arbitrary_self_types)] + +use std::task::{self, Poll}; +use std::future::Future; +use std::marker::Unpin; +use std::pin::Pin; + +// This is a regression test for a ICE/unbounded recursion issue relating to async-await. + +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct Lazy { + f: Option +} + +impl Unpin for Lazy {} + +pub fn lazy(f: F) -> Lazy + where F: FnOnce(&mut task::Context) -> R, +{ + Lazy { f: Some(f) } +} + +impl Future for Lazy + where F: FnOnce(&mut task::Context) -> R, +{ + type Output = R; + + fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll { + Poll::Ready((self.f.take().unwrap())(cx)) + } +} + +async fn __receive(want: WantFn) -> () + where Fut: Future, WantFn: Fn(&Box) -> Fut, +{ + lazy(|_| ()).await; +} + +pub fn basic_spawn_receive() { + async { __receive(|_| async { () }).await }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-54752-async-block.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-54752-async-block.rs new file mode 100644 index 000000000000..e3e05a431b36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-54752-async-block.rs @@ -0,0 +1,8 @@ +// run-pass + +// edition:2018 +// pp-exact + +fn main() { let _a = (async { }); } +// { dg-warning "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-54974.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-54974.rs new file mode 100644 index 000000000000..2c0c907e6e3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-54974.rs @@ -0,0 +1,15 @@ +// check-pass +// edition:2018 + +use std::sync::Arc; + +trait SomeTrait: Send + Sync + 'static { + fn do_something(&self); +} + +async fn my_task(obj: Arc) { + unimplemented!() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-55324.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-55324.rs new file mode 100644 index 000000000000..dd77fb67dda9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-55324.rs @@ -0,0 +1,12 @@ +// check-pass +// edition:2018 + +use std::future::Future; + +async fn foo>(x: &i32, future: F) -> i32 { + let y = future.await; + *x + y +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-55809.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-55809.rs new file mode 100644 index 000000000000..c4b68825af98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-55809.rs @@ -0,0 +1,29 @@ +// edition:2018 +// run-pass + +trait Foo { } + +impl Foo for () { } + +impl<'a, T> Foo for &'a mut T where T: Foo { } + +async fn foo_async(_v: T) -> u8 where T: Foo { + 0 +} + +async fn bad(v: T) -> u8 where T: Foo { + foo_async(v).await +} + +async fn async_main() { + let mut v = (); + + let _ = bad(&mut v).await; + let _ = foo_async(&mut v).await; + let _ = bad(v).await; +} + +fn main() { + let _ = async_main(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-58885.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-58885.rs new file mode 100644 index 000000000000..92a30b150afc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-58885.rs @@ -0,0 +1,20 @@ +// check-pass +// edition:2018 + +struct Xyz { + a: u64, +} + +trait Foo {} + +impl Xyz { + async fn do_sth<'a>( + &'a self, foo: &'a dyn Foo + ) -> bool + { + true + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-59001.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-59001.rs new file mode 100644 index 000000000000..74936ee8a3a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-59001.rs @@ -0,0 +1,15 @@ +// check-pass +// edition:2018 + +use std::future::Future; + +async fn enter<'a, F, R>(mut callback: F) +where + F: FnMut(&'a mut i32) -> R, + R: Future + 'a, +{ + unimplemented!() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-59972.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-59972.rs new file mode 100644 index 000000000000..1c2f449f3d93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-59972.rs @@ -0,0 +1,35 @@ +// Incorrect handling of uninhabited types could cause us to mark generator +// types as entirely uninhabited, when they were in fact constructible. This +// caused us to hit "unreachable" code (illegal instruction on x86). + +// run-pass + +// compile-flags: --edition=2018 -Aunused + +pub enum Uninhabited { } + +fn uninhabited_async() -> Uninhabited { + unreachable!() +} + +async fn noop() { } + +async fn contains_never() { + let error = uninhabited_async(); + noop().await; + let error2 = error; +} + +async fn overlap_never() { + let error1 = uninhabited_async(); + noop().await; + let error2 = uninhabited_async(); + drop(error1); + noop().await; + drop(error2); +} + +#[allow(unused_must_use)] +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-60518.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-60518.rs new file mode 100644 index 000000000000..68c633b052ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-60518.rs @@ -0,0 +1,11 @@ +// check-pass +// edition:2018 + +// This is a regression test to ensure that simple bindings (where replacement arguments aren't +// created during async fn lowering) that have their DefId used during HIR lowering (such as impl +// trait) are visited during def collection and thus have a DefId. + +async fn foo(ws: impl Iterator) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-60655-latebound-regions.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-60655-latebound-regions.rs new file mode 100644 index 000000000000..7cb401342776 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-60655-latebound-regions.rs @@ -0,0 +1,31 @@ +// Test that opaque `impl Trait` types are allowed to contain late-bound regions. + +// check-pass +// edition:2018 + +#![feature(type_alias_impl_trait)] + +use std::future::Future; + +pub type Func = impl Sized; + +// Late bound region should be allowed to escape the function, since it's bound +// in the type. +fn null_function_ptr() -> Func { + None:: fn(&'a ())> +} + +async fn async_nop(_: &u8) {} + +pub type ServeFut = impl Future; + +// Late bound regions occur in the generator witness type here. +fn serve() -> ServeFut { + async move { + let x = 5; + async_nop(&x).await + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-60674.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-60674.rs new file mode 100644 index 000000000000..0591e1d5011f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-60674.rs @@ -0,0 +1,20 @@ +// aux-build:issue-60674.rs +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 + +// This is a regression test that ensures that `mut` patterns are not lost when provided as input +// to a proc macro. + +extern crate issue_60674; + +#[issue_60674::attr] +async fn f(mut x: u8) {} + +#[issue_60674::attr] +async fn g((mut x, y, mut z): (u8, u8, u8)) {} + +#[issue_60674::attr] +async fn g(mut x: u8, (a, mut b, c): (u8, u8, u8), y: u8) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-61187.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-61187.rs new file mode 100644 index 000000000000..e28225d75c04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-61187.rs @@ -0,0 +1,8 @@ +// edition:2018 + +fn main() {} + +async fn response(data: Vec) { + data.reverse(); // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-61986.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-61986.rs new file mode 100644 index 000000000000..928451febf81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-61986.rs @@ -0,0 +1,20 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 +// +// Tests that we properly handle StorageDead/StorageLives for temporaries +// created in async loop bodies. + +async fn bar() -> Option<()> { + Some(()) +} + +async fn listen() { + while let Some(_) = bar().await { + String::new(); + } +} + +fn main() { + listen(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62009-1.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62009-1.rs new file mode 100644 index 000000000000..1259e5ac09ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62009-1.rs @@ -0,0 +1,16 @@ +// edition:2018 + +async fn print_dur() {} + +fn main() { + async { let (); }.await; +// { dg-error ".E0728." "" { target *-*-* } .-1 } + async { +// { dg-error ".E0728." "" { target *-*-* } .-1 } + let task1 = print_dur().await; + }.await; + (|_| 2333).await; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62009-2.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62009-2.rs new file mode 100644 index 000000000000..ac720fbfa727 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62009-2.rs @@ -0,0 +1,11 @@ +// edition:2018 + +#![feature(async_closure)] + +async fn print_dur() {} + +fn main() { + (async || 2333)().await; +// { dg-error ".E0728." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62097.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62097.rs new file mode 100644 index 000000000000..d311473f05ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62097.rs @@ -0,0 +1,20 @@ +// edition:2018 +async fn foo(fun: F) +where + F: FnOnce() + 'static +{ + fun() +} + +struct Struct; + +impl Struct { + pub async fn run_dummy_fn(&self) { // { dg-error ".E0759." "" { target *-*-* } } + foo(|| self.bar()).await; + } + + pub fn bar(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62517-1.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62517-1.rs new file mode 100644 index 000000000000..a39cd80770d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62517-1.rs @@ -0,0 +1,22 @@ +// Regression test for #62517. We used to ICE when you had an `async +// fn` with an `impl Trait` return that mentioned a `dyn Bar` with no +// explicit lifetime bound. +// +// edition:2018 +// check-pass + +trait FirstTrait {} +trait SecondTrait { + type Item: ?Sized; +} + +async fn foo(x: &str) -> impl SecondTrait { +} + + +impl SecondTrait for T { + type Item = dyn FirstTrait; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62517-2.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62517-2.rs new file mode 100644 index 000000000000..5d8ab17be06f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-62517-2.rs @@ -0,0 +1,17 @@ +// Regression test for #62517. We used to ICE when you had an `async +// fn` with an `impl Trait` return that mentioned a `dyn Bar` with no +// explicit lifetime bound. +// +// edition:2018 +// check-pass + +trait Object {} + +trait Alpha {} + +async fn foo<'a>(_: &'a ()) -> impl Alpha {} + +impl Alpha for T { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-1.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-1.rs new file mode 100644 index 000000000000..1c2de448ae5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-1.rs @@ -0,0 +1,19 @@ +// edition:2018 + +struct Xyz { + a: u64, +} + +trait Foo {} + +impl Xyz { + async fn do_sth<'a>( + &'a self, foo: &dyn Foo + ) -> &dyn Foo + { + foo // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-2.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-2.rs new file mode 100644 index 000000000000..76004921b85a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-2.rs @@ -0,0 +1,19 @@ +// edition:2018 + +struct Xyz { + a: u64, +} + +trait Foo {} + +impl Xyz { + async fn do_sth<'a>( + foo: &dyn Foo, bar: &'a dyn Foo + ) -> &dyn Foo // { dg-error ".E0106." "" { target *-*-* } } + { + foo + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-3.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-3.rs new file mode 100644 index 000000000000..a0fafbbe36e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-3.rs @@ -0,0 +1,18 @@ +// edition:2018 +// check-pass + +struct Xyz { + a: u64, +} + +trait Foo {} + +impl Xyz { + async fn do_sth( + &self, foo: &dyn Foo + ) { + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-4.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-4.rs new file mode 100644 index 000000000000..ff518352c688 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-63388-4.rs @@ -0,0 +1,11 @@ +// check-pass +// edition:2018 + +struct A; + +impl A { + async fn foo(&self, f: &u32) -> &A { self } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64391-2.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64391-2.rs new file mode 100644 index 000000000000..a6345b890078 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64391-2.rs @@ -0,0 +1,21 @@ +// Regression test for #64391 +// +// As described on the issue, the (spurious) `DROP` inserted for the +// `"".to_string()` value was causing a (spurious) unwind path that +// led us to believe that the future might be dropped after `config` +// had been dropped. This cannot, in fact, happen. +// +// check-pass +// edition:2018 + +async fn connect() { + let config = 666; + connect2(&config, "".to_string()).await +} + +async fn connect2(_config: &u32, _tls: String) { + unimplemented!() +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64433.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64433.rs new file mode 100644 index 000000000000..2281ff796cb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64433.rs @@ -0,0 +1,31 @@ +// Regression test for issue #64433. +// +// See issue-64391-2.rs for more details, as that was fixed by the +// same PR. +// +// check-pass +// edition:2018 + +#[derive(Debug)] +struct A<'a> { + inner: Vec<&'a str>, +} + +struct B {} + +impl B { + async fn something_with_a(&mut self, a: A<'_>) -> Result<(), String> { + println!("{:?}", a); + Ok(()) + } +} + +async fn can_error(some_string: &str) -> Result<(), String> { + let a = A { inner: vec![some_string, "foo"] }; + let mut b = B {}; + Ok(b.something_with_a(a).await.map(drop)?) +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64477-2.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64477-2.rs new file mode 100644 index 000000000000..35a2ac90fd95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64477-2.rs @@ -0,0 +1,23 @@ +// Another regression test for #64477. +// +// In the past, the code generated by `format!` produced temporaries in the surrounding scope that +// borrowed the arguments through `&dyn Trait`. These temporaries do not implement `Send`, which +// meant that when `format!` was used in an async block, the resulting generator was not `Send`. +// See https://github.com/rust-lang/rust/issues/64477#issuecomment-534669068 for details +// and https://github.com/rust-lang/rust/issues/64477#issuecomment-531882958 for an example. +// +// check-pass +// edition:2018 + +async fn foo(_: String) {} + +fn bar() -> impl Send { + async move { + foo(format!("{}:{}", 1, 2)).await; + } +} + +fn main() { + let _ = bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64477.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64477.rs new file mode 100644 index 000000000000..83be61bf674e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64477.rs @@ -0,0 +1,21 @@ +// Regression test for #64477. +// +// We were incorrectly claiming that the `f(x).await` future captured +// a value of type `T`, and hence that `T: Send` would have to hold. +// +// check-pass +// edition:2018 + +use std::future::Future; +use std::pin::Pin; + +fn f(_: &T) -> Pin + Send>> { + unimplemented!() +} + +pub fn g(x: &'static T) -> impl Future + Send { + async move { f(x).await } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64964.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64964.rs new file mode 100644 index 000000000000..9877df1ccf27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-64964.rs @@ -0,0 +1,23 @@ +// check-pass +// compile-flags: -Z query-dep-graph +// edition:2018 + +// Regression test for ICE related to `await`ing in a method + incr. comp. (#64964) + +struct Body; +impl Body { + async fn next(&mut self) { + async {}.await + } +} + +// Another reproduction: `await`ing with a variable from for-loop. + +async fn bar() { + for x in 0..10 { + async { Some(x) }.await.unwrap(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65159.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65159.rs new file mode 100644 index 000000000000..f23251a03178 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65159.rs @@ -0,0 +1,12 @@ +// Regression test for #65159. We used to ICE. +// +// edition:2018 + +async fn copy() -> Result<()> // { dg-error ".E0107." "" { target *-*-* } } +{ + Ok(()) +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs new file mode 100644 index 000000000000..d8faa30f0b14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs @@ -0,0 +1,47 @@ +// issue 65419 - Attempting to run an async fn after completion mentions generators when it should +// be talking about `async fn`s instead. + +// run-fail +// error-pattern: thread 'main' panicked at '`async fn` resumed after completion' +// edition:2018 +// ignore-wasm no panic or subprocess support +// ignore-emscripten no panic or subprocess support + +#![feature(generators, generator_trait)] + +async fn foo() { +} + +fn main() { + let mut future = Box::pin(foo()); + executor::block_on(future.as_mut()); + executor::block_on(future.as_mut()); +} + +mod executor { + use core::{ + future::Future, + pin::Pin, + task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, + }; + + pub fn block_on(mut future: F) -> F::Output { + let mut future = unsafe { Pin::new_unchecked(&mut future) }; + + static VTABLE: RawWakerVTable = RawWakerVTable::new( + |_| unimplemented!("clone"), + |_| unimplemented!("wake"), + |_| unimplemented!("wake_by_ref"), + |_| (), + ); + let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + let mut context = Context::from_waker(&waker); + + loop { + if let Poll::Ready(val) = future.as_mut().poll(&mut context) { + break val; + } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs new file mode 100644 index 000000000000..149cece2c028 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs @@ -0,0 +1,53 @@ +// issue 65419 - Attempting to run an async fn after completion mentions generators when it should +// be talking about `async fn`s instead. Should also test what happens when it panics. + +// run-fail +// error-pattern: thread 'main' panicked at '`async fn` resumed after panicking' +// edition:2018 +// ignore-wasm no panic or subprocess support +// ignore-emscripten no panic or subprocess support + +#![feature(generators, generator_trait)] + +use std::panic; + +async fn foo() { + panic!(); +} + +fn main() { + let mut future = Box::pin(foo()); + panic::catch_unwind(panic::AssertUnwindSafe(|| { + executor::block_on(future.as_mut()); + })); + + executor::block_on(future.as_mut()); +} + +mod executor { + use core::{ + future::Future, + pin::Pin, + task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, + }; + + pub fn block_on(mut future: F) -> F::Output { + let mut future = unsafe { Pin::new_unchecked(&mut future) }; + + static VTABLE: RawWakerVTable = RawWakerVTable::new( + |_| unimplemented!("clone"), + |_| unimplemented!("wake"), + |_| unimplemented!("wake_by_ref"), + |_| (), + ); + let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; + let mut context = Context::from_waker(&waker); + + loop { + if let Poll::Ready(val) = future.as_mut().poll(&mut context) { + break val; + } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65419/issue-65419-generator-resume-after-completion.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65419/issue-65419-generator-resume-after-completion.rs new file mode 100644 index 000000000000..60837551ff8b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65419/issue-65419-generator-resume-after-completion.rs @@ -0,0 +1,26 @@ +// issue 65419 - Attempting to run an `async fn` after completion mentions generators when it should +// be talking about `async fn`s instead. Regression test added to make sure generators still +// panic when resumed after completion. + +// run-fail +// error-pattern:generator resumed after completion +// edition:2018 +// ignore-wasm no panic or subprocess support +// ignore-emscripten no panic or subprocess support + +#![feature(generators, generator_trait)] + +use std::{ + ops::Generator, + pin::Pin, +}; + +fn main() { + let mut g = || { + yield; + }; + Pin::new(&mut g).resume(()); // Yields once. + Pin::new(&mut g).resume(()); // Completes here. + Pin::new(&mut g).resume(()); // Panics here. +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs new file mode 100644 index 000000000000..1caff1c586e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs @@ -0,0 +1,17 @@ +// edition:2018 + +struct Foo(*const u8); + +unsafe impl Send for Foo {} + +async fn bar(_: Foo) {} + +fn assert_send(_: T) {} + +fn main() { + assert_send(async { +// { dg-error "" "" { target *-*-* } .-1 } + bar(Foo(std::ptr::null())).await; + }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-66695-static-refs.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-66695-static-refs.rs new file mode 100644 index 000000000000..67969bb60d95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-66695-static-refs.rs @@ -0,0 +1,25 @@ +// build-pass +// edition:2018 + +static A: [i32; 5] = [1, 2, 3, 4, 5]; + +async fn fun() { + let u = A[async { 1 }.await]; + match A { + i if async { true }.await => (), + _ => (), + } +} + +fn main() { + async { + let u = A[async { 1 }.await]; + }; + async { + match A { + i if async { true }.await => (), + _ => (), + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs new file mode 100644 index 000000000000..52e84b325538 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs @@ -0,0 +1,16 @@ +// edition:2018 + +struct Ia(S); + +impl Ia { + fn partial(_: S) {} + fn full(self) {} + + async fn crash(self) { + Self::partial(self.0); + Self::full(self); // { dg-error ".E0382." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-67611-static-mut-refs.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-67611-static-mut-refs.rs new file mode 100644 index 000000000000..fe0b21503a7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-67611-static-mut-refs.rs @@ -0,0 +1,34 @@ +// build-pass +// edition:2018 + +static mut A: [i32; 5] = [1, 2, 3, 4, 5]; + +fn is_send_sync(_: T) {} + +async fn fun() { + let u = unsafe { A[async { 1 }.await] }; + unsafe { + match A { + i if async { true }.await => (), + _ => (), + } + } +} + +fn main() { + let index_block = async { + let u = unsafe { A[async { 1 }.await] }; + }; + let match_block = async { + unsafe { + match A { + i if async { true }.await => (), + _ => (), + } + } + }; + is_send_sync(index_block); + is_send_sync(match_block); + is_send_sync(fun()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-67893.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-67893.rs new file mode 100644 index 000000000000..7b76564ae572 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-67893.rs @@ -0,0 +1,12 @@ +// aux-build: issue_67893.rs +// edition:2018 + +extern crate issue_67893; + +fn g(_: impl Send) {} + +fn main() { + g(issue_67893::run()) +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-69307-nested.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-69307-nested.rs new file mode 100644 index 000000000000..b2b45dcc7220 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-69307-nested.rs @@ -0,0 +1,31 @@ +// Regression test for #69307 +// +// Having a `async { .. foo.await .. }` block appear inside of a `+=` +// expression was causing an ICE due to a failure to save/restore +// state in the AST numbering pass when entering a nested body. +// +// check-pass +// edition:2018 + +fn block_on(_: F) -> usize { + 0 +} + +fn main() {} + +async fn bar() { + let mut sum = 0; + sum += { + block_on(async { + baz().await; + let mut inner = 1; + inner += block_on(async { + baz().await; + 0 + }) + }) + }; +} + +async fn baz() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-69307.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-69307.rs new file mode 100644 index 000000000000..0e7b31c45b44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-69307.rs @@ -0,0 +1,24 @@ +// Regression test for #69307 +// +// Having a `async { .. foo.await .. }` block appear inside of a `+=` +// expression was causing an ICE due to a failure to save/restore +// state in the AST numbering pass when entering a nested body. +// +// check-pass +// edition:2018 + +fn block_on(_: F) -> usize { + 0 +} + +fn main() {} + +async fn bar() { + let mut sum = 0; + sum += block_on(async { + baz().await; + }); +} + +async fn baz() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-78654.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-78654.rs new file mode 100644 index 000000000000..ae4ed222abc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/issue-78654.rs @@ -0,0 +1,17 @@ +// edition:2018 +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Foo; + +impl Foo { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + async fn biz() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/issues/non-async-enclosing-span.rs b/gcc/testsuite/rust/rustc/ui/async-await/issues/non-async-enclosing-span.rs new file mode 100644 index 000000000000..b69304829a7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/issues/non-async-enclosing-span.rs @@ -0,0 +1,12 @@ +// edition:2018 + +async fn do_the_thing() -> u8 { + 8 +} +// #63398: point at the enclosing scope and not the previously seen closure +fn main() { // { dg-note "" "" { target *-*-* } } + let x = move || {}; + let y = do_the_thing().await; // { dg-error ".E0728." "" { target *-*-* } } +// { dg-note ".E0728." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/move-part-await-return-rest-struct.rs b/gcc/testsuite/rust/rustc/ui/async-await/move-part-await-return-rest-struct.rs new file mode 100644 index 000000000000..4f2ca47f79c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/move-part-await-return-rest-struct.rs @@ -0,0 +1,19 @@ +// build-pass +// edition:2018 +// compile-flags: --crate-type lib + +struct Small { + x: Vec, + y: Vec, +} + +// You are allowed to move out part of a struct to an async fn, you still +// have access to remaining parts after awaiting +async fn move_part_await_return_rest_struct() -> Vec { + let s = Small { x: vec![31], y: vec![19, 1441] }; + needs_vec(s.x).await; + s.y +} + +async fn needs_vec(_vec: Vec) {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/move-part-await-return-rest-tuple.rs b/gcc/testsuite/rust/rustc/ui/async-await/move-part-await-return-rest-tuple.rs new file mode 100644 index 000000000000..04abf86d365b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/move-part-await-return-rest-tuple.rs @@ -0,0 +1,13 @@ +// build-pass +// edition:2018 +// compile-flags: --crate-type lib + +async fn move_part_await_return_rest_tuple() -> Vec { + let x = (vec![3], vec![4, 4]); + drop(x.1); + echo(x.0[0]).await; + x.0 +} + +async fn echo(x: usize) -> usize { x } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/elided.rs b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/elided.rs new file mode 100644 index 000000000000..907388b67297 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/elided.rs @@ -0,0 +1,11 @@ +// edition:2018 +// run-pass + +// Test that we can use async fns with multiple arbitrary lifetimes. + +async fn multiple_elided_lifetimes(_: &u8, _: &u8) {} + +fn main() { + let _ = multiple_elided_lifetimes(&22, &44); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/fn-ptr.rs b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/fn-ptr.rs new file mode 100644 index 000000000000..0d21d79f8469 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/fn-ptr.rs @@ -0,0 +1,13 @@ +// edition:2018 +// run-pass + +// Test that we can use async fns with multiple arbitrary lifetimes. + +async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8, _: fn(&u8)) {} + +fn gimme(_: &u8) { } + +fn main() { + let _ = multiple_named_lifetimes(&22, &44, gimme); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/hrtb.rs b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/hrtb.rs new file mode 100644 index 000000000000..538e69811a45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/hrtb.rs @@ -0,0 +1,15 @@ +// edition:2018 +// check-pass + +// Test that we can use async fns with multiple arbitrary lifetimes. + +use std::ops::Add; + +async fn multiple_hrtb_and_single_named_lifetime_ok<'c>( + _: impl for<'a> Add<&'a u8>, + _: impl for<'b> Add<&'b u8>, + _: &'c u8, +) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/named.rs b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/named.rs new file mode 100644 index 000000000000..79604e764318 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/named.rs @@ -0,0 +1,11 @@ +// edition:2018 +// run-pass + +// Test that we can use async fns with multiple arbitrary lifetimes. + +async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {} + +fn main() { + let _ = multiple_named_lifetimes(&22, &44); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/partial-relation.rs b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/partial-relation.rs new file mode 100644 index 000000000000..9085797656e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/partial-relation.rs @@ -0,0 +1,14 @@ +// edition:2018 +// run-pass + +async fn lotsa_lifetimes<'a, 'b, 'c>(a: &'a u32, b: &'b u32, c: &'c u32) -> (&'a u32, &'b u32) + where 'b: 'a +{ + drop((a, c)); + (b, b) +} + +fn main() { + let _ = lotsa_lifetimes(&22, &44, &66); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs new file mode 100644 index 000000000000..a1268fa1c0e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs @@ -0,0 +1,19 @@ +// edition:2018 +// run-pass + +// Test that a feature gate is needed to use `impl Trait` as the +// return type of an async. + +#![feature(member_constraints)] + +trait Trait<'a, 'b> { } +impl Trait<'_, '_> for T { } + +async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + (a, b) +} + +fn main() { + let _ = async_ret_impl_trait(&22, &44); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs new file mode 100644 index 000000000000..9e75bdfb5fec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs @@ -0,0 +1,21 @@ +// edition:2018 + +// Test that a feature gate is needed to use `impl Trait` as the +// return type of an async. + +trait Trait<'a, 'b> { } +impl Trait<'_, '_> for T { } + +async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { +// { dg-error ".E0700." "" { target *-*-* } .-1 } +// { dg-error ".E0700." "" { target *-*-* } .-2 } +// { dg-error ".E0700." "" { target *-*-* } .-3 } +// { dg-error ".E0700." "" { target *-*-* } .-4 } +// { dg-error ".E0700." "" { target *-*-* } .-5 } + (a, b) +} + +fn main() { + let _ = async_ret_impl_trait(&22, &44); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs new file mode 100644 index 000000000000..034cefacc6cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs @@ -0,0 +1,28 @@ +// edition:2018 + +// Test that a feature gate is needed to use `impl Trait` as the +// return type of an async. + +#![feature(member_constraints)] + +trait Trait<'a> { } +impl Trait<'_> for T { } + +// Only `'a` permitted in return type, not `'b`. +async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { +// { dg-error ".E0623." "" { target *-*-* } .-1 } + (a, b) +} + +// As above, but `'b: 'a`, so return type can be inferred to `(&'a u8, +// &'a u8)`. +async fn async_ret_impl_trait2<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> +where + 'b: 'a, +{ + (a, b) +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-ref.rs b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-ref.rs new file mode 100644 index 000000000000..7f05816b99c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/ret-ref.rs @@ -0,0 +1,45 @@ +// edition:2018 + +// Test that we get the expected borrow check errors when an async +// function (which takes multiple lifetimes) only returns data from +// one of them. + +async fn multiple_named_lifetimes<'a, 'b>(a: &'a u8, _: &'b u8) -> &'a u8 { + a +} + +// Both are borrowed whilst the future is live. +async fn future_live() { + let mut a = 22; + let mut b = 44; + let future = multiple_named_lifetimes(&a, &b); + a += 1; // { dg-error ".E0506." "" { target *-*-* } } + b += 1; // { dg-error ".E0506." "" { target *-*-* } } + let p = future.await; + drop(p); +} + +// Just the return value is live after future is awaited. +async fn just_return_live() { + let mut a = 22; + let mut b = 44; + let future = multiple_named_lifetimes(&a, &b); + let p = future.await; + a += 1; // { dg-error ".E0506." "" { target *-*-* } } + b += 1; + drop(p); +} + +// Once `p` is dead, both `a` and `b` are unborrowed. +async fn after_both_dead() { + let mut a = 22; + let mut b = 44; + let future = multiple_named_lifetimes(&a, &b); + let p = future.await; + drop(p); + a += 1; + b += 1; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/variance.rs b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/variance.rs new file mode 100644 index 000000000000..c3b8a6f3c1e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/multiple-lifetimes/variance.rs @@ -0,0 +1,16 @@ +// edition:2018 +// run-pass + +// Test for async fn where the parameters have distinct lifetime +// parameters that appear in all possible variances. + +async fn lotsa_lifetimes<'a, 'b, 'c>(_: fn(&'a u8), _: fn(&'b u8) -> &'b u8, _: fn() -> &'c u8) { } + +fn take_any(_: &u8) { } +fn identify(x: &u8) -> &u8 { x } +fn give_back() -> &'static u8 { &22 } + +fn main() { + let _ = lotsa_lifetimes(take_any, identify, give_back); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/mutually-recursive-async-impl-trait-type.rs b/gcc/testsuite/rust/rustc/ui/async-await/mutually-recursive-async-impl-trait-type.rs new file mode 100644 index 000000000000..7794dceb9574 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/mutually-recursive-async-impl-trait-type.rs @@ -0,0 +1,14 @@ +// edition:2018 +// Test that impl trait does not allow creating recursive types that are +// otherwise forbidden when using `async` and `await`. + +async fn rec_1() { // { dg-error ".E0733." "" { target *-*-* } } + rec_2().await; +} + +async fn rec_2() { // { dg-error ".E0733." "" { target *-*-* } } + rec_1().await; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/nested-in-impl.rs b/gcc/testsuite/rust/rustc/ui/async-await/nested-in-impl.rs new file mode 100644 index 000000000000..cde6044455c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/nested-in-impl.rs @@ -0,0 +1,16 @@ +// Test that async fn works when nested inside of +// impls with lifetime parameters. +// +// check-pass +// edition:2018 + +struct Foo<'a>(&'a ()); + +impl<'a> Foo<'a> { + fn test() { + async fn test() {} + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/no-async-const.rs b/gcc/testsuite/rust/rustc/ui/async-await/no-async-const.rs new file mode 100644 index 000000000000..3b3cb71910a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/no-async-const.rs @@ -0,0 +1,6 @@ +// edition:2018 +// compile-flags: --crate-type lib + +pub async const fn x() {} +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/no-const-async.rs b/gcc/testsuite/rust/rustc/ui/async-await/no-const-async.rs new file mode 100644 index 000000000000..4ac5faf29b39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/no-const-async.rs @@ -0,0 +1,6 @@ +// edition:2018 +// compile-flags: --crate-type lib + +pub const async fn x() {} +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/no-move-across-await-struct.rs b/gcc/testsuite/rust/rustc/ui/async-await/no-move-across-await-struct.rs new file mode 100644 index 000000000000..255a42b15f78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/no-move-across-await-struct.rs @@ -0,0 +1,17 @@ +// edition:2018 +// compile-flags: --crate-type lib + +async fn no_move_across_await_struct() -> Vec { + let s = Small { x: vec![31], y: vec![19, 1441] }; + needs_vec(s.x).await; + s.x +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +struct Small { + x: Vec, + y: Vec, +} + +async fn needs_vec(_vec: Vec) {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/no-move-across-await-tuple.rs b/gcc/testsuite/rust/rustc/ui/async-await/no-move-across-await-tuple.rs new file mode 100644 index 000000000000..d8783950c4e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/no-move-across-await-tuple.rs @@ -0,0 +1,13 @@ +// edition:2018 +// compile-flags: --crate-type lib + +async fn no_move_across_await_tuple() -> Vec { + let x = (vec![3], vec![4, 4]); + drop(x.1); + nothing().await; + x.1 +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +async fn nothing() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/no-non-guaranteed-initialization.rs b/gcc/testsuite/rust/rustc/ui/async-await/no-non-guaranteed-initialization.rs new file mode 100644 index 000000000000..1fe7582aff62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/no-non-guaranteed-initialization.rs @@ -0,0 +1,14 @@ +// edition:2018 +// compile-flags: --crate-type lib + +async fn no_non_guaranteed_initialization(x: usize) -> usize { + let y; + if x > 5 { + y = echo(10).await; + } + y +// { dg-error ".E0381." "" { target *-*-* } .-1 } +} + +async fn echo(x: usize) -> usize { x + 1 } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/no-params-non-move-async-closure.rs b/gcc/testsuite/rust/rustc/ui/async-await/no-params-non-move-async-closure.rs new file mode 100644 index 000000000000..8d57ac4f0831 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/no-params-non-move-async-closure.rs @@ -0,0 +1,9 @@ +// edition:2018 + +#![feature(async_closure)] + +fn main() { + let _ = async |x: u8| {}; +// { dg-error ".E0708." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/no-std.rs b/gcc/testsuite/rust/rustc/ui/async-await/no-std.rs new file mode 100644 index 000000000000..6db2c56ff1f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/no-std.rs @@ -0,0 +1,14 @@ +// edition:2018 +// check-pass + +#![no_std] +#![crate_type = "rlib"] + +use core::future::Future; + +async fn a(f: impl Future) { + f.await; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/no-unsafe-async.rs b/gcc/testsuite/rust/rustc/ui/async-await/no-unsafe-async.rs new file mode 100644 index 000000000000..e19fd05699c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/no-unsafe-async.rs @@ -0,0 +1,12 @@ +// edition:2018 + +struct S; + +impl S { + #[cfg(FALSE)] + unsafe async fn g() {} // { dg-error "" "" { target *-*-* } } +} + +#[cfg(FALSE)] +unsafe async fn f() {} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/partial-initialization-across-await.rs b/gcc/testsuite/rust/rustc/ui/async-await/partial-initialization-across-await.rs new file mode 100644 index 000000000000..1f5cfbe96d75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/partial-initialization-across-await.rs @@ -0,0 +1,43 @@ +// Test that we don't allow awaiting from an async fn while a local is partially +// initialized. + +// edition:2018 + +struct S { x: i32, y: i32 } +struct T(i32, i32); + +async fn noop() {} + +async fn test_tuple() { + let mut t: (i32, i32); + t.0 = 42; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + noop().await; + t.1 = 88; + let _ = t; +} + +async fn test_tuple_struct() { + let mut t: T; + t.0 = 42; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + noop().await; + t.1 = 88; + let _ = t; +} + +async fn test_struct() { + let mut t: S; + t.x = 42; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + noop().await; + t.y = 88; + let _ = t; +} + +fn main() { + let _ = test_tuple(); + let _ = test_tuple_struct(); + let _ = test_struct(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/recursive-async-impl-trait-type.rs b/gcc/testsuite/rust/rustc/ui/async-await/recursive-async-impl-trait-type.rs new file mode 100644 index 000000000000..15520ec92d8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/recursive-async-impl-trait-type.rs @@ -0,0 +1,10 @@ +// edition:2018 +// Test that impl trait does not allow creating recursive types that are +// otherwise forbidden when using `async` and `await`. + +async fn recursive_async_function() -> () { // { dg-error ".E0733." "" { target *-*-* } } + recursive_async_function().await; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/return-ty-raw-ptr-coercion.rs b/gcc/testsuite/rust/rustc/ui/async-await/return-ty-raw-ptr-coercion.rs new file mode 100644 index 000000000000..a9dfa4eac036 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/return-ty-raw-ptr-coercion.rs @@ -0,0 +1,26 @@ +// Check that we apply unsizing coercions based on the return type. +// +// Also serves as a regression test for #60424. +// +// edition:2018 +// check-pass + +#![allow(warnings)] + +use std::fmt::Debug; + +const TMP: u32 = 22; + +// Coerce from `&u32` to `*const u32` +fn raw_pointer_coercion() { + fn sync_example() -> *const u32 { + &TMP + } + + async fn async_example() -> *const u32 { + &TMP + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/return-ty-unsize-coercion.rs b/gcc/testsuite/rust/rustc/ui/async-await/return-ty-unsize-coercion.rs new file mode 100644 index 000000000000..0a2fb12d1742 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/return-ty-unsize-coercion.rs @@ -0,0 +1,46 @@ +// Check that we apply unsizing coercions based on the return type. +// +// Also serves as a regression test for #60424. +// +// edition:2018 +// check-pass + +#![allow(warnings)] + +use std::fmt::Debug; + +// Unsizing coercion from `Box<&'static str>` to `Box`. +fn unsize_trait_coercion() { + fn sync_example() -> Box { + Box::new("asdf") + } + + async fn async_example() -> Box { + Box::new("asdf") + } +} + +// Unsizing coercion from `Box<[u32; N]>` to `Box<[32]>`. +fn unsize_slice_coercion() { + fn sync_example() -> Box<[u32]> { + Box::new([0]) + } + + async fn async_example() -> Box<[u32]> { + Box::new([0]) + } +} + +// Unsizing coercion from `&[&str; 1]` to `&[&str]` +fn unsize_slice_str_coercion() { + fn sync_example() -> &'static [&'static str] { + &["hi"] + } + + async fn async_example() -> &'static [&'static str] { + &["hi"] + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/suggest-missing-await-closure.rs b/gcc/testsuite/rust/rustc/ui/async-await/suggest-missing-await-closure.rs new file mode 100644 index 000000000000..b30c080dbab0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/suggest-missing-await-closure.rs @@ -0,0 +1,24 @@ +// edition:2018 +// run-rustfix + +#![feature(async_closure)] + +fn take_u32(_x: u32) {} + +async fn make_u32() -> u32 { + 22 +} + +#[allow(unused)] +async fn suggest_await_in_async_closure() { + async || { + let x = make_u32(); + take_u32(x) +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/suggest-missing-await.rs b/gcc/testsuite/rust/rustc/ui/async-await/suggest-missing-await.rs new file mode 100644 index 000000000000..c102dfdf6c8b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/suggest-missing-await.rs @@ -0,0 +1,30 @@ +// edition:2018 + +fn take_u32(_x: u32) {} + +async fn make_u32() -> u32 { + 22 +} + +#[allow(unused)] +async fn suggest_await_in_async_fn() { + let x = make_u32(); + take_u32(x) +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } +} + +async fn dummy() {} + +#[allow(unused)] +async fn suggest_await_in_async_fn_return() { + dummy() +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { help ".E0308." "" { target *-*-* } .-3 } +// { suggestion ".E0308." "" { target *-*-* } .-4 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/suggest-switching-edition-on-await.rs b/gcc/testsuite/rust/rustc/ui/async-await/suggest-switching-edition-on-await.rs new file mode 100644 index 000000000000..f0e87bd61075 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/suggest-switching-edition-on-await.rs @@ -0,0 +1,46 @@ +use std::pin::Pin; +use std::future::Future; + +fn main() {} + +fn await_on_struct_missing() { + struct S; + let x = S; + x.await; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +// { dg-note ".E0609." "" { target *-*-* } .-2 } +// { dg-note ".E0609." "" { target *-*-* } .-3 } +// { help ".E0609." "" { target *-*-* } .-4 } +// { dg-note ".E0609." "" { target *-*-* } .-5 } +} + +fn await_on_struct_similar() { + struct S { + awai: u8, + } + let x = S { awai: 42 }; + x.await; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +// { help ".E0609." "" { target *-*-* } .-2 } +// { dg-note ".E0609." "" { target *-*-* } .-3 } +// { help ".E0609." "" { target *-*-* } .-4 } +// { dg-note ".E0609." "" { target *-*-* } .-5 } +} + +fn await_on_63533(x: Pin<&mut dyn Future>) { + x.await; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +// { dg-note ".E0609." "" { target *-*-* } .-2 } +// { dg-note ".E0609." "" { target *-*-* } .-3 } +// { help ".E0609." "" { target *-*-* } .-4 } +// { dg-note ".E0609." "" { target *-*-* } .-5 } +} + +fn await_on_apit(x: impl Future) { + x.await; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +// { dg-note ".E0609." "" { target *-*-* } .-2 } +// { help ".E0609." "" { target *-*-* } .-3 } +// { dg-note ".E0609." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/try-on-option-in-async.rs b/gcc/testsuite/rust/rustc/ui/async-await/try-on-option-in-async.rs new file mode 100644 index 000000000000..824e7f4d09fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/try-on-option-in-async.rs @@ -0,0 +1,29 @@ +#![feature(try_trait, async_closure)] +// edition:2018 +fn main() {} + +async fn an_async_block() -> u32 { + async { + let x: Option = None; + x?; // { dg-error ".E0277." "" { target *-*-* } } + 22 + } + .await +} + +async fn async_closure_containing_fn() -> u32 { + let async_closure = async || { + let x: Option = None; + x?; // { dg-error ".E0277." "" { target *-*-* } } + 22_u32 + }; + + async_closure().await +} + +async fn an_async_function() -> u32 { + let x: Option = None; + x?; // { dg-error ".E0277." "" { target *-*-* } } + 22 +} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/unreachable-lint-1.rs b/gcc/testsuite/rust/rustc/ui/async-await/unreachable-lint-1.rs new file mode 100644 index 000000000000..1ebbeeb6558a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/unreachable-lint-1.rs @@ -0,0 +1,13 @@ +// edition:2018 +#![deny(unreachable_code)] + +async fn foo() { + return; bar().await; +// { dg-error "" "" { target *-*-* } .-1 } +} + +async fn bar() { +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/unreachable-lint.rs b/gcc/testsuite/rust/rustc/ui/async-await/unreachable-lint.rs new file mode 100644 index 000000000000..3273c1db5b1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/unreachable-lint.rs @@ -0,0 +1,14 @@ +// check-pass +// edition:2018 +#![deny(unreachable_code)] + +async fn foo() { + endless().await; +} + +async fn endless() -> ! { + loop {} +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/unresolved_type_param.rs b/gcc/testsuite/rust/rustc/ui/async-await/unresolved_type_param.rs new file mode 100644 index 000000000000..70395c489764 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/unresolved_type_param.rs @@ -0,0 +1,24 @@ +// Provoke an unresolved type error (T). +// Error message should pinpoint the type parameter T as needing to be bound +// (rather than give a general error message) +// edition:2018 + +async fn bar() -> () {} + +async fn foo() { + bar().await; +// { dg-error ".E0698." "" { target *-*-* } .-1 } +// { dg-error ".E0698." "" { target *-*-* } .-2 } +// { dg-error ".E0698." "" { target *-*-* } .-3 } +// { dg-note ".E0698." "" { target *-*-* } .-4 } +// { dg-note ".E0698." "" { target *-*-* } .-5 } +// { dg-note ".E0698." "" { target *-*-* } .-6 } +// { dg-note ".E0698." "" { target *-*-* } .-7 } +// { dg-note ".E0698." "" { target *-*-* } .-8 } +// { dg-note ".E0698." "" { target *-*-* } .-9 } +// { dg-note ".E0698." "" { target *-*-* } .-10 } +// { dg-note ".E0698." "" { target *-*-* } .-11 } +// { dg-note ".E0698." "" { target *-*-* } .-12 } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/async-await/unused-lifetime.rs b/gcc/testsuite/rust/rustc/ui/async-await/unused-lifetime.rs new file mode 100644 index 000000000000..a138728eb3b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/async-await/unused-lifetime.rs @@ -0,0 +1,43 @@ +// edition:2018 + +// Avoid spurious warnings of unused lifetime. The below async functions +// are desugered to have an unused lifetime +// but we don't want to warn about that as there's nothing they can do about it. + +#![deny(unused_lifetimes)] +#![allow(dead_code)] + +pub async fn october(s: &str) { + println!("{}", s); +} + +pub async fn async_fn(&mut ref s: &mut[i32]) { + println!("{:?}", s); +} + +macro_rules! foo_macro { + () => { + pub async fn async_fn_in_macro(&mut ref _s: &mut[i32]) {} + }; +} + +foo_macro!(); + +pub async fn func_with_unused_lifetime<'a>(s: &'a str) { +// { dg-error "" "" { target *-*-* } .-1 } + println!("{}", s); +} + +pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + println!("{}", s); +} + +pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) { +// { dg-error "" "" { target *-*-* } .-1 } + println!("{}", s); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/atomic-access-bool.rs b/gcc/testsuite/rust/rustc/ui/atomic-access-bool.rs new file mode 100644 index 000000000000..ac326ee36d05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/atomic-access-bool.rs @@ -0,0 +1,25 @@ +// run-pass + +#![allow(stable_features)] +#![feature(atomic_access)] +use std::sync::atomic::AtomicBool; +use std::sync::atomic::Ordering::*; + +static mut ATOMIC: AtomicBool = AtomicBool::new(false); + +fn main() { + unsafe { + assert_eq!(*ATOMIC.get_mut(), false); + ATOMIC.store(true, SeqCst); + assert_eq!(*ATOMIC.get_mut(), true); + ATOMIC.fetch_or(false, SeqCst); + assert_eq!(*ATOMIC.get_mut(), true); + ATOMIC.fetch_and(false, SeqCst); + assert_eq!(*ATOMIC.get_mut(), false); + ATOMIC.fetch_nand(true, SeqCst); + assert_eq!(*ATOMIC.get_mut(), true); + ATOMIC.fetch_xor(true, SeqCst); + assert_eq!(*ATOMIC.get_mut(), false); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/atomic-alignment.rs b/gcc/testsuite/rust/rustc/ui/atomic-alignment.rs new file mode 100644 index 000000000000..43c11782d384 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/atomic-alignment.rs @@ -0,0 +1,39 @@ +// run-pass + +#![feature(cfg_target_has_atomic)] +#![feature(integer_atomics)] + +use std::mem::{align_of, size_of}; +use std::sync::atomic::*; + +fn main() { + #[cfg(target_has_atomic = "8")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "ptr")] + assert_eq!(align_of::>(), size_of::>()); + #[cfg(target_has_atomic = "8")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "8")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "16")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "16")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "32")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "32")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "64")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "64")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "128")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "128")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "ptr")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "ptr")] + assert_eq!(align_of::(), size_of::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/atomic-compare_exchange.rs b/gcc/testsuite/rust/rustc/ui/atomic-compare_exchange.rs new file mode 100644 index 000000000000..f2a8f302cb68 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/atomic-compare_exchange.rs @@ -0,0 +1,32 @@ +// run-pass + +#![allow(stable_features)] + +#![feature(extended_compare_and_swap)] +use std::sync::atomic::AtomicIsize; +use std::sync::atomic::Ordering::*; + +static ATOMIC: AtomicIsize = AtomicIsize::new(0); + +fn main() { + // Make sure codegen can emit all the intrinsics correctly + ATOMIC.compare_exchange(0, 1, Relaxed, Relaxed).ok(); + ATOMIC.compare_exchange(0, 1, Acquire, Relaxed).ok(); + ATOMIC.compare_exchange(0, 1, Release, Relaxed).ok(); + ATOMIC.compare_exchange(0, 1, AcqRel, Relaxed).ok(); + ATOMIC.compare_exchange(0, 1, SeqCst, Relaxed).ok(); + ATOMIC.compare_exchange(0, 1, Acquire, Acquire).ok(); + ATOMIC.compare_exchange(0, 1, AcqRel, Acquire).ok(); + ATOMIC.compare_exchange(0, 1, SeqCst, Acquire).ok(); + ATOMIC.compare_exchange(0, 1, SeqCst, SeqCst).ok(); + ATOMIC.compare_exchange_weak(0, 1, Relaxed, Relaxed).ok(); + ATOMIC.compare_exchange_weak(0, 1, Acquire, Relaxed).ok(); + ATOMIC.compare_exchange_weak(0, 1, Release, Relaxed).ok(); + ATOMIC.compare_exchange_weak(0, 1, AcqRel, Relaxed).ok(); + ATOMIC.compare_exchange_weak(0, 1, SeqCst, Relaxed).ok(); + ATOMIC.compare_exchange_weak(0, 1, Acquire, Acquire).ok(); + ATOMIC.compare_exchange_weak(0, 1, AcqRel, Acquire).ok(); + ATOMIC.compare_exchange_weak(0, 1, SeqCst, Acquire).ok(); + ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/atomic-from-mut-not-available.rs b/gcc/testsuite/rust/rustc/ui/atomic-from-mut-not-available.rs new file mode 100644 index 000000000000..7d691315e61a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/atomic-from-mut-not-available.rs @@ -0,0 +1,8 @@ +// only-x86 +// only-linux + +fn main() { + core::sync::atomic::AtomicU64::from_mut(&mut 0u64); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/atomic-print.rs b/gcc/testsuite/rust/rustc/ui/atomic-print.rs new file mode 100644 index 000000000000..59042d7ba53a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/atomic-print.rs @@ -0,0 +1,47 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(deprecated)] +// ignore-cloudabi no process support +// ignore-emscripten no threads support +// ignore-sgx no processes + +use std::{env, fmt, process, sync, thread}; + +struct SlowFmt(u32); +impl fmt::Debug for SlowFmt { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + thread::sleep_ms(3); + self.0.fmt(f) + } +} + +fn do_print(x: u32) { + let x = SlowFmt(x); + println!("{:?}{:?}{:?}{:?}{:?}", x, x, x, x, x); +} + +fn main(){ + if env::args().count() == 2 { + let barrier = sync::Arc::new(sync::Barrier::new(2)); + let tbarrier = barrier.clone(); + let t = thread::spawn(move || { + tbarrier.wait(); + do_print(1); + }); + barrier.wait(); + do_print(2); + t.join(); + } else { + let this = env::args().next().unwrap(); + let output = process::Command::new(this).arg("-").output().unwrap(); + for line in String::from_utf8(output.stdout).unwrap().lines() { + match line.chars().next().unwrap() { + '1' => assert_eq!(line, "11111"), + '2' => assert_eq!(line, "22222"), + chr => panic!("unexpected character {:?}", chr) + } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/attempted-access-non-fatal.rs b/gcc/testsuite/rust/rustc/ui/attempted-access-non-fatal.rs new file mode 100644 index 000000000000..091b505d754e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attempted-access-non-fatal.rs @@ -0,0 +1,7 @@ +// Check that bogus field access is non-fatal +fn main() { + let x = 0; + let _ = x.foo; // { dg-error ".E0610." "" { target *-*-* } } + let _ = x.bar; // { dg-error ".E0610." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/attr-eq-token-tree.rs b/gcc/testsuite/rust/rustc/ui/attr-eq-token-tree.rs new file mode 100644 index 000000000000..f89a5df1d4a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attr-eq-token-tree.rs @@ -0,0 +1,3 @@ +#[my_attr = !] // { dg-error "" "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attr-main-2.rs b/gcc/testsuite/rust/rustc/ui/attr-main-2.rs new file mode 100644 index 000000000000..6c82da781c46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attr-main-2.rs @@ -0,0 +1,12 @@ +// run-pass + +#![feature(main)] + +pub fn main() { + panic!() +} + +#[main] +fn foo() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/attr-main.rs b/gcc/testsuite/rust/rustc/ui/attr-main.rs new file mode 100644 index 000000000000..457deb79364e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attr-main.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(main)] + +#[main] +fn foo() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/attr-shebang.rs b/gcc/testsuite/rust/rustc/ui/attr-shebang.rs new file mode 100644 index 000000000000..e29dfbc14ce6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attr-shebang.rs @@ -0,0 +1,6 @@ +// run-pass + +#![allow(stable_features)] +#![feature(rust1)] +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/attr-start.rs b/gcc/testsuite/rust/rustc/ui/attr-start.rs new file mode 100644 index 000000000000..bb2eccf20477 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attr-start.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(start)] + +#[start] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + return 0; +} + diff --git a/gcc/testsuite/rust/rustc/ui/attr-usage-inline.rs b/gcc/testsuite/rust/rustc/ui/attr-usage-inline.rs new file mode 100644 index 000000000000..8118f2048d29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attr-usage-inline.rs @@ -0,0 +1,10 @@ +#![allow(dead_code)] + +#[inline] +fn f() {} + +#[inline] // { dg-error ".E0518." "" { target *-*-* } } +struct S; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attr-usage-repr.rs b/gcc/testsuite/rust/rustc/ui/attr-usage-repr.rs new file mode 100644 index 000000000000..ddd196621b07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attr-usage-repr.rs @@ -0,0 +1,34 @@ +#![feature(repr_simd)] + +#[repr(C)] // { dg-error ".E0517." "" { target *-*-* } } +fn f() {} + +#[repr(C)] +struct SExtern(f64, f64); + +#[repr(packed)] +struct SPacked(f64, f64); + +#[repr(simd)] +struct SSimd(f64, f64); + +#[repr(i8)] // { dg-error ".E0517." "" { target *-*-* } } +struct SInt(f64, f64); + +#[repr(C)] +enum EExtern { A, B } + +#[repr(align(8))] +enum EAlign { A, B } + +#[repr(packed)] // { dg-error ".E0517." "" { target *-*-* } } +enum EPacked { A, B } + +#[repr(simd)] // { dg-error ".E0517." "" { target *-*-* } } +enum ESimd { A, B } + +#[repr(i8)] +enum EInt { A, B } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attr.rs b/gcc/testsuite/rust/rustc/ui/attr.rs new file mode 100644 index 000000000000..457deb79364e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attr.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(main)] + +#[main] +fn foo() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/attribute-with-no-generics-in-parameter-list.rs b/gcc/testsuite/rust/rustc/ui/attribute-with-no-generics-in-parameter-list.rs new file mode 100644 index 000000000000..13a6400e9ae5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attribute-with-no-generics-in-parameter-list.rs @@ -0,0 +1,4 @@ +fn foo<#[attr]>() {} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/attr-before-view-item.rs b/gcc/testsuite/rust/rustc/ui/attributes/attr-before-view-item.rs new file mode 100644 index 000000000000..05ffe901d83e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/attr-before-view-item.rs @@ -0,0 +1,11 @@ +// build-pass (FIXME(62277): could be check-pass?) +// pretty-expanded FIXME #23616 + +#![feature(rustc_attrs)] +#![feature(test)] + +#[rustc_dummy = "bar"] +extern crate test; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/attr-before-view-item2.rs b/gcc/testsuite/rust/rustc/ui/attributes/attr-before-view-item2.rs new file mode 100644 index 000000000000..f09bed2023bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/attr-before-view-item2.rs @@ -0,0 +1,13 @@ +// build-pass (FIXME(62277): could be check-pass?) +// pretty-expanded FIXME #23616 + +#![feature(rustc_attrs)] +#![feature(test)] + +mod m { + #[rustc_dummy = "bar"] + extern crate test; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/attr-mix-new.rs b/gcc/testsuite/rust/rustc/ui/attributes/attr-mix-new.rs new file mode 100644 index 000000000000..50e883451f71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/attr-mix-new.rs @@ -0,0 +1,12 @@ +// build-pass (FIXME(62277): could be check-pass?) +// pretty-expanded FIXME #23616 + +#![feature(rustc_attrs)] + +#[rustc_dummy(bar)] +mod foo { + #![feature(globs)] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-1.rs b/gcc/testsuite/rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-1.rs new file mode 100644 index 000000000000..6923a9b8d19f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-1.rs @@ -0,0 +1,14 @@ +// This test checks variations on `<#[attr] 'a, #[oops]>`, where +// `#[oops]` is left dangling (that is, it is unattached, with no +// formal binding following it). + +#![feature(rustc_attrs)] + +struct RefIntPair<'a, 'b>(&'a u32, &'b u32); + +impl<#[rustc_dummy] 'a, 'b, #[oops]> RefIntPair<'a, 'b> { +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-2.rs b/gcc/testsuite/rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-2.rs new file mode 100644 index 000000000000..fe9fad58fdc3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-2.rs @@ -0,0 +1,13 @@ +// This test checks variations on `<#[attr] 'a, #[oops]>`, where +// `#[oops]` is left dangling (that is, it is unattached, with no +// formal binding following it). + +#![feature(rustc_attrs)] + +struct RefAny<'a, T>(&'a T); + +impl<#[rustc_dummy] 'a, #[rustc_dummy] T, #[oops]> RefAny<'a, T> {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-3.rs b/gcc/testsuite/rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-3.rs new file mode 100644 index 000000000000..bc6ea45ac435 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/attrs-with-no-formal-in-generics-3.rs @@ -0,0 +1,13 @@ +// This test checks variations on `<#[attr] 'a, #[oops]>`, where +// `#[oops]` is left dangling (that is, it is unattached, with no +// formal binding following it). + +struct RefIntPair<'a, 'b>(&'a u32, &'b u32); + +fn hof_lt(_: Q) + where Q: for <#[allow(unused)] 'a, 'b, #[oops]> Fn(RefIntPair<'a,'b>) -> &'b u32 +// { dg-error "" "" { target *-*-* } .-1 } +{} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/auxiliary/key-value-expansion.rs b/gcc/testsuite/rust/rustc/ui/attributes/auxiliary/key-value-expansion.rs new file mode 100644 index 000000000000..45cefe9eacda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/auxiliary/key-value-expansion.rs @@ -0,0 +1,13 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro_derive(EthabiContract, attributes(ethabi_contract_options))] +pub fn ethabi_derive(input: TokenStream) -> TokenStream { + Default::default() +} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/class-attributes-1.rs b/gcc/testsuite/rust/rustc/ui/attributes/class-attributes-1.rs new file mode 100644 index 000000000000..4f38b2d04861 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/class-attributes-1.rs @@ -0,0 +1,20 @@ +// build-pass (FIXME(62277): could be check-pass?) +// pp-exact - Make sure we actually print the attributes + +#![feature(rustc_attrs)] + +struct Cat { + name: String, +} + +impl Drop for Cat { + #[rustc_dummy] + fn drop(&mut self) { println!("{} landed on hir feet" , self . name); } +} + + +#[rustc_dummy] +fn cat(name: String) -> Cat { Cat{name: name,} } + +fn main() { let _kitty = cat("Spotty".to_string()); } + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/class-attributes-2.rs b/gcc/testsuite/rust/rustc/ui/attributes/class-attributes-2.rs new file mode 100644 index 000000000000..d9d6b746d0a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/class-attributes-2.rs @@ -0,0 +1,32 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(rustc_attrs)] + +struct Cat { + name: String, +} + +impl Drop for Cat { + #[rustc_dummy] + /** + Actually, cats don't always land on their feet when you drop them. + */ + fn drop(&mut self) { + println!("{} landed on hir feet", self.name); + } +} + +#[rustc_dummy] +/** +Maybe it should technically be a kitten_maker. +*/ +fn cat(name: String) -> Cat { + Cat { + name: name + } +} + +fn main() { + let _kitty = cat("Spotty".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/field-attributes-vis-unresolved.rs b/gcc/testsuite/rust/rustc/ui/attributes/field-attributes-vis-unresolved.rs new file mode 100644 index 000000000000..5ee053f21f2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/field-attributes-vis-unresolved.rs @@ -0,0 +1,26 @@ +// Non-builtin attributes do not mess with field visibility resolution (issue #67006). + +mod internal { + struct S { + #[rustfmt::skip] + pub(in crate::internal) field: u8 // OK + } + + struct Z( + #[rustfmt::skip] + pub(in crate::internal) u8 // OK + ); +} + +struct S { + #[rustfmt::skip] + pub(in nonexistent) field: u8 // { dg-error ".E0433." "" { target *-*-* } } +} + +struct Z( + #[rustfmt::skip] + pub(in nonexistent) u8 // { dg-error ".E0433." "" { target *-*-* } } +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/item-attributes.rs b/gcc/testsuite/rust/rustc/ui/attributes/item-attributes.rs new file mode 100644 index 000000000000..83ca4b21e7cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/item-attributes.rs @@ -0,0 +1,180 @@ +// These are attributes of the implicit crate. Really this just needs to parse +// for completeness since .rs files linked from .rc files support this +// notation to specify their module's attributes + +// check-pass + +#![feature(rustc_attrs)] + +#![rustc_dummy = "val"] +#![rustc_dummy = "val"] +#![rustc_dummy] +#![rustc_dummy(attr5)] + +// These are attributes of the following mod +#[rustc_dummy = "val"] +#[rustc_dummy = "val"] +mod test_first_item_in_file_mod {} + +mod test_single_attr_outer { + #[rustc_dummy = "val"] + pub static X: isize = 10; + + #[rustc_dummy = "val"] + pub fn f() { } + + #[rustc_dummy = "val"] + pub mod mod1 {} + + pub mod rustrt { + #[rustc_dummy = "val"] + extern {} + } +} + +mod test_multi_attr_outer { + #[rustc_dummy = "val"] + #[rustc_dummy = "val"] + pub static X: isize = 10; + + #[rustc_dummy = "val"] + #[rustc_dummy = "val"] + pub fn f() { } + + #[rustc_dummy = "val"] + #[rustc_dummy = "val"] + pub mod mod1 {} + + pub mod rustrt { + #[rustc_dummy = "val"] + #[rustc_dummy = "val"] + extern {} + } + + #[rustc_dummy = "val"] + #[rustc_dummy = "val"] + struct T {x: isize} +} + +mod test_stmt_single_attr_outer { + pub fn f() { + #[rustc_dummy = "val"] + static X: isize = 10; + + #[rustc_dummy = "val"] + fn f() { } + + #[rustc_dummy = "val"] + mod mod1 { + } + + mod rustrt { + #[rustc_dummy = "val"] + extern { + } + } + } +} + +mod test_stmt_multi_attr_outer { + pub fn f() { + + #[rustc_dummy = "val"] + #[rustc_dummy = "val"] + static X: isize = 10; + + #[rustc_dummy = "val"] + #[rustc_dummy = "val"] + fn f() { } + + #[rustc_dummy = "val"] + #[rustc_dummy = "val"] + mod mod1 { + } + + mod rustrt { + #[rustc_dummy = "val"] + #[rustc_dummy = "val"] + extern { + } + } + } +} + +mod test_attr_inner { + pub mod m { + // This is an attribute of mod m + #![rustc_dummy = "val"] + } +} + +mod test_attr_inner_then_outer { + pub mod m { + // This is an attribute of mod m + #![rustc_dummy = "val"] + // This is an attribute of fn f + #[rustc_dummy = "val"] + fn f() { } + } +} + +mod test_attr_inner_then_outer_multi { + pub mod m { + // This is an attribute of mod m + #![rustc_dummy = "val"] + #![rustc_dummy = "val"] + // This is an attribute of fn f + #[rustc_dummy = "val"] + #[rustc_dummy = "val"] + fn f() { } + } +} + +mod test_distinguish_syntax_ext { + pub fn f() { + format!("test{}", "s"); + #[rustc_dummy = "val"] + fn g() { } + } +} + +mod test_other_forms { + #[rustc_dummy] + #[rustc_dummy(word)] + #[rustc_dummy(attr(word))] + #[rustc_dummy(key1 = "val", key2 = "val", attr)] + pub fn f() { } +} + +mod test_foreign_items { + pub mod rustrt { + extern { + #![rustc_dummy] + + #[rustc_dummy] + fn rust_get_test_int() -> u32; + } + } +} + + +// FIXME(#623): - these aren't supported yet +/*mod test_literals { + #![str = "s"] + #![char = 'c'] + #![isize = 100] + #![usize = 100_usize] + #![mach_int = 100u32] + #![float = 1.0] + #![mach_float = 1.0f32] + #![nil = ()] + #![bool = true] + mod m {} +}*/ + +fn test_fn_inner() { + #![rustc_dummy] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/key-value-expansion.rs b/gcc/testsuite/rust/rustc/ui/attributes/key-value-expansion.rs new file mode 100644 index 000000000000..321e2fab84bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/key-value-expansion.rs @@ -0,0 +1,56 @@ +// Regression tests for issue #55414, expansion happens in the value of a key-value attribute, +// and the expanded expression is more complex than simply a macro call. + +// aux-build:key-value-expansion.rs + +#![feature(rustc_attrs)] + +extern crate key_value_expansion; + +// Minimized test case. + +macro_rules! bug { + ($expr:expr) => { + #[rustc_dummy = $expr] // Any key-value attribute, not necessarily `doc` +// { dg-error "" "" { target *-*-* } .-1 } + struct S; + }; +} + +// Any expressions containing macro call `X` that's more complex than `X` itself. +// Parentheses will work. +bug!((column!())); + +// Original test case. + +macro_rules! bug { + () => { + bug!("bug" + stringify!(found)); + }; + ($test:expr) => { + #[doc = $test] // { dg-error "" "" { target *-*-* } } + struct Test {} + }; +} + +bug!(); + +// Test case from #66804. + +macro_rules! doc_comment { + ($x:expr) => { + #[doc = $x] // { dg-error "" "" { target *-*-* } } + extern {} + }; +} + +macro_rules! some_macro { + ($t1: ty) => { + doc_comment! {format!("{coor}", coor = stringify!($t1)).as_str()} + }; +} + +some_macro!(u8); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/method-attributes.rs b/gcc/testsuite/rust/rustc/ui/attributes/method-attributes.rs new file mode 100644 index 000000000000..e88409cd91ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/method-attributes.rs @@ -0,0 +1,29 @@ +// build-pass (FIXME(62277): could be check-pass?) +// pp-exact - Make sure we print all the attributes +// pretty-expanded FIXME #23616 + +#![feature(rustc_attrs)] + +#[rustc_dummy] +trait Frobable { + #[rustc_dummy] + fn frob(&self); + #[rustc_dummy] + fn defrob(&self); +} + +#[rustc_dummy] +impl Frobable for isize { + #[rustc_dummy] + fn frob(&self) { + #![rustc_dummy] + } + + #[rustc_dummy] + fn defrob(&self) { + #![rustc_dummy] + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/multiple-invalid.rs b/gcc/testsuite/rust/rustc/ui/attributes/multiple-invalid.rs new file mode 100644 index 000000000000..4654bac613ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/multiple-invalid.rs @@ -0,0 +1,11 @@ +// This test checks that all expected errors occur when there are multiple invalid attributes +// on an item. + +#[inline] +// { dg-error ".E0518." "" { target *-*-* } .-1 } +#[target_feature(enable = "sse2")] +// { dg-error "" "" { target *-*-* } .-1 } +const FOO: u8 = 0; + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/nonterminal-expansion.rs b/gcc/testsuite/rust/rustc/ui/attributes/nonterminal-expansion.rs new file mode 100644 index 000000000000..fbcad68d61a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/nonterminal-expansion.rs @@ -0,0 +1,18 @@ +// Macros were previously expanded in `Expr` nonterminal tokens, now they are not. + +macro_rules! pass_nonterminal { + ($n:expr) => { + #[repr(align($n))] // { dg-error ".E0552." "" { target *-*-* } } +// { dg-error ".E0552." "" { target *-*-* } .-2 } + struct S; + }; +} + +macro_rules! n { + () => { 32 }; +} + +pass_nonterminal!(n!()); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/obsolete-attr.rs b/gcc/testsuite/rust/rustc/ui/attributes/obsolete-attr.rs new file mode 100644 index 000000000000..c2b2731c3be5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/obsolete-attr.rs @@ -0,0 +1,10 @@ +// Obsolete attributes fall back to unstable custom attributes. + +#[ab_isize="stdcall"] extern {} +// { dg-error "" "" { target *-*-* } .-1 } + +#[fixed_stack_segment] fn f() {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-fail.rs b/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-fail.rs new file mode 100644 index 000000000000..41ed5489cb9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-fail.rs @@ -0,0 +1,14 @@ +#![feature(register_attr)] +#![feature(register_tool)] + +#![register_attr] // { dg-error "" "" { target *-*-* } } +#![register_tool] // { dg-error "" "" { target *-*-* } } + +#![register_attr(a::b)] // { dg-error "" "" { target *-*-* } } +#![register_tool(a::b)] // { dg-error "" "" { target *-*-* } } + +#![register_attr(attr, attr)] // { dg-error "" "" { target *-*-* } } +#![register_tool(tool, tool)] // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-import.rs b/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-import.rs new file mode 100644 index 000000000000..e3ad119f8cb8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-import.rs @@ -0,0 +1,18 @@ +// edition:2018 +// compile-flags: -Zsave-analysis +// ~^ Also regression test for #69588 + +#![feature(register_attr)] +#![feature(register_tool)] + +#![register_attr(attr)] +#![register_tool(tool)] + +use attr as renamed_attr; // OK +use tool as renamed_tool; // OK + +#[renamed_attr] // { dg-error "" "" { target *-*-* } } +#[renamed_tool::attr] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-prelude.rs b/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-prelude.rs new file mode 100644 index 000000000000..e6273cd2bfc4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-prelude.rs @@ -0,0 +1,15 @@ +#![feature(register_attr)] +#![feature(register_tool)] + +#![register_attr(attr)] +#![register_tool(tool)] + +#[no_implicit_prelude] +mod m { + #[attr] // { dg-error "" "" { target *-*-* } } + #[tool::attr] // { dg-error ".E0433." "" { target *-*-* } } + fn check() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-unused.rs b/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-unused.rs new file mode 100644 index 000000000000..b83167aaceb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool-unused.rs @@ -0,0 +1,11 @@ +#![deny(unused)] + +#![feature(register_attr)] +#![feature(register_tool)] + +#[register_attr(attr)] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[register_tool(tool)] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool.rs b/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool.rs new file mode 100644 index 000000000000..d3af83891064 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/register-attr-tool.rs @@ -0,0 +1,20 @@ +// check-pass +// compile-flags: --cfg foo + +#![feature(register_attr)] +#![feature(register_tool)] + +#![register_attr(attr)] +#![register_tool(tool)] +#![register_tool(rustfmt, clippy)] // OK +#![cfg_attr(foo, register_attr(conditional_attr))] +#![cfg_attr(foo, register_tool(conditional_tool))] + +#[attr] +#[tool::attr] +#[rustfmt::attr] +#[clippy::attr] +#[conditional_attr] +#[conditional_tool::attr] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/unknown-attr.rs b/gcc/testsuite/rust/rustc/ui/attributes/unknown-attr.rs new file mode 100644 index 000000000000..c8836bab28fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/unknown-attr.rs @@ -0,0 +1,13 @@ +// Unknown attributes fall back to unstable custom attributes. + +#![feature(custom_inner_attributes)] + +#![mutable_doc] +// { dg-error "" "" { target *-*-* } .-1 } + +#[dance] mod a {} +// { dg-error "" "" { target *-*-* } .-1 } + +#[dance] fn main() {} +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/unnamed-field-attributes-dup.rs b/gcc/testsuite/rust/rustc/ui/attributes/unnamed-field-attributes-dup.rs new file mode 100644 index 000000000000..6e764d730c5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/unnamed-field-attributes-dup.rs @@ -0,0 +1,12 @@ +// Duplicate non-builtin attributes can be used on unnamed fields. + +// check-pass + +struct S ( + #[rustfmt::skip] + #[rustfmt::skip] + u8 +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/unnamed-field-attributes-vis.rs b/gcc/testsuite/rust/rustc/ui/attributes/unnamed-field-attributes-vis.rs new file mode 100644 index 000000000000..eb003b2f71a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/unnamed-field-attributes-vis.rs @@ -0,0 +1,12 @@ +// Unnamed fields don't lose their visibility due to non-builtin attributes on them. + +// check-pass + +mod m { + pub struct S(#[rustfmt::skip] pub u8); +} + +fn main() { + m::S(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/unnamed-field-attributes.rs b/gcc/testsuite/rust/rustc/ui/attributes/unnamed-field-attributes.rs new file mode 100644 index 000000000000..e01e10afa52d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/unnamed-field-attributes.rs @@ -0,0 +1,10 @@ +// check-pass + +struct S( + #[rustfmt::skip] u8, + u16, + #[rustfmt::skip] u32, +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/attributes/variant-attributes.rs b/gcc/testsuite/rust/rustc/ui/attributes/variant-attributes.rs new file mode 100644 index 000000000000..dcb4b170556a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attributes/variant-attributes.rs @@ -0,0 +1,38 @@ +// build-pass (FIXME(62277): could be check-pass?) +// pp-exact - Make sure we actually print the attributes +// pretty-expanded FIXME #23616 + +#![allow(non_camel_case_types)] +#![feature(rustc_attrs)] + +enum crew_of_enterprise_d { + + #[rustc_dummy] + jean_luc_picard, + + #[rustc_dummy] + william_t_riker, + + #[rustc_dummy] + beverly_crusher, + + #[rustc_dummy] + deanna_troi, + + #[rustc_dummy] + data, + + #[rustc_dummy] + worf, + + #[rustc_dummy] + geordi_la_forge, +} + +fn boldly_go(_crew_member: crew_of_enterprise_d, _where: String) { } + +fn main() { + boldly_go(crew_of_enterprise_d::worf, + "where no one has gone before".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/attrs-resolution-errors.rs b/gcc/testsuite/rust/rustc/ui/attrs-resolution-errors.rs new file mode 100644 index 000000000000..07375840fff0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attrs-resolution-errors.rs @@ -0,0 +1,41 @@ +enum FooEnum { + #[test] +// { dg-error "" "" { target *-*-* } .-1 } + Bar(i32), +} + +struct FooStruct { + #[test] +// { dg-error "" "" { target *-*-* } .-1 } + bar: i32, +} + +fn main() { + let foo_enum_bar = FooEnum::Bar(1); + match foo_enum_bar { + FooEnum::Bar(x) => {}, + _ => {} + } + + let foo_struct = FooStruct { bar: 1 }; + match foo_struct { + FooStruct { + #[test] bar +// { dg-error "" "" { target *-*-* } .-1 } + } => {} + } + + match 1 { + 0 => {} + #[test] +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} + } + + let _another_foo_strunct = FooStruct { + #[test] +// { dg-error "" "" { target *-*-* } .-1 } + bar: 1, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/attrs-resolution.rs b/gcc/testsuite/rust/rustc/ui/attrs-resolution.rs new file mode 100644 index 000000000000..d75076d3bf3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/attrs-resolution.rs @@ -0,0 +1,38 @@ +// check-pass + +enum FooEnum { + #[rustfmt::skip] + Bar(i32), +} + +struct FooStruct { + #[rustfmt::skip] + bar: i32, +} + +fn main() { + let foo_enum_bar = FooEnum::Bar(1); + match foo_enum_bar { + FooEnum::Bar(x) => {} + _ => {} + } + + let foo_struct = FooStruct { bar: 1 }; + match foo_struct { + FooStruct { + #[rustfmt::skip] bar + } => {} + } + + match 1 { + 0 => {} + #[rustfmt::skip] + _ => {} + } + + let _another_foo_strunct = FooStruct { + #[rustfmt::skip] + bar: 1, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/augmented-assignments-feature-gate-cross.rs b/gcc/testsuite/rust/rustc/ui/augmented-assignments-feature-gate-cross.rs new file mode 100644 index 000000000000..1bbac91d5405 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/augmented-assignments-feature-gate-cross.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:augmented_assignments.rs + +extern crate augmented_assignments; + +use augmented_assignments::Int; + +fn main() { + let mut x = Int(0); + x += 1; +} + diff --git a/gcc/testsuite/rust/rustc/ui/augmented-assignments-feature-gate.rs b/gcc/testsuite/rust/rustc/ui/augmented-assignments-feature-gate.rs new file mode 100644 index 000000000000..427a6c8acff4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/augmented-assignments-feature-gate.rs @@ -0,0 +1,16 @@ +// run-pass + +use std::ops::AddAssign; + +struct Int(i32); + +impl AddAssign for Int { + fn add_assign(&mut self, _: i32) { + } +} + +fn main() { + let mut x = Int(0); + x += 1; +} + diff --git a/gcc/testsuite/rust/rustc/ui/augmented-assignments-rpass.rs b/gcc/testsuite/rust/rustc/ui/augmented-assignments-rpass.rs new file mode 100644 index 000000000000..09dfcf1eb34f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/augmented-assignments-rpass.rs @@ -0,0 +1,173 @@ +// run-pass + +#![allow(unused_imports)] +#![deny(unused_assignments)] + +use std::mem; +use std::ops::{ + AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, DivAssign, Index, MulAssign, RemAssign, + ShlAssign, ShrAssign, SubAssign, +}; + +#[derive(Debug, PartialEq)] +struct Int(i32); + +struct Slice([i32]); + +impl Slice { + fn new(slice: &mut [i32]) -> &mut Slice { + unsafe { + mem::transmute(slice) + } + } +} + +struct View<'a>(&'a mut [i32]); + +fn main() { + let mut x = Int(1); + + x += Int(2); + assert_eq!(x, Int(0b11)); + + x &= Int(0b01); + assert_eq!(x, Int(0b01)); + + x |= Int(0b10); + assert_eq!(x, Int(0b11)); + + x ^= Int(0b01); + assert_eq!(x, Int(0b10)); + + x /= Int(2); + assert_eq!(x, Int(1)); + + x *= Int(3); + assert_eq!(x, Int(3)); + + x %= Int(2); + assert_eq!(x, Int(1)); + + // overloaded RHS + x <<= 1u8; + assert_eq!(x, Int(2)); + + x <<= 1u16; + assert_eq!(x, Int(4)); + + x >>= 1u8; + assert_eq!(x, Int(2)); + + x >>= 1u16; + assert_eq!(x, Int(1)); + + x -= Int(1); + assert_eq!(x, Int(0)); + + // indexed LHS + let mut v = vec![Int(1), Int(2)]; + v[0] += Int(2); + assert_eq!(v[0], Int(3)); + + // unsized RHS + let mut array = [0, 1, 2]; + *Slice::new(&mut array) += 1; + assert_eq!(array[0], 1); + assert_eq!(array[1], 2); + assert_eq!(array[2], 3); + + // sized indirection + // check that this does *not* trigger the unused_assignments lint + let mut array = [0, 1, 2]; + let mut view = View(&mut array); + view += 1; +} + +impl AddAssign for Int { + fn add_assign(&mut self, rhs: Int) { + self.0 += rhs.0; + } +} + +impl BitAndAssign for Int { + fn bitand_assign(&mut self, rhs: Int) { + self.0 &= rhs.0; + } +} + +impl BitOrAssign for Int { + fn bitor_assign(&mut self, rhs: Int) { + self.0 |= rhs.0; + } +} + +impl BitXorAssign for Int { + fn bitxor_assign(&mut self, rhs: Int) { + self.0 ^= rhs.0; + } +} + +impl DivAssign for Int { + fn div_assign(&mut self, rhs: Int) { + self.0 /= rhs.0; + } +} + +impl MulAssign for Int { + fn mul_assign(&mut self, rhs: Int) { + self.0 *= rhs.0; + } +} + +impl RemAssign for Int { + fn rem_assign(&mut self, rhs: Int) { + self.0 %= rhs.0; + } +} + +impl ShlAssign for Int { + fn shl_assign(&mut self, rhs: u8) { + self.0 <<= rhs; + } +} + +impl ShlAssign for Int { + fn shl_assign(&mut self, rhs: u16) { + self.0 <<= rhs; + } +} + +impl ShrAssign for Int { + fn shr_assign(&mut self, rhs: u8) { + self.0 >>= rhs; + } +} + +impl ShrAssign for Int { + fn shr_assign(&mut self, rhs: u16) { + self.0 >>= rhs; + } +} + +impl SubAssign for Int { + fn sub_assign(&mut self, rhs: Int) { + self.0 -= rhs.0; + } +} + +impl AddAssign for Slice { + fn add_assign(&mut self, rhs: i32) { + for lhs in &mut self.0 { + *lhs += rhs; + } + } +} + +impl<'a> AddAssign for View<'a> { + fn add_assign(&mut self, rhs: i32) { + for lhs in self.0.iter_mut() { + *lhs += rhs; + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/augmented-assignments.rs b/gcc/testsuite/rust/rustc/ui/augmented-assignments.rs new file mode 100644 index 000000000000..5b817dd252d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/augmented-assignments.rs @@ -0,0 +1,28 @@ +use std::ops::AddAssign; + +struct Int(i32); + +impl AddAssign for Int { + fn add_assign(&mut self, _: Int) { + unimplemented!() + } +} + +fn main() { + let mut x = Int(1); + x +// { dg-note "" "" { target *-*-* } .-1 } + += + x; +// { dg-error ".E0505." "" { target *-*-* } .-1 } +// { dg-error ".E0505." "" { target *-*-* } .-2 } + + let y = Int(2); +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + y // { dg-error ".E0596." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + += + Int(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-instantiate.rs b/gcc/testsuite/rust/rustc/ui/auto-instantiate.rs new file mode 100644 index 000000000000..475c8ff148f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-instantiate.rs @@ -0,0 +1,14 @@ +// run-pass + +#![allow(dead_code)] +#[derive(Debug)] +struct Pair { a: T, b: U } +struct Triple { x: isize, y: isize, z: isize } + +fn f(x: T, y: U) -> Pair { return Pair {a: x, b: y}; } + +pub fn main() { + println!("{}", f(Triple {x: 3, y: 4, z: 5}, 4).a.x); + println!("{}", f(5, 6).a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-ref-slice-plus-ref.rs b/gcc/testsuite/rust/rustc/ui/auto-ref-slice-plus-ref.rs new file mode 100644 index 000000000000..64dd8a53eb19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-ref-slice-plus-ref.rs @@ -0,0 +1,28 @@ +fn main() { + + // Testing that method lookup does not automatically borrow + // vectors to slices then automatically create a self reference. + + let mut a = vec![0]; + a.test_mut(); // { dg-error ".E0599." "" { target *-*-* } } + a.test(); // { dg-error ".E0599." "" { target *-*-* } } + + ([1]).test(); // { dg-error ".E0599." "" { target *-*-* } } + (&[1]).test(); // { dg-error ".E0599." "" { target *-*-* } } +} + +trait MyIter { + fn test_mut(&mut self); + fn test(&self); +} + +impl<'a> MyIter for &'a [isize] { + fn test_mut(&mut self) { } + fn test(&self) { } +} + +impl<'a> MyIter for &'a str { + fn test_mut(&mut self) { } + fn test(&self) { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-traits/auto-is-contextual.rs b/gcc/testsuite/rust/rustc/ui/auto-traits/auto-is-contextual.rs new file mode 100644 index 000000000000..deaf55794885 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-traits/auto-is-contextual.rs @@ -0,0 +1,19 @@ +// run-pass + +#![allow(path_statements)] +#![allow(dead_code)] +macro_rules! auto { + () => (struct S;) +} + +auto!(); + +fn auto() {} + +fn main() { + auto(); + let auto = 10; + auto; + auto as u8; +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-traits/auto-trait-projection-recursion.rs b/gcc/testsuite/rust/rustc/ui/auto-traits/auto-trait-projection-recursion.rs new file mode 100644 index 000000000000..2b0fc0646e79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-traits/auto-trait-projection-recursion.rs @@ -0,0 +1,35 @@ +// Checking the `Send` bound in `main` requires: +// +// checking as Y>::P: Send +// which normalizes to Box>>: Send +// which needs X>: Send +// which needs as Y>::P: Send +// +// At this point we used to normalize the predicate to `Box>>: Send` +// and continue in a loop where we created new region variables to the +// recursion limit. To avoid this we now "canonicalize" region variables to +// lowest unified region vid. This means we instead have to prove +// `Box>>: Send`, which we can because auto traits are coinductive. + +// check-pass + +// Avoid a really long error message if this regresses. +#![recursion_limit="20"] + +trait Y { + type P; +} + +impl<'a> Y for C<'a> { + type P = Box>>; +} + +struct C<'a>(&'a ()); +struct X(T::P); + +fn is_send() {} + +fn main() { + is_send::>>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-traits/auto-trait-validation.rs b/gcc/testsuite/rust/rustc/ui/auto-traits/auto-trait-validation.rs new file mode 100644 index 000000000000..5dcc8ed471b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-traits/auto-trait-validation.rs @@ -0,0 +1,10 @@ +#![feature(optin_builtin_traits)] + +auto trait Generic {} +// { dg-error ".E0567." "" { target *-*-* } .-1 } +auto trait Bound : Copy {} +// { dg-error ".E0568." "" { target *-*-* } .-1 } +auto trait MyTrait { fn foo() {} } +// { dg-error ".E0380." "" { target *-*-* } .-1 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-traits/auto-traits.rs b/gcc/testsuite/rust/rustc/ui/auto-traits/auto-traits.rs new file mode 100644 index 000000000000..ee8ee8c07a83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-traits/auto-traits.rs @@ -0,0 +1,33 @@ +// run-pass +#![allow(unused_doc_comments)] +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +auto trait Auto {} +unsafe auto trait AutoUnsafe {} + +impl !Auto for bool {} +impl !AutoUnsafe for bool {} + +struct AutoBool(bool); + +impl Auto for AutoBool {} +unsafe impl AutoUnsafe for AutoBool {} + +fn take_auto(_: T) {} +fn take_auto_unsafe(_: T) {} + +fn main() { + // Parse inside functions. + auto trait AutoInner {} + unsafe auto trait AutoUnsafeInner {} + + take_auto(0); + take_auto(AutoBool(true)); + take_auto_unsafe(0); + take_auto_unsafe(AutoBool(true)); + + /// Auto traits are allowed in trait object bounds. + let _: &(dyn Send + Auto) = &0; +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-traits/issue-23080-2.rs b/gcc/testsuite/rust/rustc/ui/auto-traits/issue-23080-2.rs new file mode 100644 index 000000000000..1c254c8c6ec4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-traits/issue-23080-2.rs @@ -0,0 +1,14 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +unsafe auto trait Trait { + type Output; // { dg-error ".E0380." "" { target *-*-* } } +} + +fn call_method(x: T) {} + +fn main() { + // ICE + call_method(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-traits/issue-23080.rs b/gcc/testsuite/rust/rustc/ui/auto-traits/issue-23080.rs new file mode 100644 index 000000000000..48d3e3ec7635 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-traits/issue-23080.rs @@ -0,0 +1,18 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +unsafe auto trait Trait { + fn method(&self) { // { dg-error ".E0380." "" { target *-*-* } } + println!("Hello"); + } +} + +fn call_method(x: T) { + x.method(); +} + +fn main() { + // ICE + call_method(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs b/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs new file mode 100644 index 000000000000..bc80731c17b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs @@ -0,0 +1,16 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +auto trait Magic : Sized where Option : Magic {} // { dg-error ".E0568." "" { target *-*-* } } +impl Magic for T {} + +fn copy(x: T) -> (T, T) { (x, x) } + +#[derive(Debug)] +struct NoClone; + +fn main() { + let (a, b) = copy(NoClone); + println!("{:?} {:?}", a, b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-auto-trait-no-supertraits.rs b/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-auto-trait-no-supertraits.rs new file mode 100644 index 000000000000..520bc7e9e752 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-auto-trait-no-supertraits.rs @@ -0,0 +1,40 @@ +// This test is for #29859, we need to ensure auto traits, +// (also known previously as default traits), do not have +// supertraits. Since the compiler synthesizes these +// instances on demand, we are essentially enabling +// users to write axioms if we view trait selection, +// as a proof system. +// +// For example the below test allows us to add the rule: +// forall (T : Type), T : Copy +// +// Providing a copy instance for *any* type, which +// is most definitely unsound. Imagine copying a +// type that contains a mutable reference, enabling +// mutable aliasing. +// +// You can imagine an even more dangerous test, +// which currently compiles on nightly. +// +// fn main() { +// let mut i = 10; +// let (a, b) = copy(&mut i); +// println!("{:?} {:?}", a, b); +// } + +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +auto trait Magic: Copy {} // { dg-error ".E0568." "" { target *-*-* } } +impl Magic for T {} + +fn copy(x: T) -> (T, T) { (x, x) } + +#[derive(Debug)] +struct NoClone; + +fn main() { + let (a, b) = copy(NoClone); + println!("{:?} {:?}", a, b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.rs b/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.rs new file mode 100644 index 000000000000..41f89a98ebd7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-constituent-types-2.rs @@ -0,0 +1,20 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +auto trait MyTrait {} + +struct MyS; + +struct MyS2; + +impl !MyTrait for MyS2 {} + +fn is_mytrait() {} + +fn main() { + is_mytrait::(); + + is_mytrait::<(MyS2, MyS)>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-constituent-types.rs b/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-constituent-types.rs new file mode 100644 index 000000000000..4826a0ea2c1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-constituent-types.rs @@ -0,0 +1,24 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +auto trait MyTrait {} + +impl !MyTrait for *mut T {} + +struct MyS; + +struct MyS2; + +impl !MyTrait for MyS2 {} + +struct MyS3; + +fn is_mytrait() {} + +fn main() { + is_mytrait::(); + + is_mytrait::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-negation.rs b/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-negation.rs new file mode 100644 index 000000000000..0a11e81231d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-negation.rs @@ -0,0 +1,30 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +auto trait MyTrait {} + +unsafe auto trait MyUnsafeTrait {} + +struct ThisImplsTrait; + +impl !MyUnsafeTrait for ThisImplsTrait {} + + +struct ThisImplsUnsafeTrait; + +impl !MyTrait for ThisImplsUnsafeTrait {} + +fn is_my_trait() {} +fn is_my_unsafe_trait() {} + +fn main() { + is_my_trait::(); + is_my_trait::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + is_my_unsafe_trait::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + is_my_unsafe_trait::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-precedence.rs b/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-precedence.rs new file mode 100644 index 000000000000..5250d61936b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auto-traits/typeck-default-trait-impl-precedence.rs @@ -0,0 +1,22 @@ +// Test that declaring that `&T` is `Defaulted` if `T:Signed` implies +// that other `&T` is NOT `Defaulted` if `T:Signed` does not hold. In +// other words, the auto impl only applies if there are no existing +// impls whose types unify. + +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +auto trait Defaulted { } +impl<'a,T:Signed> Defaulted for &'a T { } +impl<'a,T:Signed> Defaulted for &'a mut T { } +fn is_defaulted() { } + +trait Signed { } +impl Signed for i32 { } + +fn main() { + is_defaulted::<&'static i32>(); + is_defaulted::<&'static u32>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/autobind.rs b/gcc/testsuite/rust/rustc/ui/autobind.rs new file mode 100644 index 000000000000..eaf1ae1a28f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autobind.rs @@ -0,0 +1,13 @@ +// run-pass + +fn f(x: Vec) -> T { return x.into_iter().next().unwrap(); } + +fn g(act: F) -> isize where F: FnOnce(Vec) -> isize { return act(vec![1, 2, 3]); } + +pub fn main() { + assert_eq!(g(f), 1); + let f1 = f; + assert_eq!(f1(vec!["x".to_string(), "y".to_string(), "z".to_string()]), + "x".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/autoderef-full-lval.rs b/gcc/testsuite/rust/rustc/ui/autoderef-full-lval.rs new file mode 100644 index 000000000000..9c3c9df6a9f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autoderef-full-lval.rs @@ -0,0 +1,26 @@ +#![feature(box_syntax)] + +struct Clam { + x: Box, + y: Box, +} + +struct Fish { + a: Box, +} + +fn main() { + let a: Clam = Clam{x: box 1, y: box 2}; + let b: Clam = Clam{x: box 10, y: box 20}; + let z: isize = a.x + b.y; +// { dg-error ".E0369." "" { target *-*-* } .-1 } + println!("{}", z); + assert_eq!(z, 21); + let forty: Fish = Fish{a: box 40}; + let two: Fish = Fish{a: box 2}; + let answer: isize = forty.a + two.a; +// { dg-error ".E0369." "" { target *-*-* } .-1 } + println!("{}", answer); + assert_eq!(answer, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs new file mode 100644 index 000000000000..97da62dc6636 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/auto-ref-bounded-ty-param.rs @@ -0,0 +1,30 @@ +// run-pass +trait Foo { + fn f(&self); +} + +struct Bar { + x: isize +} + +trait Baz { + fn g(&self); +} + +impl Foo for T { + fn f(&self) { + self.g(); + } +} + +impl Baz for Bar { + fn g(&self) { + println!("{}", self.x); + } +} + +pub fn main() { + let y = Bar { x: 42 }; + y.f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/autoref-autoderef/auto-ref-sliceable.rs b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/auto-ref-sliceable.rs new file mode 100644 index 000000000000..8b5ed424fec3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/auto-ref-sliceable.rs @@ -0,0 +1,20 @@ +// run-pass + + +trait Pushable { + fn push_val(&mut self, t: T); +} + +impl Pushable for Vec { + fn push_val(&mut self, t: T) { + self.push(t); + } +} + +pub fn main() { + let mut v = vec![1]; + v.push_val(2); + v.push_val(3); + assert_eq!(v, [1, 2, 3]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/autoref-autoderef/auto-ref.rs b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/auto-ref.rs new file mode 100644 index 000000000000..899d5697d146 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/auto-ref.rs @@ -0,0 +1,20 @@ +// run-pass +struct Foo { + x: isize, +} + +trait Stuff { + fn printme(&self); +} + +impl Stuff for Foo { + fn printme(&self) { + println!("{}", self.x); + } +} + +pub fn main() { + let x = Foo { x: 3 }; + x.printme(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs new file mode 100644 index 000000000000..548bb38f2b68 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-and-borrow-method-receiver.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct Foo { + x: isize, +} + +impl Foo { + pub fn f(&self) {} +} + +fn g(x: &mut Foo) { + x.f(); +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-on-trait.rs b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-on-trait.rs new file mode 100644 index 000000000000..aef71ad8c6c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-on-trait.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(non_camel_case_types)] +#![feature(box_syntax)] + +trait double { + fn double(self: Box) -> usize; +} + +impl double for usize { + fn double(self: Box) -> usize { *self * 2 } +} + +pub fn main() { + let x: Box<_> = box (box 3usize as Box); + assert_eq!(x.double(), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-priority.rs b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-priority.rs new file mode 100644 index 000000000000..d9da87d15ee9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-priority.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(non_camel_case_types)] +#![feature(box_syntax)] + +trait double { + fn double(self) -> usize; +} + +impl double for usize { + fn double(self) -> usize { self } +} + +impl double for Box { + fn double(self) -> usize { *self * 2 } +} + +pub fn main() { + let x: Box<_> = box 3; + assert_eq!(x.double(), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs new file mode 100644 index 000000000000..19561ae4f998 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-twice-but-not-thrice.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(non_camel_case_types)] +#![feature(box_syntax)] + +trait double { + fn double(self: Box) -> usize; +} + +impl double for Box { + fn double(self: Box>) -> usize { **self * 2 } +} + +pub fn main() { + let x: Box>>>> = box box box box box 3; + assert_eq!(x.double(), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-twice.rs b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-twice.rs new file mode 100644 index 000000000000..bad5861d52a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method-twice.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(non_camel_case_types)] +#![feature(box_syntax)] + +trait double { + fn double(self: Box) -> usize; +} + +impl double for usize { + fn double(self: Box) -> usize { *self * 2 } +} + +pub fn main() { + let x: Box> = box box 3; + assert_eq!(x.double(), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method.rs b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method.rs new file mode 100644 index 000000000000..a9b83a847c98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-method.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(non_camel_case_types)] +#![feature(box_syntax)] + +trait double { + fn double(self: Box) -> usize; +} + +impl double for usize { + fn double(self: Box) -> usize { *self * 2 } +} + +pub fn main() { + let x: Box<_> = box 3; + assert_eq!(x.double(), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-privacy.rs b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-privacy.rs new file mode 100644 index 000000000000..5ed4732ca2d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoderef-privacy.rs @@ -0,0 +1,52 @@ +// run-pass +// Check we do not select a private method or field when computing autoderefs + +#![allow(unused)] + +#[derive(Default)] +pub struct Bar2 { i: i32 } +#[derive(Default)] +pub struct Baz2(i32); + +impl Bar2 { + fn f(&self) -> bool { true } +} + +mod foo { + #[derive(Default)] + pub struct Bar { i: ::Bar2 } + #[derive(Default)] + pub struct Baz(::Baz2); + + impl Bar { + fn f(&self) -> bool { false } + } + + impl ::std::ops::Deref for Bar { + type Target = ::Bar2; + fn deref(&self) -> &::Bar2 { &self.i } + } + + impl ::std::ops::Deref for Baz { + type Target = ::Baz2; + fn deref(&self) -> &::Baz2 { &self.0 } + } + + pub fn f(bar: &Bar, baz: &Baz) { + // Since the private fields and methods are visible here, there should be no autoderefs. + let _: &::Bar2 = &bar.i; + let _: &::Baz2 = &baz.0; + assert!(!bar.f()); + } +} + +fn main() { + let bar = foo::Bar::default(); + let baz = foo::Baz::default(); + foo::f(&bar, &baz); + + let _: i32 = bar.i; + let _: i32 = baz.0; + assert!(bar.f()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs new file mode 100644 index 000000000000..a6d913ecadd5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/autoref-autoderef/autoref-intermediate-types-issue-3585.rs @@ -0,0 +1,24 @@ +// run-pass +#![feature(box_syntax)] + +trait Foo { + fn foo(&self) -> String; +} + +impl Foo for Box { + fn foo(&self) -> String { + format!("box {}", (**self).foo()) + } +} + +impl Foo for usize { + fn foo(&self) -> String { + format!("{}", *self) + } +} + +pub fn main() { + let x: Box<_> = box 3; + assert_eq!(x.foo(), "box 3".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/augmented_assignments.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/augmented_assignments.rs new file mode 100644 index 000000000000..58d486fe25df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/augmented_assignments.rs @@ -0,0 +1,9 @@ +use std::ops::AddAssign; + +pub struct Int(pub i32); + +impl AddAssign for Int { + fn add_assign(&mut self, _: i32) { + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/blind-item-mixed-crate-use-item-foo.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/blind-item-mixed-crate-use-item-foo.rs new file mode 100644 index 000000000000..62797e4c326f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/blind-item-mixed-crate-use-item-foo.rs @@ -0,0 +1,4 @@ +#![crate_type="lib"] + +pub const X: () = (); + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/blind-item-mixed-crate-use-item-foo2.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/blind-item-mixed-crate-use-item-foo2.rs new file mode 100644 index 000000000000..f9fa6e6defc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/blind-item-mixed-crate-use-item-foo2.rs @@ -0,0 +1,4 @@ +#![crate_type="lib"] + +pub const Y: () = (); + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/changing-crates-a1.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/changing-crates-a1.rs new file mode 100644 index 000000000000..e28ad2401d21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/changing-crates-a1.rs @@ -0,0 +1,4 @@ +#![crate_name = "a"] + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/changing-crates-a2.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/changing-crates-a2.rs new file mode 100644 index 000000000000..0e145b6a6333 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/changing-crates-a2.rs @@ -0,0 +1,4 @@ +#![crate_name = "a"] + +pub fn foo() { println!("hello!"); } + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/changing-crates-b.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/changing-crates-b.rs new file mode 100644 index 000000000000..c53dddf85dc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/changing-crates-b.rs @@ -0,0 +1,6 @@ +#![crate_name = "b"] + +extern crate a; + +pub fn foo() { a::foo::(); } + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/check_static_recursion_foreign_helper.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/check_static_recursion_foreign_helper.rs new file mode 100644 index 000000000000..f1adf7c2297e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/check_static_recursion_foreign_helper.rs @@ -0,0 +1,12 @@ +// Helper definition for test/run-pass/check-static-recursion-foreign.rs. + +#![feature(rustc_private)] + +#![crate_name = "check_static_recursion_foreign_helper"] +#![crate_type = "lib"] + +extern crate libc; + +#[no_mangle] +pub static test_static: libc::c_int = 0; + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/cond_plugin.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/cond_plugin.rs new file mode 100644 index 000000000000..523f67b22398 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/cond_plugin.rs @@ -0,0 +1,39 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_quote)] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro] +pub fn cond(input: TokenStream) -> TokenStream { + let mut conds = Vec::new(); + let mut input = input.into_iter().peekable(); + while let Some(tree) = input.next() { + let cond = match tree { + TokenTree::Group(tt) => tt.stream(), + _ => panic!("Invalid input"), + }; + let mut cond_trees = cond.clone().into_iter(); + let test = cond_trees.next().expect("Unexpected empty condition in `cond!`"); + let rhs = cond_trees.collect::(); + if rhs.is_empty() { + panic!("Invalid macro usage in cond: {}", cond); + } + let is_else = match test { + TokenTree::Ident(ref word) => &*word.to_string() == "else", + _ => false, + }; + conds.push(if is_else || input.peek().is_none() { + quote!({ $rhs }) + } else { + quote!(if $test { $rhs } else) + }); + } + + conds.into_iter().flat_map(|x| x.into_iter()).collect() +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs new file mode 100644 index 000000000000..c391ac87fe20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/crate-method-reexport-grrrrrrr2.rs @@ -0,0 +1,32 @@ +#![crate_name="crate_method_reexport_grrrrrrr2"] + +pub use name_pool::add; + +pub mod name_pool { + pub type name_pool = (); + + pub trait add { + fn add(&self, s: String); + } + + impl add for name_pool { + fn add(&self, _s: String) { + } + } +} + +pub mod rust { + pub use name_pool::add; + + pub type rt = Box<()>; + + pub trait cx { + fn cx(&self); + } + + impl cx for rt { + fn cx(&self) { + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/debuginfo-lto-aux.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/debuginfo-lto-aux.rs new file mode 100644 index 000000000000..4923124ec763 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/debuginfo-lto-aux.rs @@ -0,0 +1,30 @@ +// compile-flags: -g --crate-type=rlib + +pub struct StructWithLifetime<'a>(&'a i32); +pub fn mk_struct_with_lt<'a>(x: &'a i32) -> StructWithLifetime<'a> { + StructWithLifetime(x) +} + +pub struct RegularStruct(u32); +pub fn mk_regular_struct(x: u32) -> RegularStruct { + RegularStruct(x) +} + +pub fn take_fn(f: fn(i32) -> i32, x: i32) -> i32 { + f(x) +} + +pub fn with_closure(x: i32) -> i32 { + let closure = |i| { x + i }; + + closure(1) + closure(2) +} + +pub fn generic_fn(x: T) -> (T, u32) { + (x, 1) +} + +pub fn user_of_generic_fn(x: f32) -> (f32, u32) { + generic_fn(x) +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/default-ty-param-cross-crate-crate.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/default-ty-param-cross-crate-crate.rs new file mode 100644 index 000000000000..612f99dbcf88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/default-ty-param-cross-crate-crate.rs @@ -0,0 +1,10 @@ +#![crate_type = "lib"] +#![crate_name = "default_param_test"] +#![feature(default_type_parameter_fallback)] + +use std::marker::PhantomData; + +pub struct Foo(PhantomData<(A, B)>); + +pub fn bleh() -> Foo { Foo(PhantomData) } + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/define-macro.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/define-macro.rs new file mode 100644 index 000000000000..f71748f63040 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/define-macro.rs @@ -0,0 +1,7 @@ +#[macro_export] +macro_rules! define_macro { + ($i:ident) => { + macro_rules! $i { () => {} } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/edition-kw-macro-2015.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/edition-kw-macro-2015.rs new file mode 100644 index 000000000000..27aaed61c7b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/edition-kw-macro-2015.rs @@ -0,0 +1,27 @@ +// edition:2015 + +#[macro_export] +macro_rules! produces_async { + () => (pub fn async() {}) +} + +#[macro_export] +macro_rules! produces_async_raw { + () => (pub fn r#async() {}) +} + +#[macro_export] +macro_rules! consumes_async { + (async) => (1) +} + +#[macro_export] +macro_rules! consumes_async_raw { + (r#async) => (1) +} + +#[macro_export] +macro_rules! passes_ident { + ($i: ident) => ($i) +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/edition-kw-macro-2018.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/edition-kw-macro-2018.rs new file mode 100644 index 000000000000..b3624f66e243 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/edition-kw-macro-2018.rs @@ -0,0 +1,27 @@ +// edition:2018 + +#[macro_export] +macro_rules! produces_async { + () => (pub fn async() {}) +} + +#[macro_export] +macro_rules! produces_async_raw { + () => (pub fn r#async() {}) +} + +#[macro_export] +macro_rules! consumes_async { + (async) => (1) +} + +#[macro_export] +macro_rules! consumes_async_raw { + (r#async) => (1) +} + +#[macro_export] +macro_rules! passes_ident { + ($i: ident) => ($i) +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/empty-struct.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/empty-struct.rs new file mode 100644 index 000000000000..8972f6e406ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/empty-struct.rs @@ -0,0 +1,10 @@ +pub struct XEmpty1 {} +pub struct XEmpty2; +pub struct XEmpty6(); + +pub enum XE { + XEmpty3 {}, + XEmpty4, + XEmpty5(), +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/extern-prelude-vec.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/extern-prelude-vec.rs new file mode 100644 index 000000000000..7c15d2486d89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/extern-prelude-vec.rs @@ -0,0 +1,4 @@ +#![crate_name = "Vec"] + +pub fn new(arg1: f32, arg2: ()) {} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/extern-prelude.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/extern-prelude.rs new file mode 100644 index 000000000000..4953def221d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/extern-prelude.rs @@ -0,0 +1,6 @@ +pub struct S; + +impl S { + pub fn external(&self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/extern-statics.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/extern-statics.rs new file mode 100644 index 000000000000..85eb5881ffaf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/extern-statics.rs @@ -0,0 +1,5 @@ +extern { + pub static XA: u8; + pub static mut XB: u8; +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/hello_macro.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/hello_macro.rs new file mode 100644 index 000000000000..859ba5bd5653 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/hello_macro.rs @@ -0,0 +1,22 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_quote)] + +extern crate proc_macro; + +use proc_macro::{TokenStream, quote}; + +// This macro is not very interesting, but it does contain delimited tokens with +// no content - `()` and `{}` - which has caused problems in the past. +// Also, it tests that we can escape `$` via `$$`. +#[proc_macro] +pub fn hello(_: TokenStream) -> TokenStream { + quote!({ + fn hello() {} + macro_rules! m { ($$($$t:tt)*) => { $$($$t)* } } + m!(hello()); + }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/impl_privacy_xc_1.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/impl_privacy_xc_1.rs new file mode 100644 index 000000000000..ac6afb776a8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/impl_privacy_xc_1.rs @@ -0,0 +1,10 @@ +#![crate_type = "lib"] + +pub struct Fish { + pub x: isize +} + +impl Fish { + pub fn swim(&self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/impl_privacy_xc_2.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/impl_privacy_xc_2.rs new file mode 100644 index 000000000000..deffa44cef3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/impl_privacy_xc_2.rs @@ -0,0 +1,14 @@ +#![crate_type = "lib"] + +pub struct Fish { + pub x: isize +} + +mod unexported { + use super::Fish; + impl PartialEq for Fish { + fn eq(&self, _: &Fish) -> bool { true } + fn ne(&self, _: &Fish) -> bool { false } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/inline_dtor.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/inline_dtor.rs new file mode 100644 index 000000000000..6c41341180f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/inline_dtor.rs @@ -0,0 +1,9 @@ +#![crate_name="inline_dtor"] + +pub struct Foo; + +impl Drop for Foo { + #[inline] + fn drop(&mut self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/inner_static.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/inner_static.rs new file mode 100644 index 000000000000..0a153e020ff6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/inner_static.rs @@ -0,0 +1,52 @@ +pub struct A { pub v: T } +pub struct B { pub v: T } + +pub mod test { + pub struct A { pub v: T } + + impl A { + pub fn foo(&self) -> isize { + static a: isize = 5; + return a + } + + pub fn bar(&self) -> isize { + static a: isize = 6; + return a; + } + } +} + +impl A { + pub fn foo(&self) -> isize { + static a: isize = 1; + return a + } + + pub fn bar(&self) -> isize { + static a: isize = 2; + return a; + } +} + +impl B { + pub fn foo(&self) -> isize { + static a: isize = 3; + return a + } + + pub fn bar(&self) -> isize { + static a: isize = 4; + return a; + } +} + +pub fn foo() -> isize { + let a = A { v: () }; + let b = B { v: () }; + let c = test::A { v: () }; + return a.foo() + a.bar() + + b.foo() + b.bar() + + c.foo() + c.bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/issue-72470-lib.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/issue-72470-lib.rs new file mode 100644 index 000000000000..85e045ba55b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/issue-72470-lib.rs @@ -0,0 +1,176 @@ +// compile-flags: -C opt-level=3 +// edition:2018 + +use std::future::Future; +use std::marker::PhantomData; +use std::pin::Pin; +use std::sync::atomic::AtomicUsize; +use std::sync::Arc; +use std::task::Poll::{Pending, Ready}; +use std::task::Waker; +use std::task::{Context, Poll}; +use std::{ + ptr, + task::{RawWaker, RawWakerVTable}, +}; + +/// Future for the [`poll_fn`] function. +pub struct PollFn { + f: F, +} + +impl Unpin for PollFn {} + +/// Creates a new future wrapping around a function returning [`Poll`]. +pub fn poll_fn(f: F) -> PollFn +where + F: FnMut(&mut Context<'_>) -> Poll, +{ + PollFn { f } +} + +impl Future for PollFn +where + F: FnMut(&mut Context<'_>) -> Poll, +{ + type Output = T; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + (&mut self.f)(cx) + } +} +pub fn run(future: F) -> F::Output { + BasicScheduler.block_on(future) +} + +pub(crate) struct BasicScheduler; + +impl BasicScheduler { + pub(crate) fn block_on(&mut self, mut future: F) -> F::Output + where + F: Future, + { + let waker = unsafe { Waker::from_raw(raw_waker()) }; + let mut cx = std::task::Context::from_waker(&waker); + + let mut future = unsafe { Pin::new_unchecked(&mut future) }; + + loop { + if let Ready(v) = future.as_mut().poll(&mut cx) { + return v; + } + } + } +} + +// ===== impl Spawner ===== + +fn raw_waker() -> RawWaker { + RawWaker::new(ptr::null(), waker_vtable()) +} + +fn waker_vtable() -> &'static RawWakerVTable { + &RawWakerVTable::new( + clone_arc_raw, + wake_arc_raw, + wake_by_ref_arc_raw, + drop_arc_raw, + ) +} + +unsafe fn clone_arc_raw(_: *const ()) -> RawWaker { + raw_waker() +} + +unsafe fn wake_arc_raw(_: *const ()) {} + +unsafe fn wake_by_ref_arc_raw(_: *const ()) {} + +unsafe fn drop_arc_raw(_: *const ()) {} + +struct AtomicWaker {} + +impl AtomicWaker { + /// Create an `AtomicWaker` + fn new() -> AtomicWaker { + AtomicWaker {} + } + + fn register_by_ref(&self, _waker: &Waker) {} +} + +#[allow(dead_code)] +struct Tx { + inner: Arc>, +} + +struct Rx { + inner: Arc>, +} + +#[allow(dead_code)] +struct Chan { + tx: PhantomData, + semaphore: Sema, + rx_waker: AtomicWaker, + rx_closed: bool, +} + +fn channel() -> (Tx, Rx) { + let chan = Arc::new(Chan { + tx: PhantomData, + semaphore: Sema(AtomicUsize::new(0)), + rx_waker: AtomicWaker::new(), + rx_closed: false, + }); + + ( + Tx { + inner: chan.clone(), + }, + Rx { inner: chan }, + ) +} + +// ===== impl Rx ===== + +impl Rx { + /// Receive the next value + fn recv(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.rx_waker.register_by_ref(cx.waker()); + + if self.inner.rx_closed && self.inner.semaphore.is_idle() { + Ready(None) + } else { + Pending + } + } +} + +struct Sema(AtomicUsize); + +impl Sema { + fn is_idle(&self) -> bool { + false + } +} + +pub struct UnboundedReceiver { + chan: Rx, +} + +pub fn unbounded_channel() -> UnboundedReceiver { + let (tx, rx) = channel(); + + drop(tx); + let rx = UnboundedReceiver { chan: rx }; + + rx +} + +impl UnboundedReceiver { + pub async fn recv(&mut self) -> Option { + poll_fn(|cx| self.chan.recv(cx)).await + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/issue-76387.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/issue-76387.rs new file mode 100644 index 000000000000..25c55282fb07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/issue-76387.rs @@ -0,0 +1,30 @@ +// compile-flags: -C opt-level=3 + +pub struct FatPtr { + ptr: *mut u8, + len: usize, +} + +impl FatPtr { + pub fn new(len: usize) -> FatPtr { + let ptr = Box::into_raw(vec![42u8; len].into_boxed_slice()) as *mut u8; + + FatPtr { ptr, len } + } +} + +impl std::ops::Deref for FatPtr { + type Target = [u8]; + + #[inline] + fn deref(&self) -> &[u8] { + unsafe { std::slice::from_raw_parts(self.ptr, self.len) } + } +} + +impl std::ops::Drop for FatPtr { + fn drop(&mut self) { + println!("Drop"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/kinds_in_metadata.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/kinds_in_metadata.rs new file mode 100644 index 000000000000..4eb3ed276026 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/kinds_in_metadata.rs @@ -0,0 +1,9 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Tests that metadata serialization works for the `Copy` kind. + +#![crate_type="lib"] + +pub fn f() {} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/link-cfg-works-transitive-dylib.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/link-cfg-works-transitive-dylib.rs new file mode 100644 index 000000000000..87b3b27bb7d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/link-cfg-works-transitive-dylib.rs @@ -0,0 +1,5 @@ +#![feature(link_cfg)] + +#[link(name = "foo", cfg(foo))] +extern {} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/link-cfg-works-transitive-rlib.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/link-cfg-works-transitive-rlib.rs new file mode 100644 index 000000000000..0e64b79eeb65 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/link-cfg-works-transitive-rlib.rs @@ -0,0 +1,8 @@ +// no-prefer-dynamic + +#![feature(link_cfg)] +#![crate_type = "rlib"] + +#[link(name = "foo", cfg(foo))] +extern {} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/linkage1.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/linkage1.rs new file mode 100644 index 000000000000..cae6c282290a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/linkage1.rs @@ -0,0 +1,5 @@ +#[no_mangle] +pub static foo: isize = 3; + +pub fn bar() {} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/llvm_pr32379.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/llvm_pr32379.rs new file mode 100644 index 000000000000..c0d649c454be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/llvm_pr32379.rs @@ -0,0 +1,6 @@ +pub fn pr32379(mut data: u64, f1: bool, f2: bool) -> u64 { + if f1 { data &= !2; } + if f2 { data |= 2; } + data +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/lto-duplicate-symbols1.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/lto-duplicate-symbols1.rs new file mode 100644 index 000000000000..4f987372c091 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/lto-duplicate-symbols1.rs @@ -0,0 +1,7 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +#[no_mangle] +pub extern fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/lto-duplicate-symbols2.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/lto-duplicate-symbols2.rs new file mode 100644 index 000000000000..4f987372c091 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/lto-duplicate-symbols2.rs @@ -0,0 +1,7 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +#[no_mangle] +pub extern fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/lto-rustc-loads-linker-plugin.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/lto-rustc-loads-linker-plugin.rs new file mode 100644 index 000000000000..4f5c91a39a7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/lto-rustc-loads-linker-plugin.rs @@ -0,0 +1,7 @@ +// compile-flags: -Clinker-plugin-lto +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/msvc-data-only-lib.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/msvc-data-only-lib.rs new file mode 100644 index 000000000000..6ae7309b142d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/msvc-data-only-lib.rs @@ -0,0 +1,6 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub static FOO: i32 = 42; + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/nested_item.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/nested_item.rs new file mode 100644 index 000000000000..9a2fab1e1d19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/nested_item.rs @@ -0,0 +1,31 @@ +// original problem +pub fn foo() -> isize { + { + static foo: isize = 2; + foo + } +} + +// issue 8134 +struct Foo; +impl Foo { + pub fn foo(&self) { + static X: usize = 1; + } +} + +// issue 8134 +pub struct Parser(T); +impl> Parser { + fn in_doctype(&mut self) { + static DOCTYPEPattern: [char; 6] = ['O', 'C', 'T', 'Y', 'P', 'E']; + } +} + +struct Bar; +impl Foo { + pub fn bar(&self) { + static X: usize = 1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/noexporttypelib.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/noexporttypelib.rs new file mode 100644 index 000000000000..f500a09fbbb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/noexporttypelib.rs @@ -0,0 +1,3 @@ +pub type oint = Option; +pub fn foo() -> oint { Some(3) } + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/orphan-check-diagnostics.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/orphan-check-diagnostics.rs new file mode 100644 index 000000000000..062f054d0c1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/orphan-check-diagnostics.rs @@ -0,0 +1,2 @@ +pub trait RemoteTrait { fn dummy(&self) { } } + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/proc_macro_def.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/proc_macro_def.rs new file mode 100644 index 000000000000..3f4f5b8f7801 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/proc_macro_def.rs @@ -0,0 +1,36 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_quote)] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro_attribute] +pub fn attr_tru(_attr: TokenStream, item: TokenStream) -> TokenStream { + let name = item.into_iter().nth(1).unwrap(); + quote!(fn $name() -> bool { true }) +} + +#[proc_macro_attribute] +pub fn attr_identity(_attr: TokenStream, item: TokenStream) -> TokenStream { + quote!($item) +} + +#[proc_macro] +pub fn tru(_ts: TokenStream) -> TokenStream { + quote!(true) +} + +#[proc_macro] +pub fn ret_tru(_ts: TokenStream) -> TokenStream { + quote!(return true;) +} + +#[proc_macro] +pub fn identity(ts: TokenStream) -> TokenStream { + quote!($ts) +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/pub-and-stability.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/pub-and-stability.rs new file mode 100644 index 000000000000..e6c743fe1f6b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/pub-and-stability.rs @@ -0,0 +1,134 @@ +// This crate attempts to enumerate the various scenarios for how a +// type can define fields and methods with various visibilities and +// stabilities. +// +// The basic stability pattern in this file has four cases: +// 1. no stability attribute at all +// 2. a stable attribute (feature "unit_test") +// 3. an unstable attribute that unit test declares (feature "unstable_declared") +// 4. an unstable attribute that unit test fails to declare (feature "unstable_undeclared") +// +// This file also covers four kinds of visibility: private, +// pub(module), pub(crate), and pub. +// +// However, since stability attributes can only be observed in +// cross-crate linkage scenarios, there is little reason to take the +// cross-product (4 stability cases * 4 visibility cases), because the +// first three visibility cases cannot be accessed outside this crate, +// and therefore stability is only relevant when the visibility is pub +// to the whole universe. +// +// (The only reason to do so would be if one were worried about the +// compiler having some subtle bug where adding a stability attribute +// introduces a privacy violation. As a way to provide evidence that +// this is not occurring, I have put stability attributes on some +// non-pub fields, marked with SILLY below) + +#![feature(staged_api)] + +#![stable(feature = "unit_test", since = "1.0.0")] + +#[stable(feature = "unit_test", since = "1.0.0")] +pub use m::{Record, Trait, Tuple}; + +mod m { + #[derive(Default)] + #[stable(feature = "unit_test", since = "1.0.0")] + pub struct Record { + #[stable(feature = "unit_test", since = "1.0.0")] + pub a_stable_pub: i32, + #[unstable(feature = "unstable_declared", issue = "38412")] + pub a_unstable_declared_pub: i32, + #[unstable(feature = "unstable_undeclared", issue = "38412")] + pub a_unstable_undeclared_pub: i32, + #[unstable(feature = "unstable_undeclared", issue = "38412")] // SILLY + pub(crate) b_crate: i32, + #[unstable(feature = "unstable_declared", issue = "38412")] // SILLY + pub(in m) c_mod: i32, + #[stable(feature = "unit_test", since = "1.0.0")] // SILLY + d_priv: i32 + } + + #[derive(Default)] + #[stable(feature = "unit_test", since = "1.0.0")] + pub struct Tuple( + #[stable(feature = "unit_test", since = "1.0.0")] + pub i32, + #[unstable(feature = "unstable_declared", issue = "38412")] + pub i32, + #[unstable(feature = "unstable_undeclared", issue = "38412")] + pub i32, + + pub(crate) i32, + pub(in m) i32, + i32); + + impl Record { + #[stable(feature = "unit_test", since = "1.0.0")] + pub fn new() -> Self { Default::default() } + } + + impl Tuple { + #[stable(feature = "unit_test", since = "1.0.0")] + pub fn new() -> Self { Default::default() } + } + + + #[stable(feature = "unit_test", since = "1.0.0")] + pub trait Trait { + #[stable(feature = "unit_test", since = "1.0.0")] + type Type; + #[stable(feature = "unit_test", since = "1.0.0")] + fn stable_trait_method(&self) -> Self::Type; + #[unstable(feature = "unstable_undeclared", issue = "38412")] + fn unstable_undeclared_trait_method(&self) -> Self::Type; + #[unstable(feature = "unstable_declared", issue = "38412")] + fn unstable_declared_trait_method(&self) -> Self::Type; + } + + #[stable(feature = "unit_test", since = "1.0.0")] + impl Trait for Record { + type Type = i32; + fn stable_trait_method(&self) -> i32 { self.d_priv } + fn unstable_undeclared_trait_method(&self) -> i32 { self.d_priv } + fn unstable_declared_trait_method(&self) -> i32 { self.d_priv } + } + + #[stable(feature = "unit_test", since = "1.0.0")] + impl Trait for Tuple { + type Type = i32; + fn stable_trait_method(&self) -> i32 { self.3 } + fn unstable_undeclared_trait_method(&self) -> i32 { self.3 } + fn unstable_declared_trait_method(&self) -> i32 { self.3 } + } + + impl Record { + #[unstable(feature = "unstable_undeclared", issue = "38412")] + pub fn unstable_undeclared(&self) -> i32 { self.d_priv } + #[unstable(feature = "unstable_declared", issue = "38412")] + pub fn unstable_declared(&self) -> i32 { self.d_priv } + #[stable(feature = "unit_test", since = "1.0.0")] + pub fn stable(&self) -> i32 { self.d_priv } + + #[unstable(feature = "unstable_undeclared", issue = "38412")] // SILLY + pub(crate) fn pub_crate(&self) -> i32 { self.d_priv } + #[unstable(feature = "unstable_declared", issue = "38412")] // SILLY + pub(in m) fn pub_mod(&self) -> i32 { self.d_priv } + #[stable(feature = "unit_test", since = "1.0.0")] // SILLY + fn private(&self) -> i32 { self.d_priv } + } + + impl Tuple { + #[unstable(feature = "unstable_undeclared", issue = "38412")] + pub fn unstable_undeclared(&self) -> i32 { self.0 } + #[unstable(feature = "unstable_declared", issue = "38412")] + pub fn unstable_declared(&self) -> i32 { self.0 } + #[stable(feature = "unit_test", since = "1.0.0")] + pub fn stable(&self) -> i32 { self.0 } + + pub(crate) fn pub_crate(&self) -> i32 { self.0 } + pub(in m) fn pub_mod(&self) -> i32 { self.0 } + fn private(&self) -> i32 { self.0 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/reachable-unnameable-items.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/reachable-unnameable-items.rs new file mode 100644 index 000000000000..d901cb422491 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/reachable-unnameable-items.rs @@ -0,0 +1,107 @@ +use inner_private_module::*; + +mod inner_private_module { + pub struct Unnameable1; + pub struct Unnameable2; + #[derive(Clone, Copy)] + pub struct Unnameable3; + pub struct Unnameable4; + pub struct Unnameable5; + pub struct Unnameable6; + pub struct Unnameable7; + #[derive(Default)] + pub struct Unnameable8; + pub enum UnnameableEnum { + NameableVariant + } + pub trait UnnameableTrait { + type Alias: Default; + } + + impl Unnameable1 { + pub fn method_of_unnameable_type1(&self) -> &'static str { + "Hello1" + } + } + impl Unnameable2 { + pub fn method_of_unnameable_type2(&self) -> &'static str { + "Hello2" + } + } + impl Unnameable3 { + pub fn method_of_unnameable_type3(&self) -> &'static str { + "Hello3" + } + } + impl Unnameable4 { + pub fn method_of_unnameable_type4(&self) -> &'static str { + "Hello4" + } + } + impl Unnameable5 { + pub fn method_of_unnameable_type5(&self) -> &'static str { + "Hello5" + } + } + impl Unnameable6 { + pub fn method_of_unnameable_type6(&self) -> &'static str { + "Hello6" + } + } + impl Unnameable7 { + pub fn method_of_unnameable_type7(&self) -> &'static str { + "Hello7" + } + } + impl Unnameable8 { + pub fn method_of_unnameable_type8(&self) -> &'static str { + "Hello8" + } + } + impl UnnameableEnum { + pub fn method_of_unnameable_enum(&self) -> &'static str { + "HelloEnum" + } + } +} + +pub fn function_returning_unnameable_type() -> Unnameable1 { + Unnameable1 +} + +pub const CONSTANT_OF_UNNAMEABLE_TYPE: Unnameable2 = + Unnameable2; + +pub fn function_accepting_unnameable_type(_: Option) {} + +pub type AliasOfUnnameableType = Unnameable4; + +impl Unnameable1 { + pub fn inherent_method_returning_unnameable_type(&self) -> Unnameable5 { + Unnameable5 + } +} + +pub trait Tr { + fn trait_method_returning_unnameable_type(&self) -> Unnameable6 { + Unnameable6 + } +} +impl Tr for Unnameable1 {} + +pub use inner_private_module::UnnameableEnum::NameableVariant; + +pub struct Struct { + pub field_of_unnameable_type: Unnameable7 +} + +pub static STATIC: Struct = Struct { field_of_unnameable_type: Unnameable7 } ; + +impl UnnameableTrait for AliasOfUnnameableType { + type Alias = Unnameable8; +} + +pub fn generic_function() -> T::Alias { + Default::default() +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/reexport-should-still-link.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/reexport-should-still-link.rs new file mode 100644 index 000000000000..2ff2e1b7df01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/reexport-should-still-link.rs @@ -0,0 +1,6 @@ +pub use foo::bar; + +mod foo { + pub fn bar() {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/removing-extern-crate.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/removing-extern-crate.rs new file mode 100644 index 000000000000..c5324d246902 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/removing-extern-crate.rs @@ -0,0 +1,2 @@ +// intentionally blank + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-meta.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-meta.rs new file mode 100644 index 000000000000..76ae4483bd5a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-meta.rs @@ -0,0 +1,9 @@ +// no-prefer-dynamic +// compile-flags: --emit=metadata + +#![crate_type="rlib"] + +pub struct Foo { + pub field: i32, +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-rlib-rpass.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-rlib-rpass.rs new file mode 100644 index 000000000000..2bb1bd1bb7fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-rlib-rpass.rs @@ -0,0 +1,9 @@ +// no-prefer-dynamic + +#![crate_type="rlib"] +#![crate_name="rmeta_aux"] + +pub struct Foo { + pub field: i32, +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-rlib.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-rlib.rs new file mode 100644 index 000000000000..11207caecb56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-rlib.rs @@ -0,0 +1,6 @@ +#![crate_type="rlib"] + +pub struct Foo { + pub field: i32, +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-rmeta.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-rmeta.rs new file mode 100644 index 000000000000..b8632ed8de07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/rmeta-rmeta.rs @@ -0,0 +1,10 @@ +// no-prefer-dynamic +// compile-flags: --emit=metadata + +#![crate_type="rlib"] +#![crate_name="rmeta_aux"] + +pub struct Foo { + pub field2: i32, +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/rustc-rust-log-aux.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/rustc-rust-log-aux.rs new file mode 100644 index 000000000000..243bd763869b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/rustc-rust-log-aux.rs @@ -0,0 +1,2 @@ +// rustc-env:RUSTC_LOG=debug + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/stability-cfg2.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/stability-cfg2.rs new file mode 100644 index 000000000000..eaa1d1f9f89c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/stability-cfg2.rs @@ -0,0 +1,6 @@ +// compile-flags:--cfg foo + +#![cfg_attr(foo, unstable(feature = "unstable_test_feature", issue = "none"))] +#![cfg_attr(not(foo), stable(feature = "test_feature", since = "1.0.0"))] +#![feature(staged_api)] + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/svh-a-base.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/svh-a-base.rs new file mode 100644 index 000000000000..0457648ed473 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/svh-a-base.rs @@ -0,0 +1,26 @@ +//! The `svh-a-*.rs` files are all deviations from the base file +//! svh-a-base.rs with some difference (usually in `fn foo`) that +//! should not affect the strict version hash (SVH) computation +//! (#14132). + +#![crate_name = "a"] + +macro_rules! three { + () => { 3 } +} + +pub trait U {} +pub trait V {} +impl U for () {} +impl V for () {} + +static A_CONSTANT : isize = 2; + +pub fn foo(_: isize) -> isize { + 3 +} + +pub fn an_unused_name() -> isize { + 4 +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/svh-b.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/svh-b.rs new file mode 100644 index 000000000000..f3d7138bbabe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/svh-b.rs @@ -0,0 +1,14 @@ +//! This is a client of the `a` crate defined in `svn-a-base.rs`. The +//! rpass and cfail tests (such as `run-pass/svh-add-comment.rs`) use +//! it by swapping in a different object code library crate built from +//! some variant of `svn-a-base.rs`, and then we are checking if the +//! compiler properly ignores or accepts the change, based on whether +//! the change could affect the downstream crate content or not +//! (#14132). + +#![crate_name = "b"] + +extern crate a; + +pub fn foo() { assert_eq!(a::foo::<()>(0), 3); } + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/trait_superkinds_in_metadata.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/trait_superkinds_in_metadata.rs new file mode 100644 index 000000000000..41e1f74cdac2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/trait_superkinds_in_metadata.rs @@ -0,0 +1,9 @@ +// Test library crate for cross-crate usages of traits inheriting +// from the builtin kinds. Mostly tests metadata correctness. + +#![crate_type="lib"] + +pub trait RequiresShare : Sync { } +pub trait RequiresRequiresShareAndSend : RequiresShare + Send { } +pub trait RequiresCopy : Copy { } + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/typeid-intrinsic-aux1.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/typeid-intrinsic-aux1.rs new file mode 100644 index 000000000000..e069cbb9e75e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/typeid-intrinsic-aux1.rs @@ -0,0 +1,30 @@ +use std::any::{Any, TypeId}; + +pub struct A; +pub struct B(Option); +pub struct C(Option); +pub struct D(Option<&'static str>); +pub struct E(Result<&'static str, isize>); + +pub type F = Option; +pub type G = usize; +pub type H = &'static str; +pub type I = Box; +pub type I32Iterator = Iterator; +pub type U32Iterator = Iterator; + +pub fn id_A() -> TypeId { TypeId::of::() } +pub fn id_B() -> TypeId { TypeId::of::() } +pub fn id_C() -> TypeId { TypeId::of::() } +pub fn id_D() -> TypeId { TypeId::of::() } +pub fn id_E() -> TypeId { TypeId::of::() } +pub fn id_F() -> TypeId { TypeId::of::() } +pub fn id_G() -> TypeId { TypeId::of::() } +pub fn id_H() -> TypeId { TypeId::of::() } +pub fn id_I() -> TypeId { TypeId::of::() } + +pub fn foo() -> TypeId { TypeId::of::() } + +pub fn id_i32_iterator() -> TypeId { TypeId::of::() } +pub fn id_u32_iterator() -> TypeId { TypeId::of::() } + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/typeid-intrinsic-aux2.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/typeid-intrinsic-aux2.rs new file mode 100644 index 000000000000..e069cbb9e75e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/typeid-intrinsic-aux2.rs @@ -0,0 +1,30 @@ +use std::any::{Any, TypeId}; + +pub struct A; +pub struct B(Option); +pub struct C(Option); +pub struct D(Option<&'static str>); +pub struct E(Result<&'static str, isize>); + +pub type F = Option; +pub type G = usize; +pub type H = &'static str; +pub type I = Box; +pub type I32Iterator = Iterator; +pub type U32Iterator = Iterator; + +pub fn id_A() -> TypeId { TypeId::of::() } +pub fn id_B() -> TypeId { TypeId::of::() } +pub fn id_C() -> TypeId { TypeId::of::() } +pub fn id_D() -> TypeId { TypeId::of::() } +pub fn id_E() -> TypeId { TypeId::of::() } +pub fn id_F() -> TypeId { TypeId::of::() } +pub fn id_G() -> TypeId { TypeId::of::() } +pub fn id_H() -> TypeId { TypeId::of::() } +pub fn id_I() -> TypeId { TypeId::of::() } + +pub fn foo() -> TypeId { TypeId::of::() } + +pub fn id_i32_iterator() -> TypeId { TypeId::of::() } +pub fn id_u32_iterator() -> TypeId { TypeId::of::() } + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/using-target-feature-unstable.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/using-target-feature-unstable.rs new file mode 100644 index 000000000000..7013e7d741fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/using-target-feature-unstable.rs @@ -0,0 +1,6 @@ +#![feature(avx512_target_feature)] + +#[inline] +#[target_feature(enable = "avx512ifma")] +pub unsafe fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/weak-lang-items.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/weak-lang-items.rs new file mode 100644 index 000000000000..520717752791 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/weak-lang-items.rs @@ -0,0 +1,23 @@ +// no-prefer-dynamic + +// This aux-file will require the eh_personality function to be codegen'd, but +// it hasn't been defined just yet. Make sure we don't explode. + +#![no_std] +#![crate_type = "rlib"] + +struct A; + +impl core::ops::Drop for A { + fn drop(&mut self) {} +} + +pub fn foo() { + let _a = A; + panic!("wut"); +} + +mod std { + pub use core::{option, fmt}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/auxiliary/xc-private-method-lib.rs b/gcc/testsuite/rust/rustc/ui/auxiliary/xc-private-method-lib.rs new file mode 100644 index 000000000000..197b5bc79cde --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/auxiliary/xc-private-method-lib.rs @@ -0,0 +1,34 @@ +#![crate_type="lib"] + +pub struct Struct { + pub x: isize +} + +impl Struct { + fn static_meth_struct() -> Struct { + Struct { x: 1 } + } + + fn meth_struct(&self) -> isize { + self.x + } +} + +pub enum Enum { + Variant1(isize), + Variant2(isize) +} + +impl Enum { + fn static_meth_enum() -> Enum { + Enum::Variant2(10) + } + + fn meth_enum(&self) -> isize { + match *self { + Enum::Variant1(x) | + Enum::Variant2(x) => x + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/backtrace-debuginfo-aux.rs b/gcc/testsuite/rust/rustc/ui/backtrace-debuginfo-aux.rs new file mode 100644 index 000000000000..7fde20a318a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/backtrace-debuginfo-aux.rs @@ -0,0 +1,15 @@ +// run-pass +// ignore-test: not a test, used by backtrace-debuginfo.rs to test file!() + +#[inline(never)] +pub fn callback(f: F) where F: FnOnce((&'static str, u32)) { + f((file!(), line!())) +} + +// We emit the wrong location for the caller here when inlined on MSVC +#[cfg_attr(not(target_env = "msvc"), inline(always))] +#[cfg_attr(target_env = "msvc", inline(never))] +pub fn callback_inlined(f: F) where F: FnOnce((&'static str, u32)) { + f((file!(), line!())) +} + diff --git a/gcc/testsuite/rust/rustc/ui/backtrace-debuginfo.rs b/gcc/testsuite/rust/rustc/ui/backtrace-debuginfo.rs new file mode 100644 index 000000000000..adc586ae0e2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/backtrace-debuginfo.rs @@ -0,0 +1,195 @@ +// run-pass +// We disable tail merging here because it can't preserve debuginfo and thus +// potentially breaks the backtraces. Also, subtle changes can decide whether +// tail merging succeeds, so the test might work today but fail tomorrow due to a +// seemingly completely unrelated change. +// Unfortunately, LLVM has no "disable" option for this, so we have to set +// "enable" to 0 instead. + +// compile-flags:-g -Cllvm-args=-enable-tail-merge=0 -Cllvm-args=-opt-bisect-limit=0 +// compile-flags:-Cforce-frame-pointers=yes +// ignore-pretty issue #37195 +// ignore-cloudabi spawning processes is not supported +// ignore-emscripten spawning processes is not supported +// ignore-sgx no processes +// normalize-stderr-test ".*\n" -> "" + +// Note that above `-opt-bisect-limit=0` is used to basically disable +// optimizations. It creates tons of output on stderr, hence we normalize +// that away entirely. + +use std::env; + +#[path = "backtrace-debuginfo-aux.rs"] mod aux; + +macro_rules! pos { + () => ((file!(), line!())) +} + +macro_rules! dump_and_die { + ($($pos:expr),*) => ({ + // FIXME(#18285): we cannot include the current position because + // the macro span takes over the last frame's file/line. + // + // You might also be wondering why a major platform, + // i686-pc-windows-msvc, is located in here. Some of the saga can be + // found on #62897, but the tl;dr; is that it appears that if the + // standard library doesn't have debug information or frame pointers, + // which it doesn't by default on the test builders, then the stack + // walking routines in dbghelp will randomly terminate the stack trace + // in libstd without going further. Presumably the addition of frame + // pointers and/or debuginfo fixes this since tests always work with + // nightly compilers (which have debuginfo). In general though this test + // is replicated in rust-lang/backtrace-rs and has extensive coverage + // there, even on i686-pc-windows-msvc. We do the best we can in + // rust-lang/rust to test it as well, but sometimes we just gotta keep + // landing PRs. + if cfg!(any(target_os = "android", + all(target_os = "linux", target_arch = "arm"), + all(target_env = "msvc", target_arch = "x86"), + target_os = "freebsd", + target_os = "dragonfly", + target_os = "openbsd")) { + // skip these platforms as this support isn't implemented yet. + } else { + dump_filelines(&[$($pos),*]); + panic!(); + } + }) +} + +// we can't use a function as it will alter the backtrace +macro_rules! check { + ($counter:expr; $($pos:expr),*) => ({ + if *$counter == 0 { + dump_and_die!($($pos),*) + } else { + *$counter -= 1; + } + }) +} + +type Pos = (&'static str, u32); + +// this goes to stdout and each line has to be occurred +// in the following backtrace to stderr with a correct order. +fn dump_filelines(filelines: &[Pos]) { + for &(file, line) in filelines.iter().rev() { + // extract a basename + let basename = file.split(&['/', '\\'][..]).last().unwrap(); + println!("{}:{}", basename, line); + } +} + +#[inline(never)] +fn inner(counter: &mut i32, main_pos: Pos, outer_pos: Pos) { + check!(counter; main_pos, outer_pos); + check!(counter; main_pos, outer_pos); + let inner_pos = pos!(); aux::callback(|aux_pos| { + check!(counter; main_pos, outer_pos, inner_pos, aux_pos); + }); + let inner_pos = pos!(); aux::callback_inlined(|aux_pos| { + check!(counter; main_pos, outer_pos, inner_pos, aux_pos); + }); +} + +// We emit the wrong location for the caller here when inlined on MSVC +#[cfg_attr(not(target_env = "msvc"), inline(always))] +#[cfg_attr(target_env = "msvc", inline(never))] +fn inner_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos) { + check!(counter; main_pos, outer_pos); + check!(counter; main_pos, outer_pos); + + // Again, disable inlining for MSVC. + #[cfg_attr(not(target_env = "msvc"), inline(always))] + #[cfg_attr(target_env = "msvc", inline(never))] + fn inner_further_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos, inner_pos: Pos) { + check!(counter; main_pos, outer_pos, inner_pos); + } + inner_further_inlined(counter, main_pos, outer_pos, pos!()); + + let inner_pos = pos!(); aux::callback(|aux_pos| { + check!(counter; main_pos, outer_pos, inner_pos, aux_pos); + }); + let inner_pos = pos!(); aux::callback_inlined(|aux_pos| { + check!(counter; main_pos, outer_pos, inner_pos, aux_pos); + }); + + // this tests a distinction between two independent calls to the inlined function. + // (un)fortunately, LLVM somehow merges two consecutive such calls into one node. + inner_further_inlined(counter, main_pos, outer_pos, pos!()); +} + +#[inline(never)] +fn outer(mut counter: i32, main_pos: Pos) { + inner(&mut counter, main_pos, pos!()); + inner_inlined(&mut counter, main_pos, pos!()); +} + +fn check_trace(output: &str, error: &str) -> Result<(), String> { + // reverse the position list so we can start with the last item (which was the first line) + let mut remaining: Vec<&str> = output.lines().map(|s| s.trim()).rev().collect(); + + if !error.contains("stack backtrace") { + return Err(format!("no backtrace found in stderr:\n{}", error)) + } + for line in error.lines() { + if !remaining.is_empty() && line.contains(remaining.last().unwrap()) { + remaining.pop(); + } + } + if !remaining.is_empty() { + return Err(format!("trace does not match position list\n\ + still need to find {:?}\n\n\ + --- stdout\n{}\n\ + --- stderr\n{}", + remaining, output, error)) + } + Ok(()) +} + +fn run_test(me: &str) { + use std::str; + use std::process::Command; + + let mut i = 0; + let mut errors = Vec::new(); + loop { + let out = Command::new(me) + .env("RUST_BACKTRACE", "full") + .arg(i.to_string()).output().unwrap(); + let output = str::from_utf8(&out.stdout).unwrap(); + let error = str::from_utf8(&out.stderr).unwrap(); + if out.status.success() { + assert!(output.contains("done."), "bad output for successful run: {}", output); + break; + } else { + if let Err(e) = check_trace(output, error) { + errors.push(e); + } + } + i += 1; + } + if errors.len() > 0 { + for error in errors { + println!("---------------------------------------"); + println!("{}", error); + } + + panic!("found some errors"); + } +} + +#[inline(never)] +fn main() { + let args: Vec = env::args().collect(); + if args.len() >= 2 { + let case = args[1].parse().unwrap(); + eprintln!("test case {}", case); + outer(case, pos!()); + println!("done."); + } else { + run_test(&args[0]); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/backtrace.rs b/gcc/testsuite/rust/rustc/ui/backtrace.rs new file mode 100644 index 000000000000..f4b1ccd2756e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/backtrace.rs @@ -0,0 +1,126 @@ +// run-pass +// ignore-android FIXME #17520 +// ignore-cloudabi spawning processes is not supported +// ignore-emscripten spawning processes is not supported +// ignore-openbsd no support for libbacktrace without filename +// ignore-sgx no processes +// ignore-msvc see #62897 and `backtrace-debuginfo.rs` test +// compile-flags:-g + +use std::env; +use std::process::{Command, Stdio}; +use std::str; + +#[inline(never)] +fn foo() { + let _v = vec![1, 2, 3]; + if env::var_os("IS_TEST").is_some() { + panic!() + } +} + +#[inline(never)] +fn double() { + struct Double; + + impl Drop for Double { + fn drop(&mut self) { panic!("twice") } + } + + let _d = Double; + + panic!("once"); +} + +fn template(me: &str) -> Command { + let mut m = Command::new(me); + m.env("IS_TEST", "1") + .stdout(Stdio::piped()) + .stderr(Stdio::piped()); + return m; +} + +fn expected(fn_name: &str) -> String { + format!(" backtrace::{}", fn_name) +} + +fn contains_verbose_expected(s: &str, fn_name: &str) -> bool { + // HACK(eddyb) work around the fact that verbosely demangled stack traces + // (from `RUST_BACKTRACE=full`, or, as is the case here, panic-in-panic) + // may contain symbols with hashes in them, i.e. `backtrace[...]::`. + let prefix = " backtrace"; + let suffix = &format!("::{}", fn_name); + s.match_indices(prefix).any(|(i, _)| { + s[i + prefix.len()..] + .trim_start_matches('[') + .trim_start_matches(char::is_alphanumeric) + .trim_start_matches(']') + .starts_with(suffix) + }) +} + +fn runtest(me: &str) { + // Make sure that the stack trace is printed + let p = template(me).arg("fail").env("RUST_BACKTRACE", "1").spawn().unwrap(); + let out = p.wait_with_output().unwrap(); + assert!(!out.status.success()); + let s = str::from_utf8(&out.stderr).unwrap(); + assert!(s.contains("stack backtrace") && s.contains(&expected("foo")), + "bad output: {}", s); + assert!(s.contains(" 0:"), "the frame number should start at 0"); + + // Make sure the stack trace is *not* printed + // (Remove RUST_BACKTRACE from our own environment, in case developer + // is running `make check` with it on.) + let p = template(me).arg("fail").env_remove("RUST_BACKTRACE").spawn().unwrap(); + let out = p.wait_with_output().unwrap(); + assert!(!out.status.success()); + let s = str::from_utf8(&out.stderr).unwrap(); + assert!(!s.contains("stack backtrace") && !s.contains(&expected("foo")), + "bad output2: {}", s); + + // Make sure the stack trace is *not* printed + // (RUST_BACKTRACE=0 acts as if it were unset from our own environment, + // in case developer is running `make check` with it set.) + let p = template(me).arg("fail").env("RUST_BACKTRACE","0").spawn().unwrap(); + let out = p.wait_with_output().unwrap(); + assert!(!out.status.success()); + let s = str::from_utf8(&out.stderr).unwrap(); + assert!(!s.contains("stack backtrace") && !s.contains(" - foo"), + "bad output3: {}", s); + + // Make sure a stack trace is printed + let p = template(me).arg("double-fail").spawn().unwrap(); + let out = p.wait_with_output().unwrap(); + assert!(!out.status.success()); + let s = str::from_utf8(&out.stderr).unwrap(); + // loosened the following from double::h to double:: due to + // spurious failures on mac, 32bit, optimized + assert!(s.contains("stack backtrace") && contains_verbose_expected(s, "double"), + "bad output3: {}", s); + + // Make sure a stack trace isn't printed too many times + let p = template(me).arg("double-fail") + .env("RUST_BACKTRACE", "1").spawn().unwrap(); + let out = p.wait_with_output().unwrap(); + assert!(!out.status.success()); + let s = str::from_utf8(&out.stderr).unwrap(); + let mut i = 0; + for _ in 0..2 { + i += s[i + 10..].find("stack backtrace").unwrap() + 10; + } + assert!(s[i + 10..].find("stack backtrace").is_none(), + "bad output4: {}", s); +} + +fn main() { + let args: Vec = env::args().collect(); + if args.len() >= 2 && args[1] == "fail" { + foo(); + } else if args.len() >= 2 && args[1] == "double-fail" { + double(); + } else { + runtest(&args[0]); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-const-type.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-const-type.rs new file mode 100644 index 000000000000..0636bd2b72d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-const-type.rs @@ -0,0 +1,5 @@ +static i: String = 10; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +fn main() { println!("{}", i); } + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-crate-name.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-crate-name.rs new file mode 100644 index 000000000000..ea294da53a73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-crate-name.rs @@ -0,0 +1,6 @@ +extern crate krate-name-here; +// { dg-error ".E0463." "" { target *-*-* } .-1 } +// { dg-error ".E0463." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-env-capture.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-env-capture.rs new file mode 100644 index 000000000000..faefa33df0a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-env-capture.rs @@ -0,0 +1,7 @@ +// error-pattern: can't capture dynamic environment in a fn item +fn foo() { + let x: isize; + fn bar() { log(debug, x); } +} +fn main() { foo(); } + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-env-capture2.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-env-capture2.rs new file mode 100644 index 000000000000..9c068c201ac6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-env-capture2.rs @@ -0,0 +1,6 @@ +// error-pattern: can't capture dynamic environment in a fn item +fn foo(x: isize) { + fn bar() { log(debug, x); } +} +fn main() { foo(2); } + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-env-capture3.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-env-capture3.rs new file mode 100644 index 000000000000..29a6a3f2c57a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-env-capture3.rs @@ -0,0 +1,9 @@ +// error-pattern: can't capture dynamic environment in a fn item +fn foo(x: isize) { + fn mth() { + fn bar() { log(debug, x); } + } +} + +fn main() { foo(2); } + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-expr-lhs.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-expr-lhs.rs new file mode 100644 index 000000000000..e0fc26e18942 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-expr-lhs.rs @@ -0,0 +1,13 @@ +fn main() { + 1 = 2; // { dg-error ".E0070." "" { target *-*-* } } + 1 += 2; // { dg-error ".E0070." "" { target *-*-* } } + (1, 2) = (3, 4); // { dg-error ".E0070." "" { target *-*-* } } +// { dg-error ".E0070." "" { target *-*-* } .-2 } +// { dg-error ".E0070." "" { target *-*-* } .-3 } + + let (a, b) = (1, 2); + (a, b) = (3, 4); // { dg-error ".E0658." "" { target *-*-* } } + + None = Some(3); // { dg-error ".E0070." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-expr-path.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-expr-path.rs new file mode 100644 index 000000000000..8a3845059dad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-expr-path.rs @@ -0,0 +1,9 @@ +mod m1 {} + +fn main(arguments: Vec) { // { dg-error ".E0580." "" { target *-*-* } } + log(debug, m1::arguments); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { dg-error ".E0425." "" { target *-*-* } .-2 } +// { dg-error ".E0425." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-expr-path2.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-expr-path2.rs new file mode 100644 index 000000000000..5666ee46bc03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-expr-path2.rs @@ -0,0 +1,11 @@ +mod m1 { + pub mod arguments {} +} + +fn main(arguments: Vec) { // { dg-error ".E0580." "" { target *-*-* } } + log(debug, m1::arguments); +// { dg-error ".E0423." "" { target *-*-* } .-1 } +// { dg-error ".E0423." "" { target *-*-* } .-2 } +// { dg-error ".E0423." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-extern-link-attrs.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-extern-link-attrs.rs new file mode 100644 index 000000000000..d3240317b39d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-extern-link-attrs.rs @@ -0,0 +1,8 @@ +#[link()] // { dg-error ".E0459." "" { target *-*-* } } +#[link(name = "")] // { dg-error ".E0454." "" { target *-*-* } } +#[link(name = "foo")] +#[link(name = "foo", kind = "bar")] // { dg-error ".E0458." "" { target *-*-* } } +extern {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-intrinsic-monomorphization.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-intrinsic-monomorphization.rs new file mode 100644 index 000000000000..2ca0bb24e936 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-intrinsic-monomorphization.rs @@ -0,0 +1,33 @@ +// build-fail + +#![feature(repr_simd, platform_intrinsics, core_intrinsics)] +#![allow(warnings)] +#![crate_type = "rlib"] + +// Bad monomorphizations could previously cause LLVM asserts even though the +// error was caught in the compiler. + +extern "platform-intrinsic" { + fn simd_add(x: T, y: T) -> T; +} + +use std::intrinsics; + +#[derive(Copy, Clone)] +pub struct Foo(i64); + +pub fn test_cttz(v: Foo) -> Foo { + intrinsics::cttz(v) +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_fadd_fast(a: Foo, b: Foo) -> Foo { + intrinsics::fadd_fast(a, b) +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_simd_add(a: Foo, b: Foo) -> Foo { + simd_add(a, b) +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-lint-cap.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-lint-cap.rs new file mode 100644 index 000000000000..e46a88301462 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-lint-cap.rs @@ -0,0 +1,5 @@ +// compile-flags: --cap-lints test +// error-pattern: unknown lint level: `test` + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-lint-cap2.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-lint-cap2.rs new file mode 100644 index 000000000000..51a2ba90d4ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-lint-cap2.rs @@ -0,0 +1,9 @@ +// compile-flags: --cap-lints deny + +#![warn(unused)] +#![deny(warnings)] + +use std::option; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-lint-cap3.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-lint-cap3.rs new file mode 100644 index 000000000000..921402902692 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-lint-cap3.rs @@ -0,0 +1,10 @@ +// check-pass +// compile-flags: --cap-lints warn + +#![warn(unused)] +#![deny(warnings)] + +use std::option; // { dg-warning "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-main.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-main.rs new file mode 100644 index 000000000000..04f3aa3e7105 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-main.rs @@ -0,0 +1,2 @@ +fn main(x: isize) { } // { dg-error ".E0580." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-method-typaram-kind.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-method-typaram-kind.rs new file mode 100644 index 000000000000..1b5ba13b9357 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-method-typaram-kind.rs @@ -0,0 +1,15 @@ +fn foo() { + 1.bar::(); // { dg-error ".E0277." "" { target *-*-* } } +} + +trait Bar { + fn bar(&self); +} + +impl Bar for usize { + fn bar(&self) { + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-mid-path-type-params.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-mid-path-type-params.rs new file mode 100644 index 000000000000..039dbfdd68b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-mid-path-type-params.rs @@ -0,0 +1,44 @@ +struct S { + contents: T, +} + +impl S { + fn new(x: T, _: U) -> S { + S { + contents: x, + } + } +} + +trait Trait { + fn new(x: T, y: U) -> Self; +} + +struct S2 { + contents: isize, +} + +impl Trait for S2 { + fn new(x: isize, _: U) -> S2 { + S2 { + contents: x, + } + } +} + +fn foo<'a>() { + let _ = S::new::(1, 1.0); +// { dg-error ".E0107." "" { target *-*-* } .-1 } + + let _ = S::<'a,isize>::new::(1, 1.0); +// { dg-error ".E0107." "" { target *-*-* } .-1 } + + let _: S2 = Trait::new::(1, 1.0); +// { dg-error ".E0107." "" { target *-*-* } .-1 } + + let _: S2 = Trait::<'a,isize>::new::(1, 1.0); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-module.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-module.rs new file mode 100644 index 000000000000..c9b8fcf07388 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-module.rs @@ -0,0 +1,8 @@ +fn main() { + let foo = thing::len(Vec::new()); +// { dg-error ".E0433." "" { target *-*-* } .-1 } + + let foo = foo::bar::baz(); +// { dg-error ".E0433." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-sized.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-sized.rs new file mode 100644 index 000000000000..4d6d74e88ee6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-sized.rs @@ -0,0 +1,9 @@ +trait Trait {} + +pub fn main() { + let x: Vec = Vec::new(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/bad/bad-type-env-capture.rs b/gcc/testsuite/rust/rustc/ui/bad/bad-type-env-capture.rs new file mode 100644 index 000000000000..280840c2f3cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bad/bad-type-env-capture.rs @@ -0,0 +1,5 @@ +fn foo() { + fn bar(b: T) { } // { dg-error ".E0401." "" { target *-*-* } } +} +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/bare-fn-implements-fn-mut.rs b/gcc/testsuite/rust/rustc/ui/bare-fn-implements-fn-mut.rs new file mode 100644 index 000000000000..12b15ee9d220 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bare-fn-implements-fn-mut.rs @@ -0,0 +1,28 @@ +// run-pass + +use std::ops::FnMut; + +fn call_f(mut f: F) { + f(); +} + +fn f() { + println!("hello"); +} + +fn call_g String>(mut g: G, x: String, y: String) + -> String { + g(x, y) +} + +fn g(mut x: String, y: String) -> String { + x.push_str(&y); + x +} + +fn main() { + call_f(f); + assert_eq!(call_g(g, "foo".to_string(), "bar".to_string()), + "foobar"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/bare-static-string.rs b/gcc/testsuite/rust/rustc/ui/bare-static-string.rs new file mode 100644 index 000000000000..b3b2419a6490 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bare-static-string.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + let x: &'static str = "foo"; + println!("{}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/bastion-of-the-turbofish.rs b/gcc/testsuite/rust/rustc/ui/bastion-of-the-turbofish.rs new file mode 100644 index 000000000000..3ad936e99ac2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bastion-of-the-turbofish.rs @@ -0,0 +1,37 @@ +// check-pass + +// Bastion of the Turbofish +// ------------------------ +// Beware travellers, lest you venture into waters callous and unforgiving, +// where hope must be abandoned, ere it is cruelly torn from you. For here +// stands the bastion of the Turbofish: an impenetrable fortress holding +// unshaking against those who would dare suggest the supererogation of the +// Turbofish. +// +// Once I was young and foolish and had the impudence to imagine that I could +// shake free from the coils by which that creature had us tightly bound. I +// dared to suggest that there was a better way: a brighter future, in which +// Rustaceans both new and old could be rid of that vile beast. But alas! In +// my foolhardiness my ignorance was unveiled and my dreams were dashed +// unforgivingly against the rock of syntactic ambiguity. +// +// This humble program, small and insignificant though it might seem, +// demonstrates that to which we had previously cast a blind eye: an ambiguity +// in permitting generic arguments to be provided without the consent of the +// Great Turbofish. Should you be so naïve as to try to revolt against its +// mighty clutches, here shall its wrath be indomitably displayed. This +// program must pass for all eternity, fundamentally at odds with an impetuous +// rebellion against the Turbofish. +// +// My heart aches in sorrow, for I know I am defeated. Let this be a warning +// to all those who come after. Here stands the bastion of the Turbofish. + +// See https://github.com/rust-lang/rust/pull/53562 +// and https://github.com/rust-lang/rfcs/pull/2527 +// for context. + +fn main() { + let (oh, woe, is, me) = ("the", "Turbofish", "remains", "undefeated"); + let _: (bool, bool) = (oh(me)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/bench/issue-32062.rs b/gcc/testsuite/rust/rustc/ui/bench/issue-32062.rs new file mode 100644 index 000000000000..a43cccbd1735 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bench/issue-32062.rs @@ -0,0 +1,51 @@ +// run-pass + +// pretty-expanded FIXME #23616 + +fn main() { + let _ = test(Some(0).into_iter()); +} + +trait Parser { + type Input: Iterator; + type Output; + fn parse(self, input: Self::Input) -> Result<(Self::Output, Self::Input), ()>; + fn chain

(self, p: P) -> Chain where Self: Sized { + Chain(self, p) + } +} + +struct Token(T::Item) where T: Iterator; + +impl Parser for Token where T: Iterator { + type Input = T; + type Output = T::Item; + fn parse(self, _input: Self::Input) -> Result<(Self::Output, Self::Input), ()> { + Err(()) + } +} + +struct Chain(L, R); + +impl Parser for Chain where L: Parser, R: Parser { + type Input = L::Input; + type Output = (L::Output, R::Output); + fn parse(self, _input: Self::Input) -> Result<(Self::Output, Self::Input), ()> { + Err(()) + } +} + +fn test(i: I) -> Result<((), I), ()> where I: Iterator { + Chain(Token(0), Token(1)) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .chain(Chain(Token(0), Token(1))) + .parse(i) + .map(|(_, i)| ((), i)) +} + diff --git a/gcc/testsuite/rust/rustc/ui/big-literals.rs b/gcc/testsuite/rust/rustc/ui/big-literals.rs new file mode 100644 index 000000000000..cc8cd6a8e55c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/big-literals.rs @@ -0,0 +1,18 @@ +// run-pass +// Catch mistakes in the overflowing literals lint. +#![deny(overflowing_literals)] + +pub fn main() { + assert_eq!(0xffffffff, (!0 as u32)); + assert_eq!(4294967295, (!0 as u32)); + assert_eq!(0xffffffffffffffff, (!0 as u64)); + assert_eq!(18446744073709551615, (!0 as u64)); + + assert_eq!((-2147483648i32).wrapping_sub(1), 2147483647); + + assert_eq!(-3.40282356e+38_f32, ::std::f32::MIN); + assert_eq!(3.40282356e+38_f32, ::std::f32::MAX); + assert_eq!(-1.7976931348623158e+308_f64, ::std::f64::MIN); + assert_eq!(1.7976931348623158e+308_f64, ::std::f64::MAX); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binary-minus-without-space.rs b/gcc/testsuite/rust/rustc/ui/binary-minus-without-space.rs new file mode 100644 index 000000000000..333a62ff13c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binary-minus-without-space.rs @@ -0,0 +1,9 @@ +// run-pass +// Check that issue #954 stays fixed + + +pub fn main() { + match -1 { -1 => {}, _ => panic!("wat") } + assert_eq!(1-1, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binary-op-on-double-ref.rs b/gcc/testsuite/rust/rustc/ui/binary-op-on-double-ref.rs new file mode 100644 index 000000000000..12a7a67fce04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binary-op-on-double-ref.rs @@ -0,0 +1,10 @@ +// run-rustfix +fn main() { + let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; + let vr = v.iter().filter(|x| { + x % 2 == 0 +// { dg-error ".E0369." "" { target *-*-* } .-1 } + }); + println!("{:?}", vr); +} + diff --git a/gcc/testsuite/rust/rustc/ui/bind-by-move.rs b/gcc/testsuite/rust/rustc/ui/bind-by-move.rs new file mode 100644 index 000000000000..0c179fd68fbf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bind-by-move.rs @@ -0,0 +1,14 @@ +// run-pass + +use std::sync::Arc; +fn dispose(_x: Arc) { } + +pub fn main() { + let p = Arc::new(true); + let x = Some(p); + match x { + Some(z) => { dispose(z); }, + None => panic!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/ambiguity-item.rs b/gcc/testsuite/rust/rustc/ui/binding/ambiguity-item.rs new file mode 100644 index 000000000000..ee1982b3ebd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/ambiguity-item.rs @@ -0,0 +1,20 @@ +// Identifier pattern referring to an ambiguity item is an error (issue #46079). + +mod m { + pub fn f() {} +} +use m::*; + +mod n { + pub fn f() {} +} +use n::*; // OK, no conflict with `use m::*;` + +fn main() { + let v = f; // { dg-error ".E0659." "" { target *-*-* } } + match v { + f => {} // { dg-error ".E0659." "" { target *-*-* } } + mut f => {} // OK, unambiguously a fresh binding due to `mut` + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/bind-field-short-with-modifiers.rs b/gcc/testsuite/rust/rustc/ui/binding/bind-field-short-with-modifiers.rs new file mode 100644 index 000000000000..ea5b3e006004 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/bind-field-short-with-modifiers.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(unused_assignments)] +#![allow(unused_variables)] +#![allow(non_shorthand_field_patterns)] + +pub fn main() { + struct Foo { x: isize, y: isize } + let mut f = Foo { x: 10, y: 0 }; + match f { + Foo { ref mut x, .. } => *x = 11, + } + match f { + Foo { ref x, ref y } => { + assert_eq!(f.x, 11); + assert_eq!(f.y, 0); + } + } + match f { + Foo { mut x, y: ref mut y } => { + x = 12; + *y = 1; + } + } + assert_eq!(f.x, 11); + assert_eq!(f.y, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-2.rs b/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-2.rs new file mode 100644 index 000000000000..1d711f9aed3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-2.rs @@ -0,0 +1,14 @@ +// run-pass + +fn foo(s: &String) -> bool { + match &**s { + "kitty" => true, + _ => false + } +} + +pub fn main() { + assert!(foo(&"kitty".to_string())); + assert!(!foo(&"gata".to_string())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-3.rs b/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-3.rs new file mode 100644 index 000000000000..75944e9b2654 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-3.rs @@ -0,0 +1,14 @@ +// run-pass + +fn foo<'r>(s: &'r usize) -> bool { + match s { + &3 => true, + _ => false + } +} + +pub fn main() { + assert!(foo(&3)); + assert!(!foo(&4)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-infallible.rs b/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-infallible.rs new file mode 100644 index 000000000000..ed8bfa43acf4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-infallible.rs @@ -0,0 +1,9 @@ +// run-pass + + +pub fn main() { + let (&x, &y) = (&3, &'a'); + assert_eq!(x, 3); + assert_eq!(y, 'a'); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-option.rs b/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-option.rs new file mode 100644 index 000000000000..c14a3b0b39d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern-option.rs @@ -0,0 +1,16 @@ +// run-pass + +fn select<'r>(x: &'r Option, y: &'r Option) -> &'r Option { + match (x, y) { + (&None, &None) => x, + (&Some(_), _) => x, + (&None, &Some(_)) => y + } +} + +pub fn main() { + let x = None; + let y = Some(3); + assert_eq!(select(&x, &y).unwrap(), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern.rs b/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern.rs new file mode 100644 index 000000000000..60112309da03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/borrowed-ptr-pattern.rs @@ -0,0 +1,13 @@ +// run-pass + +fn foo(x: &T) -> T{ + match x { + &ref a => (*a).clone() + } +} + +pub fn main() { + assert_eq!(foo(&3), 3); + assert_eq!(foo(&'a'), 'a'); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/const-param.rs b/gcc/testsuite/rust/rustc/ui/binding/const-param.rs new file mode 100644 index 000000000000..b4c66a0c7aee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/const-param.rs @@ -0,0 +1,13 @@ +// Identifier pattern referring to a const generic parameter is an error (issue #68853). + +#![feature(const_generics)] // { dg-warning "" "" { target *-*-* } } + +fn check() { + match 1 { + N => {} // { dg-error ".E0158." "" { target *-*-* } } + _ => {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/empty-types-in-patterns.rs b/gcc/testsuite/rust/rustc/ui/binding/empty-types-in-patterns.rs new file mode 100644 index 000000000000..5e3d45ec4616 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/empty-types-in-patterns.rs @@ -0,0 +1,60 @@ +// run-pass + +#![feature(never_type, never_type_fallback)] +#![feature(exhaustive_patterns)] + +#![allow(unreachable_patterns)] +#![allow(unreachable_code)] +#![allow(unused_variables)] + +#[allow(dead_code)] +fn foo(z: !) { + let x: Result = Ok(z); + + let Ok(_y) = x; + let Err(_y) = x; + + let x = [z; 1]; + + match x {}; + match x { + [q] => q, + }; +} + +fn bar(nevers: &[!]) { + match nevers { + &[] => (), + }; + + match nevers { + &[] => (), + &[_] => (), + &[_, _, _, ..] => (), + }; +} + +fn main() { + let x: Result = Ok(123); + let Ok(y) = x; + + assert_eq!(123, y); + + match x { + Ok(y) => y, + }; + + match x { + Ok(y) => y, + Err(e) => match e {}, + }; + + let x: Result = Ok(123); + match x { + Ok(y) => y, + Err(_) => unimplemented!(), + }; + + bar(&[]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/exhaustive-bool-match-sanity.rs b/gcc/testsuite/rust/rustc/ui/binding/exhaustive-bool-match-sanity.rs new file mode 100644 index 000000000000..ef2a29258812 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/exhaustive-bool-match-sanity.rs @@ -0,0 +1,23 @@ +// run-pass +// Issue #33540 +// We previously used to generate a 3-armed boolean `SwitchInt` in the +// MIR of the function `foo` below. #33583 changed rustc to +// generate an `If` terminator instead. This test is to just ensure +// sanity in that we generate an if-else chain giving the correct +// results. + +fn foo(x: bool, y: bool) -> u32 { + match (x, y) { + (false, _) => 0, + (_, false) => 1, + (true, true) => 2 + } +} + +fn main() { + assert_eq!(foo(false, true), 0); + assert_eq!(foo(false, false), 0); + assert_eq!(foo(true, false), 1); + assert_eq!(foo(true, true), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/expr-match-generic-unique1.rs b/gcc/testsuite/rust/rustc/ui/binding/expr-match-generic-unique1.rs new file mode 100644 index 000000000000..dfa59c8774f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/expr-match-generic-unique1.rs @@ -0,0 +1,20 @@ +// run-pass +#![feature(box_syntax)] + +fn test_generic(expected: Box, eq: F) where F: FnOnce(Box, Box) -> bool { + let actual: Box = match true { + true => { expected.clone() }, + _ => panic!("wat") + }; + assert!(eq(expected, actual)); +} + +fn test_box() { + fn compare_box(b1: Box, b2: Box) -> bool { + return *b1 == *b2; + } + test_generic::(box true, compare_box); +} + +pub fn main() { test_box(); } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/expr-match-generic-unique2.rs b/gcc/testsuite/rust/rustc/ui/binding/expr-match-generic-unique2.rs new file mode 100644 index 000000000000..3323967e3f35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/expr-match-generic-unique2.rs @@ -0,0 +1,18 @@ +// run-pass +#![feature(box_syntax)] + +fn test_generic(expected: T, eq: F) where F: FnOnce(T, T) -> bool { + let actual: T = match true { + true => expected.clone(), + _ => panic!("wat") + }; + assert!(eq(expected, actual)); +} + +fn test_vec() { + fn compare_box(v1: Box, v2: Box) -> bool { return v1 == v2; } + test_generic::, _>(box 1, compare_box); +} + +pub fn main() { test_vec(); } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/expr-match-generic.rs b/gcc/testsuite/rust/rustc/ui/binding/expr-match-generic.rs new file mode 100644 index 000000000000..1af11e3530af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/expr-match-generic.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(non_camel_case_types)] + +type compare = extern "Rust" fn(T, T) -> bool; + +fn test_generic(expected: T, eq: compare) { + let actual: T = match true { true => { expected.clone() }, _ => panic!("wat") }; + assert!((eq(expected, actual))); +} + +fn test_bool() { + fn compare_bool(b1: bool, b2: bool) -> bool { return b1 == b2; } + test_generic::(true, compare_bool); +} + +#[derive(Clone)] +struct Pair { + a: isize, + b: isize, +} + +fn test_rec() { + fn compare_rec(t1: Pair, t2: Pair) -> bool { + t1.a == t2.a && t1.b == t2.b + } + test_generic::(Pair {a: 1, b: 2}, compare_rec); +} + +pub fn main() { test_bool(); test_rec(); } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/expr-match-panic-all.rs b/gcc/testsuite/rust/rustc/ui/binding/expr-match-panic-all.rs new file mode 100644 index 000000000000..299f0323b6b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/expr-match-panic-all.rs @@ -0,0 +1,15 @@ +// run-pass + + + +// When all branches of a match expression result in panic, the entire +// match expression results in panic. + +pub fn main() { + let _x = + match true { + true => { 10 } + false => { match true { true => { panic!() } false => { panic!() } } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/expr-match-panic.rs b/gcc/testsuite/rust/rustc/ui/binding/expr-match-panic.rs new file mode 100644 index 000000000000..fe480410e275 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/expr-match-panic.rs @@ -0,0 +1,15 @@ +// run-pass + + +fn test_simple() { + let r = match true { true => { true } false => { panic!() } }; + assert_eq!(r, true); +} + +fn test_box() { + let r = match true { true => { vec![10] } false => { panic!() } }; + assert_eq!(r[0], 10); +} + +pub fn main() { test_simple(); test_box(); } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/expr-match-unique.rs b/gcc/testsuite/rust/rustc/ui/binding/expr-match-unique.rs new file mode 100644 index 000000000000..6c6bd0c6f171 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/expr-match-unique.rs @@ -0,0 +1,11 @@ +// run-pass +#![feature(box_syntax)] + +// Tests for match as expressions resulting in boxed types +fn test_box() { + let res: Box<_> = match true { true => { box 100 }, _ => panic!() }; + assert_eq!(*res, 100); +} + +pub fn main() { test_box(); } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/expr-match.rs b/gcc/testsuite/rust/rustc/ui/binding/expr-match.rs new file mode 100644 index 000000000000..c97d2a62f45b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/expr-match.rs @@ -0,0 +1,46 @@ +// run-pass + + + + +// Tests for using match as an expression + +fn test_basic() { + let mut rs: bool = match true { true => { true } false => { false } }; + assert!((rs)); + rs = match false { true => { false } false => { true } }; + assert!((rs)); +} + +fn test_inferrence() { + let rs = match true { true => { true } false => { false } }; + assert!((rs)); +} + +fn test_alt_as_alt_head() { + // Yeah, this is kind of confusing ... + + let rs = + match match false { true => { true } false => { false } } { + true => { false } + false => { true } + }; + assert!((rs)); +} + +fn test_alt_as_block_result() { + let rs = + match false { + true => { false } + false => { match true { true => { true } false => { false } } } + }; + assert!((rs)); +} + +pub fn main() { + test_basic(); + test_inferrence(); + test_alt_as_alt_head(); + test_alt_as_block_result(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/fat-arrow-match.rs b/gcc/testsuite/rust/rustc/ui/binding/fat-arrow-match.rs new file mode 100644 index 000000000000..dab9b83cf847 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/fat-arrow-match.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +enum color { + red, + green, + blue +} + +pub fn main() { + println!("{}", match color::red { + color::red => { 1 } + color::green => { 2 } + color::blue => { 3 } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/fn-arg-incomplete-pattern-drop-order.rs b/gcc/testsuite/rust/rustc/ui/binding/fn-arg-incomplete-pattern-drop-order.rs new file mode 100644 index 000000000000..01eeb79839e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/fn-arg-incomplete-pattern-drop-order.rs @@ -0,0 +1,70 @@ +// run-pass +// Check that partially moved from function parameters are dropped after the +// named bindings that move from them. + +// ignore-wasm32-bare compiled with panic=abort by default + +use std::{panic, cell::RefCell}; + +struct LogDrop<'a>(i32, Context<'a>); + +#[derive(Copy, Clone)] +struct Context<'a> { + panic_on: i32, + drops: &'a RefCell>, +} + +impl<'a> Context<'a> { + fn record_drop(self, index: i32) { + self.drops.borrow_mut().push(index); + if index == self.panic_on { + panic!(); + } + } +} + +impl<'a> Drop for LogDrop<'a> { + fn drop(&mut self) { + self.1.record_drop(self.0); + } +} + +fn bindings_in_params((_x, _): (LogDrop, LogDrop), (_, _y): (LogDrop, LogDrop)) {} +fn bindings_with_let(a: (LogDrop, LogDrop), b: (LogDrop, LogDrop)) { + // Drop order in foo is the same as the following bindings. + // _temp2 is declared after _x to avoid a difference between `_: T` and + // `x: T` in function parameters. + let _temp1 = a; + let (_x, _) = _temp1; + + let _temp2 = b; + let (_, _y) = _temp2; +} + +fn test_drop_order(panic_on: i32, fun: fn((LogDrop, LogDrop), (LogDrop, LogDrop))) { + let context = Context { + panic_on, + drops: &RefCell::new(Vec::new()), + }; + let one = LogDrop(1, context); + let two = LogDrop(2, context); + let three = LogDrop(3, context); + let four = LogDrop(4, context); + + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + fun((three, four), (two, one)); + })); + if panic_on == 0 { + assert!(res.is_ok(), "should not have panicked"); + } else { + assert!(res.is_err(), "should have panicked"); + } + assert_eq!(*context.drops.borrow(), [1, 2, 3, 4], "incorrect drop order"); +} + +fn main() { + (0..=4).for_each(|i| test_drop_order(i, bindings_in_params)); + (0..=4).for_each(|i| test_drop_order(i, bindings_with_let)); + (0..=4).for_each(|i| test_drop_order(i, |(_x, _), (_, _y)| {})); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/fn-pattern-expected-type-2.rs b/gcc/testsuite/rust/rustc/ui/binding/fn-pattern-expected-type-2.rs new file mode 100644 index 000000000000..f59c0d1a3187 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/fn-pattern-expected-type-2.rs @@ -0,0 +1,9 @@ +// run-pass +pub fn main() { + let v : &[(isize,isize)] = &[ (1, 2), (3, 4), (5, 6) ]; + for &(x, y) in v { + println!("{}", y); + println!("{}", x); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/fn-pattern-expected-type.rs b/gcc/testsuite/rust/rustc/ui/binding/fn-pattern-expected-type.rs new file mode 100644 index 000000000000..e12d05828285 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/fn-pattern-expected-type.rs @@ -0,0 +1,10 @@ +// run-pass + +pub fn main() { + let f = |(x, y): (isize, isize)| { + assert_eq!(x, 1); + assert_eq!(y, 2); + }; + f((1, 2)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/func-arg-incomplete-pattern.rs b/gcc/testsuite/rust/rustc/ui/binding/func-arg-incomplete-pattern.rs new file mode 100644 index 000000000000..1a909ef0a7f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/func-arg-incomplete-pattern.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] +// Test that we do not leak when the arg pattern must drop part of the +// argument (in this case, the `y` field). + +#![feature(box_syntax)] + +struct Foo { + x: Box, + y: Box, +} + +fn foo(Foo {x, ..}: Foo) -> *const usize { + let addr: *const usize = &*x; + addr +} + +pub fn main() { + let obj: Box<_> = box 1; + let objptr: *const usize = &*obj; + let f = Foo {x: obj, y: box 2}; + let xptr = foo(f); + assert_eq!(objptr, xptr); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/func-arg-ref-pattern.rs b/gcc/testsuite/rust/rustc/ui/binding/func-arg-ref-pattern.rs new file mode 100644 index 000000000000..56c6c76c1934 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/func-arg-ref-pattern.rs @@ -0,0 +1,28 @@ +// run-pass + +// Test argument patterns where we create refs to the inside of +// boxes. Make sure that we don't free the box as we match the +// pattern. + +#![feature(box_patterns)] +#![feature(box_syntax)] + +fn getaddr(box ref x: Box) -> *const usize { + let addr: *const usize = &*x; + addr +} + +fn checkval(box ref x: Box) -> usize { + *x +} + +pub fn main() { + let obj: Box<_> = box 1; + let objptr: *const usize = &*obj; + let xptr = getaddr(obj); + assert_eq!(objptr, xptr); + + let obj = box 22; + assert_eq!(checkval(obj), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/func-arg-wild-pattern.rs b/gcc/testsuite/rust/rustc/ui/binding/func-arg-wild-pattern.rs new file mode 100644 index 000000000000..597cd23256cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/func-arg-wild-pattern.rs @@ -0,0 +1,13 @@ +// run-pass +// Test that we can compile code that uses a `_` in function argument +// patterns. + + +fn foo((x, _): (isize, isize)) -> isize { + x +} + +pub fn main() { + assert_eq!(foo((22, 23)), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/if-let.rs b/gcc/testsuite/rust/rustc/ui/binding/if-let.rs new file mode 100644 index 000000000000..5715fd4dbbcb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/if-let.rs @@ -0,0 +1,61 @@ +// run-pass +#![allow(dead_code)] + +pub fn main() { + let x = Some(3); + if let Some(y) = x { + assert_eq!(y, 3); + } else { + panic!("if-let panicked"); + } + let mut worked = false; + if let Some(_) = x { + worked = true; + } + assert!(worked); + let clause: usize; + if let None = Some("test") { + clause = 1; + } else if 4_usize > 5 { + clause = 2; + } else if let Ok(()) = Err::<(),&'static str>("test") { + clause = 3; + } else { + clause = 4; + } + assert_eq!(clause, 4_usize); + + if 3 > 4 { + panic!("bad math"); + } else if let 1 = 2 { + panic!("bad pattern match"); + } + + enum Foo { + One, + Two(usize), + Three(String, isize) + } + + let foo = Foo::Three("three".to_string(), 42); + if let Foo::One = foo { + panic!("bad pattern match"); + } else if let Foo::Two(_x) = foo { + panic!("bad pattern match"); + } else if let Foo::Three(s, _) = foo { + assert_eq!(s, "three"); + } else { + panic!("bad else"); + } + + if false { + panic!("wat"); + } else if let a@Foo::Two(_) = Foo::Two(42_usize) { + if let Foo::Two(b) = a { + assert_eq!(b, 42_usize); + } else { + panic!("panic in nested if-let"); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/inconsistent-lifetime-mismatch.rs b/gcc/testsuite/rust/rustc/ui/binding/inconsistent-lifetime-mismatch.rs new file mode 100644 index 000000000000..9c58d8744650 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/inconsistent-lifetime-mismatch.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn foo(_: &[&str]) {} + +fn bad(a: &str, b: &str) { + foo(&[a, b]); +} + +fn good(a: &str, b: &str) { + foo(&[a, b]); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/inferred-suffix-in-pattern-range.rs b/gcc/testsuite/rust/rustc/ui/binding/inferred-suffix-in-pattern-range.rs new file mode 100644 index 000000000000..30cc7d00915f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/inferred-suffix-in-pattern-range.rs @@ -0,0 +1,25 @@ +// run-pass + +pub fn main() { + let x = 2; + let x_message = match x { + 0 ..= 1 => { "not many".to_string() } + _ => { "lots".to_string() } + }; + assert_eq!(x_message, "lots".to_string()); + + let y = 2; + let y_message = match y { + 0 ..= 1 => { "not many".to_string() } + _ => { "lots".to_string() } + }; + assert_eq!(y_message, "lots".to_string()); + + let z = 1u64; + let z_message = match z { + 0 ..= 1 => { "not many".to_string() } + _ => { "lots".to_string() } + }; + assert_eq!(z_message, "not many".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/irrefutable-slice-patterns.rs b/gcc/testsuite/rust/rustc/ui/binding/irrefutable-slice-patterns.rs new file mode 100644 index 000000000000..fb330fbedd8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/irrefutable-slice-patterns.rs @@ -0,0 +1,15 @@ +// run-pass + +// Regression test for #47096. + +fn foo(s: &[i32]) -> &[i32] { + let &[ref xs @ ..] = s; + xs +} + +fn main() { + let x = [1, 2, 3]; + let y = foo(&x); + assert_eq!(x, y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/issue-53114-borrow-checks.rs b/gcc/testsuite/rust/rustc/ui/binding/issue-53114-borrow-checks.rs new file mode 100644 index 000000000000..72d7096a66b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/issue-53114-borrow-checks.rs @@ -0,0 +1,85 @@ +// Issue #53114: NLL's borrow check had some deviations from the old borrow +// checker, and both had some deviations from our ideal state. This test +// captures the behavior of how `_` bindings are handled with respect to how we +// flag expressions that are meant to request unsafe blocks. +#![allow(irrefutable_let_patterns)] +struct M; + +fn let_wild_gets_moved_expr() { + let m = M; + drop(m); + let _ = m; // accepted, and want it to continue to be + + let mm = (M, M); // variation on above with `_` in substructure + let (_x, _) = mm; + let (_, _y) = mm; + let (_, _) = mm; +} + +fn match_moved_expr_to_wild() { + let m = M; + drop(m); + match m { _ => { } } // #53114: should eventually be accepted too +// { dg-error ".E0382." "" { target *-*-* } .-1 } + + let mm = (M, M); // variation on above with `_` in substructure + match mm { (_x, _) => { } } + match mm { (_, _y) => { } } +// { dg-error ".E0382." "" { target *-*-* } .-1 } + match mm { (_, _) => { } } +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn if_let_moved_expr_to_wild() { + let m = M; + drop(m); + if let _ = m { } // #53114: should eventually be accepted too +// { dg-error ".E0382." "" { target *-*-* } .-1 } + + let mm = (M, M); // variation on above with `_` in substructure + if let (_x, _) = mm { } + if let (_, _y) = mm { } +// { dg-error ".E0382." "" { target *-*-* } .-1 } + if let (_, _) = mm { } +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn let_wild_gets_borrowed_expr() { + let mut m = M; + let r = &mut m; + let _ = m; // accepted, and want it to continue to be + // let _x = m; // (compare with this error.) + drop(r); + + let mut mm = (M, M); // variation on above with `_` in substructure + let (r1, r2) = (&mut mm.0, &mut mm.1); + let (_, _) = mm; + drop((r1, r2)); +} + +fn match_borrowed_expr_to_wild() { + let mut m = M; + let r = &mut m; + match m { _ => {} } ; // accepted, and want it to continue to be + drop(r); + + let mut mm = (M, M); // variation on above with `_` in substructure + let (r1, r2) = (&mut mm.0, &mut mm.1); + match mm { (_, _) => { } } + drop((r1, r2)); +} + +fn if_let_borrowed_expr_to_wild() { + let mut m = M; + let r = &mut m; + if let _ = m { } // accepted, and want it to continue to be + drop(r); + + let mut mm = (M, M); // variation on above with `_` in substructure + let (r1, r2) = (&mut mm.0, &mut mm.1); + if let (_, _) = mm { } + drop((r1, r2)); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/issue-53114-safety-checks.rs b/gcc/testsuite/rust/rustc/ui/binding/issue-53114-safety-checks.rs new file mode 100644 index 000000000000..64d6becdf859 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/issue-53114-safety-checks.rs @@ -0,0 +1,52 @@ +// Issue #53114: NLL's borrow check had some deviations from the old borrow +// checker, and both had some deviations from our ideal state. This test +// captures the behavior of how `_` bindings are handled with respect to how we +// flag expressions that are meant to request unsafe blocks. + +#![feature(untagged_unions)] + +struct I(i64); +struct F(f64); + +union U { a: I, b: F } + +#[repr(packed)] +struct P { + a: &'static i8, + b: &'static u32, +} + +fn let_wild_gets_unsafe_field() { + let u1 = U { a: I(0) }; + let u2 = U { a: I(1) }; + let p = P { a: &2, b: &3 }; + let _ = &p.b; // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + let _ = u1.a; // #53114: should eventually signal error as well + let _ = &u2.a; // { dg-error ".E0133." "" { target *-*-* } } + + // variation on above with `_` in substructure + let (_,) = (&p.b,); // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + let (_,) = (u1.a,); // { dg-error ".E0133." "" { target *-*-* } } + let (_,) = (&u2.a,); // { dg-error ".E0133." "" { target *-*-* } } +} + +fn match_unsafe_field_to_wild() { + let u1 = U { a: I(0) }; + let u2 = U { a: I(1) }; + let p = P { a: &2, b: &3 }; + match &p.b { _ => { } } // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + match u1.a { _ => { } } // { dg-error ".E0133." "" { target *-*-* } } + match &u2.a { _ => { } } // { dg-error ".E0133." "" { target *-*-* } } + + // variation on above with `_` in substructure + match (&p.b,) { (_,) => { } } // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + match (u1.a,) { (_,) => { } } // { dg-error ".E0133." "" { target *-*-* } } + match (&u2.a,) { (_,) => { } } // { dg-error ".E0133." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/let-assignability.rs b/gcc/testsuite/rust/rustc/ui/binding/let-assignability.rs new file mode 100644 index 000000000000..4fea101104ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/let-assignability.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(box_syntax)] + +fn f() { + let a: Box<_> = box 1; + let b: &isize = &*a; + println!("{}", b); +} + +pub fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/let-destruct-ref.rs b/gcc/testsuite/rust/rustc/ui/binding/let-destruct-ref.rs new file mode 100644 index 000000000000..413a40783998 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/let-destruct-ref.rs @@ -0,0 +1,8 @@ +// run-pass + +pub fn main() { + let x = 3_usize; + let ref y = x; + assert_eq!(x, *y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/let-var-hygiene.rs b/gcc/testsuite/rust/rustc/ui/binding/let-var-hygiene.rs new file mode 100644 index 000000000000..3f9f4543b580 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/let-var-hygiene.rs @@ -0,0 +1,12 @@ +// run-pass +// shouldn't affect evaluation of $ex: + +macro_rules! bad_macro { + ($ex:expr) => ({let _x = 9; $ex}) +} + +pub fn main() { + let _x = 8; + assert_eq!(bad_macro!(_x),8) +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-arm-statics.rs b/gcc/testsuite/rust/rustc/ui/binding/match-arm-statics.rs new file mode 100644 index 000000000000..3ba7410ea9a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-arm-statics.rs @@ -0,0 +1,166 @@ +// run-pass +#![allow(dead_code)] +// compile-flags: -g +// ignore-asmjs wasm2js does not support source maps yet + +#[derive(PartialEq, Eq)] +struct NewBool(bool); + +#[derive(PartialEq, Eq)] +enum Direction { + North, + East, + South, + West +} + +#[derive(PartialEq, Eq)] +struct Foo { + bar: Option, + baz: NewBool +} + +#[derive(PartialEq, Eq)] +enum EnumWithStructVariants { + Variant1(bool), + Variant2 { + dir: Direction + } +} + +const TRUE_TRUE: (bool, bool) = (true, true); +const NONE: Option = None; +const EAST: Direction = Direction::East; +const NEW_FALSE: NewBool = NewBool(false); +const STATIC_FOO: Foo = Foo { bar: Some(Direction::South), baz: NEW_FALSE }; +const VARIANT2_NORTH: EnumWithStructVariants = EnumWithStructVariants::Variant2 { + dir: Direction::North }; + +pub mod glfw { + #[derive(Copy, Clone, PartialEq, Eq)] + pub struct InputState(usize); + + pub const RELEASE : InputState = InputState(0); + pub const PRESS : InputState = InputState(1); + pub const REPEAT : InputState = InputState(2); +} + +fn issue_6533() { + fn action_to_str(state: glfw::InputState) -> &'static str { + use glfw::{RELEASE, PRESS, REPEAT}; + match state { + RELEASE => { "Released" } + PRESS => { "Pressed" } + REPEAT => { "Repeated" } + _ => { "Unknown" } + } + } + + assert_eq!(action_to_str(glfw::RELEASE), "Released"); + assert_eq!(action_to_str(glfw::PRESS), "Pressed"); + assert_eq!(action_to_str(glfw::REPEAT), "Repeated"); +} + +fn issue_13626() { + const VAL: [u8; 1] = [0]; + match [1] { + VAL => unreachable!(), + _ => () + } +} + +fn issue_14576() { + type Foo = (i32, i32); + const ON: Foo = (1, 1); + const OFF: Foo = (0, 0); + + match (1, 1) { + OFF => unreachable!(), + ON => (), + _ => unreachable!() + } + + #[derive(PartialEq, Eq)] + enum C { D = 3, E = 4 } + const F : C = C::D; + + assert_eq!(match C::D { F => 1, _ => 2, }, 1); + + // test gaps + #[derive(PartialEq, Eq)] + enum G { H = 3, I = 5 } + const K : G = G::I; + + assert_eq!(match G::I { K => 1, _ => 2, }, 1); +} + +fn issue_13731() { + #[derive(PartialEq, Eq)] + enum A { AA(()) } + const B: A = A::AA(()); + + match A::AA(()) { + B => () + } +} + +fn issue_15393() { + #![allow(dead_code)] + #[derive(PartialEq, Eq)] + struct Flags { + bits: usize + } + + const FOO: Flags = Flags { bits: 0x01 }; + const BAR: Flags = Flags { bits: 0x02 }; + match (Flags { bits: 0x02 }) { + FOO => unreachable!(), + BAR => (), + _ => unreachable!() + } +} + +fn main() { + assert_eq!(match (true, false) { + TRUE_TRUE => 1, + (false, false) => 2, + (false, true) => 3, + (true, false) => 4 + }, 4); + + assert_eq!(match Some(Some(Direction::North)) { + Some(NONE) => 1, + Some(Some(Direction::North)) => 2, + Some(Some(EAST)) => 3, + Some(Some(Direction::South)) => 4, + Some(Some(Direction::West)) => 5, + None => 6 + }, 2); + + assert_eq!(match (Foo { bar: Some(Direction::West), baz: NewBool(true) }) { + Foo { bar: None, baz: NewBool(true) } => 1, + Foo { bar: NONE, baz: NEW_FALSE } => 2, + STATIC_FOO => 3, + Foo { bar: _, baz: NEW_FALSE } => 4, + Foo { bar: Some(Direction::West), baz: NewBool(true) } => 5, + Foo { bar: Some(Direction::South), baz: NewBool(true) } => 6, + Foo { bar: Some(EAST), .. } => 7, + Foo { bar: Some(Direction::North), baz: NewBool(true) } => 8 + }, 5); + + assert_eq!(match (EnumWithStructVariants::Variant2 { dir: Direction::North }) { + EnumWithStructVariants::Variant1(true) => 1, + EnumWithStructVariants::Variant1(false) => 2, + EnumWithStructVariants::Variant2 { dir: Direction::West } => 3, + VARIANT2_NORTH => 4, + EnumWithStructVariants::Variant2 { dir: Direction::South } => 5, + EnumWithStructVariants::Variant2 { dir: Direction::East } => 6 + }, 4); + + issue_6533(); + issue_13626(); + issue_13731(); + issue_14576(); + issue_15393(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-beginning-vert.rs b/gcc/testsuite/rust/rustc/ui/binding/match-beginning-vert.rs new file mode 100644 index 000000000000..90209a8e4e9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-beginning-vert.rs @@ -0,0 +1,20 @@ +// run-pass +enum Foo { + A, + B, + C, + D, + E, +} +use Foo::*; + +fn main() { + for foo in &[A, B, C, D, E] { + match *foo { + | A => println!("A"), + | B | C if 1 < 2 => println!("BC!"), + | _ => {}, + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-borrowed_str.rs b/gcc/testsuite/rust/rustc/ui/binding/match-borrowed_str.rs new file mode 100644 index 000000000000..42dbd87dd079 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-borrowed_str.rs @@ -0,0 +1,49 @@ +// run-pass + +fn f1(ref_string: &str) -> String { + match ref_string { + "a" => "found a".to_string(), + "b" => "found b".to_string(), + _ => "not found".to_string() + } +} + +fn f2(ref_string: &str) -> String { + match ref_string { + "a" => "found a".to_string(), + "b" => "found b".to_string(), + s => format!("not found ({})", s) + } +} + +fn g1(ref_1: &str, ref_2: &str) -> String { + match (ref_1, ref_2) { + ("a", "b") => "found a,b".to_string(), + ("b", "c") => "found b,c".to_string(), + _ => "not found".to_string() + } +} + +fn g2(ref_1: &str, ref_2: &str) -> String { + match (ref_1, ref_2) { + ("a", "b") => "found a,b".to_string(), + ("b", "c") => "found b,c".to_string(), + (s1, s2) => format!("not found ({}, {})", s1, s2) + } +} + +pub fn main() { + assert_eq!(f1("b"), "found b".to_string()); + assert_eq!(f1("c"), "not found".to_string()); + assert_eq!(f1("d"), "not found".to_string()); + assert_eq!(f2("b"), "found b".to_string()); + assert_eq!(f2("c"), "not found (c)".to_string()); + assert_eq!(f2("d"), "not found (d)".to_string()); + assert_eq!(g1("b", "c"), "found b,c".to_string()); + assert_eq!(g1("c", "d"), "not found".to_string()); + assert_eq!(g1("d", "e"), "not found".to_string()); + assert_eq!(g2("b", "c"), "found b,c".to_string()); + assert_eq!(g2("c", "d"), "not found (c, d)".to_string()); + assert_eq!(g2("d", "e"), "not found (d, e)".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-bot-2.rs b/gcc/testsuite/rust/rustc/ui/binding/match-bot-2.rs new file mode 100644 index 000000000000..8c5263606b96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-bot-2.rs @@ -0,0 +1,7 @@ +// run-pass +#![allow(unreachable_code)] +// n.b. This was only ever failing with optimization disabled. + +fn a() -> isize { match return 1 { 2 => 3, _ => panic!() } } +pub fn main() { a(); } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-bot.rs b/gcc/testsuite/rust/rustc/ui/binding/match-bot.rs new file mode 100644 index 000000000000..4802022d4927 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-bot.rs @@ -0,0 +1,8 @@ +// run-pass + +pub fn main() { + let i: isize = + match Some::(3) { None:: => { panic!() } Some::(_) => { 5 } }; + println!("{}", i); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-byte-array-patterns.rs b/gcc/testsuite/rust/rustc/ui/binding/match-byte-array-patterns.rs new file mode 100644 index 000000000000..13330dae009d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-byte-array-patterns.rs @@ -0,0 +1,45 @@ +// run-pass + +fn main() { + let buf = &[0u8; 4]; + match buf { + &[0, 1, 0, 0] => unimplemented!(), + b"true" => unimplemented!(), + _ => {} + } + + match buf { + b"true" => unimplemented!(), + &[0, 1, 0, 0] => unimplemented!(), + _ => {} + } + + match buf { + b"true" => unimplemented!(), + &[0, x, 0, 0] => assert_eq!(x, 0), + _ => unimplemented!(), + } + + let buf: &[u8] = buf; + + match buf { + &[0, 1, 0, 0] => unimplemented!(), + &[_] => unimplemented!(), + &[_, _, _, _, _, ..] => unimplemented!(), + b"true" => unimplemented!(), + _ => {} + } + + match buf { + b"true" => unimplemented!(), + &[0, 1, 0, 0] => unimplemented!(), + _ => {} + } + + match buf { + b"true" => unimplemented!(), + &[0, x, 0, 0] => assert_eq!(x, 0), + _ => unimplemented!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-enum-struct-0.rs b/gcc/testsuite/rust/rustc/ui/binding/match-enum-struct-0.rs new file mode 100644 index 000000000000..b86710853d40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-enum-struct-0.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +// regression test for issue #5625 + + +enum E { + Foo{f : isize}, + Bar +} + +pub fn main() { + let e = E::Bar; + match e { + E::Foo{f: _f} => panic!(), + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-enum-struct-1.rs b/gcc/testsuite/rust/rustc/ui/binding/match-enum-struct-1.rs new file mode 100644 index 000000000000..0ec3532d1e4f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-enum-struct-1.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] + +enum E { + Foo{f : isize}, + Bar +} + +pub fn main() { + let e = E::Foo{f: 1}; + match e { + E::Foo{..} => (), + _ => panic!(), + } + match e { + E::Foo{f: _f} => (), + _ => panic!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-implicit-copy-unique.rs b/gcc/testsuite/rust/rustc/ui/binding/match-implicit-copy-unique.rs new file mode 100644 index 000000000000..dd4f0bbc3224 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-implicit-copy-unique.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(non_shorthand_field_patterns)] +#![feature(box_syntax)] + +struct Pair { a: Box, b: Box } + +pub fn main() { + let mut x: Box<_> = box Pair {a: box 10, b: box 20}; + let x_internal = &mut *x; + match *x_internal { + Pair {a: ref mut a, b: ref mut _b} => { + assert_eq!(**a, 10); + *a = box 30; + assert_eq!(**a, 30); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-in-macro.rs b/gcc/testsuite/rust/rustc/ui/binding/match-in-macro.rs new file mode 100644 index 000000000000..5cba7a4d7f59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-in-macro.rs @@ -0,0 +1,18 @@ +// run-pass + +enum Foo { + B { b1: isize, bb1: isize}, +} + +macro_rules! match_inside_expansion { + () => ( + match (Foo::B { b1:29 , bb1: 100}) { + Foo::B { b1:b2 , bb1:bb2 } => b2+bb2 + } + ) +} + +pub fn main() { + assert_eq!(match_inside_expansion!(),129); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-join.rs b/gcc/testsuite/rust/rustc/ui/binding/match-join.rs new file mode 100644 index 000000000000..9c80d3846f53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-join.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(unused_mut)] +fn foo(y: Option) { + let mut x: isize; + let mut rs: Vec = Vec::new(); + /* tests that x doesn't get put in the precondition for the + entire if expression */ + + if true { + } else { + match y { + None:: => x = 17, + _ => x = 42 + } + rs.push(x); + } + return; +} + +pub fn main() { println!("hello"); foo::(Some::(5)); } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-larger-const.rs b/gcc/testsuite/rust/rustc/ui/binding/match-larger-const.rs new file mode 100644 index 000000000000..fb2a0a39d681 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-larger-const.rs @@ -0,0 +1,13 @@ +// run-pass +#[derive(Eq, PartialEq)] +pub struct Data([u8; 4]); + +const DATA: Data = Data([1, 2, 3, 4]); + +fn main() { + match DATA { + DATA => (), + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-naked-record-expr.rs b/gcc/testsuite/rust/rustc/ui/binding/match-naked-record-expr.rs new file mode 100644 index 000000000000..5aa03d655115 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-naked-record-expr.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct X { x: isize } + +pub fn main() { + let _x = match 0 { + _ => X { + x: 0 + }.x + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-naked-record.rs b/gcc/testsuite/rust/rustc/ui/binding/match-naked-record.rs new file mode 100644 index 000000000000..5dc9766607a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-naked-record.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct X { x: isize } + +pub fn main() { + let _x = match 0 { + _ => X { + x: 0 + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-path.rs b/gcc/testsuite/rust/rustc/ui/binding/match-path.rs new file mode 100644 index 000000000000..8feed27874a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-path.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + + +// pretty-expanded FIXME #23616 + +mod m1 { + pub enum foo { foo1, foo2, } +} + +fn bar(x: m1::foo) { match x { m1::foo::foo1 => { } m1::foo::foo2 => { } } } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-pattern-bindings.rs b/gcc/testsuite/rust/rustc/ui/binding/match-pattern-bindings.rs new file mode 100644 index 000000000000..748cee1fa87b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-pattern-bindings.rs @@ -0,0 +1,22 @@ +// run-pass + +fn main() { + let value = Some(1); + assert_eq!(match value { + ref a @ Some(_) => a, + ref b @ None => b + }, &Some(1)); + assert_eq!(match value { + ref c @ Some(_) => c, + ref b @ None => b + }, &Some(1)); + assert_eq!(match "foobarbaz" { + b @ _ => b + }, "foobarbaz"); + let a @ _ = "foobarbaz"; + assert_eq!(a, "foobarbaz"); + let value = Some(true); + let ref a @ _ = value; + assert_eq!(a, &Some(true)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-pattern-lit.rs b/gcc/testsuite/rust/rustc/ui/binding/match-pattern-lit.rs new file mode 100644 index 000000000000..ab200ab2400e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-pattern-lit.rs @@ -0,0 +1,16 @@ +// run-pass + + +fn altlit(f: isize) -> isize { + match f { + 10 => { println!("case 10"); return 20; } + 11 => { println!("case 11"); return 22; } + _ => panic!("the impossible happened") + } +} + +pub fn main() { + assert_eq!(altlit(10), 20); + assert_eq!(altlit(11), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-pattern-no-type-params.rs b/gcc/testsuite/rust/rustc/ui/binding/match-pattern-no-type-params.rs new file mode 100644 index 000000000000..9a37c4dfa76b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-pattern-no-type-params.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +enum maybe { nothing, just(T), } + +fn foo(x: maybe) { + match x { + maybe::nothing => { println!("A"); } + maybe::just(_a) => { println!("B"); } + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-pattern-simple.rs b/gcc/testsuite/rust/rustc/ui/binding/match-pattern-simple.rs new file mode 100644 index 000000000000..ef91f5106d78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-pattern-simple.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(dead_code)] + + +// pretty-expanded FIXME #23616 + +fn altsimple(f: isize) { match f { _x => () } } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-phi.rs b/gcc/testsuite/rust/rustc/ui/binding/match-phi.rs new file mode 100644 index 000000000000..ea27a9e85dcf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-phi.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_assignments)] +// pretty-expanded FIXME #23616 +#![allow(non_camel_case_types)] +#![allow(unused_variables)] + +enum thing { a, b, c, } + +fn foo(it: F) where F: FnOnce(isize) { it(10); } + +pub fn main() { + let mut x = true; + match thing::a { + thing::a => { x = true; foo(|_i| { } ) } + thing::b => { x = false; } + thing::c => { x = false; } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-pipe-binding.rs b/gcc/testsuite/rust/rustc/ui/binding/match-pipe-binding.rs new file mode 100644 index 000000000000..aadefe6148a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-pipe-binding.rs @@ -0,0 +1,61 @@ +// run-pass + +fn test1() { + // from issue 6338 + match ((1, "a".to_string()), (2, "b".to_string())) { + ((1, a), (2, b)) | ((2, b), (1, a)) => { + assert_eq!(a, "a".to_string()); + assert_eq!(b, "b".to_string()); + }, + _ => panic!(), + } +} + +fn test2() { + match (1, 2, 3) { + (1, a, b) | (2, b, a) => { + assert_eq!(a, 2); + assert_eq!(b, 3); + }, + _ => panic!(), + } +} + +fn test3() { + match (1, 2, 3) { + (1, ref a, ref b) | (2, ref b, ref a) => { + assert_eq!(*a, 2); + assert_eq!(*b, 3); + }, + _ => panic!(), + } +} + +fn test4() { + match (1, 2, 3) { + (1, a, b) | (2, b, a) if a == 2 => { + assert_eq!(a, 2); + assert_eq!(b, 3); + }, + _ => panic!(), + } +} + +fn test5() { + match (1, 2, 3) { + (1, ref a, ref b) | (2, ref b, ref a) if *a == 2 => { + assert_eq!(*a, 2); + assert_eq!(*b, 3); + }, + _ => panic!(), + } +} + +pub fn main() { + test1(); + test2(); + test3(); + test4(); + test5(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-range-infer.rs b/gcc/testsuite/rust/rustc/ui/binding/match-range-infer.rs new file mode 100644 index 000000000000..3173e90a56a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-range-infer.rs @@ -0,0 +1,18 @@ +// run-pass +// Test that type inference for range patterns works correctly (is bi-directional). + +pub fn main() { + match 1 { + 1 ..= 3 => {} + _ => panic!("should match range") + } + match 1 { + 1 ..= 3u16 => {} + _ => panic!("should match range with inferred start type") + } + match 1 { + 1u16 ..= 3 => {} + _ => panic!("should match range with inferred end type") + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-range-static.rs b/gcc/testsuite/rust/rustc/ui/binding/match-range-static.rs new file mode 100644 index 000000000000..8da044bce058 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-range-static.rs @@ -0,0 +1,14 @@ +// run-pass +// pretty-expanded FIXME #23616 +#![allow(non_upper_case_globals)] + +const s: isize = 1; +const e: isize = 42; + +pub fn main() { + match 7 { + s..=e => (), + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-range.rs b/gcc/testsuite/rust/rustc/ui/binding/match-range.rs new file mode 100644 index 000000000000..0b608c455304 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-range.rs @@ -0,0 +1,52 @@ +// run-pass +#![allow(illegal_floating_point_literal_pattern)] // FIXME #41620 +#![feature(exclusive_range_pattern)] + +pub fn main() { + match 5_usize { + 1_usize..=5_usize => {} + _ => panic!("should match range"), + } + match 1_usize { + 1_usize..5_usize => {} + _ => panic!("should match range start"), + } + match 5_usize { + 6_usize..=7_usize => panic!("shouldn't match range"), + _ => {} + } + match 7_usize { + 6_usize..7_usize => panic!("shouldn't match range end"), + _ => {}, + } + match 5_usize { + 1_usize => panic!("should match non-first range"), + 2_usize..=6_usize => {} + _ => panic!("math is broken") + } + match 'c' { + 'a'..='z' => {} + _ => panic!("should support char ranges") + } + match -3 { + -7..=5 => {} + _ => panic!("should match signed range") + } + match 3.0f64 { + 1.0..=5.0 => {} + _ => panic!("should match float range") + } + match -1.5f64 { + -3.6..=3.6 => {} + _ => panic!("should match negative float range") + } + match 3.5 { + 0.0..3.5 => panic!("should not match the range end"), + _ => {}, + } + match 0.0 { + 0.0..3.5 => {}, + _ => panic!("should match the range start"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-reassign.rs b/gcc/testsuite/rust/rustc/ui/binding/match-reassign.rs new file mode 100644 index 000000000000..c48d3b4ae81d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-reassign.rs @@ -0,0 +1,22 @@ +// run-pass +// Regression test for #23698: The reassignment checker only cared +// about the last assignment in a match arm body + +// Use an extra function to make sure no extra assignments +// are introduced by macros in the match statement +fn check_eq(x: i32, y: i32) { + assert_eq!(x, y); +} + +#[allow(unused_assignments)] +fn main() { + let mut x = Box::new(1); + match x { + y => { + x = Box::new(2); + let _tmp = 1; // This assignment used to throw off the reassignment checker + check_eq(*y, 1); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-ref-binding-in-guard-3256.rs b/gcc/testsuite/rust/rustc/ui/binding/match-ref-binding-in-guard-3256.rs new file mode 100644 index 000000000000..734470575bf6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-ref-binding-in-guard-3256.rs @@ -0,0 +1,14 @@ +// run-pass + +use std::sync::Mutex; + +pub fn main() { + let x = Some(Mutex::new(true)); + match x { + Some(ref z) if *z.lock().unwrap() => { + assert!(*z.lock().unwrap()); + }, + _ => panic!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-ref-binding-mut-option.rs b/gcc/testsuite/rust/rustc/ui/binding/match-ref-binding-mut-option.rs new file mode 100644 index 000000000000..eb7de31ac0e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-ref-binding-mut-option.rs @@ -0,0 +1,11 @@ +// run-pass + +pub fn main() { + let mut v = Some(22); + match v { + None => {} + Some(ref mut p) => { *p += 1; } + } + assert_eq!(v, Some(23)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-ref-binding-mut.rs b/gcc/testsuite/rust/rustc/ui/binding/match-ref-binding-mut.rs new file mode 100644 index 000000000000..9a6600eea4a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-ref-binding-mut.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(non_shorthand_field_patterns)] + +struct Rec { + f: isize +} + +fn destructure(x: &mut Rec) { + match *x { + Rec {f: ref mut f} => *f += 1 + } +} + +pub fn main() { + let mut v = Rec {f: 22}; + destructure(&mut v); + assert_eq!(v.f, 23); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-ref-binding.rs b/gcc/testsuite/rust/rustc/ui/binding/match-ref-binding.rs new file mode 100644 index 000000000000..c57334e0cd44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-ref-binding.rs @@ -0,0 +1,13 @@ +// run-pass + +fn destructure(x: Option) -> isize { + match x { + None => 0, + Some(ref v) => *v + } +} + +pub fn main() { + assert_eq!(destructure(Some(22)), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-ref-unsized.rs b/gcc/testsuite/rust/rustc/ui/binding/match-ref-unsized.rs new file mode 100644 index 000000000000..770b339cc770 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-ref-unsized.rs @@ -0,0 +1,12 @@ +// run-pass +// Binding unsized expressions to ref patterns + +pub fn main() { + let ref a = *"abcdef"; + assert_eq!(a, "abcdef"); + + match *"12345" { + ref b => { assert_eq!(b, "12345") } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-str.rs b/gcc/testsuite/rust/rustc/ui/binding/match-str.rs new file mode 100644 index 000000000000..c76e6451b9d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-str.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +// Issue #53 +#![allow(non_camel_case_types)] + + +pub fn main() { + match "test" { "not-test" => panic!(), "test" => (), _ => panic!() } + + enum t { tag1(String), tag2, } + + + match t::tag1("test".to_string()) { + t::tag2 => panic!(), + t::tag1(ref s) if "test" != &**s => panic!(), + t::tag1(ref s) if "test" == &**s => (), + _ => panic!() + } + + let x = match "a" { "a" => 1, "b" => 2, _ => panic!() }; + assert_eq!(x, 1); + + match "a" { "a" => { } "b" => { }, _ => panic!() } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-struct-0.rs b/gcc/testsuite/rust/rustc/ui/binding/match-struct-0.rs new file mode 100644 index 000000000000..495c044299f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-struct-0.rs @@ -0,0 +1,22 @@ +// run-pass + +struct Foo{ + f : isize, +} + +pub fn main() { + let f = Foo{f: 1}; + match f { + Foo{f: 0} => panic!(), + Foo{..} => (), + } + match f { + Foo{f: 0} => panic!(), + Foo{f: _f} => (), + } + match f { + Foo{f: 0} => panic!(), + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-tag.rs b/gcc/testsuite/rust/rustc/ui/binding/match-tag.rs new file mode 100644 index 000000000000..5154c41299f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-tag.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(unused_mut)] +#![allow(non_camel_case_types)] + + + +enum color { + rgb(isize, isize, isize), + rgba(isize, isize, isize, isize), + hsl(isize, isize, isize), +} + +fn process(c: color) -> isize { + let mut x: isize; + match c { + color::rgb(r, _, _) => { x = r; } + color::rgba(_, _, _, a) => { x = a; } + color::hsl(_, s, _) => { x = s; } + } + return x; +} + +pub fn main() { + let gray: color = color::rgb(127, 127, 127); + let clear: color = color::rgba(50, 150, 250, 0); + let red: color = color::hsl(0, 255, 255); + assert_eq!(process(gray), 127); + assert_eq!(process(clear), 0); + assert_eq!(process(red), 255); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-unique-bind.rs b/gcc/testsuite/rust/rustc/ui/binding/match-unique-bind.rs new file mode 100644 index 000000000000..e008e78cc942 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-unique-bind.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(box_patterns)] +#![feature(box_syntax)] + +pub fn main() { + match box 100 { + box x => { + println!("{}", x); + assert_eq!(x, 100); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-unsized.rs b/gcc/testsuite/rust/rustc/ui/binding/match-unsized.rs new file mode 100644 index 000000000000..91c9924234a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-unsized.rs @@ -0,0 +1,10 @@ +// run-pass +fn main() { + let data: &'static str = "Hello, World!"; + match data { + &ref xs => { + assert_eq!(data, xs); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-value-binding-in-guard-3291.rs b/gcc/testsuite/rust/rustc/ui/binding/match-value-binding-in-guard-3291.rs new file mode 100644 index 000000000000..a5a9a4711474 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-value-binding-in-guard-3291.rs @@ -0,0 +1,20 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +fn foo(x: Option>, b: bool) -> isize { + match x { + None => { 1 } + Some(ref x) if b => { *x.clone() } + Some(_) => { 0 } + } +} + +pub fn main() { + foo(Some(box 22), true); + foo(Some(box 22), false); + foo(None, true); + foo(None, false); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-var-hygiene.rs b/gcc/testsuite/rust/rustc/ui/binding/match-var-hygiene.rs new file mode 100644 index 000000000000..0293f6a0dc1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-var-hygiene.rs @@ -0,0 +1,12 @@ +// run-pass +// shouldn't affect evaluation of $ex. +macro_rules! bad_macro { ($ex:expr) => ( + {match 9 {_x => $ex}} +)} + +fn main() { + match 8 { + _x => assert_eq!(bad_macro!(_x),8) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-vec-alternatives.rs b/gcc/testsuite/rust/rustc/ui/binding/match-vec-alternatives.rs new file mode 100644 index 000000000000..da9e59f88882 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-vec-alternatives.rs @@ -0,0 +1,81 @@ +// run-pass + +fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) -> &'static str { + match (l1, l2) { + (&[], &[]) => "both empty", + (&[], &[..]) | (&[..], &[]) => "one empty", + (&[..], &[..]) => "both non-empty" + } +} + +fn match_vecs_cons<'a, T>(l1: &'a [T], l2: &'a [T]) -> &'static str { + match (l1, l2) { + (&[], &[]) => "both empty", + (&[], &[_, ..]) | (&[_, ..], &[]) => "one empty", + (&[_, ..], &[_, ..]) => "both non-empty" + } +} + +fn match_vecs_snoc<'a, T>(l1: &'a [T], l2: &'a [T]) -> &'static str { + match (l1, l2) { + (&[], &[]) => "both empty", + (&[], &[.., _]) | (&[.., _], &[]) => "one empty", + (&[.., _], &[.., _]) => "both non-empty" + } +} + +fn match_nested_vecs_cons<'a, T>(l1: Option<&'a [T]>, l2: Result<&'a [T], ()>) -> &'static str { + match (l1, l2) { + (Some(&[]), Ok(&[])) => "Some(empty), Ok(empty)", + (Some(&[_, ..]), Ok(_)) | (Some(&[_, ..]), Err(())) => "Some(non-empty), any", + (None, Ok(&[])) | (None, Err(())) | (None, Ok(&[_])) => "None, Ok(less than one element)", + (None, Ok(&[_, _, ..])) => "None, Ok(at least two elements)", + _ => "other" + } +} + +fn match_nested_vecs_snoc<'a, T>(l1: Option<&'a [T]>, l2: Result<&'a [T], ()>) -> &'static str { + match (l1, l2) { + (Some(&[]), Ok(&[])) => "Some(empty), Ok(empty)", + (Some(&[.., _]), Ok(_)) | (Some(&[.., _]), Err(())) => "Some(non-empty), any", + (None, Ok(&[])) | (None, Err(())) | (None, Ok(&[_])) => "None, Ok(less than one element)", + (None, Ok(&[.., _, _])) => "None, Ok(at least two elements)", + _ => "other" + } +} + +fn main() { + assert_eq!(match_vecs(&[1, 2], &[2, 3]), "both non-empty"); + assert_eq!(match_vecs(&[], &[1, 2, 3, 4]), "one empty"); + assert_eq!(match_vecs::(&[], &[]), "both empty"); + assert_eq!(match_vecs(&[1, 2, 3], &[]), "one empty"); + + assert_eq!(match_vecs_cons(&[1, 2], &[2, 3]), "both non-empty"); + assert_eq!(match_vecs_cons(&[], &[1, 2, 3, 4]), "one empty"); + assert_eq!(match_vecs_cons::(&[], &[]), "both empty"); + assert_eq!(match_vecs_cons(&[1, 2, 3], &[]), "one empty"); + + assert_eq!(match_vecs_snoc(&[1, 2], &[2, 3]), "both non-empty"); + assert_eq!(match_vecs_snoc(&[], &[1, 2, 3, 4]), "one empty"); + assert_eq!(match_vecs_snoc::(&[], &[]), "both empty"); + assert_eq!(match_vecs_snoc(&[1, 2, 3], &[]), "one empty"); + + assert_eq!(match_nested_vecs_cons(None, Ok::<&[_], ()>(&[4_usize, 2_usize])), + "None, Ok(at least two elements)"); + assert_eq!(match_nested_vecs_cons::(None, Err(())), "None, Ok(less than one element)"); + assert_eq!(match_nested_vecs_cons::(Some::<&[_]>(&[]), Ok::<&[_], ()>(&[])), + "Some(empty), Ok(empty)"); + assert_eq!(match_nested_vecs_cons(Some::<&[_]>(&[1]), Err(())), "Some(non-empty), any"); + assert_eq!(match_nested_vecs_cons(Some::<&[_]>(&[(42, ())]), Ok::<&[_], ()>(&[(1, ())])), + "Some(non-empty), any"); + + assert_eq!(match_nested_vecs_snoc(None, Ok::<&[_], ()>(&[4_usize, 2_usize])), + "None, Ok(at least two elements)"); + assert_eq!(match_nested_vecs_snoc::(None, Err(())), "None, Ok(less than one element)"); + assert_eq!(match_nested_vecs_snoc::(Some::<&[_]>(&[]), Ok::<&[_], ()>(&[])), + "Some(empty), Ok(empty)"); + assert_eq!(match_nested_vecs_snoc(Some::<&[_]>(&[1]), Err(())), "Some(non-empty), any"); + assert_eq!(match_nested_vecs_snoc(Some::<&[_]>(&[(42, ())]), Ok::<&[_], ()>(&[(1, ())])), + "Some(non-empty), any"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-vec-rvalue.rs b/gcc/testsuite/rust/rustc/ui/binding/match-vec-rvalue.rs new file mode 100644 index 000000000000..869290fe0757 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-vec-rvalue.rs @@ -0,0 +1,16 @@ +// run-pass +// Tests that matching rvalues with drops does not crash. + + + +pub fn main() { + match vec![1, 2, 3] { + x => { + assert_eq!(x.len(), 3); + assert_eq!(x[0], 1); + assert_eq!(x[1], 2); + assert_eq!(x[2], 3); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/match-with-ret-arm.rs b/gcc/testsuite/rust/rustc/ui/binding/match-with-ret-arm.rs new file mode 100644 index 000000000000..85f484e490f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/match-with-ret-arm.rs @@ -0,0 +1,13 @@ +// run-pass +pub fn main() { + // sometimes we have had trouble finding + // the right type for f, as we unified + // bot and u32 here + let f = match "1234".parse::().ok() { + None => return (), + Some(num) => num as u32 + }; + assert_eq!(f, 1234); + println!("{}", f) +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/multi-let.rs b/gcc/testsuite/rust/rustc/ui/binding/multi-let.rs new file mode 100644 index 000000000000..78dbeba1581a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/multi-let.rs @@ -0,0 +1,8 @@ +// run-pass + +pub fn main() { + let x = 10; + let y = x; + assert_eq!(y, 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/mut-in-ident-patterns.rs b/gcc/testsuite/rust/rustc/ui/binding/mut-in-ident-patterns.rs new file mode 100644 index 000000000000..9c6477e46f07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/mut-in-ident-patterns.rs @@ -0,0 +1,77 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_assignments)] +#![allow(non_camel_case_types)] +#![allow(non_shorthand_field_patterns)] + +trait Foo { + fn foo(&self, mut x: isize) -> isize { + let val = x; + x = 37 * x; + val + x + } +} + +struct X; +impl Foo for X {} + +pub fn main() { + let (a, mut b) = (23, 4); + assert_eq!(a, 23); + assert_eq!(b, 4); + b = a + b; + assert_eq!(b, 27); + + + assert_eq!(X.foo(2), 76); + + enum Bar { + Foo(isize), + Baz(f32, u8) + } + + let (x, mut y) = (32, Bar::Foo(21)); + + match x { + mut z @ 32 => { + assert_eq!(z, 32); + z = 34; + assert_eq!(z, 34); + } + _ => {} + } + + check_bar(&y); + y = Bar::Baz(10.0, 3); + check_bar(&y); + + fn check_bar(y: &Bar) { + match y { + &Bar::Foo(a) => { + assert_eq!(a, 21); + } + &Bar::Baz(a, b) => { + assert_eq!(a, 10.0); + assert_eq!(b, 3); + } + } + } + + fn foo1((x, mut y): (f64, isize), mut z: isize) -> isize { + y = 2 * 6; + z = y + (x as isize); + y - z + } + + struct A { + x: isize + } + let A { x: mut x } = A { x: 10 }; + assert_eq!(x, 10); + x = 30; + assert_eq!(x, 30); + + (|A { x: mut t }: A| { t = t+1; t })(A { x: 34 }); + +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/nested-matchs.rs b/gcc/testsuite/rust/rustc/ui/binding/nested-matchs.rs new file mode 100644 index 000000000000..31e0468d63df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/nested-matchs.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(unused_mut)] // under NLL we get warning about `bar` below +fn baz() -> ! { panic!(); } + +fn foo() { + match Some::(5) { + Some::(_x) => { + let mut bar; + match None:: { None:: => { bar = 5; } _ => { baz(); } } + println!("{}", bar); + } + None:: => { println!("hello"); } + } +} + +pub fn main() { foo(); } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/nested-pattern.rs b/gcc/testsuite/rust/rustc/ui/binding/nested-pattern.rs new file mode 100644 index 000000000000..fbabd6a65a1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/nested-pattern.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// a bug was causing this to complain about leaked memory on exit + +enum t { foo(isize, usize), bar(isize, Option), } + +fn nested(o: t) { + match o { + t::bar(_i, Some::(_)) => { println!("wrong pattern matched"); panic!(); } + _ => { println!("succeeded"); } + } +} + +pub fn main() { nested(t::bar(1, None::)); } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/nil-pattern.rs b/gcc/testsuite/rust/rustc/ui/binding/nil-pattern.rs new file mode 100644 index 000000000000..976bf92f74b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/nil-pattern.rs @@ -0,0 +1,5 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { let x = (); match x { () => { } } } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/nullary-or-pattern.rs b/gcc/testsuite/rust/rustc/ui/binding/nullary-or-pattern.rs new file mode 100644 index 000000000000..a9031e11275f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/nullary-or-pattern.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(non_camel_case_types)] + +enum blah { a, b, } + +fn or_alt(q: blah) -> isize { + match q { blah::a | blah::b => { 42 } } +} + +pub fn main() { + assert_eq!(or_alt(blah::a), 42); + assert_eq!(or_alt(blah::b), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/optional_comma_in_match_arm.rs b/gcc/testsuite/rust/rustc/ui/binding/optional_comma_in_match_arm.rs new file mode 100644 index 000000000000..fd0e504f35ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/optional_comma_in_match_arm.rs @@ -0,0 +1,41 @@ +// run-pass +#![allow(unused_unsafe)] +// ignore-pretty issue #37199 +#![allow(while_true)] + +fn main() { + let x = 1; + + match x { + 1 => loop { break; }, + 2 => while true { break; }, + 3 => if true { () }, + 4 => if true { () } else { () }, + 5 => match () { () => () }, + 6 => { () }, + 7 => unsafe { () }, + _ => (), + } + + match x { + 1 => loop { break; } + 2 => while true { break; } + 3 => if true { () } + 4 => if true { () } else { () } + 5 => match () { () => () } + 6 => { () } + 7 => unsafe { () } + _ => () + } + + let r: &i32 = &x; + + match r { + // Absence of comma should not cause confusion between a pattern + // and a bitwise and. + &1 => if true { () } else { () } + &2 => (), + _ =>() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/or-pattern.rs b/gcc/testsuite/rust/rustc/ui/binding/or-pattern.rs new file mode 100644 index 000000000000..f60f2a8d58fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/or-pattern.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(non_camel_case_types)] + +enum blah { a(isize, isize, usize), b(isize, isize), c, } + +fn or_alt(q: blah) -> isize { + match q { blah::a(x, y, _) | blah::b(x, y) => { return x + y; } blah::c => { return 0; } } +} + +pub fn main() { + assert_eq!(or_alt(blah::c), 0); + assert_eq!(or_alt(blah::a(10, 100, 0)), 110); + assert_eq!(or_alt(blah::b(20, 200)), 220); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/order-drop-with-match.rs b/gcc/testsuite/rust/rustc/ui/binding/order-drop-with-match.rs new file mode 100644 index 000000000000..52cac539e08c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/order-drop-with-match.rs @@ -0,0 +1,58 @@ +// run-pass + +// Test to make sure the destructors run in the right order. +// Each destructor sets it's tag in the corresponding entry +// in ORDER matching up to when it ran. +// Correct order is: matched, inner, outer + + +static mut ORDER: [usize; 3] = [0, 0, 0]; +static mut INDEX: usize = 0; + +struct A; +impl Drop for A { + fn drop(&mut self) { + unsafe { + ORDER[INDEX] = 1; + INDEX = INDEX + 1; + } + } +} + +struct B; +impl Drop for B { + fn drop(&mut self) { + unsafe { + ORDER[INDEX] = 2; + INDEX = INDEX + 1; + } + } +} + +struct C; +impl Drop for C { + fn drop(&mut self) { + unsafe { + ORDER[INDEX] = 3; + INDEX = INDEX + 1; + } + } +} + +fn main() { + { + let matched = A; + let _outer = C; + { + match matched { + _s => {} + } + let _inner = B; + } + } + unsafe { + let expected: &[_] = &[1, 2, 3]; + assert_eq!(expected, ORDER); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/pat-ranges.rs b/gcc/testsuite/rust/rustc/ui/binding/pat-ranges.rs new file mode 100644 index 000000000000..02ad80a45ae2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/pat-ranges.rs @@ -0,0 +1,21 @@ +// run-pass +// Parsing of range patterns + +#![allow(ellipsis_inclusive_range_patterns)] + +const NUM1: i32 = 10; + +mod m { + pub const NUM2: i32 = 16; +} + +fn main() { + if let NUM1 ... m::NUM2 = 10 {} else { panic!() } + if let ::NUM1 ... ::m::NUM2 = 11 {} else { panic!() } + if let -13 ... -10 = 12 { panic!() } else {} + + if let NUM1 ..= m::NUM2 = 10 {} else { panic!() } + if let ::NUM1 ..= ::m::NUM2 = 11 {} else { panic!() } + if let -13 ..= -10 = 12 { panic!() } else {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-1.rs b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-1.rs new file mode 100644 index 000000000000..043e8ce6640b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-1.rs @@ -0,0 +1,94 @@ +// run-pass +fn tuple() { + let x = (1, 2, 3); + match x { + (a, b, ..) => { + assert_eq!(a, 1); + assert_eq!(b, 2); + } + } + match x { + (.., b, c) => { + assert_eq!(b, 2); + assert_eq!(c, 3); + } + } + match x { + (a, .., c) => { + assert_eq!(a, 1); + assert_eq!(c, 3); + } + } + match x { + (a, b, c) => { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + } + } + match x { + (a, b, c, ..) => { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + } + } + match x { + (.., a, b, c) => { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + } + } +} + +fn tuple_struct() { + struct S(u8, u8, u8); + + let x = S(1, 2, 3); + match x { + S(a, b, ..) => { + assert_eq!(a, 1); + assert_eq!(b, 2); + } + } + match x { + S(.., b, c) => { + assert_eq!(b, 2); + assert_eq!(c, 3); + } + } + match x { + S(a, .., c) => { + assert_eq!(a, 1); + assert_eq!(c, 3); + } + } + match x { + S(a, b, c) => { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + } + } + match x { + S(a, b, c, ..) => { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + } + } + match x { + S(.., a, b, c) => { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + } + } +} + +fn main() { + tuple(); + tuple_struct(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-2.rs b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-2.rs new file mode 100644 index 000000000000..f3aca577109e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-2.rs @@ -0,0 +1,24 @@ +// run-pass +fn tuple() { + let x = (1,); + match x { + (2, ..) => panic!(), + (..) => () + } +} + +fn tuple_struct() { + struct S(u8); + + let x = S(1); + match x { + S(2, ..) => panic!(), + S(..) => () + } +} + +fn main() { + tuple(); + tuple_struct(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-3.rs b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-3.rs new file mode 100644 index 000000000000..e52c7b4531d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-3.rs @@ -0,0 +1,30 @@ +// run-pass +fn tuple() { + let x = (1, 2, 3); + let branch = match x { + (1, 1, ..) => 0, + (1, 2, 3, ..) => 1, + (1, 2, ..) => 2, + _ => 3 + }; + assert_eq!(branch, 1); +} + +fn tuple_struct() { + struct S(u8, u8, u8); + + let x = S(1, 2, 3); + let branch = match x { + S(1, 1, ..) => 0, + S(1, 2, 3, ..) => 1, + S(1, 2, ..) => 2, + _ => 3 + }; + assert_eq!(branch, 1); +} + +fn main() { + tuple(); + tuple_struct(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-4.rs b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-4.rs new file mode 100644 index 000000000000..b93834ece0e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-4.rs @@ -0,0 +1,58 @@ +// run-pass +fn tuple() { + let x = (1, 2, 3); + match x { + (1, 2, 4) => unreachable!(), + (0, 2, 3, ..) => unreachable!(), + (0, .., 3) => unreachable!(), + (0, ..) => unreachable!(), + (1, 2, 3) => (), + (_, _, _) => unreachable!(), + } + match x { + (..) => (), + } + match x { + (_, _, _, ..) => (), + } + match x { + (a, b, c) => { + assert_eq!(1, a); + assert_eq!(2, b); + assert_eq!(3, c); + } + } +} + +fn tuple_struct() { + struct S(u8, u8, u8); + + let x = S(1, 2, 3); + match x { + S(1, 2, 4) => unreachable!(), + S(0, 2, 3, ..) => unreachable!(), + S(0, .., 3) => unreachable!(), + S(0, ..) => unreachable!(), + S(1, 2, 3) => (), + S(_, _, _) => unreachable!(), + } + match x { + S(..) => (), + } + match x { + S(_, _, _, ..) => (), + } + match x { + S(a, b, c) => { + assert_eq!(1, a); + assert_eq!(2, b); + assert_eq!(3, c); + } + } +} + +fn main() { + tuple(); + tuple_struct(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-5.rs b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-5.rs new file mode 100644 index 000000000000..b3369e384828 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-5.rs @@ -0,0 +1,30 @@ +// run-pass +fn tuple() { + struct S; + struct Z; + struct W; + let x = (S, Z, W); + match x { (S, ..) => {} } + match x { (.., W) => {} } + match x { (S, .., W) => {} } + match x { (.., Z, _) => {} } +} + +fn tuple_struct() { + struct SS(S, Z, W); + + struct S; + struct Z; + struct W; + let x = SS(S, Z, W); + match x { SS(S, ..) => {} } + match x { SS(.., W) => {} } + match x { SS(S, .., W) => {} } + match x { SS(.., Z, _) => {} } +} + +fn main() { + tuple(); + tuple_struct(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-6.rs b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-6.rs new file mode 100644 index 000000000000..ed9372ea1fc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-6.rs @@ -0,0 +1,46 @@ +// run-pass +fn tuple() { + let x = (1, 2, 3, 4, 5); + match x { + (a, .., b, c) => { + assert_eq!(a, 1); + assert_eq!(b, 4); + assert_eq!(c, 5); + } + } + match x { + (a, b, c, .., d) => { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + assert_eq!(d, 5); + } + } +} + +fn tuple_struct() { + struct S(u8, u8, u8, u8, u8); + + let x = S(1, 2, 3, 4, 5); + match x { + S(a, .., b, c) => { + assert_eq!(a, 1); + assert_eq!(b, 4); + assert_eq!(c, 5); + } + } + match x { + S(a, b, c, .., d) => { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + assert_eq!(d, 5); + } + } +} + +fn main() { + tuple(); + tuple_struct(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-7.rs b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-7.rs new file mode 100644 index 000000000000..89307c8cce20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/pat-tuple-7.rs @@ -0,0 +1,9 @@ +// run-pass + +fn main() { + #[allow(unused_parens)] + match 0 { + (pat) => assert_eq!(pat, 0) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/pattern-bound-var-in-for-each.rs b/gcc/testsuite/rust/rustc/ui/binding/pattern-bound-var-in-for-each.rs new file mode 100644 index 000000000000..11ae7bec5eec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/pattern-bound-var-in-for-each.rs @@ -0,0 +1,21 @@ +// run-pass +// Tests that codegen_path checks whether a +// pattern-bound var is an upvar (when codegenning +// the for-each body) + + +fn foo(src: usize) { + + match Some(src) { + Some(src_id) => { + for _i in 0_usize..10_usize { + let yyy = src_id; + assert_eq!(yyy, 0_usize); + } + } + _ => { } + } +} + +pub fn main() { foo(0_usize); } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/pattern-in-closure.rs b/gcc/testsuite/rust/rustc/ui/binding/pattern-in-closure.rs new file mode 100644 index 000000000000..acb804252ead --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/pattern-in-closure.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(non_shorthand_field_patterns)] + +struct Foo { + x: isize, + y: isize +} + +pub fn main() { + let f = |(x, _): (isize, isize)| println!("{}", x + 1); + let g = |Foo { x: x, y: _y }: Foo| println!("{}", x + 1); + f((2, 3)); + g(Foo { x: 1, y: 2 }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/range-inclusive-pattern-precedence.rs b/gcc/testsuite/rust/rustc/ui/binding/range-inclusive-pattern-precedence.rs new file mode 100644 index 000000000000..b97b3cf0f1b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/range-inclusive-pattern-precedence.rs @@ -0,0 +1,24 @@ +// run-pass +#![feature(box_patterns)] + +const VALUE: usize = 21; + +pub fn main() { + match &18 { + &(18..=18) => {} + _ => { unreachable!(); } + } + match &21 { + &(VALUE..=VALUE) => {} + _ => { unreachable!(); } + } + match Box::new(18) { + box (18..=18) => {} + _ => { unreachable!(); } + } + match Box::new(21) { + box (VALUE..=VALUE) => {} + _ => { unreachable!(); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binding/simple-generic-match.rs b/gcc/testsuite/rust/rustc/ui/binding/simple-generic-match.rs new file mode 100644 index 000000000000..cac0ce4d847f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/simple-generic-match.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +enum clam { a(T), } + +pub fn main() { let c = clam::a(2); match c { clam::a::(_) => { } } } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/use-uninit-match.rs b/gcc/testsuite/rust/rustc/ui/binding/use-uninit-match.rs new file mode 100644 index 000000000000..41f26435103b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/use-uninit-match.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + + +fn foo(o: myoption) -> isize { + let mut x: isize = 5; + match o { + myoption::none:: => { } + myoption::some::(_t) => { x += 1; } + } + return x; +} + +enum myoption { none, some(T), } + +pub fn main() { println!("{}", 5); } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/use-uninit-match2.rs b/gcc/testsuite/rust/rustc/ui/binding/use-uninit-match2.rs new file mode 100644 index 000000000000..3a2abb70c7f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/use-uninit-match2.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_mut)] +#![allow(non_camel_case_types)] + + +fn foo(o: myoption) -> isize { + let mut x: isize; + match o { + myoption::none:: => { panic!(); } + myoption::some::(_t) => { x = 5; } + } + return x; +} + +enum myoption { none, some(T), } + +pub fn main() { println!("{}", 5); } + diff --git a/gcc/testsuite/rust/rustc/ui/binding/zero_sized_subslice_match.rs b/gcc/testsuite/rust/rustc/ui/binding/zero_sized_subslice_match.rs new file mode 100644 index 000000000000..cdfac1aabac4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binding/zero_sized_subslice_match.rs @@ -0,0 +1,12 @@ +// run-pass + +fn main() { + let x = [(), ()]; + + // The subslice used to go out of bounds for zero-sized array items, check that this doesn't + // happen anymore + match x { + [_, ref y @ ..] => assert_eq!(&x[1] as *const (), &y[0] as *const ()) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binop/binop-bitxor-str.rs b/gcc/testsuite/rust/rustc/ui/binop/binop-bitxor-str.rs new file mode 100644 index 000000000000..36c0ef712467 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binop/binop-bitxor-str.rs @@ -0,0 +1,4 @@ +// error-pattern:no implementation for `String ^ String` + +fn main() { let x = "a".to_string() ^ "b".to_string(); } + diff --git a/gcc/testsuite/rust/rustc/ui/binop/binop-consume-args.rs b/gcc/testsuite/rust/rustc/ui/binop/binop-consume-args.rs new file mode 100644 index 000000000000..7e3fcdbf184e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binop/binop-consume-args.rs @@ -0,0 +1,66 @@ +// Test that binary operators consume their arguments + +use std::ops::{Add, Sub, Mul, Div, Rem, BitAnd, BitXor, BitOr, Shl, Shr}; + +fn add, B>(lhs: A, rhs: B) { + lhs + rhs; + drop(lhs); // { dg-error ".E0382." "" { target *-*-* } } + drop(rhs); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn sub, B>(lhs: A, rhs: B) { + lhs - rhs; + drop(lhs); // { dg-error ".E0382." "" { target *-*-* } } + drop(rhs); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn mul, B>(lhs: A, rhs: B) { + lhs * rhs; + drop(lhs); // { dg-error ".E0382." "" { target *-*-* } } + drop(rhs); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn div, B>(lhs: A, rhs: B) { + lhs / rhs; + drop(lhs); // { dg-error ".E0382." "" { target *-*-* } } + drop(rhs); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn rem, B>(lhs: A, rhs: B) { + lhs % rhs; + drop(lhs); // { dg-error ".E0382." "" { target *-*-* } } + drop(rhs); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn bitand, B>(lhs: A, rhs: B) { + lhs & rhs; + drop(lhs); // { dg-error ".E0382." "" { target *-*-* } } + drop(rhs); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn bitor, B>(lhs: A, rhs: B) { + lhs | rhs; + drop(lhs); // { dg-error ".E0382." "" { target *-*-* } } + drop(rhs); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn bitxor, B>(lhs: A, rhs: B) { + lhs ^ rhs; + drop(lhs); // { dg-error ".E0382." "" { target *-*-* } } + drop(rhs); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn shl, B>(lhs: A, rhs: B) { + lhs << rhs; + drop(lhs); // { dg-error ".E0382." "" { target *-*-* } } + drop(rhs); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn shr, B>(lhs: A, rhs: B) { + lhs >> rhs; + drop(lhs); // { dg-error ".E0382." "" { target *-*-* } } + drop(rhs); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/binop/binop-fail-3.rs b/gcc/testsuite/rust/rustc/ui/binop/binop-fail-3.rs new file mode 100644 index 000000000000..0aac1c0191e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binop/binop-fail-3.rs @@ -0,0 +1,12 @@ +// run-fail +// error-pattern:quux +// ignore-emscripten no processes + +fn foo() -> ! { + panic!("quux"); +} + +fn main() { + foo() == foo(); // these types wind up being defaulted to () +} + diff --git a/gcc/testsuite/rust/rustc/ui/binop/binop-logic-float.rs b/gcc/testsuite/rust/rustc/ui/binop/binop-logic-float.rs new file mode 100644 index 000000000000..6983949cc410 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binop/binop-logic-float.rs @@ -0,0 +1,4 @@ +fn main() { let x = 1.0_f32 || 2.0_f32; } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/binop/binop-logic-int.rs b/gcc/testsuite/rust/rustc/ui/binop/binop-logic-int.rs new file mode 100644 index 000000000000..a6568451acdf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binop/binop-logic-int.rs @@ -0,0 +1,4 @@ +fn main() { let x = 1 && 2; } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/binop/binop-move-semantics.rs b/gcc/testsuite/rust/rustc/ui/binop/binop-move-semantics.rs new file mode 100644 index 000000000000..cc6420b4ea56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binop/binop-move-semantics.rs @@ -0,0 +1,69 @@ +// Test that move restrictions are enforced on overloaded binary operations + +use std::ops::Add; + +fn double_move>(x: T) { + x + + + x; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_then_borrow + Clone>(x: T) { + x + + + x.clone(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_borrowed>(x: T, mut y: T) { + let m = &x; + let n = &mut y; + + x // { dg-error ".E0505." "" { target *-*-* } } + + + y; // { dg-error ".E0505." "" { target *-*-* } } + use_mut(n); use_imm(m); +} +fn illegal_dereference>(mut x: T, y: T) { + let m = &mut x; + let n = &y; + + *m // { dg-error ".E0507." "" { target *-*-* } } + + + *n; // { dg-error ".E0507." "" { target *-*-* } } + use_imm(n); use_mut(m); +} +struct Foo; + +impl<'a, 'b> Add<&'b Foo> for &'a mut Foo { + type Output = (); + + fn add(self, _: &Foo) {} +} + +impl<'a, 'b> Add<&'b mut Foo> for &'a Foo { + type Output = (); + + fn add(self, _: &mut Foo) {} +} + +fn mut_plus_immut() { + let mut f = Foo; + + &mut f + + + &f; // { dg-error ".E0502." "" { target *-*-* } } +} + +fn immut_plus_mut() { + let mut f = Foo; + + &f + + + &mut f; // { dg-error ".E0502." "" { target *-*-* } } +} + +fn main() {} + +fn use_mut(_: &mut T) { } +fn use_imm(_: &T) { } + diff --git a/gcc/testsuite/rust/rustc/ui/binop/binop-mul-bool.rs b/gcc/testsuite/rust/rustc/ui/binop/binop-mul-bool.rs new file mode 100644 index 000000000000..0ce2c49690af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binop/binop-mul-bool.rs @@ -0,0 +1,4 @@ +// error-pattern:cannot multiply `bool` by `bool` + +fn main() { let x = true * false; } + diff --git a/gcc/testsuite/rust/rustc/ui/binop/binop-mul-i32-f32.rs b/gcc/testsuite/rust/rustc/ui/binop/binop-mul-i32-f32.rs new file mode 100644 index 000000000000..cb9b254456d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binop/binop-mul-i32-f32.rs @@ -0,0 +1,6 @@ +fn foo(x: i32, y: f32) -> f32 { + x * y // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/binop/binop-panic.rs b/gcc/testsuite/rust/rustc/ui/binop/binop-panic.rs new file mode 100644 index 000000000000..df2d3f725082 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binop/binop-panic.rs @@ -0,0 +1,13 @@ +// run-fail +// error-pattern:quux +// ignore-emscripten no processes + +fn my_err(s: String) -> ! { + println!("{}", s); + panic!("quux"); +} + +fn main() { + 3_usize == my_err("bye".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binop/binop-typeck.rs b/gcc/testsuite/rust/rustc/ui/binop/binop-typeck.rs new file mode 100644 index 000000000000..f4eb25ddeac3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binop/binop-typeck.rs @@ -0,0 +1,9 @@ +// issue #500 + +fn main() { + let x = true; + let y = 1; + let z = x + y; +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/binops-issue-22743.rs b/gcc/testsuite/rust/rustc/ui/binops-issue-22743.rs new file mode 100644 index 000000000000..d01037af2f8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binops-issue-22743.rs @@ -0,0 +1,25 @@ +// run-pass + +use std::ops::Mul; + +#[derive(Copy, Clone)] +pub struct Foo { + x: f64, +} + +impl Mul for f64 { + type Output = Foo; + + fn mul(self, rhs: Foo) -> Foo { + // intentionally do something that is not * + Foo { x: self + rhs.x } + } +} + +pub fn main() { + let f: Foo = Foo { x: 5.0 }; + let val: f64 = 3.0; + let f2: Foo = val * f; + assert_eq!(f2.x, 8.0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/binops.rs b/gcc/testsuite/rust/rustc/ui/binops.rs new file mode 100644 index 000000000000..3deb07e48f15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/binops.rs @@ -0,0 +1,90 @@ +// run-pass + +#![allow(non_camel_case_types)] +// Binop corner cases + +fn test_nil() { + assert_eq!((), ()); + assert!((!(() != ()))); + assert!((!(() < ()))); + assert!((() <= ())); + assert!((!(() > ()))); + assert!((() >= ())); +} + +fn test_bool() { + assert!((!(true < false))); + assert!((!(true <= false))); + assert!((true > false)); + assert!((true >= false)); + + assert!((false < true)); + assert!((false <= true)); + assert!((!(false > true))); + assert!((!(false >= true))); + + // Bools support bitwise binops + assert_eq!(false & false, false); + assert_eq!(true & false, false); + assert_eq!(true & true, true); + assert_eq!(false | false, false); + assert_eq!(true | false, true); + assert_eq!(true | true, true); + assert_eq!(false ^ false, false); + assert_eq!(true ^ false, true); + assert_eq!(true ^ true, false); +} + +fn test_ptr() { + unsafe { + let p1: *const u8 = ::std::mem::transmute(0_usize); + let p2: *const u8 = ::std::mem::transmute(0_usize); + let p3: *const u8 = ::std::mem::transmute(1_usize); + + assert_eq!(p1, p2); + assert!(p1 != p3); + assert!(p1 < p3); + assert!(p1 <= p3); + assert!(p3 > p1); + assert!(p3 >= p3); + assert!(p1 <= p2); + assert!(p1 >= p2); + } +} + +#[derive(PartialEq, Debug)] +struct p { + x: isize, + y: isize, +} + +fn p(x: isize, y: isize) -> p { + p { + x: x, + y: y + } +} + +fn test_class() { + let q = p(1, 2); + let mut r = p(1, 2); + + unsafe { + println!("q = {:x}, r = {:x}", + (::std::mem::transmute::<*const p, usize>(&q)), + (::std::mem::transmute::<*const p, usize>(&r))); + } + assert_eq!(q, r); + r.y = 17; + assert!((r.y != q.y)); + assert_eq!(r.y, 17); + assert!((q != r)); +} + +pub fn main() { + test_nil(); + test_bool(); + test_ptr(); + test_class(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/bitwise.rs b/gcc/testsuite/rust/rustc/ui/bitwise.rs new file mode 100644 index 000000000000..f41a6405167c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bitwise.rs @@ -0,0 +1,35 @@ +// run-pass + +#[cfg(any(target_pointer_width = "32"))] +fn target() { + assert_eq!(-1000isize as usize >> 3_usize, 536870787_usize); +} + +#[cfg(any(target_pointer_width = "64"))] +fn target() { + assert_eq!(-1000isize as usize >> 3_usize, 2305843009213693827_usize); +} + +fn general() { + let mut a: isize = 1; + let mut b: isize = 2; + a ^= b; + b ^= a; + a = a ^ b; + println!("{}", a); + println!("{}", b); + assert_eq!(b, 1); + assert_eq!(a, 2); + assert_eq!(!0xf0_isize & 0xff, 0xf); + assert_eq!(0xf0_isize | 0xf, 0xff); + assert_eq!(0xf_isize << 4, 0xf0); + assert_eq!(0xf0_isize >> 4, 0xf); + assert_eq!(-16 >> 2, -4); + assert_eq!(0b1010_1010_isize | 0b0101_0101, 0xff); +} + +pub fn main() { + general(); + target(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/blind-item-local-shadow.rs b/gcc/testsuite/rust/rustc/ui/blind-item-local-shadow.rs new file mode 100644 index 000000000000..c6990873152c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/blind-item-local-shadow.rs @@ -0,0 +1,14 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_imports)] +mod bar { + pub fn foo() -> bool { true } +} + +fn main() { + let foo = || false; + use bar::foo; + assert_eq!(foo(), false); +} + diff --git a/gcc/testsuite/rust/rustc/ui/blind-item-mixed-crate-use-item.rs b/gcc/testsuite/rust/rustc/ui/blind-item-mixed-crate-use-item.rs new file mode 100644 index 000000000000..1f18df8701e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/blind-item-mixed-crate-use-item.rs @@ -0,0 +1,27 @@ +// run-pass +// aux-build:blind-item-mixed-crate-use-item-foo.rs +// aux-build:blind-item-mixed-crate-use-item-foo2.rs + +// pretty-expanded FIXME #23616 + +mod m { + pub fn f(_: T, _: (), _: ()) { } + pub fn g(_: T, _: (), _: ()) { } +} + +const BAR: () = (); +struct Data; +use m::f; +extern crate blind_item_mixed_crate_use_item_foo as foo; + +fn main() { + const BAR2: () = (); + struct Data2; + use m::g; + + extern crate blind_item_mixed_crate_use_item_foo2 as foo2; + + f(Data, BAR, foo::X); + g(Data2, BAR2, foo2::Y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/blind-item-mixed-use-item.rs b/gcc/testsuite/rust/rustc/ui/blind-item-mixed-use-item.rs new file mode 100644 index 000000000000..5cb1b79b1260 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/blind-item-mixed-use-item.rs @@ -0,0 +1,21 @@ +// run-pass +// pretty-expanded FIXME #23616 + +mod m { + pub fn f(_: T, _: ()) { } + pub fn g(_: T, _: ()) { } +} + +const BAR: () = (); +struct Data; +use m::f; + +fn main() { + const BAR2: () = (); + struct Data2; + use m::g; + + f(Data, BAR); + g(Data2, BAR2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/blind/blind-item-block-item-shadow.rs b/gcc/testsuite/rust/rustc/ui/blind/blind-item-block-item-shadow.rs new file mode 100644 index 000000000000..ed74f2867d62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/blind/blind-item-block-item-shadow.rs @@ -0,0 +1,10 @@ +mod foo { pub struct Bar; } + +fn main() { + { + struct Bar; + use foo::Bar; +// { dg-error ".E0255." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/blind/blind-item-block-middle.rs b/gcc/testsuite/rust/rustc/ui/blind/blind-item-block-middle.rs new file mode 100644 index 000000000000..b86a14572042 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/blind/blind-item-block-middle.rs @@ -0,0 +1,10 @@ +#![allow(non_camel_case_types)] + +mod foo { pub struct bar; } + +fn main() { + let bar = 5; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + use foo::bar; +} + diff --git a/gcc/testsuite/rust/rustc/ui/blind/blind-item-item-shadow.rs b/gcc/testsuite/rust/rustc/ui/blind/blind-item-item-shadow.rs new file mode 100644 index 000000000000..52be8e21e72f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/blind/blind-item-item-shadow.rs @@ -0,0 +1,8 @@ +mod foo { pub mod foo { } } + +use foo::foo; +// { dg-error ".E0255." "" { target *-*-* } .-1 } +// { dg-error ".E0255." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/block-arg-call-as.rs b/gcc/testsuite/rust/rustc/ui/block-arg-call-as.rs new file mode 100644 index 000000000000..0ab7da8f7c57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-arg-call-as.rs @@ -0,0 +1,13 @@ +// run-pass + +#![allow(non_snake_case)] + +fn asBlock(f: F) -> usize where F: FnOnce() -> usize { + return f(); +} + +pub fn main() { + let x = asBlock(|| 22); + assert_eq!(x, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-arg.rs b/gcc/testsuite/rust/rustc/ui/block-arg.rs new file mode 100644 index 000000000000..0d73f41076fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-arg.rs @@ -0,0 +1,12 @@ +// run-pass +// Check usage and precedence of block arguments in expressions: +pub fn main() { + let v = vec![-1.0f64, 0.0, 1.0, 2.0, 3.0]; + + // Statement form does not require parentheses: + for i in &v { + println!("{}", *i); + } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-explicit-types.rs b/gcc/testsuite/rust/rustc/ui/block-explicit-types.rs new file mode 100644 index 000000000000..b2b6996094d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-explicit-types.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + fn as_buf(s: String, f: F) -> T where F: FnOnce(String) -> T { f(s) } + as_buf("foo".to_string(), |foo: String| -> () { println!("{}", foo) }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-expr-precedence.rs b/gcc/testsuite/rust/rustc/ui/block-expr-precedence.rs new file mode 100644 index 000000000000..fc3b41890d03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-expr-precedence.rs @@ -0,0 +1,63 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(unused_parens)] +// This test has some extra semis in it that the pretty-printer won't +// reproduce so we don't want to automatically reformat it + +// no-reformat + + +/* + * + * When you write a block-expression thing followed by + * a lone unary operator, you can get a surprising parse: + * + * if (...) { ... } + * -num; + * + * for example, or: + * + * if (...) { ... } + * *box; + * + * These will parse as subtraction and multiplication binops. + * To get them to parse "the way you want" you need to brace + * the leading unops: + + * if (...) { ... } + * {-num}; + * + * or alternatively, semi-separate them: + * + * if (...) { ... }; + * -num; + * + * This seems a little wonky, but the alternative is to lower + * precedence of such block-like exprs to the point where + * you have to parenthesize them to get them to occur in the + * RHS of a binop. For example, you'd have to write: + * + * 12 + (if (foo) { 13 } else { 14 }); + * + * rather than: + * + * 12 + if (foo) { 13 } else { 14 }; + * + * Since we want to maintain the ability to write the latter, + * we leave the parens-burden on the trailing unop case. + * + */ + +pub fn main() { + + let num = 12; + + assert_eq!(if (true) { 12 } else { 12 } - num, 0); + assert_eq!(12 - if (true) { 12 } else { 12 }, 0); + if (true) { 12; } {-num}; + if (true) { 12; }; {-num}; + if (true) { 12; };;; -num; +// { dg-warning "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-expression-remove-semicolon.rs b/gcc/testsuite/rust/rustc/ui/block-expression-remove-semicolon.rs new file mode 100644 index 000000000000..ae0505ef0fdf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-expression-remove-semicolon.rs @@ -0,0 +1,13 @@ +// run-rustfix + +fn foo() -> i32 { + 0 +} + +fn main() { + let _x: i32 = { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo(); // { help "" "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-fn-coerce.rs b/gcc/testsuite/rust/rustc/ui/block-fn-coerce.rs new file mode 100644 index 000000000000..d929ee1e5e3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-fn-coerce.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(unused_braces)] + +fn force(f: F) -> isize where F: FnOnce() -> isize { return f(); } + +pub fn main() { + fn f() -> isize { return 7; } + assert_eq!(force(f), 7); + let g = {||force(f)}; + assert_eq!(g(), 7); +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-iter-1.rs b/gcc/testsuite/rust/rustc/ui/block-iter-1.rs new file mode 100644 index 000000000000..f5bc1c847643 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-iter-1.rs @@ -0,0 +1,16 @@ +// run-pass + +fn iter_vec(v: Vec , mut f: F) where F: FnMut(&T) { for x in &v { f(x); } } + +pub fn main() { + let v = vec![1, 2, 3, 4, 5, 6, 7]; + let mut odds = 0; + iter_vec(v, |i| { + if *i % 2 == 1 { + odds += 1; + } + }); + println!("{}", odds); + assert_eq!(odds, 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-iter-2.rs b/gcc/testsuite/rust/rustc/ui/block-iter-2.rs new file mode 100644 index 000000000000..3d4953f6c9fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-iter-2.rs @@ -0,0 +1,16 @@ +// run-pass + +fn iter_vec(v: Vec, mut f: F) where F: FnMut(&T) { for x in &v { f(x); } } + +pub fn main() { + let v = vec![1, 2, 3, 4, 5]; + let mut sum = 0; + iter_vec(v.clone(), |i| { + iter_vec(v.clone(), |j| { + sum += *i * *j; + }); + }); + println!("{}", sum); + assert_eq!(sum, 225); +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-result/block-must-not-have-result-do.rs b/gcc/testsuite/rust/rustc/ui/block-result/block-must-not-have-result-do.rs new file mode 100644 index 000000000000..0a5376b81e43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-result/block-must-not-have-result-do.rs @@ -0,0 +1,6 @@ +fn main() { + loop { + true // { dg-error ".E0308." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-result/block-must-not-have-result-res.rs b/gcc/testsuite/rust/rustc/ui/block-result/block-must-not-have-result-res.rs new file mode 100644 index 000000000000..ef83cfdd0587 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-result/block-must-not-have-result-res.rs @@ -0,0 +1,11 @@ +struct R; + +impl Drop for R { + fn drop(&mut self) { + true // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-result/block-must-not-have-result-while.rs b/gcc/testsuite/rust/rustc/ui/block-result/block-must-not-have-result-while.rs new file mode 100644 index 000000000000..db2252d8c0f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-result/block-must-not-have-result-while.rs @@ -0,0 +1,7 @@ +fn main() { + while true { // { dg-warning "" "" { target *-*-* } } + true // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-result/consider-removing-last-semi.rs b/gcc/testsuite/rust/rustc/ui/block-result/consider-removing-last-semi.rs new file mode 100644 index 000000000000..9d116f5ecdea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-result/consider-removing-last-semi.rs @@ -0,0 +1,14 @@ +// run-rustfix + +pub fn f() -> String { // { dg-error ".E0308." "" { target *-*-* } } + 0u8; + "bla".to_string(); +} + +pub fn g() -> String { // { dg-error ".E0308." "" { target *-*-* } } + "this won't work".to_string(); + "removeme".to_string(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/block-result/issue-11714.rs b/gcc/testsuite/rust/rustc/ui/block-result/issue-11714.rs new file mode 100644 index 000000000000..3186d072aceb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-result/issue-11714.rs @@ -0,0 +1,8 @@ +fn blah() -> i32 { // { dg-error ".E0308." "" { target *-*-* } } + 1 + + ; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/block-result/issue-13428.rs b/gcc/testsuite/rust/rustc/ui/block-result/issue-13428.rs new file mode 100644 index 000000000000..9e6903588263 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-result/issue-13428.rs @@ -0,0 +1,17 @@ +// Regression test for #13428 + +fn foo() -> String { // { dg-error ".E0308." "" { target *-*-* } } + format!("Hello {}", + "world") + // Put the trailing semicolon on its own line to test that the + // note message gets the offending semicolon exactly + ; +} + +fn bar() -> String { // { dg-error ".E0308." "" { target *-*-* } } + "foobar".to_string() + ; +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/block-result/issue-13624.rs b/gcc/testsuite/rust/rustc/ui/block-result/issue-13624.rs new file mode 100644 index 000000000000..6c165dc50d8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-result/issue-13624.rs @@ -0,0 +1,30 @@ +mod a { + pub enum Enum { + EnumStructVariant { x: u8, y: u8, z: u8 } + } + + pub fn get_enum_struct_variant() -> () { + Enum::EnumStructVariant { x: 1, y: 2, z: 3 } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } +} + +mod b { + mod test { + use a; + + fn test_enum_struct_variant() { + let enum_struct_variant = ::a::get_enum_struct_variant(); + match enum_struct_variant { + a::Enum::EnumStructVariant { x, y, z } => { +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } + } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/block-result/issue-20862.rs b/gcc/testsuite/rust/rustc/ui/block-result/issue-20862.rs new file mode 100644 index 000000000000..b5cb799b4091 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-result/issue-20862.rs @@ -0,0 +1,10 @@ +fn foo(x: i32) { + |y| x + y +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() { + let x = foo(5)(2); +// { dg-error ".E0618." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-result/issue-22645.rs b/gcc/testsuite/rust/rustc/ui/block-result/issue-22645.rs new file mode 100644 index 000000000000..505dc180d743 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-result/issue-22645.rs @@ -0,0 +1,18 @@ +use std::ops::Add; + +trait Scalar {} +impl Scalar for f64 {} + +struct Bob; + +impl Add for Bob { + type Output = Bob; + fn add(self, rhs : RHS) -> Bob { Bob } +} + +fn main() { + let b = Bob + 3.5; + b + 3 // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-result/issue-3563.rs b/gcc/testsuite/rust/rustc/ui/block-result/issue-3563.rs new file mode 100644 index 000000000000..120910f77936 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-result/issue-3563.rs @@ -0,0 +1,8 @@ +trait A { + fn a(&self) { + || self.b() +// { dg-error ".E0599." "" { target *-*-* } .-1 } + } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/block-result/issue-5500.rs b/gcc/testsuite/rust/rustc/ui/block-result/issue-5500.rs new file mode 100644 index 000000000000..b0cc71564c0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-result/issue-5500.rs @@ -0,0 +1,8 @@ +fn main() { + &panic!() +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/block-result/unexpected-return-on-unit.rs b/gcc/testsuite/rust/rustc/ui/block-result/unexpected-return-on-unit.rs new file mode 100644 index 000000000000..66272440b4c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/block-result/unexpected-return-on-unit.rs @@ -0,0 +1,15 @@ +// Test that we do some basic error correction in the tokeniser (and don't spew +// too many bogus errors). + +fn foo() -> usize { + 3 +} + +fn bar() { + foo() // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { + bar() +} + diff --git a/gcc/testsuite/rust/rustc/ui/bogus-tag.rs b/gcc/testsuite/rust/rustc/ui/bogus-tag.rs new file mode 100644 index 000000000000..0bd562f1e309 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bogus-tag.rs @@ -0,0 +1,11 @@ +enum Color { Rgb(isize, isize, isize), Rgba(isize, isize, isize, isize), } + +fn main() { + let red: Color = Color::Rgb(255, 0, 0); + match red { + Color::Rgb(r, g, b) => { println!("rgb"); } + Color::Hsl(h, s, l) => { println!("hsl"); } +// { dg-error ".E0599." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/bool-not.rs b/gcc/testsuite/rust/rustc/ui/bool-not.rs new file mode 100644 index 000000000000..35f910a51b9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bool-not.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + if !false { assert!((true)); } else { assert!((false)); } + if !true { assert!((false)); } else { assert!((true)); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/bool.rs b/gcc/testsuite/rust/rustc/ui/bool.rs new file mode 100644 index 000000000000..7c47fa7e2ab9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bool.rs @@ -0,0 +1,73 @@ +// run-pass +// Basic boolean tests + + +use std::cmp::Ordering::{Equal, Greater, Less}; +use std::ops::{BitAnd, BitOr, BitXor}; + +fn main() { + assert_eq!(false.eq(&true), false); + assert_eq!(false == false, true); + assert_eq!(false != true, true); + assert_eq!(false.ne(&false), false); + + assert_eq!(false.bitand(false), false); + assert_eq!(true.bitand(false), false); + assert_eq!(false.bitand(true), false); + assert_eq!(true.bitand(true), true); + + assert_eq!(false & false, false); + assert_eq!(true & false, false); + assert_eq!(false & true, false); + assert_eq!(true & true, true); + + assert_eq!(false.bitor(false), false); + assert_eq!(true.bitor(false), true); + assert_eq!(false.bitor(true), true); + assert_eq!(true.bitor(true), true); + + assert_eq!(false | false, false); + assert_eq!(true | false, true); + assert_eq!(false | true, true); + assert_eq!(true | true, true); + + assert_eq!(false.bitxor(false), false); + assert_eq!(true.bitxor(false), true); + assert_eq!(false.bitxor(true), true); + assert_eq!(true.bitxor(true), false); + + assert_eq!(false ^ false, false); + assert_eq!(true ^ false, true); + assert_eq!(false ^ true, true); + assert_eq!(true ^ true, false); + + assert_eq!(!true, false); + assert_eq!(!false, true); + + let s = false.to_string(); + assert_eq!(s, "false"); + let s = true.to_string(); + assert_eq!(s, "true"); + + assert!(true > false); + assert!(!(false > true)); + + assert!(false < true); + assert!(!(true < false)); + + assert!(false <= false); + assert!(false >= false); + assert!(true <= true); + assert!(true >= true); + + assert!(false <= true); + assert!(!(false >= true)); + assert!(true >= false); + assert!(!(true <= false)); + + assert_eq!(true.cmp(&true), Equal); + assert_eq!(false.cmp(&false), Equal); + assert_eq!(true.cmp(&false), Greater); + assert_eq!(false.cmp(&true), Less); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrow-by-val-method-receiver.rs b/gcc/testsuite/rust/rustc/ui/borrow-by-val-method-receiver.rs new file mode 100644 index 000000000000..df8dbb2718c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrow-by-val-method-receiver.rs @@ -0,0 +1,15 @@ +// run-pass + +trait Foo { + fn foo(self); +} + +impl<'a> Foo for &'a [isize] { + fn foo(self) {} +} + +pub fn main() { + let items = vec![ 3, 5, 1, 2, 4 ]; + items.foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/assign-never-type.rs b/gcc/testsuite/rust/rustc/ui/borrowck/assign-never-type.rs new file mode 100644 index 000000000000..e3f53da8d09d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/assign-never-type.rs @@ -0,0 +1,15 @@ +// Regression test for issue 62165 + +// check-pass + +#![feature(never_type)] + +pub fn main() { + loop { + match None { + None => return, + Some(val) => val, + }; + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/assign_mutable_fields.rs b/gcc/testsuite/rust/rustc/ui/borrowck/assign_mutable_fields.rs new file mode 100644 index 000000000000..a06d1da25351 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/assign_mutable_fields.rs @@ -0,0 +1,23 @@ +// Currently, we do permit you to assign to individual fields of an +// uninitialized var. +// We hope to fix this at some point. +// +// FIXME(#54987) + +fn assign_both_fields_and_use() { + let mut x: (u32, u32); + x.0 = 1; // { dg-error ".E0381." "" { target *-*-* } } + x.1 = 22; + drop(x.0); + drop(x.1); +} + +fn assign_both_fields_the_use_var() { + let mut x: (u32, u32); + x.0 = 1; // { dg-error ".E0381." "" { target *-*-* } } + x.1 = 22; + drop(x); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs b/gcc/testsuite/rust/rustc/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs new file mode 100644 index 000000000000..b75aaba335c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs @@ -0,0 +1,223 @@ +// Tests using a combination of pattern features has the expected borrow checking behavior +#![feature(bindings_after_at)] +#![feature(or_patterns)] +#![feature(box_patterns)] + +enum Test { + Foo, + Bar, + _Baz, +} + +// bindings_after_at + slice_patterns + +fn bindings_after_at_slice_patterns_move_binding(x: [String; 4]) { + match x { + a @ [.., _] => (), + _ => (), + }; + + &x; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn bindings_after_at_slice_patterns_borrows_binding_mut(mut x: [String; 4]) { + let r = match x { + ref mut foo @ [.., _] => Some(foo), + _ => None, + }; + + &x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + drop(r); +} + +fn bindings_after_at_slice_patterns_borrows_slice_mut1(mut x: [String; 4]) { + let r = match x { + ref foo @ [.., ref mut bar] => (), +// { dg-error "" "" { target *-*-* } .-1 } + _ => (), + }; + + drop(r); +} + +fn bindings_after_at_slice_patterns_borrows_slice_mut2(mut x: [String; 4]) { + let r = match x { + [ref foo @ .., ref bar] => Some(foo), + _ => None, + }; + + &mut x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + drop(r); +} + +fn bindings_after_at_slice_patterns_borrows_both(mut x: [String; 4]) { + let r = match x { + ref foo @ [.., ref bar] => Some(foo), + _ => None, + }; + + &mut x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + drop(r); +} + +// bindings_after_at + or_patterns + +fn bindings_after_at_or_patterns_move(x: Option) { + match x { + foo @ Some(Test::Foo | Test::Bar) => (), + _ => (), + } + + &x; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn bindings_after_at_or_patterns_borrows(mut x: Option) { + let r = match x { + ref foo @ Some(Test::Foo | Test::Bar) => Some(foo), + _ => None, + }; + + &mut x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + drop(r); +} + +fn bindings_after_at_or_patterns_borrows_mut(mut x: Option) { + let r = match x { + ref mut foo @ Some(Test::Foo | Test::Bar) => Some(foo), + _ => None, + }; + + &x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + drop(r); +} + +// bindings_after_at + box_patterns + +fn bindings_after_at_box_patterns_borrows_both(mut x: Option>) { + let r = match x { + ref foo @ Some(box ref s) => Some(foo), + _ => None, + }; + + &mut x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + drop(r); +} + +fn bindings_after_at_box_patterns_borrows_mut(mut x: Option>) { + match x { + ref foo @ Some(box ref mut s) => (), +// { dg-error "" "" { target *-*-* } .-1 } + _ => (), + }; +} + +// bindings_after_at + slice_patterns + or_patterns + +fn bindings_after_at_slice_patterns_or_patterns_moves(x: [Option; 4]) { + match x { + a @ [.., Some(Test::Foo | Test::Bar)] => (), + _ => (), + }; + + &x; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn bindings_after_at_slice_patterns_or_patterns_borrows_binding(mut x: [Option; 4]) { + let r = match x { + ref a @ [ref b @ .., Some(Test::Foo | Test::Bar)] => Some(a), + _ => None, + }; + + &mut x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + drop(r); +} + +fn bindings_after_at_slice_patterns_or_patterns_borrows_slice(mut x: [Option; 4]) { + let r = match x { + ref a @ [ref b @ .., Some(Test::Foo | Test::Bar)] => Some(b), + _ => None, + }; + + &mut x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + drop(r); +} + +// bindings_after_at + slice_patterns + box_patterns + +fn bindings_after_at_slice_patterns_box_patterns_borrows(mut x: [Option>; 4]) { + let r = match x { + [_, ref a @ Some(box ref b), ..] => Some(a), + _ => None, + }; + + &mut x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + drop(r); +} + +// bindings_after_at + slice_patterns + or_patterns + box_patterns + +fn bindings_after_at_slice_patterns_or_patterns_box_patterns_borrows( + mut x: [Option>; 4] +) { + let r = match x { + [_, ref a @ Some(box Test::Foo | box Test::Bar), ..] => Some(a), + _ => None, + }; + + &mut x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + drop(r); +} + +fn bindings_after_at_slice_patterns_or_patterns_box_patterns_borrows_mut( + mut x: [Option>; 4] +) { + let r = match x { + [_, ref mut a @ Some(box Test::Foo | box Test::Bar), ..] => Some(a), + _ => None, + }; + + &x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + drop(r); +} + +fn bindings_after_at_slice_patterns_or_patterns_box_patterns_borrows_binding( + mut x: [Option>; 4] +) { + let r = match x { + ref a @ [_, ref b @ Some(box Test::Foo | box Test::Bar), ..] => Some(a), + _ => None, + }; + + &mut x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + drop(r); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrow-immutable-upvar-mutation-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-immutable-upvar-mutation-impl-trait.rs new file mode 100644 index 000000000000..6eb43859d520 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-immutable-upvar-mutation-impl-trait.rs @@ -0,0 +1,15 @@ +#![feature(unboxed_closures)] + +// Tests that we can't assign to or mutably borrow upvars from `Fn` +// closures (issue #17780) + +fn main() {} + +fn bar() -> impl Fn() -> usize { + let mut x = 0; + move || { + x += 1; // { dg-error ".E0594." "" { target *-*-* } } + x + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrow-immutable-upvar-mutation.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-immutable-upvar-mutation.rs new file mode 100644 index 000000000000..2bd92356bc92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-immutable-upvar-mutation.rs @@ -0,0 +1,57 @@ +#![feature(unboxed_closures)] + +// Tests that we can't assign to or mutably borrow upvars from `Fn` +// closures (issue #17780) + +fn set(x: &mut usize) { + *x = 5; +} + +fn to_fn>(f: F) -> F { + f +} +fn to_fn_mut>(f: F) -> F { + f +} + +fn main() { + // By-ref captures + { + let mut x = 0; + let _f = to_fn(|| x = 42); // { dg-error ".E0594." "" { target *-*-* } } + + let mut y = 0; + let _g = to_fn(|| set(&mut y)); // { dg-error ".E0596." "" { target *-*-* } } + + let mut z = 0; + let _h = to_fn_mut(|| { + set(&mut z); + to_fn(|| z = 42); // { dg-error ".E0594." "" { target *-*-* } } + }); + } + + // By-value captures + { + let mut x = 0; + let _f = to_fn(move || x = 42); // { dg-error ".E0594." "" { target *-*-* } } + + let mut y = 0; + let _g = to_fn(move || set(&mut y)); // { dg-error ".E0596." "" { target *-*-* } } + + let mut z = 0; + let _h = to_fn_mut(move || { + set(&mut z); + to_fn(move || z = 42); +// { dg-error ".E0594." "" { target *-*-* } .-1 } + }); + } +} + +fn foo() -> Box usize> { + let mut x = 0; + Box::new(move || { + x += 1; // { dg-error ".E0594." "" { target *-*-* } } + x + }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-borrowed.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-borrowed.rs new file mode 100644 index 000000000000..3ae5245c70b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-borrowed.rs @@ -0,0 +1,23 @@ +#![feature(raw_ref_op)] + +fn address_of_shared() { + let mut x = 0; + let y = &x; + + let q = &raw mut x; // { dg-error ".E0502." "" { target *-*-* } } + + drop(y); +} + +fn address_of_mutably_borrowed() { + let mut x = 0; + let y = &mut x; + + let p = &raw const x; // { dg-error ".E0502." "" { target *-*-* } } + let q = &raw mut x; // { dg-error ".E0499." "" { target *-*-* } } + + drop(y); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-deref-mutability-ok.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-deref-mutability-ok.rs new file mode 100644 index 000000000000..4409a4041cba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-deref-mutability-ok.rs @@ -0,0 +1,24 @@ +// check-pass + +#![feature(raw_ref_op)] + +fn raw_reborrow() { + let x = &0; + let y = &mut 0; + + let p = &raw const *x; + let r = &raw const *y; + let s = &raw mut *y; +} + +unsafe fn raw_reborrow_of_raw() { + let x = &0 as *const i32; + let y = &mut 0 as *mut i32; + + let p = &raw const *x; + let r = &raw const *y; + let s = &raw mut *y; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-deref-mutability.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-deref-mutability.rs new file mode 100644 index 000000000000..51f7d4a65523 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-deref-mutability.rs @@ -0,0 +1,18 @@ +// Check that `&raw mut` cannot be used to turn a `&T` into a `*mut T`. + +#![feature(raw_ref_op)] + +fn raw_reborrow() { + let x = &0; + + let q = &raw mut *x; // { dg-error ".E0596." "" { target *-*-* } } +} + +unsafe fn raw_reborrow_of_raw() { + let x = &0 as *const i32; + + let q = &raw mut *x; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-mutability-ok.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-mutability-ok.rs new file mode 100644 index 000000000000..7f54678fccdc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-mutability-ok.rs @@ -0,0 +1,45 @@ +// check-pass + +#![feature(raw_ref_op)] + +fn mutable_address_of() { + let mut x = 0; + let y = &raw mut x; +} + +fn mutable_address_of_closure() { + let mut x = 0; + let mut f = || { + let y = &raw mut x; + }; + f(); +} + +fn const_address_of_closure() { + let x = 0; + let f = || { + let y = &raw const x; + }; + f(); +} + +fn make_fn(f: F) -> F { f } + +fn const_address_of_fn_closure() { + let x = 0; + let f = make_fn(|| { + let y = &raw const x; + }); + f(); +} + +fn const_address_of_fn_closure_move() { + let x = 0; + let f = make_fn(move || { + let y = &raw const x; + }); + f(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-mutability.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-mutability.rs new file mode 100644 index 000000000000..0a6a598f7585 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-raw-address-of-mutability.rs @@ -0,0 +1,43 @@ +#![feature(raw_ref_op)] + +fn mutable_address_of() { + let x = 0; + let y = &raw mut x; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn mutable_address_of_closure() { + let x = 0; + let mut f = || { + let y = &raw mut x; // { dg-error ".E0596." "" { target *-*-* } } + }; + f(); +} + +fn mutable_address_of_imm_closure() { + let mut x = 0; + let f = || { + let y = &raw mut x; + }; + f(); // { dg-error ".E0596." "" { target *-*-* } } +} + +fn make_fn(f: F) -> F { f } + +fn mutable_address_of_fn_closure() { + let mut x = 0; + let f = make_fn(|| { + let y = &raw mut x; // { dg-error ".E0596." "" { target *-*-* } } + }); + f(); +} + +fn mutable_address_of_fn_closure_move() { + let mut x = 0; + let f = make_fn(move || { + let y = &raw mut x; // { dg-error ".E0596." "" { target *-*-* } } + }); + f(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrow-tuple-fields.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-tuple-fields.rs new file mode 100644 index 000000000000..c15575be18d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrow-tuple-fields.rs @@ -0,0 +1,44 @@ +#![feature(box_syntax)] + + + +struct Foo(Box, isize); + +struct Bar(isize, isize); + +fn main() { + let x: (Box<_>, _) = (box 1, 2); + let r = &x.0; + let y = x; // { dg-error ".E0505." "" { target *-*-* } } + + r.use_ref(); + + let mut x = (1, 2); + let a = &x.0; + let b = &mut x.0; // { dg-error ".E0502." "" { target *-*-* } } + a.use_ref(); + + let mut x = (1, 2); + let a = &mut x.0; + let b = &mut x.0; // { dg-error ".E0499." "" { target *-*-* } } + a.use_ref(); + + let x = Foo(box 1, 2); + let r = &x.0; + let y = x; // { dg-error ".E0505." "" { target *-*-* } } + r.use_ref(); + + let mut x = Bar(1, 2); + let a = &x.0; + let b = &mut x.0; // { dg-error ".E0502." "" { target *-*-* } } + a.use_ref(); + + let mut x = Bar(1, 2); + let a = &mut x.0; + let b = &mut x.0; // { dg-error ".E0499." "" { target *-*-* } } + a.use_mut(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-access-permissions.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-access-permissions.rs new file mode 100644 index 000000000000..72aef8160b23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-access-permissions.rs @@ -0,0 +1,51 @@ +static static_x : i32 = 1; +static mut static_x_mut : i32 = 1; + +fn main() { + let x = 1; + let mut x_mut = 1; + + { // borrow of local + let _y1 = &mut x; // { dg-error ".E0596." "" { target *-*-* } } + let _y2 = &mut x_mut; // No error + } + + { // borrow of static + let _y1 = &mut static_x; // { dg-error ".E0596." "" { target *-*-* } } + unsafe { let _y2 = &mut static_x_mut; } // No error + } + + { // borrow of deref to box + let box_x = Box::new(1); + let mut box_x_mut = Box::new(1); + + let _y1 = &mut *box_x; // { dg-error ".E0596." "" { target *-*-* } } + let _y2 = &mut *box_x_mut; // No error + } + + { // borrow of deref to reference + let ref_x = &x; + let ref_x_mut = &mut x_mut; + + let _y1 = &mut *ref_x; // { dg-error ".E0596." "" { target *-*-* } } + let _y2 = &mut *ref_x_mut; // No error + } + + { // borrow of deref to pointer + let ptr_x : *const _ = &x; + let ptr_mut_x : *mut _ = &mut x_mut; + + unsafe { + let _y1 = &mut *ptr_x; // { dg-error ".E0596." "" { target *-*-* } } + let _y2 = &mut *ptr_mut_x; // No error + } + } + + { // borrowing mutably through an immutable reference + struct Foo<'a> { f: &'a mut i32, g: &'a i32 }; + let mut foo = Foo { f: &mut x_mut, g: &x }; + let foo_ref = &foo; + let _y = &mut *foo_ref.f; // { dg-error ".E0596." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-and-init.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-and-init.rs new file mode 100644 index 000000000000..13d763abd456 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-and-init.rs @@ -0,0 +1,7 @@ +fn main() { + let i: isize; + + println!("{}", false && { i = 5; true }); + println!("{}", i); // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-anon-fields-struct.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-anon-fields-struct.rs new file mode 100644 index 000000000000..23159ca35d29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-anon-fields-struct.rs @@ -0,0 +1,38 @@ +// Tests that we are able to distinguish when loans borrow different +// anonymous fields of a tuple vs the same anonymous field. + +struct Y(usize, usize); + +fn distinct_variant() { + let mut y = Y(1, 2); + + let a = match y { + Y(ref mut a, _) => a + }; + + let b = match y { + Y(_, ref mut b) => b + }; + + *a += 1; + *b += 1; +} + +fn same_variant() { + let mut y = Y(1, 2); + + let a = match y { + Y(ref mut a, _) => a + }; + + let b = match y { + Y(ref mut b, _) => b // { dg-error ".E0499." "" { target *-*-* } } + }; + + *a += 1; + *b += 1; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-anon-fields-tuple.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-anon-fields-tuple.rs new file mode 100644 index 000000000000..fb61e575f75f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-anon-fields-tuple.rs @@ -0,0 +1,36 @@ +// Tests that we are able to distinguish when loans borrow different +// anonymous fields of a tuple vs the same anonymous field. + +fn distinct_variant() { + let mut y = (1, 2); + + let a = match y { + (ref mut a, _) => a + }; + + let b = match y { + (_, ref mut b) => b + }; + + *a += 1; + *b += 1; +} + +fn same_variant() { + let mut y = (1, 2); + + let a = match y { + (ref mut a, _) => a + }; + + let b = match y { + (ref mut b, _) => b // { dg-error ".E0499." "" { target *-*-* } } + }; + + *a += 1; + *b += 1; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-anon-fields-variant.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-anon-fields-variant.rs new file mode 100644 index 000000000000..377b1fdfe3e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-anon-fields-variant.rs @@ -0,0 +1,46 @@ +enum Foo { + X, Y(usize, usize) +} + +fn distinct_variant() { + let mut y = Foo::Y(1, 2); + + let a = match y { + Foo::Y(ref mut a, _) => a, + Foo::X => panic!() + }; + + // While `a` and `b` are disjoint, borrowck doesn't know that `a` is not + // also used for the discriminant of `Foo`, which it would be if `a` was a + // reference. + let b = match y { + Foo::Y(_, ref mut b) => b, +// { dg-error ".E0503." "" { target *-*-* } .-1 } + Foo::X => panic!() + }; + + *a += 1; + *b += 1; +} + +fn same_variant() { + let mut y = Foo::Y(1, 2); + + let a = match y { + Foo::Y(ref mut a, _) => a, + Foo::X => panic!() + }; + + let b = match y { + Foo::Y(ref mut b, _) => b, // { dg-error ".E0499." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + Foo::X => panic!() + }; + + *a += 1; + *b += 1; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-argument.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-argument.rs new file mode 100644 index 000000000000..c1b5060b2bf8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-argument.rs @@ -0,0 +1,35 @@ +#[derive(Copy, Clone)] +struct S; + +impl S { + fn mutate(&mut self) { + } +} + +fn func(arg: S) { + arg.mutate(); // { dg-error ".E0596." "" { target *-*-* } } +} + +impl S { + fn method(&self, arg: S) { + arg.mutate(); // { dg-error ".E0596." "" { target *-*-* } } + } +} + +trait T { + fn default(&self, arg: S) { + arg.mutate(); // { dg-error ".E0596." "" { target *-*-* } } + } +} + +impl T for S {} + +fn main() { + let s = S; + func(s); + s.method(s); + s.default(s); + (|arg: S| { arg.mutate() })(s); +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-asm.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-asm.rs new file mode 100644 index 000000000000..adc065d737e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-asm.rs @@ -0,0 +1,83 @@ +// ignore-s390x +// ignore-emscripten +// ignore-powerpc +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-riscv64 +// ignore-sparc +// ignore-sparc64 + +#![feature(llvm_asm)] + +#[cfg(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64", + target_arch = "mips", + target_arch = "mips64"))] +mod test_cases { + fn is_move() { + let y: &mut isize; + let x = &mut 0isize; + unsafe { + llvm_asm!("nop" : : "r"(x)); + } + let z = x; // { dg-error ".E0382." "" { target *-*-* } } + } + + fn in_is_read() { + let mut x = 3; + let y = &mut x; + unsafe { + llvm_asm!("nop" : : "r"(x)); // { dg-error ".E0503." "" { target *-*-* } } + } + let z = y; + } + + fn out_is_assign() { + let x = 3; + unsafe { + llvm_asm!("nop" : "=r"(x)); // { dg-error ".E0384." "" { target *-*-* } } + } + let mut a = &mut 3; + let b = &*a; + unsafe { + llvm_asm!("nop" : "=r"(a)); // OK, Shallow write to `a` + } + let c = b; + let d = *a; + } + + fn rw_is_assign() { + let x = 3; + unsafe { + llvm_asm!("nop" : "+r"(x)); // { dg-error ".E0384." "" { target *-*-* } } + } + } + + fn indirect_is_not_init() { + let x: i32; + unsafe { + llvm_asm!("nop" : "=*r"(x)); // { dg-error ".E0381." "" { target *-*-* } } + } + } + + fn rw_is_read() { + let mut x = &mut 3; + let y = &*x; + unsafe { + llvm_asm!("nop" : "+r"(x)); // { dg-error ".E0506." "" { target *-*-* } } + } + let z = y; + } + + fn two_moves() { + let x = &mut 2; + unsafe { + llvm_asm!("nop" : : "r"(x), "r"(x) ); // { dg-error ".E0382." "" { target *-*-* } } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-comp-idx.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-comp-idx.rs new file mode 100644 index 000000000000..0c020a106036 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-comp-idx.rs @@ -0,0 +1,40 @@ +struct Point { + x: isize, + y: isize, +} + +fn a() { + let mut p = vec![1]; + + // Create an immutable pointer into p's contents: + let q: &isize = &p[0]; + + p[0] = 5; // { dg-error ".E0502." "" { target *-*-* } } + + println!("{}", *q); +} + +fn borrow(_x: &[isize], _f: F) where F: FnOnce() {} + +fn b() { + // here we alias the mutable vector into an imm slice and try to + // modify the original: + + let mut p = vec![1]; + + borrow( + &p, + || p[0] = 5); // { dg-error ".E0502." "" { target *-*-* } } +} + +fn c() { + // Legal because the scope of the borrow does not include the + // modification: + let mut p = vec![1]; + borrow(&p, ||{}); + p[0] = 5; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-comp.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-comp.rs new file mode 100644 index 000000000000..597b0ab0cb18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-comp.rs @@ -0,0 +1,37 @@ +struct Point { x: isize, y: isize } + +fn a() { + let mut p = Point {x: 3, y: 4}; + let q = &p; + + // This assignment is illegal because the field x is not + // inherently mutable; since `p` was made immutable, `p.x` is now + // immutable. Otherwise the type of &_q.x (&isize) would be wrong. + p.x = 5; // { dg-error ".E0506." "" { target *-*-* } } + q.x; +} + +fn c() { + // this is sort of the opposite. We take a loan to the interior of `p` + // and then try to overwrite `p` as a whole. + + let mut p = Point {x: 3, y: 4}; + let q = &p.y; + p = Point {x: 5, y: 7};// { dg-error ".E0506." "" { target *-*-* } } + p.x; // silence warning + *q; // stretch loan +} + +fn d() { + // just for completeness's sake, the easy case, where we take the + // address of a subcomponent and then modify that subcomponent: + + let mut p = Point {x: 3, y: 4}; + let q = &p.y; + p.y = 5; // { dg-error ".E0506." "" { target *-*-* } } + *q; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.rs new file mode 100644 index 000000000000..76a0aa5968ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-andmut-in-aliasable-loc.rs @@ -0,0 +1,21 @@ +// Test that assignments to an `&mut` pointer which is found in a +// borrowed (but otherwise non-aliasable) location is illegal. + +struct S<'a> { + pointer: &'a mut isize +} + +fn a(s: &S) { + *s.pointer += 1; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn b(s: &mut S) { + *s.pointer += 1; +} + +fn c(s: & &mut S) { + *s.pointer += 1; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-andmut-in-borrowed-loc.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-andmut-in-borrowed-loc.rs new file mode 100644 index 000000000000..bb85f250bf22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-andmut-in-borrowed-loc.rs @@ -0,0 +1,24 @@ +// Test that assignments to an `&mut` pointer which is found in a +// borrowed (but otherwise non-aliasable) location is illegal. + +struct S<'a> { + pointer: &'a mut isize +} + +fn copy_borrowed_ptr<'a>(p: &'a mut S<'a>) -> S<'a> { + S { pointer: &mut *p.pointer } +} + +fn main() { + let mut x = 1; + + { + let mut y = S { pointer: &mut x }; + let z = copy_borrowed_ptr(&mut y); + *y.pointer += 1; +// { dg-error ".E0506." "" { target *-*-* } .-1 } +// { dg-error ".E0506." "" { target *-*-* } .-2 } + *z.pointer += 1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-constants.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-constants.rs new file mode 100644 index 000000000000..7788919826d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-constants.rs @@ -0,0 +1,7 @@ +static foo: isize = 5; + +fn main() { + // assigning to various global constants + foo = 6; // { dg-error ".E0594." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-subfield.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-subfield.rs new file mode 100644 index 000000000000..1173fa0d852f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assign-to-subfield.rs @@ -0,0 +1,24 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + struct A { + a: isize, + w: B, + } + struct B { + a: isize + } + let mut p = A { + a: 1, + w: B {a: 1}, + }; + + // even though `x` is not declared as a mutable field, + // `p` as a whole is mutable, so it can be modified. + p.a = 2; + + // this is true for an interior field too + p.w.a = 2; +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assignment-to-static-mut.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assignment-to-static-mut.rs new file mode 100644 index 000000000000..70e92ffa46d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-assignment-to-static-mut.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +// Test taken from #45641 (https://github.com/rust-lang/rust/issues/45641) + +static mut Y: u32 = 0; + +unsafe fn should_ok() { + Y = 1; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-auto-mut-ref-to-immut-var.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-auto-mut-ref-to-immut-var.rs new file mode 100644 index 000000000000..23e7e98e1705 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-auto-mut-ref-to-immut-var.rs @@ -0,0 +1,17 @@ +// Tests that auto-ref can't create mutable aliases to immutable memory. + +struct Foo { + x: isize +} + +impl Foo { + pub fn printme(&mut self) { + println!("{}", self.x); + } +} + +fn main() { + let x = Foo { x: 3 }; + x.printme(); // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-autoref-3261.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-autoref-3261.rs new file mode 100644 index 000000000000..20cb7c587ada --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-autoref-3261.rs @@ -0,0 +1,25 @@ +enum Either { Left(T), Right(U) } + +struct X(Either<(usize,usize), fn()>); + +impl X { + pub fn with(&self, blk: F) where F: FnOnce(&Either<(usize, usize), fn()>) { + let X(ref e) = *self; + blk(e) + } +} + +fn main() { + let mut x = X(Either::Right(main as fn())); + (&mut x).with( + |opt| { // { dg-error ".E0499." "" { target *-*-* } } + match opt { + &Either::Right(ref f) => { + x = X(Either::Left((0, 0))); + (*f)() + }, + _ => panic!() + } + }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-bad-nested-calls-free.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-bad-nested-calls-free.rs new file mode 100644 index 000000000000..5f2a6cf2c205 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-bad-nested-calls-free.rs @@ -0,0 +1,36 @@ +// Test that we detect nested calls that could free pointers evaluated +// for earlier arguments. + +#![feature(box_syntax)] + +fn rewrite(v: &mut Box) -> usize { + *v = box 22; + **v +} + +fn add(v: &usize, w: usize) -> usize { + *v + w +} + +fn implicit() { + let mut a: Box<_> = box 1; + + // Note the danger here: + // + // the pointer for the first argument has already been + // evaluated, but it gets freed when evaluating the second + // argument! + add( + &*a, + rewrite(&mut a)); // { dg-error ".E0502." "" { target *-*-* } } +} + +fn explicit() { + let mut a: Box<_> = box 1; + add( + &*a, + rewrite(&mut a)); // { dg-error ".E0502." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-bad-nested-calls-move.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-bad-nested-calls-move.rs new file mode 100644 index 000000000000..0dd45bb1fb9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-bad-nested-calls-move.rs @@ -0,0 +1,36 @@ +// Test that we detect nested calls that could free pointers evaluated +// for earlier arguments. + +#![feature(box_syntax)] + +fn rewrite(v: &mut Box) -> usize { + *v = box 22; + **v +} + +fn add(v: &usize, w: Box) -> usize { + *v + *w +} + +fn implicit() { + let mut a: Box<_> = box 1; + + // Note the danger here: + // + // the pointer for the first argument has already been + // evaluated, but it gets moved when evaluating the second + // argument! + add( + &*a, + a); // { dg-error ".E0505." "" { target *-*-* } } +} + +fn explicit() { + let mut a: Box<_> = box 1; + add( + &*a, + a); // { dg-error ".E0505." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-binding-mutbl.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-binding-mutbl.rs new file mode 100644 index 000000000000..a7d44e3f6cdc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-binding-mutbl.rs @@ -0,0 +1,17 @@ +// run-pass + +struct F { f: Vec } + +fn impure(_v: &[isize]) { +} + +pub fn main() { + let mut x = F {f: vec![3]}; + + match x { + F {f: ref mut v} => { + impure(v); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-block-unint.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-block-unint.rs new file mode 100644 index 000000000000..030840796dd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-block-unint.rs @@ -0,0 +1,8 @@ +fn force(f: F) where F: FnOnce() { f(); } +fn main() { + let x: isize; + force(|| { // { dg-error ".E0381." "" { target *-*-* } } + println!("{}", x); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-expr-block.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-expr-block.rs new file mode 100644 index 000000000000..12e9ea9106c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-expr-block.rs @@ -0,0 +1,19 @@ +// run-pass +#![feature(box_syntax)] + +fn borrow(x: &isize, f: F) where F: FnOnce(&isize) { + f(x) +} + +fn test1(x: &Box) { + borrow(&*(*x).clone(), |p| { + let x_a = &**x as *const isize; + assert!((x_a as usize) != (p as *const isize as usize)); + assert_eq!(unsafe{*x_a}, *p); + }) +} + +pub fn main() { + test1(&box 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-owned-ptr.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-owned-ptr.rs new file mode 100644 index 000000000000..18b766de917a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-owned-ptr.rs @@ -0,0 +1,135 @@ +#[derive(Copy, Clone)] +struct Foo { + bar1: Bar, + bar2: Bar +} + +#[derive(Copy, Clone)] +struct Bar { + int1: isize, + int2: isize, +} + +fn make_foo() -> Box { panic!() } + +fn borrow_same_field_twice_mut_mut() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1; + let _bar2 = &mut foo.bar1; // { dg-error ".E0499." "" { target *-*-* } } + *bar1; +} + +fn borrow_same_field_twice_mut_imm() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1; + let _bar2 = &foo.bar1; // { dg-error ".E0502." "" { target *-*-* } } + *bar1; +} + +fn borrow_same_field_twice_imm_mut() { + let mut foo = make_foo(); + let bar1 = &foo.bar1; + let _bar2 = &mut foo.bar1; // { dg-error ".E0502." "" { target *-*-* } } + *bar1; +} + +fn borrow_same_field_twice_imm_imm() { + let mut foo = make_foo(); + let bar1 = &foo.bar1; + let _bar2 = &foo.bar1; + *bar1; +} + +fn borrow_both_fields_mut() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1; + let _bar2 = &mut foo.bar2; + *bar1; +} + +fn borrow_both_mut_pattern() { + let mut foo = make_foo(); + match *foo { + Foo { bar1: ref mut _bar1, bar2: ref mut _bar2 } => { + *_bar1; + *_bar2; + } + } +} + +fn borrow_var_and_pattern() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1; + match *foo { + Foo { bar1: ref mut _bar1, bar2: _ } => {} +// { dg-error ".E0499." "" { target *-*-* } .-1 } + } + *bar1; +} + +fn borrow_mut_and_base_imm() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1.int1; + let _foo1 = &foo.bar1; // { dg-error ".E0502." "" { target *-*-* } } + let _foo2 = &*foo; // { dg-error ".E0502." "" { target *-*-* } } + *bar1; +} + +fn borrow_mut_and_base_mut() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1.int1; + let _foo1 = &mut foo.bar1; // { dg-error ".E0499." "" { target *-*-* } } + *bar1; +} + +fn borrow_mut_and_base_mut2() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1.int1; + let _foo2 = &mut *foo; // { dg-error ".E0499." "" { target *-*-* } } + *bar1; +} + +fn borrow_imm_and_base_mut() { + let mut foo = make_foo(); + let bar1 = &foo.bar1.int1; + let _foo1 = &mut foo.bar1; // { dg-error ".E0502." "" { target *-*-* } } + *bar1; +} + +fn borrow_imm_and_base_mut2() { + let mut foo = make_foo(); + let bar1 = &foo.bar1.int1; + let _foo2 = &mut *foo; // { dg-error ".E0502." "" { target *-*-* } } + *bar1; +} + +fn borrow_imm_and_base_imm() { + let mut foo = make_foo(); + let bar1 = &foo.bar1.int1; + let _foo1 = &foo.bar1; + let _foo2 = &*foo; + *bar1; +} + +fn borrow_mut_and_imm() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1; + let _foo1 = &foo.bar2; +} + +fn borrow_mut_from_imm() { + let foo = make_foo(); + let bar1 = &mut foo.bar1; // { dg-error ".E0596." "" { target *-*-* } } + *bar1; +} + +fn borrow_long_path_both_mut() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1.int1; + let foo1 = &mut foo.bar2.int2; + *bar1; + *foo1; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-stack-variable.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-stack-variable.rs new file mode 100644 index 000000000000..40d82f0247cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-stack-variable.rs @@ -0,0 +1,132 @@ +#[derive(Copy, Clone)] +struct Foo { + bar1: Bar, + bar2: Bar +} + +#[derive(Copy, Clone)] +struct Bar { + int1: isize, + int2: isize, +} + +fn make_foo() -> Foo { panic!() } + +fn borrow_same_field_twice_mut_mut() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1; + let _bar2 = &mut foo.bar1; // { dg-error ".E0499." "" { target *-*-* } } + *bar1; +} + +fn borrow_same_field_twice_mut_imm() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1; + let _bar2 = &foo.bar1; // { dg-error ".E0502." "" { target *-*-* } } + *bar1; +} + +fn borrow_same_field_twice_imm_mut() { + let mut foo = make_foo(); + let bar1 = &foo.bar1; + let _bar2 = &mut foo.bar1; // { dg-error ".E0502." "" { target *-*-* } } + *bar1; +} + +fn borrow_same_field_twice_imm_imm() { + let mut foo = make_foo(); + let bar1 = &foo.bar1; + let _bar2 = &foo.bar1; + *bar1; +} + +fn borrow_both_mut() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1; + let _bar2 = &mut foo.bar2; + *bar1; +} + +fn borrow_both_mut_pattern() { + let mut foo = make_foo(); + match foo { + Foo { bar1: ref mut _bar1, bar2: ref mut _bar2 } => {} + } +} + +fn borrow_var_and_pattern() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1; + match foo { + Foo { bar1: ref mut _bar1, bar2: _ } => {} // +// { dg-error ".E0499." "" { target *-*-* } .-1 } + } + *bar1; +} + +fn borrow_mut_and_base_imm() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1.int1; + let _foo1 = &foo.bar1; // { dg-error ".E0502." "" { target *-*-* } } + let _foo2 = &foo; // { dg-error ".E0502." "" { target *-*-* } } + *bar1; +} + +fn borrow_mut_and_base_mut() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1.int1; + let _foo1 = &mut foo.bar1; // { dg-error ".E0499." "" { target *-*-* } } + *bar1; +} + +fn borrow_mut_and_base_mut2() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1.int1; + let _foo2 = &mut foo; // { dg-error ".E0499." "" { target *-*-* } } + *bar1; +} + +fn borrow_imm_and_base_mut() { + let mut foo = make_foo(); + let bar1 = &foo.bar1.int1; + let _foo1 = &mut foo.bar1; // { dg-error ".E0502." "" { target *-*-* } } + *bar1; +} + +fn borrow_imm_and_base_mut2() { + let mut foo = make_foo(); + let bar1 = &foo.bar1.int1; + let _foo2 = &mut foo; // { dg-error ".E0502." "" { target *-*-* } } + *bar1; +} + +fn borrow_imm_and_base_imm() { + let mut foo = make_foo(); + let bar1 = &foo.bar1.int1; + let _foo1 = &foo.bar1; + let _foo2 = &foo; + *bar1; +} + +fn borrow_mut_and_imm() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1; + let _foo1 = &foo.bar2; + *bar1; +} + +fn borrow_mut_from_imm() { + let foo = make_foo(); + let bar1 = &mut foo.bar1; // { dg-error ".E0596." "" { target *-*-* } } + *bar1; +} + +fn borrow_long_path_both_mut() { + let mut foo = make_foo(); + let bar1 = &mut foo.bar1.int1; + let _foo1 = &mut foo.bar2.int2; + *bar1; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-temporary.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-temporary.rs new file mode 100644 index 000000000000..d820c235323b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-from-temporary.rs @@ -0,0 +1,15 @@ +// Test lifetimes are linked properly when we take reference +// to interior. + +fn id(x: T) -> T { x } + +struct Foo(isize); + +fn foo<'a>() -> &'a isize { + let &Foo(ref x) = &id(Foo(3)); + x // { dg-error ".E0515." "" { target *-*-* } } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-immut-deref-of-box-as-mut.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-immut-deref-of-box-as-mut.rs new file mode 100644 index 000000000000..8dc0204859ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-immut-deref-of-box-as-mut.rs @@ -0,0 +1,15 @@ +#![feature(box_syntax)] + +struct A; + +impl A { + fn foo(&mut self) { + } +} + +pub fn main() { + let a: Box<_> = box A; + a.foo(); +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs new file mode 100644 index 000000000000..f4c66905d082 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs @@ -0,0 +1,25 @@ +// Test that attempt to reborrow an `&mut` pointer in an aliasable +// location yields an error. +// +// Example from compiler/rustc_borrowck/borrowck/README.md + +fn foo(t0: & &mut isize) { + let t1 = t0; + let p: &isize = &**t0; + **t1 = 22; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn foo3(t0: &mut &mut isize) { + let t1 = &mut *t0; + let p: &isize = &**t0; // { dg-error ".E0502." "" { target *-*-* } } + **t1 = 22; +} + +fn foo4(t0: & &mut isize) { + let x: &mut isize = &mut **t0; // { dg-error ".E0596." "" { target *-*-* } } + *x += 1; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-mut-object-twice.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-mut-object-twice.rs new file mode 100644 index 000000000000..8cfe565c5772 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-mut-object-twice.rs @@ -0,0 +1,21 @@ +// Check that `&mut` objects cannot be borrowed twice, just like +// other `&mut` pointers. + + + +trait Foo { + fn f1(&mut self) -> &(); + fn f2(&mut self); +} + +fn test(x: &mut dyn Foo) { + let y = x.f1(); + x.f2(); // { dg-error ".E0499." "" { target *-*-* } } + y.use_ref(); +} + +fn main() {} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs new file mode 100644 index 000000000000..29ddf22be785 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-of-mut-base-ptr-safe.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_mut)] +#![allow(unused_variables)] +// Test that freezing an `&mut` pointer while referent is +// frozen is legal. +// +// Example from compiler/rustc_borrowck/borrowck/README.md + +// pretty-expanded FIXME #23616 + +fn foo<'a>(mut t0: &'a mut isize, + mut t1: &'a mut isize) { + let p: &isize = &*t0; // Freezes `*t0` + let mut t2 = &t0; + let q: &isize = &**t2; // Freezes `*t0`, but that's ok... + let r: &isize = &*t0; // ...after all, could do same thing directly. +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs new file mode 100644 index 000000000000..9f2373307012 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-overloaded-auto-deref.rs @@ -0,0 +1,104 @@ +// Test how overloaded deref interacts with borrows when only +// Deref and not DerefMut is implemented. + +use std::ops::Deref; +use std::rc::Rc; + +struct Point { + x: isize, + y: isize +} + +impl Point { + fn get(&self) -> (isize, isize) { + (self.x, self.y) + } + + fn set(&mut self, x: isize, y: isize) { + self.x = x; + self.y = y; + } + + fn x_ref(&self) -> &isize { + &self.x + } + + fn y_mut(&mut self) -> &mut isize { + &mut self.y + } +} + +fn deref_imm_field(x: Rc) { + let __isize = &x.y; +} + +fn deref_mut_field1(x: Rc) { + let __isize = &mut x.y; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_mut_field2(mut x: Rc) { + let __isize = &mut x.y; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_extend_field(x: &Rc) -> &isize { + &x.y +} + +fn deref_extend_mut_field1(x: &Rc) -> &mut isize { + &mut x.y // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_extend_mut_field2(x: &mut Rc) -> &mut isize { + &mut x.y // { dg-error ".E0596." "" { target *-*-* } } +} + +fn assign_field1<'a>(x: Rc) { + x.y = 3; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn assign_field2<'a>(x: &'a Rc) { + x.y = 3; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn assign_field3<'a>(x: &'a mut Rc) { + x.y = 3; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn deref_imm_method(x: Rc) { + let __isize = x.get(); +} + +fn deref_mut_method1(x: Rc) { + x.set(0, 0); // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_mut_method2(mut x: Rc) { + x.set(0, 0); // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_extend_method(x: &Rc) -> &isize { + x.x_ref() +} + +fn deref_extend_mut_method1(x: &Rc) -> &mut isize { + x.y_mut() // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_extend_mut_method2(x: &mut Rc) -> &mut isize { + x.y_mut() // { dg-error ".E0596." "" { target *-*-* } } +} + +fn assign_method1<'a>(x: Rc) { + *x.y_mut() = 3; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn assign_method2<'a>(x: &'a Rc) { + *x.y_mut() = 3; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn assign_method3<'a>(x: &'a mut Rc) { + *x.y_mut() = 3; // { dg-error ".E0596." "" { target *-*-* } } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-overloaded-deref.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-overloaded-deref.rs new file mode 100644 index 000000000000..c9d682b0b9fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrow-overloaded-deref.rs @@ -0,0 +1,44 @@ +// Test how overloaded deref interacts with borrows when only +// Deref and not DerefMut is implemented. + +use std::ops::Deref; +use std::rc::Rc; + +fn deref_imm(x: Rc) { + let __isize = &*x; +} + +fn deref_mut1(x: Rc) { + let __isize = &mut *x; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_mut2(mut x: Rc) { + let __isize = &mut *x; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_extend<'a>(x: &'a Rc) -> &'a isize { + &**x +} + +fn deref_extend_mut1<'a>(x: &'a Rc) -> &'a mut isize { + &mut **x // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_extend_mut2<'a>(x: &'a mut Rc) -> &'a mut isize { + &mut **x // { dg-error ".E0596." "" { target *-*-* } } +} + +fn assign1<'a>(x: Rc) { + *x = 3; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn assign2<'a>(x: &'a Rc) { + **x = 3; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn assign3<'a>(x: &'a mut Rc) { + **x = 3; // { dg-error ".E0594." "" { target *-*-* } } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.rs new file mode 100644 index 000000000000..7d55207b92bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.rs @@ -0,0 +1,23 @@ +struct Defer<'a> { + x: &'a [&'a str], +} + +impl<'a> Drop for Defer<'a> { + fn drop(&mut self) { + unsafe { + println!("{:?}", self.x); + } + } +} + +fn defer<'r>(x: &'r [&'r str]) -> Defer<'r> { + Defer { + x: x + } +} + +fn main() { + let x = defer(&vec!["Goodbye", "world!"]); // { dg-error ".E0716." "" { target *-*-* } } + x.x[0]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrowed-uniq-rvalue.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrowed-uniq-rvalue.rs new file mode 100644 index 000000000000..a990c35fdc2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-borrowed-uniq-rvalue.rs @@ -0,0 +1,16 @@ +//buggy.rs + +#![feature(box_syntax)] + +use std::collections::HashMap; + +fn main() { + let tmp: Box<_>; + let mut buggy_map: HashMap = HashMap::new(); + buggy_map.insert(42, &*Box::new(1)); // { dg-error ".E0716." "" { target *-*-* } } + + // but it is ok if we use a temporary + tmp = box 2; + buggy_map.insert(43, &*tmp); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-box-sensitivity.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-box-sensitivity.rs new file mode 100644 index 000000000000..48a9e1a1950b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-box-sensitivity.rs @@ -0,0 +1,151 @@ +// Test that `Box` is treated specially by borrow checking. This is the case +// because NLL reverted the deicision in rust-lang/rfcs#130. + +// run-pass + +#![feature(box_syntax)] + +struct A { + x: Box, + y: isize, +} + +struct B { + x: Box, + y: Box, +} + +struct C { + x: Box, + y: isize, +} + +struct D { + x: Box, + y: Box, +} + +fn copy_after_move() { + let a: Box<_> = box A { x: box 0, y: 1 }; + let _x = a.x; + let _y = a.y; +} + +fn move_after_move() { + let a: Box<_> = box B { x: box 0, y: box 1 }; + let _x = a.x; + let _y = a.y; +} + +fn borrow_after_move() { + let a: Box<_> = box A { x: box 0, y: 1 }; + let _x = a.x; + let _y = &a.y; +} + +fn move_after_borrow() { + let a: Box<_> = box B { x: box 0, y: box 1 }; + let _x = &a.x; + let _y = a.y; + use_imm(_x); +} +fn copy_after_mut_borrow() { + let mut a: Box<_> = box A { x: box 0, y: 1 }; + let _x = &mut a.x; + let _y = a.y; + use_mut(_x); +} +fn move_after_mut_borrow() { + let mut a: Box<_> = box B { x: box 0, y: box 1 }; + let _x = &mut a.x; + let _y = a.y; + use_mut(_x); +} +fn borrow_after_mut_borrow() { + let mut a: Box<_> = box A { x: box 0, y: 1 }; + let _x = &mut a.x; + let _y = &a.y; + use_mut(_x); +} +fn mut_borrow_after_borrow() { + let mut a: Box<_> = box A { x: box 0, y: 1 }; + let _x = &a.x; + let _y = &mut a.y; + use_imm(_x); +} +fn copy_after_move_nested() { + let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 }; + let _x = a.x.x; + let _y = a.y; +} + +fn move_after_move_nested() { + let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 }; + let _x = a.x.x; + let _y = a.y; +} + +fn borrow_after_move_nested() { + let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 }; + let _x = a.x.x; + let _y = &a.y; +} + +fn move_after_borrow_nested() { + let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 }; + let _x = &a.x.x; + let _y = a.y; + use_imm(_x); +} +fn copy_after_mut_borrow_nested() { + let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 }; + let _x = &mut a.x.x; + let _y = a.y; + use_mut(_x); +} +fn move_after_mut_borrow_nested() { + let mut a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 }; + let _x = &mut a.x.x; + let _y = a.y; + use_mut(_x); +} +fn borrow_after_mut_borrow_nested() { + let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 }; + let _x = &mut a.x.x; + let _y = &a.y; + use_mut(_x); +} +fn mut_borrow_after_borrow_nested() { + let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 }; + let _x = &a.x.x; + let _y = &mut a.y; + use_imm(_x); +} + +fn main() { + copy_after_move(); + move_after_move(); + borrow_after_move(); + + move_after_borrow(); + + copy_after_mut_borrow(); + move_after_mut_borrow(); + borrow_after_mut_borrow(); + mut_borrow_after_borrow(); + + copy_after_move_nested(); + move_after_move_nested(); + borrow_after_move_nested(); + + move_after_borrow_nested(); + + copy_after_mut_borrow_nested(); + move_after_mut_borrow_nested(); + borrow_after_mut_borrow_nested(); + mut_borrow_after_borrow_nested(); +} + +fn use_mut(_: &mut T) { } +fn use_imm(_: &T) { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-break-uninit-2.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-break-uninit-2.rs new file mode 100644 index 000000000000..734387e8e2d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-break-uninit-2.rs @@ -0,0 +1,15 @@ +fn foo() -> isize { + let x: isize; + + while 1 != 2 { + break; + x = 0; + } + + println!("{}", x); // { dg-error ".E0381." "" { target *-*-* } } + + return 17; +} + +fn main() { println!("{}", foo()); } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-break-uninit.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-break-uninit.rs new file mode 100644 index 000000000000..d3e05c464b1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-break-uninit.rs @@ -0,0 +1,15 @@ +fn foo() -> isize { + let x: isize; + + loop { + break; + x = 0; + } + + println!("{}", x); // { dg-error ".E0381." "" { target *-*-* } } + + return 17; +} + +fn main() { println!("{}", foo()); } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-mut-and-imm.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-mut-and-imm.rs new file mode 100644 index 000000000000..679bb9711710 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-mut-and-imm.rs @@ -0,0 +1,88 @@ +// Tests that two closures cannot simultaneously have mutable +// and immutable access to the variable. Issue #6801. + +#![feature(box_syntax)] + +fn get(x: &isize) -> isize { + *x +} + +fn set(x: &mut isize) { + *x = 4; +} + +fn a() { + let mut x = 3; + let c1 = || x = 4; + let c2 = || x * 5; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + drop(c1); +} + +fn b() { + let mut x = 3; + let c1 = || set(&mut x); + let c2 = || get(&x); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + drop(c1); +} + +fn c() { + let mut x = 3; + let c1 = || set(&mut x); + let c2 = || x * 5; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + drop(c1); +} + +fn d() { + let mut x = 3; + let c2 = || x * 5; + x = 5; +// { dg-error ".E0506." "" { target *-*-* } .-1 } + drop(c2); +} + +fn e() { + let mut x = 3; + let c1 = || get(&x); + x = 5; +// { dg-error ".E0506." "" { target *-*-* } .-1 } + drop(c1); +} + +fn f() { + let mut x: Box<_> = box 3; + let c1 = || get(&*x); + *x = 5; +// { dg-error ".E0506." "" { target *-*-* } .-1 } + drop(c1); +} + +fn g() { + struct Foo { + f: Box + } + + let mut x: Box<_> = box Foo { f: box 3 }; + let c1 = || get(&*x.f); + *x.f = 5; +// { dg-error ".E0506." "" { target *-*-* } .-1 } + drop(c1); +} + +fn h() { + struct Foo { + f: Box + } + + let mut x: Box<_> = box Foo { f: box 3 }; + let c1 = || get(&*x.f); + let c2 = || *x.f = 5; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + drop(c1); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-mut-of-imm.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-mut-of-imm.rs new file mode 100644 index 000000000000..13e01629833d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-mut-of-imm.rs @@ -0,0 +1,19 @@ +// Tests that two closures cannot simultaneously have mutable +// and immutable access to the variable. Issue #6801. + +fn set(x: &mut isize) { + *x = 4; +} + +fn a(x: &isize) { + let mut c1 = || set(&mut *x); +// { dg-error ".E0596." "" { target *-*-* } .-1 } + let mut c2 = || set(&mut *x); +// { dg-error ".E0524." "" { target *-*-* } .-1 } +// { dg-error ".E0524." "" { target *-*-* } .-2 } + c2(); c1(); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-mut-of-mut.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-mut-of-mut.rs new file mode 100644 index 000000000000..f9245eed40f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-mut-of-mut.rs @@ -0,0 +1,21 @@ +// Tests that two closures cannot simultaneously both have mutable +// access to the variable. Related to issue #6801. + +fn get(x: &isize) -> isize { + *x +} + +fn set(x: &mut isize) { + *x = 4; +} + +fn a(x: &mut isize) { + let mut c1 = || set(&mut *x); + let mut c2 = || set(&mut *x); +// { dg-error ".E0524." "" { target *-*-* } .-1 } + c2(); c1(); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-slice-patterns-ok.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-slice-patterns-ok.rs new file mode 100644 index 000000000000..db4502a65561 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-slice-patterns-ok.rs @@ -0,0 +1,118 @@ +// Check that closure captures for slice patterns are inferred correctly + +#![allow(unused_variables)] + +// run-pass + +fn arr_by_ref(x: [String; 3]) { + let r = &x; + let f = || { + let [ref y, ref z @ ..] = x; + }; + f(); + f(); + // Ensure `x` was borrowed + drop(r); + // Ensure that `x` wasn't moved from. + drop(x); +} + +fn arr_by_mut(mut x: [String; 3]) { + let mut f = || { + let [ref mut y, ref mut z @ ..] = x; + }; + f(); + f(); + drop(x); +} + +fn arr_by_move(x: [String; 3]) { + let f = || { + let [y, z @ ..] = x; + }; + f(); +} + +fn arr_ref_by_ref(x: &[String; 3]) { + let r = &x; + let f = || { + let [ref y, ref z @ ..] = *x; + }; + let g = || { + let [y, z @ ..] = x; + }; + f(); + g(); + f(); + g(); + drop(r); + drop(x); +} + +fn arr_ref_by_mut(x: &mut [String; 3]) { + let mut f = || { + let [ref mut y, ref mut z @ ..] = *x; + }; + f(); + f(); + let mut g = || { + let [y, z @ ..] = x; + // Ensure binding mode was chosen correctly: + std::mem::swap(y, &mut z[0]); + }; + g(); + g(); + drop(x); +} + +fn arr_box_by_move(x: Box<[String; 3]>) { + let f = || { + let [y, z @ ..] = *x; + }; + f(); +} + +fn slice_by_ref(x: &[String]) { + let r = &x; + let f = || { + if let [ref y, ref z @ ..] = *x {} + }; + let g = || { + if let [y, z @ ..] = x {} + }; + f(); + g(); + f(); + g(); + drop(r); + drop(x); +} + +fn slice_by_mut(x: &mut [String]) { + let mut f = || { + if let [ref mut y, ref mut z @ ..] = *x {} + }; + f(); + f(); + let mut g = || { + if let [y, z @ ..] = x { + // Ensure binding mode was chosen correctly: + std::mem::swap(y, &mut z[0]); + } + }; + g(); + g(); + drop(x); +} + +fn main() { + arr_by_ref(Default::default()); + arr_by_mut(Default::default()); + arr_by_move(Default::default()); + arr_ref_by_ref(&Default::default()); + arr_ref_by_mut(&mut Default::default()); + arr_box_by_move(Default::default()); + slice_by_ref(&<[_; 3]>::default()); + slice_by_mut(&mut <[_; 3]>::default()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-slice-patterns.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-slice-patterns.rs new file mode 100644 index 000000000000..0c90407cb690 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-slice-patterns.rs @@ -0,0 +1,83 @@ +// Check that closure captures for slice patterns are inferred correctly + +fn arr_by_ref(mut x: [String; 3]) { + let f = || { + let [ref y, ref z @ ..] = x; + }; + let r = &mut x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + f(); +} + +fn arr_by_mut(mut x: [String; 3]) { + let mut f = || { + let [ref mut y, ref mut z @ ..] = x; + }; + let r = &x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + f(); +} + +fn arr_by_move(x: [String; 3]) { + let f = || { + let [y, z @ ..] = x; + }; + &x; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn arr_ref_by_ref(x: &mut [String; 3]) { + let f = || { + let [ref y, ref z @ ..] = *x; + }; + let r = &mut *x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + f(); +} + +fn arr_ref_by_uniq(x: &mut [String; 3]) { + let mut f = || { + let [ref mut y, ref mut z @ ..] = *x; + }; + let r = &x; +// { dg-error ".E0501." "" { target *-*-* } .-1 } + f(); +} + +fn arr_box_by_move(x: Box<[String; 3]>) { + let f = || { + let [y, z @ ..] = *x; + }; + &x; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn slice_by_ref(x: &mut [String]) { + let f = || { + if let [ref y, ref z @ ..] = *x {} + }; + let r = &mut *x; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + f(); +} + +fn slice_by_uniq(x: &mut [String]) { + let mut f = || { + if let [ref mut y, ref mut z @ ..] = *x {} + }; + let r = &x; +// { dg-error ".E0501." "" { target *-*-* } .-1 } + f(); +} + +fn main() { + arr_by_ref(Default::default()); + arr_by_mut(Default::default()); + arr_by_move(Default::default()); + arr_ref_by_ref(&mut Default::default()); + arr_ref_by_uniq(&mut Default::default()); + arr_box_by_move(Default::default()); + slice_by_ref(&mut <[_; 3]>::default()); + slice_by_uniq(&mut <[_; 3]>::default()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-two-imm.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-two-imm.rs new file mode 100644 index 000000000000..c1eb23301d03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-two-imm.rs @@ -0,0 +1,42 @@ +// run-pass +// Tests that two closures can simultaneously have immutable +// access to the variable, whether that immutable access be used +// for direct reads or for taking immutable ref. Also check +// that the main function can read the variable too while +// the closures are in scope. Issue #6801. + + +fn a() -> i32 { + let mut x = 3; + x += 1; + let c1 = || x * 4; + let c2 = || x * 5; + c1() * c2() * x +} + +fn get(x: &i32) -> i32 { + *x * 4 +} + +fn b() -> i32 { + let mut x = 3; + x += 1; + let c1 = || get(&x); + let c2 = || get(&x); + c1() * c2() * x +} + +fn c() -> i32 { + let mut x = 3; + x += 1; + let c1 = || x * 5; + let c2 = || get(&x); + c1() * c2() * x +} + +pub fn main() { + assert_eq!(a(), 1280); + assert_eq!(b(), 1024); + assert_eq!(c(), 1280); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-two-mut-fail.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-two-mut-fail.rs new file mode 100644 index 000000000000..f71f4134d521 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-two-mut-fail.rs @@ -0,0 +1,60 @@ +// Tests that two closures cannot simultaneously have mutable +// access to the variable, whether that mutable access be used +// for direct assignment or for taking mutable ref. Issue #6801. + +#![feature(box_syntax)] + + + + + +fn to_fn_mut(f: F) -> F { f } + +fn a() { + let mut x = 3; + let c1 = to_fn_mut(|| x = 4); + let c2 = to_fn_mut(|| x = 5); // { dg-error ".E0499." "" { target *-*-* } } + c1; +} + +fn set(x: &mut isize) { + *x = 4; +} + +fn b() { + let mut x = 3; + let c1 = to_fn_mut(|| set(&mut x)); + let c2 = to_fn_mut(|| set(&mut x)); // { dg-error ".E0499." "" { target *-*-* } } + c1; +} + +fn c() { + let mut x = 3; + let c1 = to_fn_mut(|| x = 5); + let c2 = to_fn_mut(|| set(&mut x)); // { dg-error ".E0499." "" { target *-*-* } } + c1; +} + +fn d() { + let mut x = 3; + let c1 = to_fn_mut(|| x = 5); + let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure) +// { dg-error ".E0499." "" { target *-*-* } .-1 } + c1; +} + +fn g() { + struct Foo { + f: Box + } + + let mut x: Box<_> = box Foo { f: box 3 }; + let c1 = to_fn_mut(|| set(&mut *x.f)); + let c2 = to_fn_mut(|| set(&mut *x.f)); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + c1; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-two-mut.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-two-mut.rs new file mode 100644 index 000000000000..c710cc52aa6c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-two-mut.rs @@ -0,0 +1,56 @@ +// Tests that two closures cannot simultaneously have mutable +// access to the variable, whether that mutable access be used +// for direct assignment or for taking mutable ref. Issue #6801. + +#![feature(box_syntax)] + +fn to_fn_mut(f: F) -> F { f } + +fn a() { + let mut x = 3; + let c1 = to_fn_mut(|| x = 4); + let c2 = to_fn_mut(|| x = 5); // { dg-error ".E0499." "" { target *-*-* } } + drop((c1, c2)); +} + +fn set(x: &mut isize) { + *x = 4; +} + +fn b() { + let mut x = 3; + let c1 = to_fn_mut(|| set(&mut x)); + let c2 = to_fn_mut(|| set(&mut x)); // { dg-error ".E0499." "" { target *-*-* } } + drop((c1, c2)); +} + +fn c() { + let mut x = 3; + let c1 = to_fn_mut(|| x = 5); + let c2 = to_fn_mut(|| set(&mut x)); // { dg-error ".E0499." "" { target *-*-* } } + drop((c1, c2)); +} + +fn d() { + let mut x = 3; + let c1 = to_fn_mut(|| x = 5); + let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure) +// { dg-error ".E0499." "" { target *-*-* } .-1 } + drop((c1, c2)); +} + +fn g() { + struct Foo { + f: Box + } + + let mut x: Box<_> = box Foo { f: box 3 }; + let c1 = to_fn_mut(|| set(&mut *x.f)); + let c2 = to_fn_mut(|| set(&mut *x.f)); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + drop((c1, c2)); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-unique-imm.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-unique-imm.rs new file mode 100644 index 000000000000..0ad07593ade5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-unique-imm.rs @@ -0,0 +1,19 @@ +struct Foo { + x: isize, +} + +pub fn main() { + let mut this = &mut Foo { + x: 1, + }; + let mut r = || { + let p = &this.x; + &mut this.x; // { dg-error ".E0502." "" { target *-*-* } } + p.use_ref(); + }; + r() +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-unique.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-unique.rs new file mode 100644 index 000000000000..de8e98e45a2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-unique.rs @@ -0,0 +1,55 @@ +// Tests that a closure which requires mutable access to the referent +// of an `&mut` requires a "unique" borrow -- that is, the variable to +// be borrowed (here, `x`) will not be borrowed *mutably*, but +// may be *immutable*, but we cannot allow +// multiple borrows. + + + +fn get(x: &isize) -> isize { + *x +} + +fn set(x: &mut isize) -> isize { + *x +} + +fn a(x: &mut isize) { + let c1 = || get(x); + let c2 = || get(x); + c1(); + c2(); +} + +fn b(x: &mut isize) { + let c1 = || get(x); + let c2 = || set(x); // { dg-error ".E0500." "" { target *-*-* } } + c1; +} + +fn c(x: &mut isize) { + let c1 = || get(x); + let c2 = || { get(x); set(x); }; // { dg-error ".E0500." "" { target *-*-* } } + c1; +} + +fn d(x: &mut isize) { + let c1 = || set(x); + let c2 = || set(x); // { dg-error ".E0524." "" { target *-*-* } } + c1; +} + +fn e(x: &'static mut isize) { + let c1 = |y: &'static mut isize| x = y; +// { dg-error ".E0594." "" { target *-*-* } .-1 } + c1; +} + +fn f(x: &'static mut isize) { + let c1 = || x = panic!(); // OK assignment is unreachable. + c1; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-use-after-free.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-use-after-free.rs new file mode 100644 index 000000000000..a22ff78b888f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-closures-use-after-free.rs @@ -0,0 +1,24 @@ +// Tests that a closure which mutates a local variable +// cannot also be supplied a borrowed version of that +// variable's contents. Issue #11192. + +#![feature(box_syntax)] + +struct Foo { + x: isize +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("drop {}", self.x); + } +} + +fn main() { + let mut ptr: Box<_> = box Foo { x: 0 }; + let mut test = |foo: &Foo| { + ptr = box Foo { x: ptr.x + 1 }; + }; + test(&*ptr); // { dg-error ".E0502." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-consume-unsize-vec.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-consume-unsize-vec.rs new file mode 100644 index 000000000000..b0b5f99e56cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-consume-unsize-vec.rs @@ -0,0 +1,13 @@ +// Check that we report an error if an upcast box is moved twice. + +fn consume(_: Box<[i32]>) { +} + +fn foo(b: Box<[i32;5]>) { + consume(b); + consume(b); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-consume-upcast-box.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-consume-upcast-box.rs new file mode 100644 index 000000000000..17ce60463ad7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-consume-upcast-box.rs @@ -0,0 +1,15 @@ +// Check that we report an error if an upcast box is moved twice. + +trait Foo { fn dummy(&self); } + +fn consume(_: Box) { +} + +fn foo(b: Box) { + consume(b); + consume(b); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-describe-lvalue.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-describe-lvalue.rs new file mode 100644 index 000000000000..1d15ec87cdb8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-describe-lvalue.rs @@ -0,0 +1,282 @@ +// ignore-tidy-linelength + +pub struct Foo { + x: u32 +} + +pub struct Bar(u32); + +pub enum Baz { + X(u32) +} + +union U { + a: u8, + b: u64, +} + +impl Foo { + fn x(&mut self) -> &mut u32 { &mut self.x } +} + +impl Bar { + fn x(&mut self) -> &mut u32 { &mut self.0 } +} + +impl Baz { + fn x(&mut self) -> &mut u32 { + match *self { + Baz::X(ref mut value) => value + } + } +} + +fn main() { + // Local and field from struct + { + let mut f = Foo { x: 22 }; + let x = f.x(); + f.x; // { dg-error ".E0503." "" { target *-*-* } } + drop(x); + } + // Local and field from tuple-struct + { + let mut g = Bar(22); + let x = g.x(); + g.0; // { dg-error ".E0503." "" { target *-*-* } } + drop(x); + } + // Local and field from tuple + { + let mut h = (22, 23); + let x = &mut h.0; + h.0; // { dg-error ".E0503." "" { target *-*-* } } + drop(x); + } + // Local and field from enum + { + let mut e = Baz::X(2); + let x = e.x(); + match e { + Baz::X(value) => value // { dg-error ".E0503." "" { target *-*-* } } + }; + drop(x); + } + // Local and field from union + unsafe { + let mut u = U { b: 0 }; + let x = &mut u.a; + u.a; // { dg-error ".E0503." "" { target *-*-* } } + drop(x); + } + // Deref and field from struct + { + let mut f = Box::new(Foo { x: 22 }); + let x = f.x(); + f.x; // { dg-error ".E0503." "" { target *-*-* } } + drop(x); + } + // Deref and field from tuple-struct + { + let mut g = Box::new(Bar(22)); + let x = g.x(); + g.0; // { dg-error ".E0503." "" { target *-*-* } } + drop(x); + } + // Deref and field from tuple + { + let mut h = Box::new((22, 23)); + let x = &mut h.0; + h.0; // { dg-error ".E0503." "" { target *-*-* } } + drop(x); + } + // Deref and field from enum + { + let mut e = Box::new(Baz::X(3)); + let x = e.x(); + match *e { + Baz::X(value) => value +// { dg-error ".E0503." "" { target *-*-* } .-1 } + }; + drop(x); + } + // Deref and field from union + unsafe { + let mut u = Box::new(U { b: 0 }); + let x = &mut u.a; + u.a; // { dg-error ".E0503." "" { target *-*-* } } + drop(x); + } + // Constant index + { + let mut v = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let x = &mut v; + match v { + &[x, _, .., _, _] => println!("{}", x), +// { dg-error ".E0503." "" { target *-*-* } .-1 } + _ => panic!("other case"), + } + match v { + &[_, x, .., _, _] => println!("{}", x), +// { dg-error ".E0503." "" { target *-*-* } .-1 } + _ => panic!("other case"), + } + match v { + &[_, _, .., x, _] => println!("{}", x), +// { dg-error ".E0503." "" { target *-*-* } .-1 } + _ => panic!("other case"), + } + match v { + &[_, _, .., _, x] => println!("{}", x), +// { dg-error ".E0503." "" { target *-*-* } .-1 } + _ => panic!("other case"), + } + drop(x); + } + // Subslices + { + let mut v = &[1, 2, 3, 4, 5]; + let x = &mut v; + match v { + &[x @ ..] => println!("{:?}", x), +// { dg-error ".E0503." "" { target *-*-* } .-1 } + _ => panic!("other case"), + } + match v { + &[_, x @ ..] => println!("{:?}", x), +// { dg-error ".E0503." "" { target *-*-* } .-1 } + _ => panic!("other case"), + } + match v { + &[x @ .., _] => println!("{:?}", x), +// { dg-error ".E0503." "" { target *-*-* } .-1 } + _ => panic!("other case"), + } + match v { + &[_, x @ .., _] => println!("{:?}", x), +// { dg-error ".E0503." "" { target *-*-* } .-1 } + _ => panic!("other case"), + } + drop(x); + } + // Downcasted field + { + enum E { A(X), B { x: X } } + + let mut e = E::A(3); + let x = &mut e; + match e { + E::A(ref ax) => +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + println!("e.ax: {:?}", ax), + E::B { x: ref bx } => +// { dg-error ".E0502." "" { target *-*-* } .-1 } + println!("e.bx: {:?}", bx), + } + drop(x); + } + // Field in field + { + struct F { x: u32, y: u32 }; + struct S { x: F, y: (u32, u32), }; + let mut s = S { x: F { x: 1, y: 2}, y: (999, 998) }; + let x = &mut s; + match s { + S { y: (ref y0, _), .. } => +// { dg-error ".E0502." "" { target *-*-* } .-1 } + println!("y0: {:?}", y0), + _ => panic!("other case"), + } + match s { + S { x: F { y: ref x0, .. }, .. } => +// { dg-error ".E0502." "" { target *-*-* } .-1 } + println!("x0: {:?}", x0), + _ => panic!("other case"), + } + drop(x); + } + // Field of ref + { + struct Block<'a> { + current: &'a u8, + unrelated: &'a u8, + }; + + fn bump<'a>(mut block: &mut Block<'a>) { + let x = &mut block; + let p: &'a u8 = &*block.current; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + // See issue rust#38899 + drop(x); + } + } + // Field of ptr + { + struct Block2 { + current: *const u8, + unrelated: *const u8, + } + + unsafe fn bump2(mut block: *mut Block2) { + let x = &mut block; + let p : *const u8 = &*(*block).current; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + // See issue rust#38899 + drop(x); + } + } + // Field of index + { + struct F {x: u32, y: u32}; + let mut v = &[F{x: 1, y: 2}, F{x: 3, y: 4}]; + let x = &mut v; + v[0].y; +// { dg-error ".E0503." "" { target *-*-* } .-1 } +// { dg-error ".E0503." "" { target *-*-* } .-2 } + drop(x); + } + // Field of constant index + { + struct F {x: u32, y: u32}; + let mut v = &[F{x: 1, y: 2}, F{x: 3, y: 4}]; + let x = &mut v; + match v { + &[_, F {x: ref xf, ..}] => println!("{}", xf), +// { dg-error ".E0502." "" { target *-*-* } .-1 } + _ => panic!("other case") + } + drop(x); + } + // Field from upvar + { + let mut x = 0; + || { + let y = &mut x; + &mut x; // { dg-error ".E0499." "" { target *-*-* } } + *y = 1; + }; + } + // Field from upvar nested + { + let mut x = 0; + || { + || { // { dg-error "" "" { target *-*-* } } + let y = &mut x; + &mut x; // { dg-error ".E0499." "" { target *-*-* } } + *y = 1; + drop(y); + } + }; + } + { + fn foo(x: Vec) { + let c = || { + drop(x); + drop(x); // { dg-error ".E0382." "" { target *-*-* } } + }; + c(); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-drop-from-guard.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-drop-from-guard.rs new file mode 100644 index 000000000000..f6933f5fb88f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-drop-from-guard.rs @@ -0,0 +1,14 @@ +//compile-flags: -Z borrowck=mir + +fn foo(_:String) {} + +fn main() +{ + let my_str = "hello".to_owned(); + match Some(42) { + Some(_) if { drop(my_str); false } => {} + Some(_) => {} + None => { foo(my_str); } // { dg-error ".E0382." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-escaping-closure-error-1.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-escaping-closure-error-1.rs new file mode 100644 index 000000000000..b540e39e1b75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-escaping-closure-error-1.rs @@ -0,0 +1,16 @@ +use std::thread::spawn; + +// Test that we give a custom error (E0373) for the case where a +// closure is escaping current frame, and offer a suggested code edit. +// I refrained from including the precise message here, but the +// original text as of the time of this writing is: +// +// closure may outlive the current function, but it borrows `books`, +// which is owned by the current function + +fn main() { + let mut books = vec![1,2,3]; + spawn(|| books.push(4)); +// { dg-error ".E0373." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-escaping-closure-error-2.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-escaping-closure-error-2.rs new file mode 100644 index 000000000000..22a175d8d844 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-escaping-closure-error-2.rs @@ -0,0 +1,16 @@ +// Test that we give a custom error (E0373) for the case where a +// closure is escaping current frame, and offer a suggested code edit. +// I refrained from including the precise message here, but the +// original text as of the time of this writing is: +// +// closure may outlive the current function, but it borrows `books`, +// which is owned by the current function + +fn foo<'a>(x: &'a i32) -> Box { + let mut books = vec![1,2,3]; + Box::new(|| books.push(4)) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs new file mode 100644 index 000000000000..b600c4e2998e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs @@ -0,0 +1,31 @@ +// This is a test that the `#![feature(nll)]` opt-in overrides the +// migration mode. The intention here is to emulate the goal behavior +// that `--edition 2018` effects on borrowck (modeled here by `-Z +// borrowck=migrate`) are themselves overridden by the +// `#![feature(nll)]` opt-in. +// +// Therefore, for developer convenience, under `#[feature(nll)]` the +// NLL checks will be emitted as errors *even* in the presence of `-Z +// borrowck=migrate`. + +// revisions: zflag edition +//[zflag]compile-flags: -Z borrowck=migrate +//[edition]edition:2018 + +#![feature(nll)] + +fn main() { + match Some(&4) { + None => {}, + ref mut foo + if { + (|| { let bar = foo; bar.take() })(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + false + } => {}, + Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."), + _ => println!("Here is some supposedly unreachable code."), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-field-sensitivity-rpass.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-field-sensitivity-rpass.rs new file mode 100644 index 000000000000..ff5cc8766ad1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-field-sensitivity-rpass.rs @@ -0,0 +1,267 @@ +// run-pass +#![allow(unused_mut)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +struct A { a: isize, b: Box } +struct B { a: Box, b: Box } + +fn move_after_copy() { + let x = A { a: 1, b: box 2 }; + drop(x.a); + drop(x.b); +} + +fn move_after_fu_copy() { + let x = A { a: 1, b: box 2 }; + let _y = A { b: box 3, .. x }; + drop(x.b); +} + +fn fu_move_after_copy() { + let x = A { a: 1, b: box 2 }; + drop(x.a); + let _y = A { a: 3, .. x }; +} + +fn fu_move_after_fu_copy() { + let x = A { a: 1, b: box 2 }; + let _y = A { b: box 3, .. x }; + let _z = A { a: 4, .. x }; +} + +fn copy_after_move() { + let x = A { a: 1, b: box 2 }; + drop(x.b); + drop(x.a); +} + +fn copy_after_fu_move() { + let x = A { a: 1, b: box 2 }; + let y = A { a: 3, .. x }; + drop(x.a); +} + +fn fu_copy_after_move() { + let x = A { a: 1, b: box 2 }; + drop(x.b); + let _y = A { b: box 3, .. x }; +} + +fn fu_copy_after_fu_move() { + let x = A { a: 1, b: box 2 }; + let _y = A { a: 3, .. x }; + let _z = A { b: box 3, .. x }; +} + +fn borrow_after_move() { + let x = A { a: 1, b: box 2 }; + drop(x.b); + let p = &x.a; + drop(*p); +} + +fn borrow_after_fu_move() { + let x = A { a: 1, b: box 2 }; + let _y = A { a: 3, .. x }; + let p = &x.a; + drop(*p); +} + +fn move_after_borrow() { + let x = A { a: 1, b: box 2 }; + let p = &x.a; + drop(x.b); + drop(*p); +} + +fn fu_move_after_borrow() { + let x = A { a: 1, b: box 2 }; + let p = &x.a; + let _y = A { a: 3, .. x }; + drop(*p); +} + +fn mut_borrow_after_mut_borrow() { + let mut x = A { a: 1, b: box 2 }; + let p = &mut x.a; + let q = &mut x.b; + drop(*p); + drop(**q); +} + +fn move_after_move() { + let x = B { a: box 1, b: box 2 }; + drop(x.a); + drop(x.b); +} + +fn move_after_fu_move() { + let x = B { a: box 1, b: box 2 }; + let y = B { a: box 3, .. x }; + drop(x.a); +} + +fn fu_move_after_move() { + let x = B { a: box 1, b: box 2 }; + drop(x.a); + let z = B { a: box 3, .. x }; + drop(z.b); +} + +fn fu_move_after_fu_move() { + let x = B { a: box 1, b: box 2 }; + let _y = B { b: box 3, .. x }; + let _z = B { a: box 4, .. x }; +} + +fn copy_after_assign_after_move() { + let mut x = A { a: 1, b: box 2 }; + drop(x.b); + x = A { a: 3, b: box 4 }; + drop(*x.b); +} + +fn copy_after_assign_after_fu_move() { + let mut x = A { a: 1, b: box 2 }; + let _y = A { a: 3, .. x }; + x = A { a: 3, b: box 4 }; + drop(*x.b); +} + +fn copy_after_field_assign_after_move() { + let mut x = A { a: 1, b: box 2 }; + drop(x.b); + x.b = box 3; + drop(*x.b); +} + +fn copy_after_field_assign_after_fu_move() { + let mut x = A { a: 1, b: box 2 }; + let _y = A { a: 3, .. x }; + x.b = box 3; + drop(*x.b); +} + +fn borrow_after_assign_after_move() { + let mut x = A { a: 1, b: box 2 }; + drop(x.b); + x = A { a: 3, b: box 4 }; + let p = &x.b; + drop(**p); +} + +fn borrow_after_assign_after_fu_move() { + let mut x = A { a: 1, b: box 2 }; + let _y = A { a: 3, .. x }; + x = A { a: 3, b: box 4 }; + let p = &x.b; + drop(**p); +} + +fn borrow_after_field_assign_after_move() { + let mut x = A { a: 1, b: box 2 }; + drop(x.b); + x.b = box 3; + let p = &x.b; + drop(**p); +} + +fn borrow_after_field_assign_after_fu_move() { + let mut x = A { a: 1, b: box 2 }; + let _y = A { a: 3, .. x }; + x.b = box 3; + let p = &x.b; + drop(**p); +} + +fn move_after_assign_after_move() { + let mut x = A { a: 1, b: box 2 }; + let _y = x.b; + x = A { a: 3, b: box 4 }; + drop(x.b); +} + +fn move_after_assign_after_fu_move() { + let mut x = A { a: 1, b: box 2 }; + let _y = A { a: 3, .. x }; + x = A { a: 3, b: box 4 }; + drop(x.b); +} + +fn move_after_field_assign_after_move() { + let mut x = A { a: 1, b: box 2 }; + drop(x.b); + x.b = box 3; + drop(x.b); +} + +fn move_after_field_assign_after_fu_move() { + let mut x = A { a: 1, b: box 2 }; + let _y = A { a: 3, .. x }; + x.b = box 3; + drop(x.b); +} + +fn copy_after_assign_after_uninit() { + let mut x: A; + x = A { a: 1, b: box 2 }; + drop(x.a); +} + +fn borrow_after_assign_after_uninit() { + let mut x: A; + x = A { a: 1, b: box 2 }; + let p = &x.a; + drop(*p); +} + +fn move_after_assign_after_uninit() { + let mut x: A; + x = A { a: 1, b: box 2 }; + drop(x.b); +} + +fn main() { + move_after_copy(); + move_after_fu_copy(); + fu_move_after_copy(); + fu_move_after_fu_copy(); + copy_after_move(); + copy_after_fu_move(); + fu_copy_after_move(); + fu_copy_after_fu_move(); + + borrow_after_move(); + borrow_after_fu_move(); + move_after_borrow(); + fu_move_after_borrow(); + mut_borrow_after_mut_borrow(); + + move_after_move(); + move_after_fu_move(); + fu_move_after_move(); + fu_move_after_fu_move(); + + copy_after_assign_after_move(); + copy_after_assign_after_fu_move(); + copy_after_field_assign_after_move(); + copy_after_field_assign_after_fu_move(); + + borrow_after_assign_after_move(); + borrow_after_assign_after_fu_move(); + borrow_after_field_assign_after_move(); + borrow_after_field_assign_after_fu_move(); + + move_after_assign_after_move(); + move_after_assign_after_fu_move(); + move_after_field_assign_after_move(); + move_after_field_assign_after_fu_move(); + + copy_after_assign_after_uninit(); + borrow_after_assign_after_uninit(); + move_after_assign_after_uninit(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-field-sensitivity.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-field-sensitivity.rs new file mode 100644 index 000000000000..d252aa431bc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-field-sensitivity.rs @@ -0,0 +1,117 @@ +#![feature(box_syntax)] + +struct A { a: isize, b: Box } + +fn deref_after_move() { + let x = A { a: 1, b: box 2 }; + drop(x.b); + drop(*x.b); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn deref_after_fu_move() { + let x = A { a: 1, b: box 2 }; + let y = A { a: 3, .. x }; + drop(*x.b); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn borrow_after_move() { + let x = A { a: 1, b: box 2 }; + drop(x.b); + let p = &x.b; // { dg-error ".E0382." "" { target *-*-* } } + drop(**p); +} + +fn borrow_after_fu_move() { + let x = A { a: 1, b: box 2 }; + let _y = A { a: 3, .. x }; + let p = &x.b; // { dg-error ".E0382." "" { target *-*-* } } + drop(**p); +} + +fn move_after_borrow() { + let x = A { a: 1, b: box 2 }; + let p = &x.b; + drop(x.b); // { dg-error ".E0505." "" { target *-*-* } } + drop(**p); +} + +fn fu_move_after_borrow() { + let x = A { a: 1, b: box 2 }; + let p = &x.b; + let _y = A { a: 3, .. x }; // { dg-error ".E0505." "" { target *-*-* } } + drop(**p); +} + +fn mut_borrow_after_mut_borrow() { + let mut x = A { a: 1, b: box 2 }; + let p = &mut x.a; + let q = &mut x.a; // { dg-error ".E0499." "" { target *-*-* } } + drop(*p); + drop(*q); +} + +fn move_after_move() { + let x = A { a: 1, b: box 2 }; + drop(x.b); + drop(x.b); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_after_fu_move() { + let x = A { a: 1, b: box 2 }; + let _y = A { a: 3, .. x }; + drop(x.b); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn fu_move_after_move() { + let x = A { a: 1, b: box 2 }; + drop(x.b); + let _z = A { a: 3, .. x }; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn fu_move_after_fu_move() { + let x = A { a: 1, b: box 2 }; + let _y = A { a: 3, .. x }; + let _z = A { a: 4, .. x }; // { dg-error ".E0382." "" { target *-*-* } } +} + +// The following functions aren't yet accepted, but they should be. + +fn copy_after_field_assign_after_uninit() { + let mut x: A; + x.a = 1; // { dg-error ".E0381." "" { target *-*-* } } + drop(x.a); +} + +fn borrow_after_field_assign_after_uninit() { + let mut x: A; + x.a = 1; // { dg-error ".E0381." "" { target *-*-* } } + let p = &x.a; + drop(*p); +} + +fn move_after_field_assign_after_uninit() { + let mut x: A; + x.b = box 1; // { dg-error ".E0381." "" { target *-*-* } } + drop(x.b); +} + +fn main() { + deref_after_move(); + deref_after_fu_move(); + + borrow_after_move(); + borrow_after_fu_move(); + move_after_borrow(); + fu_move_after_borrow(); + mut_borrow_after_mut_borrow(); + + move_after_move(); + move_after_fu_move(); + fu_move_after_move(); + fu_move_after_fu_move(); + + copy_after_field_assign_after_uninit(); + borrow_after_field_assign_after_uninit(); + move_after_field_assign_after_uninit(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-fixed-length-vecs.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-fixed-length-vecs.rs new file mode 100644 index 000000000000..41ecbe56c24f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-fixed-length-vecs.rs @@ -0,0 +1,8 @@ +// run-pass + +pub fn main() { + let x = [22]; + let y = &x[0]; + assert_eq!(*y, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-fn-in-const-a.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-fn-in-const-a.rs new file mode 100644 index 000000000000..e9442ce4db90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-fn-in-const-a.rs @@ -0,0 +1,13 @@ +// Check that we check fns appearing in constant declarations. +// Issue #22382. + +const MOVE: fn(&String) -> String = { + fn broken(x: &String) -> String { + return *x // { dg-error ".E0507." "" { target *-*-* } } + } + broken +}; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-fn-in-const-c.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-fn-in-const-c.rs new file mode 100644 index 000000000000..9ed84b3582d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-fn-in-const-c.rs @@ -0,0 +1,24 @@ +// Check that we check fns appearing in constant declarations. +// Issue #22382. + +// Returning local references? +struct DropString { + inner: String +} +impl Drop for DropString { + fn drop(&mut self) { + self.inner.clear(); + self.inner.push_str("dropped"); + } +} +const LOCAL_REF: fn() -> &'static str = { + fn broken() -> &'static str { + let local = DropString { inner: format!("Some local string") }; + return &local.inner; // { dg-error ".E0713." "" { target *-*-* } } + } + broken +}; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-for-loop-correct-cmt-for-pattern.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-for-loop-correct-cmt-for-pattern.rs new file mode 100644 index 000000000000..597480379930 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-for-loop-correct-cmt-for-pattern.rs @@ -0,0 +1,25 @@ +// Issue #16205. + +#![feature(box_syntax)] + +struct Foo { + a: [Box; 3], +} + +fn main() { + let mut y = 1; + let x = Some(&mut y); + for &a in x.iter() { // { dg-error ".E0507." "" { target *-*-* } } + } + + let f = Foo { + a: [box 3, box 4, box 5], + }; + for &a in &f.a { // { dg-error ".E0507." "" { target *-*-* } } + } + + let x: Option> = Some(box 1); + for &a in x.iter() { // { dg-error ".E0507." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-for-loop-head-linkage.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-for-loop-head-linkage.rs new file mode 100644 index 000000000000..ce831b3c1995 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-for-loop-head-linkage.rs @@ -0,0 +1,11 @@ +use std::iter::repeat; + +fn main() { + let mut vector = vec![1, 2]; + for &x in &vector { + let cap = vector.capacity(); + vector.extend(repeat(0)); // { dg-error ".E0502." "" { target *-*-* } } + vector[1] = 5; // { dg-error ".E0502." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-freeze-frozen-mut.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-freeze-frozen-mut.rs new file mode 100644 index 000000000000..8030d119a27e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-freeze-frozen-mut.rs @@ -0,0 +1,29 @@ +// run-pass +// Test that a `&mut` inside of an `&` is freezable. + + +struct MutSlice<'a, T:'a> { + data: &'a mut [T] +} + +fn get<'a, T>(ms: &'a MutSlice<'a, T>, index: usize) -> &'a T { + &ms.data[index] +} + +pub fn main() { + let mut data = [1, 2, 3]; + { + let slice = MutSlice { data: &mut data }; + slice.data[0] += 4; + let index0 = get(&slice, 0); + let index1 = get(&slice, 1); + let index2 = get(&slice, 2); + assert_eq!(*index0, 5); + assert_eq!(*index1, 2); + assert_eq!(*index2, 3); + } + assert_eq!(data[0], 5); + assert_eq!(data[1], 2); + assert_eq!(data[2], 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-if-no-else.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-if-no-else.rs new file mode 100644 index 000000000000..cd17e1667622 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-if-no-else.rs @@ -0,0 +1,7 @@ +fn foo(x: isize) { println!("{}", x); } + +fn main() { + let x: isize; if 1 > 2 { x = 10; } + foo(x); // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-if-with-else.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-if-with-else.rs new file mode 100644 index 000000000000..a1a848b1dd7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-if-with-else.rs @@ -0,0 +1,12 @@ +fn foo(x: isize) { println!("{}", x); } + +fn main() { + let x: isize; + if 1 > 2 { + println!("whoops"); + } else { + x = 10; + } + foo(x); // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs new file mode 100644 index 000000000000..d6431ef21f6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs @@ -0,0 +1,11 @@ +fn main() { + let mut _a = 3; + let b = &mut _a; + { + let c = &*b; + _a = 4; // { dg-error ".E0506." "" { target *-*-* } } + drop(c); + } + drop(b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-in-static.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-in-static.rs new file mode 100644 index 000000000000..0d4e39621c9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-in-static.rs @@ -0,0 +1,13 @@ +// check that borrowck looks inside consts/statics + +static FN : &'static (dyn Fn() -> (BoxBox>) + Sync) = &|| { + let x = Box::new(0); + Box::new(|| x) // { dg-error ".E0507." "" { target *-*-* } } +}; + +fn main() { + let f = (FN)(); + f(); + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-in-called-fn-expr.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-in-called-fn-expr.rs new file mode 100644 index 000000000000..06943e84297b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-in-called-fn-expr.rs @@ -0,0 +1,8 @@ +fn main() { + let j = || -> isize { + let i: isize; + i // { dg-error ".E0381." "" { target *-*-* } } + }; + j(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-in-fn-expr.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-in-fn-expr.rs new file mode 100644 index 000000000000..17a7e93b72d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-in-fn-expr.rs @@ -0,0 +1,8 @@ +fn main() { + let f = || -> isize { + let i: isize; + i // { dg-error ".E0381." "" { target *-*-* } } + }; + println!("{}", f()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-in-fru.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-in-fru.rs new file mode 100644 index 000000000000..e2ff8a094a6a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-in-fru.rs @@ -0,0 +1,13 @@ +#[derive(Clone)] +struct Point { + x: isize, + y: isize, +} + +fn main() { + let mut origin: Point; + origin = Point { x: 10, ..origin }; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + origin.clone(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-op-equal.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-op-equal.rs new file mode 100644 index 000000000000..d9ca799c7399 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-op-equal.rs @@ -0,0 +1,9 @@ +fn test() { + let v: isize; + v += 1; // { dg-error ".E0381." "" { target *-*-* } } + v.clone(); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-plus-equal.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-plus-equal.rs new file mode 100644 index 000000000000..260f17a362a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-init-plus-equal.rs @@ -0,0 +1,9 @@ +fn test() { + let mut v: isize; + v = v + 1; // { dg-error ".E0381." "" { target *-*-* } } + v.clone(); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-insert-during-each.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-insert-during-each.rs new file mode 100644 index 000000000000..964afdc09eec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-insert-during-each.rs @@ -0,0 +1,27 @@ +use std::collections::HashSet; + +struct Foo { + n: HashSet, +} + +impl Foo { + pub fn foo(&mut self, mut fun: F) where F: FnMut(&isize) { + for f in &self.n { + fun(f); + } + } +} + +fn bar(f: &mut Foo) { + f.foo( +// { dg-error ".E0501." "" { target *-*-* } .-1 } + |a| { // { dg-error ".E0500." "" { target *-*-* } } + f.n.insert(*a); + }) +} + +fn main() { + let mut f = Foo { n: HashSet::new() }; + bar(&mut f); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-14498.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-14498.rs new file mode 100644 index 000000000000..d10b56d57835 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-14498.rs @@ -0,0 +1,111 @@ +// This tests that we can't modify Box<&mut T> contents while they +// are borrowed (#14498). +// +// Also includes tests of the errors reported when the Box in question +// is immutable (#14270). + +#![feature(box_syntax)] + +struct A { a: isize } +struct B<'a> { a: Box<&'a mut isize> } + +fn indirect_write_to_imm_box() { + let mut x: isize = 1; + let y: Box<_> = box &mut x; + let p = &y; + ***p = 2; // { dg-error ".E0594." "" { target *-*-* } } + drop(p); +} + +fn borrow_in_var_from_var() { + let mut x: isize = 1; + let mut y: Box<_> = box &mut x; + let p = &y; + let q = &***p; + **y = 2; // { dg-error ".E0506." "" { target *-*-* } } + drop(p); + drop(q); +} + +fn borrow_in_var_from_var_via_imm_box() { + let mut x: isize = 1; + let y: Box<_> = box &mut x; + let p = &y; + let q = &***p; + **y = 2; // { dg-error ".E0506." "" { target *-*-* } } + drop(p); + drop(q); +} + +fn borrow_in_var_from_field() { + let mut x = A { a: 1 }; + let mut y: Box<_> = box &mut x.a; + let p = &y; + let q = &***p; + **y = 2; // { dg-error ".E0506." "" { target *-*-* } } + drop(p); + drop(q); +} + +fn borrow_in_var_from_field_via_imm_box() { + let mut x = A { a: 1 }; + let y: Box<_> = box &mut x.a; + let p = &y; + let q = &***p; + **y = 2; // { dg-error ".E0506." "" { target *-*-* } } + drop(p); + drop(q); +} + +fn borrow_in_field_from_var() { + let mut x: isize = 1; + let mut y = B { a: box &mut x }; + let p = &y.a; + let q = &***p; + **y.a = 2; // { dg-error ".E0506." "" { target *-*-* } } + drop(p); + drop(q); +} + +fn borrow_in_field_from_var_via_imm_box() { + let mut x: isize = 1; + let y = B { a: box &mut x }; + let p = &y.a; + let q = &***p; + **y.a = 2; // { dg-error ".E0506." "" { target *-*-* } } + drop(p); + drop(q); +} + +fn borrow_in_field_from_field() { + let mut x = A { a: 1 }; + let mut y = B { a: box &mut x.a }; + let p = &y.a; + let q = &***p; + **y.a = 2; // { dg-error ".E0506." "" { target *-*-* } } + drop(p); + drop(q); +} + +fn borrow_in_field_from_field_via_imm_box() { + let mut x = A { a: 1 }; + let y = B { a: box &mut x.a }; + let p = &y.a; + let q = &***p; + **y.a = 2; // { dg-error ".E0506." "" { target *-*-* } } + drop(p); + drop(q); +} + +fn main() { + indirect_write_to_imm_box(); + borrow_in_var_from_var(); + borrow_in_var_from_var_via_imm_box(); + borrow_in_var_from_field(); + borrow_in_var_from_field_via_imm_box(); + borrow_in_field_from_var(); + borrow_in_field_from_var_via_imm_box(); + borrow_in_field_from_field(); + borrow_in_field_from_field_via_imm_box(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-2657-1.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-2657-1.rs new file mode 100644 index 000000000000..66de7938f715 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-2657-1.rs @@ -0,0 +1,18 @@ +#![feature(box_syntax)] + + + +fn main() { + let x: Option> = Some(box 1); + match x { + Some(ref _y) => { + let _a = x; // { dg-error ".E0505." "" { target *-*-* } } + _y.use_ref(); + } + _ => {} + } +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-2657-2.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-2657-2.rs new file mode 100644 index 000000000000..763d4f6bb844 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-2657-2.rs @@ -0,0 +1,12 @@ +#![feature(box_syntax)] + +fn main() { + let x: Option> = Some(box 1); + match x { + Some(ref y) => { + let _b = *y; // { dg-error ".E0507." "" { target *-*-* } } + } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-48962.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-48962.rs new file mode 100644 index 000000000000..9dde1aa8b376 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-issue-48962.rs @@ -0,0 +1,27 @@ +struct Node { + elem: i32, + next: Option>, +} + +fn a() { + let mut node = Node { + elem: 5, + next: None, + }; + + let mut src = &mut node; + {src}; + src.next = None; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn b() { + let mut src = &mut (22, 44); + {src}; + src.0 = 66; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() { + a(); + b(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-args.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-args.rs new file mode 100644 index 000000000000..91cd324e67cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-args.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(dead_code)] + +// pretty-expanded FIXME #23616 + +fn borrow(_v: &isize) {} + +fn borrow_from_arg_imm_ref(v: Box) { + borrow(&*v); +} + +fn borrow_from_arg_mut_ref(v: &mut Box) { + borrow(&**v); +} + +fn borrow_from_arg_copy(v: Box) { + borrow(&*v); +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow-if.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow-if.rs new file mode 100644 index 000000000000..596dd8079584 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow-if.rs @@ -0,0 +1,52 @@ +// Note: the borrowck analysis is currently flow-insensitive. +// Therefore, some of these errors are marked as spurious and could be +// corrected by a simple change to the analysis. The others are +// either genuine or would require more advanced changes. The latter +// cases are noted. + +#![feature(box_syntax)] + +fn borrow(_v: &isize) {} +fn borrow_mut(_v: &mut isize) {} +fn cond() -> bool { panic!() } +fn for_func(_f: F) where F: FnOnce() -> bool { panic!() } +fn produce() -> T { panic!(); } + +fn inc(v: &mut Box) { + *v = box (**v + 1); +} + +fn pre_freeze_cond() { + // In this instance, the freeze is conditional and starts before + // the mut borrow. + + let u = box 0; + let mut v: Box<_> = box 3; + let mut _w = &u; + if cond() { + _w = &v; + } + borrow_mut(&mut *v); // { dg-error ".E0502." "" { target *-*-* } } + _w.use_ref(); +} + +fn pre_freeze_else() { + // In this instance, the freeze and mut borrow are on separate sides + // of the if. + + let u = box 0; + let mut v: Box<_> = box 3; + let mut _w = &u; + if cond() { + _w = &v; + } else { + borrow_mut(&mut *v); + } + _w.use_ref(); +} + +fn main() {} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow-loop.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow-loop.rs new file mode 100644 index 000000000000..893cb9f31b7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow-loop.rs @@ -0,0 +1,133 @@ +#![feature(box_syntax)] + +fn borrow(_v: &isize) {} +fn borrow_mut(_v: &mut isize) {} +fn cond() -> bool { panic!() } +fn produce() -> T { panic!(); } + +fn inc(v: &mut Box) { + *v = box (**v + 1); +} + +fn loop_overarching_alias_mut() { + // In this instance, the borrow ends on the line before the loop + + let mut v: Box<_> = box 3; + let mut x = &mut v; + **x += 1; + loop { + borrow(&*v); // OK + } +} + +fn block_overarching_alias_mut() { + // In this instance, the borrow encompasses the entire closure call. + + let mut v: Box<_> = box 3; + let mut x = &mut v; + for _ in 0..3 { + borrow(&*v); // { dg-error ".E0502." "" { target *-*-* } } + } + *x = box 5; +} +fn loop_aliased_mut() { + // In this instance, the borrow ends right after each assignment to _x + + let mut v: Box<_> = box 3; + let mut w: Box<_> = box 4; + let mut _x = &w; + loop { + borrow_mut(&mut *v); // OK + _x = &v; + } +} + +fn while_aliased_mut() { + // In this instance, the borrow ends right after each assignment to _x + + let mut v: Box<_> = box 3; + let mut w: Box<_> = box 4; + let mut _x = &w; + while cond() { + borrow_mut(&mut *v); // OK + _x = &v; + } +} + + +fn loop_aliased_mut_break() { + // In this instance, the borrow ends right after each assignment to _x + + let mut v: Box<_> = box 3; + let mut w: Box<_> = box 4; + let mut _x = &w; + loop { + borrow_mut(&mut *v); + _x = &v; + break; + } + borrow_mut(&mut *v); // OK +} + +fn while_aliased_mut_break() { + // In this instance, the borrow ends right after each assignment to _x + + let mut v: Box<_> = box 3; + let mut w: Box<_> = box 4; + let mut _x = &w; + while cond() { + borrow_mut(&mut *v); + _x = &v; + break; + } + borrow_mut(&mut *v); // OK +} + +fn while_aliased_mut_cond(cond: bool, cond2: bool) { + let mut v: Box<_> = box 3; + let mut w: Box<_> = box 4; + let mut x = &mut w; + while cond { + **x += 1; + borrow(&*v); // { dg-error ".E0502." "" { target *-*-* } } + if cond2 { + x = &mut v; // OK + } + } +} +fn loop_break_pops_scopes<'r, F>(_v: &'r mut [usize], mut f: F) where + F: FnMut(&'r mut usize) -> bool, +{ + // Here we check that when you break out of an inner loop, the + // borrows that go out of scope as you exit the inner loop are + // removed from the bitset. + + while cond() { + while cond() { + // this borrow is limited to the scope of `r`... + let r: &'r mut usize = produce(); + if !f(&mut *r) { + break; // ...so it is not live as exit the `while` loop here + } + } + } +} + +fn loop_loop_pops_scopes<'r, F>(_v: &'r mut [usize], mut f: F) + where F: FnMut(&'r mut usize) -> bool +{ + // Similar to `loop_break_pops_scopes` but for the `loop` keyword + + while cond() { + while cond() { + // this borrow is limited to the scope of `r`... + let r: &'r mut usize = produce(); + if !f(&mut *r) { + continue; // ...so it is not live as exit (and re-enter) the `while` loop here + } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow-match.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow-match.rs new file mode 100644 index 000000000000..1f32bc2f35b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow-match.rs @@ -0,0 +1,19 @@ +fn separate_arms() { + // Here both arms perform assignments, but only one is illegal. + + let mut x = None; + match x { + None => { + // It is ok to reassign x here, because there is in + // fact no outstanding loan of x! + x = Some(0); + } + Some(ref r) => { + x = Some(1); // { dg-error ".E0506." "" { target *-*-* } } + drop(r); + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow.rs new file mode 100644 index 000000000000..3a6972a0c8d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-lend-flow.rs @@ -0,0 +1,40 @@ +// Note: the borrowck analysis is currently flow-insensitive. +// Therefore, some of these errors are marked as spurious and could be +// corrected by a simple change to the analysis. The others are +// either genuine or would require more advanced changes. The latter +// cases are noted. + +#![feature(box_syntax)] + +fn borrow(_v: &isize) {} +fn borrow_mut(_v: &mut isize) {} +fn cond() -> bool { panic!() } +fn for_func(_f: F) where F: FnOnce() -> bool { panic!() } +fn produce() -> T { panic!(); } + +fn inc(v: &mut Box) { + *v = box (**v + 1); +} + +fn pre_freeze() { + // In this instance, the freeze starts before the mut borrow. + + let mut v: Box<_> = box 3; + let _w = &v; + borrow_mut(&mut *v); // { dg-error ".E0502." "" { target *-*-* } } + _w.use_ref(); +} + +fn post_freeze() { + // In this instance, the const alias starts after the borrow. + + let mut v: Box<_> = box 3; + borrow_mut(&mut *v); + let _w = &v; +} + +fn main() {} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-blocks-move-cc.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-blocks-move-cc.rs new file mode 100644 index 000000000000..3d019ce8bd65 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-blocks-move-cc.rs @@ -0,0 +1,36 @@ +#![feature(box_syntax)] + +use std::thread; + + + +fn borrow(v: &isize, f: F) where F: FnOnce(&isize) { + f(v); +} + +fn box_imm() { + let v: Box<_> = box 3; + let w = &v; + thread::spawn(move|| { +// { dg-error ".E0505." "" { target *-*-* } .-1 } + println!("v={}", *v); + }); + w.use_ref(); +} + +fn box_imm_explicit() { + let v: Box<_> = box 3; + let w = &v; + thread::spawn(move|| { +// { dg-error ".E0505." "" { target *-*-* } .-1 } + println!("v={}", *v); + }); + w.use_ref(); +} + +fn main() { +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-blocks-move.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-blocks-move.rs new file mode 100644 index 000000000000..3b82313ec459 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-blocks-move.rs @@ -0,0 +1,20 @@ +#![feature(box_syntax)] + + + +fn take(_v: Box) { +} + +fn box_imm() { + let v = box 3; + let w = &v; + take(v); // { dg-error ".E0505." "" { target *-*-* } } + w.use_ref(); +} + +fn main() { +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-blocks-mut-uniq.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-blocks-mut-uniq.rs new file mode 100644 index 000000000000..43cbc0d9e7cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-blocks-mut-uniq.rs @@ -0,0 +1,19 @@ +#![feature(box_syntax)] + +fn borrow(v: &isize, f: F) where F: FnOnce(&isize) { + f(v); +} + +fn box_imm() { + let mut v: Box<_> = box 3; + borrow(&*v, + |w| { // { dg-error ".E0502." "" { target *-*-* } } + v = box 4; + assert_eq!(*v, 3); + assert_eq!(*w, 4); + }) +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-in-overloaded-op.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-in-overloaded-op.rs new file mode 100644 index 000000000000..5828a0d755d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-in-overloaded-op.rs @@ -0,0 +1,24 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] + +use std::ops::Add; + +#[derive(Clone)] +struct Foo(Box); + +impl Add for Foo { + type Output = Foo; + + fn add(self, f: Foo) -> Foo { + let Foo(box i) = self; + let Foo(box j) = f; + Foo(box (i + j)) + } +} + +fn main() { + let x = Foo(box 3); + let _y = {x} + x.clone(); // the `{x}` forces a move to occur +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-of-static-data-issue-27616.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-of-static-data-issue-27616.rs new file mode 100644 index 000000000000..f52df311e1b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-of-static-data-issue-27616.rs @@ -0,0 +1,25 @@ +use std::mem; + +fn leak(mut b: Box) -> &'static mut T { + // isn't this supposed to be safe? + let inner = &mut *b as *mut _; + mem::forget(b); + unsafe { &mut *inner } +} + +fn evil(mut s: &'static mut String) +{ + // create alias + let alias: &'static mut String = s; + let inner: &str = &alias; + // free value + *s = String::new(); // { dg-error ".E0506." "" { target *-*-* } } + let _spray = "0wned".to_owned(); + // ... and then use it + println!("{}", inner); +} + +fn main() { + evil(leak(Box::new("hello".to_owned()))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-rcvr-overloaded-op.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-rcvr-overloaded-op.rs new file mode 100644 index 000000000000..9dd3dc096a95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-rcvr-overloaded-op.rs @@ -0,0 +1,47 @@ +use std::ops::Add; + +#[derive(Copy, Clone)] +struct Point { + x: isize, + y: isize, +} + +impl Add for Point { + type Output = isize; + + fn add(self, z: isize) -> isize { + self.x + self.y + z + } +} + +impl Point { + pub fn times(&self, z: isize) -> isize { + self.x * self.y * z + } +} + +fn a() { + let mut p = Point {x: 3, y: 4}; + + // ok (we can loan out rcvr) + p + 3; + p.times(3); +} + +fn b() { + let mut p = Point {x: 3, y: 4}; + + // Here I create an outstanding loan and check that we get conflicts: + + let q = &mut p; + + p + 3; // { dg-error ".E0503." "" { target *-*-* } } + p.times(3); // { dg-error ".E0502." "" { target *-*-* } } + + *q + 3; // OK to use the new alias `q` + q.x += 1; // and OK to mutate it +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-rcvr.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-rcvr.rs new file mode 100644 index 000000000000..e424df7b894d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-rcvr.rs @@ -0,0 +1,41 @@ +struct Point { x: isize, y: isize } + +trait Methods { + fn impurem(&self); + fn blockm(&self, f: F) where F: FnOnce(); +} + +impl Methods for Point { + fn impurem(&self) { + } + + fn blockm(&self, f: F) where F: FnOnce() { f() } +} + +fn a() { + let mut p = Point {x: 3, y: 4}; + + // Here: it's ok to call even though receiver is mutable, because we + // can loan it out. + p.impurem(); + + // But in this case we do not honor the loan: + p.blockm(|| { // { dg-error ".E0502." "" { target *-*-* } } + p.x = 10; + }) +} + +fn b() { + let mut p = Point {x: 3, y: 4}; + + // Here I create an outstanding loan and check that we get conflicts: + + let l = &mut p; + p.impurem(); // { dg-error ".E0502." "" { target *-*-* } } + + l.x += 1; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-vec-content.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-vec-content.rs new file mode 100644 index 000000000000..90d11c6a46e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-loan-vec-content.rs @@ -0,0 +1,25 @@ +// Here we check that it is allowed to lend out an element of a +// (locally rooted) mutable, unique vector, and that we then prevent +// modifications to the contents. + +fn takes_imm_elt(_v: &isize, f: F) where F: FnOnce() { + f(); +} + +fn has_mut_vec_and_does_not_try_to_change_it() { + let mut v: Vec = vec![1, 2, 3]; + takes_imm_elt(&v[0], || {}) +} + +fn has_mut_vec_but_tries_to_change_it() { + let mut v: Vec = vec![1, 2, 3]; + takes_imm_elt( + &v[0], + || { // { dg-error ".E0502." "" { target *-*-* } } + v[1] = 4; + }) +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-local-borrow-outlives-fn.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-local-borrow-outlives-fn.rs new file mode 100644 index 000000000000..eac546a7927e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-local-borrow-outlives-fn.rs @@ -0,0 +1,7 @@ +fn cplusplus_mode(x: isize) -> &'static isize { + &x +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-local-borrow-with-panic-outlives-fn.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-local-borrow-with-panic-outlives-fn.rs new file mode 100644 index 000000000000..f1f2d8f29afe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-local-borrow-with-panic-outlives-fn.rs @@ -0,0 +1,11 @@ +fn cplusplus_mode_exceptionally_unsafe(x: &mut Option<&'static mut isize>) { + let mut z = (0, 0); + *x = Some(&mut z.1); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + panic!("catch me for a dangling pointer!") +} + +fn main() { + cplusplus_mode_exceptionally_unsafe(&mut None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-local-borrow.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-local-borrow.rs new file mode 100644 index 000000000000..d1d539192b1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-local-borrow.rs @@ -0,0 +1,13 @@ +// run-fail +// error-pattern:panic 1 +// ignore-emscripten no processes + +// revisions: migrate mir +//[mir]compile-flags: -Z borrowck=mir + +fn main() { + let x = 2; + let y = &x; + panic!("panic 1"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-macro-interaction-issue-6304.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-macro-interaction-issue-6304.rs new file mode 100644 index 000000000000..4e668b3c4604 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-macro-interaction-issue-6304.rs @@ -0,0 +1,39 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unconditional_recursion)] + +// Check that we do not ICE when compiling this +// macro, which reuses the expression `$id` + + +#![feature(box_patterns)] +#![feature(box_syntax)] + +struct Foo { + a: isize +} + +pub enum Bar { + Bar1, Bar2(isize, Box), +} + +impl Foo { + fn elaborate_stm(&mut self, s: Box) -> Box { + macro_rules! declare { + ($id:expr, $rest:expr) => ({ + self.check_id($id); + box Bar::Bar2($id, $rest) + }) + } + match s { + box Bar::Bar2(id, rest) => declare!(id, self.elaborate_stm(rest)), + _ => panic!() + } + } + + fn check_id(&mut self, s: isize) { panic!() } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-match-already-borrowed.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-match-already-borrowed.rs new file mode 100644 index 000000000000..70b14e16dcdd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-match-already-borrowed.rs @@ -0,0 +1,27 @@ +enum Foo { + A(i32), + B +} + +fn match_enum() { + let mut foo = Foo::B; + let p = &mut foo; + let _ = match foo { + Foo::B => 1, // { dg-error ".E0503." "" { target *-*-* } } + _ => 2, + Foo::A(x) => x // { dg-error ".E0503." "" { target *-*-* } } + }; + drop(p); +} + + +fn main() { + let mut x = 1; + let r = &mut x; + let _ = match x { + x => x + 1, // { dg-error ".E0503." "" { target *-*-* } } + y => y + 2, // { dg-error ".E0503." "" { target *-*-* } } + }; + drop(r); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-match-binding-is-assignment.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-match-binding-is-assignment.rs new file mode 100644 index 000000000000..898525e71276 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-match-binding-is-assignment.rs @@ -0,0 +1,42 @@ +// Test that immutable pattern bindings cannot be reassigned. + +enum E { + Foo(isize) +} + +struct S { + bar: isize, +} + +pub fn main() { + match 1 { + x => { + x += 1; // { dg-error ".E0384." "" { target *-*-* } } + } + } + + match E::Foo(1) { + E::Foo(x) => { + x += 1; // { dg-error ".E0384." "" { target *-*-* } } + } + } + + match (S { bar: 1 }) { + S { bar: x } => { + x += 1; // { dg-error ".E0384." "" { target *-*-* } } + } + } + + match (1,) { + (x,) => { + x += 1; // { dg-error ".E0384." "" { target *-*-* } } + } + } + + match [1,2,3] { + [x,_,_] => { + x += 1; // { dg-error ".E0384." "" { target *-*-* } } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-by-capture-ok.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-by-capture-ok.rs new file mode 100644 index 000000000000..c173ff7aa7a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-by-capture-ok.rs @@ -0,0 +1,9 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let bar: Box<_> = box 3; + let h = || -> isize { *bar }; + assert_eq!(h(), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-by-capture.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-by-capture.rs new file mode 100644 index 000000000000..e9c23564b8a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-by-capture.rs @@ -0,0 +1,12 @@ +#![feature(box_syntax,unboxed_closures)] + +fn to_fn_mut>(f: F) -> F { f } +fn to_fn_once>(f: F) -> F { f } + +pub fn main() { + let bar: Box<_> = box 3; + let _g = to_fn_mut(|| { + let _h = to_fn_once(move || -> isize { *bar }); // { dg-error ".E0507." "" { target *-*-* } } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-error-with-note.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-error-with-note.rs new file mode 100644 index 000000000000..98c7d312c72f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-error-with-note.rs @@ -0,0 +1,55 @@ +#![feature(box_syntax)] + +enum Foo { + Foo1(Box, Box), + Foo2(Box), + Foo3, +} + +fn blah() { + let f = &Foo::Foo1(box 1, box 2); + match *f { // { dg-error ".E0507." "" { target *-*-* } } + Foo::Foo1(num1, + num2) => (), + Foo::Foo2(num) => (), + Foo::Foo3 => () + } +} + +struct S { + f: String, + g: String +} +impl Drop for S { + fn drop(&mut self) { println!("{}", self.f); } +} + +fn move_in_match() { + match (S {f: "foo".to_string(), g: "bar".to_string()}) { +// { dg-error ".E0509." "" { target *-*-* } .-1 } + S { + f: _s, + g: _t + } => {} + } +} + +// from issue-8064 +struct A { + a: Box, +} + +fn free(_: T) {} + +fn blah2() { + let a = &A { a: box 1 }; + match a.a { // { dg-error ".E0507." "" { target *-*-* } } + n => { + free(n) + } + } + free(a) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.rs new file mode 100644 index 000000000000..bbf43d5b751e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.rs @@ -0,0 +1,18 @@ +// verify that an error is raised when trying to move out of a +// borrowed path. + + + +#![feature(box_syntax)] + +fn main() { + let a: Box> = box box 2; + let b = &a; + + let z = *a; // { dg-error ".E0505." "" { target *-*-* } } + b.use_ref(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-from-unsafe-ptr.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-from-unsafe-ptr.rs new file mode 100644 index 000000000000..5250792473c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-from-unsafe-ptr.rs @@ -0,0 +1,8 @@ +unsafe fn foo(x: *const Box) -> Box { + let y = *x; // { dg-error ".E0507." "" { target *-*-* } } + return y; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-in-irrefut-pat.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-in-irrefut-pat.rs new file mode 100644 index 000000000000..748cda4f5311 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-in-irrefut-pat.rs @@ -0,0 +1,17 @@ +fn with(f: F) where F: FnOnce(&String) {} + +fn arg_item(&_x: &String) {} +// { dg-error ".E0507." "" { target *-*-* } .-1 } + +fn arg_closure() { + with(|&_x| ()) +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + +fn let_pat() { + let &_x = &"hi".to_string(); +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-moved-value-into-closure.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-moved-value-into-closure.rs new file mode 100644 index 000000000000..2c5714bdaa8b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-moved-value-into-closure.rs @@ -0,0 +1,13 @@ +#![feature(box_syntax)] + +fn call_f isize>(f: F) -> isize { + f() +} + +fn main() { + let t: Box<_> = box 3; + + call_f(move|| { *t + 1 }); + call_f(move|| { *t + 1 }); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-mut-base-ptr.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-mut-base-ptr.rs new file mode 100644 index 000000000000..8f014ffcc35a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-mut-base-ptr.rs @@ -0,0 +1,20 @@ +// Test that attempt to move `&mut` pointer while pointee is borrowed +// yields an error. +// +// Example from compiler/rustc_borrowck/borrowck/README.md + + + +fn foo(t0: &mut isize) { + let p: &isize = &*t0; // Freezes `*t0` + let t1 = t0; // { dg-error ".E0505." "" { target *-*-* } } + *t1 = 22; + p.use_ref(); +} + +fn main() { +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-match.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-match.rs new file mode 100644 index 000000000000..8c59762c66b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-match.rs @@ -0,0 +1,117 @@ +fn array() -> [(String, String); 3] { + Default::default() +} + +// Const Index + Const Index + +fn move_out_from_begin_and_end() { + let a = array(); + match a { + [_, _, _x] => {} + } + match a { + [.., _y] => {} // { dg-error ".E0382." "" { target *-*-* } } + } +} + +fn move_out_from_begin_field_and_end() { + let a = array(); + match a { + [_, _, (_x, _)] => {} + } + match a { + [.., _y] => {} // { dg-error ".E0382." "" { target *-*-* } } + } +} + +fn move_out_from_begin_field_and_end_field() { + let a = array(); + match a { + [_, _, (_x, _)] => {} + } + match a { + [.., (_y, _)] => {} // { dg-error ".E0382." "" { target *-*-* } } + } +} + +// Const Index + Slice + +fn move_out_by_const_index_and_subslice() { + let a = array(); + match a { + [_x, _, _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_y @ .., _, _] => {} + } +} + +fn move_out_by_const_index_end_and_subslice() { + let a = array(); + match a { + [.., _x] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_, _, _y @ ..] => {} + } +} + +fn move_out_by_const_index_field_and_subslice() { + let a = array(); + match a { + [(_x, _), _, _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_y @ .., _, _] => {} + } +} + +fn move_out_by_const_index_end_field_and_subslice() { + let a = array(); + match a { + [.., (_x, _)] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_, _, _y @ ..] => {} + } +} + +fn move_out_by_subslice_and_const_index_field() { + let a = array(); + match a { + [_y @ .., _, _] => {} + } + match a { + [(_x, _), _, _] => {} // { dg-error ".E0382." "" { target *-*-* } } + } +} + +fn move_out_by_subslice_and_const_index_end_field() { + let a = array(); + match a { + [_, _, _y @ ..] => {} + } + match a { + [.., (_x, _)] => {} // { dg-error ".E0382." "" { target *-*-* } } + } +} + +// Slice + Slice + +fn move_out_by_subslice_and_subslice() { + let a = array(); + match a { + [x @ .., _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_, _y @ ..] => {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs new file mode 100644 index 000000000000..13f14582c79c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs @@ -0,0 +1,116 @@ +// Due to #53114, which causes a "read" of the `_` patterns, +// the borrow-checker refuses this code, while it should probably be allowed. +// Once the bug is fixed, the test, which is derived from a +// passing test for `let` statements, should become check-pass. + +fn array() -> [(String, String); 3] { + Default::default() +} + +// Const Index + Const Index + +fn move_out_from_begin_and_one_from_end() { + let a = array(); + match a { + [_, _, _x] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [.., _y, _] => {} + } +} + +fn move_out_from_begin_field_and_end_field() { + let a = array(); + match a { + [_, _, (_x, _)] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [.., (_, _y)] => {} + } +} + +// Const Index + Slice + +fn move_out_by_const_index_and_subslice() { + let a = array(); + match a { + [_x, _, _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_, _y @ ..] => {} + } +} + +fn move_out_by_const_index_end_and_subslice() { + let a = array(); + match a { + [.., _x] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_y @ .., _] => {} + } +} + +fn move_out_by_const_index_field_and_subslice() { + let a = array(); + match a { + [(_x, _), _, _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_, _y @ ..] => {} + } +} + +fn move_out_by_const_index_end_field_and_subslice() { + let a = array(); + match a { + [.., (_x, _)] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_y @ .., _] => {} + } +} + +fn move_out_by_const_subslice_and_index_field() { + let a = array(); + match a { + [_, _y @ ..] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [(_x, _), _, _] => {} + } +} + +fn move_out_by_const_subslice_and_end_index_field() { + let a = array(); + match a { + [_y @ .., _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [.., (_x, _)] => {} + } +} + +// Slice + Slice + +fn move_out_by_subslice_and_subslice() { + let a = array(); + match a { + [x @ .., _, _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_, _y @ ..] => {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs new file mode 100644 index 000000000000..4509a09cf18b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs @@ -0,0 +1,68 @@ +// check-pass + +fn array() -> [(String, String); 3] { + Default::default() +} + +// Const Index + Const Index + +fn move_out_from_begin_and_one_from_end() { + let a = array(); + let [_, _, _x] = a; + let [.., _y, _] = a; +} + +fn move_out_from_begin_field_and_end_field() { + let a = array(); + let [_, _, (_x, _)] = a; + let [.., (_, _y)] = a; +} + +// Const Index + Slice + +fn move_out_by_const_index_and_subslice() { + let a = array(); + let [_x, _, _] = a; + let [_, _y @ ..] = a; +} + +fn move_out_by_const_index_end_and_subslice() { + let a = array(); + let [.., _x] = a; + let [_y @ .., _] = a; +} + +fn move_out_by_const_index_field_and_subslice() { + let a = array(); + let [(_x, _), _, _] = a; + let [_, _y @ ..] = a; +} + +fn move_out_by_const_index_end_field_and_subslice() { + let a = array(); + let [.., (_x, _)] = a; + let [_y @ .., _] = a; +} + +fn move_out_by_const_subslice_and_index_field() { + let a = array(); + let [_, _y @ ..] = a; + let [(_x, _), _, _] = a; +} + +fn move_out_by_const_subslice_and_end_index_field() { + let a = array(); + let [_y @ .., _] = a; + let [.., (_x, _)] = a; +} + +// Slice + Slice + +fn move_out_by_subslice_and_subslice() { + let a = array(); + let [x @ .., _, _] = a; + let [_, _y @ ..] = a; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-match.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-match.rs new file mode 100644 index 000000000000..f89f49a7fd8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-match.rs @@ -0,0 +1,151 @@ +fn array() -> [(String, String); 3] { + Default::default() +} + +// Const Index + Const Index + +fn move_out_from_begin_and_end() { + let a = array(); + match a { + [_, _, _x] => {} + } + match a { + [.., ref _y] => {} // { dg-error ".E0382." "" { target *-*-* } } + } +} + +fn move_out_from_begin_field_and_end() { + let a = array(); + match a { + [_, _, (_x, _)] => {} + } + match a { + [.., ref _y] => {} // { dg-error ".E0382." "" { target *-*-* } } + } +} + +fn move_out_from_begin_field_and_end_field() { + let a = array(); + match a { + [_, _, (_x, _)] => {} + } + match a { + [.., (ref _y, _)] => {} // { dg-error ".E0382." "" { target *-*-* } } + } +} + +// Const Index + Slice + +fn move_out_by_const_index_and_subslice() { + let a = array(); + match a { + [_x, _, _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [ref _y @ .., _, _] => {} + } +} + +fn move_out_by_const_index_end_and_subslice() { + let a = array(); + match a { + [.., _x] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_, _, ref _y @ ..] => {} + } +} + +fn move_out_by_const_index_field_and_subslice() { + let a = array(); + match a { + [(_x, _), _, _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [ref _y @ .., _, _] => {} + } +} + +fn move_out_by_const_index_end_field_and_subslice() { + let a = array(); + match a { + [.., (_x, _)] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_, _, ref _y @ ..] => {} + } +} + +fn move_out_by_subslice_and_const_index_field() { + let a = array(); + match a { + [_y @ .., _, _] => {} + } + match a { + [(ref _x, _), _, _] => {} // { dg-error ".E0382." "" { target *-*-* } } + } +} + +fn move_out_by_subslice_and_const_index_end_field() { + let a = array(); + match a { + [_, _, _y @ ..] => {} + } + match a { + [.., (ref _x, _)] => {} // { dg-error ".E0382." "" { target *-*-* } } + } +} + +// Slice + Slice + +fn move_out_by_subslice_and_subslice() { + let a = array(); + match a { + [x @ .., _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_, ref _y @ ..] => {} + } +} + +// Move + Assign + +fn move_out_and_assign_end() { + let mut a = array(); + match a { + [_, _, _x] => {} + } + a[2] = Default::default(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_and_assign_end_field() { + let mut a = array(); + match a { + [_, _, (_x, _)] => {} + } + a[2].1 = Default::default(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_slice_and_assign_end() { + let mut a = array(); + match a { + [_, _, _x @ ..] => {} + } + a[0] = Default::default(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_slice_and_assign_end_field() { + let mut a = array(); + match a { + [_, _, _x @ ..] => {} + } + a[0].1 = Default::default(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs new file mode 100644 index 000000000000..1db08996ea89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs @@ -0,0 +1,116 @@ +// Due to #53114, which causes a "read" of the `_` patterns, +// the borrow-checker refuses this code, while it should probably be allowed. +// Once the bug is fixed, the test, which is derived from a +// passing test for `let` statements, should become check-pass. + +fn array() -> [(String, String); 3] { + Default::default() +} + +// Const Index + Const Index + +fn move_out_from_begin_and_one_from_end() { + let a = array(); + match a { + [_, _, _x] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [.., ref _y, _] => {} + } +} + +fn move_out_from_begin_field_and_end_field() { + let a = array(); + match a { + [_, _, (_x, _)] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [.., (_, ref _y)] => {} + } +} + +// Const Index + Slice + +fn move_out_by_const_index_and_subslice() { + let a = array(); + match a { + [_x, _, _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_, ref _y @ ..] => {} + } +} + +fn move_out_by_const_index_end_and_subslice() { + let a = array(); + match a { + [.., _x] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [ref _y @ .., _] => {} + } +} + +fn move_out_by_const_index_field_and_subslice() { + let a = array(); + match a { + [(_x, _), _, _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_, ref _y @ ..] => {} + } +} + +fn move_out_by_const_index_end_field_and_subslice() { + let a = array(); + match a { + [.., (_x, _)] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [ref _y @ .., _] => {} + } +} + +fn move_out_by_const_subslice_and_index_field() { + let a = array(); + match a { + [_, _y @ ..] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [(ref _x, _), _, _] => {} + } +} + +fn move_out_by_const_subslice_and_end_index_field() { + let a = array(); + match a { + [_y @ .., _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [.., (ref _x, _)] => {} + } +} + +// Slice + Slice + +fn move_out_by_subslice_and_subslice() { + let a = array(); + match a { + [x @ .., _, _] => {} + } + match a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + [_, ref _y @ ..] => {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs new file mode 100644 index 000000000000..f2542c258c2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs @@ -0,0 +1,68 @@ +// check-pass + +fn array() -> [(String, String); 3] { + Default::default() +} + +// Const Index + Const Index + +fn move_out_from_begin_and_one_from_end() { + let a = array(); + let [_, _, _x] = a; + let [.., ref _y, _] = a; +} + +fn move_out_from_begin_field_and_end_field() { + let a = array(); + let [_, _, (_x, _)] = a; + let [.., (_, ref _y)] = a; +} + +// Const Index + Slice + +fn move_out_by_const_index_and_subslice() { + let a = array(); + let [_x, _, _] = a; + let [_, ref _y @ ..] = a; +} + +fn move_out_by_const_index_end_and_subslice() { + let a = array(); + let [.., _x] = a; + let [ref _y @ .., _] = a; +} + +fn move_out_by_const_index_field_and_subslice() { + let a = array(); + let [(_x, _), _, _] = a; + let [_, ref _y @ ..] = a; +} + +fn move_out_by_const_index_end_field_and_subslice() { + let a = array(); + let [.., (_x, _)] = a; + let [ref _y @ .., _] = a; +} + +fn move_out_by_const_subslice_and_index_field() { + let a = array(); + let [_, _y @ ..] = a; + let [(ref _x, _), _, _] = a; +} + +fn move_out_by_const_subslice_and_end_index_field() { + let a = array(); + let [_y @ .., _] = a; + let [.., (ref _x, _)] = a; +} + +// Slice + Slice + +fn move_out_by_subslice_and_subslice() { + let a = array(); + let [x @ .., _, _] = a; + let [_, ref _y @ ..] = a; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use.rs new file mode 100644 index 000000000000..5808cfc53d12 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array-use.rs @@ -0,0 +1,98 @@ +fn array() -> [(String, String); 3] { + Default::default() +} + +// Const Index + Const Index + +fn move_out_from_begin_and_end() { + let a = array(); + let [_, _, _x] = a; + let [.., ref _y] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_from_begin_field_and_end() { + let a = array(); + let [_, _, (_x, _)] = a; + let [.., ref _y] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_from_begin_field_and_end_field() { + let a = array(); + let [_, _, (_x, _)] = a; + let [.., (ref _y, _)] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +// Const Index + Slice + +fn move_out_by_const_index_and_subslice() { + let a = array(); + let [_x, _, _] = a; + let [ref _y @ .., _, _] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_by_const_index_end_and_subslice() { + let a = array(); + let [.., _x] = a; + let [_, _, ref _y @ ..] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_by_const_index_field_and_subslice() { + let a = array(); + let [(_x, _), _, _] = a; + let [ref _y @ .., _, _] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_by_const_index_end_field_and_subslice() { + let a = array(); + let [.., (_x, _)] = a; + let [_, _, ref _y @ ..] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_by_subslice_and_const_index_field() { + let a = array(); + let [_y @ .., _, _] = a; + let [(ref _x, _), _, _] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_by_subslice_and_const_index_end_field() { + let a = array(); + let [_, _, _y @ ..] = a; + let [.., (ref _x, _)] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +// Slice + Slice + +fn move_out_by_subslice_and_subslice() { + let a = array(); + let [x @ .., _] = a; + let [_, ref _y @ ..] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +// Move + Assign + +fn move_out_and_assign_end() { + let mut a = array(); + let [_, _, _x] = a; + a[2] = Default::default(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_and_assign_end_field() { + let mut a = array(); + let [_, _, (_x, _)] = a; + a[2].1 = Default::default(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_slice_and_assign_end() { + let mut a = array(); + let [_, _, _x @ ..] = a; + a[0] = Default::default(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_slice_and_assign_end_field() { + let mut a = array(); + let [_, _, _x @ ..] = a; + a[0].1 = Default::default(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array.rs new file mode 100644 index 000000000000..a997d1060c76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-from-array.rs @@ -0,0 +1,72 @@ +fn array() -> [(String, String); 3] { + Default::default() +} + +// Const Index + Const Index + +fn move_out_from_begin_and_end() { + let a = array(); + let [_, _, _x] = a; + let [.., _y] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_from_begin_field_and_end() { + let a = array(); + let [_, _, (_x, _)] = a; + let [.., _y] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_from_begin_field_and_end_field() { + let a = array(); + let [_, _, (_x, _)] = a; + let [.., (_y, _)] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +// Const Index + Slice + +fn move_out_by_const_index_and_subslice() { + let a = array(); + let [_x, _, _] = a; + let [_y @ .., _, _] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_by_const_index_end_and_subslice() { + let a = array(); + let [.., _x] = a; + let [_, _, _y @ ..] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_by_const_index_field_and_subslice() { + let a = array(); + let [(_x, _), _, _] = a; + let [_y @ .., _, _] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_by_const_index_end_field_and_subslice() { + let a = array(); + let [.., (_x, _)] = a; + let [_, _, _y @ ..] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_by_subslice_and_const_index_field() { + let a = array(); + let [_y @ .., _, _] = a; + let [(_x, _), _, _] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_out_by_subslice_and_const_index_end_field() { + let a = array(); + let [_, _, _y @ ..] = a; + let [.., (_x, _)] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +// Slice + Slice + +fn move_out_by_subslice_and_subslice() { + let a = array(); + let [x @ .., _] = a; + let [_, _y @ ..] = a; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.rs new file mode 100644 index 000000000000..eced58b3cbf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-overloaded-auto-deref.rs @@ -0,0 +1,7 @@ +use std::rc::Rc; + +pub fn main() { + let _x = Rc::new(vec![1, 2]).into_iter(); +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-overloaded-deref.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-overloaded-deref.rs new file mode 100644 index 000000000000..1ffba8cf497a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-overloaded-deref.rs @@ -0,0 +1,7 @@ +use std::rc::Rc; + +pub fn main() { + let _x = *Rc::new("hi".to_string()); +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-static-item.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-static-item.rs new file mode 100644 index 000000000000..ff18a38d2caf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-static-item.rs @@ -0,0 +1,17 @@ +// Ensure that moves out of static items is forbidden + +struct Foo { + foo: isize, +} + +static BAR: Foo = Foo { foo: 5 }; + + +fn test(f: Foo) { + let _f = Foo{foo: 4, ..f}; +} + +fn main() { + test(BAR); // { dg-error ".E0507." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-struct-with-dtor.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-struct-with-dtor.rs new file mode 100644 index 000000000000..56761a3012e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-struct-with-dtor.rs @@ -0,0 +1,23 @@ +struct S {f:String} +impl Drop for S { + fn drop(&mut self) { println!("{}", self.f); } +} + +fn move_in_match() { + match (S {f:"foo".to_string()}) { +// { dg-error ".E0509." "" { target *-*-* } .-1 } + S {f:_s} => {} + } +} + +fn move_in_let() { + let S {f:_s} = S {f:"foo".to_string()}; +// { dg-error ".E0509." "" { target *-*-* } .-1 } +} + +fn move_in_fn_arg(S {f:_s}: S) { +// { dg-error ".E0509." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-tuple-struct-with-dtor.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-tuple-struct-with-dtor.rs new file mode 100644 index 000000000000..950f369c80b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-tuple-struct-with-dtor.rs @@ -0,0 +1,23 @@ +struct S(String); +impl Drop for S { + fn drop(&mut self) { } +} + +fn move_in_match() { + match S("foo".to_string()) { +// { dg-error ".E0509." "" { target *-*-* } .-1 } + S(_s) => {} + } +} + +fn move_in_let() { + let S(_s) = S("foo".to_string()); +// { dg-error ".E0509." "" { target *-*-* } .-1 } +} + +fn move_in_fn_arg(S(_s): S) { +// { dg-error ".E0509." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-vec-tail.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-vec-tail.rs new file mode 100644 index 000000000000..e881d16d8a06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-out-of-vec-tail.rs @@ -0,0 +1,34 @@ +// Test that we do not permit moves from &[] matched by a vec pattern. + +#[derive(Clone, Debug)] +struct Foo { + string: String +} + +pub fn main() { + let x = vec![ + Foo { string: "foo".to_string() }, + Foo { string: "bar".to_string() }, + Foo { string: "baz".to_string() } + ]; + let x: &[Foo] = &x; + match *x { + [_, ref tail @ ..] => { + match tail { +// { dg-error ".E0508." "" { target *-*-* } .-1 } + &[Foo { string: a }, + Foo { string: b }] => { + } + _ => { + unreachable!(); + } + } + let z = tail[0].clone(); + println!("{:?}", z); + } + _ => { + unreachable!(); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-subcomponent.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-subcomponent.rs new file mode 100644 index 000000000000..e9969606e141 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-move-subcomponent.rs @@ -0,0 +1,18 @@ +// Tests that the borrow checker checks all components of a path when moving +// out. + +#![feature(box_syntax)] + +struct S { + x : Box +} + +fn f(_: T) {} + +fn main() { + let a : S = S { x : box 1 }; + let pb = &a; + let S { x: ax } = a; // { dg-error ".E0505." "" { target *-*-* } } + f(pb); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs new file mode 100644 index 000000000000..d579da51671d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-multiple-borrows-interior-boxes.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test case from #39963. + +#[derive(Clone)] +struct Foo(Option>, Option>); + +fn test(f: &mut Foo) { + match *f { + Foo(Some(ref mut left), Some(ref mut right)) => match **left { + Foo(Some(ref mut left), Some(ref mut right)) => panic!(), + _ => panic!(), + }, + _ => panic!(), + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-multiple-captures.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-multiple-captures.rs new file mode 100644 index 000000000000..da5508a867f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-multiple-captures.rs @@ -0,0 +1,62 @@ +#![feature(box_syntax)] + +use std::thread; + +fn borrow(_: &T) { } + +fn different_vars_after_borrows() { + let x1: Box<_> = box 1; + let p1 = &x1; + let x2: Box<_> = box 2; + let p2 = &x2; + thread::spawn(move|| { +// { dg-error ".E0505." "" { target *-*-* } .-1 } +// { dg-error ".E0505." "" { target *-*-* } .-2 } + drop(x1); + drop(x2); + }); + borrow(&*p1); + borrow(&*p2); +} + +fn different_vars_after_moves() { + let x1: Box<_> = box 1; + drop(x1); + let x2: Box<_> = box 2; + drop(x2); + thread::spawn(move|| { +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + drop(x1); + drop(x2); + }); +} + +fn same_var_after_borrow() { + let x: Box<_> = box 1; + let p = &x; + thread::spawn(move|| { +// { dg-error ".E0505." "" { target *-*-* } .-1 } + drop(x); + drop(x); // { dg-error ".E0382." "" { target *-*-* } } + }); + borrow(&*p); +} + +fn same_var_after_move() { + let x: Box<_> = box 1; + drop(x); + thread::spawn(move|| { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + drop(x); + drop(x); // { dg-error ".E0382." "" { target *-*-* } } + }); +} + +fn main() { + different_vars_after_borrows(); + different_vars_after_moves(); + same_var_after_borrow(); + same_var_after_move(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-addr-of-imm-var.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-addr-of-imm-var.rs new file mode 100644 index 000000000000..3c8247848fc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-addr-of-imm-var.rs @@ -0,0 +1,7 @@ +fn main() { + let x: isize = 3; + let y: &mut isize = &mut x; // { dg-error ".E0596." "" { target *-*-* } } + *y = 5; + println!("{}", *y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-borrow-linear-errors.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-borrow-linear-errors.rs new file mode 100644 index 000000000000..a918b27e2db0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-borrow-linear-errors.rs @@ -0,0 +1,16 @@ +// Test to ensure we only report an error for the first issued loan that +// conflicts with a new loan, as opposed to every issued loan. This keeps us +// down to O(n) errors (for n problem lines), instead of O(n^2) errors. + +fn main() { + let mut x = 1; + let mut addr = vec![]; + loop { + match 1 { + 1 => { addr.push(&mut x); } // { dg-error ".E0499." "" { target *-*-* } } + 2 => { addr.push(&mut x); } // { dg-error ".E0499." "" { target *-*-* } } + _ => { addr.push(&mut x); } // { dg-error ".E0499." "" { target *-*-* } } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs new file mode 100644 index 000000000000..32737f304b8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-borrow-of-mut-base-ptr.rs @@ -0,0 +1,29 @@ +// Test that attempt to mutably borrow `&mut` pointer while pointee is +// borrowed yields an error. +// +// Example from compiler/rustc_borrowck/borrowck/README.md + + + +fn foo<'a>(mut t0: &'a mut isize, + mut t1: &'a mut isize) { + let p: &isize = &*t0; // Freezes `*t0` + let mut t2 = &mut t0; // { dg-error ".E0502." "" { target *-*-* } } + **t2 += 1; // Mutates `*t0` + p.use_ref(); +} + +fn bar<'a>(mut t0: &'a mut isize, + mut t1: &'a mut isize) { + let p: &mut isize = &mut *t0; // Claims `*t0` + let mut t2 = &mut t0; // { dg-error ".E0499." "" { target *-*-* } } + **t2 += 1; // Mutates `*t0` but not through `*p` + p.use_mut(); +} + +fn main() { +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-slice-of-imm-vec.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-slice-of-imm-vec.rs new file mode 100644 index 000000000000..36dce7d80cf5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-slice-of-imm-vec.rs @@ -0,0 +1,9 @@ +fn write(v: &mut [isize]) { + v[0] += 1; +} + +fn main() { + let v = vec![1, 2, 3]; + write(&mut v); // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-uniq.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-uniq.rs new file mode 100644 index 000000000000..3fd2ad7abe7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-uniq.rs @@ -0,0 +1,34 @@ +// run-pass +#![feature(box_syntax)] + +use std::mem::swap; + +#[derive(Debug)] +struct Ints {sum: Box, values: Vec } + +fn add_int(x: &mut Ints, v: isize) { + *x.sum += v; + let mut values = Vec::new(); + swap(&mut values, &mut x.values); + values.push(v); + swap(&mut values, &mut x.values); +} + +fn iter_ints(x: &Ints, mut f: F) -> bool where F: FnMut(&isize) -> bool { + let l = x.values.len(); + (0..l).all(|i| f(&x.values[i])) +} + +pub fn main() { + let mut ints: Box<_> = box Ints {sum: box 0, values: Vec::new()}; + add_int(&mut *ints, 22); + add_int(&mut *ints, 44); + + iter_ints(&*ints, |i| { + println!("isize = {:?}", *i); + true + }); + + println!("ints={:?}", ints); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs new file mode 100644 index 000000000000..15050c9d8e82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mut-vec-as-imm-slice.rs @@ -0,0 +1,17 @@ +// run-pass + + +fn want_slice(v: &[isize]) -> isize { + let mut sum = 0; + for i in v { sum += *i; } + sum +} + +fn has_mut_vec(v: Vec ) -> isize { + want_slice(&v) +} + +pub fn main() { + assert_eq!(has_mut_vec(vec![1, 2, 3]), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mutate-in-guard.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mutate-in-guard.rs new file mode 100644 index 000000000000..6d3883f06712 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-mutate-in-guard.rs @@ -0,0 +1,22 @@ +enum Enum<'a> { + A(&'a isize), + B(bool), +} + +fn foo() -> isize { + let mut n = 42; + let mut x = Enum::A(&mut n); + match x { + Enum::A(_) if { x = Enum::B(false); false } => 1, +// { dg-error ".E0510." "" { target *-*-* } .-1 } + Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1, +// { dg-error ".E0510." "" { target *-*-* } .-1 } + Enum::A(p) => *p, + Enum::B(_) => 2, + } +} + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-no-cycle-in-exchange-heap.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-no-cycle-in-exchange-heap.rs new file mode 100644 index 000000000000..96558201aaac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-no-cycle-in-exchange-heap.rs @@ -0,0 +1,21 @@ +#![feature(box_syntax)] + +struct Node_ { + a: Box +} + +enum Cycle { + Node(Node_), + Empty, +} +fn main() { + let mut x: Box<_> = box Cycle::Node(Node_ {a: box Cycle::Empty}); + // Create a cycle! + match *x { + Cycle::Node(ref mut y) => { + y.a = x; // { dg-error ".E0505." "" { target *-*-* } } + } + Cycle::Empty => {} + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-object-lifetime.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-object-lifetime.rs new file mode 100644 index 000000000000..10408f8f09cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-object-lifetime.rs @@ -0,0 +1,41 @@ +// Test that borrows that occur due to calls to object methods +// properly "claim" the object path. + + + +trait Foo { + fn borrowed(&self) -> &(); + fn mut_borrowed(&mut self) -> &(); +} + +fn borrowed_receiver(x: &dyn Foo) { + let y = x.borrowed(); + let z = x.borrowed(); + z.use_ref(); + y.use_ref(); +} + +fn mut_borrowed_receiver(x: &mut dyn Foo) { + let y = x.borrowed(); + let z = x.mut_borrowed(); // { dg-error ".E0502." "" { target *-*-* } } + y.use_ref(); +} + +fn mut_owned_receiver(mut x: Box) { + let y = x.borrowed(); + let z = &mut x; // { dg-error ".E0502." "" { target *-*-* } } + y.use_ref(); +} + +fn imm_owned_receiver(mut x: Box) { + let y = x.borrowed(); + let z = &x; + z.use_ref(); + y.use_ref(); +} + +fn main() {} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-or-init.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-or-init.rs new file mode 100644 index 000000000000..0afbd56a977e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-or-init.rs @@ -0,0 +1,7 @@ +fn main() { + let i: isize; + + println!("{}", false || { i = 5; true }); + println!("{}", i); // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-call.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-call.rs new file mode 100644 index 000000000000..4143ef631d54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-call.rs @@ -0,0 +1,81 @@ +#![feature(fn_traits, unboxed_closures)] + +use std::ops::{Fn, FnMut, FnOnce}; + +struct SFn { + x: isize, + y: isize, +} + +impl Fn<(isize,)> for SFn { + extern "rust-call" fn call(&self, (z,): (isize,)) -> isize { + self.x * self.y * z + } +} + +impl FnMut<(isize,)> for SFn { + extern "rust-call" fn call_mut(&mut self, args: (isize,)) -> isize { self.call(args) } +} + +impl FnOnce<(isize,)> for SFn { + type Output = isize; + extern "rust-call" fn call_once(self, args: (isize,)) -> isize { self.call(args) } +} + +struct SFnMut { + x: isize, + y: isize, +} + +impl FnMut<(isize,)> for SFnMut { + extern "rust-call" fn call_mut(&mut self, (z,): (isize,)) -> isize { + self.x * self.y * z + } +} + +impl FnOnce<(isize,)> for SFnMut { + type Output = isize; + extern "rust-call" fn call_once(mut self, args: (isize,)) -> isize { self.call_mut(args) } +} + +struct SFnOnce { + x: String, +} + +impl FnOnce<(String,)> for SFnOnce { + type Output = usize; + + extern "rust-call" fn call_once(self, (z,): (String,)) -> usize { + self.x.len() + z.len() + } +} + +fn f() { + let mut s = SFn { + x: 1, + y: 2, + }; + let sp = &mut s; + s(3); // { dg-error ".E0502." "" { target *-*-* } } + use_mut(sp); +} +fn g() { + let s = SFnMut { + x: 1, + y: 2, + }; + s(3); // { dg-error ".E0596." "" { target *-*-* } } +} + +fn h() { + let s = SFnOnce { + x: "hello".to_string(), + }; + s(" world".to_string()); + s(" world".to_string()); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() {} + +fn use_mut(_: &mut T) { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-and-overloaded-deref.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-and-overloaded-deref.rs new file mode 100644 index 000000000000..9555eb4804a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-and-overloaded-deref.rs @@ -0,0 +1,37 @@ +// Check that we properly record borrows when we are doing an +// overloaded, autoderef of a value obtained via an overloaded index +// operator. The accounting of the all the implicit things going on +// here is rather subtle. Issue #20232. + +use std::ops::{Deref, Index}; + +struct MyVec { x: T } + +impl Index for MyVec { + type Output = T; + fn index(&self, _: usize) -> &T { + &self.x + } +} + +struct MyPtr { x: T } + +impl Deref for MyPtr { + type Target = T; + fn deref(&self) -> &T { + &self.x + } +} + +struct Foo { f: usize } + +fn main() { + let mut v = MyVec { x: MyPtr { x: Foo { f: 22 } } }; + let i = &v[0].f; + v = MyVec { x: MyPtr { x: Foo { f: 23 } } }; +// { dg-error ".E0506." "" { target *-*-* } .-1 } + read(*i); +} + +fn read(_: usize) { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-autoderef.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-autoderef.rs new file mode 100644 index 000000000000..7e44297eca96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-autoderef.rs @@ -0,0 +1,98 @@ +// Test that we still see borrowck errors of various kinds when using +// indexing and autoderef in combination. + +use std::ops::{Index, IndexMut}; + + + +struct Foo { + x: isize, + y: isize, +} + +impl<'a> Index<&'a String> for Foo { + type Output = isize; + + fn index(&self, z: &String) -> &isize { + if *z == "x" { + &self.x + } else { + &self.y + } + } +} + +impl<'a> IndexMut<&'a String> for Foo { + fn index_mut(&mut self, z: &String) -> &mut isize { + if *z == "x" { + &mut self.x + } else { + &mut self.y + } + } +} + +fn test1(mut f: Box, s: String) { + let p = &mut f[&s]; + let q = &f[&s]; // { dg-error ".E0502." "" { target *-*-* } } + p.use_mut(); +} + +fn test2(mut f: Box, s: String) { + let p = &mut f[&s]; + let q = &mut f[&s]; // { dg-error ".E0499." "" { target *-*-* } } + p.use_mut(); +} + +struct Bar { + foo: Foo +} + +fn test3(mut f: Box, s: String) { + let p = &mut f.foo[&s]; + let q = &mut f.foo[&s]; // { dg-error ".E0499." "" { target *-*-* } } + p.use_mut(); +} + +fn test4(mut f: Box, s: String) { + let p = &f.foo[&s]; + let q = &f.foo[&s]; + p.use_ref(); +} + +fn test5(mut f: Box, s: String) { + let p = &f.foo[&s]; + let q = &mut f.foo[&s]; // { dg-error ".E0502." "" { target *-*-* } } + p.use_ref(); +} + +fn test6(mut f: Box, g: Foo, s: String) { + let p = &f.foo[&s]; + f.foo = g; // { dg-error ".E0506." "" { target *-*-* } } + p.use_ref(); +} + +fn test7(mut f: Box, g: Bar, s: String) { + let p = &f.foo[&s]; + *f = g; // { dg-error ".E0506." "" { target *-*-* } } + p.use_ref(); +} + +fn test8(mut f: Box, g: Foo, s: String) { + let p = &mut f.foo[&s]; + f.foo = g; // { dg-error ".E0506." "" { target *-*-* } } + p.use_mut(); +} + +fn test9(mut f: Box, g: Bar, s: String) { + let p = &mut f.foo[&s]; + *f = g; // { dg-error ".E0506." "" { target *-*-* } } + p.use_mut(); +} + +fn main() { +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-move-from-vec.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-move-from-vec.rs new file mode 100644 index 000000000000..df082bd212d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-move-from-vec.rs @@ -0,0 +1,23 @@ +#![feature(box_syntax)] + +use std::ops::Index; + +struct MyVec { + data: Vec, +} + +impl Index for MyVec { + type Output = T; + + fn index(&self, i: usize) -> &T { + &self.data[i] + } +} + +fn main() { + let v = MyVec::> { data: vec![box 1, box 2, box 3] }; + let good = &v[0]; // Shouldn't fail here + let bad = v[0]; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-move-index.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-move-index.rs new file mode 100644 index 000000000000..8d71fc53c05e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-move-index.rs @@ -0,0 +1,69 @@ +use std::ops::{Index, IndexMut}; + +struct Foo { + x: isize, + y: isize, +} + +impl Index for Foo { + type Output = isize; + + fn index(&self, z: String) -> &isize { + if z == "x" { + &self.x + } else { + &self.y + } + } +} + +impl IndexMut for Foo { + fn index_mut(&mut self, z: String) -> &mut isize { + if z == "x" { + &mut self.x + } else { + &mut self.y + } + } +} + +struct Bar { + x: isize, +} + +impl Index for Bar { + type Output = isize; + + fn index<'a>(&'a self, z: isize) -> &'a isize { + &self.x + } +} + +fn main() { + let mut f = Foo { + x: 1, + y: 2, + }; + let mut s = "hello".to_string(); + let rs = &mut s; + + println!("{}", f[s]); +// { dg-error ".E0505." "" { target *-*-* } .-1 } + + f[s] = 10; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + + let s = Bar { + x: 1, + }; + let i = 2; + let _j = &i; + println!("{}", s[i]); // no error, i is copy + println!("{}", s[i]); + + use_mut(rs); +} + +fn use_mut(_: &mut T) { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-ref-index.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-ref-index.rs new file mode 100644 index 000000000000..d9330597a11e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-overloaded-index-ref-index.rs @@ -0,0 +1,60 @@ +use std::ops::{Index, IndexMut}; + +struct Foo { + x: isize, + y: isize, +} + +impl<'a> Index<&'a String> for Foo { + type Output = isize; + + fn index(&self, z: &String) -> &isize { + if *z == "x" { + &self.x + } else { + &self.y + } + } +} + +impl<'a> IndexMut<&'a String> for Foo { + fn index_mut(&mut self, z: &String) -> &mut isize { + if *z == "x" { + &mut self.x + } else { + &mut self.y + } + } +} + +struct Bar { + x: isize, +} + +impl Index for Bar { + type Output = isize; + + fn index<'a>(&'a self, z: isize) -> &'a isize { + &self.x + } +} + +fn main() { + let mut f = Foo { + x: 1, + y: 2, + }; + let mut s = "hello".to_string(); + let rs = &mut s; + println!("{}", f[&s]); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + f[&s] = 10; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + let s = Bar { + x: 1, + }; + s[2] = 20; +// { dg-error ".E0594." "" { target *-*-* } .-1 } + drop(rs); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-1.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-1.rs new file mode 100644 index 000000000000..db2cccb0e46a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-1.rs @@ -0,0 +1,40 @@ +struct Test; + +struct Test2 { + b: Option, +} + +struct Test3(Option); + +impl Drop for Test { + fn drop(&mut self) { + println!("dropping!"); + } +} + +impl Drop for Test2 { + fn drop(&mut self) {} +} + +impl Drop for Test3 { + fn drop(&mut self) {} +} + +fn stuff() { + let mut t = Test2 { b: None }; + let u = Test; + drop(t); + t.b = Some(u); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + + let mut t = Test3(None); + let u = Test; + drop(t); + t.0 = Some(u); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn main() { + stuff() +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-2.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-2.rs new file mode 100644 index 000000000000..e4abdb2bc18a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-2.rs @@ -0,0 +1,24 @@ +struct Test { + a: isize, + b: Option>, +} + +impl Drop for Test { + fn drop(&mut self) { + println!("Dropping {}", self.a); + } +} + +fn stuff() { + let mut t = Test { a: 1, b: None}; + let mut u = Test { a: 2, b: Some(Box::new(t))}; + t.b = Some(Box::new(u)); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + println!("done"); +} + +fn main() { + stuff(); + println!("Hello, world!") +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-3.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-3.rs new file mode 100644 index 000000000000..bbd08715f059 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-3.rs @@ -0,0 +1,14 @@ +use std::mem; + +struct Test { f: usize } +impl Drop for Test { + fn drop(&mut self) {} +} + +fn main() { + let mut x = (Test { f: 2 }, Test { f: 4 }); + mem::drop(x.0); + x.0.f = 3; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-4.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-4.rs new file mode 100644 index 000000000000..98aca2b4b001 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-partial-reinit-4.rs @@ -0,0 +1,24 @@ +struct Test; + +struct Test2(Option); + +impl Drop for Test { + fn drop(&mut self) { + println!("dropping!"); + } +} + +impl Drop for Test2 { + fn drop(&mut self) {} +} + +fn stuff() { + let mut x : (Test2, Test2); + (x.0).0 = Some(Test); +// { dg-error ".E0381." "" { target *-*-* } .-1 } +} + +fn main() { + stuff() +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-pat-enum.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-pat-enum.rs new file mode 100644 index 000000000000..eace36405c37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-pat-enum.rs @@ -0,0 +1,40 @@ +// run-pass +#![allow(dead_code)] +// ignore-pretty issue #37199 + +fn match_ref(v: Option) -> isize { + match v { + Some(ref i) => { + *i + } + None => {0} + } +} + +fn match_ref_unused(v: Option) { + match v { + Some(_) => {} + None => {} + } +} + +fn impure(_i: isize) { +} + +fn match_imm_reg(v: &Option) { + match *v { + Some(ref i) => {impure(*i)} // OK because immutable + None => {} + } +} + +fn match_mut_reg(v: &mut Option) { + match *v { + Some(ref i) => {impure(*i)} // OK, frozen + None => {} + } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-pat-reassign-binding.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-pat-reassign-binding.rs new file mode 100644 index 000000000000..cce41687aef7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-pat-reassign-binding.rs @@ -0,0 +1,16 @@ +fn main() { + let mut x: Option = None; + match x { + None => { + // Note: on this branch, no borrow has occurred. + x = Some(0); + } + Some(ref i) => { + // But on this branch, `i` is an outstanding borrow + x = Some(*i+1); // { dg-error ".E0506." "" { target *-*-* } } + drop(i); + } + } + x.clone(); // just to prevent liveness warnings +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-pat-reassign-no-binding.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-pat-reassign-no-binding.rs new file mode 100644 index 000000000000..029d273c22cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-pat-reassign-no-binding.rs @@ -0,0 +1,15 @@ +// run-pass + +pub fn main() { + let mut x = None; + match x { + None => { + // It is ok to reassign x here, because there is in + // fact no outstanding loan of x! + x = Some(0); + } + Some(_) => { } + } + assert_eq!(x, Some(0)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-reborrow-from-mut.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-reborrow-from-mut.rs new file mode 100644 index 000000000000..4600e4de5c49 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-reborrow-from-mut.rs @@ -0,0 +1,100 @@ +struct Foo { + bar1: Bar, + bar2: Bar +} + +struct Bar { + int1: isize, + int2: isize, +} + +fn borrow_same_field_twice_mut_mut(foo: &mut Foo) { + let _bar1 = &mut foo.bar1; + let _bar2 = &mut foo.bar1; // { dg-error ".E0499." "" { target *-*-* } } + use_mut(_bar1); +} +fn borrow_same_field_twice_mut_imm(foo: &mut Foo) { + let _bar1 = &mut foo.bar1; + let _bar2 = &foo.bar1; // { dg-error ".E0502." "" { target *-*-* } } + use_mut(_bar1); +} +fn borrow_same_field_twice_imm_mut(foo: &mut Foo) { + let _bar1 = &foo.bar1; + let _bar2 = &mut foo.bar1; // { dg-error ".E0502." "" { target *-*-* } } + use_imm(_bar1); +} +fn borrow_same_field_twice_imm_imm(foo: &mut Foo) { + let _bar1 = &foo.bar1; + let _bar2 = &foo.bar1; + use_imm(_bar1); +} +fn borrow_both_mut(foo: &mut Foo) { + let _bar1 = &mut foo.bar1; + let _bar2 = &mut foo.bar2; + use_mut(_bar1); +} +fn borrow_both_mut_pattern(foo: &mut Foo) { + match *foo { + Foo { bar1: ref mut _bar1, bar2: ref mut _bar2 } => + { use_mut(_bar1); use_mut(_bar2); } + } +} +fn borrow_var_and_pattern(foo: &mut Foo) { + let _bar1 = &mut foo.bar1; + match *foo { + Foo { bar1: ref mut _bar1, bar2: _ } => {} +// { dg-error ".E0499." "" { target *-*-* } .-1 } + } + use_mut(_bar1); +} +fn borrow_mut_and_base_imm(foo: &mut Foo) { + let _bar1 = &mut foo.bar1.int1; + let _foo1 = &foo.bar1; // { dg-error ".E0502." "" { target *-*-* } } + let _foo2 = &*foo; // { dg-error ".E0502." "" { target *-*-* } } + use_mut(_bar1); +} +fn borrow_mut_and_base_mut(foo: &mut Foo) { + let _bar1 = &mut foo.bar1.int1; + let _foo1 = &mut foo.bar1; // { dg-error ".E0499." "" { target *-*-* } } + use_mut(_bar1); +} +fn borrow_mut_and_base_mut2(foo: &mut Foo) { + let _bar1 = &mut foo.bar1.int1; + let _foo2 = &mut *foo; // { dg-error ".E0499." "" { target *-*-* } } + use_mut(_bar1); +} +fn borrow_imm_and_base_mut(foo: &mut Foo) { + let _bar1 = &foo.bar1.int1; + let _foo1 = &mut foo.bar1; // { dg-error ".E0502." "" { target *-*-* } } + use_imm(_bar1); +} +fn borrow_imm_and_base_mut2(foo: &mut Foo) { + let _bar1 = &foo.bar1.int1; + let _foo2 = &mut *foo; // { dg-error ".E0502." "" { target *-*-* } } + use_imm(_bar1); +} +fn borrow_imm_and_base_imm(foo: &mut Foo) { + let _bar1 = &foo.bar1.int1; + let _foo1 = &foo.bar1; + let _foo2 = &*foo; + use_imm(_bar1); +} +fn borrow_mut_and_imm(foo: &mut Foo) { + let _bar1 = &mut foo.bar1; + let _foo1 = &foo.bar2; + use_mut(_bar1); +} +fn borrow_mut_from_imm(foo: &Foo) { + let _bar1 = &mut foo.bar1; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn borrow_long_path_both_mut(foo: &mut Foo) { + let _bar1 = &mut foo.bar1.int1; + let _foo1 = &mut foo.bar2.int2; + use_mut(_bar1); +} +fn main() {} + +fn use_mut(_: &mut T) { } +fn use_imm(_: &T) { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.rs new file mode 100644 index 000000000000..0be89efa972b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-reborrow-from-shorter-lived-andmut.rs @@ -0,0 +1,23 @@ +// Test that assignments to an `&mut` pointer which is found in a +// borrowed (but otherwise non-aliasable) location is illegal. + +struct S<'a> { + pointer: &'a mut isize +} + +fn copy_borrowed_ptr<'a,'b>(p: &'a mut S<'b>) -> S<'b> { + S { pointer: &mut *p.pointer } +// { dg-error ".E0623." "" { target *-*-* } .-1 } +} + +fn main() { + let mut x = 1; + + { + let mut y = S { pointer: &mut x }; + let z = copy_borrowed_ptr(&mut y); + *y.pointer += 1; + *z.pointer += 1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-ref-mut-of-imm.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-ref-mut-of-imm.rs new file mode 100644 index 000000000000..4803f1b4bb92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-ref-mut-of-imm.rs @@ -0,0 +1,11 @@ +fn destructure(x: Option) -> isize { + match x { + None => 0, + Some(ref mut v) => *v // { dg-error ".E0596." "" { target *-*-* } } + } +} + +fn main() { + assert_eq!(destructure(Some(22)), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-reinit.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-reinit.rs new file mode 100644 index 000000000000..52ebcbd37946 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-reinit.rs @@ -0,0 +1,8 @@ +fn main() { + let mut x = Box::new(0); + let _u = x; // error shouldn't note this move + x = Box::new(1); + drop(x); + let _ = (1,x); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-report-with-custom-diagnostic.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-report-with-custom-diagnostic.rs new file mode 100644 index 000000000000..2563fcff32b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-report-with-custom-diagnostic.rs @@ -0,0 +1,45 @@ +#![feature(rustc_attrs)] +#![allow(dead_code)] +fn main() { #![rustc_error] // rust-lang/rust#49855 + // Original borrow ends at end of function + let mut x = 1; + let y = &mut x; +// { dg-error "" "" { target *-*-* } .-1 } + let z = &x; // { dg-error ".E0502." "" { target *-*-* } } +// { dg-error ".E0502." "" { target *-*-* } .-1 } + z.use_ref(); + y.use_mut(); +} + +fn foo() { + match true { + true => { + // Original borrow ends at end of match arm + let mut x = 1; + let y = &x; +// { dg-error "" "" { target *-*-* } .-1 } + let z = &mut x; // { dg-error ".E0502." "" { target *-*-* } } +// { dg-error ".E0502." "" { target *-*-* } .-1 } + z.use_mut(); + y.use_ref(); + } + false => () + } +} + +fn bar() { + // Original borrow ends at end of closure + || { + let mut x = 1; + let y = &mut x; +// { dg-error "" "" { target *-*-* } .-1 } + let z = &mut x; // { dg-error ".E0499." "" { target *-*-* } } +// { dg-error ".E0499." "" { target *-*-* } .-1 } + z.use_mut(); + y.use_mut(); + }; +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-return-variable-on-stack-via-clone.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-return-variable-on-stack-via-clone.rs new file mode 100644 index 000000000000..fb7280ab5289 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-return-variable-on-stack-via-clone.rs @@ -0,0 +1,11 @@ +// Check that when we clone a `&T` pointer we properly relate the +// lifetime of the pointer which results to the pointer being cloned. +// Bugs in method resolution have sometimes broken this connection. +// Issue #19261. + +fn leak<'a, T>(x: T) -> &'a T { + (&x).clone() // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-return.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-return.rs new file mode 100644 index 000000000000..c94016d72ed7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-return.rs @@ -0,0 +1,7 @@ +fn f() -> isize { + let x: isize; + return x; // { dg-error ".E0381." "" { target *-*-* } } +} + +fn main() { f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-rvalues-mutable.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-rvalues-mutable.rs new file mode 100644 index 000000000000..f321e59c4446 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-rvalues-mutable.rs @@ -0,0 +1,35 @@ +// run-pass + +struct Counter { + value: usize +} + +impl Counter { + fn new(v: usize) -> Counter { + Counter {value: v} + } + + fn inc<'a>(&'a mut self) -> &'a mut Counter { + self.value += 1; + self + } + + fn get(&self) -> usize { + self.value + } + + fn get_and_inc(&mut self) -> usize { + let v = self.value; + self.value += 1; + v + } +} + +pub fn main() { + let v = Counter::new(22).get_and_inc(); + assert_eq!(v, 22); + + let v = Counter::new(22).inc().inc().get(); + assert_eq!(v, 24); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs new file mode 100644 index 000000000000..3c73d5017d94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-scope-of-deref-issue-4666.rs @@ -0,0 +1,43 @@ +// run-pass +// Tests that the scope of the pointer returned from `get()` is +// limited to the deref operation itself, and does not infect the +// block as a whole. + + +struct Box { + x: usize +} + +impl Box { + fn get(&self) -> &usize { + &self.x + } + fn set(&mut self, x: usize) { + self.x = x; + } +} + +fn fun1() { + // in the past, borrow checker behaved differently when + // init and decl of `v` were distinct + let v; + let mut a_box = Box {x: 0}; + a_box.set(22); + v = *a_box.get(); + a_box.set(v+1); + assert_eq!(23, *a_box.get()); +} + +fn fun2() { + let mut a_box = Box {x: 0}; + a_box.set(22); + let v = *a_box.get(); + a_box.set(v+1); + assert_eq!(23, *a_box.get()); +} + +pub fn main() { + fun1(); + fun2(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs new file mode 100644 index 000000000000..1b205c00e2aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs @@ -0,0 +1,65 @@ +// check-pass + +fn nop(_s: &[& i32]) {} +fn nop_subslice(_s: &[i32]) {} + +fn const_index_ok(s: &mut [i32; 4]) { + let [ref first, ref second, _, ref fourth, ..] = *s; + let [_, _, ref mut third, ..] = *s; + nop(&[first, second, third, fourth]); +} + +fn const_index_from_end_ok(s: &mut [i32; 4]) { + let [.., ref fourth, ref third, _, ref first] = *s; + let [.., ref mut second, _] = *s; + nop(&[first, second, third, fourth]); +} + +fn const_index_mixed(s: &mut [i32; 6]) { + let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s; + + let [ref mut from_begin0, ..] = *s; + nop(&[from_begin0, from_end1, from_end3, from_end4]); + let [_, ref mut from_begin1, ..] = *s; + nop(&[from_begin1, from_end1, from_end3, from_end4]); + + let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s; + + let [.., ref mut from_end1] = *s; + nop(&[from_begin0, from_begin1, from_begin3, from_end1]); + let [.., ref mut from_end2, _] = *s; + nop(&[from_begin0, from_begin1, from_begin3, from_end2]); + let [.., ref mut from_end4, _, _, _] = *s; + nop(&[from_begin0, from_begin1, from_begin3, from_end4]); +} + +fn const_index_and_subslice_ok(s: &mut [i32; 4]) { + let [ref first, ref second, ..] = *s; + let [_, _, ref mut tail @ ..] = *s; + nop(&[first, second]); + nop_subslice(tail); +} + +fn const_index_and_subslice_from_end_ok(s: &mut [i32; 4]) { + let [.., ref second, ref first] = *s; + let [ref mut tail @ .., _, _] = *s; + nop(&[first, second]); + nop_subslice(tail); +} + +fn subslices(s: &mut [i32; 4]) { + let [_, _, ref s1 @ ..] = *s; + let [ref mut s2 @ .., _, _] = *s; + nop_subslice(s1); + nop_subslice(s2); +} + +fn main() { + let mut v = [1,2,3,4]; + const_index_ok(&mut v); + const_index_from_end_ok(&mut v); + const_index_and_subslice_ok(&mut v); + const_index_and_subslice_from_end_ok(&mut v); + subslices(&mut v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs new file mode 100644 index 000000000000..bffec08672b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs @@ -0,0 +1,59 @@ +fn nop(_s: &[& i32]) {} +fn nop_subslice(_s: &[i32]) {} + +fn const_index_err(s: &mut [i32; 4]) { + let [ref first, ref second, ..] = *s; + let [_, ref mut second2, ref mut third, ..] = *s; // { dg-error ".E0502." "" { target *-*-* } } + nop(&[first, second, second2, third]); +} + +fn const_index_from_end_err(s: &mut [i32; 4]) { + let [.., ref fourth, ref third, _, ref first] = *s; + let [.., ref mut third2, _, _] = *s; // { dg-error ".E0502." "" { target *-*-* } } + nop(&[first, third, third2, fourth]); +} + +fn const_index_mixed(s: &mut [i32; 6]) { + let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s; + + let [_, _, ref mut from_begin2, ..] = *s; // { dg-error ".E0502." "" { target *-*-* } } + nop(&[from_begin2, from_end1, from_end3, from_end4]); + let [_, _, _, ref mut from_begin3, ..] = *s; // { dg-error ".E0502." "" { target *-*-* } } + nop(&[from_begin3, from_end1, from_end3, from_end4]); + + let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s; + + let [.., ref mut from_end3, _, _] = *s; // { dg-error ".E0502." "" { target *-*-* } } + nop(&[from_begin0, from_begin1, from_begin3, from_end3]); +} + +fn const_index_and_subslice_err(s: &mut [i32; 4]) { + let [ref first, ref second, ..] = *s; + let [_, ref mut tail @ ..] = *s; // { dg-error ".E0502." "" { target *-*-* } } + nop(&[first, second]); + nop_subslice(tail); +} + +fn const_index_and_subslice_from_end_err(s: &mut [i32; 4]) { + let [.., ref second, ref first] = *s; + let [ref mut tail @ .., _] = *s; // { dg-error ".E0502." "" { target *-*-* } } + nop(&[first, second]); + nop_subslice(tail); +} + +fn subslices_overlap(s: &mut [i32; 4]) { + let [_, ref s1 @ ..] = *s; + let [ref mut s2 @ .., _, _] = *s; // { dg-error ".E0502." "" { target *-*-* } } + nop_subslice(s1); + nop_subslice(s2); +} + +fn main() { + let mut v = [1,2,3,4]; + const_index_err(&mut v); + const_index_from_end_err(&mut v); + const_index_and_subslice_err(&mut v); + const_index_and_subslice_from_end_err(&mut v); + subslices_overlap(&mut v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs new file mode 100644 index 000000000000..3a377d114595 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs @@ -0,0 +1,22 @@ +// run-pass + +fn mut_head_tail<'a, A>(v: &'a mut [A]) -> Option<(&'a mut A, &'a mut [A])> { + match *v { + [ref mut head, ref mut tail @ ..] => { + Some((head, tail)) + } + [] => None + } +} + +fn main() { + let mut v = [1,2,3,4]; + match mut_head_tail(&mut v) { + None => {}, + Some((h,t)) => { + *h = 1000; + t.reverse(); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs new file mode 100644 index 000000000000..a22ab1ef3106 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs @@ -0,0 +1,60 @@ +// check-pass + +fn nop(_s: &[& i32]) {} +fn nop_subslice(_s: &[i32]) {} + +fn const_index_ok(s: &mut [i32]) { + if let [ref first, ref second, _, ref fourth, ..] = *s { + if let [_, _, ref mut third, ..] = *s { + nop(&[first, second, third, fourth]); + } + } +} + +fn const_index_from_end_ok(s: &mut [i32]) { + if let [.., ref fourth, ref third, _, ref first] = *s { + if let [.., ref mut second, _] = *s { + nop(&[first, second, third, fourth]); + } + } +} + +fn const_index_mixed(s: &mut [i32]) { + if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s { + if let [ref mut from_begin0, ..] = *s { + nop(&[from_begin0, from_end1, from_end3, from_end4]); + } + } + if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s { + if let [.., ref mut from_end1] = *s { + nop(&[from_begin0, from_begin1, from_begin3, from_end1]); + } + } +} + +fn const_index_and_subslice_ok(s: &mut [i32]) { + if let [ref first, ref second, ..] = *s { + if let [_, _, ref mut tail @ ..] = *s { + nop(&[first, second]); + nop_subslice(tail); + } + } +} + +fn const_index_and_subslice_from_end_ok(s: &mut [i32]) { + if let [.., ref second, ref first] = *s { + if let [ref mut tail @ .., _, _] = *s { + nop(&[first, second]); + nop_subslice(tail); + } + } +} + +fn main() { + let mut v = [1,2,3,4]; + const_index_ok(&mut v); + const_index_from_end_ok(&mut v); + const_index_and_subslice_ok(&mut v); + const_index_and_subslice_from_end_ok(&mut v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs new file mode 100644 index 000000000000..abb179478beb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs @@ -0,0 +1,80 @@ +fn nop(_s: &[& i32]) {} +fn nop_subslice(_s: &[i32]) {} + +fn const_index_err(s: &mut [i32]) { + if let [ref first, ref second, ..] = *s { + if let [_, ref mut second2, ref mut third, ..] = *s { // { dg-error ".E0502." "" { target *-*-* } } + nop(&[first, second, second2, third]); + } + } +} + +fn const_index_from_end_err(s: &mut [i32]) { + if let [.., ref fourth, ref third, _, ref first] = *s { + if let [.., ref mut third2, _, _] = *s { // { dg-error ".E0502." "" { target *-*-* } } + nop(&[first, third, third2, fourth]); + } + } +} + +fn const_index_mixed(s: &mut [i32]) { + if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s { + if let [_, ref mut from_begin1, ..] = *s { // { dg-error ".E0502." "" { target *-*-* } } + nop(&[from_begin1, from_end1, from_end3, from_end4]); + } + if let [_, _, ref mut from_begin2, ..] = *s { // { dg-error ".E0502." "" { target *-*-* } } + nop(&[from_begin2, from_end1, from_end3, from_end4]); + } + if let [_, _, _, ref mut from_begin3, ..] = *s { // { dg-error ".E0502." "" { target *-*-* } } + nop(&[from_begin3, from_end1, from_end3, from_end4]); + } + } + if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s { + if let [.., ref mut from_end2, _] = *s { // { dg-error ".E0502." "" { target *-*-* } } + nop(&[from_begin0, from_begin1, from_begin3, from_end2]); + } + if let [.., ref mut from_end3, _, _] = *s { // { dg-error ".E0502." "" { target *-*-* } } + nop(&[from_begin0, from_begin1, from_begin3, from_end3]); + } + if let [.., ref mut from_end4, _, _, _] = *s { // { dg-error ".E0502." "" { target *-*-* } } + nop(&[from_begin0, from_begin1, from_begin3, from_end4]); + } + } +} + +fn const_index_and_subslice_err(s: &mut [i32]) { + if let [ref first, ref second, ..] = *s { + if let [_, ref mut tail @ ..] = *s { // { dg-error ".E0502." "" { target *-*-* } } + nop(&[first, second]); + nop_subslice(tail); + } + } +} + +fn const_index_and_subslice_from_end_err(s: &mut [i32]) { + if let [.., ref second, ref first] = *s { + if let [ref mut tail @ .., _] = *s { // { dg-error ".E0502." "" { target *-*-* } } + nop(&[first, second]); + nop_subslice(tail); + } + } +} + +fn subslices(s: &mut [i32]) { + if let [_, _, _, ref s1 @ ..] = *s { + if let [ref mut s2 @ .., _, _, _] = *s { // { dg-error ".E0502." "" { target *-*-* } } + nop_subslice(s1); + nop_subslice(s2); + } + } +} + +fn main() { + let mut v = [1,2,3,4]; + const_index_err(&mut v); + const_index_from_end_err(&mut v); + const_index_and_subslice_err(&mut v); + const_index_and_subslice_from_end_err(&mut v); + subslices(&mut v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-static-item-in-fn.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-static-item-in-fn.rs new file mode 100644 index 000000000000..0da5ed8ba489 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-static-item-in-fn.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(dead_code)] +// Regression test for issue #7740 + +// pretty-expanded FIXME #23616 + +pub fn main() { + static A: &'static char = &'A'; +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-storage-dead.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-storage-dead.rs new file mode 100644 index 000000000000..facaebba90e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-storage-dead.rs @@ -0,0 +1,25 @@ +fn ok() { + loop { + let _x = 1; + } +} + +fn also_ok() { + loop { + let _x = String::new(); + } +} + +fn fail() { + loop { + let x: i32; + let _ = x + 1; // { dg-error ".E0381." "" { target *-*-* } } + } +} + +fn main() { + ok(); + also_ok(); + fail(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-struct-update-with-dtor.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-struct-update-with-dtor.rs new file mode 100644 index 000000000000..b7406311cd13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-struct-update-with-dtor.rs @@ -0,0 +1,22 @@ +// Issue 4691: Ensure that functional-struct-update can only copy, not +// move, when the struct implements Drop. + +struct B; +struct S { a: isize, b: B } +impl Drop for S { fn drop(&mut self) { } } + +struct T { a: isize, mv: Box } +impl Drop for T { fn drop(&mut self) { } } + +fn f(s0:S) { + let _s2 = S{a: 2, ..s0}; +// { dg-error ".E0509." "" { target *-*-* } .-1 } +} + +fn g(s0:T) { + let _s2 = T{a: 2, ..s0}; +// { dg-error ".E0509." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-swap-mut-base-ptr.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-swap-mut-base-ptr.rs new file mode 100644 index 000000000000..8344262ce556 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-swap-mut-base-ptr.rs @@ -0,0 +1,23 @@ +// Test that attempt to swap `&mut` pointer while pointee is borrowed +// yields an error. +// +// Example from compiler/rustc_borrowck/borrowck/README.md + +use std::mem::swap; + + + +fn foo<'a>(mut t0: &'a mut isize, + mut t1: &'a mut isize) { + let p: &isize = &*t0; // Freezes `*t0` + swap(&mut t0, &mut t1); // { dg-error ".E0502." "" { target *-*-* } } + *t1 = 22; + p.use_ref(); +} + +fn main() { +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.rs new file mode 100644 index 000000000000..5c3615c9b5ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.rs @@ -0,0 +1,10 @@ +#![feature(thread_local)] + +#[thread_local] +static FOO: u8 = 3; + +fn assert_static(_t: &'static u8) {} +fn main() { + assert_static(&FOO); // { dg-error ".E0712." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-trait-lifetime.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-trait-lifetime.rs new file mode 100644 index 000000000000..eb0ed6cca808 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-trait-lifetime.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_imports)] +// This test verifies that casting from the same lifetime on a value +// to the same lifetime on a trait succeeds. See issue #10766. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +use std::marker; + +fn main() { + trait T { fn foo(&self) {} } + + fn f<'a, V: T>(v: &'a V) -> &'a dyn T { + v as &'a dyn T + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unary-move.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unary-move.rs new file mode 100644 index 000000000000..5060d981b7b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unary-move.rs @@ -0,0 +1,12 @@ +fn foo(x: Box) -> isize { + let y = &*x; + free(x); // { dg-error ".E0505." "" { target *-*-* } } + *y +} + +fn free(_x: Box) { +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unboxed-closures.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unboxed-closures.rs new file mode 100644 index 000000000000..8b4736f53321 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unboxed-closures.rs @@ -0,0 +1,18 @@ +fn a isize>(mut f: F) { + let g = &mut f; + f(1, 2); // { dg-error ".E0502." "" { target *-*-* } } + use_mut(g); +} +fn b isize>(f: F) { + f(1, 2); // { dg-error ".E0596." "" { target *-*-* } } +} + +fn c isize>(f: F) { + f(1, 2); + f(1, 2); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() {} + +fn use_mut(_: &mut T) { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-after-item.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-after-item.rs new file mode 100644 index 000000000000..53baa4614013 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-after-item.rs @@ -0,0 +1,6 @@ +fn main() { + let bar; + fn baz(_x: isize) { } + baz(bar); // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-field-access.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-field-access.rs new file mode 100644 index 000000000000..9ff4657318c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-field-access.rs @@ -0,0 +1,31 @@ +// Check that do not allow access to fields of uninitialized or moved +// structs. + +#[derive(Default)] +struct Point { + x: isize, + y: isize, +} + +#[derive(Default)] +struct Line { + origin: Point, + middle: Point, + target: Point, +} + +impl Line { fn consume(self) { } } + +fn main() { + let mut a: Point; + let _ = a.x + 1; // { dg-error ".E0381." "" { target *-*-* } } + + let mut line1 = Line::default(); + let _moved = line1.origin; + let _ = line1.origin.x + 1; // { dg-error ".E0382." "" { target *-*-* } } + + let mut line2 = Line::default(); + let _moved = (line2.origin, line2.middle); + line2.consume(); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-in-assignop.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-in-assignop.rs new file mode 100644 index 000000000000..48e343cc19c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-in-assignop.rs @@ -0,0 +1,35 @@ +// Tests that the use of uninitialized variable in assignment operator +// expression is detected. + +pub fn main() { + let x: isize; + x += 1; // { dg-error ".E0381." "" { target *-*-* } } + + let x: isize; + x -= 1; // { dg-error ".E0381." "" { target *-*-* } } + + let x: isize; + x *= 1; // { dg-error ".E0381." "" { target *-*-* } } + + let x: isize; + x /= 1; // { dg-error ".E0381." "" { target *-*-* } } + + let x: isize; + x %= 1; // { dg-error ".E0381." "" { target *-*-* } } + + let x: isize; + x ^= 1; // { dg-error ".E0381." "" { target *-*-* } } + + let x: isize; + x &= 1; // { dg-error ".E0381." "" { target *-*-* } } + + let x: isize; + x |= 1; // { dg-error ".E0381." "" { target *-*-* } } + + let x: isize; + x <<= 1; // { dg-error ".E0381." "" { target *-*-* } } + + let x: isize; + x >>= 1; // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-ref-chain.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-ref-chain.rs new file mode 100644 index 000000000000..1eda29f8a90c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit-ref-chain.rs @@ -0,0 +1,34 @@ +struct S { + x: X, + y: Y, +} + +fn main() { + let x: &&Box; + let _y = &**x; // { dg-error ".E0381." "" { target *-*-* } } + + let x: &&S; + let _y = &**x; // { dg-error ".E0381." "" { target *-*-* } } + + let x: &&i32; + let _y = &**x; // { dg-error ".E0381." "" { target *-*-* } } + + + let mut a: S; + a.x = 0; // { dg-error ".E0381." "" { target *-*-* } } + let _b = &a.x; + + let mut a: S<&&i32, &&i32>; + a.x = &&0; // { dg-error ".E0381." "" { target *-*-* } } + let _b = &**a.x; + + + let mut a: S; + a.x = 0; // { dg-error ".E0381." "" { target *-*-* } } + let _b = &a.y; + + let mut a: S<&&i32, &&i32>; + a.x = &&0; // { dg-error ".E0381." "" { target *-*-* } } + let _b = &**a.y; +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit.rs new file mode 100644 index 000000000000..f5191f803a46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uninit.rs @@ -0,0 +1,7 @@ +fn foo(x: isize) { println!("{}", x); } + +fn main() { + let x: isize; + foo(x); // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-borrow-nested.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-borrow-nested.rs new file mode 100644 index 000000000000..b90266139242 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-borrow-nested.rs @@ -0,0 +1,32 @@ +#[derive(Clone, Copy)] +struct S { + a: u8, + b: u16, +} + +#[derive(Clone, Copy)] +union U { + s: S, + c: u32, +} + +fn main() { + unsafe { + { + let mut u = U { s: S { a: 0, b: 1 } }; + let ra = &mut u.s.a; + let b = u.s.b; // OK + ra.use_mut(); + } + { + let mut u = U { s: S { a: 0, b: 1 } }; + let ra = &mut u.s.a; + let b = u.c; // { dg-error ".E0503." "" { target *-*-* } } + ra.use_mut(); + } + } +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-borrow.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-borrow.rs new file mode 100644 index 000000000000..5e58e26f7a30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-borrow.rs @@ -0,0 +1,99 @@ +// ignore-tidy-linelength + +#[derive(Clone, Copy)] +union U { + a: u8, + b: u64, +} + +fn main() { + unsafe { + let mut u = U { b: 0 }; + // Imm borrow, same field + { + let ra = &u.a; + let ra2 = &u.a; // OK + drop(ra); + } + { + let ra = &u.a; + let a = u.a; // OK + drop(ra); + } + { + let ra = &u.a; + let rma = &mut u.a; // { dg-error ".E0502." "" { target *-*-* } } + drop(ra); + } + { + let ra = &u.a; + u.a = 1; // { dg-error ".E0506." "" { target *-*-* } } + drop(ra); + } + // Imm borrow, other field + { + let ra = &u.a; + let rb = &u.b; // OK + drop(ra); + } + { + let ra = &u.a; + let b = u.b; // OK + drop(ra); + } + { + let ra = &u.a; + let rmb = &mut u.b; // { dg-error ".E0502." "" { target *-*-* } } + drop(ra); + } + { + let ra = &u.a; + u.b = 1; // { dg-error ".E0506." "" { target *-*-* } } + drop(ra); + } + // Mut borrow, same field + { + let rma = &mut u.a; + let ra = &u.a; // { dg-error ".E0502." "" { target *-*-* } } + drop(rma); + } + { + let ra = &mut u.a; + let a = u.a; // { dg-error ".E0503." "" { target *-*-* } } + drop(ra); + } + { + let rma = &mut u.a; + let rma2 = &mut u.a; // { dg-error ".E0499." "" { target *-*-* } } + drop(rma); + } + { + let rma = &mut u.a; + u.a = 1; // { dg-error ".E0506." "" { target *-*-* } } + drop(rma); + } + // Mut borrow, other field + { + let rma = &mut u.a; + let rb = &u.b; // { dg-error ".E0502." "" { target *-*-* } } + drop(rma); + } + { + let ra = &mut u.a; + let b = u.b; // { dg-error ".E0503." "" { target *-*-* } } + + drop(ra); + } + { + let rma = &mut u.a; + let rmb2 = &mut u.b; // { dg-error ".E0499." "" { target *-*-* } } + drop(rma); + } + { + let rma = &mut u.a; + u.b = 1; // { dg-error ".E0506." "" { target *-*-* } } + drop(rma); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-move-assign.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-move-assign.rs new file mode 100644 index 000000000000..81c7f658d089 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-move-assign.rs @@ -0,0 +1,33 @@ +#![feature(untagged_unions)] + +// Non-copy +struct A; +struct B; + +union U { + a: A, + b: B, +} + +fn main() { + unsafe { + { + let mut u = U { a: A }; + let a = u.a; + let a = u.a; // { dg-error ".E0382." "" { target *-*-* } } + } + { + let mut u = U { a: A }; + let a = u.a; + u.a = A; + let a = u.a; // OK + } + { + let mut u = U { a: A }; + let a = u.a; + u.b = B; + let a = u.a; // OK + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-move.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-move.rs new file mode 100644 index 000000000000..f3e837cbc381 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-move.rs @@ -0,0 +1,87 @@ +#![feature(untagged_unions)] + +#[derive(Clone, Copy)] +struct Copy; +struct NonCopy; + +union Unn { + n1: NonCopy, + n2: NonCopy, +} +union Ucc { + c1: Copy, + c2: Copy, +} +union Ucn { + c: Copy, + n: NonCopy, +} + +fn main() { + unsafe { + // 2 NonCopy + { + let mut u = Unn { n1: NonCopy }; + let a = u.n1; + let a = u.n1; // { dg-error ".E0382." "" { target *-*-* } } + } + { + let mut u = Unn { n1: NonCopy }; + let a = u.n1; + let a = u; // { dg-error ".E0382." "" { target *-*-* } } + } + { + let mut u = Unn { n1: NonCopy }; + let a = u.n1; + let a = u.n2; // { dg-error ".E0382." "" { target *-*-* } } + } + // 2 Copy + { + let mut u = Ucc { c1: Copy }; + let a = u.c1; + let a = u.c1; // OK + } + { + let mut u = Ucc { c1: Copy }; + let a = u.c1; + let a = u; // OK + } + { + let mut u = Ucc { c1: Copy }; + let a = u.c1; + let a = u.c2; // OK + } + // 1 Copy, 1 NonCopy + { + let mut u = Ucn { c: Copy }; + let a = u.c; + let a = u.c; // OK + } + { + let mut u = Ucn { c: Copy }; + let a = u.n; + let a = u.n; // { dg-error ".E0382." "" { target *-*-* } } + } + { + let mut u = Ucn { c: Copy }; + let a = u.n; + let a = u.c; // { dg-error ".E0382." "" { target *-*-* } } + } + { + let mut u = Ucn { c: Copy }; + let a = u.c; + let a = u.n; // OK + } + { + let mut u = Ucn { c: Copy }; + let a = u.c; + let a = u; // OK + } + { + let mut u = Ucn { c: Copy }; + let a = u.n; + let a = u; // { dg-error ".E0382." "" { target *-*-* } } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-uninitialized.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-uninitialized.rs new file mode 100644 index 000000000000..5bbf6c1a1df2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-union-uninitialized.rs @@ -0,0 +1,19 @@ +struct S { + a: u8, +} + +union U { + a: u8, +} + +fn main() { + unsafe { + let mut s: S; + let mut u: U; + s.a = 0; // { dg-error ".E0381." "" { target *-*-* } } + u.a = 0; // { dg-error ".E0381." "" { target *-*-* } } + let sa = s.a; + let ua = u.a; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uniq-via-lend.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uniq-via-lend.rs new file mode 100644 index 000000000000..8cbf8c3a981d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uniq-via-lend.rs @@ -0,0 +1,62 @@ +#![feature(box_syntax)] + + + +fn borrow(_v: &isize) {} + +fn local() { + let mut v: Box<_> = box 3; + borrow(&*v); +} + +fn local_rec() { + struct F { f: Box } + let mut v = F {f: box 3}; + borrow(&*v.f); +} + +fn local_recs() { + struct F { f: G } + struct G { g: H } + struct H { h: Box } + let mut v = F {f: G {g: H {h: box 3}}}; + borrow(&*v.f.g.h); +} + +fn aliased_imm() { + let mut v: Box<_> = box 3; + let w = &v; + borrow(&*v); + w.use_ref(); +} + +fn aliased_mut() { + let mut v: Box<_> = box 3; + let w = &mut v; + borrow(&*v); // { dg-error ".E0502." "" { target *-*-* } } + w.use_mut(); +} + +fn aliased_other() { + let mut v: Box<_> = box 3; + let mut w: Box<_> = box 4; + let x = &mut w; + borrow(&*v); + x.use_mut(); +} + +fn aliased_other_reassign() { + let mut v: Box<_> = box 3; + let mut w: Box<_> = box 4; + let mut x = &mut w; + x = &mut v; + borrow(&*v); // { dg-error ".E0502." "" { target *-*-* } } + x.use_mut(); +} + +fn main() { +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uniq-via-ref.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uniq-via-ref.rs new file mode 100644 index 000000000000..cd90ab439ef1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-uniq-via-ref.rs @@ -0,0 +1,50 @@ +// run-pass +#![allow(dead_code)] + +// pretty-expanded FIXME #23616 + +struct Rec { + f: Box, +} + +struct Outer { + f: Inner +} + +struct Inner { + g: Innermost +} + +struct Innermost { + h: Box, +} + +fn borrow(_v: &isize) {} + +fn box_mut(v: &mut Box) { + borrow(&**v); // OK: &mut -> &imm +} + +fn box_mut_rec(v: &mut Rec) { + borrow(&*v.f); // OK: &mut -> &imm +} + +fn box_mut_recs(v: &mut Outer) { + borrow(&*v.f.g.h); // OK: &mut -> &imm +} + +fn box_imm(v: &Box) { + borrow(&**v); // OK +} + +fn box_imm_rec(v: &Rec) { + borrow(&*v.f); // OK +} + +fn box_imm_recs(v: &Outer) { + borrow(&*v.f.g.h); // OK +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-univariant-enum.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-univariant-enum.rs new file mode 100644 index 000000000000..812b4c9139bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-univariant-enum.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(non_camel_case_types)] + +use std::cell::Cell; + +#[derive(Copy, Clone)] +enum newtype { + newvar(isize) +} + +pub fn main() { + + // Test that borrowck treats enums with a single variant + // specially. + + let x = &Cell::new(5); + let y = &Cell::new(newtype::newvar(3)); + let z = match y.get() { + newtype::newvar(b) => { + x.set(x.get() + 1); + x.get() * b + } + }; + assert_eq!(z, 18); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs new file mode 100644 index 000000000000..f4cf38a3f00d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unsafe-static-mutable-borrows.rs @@ -0,0 +1,21 @@ +// run-pass + +// Test file taken from issue 45129 (https://github.com/rust-lang/rust/issues/45129) + +struct Foo { x: [usize; 2] } + +static mut SFOO: Foo = Foo { x: [23, 32] }; + +impl Foo { + fn x(&mut self) -> &mut usize { &mut self.x[0] } +} + +fn main() { + unsafe { + let sfoo: *mut Foo = &mut SFOO; + let x = (*sfoo).x(); + (*sfoo).x[1] += 1; + *x += 1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unused-mut-locals.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unused-mut-locals.rs new file mode 100644 index 000000000000..41106e016afe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-unused-mut-locals.rs @@ -0,0 +1,47 @@ +// run-pass +#![deny(unused_mut)] + +#[derive(Debug)] +struct A {} + +fn init_a() -> A { + A {} +} + +#[derive(Debug)] +struct B<'a> { + ed: &'a mut A, +} + +fn init_b<'a>(ed: &'a mut A) -> B<'a> { + B { ed } +} + +#[derive(Debug)] +struct C<'a> { + pd: &'a mut B<'a>, +} + +fn init_c<'a>(pd: &'a mut B<'a>) -> C<'a> { + C { pd } +} + +#[derive(Debug)] +struct D<'a> { + sd: &'a mut C<'a>, +} + +fn init_d<'a>(sd: &'a mut C<'a>) -> D<'a> { + D { sd } +} + +fn main() { + let mut a = init_a(); + let mut b = init_b(&mut a); + let mut c = init_c(&mut b); + + let d = init_d(&mut c); + + println!("{:?}", d) +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-in-index-lvalue.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-in-index-lvalue.rs new file mode 100644 index 000000000000..596f0c363534 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-in-index-lvalue.rs @@ -0,0 +1,10 @@ +fn test() { + let w: &mut [isize]; + w[5] = 0; // { dg-error ".E0381." "" { target *-*-* } } + + let mut w: &mut [isize]; + w[5] = 0; // { dg-error ".E0381." "" { target *-*-* } } +} + +fn main() { test(); } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-mut-borrow-rpass.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-mut-borrow-rpass.rs new file mode 100644 index 000000000000..4449d8a16e15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-mut-borrow-rpass.rs @@ -0,0 +1,52 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +struct A { a: isize, b: Box } + +fn field_copy_after_field_borrow() { + let mut x = A { a: 1, b: box 2 }; + let p = &mut x.b; + drop(x.a); + **p = 3; +} + +fn fu_field_copy_after_field_borrow() { + let mut x = A { a: 1, b: box 2 }; + let p = &mut x.b; + let y = A { b: box 3, .. x }; + drop(y); + **p = 4; +} + +fn field_deref_after_field_borrow() { + let mut x = A { a: 1, b: box 2 }; + let p = &mut x.a; + drop(*x.b); + *p = 3; +} + +fn field_move_after_field_borrow() { + let mut x = A { a: 1, b: box 2 }; + let p = &mut x.a; + drop(x.b); + *p = 3; +} + +fn fu_field_move_after_field_borrow() { + let mut x = A { a: 1, b: box 2 }; + let p = &mut x.a; + let y = A { a: 3, .. x }; + drop(y); + *p = 4; +} + +fn main() { + field_copy_after_field_borrow(); + fu_field_copy_after_field_borrow(); + field_deref_after_field_borrow(); + field_move_after_field_borrow(); + fu_field_move_after_field_borrow(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-mut-borrow.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-mut-borrow.rs new file mode 100644 index 000000000000..ea4aafb5bd86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-mut-borrow.rs @@ -0,0 +1,87 @@ +#![feature(box_syntax)] + +#[derive(Copy, Clone)] +struct A { a: isize, b: isize } + +struct B { a: isize, b: Box } + +fn var_copy_after_var_borrow() { + let mut x: isize = 1; + let p = &mut x; + drop(x); // { dg-error ".E0503." "" { target *-*-* } } + *p = 2; +} + +fn var_copy_after_field_borrow() { + let mut x = A { a: 1, b: 2 }; + let p = &mut x.a; + drop(x); // { dg-error ".E0503." "" { target *-*-* } } + *p = 3; +} + +fn field_copy_after_var_borrow() { + let mut x = A { a: 1, b: 2 }; + let p = &mut x; + drop(x.a); // { dg-error ".E0503." "" { target *-*-* } } + p.a = 3; +} + +fn field_copy_after_field_borrow() { + let mut x = A { a: 1, b: 2 }; + let p = &mut x.a; + drop(x.a); // { dg-error ".E0503." "" { target *-*-* } } + *p = 3; +} + +fn fu_field_copy_after_var_borrow() { + let mut x = A { a: 1, b: 2 }; + let p = &mut x; + let y = A { b: 3, .. x }; // { dg-error ".E0503." "" { target *-*-* } } + drop(y); + p.a = 4; +} + +fn fu_field_copy_after_field_borrow() { + let mut x = A { a: 1, b: 2 }; + let p = &mut x.a; + let y = A { b: 3, .. x }; // { dg-error ".E0503." "" { target *-*-* } } + drop(y); + *p = 4; +} + +fn var_deref_after_var_borrow() { + let mut x: Box = box 1; + let p = &mut x; + drop(*x); // { dg-error ".E0503." "" { target *-*-* } } + **p = 2; +} + +fn field_deref_after_var_borrow() { + let mut x = B { a: 1, b: box 2 }; + let p = &mut x; + drop(*x.b); // { dg-error ".E0503." "" { target *-*-* } } + p.a = 3; +} + +fn field_deref_after_field_borrow() { + let mut x = B { a: 1, b: box 2 }; + let p = &mut x.b; + drop(*x.b); // { dg-error ".E0503." "" { target *-*-* } } + **p = 3; +} + +fn main() { + var_copy_after_var_borrow(); + var_copy_after_field_borrow(); + + field_copy_after_var_borrow(); + field_copy_after_field_borrow(); + + fu_field_copy_after_var_borrow(); + fu_field_copy_after_field_borrow(); + + var_deref_after_var_borrow(); + field_deref_after_var_borrow(); + field_deref_after_field_borrow(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.rs new file mode 100644 index 000000000000..8b39128d6e2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.rs @@ -0,0 +1,11 @@ +// Variation on `borrowck-use-uninitialized-in-cast` in which we do a +// trait cast from an uninitialized source. Issue #20791. + +trait Foo { fn dummy(&self) { } } +impl Foo for i32 { } + +fn main() { + let x: &i32; + let y = x as *const dyn Foo; // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-uninitialized-in-cast.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-uninitialized-in-cast.rs new file mode 100644 index 000000000000..d32a7751aa87 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-use-uninitialized-in-cast.rs @@ -0,0 +1,9 @@ +// Check that we detect unused values that are cast to other things. +// The problem was specified to casting to `*`, as creating unsafe +// pointers was not being fully checked. Issue #20791. + +fn main() { + let x: &i32; + let y = x as *const i32; // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-element-loan.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-element-loan.rs new file mode 100644 index 000000000000..b2ede6dfa4e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-element-loan.rs @@ -0,0 +1,32 @@ +fn a<'a>() -> &'a [isize] { + let vec = vec![1, 2, 3, 4]; + let vec: &[isize] = &vec; + let tail = match vec { + &[_, ref tail @ ..] => tail, + _ => panic!("a") + }; + tail // { dg-error ".E0515." "" { target *-*-* } } +} + +fn b<'a>() -> &'a [isize] { + let vec = vec![1, 2, 3, 4]; + let vec: &[isize] = &vec; + let init = match vec { + &[ref init @ .., _] => init, + _ => panic!("b") + }; + init // { dg-error ".E0515." "" { target *-*-* } } +} + +fn c<'a>() -> &'a [isize] { + let vec = vec![1, 2, 3, 4]; + let vec: &[isize] = &vec; + let slice = match vec { + &[_, ref slice @ .., _] => slice, + _ => panic!("c") + }; + slice // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs new file mode 100644 index 000000000000..c0930520e43f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs @@ -0,0 +1,13 @@ +fn a() { + let mut v = vec![1, 2, 3]; + let vb: &mut [isize] = &mut v; + match vb { + &mut [_a, ref tail @ ..] => { + v.push(tail[0] + tail[1]); // { dg-error ".E0499." "" { target *-*-* } } + } + _ => {} + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-move-tail.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-move-tail.rs new file mode 100644 index 000000000000..5a19f3ebb480 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-move-tail.rs @@ -0,0 +1,12 @@ +fn main() { + let mut a = [1, 2, 3, 4]; + let t = match a { + [1, 2, ref tail @ ..] => tail, + _ => unreachable!() + }; + println!("t[0]: {}", t[0]); + a[2] = 0; // { dg-error ".E0506." "" { target *-*-* } } + println!("t[0]: {}", t[0]); + t[0]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-nesting.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-nesting.rs new file mode 100644 index 000000000000..d11f8367b0d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-nesting.rs @@ -0,0 +1,95 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] + +fn a() { + let mut vec = [box 1, box 2, box 3]; + match vec { + [box ref _a, _, _] => { +// { dg-note "" "" { target *-*-* } .-1 } + vec[0] = box 4; // { dg-error ".E0506." "" { target *-*-* } } +// { dg-note ".E0506." "" { target *-*-* } .-1 } + _a.use_ref(); +// { dg-note "" "" { target *-*-* } .-1 } + } + } +} + +fn b() { + let mut vec = vec![box 1, box 2, box 3]; + let vec: &mut [Box] = &mut vec; + match vec { + &mut [ref _b @ ..] => { +// { dg-error "" "" { target *-*-* } .-1 } + vec[0] = box 4; // { dg-error ".E0506." "" { target *-*-* } } +// { dg-note ".E0506." "" { target *-*-* } .-1 } + _b.use_ref(); +// { dg-note "" "" { target *-*-* } .-1 } + } + } +} + +fn c() { + let mut vec = vec![box 1, box 2, box 3]; + let vec: &mut [Box] = &mut vec; + match vec { +// { dg-error ".E0508." "" { target *-*-* } .-1 } +// { dg-note ".E0508." "" { target *-*-* } .-2 } + &mut [_a, +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } + .. + ] => { + } + _ => {} + } + let a = vec[0]; // { dg-error ".E0508." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +// { help "" "" { target *-*-* } .-4 } +} + +fn d() { + let mut vec = vec![box 1, box 2, box 3]; + let vec: &mut [Box] = &mut vec; + match vec { +// { dg-error ".E0508." "" { target *-*-* } .-1 } +// { dg-note ".E0508." "" { target *-*-* } .-2 } + &mut [ +// { help "" "" { target *-*-* } .-1 } + _b] => {} +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + _ => {} + } + let a = vec[0]; // { dg-error ".E0508." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +// { help "" "" { target *-*-* } .-4 } +} + +fn e() { + let mut vec = vec![box 1, box 2, box 3]; + let vec: &mut [Box] = &mut vec; + match vec { +// { dg-error ".E0508." "" { target *-*-* } .-1 } +// { dg-note ".E0508." "" { target *-*-* } .-2 } +// { dg-note ".E0508." "" { target *-*-* } .-3 } + &mut [_a, _b, _c] => {} +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +// { help "" "" { target *-*-* } .-4 } + _ => {} + } + let a = vec[0]; // { dg-error ".E0508." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +// { help "" "" { target *-*-* } .-4 } +} + +fn main() {} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs new file mode 100644 index 000000000000..697afcc537e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs @@ -0,0 +1,15 @@ +fn a<'a>() -> &'a isize { + let vec = vec![1, 2, 3, 4]; + let vec: &[isize] = &vec; + let tail = match vec { + &[_a, ref tail @ ..] => &tail[0], + _ => panic!("foo") + }; + tail // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() { + let fifth = a(); + println!("{}", *fifth); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-while-break.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-while-break.rs new file mode 100644 index 000000000000..8173c31aa5ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-while-break.rs @@ -0,0 +1,13 @@ +fn test(cond: bool) { + let v; + while cond { + v = 3; + break; + } + println!("{}", v); // { dg-error ".E0381." "" { target *-*-* } } +} + +fn main() { + test(true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-while-cond.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-while-cond.rs new file mode 100644 index 000000000000..594ddbc00268 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-while-cond.rs @@ -0,0 +1,5 @@ +fn main() { + let x: bool; + while x { } // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-while.rs b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-while.rs new file mode 100644 index 000000000000..76ed645ec707 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/borrowck-while.rs @@ -0,0 +1,8 @@ +fn f() -> isize { + let mut x: isize; + while 1 == 1 { x = 10; } + return x; // { dg-error ".E0381." "" { target *-*-* } } +} + +fn main() { f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/disallow-possibly-uninitialized.rs b/gcc/testsuite/rust/rustc/ui/borrowck/disallow-possibly-uninitialized.rs new file mode 100644 index 000000000000..12c1e87d1ee7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/disallow-possibly-uninitialized.rs @@ -0,0 +1,23 @@ +// Test that we don't allow partial initialization. +// This may be relaxed in the future (see #54987). + +fn main() { + let mut t: (u64, u64); + t.0 = 1; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + t.1 = 1; + + let mut t: (u64, u64); + t.1 = 1; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + t.0 = 1; + + let mut t: (u64, u64); + t.0 = 1; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + + let mut t: (u64,); + t.0 = 1; +// { dg-error ".E0381." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/immutable-arg.rs b/gcc/testsuite/rust/rustc/ui/borrowck/immutable-arg.rs new file mode 100644 index 000000000000..3dd60b9d6022 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/immutable-arg.rs @@ -0,0 +1,7 @@ +fn foo(_x: u32) { + _x = 4; +// { dg-error ".E0384." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/index-mut-help-with-impl.rs b/gcc/testsuite/rust/rustc/ui/borrowck/index-mut-help-with-impl.rs new file mode 100644 index 000000000000..e4bb17cc787c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/index-mut-help-with-impl.rs @@ -0,0 +1,11 @@ +// When mutably indexing a type that implements `Index` and `IndexMut` but +// `Index::index` is being used specifically, the normal special help message +// should not mention a missing `IndexMut` impl. + +fn main() { + use std::ops::Index; + + let v = String::from("dinosaur"); + Index::index(&v, 1..2).make_ascii_uppercase(); // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/index-mut-help.rs b/gcc/testsuite/rust/rustc/ui/borrowck/index-mut-help.rs new file mode 100644 index 000000000000..8e49c125560f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/index-mut-help.rs @@ -0,0 +1,15 @@ +// When mutably indexing a type that implements `Index` but not `IndexMut`, a +// special 'help' message is added to the output. + + +fn main() { + use std::collections::HashMap; + + let mut map = HashMap::new(); + map.insert("peter", "23".to_string()); + + map["peter"].clear(); // { dg-error ".E0596." "" { target *-*-* } } + map["peter"] = "0".to_string(); // { dg-error ".E0594." "" { target *-*-* } } + let _ = &mut map["peter"]; // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-10876.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-10876.rs new file mode 100644 index 000000000000..c3e9833ebd7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-10876.rs @@ -0,0 +1,18 @@ +// check-pass + +enum Nat { + S(Box), + Z +} +fn test(x: &mut Nat) { + let mut p = &mut *x; + loop { + match p { + &mut Nat::Z => break, + &mut Nat::S(ref mut n) => p = &mut *n + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-27282-mutation-in-guard.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-27282-mutation-in-guard.rs new file mode 100644 index 000000000000..3a0b987d3f27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-27282-mutation-in-guard.rs @@ -0,0 +1,14 @@ +fn main() { + match Some(&4) { + None => {}, + ref mut foo + if { + (|| { let bar = foo; bar.take() })(); +// { dg-error ".E0507." "" { target *-*-* } .-1 } + false + } => {}, + Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."), + _ => println!("Here is some supposedly unreachable code."), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-31287-drop-in-guard.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-31287-drop-in-guard.rs new file mode 100644 index 000000000000..26ce943218b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-31287-drop-in-guard.rs @@ -0,0 +1,9 @@ +fn main() { + let a = Some("...".to_owned()); + let b = match a { + Some(_) if { drop(a); false } => None, + x => x, // { dg-error ".E0382." "" { target *-*-* } } + }; + println!("{:?}", b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-41962.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-41962.rs new file mode 100644 index 000000000000..0e313c7c74e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-41962.rs @@ -0,0 +1,10 @@ +pub fn main(){ + let maybe = Some(vec![true, true]); + + loop { + if let Some(thing) = maybe { + } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-45983.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-45983.rs new file mode 100644 index 000000000000..f747f7611140 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-45983.rs @@ -0,0 +1,13 @@ +// As documented in Issue #45983, this test is evaluating the quality +// of our diagnostics on erroneous code using higher-ranked closures. + +fn give_any FnOnce(&'r ())>(f: F) { + f(&()); +} + +fn main() { + let mut x = None; + give_any(|y| x = Some(y)); +// { dg-error ".E0521." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-47215-ice-from-drop-elab.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-47215-ice-from-drop-elab.rs new file mode 100644 index 000000000000..2019b98240f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-47215-ice-from-drop-elab.rs @@ -0,0 +1,21 @@ +// rust-lang/rust#47215: at one time, the compiler categorized +// thread-local statics as a temporary rvalue, as a way to enforce +// that they are only valid for a given lifetime. +// +// The problem with this is that you cannot move out of static items, +// but you *can* move temporary rvalues. I.e., the categorization +// above only solves half of the problem presented by thread-local +// statics. + +#![feature(thread_local)] + +#[thread_local] +static mut X: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::AtomicUsize::new(0); + +fn main() { + unsafe { + let mut x = X; // { dg-error ".E0507." "" { target *-*-* } } + let _y = x.get_mut(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-51117.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-51117.rs new file mode 100644 index 000000000000..19729282b765 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-51117.rs @@ -0,0 +1,16 @@ +// Regression test for #51117 in borrowck interaction with match +// default bindings. The borrow of `*bar` created by `baz` was failing +// to register as a conflict with `bar.take()`. + +fn main() { + let mut foo = Some("foo".to_string()); + let bar = &mut foo; + match bar { + Some(baz) => { + bar.take(); // { dg-error ".E0499." "" { target *-*-* } } + drop(baz); + }, + None => unreachable!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs new file mode 100644 index 000000000000..e2f756ffc905 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs @@ -0,0 +1,22 @@ +// We used to ICE if you had a single match arm with multiple +// candidate patterns with `ref mut` identifiers used in the arm's +// guard. +// +// Also, this test expands on the original bug's example by actually +// trying to double check that we are matching against the right part +// of the input data based on which candidate pattern actually fired. + +// run-pass + +fn foo(x: &mut Result<(u32, u32), (u32, u32)>) -> u32 { + match *x { + Ok((ref mut v, _)) | Err((_, ref mut v)) if *v > 0 => { *v } + _ => { 0 } + } +} + +fn main() { + assert_eq!(foo(&mut Ok((3, 4))), 3); + assert_eq!(foo(&mut Err((3, 4))), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-51415.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-51415.rs new file mode 100644 index 000000000000..76315f29c42f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-51415.rs @@ -0,0 +1,12 @@ +// Regression test for #51415: match default bindings were failing to +// see the "move out" implied by `&s` below. + +fn main() { + let a = vec![String::from("a")]; + let opt = a.iter().enumerate().find(|(_, &s)| { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + *s == String::from("d") + }).map(|(i, _)| i); + println!("{:?}", opt); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-52713-bug.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-52713-bug.rs new file mode 100644 index 000000000000..7cc7b3a4224c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-52713-bug.rs @@ -0,0 +1,18 @@ +// Regression test for a bug in #52713: this was an optimization for +// computing liveness that wound up accidentally causing the program +// below to be accepted. + +fn foo<'a>(x: &'a mut u32) -> u32 { + let mut x = 22; + let y = &x; + if false { + return x; + } + + x += 1; // { dg-error ".E0506." "" { target *-*-* } } + println!("{}", y); + return 0; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-52967-edition-2018-needs-two-phase-borrows.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-52967-edition-2018-needs-two-phase-borrows.rs new file mode 100644 index 000000000000..4454f8d7d735 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-52967-edition-2018-needs-two-phase-borrows.rs @@ -0,0 +1,22 @@ +// This is a regression test for #52967, where we discovered that in +// the initial deployment of NLL for the 2018 edition, I forgot to +// turn on two-phase-borrows in addition to `-Z borrowck=migrate`. + +// revisions: edition2015 edition2018 +//[edition2018]edition:2018 + +// run-pass + +fn the_bug() { + let mut stuff = ("left", "right"); + match stuff { + (ref mut left, _) if *left == "left" => { *left = "new left"; } + _ => {} + } + assert_eq!(stuff, ("new left", "right")); +} + +fn main() { + the_bug(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.rs new file mode 100644 index 000000000000..0cb21445e42f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.rs @@ -0,0 +1,8 @@ +fn main() { + let f = move || {}; + let _action = move || { + || f() // The `nested` closure +// { dg-error "" "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs new file mode 100644 index 000000000000..3c0bfb6ff615 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs @@ -0,0 +1,34 @@ +#![warn(unused)] +#[derive(Debug)] +struct S(i32); + +type Tuple = (S, i32); +struct Tpair(S, i32); +struct Spair { x: S, y: i32 } + +fn main() { + { + let mut t: Tuple; + t.0 = S(1); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + t.1 = 2; + println!("{:?} {:?}", t.0, t.1); + } + + { + let mut u: Tpair; + u.0 = S(1); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + u.1 = 2; + println!("{:?} {:?}", u.0, u.1); + } + + { + let mut v: Spair; + v.x = S(1); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + v.y = 2; + println!("{:?} {:?}", v.x, v.y); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs new file mode 100644 index 000000000000..6961ce69d57c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-of-moved-out-with-mut.rs @@ -0,0 +1,37 @@ +#![warn(unused)] +#[derive(Debug)] +struct S(i32); + +type Tuple = (S, i32); +struct Tpair(S, i32); +struct Spair { x: S, y: i32 } + +fn main() { + { + let mut t: Tuple = (S(0), 0); + drop(t); + t.0 = S(1); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + t.1 = 2; + println!("{:?} {:?}", t.0, t.1); + } + + { + let mut u: Tpair = Tpair(S(0), 0); + drop(u); + u.0 = S(1); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + u.1 = 2; + println!("{:?} {:?}", u.0, u.1); + } + + { + let mut v: Spair = Spair { x: S(0), y: 0 }; + drop(v); + v.x = S(1); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + v.y = 2; + println!("{:?} {:?}", v.x, v.y); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-of-moved-out.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-of-moved-out.rs new file mode 100644 index 000000000000..8ca439d2ba32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-of-moved-out.rs @@ -0,0 +1,43 @@ +#![warn(unused)] +#[derive(Debug)] +struct S(i32); + +type Tuple = (S, i32); +struct Tpair(S, i32); +struct Spair { x: S, y: i32 } + +fn main() { + { + let t: Tuple = (S(0), 0); + drop(t); + t.0 = S(1); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + t.1 = 2; +// { dg-error ".E0594." "" { target *-*-* } .-1 } + println!("{:?} {:?}", t.0, t.1); + } + + { + let u: Tpair = Tpair(S(0), 0); + drop(u); + u.0 = S(1); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + u.1 = 2; +// { dg-error ".E0594." "" { target *-*-* } .-1 } + println!("{:?} {:?}", u.0, u.1); + } + + { + let v: Spair = Spair { x: S(0), y: 0 }; + drop(v); + v.x = S(1); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + v.y = 2; +// { dg-error ".E0594." "" { target *-*-* } .-1 } + println!("{:?} {:?}", v.x, v.y); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-of-never-init.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-of-never-init.rs new file mode 100644 index 000000000000..5d0a13229863 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-54499-field-mutation-of-never-init.rs @@ -0,0 +1,34 @@ +#![warn(unused)] +#[derive(Debug)] +struct S(i32); + +type Tuple = (S, i32); +struct Tpair(S, i32); +struct Spair { x: S, y: i32 } + +fn main() { + { + let t: Tuple; + t.0 = S(1); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + t.1 = 2; + println!("{:?} {:?}", t.0, t.1); + } + + { + let u: Tpair; + u.0 = S(1); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + u.1 = 2; + println!("{:?} {:?}", u.0, u.1); + } + + { + let v: Spair; + v.x = S(1); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + v.y = 2; + println!("{:?} {:?}", v.x, v.y); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs new file mode 100644 index 000000000000..943e0614614b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs @@ -0,0 +1,21 @@ +#![allow(dead_code)] + +#[derive(Debug)] +struct Value; +impl Value { + fn as_array(&self) -> Option<&Vec> { + None + } +} + +fn foo(val: Value) { + let _reviewers_original: Vec = match val.as_array() { + Some(array) => { + *array // { dg-error ".E0507." "" { target *-*-* } } + } + None => vec![] + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs new file mode 100644 index 000000000000..c2f2453991b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs @@ -0,0 +1,72 @@ +// rust-lang/rust#55492: errors detected during MIR-borrowck's +// analysis of a closure body may only be caught when AST-borrowck +// looks at some parent. + +// revisions: migrate nll + +// Since we are testing nll (and migration) explicitly as a separate +// revisions, don't worry about the --compare-mode=nll on this test. + +// ignore-compare-mode-nll + +//[nll]compile-flags: -Z borrowck=mir + + +// transcribed from borrowck-closures-unique.rs +mod borrowck_closures_unique { + pub fn e(x: &'static mut isize) { + static mut Y: isize = 3; + let mut c1 = |y: &'static mut isize| x = y; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + unsafe { c1(&mut Y); } + } +} + +mod borrowck_closures_unique_grandparent { + pub fn ee(x: &'static mut isize) { + static mut Z: isize = 3; + let mut c1 = |z: &'static mut isize| { + let mut c2 = |y: &'static mut isize| x = y; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + c2(z); + }; + unsafe { c1(&mut Z); } + } +} + +// adapted from mutability_errors.rs +mod mutability_errors { + pub fn capture_assign_whole(x: (i32,)) { + || { x = (1,); }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + } + pub fn capture_assign_part(x: (i32,)) { + || { x.0 = 1; }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + } + pub fn capture_reborrow_whole(x: (i32,)) { + || { &mut x; }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + } + pub fn capture_reborrow_part(x: (i32,)) { + || { &mut x.0; }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + } +} + +fn main() { + static mut X: isize = 2; + unsafe { borrowck_closures_unique::e(&mut X); } + + mutability_errors::capture_assign_whole((1000,)); + mutability_errors::capture_assign_part((2000,)); + mutability_errors::capture_reborrow_whole((3000,)); + mutability_errors::capture_reborrow_part((4000,)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs new file mode 100644 index 000000000000..95c967ec673f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs @@ -0,0 +1,32 @@ +// check-pass + +// rust-lang/rust#55552: The strategy pnkfelix landed in PR #55274 +// (for ensuring that NLL respects user-provided lifetime annotations) +// did not handle the case where the ascribed type has some expliit +// wildcards (`_`) mixed in, and it caused an internal compiler error +// (ICE). +// +// This test is just checking that we do not ICE when such things +// occur. + +struct X; +struct Y; +struct Z; + +struct Pair { x: X, y: Y } + +pub fn join(oper_a: A, oper_b: B) -> (RA, RB) +where A: FnOnce() -> RA + Send, + B: FnOnce() -> RB + Send, + RA: Send, + RB: Send +{ + (oper_a(), oper_b()) +} + +fn main() { + let ((_x, _y), _z): (_, Z) = join(|| (X, Y), || Z); + + let (Pair { x: _x, y: _y }, Z): (_, Z) = join(|| Pair { x: X, y: Y }, || Z); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-58776-borrowck-scans-children.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-58776-borrowck-scans-children.rs new file mode 100644 index 000000000000..e17cafaff79d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-58776-borrowck-scans-children.rs @@ -0,0 +1,12 @@ +fn main() { + let mut greeting = "Hello world!".to_string(); + let res = (|| (|| &greeting)())(); + + greeting = "DEALLOCATED".to_string(); +// { dg-error ".E0506." "" { target *-*-* } .-1 } + drop(greeting); +// { dg-error ".E0505." "" { target *-*-* } .-1 } + + println!("thread result: {:?}", res); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-62007-assign-box.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-62007-assign-box.rs new file mode 100644 index 000000000000..60ac5ac4c30c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-62007-assign-box.rs @@ -0,0 +1,28 @@ +// run-pass + +// Issue #62007: assigning over a deref projection of a box (in this +// case, `*list = n;`) should be able to kill all borrows of `*list`, +// so that `*list` can be borrowed on the next iteration through the +// loop. + +#![allow(dead_code)] + +struct List { + value: T, + next: Option>>, +} + +fn to_refs(mut list: Box<&mut List>) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.value); + if let Some(n) = list.next.as_mut() { + *list = n; + } else { + return result; + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-62007-assign-field.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-62007-assign-field.rs new file mode 100644 index 000000000000..7f76544846d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-62007-assign-field.rs @@ -0,0 +1,27 @@ +// run-pass + +// Issue #62007: assigning over a field projection (`list.0 = n;` in +// this case) should be able to kill all borrows of `list.0`, so that +// `list.0` can be borrowed on the next iteration through the loop. + +#![allow(dead_code)] + +struct List { + value: T, + next: Option>>, +} + +fn to_refs(mut list: (&mut List,)) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut (list.0).value); + if let Some(n) = (list.0).next.as_mut() { + list.0 = n; + } else { + return result; + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-62107-match-arm-scopes.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-62107-match-arm-scopes.rs new file mode 100644 index 000000000000..53c9b6539e56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-62107-match-arm-scopes.rs @@ -0,0 +1,13 @@ +fn main() { + let e: i32; + match e { +// { dg-error ".E0381." "" { target *-*-* } .-1 } + ref u if true => {} + ref v if true => { + let tx = 0; + &tx; + } + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-64453.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-64453.rs new file mode 100644 index 000000000000..5ebe0ae84d3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-64453.rs @@ -0,0 +1,24 @@ +struct Project; +struct Value; + +static settings_dir: String = format!(""); +// { dg-error ".E0015." "" { target *-*-* } .-1 } +// { dg-error ".E0015." "" { target *-*-* } .-2 } + +fn from_string(_: String) -> Value { + Value +} +fn set_editor(_: Value) {} + +fn main() { + let settings_data = from_string(settings_dir); +// { dg-error ".E0507." "" { target *-*-* } .-1 } + let args: i32 = 0; + + match args { + ref x if x == &0 => set_editor(settings_data), + ref x if x == &1 => set_editor(settings_data), + _ => unimplemented!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-69789-iterator-mut-suggestion.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-69789-iterator-mut-suggestion.rs new file mode 100644 index 000000000000..c20bdaf9fbd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-69789-iterator-mut-suggestion.rs @@ -0,0 +1,12 @@ +// Regression test for #69789: rustc generated an invalid suggestion +// when `&` reference from `&mut` iterator is mutated. + +fn main() { + for item in &mut std::iter::empty::<&'static ()>() { +// { dg-note "" "" { target *-*-* } .-1 } + *item = (); +// { dg-error ".E0594." "" { target *-*-* } .-1 } +// { dg-note ".E0594." "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/issue-7573.rs b/gcc/testsuite/rust/rustc/ui/borrowck/issue-7573.rs new file mode 100644 index 000000000000..da1b6d4d2768 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/issue-7573.rs @@ -0,0 +1,42 @@ +pub struct CrateId { + local_path: String, + junk: String, +} + +impl CrateId { + fn new(s: &str) -> CrateId { + CrateId { local_path: s.to_string(), junk: "wutevs".to_string() } + } +} + +pub fn remove_package_from_database() { + let mut lines_to_use: Vec<&CrateId> = Vec::new(); +// { dg-note "" "" { target *-*-* } .-1 } + let push_id = |installed_id: &CrateId| { +// { dg-note "" "" { target *-*-* } .-1 } + lines_to_use.push(installed_id); +// { dg-error ".E0521." "" { target *-*-* } .-1 } +// { dg-note ".E0521." "" { target *-*-* } .-2 } + }; + list_database(push_id); + + for l in &lines_to_use { + println!("{}", l.local_path); + } +} + +pub fn list_database(mut f: F) +where + F: FnMut(&CrateId), +{ + let stuff = ["foo", "bar"]; + + for l in &stuff { + f(&CrateId::new(*l)); + } +} + +pub fn main() { + remove_package_from_database(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/move-error-in-promoted-2.rs b/gcc/testsuite/rust/rustc/ui/borrowck/move-error-in-promoted-2.rs new file mode 100644 index 000000000000..9697dd467a81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/move-error-in-promoted-2.rs @@ -0,0 +1,11 @@ +// Regression test for #70934 + +struct S; + +fn foo() { + &([S][0],); +// { dg-error ".E0508." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/move-error-in-promoted.rs b/gcc/testsuite/rust/rustc/ui/borrowck/move-error-in-promoted.rs new file mode 100644 index 000000000000..4af8bf8305ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/move-error-in-promoted.rs @@ -0,0 +1,18 @@ +// Regression test for #70934 + +fn f() { + const C: [S2; 1] = [S2]; + let _ = S1(C[0]).clone(); +// { dg-error ".E0508." "" { target *-*-* } .-1 } +} + +#[derive(Clone)] +struct S1(S2); + +#[derive(Clone)] +struct S2; + +fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/move-error-snippets-ext.rs b/gcc/testsuite/rust/rustc/ui/borrowck/move-error-snippets-ext.rs new file mode 100644 index 000000000000..c55a2b4508fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/move-error-snippets-ext.rs @@ -0,0 +1,8 @@ +// ignore-test + +macro_rules! aaa { + ($c:ident) => {{ + let a = $c; + }} +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/move-error-snippets.rs b/gcc/testsuite/rust/rustc/ui/borrowck/move-error-snippets.rs new file mode 100644 index 000000000000..876feb6aba39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/move-error-snippets.rs @@ -0,0 +1,24 @@ +// Test that we don't ICE after trying to construct a cross-file snippet #63800. + +// compile-flags: --test + +#[macro_use] +#[path = "move-error-snippets-ext.rs"] +mod move_error_snippets_ext; + +struct A; + +macro_rules! sss { + () => { + #[test] + fn fff() { + static D: A = A; + aaa!(D); // { dg-error "" "" { target *-*-* } } + } + }; +} + +sss!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/move-from-union-field-issue-66500.rs b/gcc/testsuite/rust/rustc/ui/borrowck/move-from-union-field-issue-66500.rs new file mode 100644 index 000000000000..4fa816b47a55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/move-from-union-field-issue-66500.rs @@ -0,0 +1,31 @@ +// Moving from a reference/raw pointer should be an error, even when they're +// the field of a union. + +#![feature(untagged_unions)] + +union Pointers { + a: &'static String, + b: &'static mut String, + c: *const String, + d: *mut String, +} + +unsafe fn move_ref(u: Pointers) -> String { + *u.a +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} +unsafe fn move_ref_mut(u: Pointers) -> String { + *u.b +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} +unsafe fn move_ptr(u: Pointers) -> String { + *u.c +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} +unsafe fn move_ptr_mut(u: Pointers) -> String { + *u.d +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/move-in-pattern-mut.rs b/gcc/testsuite/rust/rustc/ui/borrowck/move-in-pattern-mut.rs new file mode 100644 index 000000000000..df835a3eca0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/move-in-pattern-mut.rs @@ -0,0 +1,24 @@ +// Issue #63988 +#[derive(Debug)] +struct S; +fn foo(_: Option) {} + +enum E { + V { + s: S, + } +} +fn bar(_: E) {} + +fn main() { + let s = Some(S); + if let Some(mut x) = s { + x = S; + } + foo(s); // { dg-error ".E0382." "" { target *-*-* } } + let mut e = E::V { s: S }; + let E::V { s: mut x } = e; + x = S; + bar(e); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/move-in-pattern.rs b/gcc/testsuite/rust/rustc/ui/borrowck/move-in-pattern.rs new file mode 100644 index 000000000000..9527cfc2ce42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/move-in-pattern.rs @@ -0,0 +1,25 @@ +// run-rustfix +// Issue #63988 +#[derive(Debug)] +struct S; +fn foo(_: Option) {} + +enum E { + V { + s: S, + } +} +fn bar(_: E) {} + +fn main() { + let s = Some(S); + if let Some(x) = s { + let _ = x; + } + foo(s); // { dg-error ".E0382." "" { target *-*-* } } + let e = E::V { s: S }; + let E::V { s: x } = e; + let _ = x; + bar(e); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/move-in-static-initializer-issue-38520.rs b/gcc/testsuite/rust/rustc/ui/borrowck/move-in-static-initializer-issue-38520.rs new file mode 100644 index 000000000000..4e10e1fd5a47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/move-in-static-initializer-issue-38520.rs @@ -0,0 +1,17 @@ +// Regression test for #38520. Check that moves of `Foo` are not +// permitted as `Foo` is not copy (even in a static/const +// initializer). + +struct Foo(usize); + +const fn get(x: Foo) -> usize { + x.0 +} + +const X: Foo = Foo(22); +static Y: usize = get(*&X); // { dg-error ".E0507." "" { target *-*-* } } +const Z: usize = get(*&X); // { dg-error ".E0507." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-in-loop-2.rs b/gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-in-loop-2.rs new file mode 100644 index 000000000000..8e9116f41aba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-in-loop-2.rs @@ -0,0 +1,36 @@ +// run-rustfix +#![allow(dead_code)] + +struct Events(R); + +struct Other; + +pub trait Trait { + fn handle(value: T) -> Self; +} + +// Blanket impl. (If you comment this out, compiler figures out that it +// is passing an `&mut` to a method that must be expecting an `&mut`, +// and injects an auto-reborrow.) +impl Trait for T where T: From { + fn handle(_: U) -> Self { unimplemented!() } +} + +impl<'a, R> Trait<&'a mut Events> for Other { + fn handle(_: &'a mut Events) -> Self { unimplemented!() } +} + +fn this_compiles<'a, R>(value: &'a mut Events) { + for _ in 0..3 { + Other::handle(&mut *value); + } +} + +fn this_does_not<'a, R>(value: &'a mut Events) { + for _ in 0..3 { + Other::handle(value); // { dg-error ".E0382." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-in-loop.rs b/gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-in-loop.rs new file mode 100644 index 000000000000..8b51497d2e3b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-in-loop.rs @@ -0,0 +1,30 @@ +// produce special borrowck message inside all kinds of loops + +struct FuncWrapper<'a, T : 'a> { + func : fn(&'a mut T) -> () +} + +impl<'a, T : 'a> FuncWrapper<'a, T> { + fn in_loop(self, arg : &'a mut T) { + loop { + (self.func)(arg) // { dg-error ".E0499." "" { target *-*-* } } + } + } + + fn in_while(self, arg : &'a mut T) { + while true { // { dg-warning "" "" { target *-*-* } } + (self.func)(arg) // { dg-error ".E0499." "" { target *-*-* } } + } + } + + fn in_for(self, arg : &'a mut T) { + let v : Vec<()> = vec![]; + for _ in v.iter() { + (self.func)(arg) // { dg-error ".E0499." "" { target *-*-* } } + } + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-of-mut-ref.rs b/gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-of-mut-ref.rs new file mode 100644 index 000000000000..8e6a53ac592c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-of-mut-ref.rs @@ -0,0 +1,12 @@ +// Suggest not mutably borrowing a mutable reference +#![crate_type = "rlib"] + +pub fn f(b: &mut i32) { + g(&mut b); +// { dg-error ".E0596." "" { target *-*-* } .-1 } + g(&mut &mut b); +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + +pub fn g(_: &mut i32) {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-outside-loop.rs b/gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-outside-loop.rs new file mode 100644 index 000000000000..207e3b06d695 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/mut-borrow-outside-loop.rs @@ -0,0 +1,23 @@ +// ensure borrowck messages are correct outside special case +#![feature(rustc_attrs)] +fn main() { #![rustc_error] // rust-lang/rust#49855 + let mut void = (); + + let first = &mut void; + let second = &mut void; // { dg-error ".E0499." "" { target *-*-* } } + first.use_mut(); + second.use_mut(); + + loop { + let mut inner_void = (); + + let inner_first = &mut inner_void; + let inner_second = &mut inner_void; // { dg-error ".E0499." "" { target *-*-* } } + inner_second.use_mut(); + inner_first.use_mut(); + } +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/mutability-errors.rs b/gcc/testsuite/rust/rustc/ui/borrowck/mutability-errors.rs new file mode 100644 index 000000000000..0e23aad1a773 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/mutability-errors.rs @@ -0,0 +1,83 @@ +// All the possible mutability error cases. + +#![allow(unused)] + +type MakeRef = fn() -> &'static (i32,); +type MakePtr = fn() -> *const (i32,); + +fn named_ref(x: &(i32,)) { + *x = (1,); // { dg-error ".E0594." "" { target *-*-* } } + x.0 = 1; // { dg-error ".E0594." "" { target *-*-* } } + &mut *x; // { dg-error ".E0596." "" { target *-*-* } } + &mut x.0; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn unnamed_ref(f: MakeRef) { + *f() = (1,); // { dg-error ".E0594." "" { target *-*-* } } + f().0 = 1; // { dg-error ".E0594." "" { target *-*-* } } + &mut *f(); // { dg-error ".E0596." "" { target *-*-* } } + &mut f().0; // { dg-error ".E0596." "" { target *-*-* } } +} + +unsafe fn named_ptr(x: *const (i32,)) { + *x = (1,); // { dg-error ".E0594." "" { target *-*-* } } + (*x).0 = 1; // { dg-error ".E0594." "" { target *-*-* } } + &mut *x; // { dg-error ".E0596." "" { target *-*-* } } + &mut (*x).0; // { dg-error ".E0596." "" { target *-*-* } } +} + +unsafe fn unnamed_ptr(f: MakePtr) { + *f() = (1,); // { dg-error ".E0594." "" { target *-*-* } } + (*f()).0 = 1; // { dg-error ".E0594." "" { target *-*-* } } + &mut *f(); // { dg-error ".E0596." "" { target *-*-* } } + &mut (*f()).0; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn fn_ref(f: F) -> F { f } + +fn ref_closure(mut x: (i32,)) { + fn_ref(|| { + x = (1,); // { dg-error ".E0594." "" { target *-*-* } } + x.0 = 1; // { dg-error ".E0594." "" { target *-*-* } } + &mut x; // { dg-error ".E0596." "" { target *-*-* } } + &mut x.0; // { dg-error ".E0596." "" { target *-*-* } } + }); + fn_ref(move || { + x = (1,); // { dg-error ".E0594." "" { target *-*-* } } + x.0 = 1; // { dg-error ".E0594." "" { target *-*-* } } + &mut x; // { dg-error ".E0596." "" { target *-*-* } } + &mut x.0; // { dg-error ".E0596." "" { target *-*-* } } + }); +} + +fn imm_local(x: (i32,)) { + &mut x; // { dg-error ".E0596." "" { target *-*-* } } + &mut x.0; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn imm_capture(x: (i32,)) { + || { + x = (1,); // { dg-error ".E0594." "" { target *-*-* } } + x.0 = 1; // { dg-error ".E0594." "" { target *-*-* } } + &mut x; // { dg-error ".E0596." "" { target *-*-* } } + &mut x.0; // { dg-error ".E0596." "" { target *-*-* } } + }; + move || { + x = (1,); // { dg-error ".E0594." "" { target *-*-* } } + x.0 = 1; // { dg-error ".E0594." "" { target *-*-* } } + &mut x; // { dg-error ".E0596." "" { target *-*-* } } + &mut x.0; // { dg-error ".E0596." "" { target *-*-* } } + }; +} + +static X: (i32,) = (0,); + +fn imm_static() { + X = (1,); // { dg-error ".E0594." "" { target *-*-* } } + X.0 = 1; // { dg-error ".E0594." "" { target *-*-* } } + &mut X; // { dg-error ".E0596." "" { target *-*-* } } + &mut X.0; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/or-patterns.rs b/gcc/testsuite/rust/rustc/ui/borrowck/or-patterns.rs new file mode 100644 index 000000000000..4b8619480e0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/or-patterns.rs @@ -0,0 +1,65 @@ +// Test that borrow check considers all choices in an or pattern, even the +// unreachable ones. + +#![feature(or_patterns)] + +fn or_pattern_moves_all(x: ((String, String),)) { + match x { + ((y, _) | (_, y),) => (), + } + &x.0 .0; +// { dg-error ".E0382." "" { target *-*-* } .-1 } + &x.0 .1; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn or_pattern_borrows_all(mut x: ((String, String),)) { + let r = match x { + ((ref y, _) | (_, ref y),) => y, + }; + &mut x.0 .0; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + &mut x.0 .1; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + drop(r); +} + +fn or_pattern_borrows_all_mut(mut x: ((String, String),)) { + let r = match x { + ((ref mut y, _) | (_, ref mut y),) => y, + }; + &x.0 .0; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + &x.0 .1; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + drop(r); +} + +fn let_or_pattern_moves_all(x: ((String, String),)) { + let ((y, _) | (_, y),) = x; + &x.0 .0; +// { dg-error ".E0382." "" { target *-*-* } .-1 } + &x.0 .1; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn let_or_pattern_borrows_all(mut x: ((String, String),)) { + let ((ref r, _) | (_, ref r),) = x; + &mut x.0 .0; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + &mut x.0 .1; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + drop(r); +} + +fn let_or_pattern_borrows_all_mut(mut x: ((String, String),)) { + let ((ref mut r, _) | (_, ref mut r),) = x; + &x.0 .0; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + &x.0 .1; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + drop(r); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/promote-ref-mut-in-let-issue-46557.rs b/gcc/testsuite/rust/rustc/ui/borrowck/promote-ref-mut-in-let-issue-46557.rs new file mode 100644 index 000000000000..fa647735cf9a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/promote-ref-mut-in-let-issue-46557.rs @@ -0,0 +1,32 @@ +// Test that we fail to promote the constant here which has a `ref +// mut` borrow. + +fn gimme_static_mut_let() -> &'static mut u32 { + let ref mut x = 1234543; + x // { dg-error ".E0515." "" { target *-*-* } } +} + +fn gimme_static_mut_let_nested() -> &'static mut u32 { + let (ref mut x, ) = (1234543, ); + x // { dg-error ".E0515." "" { target *-*-* } } +} + +fn gimme_static_mut_match() -> &'static mut u32 { + match 1234543 { // { dg-error ".E0515." "" { target *-*-* } } + ref mut x => x + } +} + +fn gimme_static_mut_match_nested() -> &'static mut u32 { + match (123443,) { // { dg-error ".E0515." "" { target *-*-* } } + (ref mut x,) => x, + } +} + +fn gimme_static_mut_ampersand() -> &'static mut u32 { + &mut 1234543 // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/reassignment_immutable_fields.rs b/gcc/testsuite/rust/rustc/ui/borrowck/reassignment_immutable_fields.rs new file mode 100644 index 000000000000..47b58e03bfb6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/reassignment_immutable_fields.rs @@ -0,0 +1,21 @@ +// This test is currently disallowed, but we hope someday to support it. +// +// FIXME(#21232) + +fn assign_both_fields_and_use() { + let x: (u32, u32); + x.0 = 1; // { dg-error ".E0381." "" { target *-*-* } } + x.1 = 22; + drop(x.0); + drop(x.1); +} + +fn assign_both_fields_the_use_var() { + let x: (u32, u32); + x.0 = 1; // { dg-error ".E0381." "" { target *-*-* } } + x.1 = 22; + drop(x); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/reassignment_immutable_fields_overlapping.rs b/gcc/testsuite/rust/rustc/ui/borrowck/reassignment_immutable_fields_overlapping.rs new file mode 100644 index 000000000000..452dbc6ee335 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/reassignment_immutable_fields_overlapping.rs @@ -0,0 +1,17 @@ +// This should never be allowed -- `foo.a` and `foo.b` are +// overlapping, so since `x` is not `mut` we should not permit +// reassignment. + +union Foo { + a: u32, + b: u32, +} + +unsafe fn overlapping_fields() { + let x: Foo; + x.a = 1; // { dg-error ".E0381." "" { target *-*-* } } + x.b = 22; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/reassignment_immutable_fields_twice.rs b/gcc/testsuite/rust/rustc/ui/borrowck/reassignment_immutable_fields_twice.rs new file mode 100644 index 000000000000..9321556a44bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/reassignment_immutable_fields_twice.rs @@ -0,0 +1,18 @@ +// This should never be allowed -- since `x` is not `mut`, so `x.0` +// cannot be assigned twice. + +fn var_then_field() { + let x: (u32, u32); + x = (22, 44); + x.0 = 1; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn same_field_twice() { + let x: (u32, u32); + x.0 = 1; // { dg-error ".E0381." "" { target *-*-* } } + x.0 = 22; + x.1 = 44; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/regions-bound-missing-bound-in-impl.rs b/gcc/testsuite/rust/rustc/ui/borrowck/regions-bound-missing-bound-in-impl.rs new file mode 100644 index 000000000000..20513a8cca18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/regions-bound-missing-bound-in-impl.rs @@ -0,0 +1,55 @@ +// Check that explicit region bounds are allowed on the various +// nominal types (but not on other types) and that they are type +// checked. + +struct Inv<'a> { // invariant w/r/t 'a + x: &'a mut &'a isize +} + +pub trait Foo<'a, 't> { + fn no_bound<'b>(self, b: Inv<'b>); + fn has_bound<'b:'a>(self, b: Inv<'b>); + fn wrong_bound1<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); + fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); + fn okay_bound<'b,'c,'d:'a+'b+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>); + fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>); +} + +impl<'a, 't> Foo<'a, 't> for &'a isize { + fn no_bound<'b:'a>(self, b: Inv<'b>) { +// { dg-error ".E0195." "" { target *-*-* } .-1 } + } + + fn has_bound<'b>(self, b: Inv<'b>) { +// { dg-error ".E0195." "" { target *-*-* } .-1 } + } + + fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + // + // Note: This is a terrible error message. It is caused + // because, in the trait, 'b is early bound, and in the impl, + // 'c is early bound, so -- after substitution -- the + // lifetimes themselves look isomorphic. We fail because the + // lifetimes that appear in the types are in the wrong + // order. This should really be fixed by keeping more + // information about the lifetime declarations in the trait so + // that we can compare better to the impl, even in cross-crate + // cases. + } + + fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) { +// { dg-error ".E0195." "" { target *-*-* } .-1 } + } + + fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) { + } + + fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) { +// { dg-error ".E0276." "" { target *-*-* } .-1 } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/regions-escape-bound-fn-2.rs b/gcc/testsuite/rust/rustc/ui/borrowck/regions-escape-bound-fn-2.rs new file mode 100644 index 000000000000..65b06823cfc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/regions-escape-bound-fn-2.rs @@ -0,0 +1,14 @@ +fn with_int(f: F) +where + F: FnOnce(&isize), +{ + let x = 3; + f(&x); +} + +fn main() { + let mut x = None; + with_int(|y| x = Some(y)); +// { dg-error ".E0521." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/regions-escape-bound-fn.rs b/gcc/testsuite/rust/rustc/ui/borrowck/regions-escape-bound-fn.rs new file mode 100644 index 000000000000..6f3d3338606c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/regions-escape-bound-fn.rs @@ -0,0 +1,14 @@ +fn with_int(f: F) +where + F: FnOnce(&isize), +{ + let x = 3; + f(&x); +} + +fn main() { + let mut x: Option<&isize> = None; + with_int(|y| x = Some(y)); +// { dg-error ".E0521." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/regions-escape-unboxed-closure.rs b/gcc/testsuite/rust/rustc/ui/borrowck/regions-escape-unboxed-closure.rs new file mode 100644 index 000000000000..5ab12168390a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/regions-escape-unboxed-closure.rs @@ -0,0 +1,8 @@ +fn with_int(f: &mut dyn FnMut(&isize)) {} + +fn main() { + let mut x: Option<&isize> = None; + with_int(&mut |y| x = Some(y)); +// { dg-error ".E0521." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/return-local-binding-from-desugaring.rs b/gcc/testsuite/rust/rustc/ui/borrowck/return-local-binding-from-desugaring.rs new file mode 100644 index 000000000000..7c0707bb5861 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/return-local-binding-from-desugaring.rs @@ -0,0 +1,34 @@ +// To avoid leaking the names of local bindings from expressions like for loops, #60984 +// explicitly ignored them, but an assertion that `LocalKind::Var` *must* have a name would +// trigger an ICE. Before this change, this file's output would be: +// ``` +// error[E0515]: cannot return value referencing local variable `__next` +// --> return-local-binding-from-desugaring.rs:LL:CC +// | +// LL | for ref x in xs { +// | ----- `__next` is borrowed here +// ... +// LL | result +// | ^^^^^^ returns a value referencing data owned by the current function +// ``` +// FIXME: ideally `LocalKind` would carry more information to more accurately explain the problem. + +use std::collections::HashMap; +use std::hash::Hash; + +fn group_by(xs: &mut I, f: F) -> HashMap> +where + I: Iterator, + F: Fn(&I::Item) -> T, + T: Eq + Hash, +{ + let mut result = HashMap::new(); + for ref x in xs { + let key = f(x); + result.entry(key).or_insert(Vec::new()).push(x); + } + result // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/slice-index-bounds-check-invalidation.rs b/gcc/testsuite/rust/rustc/ui/borrowck/slice-index-bounds-check-invalidation.rs new file mode 100644 index 000000000000..738fd0645697 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/slice-index-bounds-check-invalidation.rs @@ -0,0 +1,83 @@ +// Test that we error if a slice is modified after it has been bounds checked +// and before we actually index it. + +fn modify_before_assert_slice_slice(x: &[&[i32]]) -> i32 { + let mut x = x; + let z: &[i32] = &[1, 2, 3]; + let y: &[&[i32]] = &[z]; + x[{ x = y; 0 }][2] // OK we haven't checked any bounds before we index `x`. +} + +fn modify_before_assert_array_slice(x: &[&[i32]; 3]) -> i32 { + let mut x = x; + let z: &[i32] = &[1, 2, 3]; + let y: &[&[i32]; 3] = &[z, z, z]; + x[{ x = y; 0 }][2] // OK we haven't checked any bounds before we index `x`. +} + +fn modify_before_assert_slice_array(x: &[&[i32; 3]]) -> i32 { + let mut x = x; + let z: &[i32; 3] = &[1, 2, 3]; + let y: &[&[i32; 3]] = &[z]; + x[{ x = y; 0 }][2] // OK we haven't checked any bounds before we index `x`. +} + +fn modify_before_assert_array_array(x: &[&[i32; 3]; 3]) -> i32 { + let mut x = x; + let z: &[i32; 3] = &[1, 2, 3]; + let y: &[&[i32; 3]; 3] = &[z, z, z]; + x[{ x = y; 0 }][2] // OK we haven't checked any bounds before we index `x`. +} + +fn modify_after_assert_slice_slice(x: &[&[i32]]) -> i32 { + let mut x = x; + let z: &[i32] = &[1, 2, 3]; + let y: &[&[i32]] = &[&z]; + x[1][{ x = y; 2}] // { dg-error ".E0510." "" { target *-*-* } } +} + +fn modify_after_assert_array_slice(x: &[&[i32]; 1]) -> i32 { + let mut x = x; + let z: &[i32] = &[1, 2, 3]; + let y: &[&[i32]; 1] = &[&z]; + x[0][{ x = y; 2}] // OK cannot invalidate a fixed-size array bounds check +} + +fn modify_after_assert_slice_array(x: &[&[i32; 3]]) -> i32 { + let mut x = x; + let z: &[i32; 3] = &[1, 2, 3]; + let y: &[&[i32; 3]] = &[&z]; + x[1][{ x = y; 2}] // { dg-error ".E0510." "" { target *-*-* } } +} + +fn modify_after_assert_array_array(x: &[&[i32; 3]; 1]) -> i32 { + let mut x = x; + let z: &[i32; 3] = &[1, 2, 3]; + let y: &[&[i32; 3]; 1] = &[&z]; + x[0][{ x = y; 2}] // OK cannot invalidate a fixed-size array bounds check +} + +fn modify_after_assert_slice_slice_array(x: &[&[[i32; 1]]]) -> i32 { + let mut x = x; + let z: &[[i32; 1]] = &[[1], [2], [3]]; + let y: &[&[[i32; 1]]] = &[&z]; + x[1][{ x = y; 2}][0] // { dg-error ".E0510." "" { target *-*-* } } +} + +fn modify_after_assert_slice_slice_slice(x: &[&[&[i32]]]) -> i32 { + let mut x = x; + let z: &[&[i32]] = &[&[1], &[2], &[3]]; + let y: &[&[&[i32]]] = &[z]; + x[1][{ x = y; 2}][0] // { dg-error ".E0510." "" { target *-*-* } } +} + + +fn main() { + println!("{}", modify_after_assert_slice_array(&[&[4, 5, 6], &[9, 10, 11]])); + println!("{}", modify_after_assert_slice_slice(&[&[4, 5, 6], &[9, 10, 11]])); + println!("{}", modify_after_assert_slice_slice_array(&[&[[4], [5], [6]], &[[9], [10], [11]]])); + println!("{}", modify_after_assert_slice_slice_slice( + &[&[&[4], &[5], &[6]], &[&[9], &[10], &[11]]]), + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-across-loop.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-across-loop.rs new file mode 100644 index 000000000000..6b6886114d7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-across-loop.rs @@ -0,0 +1,23 @@ +// Test that a borrow which starts as a two-phase borrow and gets +// carried around a loop winds up conflicting with itself. + +struct Foo { x: String } + +impl Foo { + fn get_string(&mut self) -> &str { + &self.x + } +} + +fn main() { + let mut foo = Foo { x: format!("Hello, world") }; + let mut strings = vec![]; + + loop { + strings.push(foo.get_string()); // { dg-error ".E0499." "" { target *-*-* } } + if strings.len() > 2 { break; } + } + + println!("{:?}", strings); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-activation-sharing-interference.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-activation-sharing-interference.rs new file mode 100644 index 000000000000..44d6097d7d6b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-activation-sharing-interference.rs @@ -0,0 +1,68 @@ +// revisions: nll_target + +// The following revisions are disabled due to missing support from two-phase beyond autorefs +//[nll_beyond] compile-flags: -Z borrowck=mir -Z two-phase-beyond-autoref + +//[nll_target] compile-flags: -Z borrowck=mir + +// This is an important corner case pointed out by Niko: one is +// allowed to initiate a shared borrow during a reservation, but it +// *must end* before the activation occurs. +// +// FIXME: for clarity, diagnostics for these cases might be better off +// if they specifically said "cannot activate mutable borrow of `x`" +// +// The convention for the listed revisions: "lxl" means lexical +// lifetimes (which can be easier to reason about). "nll" means +// non-lexical lifetimes. "nll_target" means the initial conservative +// two-phase borrows that only applies to autoref-introduced borrows. +// "nll_beyond" means the generalization of two-phase borrows to all +// `&mut`-borrows (doing so makes it easier to write code for specific +// corner cases). + +#![allow(dead_code)] + +fn read(_: &i32) { } + +fn ok() { + let mut x = 3; + let y = &mut x; + { let z = &x; read(z); } +// { dg-error "" "" { target *-*-* } .-1 } + *y += 1; +} + +fn not_ok() { + let mut x = 3; + let y = &mut x; + let z = &x; +// { dg-error "" "" { target *-*-* } .-1 } + *y += 1; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + read(z); +} + +fn should_be_ok_with_nll() { + let mut x = 3; + let y = &mut x; + let z = &x; +// { dg-error "" "" { target *-*-* } .-1 } + read(z); + *y += 1; +// { dg-error "" "" { target *-*-* } .-1 } + // (okay with (generalized) nll today) +} + +fn should_also_eventually_be_ok_with_nll() { + let mut x = 3; + let y = &mut x; + let _z = &x; +// { dg-error "" "" { target *-*-* } .-1 } + *y += 1; +// { dg-error "" "" { target *-*-* } .-1 } + // (okay with (generalized) nll today) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-allow-access-during-reservation.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-allow-access-during-reservation.rs new file mode 100644 index 000000000000..cc79d87f6931 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-allow-access-during-reservation.rs @@ -0,0 +1,42 @@ +// ignore-tidy-linelength + +// revisions: nll_target + +// The following revisions are disabled due to missing support for two_phase_beyond_autoref +//[nll_beyond] compile-flags: -Z borrowck=mir -Z two_phase_beyond_autoref + +//[nll_target] compile-flags: -Z borrowck=mir + +// This is the second counter-example from Niko's blog post +// smallcultfollowing.com/babysteps/blog/2017/03/01/nested-method-calls-via-two-phase-borrowing/ +// +// It is "artificial". It is meant to illustrate directly that we +// should allow an aliasing access during reservation, but *not* while +// the mutable borrow is active. +// +// The convention for the listed revisions: "lxl" means lexical +// lifetimes (which can be easier to reason about). "nll" means +// non-lexical lifetimes. "nll_target" means the initial conservative +// two-phase borrows that only applies to autoref-introduced borrows. +// "nll_beyond" means the generalization of two-phase borrows to all +// `&mut`-borrows (doing so makes it easier to write code for specific +// corner cases). + +fn main() { + /*0*/ let mut i = 0; + + /*1*/ let p = &mut i; // (reservation of `i` starts here) + + /*2*/ let j = i; // OK: `i` is only reserved here +// { dg-error "" "" { target *-*-* } .-1 } + + /*3*/ *p += 1; // (mutable borrow of `i` starts here, since `p` is used) + + /*4*/ let k = i; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + + /*5*/ *p += 1; + + let _ = (j, k, p); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-baseline.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-baseline.rs new file mode 100644 index 000000000000..262acd20231a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-baseline.rs @@ -0,0 +1,10 @@ +// run-pass + +// This is the "goto example" for why we want two phase borrows. + +fn main() { + let mut v = vec![0, 1, 2]; + v.push(v.len()); + assert_eq!(v, [0, 1, 2, 3]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-bin-ops.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-bin-ops.rs new file mode 100644 index 000000000000..fcc6c45a5f5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-bin-ops.rs @@ -0,0 +1,36 @@ +// run-pass +use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign}; +use std::ops::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign}; + +struct A(i32); + +macro_rules! trivial_binop { + ($Trait:ident, $m:ident) => { + impl $Trait for A { fn $m(&mut self, rhs: i32) { self.0 = rhs; } } + } +} + +trivial_binop!(AddAssign, add_assign); +trivial_binop!(SubAssign, sub_assign); +trivial_binop!(MulAssign, mul_assign); +trivial_binop!(DivAssign, div_assign); +trivial_binop!(RemAssign, rem_assign); +trivial_binop!(BitAndAssign, bitand_assign); +trivial_binop!(BitOrAssign, bitor_assign); +trivial_binop!(BitXorAssign, bitxor_assign); +trivial_binop!(ShlAssign, shl_assign); +trivial_binop!(ShrAssign, shr_assign); + +fn main() { + let mut a = A(10); + a += a.0; + a -= a.0; + a *= a.0; + a /= a.0; + a &= a.0; + a |= a.0; + a ^= a.0; + a <<= a.0; + a >>= a.0; +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-cannot-nest-mut-self-calls.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-cannot-nest-mut-self-calls.rs new file mode 100644 index 000000000000..190f63d70f58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-cannot-nest-mut-self-calls.rs @@ -0,0 +1,22 @@ +// compile-flags: -Z borrowck=mir + +// This is the third counter-example from Niko's blog post +// smallcultfollowing.com/babysteps/blog/2017/03/01/nested-method-calls-via-two-phase-borrowing/ +// +// It shows that not all nested method calls on `self` are magically +// allowed by this change. In particular, a nested `&mut` borrow is +// still disallowed. + +fn main() { + + + let mut vec = vec![0, 1]; + vec.get({ + + vec.push(2); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + 0 + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-control-flow-split-before-activation.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-control-flow-split-before-activation.rs new file mode 100644 index 000000000000..c09ed36b49e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-control-flow-split-before-activation.rs @@ -0,0 +1,16 @@ +// run-pass + +fn main() { + let mut a = 0; + let mut b = 0; + let p = if maybe() { + &mut a + } else { + &mut b + }; + use_(p); +} + +fn maybe() -> bool { false } +fn use_(_: T) { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-method-receivers.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-method-receivers.rs new file mode 100644 index 000000000000..f11dab250d44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-method-receivers.rs @@ -0,0 +1,18 @@ +// compile-flags: -Z borrowck=mir + +// run-pass + +struct Foo<'a> { + x: &'a i32 +} + +impl<'a> Foo<'a> { + fn method(&mut self, _: &i32) { + } +} + +fn main() { + let a = &mut Foo { x: &22 }; + Foo::method(a, a.x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-multi-mut.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-multi-mut.rs new file mode 100644 index 000000000000..8d32eb193f1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-multi-mut.rs @@ -0,0 +1,15 @@ +struct Foo { +} + +impl Foo { + fn method(&mut self, foo: &mut Foo) { + } +} + +fn main() { + let mut foo = Foo { }; + foo.method(&mut foo); +// { dg-error ".E0499." "" { target *-*-* } .-1 } +// { dg-error ".E0499." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-multiple-activations.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-multiple-activations.rs new file mode 100644 index 000000000000..272442f241a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-multiple-activations.rs @@ -0,0 +1,24 @@ +// compile-flags: -Z borrowck=mir + +// run-pass + +use std::io::Result; + +struct Foo {} + +pub trait FakeRead { + fn read_to_end(&mut self, buf: &mut Vec) -> Result; +} + +impl FakeRead for Foo { + fn read_to_end(&mut self, _buf: &mut Vec) -> Result { + Ok(4) + } +} + +fn main() { + let mut a = Foo {}; + let mut v = Vec::new(); + a.read_to_end(&mut v).unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-nonrecv-autoref.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-nonrecv-autoref.rs new file mode 100644 index 000000000000..e64ec7b3687e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-nonrecv-autoref.rs @@ -0,0 +1,171 @@ +// revisions: nll +//[nll]compile-flags: -Z borrowck=mir + +//[g2p]compile-flags: -Z borrowck=mir -Z two-phase-beyond-autoref +// the above revision is disabled until two-phase-beyond-autoref support is better + +// This is a test checking that when we limit two-phase borrows to +// method receivers, we do not let other kinds of auto-ref to leak +// through. +// +// The g2p revision illustrates the "undesirable" behavior you would +// otherwise observe without limiting the phasing to autoref on method +// receivers (namely, in many cases demonstrated below, the error +// would not arise). + +use std::ops::{Index, IndexMut}; + +fn foo(x: &mut u32, y: u32) { + *x += y; +} + +fn deref_coercion(x: &mut u32) { + foo(x, *x); + // Above error is a known limitation of AST borrowck +} + +// While adding a flag to adjustments (indicating whether they +// should support two-phase borrows, here are the cases I +// encountered: +// +// - [x] Resolving overloaded_call_traits (call, call_mut, call_once) +// - [x] deref_coercion (shown above) +// - [x] coerce_unsized e.g., `&[T; n]`, `&mut [T; n] -> &[T]`, +// `&mut [T; n] -> &mut [T]`, `&Concrete -> &Trait` +// - [x] Method Call Receivers (the case we want to support!) +// - [x] ExprKind::Index and ExprKind::Unary Deref; only need to handle coerce_index_op +// - [x] overloaded_binops + +fn overloaded_call_traits() { + // Regarding overloaded call traits, note that there is no + // scenario where adding two-phase borrows should "fix" these + // cases, because either we will resolve both invocations to + // `call_mut` (in which case the inner call requires a mutable + // borrow which will conflict with the outer reservation), or we + // will resolve both to `call` (which will just work, regardless + // of two-phase borrow support), or we will resolve both to + // `call_once` (in which case the inner call requires moving the + // receiver, invalidating the outer call). + + fn twice_ten_sm i32>(f: &mut F) { + f(f(10)); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + } + fn twice_ten_si i32>(f: &mut F) { + f(f(10)); + } + fn twice_ten_so i32>(f: Box) { + f(f(10)); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + } + + fn twice_ten_om(f: &mut dyn FnMut(i32) -> i32) { + f(f(10)); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + } + fn twice_ten_oi(f: &mut dyn Fn(i32) -> i32) { + f(f(10)); + } + fn twice_ten_oo(f: Box i32>) { + f(f(10)); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + } + + twice_ten_sm(&mut |x| x + 1); + twice_ten_si(&mut |x| x + 1); + twice_ten_so(Box::new(|x| x + 1)); + twice_ten_om(&mut |x| x + 1); + twice_ten_oi(&mut |x| x + 1); + twice_ten_oo(Box::new(|x| x + 1)); +} + +trait TwoMethods { + fn m(&mut self, x: i32) -> i32 { x + 1 } + fn i(&self, x: i32) -> i32 { x + 1 } +} + +struct T; + +impl TwoMethods for T { } + +struct S; + +impl S { + fn m(&mut self, x: i32) -> i32 { x + 1 } + fn i(&self, x: i32) -> i32 { x + 1 } +} + +impl TwoMethods for [i32; 3] { } + +fn double_access(m: &mut [X], s: &[X]) { + m[0] = s[1]; +} + +fn coerce_unsized() { + let mut a = [1, 2, 3]; + + // This is not okay. + double_access(&mut a, &a); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + // But this is okay. + a.m(a.i(10)); + // Above error is an expected limitation of AST borrowck +} + +struct I(i32); + +impl Index for I { + type Output = i32; + fn index(&self, _: i32) -> &i32 { + &self.0 + } +} + +impl IndexMut for I { + fn index_mut(&mut self, _: i32) -> &mut i32 { + &mut self.0 + } +} + +fn coerce_index_op() { + let mut i = I(10); + i[i[3]] = 4; +// { dg-error "" "" { target *-*-* } .-1 } + + i[3] = i[4]; + + i[i[3]] = i[4]; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + + // As a reminder, this is the basic case we want to ensure we handle. + let mut v = vec![1, 2, 3]; + v.push(v.len()); + // Error above is an expected limitation of AST borrowck + + // (as a rule, pnkfelix does not like to write tests with dead code.) + + deref_coercion(&mut 5); + overloaded_call_traits(); + + + let mut s = S; + s.m(s.i(10)); + // Error above is an expected limitation of AST borrowck + + let mut t = T; + t.m(t.i(10)); + // Error above is an expected limitation of AST borrowck + + coerce_unsized(); + coerce_index_op(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference-2.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference-2.rs new file mode 100644 index 000000000000..ca9367b13c5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference-2.rs @@ -0,0 +1,51 @@ +// Test for #56254, we previously allowed the last example on the 2018 +// edition. Make sure that we now emit a warning in that case and an error for +// everyone else. + +//ignore-compare-mode-nll +//ignore-compare-mode-polonius + +//revisions: migrate2015 migrate2018 nll2015 nll2018 + +//[migrate2018] edition:2018 +//[nll2018] edition:2018 + +#![cfg_attr(any(nll2015, nll2018), feature(nll))] + +fn double_conflicts() { + let mut v = vec![0, 1, 2]; + let shared = &v; + + v.extend(shared); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +} + +fn activation_conflict() { + let mut v = vec![0, 1, 2]; + + v.extend(&v); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +} + +fn reservation_conflict() { + let mut v = vec![0, 1, 2]; + let shared = &v; + + v.push(shared.len()); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-2 } + +// { dg-warning "" "" { target *-*-* } .-6 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.rs new file mode 100644 index 000000000000..a232b712e086 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference-future-compat-lint.rs @@ -0,0 +1,44 @@ +// Check that the future-compat-lint for the reservation conflict is +// handled like any other lint. + +// edition:2018 + +mod future_compat_allow { + #![allow(mutable_borrow_reservation_conflict)] + + fn reservation_conflict() { + let mut v = vec![0, 1, 2]; + let shared = &v; + + v.push(shared.len()); + } +} + +mod future_compat_warn { + #![warn(mutable_borrow_reservation_conflict)] + + fn reservation_conflict() { + let mut v = vec![0, 1, 2]; + let shared = &v; + + v.push(shared.len()); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + } +} + +mod future_compat_deny { + #![deny(mutable_borrow_reservation_conflict)] + + fn reservation_conflict() { + let mut v = vec![0, 1, 2]; + let shared = &v; + + v.push(shared.len()); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference.rs new file mode 100644 index 000000000000..3cbe2ac8469d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-reservation-sharing-interference.rs @@ -0,0 +1,50 @@ +// ignore-tidy-linelength + +// revisions: nll_target + +// The following revisions are disabled due to missing support from two-phase beyond autorefs +//[nll_beyond]compile-flags: -Z borrowck=mir -Z two-phase-beyond-autoref +//[nll_beyond] should-fail + +//[nll_target]compile-flags: -Z borrowck=mir + +// This is a corner case that the current implementation is (probably) +// treating more conservatively than is necessary. But it also does +// not seem like a terribly important use case to cover. +// +// So this test is just making a note of the current behavior, with +// the caveat that in the future, the rules may be loosened, at which +// point this test might be thrown out. +// +// The convention for the listed revisions: "lxl" means lexical +// lifetimes (which can be easier to reason about). "nll" means +// non-lexical lifetimes. "nll_target" means the initial conservative +// two-phase borrows that only applies to autoref-introduced borrows. +// "nll_beyond" means the generalization of two-phase borrows to all +// `&mut`-borrows (doing so makes it easier to write code for specific +// corner cases). + +fn main() { + let mut vec = vec![0, 1]; + let delay: &mut Vec<_>; + { + let shared = &vec; + + // we reserve here, which could (on its own) be compatible + // with the shared borrow. But in the current implementation, + // its an error. + delay = &mut vec; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + shared[0]; + } + + // the &mut-borrow only becomes active way down here. + // + // (At least in theory; part of the reason this test fails is that + // the constructed MIR throws in extra &mut reborrows which + // flummoxes our attmpt to delay the activation point here.) + delay.push(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-sneaky.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-sneaky.rs new file mode 100644 index 000000000000..0389461a0efb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-sneaky.rs @@ -0,0 +1,18 @@ +// cmpile-flags: -Z borrowck=mir + +// This is the first counter-example from Niko's blog post +// smallcultfollowing.com/babysteps/blog/2017/03/01/nested-method-calls-via-two-phase-borrowing/ +// of a danger for code to crash if we just turned off the check for whether +// a mutable-borrow aliases another borrow. + +fn main() { + let mut v: Vec = vec![format!("Hello, ")]; + v[0].push_str({ + + v.push(format!("foo")); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + + "World!" + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-surprise-no-conflict.rs b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-surprise-no-conflict.rs new file mode 100644 index 000000000000..50f2aeee48c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/two-phase-surprise-no-conflict.rs @@ -0,0 +1,168 @@ +// This is a test adapted from a minimization of the code from +// rust-lang/rust#52934, where an accidental disabling of +// two-phase-borrows (in the initial 2018 edition integration) broke +// Clippy, but the scenarios where it was breaking were subtle enough +// that we decided it warranted its own unit test, and pnkfelix +// decided to use that test as an opportunity to illustrate the cases. + +#[derive(Copy, Clone)] +struct BodyId; +enum Expr { Closure(BodyId), Others } +struct Body { value: Expr } + +struct Map { body: Body, } +impl Map { fn body(&self, _: BodyId) -> &Body { unimplemented!() } } + +struct SpanlessHash<'a> { cx: &'a Map, cx_mut: &'a mut Map } + +impl <'a> SpanlessHash<'a> { + fn demo(&mut self) { + let _mut_borrow = &mut *self; + let _access = self.cx; +// { dg-error ".E0503." "" { target *-*-* } .-1 } + _mut_borrow; + } + + fn hash_expr(&mut self, e: &Expr) { + match *e { + Expr::Closure(eid) => { + // Accepted by AST-borrowck for erroneous reasons + // (rust-lang/rust#38899). + // + // Not okay without two-phase borrows: the implicit + // `&mut self` of the receiver is evaluated first, and + // that conflicts with the `self.cx` access during + // argument evaluation, as demonstrated in `fn demo` + // above. + // + // Okay if we have two-phase borrows. Note that even + // if `self.cx.body(..)` holds onto a reference into + // `self.cx`, `self.cx` is an immutable-borrow, so + // nothing in the activation for `self.hash_expr(..)` + // can interfere with that immutable borrow. + self.hash_expr(&self.cx.body(eid).value); + }, + _ => {} + } + } + + fn hash_expr_mut(&mut self, e: &Expr) { + match *e { + Expr::Closure(eid) => { + // Not okay: the call to `self.cx_mut.body(eid)` might + // hold on to some mutably borrowed state in + // `self.cx_mut`, which would then interfere with the + // eventual activation of the `self` mutable borrow + // for `self.hash_expr(..)` + self.hash_expr(&self.cx_mut.body(eid).value); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + }, + _ => {} + } + } +} + +struct Session; +struct Config; +trait LateLintPass<'a> { } + +struct TrivialPass; +impl TrivialPass { + fn new(_: &Session) -> Self { TrivialPass } + fn new_mut(_: &mut Session) -> Self { TrivialPass } +} + +struct CapturePass<'a> { s: &'a Session } +impl<'a> CapturePass<'a> { + fn new(s: &'a Session) -> Self { CapturePass { s } } + fn new_mut(s: &'a mut Session) -> Self { CapturePass { s } } +} + +impl<'a> LateLintPass<'a> for TrivialPass { } +impl<'a, 'b> LateLintPass<'a> for CapturePass<'b> { } + +struct Registry<'a> { sess_mut: &'a mut Session } +impl<'a> Registry<'a> { + fn register_static(&mut self, _: Box) { } + + // Note: there isn't an interesting distinction between these + // different methods explored by any of the cases in the test + // below. pnkfelix just happened to write these cases out while + // exploring variations on `dyn for <'a> Trait<'a> + 'static`, and + // then decided to keep these particular ones in. + fn register_bound(&mut self, _: Box) { } + fn register_univ(&mut self, _: Box LateLintPass<'b> + 'a>) { } + fn register_ref(&mut self, _: &dyn LateLintPass) { } +} + +fn register_plugins<'a>(mk_reg: impl Fn() -> &'a mut Registry<'a>) { + // Not okay without two-phase borrows: The implicit `&mut reg` of + // the receiver is evaluaated first, and that conflicts with the + // `reg.sess_mut` access during argument evaluation. + // + // Okay if we have two-phase borrows: inner borrows do not survive + // to the actual method invocation, because `TrivialPass::new` + // cannot (according to its type) keep them alive. + let reg = mk_reg(); + reg.register_static(Box::new(TrivialPass::new(®.sess_mut))); + let reg = mk_reg(); + reg.register_bound(Box::new(TrivialPass::new(®.sess_mut))); + let reg = mk_reg(); + reg.register_univ(Box::new(TrivialPass::new(®.sess_mut))); + let reg = mk_reg(); + reg.register_ref(&TrivialPass::new(®.sess_mut)); + + // These are not okay: the inner mutable borrows immediately + // conflict with the outer borrow/reservation, even with support + // for two-phase borrows. + let reg = mk_reg(); + reg.register_static(Box::new(TrivialPass::new(&mut reg.sess_mut))); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + let reg = mk_reg(); + reg.register_bound(Box::new(TrivialPass::new_mut(&mut reg.sess_mut))); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + let reg = mk_reg(); + reg.register_univ(Box::new(TrivialPass::new_mut(&mut reg.sess_mut))); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + let reg = mk_reg(); + reg.register_ref(&TrivialPass::new_mut(&mut reg.sess_mut)); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + + // These are not okay: the inner borrows may reach the actual + // method invocation, because `CapturePass::new` might (according + // to its type) keep them alive. + // + // (Also, we don't test `register_static` on CapturePass because + // that will fail to get past lifetime inference.) + let reg = mk_reg(); + reg.register_bound(Box::new(CapturePass::new(®.sess_mut))); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + let reg = mk_reg(); + reg.register_univ(Box::new(CapturePass::new(®.sess_mut))); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + let reg = mk_reg(); + reg.register_ref(&CapturePass::new(®.sess_mut)); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + // These are not okay: the inner mutable borrows immediately + // conflict with the outer borrow/reservation, even with support + // for two-phase borrows. + // + // (Again, we don't test `register_static` on CapturePass because + // that will fail to get past lifetime inference.) + let reg = mk_reg(); + reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); +// { dg-error ".E0499." "" { target *-*-* } .-1 } +// { dg-error ".E0499." "" { target *-*-* } .-2 } + let reg = mk_reg(); + reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); +// { dg-error ".E0499." "" { target *-*-* } .-1 } +// { dg-error ".E0499." "" { target *-*-* } .-2 } + let reg = mk_reg(); + reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut)); +// { dg-error ".E0499." "" { target *-*-* } .-1 } +// { dg-error ".E0499." "" { target *-*-* } .-2 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs b/gcc/testsuite/rust/rustc/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs new file mode 100644 index 000000000000..c4c4b4785a42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.rs @@ -0,0 +1,15 @@ +// Test that a by-ref `FnMut` closure gets an error when it tries to +// consume a value. + +fn call(f: F) where F : Fn() { + f(); +} + +fn main() { + let y = vec![format!("World")]; + call(|| { + y.into_iter(); +// { dg-error ".E0507." "" { target *-*-* } .-1 } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/bound-suggestions.rs b/gcc/testsuite/rust/rustc/ui/bound-suggestions.rs new file mode 100644 index 000000000000..730806f9032d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bound-suggestions.rs @@ -0,0 +1,44 @@ +// run-rustfix + +#[allow(unused)] +use std::fmt::Debug; +// Rustfix should add this, or use `std::fmt::Debug` instead. + +#[allow(dead_code)] +fn test_impl(t: impl Sized) { + println!("{:?}", t); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +#[allow(dead_code)] +fn test_no_bounds(t: T) { + println!("{:?}", t); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +#[allow(dead_code)] +fn test_one_bound(t: T) { + println!("{:?}", t); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +#[allow(dead_code)] +fn test_no_bounds_where(x: X, y: Y) where X: std::fmt::Debug, { + println!("{:?} {:?}", x, y); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +#[allow(dead_code)] +fn test_one_bound_where(x: X) where X: Sized { + println!("{:?}", x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +#[allow(dead_code)] +fn test_many_bounds_where(x: X) where X: Sized, X: Sized { + println!("{:?}", x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/bounds-lifetime.rs b/gcc/testsuite/rust/rustc/ui/bounds-lifetime.rs new file mode 100644 index 000000000000..275beb6123db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bounds-lifetime.rs @@ -0,0 +1,8 @@ +type A = for<'b, 'a: 'b> fn(); // { dg-error "" "" { target *-*-* } } +type B = for<'b, 'a: 'b,> fn(); // { dg-error "" "" { target *-*-* } } +type C = for<'b, 'a: 'b +> fn(); // { dg-error "" "" { target *-*-* } } +type D = for<'a, T> fn(); // { dg-error "" "" { target *-*-* } } +type E = dyn for Fn(); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/box/alloc-unstable-fail.rs b/gcc/testsuite/rust/rustc/ui/box/alloc-unstable-fail.rs new file mode 100644 index 000000000000..ad99c22bead7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/box/alloc-unstable-fail.rs @@ -0,0 +1,7 @@ +use std::boxed::Box; + +fn main() { + let _boxed: Box = Box::new(10); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/box/alloc-unstable.rs b/gcc/testsuite/rust/rustc/ui/box/alloc-unstable.rs new file mode 100644 index 000000000000..f9386c8e5510 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/box/alloc-unstable.rs @@ -0,0 +1,9 @@ +// run-pass +#![feature(allocator_api)] + +use std::boxed::Box; + +fn main() { + let _boxed: Box = Box::new(10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/box/into-boxed-slice-fail.rs b/gcc/testsuite/rust/rustc/ui/box/into-boxed-slice-fail.rs new file mode 100644 index 000000000000..f574d6a4ceb7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/box/into-boxed-slice-fail.rs @@ -0,0 +1,15 @@ +#![feature(box_into_boxed_slice)] + +use std::boxed::Box; +use std::fmt::Debug; +fn main() { + let boxed_slice = Box::new([1,2,3]) as Box<[u8]>; + let _ = Box::into_boxed_slice(boxed_slice); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + let boxed_trait: Box = Box::new(5u8); + let _ = Box::into_boxed_slice(boxed_trait); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/box/into-boxed-slice.rs b/gcc/testsuite/rust/rustc/ui/box/into-boxed-slice.rs new file mode 100644 index 000000000000..9c25c58c0cf4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/box/into-boxed-slice.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(box_into_boxed_slice)] + +use std::boxed::Box; +fn main() { + assert_eq!(Box::into_boxed_slice(Box::new(5u8)), Box::new([5u8]) as Box<[u8]>); + assert_eq!(Box::into_boxed_slice(Box::new([25u8])), Box::new([[25u8]]) as Box<[[u8; 1]]>); + let a: Box<[Box<[u8; 1]>]> = Box::into_boxed_slice(Box::new(Box::new([5u8]))); + let b: Box<[Box<[u8; 1]>]> = Box::new([Box::new([5u8])]); + assert_eq!(a, b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/box/leak-alloc.rs b/gcc/testsuite/rust/rustc/ui/box/leak-alloc.rs new file mode 100644 index 000000000000..af7084b6dc98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/box/leak-alloc.rs @@ -0,0 +1,30 @@ +#![feature(allocator_api)] + +use std::alloc::{AllocError, AllocRef, Layout, System}; +use std::ptr::NonNull; + +use std::boxed::Box; + +struct Allocator {} + +unsafe impl AllocRef for Allocator { + fn alloc(&self, layout: Layout) -> Result, AllocError> { + System.alloc(layout) + } + + unsafe fn dealloc(&self, ptr: NonNull, layout: Layout) { + System.dealloc(ptr, layout) + } +} + +fn use_value(_: u32) {} + +fn main() { + let alloc = Allocator {}; + let boxed = Box::new_in(10, alloc.by_ref()); + let theref = Box::leak(boxed); + drop(alloc); +// { dg-error ".E0505." "" { target *-*-* } .-1 } + use_value(*theref) +} + diff --git a/gcc/testsuite/rust/rustc/ui/box/new.rs b/gcc/testsuite/rust/rustc/ui/box/new.rs new file mode 100644 index 000000000000..d54244b03f7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/box/new.rs @@ -0,0 +1,7 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + let _a = Box::new(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/break-diverging-value.rs b/gcc/testsuite/rust/rustc/ui/break-diverging-value.rs new file mode 100644 index 000000000000..e993e851fdce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/break-diverging-value.rs @@ -0,0 +1,38 @@ +#![feature(never_type)] + +fn loop_break_return() -> i32 { + let loop_value = loop { break return 0 }; // ok +} + +fn loop_break_loop() -> i32 { + let loop_value = loop { break loop {} }; // ok +} + +fn loop_break_break() -> i32 { // { dg-error ".E0308." "" { target *-*-* } } + let loop_value = loop { break break }; +} + +fn loop_break_return_2() -> i32 { + let loop_value = loop { break { return 0; () } }; // ok +} + +enum Void {} + +fn get_void() -> Void { + panic!() +} + +fn loop_break_void() -> i32 { // { dg-error ".E0308." "" { target *-*-* } } + let loop_value = loop { break get_void() }; +} + +fn get_never() -> ! { + panic!() +} + +fn loop_break_never() -> i32 { + let loop_value = loop { break get_never() }; // ok +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/break-outside-loop.rs b/gcc/testsuite/rust/rustc/ui/break-outside-loop.rs new file mode 100644 index 000000000000..66dcdce4af73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/break-outside-loop.rs @@ -0,0 +1,36 @@ +struct Foo { + t: String +} + +fn cond() -> bool { true } + +fn foo(_: F) where F: FnOnce() {} + +fn main() { + let pth = break; // { dg-error ".E0268." "" { target *-*-* } } + if cond() { continue } // { dg-error ".E0268." "" { target *-*-* } } + + while cond() { + if cond() { break } + if cond() { continue } + foo(|| { + if cond() { break } // { dg-error ".E0267." "" { target *-*-* } } + if cond() { continue } // { dg-error ".E0267." "" { target *-*-* } } + }) + } + + let rs: Foo = Foo{t: pth}; + + let unconstrained = break; // { dg-error ".E0268." "" { target *-*-* } } + + // This used to ICE because `target_id` passed to `check_expr_break` would be the closure and + // not the `loop`, which failed in the call to `find_breakable`. (#65383) + 'lab: loop { + || { + break 'lab; +// { dg-error ".E0267." "" { target *-*-* } .-1 } +// { dg-error ".E0267." "" { target *-*-* } .-2 } + }; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/break-while-condition.rs b/gcc/testsuite/rust/rustc/ui/break-while-condition.rs new file mode 100644 index 000000000000..8ca60a9dd97e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/break-while-condition.rs @@ -0,0 +1,30 @@ +#![feature(never_type)] + +fn main() { + // The `if false` expressions are simply to + // make sure we don't avoid checking everything + // simply because a few expressions are unreachable. + + if false { + let _: ! = { // { dg-error ".E0308." "" { target *-*-* } } + 'a: while break 'a {}; + }; + } + + if false { + let _: ! = { + while false { // { dg-error ".E0308." "" { target *-*-* } } + break + } + }; + } + + if false { + let _: ! = { + while false { // { dg-error ".E0308." "" { target *-*-* } } + return + } + }; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/btreemap/btreemap_into_iterator_lifetime.rs b/gcc/testsuite/rust/rustc/ui/btreemap/btreemap_into_iterator_lifetime.rs new file mode 100644 index 000000000000..dfc99835495e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/btreemap/btreemap_into_iterator_lifetime.rs @@ -0,0 +1,24 @@ +// check-pass + +use std::collections::{BTreeMap, HashMap}; + +trait Map +where + for<'a> &'a Self: IntoIterator, +{ + type Key; + type Value; +} + +impl Map for HashMap { + type Key = K; + type Value = V; +} + +impl Map for BTreeMap { + type Key = K; + type Value = V; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/bug-7183-generics.rs b/gcc/testsuite/rust/rustc/ui/bug-7183-generics.rs new file mode 100644 index 000000000000..c7031ad88e84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bug-7183-generics.rs @@ -0,0 +1,37 @@ +// run-pass + +trait Speak : Sized { + fn say(&self, s:&str) -> String; + fn hi(&self) -> String { hello(self) } +} + +fn hello(s:&S) -> String{ + s.say("hello") +} + +impl Speak for isize { + fn say(&self, s:&str) -> String { + format!("{}: {}", s, *self) + } +} + +impl Speak for Option { + fn say(&self, s:&str) -> String { + match *self { + None => format!("{} - none", s), + Some(ref x) => { format!("something!{}", x.say(s)) } + } + } +} + + +pub fn main() { + assert_eq!(3.hi(), "hello: 3".to_string()); + assert_eq!(Some(Some(3)).hi(), + "something!something!hello: 3".to_string()); + assert_eq!(None::.hi(), "hello - none".to_string()); + + assert_eq!(Some(None::).hi(), "something!hello - none".to_string()); + assert_eq!(Some(3).hi(), "something!hello: 3".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/bug-7295.rs b/gcc/testsuite/rust/rustc/ui/bug-7295.rs new file mode 100644 index 000000000000..53a840b6146f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/bug-7295.rs @@ -0,0 +1,15 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub trait Foo { + fn func1(&self, t: U, w: T); + + fn func2(&self, t: U, w: T) { + self.func1(t, w); + } +} + +pub fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-clone-unwind.rs b/gcc/testsuite/rust/rustc/ui/builtin-clone-unwind.rs new file mode 100644 index 000000000000..26d5b4476163 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-clone-unwind.rs @@ -0,0 +1,62 @@ +// run-pass + +#![allow(unused_variables)] +#![allow(unused_imports)] +// ignore-wasm32-bare compiled with panic=abort by default + +// Test that builtin implementations of `Clone` cleanup everything +// in case of unwinding. + +use std::thread; +use std::rc::Rc; + +struct S(Rc<()>); + +impl Clone for S { + fn clone(&self) -> Self { + if Rc::strong_count(&self.0) == 7 { + panic!("oops"); + } + + S(self.0.clone()) + } +} + +fn main() { + let counter = Rc::new(()); + + // Unwinding with tuples... + let ccounter = counter.clone(); + let result = std::panic::catch_unwind(move || { + let _ = ( + S(ccounter.clone()), + S(ccounter.clone()), + S(ccounter.clone()), + S(ccounter) + ).clone(); + }); + + assert!(result.is_err()); + assert_eq!( + 1, + Rc::strong_count(&counter) + ); + + // ... and with arrays. + let ccounter = counter.clone(); + let child = std::panic::catch_unwind(move || { + let _ = [ + S(ccounter.clone()), + S(ccounter.clone()), + S(ccounter.clone()), + S(ccounter) + ].clone(); + }); + + assert!(result.is_err()); + assert_eq!( + 1, + Rc::strong_count(&counter) + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-clone.rs b/gcc/testsuite/rust/rustc/ui/builtin-clone.rs new file mode 100644 index 000000000000..1e0c42cf2bd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-clone.rs @@ -0,0 +1,46 @@ +// run-pass +// Test that `Clone` is correctly implemented for builtin types. +// Also test that cloning an array or a tuple is done right, i.e. +// each component is cloned. + +fn test_clone(arg: T) { + let _ = arg.clone(); +} + +fn foo() { } + +#[derive(Debug, PartialEq, Eq)] +struct S(i32); + +impl Clone for S { + fn clone(&self) -> Self { + S(self.0 + 1) + } +} + +fn main() { + test_clone(foo); + test_clone([1; 56]); + test_clone((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)); + + let a = [S(0), S(1), S(2)]; + let b = [S(1), S(2), S(3)]; + assert_eq!(b, a.clone()); + + let a = ( + (S(1), S(0)), + ( + (S(0), S(0), S(1)), + S(0) + ) + ); + let b = ( + (S(2), S(1)), + ( + (S(1), S(1), S(2)), + S(1) + ) + ); + assert_eq!(b, a.clone()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds-capabilities-transitive.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-capabilities-transitive.rs new file mode 100644 index 000000000000..692b8214e20e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-capabilities-transitive.rs @@ -0,0 +1,26 @@ +// run-pass +// Tests "transitivity" of super-builtin-kinds on traits. Here, if +// we have a Foo, we know we have a Bar, and if we have a Bar, we +// know we have a Send. So if we have a Foo we should know we have +// a Send. Basically this just makes sure rustc is using +// each_bound_trait_and_supertraits in type_contents correctly. + + +use std::sync::mpsc::{channel, Sender}; + +trait Bar : Send { } +trait Foo : Bar { } + +impl Foo for T { } +impl Bar for T { } + +fn foo(val: T, chan: Sender) { + chan.send(val).unwrap(); +} + +pub fn main() { + let (tx, rx) = channel(); + foo(31337, tx); + assert_eq!(rx.recv().unwrap(), 31337); +} + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds-capabilities-xc.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-capabilities-xc.rs new file mode 100644 index 000000000000..6ecea370c12a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-capabilities-xc.rs @@ -0,0 +1,28 @@ +// run-pass +// aux-build:trait_superkinds_in_metadata.rs + +// Tests "capabilities" granted by traits with super-builtin-kinds, +// even when using them cross-crate. + + +extern crate trait_superkinds_in_metadata; + +use std::sync::mpsc::{channel, Sender, Receiver}; +use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare}; + +#[derive(PartialEq, Debug)] +struct X(T); + +impl RequiresShare for X { } +impl RequiresRequiresShareAndSend for X { } + +fn foo(val: T, chan: Sender) { + chan.send(val).unwrap(); +} + +pub fn main() { + let (tx, rx): (Sender>, Receiver>) = channel(); + foo(X(31337), tx); + assert_eq!(rx.recv().unwrap(), X(31337)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds-capabilities.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-capabilities.rs new file mode 100644 index 000000000000..b022a342fbd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-capabilities.rs @@ -0,0 +1,22 @@ +// run-pass +// Tests "capabilities" granted by traits that inherit from super- +// builtin-kinds, e.g., if a trait requires Send to implement, then +// at usage site of that trait, we know we have the Send capability. + + +use std::sync::mpsc::{channel, Sender, Receiver}; + +trait Foo : Send { } + +impl Foo for T { } + +fn foo(val: T, chan: Sender) { + chan.send(val).unwrap(); +} + +pub fn main() { + let (tx, rx): (Sender, Receiver) = channel(); + foo(31337, tx); + assert_eq!(rx.recv().unwrap(), 31337); +} + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds-in-metadata.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-in-metadata.rs new file mode 100644 index 000000000000..19974dc35464 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-in-metadata.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(unused_imports)] + +// aux-build:trait_superkinds_in_metadata.rs + +// Tests (correct) usage of trait super-builtin-kinds cross-crate. + +extern crate trait_superkinds_in_metadata; +use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare}; +use trait_superkinds_in_metadata::RequiresCopy; +use std::marker; + +#[derive(Copy, Clone)] +struct X(T); + +impl RequiresShare for X { } + +impl RequiresRequiresShareAndSend for X { } + +impl RequiresCopy for X { } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds-phantom-typaram.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-phantom-typaram.rs new file mode 100644 index 000000000000..d7b99b5f1559 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-phantom-typaram.rs @@ -0,0 +1,19 @@ +// run-pass + +#![allow(dead_code)] +// Tests that even when a type parameter doesn't implement a required +// super-builtin-kind of a trait, if the type parameter is never used, +// the type can implement the trait anyway. + +// pretty-expanded FIXME #23616 + +use std::marker; + +trait Foo : Send { } + +struct X { marker: marker::PhantomData } + +impl Foo for X { } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds-simple.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-simple.rs new file mode 100644 index 000000000000..7e3727163cd5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-simple.rs @@ -0,0 +1,11 @@ +// run-pass +// Simple test case of implementing a trait with super-builtin-kinds. + +// pretty-expanded FIXME #23616 + +trait Foo : Send { } + +impl Foo for isize { } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds-typaram.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-typaram.rs new file mode 100644 index 000000000000..727e938f135e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds-typaram.rs @@ -0,0 +1,12 @@ +// run-pass +// Tests correct implementation of traits with super-builtin-kinds +// using a bounded type parameter. + +// pretty-expanded FIXME #23616 + +trait Foo : Send { } + +impl Foo for T { } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds/auxiliary/trait_superkinds_in_metadata.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds/auxiliary/trait_superkinds_in_metadata.rs new file mode 100644 index 000000000000..41e1f74cdac2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds/auxiliary/trait_superkinds_in_metadata.rs @@ -0,0 +1,9 @@ +// Test library crate for cross-crate usages of traits inheriting +// from the builtin kinds. Mostly tests metadata correctness. + +#![crate_type="lib"] + +pub trait RequiresShare : Sync { } +pub trait RequiresRequiresShareAndSend : RequiresShare + Send { } +pub trait RequiresCopy : Copy { } + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-double-superkind.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-double-superkind.rs new file mode 100644 index 000000000000..7a8a52235507 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-double-superkind.rs @@ -0,0 +1,15 @@ +// Test for traits that inherit from multiple builtin kinds at once, +// testing that all such kinds must be present on implementing types. + +trait Foo : Send+Sync { } + +impl Foo for (T,) { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +impl Foo for (T,T) { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +impl Foo for (T,T,T) { } // (ok) + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-in-metadata.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-in-metadata.rs new file mode 100644 index 000000000000..1b6b0e60ca5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-in-metadata.rs @@ -0,0 +1,17 @@ +// aux-build:trait_superkinds_in_metadata.rs + +// Test for traits inheriting from the builtin kinds cross-crate. +// Mostly tests correctness of metadata. + +extern crate trait_superkinds_in_metadata; +use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare}; + +struct X(T); + +impl RequiresShare for X { } + +impl RequiresRequiresShareAndSend for X { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-self-type.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-self-type.rs new file mode 100644 index 000000000000..19018ab3a74e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-self-type.rs @@ -0,0 +1,18 @@ +// Tests (negatively) the ability for the Self type in default methods +// to use capabilities granted by builtin kinds as supertraits. + +use std::sync::mpsc::{channel, Sender}; + +trait Foo : Sized+Sync+'static { + fn foo(self, mut chan: Sender) { } +} + +impl Foo for T { } +// { dg-error ".E0310." "" { target *-*-* } .-1 } + +fn main() { + let (tx, rx) = channel(); + 1193182.foo(tx); + assert_eq!(rx.recv(), 1193182); +} + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-simple.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-simple.rs new file mode 100644 index 000000000000..eeb46f337f0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-simple.rs @@ -0,0 +1,10 @@ +// Basic test for traits inheriting from the builtin kinds, checking +// the type contents of the implementing type (that's not a typaram). + +trait Foo : Send { } + +impl Foo for std::rc::Rc { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.rs b/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.rs new file mode 100644 index 000000000000..f9b55afabe83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.rs @@ -0,0 +1,9 @@ +// Basic test for traits inheriting from the builtin kinds. + +trait Foo : Send { } + +impl Foo for T { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/by-move-pattern-binding.rs b/gcc/testsuite/rust/rustc/ui/by-move-pattern-binding.rs new file mode 100644 index 000000000000..bde5eb4437b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/by-move-pattern-binding.rs @@ -0,0 +1,23 @@ +enum E { + Foo, + Bar(String) +} + +struct S { + x: E +} + +fn f(x: String) {} + +fn main() { + let s = S { x: E::Bar("hello".to_string()) }; + match &s.x { // { dg-error ".E0507." "" { target *-*-* } } + &E::Foo => {} + &E::Bar(identifier) => f(identifier.clone()) + }; + match &s.x { + &E::Foo => {} + &E::Bar(ref identifier) => println!("{}", *identifier) + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/byte-literals.rs b/gcc/testsuite/rust/rustc/ui/byte-literals.rs new file mode 100644 index 000000000000..8d38bc52f954 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/byte-literals.rs @@ -0,0 +1,68 @@ +// run-pass +// + + +static FOO: u8 = b'\xF0'; +static BAR: &'static [u8] = b"a\xF0\t"; +static BAR_FIXED: &'static [u8; 3] = b"a\xF0\t"; +static BAZ: &'static [u8] = br"a\n"; + +pub fn main() { + let bar: &'static [u8] = b"a\xF0\t"; + let bar_fixed: &'static [u8; 3] = b"a\xF0\t"; + + assert_eq!(b'a', 97u8); + assert_eq!(b'\n', 10u8); + assert_eq!(b'\r', 13u8); + assert_eq!(b'\t', 9u8); + assert_eq!(b'\\', 92u8); + assert_eq!(b'\'', 39u8); + assert_eq!(b'\"', 34u8); + assert_eq!(b'\0', 0u8); + assert_eq!(b'\xF0', 240u8); + assert_eq!(FOO, 240u8); + + match 42 { + b'*' => {}, + _ => panic!() + } + + match 100 { + b'a' ..= b'z' => {}, + _ => panic!() + } + + let expected: &[_] = &[97u8, 10u8, 13u8, 9u8, 92u8, 39u8, 34u8, 0u8, 240u8]; + assert_eq!(b"a\n\r\t\\\'\"\0\xF0", expected); + let expected: &[_] = &[97u8, 98u8]; + assert_eq!(b"a\ + b", expected); + let expected: &[_] = &[97u8, 240u8, 9u8]; + assert_eq!(BAR, expected); + assert_eq!(BAR_FIXED, expected); + assert_eq!(bar, expected); + assert_eq!(bar_fixed, expected); + + let val = &[97u8, 10u8]; + match val { + b"a\n" => {}, + _ => panic!(), + } + + let buf = vec![97u8, 98, 99, 100]; + assert_eq!(match &buf[0..3] { + b"def" => 1, + b"abc" => 2, + _ => 3 + }, 2); + + let expected: &[_] = &[97u8, 92u8, 110u8]; + assert_eq!(BAZ, expected); + let expected: &[_] = &[97u8, 92u8, 110u8]; + assert_eq!(br"a\n", expected); + assert_eq!(br"a\n", b"a\\n"); + let expected: &[_] = &[97u8, 34u8, 35u8, 35u8, 98u8]; + assert_eq!(br###"a"##b"###, expected); + assert_eq!(br###"a"##b"###, b"a\"##b"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/c-stack-returning-int64.rs b/gcc/testsuite/rust/rustc/ui/c-stack-returning-int64.rs new file mode 100644 index 000000000000..6d9876a9df86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/c-stack-returning-int64.rs @@ -0,0 +1,35 @@ +// run-pass +// ignore-wasm32-bare no libc to test with +// ignore-sgx no libc + +#![feature(rustc_private)] + +extern crate libc; + +use std::ffi::CString; + +mod mlibc { + use libc::{c_char, c_long, c_longlong}; + + extern { + pub fn atol(x: *const c_char) -> c_long; + pub fn atoll(x: *const c_char) -> c_longlong; + } +} + +fn atol(s: String) -> isize { + let c = CString::new(s).unwrap(); + unsafe { mlibc::atol(c.as_ptr()) as isize } +} + +fn atoll(s: String) -> i64 { + let c = CString::new(s).unwrap(); + unsafe { mlibc::atoll(c.as_ptr()) as i64 } +} + +pub fn main() { + assert_eq!(atol("1024".to_string()) * 10, atol("10240".to_string())); + assert_eq!((atoll("11111111111111111".to_string()) * 10), + atoll("111111111111111110".to_string())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-1.rs b/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-1.rs new file mode 100644 index 000000000000..3f7983549804 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-1.rs @@ -0,0 +1,31 @@ +// ignore-arm stdcall isn't supported +// ignore-aarch64 stdcall isn't supported +// ignore-riscv64 stdcall isn't supported + +extern "stdcall" { + fn printf(_: *const u8, ...); // { dg-error ".E0045." "" { target *-*-* } } +} + +extern { + fn foo(f: isize, x: u8, ...); +} + +extern "C" fn bar(f: isize, x: u8) {} + +fn main() { + unsafe { + foo(); // { dg-error ".E0060." "" { target *-*-* } } + foo(1); // { dg-error ".E0060." "" { target *-*-* } } + + let x: unsafe extern "C" fn(f: isize, x: u8) = foo; // { dg-error ".E0308." "" { target *-*-* } } + let y: extern "C" fn(f: isize, x: u8, ...) = bar; // { dg-error ".E0308." "" { target *-*-* } } + + foo(1, 2, 3f32); // { dg-error ".E0617." "" { target *-*-* } } + foo(1, 2, true); // { dg-error ".E0617." "" { target *-*-* } } + foo(1, 2, 1i8); // { dg-error ".E0617." "" { target *-*-* } } + foo(1, 2, 1u8); // { dg-error ".E0617." "" { target *-*-* } } + foo(1, 2, 1i16); // { dg-error ".E0617." "" { target *-*-* } } + foo(1, 2, 1u16); // { dg-error ".E0617." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-2.rs b/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-2.rs new file mode 100644 index 000000000000..65e435f0f7a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-2.rs @@ -0,0 +1,9 @@ +// ignore-arm stdcall isn't supported + +fn baz(f: extern "stdcall" fn(usize, ...)) { +// { dg-error ".E0045." "" { target *-*-* } .-1 } + f(22, 44); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-4.rs b/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-4.rs new file mode 100644 index 000000000000..f6742575bf45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-4.rs @@ -0,0 +1,39 @@ +#![crate_type = "lib"] +#![no_std] +#![feature(c_variadic)] + +use core::ffi::{VaList, VaListImpl}; + +pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { + ap +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { + ap // { dg-error "" "" { target *-*-* } } +} + +pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) { + let _ = ap.with_copy(|ap| ap); // { dg-error "" "" { target *-*-* } } +} + +pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + *ap0 = ap1; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + ap0 = &mut ap1; +// { dg-error ".E0597." "" { target *-*-* } .-1 } +// { dg-error ".E0597." "" { target *-*-* } .-2 } +// { dg-error ".E0597." "" { target *-*-* } .-3 } +} + +pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { + *ap0 = ap1.clone(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-6.rs b/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-6.rs new file mode 100644 index 000000000000..574cc52288f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-6.rs @@ -0,0 +1,14 @@ +#![crate_type="lib"] +#![feature(c_variadic)] + +pub unsafe extern "C" fn use_vararg_lifetime( + x: usize, + y: ... +) -> &usize { // { dg-error ".E0106." "" { target *-*-* } } + &0 +} + +pub unsafe extern "C" fn use_normal_arg_lifetime(x: &usize, y: ...) -> &usize { // OK + x +} + diff --git a/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-no-fixed-args.rs b/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-no-fixed-args.rs new file mode 100644 index 000000000000..b80afba00cf8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/c-variadic/variadic-ffi-no-fixed-args.rs @@ -0,0 +1,7 @@ +extern { + fn foo(...); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/can-begin-expr-check.rs b/gcc/testsuite/rust/rustc/ui/can-begin-expr-check.rs new file mode 100644 index 000000000000..d565ff492f0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/can-begin-expr-check.rs @@ -0,0 +1,21 @@ +pub fn main() { + + return; + return (); + return as (); + return return as (); + return return return; + + return if true { + () + } else { + () + }; + + loop { + return break as (); + } + + return enum; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/can-copy-pod.rs b/gcc/testsuite/rust/rustc/ui/can-copy-pod.rs new file mode 100644 index 000000000000..d71a196124b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/can-copy-pod.rs @@ -0,0 +1,17 @@ +// run-pass +// pretty-expanded FIXME #23616 + +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Tests that type parameters with the `Copy` are implicitly copyable. + +#![allow(dead_code)] + +fn can_copy_copy(v: T) { + let _a = v; + let _b = v; +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/cancel-clean-via-immediate-rvalue-ref.rs b/gcc/testsuite/rust/rustc/ui/cancel-clean-via-immediate-rvalue-ref.rs new file mode 100644 index 000000000000..e83bc77d1593 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cancel-clean-via-immediate-rvalue-ref.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +fn foo(x: &mut Box) { + *x = box 5; +} + +pub fn main() { + foo(&mut box 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cannot-mutate-captured-non-mut-var.rs b/gcc/testsuite/rust/rustc/ui/cannot-mutate-captured-non-mut-var.rs new file mode 100644 index 000000000000..02082fddefb7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cannot-mutate-captured-non-mut-var.rs @@ -0,0 +1,16 @@ +#![feature(unboxed_closures)] + +use std::io::Read; + +fn to_fn_once>(f: F) -> F { f } + +fn main() { + let x = 1; + to_fn_once(move|| { x = 2; }); +// { dg-error ".E0594." "" { target *-*-* } .-1 } + + let s = std::io::stdin(); + to_fn_once(move|| { s.read_to_end(&mut Vec::new()); }); +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/capture1.rs b/gcc/testsuite/rust/rustc/ui/capture1.rs new file mode 100644 index 000000000000..1f2a1c725dcd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/capture1.rs @@ -0,0 +1,7 @@ +// error-pattern: can't capture dynamic environment in a fn item + +fn main() { + let bar: isize = 5; + fn foo() -> isize { return bar; } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cast-char.rs b/gcc/testsuite/rust/rustc/ui/cast-char.rs new file mode 100644 index 000000000000..038c309ed2a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast-char.rs @@ -0,0 +1,11 @@ +#![deny(overflowing_literals)] + +fn main() { + const XYZ: char = 0x1F888 as char; +// { dg-error "" "" { target *-*-* } .-1 } + const XY: char = 129160 as char; +// { dg-error "" "" { target *-*-* } .-1 } + const ZYX: char = '\u{01F888}'; + println!("{}", XYZ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cast-does-fallback.rs b/gcc/testsuite/rust/rustc/ui/cast-does-fallback.rs new file mode 100644 index 000000000000..5f3ebc23ae27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast-does-fallback.rs @@ -0,0 +1,13 @@ +// run-pass + +pub fn main() { + // Test that these type check correctly. + (&42u8 >> 4) as usize; + (&42u8 << 4) as usize; + + let cap = 512 * 512; + cap as u8; + // Assert `cap` did not get inferred to `u8` and overflowed. + assert_ne!(cap, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cast-region-to-uint.rs b/gcc/testsuite/rust/rustc/ui/cast-region-to-uint.rs new file mode 100644 index 000000000000..58d154edb01f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast-region-to-uint.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + let x: isize = 3; + println!("&x={:x}", (&x as *const isize as usize)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cast-rfc0401-vtable-kinds.rs b/gcc/testsuite/rust/rustc/ui/cast-rfc0401-vtable-kinds.rs new file mode 100644 index 000000000000..12bc9d190a18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast-rfc0401-vtable-kinds.rs @@ -0,0 +1,63 @@ +// run-pass +// Check that you can cast between different pointers to trait objects +// whose vtable have the same kind (both lengths, or both trait pointers). + +#![feature(unsized_tuple_coercion)] + +trait Foo { + fn foo(&self, _: T) -> u32 { 42 } +} + +trait Bar { + fn bar(&self) { println!("Bar!"); } +} + +impl Foo for () {} +impl Foo for u32 { fn foo(&self, _: u32) -> u32 { self+43 } } +impl Bar for () {} + +unsafe fn round_trip_and_call<'a>(t: *const (dyn Foo+'a)) -> u32 { + let foo_e : *const dyn Foo = t as *const _; + let r_1 = foo_e as *mut dyn Foo; + + (&*r_1).foo(0) +} + +#[repr(C)] +struct FooS(T); +#[repr(C)] +struct BarS(T); + +fn foo_to_bar(u: *const FooS) -> *const BarS { + u as *const BarS +} + +fn tuple_i32_to_u32(u: *const (i32, T)) -> *const (u32, T) { + u as *const (u32, T) +} + + +fn main() { + let x = 4u32; + let y : &dyn Foo = &x; + let fl = unsafe { round_trip_and_call(y as *const dyn Foo) }; + assert_eq!(fl, (43+4)); + + let s = FooS([0,1,2]); + let u: &FooS<[u32]> = &s; + let u: *const FooS<[u32]> = u; + let bar_ref : *const BarS<[u32]> = foo_to_bar(u); + let z : &BarS<[u32]> = unsafe{&*bar_ref}; + assert_eq!(&z.0, &[0,1,2]); + + // this assumes that tuple reprs for (i32, _) and (u32, _) are + // the same. + let s = (0i32, [0, 1, 2]); + let u: &(i32, [u8]) = &s; + let u: *const (i32, [u8]) = u; + let u_u32 : *const (u32, [u8]) = tuple_i32_to_u32(u); + unsafe { + assert_eq!(&(*u_u32).1, &[0, 1, 2]); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cast-rfc0401.rs b/gcc/testsuite/rust/rustc/ui/cast-rfc0401.rs new file mode 100644 index 000000000000..b0ac10c5375f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast-rfc0401.rs @@ -0,0 +1,174 @@ +// run-pass + +#![allow(dead_code)] + +use std::vec; + +enum Simple { + A, + B, + C +} + +enum Valued { + H8=163, + Z=0, + X=256, + H7=67, +} + +enum ValuedSigned { + M1=-1, + P1=1 +} + +fn main() +{ + // coercion-cast + let mut it = vec![137].into_iter(); + let itr: &mut vec::IntoIter = &mut it; + assert_eq!((itr as &mut dyn Iterator).next(), Some(137)); + assert_eq!((itr as &mut dyn Iterator).next(), None); + + assert_eq!(Some(4u32) as Option, Some(4u32)); + assert_eq!((1u32,2u32) as (u32,u32), (1,2)); + + // this isn't prim-int-cast. Check that it works. + assert_eq!(false as bool, false); + assert_eq!(true as bool, true); + + // numeric-cast + let l: u64 = 0x8090a0b0c0d0e0f0; + let lsz: usize = l as usize; + assert_eq!(l as u32, 0xc0d0e0f0); + + // numeric-cast + assert_eq!(l as u8, 0xf0); + assert_eq!(l as i8,-0x10); + assert_eq!(l as u32, 0xc0d0e0f0); + assert_eq!(l as u32 as usize as u32, l as u32); + assert_eq!(l as i32,-0x3f2f1f10); + assert_eq!(l as i32 as isize as i32, l as i32); + assert_eq!(l as i64,-0x7f6f5f4f3f2f1f10); + + assert_eq!(0 as f64, 0f64); + assert_eq!(1 as f64, 1f64); + + assert_eq!(l as f64, 9264081114510712022f64); + + assert_eq!(l as i64 as f64, -9182662959198838444f64); +// float overflow : needs fixing +// assert_eq!(l as f32 as i64 as u64, 9264082620822882088u64); +// assert_eq!(l as i64 as f32 as i64, 9182664080220408446i64); + + assert_eq!(4294967040f32 as u32, 0xffffff00u32); + assert_eq!(1.844674407370955e19f64 as u64, 0xfffffffffffff800u64); + + assert_eq!(9.223372036854775e18f64 as i64, 0x7ffffffffffffc00i64); + assert_eq!(-9.223372036854776e18f64 as i64, 0x8000000000000000u64 as i64); + + // addr-ptr-cast/ptr-addr-cast (thin ptr) + let p: *const [u8; 1] = lsz as *const [u8; 1]; + assert_eq!(p as usize, lsz); + + // ptr-ptr-cast (thin ptr) + let w: *const () = p as *const (); + assert_eq!(w as usize, lsz); + + // ptr-ptr-cast (fat->thin) + let u: *const [u8] = unsafe{&*p}; + assert_eq!(u as *const u8, p as *const u8); + assert_eq!(u as *const u16, p as *const u16); + + // ptr-ptr-cast (Length vtables) + let mut l : [u8; 2] = [0,1]; + let w: *mut [u16; 2] = &mut l as *mut [u8; 2] as *mut _; + let w: *mut [u16] = unsafe {&mut *w}; + let w_u8 : *const [u8] = w as *const [u8]; + assert_eq!(unsafe{&*w_u8}, &l); + + let s: *mut str = w as *mut str; + let l_via_str = unsafe{&*(s as *const [u8])}; + assert_eq!(&l, l_via_str); + + // ptr-ptr-cast (Length vtables, check length is preserved) + let l: [[u8; 3]; 2] = [[3, 2, 6], [4, 5, 1]]; + let p: *const [[u8; 3]] = &l; + let p: &[[u8; 2]] = unsafe {&*(p as *const [[u8; 2]])}; + assert_eq!(p, [[3, 2], [6, 4]]); + + // enum-cast + assert_eq!(Simple::A as u8, 0); + assert_eq!(Simple::B as u8, 1); + + assert_eq!(Valued::H8 as i8, -93); + assert_eq!(Valued::H7 as i8, 67); + assert_eq!(Valued::Z as i8, 0); + + assert_eq!(Valued::H8 as u8, 163); + assert_eq!(Valued::H7 as u8, 67); + assert_eq!(Valued::Z as u8, 0); + + assert_eq!(Valued::H8 as u16, 163); + assert_eq!(Valued::Z as u16, 0); + assert_eq!(Valued::H8 as u16, 163); + assert_eq!(Valued::Z as u16, 0); + + assert_eq!(ValuedSigned::M1 as u16, 65535); + assert_eq!(ValuedSigned::M1 as i16, -1); + assert_eq!(ValuedSigned::P1 as u16, 1); + assert_eq!(ValuedSigned::P1 as i16, 1); + + // prim-int-cast + assert_eq!(false as u16, 0); + assert_eq!(true as u16, 1); + assert_eq!(false as i64, 0); + assert_eq!(true as i64, 1); + assert_eq!('a' as u32, 0x61); + assert_eq!('a' as u16, 0x61); + assert_eq!('a' as u8, 0x61); + assert_eq!('א' as u8, 0xd0); + assert_eq!('א' as u16, 0x5d0); + assert_eq!('א' as u32, 0x5d0); + assert_eq!('🐵' as u8, 0x35); + assert_eq!('🐵' as u16, 0xf435); + assert_eq!('🐵' as u32, 0x1f435); + assert_eq!('英' as i16, -0x7d0f); + assert_eq!('英' as u16, 0x82f1); + + // u8-char-cast + assert_eq!(0x61 as char, 'a'); + assert_eq!(0u8 as char, '\0'); + assert_eq!(0xd7 as char, '×'); + + // array-ptr-cast + let x = [1,2,3]; + let first : *const u32 = &x[0]; + + assert_eq!(first, &x as *const _); + assert_eq!(first, &x as *const u32); + + // fptr-addr-cast + fn foo() { + println!("foo!"); + } + fn bar() { + println!("bar!"); + } + + assert!(foo as usize != bar as usize); + + // Taking a few bits of a function's address is totally pointless and we detect that + // Disabling the lint to ensure that the assertion can still be run + #[allow(const_err)] + { + assert_eq!(foo as i16, foo as usize as i16); + } + + // fptr-ptr-cast + + assert_eq!(foo as *const u8 as usize, foo as usize); + assert!(foo as *const u32 != first); +} +fn foo() { } + diff --git a/gcc/testsuite/rust/rustc/ui/cast-to-infer-ty.rs b/gcc/testsuite/rust/rustc/ui/cast-to-infer-ty.rs new file mode 100644 index 000000000000..caecc7e97857 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast-to-infer-ty.rs @@ -0,0 +1,9 @@ +// run-pass +// Check that we allow a cast to `_` so long as the target type can be +// inferred elsewhere. + +pub fn main() { + let i: *const i32 = 0 as _; + assert!(i.is_null()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cast.rs b/gcc/testsuite/rust/rustc/ui/cast.rs new file mode 100644 index 000000000000..532b4832c743 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast.rs @@ -0,0 +1,22 @@ +// run-pass + +#![allow(unused_assignments)] +#![allow(unused_variables)] + +pub fn main() { + let i: isize = 'Q' as isize; + assert_eq!(i, 0x51); + let u: u32 = i as u32; + assert_eq!(u, 0x51 as u32); + assert_eq!(u, 'Q' as u32); + assert_eq!(i as u8, 'Q' as u8); + assert_eq!(i as u8 as i8, 'Q' as u8 as i8); + assert_eq!(0x51 as char, 'Q'); + assert_eq!(0 as u32, false as u32); + + // Test that `_` is correctly inferred. + let x = &"hello"; + let mut y = x as *const _; + y = core::ptr::null_mut(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cast/cast-as-bool.rs b/gcc/testsuite/rust/rustc/ui/cast/cast-as-bool.rs new file mode 100644 index 000000000000..259d71328421 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast/cast-as-bool.rs @@ -0,0 +1,10 @@ +fn main() { + let u = 5 as bool; // { dg-error ".E0054." "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + let t = (1 + 2) as bool; // { dg-error ".E0054." "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + let v = "hello" as bool; // { dg-error ".E0606." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cast/cast-errors-issue-43825.rs b/gcc/testsuite/rust/rustc/ui/cast/cast-errors-issue-43825.rs new file mode 100644 index 000000000000..d827b72ceeae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast/cast-errors-issue-43825.rs @@ -0,0 +1,8 @@ +fn main() { + let error = error; // { dg-error ".E0425." "" { target *-*-* } } + + // These used to cause errors. + 0 as f32; + 0.0 as u32; +} + diff --git a/gcc/testsuite/rust/rustc/ui/cast/cast-from-nil.rs b/gcc/testsuite/rust/rustc/ui/cast/cast-from-nil.rs new file mode 100644 index 000000000000..657ad9293489 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast/cast-from-nil.rs @@ -0,0 +1,3 @@ +// error-pattern: non-primitive cast: `()` as `u32` +fn main() { let u = (assert!(true) as u32); } + diff --git a/gcc/testsuite/rust/rustc/ui/cast/cast-ptr-to-int-const.rs b/gcc/testsuite/rust/rustc/ui/cast/cast-ptr-to-int-const.rs new file mode 100644 index 000000000000..428b798125bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast/cast-ptr-to-int-const.rs @@ -0,0 +1,12 @@ +// gate-test-const_raw_ptr_to_usize_cast + +fn main() { + const X: u32 = unsafe { + main as u32 // { dg-error ".E0658." "" { target *-*-* } } + }; + const Y: u32 = 0; + const Z: u32 = unsafe { + &Y as *const u32 as u32 // { dg-error ".E0658." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/cast/cast-rfc0401-2.rs b/gcc/testsuite/rust/rustc/ui/cast/cast-rfc0401-2.rs new file mode 100644 index 000000000000..cc9248060137 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast/cast-rfc0401-2.rs @@ -0,0 +1,9 @@ +// RFC 401 test extracted into distinct file. This is because some the +// change to suppress "derived" errors wound up suppressing this error +// message, since the fallback for `3` doesn't occur. + +fn main() { + let _ = 3 as bool; +// { dg-error ".E0054." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cast/cast-to-bare-fn.rs b/gcc/testsuite/rust/rustc/ui/cast/cast-to-bare-fn.rs new file mode 100644 index 000000000000..523b37cc907e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast/cast-to-bare-fn.rs @@ -0,0 +1,11 @@ +fn foo(_x: isize) { } + +fn main() { + let v: u64 = 5; + let x = foo as extern "C" fn() -> isize; +// { dg-error ".E0605." "" { target *-*-* } .-1 } + let y = v as extern "Rust" fn(isize) -> (isize, isize); +// { dg-error ".E0605." "" { target *-*-* } .-1 } + y(x()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cast/cast-to-nil.rs b/gcc/testsuite/rust/rustc/ui/cast/cast-to-nil.rs new file mode 100644 index 000000000000..d7bf21686a29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast/cast-to-nil.rs @@ -0,0 +1,3 @@ +// error-pattern: non-primitive cast: `u32` as `()` +fn main() { let u = 0u32 as (); } + diff --git a/gcc/testsuite/rust/rustc/ui/cast/cast-to-unsized-trait-object-suggestion.rs b/gcc/testsuite/rust/rustc/ui/cast/cast-to-unsized-trait-object-suggestion.rs new file mode 100644 index 000000000000..79107e93168a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cast/cast-to-unsized-trait-object-suggestion.rs @@ -0,0 +1,5 @@ +fn main() { + &1 as dyn Send; // { dg-error ".E0620." "" { target *-*-* } } + Box::new(1) as dyn Send; // { dg-error ".E0620." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/casts-differing-anon.rs b/gcc/testsuite/rust/rustc/ui/casts-differing-anon.rs new file mode 100644 index 000000000000..7e024c2c5df1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/casts-differing-anon.rs @@ -0,0 +1,23 @@ +use std::fmt; + +fn foo() -> Box { + let x : Box<[u8]> = Box::new([0]); + x +} +fn bar() -> Box { + let y: Box = Box::new([0]); + y +} + +fn main() { + let f = foo(); + let b = bar(); + + // this is an `*mut [u8]` in practice + let f_raw : *mut _ = Box::into_raw(f); + // this is an `*mut fmt::Debug` in practice + let mut b_raw = Box::into_raw(b); + // ... and they should not be mixable + b_raw = f_raw as *mut _; // { dg-error ".E0606." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/casts-issue-46365.rs b/gcc/testsuite/rust/rustc/ui/casts-issue-46365.rs new file mode 100644 index 000000000000..14b027b90be5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/casts-issue-46365.rs @@ -0,0 +1,8 @@ +struct Lorem { + ipsum: Ipsum // { dg-error ".E0412." "" { target *-*-* } } +} + +fn main() { + let _foo: *mut Lorem = core::ptr::null_mut(); // no error here +} + diff --git a/gcc/testsuite/rust/rustc/ui/catch-unwind-bang.rs b/gcc/testsuite/rust/rustc/ui/catch-unwind-bang.rs new file mode 100644 index 000000000000..9bee6b6e2da4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/catch-unwind-bang.rs @@ -0,0 +1,11 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default + +fn worker() -> ! { + panic!() +} + +fn main() { + std::panic::catch_unwind(worker).unwrap_err(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cenum_impl_drop_cast.rs b/gcc/testsuite/rust/rustc/ui/cenum_impl_drop_cast.rs new file mode 100644 index 000000000000..39f78a2fbbab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cenum_impl_drop_cast.rs @@ -0,0 +1,19 @@ +#![deny(cenum_impl_drop_cast)] + +enum E { + A = 0, +} + +impl Drop for E { + fn drop(&mut self) { + println!("Drop"); + } +} + +fn main() { + let e = E::A; + let i = e as u32; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg-rustdoc.rs b/gcc/testsuite/rust/rustc/ui/cfg-rustdoc.rs new file mode 100644 index 000000000000..4326339bd22c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg-rustdoc.rs @@ -0,0 +1,7 @@ +#[cfg(doc)] +pub struct Foo; + +fn main() { + let f = Foo; // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/auxiliary/cfg_inner_static.rs b/gcc/testsuite/rust/rustc/ui/cfg/auxiliary/cfg_inner_static.rs new file mode 100644 index 000000000000..c10b456e5b7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/auxiliary/cfg_inner_static.rs @@ -0,0 +1,8 @@ +// this used to just ICE on compiling +pub fn foo() { + if cfg!(foo) { + static a: isize = 3; + a + } else { 3 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs b/gcc/testsuite/rust/rustc/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs new file mode 100644 index 000000000000..7a08fbfc7dfc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/auxiliary/crate-attributes-using-cfg_attr.rs @@ -0,0 +1,7 @@ +// no-prefer-dynamic +// compile-flags: --cfg foo + +#![cfg_attr(foo, crate_type="lib")] + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg-attr-cfg.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg-attr-cfg.rs new file mode 100644 index 000000000000..4ac94ee16102 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg-attr-cfg.rs @@ -0,0 +1,9 @@ +// run-pass +// main is conditionally compiled, but the conditional compilation +// is conditional too! + +// pretty-expanded FIXME #23616 + +#[cfg_attr(foo, cfg(bar))] +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg-attr-crate.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg-attr-crate.rs new file mode 100644 index 000000000000..0391a4ed1bbc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg-attr-crate.rs @@ -0,0 +1,9 @@ +// run-pass +// https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044 + +// pretty-expanded FIXME #23616 + +#![cfg_attr(not_used, no_core)] + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg-family.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg-family.rs new file mode 100644 index 000000000000..a926d2ca6d01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg-family.rs @@ -0,0 +1,14 @@ +// run-pass +// pretty-expanded FIXME #23616 +// ignore-cloudabi no target_family +// ignore-wasm32-bare no target_family +// ignore-sgx + +#[cfg(windows)] +pub fn main() { +} + +#[cfg(unix)] +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg-in-crate-1.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg-in-crate-1.rs new file mode 100644 index 000000000000..2cce5ac93767 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg-in-crate-1.rs @@ -0,0 +1,6 @@ +// run-pass +// compile-flags: --cfg bar -D warnings +#![cfg(bar)] + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg-macros-foo.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg-macros-foo.rs new file mode 100644 index 000000000000..0e969e61e4a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg-macros-foo.rs @@ -0,0 +1,27 @@ +// run-pass +// compile-flags: --cfg foo + +// check that cfg correctly chooses between the macro impls (see also +// cfg-macros-notfoo.rs) + + +#[cfg(foo)] +#[macro_use] +mod foo { + macro_rules! bar { + () => { true } + } +} + +#[cfg(not(foo))] +#[macro_use] +mod foo { + macro_rules! bar { + () => { false } + } +} + +pub fn main() { + assert!(bar!()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg-macros-notfoo.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg-macros-notfoo.rs new file mode 100644 index 000000000000..9a2053441292 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg-macros-notfoo.rs @@ -0,0 +1,27 @@ +// run-pass +// compile-flags: + +// check that cfg correctly chooses between the macro impls (see also +// cfg-macros-foo.rs) + + +#[cfg(foo)] +#[macro_use] +mod foo { + macro_rules! bar { + () => { true } + } +} + +#[cfg(not(foo))] +#[macro_use] +mod foo { + macro_rules! bar { + () => { false } + } +} + +pub fn main() { + assert!(!bar!()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg-match-arm.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg-match-arm.rs new file mode 100644 index 000000000000..b703a7d12e0b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg-match-arm.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +enum Foo { + Bar, + Baz, +} + +fn foo(f: Foo) { + match f { + Foo::Bar => {}, + #[cfg(not(asdfa))] + Foo::Baz => {}, + #[cfg(afsd)] + Basdfwe => {} + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg-panic-abort.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg-panic-abort.rs new file mode 100644 index 000000000000..dd04bfb382c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg-panic-abort.rs @@ -0,0 +1,17 @@ +// build-pass +// compile-flags: -C panic=abort +// no-prefer-dynamic +#![feature(cfg_panic)] + +#[cfg(panic = "unwind")] +pub fn bad() -> i32 { } + +#[cfg(not(panic = "abort"))] +pub fn bad() -> i32 { } + +#[cfg(panic = "some_imaginary_future_panic_handler")] +pub fn bad() -> i32 { } + +#[cfg(panic = "abort")] +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg-panic.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg-panic.rs new file mode 100644 index 000000000000..3d715e196769 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg-panic.rs @@ -0,0 +1,19 @@ +// build-pass +// compile-flags: -C panic=unwind +// ignore-emscripten no panic_unwind implementation +// ignore-wasm32 no panic_unwind implementation +// ignore-wasm64 no panic_unwind implementation +#![feature(cfg_panic)] + +#[cfg(panic = "abort")] +pub fn bad() -> i32 { } + +#[cfg(not(panic = "unwind"))] +pub fn bad() -> i32 { } + +#[cfg(panic = "some_imaginary_future_panic_handler")] +pub fn bad() -> i32 { } + +#[cfg(panic = "unwind")] +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg-target-family.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg-target-family.rs new file mode 100644 index 000000000000..d61a7b2a4656 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg-target-family.rs @@ -0,0 +1,15 @@ +// run-pass +// ignore-cloudabi no target_family +// ignore-wasm32-bare no target_family +// ignore-sgx + +// pretty-expanded FIXME #23616 + +#[cfg(target_family = "windows")] +pub fn main() { +} + +#[cfg(target_family = "unix")] +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg-target-vendor.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg-target-vendor.rs new file mode 100644 index 000000000000..84dfa1373c57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg-target-vendor.rs @@ -0,0 +1,9 @@ +// run-pass +#[cfg(target_vendor = "unknown")] +pub fn main() { +} + +#[cfg(not(target_vendor = "unknown"))] +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg_attr.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg_attr.rs new file mode 100644 index 000000000000..0a03f60b7aee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg_attr.rs @@ -0,0 +1,51 @@ +// run-pass +// compile-flags:--cfg set1 --cfg set2 +#![allow(dead_code)] +use std::fmt::Debug; + +struct NotDebugable; + +#[cfg_attr(set1, derive(Debug))] +struct Set1; + +#[cfg_attr(notset, derive(Debug))] +struct Notset(NotDebugable); + +#[cfg_attr(not(notset), derive(Debug))] +struct NotNotset; + +#[cfg_attr(not(set1), derive(Debug))] +struct NotSet1(NotDebugable); + +#[cfg_attr(all(set1, set2), derive(Debug))] +struct AllSet1Set2; + +#[cfg_attr(all(set1, notset), derive(Debug))] +struct AllSet1Notset(NotDebugable); + +#[cfg_attr(any(set1, notset), derive(Debug))] +struct AnySet1Notset; + +#[cfg_attr(any(notset, notset2), derive(Debug))] +struct AnyNotsetNotset2(NotDebugable); + +#[cfg_attr(all(not(notset), any(set1, notset)), derive(Debug))] +struct Complex; + +#[cfg_attr(any(notset, not(any(set1, notset))), derive(Debug))] +struct ComplexNot(NotDebugable); + +#[cfg_attr(any(target_endian = "little", target_endian = "big"), derive(Debug))] +struct KeyValue; + +fn is_show() {} + +fn main() { + is_show::(); + is_show::(); + is_show::(); + is_show::(); + is_show::(); + is_show::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg_inner_static.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg_inner_static.rs new file mode 100644 index 000000000000..dc894920c0e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg_inner_static.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:cfg_inner_static.rs + +// pretty-expanded FIXME #23616 + +extern crate cfg_inner_static; + +pub fn main() { + cfg_inner_static::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfg_stmt_expr.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfg_stmt_expr.rs new file mode 100644 index 000000000000..94cbaf6acfd9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfg_stmt_expr.rs @@ -0,0 +1,93 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_mut)] +#![allow(unused_variables)] +#![deny(non_snake_case)] +#![feature(stmt_expr_attributes)] + +fn main() { + let a = 413; + #[cfg(unset)] + let a = (); + assert_eq!(a, 413); + + let mut b = 612; + #[cfg(unset)] + { + b = 1111; + } + assert_eq!(b, 612); + + #[cfg(unset)] + undefined_fn(); + + #[cfg(unset)] + undefined_macro!(); + #[cfg(unset)] + undefined_macro![]; + #[cfg(unset)] + undefined_macro!{}; + + // pretty printer bug... + // #[cfg(unset)] + // undefined_macro!{} + + let () = (#[cfg(unset)] 341,); // Should this also work on parens? + let t = (1, #[cfg(unset)] 3, 4); + assert_eq!(t, (1, 4)); + + let f = |_: u32, _: u32| (); + f(2, 1, #[cfg(unset)] 6); + + let _: u32 = a.clone(#[cfg(unset)] undefined); + + let _: [(); 0] = [#[cfg(unset)] 126]; + let t = [#[cfg(unset)] 1, 2, 6]; + assert_eq!(t, [2, 6]); + + { + let r; + #[cfg(unset)] + (r = 5); + #[cfg(not(unset))] + (r = 10); + assert_eq!(r, 10); + } + + // check that macro expanded code works + + macro_rules! if_cfg { + ($cfg:meta? $ib:block else $eb:block) => { + { + let r; + #[cfg($cfg)] + (r = $ib); + #[cfg(not($cfg))] + (r = $eb); + r + } + } + } + + let n = if_cfg!(unset? { + 413 + } else { + 612 + }); + + assert_eq!((#[cfg(unset)] 1, #[cfg(not(unset))] 2), (2,)); + assert_eq!(n, 612); + + // check that lints work + + #[allow(non_snake_case)] + let FOOBAR = { + fn SYLADEX() {} + }; + + #[allow(non_snake_case)] + { + fn CRUXTRUDER() {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/cfgs-on-items.rs b/gcc/testsuite/rust/rustc/ui/cfg/cfgs-on-items.rs new file mode 100644 index 000000000000..93fff451296f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/cfgs-on-items.rs @@ -0,0 +1,30 @@ +// run-pass +// compile-flags: --cfg fooA --cfg fooB + +// fooA AND !bar + +#[cfg(all(fooA, not(bar)))] +fn foo1() -> isize { 1 } + +// !fooA AND !bar +#[cfg(all(not(fooA), not(bar)))] +fn foo2() -> isize { 2 } + +// fooC OR (fooB AND !bar) +#[cfg(any(fooC, all(fooB, not(bar))))] +fn foo2() -> isize { 3 } + +// fooA AND bar +#[cfg(all(fooA, bar))] +fn foo3() -> isize { 2 } + +// !(fooA AND bar) +#[cfg(not(all(fooA, bar)))] +fn foo3() -> isize { 3 } + +pub fn main() { + assert_eq!(1, foo1()); + assert_eq!(3, foo2()); + assert_eq!(3, foo3()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/conditional-compile-arch.rs b/gcc/testsuite/rust/rustc/ui/cfg/conditional-compile-arch.rs new file mode 100644 index 000000000000..1a02316b6580 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/conditional-compile-arch.rs @@ -0,0 +1,42 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#[cfg(target_arch = "x86")] +pub fn main() { } + +#[cfg(target_arch = "x86_64")] +pub fn main() { } + +#[cfg(target_arch = "arm")] +pub fn main() { } + +#[cfg(target_arch = "aarch64")] +pub fn main() { } + +#[cfg(target_arch = "mips")] +pub fn main() { } + +#[cfg(target_arch = "mips64")] +pub fn main() { } + +#[cfg(target_arch = "powerpc")] +pub fn main() { } + +#[cfg(target_arch = "powerpc64")] +pub fn main() { } + +#[cfg(target_arch = "s390x")] +pub fn main() { } + +#[cfg(target_arch = "asmjs")] +pub fn main() { } + +#[cfg(target_arch = "wasm32")] +pub fn main() { } + +#[cfg(target_arch = "sparc64")] +pub fn main() { } + +#[cfg(target_arch = "riscv64")] +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/conditional-compile.rs b/gcc/testsuite/rust/rustc/ui/cfg/conditional-compile.rs new file mode 100644 index 000000000000..45be7488367b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/conditional-compile.rs @@ -0,0 +1,150 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(improper_ctypes)] + +// Crate use statements + +#[cfg(bogus)] +use flippity; + +#[cfg(bogus)] +static b: bool = false; + +static b: bool = true; + +mod rustrt { + #[cfg(bogus)] + extern { + // This symbol doesn't exist and would be a link error if this + // module was codegened + pub fn bogus(); + } + + extern {} +} + +#[cfg(bogus)] +type t = isize; + +type t = bool; + +#[cfg(bogus)] +enum tg { foo, } + +enum tg { bar, } + +#[cfg(bogus)] +struct r { + i: isize, +} + +#[cfg(bogus)] +fn r(i:isize) -> r { + r { + i: i + } +} + +struct r { + i: isize, +} + +fn r(i:isize) -> r { + r { + i: i + } +} + +#[cfg(bogus)] +mod m { + // This needs to parse but would fail in typeck. Since it's not in + // the current config it should not be typechecked. + pub fn bogus() { return 0; } +} + +mod m { + // Submodules have slightly different code paths than the top-level + // module, so let's make sure this jazz works here as well + #[cfg(bogus)] + pub fn f() { } + + pub fn f() { } +} + +// Since the bogus configuration isn't defined main will just be +// parsed, but nothing further will be done with it +#[cfg(bogus)] +pub fn main() { panic!() } + +pub fn main() { + // Exercise some of the configured items in ways that wouldn't be possible + // if they had the bogus definition + assert!((b)); + let _x: t = true; + let _y: tg = tg::bar; + + test_in_fn_ctxt(); +} + +fn test_in_fn_ctxt() { + #[cfg(bogus)] + fn f() { panic!() } + fn f() { } + f(); + + #[cfg(bogus)] + static i: isize = 0; + static i: isize = 1; + assert_eq!(i, 1); +} + +mod test_foreign_items { + pub mod rustrt { + extern { + #[cfg(bogus)] + pub fn write() -> String; + pub fn write() -> String; + } + } +} + +mod test_use_statements { + #[cfg(bogus)] + use flippity_foo; +} + +mod test_methods { + struct Foo { + bar: usize + } + + impl Fooable for Foo { + #[cfg(bogus)] + fn what(&self) { } + + fn what(&self) { } + + #[cfg(bogus)] + fn the(&self) { } + + fn the(&self) { } + } + + trait Fooable { + #[cfg(bogus)] + fn what(&self); + + fn what(&self); + + #[cfg(bogus)] + fn the(&self); + + fn the(&self); + } +} + +#[cfg(any())] +mod nonexistent_file; // Check that unconfigured non-inline modules are not loaded or parsed. + diff --git a/gcc/testsuite/rust/rustc/ui/cfg/crate-attributes-using-cfg_attr.rs b/gcc/testsuite/rust/rustc/ui/cfg/crate-attributes-using-cfg_attr.rs new file mode 100644 index 000000000000..111996d765b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfg/crate-attributes-using-cfg_attr.rs @@ -0,0 +1,7 @@ +// run-pass +// aux-build:crate-attributes-using-cfg_attr.rs + +extern crate crate_attributes_using_cfg_attr; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/cfguard-run.rs b/gcc/testsuite/rust/rustc/ui/cfguard-run.rs new file mode 100644 index 000000000000..75f17608e0f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cfguard-run.rs @@ -0,0 +1,7 @@ +// run-pass +// compile-flags: -C control-flow-guard + +pub fn main() { + println!("hello, world"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/arithmetic.rs b/gcc/testsuite/rust/rustc/ui/chalkify/arithmetic.rs new file mode 100644 index 000000000000..4565e589430c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/arithmetic.rs @@ -0,0 +1,21 @@ +// check-pass +// compile-flags: -Z chalk + +fn main() { + 1 + 2; + 3 * 6; + 2 - 5; + 17 / 6; + 23 % 11; + 4 & 6; + 7 | 15; + 4 << 7; + 123 >> 3; + 1 == 2; + 5 != 5; + 6 < 2; + 7 > 11; + 3 <= 1; + 9 >= 14; +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/basic.rs b/gcc/testsuite/rust/rustc/ui/chalkify/basic.rs new file mode 100644 index 000000000000..37365fb5af41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/basic.rs @@ -0,0 +1,13 @@ +// check-pass +// compile-flags: -Z chalk + +trait Foo {} + +struct Bar {} + +impl Foo for Bar {} + +fn main() -> () { + let _ = Bar {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/builtin-copy-clone.rs b/gcc/testsuite/rust/rustc/ui/chalkify/builtin-copy-clone.rs new file mode 100644 index 000000000000..662a7252c773 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/builtin-copy-clone.rs @@ -0,0 +1,45 @@ +// run-pass +// compile-flags: -Z chalk + +// Test that `Clone` is correctly implemented for builtin types. + +#[derive(Copy, Clone)] +struct S(i32); + +fn test_clone(arg: T) { + let _ = arg.clone(); +} + +fn test_copy(arg: T) { + let _ = arg; + let _ = arg; +} + +fn test_copy_clone(arg: T) { + test_copy(arg); + test_clone(arg); +} + +fn foo() { } + +fn main() { + test_copy_clone(foo); + let f: fn() = foo; + test_copy_clone(f); + // FIXME: add closures when they're considered WF + test_copy_clone([1; 56]); + test_copy_clone((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)); + test_copy_clone((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, true, 'a', 1.1)); + test_copy_clone(()); + test_copy_clone(((1, 1), (1, 1, 1), (1.1, 1, 1, 'a'), ())); + + let a = ( + (S(1), S(0)), + ( + (S(0), S(0), S(1)), + S(0) + ) + ); + test_copy_clone(a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/chalk_initial_program.rs b/gcc/testsuite/rust/rustc/ui/chalkify/chalk_initial_program.rs new file mode 100644 index 000000000000..d9a78ac11154 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/chalk_initial_program.rs @@ -0,0 +1,17 @@ +// compile-flags: -Z chalk + +trait Foo { } + +impl Foo for i32 { } + +impl Foo for u32 { } + +fn gimme() { } + +// Note: this also tests that `std::process::Termination` is implemented for `()`. +fn main() { + gimme::(); + gimme::(); + gimme::(); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/closure.rs b/gcc/testsuite/rust/rustc/ui/chalkify/closure.rs new file mode 100644 index 000000000000..438e611ab776 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/closure.rs @@ -0,0 +1,40 @@ +// check-fail +// compile-flags: -Z chalk + +fn main() -> () { + let t = || {}; + t(); + + let mut a = 0; + let mut b = move || { + a = 1; + }; + b(); + + let mut c = b; + + c(); + b(); + + let mut a = 0; + let mut b = || { + a = 1; + }; + b(); + + let mut c = b; + + c(); + b(); // { dg-error ".E0382." "" { target *-*-* } } + + // FIXME(chalk): this doesn't quite work + /* + let b = |c| { + c + }; + + let a = &32; + b(a); + */ +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/generic_impls.rs b/gcc/testsuite/rust/rustc/ui/chalkify/generic_impls.rs new file mode 100644 index 000000000000..90df0e5ba4d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/generic_impls.rs @@ -0,0 +1,19 @@ +// compile-flags: -Z chalk + +trait Foo { } + +impl Foo for (T, u32) { } + +fn gimme() { } + +fn foo() { + gimme::<(T, u32)>(); + gimme::<(Option, u32)>(); + gimme::<(Option, f32)>(); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() { + gimme::<(i32, u32)>(); + gimme::<(i32, f32)>(); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/impl_wf.rs b/gcc/testsuite/rust/rustc/ui/chalkify/impl_wf.rs new file mode 100644 index 000000000000..dc5f4c1ff4e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/impl_wf.rs @@ -0,0 +1,27 @@ +// compile-flags: -Z chalk + +trait Foo: Sized { } + +trait Bar { + type Item: Foo; +} + +impl Foo for i32 { } + +impl Foo for str { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + +// Implicit `T: Sized` bound. +impl Foo for Option { } + +trait Baz where U: Foo { } + +impl Baz for i32 { } + +impl Baz for f32 { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/impl_wf_2.rs b/gcc/testsuite/rust/rustc/ui/chalkify/impl_wf_2.rs new file mode 100644 index 000000000000..d17ade6566ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/impl_wf_2.rs @@ -0,0 +1,34 @@ +// Split out of impl_wf.rs to work around rust aborting compilation early + +// compile-flags: -Z chalk + +trait Foo: Sized { } + +trait Bar { + type Item: Foo; +} + +impl Foo for i32 { } + +// Implicit `T: Sized` bound. +impl Foo for Option { } + +impl Bar for () { + type Item = i32; +} + +impl Bar for Option { + type Item = Option; +} + +impl Bar for f32 { + type Item = f32; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +trait Baz where U: Foo { } + +impl Baz for i32 { } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/inherent_impl.rs b/gcc/testsuite/rust/rustc/ui/chalkify/inherent_impl.rs new file mode 100644 index 000000000000..f5e6135f4c2e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/inherent_impl.rs @@ -0,0 +1,43 @@ +// run-pass +// compile-flags: -Z chalk + +trait Foo { } + +impl Foo for i32 { } + +struct S { + x: T, +} + +fn only_foo(_x: &T) { } + +impl S { + // Test that we have the correct environment inside an inherent method. + fn dummy_foo(&self) { + only_foo(&self.x) + } +} + +trait Bar { } +impl Bar for u32 { } + +fn only_bar() { } + +impl S { + // Test that the environment of `dummy_bar` adds up with the environment + // of the inherent impl. + fn dummy_bar(&self) { + only_foo(&self.x); + only_bar::(); + } +} + +fn main() { + let s = S { + x: 5, + }; + + s.dummy_bar::(); + s.dummy_foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/inherent_impl_min.rs b/gcc/testsuite/rust/rustc/ui/chalkify/inherent_impl_min.rs new file mode 100644 index 000000000000..5150260e95ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/inherent_impl_min.rs @@ -0,0 +1,28 @@ +// run-pass +// compile-flags: -Z chalk + +trait Foo { } + +impl Foo for i32 { } + +struct S { + x: T, +} + +fn only_foo(_x: &T) { } + +impl S { + // Test that we have the correct environment inside an inherent method. + fn dummy_foo(&self) { + only_foo(&self.x) + } +} + +fn main() { + let s = S { + x: 5, + }; + + s.dummy_foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/lower_env1.rs b/gcc/testsuite/rust/rustc/ui/chalkify/lower_env1.rs new file mode 100644 index 000000000000..60a4f08d96ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/lower_env1.rs @@ -0,0 +1,15 @@ +// check-pass +// compile-flags: -Z chalk + +#![allow(dead_code)] + +trait Foo { } + +trait Bar where Self: Foo { } + +fn bar() { +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/lower_env2.rs b/gcc/testsuite/rust/rustc/ui/chalkify/lower_env2.rs new file mode 100644 index 000000000000..a6e4ce59861d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/lower_env2.rs @@ -0,0 +1,17 @@ +// check-pass +// compile-flags: -Z chalk + +#![allow(dead_code)] + +trait Foo { } + +struct S<'a, T: ?Sized> where T: Foo { + data: &'a T, +} + +fn bar(_x: S<'_, T>) { // note that we have an implicit `T: Sized` bound +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/lower_env3.rs b/gcc/testsuite/rust/rustc/ui/chalkify/lower_env3.rs new file mode 100644 index 000000000000..0a885d3b9a84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/lower_env3.rs @@ -0,0 +1,17 @@ +// check-pass +// compile-flags: -Z chalk + +#![allow(dead_code)] + +trait Foo { + fn foo(&self); +} + +impl Foo for T where T: Clone { + fn foo(&self) { + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/lower_impl.rs b/gcc/testsuite/rust/rustc/ui/chalkify/lower_impl.rs new file mode 100644 index 000000000000..7a6a65c2fc5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/lower_impl.rs @@ -0,0 +1,18 @@ +// check-pass +// compile-flags: -Z chalk + +trait Foo { } + +impl Foo for T where T: Iterator { } + +trait Bar { + type Assoc; +} + +impl Bar for T where T: Iterator { + type Assoc = Vec; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/lower_struct.rs b/gcc/testsuite/rust/rustc/ui/chalkify/lower_struct.rs new file mode 100644 index 000000000000..e0a939a353b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/lower_struct.rs @@ -0,0 +1,9 @@ +// check-pass +// compile-flags: -Z chalk + +struct Foo<'a, T> where Box: Clone { + _x: std::marker::PhantomData<&'a T>, +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/lower_trait.rs b/gcc/testsuite/rust/rustc/ui/chalkify/lower_trait.rs new file mode 100644 index 000000000000..215a72474525 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/lower_trait.rs @@ -0,0 +1,12 @@ +// check-pass +// compile-flags: -Z chalk + +trait Bar { } + +trait Foo { + type Assoc: Bar + ?Sized; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/lower_trait_higher_rank.rs b/gcc/testsuite/rust/rustc/ui/chalkify/lower_trait_higher_rank.rs new file mode 100644 index 000000000000..bae181eda3bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/lower_trait_higher_rank.rs @@ -0,0 +1,10 @@ +// check-pass +// compile-flags: -Z chalk + +trait Foo where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8 +{ +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/lower_trait_where_clause.rs b/gcc/testsuite/rust/rustc/ui/chalkify/lower_trait_where_clause.rs new file mode 100644 index 000000000000..656e7d0bcafb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/lower_trait_where_clause.rs @@ -0,0 +1,17 @@ +// check-pass +// compile-flags: -Z chalk + +use std::borrow::Borrow; + +trait Foo<'a, 'b, T, U> +where + T: Borrow + ?Sized, + U: ?Sized + 'b, + 'a: 'b, + Box:, // NOTE(#53696) this checks an empty list of bounds. +{ +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/println.rs b/gcc/testsuite/rust/rustc/ui/chalkify/println.rs new file mode 100644 index 000000000000..9bed8522deb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/println.rs @@ -0,0 +1,8 @@ +// check-pass +// compile-flags: -Z chalk + +fn main() { + // FIXME(chalk): Require `RegionOutlives`/`TypeOutlives`/`Subtype` support + //println!("hello"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/projection.rs b/gcc/testsuite/rust/rustc/ui/chalkify/projection.rs new file mode 100644 index 000000000000..42a24e340023 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/projection.rs @@ -0,0 +1,26 @@ +// run-pass +// compile-flags: -Z chalk + +trait Foo { } + +trait Bar { + type Item: Foo; +} + +impl Foo for i32 { } +impl Bar for i32 { + type Item = i32; +} + +fn only_foo() { } + +fn only_bar() { + // `T` implements `Bar` hence `::Item` must also implement `Bar` + only_foo::() +} + +fn main() { + only_bar::(); + only_foo::<::Item>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/recursive_where_clause_on_type.rs b/gcc/testsuite/rust/rustc/ui/chalkify/recursive_where_clause_on_type.rs new file mode 100644 index 000000000000..6060106f38b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/recursive_where_clause_on_type.rs @@ -0,0 +1,31 @@ +// FIXME(chalk): should fail, see comments +// check-fail +// compile-flags: -Z chalk + +#![feature(trivial_bounds)] + +trait Bar { + fn foo(); +} +trait Foo: Bar { } + +struct S where S: Foo; + +impl Foo for S { +} + +fn bar() { + T::foo(); +} + +fn foo() { + bar::() +} + +fn main() { + // For some reason, the error is duplicated... + + foo::() // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/super_trait.rs b/gcc/testsuite/rust/rustc/ui/chalkify/super_trait.rs new file mode 100644 index 000000000000..1bdb5b7828ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/super_trait.rs @@ -0,0 +1,20 @@ +// run-pass +// compile-flags: -Z chalk + +trait Foo { } +trait Bar: Foo { } + +impl Foo for i32 { } +impl Bar for i32 { } + +fn only_foo() { } + +fn only_bar() { + // `T` implements `Bar` hence `T` must also implement `Foo` + only_foo::() +} + +fn main() { + only_bar::() +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/trait-objects.rs b/gcc/testsuite/rust/rustc/ui/chalkify/trait-objects.rs new file mode 100644 index 000000000000..9a0e30028eb7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/trait-objects.rs @@ -0,0 +1,14 @@ +// check-pass +// compile-flags: -Z chalk + +use std::fmt::Display; + +fn main() { + let d: &dyn Display = &mut 3; + // FIXME(chalk) should be able to call d.to_string() as well, but doing so + // requires Chalk to be able to prove trait object well-formed goals. + (&d).to_string(); + let f: &dyn Fn(i32) -> _ = &|x| x + x; + f(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/trait_implied_bound.rs b/gcc/testsuite/rust/rustc/ui/chalkify/trait_implied_bound.rs new file mode 100644 index 000000000000..34915f03c660 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/trait_implied_bound.rs @@ -0,0 +1,19 @@ +// run-pass +// compile-flags: -Z chalk + +trait Foo { } +trait Bar where U: Foo { } + +impl Foo for i32 { } +impl Bar for i32 { } + +fn only_foo() { } + +fn only_bar>() { + only_foo::() +} + +fn main() { + only_bar::() +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/type_implied_bound.rs b/gcc/testsuite/rust/rustc/ui/chalkify/type_implied_bound.rs new file mode 100644 index 000000000000..1d534926eef4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/type_implied_bound.rs @@ -0,0 +1,30 @@ +// run-pass +// compile-flags: -Z chalk + +trait Eq { } +trait Hash: Eq { } + +impl Eq for i32 { } +impl Hash for i32 { } + +struct Set { + _x: T, +} + +fn only_eq() { } + +fn take_a_set(_: &Set) { + // `Set` is an input type of `take_a_set`, hence we know that + // `T` must implement `Hash`, and we know in turn that `T` must + // implement `Eq`. + only_eq::() +} + +fn main() { + let set = Set { + _x: 5, + }; + + take_a_set(&set); +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/type_inference.rs b/gcc/testsuite/rust/rustc/ui/chalkify/type_inference.rs new file mode 100644 index 000000000000..bbdd0bbc6c76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/type_inference.rs @@ -0,0 +1,29 @@ +// compile-flags: -Z chalk + +trait Foo { } +impl Foo for i32 { } + +trait Bar { } +impl Bar for i32 { } +impl Bar for u32 { } + +fn only_foo(_x: T) { } + +fn only_bar(_x: T) { } + +fn main() { + let x = 5.0; + + // The only type which implements `Foo` is `i32`, so the chalk trait solver + // is expecting a variable of type `i32`. This behavior differs from the + // old-style trait solver. I guess this will change, that's why I'm + // adding that test. + // FIXME(chalk): order of these two errors is non-deterministic, + // so let's just hide one for now + //only_foo(x); // ERROR the trait bound `f64: Foo` is not satisfied + + // Here we have two solutions so we get back the behavior of the old-style + // trait solver. + only_bar(x); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/chalkify/type_wf.rs b/gcc/testsuite/rust/rustc/ui/chalkify/type_wf.rs new file mode 100644 index 000000000000..c6d96428fb8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/chalkify/type_wf.rs @@ -0,0 +1,26 @@ +// check-fail +// compile-flags: -Z chalk + +trait Foo { } + +struct S { + x: T, +} + +impl Foo for i32 { } +impl Foo for Option { } + +fn main() { + let s = S { + x: 5, + }; + + let s = S { // { dg-error ".E0277." "" { target *-*-* } } + x: 5.0, + }; + + let s = S { + x: Some(5.0), + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/changing-crates.rs b/gcc/testsuite/rust/rustc/ui/changing-crates.rs new file mode 100644 index 000000000000..e12929704039 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/changing-crates.rs @@ -0,0 +1,13 @@ +// ignore-msvc FIXME #31306 + +// note that these aux-build directives must be in this order +// aux-build:changing-crates-a1.rs +// aux-build:changing-crates-b.rs +// aux-build:changing-crates-a2.rs +// normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" + +extern crate a; +extern crate b; // { dg-error ".E0460." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/char.rs b/gcc/testsuite/rust/rustc/ui/char.rs new file mode 100644 index 000000000000..7df873cb6a2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/char.rs @@ -0,0 +1,14 @@ +// run-pass + +pub fn main() { + let c: char = 'x'; + let d: char = 'x'; + assert_eq!(c, 'x'); + assert_eq!('x', c); + assert_eq!(c, c); + assert_eq!(c, d); + assert_eq!(d, c); + assert_eq!(d, 'x'); + assert_eq!('x', d); +} + diff --git a/gcc/testsuite/rust/rustc/ui/char_unicode.rs b/gcc/testsuite/rust/rustc/ui/char_unicode.rs new file mode 100644 index 000000000000..00159aa93794 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/char_unicode.rs @@ -0,0 +1,11 @@ +// run-pass + +/// Tests access to the Unicode version constant. +pub fn main() { + check(std::char::UNICODE_VERSION); +} + +pub fn check(unicode_version: (u8, u8, u8)) { + assert!(unicode_version.0 >= 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/check-doc-alias-attr-location.rs b/gcc/testsuite/rust/rustc/ui/check-doc-alias-attr-location.rs new file mode 100644 index 000000000000..6d8a5e37ed8a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/check-doc-alias-attr-location.rs @@ -0,0 +1,25 @@ +#![crate_type="lib"] +#![feature(doc_alias)] + +pub struct Bar; +pub trait Foo { + type X; + fn foo() -> Self::X; +} + +#[doc(alias = "foo")] // { dg-error "" "" { target *-*-* } } +extern {} + +#[doc(alias = "bar")] // { dg-error "" "" { target *-*-* } } +impl Bar { + #[doc(alias = "const")] + const A: u32 = 0; +} + +#[doc(alias = "foobar")] // { dg-error "" "" { target *-*-* } } +impl Foo for Bar { + #[doc(alias = "assoc")] // { dg-error "" "" { target *-*-* } } + type X = i32; + fn foo() -> Self::X { 0 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/check-doc-alias-attr.rs b/gcc/testsuite/rust/rustc/ui/check-doc-alias-attr.rs new file mode 100644 index 000000000000..96a3d52bb6c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/check-doc-alias-attr.rs @@ -0,0 +1,18 @@ +#![crate_type = "lib"] +#![feature(doc_alias)] + +#[doc(alias = "foo")] // ok! +pub struct Bar; + +#[doc(alias)] // { dg-error "" "" { target *-*-* } } +#[doc(alias = 0)] // { dg-error "" "" { target *-*-* } } +#[doc(alias("bar"))] // { dg-error "" "" { target *-*-* } } +#[doc(alias = "\"")] // { dg-error "" "" { target *-*-* } } +#[doc(alias = "\n")] // { dg-error "" "" { target *-*-* } } +#[doc(alias = " +// { dg-error "" "" { target *-*-* } .-1 } +#[doc(alias = "\t")] // { dg-error "" "" { target *-*-* } } +#[doc(alias = " hello")] // { dg-error "" "" { target *-*-* } } +#[doc(alias = "hello ")] // { dg-error "" "" { target *-*-* } } +pub struct Foo; + diff --git a/gcc/testsuite/rust/rustc/ui/check-static-immutable-mut-slices.rs b/gcc/testsuite/rust/rustc/ui/check-static-immutable-mut-slices.rs new file mode 100644 index 000000000000..9da640097dd8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/check-static-immutable-mut-slices.rs @@ -0,0 +1,7 @@ +// Checks that immutable static items can't have mutable slices + +static TEST: &'static mut [isize] = &mut []; +// { dg-error ".E0764." "" { target *-*-* } .-1 } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/check-static-recursion-foreign.rs b/gcc/testsuite/rust/rustc/ui/check-static-recursion-foreign.rs new file mode 100644 index 000000000000..f89d2f785ec2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/check-static-recursion-foreign.rs @@ -0,0 +1,24 @@ +// run-pass + +// Static recursion check shouldn't fail when given a foreign item (#18279) + +// aux-build:check_static_recursion_foreign_helper.rs +// ignore-wasm32-bare no libc to test ffi with + +// pretty-expanded FIXME #23616 + +#![feature(rustc_private)] + +extern crate check_static_recursion_foreign_helper; +extern crate libc; + +use libc::c_int; + +extern "C" { + static test_static: c_int; +} + +pub static B: &'static c_int = unsafe { &test_static }; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/check-static-values-constraints.rs b/gcc/testsuite/rust/rustc/ui/check-static-values-constraints.rs new file mode 100644 index 000000000000..dd9827c2bb14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/check-static-values-constraints.rs @@ -0,0 +1,114 @@ +// Verifies all possible restrictions for statics values. + +#![allow(warnings)] +#![feature(box_syntax)] + +use std::marker; + +struct WithDtor; + +impl Drop for WithDtor { + fn drop(&mut self) {} +} + +// This enum will be used to test the following rules: +// 1. Variants are safe for static +// 2. Expr calls are allowed as long as they arguments are safe +// 3. Expr calls with unsafe arguments for statics are rejected +enum SafeEnum { + Variant1, + Variant2(isize), + Variant3(WithDtor), + Variant4(String) +} + +// These should be ok +static STATIC1: SafeEnum = SafeEnum::Variant1; +static STATIC2: SafeEnum = SafeEnum::Variant2(0); +static STATIC3: SafeEnum = SafeEnum::Variant3(WithDtor); + +enum UnsafeEnum { + Variant5, + Variant6(isize) +} + +impl Drop for UnsafeEnum { + fn drop(&mut self) {} +} + + +static STATIC4: UnsafeEnum = UnsafeEnum::Variant5; +static STATIC5: UnsafeEnum = UnsafeEnum::Variant6(0); + + +struct SafeStruct { + field1: SafeEnum, + field2: SafeEnum, +} + + +// Struct fields are safe, hence this static should be safe +static STATIC6: SafeStruct = SafeStruct{field1: SafeEnum::Variant1, field2: SafeEnum::Variant2(0)}; + +static STATIC7: SafeStruct = SafeStruct{field1: SafeEnum::Variant1, + field2: SafeEnum::Variant3(WithDtor)}; + +// Test variadic constructor for structs. The base struct should be examined +// as well as every field present in the constructor. +// This example shouldn't fail because all the fields are safe. +static STATIC8: SafeStruct = SafeStruct{field1: SafeEnum::Variant1, + ..SafeStruct{field1: SafeEnum::Variant1, + field2: SafeEnum::Variant1}}; + +// This example should fail because field1 in the base struct is not safe +static STATIC9: SafeStruct = SafeStruct{field1: SafeEnum::Variant1, + ..SafeStruct{field1: SafeEnum::Variant3(WithDtor), +// { dg-error ".E0493." "" { target *-*-* } .-1 } + field2: SafeEnum::Variant1}}; + +struct UnsafeStruct; + +impl Drop for UnsafeStruct { + fn drop(&mut self) {} +} + +static STATIC10: UnsafeStruct = UnsafeStruct; + +struct MyOwned; + +static STATIC11: Box = box MyOwned; +// { dg-error ".E0010." "" { target *-*-* } .-1 } + +static mut STATIC12: UnsafeStruct = UnsafeStruct; + +static mut STATIC13: SafeStruct = SafeStruct{field1: SafeEnum::Variant1, + field2: SafeEnum::Variant3(WithDtor)}; + +static mut STATIC14: SafeStruct = SafeStruct { + field1: SafeEnum::Variant1, + field2: SafeEnum::Variant4("str".to_string()) +// { dg-error ".E0015." "" { target *-*-* } .-1 } +}; + +static STATIC15: &'static [Box] = &[ + box MyOwned, // { dg-error ".E0010." "" { target *-*-* } } + box MyOwned, // { dg-error ".E0010." "" { target *-*-* } } +]; + +static STATIC16: (&'static Box, &'static Box) = ( + &box MyOwned, // { dg-error ".E0010." "" { target *-*-* } } + &box MyOwned, // { dg-error ".E0010." "" { target *-*-* } } +); + +static mut STATIC17: SafeEnum = SafeEnum::Variant1; + +static STATIC19: Box = + box 3; +// { dg-error ".E0010." "" { target *-*-* } .-1 } + +pub fn main() { + let y = { static x: Box = box 3; x }; +// { dg-error ".E0010." "" { target *-*-* } .-1 } +// { dg-error ".E0010." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/check_const-feature-gated.rs b/gcc/testsuite/rust/rustc/ui/check_const-feature-gated.rs new file mode 100644 index 000000000000..2f6c85f49b8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/check_const-feature-gated.rs @@ -0,0 +1,8 @@ +// run-pass + +const ARR: [usize; 1] = [2]; + +fn main() { + let _ = 5 << ARR[0]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/child-outlives-parent.rs b/gcc/testsuite/rust/rustc/ui/child-outlives-parent.rs new file mode 100644 index 000000000000..323fe9cb6976 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/child-outlives-parent.rs @@ -0,0 +1,14 @@ +// run-pass +// Reported as issue #126, child leaks the string. + +// pretty-expanded FIXME #23616 +// ignore-emscripten no threads support + +use std::thread; + +fn child2(_s: String) { } + +pub fn main() { + let _x = thread::spawn(move|| child2("hi".to_string())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/class-cast-to-trait.rs b/gcc/testsuite/rust/rustc/ui/class-cast-to-trait.rs new file mode 100644 index 000000000000..a38a1cc529c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/class-cast-to-trait.rs @@ -0,0 +1,55 @@ +#![feature(box_syntax)] + +trait Noisy { + fn speak(&self); +} + +struct Cat { + meows : usize, + + how_hungry : isize, + name : String, +} + +impl Cat { + pub fn eat(&self) -> bool { + if self.how_hungry > 0 { + println!("OM NOM NOM"); + self.how_hungry -= 2; + return true; + } + else { + println!("Not hungry!"); + return false; + } + } +} + +impl Noisy for Cat { + fn speak(&self) { self.meow(); } + +} + +impl Cat { + fn meow(&self) { + println!("Meow"); + self.meows += 1; + if self.meows % 5 == 0 { + self.how_hungry += 1; + } + } +} + +fn cat(in_x : usize, in_y : isize, in_name: String) -> Cat { + Cat { + meows: in_x, + how_hungry: in_y, + name: in_name + } +} + +fn main() { + let nyan: Box = box cat(0, 2, "nyan".to_string()) as Box; + nyan.eat(); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/class-method-missing.rs b/gcc/testsuite/rust/rustc/ui/class-method-missing.rs new file mode 100644 index 000000000000..aaeb028b9277 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/class-method-missing.rs @@ -0,0 +1,22 @@ +trait Animal { + fn eat(&self); +} + +struct Cat { + meows: usize, +} + +impl Animal for Cat { +// { dg-error ".E0046." "" { target *-*-* } .-1 } +} + +fn cat(in_x : usize) -> Cat { + Cat { + meows: in_x + } +} + +fn main() { + let nyan = cat(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/class-missing-self.rs b/gcc/testsuite/rust/rustc/ui/class-missing-self.rs new file mode 100644 index 000000000000..bb658f7bf588 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/class-missing-self.rs @@ -0,0 +1,17 @@ +struct Cat { + meows : usize, +} + +impl Cat { + fn sleep(&self) { loop{} } + fn meow(&self) { + println!("Meow"); + meows += 1; // { dg-error ".E0425." "" { target *-*-* } } + sleep(); // { dg-error ".E0425." "" { target *-*-* } } + } + +} + + + fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/cleanup-arm-conditional.rs b/gcc/testsuite/rust/rustc/ui/cleanup-arm-conditional.rs new file mode 100644 index 000000000000..7610782c9b4c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cleanup-arm-conditional.rs @@ -0,0 +1,40 @@ +// run-pass + +#![allow(stable_features)] +#![allow(unused_imports)] +// Test that cleanup scope for temporaries created in a match +// arm is confined to the match arm itself. + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax, os)] + +use std::os; + +struct Test { x: isize } + +impl Test { + fn get_x(&self) -> Option> { + Some(box self.x) + } +} + +fn do_something(t: &Test) -> isize { + + // The cleanup scope for the result of `t.get_x()` should be the + // arm itself and not the match, otherwise we'll (potentially) get + // a crash trying to free an uninitialized stack slot. + + match t { + &Test { x: 2 } if t.get_x().is_some() => { + t.x * 2 + } + _ => { 22 } + } +} + +pub fn main() { + let t = Test { x: 1 }; + do_something(&t); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-during-if-and-while.rs b/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-during-if-and-while.rs new file mode 100644 index 000000000000..f6727b8cedab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-during-if-and-while.rs @@ -0,0 +1,44 @@ +// run-pass +// This test verifies that temporaries created for `while`'s and `if` +// conditions are dropped after the condition is evaluated. + +#![feature(box_syntax)] + +struct Temporary; + +static mut DROPPED: isize = 0; + +impl Drop for Temporary { + fn drop(&mut self) { + unsafe { DROPPED += 1; } + } +} + +impl Temporary { + fn do_stuff(&self) -> bool {true} +} + +fn borrow() -> Box { box Temporary } + + +pub fn main() { + let mut i = 0; + + // This loop's condition + // should call `Temporary`'s + // `drop` 6 times. + while borrow().do_stuff() { + i += 1; + unsafe { assert_eq!(DROPPED, i) } + if i > 5 { + break; + } + } + + // This if condition should + // call it 1 time + if borrow().do_stuff() { + unsafe { assert_eq!(DROPPED, i + 1) } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-for-scope.rs b/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-for-scope.rs new file mode 100644 index 000000000000..42e06162cd73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-for-scope.rs @@ -0,0 +1,64 @@ +// run-pass + +#![allow(non_snake_case)] +#![allow(dead_code)] +#![allow(unused_variables)] +// Test that the lifetime of rvalues in for loops is extended +// to the for loop itself. + +use std::ops::Drop; + +static mut FLAGS: u64 = 0; + +struct Box { f: T } +struct AddFlags { bits: u64 } + +fn AddFlags(bits: u64) -> AddFlags { + AddFlags { bits: bits } +} + +fn arg(exp: u64, _x: &AddFlags) { + check_flags(exp); +} + +fn pass(v: T) -> T { + v +} + +fn check_flags(exp: u64) { + unsafe { + let x = FLAGS; + FLAGS = 0; + println!("flags {}, expected {}", x, exp); + assert_eq!(x, exp); + } +} + +impl AddFlags { + fn check_flags(&self, exp: u64) -> &AddFlags { + check_flags(exp); + self + } + + fn bits(&self) -> u64 { + self.bits + } +} + +impl Drop for AddFlags { + fn drop(&mut self) { + unsafe { + FLAGS = FLAGS + self.bits; + } + } +} + +pub fn main() { + // The array containing [AddFlags] should not be dropped until + // after the for loop: + for x in &[AddFlags(1)] { + check_flags(0); + } + check_flags(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-scopes-cf.rs b/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-scopes-cf.rs new file mode 100644 index 000000000000..5e99f54449ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-scopes-cf.rs @@ -0,0 +1,36 @@ +// Test that the borrow checker prevents pointers to temporaries +// with statement lifetimes from escaping. + +use std::ops::Drop; + +static mut FLAGS: u64 = 0; + +struct StackBox { f: T } +struct AddFlags { bits: u64 } + +fn AddFlags(bits: u64) -> AddFlags { + AddFlags { bits: bits } +} + +fn arg(x: &AddFlags) -> &AddFlags { + x +} + +impl AddFlags { + fn get(&self) -> &AddFlags { + self + } +} + +pub fn main() { + let x1 = arg(&AddFlags(1)); // { dg-error ".E0716." "" { target *-*-* } } + let x2 = AddFlags(1).get(); // { dg-error ".E0716." "" { target *-*-* } } + let x3 = &*arg(&AddFlags(1)); // { dg-error ".E0716." "" { target *-*-* } } + let ref x4 = *arg(&AddFlags(1)); // { dg-error ".E0716." "" { target *-*-* } } + let &ref x5 = arg(&AddFlags(1)); // { dg-error ".E0716." "" { target *-*-* } } + let x6 = AddFlags(1).get(); // { dg-error ".E0716." "" { target *-*-* } } + let StackBox { f: x7 } = StackBox { f: AddFlags(1).get() }; +// { dg-error ".E0716." "" { target *-*-* } .-1 } + (x1, x2, x3, x4, x5, x6, x7); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-scopes.rs b/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-scopes.rs new file mode 100644 index 000000000000..972c54b9cf28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-scopes.rs @@ -0,0 +1,132 @@ +// run-pass +#![allow(unused_braces)] +#![allow(non_snake_case)] +#![allow(unused_variables)] +// Test that destructors for rvalue temporaries run either at end of +// statement or end of block, as appropriate given the temporary +// lifetime rules. + +#![feature(box_patterns)] +#![feature(box_syntax)] + +use std::ops::Drop; + +static mut FLAGS: u64 = 0; + +struct Box { f: T } +struct AddFlags { bits: u64 } + +fn AddFlags(bits: u64) -> AddFlags { + AddFlags { bits: bits } +} + +fn arg(exp: u64, _x: &AddFlags) { + check_flags(exp); +} + +fn pass(v: T) -> T { + v +} + +fn check_flags(exp: u64) { + unsafe { + let x = FLAGS; + FLAGS = 0; + println!("flags {}, expected {}", x, exp); + assert_eq!(x, exp); + } +} + +impl AddFlags { + fn check_flags<'a>(&'a self, exp: u64) -> &'a AddFlags { + check_flags(exp); + self + } + + fn bits(&self) -> u64 { + self.bits + } +} + +impl Drop for AddFlags { + fn drop(&mut self) { + unsafe { + FLAGS = FLAGS + self.bits; + } + } +} + +macro_rules! end_of_block { + ($pat:pat, $expr:expr) => ( + { + println!("end_of_block({})", stringify!({let $pat = $expr;})); + + { + // Destructor here does not run until exit from the block. + let $pat = $expr; + check_flags(0); + } + check_flags(1); + } + ) +} + +macro_rules! end_of_stmt { + ($pat:pat, $expr:expr) => ( + { + println!("end_of_stmt({})", stringify!($expr)); + + { + // Destructor here run after `let` statement + // terminates. + let $pat = $expr; + check_flags(1); + } + + check_flags(0); + } + ) +} + +pub fn main() { + + // In all these cases, we trip over the rules designed to cover + // the case where we are taking addr of rvalue and storing that + // addr into a stack slot, either via `let ref` or via a `&` in + // the initializer. + + end_of_block!(_x, AddFlags(1)); + end_of_block!(_x, &AddFlags(1)); + end_of_block!(_x, & &AddFlags(1)); + end_of_block!(_x, Box { f: AddFlags(1) }); + end_of_block!(_x, Box { f: &AddFlags(1) }); + end_of_block!(_x, Box { f: &AddFlags(1) }); + end_of_block!(_x, pass(AddFlags(1))); + end_of_block!(ref _x, AddFlags(1)); + end_of_block!(AddFlags { bits: ref _x }, AddFlags(1)); + end_of_block!(&AddFlags { bits }, &AddFlags(1)); + end_of_block!((_, ref _y), (AddFlags(1), 22)); + end_of_block!(box ref _x, box AddFlags(1)); + end_of_block!(box _x, box AddFlags(1)); + end_of_block!(_, { { check_flags(0); &AddFlags(1) } }); + end_of_block!(_, &((Box { f: AddFlags(1) }).f)); + end_of_block!(_, &(([AddFlags(1)])[0])); + + // LHS does not create a ref binding, so temporary lives as long + // as statement, and we do not move the AddFlags out: + end_of_stmt!(_, AddFlags(1)); + end_of_stmt!((_, _), (AddFlags(1), 22)); + + // `&` operator appears inside an arg to a function, + // so it is not prolonged: + end_of_stmt!(ref _x, arg(0, &AddFlags(1))); + + // autoref occurs inside receiver, so temp lifetime is not + // prolonged: + end_of_stmt!(ref _x, AddFlags(1).check_flags(0).bits()); + + // No reference is created on LHS, thus RHS is moved into + // a temporary that lives just as long as the statement. + end_of_stmt!(AddFlags { bits }, AddFlags(1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs b/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs new file mode 100644 index 000000000000..e8ef180e3781 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs @@ -0,0 +1,49 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(dead_code)] +#![allow(unused_variables)] +// Test cleanup of rvalue temporary that occurs while `box` construction +// is in progress. This scenario revealed a rather terrible bug. The +// ingredients are: +// +// 1. Partial cleanup of `box` is in scope, +// 2. cleanup of return value from `get_bar()` is in scope, +// 3. do_it() panics. +// +// This led to a bug because `the top-most frame that was to be +// cleaned (which happens to be the partial cleanup of `box`) required +// multiple basic blocks, which led to us dropping part of the cleanup +// from the top-most frame. +// +// It's unclear how likely such a bug is to recur, but it seems like a +// scenario worth testing. + +// ignore-emscripten no threads support + +#![feature(box_syntax)] + +use std::thread; + +enum Conzabble { + Bickwick(Foo) +} + +struct Foo { field: Box } + +fn do_it(x: &[usize]) -> Foo { + panic!() +} + +fn get_bar(x: usize) -> Vec { vec![x * 2] } + +pub fn fails() { + let x = 2; + let mut y: Vec> = Vec::new(); + y.push(box Conzabble::Bickwick(do_it(&get_bar(x)))); +} + +pub fn main() { + thread::spawn(fails).join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cleanup-shortcircuit.rs b/gcc/testsuite/rust/rustc/ui/cleanup-shortcircuit.rs new file mode 100644 index 000000000000..e14b0fe15f57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cleanup-shortcircuit.rs @@ -0,0 +1,23 @@ +// run-pass +// Test that cleanups for the RHS of shortcircuiting operators work. + +// pretty-expanded FIXME #23616 +// ignore-cloudabi no std::env support + +use std::env; + +pub fn main() { + let args: Vec = env::args().collect(); + + // Here, the rvalue `"signal".to_string()` requires cleanup. Older versions + // of the code had a problem that the cleanup scope for this + // expression was the end of the `if`, and as the `"signal".to_string()` + // expression was never evaluated, we wound up trying to clean + // uninitialized memory. + + if args.len() >= 2 && args[1] == "signal" { + // Raise a segfault. + unsafe { *std::ptr::null_mut::() = 0; } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/clone-with-exterior.rs b/gcc/testsuite/rust/rustc/ui/clone-with-exterior.rs new file mode 100644 index 000000000000..bdeee7aea9e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/clone-with-exterior.rs @@ -0,0 +1,23 @@ +// run-pass + +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +#![feature(box_syntax)] + +use std::thread; + +struct Pair { + a: isize, + b: isize +} + +pub fn main() { + let z: Box<_> = box Pair { a : 10, b : 12}; + + thread::spawn(move|| { + assert_eq!(z.a, 10); + assert_eq!(z.b, 12); + }).join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/close-over-big-then-small-data.rs b/gcc/testsuite/rust/rustc/ui/close-over-big-then-small-data.rs new file mode 100644 index 000000000000..a67d33cc8740 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/close-over-big-then-small-data.rs @@ -0,0 +1,42 @@ +// run-pass + +#![allow(dead_code)] +// If we use GEPi rather than GEP_tup_like when +// storing closure data (as we used to do), the u64 would +// overwrite the u16. + +#![feature(box_syntax)] + +struct Pair { + a: A, b: B +} + +struct Invoker { + a: A, + b: u16, +} + +trait Invokable { + fn f(&self) -> (A, u16); +} + +impl Invokable for Invoker { + fn f(&self) -> (A, u16) { + (self.a.clone(), self.b) + } +} + +fn f(a: A, b: u16) -> Box+'static> { + box Invoker { + a: a, + b: b, + } as Box+'static> +} + +pub fn main() { + let (a, b) = f(22_u64, 44u16).f(); + println!("a={} b={}", a, b); + assert_eq!(a, 22u64); + assert_eq!(b, 44u16); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs b/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs new file mode 100644 index 000000000000..e98c45021476 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-fn-supply-fn-multiple.rs @@ -0,0 +1,39 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(warnings)] + +type Different<'a, 'b> = &'a mut (&'a (), &'b ()); +type Same<'a> = Different<'a, 'a>; + +fn with_closure_expecting_different(_: F) + where F: for<'a, 'b> FnOnce(Different<'a, 'b>) +{ +} + +fn with_closure_expecting_different_anon(_: F) + where F: FnOnce(Different<'_, '_>) +{ +} + +fn supplying_nothing_expecting_anon() { + with_closure_expecting_different_anon(|x: Different| { + }) +} + +fn supplying_nothing_expecting_named() { + with_closure_expecting_different(|x: Different| { + }) +} + +fn supplying_underscore_expecting_anon() { + with_closure_expecting_different_anon(|x: Different<'_, '_>| { + }) +} + +fn supplying_underscore_expecting_named() { + with_closure_expecting_different(|x: Different<'_, '_>| { + }) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-fn-supply-fn.rs b/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-fn-supply-fn.rs new file mode 100644 index 000000000000..d97971471f67 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-fn-supply-fn.rs @@ -0,0 +1,61 @@ +fn with_closure_expecting_fn_with_free_region(_: F) +where + F: for<'a> FnOnce(fn(&'a u32), &i32), +{ +} + +fn with_closure_expecting_fn_with_bound_region(_: F) +where + F: FnOnce(fn(&u32), &i32), +{ +} + +fn expect_free_supply_free_from_fn<'x>(x: &'x u32) { + // Here, the type given for `'x` "obscures" a region from the + // expected signature that is bound at closure level. + with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {}); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn expect_free_supply_free_from_closure() { + // A variant on the previous test. Here, the region `'a` will be + // bound at the closure level, just as is expected, so no error + // results. + type Foo<'a> = fn(&'a u32); + with_closure_expecting_fn_with_free_region(|_x: Foo<'_>, y| {}); +} + +fn expect_free_supply_bound() { + // Here, we are given a function whose region is bound at closure level, + // but we expect one bound in the argument. Error results. + with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {}); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn expect_bound_supply_free_from_fn<'x>(x: &'x u32) { + // Here, we are given a `fn(&u32)` but we expect a `fn(&'x + // u32)`. In principle, this could be ok, but we demand equality. + with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {}); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn expect_bound_supply_free_from_closure() { + // A variant on the previous test. Here, the region `'a` will be + // bound at the closure level, but we expect something bound at + // the argument level. + type Foo<'a> = fn(&'a u32); + with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + }); +} + +fn expect_bound_supply_bound<'x>(x: &'x u32) { + // No error in this case. The supplied type supplies the bound + // regions, and hence we are able to figure out the type of `y` + // from the expected type + with_closure_expecting_fn_with_bound_region(|x: for<'z> fn(&'z u32), y| {}); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-infer-var-appearing-twice.rs b/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-infer-var-appearing-twice.rs new file mode 100644 index 000000000000..cb9e80783238 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-infer-var-appearing-twice.rs @@ -0,0 +1,26 @@ +fn with_closure(_: F) + where F: FnOnce(A, A) +{ +} + +fn a() { + with_closure(|x: u32, y| { + // We deduce type of `y` from `x`. + }); +} + +fn b() { + // Here we take the supplied types, resulting in an error later on. + with_closure(|x: u32, y: i32| { +// { dg-error ".E0631." "" { target *-*-* } .-1 } + }); +} + +fn c() { + with_closure(|x, y: i32| { + // We deduce type of `x` from `y`. + }); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs b/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs new file mode 100644 index 000000000000..29fe30e7b871 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-infer-var-supply-ty-with-bound-region.rs @@ -0,0 +1,20 @@ +// build-pass (FIXME(62277): could be check-pass?) + +fn with_closure(_: F) + where F: FnOnce(A, &u32) +{ +} + +fn foo() { + // This version works; we infer `A` to be `u32`, and take the type + // of `y` to be `&u32`. + with_closure(|x: u32, y| {}); +} + +fn bar() { + // This version also works. + with_closure(|x: &u32, y| {}); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs b/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs new file mode 100644 index 000000000000..c52dec4b7054 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-infer-var-supply-ty-with-free-region.rs @@ -0,0 +1,20 @@ +// build-pass (FIXME(62277): could be check-pass?) + +fn with_closure(_: F) + where F: FnOnce(A, &u32) +{ +} + +fn foo() { + // This version works; we infer `A` to be `u32`, and take the type + // of `y` to be `&u32`. + with_closure(|x: u32, y| {}); +} + +fn bar<'x>(x: &'x u32) { + // Same. + with_closure(|x: &'x u32, y| {}); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.rs b/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.rs new file mode 100644 index 000000000000..4a7603d28b23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.rs @@ -0,0 +1,20 @@ +fn with_closure(_: F) + where F: FnOnce(A, B) +{ +} + +fn a() { + // Type of `y` is unconstrained. + with_closure(|x: u32, y| {}); // { dg-error ".E0282." "" { target *-*-* } } +} + +fn b() { + with_closure(|x: u32, y: u32| {}); // OK +} + +fn c() { + with_closure(|x: u32, y: u32| {}); // OK +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/closure-expected-type/issue-24421.rs b/gcc/testsuite/rust/rustc/ui/closure-expected-type/issue-24421.rs new file mode 100644 index 000000000000..3d8778373fd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closure-expected-type/issue-24421.rs @@ -0,0 +1,11 @@ +// check-pass + +fn test(f: F) {} + +fn main() { + test(|x, y | {}); + test(|x:&u64, y:&u64| {}); + test(|x:&u64, y | {}); + test(|x, y:&u64| {}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closure-expected.rs b/gcc/testsuite/rust/rustc/ui/closure-expected.rs new file mode 100644 index 000000000000..d1c0b18e3a3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closure-expected.rs @@ -0,0 +1,6 @@ +fn main() { + let x = Some(1); + let y = x.or_else(4); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closure_context/issue-26046-fn-mut.rs b/gcc/testsuite/rust/rustc/ui/closure_context/issue-26046-fn-mut.rs new file mode 100644 index 000000000000..9b436aec91f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closure_context/issue-26046-fn-mut.rs @@ -0,0 +1,12 @@ +fn foo() -> Box { + let num = 5; + + let closure = || { // { dg-error ".E0525." "" { target *-*-* } } + num += 1; + }; + + Box::new(closure) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/closure_context/issue-26046-fn-once.rs b/gcc/testsuite/rust/rustc/ui/closure_context/issue-26046-fn-once.rs new file mode 100644 index 000000000000..6ece8b4534e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closure_context/issue-26046-fn-once.rs @@ -0,0 +1,12 @@ +fn get_closure() -> Box Vec> { + let vec = vec![1u8, 2u8]; + + let closure = move || { // { dg-error ".E0525." "" { target *-*-* } } + vec + }; + + Box::new(closure) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/closure_context/issue-42065.rs b/gcc/testsuite/rust/rustc/ui/closure_context/issue-42065.rs new file mode 100644 index 000000000000..00e66b987357 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closure_context/issue-42065.rs @@ -0,0 +1,14 @@ +use std::collections::HashMap; + +fn main() { + let dict: HashMap = HashMap::new(); + let debug_dump_dict = || { + for (key, value) in dict { + println!("{:?} - {:?}", key, value); + } + }; + debug_dump_dict(); + debug_dump_dict(); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closure_promotion.rs b/gcc/testsuite/rust/rustc/ui/closure_promotion.rs new file mode 100644 index 000000000000..cfba165df1a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closure_promotion.rs @@ -0,0 +1,8 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(const_err)] + +fn main() { + let x: &'static _ = &|| { let z = 3; z }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-array-break-length.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-array-break-length.rs new file mode 100644 index 000000000000..42db4b81af0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-array-break-length.rs @@ -0,0 +1,8 @@ +fn main() { + |_: [_; continue]| {}; // { dg-error ".E0268." "" { target *-*-* } } + + while |_: [_; continue]| {} {} // { dg-error ".E0268." "" { target *-*-* } } + + while |_: [_; break]| {} {} // { dg-error ".E0268." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs new file mode 100644 index 000000000000..6751ff2124d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-bounds-cant-promote-superkind-in-struct.rs @@ -0,0 +1,12 @@ +struct X where F: FnOnce() + 'static + Send { + field: F, +} + +fn foo(blk: F) -> X where F: FnOnce() + 'static { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + return X { field: blk }; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-bounds-static-cant-capture-borrowed.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-bounds-static-cant-capture-borrowed.rs new file mode 100644 index 000000000000..32c12e463e91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-bounds-static-cant-capture-borrowed.rs @@ -0,0 +1,13 @@ +fn bar(blk: F) where F: FnOnce() + 'static { +} + +fn foo(x: &()) { + bar(|| { +// { dg-error ".E0621." "" { target *-*-* } .-1 } + let _ = x; + }) +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-bounds-subtype.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-bounds-subtype.rs new file mode 100644 index 000000000000..4bcd503b87c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-bounds-subtype.rs @@ -0,0 +1,17 @@ +fn take_any(_: F) where F: FnOnce() { +} + +fn take_const_owned(_: F) where F: FnOnce() + Sync + Send { +} + +fn give_any(f: F) where F: FnOnce() { + take_any(f); +} + +fn give_owned(f: F) where F: FnOnce() + Send { + take_any(f); + take_const_owned(f); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-expected-type/expect-region-supply-region-2.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-expected-type/expect-region-supply-region-2.rs new file mode 100644 index 000000000000..168332505cd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-expected-type/expect-region-supply-region-2.rs @@ -0,0 +1,25 @@ +#![allow(warnings)] + +fn closure_expecting_bound(_: F) +where + F: FnOnce(&u32), +{ +} + +fn expect_bound_supply_named<'x>() { + let mut f: Option<&u32> = None; + + // Here we give a type annotation that `x` should be free. We get + // an error because of that. + closure_expecting_bound(|x: &'x u32| { +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + // Borrowck doesn't get a chance to run, but if it did it should error + // here. + f = Some(x); + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-expected-type/expect-region-supply-region.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-expected-type/expect-region-supply-region.rs new file mode 100644 index 000000000000..99d97843c8c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-expected-type/expect-region-supply-region.rs @@ -0,0 +1,58 @@ +#![allow(warnings)] + +fn closure_expecting_bound(_: F) +where + F: FnOnce(&u32), +{ +} + +fn closure_expecting_free<'a, F>(_: F) +where + F: FnOnce(&'a u32), +{ +} + +fn expect_bound_supply_nothing() { + // Because `x` is inferred to have a bound region, we cannot allow + // it to escape into `f`: + let mut f: Option<&u32> = None; + closure_expecting_bound(|x| { + f = Some(x); // { dg-error ".E0521." "" { target *-*-* } } + }); +} + +fn expect_bound_supply_bound() { + // Because `x` is inferred to have a bound region, we cannot allow + // it to escape into `f`, even with an explicit type annotation on + // closure: + let mut f: Option<&u32> = None; + closure_expecting_bound(|x: &u32| { + f = Some(x); // { dg-error ".E0521." "" { target *-*-* } } + }); +} + +fn expect_free_supply_nothing() { + let mut f: Option<&u32> = None; + closure_expecting_free(|x| f = Some(x)); // OK +} + +fn expect_free_supply_bound() { + let mut f: Option<&u32> = None; + + // Here, even though the annotation `&u32` could be seen as being + // bound in the closure, we permit it to be defined as a free + // region (which is inferred to something in the fn body). + closure_expecting_free(|x: &u32| f = Some(x)); // OK +} + +fn expect_free_supply_named<'x>() { + let mut f: Option<&u32> = None; + + // Here, even though the annotation `&u32` could be seen as being + // bound in the closure, we permit it to be defined as a free + // region (which is inferred to something in the fn body). + closure_expecting_free(|x: &'x u32| f = Some(x)); // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-immutable-outer-variable.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-immutable-outer-variable.rs new file mode 100644 index 000000000000..c098a639965e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-immutable-outer-variable.rs @@ -0,0 +1,14 @@ +// run-rustfix + +// Point at the captured immutable outer variable + +fn foo(mut f: Box) { + f(); +} + +fn main() { + let y = true; + foo(Box::new(move || y = !y) as Box<_>); +// { dg-error ".E0594." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-move-sync.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-move-sync.rs new file mode 100644 index 000000000000..693639da513a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-move-sync.rs @@ -0,0 +1,23 @@ +use std::thread; +use std::sync::mpsc::channel; + +fn bar() { + let (send, recv) = channel(); + let t = thread::spawn(|| { + recv.recv().unwrap(); +// { dg-error ".E0277." "" { target *-*-* } .-2 } + }); + + send.send(()); + + t.join().unwrap(); +} + +fn foo() { + let (tx, _rx) = channel(); + thread::spawn(|| tx.send(()).unwrap()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-no-fn-1.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-no-fn-1.rs new file mode 100644 index 000000000000..4f20986e81c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-no-fn-1.rs @@ -0,0 +1,9 @@ +// Ensure that capturing closures are never coerced to fns +// Especially interesting as non-capturing closures can be. + +fn main() { + let mut a = 0u8; + let foo: fn(u8) -> u8 = |v: u8| { a += v; a }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-no-fn-2.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-no-fn-2.rs new file mode 100644 index 000000000000..f9da3ae6c146 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-no-fn-2.rs @@ -0,0 +1,9 @@ +// Ensure that capturing closures are never coerced to fns +// Especially interesting as non-capturing closures can be. + +fn main() { + let b = 0u8; + let bar: fn() -> u8 = || { b }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-no-fn-3.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-no-fn-3.rs new file mode 100644 index 000000000000..5b1a965f6a72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-no-fn-3.rs @@ -0,0 +1,9 @@ +// Ensure that capturing closures are never coerced to fns +// Especially interesting as non-capturing closures can be. + +fn main() { + let b = 0u8; + let baz: fn() -> u8 = (|| { b }) as fn() -> u8; +// { dg-error ".E0605." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-referencing-itself-issue-25954.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-referencing-itself-issue-25954.rs new file mode 100644 index 000000000000..921c543da0b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-referencing-itself-issue-25954.rs @@ -0,0 +1,19 @@ +// Regression test for #25954: detect and reject a closure type that +// references itself. + +use std::cell::{Cell, RefCell}; + +struct A { + x: RefCell>, + b: Cell, +} + +fn main() { + let mut p = A{x: RefCell::new(None), b: Cell::new(4i32)}; + + // This is an error about types of infinite size: + let q = || p.b.set(5i32); // { dg-error ".E0308." "" { target *-*-* } } + + *(p.x.borrow_mut()) = Some(q); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-reform-bad.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-reform-bad.rs new file mode 100644 index 000000000000..60819fcf643f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-reform-bad.rs @@ -0,0 +1,13 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +fn call_bare(f: fn(&str)) { + f("Hello "); +} + +fn main() { + let string = "world!"; + let f = |s: &str| println!("{}{}", s, string); + call_bare(f) // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-return-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-return-type-mismatch.rs new file mode 100644 index 000000000000..3d3ad66b673a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-return-type-mismatch.rs @@ -0,0 +1,18 @@ +fn main() { + || { + if false { + return "test"; + } + let a = true; + a // { dg-error ".E0308." "" { target *-*-* } } + }; + + || -> bool { + if false { + return "hello" // { dg-error ".E0308." "" { target *-*-* } } + }; + let b = true; + b + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure-wrong-kind.rs b/gcc/testsuite/rust/rustc/ui/closures/closure-wrong-kind.rs new file mode 100644 index 000000000000..21570269d7df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure-wrong-kind.rs @@ -0,0 +1,13 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +struct X; +fn foo(_: T) {} +fn bar(_: T) {} + +fn main() { + let x = X; + let closure = |_| foo(x); // { dg-error ".E0525." "" { target *-*-* } } + bar(closure); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure_cap_coerce_many_fail.rs b/gcc/testsuite/rust/rustc/ui/closures/closure_cap_coerce_many_fail.rs new file mode 100644 index 000000000000..9fed838cd1eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure_cap_coerce_many_fail.rs @@ -0,0 +1,40 @@ +fn add(a: i32, b: i32) -> i32 { + a + b +} +fn main() { + // We shouldn't coerce capturing closure to a function + let cap = 0; + let _ = match "+" { + "+" => add, + "-" => |a, b| (a - b + cap) as i32, + _ => unimplemented!(), + }; +// { dg-error ".E0308." "" { target *-*-* } .-3 } + + + // We shouldn't coerce capturing closure to a non-capturing closure + let _ = match "+" { + "+" => |a, b| (a + b) as i32, + "-" => |a, b| (a - b + cap) as i32, + _ => unimplemented!(), + }; +// { dg-error ".E0308." "" { target *-*-* } .-3 } + + + // We shouldn't coerce non-capturing closure to a capturing closure + let _ = match "+" { + "+" => |a, b| (a + b + cap) as i32, + "-" => |a, b| (a - b) as i32, + _ => unimplemented!(), + }; +// { dg-error ".E0308." "" { target *-*-* } .-3 } + + // We shouldn't coerce capturing closure to a capturing closure + let _ = match "+" { + "+" => |a, b| (a + b + cap) as i32, + "-" => |a, b| (a - b + cap) as i32, + _ => unimplemented!(), + }; +// { dg-error ".E0308." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_check_pass.rs b/gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_check_pass.rs new file mode 100644 index 000000000000..a3813913edad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_check_pass.rs @@ -0,0 +1,167 @@ +// check-pass +// Ensure non-capturing Closure passes CoerceMany. +fn foo(x: usize) -> usize { + 0 +} + +fn bar(x: usize) -> usize { + 1 +} + +fn main() { + // One FnDef and one non-capturing Closure + let _ = match 0 { + 0 => foo, + 2 => |a| 2, + _ => unimplemented!(), + }; + + let _ = match 0 { + 2 => |a| 2, + 0 => foo, + _ => unimplemented!(), + }; + + let _ = [foo, |a| 2]; + let _ = [|a| 2, foo]; + + + + // Two FnDefs and one non-capturing Closure + let _ = match 0 { + 0 => foo, + 1 => bar, + 2 => |a| 2, + _ => unimplemented!(), + }; + + let _ = match 0 { + 0 => foo, + 2 => |a| 2, + 1 => bar, + _ => unimplemented!(), + }; + + let _ = match 0 { + 2 => |a| 2, + 0 => foo, + 1 => bar, + _ => unimplemented!(), + }; + + let _ = [foo, bar, |a| 2]; + let _ = [foo, |a| 2, bar]; + let _ = [|a| 2, foo, bar]; + + + + // One FnDef and two non-capturing Closures + let _ = match 0 { + 0 => foo, + 1 => |a| 1, + 2 => |a| 2, + _ => unimplemented!(), + }; + + let _ = match 0 { + 1 => |a| 1, + 0 => foo, + 2 => |a| 2, + _ => unimplemented!(), + }; + + let _ = match 0 { + 1 => |a| 1, + 2 => |a| 2, + 0 => foo, + _ => unimplemented!(), + }; + + let _ = [foo, |a| 1, |a| 2]; + let _ = [|a| 1, foo, |a| 2]; + let _ = [|a| 1, |a| 2, foo]; + + + + // Three non-capturing Closures + let _ = match 0 { + 0 => |a: usize| 0, + 1 => |a| 1, + 2 => |a| 2, + _ => unimplemented!(), + }; + + let _ = [|a: usize| 0, |a| 1, |a| 2]; + + + + // Three non-capturing Closures variable + let clo0 = |a: usize| 0; + let clo1 = |a| 1; + let clo2 = |a| 2; + let _ = match 0 { + 0 => clo0, + 1 => clo1, + 2 => clo2, + _ => unimplemented!(), + }; + + let clo0 = |a: usize| 0; + let clo1 = |a| 1; + let clo2 = |a| 2; + let _ = [clo0, clo1, clo2]; + + + + // --- Function pointer related part + + // Closure is not in a variable + type FnPointer = fn(usize) -> usize; + + let _ = match 0 { + 0 => foo as FnPointer, + 2 => |a| 2, + _ => unimplemented!(), + }; + let _ = match 0 { + 2 => |a| 2, + 0 => foo as FnPointer, + _ => unimplemented!(), + }; + let _ = [foo as FnPointer, |a| 2]; + let _ = [|a| 2, foo as FnPointer]; + let _ = [foo, bar, |x| x]; + let _ = [foo as FnPointer, bar, |x| x]; + let _ = [foo, bar as FnPointer, |x| x]; + let _ = [foo, bar, (|x| x) as FnPointer]; + let _ = [foo as FnPointer, bar as FnPointer, |x| x]; + + // Closure is in a variable + let x = |a| 2; + let _ = match 0 { + 0 => foo as FnPointer, + 2 => x, + _ => unimplemented!(), + }; + let x = |a| 2; + let _ = match 0 { + 2 => x, + 0 => foo as FnPointer, + _ => unimplemented!(), + }; + let x = |a| 2; + let _ = [foo as FnPointer, x]; + let _ = [x, foo as FnPointer]; + + let x = |a| 2; + let _ = [foo, bar, x]; + let x: FnPointer = |a| 2; + let _ = [foo, bar, x]; + let x = |a| 2; + let _ = [foo, bar as FnPointer, x]; + let x = |a| 2; + let _ = [foo as FnPointer, bar, x]; + let x = |a| 2; + let _ = [foo as FnPointer, bar as FnPointer, x]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_run_pass.rs b/gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_run_pass.rs new file mode 100644 index 000000000000..61a161856903 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_run_pass.rs @@ -0,0 +1,60 @@ +// run-pass +// Ensure non-capturing Closure passing CoerceMany work correctly. +fn foo(_: usize) -> usize { + 0 +} + +fn bar(_: usize) -> usize { + 1 +} + +fn add(a: i32, b: i32) -> i32 { + a + b +} + +fn main() { + // Coerce result check + + type FnPointer = fn(usize) -> usize; + + let c = |x| x; + let c_pointer: FnPointer = c; + assert_eq!(c_pointer(42), 42); + + let f = match 0 { + 0 => foo, + 1 => |_| 1, + _ => unimplemented!(), + }; + assert_eq!(f(42), 0); + + let f = match 2 { + 2 => |_| 2, + 0 => foo, + _ => unimplemented!(), + }; + assert_eq!(f(42), 2); + + let f = match 1 { + 0 => foo, + 1 => bar, + 2 => |_| 2, + _ => unimplemented!(), + }; + assert_eq!(f(42), 1); + + let clo0 = |_: usize| 0; + let clo1 = |_| 1; + let clo2 = |_| 2; + let f = match 0 { + 0 => clo0, + 1 => clo1, + 2 => clo2, + _ => unimplemented!(), + }; + assert_eq!(f(42), 0); + + let funcs = [add, |a, b| (a - b) as i32]; + assert_eq!([funcs[0](5, 5), funcs[1](5, 5)], [10, 0]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_unsafe_0.rs b/gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_unsafe_0.rs new file mode 100644 index 000000000000..6d1ef845f016 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_unsafe_0.rs @@ -0,0 +1,23 @@ +// Ensure we get unsafe function after coercion +unsafe fn add(a: i32, b: i32) -> i32 { + a + b +} +fn main() { + // We can coerce non-capturing closure to unsafe function + let foo = match "+" { + "+" => add, + "-" => |a, b| (a - b) as i32, + _ => unimplemented!(), + }; + let result: i32 = foo(5, 5); // { dg-error ".E0133." "" { target *-*-* } } + + + // We can coerce unsafe function to non-capturing closure + let foo = match "+" { + "-" => |a, b| (a - b) as i32, + "+" => add, + _ => unimplemented!(), + }; + let result: i32 = foo(5, 5); // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_unsafe_1.rs b/gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_unsafe_1.rs new file mode 100644 index 000000000000..87e68a88f6a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/closure_no_cap_coerce_many_unsafe_1.rs @@ -0,0 +1,24 @@ +// run-pass +// Ensure we get correct unsafe function after coercion +unsafe fn add(a: i32, b: i32) -> i32 { + a + b +} +fn main() { + // We can coerce non-capturing closure to unsafe function + let foo = match "+" { + "+" => add, + "-" => |a, b| (a - b) as i32, + _ => unimplemented!(), + }; + assert_eq!(unsafe { foo(5, 5) }, 10); + + + // We can coerce unsafe function to non-capturing closure + let foo = match "-" { + "-" => |a, b| (a - b) as i32, + "+" => add, + _ => unimplemented!(), + }; + assert_eq!(unsafe { foo(5, 5) }, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/deeply-nested_closures.rs b/gcc/testsuite/rust/rustc/ui/closures/deeply-nested_closures.rs new file mode 100644 index 000000000000..4a8dc7f338d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/deeply-nested_closures.rs @@ -0,0 +1,24 @@ +// Check that this can be compiled in a reasonable time. + +// build-pass + +fn main() { + // 96 nested closures + let x = (); + || || || || || || || || + || || || || || || || || + || || || || || || || || + || || || || || || || || + + || || || || || || || || + || || || || || || || || + || || || || || || || || + || || || || || || || || + + || || || || || || || || + || || || || || || || || + || || || || || || || || + || || || || || || || || + [&(), &x]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/diverging-closure.rs b/gcc/testsuite/rust/rustc/ui/closures/diverging-closure.rs new file mode 100644 index 000000000000..5eaf5c362f77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/diverging-closure.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:oops +// ignore-emscripten no processes + +fn main() { + let func = || -> ! { + panic!("oops"); + }; + func(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/issue-41366.rs b/gcc/testsuite/rust/rustc/ui/closures/issue-41366.rs new file mode 100644 index 000000000000..9b62287b6fa9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/issue-41366.rs @@ -0,0 +1,14 @@ +trait T<'x> { + type V; +} + +impl<'g> T<'g> for u32 { + type V = u16; +} + +fn main() { + (&|_| ()) as &dyn for<'x> Fn(>::V); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/issue-46742.rs b/gcc/testsuite/rust/rustc/ui/closures/issue-46742.rs new file mode 100644 index 000000000000..0e2a3e992167 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/issue-46742.rs @@ -0,0 +1,10 @@ +// check-pass +fn main() { + let _: i32 = (match "" { + "+" => ::std::ops::Add::add, + "-" => ::std::ops::Sub::sub, + "<" => |a,b| (a < b) as i32, + _ => unimplemented!(), + })(5, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/issue-48109.rs b/gcc/testsuite/rust/rustc/ui/closures/issue-48109.rs new file mode 100644 index 000000000000..d04544daffd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/issue-48109.rs @@ -0,0 +1,15 @@ +// check-pass +fn useful(i: usize) -> usize { + i +} + +fn useful2(i: usize) -> usize { + i +} + +fn main() { + for f in &[useful, useful2, |x| x] { + println!("{}", f(6)); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/issue-52437.rs b/gcc/testsuite/rust/rustc/ui/closures/issue-52437.rs new file mode 100644 index 000000000000..db51006b9ba9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/issue-52437.rs @@ -0,0 +1,7 @@ +fn main() { + [(); &(&'static: loop { |x| {}; }) as *const _ as usize] +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/issue-67123.rs b/gcc/testsuite/rust/rustc/ui/closures/issue-67123.rs new file mode 100644 index 000000000000..4727ed0beebb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/issue-67123.rs @@ -0,0 +1,6 @@ +fn foo(t: T) { + || { t; t; }; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/issue-68025.rs b/gcc/testsuite/rust/rustc/ui/closures/issue-68025.rs new file mode 100644 index 000000000000..1644a405ee18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/issue-68025.rs @@ -0,0 +1,13 @@ +// check-pass + +fn foo(_: G, _: Box) +where + F: Fn(), + G: Fn(Box), +{ +} + +fn main() { + foo(|f| (*f)(), Box::new(|| {})); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/issue-72408-nested-closures-exponential.rs b/gcc/testsuite/rust/rustc/ui/closures/issue-72408-nested-closures-exponential.rs new file mode 100644 index 000000000000..2085a8378009 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/issue-72408-nested-closures-exponential.rs @@ -0,0 +1,60 @@ +// build-pass + +// Closures include captured types twice in a type tree. +// +// Wrapping one closure with another leads to doubling +// the amount of types in the type tree. +// +// This test ensures that rust can handle +// deeply nested type trees with a lot +// of duplicated subtrees. + +fn dup(f: impl Fn(i32) -> i32) -> impl Fn(i32) -> i32 { + move |a| f(a * 2) +} + +fn main() { + let f = |a| a; + + let f = dup(f); + let f = dup(f); + let f = dup(f); + let f = dup(f); + let f = dup(f); + + let f = dup(f); + let f = dup(f); + let f = dup(f); + let f = dup(f); + let f = dup(f); + + let f = dup(f); + let f = dup(f); + let f = dup(f); + let f = dup(f); + let f = dup(f); + + let f = dup(f); + let f = dup(f); + let f = dup(f); + let f = dup(f); + let f = dup(f); + + // Compiler dies around here if it tries + // to walk the tree exhaustively. + + let f = dup(f); + let f = dup(f); + let f = dup(f); + let f = dup(f); + let f = dup(f); + + let f = dup(f); + let f = dup(f); + let f = dup(f); + let f = dup(f); + let f = dup(f); + + println!("Type size was at least {}", f(1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-1.rs b/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-1.rs new file mode 100644 index 000000000000..f321c8cf2433 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-1.rs @@ -0,0 +1,24 @@ +fn to_fn_once(f: F) -> F { + f +} + +fn f(y: T) { + struct Foo { + x: U, + }; + + let foo = Foo { x: "x" }; + + let c = to_fn_once(move || { + println!("{} {}", foo.x, y); + }); + + c(); + c(); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn main() { + f("S"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-2.rs b/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-2.rs new file mode 100644 index 000000000000..ba95496160de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-2.rs @@ -0,0 +1,14 @@ +mod mod1 { + pub fn f(t: T) { + let x = 20; + + let c = || println!("{} {}", t, x); + let c1: () = c; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } +} + +fn main() { + mod1::f(5i32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-trim-off-verbose-2.rs b/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-trim-off-verbose-2.rs new file mode 100644 index 000000000000..8355e0c679e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-trim-off-verbose-2.rs @@ -0,0 +1,17 @@ +// compile-flags: -Ztrim-diagnostic-paths=off -Zverbose + +mod mod1 { + pub fn f(t: T) + { + let x = 20; + + let c = || println!("{} {}", t, x); + let c1 : () = c; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } +} + +fn main() { + mod1::f(5i32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-verbose-1.rs b/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-verbose-1.rs new file mode 100644 index 000000000000..7570580674fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-verbose-1.rs @@ -0,0 +1,25 @@ +// compile-flags: -Zverbose + +fn to_fn_once(f: F) -> F { f } + +fn f(y: T) { + struct Foo { + x: U + }; + + let foo = Foo{ x: "x" }; + + let c = to_fn_once(move|| { + println!("{} {}", foo.x, y); + }); + + c(); + c(); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + + +fn main() { + f("S"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-verbose-2.rs b/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-verbose-2.rs new file mode 100644 index 000000000000..710f9086b57e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-generic-verbose-2.rs @@ -0,0 +1,17 @@ +// compile-flags: -Zverbose + +mod mod1 { + pub fn f(t: T) + { + let x = 20; + + let c = || println!("{} {}", t, x); + let c1 : () = c; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } +} + +fn main() { + mod1::f(5i32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-verbose.rs b/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-verbose.rs new file mode 100644 index 000000000000..7c90f18de4f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/closures/print/closure-print-verbose.rs @@ -0,0 +1,13 @@ +// compile-flags: -Zverbose + +// Same as closure-coerce-fn-1.rs + +// Ensure that capturing closures are never coerced to fns +// Especially interesting as non-capturing closures can be. + +fn main() { + let mut a = 0u8; + let foo: fn(u8) -> u8 = |v: u8| { a += v; a }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cmp-default.rs b/gcc/testsuite/rust/rustc/ui/cmp-default.rs new file mode 100644 index 000000000000..2f52ebbc27ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cmp-default.rs @@ -0,0 +1,74 @@ +// run-pass + +use std::cmp::Ordering; + +// Test default methods in PartialOrd and PartialEq +// +#[derive(Debug)] +struct Fool(bool); + +impl PartialEq for Fool { + fn eq(&self, other: &Fool) -> bool { + let Fool(this) = *self; + let Fool(other) = *other; + this != other + } +} + +struct Int(isize); + +impl PartialEq for Int { + fn eq(&self, other: &Int) -> bool { + let Int(this) = *self; + let Int(other) = *other; + this == other + } +} + +impl PartialOrd for Int { + fn partial_cmp(&self, other: &Int) -> Option { + let Int(this) = *self; + let Int(other) = *other; + this.partial_cmp(&other) + } +} + +struct RevInt(isize); + +impl PartialEq for RevInt { + fn eq(&self, other: &RevInt) -> bool { + let RevInt(this) = *self; + let RevInt(other) = *other; + this == other + } +} + +impl PartialOrd for RevInt { + fn partial_cmp(&self, other: &RevInt) -> Option { + let RevInt(this) = *self; + let RevInt(other) = *other; + other.partial_cmp(&this) + } +} + +pub fn main() { + assert!(Int(2) > Int(1)); + assert!(Int(2) >= Int(1)); + assert!(Int(1) >= Int(1)); + assert!(Int(1) < Int(2)); + assert!(Int(1) <= Int(2)); + assert!(Int(1) <= Int(1)); + + assert!(RevInt(2) < RevInt(1)); + assert!(RevInt(2) <= RevInt(1)); + assert!(RevInt(1) <= RevInt(1)); + assert!(RevInt(1) > RevInt(2)); + assert!(RevInt(1) >= RevInt(2)); + assert!(RevInt(1) >= RevInt(1)); + + assert_eq!(Fool(true), Fool(false)); + assert!(Fool(true) != Fool(true)); + assert!(Fool(false) != Fool(false)); + assert_eq!(Fool(false), Fool(true)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/gate_test.rs b/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/gate_test.rs new file mode 100644 index 000000000000..d436611a586d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/gate_test.rs @@ -0,0 +1,12 @@ +// gate-test-cmse_nonsecure_entry + +#[no_mangle] +#[cmse_nonsecure_entry] +// { dg-error ".E0775." "" { target *-*-* } .-1 } +// { dg-error ".E0775." "" { target *-*-* } .-2 } +pub extern "C" fn entry_function(input: u32) -> u32 { + input + 6 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/params-on-registers.rs b/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/params-on-registers.rs new file mode 100644 index 000000000000..ffc5ef4a41b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/params-on-registers.rs @@ -0,0 +1,12 @@ +// build-pass +// compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +// only-thumbv8m.main-none-eabi +#![feature(cmse_nonsecure_entry)] +#![no_std] + +#[no_mangle] +#[cmse_nonsecure_entry] +pub extern "C" fn entry_function(a: u32, b: u32, c: u32, d: u32) -> u32 { + a + b + c + d +} + diff --git a/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/params-on-stack.rs b/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/params-on-stack.rs new file mode 100644 index 000000000000..15c693eea324 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/params-on-stack.rs @@ -0,0 +1,11 @@ +// compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +// only-thumbv8m.main-none-eabi +#![feature(cmse_nonsecure_entry)] +#![no_std] + +#[no_mangle] +#[cmse_nonsecure_entry] +pub extern "C" fn entry_function(a: u32, b: u32, c: u32, d: u32, e: u32) -> u32 { // { dg-error "" "" { target *-*-* } } + a + b + c + d + e +} + diff --git a/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/trustzone-only.rs b/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/trustzone-only.rs new file mode 100644 index 000000000000..be4ba1573d12 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/trustzone-only.rs @@ -0,0 +1,11 @@ +// ignore-thumbv8m.main-none-eabi +#![feature(cmse_nonsecure_entry)] + +#[no_mangle] +#[cmse_nonsecure_entry] // { dg-error ".E0775." "" { target *-*-* } } +pub extern "C" fn entry_function(input: u32) -> u32 { + input + 6 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/wrong-abi.rs b/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/wrong-abi.rs new file mode 100644 index 000000000000..f62bbb7d40af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cmse-nonsecure-entry/wrong-abi.rs @@ -0,0 +1,11 @@ +// compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +// only-thumbv8m.main-none-eabi +#![feature(cmse_nonsecure_entry)] +#![no_std] + +#[no_mangle] +#[cmse_nonsecure_entry] +pub fn entry_function(a: u32, b: u32, c: u32, d: u32) -> u32 { // { dg-error "" "" { target *-*-* } } + a + b + c + d +} + diff --git a/gcc/testsuite/rust/rustc/ui/codegen-object-shim.rs b/gcc/testsuite/rust/rustc/ui/codegen-object-shim.rs new file mode 100644 index 000000000000..94ceb3e341fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codegen-object-shim.rs @@ -0,0 +1,7 @@ +// run-pass + +fn main() { + assert_eq!((ToString::to_string as fn(&(dyn ToString+'static)) -> String)(&"foo"), + String::from("foo")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/bad-format-args.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/bad-format-args.rs new file mode 100644 index 000000000000..d649a4ea282b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/bad-format-args.rs @@ -0,0 +1,6 @@ +fn main() { + format!(); // { dg-error "" "" { target *-*-* } } + format!("" 1); // { dg-error "" "" { target *-*-* } } + format!("", 1 1); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs new file mode 100644 index 000000000000..fa7660fbd48b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs @@ -0,0 +1,7 @@ +#![allow(dead_code)] + +trait C {} +impl dyn C { fn f() {} } // { dg-error ".E0592." "" { target *-*-* } } +impl dyn C { fn f() {} } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/empty_span.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/empty_span.rs new file mode 100644 index 000000000000..1be5a2e9f91d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/empty_span.rs @@ -0,0 +1,9 @@ +#![feature(negative_impls)] +fn main() { + struct Foo; + + impl !Sync for Foo {} + + unsafe impl Send for &'static Foo { } // { dg-error ".E0321." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/huge_multispan_highlight.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/huge_multispan_highlight.rs new file mode 100644 index 000000000000..b4f7f6ff5915 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/huge_multispan_highlight.rs @@ -0,0 +1,92 @@ +fn main() { + let x = "foo"; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + let y = &mut x; // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/issue-11715.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/issue-11715.rs new file mode 100644 index 000000000000..497610b2d505 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/issue-11715.rs @@ -0,0 +1,12 @@ +#![feature(rustc_attrs)] +fn main() { #![rustc_error] // rust-lang/rust#49855 + let mut x = "foo"; + let y = &mut x; + let z = &mut x; // { dg-error ".E0499." "" { target *-*-* } } + z.use_mut(); + y.use_mut(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/issue-28308.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/issue-28308.rs new file mode 100644 index 000000000000..47f8a7922583 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/issue-28308.rs @@ -0,0 +1,5 @@ +fn main() { + assert!("foo"); +// { dg-error ".E0600." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/one_line.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/one_line.rs new file mode 100644 index 000000000000..d6650dd29770 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/one_line.rs @@ -0,0 +1,5 @@ +fn main() { + let mut v = vec![Some("foo"), Some("bar")]; + v.push(v.pop().unwrap()); // { dg-error ".E0499." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/overlapping_inherent_impls.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/overlapping_inherent_impls.rs new file mode 100644 index 000000000000..448d3b9b0acf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/overlapping_inherent_impls.rs @@ -0,0 +1,37 @@ +// Test that you cannot define items with the same name in overlapping inherent +// impl blocks. + +#![allow(unused)] + +struct Foo; + +impl Foo { + fn id() {} // { dg-error ".E0592." "" { target *-*-* } } +} + +impl Foo { + fn id() {} +} + +struct Bar(T); + +impl Bar { + fn bar(&self) {} // { dg-error ".E0592." "" { target *-*-* } } +} + +impl Bar { + fn bar(&self) {} +} + +struct Baz(T); + +impl Baz { + fn baz(&self) {} // { dg-error ".E0592." "" { target *-*-* } } +} + +impl Baz> { + fn baz(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/tab.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/tab.rs new file mode 100644 index 000000000000..6896827f09ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/tab.rs @@ -0,0 +1,10 @@ +// ignore-tidy-tab + +fn main() { + bar; // { dg-error ".E0425." "" { target *-*-* } } +} + +fn foo() { + "bar boo" // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/tab_2.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/tab_2.rs new file mode 100644 index 000000000000..c8b20797fac2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/tab_2.rs @@ -0,0 +1,6 @@ +// ignore-tidy-tab + +fn main() { + """; // { dg-error ".E0765." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/tab_3.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/tab_3.rs new file mode 100644 index 000000000000..6ffc80f42ba5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/tab_3.rs @@ -0,0 +1,10 @@ +// ignore-tidy-tab + +fn main() { + let some_vec = vec!["hi"]; + some_vec.into_iter(); + { + println!("{:?}", some_vec); // { dg-error ".E0382." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/two_files.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/two_files.rs new file mode 100644 index 000000000000..3ee26716c7cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/two_files.rs @@ -0,0 +1,8 @@ +include!("two_files_data.rs"); + +struct Baz { } + +impl Bar for Baz { } // { dg-error ".E0404." "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/two_files_data.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/two_files_data.rs new file mode 100644 index 000000000000..f68a317500ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/two_files_data.rs @@ -0,0 +1,6 @@ +// ignore-test + +trait Foo { } + +type Bar = dyn Foo; + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/unicode.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/unicode.rs new file mode 100644 index 000000000000..a49bad487b11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/unicode.rs @@ -0,0 +1,4 @@ +extern "路濫狼á́́" fn foo() {} // { dg-error ".E0703." "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/unicode_2.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/unicode_2.rs new file mode 100644 index 000000000000..83f3bf9d6e30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/unicode_2.rs @@ -0,0 +1,8 @@ +#![feature(non_ascii_idents)] + +fn main() { + let _ = ("a̐éö̲", 0u7); // { dg-error "" "" { target *-*-* } } + let _ = ("아あ", 1i42); // { dg-error "" "" { target *-*-* } } + let _ = a̐é; // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/codemap_tests/unicode_3.rs b/gcc/testsuite/rust/rustc/ui/codemap_tests/unicode_3.rs new file mode 100644 index 000000000000..1574a123de36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/codemap_tests/unicode_3.rs @@ -0,0 +1,7 @@ +// check-pass + +fn main() { + let s = "ZͨA͑ͦ͒͋ͤ͑̚L̄͑͋Ĝͨͥ̿͒̽̈́Oͥ͛ͭ!̏"; while true { break; } // { dg-warning "" "" { target *-*-* } } + println!("{}", s); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-expect-unsized-ascribed.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-expect-unsized-ascribed.rs new file mode 100644 index 000000000000..72abd7752fdf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-expect-unsized-ascribed.rs @@ -0,0 +1,33 @@ +// A version of coerce-expect-unsized that uses type ascription. +// Doesn't work so far, but supposed to work eventually + +#![feature(box_syntax, type_ascription)] + +use std::fmt::Debug; + +pub fn main() { + let _ = box { [1, 2, 3] }: Box<[i32]>; // { dg-error ".E0308." "" { target *-*-* } } + let _ = box if true { [1, 2, 3] } else { [1, 3, 4] }: Box<[i32]>; // { dg-error ".E0308." "" { target *-*-* } } + let _ = box match true { true => [1, 2, 3], false => [1, 3, 4] }: Box<[i32]>; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let _ = box { |x| (x as u8) }: Box _>; // { dg-error ".E0308." "" { target *-*-* } } + let _ = box if true { false } else { true }: Box; // { dg-error ".E0308." "" { target *-*-* } } + let _ = box match true { true => 'a', false => 'b' }: Box; // { dg-error ".E0308." "" { target *-*-* } } + + let _ = &{ [1, 2, 3] }: &[i32]; // { dg-error ".E0308." "" { target *-*-* } } + let _ = &if true { [1, 2, 3] } else { [1, 3, 4] }: &[i32]; // { dg-error ".E0308." "" { target *-*-* } } + let _ = &match true { true => [1, 2, 3], false => [1, 3, 4] }: &[i32]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let _ = &{ |x| (x as u8) }: &dyn Fn(i32) -> _; // { dg-error ".E0308." "" { target *-*-* } } + let _ = &if true { false } else { true }: &dyn Debug; // { dg-error ".E0308." "" { target *-*-* } } + let _ = &match true { true => 'a', false => 'b' }: &dyn Debug; // { dg-error ".E0308." "" { target *-*-* } } + + let _ = Box::new([1, 2, 3]): Box<[i32]>; // { dg-error ".E0308." "" { target *-*-* } } + let _ = Box::new(|x| (x as u8)): Box _>; // { dg-error ".E0308." "" { target *-*-* } } + + let _ = vec![ + Box::new(|x| (x as u8)), + box |x| (x as i16 as u8), + ]: Vec _>>; +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-expect-unsized.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-expect-unsized.rs new file mode 100644 index 000000000000..2015d29b0712 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-expect-unsized.rs @@ -0,0 +1,45 @@ +// run-pass +#![allow(unused_braces)] +#![feature(box_syntax)] + +use std::cell::RefCell; +use std::fmt::Debug; +use std::rc::Rc; + +// Check that coercions apply at the pointer level and don't cause +// rvalue expressions to be unsized. See #20169 for more information. + +pub fn main() { + let _: Box<[isize]> = Box::new({ [1, 2, 3] }); + let _: Box<[isize]> = Box::new(if true { [1, 2, 3] } else { [1, 3, 4] }); + let _: Box<[isize]> = Box::new(match true { true => [1, 2, 3], false => [1, 3, 4] }); + let _: Box _> = Box::new({ |x| (x as u8) }); + let _: Box = Box::new(if true { false } else { true }); + let _: Box = Box::new(match true { true => 'a', false => 'b' }); + + let _: &[isize] = &{ [1, 2, 3] }; + let _: &[isize] = &if true { [1, 2, 3] } else { [1, 3, 4] }; + let _: &[isize] = &match true { true => [1, 2, 3], false => [1, 3, 4] }; + let _: &dyn Fn(isize) -> _ = &{ |x| (x as u8) }; + let _: &dyn Debug = &if true { false } else { true }; + let _: &dyn Debug = &match true { true => 'a', false => 'b' }; + + let _: &str = &{ String::new() }; + let _: &str = &if true { String::from("...") } else { 5.to_string() }; + let _: &str = &match true { + true => format!("{}", false), + false => ["x", "y"].join("+") + }; + + let _: Box<[isize]> = Box::new([1, 2, 3]); + let _: Box _> = Box::new(|x| (x as u8)); + + let _: Rc> = Rc::new(RefCell::new([1, 2, 3])); + let _: Rc _>> = Rc::new(RefCell::new(|x| (x as u8))); + + let _: Vec _>> = vec![ + Box::new(|x| (x as u8)), + Box::new(|x| (x as i16 as u8)), + ]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-issue-49593-box-never.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-issue-49593-box-never.rs new file mode 100644 index 000000000000..f6bec073d415 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-issue-49593-box-never.rs @@ -0,0 +1,52 @@ +// check-pass +#![feature(never_type, never_type_fallback)] +#![allow(unreachable_code)] + +use std::error::Error; +use std::mem; + +fn raw_ptr_box(t: T) -> *mut T { + panic!() +} + +fn foo(x: !) -> Box { + /* *mut $0 is coerced to Box here */ Box::<_ /* ! */>::new(x) +} + +fn foo_raw_ptr(x: !) -> *mut dyn Error { + /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x) +} + +fn no_coercion(d: *mut dyn Error) -> *mut dyn Error { + /* an unsize coercion won't compile here, and it is indeed not used + because there is nothing requiring the _ to be Sized */ + d as *mut _ +} + +trait Xyz {} +struct S; +struct T; +impl Xyz for S {} +impl Xyz for T {} + +fn foo_no_never() { + let mut x /* : Option */ = None; + let mut first_iter = false; + loop { + if !first_iter { + let y: Box + = /* Box<$0> is coerced to Box here */ Box::new(x.unwrap()); + } + + x = Some(S); + first_iter = true; + } + + let mut y : Option = None; + // assert types are equal + mem::swap(&mut x, &mut y); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-mut.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-mut.rs new file mode 100644 index 000000000000..aa9552e78c65 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-mut.rs @@ -0,0 +1,11 @@ +fn f(x: &mut i32) {} + +fn main() { + let x = 0; + f(&x); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-overloaded-autoderef-fail.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-overloaded-autoderef-fail.rs new file mode 100644 index 000000000000..2f38db757a55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-overloaded-autoderef-fail.rs @@ -0,0 +1,33 @@ +fn borrow_mut(x: &mut T) -> &mut T { x } +fn borrow(x: &T) -> &T { x } + +fn borrow_mut2(_: &mut T, _: &mut T) {} +fn borrow2(_: &mut T, _: &T) {} + +fn double_mut_borrow(x: &mut Box) { + let y = borrow_mut(x); + let z = borrow_mut(x); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + drop((y, z)); +} + +fn double_imm_borrow(x: &mut Box) { + let y = borrow(x); + let z = borrow(x); + **x += 1; +// { dg-error ".E0506." "" { target *-*-* } .-1 } + drop((y, z)); +} + +fn double_mut_borrow2(x: &mut Box) { + borrow_mut2(x, x); +// { dg-error ".E0499." "" { target *-*-* } .-1 } +} + +fn double_borrow2(x: &mut Box) { + borrow2(x, x); +// { dg-error ".E0502." "" { target *-*-* } .-1 } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-overloaded-autoderef.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-overloaded-autoderef.rs new file mode 100644 index 000000000000..d8559223370e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-overloaded-autoderef.rs @@ -0,0 +1,69 @@ +// run-pass +#![allow(unused_braces)] +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +use std::rc::Rc; + +// Examples from the "deref coercions" RFC, at rust-lang/rfcs#241. + +fn use_ref(_: &T) {} +fn use_mut(_: &mut T) {} + +fn use_rc(t: Rc) { + use_ref(&*t); // what you have to write today + use_ref(&t); // what you'd be able to write + use_ref(&&&&&&t); + use_ref(&mut &&&&&t); + use_ref(&&&mut &&&t); +} + +fn use_mut_box(mut t: &mut Box) { + use_mut(&mut *t); // what you have to write today + use_mut(t); // what you'd be able to write + use_mut(&mut &mut &mut t); + + use_ref(&*t); // what you have to write today + use_ref(t); // what you'd be able to write + use_ref(&&&&&&t); + use_ref(&mut &&&&&t); + use_ref(&&&mut &&&t); +} + +fn use_nested(t: &Box) { + use_ref(&**t); // what you have to write today + use_ref(t); // what you'd be able to write (note: recursive deref) + use_ref(&&&&&&t); + use_ref(&mut &&&&&t); + use_ref(&&&mut &&&t); +} + +fn use_slice(_: &[u8]) {} +fn use_slice_mut(_: &mut [u8]) {} + +fn use_vec(mut v: Vec) { + use_slice_mut(&mut v[..]); // what you have to write today + use_slice_mut(&mut v); // what you'd be able to write + use_slice_mut(&mut &mut &mut v); + + use_slice(&v[..]); // what you have to write today + use_slice(&v); // what you'd be able to write + use_slice(&&&&&&v); + use_slice(&mut &&&&&v); + use_slice(&&&mut &&&v); +} + +fn use_vec_ref(v: &Vec) { + use_slice(&v[..]); // what you have to write today + use_slice(v); // what you'd be able to write + use_slice(&&&&&&v); + use_slice(&mut &&&&&v); + use_slice(&&&mut &&&v); +} + +fn use_op_rhs(s: &mut String) { + *s += {&String::from(" ")}; +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-ptr-arg.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-ptr-arg.rs new file mode 100644 index 000000000000..03526a42fa1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-ptr-arg.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn negate(x: &isize) -> isize { + -*x +} + +fn negate_mut(y: &mut isize) -> isize { + negate(y) +} + +fn negate_imm(y: &isize) -> isize { + negate(y) +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-ptr-rcvr.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-ptr-rcvr.rs new file mode 100644 index 000000000000..f9bc6beac3bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-ptr-rcvr.rs @@ -0,0 +1,19 @@ +// run-pass + +struct SpeechMaker { + speeches: usize +} + +impl SpeechMaker { + pub fn how_many(&self) -> usize { self.speeches } +} + +fn foo(speaker: &SpeechMaker) -> usize { + speaker.how_many() + 33 +} + +pub fn main() { + let lincoln = SpeechMaker {speeches: 22}; + assert_eq!(foo(&lincoln), 55); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-vec-arg.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-vec-arg.rs new file mode 100644 index 000000000000..734fd59f71c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-vec-arg.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn sum(x: &[isize]) -> isize { + let mut sum = 0; + for y in x { sum += *y; } + return sum; +} + +fn sum_mut(y: &mut [isize]) -> isize { + sum(y) +} + +fn sum_imm(y: &[isize]) -> isize { + sum(y) +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-vec-rcvr.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-vec-rcvr.rs new file mode 100644 index 000000000000..6836febded22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-imm-vec-rcvr.rs @@ -0,0 +1,17 @@ +// run-pass + + +fn bar(v: &mut [usize]) -> Vec { + v.to_vec() +} + +fn bip(v: &[usize]) -> Vec { + v.to_vec() +} + +pub fn main() { + let mut the_vec = vec![1, 2, 3, 100]; + assert_eq!(the_vec.clone(), bar(&mut the_vec)); + assert_eq!(the_vec.clone(), bip(&the_vec)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-multi-arg-fail.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-multi-arg-fail.rs new file mode 100644 index 000000000000..89e9068851e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-multi-arg-fail.rs @@ -0,0 +1,7 @@ +fn test(_a: T, _b: T) {} + +fn main() { + test(&mut 7, &7); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-multi-arg.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-multi-arg.rs new file mode 100644 index 000000000000..bb9e41aead4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-multi-arg.rs @@ -0,0 +1,10 @@ +// build-pass +fn test(_a: T, _b: T) {} + +fn main() { + test(&7, &7); + test(&7, &mut 7); + test::<&i32>(&mut 7, &7); + test::<&i32>(&mut 7, &mut 7); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-ptr-arg.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-ptr-arg.rs new file mode 100644 index 000000000000..b62f2d6d4b2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-ptr-arg.rs @@ -0,0 +1,26 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct SpeechMaker { + speeches: usize +} + +fn talk(x: &mut SpeechMaker) { + x.speeches += 1; +} + +fn give_a_few_speeches(speaker: &mut SpeechMaker) { + + // Here speaker is reborrowed for each call, so we don't get errors + // about speaker being moved. + + talk(speaker); + talk(speaker); + talk(speaker); +} + +pub fn main() { + let mut lincoln = SpeechMaker {speeches: 22}; + give_a_few_speeches(&mut lincoln); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs new file mode 100644 index 000000000000..411112e83aea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-ptr-rcvr.rs @@ -0,0 +1,28 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct SpeechMaker { + speeches: usize +} + +impl SpeechMaker { + pub fn talk(&mut self) { + self.speeches += 1; + } +} + +fn give_a_few_speeches(speaker: &mut SpeechMaker) { + + // Here speaker is reborrowed for each call, so we don't get errors + // about speaker being moved. + + speaker.talk(); + speaker.talk(); + speaker.talk(); +} + +pub fn main() { + let mut lincoln = SpeechMaker {speeches: 22}; + give_a_few_speeches(&mut lincoln); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-vec-arg.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-vec-arg.rs new file mode 100644 index 000000000000..30375d19b8d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-vec-arg.rs @@ -0,0 +1,19 @@ +// run-pass + + +fn reverse(v: &mut [usize]) { + v.reverse(); +} + +fn bar(v: &mut [usize]) { + reverse(v); + reverse(v); + reverse(v); +} + +pub fn main() { + let mut the_vec = vec![1, 2, 3, 100]; + bar(&mut the_vec); + assert_eq!(the_vec, [100, 3, 2, 1]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-vec-rcvr.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-vec-rcvr.rs new file mode 100644 index 000000000000..e7e8824eb672 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-reborrow-mut-vec-rcvr.rs @@ -0,0 +1,15 @@ +// run-pass + + +fn bar(v: &mut [usize]) { + v.reverse(); + v.reverse(); + v.reverse(); +} + +pub fn main() { + let mut the_vec = vec![1, 2, 3, 100]; + bar(&mut the_vec); + assert_eq!(the_vec, [100, 3, 2, 1]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-to-bang-cast.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-to-bang-cast.rs new file mode 100644 index 000000000000..cd671ef08fc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-to-bang-cast.rs @@ -0,0 +1,13 @@ +#![feature(never_type)] + +fn cast_a() { + let y = {return; 22} as !; +// { dg-error ".E0605." "" { target *-*-* } .-1 } +} + +fn cast_b() { + let y = 22 as !; // { dg-error ".E0605." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-to-bang.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-to-bang.rs new file mode 100644 index 000000000000..ea0e3f157e8a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-to-bang.rs @@ -0,0 +1,80 @@ +#![feature(never_type)] + +fn foo(x: usize, y: !, z: usize) { } + +fn call_foo_a() { + foo(return, 22, 44); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn call_foo_b() { + // Divergence happens in the argument itself, definitely ok. + foo(22, return, 44); +} + +fn call_foo_c() { + // This test fails because the divergence happens **after** the + // coercion to `!`: + foo(22, 44, return); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn call_foo_d() { + // This test passes because `a` has type `!`: + let a: ! = return; + let b = 22; + let c = 44; + foo(a, b, c); // ... and hence a reference to `a` is expected to diverge. +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn call_foo_e() { + // This test probably could pass but we don't *know* that `a` + // has type `!` so we don't let it work. + let a = return; + let b = 22; + let c = 44; + foo(a, b, c); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn call_foo_f() { + // This fn fails because `a` has type `usize`, and hence a + // reference to is it **not** considered to diverge. + let a: usize = return; + let b = 22; + let c = 44; + foo(a, b, c); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn array_a() { + // Return is coerced to `!` just fine, but `22` cannot be. + let x: [!; 2] = [return, 22]; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn array_b() { + // Error: divergence has not yet occurred. + let x: [!; 2] = [22, return]; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn tuple_a() { + // No divergence at all. + let x: (usize, !, usize) = (22, 44, 66); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn tuple_b() { + // Divergence happens before coercion: OK + let x: (usize, !, usize) = (return, 44, 66); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn tuple_c() { + // Divergence happens before coercion: OK + let x: (usize, !, usize) = (22, return, 66); +} + +fn tuple_d() { + // Error: divergence happens too late + let x: (usize, !, usize) = (22, 44, return); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-unify-return.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-unify-return.rs new file mode 100644 index 000000000000..804a4b7f5bea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-unify-return.rs @@ -0,0 +1,20 @@ +// run-pass +// Check that coercions unify the expected return type of a polymorphic +// function call, instead of leaving the type variables as they were. + +// pretty-expanded FIXME #23616 + +struct Foo; +impl Foo { + fn foo(self, x: T) -> Option { Some(x) } +} + +pub fn main() { + let _: Option = Some(main); + let _: Option = Foo.foo(main); + + // The same two cases, with implicit type variables made explicit. + let _: Option = Some::<_>(main); + let _: Option = Foo.foo::<_>(main); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-unify.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-unify.rs new file mode 100644 index 000000000000..301cfcd2dedb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-unify.rs @@ -0,0 +1,69 @@ +// run-pass +// Check that coercions can unify if-else, match arms and array elements. + +// Try to construct if-else chains, matches and arrays out of given expressions. +macro_rules! check { + ($last:expr $(, $rest:expr)+) => { + // Last expression comes first because of whacky ifs and matches. + let _ = $(if false { $rest })else+ else { $last }; + + let _ = match 0 { $(_ if false => $rest,)+ _ => $last }; + + let _ = [$($rest,)+ $last]; + } +} + +// Check all non-uniform cases of 2 and 3 expressions of 2 types. +macro_rules! check2 { + ($a:expr, $b:expr) => { + check!($a, $b); + check!($b, $a); + + check!($a, $a, $b); + check!($a, $b, $a); + check!($a, $b, $b); + + check!($b, $a, $a); + check!($b, $a, $b); + check!($b, $b, $a); + } +} + +// Check all non-uniform cases of 2 and 3 expressions of 3 types. +macro_rules! check3 { + ($a:expr, $b:expr, $c:expr) => { + // Delegate to check2 for cases where a type repeats. + check2!($a, $b); + check2!($b, $c); + check2!($a, $c); + + // Check the remaining cases, i.e., permutations of ($a, $b, $c). + check!($a, $b, $c); + check!($a, $c, $b); + check!($b, $a, $c); + check!($b, $c, $a); + check!($c, $a, $b); + check!($c, $b, $a); + } +} + +use std::mem::size_of; + +fn foo() {} +fn bar() {} + +pub fn main() { + check3!(foo, bar, foo as fn()); + check3!(size_of::, size_of::, size_of:: as fn() -> usize); + + let s = String::from("bar"); + check2!("foo", &s); + + let a = [1, 2, 3]; + let v = vec![1, 2, 3]; + check2!(&a[..], &v); + + // Make sure in-array coercion still works. + let _ = [("a", Default::default()), (Default::default(), "b"), (&s, &s)]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coerce-unsize-subtype.rs b/gcc/testsuite/rust/rustc/ui/coercion/coerce-unsize-subtype.rs new file mode 100644 index 000000000000..53567e9d4264 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coerce-unsize-subtype.rs @@ -0,0 +1,41 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +use std::rc::Rc; + +fn lub_short<'a, T>(_: &[&'a T], _: &[&'a T]) {} + +// The two arguments are a subtype of their LUB, after coercion. +fn long_and_short<'a, T>(xs: &[&'static T; 1], ys: &[&'a T; 1]) { + lub_short(xs, ys); +} + +// The argument coerces to a subtype of the return type. +fn long_to_short<'a, 'b, T>(xs: &'b [&'static T; 1]) -> &'b [&'a T] { + xs +} + +// Rc is covariant over T just like &T. +fn long_to_short_rc<'a, T>(xs: Rc<[&'static T; 1]>) -> Rc<[&'a T]> { + xs +} + +// LUB-coercion (if-else/match/array) coerces `xs: &'b [&'static T: N]` +// to a subtype of the LUB of `xs` and `ys` (i.e., `&'b [&'a T]`), +// regardless of the order they appear (in if-else/match/array). +fn long_and_short_lub1<'a, 'b, T>(xs: &'b [&'static T; 1], ys: &'b [&'a T]) { + let _order1 = [xs, ys]; + let _order2 = [ys, xs]; +} + +// LUB-coercion should also have the exact same effect when `&'b [&'a T; N]` +// needs to be coerced, i.e., the resulting type is not &'b [&'static T], but +// rather the `&'b [&'a T]` LUB. +fn long_and_short_lub2<'a, 'b, T>(xs: &'b [&'static T], ys: &'b [&'a T; 1]) { + let _order1 = [xs, ys]; + let _order2 = [ys, xs]; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coercion-missing-tail-expected-type.rs b/gcc/testsuite/rust/rustc/ui/coercion/coercion-missing-tail-expected-type.rs new file mode 100644 index 000000000000..e9864c3ce714 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coercion-missing-tail-expected-type.rs @@ -0,0 +1,17 @@ +// #41425 -- error message "mismatched types" has wrong types +// run-rustfix + +fn plus_one(x: i32) -> i32 { // { dg-error ".E0308." "" { target *-*-* } } + x + 1; +} + +fn foo() -> Result { // { dg-error ".E0308." "" { target *-*-* } } + Ok(1); +} + +fn main() { + let x = plus_one(5); + let _ = foo(); + println!("X = {}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coercion/coercion-slice.rs b/gcc/testsuite/rust/rustc/ui/coercion/coercion-slice.rs new file mode 100644 index 000000000000..51e0a7b05098 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coercion/coercion-slice.rs @@ -0,0 +1,8 @@ +// Tests that we forbid coercion from `[T; n]` to `&[T]` + +fn main() { + let _: &[i32] = [0]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_copy_like_lib.rs b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_copy_like_lib.rs new file mode 100644 index 000000000000..4e7163e8fef4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_copy_like_lib.rs @@ -0,0 +1,11 @@ +#![crate_type = "rlib"] +#![feature(fundamental)] + +pub trait MyCopy { } +impl MyCopy for i32 { } + +pub struct MyStruct(T); + +#[fundamental] +pub struct MyFundamentalStruct(T); + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_fundamental_trait_lib.rs b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_fundamental_trait_lib.rs new file mode 100644 index 000000000000..5acf360211f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_fundamental_trait_lib.rs @@ -0,0 +1,8 @@ +#![crate_type = "rlib"] +#![feature(fundamental)] + +pub trait Misc {} + +#[fundamental] +pub trait Fundamental {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_inherent_cc_lib.rs b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_inherent_cc_lib.rs new file mode 100644 index 000000000000..5f72afa7e5bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_inherent_cc_lib.rs @@ -0,0 +1,12 @@ +// See coherence_inherent_cc.rs + +pub trait TheTrait { + fn the_fn(&self); +} + +pub struct TheStruct; + +impl TheTrait for TheStruct { + fn the_fn(&self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_lib.rs b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_lib.rs new file mode 100644 index 000000000000..24533eba7074 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_lib.rs @@ -0,0 +1,16 @@ +#![crate_type="lib"] + +pub trait Remote { + fn foo(&self) { } +} + +pub trait Remote1 { + fn foo(&self, _t: T) { } +} + +pub trait Remote2 { + fn foo(&self, _t: T, _u: U) { } +} + +pub struct Pair(T,U); + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_orphan_lib.rs b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_orphan_lib.rs new file mode 100644 index 000000000000..189359696437 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/coherence_orphan_lib.rs @@ -0,0 +1,4 @@ +pub trait TheTrait { + fn the_fn(&self); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/go_trait.rs b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/go_trait.rs new file mode 100644 index 000000000000..fa6463468673 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/go_trait.rs @@ -0,0 +1,44 @@ +#![feature(specialization)] + +// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy. + +pub trait Go { + fn go(&self, arg: isize); +} + +pub fn go(this: &G, arg: isize) { + this.go(arg) +} + +pub trait GoMut { + fn go_mut(&mut self, arg: isize); +} + +pub fn go_mut(this: &mut G, arg: isize) { + this.go_mut(arg) +} + +pub trait GoOnce { + fn go_once(self, arg: isize); +} + +pub fn go_once(this: G, arg: isize) { + this.go_once(arg) +} + +impl GoMut for G + where G : Go +{ + default fn go_mut(&mut self, arg: isize) { + go(&*self, arg) + } +} + +impl GoOnce for G + where G : GoMut +{ + default fn go_once(mut self, arg: isize) { + go_mut(&mut self, arg) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs new file mode 100644 index 000000000000..6ddea7cf7de7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/re_rebalance_coherence_lib-rpass.rs @@ -0,0 +1,32 @@ +pub trait Backend {} +pub trait SupportsDefaultKeyword {} + +impl SupportsDefaultKeyword for Postgres {} + +pub struct Postgres; + +impl Backend for Postgres {} + +pub struct AstPass(::std::marker::PhantomData); + +pub trait QueryFragment {} + + +#[derive(Debug, Clone, Copy)] +pub struct BatchInsert<'a, T: 'a, Tab> { + _marker: ::std::marker::PhantomData<(&'a T, Tab)>, +} + +impl<'a, T:'a, Tab, DB> QueryFragment for BatchInsert<'a, T, Tab> +where DB: SupportsDefaultKeyword + Backend, +{} + +pub trait LibToOwned { + type Owned; +} + +pub struct LibCow::Owned> { + pub t: T, + pub o: Owned, +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/re_rebalance_coherence_lib.rs b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/re_rebalance_coherence_lib.rs new file mode 100644 index 000000000000..722d96872989 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/re_rebalance_coherence_lib.rs @@ -0,0 +1,23 @@ +pub trait Backend {} +pub trait SupportsDefaultKeyword {} + +impl SupportsDefaultKeyword for Postgres {} + +pub struct Postgres; + +impl Backend for Postgres {} + +pub struct AstPass(::std::marker::PhantomData); + +pub trait QueryFragment {} + + +#[derive(Debug, Clone, Copy)] +pub struct BatchInsert<'a, T: 'a, Tab> { + _marker: ::std::marker::PhantomData<(&'a T, Tab)>, +} + +impl<'a, T:'a, Tab, DB> QueryFragment for BatchInsert<'a, T, Tab> +where DB: SupportsDefaultKeyword + Backend, +{} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/trait_impl_conflict.rs b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/trait_impl_conflict.rs new file mode 100644 index 000000000000..da9e3592ffcf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/auxiliary/trait_impl_conflict.rs @@ -0,0 +1,7 @@ +pub trait Foo { + fn foo() {} +} + +impl Foo for isize { +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-all-remote.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-all-remote.rs new file mode 100644 index 000000000000..6df480a7aa32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-all-remote.rs @@ -0,0 +1,10 @@ +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::Remote1; + +impl Remote1 for isize { } +// { dg-error ".E0210." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-bigint-int.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-bigint-int.rs new file mode 100644 index 000000000000..ca805d636c4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-bigint-int.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:coherence_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate coherence_lib as lib; +use lib::Remote1; + +pub struct BigInt; + +impl Remote1 for isize { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-bigint-param.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-bigint-param.rs new file mode 100644 index 000000000000..42659b4f7e08 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-bigint-param.rs @@ -0,0 +1,12 @@ +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::Remote1; + +pub struct BigInt; + +impl Remote1 for T { } +// { dg-error ".E0210." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-bigint-vecint.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-bigint-vecint.rs new file mode 100644 index 000000000000..1cef5c13b4c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-bigint-vecint.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:coherence_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate coherence_lib as lib; +use lib::Remote1; + +pub struct BigInt; + +impl Remote1 for Vec { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs new file mode 100644 index 000000000000..ead3951e8251 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs @@ -0,0 +1,31 @@ +use std::fmt::Debug; +use std::default::Default; + +// Test that two blanket impls conflict (at least without negative +// bounds). After all, some other crate could implement Even or Odd +// for the same type (though this crate doesn't). + +trait MyTrait { + fn get(&self) -> usize; +} + +trait Even { } + +trait Odd { } + +impl Even for isize { } + +impl Odd for usize { } + +impl MyTrait for T { + fn get(&self) -> usize { 0 } +} + +impl MyTrait for T { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + + fn get(&self) -> usize { 0 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs new file mode 100644 index 000000000000..8290ad64670b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs @@ -0,0 +1,26 @@ +use std::fmt::Debug; +use std::default::Default; + +// Test that two blanket impls conflict (at least without negative +// bounds). After all, some other crate could implement Even or Odd +// for the same type (though this crate doesn't implement them at all). + +trait MyTrait { + fn get(&self) -> usize; +} + +trait Even {} + +trait Odd {} + +impl MyTrait for T { + fn get(&self) -> usize { 0 } +} + +impl MyTrait for T { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + fn get(&self) -> usize { 0 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs new file mode 100644 index 000000000000..0219db53eced --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs @@ -0,0 +1,21 @@ +// aux-build:go_trait.rs + +extern crate go_trait; + +use go_trait::{Go,GoMut}; +use std::fmt::Debug; +use std::default::Default; + +struct MyThingy; + +impl Go for MyThingy { + fn go(&self, arg: isize) { } +} + +impl GoMut for MyThingy { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + fn go_mut(&mut self, arg: isize) { } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs new file mode 100644 index 000000000000..3cc2462d53e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs @@ -0,0 +1,28 @@ +use std::fmt::Debug; +use std::default::Default; + +// Test that a blank impl for all T conflicts with an impl for some +// specific T, even when there are multiple type parameters involved. + +trait MyTrait { + fn get(&self) -> T; +} + +impl MyTrait for T { + fn get(&self) -> T { + panic!() + } +} + +#[derive(Clone)] +struct MyType { + dummy: usize +} + +impl MyTrait for MyType { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + fn get(&self) -> usize { (*self).clone() } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs new file mode 100644 index 000000000000..a0919d47af90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs @@ -0,0 +1,30 @@ +// Test that a blank impl for all T:PartialEq conflicts with an impl for some +// specific T when T:PartialEq. + +trait OtherTrait { + fn noop(&self); +} + +trait MyTrait { + fn get(&self) -> usize; +} + +impl MyTrait for T { + fn get(&self) -> usize { 0 } +} + +struct MyType { + dummy: usize +} + +impl MyTrait for MyType { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + fn get(&self) -> usize { self.dummy } +} + +impl OtherTrait for MyType { + fn noop(&self) { } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific.rs new file mode 100644 index 000000000000..c24a6326891f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket-conflicts-with-specific.rs @@ -0,0 +1,25 @@ +use std::fmt::Debug; +use std::default::Default; + +// Test that a blank impl for all T conflicts with an impl for some +// specific T. + +trait MyTrait { + fn get(&self) -> usize; +} + +impl MyTrait for T { + fn get(&self) -> usize { 0 } +} + +struct MyType { + dummy: usize +} + +impl MyTrait for MyType { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + fn get(&self) -> usize { self.dummy } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket.rs new file mode 100644 index 000000000000..6aa9adc20c55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-blanket.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(unused_imports)] +// aux-build:coherence_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate coherence_lib as lib; +use lib::Remote1; + +pub trait Local { + fn foo(&self) { } +} + +impl Local for T { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-conflicting-negative-trait-impl.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-conflicting-negative-trait-impl.rs new file mode 100644 index 000000000000..75bd14a1b8f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-conflicting-negative-trait-impl.rs @@ -0,0 +1,18 @@ +#![feature(negative_impls)] +#![feature(marker_trait_attr)] + +#[marker] +trait MyTrait {} + +struct TestType(::std::marker::PhantomData); + +unsafe impl Send for TestType {} + +impl !Send for TestType {} // { dg-error ".E0751." "" { target *-*-* } } + +unsafe impl Send for TestType {} // { dg-error ".E0119." "" { target *-*-* } } + +impl !Send for TestType {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-covered-type-parameter.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-covered-type-parameter.rs new file mode 100644 index 000000000000..1b2d3a59f4ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-covered-type-parameter.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +// aux-build:coherence_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate coherence_lib as lib; +use lib::Remote; + +struct Foo(T); + +impl Remote for Foo { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-cow.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-cow.rs new file mode 100644 index 000000000000..78e7efbf6dd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-cow.rs @@ -0,0 +1,30 @@ +// revisions: re_a re_b re_c + +#![cfg_attr(any(), re_a, re_b, re_c)] + +// aux-build:coherence_lib.rs + +// Test that the `Pair` type reports an error if it contains type +// parameters, even when they are covered by local types. This test +// was originally intended to test the opposite, but the rules changed +// with RFC 1023 and this became illegal. + +extern crate coherence_lib as lib; +use lib::{Remote,Pair}; + +pub struct Cover(T); + +#[cfg(any(re_a))] +impl Remote for Pair> { } +// { dg-error "" "" { target *-*-* } .-1 } + +#[cfg(any(re_b))] +impl Remote for Pair,T> { } +// { dg-error "" "" { target *-*-* } .-1 } + +#[cfg(any(re_c))] +impl Remote for Pair,U> { } +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-cross-crate-conflict.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-cross-crate-conflict.rs new file mode 100644 index 000000000000..fb326d8b0fc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-cross-crate-conflict.rs @@ -0,0 +1,16 @@ +// The error here is strictly due to orphan rules; the impl here +// generalizes the one upstream + +// aux-build:trait_impl_conflict.rs + +extern crate trait_impl_conflict; +use trait_impl_conflict::Foo; + +impl Foo for A { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +// { dg-error ".E0210." "" { target *-*-* } .-2 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-default-trait-impl.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-default-trait-impl.rs new file mode 100644 index 000000000000..c0965531a6b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-default-trait-impl.rs @@ -0,0 +1,17 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +auto trait MySafeTrait {} + +struct Foo; + +unsafe impl MySafeTrait for Foo {} +// { dg-error ".E0199." "" { target *-*-* } .-1 } + +unsafe auto trait MyUnsafeTrait {} + +impl MyUnsafeTrait for Foo {} +// { dg-error ".E0200." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-error-suppression.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-error-suppression.rs new file mode 100644 index 000000000000..bcf150ce86b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-error-suppression.rs @@ -0,0 +1,17 @@ +// check that error types in coherence do not cause error cascades. + +trait Foo {} + +impl Foo for i8 {} +impl Foo for i16 {} +impl Foo for i32 {} +impl Foo for i64 {} +impl Foo for DoesNotExist {} +// { dg-error ".E0412." "" { target *-*-* } .-1 } +impl Foo for u8 {} +impl Foo for u16 {} +impl Foo for u32 {} +impl Foo for u64 {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-fn-covariant-bound-vs-static.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-fn-covariant-bound-vs-static.rs new file mode 100644 index 000000000000..a8b017b16442 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-fn-covariant-bound-vs-static.rs @@ -0,0 +1,27 @@ +// Test that impls for these two types are considered ovelapping: +// +// * `for<'r> fn(fn(&'r u32))` +// * `fn(fn(&'a u32)` where `'a` is free +// +// This is because, for `'a = 'static`, the two types overlap. +// Effectively for them to be equal to you get: +// +// * `for<'r> fn(fn(&'r u32)) <: fn(fn(&'static u32))` +// * true if `exists<'r> { 'r: 'static }` (obviously true) +// * `fn(fn(&'static u32)) <: for<'r> fn(fn(&'r u32))` +// * true if `forall<'r> { 'static: 'r }` (also true) + +trait Trait {} + +impl Trait for for<'r> fn(fn(&'r ())) {} +impl<'a> Trait for fn(fn(&'a ())) {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } +// +// Note in particular that we do NOT get a future-compatibility warning +// here. This is because the new leak-check proposed in [MCP 295] does not +// "error" when these two types are equated. +// +// [MCP 295]: https://github.com/rust-lang/compiler-team/issues/295 + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-fn-implied-bounds.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-fn-implied-bounds.rs new file mode 100644 index 000000000000..aaf2b43fb5c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-fn-implied-bounds.rs @@ -0,0 +1,27 @@ +// Test that our leak-check is not smart enough to take implied bounds +// into account (yet). Here we have two types that look like they +// should not be equivalent, but because of the rules on implied +// bounds we ought to know that, in fact, `'a = 'b` must always hold, +// and hence they are. +// +// Rustc can't figure this out and hence it accepts the impls but +// gives a future-compatibility warning (because we'd like to make +// this an error someday). +// +// Note that while we would like to make this a hard error, we also +// give the same warning for `coherence-wasm-bindgen.rs`, which ought +// to be accepted. + +#![deny(coherence_leak_check)] + +trait Trait {} + +impl Trait for for<'a, 'b> fn(&'a &'b u32, &'b &'a u32) -> &'b u32 {} + +impl Trait for for<'c> fn(&'c &'c u32, &'c &'c u32) -> &'c u32 { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-fn-inputs.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-fn-inputs.rs new file mode 100644 index 000000000000..b18b548c0369 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-fn-inputs.rs @@ -0,0 +1,26 @@ +// Test that we consider these two types completely equal: +// +// * `for<'a, 'b> fn(&'a u32, &'b u32)` +// * `for<'c> fn(&'c u32, &'c u32)` +// +// For a long time we considered these to be distinct types. But in fact they +// are equivalent, if you work through the implications of subtyping -- this is +// because: +// +// * `'c` can be the intersection of `'a` and `'b` (and there is always an intersection) +// * `'a` and `'b` can both be equal to `'c` + +trait Trait {} +impl Trait for for<'a, 'b> fn(&'a u32, &'b u32) {} +impl Trait for for<'c> fn(&'c u32, &'c u32) { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + // + // Note in particular that we do NOT get a future-compatibility warning + // here. This is because the new leak-check proposed in [MCP 295] does not + // "error" when these two types are equated. + // + // [MCP 295]: https://github.com/rust-lang/compiler-team/issues/295 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-free-vs-bound-region.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-free-vs-bound-region.rs new file mode 100644 index 000000000000..fec0a0c68486 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-free-vs-bound-region.rs @@ -0,0 +1,22 @@ +// Capture a coherence pattern from wasm-bindgen that we discovered as part of +// future-compatibility warning #56105. This pattern currently receives a lint +// warning but we probably want to support it long term. +// +// Key distinction: we are implementing once for `A` (take ownership) and one +// for `&A` (borrow). +// +// c.f. #56105 + +#![deny(coherence_leak_check)] + +trait TheTrait {} + +impl<'a> TheTrait for fn(&'a u8) {} + +impl TheTrait for fn(&u8) { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-fundamental-trait-objects.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-fundamental-trait-objects.rs new file mode 100644 index 000000000000..e537b9c5ba97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-fundamental-trait-objects.rs @@ -0,0 +1,16 @@ +// Check that trait objects from #[fundamental] traits are not +// treated as #[fundamental] types - the 2 meanings of #[fundamental] +// are distinct. + +// aux-build:coherence_fundamental_trait_lib.rs + +extern crate coherence_fundamental_trait_lib; + +use coherence_fundamental_trait_lib::{Fundamental, Misc}; + +pub struct Local; +impl Misc for dyn Fundamental {} +// { dg-error ".E0117." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-in-fn.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-in-fn.rs new file mode 100644 index 000000000000..617599c903bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-in-fn.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +pub fn main() { + #[derive(Copy, Clone)] + enum x { foo } + impl ::std::cmp::PartialEq for x { + fn eq(&self, other: &x) -> bool { + (*self) as isize == (*other) as isize + } + fn ne(&self, other: &x) -> bool { !(*self).eq(other) } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs new file mode 100644 index 000000000000..a3b5f86c3d0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-marker-trait-negative.rs @@ -0,0 +1,31 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +// Test for issue #56934 - that it is impossible to redundantly +// implement an auto-trait for a trait object type that contains it. + +// Negative impl variant. + +auto trait Marker1 {} +auto trait Marker2 {} + +trait Object: Marker1 {} + +// A supertrait marker is illegal... +impl !Marker1 for dyn Object + Marker2 { } // { dg-error ".E0371." "" { target *-*-* } } +// ...and also a direct component. +impl !Marker2 for dyn Object + Marker2 { } // { dg-error ".E0371." "" { target *-*-* } } + +// But implementing a marker if it is not present is OK. +impl !Marker2 for dyn Object {} // OK + +// A non-principal trait-object type is orphan even in its crate. +impl !Send for dyn Marker2 {} // { dg-error ".E0117." "" { target *-*-* } } + +// And impl'ing a remote marker for a local trait object is forbidden +// by one of these special orphan-like rules. +impl !Send for dyn Object {} // { dg-error ".E0321." "" { target *-*-* } } +impl !Send for dyn Object + Marker2 {} // { dg-error ".E0321." "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs new file mode 100644 index 000000000000..9d060f0995eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-marker-trait-positive.rs @@ -0,0 +1,31 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +// Test for issue #56934 - that it is impossible to redundantly +// implement an auto-trait for a trait object type that contains it. + +// Positive impl variant. + +auto trait Marker1 {} +auto trait Marker2 {} + +trait Object: Marker1 {} + +// A supertrait marker is illegal... +impl Marker1 for dyn Object + Marker2 { } // { dg-error ".E0371." "" { target *-*-* } } +// ...and also a direct component. +impl Marker2 for dyn Object + Marker2 { } // { dg-error ".E0371." "" { target *-*-* } } + +// But implementing a marker if it is not present is OK. +impl Marker2 for dyn Object {} // OK + +// A non-principal trait-object type is orphan even in its crate. +unsafe impl Send for dyn Marker2 {} // { dg-error ".E0117." "" { target *-*-* } } + +// And impl'ing a remote marker for a local trait object is forbidden +// by one of these special orphan-like rules. +unsafe impl Send for dyn Object {} // { dg-error ".E0321." "" { target *-*-* } } +unsafe impl Send for dyn Object + Marker2 {} // { dg-error ".E0321." "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs new file mode 100644 index 000000000000..517807da14c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs @@ -0,0 +1,11 @@ +// Test that we give suitable error messages when the user attempts to +// impl a trait `Trait` for its own object type. + +// If the trait is not object-safe, we give a more tailored message +// because we're such schnuckels: +trait NotObjectSafe { fn eq(&self, other: Self); } +impl NotObjectSafe for dyn NotObjectSafe { } +// { dg-error ".E0038." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-trait.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-trait.rs new file mode 100644 index 000000000000..305d13505e3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impl-trait-for-trait.rs @@ -0,0 +1,21 @@ +// Test that we give suitable error messages when the user attempts to +// impl a trait `Trait` for its own object type. + +trait Foo { fn dummy(&self) { } } +trait Bar: Foo { } +trait Baz: Bar { } + +// Supertraits of Baz are not legal: +impl Foo for dyn Baz { } +// { dg-error ".E0371." "" { target *-*-* } .-1 } +impl Bar for dyn Baz { } +// { dg-error ".E0371." "" { target *-*-* } .-1 } +impl Baz for dyn Baz { } +// { dg-error ".E0371." "" { target *-*-* } .-1 } + +// But other random traits are: +trait Other { } +impl Other for dyn Baz { } // OK, Other not a supertrait of Baz + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-impls-copy.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impls-copy.rs new file mode 100644 index 000000000000..37758c023fa0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impls-copy.rs @@ -0,0 +1,39 @@ +#![feature(negative_impls)] + +use std::marker::Copy; + +impl Copy for i32 {} +// { dg-error ".E0117." "" { target *-*-* } .-1 } +// { dg-error ".E0117." "" { target *-*-* } .-2 } +enum TestE { + A +} + +struct MyType; + +struct NotSync; +impl !Sync for NotSync {} + +impl Copy for TestE {} +impl Clone for TestE { fn clone(&self) -> Self { *self } } + +impl Copy for MyType {} + +impl Copy for &'static mut MyType {} +// { dg-error ".E0206." "" { target *-*-* } .-1 } +impl Clone for MyType { fn clone(&self) -> Self { *self } } + +impl Copy for (MyType, MyType) {} +// { dg-error ".E0117." "" { target *-*-* } .-1 } +// { dg-error ".E0117." "" { target *-*-* } .-2 } +impl Copy for &'static NotSync {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } +impl Copy for [MyType] {} +// { dg-error ".E0117." "" { target *-*-* } .-1 } +// { dg-error ".E0117." "" { target *-*-* } .-2 } +impl Copy for &'static [NotSync] {} +// { dg-error ".E0117." "" { target *-*-* } .-1 } +// { dg-error ".E0117." "" { target *-*-* } .-2 } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-impls-send.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impls-send.rs new file mode 100644 index 000000000000..817a6f5c5c9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impls-send.rs @@ -0,0 +1,30 @@ +#![feature(negative_impls)] + +use std::marker::Copy; + +enum TestE { + A, +} + +struct MyType; + +struct NotSync; +impl !Sync for NotSync {} + +unsafe impl Send for TestE {} +unsafe impl Send for MyType {} +unsafe impl Send for (MyType, MyType) {} +// { dg-error ".E0117." "" { target *-*-* } .-1 } + +unsafe impl Send for &'static NotSync {} +// { dg-error ".E0321." "" { target *-*-* } .-1 } + +unsafe impl Send for [MyType] {} +// { dg-error ".E0117." "" { target *-*-* } .-1 } + +unsafe impl Send for &'static [NotSync] {} +// { dg-error ".E0117." "" { target *-*-* } .-1 } +// { dg-error ".E0117." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-impls-sized.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impls-sized.rs new file mode 100644 index 000000000000..955b453034a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-impls-sized.rs @@ -0,0 +1,37 @@ +#![feature(negative_impls)] + +use std::marker::Copy; + +enum TestE { + A +} + +struct MyType; + +struct NotSync; +impl !Sync for NotSync {} + +impl Sized for TestE {} +// { dg-error ".E0322." "" { target *-*-* } .-1 } + +impl Sized for MyType {} +// { dg-error ".E0322." "" { target *-*-* } .-1 } + +impl Sized for (MyType, MyType) {} +// { dg-error ".E0117." "" { target *-*-* } .-1 } +// { dg-error ".E0117." "" { target *-*-* } .-2 } + +impl Sized for &'static NotSync {} +// { dg-error ".E0322." "" { target *-*-* } .-1 } + +impl Sized for [MyType] {} +// { dg-error ".E0117." "" { target *-*-* } .-1 } +// { dg-error ".E0117." "" { target *-*-* } .-2 } + +impl Sized for &'static [NotSync] {} +// { dg-error ".E0117." "" { target *-*-* } .-1 } +// { dg-error ".E0117." "" { target *-*-* } .-2 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs new file mode 100644 index 000000000000..197dcf792ee2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs @@ -0,0 +1,25 @@ +// Formerly this ICEd with the following message: +// Tried to project an inherited associated type during coherence checking, +// which is currently not supported. +// +// No we expect to run into a more user-friendly cycle error instead. +#![feature(specialization)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait Trait { type Assoc; } +// { dg-error ".E0391." "" { target *-*-* } .-1 } + +impl Trait for Vec { + type Assoc = (); +} + +impl Trait for Vec {} + +impl Trait for String { + type Assoc = (); +} + +impl Trait< as Trait>::Assoc> for String {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-inherited-subtyping.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-inherited-subtyping.rs new file mode 100644 index 000000000000..5f607662e703 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-inherited-subtyping.rs @@ -0,0 +1,22 @@ +// Test that two distinct impls which match subtypes of one another +// yield coherence errors (or not) depending on the variance. +// +// Note: This scenario is currently accepted, but as part of the +// universe transition (#56105) may eventually become an error. + +// revisions: old re + +struct Foo { + t: T, +} + +impl Foo fn(&'a u8, &'b u8) -> &'a u8> { + fn method1(&self) {} // { dg-error "" "" { target *-*-* } } +} + +impl Foo fn(&'a u8, &'a u8) -> &'a u8> { + fn method1(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-iterator-vec-any-elem.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-iterator-vec-any-elem.rs new file mode 100644 index 000000000000..b56639bb23c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-iterator-vec-any-elem.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +// aux-build:coherence_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate coherence_lib as lib; +use lib::Remote1; + +struct Foo(T); + +impl Remote1 for Foo { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-iterator-vec.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-iterator-vec.rs new file mode 100644 index 000000000000..6765efe91d61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-iterator-vec.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +// aux-build:coherence_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate coherence_lib as lib; +use lib::Remote1; + +struct Foo(T); + +impl Remote1 for Foo { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-lone-type-parameter.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-lone-type-parameter.rs new file mode 100644 index 000000000000..ff01a07a41a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-lone-type-parameter.rs @@ -0,0 +1,11 @@ +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::Remote; + +impl Remote for T { } +// { dg-error ".E0210." "" { target *-*-* } .-1 } + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-multidispatch-tuple.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-multidispatch-tuple.rs new file mode 100644 index 000000000000..b5b3375771f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-multidispatch-tuple.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(unused_imports)] +// pretty-expanded FIXME #23616 + +use std::fmt::Debug; +use std::default::Default; + +// Test that an impl for homogeneous pairs does not conflict with a +// heterogeneous pair. + +trait MyTrait { + fn get(&self) -> usize; +} + +impl MyTrait for (T,T) { + fn get(&self) -> usize { 0 } +} + +impl MyTrait for (usize,isize) { + fn get(&self) -> usize { 0 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-negative-impls-safe-rpass.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-negative-impls-safe-rpass.rs new file mode 100644 index 000000000000..42ad7ec42b58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-negative-impls-safe-rpass.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#![feature(negative_impls)] + +use std::marker::Send; + +struct TestType; + +impl !Send for TestType {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-negative-impls-safe.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-negative-impls-safe.rs new file mode 100644 index 000000000000..ce2f420d46a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-negative-impls-safe.rs @@ -0,0 +1,11 @@ +#![feature(negative_impls)] + +use std::marker::Send; + +struct TestType; + +unsafe impl !Send for TestType {} +// { dg-error ".E0198." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-no-direct-lifetime-dispatch.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-no-direct-lifetime-dispatch.rs new file mode 100644 index 000000000000..e0a2a3c76c8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-no-direct-lifetime-dispatch.rs @@ -0,0 +1,10 @@ +// Test that you cannot *directly* dispatch on lifetime requirements + +trait MyTrait { fn foo() {} } + +impl MyTrait for T {} +impl MyTrait for T {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-orphan.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-orphan.rs new file mode 100644 index 000000000000..ae020257aa41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-orphan.rs @@ -0,0 +1,21 @@ +// aux-build:coherence_orphan_lib.rs +#![feature(negative_impls)] + +extern crate coherence_orphan_lib as lib; + +use lib::TheTrait; + +struct TheType; + +impl TheTrait for isize { } +// { dg-error ".E0117." "" { target *-*-* } .-1 } + +impl TheTrait for isize { } + +impl TheTrait for TheType { } + +impl !Send for Vec { } +// { dg-error ".E0117." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-all-t-and-tuple.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-all-t-and-tuple.rs new file mode 100644 index 000000000000..50bc52227d45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-all-t-and-tuple.rs @@ -0,0 +1,21 @@ +// Check that we detect an overlap here in the case where: +// +// for some type X: +// T = (X,) +// T11 = X, U11 = X +// +// Seems pretty basic, but then there was issue #24241. :) + +trait From { + fn foo() {} +} + +impl From for T { +} + +impl From<(U11,)> for (T11,) { +// { dg-error ".E0119." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-downstream-inherent.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-downstream-inherent.rs new file mode 100644 index 000000000000..3bd0a3da91c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-downstream-inherent.rs @@ -0,0 +1,18 @@ +// Tests that we consider `T: Sugar + Fruit` to be ambiguous, even +// though no impls are found. + +struct Sweet(X); +pub trait Sugar {} +pub trait Fruit {} +impl Sweet { fn dummy(&self) { } } +// { dg-error ".E0592." "" { target *-*-* } .-1 } +impl Sweet { fn dummy(&self) { } } + +trait Bar {} +struct A(T, X); +impl A where T: Bar { fn f(&self) {} } +// { dg-error ".E0592." "" { target *-*-* } .-1 } +impl A { fn f(&self) {} } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-downstream.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-downstream.rs new file mode 100644 index 000000000000..4dbb5eb36d24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-downstream.rs @@ -0,0 +1,18 @@ +// Tests that we consider `T: Sugar + Fruit` to be ambiguous, even +// though no impls are found. + +pub trait Sugar {} +pub trait Fruit {} +pub trait Sweet {} +impl Sweet for T { } +impl Sweet for T { } +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +pub trait Foo {} +pub trait Bar {} +impl Foo for T where T: Bar {} +impl Foo for i32 {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-issue-23516-inherent.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-issue-23516-inherent.rs new file mode 100644 index 000000000000..eb201502f948 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-issue-23516-inherent.rs @@ -0,0 +1,14 @@ +// Tests that we consider `Box: !Sugar` to be ambiguous, even +// though we see no impl of `Sugar` for `Box`. Therefore, an overlap +// error is reported for the following pair of impls (#23516). + +pub trait Sugar {} + +struct Cake(X); + +impl Cake { fn dummy(&self) { } } +// { dg-error ".E0592." "" { target *-*-* } .-1 } +impl Cake> { fn dummy(&self) { } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-issue-23516.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-issue-23516.rs new file mode 100644 index 000000000000..f43285e39356 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-issue-23516.rs @@ -0,0 +1,12 @@ +// Tests that we consider `Box: !Sugar` to be ambiguous, even +// though we see no impl of `Sugar` for `Box`. Therefore, an overlap +// error is reported for the following pair of impls (#23516). + +pub trait Sugar { fn dummy(&self) { } } +pub trait Sweet { fn dummy(&self) { } } +impl Sweet for T { } +impl Sweet for Box { } +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-messages.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-messages.rs new file mode 100644 index 000000000000..48d54aab17c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-messages.rs @@ -0,0 +1,29 @@ +trait Foo { fn foo() {} } + +impl Foo for T {} +impl Foo for U {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + + +trait Bar { fn bar() {} } + +impl Bar for (T, u8) {} +impl Bar for (u8, T) {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +trait Baz { fn baz() {} } + +impl Baz for T {} +impl Baz for u8 {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +trait Quux { fn quux() {} } + +impl Quux for T {} +impl Quux for T {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } +impl Quux for T {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-upstream-inherent.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-upstream-inherent.rs new file mode 100644 index 000000000000..95a6f3a145fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-upstream-inherent.rs @@ -0,0 +1,17 @@ +// Tests that we consider `i16: Remote` to be ambiguous, even +// though the upstream crate doesn't implement it for now. + +// aux-build:coherence_lib.rs + + +extern crate coherence_lib; + +use coherence_lib::Remote; + +struct A(X); +impl A where T: Remote { fn dummy(&self) { } } +// { dg-error ".E0592." "" { target *-*-* } .-1 } +impl A { fn dummy(&self) { } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-upstream.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-upstream.rs new file mode 100644 index 000000000000..8143f75035c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlap-upstream.rs @@ -0,0 +1,17 @@ +// Tests that we consider `i16: Remote` to be ambiguous, even +// though the upstream crate doesn't implement it for now. + +// aux-build:coherence_lib.rs + + +extern crate coherence_lib; + +use coherence_lib::Remote; + +trait Foo {} +impl Foo for T where T: Remote {} +impl Foo for i16 {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlapping-pairs.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlapping-pairs.rs new file mode 100644 index 000000000000..beb6be19b64e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-overlapping-pairs.rs @@ -0,0 +1,12 @@ +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::Remote; + +struct Foo; + +impl Remote for lib::Pair { } +// { dg-error ".E0117." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-pair-covered-uncovered-1.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-pair-covered-uncovered-1.rs new file mode 100644 index 000000000000..3712d8c49963 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-pair-covered-uncovered-1.rs @@ -0,0 +1,16 @@ +// Test that the same coverage rules apply even if the local type appears in the +// list of type parameters, not the self type. + +// aux-build:coherence_lib.rs + + +extern crate coherence_lib as lib; +use lib::{Remote1, Pair}; + +pub struct Local(T); + +impl Remote1>> for i32 { } +// { dg-error ".E0117." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-pair-covered-uncovered.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-pair-covered-uncovered.rs new file mode 100644 index 000000000000..fbd54d3830b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-pair-covered-uncovered.rs @@ -0,0 +1,12 @@ +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::{Remote, Pair}; + +struct Local(T); + +impl Remote for Pair> { } +// { dg-error ".E0117." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-conflict-orphan.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-conflict-orphan.rs new file mode 100644 index 000000000000..7e6ec4d4c057 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-conflict-orphan.rs @@ -0,0 +1,20 @@ +#![feature(rustc_attrs)] + +// Here we expect a coherence conflict because, even though `i32` does +// not implement `Iterator`, we cannot rely on that negative reasoning +// due to the orphan rules. Therefore, `A::Item` may yet turn out to +// be `i32`. + +pub trait Foo

{ fn foo() {} } + +pub trait Bar { + type Output: 'static; +} + +impl Foo for i32 { } + +impl Foo for A { } +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-conflict-ty-param.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-conflict-ty-param.rs new file mode 100644 index 000000000000..5ab92c656ceb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-conflict-ty-param.rs @@ -0,0 +1,14 @@ +// Coherence error results because we do not know whether `T: Foo

` or not +// for the second impl. + +use std::marker::PhantomData; + +pub trait Foo

{ fn foo() {} } + +impl > Foo

for Option {} + +impl Foo for Option { } +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-conflict.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-conflict.rs new file mode 100644 index 000000000000..77221fcbda5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-conflict.rs @@ -0,0 +1,19 @@ +use std::marker::PhantomData; + +pub trait Foo

{ fn foo() {} } + +pub trait Bar { + type Output: 'static; +} + +impl Foo for i32 { } + +impl Foo for A { } +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +impl Bar for i32 { + type Output = i32; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-ok-orphan.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-ok-orphan.rs new file mode 100644 index 000000000000..7095fb17b508 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-ok-orphan.rs @@ -0,0 +1,18 @@ +// Here we do not get a coherence conflict because `Baz: Iterator` +// does not hold and (due to the orphan rules), we can rely on that. + +// check-pass + +pub trait Foo

{} + +pub trait Bar { + type Output: 'static; +} + +struct Baz; +impl Foo for Baz { } + +impl Foo for A { } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-ok.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-ok.rs new file mode 100644 index 000000000000..7f2d77ad06b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-projection-ok.rs @@ -0,0 +1,18 @@ +// check-pass + +pub trait Foo

{} + +pub trait Bar { + type Output: 'static; +} + +impl Foo for i32 { } + +impl Foo for A { } + +impl Bar for i32 { + type Output = u32; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-rfc447-constrained.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-rfc447-constrained.rs new file mode 100644 index 000000000000..2ba730ced6f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-rfc447-constrained.rs @@ -0,0 +1,23 @@ +// run-pass +// check that trait matching can handle impls whose types are only +// constrained by a projection. + +trait IsU32 {} +impl IsU32 for u32 {} + +trait Mirror { type Image: ?Sized; } +impl Mirror for T { type Image = T; } + +trait Bar {} +impl, L: Mirror> Bar for V + where U::Image: IsU32 {} + +trait Foo { fn name() -> &'static str; } +impl Foo for u64 { fn name() -> &'static str { "u64" } } +impl Foo for T { fn name() -> &'static str { "Bar" }} + +fn main() { + assert_eq!(::name(), "u64"); + assert_eq!(::name(), "Bar"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-subtyping.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-subtyping.rs new file mode 100644 index 000000000000..aca5e7f5c966 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-subtyping.rs @@ -0,0 +1,21 @@ +// Test that two distinct impls which match subtypes of one another +// yield coherence errors (or not) depending on the variance. +// +// Note: This scenario is currently accepted, but as part of the +// universe transition (#56105) may eventually become an error. + +// check-pass + +trait TheTrait { + fn foo(&self) {} +} + +impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} + +impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-tuple-conflict.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-tuple-conflict.rs new file mode 100644 index 000000000000..8db3c0da67ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-tuple-conflict.rs @@ -0,0 +1,21 @@ +use std::fmt::Debug; +use std::default::Default; + +// Test that a blank impl for all T conflicts with an impl for some +// specific T. + +trait MyTrait { + fn get(&self) -> usize; +} + +impl MyTrait for (T,T) { + fn get(&self) -> usize { 0 } +} + +impl MyTrait for (A,B) { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + fn get(&self) -> usize { self.dummy } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-unsafe-trait-object-impl.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-unsafe-trait-object-impl.rs new file mode 100644 index 000000000000..a3ab318b0e9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-unsafe-trait-object-impl.rs @@ -0,0 +1,19 @@ +// Check that unsafe trait object do not implement themselves +// automatically + +#![feature(object_safe_for_dispatch)] + +trait Trait: Sized { + fn call(&self); +} + +fn takes_t(s: S) { + s.call(); +} + +fn takes_t_obj(t: &dyn Trait) { + takes_t(t); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-vec-local-2.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-vec-local-2.rs new file mode 100644 index 000000000000..f5f6a139dfe5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-vec-local-2.rs @@ -0,0 +1,15 @@ +// Test that a local, generic type appearing within a +// *non-fundamental* remote type like `Vec` is not considered local. + +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::Remote; + +struct Local(T); + +impl Remote for Vec> { } +// { dg-error ".E0117." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-vec-local.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-vec-local.rs new file mode 100644 index 000000000000..f5e1909b6bed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-vec-local.rs @@ -0,0 +1,15 @@ +// Test that a local type (with no type parameters) appearing within a +// *non-fundamental* remote type like `Vec` is not considered local. + +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::Remote; + +struct Local; + +impl Remote for Vec { } +// { dg-error ".E0117." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-wasm-bindgen.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-wasm-bindgen.rs new file mode 100644 index 000000000000..7611dd6b1db2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-wasm-bindgen.rs @@ -0,0 +1,38 @@ +// Capture a coherence pattern from wasm-bindgen that we discovered as part of +// future-compatibility warning #56105. This pattern currently receives a lint +// warning but we probably want to support it long term. +// +// Key distinction: we are implementing once for `A` (take ownership) and one +// for `&A` (borrow). +// +// c.f. #56105 + +#![deny(coherence_leak_check)] + +trait IntoWasmAbi { + fn some_method(&self) {} +} + +trait FromWasmAbi {} +trait RefFromWasmAbi {} +trait ReturnWasmAbi {} + +impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn Fn(A) -> R + 'b) +where + A: FromWasmAbi, + R: ReturnWasmAbi, +{ +} + +// Explicitly writing the bound lifetime. +impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn for<'x> Fn(&'x A) -> R + 'b) +where + A: RefFromWasmAbi, + R: ReturnWasmAbi, +{ +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence-where-clause.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence-where-clause.rs new file mode 100644 index 000000000000..5b63c59dc09b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence-where-clause.rs @@ -0,0 +1,39 @@ +// run-pass + +use std::fmt::Debug; +use std::default::Default; + +trait MyTrait { + fn get(&self) -> Self; +} + +impl MyTrait for T + where T : Default +{ + fn get(&self) -> T { + Default::default() + } +} + +#[derive(Clone, Copy, Debug, PartialEq)] +struct MyType { + dummy: usize +} + +impl MyTrait for MyType { + fn get(&self) -> MyType { (*self).clone() } +} + +fn test_eq(m: M, n: M) +where M : MyTrait + Debug + PartialEq +{ + assert_eq!(m.get(), n); +} + +pub fn main() { + test_eq(0_usize, 0_usize); + + let value = MyType { dummy: 256 + 22 }; + test_eq(value, value); +} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like.rs new file mode 100644 index 000000000000..34735d73eef6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// aux-build:coherence_copy_like_lib.rs + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +trait MyTrait { } +impl MyTrait for T { } +impl MyTrait for MyType { } +impl<'a> MyTrait for &'a MyType { } +impl MyTrait for Box { } +impl<'a> MyTrait for &'a Box { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct.rs new file mode 100644 index 000000000000..fb0c5b6eca21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct.rs @@ -0,0 +1,25 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// aux-build:coherence_copy_like_lib.rs +// build-pass (FIXME(62277): could be check-pass?) +// skip-codgen +#![allow(dead_code)] + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +trait MyTrait { fn foo() {} } +impl MyTrait for T { } + +// `MyFundamentalStruct` is declared fundamental, so we can test that +// +// MyFundamentalStruct: !MyTrait +// +// Huzzah. +impl MyTrait for lib::MyFundamentalStruct { } + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs new file mode 100644 index 000000000000..beee81afa943 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs @@ -0,0 +1,22 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// check-pass +// aux-build:coherence_copy_like_lib.rs + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +trait MyTrait { fn foo() {} } +impl MyTrait for T { } + +// `MyFundamentalStruct` is declared fundamental, so we can test that +// +// MyFundamentalStruct<&MyTrait>: !MyTrait +// +// Huzzah. +impl<'a> MyTrait for lib::MyFundamentalStruct<&'a MyType> { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs new file mode 100644 index 000000000000..4aadd06ebbdd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs @@ -0,0 +1,21 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// aux-build:coherence_copy_like_lib.rs + + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +trait MyTrait { fn foo() {} } + +impl MyTrait for T { } + +// Tuples are not fundamental. +impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { } +// { dg-error ".E0119." "" { target *-*-* } .-1 } + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_struct.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_struct.rs new file mode 100644 index 000000000000..66561878d1cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_struct.rs @@ -0,0 +1,23 @@ +// aux-build:coherence_copy_like_lib.rs + +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +trait MyTrait { fn foo() {} } +impl MyTrait for T { } + +// `MyStruct` is not declared fundamental, therefore this would +// require that +// +// MyStruct: !MyTrait +// +// which we cannot approve. +impl MyTrait for lib::MyStruct { } +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_tuple.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_tuple.rs new file mode 100644 index 000000000000..7e8d0303cca1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence_copy_like_err_tuple.rs @@ -0,0 +1,22 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// aux-build:coherence_copy_like_lib.rs + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +trait MyTrait { fn foo() {} } +impl MyTrait for T { } + +// Tuples are not fundamental, therefore this would require that +// +// (MyType,): !MyTrait +// +// which we cannot approve. +impl MyTrait for (MyType,) { } +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence_inherent.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence_inherent.rs new file mode 100644 index 000000000000..b9d8ca0079e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence_inherent.rs @@ -0,0 +1,37 @@ +// Tests that methods that implement a trait cannot be invoked +// unless the trait is imported. + +mod Lib { + pub trait TheTrait { + fn the_fn(&self); + } + + pub struct TheStruct; + + impl TheTrait for TheStruct { + fn the_fn(&self) {} + } +} + +mod Import { + // Trait is in scope here: + use Lib::TheStruct; + use Lib::TheTrait; + + fn call_the_fn(s: &TheStruct) { + s.the_fn(); + } +} + +mod NoImport { + // Trait is not in scope here: + use Lib::TheStruct; + + fn call_the_fn(s: &TheStruct) { + s.the_fn(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence_inherent_cc.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence_inherent_cc.rs new file mode 100644 index 000000000000..7a67aa2756fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence_inherent_cc.rs @@ -0,0 +1,29 @@ +// aux-build:coherence_inherent_cc_lib.rs + +// Tests that methods that implement a trait cannot be invoked +// unless the trait is imported. + +extern crate coherence_inherent_cc_lib; + +mod Import { + // Trait is in scope here: + use coherence_inherent_cc_lib::TheStruct; + use coherence_inherent_cc_lib::TheTrait; + + fn call_the_fn(s: &TheStruct) { + s.the_fn(); + } +} + +mod NoImport { + // Trait is not in scope here: + use coherence_inherent_cc_lib::TheStruct; + + fn call_the_fn(s: &TheStruct) { + s.the_fn(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence_local.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence_local.rs new file mode 100644 index 000000000000..6ddf092e26a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence_local.rs @@ -0,0 +1,21 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// check-pass +// aux-build:coherence_copy_like_lib.rs + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +// These are all legal because they are all fundamental types: + +impl lib::MyCopy for MyType { } +impl<'a> lib::MyCopy for &'a MyType { } +impl<'a> lib::MyCopy for &'a Box { } +impl lib::MyCopy for Box { } +impl lib::MyCopy for lib::MyFundamentalStruct { } +impl lib::MyCopy for lib::MyFundamentalStruct> { } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence_local_err_struct.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence_local_err_struct.rs new file mode 100644 index 000000000000..af726f4f6da3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence_local_err_struct.rs @@ -0,0 +1,19 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// aux-build:coherence_copy_like_lib.rs +#![allow(dead_code)] + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +// These are all legal because they are all fundamental types: + +// MyStruct is not fundamental. +impl lib::MyCopy for lib::MyStruct { } +// { dg-error ".E0117." "" { target *-*-* } .-1 } + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence_local_err_tuple.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence_local_err_tuple.rs new file mode 100644 index 000000000000..0cfe2f6e3fac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence_local_err_tuple.rs @@ -0,0 +1,19 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// aux-build:coherence_copy_like_lib.rs +#![allow(dead_code)] + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +// These are all legal because they are all fundamental types: + +// Tuples are not fundamental, so this is not a local impl. +impl lib::MyCopy for (MyType,) { } +// { dg-error ".E0117." "" { target *-*-* } .-1 } + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/coherence_local_ref.rs b/gcc/testsuite/rust/rustc/ui/coherence/coherence_local_ref.rs new file mode 100644 index 000000000000..764b47897391 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/coherence_local_ref.rs @@ -0,0 +1,15 @@ +// Test that we are able to introduce a negative constraint that +// `MyType: !MyTrait` along with other "fundamental" wrappers. + +// check-pass +// aux-build:coherence_copy_like_lib.rs + +extern crate coherence_copy_like_lib as lib; + +struct MyType { x: i32 } + +// naturally, legal +impl lib::MyCopy for MyType { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/conflicting-impl-with-err.rs b/gcc/testsuite/rust/rustc/ui/coherence/conflicting-impl-with-err.rs new file mode 100644 index 000000000000..18e4484f2f8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/conflicting-impl-with-err.rs @@ -0,0 +1,17 @@ +struct ErrorKind; +struct Error(ErrorKind); + +impl From for Error { // { dg-error ".E0433." "" { target *-*-* } } + fn from(_: nope::Thing) -> Self { // { dg-error ".E0433." "" { target *-*-* } } + unimplemented!() + } +} + +impl From for Error { + fn from(_: ErrorKind) -> Self { + unimplemented!() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-foreign.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-foreign.rs new file mode 100644 index 000000000000..c3ba39e67440 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-foreign.rs @@ -0,0 +1,16 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote for i32 { +// { dg-error ".E0117." "" { target *-*-* } .-1 } + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-foreign[foreign].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-foreign[foreign].rs new file mode 100644 index 000000000000..af6eb5b1c5a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-foreign[foreign].rs @@ -0,0 +1,24 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1> for i32 { +// { dg-error ".E0117." "" { target *-*-* } .-1 } + // | can be implemented for arbitrary types [E0117] +} +impl Remote1> for f64 { +// { dg-error ".E0117." "" { target *-*-* } .-1 } + // | can be implemented for arbitrary types [E0117] +} +impl Remote1> for f32 { +// { dg-error ".E0117." "" { target *-*-* } .-1 } + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-foreign[local].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-foreign[local].rs new file mode 100644 index 000000000000..e9b37e777a94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-foreign[local].rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local(Rc); + +impl Remote1> for i32 {} +impl Remote1> for f32 {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-fundamental[foreign].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-fundamental[foreign].rs new file mode 100644 index 000000000000..268eae9a5139 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-fundamental[foreign].rs @@ -0,0 +1,20 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote for Box { +// { dg-error ".E0117." "" { target *-*-* } .-1 } + // | can be implemented for arbitrary types [E0117] +} +impl Remote for Box> { +// { dg-error ".E0117." "" { target *-*-* } .-1 } + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-fundamental[local].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-fundamental[local].rs new file mode 100644 index 000000000000..04c63ceae00a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-fundamental[local].rs @@ -0,0 +1,16 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1(Rc); + +impl Remote for Box {} +impl Remote for Box> {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-local.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-local.rs new file mode 100644 index 000000000000..77a86115b9f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-local.rs @@ -0,0 +1,14 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote for Local {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs new file mode 100644 index 000000000000..d3600ef8236a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs @@ -0,0 +1,16 @@ +#![feature(fundamental)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; + +#[fundamental] +struct Local(T); + +impl Remote for Local<()> {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs new file mode 100644 index 000000000000..9284576ef994 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs @@ -0,0 +1,16 @@ +#![feature(fundamental)] + +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; + +#[fundamental] +struct MyBox(T); + +impl Remote for MyBox {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[foreign]-for-foreign.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[foreign]-for-foreign.rs new file mode 100644 index 000000000000..06f00ff85923 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[foreign]-for-foreign.rs @@ -0,0 +1,16 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for f64 { +// { dg-error ".E0117." "" { target *-*-* } .-1 } + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[foreign]-for-local.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[foreign]-for-local.rs new file mode 100644 index 000000000000..bbb05b18ee9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[foreign]-for-local.rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Local { +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs new file mode 100644 index 000000000000..8959df5a8c84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs @@ -0,0 +1,25 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1(Rc); + +impl Remote1> for i32 { +// { dg-error ".E0117." "" { target *-*-* } .-1 } + // | can be implemented for arbitrary types [E0117] +} +impl Remote1>> for f64 { +// { dg-error ".E0117." "" { target *-*-* } .-1 } + // | can be implemented for arbitrary types [E0117] +} +impl Remote1>> for f32 { +// { dg-error ".E0117." "" { target *-*-* } .-1 } + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs new file mode 100644 index 000000000000..0233136367db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs @@ -0,0 +1,17 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1(Rc); + +impl Remote1> for i32 {} +impl Remote1>> for f64 {} +impl Remote1>> for f32 {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign-for-foreign[t].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign-for-foreign[t].rs new file mode 100644 index 000000000000..dcd04f1c84e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign-for-foreign[t].rs @@ -0,0 +1,22 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; +use std::sync::Arc; + +struct Local; + +impl Remote for Rc { +// { dg-error ".E0117." "" { target *-*-* } .-1 } + // | can be implemented for arbitrary types [E0117] +} + +impl Remote for Arc { +// { dg-error ".E0117." "" { target *-*-* } .-1 } + // | can be implemented for arbitrary types [E0117] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign-for-fundamental[t].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign-for-fundamental[t].rs new file mode 100644 index 000000000000..85d9f5b59030 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign-for-fundamental[t].rs @@ -0,0 +1,16 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote for Box { +// { dg-error ".E0210." "" { target *-*-* } .-1 } + // | some local type (e.g., `MyStruct`) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs new file mode 100644 index 000000000000..f8ad5af4a08d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs @@ -0,0 +1,13 @@ +// check-pass +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +impl Remote2, Local> for usize { } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs new file mode 100644 index 000000000000..756d76b36644 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs @@ -0,0 +1,19 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Box { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +impl<'a, T> Remote1 for &'a T { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[foreign]-for-t.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[foreign]-for-t.rs new file mode 100644 index 000000000000..22da697a7485 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[foreign]-for-t.rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for T { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs new file mode 100644 index 000000000000..2948e8a2f03e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs @@ -0,0 +1,19 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1> for u32 { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +impl<'a, T> Remote1<&'a T> for u32 { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs new file mode 100644 index 000000000000..0580768b69e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs @@ -0,0 +1,18 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl<'a, T> Remote1> for &'a T { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} +impl<'a, T> Remote1<&'a T> for Box { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs new file mode 100644 index 000000000000..77682322a030 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs @@ -0,0 +1,16 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1> for Local {} + +impl<'a, T> Remote1<&'a T> for Local {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs new file mode 100644 index 000000000000..ae76f7d3317f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs @@ -0,0 +1,18 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1> for T { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} +impl<'a, T> Remote1<&'a T> for T { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs new file mode 100644 index 000000000000..86bec35a0eae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs @@ -0,0 +1,19 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote2, Local> for u32 { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +impl<'a, T> Remote2<&'a T, Local> for u32 { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs new file mode 100644 index 000000000000..430f0bcd64d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs @@ -0,0 +1,16 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1(Rc); + +impl Remote1> for Rc {} +impl Remote1>> for Rc {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-foreign.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-foreign.rs new file mode 100644 index 000000000000..3bec7276be27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-foreign.rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Rc {} +impl Remote1 for Vec> {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs new file mode 100644 index 000000000000..6f5f89fc1957 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs @@ -0,0 +1,16 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1(Rc); + +impl Remote1 for Rc {} +impl Remote1> for Rc {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs new file mode 100644 index 000000000000..9398e85ca019 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs @@ -0,0 +1,18 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local1(Rc); + +impl Remote1 for Box> {} +impl Remote1> for Box> {} +impl Remote1> for Box> {} +impl Remote1>> for Box> {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs new file mode 100644 index 000000000000..1159ac013f5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs @@ -0,0 +1,19 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Box { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +impl Remote1 for &T { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-local.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-local.rs new file mode 100644 index 000000000000..f3e93dd10df3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-local.rs @@ -0,0 +1,14 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Local {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-t.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-t.rs new file mode 100644 index 000000000000..a7357e14e868 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local]-for-t.rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for T { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs new file mode 100644 index 000000000000..e9311895d10f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs @@ -0,0 +1,18 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; +struct Local2(Rc); + +impl Remote2> for u32 {} +impl<'a, T> Remote2 for u32 {} +impl Remote2, Box> for u32 {} +impl<'a, T> Remote2, &'a T> for u32 {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-foreign.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-foreign.rs new file mode 100644 index 000000000000..623addb24c18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-foreign.rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for u32 { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs new file mode 100644 index 000000000000..6bafa7a2cbe1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs @@ -0,0 +1,19 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Box { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +impl<'a, A, B> Remote1 for &'a B { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-local.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-local.rs new file mode 100644 index 000000000000..a2c10da5fcfb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-local.rs @@ -0,0 +1,14 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs +// check-pass + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for Local {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-t.rs b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-t.rs new file mode 100644 index 000000000000..4d719f890364 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/impl[t]-foreign[t]-for-t.rs @@ -0,0 +1,15 @@ +// compile-flags:--crate-name=test +// aux-build:coherence_lib.rs + +extern crate coherence_lib as lib; +use lib::*; +use std::rc::Rc; + +struct Local; + +impl Remote1 for T { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs b/gcc/testsuite/rust/rustc/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs new file mode 100644 index 000000000000..e143fbb2bf8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs @@ -0,0 +1,27 @@ +// run-pass +// aux-build:re_rebalance_coherence_lib-rpass.rs + +#![allow(dead_code)] +// check that a generic type with a default value from an associated type can be used without +// specifying the value, and without invoking coherence errors. + +extern crate re_rebalance_coherence_lib_rpass as lib; +use lib::*; + +struct MyString {} + +impl LibToOwned for MyString { + type Owned = String; +} + +impl PartialEq for LibCow { + fn eq(&self, _other: &MyString) -> bool { + // Test that the default type is used. + let _s: &String = &self.o; + + false + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/coherence/re-rebalance-coherence.rs b/gcc/testsuite/rust/rustc/ui/coherence/re-rebalance-coherence.rs new file mode 100644 index 000000000000..915d12384b67 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/coherence/re-rebalance-coherence.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:re_rebalance_coherence_lib.rs + +extern crate re_rebalance_coherence_lib as lib; +use lib::*; + +struct Oracle; +impl Backend for Oracle {} +impl<'a, T:'a, Tab> QueryFragment for BatchInsert<'a, T, Tab> {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/collections-const-new.rs b/gcc/testsuite/rust/rustc/ui/collections-const-new.rs new file mode 100644 index 000000000000..2b310866ec0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/collections-const-new.rs @@ -0,0 +1,21 @@ +// check-pass + +// Test several functions can be used for constants +// 1. Vec::new() +// 2. String::new() +// 3. BTreeMap::new() +// 4. BTreeSet::new() + +#![feature(const_btree_new)] + +const MY_VEC: Vec = Vec::new(); + +const MY_STRING: String = String::new(); + +use std::collections::{BTreeMap, BTreeSet}; +const MY_BTREEMAP: BTreeMap = BTreeMap::new(); + +const MY_BTREESET: BTreeSet = BTreeSet::new(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/command-line-diagnostics.rs b/gcc/testsuite/rust/rustc/ui/command-line-diagnostics.rs new file mode 100644 index 000000000000..5733359c44e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/command-line-diagnostics.rs @@ -0,0 +1,8 @@ +// This test checks the output format without the intermediate json representation +// compile-flags: --error-format=human + +pub fn main() { + let x = 42; + x = 43; +} + diff --git a/gcc/testsuite/rust/rustc/ui/command/command-argv0-debug.rs b/gcc/testsuite/rust/rustc/ui/command/command-argv0-debug.rs new file mode 100644 index 000000000000..9d8f77c1e8b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/command/command-argv0-debug.rs @@ -0,0 +1,23 @@ +// run-pass + +// ignore-windows - this is a unix-specific test +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +use std::os::unix::process::CommandExt; +use std::process::Command; + +fn main() { + let mut command = Command::new("some-boring-name"); + + assert_eq!(format!("{:?}", command), r#""some-boring-name""#); + + command.args(&["1", "2", "3"]); + + assert_eq!(format!("{:?}", command), r#""some-boring-name" "1" "2" "3""#); + + command.arg0("exciting-name"); + + assert_eq!(format!("{:?}", command), r#"["some-boring-name"] "exciting-name" "1" "2" "3""#); +} + diff --git a/gcc/testsuite/rust/rustc/ui/command/command-argv0.rs b/gcc/testsuite/rust/rustc/ui/command/command-argv0.rs new file mode 100644 index 000000000000..7772325a53a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/command/command-argv0.rs @@ -0,0 +1,32 @@ +// run-pass + +// ignore-windows - this is a unix-specific test +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +use std::env; +use std::os::unix::process::CommandExt; +use std::process::Command; + +fn main() { + let args: Vec<_> = env::args().collect(); + + if args.len() > 1 { + assert_eq!(args[1], "doing-test"); + assert_eq!(args[0], "i have a silly name"); + + println!("passed"); + return; + } + + let output = + Command::new(&args[0]).arg("doing-test").arg0("i have a silly name").output().unwrap(); + assert!( + output.stderr.is_empty(), + "Non-empty stderr: {}", + String::from_utf8_lossy(&output.stderr) + ); + assert!(output.status.success()); + assert_eq!(output.stdout, b"passed\n"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/command/command-exec.rs b/gcc/testsuite/rust/rustc/ui/command/command-exec.rs new file mode 100644 index 000000000000..dcf5ccde7d93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/command/command-exec.rs @@ -0,0 +1,105 @@ +// run-pass + +#![allow(stable_features)] +// ignore-windows - this is a unix-specific test +// ignore-pretty issue #37199 +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +#![feature(process_exec)] + +use std::env; +use std::os::unix::process::CommandExt; +use std::process::Command; + +fn main() { + let mut args = env::args(); + let me = args.next().unwrap(); + + if let Some(arg) = args.next() { + match &arg[..] { + "test1" => println!("passed"), + + "exec-test1" => { + let err = Command::new(&me).arg("test1").exec(); + panic!("failed to spawn: {}", err); + } + + "exec-test2" => { + Command::new("/path/to/nowhere").exec(); + println!("passed"); + } + + "exec-test3" => { + Command::new(&me).arg("bad\0").exec(); + println!("passed"); + } + + "exec-test4" => { + Command::new(&me).current_dir("/path/to/nowhere").exec(); + println!("passed"); + } + + "exec-test5" => { + env::set_var("VARIABLE", "ABC"); + Command::new("definitely-not-a-real-binary").env("VARIABLE", "XYZ").exec(); + assert_eq!(env::var("VARIABLE").unwrap(), "ABC"); + println!("passed"); + } + + "exec-test6" => { + let err = Command::new("echo").arg("passed").env_clear().exec(); + panic!("failed to spawn: {}", err); + } + + "exec-test7" => { + let err = Command::new("echo").arg("passed").env_remove("PATH").exec(); + panic!("failed to spawn: {}", err); + } + + _ => panic!("unknown argument: {}", arg), + } + return + } + + let output = Command::new(&me).arg("exec-test1").output().unwrap(); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"passed\n"); + + let output = Command::new(&me).arg("exec-test2").output().unwrap(); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"passed\n"); + + let output = Command::new(&me).arg("exec-test3").output().unwrap(); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"passed\n"); + + let output = Command::new(&me).arg("exec-test4").output().unwrap(); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"passed\n"); + + let output = Command::new(&me).arg("exec-test5").output().unwrap(); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"passed\n"); + + if cfg!(target_os = "linux") { + let output = Command::new(&me).arg("exec-test6").output().unwrap(); + println!("{:?}", output); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"passed\n"); + + let output = Command::new(&me).arg("exec-test7").output().unwrap(); + println!("{:?}", output); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"passed\n"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/command/command-pre-exec.rs b/gcc/testsuite/rust/rustc/ui/command/command-pre-exec.rs new file mode 100644 index 000000000000..87d4a41a6a33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/command/command-pre-exec.rs @@ -0,0 +1,119 @@ +// run-pass + +#![allow(stable_features)] +// ignore-windows - this is a unix-specific test +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +#![feature(process_exec, rustc_private)] + +extern crate libc; + +use std::env; +use std::io::Error; +use std::os::unix::process::CommandExt; +use std::process::Command; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; + +fn main() { + if let Some(arg) = env::args().nth(1) { + match &arg[..] { + "test1" => println!("hello2"), + "test2" => assert_eq!(env::var("FOO").unwrap(), "BAR"), + "test3" => assert_eq!(env::current_dir().unwrap().to_str().unwrap(), "/"), + "empty" => {} + _ => panic!("unknown argument: {}", arg), + } + return; + } + + let me = env::current_exe().unwrap(); + + let output = unsafe { + Command::new(&me) + .arg("test1") + .pre_exec(|| { + println!("hello"); + Ok(()) + }) + .output() + .unwrap() + }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"hello\nhello2\n"); + + let output = unsafe { + Command::new(&me) + .arg("test2") + .pre_exec(|| { + env::set_var("FOO", "BAR"); + Ok(()) + }) + .output() + .unwrap() + }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); + + let output = unsafe { + Command::new(&me) + .arg("test3") + .pre_exec(|| { + env::set_current_dir("/").unwrap(); + Ok(()) + }) + .output() + .unwrap() + }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); + + let output = unsafe { + Command::new(&me) + .arg("bad") + .pre_exec(|| Err(Error::from_raw_os_error(102))) + .output() + .unwrap_err() + }; + assert_eq!(output.raw_os_error(), Some(102)); + + let pid = unsafe { libc::getpid() }; + assert!(pid >= 0); + let output = unsafe { + Command::new(&me) + .arg("empty") + .pre_exec(move || { + let child = libc::getpid(); + assert!(child >= 0); + assert!(pid != child); + Ok(()) + }) + .output() + .unwrap() + }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); + + let mem = Arc::new(AtomicUsize::new(0)); + let mem2 = mem.clone(); + let output = unsafe { + Command::new(&me) + .arg("empty") + .pre_exec(move || { + assert_eq!(mem2.fetch_add(1, Ordering::SeqCst), 0); + Ok(()) + }) + .output() + .unwrap() + }; + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert!(output.stdout.is_empty()); + assert_eq!(mem.load(Ordering::SeqCst), 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/command/command-uid-gid.rs b/gcc/testsuite/rust/rustc/ui/command/command-uid-gid.rs new file mode 100644 index 000000000000..c17a22f5a623 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/command/command-uid-gid.rs @@ -0,0 +1,33 @@ +// run-pass +// ignore-android +// ignore-cloudabi +// ignore-emscripten +// ignore-sgx + +#![feature(rustc_private)] + +fn main() { + #[cfg(unix)] + run() +} + +#[cfg(unix)] +fn run() { + extern crate libc; + use std::process::Command; + use std::os::unix::prelude::*; + + let mut p = Command::new("/bin/sh") + .arg("-c").arg("true") + .uid(unsafe { libc::getuid() }) + .gid(unsafe { libc::getgid() }) + .spawn().unwrap(); + assert!(p.wait().unwrap().success()); + + // if we're already root, this isn't a valid test. Most of the bots run + // as non-root though (android is an exception). + if unsafe { libc::getuid() != 0 } { + assert!(Command::new("/bin/ls").uid(0).gid(0).spawn().is_err()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/commandline-argfile-badutf8.rs b/gcc/testsuite/rust/rustc/ui/commandline-argfile-badutf8.rs new file mode 100644 index 000000000000..5e3853910010 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/commandline-argfile-badutf8.rs @@ -0,0 +1,13 @@ +// Check to see if we can get parameters from an @argsfile file +// +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/commandline-argfile-missing.rs b/gcc/testsuite/rust/rustc/ui/commandline-argfile-missing.rs new file mode 100644 index 000000000000..2d5e41334f96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/commandline-argfile-missing.rs @@ -0,0 +1,16 @@ +// Check to see if we can get parameters from an @argsfile file +// +// ignore-tidy-linelength +// normalize-stderr-test: "os error \d+" -> "os error $$ERR" +// normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/commandline-argfile.rs b/gcc/testsuite/rust/rustc/ui/commandline-argfile.rs new file mode 100644 index 000000000000..98254f074644 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/commandline-argfile.rs @@ -0,0 +1,14 @@ +// Check to see if we can get parameters from an @argsfile file +// +// build-pass +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/compare-method/proj-outlives-region.rs b/gcc/testsuite/rust/rustc/ui/compare-method/proj-outlives-region.rs new file mode 100644 index 000000000000..f6f5dd840c8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/compare-method/proj-outlives-region.rs @@ -0,0 +1,15 @@ +// Test that we elaborate `Type: 'region` constraints and infer various important things. + +trait Master<'a, T: ?Sized, U> { + fn foo() where T: 'a; +} + +// `U::Item: 'a` does not imply that `U: 'a` +impl<'a, U: Iterator> Master<'a, U::Item, U> for () { + fn foo() where U: 'a { } // { dg-error ".E0276." "" { target *-*-* } } +} + +fn main() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/compare-method/region-extra-2.rs b/gcc/testsuite/rust/rustc/ui/compare-method/region-extra-2.rs new file mode 100644 index 000000000000..a19d97a3cfce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/compare-method/region-extra-2.rs @@ -0,0 +1,16 @@ +// Regression test for issue #22779. An extra where clause was +// permitted on the impl that is not present on the trait. + +trait Tr<'a, T> { + fn renew<'b: 'a>(self) -> &'b mut [T]; +} + +impl<'a, T> Tr<'a, T> for &'a mut [T] { + fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b { +// { dg-error ".E0276." "" { target *-*-* } .-1 } + &mut self[..] + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/compare-method/region-extra.rs b/gcc/testsuite/rust/rustc/ui/compare-method/region-extra.rs new file mode 100644 index 000000000000..ee08c429ceeb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/compare-method/region-extra.rs @@ -0,0 +1,15 @@ +// Test that you cannot add an extra where clause in the impl relating +// two regions. + +trait Master<'a, 'b> { + fn foo(); +} + +impl<'a, 'b> Master<'a, 'b> for () { + fn foo() where 'a: 'b { } // { dg-error ".E0276." "" { target *-*-* } } +} + +fn main() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/compare-method/region-unrelated.rs b/gcc/testsuite/rust/rustc/ui/compare-method/region-unrelated.rs new file mode 100644 index 000000000000..adac5c91ea83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/compare-method/region-unrelated.rs @@ -0,0 +1,16 @@ +// Test that we elaborate `Type: 'region` constraints and infer various important things. + +trait Master<'a, T: ?Sized, U> { + fn foo() where T: 'a; +} + +// `U: 'a` does not imply `V: 'a` +impl<'a, U, V> Master<'a, U, V> for () { + fn foo() where V: 'a { } +// { dg-error ".E0276." "" { target *-*-* } .-1 } +} + +fn main() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/compare-method/reordered-type-param.rs b/gcc/testsuite/rust/rustc/ui/compare-method/reordered-type-param.rs new file mode 100644 index 000000000000..c25d206f2675 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/compare-method/reordered-type-param.rs @@ -0,0 +1,20 @@ +// Tests that ty params get matched correctly when comparing +// an impl against a trait +// +// cc #26111 + +trait A { + fn b(&self, x: C) -> C; +} + +struct E { + f: isize +} + +impl A for E { + // n.b. The error message is awful -- see #3404 + fn b(&self, _x: G) -> G { panic!() } // { dg-error ".E0053." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/compare-method/trait-bound-on-type-parameter.rs b/gcc/testsuite/rust/rustc/ui/compare-method/trait-bound-on-type-parameter.rs new file mode 100644 index 000000000000..ca73b1598aa7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/compare-method/trait-bound-on-type-parameter.rs @@ -0,0 +1,19 @@ +// Tests that impl can't add extra `F: Sync` bound aren't *more* restrictive +// than the trait method it's implementing. +// +// Regr test for #26111. + +trait A { + fn b(&self, x: C) -> C; +} + +struct E { + f: isize +} + +impl A for E { + fn b(&self, _x: F) -> F { panic!() } // { dg-error ".E0276." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/compare-method/traits-misc-mismatch-1.rs b/gcc/testsuite/rust/rustc/ui/compare-method/traits-misc-mismatch-1.rs new file mode 100644 index 000000000000..c7b9d82396d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/compare-method/traits-misc-mismatch-1.rs @@ -0,0 +1,72 @@ +// +// Make sure rustc checks the type parameter bounds in implementations of traits, +// see #2687 + +use std::marker; + +trait A { } + +trait B: A {} + +trait C: A {} + +trait Foo { + fn test_error1_fn(&self); + fn test_error2_fn(&self); + fn test_error3_fn(&self); + fn test3_fn(&self); + fn test4_fn(&self); + fn test_error5_fn(&self); + fn test6_fn(&self); + fn test_error7_fn(&self); + fn test_error8_fn(&self); +} + +impl Foo for isize { + // invalid bound for T, was defined as Eq in trait + fn test_error1_fn(&self) {} +// { dg-error ".E0276." "" { target *-*-* } .-1 } + + // invalid bound for T, was defined as Eq + Ord in trait + fn test_error2_fn(&self) {} +// { dg-error ".E0276." "" { target *-*-* } .-1 } + + // invalid bound for T, was defined as Eq + Ord in trait + fn test_error3_fn(&self) {} +// { dg-error ".E0276." "" { target *-*-* } .-1 } + + // multiple bounds, same order as in trait + fn test3_fn(&self) {} + + // multiple bounds, different order as in trait + fn test4_fn(&self) {} + + // parameters in impls must be equal or more general than in the defining trait + fn test_error5_fn(&self) {} +// { dg-error ".E0276." "" { target *-*-* } .-1 } + + // bound `std::cmp::Eq` not enforced by this implementation, but this is OK + fn test6_fn(&self) {} + + fn test_error7_fn(&self) {} +// { dg-error ".E0276." "" { target *-*-* } .-1 } + + fn test_error8_fn(&self) {} +// { dg-error ".E0276." "" { target *-*-* } .-1 } +} + +trait Getter { + fn get(&self) -> T { loop { } } +} + +trait Trait { + fn method>(&self); +} + +impl Trait for usize { + fn method>(&self) {} +// { dg-error ".E0276." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/compare-method/traits-misc-mismatch-2.rs b/gcc/testsuite/rust/rustc/ui/compare-method/traits-misc-mismatch-2.rs new file mode 100644 index 000000000000..eb9d186ec0a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/compare-method/traits-misc-mismatch-2.rs @@ -0,0 +1,24 @@ +// Issue #5886: a complex instance of issue #2687. + +trait Iterator { + fn next(&mut self) -> Option; +} + +trait IteratorUtil: Sized +{ + fn zip>(self, other: U) -> ZipIterator; +} + +impl> IteratorUtil for T { + fn zip>(self, other: U) -> ZipIterator { +// { dg-error ".E0276." "" { target *-*-* } .-1 } + ZipIterator{a: self, b: other} + } +} + +struct ZipIterator { + a: T, b: U +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/compile_error_macro.rs b/gcc/testsuite/rust/rustc/ui/compile_error_macro.rs new file mode 100644 index 000000000000..c9ee4d8a8cb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/compile_error_macro.rs @@ -0,0 +1,4 @@ +fn main() { + compile_error!("a very descriptive error message"); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/complex.rs b/gcc/testsuite/rust/rustc/ui/complex.rs new file mode 100644 index 000000000000..5362e0ac20be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/complex.rs @@ -0,0 +1,39 @@ +// run-pass + +#![allow(unconditional_recursion)] +#![allow(non_camel_case_types)] +#![allow(dead_code)] +#![allow(unused_mut)] + + + +type t = isize; + +fn nothing() { } + +fn putstr(_s: String) { } + +fn putint(_i: isize) { + let mut i: isize = 33; + while i < 36 { putstr("hi".to_string()); i = i + 1; } +} + +fn zerg(i: isize) -> isize { return i; } + +fn foo(x: isize) -> isize { + let mut y: t = x + 2; + putstr("hello".to_string()); + while y < 10 { putint(y); if y * 3 == 4 { y = y + 2; nothing(); } } + let mut z: t; + z = 0x55; + foo(z); + return 0; +} + +pub fn main() { + let x: isize = 2 + 2; + println!("{}", x); + println!("hello, world"); + println!("{}", 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/concat-rpass.rs b/gcc/testsuite/rust/rustc/ui/concat-rpass.rs new file mode 100644 index 000000000000..1fa365188366 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/concat-rpass.rs @@ -0,0 +1,19 @@ +// run-pass + +pub fn main() { + assert_eq!(format!(concat!("foo", "bar", "{}"), "baz"), "foobarbaz".to_string()); + assert_eq!(format!(concat!()), "".to_string()); + // check trailing comma is allowed in concat + assert_eq!(concat!("qux", "quux",).to_string(), "quxquux".to_string()); + + assert_eq!( + concat!(1, 2, 3, 4f32, 4.0, 'a', true), + "12344.0atrue" + ); + + assert!(match "12344.0atrue" { + concat!(1, 2, 3, 4f32, 4.0, 'a', true) => true, + _ => false + }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/concat.rs b/gcc/testsuite/rust/rustc/ui/concat.rs new file mode 100644 index 000000000000..df34d9cc4e30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/concat.rs @@ -0,0 +1,7 @@ +fn main() { + concat!(b'f'); // { dg-error "" "" { target *-*-* } } + concat!(b"foo"); // { dg-error "" "" { target *-*-* } } + concat!(foo); // { dg-error "" "" { target *-*-* } } + concat!(foo()); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/auxiliary/namespaced_enums.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/auxiliary/namespaced_enums.rs new file mode 100644 index 000000000000..dcd0b95974b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/auxiliary/namespaced_enums.rs @@ -0,0 +1,11 @@ +pub enum Foo { + A, + B(isize), + C { a: isize }, +} + +impl Foo { + pub fn foo() {} + pub fn bar(&self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-1.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-1.rs new file mode 100644 index 000000000000..b49d24891459 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-1.rs @@ -0,0 +1,4 @@ +// compile-flags: --cfg a(b=c) +// error-pattern: invalid `--cfg` argument: `a(b=c)` (expected `key` or `key="value"`) +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-2.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-2.rs new file mode 100644 index 000000000000..3177a84e7187 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-2.rs @@ -0,0 +1,4 @@ +// compile-flags: --cfg a{b} +// error-pattern: invalid `--cfg` argument: `a{b}` (expected `key` or `key="value"`) +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-3.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-3.rs new file mode 100644 index 000000000000..459a1b0168a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-3.rs @@ -0,0 +1,4 @@ +// compile-flags: --cfg a::b +// error-pattern: invalid `--cfg` argument: `a::b` (argument key must be an identifier) +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-4.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-4.rs new file mode 100644 index 000000000000..077580122ba7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-4.rs @@ -0,0 +1,4 @@ +// compile-flags: --cfg a(b) +// error-pattern: invalid `--cfg` argument: `a(b)` (expected `key` or `key="value"`) +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-5.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-5.rs new file mode 100644 index 000000000000..216878fbd9d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-5.rs @@ -0,0 +1,4 @@ +// compile-flags: --cfg a=10 +// error-pattern: invalid `--cfg` argument: `a=10` (argument value must be a string) +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-6.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-6.rs new file mode 100644 index 000000000000..6c4834371d5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-arg-invalid-6.rs @@ -0,0 +1,4 @@ +// compile-flags: --cfg a{ +// error-pattern: invalid `--cfg` argument: `a{` (expected `key` or `key="value"`) +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-cfg-2.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-cfg-2.rs new file mode 100644 index 000000000000..41bee81ea965 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-cfg-2.rs @@ -0,0 +1,10 @@ +// +// error-pattern: `main` function not found +// compile-flags: --cfg foo + +// main is conditionally compiled, but the conditional compilation +// is conditional too! + +#[cfg_attr(foo, cfg(bar))] +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-crate-2.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-crate-2.rs new file mode 100644 index 000000000000..c7b9339b2ed7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-crate-2.rs @@ -0,0 +1,9 @@ +// https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044 + +// compile-flags: --cfg broken + +#![crate_type = "lib"] +#![cfg_attr(broken, no_core)] // { dg-error ".E0658." "" { target *-*-* } } + +pub struct S {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-empty-is-unused.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-empty-is-unused.rs new file mode 100644 index 000000000000..6c9bf404a3fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-empty-is-unused.rs @@ -0,0 +1,14 @@ +// Check that `#[cfg_attr($PREDICATE,)]` triggers the `unused_attribute` lint. + +// compile-flags: --cfg TRUE + +#![deny(unused)] + +#[cfg_attr(FALSE,)] // { dg-error "" "" { target *-*-* } } +fn _f() {} + +#[cfg_attr(TRUE,)] // { dg-error "" "" { target *-*-* } } +fn _g() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-invalid-predicate.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-invalid-predicate.rs new file mode 100644 index 000000000000..b509dc329201 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-invalid-predicate.rs @@ -0,0 +1,5 @@ +#[cfg(foo(bar))] // { dg-error ".E0537." "" { target *-*-* } } +fn check() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-false.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-false.rs new file mode 100644 index 000000000000..e29649dba8a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-false.rs @@ -0,0 +1,20 @@ +// Test that cfg_attr doesn't emit any attributes when the +// configuration variable is false. This mirrors `cfg-attr-multi-true.rs` + +// build-pass (FIXME(62277): could be check-pass?) + +#![warn(unused_must_use)] + +#[cfg_attr(any(), deprecated, must_use)] +struct Struct {} + +impl Struct { + fn new() -> Struct { + Struct {} + } +} + +fn main() { + Struct::new(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs new file mode 100644 index 000000000000..e5cfdb5557cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs @@ -0,0 +1,8 @@ +// compile-flags: --cfg broken + +#![crate_type = "lib"] +#![cfg_attr(broken, no_core, no_std)] +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +pub struct S {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs new file mode 100644 index 000000000000..2400a920ab34 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs @@ -0,0 +1,8 @@ +// compile-flags: --cfg broken + +#![crate_type = "lib"] +#![cfg_attr(broken, no_std, no_core)] +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +pub struct S {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-true.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-true.rs new file mode 100644 index 000000000000..a036dcb3b767 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-multi-true.rs @@ -0,0 +1,22 @@ +// Test that cfg_attr with multiple attributes actually emits both attributes. +// This is done by emitting two attributes that cause new warnings, and then +// triggering those warnings. + +// build-pass (FIXME(62277): could be check-pass?) + +#![warn(unused_must_use)] + +#[cfg_attr(all(), deprecated, must_use)] +struct MustUseDeprecated {} + +impl MustUseDeprecated { // { dg-warning "" "" { target *-*-* } } + fn new() -> MustUseDeprecated { // { dg-warning "" "" { target *-*-* } } + MustUseDeprecated {} // { dg-warning "" "" { target *-*-* } } + } +} + +fn main() { + MustUseDeprecated::new(); // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-parse.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-parse.rs new file mode 100644 index 000000000000..2cc57e52b47d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-parse.rs @@ -0,0 +1,56 @@ +// Parse `cfg_attr` with varying numbers of attributes and trailing commas + +// Completely empty `cfg_attr` input +#[cfg_attr()] // { dg-error "" "" { target *-*-* } } +struct NoConfigurationPredicate; + +// Zero attributes, zero trailing comma (comma manatory here) +#[cfg_attr(all())] // { dg-error "" "" { target *-*-* } } +struct A0C0; + +// Zero attributes, one trailing comma +#[cfg_attr(all(),)] // Ok +struct A0C1; + +// Zero attributes, two trailing commas +#[cfg_attr(all(),,)] // { dg-error "" "" { target *-*-* } } +struct A0C2; + +// One attribute, no trailing comma +#[cfg_attr(all(), must_use)] // Ok +struct A1C0; + +// One attribute, one trailing comma +#[cfg_attr(all(), must_use,)] // Ok +struct A1C1; + +// One attribute, two trailing commas +#[cfg_attr(all(), must_use,,)] // { dg-error "" "" { target *-*-* } } +struct A1C2; + +// Two attributes, no trailing comma +#[cfg_attr(all(), must_use, deprecated)] // Ok +struct A2C0; + +// Two attributes, one trailing comma +#[cfg_attr(all(), must_use, deprecated,)] // Ok +struct A2C1; + +// Two attributes, two trailing commas +#[cfg_attr(all(), must_use, deprecated,,)] // { dg-error "" "" { target *-*-* } } +struct A2C2; + +// Wrong delimiter `[` +#[cfg_attr[all(),,]] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +struct BracketZero; + +// Wrong delimiter `{` +#[cfg_attr{all(),,}] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +struct BraceZero; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-syntax-validation.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-syntax-validation.rs new file mode 100644 index 000000000000..1bcb22410f2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-syntax-validation.rs @@ -0,0 +1,40 @@ +#[cfg] // { dg-error "" "" { target *-*-* } } +struct S1; + +#[cfg = 10] // { dg-error "" "" { target *-*-* } } +struct S2; + +#[cfg()] // { dg-error "" "" { target *-*-* } } +struct S3; + +#[cfg(a, b)] // { dg-error "" "" { target *-*-* } } +struct S4; + +#[cfg("str")] // { dg-error "" "" { target *-*-* } } +struct S5; + +#[cfg(a::b)] // { dg-error "" "" { target *-*-* } } +struct S6; + +#[cfg(a())] // { dg-error ".E0537." "" { target *-*-* } } +struct S7; + +#[cfg(a = 10)] // { dg-error ".E0565." "" { target *-*-* } } +struct S8; + +#[cfg(a = b"hi")] // { dg-error ".E0565." "" { target *-*-* } } +struct S9; + +macro_rules! generate_s10 { + ($expr: expr) => { + #[cfg(feature = $expr)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + struct S10; + } +} + +generate_s10!(concat!("nonexistent")); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs new file mode 100644 index 000000000000..1ab9bd0c0198 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs @@ -0,0 +1,12 @@ +macro_rules! foo { + () => { + #[cfg_attr(all(), unknown)] +// { dg-error "" "" { target *-*-* } .-1 } + fn foo() {} + } +} + +foo!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-empty-codemap.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-empty-codemap.rs new file mode 100644 index 000000000000..fda4e496ec32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-empty-codemap.rs @@ -0,0 +1,9 @@ +// Tests that empty source_maps don't ICE (#23301) + +// compile-flags: --cfg "" + +// error-pattern: invalid `--cfg` argument: `""` (expected `key` or `key="value"`) + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-generic-params.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-generic-params.rs new file mode 100644 index 000000000000..c77a8d28c715 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-generic-params.rs @@ -0,0 +1,41 @@ +// compile-flags:--cfg yes + +fn f_lt<#[cfg(yes)] 'a: 'a, #[cfg(no)] T>() {} +fn f_ty<#[cfg(no)] 'a: 'a, #[cfg(yes)] T>() {} + +type FnGood = for<#[cfg(yes)] 'a, #[cfg(no)] T> fn(); // OK +type FnBad = for<#[cfg(no)] 'a, #[cfg(yes)] T> fn(); +// { dg-error "" "" { target *-*-* } .-1 } + +type PolyGood = dyn for<#[cfg(yes)] 'a, #[cfg(no)] T> Copy; // OK +type PolyBad = dyn for<#[cfg(no)] 'a, #[cfg(yes)] T> Copy; +// { dg-error "" "" { target *-*-* } .-1 } + +struct WhereGood where for<#[cfg(yes)] 'a, #[cfg(no)] T> u8: Copy; // OK +struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy; +// { dg-error "" "" { target *-*-* } .-1 } + +fn f_lt_no<#[cfg_attr(no, unknown)] 'a>() {} // OK +fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {} +// { dg-error "" "" { target *-*-* } .-1 } +fn f_ty_no<#[cfg_attr(no, unknown)] T>() {} // OK +fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {} +// { dg-error "" "" { target *-*-* } .-1 } + +type FnNo = for<#[cfg_attr(no, unknown)] 'a> fn(); // OK +type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn(); +// { dg-error "" "" { target *-*-* } .-1 } + +type PolyNo = dyn for<#[cfg_attr(no, unknown)] 'a> Copy; // OK +type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy; +// { dg-error "" "" { target *-*-* } .-1 } + +struct WhereNo where for<#[cfg_attr(no, unknown)] 'a> u8: Copy; // OK +struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + f_lt::<'static>(); + f_ty::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-in-crate-1.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-in-crate-1.rs new file mode 100644 index 000000000000..21e09335ed54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-in-crate-1.rs @@ -0,0 +1,4 @@ +// error-pattern: `main` function not found + +#![cfg(bar)] + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-non-opt-expr.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-non-opt-expr.rs new file mode 100644 index 000000000000..176c0940fc29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg-non-opt-expr.rs @@ -0,0 +1,12 @@ +#![feature(stmt_expr_attributes)] +#![feature(custom_test_frameworks)] + +fn main() { + let _ = #[cfg(unset)] (); +// { dg-error "" "" { target *-*-* } .-1 } + let _ = 1 + 2 + #[cfg(unset)] 3; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = [1, 2, 3][#[cfg(unset)] 1]; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible-input-validation.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible-input-validation.rs new file mode 100644 index 000000000000..0e87ab70eeca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible-input-validation.rs @@ -0,0 +1,25 @@ +#![feature(cfg_accessible)] + +#[cfg_accessible] // { dg-error "" "" { target *-*-* } } +struct S1; + +#[cfg_accessible = "value"] // { dg-error "" "" { target *-*-* } } +struct S2; + +#[cfg_accessible()] // { dg-error "" "" { target *-*-* } } +struct S3; + +#[cfg_accessible(std, core)] // { dg-error "" "" { target *-*-* } } +struct S4; + +#[cfg_accessible("std")] // { dg-error "" "" { target *-*-* } } +struct S5; + +#[cfg_accessible(std = "value")] // { dg-error "" "" { target *-*-* } } +struct S6; + +#[cfg_accessible(std(value))] // { dg-error "" "" { target *-*-* } } +struct S7; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible-stuck.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible-stuck.rs new file mode 100644 index 000000000000..da757ee29aca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible-stuck.rs @@ -0,0 +1,10 @@ +#![feature(cfg_accessible)] + +#[cfg_accessible(Z)] // { dg-error "" "" { target *-*-* } } +struct S; + +#[cfg_accessible(S)] // { dg-error "" "" { target *-*-* } } +struct Z; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible-unstable.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible-unstable.rs new file mode 100644 index 000000000000..acda94b952da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible-unstable.rs @@ -0,0 +1,3 @@ +#[cfg_accessible(std)] // { dg-error ".E0658." "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible.rs new file mode 100644 index 000000000000..4162e07bdea4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_accessible.rs @@ -0,0 +1,44 @@ +#![feature(cfg_accessible)] + +mod m { + pub struct ExistingPublic; + struct ExistingPrivate; +} + +#[cfg_accessible(m::ExistingPublic)] +struct ExistingPublic; + +// FIXME: Not implemented yet. +#[cfg_accessible(m::ExistingPrivate)] // { dg-error "" "" { target *-*-* } } +struct ExistingPrivate; + +// FIXME: Not implemented yet. +#[cfg_accessible(m::NonExistent)] // { dg-error "" "" { target *-*-* } } +struct ExistingPrivate; + +#[cfg_accessible(n::AccessibleExpanded)] // OK, `cfg_accessible` can wait and retry. +struct AccessibleExpanded; + +macro_rules! generate_accessible_expanded { + () => { + mod n { + pub struct AccessibleExpanded; + } + }; +} + +generate_accessible_expanded!(); + +struct S { + field: u8, +} + +// FIXME: Not implemented yet. +#[cfg_accessible(S::field)] // { dg-error "" "" { target *-*-* } } +struct Field; + +fn main() { + ExistingPublic; + AccessibleExpanded; +} + diff --git a/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_attr_path.rs b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_attr_path.rs new file mode 100644 index 000000000000..2e3e0537bb42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conditional-compilation/cfg_attr_path.rs @@ -0,0 +1,14 @@ +// check-pass + +#![deny(unused_attributes)] // c.f #35584 + +mod auxiliary { + #[cfg_attr(any(), path = "nonexistent_file.rs")] pub mod namespaced_enums; + #[cfg_attr(all(), path = "namespaced_enums.rs")] pub mod nonexistent_file; +} + +fn main() { + let _ = auxiliary::namespaced_enums::Foo::A; + let _ = auxiliary::nonexistent_file::Foo::A; +} + diff --git a/gcc/testsuite/rust/rustc/ui/conflicting-repr-hints.rs b/gcc/testsuite/rust/rustc/ui/conflicting-repr-hints.rs new file mode 100644 index 000000000000..5da6d05ac324 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conflicting-repr-hints.rs @@ -0,0 +1,70 @@ +#![allow(dead_code)] + +#[repr(C)] +enum A { + A, +} + +#[repr(u64)] +enum B { + B, +} + +#[repr(C, u64)] // { dg-error ".E0566." "" { target *-*-* } } +// { dg-warning ".E0566." "" { target *-*-* } .-1 } +enum C { + C, +} + +#[repr(u32, u64)] // { dg-error ".E0566." "" { target *-*-* } } +// { dg-warning ".E0566." "" { target *-*-* } .-1 } +enum D { + D, +} + +#[repr(C, packed)] +struct E(i32); + +#[repr(packed, align(8))] +struct F(i32); // { dg-error ".E0587." "" { target *-*-* } } + +#[repr(packed)] +#[repr(align(8))] +struct G(i32); // { dg-error ".E0587." "" { target *-*-* } } + +#[repr(align(8))] +#[repr(packed)] +struct H(i32); // { dg-error ".E0587." "" { target *-*-* } } + +#[repr(packed, packed(2))] +struct I(i32); // { dg-error ".E0634." "" { target *-*-* } } + +#[repr(packed(2))] +#[repr(packed)] +struct J(i32); // { dg-error ".E0634." "" { target *-*-* } } + +#[repr(packed, packed(1))] +struct K(i32); + +#[repr(packed, align(8))] +union X { +// { dg-error ".E0587." "" { target *-*-* } .-1 } + i: i32, +} + +#[repr(packed)] +#[repr(align(8))] +union Y { +// { dg-error ".E0587." "" { target *-*-* } .-1 } + i: i32, +} + +#[repr(align(8))] +#[repr(packed)] +union Z { +// { dg-error ".E0587." "" { target *-*-* } .-1 } + i: i32, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-18343.rs b/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-18343.rs new file mode 100644 index 000000000000..e2cf4a53bc15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-18343.rs @@ -0,0 +1,10 @@ +struct Obj where F: FnMut() -> u32 { + closure: F, +} + +fn main() { + let o = Obj { closure: || 42 }; + o.closure(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-2392.rs b/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-2392.rs new file mode 100644 index 000000000000..057c1b5eec29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-2392.rs @@ -0,0 +1,70 @@ +struct FuncContainer { + f1: fn(data: u8), + f2: extern "C" fn(data: u8), + f3: unsafe fn(data: u8), +} + +struct FuncContainerOuter { + container: Box +} + +struct Obj where F: FnOnce() -> u32 { + closure: F, + not_closure: usize, +} + +struct BoxedObj { + boxed_closure: Box u32>, +} + +struct Wrapper where F: FnMut() -> u32 { + wrap: Obj, +} + +fn func() -> u32 { + 0 +} + +fn check_expression() -> Obj u32>> { + Obj { closure: Box::new(|| 42_u32) as Box u32>, not_closure: 42 } +} + +fn main() { + // test variations of function + + let o_closure = Obj { closure: || 42, not_closure: 42 }; + o_closure.closure(); // { dg-error ".E0599." "" { target *-*-* } } + + o_closure.not_closure(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + + let o_func = Obj { closure: func, not_closure: 5 }; + o_func.closure(); // { dg-error ".E0599." "" { target *-*-* } } + + let boxed_fn = BoxedObj { boxed_closure: Box::new(func) }; + boxed_fn.boxed_closure();// { dg-error ".E0599." "" { target *-*-* } } + + let boxed_closure = BoxedObj { boxed_closure: Box::new(|| 42_u32) as Box u32> }; + boxed_closure.boxed_closure();// { dg-error ".E0599." "" { target *-*-* } } + + // test expression writing in the notes + + let w = Wrapper { wrap: o_func }; + w.wrap.closure();// { dg-error ".E0599." "" { target *-*-* } } + + w.wrap.not_closure(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + + check_expression().closure();// { dg-error ".E0599." "" { target *-*-* } } +} + +impl FuncContainerOuter { + fn run(&self) { + unsafe { + (*self.container).f1(1); // { dg-error ".E0599." "" { target *-*-* } } + (*self.container).f2(1); // { dg-error ".E0599." "" { target *-*-* } } + (*self.container).f3(1); // { dg-error ".E0599." "" { target *-*-* } } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-32128.rs b/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-32128.rs new file mode 100644 index 000000000000..1a48f1f498ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-32128.rs @@ -0,0 +1,16 @@ +struct Example { + example: Box i32> +} + +fn main() { + let demo = Example { + example: Box::new(|x| { + x + 1 + }) + }; + + demo.example(1); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + // (demo.example)(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-33784.rs b/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-33784.rs new file mode 100644 index 000000000000..0ca1ed12d06d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/issue-33784.rs @@ -0,0 +1,34 @@ +use std::ops::Deref; + +struct Obj where F: FnMut() -> u32 { + fn_ptr: fn() -> (), + closure: F, +} + +struct C { + c_fn_ptr: fn() -> (), +} + +struct D(C); + +impl Deref for D { + type Target = C; + fn deref(&self) -> &C { + &self.0 + } +} + + +fn empty() {} + +fn main() { + let o = Obj { fn_ptr: empty, closure: || 42 }; + let p = &o; + p.closure(); // { dg-error ".E0599." "" { target *-*-* } } + let q = &p; + q.fn_ptr(); // { dg-error ".E0599." "" { target *-*-* } } + let r = D(C { c_fn_ptr: empty }); + let s = &r; + s.c_fn_ptr(); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/private-field.rs b/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/private-field.rs new file mode 100644 index 000000000000..76532d9f5755 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/confuse-field-and-method/private-field.rs @@ -0,0 +1,20 @@ +pub mod animal { + pub struct Dog { + pub age: usize, + dog_age: usize, + } + + impl Dog { + pub fn new(age: usize) -> Dog { + Dog { age: age, dog_age: age * 7 } + } + } +} + +fn main() { + let dog = animal::Dog::new(3); + let dog_age = dog.dog_age(); // { dg-error ".E0599." "" { target *-*-* } } + //let dog_age = dog.dog_age; + println!("{}", dog_age); +} + diff --git a/gcc/testsuite/rust/rustc/ui/conservative_impl_trait.rs b/gcc/testsuite/rust/rustc/ui/conservative_impl_trait.rs new file mode 100644 index 000000000000..108ab4a928b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conservative_impl_trait.rs @@ -0,0 +1,8 @@ +// #39872, #39553 + +fn will_ice(something: &u32) -> impl Iterator { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/apit-with-const-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/apit-with-const-param.rs new file mode 100644 index 000000000000..7fd4db876772 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/apit-with-const-param.rs @@ -0,0 +1,13 @@ +// check-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Trait {} + +fn f(_: impl Trait) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/argument_order.rs b/gcc/testsuite/rust/rustc/ui/const-generics/argument_order.rs new file mode 100644 index 000000000000..4774a43129d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/argument_order.rs @@ -0,0 +1,23 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Bad { +// { dg-error "" "" { target *-*-* } .-1 } + arr: [u8; { N }], + another: T, +} + +struct AlsoBad { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + a: &'a T, + b: &'b U, +} + +fn main() { + let _: AlsoBad<7, 'static, u32, 'static, 17, u16>; +// { dg-error "" "" { target *-*-* } .-1 } + } + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs new file mode 100644 index 000000000000..92beaf97dd80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/alloc-traits-impls-length-32.rs @@ -0,0 +1,49 @@ +// check-pass + +pub fn yes_vec_partial_eq_array() -> impl PartialEq<[B; 32]> +where + A: PartialEq, +{ + Vec::::new() +} + +pub fn yes_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 32]> +where + A: PartialEq, +{ + Vec::::new() +} + +pub fn yes_array_into_vec() -> Vec { + [].into() +} + +pub fn yes_array_into_box() -> Box<[T]> { + [].into() +} + +use std::collections::VecDeque; + +pub fn yes_vecdeque_partial_eq_array() -> impl PartialEq<[B; 32]> +where + A: PartialEq, +{ + VecDeque::::new() +} + +pub fn yes_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 32]> +where + A: PartialEq, +{ + VecDeque::::new() +} + +pub fn yes_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 32]> +where + A: PartialEq, +{ + VecDeque::::new() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/alloc-traits-impls-length-33.rs b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/alloc-traits-impls-length-33.rs new file mode 100644 index 000000000000..e7f278dbdb4d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/alloc-traits-impls-length-33.rs @@ -0,0 +1,41 @@ +// check-pass + +pub fn yes_vec_partial_eq_array() -> impl PartialEq<[B; 33]> +where + A: PartialEq, +{ + Vec::::new() +} + +pub fn yes_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]> +where + A: PartialEq, +{ + Vec::::new() +} + +use std::collections::VecDeque; + +pub fn yes_vecdeque_partial_eq_array() -> impl PartialEq<[B; 33]> +where + A: PartialEq, +{ + VecDeque::::new() +} + +pub fn yes_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]> +where + A: PartialEq, +{ + VecDeque::::new() +} + +pub fn yes_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 33]> +where + A: PartialEq, +{ + VecDeque::::new() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/alloc-types-impls-length-33.rs b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/alloc-types-impls-length-33.rs new file mode 100644 index 000000000000..d27730674a43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/alloc-types-impls-length-33.rs @@ -0,0 +1,26 @@ +// check-pass + +use std::{convert::TryFrom, rc::Rc, sync::Arc}; + +pub fn yes_vec() { + let v: Vec<_> = [0; 33].into(); +} + +pub fn yes_box() { + let boxed_slice = Box::new([0; 33]) as Box<[i32]>; + let boxed_array = >::try_from(boxed_slice); + let boxed_slice = >::from([0; 33]); +} + +pub fn yes_rc() { + let boxed_slice = Rc::new([0; 33]) as Rc<[i32]>; + let boxed_array = >::try_from(boxed_slice); +} + +pub fn yes_arc() { + let boxed_slice = Arc::new([0; 33]) as Arc<[i32]>; + let boxed_array = >::try_from(boxed_slice); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/core-traits-impls-length-32.rs b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/core-traits-impls-length-32.rs new file mode 100644 index 000000000000..909176119450 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/core-traits-impls-length-32.rs @@ -0,0 +1,67 @@ +// check-pass + +pub fn yes_as_ref() -> impl AsRef<[u8]> { + [0; 32] +} + +pub fn yes_as_mut() -> impl AsMut<[u8]> { + [0; 32] +} + +pub fn yes_borrow() -> impl std::borrow::Borrow<[u8]> { + [0; 32] +} + +pub fn yes_borrow_mut() -> impl std::borrow::BorrowMut<[u8]> { + [0; 32] +} + +pub fn yes_try_from_slice() -> impl std::convert::TryFrom<&'static [u8]> { + [0; 32] +} + +pub fn yes_ref_try_from_slice() -> impl std::convert::TryFrom<&'static [u8]> { + let a: &'static _ = &[0; 32]; + a +} + +pub fn yes_hash() -> impl std::hash::Hash { + [0; 32] +} + +pub fn yes_debug() -> impl std::fmt::Debug { + [0; 32] +} + +pub fn yes_ref_into_iterator() -> impl IntoIterator { + let a: &'static _ = &[0; 32]; + a +} + +pub fn yes_partial_eq() -> impl PartialEq<[u8; 32]> { + [0; 32] +} + +pub fn yes_partial_eq_slice() -> impl PartialEq<[u8]> { + [0; 32] +} + +pub fn yes_slice_partial_eq() -> impl PartialEq<[u8; 32]> { + let a: &'static _ = &[0; 32]; + &a[..] +} + +pub fn yes_eq() -> impl Eq { + [0; 32] +} + +pub fn yes_partial_ord() -> impl PartialOrd<[u8; 32]> { + [0; 32] +} + +pub fn yes_ord() -> impl Ord { + [0; 32] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/core-traits-impls-length-33.rs b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/core-traits-impls-length-33.rs new file mode 100644 index 000000000000..0d5a6ea5ba55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/core-traits-impls-length-33.rs @@ -0,0 +1,67 @@ +// check-pass + +pub fn yes_as_ref() -> impl AsRef<[u8]> { + [0; 33] +} + +pub fn yes_as_mut() -> impl AsMut<[u8]> { + [0; 33] +} + +pub fn yes_borrow() -> impl std::borrow::Borrow<[u8]> { + [0; 33] +} + +pub fn yes_borrow_mut() -> impl std::borrow::BorrowMut<[u8]> { + [0; 33] +} + +pub fn yes_try_from_slice() -> impl std::convert::TryFrom<&'static [u8]> { + [0; 33] +} + +pub fn yes_ref_try_from_slice() -> impl std::convert::TryFrom<&'static [u8]> { + let a: &'static _ = &[0; 33]; + a +} + +pub fn yes_hash() -> impl std::hash::Hash { + [0; 33] +} + +pub fn yes_debug() -> impl std::fmt::Debug { + [0; 33] +} + +pub fn yes_ref_into_iterator() -> impl IntoIterator { + let a: &'static _ = &[0; 33]; + a +} + +pub fn yes_partial_eq() -> impl PartialEq<[u8; 33]> { + [0; 33] +} + +pub fn yes_partial_eq_slice() -> impl PartialEq<[u8]> { + [0; 33] +} + +pub fn yes_slice_partial_eq() -> impl PartialEq<[u8; 33]> { + let a: &'static _ = &[0; 33]; + &a[..] +} + +pub fn yes_eq() -> impl Eq { + [0; 33] +} + +pub fn yes_partial_ord() -> impl PartialOrd<[u8; 33]> { + [0; 33] +} + +pub fn yes_ord() -> impl Ord { + [0; 33] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/into-iter-impls-length-32.rs b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/into-iter-impls-length-32.rs new file mode 100644 index 000000000000..869a7f663e46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/into-iter-impls-length-32.rs @@ -0,0 +1,42 @@ +// check-pass + +#![feature(array_value_iter)] +#![feature(trusted_len)] + +use std::{ + array::IntoIter, + fmt::Debug, + iter::{ExactSizeIterator, FusedIterator, TrustedLen}, +}; + +pub fn yes_iterator() -> impl Iterator { + IntoIter::new([0i32; 32]) +} + +pub fn yes_double_ended_iterator() -> impl DoubleEndedIterator { + IntoIter::new([0i32; 32]) +} + +pub fn yes_exact_size_iterator() -> impl ExactSizeIterator { + IntoIter::new([0i32; 32]) +} + +pub fn yes_fused_iterator() -> impl FusedIterator { + IntoIter::new([0i32; 32]) +} + +pub fn yes_trusted_len() -> impl TrustedLen { + IntoIter::new([0i32; 32]) +} + +pub fn yes_clone() -> impl Clone { + IntoIter::new([0i32; 32]) +} + +pub fn yes_debug() -> impl Debug { + IntoIter::new([0i32; 32]) +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/into-iter-impls-length-33.rs b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/into-iter-impls-length-33.rs new file mode 100644 index 000000000000..da215656d4f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/array-impls/into-iter-impls-length-33.rs @@ -0,0 +1,42 @@ +// check-pass + +#![feature(array_value_iter)] +#![feature(trusted_len)] + +use std::{ + array::IntoIter, + fmt::Debug, + iter::{ExactSizeIterator, FusedIterator, TrustedLen}, +}; + +pub fn yes_iterator() -> impl Iterator { + IntoIter::new([0i32; 33]) +} + +pub fn yes_double_ended_iterator() -> impl DoubleEndedIterator { + IntoIter::new([0i32; 33]) +} + +pub fn yes_exact_size_iterator() -> impl ExactSizeIterator { + IntoIter::new([0i32; 33]) +} + +pub fn yes_fused_iterator() -> impl FusedIterator { + IntoIter::new([0i32; 33]) +} + +pub fn yes_trusted_len() -> impl TrustedLen { + IntoIter::new([0i32; 33]) +} + +pub fn yes_clone() -> impl Clone { + IntoIter::new([0i32; 33]) +} + +pub fn yes_debug() -> impl Debug { + IntoIter::new([0i32; 33]) +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/array-size-in-generic-struct-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/array-size-in-generic-struct-param.rs new file mode 100644 index 000000000000..19b3cd6b5e25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/array-size-in-generic-struct-param.rs @@ -0,0 +1,31 @@ +// Tests that array sizes that depend on const-params are checked using `ConstEvaluatable`. +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +#[allow(dead_code)] +struct ArithArrayLen([u32; 0 + N]); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +#[derive(PartialEq, Eq)] +struct Config { + arr_size: usize, +} + +struct B { +// { dg-error "" "" { target *-*-* } .-1 } + arr: [u8; CFG.arr_size], +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +const C: Config = Config { arr_size: 5 }; + +fn main() { + let b = B:: { arr: [1, 2, 3, 4, 5] }; + assert_eq!(b.arr.len(), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/array-wrapper-struct-ctor.rs b/gcc/testsuite/rust/rustc/ui/const-generics/array-wrapper-struct-ctor.rs new file mode 100644 index 000000000000..519652ab039f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/array-wrapper-struct-ctor.rs @@ -0,0 +1,19 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +#![allow(dead_code)] + +struct ArrayStruct { + data: [T; N], +} + +struct ArrayTuple([T; N]); + +fn main() { + let _ = ArrayStruct { data: [0u32; 8] }; + let _ = ArrayTuple([0u32; 8]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/associated-type-bound-fail.rs b/gcc/testsuite/rust/rustc/ui/const-generics/associated-type-bound-fail.rs new file mode 100644 index 000000000000..9cf10e2bc627 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/associated-type-bound-fail.rs @@ -0,0 +1,18 @@ +// revisions: full min +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Bar {} + +trait Foo { + type Assoc: Bar; +} + +impl Bar<3> for u16 {} +impl Foo for i16 { + type Assoc = u16; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/associated-type-bound.rs b/gcc/testsuite/rust/rustc/ui/const-generics/associated-type-bound.rs new file mode 100644 index 000000000000..27d41511fb1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/associated-type-bound.rs @@ -0,0 +1,25 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Bar {} + +trait Foo { + type Assoc: Bar; +} + +impl Bar for u8 {} +impl Bar<3> for u16 {} + +impl Foo for i8 { + type Assoc = u8; +} + +impl Foo<3> for i16 { + type Assoc = u16; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/auxiliary/const_generic_lib.rs b/gcc/testsuite/rust/rustc/ui/const-generics/auxiliary/const_generic_lib.rs new file mode 100644 index 000000000000..ddd8c6e4aef7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/auxiliary/const_generic_lib.rs @@ -0,0 +1,12 @@ +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub struct Struct(pub [u8; N]); + +pub type Alias = Struct<2>; + +pub fn function(value: Struct<3>) -> u8 { + value.0[0] +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/auxiliary/crayte.rs b/gcc/testsuite/rust/rustc/ui/const-generics/auxiliary/crayte.rs new file mode 100644 index 000000000000..5e5dfc027f56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/auxiliary/crayte.rs @@ -0,0 +1,20 @@ +// edition:2018 +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub trait Foo {} +struct Local; +impl Foo for Local {} + +pub fn out_foo() -> impl Foo { Local } +pub fn in_foo(_: impl Foo) {} + +pub async fn async_simple(_: [u8; N]) {} +pub async fn async_out_foo() -> impl Foo { Local } +pub async fn async_in_foo(_: impl Foo) {} + +pub trait Bar { + type Assoc: Foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/auxiliary/impl-const.rs b/gcc/testsuite/rust/rustc/ui/const-generics/auxiliary/impl-const.rs new file mode 100644 index 000000000000..dce152de79ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/auxiliary/impl-const.rs @@ -0,0 +1,12 @@ +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub struct Num; + +// Braces around const expression causes crash +impl Num<{5}> { + pub fn five(&self) { + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/broken-mir-1.rs b/gcc/testsuite/rust/rustc/ui/const-generics/broken-mir-1.rs new file mode 100644 index 000000000000..09ced1c4687e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/broken-mir-1.rs @@ -0,0 +1,20 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub trait Foo { + fn foo(&self); +} + + +impl Foo for [T; N] { + fn foo(&self) { + let _ = &self; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/broken-mir-2.rs b/gcc/testsuite/rust/rustc/ui/const-generics/broken-mir-2.rs new file mode 100644 index 000000000000..7a4e4ac29ce5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/broken-mir-2.rs @@ -0,0 +1,14 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +use std::fmt::Debug; + +#[derive(Debug)] +struct S([T; N]); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/cannot-infer-type-for-const-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/cannot-infer-type-for-const-param.rs new file mode 100644 index 000000000000..87ba9834047f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/cannot-infer-type-for-const-param.rs @@ -0,0 +1,15 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +// This test confirms that the types can be inferred correctly for this example with const +// generics. Previously this would ICE, and more recently error. + +struct Foo(pub [u8; NUM_BYTES]); + +fn main() { + let _ = Foo::<3>([1, 2, 3]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/closing-args-token.rs b/gcc/testsuite/rust/rustc/ui/const-generics/closing-args-token.rs new file mode 100644 index 000000000000..db169211c3a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/closing-args-token.rs @@ -0,0 +1,33 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct S; +struct T; + +fn bad_args_1() { + S::<5 + 2 >> 7>; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn bad_args_2() { + S::<{ 5 + 2 } >> 7>; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn bad_args_3() { + T::<0 >= 3>; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn bad_args_4() { + let mut x = 0; + T::>= 2 > 0>; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/coerce_unsized_array.rs b/gcc/testsuite/rust/rustc/ui/const-generics/coerce_unsized_array.rs new file mode 100644 index 000000000000..8c053aed6539 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/coerce_unsized_array.rs @@ -0,0 +1,15 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn foo(v: &[u8; N]) -> &[u8] { + v +} + +fn main() { + assert_eq!(foo(&[1, 2]), &[1, 2]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/concrete-const-as-fn-arg.rs b/gcc/testsuite/rust/rustc/ui/const-generics/concrete-const-as-fn-arg.rs new file mode 100644 index 000000000000..ad62966d237b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/concrete-const-as-fn-arg.rs @@ -0,0 +1,17 @@ +// Test that a concrete const type i.e. A<2>, can be used as an argument type in a function +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct A; // ok + +fn with_concrete_const_arg(_: A<2>) -> u32 { 17 } + +fn main() { + let val: A<2> = A; + assert_eq!(with_concrete_const_arg(val), 17); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/concrete-const-impl-method.rs b/gcc/testsuite/rust/rustc/ui/const-generics/concrete-const-impl-method.rs new file mode 100644 index 000000000000..57aefcef9b06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/concrete-const-impl-method.rs @@ -0,0 +1,27 @@ +// Test that a method/associated non-method within an impl block of a concrete const type i.e. A<2>, +// is callable. +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub struct A; + +impl A<2> { + fn impl_method(&self) -> u32 { + 17 + } + + fn associated_non_method() -> u32 { + 17 + } +} + +fn main() { + let val: A<2> = A; + assert_eq!(val.impl_method(), 17); + assert_eq!(A::<2>::associated_non_method(), 17); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/condition-in-trait-const-arg.rs b/gcc/testsuite/rust/rustc/ui/const-generics/condition-in-trait-const-arg.rs new file mode 100644 index 000000000000..844c18c2f926 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/condition-in-trait-const-arg.rs @@ -0,0 +1,16 @@ +// Checks that `impl Trait<{anon_const}> for Type` evaluates successfully. +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait IsZeroTrait{} + +impl IsZeroTrait<{0u8 == 0u8}> for () {} + +impl IsZeroTrait for ((),) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-arg-in-const-arg.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-arg-in-const-arg.rs new file mode 100644 index 000000000000..87fa8e5e3997 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-arg-in-const-arg.rs @@ -0,0 +1,45 @@ +// revisions: min +// FIXME(const_generics): This test currently causes an ICE because +// we don't yet correctly deal with lifetimes, reenable this test once +// this is fixed. +#![cfg_attr(min, feature(min_const_generics))] + +const fn foo() -> usize { std::mem::size_of::() } +const fn bar() -> usize { N } +const fn faz<'a>(_: &'a ()) -> usize { 13 } +const fn baz<'a>(_: &'a ()) -> usize where &'a (): Sized { 13 } + +struct Foo; +fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { + let _: [u8; foo::()]; // { dg-error "" "" { target *-*-* } } + let _: [u8; bar::()]; // { dg-error "" "" { target *-*-* } } + let _: [u8; faz::<'a>(&())]; // { dg-error "" "" { target *-*-* } } + let _: [u8; baz::<'a>(&())]; // { dg-error "" "" { target *-*-* } } + let _: [u8; faz::<'b>(&())]; // { dg-error "" "" { target *-*-* } } + let _: [u8; baz::<'b>(&())]; // { dg-error "" "" { target *-*-* } } + + // NOTE: This can be a future compat warning instead of an error, + // so we stop compilation before emitting this error in this test. + let _ = [0; foo::()]; + + let _ = [0; bar::()]; // { dg-error "" "" { target *-*-* } } + let _ = [0; faz::<'a>(&())]; // { dg-error "" "" { target *-*-* } } + let _ = [0; baz::<'a>(&())]; // { dg-error "" "" { target *-*-* } } + let _ = [0; faz::<'b>(&())]; // { dg-error "" "" { target *-*-* } } + let _ = [0; baz::<'b>(&())]; // { dg-error "" "" { target *-*-* } } + let _: Foo<{ foo::() }>; // { dg-error "" "" { target *-*-* } } + let _: Foo<{ bar::() }>; // { dg-error "" "" { target *-*-* } } + let _: Foo<{ faz::<'a>(&()) }>; // { dg-error "" "" { target *-*-* } } + let _: Foo<{ baz::<'a>(&()) }>; // { dg-error "" "" { target *-*-* } } + let _: Foo<{ faz::<'b>(&()) }>; // { dg-error "" "" { target *-*-* } } + let _: Foo<{ baz::<'b>(&()) }>; // { dg-error "" "" { target *-*-* } } + let _ = Foo::<{ foo::() }>; // { dg-error "" "" { target *-*-* } } + let _ = Foo::<{ bar::() }>; // { dg-error "" "" { target *-*-* } } + let _ = Foo::<{ faz::<'a>(&()) }>; // { dg-error "" "" { target *-*-* } } + let _ = Foo::<{ baz::<'a>(&()) }>; // { dg-error "" "" { target *-*-* } } + let _ = Foo::<{ faz::<'b>(&()) }>; // { dg-error "" "" { target *-*-* } } + let _ = Foo::<{ baz::<'b>(&()) }>; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-arg-in-fn.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-arg-in-fn.rs new file mode 100644 index 000000000000..579a0dc745fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-arg-in-fn.rs @@ -0,0 +1,16 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn const_u32_identity() -> u32 { + X +} + + fn main() { + let val = const_u32_identity::<18>(); + assert_eq!(val, 18); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-arg-type-arg-misordered.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-arg-type-arg-misordered.rs new file mode 100644 index 000000000000..2565e062b66f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-arg-type-arg-misordered.rs @@ -0,0 +1,14 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +type Array = [T; N]; + +fn foo() -> Array { +// { dg-error "" "" { target *-*-* } .-1 } + unimplemented!() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-argument-cross-crate-mismatch.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-argument-cross-crate-mismatch.rs new file mode 100644 index 000000000000..a4d93ec2e41d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-argument-cross-crate-mismatch.rs @@ -0,0 +1,12 @@ +// aux-build:const_generic_lib.rs +// revisions: full min + +extern crate const_generic_lib; + +fn main() { + let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8])); +// { dg-error "" "" { target *-*-* } .-1 } + let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-argument-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-argument-cross-crate.rs new file mode 100644 index 000000000000..af945a93128a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-argument-cross-crate.rs @@ -0,0 +1,14 @@ +// run-pass +// revisions: full min +// aux-build:const_generic_lib.rs + +extern crate const_generic_lib; + +struct Container(const_generic_lib::Alias); + +fn main() { + let res = const_generic_lib::function(const_generic_lib::Struct([14u8, 1u8, 2u8])); + assert_eq!(res, 14u8); + let _ = Container(const_generic_lib::Struct([0u8, 1u8])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-argument-if-length.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-argument-if-length.rs new file mode 100644 index 000000000000..2e4e56f945a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-argument-if-length.rs @@ -0,0 +1,25 @@ +// revisions: full min + +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +pub const fn is_zst() -> usize { + if std::mem::size_of::() == 0 { +// { dg-error "" "" { target *-*-* } .-1 } + 1 + } else { + 0 + } +} + +pub struct AtLeastByte { + value: T, +// { dg-error "" "" { target *-*-* } .-1 } + pad: [u8; is_zst::()], +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-argument-non-static-lifetime.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-argument-non-static-lifetime.rs new file mode 100644 index 000000000000..f471861d018e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-argument-non-static-lifetime.rs @@ -0,0 +1,20 @@ +// run-pass +// revisions: full +// FIXME(#75323) Omitted min revision for now due to ICE. + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![allow(dead_code)] + +fn test() {} + +fn wow<'a>() -> &'a () { + test::<{ + let _: &'a (); + 3 + }>(); + &() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-expression-parameter.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-expression-parameter.rs new file mode 100644 index 000000000000..9d823a68a2b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-expression-parameter.rs @@ -0,0 +1,26 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn i32_identity() -> i32 { + 5 +} + +fn foo_a() { + i32_identity::<-1>(); // ok +} + +fn foo_b() { + i32_identity::<1 + 2>(); // { dg-error "" "" { target *-*-* } } +} + +fn foo_c() { + i32_identity::< -1 >(); // ok +} + +fn main() { + i32_identity::<5>(); // ok +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-fn-with-const-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-fn-with-const-param.rs new file mode 100644 index 000000000000..74d619ba87ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-fn-with-const-param.rs @@ -0,0 +1,16 @@ +// Checks that `const fn` with const params can be used. +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +const fn const_u32_identity() -> u32 { + X +} + +fn main() { + assert_eq!(const_u32_identity::<18>(), 18); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-generic-array-wrapper.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-generic-array-wrapper.rs new file mode 100644 index 000000000000..df1c8701aee6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-generic-array-wrapper.rs @@ -0,0 +1,21 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Foo([T; N]); + +impl Foo { + fn foo(&self) -> usize { + N + } +} + +fn main() { + let foo = Foo([0u32; 21]); + assert_eq!(foo.0, [0u32; 21]); + assert_eq!(foo.foo(), 21); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-generic-type_name.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-generic-type_name.rs new file mode 100644 index 000000000000..82e380f077df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-generic-type_name.rs @@ -0,0 +1,14 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +#[derive(Debug)] +struct S; + +fn main() { + assert_eq!(std::any::type_name::>(), "const_generic_type_name::S<3>"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-param-after-const-literal-arg.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-after-const-literal-arg.rs new file mode 100644 index 000000000000..b797ad9edee2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-after-const-literal-arg.rs @@ -0,0 +1,13 @@ +// check-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Foo; + +impl Foo<1, A> {} // ok + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-param-before-other-params.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-before-other-params.rs new file mode 100644 index 000000000000..548efce8b555 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-before-other-params.rs @@ -0,0 +1,16 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn bar(_: &'a ()) { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn foo(_: &T) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-param-elided-lifetime.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-elided-lifetime.rs new file mode 100644 index 000000000000..b5bf7d2c5ce6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-elided-lifetime.rs @@ -0,0 +1,33 @@ +// Elided lifetimes within the type of a const generic parameters is disallowed. This matches the +// behaviour of trait bounds where `fn foo>() {}` is illegal. Though we could change +// elided lifetimes within the type of a const generic parameters to be 'static, like elided +// lifetimes within const/static items. +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct A; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +trait B {} + +impl A { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn foo(&self) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +impl B for A {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn bar() {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-param-from-outer-fn.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-from-outer-fn.rs new file mode 100644 index 000000000000..404fdad4cef0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-from-outer-fn.rs @@ -0,0 +1,14 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn foo() { + fn bar() -> u32 { + X // { dg-error "" "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-param-hygiene.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-hygiene.rs new file mode 100644 index 000000000000..f61b8653ed74 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-hygiene.rs @@ -0,0 +1,23 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +macro_rules! bar { + ($($t:tt)*) => { impl $($t)* }; +} + +macro_rules! baz { + ($t:tt) => { fn test(&self) -> usize { $t } }; +} + +struct Foo; + +bar!(Foo { baz!{ M } }); + +fn main() { + assert_eq!(Foo::<7>.test::<3>(), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-param-in-async.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-in-async.rs new file mode 100644 index 000000000000..fad782e4fc7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-in-async.rs @@ -0,0 +1,36 @@ +// edition:2018 +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +async fn foo(arg: [u8; N]) -> usize { arg.len() } + +async fn bar() -> [u8; N] { + [0; N] +} + +trait Trait { + fn fynn(&self) -> usize; +} +impl Trait for [u8; N] { + fn fynn(&self) -> usize { + N + } +} +async fn baz() -> impl Trait { + [0; N] +} + +async fn biz(v: impl Trait) -> usize { + v.fynn() +} + +async fn user() { + let _ = foo::(bar().await).await; + let _ = biz(baz::().await).await; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-param-in-trait-ungated.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-in-trait-ungated.rs new file mode 100644 index 000000000000..47a00c811ac6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-in-trait-ungated.rs @@ -0,0 +1,4 @@ +trait Trait {} // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-param-in-trait.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-in-trait.rs new file mode 100644 index 000000000000..d8ef76501109 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-in-trait.rs @@ -0,0 +1,13 @@ +// Check that const parameters are permitted in traits. +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + + +trait Trait {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-param-type-depends-on-const-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-type-depends-on-const-param.rs new file mode 100644 index 000000000000..3b34e1d86a26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-type-depends-on-const-param.rs @@ -0,0 +1,21 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +// Currently, const parameters cannot depend on other generic parameters, +// as our current implementation can't really support this. +// +// We may want to lift this restriction in the future. + +pub struct Dependent([(); N]); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +pub struct SelfDependent; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs new file mode 100644 index 000000000000..6d182551b608 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-type-depends-on-type-param-ungated.rs @@ -0,0 +1,10 @@ +// compile-flags: -Zsave-analysis +// Regression test for #69414 ^ + +use std::marker::PhantomData; + +struct B(PhantomData<[T; N]>); // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-param-type-depends-on-type-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-type-depends-on-type-param.rs new file mode 100644 index 000000000000..e2e98367a8e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-param-type-depends-on-type-param.rs @@ -0,0 +1,17 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +// Currently, const parameters cannot depend on other generic parameters, +// as our current implementation can't really support this. +// +// We may want to lift this restriction in the future. + +pub struct Dependent([(); X]); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-parameter-uppercase-lint.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-parameter-uppercase-lint.rs new file mode 100644 index 000000000000..9d800090ce53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-parameter-uppercase-lint.rs @@ -0,0 +1,14 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +#![deny(non_upper_case_globals)] + +fn noop() { +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const-types.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const-types.rs new file mode 100644 index 000000000000..93ff4c4fea68 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const-types.rs @@ -0,0 +1,20 @@ +// Check that arrays can be used with generic const and type. +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +#![allow(dead_code, unused_variables)] + +struct ConstArray { + array: [T; LEN], +} + +fn main() { + let arr = ConstArray:: { + array: [0; 8], + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/associated-consts.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/associated-consts.rs new file mode 100644 index 000000000000..427d43dff5b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/associated-consts.rs @@ -0,0 +1,32 @@ +// run-pass +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +pub trait BlockCipher { + const BLOCK_SIZE: usize; +} + +struct FooCipher; +impl BlockCipher for FooCipher { + const BLOCK_SIZE: usize = 64; +} + +struct BarCipher; +impl BlockCipher for BarCipher { + const BLOCK_SIZE: usize = 32; +} + +pub struct Block(C); + +pub fn test() +where + [u8; M - C::BLOCK_SIZE]: Sized, +{ + let _ = [0; M - C::BLOCK_SIZE]; +} + +fn main() { + test::(); + test::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/auxiliary/const_evaluatable_lib.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/auxiliary/const_evaluatable_lib.rs new file mode 100644 index 000000000000..7c361c1c8bdb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/auxiliary/const_evaluatable_lib.rs @@ -0,0 +1,10 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +pub fn test1() -> [u8; std::mem::size_of::() - 1] +where + [u8; std::mem::size_of::() - 1]: Sized, +{ + [0; std::mem::size_of::() - 1] +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/closures.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/closures.rs new file mode 100644 index 000000000000..8c51d79a1047 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/closures.rs @@ -0,0 +1,7 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] +fn test() -> [u8; N + (|| 42)()] {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/cross_crate.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/cross_crate.rs new file mode 100644 index 000000000000..a6db4bb88caa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/cross_crate.rs @@ -0,0 +1,16 @@ +// aux-build:const_evaluatable_lib.rs +// run-pass +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] +extern crate const_evaluatable_lib; + +fn user() where [u8; std::mem::size_of::() - 1]: Sized { + assert_eq!(const_evaluatable_lib::test1::(), [0; std::mem::size_of::() - 1]); +} + +fn main() { + assert_eq!(const_evaluatable_lib::test1::(), [0; 3]); + user::(); + user::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs new file mode 100644 index 000000000000..2913a042af37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs @@ -0,0 +1,15 @@ +// aux-build:const_evaluatable_lib.rs +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] +extern crate const_evaluatable_lib; + +fn user() { + let _ = const_evaluatable_lib::test1::(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/different-fn.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/different-fn.rs new file mode 100644 index 000000000000..ea33ee3f8ac4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/different-fn.rs @@ -0,0 +1,17 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +use std::mem::size_of; +use std::marker::PhantomData; + +struct Foo(PhantomData); + +fn test() -> [u8; size_of::()] { + [0; size_of::>()] +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + test::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/division.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/division.rs new file mode 100644 index 000000000000..191ed552e439 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/division.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +fn with_bound() where [u8; N / 2]: Sized { + let _: [u8; N / 2] = [0; N / 2]; +} + +fn main() { + with_bound::<4>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs new file mode 100644 index 000000000000..c02bac978e9a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/feature-gate-const_evaluatable_checked.rs @@ -0,0 +1,18 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +type Arr = [u8; N - 1]; +// { dg-error "" "" { target *-*-* } .-1 } + +fn test() -> Arr where Arr: Default { +// { dg-error "" "" { target *-*-* } .-1 } + Default::default() +} + +fn main() { + let x = test::<33>(); + assert_eq!(x, [0; 32]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/fn_call.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/fn_call.rs new file mode 100644 index 000000000000..93fcd4785217 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/fn_call.rs @@ -0,0 +1,31 @@ +// run-pass +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +const fn test_me(a: usize, b: usize) -> usize { + if a < b { + std::mem::size_of::() + } else { + std::usize::MAX + } +} + +fn test_simple() -> [u8; std::mem::size_of::()] +where + [u8; std::mem::size_of::()]: Sized, +{ + [0; std::mem::size_of::()] +} + +fn test_with_args() -> [u8; test_me::(N, N + 1) + N] +where + [u8; test_me::(N, N + 1) + N]: Sized, +{ + [0; test_me::(N, N + 1) + N] +} + +fn main() { + assert_eq!([0; 8], test_simple::()); + assert_eq!([0; 12], test_with_args::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs new file mode 100644 index 000000000000..2fc56e810f70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs @@ -0,0 +1,12 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +fn test() -> [u8; N - 1] { +// { dg-error ".E0080." "" { target *-*-* } .-1 } + todo!() +} + +fn main() { + test::<0>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/from-sig.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/from-sig.rs new file mode 100644 index 000000000000..749011df7d79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/from-sig.rs @@ -0,0 +1,15 @@ +// run-pass +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +struct Foo; + +fn test() -> Foo<{ N > 10 }> { + Foo +} + +fn main() { + let _: Foo = test::<12>(); + let _: Foo = test::<9>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/impl-bounds.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/impl-bounds.rs new file mode 100644 index 000000000000..41b7ba59c1b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/impl-bounds.rs @@ -0,0 +1,26 @@ +// check-pass +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +use std::mem::size_of; + +struct Foo(T); + +impl Foo() }> { + fn test() { + let _: [u8; std::mem::size_of::()]; + } +} + +trait Bar { + fn test_me(); +} + +impl Bar<{ size_of::() }> for Foo { + fn test_me() { + let _: [u8; std::mem::size_of::()]; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/infer-too-generic.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/infer-too-generic.rs new file mode 100644 index 000000000000..2a32d3d7843b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/infer-too-generic.rs @@ -0,0 +1,25 @@ +// run-pass +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +use std::{mem, ptr}; + +fn split_first(arr: [T; N]) -> (T, [T; N - 1]) +where + [T; N - 1]: Sized, +{ + let arr = mem::ManuallyDrop::new(arr); + unsafe { + let head = ptr::read(&arr[0]); + let tail = ptr::read(&arr[1..] as *const [T] as *const [T; N - 1]); + (head, tail) + } +} + +fn main() { + let arr = [0, 1, 2, 3, 4]; + let (head, tail) = split_first(arr); + assert_eq!(head, 0); + assert_eq!(tail, [1, 2, 3, 4]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/less_than.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/less_than.rs new file mode 100644 index 000000000000..8783e2a521b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/less_than.rs @@ -0,0 +1,15 @@ +// run-pass +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +struct Foo; + +fn test() -> Foo<{ N > 10 }> where Foo<{ N > 10 }>: Sized { + Foo +} + +fn main() { + let _: Foo = test::<12>(); + let _: Foo = test::<9>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/let-bindings.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/let-bindings.rs new file mode 100644 index 000000000000..6556d226247c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/let-bindings.rs @@ -0,0 +1,16 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +// We do not yet want to support let-bindings in abstract consts, +// so this test should keep failing for now. +fn test() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + Default::default() +} + +fn main() { + let x = test::<31>(); + assert_eq!(x, [0; 32]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.rs new file mode 100644 index 000000000000..f9191957517e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.rs @@ -0,0 +1,22 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + + +const fn bar() -> usize { 7 } + +trait Foo { + fn test(&self) -> [u8; bar::()]; +} + +impl Foo for () { + fn test(&self) -> [u8; bar::()] { + [0; bar::()] + } +} + +fn use_dyn(v: &dyn Foo) { // { dg-error ".E0038." "" { target *-*-* } } + v.test(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-err-where-bounds.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-err-where-bounds.rs new file mode 100644 index 000000000000..ef3a9a38ff3d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-err-where-bounds.rs @@ -0,0 +1,23 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] +#![deny(where_clauses_object_safety)] + + +const fn bar() -> usize { 7 } + +trait Foo { + fn test(&self) where [u8; bar::()]: Sized; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +impl Foo for () { + fn test(&self) where [u8; bar::()]: Sized {} +} + +fn use_dyn(v: &dyn Foo) { + v.test(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-ok-infer-err.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-ok-infer-err.rs new file mode 100644 index 000000000000..411c34464253 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-ok-infer-err.rs @@ -0,0 +1,23 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +trait Foo { + fn test(&self) -> [u8; N + 1]; +} + +impl Foo for () { + fn test(&self) -> [u8; N + 1] { + [0; N + 1] + } +} + +fn use_dyn(v: &dyn Foo) where [u8; N + 1]: Sized { + assert_eq!(v.test(), [0; N + 1]); +} + +fn main() { + // FIXME(const_evaluatable_checked): Improve the error message here. + use_dyn(&()); +// { dg-error ".E0284." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-ok.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-ok.rs new file mode 100644 index 000000000000..670932f489d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/object-safety-ok.rs @@ -0,0 +1,22 @@ +// run-pass +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +trait Foo { + fn test(&self) -> [u8; N + 1]; +} + +impl Foo for () { + fn test(&self) -> [u8; N + 1] { + [0; N + 1] + } +} + +fn use_dyn(v: &dyn Foo) where [u8; N + 1]: Sized { + assert_eq!(v.test(), [0; N + 1]); +} + +fn main() { + use_dyn::<3>(&()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/simple.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/simple.rs new file mode 100644 index 000000000000..2cfa0e0484f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/simple.rs @@ -0,0 +1,18 @@ +// [full] run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] +#![feature(const_evaluatable_checked)] +#![allow(incomplete_features)] + +fn test() -> [u8; N - 1] where [u8; N - 1]: Default { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + Default::default() +} + +fn main() { + let x = test::<33>(); + assert_eq!(x, [0; 32]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/simple_fail.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/simple_fail.rs new file mode 100644 index 000000000000..9af858ee2b2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/simple_fail.rs @@ -0,0 +1,17 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] +#![feature(const_evaluatable_checked)] +#![allow(incomplete_features)] + +type Arr = [u8; N - 1]; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + +fn test() -> Arr where Arr: Sized { + todo!() +} + +fn main() { + test::<0>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/unop.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/unop.rs new file mode 100644 index 000000000000..fe425824903f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/unop.rs @@ -0,0 +1,15 @@ +// run-pass +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +struct Foo; + +fn test() -> Foo<{ !(N > 10) }> where Foo<{ !(N > 10) }>: Sized { + Foo +} + +fn main() { + let _: Foo = test::<12>(); + let _: Foo = test::<9>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/unused_expr.rs b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/unused_expr.rs new file mode 100644 index 000000000000..445eb5b8cc9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/const_evaluatable_checked/unused_expr.rs @@ -0,0 +1,26 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +fn add() -> [u8; { N + 1; 5 }] { +// { dg-error "" "" { target *-*-* } .-1 } + todo!() +} + +fn div() -> [u8; { N / 1; 5 }] { +// { dg-error "" "" { target *-*-* } .-1 } + todo!() +} + +const fn foo(n: usize) {} + +fn fn_call() -> [u8; { foo(N); 5 }] { +// { dg-error "" "" { target *-*-* } .-1 } + todo!() +} + +fn main() { + add::<12>(); + div::<9>(); + fn_call::<14>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/core-types.rs b/gcc/testsuite/rust/rustc/ui/const-generics/core-types.rs new file mode 100644 index 000000000000..ee9bdb1b5c42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/core-types.rs @@ -0,0 +1,52 @@ +// Check that all types allowed with `min_const_generics` work. +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct A; +struct B; +struct C; +struct D; +struct E; +struct F; +struct G; +struct H; +struct I; +struct J; +struct K; +struct L; +struct M; +struct N; + +fn main() { + let _ = A::<{u8::MIN}>; + let _ = A::<{u8::MAX}>; + let _ = B::<{u16::MIN}>; + let _ = B::<{u16::MAX}>; + let _ = C::<{u32::MIN}>; + let _ = C::<{u32::MAX}>; + let _ = D::<{u64::MIN}>; + let _ = D::<{u64::MAX}>; + let _ = E::<{u128::MIN}>; + let _ = E::<{u128::MAX}>; + let _ = F::<{usize::MIN}>; + let _ = F::<{usize::MAX}>; + let _ = G::<{i8::MIN}>; + let _ = G::<{i8::MAX}>; + let _ = H::<{i16::MIN}>; + let _ = H::<{i16::MAX}>; + let _ = I::<{i32::MIN}>; + let _ = I::<{i32::MAX}>; + let _ = J::<{i64::MIN}>; + let _ = J::<{i64::MAX}>; + let _ = K::<{i128::MIN}>; + let _ = K::<{i128::MAX}>; + let _ = L::<{isize::MIN}>; + let _ = L::<{isize::MAX}>; + let _ = M::<'A'>; + let _ = N::; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/cross_crate_complex.rs b/gcc/testsuite/rust/rustc/ui/const-generics/cross_crate_complex.rs new file mode 100644 index 000000000000..0389ffb5ae57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/cross_crate_complex.rs @@ -0,0 +1,29 @@ +// aux-build:crayte.rs +// edition:2018 +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] +extern crate crayte; + +use crayte::*; + +async fn foo() { + in_foo(out_foo::<3>()); + async_simple([0; 17]).await; + async_in_foo(async_out_foo::<4>().await).await; +} + +struct Faz; + +impl Foo for Faz {} +impl Bar for Faz { + type Assoc = Faz; +} + +fn main() { + let _ = foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/defaults/complex-unord-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/defaults/complex-unord-param.rs new file mode 100644 index 000000000000..cd74df0d1b27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/defaults/complex-unord-param.rs @@ -0,0 +1,23 @@ +// [full] run-pass +// revisions: full min +// Checks a complicated usage of unordered params +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] +#![allow(dead_code)] + +struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> { +// { dg-error "" "" { target *-*-* } .-1 } + args: &'a [&'a [T; M]; N], + specifier: A, +} + +fn main() { + let array = [1, 2, 3]; + let nest = [&array]; + let _ = NestedArrays { + args: &nest, + specifier: true, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/defaults/intermixed-lifetime.rs b/gcc/testsuite/rust/rustc/ui/const-generics/defaults/intermixed-lifetime.rs new file mode 100644 index 000000000000..7cdda8dfdab4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/defaults/intermixed-lifetime.rs @@ -0,0 +1,17 @@ +// revisions: full min +// Checks that lifetimes cannot be interspersed between consts and types. +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Foo(&'a (), T); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +struct Bar(&'a (), T); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/defaults/needs-feature.rs b/gcc/testsuite/rust/rustc/ui/const-generics/defaults/needs-feature.rs new file mode 100644 index 000000000000..eedbd7aa41ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/defaults/needs-feature.rs @@ -0,0 +1,18 @@ +//[full] run-pass +// Verifies that having generic parameters after constants is not permitted without the +// `const_generics` feature. +// revisions: none min full + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct A(T); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + +fn main() { + let _: A<3> = A(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/defaults/simple-defaults.rs b/gcc/testsuite/rust/rustc/ui/const-generics/defaults/simple-defaults.rs new file mode 100644 index 000000000000..d32fe7d0a695 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/defaults/simple-defaults.rs @@ -0,0 +1,19 @@ +// [full] run-pass +// revisions: min full +// Checks some basic test cases for defaults. +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] +#![allow(dead_code)] + +struct FixedOutput<'a, const N: usize, T=u32> { +// { dg-error "" "" { target *-*-* } .-1 } + out: &'a [T; N], +} + +trait FixedOutputter { + fn out(&self) -> FixedOutput<'_, 10>; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/defaults/wrong-order.rs b/gcc/testsuite/rust/rustc/ui/const-generics/defaults/wrong-order.rs new file mode 100644 index 000000000000..92ff8f5fbfbe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/defaults/wrong-order.rs @@ -0,0 +1,11 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] // { dg-warning "" "" { target *-*-* } } +#![cfg_attr(min, feature(min_const_generics))] + +struct A { +// { dg-error "" "" { target *-*-* } .-1 } + arg: T, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/derive-debug-array-wrapper.rs b/gcc/testsuite/rust/rustc/ui/const-generics/derive-debug-array-wrapper.rs new file mode 100644 index 000000000000..a8d55ae1844d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/derive-debug-array-wrapper.rs @@ -0,0 +1,15 @@ +// Check that deriving debug on struct with const is permitted. +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +#[derive(Debug)] +struct X { + a: [u32; N], +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/different_byref.rs b/gcc/testsuite/rust/rustc/ui/const-generics/different_byref.rs new file mode 100644 index 000000000000..ca95fbac30ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/different_byref.rs @@ -0,0 +1,16 @@ +// Check that different const types are different. +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Const {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + let mut x = Const::<{ [3] }> {}; + x = Const::<{ [4] }> {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/different_byref_simple.rs b/gcc/testsuite/rust/rustc/ui/const-generics/different_byref_simple.rs new file mode 100644 index 000000000000..1e6d7e13dfea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/different_byref_simple.rs @@ -0,0 +1,15 @@ +// Check that different const types are different. +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct ConstUsize {} + +fn main() { + let mut u = ConstUsize::<3> {}; + u = ConstUsize::<4> {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/dyn-supertraits.rs b/gcc/testsuite/rust/rustc/ui/const-generics/dyn-supertraits.rs new file mode 100644 index 000000000000..98a9822e9489 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/dyn-supertraits.rs @@ -0,0 +1,86 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Foo { + fn myfun(&self) -> usize; +} +trait Bar : Foo {} +trait Baz: Foo<3> {} + +struct FooType; +struct BarType; +struct BazType; + +impl Foo for FooType { + fn myfun(&self) -> usize { N } +} +impl Foo for BarType { + fn myfun(&self) -> usize { N + 1 } +} +impl Bar for BarType {} +impl Foo<3> for BazType { + fn myfun(&self) -> usize { 999 } +} +impl Baz for BazType {} + +trait Foz {} +trait Boz: Foo<3> + Foz {} +trait Bok: Foo + Foz {} + +struct FozType; +struct BozType; +struct BokType; + +impl Foz for FozType {} + +impl Foz for BozType {} +impl Foo<3> for BozType { + fn myfun(&self) -> usize { 9999 } +} +impl Boz for BozType {} + +impl Foz for BokType {} +impl Foo for BokType { + fn myfun(&self) -> usize { N + 2 } +} +impl Bok for BokType {} + +fn a(x: &dyn Foo) -> usize { x.myfun() } +fn b(x: &dyn Foo<3>) -> usize { x.myfun() } +fn c, const N: usize>(x: T) -> usize { a::(&x) } +fn d>(x: &T) -> usize { x.myfun() } +fn e(x: &dyn Bar<3>) -> usize { d(x) } + +fn main() { + let foo = FooType::<3> {}; + assert!(a(&foo) == 3); + assert!(b(&foo) == 3); + assert!(d(&foo) == 3); + + let bar = BarType::<3> {}; + assert!(a(&bar) == 4); + assert!(b(&bar) == 4); + assert!(d(&bar) == 4); + assert!(e(&bar) == 4); + + let baz = BazType {}; + assert!(a(&baz) == 999); + assert!(b(&baz) == 999); + assert!(d(&baz) == 999); + + let boz = BozType {}; + assert!(a(&boz) == 9999); + assert!(b(&boz) == 9999); + assert!(d(&boz) == 9999); + + let bok = BokType::<3> {}; + assert!(a(&bok) == 5); + assert!(b(&bok) == 5); + assert!(d(&bok) == 5); + assert!(c(BokType::<3> {}) == 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/exhaustive-value.rs b/gcc/testsuite/rust/rustc/ui/const-generics/exhaustive-value.rs new file mode 100644 index 000000000000..424b26a950fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/exhaustive-value.rs @@ -0,0 +1,273 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Foo { + fn test() {} +} +impl Foo<0> for () {} +impl Foo<1> for () {} +impl Foo<2> for () {} +impl Foo<3> for () {} +impl Foo<4> for () {} +impl Foo<5> for () {} +impl Foo<6> for () {} +impl Foo<7> for () {} +impl Foo<8> for () {} +impl Foo<9> for () {} +impl Foo<10> for () {} +impl Foo<11> for () {} +impl Foo<12> for () {} +impl Foo<13> for () {} +impl Foo<14> for () {} +impl Foo<15> for () {} +impl Foo<16> for () {} +impl Foo<17> for () {} +impl Foo<18> for () {} +impl Foo<19> for () {} +impl Foo<20> for () {} +impl Foo<21> for () {} +impl Foo<22> for () {} +impl Foo<23> for () {} +impl Foo<24> for () {} +impl Foo<25> for () {} +impl Foo<26> for () {} +impl Foo<27> for () {} +impl Foo<28> for () {} +impl Foo<29> for () {} +impl Foo<30> for () {} +impl Foo<31> for () {} +impl Foo<32> for () {} +impl Foo<33> for () {} +impl Foo<34> for () {} +impl Foo<35> for () {} +impl Foo<36> for () {} +impl Foo<37> for () {} +impl Foo<38> for () {} +impl Foo<39> for () {} +impl Foo<40> for () {} +impl Foo<41> for () {} +impl Foo<42> for () {} +impl Foo<43> for () {} +impl Foo<44> for () {} +impl Foo<45> for () {} +impl Foo<46> for () {} +impl Foo<47> for () {} +impl Foo<48> for () {} +impl Foo<49> for () {} +impl Foo<50> for () {} +impl Foo<51> for () {} +impl Foo<52> for () {} +impl Foo<53> for () {} +impl Foo<54> for () {} +impl Foo<55> for () {} +impl Foo<56> for () {} +impl Foo<57> for () {} +impl Foo<58> for () {} +impl Foo<59> for () {} +impl Foo<60> for () {} +impl Foo<61> for () {} +impl Foo<62> for () {} +impl Foo<63> for () {} +impl Foo<64> for () {} +impl Foo<65> for () {} +impl Foo<66> for () {} +impl Foo<67> for () {} +impl Foo<68> for () {} +impl Foo<69> for () {} +impl Foo<70> for () {} +impl Foo<71> for () {} +impl Foo<72> for () {} +impl Foo<73> for () {} +impl Foo<74> for () {} +impl Foo<75> for () {} +impl Foo<76> for () {} +impl Foo<77> for () {} +impl Foo<78> for () {} +impl Foo<79> for () {} +impl Foo<80> for () {} +impl Foo<81> for () {} +impl Foo<82> for () {} +impl Foo<83> for () {} +impl Foo<84> for () {} +impl Foo<85> for () {} +impl Foo<86> for () {} +impl Foo<87> for () {} +impl Foo<88> for () {} +impl Foo<89> for () {} +impl Foo<90> for () {} +impl Foo<91> for () {} +impl Foo<92> for () {} +impl Foo<93> for () {} +impl Foo<94> for () {} +impl Foo<95> for () {} +impl Foo<96> for () {} +impl Foo<97> for () {} +impl Foo<98> for () {} +impl Foo<99> for () {} +impl Foo<100> for () {} +impl Foo<101> for () {} +impl Foo<102> for () {} +impl Foo<103> for () {} +impl Foo<104> for () {} +impl Foo<105> for () {} +impl Foo<106> for () {} +impl Foo<107> for () {} +impl Foo<108> for () {} +impl Foo<109> for () {} +impl Foo<110> for () {} +impl Foo<111> for () {} +impl Foo<112> for () {} +impl Foo<113> for () {} +impl Foo<114> for () {} +impl Foo<115> for () {} +impl Foo<116> for () {} +impl Foo<117> for () {} +impl Foo<118> for () {} +impl Foo<119> for () {} +impl Foo<120> for () {} +impl Foo<121> for () {} +impl Foo<122> for () {} +impl Foo<123> for () {} +impl Foo<124> for () {} +impl Foo<125> for () {} +impl Foo<126> for () {} +impl Foo<127> for () {} +impl Foo<128> for () {} +impl Foo<129> for () {} +impl Foo<130> for () {} +impl Foo<131> for () {} +impl Foo<132> for () {} +impl Foo<133> for () {} +impl Foo<134> for () {} +impl Foo<135> for () {} +impl Foo<136> for () {} +impl Foo<137> for () {} +impl Foo<138> for () {} +impl Foo<139> for () {} +impl Foo<140> for () {} +impl Foo<141> for () {} +impl Foo<142> for () {} +impl Foo<143> for () {} +impl Foo<144> for () {} +impl Foo<145> for () {} +impl Foo<146> for () {} +impl Foo<147> for () {} +impl Foo<148> for () {} +impl Foo<149> for () {} +impl Foo<150> for () {} +impl Foo<151> for () {} +impl Foo<152> for () {} +impl Foo<153> for () {} +impl Foo<154> for () {} +impl Foo<155> for () {} +impl Foo<156> for () {} +impl Foo<157> for () {} +impl Foo<158> for () {} +impl Foo<159> for () {} +impl Foo<160> for () {} +impl Foo<161> for () {} +impl Foo<162> for () {} +impl Foo<163> for () {} +impl Foo<164> for () {} +impl Foo<165> for () {} +impl Foo<166> for () {} +impl Foo<167> for () {} +impl Foo<168> for () {} +impl Foo<169> for () {} +impl Foo<170> for () {} +impl Foo<171> for () {} +impl Foo<172> for () {} +impl Foo<173> for () {} +impl Foo<174> for () {} +impl Foo<175> for () {} +impl Foo<176> for () {} +impl Foo<177> for () {} +impl Foo<178> for () {} +impl Foo<179> for () {} +impl Foo<180> for () {} +impl Foo<181> for () {} +impl Foo<182> for () {} +impl Foo<183> for () {} +impl Foo<184> for () {} +impl Foo<185> for () {} +impl Foo<186> for () {} +impl Foo<187> for () {} +impl Foo<188> for () {} +impl Foo<189> for () {} +impl Foo<190> for () {} +impl Foo<191> for () {} +impl Foo<192> for () {} +impl Foo<193> for () {} +impl Foo<194> for () {} +impl Foo<195> for () {} +impl Foo<196> for () {} +impl Foo<197> for () {} +impl Foo<198> for () {} +impl Foo<199> for () {} +impl Foo<200> for () {} +impl Foo<201> for () {} +impl Foo<202> for () {} +impl Foo<203> for () {} +impl Foo<204> for () {} +impl Foo<205> for () {} +impl Foo<206> for () {} +impl Foo<207> for () {} +impl Foo<208> for () {} +impl Foo<209> for () {} +impl Foo<210> for () {} +impl Foo<211> for () {} +impl Foo<212> for () {} +impl Foo<213> for () {} +impl Foo<214> for () {} +impl Foo<215> for () {} +impl Foo<216> for () {} +impl Foo<217> for () {} +impl Foo<218> for () {} +impl Foo<219> for () {} +impl Foo<220> for () {} +impl Foo<221> for () {} +impl Foo<222> for () {} +impl Foo<223> for () {} +impl Foo<224> for () {} +impl Foo<225> for () {} +impl Foo<226> for () {} +impl Foo<227> for () {} +impl Foo<228> for () {} +impl Foo<229> for () {} +impl Foo<230> for () {} +impl Foo<231> for () {} +impl Foo<232> for () {} +impl Foo<233> for () {} +impl Foo<234> for () {} +impl Foo<235> for () {} +impl Foo<236> for () {} +impl Foo<237> for () {} +impl Foo<238> for () {} +impl Foo<239> for () {} +impl Foo<240> for () {} +impl Foo<241> for () {} +impl Foo<242> for () {} +impl Foo<243> for () {} +impl Foo<244> for () {} +impl Foo<245> for () {} +impl Foo<246> for () {} +impl Foo<247> for () {} +impl Foo<248> for () {} +impl Foo<249> for () {} +impl Foo<250> for () {} +impl Foo<251> for () {} +impl Foo<252> for () {} +impl Foo<253> for () {} +impl Foo<254> for () {} +impl Foo<255> for () {} + +fn foo() { + <() as Foo>::test() // { dg-error "" "" { target *-*-* } } +} + +fn main() { + foo::<7>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/fn-const-param-call.rs b/gcc/testsuite/rust/rustc/ui/const-generics/fn-const-param-call.rs new file mode 100644 index 000000000000..b5d2674aa951 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/fn-const-param-call.rs @@ -0,0 +1,24 @@ +// Check that functions cannot be used as const parameters. +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn function() -> u32 { + 17 +} + +struct Wrapper u32>; // { dg-error "" "" { target *-*-* } } + +impl u32> Wrapper { +// { dg-error "" "" { target *-*-* } .-1 } + fn call() -> u32 { + F() + } +} + +fn main() { + assert_eq!(Wrapper::::call(), 17); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/fn-const-param-infer.rs b/gcc/testsuite/rust/rustc/ui/const-generics/fn-const-param-infer.rs new file mode 100644 index 000000000000..11f32b0ba8aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/fn-const-param-infer.rs @@ -0,0 +1,31 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Checked bool>; +// { dg-error "" "" { target *-*-* } .-1 } + +fn not_one(val: usize) -> bool { val != 1 } +fn not_two(val: usize) -> bool { val != 2 } + +fn generic_arg(val: T) -> bool { true } + +fn generic(val: usize) -> bool { val != 1 } + +fn main() { + let _: Option> = None; + let _: Checked = Checked::; + let _: Checked = Checked::; + + let _ = Checked::; + let _ = Checked::<{generic_arg::}>; + let _ = Checked::<{generic_arg::}>; + + let _ = Checked::; + let _ = Checked::<{generic::}>; + let _: Checked<{generic::}> = Checked::<{generic::}>; + let _: Checked<{generic::}> = Checked::<{generic::}>; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/fn-taking-const-generic-array.rs b/gcc/testsuite/rust/rustc/ui/const-generics/fn-taking-const-generic-array.rs new file mode 100644 index 000000000000..e850230e6bf8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/fn-taking-const-generic-array.rs @@ -0,0 +1,19 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +use std::fmt::Display; + +fn print_slice(slice: &[T; N]) { + for x in slice.iter() { + println!("{}", x); + } +} + +fn main() { + print_slice(&[1, 2, 3]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/forbid-non-structural_match-types.rs b/gcc/testsuite/rust/rustc/ui/const-generics/forbid-non-structural_match-types.rs new file mode 100644 index 000000000000..a700d71b8877 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/forbid-non-structural_match-types.rs @@ -0,0 +1,19 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +#[derive(PartialEq, Eq)] +struct A; + +struct B; // ok +// { dg-error "" "" { target *-*-* } .-1 } + +struct C; + +struct D; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/foreign-item-const-parameter.rs b/gcc/testsuite/rust/rustc/ui/const-generics/foreign-item-const-parameter.rs new file mode 100644 index 000000000000..bca931c980be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/foreign-item-const-parameter.rs @@ -0,0 +1,14 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +extern "C" { + fn foo(); // { dg-error "" "" { target *-*-* } } + + fn bar(_: T); // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/generic-function-call-in-array-length.rs b/gcc/testsuite/rust/rustc/ui/const-generics/generic-function-call-in-array-length.rs new file mode 100644 index 000000000000..24bc8ec80412 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/generic-function-call-in-array-length.rs @@ -0,0 +1,17 @@ +// revisions: full min + +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +const fn foo(n: usize) -> usize { n * 2 } + +fn bar() -> [u32; foo(N)] { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + [0; foo(N)] +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/generic-param-mismatch.rs b/gcc/testsuite/rust/rustc/ui/const-generics/generic-param-mismatch.rs new file mode 100644 index 000000000000..34f129fb95ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/generic-param-mismatch.rs @@ -0,0 +1,11 @@ +// revisions: full min +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +fn test() -> [u8; M] { + [0; N] // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/generic-sum-in-array-length.rs b/gcc/testsuite/rust/rustc/ui/const-generics/generic-sum-in-array-length.rs new file mode 100644 index 000000000000..e1b57ef42c34 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/generic-sum-in-array-length.rs @@ -0,0 +1,13 @@ +// revisions: full min + +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +fn foo(bar: [usize; A + B]) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/impl-const-generic-struct.rs b/gcc/testsuite/rust/rustc/ui/const-generics/impl-const-generic-struct.rs new file mode 100644 index 000000000000..5c3484a148bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/impl-const-generic-struct.rs @@ -0,0 +1,19 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct S; + +impl S { + fn x() -> u32 { + X + } +} + +fn main() { + assert_eq!(S::<19>::x(), 19); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/impl-trait-with-const-arguments.rs b/gcc/testsuite/rust/rustc/ui/const-generics/impl-trait-with-const-arguments.rs new file mode 100644 index 000000000000..826c92e1c50f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/impl-trait-with-const-arguments.rs @@ -0,0 +1,27 @@ +// revisions: full min + +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Usizer { + fn m(self) -> usize; +} + +fn f(u: impl Usizer) -> usize { + N + u.m() +} + +struct Usizable; + +impl Usizer for Usizable { + fn m(self) -> usize { + 16 + } +} + +fn main() { + assert_eq!(f::<4usize>(Usizable), 20usize); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/incorrect-number-of-const-args.rs b/gcc/testsuite/rust/rustc/ui/const-generics/incorrect-number-of-const-args.rs new file mode 100644 index 000000000000..0d4badb9a08e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/incorrect-number-of-const-args.rs @@ -0,0 +1,15 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn foo() -> usize { + 0 +} + +fn main() { + foo::<0>(); // { dg-error "" "" { target *-*-* } } + foo::<0, 0, 0>(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/infer/cannot-infer-const-args.rs b/gcc/testsuite/rust/rustc/ui/const-generics/infer/cannot-infer-const-args.rs new file mode 100644 index 000000000000..8ccd351a83d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/infer/cannot-infer-const-args.rs @@ -0,0 +1,14 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn foo() -> usize { + 0 +} + +fn main() { + foo(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/infer/issue-77092.rs b/gcc/testsuite/rust/rustc/ui/const-generics/infer/issue-77092.rs new file mode 100644 index 000000000000..f6ff94c1522b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/infer/issue-77092.rs @@ -0,0 +1,17 @@ +#![feature(min_const_generics)] + +use std::convert::TryInto; + +fn take_array_from_mut(data: &mut [T], start: usize) -> &mut [T; N] { + (&mut data[start .. start + N]).try_into().unwrap() +} + +fn main() { + let mut arr = [0, 1, 2, 3, 4, 5, 6, 7, 8]; + + for i in 1 .. 4 { + println!("{:?}", take_array_from_mut(&mut arr, i)); +// { dg-error ".E0282." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/infer/method-chain.rs b/gcc/testsuite/rust/rustc/ui/const-generics/infer/method-chain.rs new file mode 100644 index 000000000000..c1713ab39e6a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/infer/method-chain.rs @@ -0,0 +1,23 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Foo; + +impl Foo { + fn bar(self) -> Foo { + Foo + } + + fn baz(self) -> Foo { + println!("baz: {}", N); + Foo + } +} + +fn main() { + Foo.bar().bar().bar().bar().baz(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/infer/uninferred-consts.rs b/gcc/testsuite/rust/rustc/ui/const-generics/infer/uninferred-consts.rs new file mode 100644 index 000000000000..52aed2a34753 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/infer/uninferred-consts.rs @@ -0,0 +1,17 @@ +// Test that we emit an error if we cannot properly infer a constant. +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +// taken from https://github.com/rust-lang/rust/issues/70507#issuecomment-615268893 +struct Foo; +impl Foo { + fn foo(self) {} +} +fn main() { + Foo.foo(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/infer_arg_from_pat.rs b/gcc/testsuite/rust/rustc/ui/const-generics/infer_arg_from_pat.rs new file mode 100644 index 000000000000..a600895f22ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/infer_arg_from_pat.rs @@ -0,0 +1,31 @@ +// run-pass +// +// see issue #70529 +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct A { + arr: [u8; N], +} + +impl A { + fn new() -> Self { + A { + arr: [0; N], + } + } + + fn value(&self) -> usize { + N + } +} + +fn main() { + let a = A::new(); + let [_, _] = a.arr; + assert_eq!(a.value(), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/infer_arr_len_from_pat.rs b/gcc/testsuite/rust/rustc/ui/const-generics/infer_arr_len_from_pat.rs new file mode 100644 index 000000000000..c6b844f679d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/infer_arr_len_from_pat.rs @@ -0,0 +1,17 @@ +// check-pass +// +// see issue #70529 +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn as_chunks() -> [u8; N] { + loop {} +} + +fn main() { + let [_, _] = as_chunks(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs b/gcc/testsuite/rust/rustc/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs new file mode 100644 index 000000000000..797011ed578d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs @@ -0,0 +1,24 @@ +// check-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn takes_closure_of_array_3(f: F) where F: Fn([i32; 3]) { + f([1, 2, 3]); +} + +fn takes_closure_of_array_3_apit(f: impl Fn([i32; 3])) { + f([1, 2, 3]); +} + +fn returns_closure_of_array_3() -> impl Fn([i32; 3]) { + |_| {} +} + +fn main() { + takes_closure_of_array_3(returns_closure_of_array_3()); + takes_closure_of_array_3_apit(returns_closure_of_array_3()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/intrinsics-type_name-as-const-argument.rs b/gcc/testsuite/rust/rustc/ui/const-generics/intrinsics-type_name-as-const-argument.rs new file mode 100644 index 000000000000..3e04d87cd764 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/intrinsics-type_name-as-const-argument.rs @@ -0,0 +1,23 @@ +// revisions: full min + +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +#![feature(core_intrinsics)] +#![feature(const_type_name)] + +trait Trait {} +// { dg-error "" "" { target *-*-* } .-1 } + +struct Bug +where + T: Trait<{std::intrinsics::type_name::()}> +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +{ + t: T +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/invalid-const-arg-for-type-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/invalid-const-arg-for-type-param.rs new file mode 100644 index 000000000000..f7ed90ec6c78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/invalid-const-arg-for-type-param.rs @@ -0,0 +1,10 @@ +use std::convert::TryInto; + +struct S; + +fn main() { + let _: u32 = 5i32.try_into::<32>().unwrap(); // { dg-error ".E0107." "" { target *-*-* } } + S.f::<0>(); // { dg-error ".E0599." "" { target *-*-* } } + S::<0>; // { dg-error ".E0107." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/invalid-constant-in-args.rs b/gcc/testsuite/rust/rustc/ui/const-generics/invalid-constant-in-args.rs new file mode 100644 index 000000000000..8328d3a7efc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/invalid-constant-in-args.rs @@ -0,0 +1,4 @@ +fn main() { + let _: Vec<&str, "a"> = Vec::new(); // { dg-error ".E0107." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/invalid-enum.rs b/gcc/testsuite/rust/rustc/ui/const-generics/invalid-enum.rs new file mode 100644 index 000000000000..53a7287529b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/invalid-enum.rs @@ -0,0 +1,40 @@ +#![feature(const_generics)] +#![allow(incomplete_features)] + +#[derive(PartialEq, Eq)] +enum CompileFlag { + A, + B, +} + +pub fn test_1() {} +pub fn test_2(x: T) {} +pub struct Example{ + x: T, +} + +impl Example { + const ASSOC_FLAG: CompileFlag = CompileFlag::A; +} + +pub fn main() { + test_1::(); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +// { dg-error ".E0107." "" { target *-*-* } .-3 } + + test_2::<_, CompileFlag::A>(0); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +// { dg-error ".E0107." "" { target *-*-* } .-3 } + + let _: Example = Example { x: 0 }; +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +// { dg-error ".E0107." "" { target *-*-* } .-3 } + + let _: Example = Example { x: 0 }; +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issue-61522-array-len-succ.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issue-61522-array-len-succ.rs new file mode 100644 index 000000000000..22c62aef0149 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issue-61522-array-len-succ.rs @@ -0,0 +1,20 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub struct MyArray([u8; COUNT + 1]); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +impl MyArray { + fn inner(&self) -> &[u8; COUNT + 1] { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + &self.0 + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs new file mode 100644 index 000000000000..e243b546aeb5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issue-66596-impl-trait-for-str-const-arg.rs @@ -0,0 +1,21 @@ +//[full] check-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + + +trait Trait { +// { dg-error "" "" { target *-*-* } .-1 } + type Assoc; +} + +impl Trait<"0"> for () { + type Assoc = (); +} + +fn main() { + let _: <() as Trait<"0">>::Assoc = (); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issue-67375.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issue-67375.rs new file mode 100644 index 000000000000..4de3c25ca313 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issue-67375.rs @@ -0,0 +1,16 @@ +// revisions: full min + +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Bug { +// { dg-error "" "" { target *-*-* } .-1 } + inner: [(); { [|_: &T| {}; 0].len() }], +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issue-67945-1.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issue-67945-1.rs new file mode 100644 index 000000000000..ebd6eacc66c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issue-67945-1.rs @@ -0,0 +1,24 @@ +// revisions: full min + +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +use std::marker::PhantomData; + +use std::mem::{self, MaybeUninit}; + +struct Bug { +// { dg-error "" "" { target *-*-* } .-1 } + A: [(); { + let x: S = MaybeUninit::uninit(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + let b = &*(&x as *const _ as *const S); +// { dg-error "" "" { target *-*-* } .-1 } + 0 + }], +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issue-67945-2.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issue-67945-2.rs new file mode 100644 index 000000000000..9e001556782d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issue-67945-2.rs @@ -0,0 +1,22 @@ +// revisions: full min + +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +use std::mem::MaybeUninit; + +struct Bug { +// { dg-error "" "" { target *-*-* } .-1 } + A: [(); { + let x: S = MaybeUninit::uninit(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + let b = &*(&x as *const _ as *const S); +// { dg-error "" "" { target *-*-* } .-1 } + 0 + }], +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issue-67945-3.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issue-67945-3.rs new file mode 100644 index 000000000000..d6e159c0462b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issue-67945-3.rs @@ -0,0 +1,18 @@ +// revisions: full min + +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Bug { + A: [(); { +// { dg-error "" "" { target *-*-* } .-1 } + let x: Option> = None; +// { dg-error "" "" { target *-*-* } .-1 } + 0 + }], + B: S +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issue-68104-print-stack-overflow.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issue-68104-print-stack-overflow.rs new file mode 100644 index 000000000000..9c89ce09d416 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issue-68104-print-stack-overflow.rs @@ -0,0 +1,17 @@ +// aux-build:impl-const.rs +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +extern crate impl_const; + +use impl_const::*; + +pub fn main() { + let n = Num::<5>; + n.five(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issue-70180-1-stalled_on.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issue-70180-1-stalled_on.rs new file mode 100644 index 000000000000..327ce4596b96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issue-70180-1-stalled_on.rs @@ -0,0 +1,39 @@ +// build-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub fn works() { + let array/*: [_; _]*/ = default_array(); + let _: [_; 4] = array; + Foo::foo(&array); +} + +pub fn didnt_work() { + let array/*: [_; _]*/ = default_array(); + Foo::foo(&array); + let _: [_; 4] = array; +} + +trait Foo { + fn foo(&self) {} +} + +impl Foo for [i32; 4] {} +impl Foo for [i64; 8] {} + +// Only needed because `[_; _]` is not valid type syntax. +fn default_array() -> [T; N] +where + [T; N]: Default, +{ + Default::default() +} + +fn main() { + works(); + didnt_work(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issue-70180-2-stalled_on.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issue-70180-2-stalled_on.rs new file mode 100644 index 000000000000..2d230f990580 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issue-70180-2-stalled_on.rs @@ -0,0 +1,39 @@ +// build-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn works() { + let array/*: [u8; _]*/ = default_byte_array(); + let _: [_; 4] = array; + Foo::foo(&array); +} + +fn didnt_work() { + let array/*: [u8; _]*/ = default_byte_array(); + Foo::foo(&array); + let _: [_; 4] = array; +} + +trait Foo { + fn foo(&self) {} +} + +impl Foo for [u8; 4] {} +impl Foo for [u8; 8] {} + +// Only needed because `[u8; _]` is not valid type syntax. +fn default_byte_array() -> [u8; N] +where + [u8; N]: Default, +{ + Default::default() +} + +fn main() { + works(); + didnt_work(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issue-71986.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issue-71986.rs new file mode 100644 index 000000000000..6fa326ab0f6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issue-71986.rs @@ -0,0 +1,12 @@ +// check-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub trait Foo {} +pub fn bar>() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issue-74906.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issue-74906.rs new file mode 100644 index 000000000000..d550d85ef27f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issue-74906.rs @@ -0,0 +1,26 @@ +// edition:2018 +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +const SIZE: usize = 16; + +struct Bar {} + +struct Foo {} + +impl Foo { + async fn biz(_: &[[u8; SIZE]]) -> Vec<()> { + vec![] + } + + pub async fn baz(&self) -> Bar { + Self::biz(&vec![]).await; + Bar {} + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs new file mode 100644 index 000000000000..8af20df00de3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/auxiliary/const_generic_issues_lib.rs @@ -0,0 +1,17 @@ +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +// All of these three items must be in `lib2` to reproduce the error + +pub trait TypeFn { + type Output; +} + +pub struct GenericType; + +// Removing the braces around `42` resolves the crash +impl TypeFn for GenericType<{ 42 }> { + type Output = (); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-56445.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-56445.rs new file mode 100644 index 000000000000..3a13f105c2ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-56445.rs @@ -0,0 +1,13 @@ +// Regression test for https://github.com/rust-lang/rust/issues/56445#issuecomment-518402995. +// revisions: full min +#![cfg_attr(full, feature(const_generics))] // { dg-warning "" "" { target *-*-* } } +#![cfg_attr(min, feature(min_const_generics))] +#![crate_type = "lib"] + +use std::marker::PhantomData; + +struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); +// { dg-error "" "" { target *-*-* } .-1 } + +impl Bug<'_, ""> {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-60263.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-60263.rs new file mode 100644 index 000000000000..6395d74da2b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-60263.rs @@ -0,0 +1,10 @@ +struct B; // { dg-error ".E0658." "" { target *-*-* } } + +impl B<0> { + fn bug() -> Self { + panic!() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-60818-struct-constructors.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-60818-struct-constructors.rs new file mode 100644 index 000000000000..fa9063603a7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-60818-struct-constructors.rs @@ -0,0 +1,11 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] // { dg-warning "" "" { target *-*-* } } +#![cfg_attr(min, feature(min_const_generics))] + +struct Generic; + +fn main() { + let _ = Generic::<0>; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61336-1.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61336-1.rs new file mode 100644 index 000000000000..d06e452f6bb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61336-1.rs @@ -0,0 +1,14 @@ +// build-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] // { dg-warning "" "" { target *-*-* } } +#![cfg_attr(min, feature(min_const_generics))] + +fn f(x: T) -> [T; N] { + [x; N] +} + +fn main() { + let x: [u32; 5] = f::(3); + assert_eq!(x, [3u32; 5]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61336-2.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61336-2.rs new file mode 100644 index 000000000000..2dc034bb29a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61336-2.rs @@ -0,0 +1,18 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] // { dg-warning "" "" { target *-*-* } } +#![cfg_attr(min, feature(min_const_generics))] + +fn f(x: T) -> [T; N] { + [x; { N }] +} + +fn g(x: T) -> [T; N] { + [x; { N }] +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + let x: [u32; 5] = f::(3); + assert_eq!(x, [3u32; 5]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61336.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61336.rs new file mode 100644 index 000000000000..74bb395a7463 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61336.rs @@ -0,0 +1,18 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] // { dg-warning "" "" { target *-*-* } } +#![cfg_attr(min, feature(min_const_generics))] + +fn f(x: T) -> [T; N] { + [x; N] +} + +fn g(x: T) -> [T; N] { + [x; N] +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { + let x: [u32; 5] = f::(3); + assert_eq!(x, [3u32; 5]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61422.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61422.rs new file mode 100644 index 000000000000..01d8cb61a449 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61422.rs @@ -0,0 +1,29 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] // { dg-warning "" "" { target *-*-* } } +#![cfg_attr(min, feature(min_const_generics))] + +use std::mem; + +// Neither of the uninits below are currently accepted as not UB, however, +// this code does not run and is merely checking that we do not ICE on this pattern, +// so this is fine. + +fn foo() { + let arr: [u8; SIZE] = unsafe { + #[allow(deprecated)] + let array: [u8; SIZE] = mem::uninitialized(); + array + }; +} + +fn bar() { + let arr: [u8; SIZE] = unsafe { + let array: [u8; SIZE] = mem::MaybeUninit::uninit().assume_init(); + array + }; +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61432.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61432.rs new file mode 100644 index 000000000000..168d834dc36e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61432.rs @@ -0,0 +1,18 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] // { dg-warning "" "" { target *-*-* } } +#![cfg_attr(min, feature(min_const_generics))] + +fn promote() { + // works: + // + // let n = N; + // &n; + + &N; +} + +fn main() { + promote::<0>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61747.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61747.rs new file mode 100644 index 000000000000..cbea1b251038 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61747.rs @@ -0,0 +1,18 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] // { dg-warning "" "" { target *-*-* } } +#![cfg_attr(min, feature(min_const_generics))] + +struct Const; + +impl Const<{C}> { + fn successor() -> Const<{C + 1}> { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + Const + } +} + +fn main() { + let _x: Const::<2> = Const::<1>::successor(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61935.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61935.rs new file mode 100644 index 000000000000..980c82c38b6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-61935.rs @@ -0,0 +1,27 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Foo {} + +impl Foo for [(); N] + where + Self:FooImpl<{N==0}> +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +{} + +trait FooImpl{} + +impl FooImpl for [(); 0] {} + +impl FooImpl for [();N] {} + +fn foo(_: impl Foo) {} + +fn main() { + foo([]); + foo([()]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs new file mode 100644 index 000000000000..1e785d521ffe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62187-encountered-polymorphic-const.rs @@ -0,0 +1,19 @@ +// run-pass + +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub trait BitLen: Sized { + const BIT_LEN: usize; +} + +impl BitLen for [u8; L] { + const BIT_LEN: usize = 8 * L; +} + +fn main() { + let _foo = <[u8; 2]>::BIT_LEN; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62220.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62220.rs new file mode 100644 index 000000000000..9c81c4ef0ed2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62220.rs @@ -0,0 +1,26 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub struct Vector([T; N]); + +pub type TruncatedVector = Vector; +// { dg-error "" "" { target *-*-* } .-1 } + +impl Vector { + /// Drop the last component and return the vector with one fewer dimension. + pub fn trunc(self) -> (TruncatedVector, T) { +// { dg-error "" "" { target *-*-* } .-1 } + unimplemented!() + } +} + +fn vec4(a: T, b: T, c: T, d: T) -> Vector { + Vector([a, b, c, d]) +} + +fn main() { + let (_xyz, _w): (TruncatedVector, u32) = vec4(0u32, 1, 2, 3).trunc(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62456.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62456.rs new file mode 100644 index 000000000000..3235a703454a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62456.rs @@ -0,0 +1,13 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn foo() { + let _ = [0u64; N + 1]; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62504.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62504.rs new file mode 100644 index 000000000000..44f8ad2ff85e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62504.rs @@ -0,0 +1,28 @@ +// revisions: full min +#![allow(incomplete_features)] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait HasSize { + const SIZE: usize; +} + +impl HasSize for ArrayHolder { + const SIZE: usize = X; +} + +struct ArrayHolder([u32; X]); + +impl ArrayHolder { + pub const fn new() -> Self { + ArrayHolder([0; Self::SIZE]) +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + } +} + +fn main() { + let mut array = ArrayHolder::new(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62579-no-match.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62579-no-match.rs new file mode 100644 index 000000000000..0c33a8f36540 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62579-no-match.rs @@ -0,0 +1,18 @@ +// [full] run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +#[derive(PartialEq, Eq)] +struct NoMatch; + +fn foo() -> bool { +// { dg-error "" "" { target *-*-* } .-1 } + true +} + +fn main() { + foo::<{NoMatch}>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62878.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62878.rs new file mode 100644 index 000000000000..68d47009e98b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-62878.rs @@ -0,0 +1,16 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn foo() {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { + foo::<_, {[1]}>(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-63322-forbid-dyn.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-63322-forbid-dyn.rs new file mode 100644 index 000000000000..3ce5b7188ac9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-63322-forbid-dyn.rs @@ -0,0 +1,19 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait A {} +struct B; +impl A for B {} + +fn test() { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + unimplemented!() +} + +fn main() { + test::<{ &B }>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-64494.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-64494.rs new file mode 100644 index 000000000000..786851a46c12 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-64494.rs @@ -0,0 +1,25 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Foo { + const VAL: usize; +} + +trait MyTrait {} + +trait True {} +struct Is; +impl True for Is<{true}> {} + +impl MyTrait for T where Is<{T::VAL == 5}>: True {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +impl MyTrait for T where Is<{T::VAL == 6}>: True {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-64519.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-64519.rs new file mode 100644 index 000000000000..15a1e335a08c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-64519.rs @@ -0,0 +1,23 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Foo { + state: Option<[u8; D]>, +} + +impl Iterator for Foo<{D}> { + type Item = [u8; D]; + fn next(&mut self) -> Option { + if true { + return Some(self.state.unwrap().clone()); + } else { + return Some(self.state.unwrap().clone()); + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-66205.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-66205.rs new file mode 100644 index 000000000000..6c8d48beaf62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-66205.rs @@ -0,0 +1,14 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] +#![allow(dead_code, unconditional_recursion)] + +fn fact() { + fact::<{ N - 1 }>(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-66906.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-66906.rs new file mode 100644 index 000000000000..0186cd9c6e41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-66906.rs @@ -0,0 +1,14 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub struct Tuple; + +pub trait Trait { + type Input: From<>::Input>; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-67185-1.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-67185-1.rs new file mode 100644 index 000000000000..3966dc5cadc6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-67185-1.rs @@ -0,0 +1,34 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Baz { + type Quaks; +} +impl Baz for u8 { + type Quaks = [u16; 3]; +} + +trait Bar {} +impl Bar for [u16; 3] {} +impl Bar for [[u16; 3]; 2] {} + +trait Foo + where + [::Quaks; 2]: Bar, + ::Quaks: Bar, +{ +} + +struct FooImpl; + +impl Foo for FooImpl {} + +fn f(_: impl Foo) {} + +fn main() { + f(FooImpl) +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-67185-2.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-67185-2.rs new file mode 100644 index 000000000000..85374970769e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-67185-2.rs @@ -0,0 +1,38 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Baz { + type Quaks; +} +impl Baz for u8 { + type Quaks = [u16; 3]; +} + +trait Bar {} +impl Bar for [u16; 4] {} +impl Bar for [[u16; 3]; 3] {} + +trait Foo // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + where + [::Quaks; 2]: Bar, + ::Quaks: Bar, +{ +} + +struct FooImpl; + +impl Foo for FooImpl {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn f(_: impl Foo) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { + f(FooImpl) +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-67739.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-67739.rs new file mode 100644 index 000000000000..e74955d94302 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-67739.rs @@ -0,0 +1,19 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +use std::mem; + +pub trait Trait { + type Associated: Sized; + + fn associated_size(&self) -> usize { + [0u8; mem::size_of::()]; +// { dg-error "" "" { target *-*-* } .-1 } + 0 + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68366.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68366.rs new file mode 100644 index 000000000000..fcd5fe4d1e78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68366.rs @@ -0,0 +1,22 @@ +// Checks that const expressions have a useful note explaining why they can't be evaluated. +// The note should relate to the fact that it cannot be shown forall N that it maps 1-1 to a new +// type. + +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Collatz>; + +impl Collatz<{Some(N)}> {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +struct Foo; + +impl Foo {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68596.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68596.rs new file mode 100644 index 000000000000..98efaee9cf3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68596.rs @@ -0,0 +1,21 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub struct S(u8); + +impl S { + pub fn get(&self) -> &u8 { + &self.0 + } +} + +fn main() { + const A: u8 = 5; + let s = S(0); + + s.get::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68615-adt.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68615-adt.rs new file mode 100644 index 000000000000..7f45cc031b58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68615-adt.rs @@ -0,0 +1,15 @@ +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Const {} +// { dg-error "" "" { target *-*-* } .-1 } +type MyConst = Const<{ [] }>; + +fn main() { + let _x = Const::<{ [] }> {}; + let _y = MyConst {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68615-array.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68615-array.rs new file mode 100644 index 000000000000..6210dbc41400 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68615-array.rs @@ -0,0 +1,15 @@ +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Foo {} +// { dg-error "" "" { target *-*-* } .-1 } + +type MyFoo = Foo<{ [] }>; + +fn main() { + let _ = Foo::<{ [] }> {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68977.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68977.rs new file mode 100644 index 000000000000..ee2ea8b47d5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-68977.rs @@ -0,0 +1,45 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct PhantomU8; + +trait FxpStorage { + type SInt; // Add arithmetic traits as needed. +} + +macro_rules! fxp_storage_impls { + ($($($n:literal)|+ => $sint:ty),* $(,)?) => { + $($(impl FxpStorage for PhantomU8<$n> { + type SInt = $sint; + })*)* + } +} + +fxp_storage_impls! { + 1 => i8, + 2 => i16, + 3 | 4 => i32, + 5 | 6 | 7 | 8 => i64, + 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 => i128, +} + +type FxpStorageHelper = + PhantomU8<{(INT_BITS + FRAC_BITS + 7) / 8}>; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +struct Fxp +where + FxpStorageHelper: FxpStorage, +// { dg-error "" "" { target *-*-* } .-1 } +{ + storage: as FxpStorage>::SInt, +} + +fn main() { + Fxp::<1, 15> { storage: 0i16 }; + Fxp::<2, 15> { storage: 0i32 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-69654-run-pass.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-69654-run-pass.rs new file mode 100644 index 000000000000..18b47a65aa9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-69654-run-pass.rs @@ -0,0 +1,19 @@ +// run-pass +#![feature(const_generics)] +#![allow(incomplete_features, unused_braces)] + +trait Bar {} +impl Bar for [u8; {7}] {} + +struct Foo {} +impl Foo +where + [u8; N]: Bar<[(); N]>, +{ + fn foo() {} +} + +fn main() { + Foo::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-69654.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-69654.rs new file mode 100644 index 000000000000..7509d44785d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-69654.rs @@ -0,0 +1,19 @@ +#![feature(const_generics)] +#![allow(incomplete_features)] + +trait Bar {} +impl Bar for [u8; T] {} +// { dg-error ".E0423." "" { target *-*-* } .-1 } + +struct Foo {} +impl Foo +where + [u8; N]: Bar<[(); N]>, +{ + fn foo() {} +} + +fn main() { + Foo::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70125-1.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70125-1.rs new file mode 100644 index 000000000000..23b720c53eb7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70125-1.rs @@ -0,0 +1,22 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +const L: usize = 4; + +pub trait Print { + fn print(&self) -> usize { + N + } +} + +pub struct Printer; +impl Print for Printer {} + +fn main() { + let p = Printer; + assert_eq!(p.print(), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70125-2.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70125-2.rs new file mode 100644 index 000000000000..f5166c0d24ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70125-2.rs @@ -0,0 +1,18 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn main() { + <()>::foo(); +} + +trait Foo { + fn foo() -> usize { + X + } +} + +impl Foo<3> for () {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70167.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70167.rs new file mode 100644 index 000000000000..8ae4cb8b106e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70167.rs @@ -0,0 +1,12 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub trait Trait: From<>::Item> { + type Item; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70225.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70225.rs new file mode 100644 index 000000000000..e09d2b667c62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-70225.rs @@ -0,0 +1,22 @@ +// check-pass +#![feature(const_generics)] +#![allow(incomplete_features)] +#![deny(dead_code)] + +// We previously incorrectly linted `L` as unused here. +const L: usize = 3; + +fn main() { + let p = Printer {}; + p.print(); +} + +trait Print { + fn print(&self) -> usize { + 3 + } +} + +struct Printer {} +impl Print for Printer {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71169.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71169.rs new file mode 100644 index 000000000000..fdaf4f65e357 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71169.rs @@ -0,0 +1,14 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn foo() {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +fn main() { + const DATA: [u8; 4] = *b"ABCD"; + foo::<4, DATA>(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71381.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71381.rs new file mode 100644 index 000000000000..c3c745437719 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71381.rs @@ -0,0 +1,38 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Test(*const usize); + +type PassArg = (); + +unsafe extern "C" fn pass(args: PassArg) { + println!("Hello, world!"); +} + +impl Test { + pub fn call_me(&self) { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + self.0 = Self::trampiline:: as _ + } + + unsafe extern "C" fn trampiline< + Args: Sized, + const IDX: usize, + const FN: unsafe extern "C" fn(Args), +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + >( + args: Args, + ) { + FN(args) + } +} + +fn main() { + let x = Test(); + x.call_me::() +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71382.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71382.rs new file mode 100644 index 000000000000..6f2d5ad6c3e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71382.rs @@ -0,0 +1,27 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Test(); + +fn pass() { + println!("Hello, world!"); +} + +impl Test { + pub fn call_me(&self) { + self.test::(); + } + + fn test(&self) { +// { dg-error "" "" { target *-*-* } .-1 } + FN(); + } +} + +fn main() { + let x = Test(); + x.call_me() +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71611.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71611.rs new file mode 100644 index 000000000000..2be1363d669e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-71611.rs @@ -0,0 +1,13 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn func(outer: A) { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + F(outer); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-72352.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-72352.rs new file mode 100644 index 000000000000..58ae8a882869 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-72352.rs @@ -0,0 +1,24 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +use std::ffi::{CStr, CString}; + +unsafe fn unsafely_do_the_thing usize>(ptr: *const i8) -> usize { +// { dg-error "" "" { target *-*-* } .-1 } + F(CStr::from_ptr(ptr)) +} + +fn safely_do_the_thing(s: &CStr) -> usize { + s.to_bytes().len() +} + +fn main() { + let baguette = CString::new("baguette").unwrap(); + let ptr = baguette.as_ptr(); + println!("{}", unsafe { + unsafely_do_the_thing::(ptr) + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-72787.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-72787.rs new file mode 100644 index 000000000000..838187405c01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-72787.rs @@ -0,0 +1,41 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub struct IsLessOrEqual; +pub struct Condition; +pub trait True {} + +impl True for IsLessOrEqual where + Condition<{ LHS <= RHS }>: True +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-2 } +{ +} +impl True for Condition {} + +struct S; +impl S +where + IsLessOrEqual: True, +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + IsLessOrEqual: True, + IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-error "" "" { target *-*-* } .-2 } + // Condition<{ 8 - I <= 8 - J }>: True, +{ + fn print() { + println!("I {} J {}", I, J); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs new file mode 100644 index 000000000000..4c0462654e0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-72819-generic-in-const-eval.rs @@ -0,0 +1,24 @@ +// Regression test for #72819: ICE due to failure in resolving the const generic in `Arr`'s type +// bounds. +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Arr +where Assert::<{N < usize::max_value() / 2}>: IsTrue, +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +{ +} + +enum Assert {} + +trait IsTrue {} + +impl IsTrue for Assert {} + +fn main() { + let x: Arr<{usize::max_value()}> = Arr {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73120.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73120.rs new file mode 100644 index 000000000000..f3c6de3466d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73120.rs @@ -0,0 +1,10 @@ +// revisions: full min +// check-pass +// aux-build:const_generic_issues_lib.rs +extern crate const_generic_issues_lib as lib2; +fn unused_function( + _: as lib2::TypeFn>::Output +) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73260.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73260.rs new file mode 100644 index 000000000000..d082a0b2d737 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73260.rs @@ -0,0 +1,21 @@ +// compile-flags: -Zsave-analysis + +#![feature(const_generics)] +#![allow(incomplete_features)] +struct Arr +where Assert::<{N < usize::max_value() / 2}>: IsTrue, // { dg-error "" "" { target *-*-* } } +{ +} + +enum Assert {} + +trait IsTrue {} + +impl IsTrue for Assert {} + +fn main() { + let x: Arr<{usize::max_value()}> = Arr {}; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73491.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73491.rs new file mode 100644 index 000000000000..0b55ae74ee1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73491.rs @@ -0,0 +1,13 @@ +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +const LEN: usize = 1024; + +fn hoge() {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73508.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73508.rs new file mode 100644 index 000000000000..e6761f760557 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-73508.rs @@ -0,0 +1,10 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub const fn func_name() {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74101.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74101.rs new file mode 100644 index 000000000000..c7d44929a05c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74101.rs @@ -0,0 +1,14 @@ +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn test() {} +// { dg-error "" "" { target *-*-* } .-1 } + +struct Foo; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74255.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74255.rs new file mode 100644 index 000000000000..9d3fe7c1c879 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74255.rs @@ -0,0 +1,22 @@ +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +#[derive(PartialEq, Eq)] +enum IceEnum { + Variant +} + +struct IceStruct; + +impl IceStruct { + fn ice_struct_fn() {} +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + IceStruct::ice_struct_fn::<{IceEnum::Variant}>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74634.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74634.rs new file mode 100644 index 000000000000..0ef7cd5d07c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74634.rs @@ -0,0 +1,28 @@ +#![feature(const_generics)] +#![allow(incomplete_features)] + +trait If {} +impl If for () {} + +trait IsZero { + type Answer; +} + +struct True; +struct False; + +impl IsZero for () +where (): If<{N == 0}> { // { dg-error "" "" { target *-*-* } } + type Answer = True; +} + +trait Foobar {} + +impl Foobar for () +where (): IsZero {} + +impl Foobar for () +where (): IsZero {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74950.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74950.rs new file mode 100644 index 000000000000..977838190724 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-74950.rs @@ -0,0 +1,26 @@ +// [full] build-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + + +#[derive(PartialEq, Eq)] +struct Inner; + +// Note: We emit the error 5 times if we don't deduplicate: +// - struct definition +// - impl PartialEq +// - impl Eq +// - impl StructuralPartialEq +// - impl StructuralEq +#[derive(PartialEq, Eq)] +struct Outer; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-75047.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-75047.rs new file mode 100644 index 000000000000..737ce30bdb4d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-75047.rs @@ -0,0 +1,19 @@ +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Bar(T); + +impl Bar { + const fn value() -> usize { + 42 + } +} + +struct Foo::value()]>; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-75299.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-75299.rs new file mode 100644 index 000000000000..abc521a0b57b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-75299.rs @@ -0,0 +1,12 @@ +// compile-flags: -Zmir-opt-level=3 +// run-pass + +#![feature(const_generics)] +#![allow(incomplete_features)] +fn main() { + fn foo() -> [u8; N] { + [0; N] + } + let _x = foo::<1>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-76595.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-76595.rs new file mode 100644 index 000000000000..2cecf706a3f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-76595.rs @@ -0,0 +1,18 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +struct Bool; + +trait True {} + +impl True for Bool {} + +fn test() where Bool<{core::mem::size_of::() > 4}>: True { + todo!() +} + +fn main() { + test::<2>(); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-76701-ty-param-in-const.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-76701-ty-param-in-const.rs new file mode 100644 index 000000000000..82cb810de903 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue-76701-ty-param-in-const.rs @@ -0,0 +1,19 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn ty_param() -> [u8; std::mem::size_of::()] { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + todo!() +} + +fn const_param() -> [u8; N + 1] { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + todo!() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue70273-assoc-fn.rs b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue70273-assoc-fn.rs new file mode 100644 index 000000000000..84ccd0feed15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/issues/issue70273-assoc-fn.rs @@ -0,0 +1,19 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait T { + fn f(); +} +struct S; + +impl T<0usize> for S { + fn f() {} +} + +fn main() { + let _err = >::f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/macro_rules-braces.rs b/gcc/testsuite/rust/rustc/ui/const-generics/macro_rules-braces.rs new file mode 100644 index 000000000000..510f116d206e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/macro_rules-braces.rs @@ -0,0 +1,44 @@ +// revisions: full min +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] + +fn test() { + struct Foo; + macro_rules! foo { + ($x:expr) => { + [u8; $x] // { dg-error "" "" { target *-*-* } } + } + } + macro_rules! bar { + ($x:expr) => { + [u8; { $x }] // { dg-error "" "" { target *-*-* } } + } + } + macro_rules! baz { + ( $x:expr) => { + Foo<$x> // { dg-error "" "" { target *-*-* } } + } + } + macro_rules! biz { + ($x:expr) => { + Foo<{ $x }> // { dg-error "" "" { target *-*-* } } + }; + } + + let _: foo!(N); + let _: foo!({ N }); + let _: foo!({{ N }}); // { dg-error "" "" { target *-*-* } } + let _: bar!(N); + let _: bar!({ N }); // { dg-error "" "" { target *-*-* } } + let _: baz!(N); // { dg-error "" "" { target *-*-* } } + let _: baz!({ N }); + let _: baz!({{ N }}); // { dg-error "" "" { target *-*-* } } + let _: biz!(N); + let _: biz!({ N }); // { dg-error "" "" { target *-*-* } } +} + +fn main() { + test::<3>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min-and-full-same-time.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min-and-full-same-time.rs new file mode 100644 index 000000000000..6428ea39041f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min-and-full-same-time.rs @@ -0,0 +1,8 @@ +#![feature(const_generics)] +// { dg-error "" "" { target *-*-* } .-1 } +#![allow(incomplete_features)] +#![feature(min_const_generics)] + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/assoc_const.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/assoc_const.rs new file mode 100644 index 000000000000..76c8be886b20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/assoc_const.rs @@ -0,0 +1,19 @@ +// check-pass +#![feature(min_const_generics)] + +struct Foo; + +impl Foo { + const VALUE: usize = N * 2; +} + +trait Bar { + const ASSOC: usize; +} + +impl Bar for Foo { + const ASSOC: usize = N * 3; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/complex-expression.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/complex-expression.rs new file mode 100644 index 000000000000..dce1768ceb6a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/complex-expression.rs @@ -0,0 +1,50 @@ +#![feature(min_const_generics)] + +use std::mem::size_of; + +fn test() {} + +fn ok() -> [u8; M] { + [0; { M }] +} + +struct Break0([u8; { N + 1 }]); +// { dg-error "" "" { target *-*-* } .-1 } + +struct Break1([u8; { { N } }]); +// { dg-error "" "" { target *-*-* } .-1 } + +fn break2() { + let _: [u8; N + 1]; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn break3() { + let _ = [0; N + 1]; +// { dg-error "" "" { target *-*-* } .-1 } +} + +struct BreakTy0(T, [u8; { size_of::<*mut T>() }]); +// { dg-error "" "" { target *-*-* } .-1 } + +struct BreakTy1(T, [u8; { { size_of::<*mut T>() } }]); +// { dg-error "" "" { target *-*-* } .-1 } + +fn break_ty2() { + let _: [u8; size_of::<*mut T>() + 1]; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn break_ty3() { + let _ = [0; size_of::<*mut T>() + 1]; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + + +trait Foo { + const ASSOC: usize; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/complex-types.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/complex-types.rs new file mode 100644 index 000000000000..aa03e25621af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/complex-types.rs @@ -0,0 +1,29 @@ +#![feature(min_const_generics)] +#![feature(never_type)] + +struct Foo; +// { dg-error "" "" { target *-*-* } .-1 } + +struct Bar; +// { dg-error "" "" { target *-*-* } .-1 } +#[derive(PartialEq, Eq)] +struct No; + +struct Fez; +// { dg-error "" "" { target *-*-* } .-1 } + +struct Faz; +// { dg-error "" "" { target *-*-* } .-1 } + +struct Fiz; +// { dg-error "" "" { target *-*-* } .-1 } + +enum Goo { A, B } +// { dg-error "" "" { target *-*-* } .-1 } + +union Boo { a: () } +// { dg-error "" "" { target *-*-* } .-1 } + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs new file mode 100644 index 000000000000..71386cc6d533 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs @@ -0,0 +1,36 @@ +// check-pass +#![feature(min_const_generics)] +#![allow(dead_code)] + +fn foo() { + [0; std::mem::size_of::<*mut T>()]; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +struct Foo(T); + +impl Foo { + const ASSOC: usize = 4; + + fn test() { + let _ = [0; Self::ASSOC]; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + } +} + +struct Bar; + +impl Bar { + const ASSOC: usize = 4; + + fn test() { + let _ = [0; Self::ASSOC]; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs new file mode 100644 index 000000000000..e074ef24646f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces-without-turbofish.rs @@ -0,0 +1,50 @@ +#![feature(min_const_generics)] + +fn foo() {} + +const BAR: usize = 42; + +fn a() { + foo(); // { dg-error "" "" { target *-*-* } } +} +fn b() { + foo(); // { dg-error "" "" { target *-*-* } } +} +fn c() { + foo<3 + 3>(); // { dg-error "" "" { target *-*-* } } +} +fn d() { + foo(); // { dg-error "" "" { target *-*-* } } +} +fn e() { + foo(); // { dg-error "" "" { target *-*-* } } +} +fn f() { + foo<100 - BAR>(); // { dg-error "" "" { target *-*-* } } +} +fn g() { + foo()>(); // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} +fn h() { + foo()>(); // { dg-error "" "" { target *-*-* } } +} +fn i() { + foo() + BAR>(); // { dg-error "" "" { target *-*-* } } +} +fn j() { + foo() - BAR>(); // { dg-error "" "" { target *-*-* } } +} +fn k() { + foo()>(); // { dg-error "" "" { target *-*-* } } +} +fn l() { + foo()>(); // { dg-error "" "" { target *-*-* } } +} + +const fn bar() -> usize { + C +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs new file mode 100644 index 000000000000..2833c4401e84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const-expression-suggest-missing-braces.rs @@ -0,0 +1,56 @@ +#![feature(min_const_generics)] + +fn foo() {} + +const BAR: usize = 42; + +fn a() { + foo::(); // { dg-error "" "" { target *-*-* } } +} +fn b() { + // FIXME(const_generics): these diagnostics are awful, because trait objects without `dyn` were + // a terrible mistake. + foo::(); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +// { dg-error ".E0107." "" { target *-*-* } .-3 } +// { dg-error ".E0107." "" { target *-*-* } .-4 } +// { dg-warning ".E0107." "" { target *-*-* } .-5 } +} +fn c() { + foo::<3 + 3>(); // { dg-error "" "" { target *-*-* } } +} +fn d() { + foo::(); // { dg-error "" "" { target *-*-* } } +} +fn e() { + foo::(); // { dg-error "" "" { target *-*-* } } +} +fn f() { + foo::<100 - BAR>(); // { dg-error "" "" { target *-*-* } } +} +fn g() { + foo::()>(); // { dg-error "" "" { target *-*-* } } +} +fn h() { + foo::()>(); // { dg-error "" "" { target *-*-* } } +} +fn i() { + foo::() + BAR>(); // { dg-error "" "" { target *-*-* } } +} +fn j() { + foo::() - BAR>(); // { dg-error "" "" { target *-*-* } } +} +fn k() { + foo::()>(); // { dg-error "" "" { target *-*-* } } +} +fn l() { + foo::()>(); // { dg-error "" "" { target *-*-* } } +} + +const fn bar() -> usize { + C +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const_fn_in_generics.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const_fn_in_generics.rs new file mode 100644 index 000000000000..4e6bf49ae8da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/const_fn_in_generics.rs @@ -0,0 +1,18 @@ +// run-pass + +#![feature(min_const_generics)] + +const fn identity() -> u32 { T } + +#[derive(Eq, PartialEq, Debug)] +pub struct ConstU32; + +pub fn new() -> ConstU32<{ identity::<3>() }> { + ConstU32::<{ identity::<3>() }> +} + +fn main() { + let v = new(); + assert_eq!(v, ConstU32::<3>); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/default_function_param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/default_function_param.rs new file mode 100644 index 000000000000..d84ca96e6245 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/default_function_param.rs @@ -0,0 +1,7 @@ +#![feature(min_const_generics)] + +fn foo() {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/default_trait_param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/default_trait_param.rs new file mode 100644 index 000000000000..35672ecd9f15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/default_trait_param.rs @@ -0,0 +1,7 @@ +#![feature(min_const_generics)] + +trait Foo {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/feature-gate-min_const_generics.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/feature-gate-min_const_generics.rs new file mode 100644 index 000000000000..91dd38c65955 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/feature-gate-min_const_generics.rs @@ -0,0 +1,5 @@ +fn test() {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs new file mode 100644 index 000000000000..6a4abf4e6af3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/forbid-non-static-lifetimes.rs @@ -0,0 +1,28 @@ +#![feature(min_const_generics)] + +// This test checks that non-static lifetimes are prohibited under `min_const_generics`. It +// currently emits an error with `min_const_generics`. This will ICE under `const_generics`. + +fn test() {} + +fn issue_75323_and_74447_1<'a>() -> &'a () { + test::<{ let _: &'a (); 3 },>(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + &() +} + +fn issue_75323_and_74447_2() { + test::<{ let _: &(); 3 },>(); +} + +fn issue_75323_and_74447_3() { + test::<{ let _: &'static (); 3 },>(); +} + +fn issue_73375<'a>() { + [(); (|_: &'a u8| (), 0).1]; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/invalid-patterns.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/invalid-patterns.rs new file mode 100644 index 000000000000..6fbc77490619 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/invalid-patterns.rs @@ -0,0 +1,46 @@ +#![feature(min_const_generics)] +use std::mem::transmute; + +fn get_flag() -> Option { + if FlagSet { + Some(ShortName) + } else { + None + } +} + +union CharRaw { + byte: u8, + character: char, +} + +union BoolRaw { + byte: u8, + boolean: bool, +} + +const char_raw: CharRaw = CharRaw { byte: 0xFF }; +const bool_raw: BoolRaw = BoolRaw { byte: 0x42 }; + +fn main() { + // Test that basic cases don't work + assert!(get_flag::().is_some()); + assert!(get_flag::().is_none()); + get_flag::(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + get_flag::<7, 'c'>(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + get_flag::<42, 0x5ad>(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + + get_flag::(); +// { dg-error ".E0080." "" { target *-*-* } .-1 } + get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>(); +// { dg-error ".E0080." "" { target *-*-* } .-1 } + get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>(); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/macro-fail.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/macro-fail.rs new file mode 100644 index 000000000000..41ca6a111029 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/macro-fail.rs @@ -0,0 +1,49 @@ +#![feature(min_const_generics)] + +struct Example; + +macro_rules! external_macro { + () => {{ +// { dg-error "" "" { target *-*-* } .-1 } + const X: usize = 1337; + X + }} +} + +trait Marker {} +impl Marker for Example {} + +fn make_marker() -> impl Marker { +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } + Example:: +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +} + +fn from_marker(_: impl Marker<{ + #[macro_export] + macro_rules! inline { () => {{ 3 }} }; inline!() +}>) {} + +fn main() { + let _ok = Example::<{ + #[macro_export] + macro_rules! gimme_a_const { + ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + }; + gimme_a_const!(run) + }>; + + let _fail = Example::; +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } + + let _fail = Example::; +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +// { dg-error ".E0107." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/macro.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/macro.rs new file mode 100644 index 000000000000..9f3cd440eae2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/macro.rs @@ -0,0 +1,58 @@ +// run-pass +#![feature(min_const_generics)] + +struct Example; + +macro_rules! external_macro { + () => {{ + const X: usize = 1337; + X + }} +} + +trait Marker {} +impl Marker for Example {} + +fn make_marker() -> impl Marker<{ + #[macro_export] + macro_rules! const_macro { () => {{ 3 }} }; inline!() +}> { + Example::<{ const_macro!() }> +} + +fn from_marker(_: impl Marker<{ + #[macro_export] + macro_rules! inline { () => {{ 3 }} }; inline!() +}>) {} + +fn main() { + let _ok = Example::<{ + #[macro_export] + macro_rules! gimme_a_const { + ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} + }; + gimme_a_const!(run) + }>; + + let _ok = Example::<{ external_macro!() }>; + + let _ok: [_; gimme_a_const!(blah)] = [0,0,0]; + let _ok: [[u8; gimme_a_const!(blah)]; gimme_a_const!(blah)]; + let _ok: [u8; gimme_a_const!(blah)]; + + let _ok: [u8; { + #[macro_export] + macro_rules! const_two { () => {{ 2 }} }; + const_two!() + }]; + + let _ok = [0; { + #[macro_export] + macro_rules! const_three { () => {{ 3 }} }; + const_three!() + }]; + let _ok = [0; const_three!()]; + + from_marker(make_marker()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/self-ty-in-const-1.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/self-ty-in-const-1.rs new file mode 100644 index 000000000000..08129f036d6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/self-ty-in-const-1.rs @@ -0,0 +1,28 @@ +#![feature(min_const_generics)] + +trait Foo { + fn t1() -> [u8; std::mem::size_of::()]; // { dg-error "" "" { target *-*-* } } +} + +struct Bar(T); + +impl Bar { + fn t2() -> [u8; std::mem::size_of::()] { todo!() } // ok +} + +impl Bar { + fn t3() -> [u8; std::mem::size_of::()] {} // { dg-error "" "" { target *-*-* } } +} + +trait Baz { + fn hey(); +} + +impl Baz for u16 { + fn hey() { + let _: [u8; std::mem::size_of::()]; // ok + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/self-ty-in-const-2.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/self-ty-in-const-2.rs new file mode 100644 index 000000000000..73f2e4bf76e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/self-ty-in-const-2.rs @@ -0,0 +1,22 @@ +#![feature(min_const_generics)] + +struct Bar(T); + +trait Baz { + fn hey(); +} + +impl Baz for u16 { + fn hey() { + let _: [u8; std::mem::size_of::()]; // ok + } +} + +impl Baz for Bar { + fn hey() { + let _: [u8; std::mem::size_of::()]; // { dg-error "" "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/static-reference-array-const-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/static-reference-array-const-param.rs new file mode 100644 index 000000000000..9287350c09ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/static-reference-array-const-param.rs @@ -0,0 +1,9 @@ +#![feature(min_const_generics)] + +fn a() {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + a::<{&[]}>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs new file mode 100644 index 000000000000..1f56e67c9418 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/min_const_generics/transmute-const-param-static-reference.rs @@ -0,0 +1,13 @@ +#![feature(min_const_generics)] + +struct Const; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + const A: &'static () = unsafe { + std::mem::transmute(10 as *const ()) + }; + + let _ = Const::<{A}>; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/mut-ref-const-param-array.rs b/gcc/testsuite/rust/rustc/ui/const-generics/mut-ref-const-param-array.rs new file mode 100644 index 000000000000..f0091bbf55bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/mut-ref-const-param-array.rs @@ -0,0 +1,23 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + + +use std::ops::AddAssign; + +fn inc(v: &mut [T; N]) -> &mut [T; N] { + for x in v.iter_mut() { + *x += x.clone(); + } + v +} + +fn main() { + let mut v = [1, 2, 3]; + inc(&mut v); + assert_eq!(v, [2, 4, 6]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/nested-type.rs b/gcc/testsuite/rust/rustc/ui/const-generics/nested-type.rs new file mode 100644 index 000000000000..3ca322c8c2b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/nested-type.rs @@ -0,0 +1,22 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Foo; + + impl Foo { + fn value() -> usize { + N + } + } + + Foo::<17>::value() +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +}]>; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/bind-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/bind-param.rs new file mode 100644 index 000000000000..6701c19ee01d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/bind-param.rs @@ -0,0 +1,18 @@ +// build-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +// This test does not use any "unevaluated" consts, so it should compile just fine. + +fn bind(value: [u8; N]) -> [u8; N] { + todo!() +} + +fn sink(_: [u8; 5]) {} + +fn main() { + let mut arr = Default::default(); + arr = bind(arr); + sink(arr); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unify-fixpoint.rs b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unify-fixpoint.rs new file mode 100644 index 000000000000..dad8b3464cf4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unify-fixpoint.rs @@ -0,0 +1,19 @@ +#![feature(const_generics)] // { dg-warning "" "" { target *-*-* } } + +// It depends on how we normalize constants and how const equate works if this +// compiles. +// +// Please ping @lcnr if the output if this test changes. + + +fn bind(value: [u8; N + 2]) -> [u8; N * 2] { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + todo!() +} + +fn main() { + let mut arr = Default::default(); + arr = bind::<2>(arr); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unify-n-nplusone.rs b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unify-n-nplusone.rs new file mode 100644 index 000000000000..d7ef2a0d7006 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unify-n-nplusone.rs @@ -0,0 +1,18 @@ +#![feature(const_generics)] +#![allow(incomplete_features)] + +// This test would try to unify `N` with `N + 1` which must fail the occurs check. + +fn bind(value: [u8; N]) -> [u8; N + 1] { +// { dg-error "" "" { target *-*-* } .-1 } + todo!() +} + +fn sink(_: [u8; 5]) {} + +fn main() { + let mut arr = Default::default(); + arr = bind(arr); + sink(arr); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-1.rs b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-1.rs new file mode 100644 index 000000000000..14a2f4fc9aef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-1.rs @@ -0,0 +1,15 @@ +// build-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +trait Bar {} +impl Bar for A<{ 6 + 1 }> {} + +struct A +where + A: Bar; + +fn main() { + let _ = A; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-2.rs b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-2.rs new file mode 100644 index 000000000000..8b3e7d51a259 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-2.rs @@ -0,0 +1,28 @@ +// check-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +// The goal is is to get an unevaluated const `ct` with a `Ty::Infer(TyVar(_#1t)` subst. +// +// If we are then able to infer `ty::Infer(TyVar(_#1t) := Ty` we introduced an +// artificial inference cycle. +struct Foo; + +trait Bind { + fn bind() -> (T, Self); +} + +// `N` has to be `ConstKind::Unevaluated`. +impl Bind for Foo<{ 6 + 1 }> { + fn bind() -> (T, Self) { + (panic!(), Foo) + } +} + +fn main() { + let (mut t, foo) = Foo::bind(); + // `t` is `ty::Infer(TyVar(_#1t))` + // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs + t = foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-3.rs b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-3.rs new file mode 100644 index 000000000000..9af3a7612615 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-3.rs @@ -0,0 +1,19 @@ +// check-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +// The goal is is to get an unevaluated const `ct` with a `Ty::Infer(TyVar(_#1t)` subst. +// +// If we are then able to infer `ty::Infer(TyVar(_#1t) := Ty` we introduced an +// artificial inference cycle. +fn bind() -> (T, [u8; 6 + 1]) { + todo!() +} + +fn main() { + let (mut t, foo) = bind(); + // `t` is `ty::Infer(TyVar(_#1t))` + // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs + t = foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-4.rs b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-4.rs new file mode 100644 index 000000000000..bd5bae945e93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/occurs-check/unused-substs-4.rs @@ -0,0 +1,13 @@ +// build-pass +#![feature(const_generics)] +#![allow(incomplete_features)] + +fn bind(value: [u8; N]) -> [u8; 3 + 4] { + todo!() +} + +fn main() { + let mut arr = Default::default(); + arr = bind(arr); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs b/gcc/testsuite/rust/rustc/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs new file mode 100644 index 000000000000..9a0657e680f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/params-in-ct-in-ty-param-lazy-norm.rs @@ -0,0 +1,17 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Foo()]>(T, U); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +// FIXME(const_generics:defaults): We still don't know how to we deal with type defaults. +struct Bar(T); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/raw-ptr-const-param-deref.rs b/gcc/testsuite/rust/rustc/ui/const-generics/raw-ptr-const-param-deref.rs new file mode 100644 index 000000000000..00a330695981 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/raw-ptr-const-param-deref.rs @@ -0,0 +1,23 @@ +// Checks that pointers must not be used as the type of const params. +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +const A: u32 = 3; + +struct Const; // { dg-error "" "" { target *-*-* } } + +impl Const

{ // { dg-error "" "" { target *-*-* } } + fn get() -> u32 { + unsafe { + *P + } + } +} + +fn main() { + assert_eq!(Const::<{&A as *const _}>::get(), 3) +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/raw-ptr-const-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/raw-ptr-const-param.rs new file mode 100644 index 000000000000..e4a3715ec1d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/raw-ptr-const-param.rs @@ -0,0 +1,13 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Const; // { dg-error "" "" { target *-*-* } } + +fn main() { + let _: Const<{ 15 as *const _ }> = Const::<{ 10 as *const _ }>; + let _: Const<{ 10 as *const _ }> = Const::<{ 10 as *const _ }>; +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/slice-const-param-mismatch.rs b/gcc/testsuite/rust/rustc/ui/const-generics/slice-const-param-mismatch.rs new file mode 100644 index 000000000000..f443842e9385 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/slice-const-param-mismatch.rs @@ -0,0 +1,21 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + + +struct ConstString; +// { dg-error "" "" { target *-*-* } .-1 } +struct ConstBytes; +// { dg-error "" "" { target *-*-* } .-1 } + +pub fn main() { + let _: ConstString<"Hello"> = ConstString::<"Hello">; + let _: ConstString<"Hello"> = ConstString::<"World">; // { dg-error "" "" { target *-*-* } } + let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↦">; + let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">; // { dg-error "" "" { target *-*-* } } + let _: ConstBytes = ConstBytes::<{&[0x41, 0x41, 0x41]}>; + let _: ConstBytes = ConstBytes::; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/slice-const-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/slice-const-param.rs new file mode 100644 index 000000000000..dcdae21f29ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/slice-const-param.rs @@ -0,0 +1,24 @@ +//[full] run-pass +// revisions: min full + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub fn function_with_str() -> &'static str { +// { dg-error "" "" { target *-*-* } .-1 } + STRING +} + +pub fn function_with_bytes() -> &'static [u8] { +// { dg-error "" "" { target *-*-* } .-1 } + BYTES +} + +pub fn main() { + assert_eq!(function_with_str::<"Rust">(), "Rust"); + assert_eq!(function_with_str::<"ℇ㇈↦">(), "ℇ㇈↦"); + assert_eq!(function_with_bytes::(), &[0x41, 0x41, 0x41, 0x41]); + assert_eq!(function_with_bytes::<{&[0x41, 0x41, 0x41, 0x41]}>(), b"AAAA"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/std/const-generics-range.rs b/gcc/testsuite/rust/rustc/ui/const-generics/std/const-generics-range.rs new file mode 100644 index 000000000000..2f7576956b02 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/std/const-generics-range.rs @@ -0,0 +1,39 @@ +// [full] check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +// `Range` should be usable within const generics: +struct _Range>; +// { dg-error "" "" { target *-*-* } .-1 } +const RANGE : _Range<{ 0 .. 1000 }> = _Range; + +// `RangeFrom` should be usable within const generics: +struct _RangeFrom>; +// { dg-error "" "" { target *-*-* } .-1 } +const RANGE_FROM : _RangeFrom<{ 0 .. }> = _RangeFrom; + +// `RangeFull` should be usable within const generics: +struct _RangeFull; +// { dg-error "" "" { target *-*-* } .-1 } +const RANGE_FULL : _RangeFull<{ .. }> = _RangeFull; + +// Regression test for #70155 +// `RangeInclusive` should be usable within const generics: +struct _RangeInclusive>; +// { dg-error "" "" { target *-*-* } .-1 } +const RANGE_INCLUSIVE : _RangeInclusive<{ 0 ..= 999 }> = _RangeInclusive; + +// `RangeTo` should be usable within const generics: +struct _RangeTo>; +// { dg-error "" "" { target *-*-* } .-1 } +const RANGE_TO : _RangeTo<{ .. 1000 }> = _RangeTo; + +// `RangeToInclusive` should be usable within const generics: +struct _RangeToInclusive>; +// { dg-error "" "" { target *-*-* } .-1 } +const RANGE_TO_INCLUSIVE : _RangeToInclusive<{ ..= 999 }> = _RangeToInclusive; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/struct-with-invalid-const-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/struct-with-invalid-const-param.rs new file mode 100644 index 000000000000..6a0c948b1c82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/struct-with-invalid-const-param.rs @@ -0,0 +1,11 @@ +// Checks that a const param cannot be stored in a struct. +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct S(C); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/trait-const-args.rs b/gcc/testsuite/rust/rustc/ui/const-generics/trait-const-args.rs new file mode 100644 index 000000000000..83762baa2ade --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/trait-const-args.rs @@ -0,0 +1,33 @@ +// check-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Const; +trait Foo {} + +impl Foo for Const {} + +fn foo_impl(_: impl Foo<3>) {} + +fn foo_explicit>(_: T) {} + +fn foo_where(_: T) +where + T: Foo<3>, +{ +} + +fn main() { + foo_impl(Const); + foo_impl(Const::<3>); + + foo_explicit(Const); + foo_explicit(Const::<3>); + + foo_where(Const); + foo_where(Const::<3>); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/transparent-maybeunit-array-wrapper.rs b/gcc/testsuite/rust/rustc/ui/const-generics/transparent-maybeunit-array-wrapper.rs new file mode 100644 index 000000000000..b1872c2452c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/transparent-maybeunit-array-wrapper.rs @@ -0,0 +1,14 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +use std::mem::MaybeUninit; + +#[repr(transparent)] +pub struct MaybeUninitWrapper(MaybeUninit<[u64; N]>); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-after-const-ok.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-after-const-ok.rs new file mode 100644 index 000000000000..96365fa45c9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-after-const-ok.rs @@ -0,0 +1,13 @@ +// [full] run-pass +// revisions: full min +// Verifies that having generic parameters after constants is permitted +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +#[allow(dead_code)] +struct A(T); +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs new file mode 100644 index 000000000000..5226634c43be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/auxiliary/type_dependent_lib.rs @@ -0,0 +1,38 @@ +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub struct Struct(()); + +impl Struct { + pub fn new() -> Self { + Struct(()) + } + + pub fn same_ty(&self) -> (usize, usize) { + (N, M) + } + + pub fn different_ty(&self) -> (usize, u8) { + (N, M) + } + + pub fn containing_ty(&self) -> (usize, u8) { + (std::mem::size_of::() + N, M) + } + + pub fn we_have_to_go_deeper(&self) -> Struct { + Struct(()) + } +} + +pub trait Foo { + fn foo(&self) -> usize; +} + +impl Foo for Struct<7> { + fn foo(&self) -> usize { + M + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/const-arg-in-const-arg.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/const-arg-in-const-arg.rs new file mode 100644 index 000000000000..e3b7e8fda4a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/const-arg-in-const-arg.rs @@ -0,0 +1,28 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] +#![allow(incomplete_features)] + +struct Foo; + +impl Foo { + fn foo(&self) -> usize { + let f = self; + f.bar::<{ + let f = Foo; + f.bar::<7>() + }>() + N + } + + const fn bar(&self) -> usize { + M + } +} + +fn main() { + let f = Foo; + + assert_eq!(f.foo::<13>(), 20) +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-61936.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-61936.rs new file mode 100644 index 000000000000..34ba920e52dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-61936.rs @@ -0,0 +1,52 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait SliceExt { + fn array_windows_example<'a, const N: usize>(&'a self) -> ArrayWindowsExample<'a, T, N>; +} + +impl SliceExt for [T] { + fn array_windows_example<'a, const N: usize>(&'a self) -> ArrayWindowsExample<'a, T, N> { + ArrayWindowsExample{ idx: 0, slice: &self } + } +} + +struct ArrayWindowsExample<'a, T, const N: usize> { + slice: &'a [T], + idx: usize, +} + +impl <'a, T: Clone, const N: usize> Iterator for ArrayWindowsExample<'a, T, N> { + type Item = [T; N]; + fn next(&mut self) -> Option { + // Note: this is unsound for some `T` and not meant as an example + // on how to implement `ArrayWindows`. + let mut res = unsafe{ std::mem::zeroed() }; + let mut ptr = &mut res as *mut [T; N] as *mut T; + + for i in 0..N { + match self.slice[self.idx..].get(i) { + None => return None, + Some(elem) => unsafe { std::ptr::write_volatile(ptr, elem.clone())}, + }; + ptr = ptr.wrapping_add(1); + self.idx += 1; + } + + Some(res) + } +} + +const FOUR: usize = 4; + +fn main() { + let v: Vec = vec![0; 100]; + + for array in v.as_slice().array_windows_example::() { + assert_eq!(array, [0, 0, 0, 0]) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-63695.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-63695.rs new file mode 100644 index 000000000000..f69bcd95f89d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-63695.rs @@ -0,0 +1,20 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait T { + fn test(&self) -> i32 { A } +} + +struct S(); + +impl T for S {} + +fn main() { + let foo = S(); + assert_eq!(foo.test::<8i32>(), 8); + assert_eq!(foo.test::<16i32>(), 16); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-67144-1.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-67144-1.rs new file mode 100644 index 000000000000..584a6fe0f85d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-67144-1.rs @@ -0,0 +1,31 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct X; + +impl X { + pub fn getn(&self) -> [u8; N] { + getn::() + } +} + +fn getn() -> [u8; N] { + unsafe { + std::mem::zeroed() + } +} + +fn main() { + // works + let [a,b,c] = getn::<3>(); + + // cannot pattern-match on an array without a fixed length + let [a,b,c] = X.getn::<3>(); + + // mismatched types, expected array `[u8; 3]` found array `[u8; _]` + let arr: [u8; 3] = X.getn::<3>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-67144-2.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-67144-2.rs new file mode 100644 index 000000000000..3d418a1599be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-67144-2.rs @@ -0,0 +1,25 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct A; + +struct X; + +impl X { + fn inner() -> A { + outer::() + } +} + +fn outer() -> A { + A +} + +fn main() { + let i: A<3usize> = outer::<3usize>(); + let o: A<3usize> = X::inner::<3usize>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-69816.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-69816.rs new file mode 100644 index 000000000000..7bec82506c84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-69816.rs @@ -0,0 +1,23 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait IterExt: Sized + Iterator { + fn default_for_size(self) -> [Self::Item; N] + where + [Self::Item; N]: Default, + { + Default::default() + } +} + +impl IterExt for T {} + +fn main(){ + const N: usize = 10; + let arr = (0u32..10).default_for_size::(); + assert_eq!(arr, [0; 10]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-70217.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-70217.rs new file mode 100644 index 000000000000..c81079f8c3ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-70217.rs @@ -0,0 +1,20 @@ +// check-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Struct; + +impl Struct { + fn method(&self) {} +} + +fn test(x: Struct) { + Struct::::method::(&x); + x.method::(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-70507.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-70507.rs new file mode 100644 index 000000000000..fdcfe1de0a6b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-70507.rs @@ -0,0 +1,50 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait ConstChunksExactTrait { + fn const_chunks_exact(&self) -> ConstChunksExact<'_, T, {N}>; +} + +impl ConstChunksExactTrait for [T] { + fn const_chunks_exact(&self) -> ConstChunksExact<'_, T, {N}> { + assert!(N != 0); + let rem = self.len() % N; + let len = self.len() - rem; + let (fst, _) = self.split_at(len); + ConstChunksExact { v: fst, } + } +} + +struct ConstChunksExact<'a, T: 'a, const N: usize> { + v: &'a [T], +} + +impl <'a, T: std::fmt::Debug, const N: usize> Iterator for ConstChunksExact<'a, T, {N}> { + type Item = &'a [T; N]; + + fn next(&mut self) -> Option { + if self.v.len() < N { + None + } else { + let (fst, snd) = self.v.split_at(N); + + self.v = snd; + let ptr = fst.as_ptr() as *const _; + Some(unsafe { &*ptr}) + } + } +} + +fn main() { + let slice = &[1i32, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + let mut iter = [[1, 2, 3], [4, 5, 6], [7, 8, 9]].iter(); + + for a in slice.const_chunks_exact::<3>() { + assert_eq!(a, iter.next().unwrap()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-70586.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-70586.rs new file mode 100644 index 000000000000..cca861c9da3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-70586.rs @@ -0,0 +1,36 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +use std::marker::PhantomData; + +// This namespace is necessary for the ICE to trigger +struct Namespace; + +impl Namespace { + pub fn const_chunks_exact() -> ConstChunksExact<'static, T, N> { + ConstChunksExact { inner: PhantomData } + } +} + + +#[derive(Debug)] +pub struct ConstChunksExact<'a, T, const N: usize> { + inner: PhantomData<&'a T> +} + +impl <'a, T, const N: usize> Iterator for ConstChunksExact<'a, T, { N }> { + type Item = &'a [T; N]; + + fn next(&mut self) -> Option { + unreachable!() + } +} + +fn main() { + let mut chunks = Namespace::const_chunks_exact::(); + let _next: &[i32; 3] = chunks.next().unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-71348.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-71348.rs new file mode 100644 index 000000000000..e385b0c6313d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-71348.rs @@ -0,0 +1,40 @@ +// [full] run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Foo { + i: i32, +} + +trait Get<'a, const N: &'static str> { +// { dg-error "" "" { target *-*-* } .-1 } + type Target: 'a; + + fn get(&'a self) -> &'a Self::Target; +} + +impl Foo { + fn ask<'a, const N: &'static str>(&'a self) -> &'a >::Target +// { dg-error "" "" { target *-*-* } .-1 } + where + Self: Get<'a, N>, + { + self.get() + } +} + +impl<'a> Get<'a, "int"> for Foo { + type Target = i32; + + fn get(&'a self) -> &'a Self::Target { + &self.i + } +} + +fn main() { + let foo = Foo { i: 123 }; + assert_eq!(foo.ask::<"int">(), &123); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-71382.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-71382.rs new file mode 100644 index 000000000000..c76c007a54bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-71382.rs @@ -0,0 +1,27 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct Test; + +fn pass() -> u8 { + 42 +} + +impl Test { + pub fn call_me(&self) -> u8 { + self.test::() + } + + fn test u8>(&self) -> u8 { +// { dg-error "" "" { target *-*-* } .-1 } + FN() + } +} + +fn main() { + let x = Test; + assert_eq!(x.call_me(), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-71805.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-71805.rs new file mode 100644 index 000000000000..f3ca7c27960c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-71805.rs @@ -0,0 +1,44 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +use std::mem::MaybeUninit; + +trait CollectSlice<'a>: Iterator { + fn inner_array(&mut self) -> [Self::Item; N]; + + fn collect_array(&mut self) -> [Self::Item; N] { + let result = self.inner_array(); + assert!(self.next().is_none()); + result + } +} + +impl<'a, I: ?Sized> CollectSlice<'a> for I +where + I: Iterator, +{ + fn inner_array(&mut self) -> [Self::Item; N] { + let mut result: [MaybeUninit; N] = + unsafe { MaybeUninit::uninit().assume_init() }; + + let mut count = 0; + for (dest, item) in result.iter_mut().zip(self) { + *dest = MaybeUninit::new(item); + count += 1; + } + + assert_eq!(N, count); + + let temp_ptr: *const [MaybeUninit; N] = &result; + unsafe { std::ptr::read(temp_ptr as *const [Self::Item; N]) } + } +} + +fn main() { + let mut foos = [0u64; 9].iter().cloned(); + let _bar: [u64; 9] = foos.collect_array::<9_usize>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-73730.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-73730.rs new file mode 100644 index 000000000000..c4857b4d3918 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/issue-73730.rs @@ -0,0 +1,20 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Foo<'a, A>: Iterator { + fn bar(&mut self) -> *const [A; N]; +} + +impl<'a, A, I: ?Sized> Foo<'a, A> for I where I: Iterator { + fn bar(&mut self) -> *const [A; N] { + std::ptr::null() + } +} + +fn main() { + (0_u8 .. 10).bar::<10_usize>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/non-local.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/non-local.rs new file mode 100644 index 000000000000..74bb298c66be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/non-local.rs @@ -0,0 +1,27 @@ +// aux-build:type_dependent_lib.rs +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +extern crate type_dependent_lib; + +use type_dependent_lib::*; + +fn main() { + let s = Struct::<42>::new(); + assert_eq!(s.same_ty::<7>(), (42, 7)); + assert_eq!(s.different_ty::<19>(), (42, 19)); + assert_eq!(Struct::<1337>::new().different_ty::<96>(), (1337, 96)); + assert_eq!( + Struct::<18>::new() + .we_have_to_go_deeper::<19>() + .containing_ty::, 3>(), + (27, 3), + ); + + let s = Struct::<7>::new(); + assert_eq!(s.foo::<18>(), 18); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/qpath.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/qpath.rs new file mode 100644 index 000000000000..ec2d9387ca90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/qpath.rs @@ -0,0 +1,15 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct A; +impl A { + fn foo() -> usize { N + 1 } +} + +fn main() { + assert_eq!(A::foo::<7>(), 8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/simple.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/simple.rs new file mode 100644 index 000000000000..b66ccb7423fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/simple.rs @@ -0,0 +1,15 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct R; + +impl R { + fn method(&self) -> u8 { N } +} +fn main() { + assert_eq!(R.method::<1u8>(), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/type-mismatch.rs new file mode 100644 index 000000000000..de4c62fce4fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type-dependent/type-mismatch.rs @@ -0,0 +1,15 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct R; + +impl R { + fn method(&self) -> u8 { N } +} +fn main() { + assert_eq!(R.method::<1u16>(), 1); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/type_of_anon_const.rs b/gcc/testsuite/rust/rustc/ui/const-generics/type_of_anon_const.rs new file mode 100644 index 000000000000..01d813a3ab00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/type_of_anon_const.rs @@ -0,0 +1,24 @@ +// run-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait T { + fn l() -> usize; + fn r() -> bool; +} + +struct S; + +impl T for S { + fn l() -> usize { N } + fn r() -> bool { M } +} + +fn main() { + assert_eq!(>::l::(), 123); + assert!(>::r::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/types-mismatch-const-args.rs b/gcc/testsuite/rust/rustc/ui/const-generics/types-mismatch-const-args.rs new file mode 100644 index 000000000000..ae6e69d3b04f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/types-mismatch-const-args.rs @@ -0,0 +1,22 @@ +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +// tests the diagnostic output of type mismatches for types that have const generics arguments. + +use std::marker::PhantomData; + +struct A<'a, T, const X: u32, const Y: u32> { + data: PhantomData<&'a T> +} + +fn a<'a, 'b>() { + let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {4u32}, {3u32}> { data: PhantomData }; +// { dg-error "" "" { target *-*-* } .-1 } + let _: A<'a, u16, {2u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data: PhantomData }; +// { dg-error "" "" { target *-*-* } .-1 } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/uninferred-consts-during-codegen-1.rs b/gcc/testsuite/rust/rustc/ui/const-generics/uninferred-consts-during-codegen-1.rs new file mode 100644 index 000000000000..0d07b6b87eaf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/uninferred-consts-during-codegen-1.rs @@ -0,0 +1,20 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +use std::fmt; + +struct Array([T; N]); + +impl fmt::Debug for Array { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list().entries(self.0.iter()).finish() + } +} + +fn main() { + assert_eq!(format!("{:?}", Array([1, 2, 3])), "[1, 2, 3]"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/uninferred-consts-during-codegen-2.rs b/gcc/testsuite/rust/rustc/ui/const-generics/uninferred-consts-during-codegen-2.rs new file mode 100644 index 000000000000..70135c1eb7db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/uninferred-consts-during-codegen-2.rs @@ -0,0 +1,20 @@ +// run-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +use std::fmt; + +struct Array(T); + +impl fmt::Debug for Array<[T; N]> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list().entries((&self.0 as &[T]).iter()).finish() + } +} + +fn main() { + assert_eq!(format!("{:?}", Array([1, 2, 3])), "[1, 2, 3]"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/unknown_adt.rs b/gcc/testsuite/rust/rustc/ui/const-generics/unknown_adt.rs new file mode 100644 index 000000000000..a4e2e94f32cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/unknown_adt.rs @@ -0,0 +1,11 @@ +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +fn main() { + let _: UnknownStruct<7>; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/unused-const-param.rs b/gcc/testsuite/rust/rustc/ui/const-generics/unused-const-param.rs new file mode 100644 index 000000000000..9ed51e544079 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/unused-const-param.rs @@ -0,0 +1,11 @@ +// check-pass +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +struct A; // ok + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/unused_braces.rs b/gcc/testsuite/rust/rustc/ui/const-generics/unused_braces.rs new file mode 100644 index 000000000000..9f60e21d3f1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/unused_braces.rs @@ -0,0 +1,18 @@ +// check-pass +// run-rustfix +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] +#![warn(unused_braces)] + + +struct A; + +fn main() { + let _: A<7>; // ok + let _: A<{ 7 }>; // { dg-warning "" "" { target *-*-* } } + let _: A<{ 3 + 5 }>; // ok +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/wf-misc.rs b/gcc/testsuite/rust/rustc/ui/const-generics/wf-misc.rs new file mode 100644 index 000000000000..e745043e6f94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/wf-misc.rs @@ -0,0 +1,23 @@ +// Tests miscellaneous well-formedness examples. +// revisions: full min + +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +pub fn arr_len() { + let _: [u8; N + 1]; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +struct Const; + +pub fn func_call() { + let _: Const::<{N + 1}>; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const-generics/where-clauses.rs b/gcc/testsuite/rust/rustc/ui/const-generics/where-clauses.rs new file mode 100644 index 000000000000..8675ec539edb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-generics/where-clauses.rs @@ -0,0 +1,36 @@ +// check-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(full, allow(incomplete_features))] +#![cfg_attr(min, feature(min_const_generics))] + +trait Bar { fn bar() {} } +trait Foo: Bar {} + +fn test() where T: Foo { + >::bar(); +} + +struct Faz; + +impl Faz { + fn test() where T: Foo { + >::bar() + } +} + +trait Fiz { + fn fiz() where T: Foo { + >::bar(); + } +} + +impl Bar for u8 {} +impl Foo for u8 {} +impl Fiz for u8 {} +fn main() { + test::(); + Faz::<3>::test::(); + >::fiz::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/const-suggest-feature.rs b/gcc/testsuite/rust/rustc/ui/const-suggest-feature.rs new file mode 100644 index 000000000000..367994ed22a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const-suggest-feature.rs @@ -0,0 +1,8 @@ +const WRITE: () = unsafe { + *std::ptr::null_mut() = 0; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { help ".E0658." "" { target *-*-* } .-2 } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const_evaluatable/associated-const.rs b/gcc/testsuite/rust/rustc/ui/const_evaluatable/associated-const.rs new file mode 100644 index 000000000000..088d5677af6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const_evaluatable/associated-const.rs @@ -0,0 +1,12 @@ +// check-pass +struct Foo(T); +impl Foo { + const VALUE: usize = std::mem::size_of::(); +} + +fn test() { + let _ = [0; Foo::::VALUE]; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const_evaluatable/function-call.rs b/gcc/testsuite/rust/rustc/ui/const_evaluatable/function-call.rs new file mode 100644 index 000000000000..f931b9ebead4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const_evaluatable/function-call.rs @@ -0,0 +1,20 @@ +// check-pass + +const fn foo() -> usize { + // We might instead branch on `std::mem::size_of::<*mut T>() < 8` here, + // which would cause this function to fail on 32 bit systems. + if false { + std::mem::size_of::() + } else { + 8 + } +} + +fn test() { + let _ = [0; foo::()]; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/const_prop/ice-assert-fail-div-by-zero.rs b/gcc/testsuite/rust/rustc/ui/const_prop/ice-assert-fail-div-by-zero.rs new file mode 100644 index 000000000000..1e17805384c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const_prop/ice-assert-fail-div-by-zero.rs @@ -0,0 +1,13 @@ +// check-pass + +// compile-flags: --crate-type lib + +#![warn(unconditional_panic)] + +pub struct Fixed64(i64); + +// HACK: this test passes only because this is a const fn that is written to metadata +pub const fn div(f: Fixed64) { + f.0 / 0; // { dg-warning "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/const_prop/inline_spans.rs b/gcc/testsuite/rust/rustc/ui/const_prop/inline_spans.rs new file mode 100644 index 000000000000..b206c0996efb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/const_prop/inline_spans.rs @@ -0,0 +1,15 @@ +// build-fail +// compile-flags: -Zmir-opt-level=2 + +#![deny(warnings)] + +fn main() { + let _ = add(u8::MAX, 1); +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[inline(always)] +fn add(x: u8, y: u8) -> u8 { + x + y +} + diff --git a/gcc/testsuite/rust/rustc/ui/constructor-lifetime-args.rs b/gcc/testsuite/rust/rustc/ui/constructor-lifetime-args.rs new file mode 100644 index 000000000000..7ae173426407 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/constructor-lifetime-args.rs @@ -0,0 +1,27 @@ +// All lifetime parameters in struct constructors are currently considered early bound, +// i.e., `S::` is interpreted kinda like an associated item `S::::ctor`. +// This behavior is a bit weird, because if equivalent constructor were written manually +// it would get late bound lifetime parameters. +// Variant constructors behave in the same way, lifetime parameters are considered +// belonging to the enum and being early bound. +// https://github.com/rust-lang/rust/issues/30904 + +struct S<'a, 'b>(&'a u8, &'b u8); +enum E<'a, 'b> { + V(&'a u8), + U(&'b u8), +} + +fn main() { + S(&0, &0); // OK + S::<'static>(&0, &0); +// { dg-error ".E0107." "" { target *-*-* } .-1 } + S::<'static, 'static, 'static>(&0, &0); +// { dg-error ".E0107." "" { target *-*-* } .-1 } + E::V(&0); // OK + E::V::<'static>(&0); +// { dg-error ".E0107." "" { target *-*-* } .-1 } + E::V::<'static, 'static, 'static>(&0); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/array-literal-index-oob.rs b/gcc/testsuite/rust/rustc/ui/consts/array-literal-index-oob.rs new file mode 100644 index 000000000000..61d997ba08fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/array-literal-index-oob.rs @@ -0,0 +1,12 @@ +// build-pass +// ignore-pass (test emits codegen-time warnings and verifies that they are not errors) + +#![warn(const_err, unconditional_panic)] + +fn main() { + &{ [1, 2, 3][4] }; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/array-to-slice-cast.rs b/gcc/testsuite/rust/rustc/ui/consts/array-to-slice-cast.rs new file mode 100644 index 000000000000..c609e94bb696 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/array-to-slice-cast.rs @@ -0,0 +1,14 @@ +// check-pass + +fn main() {} + +const fn foo() { + let x = [1, 2, 3, 4, 5]; + let y: &[_] = &x; + + struct Foo(bool, T); + + let x: Foo<[u8; 3]> = Foo(true, [1, 2, 3]); + let y: &Foo<[u8]> = &x; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/ascii_ctype.rs b/gcc/testsuite/rust/rustc/ui/consts/ascii_ctype.rs new file mode 100644 index 000000000000..7875b03d1854 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/ascii_ctype.rs @@ -0,0 +1,54 @@ +// run-pass + +macro_rules! suite { + ( $( $fn:ident => [$a:ident, $A:ident, $nine:ident, $dot:ident, $space:ident]; )* ) => { + $( + mod $fn { + const CHAR_A_LOWER: bool = 'a'.$fn(); + const CHAR_A_UPPER: bool = 'A'.$fn(); + const CHAR_NINE: bool = '9'.$fn(); + const CHAR_DOT: bool = '.'.$fn(); + const CHAR_SPACE: bool = ' '.$fn(); + + const U8_A_LOWER: bool = b'a'.$fn(); + const U8_A_UPPER: bool = b'A'.$fn(); + const U8_NINE: bool = b'9'.$fn(); + const U8_DOT: bool = b'.'.$fn(); + const U8_SPACE: bool = b' '.$fn(); + + pub fn run() { + assert_eq!(CHAR_A_LOWER, $a); + assert_eq!(CHAR_A_UPPER, $A); + assert_eq!(CHAR_NINE, $nine); + assert_eq!(CHAR_DOT, $dot); + assert_eq!(CHAR_SPACE, $space); + + assert_eq!(U8_A_LOWER, $a); + assert_eq!(U8_A_UPPER, $A); + assert_eq!(U8_NINE, $nine); + assert_eq!(U8_DOT, $dot); + assert_eq!(U8_SPACE, $space); + } + } + )* + + fn main() { + $( $fn::run(); )* + } + } +} + +suite! { + // 'a' 'A' '9' '.' ' ' + is_ascii_alphabetic => [true, true, false, false, false]; + is_ascii_uppercase => [false, true, false, false, false]; + is_ascii_lowercase => [true, false, false, false, false]; + is_ascii_alphanumeric => [true, true, true, false, false]; + is_ascii_digit => [false, false, true, false, false]; + is_ascii_hexdigit => [true, true, true, false, false]; + is_ascii_punctuation => [false, false, false, true, false]; + is_ascii_graphic => [true, true, true, true, false]; + is_ascii_whitespace => [false, false, false, false, true]; + is_ascii_control => [false, false, false, false, false]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/assoc-const.rs b/gcc/testsuite/rust/rustc/ui/consts/assoc-const.rs new file mode 100644 index 000000000000..9480acde83b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/assoc-const.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(unused_variables)] + +trait Nat { + const VALUE: usize; +} + +struct Zero; +struct Succ(N); + +impl Nat for Zero { + const VALUE: usize = 0; +} + +impl Nat for Succ { + const VALUE: usize = N::VALUE + 1; +} + +fn main() { + let x: [i32; >>>>::VALUE] = [1, 2, 3, 4]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/assoc_const_generic_impl.rs b/gcc/testsuite/rust/rustc/ui/consts/assoc_const_generic_impl.rs new file mode 100644 index 000000000000..f3c4493d8d09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/assoc_const_generic_impl.rs @@ -0,0 +1,22 @@ +// build-fail + +#![warn(const_err)] + +trait ZeroSized: Sized { + const I_AM_ZERO_SIZED: (); + fn requires_zero_size(self); +} + +impl ZeroSized for T { + const I_AM_ZERO_SIZED: () = [()][std::mem::size_of::()]; // { dg-warning "" "" { target *-*-* } } + fn requires_zero_size(self) { + let () = Self::I_AM_ZERO_SIZED; // { dg-error "" "" { target *-*-* } } + println!("requires_zero_size called"); + } +} + +fn main() { + ().requires_zero_size(); + 42_u32.requires_zero_size(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/associated_const_generic.rs b/gcc/testsuite/rust/rustc/ui/consts/associated_const_generic.rs new file mode 100644 index 000000000000..5b6395c79f1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/associated_const_generic.rs @@ -0,0 +1,26 @@ +// check-pass + +trait TraitA { + const VALUE: usize; +} + +struct A; +impl TraitA for A { + const VALUE: usize = 1; +} + +trait TraitB { + type MyA: TraitA; + const VALUE: usize = Self::MyA::VALUE; +} + +struct B; +impl TraitB for B { + type MyA = A; +} + +fn main() { + let _ = [0; A::VALUE]; + let _ = [0; B::VALUE]; // Indirectly refers to `A::VALUE` +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/async-block.rs b/gcc/testsuite/rust/rustc/ui/consts/async-block.rs new file mode 100644 index 000000000000..e5eff88dcd25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/async-block.rs @@ -0,0 +1,9 @@ +// From + +// edition:2018 + +const _: i32 = { core::mem::ManuallyDrop::new(async { 0 }); 4 }; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/auxiliary/cci_borrow_lib.rs b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/cci_borrow_lib.rs new file mode 100644 index 000000000000..eb3909314d0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/cci_borrow_lib.rs @@ -0,0 +1,4 @@ +pub fn foo(x: &usize) -> usize { + *x +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/auxiliary/cci_const.rs b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/cci_const.rs new file mode 100644 index 000000000000..a058705c156b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/cci_const.rs @@ -0,0 +1,7 @@ +pub extern fn bar() { +} + +pub const foopy: &'static str = "hi there"; +pub const uint_val: usize = 12; +pub const uint_expr: usize = (1 << uint_val) - 1; + diff --git a/gcc/testsuite/rust/rustc/ui/consts/auxiliary/cci_const_block.rs b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/cci_const_block.rs new file mode 100644 index 000000000000..68660f4601f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/cci_const_block.rs @@ -0,0 +1,7 @@ +pub static BLOCK_FN_DEF: fn(usize) -> usize = { + fn foo(a: usize) -> usize { + a + 10 + } + foo +}; + diff --git a/gcc/testsuite/rust/rustc/ui/consts/auxiliary/const_fn_lib.rs b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/const_fn_lib.rs new file mode 100644 index 000000000000..dde88d94ed76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/const_fn_lib.rs @@ -0,0 +1,24 @@ +// Crate that exports a const fn. Used for testing cross-crate. + +#![feature(const_fn_fn_ptr_basics)] +#![crate_type="rlib"] + +pub const fn foo() -> usize { 22 } + +pub const fn bar() -> fn() { + fn x() {} + x +} + +#[inline] +pub const fn bar_inlined() -> fn() { + fn x() {} + x +} + +#[inline(always)] +pub const fn bar_inlined_always() -> fn() { + fn x() {} + x +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/auxiliary/external_macro.rs b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/external_macro.rs new file mode 100644 index 000000000000..3ad8f33f44b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/external_macro.rs @@ -0,0 +1,15 @@ +#![feature(allow_internal_unstable)] + +// Macro to help ensure CONST_ERR lint errors +// are not silenced in external macros. +// https://github.com/rust-lang/rust/issues/65300 + +#[macro_export] +#[allow_internal_unstable(type_ascription)] +macro_rules! static_assert { + ($test:expr) => { + #[allow(dead_code)] + const _: () = [()][!($test: bool) as usize]; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/auxiliary/issue-63226.rs b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/issue-63226.rs new file mode 100644 index 000000000000..665d2cd6e6ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/issue-63226.rs @@ -0,0 +1,15 @@ +pub struct VTable{ + state:extern fn(), +} + +impl VTable{ + pub const fn vtable()->&'static VTable{ + Self::VTABLE + } + + const VTABLE: &'static VTable = + &VTable{state}; +} + +extern fn state() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/auxiliary/promotable_const_fn_lib.rs b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/promotable_const_fn_lib.rs new file mode 100644 index 000000000000..019b7bc4cc58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/auxiliary/promotable_const_fn_lib.rs @@ -0,0 +1,24 @@ +// Crate that exports a const fn. Used for testing cross-crate. + +#![feature(staged_api, rustc_attrs)] +#![stable(since="1.0.0", feature = "mep")] + +#![crate_type="rlib"] + +#[rustc_promotable] +#[stable(since="1.0.0", feature = "mep")] +#[rustc_const_stable(since="1.0.0", feature = "mep")] +#[inline] +pub const fn foo() -> usize { 22 } + +#[stable(since="1.0.0", feature = "mep")] +pub struct Foo(usize); + +impl Foo { + #[stable(since="1.0.0", feature = "mep")] + #[rustc_const_stable(feature = "mep", since = "1.0.0")] + #[inline] + #[rustc_promotable] + pub const fn foo() -> usize { 22 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/bswap-const.rs b/gcc/testsuite/rust/rustc/ui/consts/bswap-const.rs new file mode 100644 index 000000000000..6fe5c917fc31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/bswap-const.rs @@ -0,0 +1,16 @@ +// run-pass + +#![feature(core_intrinsics)] + +use std::intrinsics; + +const SWAPPED_U8: u8 = intrinsics::bswap(0x12_u8); +const SWAPPED_U16: u16 = intrinsics::bswap(0x12_34_u16); +const SWAPPED_I32: i32 = intrinsics::bswap(0x12_34_56_78_i32); + +fn main() { + assert_eq!(SWAPPED_U8, 0x12); + assert_eq!(SWAPPED_U16, 0x34_12); + assert_eq!(SWAPPED_I32, 0x78_56_34_12); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/cast-discriminant-zst-enum.rs b/gcc/testsuite/rust/rustc/ui/consts/cast-discriminant-zst-enum.rs new file mode 100644 index 000000000000..76298f4cb78a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/cast-discriminant-zst-enum.rs @@ -0,0 +1,47 @@ +// run-pass +// Test a ZST enum whose dicriminant is ~0i128. This caused an ICE when casting to a i32. +#![feature(test)] +use std::hint::black_box; + +#[derive(Copy, Clone)] +enum Nums { + NegOne = -1, +} + +const NEG_ONE_I8: i8 = Nums::NegOne as i8; +const NEG_ONE_I16: i16 = Nums::NegOne as i16; +const NEG_ONE_I32: i32 = Nums::NegOne as i32; +const NEG_ONE_I64: i64 = Nums::NegOne as i64; +const NEG_ONE_I128: i128 = Nums::NegOne as i128; + +fn test_as_arg(n: Nums) { + assert_eq!(-1i8, n as i8); + assert_eq!(-1i16, n as i16); + assert_eq!(-1i32, n as i32); + assert_eq!(-1i64, n as i64); + assert_eq!(-1i128, n as i128); +} + +fn main() { + let kind = Nums::NegOne; + assert_eq!(-1i8, kind as i8); + assert_eq!(-1i16, kind as i16); + assert_eq!(-1i32, kind as i32); + assert_eq!(-1i64, kind as i64); + assert_eq!(-1i128, kind as i128); + + assert_eq!(-1i8, black_box(kind) as i8); + assert_eq!(-1i16, black_box(kind) as i16); + assert_eq!(-1i32, black_box(kind) as i32); + assert_eq!(-1i64, black_box(kind) as i64); + assert_eq!(-1i128, black_box(kind) as i128); + + test_as_arg(Nums::NegOne); + + assert_eq!(-1i8, NEG_ONE_I8); + assert_eq!(-1i16, NEG_ONE_I16); + assert_eq!(-1i32, NEG_ONE_I32); + assert_eq!(-1i64, NEG_ONE_I64); + assert_eq!(-1i128, NEG_ONE_I128); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/chained-constants-stackoverflow.rs b/gcc/testsuite/rust/rustc/ui/consts/chained-constants-stackoverflow.rs new file mode 100644 index 000000000000..5c0cf3b3b10b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/chained-constants-stackoverflow.rs @@ -0,0 +1,357 @@ +// run-pass + +// https://github.com/rust-lang/rust/issues/34997 + +pub const CST_1: u32 = 0; +pub const CST_2: u32 = CST_1+1; +pub const CST_3: u32 = CST_2+1; +pub const CST_4: u32 = CST_3+1; +pub const CST_5: u32 = CST_4+1; +pub const CST_6: u32 = CST_5+1; +pub const CST_7: u32 = CST_6+1; +pub const CST_8: u32 = CST_7+1; +pub const CST_9: u32 = CST_8+1; +pub const CST_10: u32 = CST_9+1; +pub const CST_11: u32 = CST_10+1; +pub const CST_12: u32 = CST_11+1; +pub const CST_13: u32 = CST_12+1; +pub const CST_14: u32 = CST_13+1; +pub const CST_15: u32 = CST_14+1; +pub const CST_16: u32 = CST_15+1; +pub const CST_17: u32 = CST_16+1; +pub const CST_18: u32 = CST_17+1; +pub const CST_19: u32 = CST_18+1; +pub const CST_20: u32 = CST_19+1; +pub const CST_21: u32 = CST_20+1; +pub const CST_22: u32 = CST_21+1; +pub const CST_23: u32 = CST_22+1; +pub const CST_24: u32 = CST_23+1; +pub const CST_25: u32 = CST_24+1; +pub const CST_26: u32 = CST_25+1; +pub const CST_27: u32 = CST_26+1; +pub const CST_28: u32 = CST_27+1; +pub const CST_29: u32 = CST_28+1; +pub const CST_30: u32 = CST_29+1; +pub const CST_31: u32 = CST_30+1; +pub const CST_32: u32 = CST_31+1; +pub const CST_33: u32 = CST_32+1; +pub const CST_34: u32 = CST_33+1; +pub const CST_35: u32 = CST_34+1; +pub const CST_36: u32 = CST_35+1; +pub const CST_37: u32 = CST_36+1; +pub const CST_38: u32 = CST_37+1; +pub const CST_39: u32 = CST_38+1; +pub const CST_40: u32 = CST_39+1; +pub const CST_41: u32 = CST_40+1; +pub const CST_42: u32 = CST_41+1; +pub const CST_43: u32 = CST_42+1; +pub const CST_44: u32 = CST_43+1; +pub const CST_45: u32 = CST_44+1; +pub const CST_46: u32 = CST_45+1; +pub const CST_47: u32 = CST_46+1; +pub const CST_48: u32 = CST_47+1; +pub const CST_49: u32 = CST_48+1; +pub const CST_50: u32 = CST_49+1; +pub const CST_51: u32 = CST_50+1; +pub const CST_52: u32 = CST_51+1; +pub const CST_53: u32 = CST_52+1; +pub const CST_54: u32 = CST_53+1; +pub const CST_55: u32 = CST_54+1; +pub const CST_56: u32 = CST_55+1; +pub const CST_57: u32 = CST_56+1; +pub const CST_58: u32 = CST_57+1; +pub const CST_59: u32 = CST_58+1; +pub const CST_60: u32 = CST_59+1; +pub const CST_61: u32 = CST_60+1; +pub const CST_62: u32 = CST_61+1; +pub const CST_63: u32 = CST_62+1; +pub const CST_64: u32 = CST_63+1; +pub const CST_65: u32 = CST_64+1; +pub const CST_66: u32 = CST_65+1; +pub const CST_67: u32 = CST_66+1; +pub const CST_68: u32 = CST_67+1; +pub const CST_69: u32 = CST_68+1; +pub const CST_70: u32 = CST_69+1; +pub const CST_71: u32 = CST_70+1; +pub const CST_72: u32 = CST_71+1; +pub const CST_73: u32 = CST_72+1; +pub const CST_74: u32 = CST_73+1; +pub const CST_75: u32 = CST_74+1; +pub const CST_76: u32 = CST_75+1; +pub const CST_77: u32 = CST_76+1; +pub const CST_78: u32 = CST_77+1; +pub const CST_79: u32 = CST_78+1; +pub const CST_80: u32 = CST_79+1; +pub const CST_81: u32 = CST_80+1; +pub const CST_82: u32 = CST_81+1; +pub const CST_83: u32 = CST_82+1; +pub const CST_84: u32 = CST_83+1; +pub const CST_85: u32 = CST_84+1; +pub const CST_86: u32 = CST_85+1; +pub const CST_87: u32 = CST_86+1; +pub const CST_88: u32 = CST_87+1; +pub const CST_89: u32 = CST_88+1; +pub const CST_90: u32 = CST_89+1; +pub const CST_91: u32 = CST_90+1; +pub const CST_92: u32 = CST_91+1; +pub const CST_93: u32 = CST_92+1; +pub const CST_94: u32 = CST_93+1; +pub const CST_95: u32 = CST_94+1; +pub const CST_96: u32 = CST_95+1; +pub const CST_97: u32 = CST_96+1; +pub const CST_98: u32 = CST_97+1; +pub const CST_99: u32 = CST_98+1; +pub const CST_100: u32 = CST_99+1; +pub const CST_101: u32 = CST_100+1; +pub const CST_102: u32 = CST_101+1; +pub const CST_103: u32 = CST_102+1; +pub const CST_104: u32 = CST_103+1; +pub const CST_105: u32 = CST_104+1; +pub const CST_106: u32 = CST_105+1; +pub const CST_107: u32 = CST_106+1; +pub const CST_108: u32 = CST_107+1; +pub const CST_109: u32 = CST_108+1; +pub const CST_110: u32 = CST_109+1; +pub const CST_111: u32 = CST_110+1; +pub const CST_112: u32 = CST_111+1; +pub const CST_113: u32 = CST_112+1; +pub const CST_114: u32 = CST_113+1; +pub const CST_115: u32 = CST_114+1; +pub const CST_116: u32 = CST_115+1; +pub const CST_117: u32 = CST_116+1; +pub const CST_118: u32 = CST_117+1; +pub const CST_119: u32 = CST_118+1; +pub const CST_120: u32 = CST_119+1; +pub const CST_121: u32 = CST_120+1; +pub const CST_122: u32 = CST_121+1; +pub const CST_123: u32 = CST_122+1; +pub const CST_124: u32 = CST_123+1; +pub const CST_125: u32 = CST_124+1; +pub const CST_126: u32 = CST_125+1; +pub const CST_127: u32 = CST_126+1; +pub const CST_128: u32 = CST_127+1; +pub const CST_129: u32 = CST_128+1; +pub const CST_130: u32 = CST_129+1; +pub const CST_131: u32 = CST_130+1; +pub const CST_132: u32 = CST_131+1; +pub const CST_133: u32 = CST_132+1; +pub const CST_134: u32 = CST_133+1; +pub const CST_135: u32 = CST_134+1; +pub const CST_136: u32 = CST_135+1; +pub const CST_137: u32 = CST_136+1; +pub const CST_138: u32 = CST_137+1; +pub const CST_139: u32 = CST_138+1; +pub const CST_140: u32 = CST_139+1; +pub const CST_141: u32 = CST_140+1; +pub const CST_142: u32 = CST_141+1; +pub const CST_143: u32 = CST_142+1; +pub const CST_144: u32 = CST_143+1; +pub const CST_145: u32 = CST_144+1; +pub const CST_146: u32 = CST_145+1; +pub const CST_147: u32 = CST_146+1; +pub const CST_148: u32 = CST_147+1; +pub const CST_149: u32 = CST_148+1; +pub const CST_150: u32 = CST_149+1; +pub const CST_151: u32 = CST_150+1; +pub const CST_152: u32 = CST_151+1; +pub const CST_153: u32 = CST_152+1; +pub const CST_154: u32 = CST_153+1; +pub const CST_155: u32 = CST_154+1; +pub const CST_156: u32 = CST_155+1; +pub const CST_157: u32 = CST_156+1; +pub const CST_158: u32 = CST_157+1; +pub const CST_159: u32 = CST_158+1; +pub const CST_160: u32 = CST_159+1; +pub const CST_161: u32 = CST_160+1; +pub const CST_162: u32 = CST_161+1; +pub const CST_163: u32 = CST_162+1; +pub const CST_164: u32 = CST_163+1; +pub const CST_165: u32 = CST_164+1; +pub const CST_166: u32 = CST_165+1; +pub const CST_167: u32 = CST_166+1; +pub const CST_168: u32 = CST_167+1; +pub const CST_169: u32 = CST_168+1; +pub const CST_170: u32 = CST_169+1; +pub const CST_171: u32 = CST_170+1; +pub const CST_172: u32 = CST_171+1; +pub const CST_173: u32 = CST_172+1; +pub const CST_174: u32 = CST_173+1; +pub const CST_175: u32 = CST_174+1; +pub const CST_176: u32 = CST_175+1; +pub const CST_177: u32 = CST_176+1; +pub const CST_178: u32 = CST_177+1; +pub const CST_179: u32 = CST_178+1; +pub const CST_180: u32 = CST_179+1; +pub const CST_181: u32 = CST_180+1; +pub const CST_182: u32 = CST_181+1; +pub const CST_183: u32 = CST_182+1; +pub const CST_184: u32 = CST_183+1; +pub const CST_185: u32 = CST_184+1; +pub const CST_186: u32 = CST_185+1; +pub const CST_187: u32 = CST_186+1; +pub const CST_188: u32 = CST_187+1; +pub const CST_189: u32 = CST_188+1; +pub const CST_190: u32 = CST_189+1; +pub const CST_191: u32 = CST_190+1; +pub const CST_192: u32 = CST_191+1; +pub const CST_193: u32 = CST_192+1; +pub const CST_194: u32 = CST_193+1; +pub const CST_195: u32 = CST_194+1; +pub const CST_196: u32 = CST_195+1; +pub const CST_197: u32 = CST_196+1; +pub const CST_198: u32 = CST_197+1; +pub const CST_199: u32 = CST_198+1; +pub const CST_200: u32 = CST_199+1; +pub const CST_201: u32 = CST_200+1; +pub const CST_202: u32 = CST_201+1; +pub const CST_203: u32 = CST_202+1; +pub const CST_204: u32 = CST_203+1; +pub const CST_205: u32 = CST_204+1; +pub const CST_206: u32 = CST_205+1; +pub const CST_207: u32 = CST_206+1; +pub const CST_208: u32 = CST_207+1; +pub const CST_209: u32 = CST_208+1; +pub const CST_210: u32 = CST_209+1; +pub const CST_211: u32 = CST_210+1; +pub const CST_212: u32 = CST_211+1; +pub const CST_213: u32 = CST_212+1; +pub const CST_214: u32 = CST_213+1; +pub const CST_215: u32 = CST_214+1; +pub const CST_216: u32 = CST_215+1; +pub const CST_217: u32 = CST_216+1; +pub const CST_218: u32 = CST_217+1; +pub const CST_219: u32 = CST_218+1; +pub const CST_220: u32 = CST_219+1; +pub const CST_221: u32 = CST_220+1; +pub const CST_222: u32 = CST_221+1; +pub const CST_223: u32 = CST_222+1; +pub const CST_224: u32 = CST_223+1; +pub const CST_225: u32 = CST_224+1; +pub const CST_226: u32 = CST_225+1; +pub const CST_227: u32 = CST_226+1; +pub const CST_228: u32 = CST_227+1; +pub const CST_229: u32 = CST_228+1; +pub const CST_230: u32 = CST_229+1; +pub const CST_231: u32 = CST_230+1; +pub const CST_232: u32 = CST_231+1; +pub const CST_233: u32 = CST_232+1; +pub const CST_234: u32 = CST_233+1; +pub const CST_235: u32 = CST_234+1; +pub const CST_236: u32 = CST_235+1; +pub const CST_237: u32 = CST_236+1; +pub const CST_238: u32 = CST_237+1; +pub const CST_239: u32 = CST_238+1; +pub const CST_240: u32 = CST_239+1; +pub const CST_241: u32 = CST_240+1; +pub const CST_242: u32 = CST_241+1; +pub const CST_243: u32 = CST_242+1; +pub const CST_244: u32 = CST_243+1; +pub const CST_245: u32 = CST_244+1; +pub const CST_246: u32 = CST_245+1; +pub const CST_247: u32 = CST_246+1; +pub const CST_248: u32 = CST_247+1; +pub const CST_249: u32 = CST_248+1; +pub const CST_250: u32 = CST_249+1; +pub const CST_251: u32 = CST_250+1; +pub const CST_252: u32 = CST_251+1; +pub const CST_253: u32 = CST_252+1; +pub const CST_254: u32 = CST_253+1; +pub const CST_255: u32 = CST_254+1; +pub const CST_256: u32 = CST_255+1; +pub const CST_257: u32 = CST_256+1; +pub const CST_258: u32 = CST_257+1; +pub const CST_259: u32 = CST_258+1; +pub const CST_260: u32 = CST_259+1; +pub const CST_261: u32 = CST_260+1; +pub const CST_262: u32 = CST_261+1; +pub const CST_263: u32 = CST_262+1; +pub const CST_264: u32 = CST_263+1; +pub const CST_265: u32 = CST_264+1; +pub const CST_266: u32 = CST_265+1; +pub const CST_267: u32 = CST_266+1; +pub const CST_268: u32 = CST_267+1; +pub const CST_269: u32 = CST_268+1; +pub const CST_270: u32 = CST_269+1; +pub const CST_271: u32 = CST_270+1; +pub const CST_272: u32 = CST_271+1; +pub const CST_273: u32 = CST_272+1; +pub const CST_274: u32 = CST_273+1; +pub const CST_275: u32 = CST_274+1; +pub const CST_276: u32 = CST_275+1; +pub const CST_277: u32 = CST_276+1; +pub const CST_278: u32 = CST_277+1; +pub const CST_279: u32 = CST_278+1; +pub const CST_280: u32 = CST_279+1; +pub const CST_281: u32 = CST_280+1; +pub const CST_282: u32 = CST_281+1; +pub const CST_283: u32 = CST_282+1; +pub const CST_284: u32 = CST_283+1; +pub const CST_285: u32 = CST_284+1; +pub const CST_286: u32 = CST_285+1; +pub const CST_287: u32 = CST_286+1; +pub const CST_288: u32 = CST_287+1; +pub const CST_289: u32 = CST_288+1; +pub const CST_290: u32 = CST_289+1; +pub const CST_291: u32 = CST_290+1; +pub const CST_292: u32 = CST_291+1; +pub const CST_293: u32 = CST_292+1; +pub const CST_294: u32 = CST_293+1; +pub const CST_295: u32 = CST_294+1; +pub const CST_296: u32 = CST_295+1; +pub const CST_297: u32 = CST_296+1; +pub const CST_298: u32 = CST_297+1; +pub const CST_299: u32 = CST_298+1; +pub const CST_300: u32 = CST_299+1; +pub const CST_301: u32 = CST_300+1; +pub const CST_302: u32 = CST_301+1; +pub const CST_303: u32 = CST_302+1; +pub const CST_304: u32 = CST_303+1; +pub const CST_305: u32 = CST_304+1; +pub const CST_306: u32 = CST_305+1; +pub const CST_307: u32 = CST_306+1; +pub const CST_308: u32 = CST_307+1; +pub const CST_309: u32 = CST_308+1; +pub const CST_310: u32 = CST_309+1; +pub const CST_311: u32 = CST_310+1; +pub const CST_312: u32 = CST_311+1; +pub const CST_313: u32 = CST_312+1; +pub const CST_314: u32 = CST_313+1; +pub const CST_315: u32 = CST_314+1; +pub const CST_316: u32 = CST_315+1; +pub const CST_317: u32 = CST_316+1; +pub const CST_318: u32 = CST_317+1; +pub const CST_319: u32 = CST_318+1; +pub const CST_320: u32 = CST_319+1; +pub const CST_321: u32 = CST_320+1; +pub const CST_322: u32 = CST_321+1; +pub const CST_323: u32 = CST_322+1; +pub const CST_324: u32 = CST_323+1; +pub const CST_325: u32 = CST_324+1; +pub const CST_326: u32 = CST_325+1; +pub const CST_327: u32 = CST_326+1; +pub const CST_328: u32 = CST_327+1; +pub const CST_329: u32 = CST_328+1; +pub const CST_330: u32 = CST_329+1; +pub const CST_331: u32 = CST_330+1; +pub const CST_332: u32 = CST_331+1; +pub const CST_333: u32 = CST_332+1; +pub const CST_334: u32 = CST_333+1; +pub const CST_335: u32 = CST_334+1; +pub const CST_336: u32 = CST_335+1; +pub const CST_337: u32 = CST_336+1; +pub const CST_338: u32 = CST_337+1; +pub const CST_339: u32 = CST_338+1; +pub const CST_340: u32 = CST_339+1; +pub const CST_341: u32 = CST_340+1; +pub const CST_342: u32 = CST_341+1; +pub const CST_343: u32 = CST_342+1; +pub const CST_344: u32 = CST_343+1; +pub const CST_345: u32 = CST_344+1; +pub const CST_346: u32 = CST_345+1; +pub const CST_347: u32 = CST_346+1; +pub const CST_348: u32 = CST_347+1; +pub const CST_349: u32 = CST_348+1; +pub const CST_350: u32 = CST_349+1; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-address-of-interior-mut.rs b/gcc/testsuite/rust/rustc/ui/consts/const-address-of-interior-mut.rs new file mode 100644 index 000000000000..59ed0cc008a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-address-of-interior-mut.rs @@ -0,0 +1,17 @@ +#![feature(raw_ref_op)] + +use std::cell::Cell; + +const A: () = { let x = Cell::new(2); &raw const x; }; // { dg-error ".E0492." "" { target *-*-* } } + +static B: () = { let x = Cell::new(2); &raw const x; }; // { dg-error ".E0492." "" { target *-*-* } } + +static mut C: () = { let x = Cell::new(2); &raw const x; }; // { dg-error ".E0492." "" { target *-*-* } } + +const fn foo() { + let x = Cell::new(0); + let y = &raw const x; // { dg-error ".E0492." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-address-of-mut.rs b/gcc/testsuite/rust/rustc/ui/consts/const-address-of-mut.rs new file mode 100644 index 000000000000..ba708e6511df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-address-of-mut.rs @@ -0,0 +1,15 @@ +#![feature(raw_ref_op)] + +const A: () = { let mut x = 2; &raw mut x; }; // { dg-error ".E0764." "" { target *-*-* } } + +static B: () = { let mut x = 2; &raw mut x; }; // { dg-error ".E0764." "" { target *-*-* } } + +static mut C: () = { let mut x = 2; &raw mut x; }; // { dg-error ".E0764." "" { target *-*-* } } + +const fn foo() { + let mut x = 0; + let y = &raw mut x; // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-address-of.rs b/gcc/testsuite/rust/rustc/ui/consts/const-address-of.rs new file mode 100644 index 000000000000..294fb4307fc4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-address-of.rs @@ -0,0 +1,20 @@ +// check-pass + +#![feature(raw_ref_op)] + +const A: *const i32 = &raw const *&2; +static B: () = { &raw const *&2; }; +static mut C: *const i32 = &raw const *&2; +const D: () = { let x = 2; &raw const x; }; +static E: () = { let x = 2; &raw const x; }; +static mut F: () = { let x = 2; &raw const x; }; + +const fn const_ptr() { + let x = 0; + let ptr = &raw const x; + let r = &x; + let ptr2 = &raw const *r; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-adt-align-mismatch.rs b/gcc/testsuite/rust/rustc/ui/consts/const-adt-align-mismatch.rs new file mode 100644 index 000000000000..31ced0d450c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-adt-align-mismatch.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(dead_code)] +#![allow(deprecated)] + +use std::mem; + +#[derive(PartialEq, Debug)] +enum Foo { + A(u32), + Bar([u16; 4]), + C +} + +// NOTE(eddyb) Don't make this a const, needs to be a static +// so it is always instantiated as a LLVM constant value. +static FOO: Foo = Foo::C; + +fn main() { + assert_eq!(FOO, Foo::C); + assert_eq!(mem::size_of::(), 12); + assert_eq!(mem::min_align_of::(), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-array-oob-arith.rs b/gcc/testsuite/rust/rustc/ui/consts/const-array-oob-arith.rs new file mode 100644 index 000000000000..bff49d1d054c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-array-oob-arith.rs @@ -0,0 +1,17 @@ +#![feature(const_indexing)] + +const ARR: [i32; 6] = [42, 43, 44, 45, 46, 47]; +const IDX: usize = 3; +const VAL: i32 = ARR[IDX]; +const BONG: [i32; (ARR[0] - 41) as usize] = [5]; +const BLUB: [i32; (ARR[0] - 40) as usize] = [5]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + +fn main() { + let _ = VAL; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-array-oob.rs b/gcc/testsuite/rust/rustc/ui/consts/const-array-oob.rs new file mode 100644 index 000000000000..2c166ac60931 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-array-oob.rs @@ -0,0 +1,13 @@ +#![feature(const_indexing)] + +const FOO: [usize; 3] = [1, 2, 3]; +const BAR: usize = FOO[5]; // no error, because the error below occurs before regular const eval + +const BLUB: [u32; FOO[4]] = [5, 6]; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } + +fn main() { + let _ = BAR; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-autoderef.rs b/gcc/testsuite/rust/rustc/ui/consts/const-autoderef.rs new file mode 100644 index 000000000000..b857ec10ef96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-autoderef.rs @@ -0,0 +1,12 @@ +// run-pass + +const A: [u8; 1] = ['h' as u8]; +const B: u8 = (&A)[0]; +const C: &'static &'static &'static &'static [u8; 1] = & & & &A; +const D: u8 = (&C)[0]; + +pub fn main() { + assert_eq!(B, A[0]); + assert_eq!(D, A[0]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-big-enum.rs b/gcc/testsuite/rust/rustc/ui/consts/const-big-enum.rs new file mode 100644 index 000000000000..ece8c4f41771 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-big-enum.rs @@ -0,0 +1,31 @@ +// run-pass + +enum Foo { + Bar(u32), + Baz, + Quux(u64, u16) +} + +static X: Foo = Foo::Baz; + +pub fn main() { + match X { + Foo::Baz => {} + _ => panic!() + } + match Y { + Foo::Bar(s) => assert_eq!(s, 2654435769), + _ => panic!() + } + match Z { + Foo::Quux(d,h) => { + assert_eq!(d, 0x123456789abcdef0); + assert_eq!(h, 0x1234); + } + _ => panic!() + } +} + +static Y: Foo = Foo::Bar(2654435769); +static Z: Foo = Foo::Quux(0x123456789abcdef0, 0x1234); + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-binops.rs b/gcc/testsuite/rust/rustc/ui/consts/const-binops.rs new file mode 100644 index 000000000000..8b4ceea197e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-binops.rs @@ -0,0 +1,127 @@ +// run-pass + +macro_rules! assert_approx_eq { + ($a:expr, $b:expr) => ({ + let (a, b) = (&$a, &$b); + assert!((*a - *b).abs() < 1.0e-6, + "{} is not approximately equal to {}", *a, *b); + }) +} + +static A: isize = -4 + 3; +static A2: usize = 3 + 3; +static B: f64 = 3.0 + 2.7; + +static C: isize = 3 - 4; +static D: usize = 3 - 3; +static E: f64 = 3.0 - 2.7; + +static E2: isize = -3 * 3; +static F: usize = 3 * 3; +static G: f64 = 3.3 * 3.3; + +static H: isize = 3 / -1; +static I: usize = 3 / 3; +static J: f64 = 3.3 / 3.3; + +static N: bool = true && false; + +static O: bool = true || false; + +static P: isize = 3 & 1; +static Q: usize = 1 & 3; + +static R: isize = 3 | 1; +static S: usize = 1 | 3; + +static T: isize = 3 ^ 1; +static U: usize = 1 ^ 3; + +static V: isize = 1 << 3; + +// NOTE: better shr coverage +static W: isize = 1024 >> 4; +static X: usize = 1024 >> 4; + +static Y: bool = 1 == 1; +static Z: bool = 1.0f64 == 1.0; + +static AA: bool = 1 <= 2; +static AB: bool = -1 <= 2; +static AC: bool = 1.0f64 <= 2.0; + +static AD: bool = 1 < 2; +static AE: bool = -1 < 2; +static AF: bool = 1.0f64 < 2.0; + +static AG: bool = 1 != 2; +static AH: bool = -1 != 2; +static AI: bool = 1.0f64 != 2.0; + +static AJ: bool = 2 >= 1; +static AK: bool = 2 >= -2; +static AL: bool = 1.0f64 >= -2.0; + +static AM: bool = 2 > 1; +static AN: bool = 2 > -2; +static AO: bool = 1.0f64 > -2.0; + +pub fn main() { + assert_eq!(A, -1); + assert_eq!(A2, 6); + assert_approx_eq!(B, 5.7); + + assert_eq!(C, -1); + assert_eq!(D, 0); + assert_approx_eq!(E, 0.3); + + assert_eq!(E2, -9); + assert_eq!(F, 9); + assert_approx_eq!(G, 10.89); + + assert_eq!(H, -3); + assert_eq!(I, 1); + assert_approx_eq!(J, 1.0); + + assert_eq!(N, false); + + assert_eq!(O, true); + + assert_eq!(P, 1); + assert_eq!(Q, 1); + + assert_eq!(R, 3); + assert_eq!(S, 3); + + assert_eq!(T, 2); + assert_eq!(U, 2); + + assert_eq!(V, 8); + + assert_eq!(W, 64); + assert_eq!(X, 64); + + assert_eq!(Y, true); + assert_eq!(Z, true); + + assert_eq!(AA, true); + assert_eq!(AB, true); + assert_eq!(AC, true); + + assert_eq!(AD, true); + assert_eq!(AE, true); + assert_eq!(AF, true); + + assert_eq!(AG, true); + assert_eq!(AH, true); + assert_eq!(AI, true); + + assert_eq!(AJ, true); + assert_eq!(AK, true); + assert_eq!(AL, true); + + assert_eq!(AM, true); + assert_eq!(AN, true); + assert_eq!(AO, true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-bitshift-rhs-inference.rs b/gcc/testsuite/rust/rustc/ui/consts/const-bitshift-rhs-inference.rs new file mode 100644 index 000000000000..b11711bf826b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-bitshift-rhs-inference.rs @@ -0,0 +1,25 @@ +// run-pass +const RHS: u8 = 8; +const IRHS: i8 = 8; +const RHS16: u16 = 8; +const IRHS16: i16 = 8; +const RHS32: u32 = 8; +const IRHS32: i32 = 8; +const RHS64: u64 = 8; +const IRHS64: i64 = 8; +const RHSUS: usize = 8; +const IRHSIS: isize = 8; + +fn main() { + let _: [&'static str; 1 << RHS] = [""; 256]; + let _: [&'static str; 1 << IRHS] = [""; 256]; + let _: [&'static str; 1 << RHS16] = [""; 256]; + let _: [&'static str; 1 << IRHS16] = [""; 256]; + let _: [&'static str; 1 << RHS32] = [""; 256]; + let _: [&'static str; 1 << IRHS32] = [""; 256]; + let _: [&'static str; 1 << RHS64] = [""; 256]; + let _: [&'static str; 1 << IRHS64] = [""; 256]; + let _: [&'static str; 1 << RHSUS] = [""; 256]; + let _: [&'static str; 1 << IRHSIS] = [""; 256]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-block-cross-crate-fn.rs b/gcc/testsuite/rust/rustc/ui/consts/const-block-cross-crate-fn.rs new file mode 100644 index 000000000000..e16254ea61a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-block-cross-crate-fn.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:cci_const_block.rs + + +extern crate cci_const_block; + +pub fn main() { + assert_eq!(cci_const_block::BLOCK_FN_DEF(390), 400); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-block-item-macro-codegen.rs b/gcc/testsuite/rust/rustc/ui/consts/const-block-item-macro-codegen.rs new file mode 100644 index 000000000000..15e70efcb284 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-block-item-macro-codegen.rs @@ -0,0 +1,41 @@ +// run-pass +#![allow(dead_code)] +// General test that function items in static blocks +// can be generated with a macro. + + +struct MyType { + desc: &'static str, + data: usize, + code: fn(usize, usize) -> usize +} + +impl MyType { + fn eval(&self, a: usize) -> usize { + (self.code)(self.data, a) + } +} + +macro_rules! codegen { + ($e:expr, $v:expr) => { + { + fn generated(a: usize, b: usize) -> usize { + a - ($e * b) + } + MyType { + desc: "test", + data: $v, + code: generated + } + } + } +} + +static GENERATED_CODE_1: MyType = codegen!(2, 100); +static GENERATED_CODE_2: MyType = codegen!(5, 1000); + +pub fn main() { + assert_eq!(GENERATED_CODE_1.eval(10), 80); + assert_eq!(GENERATED_CODE_2.eval(100), 500); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-block-item.rs b/gcc/testsuite/rust/rustc/ui/consts/const-block-item.rs new file mode 100644 index 000000000000..9f7a9a0b9b22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-block-item.rs @@ -0,0 +1,42 @@ +// run-pass +#![allow(unused_imports)] + +mod foo { + pub trait Value { + fn value(&self) -> usize; + } +} + +static BLOCK_USE: usize = { + use foo::Value; + 100 +}; + +static BLOCK_STRUCT_DEF: usize = { + struct Foo { + a: usize + } + Foo{ a: 300 }.a +}; + +static BLOCK_FN_DEF: fn(usize) -> usize = { + fn foo(a: usize) -> usize { + a + 10 + } + foo +}; + +static BLOCK_MACRO_RULES: usize = { + macro_rules! baz { + () => (412) + } + baz!() +}; + +pub fn main() { + assert_eq!(BLOCK_USE, 100); + assert_eq!(BLOCK_STRUCT_DEF, 300); + assert_eq!(BLOCK_FN_DEF(390), 400); + assert_eq!(BLOCK_MACRO_RULES, 412); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-block-non-item-statement-3.rs b/gcc/testsuite/rust/rustc/ui/consts/const-block-non-item-statement-3.rs new file mode 100644 index 000000000000..24419ce38b10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-block-non-item-statement-3.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(dead_code, unused)] + +type Array = [u32; { let x = 2; 5 }]; + +pub fn main() { + let _: Array = [0; 5]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-block-non-item-statement-rpass.rs b/gcc/testsuite/rust/rustc/ui/consts/const-block-non-item-statement-rpass.rs new file mode 100644 index 000000000000..8e51ecf4ce8b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-block-non-item-statement-rpass.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code, unused)] + +#[repr(u8)] +enum Foo { + Bar = { let x = 1; 3 } +} + +pub fn main() { + assert_eq!(3, Foo::Bar as u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-block-non-item-statement.rs b/gcc/testsuite/rust/rustc/ui/consts/const-block-non-item-statement.rs new file mode 100644 index 000000000000..b5552c9a7ece --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-block-non-item-statement.rs @@ -0,0 +1,24 @@ +// check-pass + +enum Foo { + Bar = { let x = 1; 3 } +} + + +const A: usize = { 1; 2 }; + +const B: usize = { { } 2 }; + +macro_rules! foo { + () => (()) +} + +const C: usize = { foo!(); 2 }; + +const D: usize = { let x = 4; 2 }; + +type Array = [u32; { let x = 2; 5 }]; +type Array2 = [u32; { let mut x = 2; x = 3; x}]; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-block.rs b/gcc/testsuite/rust/rustc/ui/consts/const-block.rs new file mode 100644 index 000000000000..e809e81a2b2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-block.rs @@ -0,0 +1,46 @@ +// run-pass +#![allow(unused_braces)] +#![allow(dead_code)] +#![allow(unused_unsafe)] + +use std::marker::Sync; + +struct Foo { + a: usize, + b: *const () +} + +unsafe impl Sync for Foo {} + +fn foo(a: T) -> T { + a +} + +static BLOCK_INTEGRAL: usize = { 1 }; +static BLOCK_EXPLICIT_UNIT: () = { () }; +static BLOCK_IMPLICIT_UNIT: () = { }; +static BLOCK_FLOAT: f64 = { 1.0 }; +static BLOCK_ENUM: Option = { Some(100) }; +static BLOCK_STRUCT: Foo = { Foo { a: 12, b: std::ptr::null::<()>() } }; +static BLOCK_UNSAFE: usize = unsafe { 1000 }; + +static BLOCK_FN_INFERRED: fn(usize) -> usize = { foo }; + +static BLOCK_FN: fn(usize) -> usize = { foo:: }; + +static BLOCK_ENUM_CONSTRUCTOR: fn(usize) -> Option = { Some }; + +pub fn main() { + assert_eq!(BLOCK_INTEGRAL, 1); + assert_eq!(BLOCK_EXPLICIT_UNIT, ()); + assert_eq!(BLOCK_IMPLICIT_UNIT, ()); + assert_eq!(BLOCK_FLOAT, 1.0_f64); + assert_eq!(BLOCK_STRUCT.a, 12); + assert_eq!(BLOCK_STRUCT.b, std::ptr::null::<()>()); + assert_eq!(BLOCK_ENUM, Some(100)); + assert_eq!(BLOCK_UNSAFE, 1000); + assert_eq!(BLOCK_FN_INFERRED(300), 300); + assert_eq!(BLOCK_FN(300), 300); + assert_eq!(BLOCK_ENUM_CONSTRUCTOR(200), Some(200)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-bound.rs b/gcc/testsuite/rust/rustc/ui/consts/const-bound.rs new file mode 100644 index 000000000000..ea4eb29e84be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-bound.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +// Make sure const bounds work on things, and test that a few types +// are const. + +// pretty-expanded FIXME #23616 + +fn foo(x: T) -> T { x } + +struct F { field: isize } + +pub fn main() { + /*foo(1); + foo("hi".to_string()); + foo(vec![1, 2, 3]); + foo(F{field: 42}); + foo((1, 2)); + foo(@1);*/ + foo(Box::new(1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-byte-str-cast.rs b/gcc/testsuite/rust/rustc/ui/consts/const-byte-str-cast.rs new file mode 100644 index 000000000000..2546324d2e71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-byte-str-cast.rs @@ -0,0 +1,10 @@ +// run-pass +#[deny(warnings)] + +pub fn main() { + let _ = b"x" as &[u8]; + let _ = b"y" as &[u8; 1]; + let _ = b"z" as *const u8; + let _ = "ä" as *const str; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-call.rs b/gcc/testsuite/rust/rustc/ui/consts/const-call.rs new file mode 100644 index 000000000000..a7e6b3e17198 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-call.rs @@ -0,0 +1,10 @@ +fn f(x: usize) -> usize { + x +} + +fn main() { + let _ = [0; f(2)]; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-cast-different-types.rs b/gcc/testsuite/rust/rustc/ui/consts/const-cast-different-types.rs new file mode 100644 index 000000000000..b986a337cccc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-cast-different-types.rs @@ -0,0 +1,7 @@ +static a: &'static str = "foo"; +static b: *const u8 = a as *const u8; // { dg-error ".E0606." "" { target *-*-* } } +static c: *const u8 = &a as *const u8; // { dg-error ".E0606." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-cast-ptr-int.rs b/gcc/testsuite/rust/rustc/ui/consts/const-cast-ptr-int.rs new file mode 100644 index 000000000000..ef492db508ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-cast-ptr-int.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(non_upper_case_globals)] + +use std::ptr; + +struct TestStruct { + x: *const u8 +} + +unsafe impl Sync for TestStruct {} + +static a: TestStruct = TestStruct{x: 0 as *const u8}; + +pub fn main() { + assert_eq!(a.x, ptr::null()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-cast-wrong-type.rs b/gcc/testsuite/rust/rustc/ui/consts/const-cast-wrong-type.rs new file mode 100644 index 000000000000..cf80ab57fe16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-cast-wrong-type.rs @@ -0,0 +1,6 @@ +static a: [u8; 3] = ['h' as u8, 'i' as u8, 0 as u8]; +static b: *const i8 = &a as *const i8; // { dg-error ".E0308." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-cast.rs b/gcc/testsuite/rust/rustc/ui/consts/const-cast.rs new file mode 100644 index 000000000000..e95b50725804 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-cast.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(non_upper_case_globals)] + +struct TestStruct { + x: *const u8, +} + +unsafe impl Sync for TestStruct {} + +extern fn foo() {} +const x: extern "C" fn() = foo; +static y: TestStruct = TestStruct { x: x as *const u8 }; + +pub fn main() { + assert_eq!(x as *const u8, y.x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-const.rs b/gcc/testsuite/rust/rustc/ui/consts/const-const.rs new file mode 100644 index 000000000000..607a579cd317 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-const.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(non_upper_case_globals)] + +const a: isize = 1; +const b: isize = a + 2; + +pub fn main() { + assert_eq!(b, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-contents.rs b/gcc/testsuite/rust/rustc/ui/consts/const-contents.rs new file mode 100644 index 000000000000..bbb75e16bcc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-contents.rs @@ -0,0 +1,20 @@ +// run-pass +// Issue #570 +#![allow(non_upper_case_globals)] + +static lsl : isize = 1 << 2; +static add : isize = 1 + 2; +static addf : f64 = 1.0 + 2.0; +static not : isize = !0; +static notb : bool = !true; +static neg : isize = -(1); + +pub fn main() { + assert_eq!(lsl, 4); + assert_eq!(add, 3); + assert_eq!(addf, 3.0); + assert_eq!(not, -1); + assert_eq!(notb, false); + assert_eq!(neg, -1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-cross-crate-const.rs b/gcc/testsuite/rust/rustc/ui/consts/const-cross-crate-const.rs new file mode 100644 index 000000000000..4f6630e5ba9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-cross-crate-const.rs @@ -0,0 +1,17 @@ +// run-pass +// aux-build:cci_const.rs +#![allow(non_upper_case_globals)] + +extern crate cci_const; +static foo: &'static str = cci_const::foopy; +static a: usize = cci_const::uint_val; +static b: usize = cci_const::uint_expr + 5; + +pub fn main() { + assert_eq!(a, 12); + let foo2 = a; + assert_eq!(foo2, cci_const::uint_val); + assert_eq!(b, cci_const::uint_expr + 5); + assert_eq!(foo, cci_const::foopy); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-cross-crate-extern.rs b/gcc/testsuite/rust/rustc/ui/consts/const-cross-crate-extern.rs new file mode 100644 index 000000000000..e90ac9a8f81b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-cross-crate-extern.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:cci_const.rs +#![allow(non_upper_case_globals)] + +extern crate cci_const; +use cci_const::bar; +static foo: extern "C" fn() = bar; + +pub fn main() { + assert!(foo == bar); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-deref-ptr.rs b/gcc/testsuite/rust/rustc/ui/consts/const-deref-ptr.rs new file mode 100644 index 000000000000..5c238fc035dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-deref-ptr.rs @@ -0,0 +1,8 @@ +// Check that you can't dereference raw pointers in constants. + +fn main() { + static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + println!("{}", C); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-deref.rs b/gcc/testsuite/rust/rustc/ui/consts/const-deref.rs new file mode 100644 index 000000000000..0ee61a4fc020 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-deref.rs @@ -0,0 +1,9 @@ +// run-pass + +const C: &'static isize = &1000; +static D: isize = *C; + +pub fn main() { + assert_eq!(D, 1000); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-endianess.rs b/gcc/testsuite/rust/rustc/ui/consts/const-endianess.rs new file mode 100644 index 000000000000..5d4c08d45fcc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-endianess.rs @@ -0,0 +1,22 @@ +// run-pass +#![feature(test)] + +extern crate test; +use test::black_box as b; // prevent promotion of the argument and const-propagation of the result + +const BE_U32: u32 = 55u32.to_be(); +const LE_U32: u32 = 55u32.to_le(); + +fn main() { + assert_eq!(BE_U32, b(55u32).to_be()); + assert_eq!(LE_U32, b(55u32).to_le()); + + #[cfg(not(target_os = "emscripten"))] + { + const BE_U128: u128 = 999999u128.to_be(); + const LE_I128: i128 = (-999999i128).to_le(); + assert_eq!(BE_U128, b(999999u128).to_be()); + assert_eq!(LE_I128, b(-999999i128).to_le()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-byref-self.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-byref-self.rs new file mode 100644 index 000000000000..c7edc53ce63b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-byref-self.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] + +enum E { V, VV(isize) } +static C: E = E::V; + +impl E { + pub fn method(&self) { + match *self { + E::V => {} + E::VV(..) => panic!() + } + } +} + +pub fn main() { + C.method() +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-byref.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-byref.rs new file mode 100644 index 000000000000..e2d7f50e1b50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-byref.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] + +enum E { V, VV(isize) } +static C: E = E::V; + +fn f(a: &E) { + match *a { + E::V => {} + E::VV(..) => panic!() + } +} + +pub fn main() { + f(&C) +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-cast.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-cast.rs new file mode 100644 index 000000000000..a4de21acc8e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-cast.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(non_upper_case_globals)] + +enum A { A1, A2 } +enum B { B1=4, B2=2 } + +pub fn main () { + static c1: isize = A::A2 as isize; + static c2: isize = B::B2 as isize; + let a1 = A::A2 as isize; + let a2 = B::B2 as isize; + assert_eq!(c1, 1); + assert_eq!(c2, 2); + assert_eq!(a1, 1); + assert_eq!(a2, 2); + + // Turns out that adding a let-binding generates totally different MIR. + static c1_2: isize = { let v = A::A1; v as isize }; + static c2_2: isize = { let v = B::B1; v as isize }; + let a1_2 = { let v = A::A1; v as isize }; + let a2_2 = { let v = B::B1; v as isize }; + assert_eq!(c1_2, 0); + assert_eq!(c2_2, 4); + assert_eq!(a1_2, 0); + assert_eq!(a2_2, 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-ptr.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-ptr.rs new file mode 100644 index 000000000000..a32656e2d7f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-ptr.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] + +enum E { V0, V1(isize) } +static C: &'static E = &E::V0; + +pub fn main() { + match *C { + E::V0 => (), + _ => panic!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-struct.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-struct.rs new file mode 100644 index 000000000000..69b1c9927a01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-struct.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] + +enum E { V16(u16), V32(u32) } +struct S { a: E, b: u16, c: u16 } +static C: S = S { a: E::V16(0xDEAD), b: 0x600D, c: 0xBAD }; + +pub fn main() { + let n = C.b; + assert!(n != 0xBAD); + assert_eq!(n, 0x600D); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-struct2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-struct2.rs new file mode 100644 index 000000000000..14b9837c00fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-struct2.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] + +enum E { V0, V16(u16) } +struct S { a: E, b: u16, c: u16 } +static C: S = S { a: E::V0, b: 0x600D, c: 0xBAD }; + +pub fn main() { + let n = C.b; + assert!(n != 0xBAD); + assert_eq!(n, 0x600D); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-structlike.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-structlike.rs new file mode 100644 index 000000000000..533c4f74a18f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-structlike.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] + +enum E { + S0 { s: String }, + S1 { u: usize } +} + +static C: E = E::S1 { u: 23 }; + +pub fn main() { + match C { + E::S0 { .. } => panic!(), + E::S1 { u } => assert_eq!(u, 23) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-tuple.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-tuple.rs new file mode 100644 index 000000000000..f97ea8fb675a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-tuple.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] + +enum E { V16(u16), V32(u32) } +static C: (E, u16, u16) = (E::V16(0xDEAD), 0x600D, 0xBAD); + +pub fn main() { + let (_, n, _) = C; + assert!(n != 0xBAD); + assert_eq!(n, 0x600D); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-tuple2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-tuple2.rs new file mode 100644 index 000000000000..0fd515922ae3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-tuple2.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] + +enum E { V0, V16(u16) } +static C: (E, u16, u16) = (E::V0, 0x600D, 0xBAD); + +pub fn main() { + let (_, n, _) = C; + assert!(n != 0xBAD); + assert_eq!(n, 0x600D); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-tuplestruct.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-tuplestruct.rs new file mode 100644 index 000000000000..23194aa88512 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-tuplestruct.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] + +enum E { V16(u16), V32(u32) } +struct S(E, u16, u16); +static C: S = S(E::V16(0xDEAD), 0x600D, 0xBAD); + +pub fn main() { + let S(_, n, _) = C; + assert!(n != 0xBAD); + assert_eq!(n, 0x600D); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-tuplestruct2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-tuplestruct2.rs new file mode 100644 index 000000000000..b35f1bfb1ddf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-tuplestruct2.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] + +enum E { V0, V16(u16) } +struct S(E, u16, u16); +static C: S = S(E::V0, 0x600D, 0xBAD); + +pub fn main() { + let S(_, n, _) = C; + assert!(n != 0xBAD); + assert_eq!(n, 0x600D); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-vec-index.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-vec-index.rs new file mode 100644 index 000000000000..e312f93576c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-vec-index.rs @@ -0,0 +1,31 @@ +// run-pass +#[derive(Copy, Clone)] +enum E { V1(isize), V0 } + +const C: &'static [E] = &[E::V0, E::V1(0xDEADBEE)]; +static C0: E = C[0]; +static C1: E = C[1]; +const D: &'static [E; 2] = &[E::V0, E::V1(0xDEAFBEE)]; +static D0: E = D[0]; +static D1: E = D[1]; + +pub fn main() { + match C0 { + E::V0 => (), + _ => panic!() + } + match C1 { + E::V1(n) => assert_eq!(n, 0xDEADBEE), + _ => panic!() + } + + match D0 { + E::V0 => (), + _ => panic!() + } + match D1 { + E::V1(n) => assert_eq!(n, 0xDEAFBEE), + _ => panic!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-vec-ptr.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-vec-ptr.rs new file mode 100644 index 000000000000..e75034e59494 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-vec-ptr.rs @@ -0,0 +1,16 @@ +// run-pass + +enum E { V1(isize), V0 } +static C: &'static [E] = &[E::V0, E::V1(0xDEADBEE), E::V0]; + +pub fn main() { + match C[1] { + E::V1(n) => assert_eq!(n, 0xDEADBEE), + _ => panic!() + } + match C[2] { + E::V0 => (), + _ => panic!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-enum-vector.rs b/gcc/testsuite/rust/rustc/ui/consts/const-enum-vector.rs new file mode 100644 index 000000000000..2d4c18cfb2bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-enum-vector.rs @@ -0,0 +1,16 @@ +// run-pass + +enum E { V1(isize), V0 } +static C: [E; 3] = [E::V0, E::V1(0xDEADBEE), E::V0]; + +pub fn main() { + match C[1] { + E::V1(n) => assert_eq!(n, 0xDEADBEE), + _ => panic!() + } + match C[2] { + E::V0 => (), + _ => panic!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-err-early.rs b/gcc/testsuite/rust/rustc/ui/consts/const-err-early.rs new file mode 100644 index 000000000000..d6e09be9230e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-err-early.rs @@ -0,0 +1,17 @@ +#![deny(const_err)] + +pub const A: i8 = -std::i8::MIN; // { dg-error "" "" { target *-*-* } } +pub const B: u8 = 200u8 + 200u8; // { dg-error "" "" { target *-*-* } } +pub const C: u8 = 200u8 * 4; // { dg-error "" "" { target *-*-* } } +pub const D: u8 = 42u8 - (42u8 + 1); // { dg-error "" "" { target *-*-* } } +pub const E: u8 = [5u8][1]; // { dg-error "" "" { target *-*-* } } + +fn main() { + let _a = A; + let _b = B; + let _c = C; + let _d = D; + let _e = E; + let _e = [6u8][1]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-err-multi.rs b/gcc/testsuite/rust/rustc/ui/consts/const-err-multi.rs new file mode 100644 index 000000000000..8d67881936e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-err-multi.rs @@ -0,0 +1,15 @@ +#![deny(const_err)] + +pub const A: i8 = -std::i8::MIN; +// { dg-error "" "" { target *-*-* } .-1 } +pub const B: i8 = A; +// { dg-error "" "" { target *-*-* } .-1 } +pub const C: u8 = A as u8; +// { dg-error "" "" { target *-*-* } .-1 } +pub const D: i8 = 50 - A; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + let _ = (A, B, C, D); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-err-rpass.rs b/gcc/testsuite/rust/rustc/ui/consts/const-err-rpass.rs new file mode 100644 index 000000000000..99740a94b8fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-err-rpass.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +// check for const_err regressions + +#![deny(const_err)] + +const X: *const u8 = b"" as _; +const Y: bool = 'A' == 'B'; +const Z: char = 'A'; +const W: bool = Z <= 'B'; + + +fn main() { + let _ = ((-1 as i8) << 8 - 1) as f32; + let _ = 0u8 as char; + let _ = true > false; + let _ = true >= false; + let _ = true < false; + let _ = true >= false; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-err.rs b/gcc/testsuite/rust/rustc/ui/consts/const-err.rs new file mode 100644 index 000000000000..59d1ee44f12b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-err.rs @@ -0,0 +1,19 @@ +// build-fail +// compile-flags: -Zforce-overflow-checks=on + +#![allow(arithmetic_overflow)] +#![warn(const_err)] + +fn black_box(_: T) { + unimplemented!() +} + +const FOO: u8 = [5u8][1]; +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() { + black_box((FOO, FOO)); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-err2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-err2.rs new file mode 100644 index 000000000000..2cb9fb911bdd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-err2.rs @@ -0,0 +1,40 @@ +// needed because negating int::MIN will behave differently between +// optimized compilation and unoptimized compilation and thus would +// lead to different lints being emitted + +// revisions: noopt opt opt_with_overflow_checks +//[noopt]compile-flags: -C opt-level=0 +//[opt]compile-flags: -O +//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O + +// build-fail + +#![feature(rustc_attrs)] + +fn black_box(_: T) { + unimplemented!() +} + +fn main() { + let a = -std::i8::MIN; +// { dg-error "" "" { target *-*-* } .-1 } + let a_i128 = -std::i128::MIN; +// { dg-error "" "" { target *-*-* } .-1 } + let b = 200u8 + 200u8 + 200u8; +// { dg-error "" "" { target *-*-* } .-1 } + let b_i128 = std::i128::MIN - std::i128::MAX; +// { dg-error "" "" { target *-*-* } .-1 } + let c = 200u8 * 4; +// { dg-error "" "" { target *-*-* } .-1 } + let d = 42u8 - (42u8 + 1); +// { dg-error "" "" { target *-*-* } .-1 } + let _e = [5u8][1]; +// { dg-error "" "" { target *-*-* } .-1 } + black_box(a); + black_box(a_i128); + black_box(b); + black_box(b_i128); + black_box(c); + black_box(d); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-err4.rs b/gcc/testsuite/rust/rustc/ui/consts/const-err4.rs new file mode 100644 index 000000000000..81d160746e7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-err4.rs @@ -0,0 +1,15 @@ +#[derive(Copy, Clone)] +union Foo { + a: isize, + b: (), +} + +enum Bar { + Boo = [unsafe { Foo { b: () }.a }; 4][3], +// { dg-error ".E0080." "" { target *-*-* } .-1 } +} + +fn main() { + assert_ne!(Bar::Boo as isize, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/assign-to-static-within-other-static-2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/assign-to-static-within-other-static-2.rs new file mode 100644 index 000000000000..f3fb21cf3089 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/assign-to-static-within-other-static-2.rs @@ -0,0 +1,20 @@ +// New test for #53818: modifying static memory at compile-time is not allowed. +// The test should never compile successfully + +#![feature(const_raw_ptr_deref, const_mut_refs)] + +use std::cell::UnsafeCell; + +struct Foo(UnsafeCell); + +unsafe impl Send for Foo {} +unsafe impl Sync for Foo {} + +static FOO: Foo = Foo(UnsafeCell::new(42)); + +static BAR: () = unsafe { + *FOO.0.get() = 5; // { dg-error ".E0080." "" { target *-*-* } } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/assign-to-static-within-other-static.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/assign-to-static-within-other-static.rs new file mode 100644 index 000000000000..c6114f06ae3d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/assign-to-static-within-other-static.rs @@ -0,0 +1,15 @@ +// New test for #53818: modifying static memory at compile-time is not allowed. +// The test should never compile successfully + +#![feature(const_raw_ptr_deref)] + +use std::cell::UnsafeCell; + +static mut FOO: u32 = 42; +static BOO: () = unsafe { + FOO = 5; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/auxiliary/stability.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/auxiliary/stability.rs new file mode 100644 index 000000000000..5febab3a5613 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/auxiliary/stability.rs @@ -0,0 +1,12 @@ +// Crate that exports a const fn. Used for testing cross-crate. + +#![crate_type="rlib"] +#![stable(feature = "rust1", since = "1.0.0")] + +#![feature(const_fn)] +#![feature(staged_api)] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature="foo", issue = "none")] +pub const fn foo() -> u32 { 42 } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/conditional_array_execution.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/conditional_array_execution.rs new file mode 100644 index 000000000000..a099b1264b52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/conditional_array_execution.rs @@ -0,0 +1,15 @@ +// build-fail + +#![warn(const_err)] + +const X: u32 = 5; +const Y: u32 = 6; +const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() { + println!("{}", FOO); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-warning ".E0080." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-intrinsic-promotion.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-intrinsic-promotion.rs new file mode 100644 index 000000000000..72d36b845734 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-intrinsic-promotion.rs @@ -0,0 +1,7 @@ +#![feature(core_intrinsics)] +fn main() { + // Test that calls to intrinsics are never promoted + let x: &'static usize = + &std::intrinsics::size_of::(); // { dg-error ".E0716." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-2.rs new file mode 100644 index 000000000000..796cef78738d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-2.rs @@ -0,0 +1,21 @@ +// Evaluation of constants in refutable patterns goes through +// different compiler control-flow paths. + +#![allow(unused_imports, warnings, const_err)] + +use std::fmt; +use std::{i8, i16, i32, i64, isize}; +use std::{u8, u16, u32, u64, usize}; + +const NEG_128: i8 = -128; +const NEG_NEG_128: i8 = -NEG_128; + +fn main() { + match -128i8 { + NEG_NEG_128 => println!("A"), +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + _ => println!("B"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-3.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-3.rs new file mode 100644 index 000000000000..147d735bdb49 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-3.rs @@ -0,0 +1,30 @@ +// Evaluation of constants in array-elem count goes through different +// compiler control-flow paths. +// +// This test is checking the count in an array expression. + + + + + + + +#![allow(unused_imports)] + +use std::fmt; +use std::{i8, i16, i32, i64, isize}; +use std::{u8, u16, u32, u64, usize}; + +const A_I8_I + : [u32; (i8::MAX as usize) + 1] + = [0; (i8::MAX + 1) as usize]; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +fn main() { + foo(&A_I8_I[..]); +} + +fn foo(x: T) { + println!("{:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-3b.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-3b.rs new file mode 100644 index 000000000000..6f211b2e4353 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-3b.rs @@ -0,0 +1,29 @@ +// Evaluation of constants in array-elem count goes through different +// compiler control-flow paths. +// +// This test is checking the count in an array expression. +// +// This is a variation of another such test, but in this case the +// types for the left- and right-hand sides of the addition do not +// match (as well as overflow). + +#![allow(unused_imports)] + +use std::fmt; +use std::{i8, i16, i32, i64, isize}; +use std::{u8, u16, u32, u64, usize}; + +const A_I8_I + : [u32; (i8::MAX as usize) + 1] + = [0; (i8::MAX + 1u8) as usize]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + +fn main() { + foo(&A_I8_I[..]); +} + +fn foo(x: T) { + println!("{:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-4.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-4.rs new file mode 100644 index 000000000000..29993e884eba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-4.rs @@ -0,0 +1,24 @@ +// Evaluation of constants in array-elem count goes through different +// compiler control-flow paths. +// +// This test is checking the count in an array type. + +#![allow(unused_imports)] + +use std::fmt; +use std::{i8, i16, i32, i64, isize}; +use std::{u8, u16, u32, u64, usize}; + +const A_I8_T + : [u32; (i8::MAX as i8 + 1i8) as usize] +// { dg-error ".E0080." "" { target *-*-* } .-1 } + = [0; (i8::MAX as usize) + 1]; + +fn main() { + foo(&A_I8_T[..]); +} + +fn foo(x: T) { + println!("{:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-4b.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-4b.rs new file mode 100644 index 000000000000..00e6409f0d91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow-4b.rs @@ -0,0 +1,30 @@ +// Evaluation of constants in array-elem count goes through different +// compiler control-flow paths. +// +// This test is checking the count in an array type. + +#![allow(unused_imports)] + +use std::{i8, i16, i32, i64, isize}; +use std::{u8, u16, u32, u64, usize}; + +const A_I8_T + : [u32; (i8::MAX as i8 + 1u8) as usize] +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } + = [0; (i8::MAX as usize) + 1]; + + +const A_CHAR_USIZE + : [u32; 5u8 as char as usize] + = [0; 5]; + + +const A_BAD_CHAR_USIZE + : [u32; 5i8 as char as usize] +// { dg-error ".E0604." "" { target *-*-* } .-1 } + = [0; 5]; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow2.rs new file mode 100644 index 000000000000..b053012568a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow2.rs @@ -0,0 +1,74 @@ +#![allow(unused_imports)] + +// Note: the relevant lint pass here runs before some of the constant +// evaluation below (e.g., that performed by codegen and llvm), so if you +// change this warn to a deny, then the compiler will exit before +// those errors are detected. + +#![deny(const_err)] + +use std::fmt; +use std::{i8, i16, i32, i64, isize}; +use std::{u8, u16, u32, u64, usize}; + +const VALS_I8: (i8,) = + ( + i8::MIN - 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_I16: (i16,) = + ( + i16::MIN - 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_I32: (i32,) = + ( + i32::MIN - 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_I64: (i64,) = + ( + i64::MIN - 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_U8: (u8,) = + ( + u8::MIN - 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_U16: (u16,) = ( + u16::MIN - 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_U32: (u32,) = ( + u32::MIN - 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_U64: (u64,) = + ( + u64::MIN - 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { + foo(VALS_I8); + foo(VALS_I16); + foo(VALS_I32); + foo(VALS_I64); + + foo(VALS_U8); + foo(VALS_U16); + foo(VALS_U32); + foo(VALS_U64); +} + +fn foo(_: T) { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow2b.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow2b.rs new file mode 100644 index 000000000000..2c4059928015 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow2b.rs @@ -0,0 +1,74 @@ +#![allow(unused_imports)] + +// Note: the relevant lint pass here runs before some of the constant +// evaluation below (e.g., that performed by codegen and llvm), so if you +// change this warn to a deny, then the compiler will exit before +// those errors are detected. + +#![deny(const_err)] + +use std::fmt; +use std::{i8, i16, i32, i64, isize}; +use std::{u8, u16, u32, u64, usize}; + +const VALS_I8: (i8,) = + ( + i8::MAX + 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_I16: (i16,) = + ( + i16::MAX + 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_I32: (i32,) = + ( + i32::MAX + 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_I64: (i64,) = + ( + i64::MAX + 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_U8: (u8,) = + ( + u8::MAX + 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_U16: (u16,) = ( + u16::MAX + 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_U32: (u32,) = ( + u32::MAX + 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_U64: (u64,) = + ( + u64::MAX + 1, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { + foo(VALS_I8); + foo(VALS_I16); + foo(VALS_I32); + foo(VALS_I64); + + foo(VALS_U8); + foo(VALS_U16); + foo(VALS_U32); + foo(VALS_U64); +} + +fn foo(_: T) { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow2c.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow2c.rs new file mode 100644 index 000000000000..052b7af70f96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-overflow2c.rs @@ -0,0 +1,74 @@ +#![allow(unused_imports)] + +// Note: the relevant lint pass here runs before some of the constant +// evaluation below (e.g., that performed by codegen and llvm), so if you +// change this warn to a deny, then the compiler will exit before +// those errors are detected. + +#![deny(const_err)] + +use std::fmt; +use std::{i8, i16, i32, i64, isize}; +use std::{u8, u16, u32, u64, usize}; + +const VALS_I8: (i8,) = + ( + i8::MIN * 2, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_I16: (i16,) = + ( + i16::MIN * 2, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_I32: (i32,) = + ( + i32::MIN * 2, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_I64: (i64,) = + ( + i64::MIN * 2, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_U8: (u8,) = + ( + u8::MAX * 2, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_U16: (u16,) = ( + u16::MAX * 2, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_U32: (u32,) = ( + u32::MAX * 2, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +const VALS_U64: (u64,) = + ( + u64::MAX * 2, + ); +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { + foo(VALS_I8); + foo(VALS_I16); + foo(VALS_I32); + foo(VALS_I64); + + foo(VALS_U8); + foo(VALS_U16); + foo(VALS_U32); + foo(VALS_U64); +} + +fn foo(_: T) { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-query-stack.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-query-stack.rs new file mode 100644 index 000000000000..a5571c544007 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-query-stack.rs @@ -0,0 +1,23 @@ +// compile-flags: -Ztreat-err-as-bug +// build-fail +// failure-status: 101 +// rustc-env:RUST_BACKTRACE=1 +// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" +// normalize-stderr-test "thread.*panicked.*\n" -> "" +// normalize-stderr-test "stack backtrace:\n" -> "" +// normalize-stderr-test "\s\d{1,}: .*\n" -> "" +// normalize-stderr-test "\s at .*\n" -> "" +// normalize-stderr-test ".*note: Some details.*\n" -> "" + +#![allow(unconditional_panic)] + +fn main() { + let x: &'static i32 = &(1 / 0); +// { dg-error "" "" { target *-*-* } .-1 } + println!("x={}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-span.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-span.rs new file mode 100644 index 000000000000..c7f3c5bcc299 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-eval-span.rs @@ -0,0 +1,15 @@ +// Check that error in constant evaluation of enum discriminant +// provides the context for what caused the evaluation. + +struct S(i32); + +const CONSTANT: S = S(0); + +enum E { + V = CONSTANT, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-pointer-values-in-various-types.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-pointer-values-in-various-types.rs new file mode 100644 index 000000000000..2ecb762637d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const-pointer-values-in-various-types.rs @@ -0,0 +1,112 @@ +// only-x86_64 + +#[repr(C)] +union Nonsense { + u: usize, + int_32_ref: &'static i32, + uint_8: u8, + uint_16: u16, + uint_32: u32, + uint_64: u64, + uint_128: u128, + int_8: i8, + int_16: i16, + int_32: i32, + int_64: i64, + int_128: i128, + float_32: f32, + float_64: f64, + truthy_falsey: bool, + character: char, + stringy: &'static str, +} + +fn main() { + const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + + const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + + const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + + const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + + const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + + const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + + const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey }; +// { dg-error "" "" { target *-*-* } .-1 } + + const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character }; +// { dg-error "" "" { target *-*-* } .-1 } + + const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + + const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + + const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 }; +// { dg-error "" "" { target *-*-* } .-1 } + + const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + + const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey }; +// { dg-error "" "" { target *-*-* } .-1 } + + const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character }; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_fn_ptr.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_fn_ptr.rs new file mode 100644 index 000000000000..32f0afc59fc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_fn_ptr.rs @@ -0,0 +1,38 @@ +// run-pass +// compile-flags: -Zunleash-the-miri-inside-of-you +#![feature(const_fn)] + +fn double(x: usize) -> usize { x * 2 } +const fn double_const(x: usize) -> usize { x * 2 } + +const X: fn(usize) -> usize = double; +const X_CONST: fn(usize) -> usize = double_const; + +const fn bar(x: usize) -> usize { + X(x) +} + +const fn bar_const(x: usize) -> usize { + X_CONST(x) +} + +const fn foo(x: fn(usize) -> usize, y: usize) -> usize { + x(y) +} + +fn main() { + const Y: usize = bar_const(2); + assert_eq!(Y, 4); + let y = bar_const(2); + assert_eq!(y, 4); + let y = bar(2); + assert_eq!(y, 4); + + const Z: usize = foo(double_const, 2); + assert_eq!(Z, 4); + let z = foo(double_const, 2); + assert_eq!(z, 4); + let z = foo(double, 2); + assert_eq!(z, 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_fn_ptr_fail.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_fn_ptr_fail.rs new file mode 100644 index 000000000000..19caa41bdf38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_fn_ptr_fail.rs @@ -0,0 +1,14 @@ +// run-pass +// compile-flags: -Zunleash-the-miri-inside-of-you +#![feature(const_fn)] +#![allow(unused)] + +fn double(x: usize) -> usize { x * 2 } +const X: fn(usize) -> usize = double; + +const fn bar(x: usize) -> usize { + X(x) // FIXME: this should error someday +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_fn_ptr_fail2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_fn_ptr_fail2.rs new file mode 100644 index 000000000000..fb223caff62a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_fn_ptr_fail2.rs @@ -0,0 +1,25 @@ +// build-fail +// compile-flags: -Zunleash-the-miri-inside-of-you + +#![feature(const_fn)] +#![allow(const_err)] + +fn double(x: usize) -> usize { + x * 2 +} +const X: fn(usize) -> usize = double; + +const fn bar(x: fn(usize) -> usize, y: usize) -> usize { + x(y) +} + +const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday +const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday + +fn main() { + assert_eq!(Y, 4); +// { dg-error ".E0080." "" { target *-*-* } .-1 } + assert_eq!(Z, 4); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_let.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_let.rs new file mode 100644 index 000000000000..a14791303010 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_let.rs @@ -0,0 +1,30 @@ +fn main() {} + +struct FakeNeedsDrop; + +impl Drop for FakeNeedsDrop { + fn drop(&mut self) {} +} + +// ok +const X: FakeNeedsDrop = { let x = FakeNeedsDrop; x }; + +// ok (used to incorrectly error, see #62273) +const X2: FakeNeedsDrop = { let x; x = FakeNeedsDrop; x }; + +// error +const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x }; +// { dg-error ".E0493." "" { target *-*-* } .-1 } + +// error +const Y2: FakeNeedsDrop = { let mut x; x = FakeNeedsDrop; x = FakeNeedsDrop; x }; +// { dg-error ".E0493." "" { target *-*-* } .-1 } + +// error +const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); }; +// { dg-error ".E0493." "" { target *-*-* } .-1 } + +// error +const Z2: () = { let mut x; x = None; x = Some(FakeNeedsDrop); }; +// { dg-error ".E0493." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_panic.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_panic.rs new file mode 100644 index 000000000000..19316cef0f11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_panic.rs @@ -0,0 +1,35 @@ +#![feature(const_panic)] +#![crate_type = "lib"] + +const MSG: &str = "hello"; + +const Z: () = std::panic!("cheese"); +// { dg-error "" "" { target *-*-* } .-1 } + +const Z2: () = std::panic!(); +// { dg-error "" "" { target *-*-* } .-1 } + +const Y: () = std::unreachable!(); +// { dg-error "" "" { target *-*-* } .-1 } + +const X: () = std::unimplemented!(); +// { dg-error "" "" { target *-*-* } .-1 } +// +const W: () = std::panic!(MSG); +// { dg-error "" "" { target *-*-* } .-1 } + +const Z_CORE: () = core::panic!("cheese"); +// { dg-error "" "" { target *-*-* } .-1 } + +const Z2_CORE: () = core::panic!(); +// { dg-error "" "" { target *-*-* } .-1 } + +const Y_CORE: () = core::unreachable!(); +// { dg-error "" "" { target *-*-* } .-1 } + +const X_CORE: () = core::unimplemented!(); +// { dg-error "" "" { target *-*-* } .-1 } + +const W_CORE: () = core::panic!(MSG); +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_panic_libcore_bin.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_panic_libcore_bin.rs new file mode 100644 index 000000000000..7a6f54fdca3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_panic_libcore_bin.rs @@ -0,0 +1,27 @@ +#![crate_type = "bin"] +#![feature(lang_items)] +#![feature(const_panic)] +#![no_main] +#![no_std] + +use core::panic::PanicInfo; + +const Z: () = panic!("cheese"); +// { dg-error "" "" { target *-*-* } .-1 } + +const Y: () = unreachable!(); +// { dg-error "" "" { target *-*-* } .-1 } + +const X: () = unimplemented!(); +// { dg-error "" "" { target *-*-* } .-1 } + +#[lang = "eh_personality"] +fn eh() {} +#[lang = "eh_catch_typeinfo"] +static EH_CATCH_TYPEINFO: u8 = 0; + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + loop {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_prop_errors.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_prop_errors.rs new file mode 100644 index 000000000000..65d13e2b91f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_prop_errors.rs @@ -0,0 +1,15 @@ +// check-pass + +pub trait Foo { + fn foo(self) -> u32; +} + +impl Foo for T { + fn foo(self) -> u32 { + fn bar() { loop {} } + bar:: as u32 + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_raw_ptr_ops.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_raw_ptr_ops.rs new file mode 100644 index 000000000000..42bc15fd9151 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_raw_ptr_ops.rs @@ -0,0 +1,7 @@ +fn main() {} + +// unconst and bad, will thus error in miri +const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; // { dg-error "" "" { target *-*-* } } +// unconst and bad, will thus error in miri +const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_raw_ptr_ops2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_raw_ptr_ops2.rs new file mode 100644 index 000000000000..6b53eeb4cba3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_raw_ptr_ops2.rs @@ -0,0 +1,14 @@ +#![feature(const_raw_ptr_to_usize_cast, const_raw_ptr_deref)] + +fn main() {} + +// unconst and fine +const Y: usize = unsafe { 42usize as *const i32 as usize + 1 }; +// unconst and bad, will thus error in miri +const Y2: usize = unsafe { &1 as *const i32 as usize + 1 }; // { dg-error "" "" { target *-*-* } } +// unconst and fine +const Z: i32 = unsafe { *(&1 as *const i32) }; +// unconst and bad, will thus error in miri +const Z2: i32 = unsafe { *(42 as *const i32) }; // { dg-error "" "" { target *-*-* } } +const Z3: i32 = unsafe { *(44 as *const i32) }; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_signed_pat.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_signed_pat.rs new file mode 100644 index 000000000000..d8af4b0cb1e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_signed_pat.rs @@ -0,0 +1,10 @@ +// check-pass + +fn main() { + const MIN: i8 = -5; + match 5i8 { + MIN..=-1 => {}, + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_transmute.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_transmute.rs new file mode 100644 index 000000000000..1c13864047ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/const_transmute.rs @@ -0,0 +1,56 @@ +// run-pass + +#![feature(const_fn_union)] +#![allow(dead_code)] + +#[repr(C)] +union Transmute { + t: T, + u: U, +} + +trait Bar { + fn bar(&self) -> u32; +} + +struct Foo { + foo: u32, + bar: bool, +} + +impl Bar for Foo { + fn bar(&self) -> u32 { + self.foo + } +} + +impl Drop for Foo { + fn drop(&mut self) { + assert!(!self.bar); + self.bar = true; + println!("dropping Foo"); + } +} + +#[derive(Copy, Clone)] +struct Fat<'a>(&'a Foo, &'static VTable); + +struct VTable { + drop: Option fn(&'a mut Foo)>, + size: usize, + align: usize, + bar: for<'a> fn(&'a Foo) -> u32, +} + +const FOO: &dyn Bar = &Foo { foo: 128, bar: false }; +const G: Fat = unsafe { Transmute { t: FOO }.u }; +const F: Option fn(&'a mut Foo)> = G.1.drop; +const H: for<'a> fn(&'a Foo) -> u32 = G.1.bar; + +fn main() { + let mut foo = Foo { foo: 99, bar: false }; + (F.unwrap())(&mut foo); + std::mem::forget(foo); // already ran the drop impl + assert_eq!(H(&Foo { foo: 42, bar: false }), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/dangling.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/dangling.rs new file mode 100644 index 000000000000..d39d0f66d59d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/dangling.rs @@ -0,0 +1,14 @@ +#![feature(const_raw_ptr_deref)] + +use std::{mem, usize}; + +// Make sure we error with the right kind of error on a too large slice. +const TEST: () = { unsafe { // { dg-note "" "" { target *-*-* } } + let slice: *const [u8] = mem::transmute((1usize, usize::MAX)); + let _val = &*slice; // { dg-error "" "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} }; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/dont_promote_unstable_const_fn.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/dont_promote_unstable_const_fn.rs new file mode 100644 index 000000000000..faeb471d596d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/dont_promote_unstable_const_fn.rs @@ -0,0 +1,26 @@ +#![unstable(feature = "humans", + reason = "who ever let humans program computers, + we're apparently really bad at it", + issue = "none")] + +#![feature(const_fn)] +#![feature(staged_api)] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature="foo", issue = "none")] +const fn foo() -> u32 { 42 } + +fn meh() -> u32 { 42 } + +const fn bar() -> u32 { foo() } // { dg-error "" "" { target *-*-* } } + +fn a() { + let _: &'static u32 = &foo(); // { dg-error ".E0716." "" { target *-*-* } } +} + +fn main() { + let _: &'static u32 = &meh(); // { dg-error ".E0716." "" { target *-*-* } } + let x: &'static _ = &std::time::Duration::from_millis(42).subsec_millis(); +// { dg-error ".E0716." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs new file mode 100644 index 000000000000..91537a87771e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs @@ -0,0 +1,11 @@ +// aux-build:stability.rs + +extern crate stability; + +use stability::foo; + +fn main() { + let _: &'static u32 = &foo(); // { dg-error ".E0716." "" { target *-*-* } } + let _x: &'static u32 = &foo(); // { dg-error ".E0716." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/double_check.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/double_check.rs new file mode 100644 index 000000000000..bf4b060078ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/double_check.rs @@ -0,0 +1,26 @@ +// check-pass + +enum Foo { + A = 5, + B = 42, +} +enum Bar { + C = 42, + D = 99, +} +#[repr(C)] +union Union { + foo: &'static Foo, + bar: &'static Bar, + u8: &'static u8, +} +static BAR: u8 = 42; +static FOO: (&Foo, &Bar) = unsafe {( + Union { u8: &BAR }.foo, + Union { u8: &BAR }.bar, +)}; + +static FOO2: (&Foo, &Bar) = unsafe {(std::mem::transmute(&BAR), std::mem::transmute(&BAR))}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/double_check2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/double_check2.rs new file mode 100644 index 000000000000..92cd0e5655ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/double_check2.rs @@ -0,0 +1,33 @@ +// check-pass + +// This test exhibits undefined behavior, but it is very expensive and complex to check for such +// UB in constants. +// Thus, we do not detect it if you create references to statics in ways that are UB. + +enum Foo { + A = 5, + B = 42, +} +enum Bar { + C = 42, + D = 99, +} +#[repr(C)] +union Union { + foo: &'static Foo, + bar: &'static Bar, + u8: &'static u8, +} +static BAR: u8 = 5; +static FOO: (&Foo, &Bar) = unsafe { + ( + // undefined behavior + Union { u8: &BAR }.foo, + Union { u8: &BAR }.bar, + ) +}; +static FOO2: (&Foo, &Bar) = unsafe { (std::mem::transmute(&BAR), std::mem::transmute(&BAR)) }; +//^ undefined behavior + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/double_promotion.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/double_promotion.rs new file mode 100644 index 000000000000..40bfd1d54365 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/double_promotion.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(const_fn, rustc_attrs)] + +#[rustc_args_required_const(0)] +pub const fn a(value: u8) -> u8 { + value +} + +#[rustc_args_required_const(0)] +pub fn b(_: u8) { + unimplemented!() +} + +fn main() { + let _ = b(a(0)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/duration_conversion.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/duration_conversion.rs new file mode 100644 index 000000000000..4334f194d4b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/duration_conversion.rs @@ -0,0 +1,17 @@ +// check-pass + +use std::time::Duration; + +fn main() { + const _ONE_SECOND: Duration = Duration::from_nanos(1_000_000_000); + const _ONE_MILLISECOND: Duration = Duration::from_nanos(1_000_000); + const _ONE_MICROSECOND: Duration = Duration::from_nanos(1_000); + const _ONE_NANOSECOND: Duration = Duration::from_nanos(1); + const _ONE: usize = _ONE_SECOND.as_secs() as usize; + const _TWO: usize = _ONE_MILLISECOND.subsec_millis() as usize; + const _THREE: usize = _ONE_MICROSECOND.subsec_micros() as usize; + const _FOUR: usize = _ONE_NANOSECOND.subsec_nanos() as usize; + const _0: [[u8; _ONE]; _TWO] = [[1; _ONE]; _TWO]; + const _1: [[u8; _THREE]; _FOUR] = [[3; _THREE]; _FOUR]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/enum_discr.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/enum_discr.rs new file mode 100644 index 000000000000..66b67b6a2969 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/enum_discr.rs @@ -0,0 +1,26 @@ +// run-pass + +enum Foo { + X = 42, + Y = Foo::X as isize - 3, +} + +enum Bar { + X, + Y = Bar::X as isize + 2, +} + +enum Boo { + X = Boo::Y as isize * 2, + Y = 9, +} + +fn main() { + assert_eq!(Foo::X as isize, 42); + assert_eq!(Foo::Y as isize, 39); + assert_eq!(Bar::X as isize, 0); + assert_eq!(Bar::Y as isize, 2); + assert_eq!(Boo::X as isize, 18); + assert_eq!(Boo::Y as isize, 9); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/erroneous-const.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/erroneous-const.rs new file mode 100644 index 000000000000..9ccb642d6374 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/erroneous-const.rs @@ -0,0 +1,21 @@ +//! Make sure we error on erroneous consts even if they are unused. +#![warn(const_err, unconditional_panic)] + +struct PrintName(T); +impl PrintName { + const VOID: () = [()][2]; // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +const fn no_codegen() { + if false { + let _ = PrintName::::VOID; // { dg-error ".E0080." "" { target *-*-* } } + } +} + +pub static FOO: () = no_codegen::(); // { dg-error ".E0080." "" { target *-*-* } } + +fn main() { + FOO +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/extern_fat_pointer.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/extern_fat_pointer.rs new file mode 100644 index 000000000000..9eeda852b490 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/extern_fat_pointer.rs @@ -0,0 +1,14 @@ +// check-pass + +#![feature(extern_types)] + +extern { + type Opaque; +} + +const FOO: *const u8 = &42 as *const _ as *const Opaque as *const u8; + +fn main() { + let _foo = FOO; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/feature-gate-const_fn_union.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/feature-gate-const_fn_union.rs new file mode 100644 index 000000000000..f50f092135da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/feature-gate-const_fn_union.rs @@ -0,0 +1,14 @@ +#![feature(const_fn)] + +fn main() {} + +#[repr(C)] +union Foo { + u: u32, + i: i32, +} + +const unsafe fn foo(u: u32) -> i32 { + Foo { u }.i // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/feature-gate-const_panic.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/feature-gate-const_panic.rs new file mode 100644 index 000000000000..12ed89c852bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/feature-gate-const_panic.rs @@ -0,0 +1,11 @@ +fn main() {} + +const Z: () = panic!("cheese"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +const Y: () = unreachable!(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +const X: () = unimplemented!(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/generic-slice.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/generic-slice.rs new file mode 100644 index 000000000000..de2235b16353 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/generic-slice.rs @@ -0,0 +1,32 @@ +// Several variants of #64945. + +// This struct is not important, we just use it to put `T` and `'a` in scope for our associated +// consts. +struct Generic<'a, T>(std::marker::PhantomData<&'a T>); + +impl<'a, T: 'static> Generic<'a, T> { + const EMPTY_SLICE: &'a [T] = { + let x: &'a [T] = &[]; + x + }; + + const EMPTY_SLICE_REF: &'a &'static [T] = { + let x: &'static [T] = &[]; + &x +// { dg-error ".E0597." "" { target *-*-* } .-1 } + }; +} + +static mut INTERIOR_MUT_AND_DROP: &'static [std::cell::RefCell>] = { + let x: &[_] = &[]; + x +}; + +static mut INTERIOR_MUT_AND_DROP_REF: &'static &'static [std::cell::RefCell>] = { + let x: &[_] = &[]; + &x +// { dg-error ".E0597." "" { target *-*-* } .-1 } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/ice-generic-assoc-const.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ice-generic-assoc-const.rs new file mode 100644 index 000000000000..41999d47be2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ice-generic-assoc-const.rs @@ -0,0 +1,17 @@ +// build-pass (tests post-monomorphisation failure) +#![crate_type = "lib"] + +pub trait Nullable { + const NULL: Self; + + fn is_null(&self) -> bool; +} + +impl Nullable for *const T { + const NULL: Self = core::ptr::null::(); + + fn is_null(&self) -> bool { + *self == Self::NULL + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/ice-packed.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ice-packed.rs new file mode 100644 index 000000000000..50ef8cf1b151 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ice-packed.rs @@ -0,0 +1,22 @@ +// Regression test for #50356: Compiler panic when using repr(packed) +// associated constant in a match arm + +// check-pass +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(packed)] +pub struct Num(u64); + +impl Num { + pub const ZERO: Self = Num(0); +} + +pub fn decrement(a: Num) -> Num { + match a { + Num::ZERO => Num::ZERO, + a => Num(a.0 - 1) + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/index-out-of-bounds-never-type.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/index-out-of-bounds-never-type.rs new file mode 100644 index 000000000000..218190d36577 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/index-out-of-bounds-never-type.rs @@ -0,0 +1,23 @@ +// build-fail + +// Regression test for #66975 +#![warn(const_err, unconditional_panic)] +#![feature(never_type)] + +struct PrintName(T); + +impl PrintName { + const VOID: ! = { let x = 0 * std::mem::size_of::(); [][x] }; +// { dg-warning "" "" { target *-*-* } .-1 } + +} + +fn f() { + let _ = PrintName::::VOID; +// { dg-error "" "" { target *-*-* } .-1 } +} + +pub fn main() { + f::<()>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/index_out_of_bounds.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/index_out_of_bounds.rs new file mode 100644 index 000000000000..e7669fe42b9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/index_out_of_bounds.rs @@ -0,0 +1,5 @@ +static FOO: i32 = [][0]; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/index_out_of_bounds_propagated.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/index_out_of_bounds_propagated.rs new file mode 100644 index 000000000000..ccf5ab3175b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/index_out_of_bounds_propagated.rs @@ -0,0 +1,7 @@ +// build-fail + +fn main() { + let array = [std::env::args().len()]; + array[1]; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/infinite_loop.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/infinite_loop.rs new file mode 100644 index 000000000000..2fee203347ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/infinite_loop.rs @@ -0,0 +1,13 @@ +fn main() { + // Tests the Collatz conjecture with an incorrect base case (0 instead of 1). + // The value of `n` will loop indefinitely (4 - 2 - 1 - 4). + let _ = [(); { + let mut n = 113383; // #20 in https://oeis.org/A006884 + while n != 0 { + n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + } + n + }]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-43197.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-43197.rs new file mode 100644 index 000000000000..c93f0635d912 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-43197.rs @@ -0,0 +1,20 @@ +// build-fail + +#![warn(const_err)] + +const fn foo(x: u32) -> u32 { + x +} + +fn main() { + const X: u32 = 0 - 1; +// { dg-warning "" "" { target *-*-* } .-1 } + const Y: u32 = foo(0 - 1); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{} {}", X, Y); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } +// { dg-warning ".E0080." "" { target *-*-* } .-3 } +// { dg-warning ".E0080." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-44578.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-44578.rs new file mode 100644 index 000000000000..25d32a5e4875 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-44578.rs @@ -0,0 +1,30 @@ +// build-fail + +#![allow(const_err)] + +trait Foo { + const AMT: usize; +} + +enum Bar { + First(A), + Second(B), +} + +impl Foo for Bar { + const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize]; +} + +impl Foo for u8 { + const AMT: usize = 1; +} + +impl Foo for u16 { + const AMT: usize = 2; +} + +fn main() { + println!("{}", as Foo>::AMT); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-47971.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-47971.rs new file mode 100644 index 000000000000..27e64d50bd57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-47971.rs @@ -0,0 +1,10 @@ +// check-pass + +struct S(pub &'static u32, pub u32); + +const fn g(ss: &S) -> &u32 { &ss.1 } + +static T: S = S(g(&T), 0); + +fn main () { } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-49296.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-49296.rs new file mode 100644 index 000000000000..5f9b82f51cc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-49296.rs @@ -0,0 +1,25 @@ +// issue-49296: Unsafe shenigans in constants can result in missing errors + +#![feature(const_fn)] +#![feature(const_fn_union)] + +const unsafe fn transmute(t: T) -> U { + #[repr(C)] + union Transmute { + from: T, + to: U, + } + + Transmute { from: t }.to +} + +const fn wat(x: u64) -> &'static u64 { + unsafe { transmute(&x) } +} +const X: u64 = *wat(42); +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + println!("{}", X); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-50706.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-50706.rs new file mode 100644 index 000000000000..4b6c50b6ee64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-50706.rs @@ -0,0 +1,38 @@ +// check-pass + +pub struct Stats; + +#[derive(PartialEq, Eq)] +pub struct StatVariant { + pub id: u8, + _priv: (), +} + +#[derive(PartialEq, Eq)] +pub struct Stat { + pub variant: StatVariant, + pub index: usize, + _priv: (), +} + +impl Stats { + pub const TEST: StatVariant = StatVariant{id: 0, _priv: (),}; + #[allow(non_upper_case_globals)] + pub const A: Stat = Stat{ + variant: Self::TEST, + index: 0, + _priv: (),}; +} + +impl Stat { + pub fn from_index(variant: StatVariant, index: usize) -> Option { + let stat = Stat{variant, index, _priv: (),}; + match stat { + Stats::A => Some(Stats::A), + _ => None, + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-50814-2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-50814-2.rs new file mode 100644 index 000000000000..a0d8028cf10e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-50814-2.rs @@ -0,0 +1,35 @@ +// build-fail + +trait C { + const BOO: usize; +} + +trait Foo { + const BAR: usize; +} + +struct A(T); + +impl Foo for A { + const BAR: usize = [5, 6, 7][T::BOO]; // { dg-error "" "" { target *-*-* } } +} + +fn foo() -> &'static usize { + & as Foo>::BAR // { dg-error ".E0080." "" { target *-*-* } } +} + +impl C for () { + const BOO: usize = 42; +} + +impl C for u32 { + const BOO: usize = 1; +} + +fn main() { + println!("{:x}", foo::<()>() as *const usize as usize); + println!("{:x}", foo::() as *const usize as usize); + println!("{:x}", foo::<()>()); + println!("{:x}", foo::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-50814.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-50814.rs new file mode 100644 index 000000000000..304da431b7a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-50814.rs @@ -0,0 +1,27 @@ +// build-fail + +trait Unsigned { + const MAX: u8; +} + +struct U8(u8); +impl Unsigned for U8 { + const MAX: u8 = 0xff; +} + +struct Sum(A,B); + +impl Unsigned for Sum { + const MAX: u8 = A::MAX + B::MAX; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn foo(_: T) -> &'static u8 { + &Sum::::MAX +// { dg-error ".E0080." "" { target *-*-* } .-1 } +} + +fn main() { + foo(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-51300.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-51300.rs new file mode 100644 index 000000000000..a2274783ca8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-51300.rs @@ -0,0 +1,32 @@ +// check-pass +// https://github.com/rust-lang/rust/issues/51300 + +#[derive(PartialEq, Eq, Clone, Copy)] +pub struct Stat { + pub id: u8, + pub index: usize, +} + +impl Stat { + pub const STUDENT_HAPPINESS: Stat = Stat{ + id: 0, + index: 0, + }; + pub const STUDENT_HUNGER: Stat = Stat{ + id: 0, + index: Self::STUDENT_HAPPINESS.index + 1, + }; + +} + +pub fn from_index(id: u8, index: usize) -> Option { + let stat = Stat{id, index}; + match stat { + Stat::STUDENT_HAPPINESS => Some(Stat::STUDENT_HAPPINESS), + Stat::STUDENT_HUNGER => Some(Stat::STUDENT_HUNGER), + _ => None, + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-52442.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-52442.rs new file mode 100644 index 000000000000..b7bfa60a1ac1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-52442.rs @@ -0,0 +1,6 @@ +fn main() { + [(); { &loop { break } as *const _ as usize } ]; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-52475.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-52475.rs new file mode 100644 index 000000000000..43efe79bab18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-52475.rs @@ -0,0 +1,12 @@ +fn main() { + let _ = [(); { + let mut x = &0; + let mut n = 0; + while n < 5 { + n = (n + 1) % 5; // { dg-error ".E0080." "" { target *-*-* } } + x = &0; // Materialize a new AllocId + } + 0 + }]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-53157.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-53157.rs new file mode 100644 index 000000000000..1598cb4769ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-53157.rs @@ -0,0 +1,14 @@ +// check-pass + +macro_rules! m { + () => {{ + fn f(_: impl Sized) {} + f + }} +} + +fn main() { + fn f() -> impl Sized {}; + m!()(f()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-53401.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-53401.rs new file mode 100644 index 000000000000..4b3f80e34f63 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-53401.rs @@ -0,0 +1,12 @@ +// check-pass + +pub const STATIC_TRAIT: &dyn Test = &(); + +fn main() {} + +pub trait Test { + fn test() where Self: Sized {} +} + +impl Test for () {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-55541.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-55541.rs new file mode 100644 index 000000000000..413b3f0947bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-55541.rs @@ -0,0 +1,28 @@ +// check-pass + +// Test that we can handle newtypes wrapping extern types + +#![feature(extern_types)] + +use std::marker::PhantomData; + +extern "C" { + pub type ExternType; +} +unsafe impl Sync for ExternType {} +static MAGIC_FFI_STATIC: u8 = 42; + +#[repr(transparent)] +pub struct Wrapper(ExternType); +pub static MAGIC_FFI_REF: &'static Wrapper = unsafe { + std::mem::transmute(&MAGIC_FFI_STATIC) +}; + +#[repr(transparent)] +pub struct Wrapper2(PhantomData>, ExternType); +pub static MAGIC_FFI_REF2: &'static Wrapper2 = unsafe { + std::mem::transmute(&MAGIC_FFI_STATIC) +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-64908.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-64908.rs new file mode 100644 index 000000000000..a1ce8e31c97c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-64908.rs @@ -0,0 +1,21 @@ +// run-pass + +// This test verifies that the `ConstProp` pass doesn't cause an ICE when evaluating polymorphic +// promoted MIR. + +pub trait ArrowPrimitiveType { + type Native; +} + +pub fn new() { + assert_eq!(0, std::mem::size_of::()); +} + +impl ArrowPrimitiveType for () { + type Native = (); +} + +fn main() { + new::<()>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-64970.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-64970.rs new file mode 100644 index 000000000000..239ce30a25a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-64970.rs @@ -0,0 +1,16 @@ +// run-pass + +fn main() { + foo(10); +} + +fn foo(mut n: i32) { + if false { + n = 0i32; + } + + if n > 0i32 { + let _ = 1i32 / n; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-65394.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-65394.rs new file mode 100644 index 000000000000..9ac82b66f228 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-65394.rs @@ -0,0 +1,14 @@ +// This test originated from #65394. We conservatively assume that `x` is still `LiveDrop` even +// after it has been moved because a mutable reference to it exists at some point in the const body. +// +// We will likely have to change this behavior before we allow `&mut` in a `const`. + +const _: Vec = { + let mut x = Vec::::new(); // { dg-error ".E0493." "" { target *-*-* } } + let r = &mut x; // { dg-error ".E0764." "" { target *-*-* } } + let y = x; + y +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-70723.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-70723.rs new file mode 100644 index 000000000000..24663ce5cd9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-70723.rs @@ -0,0 +1,4 @@ +static _X: () = loop {}; // { dg-error ".E0080." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-70804-fn-subtyping.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-70804-fn-subtyping.rs new file mode 100644 index 000000000000..a30f6bff3b29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/issue-70804-fn-subtyping.rs @@ -0,0 +1,11 @@ +// check-pass +#![feature(const_fn_fn_ptr_basics)] + +const fn nested(x: (for<'a> fn(&'a ()), String)) -> (fn(&'static ()), String) { + x +} + +pub const TEST: (fn(&'static ()), String) = nested((|_x| (), String::new())); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/livedrop.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/livedrop.rs new file mode 100644 index 000000000000..2520baa07bea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/livedrop.rs @@ -0,0 +1,18 @@ +const _: Option> = { + let mut never_returned = Some(Vec::new()); + let mut always_returned = None; // { dg-error ".E0493." "" { target *-*-* } } + + let mut i = 0; + loop { + always_returned = never_returned; + never_returned = None; + + i += 1; + if i == 10 { + break always_returned; + } + } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/match-test-ptr-null.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/match-test-ptr-null.rs new file mode 100644 index 000000000000..73a32bb81743 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/match-test-ptr-null.rs @@ -0,0 +1,14 @@ +fn main() { + // Make sure match uses the usual pointer comparison code path -- i.e., it should complain + // that pointer comparison is disallowed, not that parts of a pointer are accessed as raw + // bytes. + let _: [u8; 0] = [4; { + match &1 as *const i32 as usize { +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } + 0 => 42, + n => n, + } + }]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/mod-static-with-const-fn.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/mod-static-with-const-fn.rs new file mode 100644 index 000000000000..c23ad46a5945 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/mod-static-with-const-fn.rs @@ -0,0 +1,23 @@ +// New test for #53818: modifying static memory at compile-time is not allowed. +// The test should never compile successfully + +#![feature(const_raw_ptr_deref)] + +use std::cell::UnsafeCell; + +struct Foo(UnsafeCell); + +unsafe impl Send for Foo {} +unsafe impl Sync for Foo {} + +static FOO: Foo = Foo(UnsafeCell::new(42)); + +static BAR: () = unsafe { + *FOO.0.get() = 5; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +}; + +fn main() { + println!("{}", unsafe { *FOO.0.get() }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/no_lint_for_statically_known_error.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/no_lint_for_statically_known_error.rs new file mode 100644 index 000000000000..54dd5bd9a839 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/no_lint_for_statically_known_error.rs @@ -0,0 +1,19 @@ +// check-pass + +// if `X` were used instead of `x`, `X - 10` would result in a lint. +// This file should never produce a lint, no matter how the const +// propagator is improved. + +#![deny(warnings)] + +const X: u32 = 5; + +fn main() { + let x = X; + if x > 10 { + println!("{}", x - 10); + } else { + println!("{}", 10 - x); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/nrvo.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/nrvo.rs new file mode 100644 index 000000000000..e985c66d2d07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/nrvo.rs @@ -0,0 +1,27 @@ +// run-pass + +// When the NRVO is applied, the return place (`_0`) gets treated like a normal local. For example, +// its address may be taken and it may be written to indirectly. Ensure that MIRI can handle this. + +#![feature(const_mut_refs)] + +#[inline(never)] // Try to ensure that MIR optimizations don't optimize this away. +const fn init(buf: &mut [u8; 1024]) { + buf[33] = 3; + buf[444] = 4; +} + +const fn nrvo() -> [u8; 1024] { + let mut buf = [0; 1024]; + init(&mut buf); + buf +} + +const BUF: [u8; 1024] = nrvo(); + +fn main() { + assert_eq!(BUF[33], 3); + assert_eq!(BUF[19], 0); + assert_eq!(BUF[444], 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/panic-assoc-never-type.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/panic-assoc-never-type.rs new file mode 100644 index 000000000000..c5c2a8a31d9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/panic-assoc-never-type.rs @@ -0,0 +1,19 @@ +// build-fail + +// Regression test for #66975 +#![warn(const_err)] +#![feature(const_panic)] +#![feature(never_type)] + +struct PrintName; + +impl PrintName { + const VOID: ! = panic!(); +// { dg-warning "" "" { target *-*-* } .-1 } +} + +fn main() { + let _ = PrintName::VOID; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/panic-never-type.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/panic-never-type.rs new file mode 100644 index 000000000000..c12bf33e6935 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/panic-never-type.rs @@ -0,0 +1,15 @@ +// build-fail + +// Regression test for #66975 +#![warn(const_err)] +#![feature(const_panic)] +#![feature(never_type)] + +const VOID: ! = panic!(); +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() { + let _ = VOID; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/promote-static.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/promote-static.rs new file mode 100644 index 000000000000..173f8d79765f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/promote-static.rs @@ -0,0 +1,15 @@ +// regression test for #67609. + +// check-pass + +static NONE: Option = None; + +static NONE_REF_REF: &&Option = { + let x = &&NONE; + x +}; + +fn main() { + println!("{:?}", NONE_REF_REF); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs new file mode 100644 index 000000000000..5bd50a42418a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs @@ -0,0 +1,6 @@ +// check-pass + +pub fn main() { + let y: &'static mut [u8; 0] = &mut []; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_const_fn_fail.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_const_fn_fail.rs new file mode 100644 index 000000000000..1739d9c96874 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_const_fn_fail.rs @@ -0,0 +1,25 @@ +#![feature(const_fn, const_fn_union)] + +#![allow(const_err)] + +#[repr(C)] +union Bar { + a: &'static u8, + b: usize, +} + +const fn bar() -> u8 { + unsafe { + // this will error as long as this test + // is run on a system whose pointers need more + // than 8 bits + Bar { a: &42 }.b as u8 + } +} + +fn main() { + let x: &'static u8 = &(bar() + 1); // { dg-error ".E0716." "" { target *-*-* } } + let y = *x; + unreachable!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs new file mode 100644 index 000000000000..be26b8013f5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs @@ -0,0 +1,27 @@ +#![feature(const_fn, const_fn_union)] + +#![deny(const_err)] + +#[repr(C)] +union Bar { + a: &'static u8, + b: usize, +} + +const fn bar() -> u8 { + unsafe { + // This will error as long as this test is run on a system whose + // pointers need more than 8 bits. + Bar { a: &42 }.b as u8 + } +} + +fn main() { + // This will compile, but then hard-abort at runtime. + // FIXME(oli-obk): this should instead panic (not hard-abort) at runtime. + let x: &'static u8 = &(bar() + 1); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let y = *x; + unreachable!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_errors.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_errors.rs new file mode 100644 index 000000000000..bd9450c72831 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_errors.rs @@ -0,0 +1,29 @@ +// revisions: noopt opt opt_with_overflow_checks +//[noopt]compile-flags: -C opt-level=0 +//[opt]compile-flags: -O +//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O + +// build-pass +// ignore-pass (test emits codegen-time warnings and verifies that they are not errors) + +#![warn(const_err, arithmetic_overflow, unconditional_panic)] + +fn main() { + println!("{}", 0u32 - 1); +// { dg-warning "" "" { target *-*-* } .-1 } + let _x = 0u32 - 1; +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{}", 1 / (1 - 1)); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + let _x = 1 / (1 - 1); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{}", 1 / (false as u32)); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + let _x = 1 / (false as u32); +// { dg-warning "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_raw_ptr_ops.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_raw_ptr_ops.rs new file mode 100644 index 000000000000..10cb705c7926 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/promoted_raw_ptr_ops.rs @@ -0,0 +1,13 @@ +#![feature(const_raw_ptr_to_usize_cast, const_raw_ptr_deref)] + +fn main() { + let x: &'static bool = &(42 as *const i32 == 43 as *const i32); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let y: &'static usize = &(&1 as *const i32 as usize + 1); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let z: &'static i32 = &(unsafe { *(42 as *const i32) }); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let a: &'static bool = &(main as fn() == main as fn()); +// { dg-error ".E0716." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/pub_const_err.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/pub_const_err.rs new file mode 100644 index 000000000000..50046bce608a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/pub_const_err.rs @@ -0,0 +1,10 @@ +// check-pass +#![warn(const_err)] + +#![crate_type = "lib"] + +pub const Z: u32 = 0 - 1; +// { dg-warning "" "" { target *-*-* } .-1 } + +pub type Foo = [i32; 0 - 1]; + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/pub_const_err_bin.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/pub_const_err_bin.rs new file mode 100644 index 000000000000..7588b65e3897 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/pub_const_err_bin.rs @@ -0,0 +1,10 @@ +// check-pass +#![warn(const_err)] + +pub const Z: u32 = 0 - 1; +// { dg-warning "" "" { target *-*-* } .-1 } + +pub type Foo = [i32; 0 - 1]; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/ref_to_int_match.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ref_to_int_match.rs new file mode 100644 index 000000000000..282d0fa3f08c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ref_to_int_match.rs @@ -0,0 +1,26 @@ +#![feature(const_fn_union)] + +fn main() { + let n: Int = 40; + match n { + 0..=10 => {}, + 10..=BAR => {}, // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + _ => {}, + } +} + +#[repr(C)] +union Foo { + f: Int, + r: &'static u32, +} + +#[cfg(target_pointer_width="64")] +type Int = u64; + +#[cfg(target_pointer_width="32")] +type Int = u32; + +const BAR: Int = unsafe { Foo { r: &42 }.f }; // { dg-error ".E0080." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/shift_overflow.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/shift_overflow.rs new file mode 100644 index 000000000000..33e0585544d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/shift_overflow.rs @@ -0,0 +1,10 @@ +enum Foo { + // test that we detect overflows for non-u32 discriminants + X = 1 << ((u32::MAX as u64) + 1), // { dg-error ".E0080." "" { target *-*-* } } + Y = 42, +} + + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/simd/insert_extract.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/simd/insert_extract.rs new file mode 100644 index 000000000000..f3ec06eab1bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/simd/insert_extract.rs @@ -0,0 +1,58 @@ +// run-pass +#![feature(const_fn)] +#![feature(repr_simd)] +#![feature(platform_intrinsics)] +#![feature(staged_api)] +#![stable(feature = "foo", since = "1.33.7")] +#![allow(non_camel_case_types)] + +#[repr(simd)] struct i8x1(i8); +#[repr(simd)] struct u16x2(u16, u16); +#[repr(simd)] struct f32x3(f32, f32, f32); + +extern "platform-intrinsic" { + #[rustc_const_stable(feature = "foo", since = "1.3.37")] + fn simd_insert(x: T, idx: u32, val: U) -> T; + #[rustc_const_stable(feature = "foo", since = "1.3.37")] + fn simd_extract(x: T, idx: u32) -> U; +} + +fn main() { + { + const U: i8x1 = i8x1(13); + const V: i8x1 = unsafe { simd_insert(U, 0_u32, 42_i8) }; + const X0: i8 = V.0; + const Y0: i8 = unsafe { simd_extract(V, 0) }; + assert_eq!(X0, 42); + assert_eq!(Y0, 42); + } + { + const U: u16x2 = u16x2(13, 14); + const V: u16x2 = unsafe { simd_insert(U, 1_u32, 42_u16) }; + const X0: u16 = V.0; + const X1: u16 = V.1; + const Y0: u16 = unsafe { simd_extract(V, 0) }; + const Y1: u16 = unsafe { simd_extract(V, 1) }; + assert_eq!(X0, 13); + assert_eq!(X1, 42); + assert_eq!(Y0, 13); + assert_eq!(Y1, 42); + } + { + const U: f32x3 = f32x3(13., 14., 15.); + const V: f32x3 = unsafe { simd_insert(U, 1_u32, 42_f32) }; + const X0: f32 = V.0; + const X1: f32 = V.1; + const X2: f32 = V.2; + const Y0: f32 = unsafe { simd_extract(V, 0) }; + const Y1: f32 = unsafe { simd_extract(V, 1) }; + const Y2: f32 = unsafe { simd_extract(V, 2) }; + assert_eq!(X0, 13.); + assert_eq!(X1, 42.); + assert_eq!(X2, 15.); + assert_eq!(Y0, 13.); + assert_eq!(Y1, 42.); + assert_eq!(Y2, 15.); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/simple_with_undef.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/simple_with_undef.rs new file mode 100644 index 000000000000..4b3b97094e4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/simple_with_undef.rs @@ -0,0 +1,7 @@ +// check-pass + +const PARSE_BOOL: Option<&'static str> = None; +static FOO: (Option<&str>, u32) = (PARSE_BOOL, 42); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/strlen.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/strlen.rs new file mode 100644 index 000000000000..be8a71b027bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/strlen.rs @@ -0,0 +1,32 @@ +// run-pass + +const S: &str = "foo"; +pub const B: &[u8] = S.as_bytes(); +pub const C: usize = B.len(); +pub const D: bool = B.is_empty(); +pub const E: bool = S.is_empty(); +pub const F: usize = S.len(); + +pub fn foo() -> [u8; S.len()] { + let mut buf = [0; S.len()]; + for (i, &c) in S.as_bytes().iter().enumerate() { + buf[i] = c; + } + buf +} + +fn main() { + assert_eq!(&foo()[..], b"foo"); + assert_eq!(foo().len(), S.len()); + const LEN: usize = S.len(); + assert_eq!(LEN, S.len()); + assert_eq!(B, foo()); + assert_eq!(B, b"foo"); + assert_eq!(C, 3); + assert_eq!(F, 3); + assert!(!D); + assert!(!E); + const EMPTY: bool = "".is_empty(); + assert!(EMPTY); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/transmute-const-promotion.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/transmute-const-promotion.rs new file mode 100644 index 000000000000..60c9bd584d83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/transmute-const-promotion.rs @@ -0,0 +1,9 @@ +#![feature(const_transmute)] + +use std::mem; + +fn main() { + let x: &'static u32 = unsafe { &mem::transmute(3.0f32) }; +// { dg-error ".E0716." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/transmute-const.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/transmute-const.rs new file mode 100644 index 000000000000..f013b3f918c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/transmute-const.rs @@ -0,0 +1,7 @@ +use std::mem; + +static FOO: bool = unsafe { mem::transmute(3u8) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-enum.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-enum.rs new file mode 100644 index 000000000000..8dde2357c120 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-enum.rs @@ -0,0 +1,99 @@ +// normalize-stderr-64bit "0x0000000000" -> "0x00" +#![feature(never_type)] +#![allow(const_err)] // make sure we cannot allow away the errors tested here + +use std::mem; + +#[repr(transparent)] +#[derive(Copy, Clone)] +struct Wrap(T); + +#[derive(Copy, Clone)] +enum Never {} + +// # simple enum with discriminant 0 + +#[repr(usize)] +#[derive(Copy, Clone)] +enum Enum { + A = 0, +} + +const GOOD_ENUM: Enum = unsafe { mem::transmute(0usize) }; + +const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +const BAD_ENUM_WRAPPED: Wrap = unsafe { mem::transmute(&1) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// # simple enum with discriminant 2 + +// (Potentially) invalid enum discriminant +#[repr(usize)] +#[derive(Copy, Clone)] +enum Enum2 { + A = 2, +} + +const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// something wrapping the enum so that we test layout first, not enum +const BAD_ENUM2_WRAPPED: Wrap = unsafe { mem::transmute(&0) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// Undef enum discriminant. +#[repr(C)] +union MaybeUninit { + uninit: (), + init: T, +} +const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// Pointer value in an enum with a niche that is not just 0. +const BAD_ENUM2_OPTION_PTR: Option = unsafe { mem::transmute(&0) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// # valid discriminant for uninhabited variant + +// An enum with 3 variants of which some are uninhabited -- so the uninhabited variants *do* +// have a discriminant. +enum UninhDiscriminant { + A, + B(!), + C, + D(Never), +} + +const GOOD_INHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(0u8) }; // variant A +const GOOD_INHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(2u8) }; // variant C + +const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// # other + +// Invalid enum field content (mostly to test printing of paths for enum tuple +// variants and tuples). +// Need to create something which does not clash with enum layout optimizations. +const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) })); +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// All variants are uninhabited but also have data. +// Use `0` as constant to make behavior endianess-independent. +const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-int-array.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-int-array.rs new file mode 100644 index 000000000000..9f7c0bc95daa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-int-array.rs @@ -0,0 +1,65 @@ +#![allow(const_err)] // make sure we cannot allow away the errors tested here + +//! Test the "array of int" fast path in validity checking, and in particular whether it +//! points at the right array element. + +use std::mem; + +#[repr(C)] +union MaybeUninit { + uninit: (), + init: T, +} + +const UNINIT_INT_0: [u32; 3] = unsafe { +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } + [ + MaybeUninit { uninit: () }.init, + 1, + 2, + ] +}; +const UNINIT_INT_1: [u32; 3] = unsafe { +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } + mem::transmute( + [ + 0u8, + 0u8, + 0u8, + 0u8, + 1u8, + MaybeUninit { uninit: () }.init, + 1u8, + 1u8, + 2u8, + 2u8, + MaybeUninit { uninit: () }.init, + 2u8, + ] + ) +}; +const UNINIT_INT_2: [u32; 3] = unsafe { +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } + mem::transmute( + [ + 0u8, + 0u8, + 0u8, + 0u8, + 1u8, + 1u8, + 1u8, + 1u8, + 2u8, + 2u8, + 2u8, + MaybeUninit { uninit: () }.init, + ] + ) +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-nonnull.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-nonnull.rs new file mode 100644 index 000000000000..089acf1dcf80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-nonnull.rs @@ -0,0 +1,50 @@ +#![feature(rustc_attrs)] +#![allow(const_err, invalid_value)] // make sure we cannot allow away the errors tested here + +use std::mem; +use std::ptr::NonNull; +use std::num::{NonZeroU8, NonZeroUsize}; + +const NON_NULL: NonNull = unsafe { mem::transmute(1usize) }; +const NON_NULL_PTR: NonNull = unsafe { mem::transmute(&1) }; + +const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +#[deny(const_err)] // this triggers a `const_err` so validation does not even happen +const OUT_OF_BOUNDS_PTR: NonNull = { unsafe { + let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle + // Use address-of-element for pointer arithmetic. This could wrap around to NULL! + let out_of_bounds_ptr = &ptr[255]; // { dg-error "" "" { target *-*-* } } + mem::transmute(out_of_bounds_ptr) +} }; + +const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +#[repr(C)] +union MaybeUninit { + uninit: (), + init: T, +} +const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// Also test other uses of rustc_layout_scalar_valid_range_start + +#[rustc_layout_scalar_valid_range_start(10)] +#[rustc_layout_scalar_valid_range_end(30)] +struct RestrictedRange1(u32); +const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +#[rustc_layout_scalar_valid_range_start(30)] +#[rustc_layout_scalar_valid_range_end(10)] +struct RestrictedRange2(u32); +const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-ref.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-ref.rs new file mode 100644 index 000000000000..07e06220c760 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-ref.rs @@ -0,0 +1,39 @@ +// ignore-tidy-linelength +#![allow(const_err, invalid_value)] // make sure we cannot allow away the errors tested here + +use std::mem; + +const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } + +const UNALIGNED_BOX: Box = unsafe { mem::transmute(&[0u8; 4]) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } + +const NULL: &u16 = unsafe { mem::transmute(0usize) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// It is very important that we reject this: We do promote `&(4 * REF_AS_USIZE)`, +// but that would fail to compile; so we ended up breaking user code that would +// have worked fine had we not promoted. +const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-uninhabit.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-uninhabit.rs new file mode 100644 index 000000000000..732d7e25c9b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-uninhabit.rs @@ -0,0 +1,24 @@ +#![allow(const_err)] // make sure we cannot allow away the errors tested here + +use std::mem; + +#[derive(Copy, Clone)] +enum Bar {} + +#[repr(C)] +union MaybeUninit { + uninit: (), + init: T, +} + +const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-upvars.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-upvars.rs new file mode 100644 index 000000000000..8c4e6e18dc8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-upvars.rs @@ -0,0 +1,12 @@ +#![allow(const_err, invalid_value)] // make sure we cannot allow away the errors tested here + +use std::mem; + +const BAD_UPVAR: &dyn FnOnce() = &{ // { dg-error ".E0080." "" { target *-*-* } } + let bad_ref: &'static u16 = unsafe { mem::transmute(0usize) }; + let another_var = 13; + move || { let _ = bad_ref; let _ = another_var; } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-wide-ptr.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-wide-ptr.rs new file mode 100644 index 000000000000..ffcc6853de81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/ub-wide-ptr.rs @@ -0,0 +1,137 @@ +// ignore-tidy-linelength +#![allow(unused)] +#![allow(const_err)] // make sure we cannot allow away the errors tested here + +use std::mem; + +// normalize-stderr-test "offset \d+" -> "offset N" +// normalize-stderr-test "alloc\d+" -> "allocN" +// normalize-stderr-test "size \d+" -> "size N" + +#[repr(C)] +union MaybeUninit { + uninit: (), + init: T, +} + +trait Trait {} +impl Trait for bool {} + +// custom unsized type +struct MyStr(str); + +// custom unsized type with sized fields +struct MySlice(bool, T); +type MySliceBool = MySlice<[bool]>; + +// # str +// OK +const STR_VALID: &str = unsafe { mem::transmute((&42u8, 1usize)) }; +// bad str +const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// bad str +const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// bad str in user-defined unsized type +const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// uninitialized byte +const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// uninitialized byte in user-defined str-like +const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// # slice +// OK +const SLICE_VALID: &[u8] = unsafe { mem::transmute((&42u8, 1usize)) }; +// bad slice: length uninit +const SLICE_LENGTH_UNINIT: &[u8] = unsafe { +// { dg-error ".E0080." "" { target *-*-* } .-1 } + let uninit_len = MaybeUninit:: { uninit: () }; + mem::transmute((42, uninit_len)) +}; +// bad slice: length too big +const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// bad slice: length not an int +const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// bad slice box: length too big +const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// bad slice box: length not an int +const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// bad data *inside* the slice +const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// good MySliceBool +const MYSLICE_GOOD: &MySliceBool = &MySlice(true, [false]); +// bad: sized field is not okay +const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// bad: unsized part is not okay +const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// # raw slice +const RAW_SLICE_VALID: *const [u8] = unsafe { mem::transmute((&42u8, 1usize)) }; // ok +const RAW_SLICE_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, 999usize)) }; // ok because raw +const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, usize::MAX)) }; // ok because raw +const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { +// { dg-error ".E0080." "" { target *-*-* } .-1 } + let uninit_len = MaybeUninit:: { uninit: () }; + mem::transmute((42, uninit_len)) +}; + +// # trait object +// bad trait object +const TRAIT_OBJ_SHORT_VTABLE_1: &dyn Trait = unsafe { mem::transmute((&92u8, &3u8)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// bad trait object +const TRAIT_OBJ_SHORT_VTABLE_2: &dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// bad trait object +const TRAIT_OBJ_INT_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, 4usize)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: &dyn Trait = unsafe { mem::transmute((&92u8, &[&42u8; 8])) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// bad data *inside* the trait object +const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// # raw trait object +const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const RAW_TRAIT_OBJ_CONTENT_INVALID: *const dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) } as *const dyn Trait; // ok because raw + +// Const eval fails for these, so they need to be statics to error. +static mut RAW_TRAIT_OBJ_VTABLE_NULL_THROUGH_REF: *const dyn Trait = unsafe { + mem::transmute::<_, &dyn Trait>((&92u8, 0usize)) +// { dg-error ".E0080." "" { target *-*-* } .-1 } +}; +static mut RAW_TRAIT_OBJ_VTABLE_INVALID_THROUGH_REF: *const dyn Trait = unsafe { + mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) +// { dg-error ".E0080." "" { target *-*-* } .-1 } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/union-const-eval-field.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/union-const-eval-field.rs new file mode 100644 index 000000000000..479028c3f0ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/union-const-eval-field.rs @@ -0,0 +1,38 @@ +#![feature(const_fn)] + +type Field1 = i32; +type Field2 = f32; +type Field3 = i64; + +#[repr(C)] +union DummyUnion { + field1: Field1, + field2: Field2, + field3: Field3, +} + +const FLOAT1_AS_I32: i32 = 1065353216; +const UNION: DummyUnion = DummyUnion { field1: FLOAT1_AS_I32 }; + +const fn read_field1() -> Field1 { + const FIELD1: Field1 = unsafe { UNION.field1 }; + FIELD1 +} + +const fn read_field2() -> Field2 { + const FIELD2: Field2 = unsafe { UNION.field2 }; + FIELD2 +} + +const fn read_field3() -> Field3 { + const FIELD3: Field3 = unsafe { UNION.field3 }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + FIELD3 +} + +fn main() { + assert_eq!(read_field1(), FLOAT1_AS_I32); + assert_eq!(read_field2(), 1.0); + assert_eq!(read_field3(), unsafe { UNION.field3 }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/union-ice.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/union-ice.rs new file mode 100644 index 000000000000..25662c512115 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/union-ice.rs @@ -0,0 +1,43 @@ +#![feature(const_fn)] + +type Field1 = i32; +type Field3 = i64; + +#[repr(C)] +union DummyUnion { + field1: Field1, + field3: Field3, +} + +const UNION: DummyUnion = DummyUnion { field1: 1065353216 }; + +const FIELD3: Field3 = unsafe { UNION.field3 }; // { dg-error ".E0080." "" { target *-*-* } } + +const FIELD_PATH: Struct = Struct { // { dg-error ".E0080." "" { target *-*-* } } + a: 42, + b: unsafe { UNION.field3 }, +}; + +struct Struct { + a: u8, + b: Field3, +} + +const FIELD_PATH2: Struct2 = Struct2 { // { dg-error ".E0080." "" { target *-*-* } } + b: [ + 21, + unsafe { UNION.field3 }, + 23, + 24, + ], + a: 42, +}; + +struct Struct2 { + b: [Field3; 4], + a: u8, +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/union-ub.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/union-ub.rs new file mode 100644 index 000000000000..8e7bd29ac9c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/union-ub.rs @@ -0,0 +1,43 @@ +#![allow(const_err)] // make sure we cannot allow away the errors tested here + +#[repr(C)] +union DummyUnion { + unit: (), + u8: u8, + bool: bool, +} + +#[repr(C)] +#[derive(Copy, Clone)] +enum Enum { + A, + B, + C, +} + +#[derive(Copy, Clone)] +#[repr(C)] +union Foo { + a: bool, + b: Enum, +} + +#[repr(C)] +union Bar { + foo: Foo, + u8: u8, +} + +// the value is not valid for bools +const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool}; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool}; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// The value is not valid for any union variant, but that's fine +// unions are just a convenient way to transmute bits around +const BAD_UNION: Foo = unsafe { Bar { u8: 42 }.foo }; + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/union_promotion.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/union_promotion.rs new file mode 100644 index 000000000000..c8fb6f0f675c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/union_promotion.rs @@ -0,0 +1,14 @@ +#![allow(const_err)] + +#[repr(C)] +union Foo { + a: &'static u32, + b: usize, +} + +fn main() { + let x: &'static bool = &unsafe { // { dg-error ".E0716." "" { target *-*-* } } + Foo { a: &1 }.b == Foo { a: &2 }.b + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/unused-broken-const.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/unused-broken-const.rs new file mode 100644 index 000000000000..5d41f265687d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/unused-broken-const.rs @@ -0,0 +1,9 @@ +// make sure that an *unused* broken const triggers an error even in a check build + +// compile-flags: --emit=dep-info,metadata + +const FOO: i32 = [][0]; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/unwind-abort.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/unwind-abort.rs new file mode 100644 index 000000000000..31d3ccd7ae6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/unwind-abort.rs @@ -0,0 +1,14 @@ +#![feature(unwind_attributes, const_panic)] + +#[unwind(aborts)] +const fn foo() { + panic!() // { dg-error ".E0080." "" { target *-*-* } } +} + +const _: () = foo(); // { dg-error "" "" { target *-*-* } } +// Ensure that the CTFE engine handles calls to `#[unwind(aborts)]` gracefully + +fn main() { + let _ = foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/valid-const.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/valid-const.rs new file mode 100644 index 000000000000..b297717dfd53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/valid-const.rs @@ -0,0 +1,19 @@ +// check-pass + +// Some constants that *are* valid +#![deny(const_err)] + +use std::mem; +use std::ptr::NonNull; +use std::num::{NonZeroU8, NonZeroUsize}; + +const NON_NULL_PTR1: NonNull = unsafe { mem::transmute(1usize) }; +const NON_NULL_PTR2: NonNull = unsafe { mem::transmute(&0) }; + +const NON_NULL_U8: NonZeroU8 = unsafe { mem::transmute(1u8) }; +const NON_NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(1usize) }; + +const UNIT: () = (); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/validate_uninhabited_zsts.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/validate_uninhabited_zsts.rs new file mode 100644 index 000000000000..15e312a37edc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/validate_uninhabited_zsts.rs @@ -0,0 +1,25 @@ +#![feature(const_fn)] +#![feature(const_fn_transmute)] + +const fn foo() -> ! { + unsafe { std::mem::transmute(()) } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +#[derive(Clone, Copy)] +enum Empty { } + +#[warn(const_err)] +const FOO: [Empty; 3] = [foo(); 3]; + +#[warn(const_err)] +const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-warning ".E0080." "" { target *-*-* } .-2 } + +fn main() { + FOO; + BAR; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs new file mode 100644 index 000000000000..aaad63345283 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs @@ -0,0 +1,29 @@ +// run-pass + +#![allow(dead_code)] + +enum Empty { } +enum Test1 { + A(u8), + B(Empty), +} +enum Test2 { + A(u8), + B(Empty), + C, +} + +fn bar() -> Option { + None +} + +fn main() { + if let Some(x) = bar() { + Test1::B(x); + } + + if let Some(x) = bar() { + Test2::B(x); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-eval/zst_operand_eval.rs b/gcc/testsuite/rust/rustc/ui/consts/const-eval/zst_operand_eval.rs new file mode 100644 index 000000000000..dc4040afc444 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-eval/zst_operand_eval.rs @@ -0,0 +1,6 @@ +// check-pass + +static ASSERT: () = [()][!(std::mem::size_of::() == 4) as usize]; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-expr-addr-operator.rs b/gcc/testsuite/rust/rustc/ui/consts/const-expr-addr-operator.rs new file mode 100644 index 000000000000..5e33b9ff9d6a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-expr-addr-operator.rs @@ -0,0 +1,12 @@ +// Encountered while testing #44614. +// build-pass (FIXME(62277): could be check-pass?) + +pub fn main() { + // Constant of generic type (int) + const X: &'static u32 = &22; + assert_eq!(0, match &22 { + X => 0, + _ => 1, + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-expr-in-fixed-length-vec.rs b/gcc/testsuite/rust/rustc/ui/consts/const-expr-in-fixed-length-vec.rs new file mode 100644 index 000000000000..f37b17ae2be6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-expr-in-fixed-length-vec.rs @@ -0,0 +1,13 @@ +// run-pass +// Check that constant expressions can be used for declaring the +// type of a fixed length vector. + +// pretty-expanded FIXME #23616 + +pub fn main() { + + const FOO: usize = 2; + let _v: [isize; FOO*3]; + +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-expr-in-vec-repeat.rs b/gcc/testsuite/rust/rustc/ui/consts/const-expr-in-vec-repeat.rs new file mode 100644 index 000000000000..bb9d9f923814 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-expr-in-vec-repeat.rs @@ -0,0 +1,12 @@ +// run-pass +// Check that constant expressions can be used in vec repeat syntax. + +// pretty-expanded FIXME #23616 + +pub fn main() { + + const FOO: usize = 2; + let _v = [0; FOO*3*2/2]; + +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.rs b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.rs new file mode 100644 index 000000000000..a96f2cd12d8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn-call-extern-fn.rs @@ -0,0 +1,24 @@ +#![feature(const_extern_fn)] + +extern "C" { + fn regular_in_block(); +} + +const extern fn bar() { + unsafe { + regular_in_block(); +// { dg-error ".E0015." "" { target *-*-* } .-1 } + } +} + +extern fn regular() {} + +const extern fn foo() { + unsafe { + regular(); +// { dg-error ".E0015." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs new file mode 100644 index 000000000000..a327eb819226 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs @@ -0,0 +1,14 @@ +#![feature(const_extern_fn)] + +const extern fn unsize(x: &[u8; 3]) -> &[u8] { x } +const unsafe extern "C" fn closure() -> fn() { || {} } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +const unsafe extern fn use_float() { 1.0 + 1.0; } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +const extern "C" fn ptr_cast(val: *const u8) { val as usize; } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs new file mode 100644 index 000000000000..44cb500c9d1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs @@ -0,0 +1,11 @@ +#![feature(const_extern_fn)] + +const unsafe extern fn foo() -> usize { 5 } + +fn main() { + let a: [u8; foo()]; +// { dg-error ".E0133." "" { target *-*-* } .-1 } + foo(); +// { dg-error ".E0133." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn.rs b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn.rs new file mode 100644 index 000000000000..eb3b79482d36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/const-extern-fn.rs @@ -0,0 +1,36 @@ +// run-pass +#![feature(const_extern_fn)] + +const extern fn foo1(val: u8) -> u8 { + val + 1 +} + +const extern "C" fn foo2(val: u8) -> u8 { + val + 1 +} + +const unsafe extern fn bar1(val: bool) -> bool { + !val +} + +const unsafe extern "C" fn bar2(val: bool) -> bool { + !val +} + + +fn main() { + let a: [u8; foo1(25) as usize] = [0; 26]; + let b: [u8; foo2(25) as usize] = [0; 26]; + assert_eq!(a, b); + + let bar1_res = unsafe { bar1(false) }; + let bar2_res = unsafe { bar2(false) }; + assert!(bar1_res); + assert_eq!(bar1_res, bar2_res); + + let _foo1_cast: extern fn(u8) -> u8 = foo1; + let _foo2_cast: extern fn(u8) -> u8 = foo2; + let _bar1_cast: unsafe extern fn(bool) -> bool = bar1; + let _bar2_cast: unsafe extern fn(bool) -> bool = bar2; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs new file mode 100644 index 000000000000..5e677f30c1d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/feature-gate-const_extern_fn.rs @@ -0,0 +1,11 @@ +// Check that `const extern fn` and `const unsafe extern fn` are feature-gated. + +const extern fn foo1() {} // { dg-error ".E0658." "" { target *-*-* } } +const extern "C" fn foo2() {} // { dg-error ".E0658." "" { target *-*-* } } +const extern "Rust" fn foo3() {} // { dg-error ".E0658." "" { target *-*-* } } +const unsafe extern fn bar1() {} // { dg-error ".E0658." "" { target *-*-* } } +const unsafe extern "C" fn bar2() {} // { dg-error ".E0658." "" { target *-*-* } } +const unsafe extern "Rust" fn bar3() {} // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs new file mode 100644 index 000000000000..687476d746a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier-2.rs @@ -0,0 +1,8 @@ +fn main() {} + +#[cfg(FALSE)] +fn container() { + const unsafe WhereIsFerris Now() {} +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs new file mode 100644 index 000000000000..7c2df69eb0d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-extern-fn/issue-68062-const-extern-fns-dont-need-fn-specifier.rs @@ -0,0 +1,8 @@ +fn main() {} + +#[cfg(FALSE)] +fn container() { + const extern "Rust" PUT_ANYTHING_YOU_WANT_HERE bug() -> usize { 1 } +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-extern-function.rs b/gcc/testsuite/rust/rustc/ui/consts/const-extern-function.rs new file mode 100644 index 000000000000..94ae936f18c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-extern-function.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(non_upper_case_globals)] + +extern fn foopy() {} + +static f: extern "C" fn() = foopy; +static s: S = S { f: foopy }; + +struct S { + f: extern "C" fn() +} + +pub fn main() { + assert!(foopy as extern "C" fn() == f); + assert!(f == s.f); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-external-macro-const-err.rs b/gcc/testsuite/rust/rustc/ui/consts/const-external-macro-const-err.rs new file mode 100644 index 000000000000..c69ab5163d80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-external-macro-const-err.rs @@ -0,0 +1,14 @@ +// edition:2018 +// aux-build:external_macro.rs + +// Ensure that CONST_ERR lint errors +// are not silenced in external macros. +// https://github.com/rust-lang/rust/issues/65300 + +extern crate external_macro; +use external_macro::static_assert; + +fn main() { + static_assert!(2 + 2 == 5); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fields-and-indexing.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fields-and-indexing.rs new file mode 100644 index 000000000000..390d9900862c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fields-and-indexing.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +const x : [isize; 4] = [1,2,3,4]; +static p : isize = x[2]; +const y : &'static [isize] = &[1,2,3,4]; +static q : isize = y[2]; + +struct S {a: isize, b: isize} + +const s : S = S {a: 10, b: 20}; +static t : isize = s.b; + +struct K {a: isize, b: isize, c: D} +struct D { d: isize, e: isize } + +const k : K = K {a: 10, b: 20, c: D {d: 30, e: 40}}; +static m : isize = k.c.e; + +pub fn main() { + println!("{}", p); + println!("{}", q); + println!("{}", t); + assert_eq!(p, 3); + assert_eq!(q, 3); + assert_eq!(t, 20); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-float-bits-conv.rs b/gcc/testsuite/rust/rustc/ui/consts/const-float-bits-conv.rs new file mode 100644 index 000000000000..1d1c8c7b3a4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-float-bits-conv.rs @@ -0,0 +1,94 @@ +// compile-flags: -Zmir-opt-level=0 +// run-pass + +#![feature(const_panic)] +#![feature(const_float_bits_conv)] +#![feature(const_float_classify)] + +// Don't promote +const fn nop(x: T) -> T { x } + +macro_rules! const_assert { + ($a:expr) => { + { + const _: () = assert!($a); + assert!(nop($a)); + } + }; + ($a:expr, $b:expr) => { + { + const _: () = assert!($a == $b); + assert_eq!(nop($a), nop($b)); + } + }; +} + +fn f32() { + const_assert!((1f32).to_bits(), 0x3f800000); + const_assert!(u32::from_be_bytes(1f32.to_be_bytes()), 0x3f800000); + const_assert!((12.5f32).to_bits(), 0x41480000); + const_assert!(u32::from_le_bytes(12.5f32.to_le_bytes()), 0x41480000); + const_assert!((1337f32).to_bits(), 0x44a72000); + const_assert!(u32::from_ne_bytes(1337f32.to_ne_bytes()), 0x44a72000); + const_assert!((-14.25f32).to_bits(), 0xc1640000); + const_assert!(f32::from_bits(0x3f800000), 1.0); + const_assert!(f32::from_be_bytes(0x3f800000u32.to_be_bytes()), 1.0); + const_assert!(f32::from_bits(0x41480000), 12.5); + const_assert!(f32::from_le_bytes(0x41480000u32.to_le_bytes()), 12.5); + const_assert!(f32::from_bits(0x44a72000), 1337.0); + const_assert!(f32::from_ne_bytes(0x44a72000u32.to_ne_bytes()), 1337.0); + const_assert!(f32::from_bits(0xc1640000), -14.25); + + // Check that NaNs roundtrip their bits regardless of signalingness + // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits + const MASKED_NAN1: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA; + const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555; + + const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); + const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); + + // LLVM does not guarantee that loads and stores of NaNs preserve their exact bit pattern. + // In practice, this seems to only cause a problem on x86, since the most widely used calling + // convention mandates that floating point values are returned on the x87 FPU stack. See #73328. + if !cfg!(target_arch = "x86") { + const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); + const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); + } +} + +fn f64() { + const_assert!((1f64).to_bits(), 0x3ff0000000000000); + const_assert!(u64::from_be_bytes(1f64.to_be_bytes()), 0x3ff0000000000000); + const_assert!((12.5f64).to_bits(), 0x4029000000000000); + const_assert!(u64::from_le_bytes(12.5f64.to_le_bytes()), 0x4029000000000000); + const_assert!((1337f64).to_bits(), 0x4094e40000000000); + const_assert!(u64::from_ne_bytes(1337f64.to_ne_bytes()), 0x4094e40000000000); + const_assert!((-14.25f64).to_bits(), 0xc02c800000000000); + const_assert!(f64::from_bits(0x3ff0000000000000), 1.0); + const_assert!(f64::from_be_bytes(0x3ff0000000000000u64.to_be_bytes()), 1.0); + const_assert!(f64::from_bits(0x4029000000000000), 12.5); + const_assert!(f64::from_le_bytes(0x4029000000000000u64.to_le_bytes()), 12.5); + const_assert!(f64::from_bits(0x4094e40000000000), 1337.0); + const_assert!(f64::from_ne_bytes(0x4094e40000000000u64.to_ne_bytes()), 1337.0); + const_assert!(f64::from_bits(0xc02c800000000000), -14.25); + + // Check that NaNs roundtrip their bits regardless of signalingness + // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits + const MASKED_NAN1: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA; + const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555; + + const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); + const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); + + // See comment above. + if !cfg!(target_arch = "x86") { + const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); + const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); + } +} + +fn main() { + f32(); + f64(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-float-classify.rs b/gcc/testsuite/rust/rustc/ui/consts/const-float-classify.rs new file mode 100644 index 000000000000..49fe858f601c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-float-classify.rs @@ -0,0 +1,78 @@ +// compile-flags: -Zmir-opt-level=0 +// run-pass + +#![feature(const_panic)] +#![feature(const_float_bits_conv)] +#![feature(const_float_classify)] +#![feature(const_trait_impl)] +#![allow(incomplete_features)] + +// Don't promote +const fn nop(x: T) -> T { x } + +macro_rules! const_assert { + ($a:expr, $b:expr) => { + { + const _: () = assert!($a == $b); + assert_eq!(nop($a), nop($b)); + } + }; +} + +macro_rules! suite { + ( $( $tt:tt )* ) => { + fn f32() { + suite_inner!(f32 $($tt)*); + } + + fn f64() { + suite_inner!(f64 $($tt)*); + } + } + +} + +macro_rules! suite_inner { + ( + $ty:ident [$( $fn:ident ),*] + $val:expr => [$($out:ident),*] + + $( $tail:tt )* + ) => { + $( const_assert!($ty::$fn($val), $out); )* + suite_inner!($ty [$($fn),*] $($tail)*) + }; + + ( $ty:ident [$( $fn:ident ),*]) => {}; +} + +#[derive(Debug)] +struct NonDet; + +impl const PartialEq for bool { + fn eq(&self, _: &NonDet) -> bool { + true + } +} + +// The result of the `is_sign` methods are not checked for correctness, since LLVM does not +// guarantee anything about the signedness of NaNs. See +// https://github.com/rust-lang/rust/issues/55131. + +suite! { + [is_nan, is_infinite, is_finite, is_normal, is_sign_positive, is_sign_negative] + -0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] + 0.0 / 0.0 => [ true, false, false, false, NonDet, NonDet] + 1.0 => [ false, false, true, true, true, false] + -1.0 => [ false, false, true, true, false, true] + 0.0 => [ false, false, true, false, true, false] + -0.0 => [ false, false, true, false, false, true] + 1.0 / 0.0 => [ false, true, false, false, true, false] + -1.0 / 0.0 => [ false, true, false, false, false, true] +} + +fn main() { + f32(); + f64(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-const-eval.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-const-eval.rs new file mode 100644 index 000000000000..11953deec31f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-const-eval.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] + +const fn add(x: usize, y: usize) -> usize { + x + y +} + +const ARR: [i32; add(1, 2)] = [5, 6, 7]; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-destructuring-arg.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-destructuring-arg.rs new file mode 100644 index 000000000000..2bcb70e25e94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-destructuring-arg.rs @@ -0,0 +1,8 @@ +// check-pass + +const fn i((a, b): (u32, u32)) -> u32 { + a + b +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-feature-flags.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-feature-flags.rs new file mode 100644 index 000000000000..83a98f0f8e9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-feature-flags.rs @@ -0,0 +1,14 @@ +// run-pass +// Test use of stabilized const fns in std formerly using individual feature gates. + +use std::cell::Cell; + +const CELL: Cell = Cell::new(42); + +fn main() { + let v = CELL.get(); + CELL.set(v+1); + + assert_eq!(CELL.get(), v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-method.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-method.rs new file mode 100644 index 000000000000..1f29c56fe8e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-method.rs @@ -0,0 +1,17 @@ +// run-pass + +struct Foo { value: u32 } + +impl Foo { + const fn new() -> Foo { + Foo { value: 22 } + } +} + +const FOO: Foo = Foo::new(); + +pub fn main() { + assert_eq!(FOO.value, 22); + let _: [&'static str; Foo::new().value as usize] = ["hey"; 22]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-mismatch.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-mismatch.rs new file mode 100644 index 000000000000..cca3551dfaff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-mismatch.rs @@ -0,0 +1,20 @@ +// Test that we can't declare a const fn in an impl -- right now it's +// just not allowed at all, though eventually it'd make sense to allow +// it if the trait fn is const (but right now no trait fns can be +// const). + +#![feature(const_fn)] + +trait Foo { + fn f() -> u32; +} + +impl Foo for u32 { + const fn f() -> u32 { +// { dg-error ".E0379." "" { target *-*-* } .-1 } + 22 + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-nested.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-nested.rs new file mode 100644 index 000000000000..791d75864da6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-nested.rs @@ -0,0 +1,13 @@ +// run-pass +// Test a call whose argument is the result of another call. + +const fn sub(x: u32, y: u32) -> u32 { + x - y +} + +const X: u32 = sub(sub(88, 44), 22); + +fn main() { + assert_eq!(X, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-not-in-trait.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-not-in-trait.rs new file mode 100644 index 000000000000..c44e0244759a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-not-in-trait.rs @@ -0,0 +1,16 @@ +// Test that const fn is illegal in a trait declaration, whether or +// not a default is provided. + +#![feature(const_fn)] + +trait Foo { + const fn f() -> u32; +// { dg-error ".E0379." "" { target *-*-* } .-1 } + const fn g() -> u32 { +// { dg-error ".E0379." "" { target *-*-* } .-1 } + 0 + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-not-safe-for-const.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-not-safe-for-const.rs new file mode 100644 index 000000000000..4e65df8a145c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-not-safe-for-const.rs @@ -0,0 +1,36 @@ +// Test that we can't call random fns in a const fn or do other bad things. + +#![feature(const_fn, const_fn_transmute)] + +use std::mem::transmute; + +fn random() -> u32 { 0 } + +const fn sub(x: &u32) -> usize { + unsafe { transmute(x) } +} + +const fn sub1() -> u32 { + random() // { dg-error ".E0015." "" { target *-*-* } } +} + +static Y: u32 = 0; + +const fn get_Y() -> u32 { + Y +// { dg-error ".E0013." "" { target *-*-* } .-1 } +} + +const fn get_Y_addr() -> &'static u32 { + &Y +// { dg-error ".E0013." "" { target *-*-* } .-1 } +} + +const fn get() -> u32 { + let x = 22; + let y = 44; + x + y +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-stability-calls-3.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-stability-calls-3.rs new file mode 100644 index 000000000000..840679568bf7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-stability-calls-3.rs @@ -0,0 +1,13 @@ +// Test use of const fn from another crate without a feature gate. + +// check-pass +// aux-build:const_fn_lib.rs + +extern crate const_fn_lib; + +use const_fn_lib::foo; + +fn main() { + let x = foo(); // use outside a constant is ok +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-stability-calls.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-stability-calls.rs new file mode 100644 index 000000000000..18ef7c2dfcf4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-stability-calls.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test use of const fn from another crate without a feature gate. + +// aux-build:const_fn_lib.rs + +extern crate const_fn_lib; + +use const_fn_lib::foo; + +static FOO: usize = foo(); +const BAR: usize = foo(); + +macro_rules! constant { + ($n:ident: $t:ty = $v:expr) => { + const $n: $t = $v; + } +} + +constant! { + BAZ: usize = foo() +} + +fn main() { + let x: [usize; foo()] = [42; foo()]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-type-name-any.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-type-name-any.rs new file mode 100644 index 000000000000..342dce6fb197 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-type-name-any.rs @@ -0,0 +1,30 @@ +// run-pass + +#![feature(const_fn)] +#![feature(const_type_name)] +#![allow(dead_code)] + +const fn type_name_wrapper(_: &T) -> &'static str { + std::any::type_name::() +} + +struct Struct { + a: TA, + b: TB, + c: TC, +} + +type StructInstantiation = Struct; + +const CONST_STRUCT: StructInstantiation = StructInstantiation { a: 12, b: 13.7, c: false }; + +const CONST_STRUCT_NAME: &'static str = type_name_wrapper(&CONST_STRUCT); + +fn main() { + let non_const_struct = StructInstantiation { a: 87, b: 65.99, c: true }; + + let non_const_struct_name = type_name_wrapper(&non_const_struct); + + assert_eq!(CONST_STRUCT_NAME, non_const_struct_name); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-type-name.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-type-name.rs new file mode 100644 index 000000000000..3bf3291be72d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-type-name.rs @@ -0,0 +1,39 @@ +// run-pass + +#![feature(core_intrinsics)] +#![feature(const_fn)] +#![feature(const_type_name)] +#![allow(dead_code)] + +const fn type_name_wrapper(_: &T) -> &'static str { + core::intrinsics::type_name::() +} + +struct Struct { + a: TA, + b: TB, + c: TC, +} + +type StructInstantiation = Struct; + +const CONST_STRUCT: StructInstantiation = StructInstantiation { + a: 12, + b: 13.7, + c: false, +}; + +const CONST_STRUCT_NAME: &'static str = type_name_wrapper(&CONST_STRUCT); + +fn main() { + let non_const_struct = StructInstantiation { + a: 87, + b: 65.99, + c: true, + }; + + let non_const_struct_name = type_name_wrapper(&non_const_struct); + + assert_eq!(CONST_STRUCT_NAME, non_const_struct_name); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-val.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-val.rs new file mode 100644 index 000000000000..700c7acfd379 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-val.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(non_upper_case_globals)] +#![allow(overflowing_literals)] + +fn foo() -> isize { + return 0xca7f000d; +} + +struct Bar where F: FnMut() -> isize { f: F } + +static mut b : Bar isize> = Bar { f: foo as fn() -> isize}; + +pub fn main() { + unsafe { assert_eq!((b.f)(), 0xca7f000d); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn-zst-args.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn-zst-args.rs new file mode 100644 index 000000000000..c0523678afe8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn-zst-args.rs @@ -0,0 +1,15 @@ +// build-pass + +// Check that the evaluation of const-functions with +// zero-sized types as arguments compiles successfully + +struct Zst {} + +const fn foo(val: Zst) -> Zst { val } + +const FOO: Zst = foo(Zst {}); + +fn main() { + const _: Zst = FOO; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-fn.rs b/gcc/testsuite/rust/rustc/ui/consts/const-fn.rs new file mode 100644 index 000000000000..a898bb92b99c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-fn.rs @@ -0,0 +1,43 @@ +// run-pass +#![allow(stable_features)] + +// A very basic test of const fn functionality. + +#![feature(const_fn, const_indexing)] + +const fn add(x: u32, y: u32) -> u32 { + x + y +} + +const fn sub(x: u32, y: u32) -> u32 { + x - y +} + +const unsafe fn div(x: u32, y: u32) -> u32 { + x / y +} + +const fn generic(t: T) -> T { + t +} + +const fn generic_arr(t: [T; 1]) -> T { + t[0] +} + +const SUM: u32 = add(44, 22); +const DIFF: u32 = sub(44, 22); +const DIV: u32 = unsafe{div(44, 22)}; + +fn main() { + assert_eq!(SUM, 66); + assert!(SUM != 88); + + assert_eq!(DIFF, 22); + assert_eq!(DIV, 2); + + let _: [&'static str; sub(100, 99) as usize] = ["hi"]; + let _: [&'static str; generic(1)] = ["hi"]; + let _: [&'static str; generic_arr([1])] = ["hi"]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-index-feature-gate.rs b/gcc/testsuite/rust/rustc/ui/consts/const-index-feature-gate.rs new file mode 100644 index 000000000000..46602cad91b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-index-feature-gate.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(dead_code)] +const ARR: [usize; 1] = [2]; +const ARR2: [i32; ARR[0]] = [5, 6]; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-arithmetic-overflow.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-arithmetic-overflow.rs new file mode 100644 index 000000000000..cc7102c15077 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-arithmetic-overflow.rs @@ -0,0 +1,27 @@ +// run-pass +// compile-flags: -O +#![allow(const_err)] + +// Make sure arithmetic unary/binary ops actually return the right result, even when overflowing. +// We have to put them in `const fn` and turn on optimizations to avoid overflow checks. + +const fn add(x: i8, y: i8) -> i8 { x+y } +const fn sub(x: i8, y: i8) -> i8 { x-y } +const fn mul(x: i8, y: i8) -> i8 { x*y } +// div and rem are always checked, so we cannot test their result in case of overflow. +const fn neg(x: i8) -> i8 { -x } + +fn main() { + const ADD_OFLOW: i8 = add(100, 100); + assert_eq!(ADD_OFLOW, -56); + + const SUB_OFLOW: i8 = sub(100, -100); + assert_eq!(SUB_OFLOW, -56); + + const MUL_OFLOW: i8 = mul(-100, -2); + assert_eq!(MUL_OFLOW, -56); + + const NEG_OFLOW: i8 = neg(-128); + assert_eq!(NEG_OFLOW, -128); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-arithmetic.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-arithmetic.rs new file mode 100644 index 000000000000..4dacee579311 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-arithmetic.rs @@ -0,0 +1,146 @@ +// run-pass + +#![feature(const_checked_int_methods)] +#![feature(const_euclidean_int_methods)] +#![feature(const_overflowing_int_methods)] +#![feature(const_wrapping_int_methods)] + +use std::{i8, i128}; + +macro_rules! suite { + ($( + $fn:ident -> $ty:ty { $( $label:ident : $expr:expr, $result:expr; )* } + )*) => { $( + fn $fn() { + $( + const $label: $ty = $expr; + assert_eq!($label, $result); + )* + } + )* } +} + +suite!( + checked -> Option { + // `const_checked_int_methods` + C1: 5i8.checked_add(2), Some(7); + C2: 127i8.checked_add(2), None; + + C3: 5i8.checked_sub(2), Some(3); + C4: (-127i8).checked_sub(2), None; + + C5: 1i8.checked_mul(3), Some(3); + C6: 5i8.checked_mul(122), None; + C7: (-127i8).checked_mul(-99), None; + + C8: (i8::MIN + 1).checked_div(-1), Some(127); + C9: i8::MIN.checked_div(-1), None; + C10: 1i8.checked_div(0), None; + + C11: 5i8.checked_rem(2), Some(1); + C12: 5i8.checked_rem(0), None; + C13: i8::MIN.checked_rem(-1), None; + + C14: 5i8.checked_neg(), Some(-5); + C15: i8::MIN.checked_neg(), None; + + C16: 0x1i8.checked_shl(4), Some(0x10); + C17: 0x1i8.checked_shl(129), None; + + C18: 0x10i8.checked_shr(4), Some(0x1); + C19: 0x10i8.checked_shr(128), None; + + + C20: (-5i8).checked_abs(), Some(5); + C21: i8::MIN.checked_abs(), None; + + // `const_euclidean_int_methods` + C22: (i8::MIN + 1).checked_div_euclid(-1), Some(127); + C23: i8::MIN.checked_div_euclid(-1), None; + C24: (1i8).checked_div_euclid(0), None; + + C25: 5i8.checked_rem_euclid(2), Some(1); + C26: 5i8.checked_rem_euclid(0), None; + C27: i8::MIN.checked_rem_euclid(-1), None; + } + checked_i128 -> Option { + CHK_ADD_I128: i128::MAX.checked_add(1), None; + CHK_MUL_I128: i128::MIN.checked_mul(-1), None; + } + + saturating_and_wrapping -> i8 { + // `const_saturating_int_methods` + C28: 100i8.saturating_add(1), 101; + C29: i8::MAX.saturating_add(100), i8::MAX; + C30: i8::MIN.saturating_add(-1), i8::MIN; + + C31: 100i8.saturating_sub(127), -27; + C32: i8::MIN.saturating_sub(100), i8::MIN; + C33: i8::MAX.saturating_sub(-1), i8::MAX; + + C34: 10i8.saturating_mul(12), 120; + C35: i8::MAX.saturating_mul(10), i8::MAX; + C36: i8::MIN.saturating_mul(10), i8::MIN; + + C37: 100i8.saturating_neg(), -100; + C38: (-100i8).saturating_neg(), 100; + C39: i8::MIN.saturating_neg(), i8::MAX; + C40: i8::MAX.saturating_neg(), i8::MIN + 1; + + C57: 100i8.saturating_abs(), 100; + C58: (-100i8).saturating_abs(), 100; + C59: i8::MIN.saturating_abs(), i8::MAX; + C60: (i8::MIN + 1).saturating_abs(), i8::MAX; + + // `const_wrapping_int_methods` + C41: 100i8.wrapping_div(10), 10; + C42: (-128i8).wrapping_div(-1), -128; + + C43: 100i8.wrapping_rem(10), 0; + C44: (-128i8).wrapping_rem(-1), 0; + + // `const_euclidean_int_methods` + C45: 100i8.wrapping_div_euclid(10), 10; + C46: (-128i8).wrapping_div_euclid(-1), -128; + + C47: 100i8.wrapping_rem_euclid(10), 0; + C48: (-128i8).wrapping_rem_euclid(-1), 0; + } + saturating_and_wrapping_i128 -> i128 { + SAT_ADD_I128: i128::MAX.saturating_add(1), i128::MAX; + SAT_MUL_I128: i128::MAX.saturating_mul(2), i128::MAX; + + WRP_ADD_I128: i128::MAX.wrapping_add(1), i128::MIN; + WRP_MUL_I128: i128::MAX.wrapping_mul(3), i128::MAX-2; + } + + overflowing -> (i8, bool) { + // `const_overflowing_int_methods` + C49: 5i8.overflowing_div(2), (2, false); + C50: i8::MIN.overflowing_div(-1), (i8::MIN, true); + + C51: 5i8.overflowing_rem(2), (1, false); + C52: i8::MIN.overflowing_rem(-1), (0, true); + + // `const_euclidean_int_methods` + C53: 5i8.overflowing_div_euclid(2), (2, false); + C54: i8::MIN.overflowing_div_euclid(-1), (i8::MIN, true); + + C55: 5i8.overflowing_rem_euclid(2), (1, false); + C56: i8::MIN.overflowing_rem_euclid(-1), (0, true); + } + overflowing_i128 -> (i128, bool) { + OFL_ADD_I128: i128::MAX.overflowing_add(1), (i128::MIN, true); + OFL_MUL_I128: i128::MAX.overflowing_mul(3), (i128::MAX-2, true); + } +); + +fn main() { + checked(); + checked_i128(); + saturating_and_wrapping(); + saturating_and_wrapping_i128(); + overflowing(); + overflowing_i128(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-conversion-rpass.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-conversion-rpass.rs new file mode 100644 index 000000000000..e6e08f197bd9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-conversion-rpass.rs @@ -0,0 +1,20 @@ +// run-pass + +const REVERSE: u32 = 0x12345678_u32.reverse_bits(); +const FROM_BE_BYTES: i32 = i32::from_be_bytes([0x12, 0x34, 0x56, 0x78]); +const FROM_LE_BYTES: i32 = i32::from_le_bytes([0x12, 0x34, 0x56, 0x78]); +const FROM_NE_BYTES: i32 = i32::from_be(i32::from_ne_bytes([0x80, 0, 0, 0])); +const TO_BE_BYTES: [u8; 4] = 0x12_34_56_78_i32.to_be_bytes(); +const TO_LE_BYTES: [u8; 4] = 0x12_34_56_78_i32.to_le_bytes(); +const TO_NE_BYTES: [u8; 4] = i32::MIN.to_be().to_ne_bytes(); + +fn main() { + assert_eq!(REVERSE, 0x1e6a2c48); + assert_eq!(FROM_BE_BYTES, 0x12_34_56_78); + assert_eq!(FROM_LE_BYTES, 0x78_56_34_12); + assert_eq!(FROM_NE_BYTES, i32::MIN); + assert_eq!(TO_BE_BYTES, [0x12, 0x34, 0x56, 0x78]); + assert_eq!(TO_LE_BYTES, [0x78, 0x56, 0x34, 0x12]); + assert_eq!(TO_NE_BYTES, [0x80, 0, 0, 0]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-conversion.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-conversion.rs new file mode 100644 index 000000000000..5cd162390895 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-conversion.rs @@ -0,0 +1,17 @@ +fn main() { + let x: &'static i32 = &(5_i32.reverse_bits()); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let y: &'static i32 = &(i32::from_be_bytes([0x12, 0x34, 0x56, 0x78])); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let z: &'static i32 = &(i32::from_le_bytes([0x12, 0x34, 0x56, 0x78])); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let a: &'static i32 = &(i32::from_be(i32::from_ne_bytes([0x80, 0, 0, 0]))); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let b: &'static [u8] = &(0x12_34_56_78_i32.to_be_bytes()); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let c: &'static [u8] = &(0x12_34_56_78_i32.to_le_bytes()); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let d: &'static [u8] = &(i32::MIN.to_be().to_ne_bytes()); +// { dg-error ".E0716." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-overflowing-rpass.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-overflowing-rpass.rs new file mode 100644 index 000000000000..c550244e72f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-overflowing-rpass.rs @@ -0,0 +1,48 @@ +// run-pass + +const ADD_A: (u32, bool) = 5u32.overflowing_add(2); +const ADD_B: (u32, bool) = u32::MAX.overflowing_add(1); + +const SUB_A: (u32, bool) = 5u32.overflowing_sub(2); +const SUB_B: (u32, bool) = 0u32.overflowing_sub(1); + +const MUL_A: (u32, bool) = 5u32.overflowing_mul(2); +const MUL_B: (u32, bool) = 1_000_000_000u32.overflowing_mul(10); + +const SHL_A: (u32, bool) = 0x1u32.overflowing_shl(4); +const SHL_B: (u32, bool) = 0x1u32.overflowing_shl(132); + +const SHR_A: (u32, bool) = 0x10u32.overflowing_shr(4); +const SHR_B: (u32, bool) = 0x10u32.overflowing_shr(132); + +const NEG_A: (u32, bool) = 0u32.overflowing_neg(); +const NEG_B: (u32, bool) = core::u32::MAX.overflowing_neg(); + +const ABS_POS: (i32, bool) = 10i32.overflowing_abs(); +const ABS_NEG: (i32, bool) = (-10i32).overflowing_abs(); +const ABS_MIN: (i32, bool) = i32::MIN.overflowing_abs(); + +fn main() { + assert_eq!(ADD_A, (7, false)); + assert_eq!(ADD_B, (0, true)); + + assert_eq!(SUB_A, (3, false)); + assert_eq!(SUB_B, (u32::MAX, true)); + + assert_eq!(MUL_A, (10, false)); + assert_eq!(MUL_B, (1410065408, true)); + + assert_eq!(SHL_A, (0x10, false)); + assert_eq!(SHL_B, (0x10, true)); + + assert_eq!(SHR_A, (0x1, false)); + assert_eq!(SHR_B, (0x1, true)); + + assert_eq!(NEG_A, (0, false)); + assert_eq!(NEG_B, (1, true)); + + assert_eq!(ABS_POS, (10, false)); + assert_eq!(ABS_NEG, (10, false)); + assert_eq!(ABS_MIN, (i32::MIN, true)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-overflowing.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-overflowing.rs new file mode 100644 index 000000000000..9a151c4a591f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-overflowing.rs @@ -0,0 +1,9 @@ +fn main() { + let x: &'static (i32, bool) = &(5_i32.overflowing_add(3)); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let y: &'static (i32, bool) = &(5_i32.overflowing_sub(3)); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let z: &'static (i32, bool) = &(5_i32.overflowing_mul(3)); +// { dg-error ".E0716." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-pow-rpass.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-pow-rpass.rs new file mode 100644 index 000000000000..f4ed5a16ef59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-pow-rpass.rs @@ -0,0 +1,49 @@ +// run-pass + +#![feature(const_int_pow)] +#![feature(wrapping_next_power_of_two)] + +const IS_POWER_OF_TWO_A: bool = 0u32.is_power_of_two(); +const IS_POWER_OF_TWO_B: bool = 32u32.is_power_of_two(); +const IS_POWER_OF_TWO_C: bool = 33u32.is_power_of_two(); + +const POW: u8 = 3u8.pow(5); + +const CHECKED_POW_OK: Option = 3u8.checked_pow(5); +const CHECKED_POW_OVERFLOW: Option = 3u8.checked_pow(6); + +const WRAPPING_POW: u8 = 3u8.wrapping_pow(6); +const OVERFLOWING_POW: (u8, bool) = 3u8.overflowing_pow(6); +const SATURATING_POW: u8 = 3u8.saturating_pow(6); + +const NEXT_POWER_OF_TWO: u32 = 3u32.next_power_of_two(); + +const CHECKED_NEXT_POWER_OF_TWO_OK: Option = 3u32.checked_next_power_of_two(); +const CHECKED_NEXT_POWER_OF_TWO_OVERFLOW: Option = + u32::MAX.checked_next_power_of_two(); + +const WRAPPING_NEXT_POWER_OF_TWO: u32 = + u32::MAX.wrapping_next_power_of_two(); + +fn main() { + assert!(!IS_POWER_OF_TWO_A); + assert!(IS_POWER_OF_TWO_B); + assert!(!IS_POWER_OF_TWO_C); + + assert_eq!(POW, 243); + + assert_eq!(CHECKED_POW_OK, Some(243)); + assert_eq!(CHECKED_POW_OVERFLOW, None); + + assert_eq!(WRAPPING_POW, 217); + assert_eq!(OVERFLOWING_POW, (217, true)); + assert_eq!(SATURATING_POW, u8::MAX); + + assert_eq!(NEXT_POWER_OF_TWO, 4); + + assert_eq!(CHECKED_NEXT_POWER_OF_TWO_OK, Some(4)); + assert_eq!(CHECKED_NEXT_POWER_OF_TWO_OVERFLOW, None); + + assert_eq!(WRAPPING_NEXT_POWER_OF_TWO, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-rotate-rpass.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-rotate-rpass.rs new file mode 100644 index 000000000000..b49c809ac81a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-rotate-rpass.rs @@ -0,0 +1,44 @@ +// run-pass + +const LEFT: u32 = 0x10000b3u32.rotate_left(8); +const RIGHT: u32 = 0xb301u32.rotate_right(8); + +// Rotating these should make no difference +// +// We test using 124 bits because to ensure that overlong bit shifts do +// not cause undefined behaviour. See #10183. +const LEFT_OVERFLOW: i16 = 0i16.rotate_left(124); +const RIGHT_OVERFLOW: i16 = 0i16.rotate_right(124); +const ONE_LEFT_OVERFLOW: u16 = 1u16.rotate_left(124); +const ONE_RIGHT_OVERFLOW: u16 = 1u16.rotate_right(124); + +const NON_ZERO_LEFT_OVERFLOW: u16 = 0b10u16.rotate_left(124); +const NON_ZERO_RIGHT_OVERFLOW: u16 = 0b10u16.rotate_right(124); + +// Rotating by 0 should have no effect +const ZERO_ROTATE_LEFT: i8 = 0b0010_0001i8.rotate_left(0); +const ZERO_ROTATE_RIGHT: i8 = 0b0111_1001i8.rotate_right(0); + +// Rotating by a multiple of word size should also have no effect +const MULTIPLE_ROTATE_LEFT: i32 = 0b0010_0001i32.rotate_left(128); +const MULTIPLE_ROTATE_RIGHT: i32 = 0b0010_0001i32.rotate_right(128); + +fn main() { + assert_eq!(LEFT, 0xb301); + assert_eq!(RIGHT, 0x0100_00b3); + + assert_eq!(LEFT_OVERFLOW, 0); + assert_eq!(RIGHT_OVERFLOW, 0); + assert_eq!(ONE_LEFT_OVERFLOW, 0b0001_0000_0000_0000); + assert_eq!(ONE_RIGHT_OVERFLOW, 0b0001_0000); + + assert_eq!(NON_ZERO_LEFT_OVERFLOW, 0b0010_0000_0000_0000); + assert_eq!(NON_ZERO_RIGHT_OVERFLOW, 0b0000_0000_0010_0000); + + assert_eq!(ZERO_ROTATE_LEFT, 0b0010_0001); + assert_eq!(ZERO_ROTATE_RIGHT, 0b0111_1001); + + assert_eq!(MULTIPLE_ROTATE_LEFT, 0b0010_0001); + assert_eq!(MULTIPLE_ROTATE_RIGHT, 0b0010_0001); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-rotate.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-rotate.rs new file mode 100644 index 000000000000..02da9861dd5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-rotate.rs @@ -0,0 +1,7 @@ +fn main() { + let x: &'static i32 = &(5_i32.rotate_left(3)); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let y: &'static i32 = &(5_i32.rotate_right(3)); +// { dg-error ".E0716." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-saturating-arith.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-saturating-arith.rs new file mode 100644 index 000000000000..9724a93f36cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-saturating-arith.rs @@ -0,0 +1,34 @@ +// run-pass + +const INT_U32_NO: u32 = (42 as u32).saturating_add(2); +const INT_U32: u32 = u32::MAX.saturating_add(1); +const INT_U128: u128 = u128::MAX.saturating_add(1); +const INT_I128: i128 = i128::MAX.saturating_add(1); +const INT_I128_NEG: i128 = i128::MIN.saturating_add(-1); + +const INT_U32_NO_SUB: u32 = (42 as u32).saturating_sub(2); +const INT_U32_SUB: u32 = (1 as u32).saturating_sub(2); +const INT_I32_NO_SUB: i32 = (-42 as i32).saturating_sub(2); +const INT_I32_NEG_SUB: i32 = i32::MIN.saturating_sub(1); +const INT_I32_POS_SUB: i32 = i32::MAX.saturating_sub(-1); +const INT_U128_SUB: u128 = (0 as u128).saturating_sub(1); +const INT_I128_NEG_SUB: i128 = i128::MIN.saturating_sub(1); +const INT_I128_POS_SUB: i128 = i128::MAX.saturating_sub(-1); + +fn main() { + assert_eq!(INT_U32_NO, 44); + assert_eq!(INT_U32, u32::MAX); + assert_eq!(INT_U128, u128::MAX); + assert_eq!(INT_I128, i128::MAX); + assert_eq!(INT_I128_NEG, i128::MIN); + + assert_eq!(INT_U32_NO_SUB, 40); + assert_eq!(INT_U32_SUB, 0); + assert_eq!(INT_I32_NO_SUB, -44); + assert_eq!(INT_I32_NEG_SUB, i32::MIN); + assert_eq!(INT_I32_POS_SUB, i32::MAX); + assert_eq!(INT_U128_SUB, 0); + assert_eq!(INT_I128_NEG_SUB, i128::MIN); + assert_eq!(INT_I128_POS_SUB, i128::MAX); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-sign-rpass.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-sign-rpass.rs new file mode 100644 index 000000000000..20f46894abe9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-sign-rpass.rs @@ -0,0 +1,28 @@ +// run-pass + +const NEGATIVE_A: bool = (-10i32).is_negative(); +const NEGATIVE_B: bool = 10i32.is_negative(); +const POSITIVE_A: bool = (-10i32).is_positive(); +const POSITIVE_B: bool = 10i32.is_positive(); + +const SIGNUM_POS: i32 = 10i32.signum(); +const SIGNUM_NIL: i32 = 0i32.signum(); +const SIGNUM_NEG: i32 = (-42i32).signum(); + +const ABS_A: i32 = 10i32.abs(); +const ABS_B: i32 = (-10i32).abs(); + +fn main() { + assert!(NEGATIVE_A); + assert!(!NEGATIVE_B); + assert!(!POSITIVE_A); + assert!(POSITIVE_B); + + assert_eq!(SIGNUM_POS, 1); + assert_eq!(SIGNUM_NIL, 0); + assert_eq!(SIGNUM_NEG, -1); + + assert_eq!(ABS_A, 10); + assert_eq!(ABS_B, 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-sign.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-sign.rs new file mode 100644 index 000000000000..db2ce5856e41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-sign.rs @@ -0,0 +1,7 @@ +fn main() { + let x: &'static bool = &(5_i32.is_negative()); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let y: &'static bool = &(5_i32.is_positive()); +// { dg-error ".E0716." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-unchecked.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-unchecked.rs new file mode 100644 index 000000000000..35aed991ed73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-unchecked.rs @@ -0,0 +1,143 @@ +#![feature(core_intrinsics)] +#![feature(const_int_unchecked_arith)] + +use std::intrinsics; + +// The documentation of `unchecked_shl` states that it: +// +// Performs an unchecked left shift, resulting in undefined behavior when +// y < 0 or y >= N, where N is the width of T in bits. +// +// So we check this for a few `y`. + +// unsigned types: + +const SHL_U8: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_U16: u16 = unsafe { intrinsics::unchecked_shl(5_u16, 16) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_U32: u32 = unsafe { intrinsics::unchecked_shl(5_u32, 32) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_U64: u64 = unsafe { intrinsics::unchecked_shl(5_u64, 64) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_U128: u128 = unsafe { intrinsics::unchecked_shl(5_u128, 128) }; +// { dg-error "" "" { target *-*-* } .-1 } + +// signed types: + +const SHL_I8: i8 = unsafe { intrinsics::unchecked_shl(5_i8, 8) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_I16: i16 = unsafe { intrinsics::unchecked_shl(5_16, 16) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_I32: i32 = unsafe { intrinsics::unchecked_shl(5_i32, 32) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_I64: i64 = unsafe { intrinsics::unchecked_shl(5_i64, 64) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_I128: i128 = unsafe { intrinsics::unchecked_shl(5_i128, 128) }; +// { dg-error "" "" { target *-*-* } .-1 } + +// and make sure we capture y < 0: + +const SHL_I8_NEG: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -1) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_I16_NEG: i16 = unsafe { intrinsics::unchecked_shl(5_16, -1) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_I32_NEG: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -1) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_I64_NEG: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -1) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_I128_NEG: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -1) }; +// { dg-error "" "" { target *-*-* } .-1 } + +// and that there's no special relation to the value -1 by picking some +// negative values at random: + +const SHL_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -6) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shl(5_16, -13) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -25) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -30) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHL_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -93) }; +// { dg-error "" "" { target *-*-* } .-1 } + +// Repeat it all over for `unchecked_shr` + +// unsigned types: + +const SHR_U8: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_U16: u16 = unsafe { intrinsics::unchecked_shr(5_u16, 16) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_U32: u32 = unsafe { intrinsics::unchecked_shr(5_u32, 32) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_U64: u64 = unsafe { intrinsics::unchecked_shr(5_u64, 64) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_U128: u128 = unsafe { intrinsics::unchecked_shr(5_u128, 128) }; +// { dg-error "" "" { target *-*-* } .-1 } + +// signed types: + +const SHR_I8: i8 = unsafe { intrinsics::unchecked_shr(5_i8, 8) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_I16: i16 = unsafe { intrinsics::unchecked_shr(5_16, 16) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_I32: i32 = unsafe { intrinsics::unchecked_shr(5_i32, 32) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_I64: i64 = unsafe { intrinsics::unchecked_shr(5_i64, 64) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_I128: i128 = unsafe { intrinsics::unchecked_shr(5_i128, 128) }; +// { dg-error "" "" { target *-*-* } .-1 } + +// and make sure we capture y < 0: + +const SHR_I8_NEG: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -1) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_I16_NEG: i16 = unsafe { intrinsics::unchecked_shr(5_16, -1) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_I32_NEG: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -1) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_I64_NEG: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -1) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_I128_NEG: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -1) }; +// { dg-error "" "" { target *-*-* } .-1 } + +// and that there's no special relation to the value -1 by picking some +// negative values at random: + +const SHR_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -6) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shr(5_16, -13) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -25) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -30) }; +// { dg-error "" "" { target *-*-* } .-1 } +const SHR_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -93) }; +// { dg-error "" "" { target *-*-* } .-1 } + +// Other arithmetic functions: + +const _: u16 = unsafe { std::intrinsics::unchecked_add(40000u16, 30000) }; +// { dg-error "" "" { target *-*-* } .-1 } + +const _: u32 = unsafe { std::intrinsics::unchecked_sub(14u32, 22) }; +// { dg-error "" "" { target *-*-* } .-1 } + +const _: u16 = unsafe { std::intrinsics::unchecked_mul(300u16, 250u16) }; +// { dg-error "" "" { target *-*-* } .-1 } + +const _: i32 = unsafe { std::intrinsics::unchecked_div(1, 0) }; +// { dg-error "" "" { target *-*-* } .-1 } +const _: i32 = unsafe { std::intrinsics::unchecked_div(i32::MIN, -1) }; +// { dg-error "" "" { target *-*-* } .-1 } + +const _: i32 = unsafe { std::intrinsics::unchecked_rem(1, 0) }; +// { dg-error "" "" { target *-*-* } .-1 } +const _: i32 = unsafe { std::intrinsics::unchecked_rem(i32::MIN, -1) }; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-wrapping-rpass.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-wrapping-rpass.rs new file mode 100644 index 000000000000..855ef21687ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-wrapping-rpass.rs @@ -0,0 +1,48 @@ +// run-pass + +const ADD_A: u32 = 200u32.wrapping_add(55); +const ADD_B: u32 = 200u32.wrapping_add(u32::MAX); + +const SUB_A: u32 = 100u32.wrapping_sub(100); +const SUB_B: u32 = 100u32.wrapping_sub(u32::MAX); + +const MUL_A: u8 = 10u8.wrapping_mul(12); +const MUL_B: u8 = 25u8.wrapping_mul(12); + +const SHL_A: u32 = 1u32.wrapping_shl(7); +const SHL_B: u32 = 1u32.wrapping_shl(128); + +const SHR_A: u32 = 128u32.wrapping_shr(7); +const SHR_B: u32 = 128u32.wrapping_shr(128); + +const NEG_A: u32 = 5u32.wrapping_neg(); +const NEG_B: u32 = 1234567890u32.wrapping_neg(); + +const ABS_POS: i32 = 10i32.wrapping_abs(); +const ABS_NEG: i32 = (-10i32).wrapping_abs(); +const ABS_MIN: i32 = i32::MIN.wrapping_abs(); + +fn main() { + assert_eq!(ADD_A, 255); + assert_eq!(ADD_B, 199); + + assert_eq!(SUB_A, 0); + assert_eq!(SUB_B, 101); + + assert_eq!(MUL_A, 120); + assert_eq!(MUL_B, 44); + + assert_eq!(SHL_A, 128); + assert_eq!(SHL_B, 1); + + assert_eq!(SHR_A, 1); + assert_eq!(SHR_B, 128); + + assert_eq!(NEG_A, 4294967291); + assert_eq!(NEG_B, 3060399406); + + assert_eq!(ABS_POS, 10); + assert_eq!(ABS_NEG, 10); + assert_eq!(ABS_MIN, i32::MIN); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-int-wrapping.rs b/gcc/testsuite/rust/rustc/ui/consts/const-int-wrapping.rs new file mode 100644 index 000000000000..52ad964d1e0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-int-wrapping.rs @@ -0,0 +1,13 @@ +fn main() { + let x: &'static i32 = &(5_i32.wrapping_add(3)); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let y: &'static i32 = &(5_i32.wrapping_sub(3)); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let z: &'static i32 = &(5_i32.wrapping_mul(3)); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let a: &'static i32 = &(5_i32.wrapping_shl(3)); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + let b: &'static i32 = &(5_i32.wrapping_shr(3)); +// { dg-error ".E0716." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-integer-bool-ops.rs b/gcc/testsuite/rust/rustc/ui/consts/const-integer-bool-ops.rs new file mode 100644 index 000000000000..cd7b5114375c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-integer-bool-ops.rs @@ -0,0 +1,76 @@ +const X: usize = 42 && 39; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } +// { dg-error ".E0308." "" { target *-*-* } .-6 } +const ARR: [i32; X] = [99; 34]; + +const X1: usize = 42 || 39; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } +// { dg-error ".E0308." "" { target *-*-* } .-6 } +const ARR1: [i32; X1] = [99; 47]; + +const X2: usize = -42 || -39; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } +// { dg-error ".E0308." "" { target *-*-* } .-6 } +const ARR2: [i32; X2] = [99; 18446744073709551607]; + +const X3: usize = -42 && -39; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } +// { dg-error ".E0308." "" { target *-*-* } .-6 } +const ARR3: [i32; X3] = [99; 6]; + +const Y: usize = 42.0 == 42.0; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +const ARRR: [i32; Y] = [99; 1]; + +const Y1: usize = 42.0 >= 42.0; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +const ARRR1: [i32; Y1] = [99; 1]; + +const Y2: usize = 42.0 <= 42.0; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +const ARRR2: [i32; Y2] = [99; 1]; + +const Y3: usize = 42.0 > 42.0; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +const ARRR3: [i32; Y3] = [99; 0]; + +const Y4: usize = 42.0 < 42.0; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +const ARRR4: [i32; Y4] = [99; 0]; + +const Y5: usize = 42.0 != 42.0; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +const ARRR5: [i32; Y5] = [99; 0]; + +fn main() { + let _ = ARR; + let _ = ARRR; + let _ = ARRR1; + let _ = ARRR2; + let _ = ARRR3; + let _ = ARRR4; + let _ = ARRR5; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-labeled-break.rs b/gcc/testsuite/rust/rustc/ui/consts/const-labeled-break.rs new file mode 100644 index 000000000000..db2210c38049 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-labeled-break.rs @@ -0,0 +1,12 @@ +// run-pass + +// Using labeled break in a while loop has caused an illegal instruction being +// generated, and an ICE later. +// +// See https://github.com/rust-lang/rust/issues/51350 for more information. + +#[allow(unreachable_code)] +const _: () = 'a: while break 'a {}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-len-underflow-separate-spans.rs b/gcc/testsuite/rust/rustc/ui/consts/const-len-underflow-separate-spans.rs new file mode 100644 index 000000000000..1742d04548dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-len-underflow-separate-spans.rs @@ -0,0 +1,14 @@ +// Check that a constant-evaluation underflow highlights the correct +// spot (where the underflow occurred), while also providing the +// overall context for what caused the evaluation. + +const ONE: usize = 1; +const TWO: usize = 2; +const LEN: usize = ONE - TWO; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + let a: [i8; LEN] = unimplemented!(); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-len-underflow-subspans.rs b/gcc/testsuite/rust/rustc/ui/consts/const-len-underflow-subspans.rs new file mode 100644 index 000000000000..322ae093a94b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-len-underflow-subspans.rs @@ -0,0 +1,12 @@ +// Check that a constant-evaluation underflow highlights the correct +// spot (where the underflow occurred). + +const ONE: usize = 1; +const TWO: usize = 2; + +fn main() { + let a: [i8; ONE - TWO] = unimplemented!(); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-match-check.rs b/gcc/testsuite/rust/rustc/ui/consts/const-match-check.rs new file mode 100644 index 000000000000..f698764c7052 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-match-check.rs @@ -0,0 +1,34 @@ +// revisions: matchck eval1 eval2 + +#[cfg(matchck)] +const X: i32 = { let 0 = 0; 0 }; +// { dg-error "" "" { target *-*-* } .-1 } + +#[cfg(matchck)] +static Y: i32 = { let 0 = 0; 0 }; +// { dg-error "" "" { target *-*-* } .-1 } + +#[cfg(matchck)] +trait Bar { + const X: i32 = { let 0 = 0; 0 }; +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(matchck)] +impl Bar for () { + const X: i32 = { let 0 = 0; 0 }; +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(eval1)] +enum Foo { + A = { let 0 = 0; 0 }, +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + #[cfg(eval2)] + let x: [i32; { let 0 = 0; 0 }] = []; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-match-pattern-arm.rs b/gcc/testsuite/rust/rustc/ui/consts/const-match-pattern-arm.rs new file mode 100644 index 000000000000..7327ddb89ab3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-match-pattern-arm.rs @@ -0,0 +1,16 @@ +// check-pass + +const _: bool = match Some(true) { + Some(value) => true, + _ => false +}; + +const _: bool = { + match Some(true) { + Some(value) => true, + _ => false + } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-meth-pattern.rs b/gcc/testsuite/rust/rustc/ui/consts/const-meth-pattern.rs new file mode 100644 index 000000000000..a4034d80abdd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-meth-pattern.rs @@ -0,0 +1,19 @@ +// run-pass + +struct A; + +impl A { + const fn banana() -> bool { + true + } +} + +const ABANANA: bool = A::banana(); + +fn main() { + match true { + ABANANA => {}, + _ => panic!("what?") + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-multi-ref.rs b/gcc/testsuite/rust/rustc/ui/consts/const-multi-ref.rs new file mode 100644 index 000000000000..d21ffd735f43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-multi-ref.rs @@ -0,0 +1,25 @@ +// Ensure that we point the user to the erroneous borrow but not to any subsequent borrows of that +// initial one. + +const _: i32 = { + let mut a = 5; + let p = &mut a; // { dg-error ".E0764." "" { target *-*-* } } + + let reborrow = {p}; + let pp = &reborrow; + let ppp = &pp; + ***ppp +}; + +const _: std::cell::Cell = { + let mut a = std::cell::Cell::new(5); + let p = &a; // { dg-error ".E0492." "" { target *-*-* } } + + let reborrow = {p}; + let pp = &reborrow; + let ppp = &pp; + a +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-mut-refs/const_mut_address_of.rs b/gcc/testsuite/rust/rustc/ui/consts/const-mut-refs/const_mut_address_of.rs new file mode 100644 index 000000000000..ef79b03c2ab2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-mut-refs/const_mut_address_of.rs @@ -0,0 +1,31 @@ +#![feature(const_mut_refs)] +#![feature(const_fn)] +#![feature(raw_ref_op)] + +struct Foo { + x: usize +} + +const fn foo() -> Foo { + Foo { x: 0 } +} + +impl Foo { + const fn bar(&mut self) -> *mut usize { + &raw mut self.x + } +} + +const fn baz(foo: &mut Foo)-> *mut usize { + &raw mut foo.x +} + +const _: () = { + foo().bar(); +// { dg-error ".E0764." "" { target *-*-* } .-1 } + baz(&mut foo()); +// { dg-error ".E0764." "" { target *-*-* } .-1 } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-mut-refs/const_mut_refs.rs b/gcc/testsuite/rust/rustc/ui/consts/const-mut-refs/const_mut_refs.rs new file mode 100644 index 000000000000..c400aaa10abf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-mut-refs/const_mut_refs.rs @@ -0,0 +1,38 @@ +#![feature(const_mut_refs)] + +struct Foo { + x: usize +} + +const fn foo() -> Foo { + Foo { x: 0 } +} + +impl Foo { + const fn bar(&mut self) -> usize { + self.x = 1; + self.x + } + +} + +const fn baz(foo: &mut Foo) -> usize { + let x = &mut foo.x; + *x = 2; + *x +} + +const fn bazz(foo: &mut Foo) -> usize { + foo.x = 3; + foo.x +} + +fn main() { + let _: [(); foo().bar()] = [(); 1]; +// { dg-error ".E0764." "" { target *-*-* } .-1 } + let _: [(); baz(&mut foo())] = [(); 2]; +// { dg-error ".E0764." "" { target *-*-* } .-1 } + let _: [(); bazz(&mut foo())] = [(); 3]; +// { dg-error ".E0764." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-mut-refs/feature-gate-const_mut_refs.rs b/gcc/testsuite/rust/rustc/ui/consts/const-mut-refs/feature-gate-const_mut_refs.rs new file mode 100644 index 000000000000..0d398ae120c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-mut-refs/feature-gate-const_mut_refs.rs @@ -0,0 +1,9 @@ +fn main() { + foo(&mut 5); +} + +const fn foo(x: &mut i32) -> i32 { // { dg-error ".E0658." "" { target *-*-* } } + *x + 1 + +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-needs_drop.rs b/gcc/testsuite/rust/rustc/ui/consts/const-needs_drop.rs new file mode 100644 index 000000000000..5d87ad75ae09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-needs_drop.rs @@ -0,0 +1,30 @@ +// run-pass + +use std::mem; + +struct Trivial(u8, f32); + +struct NonTrivial(u8, String); + +const CONST_U8: bool = mem::needs_drop::(); +const CONST_STRING: bool = mem::needs_drop::(); +const CONST_TRIVIAL: bool = mem::needs_drop::(); +const CONST_NON_TRIVIAL: bool = mem::needs_drop::(); + +static STATIC_U8: bool = mem::needs_drop::(); +static STATIC_STRING: bool = mem::needs_drop::(); +static STATIC_TRIVIAL: bool = mem::needs_drop::(); +static STATIC_NON_TRIVIAL: bool = mem::needs_drop::(); + +fn main() { + assert!(!CONST_U8); + assert!(CONST_STRING); + assert!(!CONST_TRIVIAL); + assert!(CONST_NON_TRIVIAL); + + assert!(!STATIC_U8); + assert!(STATIC_STRING); + assert!(!STATIC_TRIVIAL); + assert!(STATIC_NON_TRIVIAL); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-negation.rs b/gcc/testsuite/rust/rustc/ui/consts/const-negation.rs new file mode 100644 index 000000000000..87474928ae10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-negation.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(overflowing_literals)] + +#[deny(const_err)] + +fn main() { + #[cfg(target_pointer_width = "32")] + const I: isize = -2147483648isize; + #[cfg(target_pointer_width = "64")] + const I: isize = -9223372036854775808isize; + assert_eq!(::std::i32::MIN as u64, 0xffffffff80000000); + assert_eq!(-2147483648isize as u64, 0xffffffff80000000); + assert_eq!(-2147483648i32 as u64, 0xffffffff80000000); + assert_eq!(::std::i64::MIN as u64, 0x8000000000000000); + #[cfg(target_pointer_width = "64")] + assert_eq!(-9223372036854775808isize as u64, 0x8000000000000000); + #[cfg(target_pointer_width = "32")] + assert_eq!(-9223372036854775808isize as u64, 0); + assert_eq!(-9223372036854775808i32 as u64, 0); + const J: usize = ::std::i32::MAX as usize; + const K: usize = -1i32 as u32 as usize; + const L: usize = ::std::i32::MIN as usize; + const M: usize = ::std::i64::MIN as usize; + match 5 { + J => {}, + K => {}, + L => {}, + M => {}, + _ => {} + } + match 5 { + I => {}, + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-negative.rs b/gcc/testsuite/rust/rustc/ui/consts/const-negative.rs new file mode 100644 index 000000000000..9e8db2ba468c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-negative.rs @@ -0,0 +1,10 @@ +// run-pass +// Issue #358 +#![allow(non_upper_case_globals)] + +static toplevel_mod: isize = -1; + +pub fn main() { + assert_eq!(toplevel_mod, -1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-nullary-enum.rs b/gcc/testsuite/rust/rustc/ui/consts/const-nullary-enum.rs new file mode 100644 index 000000000000..2741e211d057 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-nullary-enum.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] + +enum Foo { + Bar, + Baz, + Boo, +} + +static X: Foo = Foo::Bar; + +pub fn main() { + match X { + Foo::Bar => {} + Foo::Baz | Foo::Boo => panic!() + } + match Y { + Foo::Baz => {} + Foo::Bar | Foo::Boo => panic!() + } +} + +static Y: Foo = Foo::Baz; + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-nullary-univariant-enum.rs b/gcc/testsuite/rust/rustc/ui/consts/const-nullary-univariant-enum.rs new file mode 100644 index 000000000000..b1b09215e3d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-nullary-univariant-enum.rs @@ -0,0 +1,16 @@ +// run-pass + +#[derive(Copy, Clone)] +enum Foo { + Bar = 0xDEADBEE +} + +static X: Foo = Foo::Bar; + +pub fn main() { + assert_eq!((X as usize), 0xDEADBEE); + assert_eq!((Y as usize), 0xDEADBEE); +} + +static Y: Foo = Foo::Bar; + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-pattern-irrefutable.rs b/gcc/testsuite/rust/rustc/ui/consts/const-pattern-irrefutable.rs new file mode 100644 index 000000000000..9d454b3c4f7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-pattern-irrefutable.rs @@ -0,0 +1,17 @@ +mod foo { + pub const b: u8 = 2; + pub const d: u8 = 2; +} + +use foo::b as c; +use foo::d; + +const a: u8 = 2; + +fn main() { + let a = 4; // { dg-error ".E0005." "" { target *-*-* } } + let c = 4; // { dg-error ".E0005." "" { target *-*-* } } + let d = 4; // { dg-error ".E0005." "" { target *-*-* } } + fn f() {} // Check that the `NOTE`s still work with an item here (cf. issue #35115). +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-pattern-not-const-evaluable.rs b/gcc/testsuite/rust/rustc/ui/consts/const-pattern-not-const-evaluable.rs new file mode 100644 index 000000000000..a6903745e52c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-pattern-not-const-evaluable.rs @@ -0,0 +1,31 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#[derive(PartialEq, Eq)] +enum Cake { + BlackForest, + Marmor, +} +use Cake::*; + +struct Pair(A, B); + +const BOO: Pair = Pair(Marmor, BlackForest); +const FOO: Cake = BOO.1; + +const fn foo() -> Cake { + Marmor +} + +const WORKS: Cake = Marmor; + +const GOO: Cake = foo(); + +fn main() { + match BlackForest { + FOO => println!("hi"), + GOO => println!("meh"), + WORKS => println!("möp"), + _ => println!("bye"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-pattern-variant.rs b/gcc/testsuite/rust/rustc/ui/consts/const-pattern-variant.rs new file mode 100644 index 000000000000..f3ac14e35cde --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-pattern-variant.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(unreachable_patterns)] + +#[derive(PartialEq, Eq)] +enum Cake { + BlackForest, + Marmor, +} +use Cake::*; + +const BOO: (Cake, Cake) = (Marmor, BlackForest); +const FOO: Cake = BOO.1; + +const fn foo() -> Cake { + Marmor +} + +const WORKS: Cake = Marmor; + +const GOO: Cake = foo(); + +fn main() { + match BlackForest { + FOO => println!("hi"), + GOO => println!("meh"), + WORKS => println!("möp"), + _ => println!("bye"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-points-to-static.rs b/gcc/testsuite/rust/rustc/ui/consts/const-points-to-static.rs new file mode 100644 index 000000000000..db3fd75367c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-points-to-static.rs @@ -0,0 +1,14 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you + +#![allow(dead_code)] + +const TEST: &u8 = &MY_STATIC; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-note ".E0080." "" { target *-*-* } .-2 } +// { dg-note ".E0080." "" { target *-*-* } .-3 } + +static MY_STATIC: u8 = 4; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-prop-ice.rs b/gcc/testsuite/rust/rustc/ui/consts/const-prop-ice.rs new file mode 100644 index 000000000000..10fa2e5f8505 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-prop-ice.rs @@ -0,0 +1,6 @@ +// build-fail + +fn main() { + [0; 3][3u64 as usize]; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-prop-ice2.rs b/gcc/testsuite/rust/rustc/ui/consts/const-prop-ice2.rs new file mode 100644 index 000000000000..72645cc8de39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-prop-ice2.rs @@ -0,0 +1,8 @@ +// build-fail + +fn main() { + enum Enum { One=1 } + let xs=[0;1 as usize]; + println!("{}", xs[Enum::One as usize]); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-prop-ice3.rs b/gcc/testsuite/rust/rustc/ui/consts/const-prop-ice3.rs new file mode 100644 index 000000000000..24d0c0a799d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-prop-ice3.rs @@ -0,0 +1,8 @@ +// run-pass (ensure that const-prop is run) + +struct A(T); + +fn main() { + let _x = &(&A([2, 3]) as &A<[i32]>).0 as *const [i32] as *const i32; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-prop-overflowing-casts.rs b/gcc/testsuite/rust/rustc/ui/consts/const-prop-overflowing-casts.rs new file mode 100644 index 000000000000..e30a73ccfa8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-prop-overflowing-casts.rs @@ -0,0 +1,16 @@ +// check-pass + +enum Foo { + Bar = -42, + Baz = 42, +} + +fn main() { + let _ = 0u8 as u32; + let _ = (1u32 << 31) as u16; + let _ = (1u16 << 15) as u8; + let _ = (!0u16) as u8; + let _ = (-1i16) as i8; + let _ = (Foo::Bar) as i8; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-prop-read-static-in-const.rs b/gcc/testsuite/rust/rustc/ui/consts/const-prop-read-static-in-const.rs new file mode 100644 index 000000000000..53b027da8972 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-prop-read-static-in-const.rs @@ -0,0 +1,11 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you + +#![allow(dead_code)] + +const TEST: u8 = MY_STATIC; // { dg-error "" "" { target *-*-* } } + +static MY_STATIC: u8 = 4; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-ptr-nonnull-rpass.rs b/gcc/testsuite/rust/rustc/ui/consts/const-ptr-nonnull-rpass.rs new file mode 100644 index 000000000000..823722d530f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-ptr-nonnull-rpass.rs @@ -0,0 +1,18 @@ +// run-pass + +#![feature(ptr_internals, test)] + +extern crate test; +use test::black_box as b; // prevent promotion of the argument and const-propagation of the result + +use std::ptr::NonNull; + +const DANGLING: NonNull = NonNull::dangling(); +const CASTED: NonNull = NonNull::cast(NonNull::::dangling()); + +pub fn main() { + // Be super-extra paranoid and cast the fn items to fn pointers before blackboxing them. + assert_eq!(DANGLING, b:: _>(NonNull::dangling)()); + assert_eq!(CASTED, b:: _>(NonNull::dangling)()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-ptr-nonnull.rs b/gcc/testsuite/rust/rustc/ui/consts/const-ptr-nonnull.rs new file mode 100644 index 000000000000..da4165fcf467 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-ptr-nonnull.rs @@ -0,0 +1,12 @@ +use std::ptr::NonNull; + +fn main() { + let x: &'static NonNull = &(NonNull::dangling()); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + + let mut i: i32 = 10; + let non_null = NonNull::new(&mut i).unwrap(); + let x: &'static NonNull = &(non_null.cast()); +// { dg-error ".E0716." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-ptr-unique-rpass.rs b/gcc/testsuite/rust/rustc/ui/consts/const-ptr-unique-rpass.rs new file mode 100644 index 000000000000..e96167da200f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-ptr-unique-rpass.rs @@ -0,0 +1,17 @@ +// run-pass + +#![feature(ptr_internals, test)] + +extern crate test; +use test::black_box as b; // prevent promotion of the argument and const-propagation of the result + +use std::ptr::Unique; + + +const PTR: *mut u32 = Unique::dangling().as_ptr(); + +pub fn main() { + // Be super-extra paranoid and cast the fn items to fn pointers before blackboxing them. + assert_eq!(PTR, b:: _>(Unique::::dangling)().as_ptr()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-ptr-unique.rs b/gcc/testsuite/rust/rustc/ui/consts/const-ptr-unique.rs new file mode 100644 index 000000000000..f200f359ab78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-ptr-unique.rs @@ -0,0 +1,11 @@ +#![feature(ptr_internals)] + +use std::ptr::Unique; + +fn main() { + let mut i: u32 = 10; + let unique = Unique::new(&mut i).unwrap(); + let x: &'static *mut u32 = &(unique.as_ptr()); +// { dg-error ".E0716." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-rec-and-tup.rs b/gcc/testsuite/rust/rustc/ui/consts/const-rec-and-tup.rs new file mode 100644 index 000000000000..54c98a88924b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-rec-and-tup.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] +#![allow(overflowing_literals)] + +struct Pair { a: f64, b: f64 } + +struct AnotherPair { x: (i64, i64), y: Pair } + +static x : (i32,i32) = (0xfeedf00dd,0xca11ab1e); +static y : AnotherPair = AnotherPair{ x: (0xf0f0f0f0_f0f0f0f0, + 0xabababab_abababab), + y: Pair { a: 3.14159265358979323846, + b: 2.7182818284590452354 }}; + +pub fn main() { + let (p, _) = y.x; + assert_eq!(p, - 1085102592571150096); + println!("{:#x}", p); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-region-ptrs-noncopy.rs b/gcc/testsuite/rust/rustc/ui/consts/const-region-ptrs-noncopy.rs new file mode 100644 index 000000000000..c731da4249e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-region-ptrs-noncopy.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +type Big = [u64; 8]; +struct Pair<'a> { a: isize, b: &'a Big } +const x: &'static Big = &([13, 14, 10, 13, 11, 14, 14, 15]); +const y: &'static Pair<'static> = &Pair {a: 15, b: x}; + +pub fn main() { + assert_eq!(x as *const Big, y.b as *const Big); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-region-ptrs.rs b/gcc/testsuite/rust/rustc/ui/consts/const-region-ptrs.rs new file mode 100644 index 000000000000..c5ce3a7977f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-region-ptrs.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(non_upper_case_globals)] + +struct Pair<'a> { a: isize, b: &'a isize } + +const x: &'static isize = &10; + +const y: &'static Pair<'static> = &Pair {a: 15, b: x}; + +pub fn main() { + println!("x = {}", *x); + println!("y = {{a: {}, b: {}}}", y.a, *(y.b)); + assert_eq!(*x, 10); + assert_eq!(*(y.b), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-repeated-values.rs b/gcc/testsuite/rust/rustc/ui/consts/const-repeated-values.rs new file mode 100644 index 000000000000..e556fe465f04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-repeated-values.rs @@ -0,0 +1,11 @@ +// run-pass +const FOO: isize = 42; + +enum Bar { + Boo = *[&FOO; 4][3], +} + +fn main() { + assert_eq!(Bar::Boo as isize, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-size_of-align_of.rs b/gcc/testsuite/rust/rustc/ui/consts/const-size_of-align_of.rs new file mode 100644 index 000000000000..b3d4fce8a25e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-size_of-align_of.rs @@ -0,0 +1,52 @@ +// run-pass +#![allow(dead_code)] + +use std::mem; + +// Get around the limitations of CTFE in today's Rust. +const fn choice_u64(c: bool, a: u64, b: u64) -> u64 { + (-(c as i64) as u64) & a | (-(!c as i64) as u64) & b +} + +const fn max_usize(a: usize, b: usize) -> usize { + choice_u64(a > b, a as u64, b as u64) as usize +} + +const fn align_to(size: usize, align: usize) -> usize { + (size + (align - 1)) & !(align - 1) +} + +const fn packed_union_size_of() -> usize { + max_usize(mem::size_of::(), mem::size_of::()) +} + +const fn union_align_of() -> usize { + max_usize(mem::align_of::(), mem::align_of::()) +} + +const fn union_size_of() -> usize { + align_to(packed_union_size_of::(), union_align_of::()) +} + +macro_rules! fake_union { + ($name:ident { $a:ty, $b:ty }) => ( + struct $name { + _align: ([$a; 0], [$b; 0]), + _bytes: [u8; union_size_of::<$a, $b>()] + } + ) +} + +// Check that we can (poorly) emulate unions by +// calling size_of and align_of at compile-time. +fake_union!(U { u16, [u8; 3] }); + +fn test(u: U) { + assert_eq!(mem::size_of_val(&u._bytes), 4); +} + +fn main() { + assert_eq!(mem::size_of::(), 4); + assert_eq!(mem::align_of::(), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-size_of-cycle.rs b/gcc/testsuite/rust/rustc/ui/consts/const-size_of-cycle.rs new file mode 100644 index 000000000000..26165d34fb0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-size_of-cycle.rs @@ -0,0 +1,8 @@ +// error-pattern: cycle detected + +struct Foo { + bytes: [u8; std::mem::size_of::()] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-size_of_val-align_of_val-extern-type.rs b/gcc/testsuite/rust/rustc/ui/consts/const-size_of_val-align_of_val-extern-type.rs new file mode 100644 index 000000000000..fddd71957e92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-size_of_val-align_of_val-extern-type.rs @@ -0,0 +1,15 @@ +#![feature(extern_types)] +#![feature(core_intrinsics)] +#![feature(const_size_of_val, const_align_of_val)] + +use std::intrinsics::{size_of_val, min_align_of_val}; + +extern { + type Opaque; +} + +const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; // { dg-error "" "" { target *-*-* } } +const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) }; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-size_of_val-align_of_val.rs b/gcc/testsuite/rust/rustc/ui/consts/const-size_of_val-align_of_val.rs new file mode 100644 index 000000000000..8e7643a4e3ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-size_of_val-align_of_val.rs @@ -0,0 +1,46 @@ +// run-pass + +#![feature(const_size_of_val, const_align_of_val)] + +use std::mem; + +struct Foo(u32); + +#[derive(Clone, Copy)] +struct Bar { + _x: u8, + _y: u16, + _z: u8, +} + +union Ugh { + _a: [u8; 3], + _b: Bar, +} + +const FOO: Foo = Foo(4); +const BAR: Bar = Bar { _x: 4, _y: 1, _z: 2 }; +const UGH: Ugh = Ugh { _a: [0; 3] }; + +const SIZE_OF_FOO: usize = mem::size_of_val(&FOO); +const SIZE_OF_BAR: usize = mem::size_of_val(&BAR); +const SIZE_OF_UGH: usize = mem::size_of_val(&UGH); + +const ALIGN_OF_FOO: usize = mem::align_of_val(&FOO); +const ALIGN_OF_BAR: usize = mem::align_of_val(&BAR); +const ALIGN_OF_UGH: usize = mem::align_of_val(&UGH); + +const SIZE_OF_SLICE: usize = mem::size_of_val("foobar".as_bytes()); + +fn main() { + assert_eq!(SIZE_OF_FOO, mem::size_of::()); + assert_eq!(SIZE_OF_BAR, mem::size_of::()); + assert_eq!(SIZE_OF_UGH, mem::size_of::()); + + assert_eq!(ALIGN_OF_FOO, mem::align_of::()); + assert_eq!(ALIGN_OF_BAR, mem::align_of::()); + assert_eq!(ALIGN_OF_UGH, mem::align_of::()); + + assert_eq!(SIZE_OF_SLICE, "foobar".len()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-slice-oob.rs b/gcc/testsuite/rust/rustc/ui/consts/const-slice-oob.rs new file mode 100644 index 000000000000..1d4c4f5fbd1e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-slice-oob.rs @@ -0,0 +1,11 @@ +#[deny(const_err)] + +const FOO: &'static[u32] = &[1, 2, 3]; +const BAR: u32 = FOO[5]; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { + let _ = BAR; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-str-ptr.rs b/gcc/testsuite/rust/rustc/ui/consts/const-str-ptr.rs new file mode 100644 index 000000000000..d8b85297dc07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-str-ptr.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(unused_imports)] +use std::{str, string}; + +const A: [u8; 2] = ['h' as u8, 'i' as u8]; +const B: &'static [u8; 2] = &A; +const C: *const u8 = B as *const u8; + +pub fn main() { + unsafe { + let foo = &A as *const u8; + assert_eq!(foo, C); + assert_eq!(str::from_utf8_unchecked(&A), "hi"); + assert_eq!(*C, A[0]); + assert_eq!(*(&B[0] as *const u8), A[0]); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-struct-offsets.rs b/gcc/testsuite/rust/rustc/ui/consts/const-struct-offsets.rs new file mode 100644 index 000000000000..2c0f3727e4b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-struct-offsets.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 +#![allow(non_upper_case_globals)] + +enum Foo { + IntVal(i32), + Int64Val(i64) +} + +struct Bar { + i: i32, + v: Foo +} + +static bar: Bar = Bar { i: 0, v: Foo::IntVal(0) }; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-struct.rs b/gcc/testsuite/rust/rustc/ui/consts/const-struct.rs new file mode 100644 index 000000000000..78c031d9de80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-struct.rs @@ -0,0 +1,33 @@ +// run-pass +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] + +use std::cmp; + +#[derive(Debug)] +struct foo { a: isize, b: isize, c: isize } + +impl cmp::PartialEq for foo { + fn eq(&self, other: &foo) -> bool { + (*self).a == (*other).a && + (*self).b == (*other).b && + (*self).c == (*other).c + } + fn ne(&self, other: &foo) -> bool { !(*self).eq(other) } +} + +const x : foo = foo { a:1, b:2, c: 3 }; +const y : foo = foo { b:2, c:3, a: 1 }; +const z : &'static foo = &foo { a: 10, b: 22, c: 12 }; +const w : foo = foo { a:5, ..x }; + +pub fn main() { + assert_eq!(x.b, 2); + assert_eq!(x, y); + assert_eq!(z.b, 22); + assert_eq!(w.a, 5); + assert_eq!(w.c, 3); + println!("{:#x}", x.b); + println!("{:#x}", z.c); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-trait-to-trait.rs b/gcc/testsuite/rust/rustc/ui/consts/const-trait-to-trait.rs new file mode 100644 index 000000000000..85ea1ebcc34c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-trait-to-trait.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Issue #24644 - block causes a &Trait -> &Trait coercion: +trait Trait {} + +struct Bar; +impl Trait for Bar {} + +fn main() { + let x: &[&dyn Trait] = &[{ &Bar }]; +} + +// Issue #25748 - the cast causes an &Encoding -> &Encoding coercion: +pub struct UTF8Encoding; +pub const UTF_8: &'static UTF8Encoding = &UTF8Encoding; +pub trait Encoding {} +impl Encoding for UTF8Encoding {} +pub fn f() -> &'static dyn Encoding { UTF_8 as &'static dyn Encoding } + +// Root of the problem: &Trait -> &Trait coercions: +const FOO: &'static dyn Trait = &Bar; +const BAR: &'static dyn Trait = FOO; +fn foo() { let _x = BAR; } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-tup-index-span.rs b/gcc/testsuite/rust/rustc/ui/consts/const-tup-index-span.rs new file mode 100644 index 000000000000..a94b573bb875 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-tup-index-span.rs @@ -0,0 +1,10 @@ +// Test spans of errors + +const TUP: (usize,) = 5usize << 64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +const ARR: [i32; TUP.0] = []; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/consts/const-tuple-struct.rs new file mode 100644 index 000000000000..8ed604c42a79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-tuple-struct.rs @@ -0,0 +1,15 @@ +// run-pass + +struct Bar(isize, isize); + +static X: Bar = Bar(1, 2); + +pub fn main() { + match X { + Bar(x, y) => { + assert_eq!(x, 1); + assert_eq!(y, 2); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/consts/const-type-mismatch.rs new file mode 100644 index 000000000000..fcc4b5063d9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-type-mismatch.rs @@ -0,0 +1,12 @@ +// `const`s shouldn't suggest `.into()` + +const TEN: u8 = 10; +const TWELVE: u16 = TEN + 2; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + +fn main() { + const TEN: u8 = 10; + const ALSO_TEN: u16 = TEN; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-typeid-of-rpass.rs b/gcc/testsuite/rust/rustc/ui/consts/const-typeid-of-rpass.rs new file mode 100644 index 000000000000..6e5c206f1bc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-typeid-of-rpass.rs @@ -0,0 +1,35 @@ +// run-pass +#![feature(const_type_id)] +#![feature(core_intrinsics)] + +use std::any::TypeId; + +struct A; + +static ID_ISIZE: TypeId = TypeId::of::(); + +pub fn main() { + assert_eq!(ID_ISIZE, TypeId::of::()); + + // sanity test of TypeId + const T: (TypeId, TypeId, TypeId) = (TypeId::of::(), + TypeId::of::<&'static str>(), + TypeId::of::()); + let (d, e, f) = (TypeId::of::(), TypeId::of::<&'static str>(), + TypeId::of::()); + + assert!(T.0 != T.1); + assert!(T.0 != T.2); + assert!(T.1 != T.2); + + assert_eq!(T.0, d); + assert_eq!(T.1, e); + assert_eq!(T.2, f); + + // Check fn pointer against collisions + const F: (TypeId, TypeId) = (TypeId::of:: A) -> A>(), + TypeId::of:: A, A) -> A>()); + + assert!(F.0 != F.1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-unit-struct.rs b/gcc/testsuite/rust/rustc/ui/consts/const-unit-struct.rs new file mode 100644 index 000000000000..a7dee8228521 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-unit-struct.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct Foo; + +static X: Foo = Foo; + +pub fn main() { + match X { + Foo => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-unsafe-fn.rs b/gcc/testsuite/rust/rustc/ui/consts/const-unsafe-fn.rs new file mode 100644 index 000000000000..96489f9ab509 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-unsafe-fn.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(dead_code)] +// A quick test of 'unsafe const fn' functionality + +const unsafe fn dummy(v: u32) -> u32 { + !v +} + +struct Type; +impl Type { + const unsafe fn new() -> Type { + Type + } +} + +const VAL: u32 = unsafe { dummy(0xFFFF) }; +const TYPE_INST: Type = unsafe { Type::new() }; + +fn main() { + assert_eq!(VAL, 0xFFFF0000); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-unsized.rs b/gcc/testsuite/rust/rustc/ui/consts/const-unsized.rs new file mode 100644 index 000000000000..57451f13cc3d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-unsized.rs @@ -0,0 +1,18 @@ +use std::fmt::Debug; + +const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +const CONST_FOO: str = *"foo"; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +static STATIC_BAR: str = *"bar"; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { + println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-unwrap.rs b/gcc/testsuite/rust/rustc/ui/consts/const-unwrap.rs new file mode 100644 index 000000000000..cab83ee97336 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-unwrap.rs @@ -0,0 +1,15 @@ +// check-fail + +#![feature(const_option)] + +const FOO: i32 = Some(42i32).unwrap(); + +// This causes an error, but it is attributed to the `panic` *inside* `Option::unwrap` (maybe due +// to `track_caller`?). A note points to the originating `const`. +const BAR: i32 = Option::::None.unwrap(); // { dg-note "" "" { target *-*-* } } + +fn main() { + println!("{}", FOO); + println!("{}", BAR); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-validation-fail-55455.rs b/gcc/testsuite/rust/rustc/ui/consts/const-validation-fail-55455.rs new file mode 100644 index 000000000000..8331eb06bd4f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-validation-fail-55455.rs @@ -0,0 +1,10 @@ +// https://github.com/rust-lang/rust/issues/55454 +// build-pass (FIXME(62277): could be check-pass?) + +struct This(T); + +const C: This> = This(Some(&1)); + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-variant-count.rs b/gcc/testsuite/rust/rustc/ui/consts/const-variant-count.rs new file mode 100644 index 000000000000..902f4e2d15d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-variant-count.rs @@ -0,0 +1,48 @@ +// run-pass +#![allow(dead_code)] +#![feature(variant_count)] +#![feature(never_type)] + +use std::mem::variant_count; + +enum Void {} + +enum Foo { + A, + B, + C, +} + +enum Bar { + A, + B, + C, + D(usize), + E { field_1: usize, field_2: Foo }, +} + +struct Baz { + a: u32, + b: *const u8, +} + +const TEST_VOID: usize = variant_count::(); +const TEST_FOO: usize = variant_count::(); +const TEST_BAR: usize = variant_count::(); + +const NO_ICE_STRUCT: usize = variant_count::(); +const NO_ICE_BOOL: usize = variant_count::(); +const NO_ICE_PRIM: usize = variant_count::<*const u8>(); + +fn main() { + assert_eq!(TEST_VOID, 0); + assert_eq!(TEST_FOO, 3); + assert_eq!(TEST_BAR, 5); + assert_eq!(variant_count::(), 0); + assert_eq!(variant_count::(), 3); + assert_eq!(variant_count::(), 5); + assert_eq!(variant_count::>(), 2); + assert_eq!(variant_count::>(), 2); + assert_eq!(variant_count::>(), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-vec-of-fns.rs b/gcc/testsuite/rust/rustc/ui/consts/const-vec-of-fns.rs new file mode 100644 index 000000000000..e3ef5a6c7bb8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-vec-of-fns.rs @@ -0,0 +1,26 @@ +// run-pass +// pretty-expanded FIXME #23616 +#![allow(non_upper_case_globals)] + +/*! + * Try to double-check that static fns have the right size (with or + * without dummy env ptr, as appropriate) by iterating a size-2 array. + * If the static size differs from the runtime size, the second element + * should be read as a null or otherwise wrong pointer and crash. + */ + +fn f() { } +static bare_fns: &'static [fn()] = &[f, f]; +struct S(F); +static mut closures: &'static mut [S] = &mut [S(f as fn()), S(f as fn())]; + +pub fn main() { + unsafe { + for &bare_fn in bare_fns { bare_fn() } + for closure in &mut *closures { + let S(ref mut closure) = *closure; + (*closure)() + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-vec-syntax.rs b/gcc/testsuite/rust/rustc/ui/consts/const-vec-syntax.rs new file mode 100644 index 000000000000..ef7d4f43af79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-vec-syntax.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn f(_: &[isize]) {} + +pub fn main() { + let v = [ 1, 2, 3 ]; + f(&v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const-vecs-and-slices.rs b/gcc/testsuite/rust/rustc/ui/consts/const-vecs-and-slices.rs new file mode 100644 index 000000000000..bb39fa297d8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const-vecs-and-slices.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(non_upper_case_globals)] + +static x : [isize; 4] = [1,2,3,4]; +static y : &'static [isize] = &[1,2,3,4]; +static z : &'static [isize; 4] = &[1,2,3,4]; +static zz : &'static [isize] = &[1,2,3,4]; + +pub fn main() { + println!("{}", x[1]); + println!("{}", y[1]); + println!("{}", z[1]); + println!("{}", zz[1]); + assert_eq!(x[1], 2); + assert_eq!(x[3], 4); + assert_eq!(x[3], y[3]); + assert_eq!(z[1], 2); + assert_eq!(z[3], 4); + assert_eq!(z[3], y[3]); + assert_eq!(zz[1], 2); + assert_eq!(zz[3], 4); + assert_eq!(zz[3], y[3]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const.rs b/gcc/testsuite/rust/rustc/ui/consts/const.rs new file mode 100644 index 000000000000..45ebb87625e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const.rs @@ -0,0 +1,7 @@ +// run-pass +#![allow(non_upper_case_globals)] + +static i: isize = 10; + +pub fn main() { println!("{}", i); } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_arg_local.rs b/gcc/testsuite/rust/rustc/ui/consts/const_arg_local.rs new file mode 100644 index 000000000000..5273cffec21e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_arg_local.rs @@ -0,0 +1,14 @@ +// only-x86_64 + +#[cfg(target_arch = "x86")] +use std::arch::x86::*; +#[cfg(target_arch = "x86_64")] +use std::arch::x86_64::*; + +unsafe fn pclmul(a: __m128i, b: __m128i) -> __m128i { + let imm8 = 3; + _mm_clmulepi64_si128(a, b, imm8) // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_arg_promotable.rs b/gcc/testsuite/rust/rustc/ui/consts/const_arg_promotable.rs new file mode 100644 index 000000000000..250926364fa5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_arg_promotable.rs @@ -0,0 +1,13 @@ +// only-x86_64 + +#[cfg(target_arch = "x86")] +use std::arch::x86::*; +#[cfg(target_arch = "x86_64")] +use std::arch::x86_64::*; + +unsafe fn pclmul(a: __m128i, b: __m128i) -> __m128i { + _mm_clmulepi64_si128(a, b, *&mut 42) // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_arg_promotable2.rs b/gcc/testsuite/rust/rustc/ui/consts/const_arg_promotable2.rs new file mode 100644 index 000000000000..73a635ef29cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_arg_promotable2.rs @@ -0,0 +1,19 @@ +// This test is a regression test for a bug where we only checked function calls in no-const +// functions for `rustc_args_required_const` arguments. This meant that even though `bar` needs its +// argument to be const, inside a const fn (callable at runtime), the value for it may come from a +// non-constant (namely an argument to the const fn). + +#![feature(rustc_attrs)] +const fn foo(a: i32) { + bar(a); // { dg-error "" "" { target *-*-* } } +} + +#[rustc_args_required_const(0)] +const fn bar(_: i32) {} + +fn main() { + // this function call will pass a runtime-value (number of program arguments) to `foo`, which + // will in turn forward it to `bar`, which expects a compile-time argument + foo(std::env::args().count() as i32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_arg_wrapper.rs b/gcc/testsuite/rust/rustc/ui/consts/const_arg_wrapper.rs new file mode 100644 index 000000000000..e599a3bffb10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_arg_wrapper.rs @@ -0,0 +1,13 @@ +// only-x86_64 + +#[cfg(target_arch = "x86")] +use std::arch::x86::*; +#[cfg(target_arch = "x86_64")] +use std::arch::x86_64::*; + +unsafe fn pclmul(a: __m128i, b: __m128i, imm8: i32) -> __m128i { + _mm_clmulepi64_si128(a, b, imm8) // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_constructor/const-construct-call.rs b/gcc/testsuite/rust/rustc/ui/consts/const_constructor/const-construct-call.rs new file mode 100644 index 000000000000..d3825e83a019 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_constructor/const-construct-call.rs @@ -0,0 +1,115 @@ +// Test that constructors are considered to be const fns with the required feature. + +// run-pass + +// revisions: min_const_fn const_fn + +#![cfg_attr(const_fn, feature(const_fn))] + +// Ctor(..) is transformed to Ctor { 0: ... } in THIR lowering, so directly +// calling constructors doesn't require them to be const. + +type ExternalType = std::panic::AssertUnwindSafe<(Option, Result)>; + +const fn call_external_constructors_in_local_vars() -> ExternalType { + let f = Some; + let g = Err; + let h = std::panic::AssertUnwindSafe; + let x = f(5); + let y = g(false); + let z = h((x, y)); + z +} + +const CALL_EXTERNAL_CONSTRUCTORS_IN_LOCAL_VARS: ExternalType = { + let f = Some; + let g = Err; + let h = std::panic::AssertUnwindSafe; + let x = f(5); + let y = g(false); + let z = h((x, y)); + z +}; + +const fn call_external_constructors_in_temps() -> ExternalType { + let x = { Some }(5); + let y = (*&Err)(false); + let z = [std::panic::AssertUnwindSafe][0]((x, y)); + z +} + +const CALL_EXTERNAL_CONSTRUCTORS_IN_TEMPS: ExternalType = { + let x = { Some }(5); + let y = (*&Err)(false); + let z = [std::panic::AssertUnwindSafe][0]((x, y)); + z +}; + +#[derive(Debug, PartialEq)] +enum LocalOption { + Some(T), + _None, +} + +#[derive(Debug, PartialEq)] +enum LocalResult { + _Ok(T), + Err(E), +} + +#[derive(Debug, PartialEq)] +struct LocalAssertUnwindSafe(T); + +type LocalType = LocalAssertUnwindSafe<(LocalOption, LocalResult)>; + +const fn call_local_constructors_in_local_vars() -> LocalType { + let f = LocalOption::Some; + let g = LocalResult::Err; + let h = LocalAssertUnwindSafe; + let x = f(5); + let y = g(false); + let z = h((x, y)); + z +} + +const CALL_LOCAL_CONSTRUCTORS_IN_LOCAL_VARS: LocalType = { + let f = LocalOption::Some; + let g = LocalResult::Err; + let h = LocalAssertUnwindSafe; + let x = f(5); + let y = g(false); + let z = h((x, y)); + z +}; + +const fn call_local_constructors_in_temps() -> LocalType { + let x = { LocalOption::Some }(5); + let y = (*&LocalResult::Err)(false); + let z = [LocalAssertUnwindSafe][0]((x, y)); + z +} + +const CALL_LOCAL_CONSTRUCTORS_IN_TEMPS: LocalType = { + let x = { LocalOption::Some }(5); + let y = (*&LocalResult::Err)(false); + let z = [LocalAssertUnwindSafe][0]((x, y)); + z +}; + +fn main() { + assert_eq!( + ( + call_external_constructors_in_local_vars().0, + call_external_constructors_in_temps().0, + call_local_constructors_in_local_vars(), + call_local_constructors_in_temps(), + ), + ( + CALL_EXTERNAL_CONSTRUCTORS_IN_LOCAL_VARS.0, + CALL_EXTERNAL_CONSTRUCTORS_IN_TEMPS.0, + CALL_LOCAL_CONSTRUCTORS_IN_LOCAL_VARS, + CALL_LOCAL_CONSTRUCTORS_IN_TEMPS, + ) + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_constructor/const_constructor_qpath.rs b/gcc/testsuite/rust/rustc/ui/consts/const_constructor/const_constructor_qpath.rs new file mode 100644 index 000000000000..4db74db0f215 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_constructor/const_constructor_qpath.rs @@ -0,0 +1,41 @@ +// revisions: min_const_fn const_fn +// run-pass + +#![cfg_attr(const_fn, feature(const_fn))] + +trait ConstDefault { + const DEFAULT: Self; +} + +#[derive(PartialEq)] +enum E { + V(i32), + W(usize), +} + +impl ConstDefault for E { + const DEFAULT: Self = Self::V(23); +} + +impl ConstDefault for Option { + const DEFAULT: Self = Self::Some(23); +} + +impl E { + const NON_DEFAULT: Self = Self::W(12); + const fn local_fn() -> Self { + Self::V(23) + } +} + +const fn explicit_qpath() -> E { + let _x = >::Some(23); + ::W(12) +} + +fn main() { + assert!(E::DEFAULT == E::local_fn()); + assert!(Option::DEFAULT == Some(23)); + assert!(E::NON_DEFAULT == explicit_qpath()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_discriminant.rs b/gcc/testsuite/rust/rustc/ui/consts/const_discriminant.rs new file mode 100644 index 000000000000..79dcfd3e55a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_discriminant.rs @@ -0,0 +1,37 @@ +// run-pass +#![feature(const_discriminant)] +#![feature(test)] +#![allow(dead_code)] + +use std::mem::{discriminant, Discriminant}; +use std::hint::black_box; + +enum Test { + A(u8), + B, + C { a: u8, b: u8 }, +} + +const TEST_A: Discriminant = discriminant(&Test::A(5)); +const TEST_A_OTHER: Discriminant = discriminant(&Test::A(17)); +const TEST_B: Discriminant = discriminant(&Test::B); + +enum Void {} + +enum SingleVariant { + V, + Never(Void), +} + +const TEST_V: Discriminant = discriminant(&SingleVariant::V); + +fn main() { + assert_eq!(TEST_A, TEST_A_OTHER); + assert_eq!(TEST_A, discriminant(black_box(&Test::A(17)))); + assert_eq!(TEST_B, discriminant(black_box(&Test::B))); + assert_ne!(TEST_A, TEST_B); + assert_ne!(TEST_B, discriminant(black_box(&Test::C { a: 42, b: 7 }))); + + assert_eq!(TEST_V, discriminant(black_box(&SingleVariant::V))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_fn_floating_point_arithmetic.rs b/gcc/testsuite/rust/rustc/ui/consts/const_fn_floating_point_arithmetic.rs new file mode 100644 index 000000000000..00bb35fce949 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_fn_floating_point_arithmetic.rs @@ -0,0 +1,21 @@ +// gate-test-const_fn_floating_point_arithmetic + +// revisions: stock gated + +#![feature(rustc_attrs)] +#![cfg_attr(gated, feature(const_fn_floating_point_arithmetic))] + +const fn add(f: f32) -> f32 { f + 2.0 } +// { dg-error "" "" { target *-*-* } .-1 } +const fn sub(f: f32) -> f32 { 2.0 - f } +// { dg-error "" "" { target *-*-* } .-1 } +const fn mul(f: f32, g: f32) -> f32 { f * g } +// { dg-error "" "" { target *-*-* } .-1 } +const fn div(f: f32, g: f32) -> f32 { f / g } +// { dg-error "" "" { target *-*-* } .-1 } +const fn neg(f: f32) -> f32 { -f } +// { dg-error "" "" { target *-*-* } .-1 } + +#[rustc_error] +fn main() {} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_fn_return_nested_fn_ptr.rs b/gcc/testsuite/rust/rustc/ui/consts/const_fn_return_nested_fn_ptr.rs new file mode 100644 index 000000000000..486832355f71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_fn_return_nested_fn_ptr.rs @@ -0,0 +1,11 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:const_fn_lib.rs + +extern crate const_fn_lib; + +fn main() { + const_fn_lib::bar()(); + const_fn_lib::bar_inlined()(); + const_fn_lib::bar_inlined_always()(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_forget.rs b/gcc/testsuite/rust/rustc/ui/consts/const_forget.rs new file mode 100644 index 000000000000..3ddf5a044335 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_forget.rs @@ -0,0 +1,21 @@ +// check-pass + +use std::mem::forget; + +const _: () = forget(0i32); +const _: () = forget(Vec::>>::new()); + +// Writing this function signature without const-forget +// triggers compiler errors: +// 1) That we use a non-const fn inside a const fn +// 2) without the forget, it complains about the destructor of Box +// +// FIXME: this method cannot be called in const-eval yet, as Box isn't +// const constructable +#[allow(unused)] +const fn const_forget_box(b: Box) { + forget(b); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/accept_structural.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/accept_structural.rs new file mode 100644 index 000000000000..37646c950ed6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/accept_structural.rs @@ -0,0 +1,67 @@ +// run-pass + +#![warn(indirect_structural_match)] + +// This test is checking our logic for structural match checking by enumerating +// the different kinds of const expressions. This test is collecting cases where +// we have accepted the const expression as a pattern in the past and wish to +// continue doing so. +// +// Even if a non-structural-match type is part of an expression in a const's +// definition, that does not necessarily disqualify the const from being a match +// pattern: in principle, we just need the types involved in the final value to +// be structurally matchable. + +// See also RFC 1445 + +#![feature(type_ascription)] + +#[derive(Copy, Clone, Debug)] +struct NoPartialEq(u32); + +#[derive(Copy, Clone, Debug)] +struct NoDerive(u32); + +// This impl makes `NoDerive` irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } +impl Eq for NoDerive { } + +type OND = Option; + +fn main() { + const FIELD1: u32 = NoPartialEq(1).0; + match 1 { FIELD1 => dbg!(FIELD1), _ => panic!("whoops"), }; + const FIELD2: u32 = NoDerive(1).0; + match 1 { FIELD2 => dbg!(FIELD2), _ => panic!("whoops"), }; + + enum CLike { One = 1, #[allow(dead_code)] Two = 2, } + const ONE_CAST: u32 = CLike::One as u32; + match 1 { ONE_CAST => dbg!(ONE_CAST), _ => panic!("whoops"), }; + + const NO_DERIVE_NONE: OND = None; + const INDIRECT: OND = NO_DERIVE_NONE; + match None { INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; + + const TUPLE: (OND, OND) = (None, None); + match (None, None) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; + + const TYPE_ASCRIPTION: OND = None: OND; + match None { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; + + const ARRAY: [OND; 2] = [None, None]; + match [None; 2] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; + + const REPEAT: [OND; 2] = [None; 2]; + match [None, None] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; + + trait Trait: Sized { const ASSOC: Option; } + impl Trait for NoDerive { const ASSOC: Option = None; } + match None { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; + + const BLOCK: OND = { NoDerive(10); None }; + match None { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; + + const ADDR_OF: &OND = &None; + match &None { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/auxiliary/consts.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/auxiliary/consts.rs new file mode 100644 index 000000000000..84ea93387870 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/auxiliary/consts.rs @@ -0,0 +1,17 @@ +pub struct CustomEq; + +impl Eq for CustomEq {} +impl PartialEq for CustomEq { + fn eq(&self, _: &Self) -> bool { + false + } +} + +pub const NONE: Option = None; +pub const SOME: Option = Some(CustomEq); + +pub trait AssocConst { + const NONE: Option = None; + const SOME: Option = Some(CustomEq); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/cross-crate-fail.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/cross-crate-fail.rs new file mode 100644 index 000000000000..2bce7688edda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/cross-crate-fail.rs @@ -0,0 +1,26 @@ +// aux-build:consts.rs + +#![warn(indirect_structural_match)] + +extern crate consts; + +struct Defaulted; +impl consts::AssocConst for Defaulted {} + +fn main() { + let _ = Defaulted; + match None { + consts::SOME => panic!(), +// { dg-error "" "" { target *-*-* } .-1 } + + _ => {} + } + + match None { + ::SOME => panic!(), +// { dg-error "" "" { target *-*-* } .-1 } + + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/cross-crate-pass.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/cross-crate-pass.rs new file mode 100644 index 000000000000..c5d92544f266 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/cross-crate-pass.rs @@ -0,0 +1,24 @@ +// run-pass +// aux-build:consts.rs + +#![warn(indirect_structural_match)] + +extern crate consts; +use consts::CustomEq; + +struct Defaulted; +impl consts::AssocConst for Defaulted {} + +fn main() { + let _ = Defaulted; + match Some(CustomEq) { + consts::NONE => panic!(), + _ => {} + } + + match Some(CustomEq) { + ::NONE => panic!(), + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/custom-eq-branch-pass.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/custom-eq-branch-pass.rs new file mode 100644 index 000000000000..97607c92cbcb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/custom-eq-branch-pass.rs @@ -0,0 +1,33 @@ +// run-pass + +#![warn(indirect_structural_match)] + +struct CustomEq; + +impl Eq for CustomEq {} +impl PartialEq for CustomEq { + fn eq(&self, _: &Self) -> bool { + false + } +} + +#[derive(PartialEq, Eq)] +enum Foo { + Bar, + Baz, + Qux(CustomEq), +} + +const BAR_BAZ: Foo = if 42 == 42 { + Foo::Bar +} else { + Foo::Baz +}; + +fn main() { + match Foo::Qux(CustomEq) { + BAR_BAZ => panic!(), + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/custom-eq-branch-warn.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/custom-eq-branch-warn.rs new file mode 100644 index 000000000000..6190e7798830 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/custom-eq-branch-warn.rs @@ -0,0 +1,37 @@ +// check-pass + +struct CustomEq; + +impl Eq for CustomEq {} +impl PartialEq for CustomEq { + fn eq(&self, _: &Self) -> bool { + false + } +} + +#[derive(PartialEq, Eq)] +enum Foo { + Bar, + Baz, + Qux(CustomEq), +} + +// We know that `BAR_BAZ` will always be `Foo::Bar` and thus eligible for structural matching, but +// dataflow will be more conservative. +const BAR_BAZ: Foo = if 42 == 42 { + Foo::Bar +} else { + Foo::Qux(CustomEq) +}; + +fn main() { + match Foo::Qux(CustomEq) { + BAR_BAZ => panic!(), +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +// { dg-note "" "" { target *-*-* } .-4 } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-44333.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-44333.rs new file mode 100644 index 000000000000..e98f3188eb72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-44333.rs @@ -0,0 +1,26 @@ +// run-pass + +#![warn(pointer_structural_match)] + +type Func = fn(usize, usize) -> usize; + +fn foo(a: usize, b: usize) -> usize { a + b } +fn bar(a: usize, b: usize) -> usize { a * b } +fn test(x: usize) -> Func { + if x % 2 == 0 { foo } + else { bar } +} + +const FOO: Func = foo; +const BAR: Func = bar; + +fn main() { + match test(std::env::consts::ARCH.len()) { + FOO => println!("foo"), // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + BAR => println!("bar"), // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + _ => unreachable!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-53708.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-53708.rs new file mode 100644 index 000000000000..a211c4bc688c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-53708.rs @@ -0,0 +1,12 @@ +// check-pass +// https://github.com/rust-lang/rust/issues/53708 +#[derive(PartialEq, Eq)] +struct S; + +fn main() { + const C: &S = &S; + match C { + C => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-62614.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-62614.rs new file mode 100644 index 000000000000..dbe97984d59a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-62614.rs @@ -0,0 +1,25 @@ +// run-pass + +struct Sum(u32, u32); + +impl PartialEq for Sum { + fn eq(&self, other: &Self) -> bool { self.0 + self.1 == other.0 + other.1 } +} + +impl Eq for Sum { } + +#[derive(PartialEq, Eq)] +enum Eek { + TheConst, + UnusedByTheConst(Sum) +} + +const THE_CONST: Eek = Eek::TheConst; + +pub fn main() { + match Eek::UnusedByTheConst(Sum(1,2)) { + THE_CONST => { panic!(); } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-65466.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-65466.rs new file mode 100644 index 000000000000..2d84edd77a93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-65466.rs @@ -0,0 +1,22 @@ +#![deny(indirect_structural_match)] + +// check-pass + +#[derive(PartialEq, Eq)] +enum O { + Some(*const T), // Can also use PhantomData + None, +} + +struct B; + +const C: &[O] = &[O::None]; + +fn main() { + let x = O::None; + match &[x][..] { + C => (), + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-73431.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-73431.rs new file mode 100644 index 000000000000..fd2363a81c3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-73431.rs @@ -0,0 +1,30 @@ +// run-pass + +// Regression test for https://github.com/rust-lang/rust/issues/73431. + +pub trait Zero { + const ZERO: Self; +} + +impl Zero for usize { + const ZERO: Self = 0; +} + +impl Zero for Wrapper { + const ZERO: Self = Wrapper(T::ZERO); +} + +#[derive(Debug, PartialEq, Eq)] +pub struct Wrapper(T); + +fn is_zero(x: Wrapper) -> bool { + match x { + Zero::ZERO => true, + _ => false, + } +} + +fn main() { + let _ = is_zero(Wrapper(42)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-78057.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-78057.rs new file mode 100644 index 000000000000..1ba3b9085f3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/issue-78057.rs @@ -0,0 +1,18 @@ +#![deny(unreachable_patterns)] + +#[derive(PartialEq)] +struct Opaque(i32); + +impl Eq for Opaque {} + +const FOO: Opaque = Opaque(42); + +fn main() { + match FOO { + FOO => {}, +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/no-eq-branch-fail.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/no-eq-branch-fail.rs new file mode 100644 index 000000000000..8839c02469cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/no-eq-branch-fail.rs @@ -0,0 +1,26 @@ +#![warn(indirect_structural_match)] + +struct NoEq; + +enum Foo { + Bar, + Baz, + Qux(NoEq), +} + +// Even though any of these values can be compared structurally, we still disallow it in a pattern +// because `Foo` does not impl `PartialEq`. +const BAR_BAZ: Foo = if 42 == 42 { + Foo::Baz +} else { + Foo::Bar +}; + +fn main() { + match Foo::Qux(NoEq) { + BAR_BAZ => panic!(), +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/reject_non_partial_eq.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/reject_non_partial_eq.rs new file mode 100644 index 000000000000..862954d632a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/reject_non_partial_eq.rs @@ -0,0 +1,33 @@ +// This test is illustrating the difference between how failing to derive +// `PartialEq` is handled compared to failing to implement it at all. + +// See also RFC 1445 + +#[derive(PartialEq, Eq)] +struct Structural(u32); + +struct NoPartialEq(u32); + +struct NoDerive(u32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +const NO_DERIVE_NONE: Option = None; +const NO_PARTIAL_EQ_NONE: Option = None; + +fn main() { + match None { + NO_DERIVE_NONE => println!("NO_DERIVE_NONE"), + _ => panic!("whoops"), + } + + match None { + NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"), +// { dg-error "" "" { target *-*-* } .-1 } + _ => panic!("whoops"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/reject_non_structural.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/reject_non_structural.rs new file mode 100644 index 000000000000..bc32bee12092 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/reject_non_structural.rs @@ -0,0 +1,84 @@ +// This test of structural match checking enumerates the different kinds of +// const definitions, collecting cases where the const pattern is rejected. +// +// Note: Even if a non-structural-match type is part of an expression in a +// const's definition, that does not necessarily disqualify the const from being +// a match pattern: in principle, we just need the types involved in the final +// value to be structurally matchable. + +// See also RFC 1445 + +#![feature(type_ascription)] +#![warn(indirect_structural_match)] +// { dg-note "" "" { target *-*-* } .-1 } + +#[derive(Copy, Clone, Debug)] +struct NoPartialEq; + +#[derive(Copy, Clone, Debug)] +struct NoDerive; + +// This impl makes `NoDerive` irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +type OND = Option; + +struct TrivialEq(OND); + +// This impl makes `TrivialEq` trivial. +impl PartialEq for TrivialEq { fn eq(&self, _: &Self) -> bool { true } } + +impl Eq for TrivialEq { } + +fn main() { + #[derive(PartialEq, Eq, Debug)] + enum Derive { Some(X), None, } + + const ENUM: Derive = Derive::Some(NoDerive); + match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), }; +// { dg-error "" "" { target *-*-* } .-1 } + + const FIELD: OND = TrivialEq(Some(NoDerive)).0; + match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; +// { dg-error "" "" { target *-*-* } .-1 } + + const NO_DERIVE_SOME: OND = Some(NoDerive); + const INDIRECT: OND = NO_DERIVE_SOME; + match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; +// { dg-error "" "" { target *-*-* } .-1 } + + const TUPLE: (OND, OND) = (None, Some(NoDerive)); + match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; +// { dg-error "" "" { target *-*-* } .-1 } + + const TYPE_ASCRIPTION: OND = Some(NoDerive): OND; + match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; +// { dg-error "" "" { target *-*-* } .-1 } + + const ARRAY: [OND; 2] = [None, Some(NoDerive)]; + match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; +// { dg-error "" "" { target *-*-* } .-1 } + + const REPEAT: [OND; 2] = [Some(NoDerive); 2]; + match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + trait Trait: Sized { const ASSOC: Option; } + impl Trait for NoDerive { const ASSOC: Option = Some(NoDerive); } + match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; +// { dg-error "" "" { target *-*-* } .-1 } + + const BLOCK: OND = { NoDerive; Some(NoDerive) }; + match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; +// { dg-error "" "" { target *-*-* } .-1 } + + const ADDR_OF: &OND = &Some(NoDerive); + match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/warn_corner_cases.rs b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/warn_corner_cases.rs new file mode 100644 index 000000000000..2e064278a665 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_in_pattern/warn_corner_cases.rs @@ -0,0 +1,42 @@ +// run-pass + +// This test is checking our logic for structural match checking by enumerating +// the different kinds of const expressions. This test is collecting cases where +// we have accepted the const expression as a pattern in the past but we want +// to begin warning the user that a future version of Rust may start rejecting +// such const expressions. + +// The specific corner cases we are exploring here are instances where the +// const-evaluator computes a value that *does* meet the conditions for +// structural-match, but the const expression itself has abstractions (like +// calls to const functions) that may fit better with a type-based analysis +// rather than a commitment to a specific value. + +#![warn(indirect_structural_match)] + +#[derive(Copy, Clone, Debug)] +struct NoDerive(u32); + +// This impl makes `NoDerive` irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } +impl Eq for NoDerive { } + +fn main() { + const INDEX: Option = [None, Some(NoDerive(10))][0]; + match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), }; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + const fn build() -> Option { None } + const CALL: Option = build(); + match None { Some(_) => panic!("whoops"), CALL => dbg!(CALL), }; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + impl NoDerive { const fn none() -> Option { None } } + const METHOD_CALL: Option = NoDerive::none(); + match None { Some(_) => panic!("whoops"), METHOD_CALL => dbg!(METHOD_CALL), }; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_let_assign.rs b/gcc/testsuite/rust/rustc/ui/consts/const_let_assign.rs new file mode 100644 index 000000000000..5105bb476fe2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_let_assign.rs @@ -0,0 +1,11 @@ +// check-pass + +struct S(i32); + +const A: () = { + let mut s = S(0); + s.0 = 1; +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_let_assign2.rs b/gcc/testsuite/rust/rustc/ui/consts/const_let_assign2.rs new file mode 100644 index 000000000000..538334ef4f57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_let_assign2.rs @@ -0,0 +1,23 @@ +// check-pass + +pub struct AA { + pub data: [u8; 10], +} + +impl AA { + pub const fn new() -> Self { + let mut res: AA = AA { data: [0; 10] }; + res.data[0] = 5; + res + } +} + +static mut BB: AA = AA::new(); + +fn main() { + let ptr = unsafe { &mut BB }; + for a in ptr.data.iter() { + println!("{}", a); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_let_assign3.rs b/gcc/testsuite/rust/rustc/ui/consts/const_let_assign3.rs new file mode 100644 index 000000000000..4de56be2793d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_let_assign3.rs @@ -0,0 +1,30 @@ +#![feature(const_fn)] + +struct S { + state: u32, +} + +impl S { + const fn foo(&mut self, x: u32) { +// { dg-error ".E0658." "" { target *-*-* } .-1 } + self.state = x; + } +} + +const FOO: S = { + let mut s = S { state: 42 }; + s.foo(3); // { dg-error ".E0764." "" { target *-*-* } } + s +}; + +type Array = [u32; { + let mut x = 2; + let y = &mut x; // { dg-error ".E0764." "" { target *-*-* } } + *y = 42; + *y +}]; + +fn main() { + assert_eq!(FOO.state, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_let_eq.rs b/gcc/testsuite/rust/rustc/ui/consts/const_let_eq.rs new file mode 100644 index 000000000000..7cf89bc221db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_let_eq.rs @@ -0,0 +1,470 @@ +// run-pass + +struct Foo(T); +struct Bar { x: T } +struct W(u32); +struct A { a: u32 } + +#[allow(redundant_semicolons)] +const fn basics((a,): (u32,)) -> u32 { + // Deferred assignment: + let b: u32; + b = a + 1; + + // Immediate assignment: + let c: u32 = b + 1; + + // Mutables: + let mut d: u32 = c + 1; + d = d + 1; + // +4 so far. + + // No effect statements work: + ; ; + 1; + + // Array projection + let mut arr: [u32; 1] = [0]; + arr[0] = 1; + d = d + arr[0]; + // +5 + + // Field projection: + let mut foo: Foo = Foo(0); + let mut bar: Bar = Bar { x: 0 }; + foo.0 = 1; + bar.x = 1; + d = d + foo.0 + bar.x; + // +7 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(0)]; + arr[0].0 = 1; + d = d + arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 0 }]; + arr[0].x = 1; + d = d + arr[0].x; + // +9 + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([0]); + (arr.0)[0] = 1; + d = d + (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [0] }; + arr.x[0] = 1; + d = d + arr.x[0]; + // +11 + + d +} + +const fn add_assign(W(a): W) -> u32 { + // Mutables: + let mut d: u32 = a + 1; + d += 1; + // +2 so far. + + // Array projection + let mut arr: [u32; 1] = [0]; + arr[0] += 1; + d += arr[0]; + // +3 + + // Field projection: + let mut foo: Foo = Foo(0); + let mut bar: Bar = Bar { x: 0 }; + foo.0 += 1; + bar.x += 1; + d += foo.0 + bar.x; + // +5 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(0)]; + arr[0].0 += 1; + d += arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 0 }]; + arr[0].x += 1; + d += arr[0].x; + // +7 + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([0]); + (arr.0)[0] += 1; + d += (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [0] }; + arr.x[0] += 1; + d += arr.x[0]; + // +9 + + d +} + +const fn mul_assign(A { a }: A) -> u32 { + // Mutables: + let mut d: u32 = a + 1; + d *= 2; + // 2^1 * (a + 1) + + // Array projection + let mut arr: [u32; 1] = [1]; + arr[0] *= 2; + d *= arr[0]; + // 2^2 * (a + 1) + + // Field projection: + let mut foo: Foo = Foo(1); + let mut bar: Bar = Bar { x: 1 }; + foo.0 *= 2; + bar.x *= 2; + d *= foo.0 + bar.x; + // 2^4 * (a + 1) + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(1)]; + arr[0].0 *= 2; + d *= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 1 }]; + arr[0].x *= 2; + d *= arr[0].x; + // 2^6 * (a + 1) + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([1]); + (arr.0)[0] *= 2; + d *= (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [1] }; + arr.x[0] *= 2; + d *= arr.x[0]; + // 2^8 * (a + 1) + + d +} + +const fn div_assign(a: [u32; 1]) -> u32 { + let a = a[0]; + // Mutables: + let mut d: u32 = 1024 * a; + d /= 2; + // 512 + + // Array projection + let mut arr: [u32; 1] = [4]; + arr[0] /= 2; + d /= arr[0]; + // 256 + + // Field projection: + let mut foo: Foo = Foo(4); + let mut bar: Bar = Bar { x: 4 }; + foo.0 /= 2; + bar.x /= 2; + d /= foo.0; + d /= bar.x; + // 64 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(4)]; + arr[0].0 /= 2; + d /= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 4 }]; + arr[0].x /= 2; + d /= arr[0].x; + // 16 + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([4]); + (arr.0)[0] /= 2; + d /= (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [4] }; + arr.x[0] /= 2; + d /= arr.x[0]; + // 4 + + d +} + +const fn rem_assign(W(a): W) -> u32 { + // Mutables: + let mut d: u32 = a; + d %= 10; + d += 10; + + // Array projection + let mut arr: [u32; 1] = [3]; + arr[0] %= 2; + d %= 9 + arr[0]; + d += 10; + + // Field projection: + let mut foo: Foo = Foo(5); + let mut bar: Bar = Bar { x: 7 }; + foo.0 %= 2; + bar.x %= 2; + d %= 8 + foo.0 + bar.x; + d += 10; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(4)]; + arr[0].0 %= 3; + d %= 9 + arr[0].0; + d += 10; + let mut arr: [Bar; 1] = [Bar { x: 7 }]; + arr[0].x %= 3; + d %= 9 + arr[0].x; + d += 10; + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([6]); + (arr.0)[0] %= 5; + d %= 9 + (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [11] }; + arr.x[0] %= 5; + d %= 9 + arr.x[0]; + + d +} + +const fn sub_assign(W(a): W) -> u32 { + // Mutables: + let mut d: u32 = a; + d -= 1; + + // Array projection + let mut arr: [u32; 1] = [2]; + arr[0] -= 1; + d -= arr[0]; + + // Field projection: + let mut foo: Foo = Foo(2); + let mut bar: Bar = Bar { x: 2 }; + foo.0 -= 1; + bar.x -= 1; + d -= foo.0 + bar.x; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(2)]; + arr[0].0 -= 1; + d -= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 2 }]; + arr[0].x -= 1; + d -= arr[0].x; + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([2]); + (arr.0)[0] -= 1; + d -= (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [2] }; + arr.x[0] -= 1; + d -= arr.x[0]; + + d +} + +const fn shl_assign(W(a): W) -> u32 { + // Mutables: + let mut d: u32 = a; + d <<= 1; // 10 + + // Array projection + let mut arr: [u32; 1] = [1]; + arr[0] <<= 1; + d <<= arr[0]; // 10 << 2 + + // Field projection: + let mut foo: Foo = Foo(1); + let mut bar: Bar = Bar { x: 1 }; + foo.0 <<= 1; + bar.x <<= 1; + d <<= foo.0 + bar.x; // 1000 << 4 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(1)]; + arr[0].0 <<= 1; + d <<= arr[0].0; // 1000_0000 << 2 + let mut arr: [Bar; 1] = [Bar { x: 1 }]; + arr[0].x <<= 1; + d <<= arr[0].x; // 1000_0000_00 << 2 + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([1]); + (arr.0)[0] <<= 1; + d <<= (arr.0)[0]; // 1000_0000_0000 << 2 + let mut arr: Bar<[u32; 1]> = Bar { x: [1] }; + arr.x[0] <<= 1; + d <<= arr.x[0]; // 1000_0000_0000_00 << 2 + + d +} + +const fn shr_assign(W(a): W) -> u32 { + // Mutables: + let mut d: u32 = a; + d >>= 1; // /= 2 + + // Array projection + let mut arr: [u32; 1] = [2]; + arr[0] >>= 1; + d >>= arr[0]; // /= 4 + + // Field projection: + let mut foo: Foo = Foo(2); + let mut bar: Bar = Bar { x: 2 }; + foo.0 >>= 1; + bar.x >>= 1; + d >>= foo.0 + bar.x; // /= 16 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(2)]; + arr[0].0 >>= 1; + d >>= arr[0].0; // /= 32 + let mut arr: [Bar; 1] = [Bar { x: 2 }]; + arr[0].x >>= 1; + d >>= arr[0].x; // /= 64 + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([2]); + (arr.0)[0] >>= 1; + d >>= (arr.0)[0]; // /= 128 + let mut arr: Bar<[u32; 1]> = Bar { x: [2] }; + arr.x[0] >>= 1; + d >>= arr.x[0]; // /= 256 + + d +} + +const fn bit_and_assign(W(a): W) -> u32 { + let f = 0b1111_1111_1111_1111; + + // Mutables: + let mut d: u32 = a; + d &= 0b1111_1111_1111_1110; + + // Array projection + let mut arr: [u32; 1] = [f]; + arr[0] &= 0b1111_1111_1111_1101; + d &= arr[0]; + + // Field projection: + let mut foo: Foo = Foo(f); + let mut bar: Bar = Bar { x: f }; + foo.0 &= 0b1111_1111_1111_0111; + bar.x &= 0b1111_1111_1101_1111; + d &= foo.0 & bar.x; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(f)]; + arr[0].0 &= 0b1111_1110_1111_1111; + d &= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: f }]; + arr[0].x &= 0b1111_1101_1111_1111; + d &= arr[0].x; + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([f]); + (arr.0)[0] &= 0b1011_1111_1111_1111; + d &= (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [f] }; + arr.x[0] &= 0b0111_1111_1111_1111; + d &= arr.x[0]; + + d +} + +const fn bit_or_assign(W(a): W) -> u32 { + let f = 0b0000_0000_0000_0000; + + // Mutables: + let mut d: u32 = a; + d |= 0b0000_0000_0000_0001; + + // Array projection + let mut arr: [u32; 1] = [f]; + arr[0] |= 0b0000_0000_0000_1001; + d |= arr[0]; + + // Field projection: + let mut foo: Foo = Foo(f); + let mut bar: Bar = Bar { x: f }; + foo.0 |= 0b0000_0000_0001_0000; + bar.x |= 0b0000_0000_0100_0000; + d |= foo.0 | bar.x; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(f)]; + arr[0].0 |= 0b0000_0001_0000_0000; + d |= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: f }]; + arr[0].x |= 0b0000_0010_0000_0000; + d |= arr[0].x; + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([f]); + (arr.0)[0] |= 0b1000_0000_0000_0000; + d |= (arr.0)[0]; // /= 128 + let mut arr: Bar<[u32; 1]> = Bar { x: [f] }; + arr.x[0] |= 0b1100_0000_0000_0000; + d |= arr.x[0]; // /= 256 + + d +} + +const fn bit_xor_assign(W(a): W) -> u32 { + let f = 0b0000_0000_0000_0000; + + // Mutables: + let mut d: u32 = a; + d ^= 0b0000_0000_0000_0001; + + // Array projection + let mut arr: [u32; 1] = [f]; + arr[0] ^= 0b0000_0000_0000_0010; + d ^= arr[0]; + + // Field projection: + let mut foo: Foo = Foo(f); + let mut bar: Bar = Bar { x: f }; + foo.0 ^= 0b0000_0000_0001_0000; + bar.x ^= 0b0000_0000_1000_0000; + d ^= foo.0 ^ bar.x; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(f)]; + arr[0].0 ^= 0b0000_0001_0000_0000; + d ^= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: f }]; + arr[0].x ^= 0b0000_0010_0000_0000; + d ^= arr[0].x; + + // Field + Array projection: + let mut arr: Foo<[u32; 1]> = Foo([f]); + (arr.0)[0] ^= 0b0100_0000_0000_0000; + d ^= (arr.0)[0]; + let mut arr: Bar<[u32; 1]> = Bar { x: [f] }; + arr.x[0] ^= 0b1000_0000_0000_0000; + d ^= arr.x[0]; + + d +} + +macro_rules! test { + ($c:ident, $e:expr, $r:expr) => { + const $c: u32 = $e; + assert_eq!($c, $r); + assert_eq!($e, $r); + } +} + +fn main() { + test!(BASICS, basics((2,)), 13); + test!(ADD, add_assign(W(1)), 10); + test!(MUL, mul_assign(A { a: 0 }), 256); + test!(DIV, div_assign([1]), 4); + test!(REM, rem_assign(W(5)), 5); + test!(SUB, sub_assign(W(8)), 0); + test!(SHL, shl_assign(W(1)), 0b1000_0000_0000_0000); + test!(SHR, shr_assign(W(256)), 1); + test!(AND, bit_and_assign(W(0b1011_1111_1111_1111_1111)), 0b0011_1100_1101_0100); + test!(OR, bit_or_assign(W(0b1011_0000_0000_0000)), 0b1111_0011_0101_1001); + test!(XOR, bit_xor_assign(W(0b0000_0000_0000_0000)), 0b1100_0011_1001_0011); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_let_eq_float.rs b/gcc/testsuite/rust/rustc/ui/consts/const_let_eq_float.rs new file mode 100644 index 000000000000..503fcb741ee8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_let_eq_float.rs @@ -0,0 +1,281 @@ +// run-pass + +#![feature(const_fn_floating_point_arithmetic)] + +struct Foo(T); +struct Bar { x: T } +struct W(f32); +struct A { a: f32 } + +#[allow(redundant_semicolons)] +const fn basics((a,): (f32,)) -> f32 { + // Deferred assignment: + let b: f32; + b = a + 1.0; + + // Immediate assignment: + let c: f32 = b + 1.0; + + // Mutables: + let mut d: f32 = c + 1.0; + d = d + 1.0; + // +4 so far. + + // No effect statements work: + ; ; + 1; + + // Array projection + let mut arr: [f32; 1] = [0.0]; + arr[0] = 1.0; + d = d + arr[0]; + // +5 + + // Field projection: + let mut foo: Foo = Foo(0.0); + let mut bar: Bar = Bar { x: 0.0 }; + foo.0 = 1.0; + bar.x = 1.0; + d = d + foo.0 + bar.x; + // +7 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(0.0)]; + arr[0].0 = 1.0; + d = d + arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 0.0 }]; + arr[0].x = 1.0; + d = d + arr[0].x; + // +9 + + // Field + Array projection: + let mut arr: Foo<[f32; 1]> = Foo([0.0]); + (arr.0)[0] = 1.0; + d = d + (arr.0)[0]; + let mut arr: Bar<[f32; 1]> = Bar { x: [0.0] }; + arr.x[0] = 1.0; + d = d + arr.x[0]; + // +11 + + d +} + +const fn add_assign(W(a): W) -> f32 { + // Mutables: + let mut d: f32 = a + 1.0; + d += 1.0; + // +2 so far. + + // Array projection + let mut arr: [f32; 1] = [0.0]; + arr[0] += 1.0; + d += arr[0]; + // +3 + + // Field projection: + let mut foo: Foo = Foo(0.0); + let mut bar: Bar = Bar { x: 0.0 }; + foo.0 += 1.0; + bar.x += 1.0; + d += foo.0 + bar.x; + // +5 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(0.0)]; + arr[0].0 += 1.0; + d += arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 0.0 }]; + arr[0].x += 1.0; + d += arr[0].x; + // +7 + + // Field + Array projection: + let mut arr: Foo<[f32; 1]> = Foo([0.0]); + (arr.0)[0] += 1.0; + d += (arr.0)[0]; + let mut arr: Bar<[f32; 1]> = Bar { x: [0.0] }; + arr.x[0] += 1.0; + d += arr.x[0]; + // +9 + + d +} + +const fn mul_assign(A { a }: A) -> f32 { + // Mutables: + let mut d: f32 = a + 1.0; + d *= 2.0; + // 2^1 * (a + 1) + + // Array projection + let mut arr: [f32; 1] = [1.0]; + arr[0] *= 2.0; + d *= arr[0]; + // 2^2 * (a + 1) + + // Field projection: + let mut foo: Foo = Foo(1.0); + let mut bar: Bar = Bar { x: 1.0 }; + foo.0 *= 2.0; + bar.x *= 2.0; + d *= foo.0 + bar.x; + // 2^4 * (a + 1) + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(1.0)]; + arr[0].0 *= 2.0; + d *= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 1.0 }]; + arr[0].x *= 2.0; + d *= arr[0].x; + // 2^6 * (a + 1) + + // Field + Array projection: + let mut arr: Foo<[f32; 1]> = Foo([1.0]); + (arr.0)[0] *= 2.0; + d *= (arr.0)[0]; + let mut arr: Bar<[f32; 1]> = Bar { x: [1.0] }; + arr.x[0] *= 2.0; + d *= arr.x[0]; + // 2^8 * (a + 1) + + d +} + +const fn div_assign(a: [f32; 1]) -> f32 { + let a = a[0]; + // Mutables: + let mut d: f32 = 1024.0 * a; + d /= 2.0; + // 512 + + // Array projection + let mut arr: [f32; 1] = [4.0]; + arr[0] /= 2.0; + d /= arr[0]; + // 256 + + // Field projection: + let mut foo: Foo = Foo(4.0); + let mut bar: Bar = Bar { x: 4.0 }; + foo.0 /= 2.0; + bar.x /= 2.0; + d /= foo.0; + d /= bar.x; + // 64 + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(4.0)]; + arr[0].0 /= 2.0; + d /= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 4.0 }]; + arr[0].x /= 2.0; + d /= arr[0].x; + // 16 + + // Field + Array projection: + let mut arr: Foo<[f32; 1]> = Foo([4.0]); + (arr.0)[0] /= 2.0; + d /= (arr.0)[0]; + let mut arr: Bar<[f32; 1]> = Bar { x: [4.0] }; + arr.x[0] /= 2.0; + d /= arr.x[0]; + // 4 + + d +} + +const fn rem_assign(W(a): W) -> f32 { + // Mutables: + let mut d: f32 = a; + d %= 10.0; + d += 10.0; + + // Array projection + let mut arr: [f32; 1] = [3.0]; + arr[0] %= 2.0; + d %= 9.0 + arr[0]; + d += 10.0; + + // Field projection: + let mut foo: Foo = Foo(5.0); + let mut bar: Bar = Bar { x: 7.0 }; + foo.0 %= 2.0; + bar.x %= 2.0; + d %= 8.0 + foo.0 + bar.x; + d += 10.0; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(4.0)]; + arr[0].0 %= 3.0; + d %= 9.0 + arr[0].0; + d += 10.0; + let mut arr: [Bar; 1] = [Bar { x: 7.0 }]; + arr[0].x %= 3.0; + d %= 9.0 + arr[0].x; + d += 10.0; + + // Field + Array projection: + let mut arr: Foo<[f32; 1]> = Foo([6.0]); + (arr.0)[0] %= 5.0; + d %= 9.0 + (arr.0)[0]; + let mut arr: Bar<[f32; 1]> = Bar { x: [11.0] }; + arr.x[0] %= 5.0; + d %= 9.0 + arr.x[0]; + + d +} + +const fn sub_assign(W(a): W) -> f32 { + // Mutables: + let mut d: f32 = a; + d -= 1.0; + + // Array projection + let mut arr: [f32; 1] = [2.0]; + arr[0] -= 1.0; + d -= arr[0]; + + // Field projection: + let mut foo: Foo = Foo(2.0); + let mut bar: Bar = Bar { x: 2.0 }; + foo.0 -= 1.0; + bar.x -= 1.0; + d -= foo.0 + bar.x; + + // Array + Field projection: + let mut arr: [Foo; 1] = [Foo(2.0)]; + arr[0].0 -= 1.0; + d -= arr[0].0; + let mut arr: [Bar; 1] = [Bar { x: 2.0 }]; + arr[0].x -= 1.0; + d -= arr[0].x; + + // Field + Array projection: + let mut arr: Foo<[f32; 1]> = Foo([2.0]); + (arr.0)[0] -= 1.0; + d -= (arr.0)[0]; + let mut arr: Bar<[f32; 1]> = Bar { x: [2.0] }; + arr.x[0] -= 1.0; + d -= arr.x[0]; + + d +} + +macro_rules! test { + ($c:ident, $e:expr, $r:expr) => { + const $c: f32 = $e; + assert_eq!($c, $r); + assert_eq!($e, $r); + } +} + +fn main() { + test!(BASICS, basics((2.0,)), 13.0); + test!(ADD, add_assign(W(1.0)), 10.0); + test!(MUL, mul_assign(A { a: 0.0 }), 256.0); + test!(DIV, div_assign([1.0]), 4.0); + test!(REM, rem_assign(W(5.0)), 5.0); + test!(SUB, sub_assign(W(8.0)), 0.0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_let_irrefutable.rs b/gcc/testsuite/rust/rustc/ui/consts/const_let_irrefutable.rs new file mode 100644 index 000000000000..7b668e0109a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_let_irrefutable.rs @@ -0,0 +1,12 @@ +// build-pass (FIXME(62277): could be check-pass?) + +fn main() {} + +const fn tup((a, b): (i32, i32)) -> i32 { + a + b +} + +const fn array([a, b]: [i32; 2]) -> i32 { + a + b +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_let_promote.rs b/gcc/testsuite/rust/rustc/ui/consts/const_let_promote.rs new file mode 100644 index 000000000000..7cce31577a97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_let_promote.rs @@ -0,0 +1,18 @@ +// run-pass + +use std::cell::Cell; + +const X: Option> = None; + +const Y: Option> = { + let x = None; + x +}; + +// Ensure that binding the final value of a `const` to a variable does not affect promotion. +#[allow(unused)] +fn main() { + let x: &'static _ = &X; + let y: &'static _ = &Y; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_let_refutable.rs b/gcc/testsuite/rust/rustc/ui/consts/const_let_refutable.rs new file mode 100644 index 000000000000..dd8f18188b08 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_let_refutable.rs @@ -0,0 +1,7 @@ +fn main() {} + +const fn slice(&[a, b]: &[i32]) -> i32 { +// { dg-error ".E0005." "" { target *-*-* } .-1 } + a + b +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_limit/const_eval_limit_not_reached.rs b/gcc/testsuite/rust/rustc/ui/consts/const_limit/const_eval_limit_not_reached.rs new file mode 100644 index 000000000000..f101109df1b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_limit/const_eval_limit_not_reached.rs @@ -0,0 +1,21 @@ +// check-pass + +#![feature(const_eval_limit)] + +// This needs to be higher than the number of loop iterations since each pass through the loop may +// hit more than one terminator. +#![const_eval_limit="4000"] + +const X: usize = { + let mut x = 0; + while x != 1000 { + x += 1; + } + + x +}; + +fn main() { + assert_eq!(X, 1000); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_limit/const_eval_limit_overflow.rs b/gcc/testsuite/rust/rustc/ui/consts/const_limit/const_eval_limit_overflow.rs new file mode 100644 index 000000000000..b6bfaeff64be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_limit/const_eval_limit_overflow.rs @@ -0,0 +1,16 @@ +#![feature(const_eval_limit)] +#![const_eval_limit="18_446_744_073_709_551_615"] +// { dg-error "" "" { target *-*-* } .-1 } + +const CONSTANT: usize = limit(); + +fn main() { + assert_eq!(CONSTANT, 1764); +} + +const fn limit() -> usize { + let x = 42; + + x * 42 +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_limit/const_eval_limit_reached.rs b/gcc/testsuite/rust/rustc/ui/consts/const_limit/const_eval_limit_reached.rs new file mode 100644 index 000000000000..61a2ecc1807f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_limit/const_eval_limit_reached.rs @@ -0,0 +1,17 @@ +#![feature(const_eval_limit)] +#![const_eval_limit = "500"] + +const X: usize = { + let mut x = 0; + while x != 1000 { +// { dg-error "" "" { target *-*-* } .-1 } + x += 1; + } + + x +}; + +fn main() { + assert_eq!(X, 1000); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_limit/feature-gate-const_eval_limit.rs b/gcc/testsuite/rust/rustc/ui/consts/const_limit/feature-gate-const_eval_limit.rs new file mode 100644 index 000000000000..e72fb7df7edb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_limit/feature-gate-const_eval_limit.rs @@ -0,0 +1,15 @@ +#![const_eval_limit="42"] +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +const CONSTANT: usize = limit(); + +fn main() { + assert_eq!(CONSTANT, 1764); +} + +const fn limit() -> usize { + let x = 42; + + x * 42 +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_prop_slice_pat_ice.rs b/gcc/testsuite/rust/rustc/ui/consts/const_prop_slice_pat_ice.rs new file mode 100644 index 000000000000..553f48ce6349 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_prop_slice_pat_ice.rs @@ -0,0 +1,9 @@ +// check-pass + +fn main() { + match &[0, 1] as &[i32] { + [a @ .., x] => {} + &[] => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_short_circuit.rs b/gcc/testsuite/rust/rustc/ui/consts/const_short_circuit.rs new file mode 100644 index 000000000000..f86c2ad4dcf5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_short_circuit.rs @@ -0,0 +1,15 @@ +// check-pass + +const _: bool = false && false; +const _: bool = true && false; +const _: bool = { + let mut x = true && false; + x +}; +const _: bool = { + let x = true && false; + x +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_unsafe_unreachable.rs b/gcc/testsuite/rust/rustc/ui/consts/const_unsafe_unreachable.rs new file mode 100644 index 000000000000..968ec5ced3db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_unsafe_unreachable.rs @@ -0,0 +1,18 @@ +// run-pass + +#![feature(const_fn)] +#![feature(const_unreachable_unchecked)] + +const unsafe fn foo(x: bool) -> bool { + match x { + true => true, + false => std::hint::unreachable_unchecked(), + } +} + +const BAR: bool = unsafe { foo(true) }; + +fn main() { + assert_eq!(BAR, true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/const_unsafe_unreachable_ub.rs b/gcc/testsuite/rust/rustc/ui/consts/const_unsafe_unreachable_ub.rs new file mode 100644 index 000000000000..38272fbe3fe6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/const_unsafe_unreachable_ub.rs @@ -0,0 +1,21 @@ +// build-fail + +#![feature(const_fn)] +#![feature(const_unreachable_unchecked)] + +const unsafe fn foo(x: bool) -> bool { + match x { + true => true, + false => std::hint::unreachable_unchecked(), + } +} + +#[warn(const_err)] +const BAR: bool = unsafe { foo(false) }; + +fn main() { + assert_eq!(BAR, true); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/consts-in-patterns.rs b/gcc/testsuite/rust/rustc/ui/consts/consts-in-patterns.rs new file mode 100644 index 000000000000..40c8e77c6d9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/consts-in-patterns.rs @@ -0,0 +1,29 @@ +// run-pass + +const FOO: isize = 10; +const BAR: isize = 3; +const ZST: &() = unsafe { std::mem::transmute(1usize) }; +const ZST_ARR: &[u8; 0] = unsafe { std::mem::transmute(1usize) }; + +const fn foo() -> isize { 4 } +const BOO: isize = foo(); + +pub fn main() { + let x: isize = 3; + let y = match x { + FOO => 1, + BAR => 2, + BOO => 4, + _ => 3 + }; + assert_eq!(y, 2); + let z = match &() { + ZST => 9, + }; + assert_eq!(z, 9); + let z = match b"" { + ZST_ARR => 10, + }; + assert_eq!(z, 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/assert.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/assert.rs new file mode 100644 index 000000000000..891932f43e67 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/assert.rs @@ -0,0 +1,15 @@ +// Test that `assert` works when `const_panic` is enabled. + +// revisions: stock const_panic + +#![cfg_attr(const_panic, feature(const_panic))] + +const _: () = assert!(true); +// { dg-error "" "" { target *-*-* } .-1 } + +const _: () = assert!(false); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/basics.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/basics.rs new file mode 100644 index 000000000000..3775ed31425a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/basics.rs @@ -0,0 +1,86 @@ +// Test basic functionality of control flow in a const context. + +// run-pass + +#![feature(const_panic)] +#![feature(const_fn)] + +const X: u32 = 4; +const Y: u32 = 5; + +const ABS_DIFF: u32 = if X < Y { + Y - X +} else { + X - Y +}; + +const fn abs_diff(a: u32, b: u32) -> u32 { + match (a, b) { + (big, little) if big > little => big - little, + (little, big) => big - little, + } +} + +const fn gcd(a: u32, b: u32) -> u32 { + if b == 0 { + return a; + } + + gcd(b, a % b) +} + +const fn fib(n: u64) -> u64 { + if n == 0 { + return 0; + } + + let mut fib = (0, 1); + let mut i = 1; + while i < n { + fib = (fib.1, fib.0 + fib.1); + i += 1; + } + + fib.1 +} + +const fn is_prime(n: u64) -> bool { + if n % 2 == 0 { + return false; + } + + let mut div = 3; + loop { + if n % div == 0 { + return false; + } + + if div * div > n { + return true; + } + + div += 2; + } +} + +macro_rules! const_assert { + ($expr:expr) => { + const _: () = assert!($expr); + assert!($expr); + } +} + +fn main() { + const_assert!(abs_diff(4, 5) == abs_diff(5, 4)); + const_assert!(ABS_DIFF == abs_diff(5, 4)); + + const_assert!(gcd(48, 18) == 6); + const_assert!(gcd(18, 48) == 6); + + const_assert!(fib(2) == 1); + const_assert!(fib(8) == 21); + + const_assert!(is_prime(113)); + const_assert!(!is_prime(117)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/drop-fail.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/drop-fail.rs new file mode 100644 index 000000000000..d7513f342aae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/drop-fail.rs @@ -0,0 +1,63 @@ +// revisions: stock precise + +#![cfg_attr(precise, feature(const_precise_live_drops))] + +// `x` is *not* always moved into the final value and may be dropped inside the initializer. +const _: Option> = { + let y: Option> = None; + let x = Some(Vec::new()); +// { dg-error "" "" { target *-*-* } .-1 } + + if true { + x + } else { + y + } +}; + +// We only clear `NeedsDrop` if a local is moved from in entirely. This is a shortcoming of the +// existing analysis. +const _: Vec = { + let vec_tuple = (Vec::new(),); +// { dg-error "" "" { target *-*-* } .-1 } + + vec_tuple.0 +}; + +// This applies to single-field enum variants as well. +const _: Vec = { + let x: Result<_, Vec> = Ok(Vec::new()); +// { dg-error "" "" { target *-*-* } .-1 } + + match x { + Ok(x) | Err(x) => x, + } +}; + +const _: Option> = { + let mut some = Some(Vec::new()); + let mut tmp = None; +// { dg-error "" "" { target *-*-* } .-1 } + + let mut i = 0; + while i < 10 { + tmp = some; + some = None; + + // We can escape the loop with `Some` still in `tmp`, + // which would require that it be dropped at the end of the block. + if i > 100 { + break; + } + + some = tmp; + tmp = None; + + i += 1; + } + + some +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/drop-pass.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/drop-pass.rs new file mode 100644 index 000000000000..b4f6766410c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/drop-pass.rs @@ -0,0 +1,47 @@ +// run-pass +// revisions: stock precise + +#![allow(unused)] +#![cfg_attr(precise, feature(const_precise_live_drops))] + +// `x` is always moved into the final value and is not dropped inside the initializer. +const _: Option> = { + let y: Option> = None; + let x = Some(Vec::new()); + + if true { + x + } else { + x + } +}; + +const _: Option> = { + let x = Some(Vec::new()); + match () { + () => x, + } +}; + +const _: Option> = { + let mut some = Some(Vec::new()); + let mut tmp = None; + + let mut i = 0; + while i < 10 { + tmp = some; + some = None; + + // We can never exit the loop with `Some` in `tmp`. + + some = tmp; + tmp = None; + + i += 1; + } + + some +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/drop-precise.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/drop-precise.rs new file mode 100644 index 000000000000..842d715627b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/drop-precise.rs @@ -0,0 +1,19 @@ +// run-pass +// gate-test-const_precise_live_drops + +#![feature(const_precise_live_drops)] + +const _: Vec = { + let vec_tuple = (Vec::new(),); + vec_tuple.0 +}; + +const _: Vec = { + let x: Result<_, Vec> = Ok(Vec::new()); + match x { + Ok(x) | Err(x) => x, + } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/exhaustive-c-like-enum-match.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/exhaustive-c-like-enum-match.rs new file mode 100644 index 000000000000..064f3b8a7f2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/exhaustive-c-like-enum-match.rs @@ -0,0 +1,30 @@ +// Test for + +// check-pass + +enum E { + A, + B, + C +} + +const fn f(e: E) { + match e { + E::A => {} + E::B => {} + E::C => {} + } +} + +const fn g(e: E) -> usize { + match e { + _ => 0 + } +} + +fn main() { + const X: usize = g(E::C); + assert_eq!(X, 0); + assert_eq!(g(E::A), 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/feature-gate-const-if-match.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/feature-gate-const-if-match.rs new file mode 100644 index 000000000000..f133b75bc6f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/feature-gate-const-if-match.rs @@ -0,0 +1,97 @@ +// check-pass + +const _: i32 = if true { 5 } else { 6 }; + +const _: i32 = if let Some(true) = Some(false) { 0 } else { 1 }; + +const _: i32 = match 1 { + 2 => 3, + 4 => 5, + _ => 0, +}; + +static FOO: i32 = { + let x = if true { 0 } else { 1 }; + let x = match x { + 0 => 1, + _ => 0, + }; + if let Some(x) = Some(x) { x } else { 1 } +}; + +static mut BAR: i32 = { + let x = if true { 0 } else { 1 }; + let x = match x { + 0 => 1, + _ => 0, + }; + if let Some(x) = Some(x) { x } else { 1 } +}; + +const fn if_() -> i32 { + if true { 5 } else { 6 } +} + +const fn if_let(a: Option) -> i32 { + if let Some(true) = a { 0 } else { 1 } +} + +const fn match_(i: i32) -> i32 { + match i { + i if i > 10 => i, + 1 => 2, + _ => 0, + } +} + +pub trait Foo { + const IF: i32 = if true { 5 } else { 6 }; + const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 }; + const MATCH: i32 = match 0 { + 1 => 2, + _ => 0, + }; +} + +impl Foo for () { + const IF: i32 = if true { 5 } else { 6 }; + const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 }; + const MATCH: i32 = match 0 { + 1 => 2, + _ => 0, + }; +} + +fn non_const_outside() { + const fn const_inside(y: bool) -> i32 { + let x = if y { 0 } else { 1 }; + let x = match x { + 0 => 1, + _ => 0, + }; + if let Some(x) = Some(x) { x } else { 1 } + } +} + +const fn const_outside() { + fn non_const_inside(y: bool) -> i32 { + let x = if y { 0 } else { 1 }; + let x = match x { + 0 => 1, + _ => 0, + }; + if let Some(x) = Some(x) { x } else { 1 } + } +} + +fn main() { + let _ = [0; { + let x = if false { 0 } else { 1 }; + let x = match x { + 0 => 1, + _ => 0, + }; + if let Some(x) = Some(x) { x } else { 1 } + }]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/interior-mutability.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/interior-mutability.rs new file mode 100644 index 000000000000..20201c9ae91d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/interior-mutability.rs @@ -0,0 +1,44 @@ +// Ensure that *any* assignment to the return place of a value with interior mutability +// disqualifies it from promotion. + +use std::cell::Cell; + +const X: Option> = { + let mut x = None; + if false { + x = Some(Cell::new(4)); + } + x +}; + +const Y: Option> = { + let mut y = Some(Cell::new(4)); + if true { + y = None; + } + y +}; + +const Z: Option> = { + let mut z = None; + let mut i = 0; + while i < 10 { + if i == 8 { + z = Some(Cell::new(4)); + } + + if i == 9 { + z = None; + } + + i += 1; + } + z +}; + +fn main() { + let x: &'static _ = &X; // { dg-error ".E0716." "" { target *-*-* } } + let y: &'static _ = &Y; // { dg-error ".E0716." "" { target *-*-* } } + let z: &'static _ = &Z; // { dg-error ".E0716." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/issue-46843.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/issue-46843.rs new file mode 100644 index 000000000000..489dcb767d41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/issue-46843.rs @@ -0,0 +1,17 @@ +enum Thing { + This, + That, +} + +fn non_const() -> Thing { + Thing::This +} + +pub const Q: i32 = match non_const() { +// { dg-error ".E0015." "" { target *-*-* } .-1 } + Thing::This => 1, + Thing::That => 0 +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/issue-50577.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/issue-50577.rs new file mode 100644 index 000000000000..4214c329c92c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/issue-50577.rs @@ -0,0 +1,7 @@ +fn main() { + enum Foo { + Drop = assert_eq!(1, 1), +// { dg-error ".E0317." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/loop.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/loop.rs new file mode 100644 index 000000000000..632981476b82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/loop.rs @@ -0,0 +1,90 @@ +const _: () = loop { break (); }; + +static FOO: i32 = loop { break 4; }; + +const fn foo() { + loop {} +} + +pub trait Foo { + const BAR: i32 = loop { break 4; }; +} + +impl Foo for () { + const BAR: i32 = loop { break 4; }; +} + +fn non_const_outside() { + const fn const_inside() { + loop {} + } +} + +const fn const_outside() { + fn non_const_inside() { + loop {} + } +} + +fn main() { + let x = [0; { + while false {} + 4 + }]; +} + +const _: i32 = { + let mut x = 0; + + while x < 4 { + x += 1; + } + + while x < 8 { + x += 1; + } + + x +}; + +const _: i32 = { + let mut x = 0; + + for i in 0..4 { // { dg-error ".E0744." "" { target *-*-* } } + x += i; + } + + for i in 0..4 { // { dg-error ".E0744." "" { target *-*-* } } + x += i; + } + + x +}; + +const _: i32 = { + let mut x = 0; + + loop { + x += 1; + if x == 4 { + break; + } + } + + loop { + x += 1; + if x == 8 { + break; + } + } + + x +}; + +const _: i32 = { + let mut x = 0; + while let None = Some(x) { } + while let None = Some(x) { } + x +}; + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/short-circuit-let.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/short-circuit-let.rs new file mode 100644 index 000000000000..9e4764965981 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/short-circuit-let.rs @@ -0,0 +1,39 @@ +// `&&` and `||` were previously forbidden in constants alongside let bindings. + +// run-pass + +#![feature(const_panic)] + +const X: i32 = { + let mut x = 0; + let _ = true && { x = 1; false }; + x +}; + +const Y: bool = { + let x = true && false || true; + x +}; + +const fn truthy() -> bool { + let x = true || return false; + x +} + +const fn falsy() -> bool { + let x = true && return false; + x +} + +fn main() { + const _: () = assert!(Y); + assert!(Y); + + const _: () = assert!(X == 1); + assert_eq!(X, 1); + + const _: () = assert!(truthy()); + const _: () = assert!(!falsy()); + assert!(truthy() && !falsy()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/short-circuit.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/short-circuit.rs new file mode 100644 index 000000000000..91bd1dcd6d23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/short-circuit.rs @@ -0,0 +1,15 @@ +// run-pass + +// Test that both `&&` and `||` actually short-circuit. +// Formerly, both sides were evaluated unconditionally + +#![feature(const_panic)] + +const TRUE: bool = true || panic!(); +const FALSE: bool = false && panic!(); + +fn main() { + assert!(TRUE); + assert!(!FALSE); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/single_variant_match_ice.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/single_variant_match_ice.rs new file mode 100644 index 000000000000..714c91808db6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/single_variant_match_ice.rs @@ -0,0 +1,26 @@ +// check-pass + +enum Foo { + Prob, +} + +const FOO: u32 = match Foo::Prob { + Foo::Prob => 42, +}; + +const BAR: u32 = match Foo::Prob { + x => 42, +}; + +impl Foo { + pub const fn as_val(&self) -> u8 { + use self::Foo::*; + + match *self { + Prob => 0x1, + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/control-flow/try.rs b/gcc/testsuite/rust/rustc/ui/consts/control-flow/try.rs new file mode 100644 index 000000000000..33a300a23c2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/control-flow/try.rs @@ -0,0 +1,11 @@ +// The `?` operator is still not const-evaluatable because it calls `From::from` on the error +// variant. + +const fn opt() -> Option { + let x = Some(2); + x?; // { dg-error ".E0744." "" { target *-*-* } } + None +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/dangling-alloc-id-ice.rs b/gcc/testsuite/rust/rustc/ui/consts/dangling-alloc-id-ice.rs new file mode 100644 index 000000000000..72102e600c38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/dangling-alloc-id-ice.rs @@ -0,0 +1,16 @@ +// https://github.com/rust-lang/rust/issues/55223 +#![allow(const_err)] + +union Foo<'a> { + y: &'a (), + long_live_the_unit: &'static (), +} + +const FOO: &() = { +// { dg-error "" "" { target *-*-* } .-1 } + let y = (); + unsafe { Foo { y: &y }.long_live_the_unit } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/dangling_raw_ptr.rs b/gcc/testsuite/rust/rustc/ui/consts/dangling_raw_ptr.rs new file mode 100644 index 000000000000..8181762b3747 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/dangling_raw_ptr.rs @@ -0,0 +1,9 @@ +const FOO: *const u32 = { // { dg-error "" "" { target *-*-* } } + let x = 42; + &x +}; + +fn main() { + let x = FOO; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/deref_in_pattern.rs b/gcc/testsuite/rust/rustc/ui/consts/deref_in_pattern.rs new file mode 100644 index 000000000000..6b3fb7018b73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/deref_in_pattern.rs @@ -0,0 +1,13 @@ +// run-pass + +// https://github.com/rust-lang/rust/issues/25574 + +const A: [u8; 4] = *b"fooo"; + +fn main() { + match *b"xxxx" { + A => {}, + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/drop_none.rs b/gcc/testsuite/rust/rustc/ui/consts/drop_none.rs new file mode 100644 index 000000000000..c61a197ef2b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/drop_none.rs @@ -0,0 +1,14 @@ +// build-pass (FIXME(62277): could be check-pass?) +#![allow(dead_code)] +struct A; +impl Drop for A { + fn drop(&mut self) {} +} + +const FOO: Option = None; + +const BAR: () = (FOO, ()).1; + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/enum-discr-type-err.rs b/gcc/testsuite/rust/rustc/ui/consts/enum-discr-type-err.rs new file mode 100644 index 000000000000..e0fe7eed11c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/enum-discr-type-err.rs @@ -0,0 +1,31 @@ +// Test that we mark enum discriminant values as having errors, even when the +// diagnostic is deduplicated. + +struct F; +struct T; + +impl F { + const V: i32 = 0; +} + +impl T { + const V: i32 = 0; +} + +macro_rules! mac { + ($( $v: ident = $s: ident,)*) => { + enum E { + $( $v = $s::V, )* +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } + } +} + +mac! { + A = F, + B = T, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/huge-values.rs b/gcc/testsuite/rust/rustc/ui/consts/huge-values.rs new file mode 100644 index 000000000000..30787b9a6fa7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/huge-values.rs @@ -0,0 +1,18 @@ +// build-pass +// ignore-32bit + +// This test is a canary test that will essentially not compile in a reasonable time frame +// (so it'll take hours) if any of the optimizations regress. With the optimizations, these compile +// in milliseconds just as if the length were set to `1`. + +#[derive(Clone, Copy)] +struct Foo; + +fn main() { + let _ = [(); 4_000_000_000]; + let _ = [0u8; 4_000_000_000]; + let _ = [Foo; 4_000_000_000]; + let _ = [(Foo, (), Foo, ((), Foo, [0; 0])); 4_000_000_000]; + let _ = [[0; 0]; 4_000_000_000]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/ice-48279.rs b/gcc/testsuite/rust/rustc/ui/consts/ice-48279.rs new file mode 100644 index 000000000000..277284765ae2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/ice-48279.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_unsafe)] + +// https://github.com/rust-lang/rust/issues/48279 + +#[derive(PartialEq, Eq)] +pub struct NonZeroU32 { + value: u32 +} + +impl NonZeroU32 { + const unsafe fn new_unchecked(value: u32) -> Self { + NonZeroU32 { value } + } +} + +//pub const FOO_ATOM: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(7) }; +pub const FOO_ATOM: NonZeroU32 = unsafe { NonZeroU32 { value: 7 } }; + +fn main() { + match None { + Some(FOO_ATOM) => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/ice-zst-static-access.rs b/gcc/testsuite/rust/rustc/ui/consts/ice-zst-static-access.rs new file mode 100644 index 000000000000..823a7e6f8fe4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/ice-zst-static-access.rs @@ -0,0 +1,33 @@ +// check-pass + +// This is a regression test for ICEs from +// https://github.com/rust-lang/rust/issues/71612 +// and +// https://github.com/rust-lang/rust/issues/71709 + +#[derive(Copy, Clone)] +pub struct Glfw; + +static mut GLFW: Option = None; +pub fn new() -> Glfw { + unsafe { + if let Some(glfw) = GLFW { + return glfw; + } else { + todo!() + } + }; +} + +extern "C" { + static _dispatch_queue_attr_concurrent: [u8; 0]; +} + +static DISPATCH_QUEUE_CONCURRENT: &'static [u8; 0] = + unsafe { &_dispatch_queue_attr_concurrent }; + +fn main() { + *DISPATCH_QUEUE_CONCURRENT; + new(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/inline_asm.rs b/gcc/testsuite/rust/rustc/ui/consts/inline_asm.rs new file mode 100644 index 000000000000..1b1679fdb5c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/inline_asm.rs @@ -0,0 +1,7 @@ +#![feature(llvm_asm)] + +const _: () = unsafe { llvm_asm!("nop") }; +// { dg-error ".E0015." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/int_ptr_for_zst_slices.rs b/gcc/testsuite/rust/rustc/ui/consts/int_ptr_for_zst_slices.rs new file mode 100644 index 000000000000..7a4b31b03f7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/int_ptr_for_zst_slices.rs @@ -0,0 +1,8 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(const_raw_ptr_deref)] + +const FOO: &str = unsafe { &*(1_usize as *const [u8; 0] as *const [u8] as *const str) }; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/invalid_promotion.rs b/gcc/testsuite/rust/rustc/ui/consts/invalid_promotion.rs new file mode 100644 index 000000000000..840f785e1027 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/invalid_promotion.rs @@ -0,0 +1,19 @@ +// build-pass (FIXME(62277): could be check-pass?) +// note this was only reproducible with lib crates +// compile-flags: --crate-type=lib + +pub struct Hz; + +impl Hz { + pub const fn num(&self) -> u32 { + 42 + } + pub const fn normalized(&self) -> Hz { + Hz + } + + pub const fn as_u32(&self) -> u32 { + self.normalized().num() // this used to promote the `self.normalized()` + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-37550.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-37550.rs new file mode 100644 index 000000000000..c53d2e075bf2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-37550.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] + +#![feature(const_fn_fn_ptr_basics)] + +const fn x() { + let t = true; + let x = || t; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-51559.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-51559.rs new file mode 100644 index 000000000000..3277a393cfd9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-51559.rs @@ -0,0 +1,8 @@ +#![feature(const_raw_ptr_to_usize_cast)] + +const BAR: *mut () = ((|| 3) as fn() -> i32) as *mut (); +pub const FOO: usize = unsafe { BAR as usize }; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-52432.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-52432.rs new file mode 100644 index 000000000000..4a68b425343e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-52432.rs @@ -0,0 +1,11 @@ +#![feature(const_raw_ptr_to_usize_cast)] + +fn main() { + [(); &(static |x| {}) as *const _ as usize]; +// { dg-error ".E0282." "" { target *-*-* } .-1 } +// { dg-error ".E0282." "" { target *-*-* } .-2 } + [(); &(static || {}) as *const _ as usize]; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-54224.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-54224.rs new file mode 100644 index 000000000000..8e1368bdacd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-54224.rs @@ -0,0 +1,13 @@ +const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); // { dg-error ".E0716." "" { target *-*-* } } + +use std::borrow::Cow; + +pub const X: [u8; 3] = *b"ABC"; +pub const Y: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[X]); + + +pub const Z: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[*b"ABC"]); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-56164.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-56164.rs new file mode 100644 index 000000000000..079253e42b61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-56164.rs @@ -0,0 +1,13 @@ +#![feature(const_fn_fn_ptr_basics)] + +const fn foo() { (||{})() } +// { dg-error ".E0015." "" { target *-*-* } .-1 } + +const fn bad(input: fn()) { + input() +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-62045.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-62045.rs new file mode 100644 index 000000000000..00cf81b48075 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-62045.rs @@ -0,0 +1,6 @@ +// check-pass + +fn main() { + assert_eq!(&mut [0; 1][..], &mut []); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-63226.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-63226.rs new file mode 100644 index 000000000000..e3d94116950c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-63226.rs @@ -0,0 +1,13 @@ +// aux-build:issue-63226.rs +// compile-flags:--extern issue_63226 +// edition:2018 +// build-pass +// A regression test for issue #63226. +// Checks if `const fn` is marked as reachable. + +use issue_63226::VTable; + +static ICE_ICE:&'static VTable=VTable::vtable(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-63952.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-63952.rs new file mode 100644 index 000000000000..99f0aa45ad96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-63952.rs @@ -0,0 +1,29 @@ +// Regression test for #63952, shouldn't hang. + +use std::usize; + +#[repr(C)] +#[derive(Copy, Clone)] +struct SliceRepr { + ptr: *const u8, + len: usize, +} + +union SliceTransmute { + repr: SliceRepr, + slice: &'static [u8], +} + +// bad slice: length too big to even exist anywhere +const SLICE_WAY_TOO_LONG: &[u8] = unsafe { // { dg-error ".E0080." "" { target *-*-* } } + SliceTransmute { + repr: SliceRepr { + ptr: &42, + len: usize::MAX, + }, + } + .slice +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-64059.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-64059.rs new file mode 100644 index 000000000000..7f0cb4fceacc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-64059.rs @@ -0,0 +1,11 @@ +// revisions: noopt opt opt_with_overflow_checks +//[noopt]compile-flags: -C opt-level=0 +//[opt]compile-flags: -O +//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O + +// run-pass + +fn main() { + let _ = -(-0.0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-64506.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-64506.rs new file mode 100644 index 000000000000..b667e2f8108d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-64506.rs @@ -0,0 +1,21 @@ +// check-pass + +#[derive(Copy, Clone)] +pub struct ChildStdin { + inner: AnonPipe, +} + +#[derive(Copy, Clone)] +enum AnonPipe {} + +const FOO: () = { + union Foo { + a: ChildStdin, + b: (), + } + let x = unsafe { Foo { b: () }.a }; + let x = &x.inner; +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-64662.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-64662.rs new file mode 100644 index 000000000000..c4f24e125cb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-64662.rs @@ -0,0 +1,11 @@ +enum Foo { + A = foo(), // { dg-error ".E0282." "" { target *-*-* } } + B = foo(), // { dg-error ".E0282." "" { target *-*-* } } +} + +const fn foo() -> isize { + 0 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-65348.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-65348.rs new file mode 100644 index 000000000000..9bd0b0b15ead --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-65348.rs @@ -0,0 +1,24 @@ +// check-pass + +struct Generic(T); + +impl Generic { + const ARRAY: [T; 0] = []; + const NEWTYPE_ARRAY: Generic<[T; 0]> = Generic([]); + const ARRAY_FIELD: Generic<(i32, [T; 0])> = Generic((0, [])); +} + +pub const fn array() -> &'static T { + &Generic::::ARRAY[0] +} + +pub const fn newtype_array() -> &'static T { + &Generic::::NEWTYPE_ARRAY.0[0] +} + +pub const fn array_field() -> &'static T { + &(Generic::::ARRAY_FIELD.0).1[0] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-66342.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-66342.rs new file mode 100644 index 000000000000..385db0c87418 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-66342.rs @@ -0,0 +1,13 @@ +// check-pass +// only-x86_64 + +// Checks that the compiler does not actually try to allocate 4 TB during compilation and OOM crash. + +fn foo() -> [u8; 4 * 1024 * 1024 * 1024 * 1024] { + unimplemented!() +} + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-66345.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-66345.rs new file mode 100644 index 000000000000..5682ceaa6516 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-66345.rs @@ -0,0 +1,25 @@ +// run-pass +// compile-flags: -Z mir-opt-level=3 + +// Checks that the compiler does not ICE when passing references to field of by-value struct +// with -Z mir-opt-level=3 + +fn do_nothing(_: &()) {} + +pub struct Foo { + bar: (), +} + +pub fn by_value_1(foo: Foo) { + do_nothing(&foo.bar); +} + +pub fn by_value_2(foo: Foo) { + do_nothing(&foo.bar); +} + +fn main() { + by_value_1(Foo { bar: () }); + by_value_2::<()>(Foo { bar: () }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-66397.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-66397.rs new file mode 100644 index 000000000000..dabbc4aca730 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-66397.rs @@ -0,0 +1,9 @@ +// check-pass +// only-x86_64 + +// Checks that the compiler does not actually try to allocate 4 TB during compilation and OOM crash. + +fn main() { + [0; 4 * 1024 * 1024 * 1024 * 1024]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-66787.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-66787.rs new file mode 100644 index 000000000000..25fac1484d3b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-66787.rs @@ -0,0 +1,40 @@ +// build-pass +// compile-flags: --crate-type lib + +// Regression test for ICE which occurred when const propagating an enum with three variants +// one of which is uninhabited. + +pub enum ApiError {} +#[allow(dead_code)] +pub struct TokioError { + b: bool, +} +pub enum Error { + Api { + source: ApiError, + }, + Ethereum, + Tokio { + source: TokioError, + }, +} +struct Api; +impl IntoError for Api +{ + type Source = ApiError; + fn into_error(self, error: Self::Source) -> Error { + Error::Api { + source: (|v| v)(error), + } + } +} + +pub trait IntoError +{ + /// The underlying error + type Source; + + /// Combine the information to produce the error + fn into_error(self, source: Self::Source) -> E; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-67529.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-67529.rs new file mode 100644 index 000000000000..517e56fe9520 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-67529.rs @@ -0,0 +1,12 @@ +// compile-flags: -Z mir-opt-level=2 +// run-pass + +struct Baz { + a: T +} + +fn main() { + let d : Baz<[i32; 4]> = Baz { a: [1,2,3,4] }; + assert_eq!([1, 2, 3, 4], d.a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-67640.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-67640.rs new file mode 100644 index 000000000000..738121b431c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-67640.rs @@ -0,0 +1,25 @@ +// compile-flags: -Z mir-opt-level=3 +// run-pass + +struct X { + x: isize +} + +fn f1(a: &mut X, b: &mut isize, c: isize) -> isize { + let r = a.x + *b + c; + a.x = 0; + *b = 10; + return r; +} + +fn f2(a: isize, f: F) -> isize where F: FnOnce(isize) { f(1); return a; } + +pub fn main() { + let mut a = X {x: 1}; + let mut b = 2; + let c = 3; + assert_eq!(f1(&mut a, &mut b, c), 6); + assert_eq!(a.x, 0); + assert_eq!(f2(a.x, |_| a.x = 50), 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-67641.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-67641.rs new file mode 100644 index 000000000000..7c1fb8e63aff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-67641.rs @@ -0,0 +1,25 @@ +// compile-flags: -Z mir-opt-level=2 +// run-pass + +use std::cell::Cell; + +#[derive(Debug)] +struct B<'a> { + a: [Cell>>; 2] +} + +impl<'a> B<'a> { + fn new() -> B<'a> { + B { a: [Cell::new(None), Cell::new(None)] } + } +} + +fn f() { + let b2 = B::new(); + b2.a[0].set(Some(&b2)); +} + +fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-67696-const-prop-ice.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-67696-const-prop-ice.rs new file mode 100644 index 000000000000..892b16393937 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-67696-const-prop-ice.rs @@ -0,0 +1,21 @@ +// check-pass +// compile-flags: --emit=mir,link +// Checks that we don't ICE due to attempting to run const prop +// on a function with unsatisifable 'where' clauses + +#![allow(unused)] + +trait A { + fn foo(&self) -> Self where Self: Copy; +} + +impl A for [fn(&())] { + fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) } +} + +impl A for i32 { + fn foo(&self) -> Self { 3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-67862.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-67862.rs new file mode 100644 index 000000000000..997e47ff2e54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-67862.rs @@ -0,0 +1,19 @@ +// compile-flags: -Z mir-opt-level=2 +// run-pass + +fn e220() -> (i64, i64) { + #[inline(never)] + fn get_displacement() -> [i64; 2] { + [139776, 963904] + } + + let res = get_displacement(); + match (&res[0], &res[1]) { + (arg0, arg1) => (*arg0, *arg1), + } +} + +fn main() { + assert_eq!(e220(), (139776, 963904)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-68264-overflow.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-68264-overflow.rs new file mode 100644 index 000000000000..dd87763ed298 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-68264-overflow.rs @@ -0,0 +1,44 @@ +// check-pass +// compile-flags: --emit=mir,link +// Regression test for issue #68264 +// Checks that we don't encounter overflow +// when running const-prop on functions with +// complicated bounds +pub trait Query {} + +pub trait AsQuery { + type Query: Query; +} +pub trait Table: AsQuery + Sized {} + +pub trait LimitDsl { + type Output; +} + +pub(crate) trait LoadQuery: RunQueryDsl {} + +impl AsQuery for T { + type Query = Self; +} + +impl LimitDsl for T +where + T: Table, + T::Query: LimitDsl, +{ + type Output = ::Output; +} + +pub(crate) trait RunQueryDsl: Sized { + fn first(self, _conn: &Conn) -> U + where + Self: LimitDsl, + Self::Output: LoadQuery, + { + // Overflow is caused by this function body + unimplemented!() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-68542-closure-in-array-len.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-68542-closure-in-array-len.rs new file mode 100644 index 000000000000..cf006abc4857 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-68542-closure-in-array-len.rs @@ -0,0 +1,11 @@ +// Regression test for issue #68542 +// Tests that we don't ICE when a closure appears +// in the length part of an array. + +struct Bug { + a: [(); (|| { 0 })()] // { dg-error ".E0080." "" { target *-*-* } } +// { dg-error ".E0080." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-68684.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-68684.rs new file mode 100644 index 000000000000..0fc773067bc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-68684.rs @@ -0,0 +1,16 @@ +// check-pass + +enum _Enum { + A(), +} + +type _E = _Enum; + +const fn _a() -> _Enum { + _E::A() +} + +const _A: _Enum = _a(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs new file mode 100644 index 000000000000..416ae35c6aaa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs @@ -0,0 +1,92 @@ +// build-pass +// +// (this is deliberately *not* check-pass; I have confirmed that the bug in +// question does not replicate when one uses `cargo check` alone.) + +pub enum Void {} + +enum UninhabitedUnivariant { + _Variant(Void), +} + +enum UninhabitedMultivariant2 { + _Variant(Void), + _Warriont(Void), +} + +enum UninhabitedMultivariant3 { + _Variant(Void), + _Warriont(Void), + _Worrynot(Void), +} + +#[repr(C)] +enum UninhabitedUnivariantC { + _Variant(Void), +} + +#[repr(i32)] +enum UninhabitedUnivariant32 { + _Variant(Void), +} + +fn main() { + let _seed: UninhabitedUnivariant = None.unwrap(); + match _seed { + UninhabitedUnivariant::_Variant(_x) => {} + } + + let _seed: UninhabitedMultivariant2 = None.unwrap(); + match _seed { + UninhabitedMultivariant2::_Variant(_x) => {} + UninhabitedMultivariant2::_Warriont(_x) => {} + } + + let _seed: UninhabitedMultivariant2 = None.unwrap(); + match _seed { + UninhabitedMultivariant2::_Variant(_x) => {} + _ => {} + } + + let _seed: UninhabitedMultivariant2 = None.unwrap(); + match _seed { + UninhabitedMultivariant2::_Warriont(_x) => {} + _ => {} + } + + let _seed: UninhabitedMultivariant3 = None.unwrap(); + match _seed { + UninhabitedMultivariant3::_Variant(_x) => {} + UninhabitedMultivariant3::_Warriont(_x) => {} + UninhabitedMultivariant3::_Worrynot(_x) => {} + } + + let _seed: UninhabitedMultivariant3 = None.unwrap(); + match _seed { + UninhabitedMultivariant3::_Variant(_x) => {} + _ => {} + } + + let _seed: UninhabitedMultivariant3 = None.unwrap(); + match _seed { + UninhabitedMultivariant3::_Warriont(_x) => {} + _ => {} + } + + let _seed: UninhabitedMultivariant3 = None.unwrap(); + match _seed { + UninhabitedMultivariant3::_Worrynot(_x) => {} + _ => {} + } + + let _seed: UninhabitedUnivariantC = None.unwrap(); + match _seed { + UninhabitedUnivariantC::_Variant(_x) => {} + } + + let _seed: UninhabitedUnivariant32 = None.unwrap(); + match _seed { + UninhabitedUnivariant32::_Variant(_x) => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-69310-array-size-lit-wrong-ty.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-69310-array-size-lit-wrong-ty.rs new file mode 100644 index 000000000000..83f8e4be4e4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-69310-array-size-lit-wrong-ty.rs @@ -0,0 +1,12 @@ +// This is a regression test for #69310, which was injected by #68118. +// The issue here was that as a performance optimization, +// we call the query `lit_to_const(input);`. +// However, the literal `input.lit` would not be of the type expected by `input.ty`. +// As a result, we immediately called `bug!(...)` instead of bubbling up the problem +// so that it could be handled by the caller of `lit_to_const` (`from_anon_const`). + +fn main() {} + +const A: [(); 0.1] = [()]; // { dg-error ".E0308." "" { target *-*-* } } +const B: [(); b"a"] = [()]; // { dg-error ".E0308." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-69312.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-69312.rs new file mode 100644 index 000000000000..cec63a686ee7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-69312.rs @@ -0,0 +1,11 @@ +// build-pass + +// Verify that the compiler doesn't ICE during const prop while evaluating the index operation. + +#![allow(unconditional_panic)] + +fn main() { + let cols = [0u32; 0]; + cols[0]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-70773-mir-typeck-lt-norm.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-70773-mir-typeck-lt-norm.rs new file mode 100644 index 000000000000..d18944711404 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-70773-mir-typeck-lt-norm.rs @@ -0,0 +1,17 @@ +// run-pass + +const HASH_LEN: usize = 20; +struct Hash([u8; HASH_LEN]); +fn init_hash(_: &mut [u8; HASH_LEN]) {} + +fn foo<'a>() -> &'a () { + Hash([0; HASH_LEN]); + init_hash(&mut [0; HASH_LEN]); + let (_array,) = ([0; HASH_LEN],); + &() +} + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-70942-trait-vs-impl-mismatch.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-70942-trait-vs-impl-mismatch.rs new file mode 100644 index 000000000000..0a185cbf10c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-70942-trait-vs-impl-mismatch.rs @@ -0,0 +1,15 @@ +trait Nat { + const VALUE: usize; +} + +struct Zero; + +impl Nat for Zero { + const VALUE: i32 = 0; +// { dg-error ".E0326." "" { target *-*-* } .-1 } +} + +fn main() { + let _: [i32; Zero::VALUE] = []; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-73976-monomorphic.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-73976-monomorphic.rs new file mode 100644 index 000000000000..a4f451eed366 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-73976-monomorphic.rs @@ -0,0 +1,37 @@ +// check-pass +// +// This test is complement to the test in issue-73976-polymorphic.rs. +// In that test we ensure that polymorphic use of type_id and type_name in patterns +// will be properly rejected. This test will ensure that monomorphic use of these +// would not be wrongly rejected in patterns. + +#![feature(const_type_id)] +#![feature(const_type_name)] + +use std::any::{self, TypeId}; + +pub struct GetTypeId(T); + +impl GetTypeId { + pub const VALUE: TypeId = TypeId::of::(); +} + +const fn check_type_id() -> bool { + matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) +} + +pub struct GetTypeNameLen(T); + +impl GetTypeNameLen { + pub const VALUE: usize = any::type_name::().len(); +} + +const fn check_type_name_len() -> bool { + matches!(GetTypeNameLen::::VALUE, GetTypeNameLen::::VALUE) +} + +fn main() { + assert!(check_type_id::()); + assert!(check_type_name_len::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-73976-polymorphic.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-73976-polymorphic.rs new file mode 100644 index 000000000000..5ac6921ec750 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-73976-polymorphic.rs @@ -0,0 +1,41 @@ +// This test is from #73976. We previously did not check if a type is monomorphized +// before calculating its type id, which leads to the bizarre behaviour below that +// TypeId of a generic type does not match itself. +// +// This test case should either run-pass or be rejected at compile time. +// Currently we just disallow this usage and require pattern is monomorphic. + +#![feature(const_type_id)] +#![feature(const_type_name)] + +use std::any::{self, TypeId}; + +pub struct GetTypeId(T); + +impl GetTypeId { + pub const VALUE: TypeId = TypeId::of::(); +} + +const fn check_type_id() -> bool { + matches!(GetTypeId::::VALUE, GetTypeId::::VALUE) +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +pub struct GetTypeNameLen(T); + +impl GetTypeNameLen { + pub const VALUE: usize = any::type_name::().len(); +} + +const fn check_type_name_len() -> bool { + matches!(GetTypeNameLen::::VALUE, GetTypeNameLen::::VALUE) +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() { + assert!(check_type_id::()); + assert!(check_type_name_len::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-77062-large-zst-array.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-77062-large-zst-array.rs new file mode 100644 index 000000000000..4b3019824e2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-77062-large-zst-array.rs @@ -0,0 +1,6 @@ +// build-pass + +fn main() { + let _ = &[(); usize::MAX]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-78655.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-78655.rs new file mode 100644 index 000000000000..b207f28a109a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-78655.rs @@ -0,0 +1,11 @@ +const FOO: *const u32 = { // { dg-error "" "" { target *-*-* } } + let x; + &x // { dg-error ".E0381." "" { target *-*-* } } +}; + +fn main() { + let FOO = FOO; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/issue-broken-mir.rs b/gcc/testsuite/rust/rustc/ui/consts/issue-broken-mir.rs new file mode 100644 index 000000000000..7f01bcfc7e96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/issue-broken-mir.rs @@ -0,0 +1,11 @@ +// run-pass + +// https://github.com/rust-lang/rust/issues/27918 + +fn main() { + match b" " { + b"1234" => {}, + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/locals-in-const-fn.rs b/gcc/testsuite/rust/rustc/ui/consts/locals-in-const-fn.rs new file mode 100644 index 000000000000..4d65f0fc594e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/locals-in-const-fn.rs @@ -0,0 +1,36 @@ +// run-pass + +// https://github.com/rust-lang/rust/issues/48821 + +const fn foo(i: usize) -> usize { + let x = i; + x +} + +static FOO: usize = foo(42); + +const fn bar(mut i: usize) -> usize { + i += 8; + let x = &i; + *x +} + +static BAR: usize = bar(42); + +const fn boo(mut i: usize) -> usize { + { + let mut x = i; + x += 10; + i = x; + } + i +} + +static BOO: usize = boo(42); + +fn main() { + assert!(FOO == 42); + assert!(BAR == 50); + assert!(BOO == 52); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/match-const-fn-structs.rs b/gcc/testsuite/rust/rustc/ui/consts/match-const-fn-structs.rs new file mode 100644 index 000000000000..16280eb7f5c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/match-const-fn-structs.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(unused_variables)] + +// https://github.com/rust-lang/rust/issues/46114 + +#[derive(Eq, PartialEq)] +struct A { value: u32 } + +const fn new(value: u32) -> A { + A { value } +} + +const A_1: A = new(1); +const A_2: A = new(2); + +fn main() { + let a_str = match new(42) { + A_1 => "A 1", + A_2 => "A 2", + _ => "Unknown A", + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/match_ice.rs b/gcc/testsuite/rust/rustc/ui/consts/match_ice.rs new file mode 100644 index 000000000000..e68e037f1045 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/match_ice.rs @@ -0,0 +1,19 @@ +// https://github.com/rust-lang/rust/issues/53708 + +struct S; + +#[derive(PartialEq, Eq)] +struct T; + +fn main() { + const C: &S = &S; + match C { + C => {} +// { dg-error "" "" { target *-*-* } .-1 } + } + const K: &T = &T; + match K { + K => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/address_of.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/address_of.rs new file mode 100644 index 000000000000..e7309826dc53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/address_of.rs @@ -0,0 +1,18 @@ +#![feature(raw_ref_op)] + +const fn mutable_address_of_in_const() { + let mut a = 0; + let b = &raw mut a; // { dg-error ".E0658." "" { target *-*-* } } +} + +struct X; + +impl X { + const fn inherent_mutable_address_of_in_const() { + let mut a = 0; + let b = &raw mut a; // { dg-error ".E0658." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/address_of_const.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/address_of_const.rs new file mode 100644 index 000000000000..912f47134f58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/address_of_const.rs @@ -0,0 +1,20 @@ +// check-pass + +#![feature(raw_ref_op)] + +const fn const_address_of_in_const() { + let mut a = 0; + let b = &raw const a; +} + +struct X; + +impl X { + const fn inherent_const_address_of_in_const() { + let mut a = 0; + let b = &raw const a; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/allow_const_fn_ptr.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/allow_const_fn_ptr.rs new file mode 100644 index 000000000000..6a7913febbb2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/allow_const_fn_ptr.rs @@ -0,0 +1,15 @@ +#![feature(rustc_attrs, staged_api, rustc_allow_const_fn_unstable)] +#![feature(const_fn_fn_ptr_basics)] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(since="1.0.0", feature = "mep")] +const fn error(_: fn()) {} +// { dg-error "" "" { target *-*-* } .-1 } + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(since="1.0.0", feature = "mep")] +#[rustc_allow_const_fn_unstable(const_fn_fn_ptr_basics)] +const fn compiles(_: fn()) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs new file mode 100644 index 000000000000..dd06da623002 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs @@ -0,0 +1,22 @@ +// run-pass +#![feature(rustc_allow_const_fn_unstable)] +#![feature(const_fn_fn_ptr_basics)] + +#![feature(rustc_attrs, staged_api)] +#![stable(feature = "rust1", since = "1.0.0")] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(since="1.0.0", feature = "mep")] +#[rustc_allow_const_fn_unstable(const_fn_fn_ptr_basics)] +const fn takes_fn_ptr(_: fn()) {} + +const FN: fn() = || (); + +const fn gives_fn_ptr() { + takes_fn_ptr(FN) +} + +fn main() { + gives_fn_ptr(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/allow_raw_ptr_dereference_const_fn.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/allow_raw_ptr_dereference_const_fn.rs new file mode 100644 index 000000000000..b0290918740b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/allow_raw_ptr_dereference_const_fn.rs @@ -0,0 +1,12 @@ +// check-pass +#![feature(const_raw_ptr_deref)] +#![feature(raw_ref_macros)] + +use std::ptr; + +const fn test_fn(x: *const i32) { + let x2 = unsafe { ptr::raw_const!(*x) }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/bad_const_fn_body_ice.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/bad_const_fn_body_ice.rs new file mode 100644 index 000000000000..e7b22519bf20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/bad_const_fn_body_ice.rs @@ -0,0 +1,8 @@ +const fn foo(a: i32) -> Vec { + vec![1, 2, 3] +// { dg-error ".E0015." "" { target *-*-* } .-1 } +// { dg-error ".E0015." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/cast_errors.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/cast_errors.rs new file mode 100644 index 000000000000..db03facafa5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/cast_errors.rs @@ -0,0 +1,18 @@ +fn main() {} + +const fn unsize(x: &[u8; 3]) -> &[u8] { x } +const fn closure() -> fn() { || {} } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +const fn closure2() { + (|| {}) as fn(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} +const fn reify(f: fn()) -> unsafe fn() { f } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +const fn reify2() { main as unsafe fn(); } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/cmp_fn_pointers.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/cmp_fn_pointers.rs new file mode 100644 index 000000000000..7611fbe467e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/cmp_fn_pointers.rs @@ -0,0 +1,9 @@ +const fn cmp(x: fn(), y: fn()) -> bool { +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + unsafe { x == y } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn.rs new file mode 100644 index 000000000000..c49e7b300a10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn.rs @@ -0,0 +1,149 @@ +// ok +const fn foo1() {} +const fn foo2(x: i32) -> i32 { x } +const fn foo3(x: T) -> T { x } +const fn foo7() { + ( + foo1(), + foo2(420), + foo3(69), + ).0 +} +const fn foo12(t: T) -> T { t } +const fn foo13(t: &T) -> &T { t } +const fn foo14<'a, T: 'a>(t: &'a T) -> &'a T { t } +const fn foo15(t: T) -> T where T: Sized { t } +const fn foo15_2(t: &T) -> &T where T: ?Sized { t } +const fn foo16(f: f32) -> f32 { f } +const fn foo17(f: f32) -> u32 { f as u32 } +const fn foo18(i: i32) -> i32 { i * 3 } +const fn foo20(b: bool) -> bool { !b } +const fn foo21(t: T, u: U) -> (T, U) { (t, u) } +const fn foo22(s: &[u8], i: usize) -> u8 { s[i] } +const FOO: u32 = 42; +const fn foo23() -> u32 { FOO } +const fn foo24() -> &'static u32 { &FOO } +const fn foo27(x: &u32) -> u32 { *x } +const fn foo28(x: u32) -> u32 { *&x } +const fn foo29(x: u32) -> i32 { x as i32 } +const fn foo31(a: bool, b: bool) -> bool { a & b } +const fn foo32(a: bool, b: bool) -> bool { a | b } +const fn foo33(a: bool, b: bool) -> bool { a & b } +const fn foo34(a: bool, b: bool) -> bool { a | b } +const fn foo35(a: bool, b: bool) -> bool { a ^ b } +struct Foo(T); +impl Foo { + const fn new(t: T) -> Self { Foo(t) } + const fn into_inner(self) -> T { self.0 } // { dg-error ".E0493." "" { target *-*-* } } + const fn get(&self) -> &T { &self.0 } + const fn get_mut(&mut self) -> &mut T { &mut self.0 } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +} +impl<'a, T> Foo { + const fn new_lt(t: T) -> Self { Foo(t) } + const fn into_inner_lt(self) -> T { self.0 } // { dg-error ".E0493." "" { target *-*-* } } + const fn get_lt(&'a self) -> &T { &self.0 } + const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +} +impl Foo { + const fn new_s(t: T) -> Self { Foo(t) } + const fn into_inner_s(self) -> T { self.0 } // { dg-error ".E0493." "" { target *-*-* } } + const fn get_s(&self) -> &T { &self.0 } + const fn get_mut_s(&mut self) -> &mut T { &mut self.0 } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +} +impl Foo { + const fn get_sq(&self) -> &T { &self.0 } + const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +} + + +const fn char_ops(c: char, d: char) -> bool { c == d } +const fn char_ops2(c: char, d: char) -> bool { c < d } +const fn char_ops3(c: char, d: char) -> bool { c != d } +const fn i32_ops(c: i32, d: i32) -> bool { c == d } +const fn i32_ops2(c: i32, d: i32) -> bool { c < d } +const fn i32_ops3(c: i32, d: i32) -> bool { c != d } +const fn i32_ops4(c: i32, d: i32) -> i32 { c + d } +const fn char_cast(u: u8) -> char { u as char } +const unsafe fn ret_i32_no_unsafe() -> i32 { 42 } +const unsafe fn ret_null_ptr_no_unsafe() -> *const T { core::ptr::null() } +const unsafe fn ret_null_mut_ptr_no_unsafe() -> *mut T { core::ptr::null_mut() } + +// not ok +const fn foo11(t: T) -> T { t } +// { dg-error ".E0723." "" { target *-*-* } .-1 } +const fn foo11_2(t: T) -> T { t } +// { dg-error ".E0723." "" { target *-*-* } .-1 } + +static BAR: u32 = 42; +const fn foo25() -> u32 { BAR } // { dg-error ".E0013." "" { target *-*-* } } +const fn foo26() -> &'static u32 { &BAR } // { dg-error ".E0013." "" { target *-*-* } } +const fn foo30(x: *const u32) -> usize { x as usize } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +const fn foo30_2(x: *mut u32) -> usize { x as usize } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +const fn foo30_6() -> bool { let x = true; x } +const fn inc(x: &mut i32) { *x += 1 } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +// ok +const fn foo36(a: bool, b: bool) -> bool { a && b } +const fn foo37(a: bool, b: bool) -> bool { a || b } + +fn main() {} + +impl Foo { +// { dg-error ".E0723." "" { target *-*-* } .-1 } + const fn foo(&self) {} +} + +impl Foo { +// { dg-error ".E0723." "" { target *-*-* } .-1 } + const fn foo2(&self) {} +} + +impl Foo { +// { dg-error ".E0723." "" { target *-*-* } .-1 } + const fn foo3(&self) {} +} + +struct AlanTuring(T); +const fn no_apit2(_x: AlanTuring) {} +// { dg-error ".E0493." "" { target *-*-* } .-1 } +// { dg-error ".E0493." "" { target *-*-* } .-2 } +const fn no_apit(_x: impl std::fmt::Debug) {} +// { dg-error ".E0493." "" { target *-*-* } .-1 } +// { dg-error ".E0493." "" { target *-*-* } .-2 } +const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} +// { dg-error ".E0723." "" { target *-*-* } .-1 } +const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } +// { dg-error ".E0723." "" { target *-*-* } .-1 } +// { dg-error ".E0723." "" { target *-*-* } .-2 } +// { dg-error ".E0723." "" { target *-*-* } .-3 } + +const fn no_unsafe() { unsafe {} } + +const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } +// { dg-error ".E0723." "" { target *-*-* } .-1 } + +const fn no_fn_ptrs(_x: fn()) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_dyn.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_dyn.rs new file mode 100644 index 000000000000..6e22356a2ce0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_dyn.rs @@ -0,0 +1,16 @@ +struct HasDyn { + field: &'static dyn std::fmt::Debug, +} + +struct Hide(HasDyn); + +const fn no_inner_dyn_trait(_x: Hide) {} +const fn no_inner_dyn_trait2(x: Hide) { + x.0.field; +// { dg-error ".E0723." "" { target *-*-* } .-1 } +} +const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) } +// { dg-error ".E0723." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_fn_ptr.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_fn_ptr.rs new file mode 100644 index 000000000000..d4ec97384e16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_fn_ptr.rs @@ -0,0 +1,20 @@ +// gate-test-const_fn_fn_ptr_basics + +struct HasPtr { + field: fn(), +} + +struct Hide(HasPtr); + +fn field() {} + +const fn no_inner_dyn_trait(_x: Hide) {} +const fn no_inner_dyn_trait2(x: Hide) { + x.0.field; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} +const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasPtr { field }) } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_impl_trait.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_impl_trait.rs new file mode 100644 index 000000000000..d368a79c078a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_impl_trait.rs @@ -0,0 +1,11 @@ +// gate-test-const_impl_trait + +struct AlanTuring(T); +const fn no_rpit2() -> AlanTuring { // { dg-error ".E0658." "" { target *-*-* } } + AlanTuring(0) +} + +const fn no_rpit() -> impl std::fmt::Debug {} // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_libstd.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_libstd.rs new file mode 100644 index 000000000000..73857fd67164 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_libstd.rs @@ -0,0 +1,27 @@ +// build-pass (FIXME(62277): could be check-pass?) + +use std::cell::UnsafeCell; +use std::sync::atomic::AtomicU32; +pub struct Condvar { + condvar: UnsafeCell, +} + +unsafe impl Send for Condvar {} +unsafe impl Sync for Condvar {} + +#[repr(C)] +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +struct NoWait(u32); + +const CONDVAR_HAS_NO_WAITERS: NoWait = NoWait(42); + +impl Condvar { + pub const fn new() -> Condvar { + Condvar { + condvar: UnsafeCell::new(AtomicU32::new(CONDVAR_HAS_NO_WAITERS.0)), + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs new file mode 100644 index 000000000000..bd5ff35f5e10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs @@ -0,0 +1,42 @@ +#![unstable(feature = "humans", + reason = "who ever let humans program computers, + we're apparently really bad at it", + issue = "none")] + +#![feature(const_fn, const_fn_floating_point_arithmetic, foo, foo2)] +#![feature(staged_api)] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature="foo", issue = "none")] +const fn foo() -> u32 { 42 } + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +// can't call non-min_const_fn +const fn bar() -> u32 { foo() } // { dg-error "" "" { target *-*-* } } + +#[unstable(feature = "rust1", issue = "none")] +const fn foo2() -> u32 { 42 } + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +// can't call non-min_const_fn +const fn bar2() -> u32 { foo2() } // { dg-error "" "" { target *-*-* } } + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +// Const-stable functions cannot rely on unstable const-eval features. +const fn bar3() -> u32 { (5f32 + 6f32) as u32 } +// { dg-error "" "" { target *-*-* } .-1 } + +// check whether this function cannot be called even with the feature gate active +#[unstable(feature = "foo2", issue = "none")] +const fn foo2_gated() -> u32 { 42 } + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +// can't call non-min_const_fn +const fn bar2_gated() -> u32 { foo2_gated() } // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs new file mode 100644 index 000000000000..817761fd5c56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs @@ -0,0 +1,17 @@ +const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static usize { &*x } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() {} + +const unsafe fn no_union() { + union Foo { x: (), y: () } + Foo { x: () }.y +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_unsafe_ok.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_unsafe_ok.rs new file mode 100644 index 000000000000..d47cbb55814b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_fn_unsafe_ok.rs @@ -0,0 +1,45 @@ +// check-pass + +const unsafe fn ret_i32_no_unsafe() -> i32 { 42 } +const unsafe fn ret_null_ptr_no_unsafe() -> *const T { std::ptr::null() } +const unsafe fn ret_null_mut_ptr_no_unsafe() -> *mut T { std::ptr::null_mut() } +const fn no_unsafe() { unsafe {} } + +const fn call_unsafe_const_fn() -> i32 { + unsafe { ret_i32_no_unsafe() } +} +const fn call_unsafe_generic_const_fn() -> *const String { + unsafe { ret_null_ptr_no_unsafe::() } +} +const fn call_unsafe_generic_cell_const_fn() + -> *const Vec> +{ + unsafe { ret_null_mut_ptr_no_unsafe::>>() } +} + +const unsafe fn call_unsafe_const_unsafe_fn() -> i32 { + unsafe { ret_i32_no_unsafe() } +} +const unsafe fn call_unsafe_generic_const_unsafe_fn() -> *const String { + unsafe { ret_null_ptr_no_unsafe::() } +} +const unsafe fn call_unsafe_generic_cell_const_unsafe_fn() + -> *const Vec> +{ + unsafe { ret_null_mut_ptr_no_unsafe::>>() } +} + +const unsafe fn call_unsafe_const_unsafe_fn_immediate() -> i32 { + ret_i32_no_unsafe() +} +const unsafe fn call_unsafe_generic_const_unsafe_fn_immediate() -> *const String { + ret_null_ptr_no_unsafe::() +} +const unsafe fn call_unsafe_generic_cell_const_unsafe_fn_immediate() + -> *const Vec> +{ + ret_null_mut_ptr_no_unsafe::>>() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs new file mode 100644 index 000000000000..686637bcc2cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs @@ -0,0 +1,43 @@ +#![unstable(feature = "humans", + reason = "who ever let humans program computers, + we're apparently really bad at it", + issue = "none")] + +#![feature(const_fn, const_fn_floating_point_arithmetic, foo, foo2)] +#![feature(staged_api)] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature="foo", issue = "none")] +const unsafe fn foo() -> u32 { 42 } + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +// can't call non-min_const_fn +const unsafe fn bar() -> u32 { unsafe { foo() } } // { dg-error "" "" { target *-*-* } } + +#[unstable(feature = "rust1", issue = "none")] +const unsafe fn foo2() -> u32 { 42 } + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +// can't call non-min_const_fn +const unsafe fn bar2() -> u32 { unsafe { foo2() } } // { dg-error "" "" { target *-*-* } } + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +// conformity is required, even with `const_fn` feature gate +const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } +// { dg-error "" "" { target *-*-* } .-1 } + +// check whether this function cannot be called even with the feature gate active +#[unstable(feature = "foo2", issue = "none")] +const unsafe fn foo2_gated() -> u32 { 42 } + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +// can't call non-min_const_fn +const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } } +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs new file mode 100644 index 000000000000..2e129427f940 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.rs @@ -0,0 +1,36 @@ +#![unstable(feature = "humans", + reason = "who ever let humans program computers, + we're apparently really bad at it", + issue = "none")] + +#![feature(const_fn, foo, foo2)] +#![feature(staged_api)] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature="foo", issue = "none")] +const fn foo() -> u32 { 42 } + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +// can't call non-min_const_fn +const unsafe fn bar() -> u32 { foo() } // { dg-error "" "" { target *-*-* } } + +#[unstable(feature = "rust1", issue = "none")] +const fn foo2() -> u32 { 42 } + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +// can't call non-min_const_fn +const unsafe fn bar2() -> u32 { foo2() } // { dg-error "" "" { target *-*-* } } + +// check whether this function cannot be called even with the feature gate active +#[unstable(feature = "foo2", issue = "none")] +const fn foo2_gated() -> u32 { 42 } + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +// can't call non-min_const_fn +const unsafe fn bar2_gated() -> u32 { foo2_gated() } // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/mutable_borrow.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/mutable_borrow.rs new file mode 100644 index 000000000000..90ddd378b04d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/mutable_borrow.rs @@ -0,0 +1,18 @@ +const fn mutable_ref_in_const() -> u8 { + let mut a = 0; + let b = &mut a; // { dg-error ".E0658." "" { target *-*-* } } + *b +} + +struct X; + +impl X { + const fn inherent_mutable_ref_in_const() -> u8 { + let mut a = 0; + let b = &mut a; // { dg-error ".E0658." "" { target *-*-* } } + *b + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/promotion.rs b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/promotion.rs new file mode 100644 index 000000000000..34c79d837af2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/min_const_fn/promotion.rs @@ -0,0 +1,18 @@ +use std::cell::Cell; + +const fn foo1() {} +const fn foo2(x: i32) -> i32 { x } +const fn foo3() -> i32 { 42 } +const fn foo4() -> Cell { Cell::new(42) } +const fn foo5() -> Option> { Some(Cell::new(42)) } +const fn foo6() -> Option> { None } + +fn main() { + let x: &'static () = &foo1(); // { dg-error ".E0716." "" { target *-*-* } } + let y: &'static i32 = &foo2(42); // { dg-error ".E0716." "" { target *-*-* } } + let z: &'static i32 = &foo3(); // { dg-error ".E0716." "" { target *-*-* } } + let a: &'static Cell = &foo4(); // { dg-error ".E0716." "" { target *-*-* } } + let a: &'static Option> = &foo5(); // { dg-error ".E0716." "" { target *-*-* } } + let a: &'static Option> = &foo6(); // { dg-error ".E0716." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/abi-mismatch.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/abi-mismatch.rs new file mode 100644 index 000000000000..fb8b2955dcdf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/abi-mismatch.rs @@ -0,0 +1,20 @@ +// Checks that we report ABI mismatches for "const extern fn" +// compile-flags: -Z unleash-the-miri-inside-of-you + +#![feature(const_extern_fn)] +#![allow(const_err)] + +const extern "C" fn c_fn() {} + +const fn call_rust_fn(my_fn: extern "Rust" fn()) { + my_fn(); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-note ".E0080." "" { target *-*-* } .-2 } +// { dg-note ".E0080." "" { target *-*-* } .-3 } +} + +static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) }); +// { dg-note "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/assoc_const.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/assoc_const.rs new file mode 100644 index 000000000000..a73e491b0bcd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/assoc_const.rs @@ -0,0 +1,33 @@ +// build-fail +// compile-flags: -Zunleash-the-miri-inside-of-you + +#![allow(const_err)] + +// a test demonstrating why we do need to run static const qualification on associated constants +// instead of just checking the final constant + +trait Foo { + const X: T; +} + +trait Bar> { + const F: u32 = (U::X, 42).1; +} + +impl Foo for () { + const X: u32 = 42; +} +impl Foo> for String { + const X: Vec = Vec::new(); +} + +impl Bar for () {} +impl Bar, String> for String {} + +fn main() { + // this is fine, but would have been forbidden by the static checks on `F` + let x = <() as Bar>::F; + // this test only causes errors due to the line below, so post-monomorphization + let y = , String>>::F; // { dg-error ".E0080." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/assoc_const_2.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/assoc_const_2.rs new file mode 100644 index 000000000000..28c3225a1e04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/assoc_const_2.rs @@ -0,0 +1,31 @@ +// build-fail + +#![allow(const_err)] + +// a test demonstrating that const qualification cannot prevent monomorphization time errors + +trait Foo { + const X: u32; +} + +trait Bar { + const F: u32 = 100 / U::X; +} + +impl Foo for () { + const X: u32 = 42; +} + +impl Foo for String { + const X: u32 = 0; +} + +impl Bar<()> for () {} +impl Bar for String {} + +fn main() { + let x = <() as Bar<()>>::F; + // this test only causes errors due to the line below, so post-monomorphization + let y = >::F; // { dg-error ".E0080." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/auxiliary/static_cross_crate.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/auxiliary/static_cross_crate.rs new file mode 100644 index 000000000000..5fa5b9971f52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/auxiliary/static_cross_crate.rs @@ -0,0 +1,4 @@ +pub static mut ZERO: [u8; 1] = [0]; +pub static ZERO_REF: &[u8; 1] = unsafe { &ZERO }; +pub static mut OPT_ZERO: Option = Some(0); + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/box.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/box.rs new file mode 100644 index 000000000000..c3259180b10d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/box.rs @@ -0,0 +1,14 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +#![feature(box_syntax)] +#![allow(const_err)] + +use std::mem::ManuallyDrop; + +fn main() {} + +static TEST_BAD: &mut i32 = { + &mut *(box 0) +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-note ".E0080." "" { target *-*-* } .-2 } +}; + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/const_refers_to_static.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/const_refers_to_static.rs new file mode 100644 index 000000000000..397f1891e503 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/const_refers_to_static.rs @@ -0,0 +1,32 @@ +// build-fail +// compile-flags: -Zunleash-the-miri-inside-of-you +#![allow(const_err)] + +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; + +// These fail during CTFE (as they read a static), so they only cause an error +// when *using* the const. + +const MUTATE_INTERIOR_MUT: usize = { + static FOO: AtomicUsize = AtomicUsize::new(0); + FOO.fetch_add(1, Ordering::Relaxed) +}; + +const READ_INTERIOR_MUT: usize = { + static FOO: AtomicUsize = AtomicUsize::new(0); + unsafe { *(&FOO as *const _ as *const usize) } +}; + +static mut MUTABLE: u32 = 0; +const READ_MUT: u32 = unsafe { MUTABLE }; + +fn main() { + MUTATE_INTERIOR_MUT; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + READ_INTERIOR_MUT; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + READ_MUT; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/const_refers_to_static2.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/const_refers_to_static2.rs new file mode 100644 index 000000000000..958a4ccad79d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/const_refers_to_static2.rs @@ -0,0 +1,26 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +#![allow(const_err)] + +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; + +// These only fail during validation (they do not use but just create a reference to a static), +// so they cause an immediate error when *defining* the const. + +const REF_INTERIOR_MUT: &usize = { // { dg-error ".E0080." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + static FOO: AtomicUsize = AtomicUsize::new(0); + unsafe { &*(&FOO as *const _ as *const usize) } +}; + +// ok some day perhaps +const READ_IMMUT: &usize = { // { dg-error ".E0080." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + static FOO: usize = 0; + &FOO +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs new file mode 100644 index 000000000000..5b12d5d2a9fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs @@ -0,0 +1,82 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +// aux-build:static_cross_crate.rs +#![allow(const_err)] + +#![feature(exclusive_range_pattern, half_open_range_patterns)] + +extern crate static_cross_crate; + +// Sneaky: reference to a mutable static. +// Allowing this would be a disaster for pattern matching, we could violate exhaustiveness checking! +const SLICE_MUT: &[u8; 1] = { // { dg-error ".E0080." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + unsafe { &static_cross_crate::ZERO } +}; + +const U8_MUT: &u8 = { // { dg-error ".E0080." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + unsafe { &static_cross_crate::ZERO[0] } +}; + +// Also test indirection that reads from other static. This causes a const_err. +#[warn(const_err)] // { dg-note "" "" { target *-*-* } } +const U8_MUT2: &u8 = { // { dg-note "" "" { target *-*-* } } + unsafe { &(*static_cross_crate::ZERO_REF)[0] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +}; +#[warn(const_err)] // { dg-note "" "" { target *-*-* } } +const U8_MUT3: &u8 = { // { dg-note "" "" { target *-*-* } } + unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +}; + +pub fn test(x: &[u8; 1]) -> bool { + match x { + SLICE_MUT => true, +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + &[1..] => false, + } +} + +pub fn test2(x: &u8) -> bool { + match x { + U8_MUT => true, +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + &(1..) => false, + } +} + +// We need to use these *in a pattern* to trigger the failure... likely because +// the errors above otherwise stop compilation too early? +pub fn test3(x: &u8) -> bool { + match x { + U8_MUT2 => true, +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + &(1..) => false, + } +} +pub fn test4(x: &u8) -> bool { + match x { + U8_MUT3 => true, +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + &(1..) => false, + } +} + +fn main() { + unsafe { + static_cross_crate::ZERO[0] = 1; + } + // Now the pattern is not exhaustive any more! + test(&[0]); + test2(&0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/drop.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/drop.rs new file mode 100644 index 000000000000..e449d17f0680 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/drop.rs @@ -0,0 +1,19 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +// error-pattern: calling non-const function ` as Drop>::drop` +#![allow(const_err)] + +use std::mem::ManuallyDrop; + +fn main() {} + +static TEST_OK: () = { + let v: Vec = Vec::new(); + let _v = ManuallyDrop::new(v); +}; + +// Make sure we catch executing bad drop functions. +// The actual error is tested by the error-pattern above. +static TEST_BAD: () = { + let _v: Vec = Vec::new(); +}; + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs new file mode 100644 index 000000000000..65622c1d8c37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs @@ -0,0 +1,29 @@ +#![allow(const_err)] + +// a test demonstrating why we do need to run static const qualification on associated constants +// instead of just checking the final constant + +trait Foo { + const X: T; +} + +trait Bar> { + const F: u32 = (U::X, 42).1; // { dg-error ".E0493." "" { target *-*-* } } +} + +impl Foo for () { + const X: u32 = 42; +} + +impl Foo> for String { + const X: Vec = Vec::new(); +} + +impl Bar for () {} +impl Bar, String> for String {} + +fn main() { + let x = <() as Bar>::F; + let y = , String>>::F; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/inline_asm.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/inline_asm.rs new file mode 100644 index 000000000000..97452f2c9c48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/inline_asm.rs @@ -0,0 +1,23 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +// only-x86_64 +#![feature(asm,llvm_asm)] +#![allow(const_err)] + +fn main() {} + +// Make sure we catch executing inline assembly. +static TEST_BAD1: () = { + unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-note ".E0080." "" { target *-*-* } .-2 } +// { dg-note ".E0080." "" { target *-*-* } .-3 } +// { dg-note ".E0080." "" { target *-*-* } .-4 } +}; + +// Make sure we catch executing inline assembly. +static TEST_BAD2: () = { + unsafe { asm!("nop"); } +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-note ".E0080." "" { target *-*-* } .-2 } +}; + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/mutable_references.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/mutable_references.rs new file mode 100644 index 000000000000..4b13ef29a7fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/mutable_references.rs @@ -0,0 +1,38 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +#![allow(const_err)] + +use std::cell::UnsafeCell; + +// a test demonstrating what things we could allow with a smarter const qualification + +// this is fine because is not possible to mutate through an immutable reference. +static FOO: &&mut u32 = &&mut 42; + +// this is fine because accessing an immutable static `BAR` is equivalent to accessing `*&BAR` +// which puts the mutable reference behind an immutable one. +static BAR: &mut () = &mut (); + +struct Foo(T); + +// this is fine for the same reason as `BAR`. +static BOO: &mut Foo<()> = &mut Foo(()); + +// interior mutability is fine +struct Meh { + x: &'static UnsafeCell, +} +unsafe impl Sync for Meh {} +static MEH: Meh = Meh { + x: &UnsafeCell::new(42), +}; + +// this is fine for the same reason as `BAR`. +static OH_YES: &mut i32 = &mut 42; + +fn main() { + unsafe { + *MEH.x.get() = 99; + } + *OH_YES = 99; // { dg-error ".E0594." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/mutable_references_err.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/mutable_references_err.rs new file mode 100644 index 000000000000..3e46459ea26f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/mutable_references_err.rs @@ -0,0 +1,38 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you + +#![allow(const_err)] + +use std::cell::UnsafeCell; + +// this test ensures that our mutability story is sound + +struct Meh { + x: &'static UnsafeCell, +} +unsafe impl Sync for Meh {} + +// the following will never be ok! no interior mut behind consts, because +// all allocs interned here will be marked immutable. +const MUH: Meh = Meh { // { dg-error ".E0080." "" { target *-*-* } } + x: &UnsafeCell::new(42), +}; + +struct Synced { + x: UnsafeCell, +} +unsafe impl Sync for Synced {} + +// Make sure we also catch this behind a type-erased `dyn Trait` reference. +const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +// Make sure we also catch mutable references. +const BLUNT: &mut i32 = &mut 42; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +fn main() { + unsafe { + *MUH.x.get() = 99; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/mutating_global.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/mutating_global.rs new file mode 100644 index 000000000000..0c7c89cf2ecb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/mutating_global.rs @@ -0,0 +1,17 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +#![allow(const_err)] + +// Make sure we cannot mutate globals. + +static mut GLOBAL: i32 = 0; + +static MUTATING_GLOBAL: () = { + unsafe { + GLOBAL = 99 +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-note ".E0080." "" { target *-*-* } .-2 } + } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/non_const_fn.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/non_const_fn.rs new file mode 100644 index 000000000000..215e996d88f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/non_const_fn.rs @@ -0,0 +1,14 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you + +#![allow(const_err)] + +// A test demonstrating that we prevent calling non-const fn during CTFE. + +fn foo() {} + +static C: () = foo(); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-note ".E0080." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/ptr_arith.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/ptr_arith.rs new file mode 100644 index 000000000000..549c7ffec18b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/ptr_arith.rs @@ -0,0 +1,22 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +#![feature(core_intrinsics)] +#![allow(const_err)] + +// During CTFE, we prevent pointer comparison and pointer-to-int casts. + +static CMP: () = { + let x = &0 as *const _; + let _v = x == x; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-note ".E0080." "" { target *-*-* } .-2 } +}; + +static INT_PTR_ARITH: () = unsafe { + let x: usize = std::mem::transmute(&0); + let _v = x + 0; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-note ".E0080." "" { target *-*-* } .-2 } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/raw_mutable_const.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/raw_mutable_const.rs new file mode 100644 index 000000000000..117d5f2e86e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/raw_mutable_const.rs @@ -0,0 +1,11 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you + +#![allow(const_err)] + +use std::cell::UnsafeCell; + +const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/slice_eq.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/slice_eq.rs new file mode 100644 index 000000000000..b3f4f792be95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/slice_eq.rs @@ -0,0 +1,18 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +// run-pass + +#![feature(const_raw_ptr_comparison)] + +const EMPTY_SLICE: &[i32] = &[]; +const EMPTY_EQ: bool = EMPTY_SLICE.as_ptr().guaranteed_eq(&[] as *const _); +const EMPTY_EQ2: bool = EMPTY_SLICE.as_ptr().guaranteed_ne(&[] as *const _); +const EMPTY_NE: bool = EMPTY_SLICE.as_ptr().guaranteed_ne(&[1] as *const _); +const EMPTY_NE2: bool = EMPTY_SLICE.as_ptr().guaranteed_eq(&[1] as *const _); + +fn main() { + assert!(!EMPTY_EQ); + assert!(!EMPTY_EQ2); + assert!(!EMPTY_NE); + assert!(!EMPTY_NE2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/tls.rs b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/tls.rs new file mode 100644 index 000000000000..ad4f8e1871ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/miri_unleashed/tls.rs @@ -0,0 +1,25 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +#![feature(thread_local)] +#![allow(const_err)] + +use std::thread; + +#[thread_local] +static A: u8 = 0; + +// Make sure we catch accessing thread-local storage. +static TEST_BAD: () = { + unsafe { let _val = A; } +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-note ".E0080." "" { target *-*-* } .-2 } +}; + +// Make sure we catch taking a reference to thread-local storage. +static TEST_BAD_REF: () = { + unsafe { let _val = &A; } +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-note ".E0080." "" { target *-*-* } .-2 } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/mozjs-error.rs b/gcc/testsuite/rust/rustc/ui/consts/mozjs-error.rs new file mode 100644 index 000000000000..fdb815088684 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/mozjs-error.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +struct CustomAutoRooterVFTable { + trace: unsafe extern "C" fn(this: *mut i32, trc: *mut u32), +} + +unsafe trait CustomAutoTraceable: Sized { + const vftable: CustomAutoRooterVFTable = CustomAutoRooterVFTable { + trace: Self::trace, + }; + + unsafe extern "C" fn trace(this: *mut i32, trc: *mut u32) { + let this = this as *const Self; + let this = this.as_ref().unwrap(); + Self::do_trace(this, trc); + } + + fn do_trace(&self, trc: *mut u32); +} + +unsafe impl CustomAutoTraceable for () { + fn do_trace(&self, _: *mut u32) { + // nop + } +} + +fn main() { + let _ = <()>::vftable; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/non-scalar-cast.rs b/gcc/testsuite/rust/rustc/ui/consts/non-scalar-cast.rs new file mode 100644 index 000000000000..05966c0266d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/non-scalar-cast.rs @@ -0,0 +1,10 @@ +// run-pass + +// https://github.com/rust-lang/rust/issues/37448 + +fn main() { + struct A; + const FOO: &A = &(A as A); + let _x = FOO; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/offset.rs b/gcc/testsuite/rust/rustc/ui/consts/offset.rs new file mode 100644 index 000000000000..cc7c03e1cb2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/offset.rs @@ -0,0 +1,115 @@ +// run-pass +#![feature(const_ptr_offset)] +#![feature(const_ptr_offset_from)] +use std::ptr; + +#[repr(C)] +struct Struct { + a: u32, + b: u32, + c: u32, +} +static S: Struct = Struct { a: 0, b: 0, c: 0 }; + +// For these tests we use offset_from to check that two pointers are equal. +// Rust doesn't currently support comparing pointers in const fn. + +static OFFSET_NO_CHANGE: bool = unsafe { + let p1 = &S.b as *const u32; + let p2 = p1.offset(2).offset(-2); + p1.offset_from(p2) == 0 +}; +static OFFSET_MIDDLE: bool = unsafe { + let p1 = (&S.a as *const u32).offset(1); + let p2 = (&S.c as *const u32).offset(-1); + p1.offset_from(p2) == 0 +}; +// Pointing to the end of the allocation is OK +static OFFSET_END: bool = unsafe { + let p1 = (&S.a as *const u32).offset(3); + let p2 = (&S.c as *const u32).offset(1); + p1.offset_from(p2) == 0 +}; +// Casting though a differently sized type is OK +static OFFSET_U8_PTR: bool = unsafe { + let p1 = (&S.a as *const u32 as *const u8).offset(5); + let p2 = (&S.c as *const u32 as *const u8).offset(-3); + p1.offset_from(p2) == 0 +}; +// Any offset with a ZST does nothing +const OFFSET_ZST: bool = unsafe { + let pz = &() as *const (); + // offset_from can't work with ZSTs, so cast to u8 ptr + let p1 = pz.offset(5) as *const u8; + let p2 = pz.offset(isize::MIN) as *const u8; + p1.offset_from(p2) == 0 +}; +const OFFSET_ZERO: bool = unsafe { + let p = [0u8; 0].as_ptr(); + p.offset(0).offset_from(p) == 0 +}; +const OFFSET_ONE: bool = unsafe { + let p = &42u32 as *const u32; + p.offset(1).offset_from(p) == 1 +}; +const OFFSET_DANGLING: bool = unsafe { + let p = ptr::NonNull::::dangling().as_ptr(); + p.offset(0).offset_from(p) == 0 +}; +const OFFSET_UNALIGNED: bool = unsafe { + let arr = [0u8; 32]; + let p1 = arr.as_ptr(); + let p2 = (p1.offset(2) as *const u32).offset(1); + (p2 as *const u8).offset_from(p1) == 6 +}; + +const WRAP_OFFSET_NO_CHANGE: bool = unsafe { + let p1 = &42u32 as *const u32; + let p2 = p1.wrapping_offset(1000).wrapping_offset(-1000); + let p3 = p1.wrapping_offset(-1000).wrapping_offset(1000); + (p1.offset_from(p2) == 0) & (p1.offset_from(p3) == 0) +}; +const WRAP_ADDRESS_SPACE: bool = unsafe { + let p1 = &42u8 as *const u8; + let p2 = p1.wrapping_offset(isize::MIN).wrapping_offset(isize::MIN); + p1.offset_from(p2) == 0 +}; +// Wrap on the count*size_of::() calculation. +const WRAP_SIZE_OF: bool = unsafe { + // Make sure that if p1 moves backwards, we are still in range + let arr = [0u32; 2]; + let p = &arr[1] as *const u32; + // With wrapping arithmetic, isize::MAX * 4 == -4 + let wrapped = p.wrapping_offset(isize::MAX); + let backward = p.wrapping_offset(-1); + wrapped.offset_from(backward) == 0 +}; +const WRAP_INTEGER_POINTER: bool = unsafe { + let p1 = (0x42 as *const u32).wrapping_offset(4); + let p2 = 0x52 as *const u32; + p1.offset_from(p2) == 0 +}; +const WRAP_NULL: bool = unsafe { + let p1 = ptr::null::().wrapping_offset(1); + let p2 = 0x4 as *const u32; + p1.offset_from(p2) == 0 +}; + +fn main() { + assert!(OFFSET_NO_CHANGE); + assert!(OFFSET_MIDDLE); + assert!(OFFSET_END); + assert!(OFFSET_U8_PTR); + assert!(OFFSET_ZST); + assert!(OFFSET_ZERO); + assert!(OFFSET_ONE); + assert!(OFFSET_DANGLING); + assert!(OFFSET_UNALIGNED); + + assert!(WRAP_OFFSET_NO_CHANGE); + assert!(WRAP_ADDRESS_SPACE); + assert!(WRAP_SIZE_OF); + assert!(WRAP_INTEGER_POINTER); + assert!(WRAP_NULL); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/offset_from.rs b/gcc/testsuite/rust/rustc/ui/consts/offset_from.rs new file mode 100644 index 000000000000..766fa436fe98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/offset_from.rs @@ -0,0 +1,53 @@ +// run-pass + +#![feature(const_raw_ptr_deref)] +#![feature(const_ptr_offset_from)] + +struct Struct { + field: (), +} + +#[repr(C)] +struct Struct2 { + data: u8, + field: u8, +} + +pub const OFFSET: usize = { + let uninit = std::mem::MaybeUninit::::uninit(); + let base_ptr: *const Struct = &uninit as *const _ as *const Struct; + // The following statement is UB (taking the address of an uninitialized field). + // Const eval doesn't detect this right now, but it may stop compiling at some point + // in the future. + let field_ptr = unsafe { &(*base_ptr).field as *const () as *const u8 }; + let offset = unsafe { field_ptr.offset_from(base_ptr as *const u8) }; + offset as usize +}; + +pub const OFFSET_2: usize = { + let uninit = std::mem::MaybeUninit::::uninit(); + let base_ptr: *const Struct2 = &uninit as *const _ as *const Struct2; + let field_ptr = unsafe { &(*base_ptr).field as *const u8 }; + let offset = unsafe { field_ptr.offset_from(base_ptr as *const u8) }; + offset as usize +}; + +pub const OVERFLOW: isize = { + let uninit = std::mem::MaybeUninit::::uninit(); + let base_ptr: *const Struct2 = &uninit as *const _ as *const Struct2; + let field_ptr = unsafe { &(*base_ptr).field as *const u8 }; + unsafe { (base_ptr as *const u8).offset_from(field_ptr) } +}; + +pub const OFFSET_EQUAL_INTS: isize = { + let ptr = 1 as *const u8; + unsafe { ptr.offset_from(ptr) } +}; + +fn main() { + assert_eq!(OFFSET, 0); + assert_eq!(OFFSET_2, 1); + assert_eq!(OVERFLOW, -1); + assert_eq!(OFFSET_EQUAL_INTS, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/offset_from_ub.rs b/gcc/testsuite/rust/rustc/ui/consts/offset_from_ub.rs new file mode 100644 index 000000000000..9232749375ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/offset_from_ub.rs @@ -0,0 +1,47 @@ +#![feature(const_raw_ptr_deref)] +#![feature(const_ptr_offset_from)] + +#[repr(C)] +struct Struct { + data: u8, + field: u8, +} + +pub const DIFFERENT_ALLOC: usize = { +// { dg-note "" "" { target *-*-* } .-1 } + let uninit = std::mem::MaybeUninit::::uninit(); + let base_ptr: *const Struct = &uninit as *const _ as *const Struct; + let uninit2 = std::mem::MaybeUninit::::uninit(); + let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct; + let offset = unsafe { field_ptr.offset_from(base_ptr) }; + offset as usize +}; + +pub const NOT_PTR: usize = { +// { dg-note "" "" { target *-*-* } .-1 } + unsafe { (42 as *const u8).offset_from(&5u8) as usize } +}; + +pub const NOT_MULTIPLE_OF_SIZE: isize = { +// { dg-note "" "" { target *-*-* } .-1 } + let data = [5u8, 6, 7]; + let base_ptr = data.as_ptr(); + let field_ptr = &data[1] as *const u8 as *const u16; + unsafe { field_ptr.offset_from(base_ptr as *const u16) } +}; + +pub const OFFSET_FROM_NULL: isize = { +// { dg-note "" "" { target *-*-* } .-1 } + let ptr = 0 as *const u8; + unsafe { ptr.offset_from(ptr) } +}; + +pub const DIFFERENT_INT: isize = { // offset_from with two different integers: like DIFFERENT_ALLOC +// { dg-note "" "" { target *-*-* } .-1 } + let ptr1 = 8 as *const u8; + let ptr2 = 16 as *const u8; + unsafe { ptr2.offset_from(ptr1) } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/offset_ub.rs b/gcc/testsuite/rust/rustc/ui/consts/offset_ub.rs new file mode 100644 index 000000000000..658fbfad9296 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/offset_ub.rs @@ -0,0 +1,26 @@ +// ignore-tidy-linelength +#![feature(const_ptr_offset)] +use std::ptr; + +// normalize-stderr-test "alloc\d+" -> "allocN" + +pub const BEFORE_START: *const u8 = unsafe { (&0u8 as *const u8).offset(-1) }; // { dg-note "" "" { target *-*-* } } +pub const AFTER_END: *const u8 = unsafe { (&0u8 as *const u8).offset(2) }; // { dg-note "" "" { target *-*-* } } +pub const AFTER_ARRAY: *const u8 = unsafe { [0u8; 100].as_ptr().offset(101) }; // { dg-note "" "" { target *-*-* } } + +pub const OVERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MAX) }; // { dg-note "" "" { target *-*-* } } +pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) }; // { dg-note "" "" { target *-*-* } } +pub const OVERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (usize::MAX as *const u8).offset(2) }; // { dg-note "" "" { target *-*-* } } +pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).offset(-2) }; // { dg-note "" "" { target *-*-* } } + +pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) }; // { dg-note "" "" { target *-*-* } } +pub const DANGLING: *const u8 = unsafe { ptr::NonNull::::dangling().as_ptr().offset(4) }; // { dg-note "" "" { target *-*-* } } + +// Right now, a zero offset from null is UB +pub const NULL_OFFSET_ZERO: *const u8 = unsafe { ptr::null::().offset(0) }; // { dg-note "" "" { target *-*-* } } + +// Make sure that we don't panic when computing abs(offset*size_of::()) +pub const UNDERFLOW_ABS: *const u8 = unsafe { (usize::MAX as *const u8).offset(isize::MIN) }; // { dg-note "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/packed_pattern.rs b/gcc/testsuite/rust/rustc/ui/consts/packed_pattern.rs new file mode 100644 index 000000000000..7265d70b73f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/packed_pattern.rs @@ -0,0 +1,20 @@ +// run-pass + +#[derive(PartialEq, Eq, Copy, Clone)] +#[repr(packed)] +struct Foo { + field: (i64, u32, u32, u32), +} + +const FOO: Foo = Foo { + field: (5, 6, 7, 8), +}; + +fn main() { + match FOO { + Foo { field: (5, 6, 7, 8) } => {}, + FOO => unreachable!(), // { dg-warning "" "" { target *-*-* } } + _ => unreachable!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/packed_pattern2.rs b/gcc/testsuite/rust/rustc/ui/consts/packed_pattern2.rs new file mode 100644 index 000000000000..42e0370bdd5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/packed_pattern2.rs @@ -0,0 +1,28 @@ +// run-pass + +#[derive(PartialEq, Eq, Copy, Clone)] +#[repr(packed)] +struct Foo { + field: (u8, u16), +} + +#[derive(PartialEq, Eq, Copy, Clone)] +#[repr(align(2))] +struct Bar { + a: Foo, +} + +const FOO: Bar = Bar { + a: Foo { + field: (5, 6), + } +}; + +fn main() { + match FOO { + Bar { a: Foo { field: (5, 6) } } => {}, + FOO => unreachable!(), // { dg-warning "" "" { target *-*-* } } + _ => unreachable!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/partial_qualif.rs b/gcc/testsuite/rust/rustc/ui/consts/partial_qualif.rs new file mode 100644 index 000000000000..1c45cc5cfda2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/partial_qualif.rs @@ -0,0 +1,10 @@ +use std::cell::Cell; + +const FOO: &(Cell, bool) = { + let mut a = (Cell::new(0), false); + a.1 = true; // sets `qualif(a)` to `qualif(a) | qualif(true)` + &{a} // { dg-error ".E0492." "" { target *-*-* } } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/projection_qualif.rs b/gcc/testsuite/rust/rustc/ui/consts/projection_qualif.rs new file mode 100644 index 000000000000..d3b6e03d3fcc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/projection_qualif.rs @@ -0,0 +1,17 @@ +// revisions: stock mut_refs + +#![cfg_attr(mut_refs, feature(const_mut_refs))] + +use std::cell::Cell; + +const FOO: &u32 = { + let mut a = 42; + { + let b: *mut u32 = &mut a; // { dg-error "" "" { target *-*-* } } + unsafe { *b = 5; } // { dg-error "" "" { target *-*-* } } + } + &{a} +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/promote-not.rs b/gcc/testsuite/rust/rustc/ui/consts/promote-not.rs new file mode 100644 index 000000000000..10f0989b59bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/promote-not.rs @@ -0,0 +1,36 @@ +// ignore-tidy-linelength +// Test various things that we do not want to promote. +#![allow(unconditional_panic, const_err)] +#![feature(const_fn, const_fn_union)] + +// We do not promote mutable references. +static mut TEST1: Option<&mut [i32]> = Some(&mut [1, 2, 3]); // { dg-error ".E0716." "" { target *-*-* } } + +static mut TEST2: &'static mut [i32] = { + let x = &mut [1,2,3]; // { dg-error ".E0716." "" { target *-*-* } } + x +}; + +// We do not promote fn calls in `fn`, including `const fn`. +pub const fn promote_cal(b: bool) -> i32 { + const fn foo() { [()][42] } + + if b { + let _x: &'static () = &foo(); // { dg-error ".E0716." "" { target *-*-* } } + } + 13 +} + +// We do not promote union field accesses in `fn. +union U { x: i32, y: i32 } +pub const fn promote_union() { + let _x: &'static i32 = &unsafe { U { x: 0 }.x }; // { dg-error ".E0716." "" { target *-*-* } } +} + +// We do not promote union field accesses in `const`, either. +const TEST_UNION: () = { + let _x: &'static i32 = &unsafe { U { x: 0 }.x }; // { dg-error ".E0716." "" { target *-*-* } } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/promote_borrowed_field.rs b/gcc/testsuite/rust/rustc/ui/consts/promote_borrowed_field.rs new file mode 100644 index 000000000000..7dfd188fd2e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/promote_borrowed_field.rs @@ -0,0 +1,13 @@ +// run-pass + +// From https://github.com/rust-lang/rust/issues/65727 + +const _: &i32 = { + let x = &(5, false).0; + x +}; + +fn main() { + let _: &'static i32 = &(5, false).0; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/promote_const_let.rs b/gcc/testsuite/rust/rustc/ui/consts/promote_const_let.rs new file mode 100644 index 000000000000..14865867ea1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/promote_const_let.rs @@ -0,0 +1,11 @@ +fn main() { + let x: &'static u32 = { + let y = 42; + &y // { dg-error ".E0597." "" { target *-*-* } } + }; + let x: &'static u32 = &{ // { dg-error ".E0716." "" { target *-*-* } } + let y = 42; + y + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/promote_evaluation_unused_result.rs b/gcc/testsuite/rust/rustc/ui/consts/promote_evaluation_unused_result.rs new file mode 100644 index 000000000000..eb0f163a553e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/promote_evaluation_unused_result.rs @@ -0,0 +1,7 @@ +// build-pass (FIXME(62277): could be check-pass?) + +fn main() { + + let _: &'static usize = &(loop {}, 1).1; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/promote_fn_calls.rs b/gcc/testsuite/rust/rustc/ui/consts/promote_fn_calls.rs new file mode 100644 index 000000000000..a548d9502733 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/promote_fn_calls.rs @@ -0,0 +1,12 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:promotable_const_fn_lib.rs + +extern crate promotable_const_fn_lib; + +use promotable_const_fn_lib::{foo, Foo}; + +fn main() { + let x: &'static usize = &foo(); + let x: &'static usize = &Foo::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/promote_fn_calls_std.rs b/gcc/testsuite/rust/rustc/ui/consts/promote_fn_calls_std.rs new file mode 100644 index 000000000000..e402ab48fc56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/promote_fn_calls_std.rs @@ -0,0 +1,29 @@ +// build-pass (FIXME(62277): could be check-pass?) + +fn main() { + let x: &'static u8 = &u8::max_value(); + let x: &'static u16 = &u16::max_value(); + let x: &'static u32 = &u32::max_value(); + let x: &'static u64 = &u64::max_value(); + let x: &'static u128 = &u128::max_value(); + let x: &'static usize = &usize::max_value(); + let x: &'static u8 = &u8::min_value(); + let x: &'static u16 = &u16::min_value(); + let x: &'static u32 = &u32::min_value(); + let x: &'static u64 = &u64::min_value(); + let x: &'static u128 = &u128::min_value(); + let x: &'static usize = &usize::min_value(); + let x: &'static i8 = &i8::max_value(); + let x: &'static i16 = &i16::max_value(); + let x: &'static i32 = &i32::max_value(); + let x: &'static i64 = &i64::max_value(); + let x: &'static i128 = &i128::max_value(); + let x: &'static isize = &isize::max_value(); + let x: &'static i8 = &i8::min_value(); + let x: &'static i16 = &i16::min_value(); + let x: &'static i32 = &i32::min_value(); + let x: &'static i64 = &i64::min_value(); + let x: &'static i128 = &i128::min_value(); + let x: &'static isize = &isize::min_value(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/promoted-validation-55454.rs b/gcc/testsuite/rust/rustc/ui/consts/promoted-validation-55454.rs new file mode 100644 index 000000000000..54d0028f9e7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/promoted-validation-55454.rs @@ -0,0 +1,10 @@ +// https://github.com/rust-lang/rust/issues/55454 +// build-pass (FIXME(62277): could be check-pass?) + +#[derive(PartialEq)] +struct This(T); + +fn main() { + This(Some(&1)) == This(Some(&1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/promoted_div_by_zero.rs b/gcc/testsuite/rust/rustc/ui/consts/promoted_div_by_zero.rs new file mode 100644 index 000000000000..3eae4df41c3b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/promoted_div_by_zero.rs @@ -0,0 +1,10 @@ +#![allow(unconditional_panic, const_err)] + +// run-fail +// error-pattern: attempt to divide by zero +// ignore-emscripten no processes + +fn main() { + let x = &(1 / (1 - 1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/promoted_regression.rs b/gcc/testsuite/rust/rustc/ui/consts/promoted_regression.rs new file mode 100644 index 000000000000..4d2914d56c0b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/promoted_regression.rs @@ -0,0 +1,10 @@ +// build-pass (FIXME(62277): could be check-pass?) + +fn main() { + let _ = &[("", ""); 3]; +} + +const FOO: &[(&str, &str)] = &[("", ""); 3]; +const BAR: &[(&str, &str); 5] = &[("", ""); 5]; +const BAA: &[[&str; 12]; 11] = &[[""; 12]; 11]; + diff --git a/gcc/testsuite/rust/rustc/ui/consts/promotion-mutable-ref.rs b/gcc/testsuite/rust/rustc/ui/consts/promotion-mutable-ref.rs new file mode 100644 index 000000000000..cbac25ab45ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/promotion-mutable-ref.rs @@ -0,0 +1,18 @@ +// run-pass +#![feature(const_mut_refs)] + +static mut TEST: i32 = { + // We must not promote this, as CTFE needs to be able to mutate it later. + let x = &mut [1,2,3]; + x[0] += 1; + x[0] +}; + +// This still works -- it's not done via promotion. +#[allow(unused)] +static mut TEST2: &'static mut [i32] = &mut [0,1,2]; + +fn main() { + assert_eq!(unsafe { TEST }, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/promotion.rs b/gcc/testsuite/rust/rustc/ui/consts/promotion.rs new file mode 100644 index 000000000000..6e139e0fdbe1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/promotion.rs @@ -0,0 +1,18 @@ +// check-pass + +// compile-flags: -O + +fn foo(_: &'static [&'static str]) {} +fn bar(_: &'static [&'static str; 3]) {} +fn baz_i32(_: &'static i32) {} +fn baz_u32(_: &'static u32) {} + +fn main() { + foo(&["a", "b", "c"]); + bar(&["d", "e", "f"]); + + // make sure that these do not cause trouble despite overflowing + baz_u32(&(0-1)); + baz_i32(&-std::i32::MIN); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/ptr_comparisons.rs b/gcc/testsuite/rust/rustc/ui/consts/ptr_comparisons.rs new file mode 100644 index 000000000000..0e99eb62a6b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/ptr_comparisons.rs @@ -0,0 +1,79 @@ +// compile-flags: --crate-type=lib +// normalize-stderr-32bit: "offset 8" -> "offset $$TWO_WORDS" +// normalize-stderr-64bit: "offset 16" -> "offset $$TWO_WORDS" +// normalize-stderr-32bit: "size 4" -> "size $$WORD" +// normalize-stderr-64bit: "size 8" -> "size $$WORD" + +#![feature( + const_panic, + core_intrinsics, + const_raw_ptr_comparison, + const_ptr_offset, + const_raw_ptr_deref, + raw_ref_macros +)] + +const FOO: &usize = &42; + +macro_rules! check { + (eq, $a:expr, $b:expr) => { + pub const _: () = + assert!(std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8)); + }; + (ne, $a:expr, $b:expr) => { + pub const _: () = + assert!(std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8)); + }; + (!eq, $a:expr, $b:expr) => { + pub const _: () = + assert!(!std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8)); + }; + (!ne, $a:expr, $b:expr) => { + pub const _: () = + assert!(!std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8)); + }; +} + +check!(eq, 0, 0); +check!(ne, 0, 1); +check!(!eq, 0, 1); +check!(!ne, 0, 0); +check!(ne, FOO as *const _, 0); +check!(!eq, FOO as *const _, 0); +// We want pointers to be equal to themselves, but aren't checking this yet because +// there are some open questions (e.g. whether function pointers to the same function +// compare equal, they don't necessarily at runtime). +// The case tested here should work eventually, but does not work yet. +check!(!eq, FOO as *const _, FOO as *const _); +check!(ne, unsafe { (FOO as *const usize).offset(1) }, 0); +check!(!eq, unsafe { (FOO as *const usize).offset(1) }, 0); + +check!(ne, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0); +check!(!eq, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0); + +/////////////////////////////////////////////////////////////////////////////// +// If any of the below start compiling, make sure to add a `check` test for it. +// These invocations exist as canaries so we don't forget to check that the +// behaviour of `guaranteed_eq` and `guaranteed_ne` is still correct. +// All of these try to obtain an out of bounds pointer in some manner. If we +// can create out of bounds pointers, we can offset a pointer far enough that +// at runtime it would be zero and at compile-time it would not be zero. + +const _: *const usize = unsafe { (FOO as *const usize).offset(2) }; +// { dg-note "" "" { target *-*-* } .-1 } + +const _: *const u8 = +// { dg-note "" "" { target *-*-* } .-1 } + unsafe { std::ptr::raw_const!((*(FOO as *const usize as *const [u8; 1000]))[999]) }; +// { dg-error "" "" { target *-*-* } .-1 } + +const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + +const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + diff --git a/gcc/testsuite/rust/rustc/ui/consts/ptr_is_null.rs b/gcc/testsuite/rust/rustc/ui/consts/ptr_is_null.rs new file mode 100644 index 000000000000..4c2d78add658 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/ptr_is_null.rs @@ -0,0 +1,17 @@ +// compile-flags: --crate-type=lib +// check-pass + +#![feature(const_ptr_is_null, const_panic)] + +const FOO: &usize = &42; + +pub const _: () = assert!(!(FOO as *const usize).is_null()); + +pub const _: () = assert!(!(42 as *const usize).is_null()); + +pub const _: () = assert!((0 as *const usize).is_null()); + +pub const _: () = assert!(std::ptr::null::().is_null()); + +pub const _: () = assert!(!("foo" as *const str).is_null()); + diff --git a/gcc/testsuite/rust/rustc/ui/consts/qualif_overwrite.rs b/gcc/testsuite/rust/rustc/ui/consts/qualif_overwrite.rs new file mode 100644 index 000000000000..43de2eeaf1f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/qualif_overwrite.rs @@ -0,0 +1,14 @@ +use std::cell::Cell; + +// this is overly conservative. The reset to `None` should clear `a` of all qualifications +// while we could fix this, it would be inconsistent with `qualif_overwrite_2.rs`. +// We can fix this properly in the future by allowing constants that do not depend on generics +// to be checked by an analysis on the final value instead of looking at the body. +const FOO: &Option> = { + let mut a = Some(Cell::new(0)); + a = None; // sets `qualif(a)` to `qualif(a) | qualif(None)` + &{a} // { dg-error ".E0492." "" { target *-*-* } } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/qualif_overwrite_2.rs b/gcc/testsuite/rust/rustc/ui/consts/qualif_overwrite_2.rs new file mode 100644 index 000000000000..45106fcd0293 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/qualif_overwrite_2.rs @@ -0,0 +1,12 @@ +use std::cell::Cell; + +// const qualification is not smart enough to know about fields and always assumes that there might +// be other fields that caused the qualification +const FOO: &Option> = { + let mut a = (Some(Cell::new(0)),); + a.0 = None; // sets `qualif(a)` to `qualif(a) | qualif(None)` + &{a.0} // { dg-error ".E0492." "" { target *-*-* } } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/raw-ptr-const.rs b/gcc/testsuite/rust/rustc/ui/consts/raw-ptr-const.rs new file mode 100644 index 000000000000..fc8cd6e0a252 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/raw-ptr-const.rs @@ -0,0 +1,11 @@ +#![allow(const_err)] // make sure we hit the `delay_span_bug` + +// This is a regression test for a `delay_span_bug` during interning when a constant +// evaluates to a (non-dangling) raw pointer. For now this errors; potentially it +// could also be allowed. + +const CONST_RAW: *const Vec = &Vec::new() as *const _; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/raw_pointer_promoted.rs b/gcc/testsuite/rust/rustc/ui/consts/raw_pointer_promoted.rs new file mode 100644 index 000000000000..5c1821bbe3f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/raw_pointer_promoted.rs @@ -0,0 +1,6 @@ +// check-pass + +pub const FOO: &'static *const i32 = &(&0 as _); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/read_from_static_mut_ref.rs b/gcc/testsuite/rust/rustc/ui/consts/read_from_static_mut_ref.rs new file mode 100644 index 000000000000..b7fdd1afd6af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/read_from_static_mut_ref.rs @@ -0,0 +1,10 @@ +// We are keeping this test in case we decide to allow mutable references in statics again +#![feature(const_mut_refs)] +#![allow(const_err)] + +static OH_NO: &mut i32 = &mut 42; +// { dg-error ".E0764." "" { target *-*-* } .-1 } +fn main() { + assert_eq!(*OH_NO, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/recursive-zst-static.rs b/gcc/testsuite/rust/rustc/ui/consts/recursive-zst-static.rs new file mode 100644 index 000000000000..e4db81eccc58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/recursive-zst-static.rs @@ -0,0 +1,15 @@ +// revisions: default unleash +//[unleash]compile-flags: -Zunleash-the-miri-inside-of-you + +// This test ensures that we do not allow ZST statics to initialize themselves without ever +// actually creating a value of that type. This is important, as the ZST may have private fields +// that users can reasonably expect to only get initialized by their own code. Thus unsafe code +// can depend on this fact and will thus do unsound things when it is violated. +// See https://github.com/rust-lang/rust/issues/71078 for more details. + +static FOO: () = FOO; // { dg-error "" "" { target *-*-* } } + +fn main() { + FOO +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/references.rs b/gcc/testsuite/rust/rustc/ui/consts/references.rs new file mode 100644 index 000000000000..f52329894704 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/references.rs @@ -0,0 +1,28 @@ +// run-pass + +const FOO: &[u8] = b"foo"; +const BAR: &[u8] = &[1, 2, 3]; + +const BOO: &i32 = &42; + +fn main() { + match &[1u8, 2, 3] as &[u8] { + FOO => panic!("a"), + BAR => println!("b"), + _ => panic!("c"), + } + + match b"foo" as &[u8] { + FOO => println!("a"), + BAR => panic!("b"), + _ => panic!("c"), + } + + #[allow(unreachable_patterns)] + match &43 { + &42 => panic!(), + BOO => panic!(), + _ => println!("d"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/repeat_match.rs b/gcc/testsuite/rust/rustc/ui/consts/repeat_match.rs new file mode 100644 index 000000000000..e7d4adac5c4c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/repeat_match.rs @@ -0,0 +1,13 @@ +// run-pass + +// https://github.com/rust-lang/rust/issues/45044 + +const X: [u8; 1] = [0; 1]; + +fn main() { + match &X { + &X => println!("a"), + _ => println!("b"), + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/return-in-const-fn.rs b/gcc/testsuite/rust/rustc/ui/consts/return-in-const-fn.rs new file mode 100644 index 000000000000..f2d1ce54b0b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/return-in-const-fn.rs @@ -0,0 +1,11 @@ +// run-pass + +// https://github.com/rust-lang/rust/issues/43754 + +const fn foo(x: usize) -> usize { + return x; +} +fn main() { + [0; foo(2)]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/fn-call-in-const.rs b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/fn-call-in-const.rs new file mode 100644 index 000000000000..983d78444b01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/fn-call-in-const.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(unused)] +#![feature(const_in_array_repeat_expressions)] + +// Some type that is not copyable. +struct Bar; + +const fn type_no_copy() -> Option { + None +} + +const fn type_copy() -> u32 { + 3 +} + +const _: [u32; 2] = [type_copy(); 2]; + +// This is allowed because all promotion contexts use the explicit rules for promotability when +// inside an explicit const context. +const _: [Option; 2] = [type_no_copy(); 2]; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/fn-call-in-non-const.rs b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/fn-call-in-non-const.rs new file mode 100644 index 000000000000..87e93ac0acf9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/fn-call-in-non-const.rs @@ -0,0 +1,19 @@ +#![feature(const_in_array_repeat_expressions)] + +// Some type that is not copyable. +struct Bar; + +const fn no_copy() -> Option { + None +} + +const fn copy() -> u32 { + 3 +} + +fn main() { + let _: [u32; 2] = [copy(); 2]; + let _: [Option; 2] = [no_copy(); 2]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.rs b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.rs new file mode 100644 index 000000000000..7d5955902d7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-fail.rs @@ -0,0 +1,26 @@ +// ignore-compare-mode-nll +// compile-flags: -Z borrowck=migrate +#![feature(const_in_array_repeat_expressions)] +#![allow(warnings)] + +// Some type that is not copyable. +struct Bar; + +mod non_constants { + use Bar; + + fn no_impl_copy_empty_value_multiple_elements() { + let x = None; + let arr: [Option; 2] = [x; 2]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } + + fn no_impl_copy_value_multiple_elements() { + let x = Some(Bar); + let arr: [Option; 2] = [x; 2]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-pass.rs b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-pass.rs new file mode 100644 index 000000000000..63c931f3b409 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/migrate-pass.rs @@ -0,0 +1,129 @@ +// check-pass +// compile-flags: -Z borrowck=migrate +// ignore-compare-mode-nll +#![feature(const_in_array_repeat_expressions)] +#![allow(warnings)] + +// Some type that is not copyable. +struct Bar; + +mod constants { + use Bar; + + fn no_impl_copy_empty_value_no_elements() { + const FOO: Option = None; + const ARR: [Option; 0] = [FOO; 0]; + } + + fn no_impl_copy_empty_value_single_element() { + const FOO: Option = None; + const ARR: [Option; 1] = [FOO; 1]; + } + + fn no_impl_copy_empty_value_multiple_elements() { + const FOO: Option = None; + const ARR: [Option; 2] = [FOO; 2]; + } + + fn no_impl_copy_value_no_elements() { + const FOO: Option = Some(Bar); + const ARR: [Option; 0] = [FOO; 0]; + } + + fn no_impl_copy_value_single_element() { + const FOO: Option = Some(Bar); + const ARR: [Option; 1] = [FOO; 1]; + } + + fn no_impl_copy_value_multiple_elements() { + const FOO: Option = Some(Bar); + const ARR: [Option; 2] = [FOO; 2]; + } + + fn impl_copy_empty_value_no_elements() { + const FOO: Option = None; + const ARR: [Option; 0] = [FOO; 0]; + } + + fn impl_copy_empty_value_one_element() { + const FOO: Option = None; + const ARR: [Option; 1] = [FOO; 1]; + } + + fn impl_copy_empty_value_multiple_elements() { + const FOO: Option = None; + const ARR: [Option; 2] = [FOO; 2]; + } + + fn impl_copy_value_no_elements() { + const FOO: Option = Some(4); + const ARR: [Option; 0] = [FOO; 0]; + } + + fn impl_copy_value_one_element() { + const FOO: Option = Some(4); + const ARR: [Option; 1] = [FOO; 1]; + } + + fn impl_copy_value_multiple_elements() { + const FOO: Option = Some(4); + const ARR: [Option; 2] = [FOO; 2]; + } +} + +mod non_constants { + use Bar; + + fn no_impl_copy_empty_value_no_elements() { + let x = None; + let arr: [Option; 0] = [x; 0]; + } + + fn no_impl_copy_empty_value_single_element() { + let x = None; + let arr: [Option; 1] = [x; 1]; + } + + fn no_impl_copy_value_no_elements() { + let x = Some(Bar); + let arr: [Option; 0] = [x; 0]; + } + + fn no_impl_copy_value_single_element() { + let x = Some(Bar); + let arr: [Option; 1] = [x; 1]; + } + + fn impl_copy_empty_value_no_elements() { + let x: Option = None; + let arr: [Option; 0] = [x; 0]; + } + + fn impl_copy_empty_value_one_element() { + let x: Option = None; + let arr: [Option; 1] = [x; 1]; + } + + fn impl_copy_empty_value_multiple_elements() { + let x: Option = None; + let arr: [Option; 2] = [x; 2]; + } + + fn impl_copy_value_no_elements() { + let x: Option = Some(4); + let arr: [Option; 0] = [x; 0]; + } + + fn impl_copy_value_one_element() { + let x: Option = Some(4); + let arr: [Option; 1] = [x; 1]; + } + + fn impl_copy_value_multiple_elements() { + let x: Option = Some(4); + let arr: [Option; 2] = [x; 2]; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.rs b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.rs new file mode 100644 index 000000000000..e8a38bb51759 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/nll-fail.rs @@ -0,0 +1,25 @@ +// ignore-compare-mode-nll +#![feature(const_in_array_repeat_expressions, nll)] +#![allow(warnings)] + +// Some type that is not copyable. +struct Bar; + +mod non_constants { + use Bar; + + fn no_impl_copy_empty_value_multiple_elements() { + let x = None; + let arr: [Option; 2] = [x; 2]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } + + fn no_impl_copy_value_multiple_elements() { + let x = Some(Bar); + let arr: [Option; 2] = [x; 2]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/nll-pass.rs b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/nll-pass.rs new file mode 100644 index 000000000000..095bd03fa509 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/nll-pass.rs @@ -0,0 +1,128 @@ +// check-pass +// ignore-compare-mode-nll +#![allow(warnings)] +#![feature(const_in_array_repeat_expressions, nll)] + +// Some type that is not copyable. +struct Bar; + +mod constants { + use Bar; + + fn no_impl_copy_empty_value_no_elements() { + const FOO: Option = None; + const ARR: [Option; 0] = [FOO; 0]; + } + + fn no_impl_copy_empty_value_single_element() { + const FOO: Option = None; + const ARR: [Option; 1] = [FOO; 1]; + } + + fn no_impl_copy_empty_value_multiple_elements() { + const FOO: Option = None; + const ARR: [Option; 2] = [FOO; 2]; + } + + fn no_impl_copy_value_no_elements() { + const FOO: Option = Some(Bar); + const ARR: [Option; 0] = [FOO; 0]; + } + + fn no_impl_copy_value_single_element() { + const FOO: Option = Some(Bar); + const ARR: [Option; 1] = [FOO; 1]; + } + + fn no_impl_copy_value_multiple_elements() { + const FOO: Option = Some(Bar); + const ARR: [Option; 2] = [FOO; 2]; + } + + fn impl_copy_empty_value_no_elements() { + const FOO: Option = None; + const ARR: [Option; 0] = [FOO; 0]; + } + + fn impl_copy_empty_value_one_element() { + const FOO: Option = None; + const ARR: [Option; 1] = [FOO; 1]; + } + + fn impl_copy_empty_value_multiple_elements() { + const FOO: Option = None; + const ARR: [Option; 2] = [FOO; 2]; + } + + fn impl_copy_value_no_elements() { + const FOO: Option = Some(4); + const ARR: [Option; 0] = [FOO; 0]; + } + + fn impl_copy_value_one_element() { + const FOO: Option = Some(4); + const ARR: [Option; 1] = [FOO; 1]; + } + + fn impl_copy_value_multiple_elements() { + const FOO: Option = Some(4); + const ARR: [Option; 2] = [FOO; 2]; + } +} + +mod non_constants { + use Bar; + + fn no_impl_copy_empty_value_no_elements() { + let x = None; + let arr: [Option; 0] = [x; 0]; + } + + fn no_impl_copy_empty_value_single_element() { + let x = None; + let arr: [Option; 1] = [x; 1]; + } + + fn no_impl_copy_value_no_elements() { + let x = Some(Bar); + let arr: [Option; 0] = [x; 0]; + } + + fn no_impl_copy_value_single_element() { + let x = Some(Bar); + let arr: [Option; 1] = [x; 1]; + } + + fn impl_copy_empty_value_no_elements() { + let x: Option = None; + let arr: [Option; 0] = [x; 0]; + } + + fn impl_copy_empty_value_one_element() { + let x: Option = None; + let arr: [Option; 1] = [x; 1]; + } + + fn impl_copy_empty_value_multiple_elements() { + let x: Option = None; + let arr: [Option; 2] = [x; 2]; + } + + fn impl_copy_value_no_elements() { + let x: Option = Some(4); + let arr: [Option; 0] = [x; 0]; + } + + fn impl_copy_value_one_element() { + let x: Option = Some(4); + let arr: [Option; 1] = [x; 1]; + } + + fn impl_copy_value_multiple_elements() { + let x: Option = Some(4); + let arr: [Option; 2] = [x; 2]; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/run-pass.rs b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/run-pass.rs new file mode 100644 index 000000000000..c4ebfde78238 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/run-pass.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(const_in_array_repeat_expressions)] + +#[derive(Debug, Eq, PartialEq)] +struct Bar; + +fn main() { + const FOO: Option = None; + const ARR: [Option; 2] = [FOO; 2]; + + assert_eq!(ARR, [None::, None::]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.rs b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.rs new file mode 100644 index 000000000000..825619a10806 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/rfc-2203-const-array-repeat-exprs/trait-error.rs @@ -0,0 +1,10 @@ +#![feature(const_in_array_repeat_expressions)] + +#[derive(Copy, Clone)] +struct Foo(T); + +fn main() { + [Foo(String::new()); 4]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/self_normalization.rs b/gcc/testsuite/rust/rustc/ui/consts/self_normalization.rs new file mode 100644 index 000000000000..7772e622523c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/self_normalization.rs @@ -0,0 +1,17 @@ +// check-pass + +fn testfn(_arr: &mut [(); 0]) {} + +trait TestTrait { + fn method(); +} + +impl TestTrait for [(); 0] { + fn method() { + let mut arr: Self = [(); 0]; + testfn(&mut arr); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/self_normalization2.rs b/gcc/testsuite/rust/rustc/ui/consts/self_normalization2.rs new file mode 100644 index 000000000000..3cefd874bb90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/self_normalization2.rs @@ -0,0 +1,22 @@ +// check-pass + +trait Gen { + fn gen(x: Self) -> T; +} + +struct A; + +impl Gen<[(); 0]> for A { + fn gen(x: Self) -> [(); 0] { + [] + } +} + +fn array() -> impl Gen<[(); 0]> { + A +} + +fn main() { + let [] = Gen::gen(array()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/signed_enum_discr.rs b/gcc/testsuite/rust/rustc/ui/consts/signed_enum_discr.rs new file mode 100644 index 000000000000..0e7ca40018d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/signed_enum_discr.rs @@ -0,0 +1,20 @@ +// run-pass + +// https://github.com/rust-lang/rust/issues/49181 + +#[derive(Eq, PartialEq)] +#[repr(i8)] +pub enum A { + B = -1, + C = 1, +} + +pub const D: A = A::B; + +fn main() { + match A::C { + D => {}, + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/stable-precise-live-drops-in-libcore.rs b/gcc/testsuite/rust/rustc/ui/consts/stable-precise-live-drops-in-libcore.rs new file mode 100644 index 000000000000..17210a289478 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/stable-precise-live-drops-in-libcore.rs @@ -0,0 +1,23 @@ +#![stable(feature = "core", since = "1.6.0")] +#![feature(staged_api)] +#![feature(const_precise_live_drops, const_fn)] + +enum Either { + Left(T), + Right(S), +} + +impl Either { + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_stable(feature = "foo", since = "1.0.0")] + pub const fn unwrap(self) -> T { +// { dg-error ".E0493." "" { target *-*-* } .-1 } + match self { + Self::Left(t) => t, + Self::Right(t) => t, + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/static-cycle-error.rs b/gcc/testsuite/rust/rustc/ui/consts/static-cycle-error.rs new file mode 100644 index 000000000000..c65d72220c31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/static-cycle-error.rs @@ -0,0 +1,12 @@ +// check-pass + +struct Foo { + foo: Option<&'static Foo> +} + +static FOO: Foo = Foo { + foo: Some(&FOO), +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/static-raw-pointer-interning.rs b/gcc/testsuite/rust/rustc/ui/consts/static-raw-pointer-interning.rs new file mode 100644 index 000000000000..873444841fac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/static-raw-pointer-interning.rs @@ -0,0 +1,16 @@ +// run-pass + +static FOO: Foo = Foo { + field: &42 as *const i32, +}; + +struct Foo { + field: *const i32, +} + +unsafe impl Sync for Foo {} + +fn main() { + assert_eq!(unsafe { *FOO.field }, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/static-raw-pointer-interning2.rs b/gcc/testsuite/rust/rustc/ui/consts/static-raw-pointer-interning2.rs new file mode 100644 index 000000000000..b8c70c2108ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/static-raw-pointer-interning2.rs @@ -0,0 +1,16 @@ +// run-pass + +static mut FOO: Foo = Foo { + field: &mut [42] as *mut [i32] as *mut i32, +}; + +struct Foo { + field: *mut i32, +} + +unsafe impl Sync for Foo {} + +fn main() { + assert_eq!(unsafe { *FOO.field = 69; *FOO.field }, 69); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/static_mut_containing_mut_ref.rs b/gcc/testsuite/rust/rustc/ui/consts/static_mut_containing_mut_ref.rs new file mode 100644 index 000000000000..ca0658c6cb66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/static_mut_containing_mut_ref.rs @@ -0,0 +1,8 @@ +// build-pass (FIXME(62277): could be check-pass?) + +static mut STDERR_BUFFER_SPACE: [u8; 42] = [0u8; 42]; + +pub static mut STDERR_BUFFER: *mut [u8] = unsafe { &mut STDERR_BUFFER_SPACE }; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/static_mut_containing_mut_ref2.rs b/gcc/testsuite/rust/rustc/ui/consts/static_mut_containing_mut_ref2.rs new file mode 100644 index 000000000000..e3286f2d1777 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/static_mut_containing_mut_ref2.rs @@ -0,0 +1,11 @@ +// revisions: stock mut_refs + +#![cfg_attr(mut_refs, feature(const_mut_refs))] + +static mut STDERR_BUFFER_SPACE: u8 = 0; + +pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; }; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/static_mut_containing_mut_ref3.rs b/gcc/testsuite/rust/rustc/ui/consts/static_mut_containing_mut_ref3.rs new file mode 100644 index 000000000000..04fb50fadcc9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/static_mut_containing_mut_ref3.rs @@ -0,0 +1,7 @@ +static mut FOO: (u8, u8) = (42, 43); + +static mut BAR: () = unsafe { FOO.0 = 99; }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/std/alloc.rs b/gcc/testsuite/rust/rustc/ui/consts/std/alloc.rs new file mode 100644 index 000000000000..ec6f4ca73c5a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/std/alloc.rs @@ -0,0 +1,11 @@ +use std::alloc::Layout; + +// ok +const LAYOUT_VALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x08) }; + +// not ok, since alignment needs to be non-zero. +const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/std/cell.rs b/gcc/testsuite/rust/rustc/ui/consts/std/cell.rs new file mode 100644 index 000000000000..165881f14afa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/std/cell.rs @@ -0,0 +1,31 @@ +use std::cell::*; + +// not ok, because this would create a silent constant with interior mutability. +// the rules could be relaxed in the future +static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); +// { dg-error ".E0492." "" { target *-*-* } .-1 } + +static FOO3: Wrap> = Wrap(Cell::new(42)); +// ok +static FOO4: Wrap<*mut u32> = Wrap(FOO3.0.as_ptr()); + +// not ok, because the `as_ptr` call takes a reference to a type with interior mutability +// which is not allowed in constants +const FOO2: *mut u32 = Cell::new(42).as_ptr(); +// { dg-error ".E0492." "" { target *-*-* } .-1 } + +struct IMSafeTrustMe(UnsafeCell); +unsafe impl Send for IMSafeTrustMe {} +unsafe impl Sync for IMSafeTrustMe {} + +static BAR: IMSafeTrustMe = IMSafeTrustMe(UnsafeCell::new(5)); + + +struct Wrap(T); +unsafe impl Send for Wrap {} +unsafe impl Sync for Wrap {} + +static BAR_PTR: Wrap<*mut u32> = Wrap(BAR.0.get()); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/std/iter.rs b/gcc/testsuite/rust/rustc/ui/consts/std/iter.rs new file mode 100644 index 000000000000..104f222939c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/std/iter.rs @@ -0,0 +1,10 @@ +// run-pass + +const I: std::iter::Empty = std::iter::empty(); + +fn main() { + for i in I { + panic!("magical value creation: {}", i); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/std/slice.rs b/gcc/testsuite/rust/rustc/ui/consts/std/slice.rs new file mode 100644 index 000000000000..97b10f74839a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/std/slice.rs @@ -0,0 +1,11 @@ +// build-pass (FIXME(62277): could be check-pass?) + +struct Wrap(T); +unsafe impl Send for Wrap {} +unsafe impl Sync for Wrap {} + +static FOO: Wrap<*const u32> = Wrap([42, 44, 46].as_ptr()); +static BAR: Wrap<*const u8> = Wrap("hello".as_ptr()); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/too_generic_eval_ice.rs b/gcc/testsuite/rust/rustc/ui/consts/too_generic_eval_ice.rs new file mode 100644 index 000000000000..079d4ae74d70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/too_generic_eval_ice.rs @@ -0,0 +1,15 @@ +pub struct Foo(A, B); + +impl Foo { + const HOST_SIZE: usize = std::mem::size_of::(); + + pub fn crash() -> bool { + [5; Self::HOST_SIZE] == [6; 0] +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/trait_specialization.rs b/gcc/testsuite/rust/rustc/ui/consts/trait_specialization.rs new file mode 100644 index 000000000000..cbb82e709c91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/trait_specialization.rs @@ -0,0 +1,66 @@ +// ignore-wasm32-bare which doesn't support `std::process:exit()` +// compile-flags: -Zmir-opt-level=2 +// run-pass + +// Tests that specialization does not cause optimizations running on polymorphic MIR to resolve +// to a `default` implementation. + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Marker {} + +trait SpecializedTrait { + const CONST_BOOL: bool; + const CONST_STR: &'static str; + fn method() -> &'static str; +} +impl SpecializedTrait for T { + default const CONST_BOOL: bool = false; + default const CONST_STR: &'static str = "in default impl"; + #[inline(always)] + default fn method() -> &'static str { + "in default impl" + } +} +impl SpecializedTrait for T { + const CONST_BOOL: bool = true; + const CONST_STR: &'static str = "in specialized impl"; + fn method() -> &'static str { + "in specialized impl" + } +} + +fn const_bool() -> &'static str { + if ::CONST_BOOL { + "in specialized impl" + } else { + "in default impl" + } +} +fn const_str() -> &'static str { + ::CONST_STR +} +fn run_method() -> &'static str { + ::method() +} + +struct TypeA; +impl Marker for TypeA {} +struct TypeB; + +#[inline(never)] +fn exit_if_not_eq(left: &str, right: &str) { + if left != right { + std::process::exit(1); + } +} + +pub fn main() { + exit_if_not_eq("in specialized impl", const_bool::()); + exit_if_not_eq("in default impl", const_bool::()); + exit_if_not_eq("in specialized impl", const_str::()); + exit_if_not_eq("in default impl", const_str::()); + exit_if_not_eq("in specialized impl", run_method::()); + exit_if_not_eq("in default impl", run_method::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/transmute-const.rs b/gcc/testsuite/rust/rustc/ui/consts/transmute-const.rs new file mode 100644 index 000000000000..d25dd1eb5606 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/transmute-const.rs @@ -0,0 +1,13 @@ +// run-pass + +use std::mem; + +#[repr(transparent)] +struct Foo(u32); + +const TRANSMUTED_U32: u32 = unsafe { mem::transmute(Foo(3)) }; + +fn main() { + assert_eq!(TRANSMUTED_U32, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/transmute-size-mismatch-before-typeck.rs b/gcc/testsuite/rust/rustc/ui/consts/transmute-size-mismatch-before-typeck.rs new file mode 100644 index 000000000000..e08947559d75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/transmute-size-mismatch-before-typeck.rs @@ -0,0 +1,21 @@ +#![feature(const_transmute)] + +// normalize-stderr-64bit "64 bits" -> "word size" +// normalize-stderr-32bit "32 bits" -> "word size" +// normalize-stderr-64bit "128 bits" -> "2 * word size" +// normalize-stderr-32bit "64 bits" -> "2 * word size" + +fn main() { + match &b""[..] { + ZST => {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + } +} + +const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; +// { dg-error ".E0512." "" { target *-*-* } .-1 } +// { dg-error ".E0512." "" { target *-*-* } .-2 } + +// Once the `any use of this value will cause an error` disappears in this test, make sure to +// remove the `TransmuteSizeDiff` error variant and make its emitter site an assertion again. + diff --git a/gcc/testsuite/rust/rustc/ui/consts/tuple-struct-constructors.rs b/gcc/testsuite/rust/rustc/ui/consts/tuple-struct-constructors.rs new file mode 100644 index 000000000000..0cbf9789a203 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/tuple-struct-constructors.rs @@ -0,0 +1,11 @@ +// run-pass + +// https://github.com/rust-lang/rust/issues/41898 + +use std::num::NonZeroU64; + +fn main() { + const FOO: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(2) }; + if let FOO = FOO {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/underscore_const_names.rs b/gcc/testsuite/rust/rustc/ui/consts/underscore_const_names.rs new file mode 100644 index 000000000000..e191ada00d76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/underscore_const_names.rs @@ -0,0 +1,32 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![deny(unused)] + +trait Trt {} +pub struct Str {} +impl Trt for Str {} + +macro_rules! check_impl { + ($struct:ident,$trait:ident) => { + const _ : () = { + use std::marker::PhantomData; + struct ImplementsTrait(PhantomData); + let _ = ImplementsTrait::<$struct>(PhantomData); + () + }; + } +} + +const _ : () = (); + +const _ : i32 = 42; +const _ : Str = Str{}; + +check_impl!(Str, Trt); +check_impl!(Str, Trt); + +fn main() { + check_impl!(Str, Trt); + check_impl!(Str, Trt); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/uninhabited-const-issue-61744.rs b/gcc/testsuite/rust/rustc/ui/consts/uninhabited-const-issue-61744.rs new file mode 100644 index 000000000000..6260e9e494ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/uninhabited-const-issue-61744.rs @@ -0,0 +1,20 @@ +// build-fail + +pub const unsafe fn fake_type() -> T { + hint_unreachable() +} + +pub const unsafe fn hint_unreachable() -> ! { + fake_type() // { dg-error ".E0080." "" { target *-*-* } } +} + +trait Const { + const CONSTANT: i32 = unsafe { fake_type() }; // { dg-error "" "" { target *-*-* } } +} + +impl Const for T {} + +pub fn main() -> () { + dbg!(i32::CONSTANT); // { dg-error ".E0080." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/union_constant.rs b/gcc/testsuite/rust/rustc/ui/consts/union_constant.rs new file mode 100644 index 000000000000..2a7edb559c4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/union_constant.rs @@ -0,0 +1,12 @@ +// build-pass (FIXME(62277): could be check-pass?) + +union Uninit { + _never_use: *const u8, + uninit: (), +} + +const UNINIT: Uninit = Uninit { uninit: () }; +const UNINIT2: (Uninit,) = (Uninit { uninit: () }, ); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/unsizing-cast-non-null.rs b/gcc/testsuite/rust/rustc/ui/consts/unsizing-cast-non-null.rs new file mode 100644 index 000000000000..113b4bfc4410 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/unsizing-cast-non-null.rs @@ -0,0 +1,11 @@ +// Regression test for #75118. + +use std::ptr::NonNull; + +pub const fn dangling_slice() -> NonNull<[T]> { + NonNull::<[T; 0]>::dangling() +// { dg-error ".E0723." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/unstable-const-fn-in-libcore.rs b/gcc/testsuite/rust/rustc/ui/consts/unstable-const-fn-in-libcore.rs new file mode 100644 index 000000000000..813160fc4deb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/unstable-const-fn-in-libcore.rs @@ -0,0 +1,30 @@ +// This is a non-regression test for const-qualification of unstable items in libcore +// as explained in issue #67053. +// const-qualification could miss some `const fn`s if they were unstable and the feature +// gate was not enabled in libcore. + +#![stable(feature = "core", since = "1.6.0")] +#![feature(rustc_const_unstable)] +#![feature(staged_api)] +#![feature(const_fn)] + +enum Opt { + Some(T), + None, +} + +impl Opt { + #[rustc_const_unstable(feature = "foo", issue = "none")] + #[stable(feature = "rust1", since = "1.0.0")] + const fn unwrap_or_else T>(self, f: F) -> T { +// { dg-error ".E0493." "" { target *-*-* } .-1 } +// { dg-error ".E0493." "" { target *-*-* } .-2 } + match self { + Opt::Some(t) => t, + Opt::None => f(), // { dg-error ".E0015." "" { target *-*-* } } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/unstable-precise-live-drops-in-libcore.rs b/gcc/testsuite/rust/rustc/ui/consts/unstable-precise-live-drops-in-libcore.rs new file mode 100644 index 000000000000..9003ebc3baca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/unstable-precise-live-drops-in-libcore.rs @@ -0,0 +1,24 @@ +// check-pass + +#![stable(feature = "core", since = "1.6.0")] +#![feature(staged_api)] +#![feature(const_precise_live_drops)] + +enum Either { + Left(T), + Right(S), +} + +impl Either { + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "foo", issue = "none")] + pub const fn unwrap(self) -> T { + match self { + Self::Left(t) => t, + Self::Right(t) => t, + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/unwind-abort.rs b/gcc/testsuite/rust/rustc/ui/consts/unwind-abort.rs new file mode 100644 index 000000000000..eff4922ce1ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/unwind-abort.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(unwind_attributes, const_panic)] + +// `#[unwind(aborts)]` is okay for a `const fn`. We don't unwind in const-eval anyways. +#[unwind(aborts)] +const fn foo() { + panic!() +} + +const fn bar() { + foo(); +} + +fn main() { + bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/validate_never_arrays.rs b/gcc/testsuite/rust/rustc/ui/consts/validate_never_arrays.rs new file mode 100644 index 000000000000..b8fdfd5a8145 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/validate_never_arrays.rs @@ -0,0 +1,10 @@ +#![feature(const_raw_ptr_deref, never_type)] + +const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; // { dg-error ".E0080." "" { target *-*-* } } +const _: &[!; 0] = unsafe { &*(1_usize as *const [!; 0]) }; // ok +const _: &[!] = unsafe { &*(1_usize as *const [!; 0]) }; // ok +const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; // { dg-error ".E0080." "" { target *-*-* } } +const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; // { dg-error ".E0080." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/consts/zst_no_llvm_alloc.rs b/gcc/testsuite/rust/rustc/ui/consts/zst_no_llvm_alloc.rs new file mode 100644 index 000000000000..36d28b433e48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/consts/zst_no_llvm_alloc.rs @@ -0,0 +1,22 @@ +// run-pass + +#[repr(align(4))] +struct Foo; + +static FOO: Foo = Foo; + +fn main() { + let x: &'static () = &(); + assert_ne!(x as *const () as usize, 1); + let x: &'static Foo = &Foo; + assert_ne!(x as *const Foo as usize, 4); + + // statics must have a unique address + assert_ne!(&FOO as *const Foo as usize, 4); + + // FIXME this two tests should be assert_eq! + // this stopped working since we are promoting to constants instead of statics + assert_ne!(>::new().as_ptr(), <&[i32]>::default().as_ptr()); + assert_ne!(>::default().as_ptr(), (&[]).as_ptr()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/continue-after-missing-main.rs b/gcc/testsuite/rust/rustc/ui/continue-after-missing-main.rs new file mode 100644 index 000000000000..4ad12c41c76a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/continue-after-missing-main.rs @@ -0,0 +1,31 @@ +#![allow(dead_code)] // { dg-error ".E0601." "" { target *-*-* } } + +struct Tableau<'a, MP> { + provider: &'a MP, +} + +impl<'adapted_matrix_provider, 'original_data, MP> + Tableau<'adapted_matrix_provider, AdaptedMatrixProvider<'original_data, MP>> +{ + fn provider(&self) -> &'adapted_matrix_provider AdaptedMatrixProvider { + self.provider + } +} + +struct AdaptedMatrixProvider<'a, T> { + original_problem: &'a T, +} + +impl<'a, T> AdaptedMatrixProvider<'a, T> { + fn clone_with_extra_bound(&self) -> Self { + AdaptedMatrixProvider { original_problem: self.original_problem } + } +} + +fn create_and_solve_subproblems<'data_provider, 'original_data, MP>( + tableau: Tableau<'data_provider, AdaptedMatrixProvider<'original_data, MP>>, +) { + let _: AdaptedMatrixProvider<'original_data, MP> = tableau.provider().clone_with_extra_bound(); +// { dg-error ".E0623." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/conversion-methods.rs b/gcc/testsuite/rust/rustc/ui/conversion-methods.rs new file mode 100644 index 000000000000..3eb5968a0e62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/conversion-methods.rs @@ -0,0 +1,14 @@ +use std::path::{Path, PathBuf}; + + +fn main() { + let _tis_an_instants_play: String = "'Tis a fond Ambush—"; // { dg-error ".E0308." "" { target *-*-* } } + let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise"); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + let _prove_piercing_earnest: Vec = &[1, 2, 3]; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/copy-a-resource.rs b/gcc/testsuite/rust/rustc/ui/copy-a-resource.rs new file mode 100644 index 000000000000..7c177ca9a1c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/copy-a-resource.rs @@ -0,0 +1,22 @@ +#[derive(Debug)] +struct Foo { + i: isize, +} + +impl Drop for Foo { + fn drop(&mut self) {} +} + +fn foo(i:isize) -> Foo { + Foo { + i: i + } +} + +fn main() { + let x = foo(10); + let _y = x.clone(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + println!("{:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/core-run-destroy.rs b/gcc/testsuite/rust/rustc/ui/core-run-destroy.rs new file mode 100644 index 000000000000..6794a0fcd877 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/core-run-destroy.rs @@ -0,0 +1,89 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(stable_features)] +#![allow(deprecated)] +#![allow(unused_imports)] +// compile-flags:--test +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +// ignore-vxworks no 'cat' and 'sleep' + +// N.B., these tests kill child processes. Valgrind sees these children as leaking +// memory, which makes for some *confusing* logs. That's why these are here +// instead of in std. + +#![feature(rustc_private, duration)] + +extern crate libc; + +use std::process::{self, Command, Child, Output, Stdio}; +use std::str; +use std::sync::mpsc::channel; +use std::thread; +use std::time::Duration; + +macro_rules! t { + ($e:expr) => (match $e { Ok(e) => e, Err(e) => panic!("error: {}", e) }) +} + +#[test] +fn test_destroy_once() { + let mut p = sleeper(); + t!(p.kill()); +} + +#[cfg(unix)] +pub fn sleeper() -> Child { + t!(Command::new("sleep").arg("1000").spawn()) +} +#[cfg(windows)] +pub fn sleeper() -> Child { + // There's a `timeout` command on windows, but it doesn't like having + // its output piped, so instead just ping ourselves a few times with + // gaps in between so we're sure this process is alive for awhile + t!(Command::new("ping").arg("127.0.0.1").arg("-n").arg("1000").spawn()) +} + +#[test] +fn test_destroy_twice() { + let mut p = sleeper(); + t!(p.kill()); // this shouldn't crash... + let _ = p.kill(); // ...and nor should this (and nor should the destructor) +} + +#[test] +fn test_destroy_actually_kills() { + let cmd = if cfg!(windows) { + "cmd" + } else if cfg!(target_os = "android") { + "/system/bin/cat" + } else { + "cat" + }; + + // this process will stay alive indefinitely trying to read from stdin + let mut p = t!(Command::new(cmd) + .stdin(Stdio::piped()) + .spawn()); + + t!(p.kill()); + + // Don't let this test time out, this should be quick + let (tx, rx) = channel(); + thread::spawn(move|| { + thread::sleep_ms(1000); + if rx.try_recv().is_err() { + process::exit(1); + } + }); + let code = t!(p.wait()).code(); + if cfg!(windows) { + assert!(code.is_some()); + } else { + assert!(code.is_none()); + } + tx.send(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/crate-in-paths.rs b/gcc/testsuite/rust/rustc/ui/crate-in-paths.rs new file mode 100644 index 000000000000..378c3c6d912e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/crate-in-paths.rs @@ -0,0 +1,13 @@ +// edition:2018 + +#![feature(crate_visibility_modifier)] + +mod bar { + crate struct Foo; +} + +fn main() { + Foo; +// { dg-error ".E0425." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/crate-leading-sep.rs b/gcc/testsuite/rust/rustc/ui/crate-leading-sep.rs new file mode 100644 index 000000000000..d7bc121de2ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/crate-leading-sep.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + use ::std::mem; + mem::drop(2_usize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/crate-method-reexport-grrrrrrr.rs b/gcc/testsuite/rust/rustc/ui/crate-method-reexport-grrrrrrr.rs new file mode 100644 index 000000000000..a453b38aa2be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/crate-method-reexport-grrrrrrr.rs @@ -0,0 +1,22 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +// This is a regression test that the metadata for the +// name_pool::methods impl in the other crate is reachable from this +// crate. + +// aux-build:crate-method-reexport-grrrrrrr2.rs + +extern crate crate_method_reexport_grrrrrrr2; + +pub fn main() { + use crate_method_reexport_grrrrrrr2::rust::add; + use crate_method_reexport_grrrrrrr2::rust::cx; + let x: Box<_> = box (); + x.cx(); + let y = (); + y.add("hi".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/crate-name-attr-used.rs b/gcc/testsuite/rust/rustc/ui/crate-name-attr-used.rs new file mode 100644 index 000000000000..af3802ac87d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/crate-name-attr-used.rs @@ -0,0 +1,9 @@ +// run-pass +// compile-flags:--crate-name crate_name_attr_used -F unused-attributes + +// pretty-expanded FIXME #23616 + +#![crate_name = "crate_name_attr_used"] + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/crate-name-mismatch.rs b/gcc/testsuite/rust/rustc/ui/crate-name-mismatch.rs new file mode 100644 index 000000000000..d19bcf068784 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/crate-name-mismatch.rs @@ -0,0 +1,7 @@ +// compile-flags: --crate-name foo + +#![crate_name = "bar"] +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/anon_trait_static_method_lib.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/anon_trait_static_method_lib.rs new file mode 100644 index 000000000000..44ebf71c0ec4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/anon_trait_static_method_lib.rs @@ -0,0 +1,10 @@ +pub struct Foo { + pub x: isize +} + +impl Foo { + pub fn new() -> Foo { + Foo { x: 3 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_borrow_lib.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_borrow_lib.rs new file mode 100644 index 000000000000..eb3909314d0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_borrow_lib.rs @@ -0,0 +1,4 @@ +pub fn foo(x: &usize) -> usize { + *x +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_capture_clause.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_capture_clause.rs new file mode 100644 index 000000000000..dff41d580e5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_capture_clause.rs @@ -0,0 +1,11 @@ +use std::thread; +use std::sync::mpsc::{Receiver, channel}; + +pub fn foo(x: T) -> Receiver { + let (tx, rx) = channel(); + thread::spawn(move|| { + tx.send(x.clone()); + }); + rx +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_const.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_const.rs new file mode 100644 index 000000000000..a058705c156b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_const.rs @@ -0,0 +1,7 @@ +pub extern fn bar() { +} + +pub const foopy: &'static str = "hi there"; +pub const uint_val: usize = 12; +pub const uint_expr: usize = (1 << uint_val) - 1; + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_impl_lib.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_impl_lib.rs new file mode 100644 index 000000000000..fb8cc0777d67 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_impl_lib.rs @@ -0,0 +1,17 @@ +#![crate_name="cci_impl_lib"] + +pub trait uint_helpers { + fn to(&self, v: usize, f: F) where F: FnMut(usize); +} + +impl uint_helpers for usize { + #[inline] + fn to(&self, v: usize, mut f: F) where F: FnMut(usize) { + let mut i = *self; + while i < v { + f(i); + i += 1; + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_iter_lib.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_iter_lib.rs new file mode 100644 index 000000000000..4b024bff4f1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_iter_lib.rs @@ -0,0 +1,12 @@ +#![crate_name="cci_iter_lib"] + +#[inline] +pub fn iter(v: &[T], mut f: F) where F: FnMut(&T) { + let mut i = 0; + let n = v.len(); + while i < n { + f(&v[i]); + i += 1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_nested_lib.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_nested_lib.rs new file mode 100644 index 000000000000..b64027e4c9f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_nested_lib.rs @@ -0,0 +1,53 @@ +#![feature(box_syntax)] + +use std::cell::RefCell; + +pub struct Entry { + key: A, + value: B +} + +pub struct alist { + eq_fn: extern "Rust" fn(A,A) -> bool, + data: Box>>>, +} + +pub fn alist_add(lst: &alist, k: A, v: B) { + let mut data = lst.data.borrow_mut(); + (*data).push(Entry{key:k, value:v}); +} + +pub fn alist_get( + lst: &alist, + k: A) + -> B { + let eq_fn = lst.eq_fn; + let data = lst.data.borrow(); + for entry in &(*data) { + if eq_fn(entry.key.clone(), k.clone()) { + return entry.value.clone(); + } + } + panic!(); +} + +#[inline] +pub fn new_int_alist() -> alist { + fn eq_int(a: isize, b: isize) -> bool { a == b } + return alist { + eq_fn: eq_int, + data: box RefCell::new(Vec::new()), + }; +} + +#[inline] +pub fn new_int_alist_2() -> alist { + #[inline] + fn eq_int(a: isize, b: isize) -> bool { a == b } + return alist { + eq_fn: eq_int, + data: box RefCell::new(Vec::new()), + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_no_inline_lib.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_no_inline_lib.rs new file mode 100644 index 000000000000..d1d98526ac9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/cci_no_inline_lib.rs @@ -0,0 +1,13 @@ +#![crate_name="cci_no_inline_lib"] + + +// same as cci_iter_lib, more-or-less, but not marked inline +pub fn iter(v: Vec , mut f: F) where F: FnMut(usize) { + let mut i = 0; + let n = v.len(); + while i < n { + f(v[i]); + i += 1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/moves_based_on_type_lib.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/moves_based_on_type_lib.rs new file mode 100644 index 000000000000..2c78ba96b28f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/moves_based_on_type_lib.rs @@ -0,0 +1,18 @@ +#![crate_type="lib"] + +pub struct S { + x: isize, +} + +impl Drop for S { + fn drop(&mut self) { + println!("goodbye"); + } +} + +pub fn f() { + let x = S { x: 1 }; + let y = x; + let _z = y; +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/newtype_struct_xc.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/newtype_struct_xc.rs new file mode 100644 index 000000000000..0ca9e514aa58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/newtype_struct_xc.rs @@ -0,0 +1,4 @@ +#![crate_type="lib"] + +pub struct Au(pub isize); + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/pub_static_array.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/pub_static_array.rs new file mode 100644 index 000000000000..7b6133aaf515 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/pub_static_array.rs @@ -0,0 +1,2 @@ +pub static ARRAY: [u8; 1] = [1]; + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/reexported_static_methods.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/reexported_static_methods.rs new file mode 100644 index 000000000000..cae9ef96f4e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/reexported_static_methods.rs @@ -0,0 +1,44 @@ +pub use sub_foo::Foo; +pub use self::Bar as Baz; +pub use sub_foo::Boz; +pub use sub_foo::Bort; + +pub trait Bar { + fn bar() -> Self; +} + +impl Bar for isize { + fn bar() -> isize { 84 } +} + +pub mod sub_foo { + pub trait Foo { + fn foo() -> Self; + } + + impl Foo for isize { + fn foo() -> isize { 42 } + } + + pub struct Boz { + unused_str: String + } + + impl Boz { + pub fn boz(i: isize) -> bool { + i > 0 + } + } + + pub enum Bort { + Bort1, + Bort2 + } + + impl Bort { + pub fn bort() -> String { + "bort()".to_string() + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs new file mode 100644 index 000000000000..5af591ac346a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate-trait-lifetime-param.rs @@ -0,0 +1,4 @@ +pub trait FromBuf<'a> { + fn from_buf(_: &'a [u8]) -> Self; +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_address_insignificant.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_address_insignificant.rs new file mode 100644 index 000000000000..2777a88d6988 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_address_insignificant.rs @@ -0,0 +1,9 @@ +pub fn foo() -> isize { + static a: isize = 3; + a +} + +pub fn bar() -> isize { + foo::() +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_associated_type_defaults.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_associated_type_defaults.rs new file mode 100644 index 000000000000..d4b86e76b80b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_associated_type_defaults.rs @@ -0,0 +1,13 @@ +#![feature(associated_type_defaults)] + +pub trait Foo { + type Out: Default + ToString = T; +} + +impl Foo for () { +} + +impl Foo for () { + type Out = bool; +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs new file mode 100644 index 000000000000..acad017e6eac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_generic_fn_nested_return.rs @@ -0,0 +1,17 @@ +pub struct Request { + pub id: String, + pub arg: String, +} + +pub fn decode() -> Result { + (|| { + Ok(Request { + id: "hi".to_owned(), + arg: match Err(()) { + Ok(v) => v, + Err(e) => return Err(e) + }, + }) + })() +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_static_addresses.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_static_addresses.rs new file mode 100644 index 000000000000..5fe7e80b30ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_static_addresses.rs @@ -0,0 +1,18 @@ +pub static global: isize = 3; + +static global0: isize = 4; + +pub static global2: &'static isize = &global0; + +pub fn verify_same(a: &'static isize) { + let a = a as *const isize as usize; + let b = &global as *const isize as usize; + assert_eq!(a, b); +} + +pub fn verify_same2(a: &'static isize) { + let a = a as *const isize as usize; + let b = global2 as *const isize as usize; + assert_eq!(a, b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_unit_struct.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_unit_struct.rs new file mode 100644 index 000000000000..4ba18de4bed1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/auxiliary/xcrate_unit_struct.rs @@ -0,0 +1,29 @@ +#![crate_type = "lib"] + +// used by the rpass test + +#[derive(Copy, Clone)] +pub struct Struct; + +#[derive(Copy, Clone)] +pub enum Unit { + UnitVariant, + Argument(Struct) +} + +#[derive(Copy, Clone)] +pub struct TupleStruct(pub usize, pub &'static str); + +// used by the cfail test + +#[derive(Copy, Clone)] +pub struct StructWithFields { + foo: isize, +} + +#[derive(Copy, Clone)] +pub enum EnumWithVariants { + EnumVariant, + EnumVariantArg(isize) +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/cci_borrow.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/cci_borrow.rs new file mode 100644 index 000000000000..c4dba22fc793 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/cci_borrow.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:cci_borrow_lib.rs + +#![feature(box_syntax)] + +extern crate cci_borrow_lib; +use cci_borrow_lib::foo; + +pub fn main() { + let p: Box<_> = box 22; + let r = foo(&*p); + println!("r={}", r); + assert_eq!(r, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/cci_capture_clause.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/cci_capture_clause.rs new file mode 100644 index 000000000000..3360d344b7c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/cci_capture_clause.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:cci_capture_clause.rs + +// This test makes sure we can do cross-crate inlining on functions +// that use capture clauses. + +// pretty-expanded FIXME #23616 +// ignore-emscripten no threads support + +extern crate cci_capture_clause; + +pub fn main() { + cci_capture_clause::foo(()).recv().unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/cci_impl_exe.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/cci_impl_exe.rs new file mode 100644 index 000000000000..b22506690303 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/cci_impl_exe.rs @@ -0,0 +1,19 @@ +// run-pass +// aux-build:cci_impl_lib.rs + +extern crate cci_impl_lib; +use cci_impl_lib::uint_helpers; + +pub fn main() { + //let bt0 = sys::frame_address(); + //println!("%?", bt0); + + 3.to(10, |i| { + println!("{}", i); + + //let bt1 = sys::frame_address(); + //println!("%?", bt1); + //assert_eq!(bt0, bt1); + }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/cci_iter_exe.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/cci_iter_exe.rs new file mode 100644 index 000000000000..22c209bdc2e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/cci_iter_exe.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:cci_iter_lib.rs + +extern crate cci_iter_lib; + +pub fn main() { + //let bt0 = sys::rusti::frame_address(1); + //println!("%?", bt0); + cci_iter_lib::iter(&[1, 2, 3], |i| { + println!("{}", *i); + //assert_eq!(bt0, sys::rusti::frame_address(2)); + }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/cci_nested_exe.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/cci_nested_exe.rs new file mode 100644 index 000000000000..b6643820ca85 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/cci_nested_exe.rs @@ -0,0 +1,21 @@ +// run-pass +// aux-build:cci_nested_lib.rs + + +extern crate cci_nested_lib; +use cci_nested_lib::*; + +pub fn main() { + let lst = new_int_alist(); + alist_add(&lst, 22, "hi".to_string()); + alist_add(&lst, 44, "ho".to_string()); + assert_eq!(alist_get(&lst, 22), "hi".to_string()); + assert_eq!(alist_get(&lst, 44), "ho".to_string()); + + let lst = new_int_alist_2(); + alist_add(&lst, 22, "hi".to_string()); + alist_add(&lst, 44, "ho".to_string()); + assert_eq!(alist_get(&lst, 22), "hi".to_string()); + assert_eq!(alist_get(&lst, 44), "ho".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/cci_no_inline_exe.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/cci_no_inline_exe.rs new file mode 100644 index 000000000000..60dc97f7f725 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/cci_no_inline_exe.rs @@ -0,0 +1,24 @@ +// run-pass +// aux-build:cci_no_inline_lib.rs + +extern crate cci_no_inline_lib; +use cci_no_inline_lib::iter; + +pub fn main() { + // Check that a cross-crate call function not marked as inline + // does not, in fact, get inlined. Also, perhaps more + // importantly, checks that our scheme of using + // sys::frame_address() to determine if we are inlining is + // actually working. + //let bt0 = sys::frame_address(); + //println!("%?", bt0); + iter(vec![1, 2, 3], |i| { + println!("{}", i); + + //let bt1 = sys::frame_address(); + //println!("%?", bt1); + + //assert!(bt0 != bt1); + }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/cross-crate-const-pat.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/cross-crate-const-pat.rs new file mode 100644 index 000000000000..db8584804e0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/cross-crate-const-pat.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:cci_const.rs + +// pretty-expanded FIXME #23616 + +extern crate cci_const; + +pub fn main() { + let x = cci_const::uint_val; + match x { + cci_const::uint_val => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/cross-crate-newtype-struct-pat.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/cross-crate-newtype-struct-pat.rs new file mode 100644 index 000000000000..cef80a69ffef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/cross-crate-newtype-struct-pat.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:newtype_struct_xc.rs + + +extern crate newtype_struct_xc; + +pub fn main() { + let x = newtype_struct_xc::Au(21); + match x { + newtype_struct_xc::Au(n) => assert_eq!(n, 21) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/a_def_obj.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/a_def_obj.rs new file mode 100644 index 000000000000..1b11a66a5599 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/a_def_obj.rs @@ -0,0 +1,17 @@ +// compile-flags: -C debuginfo=2 + +// no-prefer-dynamic +#![crate_type = "rlib"] + +pub trait Object { fn method(&self) { } } + +impl Object for u32 { } +impl Object for () { } +impl Object for &T { } + +pub fn unused() { + let ref u = 0_u32; + let _d = &u as &dyn crate::Object; + _d.method() +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/b_reexport_obj.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/b_reexport_obj.rs new file mode 100644 index 000000000000..5b531e596164 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/b_reexport_obj.rs @@ -0,0 +1,8 @@ +// compile-flags: -C debuginfo=2 -C prefer-dynamic + +#![crate_type="dylib"] + +extern crate a_def_obj; + +pub use a_def_obj::Object; + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/c_another_vtable_for_obj.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/c_another_vtable_for_obj.rs new file mode 100644 index 000000000000..0dd5b05759ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/c_another_vtable_for_obj.rs @@ -0,0 +1,13 @@ +// no-prefer-dynamic +// compile-flags: -C debuginfo=2 +#![crate_type="rlib"] + +extern crate b_reexport_obj; +use b_reexport_obj::Object; + +pub fn another_dyn_debug() { + let ref u = 1_u32; + let _d = &u as &dyn crate::Object; + _d.method() +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/d_chain_of_rlibs_and_dylibs.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/d_chain_of_rlibs_and_dylibs.rs new file mode 100644 index 000000000000..cf4a8ae0f29b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/auxiliary/d_chain_of_rlibs_and_dylibs.rs @@ -0,0 +1,10 @@ +// compile-flags: -C debuginfo=2 -C prefer-dynamic + +#![crate_type="rlib"] + +extern crate c_another_vtable_for_obj; + +pub fn chain() { + c_another_vtable_for_obj::another_dyn_debug(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/issue-64872.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/issue-64872.rs new file mode 100644 index 000000000000..95951661ebcd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/issue-64872/issue-64872.rs @@ -0,0 +1,18 @@ +// run-pass + +// note that these aux-build directives must be in this order: the +// later crates depend on the earlier ones. (The particular bug that +// is being exercised here used to exhibit itself during the build of +// `chain_of_rlibs_and_dylibs.dylib`) + +// aux-build:a_def_obj.rs +// aux-build:b_reexport_obj.rs +// aux-build:c_another_vtable_for_obj.rs +// aux-build:d_chain_of_rlibs_and_dylibs.rs + +extern crate d_chain_of_rlibs_and_dylibs; + +pub fn main() { + d_chain_of_rlibs_and_dylibs::chain(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/moves-based-on-type-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/moves-based-on-type-cross-crate.rs new file mode 100644 index 000000000000..7f90950a7c17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/moves-based-on-type-cross-crate.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:moves_based_on_type_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate moves_based_on_type_lib; +use moves_based_on_type_lib::f; + +pub fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/reexported-static-methods-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/reexported-static-methods-cross-crate.rs new file mode 100644 index 000000000000..714c211a5060 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/reexported-static-methods-cross-crate.rs @@ -0,0 +1,17 @@ +// run-pass +// aux-build:reexported_static_methods.rs + +extern crate reexported_static_methods; + +use reexported_static_methods::Foo; +use reexported_static_methods::Baz; +use reexported_static_methods::Boz; +use reexported_static_methods::Bort; + +pub fn main() { + assert_eq!(42_isize, Foo::foo()); + assert_eq!(84_isize, Baz::bar()); + assert!(Boz::boz(1)); + assert_eq!("bort()".to_string(), Bort::bort()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/static-array-across-crate.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/static-array-across-crate.rs new file mode 100644 index 000000000000..3e1cfa3ceac3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/static-array-across-crate.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// aux-build:pub_static_array.rs + +extern crate pub_static_array as array; + +use array::ARRAY; + +static X: &'static u8 = &ARRAY[0]; +static Y: &'static u8 = &(&ARRAY)[0]; +static Z: u8 = (&ARRAY)[0]; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-address-insignificant.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-address-insignificant.rs new file mode 100644 index 000000000000..ddf2ad1c8604 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-address-insignificant.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:xcrate_address_insignificant.rs + + +extern crate xcrate_address_insignificant as foo; + +pub fn main() { + assert_eq!(foo::foo::(), foo::bar()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-associated-type-defaults.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-associated-type-defaults.rs new file mode 100644 index 000000000000..5f9c459b5540 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-associated-type-defaults.rs @@ -0,0 +1,30 @@ +// run-pass +// aux-build:xcrate_associated_type_defaults.rs + +extern crate xcrate_associated_type_defaults; +use xcrate_associated_type_defaults::Foo; + +struct LocalDefault; +impl Foo for LocalDefault {} + +struct LocalOverride; +impl Foo for LocalOverride { + type Out = bool; +} + +fn main() { + assert_eq!( + <() as Foo>::Out::default().to_string(), + "0"); + assert_eq!( + <() as Foo>::Out::default().to_string(), + "false"); + + assert_eq!( + >::Out::default().to_string(), + "0"); + assert_eq!( + >::Out::default().to_string(), + "false"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-static-addresses.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-static-addresses.rs new file mode 100644 index 000000000000..58bceb8f6fad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-static-addresses.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:xcrate_static_addresses.rs + +// pretty-expanded FIXME #23616 + +extern crate xcrate_static_addresses; + +use xcrate_static_addresses as other; + +pub fn main() { + other::verify_same(&other::global); + other::verify_same2(other::global2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-trait-lifetime-param.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-trait-lifetime-param.rs new file mode 100644 index 000000000000..e19c6f7db429 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-trait-lifetime-param.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +// aux-build:xcrate-trait-lifetime-param.rs + +// pretty-expanded FIXME #23616 + +extern crate xcrate_trait_lifetime_param as other; + +struct Reader<'a> { + b : &'a [u8] +} + +impl <'a> other::FromBuf<'a> for Reader<'a> { + fn from_buf(b : &'a [u8]) -> Reader<'a> { + Reader { b : b } + } +} + +pub fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-unit-struct.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-unit-struct.rs new file mode 100644 index 000000000000..3bf57d4f54a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate-unit-struct.rs @@ -0,0 +1,31 @@ +// run-pass +// aux-build:xcrate_unit_struct.rs +// pretty-expanded FIXME #23616 +#![allow(non_upper_case_globals)] + +extern crate xcrate_unit_struct; + +const s1: xcrate_unit_struct::Struct = xcrate_unit_struct::Struct; +static s2: xcrate_unit_struct::Unit = xcrate_unit_struct::Unit::UnitVariant; +static s3: xcrate_unit_struct::Unit = + xcrate_unit_struct::Unit::Argument(xcrate_unit_struct::Struct); +static s4: xcrate_unit_struct::Unit = xcrate_unit_struct::Unit::Argument(s1); +static s5: xcrate_unit_struct::TupleStruct = xcrate_unit_struct::TupleStruct(20, "foo"); + +fn f1(_: xcrate_unit_struct::Struct) {} +fn f2(_: xcrate_unit_struct::Unit) {} +fn f3(_: xcrate_unit_struct::TupleStruct) {} + +pub fn main() { + f1(xcrate_unit_struct::Struct); + f2(xcrate_unit_struct::Unit::UnitVariant); + f2(xcrate_unit_struct::Unit::Argument(xcrate_unit_struct::Struct)); + f3(xcrate_unit_struct::TupleStruct(10, "bar")); + + f1(s1); + f2(s2); + f2(s3); + f2(s4); + f3(s5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate_generic_fn_nested_return.rs b/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate_generic_fn_nested_return.rs new file mode 100644 index 000000000000..2a12e295f156 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross-crate/xcrate_generic_fn_nested_return.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:xcrate_generic_fn_nested_return.rs + +extern crate xcrate_generic_fn_nested_return as test; + +pub fn main() { + assert!(test::decode::<()>().is_err()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross/cross-borrow-trait.rs b/gcc/testsuite/rust/rustc/ui/cross/cross-borrow-trait.rs new file mode 100644 index 000000000000..ad1372531a0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross/cross-borrow-trait.rs @@ -0,0 +1,14 @@ +// Test that cross-borrowing (implicitly converting from `Box` to `&T`) is +// forbidden when `T` is a trait. + +struct Foo; +trait Trait { fn foo(&self) {} } +impl Trait for Foo {} + +pub fn main() { + let x: Box = Box::new(Foo); + let _y: &dyn Trait = x; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross/cross-crate-macro-backtrace/auxiliary/extern_macro_crate.rs b/gcc/testsuite/rust/rustc/ui/cross/cross-crate-macro-backtrace/auxiliary/extern_macro_crate.rs new file mode 100644 index 000000000000..8532c5b2d333 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross/cross-crate-macro-backtrace/auxiliary/extern_macro_crate.rs @@ -0,0 +1,14 @@ +#![crate_type = "dylib"] + +pub fn print(_args: std::fmt::Arguments) {} + +#[macro_export] +macro_rules! myprint { + ($($arg:tt)*) => ($crate::print(format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! myprintln { + ($fmt:expr) => (myprint!(concat!($fmt, "\n"))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross/cross-crate-macro-backtrace/main.rs b/gcc/testsuite/rust/rustc/ui/cross/cross-crate-macro-backtrace/main.rs new file mode 100644 index 000000000000..cc6e8a9a3973 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross/cross-crate-macro-backtrace/main.rs @@ -0,0 +1,9 @@ +// aux-build:extern_macro_crate.rs +#[macro_use(myprintln, myprint)] +extern crate extern_macro_crate; + +fn main() { + myprintln!("{}"); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross/cross-file-errors/main.rs b/gcc/testsuite/rust/rustc/ui/cross/cross-file-errors/main.rs new file mode 100644 index 000000000000..20784d01be47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross/cross-file-errors/main.rs @@ -0,0 +1,8 @@ +#[macro_use] +mod underscore; + +fn main() { + underscore!(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross/cross-file-errors/underscore.rs b/gcc/testsuite/rust/rustc/ui/cross/cross-file-errors/underscore.rs new file mode 100644 index 000000000000..0de9195c61a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross/cross-file-errors/underscore.rs @@ -0,0 +1,11 @@ +// We want this file only so we can test cross-file error +// messages, but we don't want it in an external crate. +// ignore-test +#![crate_type = "lib"] + +macro_rules! underscore { + () => ( + _ + ) +} + diff --git a/gcc/testsuite/rust/rustc/ui/cross/cross-fn-cache-hole.rs b/gcc/testsuite/rust/rustc/ui/cross/cross-fn-cache-hole.rs new file mode 100644 index 000000000000..26bfef29d412 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cross/cross-fn-cache-hole.rs @@ -0,0 +1,32 @@ +// Check that when there are vacuous predicates in the environment +// (which make a fn uncallable) we don't erroneously cache those and +// then consider them satisfied elsewhere. The current technique for +// doing this is to not use global caches when there is a chance that +// the environment contains such a predicate. +// We still error for `i32: Bar` pending #48214 + +trait Foo: Bar { +} + +trait Bar { } + +// We don't always check where clauses for sanity, but in this case +// wfcheck does report an error here: +fn vacuous() // { dg-error ".E0277." "" { target *-*-* } } + where i32: Foo +{ + // ... the original intention was to check that we don't use that + // vacuous where clause (which could never be satisfied) to accept + // the following line and then mess up calls elsewhere. + require::(); +} + +fn require() + where A: Bar +{ +} + +fn main() { + require::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/crt-static-off-works.rs b/gcc/testsuite/rust/rustc/ui/crt-static-off-works.rs new file mode 100644 index 000000000000..1524a8bb0157 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/crt-static-off-works.rs @@ -0,0 +1,11 @@ +// run-pass + +#![allow(stable_features)] +// compile-flags:-C target-feature=-crt-static -Z unstable-options +// ignore-musl - requires changing the linker which is hard + +#![feature(cfg_target_feature)] + +#[cfg(not(target_feature = "crt-static"))] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/crt-static-on-works.rs b/gcc/testsuite/rust/rustc/ui/crt-static-on-works.rs new file mode 100644 index 000000000000..95b358f7e401 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/crt-static-on-works.rs @@ -0,0 +1,7 @@ +// run-pass +// compile-flags:-C target-feature=+crt-static +// only-msvc + +#[cfg(target_feature = "crt-static")] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/custom-attribute-multisegment.rs b/gcc/testsuite/rust/rustc/ui/custom-attribute-multisegment.rs new file mode 100644 index 000000000000..7a584d96a287 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/custom-attribute-multisegment.rs @@ -0,0 +1,7 @@ +// Unresolved multi-segment attributes are not treated as custom. + +mod existent {} + +#[existent::nonexistent] // { dg-error ".E0433." "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/custom-test-frameworks-simple.rs b/gcc/testsuite/rust/rustc/ui/custom-test-frameworks-simple.rs new file mode 100644 index 000000000000..b63463f2d5d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/custom-test-frameworks-simple.rs @@ -0,0 +1,23 @@ +// compile-flags: --test +// run-pass + +#![feature(custom_test_frameworks)] +#![test_runner(crate::foo_runner)] + +#[cfg(test)] +fn foo_runner(ts: &[&dyn Fn(usize)->()]) { + for (i, t) in ts.iter().enumerate() { + t(i); + } +} + +#[test_case] +fn test1(i: usize) { + println!("Hi #{}", i); +} + +#[test_case] +fn test2(i: usize) { + println!("Hey #{}", i); +} + diff --git a/gcc/testsuite/rust/rustc/ui/custom_attribute.rs b/gcc/testsuite/rust/rustc/ui/custom_attribute.rs new file mode 100644 index 000000000000..b996f9cbe79a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/custom_attribute.rs @@ -0,0 +1,10 @@ +#![feature(stmt_expr_attributes)] + +#[foo] // { dg-error "" "" { target *-*-* } } +fn main() { + #[foo] // { dg-error "" "" { target *-*-* } } + let x = (); + #[foo] // { dg-error "" "" { target *-*-* } } + x +} + diff --git a/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/auxiliary/dynamic_runner.rs b/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/auxiliary/dynamic_runner.rs new file mode 100644 index 000000000000..171b051fd946 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/auxiliary/dynamic_runner.rs @@ -0,0 +1,36 @@ +use std::process::exit; + +pub trait Testable { + // Name of the test + fn name(&self) -> String; + + // Tests pass by default + fn run(&self) -> bool { + true + } + + // A test can generate subtests + fn subtests(&self) -> Vec> { + vec![] + } +} + +fn run_test(t: &dyn Testable) -> bool { + let success = t.subtests().into_iter().all(|sub_t| run_test(&*sub_t)) && t.run(); + println!("{}...{}", t.name(), if success { "SUCCESS" } else { "FAIL" }); + success +} + +pub fn runner(tests: &[&dyn Testable]) { + let mut failed = false; + for t in tests { + if !run_test(*t) { + failed = true; + } + } + + if failed { + exit(1); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/auxiliary/example_runner.rs b/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/auxiliary/example_runner.rs new file mode 100644 index 000000000000..f65ce5fdbb46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/auxiliary/example_runner.rs @@ -0,0 +1,11 @@ +pub trait Testable { + fn name(&self) -> String; + fn run(&self) -> Option; // None will be success, Some is the error message +} + +pub fn runner(tests: &[&dyn Testable]) { + for t in tests { + print!("{}........{}", t.name(), t.run().unwrap_or_else(|| "SUCCESS".to_string())); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/dynamic.rs b/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/dynamic.rs new file mode 100644 index 000000000000..a40d6b49a14c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/dynamic.rs @@ -0,0 +1,36 @@ +// run-pass +// aux-build:dynamic_runner.rs +// compile-flags:--test +#![feature(custom_test_frameworks)] +#![test_runner(dynamic_runner::runner)] + +extern crate dynamic_runner; + +pub struct AllFoo(&'static str); +struct IsFoo(String); + +impl dynamic_runner::Testable for AllFoo { + fn name(&self) -> String { + String::from(self.0) + } + + fn subtests(&self) -> Vec> { + self.0.split(" ").map(|word| + Box::new(IsFoo(word.into())) as Box + ).collect() + } +} + +impl dynamic_runner::Testable for IsFoo { + fn name(&self) -> String { + self.0.clone() + } + + fn run(&self) -> bool { + self.0 == "foo" + } +} + +#[test_case] +const TEST_2: AllFoo = AllFoo("foo foo"); + diff --git a/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/full.rs b/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/full.rs new file mode 100644 index 000000000000..41337f70c91e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/full.rs @@ -0,0 +1,29 @@ +// run-pass +// aux-build:example_runner.rs +// compile-flags:--test + +#![feature(custom_test_frameworks)] +#![test_runner(example_runner::runner)] +extern crate example_runner; + +pub struct IsFoo(&'static str); + +impl example_runner::Testable for IsFoo { + fn name(&self) -> String { + self.0.to_string() + } + + fn run(&self) -> Option { + if self.0 != "foo" { + return Some(format!("{} != foo", self.0)); + } + None + } +} + +#[test_case] +const TEST_1: IsFoo = IsFoo("hello"); + +#[test_case] +const TEST_2: IsFoo = IsFoo("foo"); + diff --git a/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/mismatch.rs b/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/mismatch.rs new file mode 100644 index 000000000000..eaaf279a06ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/custom_test_frameworks/mismatch.rs @@ -0,0 +1,11 @@ +// aux-build:example_runner.rs +// compile-flags:--test +#![feature(custom_test_frameworks)] +#![test_runner(example_runner::runner)] + +extern crate example_runner; + +#[test] +fn wrong_kind(){} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/cycle-generic-bound.rs b/gcc/testsuite/rust/rustc/ui/cycle-generic-bound.rs new file mode 100644 index 000000000000..62283efb7743 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cycle-generic-bound.rs @@ -0,0 +1,12 @@ +// run-pass +// Regression test for #15477. This test just needs to compile. + +// pretty-expanded FIXME #23616 + +trait Chromosome> { +} + +impl Chromosome for i32 { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/cycle-projection-based-on-where-clause.rs b/gcc/testsuite/rust/rustc/ui/cycle-projection-based-on-where-clause.rs new file mode 100644 index 000000000000..37a04206496b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cycle-projection-based-on-where-clause.rs @@ -0,0 +1,25 @@ +// Example cycle where a bound on `T` uses a shorthand for `T`. This +// creates a cycle because we have to know the bounds on `T` to figure +// out what trait defines `Item`, but we can't know the bounds on `T` +// without knowing how to handle `T::Item`. +// +// Note that in the future cases like this could perhaps become legal, +// if we got more fine-grained about our cycle detection or changed +// how we handle `T::Item` resolution. + +use std::ops::Add; + +// Preamble. +trait Trait { type Item; } + +struct A + where T : Trait, + T : Add +// { dg-error ".E0391." "" { target *-*-* } .-1 } +{ + data: T +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/cycle-trait/cycle-trait-default-type-trait.rs b/gcc/testsuite/rust/rustc/ui/cycle-trait/cycle-trait-default-type-trait.rs new file mode 100644 index 000000000000..c00f1827a48c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cycle-trait/cycle-trait-default-type-trait.rs @@ -0,0 +1,10 @@ +// Test a cycle where a type parameter on a trait has a default that +// again references the trait. + +trait Foo> { +// { dg-error ".E0391." "" { target *-*-* } .-1 } +// { dg-error ".E0391." "" { target *-*-* } .-2 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/cycle-trait/cycle-trait-supertrait-direct.rs b/gcc/testsuite/rust/rustc/ui/cycle-trait/cycle-trait-supertrait-direct.rs new file mode 100644 index 000000000000..891ca25ca7ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cycle-trait/cycle-trait-supertrait-direct.rs @@ -0,0 +1,8 @@ +// Test a supertrait cycle where a trait extends itself. + +trait Chromosome: Chromosome { +// { dg-error ".E0391." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/cycle-trait/cycle-trait-supertrait-indirect.rs b/gcc/testsuite/rust/rustc/ui/cycle-trait/cycle-trait-supertrait-indirect.rs new file mode 100644 index 000000000000..f8e0e26133f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/cycle-trait/cycle-trait-supertrait-indirect.rs @@ -0,0 +1,14 @@ +// Test a supertrait cycle where the first trait we find (`A`) is not +// a direct participant in the cycle. + +trait A: B { +} + +trait B: C { +// { dg-error ".E0391." "" { target *-*-* } .-1 } +} + +trait C: B { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/debuginfo-lto.rs b/gcc/testsuite/rust/rustc/ui/debuginfo-lto.rs new file mode 100644 index 000000000000..4e6e2b8416df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/debuginfo-lto.rs @@ -0,0 +1,26 @@ +// run-pass +// This test case makes sure that we don't run into LLVM's dreaded +// "possible ODR violation" assertion when compiling with LTO + Debuginfo. +// It covers cases that have traditionally been prone to cause this error. +// If new cases emerge, add them to this file. + +// aux-build:debuginfo-lto-aux.rs +// compile-flags: -C lto -g +// no-prefer-dynamic +// ignore-asmjs wasm2js does not support source maps yet + +extern crate debuginfo_lto_aux; + +fn some_fn(x: i32) -> i32 { + x + 1 +} + +fn main() { + let i = 0; + let _ = debuginfo_lto_aux::mk_struct_with_lt(&i); + let _ = debuginfo_lto_aux::mk_regular_struct(1); + let _ = debuginfo_lto_aux::take_fn(some_fn, 1); + let _ = debuginfo_lto_aux::with_closure(22); + let _ = debuginfo_lto_aux::generic_fn(0f32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deduplicate-diagnostics-2.rs b/gcc/testsuite/rust/rustc/ui/deduplicate-diagnostics-2.rs new file mode 100644 index 000000000000..ccc944ca312e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deduplicate-diagnostics-2.rs @@ -0,0 +1,18 @@ +// build-pass +// revisions: duplicate deduplicate +//[deduplicate] compile-flags: -Z deduplicate-diagnostics=yes + +fn main() { + match 0.0 { + 1.0 => {} // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + 2.0 => {} // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/deduplicate-diagnostics.rs b/gcc/testsuite/rust/rustc/ui/deduplicate-diagnostics.rs new file mode 100644 index 000000000000..486740b5cadc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deduplicate-diagnostics.rs @@ -0,0 +1,12 @@ +// revisions: duplicate deduplicate +//[deduplicate] compile-flags: -Z deduplicate-diagnostics=yes + +#[derive(Unresolved)] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +struct S; + +#[deny("literal")] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deep.rs b/gcc/testsuite/rust/rustc/ui/deep.rs new file mode 100644 index 000000000000..961abbf19485 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deep.rs @@ -0,0 +1,9 @@ +// run-pass +// ignore-emscripten apparently blows the stack + +fn f(x: isize) -> isize { + if x == 1 { return 1; } else { let y: isize = 1 + f(x - 1); return y; } +} + +pub fn main() { assert_eq!(f(5000), 5000); } + diff --git a/gcc/testsuite/rust/rustc/ui/default-alloc-error-hook.rs b/gcc/testsuite/rust/rustc/ui/default-alloc-error-hook.rs new file mode 100644 index 000000000000..23451923c272 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/default-alloc-error-hook.rs @@ -0,0 +1,21 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::alloc::{Layout, handle_alloc_error}; +use std::env; +use std::process::Command; +use std::str; + +fn main() { + if env::args().len() > 1 { + handle_alloc_error(Layout::new::<[u8; 42]>()) + } + + let me = env::current_exe().unwrap(); + let output = Command::new(&me).arg("next").output().unwrap(); + assert!(!output.status.success(), "{:?} is a success", output.status); + assert_eq!(str::from_utf8(&output.stderr).unwrap(), "memory allocation of 42 bytes failed\n"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/default-associated-types.rs b/gcc/testsuite/rust/rustc/ui/default-associated-types.rs new file mode 100644 index 000000000000..ce99d6891857 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/default-associated-types.rs @@ -0,0 +1,24 @@ +// 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/gcc/testsuite/rust/rustc/ui/default-method-parsing.rs b/gcc/testsuite/rust/rustc/ui/default-method-parsing.rs new file mode 100644 index 000000000000..04f6da1dd772 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/default-method-parsing.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Foo { + fn m(&self, _:isize) { } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/default-method-simple.rs b/gcc/testsuite/rust/rustc/ui/default-method-simple.rs new file mode 100644 index 000000000000..ef5684e85f5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/default-method-simple.rs @@ -0,0 +1,27 @@ +// run-pass + +#![allow(dead_code)] + +trait Foo { + fn f(&self) { + println!("Hello!"); + self.g(); + } + fn g(&self); +} + +struct A { + x: isize +} + +impl Foo for A { + fn g(&self) { + println!("Goodbye!"); + } +} + +pub fn main() { + let a = A { x: 1 }; + a.f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/defaults-well-formedness.rs b/gcc/testsuite/rust/rustc/ui/defaults-well-formedness.rs new file mode 100644 index 000000000000..9940516faa83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/defaults-well-formedness.rs @@ -0,0 +1,28 @@ +// run-pass + +#![allow(dead_code)] +trait Trait {} +struct Foo(U, V) where U: Trait; + +trait Marker {} +struct TwoParams(T, U); +impl Marker for TwoParams {} + +// Clauses with more than 1 param are not checked. +struct IndividuallyBogus(TwoParams) where TwoParams: Marker; +struct BogusTogether(T, U) where TwoParams: Marker; +// Clauses with non-defaulted params are not checked. +struct NonDefaultedInClause(TwoParams) where TwoParams: Marker; +struct DefaultedLhs(U, V) where V: Trait; +// Dependent defaults are not checked. +struct Dependent(T, U) where U: Copy; +trait SelfBound {} +// Not even for well-formedness. +struct WellFormedProjection::Item>(A, T); + +// Issue #49344, predicates with lifetimes should not be checked. +trait Scope<'a> {} +struct Request<'a, S: Scope<'a> = i32>(S, &'a ()); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/definition-reachable/auxiliary/field-method-macro.rs b/gcc/testsuite/rust/rustc/ui/definition-reachable/auxiliary/field-method-macro.rs new file mode 100644 index 000000000000..4a0d4e27e89d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/definition-reachable/auxiliary/field-method-macro.rs @@ -0,0 +1,24 @@ +#![feature(decl_macro)] + +mod n { + pub struct B(pub(crate) p::C); + impl B { + pub fn new() -> Self { + B(p::C) + } + } + mod p { + pub struct C; + + impl C { + pub fn foo(&self) -> i32 { + 33 + } + } + } +} + +pub macro m() { + n::B::new().0.foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/definition-reachable/auxiliary/nested-fn-macro.rs b/gcc/testsuite/rust/rustc/ui/definition-reachable/auxiliary/nested-fn-macro.rs new file mode 100644 index 000000000000..3842242df0ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/definition-reachable/auxiliary/nested-fn-macro.rs @@ -0,0 +1,12 @@ +#![feature(decl_macro)] + +mod n { + pub(crate) mod p { + pub fn f() -> i32 { 12 } + } +} + +pub macro m() { + n::p::f() +} + diff --git a/gcc/testsuite/rust/rustc/ui/definition-reachable/auxiliary/private-use-macro.rs b/gcc/testsuite/rust/rustc/ui/definition-reachable/auxiliary/private-use-macro.rs new file mode 100644 index 000000000000..502a57fab3b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/definition-reachable/auxiliary/private-use-macro.rs @@ -0,0 +1,12 @@ +#![feature(decl_macro)] + +mod n { + pub static S: i32 = 57; +} + +use n::S; + +pub macro m() { + S +} + diff --git a/gcc/testsuite/rust/rustc/ui/definition-reachable/field-method.rs b/gcc/testsuite/rust/rustc/ui/definition-reachable/field-method.rs new file mode 100644 index 000000000000..6c1a52b62240 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/definition-reachable/field-method.rs @@ -0,0 +1,12 @@ +// Check that functions accessible through a field visible to a macro are +// considered reachable + +// aux-build:nested-fn-macro.rs +// run-pass + +extern crate nested_fn_macro; + +fn main() { + assert_eq!(nested_fn_macro::m!(), 12); +} + diff --git a/gcc/testsuite/rust/rustc/ui/definition-reachable/nested-fn.rs b/gcc/testsuite/rust/rustc/ui/definition-reachable/nested-fn.rs new file mode 100644 index 000000000000..afbd095cfd25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/definition-reachable/nested-fn.rs @@ -0,0 +1,12 @@ +// Check that functions visible to macros through paths with >2 segments are +// considered reachable + +// aux-build:field-method-macro.rs +// run-pass + +extern crate field_method_macro; + +fn main() { + assert_eq!(field_method_macro::m!(), 33); +} + diff --git a/gcc/testsuite/rust/rustc/ui/definition-reachable/private-non-types.rs b/gcc/testsuite/rust/rustc/ui/definition-reachable/private-non-types.rs new file mode 100644 index 000000000000..15324306f683 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/definition-reachable/private-non-types.rs @@ -0,0 +1,22 @@ +// Check that we don't require stability annotations for private modules, +// imports and fields that are accessible to opaque macros. + +// check-pass + +#![feature(decl_macro, staged_api)] +#![stable(feature = "test", since = "1.0.0")] + +extern crate std as local_std; +use local_std::marker::Copy as LocalCopy; +mod private_mod { + #[stable(feature = "test", since = "1.0.0")] + pub struct A { + pub(crate) f: i32, + } +} + +#[stable(feature = "test", since = "1.0.0")] +pub macro m() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/definition-reachable/private-types.rs b/gcc/testsuite/rust/rustc/ui/definition-reachable/private-types.rs new file mode 100644 index 000000000000..a799e0096da4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/definition-reachable/private-types.rs @@ -0,0 +1,20 @@ +// Check that type privacy is taken into account when considering reachability + +// check-pass + +#![feature(decl_macro, staged_api)] +#![stable(feature = "test", since = "1.0.0")] + +// Type privacy should prevent use of these in other crates, so we shouldn't +// need a stability annotation. +fn private_function() {} +struct PrivateStruct { f: () } +enum PrivateEnum { V } +union PrivateUnion { g: () } +trait PrivateTrait {} + +#[stable(feature = "test", since = "1.0.0")] +pub macro m() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/definition-reachable/private-use.rs b/gcc/testsuite/rust/rustc/ui/definition-reachable/private-use.rs new file mode 100644 index 000000000000..01fd30ec36e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/definition-reachable/private-use.rs @@ -0,0 +1,11 @@ +// Check that private use statements can be used by + +// run-pass +// aux-build:private-use-macro.rs + +extern crate private_use_macro; + +fn main() { + assert_eq!(private_use_macro::m!(), 57); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-assoc-type-codegen.rs b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-assoc-type-codegen.rs new file mode 100644 index 000000000000..7ae8f07ae6b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-assoc-type-codegen.rs @@ -0,0 +1,38 @@ +// Test that when a trait impl changes, fns whose body uses that trait +// must also be recompiled. + +// compile-flags: -Z query-dep-graph + +#![feature(rustc_attrs)] +#![allow(warnings)] + +fn main() { } + +pub trait Foo: Sized { + type T; + fn method(self) { } +} + +mod x { + use Foo; + + #[rustc_if_this_changed] + impl Foo for char { type T = char; } + + impl Foo for u32 { type T = u32; } +} + +mod y { + use Foo; + + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + pub fn use_char_assoc() { + // Careful here: in the representation, ::T gets + // normalized away, so at a certain point we had no edge to + // codegen. (But now codegen just depends on typeck.) + let x: ::T = 'a'; + } + + pub fn take_foo(t: T) { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-caller-callee.rs b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-caller-callee.rs new file mode 100644 index 000000000000..60f93cb22006 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-caller-callee.rs @@ -0,0 +1,36 @@ +// Test that immediate callers have to change when callee changes, but +// not callers' callers. + +// compile-flags: -Z query-dep-graph + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +fn main() { } + +mod x { + #[rustc_if_this_changed] + pub fn x() { } +} + +mod y { + use x; + + // These dependencies SHOULD exist: + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + pub fn y() { + x::x(); + } +} + +mod z { + use y; + + // These are expected to yield errors, because changes to `x` + // affect the BODY of `y`, but not its signature. + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + pub fn z() { + y::y(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-struct-signature.rs b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-struct-signature.rs new file mode 100644 index 000000000000..7a1906fb548c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-struct-signature.rs @@ -0,0 +1,87 @@ +// Test cases where a changing struct appears in the signature of fns +// and methods. + +// compile-flags: -Z query-dep-graph + +#![feature(rustc_attrs)] +#![allow(dead_code)] +#![allow(unused_variables)] + +fn main() { } + +#[rustc_if_this_changed] +struct WillChange { + x: u32, + y: u32 +} + +struct WontChange { + x: u32, + y: u32 +} + +// these are valid dependencies +mod signatures { + use WillChange; + + #[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } + #[rustc_then_this_would_need(associated_item)] // { dg-error "" "" { target *-*-* } } + #[rustc_then_this_would_need(trait_def)] // { dg-error "" "" { target *-*-* } } + trait Bar { + #[rustc_then_this_would_need(fn_sig)] // { dg-error "" "" { target *-*-* } } + fn do_something(x: WillChange); + } + + #[rustc_then_this_would_need(fn_sig)] // { dg-error "" "" { target *-*-* } } + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + fn some_fn(x: WillChange) { } + + #[rustc_then_this_would_need(fn_sig)] // { dg-error "" "" { target *-*-* } } + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + fn new_foo(x: u32, y: u32) -> WillChange { + WillChange { x: x, y: y } + } + + #[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } + impl WillChange { + #[rustc_then_this_would_need(fn_sig)] // { dg-error "" "" { target *-*-* } } + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + fn new(x: u32, y: u32) -> WillChange { loop { } } + } + + #[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } + impl WillChange { + #[rustc_then_this_would_need(fn_sig)] // { dg-error "" "" { target *-*-* } } + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + fn method(&self, x: u32) { } + } + + struct WillChanges { + #[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } + x: WillChange, + #[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } + y: WillChange + } + + // The fields change, not the type itself. + #[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } + fn indirect(x: WillChanges) { } +} + +mod invalid_signatures { + use WontChange; + + #[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } + trait A { + #[rustc_then_this_would_need(fn_sig)] // { dg-error "" "" { target *-*-* } } + fn do_something_else_twice(x: WontChange); + } + + #[rustc_then_this_would_need(fn_sig)] // { dg-error "" "" { target *-*-* } } + fn b(x: WontChange) { } + + #[rustc_then_this_would_need(fn_sig)] // { dg-error "" "" { target *-*-* } } + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + fn c(x: u32) { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs new file mode 100644 index 000000000000..d4d7c7ca9fa3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.rs @@ -0,0 +1,46 @@ +// Test that adding an impl to a trait `Foo` DOES affect functions +// that only use `Bar` if they have methods in common. + +// compile-flags: -Z query-dep-graph + +#![feature(rustc_attrs)] +#![allow(dead_code)] +#![allow(unused_imports)] + +fn main() { } + +pub trait Foo: Sized { + fn method(self) { } +} + +pub trait Bar: Sized { + fn method(self) { } +} + +mod x { + use {Foo, Bar}; + + #[rustc_if_this_changed] + impl Foo for u32 { } + + impl Bar for char { } +} + +mod y { + use {Foo, Bar}; + + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + pub fn with_char() { + char::method('a'); + } +} + +mod z { + use y; + + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + pub fn z() { + y::with_char(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-trait-impl-two-traits.rs b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-trait-impl-two-traits.rs new file mode 100644 index 000000000000..9c4acd4982ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-trait-impl-two-traits.rs @@ -0,0 +1,45 @@ +// Test that adding an impl to a trait `Foo` does not affect functions +// that only use `Bar`, so long as they do not have methods in common. + +// compile-flags: -Z query-dep-graph + +#![feature(rustc_attrs)] +#![allow(warnings)] + +fn main() { } + +pub trait Foo: Sized { + fn foo(self) { } +} + +pub trait Bar: Sized { + fn bar(self) { } +} + +mod x { + use {Foo, Bar}; + + #[rustc_if_this_changed] + impl Foo for char { } + + impl Bar for char { } +} + +mod y { + use {Foo, Bar}; + + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + pub fn call_bar() { + char::bar('a'); + } +} + +mod z { + use y; + + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + pub fn z() { + y::call_bar(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-trait-impl.rs b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-trait-impl.rs new file mode 100644 index 000000000000..4172374eca93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-trait-impl.rs @@ -0,0 +1,61 @@ +// Test that when a trait impl changes, fns whose body uses that trait +// must also be recompiled. + +// compile-flags: -Z query-dep-graph + +#![feature(rustc_attrs)] +#![allow(warnings)] + +fn main() { } + +pub trait Foo: Sized { + fn method(self) { } +} + +mod x { + use Foo; + + #[rustc_if_this_changed] + impl Foo for char { } + + impl Foo for u32 { } +} + +mod y { + use Foo; + + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + pub fn with_char() { + char::method('a'); + } + + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + pub fn take_foo_with_char() { + take_foo::('a'); + } + + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + pub fn with_u32() { + u32::method(22); + } + + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + pub fn take_foo_with_u32() { + take_foo::(22); + } + + pub fn take_foo(t: T) { } +} + +mod z { + use y; + + // These are expected to yield errors, because changes to `x` + // affect the BODY of `y`, but not its signature. + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + pub fn z() { + y::with_char(); + y::with_u32(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-type-alias.rs b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-type-alias.rs new file mode 100644 index 000000000000..ef900afd002c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-type-alias.rs @@ -0,0 +1,56 @@ +// Test that changing what a `type` points to does not go unnoticed. + +// compile-flags: -Z query-dep-graph + +#![feature(rustc_attrs)] +#![allow(dead_code)] +#![allow(unused_variables)] + +fn main() { } + + +#[rustc_if_this_changed] +type TypeAlias = u32; + +// The type alias directly affects the type of the field, +// not the enclosing struct: +#[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } +struct Struct { + #[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } + x: TypeAlias, + y: u32 +} + +#[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } +enum Enum { + Variant1 { + #[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } + t: TypeAlias + }, + Variant2(i32) +} + +#[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } +trait Trait { + #[rustc_then_this_would_need(fn_sig)] // { dg-error "" "" { target *-*-* } } + fn method(&self, _: TypeAlias); +} + +struct SomeType; + +#[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } +impl SomeType { + #[rustc_then_this_would_need(fn_sig)] // { dg-error "" "" { target *-*-* } } + #[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } + fn method(&self, _: TypeAlias) {} +} + +#[rustc_then_this_would_need(type_of)] // { dg-error "" "" { target *-*-* } } +type TypeAlias2 = TypeAlias; + +#[rustc_then_this_would_need(fn_sig)] // { dg-error "" "" { target *-*-* } } +#[rustc_then_this_would_need(typeck)] // { dg-error "" "" { target *-*-* } } +fn function(_: TypeAlias) { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-variance-alias.rs b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-variance-alias.rs new file mode 100644 index 000000000000..a2b13dfd894c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dep-graph/dep-graph-variance-alias.rs @@ -0,0 +1,22 @@ +// Test that changing what a `type` points to does not go unnoticed +// by the variance analysis. + +// compile-flags: -Z query-dep-graph + +#![feature(rustc_attrs)] +#![allow(dead_code)] +#![allow(unused_variables)] +#![rustc_if_this_changed(hir_crate)] +fn main() {} + +struct Foo { + f: T, +} + +type TypeAlias = Foo; + +#[rustc_then_this_would_need(variances_of)] // { dg-error "" "" { target *-*-* } } +struct Use { + x: TypeAlias, +} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation-in-force-unstable.rs b/gcc/testsuite/rust/rustc/ui/deprecation-in-force-unstable.rs new file mode 100644 index 000000000000..43b2d61d15be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation-in-force-unstable.rs @@ -0,0 +1,6 @@ +// run-pass +// compile-flags:-Zforce-unstable-if-unmarked + +#[deprecated] // should work even with -Zforce-unstable-if-unmarked +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/atomic_initializers.rs b/gcc/testsuite/rust/rustc/ui/deprecation/atomic_initializers.rs new file mode 100644 index 000000000000..190eb8b8707a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/atomic_initializers.rs @@ -0,0 +1,12 @@ +// run-rustfix +// check-pass + +#[allow(deprecated, unused_imports)] +use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT}; + +#[allow(dead_code)] +static FOO: AtomicIsize = ATOMIC_ISIZE_INIT; +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/auxiliary/deprecation-lint.rs b/gcc/testsuite/rust/rustc/ui/deprecation/auxiliary/deprecation-lint.rs new file mode 100644 index 000000000000..83b03f90158c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/auxiliary/deprecation-lint.rs @@ -0,0 +1,99 @@ +#![feature(deprecated)] + +#[deprecated(since = "1.0.0", note = "text")] +pub fn deprecated() {} +#[deprecated(since = "1.0.0", note = "text")] +pub fn deprecated_text() {} + +pub struct MethodTester; + +impl MethodTester { + #[deprecated(since = "1.0.0", note = "text")] + pub fn method_deprecated(&self) {} + #[deprecated(since = "1.0.0", note = "text")] + pub fn method_deprecated_text(&self) {} +} + +pub trait Trait { + #[deprecated(since = "1.0.0", note = "text")] + fn trait_deprecated(&self) {} + #[deprecated(since = "1.0.0", note = "text")] + fn trait_deprecated_text(&self) {} +} + +#[deprecated(since = "1.0.0", note = "text")] +pub trait DeprecatedTrait { fn dummy(&self) { } } + +impl Trait for MethodTester {} + +#[deprecated(since = "1.0.0", note = "text")] +pub struct DeprecatedStruct { + pub i: isize +} + +#[deprecated(since = "1.0.0", note = "text")] +pub struct DeprecatedUnitStruct; + +pub enum Enum { + #[deprecated(since = "1.0.0", note = "text")] + DeprecatedVariant, +} + +#[deprecated(since = "1.0.0", note = "text")] +pub struct DeprecatedTupleStruct(pub isize); + +pub mod nested { + #[deprecated(since = "1.0.0", note = "text")] + pub struct DeprecatedStruct { + pub i: isize + } + + #[deprecated(since = "1.0.0", note = "text")] + pub struct DeprecatedUnitStruct; + + pub enum Enum { + #[deprecated(since = "1.0.0", note = "text")] + DeprecatedVariant, + } + + #[deprecated(since = "1.0.0", note = "text")] + pub struct DeprecatedTupleStruct(pub isize); +} + +pub struct Stable { + #[deprecated(since = "1.0.0", note = "text")] + pub override2: u8, +} + +pub struct Stable2(pub u8, pub u8, #[deprecated(since = "1.0.0", note = "text")] pub u8); + +#[deprecated(since = "1.0.0", note = "text")] +pub struct Deprecated { + pub inherit: u8, +} + +#[deprecated(since = "1.0.0", note = "text")] +pub struct Deprecated2(pub u8, + pub u8, + pub u8); + +#[deprecated(since = "1.0.0", note = "text")] +pub mod deprecated_mod { + pub fn deprecated() {} +} + +#[macro_export] +macro_rules! macro_test { + () => (deprecated()); +} + +#[macro_export] +macro_rules! macro_test_arg { + ($func:expr) => ($func); +} + +#[macro_export] +macro_rules! macro_test_arg_nested { + ($func:ident) => (macro_test_arg!($func())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/deprecated-macro_escape-inner.rs b/gcc/testsuite/rust/rustc/ui/deprecation/deprecated-macro_escape-inner.rs new file mode 100644 index 000000000000..c2afccc3410e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/deprecated-macro_escape-inner.rs @@ -0,0 +1,9 @@ +// run-pass + +mod foo { + #![macro_escape] // { dg-warning "" "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/deprecated-macro_escape.rs b/gcc/testsuite/rust/rustc/ui/deprecation/deprecated-macro_escape.rs new file mode 100644 index 000000000000..28c411f823e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/deprecated-macro_escape.rs @@ -0,0 +1,7 @@ +// run-pass + +#[macro_escape] // { dg-warning "" "" { target *-*-* } } +mod foo {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/deprecated_no_stack_check.rs b/gcc/testsuite/rust/rustc/ui/deprecation/deprecated_no_stack_check.rs new file mode 100644 index 000000000000..d69535a636c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/deprecated_no_stack_check.rs @@ -0,0 +1,7 @@ +#![deny(warnings)] +#![feature(no_stack_check)] +// { dg-error ".E0557." "" { target *-*-* } .-1 } +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-in-future.rs b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-in-future.rs new file mode 100644 index 000000000000..6baf03461f7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-in-future.rs @@ -0,0 +1,14 @@ +// check-pass + +#![deny(deprecated_in_future)] + +#[deprecated(since = "99.99.99", note = "text")] +pub fn deprecated_future() {} + +fn test() { + deprecated_future(); // ok; deprecated_in_future only applies to rustc_deprecated +// { dg-warning "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-in-staged-api.rs b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-in-staged-api.rs new file mode 100644 index 000000000000..dd51eada668d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-in-staged-api.rs @@ -0,0 +1,9 @@ +// #[deprecated] cannot be used in staged API + +#![feature(staged_api)] + +#![stable(feature = "stable_test_feature", since = "1.0.0")] + +#[deprecated] +fn main() { } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint-2.rs b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint-2.rs new file mode 100644 index 000000000000..3c7b8c29d04d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint-2.rs @@ -0,0 +1,14 @@ +// aux-build:deprecation-lint.rs +// error-pattern: use of deprecated function + +#![deny(deprecated)] + +#[macro_use] +extern crate deprecation_lint; + +use deprecation_lint::*; + +fn main() { + macro_test!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint-3.rs b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint-3.rs new file mode 100644 index 000000000000..cb0061ff9bf8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint-3.rs @@ -0,0 +1,15 @@ +// aux-build:deprecation-lint.rs +// error-pattern: use of deprecated function + +#![deny(deprecated)] +#![allow(warnings)] + +#[macro_use] +extern crate deprecation_lint; + +use deprecation_lint::*; + +fn main() { + macro_test_arg_nested!(deprecated_text); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint-nested.rs b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint-nested.rs new file mode 100644 index 000000000000..98ec3a9eb5c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint-nested.rs @@ -0,0 +1,72 @@ +#![deny(deprecated)] +#![allow(warnings)] + +#[deprecated] +fn issue_35128() { + format_args!("foo"); +} + +#[deprecated] +fn issue_35128_minimal() { + static FOO: &'static str = "foo"; + let _ = FOO; +} + +#[deprecated] +mod silent { + type DeprecatedType = u8; + struct DeprecatedStruct; + fn deprecated_fn() {} + trait DeprecatedTrait {} + static DEPRECATED_STATIC: u8 = 0; + const DEPRECATED_CONST: u8 = 1; + + struct Foo(DeprecatedType); + + impl DeprecatedTrait for Foo {} + + impl Foo { + fn bar() { + deprecated_fn(); + } + } + + fn foo() -> u8 { + DEPRECATED_STATIC + + DEPRECATED_CONST + } +} + +#[deprecated] +mod loud { + #[deprecated] + type DeprecatedType = u8; + #[deprecated] + struct DeprecatedStruct; + #[deprecated] + fn deprecated_fn() {} + #[deprecated] + trait DeprecatedTrait {} + #[deprecated] + static DEPRECATED_STATIC: u8 = 0; + #[deprecated] + const DEPRECATED_CONST: u8 = 1; + + struct Foo(DeprecatedType); // { dg-error "" "" { target *-*-* } } + + impl DeprecatedTrait for Foo {} // { dg-error "" "" { target *-*-* } } + + impl Foo { + fn bar() { // { dg-error "" "" { target *-*-* } } + deprecated_fn(); // { dg-error "" "" { target *-*-* } } + } + } + + fn foo() -> u8 { + DEPRECATED_STATIC + // { dg-error "" "" { target *-*-* } } + DEPRECATED_CONST // { dg-error "" "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint.rs b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint.rs new file mode 100644 index 000000000000..41cd0280a0d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-lint.rs @@ -0,0 +1,437 @@ +// aux-build:deprecation-lint.rs +// ignore-tidy-linelength + +#![deny(deprecated)] +#![allow(warnings)] + +#[macro_use] +extern crate deprecation_lint; + +mod cross_crate { + use deprecation_lint::*; + + fn test() { + type Foo = MethodTester; + let foo = MethodTester; + + deprecated(); // { dg-error "" "" { target *-*-* } } + foo.method_deprecated(); // { dg-error "" "" { target *-*-* } } + Foo::method_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + ::method_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + foo.trait_deprecated(); // { dg-error "" "" { target *-*-* } } + Trait::trait_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + + deprecated_text(); // { dg-error "" "" { target *-*-* } } + foo.method_deprecated_text(); // { dg-error "" "" { target *-*-* } } + Foo::method_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + ::method_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + foo.trait_deprecated_text(); // { dg-error "" "" { target *-*-* } } + Trait::trait_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + + let _ = DeprecatedStruct { // { dg-error "" "" { target *-*-* } } + i: 0 // { dg-error "" "" { target *-*-* } } + }; + + let _ = DeprecatedUnitStruct; // { dg-error "" "" { target *-*-* } } + + let _ = Enum::DeprecatedVariant; // { dg-error "" "" { target *-*-* } } + + let _ = DeprecatedTupleStruct (1); // { dg-error "" "" { target *-*-* } } + + let _ = nested::DeprecatedStruct { // { dg-error "" "" { target *-*-* } } + i: 0 // { dg-error "" "" { target *-*-* } } + }; + + let _ = nested::DeprecatedUnitStruct; // { dg-error "" "" { target *-*-* } } + + let _ = nested::Enum::DeprecatedVariant; // { dg-error "" "" { target *-*-* } } + + let _ = nested::DeprecatedTupleStruct (1); // { dg-error "" "" { target *-*-* } } + + // At the moment, the lint checker only checks stability in + // in the arguments of macros. + // Eventually, we will want to lint the contents of the + // macro in the module *defining* it. Also, stability levels + // on macros themselves are not yet linted. + macro_test_arg!(deprecated_text()); // { dg-error "" "" { target *-*-* } } + macro_test_arg!(macro_test_arg!(deprecated_text())); // { dg-error "" "" { target *-*-* } } + } + + fn test_method_param(foo: Foo) { + foo.trait_deprecated(); // { dg-error "" "" { target *-*-* } } + Trait::trait_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + foo.trait_deprecated_text(); // { dg-error "" "" { target *-*-* } } + Trait::trait_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + } + + fn test_method_object(foo: &Trait) { + foo.trait_deprecated(); // { dg-error "" "" { target *-*-* } } + foo.trait_deprecated_text(); // { dg-error "" "" { target *-*-* } } + } + + struct S; + + impl DeprecatedTrait for S {} // { dg-error "" "" { target *-*-* } } + trait LocalTrait : DeprecatedTrait { } // { dg-error "" "" { target *-*-* } } + + pub fn foo() { + let x = Stable { + override2: 3, +// { dg-error "" "" { target *-*-* } .-1 } + }; + + let _ = x.override2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Stable { + override2: _ +// { dg-error "" "" { target *-*-* } .-1 } + } = x; + // all fine + let Stable { .. } = x; + + let x = Stable2(1, 2, 3); + + let _ = x.2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Stable2(_, + _, + _) +// { dg-error "" "" { target *-*-* } .-1 } + = x; + // all fine + let Stable2(..) = x; + + let x = Deprecated { +// { dg-error "" "" { target *-*-* } .-1 } + inherit: 1, +// { dg-error "" "" { target *-*-* } .-1 } + }; + + let _ = x.inherit; +// { dg-error "" "" { target *-*-* } .-1 } + + let Deprecated { +// { dg-error "" "" { target *-*-* } .-1 } + inherit: _, +// { dg-error "" "" { target *-*-* } .-1 } + } = x; + + let Deprecated +// { dg-error "" "" { target *-*-* } .-1 } + { .. } = x; + + let x = Deprecated2(1, 2, 3); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = x.0; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = x.1; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = x.2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Deprecated2 +// { dg-error "" "" { target *-*-* } .-1 } + (_, +// { dg-error "" "" { target *-*-* } .-1 } + _, +// { dg-error "" "" { target *-*-* } .-1 } + _) +// { dg-error "" "" { target *-*-* } .-1 } + = x; + let Deprecated2 +// { dg-error "" "" { target *-*-* } .-1 } + // the patterns are all fine: + (..) = x; + } +} + +mod inheritance { + use deprecation_lint::*; + + fn test_inheritance() { + deprecated_mod::deprecated(); // { dg-error "" "" { target *-*-* } } + } +} + +mod this_crate { + #[deprecated(since = "1.0.0", note = "text")] + pub fn deprecated() {} + #[deprecated(since = "1.0.0", note = "text")] + pub fn deprecated_text() {} + + #[deprecated(since = "99.99.99", note = "text")] + pub fn deprecated_future() {} + #[deprecated(since = "99.99.99", note = "text")] + pub fn deprecated_future_text() {} + + pub struct MethodTester; + + impl MethodTester { + #[deprecated(since = "1.0.0", note = "text")] + pub fn method_deprecated(&self) {} + #[deprecated(since = "1.0.0", note = "text")] + pub fn method_deprecated_text(&self) {} + } + + pub trait Trait { + #[deprecated(since = "1.0.0", note = "text")] + fn trait_deprecated(&self) {} + #[deprecated(since = "1.0.0", note = "text")] + fn trait_deprecated_text(&self) {} + } + + impl Trait for MethodTester {} + + #[deprecated(since = "1.0.0", note = "text")] + pub struct DeprecatedStruct { + i: isize + } + pub struct UnstableStruct { + i: isize + } + pub struct StableStruct { + i: isize + } + + #[deprecated(since = "1.0.0", note = "text")] + pub struct DeprecatedUnitStruct; + + pub enum Enum { + #[deprecated(since = "1.0.0", note = "text")] + DeprecatedVariant, + } + + #[deprecated(since = "1.0.0", note = "text")] + pub struct DeprecatedTupleStruct(isize); + + mod nested { + #[deprecated(since = "1.0.0", note = "text")] + pub struct DeprecatedStruct { + i: isize + } + + #[deprecated(since = "1.0.0", note = "text")] + pub struct DeprecatedUnitStruct; + + pub enum Enum { + #[deprecated(since = "1.0.0", note = "text")] + DeprecatedVariant, + } + + #[deprecated(since = "1.0.0", note = "text")] + pub struct DeprecatedTupleStruct(pub isize); + } + + fn test() { + use self::nested; + + // Only the deprecated cases of the following should generate + // errors, because other stability attributes now have meaning + // only *across* crates, not within a single crate. + + type Foo = MethodTester; + let foo = MethodTester; + + deprecated(); // { dg-error "" "" { target *-*-* } } + foo.method_deprecated(); // { dg-error "" "" { target *-*-* } } + Foo::method_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + ::method_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + foo.trait_deprecated(); // { dg-error "" "" { target *-*-* } } + Trait::trait_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + + deprecated_text(); // { dg-error "" "" { target *-*-* } } + foo.method_deprecated_text(); // { dg-error "" "" { target *-*-* } } + Foo::method_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + ::method_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + foo.trait_deprecated_text(); // { dg-error "" "" { target *-*-* } } + Trait::trait_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + + // Future deprecations are only permitted for rustc_deprecated. + deprecated_future(); // { dg-error "" "" { target *-*-* } } + deprecated_future_text(); // { dg-error "" "" { target *-*-* } } + + let _ = DeprecatedStruct { +// { dg-error "" "" { target *-*-* } .-1 } + i: 0 // { dg-error "" "" { target *-*-* } } + }; + + let _ = DeprecatedUnitStruct; // { dg-error "" "" { target *-*-* } } + + let _ = Enum::DeprecatedVariant; // { dg-error "" "" { target *-*-* } } + + let _ = DeprecatedTupleStruct (1); // { dg-error "" "" { target *-*-* } } + + let _ = nested::DeprecatedStruct { +// { dg-error "" "" { target *-*-* } .-1 } + i: 0 // { dg-error "" "" { target *-*-* } } + }; + + let _ = nested::DeprecatedUnitStruct; // { dg-error "" "" { target *-*-* } } + + let _ = nested::Enum::DeprecatedVariant; // { dg-error "" "" { target *-*-* } } + + let _ = nested::DeprecatedTupleStruct (1); // { dg-error "" "" { target *-*-* } } + } + + fn test_method_param(foo: Foo) { + foo.trait_deprecated(); // { dg-error "" "" { target *-*-* } } + Trait::trait_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-error "" "" { target *-*-* } } + foo.trait_deprecated_text(); // { dg-error "" "" { target *-*-* } } + Trait::trait_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-error "" "" { target *-*-* } } + } + + fn test_method_object(foo: &Trait) { + foo.trait_deprecated(); // { dg-error "" "" { target *-*-* } } + foo.trait_deprecated_text(); // { dg-error "" "" { target *-*-* } } + } + + #[deprecated(since = "1.0.0", note = "text")] + fn test_fn_body() { + fn fn_in_body() {} + fn_in_body(); + } + + fn test_fn_closure_body() { + let _ = || { + #[deprecated] + fn bar() { } + bar(); // { dg-error "" "" { target *-*-* } } + }; + } + + impl MethodTester { + #[deprecated(since = "1.0.0", note = "text")] + fn test_method_body(&self) { + fn fn_in_body() {} + fn_in_body(); + } + } + + #[deprecated(since = "1.0.0", note = "text")] + pub trait DeprecatedTrait { + fn dummy(&self) { } + } + + struct S; + + impl DeprecatedTrait for S { } // { dg-error "" "" { target *-*-* } } + + trait LocalTrait : DeprecatedTrait { } // { dg-error "" "" { target *-*-* } } +} + +mod this_crate2 { + struct Stable { + #[deprecated(since = "1.0.0", note = "text")] + override2: u8, + } + + struct Stable2(u8, + u8, + #[deprecated(since = "1.0.0", note = "text")] u8); + + #[deprecated(since = "1.0.0", note = "text")] + struct Deprecated { + inherit: u8, + } + + #[deprecated(since = "1.0.0", note = "text")] + struct Deprecated2(u8, + u8, + u8); + + pub fn foo() { + let x = Stable { + override2: 3, +// { dg-error "" "" { target *-*-* } .-1 } + }; + + let _ = x.override2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Stable { + override2: _ +// { dg-error "" "" { target *-*-* } .-1 } + } = x; + // all fine + let Stable { .. } = x; + + let x = Stable2(1, 2, 3); + + let _ = x.2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Stable2(_, + _, + _) +// { dg-error "" "" { target *-*-* } .-1 } + = x; + // all fine + let Stable2(..) = x; + + let x = Deprecated { +// { dg-error "" "" { target *-*-* } .-1 } + inherit: 1, +// { dg-error "" "" { target *-*-* } .-1 } + }; + + let _ = x.inherit; +// { dg-error "" "" { target *-*-* } .-1 } + + let Deprecated { +// { dg-error "" "" { target *-*-* } .-1 } + inherit: _, +// { dg-error "" "" { target *-*-* } .-1 } + } = x; + + let Deprecated +// { dg-error "" "" { target *-*-* } .-1 } + // the patterns are all fine: + { .. } = x; + + let x = Deprecated2(1, 2, 3); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = x.0; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = x.1; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = x.2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Deprecated2 +// { dg-error "" "" { target *-*-* } .-1 } + (_, +// { dg-error "" "" { target *-*-* } .-1 } + _, +// { dg-error "" "" { target *-*-* } .-1 } + _) +// { dg-error "" "" { target *-*-* } .-1 } + = x; + let Deprecated2 +// { dg-error "" "" { target *-*-* } .-1 } + // the patterns are all fine: + (..) = x; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-sanity.rs b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-sanity.rs new file mode 100644 index 000000000000..964cb174503e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/deprecation-sanity.rs @@ -0,0 +1,43 @@ +// Various checks that deprecation attributes are used correctly + +mod bogus_attribute_types_1 { + #[deprecated(since = "a", note = "a", reason)] // { dg-error ".E0541." "" { target *-*-* } } + fn f1() { } + + #[deprecated(since = "a", note)] // { dg-error ".E0551." "" { target *-*-* } } + fn f2() { } + + #[deprecated(since, note = "a")] // { dg-error ".E0551." "" { target *-*-* } } + fn f3() { } + + #[deprecated(since = "a", note(b))] // { dg-error ".E0551." "" { target *-*-* } } + fn f5() { } + + #[deprecated(since(b), note = "a")] // { dg-error ".E0551." "" { target *-*-* } } + fn f6() { } + + #[deprecated(note = b"test")] // { dg-error ".E0565." "" { target *-*-* } } + fn f7() { } + + #[deprecated("test")] // { dg-error ".E0565." "" { target *-*-* } } + fn f8() { } +} + +#[deprecated(since = "a", note = "b")] +#[deprecated(since = "a", note = "b")] // { dg-error ".E0550." "" { target *-*-* } } +fn multiple1() { } + +#[deprecated(since = "a", since = "b", note = "c")] // { dg-error ".E0538." "" { target *-*-* } } +fn f1() { } + +struct X; + +#[deprecated = "hello"] // { dg-error "" "" { target *-*-* } } +impl Default for X { + fn default() -> Self { + X + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/derive_on_deprecated.rs b/gcc/testsuite/rust/rustc/ui/deprecation/derive_on_deprecated.rs new file mode 100644 index 000000000000..d35cc6665254 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/derive_on_deprecated.rs @@ -0,0 +1,16 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![deny(deprecated)] + +#[deprecated = "oh no"] +#[derive(Default)] +struct X; + +#[deprecated(note="Do not use this")] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)] +pub struct Step { + _skip: Option, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/derive_on_deprecated_forbidden.rs b/gcc/testsuite/rust/rustc/ui/deprecation/derive_on_deprecated_forbidden.rs new file mode 100644 index 000000000000..310b8dca29a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/derive_on_deprecated_forbidden.rs @@ -0,0 +1,10 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![forbid(deprecated)] + +#[deprecated = "oh no"] +#[derive(Default)] +struct X; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/invalid-literal.rs b/gcc/testsuite/rust/rustc/ui/deprecation/invalid-literal.rs new file mode 100644 index 000000000000..0770a9eda339 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/invalid-literal.rs @@ -0,0 +1,5 @@ +#[deprecated = b"test"] // { dg-error "" "" { target *-*-* } } +fn foo() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs b/gcc/testsuite/rust/rustc/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs new file mode 100644 index 000000000000..7f609415b67b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs @@ -0,0 +1,12 @@ +// The original problem in #66340 was that `find_deprecation_generic` +// called `attr.meta().unwrap()` under the assumption that the attribute +// was a well-formed `MetaItem`. + +fn main() { + foo() +} + +#[deprecated(note = test)] +// { dg-error "" "" { target *-*-* } .-1 } +fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/rustc_deprecation-in-future.rs b/gcc/testsuite/rust/rustc/ui/deprecation/rustc_deprecation-in-future.rs new file mode 100644 index 000000000000..4c893cdbf79c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/rustc_deprecation-in-future.rs @@ -0,0 +1,16 @@ +// ignore-tidy-linelength + +#![deny(deprecated_in_future)] + +#![feature(staged_api)] + +#![stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")] + +#[rustc_deprecated(since = "99.99.99", reason = "effectively never")] +#[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")] +pub struct S; + +fn main() { + let _ = S; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/deprecation/suggestion.rs b/gcc/testsuite/rust/rustc/ui/deprecation/suggestion.rs new file mode 100644 index 000000000000..0c43d180d95f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deprecation/suggestion.rs @@ -0,0 +1,29 @@ +// run-rustfix + +#![feature(staged_api)] + +#![stable(since = "1.0.0", feature = "test")] + +#![deny(deprecated)] +#![allow(dead_code)] + +struct Foo; + +impl Foo { + #[rustc_deprecated( + since = "1.0.0", + reason = "replaced by `replacement`", + suggestion = "replacement", + )] + #[stable(since = "1.0.0", feature = "test")] + fn deprecated(&self) {} + + fn replacement(&self) {} +} + +fn main() { + let foo = Foo; + + foo.deprecated(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/deref-mut-on-ref.rs b/gcc/testsuite/rust/rustc/ui/deref-mut-on-ref.rs new file mode 100644 index 000000000000..5a58c115763e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deref-mut-on-ref.rs @@ -0,0 +1,16 @@ +// run-pass +// Test that `&mut T` implements `DerefMut` + + +use std::ops::{Deref, DerefMut}; + +fn inc + DerefMut>(mut t: T) { + *t += 1; +} + +fn main() { + let mut x: isize = 5; + inc(&mut x); + assert_eq!(x, 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deref-non-pointer.rs b/gcc/testsuite/rust/rustc/ui/deref-non-pointer.rs new file mode 100644 index 000000000000..0fc6f8fc2c09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deref-non-pointer.rs @@ -0,0 +1,6 @@ +fn main() { + match *1 { // { dg-error ".E0614." "" { target *-*-* } } + _ => { panic!(); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/deref-on-ref.rs b/gcc/testsuite/rust/rustc/ui/deref-on-ref.rs new file mode 100644 index 000000000000..99ceae8d532a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deref-on-ref.rs @@ -0,0 +1,20 @@ +// run-pass +// Test that `&T` and `&mut T` implement `Deref` + + +use std::ops::Deref; + +fn deref>(t: T) -> U { + *t +} + +fn main() { + let x: isize = 3; + let y = deref(&x); + assert_eq!(y, 3); + + let mut x: isize = 4; + let y = deref(&mut x); + assert_eq!(y, 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deref-rc.rs b/gcc/testsuite/rust/rustc/ui/deref-rc.rs new file mode 100644 index 000000000000..6fc67f692196 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deref-rc.rs @@ -0,0 +1,9 @@ +// run-pass + +use std::rc::Rc; + +fn main() { + let x = Rc::new([1, 2, 3, 4]); + assert_eq!(*x, [1, 2, 3, 4]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deref-suggestion.rs b/gcc/testsuite/rust/rustc/ui/deref-suggestion.rs new file mode 100644 index 000000000000..365053598994 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deref-suggestion.rs @@ -0,0 +1,49 @@ +macro_rules! borrow { + ($x:expr) => { &$x } // { dg-error ".E0308." "" { target *-*-* } } +} + +fn foo(_: String) {} + +fn foo2(s: &String) { + foo(s); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn foo3(_: u32) {} +fn foo4(u: &u32) { + foo3(u); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +struct S<'a> { + u: &'a u32, +} + +struct R { + i: u32, +} + +fn main() { + let s = String::new(); + let r_s = &s; + foo2(r_s); + foo(&"aaa".to_owned()); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo(&mut "aaa".to_owned()); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo3(borrow!(0)); + foo4(&0); + assert_eq!(3i32, &3i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let u = 3; + let s = S { u }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let s = S { u: u }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let i = &4; + let r = R { i }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let r = R { i: i }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/deref.rs b/gcc/testsuite/rust/rustc/ui/deref.rs new file mode 100644 index 000000000000..b32c7b359de3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deref.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { + let x: Box = box 10; + let _y: isize = *x; +} + diff --git a/gcc/testsuite/rust/rustc/ui/derive-uninhabited-enum-38885.rs b/gcc/testsuite/rust/rustc/ui/derive-uninhabited-enum-38885.rs new file mode 100644 index 000000000000..ee7f747ba85e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derive-uninhabited-enum-38885.rs @@ -0,0 +1,20 @@ +// check-pass +// compile-flags: -Wunused + +// ensure there are no special warnings about uninhabited types +// when deriving Debug on an empty enum + +#[derive(Debug)] +enum Void {} + +#[derive(Debug)] +enum Foo { + Bar(u8), + Void(Void), // { dg-warning "" "" { target *-*-* } } +} + +fn main() { + let x = Foo::Bar(42); + println!("{:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/derived-errors/issue-30580.rs b/gcc/testsuite/rust/rustc/ui/derived-errors/issue-30580.rs new file mode 100644 index 000000000000..914e7beebc8a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derived-errors/issue-30580.rs @@ -0,0 +1,18 @@ +// Test that we do not see uninformative region-related errors +// when we get some basic type-checking failure. See #30580. + +pub struct Foo { a: u32 } +pub struct Pass<'a, 'tcx: 'a>(&'a mut &'a (), &'a &'tcx ()); + +impl<'a, 'tcx> Pass<'a, 'tcx> +{ + pub fn tcx(&self) -> &'a &'tcx () { self.1 } + fn lol(&mut self, b: &Foo) + { + b.c; // { dg-error ".E0609." "" { target *-*-* } } + self.tcx(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derived-errors/issue-31997-1.rs b/gcc/testsuite/rust/rustc/ui/derived-errors/issue-31997-1.rs new file mode 100644 index 000000000000..5b7334c3af20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derived-errors/issue-31997-1.rs @@ -0,0 +1,57 @@ +// Regression test for this example from #31997 -- main goal is to +// emit as minimal and precise an error set as possible. Ideally, we'd +// only emit the E0433 error below, but right now we emit two. + +use std::io::prelude::*; +// use std::collections::HashMap; +use std::io; + +#[derive(Debug)] +struct Instance { + name: String, + start: Option, + end: Option, +} + +fn main() { + let input = io::stdin(); + let mut input = input.lock(); + + let mut map = HashMap::new(); +// { dg-error ".E0433." "" { target *-*-* } .-1 } + + for line in input.lines() { + let line = line.unwrap(); + println!("process: {}", line); + let mut parts = line.splitn(2, ":"); + let _logfile = parts.next().unwrap(); + let rest = parts.next().unwrap(); + let mut parts = line.split(" [-] "); + + let stamp = parts.next().unwrap(); + + let rest = parts.next().unwrap(); + let words = rest.split_whitespace().collect::>(); + + let instance = words.iter().find(|a| a.starts_with("i-")).unwrap(); + let name = words[1].to_owned(); + let mut entry = map.entry(instance.to_owned()).or_insert(Instance { + name: name, + start: None, + end: None, + }); + + if rest.contains("terminating") { + assert!(entry.end.is_none()); + entry.end = Some(stamp.to_string()); + } + if rest.contains("waiting for") { + assert!(entry.start.is_none()); + entry.start = Some(stamp.to_string()); + } + + } + + println!("{:?}", map); +} + diff --git a/gcc/testsuite/rust/rustc/ui/derived-errors/issue-31997.rs b/gcc/testsuite/rust/rustc/ui/derived-errors/issue-31997.rs new file mode 100644 index 000000000000..de7e494247ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derived-errors/issue-31997.rs @@ -0,0 +1,19 @@ +// Test that the resolve failure does not lead to downstream type errors. +// See issue #31997. +#![allow(deprecated)] + +trait TheTrait { } + +fn closure(x: F) -> Result + where F: FnMut() -> T, T: TheTrait, +{ + unimplemented!() +} + +fn foo() -> Result<(), ()> { + try!(closure(|| bar(core::ptr::null_mut()))); // { dg-error ".E0425." "" { target *-*-* } } + Ok(()) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/derives/auxiliary/derive-marker-tricky.rs b/gcc/testsuite/rust/rustc/ui/derives/auxiliary/derive-marker-tricky.rs new file mode 100644 index 000000000000..85519baf2644 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/auxiliary/derive-marker-tricky.rs @@ -0,0 +1,16 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro_derive(NoMarker)] +pub fn f(input: TokenStream) -> TokenStream { + if input.to_string().contains("rustc_copy_clone_marker") { + panic!("found `#[rustc_copy_clone_marker]`"); + } + TokenStream::new() +} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derive-assoc-type-not-impl.rs b/gcc/testsuite/rust/rustc/ui/derives/derive-assoc-type-not-impl.rs new file mode 100644 index 000000000000..f0d17125e218 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derive-assoc-type-not-impl.rs @@ -0,0 +1,20 @@ +trait Foo { + type X; + fn method(&self) {} +} + +#[derive(Clone)] +struct Bar { + x: T::X, +} + +struct NotClone; + +impl Foo for NotClone { + type X = i8; +} + +fn main() { + Bar:: { x: 1 }.clone(); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derive-hygiene.rs b/gcc/testsuite/rust/rustc/ui/derives/derive-hygiene.rs new file mode 100644 index 000000000000..9e73b8c60108 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derive-hygiene.rs @@ -0,0 +1,122 @@ +// Make sure that built-in derives don't rely on the user not declaring certain +// names to work properly. + +// check-pass + +#![allow(nonstandard_style)] +#![feature(decl_macro)] + +use std::prelude::v1::test as inline; + +static f: () = (); +static cmp: () = (); +static other: () = (); +static state: () = (); +static __self_0_0: () = (); +static __self_1_0: () = (); +static __self_vi: () = (); +static __arg_1_0: () = (); +static debug_trait_builder: () = (); + +struct isize; +trait i16 {} + +trait MethodsInDerives: Sized { + fn debug_tuple(self) {} + fn debug_struct(self) {} + fn field(self) {} + fn finish(self) {} + fn clone(self) {} + fn cmp(self) {} + fn partial_cmp(self) {} + fn eq(self) {} + fn ne(self) {} + fn le(self) {} + fn lt(self) {} + fn ge(self) {} + fn gt(self) {} + fn hash(self) {} +} + +trait GenericAny {} +impl GenericAny for S {} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +enum __H { V(i32), } + +#[repr(i16)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +enum W { A, B } + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)] +struct X>> { + A: A, +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)] +struct Y(B) +where + B: From; + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +enum Z { + C(C), + B { C: C }, +} + +// Make sure that we aren't using `self::` in paths, since it doesn't work in +// non-module scopes. +const NON_MODULE: () = { + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] + enum __H { V(i32), } + + #[repr(i16)] + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] + enum W { A, B } + + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)] + struct X self::X> { + A: A, + } + + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)] + struct Y(B) + where + B: From; + + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] + enum Z { + C(C), + B { C: C }, + } +}; + +macro m() { + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] + enum __H { V(i32), } + + #[repr(i16)] + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] + enum W { A, B } + + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)] + struct X>> { + A: A, + } + + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)] + struct Y(B) + where + B: From; + + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] + enum Z { + C(C), + B { C: C }, + } +} + +m!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derive-marker-tricky.rs b/gcc/testsuite/rust/rustc/ui/derives/derive-marker-tricky.rs new file mode 100644 index 000000000000..548dde0af796 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derive-marker-tricky.rs @@ -0,0 +1,17 @@ +// Test that `#[rustc_copy_clone_marker]` is not injected when a user-defined derive shadows +// a built-in derive in non-trivial scope (e.g. in a nested module). + +// check-pass +// aux-build:derive-marker-tricky.rs + +extern crate derive_marker_tricky; + +mod m { + use derive_marker_tricky::NoMarker as Copy; + + #[derive(Copy)] + struct S; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derive-on-trait-item-or-impl-item.rs b/gcc/testsuite/rust/rustc/ui/derives/derive-on-trait-item-or-impl-item.rs new file mode 100644 index 000000000000..56f54a965375 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derive-on-trait-item-or-impl-item.rs @@ -0,0 +1,16 @@ +trait Foo { + #[derive(Clone)] +// { dg-error ".E0774." "" { target *-*-* } .-1 } + type Bar; +} + +struct Bar; + +impl Bar { + #[derive(Clone)] +// { dg-error ".E0774." "" { target *-*-* } .-1 } + fn bar(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-enum-struct-variant.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-enum-struct-variant.rs new file mode 100644 index 000000000000..dc9721aaff2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-enum-struct-variant.rs @@ -0,0 +1,14 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Clone)] +enum Enum { + A { + x: Error // { dg-error ".E0277." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-enum.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-enum.rs new file mode 100644 index 000000000000..54b0a1af2d76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-enum.rs @@ -0,0 +1,14 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Clone)] +enum Enum { + A( + Error // { dg-error ".E0277." "" { target *-*-* } } + ) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-struct.rs new file mode 100644 index 000000000000..645de70d0367 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-struct.rs @@ -0,0 +1,12 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Clone)] +struct Struct { + x: Error // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-tuple-struct.rs new file mode 100644 index 000000000000..da10c1eac287 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Clone-tuple-struct.rs @@ -0,0 +1,12 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Clone)] +struct Struct( + Error // { dg-error ".E0277." "" { target *-*-* } } +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-enum-struct-variant.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-enum-struct-variant.rs new file mode 100644 index 000000000000..db3680d2e946 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-enum-struct-variant.rs @@ -0,0 +1,14 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Debug)] +enum Enum { + A { + x: Error // { dg-error ".E0277." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-enum.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-enum.rs new file mode 100644 index 000000000000..815ed4353f87 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-enum.rs @@ -0,0 +1,14 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Debug)] +enum Enum { + A( + Error // { dg-error ".E0277." "" { target *-*-* } } + ) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-struct.rs new file mode 100644 index 000000000000..3bc5f466a247 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-struct.rs @@ -0,0 +1,12 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Debug)] +struct Struct { + x: Error // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-tuple-struct.rs new file mode 100644 index 000000000000..9d76f05e0691 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Debug-tuple-struct.rs @@ -0,0 +1,12 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Debug)] +struct Struct( + Error // { dg-error ".E0277." "" { target *-*-* } } +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Default-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Default-struct.rs new file mode 100644 index 000000000000..4aec44836dd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Default-struct.rs @@ -0,0 +1,12 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Default)] +struct Struct { + x: Error // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Default-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Default-tuple-struct.rs new file mode 100644 index 000000000000..0f2a2b535577 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Default-tuple-struct.rs @@ -0,0 +1,12 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Default)] +struct Struct( + Error // { dg-error ".E0277." "" { target *-*-* } } +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-enum-struct-variant.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-enum-struct-variant.rs new file mode 100644 index 000000000000..5a0a8fc8a386 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-enum-struct-variant.rs @@ -0,0 +1,14 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +#[derive(PartialEq)] +struct Error; + +#[derive(Eq,PartialEq)] +enum Enum { + A { + x: Error // { dg-error ".E0277." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-enum.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-enum.rs new file mode 100644 index 000000000000..fd8829ea5e32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-enum.rs @@ -0,0 +1,14 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +#[derive(PartialEq)] +struct Error; + +#[derive(Eq,PartialEq)] +enum Enum { + A( + Error // { dg-error ".E0277." "" { target *-*-* } } + ) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-struct.rs new file mode 100644 index 000000000000..96da2c570ac2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-struct.rs @@ -0,0 +1,12 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +#[derive(PartialEq)] +struct Error; + +#[derive(Eq,PartialEq)] +struct Struct { + x: Error // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-tuple-struct.rs new file mode 100644 index 000000000000..0c38083abbd4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Eq-tuple-struct.rs @@ -0,0 +1,12 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +#[derive(PartialEq)] +struct Error; + +#[derive(Eq,PartialEq)] +struct Struct( + Error // { dg-error ".E0277." "" { target *-*-* } } +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-enum-struct-variant.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-enum-struct-variant.rs new file mode 100644 index 000000000000..5cc9baec74a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-enum-struct-variant.rs @@ -0,0 +1,14 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Hash)] +enum Enum { + A { + x: Error // { dg-error ".E0277." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-enum.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-enum.rs new file mode 100644 index 000000000000..28ec550c781c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-enum.rs @@ -0,0 +1,13 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +struct Error; + +#[derive(Hash)] +enum Enum { + A( + Error // { dg-error ".E0277." "" { target *-*-* } } + ) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-struct.rs new file mode 100644 index 000000000000..4bdfb2788b35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-struct.rs @@ -0,0 +1,12 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Hash)] +struct Struct { + x: Error // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-tuple-struct.rs new file mode 100644 index 000000000000..6cb5493a8829 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Hash-tuple-struct.rs @@ -0,0 +1,12 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(Hash)] +struct Struct( + Error // { dg-error ".E0277." "" { target *-*-* } } +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-enum-struct-variant.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-enum-struct-variant.rs new file mode 100644 index 000000000000..4f21435ad601 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-enum-struct-variant.rs @@ -0,0 +1,14 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +#[derive(Eq,PartialOrd,PartialEq)] +struct Error; + +#[derive(Ord,Eq,PartialOrd,PartialEq)] +enum Enum { + A { + x: Error // { dg-error ".E0277." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-enum.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-enum.rs new file mode 100644 index 000000000000..7acb3773eff4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-enum.rs @@ -0,0 +1,14 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +#[derive(Eq,PartialOrd,PartialEq)] +struct Error; + +#[derive(Ord,Eq,PartialOrd,PartialEq)] +enum Enum { + A( + Error // { dg-error ".E0277." "" { target *-*-* } } + ) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-struct.rs new file mode 100644 index 000000000000..9a9902a7fa33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-struct.rs @@ -0,0 +1,12 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +#[derive(Eq,PartialOrd,PartialEq)] +struct Error; + +#[derive(Ord,Eq,PartialOrd,PartialEq)] +struct Struct { + x: Error // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-tuple-struct.rs new file mode 100644 index 000000000000..c2086a5385b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-Ord-tuple-struct.rs @@ -0,0 +1,12 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +#[derive(Eq,PartialOrd,PartialEq)] +struct Error; + +#[derive(Ord,Eq,PartialOrd,PartialEq)] +struct Struct( + Error // { dg-error ".E0277." "" { target *-*-* } } +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-enum-struct-variant.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-enum-struct-variant.rs new file mode 100644 index 000000000000..b93c6b0a6244 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-enum-struct-variant.rs @@ -0,0 +1,15 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(PartialEq)] +enum Enum { + A { + x: Error // { dg-error ".E0369." "" { target *-*-* } } +// { dg-error ".E0369." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-enum.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-enum.rs new file mode 100644 index 000000000000..8786e430cb9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-enum.rs @@ -0,0 +1,15 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(PartialEq)] +enum Enum { + A( + Error // { dg-error ".E0369." "" { target *-*-* } } +// { dg-error ".E0369." "" { target *-*-* } .-1 } + ) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-struct.rs new file mode 100644 index 000000000000..d1331bde8604 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-struct.rs @@ -0,0 +1,13 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(PartialEq)] +struct Struct { + x: Error // { dg-error ".E0369." "" { target *-*-* } } +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-tuple-struct.rs new file mode 100644 index 000000000000..db5ff0c9619a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialEq-tuple-struct.rs @@ -0,0 +1,13 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + + +struct Error; + +#[derive(PartialEq)] +struct Struct( + Error // { dg-error ".E0369." "" { target *-*-* } } +// { dg-error ".E0369." "" { target *-*-* } .-1 } +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs new file mode 100644 index 000000000000..e32a226e5ea3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs @@ -0,0 +1,18 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +#[derive(PartialEq)] +struct Error; + +#[derive(PartialOrd,PartialEq)] +enum Enum { + A { + x: Error // { dg-error ".E0277." "" { target *-*-* } } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-enum.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-enum.rs new file mode 100644 index 000000000000..922226fbeb63 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-enum.rs @@ -0,0 +1,18 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +#[derive(PartialEq)] +struct Error; + +#[derive(PartialOrd,PartialEq)] +enum Enum { + A( + Error // { dg-error ".E0277." "" { target *-*-* } } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } + ) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-struct.rs new file mode 100644 index 000000000000..339f23c924ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-struct.rs @@ -0,0 +1,16 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +#[derive(PartialEq)] +struct Error; + +#[derive(PartialOrd,PartialEq)] +struct Struct { + x: Error // { dg-error ".E0277." "" { target *-*-* } } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-tuple-struct.rs new file mode 100644 index 000000000000..b5cc4105c457 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/derives-span-PartialOrd-tuple-struct.rs @@ -0,0 +1,16 @@ +// This file was auto-generated using 'src/etc/generate-deriving-span-tests.py' + +#[derive(PartialEq)] +struct Error; + +#[derive(PartialOrd,PartialEq)] +struct Struct( + Error // { dg-error ".E0277." "" { target *-*-* } } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/deriving-bounds.rs b/gcc/testsuite/rust/rustc/ui/derives/deriving-bounds.rs new file mode 100644 index 000000000000..71e4385e4159 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/deriving-bounds.rs @@ -0,0 +1,12 @@ +#[derive(Send)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +struct Test; + +#[derive(Sync)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +struct Test1; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/deriving-copyclone.rs b/gcc/testsuite/rust/rustc/ui/derives/deriving-copyclone.rs new file mode 100644 index 000000000000..94df93b4ba9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/deriving-copyclone.rs @@ -0,0 +1,38 @@ +// this will get a no-op Clone impl +#[derive(Copy, Clone)] +struct A { + a: i32, + b: i64 +} + +// this will get a deep Clone impl +#[derive(Copy, Clone)] +struct B { + a: i32, + b: T +} + +struct C; // not Copy or Clone +#[derive(Clone)] struct D; // Clone but not Copy + +fn is_copy(_: T) {} +fn is_clone(_: T) {} + +fn main() { + // A can be copied and cloned + is_copy(A { a: 1, b: 2 }); + is_clone(A { a: 1, b: 2 }); + + // B can be copied and cloned + is_copy(B { a: 1, b: 2 }); + is_clone(B { a: 1, b: 2 }); + + // B cannot be copied or cloned + is_copy(B { a: 1, b: C }); // { dg-error ".E0277." "" { target *-*-* } } + is_clone(B { a: 1, b: C }); // { dg-error ".E0277." "" { target *-*-* } } + + // B can be cloned but not copied + is_copy(B { a: 1, b: D }); // { dg-error ".E0277." "" { target *-*-* } } + is_clone(B { a: 1, b: D }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/deriving-meta-empty-trait-list.rs b/gcc/testsuite/rust/rustc/ui/derives/deriving-meta-empty-trait-list.rs new file mode 100644 index 000000000000..c5af3f6ffb71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/deriving-meta-empty-trait-list.rs @@ -0,0 +1,7 @@ +#![deny(unused)] + +#[derive()] // { dg-error "" "" { target *-*-* } } +struct _Bar; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/deriving-meta-unknown-trait.rs b/gcc/testsuite/rust/rustc/ui/derives/deriving-meta-unknown-trait.rs new file mode 100644 index 000000000000..a4f3b0f3ad93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/deriving-meta-unknown-trait.rs @@ -0,0 +1,7 @@ +#[derive(Eqr)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +struct Foo; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/deriving-no-inner-impl-error-message.rs b/gcc/testsuite/rust/rustc/ui/derives/deriving-no-inner-impl-error-message.rs new file mode 100644 index 000000000000..a76425bd0538 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/deriving-no-inner-impl-error-message.rs @@ -0,0 +1,16 @@ +struct NoCloneOrEq; + +#[derive(PartialEq)] +struct E { + x: NoCloneOrEq // { dg-error ".E0369." "" { target *-*-* } } +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} +#[derive(Clone)] +struct C { + x: NoCloneOrEq +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/deriving-non-type.rs b/gcc/testsuite/rust/rustc/ui/derives/deriving-non-type.rs new file mode 100644 index 000000000000..595db7abe9cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/deriving-non-type.rs @@ -0,0 +1,31 @@ +#![allow(dead_code)] + +struct S; + +#[derive(PartialEq)] // { dg-error ".E0774." "" { target *-*-* } } +trait T { } + +#[derive(PartialEq)] // { dg-error ".E0774." "" { target *-*-* } } +impl S { } + +#[derive(PartialEq)] // { dg-error ".E0774." "" { target *-*-* } } +impl T for S { } + +#[derive(PartialEq)] // { dg-error ".E0774." "" { target *-*-* } } +static s: usize = 0; + +#[derive(PartialEq)] // { dg-error ".E0774." "" { target *-*-* } } +const c: usize = 0; + +#[derive(PartialEq)] // { dg-error ".E0774." "" { target *-*-* } } +mod m { } + +#[derive(PartialEq)] // { dg-error ".E0774." "" { target *-*-* } } +extern "C" { } + +#[derive(PartialEq)] // { dg-error ".E0774." "" { target *-*-* } } +type A = usize; + +#[derive(PartialEq)] // { dg-error ".E0774." "" { target *-*-* } } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/derives/deriving-primitive.rs b/gcc/testsuite/rust/rustc/ui/derives/deriving-primitive.rs new file mode 100644 index 000000000000..9d72ba7d6481 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/deriving-primitive.rs @@ -0,0 +1,6 @@ +#[derive(FromPrimitive)] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +enum Foo {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/derives/deriving-with-repr-packed.rs b/gcc/testsuite/rust/rustc/ui/derives/deriving-with-repr-packed.rs new file mode 100644 index 000000000000..e4a117c736a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/derives/deriving-with-repr-packed.rs @@ -0,0 +1,32 @@ +#![deny(safe_packed_borrows)] + +// check that derive on a packed struct with non-Copy fields +// correctly. This can't be made to work perfectly because +// we can't just use the field from the struct as it might +// not be aligned. + +#[derive(Copy, Clone, PartialEq, Eq)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-2 } +#[repr(packed)] +pub struct Foo(T, T, T); + +#[derive(PartialEq, Eq)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +#[repr(packed)] +pub struct Bar(u32, u32, u32); + +#[derive(PartialEq)] +struct Y(usize); + +#[derive(PartialEq)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +#[repr(packed)] +struct X(Y); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/auxiliary/derive-no-std.rs b/gcc/testsuite/rust/rustc/ui/deriving/auxiliary/derive-no-std.rs new file mode 100644 index 000000000000..21bfd5a2909b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/auxiliary/derive-no-std.rs @@ -0,0 +1,30 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] +#![no_std] + +// Issue #16803 + +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, + Debug, Default, Copy)] +pub struct Foo { + pub x: u32, +} + +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, + Debug, Copy)] +pub enum Bar { + Qux, + Quux(u32), +} + +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, + Debug, Copy)] +pub enum Void {} +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, + Debug, Copy)] +pub struct Empty; +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, + Debug, Copy)] +pub struct AlsoEmpty {} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/derive-no-std.rs b/gcc/testsuite/rust/rustc/ui/deriving/derive-no-std.rs new file mode 100644 index 000000000000..22edd3eed592 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/derive-no-std.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:derive-no-std.rs + +extern crate derive_no_std; +use derive_no_std::*; + +fn main() { + let f = Foo { x: 0 }; + assert_eq!(f.clone(), Foo::default()); + + assert!(Bar::Qux < Bar::Quux(42)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/derive-partialord-correctness.rs b/gcc/testsuite/rust/rustc/ui/deriving/derive-partialord-correctness.rs new file mode 100644 index 000000000000..639dd80aad55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/derive-partialord-correctness.rs @@ -0,0 +1,10 @@ +// run-pass +// Original issue: #49650 + +#[derive(PartialOrd, PartialEq)] +struct FloatWrapper(f64); + +fn main() { + assert!((0.0 / 0.0 >= 0.0) == (FloatWrapper(0.0 / 0.0) >= FloatWrapper(0.0))) +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-associated-types.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-associated-types.rs new file mode 100644 index 000000000000..aff0a7971a32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-associated-types.rs @@ -0,0 +1,201 @@ +// run-pass +// ignore-compare-mode-chalk +pub trait DeclaredTrait { + type Type; +} + +impl DeclaredTrait for i32 { + type Type = i32; +} + +pub trait WhereTrait { + type Type; +} + +impl WhereTrait for i32 { + type Type = i32; +} + +// Make sure we don't add a bound that just shares a name with an associated +// type. +pub mod module { + pub type Type = i32; +} + +#[derive(PartialEq, Debug)] +struct PrivateStruct(T); + +#[derive(PartialEq, Debug)] +struct TupleStruct( + module::Type, + Option, + A, + PrivateStruct, + B, + B::Type, + Option, + ::Type, + Option<::Type>, + C, + C::Type, + Option, + ::Type, + Option<::Type>, + ::Type, +) where C: WhereTrait; + +#[derive(PartialEq, Debug)] +pub struct Struct where C: WhereTrait { + m1: module::Type, + m2: Option, + a1: A, + a2: PrivateStruct, + b: B, + b1: B::Type, + b2: Option, + b3: ::Type, + b4: Option<::Type>, + c: C, + c1: C::Type, + c2: Option, + c3: ::Type, + c4: Option<::Type>, + d: ::Type, +} + +#[derive(PartialEq, Debug)] +enum Enum where C: WhereTrait { + Unit, + Seq( + module::Type, + Option, + A, + PrivateStruct, + B, + B::Type, + Option, + ::Type, + Option<::Type>, + C, + C::Type, + Option, + ::Type, + Option<::Type>, + ::Type, + ), + Map { + m1: module::Type, + m2: Option, + a1: A, + a2: PrivateStruct, + b: B, + b1: B::Type, + b2: Option, + b3: ::Type, + b4: Option<::Type>, + c: C, + c1: C::Type, + c2: Option, + c3: ::Type, + c4: Option<::Type>, + d: ::Type, + }, +} + +fn main() { + let e: TupleStruct< + i32, + i32, + i32, + > = TupleStruct( + 0, + None, + 0, + PrivateStruct(0), + 0, + 0, + None, + 0, + None, + 0, + 0, + None, + 0, + None, + 0, + ); + assert_eq!(e, e); + + let e: Struct< + i32, + i32, + i32, + > = Struct { + m1: 0, + m2: None, + a1: 0, + a2: PrivateStruct(0), + b: 0, + b1: 0, + b2: None, + b3: 0, + b4: None, + c: 0, + c1: 0, + c2: None, + c3: 0, + c4: None, + d: 0, + }; + assert_eq!(e, e); + + let e = Enum::Unit::; + assert_eq!(e, e); + + let e: Enum< + i32, + i32, + i32, + > = Enum::Seq( + 0, + None, + 0, + PrivateStruct(0), + 0, + 0, + None, + 0, + None, + 0, + 0, + None, + 0, + None, + 0, + ); + assert_eq!(e, e); + + let e: Enum< + i32, + i32, + i32, + > = Enum::Map { + m1: 0, + m2: None, + a1: 0, + a2: PrivateStruct(0), + b: 0, + b1: 0, + b2: None, + b3: 0, + b4: None, + c: 0, + c1: 0, + c2: None, + c3: 0, + c4: None, + d: 0, + }; + assert_eq!(e, e); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-bounds.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-bounds.rs new file mode 100644 index 000000000000..0c434931fde9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-bounds.rs @@ -0,0 +1,6 @@ +// run-pass +#[derive(Copy, Clone)] +struct Test; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-array.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-array.rs new file mode 100644 index 000000000000..893f82e00b5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-array.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] +// test for issue #30244 + +#[derive(Copy, Clone)] +struct Array { + arr: [[u8; 256]; 4] +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-enum.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-enum.rs new file mode 100644 index 000000000000..9db94b6b1115 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-enum.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#[derive(Clone)] +enum E { + A, + B(()), + C +} + +pub fn main() { + let _ = E::A.clone(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-generic-enum.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-generic-enum.rs new file mode 100644 index 000000000000..cc680caacc88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-generic-enum.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#[derive(Clone)] +enum E { + A(T), + B(T,U), + C +} + +pub fn main() { + let _ = E::A::(1).clone(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-generic-struct.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-generic-struct.rs new file mode 100644 index 000000000000..4f711dea4101 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-generic-struct.rs @@ -0,0 +1,14 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#[derive(Clone)] +struct S { + foo: (), + bar: (), + baz: T, +} + +pub fn main() { + let _ = S { foo: (), bar: (), baz: 1 }.clone(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-generic-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-generic-tuple-struct.rs new file mode 100644 index 000000000000..af98d8f25251 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-generic-tuple-struct.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#[derive(Clone)] +struct S(T, ()); + +pub fn main() { + let _ = S(1, ()).clone(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-struct.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-struct.rs new file mode 100644 index 000000000000..9f012e2e83b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-struct.rs @@ -0,0 +1,27 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#[derive(Clone)] +struct S { + _int: isize, + _i8: i8, + _i16: i16, + _i32: i32, + _i64: i64, + + _uint: usize, + _u8: u8, + _u16: u16, + _u32: u32, + _u64: u64, + + _f32: f32, + _f64: f64, + + _bool: bool, + _char: char, + _nil: () +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-tuple-struct.rs new file mode 100644 index 000000000000..dbfaa56ca400 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-clone-tuple-struct.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#[derive(Clone)] +struct S((), ()); + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-enum.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-enum.rs new file mode 100644 index 000000000000..4434e7b2b4f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-enum.rs @@ -0,0 +1,45 @@ +// run-pass +#[derive(PartialEq, Eq, PartialOrd, Ord)] +enum E { + E0, + E1(T), + E2(T,T) +} + +pub fn main() { + let e0 = E::E0; + let e11 = E::E1(1); + let e12 = E::E1(2); + let e21 = E::E2(1, 1); + let e22 = E::E2(1, 2); + + // in order for both PartialOrd and Ord + let es = [e0, e11, e12, e21, e22]; + + for (i, e1) in es.iter().enumerate() { + for (j, e2) in es.iter().enumerate() { + let ord = i.cmp(&j); + + let eq = i == j; + let lt = i < j; + let le = i <= j; + let gt = i > j; + let ge = i >= j; + + // PartialEq + assert_eq!(*e1 == *e2, eq); + assert_eq!(*e1 != *e2, !eq); + + // PartialOrd + assert_eq!(*e1 < *e2, lt); + assert_eq!(*e1 > *e2, gt); + + assert_eq!(*e1 <= *e2, le); + assert_eq!(*e1 >= *e2, ge); + + // Ord + assert_eq!(e1.cmp(e2), ord); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-struct-enum.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-struct-enum.rs new file mode 100644 index 000000000000..9f9b38d76f77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-struct-enum.rs @@ -0,0 +1,49 @@ +// run-pass +#[derive(PartialEq, Eq, PartialOrd, Ord)] +enum ES { + ES1 { x: T }, + ES2 { x: T, y: T } +} + + +pub fn main() { + let (es11, es12, es21, es22) = (ES::ES1 { + x: 1 + }, ES::ES1 { + x: 2 + }, ES::ES2 { + x: 1, + y: 1 + }, ES::ES2 { + x: 1, + y: 2 + }); + + // in order for both PartialOrd and Ord + let ess = [es11, es12, es21, es22]; + + for (i, es1) in ess.iter().enumerate() { + for (j, es2) in ess.iter().enumerate() { + let ord = i.cmp(&j); + + let eq = i == j; + let (lt, le) = (i < j, i <= j); + let (gt, ge) = (i > j, i >= j); + + // PartialEq + assert_eq!(*es1 == *es2, eq); + assert_eq!(*es1 != *es2, !eq); + + // PartialOrd + assert_eq!(*es1 < *es2, lt); + assert_eq!(*es1 > *es2, gt); + + assert_eq!(*es1 <= *es2, le); + assert_eq!(*es1 >= *es2, ge); + + // Ord + assert_eq!(es1.cmp(es2), ord); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-struct.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-struct.rs new file mode 100644 index 000000000000..a3da7197c706 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-struct.rs @@ -0,0 +1,41 @@ +// run-pass +#[derive(PartialEq, Eq, PartialOrd, Ord)] +struct S { + x: T, + y: T +} + +pub fn main() { + let s1 = S {x: 1, y: 1}; + let s2 = S {x: 1, y: 2}; + + // in order for both PartialOrd and Ord + let ss = [s1, s2]; + + for (i, s1) in ss.iter().enumerate() { + for (j, s2) in ss.iter().enumerate() { + let ord = i.cmp(&j); + + let eq = i == j; + let lt = i < j; + let le = i <= j; + let gt = i > j; + let ge = i >= j; + + // PartialEq + assert_eq!(*s1 == *s2, eq); + assert_eq!(*s1 != *s2, !eq); + + // PartialOrd + assert_eq!(*s1 < *s2, lt); + assert_eq!(*s1 > *s2, gt); + + assert_eq!(*s1 <= *s2, le); + assert_eq!(*s1 >= *s2, ge); + + // Ord + assert_eq!(s1.cmp(s2), ord); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-tuple-struct.rs new file mode 100644 index 000000000000..431e7b79c8c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-generic-tuple-struct.rs @@ -0,0 +1,39 @@ +// run-pass +#[derive(PartialEq, Eq, PartialOrd, Ord)] +struct TS(T,T); + + +pub fn main() { + let ts1 = TS(1, 1); + let ts2 = TS(1, 2); + + // in order for both PartialOrd and Ord + let tss = [ts1, ts2]; + + for (i, ts1) in tss.iter().enumerate() { + for (j, ts2) in tss.iter().enumerate() { + let ord = i.cmp(&j); + + let eq = i == j; + let lt = i < j; + let le = i <= j; + let gt = i > j; + let ge = i >= j; + + // PartialEq + assert_eq!(*ts1 == *ts2, eq); + assert_eq!(*ts1 != *ts2, !eq); + + // PartialOrd + assert_eq!(*ts1 < *ts2, lt); + assert_eq!(*ts1 > *ts2, gt); + + assert_eq!(*ts1 <= *ts2, le); + assert_eq!(*ts1 >= *ts2, ge); + + // Ord + assert_eq!(ts1.cmp(ts2), ord); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-shortcircuit.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-shortcircuit.rs new file mode 100644 index 000000000000..eddf229665e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-cmp-shortcircuit.rs @@ -0,0 +1,38 @@ +// run-pass +// check that the derived impls for the comparison traits shortcircuit +// where possible, by having a type that panics when compared as the +// second element, so this passes iff the instances shortcircuit. + + +use std::cmp::Ordering; + +pub struct FailCmp; +impl PartialEq for FailCmp { + fn eq(&self, _: &FailCmp) -> bool { panic!("eq") } +} + +impl PartialOrd for FailCmp { + fn partial_cmp(&self, _: &FailCmp) -> Option { panic!("partial_cmp") } +} + +impl Eq for FailCmp {} + +impl Ord for FailCmp { + fn cmp(&self, _: &FailCmp) -> Ordering { panic!("cmp") } +} + +#[derive(PartialEq,PartialOrd,Eq,Ord)] +struct ShortCircuit { + x: isize, + y: FailCmp +} + +pub fn main() { + let a = ShortCircuit { x: 1, y: FailCmp }; + let b = ShortCircuit { x: 2, y: FailCmp }; + + assert!(a != b); + assert!(a < b); + assert_eq!(a.cmp(&b), ::std::cmp::Ordering::Less); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-copyclone.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-copyclone.rs new file mode 100644 index 000000000000..7ee5219365f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-copyclone.rs @@ -0,0 +1,39 @@ +// run-pass +//! Test that #[derive(Copy, Clone)] produces a shallow copy +//! even when a member violates RFC 1521 + +use std::sync::atomic::{AtomicBool, Ordering}; + +/// A struct that pretends to be Copy, but actually does something +/// in its Clone impl +#[derive(Copy)] +struct Liar; + +/// Static cooperating with the rogue Clone impl +static CLONED: AtomicBool = AtomicBool::new(false); + +impl Clone for Liar { + fn clone(&self) -> Self { + // this makes Clone vs Copy observable + CLONED.store(true, Ordering::SeqCst); + + *self + } +} + +/// This struct is actually Copy... at least, it thinks it is! +#[derive(Copy, Clone)] +struct Innocent(Liar); + +impl Innocent { + fn new() -> Self { + Innocent(Liar) + } +} + +fn main() { + let _ = Innocent::new().clone(); + // if Innocent was byte-for-byte copied, CLONED will still be false + assert!(!CLONED.load(Ordering::SeqCst)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-default-box.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-default-box.rs new file mode 100644 index 000000000000..b6a0a9069834 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-default-box.rs @@ -0,0 +1,16 @@ +// run-pass +#![feature(box_syntax)] + +use std::default::Default; + +#[derive(Default)] +struct A { + foo: Box<[bool]>, +} + +pub fn main() { + let a: A = Default::default(); + let b: Box<[_]> = Box::<[bool; 0]>::new([]); + assert_eq!(a.foo, b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-enum-single-variant.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-enum-single-variant.rs new file mode 100644 index 000000000000..46700041988e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-enum-single-variant.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 +#![allow(non_camel_case_types)] + +pub type task_id = isize; + +#[derive(PartialEq)] +pub enum Task { + TaskHandle(task_id) +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-eq-ord-boxed-slice.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-eq-ord-boxed-slice.rs new file mode 100644 index 000000000000..c7b7ade6ff4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-eq-ord-boxed-slice.rs @@ -0,0 +1,16 @@ +// run-pass +#[derive(PartialEq, PartialOrd, Eq, Ord, Debug)] +struct Foo(Box<[u8]>); + +pub fn main() { + let a = Foo(Box::new([0, 1, 2])); + let b = Foo(Box::new([0, 1, 2])); + assert_eq!(a, b); + println!("{}", a != b); + println!("{}", a < b); + println!("{}", a <= b); + println!("{}", a == b); + println!("{}", a > b); + println!("{}", a >= b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-hash.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-hash.rs new file mode 100644 index 000000000000..eada02e9d249 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-hash.rs @@ -0,0 +1,77 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_imports)] +#![allow(deprecated)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(overflowing_literals)] + +use std::hash::{Hash, SipHasher, Hasher}; +use std::mem::size_of; + +#[derive(Hash)] +struct Person { + id: usize, + name: String, + phone: usize, +} + +// test for hygiene name collisions +#[derive(Hash)] struct __H__H; +#[derive(Hash)] enum Collision<__H> { __H { __H__H: __H } } + +#[derive(Hash)] +enum E { A=1, B } + +fn hash(t: &T) -> u64 { + let mut s = SipHasher::new(); + t.hash(&mut s); + s.finish() +} + +struct FakeHasher<'a>(&'a mut Vec); +impl<'a> Hasher for FakeHasher<'a> { + fn finish(&self) -> u64 { + unimplemented!() + } + + fn write(&mut self, bytes: &[u8]) { + self.0.extend(bytes); + } +} + +fn fake_hash(v: &mut Vec, a: A) { + a.hash(&mut FakeHasher(v)); +} + +fn main() { + let person1 = Person { + id: 5, + name: "Janet".to_string(), + phone: 555_666_7777 + }; + let person2 = Person { + id: 5, + name: "Bob".to_string(), + phone: 555_666_7777 + }; + assert_eq!(hash(&person1), hash(&person1)); + assert!(hash(&person1) != hash(&person2)); + + // test #21714 + let mut va = vec![]; + let mut vb = vec![]; + fake_hash(&mut va, E::A); + fake_hash(&mut vb, E::B); + assert!(va != vb); + + // issue #39137: single variant enum hash should not hash discriminant + #[derive(Hash)] + enum SingleVariantEnum { + A(u8), + } + let mut v = vec![]; + fake_hash(&mut v, SingleVariantEnum::A(17)); + assert_eq!(vec![17], v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-in-fn.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-in-fn.rs new file mode 100644 index 000000000000..0a7ea4ba81b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-in-fn.rs @@ -0,0 +1,11 @@ +// run-pass +pub fn main() { + #[derive(Debug)] + struct Foo { + foo: isize, + } + + let f = Foo { foo: 10 }; + format!("{:?}", f); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-in-macro.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-in-macro.rs new file mode 100644 index 000000000000..44c7eb63ee4c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-in-macro.rs @@ -0,0 +1,17 @@ +// run-pass +// pretty-expanded FIXME #23616 +#![allow(non_camel_case_types)] + +macro_rules! define_vec { + () => ( + mod foo { + #[derive(PartialEq)] + pub struct bar; + } + ) +} + +define_vec![]; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-meta-multiple.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-meta-multiple.rs new file mode 100644 index 000000000000..59514ccd4252 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-meta-multiple.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(unused_imports)] +// pretty-expanded FIXME #23616 +#![allow(deprecated)] + +use std::hash::{Hash, SipHasher}; + +// testing multiple separate deriving attributes +#[derive(PartialEq)] +#[derive(Clone)] +#[derive(Hash)] +struct Foo { + bar: usize, + baz: isize +} + +fn hash(_t: &T) {} + +pub fn main() { + let a = Foo {bar: 4, baz: -3}; + + a == a; // check for PartialEq impl w/o testing its correctness + a.clone(); // check for Clone impl w/o testing its correctness + hash(&a); // check for Hash impl w/o testing its correctness +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-meta.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-meta.rs new file mode 100644 index 000000000000..a1f41a3cadb5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-meta.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(unused_imports)] +// pretty-expanded FIXME #23616 +#![allow(deprecated)] + +use std::hash::{Hash, SipHasher}; + +#[derive(PartialEq, Clone, Hash)] +struct Foo { + bar: usize, + baz: isize +} + +fn hash(_t: &T) {} + +pub fn main() { + let a = Foo {bar: 4, baz: -3}; + + a == a; // check for PartialEq impl w/o testing its correctness + a.clone(); // check for Clone impl w/o testing its correctness + hash(&a); // check for Hash impl w/o testing its correctness +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs new file mode 100644 index 000000000000..946fb73a69f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-self-lifetime-totalord-totaleq.rs @@ -0,0 +1,17 @@ +// run-pass +use std::cmp::Ordering::{Less,Equal,Greater}; + +#[derive(PartialEq, Eq, PartialOrd, Ord)] +struct A<'a> { + x: &'a isize +} +pub fn main() { + let (a, b) = (A { x: &1 }, A { x: &2 }); + + assert_eq!(a.cmp(&a), Equal); + assert_eq!(b.cmp(&b), Equal); + + assert_eq!(a.cmp(&b), Less); + assert_eq!(b.cmp(&a), Greater); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-show-2.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-show-2.rs new file mode 100644 index 000000000000..94d015855ecf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-show-2.rs @@ -0,0 +1,55 @@ +// run-pass +#![allow(dead_code)] +use std::fmt; + +#[derive(Debug)] +enum A {} +#[derive(Debug)] +enum B { B1, B2, B3 } +#[derive(Debug)] +enum C { C1(isize), C2(B), C3(String) } +#[derive(Debug)] +enum D { D1{ a: isize } } +#[derive(Debug)] +struct E; +#[derive(Debug)] +struct F(isize); +#[derive(Debug)] +struct G(isize, isize); +#[derive(Debug)] +struct H { a: isize } +#[derive(Debug)] +struct I { a: isize, b: isize } +#[derive(Debug)] +struct J(Custom); + +struct Custom; +impl fmt::Debug for Custom { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "yay") + } +} + +trait ToDebug { + fn to_show(&self) -> String; +} + +impl ToDebug for T { + fn to_show(&self) -> String { + format!("{:?}", self) + } +} + +pub fn main() { + assert_eq!(B::B1.to_show(), "B1".to_string()); + assert_eq!(B::B2.to_show(), "B2".to_string()); + assert_eq!(C::C1(3).to_show(), "C1(3)".to_string()); + assert_eq!(C::C2(B::B2).to_show(), "C2(B2)".to_string()); + assert_eq!(D::D1{ a: 2 }.to_show(), "D1 { a: 2 }".to_string()); + assert_eq!(E.to_show(), "E".to_string()); + assert_eq!(F(3).to_show(), "F(3)".to_string()); + assert_eq!(G(3, 4).to_show(), "G(3, 4)".to_string()); + assert_eq!(I{ a: 2, b: 4 }.to_show(), "I { a: 2, b: 4 }".to_string()); + assert_eq!(J(Custom).to_show(), "J(yay)".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-show.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-show.rs new file mode 100644 index 000000000000..0926ba0c8bea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-show.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(dead_code)] +#[derive(Debug)] +struct Unit; + +#[derive(Debug)] +struct Tuple(isize, usize); + +#[derive(Debug)] +struct Struct { x: isize, y: usize } + +#[derive(Debug)] +enum Enum { + Nullary, + Variant(isize, usize), + StructVariant { x: isize, y : usize } +} + +#[derive(Debug)] +struct Pointers(*const dyn Send, *mut dyn Sync); + +macro_rules! t { + ($x:expr, $expected:expr) => { + assert_eq!(format!("{:?}", $x), $expected.to_string()) + } +} + +pub fn main() { + t!(Unit, "Unit"); + t!(Tuple(1, 2), "Tuple(1, 2)"); + t!(Struct { x: 1, y: 2 }, "Struct { x: 1, y: 2 }"); + t!(Enum::Nullary, "Nullary"); + t!(Enum::Variant(1, 2), "Variant(1, 2)"); + t!(Enum::StructVariant { x: 1, y: 2 }, "StructVariant { x: 1, y: 2 }"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-c-enum.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-c-enum.rs new file mode 100644 index 000000000000..37c026454220 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-c-enum.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +#[derive(PartialEq, Debug)] +enum Foo { + Bar, + Baz, + Boo +} + +pub fn main() { + let a = Foo::Bar; + let b = Foo::Bar; + assert_eq!(a, b); + assert!(!(a != b)); + assert!(a.eq(&b)); + assert!(!a.ne(&b)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-enum.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-enum.rs new file mode 100644 index 000000000000..c21619759632 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-enum.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] +#[derive(PartialEq, Debug)] +enum Foo { + Bar(isize, isize), + Baz(f64, f64) +} + +pub fn main() { + let a = Foo::Bar(1, 2); + let b = Foo::Bar(1, 2); + assert_eq!(a, b); + assert!(!(a != b)); + assert!(a.eq(&b)); + assert!(!a.ne(&b)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-hash-enum.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-hash-enum.rs new file mode 100644 index 000000000000..9fae7cda9271 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-hash-enum.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +#[derive(Hash)] +enum Foo { + Bar(isize, char), + Baz(char, isize) +} + +#[derive(Hash)] +enum A { + B, + C, + D, + E +} + +pub fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-hash-struct.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-hash-struct.rs new file mode 100644 index 000000000000..df52e5c0d411 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-hash-struct.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#[derive(Hash)] +struct Foo { + x: isize, + y: isize, + z: isize +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct-empty.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct-empty.rs new file mode 100644 index 000000000000..7da9b956791f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct-empty.rs @@ -0,0 +1,9 @@ +// run-pass +#[derive(PartialEq, Debug)] +struct Foo; + +pub fn main() { + assert_eq!(Foo, Foo); + assert!(!(Foo != Foo)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs new file mode 100644 index 000000000000..f0c71ae8c52b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct-like-enum-variant.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +#[derive(PartialEq, Debug)] +enum S { + X { x: isize, y: isize }, + Y +} + +pub fn main() { + let x = S::X { x: 1, y: 2 }; + assert_eq!(x, x); + assert!(!(x != x)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct-tuple.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct-tuple.rs new file mode 100644 index 000000000000..1c17b966d7f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct-tuple.rs @@ -0,0 +1,18 @@ +// run-pass +#[derive(PartialEq, Debug)] +struct Foo(isize, isize, String); + +pub fn main() { + let a1 = Foo(5, 6, "abc".to_string()); + let a2 = Foo(5, 6, "abc".to_string()); + let b = Foo(5, 7, "def".to_string()); + + assert_eq!(a1, a1); + assert_eq!(a2, a1); + assert!(!(a1 == b)); + + assert!(a1 != b); + assert!(!(a1 != a1)); + assert!(!(a2 != a1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct.rs new file mode 100644 index 000000000000..8c872364995b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-struct.rs @@ -0,0 +1,17 @@ +// run-pass +#[derive(PartialEq, Debug)] +struct Foo { + x: isize, + y: isize, + z: isize, +} + +pub fn main() { + let a = Foo { x: 1, y: 2, z: 3 }; + let b = Foo { x: 1, y: 2, z: 3 }; + assert_eq!(a, b); + assert!(!(a != b)); + assert!(a.eq(&b)); + assert!(!a.ne(&b)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-type-params.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-type-params.rs new file mode 100644 index 000000000000..825dba34d0de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-via-extension-type-params.rs @@ -0,0 +1,17 @@ +// run-pass +#[derive(PartialEq, Hash, Debug)] +struct Foo { + x: isize, + y: T, + z: isize +} + +pub fn main() { + let a = Foo { x: 1, y: 2.0f64, z: 3 }; + let b = Foo { x: 1, y: 2.0f64, z: 3 }; + assert_eq!(a, b); + assert!(!(a != b)); + assert!(a.eq(&b)); + assert!(!a.ne(&b)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/deriving/deriving-with-repr-packed.rs b/gcc/testsuite/rust/rustc/ui/deriving/deriving-with-repr-packed.rs new file mode 100644 index 000000000000..321579ad6cdd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/deriving/deriving-with-repr-packed.rs @@ -0,0 +1,37 @@ +// run-pass +// check that derive on a packed struct does not call field +// methods with a misaligned field. + +use std::mem; + +#[derive(Copy, Clone)] +struct Aligned(usize); + +#[inline(never)] +fn check_align(ptr: *const Aligned) { + assert_eq!(ptr as usize % mem::align_of::(), + 0); +} + +impl PartialEq for Aligned { + fn eq(&self, other: &Self) -> bool { + check_align(self); + check_align(other); + self.0 == other.0 + } +} + +#[repr(packed)] +#[derive(Copy, Clone, PartialEq)] +struct Packed(Aligned, Aligned); + +#[derive(PartialEq)] +#[repr(C)] +struct Dealigned(u8, T); + +fn main() { + let d1 = Dealigned(0, Packed(Aligned(1), Aligned(2))); + let ck = d1 == d1; + assert!(ck); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dest-prop/skeptic-miscompile.rs b/gcc/testsuite/rust/rustc/ui/dest-prop/skeptic-miscompile.rs new file mode 100644 index 000000000000..21b4452067eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dest-prop/skeptic-miscompile.rs @@ -0,0 +1,25 @@ +// run-pass + +// compile-flags: -Zmir-opt-level=2 + +trait IterExt: Iterator { + fn fold_ex(mut self, init: B, mut f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B, + { + let mut accum = init; + while let Some(x) = self.next() { + accum = f(accum, x); + } + accum + } +} + +impl IterExt for T {} + +fn main() { + let test = &["\n"]; + test.iter().fold_ex(String::new(), |_, b| b.to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructure-trait-ref.rs b/gcc/testsuite/rust/rustc/ui/destructure-trait-ref.rs new file mode 100644 index 000000000000..e5f86d7e94df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructure-trait-ref.rs @@ -0,0 +1,45 @@ +// The regression test for #15031 to make sure destructuring trait +// reference work properly. + +#![feature(box_patterns)] +#![feature(box_syntax)] + +trait T { fn foo(&self) {} } +impl T for isize {} + +fn main() { + // For an expression of the form: + // + // let &...&x = &..&SomeTrait; + // + // Say we have n `&` at the left hand and m `&` right hand, then: + // if n < m, we are golden; + // if n == m, it's a derefing non-derefable type error; + // if n > m, it's a type mismatch error. + + // n < m + let &x = &(&1isize as &dyn T); + let &x = &&(&1isize as &dyn T); + let &&x = &&(&1isize as &dyn T); + + // n == m + let &x = &1isize as &dyn T; // { dg-error ".E0033." "" { target *-*-* } } + let &&x = &(&1isize as &dyn T); // { dg-error ".E0033." "" { target *-*-* } } + let box x = box 1isize as Box; +// { dg-error ".E0033." "" { target *-*-* } .-1 } + + // n > m + let &&x = &1isize as &dyn T; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + let &&&x = &(&1isize as &dyn T); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + let box box x = box 1isize as Box; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/default-match-bindings-forbidden.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/default-match-bindings-forbidden.rs new file mode 100644 index 000000000000..98abd7c0b621 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/default-match-bindings-forbidden.rs @@ -0,0 +1,8 @@ +#![feature(destructuring_assignment)] + +fn main() { + let mut x = &0; + let mut y = &0; + (x, y) = &(1, 2); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/nested_destructure.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/nested_destructure.rs new file mode 100644 index 000000000000..5330a38a6821 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/nested_destructure.rs @@ -0,0 +1,18 @@ +// run-pass + +#![feature(destructuring_assignment)] + +struct Struct { + a: S, + b: T, +} + +struct TupleStruct(S, T); + +fn main() { + let (a, b, c, d); + Struct { a: TupleStruct((a, b), c), b: [d] } = + Struct { a: TupleStruct((0, 1), 2), b: [3] }; + assert_eq!((a, b, c, d), (0, 1, 2, 3)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/note-unsupported.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/note-unsupported.rs new file mode 100644 index 000000000000..2457abb286e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/note-unsupported.rs @@ -0,0 +1,28 @@ +struct S { x: u8, y: u8 } + +fn main() { + let (a, b) = (1, 2); + + (a, b) = (3, 4); // { dg-error ".E0658." "" { target *-*-* } } + (a, b) += (3, 4); // { dg-error ".E0067." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + [a, b] = [3, 4]; // { dg-error ".E0658." "" { target *-*-* } } + [a, b] += [3, 4]; // { dg-error ".E0067." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + let s = S { x: 3, y: 4 }; + + S { x: a, y: b } = s; // { dg-error ".E0658." "" { target *-*-* } } + S { x: a, y: b } += s; // { dg-error ".E0067." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + S { x: a, ..s } = S { x: 3, y: 4 }; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + let c = 3; + + ((a, b), c) = ((3, 4), 5); // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/slice_destructure.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/slice_destructure.rs new file mode 100644 index 000000000000..f2f13522e6c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/slice_destructure.rs @@ -0,0 +1,16 @@ +// run-pass + +#![feature(destructuring_assignment)] + +fn main() { + let (mut a, mut b); + [a, b] = [0, 1]; + assert_eq!((a, b), (0, 1)); + let mut c; + [a, .., b, c] = [1, 2, 3, 4, 5]; + assert_eq!((a, b, c), (1, 4, 5)); + [..] = [1, 2, 3]; + [c, ..] = [5, 6, 6]; + assert_eq!(c, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/slice_destructure_fail.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/slice_destructure_fail.rs new file mode 100644 index 000000000000..a8ca017bcc30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/slice_destructure_fail.rs @@ -0,0 +1,8 @@ +#![feature(destructuring_assignment)] + +fn main() { + let (mut a, mut b); + [a, .., b, ..] = [0, 1]; // { dg-error "" "" { target *-*-* } } + [a, a, b] = [1, 2]; // { dg-error ".E0527." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/struct_destructure.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/struct_destructure.rs new file mode 100644 index 000000000000..61f11e6351b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/struct_destructure.rs @@ -0,0 +1,20 @@ +// run-pass + +#![feature(destructuring_assignment)] +struct Struct { + a: S, + b: T, +} + +fn main() { + let (mut a, mut b); + Struct { a, b } = Struct { a: 0, b: 1 }; + assert_eq!((a, b), (0, 1)); + Struct { a: b, b: a } = Struct { a: 1, b: 2 }; + assert_eq!((a,b), (2, 1)); + Struct { a, .. } = Struct { a: 1, b: 3 }; + assert_eq!((a, b), (1, 1)); + Struct { .. } = Struct { a: 1, b: 4 }; + assert_eq!((a, b), (1, 1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/struct_destructure_fail.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/struct_destructure_fail.rs new file mode 100644 index 000000000000..ef5647e40a6c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/struct_destructure_fail.rs @@ -0,0 +1,16 @@ +#![feature(destructuring_assignment)] +struct Struct { + a: S, + b: T, +} + +fn main() { + let (mut a, b); + let mut c; + let d = Struct { a: 0, b: 1 }; + Struct { a, b, c } = Struct { a: 0, b: 1 }; // { dg-error ".E0026." "" { target *-*-* } } + Struct { a, ..d } = Struct { a: 1, b: 2 }; +// { dg-error "" "" { target *-*-* } .-1 } + Struct { a, .. }; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_destructure.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_destructure.rs new file mode 100644 index 000000000000..dd2403b089e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_destructure.rs @@ -0,0 +1,38 @@ +// run-pass + +#![feature(destructuring_assignment)] + +fn main() { + let (mut a, mut b); + (a, b) = (0, 1); + assert_eq!((a, b), (0, 1)); + (b, a) = (a, b); + assert_eq!((a, b), (1, 0)); + (a, .., b) = (1, 2); + assert_eq!((a, b), (1, 2)); + (.., a) = (1, 2); + assert_eq!((a, b), (2, 2)); + (..) = (3, 4); + assert_eq!((a, b), (2, 2)); + (b, ..) = (5, 6, 7); + assert_eq!(b, 5); + + // Test for a non-Copy type (String): + let (mut c, mut d); + (c, d) = ("c".to_owned(), "d".to_owned()); + assert_eq!(c, "c"); + assert_eq!(d, "d"); + (d, c) = (c, d); + assert_eq!(c, "d"); + assert_eq!(d, "c"); + + // Test nesting/parentheses: + ((a, b)) = (0, 1); + assert_eq!((a, b), (0, 1)); + (((a, b)), (c)) = ((2, 3), d); + assert_eq!((a, b), (2, 3)); + assert_eq!(c, "c"); + ((a, .., b), .., (..)) = ((4, 5), ()); + assert_eq!((a, b), (4, 5)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_destructure_fail.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_destructure_fail.rs new file mode 100644 index 000000000000..e2aa9e63ae35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_destructure_fail.rs @@ -0,0 +1,11 @@ +#![feature(destructuring_assignment)] + +const C: i32 = 1; + +fn main() { + let (mut a, mut b); + (a, .., b, ..) = (0, 1); // { dg-error "" "" { target *-*-* } } + (a, a, b) = (1, 2); // { dg-error ".E0308." "" { target *-*-* } } + (C, ..) = (0,1); // { dg-error ".E0070." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_struct_destructure.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_struct_destructure.rs new file mode 100644 index 000000000000..972afff0a8b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_struct_destructure.rs @@ -0,0 +1,35 @@ +// run-pass + +#![feature(destructuring_assignment)] + +struct TupleStruct(S, T); + +impl TupleStruct { + fn assign(self, first: &mut S, second: &mut T) { + // Test usage of `Self` instead of the struct name: + Self(*first, *second) = self + } +} + +enum Enum { + SingleVariant(S, T) +} + +type Alias = Enum; + +fn main() { + let (mut a, mut b); + TupleStruct(a, b) = TupleStruct(0, 1); + assert_eq!((a, b), (0, 1)); + TupleStruct(a, .., b) = TupleStruct(1, 2); + assert_eq!((a, b), (1, 2)); + TupleStruct(..) = TupleStruct(3, 4); + assert_eq!((a, b), (1, 2)); + TupleStruct(5,6).assign(&mut a, &mut b); + assert_eq!((a, b), (5, 6)); + Enum::SingleVariant(a, b) = Enum::SingleVariant(7, 8); + assert_eq!((a, b), (7, 8)); + Alias::SingleVariant(a, b) = Alias::SingleVariant(9, 10); + assert_eq!((a, b), (9, 10)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_struct_destructure_fail.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_struct_destructure_fail.rs new file mode 100644 index 000000000000..387c7d98d5a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/tuple_struct_destructure_fail.rs @@ -0,0 +1,43 @@ +#![feature(destructuring_assignment)] + +struct TupleStruct(S, T); + +enum Enum { + SingleVariant(S, T) +} + +type Alias = Enum; + +trait Test { + fn test() -> TupleStruct { + TupleStruct(0, 0) + } +} + +impl Test for Alias {} + +fn test() -> TupleStruct { + TupleStruct(0, 0) +} + +fn main() { + let (mut a, mut b); + TupleStruct(a, .., b, ..) = TupleStruct(0, 1); +// { dg-error "" "" { target *-*-* } .-1 } + Enum::SingleVariant(a, .., b, ..) = Enum::SingleVariant(0, 1); +// { dg-error "" "" { target *-*-* } .-1 } + + TupleStruct(a, a, b) = TupleStruct(1, 2); +// { dg-error ".E0023." "" { target *-*-* } .-1 } + Enum::SingleVariant(a, a, b) = Enum::SingleVariant(1, 2); +// { dg-error ".E0023." "" { target *-*-* } .-1 } + + // Check if `test` is recognized as not a tuple struct but a function call: + test() = TupleStruct(0, 0); +// { dg-error ".E0070." "" { target *-*-* } .-1 } + (test)() = TupleStruct(0, 0); +// { dg-error ".E0070." "" { target *-*-* } .-1 } + as Test>::test() = TupleStruct(0, 0); +// { dg-error ".E0070." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/underscore-range-expr-gating.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/underscore-range-expr-gating.rs new file mode 100644 index 000000000000..8cd3b9e48c23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/underscore-range-expr-gating.rs @@ -0,0 +1,9 @@ +fn main() {} + +struct S { x : u32 } + +#[cfg(FALSE)] +fn foo() { + S { x: 5, .. }; // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/destructuring-assignment/warn-unused-duplication.rs b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/warn-unused-duplication.rs new file mode 100644 index 000000000000..8085bed205ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/destructuring-assignment/warn-unused-duplication.rs @@ -0,0 +1,24 @@ +// run-pass + +#![feature(destructuring_assignment)] + +#![warn(unused_assignments)] + +fn main() { + let mut a; + // Assignment occurs left-to-right. + // However, we emit warnings when this happens, so it is clear that this is happening. + (a, a) = (0, 1); // { dg-warning "" "" { target *-*-* } } + assert_eq!(a, 1); + + // We can't always tell when a variable is being assigned to twice, which is why we don't try + // to emit an error, which would be fallible. + let mut x = 1; + (*foo(&mut x), *foo(&mut x)) = (5, 6); + assert_eq!(x, 6); +} + +fn foo<'a>(x: &'a mut u32) -> &'a mut u32 { + x +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/E0178.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/E0178.rs new file mode 100644 index 000000000000..9f6add52ab49 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/E0178.rs @@ -0,0 +1,14 @@ +#![allow(bare_trait_objects)] + +trait Foo {} + +struct Bar<'a> { + w: &'a Foo + Copy, // { dg-error ".E0178." "" { target *-*-* } } + x: &'a Foo + 'a, // { dg-error ".E0178." "" { target *-*-* } } + y: &'a mut Foo + 'a, // { dg-error ".E0178." "" { target *-*-* } } + z: fn() -> Foo + 'a, // { dg-error ".E0178." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/bad-assoc-expr.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/bad-assoc-expr.rs new file mode 100644 index 000000000000..a2e2a3f8f285 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/bad-assoc-expr.rs @@ -0,0 +1,37 @@ +fn main() { + let a = [1, 2, 3, 4]; + [i32; 4]::clone(&a); +// { dg-error "" "" { target *-*-* } .-1 } + + [i32]::as_ref(&a); +// { dg-error "" "" { target *-*-* } .-1 } + + (u8)::clone(&0); +// { dg-error "" "" { target *-*-* } .-1 } + + (u8, u8)::clone(&(0, 0)); +// { dg-error "" "" { target *-*-* } .-1 } + + &(u8)::clone(&0); +// { dg-error "" "" { target *-*-* } .-1 } + + 10 + (u8)::clone(&0); +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! expr { + ($ty: ty) => ($ty::clone(&0)) +// { dg-error "" "" { target *-*-* } .-1 } +} +macro_rules! ty { + () => (u8) +} + +fn check_macros() { + expr!(u8); + let _ = ty!()::clone(&0); +// { dg-error "" "" { target *-*-* } .-1 } + ty!()::clone(&0); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/bad-assoc-pat.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/bad-assoc-pat.rs new file mode 100644 index 000000000000..1c86698cdeca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/bad-assoc-pat.rs @@ -0,0 +1,37 @@ +fn main() { + match 0u8 { + [u8]::AssocItem => {} +// { dg-error ".E0599." "" { target *-*-* } .-1 } +// { dg-error ".E0599." "" { target *-*-* } .-2 } + (u8, u8)::AssocItem => {} +// { dg-error ".E0599." "" { target *-*-* } .-1 } +// { dg-error ".E0599." "" { target *-*-* } .-2 } + _::AssocItem => {} +// { dg-error ".E0599." "" { target *-*-* } .-1 } +// { dg-error ".E0599." "" { target *-*-* } .-2 } + } + match &0u8 { + &(u8,)::AssocItem => {} +// { dg-error ".E0599." "" { target *-*-* } .-1 } +// { dg-error ".E0599." "" { target *-*-* } .-2 } + } +} + +macro_rules! pat { + ($ty: ty) => ($ty::AssocItem) +// { dg-error ".E0599." "" { target *-*-* } .-1 } +// { dg-error ".E0599." "" { target *-*-* } .-2 } +} +macro_rules! ty { + () => (u8) +} + +fn check_macros() { + match 0u8 { + pat!(u8) => {} + ty!()::AssocItem => {} +// { dg-error ".E0599." "" { target *-*-* } .-1 } +// { dg-error ".E0599." "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/bad-assoc-ty.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/bad-assoc-ty.rs new file mode 100644 index 000000000000..53249c732d2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/bad-assoc-ty.rs @@ -0,0 +1,84 @@ +type A = [u8; 4]::AssocTy; +// { dg-error ".E0223." "" { target *-*-* } .-1 } +// { dg-error ".E0223." "" { target *-*-* } .-2 } + +type B = [u8]::AssocTy; +// { dg-error ".E0223." "" { target *-*-* } .-1 } +// { dg-error ".E0223." "" { target *-*-* } .-2 } + +type C = (u8)::AssocTy; +// { dg-error ".E0223." "" { target *-*-* } .-1 } +// { dg-error ".E0223." "" { target *-*-* } .-2 } + +type D = (u8, u8)::AssocTy; +// { dg-error ".E0223." "" { target *-*-* } .-1 } +// { dg-error ".E0223." "" { target *-*-* } .-2 } + +type E = _::AssocTy; +// { dg-error ".E0121." "" { target *-*-* } .-1 } +// { dg-error ".E0121." "" { target *-*-* } .-2 } + +type F = &'static (u8)::AssocTy; +// { dg-error ".E0223." "" { target *-*-* } .-1 } +// { dg-error ".E0223." "" { target *-*-* } .-2 } + +// Qualified paths cannot appear in bounds, so the recovery +// should apply to the whole sum and not `(Send)`. +type G = dyn 'static + (Send)::AssocTy; +// { dg-error ".E0223." "" { target *-*-* } .-1 } +// { dg-error ".E0223." "" { target *-*-* } .-2 } + +// This is actually a legal path with fn-like generic arguments in the middle! +// Recovery should not apply in this context. +type H = Fn(u8) -> (u8)::Output; +// { dg-error ".E0223." "" { target *-*-* } .-1 } + +macro_rules! ty { + ($ty: ty) => ($ty::AssocTy); +// { dg-error ".E0223." "" { target *-*-* } .-1 } +// { dg-error ".E0223." "" { target *-*-* } .-2 } + () => (u8); +} + +type J = ty!(u8); +type I = ty!()::AssocTy; +// { dg-error ".E0223." "" { target *-*-* } .-1 } +// { dg-error ".E0223." "" { target *-*-* } .-2 } + +trait K {} +fn foo>(x: X) {} +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +fn bar(_: F) where F: Fn() -> _ {} +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +fn baz _>(_: F) {} +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +struct L(F) where F: Fn() -> _; +// { dg-error ".E0121." "" { target *-*-* } .-1 } +struct M where F: Fn() -> _ { +// { dg-error ".E0121." "" { target *-*-* } .-1 } + a: F, +} +enum N where F: Fn() -> _ { +// { dg-error ".E0121." "" { target *-*-* } .-1 } + Foo(F), +} + +union O where F: Fn() -> _ { +// { dg-error ".E0121." "" { target *-*-* } .-1 } + foo: F, +} + +trait P where F: Fn() -> _ { +// { dg-error ".E0121." "" { target *-*-* } .-1 } +} + +trait Q { + fn foo(_: F) where F: Fn() -> _ {} +// { dg-error ".E0121." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs new file mode 100644 index 000000000000..b78c162f59fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.rs @@ -0,0 +1,27 @@ +trait Foo { + fn foo(&self, a: A) -> A { + a + } +} + +trait NotRelevant { + fn nr(&self, a: A) -> A { + a + } +} + +struct Bar; + +impl Foo for Bar {} + +impl Foo for Bar {} + +impl NotRelevant for Bar {} + +fn main() { + let f1 = Bar; + + f1.foo(1usize); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs new file mode 100644 index 000000000000..760e8c5ecc68 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.rs @@ -0,0 +1,31 @@ +trait Foo { + fn foo(&self, a: A) -> A { + a + } +} + +trait NotRelevant { + fn nr(&self, a: A) -> A { + a + } +} + +struct Bar; + +impl Foo for Bar {} +impl Foo for Bar {} +impl Foo for Bar {} + +impl Foo for Bar {} +impl Foo for Bar {} +impl Foo for Bar {} + +impl NotRelevant for Bar {} + +fn main() { + let f1 = Bar; + + f1.foo(1usize); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-31424.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-31424.rs new file mode 100644 index 000000000000..7cdf3de8fb38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-31424.rs @@ -0,0 +1,19 @@ +// forbid-output: &mut mut self + +struct Struct; + +impl Struct { + fn foo(&mut self) { + (&mut self).bar(); // { dg-error ".E0596." "" { target *-*-* } } + } + + // In this case we could keep the suggestion, but to distinguish the + // two cases is pretty hard. It's an obscure case anyway. + fn bar(self: &mut Self) { +// { dg-warning "" "" { target *-*-* } .-1 } + (&mut self).bar(); // { dg-error ".E0596." "" { target *-*-* } } + } +} + +fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-34126.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-34126.rs new file mode 100644 index 000000000000..4d366b76a911 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-34126.rs @@ -0,0 +1,15 @@ +struct Z { } + +impl Z { + fn run(&self, z: &mut Z) { } + fn start(&mut self) { + self.run(&mut self); // { dg-error ".E0502." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + } +} + +fn main() { + let mut z = Z {}; + z.start(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-34337.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-34337.rs new file mode 100644 index 000000000000..3b6ed2ed9084 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-34337.rs @@ -0,0 +1,8 @@ +fn get(key: &mut String) { } + +fn main() { + let mut v: Vec = Vec::new(); + let ref mut key = v[0]; + get(&mut key); // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-35937.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-35937.rs new file mode 100644 index 000000000000..4329b48503d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-35937.rs @@ -0,0 +1,22 @@ +struct Foo { + pub v: Vec +} + +fn main() { + let f = Foo { v: Vec::new() }; + f.v.push("cat".to_string()); // { dg-error ".E0596." "" { target *-*-* } } +} + + +struct S { + x: i32, +} +fn foo() { + let s = S { x: 42 }; + s.x += 1; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn bar(s: S) { + s.x += 1; // { dg-error ".E0594." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-36798.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-36798.rs new file mode 100644 index 000000000000..ad54eedc0fa7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-36798.rs @@ -0,0 +1,9 @@ +struct Foo { + bar: u8 +} + +fn main() { + let f = Foo { bar: 22 }; + f.baz; // { dg-error ".E0609." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-36798_unknown_field.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-36798_unknown_field.rs new file mode 100644 index 000000000000..c3dd08266eb8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-36798_unknown_field.rs @@ -0,0 +1,9 @@ +struct Foo { + bar: u8 +} + +fn main() { + let f = Foo { bar: 22 }; + f.zz; // { dg-error ".E0609." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-37139.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-37139.rs new file mode 100644 index 000000000000..a4ba49c1f5ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-37139.rs @@ -0,0 +1,16 @@ +enum TestEnum { + Item(i32), +} + +fn test(_: &mut i32) { +} + +fn main() { + let mut x = TestEnum::Item(10); + match x { + TestEnum::Item(ref mut x) => { + test(&mut x); // { dg-error ".E0596." "" { target *-*-* } } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs new file mode 100644 index 000000000000..64aafc000877 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.rs @@ -0,0 +1,6 @@ +use Foo; // { dg-error ".E0432." "" { target *-*-* } } + +use Foo1; // { dg-error ".E0432." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-1.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-1.rs new file mode 100644 index 000000000000..b207ad45394c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-1.rs @@ -0,0 +1,22 @@ +struct Pass<'a> { + s: &'a mut String +} + +impl<'a> Pass<'a> { + fn f(&mut self) { + self.s.push('x'); + } +} + +struct Foo<'a> { + s: &'a mut String +} + +impl<'a> Foo<'a> { + fn f(&self) { + self.s.push('x'); // { dg-error ".E0596." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-2.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-2.rs new file mode 100644 index 000000000000..1206aa54aa8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-2.rs @@ -0,0 +1,13 @@ +struct Bar<'a> { + s: &'a String +} + +impl<'a> Bar<'a> { + fn f(&mut self) { + self.s.push('x'); +// { dg-error ".E0596." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-3.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-3.rs new file mode 100644 index 000000000000..67fa9d0893dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-3.rs @@ -0,0 +1,13 @@ +struct Qux<'a> { + s: &'a String +} + +impl<'a> Qux<'a> { + fn f(&self) { + self.s.push('x'); +// { dg-error ".E0596." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-4.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-4.rs new file mode 100644 index 000000000000..81340bb8f833 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-38147-4.rs @@ -0,0 +1,10 @@ +struct Foo<'a> { + s: &'a mut String +} + +fn f(x: usize, f: &Foo) { + f.s.push('x'); // { dg-error ".E0596." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-39544.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-39544.rs new file mode 100644 index 000000000000..3665dd22821a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-39544.rs @@ -0,0 +1,51 @@ +pub enum X { + Y +} + +pub struct Z { + x: X +} + +fn main() { + let z = Z { x: X::Y }; + let _ = &mut z.x; // { dg-error ".E0596." "" { target *-*-* } } +} + +impl Z { + fn foo<'z>(&'z self) { + let _ = &mut self.x; // { dg-error ".E0596." "" { target *-*-* } } + } + + fn foo1(&self, other: &Z) { + let _ = &mut self.x; // { dg-error ".E0596." "" { target *-*-* } } + let _ = &mut other.x; // { dg-error ".E0596." "" { target *-*-* } } + } + + fn foo2<'a>(&'a self, other: &Z) { + let _ = &mut self.x; // { dg-error ".E0596." "" { target *-*-* } } + let _ = &mut other.x; // { dg-error ".E0596." "" { target *-*-* } } + } + + fn foo3<'a>(self: &'a Self, other: &Z) { + let _ = &mut self.x; // { dg-error ".E0596." "" { target *-*-* } } + let _ = &mut other.x; // { dg-error ".E0596." "" { target *-*-* } } + } + + fn foo4(other: &Z) { + let _ = &mut other.x; // { dg-error ".E0596." "" { target *-*-* } } + } + +} + +pub fn with_arg(z: Z, w: &Z) { + let _ = &mut z.x; // { dg-error ".E0596." "" { target *-*-* } } + let _ = &mut w.x; // { dg-error ".E0596." "" { target *-*-* } } +} + +pub fn with_tuple() { + let mut y = 0; + let x = (&y,); + *x.0 = 1; +// { dg-error ".E0594." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-39802-show-5-trait-impls.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-39802-show-5-trait-impls.rs new file mode 100644 index 000000000000..8ec2b3c17cf8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-39802-show-5-trait-impls.rs @@ -0,0 +1,28 @@ +trait Foo { + fn bar(&self){} +} + +impl Foo for i8 {} +impl Foo for i8 {} +impl Foo for i8 {} +impl Foo for i8 {} +impl Foo for i8 {} + +impl Foo for u8 {} +impl Foo for u8 {} +impl Foo for u8 {} +impl Foo for u8 {} + +impl Foo for bool {} +impl Foo for bool {} +impl Foo for bool {} +impl Foo for bool {} +impl Foo for bool {} +impl Foo for bool {} + +fn main() { + Foo::::bar(&1i8); // { dg-error ".E0277." "" { target *-*-* } } + Foo::::bar(&1u8); // { dg-error ".E0277." "" { target *-*-* } } + Foo::::bar(&true); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-40006.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-40006.rs new file mode 100644 index 000000000000..56a950bd18a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-40006.rs @@ -0,0 +1,40 @@ +impl dyn A { + Y +} // { dg-error "" "" { target *-*-* } } + +struct S; + +trait X { + X() {} // { dg-error "" "" { target *-*-* } } + fn xxx() { ### } + L = M; + Z = { 2 + 3 }; + ::Y (); +} + +trait A { + X() {} // { dg-error "" "" { target *-*-* } } +} +trait B { + fn xxx() { ### } // { dg-error "" "" { target *-*-* } } +} +trait C { + L = M; // { dg-error "" "" { target *-*-* } } +} +trait D { + Z = { 2 + 3 }; // { dg-error "" "" { target *-*-* } } +} +trait E { + ::Y (); // { dg-error "" "" { target *-*-* } } +} + +impl S { + pub hello_method(&self) { // { dg-error "" "" { target *-*-* } } + println!("Hello"); + } +} + +fn main() { + S.hello_method(); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-40396.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-40396.rs new file mode 100644 index 000000000000..6d83fad1f2c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-40396.rs @@ -0,0 +1,30 @@ +fn main() { + (0..13).collect>(); +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + Vec::new(); +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + (0..13).collect(); +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + let x = std::collections::HashMap::new(); // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + let x: () = 42; // { dg-error ".E0308." "" { target *-*-* } } + let x = { + std::collections::HashMap::new() // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + }; + let x: () = 42; // { dg-error ".E0308." "" { target *-*-* } } + let x = { + std::collections::HashMap::new(); // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + let x: () = 42; // { dg-error ".E0308." "" { target *-*-* } } + }; + { + std::collections::HashMap::new(1, 2); // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + let x: () = 32; // { dg-error ".E0308." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-40823.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-40823.rs new file mode 100644 index 000000000000..b1f950a5a568 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-40823.rs @@ -0,0 +1,5 @@ +fn main() { + let mut buf = &[1, 2, 3, 4]; + buf.iter_mut(); // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs new file mode 100644 index 000000000000..1cf93052de16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs @@ -0,0 +1,6 @@ +// run-rustfix + +fn main() { + let _x = ~1; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-42599_available_fields_note.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-42599_available_fields_note.rs new file mode 100644 index 000000000000..5322ea83ae77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-42599_available_fields_note.rs @@ -0,0 +1,38 @@ +mod submodule { + + #[derive(Default)] + pub struct Demo { + pub favorite_integer: isize, + secret_integer: isize, + pub innocently_misspellable: (), + another_field: bool, + yet_another_field: bool, + always_more_fields: bool, + and_ever: bool, + } + + impl Demo { + fn new_with_secret_two() -> Self { + Self { secret_integer: 2, inocently_mispellable: () } +// { dg-error ".E0560." "" { target *-*-* } .-1 } + } + + fn new_with_secret_three() -> Self { + Self { secret_integer: 3, egregiously_nonexistent_field: () } +// { dg-error ".E0560." "" { target *-*-* } .-1 } + } + } + +} + +fn main() { + use submodule::Demo; + + let demo = Demo::default(); + let innocent_field_misaccess = demo.inocently_mispellable; +// { dg-error ".E0609." "" { target *-*-* } .-1 } + // note shouldn't suggest private fields + let egregious_field_misaccess = demo.egregiously_nonexistent_field; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-42764.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-42764.rs new file mode 100644 index 000000000000..7d2ede6dcd7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-42764.rs @@ -0,0 +1,30 @@ +enum DoubleOption { + FirstSome(T), + AlternativeSome(T), + Nothing, +} + +fn this_function_expects_a_double_option(d: DoubleOption) {} + +fn main() { + let n: usize = 42; + this_function_expects_a_double_option(n); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +} + + +// But don't issue the "try using a variant" help if the one-"variant" ADT is +// actually a one-field struct. + +struct Payload; + +struct Wrapper { payload: Payload } + +struct Context { wrapper: Wrapper } + +fn overton() { + let _c = Context { wrapper: Payload{} }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs new file mode 100644 index 000000000000..70afae178db1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs @@ -0,0 +1,37 @@ +enum Example { Ex(String), NotEx } + +enum Void {} + +enum ManyVariants { + One, + Two, + Three, + Four, + Five, + Six, + Seven, + Eight, + Nine, + Ten, +} + +fn result_test() { + let x = Option(1); // { dg-error ".E0423." "" { target *-*-* } } + + if let Option(_) = x { // { dg-error ".E0532." "" { target *-*-* } } + println!("It is OK."); + } + + let y = Example::Ex(String::from("test")); + + if let Example(_) = y { // { dg-error ".E0532." "" { target *-*-* } } + println!("It is OK."); + } + + let y = Void(); // { dg-error ".E0423." "" { target *-*-* } } + + let z = ManyVariants(); // { dg-error ".E0423." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.rs new file mode 100644 index 000000000000..72d954559024 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-46718-struct-pattern-dotdotdot.rs @@ -0,0 +1,18 @@ +#![allow(unused)] + +struct PersonalityInventory { + expressivity: f32, + instrumentality: f32 +} + +impl PersonalityInventory { + fn expressivity(&self) -> f32 { + match *self { + PersonalityInventory { expressivity: exp, ... } => exp +// { dg-error "" "" { target *-*-* } .-1 } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.rs new file mode 100644 index 000000000000..e54e33a907ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.rs @@ -0,0 +1,35 @@ +fn gratitude() { + let for_you = false; + if not for_you { +// { dg-error "" "" { target *-*-* } .-1 } + println!("I couldn't"); + } +} + +fn qualification() { + let the_worst = true; + while not the_worst { +// { dg-error "" "" { target *-*-* } .-1 } + println!("still pretty bad"); + } +} + +fn should_we() { + let not = true; + if not // lack of braces is [sic] + println!("Then when?"); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn sleepy() { + let resource = not 2; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + let be_smothered_out_before = true; + let young_souls = not be_smothered_out_before; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.rs new file mode 100644 index 000000000000..e2b7e9e8bd4f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.rs @@ -0,0 +1,88 @@ +#![allow(unused)] + +#[derive(Copy, Clone)] +enum Nucleotide { + Adenine, + Thymine, + Cytosine, + Guanine +} + +#[derive(Clone)] +struct Autosome; + +#[derive(Clone)] +enum Allosome { + X(Vec), + Y(Vec) +} + +impl Allosome { + fn is_x(&self) -> bool { + match *self { + Allosome::X(_) => true, + Allosome::Y(_) => false, + } + } +} + +#[derive(Clone)] +struct Genome { + autosomes: [Autosome; 22], + allosomes: (Allosome, Allosome) +} + +fn find_start_codon(strand: &[Nucleotide]) -> Option { + let mut reading_frame = strand.windows(3); + // (missing parentheses in `while let` tuple pattern) + while let b1, b2, b3 = reading_frame.next().expect("there should be a start codon") { +// { dg-error "" "" { target *-*-* } .-1 } + // ... + } + None +} + +fn find_thr(strand: &[Nucleotide]) -> Option { + let mut reading_frame = strand.windows(3); + let mut i = 0; + // (missing parentheses in `if let` tuple pattern) + if let b1, b2, b3 = reading_frame.next().unwrap() { +// { dg-error "" "" { target *-*-* } .-1 } + // ... + } + None +} + +fn is_thr(codon: (Nucleotide, Nucleotide, Nucleotide)) -> bool { + match codon { + // (missing parentheses in match arm tuple pattern) + Nucleotide::Adenine, Nucleotide::Cytosine, _ => true +// { dg-error "" "" { target *-*-* } .-1 } + _ => false + } +} + +fn analyze_female_sex_chromosomes(women: &[Genome]) { + // (missing parentheses in `for` tuple pattern) + for x, _barr_body in women.iter().map(|woman| woman.allosomes.clone()) { +// { dg-error "" "" { target *-*-* } .-1 } + // ... + } +} + +fn analyze_male_sex_chromosomes(men: &[Genome]) { + // (missing parentheses in pattern with `@` binding) + for x, y @ Allosome::Y(_) in men.iter().map(|man| man.allosomes.clone()) { +// { dg-error "" "" { target *-*-* } .-1 } + // ... + } +} + +fn main() { + let genomes = Vec::new(); + // (missing parentheses in `let` pattern) + let women, men: (Vec, Vec) = genomes.iter().cloned() +// { dg-error "" "" { target *-*-* } .-1 } + .partition(|g: &Genome| g.allosomes.0.is_x() && g.allosomes.1.is_x()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs new file mode 100644 index 000000000000..e759130c44ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs @@ -0,0 +1,7 @@ +const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.rs new file mode 100644 index 000000000000..44bef49d190f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-53280-expected-float-found-integer-literal.rs @@ -0,0 +1,20 @@ +fn main() { + let sixteen: f32 = 16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } + let a_million_and_seventy: f64 = 1_000_070; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } + let negative_nine: f32 = -9; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } + + + // only base-10 literals get the suggestion + + let sixteen_again: f64 = 0x10; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let and_once_more: f32 = 0o20; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs new file mode 100644 index 000000000000..2a55d1175849 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs @@ -0,0 +1,58 @@ +fn main() {} + +fn test_and() { + let a = true; + let b = false; + + let _ = a and b; // { dg-error "" "" { target *-*-* } } + + if a and b { // { dg-error "" "" { target *-*-* } } + println!("both"); + } + + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn test_or() { + let a = true; + let b = false; + + let _ = a or b; // { dg-error "" "" { target *-*-* } } + + if a or b { // { dg-error "" "" { target *-*-* } } + println!("both"); + } +} + +fn test_and_par() { + let a = true; + let b = false; + if (a and b) { // { dg-error "" "" { target *-*-* } } + println!("both"); + } +} + +fn test_or_par() { + let a = true; + let b = false; + if (a or b) { // { dg-error "" "" { target *-*-* } } + println!("both"); + } +} + +fn test_while_and() { + let a = true; + let b = false; + while a and b { // { dg-error "" "" { target *-*-* } } + println!("both"); + } +} + +fn test_while_or() { + let a = true; + let b = false; + while a or b { // { dg-error "" "" { target *-*-* } } + println!("both"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-54109-without-witness.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-54109-without-witness.rs new file mode 100644 index 000000000000..e6d9cec15b21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-54109-without-witness.rs @@ -0,0 +1,62 @@ +// run-rustfix + +// This test is to check if suggestions can be applied automatically. + +#![allow(dead_code, unused_parens)] + +fn main() {} + +fn test_and() { + let a = true; + let b = false; + + let _ = a and b; // { dg-error "" "" { target *-*-* } } + + if a and b { // { dg-error "" "" { target *-*-* } } + println!("both"); + } +} + +fn test_or() { + let a = true; + let b = false; + + let _ = a or b; // { dg-error "" "" { target *-*-* } } + + if a or b { // { dg-error "" "" { target *-*-* } } + println!("both"); + } +} + +fn test_and_par() { + let a = true; + let b = false; + if (a and b) { // { dg-error "" "" { target *-*-* } } + println!("both"); + } +} + +fn test_or_par() { + let a = true; + let b = false; + if (a or b) { // { dg-error "" "" { target *-*-* } } + println!("both"); + } +} + +fn test_while_and() { + let a = true; + let b = false; + while a and b { // { dg-error "" "" { target *-*-* } } + println!("both"); + } +} + +fn test_while_or() { + let a = true; + let b = false; + while a or b { // { dg-error "" "" { target *-*-* } } + println!("both"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs new file mode 100644 index 000000000000..0cbc7d6892e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/issue-56028-there-is-an-enum-variant.rs @@ -0,0 +1,16 @@ +enum PutDown { Set } +enum AffixHeart { Set } +enum CauseToBe { Set } +enum Determine { Set } +enum TableDishesAction { Set } +enum Solidify { Set } +enum UnorderedCollection { Set } + +fn setup() -> Set { Set } +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { dg-error ".E0425." "" { target *-*-* } .-2 } + +fn main() { + setup(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/pub-macro-rules.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/pub-macro-rules.rs new file mode 100644 index 000000000000..c9157cb7213a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/pub-macro-rules.rs @@ -0,0 +1,17 @@ +#[macro_use] mod bleh { + pub macro_rules! foo { // { dg-error "" "" { target *-*-* } } + ($n:ident) => ( + fn $n () -> i32 { + 1 + } + ) + } + +} + +foo!(meh); + +fn main() { + println!("{}", meh()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/recursion_limit.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/recursion_limit.rs new file mode 100644 index 000000000000..4c35d150f920 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/recursion_limit.rs @@ -0,0 +1,36 @@ +// Test that the recursion limit can be changed and that the compiler +// suggests a fix. In this case, we have deeply nested types that will +// fail the `Send` check by overflow when the recursion limit is set +// very low. + +#![allow(dead_code)] +#![recursion_limit="10"] + +macro_rules! link { + ($id:ident, $t:ty) => { + enum $id { $id($t) } + } +} + +link! { A, B } +link! { B, C } +link! { C, D } +link! { D, E } +link! { E, F } +link! { F, G } +link! { G, H } +link! { H, I } +link! { I, J } +link! { J, K } +link! { K, L } +link! { L, M } +link! { M, N } + +enum N { N(usize) } + +fn is_send() { } + +fn main() { + is_send::(); // { dg-error ".E0275." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/recursion_limit_deref.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/recursion_limit_deref.rs new file mode 100644 index 000000000000..f01c88449bc6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/recursion_limit_deref.rs @@ -0,0 +1,53 @@ +// Test that the recursion limit can be changed and that the compiler +// suggests a fix. In this case, we have a long chain of Deref impls +// which will cause an overflow during the autoderef loop. + +#![allow(dead_code)] +#![recursion_limit="10"] + +macro_rules! link { + ($outer:ident, $inner:ident) => { + struct $outer($inner); + + impl $outer { + fn new() -> $outer { + $outer($inner::new()) + } + } + + impl std::ops::Deref for $outer { + type Target = $inner; + + fn deref(&self) -> &$inner { + &self.0 + } + } + } +} + +struct Bottom; +impl Bottom { + fn new() -> Bottom { + Bottom + } +} + +link!(Top, A); +link!(A, B); +link!(B, C); +link!(C, D); +link!(D, E); +link!(E, F); +link!(F, G); +link!(G, H); +link!(H, I); +link!(I, J); +link!(J, K); +link!(K, Bottom); + +fn main() { + let t = Top::new(); + let x: &Bottom = &t; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/recursion_limit_macro.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/recursion_limit_macro.rs new file mode 100644 index 000000000000..4478121aa1b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/recursion_limit_macro.rs @@ -0,0 +1,16 @@ +// Test that the recursion limit can be changed and that the compiler +// suggests a fix. In this case, we have a recursing macro that will +// overflow if the number of arguments surpasses the recursion limit. + +#![allow(dead_code)] +#![recursion_limit="10"] + +macro_rules! recurse { + () => { }; + ($t:tt $($tail:tt)*) => { recurse!($($tail)*) }; // { dg-error "" "" { target *-*-* } } +} + +fn main() { + recurse!(0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9); +} + diff --git a/gcc/testsuite/rust/rustc/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs b/gcc/testsuite/rust/rustc/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs new file mode 100644 index 000000000000..895f9719acca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/did_you_mean/trait-object-reference-without-parens-suggestion.rs @@ -0,0 +1,8 @@ +#![allow(bare_trait_objects)] + +fn main() { + let _: &Copy + 'static; // { dg-error ".E0038." "" { target *-*-* } } +// { dg-error ".E0038." "" { target *-*-* } .-1 } + let _: &'static Copy + 'static; // { dg-error ".E0178." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/directory_ownership/foo/mod_file_not_owning/aux2.rs b/gcc/testsuite/rust/rustc/ui/directory_ownership/foo/mod_file_not_owning/aux2.rs new file mode 100644 index 000000000000..c84c7b394dc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/directory_ownership/foo/mod_file_not_owning/aux2.rs @@ -0,0 +1,2 @@ +// intentionally empty + diff --git a/gcc/testsuite/rust/rustc/ui/directory_ownership/foo/mod_file_not_owning_aux2.rs b/gcc/testsuite/rust/rustc/ui/directory_ownership/foo/mod_file_not_owning_aux2.rs new file mode 100644 index 000000000000..c84c7b394dc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/directory_ownership/foo/mod_file_not_owning_aux2.rs @@ -0,0 +1,2 @@ +// intentionally empty + diff --git a/gcc/testsuite/rust/rustc/ui/directory_ownership/macro-expanded-mod.rs b/gcc/testsuite/rust/rustc/ui/directory_ownership/macro-expanded-mod.rs new file mode 100644 index 000000000000..bbaf2992c35c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/directory_ownership/macro-expanded-mod.rs @@ -0,0 +1,16 @@ +// Test that macro-expanded non-inline modules behave correctly + +macro_rules! mod_decl { + ($i:ident) => { + mod $i; // { dg-error "" "" { target *-*-* } } + }; +} + +mod macro_expanded_mod_helper { + mod_decl!(foo); // This should search in the folder `macro_expanded_mod_helper` +} + +fn main() { + mod_decl!(foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/directory_ownership/macro_expanded_mod_helper/foo/bar.rs b/gcc/testsuite/rust/rustc/ui/directory_ownership/macro_expanded_mod_helper/foo/bar.rs new file mode 100644 index 000000000000..70c70d74bf1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/directory_ownership/macro_expanded_mod_helper/foo/bar.rs @@ -0,0 +1,2 @@ +// ignore-test not a test, auxiliary + diff --git a/gcc/testsuite/rust/rustc/ui/directory_ownership/macro_expanded_mod_helper/foo/mod.rs b/gcc/testsuite/rust/rustc/ui/directory_ownership/macro_expanded_mod_helper/foo/mod.rs new file mode 100644 index 000000000000..c99aae97d5f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/directory_ownership/macro_expanded_mod_helper/foo/mod.rs @@ -0,0 +1,4 @@ +// ignore-test not a test, auxiliary + +mod_decl!(bar); + diff --git a/gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux1.rs b/gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux1.rs new file mode 100644 index 000000000000..1844a20a1af1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux1.rs @@ -0,0 +1,7 @@ +// ignore-test this is not a test + +macro_rules! m { + () => { mod mod_file_not_owning_aux2; } +} +m!(); + diff --git a/gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux1/mod_file_not_owning_aux2.rs b/gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux1/mod_file_not_owning_aux2.rs new file mode 100644 index 000000000000..c84c7b394dc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux1/mod_file_not_owning_aux2.rs @@ -0,0 +1,2 @@ +// intentionally empty + diff --git a/gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux2.rs b/gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux2.rs new file mode 100644 index 000000000000..e0fd9009d1cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux2.rs @@ -0,0 +1,2 @@ +// ignore-test this is not a test + diff --git a/gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux3.rs b/gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux3.rs new file mode 100644 index 000000000000..3a1f5beb092e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/directory_ownership/mod_file_not_owning_aux3.rs @@ -0,0 +1,4 @@ +// ignore-test this is not a test + +mod mod_file_not_owning_aux2; + diff --git a/gcc/testsuite/rust/rustc/ui/directory_ownership/non-inline-mod-restriction.rs b/gcc/testsuite/rust/rustc/ui/directory_ownership/non-inline-mod-restriction.rs new file mode 100644 index 000000000000..7f0bd1212a7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/directory_ownership/non-inline-mod-restriction.rs @@ -0,0 +1,6 @@ +// Test that non-inline modules are not allowed inside blocks. + +fn main() { + mod foo; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-let.rs b/gcc/testsuite/rust/rustc/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-let.rs new file mode 100644 index 000000000000..c74af2a09505 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-let.rs @@ -0,0 +1,21 @@ +struct X { + x: String, +} + +impl Drop for X { + fn drop(&mut self) { + println!("value: {}", self.x); + } +} + +fn unwrap(x: X) -> String { + let X { x: y } = x; // { dg-error ".E0509." "" { target *-*-* } } + y +} + +fn main() { + let x = X { x: "hello".to_string() }; + let y = unwrap(x); + println!("contents: {}", y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-match.rs b/gcc/testsuite/rust/rustc/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-match.rs new file mode 100644 index 000000000000..3372ae09e9c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/disallowed-deconstructing/disallowed-deconstructing-destructing-struct-match.rs @@ -0,0 +1,19 @@ +struct X { + x: String, +} + +impl Drop for X { + fn drop(&mut self) { + println!("value: {}", self.x); + } +} + +fn main() { + let x = X { x: "hello".to_string() }; + + match x { +// { dg-error ".E0509." "" { target *-*-* } .-1 } + X { x: y } => println!("contents: {}", y) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/disambiguate-identical-names.rs b/gcc/testsuite/rust/rustc/ui/disambiguate-identical-names.rs new file mode 100644 index 000000000000..8fd985f18305 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/disambiguate-identical-names.rs @@ -0,0 +1,16 @@ +pub mod submod { + // Create ambiguity with the std::vec::Vec item: + pub struct Vec; +} + +fn test(_v: &Vec>) { +} + +fn main() { + let v = std::collections::HashMap::new(); + v.insert(3u8, 1u8); + + test(&v); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/discrim/discrim-ill-typed.rs b/gcc/testsuite/rust/rustc/ui/discrim/discrim-ill-typed.rs new file mode 100644 index 000000000000..3b0f97d26bb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/discrim/discrim-ill-typed.rs @@ -0,0 +1,117 @@ +// When explicit discriminant value has +// a type that does not match the representation +// type, rustc should fail gracefully. + +// See also run-pass/discrim-explicit-23030.rs where the input types +// are correct. + +#![allow(dead_code, unused_variables, unused_imports)] + +use std::{i8,u8,i16,u16,i32,u32,i64, u64}; + +fn f_i8() { + #[repr(i8)] + enum A { + Ok = i8::MAX - 1, + Ok2, + OhNo = 0_u8, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn f_u8() { + #[repr(u8)] + enum A { + Ok = u8::MAX - 1, + Ok2, + OhNo = 0_i8, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn f_i16() { + #[repr(i16)] + enum A { + Ok = i16::MAX - 1, + Ok2, + OhNo = 0_u16, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn f_u16() { + #[repr(u16)] + enum A { + Ok = u16::MAX - 1, + Ok2, + OhNo = 0_i16, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn f_i32() { + #[repr(i32)] + enum A { + Ok = i32::MAX - 1, + Ok2, + OhNo = 0_u32, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn f_u32() { + #[repr(u32)] + enum A { + Ok = u32::MAX - 1, + Ok2, + OhNo = 0_i32, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn f_i64() { + #[repr(i64)] + enum A { + Ok = i64::MAX - 1, + Ok2, + OhNo = 0_u64, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn f_u64() { + #[repr(u64)] + enum A { + Ok = u64::MAX - 1, + Ok2, + OhNo = 0_i64, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/discrim/discrim-overflow-2.rs b/gcc/testsuite/rust/rustc/ui/discrim/discrim-overflow-2.rs new file mode 100644 index 000000000000..56290da554aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/discrim/discrim-overflow-2.rs @@ -0,0 +1,83 @@ +// Issue 23030: Detect overflowing discriminant +// +// Check that we detect the overflow even if enum is not used. + +// See also run-pass/discrim-explicit-23030.rs where the suggested +// workaround is tested. + +use std::{i8,u8,i16,u16,i32,u32,i64, u64}; + +fn f_i8() { + #[repr(i8)] + enum A { + Ok = i8::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } + } +} + +fn f_u8() { + #[repr(u8)] + enum A { + Ok = u8::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } + } +} + +fn f_i16() { + #[repr(i16)] + enum A { + Ok = i16::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } + } +} + +fn f_u16() { + #[repr(u16)] + enum A { + Ok = u16::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } + } +} + +fn f_i32() { + #[repr(i32)] + enum A { + Ok = i32::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } + } +} + +fn f_u32() { + #[repr(u32)] + enum A { + Ok = u32::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } + } +} + +fn f_i64() { + #[repr(i64)] + enum A { + Ok = i64::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } + } +} + +fn f_u64() { + #[repr(u64)] + enum A { + Ok = u64::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/discrim/discrim-overflow.rs b/gcc/testsuite/rust/rustc/ui/discrim/discrim-overflow.rs new file mode 100644 index 000000000000..69710f3be894 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/discrim/discrim-overflow.rs @@ -0,0 +1,102 @@ +// Issue 23030: Detect overflowing discriminant + +// See also run-pass/discrim-explicit-23030.rs where the suggested +// workaround is tested. + +use std::{i8,u8,i16,u16,i32,u32,i64, u64}; + +fn f_i8() { + #[repr(i8)] + enum A { + Ok = i8::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } + } + + let x = A::Ok; +} + +fn f_u8() { + #[repr(u8)] + enum A { + Ok = u8::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } + } + + let x = A::Ok; +} + +fn f_i16() { + #[repr(i16)] + enum A { + Ok = i16::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } + } + + let x = A::Ok; +} + +fn f_u16() { + #[repr(u16)] + enum A { + Ok = u16::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn f_i32() { + #[repr(i32)] + enum A { + Ok = i32::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn f_u32() { + #[repr(u32)] + enum A { + Ok = u32::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn f_i64() { + #[repr(i64)] + enum A { + Ok = i64::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn f_u64() { + #[repr(u64)] + enum A { + Ok = u64::MAX - 1, + Ok2, + OhNo, // { dg-error ".E0370." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + } + + let x = A::Ok; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/diverging-fallback-method-chain.rs b/gcc/testsuite/rust/rustc/ui/diverging-fallback-method-chain.rs new file mode 100644 index 000000000000..369e6475b9fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/diverging-fallback-method-chain.rs @@ -0,0 +1,21 @@ +// run-pass + +#![allow(unused_imports)] +// Test a regression found when building compiler. The `produce()` +// error type `T` winds up getting unified with result of `x.parse()`; +// the type of the closure given to `unwrap_or_else` needs to be +// inferred to `usize`. + +use std::num::ParseIntError; + +fn produce() -> Result<&'static str, T> { + Ok("22") +} + +fn main() { + let x: usize = produce() + .and_then(|x| x.parse()) + .unwrap_or_else(|_| panic!()); + println!("{}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/diverging-fallback-option.rs b/gcc/testsuite/rust/rustc/ui/diverging-fallback-option.rs new file mode 100644 index 000000000000..c93692bbdf92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/diverging-fallback-option.rs @@ -0,0 +1,15 @@ +// run-pass + +#![allow(warnings)] + +// Here the type of `c` is `Option`, where `?T` is unconstrained. +// Because there is data-flow from the `{ return; }` block, which +// diverges and hence has type `!`, into `c`, we will default `?T` to +// `!`, and hence this code compiles rather than failing and requiring +// a type annotation. + +fn main() { + let c = Some({ return; }); + c.unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/diverging-fn-tail-35849.rs b/gcc/testsuite/rust/rustc/ui/diverging-fn-tail-35849.rs new file mode 100644 index 000000000000..05e00b1375ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/diverging-fn-tail-35849.rs @@ -0,0 +1,9 @@ +fn assert_sizeof() -> ! { + unsafe { + ::std::mem::transmute::(panic!()) +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/diverging-tuple-parts-39485.rs b/gcc/testsuite/rust/rustc/ui/diverging-tuple-parts-39485.rs new file mode 100644 index 000000000000..386f10af75d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/diverging-tuple-parts-39485.rs @@ -0,0 +1,16 @@ +// After #39485, this test used to pass, but that change was reverted +// due to numerous inference failures like #39808, so it now fails +// again. #39485 made it so that diverging types never propagate +// upward; but we now do propagate such types upward in many more +// cases. + +fn g() { + &panic!() // { dg-error ".E0308." "" { target *-*-* } } +} + +fn f() -> isize { + (return 1, return 2) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/doc-alias-crate-level.rs b/gcc/testsuite/rust/rustc/ui/doc-alias-crate-level.rs new file mode 100644 index 000000000000..f4c2d60e5d2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/doc-alias-crate-level.rs @@ -0,0 +1,8 @@ +// compile-flags: -Zdeduplicate-diagnostics=no + +#![feature(doc_alias)] + +#![crate_type = "lib"] + +#![doc(alias = "shouldn't work!")] // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/does-nothing.rs b/gcc/testsuite/rust/rustc/ui/does-nothing.rs new file mode 100644 index 000000000000..196775674e37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/does-nothing.rs @@ -0,0 +1,3 @@ +fn main() { println!("doing"); this_does_nothing_what_the; println!("boing"); } +// { dg-error ".E0425." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/dollar-crate/dollar-crate-is-keyword-2.rs b/gcc/testsuite/rust/rustc/ui/dollar-crate/dollar-crate-is-keyword-2.rs new file mode 100644 index 000000000000..eb2f5053426d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dollar-crate/dollar-crate-is-keyword-2.rs @@ -0,0 +1,14 @@ +mod a {} + +macro_rules! m { + () => { + use a::$crate; // { dg-error ".E0432." "" { target *-*-* } } + use a::$crate::b; // { dg-error ".E0433." "" { target *-*-* } } + type A = a::$crate; // { dg-error ".E0433." "" { target *-*-* } } + } +} + +m!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/dollar-crate/dollar-crate-is-keyword.rs b/gcc/testsuite/rust/rustc/ui/dollar-crate/dollar-crate-is-keyword.rs new file mode 100644 index 000000000000..bf662f95e5c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dollar-crate/dollar-crate-is-keyword.rs @@ -0,0 +1,18 @@ +macro_rules! m { + () => { + // Avoid having more than one `$crate`-named item in the same module, + // as even though they error, they still parse as `$crate` and conflict. + mod foo { + struct $crate {} // { dg-error "" "" { target *-*-* } } + } + + use $crate; // { dg-error "" "" { target *-*-* } } + use $crate as $crate; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +m!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/dont-suggest-private-trait-method.rs b/gcc/testsuite/rust/rustc/ui/dont-suggest-private-trait-method.rs new file mode 100644 index 000000000000..8334ee100f78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dont-suggest-private-trait-method.rs @@ -0,0 +1,7 @@ +struct T; + +fn main() { + T::new(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dotdotdot-expr.rs b/gcc/testsuite/rust/rustc/ui/dotdotdot-expr.rs new file mode 100644 index 000000000000..f876ace79286 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dotdotdot-expr.rs @@ -0,0 +1,5 @@ +fn main() { + let _redemptive = 1...21; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/double-import.rs b/gcc/testsuite/rust/rustc/ui/double-import.rs new file mode 100644 index 000000000000..b233c2b49368 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/double-import.rs @@ -0,0 +1,16 @@ +// This tests that conflicting imports shows both `use` lines +// when reporting the error. + +mod sub1 { + pub fn foo() {} // implementation 1 +} + +mod sub2 { + pub fn foo() {} // implementation 2 +} + +use sub1::foo; +use sub2::foo; // { dg-error ".E0252." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/double-ref.rs b/gcc/testsuite/rust/rustc/ui/double-ref.rs new file mode 100644 index 000000000000..9514c42923f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/double-ref.rs @@ -0,0 +1,37 @@ +// run-pass + +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn check_expr() { + let _: & usize = &1; + let _: & & usize = &&1; + let _: & & & usize = &&&1; + let _: & & & usize = & &&1; + let _: & & & & usize = &&&&1; + let _: & & & & usize = & &&&1; + let _: & & & & & usize = &&&&&1; +} + +fn check_ty() { + let _: &usize = & 1; + let _: &&usize = & & 1; + let _: &&&usize = & & & 1; + let _: & &&usize = & & & 1; + let _: &&&&usize = & & & & 1; + let _: & &&&usize = & & & & 1; + let _: &&&&&usize = & & & & & 1; +} + +fn check_pat() { + let &_ = & 1_usize; + let &&_ = & & 1_usize; + let &&&_ = & & & 1_usize; + let & &&_ = & & & 1_usize; + let &&&&_ = & & & & 1_usize; + let & &&&_ = & & & & 1_usize; + let &&&&&_ = & & & & & 1_usize; +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/double-type-import.rs b/gcc/testsuite/rust/rustc/ui/double-type-import.rs new file mode 100644 index 000000000000..076a33292be4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/double-type-import.rs @@ -0,0 +1,14 @@ +mod foo { + pub use self::bar::X; + use self::bar::X; +// { dg-error ".E0252." "" { target *-*-* } .-1 } + + mod bar { + pub struct X; + } +} + +fn main() { + let _ = foo::X; +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop-bounds/drop-bounds-impl-drop.rs b/gcc/testsuite/rust/rustc/ui/drop-bounds/drop-bounds-impl-drop.rs new file mode 100644 index 000000000000..15af5e211e9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop-bounds/drop-bounds-impl-drop.rs @@ -0,0 +1,15 @@ +// run-pass +#![deny(drop_bounds)] +// As a special exemption, `impl Drop` in the return position raises no error. +// This allows a convenient way to return an unnamed drop guard. +fn voldemort_type() -> impl Drop { + struct Voldemort; + impl Drop for Voldemort { + fn drop(&mut self) {} + } + Voldemort +} +fn main() { + let _ = voldemort_type(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop-bounds/drop-bounds.rs b/gcc/testsuite/rust/rustc/ui/drop-bounds/drop-bounds.rs new file mode 100644 index 000000000000..c4e5c0fa087b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop-bounds/drop-bounds.rs @@ -0,0 +1,20 @@ +#![deny(drop_bounds)] +fn foo() {} // { dg-error "" "" { target *-*-* } } +fn bar() +where + U: Drop, // { dg-error "" "" { target *-*-* } } +{ +} +fn baz(_x: impl Drop) {} // { dg-error "" "" { target *-*-* } } +struct Foo { // { dg-error "" "" { target *-*-* } } + _x: T +} +struct Bar where U: Drop { // { dg-error "" "" { target *-*-* } } + _x: U +} +trait Baz: Drop { // { dg-error "" "" { target *-*-* } } +} +impl Baz for T { // { dg-error "" "" { target *-*-* } } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/auxiliary/dropck_eyepatch_extern_crate.rs b/gcc/testsuite/rust/rustc/ui/drop/auxiliary/dropck_eyepatch_extern_crate.rs new file mode 100644 index 000000000000..8508f22b7726 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/auxiliary/dropck_eyepatch_extern_crate.rs @@ -0,0 +1,51 @@ +#![feature(dropck_eyepatch)] + +// The point of this test is to illustrate that the `#[may_dangle]` +// attribute specifically allows, in the context of a type +// implementing `Drop`, a generic parameter to be instantiated with a +// lifetime that does not strictly outlive the owning type itself, +// and that this attributes effects are preserved when importing +// the type from another crate. +// +// See also dropck-eyepatch.rs for more information about the general +// structure of the test. + +use std::cell::RefCell; + +pub trait Foo { fn foo(&self, _: &str); } + +pub struct Dt(pub &'static str, pub A); +pub struct Dr<'a, B:'a+Foo>(pub &'static str, pub &'a B); +pub struct Pt(pub &'static str, pub A, pub B); +pub struct Pr<'a, 'b, B:'a+'b+Foo>(pub &'static str, pub &'a B, pub &'b B); +pub struct St(pub &'static str, pub A); +pub struct Sr<'a, B:'a+Foo>(pub &'static str, pub &'a B); + +impl Drop for Dt { + fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); } +} +impl<'a, B: Foo> Drop for Dr<'a, B> { + fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); } +} +unsafe impl<#[may_dangle] A, B: Foo> Drop for Pt { + // (unsafe to access self.1 due to #[may_dangle] on A) + fn drop(&mut self) { println!("drop {}", self.0); self.2.foo(self.0); } +} +unsafe impl<#[may_dangle] 'a, 'b, B: Foo> Drop for Pr<'a, 'b, B> { + // (unsafe to access self.1 due to #[may_dangle] on 'a) + fn drop(&mut self) { println!("drop {}", self.0); self.2.foo(self.0); } +} + +impl Foo for RefCell { + fn foo(&self, s: &str) { + let s2 = format!("{}|{}", *self.borrow(), s); + *self.borrow_mut() = s2; + } +} + +impl<'a, T:Foo> Foo for &'a T { + fn foo(&self, s: &str) { + (*self).foo(s); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/drop-on-empty-block-exit.rs b/gcc/testsuite/rust/rustc/ui/drop/drop-on-empty-block-exit.rs new file mode 100644 index 000000000000..f63658b1516f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/drop-on-empty-block-exit.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 +#![allow(non_camel_case_types)] + +#![feature(box_syntax)] + +enum t { foo(Box), } + +pub fn main() { + let tt = t::foo(box 10); + match tt { t::foo(_z) => { } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/drop-on-ret.rs b/gcc/testsuite/rust/rustc/ui/drop/drop-on-ret.rs new file mode 100644 index 000000000000..9e02766eb834 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/drop-on-ret.rs @@ -0,0 +1,16 @@ +// run-pass + + + +// pretty-expanded FIXME #23616 + +fn f() -> isize { + if true { + let _s: String = "should not leak".to_string(); + return 1; + } + return 0; +} + +pub fn main() { f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/drop/drop-struct-as-object.rs b/gcc/testsuite/rust/rustc/ui/drop/drop-struct-as-object.rs new file mode 100644 index 000000000000..94c4a87e0ae6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/drop-struct-as-object.rs @@ -0,0 +1,39 @@ +// run-pass +#![allow(unused_variables)] +#![allow(non_upper_case_globals)] + +// Test that destructor on a struct runs successfully after the struct +// is boxed and converted to an object. + +#![feature(box_syntax)] + +static mut value: usize = 0; + +struct Cat { + name : usize, +} + +trait Dummy { + fn get(&self) -> usize; +} + +impl Dummy for Cat { + fn get(&self) -> usize { self.name } +} + +impl Drop for Cat { + fn drop(&mut self) { + unsafe { value = self.name; } + } +} + +pub fn main() { + { + let x = box Cat {name: 22}; + let nyan: Box = x as Box; + } + unsafe { + assert_eq!(value, 22); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/drop-trait-enum.rs b/gcc/testsuite/rust/rustc/ui/drop/drop-trait-enum.rs new file mode 100644 index 000000000000..1f12f609781d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/drop-trait-enum.rs @@ -0,0 +1,96 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_assignments)] +#![allow(unused_variables)] +// ignore-emscripten no threads support + +#![feature(box_syntax)] + +use std::thread; +use std::sync::mpsc::{channel, Sender}; + +#[derive(PartialEq, Debug)] +enum Message { + Dropped, + DestructorRan +} + +struct SendOnDrop { + sender: Sender +} + +impl Drop for SendOnDrop { + fn drop(&mut self) { + self.sender.send(Message::Dropped).unwrap(); + } +} + +enum Foo { + SimpleVariant(Sender), + NestedVariant(Box, SendOnDrop, Sender), + FailingVariant { on_drop: SendOnDrop } +} + +impl Drop for Foo { + fn drop(&mut self) { + match self { + &mut Foo::SimpleVariant(ref mut sender) => { + sender.send(Message::DestructorRan).unwrap(); + } + &mut Foo::NestedVariant(_, _, ref mut sender) => { + sender.send(Message::DestructorRan).unwrap(); + } + &mut Foo::FailingVariant { .. } => { + panic!("Failed"); + } + } + } +} + +pub fn main() { + let (sender, receiver) = channel(); + { + let v = Foo::SimpleVariant(sender); + } + assert_eq!(receiver.recv().unwrap(), Message::DestructorRan); + assert_eq!(receiver.recv().ok(), None); + + let (sender, receiver) = channel(); + { + let v = Foo::NestedVariant(box 42, SendOnDrop { sender: sender.clone() }, sender); + } + assert_eq!(receiver.recv().unwrap(), Message::DestructorRan); + assert_eq!(receiver.recv().unwrap(), Message::Dropped); + assert_eq!(receiver.recv().ok(), None); + + let (sender, receiver) = channel(); + let t = thread::spawn(move|| { + let v = Foo::FailingVariant { on_drop: SendOnDrop { sender: sender } }; + }); + assert_eq!(receiver.recv().unwrap(), Message::Dropped); + assert_eq!(receiver.recv().ok(), None); + drop(t.join()); + + let (sender, receiver) = channel(); + let t = { + thread::spawn(move|| { + let mut v = Foo::NestedVariant(box 42, SendOnDrop { + sender: sender.clone() + }, sender.clone()); + v = Foo::NestedVariant(box 42, + SendOnDrop { sender: sender.clone() }, + sender.clone()); + v = Foo::SimpleVariant(sender.clone()); + v = Foo::FailingVariant { on_drop: SendOnDrop { sender: sender } }; + }) + }; + assert_eq!(receiver.recv().unwrap(), Message::DestructorRan); + assert_eq!(receiver.recv().unwrap(), Message::Dropped); + assert_eq!(receiver.recv().unwrap(), Message::DestructorRan); + assert_eq!(receiver.recv().unwrap(), Message::Dropped); + assert_eq!(receiver.recv().unwrap(), Message::DestructorRan); + assert_eq!(receiver.recv().unwrap(), Message::Dropped); + assert_eq!(receiver.recv().ok(), None); + drop(t.join()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/drop-trait-generic.rs b/gcc/testsuite/rust/rustc/ui/drop/drop-trait-generic.rs new file mode 100644 index 000000000000..909fbacd9edc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/drop-trait-generic.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +struct S { + x: T +} + +impl ::std::ops::Drop for S { + fn drop(&mut self) { + println!("bye"); + } +} + +pub fn main() { + let _x = S { x: 1 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/drop-trait.rs b/gcc/testsuite/rust/rustc/ui/drop/drop-trait.rs new file mode 100644 index 000000000000..fbacdd31d233 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/drop-trait.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +struct Foo { + x: isize +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("bye"); + } +} + +pub fn main() { + let _x: Foo = Foo { x: 3 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/drop-uninhabited-enum.rs b/gcc/testsuite/rust/rustc/ui/drop/drop-uninhabited-enum.rs new file mode 100644 index 000000000000..bb96eca624c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/drop-uninhabited-enum.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +enum Foo { } + +impl Drop for Foo { + fn drop(&mut self) { } +} + +fn foo(x: Foo) { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/drop/drop-with-type-ascription-1.rs b/gcc/testsuite/rust/rustc/ui/drop/drop-with-type-ascription-1.rs new file mode 100644 index 000000000000..1db38260977c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/drop-with-type-ascription-1.rs @@ -0,0 +1,9 @@ +// run-pass + +fn main() { + let foo = "hello".to_string(); + let foo: Vec<&str> = foo.split_whitespace().collect(); + let invalid_string = &foo[0]; + assert_eq!(*invalid_string, "hello"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/drop-with-type-ascription-2.rs b/gcc/testsuite/rust/rustc/ui/drop/drop-with-type-ascription-2.rs new file mode 100644 index 000000000000..2ed1bcf3665b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/drop-with-type-ascription-2.rs @@ -0,0 +1,9 @@ +// run-pass + +fn main() { + let args = vec!["foobie", "asdf::asdf"]; + let arr: Vec<&str> = args[1].split("::").collect(); + assert_eq!(arr[0], "asdf"); + assert_eq!(arr[0], "asdf"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/dropck-eyepatch-extern-crate.rs b/gcc/testsuite/rust/rustc/ui/drop/dropck-eyepatch-extern-crate.rs new file mode 100644 index 000000000000..e28ab28e4dde --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/dropck-eyepatch-extern-crate.rs @@ -0,0 +1,40 @@ +// run-pass +// aux-build:dropck_eyepatch_extern_crate.rs + +extern crate dropck_eyepatch_extern_crate as other; + +use other::{Dt,Dr,Pt,Pr,St,Sr}; + +fn main() { + use std::cell::RefCell; + + struct CheckOnDrop(RefCell, &'static str); + impl Drop for CheckOnDrop { + fn drop(&mut self) { assert_eq!(*self.0.borrow(), self.1); } + } + + let c_long; + let (c, dt, dr, pt, pr, st, sr) + : (CheckOnDrop, Dt<_>, Dr<_>, Pt<_, _>, Pr<_>, St<_>, Sr<_>); + c_long = CheckOnDrop(RefCell::new("c_long".to_string()), + "c_long|pr|pt|dr|dt"); + c = CheckOnDrop(RefCell::new("c".to_string()), + "c"); + + // No error: sufficiently long-lived state can be referenced in dtors + dt = Dt("dt", &c_long.0); + dr = Dr("dr", &c_long.0); + + // No error: Drop impl asserts .1 (A and &'a _) are not accessed + pt = Pt("pt", &c.0, &c_long.0); + pr = Pr("pr", &c.0, &c_long.0); + + // No error: St and Sr have no destructor. + st = St("st", &c.0); + sr = Sr("sr", &c.0); + + println!("{:?}", (dt.0, dr.0, pt.0, pr.0, st.0, sr.0)); + assert_eq!(*c_long.0.borrow(), "c_long"); + assert_eq!(*c.0.borrow(), "c"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/dropck-eyepatch-reorder.rs b/gcc/testsuite/rust/rustc/ui/drop/dropck-eyepatch-reorder.rs new file mode 100644 index 000000000000..943a02902985 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/dropck-eyepatch-reorder.rs @@ -0,0 +1,80 @@ +// run-pass +#![feature(dropck_eyepatch)] + +// The point of this test is to test uses of `#[may_dangle]` attribute +// where the formal declaration order (in the impl generics) does not +// match the actual usage order (in the type instantiation). +// +// See also dropck-eyepatch.rs for more information about the general +// structure of the test. + +trait Foo { fn foo(&self, _: &str); } + +struct Dt(&'static str, A); +struct Dr<'a, B:'a+Foo>(&'static str, &'a B); +struct Pt(&'static str, A, B); +struct Pr<'a, 'b, B:'a+'b+Foo>(&'static str, &'a B, &'b B); +struct St(&'static str, A); +struct Sr<'a, B:'a+Foo>(&'static str, &'a B); + +impl Drop for Dt { + fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); } +} +impl<'a, B: Foo> Drop for Dr<'a, B> { + fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); } +} +unsafe impl Drop for Pt { + // (unsafe to access self.1 due to #[may_dangle] on A) + fn drop(&mut self) { println!("drop {}", self.0); self.2.foo(self.0); } +} +unsafe impl<'b, #[may_dangle] 'a, B: Foo> Drop for Pr<'a, 'b, B> { + // (unsafe to access self.1 due to #[may_dangle] on 'a) + fn drop(&mut self) { println!("drop {}", self.0); self.2.foo(self.0); } +} + +fn main() { + use std::cell::RefCell; + + impl Foo for RefCell { + fn foo(&self, s: &str) { + let s2 = format!("{}|{}", *self.borrow(), s); + *self.borrow_mut() = s2; + } + } + + impl<'a, T:Foo> Foo for &'a T { + fn foo(&self, s: &str) { + (*self).foo(s); + } + } + + struct CheckOnDrop(RefCell, &'static str); + impl Drop for CheckOnDrop { + fn drop(&mut self) { assert_eq!(*self.0.borrow(), self.1); } + } + + let c_long; + let (c, dt, dr, pt, pr, st, sr) + : (CheckOnDrop, Dt<_>, Dr<_>, Pt<_, _>, Pr<_>, St<_>, Sr<_>); + c_long = CheckOnDrop(RefCell::new("c_long".to_string()), + "c_long|pr|pt|dr|dt"); + c = CheckOnDrop(RefCell::new("c".to_string()), + "c"); + + // No error: sufficiently long-lived state can be referenced in dtors + dt = Dt("dt", &c_long.0); + dr = Dr("dr", &c_long.0); + + // No error: Drop impl asserts .1 (A and &'a _) are not accessed + pt = Pt("pt", &c.0, &c_long.0); + pr = Pr("pr", &c.0, &c_long.0); + + // No error: St and Sr have no destructor. + st = St("st", &c.0); + sr = Sr("sr", &c.0); + + println!("{:?}", (dt.0, dr.0, pt.0, pr.0, st.0, sr.0)); + assert_eq!(*c_long.0.borrow(), "c_long"); + assert_eq!(*c.0.borrow(), "c"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/dropck-eyepatch.rs b/gcc/testsuite/rust/rustc/ui/drop/dropck-eyepatch.rs new file mode 100644 index 000000000000..6b0b7631cb46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/dropck-eyepatch.rs @@ -0,0 +1,103 @@ +// run-pass +#![feature(dropck_eyepatch)] + +// The point of this test is to illustrate that the `#[may_dangle]` +// attribute specifically allows, in the context of a type +// implementing `Drop`, a generic parameter to be instantiated with a +// lifetime that does not strictly outlive the owning type itself. +// +// Here we test that a model use of `#[may_dangle]` will compile and run. +// +// The illustration is made concrete by comparison with two variations +// on the type with `#[may_dangle]`: +// +// 1. an analogous type that does not implement `Drop` (and thus +// should exhibit maximal flexibility with respect to dropck), and +// +// 2. an analogous type that does not use `#[may_dangle]` (and thus +// should exhibit the standard limitations imposed by dropck. +// +// The types in this file follow a pattern, {D,P,S}{t,r}, where: +// +// - D means "I implement Drop" +// +// - P means "I implement Drop but guarantee my (first) parameter is +// pure, i.e., not accessed from the destructor"; no other parameters +// are pure. +// +// - S means "I do not implement Drop" +// +// - t suffix is used when the first generic is a type +// +// - r suffix is used when the first generic is a lifetime. + +trait Foo { fn foo(&self, _: &str); } + +struct Dt(&'static str, A); +struct Dr<'a, B:'a+Foo>(&'static str, &'a B); +struct Pt(&'static str, A, B); +struct Pr<'a, 'b, B:'a+'b+Foo>(&'static str, &'a B, &'b B); +struct St(&'static str, A); +struct Sr<'a, B:'a+Foo>(&'static str, &'a B); + +impl Drop for Dt { + fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); } +} +impl<'a, B: Foo> Drop for Dr<'a, B> { + fn drop(&mut self) { println!("drop {}", self.0); self.1.foo(self.0); } +} +unsafe impl<#[may_dangle] A, B: Foo> Drop for Pt { + // (unsafe to access self.1 due to #[may_dangle] on A) + fn drop(&mut self) { println!("drop {}", self.0); self.2.foo(self.0); } +} +unsafe impl<#[may_dangle] 'a, 'b, B: Foo> Drop for Pr<'a, 'b, B> { + // (unsafe to access self.1 due to #[may_dangle] on 'a) + fn drop(&mut self) { println!("drop {}", self.0); self.2.foo(self.0); } +} + +fn main() { + use std::cell::RefCell; + + impl Foo for RefCell { + fn foo(&self, s: &str) { + let s2 = format!("{}|{}", *self.borrow(), s); + *self.borrow_mut() = s2; + } + } + + impl<'a, T:Foo> Foo for &'a T { + fn foo(&self, s: &str) { + (*self).foo(s); + } + } + + struct CheckOnDrop(RefCell, &'static str); + impl Drop for CheckOnDrop { + fn drop(&mut self) { assert_eq!(*self.0.borrow(), self.1); } + } + + let c_long; + let (c, dt, dr, pt, pr, st, sr) + : (CheckOnDrop, Dt<_>, Dr<_>, Pt<_, _>, Pr<_>, St<_>, Sr<_>); + c_long = CheckOnDrop(RefCell::new("c_long".to_string()), + "c_long|pr|pt|dr|dt"); + c = CheckOnDrop(RefCell::new("c".to_string()), + "c"); + + // No error: sufficiently long-lived state can be referenced in dtors + dt = Dt("dt", &c_long.0); + dr = Dr("dr", &c_long.0); + + // No error: Drop impl asserts .1 (A and &'a _) are not accessed + pt = Pt("pt", &c.0, &c_long.0); + pr = Pr("pr", &c.0, &c_long.0); + + // No error: St and Sr have no destructor. + st = St("st", &c.0); + sr = Sr("sr", &c.0); + + println!("{:?}", (dt.0, dr.0, pt.0, pr.0, st.0, sr.0)); + assert_eq!(*c_long.0.borrow(), "c_long"); + assert_eq!(*c.0.borrow(), "c"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/dropck_legal_cycles.rs b/gcc/testsuite/rust/rustc/ui/drop/dropck_legal_cycles.rs new file mode 100644 index 000000000000..cd74ffb234bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/dropck_legal_cycles.rs @@ -0,0 +1,1184 @@ +// run-pass +// This test exercises cases where cyclic structure is legal, +// including when the cycles go through data-structures such +// as `Vec` or `TypedArena`. +// +// The intent is to cover as many such cases as possible, ensuring +// that if the compiler did not complain circa Rust 1.x (1.2 as of +// this writing), then it will continue to not complain in the future. +// +// Note that while some of the tests are only exercising using the +// given collection as a "backing store" for a set of nodes that hold +// the actual cycle (and thus the cycle does not go through the +// collection itself in such cases), in general we *do* want to make +// sure to have at least one example exercising a cycle that goes +// through the collection, for every collection type that supports +// this. + +// HIGH LEVEL DESCRIPTION OF THE TEST ARCHITECTURE +// ----------------------------------------------- +// +// We pick a data structure and want to make a cyclic construction +// from it. Each test of interest is labelled starting with "Cycle N: +// { ... }" where N is the test number and the "..."`is filled in with +// a graphviz-style description of the graph structure that the +// author believes is being made. So "{ a -> b, b -> (c,d), (c,d) -> e }" +// describes a line connected to a diamond: +// +// c +// / \ +// a - b e +// \ / +// d +// +// (Note that the above directed graph is actually acyclic.) +// +// The different graph structures are often composed of different data +// types. Some may be built atop `Vec`, others atop `HashMap`, etc. +// +// For each graph structure, we actually *confirm* that a cycle exists +// (as a safe-guard against a test author accidentally leaving it out) +// by traversing each graph and "proving" that a cycle exists within it. +// +// To do this, while trying to keep the code uniform (despite working +// with different underlying collection and smart-pointer types), we +// have a standard traversal API: +// +// 1. every node in the graph carries a `mark` (a u32, init'ed to 0). +// +// 2. every node provides a method to visit its children +// +// 3. a traversal attmepts to visit the nodes of the graph and prove that +// it sees the same node twice. It does this by setting the mark of each +// node to a fresh non-zero value, and if it sees the current mark, it +// "knows" that it must have found a cycle, and stops attempting further +// traversal. +// +// 4. each traversal is controlled by a bit-string that tells it which child +// it visit when it can take different paths. As a simple example, +// in a binary tree, 0 could mean "left" (and 1, "right"), so that +// "00010" means "left, left, left, right, left". (In general it will +// read as many bits as it needs to choose one child.) +// +// The graphs in this test are all meant to be very small, and thus +// short bitstrings of less than 64 bits should always suffice. +// +// (An earlier version of this test infrastructure simply had any +// given traversal visit all children it encountered, in a +// depth-first manner; one problem with this approach is that an +// acyclic graph can still have sharing, which would then be treated +// as a repeat mark and reported as a detected cycle.) +// +// The travseral code is a little more complicated because it has been +// programmed in a somewhat defensive manner. For example it also has +// a max threshold for the number of nodes it will visit, to guard +// against scenarios where the nodes are not correctly setting their +// mark when asked. There are various other methods not discussed here +// that are for aiding debugging the test when it runs, such as the +// `name` method that all nodes provide. +// +// So each test: +// +// 1. allocates the nodes in the graph, +// +// 2. sets up the links in the graph, +// +// 3. clones the "ContextData" +// +// 4. chooses a new current mark value for this test +// +// 5. initiates a traversal, potentially from multiple starting points +// (aka "roots"), with a given control-string (potentially a +// different string for each root). if it does start from a +// distinct root, then such a test should also increment the +// current mark value, so that this traversal is considered +// distinct from the prior one on this graph structure. +// +// Note that most of the tests work with the default control string +// of all-zeroes. +// +// 6. assert that the context confirms that it actually saw a cycle (since a traversal +// might have terminated, e.g., on a tree structure that contained no cycles). + +use std::cell::{Cell, RefCell}; +use std::cmp::Ordering; +use std::collections::BinaryHeap; +use std::collections::HashMap; +use std::collections::LinkedList; +use std::collections::VecDeque; +use std::collections::btree_map::BTreeMap; +use std::collections::btree_set::BTreeSet; +use std::hash::{Hash, Hasher}; +use std::rc::Rc; +use std::sync::{Arc, RwLock, Mutex}; + +const PRINT: bool = false; + +pub fn main() { + let c_orig = ContextData { + curr_depth: 0, + max_depth: 3, + visited: 0, + max_visits: 1000, + skipped: 0, + curr_mark: 0, + saw_prev_marked: false, + control_bits: 0, + }; + + // SANITY CHECK FOR TEST SUITE (thus unnumbered) + // Not a cycle: { v[0] -> (v[1], v[2]), v[1] -> v[3], v[2] -> v[3] }; + let v: Vec = vec![Named::new("s0"), + Named::new("s1"), + Named::new("s2"), + Named::new("s3")]; + v[0].next.set((Some(&v[1]), Some(&v[2]))); + v[1].next.set((Some(&v[3]), None)); + v[2].next.set((Some(&v[3]), None)); + v[3].next.set((None, None)); + + let mut c = c_orig.clone(); + c.curr_mark = 10; + assert!(!c.saw_prev_marked); + v[0].descend_into_self(&mut c); + assert!(!c.saw_prev_marked); // <-- different from below, b/c acyclic above + + if PRINT { println!(); } + + // Cycle 1: { v[0] -> v[1], v[1] -> v[0] }; + // does not exercise `v` itself + let v: Vec = vec![Named::new("s0"), + Named::new("s1")]; + v[0].next.set(Some(&v[1])); + v[1].next.set(Some(&v[0])); + + let mut c = c_orig.clone(); + c.curr_mark = 10; + assert!(!c.saw_prev_marked); + v[0].descend_into_self(&mut c); + assert!(c.saw_prev_marked); + + if PRINT { println!(); } + + // Cycle 2: { v[0] -> v, v[1] -> v } + let v: V = Named::new("v"); + v.contents[0].set(Some(&v)); + v.contents[1].set(Some(&v)); + + let mut c = c_orig.clone(); + c.curr_mark = 20; + assert!(!c.saw_prev_marked); + v.descend_into_self(&mut c); + assert!(c.saw_prev_marked); + + if PRINT { println!(); } + + // Cycle 3: { hk0 -> hv0, hv0 -> hk0, hk1 -> hv1, hv1 -> hk1 }; + // does not exercise `h` itself + + let mut h: HashMap = HashMap::new(); + h.insert(Named::new("hk0"), Named::new("hv0")); + h.insert(Named::new("hk1"), Named::new("hv1")); + for (key, val) in h.iter() { + val.next.set(Some(key)); + key.next.set(Some(val)); + } + + let mut c = c_orig.clone(); + c.curr_mark = 30; + for (key, _) in h.iter() { + c.curr_mark += 1; + c.saw_prev_marked = false; + key.descend_into_self(&mut c); + assert!(c.saw_prev_marked); + } + + if PRINT { println!(); } + + // Cycle 4: { h -> (hmk0,hmv0,hmk1,hmv1), {hmk0,hmv0,hmk1,hmv1} -> h } + + let mut h: HashMap = HashMap::new(); + h.insert(Named::new("hmk0"), Named::new("hmv0")); + h.insert(Named::new("hmk0"), Named::new("hmv0")); + for (key, val) in h.iter() { + val.contents.set(Some(&h)); + key.contents.set(Some(&h)); + } + + let mut c = c_orig.clone(); + c.max_depth = 2; + c.curr_mark = 40; + for (key, _) in h.iter() { + c.curr_mark += 1; + c.saw_prev_marked = false; + key.descend_into_self(&mut c); + assert!(c.saw_prev_marked); + // break; + } + + if PRINT { println!(); } + + // Cycle 5: { vd[0] -> vd[1], vd[1] -> vd[0] }; + // does not exercise vd itself + let mut vd: VecDeque = VecDeque::new(); + vd.push_back(Named::new("d0")); + vd.push_back(Named::new("d1")); + vd[0].next.set(Some(&vd[1])); + vd[1].next.set(Some(&vd[0])); + + let mut c = c_orig.clone(); + c.curr_mark = 50; + assert!(!c.saw_prev_marked); + vd[0].descend_into_self(&mut c); + assert!(c.saw_prev_marked); + + if PRINT { println!(); } + + // Cycle 6: { vd -> (vd0, vd1), {vd0, vd1} -> vd } + let mut vd: VecDeque = VecDeque::new(); + vd.push_back(Named::new("vd0")); + vd.push_back(Named::new("vd1")); + vd[0].contents.set(Some(&vd)); + vd[1].contents.set(Some(&vd)); + + let mut c = c_orig.clone(); + c.curr_mark = 60; + assert!(!c.saw_prev_marked); + vd[0].descend_into_self(&mut c); + assert!(c.saw_prev_marked); + + if PRINT { println!(); } + + // Cycle 7: { vm -> (vm0, vm1), {vm0, vm1} -> vm } + let mut vm: HashMap = HashMap::new(); + vm.insert(0, Named::new("vm0")); + vm.insert(1, Named::new("vm1")); + vm[&0].contents.set(Some(&vm)); + vm[&1].contents.set(Some(&vm)); + + let mut c = c_orig.clone(); + c.curr_mark = 70; + assert!(!c.saw_prev_marked); + vm[&0].descend_into_self(&mut c); + assert!(c.saw_prev_marked); + + if PRINT { println!(); } + + // Cycle 8: { ll -> (ll0, ll1), {ll0, ll1} -> ll } + let mut ll: LinkedList = LinkedList::new(); + ll.push_back(Named::new("ll0")); + ll.push_back(Named::new("ll1")); + for e in &ll { + e.contents.set(Some(&ll)); + } + + let mut c = c_orig.clone(); + c.curr_mark = 80; + for e in &ll { + c.curr_mark += 1; + c.saw_prev_marked = false; + e.descend_into_self(&mut c); + assert!(c.saw_prev_marked); + // break; + } + + if PRINT { println!(); } + + // Cycle 9: { bh -> (bh0, bh1), {bh0, bh1} -> bh } + let mut bh: BinaryHeap = BinaryHeap::new(); + bh.push(Named::new("bh0")); + bh.push(Named::new("bh1")); + for b in bh.iter() { + b.contents.set(Some(&bh)); + } + + let mut c = c_orig.clone(); + c.curr_mark = 90; + for b in &bh { + c.curr_mark += 1; + c.saw_prev_marked = false; + b.descend_into_self(&mut c); + assert!(c.saw_prev_marked); + // break; + } + + if PRINT { println!(); } + + // Cycle 10: { btm -> (btk0, btv1), {bt0, bt1} -> btm } + let mut btm: BTreeMap = BTreeMap::new(); + btm.insert(Named::new("btk0"), Named::new("btv0")); + btm.insert(Named::new("btk1"), Named::new("btv1")); + for (k, v) in btm.iter() { + k.contents.set(Some(&btm)); + v.contents.set(Some(&btm)); + } + + let mut c = c_orig.clone(); + c.curr_mark = 100; + for (k, _) in &btm { + c.curr_mark += 1; + c.saw_prev_marked = false; + k.descend_into_self(&mut c); + assert!(c.saw_prev_marked); + // break; + } + + if PRINT { println!(); } + + // Cycle 10: { bts -> (bts0, bts1), {bts0, bts1} -> btm } + let mut bts: BTreeSet = BTreeSet::new(); + bts.insert(Named::new("bts0")); + bts.insert(Named::new("bts1")); + for v in bts.iter() { + v.contents.set(Some(&bts)); + } + + let mut c = c_orig.clone(); + c.curr_mark = 100; + for b in &bts { + c.curr_mark += 1; + c.saw_prev_marked = false; + b.descend_into_self(&mut c); + assert!(c.saw_prev_marked); + // break; + } + + if PRINT { println!(); } + + // Cycle 11: { rc0 -> (rc1, rc2), rc1 -> (), rc2 -> rc0 } + let (rc0, rc1, rc2): (RCRC, RCRC, RCRC); + rc0 = RCRC::new("rcrc0"); + rc1 = RCRC::new("rcrc1"); + rc2 = RCRC::new("rcrc2"); + rc0.0.borrow_mut().children.0 = Some(&rc1); + rc0.0.borrow_mut().children.1 = Some(&rc2); + rc2.0.borrow_mut().children.0 = Some(&rc0); + + let mut c = c_orig.clone(); + c.control_bits = 0b1; + c.curr_mark = 110; + assert!(!c.saw_prev_marked); + rc0.descend_into_self(&mut c); + assert!(c.saw_prev_marked); + + if PRINT { println!(); } + + // We want to take the previous Rc case and generalize it to Arc. + // + // We can use refcells if we're single-threaded (as this test is). + // If one were to generalize these constructions to a + // multi-threaded context, then it might seem like we could choose + // between either a RwLock or a Mutex to hold the owned arcs on + // each node. + // + // Part of the point of this test is to actually confirm that the + // cycle exists by traversing it. We can do that just fine with an + // RwLock (since we can grab the child pointers in read-only + // mode), but we cannot lock a std::sync::Mutex to guard reading + // from each node via the same pattern, since once you hit the + // cycle, you'll be trying to acquiring the same lock twice. + // (We deal with this by exiting the traversal early if try_lock fails.) + + // Cycle 12: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, refcells + let (arc0, arc1, arc2): (ARCRC, ARCRC, ARCRC); + arc0 = ARCRC::new("arcrc0"); + arc1 = ARCRC::new("arcrc1"); + arc2 = ARCRC::new("arcrc2"); + arc0.0.borrow_mut().children.0 = Some(&arc1); + arc0.0.borrow_mut().children.1 = Some(&arc2); + arc2.0.borrow_mut().children.0 = Some(&arc0); + + let mut c = c_orig.clone(); + c.control_bits = 0b1; + c.curr_mark = 110; + assert!(!c.saw_prev_marked); + arc0.descend_into_self(&mut c); + assert!(c.saw_prev_marked); + + if PRINT { println!(); } + + // Cycle 13: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, rwlocks + let (arc0, arc1, arc2): (ARCRW, ARCRW, ARCRW); + arc0 = ARCRW::new("arcrw0"); + arc1 = ARCRW::new("arcrw1"); + arc2 = ARCRW::new("arcrw2"); + arc0.0.write().unwrap().children.0 = Some(&arc1); + arc0.0.write().unwrap().children.1 = Some(&arc2); + arc2.0.write().unwrap().children.0 = Some(&arc0); + + let mut c = c_orig.clone(); + c.control_bits = 0b1; + c.curr_mark = 110; + assert!(!c.saw_prev_marked); + arc0.descend_into_self(&mut c); + assert!(c.saw_prev_marked); + + if PRINT { println!(); } + + // Cycle 14: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, mutexs + let (arc0, arc1, arc2): (ARCM, ARCM, ARCM); + arc0 = ARCM::new("arcm0"); + arc1 = ARCM::new("arcm1"); + arc2 = ARCM::new("arcm2"); + arc0.1.lock().unwrap().children.0 = Some(&arc1); + arc0.1.lock().unwrap().children.1 = Some(&arc2); + arc2.1.lock().unwrap().children.0 = Some(&arc0); + + let mut c = c_orig.clone(); + c.control_bits = 0b1; + c.curr_mark = 110; + assert!(!c.saw_prev_marked); + arc0.descend_into_self(&mut c); + assert!(c.saw_prev_marked); +} + +trait Named { + fn new(_: &'static str) -> Self; + fn name(&self) -> &str; +} + +trait Marked { + fn mark(&self) -> M; + fn set_mark(&self, mark: M); +} + +struct S<'a> { + name: &'static str, + mark: Cell, + next: Cell>>, +} + +impl<'a> Named for S<'a> { + fn new(name: &'static str) -> S<'a> { + S { name: name, mark: Cell::new(0), next: Cell::new(None) } + } + fn name(&self) -> &str { self.name } +} + +impl<'a> Marked for S<'a> { + fn mark(&self) -> u32 { self.mark.get() } + fn set_mark(&self, mark: u32) { self.mark.set(mark); } +} + +struct S2<'a> { + name: &'static str, + mark: Cell, + next: Cell<(Option<&'a S2<'a>>, Option<&'a S2<'a>>)>, +} + +impl<'a> Named for S2<'a> { + fn new(name: &'static str) -> S2<'a> { + S2 { name: name, mark: Cell::new(0), next: Cell::new((None, None)) } + } + fn name(&self) -> &str { self.name } +} + +impl<'a> Marked for S2<'a> { + fn mark(&self) -> u32 { self.mark.get() } + fn set_mark(&self, mark: u32) { + self.mark.set(mark); + } +} + +struct V<'a> { + name: &'static str, + mark: Cell, + contents: Vec>>>, +} + +impl<'a> Named for V<'a> { + fn new(name: &'static str) -> V<'a> { + V { name: name, + mark: Cell::new(0), + contents: vec![Cell::new(None), Cell::new(None)] + } + } + fn name(&self) -> &str { self.name } +} + +impl<'a> Marked for V<'a> { + fn mark(&self) -> u32 { self.mark.get() } + fn set_mark(&self, mark: u32) { self.mark.set(mark); } +} + +#[derive(Eq)] +struct H<'a> { + name: &'static str, + mark: Cell, + next: Cell>>, +} + +impl<'a> Named for H<'a> { + fn new(name: &'static str) -> H<'a> { + H { name: name, mark: Cell::new(0), next: Cell::new(None) } + } + fn name(&self) -> &str { self.name } +} + +impl<'a> Marked for H<'a> { + fn mark(&self) -> u32 { self.mark.get() } + fn set_mark(&self, mark: u32) { self.mark.set(mark); } +} + +impl<'a> PartialEq for H<'a> { + fn eq(&self, rhs: &H<'a>) -> bool { + self.name == rhs.name + } +} + +impl<'a> Hash for H<'a> { + fn hash(&self, state: &mut H) { + self.name.hash(state) + } +} + +#[derive(Eq)] +struct HM<'a> { + name: &'static str, + mark: Cell, + contents: Cell, HM<'a>>>>, +} + +impl<'a> Named for HM<'a> { + fn new(name: &'static str) -> HM<'a> { + HM { name: name, + mark: Cell::new(0), + contents: Cell::new(None) + } + } + fn name(&self) -> &str { self.name } +} + +impl<'a> Marked for HM<'a> { + fn mark(&self) -> u32 { self.mark.get() } + fn set_mark(&self, mark: u32) { self.mark.set(mark); } +} + +impl<'a> PartialEq for HM<'a> { + fn eq(&self, rhs: &HM<'a>) -> bool { + self.name == rhs.name + } +} + +impl<'a> Hash for HM<'a> { + fn hash(&self, state: &mut H) { + self.name.hash(state) + } +} + + +struct VD<'a> { + name: &'static str, + mark: Cell, + contents: Cell>>>, +} + +impl<'a> Named for VD<'a> { + fn new(name: &'static str) -> VD<'a> { + VD { name: name, + mark: Cell::new(0), + contents: Cell::new(None) + } + } + fn name(&self) -> &str { self.name } +} + +impl<'a> Marked for VD<'a> { + fn mark(&self) -> u32 { self.mark.get() } + fn set_mark(&self, mark: u32) { self.mark.set(mark); } +} + +struct VM<'a> { + name: &'static str, + mark: Cell, + contents: Cell>>>, +} + +impl<'a> Named for VM<'a> { + fn new(name: &'static str) -> VM<'a> { + VM { name: name, + mark: Cell::new(0), + contents: Cell::new(None) + } + } + fn name(&self) -> &str { self.name } +} + +impl<'a> Marked for VM<'a> { + fn mark(&self) -> u32 { self.mark.get() } + fn set_mark(&self, mark: u32) { self.mark.set(mark); } +} + +struct LL<'a> { + name: &'static str, + mark: Cell, + contents: Cell>>>, +} + +impl<'a> Named for LL<'a> { + fn new(name: &'static str) -> LL<'a> { + LL { name: name, + mark: Cell::new(0), + contents: Cell::new(None) + } + } + fn name(&self) -> &str { self.name } +} + +impl<'a> Marked for LL<'a> { + fn mark(&self) -> u32 { self.mark.get() } + fn set_mark(&self, mark: u32) { self.mark.set(mark); } +} + +struct BH<'a> { + name: &'static str, + mark: Cell, + contents: Cell>>>, +} + +impl<'a> Named for BH<'a> { + fn new(name: &'static str) -> BH<'a> { + BH { name: name, + mark: Cell::new(0), + contents: Cell::new(None) + } + } + fn name(&self) -> &str { self.name } +} + +impl<'a> Marked for BH<'a> { + fn mark(&self) -> u32 { self.mark.get() } + fn set_mark(&self, mark: u32) { self.mark.set(mark); } +} + +impl<'a> Eq for BH<'a> { } + +impl<'a> PartialEq for BH<'a> { + fn eq(&self, rhs: &BH<'a>) -> bool { + self.name == rhs.name + } +} + +impl<'a> PartialOrd for BH<'a> { + fn partial_cmp(&self, rhs: &BH<'a>) -> Option { + Some(self.cmp(rhs)) + } +} + +impl<'a> Ord for BH<'a> { + fn cmp(&self, rhs: &BH<'a>) -> Ordering { + self.name.cmp(rhs.name) + } +} + +struct BTM<'a> { + name: &'static str, + mark: Cell, + contents: Cell, BTM<'a>>>>, +} + +impl<'a> Named for BTM<'a> { + fn new(name: &'static str) -> BTM<'a> { + BTM { name: name, + mark: Cell::new(0), + contents: Cell::new(None) + } + } + fn name(&self) -> &str { self.name } +} + +impl<'a> Marked for BTM<'a> { + fn mark(&self) -> u32 { self.mark.get() } + fn set_mark(&self, mark: u32) { self.mark.set(mark); } +} + +impl<'a> Eq for BTM<'a> { } + +impl<'a> PartialEq for BTM<'a> { + fn eq(&self, rhs: &BTM<'a>) -> bool { + self.name == rhs.name + } +} + +impl<'a> PartialOrd for BTM<'a> { + fn partial_cmp(&self, rhs: &BTM<'a>) -> Option { + Some(self.cmp(rhs)) + } +} + +impl<'a> Ord for BTM<'a> { + fn cmp(&self, rhs: &BTM<'a>) -> Ordering { + self.name.cmp(rhs.name) + } +} + +struct BTS<'a> { + name: &'static str, + mark: Cell, + contents: Cell>>>, +} + +impl<'a> Named for BTS<'a> { + fn new(name: &'static str) -> BTS<'a> { + BTS { name: name, + mark: Cell::new(0), + contents: Cell::new(None) + } + } + fn name(&self) -> &str { self.name } +} + +impl<'a> Marked for BTS<'a> { + fn mark(&self) -> u32 { self.mark.get() } + fn set_mark(&self, mark: u32) { self.mark.set(mark); } +} + +impl<'a> Eq for BTS<'a> { } + +impl<'a> PartialEq for BTS<'a> { + fn eq(&self, rhs: &BTS<'a>) -> bool { + self.name == rhs.name + } +} + +impl<'a> PartialOrd for BTS<'a> { + fn partial_cmp(&self, rhs: &BTS<'a>) -> Option { + Some(self.cmp(rhs)) + } +} + +impl<'a> Ord for BTS<'a> { + fn cmp(&self, rhs: &BTS<'a>) -> Ordering { + self.name.cmp(rhs.name) + } +} + +#[derive(Clone)] +struct RCRCData<'a> { + name: &'static str, + mark: Cell, + children: (Option<&'a RCRC<'a>>, Option<&'a RCRC<'a>>), +} +#[derive(Clone)] +struct RCRC<'a>(Rc>>); + +impl<'a> Named for RCRC<'a> { + fn new(name: &'static str) -> Self { + RCRC(Rc::new(RefCell::new(RCRCData { + name: name, mark: Cell::new(0), children: (None, None), }))) + } + fn name(&self) -> &str { self.0.borrow().name } +} + +impl<'a> Marked for RCRC<'a> { + fn mark(&self) -> u32 { self.0.borrow().mark.get() } + fn set_mark(&self, mark: u32) { self.0.borrow().mark.set(mark); } +} + +impl<'a> Children<'a> for RCRC<'a> { + fn count_children(&self) -> usize { 2 } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost, Self: Sized + { + let children = &self.0.borrow().children; + let child = match index { + 0 => if let Some(child) = children.0 { child } else { return; }, + 1 => if let Some(child) = children.1 { child } else { return; }, + _ => panic!("bad children"), + }; + // println!("S2 {} descending into child {} at index {}", self.name, child.name, index); + child.descend_into_self(context); + } +} +#[derive(Clone)] +struct ARCRCData<'a> { + name: &'static str, + mark: Cell, + children: (Option<&'a ARCRC<'a>>, Option<&'a ARCRC<'a>>), +} +#[derive(Clone)] +struct ARCRC<'a>(Arc>>); + +impl<'a> Named for ARCRC<'a> { + fn new(name: &'static str) -> Self { + ARCRC(Arc::new(RefCell::new(ARCRCData { + name: name, mark: Cell::new(0), children: (None, None), }))) + } + fn name(&self) -> &str { self.0.borrow().name } +} + +impl<'a> Marked for ARCRC<'a> { + fn mark(&self) -> u32 { self.0.borrow().mark.get() } + fn set_mark(&self, mark: u32) { self.0.borrow().mark.set(mark); } +} + +impl<'a> Children<'a> for ARCRC<'a> { + fn count_children(&self) -> usize { 2 } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost, Self: Sized + { + let children = &self.0.borrow().children; + match index { + 0 => if let Some(ref child) = children.0 { + child.descend_into_self(context); + }, + 1 => if let Some(ref child) = children.1 { + child.descend_into_self(context); + }, + _ => panic!("bad children!"), + } + } +} + +#[derive(Clone)] +struct ARCMData<'a> { + mark: Cell, + children: (Option<&'a ARCM<'a>>, Option<&'a ARCM<'a>>), +} + +#[derive(Clone)] +struct ARCM<'a>(&'static str, Arc>>); + +impl<'a> Named for ARCM<'a> { + fn new(name: &'static str) -> Self { + ARCM(name, Arc::new(Mutex::new(ARCMData { + mark: Cell::new(0), children: (None, None), }))) + } + fn name(&self) -> &str { self.0 } +} + +impl<'a> Marked for ARCM<'a> { + fn mark(&self) -> u32 { self.1.lock().unwrap().mark.get() } + fn set_mark(&self, mark: u32) { self.1.lock().unwrap().mark.set(mark); } +} + +impl<'a> Children<'a> for ARCM<'a> { + fn count_children(&self) -> usize { 2 } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost, Self: Sized + { + let ref children = if let Ok(data) = self.1.try_lock() { + data.children + } else { return; }; + match index { + 0 => if let Some(ref child) = children.0 { + child.descend_into_self(context); + }, + 1 => if let Some(ref child) = children.1 { + child.descend_into_self(context); + }, + _ => panic!("bad children!"), + } + } +} + +#[derive(Clone)] +struct ARCRWData<'a> { + name: &'static str, + mark: Cell, + children: (Option<&'a ARCRW<'a>>, Option<&'a ARCRW<'a>>), +} + +#[derive(Clone)] +struct ARCRW<'a>(Arc>>); + +impl<'a> Named for ARCRW<'a> { + fn new(name: &'static str) -> Self { + ARCRW(Arc::new(RwLock::new(ARCRWData { + name: name, mark: Cell::new(0), children: (None, None), }))) + } + fn name(&self) -> &str { self.0.read().unwrap().name } +} + +impl<'a> Marked for ARCRW<'a> { + fn mark(&self) -> u32 { self.0.read().unwrap().mark.get() } + fn set_mark(&self, mark: u32) { self.0.read().unwrap().mark.set(mark); } +} + +impl<'a> Children<'a> for ARCRW<'a> { + fn count_children(&self) -> usize { 2 } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost, Self: Sized + { + let children = &self.0.read().unwrap().children; + match index { + 0 => if let Some(ref child) = children.0 { + child.descend_into_self(context); + }, + 1 => if let Some(ref child) = children.1 { + child.descend_into_self(context); + }, + _ => panic!("bad children!"), + } + } +} + +trait Context { + fn next_index(&mut self, len: usize) -> usize; + fn should_act(&self) -> bool; + fn increase_visited(&mut self); + fn increase_skipped(&mut self); + fn increase_depth(&mut self); + fn decrease_depth(&mut self); +} + +trait PrePost { + fn pre(&mut self, _: &T); + fn post(&mut self, _: &T); + fn hit_limit(&mut self, _: &T); +} + +trait Children<'a> { + fn count_children(&self) -> usize; + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost, Self: Sized; + + fn next_child(&self, context: &mut C) + where C: Context + PrePost, Self: Sized + { + let index = context.next_index(self.count_children()); + self.descend_one_child(context, index); + } + + fn descend_into_self(&self, context: &mut C) + where C: Context + PrePost, Self: Sized + { + context.pre(self); + if context.should_act() { + context.increase_visited(); + context.increase_depth(); + self.next_child(context); + context.decrease_depth(); + } else { + context.hit_limit(self); + context.increase_skipped(); + } + context.post(self); + } + + fn descend<'b, C>(&self, c: &Cell>, context: &mut C) + where C: Context + PrePost, Self: Sized + { + if let Some(r) = c.get() { + r.descend_into_self(context); + } + } +} + +impl<'a> Children<'a> for S<'a> { + fn count_children(&self) -> usize { 1 } + fn descend_one_child(&self, context: &mut C, _: usize) + where C: Context + PrePost, Self: Sized { + self.descend(&self.next, context); + } +} + +impl<'a> Children<'a> for S2<'a> { + fn count_children(&self) -> usize { 2 } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost, Self: Sized + { + let children = self.next.get(); + let child = match index { + 0 => if let Some(child) = children.0 { child } else { return; }, + 1 => if let Some(child) = children.1 { child } else { return; }, + _ => panic!("bad children"), + }; + // println!("S2 {} descending into child {} at index {}", self.name, child.name, index); + child.descend_into_self(context); + } +} + +impl<'a> Children<'a> for V<'a> { + fn count_children(&self) -> usize { self.contents.len() } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost, Self: Sized + { + if let Some(child) = self.contents[index].get() { + child.descend_into_self(context); + } + } +} + +impl<'a> Children<'a> for H<'a> { + fn count_children(&self) -> usize { 1 } + fn descend_one_child(&self, context: &mut C, _: usize) + where C: Context + PrePost, Self: Sized + { + self.descend(&self.next, context); + } +} + +impl<'a> Children<'a> for HM<'a> { + fn count_children(&self) -> usize { + if let Some(m) = self.contents.get() { 2 * m.iter().count() } else { 0 } + } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost, Self: Sized + { + if let Some(ref hm) = self.contents.get() { + for (k, v) in hm.iter().nth(index / 2) { + [k, v][index % 2].descend_into_self(context); + } + } + } +} + +impl<'a> Children<'a> for VD<'a> { + fn count_children(&self) -> usize { + if let Some(d) = self.contents.get() { d.iter().count() } else { 0 } + } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost, Self: Sized + { + if let Some(ref vd) = self.contents.get() { + for r in vd.iter().nth(index) { + r.descend_into_self(context); + } + } + } +} + +impl<'a> Children<'a> for VM<'a> { + fn count_children(&self) -> usize { + if let Some(m) = self.contents.get() { m.iter().count() } else { 0 } + } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost> + { + if let Some(ref vd) = self.contents.get() { + for (_idx, r) in vd.iter().nth(index) { + r.descend_into_self(context); + } + } + } +} + +impl<'a> Children<'a> for LL<'a> { + fn count_children(&self) -> usize { + if let Some(l) = self.contents.get() { l.iter().count() } else { 0 } + } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost> + { + if let Some(ref ll) = self.contents.get() { + for r in ll.iter().nth(index) { + r.descend_into_self(context); + } + } + } +} + +impl<'a> Children<'a> for BH<'a> { + fn count_children(&self) -> usize { + if let Some(h) = self.contents.get() { h.iter().count() } else { 0 } + } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost> + { + if let Some(ref bh) = self.contents.get() { + for r in bh.iter().nth(index) { + r.descend_into_self(context); + } + } + } +} + +impl<'a> Children<'a> for BTM<'a> { + fn count_children(&self) -> usize { + if let Some(m) = self.contents.get() { 2 * m.iter().count() } else { 0 } + } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost> + { + if let Some(ref bh) = self.contents.get() { + for (k, v) in bh.iter().nth(index / 2) { + [k, v][index % 2].descend_into_self(context); + } + } + } +} + +impl<'a> Children<'a> for BTS<'a> { + fn count_children(&self) -> usize { + if let Some(s) = self.contents.get() { s.iter().count() } else { 0 } + } + fn descend_one_child(&self, context: &mut C, index: usize) + where C: Context + PrePost> + { + if let Some(ref bh) = self.contents.get() { + for r in bh.iter().nth(index) { + r.descend_into_self(context); + } + } + } +} + +#[derive(Copy, Clone)] +struct ContextData { + curr_depth: usize, + max_depth: usize, + visited: usize, + max_visits: usize, + skipped: usize, + curr_mark: u32, + saw_prev_marked: bool, + control_bits: u64, +} + +impl Context for ContextData { + fn next_index(&mut self, len: usize) -> usize { + if len < 2 { return 0; } + let mut pow2 = len.next_power_of_two(); + let _pow2_orig = pow2; + let mut idx = 0; + let mut bits = self.control_bits; + while pow2 > 1 { + idx = (idx << 1) | (bits & 1) as usize; + bits = bits >> 1; + pow2 = pow2 >> 1; + } + idx = idx % len; + // println!("next_index({} [{:b}]) says {}, pre(bits): {:b} post(bits): {:b}", + // len, _pow2_orig, idx, self.control_bits, bits); + self.control_bits = bits; + return idx; + } + fn should_act(&self) -> bool { + self.curr_depth < self.max_depth && self.visited < self.max_visits + } + fn increase_visited(&mut self) { self.visited += 1; } + fn increase_skipped(&mut self) { self.skipped += 1; } + fn increase_depth(&mut self) { self.curr_depth += 1; } + fn decrease_depth(&mut self) { self.curr_depth -= 1; } +} + +impl> PrePost for ContextData { + fn pre(&mut self, t: &T) { + for _ in 0..self.curr_depth { + if PRINT { print!(" "); } + } + if PRINT { println!("prev {}", t.name()); } + if t.mark() == self.curr_mark { + for _ in 0..self.curr_depth { + if PRINT { print!(" "); } + } + if PRINT { println!("(probably previously marked)"); } + self.saw_prev_marked = true; + } + t.set_mark(self.curr_mark); + } + fn post(&mut self, t: &T) { + for _ in 0..self.curr_depth { + if PRINT { print!(" "); } + } + if PRINT { println!("post {}", t.name()); } + } + fn hit_limit(&mut self, t: &T) { + for _ in 0..self.curr_depth { + if PRINT { print!(" "); } + } + if PRINT { println!("LIMIT {}", t.name()); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/dynamic-drop-async.rs b/gcc/testsuite/rust/rustc/ui/drop/dynamic-drop-async.rs new file mode 100644 index 000000000000..142439fe9712 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/dynamic-drop-async.rs @@ -0,0 +1,334 @@ +// Test that values are not leaked in async functions, even in the cases where: +// * Dropping one of the values panics while running the future. +// * The future is dropped at one of its suspend points. +// * Dropping one of the values panics while dropping the future. + +// run-pass +// edition:2018 +// ignore-wasm32-bare compiled with panic=abort by default + +#![allow(unused)] + +use std::{ + cell::{Cell, RefCell}, + future::Future, + marker::Unpin, + panic, + pin::Pin, + ptr, + rc::Rc, + task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, + usize, +}; + +struct InjectedFailure; + +struct Defer { + ready: bool, + value: Option, +} + +impl Future for Defer { + type Output = T; + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + if self.ready { + Poll::Ready(self.value.take().unwrap()) + } else { + self.ready = true; + Poll::Pending + } + } +} + +/// Allocator tracks the creation and destruction of `Ptr`s. +/// The `failing_op`-th operation will panic. +struct Allocator { + data: RefCell>, + failing_op: usize, + cur_ops: Cell, +} + +impl panic::UnwindSafe for Allocator {} +impl panic::RefUnwindSafe for Allocator {} + +impl Drop for Allocator { + fn drop(&mut self) { + let data = self.data.borrow(); + if data.iter().any(|d| *d) { + panic!("missing free: {:?}", data); + } + } +} + +impl Allocator { + fn new(failing_op: usize) -> Self { + Allocator { failing_op, cur_ops: Cell::new(0), data: RefCell::new(vec![]) } + } + fn alloc(&self) -> impl Future> + '_ { + self.fallible_operation(); + + let mut data = self.data.borrow_mut(); + + let addr = data.len(); + data.push(true); + Defer { ready: false, value: Some(Ptr(addr, self)) } + } + fn fallible_operation(&self) { + self.cur_ops.set(self.cur_ops.get() + 1); + + if self.cur_ops.get() == self.failing_op { + panic!(InjectedFailure); + } + } +} + +// Type that tracks whether it was dropped and can panic when it's created or +// destroyed. +struct Ptr<'a>(usize, &'a Allocator); +impl<'a> Drop for Ptr<'a> { + fn drop(&mut self) { + match self.1.data.borrow_mut()[self.0] { + false => panic!("double free at index {:?}", self.0), + ref mut d => *d = false, + } + + self.1.fallible_operation(); + } +} + +async fn dynamic_init(a: Rc, c: bool) { + let _x; + if c { + _x = Some(a.alloc().await); + } +} + +async fn dynamic_drop(a: Rc, c: bool) { + let x = a.alloc().await; + if c { + Some(x) + } else { + None + }; +} + +struct TwoPtrs<'a>(Ptr<'a>, Ptr<'a>); +async fn struct_dynamic_drop(a: Rc, c0: bool, c1: bool, c: bool) { + for i in 0..2 { + let x; + let y; + if (c0 && i == 0) || (c1 && i == 1) { + x = (a.alloc().await, a.alloc().await, a.alloc().await); + y = TwoPtrs(a.alloc().await, a.alloc().await); + if c { + drop(x.1); + a.alloc().await; + drop(y.0); + a.alloc().await; + } + } + } +} + +async fn field_assignment(a: Rc, c0: bool) { + let mut x = (TwoPtrs(a.alloc().await, a.alloc().await), a.alloc().await); + + x.1 = a.alloc().await; + x.1 = a.alloc().await; + + let f = (x.0).0; + a.alloc().await; + if c0 { + (x.0).0 = f; + } + a.alloc().await; +} + +async fn assignment(a: Rc, c0: bool, c1: bool) { + let mut _v = a.alloc().await; + let mut _w = a.alloc().await; + if c0 { + drop(_v); + } + _v = _w; + if c1 { + _w = a.alloc().await; + } +} + +async fn array_simple(a: Rc) { + let _x = [a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await]; +} + +async fn vec_simple(a: Rc) { + let _x = vec![a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await]; +} + +async fn mixed_drop_and_nondrop(a: Rc) { + // check that destructor panics handle drop + // and non-drop blocks in the same scope correctly. + // + // Surprisingly enough, this used to not work. + let (x, y, z); + x = a.alloc().await; + y = 5; + z = a.alloc().await; +} + +#[allow(unreachable_code)] +async fn vec_unreachable(a: Rc) { + let _x = vec![a.alloc().await, a.alloc().await, a.alloc().await, return]; +} + +async fn slice_pattern_one_of(a: Rc, i: usize) { + let array = [a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await]; + let _x = match i { + 0 => { + let [a, ..] = array; + a + } + 1 => { + let [_, a, ..] = array; + a + } + 2 => { + let [_, _, a, _] = array; + a + } + 3 => { + let [_, _, _, a] = array; + a + } + _ => panic!("unmatched"), + }; + a.alloc().await; +} + +async fn subslice_pattern_from_end_with_drop(a: Rc, arg: bool, arg2: bool) { + let arr = [a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await]; + if arg2 { + drop(arr); + return; + } + + if arg { + let [.., _x, _] = arr; + } else { + let [_, _y @ ..] = arr; + } + a.alloc().await; +} + +async fn subslice_pattern_reassign(a: Rc) { + let mut ar = [a.alloc().await, a.alloc().await, a.alloc().await]; + let [_, _, _x] = ar; + ar = [a.alloc().await, a.alloc().await, a.alloc().await]; + let [_, _y @ ..] = ar; + a.alloc().await; +} + +async fn move_ref_pattern(a: Rc) { + let mut tup = (a.alloc().await, a.alloc().await, a.alloc().await, a.alloc().await); + let (ref _a, ref mut _b, _c, mut _d) = tup; + a.alloc().await; +} + +fn run_test(cx: &mut Context<'_>, ref f: F) +where + F: Fn(Rc) -> G, + G: Future, +{ + for polls in 0.. { + // Run without any panics to find which operations happen after the + // penultimate `poll`. + let first_alloc = Rc::new(Allocator::new(usize::MAX)); + let mut fut = Box::pin(f(first_alloc.clone())); + let mut ops_before_last_poll = 0; + let mut completed = false; + for _ in 0..polls { + ops_before_last_poll = first_alloc.cur_ops.get(); + if let Poll::Ready(()) = fut.as_mut().poll(cx) { + completed = true; + } + } + drop(fut); + + // Start at `ops_before_last_poll` so that we will always be able to + // `poll` the expected number of times. + for failing_op in ops_before_last_poll..first_alloc.cur_ops.get() { + let alloc = Rc::new(Allocator::new(failing_op + 1)); + let f = &f; + let cx = &mut *cx; + let result = panic::catch_unwind(panic::AssertUnwindSafe(move || { + let mut fut = Box::pin(f(alloc)); + for _ in 0..polls { + let _ = fut.as_mut().poll(cx); + } + drop(fut); + })); + match result { + Ok(..) => panic!("test executed more ops on first call"), + Err(e) => { + if e.downcast_ref::().is_none() { + panic::resume_unwind(e); + } + } + } + } + + if completed { + break; + } + } +} + +fn clone_waker(data: *const ()) -> RawWaker { + RawWaker::new(data, &RawWakerVTable::new(clone_waker, drop, drop, drop)) +} + +fn main() { + let waker = unsafe { Waker::from_raw(clone_waker(ptr::null())) }; + let context = &mut Context::from_waker(&waker); + + run_test(context, |a| dynamic_init(a, false)); + run_test(context, |a| dynamic_init(a, true)); + run_test(context, |a| dynamic_drop(a, false)); + run_test(context, |a| dynamic_drop(a, true)); + + run_test(context, |a| assignment(a, false, false)); + run_test(context, |a| assignment(a, false, true)); + run_test(context, |a| assignment(a, true, false)); + run_test(context, |a| assignment(a, true, true)); + + run_test(context, |a| array_simple(a)); + run_test(context, |a| vec_simple(a)); + run_test(context, |a| vec_unreachable(a)); + + run_test(context, |a| struct_dynamic_drop(a, false, false, false)); + run_test(context, |a| struct_dynamic_drop(a, false, false, true)); + run_test(context, |a| struct_dynamic_drop(a, false, true, false)); + run_test(context, |a| struct_dynamic_drop(a, false, true, true)); + run_test(context, |a| struct_dynamic_drop(a, true, false, false)); + run_test(context, |a| struct_dynamic_drop(a, true, false, true)); + run_test(context, |a| struct_dynamic_drop(a, true, true, false)); + run_test(context, |a| struct_dynamic_drop(a, true, true, true)); + + run_test(context, |a| field_assignment(a, false)); + run_test(context, |a| field_assignment(a, true)); + + run_test(context, |a| mixed_drop_and_nondrop(a)); + + run_test(context, |a| slice_pattern_one_of(a, 0)); + run_test(context, |a| slice_pattern_one_of(a, 1)); + run_test(context, |a| slice_pattern_one_of(a, 2)); + run_test(context, |a| slice_pattern_one_of(a, 3)); + + run_test(context, |a| subslice_pattern_from_end_with_drop(a, true, true)); + run_test(context, |a| subslice_pattern_from_end_with_drop(a, true, false)); + run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, true)); + run_test(context, |a| subslice_pattern_from_end_with_drop(a, false, false)); + run_test(context, |a| subslice_pattern_reassign(a)); + + run_test(context, |a| move_ref_pattern(a)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/dynamic-drop.rs b/gcc/testsuite/rust/rustc/ui/drop/dynamic-drop.rs new file mode 100644 index 000000000000..2f63f243fe29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/dynamic-drop.rs @@ -0,0 +1,523 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(generators, generator_trait)] +#![feature(bindings_after_at)] + +#![allow(unused_assignments)] +#![allow(unused_variables)] + +use std::cell::{Cell, RefCell}; +use std::mem::ManuallyDrop; +use std::ops::Generator; +use std::panic; +use std::pin::Pin; +use std::usize; + +struct InjectedFailure; + +struct Allocator { + data: RefCell>, + failing_op: usize, + cur_ops: Cell, +} + +impl panic::UnwindSafe for Allocator {} +impl panic::RefUnwindSafe for Allocator {} + +impl Drop for Allocator { + fn drop(&mut self) { + let data = self.data.borrow(); + if data.iter().any(|d| *d) { + panic!("missing free: {:?}", data); + } + } +} + +impl Allocator { + fn new(failing_op: usize) -> Self { + Allocator { + failing_op: failing_op, + cur_ops: Cell::new(0), + data: RefCell::new(vec![]) + } + } + fn alloc(&self) -> Ptr<'_> { + self.cur_ops.set(self.cur_ops.get() + 1); + + if self.cur_ops.get() == self.failing_op { + panic!(InjectedFailure); + } + + let mut data = self.data.borrow_mut(); + let addr = data.len(); + data.push(true); + Ptr(addr, self) + } + // FIXME(#47949) Any use of this indicates a bug in rustc: we should never + // be leaking values in the cases here. + // + // Creates a `Ptr<'_>` and checks that the allocated value is leaked if the + // `failing_op` is in the list of exception. + fn alloc_leaked(&self, exceptions: Vec) -> Ptr<'_> { + let ptr = self.alloc(); + + if exceptions.iter().any(|operation| *operation == self.failing_op) { + let mut data = self.data.borrow_mut(); + data[ptr.0] = false; + } + ptr + } +} + +struct Ptr<'a>(usize, &'a Allocator); +impl<'a> Drop for Ptr<'a> { + fn drop(&mut self) { + match self.1.data.borrow_mut()[self.0] { + false => { + panic!("double free at index {:?}", self.0) + } + ref mut d => *d = false + } + + self.1.cur_ops.set(self.1.cur_ops.get()+1); + + if self.1.cur_ops.get() == self.1.failing_op { + panic!(InjectedFailure); + } + } +} + +fn dynamic_init(a: &Allocator, c: bool) { + let _x; + if c { + _x = Some(a.alloc()); + } +} + +fn dynamic_drop(a: &Allocator, c: bool) { + let x = a.alloc(); + if c { + Some(x) + } else { + None + }; +} + +struct TwoPtrs<'a>(Ptr<'a>, Ptr<'a>); +fn struct_dynamic_drop(a: &Allocator, c0: bool, c1: bool, c: bool) { + for i in 0..2 { + let x; + let y; + if (c0 && i == 0) || (c1 && i == 1) { + x = (a.alloc(), a.alloc(), a.alloc()); + y = TwoPtrs(a.alloc(), a.alloc()); + if c { + drop(x.1); + drop(y.0); + } + } + } +} + +fn field_assignment(a: &Allocator, c0: bool) { + let mut x = (TwoPtrs(a.alloc(), a.alloc()), a.alloc()); + + x.1 = a.alloc(); + x.1 = a.alloc(); + + let f = (x.0).0; + if c0 { + (x.0).0 = f; + } +} + +fn assignment2(a: &Allocator, c0: bool, c1: bool) { + let mut _v = a.alloc(); + let mut _w = a.alloc(); + if c0 { + drop(_v); + } + _v = _w; + if c1 { + _w = a.alloc(); + } +} + +fn assignment1(a: &Allocator, c0: bool) { + let mut _v = a.alloc(); + let mut _w = a.alloc(); + if c0 { + drop(_v); + } + _v = _w; +} + +union Boxy { + a: ManuallyDrop, + b: ManuallyDrop, +} + +fn union1(a: &Allocator) { + unsafe { + let mut u = Boxy { a: ManuallyDrop::new(a.alloc()) }; + *u.b = a.alloc(); // drops first alloc + drop(ManuallyDrop::into_inner(u.a)); + } +} + +fn array_simple(a: &Allocator) { + let _x = [a.alloc(), a.alloc(), a.alloc(), a.alloc()]; +} + +fn vec_simple(a: &Allocator) { + let _x = vec![a.alloc(), a.alloc(), a.alloc(), a.alloc()]; +} + +fn generator(a: &Allocator, run_count: usize) { + assert!(run_count < 4); + + let mut gen = || { + (a.alloc(), + yield a.alloc(), + a.alloc(), + yield a.alloc() + ); + }; + for _ in 0..run_count { + Pin::new(&mut gen).resume(()); + } +} + +fn mixed_drop_and_nondrop(a: &Allocator) { + // check that destructor panics handle drop + // and non-drop blocks in the same scope correctly. + // + // Surprisingly enough, this used to not work. + let (x, y, z); + x = a.alloc(); + y = 5; + z = a.alloc(); +} + +#[allow(unreachable_code)] +fn vec_unreachable(a: &Allocator) { + let _x = vec![a.alloc(), a.alloc(), a.alloc(), return]; +} + +fn slice_pattern_first(a: &Allocator) { + let[_x, ..] = [a.alloc(), a.alloc(), a.alloc()]; +} + +fn slice_pattern_middle(a: &Allocator) { + let[_, _x, _] = [a.alloc(), a.alloc(), a.alloc()]; +} + +fn slice_pattern_two(a: &Allocator) { + let[_x, _, _y, _] = [a.alloc(), a.alloc(), a.alloc(), a.alloc()]; +} + +fn slice_pattern_last(a: &Allocator) { + let[.., _y] = [a.alloc(), a.alloc(), a.alloc(), a.alloc()]; +} + +fn slice_pattern_one_of(a: &Allocator, i: usize) { + let array = [a.alloc(), a.alloc(), a.alloc(), a.alloc()]; + let _x = match i { + 0 => { let [a, ..] = array; a } + 1 => { let [_, a, ..] = array; a } + 2 => { let [_, _, a, _] = array; a } + 3 => { let [_, _, _, a] = array; a } + _ => panic!("unmatched"), + }; +} + +fn subslice_pattern_from_end(a: &Allocator, arg: bool) { + let a = [a.alloc(), a.alloc(), a.alloc()]; + if arg { + let[.., _x, _] = a; + } else { + let[_, _y @ ..] = a; + } +} + +fn subslice_pattern_from_end_with_drop(a: &Allocator, arg: bool, arg2: bool) { + let a = [a.alloc(), a.alloc(), a.alloc(), a.alloc(), a.alloc()]; + if arg2 { + drop(a); + return; + } + + if arg { + let[.., _x, _] = a; + } else { + let[_, _y @ ..] = a; + } +} + +fn slice_pattern_reassign(a: &Allocator) { + let mut ar = [a.alloc(), a.alloc()]; + let[_, _x] = ar; + ar = [a.alloc(), a.alloc()]; + let[.., _y] = ar; +} + +fn subslice_pattern_reassign(a: &Allocator) { + let mut ar = [a.alloc(), a.alloc(), a.alloc()]; + let[_, _, _x] = ar; + ar = [a.alloc(), a.alloc(), a.alloc()]; + let[_, _y @ ..] = ar; +} + +fn index_field_mixed_ends(a: &Allocator) { + let ar = [(a.alloc(), a.alloc()), (a.alloc(), a.alloc())]; + let[(_x, _), ..] = ar; + let[(_, _y), _] = ar; + let[_, (_, _w)] = ar; + let[.., (_z, _)] = ar; +} + +fn subslice_mixed_min_lengths(a: &Allocator, c: i32) { + let ar = [(a.alloc(), a.alloc()), (a.alloc(), a.alloc())]; + match c { + 0 => { let[_x, ..] = ar; } + 1 => { let[_x, _, ..] = ar; } + 2 => { let[_x, _] = ar; } + 3 => { let[(_x, _), _, ..] = ar; } + 4 => { let[.., (_x, _)] = ar; } + 5 => { let[.., (_x, _), _] = ar; } + 6 => { let [_y @ ..] = ar; } + _ => { let [_y @ .., _] = ar; } + } +} + +fn bindings_after_at_dynamic_init_move(a: &Allocator, c: bool) { + let foo = if c { Some(a.alloc()) } else { None }; + let _x; + + if let bar @ Some(_) = foo { + _x = bar; + } +} + +fn bindings_after_at_dynamic_init_ref(a: &Allocator, c: bool) { + let foo = if c { Some(a.alloc()) } else { None }; + let _x; + + if let bar @ Some(_baz) = &foo { + _x = bar; + } +} + +fn bindings_after_at_dynamic_drop_move(a: &Allocator, c: bool) { + let foo = if c { Some(a.alloc()) } else { None }; + + if let bar @ Some(_) = foo { + bar + } else { + None + }; +} + +fn bindings_after_at_dynamic_drop_ref(a: &Allocator, c: bool) { + let foo = if c { Some(a.alloc()) } else { None }; + + if let bar @ Some(_baz) = &foo { + bar + } else { + &None + }; +} + +fn move_ref_pattern(a: &Allocator) { + let mut tup = (a.alloc(), a.alloc(), a.alloc(), a.alloc()); + let (ref _a, ref mut _b, _c, mut _d) = tup; +} + +fn panic_after_return(a: &Allocator) -> Ptr<'_> { + // Panic in the drop of `p` or `q` can leak + let exceptions = vec![8, 9]; + a.alloc(); + let p = a.alloc(); + { + a.alloc(); + let p = a.alloc(); + // FIXME (#47949) We leak values when we panic in a destructor after + // evaluating an expression with `rustc_mir::build::Builder::into`. + a.alloc_leaked(exceptions) + } +} + +fn panic_after_return_expr(a: &Allocator) -> Ptr<'_> { + // Panic in the drop of `p` or `q` can leak + let exceptions = vec![8, 9]; + a.alloc(); + let p = a.alloc(); + { + a.alloc(); + let q = a.alloc(); + // FIXME (#47949) + return a.alloc_leaked(exceptions); + } +} + +fn panic_after_init(a: &Allocator) { + // Panic in the drop of `r` can leak + let exceptions = vec![8]; + a.alloc(); + let p = a.alloc(); + let q = { + a.alloc(); + let r = a.alloc(); + // FIXME (#47949) + a.alloc_leaked(exceptions) + }; +} + +fn panic_after_init_temp(a: &Allocator) { + // Panic in the drop of `r` can leak + let exceptions = vec![8]; + a.alloc(); + let p = a.alloc(); + { + a.alloc(); + let r = a.alloc(); + // FIXME (#47949) + a.alloc_leaked(exceptions) + }; +} + +fn panic_after_init_by_loop(a: &Allocator) { + // Panic in the drop of `r` can leak + let exceptions = vec![8]; + a.alloc(); + let p = a.alloc(); + let q = loop { + a.alloc(); + let r = a.alloc(); + // FIXME (#47949) + break a.alloc_leaked(exceptions); + }; +} + +fn run_test(mut f: F) + where F: FnMut(&Allocator) +{ + let first_alloc = Allocator::new(usize::MAX); + f(&first_alloc); + + for failing_op in 1..first_alloc.cur_ops.get()+1 { + let alloc = Allocator::new(failing_op); + let alloc = &alloc; + let f = panic::AssertUnwindSafe(&mut f); + let result = panic::catch_unwind(move || { + f.0(alloc); + }); + match result { + Ok(..) => panic!("test executed {} ops but now {}", + first_alloc.cur_ops.get(), alloc.cur_ops.get()), + Err(e) => { + if e.downcast_ref::().is_none() { + panic::resume_unwind(e); + } + } + } + } +} + +fn run_test_nopanic(mut f: F) + where F: FnMut(&Allocator) +{ + let first_alloc = Allocator::new(usize::MAX); + f(&first_alloc); +} + +fn main() { + run_test(|a| dynamic_init(a, false)); + run_test(|a| dynamic_init(a, true)); + run_test(|a| dynamic_drop(a, false)); + run_test(|a| dynamic_drop(a, true)); + + run_test(|a| assignment2(a, false, false)); + run_test(|a| assignment2(a, false, true)); + run_test(|a| assignment2(a, true, false)); + run_test(|a| assignment2(a, true, true)); + + run_test(|a| assignment1(a, false)); + run_test(|a| assignment1(a, true)); + + run_test(|a| array_simple(a)); + run_test(|a| vec_simple(a)); + run_test(|a| vec_unreachable(a)); + + run_test(|a| struct_dynamic_drop(a, false, false, false)); + run_test(|a| struct_dynamic_drop(a, false, false, true)); + run_test(|a| struct_dynamic_drop(a, false, true, false)); + run_test(|a| struct_dynamic_drop(a, false, true, true)); + run_test(|a| struct_dynamic_drop(a, true, false, false)); + run_test(|a| struct_dynamic_drop(a, true, false, true)); + run_test(|a| struct_dynamic_drop(a, true, true, false)); + run_test(|a| struct_dynamic_drop(a, true, true, true)); + + run_test(|a| field_assignment(a, false)); + run_test(|a| field_assignment(a, true)); + + run_test(|a| generator(a, 0)); + run_test(|a| generator(a, 1)); + run_test(|a| generator(a, 2)); + run_test(|a| generator(a, 3)); + + run_test(|a| mixed_drop_and_nondrop(a)); + + run_test(|a| slice_pattern_first(a)); + run_test(|a| slice_pattern_middle(a)); + run_test(|a| slice_pattern_two(a)); + run_test(|a| slice_pattern_last(a)); + run_test(|a| slice_pattern_one_of(a, 0)); + run_test(|a| slice_pattern_one_of(a, 1)); + run_test(|a| slice_pattern_one_of(a, 2)); + run_test(|a| slice_pattern_one_of(a, 3)); + + run_test(|a| subslice_pattern_from_end(a, true)); + run_test(|a| subslice_pattern_from_end(a, false)); + run_test(|a| subslice_pattern_from_end_with_drop(a, true, true)); + run_test(|a| subslice_pattern_from_end_with_drop(a, true, false)); + run_test(|a| subslice_pattern_from_end_with_drop(a, false, true)); + run_test(|a| subslice_pattern_from_end_with_drop(a, false, false)); + run_test(|a| slice_pattern_reassign(a)); + run_test(|a| subslice_pattern_reassign(a)); + + run_test(|a| index_field_mixed_ends(a)); + run_test(|a| subslice_mixed_min_lengths(a, 0)); + run_test(|a| subslice_mixed_min_lengths(a, 1)); + run_test(|a| subslice_mixed_min_lengths(a, 2)); + run_test(|a| subslice_mixed_min_lengths(a, 3)); + run_test(|a| subslice_mixed_min_lengths(a, 4)); + run_test(|a| subslice_mixed_min_lengths(a, 5)); + run_test(|a| subslice_mixed_min_lengths(a, 6)); + run_test(|a| subslice_mixed_min_lengths(a, 7)); + + run_test(|a| move_ref_pattern(a)); + + run_test(|a| { + panic_after_return(a); + }); + run_test(|a| { + panic_after_return_expr(a); + }); + run_test(|a| panic_after_init(a)); + run_test(|a| panic_after_init_temp(a)); + run_test(|a| panic_after_init_by_loop(a)); + + run_test(|a| bindings_after_at_dynamic_init_move(a, true)); + run_test(|a| bindings_after_at_dynamic_init_move(a, false)); + run_test(|a| bindings_after_at_dynamic_init_ref(a, true)); + run_test(|a| bindings_after_at_dynamic_init_ref(a, false)); + run_test(|a| bindings_after_at_dynamic_drop_move(a, true)); + run_test(|a| bindings_after_at_dynamic_drop_move(a, false)); + run_test(|a| bindings_after_at_dynamic_drop_ref(a, true)); + run_test(|a| bindings_after_at_dynamic_drop_ref(a, false)); + + run_test_nopanic(|a| union1(a)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/no-drop-flag-size.rs b/gcc/testsuite/rust/rustc/ui/drop/no-drop-flag-size.rs new file mode 100644 index 000000000000..282f2a8a8f8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/no-drop-flag-size.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +use std::mem::size_of; + +struct Test { + a: T +} + +impl Drop for Test { + fn drop(&mut self) { } +} + +pub fn main() { + assert_eq!(size_of::(), size_of::>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/drop/nondrop-cycle.rs b/gcc/testsuite/rust/rustc/ui/drop/nondrop-cycle.rs new file mode 100644 index 000000000000..3f0484459b59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/drop/nondrop-cycle.rs @@ -0,0 +1,32 @@ +// run-pass +// pretty-expanded FIXME #23616 + +use std::cell::Cell; + +struct C<'a> { + p: Cell>>, +} + +impl<'a> C<'a> { + fn new() -> C<'a> { C { p: Cell::new(None) } } +} + +fn f1() { + let (c1, c2) = (C::new(), C::new()); + c1.p.set(Some(&c2)); + c2.p.set(Some(&c1)); +} + +fn f2() { + let (c1, c2); + c1 = C::new(); + c2 = C::new(); + c1.p.set(Some(&c2)); + c2.p.set(Some(&c1)); +} + +fn main() { + f1(); + f2(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/auxiliary/dropck_eyepatch_extern_crate.rs b/gcc/testsuite/rust/rustc/ui/dropck/auxiliary/dropck_eyepatch_extern_crate.rs new file mode 100644 index 000000000000..86e942d40c22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/auxiliary/dropck_eyepatch_extern_crate.rs @@ -0,0 +1,38 @@ +#![feature(dropck_eyepatch)] + +// This is a support file for ../dropck-eyepatch-extern-crate.rs +// +// The point of this test is to illustrate that the `#[may_dangle]` +// attribute specifically allows, in the context of a type +// implementing `Drop`, a generic parameter to be instantiated with a +// lifetime that does not strictly outlive the owning type itself, +// and that this attribute's effects are preserved when importing +// the type from another crate. +// +// See also ../dropck-eyepatch.rs for more information about the general +// structure of the test. + +use std::fmt; + +pub struct Dt(pub &'static str, pub A); +pub struct Dr<'a, B:'a+fmt::Debug>(pub &'static str, pub &'a B); +pub struct Pt(pub &'static str, pub A, pub B); +pub struct Pr<'a, 'b, B:'a+'b+fmt::Debug>(pub &'static str, pub &'a B, pub &'b B); +pub struct St(pub &'static str, pub A); +pub struct Sr<'a, B:'a+fmt::Debug>(pub &'static str, pub &'a B); + +impl Drop for Dt { + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); } +} +impl<'a, B: fmt::Debug> Drop for Dr<'a, B> { + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); } +} +unsafe impl<#[may_dangle] A, B: fmt::Debug> Drop for Pt { + // (unsafe to access self.1 due to #[may_dangle] on A) + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } +} +unsafe impl<#[may_dangle] 'a, 'b, B: fmt::Debug> Drop for Pr<'a, 'b, B> { + // (unsafe to access self.1 due to #[may_dangle] on 'a) + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/drop-on-non-struct.rs b/gcc/testsuite/rust/rustc/ui/dropck/drop-on-non-struct.rs new file mode 100644 index 000000000000..afc47f2d3a72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/drop-on-non-struct.rs @@ -0,0 +1,16 @@ +impl<'a> Drop for &'a mut isize { +// { dg-error ".E0117." "" { target *-*-* } .-1 } +// { dg-error ".E0117." "" { target *-*-* } .-2 } + fn drop(&mut self) { + println!("kaboom"); + } +} + +impl Drop for Nonexistent { +// { dg-error ".E0412." "" { target *-*-* } .-1 } + fn drop(&mut self) { } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/drop-with-active-borrows-1.rs b/gcc/testsuite/rust/rustc/ui/dropck/drop-with-active-borrows-1.rs new file mode 100644 index 000000000000..65bb47b3c32b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/drop-with-active-borrows-1.rs @@ -0,0 +1,9 @@ +fn main() { + let a = "".to_string(); + let b: Vec<&str> = a.lines().collect(); + drop(a); // { dg-error ".E0505." "" { target *-*-* } } + for s in &b { + println!("{}", *s); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/drop-with-active-borrows-2.rs b/gcc/testsuite/rust/rustc/ui/dropck/drop-with-active-borrows-2.rs new file mode 100644 index 000000000000..c7674887b8e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/drop-with-active-borrows-2.rs @@ -0,0 +1,10 @@ +fn read_lines_borrowed<'a>() -> Vec<&'a str> { + let raw_lines: Vec = vec!["foo ".to_string(), " bar".to_string()]; + raw_lines.iter().map(|l| l.trim()).collect() +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +fn main() { + println!("{:?}", read_lines_borrowed()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch-extern-crate.rs b/gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch-extern-crate.rs new file mode 100644 index 000000000000..5c50443609d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch-extern-crate.rs @@ -0,0 +1,83 @@ +// aux-build:dropck_eyepatch_extern_crate.rs + +// The point of this test is to illustrate that the `#[may_dangle]` +// attribute specifically allows, in the context of a type +// implementing `Drop`, a generic parameter to be instantiated with a +// lifetime that does not strictly outlive the owning type itself, +// and that this attribute's effects are preserved when importing +// the type from another crate. +// +// See also dropck-eyepatch.rs for more information about the general +// structure of the test. +extern crate dropck_eyepatch_extern_crate as other; + +use other::{Dt,Dr,Pt,Pr,St,Sr}; + +fn main() { + use std::cell::Cell; + + // We use separate blocks with separate variable to prevent the error + // messages from being deduplicated. + + { + let c_long; + let (mut dt, mut dr): (Dt<_>, Dr<_>); + c_long = Cell::new(1); + + // No error: sufficiently long-lived state can be referenced in dtors + dt = Dt("dt", &c_long); + dr = Dr("dr", &c_long); + } + + { + let (c, mut dt, mut dr): (Cell<_>, Dt<_>, Dr<_>); + c = Cell::new(1); + + // No Error: destructor order precisely modelled + dt = Dt("dt", &c); + dr = Dr("dr", &c); + } + + { + let (mut dt, mut dr, c_shortest): (Dt<_>, Dr<_>, Cell<_>); + c_shortest = Cell::new(1); + + // Error: `c_shortest` dies too soon for the references in dtors to be valid. + dt = Dt("dt", &c_shortest); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + dr = Dr("dr", &c_shortest); + } + + { + let c_long; + let (mut pt, mut pr, c_shortest): (Pt<_, _>, Pr<_>, Cell<_>); + c_long = Cell::new(1); + c_shortest = Cell::new(1); + + // No error: Drop impl asserts .1 (A and &'a _) are not accessed + pt = Pt("pt", &c_shortest, &c_long); + pr = Pr("pr", &c_shortest, &c_long); + } + + { + let c_long; + let (mut pt, mut pr, c_shortest): (Pt<_, _>, Pr<_>, Cell<_>); + c_long = Cell::new(1); + c_shortest = Cell::new(1); + // Error: Drop impl's assertion does not apply to `B` nor `&'b _` + pt = Pt("pt", &c_long, &c_shortest); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + pr = Pr("pr", &c_long, &c_shortest); + } + + { + let (st, sr, c_shortest): (St<_>, Sr<_>, Cell<_>); + c_shortest = Cell::new(1); + // No error: St and Sr have no destructor. + st = St("st", &c_shortest); + sr = Sr("sr", &c_shortest); + } +} + +fn use_imm(_: &T) { } + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch-implies-unsafe-impl.rs b/gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch-implies-unsafe-impl.rs new file mode 100644 index 000000000000..63435de3f0c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch-implies-unsafe-impl.rs @@ -0,0 +1,36 @@ +#![feature(dropck_eyepatch)] + +// This test ensures that a use of `#[may_dangle]` is rejected if +// it is not attached to an `unsafe impl`. + +use std::fmt; + +struct Dt(&'static str, A); +struct Dr<'a, B:'a+fmt::Debug>(&'static str, &'a B); +struct Pt(&'static str, A, B); +struct Pr<'a, 'b, B:'a+'b+fmt::Debug>(&'static str, &'a B, &'b B); +struct St(&'static str, A); +struct Sr<'a, B:'a+fmt::Debug>(&'static str, &'a B); + +impl Drop for Dt { + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); } +} +impl<'a, B: fmt::Debug> Drop for Dr<'a, B> { + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); } +} +impl<#[may_dangle] A, B: fmt::Debug> Drop for Pt { +// { dg-error ".E0569." "" { target *-*-* } .-1 } + + // (unsafe to access self.1 due to #[may_dangle] on A) + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } +} +impl<#[may_dangle] 'a, 'b, B: fmt::Debug> Drop for Pr<'a, 'b, B> { +// { dg-error ".E0569." "" { target *-*-* } .-1 } + + // (unsafe to access self.1 due to #[may_dangle] on 'a) + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch-reorder.rs b/gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch-reorder.rs new file mode 100644 index 000000000000..df8cc6758243 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch-reorder.rs @@ -0,0 +1,101 @@ +#![feature(dropck_eyepatch)] + +// The point of this test is to test uses of `#[may_dangle]` attribute +// where the formal declaration order (in the impl generics) does not +// match the actual usage order (in the type instantiation). +// +// See also dropck-eyepatch.rs for more information about the general +// structure of the test. + +use std::fmt; + +struct Dt(&'static str, A); +struct Dr<'a, B:'a+fmt::Debug>(&'static str, &'a B); +struct Pt(&'static str, A, B); +struct Pr<'a, 'b, B:'a+'b+fmt::Debug>(&'static str, &'a B, &'b B); +struct St(&'static str, A); +struct Sr<'a, B:'a+fmt::Debug>(&'static str, &'a B); + +impl Drop for Dt { + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); } +} +impl<'a, B: fmt::Debug> Drop for Dr<'a, B> { + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); } +} +unsafe impl Drop for Pt { + // (unsafe to access self.1 due to #[may_dangle] on A) + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } +} +unsafe impl<'b, #[may_dangle] 'a, B: fmt::Debug> Drop for Pr<'a, 'b, B> { + // (unsafe to access self.1 due to #[may_dangle] on 'a) + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } +} + +fn main() { + use std::cell::Cell; + + // We use separate blocks with separate variable to prevent the error + // messages from being deduplicated. + + { + let c_long; + let (mut dt, mut dr): (Dt<_>, Dr<_>); + c_long = Cell::new(1); + + // No error: sufficiently long-lived state can be referenced in dtors + dt = Dt("dt", &c_long); + dr = Dr("dr", &c_long); + } + + { + let (c, mut dt, mut dr): (Cell<_>, Dt<_>, Dr<_>); + c = Cell::new(1); + + // No Error: destructor order precisely modelled + dt = Dt("dt", &c); + dr = Dr("dr", &c); + } + + { + let (mut dt, mut dr, c_shortest): (Dt<_>, Dr<_>, Cell<_>); + c_shortest = Cell::new(1); + + // Error: `c_shortest` dies too soon for the references in dtors to be valid. + dt = Dt("dt", &c_shortest); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + dr = Dr("dr", &c_shortest); + } + + { + let c_long; + let (mut pt, mut pr, c_shortest): (Pt<_, _>, Pr<_>, Cell<_>); + c_long = Cell::new(1); + c_shortest = Cell::new(1); + + // No error: Drop impl asserts .1 (A and &'a _) are not accessed + pt = Pt("pt", &c_shortest, &c_long); + pr = Pr("pr", &c_shortest, &c_long); + } + + { + let c_long; + let (mut pt, mut pr, c_shortest): (Pt<_, _>, Pr<_>, Cell<_>); + c_long = Cell::new(1); + c_shortest = Cell::new(1); + // Error: Drop impl's assertion does not apply to `B` nor `&'b _` + pt = Pt("pt", &c_long, &c_shortest); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + pr = Pr("pr", &c_long, &c_shortest); + } + + { + let (st, sr, c_shortest): (St<_>, Sr<_>, Cell<_>); + c_shortest = Cell::new(1); + // No error: St and Sr have no destructor. + st = St("st", &c_shortest); + sr = Sr("sr", &c_shortest); + } +} + +fn use_imm(_: &T) { } + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch.rs b/gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch.rs new file mode 100644 index 000000000000..6818979be540 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/dropck-eyepatch.rs @@ -0,0 +1,124 @@ +#![feature(dropck_eyepatch)] + +// The point of this test is to illustrate that the `#[may_dangle]` +// attribute specifically allows, in the context of a type +// implementing `Drop`, a generic parameter to be instantiated with a +// lifetime that does not strictly outlive the owning type itself. +// +// Here we test that only the expected errors are issued. +// +// The illustration is made concrete by comparison with two variations +// on the type with `#[may_dangle]`: +// +// 1. an analogous type that does not implement `Drop` (and thus +// should exhibit maximal flexibility with respect to dropck), and +// +// 2. an analogous type that does not use `#[may_dangle]` (and thus +// should exhibit the standard limitations imposed by dropck. +// +// The types in this file follow a pattern, {D,P,S}{t,r}, where: +// +// - D means "I implement Drop" +// +// - P means "I implement Drop but guarantee my (first) parameter is +// pure, i.e., not accessed from the destructor"; no other parameters +// are pure. +// +// - S means "I do not implement Drop" +// +// - t suffix is used when the first generic is a type +// +// - r suffix is used when the first generic is a lifetime. + +use std::fmt; + +struct Dt(&'static str, A); +struct Dr<'a, B:'a+fmt::Debug>(&'static str, &'a B); +struct Pt(&'static str, A, B); +struct Pr<'a, 'b, B:'a+'b+fmt::Debug>(&'static str, &'a B, &'b B); +struct St(&'static str, A); +struct Sr<'a, B:'a+fmt::Debug>(&'static str, &'a B); + +impl Drop for Dt { + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); } +} +impl<'a, B: fmt::Debug> Drop for Dr<'a, B> { + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); } +} +unsafe impl<#[may_dangle] A, B: fmt::Debug> Drop for Pt { + // (unsafe to access self.1 due to #[may_dangle] on A) + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } +} +unsafe impl<#[may_dangle] 'a, 'b, B: fmt::Debug> Drop for Pr<'a, 'b, B> { + // (unsafe to access self.1 due to #[may_dangle] on 'a) + fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); } +} + + +fn main() { + use std::cell::Cell; + + // We use separate blocks with separate variable to prevent the error + // messages from being deduplicated. + + { + let c_long; + let (mut dt, mut dr): (Dt<_>, Dr<_>); + c_long = Cell::new(1); + + // No error: sufficiently long-lived state can be referenced in dtors + dt = Dt("dt", &c_long); + dr = Dr("dr", &c_long); + } + + { + let (c, mut dt, mut dr): (Cell<_>, Dt<_>, Dr<_>); + c = Cell::new(1); + + // No Error: destructor order precisely modelled + dt = Dt("dt", &c); + dr = Dr("dr", &c); + } + + { + let (mut dt, mut dr, c_shortest): (Dt<_>, Dr<_>, Cell<_>); + c_shortest = Cell::new(1); + + // Error: `c_shortest` dies too soon for the references in dtors to be valid. + dt = Dt("dt", &c_shortest); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + dr = Dr("dr", &c_shortest); + } + + { + let c_long; + let (mut pt, mut pr, c_shortest): (Pt<_, _>, Pr<_>, Cell<_>); + c_long = Cell::new(1); + c_shortest = Cell::new(1); + + // No error: Drop impl asserts .1 (A and &'a _) are not accessed + pt = Pt("pt", &c_shortest, &c_long); + pr = Pr("pr", &c_shortest, &c_long); + } + + { + let c_long; + let (mut pt, mut pr, c_shortest): (Pt<_, _>, Pr<_>, Cell<_>); + c_long = Cell::new(1); + c_shortest = Cell::new(1); + // Error: Drop impl's assertion does not apply to `B` nor `&'b _` + pt = Pt("pt", &c_long, &c_shortest); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + pr = Pr("pr", &c_long, &c_shortest); + } + + { + let (st, sr, c_shortest): (St<_>, Sr<_>, Cell<_>); + c_shortest = Cell::new(1); + // No error: St and Sr have no destructor. + st = St("st", &c_shortest); + sr = Sr("sr", &c_shortest); + } +} +fn use_imm(_: &T) { } + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/dropck-union.rs b/gcc/testsuite/rust/rustc/ui/dropck/dropck-union.rs new file mode 100644 index 000000000000..fccf2e80dc3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/dropck-union.rs @@ -0,0 +1,39 @@ +use std::cell::Cell; +use std::ops::Deref; +use std::mem::ManuallyDrop; + +union Wrap { x: ManuallyDrop } + +impl Drop for Wrap { + fn drop(&mut self) { + unsafe { std::ptr::drop_in_place(&mut *self.x as *mut T); } + } +} + +impl Wrap { + fn new(x: T) -> Self { + Wrap { x: ManuallyDrop::new(x) } + } +} + +impl Deref for Wrap { + type Target = T; + #[inline] + fn deref(&self) -> &Self::Target { + unsafe { + &self.x + } + } +} + +struct C<'a>(Cell>>); + +impl<'a> Drop for C<'a> { + fn drop(&mut self) {} +} + +fn main() { + let v : Wrap = Wrap::new(C(Cell::new(None))); + v.0.set(Some(&v)); // { dg-error ".E0597." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/dropck_fn_type.rs b/gcc/testsuite/rust/rustc/ui/dropck/dropck_fn_type.rs new file mode 100644 index 000000000000..f31d696f6bdb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/dropck_fn_type.rs @@ -0,0 +1,21 @@ +// run-pass +//! Regression test for #58311, regarding the usage of Fn types in drop impls + +// All of this Drop impls should compile. + +#[allow(dead_code)] +struct S [u8; 1]>(F); + +impl [u8; 1]> Drop for S { + fn drop(&mut self) {} +} + +#[allow(dead_code)] +struct P [A; 10]>(F); + +impl [A; 10]> Drop for P { + fn drop(&mut self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_1.rs b/gcc/testsuite/rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_1.rs new file mode 100644 index 000000000000..9ff582eec820 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_1.rs @@ -0,0 +1,28 @@ +// Issue 22443: Reject code using non-regular types that would +// otherwise cause dropck to loop infinitely. + +use std::marker::PhantomData; + +struct Digit { + elem: T +} + +struct Node { m: PhantomData<&'static T> } + + +enum FingerTree { + Single(T), + // Bug report said Digit after Box would stack overflow (versus + // Digit before Box; see dropck_no_diverge_on_nonregular_2). + Deep( + Box>>, + Digit, + ) +} + +fn main() { + let ft = // { dg-error ".E0320." "" { target *-*-* } } + FingerTree::Single(1); +// { dg-error ".E0320." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_2.rs b/gcc/testsuite/rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_2.rs new file mode 100644 index 000000000000..850cd94bc78e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_2.rs @@ -0,0 +1,27 @@ +// Issue 22443: Reject code using non-regular types that would +// otherwise cause dropck to loop infinitely. + +use std::marker::PhantomData; + +struct Digit { + elem: T +} + +struct Node { m: PhantomData<&'static T> } + +enum FingerTree { + Single(T), + // Bug report said Digit before Box would infinite loop (versus + // Digit after Box; see dropck_no_diverge_on_nonregular_1). + Deep( + Digit, + Box>>, + ) +} + +fn main() { + let ft = // { dg-error ".E0320." "" { target *-*-* } } + FingerTree::Single(1); +// { dg-error ".E0320." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_3.rs b/gcc/testsuite/rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_3.rs new file mode 100644 index 000000000000..93852b259fa6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/dropck_no_diverge_on_nonregular_3.rs @@ -0,0 +1,37 @@ +// Issue 22443: Reject code using non-regular types that would +// otherwise cause dropck to loop infinitely. +// +// This version is just checking that we still sanely handle a trivial +// wrapper around the non-regular type. (It also demonstrates how the +// error messages will report different types depending on which type +// dropck is analyzing.) + +use std::marker::PhantomData; + +struct Digit { + elem: T +} + +struct Node { m: PhantomData<&'static T> } + +enum FingerTree { + Single(T), + // According to the bug report, Digit before Box would infinite loop. + Deep( + Digit, + Box>>, + ) +} + +enum Wrapper { + Simple, + Other(FingerTree), +} + +fn main() { + let w = // { dg-error ".E0320." "" { target *-*-* } } + Some(Wrapper::Simple::); +// { dg-error ".E0320." "" { target *-*-* } .-1 } +// { dg-error ".E0320." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/dropck_trait_cycle_checked.rs b/gcc/testsuite/rust/rustc/ui/dropck/dropck_trait_cycle_checked.rs new file mode 100644 index 000000000000..fbb89c540d75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/dropck_trait_cycle_checked.rs @@ -0,0 +1,122 @@ +// Reject mixing cyclic structure and Drop when using trait +// objects to hide the cross-references. +// +// (Compare against compile-fail/dropck_vec_cycle_checked.rs) + +use std::cell::Cell; +use id::Id; + +mod s { + use std::sync::atomic::{AtomicUsize, Ordering}; + + static S_COUNT: AtomicUsize = AtomicUsize::new(0); + + pub fn next_count() -> usize { + S_COUNT.fetch_add(1, Ordering::SeqCst) + 1 + } +} + +mod id { + use s; + #[derive(Debug)] + pub struct Id { + orig_count: usize, + count: usize, + } + + impl Id { + pub fn new() -> Id { + let c = s::next_count(); + println!("building Id {}", c); + Id { orig_count: c, count: c } + } + pub fn count(&self) -> usize { + println!("Id::count on {} returns {}", self.orig_count, self.count); + self.count + } + } + + impl Drop for Id { + fn drop(&mut self) { + println!("dropping Id {}", self.count); + self.count = 0; + } + } +} + +trait HasId { + fn count(&self) -> usize; +} + +#[derive(Debug)] +struct CheckId { + v: T +} + +#[allow(non_snake_case)] +fn CheckId(t: T) -> CheckId { CheckId{ v: t } } + +impl Drop for CheckId { + fn drop(&mut self) { + assert!(self.v.count() > 0); + } +} + +trait Obj<'a> : HasId { + fn set0(&self, b: &'a Box>); + fn set1(&self, b: &'a Box>); +} + +struct O<'a> { + id: Id, + obj0: CheckId>>>>, + obj1: CheckId>>>>, +} + +impl<'a> HasId for O<'a> { + fn count(&self) -> usize { self.id.count() } +} + +impl<'a> O<'a> { + fn new() -> Box> { + Box::new(O { + id: Id::new(), + obj0: CheckId(Cell::new(None)), + obj1: CheckId(Cell::new(None)), + }) + } +} + +impl<'a> HasId for Cell>>> { + fn count(&self) -> usize { + match self.get() { + None => 1, + Some(c) => c.count(), + } + } +} + +impl<'a> Obj<'a> for O<'a> { + fn set0(&self, b: &'a Box>) { + self.obj0.v.set(Some(b)) + } + fn set1(&self, b: &'a Box>) { + self.obj1.v.set(Some(b)) + } +} + + +fn f() { + let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); + o1.set0(&o2); // { dg-error ".E0597." "" { target *-*-* } } + o1.set1(&o3); // { dg-error ".E0597." "" { target *-*-* } } + o2.set0(&o2); // { dg-error ".E0597." "" { target *-*-* } } + o2.set1(&o3); // { dg-error ".E0597." "" { target *-*-* } } + o3.set0(&o1); // { dg-error ".E0597." "" { target *-*-* } } + o3.set1(&o2); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dropck/dropck_traits.rs b/gcc/testsuite/rust/rustc/ui/dropck/dropck_traits.rs new file mode 100644 index 000000000000..7d661707794d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dropck/dropck_traits.rs @@ -0,0 +1,69 @@ +// run-pass +//! Regression test for #34426, regarding HRTB in drop impls + +// All of this Drop impls should compile. + +pub trait Lifetime<'a> {} +impl<'a> Lifetime<'a> for i32 {} + +#[allow(dead_code)] +struct Foo +where + for<'a> L: Lifetime<'a>, +{ + l: L, +} + +impl Drop for Foo +where + for<'a> L: Lifetime<'a>, +{ + fn drop(&mut self) {} +} + +#[allow(dead_code)] +struct Foo2 +where + for<'a> L: Lifetime<'a>, +{ + l: L, +} + +impl Lifetime<'a>> Drop for Foo2 +where + for<'x> T: Lifetime<'x>, +{ + fn drop(&mut self) {} +} + +pub trait Lifetime2<'a, 'b> {} +impl<'a, 'b> Lifetime2<'a, 'b> for i32 {} + +#[allow(dead_code)] +struct Bar +where + for<'a, 'b> L: Lifetime2<'a, 'b>, +{ + l: L, +} + +impl Drop for Bar +where + for<'a, 'b> L: Lifetime2<'a, 'b>, +{ + fn drop(&mut self) {} +} + +#[allow(dead_code)] +struct FnHolder Fn(&'a T, dyn for<'b> Lifetime2<'a, 'b>) -> u8>(T); + +impl Fn(&'a T, dyn for<'b> Lifetime2<'a, 'b>) -> u8> Drop for FnHolder { + fn drop(&mut self) {} +} + +fn main() { + let _foo = Foo { l: 0 }; + + let _bar = Bar { l: 0 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-bad-assign-2.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-assign-2.rs new file mode 100644 index 000000000000..f7874fdf23b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-assign-2.rs @@ -0,0 +1,39 @@ +// Forbid assignment into a dynamically sized type. + +struct Fat { + f1: isize, + f2: &'static str, + ptr: T +} + +#[derive(PartialEq,Eq)] +struct Bar; + +#[derive(PartialEq,Eq)] +struct Bar1 { + f: isize +} + +trait ToBar { + fn to_bar(&self) -> Bar; + fn to_val(&self) -> isize; +} + +impl ToBar for Bar1 { + fn to_bar(&self) -> Bar { + Bar + } + fn to_val(&self) -> isize { + self.f + } +} + +pub fn main() { + // Assignment. + let f5: &mut Fat = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} }; + let z: Box = Box::new(Bar1 {f: 36}); + f5.ptr = *z; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-bad-assign-3.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-assign-3.rs new file mode 100644 index 000000000000..ce1c5002f164 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-assign-3.rs @@ -0,0 +1,40 @@ +// Forbid assignment into a dynamically sized type. + +#![feature(unsized_tuple_coercion)] + +type Fat = (isize, &'static str, T); + +#[derive(PartialEq,Eq)] +struct Bar; + +#[derive(PartialEq,Eq)] +struct Bar1 { + f: isize +} + +trait ToBar { + fn to_bar(&self) -> Bar; + fn to_val(&self) -> isize; +} + +impl ToBar for Bar1 { + fn to_bar(&self) -> Bar { + Bar + } + fn to_val(&self) -> isize { + self.f + } +} + +pub fn main() { + // Assignment. + let f5: &mut Fat = &mut (5, "some str", Bar1 {f :42}); + let z: Box = Box::new(Bar1 {f: 36}); + f5.2 = Bar1 {f: 36}; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-bad-assign.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-assign.rs new file mode 100644 index 000000000000..f3cddbc7d797 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-assign.rs @@ -0,0 +1,42 @@ +// Forbid assignment into a dynamically sized type. + +struct Fat { + f1: isize, + f2: &'static str, + ptr: T +} + +#[derive(PartialEq,Eq)] +struct Bar; + +#[derive(PartialEq,Eq)] +struct Bar1 { + f: isize +} + +trait ToBar { + fn to_bar(&self) -> Bar; + fn to_val(&self) -> isize; +} + +impl ToBar for Bar1 { + fn to_bar(&self) -> Bar { + Bar + } + fn to_val(&self) -> isize { + self.f + } +} + +pub fn main() { + // Assignment. + let f5: &mut Fat = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} }; + let z: Box = Box::new(Bar1 {f: 36}); + f5.ptr = Bar1 {f: 36}; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce1.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce1.rs new file mode 100644 index 000000000000..76372782d602 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce1.rs @@ -0,0 +1,37 @@ +// Attempt to change the type as well as unsizing. + +#![feature(unsized_tuple_coercion)] + +struct Fat { + ptr: T +} + +struct Foo; +trait Bar { fn bar(&self) {} } + +pub fn main() { + // With a vec of isize. + let f1 = Fat { ptr: [1, 2, 3] }; + let f2: &Fat<[isize; 3]> = &f1; + let f3: &Fat<[usize]> = f2; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + // With a trait. + let f1 = Fat { ptr: Foo }; + let f2: &Fat = &f1; + let f3: &Fat = f2; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // Tuple with a vec of isize. + let f1 = ([1, 2, 3],); + let f2: &([isize; 3],) = &f1; + let f3: &([usize],) = f2; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + // Tuple with a trait. + let f1 = (Foo,); + let f2: &(Foo,) = &f1; + let f3: &(dyn Bar,) = f2; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce2.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce2.rs new file mode 100644 index 000000000000..e463d091be5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce2.rs @@ -0,0 +1,32 @@ +// Attempt to change the mutability as well as unsizing. + +struct Fat { + ptr: T +} + +struct Foo; +trait Bar {} +impl Bar for Foo {} + +pub fn main() { + // With a vec of ints. + let f1 = Fat { ptr: [1, 2, 3] }; + let f2: &Fat<[isize; 3]> = &f1; + let f3: &mut Fat<[isize]> = f2; // { dg-error ".E0308." "" { target *-*-* } } + + // With a trait. + let f1 = Fat { ptr: Foo }; + let f2: &Fat = &f1; + let f3: &mut Fat = f2; // { dg-error ".E0308." "" { target *-*-* } } + + // Tuple with a vec of ints. + let f1 = ([1, 2, 3],); + let f2: &([isize; 3],) = &f1; + let f3: &mut ([isize],) = f2; // { dg-error ".E0308." "" { target *-*-* } } + + // Tuple with a trait. + let f1 = (Foo,); + let f2: &(Foo,) = &f1; + let f3: &mut (dyn Bar,) = f2; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce3.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce3.rs new file mode 100644 index 000000000000..f3ad5f09949d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce3.rs @@ -0,0 +1,38 @@ +// Attempt to extend the lifetime as well as unsizing. + +#![feature(unsized_tuple_coercion)] + +struct Fat { + ptr: T +} + +struct Foo; +trait Bar { fn bar(&self) {} } +impl Bar for Foo {} + +fn baz<'a>() { + // With a vec of ints. + let f1 = Fat { ptr: [1, 2, 3] }; + let f2: &Fat<[isize; 3]> = &f1; // { dg-error ".E0597." "" { target *-*-* } } + let f3: &'a Fat<[isize]> = f2; + + // With a trait. + let f1 = Fat { ptr: Foo }; + let f2: &Fat = &f1; // { dg-error ".E0597." "" { target *-*-* } } + let f3: &'a Fat = f2; + + // Tuple with a vec of ints. + let f1 = ([1, 2, 3],); + let f2: &([isize; 3],) = &f1; // { dg-error ".E0597." "" { target *-*-* } } + let f3: &'a ([isize],) = f2; + + // Tuple with a trait. + let f1 = (Foo,); + let f2: &(Foo,) = &f1; // { dg-error ".E0597." "" { target *-*-* } } + let f3: &'a (dyn Bar,) = f2; +} + +pub fn main() { + baz(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce4.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce4.rs new file mode 100644 index 000000000000..594c0180a5b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coerce4.rs @@ -0,0 +1,26 @@ +// Attempt to coerce from unsized to sized. + +#![feature(unsized_tuple_coercion)] + +struct Fat { + ptr: T +} + +pub fn main() { + // With a vec of isizes. + let f1: &Fat<[isize]> = &Fat { ptr: [1, 2, 3] }; + let f2: &Fat<[isize; 3]> = f1; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + // Tuple with a vec of isizes. + let f1: &([isize],) = &([1, 2, 3],); + let f2: &([isize; 3],) = f1; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coercions.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coercions.rs new file mode 100644 index 000000000000..707748a1e37c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-coercions.rs @@ -0,0 +1,27 @@ +// Test implicit coercions involving DSTs and raw pointers. + +struct S; +trait T {} +impl T for S {} + +struct Foo { + f: T +} + +pub fn main() { + // Test that we cannot convert from *-ptr to &S and &T + let x: *const S = &S; + let y: &S = x; // { dg-error ".E0308." "" { target *-*-* } } + let y: &dyn T = x; // { dg-error ".E0308." "" { target *-*-* } } + + // Test that we cannot convert from *-ptr to &S and &T (mut version) + let x: *mut S = &mut S; + let y: &S = x; // { dg-error ".E0308." "" { target *-*-* } } + let y: &dyn T = x; // { dg-error ".E0308." "" { target *-*-* } } + + // Test that we cannot convert an immutable ptr to a mutable one using *-ptrs + let x: &mut dyn T = &S; // { dg-error ".E0308." "" { target *-*-* } } + let x: *mut dyn T = &S; // { dg-error ".E0308." "" { target *-*-* } } + let x: *mut S = &S; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-bad-deep-2.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-deep-2.rs new file mode 100644 index 000000000000..91d4d56ad9ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-deep-2.rs @@ -0,0 +1,14 @@ +// Try to initialise a DST struct where the lost information is deeply nested. +// This is an error because it requires an unsized rvalue. This is a problem +// because it would require stack allocation of an unsized temporary (*g in the +// test). + +#![feature(unsized_tuple_coercion)] + +pub fn main() { + let f: ([isize; 3],) = ([5, 6, 7],); + let g: &([isize],) = &f; + let h: &(([isize],),) = &(*g,); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-bad-deep.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-deep.rs new file mode 100644 index 000000000000..5860f7695e78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-bad-deep.rs @@ -0,0 +1,16 @@ +// Try to initialise a DST struct where the lost information is deeply nested. +// This is an error because it requires an unsized rvalue. This is a problem +// because it would require stack allocation of an unsized temporary (*g in the +// test). + +struct Fat { + ptr: T +} + +pub fn main() { + let f: Fat<[isize; 3]> = Fat { ptr: [5, 6, 7] }; + let g: &Fat<[isize]> = &f; + let h: &Fat> = &Fat { ptr: *g }; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-index.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-index.rs new file mode 100644 index 000000000000..d63bf7511ed7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-index.rs @@ -0,0 +1,38 @@ +// Test that overloaded index expressions with DST result types +// can't be used as rvalues + +use std::ops::Index; +use std::fmt::Debug; + +#[derive(Copy, Clone)] +struct S; + +impl Index for S { + type Output = str; + + fn index(&self, _: usize) -> &str { + "hello" + } +} + +#[derive(Copy, Clone)] +struct T; + +impl Index for T { + type Output = dyn Debug + 'static; + + fn index<'a>(&'a self, idx: usize) -> &'a (dyn Debug + 'static) { + static x: usize = 42; + &x + } +} + +fn main() { + S[0]; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { dg-error ".E0507." "" { target *-*-* } .-2 } + T[0]; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { dg-error ".E0507." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-object-from-unsized-type.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-object-from-unsized-type.rs new file mode 100644 index 000000000000..b33c8739b0d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-object-from-unsized-type.rs @@ -0,0 +1,28 @@ +// Test that we cannot create objects from unsized types. + +trait Foo { fn foo(&self) {} } +impl Foo for str {} +impl Foo for [u8] {} + +fn test1(t: &T) { + let u: &dyn Foo = t; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn test2(t: &T) { + let v: &dyn Foo = t as &dyn Foo; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn test3() { + let _: &[&dyn Foo] = &["hi"]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn test4(x: &[u8]) { + let _: &dyn Foo = x as &dyn Foo; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-rvalue.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-rvalue.rs new file mode 100644 index 000000000000..59d3588b7e3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-rvalue.rs @@ -0,0 +1,15 @@ +// Check that dynamically sized rvalues are forbidden + +#![feature(box_syntax)] + +pub fn main() { + let _x: Box = box *"hello world"; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { dg-error ".E0507." "" { target *-*-* } .-2 } + + let array: &[isize] = &[1, 2, 3]; + let _x: Box<[isize]> = box *array; +// { dg-error ".E0508." "" { target *-*-* } .-1 } +// { dg-error ".E0508." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dst/dst-sized-trait-param.rs b/gcc/testsuite/rust/rustc/ui/dst/dst-sized-trait-param.rs new file mode 100644 index 000000000000..091bc5540630 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dst/dst-sized-trait-param.rs @@ -0,0 +1,14 @@ +// Check that when you implement a trait that has a sized type +// parameter, the corresponding value must be sized. Also that the +// self type must be sized if appropriate. + +trait Foo : Sized { fn take(self, x: &T) { } } // Note: T is sized + +impl Foo<[isize]> for usize { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +impl Foo for [usize] { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-1.rs b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-1.rs new file mode 100644 index 000000000000..cc2434ddbe94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-1.rs @@ -0,0 +1,15 @@ +// build-fail + +// +#![crate_type="rlib"] +#![allow(warnings)] + +#[export_name="fail"] +pub fn a() { +} + +#[export_name="fail"] +pub fn b() { +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-2.rs b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-2.rs new file mode 100644 index 000000000000..3e3cdf50e9d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-2.rs @@ -0,0 +1,19 @@ +// build-fail + +// +#![crate_type="rlib"] +#![allow(warnings)] + +pub mod a { + #[no_mangle] + pub extern fn fail() { + } +} + +pub mod b { + #[no_mangle] + pub extern fn fail() { +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-3.rs b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-3.rs new file mode 100644 index 000000000000..e5de90b815ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-3.rs @@ -0,0 +1,15 @@ +// build-fail + +// +#![crate_type="rlib"] +#![allow(warnings)] + +#[export_name="fail"] +pub fn a() { +} + +#[no_mangle] +pub fn fail() { +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-4.rs b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-4.rs new file mode 100644 index 000000000000..2c7cb113500b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-4.rs @@ -0,0 +1,25 @@ +// build-fail + +// +// error-pattern: symbol `fail` is already defined +#![crate_type="rlib"] +#![allow(warnings)] + + +pub trait A { + fn fail(self); +} + +struct B; +struct C; + +impl A for B { + #[no_mangle] + fn fail(self) {} +} + +impl A for C { + #[no_mangle] + fn fail(self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-5.rs b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-5.rs new file mode 100644 index 000000000000..5e2e5297e3cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-5.rs @@ -0,0 +1,14 @@ +// build-fail + +// +#![crate_type="rlib"] +#![allow(warnings)] + +#[export_name="fail"] +static HELLO: u8 = 0; + +#[export_name="fail"] +pub fn b() { +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-6.rs b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-6.rs new file mode 100644 index 000000000000..e8057a52afd8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-6.rs @@ -0,0 +1,12 @@ +// build-fail + +#![crate_type="rlib"] +#![allow(warnings)] + +#[export_name="fail"] +static HELLO: u8 = 0; + +#[export_name="fail"] +static HELLO_TWICE: u16 = 0; +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-7.rs b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-7.rs new file mode 100644 index 000000000000..8a6da35756f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-7.rs @@ -0,0 +1,13 @@ +// build-fail + +// +// error-pattern: entry symbol `main` declared multiple times + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +#![allow(warnings)] + +#[no_mangle] +fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-8.rs b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-8.rs new file mode 100644 index 000000000000..ab572ae58861 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/duplicate/dupe-symbols-8.rs @@ -0,0 +1,13 @@ +// build-fail +// error-pattern: entry symbol `main` declared multiple times +// +// See #67946. + +#![allow(warnings)] +fn main() { + extern "Rust" { + fn main(); + } + unsafe { main(); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/duplicate/duplicate-check-macro-exports.rs b/gcc/testsuite/rust/rustc/ui/duplicate/duplicate-check-macro-exports.rs new file mode 100644 index 000000000000..a3e5f6f8ff81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/duplicate/duplicate-check-macro-exports.rs @@ -0,0 +1,7 @@ +pub use std::panic; + +#[macro_export] +macro_rules! panic { () => {} } // { dg-error ".E0255." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/duplicate/duplicate-parameter.rs b/gcc/testsuite/rust/rustc/ui/duplicate/duplicate-parameter.rs new file mode 100644 index 000000000000..11e9a60b0cf8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/duplicate/duplicate-parameter.rs @@ -0,0 +1,6 @@ +fn f(a: isize, a: isize) {} +// { dg-error ".E0415." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/duplicate/duplicate-type-parameter.rs b/gcc/testsuite/rust/rustc/ui/duplicate/duplicate-type-parameter.rs new file mode 100644 index 000000000000..4488ce6bacd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/duplicate/duplicate-type-parameter.rs @@ -0,0 +1,30 @@ +type Foo = Option; +// { dg-error ".E0403." "" { target *-*-* } .-1 } + +struct Bar(T); +// { dg-error ".E0403." "" { target *-*-* } .-1 } + +struct Baz { +// { dg-error ".E0403." "" { target *-*-* } .-1 } + x: T, +} + +enum Boo { +// { dg-error ".E0403." "" { target *-*-* } .-1 } + A(T), + B, +} + +fn quux(x: T) {} +// { dg-error ".E0403." "" { target *-*-* } .-1 } + +trait Qux {} +// { dg-error ".E0403." "" { target *-*-* } .-1 } + +impl Qux for Option {} +// { dg-error ".E0207." "" { target *-*-* } .-1 } +// { dg-error ".E0207." "" { target *-*-* } .-2 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/duplicate_entry_error.rs b/gcc/testsuite/rust/rustc/ui/duplicate_entry_error.rs new file mode 100644 index 000000000000..e9f716e0eb40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/duplicate_entry_error.rs @@ -0,0 +1,17 @@ +// normalize-stderr-test "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +// note-pattern: first defined in crate `std`. + +// Test for issue #31788 and E0152 + +#![feature(lang_items)] + +use std::panic::PanicInfo; + +#[lang = "panic_impl"] +fn panic_impl(info: &PanicInfo) -> ! { +// { dg-error ".E0152." "" { target *-*-* } .-1 } + loop {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs b/gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs new file mode 100644 index 000000000000..fdacadf2aece --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.rs @@ -0,0 +1,82 @@ +// Under the 2015 edition with the keyword_idents lint, `dyn` is not +// entirely acceptable as an identifier. We currently do not attempt +// to detect or fix uses of `dyn` under a macro. Since we are testing +// this file via `rustfix`, we want the rustfix output to be +// compilable; so the macros here carefully use `dyn` "correctly." + +// run-rustfix + +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod dyn { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + pub struct dyn; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + } +} +use outer_mod::dyn::dyn; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + +fn main() { + match dyn { dyn => {} } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + macro_defn::dyn(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + macro_defn::boxed(); +} + +mod macro_defn { + use super::Trait; + + macro_rules! dyn { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + // Note that we do not lint nor fix occurrences under macros + ($dyn:tt) => { (Box, Box<$dyn Trait>) } + } + + pub fn dyn() -> ::outer_mod::dyn::dyn { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-warning "" "" { target *-*-* } .-6 } + ::outer_mod::dyn::dyn +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + } + + + + pub fn boxed() -> dyn!( +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + // Note that we do not lint nor fix occurrences under macros + dyn + ) + { + (Box::new(1), Box::new(2)) + } +} + +pub trait Trait { } + +impl Trait for u32 { } + diff --git a/gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs b/gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs new file mode 100644 index 000000000000..85dae6f0e2ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-idents-in-decl-macros-unlinted.rs @@ -0,0 +1,52 @@ +// build-pass (FIXME(62277): could be check-pass?) + +// Under the 2015 edition with the keyword_idents lint, `dyn` is +// not entirely acceptable as an identifier. +// +// We currently do not attempt to detect or fix uses of `dyn` as an +// identifier under a macro, including under the declarative `macro` +// forms from macros 1.2 and macros 2.0. + +#![feature(decl_macro)] +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod r#dyn { + pub struct r#dyn; + } +} + +// Here we are illustrating that the current lint does not flag the +// occurrences of `dyn` in this macro definition; however, it +// certainly *could* (and it would be nice if it did), since these +// occurrences are not compatible with the 2018 edition's +// interpretation of `dyn` as a keyword. +macro defn_has_dyn_idents() { ::outer_mod::dyn::dyn } + +struct X; +trait Trait { fn hello(&self) { }} +impl Trait for X { } + +macro tt_trait($arg:tt) { & $arg Trait } +macro id_trait($id:ident) { & $id Trait } + +fn main() { + defn_has_dyn_idents!(); + + // Here we are illustrating that the current lint does not flag + // the occurrences of `dyn` in these macro invocations. It + // definitely should *not* flag the one in `tt_trait`, since that + // is expanding in a valid fashion to `&dyn Trait`. + // + // It is arguable whether it would be valid to flag the occurrence + // in `id_trait`, since that macro specifies that it takes an + // `ident` as its input. + fn f_tt(x: &X) -> tt_trait!(dyn) { x } + fn f_id(x: &X) -> id_trait!(dyn) { x } + + let x = X; + f_tt(&x).hello(); + f_id(&x).hello(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs b/gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs new file mode 100644 index 000000000000..03f2c2157431 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-idents-in-macros-unlinted.rs @@ -0,0 +1,57 @@ +// build-pass (FIXME(62277): could be check-pass?) + +// Under the 2015 edition with the keyword_idents lint, `dyn` is +// not entirely acceptable as an identifier. +// +// We currently do not attempt to detect or fix uses of `dyn` as an +// identifier under a macro. + +#![allow(non_camel_case_types)] +#![deny(keyword_idents)] + +mod outer_mod { + pub mod r#dyn { + pub struct r#dyn; + } +} + +// Here we are illustrating that the current lint does not flag the +// occurrences of `dyn` in this macro definition; however, it +// certainly *could* (and it would be nice if it did), since these +// occurrences are not compatible with the 2018 edition's +// interpretation of `dyn` as a keyword. +macro_rules! defn_has_dyn_idents { + () => { ::outer_mod::dyn::dyn } +} + +struct X; +trait Trait { fn hello(&self) { }} +impl Trait for X { } + +macro_rules! tt_trait { + ($arg:tt) => { & $arg Trait } +} + +macro_rules! id_trait { + ($id:ident) => { & $id Trait } +} + +fn main() { + defn_has_dyn_idents!(); + + // Here we are illustrating that the current lint does not flag + // the occurrences of `dyn` in these macro invocations. It + // definitely should *not* flag the one in `tt_trait`, since that + // is expanding in a valid fashion to `&dyn Trait`. + // + // It is arguable whether it would be valid to flag the occurrence + // in `id_trait`, since that macro specifies that it takes an + // `ident` as its input. + fn f_tt(x: &X) -> tt_trait!(dyn) { x } + fn f_id(x: &X) -> id_trait!(dyn) { x } + + let x = X; + f_tt(&x).hello(); + f_id(&x).hello(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs b/gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs new file mode 100644 index 000000000000..9b897ca79f1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs @@ -0,0 +1,28 @@ +// Under the 2015 edition without the keyword_idents lint, `dyn` is +// entirely acceptable as an identifier. + +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(non_camel_case_types)] + +mod outer_mod { + pub mod dyn { + pub struct dyn; + } +} +use outer_mod::dyn::dyn; + +fn main() { + match dyn { dyn => {} } + macro_defn::dyn(); +} +mod macro_defn { + macro_rules! dyn { + () => { ::outer_mod::dyn::dyn } + } + + pub fn dyn() -> ::outer_mod::dyn::dyn { + dyn!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs b/gcc/testsuite/rust/rustc/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs new file mode 100644 index 000000000000..53772f829c6c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs @@ -0,0 +1,26 @@ +// check-pass + +// rust-lang/rust#56327: Some occurrences of `dyn` within a macro are +// not instances of identifiers, and thus should *not* be caught by the +// keyword_ident lint. +// +// Otherwise, rustfix replaces the type `Box` with +// `Box`, which is injecting a bug rather than fixing +// anything. + +#![deny(rust_2018_compatibility)] + +macro_rules! foo { + () => { + fn generated_foo() { + let _x: Box; + } + } +} + +foo!(); + +fn main() { + generated_foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dyn-trait-compatibility.rs b/gcc/testsuite/rust/rustc/ui/dyn-trait-compatibility.rs new file mode 100644 index 000000000000..4b2f12ef21d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dyn-trait-compatibility.rs @@ -0,0 +1,15 @@ +type A0 = dyn; +// { dg-error ".E0412." "" { target *-*-* } .-1 } +type A1 = dyn::dyn; +// { dg-error ".E0433." "" { target *-*-* } .-1 } +type A2 = dyn; +// { dg-error ".E0412." "" { target *-*-* } .-1 } +// { dg-error ".E0412." "" { target *-*-* } .-2 } +// { dg-error ".E0412." "" { target *-*-* } .-3 } +type A3 = dyn<::dyn>; +// { dg-error ".E0412." "" { target *-*-* } .-1 } +// { dg-error ".E0412." "" { target *-*-* } .-2 } +// { dg-error ".E0412." "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-coerce-custom.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-coerce-custom.rs new file mode 100644 index 000000000000..90d1aa01fbd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-coerce-custom.rs @@ -0,0 +1,44 @@ +// run-pass +// Test a very simple custom DST coercion. + +#![feature(unsize, coerce_unsized)] + +use std::ops::CoerceUnsized; +use std::marker::Unsize; + +struct Bar { + x: *const T, +} + +impl, U: ?Sized> CoerceUnsized> for Bar {} + +trait Baz { + fn get(&self) -> i32; +} + +impl Baz for i32 { + fn get(&self) -> i32 { + *self + } +} + +fn main() { + // Arrays. + let a: Bar<[i32; 3]> = Bar { x: &[1, 2, 3] }; + // This is the actual coercion. + let b: Bar<[i32]> = a; + + unsafe { + assert_eq!((*b.x)[0], 1); + assert_eq!((*b.x)[1], 2); + assert_eq!((*b.x)[2], 3); + } + + // Trait objects. + let a: Bar = Bar { x: &42 }; + let b: Bar = a; + unsafe { + assert_eq!((*b.x).get(), 42); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-coerce-rc.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-coerce-rc.rs new file mode 100644 index 000000000000..bb131bd4a7bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-coerce-rc.rs @@ -0,0 +1,43 @@ +// run-pass +#![allow(unused_variables)] +#![allow(stable_features)] +// Test a very simple custom DST coercion. + +#![feature(core, rc_weak)] + +use std::cell::RefCell; +use std::rc::{Rc, Weak}; + +trait Baz { + fn get(&self) -> i32; +} + +impl Baz for i32 { + fn get(&self) -> i32 { + *self + } +} + +fn main() { + let a: Rc<[i32; 3]> = Rc::new([1, 2, 3]); + let b: Rc<[i32]> = a; + assert_eq!(b[0], 1); + assert_eq!(b[1], 2); + assert_eq!(b[2], 3); + + let a: Rc = Rc::new(42); + let b: Rc = a.clone(); + assert_eq!(b.get(), 42); + + let c: Weak = Rc::downgrade(&a); + let d: Weak = c.clone(); + + let _c = b.clone(); + + let a: Rc> = Rc::new(RefCell::new(42)); + let b: Rc> = a.clone(); + assert_eq!(b.borrow().get(), 42); + // FIXME + let c: Weak> = Rc::downgrade(&a) as Weak<_>; +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-coercions.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-coercions.rs new file mode 100644 index 000000000000..a52dc9577dfc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-coercions.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(unused_variables)] +// Test coercions involving DST and/or raw pointers + +// pretty-expanded FIXME #23616 + +struct S; +trait T { fn dummy(&self) { } } +impl T for S {} + +pub fn main() { + let x: &dyn T = &S; + // Test we can convert from &-ptr to *-ptr of trait objects + let x: *const dyn T = &S; + + // Test we can convert from &-ptr to *-ptr of struct pointer (not DST) + let x: *const S = &S; + + // As above, but mut + let x: &mut dyn T = &mut S; + let x: *mut dyn T = &mut S; + + let x: *mut S = &mut S; + + // Test we can change the mutability from mut to const. + let x: &dyn T = &mut S; + let x: *const dyn T = &mut S; +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-deref-mut.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-deref-mut.rs new file mode 100644 index 000000000000..93a854f224d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-deref-mut.rs @@ -0,0 +1,36 @@ +// run-pass +// Test that a custom deref with a fat pointer return type does not ICE + + +use std::ops::{Deref, DerefMut}; + +pub struct Arr { + ptr: Box<[usize]> +} + +impl Deref for Arr { + type Target = [usize]; + + fn deref(&self) -> &[usize] { + panic!(); + } +} + +impl DerefMut for Arr { + fn deref_mut(&mut self) -> &mut [usize] { + &mut *self.ptr + } +} + +pub fn foo(arr: &mut Arr) { + let x: &mut [usize] = &mut **arr; + assert_eq!(x[0], 1); + assert_eq!(x[1], 2); + assert_eq!(x[2], 3); +} + +fn main() { + let mut a = Arr { ptr: Box::new([1, 2, 3]) }; + foo(&mut a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-deref.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-deref.rs new file mode 100644 index 000000000000..03305ab0097e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-deref.rs @@ -0,0 +1,31 @@ +// run-pass +// Test that a custom deref with a fat pointer return type does not ICE + + +use std::ops::Deref; + +pub struct Arr { + ptr: Box<[usize]> +} + +impl Deref for Arr { + type Target = [usize]; + + fn deref(&self) -> &[usize] { + &*self.ptr + } +} + +pub fn foo(arr: &Arr) { + assert_eq!(arr.len(), 3); + let x: &[usize] = &**arr; + assert_eq!(x[0], 1); + assert_eq!(x[1], 2); + assert_eq!(x[2], 3); +} + +fn main() { + let a = Arr { ptr: Box::new([1, 2, 3]) }; + foo(&a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-field-align.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-field-align.rs new file mode 100644 index 000000000000..76da48166f88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-field-align.rs @@ -0,0 +1,68 @@ +// run-pass +#![allow(dead_code)] +struct Foo { + a: u16, + b: T +} + +trait Bar { + fn get(&self) -> usize; +} + +impl Bar for usize { + fn get(&self) -> usize { *self } +} + +struct Baz { + a: T +} + +struct HasDrop { + ptr: Box, + data: T +} + +fn main() { + // Test that zero-offset works properly + let b : Baz = Baz { a: 7 }; + assert_eq!(b.a.get(), 7); + let b : &Baz = &b; + assert_eq!(b.a.get(), 7); + + // Test that the field is aligned properly + let f : Foo = Foo { a: 0, b: 11 }; + assert_eq!(f.b.get(), 11); + let ptr1 : *const u8 = &f.b as *const _ as *const u8; + + let f : &Foo = &f; + let ptr2 : *const u8 = &f.b as *const _ as *const u8; + assert_eq!(f.b.get(), 11); + + // The pointers should be the same + assert_eq!(ptr1, ptr2); + + // Test that nested DSTs work properly + let f : Foo> = Foo { a: 0, b: Foo { a: 1, b: 17 }}; + assert_eq!(f.b.b.get(), 17); + let f : &Foo> = &f; + assert_eq!(f.b.b.get(), 17); + + // Test that get the pointer via destructuring works + + let f : Foo = Foo { a: 0, b: 11 }; + let f : &Foo = &f; + let &Foo { a: _, b: ref bar } = f; + assert_eq!(bar.get(), 11); + + // Make sure that drop flags don't screw things up + + let d : HasDrop> = HasDrop { + ptr: Box::new(0), + data: Baz { a: [1,2,3,4] } + }; + assert_eq!([1,2,3,4], d.data.a); + + let d : &HasDrop> = &d; + assert_eq!(&[1,2,3,4], &d.data.a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-index.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-index.rs new file mode 100644 index 000000000000..c450999dcce3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-index.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(unused_variables)] +// Test that overloaded index expressions with DST result types +// work and don't ICE. + +use std::ops::Index; +use std::fmt::Debug; + +struct S; + +impl Index for S { + type Output = str; + + fn index<'a>(&'a self, _: usize) -> &'a str { + "hello" + } +} + +struct T; + +impl Index for T { + type Output = dyn Debug + 'static; + + fn index<'a>(&'a self, idx: usize) -> &'a (dyn Debug + 'static) { + static X: usize = 42; + &X as &(dyn Debug + 'static) + } +} + +fn main() { + assert_eq!(&S[0], "hello"); + &T[0]; + // let x = &x as &Debug; +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-irrefutable-bind.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-irrefutable-bind.rs new file mode 100644 index 000000000000..2855fd461a52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-irrefutable-bind.rs @@ -0,0 +1,28 @@ +// run-pass +#![feature(unsized_tuple_coercion)] + +struct Test(T); + +fn main() { + let x = Test([1,2,3]); + let x : &Test<[i32]> = &x; + + let & ref _y = x; + + // Make sure binding to a fat pointer behind a reference + // still works + let slice = &[1,2,3]; + let x = Test(&slice); + let Test(&_slice) = x; + + + let x = (10, [1,2,3]); + let x : &(i32, [i32]) = &x; + + let & ref _y = x; + + let slice = &[1,2,3]; + let x = (10, &slice); + let (_, &_slice) = x; +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-raw.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-raw.rs new file mode 100644 index 000000000000..102e031026f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-raw.rs @@ -0,0 +1,139 @@ +// run-pass +// Test DST raw pointers + + +#![feature(unsized_tuple_coercion)] + +trait Trait { + fn foo(&self) -> isize; +} + +struct A { + f: isize +} +impl Trait for A { + fn foo(&self) -> isize { + self.f + } +} + +struct Foo { + f: T +} + +pub fn main() { + // raw trait object + let x = A { f: 42 }; + let z: *const dyn Trait = &x; + let r = unsafe { + (&*z).foo() + }; + assert_eq!(r, 42); + + // raw DST struct + let p = Foo {f: A { f: 42 }}; + let o: *const Foo = &p; + let r = unsafe { + (&*o).f.foo() + }; + assert_eq!(r, 42); + + // raw DST tuple + let p = (A { f: 42 },); + let o: *const (dyn Trait,) = &p; + let r = unsafe { + (&*o).0.foo() + }; + assert_eq!(r, 42); + + // raw slice + let a: *const [_] = &[1, 2, 3]; + unsafe { + let b = (*a)[2]; + assert_eq!(b, 3); + let len = (*a).len(); + assert_eq!(len, 3); + } + + // raw slice with explicit cast + let a = &[1, 2, 3] as *const [i32]; + unsafe { + let b = (*a)[2]; + assert_eq!(b, 3); + let len = (*a).len(); + assert_eq!(len, 3); + } + + // raw DST struct with slice + let c: *const Foo<[_]> = &Foo {f: [1, 2, 3]}; + unsafe { + let b = (&*c).f[0]; + assert_eq!(b, 1); + let len = (&*c).f.len(); + assert_eq!(len, 3); + } + + // raw DST tuple with slice + let c: *const ([_],) = &([1, 2, 3],); + unsafe { + let b = (&*c).0[0]; + assert_eq!(b, 1); + let len = (&*c).0.len(); + assert_eq!(len, 3); + } + + // all of the above with *mut + let mut x = A { f: 42 }; + let z: *mut dyn Trait = &mut x; + let r = unsafe { + (&*z).foo() + }; + assert_eq!(r, 42); + + let mut p = Foo {f: A { f: 42 }}; + let o: *mut Foo = &mut p; + let r = unsafe { + (&*o).f.foo() + }; + assert_eq!(r, 42); + + let mut p = (A { f: 42 },); + let o: *mut (dyn Trait,) = &mut p; + let r = unsafe { + (&*o).0.foo() + }; + assert_eq!(r, 42); + + let a: *mut [_] = &mut [1, 2, 3]; + unsafe { + let b = (*a)[2]; + assert_eq!(b, 3); + let len = (*a).len(); + assert_eq!(len, 3); + } + + let a = &mut [1, 2, 3] as *mut [i32]; + unsafe { + let b = (*a)[2]; + assert_eq!(b, 3); + let len = (*a).len(); + assert_eq!(len, 3); + } + + let c: *mut Foo<[_]> = &mut Foo {f: [1, 2, 3]}; + unsafe { + let b = (&*c).f[0]; + assert_eq!(b, 1); + let len = (&*c).f.len(); + assert_eq!(len, 3); + } + + let c: *mut ([_],) = &mut ([1, 2, 3],); + unsafe { + let b = (&*c).0[0]; + assert_eq!(b, 1); + let len = (&*c).0.len(); + assert_eq!(len, 3); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-struct-sole.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-struct-sole.rs new file mode 100644 index 000000000000..899c1f5c9b5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-struct-sole.rs @@ -0,0 +1,77 @@ +// run-pass +// As dst-struct.rs, but the unsized field is the only field in the struct. + + +struct Fat { + ptr: T +} + +// x is a fat pointer +fn foo(x: &Fat<[isize]>) { + let y = &x.ptr; + assert_eq!(x.ptr.len(), 3); + assert_eq!(y[0], 1); + assert_eq!(x.ptr[1], 2); +} + +fn foo2(x: &Fat<[T]>) { + let y = &x.ptr; + let bar = Bar; + assert_eq!(x.ptr.len(), 3); + assert_eq!(y[0].to_bar(), bar); + assert_eq!(x.ptr[1].to_bar(), bar); +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +struct Bar; + +trait ToBar { + fn to_bar(&self) -> Bar; +} + +impl ToBar for Bar { + fn to_bar(&self) -> Bar { + *self + } +} + +pub fn main() { + // With a vec of ints. + let f1 = Fat { ptr: [1, 2, 3] }; + foo(&f1); + let f2 = &f1; + foo(f2); + let f3: &Fat<[isize]> = f2; + foo(f3); + let f4: &Fat<[isize]> = &f1; + foo(f4); + let f5: &Fat<[isize]> = &Fat { ptr: [1, 2, 3] }; + foo(f5); + + // With a vec of Bars. + let bar = Bar; + let f1 = Fat { ptr: [bar, bar, bar] }; + foo2(&f1); + let f2 = &f1; + foo2(f2); + let f3: &Fat<[Bar]> = f2; + foo2(f3); + let f4: &Fat<[Bar]> = &f1; + foo2(f4); + let f5: &Fat<[Bar]> = &Fat { ptr: [bar, bar, bar] }; + foo2(f5); + + // Assignment. + let f5: &mut Fat<[isize]> = &mut Fat { ptr: [1, 2, 3] }; + f5.ptr[1] = 34; + assert_eq!(f5.ptr[0], 1); + assert_eq!(f5.ptr[1], 34); + assert_eq!(f5.ptr[2], 3); + + // Zero size vec. + let f5: &Fat<[isize]> = &Fat { ptr: [] }; + assert!(f5.ptr.is_empty()); + let f5: &Fat<[Bar]> = &Fat { ptr: [] }; + assert!(f5.ptr.is_empty()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-struct.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-struct.rs new file mode 100644 index 000000000000..d21fd65c89f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-struct.rs @@ -0,0 +1,123 @@ +// run-pass +#![feature(box_syntax)] + +struct Fat { + f1: isize, + f2: &'static str, + ptr: T +} + +// x is a fat pointer +fn foo(x: &Fat<[isize]>) { + let y = &x.ptr; + assert_eq!(x.ptr.len(), 3); + assert_eq!(y[0], 1); + assert_eq!(x.ptr[1], 2); + assert_eq!(x.f1, 5); + assert_eq!(x.f2, "some str"); +} + +fn foo2(x: &Fat<[T]>) { + let y = &x.ptr; + let bar = Bar; + assert_eq!(x.ptr.len(), 3); + assert_eq!(y[0].to_bar(), bar); + assert_eq!(x.ptr[1].to_bar(), bar); + assert_eq!(x.f1, 5); + assert_eq!(x.f2, "some str"); +} + +fn foo3(x: &Fat>) { + let y = &x.ptr.ptr; + assert_eq!(x.f1, 5); + assert_eq!(x.f2, "some str"); + assert_eq!(x.ptr.f1, 8); + assert_eq!(x.ptr.f2, "deep str"); + assert_eq!(x.ptr.ptr.len(), 3); + assert_eq!(y[0], 1); + assert_eq!(x.ptr.ptr[1], 2); +} + + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +struct Bar; + +trait ToBar { + fn to_bar(&self) -> Bar; +} + +impl ToBar for Bar { + fn to_bar(&self) -> Bar { + *self + } +} + +pub fn main() { + // With a vec of ints. + let f1 = Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] }; + foo(&f1); + let f2 = &f1; + foo(f2); + let f3: &Fat<[isize]> = f2; + foo(f3); + let f4: &Fat<[isize]> = &f1; + foo(f4); + let f5: &Fat<[isize]> = &Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] }; + foo(f5); + + // With a vec of Bars. + let bar = Bar; + let f1 = Fat { f1: 5, f2: "some str", ptr: [bar, bar, bar] }; + foo2(&f1); + let f2 = &f1; + foo2(f2); + let f3: &Fat<[Bar]> = f2; + foo2(f3); + let f4: &Fat<[Bar]> = &f1; + foo2(f4); + let f5: &Fat<[Bar]> = &Fat { f1: 5, f2: "some str", ptr: [bar, bar, bar] }; + foo2(f5); + + // Assignment. + let f5: &mut Fat<[isize]> = &mut Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] }; + f5.ptr[1] = 34; + assert_eq!(f5.ptr[0], 1); + assert_eq!(f5.ptr[1], 34); + assert_eq!(f5.ptr[2], 3); + + // Zero size vec. + let f5: &Fat<[isize]> = &Fat { f1: 5, f2: "some str", ptr: [] }; + assert!(f5.ptr.is_empty()); + let f5: &Fat<[Bar]> = &Fat { f1: 5, f2: "some str", ptr: [] }; + assert!(f5.ptr.is_empty()); + + // Deeply nested. + let f1 = Fat { f1: 5, f2: "some str", ptr: Fat { f1: 8, f2: "deep str", ptr: [1, 2, 3]} }; + foo3(&f1); + let f2 = &f1; + foo3(f2); + let f3: &Fat> = f2; + foo3(f3); + let f4: &Fat> = &f1; + foo3(f4); + let f5: &Fat> = + &Fat { f1: 5, f2: "some str", ptr: Fat { f1: 8, f2: "deep str", ptr: [1, 2, 3]} }; + foo3(f5); + + // Box. + let f1 = Box::new([1, 2, 3]); + assert_eq!((*f1)[1], 2); + let f2: Box<[isize]> = f1; + assert_eq!((*f2)[1], 2); + + // Nested Box. + let f1 : Box> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] }; + foo(&*f1); + let f2 : Box> = f1; + foo(&*f2); + + let f3 : Box> = + Box::>::new(Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] }); + foo(&*f3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-trait-tuple.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-trait-tuple.rs new file mode 100644 index 000000000000..30fd96c61fa7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-trait-tuple.rs @@ -0,0 +1,104 @@ +// run-pass +#![allow(type_alias_bounds)] + +#![allow(unused_features)] +#![feature(box_syntax)] +#![feature(unsized_tuple_coercion)] + +type Fat = (isize, &'static str, T); + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +struct Bar; + +#[derive(Copy, Clone, PartialEq, Eq)] +struct Bar1 { + f: isize +} + +trait ToBar { + fn to_bar(&self) -> Bar; + fn to_val(&self) -> isize; +} + +impl ToBar for Bar { + fn to_bar(&self) -> Bar { + *self + } + fn to_val(&self) -> isize { + 0 + } +} +impl ToBar for Bar1 { + fn to_bar(&self) -> Bar { + Bar + } + fn to_val(&self) -> isize { + self.f + } +} + +// x is a fat pointer +fn foo(x: &Fat) { + assert_eq!(x.0, 5); + assert_eq!(x.1, "some str"); + assert_eq!(x.2.to_bar(), Bar); + assert_eq!(x.2.to_val(), 42); + + let y = &x.2; + assert_eq!(y.to_bar(), Bar); + assert_eq!(y.to_val(), 42); +} + +fn bar(x: &dyn ToBar) { + assert_eq!(x.to_bar(), Bar); + assert_eq!(x.to_val(), 42); +} + +fn baz(x: &Fat>) { + assert_eq!(x.0, 5); + assert_eq!(x.1, "some str"); + assert_eq!((x.2).0, 8); + assert_eq!((x.2).1, "deep str"); + assert_eq!((x.2).2.to_bar(), Bar); + assert_eq!((x.2).2.to_val(), 42); + + let y = &(x.2).2; + assert_eq!(y.to_bar(), Bar); + assert_eq!(y.to_val(), 42); + +} + +pub fn main() { + let f1 = (5, "some str", Bar1 {f :42}); + foo(&f1); + let f2 = &f1; + foo(f2); + let f3: &Fat = f2; + foo(f3); + let f4: &Fat = &f1; + foo(f4); + let f5: &Fat = &(5, "some str", Bar1 {f :42}); + foo(f5); + + // Zero size object. + let f6: &Fat = &(5, "some str", Bar); + assert_eq!(f6.2.to_bar(), Bar); + + // &* + // + let f7: Box = Box::new(Bar1 {f :42}); + bar(&*f7); + + // Deep nesting + let f1 = (5, "some str", (8, "deep str", Bar1 {f :42})); + baz(&f1); + let f2 = &f1; + baz(f2); + let f3: &Fat> = f2; + baz(f3); + let f4: &Fat> = &f1; + baz(f4); + let f5: &Fat> = &(5, "some str", (8, "deep str", Bar1 {f :42})); + baz(f5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-trait.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-trait.rs new file mode 100644 index 000000000000..e168b2fa8607 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-trait.rs @@ -0,0 +1,106 @@ +// run-pass +#![feature(box_syntax)] + +struct Fat { + f1: isize, + f2: &'static str, + ptr: T +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +struct Bar; + +#[derive(Copy, Clone, PartialEq, Eq)] +struct Bar1 { + f: isize +} + +trait ToBar { + fn to_bar(&self) -> Bar; + fn to_val(&self) -> isize; +} + +impl ToBar for Bar { + fn to_bar(&self) -> Bar { + *self + } + fn to_val(&self) -> isize { + 0 + } +} +impl ToBar for Bar1 { + fn to_bar(&self) -> Bar { + Bar + } + fn to_val(&self) -> isize { + self.f + } +} + +// x is a fat pointer +fn foo(x: &Fat) { + assert_eq!(x.f1, 5); + assert_eq!(x.f2, "some str"); + assert_eq!(x.ptr.to_bar(), Bar); + assert_eq!(x.ptr.to_val(), 42); + + let y = &x.ptr; + assert_eq!(y.to_bar(), Bar); + assert_eq!(y.to_val(), 42); +} + +fn bar(x: &dyn ToBar) { + assert_eq!(x.to_bar(), Bar); + assert_eq!(x.to_val(), 42); +} + +fn baz(x: &Fat>) { + assert_eq!(x.f1, 5); + assert_eq!(x.f2, "some str"); + assert_eq!(x.ptr.f1, 8); + assert_eq!(x.ptr.f2, "deep str"); + assert_eq!(x.ptr.ptr.to_bar(), Bar); + assert_eq!(x.ptr.ptr.to_val(), 42); + + let y = &x.ptr.ptr; + assert_eq!(y.to_bar(), Bar); + assert_eq!(y.to_val(), 42); + +} + +pub fn main() { + let f1 = Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} }; + foo(&f1); + let f2 = &f1; + foo(f2); + let f3: &Fat = f2; + foo(f3); + let f4: &Fat = &f1; + foo(f4); + let f5: &Fat = &Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} }; + foo(f5); + + // Zero size object. + let f6: &Fat = &Fat { f1: 5, f2: "some str", ptr: Bar }; + assert_eq!(f6.ptr.to_bar(), Bar); + + // &* + // + let f7: Box = Box::new(Bar1 {f :42}); + bar(&*f7); + + // Deep nesting + let f1 = + Fat { f1: 5, f2: "some str", ptr: Fat { f1: 8, f2: "deep str", ptr: Bar1 {f :42}} }; + baz(&f1); + let f2 = &f1; + baz(f2); + let f3: &Fat> = f2; + baz(f3); + let f4: &Fat> = &f1; + baz(f4); + let f5: &Fat> = + &Fat { f1: 5, f2: "some str", ptr: Fat { f1: 8, f2: "deep str", ptr: Bar1 {f :42}} }; + baz(f5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple-no-reorder.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple-no-reorder.rs new file mode 100644 index 000000000000..f3143a3ead72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple-no-reorder.rs @@ -0,0 +1,27 @@ +// run-pass + +#![feature(unsized_tuple_coercion)] + +// Ensure that unsizable fields that might be accessed don't get reordered + +fn nonzero_size() { + let sized: (u8, [u32; 2]) = (123, [456, 789]); + let unsize: &(u8, [u32]) = &sized; + assert_eq!(unsize.0, 123); + assert_eq!(unsize.1.len(), 2); + assert_eq!(unsize.1[0], 456); + assert_eq!(unsize.1[1], 789); +} + +fn zst() { + let sized: (u8, [u32; 0]) = (123, []); + let unsize: &(u8, [u32]) = &sized; + assert_eq!(unsize.0, 123); + assert_eq!(unsize.1.len(), 0); +} + +pub fn main() { + nonzero_size(); + zst(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple-sole.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple-sole.rs new file mode 100644 index 000000000000..c63a28af8eb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple-sole.rs @@ -0,0 +1,80 @@ +// run-pass +#![allow(stable_features)] +#![allow(type_alias_bounds)] + +// As dst-tuple.rs, but the unsized field is the only field in the tuple. + + +#![feature(unsized_tuple_coercion)] + +type Fat = (T,); + +// x is a fat pointer +fn foo(x: &Fat<[isize]>) { + let y = &x.0; + assert_eq!(x.0.len(), 3); + assert_eq!(y[0], 1); + assert_eq!(x.0[1], 2); +} + +fn foo2(x: &Fat<[T]>) { + let y = &x.0; + let bar = Bar; + assert_eq!(x.0.len(), 3); + assert_eq!(y[0].to_bar(), bar); + assert_eq!(x.0[1].to_bar(), bar); +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +struct Bar; + +trait ToBar { + fn to_bar(&self) -> Bar; +} + +impl ToBar for Bar { + fn to_bar(&self) -> Bar { + *self + } +} + +pub fn main() { + // With a vec of ints. + let f1 = ([1, 2, 3],); + foo(&f1); + let f2 = &f1; + foo(f2); + let f3: &Fat<[isize]> = f2; + foo(f3); + let f4: &Fat<[isize]> = &f1; + foo(f4); + let f5: &Fat<[isize]> = &([1, 2, 3],); + foo(f5); + + // With a vec of Bars. + let bar = Bar; + let f1 = ([bar, bar, bar],); + foo2(&f1); + let f2 = &f1; + foo2(f2); + let f3: &Fat<[Bar]> = f2; + foo2(f3); + let f4: &Fat<[Bar]> = &f1; + foo2(f4); + let f5: &Fat<[Bar]> = &([bar, bar, bar],); + foo2(f5); + + // Assignment. + let f5: &mut Fat<[isize]> = &mut ([1, 2, 3],); + f5.0[1] = 34; + assert_eq!(f5.0[0], 1); + assert_eq!(f5.0[1], 34); + assert_eq!(f5.0[2], 3); + + // Zero size vec. + let f5: &Fat<[isize]> = &([],); + assert!(f5.0.is_empty()); + let f5: &Fat<[Bar]> = &([],); + assert!(f5.0.is_empty()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs new file mode 100644 index 000000000000..945b811ab0c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs @@ -0,0 +1,23 @@ +// run-pass + +#![feature(unsized_tuple_coercion)] + +// Check that we do not change the offsets of ZST fields when unsizing + +fn scalar_layout() { + let sized: &(u8, [(); 13]) = &(123, [(); 13]); + let unsize: &(u8, [()]) = sized; + assert_eq!(sized.1.as_ptr(), unsize.1.as_ptr()); +} + +fn scalarpair_layout() { + let sized: &(u8, u16, [(); 13]) = &(123, 456, [(); 13]); + let unsize: &(u8, u16, [()]) = sized; + assert_eq!(sized.2.as_ptr(), unsize.2.as_ptr()); +} + +pub fn main() { + scalar_layout(); + scalarpair_layout(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple.rs b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple.rs new file mode 100644 index 000000000000..9f40d8566cea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/dynamically-sized-types/dst-tuple.rs @@ -0,0 +1,121 @@ +// run-pass +#![allow(type_alias_bounds)] + +#![feature(box_syntax)] +#![feature(unsized_tuple_coercion)] + +type Fat = (isize, &'static str, T); + +// x is a fat pointer +fn foo(x: &Fat<[isize]>) { + let y = &x.2; + assert_eq!(x.2.len(), 3); + assert_eq!(y[0], 1); + assert_eq!(x.2[1], 2); + assert_eq!(x.0, 5); + assert_eq!(x.1, "some str"); +} + +fn foo2(x: &Fat<[T]>) { + let y = &x.2; + let bar = Bar; + assert_eq!(x.2.len(), 3); + assert_eq!(y[0].to_bar(), bar); + assert_eq!(x.2[1].to_bar(), bar); + assert_eq!(x.0, 5); + assert_eq!(x.1, "some str"); +} + +fn foo3(x: &Fat>) { + let y = &(x.2).2; + assert_eq!(x.0, 5); + assert_eq!(x.1, "some str"); + assert_eq!((x.2).0, 8); + assert_eq!((x.2).1, "deep str"); + assert_eq!((x.2).2.len(), 3); + assert_eq!(y[0], 1); + assert_eq!((x.2).2[1], 2); +} + + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +struct Bar; + +trait ToBar { + fn to_bar(&self) -> Bar; +} + +impl ToBar for Bar { + fn to_bar(&self) -> Bar { + *self + } +} + +pub fn main() { + // With a vec of ints. + let f1 = (5, "some str", [1, 2, 3]); + foo(&f1); + let f2 = &f1; + foo(f2); + let f3: &Fat<[isize]> = f2; + foo(f3); + let f4: &Fat<[isize]> = &f1; + foo(f4); + let f5: &Fat<[isize]> = &(5, "some str", [1, 2, 3]); + foo(f5); + + // With a vec of Bars. + let bar = Bar; + let f1 = (5, "some str", [bar, bar, bar]); + foo2(&f1); + let f2 = &f1; + foo2(f2); + let f3: &Fat<[Bar]> = f2; + foo2(f3); + let f4: &Fat<[Bar]> = &f1; + foo2(f4); + let f5: &Fat<[Bar]> = &(5, "some str", [bar, bar, bar]); + foo2(f5); + + // Assignment. + let f5: &mut Fat<[isize]> = &mut (5, "some str", [1, 2, 3]); + f5.2[1] = 34; + assert_eq!(f5.2[0], 1); + assert_eq!(f5.2[1], 34); + assert_eq!(f5.2[2], 3); + + // Zero size vec. + let f5: &Fat<[isize]> = &(5, "some str", []); + assert!(f5.2.is_empty()); + let f5: &Fat<[Bar]> = &(5, "some str", []); + assert!(f5.2.is_empty()); + + // Deeply nested. + let f1 = (5, "some str", (8, "deep str", [1, 2, 3])); + foo3(&f1); + let f2 = &f1; + foo3(f2); + let f3: &Fat> = f2; + foo3(f3); + let f4: &Fat> = &f1; + foo3(f4); + let f5: &Fat> = &(5, "some str", (8, "deep str", [1, 2, 3])); + foo3(f5); + + // Box. + let f1 = Box::new([1, 2, 3]); + assert_eq!((*f1)[1], 2); + let f2: Box<[isize]> = f1; + assert_eq!((*f2)[1], 2); + + // Nested Box. + let f1 : Box> = box (5, "some str", [1, 2, 3]); + foo(&*f1); + let f2 : Box> = f1; + foo(&*f2); + + let f3 : Box> = + Box::>::new((5, "some str", [1, 2, 3])); + foo(&*f3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/early-ret-binop-add.rs b/gcc/testsuite/rust/rustc/ui/early-ret-binop-add.rs new file mode 100644 index 000000000000..89f38df48e27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/early-ret-binop-add.rs @@ -0,0 +1,12 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unreachable_code)] +// pretty-expanded FIXME #23616 + +use std::ops::Add; + +fn wsucc + Copy>(n: T) -> T { n + { return n } } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/early-vtbl-resolution.rs b/gcc/testsuite/rust/rustc/ui/early-vtbl-resolution.rs new file mode 100644 index 000000000000..249eba4697b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/early-vtbl-resolution.rs @@ -0,0 +1,20 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait thing { + fn foo(&self) -> Option; +} +impl thing for isize { + fn foo(&self) -> Option { None } +} +fn foo_func>(x: B) -> Option { x.foo() } + +struct A { a: isize } + +pub fn main() { + let _x: Option = foo_func(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/edition-keywords-2015-2015.rs b/gcc/testsuite/rust/rustc/ui/edition-keywords-2015-2015.rs new file mode 100644 index 000000000000..38d9228c4bbb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/edition-keywords-2015-2015.rs @@ -0,0 +1,37 @@ +// run-pass + +#![allow(unused_mut)] +#![allow(unused_assignments)] +#![allow(unused_variables)] +// edition:2015 +// aux-build:edition-kw-macro-2015.rs + +#[macro_use] +extern crate edition_kw_macro_2015; + +pub fn check_async() { + let mut async = 1; // OK + let mut r#async = 1; // OK + + r#async = consumes_async!(async); // OK + // r#async = consumes_async!(r#async); // ERROR, not a match + // r#async = consumes_async_raw!(async); // ERROR, not a match + r#async = consumes_async_raw!(r#async); // OK + + if passes_ident!(async) == 1 {} // OK + if passes_ident!(r#async) == 1 {} // OK + one_async::async(); // OK + one_async::r#async(); // OK + two_async::async(); // OK + two_async::r#async(); // OK +} + +mod one_async { + produces_async! {} // OK +} +mod two_async { + produces_async_raw! {} // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/edition-keywords-2015-2018.rs b/gcc/testsuite/rust/rustc/ui/edition-keywords-2015-2018.rs new file mode 100644 index 000000000000..3aca68df7773 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/edition-keywords-2015-2018.rs @@ -0,0 +1,37 @@ +// run-pass + +#![allow(unused_mut)] +#![allow(unused_assignments)] +#![allow(unused_variables)] +// edition:2015 +// aux-build:edition-kw-macro-2018.rs + +#[macro_use] +extern crate edition_kw_macro_2018; + +pub fn check_async() { + let mut async = 1; // OK + let mut r#async = 1; // OK + + r#async = consumes_async!(async); // OK + // r#async = consumes_async!(r#async); // ERROR, not a match + // r#async = consumes_async_raw!(async); // ERROR, not a match + r#async = consumes_async_raw!(r#async); // OK + + if passes_ident!(async) == 1 {} // OK + if passes_ident!(r#async) == 1 {} // OK + // one_async::async(); // ERROR, unresolved name + // one_async::r#async(); // ERROR, unresolved name + two_async::async(); // OK + two_async::r#async(); // OK +} + +mod one_async { + // produces_async! {} // ERROR, reserved +} +mod two_async { + produces_async_raw! {} // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/edition-keywords-2018-2015.rs b/gcc/testsuite/rust/rustc/ui/edition-keywords-2018-2015.rs new file mode 100644 index 000000000000..346501a035f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/edition-keywords-2018-2015.rs @@ -0,0 +1,35 @@ +// run-pass + +#![allow(unused_assignments)] +// edition:2018 +// aux-build:edition-kw-macro-2015.rs + +#[macro_use] +extern crate edition_kw_macro_2015; + +pub fn check_async() { + // let mut async = 1; // ERROR, reserved + let mut r#async = 1; // OK + + r#async = consumes_async!(async); // OK + // r#async = consumes_async!(r#async); // ERROR, not a match + // r#async = consumes_async_raw!(async); // ERROR, not a match + r#async = consumes_async_raw!(r#async); // OK + + // if passes_ident!(async) == 1 {} // ERROR, reserved + if passes_ident!(r#async) == 1 {} // OK + // one_async::async(); // ERROR, reserved + one_async::r#async(); // OK + // two_async::async(); // ERROR, reserved + two_async::r#async(); // OK +} + +mod one_async { + produces_async! {} // OK +} +mod two_async { + produces_async_raw! {} // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/edition-keywords-2018-2018.rs b/gcc/testsuite/rust/rustc/ui/edition-keywords-2018-2018.rs new file mode 100644 index 000000000000..e71d36faa16f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/edition-keywords-2018-2018.rs @@ -0,0 +1,35 @@ +// run-pass + +#![allow(unused_assignments)] +// edition:2018 +// aux-build:edition-kw-macro-2018.rs + +#[macro_use] +extern crate edition_kw_macro_2018; + +pub fn check_async() { + // let mut async = 1; // ERROR, reserved + let mut r#async = 1; // OK + + r#async = consumes_async!(async); // OK + // r#async = consumes_async!(r#async); // ERROR, not a match + // r#async = consumes_async_raw!(async); // ERROR, not a match + r#async = consumes_async_raw!(r#async); // OK + + // if passes_ident!(async) == 1 {} // ERROR, reserved + if passes_ident!(r#async) == 1 {} // OK + // one_async::async(); // ERROR, reserved + // one_async::r#async(); // ERROR, unresolved name + // two_async::async(); // ERROR, reserved + two_async::r#async(); // OK +} + +mod one_async { + // produces_async! {} // ERROR, reserved +} +mod two_async { + produces_async_raw! {} // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/async-block-2015.rs b/gcc/testsuite/rust/rustc/ui/editions/async-block-2015.rs new file mode 100644 index 000000000000..4dd5a8308b64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/async-block-2015.rs @@ -0,0 +1,31 @@ +async fn foo() { +// { dg-error ".E0670." "" { target *-*-* } .-1 } +// { dg-note ".E0670." "" { target *-*-* } .-2 } +// { help ".E0670." "" { target *-*-* } .-3 } +// { dg-note ".E0670." "" { target *-*-* } .-4 } + + let x = async {}; +// { dg-error ".E0422." "" { target *-*-* } .-1 } +// { dg-note ".E0422." "" { target *-*-* } .-2 } + let y = async { // { dg-note "" "" { target *-*-* } } + let x = 42; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +// { dg-note "" "" { target *-*-* } .-4 } + 42 + }; + let z = async { // { dg-note "" "" { target *-*-* } } + 42 +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +// { dg-note "" "" { target *-*-* } .-4 } + }; + y.await; + z.await; + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/auxiliary/absolute.rs b/gcc/testsuite/rust/rustc/ui/editions/auxiliary/absolute.rs new file mode 100644 index 000000000000..296dacac2f13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/auxiliary/absolute.rs @@ -0,0 +1,2 @@ +pub struct Path; + diff --git a/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-extern-crate-allowed.rs b/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-extern-crate-allowed.rs new file mode 100644 index 000000000000..c84c7b394dc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-extern-crate-allowed.rs @@ -0,0 +1,2 @@ +// intentionally empty + diff --git a/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-imports-2015.rs b/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-imports-2015.rs new file mode 100644 index 000000000000..15a79b374b7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-imports-2015.rs @@ -0,0 +1,32 @@ +// edition:2015 + +#[macro_export] +macro_rules! gen_imports { () => { + use import::Path; + use std::collections::LinkedList; + + fn check_absolute() { + ::absolute::Path; + ::std::collections::LinkedList::::new(); + } +}} + +#[macro_export] +macro_rules! gen_glob { () => { + use *; +}} + +#[macro_export] +macro_rules! gen_gated { () => { + fn check_gated() { + enum E { A } + use E::*; + } +}} + +#[macro_export] +macro_rules! gen_ambiguous { () => { + use Ambiguous; + type A = ::edition_imports_2015::Path; +}} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-imports-2018.rs b/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-imports-2018.rs new file mode 100644 index 000000000000..3fa97cbf8402 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-imports-2018.rs @@ -0,0 +1,18 @@ +// edition:2018 + +#[macro_export] +macro_rules! gen_imports { () => { + use import::Path; + use std::collections::LinkedList; + + fn check_absolute() { + ::absolute::Path; + ::std::collections::LinkedList::::new(); + } +}} + +#[macro_export] +macro_rules! gen_glob { () => { + use *; +}} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-kw-macro-2015.rs b/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-kw-macro-2015.rs new file mode 100644 index 000000000000..f84c965d8d52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-kw-macro-2015.rs @@ -0,0 +1,29 @@ +// edition:2015 + +#![allow(keyword_idents)] + +#[macro_export] +macro_rules! produces_async { + () => (pub fn async() {}) +} + +#[macro_export] +macro_rules! produces_async_raw { + () => (pub fn r#async() {}) +} + +#[macro_export] +macro_rules! consumes_async { + (async) => (1) +} + +#[macro_export] +macro_rules! consumes_async_raw { + (r#async) => (1) +} + +#[macro_export] +macro_rules! passes_ident { + ($i: ident) => ($i) +} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-kw-macro-2018.rs b/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-kw-macro-2018.rs new file mode 100644 index 000000000000..1affecacc95b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/auxiliary/edition-kw-macro-2018.rs @@ -0,0 +1,29 @@ +// edition:2018 + +#![allow(keyword_idents)] + +#[macro_export] +macro_rules! produces_async { + () => (pub fn async() {}) +} + +#[macro_export] +macro_rules! produces_async_raw { + () => (pub fn r#async() {}) +} + +#[macro_export] +macro_rules! consumes_async { + (async) => (1) +} + +#[macro_export] +macro_rules! consumes_async_raw { + (r#async) => (1) +} + +#[macro_export] +macro_rules! passes_ident { + ($i: ident) => ($i) +} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-extern-crate-allowed.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-extern-crate-allowed.rs new file mode 100644 index 000000000000..511f167ded16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-extern-crate-allowed.rs @@ -0,0 +1,11 @@ +// aux-build:edition-extern-crate-allowed.rs +// edition:2015 +// check-pass + +#![warn(rust_2018_idioms)] + +extern crate edition_extern_crate_allowed; +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-feature-ok.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-feature-ok.rs new file mode 100644 index 000000000000..5b5c848deb94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-feature-ok.rs @@ -0,0 +1,6 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(rust_2018_preview)] + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-feature-redundant.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-feature-redundant.rs new file mode 100644 index 000000000000..a1885e2b0b88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-feature-redundant.rs @@ -0,0 +1,8 @@ +// edition:2018 +// check-pass + +#![feature(rust_2018_preview)] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-imports-2015.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-imports-2015.rs new file mode 100644 index 000000000000..c13bc53f6434 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-imports-2015.rs @@ -0,0 +1,27 @@ +// edition:2015 +// compile-flags:--extern absolute +// aux-build:edition-imports-2018.rs +// aux-build:absolute.rs + +#[macro_use] +extern crate edition_imports_2018; + +mod check { + mod import { + pub struct Path; + } + + gen_imports!(); // OK + + fn check() { + Path; + LinkedList::::new(); + } +} + +mod check_glob { + gen_glob!(); // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-imports-2018.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-imports-2018.rs new file mode 100644 index 000000000000..a029ac07ac6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-imports-2018.rs @@ -0,0 +1,28 @@ +// edition:2018 +// aux-build:edition-imports-2015.rs + +#[macro_use] +extern crate edition_imports_2015; + +mod import { + pub struct Path; +} +mod absolute { + pub struct Path; +} + +mod check { + gen_imports!(); // OK + + fn check() { + Path; + LinkedList::::new(); + } +} + +mod check_glob { + gen_glob!(); // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-imports-virtual-2015-ambiguity.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-imports-virtual-2015-ambiguity.rs new file mode 100644 index 000000000000..4729ab3e8da2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-imports-virtual-2015-ambiguity.rs @@ -0,0 +1,21 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 +// compile-flags:--extern edition_imports_2015 +// aux-build:edition-imports-2015.rs + +mod edition_imports_2015 { + pub struct Path; +} + +pub struct Ambiguous {} + +mod check { + pub struct Ambiguous {} + + fn check() { + edition_imports_2015::gen_ambiguous!(); // OK + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-imports-virtual-2015-gated.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-imports-virtual-2015-gated.rs new file mode 100644 index 000000000000..9147503624bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-imports-virtual-2015-gated.rs @@ -0,0 +1,12 @@ +// edition:2018 +// aux-build:edition-imports-2015.rs + +#[macro_use] +extern crate edition_imports_2015; + +mod check { + gen_gated!(); // { dg-error ".E0432." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2015-expansion.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2015-expansion.rs new file mode 100644 index 000000000000..d26f11d28e30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2015-expansion.rs @@ -0,0 +1,18 @@ +// edition:2015 +// aux-build:edition-kw-macro-2015.rs +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(keyword_idents)] + +#[macro_use] +extern crate edition_kw_macro_2015; + +mod one_async { + produces_async! {} // OK +} +mod two_async { + produces_async_raw! {} // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2015-parsing.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2015-parsing.rs new file mode 100644 index 000000000000..442b43d54f0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2015-parsing.rs @@ -0,0 +1,27 @@ +// edition:2015 +// aux-build:edition-kw-macro-2015.rs + +#[macro_use] +extern crate edition_kw_macro_2015; + +mod module { + pub fn async() {} +} + +pub fn check_async() { + let mut async = 1; // OK + let mut r#async = 1; // OK + + r#async = consumes_async!(async); // OK + r#async = consumes_async!(r#async); // { dg-error "" "" { target *-*-* } } + r#async = consumes_async_raw!(async); // { dg-error "" "" { target *-*-* } } + r#async = consumes_async_raw!(r#async); // OK + + if passes_ident!(async) == 1 {} // OK + if passes_ident!(r#async) == 1 {} // OK + module::async(); // OK + module::r#async(); // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2018-expansion.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2018-expansion.rs new file mode 100644 index 000000000000..e1773a21b738 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2018-expansion.rs @@ -0,0 +1,15 @@ +// edition:2015 +// aux-build:edition-kw-macro-2018.rs + +#[macro_use] +extern crate edition_kw_macro_2018; + +mod one_async { + produces_async! {} // { dg-error "" "" { target *-*-* } } +} +mod two_async { + produces_async_raw! {} // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2018-parsing.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2018-parsing.rs new file mode 100644 index 000000000000..403f78322b63 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2015-2018-parsing.rs @@ -0,0 +1,27 @@ +// edition:2015 +// aux-build:edition-kw-macro-2018.rs + +#[macro_use] +extern crate edition_kw_macro_2018; + +mod module { + pub fn async() {} +} + +pub fn check_async() { + let mut async = 1; // OK + let mut r#async = 1; // OK + + r#async = consumes_async!(async); // OK + r#async = consumes_async!(r#async); // { dg-error "" "" { target *-*-* } } + r#async = consumes_async_raw!(async); // { dg-error "" "" { target *-*-* } } + r#async = consumes_async_raw!(r#async); // OK + + if passes_ident!(async) == 1 {} // OK + if passes_ident!(r#async) == 1 {} // OK + module::async(); // OK + module::r#async(); // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2015-expansion.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2015-expansion.rs new file mode 100644 index 000000000000..4f37135e0319 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2015-expansion.rs @@ -0,0 +1,18 @@ +// edition:2018 +// aux-build:edition-kw-macro-2015.rs +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(keyword_idents)] + +#[macro_use] +extern crate edition_kw_macro_2015; + +mod one_async { + produces_async! {} // OK +} +mod two_async { + produces_async_raw! {} // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2015-parsing.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2015-parsing.rs new file mode 100644 index 000000000000..abf98a313092 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2015-parsing.rs @@ -0,0 +1,31 @@ +// edition:2018 +// aux-build:edition-kw-macro-2015.rs + +#![feature(async_closure)] + +fn main() {} + +#[macro_use] +extern crate edition_kw_macro_2015; + +mod module { + pub fn r#async() {} +} + +pub fn check_async() { + let mut async = 1; // { dg-error "" "" { target *-*-* } } + let mut r#async = 1; // OK + + r#async = consumes_async!(async); // OK + r#async = consumes_async!(r#async); // { dg-error "" "" { target *-*-* } } + r#async = consumes_async_raw!(async); // { dg-error "" "" { target *-*-* } } + r#async = consumes_async_raw!(r#async); // OK + + if passes_ident!(async) == 1 {} + if passes_ident!(r#async) == 1 {} // OK + module::async(); // { dg-error "" "" { target *-*-* } } + module::r#async(); // OK + + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2018-expansion.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2018-expansion.rs new file mode 100644 index 000000000000..367244754795 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2018-expansion.rs @@ -0,0 +1,15 @@ +// edition:2018 +// aux-build:edition-kw-macro-2018.rs + +#[macro_use] +extern crate edition_kw_macro_2018; + +mod one_async { + produces_async! {} // { dg-error "" "" { target *-*-* } } +} +mod two_async { + produces_async_raw! {} // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2018-parsing.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2018-parsing.rs new file mode 100644 index 000000000000..e0bd88d169c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-keywords-2018-2018-parsing.rs @@ -0,0 +1,31 @@ +// edition:2018 +// aux-build:edition-kw-macro-2018.rs + +#![feature(async_closure)] + +fn main() {} + +#[macro_use] +extern crate edition_kw_macro_2018; + +mod module { + pub fn r#async() {} +} + +pub fn check_async() { + let mut async = 1; // { dg-error "" "" { target *-*-* } } + let mut r#async = 1; // OK + + r#async = consumes_async!(async); // OK + r#async = consumes_async!(r#async); // { dg-error "" "" { target *-*-* } } + r#async = consumes_async_raw!(async); // { dg-error "" "" { target *-*-* } } + r#async = consumes_async_raw!(r#async); // OK + + if passes_ident!(async) == 1 {} + if passes_ident!(r#async) == 1 {} // OK + module::async(); // { dg-error "" "" { target *-*-* } } + module::r#async(); // OK + + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-raw-pointer-method-2015.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-raw-pointer-method-2015.rs new file mode 100644 index 000000000000..1aaa3ae9f06e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-raw-pointer-method-2015.rs @@ -0,0 +1,13 @@ +// edition:2015 + +// tests that editions work with the tyvar warning-turned-error + +#[deny(warnings)] +fn main() { + let x = 0; + let y = &x as *const _; + let _ = y.is_null(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/editions/edition-raw-pointer-method-2018.rs b/gcc/testsuite/rust/rustc/ui/editions/edition-raw-pointer-method-2018.rs new file mode 100644 index 000000000000..1815f7f0ea40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/editions/edition-raw-pointer-method-2018.rs @@ -0,0 +1,12 @@ +// edition:2018 + +// tests that editions work with the tyvar warning-turned-error + +#[deny(warnings)] +fn main() { + let x = 0; + let y = &x as *const _; + let _ = y.is_null(); +// { dg-error ".E0699." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/elide-errors-on-mismatched-tuple.rs b/gcc/testsuite/rust/rustc/ui/elide-errors-on-mismatched-tuple.rs new file mode 100644 index 000000000000..77dde98f567c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/elide-errors-on-mismatched-tuple.rs @@ -0,0 +1,19 @@ +// Hide irrelevant E0277 errors (#50333) + +trait T {} + +struct A; +impl T for A {} +impl A { + fn new() -> Self { + Self {} + } +} + +fn main() { + let (a, b, c) = (A::new(), A::new()); // This tuple is 2 elements, should be three +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let ts: Vec<&dyn T> = vec![&a, &b, &c]; + // There is no E0277 error above, as `a`, `b` and `c` are `TyErr` +} + diff --git a/gcc/testsuite/rust/rustc/ui/elided-test.rs b/gcc/testsuite/rust/rustc/ui/elided-test.rs new file mode 100644 index 000000000000..74ffebfa6f00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/elided-test.rs @@ -0,0 +1,8 @@ +// error-pattern: `main` function not found + +// Since we're not compiling a test runner this function should be elided +// and the build will fail because main doesn't exist +#[test] +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/else-if.rs b/gcc/testsuite/rust/rustc/ui/else-if.rs new file mode 100644 index 000000000000..ebff13e28d33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/else-if.rs @@ -0,0 +1,21 @@ +// run-pass + +pub fn main() { + if 1 == 2 { + assert!((false)); + } else if 2 == 3 { + assert!((false)); + } else if 3 == 4 { assert!((false)); } else { assert!((true)); } + if 1 == 2 { assert!((false)); } else if 2 == 2 { assert!((true)); } + if 1 == 2 { + assert!((false)); + } else if 2 == 2 { + if 1 == 1 { + assert!((true)); + } else { if 2 == 1 { assert!((false)); } else { assert!((false)); } } + } + if 1 == 2 { + assert!((false)); + } else { if 1 == 2 { assert!((false)); } else { assert!((true)); } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/emit-artifact-notifications.rs b/gcc/testsuite/rust/rustc/ui/emit-artifact-notifications.rs new file mode 100644 index 000000000000..257c692b262d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/emit-artifact-notifications.rs @@ -0,0 +1,9 @@ +// compile-flags:--emit=metadata --error-format=json --json artifacts +// build-pass +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. + +// A very basic test for the emission of artifact notifications in JSON output. + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/empty-allocation-non-null.rs b/gcc/testsuite/rust/rustc/ui/empty-allocation-non-null.rs new file mode 100644 index 000000000000..d7ddc6a9a7fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty-allocation-non-null.rs @@ -0,0 +1,15 @@ +// run-pass + +pub fn main() { + assert!(Some(Box::new(())).is_some()); + + let xs: Box<[()]> = Box::<[(); 0]>::new([]); + assert!(Some(xs).is_some()); + + struct Foo; + assert!(Some(Box::new(Foo)).is_some()); + + let ys: Box<[Foo]> = Box::<[Foo; 0]>::new([]); + assert!(Some(ys).is_some()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty-allocation-rvalue-non-null.rs b/gcc/testsuite/rust/rustc/ui/empty-allocation-rvalue-non-null.rs new file mode 100644 index 000000000000..c4acb06dd332 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty-allocation-rvalue-non-null.rs @@ -0,0 +1,9 @@ +// run-pass + +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +pub fn main() { + let x = *Box::new(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty-type-parameter-list.rs b/gcc/testsuite/rust/rustc/ui/empty-type-parameter-list.rs new file mode 100644 index 000000000000..a07a6079d591 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty-type-parameter-list.rs @@ -0,0 +1,25 @@ +// run-pass +// Test that empty type parameter list (<>) is synonymous with +// no type parameters at all + +struct S<>; +trait T<> {} +enum E<> { V } +impl<> T<> for S<> {} +impl T for E {} +fn foo<>() {} +fn bar() {} + +fn main() { + let _ = S; + let _ = S::<>; + let _ = E::V; + let _ = E::<>::V; + foo(); + foo::<>(); + + // Test that we can supply <> to non generic things + bar::<>(); + let _: i32<>; +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty/auxiliary/empty-struct.rs b/gcc/testsuite/rust/rustc/ui/empty/auxiliary/empty-struct.rs new file mode 100644 index 000000000000..8972f6e406ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/auxiliary/empty-struct.rs @@ -0,0 +1,10 @@ +pub struct XEmpty1 {} +pub struct XEmpty2; +pub struct XEmpty6(); + +pub enum XE { + XEmpty3 {}, + XEmpty4, + XEmpty5(), +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty/auxiliary/two_macros.rs b/gcc/testsuite/rust/rustc/ui/empty/auxiliary/two_macros.rs new file mode 100644 index 000000000000..b97cc55cabc3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/auxiliary/two_macros.rs @@ -0,0 +1,6 @@ +#[macro_export] +macro_rules! macro_one { () => ("one") } + +#[macro_export] +macro_rules! macro_two { () => ("two") } + diff --git a/gcc/testsuite/rust/rustc/ui/empty/empty-comment.rs b/gcc/testsuite/rust/rustc/ui/empty/empty-comment.rs new file mode 100644 index 000000000000..2f952266507d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/empty-comment.rs @@ -0,0 +1,12 @@ +// `/**/` was previously regarded as a doc comment because it starts with `/**` and ends with `*/`. +// This could break some internal logic that assumes the length of a doc comment is at least 5, +// leading to an ICE. + +macro_rules! one_arg_macro { + ($fmt:expr) => (print!(concat!($fmt, "\n"))); +} + +fn main() { + one_arg_macro!(/**/); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty/empty-linkname.rs b/gcc/testsuite/rust/rustc/ui/empty/empty-linkname.rs new file mode 100644 index 000000000000..1589cacedacf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/empty-linkname.rs @@ -0,0 +1,6 @@ +#[link(name = "")] // { dg-error ".E0454." "" { target *-*-* } } +extern { +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/empty/empty-macro-use.rs b/gcc/testsuite/rust/rustc/ui/empty/empty-macro-use.rs new file mode 100644 index 000000000000..91c60a2ddc51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/empty-macro-use.rs @@ -0,0 +1,10 @@ +// aux-build:two_macros.rs + +#[macro_use()] +extern crate two_macros; + +pub fn main() { + macro_two!(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty/empty-never-array.rs b/gcc/testsuite/rust/rustc/ui/empty/empty-never-array.rs new file mode 100644 index 000000000000..7ff2b849e765 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/empty-never-array.rs @@ -0,0 +1,18 @@ +#![feature(never_type)] + +enum Helper { + T(T, [!; 0]), + #[allow(dead_code)] + U(U), +} + +fn transmute(t: T) -> U { + let Helper::U(u) = Helper::T(t, []); +// { dg-error ".E0005." "" { target *-*-* } .-1 } + u +} + +fn main() { + println!("{:?}", transmute::<&str, (*const u8, u64)>("type safety")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-expr.rs b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-expr.rs new file mode 100644 index 000000000000..de1a01676438 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-expr.rs @@ -0,0 +1,30 @@ +// Can't use empty braced struct as constant or constructor function + +// aux-build:empty-struct.rs + +extern crate empty_struct; +use empty_struct::*; + +struct Empty1 {} + +enum E { + Empty3 {} +} + +fn main() { + let e1 = Empty1; // { dg-error ".E0423." "" { target *-*-* } } + let e1 = Empty1(); +// { dg-error ".E0423." "" { target *-*-* } .-1 } + let e3 = E::Empty3; // { dg-error ".E0423." "" { target *-*-* } } + let e3 = E::Empty3(); +// { dg-error ".E0423." "" { target *-*-* } .-1 } + + let xe1 = XEmpty1; // { dg-error ".E0423." "" { target *-*-* } } + let xe1 = XEmpty1(); +// { dg-error ".E0423." "" { target *-*-* } .-1 } + let xe3 = XE::Empty3; // { dg-error ".E0599." "" { target *-*-* } } + let xe3 = XE::Empty3(); // { dg-error ".E0599." "" { target *-*-* } } + + XE::Empty1 {}; // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-pat-1.rs b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-pat-1.rs new file mode 100644 index 000000000000..3aa49ae39d1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-pat-1.rs @@ -0,0 +1,35 @@ +// Can't use empty braced struct as constant pattern + +// aux-build:empty-struct.rs + +extern crate empty_struct; +use empty_struct::*; + +struct Empty1 {} + +enum E { + Empty3 {} +} + +fn main() { + let e1 = Empty1 {}; + let e3 = E::Empty3 {}; + let xe1 = XEmpty1 {}; + let xe3 = XE::XEmpty3 {}; + + match e1 { + Empty1 => () // Not an error, `Empty1` is interpreted as a new binding + } + match e3 { + E::Empty3 => () +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } + match xe1 { + XEmpty1 => () // Not an error, `XEmpty1` is interpreted as a new binding + } + match xe3 { + XE::XEmpty3 => () +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-pat-2.rs b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-pat-2.rs new file mode 100644 index 000000000000..848230431b32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-pat-2.rs @@ -0,0 +1,27 @@ +// Can't use empty braced struct as enum pattern + +// aux-build:empty-struct.rs + +extern crate empty_struct; +use empty_struct::*; + +struct Empty1 {} + +fn main() { + let e1 = Empty1 {}; + let xe1 = XEmpty1 {}; + + match e1 { + Empty1() => () // { dg-error ".E0532." "" { target *-*-* } } + } + match xe1 { + XEmpty1() => () // { dg-error ".E0532." "" { target *-*-* } } + } + match e1 { + Empty1(..) => () // { dg-error ".E0532." "" { target *-*-* } } + } + match xe1 { + XEmpty1(..) => () // { dg-error ".E0532." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-pat-3.rs b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-pat-3.rs new file mode 100644 index 000000000000..89143647551f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-braces-pat-3.rs @@ -0,0 +1,33 @@ +// Can't use empty braced struct as enum pattern + +// aux-build:empty-struct.rs + +extern crate empty_struct; +use empty_struct::*; + +enum E { + Empty3 {} +} + +fn main() { + let e3 = E::Empty3 {}; + let xe3 = XE::XEmpty3 {}; + + match e3 { + E::Empty3() => () +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } + match xe3 { + XE::XEmpty3() => () +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } + match e3 { + E::Empty3(..) => () +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } + match xe3 { + XE::XEmpty3(..) => () +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty/empty-struct-tuple-pat.rs b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-tuple-pat.rs new file mode 100644 index 000000000000..effe58f33492 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-tuple-pat.rs @@ -0,0 +1,38 @@ +// Can't use unit struct as enum pattern + +// aux-build:empty-struct.rs + +extern crate empty_struct; +use empty_struct::*; + +struct Empty2(); + +enum E { + Empty4() +} + +// remove attribute after warning cycle and promoting warnings to errors +fn main() { + let e2 = Empty2(); + let e4 = E::Empty4(); + let xe6 = XEmpty6(); + let xe5 = XE::XEmpty5(); + + match e2 { + Empty2 => () // { dg-error ".E0530." "" { target *-*-* } } + } + match xe6 { + XEmpty6 => () // { dg-error ".E0530." "" { target *-*-* } } + } + + match e4 { + E::Empty4 => () +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } + match xe5 { + XE::XEmpty5 => (), +// { dg-error ".E0532." "" { target *-*-* } .-1 } + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty/empty-struct-unit-expr.rs b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-unit-expr.rs new file mode 100644 index 000000000000..5c66fc954205 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-unit-expr.rs @@ -0,0 +1,22 @@ +// Can't use unit struct as constructor function + +// aux-build:empty-struct.rs + +extern crate empty_struct; +use empty_struct::*; + +struct Empty2; + +enum E { + Empty4 +} + +fn main() { + let e2 = Empty2(); // { dg-error ".E0618." "" { target *-*-* } } + let e4 = E::Empty4(); +// { dg-error ".E0618." "" { target *-*-* } .-1 } + let xe2 = XEmpty2(); // { dg-error ".E0618." "" { target *-*-* } } + let xe4 = XE::XEmpty4(); +// { dg-error ".E0618." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty/empty-struct-unit-pat.rs b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-unit-pat.rs new file mode 100644 index 000000000000..1ec3ea9b2d2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty/empty-struct-unit-pat.rs @@ -0,0 +1,55 @@ +// Can't use unit struct as tuple struct pattern + +// aux-build:empty-struct.rs + +extern crate empty_struct; +use empty_struct::*; + +struct Empty2; + +enum E { + Empty4 +} + +fn main() { + let e2 = Empty2; + let e4 = E::Empty4; + let xe2 = XEmpty2; + let xe4 = XE::XEmpty4; + + match e2 { + Empty2() => () // { dg-error ".E0532." "" { target *-*-* } } + } + match xe2 { + XEmpty2() => () +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } + match e2 { + Empty2(..) => () +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } + match xe2 { + XEmpty2(..) => () +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } + + match e4 { + E::Empty4() => () +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } + match xe4 { + XE::XEmpty4() => (), +// { dg-error ".E0532." "" { target *-*-* } .-1 } + _ => {}, + } + match e4 { + E::Empty4(..) => () +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } + match xe4 { + XE::XEmpty4(..) => (), +// { dg-error ".E0532." "" { target *-*-* } .-1 } + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/empty_global_asm.rs b/gcc/testsuite/rust/rustc/ui/empty_global_asm.rs new file mode 100644 index 000000000000..bff07a6cbb4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/empty_global_asm.rs @@ -0,0 +1,21 @@ +// run-pass + +#![feature(global_asm)] + +#[cfg(target_arch = "x86")] +global_asm!(""); + +#[cfg(target_arch = "x86_64")] +global_asm!(""); + +#[cfg(target_arch = "arm")] +global_asm!(""); + +#[cfg(target_arch = "aarch64")] +global_asm!(""); + +#[cfg(target_arch = "mips")] +global_asm!(""); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/enable-unstable-lib-feature.rs b/gcc/testsuite/rust/rustc/ui/enable-unstable-lib-feature.rs new file mode 100644 index 000000000000..2b01faf94b95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enable-unstable-lib-feature.rs @@ -0,0 +1,14 @@ +// Test that enabling an unstable feature disables warnings + +// aux-build:stability-cfg2.rs + +#![feature(unstable_test_feature)] +#![deny(non_snake_case)] // To trigger a hard error + +// Shouldn't generate a warning about unstable features +extern crate stability_cfg2; + +pub fn BOGUS() { } // { dg-error "" "" { target *-*-* } } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/actually_not_an_enum-discriminant.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/actually_not_an_enum-discriminant.rs new file mode 100644 index 000000000000..d3a8ea21711a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/actually_not_an_enum-discriminant.rs @@ -0,0 +1,50 @@ +// run-pass +#![feature(core_intrinsics)] + +use std::intrinsics::discriminant_value; + +struct Zst; + +struct Struct { + _a: u32, +} + +union Union { + _a: u32, +} + +fn check(v: u8) { + assert_eq!(v, 0); +} + +pub fn generic() +where + for<'a> T: Fn(&'a isize), +{ + let v: Vec = Vec::new(); + let _: u8 = discriminant_value(&v); +} + +fn main() { + // check that we use `u8` as the discriminant value + // for everything that is not an enum. + check(discriminant_value(&true)); + check(discriminant_value(&'a')); + check(discriminant_value(&7)); + check(discriminant_value(&7.0)); + check(discriminant_value(&Zst)); + check(discriminant_value(&Struct { _a: 7 })); + check(discriminant_value(&Union { _a: 7 })); + check(discriminant_value(&[7, 77])); + check(discriminant_value(&(7 as *const ()))); + check(discriminant_value(&(7 as *mut ()))); + check(discriminant_value(&&7)); + check(discriminant_value(&&mut 7)); + check(discriminant_value(&check)); + let fn_ptr: fn(u8) = check; + check(discriminant_value(&fn_ptr)); + let hrtb: for<'a> fn(&'a str) -> &'a str = |x| x; + check(discriminant_value(&hrtb)); + check(discriminant_value(&(7, 77, 777))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs new file mode 100644 index 000000000000..355cfdb5a7a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs @@ -0,0 +1,10 @@ +#![crate_type="lib"] +#![feature(arbitrary_enum_discriminant)] + +enum Enum { +// { dg-error ".E0732." "" { target *-*-* } .-1 } + Unit = 1, + Tuple() = 2, + Struct{} = 3, +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/arbitrary_enum_discriminant.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/arbitrary_enum_discriminant.rs new file mode 100644 index 000000000000..6326077496cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/arbitrary_enum_discriminant.rs @@ -0,0 +1,57 @@ +// run-pass +#![feature(arbitrary_enum_discriminant, const_raw_ptr_deref, test)] + +extern crate test; + +use test::black_box; + +#[allow(dead_code)] +#[repr(u8)] +enum Enum { + Unit = 3, + Tuple(u16) = 2, + Struct { + a: u8, + b: u16, + } = 1, +} + +impl Enum { + const unsafe fn tag(&self) -> u8 { + *(self as *const Self as *const u8) + } +} + +#[allow(dead_code)] +#[repr(u8)] +enum FieldlessEnum { + Unit = 3, + Tuple() = 2, + Struct {} = 1, +} + +fn main() { + const UNIT: Enum = Enum::Unit; + const TUPLE: Enum = Enum::Tuple(5); + const STRUCT: Enum = Enum::Struct{a: 7, b: 11}; + + // Ensure discriminants are correct during runtime execution + assert_eq!(3, unsafe { black_box(UNIT).tag() }); + assert_eq!(2, unsafe { black_box(TUPLE).tag() }); + assert_eq!(1, unsafe { black_box(STRUCT).tag() }); + + // Ensure discriminants are correct during CTFE + const UNIT_TAG: u8 = unsafe { UNIT.tag() }; + const TUPLE_TAG: u8 = unsafe { TUPLE.tag() }; + const STRUCT_TAG: u8 = unsafe { STRUCT.tag() }; + + assert_eq!(3, UNIT_TAG); + assert_eq!(2, TUPLE_TAG); + assert_eq!(1, STRUCT_TAG); + + // Ensure `as` conversions are correct + assert_eq!(3, FieldlessEnum::Unit as u8); + assert_eq!(2, FieldlessEnum::Tuple() as u8); + assert_eq!(1, FieldlessEnum::Struct{} as u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/discriminant_size.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/discriminant_size.rs new file mode 100644 index 000000000000..2ab0ee33010e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/discriminant_size.rs @@ -0,0 +1,55 @@ +// run-pass +#![feature(core_intrinsics, repr128)] +// { dg-warning "" "" { target *-*-* } .-1 } + +use std::intrinsics::discriminant_value; + +enum E1 { + A, + B, +} + +#[repr(i8)] +enum E2 { + A = 7, + B = -2, +} + +#[repr(C)] +enum E3 { + A = 42, + B = 100, +} + +#[repr(i128)] +enum E4 { + A = 0x1223_3445_5667_7889, + B = -0x1223_3445_5667_7889, +} + +fn main() { + let mut target: [isize; 3] = [0, 0, 0]; + target[1] = discriminant_value(&E1::A); + assert_eq!(target, [0, 0, 0]); + target[1] = discriminant_value(&E1::B); + assert_eq!(target, [0, 1, 0]); + + let mut target: [i8; 3] = [0, 0, 0]; + target[1] = discriminant_value(&E2::A); + assert_eq!(target, [0, 7, 0]); + target[1] = discriminant_value(&E2::B); + assert_eq!(target, [0, -2, 0]); + + let mut target: [isize; 3] = [0, 0, 0]; + target[1] = discriminant_value(&E3::A); + assert_eq!(target, [0, 42, 0]); + target[1] = discriminant_value(&E3::B); + assert_eq!(target, [0, 100, 0]); + + let mut target: [i128; 3] = [0, 0, 0]; + target[1] = discriminant_value(&E4::A); + assert_eq!(target, [0, 0x1223_3445_5667_7889, 0]); + target[1] = discriminant_value(&E4::B); + assert_eq!(target, [0, -0x1223_3445_5667_7889, 0]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/discriminant_value-wrapper.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/discriminant_value-wrapper.rs new file mode 100644 index 000000000000..7c2ca6ab7be7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/discriminant_value-wrapper.rs @@ -0,0 +1,17 @@ +// run-pass +use std::mem; + +enum ADT { + First(u32, u32), + Second(u64) +} + +pub fn main() { + assert!(mem::discriminant(&ADT::First(0,0)) == mem::discriminant(&ADT::First(1,1))); + assert!(mem::discriminant(&ADT::Second(5)) == mem::discriminant(&ADT::Second(6))); + assert!(mem::discriminant(&ADT::First(2,2)) != mem::discriminant(&ADT::Second(2))); + + let _ = mem::discriminant(&10); + let _ = mem::discriminant(&"test"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/discriminant_value.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/discriminant_value.rs new file mode 100644 index 000000000000..7a8a1db90852 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/discriminant_value.rs @@ -0,0 +1,82 @@ +// run-pass +#![allow(stable_features)] +#![feature(arbitrary_enum_discriminant, core, core_intrinsics)] + +extern crate core; +use core::intrinsics::discriminant_value; + +enum CLike1 { + A, + B, + C, + D +} + +enum CLike2 { + A = 5, + B = 2, + C = 19, + D +} + +#[repr(i8)] +enum CLike3 { + A = 5, + B, + C = -1, + D +} + +enum ADT { + First(u32, u32), + Second(u64) +} + +enum NullablePointer { + Something(&'static u32), + Nothing +} + +static CONST : u32 = 0xBEEF; + +#[allow(dead_code)] +#[repr(isize)] +enum Mixed { + Unit = 3, + Tuple(u16) = 2, + Struct { + a: u8, + b: u16, + } = 1, +} + +pub fn main() { + assert_eq!(discriminant_value(&CLike1::A), 0isize); + assert_eq!(discriminant_value(&CLike1::B), 1); + assert_eq!(discriminant_value(&CLike1::C), 2); + assert_eq!(discriminant_value(&CLike1::D), 3); + + assert_eq!(discriminant_value(&CLike2::A), 5isize); + assert_eq!(discriminant_value(&CLike2::B), 2); + assert_eq!(discriminant_value(&CLike2::C), 19); + assert_eq!(discriminant_value(&CLike2::D), 20); + + assert_eq!(discriminant_value(&CLike3::A), 5i8); + assert_eq!(discriminant_value(&CLike3::B), 6); + assert_eq!(discriminant_value(&CLike3::C), -1); + assert_eq!(discriminant_value(&CLike3::D), 0); + + assert_eq!(discriminant_value(&ADT::First(0,0)), 0isize); + assert_eq!(discriminant_value(&ADT::Second(5)), 1); + + assert_eq!(discriminant_value(&NullablePointer::Nothing), 1isize); + assert_eq!(discriminant_value(&NullablePointer::Something(&CONST)), 0); + + assert_eq!(discriminant_value(&10), 0u8); + assert_eq!(discriminant_value(&"test"), 0u8); + + assert_eq!(discriminant_value(&Mixed::Unit), 3isize); + assert_eq!(discriminant_value(&Mixed::Tuple(5)), 2); + assert_eq!(discriminant_value(&Mixed::Struct{a: 7, b: 11}), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.rs new file mode 100644 index 000000000000..778f06927464 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/feature-gate-arbitrary_enum_discriminant.rs @@ -0,0 +1,11 @@ +#![crate_type="lib"] + +enum Enum { + Unit = 1, +// { dg-error ".E0658." "" { target *-*-* } .-1 } + Tuple() = 2, +// { dg-error ".E0658." "" { target *-*-* } .-1 } + Struct{} = 3, +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/forbidden-discriminant-kind-impl.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/forbidden-discriminant-kind-impl.rs new file mode 100644 index 000000000000..9953fecc0bde --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/forbidden-discriminant-kind-impl.rs @@ -0,0 +1,15 @@ +#![feature(discriminant_kind)] + +use std::marker::DiscriminantKind; + +enum Uninhabited {} + +struct NewType; + +impl DiscriminantKind for NewType { +// { dg-error ".E0322." "" { target *-*-* } .-1 } + type Discriminant = Uninhabited; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs new file mode 100644 index 000000000000..df2ac3ffca91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70453-generics-in-discr-ice-2.rs @@ -0,0 +1,17 @@ +#![feature(arbitrary_enum_discriminant, core_intrinsics)] + +extern crate core; +use core::intrinsics::discriminant_value; + +#[repr(usize)] +enum MyWeirdOption { + None = 0, + Some(T) = std::mem::size_of::(), +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + assert_eq!(discriminant_value(&MyWeirdOption::::None), 0); + assert_eq!(discriminant_value(&MyWeirdOption::Some(0u8)), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs new file mode 100644 index 000000000000..b2cde8e03ee9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70453-generics-in-discr-ice.rs @@ -0,0 +1,18 @@ +#![feature(core_intrinsics)] + +extern crate core; +use core::intrinsics::discriminant_value; + +#[repr(usize)] +enum MyWeirdOption { +// { dg-error ".E0392." "" { target *-*-* } .-1 } + None = 0, + Some = std::mem::size_of::(), +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + assert_eq!(discriminant_value(&MyWeirdOption::::None), 0); + assert_eq!(discriminant_value(&MyWeirdOption::::Some), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs new file mode 100644 index 000000000000..c813d6eda82a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs @@ -0,0 +1,19 @@ +// run-pass +#![feature(arbitrary_enum_discriminant, core_intrinsics)] + +extern crate core; +use core::intrinsics::discriminant_value; + +#[repr(usize)] +enum MyWeirdOption { + None = 0, + Some(T) = core::mem::size_of::<*mut T>(), +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() { + assert_eq!(discriminant_value(&MyWeirdOption::<()>::None), 0); + assert_eq!(discriminant_value(&MyWeirdOption::Some(())), core::mem::size_of::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70509-partial_eq.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70509-partial_eq.rs new file mode 100644 index 000000000000..d0f033789db7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/issue-70509-partial_eq.rs @@ -0,0 +1,19 @@ +// run-pass +#![feature(repr128, arbitrary_enum_discriminant)] +// { dg-warning "" "" { target *-*-* } .-1 } + +#[derive(PartialEq, Debug)] +#[repr(i128)] +enum Test { + A(Box) = 0, + B(usize) = u64::MAX as i128 + 1, +} + +fn main() { + assert_ne!(Test::A(Box::new(2)), Test::B(0)); + // This previously caused a segfault. + // + // See https://github.com/rust-lang/rust/issues/70509#issuecomment-620654186 + // for a detailed explanation. +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/niche.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/niche.rs new file mode 100644 index 000000000000..ff304c59a868 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/niche.rs @@ -0,0 +1,112 @@ +// run-pass + +#![feature(const_panic)] + +//! Make sure that we read and write enum discriminants correctly for corner cases caused +//! by layout optimizations. + +const OVERFLOW: usize = { + // Tests for https://github.com/rust-lang/rust/issues/62138. + #[repr(u8)] + #[allow(dead_code)] + enum WithWraparoundInvalidValues { + X = 1, + Y = 254, + } + + #[allow(dead_code)] + enum Foo { + A, + B, + C(WithWraparoundInvalidValues), + } + + let x = Foo::B; + match x { + Foo::B => 0, + _ => panic!(), + } +}; + +const MORE_OVERFLOW: usize = { + pub enum Infallible {} + + // The check that the `bool` field of `V1` is encoding a "niche variant" + // (i.e. not `V1`, so `V3` or `V4`) used to be mathematically incorrect, + // causing valid `V1` values to be interpreted as other variants. + #[allow(dead_code)] + pub enum E1 { + V1 { f: bool }, + V2 { f: Infallible }, + V3, + V4, + } + + // Computing the discriminant used to be done using the niche type (here `u8`, + // from the `bool` field of `V1`), overflowing for variants with large enough + // indices (`V3` and `V4`), causing them to be interpreted as other variants. + #[allow(dead_code)] + pub enum E2 { + V1 { f: bool }, + + /*_00*/ _01(X), _02(X), _03(X), _04(X), _05(X), _06(X), _07(X), + _08(X), _09(X), _0A(X), _0B(X), _0C(X), _0D(X), _0E(X), _0F(X), + _10(X), _11(X), _12(X), _13(X), _14(X), _15(X), _16(X), _17(X), + _18(X), _19(X), _1A(X), _1B(X), _1C(X), _1D(X), _1E(X), _1F(X), + _20(X), _21(X), _22(X), _23(X), _24(X), _25(X), _26(X), _27(X), + _28(X), _29(X), _2A(X), _2B(X), _2C(X), _2D(X), _2E(X), _2F(X), + _30(X), _31(X), _32(X), _33(X), _34(X), _35(X), _36(X), _37(X), + _38(X), _39(X), _3A(X), _3B(X), _3C(X), _3D(X), _3E(X), _3F(X), + _40(X), _41(X), _42(X), _43(X), _44(X), _45(X), _46(X), _47(X), + _48(X), _49(X), _4A(X), _4B(X), _4C(X), _4D(X), _4E(X), _4F(X), + _50(X), _51(X), _52(X), _53(X), _54(X), _55(X), _56(X), _57(X), + _58(X), _59(X), _5A(X), _5B(X), _5C(X), _5D(X), _5E(X), _5F(X), + _60(X), _61(X), _62(X), _63(X), _64(X), _65(X), _66(X), _67(X), + _68(X), _69(X), _6A(X), _6B(X), _6C(X), _6D(X), _6E(X), _6F(X), + _70(X), _71(X), _72(X), _73(X), _74(X), _75(X), _76(X), _77(X), + _78(X), _79(X), _7A(X), _7B(X), _7C(X), _7D(X), _7E(X), _7F(X), + _80(X), _81(X), _82(X), _83(X), _84(X), _85(X), _86(X), _87(X), + _88(X), _89(X), _8A(X), _8B(X), _8C(X), _8D(X), _8E(X), _8F(X), + _90(X), _91(X), _92(X), _93(X), _94(X), _95(X), _96(X), _97(X), + _98(X), _99(X), _9A(X), _9B(X), _9C(X), _9D(X), _9E(X), _9F(X), + _A0(X), _A1(X), _A2(X), _A3(X), _A4(X), _A5(X), _A6(X), _A7(X), + _A8(X), _A9(X), _AA(X), _AB(X), _AC(X), _AD(X), _AE(X), _AF(X), + _B0(X), _B1(X), _B2(X), _B3(X), _B4(X), _B5(X), _B6(X), _B7(X), + _B8(X), _B9(X), _BA(X), _BB(X), _BC(X), _BD(X), _BE(X), _BF(X), + _C0(X), _C1(X), _C2(X), _C3(X), _C4(X), _C5(X), _C6(X), _C7(X), + _C8(X), _C9(X), _CA(X), _CB(X), _CC(X), _CD(X), _CE(X), _CF(X), + _D0(X), _D1(X), _D2(X), _D3(X), _D4(X), _D5(X), _D6(X), _D7(X), + _D8(X), _D9(X), _DA(X), _DB(X), _DC(X), _DD(X), _DE(X), _DF(X), + _E0(X), _E1(X), _E2(X), _E3(X), _E4(X), _E5(X), _E6(X), _E7(X), + _E8(X), _E9(X), _EA(X), _EB(X), _EC(X), _ED(X), _EE(X), _EF(X), + _F0(X), _F1(X), _F2(X), _F3(X), _F4(X), _F5(X), _F6(X), _F7(X), + _F8(X), _F9(X), _FA(X), _FB(X), _FC(X), _FD(X), _FE(X), _FF(X), + + V3, + V4, + } + + if let E1::V2 { .. } = (E1::V1 { f: true }) { + unreachable!() + } + if let E1::V1 { .. } = (E1::V1 { f: true }) { + } else { + unreachable!() + } + + if let E2::V1 { .. } = E2::V3:: { + unreachable!() + } + if let E2::V3 { .. } = E2::V3:: { + } else { + unreachable!() + } + + 0 +}; + +fn main() { + assert_eq!(OVERFLOW, 0); + assert_eq!(MORE_OVERFLOW, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum-discriminant/repr128.rs b/gcc/testsuite/rust/rustc/ui/enum-discriminant/repr128.rs new file mode 100644 index 000000000000..c9d27508e8ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum-discriminant/repr128.rs @@ -0,0 +1,46 @@ +// run-pass +#![feature(repr128, core_intrinsics, discriminant_kind)] +// { dg-warning "" "" { target *-*-* } .-1 } + +use std::intrinsics::discriminant_value; +use std::marker::DiscriminantKind; + +#[repr(i128)] +enum Signed { + Zero = 0, + Staircase = 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f, + U64Limit = u64::MAX as i128 + 1, + SmallNegative = -1, + BigNegative = i128::MIN, + Next, +} + +#[repr(u128)] +enum Unsigned { + Zero = 0, + Staircase = 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f, + U64Limit = u64::MAX as u128 + 1, + Next, +} + +fn discr(v: T, value: U) +where + ::Discriminant: PartialEq, +{ + assert!(discriminant_value(&v) == value); +} + +fn main() { + discr(Signed::Zero, 0); + discr(Signed::Staircase, 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f); + discr(Signed::U64Limit, u64::MAX as i128 + 1); + discr(Signed::SmallNegative, -1); + discr(Signed::BigNegative, i128::MIN); + discr(Signed::Next, i128::MIN + 1); + + discr(Unsigned::Zero, 0); + discr(Unsigned::Staircase, 0x01_02_03_04_05_06_07_08_09_0a_0b_0c_0d_0e_0f); + discr(Unsigned::U64Limit, u64::MAX as u128 + 1); + discr(Unsigned::Next, u64::MAX as u128 + 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum/enum-and-module-in-same-scope.rs b/gcc/testsuite/rust/rustc/ui/enum/enum-and-module-in-same-scope.rs new file mode 100644 index 000000000000..ba4456e68db8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/enum-and-module-in-same-scope.rs @@ -0,0 +1,11 @@ +enum Foo { + X +} + +mod Foo { // { dg-error ".E0428." "" { target *-*-* } } + pub static X: isize = 42; + fn f() { f() } // Check that this does not result in a resolution error +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/enum/enum-discrim-autosizing.rs b/gcc/testsuite/rust/rustc/ui/enum/enum-discrim-autosizing.rs new file mode 100644 index 000000000000..04a06c07f070 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/enum-discrim-autosizing.rs @@ -0,0 +1,12 @@ +// With no repr attribute the discriminant will default to isize. +// On 32-bit architectures this is equivalent to i32 so the variants +// collide. On other architectures we need compilation to fail anyway, +// so force the repr. +#[cfg_attr(not(target_pointer_width = "32"), repr(i32))] +enum Eu64 { + Au64 = 0, + Bu64 = 0x8000_0000_0000_0000 // { dg-error ".E0081." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/enum/enum-discrim-too-small.rs b/gcc/testsuite/rust/rustc/ui/enum/enum-discrim-too-small.rs new file mode 100644 index 000000000000..9b433ce0aca7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/enum-discrim-too-small.rs @@ -0,0 +1,39 @@ +#[repr(u8)] +enum Eu8 { + Au8 = 23, + Bu8 = 223, + Cu8 = -23, +// { dg-error ".E0600." "" { target *-*-* } .-1 } +} + +#[repr(u16)] +enum Eu16 { + Au16 = 23, + Bu16 = 55555, + Cu16 = -22333, +// { dg-error ".E0600." "" { target *-*-* } .-1 } +} + +#[repr(u32)] +enum Eu32 { + Au32 = 23, + Bu32 = 3_000_000_000, + Cu32 = -2_000_000_000, +// { dg-error ".E0600." "" { target *-*-* } .-1 } +} + +#[repr(u64)] +enum Eu64 { + Au32 = 23, + Bu32 = 3_000_000_000, + Cu32 = -2_000_000_000, +// { dg-error ".E0600." "" { target *-*-* } .-1 } +} + +// u64 currently allows negative numbers, and i64 allows numbers greater than `1<<63`. This is a +// little counterintuitive, but since the discriminant can store all the bits, and extracting it +// with a cast requires specifying the signedness, there is no loss of information in those cases. +// This also applies to isize and usize on 64-bit targets. + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/enum/enum-discrim-too-small2.rs b/gcc/testsuite/rust/rustc/ui/enum/enum-discrim-too-small2.rs new file mode 100644 index 000000000000..15592436b2d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/enum-discrim-too-small2.rs @@ -0,0 +1,38 @@ +#![deny(overflowing_literals)] +#![allow(dead_code)] + +#[repr(i8)] +enum Ei8 { + Ai8 = 23, + Bi8 = -23, + Ci8 = 223, // { dg-error "" "" { target *-*-* } } +} + +#[repr(i16)] +enum Ei16 { + Ai16 = 23, + Bi16 = -22333, + Ci16 = 55555, // { dg-error "" "" { target *-*-* } } +} + +#[repr(i32)] +enum Ei32 { + Ai32 = 23, + Bi32 = -2_000_000_000, + Ci32 = 3_000_000_000, // { dg-error "" "" { target *-*-* } } +} + +#[repr(i64)] +enum Ei64 { + Ai64 = 23, + Bi64 = -9223372036854775808, + Ci64 = 9223372036854775809, // { dg-error "" "" { target *-*-* } } +} + +// u64 currently allows negative numbers, and i64 allows numbers greater than `1<<63`. This is a +// little counterintuitive, but since the discriminant can store all the bits, and extracting it +// with a cast requires specifying the signedness, there is no loss of information in those cases. +// This also applies to isize and usize on 64-bit targets. + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/enum/enum-in-scope.rs b/gcc/testsuite/rust/rustc/ui/enum/enum-in-scope.rs new file mode 100644 index 000000000000..f9107e7f3863 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/enum-in-scope.rs @@ -0,0 +1,8 @@ +#![allow(non_camel_case_types)] + +struct hello(isize); + +fn main() { + let hello = 0; // { dg-error ".E0530." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum/enum-size-variance.rs b/gcc/testsuite/rust/rustc/ui/enum/enum-size-variance.rs new file mode 100644 index 000000000000..fc15a5ec9c7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/enum-size-variance.rs @@ -0,0 +1,36 @@ +// run-pass + +#![warn(variant_size_differences)] +#![allow(dead_code)] + +// Note that the following test works because all fields of the enum variants are of the same size. +// If this test is modified and the reordering logic in librustc/ty/layout.rs kicks in, it fails. + +enum Enum1 { } + +enum Enum2 { A, B, C } + +enum Enum3 { D(i64), E, F } + +enum Enum4 { H(i64), I(i64), J } + +enum Enum5 { + L(i64, i64, i64, i64), // { dg-warning "" "" { target *-*-* } } + M(i64), + N +} + +enum Enum6 { + O(T), + P(U), + Q(i64) +} + +#[allow(variant_size_differences)] +enum Enum7 { + R(i64, i64, i64, i64), + S(i64), + T +} +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/enum/enum-to-float-cast-2.rs b/gcc/testsuite/rust/rustc/ui/enum/enum-to-float-cast-2.rs new file mode 100644 index 000000000000..33ac6c7511d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/enum-to-float-cast-2.rs @@ -0,0 +1,19 @@ +// Tests that enum-to-float casts are disallowed. + +enum E { + L0 = -1, + H0 = 1 +} + +enum F { + L1 = 1, + H1 = 0xFFFFFFFFFFFFFFFF +} + +pub fn main() { + let a = E::L0 as f32; // { dg-error ".E0606." "" { target *-*-* } } + let c = F::H1 as f32; // { dg-error ".E0606." "" { target *-*-* } } + assert_eq!(a, -1.0f32); + assert_eq!(c, -1.0f32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum/enum-to-float-cast.rs b/gcc/testsuite/rust/rustc/ui/enum/enum-to-float-cast.rs new file mode 100644 index 000000000000..9bedbdd46b51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/enum-to-float-cast.rs @@ -0,0 +1,22 @@ +// Tests that enum-to-float casts are disallowed. + +enum E { + L0 = -1, + H0 = 1 +} + +enum F { + L1 = 1, + H1 = 0xFFFFFFFFFFFFFFFF +} + +static C0: f32 = E::L0 as f32; // { dg-error ".E0606." "" { target *-*-* } } +static C1: f32 = F::H1 as f32; // { dg-error ".E0606." "" { target *-*-* } } + +pub fn main() { + let b = C0; + let d = C1; + assert_eq!(b, -1.0f32); + assert_eq!(d, -1.0f32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/enum/enum-variant-type-2.rs b/gcc/testsuite/rust/rustc/ui/enum/enum-variant-type-2.rs new file mode 100644 index 000000000000..9cc6f73f2f54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/enum-variant-type-2.rs @@ -0,0 +1,10 @@ +// Test that enum variants are not actually types. + +enum Foo { + Bar +} + +fn foo(x: Foo::Bar) {} // { dg-error ".E0573." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/enum/issue-67945-1.rs b/gcc/testsuite/rust/rustc/ui/enum/issue-67945-1.rs new file mode 100644 index 000000000000..41141b7b67ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/issue-67945-1.rs @@ -0,0 +1,9 @@ +enum Bug { + Var = { + let x: S = 0; // { dg-error ".E0308." "" { target *-*-* } } + 0 + }, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/enum/issue-67945-2.rs b/gcc/testsuite/rust/rustc/ui/enum/issue-67945-2.rs new file mode 100644 index 000000000000..b2a80262aab1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/issue-67945-2.rs @@ -0,0 +1,10 @@ +#![feature(type_ascription)] + +enum Bug { + Var = 0: S, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/enum/nested-enum.rs b/gcc/testsuite/rust/rustc/ui/enum/nested-enum.rs new file mode 100644 index 000000000000..7eb561bb832d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/nested-enum.rs @@ -0,0 +1,9 @@ +enum Foo { + enum Bar { Baz }, // { dg-error "" "" { target *-*-* } } + struct Quux { field: u8 }, // { dg-error "" "" { target *-*-* } } + union Wibble { field: u8 }, // { dg-error "" "" { target *-*-* } } + Bat, +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/enum/union-in-enum.rs b/gcc/testsuite/rust/rustc/ui/enum/union-in-enum.rs new file mode 100644 index 000000000000..3c03398247c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enum/union-in-enum.rs @@ -0,0 +1,14 @@ +// This test checks that the union keyword +// is accepted as the name of an enum variant +// when not followed by an identifier +// This special case exists because `union` is a contextual keyword. + +#![allow(warnings)] + +// check-pass + +enum A { union } +enum B { union {} } +enum C { union() } +fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/enums-pats-not-idents.rs b/gcc/testsuite/rust/rustc/ui/enums-pats-not-idents.rs new file mode 100644 index 000000000000..f3de434f9ab3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/enums-pats-not-idents.rs @@ -0,0 +1,4 @@ +fn main() { + let a(1) = 13; // { dg-error ".E0531." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/env-args-reverse-iterator.rs b/gcc/testsuite/rust/rustc/ui/env-args-reverse-iterator.rs new file mode 100644 index 000000000000..7bb7d59cb856 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/env-args-reverse-iterator.rs @@ -0,0 +1,40 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::env::args; +use std::process::Command; + +fn assert_reverse_iterator_for_program_arguments(program_name: &str) { + let args: Vec<_> = args().rev().collect(); + + assert!(args.len() == 4); + assert_eq!(args[0], "c"); + assert_eq!(args[1], "b"); + assert_eq!(args[2], "a"); + assert_eq!(args[3], program_name); + + println!("passed"); +} + +fn main() { + let mut args = args(); + let me = args.next().unwrap(); + + if let Some(_) = args.next() { + assert_reverse_iterator_for_program_arguments(&me); + return + } + + let output = Command::new(&me) + .arg("a") + .arg("b") + .arg("c") + .output() + .unwrap(); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(output.stdout, b"passed\n"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/env-funky-keys.rs b/gcc/testsuite/rust/rustc/ui/env-funky-keys.rs new file mode 100644 index 000000000000..c12901069dd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/env-funky-keys.rs @@ -0,0 +1,44 @@ +// run-pass +// Ignore this test on Android, because it segfaults there. + +// ignore-android +// ignore-windows +// ignore-cloudabi no execve +// ignore-emscripten no execve +// ignore-sgx no execve +// ignore-vxworks no execve +// no-prefer-dynamic + +#![feature(rustc_private)] + +extern crate libc; + +use libc::c_char; +use libc::execve; +use std::env; +use std::ffi::CString; +use std::os::unix::prelude::*; +use std::ptr; + +fn main() { + if env::args_os().count() == 2 { + for (key, value) in env::vars_os() { + panic!("found env value {:?} {:?}", key, value); + } + return; + } + + let current_exe = CString::new(env::current_exe() + .unwrap() + .as_os_str() + .as_bytes()).unwrap(); + let new_env_var = CString::new("FOOBAR").unwrap(); + let filename: *const c_char = current_exe.as_ptr(); + let argv: &[*const c_char] = &[filename, filename, ptr::null()]; + let envp: &[*const c_char] = &[new_env_var.as_ptr(), ptr::null()]; + unsafe { + execve(filename, &argv[0], &envp[0]); + } + panic!("execve failed"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/env-home-dir.rs b/gcc/testsuite/rust/rustc/ui/env-home-dir.rs new file mode 100644 index 000000000000..a2c380d65e64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/env-home-dir.rs @@ -0,0 +1,52 @@ +// run-pass + +#![allow(unused_variables)] +#![allow(deprecated)] +// ignore-cloudabi no environment variables present +// ignore-emscripten env vars don't work? +// ignore-sgx env vars cannot be modified + +use std::env::*; +use std::path::PathBuf; + +#[cfg(unix)] +fn main() { + let oldhome = var("HOME"); + + set_var("HOME", "/home/MountainView"); + assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); + + remove_var("HOME"); + if cfg!(target_os = "android") { + assert!(home_dir().is_none()); + } else { + // When HOME is not set, some platforms return `None`, + // but others return `Some` with a default. + // Just check that it is not "/home/MountainView". + assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView"))); + } +} + +#[cfg(windows)] +fn main() { + let oldhome = var("HOME"); + let olduserprofile = var("USERPROFILE"); + + remove_var("HOME"); + remove_var("USERPROFILE"); + + assert!(home_dir().is_some()); + + set_var("HOME", "/home/MountainView"); + assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); + + remove_var("HOME"); + + set_var("USERPROFILE", "/home/MountainView"); + assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); + + set_var("HOME", "/home/MountainView"); + set_var("USERPROFILE", "/home/PaloAlto"); + assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView"))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/env-null-vars.rs b/gcc/testsuite/rust/rustc/ui/env-null-vars.rs new file mode 100644 index 000000000000..6af8e4a1e06e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/env-null-vars.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(unused_imports)] + +// ignore-windows +// ignore-wasm32-bare no libc to test ffi with + +// issue-53200 + +#![feature(rustc_private)] +extern crate libc; + +use std::env; + +// FIXME: more platforms? +#[cfg(target_os = "linux")] +fn main() { + unsafe { libc::clearenv(); } + assert_eq!(env::vars().count(), 0); +} + +#[cfg(not(target_os = "linux"))] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/env-vars.rs b/gcc/testsuite/rust/rustc/ui/env-vars.rs new file mode 100644 index 000000000000..5e640dc2f573 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/env-vars.rs @@ -0,0 +1,14 @@ +// run-pass +// ignore-cloudabi no env vars +// ignore-wasm32-bare no env vars + +use std::env::*; + +fn main() { + for (k, v) in vars_os() { + let v2 = var_os(&k); + assert!(v2.as_ref().map(|s| &**s) == Some(&*v), + "bad vars->var transition: {:?} {:?} {:?}", k, v, v2); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/epoch-gate-feature.rs b/gcc/testsuite/rust/rustc/ui/epoch-gate-feature.rs new file mode 100644 index 000000000000..cc712be2bddb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/epoch-gate-feature.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_variables)] +// Checks if the correct registers are being used to pass arguments +// when the sysv64 ABI is specified. + +#![feature(rust_2018_preview)] + +pub trait Foo {} + +// should compile without the dyn trait feature flag +fn foo(x: &dyn Foo) {} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/eprint-on-tls-drop.rs b/gcc/testsuite/rust/rustc/ui/eprint-on-tls-drop.rs new file mode 100644 index 000000000000..00060678a24d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/eprint-on-tls-drop.rs @@ -0,0 +1,50 @@ +// run-pass +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::cell::RefCell; +use std::env; +use std::process::Command; + +fn main() { + let name = "YOU_ARE_THE_TEST"; + if env::var(name).is_ok() { + std::thread::spawn(|| { + TLS.with(|f| f.borrow().ensure()); + }) + .join() + .unwrap(); + } else { + let me = env::current_exe().unwrap(); + let output = Command::new(&me).env(name, "1").output().unwrap(); + println!("{:?}", output); + assert!(output.status.success()); + let stderr = String::from_utf8(output.stderr).unwrap(); + assert!(stderr.contains("hello new\n")); + assert!(stderr.contains("hello drop\n")); + } +} + +struct Stuff { + _x: usize, +} + +impl Stuff { + fn new() -> Self { + eprintln!("hello new"); + Self { _x: 0 } + } + + fn ensure(&self) {} +} + +impl Drop for Stuff { + fn drop(&mut self) { + eprintln!("hello drop"); + } +} + +thread_local! { + static TLS: RefCell = RefCell::new(Stuff::new()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/eq-multidispatch.rs b/gcc/testsuite/rust/rustc/ui/eq-multidispatch.rs new file mode 100644 index 000000000000..5cf9a72790f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/eq-multidispatch.rs @@ -0,0 +1,31 @@ +// run-pass + +#[derive(PartialEq, Debug)] +struct Bar; +#[derive(Debug)] +struct Baz; +#[derive(Debug)] +struct Foo; +#[derive(Debug)] +struct Fu; + +impl PartialEq for Baz { fn eq(&self, _: &Baz) -> bool { true } } + +impl PartialEq for Foo { fn eq(&self, _: &Fu) -> bool { true } } +impl PartialEq for Fu { fn eq(&self, _: &Foo) -> bool { true } } + +impl PartialEq for Foo { fn eq(&self, _: &Bar) -> bool { false } } +impl PartialEq for Bar { fn eq(&self, _: &Foo) -> bool { false } } + +fn main() { + assert!(Bar != Foo); + assert!(Foo != Bar); + + assert_eq!(Bar, Bar); + + assert_eq!(Baz, Baz); + + assert_eq!(Foo, Fu); + assert_eq!(Fu, Foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0001.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0001.rs new file mode 100644 index 000000000000..bd1a6cd2b556 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0001.rs @@ -0,0 +1,11 @@ +#![deny(unreachable_patterns)] + +fn main() { + let foo = Some(1); + match foo { + Some(_) => {/* ... */} + None => {/* ... */} + _ => {/* ... */} // { dg-error "" "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0004-2.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0004-2.rs new file mode 100644 index 000000000000..7696e1851ef9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0004-2.rs @@ -0,0 +1,6 @@ +fn main() { + let x = Some(1); + + match x { } // { dg-error ".E0004." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0004.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0004.rs new file mode 100644 index 000000000000..2be8e95f45bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0004.rs @@ -0,0 +1,13 @@ +enum Terminator { + HastaLaVistaBaby, + TalkToMyHand, +} + +fn main() { + let x = Terminator::HastaLaVistaBaby; + + match x { // { dg-error ".E0004." "" { target *-*-* } } + Terminator::TalkToMyHand => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0005.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0005.rs new file mode 100644 index 000000000000..f192518cc658 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0005.rs @@ -0,0 +1,5 @@ +fn main() { + let x = Some(1); + let Some(y) = x; // { dg-error ".E0005." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0010-teach.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0010-teach.rs new file mode 100644 index 000000000000..f09c2e87ccaf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0010-teach.rs @@ -0,0 +1,9 @@ +// compile-flags: -Z teach + +#![feature(box_syntax)] +#![allow(warnings)] + +const CON : Box = box 0; // { dg-error ".E0010." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0010.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0010.rs new file mode 100644 index 000000000000..d278430d30e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0010.rs @@ -0,0 +1,7 @@ +#![feature(box_syntax)] +#![allow(warnings)] + +const CON : Box = box 0; // { dg-error ".E0010." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0017.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0017.rs new file mode 100644 index 000000000000..364d92b68a14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0017.rs @@ -0,0 +1,14 @@ +static X: i32 = 1; +const C: i32 = 2; +static mut M: i32 = 3; + +const CR: &'static mut i32 = &mut C; // { dg-error ".E0764." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +static STATIC_REF: &'static mut i32 = &mut X; // { dg-error ".E0596." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + +static CONST_REF: &'static mut i32 = &mut C; // { dg-error ".E0764." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; // { dg-error ".E0764." "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0023.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0023.rs new file mode 100644 index 000000000000..2bc618a9b501 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0023.rs @@ -0,0 +1,18 @@ +enum Fruit { + Apple(String, String), + Pear(u32), + Orange((String, String)), + Banana(()), +} + +fn main() { + let x = Fruit::Apple(String::new(), String::new()); + match x { + Fruit::Apple(a) => {}, // { dg-error ".E0023." "" { target *-*-* } } + Fruit::Apple(a, b, c) => {}, // { dg-error ".E0023." "" { target *-*-* } } + Fruit::Pear(1, 2) => {}, // { dg-error ".E0023." "" { target *-*-* } } + Fruit::Orange(a, b) => {}, // { dg-error ".E0023." "" { target *-*-* } } + Fruit::Banana() => {}, // { dg-error ".E0023." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0025.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0025.rs new file mode 100644 index 000000000000..4a06371e1904 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0025.rs @@ -0,0 +1,11 @@ +struct Foo { + a: u8, + b: u8, +} + +fn main() { + let x = Foo { a:1, b:2 }; + let Foo { a: x, a: y, b: 0 } = x; +// { dg-error ".E0025." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0026-teach.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0026-teach.rs new file mode 100644 index 000000000000..d35ac75f70ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0026-teach.rs @@ -0,0 +1,15 @@ +// compile-flags: -Z teach + +struct Thing { + x: u32, + y: u32 +} + +fn main() { + let thing = Thing { x: 0, y: 0 }; + match thing { + Thing { x, y, z } => {} +// { dg-error ".E0026." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0026.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0026.rs new file mode 100644 index 000000000000..bdde202f5a38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0026.rs @@ -0,0 +1,13 @@ +struct Thing { + x: u32, + y: u32 +} + +fn main() { + let thing = Thing { x: 0, y: 0 }; + match thing { + Thing { x, y, z } => {} +// { dg-error ".E0026." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0027.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0027.rs new file mode 100644 index 000000000000..1ad0f5d17eb6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0027.rs @@ -0,0 +1,16 @@ +struct Dog { + name: String, + age: u32, +} + +fn main() { + let d = Dog { name: "Rusty".to_string(), age: 8 }; + + match d { + Dog { age: x } => {} // { dg-error ".E0027." "" { target *-*-* } } + } + match d { + Dog {} => {} // { dg-error ".E0027." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0029-teach.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0029-teach.rs new file mode 100644 index 000000000000..66ae1daa1b30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0029-teach.rs @@ -0,0 +1,12 @@ +// compile-flags: -Z teach + +fn main() { + let s = "hoho"; + + match s { + "hello" ..= "world" => {} +// { dg-error ".E0029." "" { target *-*-* } .-1 } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0029.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0029.rs new file mode 100644 index 000000000000..906ff37c8d0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0029.rs @@ -0,0 +1,10 @@ +fn main() { + let s = "hoho"; + + match s { + "hello" ..= "world" => {} +// { dg-error ".E0029." "" { target *-*-* } .-1 } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0030-teach.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0030-teach.rs new file mode 100644 index 000000000000..95a24656545e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0030-teach.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z teach + +fn main() { + match 5u32 { + 1000 ..= 5 => {} +// { dg-error ".E0030." "" { target *-*-* } .-1 } +// { dg-error ".E0030." "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0030.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0030.rs new file mode 100644 index 000000000000..b0e7cbfd77d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0030.rs @@ -0,0 +1,8 @@ +fn main() { + match 5u32 { + 1000 ..= 5 => {} +// { dg-error ".E0030." "" { target *-*-* } .-1 } +// { dg-error ".E0030." "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0033-teach.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0033-teach.rs new file mode 100644 index 000000000000..2f75077b703b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0033-teach.rs @@ -0,0 +1,15 @@ +// compile-flags: -Z teach + +trait SomeTrait { + fn foo(); // { dg-error "" "" { target *-*-* } } +} + +fn main() { + let trait_obj: &dyn SomeTrait = SomeTrait; +// { dg-error ".E0038." "" { target *-*-* } .-1 } +// { dg-error ".E0038." "" { target *-*-* } .-2 } + + let &invalid = trait_obj; +// { dg-error ".E0033." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0033.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0033.rs new file mode 100644 index 000000000000..f832dff54cdb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0033.rs @@ -0,0 +1,13 @@ +trait SomeTrait { + fn foo(); // { dg-error "" "" { target *-*-* } } +} + +fn main() { + let trait_obj: &dyn SomeTrait = SomeTrait; +// { dg-error ".E0038." "" { target *-*-* } .-1 } +// { dg-error ".E0038." "" { target *-*-* } .-2 } + + let &invalid = trait_obj; +// { dg-error ".E0033." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0034.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0034.rs new file mode 100644 index 000000000000..67bc207054dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0034.rs @@ -0,0 +1,22 @@ +struct Test; + +trait Trait1 { + fn foo(); +} + +trait Trait2 { + fn foo(); +} + +impl Trait1 for Test { + fn foo() {} +} + +impl Trait2 for Test { + fn foo() {} +} + +fn main() { + Test::foo() // { dg-error ".E0034." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0038.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0038.rs new file mode 100644 index 000000000000..2f5a2ca8a801 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0038.rs @@ -0,0 +1,12 @@ +trait Trait { + fn foo(&self) -> Self; +} + +fn call_foo(x: Box) { +// { dg-error ".E0038." "" { target *-*-* } .-1 } + let y = x.foo(); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0040.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0040.rs new file mode 100644 index 000000000000..60cdcea5d7e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0040.rs @@ -0,0 +1,16 @@ +struct Foo { + x: i32, +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("kaboom"); + } +} + +fn main() { + let mut x = Foo { x: -7 }; + x.drop(); +// { dg-error ".E0040." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0044.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0044.rs new file mode 100644 index 000000000000..d76e041452b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0044.rs @@ -0,0 +1,10 @@ +extern { + fn sqrt(f: T) -> T; +// { dg-error ".E0044." "" { target *-*-* } .-1 } +// { help ".E0044." "" { target *-*-* } .-2 } +// { dg-note ".E0044." "" { target *-*-* } .-3 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0045.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0045.rs new file mode 100644 index 000000000000..aa31d3218cf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0045.rs @@ -0,0 +1,5 @@ +extern "Rust" { fn foo(x: u8, ...); } // { dg-error ".E0045." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0049.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0049.rs new file mode 100644 index 000000000000..27d852cd65fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0049.rs @@ -0,0 +1,23 @@ +trait Foo { + fn foo(x: T) -> Self; +} + +struct Bar; + +impl Foo for Bar { + fn foo(x: bool) -> Self { Bar } // { dg-error ".E0049." "" { target *-*-* } } +} + +trait Fuzz { + fn fuzz(x: A, y: B) -> Self; +} + +struct Baz; + +impl Fuzz for Baz { + fn fuzz(x: bool, y: bool) -> Self { Baz } // { dg-error ".E0049." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0050.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0050.rs new file mode 100644 index 000000000000..9edfd56bda20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0050.rs @@ -0,0 +1,17 @@ +trait Foo { + fn foo(&self, x: u8) -> bool; + fn bar(&self, x: u8, y: u8, z: u8); + fn less(&self); +} + +struct Bar; + +impl Foo for Bar { + fn foo(&self) -> bool { true } // { dg-error ".E0050." "" { target *-*-* } } + fn bar(&self) { } // { dg-error ".E0050." "" { target *-*-* } } + fn less(&self, x: u8, y: u8, z: u8) { } // { dg-error ".E0050." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0054.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0054.rs new file mode 100644 index 000000000000..725f813e4c66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0054.rs @@ -0,0 +1,5 @@ +fn main() { + let x = 5; + let x_is_nonzero = x as bool; // { dg-error ".E0054." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0055.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0055.rs new file mode 100644 index 000000000000..fa6a4094f7f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0055.rs @@ -0,0 +1,14 @@ +#![recursion_limit="4"] +struct Foo; + +impl Foo { + fn foo(&self) {} +} + +fn main() { + let foo = Foo; + let ref_foo = &&&&&Foo; + ref_foo.foo(); +// { dg-error ".E0055." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0057.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0057.rs new file mode 100644 index 000000000000..f7e0008bff0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0057.rs @@ -0,0 +1,7 @@ +fn main() { + let f = |x| x * 3; + let a = f(); // { dg-error ".E0057." "" { target *-*-* } } + let b = f(4); + let c = f(2, 3); // { dg-error ".E0057." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0059.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0059.rs new file mode 100644 index 000000000000..d51b0be0f9bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0059.rs @@ -0,0 +1,7 @@ +#![feature(unboxed_closures)] + +fn foo>(f: F) -> F::Output { f(3) } // { dg-error ".E0059." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0060.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0060.rs new file mode 100644 index 000000000000..554495290d0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0060.rs @@ -0,0 +1,10 @@ +extern "C" { + fn printf(_: *const u8, ...) -> u32; +} + +fn main() { + unsafe { printf(); } +// { dg-error ".E0060." "" { target *-*-* } .-1 } +// { dg-error ".E0060." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0061.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0061.rs new file mode 100644 index 000000000000..36c35433f4e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0061.rs @@ -0,0 +1,14 @@ +fn f(a: u16, b: &str) {} + +fn f2(a: u16) {} + +fn main() { + f(0); +// { dg-error ".E0061." "" { target *-*-* } .-1 } +// { dg-error ".E0061." "" { target *-*-* } .-2 } + + f2(); +// { dg-error ".E0061." "" { target *-*-* } .-1 } +// { dg-error ".E0061." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0062.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0062.rs new file mode 100644 index 000000000000..3135fa3a1042 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0062.rs @@ -0,0 +1,12 @@ +struct Foo { + x: i32 +} + +fn main() { + let x = Foo { + x: 0, + x: 0, +// { dg-error ".E0062." "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0063.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0063.rs new file mode 100644 index 000000000000..ab8c18c13693 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0063.rs @@ -0,0 +1,41 @@ +// ignore-tidy-linelength + +struct SingleFoo { + x: i32 +} + +struct PluralFoo { + x: i32, + y: i32, + z: i32 +} + +struct TruncatedFoo { + a: i32, + b: i32, + x: i32, + y: i32, + z: i32 +} + +struct TruncatedPluralFoo { + a: i32, + b: i32, + c: i32, + x: i32, + y: i32, + z: i32 +} + + +fn main() { + let w = SingleFoo { }; +// { dg-error ".E0063." "" { target *-*-* } .-1 } + let x = PluralFoo {x: 1}; +// { dg-error ".E0063." "" { target *-*-* } .-1 } + let y = TruncatedFoo{x:1}; +// { dg-error ".E0063." "" { target *-*-* } .-1 } + let z = TruncatedPluralFoo{x:1}; +// { dg-error ".E0063." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0067.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0067.rs new file mode 100644 index 000000000000..c5b036593cfd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0067.rs @@ -0,0 +1,7 @@ +use std::collections::LinkedList; + +fn main() { + LinkedList::new() += 1; // { dg-error ".E0067." "" { target *-*-* } } +// { dg-error ".E0067." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0069.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0069.rs new file mode 100644 index 000000000000..3386c15b70aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0069.rs @@ -0,0 +1,8 @@ +fn foo() -> u8 { + return; +// { dg-error ".E0069." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0070.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0070.rs new file mode 100644 index 000000000000..09a49f1a392d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0070.rs @@ -0,0 +1,14 @@ +const SOME_CONST : i32 = 12; + +fn some_other_func() {} + +fn some_function() { + SOME_CONST = 14; // { dg-error ".E0070." "" { target *-*-* } } + 1 = 3; // { dg-error ".E0070." "" { target *-*-* } } + some_other_func() = 4; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0071.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0071.rs new file mode 100644 index 000000000000..8eddf817d324 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0071.rs @@ -0,0 +1,8 @@ +enum Foo {} +type FooAlias = Foo; + +fn main() { + let u = FooAlias { value: 0 }; +// { dg-error ".E0071." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0075.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0075.rs new file mode 100644 index 000000000000..b824232e0e60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0075.rs @@ -0,0 +1,8 @@ +#![feature(repr_simd)] + +#[repr(simd)] +struct Bad; // { dg-error ".E0075." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0076.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0076.rs new file mode 100644 index 000000000000..b50c5a16bc5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0076.rs @@ -0,0 +1,9 @@ +#![feature(repr_simd)] + +#[repr(simd)] +struct Bad(u16, u32, u32); +// { dg-error ".E0076." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0077.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0077.rs new file mode 100644 index 000000000000..47ddeef40b36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0077.rs @@ -0,0 +1,8 @@ +#![feature(repr_simd)] + +#[repr(simd)] +struct Bad(String); // { dg-error ".E0077." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0080.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0080.rs new file mode 100644 index 000000000000..ba7f1f7330ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0080.rs @@ -0,0 +1,9 @@ +enum Enum { + X = (1 << 500), // { dg-error ".E0080." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + Y = (1 / 0) // { dg-error ".E0080." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0081.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0081.rs new file mode 100644 index 000000000000..a635ce6874c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0081.rs @@ -0,0 +1,10 @@ +enum Enum { + P = 3, + X = 3, +// { dg-error ".E0081." "" { target *-*-* } .-1 } + Y = 5 +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0084.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0084.rs new file mode 100644 index 000000000000..5f1b7463ed1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0084.rs @@ -0,0 +1,6 @@ +#[repr(i32)] // { dg-error ".E0084." "" { target *-*-* } } +enum Foo {} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0091.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0091.rs new file mode 100644 index 000000000000..acc7862255d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0091.rs @@ -0,0 +1,6 @@ +type Foo = u32; // { dg-error ".E0091." "" { target *-*-* } } +type Foo2 = Box; // { dg-error ".E0091." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0092.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0092.rs new file mode 100644 index 000000000000..c280f7576920 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0092.rs @@ -0,0 +1,8 @@ +#![feature(intrinsics)] +extern "rust-intrinsic" { + fn atomic_foo(); // { dg-error ".E0092." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0093.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0093.rs new file mode 100644 index 000000000000..eb7591092f4c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0093.rs @@ -0,0 +1,9 @@ +#![feature(intrinsics)] +extern "rust-intrinsic" { + fn foo(); +// { dg-error ".E0093." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0094.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0094.rs new file mode 100644 index 000000000000..6977f01069c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0094.rs @@ -0,0 +1,8 @@ +#![feature(intrinsics)] +extern "rust-intrinsic" { + fn size_of() -> usize; // { dg-error ".E0094." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0106.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0106.rs new file mode 100644 index 000000000000..54b9613245cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0106.rs @@ -0,0 +1,27 @@ +struct Foo { + x: &bool, +// { dg-error ".E0106." "" { target *-*-* } .-1 } +} +enum Bar { + A(u8), + B(&bool), +// { dg-error ".E0106." "" { target *-*-* } .-1 } +} +type MyStr = &str; +// { dg-error ".E0106." "" { target *-*-* } .-1 } + +struct Baz<'a>(&'a str); +struct Buzz<'a, 'b>(&'a str, &'b str); + +struct Quux { + baz: Baz, +// { dg-error ".E0106." "" { target *-*-* } .-1 } +// { dg-error ".E0106." "" { target *-*-* } .-2 } + buzz: Buzz, +// { dg-error ".E0106." "" { target *-*-* } .-1 } +// { dg-error ".E0106." "" { target *-*-* } .-2 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0107.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0107.rs new file mode 100644 index 000000000000..d29103155961 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0107.rs @@ -0,0 +1,24 @@ +struct Foo<'a>(&'a str); +struct Buzz<'a, 'b>(&'a str, &'b str); + +enum Bar { + A, + B, + C, +} + +struct Baz<'a, 'b, 'c> { + buzz: Buzz<'a>, +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } + bar: Bar<'a>, +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } + foo2: Foo<'a, 'b, 'c>, +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +// { dg-error ".E0107." "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0109.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0109.rs new file mode 100644 index 000000000000..38de23ef727f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0109.rs @@ -0,0 +1,5 @@ +type X = u32; // { dg-error ".E0109." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0110.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0110.rs new file mode 100644 index 000000000000..010f05e76204 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0110.rs @@ -0,0 +1,4 @@ +type X = u32<'static>; // { dg-error ".E0109." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0116.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0116.rs new file mode 100644 index 000000000000..16d7e4d5e350 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0116.rs @@ -0,0 +1,6 @@ +impl Vec {} +// { dg-error ".E0116." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0117.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0117.rs new file mode 100644 index 000000000000..46ae1dfa38dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0117.rs @@ -0,0 +1,6 @@ +impl Drop for u32 {} // { dg-error ".E0117." "" { target *-*-* } } +// { dg-error ".E0120." "" { target *-*-* } .-2 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0118-2.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0118-2.rs new file mode 100644 index 000000000000..dd9de3233cb2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0118-2.rs @@ -0,0 +1,9 @@ +struct Foo; + +impl &mut Foo { +// { dg-error ".E0118." "" { target *-*-* } .-1 } + fn bar(self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0118.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0118.rs new file mode 100644 index 000000000000..9d2b043ba627 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0118.rs @@ -0,0 +1,9 @@ +impl (u8, u8) { // { dg-error ".E0118." "" { target *-*-* } } + fn get_state(&self) -> String { + String::new() + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0119.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0119.rs new file mode 100644 index 000000000000..c90ae9d9c23a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0119.rs @@ -0,0 +1,19 @@ +trait MyTrait { + fn get(&self) -> usize; +} + +impl MyTrait for T { + fn get(&self) -> usize { 0 } +} + +struct Foo { + value: usize +} + +impl MyTrait for Foo { // { dg-error ".E0119." "" { target *-*-* } } + fn get(&self) -> usize { self.value } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0120.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0120.rs new file mode 100644 index 000000000000..c9849d866d24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0120.rs @@ -0,0 +1,10 @@ +trait MyTrait { fn foo() {} } + +impl Drop for dyn MyTrait { +// { dg-error ".E0120." "" { target *-*-* } .-1 } + fn drop(&mut self) {} +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0121.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0121.rs new file mode 100644 index 000000000000..4fbd519e9b0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0121.rs @@ -0,0 +1,7 @@ +fn foo() -> _ { 5 } // { dg-error ".E0121." "" { target *-*-* } } + +static BAR: _ = "test"; // { dg-error ".E0121." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0124.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0124.rs new file mode 100644 index 000000000000..3af5788b198b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0124.rs @@ -0,0 +1,9 @@ +struct Foo { + field1: i32, + field1: i32, +// { dg-error ".E0124." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0128.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0128.rs new file mode 100644 index 000000000000..397959479a42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0128.rs @@ -0,0 +1,8 @@ +struct Foo { // { dg-error ".E0128." "" { target *-*-* } } + field1: T, + field2: U, +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0130.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0130.rs new file mode 100644 index 000000000000..04ae21f1c90b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0130.rs @@ -0,0 +1,8 @@ +extern { + fn foo((a, b): (u32, u32)); +// { dg-error ".E0130." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0131.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0131.rs new file mode 100644 index 000000000000..f6a712042451 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0131.rs @@ -0,0 +1,4 @@ +fn main() { +// { dg-error ".E0131." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0132.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0132.rs new file mode 100644 index 000000000000..dc8b1e516236 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0132.rs @@ -0,0 +1,8 @@ +#![feature(start)] + +#[start] +fn f< T >() {} // { dg-error ".E0132." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0133.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0133.rs new file mode 100644 index 000000000000..61326eddb521 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0133.rs @@ -0,0 +1,7 @@ +unsafe fn f() { return; } + +fn main() { + f(); +// { dg-error ".E0133." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0137.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0137.rs new file mode 100644 index 000000000000..1dea5c36624f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0137.rs @@ -0,0 +1,9 @@ +#![feature(main)] + +#[main] +fn foo() {} + +#[main] +fn f() {} +// { dg-error ".E0137." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0138.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0138.rs new file mode 100644 index 000000000000..e72f3fcb3c33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0138.rs @@ -0,0 +1,9 @@ +#![feature(start)] + +#[start] +fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } + +#[start] +fn f(argc: isize, argv: *const *const u8) -> isize { 0 } +// { dg-error ".E0138." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0152.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0152.rs new file mode 100644 index 000000000000..fc7e0ebb53d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0152.rs @@ -0,0 +1,9 @@ +// normalize-stderr-test "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib" +#![feature(lang_items)] + +#[lang = "owned_box"] +struct Foo; // { dg-error ".E0152." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0161.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0161.rs new file mode 100644 index 000000000000..8df624e071bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0161.rs @@ -0,0 +1,28 @@ +// ignore-compare-mode-nll + +// Check that E0161 is a hard error in all possible configurations that might +// affect it. + +// revisions: migrate nll zflags edition migrateul nllul zflagsul editionul +//[zflags]compile-flags: -Z borrowck=migrate +//[edition]edition:2018 +//[zflagsul]compile-flags: -Z borrowck=migrate +//[editionul]edition:2018 + +#![allow(incomplete_features)] +#![cfg_attr(nll, feature(nll))] +#![cfg_attr(nllul, feature(nll))] +#![cfg_attr(migrateul, feature(unsized_locals))] +#![cfg_attr(zflagsul, feature(unsized_locals))] +#![cfg_attr(nllul, feature(unsized_locals))] +#![cfg_attr(editionul, feature(unsized_locals))] +#![feature(box_syntax)] + +fn foo(x: Box<[i32]>) { + box *x; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0164.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0164.rs new file mode 100644 index 000000000000..bd4249bed77c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0164.rs @@ -0,0 +1,15 @@ +enum Foo {} + +impl Foo { + const B: u8 = 0; +} + +fn bar(foo: Foo) -> u32 { + match foo { + Foo::B(i) => i, // { dg-error ".E0164." "" { target *-*-* } } + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0184.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0184.rs new file mode 100644 index 000000000000..11ac620ecc84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0184.rs @@ -0,0 +1,11 @@ +#[derive(Copy)] // { dg-error ".E0184." "" { target *-*-* } } +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) { + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0185.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0185.rs new file mode 100644 index 000000000000..33e4a7401212 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0185.rs @@ -0,0 +1,16 @@ +trait Foo { + fn foo(); +// { dg-note "" "" { target *-*-* } .-1 } +} + +struct Bar; + +impl Foo for Bar { + fn foo(&self) {} +// { dg-error ".E0185." "" { target *-*-* } .-1 } +// { dg-note ".E0185." "" { target *-*-* } .-2 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0186.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0186.rs new file mode 100644 index 000000000000..041dc0292266 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0186.rs @@ -0,0 +1,14 @@ +trait Foo { + fn foo(&self); // { dg-error "" "" { target *-*-* } } +} + +struct Bar; + +impl Foo for Bar { + fn foo() {} // { dg-error ".E0186." "" { target *-*-* } } +// { dg-error ".E0186." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0191.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0191.rs new file mode 100644 index 000000000000..6f065b7205db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0191.rs @@ -0,0 +1,8 @@ +trait Trait { + type Bar; +} + +type Foo = dyn Trait; // { dg-error ".E0191." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0194.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0194.rs new file mode 100644 index 000000000000..266c0e485a14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0194.rs @@ -0,0 +1,9 @@ +trait Foo { + fn do_something(&self) -> T; + fn do_something_else(&self, bar: T); +// { dg-error ".E0403." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0195.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0195.rs new file mode 100644 index 000000000000..1defd82b387a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0195.rs @@ -0,0 +1,16 @@ +trait Trait { + fn bar<'a,'b:'a>(x: &'a str, y: &'b str); +// { dg-note "" "" { target *-*-* } .-1 } +} + +struct Foo; + +impl Trait for Foo { + fn bar<'a,'b>(x: &'a str, y: &'b str) { // { dg-error ".E0195." "" { target *-*-* } } +// { dg-note ".E0195." "" { target *-*-* } .-1 } + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0197.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0197.rs new file mode 100644 index 000000000000..680e42f1f0cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0197.rs @@ -0,0 +1,7 @@ +struct Foo; + +unsafe impl Foo { } // { dg-error ".E0197." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0198.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0198.rs new file mode 100644 index 000000000000..efeb69f5bf5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0198.rs @@ -0,0 +1,9 @@ +#![feature(negative_impls)] + +struct Foo; + +unsafe impl !Send for Foo { } // { dg-error ".E0198." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0199.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0199.rs new file mode 100644 index 000000000000..a5c0194e36f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0199.rs @@ -0,0 +1,10 @@ +#![feature(negative_impls)] + +struct Foo; + +trait Bar { } +unsafe impl Bar for Foo { } // { dg-error ".E0199." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0200.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0200.rs new file mode 100644 index 000000000000..f54b37ea0a46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0200.rs @@ -0,0 +1,9 @@ +struct Foo; + +unsafe trait Bar { } + +impl Bar for Foo { } // { dg-error ".E0200." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0201.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0201.rs new file mode 100644 index 000000000000..5e26e09a62a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0201.rs @@ -0,0 +1,23 @@ +struct Foo(u8); + +impl Foo { + fn bar(&self) -> bool { self.0 > 5 } + fn bar() {} // { dg-error ".E0201." "" { target *-*-* } } +} + +trait Baz { + type Quux; + fn baz(&self) -> bool; +} + +impl Baz for Foo { + type Quux = u32; + + fn baz(&self) -> bool { true } + fn baz(&self) -> bool { self.0 > 5 } // { dg-error ".E0201." "" { target *-*-* } } + type Quux = u32; // { dg-error ".E0201." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0206.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0206.rs new file mode 100644 index 000000000000..4e0a819ee770 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0206.rs @@ -0,0 +1,15 @@ +type Foo = [u8; 256]; + +impl Copy for Foo { } +// { dg-error ".E0117." "" { target *-*-* } .-1 } +// { dg-error ".E0117." "" { target *-*-* } .-2 } + +#[derive(Copy, Clone)] +struct Bar; + +impl Copy for &'static mut Bar { } +// { dg-error ".E0206." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0207.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0207.rs new file mode 100644 index 000000000000..955aa57ffaf4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0207.rs @@ -0,0 +1,11 @@ +struct Foo; + +impl Foo { // { dg-error ".E0207." "" { target *-*-* } } + fn get(&self) -> T { + ::default() + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0214.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0214.rs new file mode 100644 index 000000000000..0a48932104f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0214.rs @@ -0,0 +1,5 @@ +fn main() { + let v: Vec(&str) = vec!["foo"]; +// { dg-error ".E0214." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0220.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0220.rs new file mode 100644 index 000000000000..85b2e5986edc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0220.rs @@ -0,0 +1,9 @@ +trait Trait { + type Bar; +} + +type Foo = dyn Trait; // { dg-error ".E0191." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0221.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0221.rs new file mode 100644 index 000000000000..52a569397591 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0221.rs @@ -0,0 +1,28 @@ +trait T1 {} +trait T2 {} + +trait Foo { + type A: T1; +} + +trait Bar : Foo { + type A: T2; + fn do_something() { + let _: Self::A; +// { dg-error ".E0221." "" { target *-*-* } .-1 } + } +} + +trait T3 {} + +trait My : std::str::FromStr { + type Err: T3; + fn test() { + let _: Self::Err; +// { dg-error ".E0221." "" { target *-*-* } .-1 } + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0223.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0223.rs new file mode 100644 index 000000000000..eb32611c338e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0223.rs @@ -0,0 +1,7 @@ +trait MyTrait { type X; } + +fn main() { + let foo: MyTrait::X; +// { dg-error ".E0223." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0225.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0225.rs new file mode 100644 index 000000000000..4456f1145e0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0225.rs @@ -0,0 +1,11 @@ +#![feature(trait_alias)] + +trait Foo = std::io::Read + std::io::Write; + +fn main() { + let _: Box; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + let _: Box; +// { dg-error ".E0225." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0229.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0229.rs new file mode 100644 index 000000000000..a4770732cd23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0229.rs @@ -0,0 +1,18 @@ +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) {} +// { dg-error ".E0229." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0252.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0252.rs new file mode 100644 index 000000000000..996694d0c3bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0252.rs @@ -0,0 +1,16 @@ +#![allow(non_camel_case_types)] + +use foo::baz; +use bar::baz; // { dg-error ".E0252." "" { target *-*-* } } + +mod foo { + pub struct baz; +} + +mod bar { + pub mod baz {} +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0253.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0253.rs new file mode 100644 index 000000000000..d5d57a8ecbb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0253.rs @@ -0,0 +1,11 @@ +mod foo { + pub trait MyTrait { + fn do_something(); + } +} + +use foo::MyTrait::do_something; +// { dg-error ".E0253." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0254.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0254.rs new file mode 100644 index 000000000000..aaade19ef1a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0254.rs @@ -0,0 +1,15 @@ +#![allow(non_camel_case_types)] + +extern crate alloc; + +mod foo { + pub trait alloc { + fn do_something(); + } +} + +use foo::alloc; +// { dg-error ".E0254." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0255.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0255.rs new file mode 100644 index 000000000000..28185b7317ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0255.rs @@ -0,0 +1,10 @@ +use bar::foo; + +fn foo() {} // { dg-error ".E0255." "" { target *-*-* } } + +mod bar { + pub fn foo() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0259.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0259.rs new file mode 100644 index 000000000000..a64b3d6bc321 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0259.rs @@ -0,0 +1,9 @@ +#![feature(rustc_private)] + +extern crate alloc; + +extern crate libc as alloc; +// { dg-error ".E0259." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0260.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0260.rs new file mode 100644 index 000000000000..b0a34dae3bad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0260.rs @@ -0,0 +1,11 @@ +extern crate alloc; + +mod alloc { +// { dg-error ".E0260." "" { target *-*-* } .-1 } + pub trait MyTrait { + fn do_something(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0261.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0261.rs new file mode 100644 index 000000000000..1d69b524d417 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0261.rs @@ -0,0 +1,10 @@ +fn foo(x: &'a str) { } // { dg-error ".E0261." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + +struct Foo { + x: &'a str, // { dg-error ".E0261." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0262.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0262.rs new file mode 100644 index 000000000000..67441fc89871 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0262.rs @@ -0,0 +1,5 @@ +fn foo<'static>(x: &'static str) { } // { dg-error ".E0262." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0263.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0263.rs new file mode 100644 index 000000000000..4979bd20163f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0263.rs @@ -0,0 +1,6 @@ +fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { +// { dg-error ".E0263." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0264.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0264.rs new file mode 100644 index 000000000000..76fa8c4b34de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0264.rs @@ -0,0 +1,9 @@ +#![feature(lang_items)] + +extern "C" { + #[lang = "cake"] + fn cake(); // { dg-error ".E0264." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0267.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0267.rs new file mode 100644 index 000000000000..7a3b66b670a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0267.rs @@ -0,0 +1,4 @@ +fn main() { + let w = || { break; }; // { dg-error ".E0267." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0268.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0268.rs new file mode 100644 index 000000000000..d36b20e4e383 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0268.rs @@ -0,0 +1,4 @@ +fn main() { + break; // { dg-error ".E0268." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0271.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0271.rs new file mode 100644 index 000000000000..622cc56bc3e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0271.rs @@ -0,0 +1,12 @@ +trait Trait { type AssociatedType; } + +fn foo(t: T) where T: Trait { + println!("in foo"); +} + +impl Trait for i8 { type AssociatedType = &'static str; } + +fn main() { + foo(3_i8); // { dg-error ".E0271." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0275.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0275.rs new file mode 100644 index 000000000000..21b446f49bec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0275.rs @@ -0,0 +1,9 @@ +trait Foo {} + +struct Bar(T); + +impl Foo for T where Bar: Foo {} // { dg-error ".E0275." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0276.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0276.rs new file mode 100644 index 000000000000..69370a701cd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0276.rs @@ -0,0 +1,11 @@ +trait Foo { + fn foo(x: T); +} + +impl Foo for bool { + fn foo(x: T) where T: Copy {} // { dg-error ".E0276." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0277-2.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0277-2.rs new file mode 100644 index 000000000000..7abf97334867 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0277-2.rs @@ -0,0 +1,19 @@ +struct Foo { + bar: Bar +} + +struct Bar { + baz: Baz +} + +struct Baz { + x: *const u8 +} + +fn is_send() { } + +fn main() { + is_send::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0277.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0277.rs new file mode 100644 index 000000000000..f063d42bdc1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0277.rs @@ -0,0 +1,20 @@ +// ignore-cloudabi no std::path + +use std::path::Path; + +trait Foo { + fn bar(&self); +} + +fn some_func(foo: T) { + foo.bar(); +} + +fn f(p: Path) { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { + some_func(5i32); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0282.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0282.rs new file mode 100644 index 000000000000..d0f5d1f69d3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0282.rs @@ -0,0 +1,4 @@ +fn main() { + let x = "hello".chars().rev().collect(); // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0283.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0283.rs new file mode 100644 index 000000000000..844e05c520dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0283.rs @@ -0,0 +1,20 @@ +trait Generator { + fn create() -> u32; +} + +struct Impl; + +impl Generator for Impl { + fn create() -> u32 { 1 } +} + +struct AnotherImpl; + +impl Generator for AnotherImpl { + fn create() -> u32 { 2 } +} + +fn main() { + let cont: u32 = Generator::create(); // { dg-error ".E0283." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0297.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0297.rs new file mode 100644 index 000000000000..753ddd1adcfd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0297.rs @@ -0,0 +1,7 @@ +fn main() { + let xs : Vec> = vec![Some(1), None]; + + for Some(x) in xs {} +// { dg-error ".E0005." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0308-2.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0308-2.rs new file mode 100644 index 000000000000..ee68a0c33530 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0308-2.rs @@ -0,0 +1,13 @@ +trait DynEq {} + +impl<'a> PartialEq for &'a (dyn DynEq + 'static) { + fn eq(&self, _other: &Self) -> bool { + true + } +} + +impl Eq for &dyn DynEq {} // { dg-error ".E0308." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0308-4.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0308-4.rs new file mode 100644 index 000000000000..d361cead6cf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0308-4.rs @@ -0,0 +1,8 @@ +fn main() { + let x = 1u8; + match x { + 0u8..=3i8 => (), // { dg-error ".E0308." "" { target *-*-* } } + _ => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0308.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0308.rs new file mode 100644 index 000000000000..9712861d37a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0308.rs @@ -0,0 +1,9 @@ +#![feature(intrinsics)] + +extern "rust-intrinsic" { + fn size_of(); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0328.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0328.rs new file mode 100644 index 000000000000..4d1438a44e5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0328.rs @@ -0,0 +1,11 @@ +#![feature(unsize)] + +use std::marker::Unsize; + +pub struct MyType; + +impl Unsize for MyType {} +// { dg-error ".E0328." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0365.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0365.rs new file mode 100644 index 000000000000..8775a7713506 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0365.rs @@ -0,0 +1,9 @@ +mod foo { + pub const X: u32 = 1; +} + +pub use foo as foo2; +// { dg-error ".E0365." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0370.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0370.rs new file mode 100644 index 000000000000..386818330f5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0370.rs @@ -0,0 +1,11 @@ +#![allow(dead_code)] + +#[deny(overflowing_literals)] +#[repr(i64)] +enum Foo { + X = 0x7fffffffffffffff, + Y, // { dg-error ".E0370." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0374.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0374.rs new file mode 100644 index 000000000000..bb7cf2aa55b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0374.rs @@ -0,0 +1,12 @@ +#![feature(coerce_unsized)] +use std::ops::CoerceUnsized; + +struct Foo { + a: i32, +} + +impl CoerceUnsized> for Foo // { dg-error ".E0374." "" { target *-*-* } } + where T: CoerceUnsized {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0375.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0375.rs new file mode 100644 index 000000000000..4d3cb4f43e7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0375.rs @@ -0,0 +1,14 @@ +#![feature(coerce_unsized)] +use std::ops::CoerceUnsized; + +struct Foo { + a: i32, + b: T, + c: U, +} + +impl CoerceUnsized> for Foo {} +// { dg-error ".E0375." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0376.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0376.rs new file mode 100644 index 000000000000..3f64a6827667 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0376.rs @@ -0,0 +1,11 @@ +#![feature(coerce_unsized)] +use std::ops::CoerceUnsized; + +struct Foo { + a: T, +} + +impl CoerceUnsized for Foo {} // { dg-error ".E0376." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0388.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0388.rs new file mode 100644 index 000000000000..7b2401b5cb22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0388.rs @@ -0,0 +1,13 @@ +static X: i32 = 1; +const C: i32 = 2; + +const CR: &'static mut i32 = &mut C; // { dg-error ".E0764." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +static STATIC_REF: &'static mut i32 = &mut X; // { dg-error ".E0596." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + +static CONST_REF: &'static mut i32 = &mut C; // { dg-error ".E0764." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0389.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0389.rs new file mode 100644 index 000000000000..d908f4b0f888 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0389.rs @@ -0,0 +1,11 @@ +struct FancyNum { + num: u8, +} + +fn main() { + let mut fancy = FancyNum{ num: 5 }; + let fancy_ref = &(&mut fancy); + fancy_ref.num = 6; // { dg-error ".E0594." "" { target *-*-* } } + println!("{}", fancy_ref.num); +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0390.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0390.rs new file mode 100644 index 000000000000..4d99381e4404 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0390.rs @@ -0,0 +1,9 @@ +struct Foo { + x: i32 +} + +impl *mut Foo {} // { dg-error ".E0390." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0392.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0392.rs new file mode 100644 index 000000000000..2b2fed5110c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0392.rs @@ -0,0 +1,5 @@ +enum Foo { Bar } // { dg-error ".E0392." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0393.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0393.rs new file mode 100644 index 000000000000..d2b970e9251c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0393.rs @@ -0,0 +1,8 @@ +trait A {} + +fn together_we_will_rule_the_galaxy(son: &dyn A) {} +// { dg-error ".E0393." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0395.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0395.rs new file mode 100644 index 000000000000..5cb23c93df8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0395.rs @@ -0,0 +1,9 @@ +static FOO: i32 = 42; +static BAR: i32 = 42; + +static BAZ: bool = unsafe { (&FOO as *const i32) == (&BAR as *const i32) }; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0396-fixed.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0396-fixed.rs new file mode 100644 index 000000000000..0abb26c09194 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0396-fixed.rs @@ -0,0 +1,10 @@ +#![feature(const_raw_ptr_deref)] + +const REG_ADDR: *const u8 = 0x5f3759df as *const u8; + +const VALUE: u8 = unsafe { *REG_ADDR }; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0396.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0396.rs new file mode 100644 index 000000000000..19f06a0449df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0396.rs @@ -0,0 +1,10 @@ +// gate-test-const_raw_ptr_deref + +const REG_ADDR: *const u8 = 0x5f3759df as *const u8; + +const VALUE: u8 = unsafe { *REG_ADDR }; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0401.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0401.rs new file mode 100644 index 000000000000..5c10e45b26f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0401.rs @@ -0,0 +1,31 @@ +trait Baz {} + +fn foo(x: T) { + fn bfnr, W: Fn()>(y: T) { // { dg-error ".E0401." "" { target *-*-* } } + } + fn baz, + W: Fn()> + (y: T) { // { dg-error ".E0401." "" { target *-*-* } } + } + bfnr(x); // { dg-error ".E0282." "" { target *-*-* } } +} + + +struct A { + inner: T, +} + +impl Iterator for A { + type Item = u8; + fn next(&mut self) -> Option { + fn helper(sel: &Self) -> u8 { // { dg-error ".E0401." "" { target *-*-* } } + unimplemented!(); + } + Some(helper(self)) + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0403.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0403.rs new file mode 100644 index 000000000000..c07303653af0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0403.rs @@ -0,0 +1,5 @@ +fn foo(s: T, u: T) {} // { dg-error ".E0403." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0404.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0404.rs new file mode 100644 index 000000000000..8a9173a1ee45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0404.rs @@ -0,0 +1,9 @@ +struct Foo; +struct Bar; + +impl Foo for Bar {} // { dg-error ".E0404." "" { target *-*-* } } + +fn main() {} + +fn baz(_: T) {} // { dg-error ".E0404." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0405.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0405.rs new file mode 100644 index 000000000000..9ab3b4ada2d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0405.rs @@ -0,0 +1,7 @@ +struct Foo; + +impl SomeTrait for Foo {} // { dg-error ".E0405." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0407.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0407.rs new file mode 100644 index 000000000000..46bebd8f4a75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0407.rs @@ -0,0 +1,15 @@ +trait Foo { + fn a(); +} + +struct Bar; + +impl Foo for Bar { + fn a() {} + fn b() {} +// { dg-error ".E0407." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0408.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0408.rs new file mode 100644 index 000000000000..665ecd1ad35c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0408.rs @@ -0,0 +1,9 @@ +fn main() { + let x = Some(0); + + match x { + Some(y) | None => {} // { dg-error ".E0408." "" { target *-*-* } } + _ => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0411.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0411.rs new file mode 100644 index 000000000000..27815201716e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0411.rs @@ -0,0 +1,4 @@ +fn main() { + ::foo; // { dg-error ".E0411." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0412.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0412.rs new file mode 100644 index 000000000000..94db02e0c8e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0412.rs @@ -0,0 +1,5 @@ +impl Something {} // { dg-error ".E0412." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0415.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0415.rs new file mode 100644 index 000000000000..2b48ed64d2a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0415.rs @@ -0,0 +1,5 @@ +fn foo(f: i32, f: i32) {} // { dg-error ".E0415." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0416.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0416.rs new file mode 100644 index 000000000000..1a1b4940f90d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0416.rs @@ -0,0 +1,6 @@ +fn main() { + match (1, 2) { + (x, x) => {} // { dg-error ".E0416." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0423.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0423.rs new file mode 100644 index 000000000000..0bf833edead6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0423.rs @@ -0,0 +1,23 @@ +fn main () { + struct Foo { a: bool }; + + let f = Foo(); // { dg-error ".E0423." "" { target *-*-* } } +} + +fn bar() { + struct S { x: i32, y: i32 } + #[derive(PartialEq)] + struct T {} + + if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } +// { dg-error "" "" { target *-*-* } .-1 } + if T {} == T {} { println!("Ok"); } +// { dg-error ".E0423." "" { target *-*-* } .-1 } +// { dg-error ".E0423." "" { target *-*-* } .-2 } +} + +fn foo() { + for _ in std::ops::Range { start: 0, end: 10 } {} +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0424.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0424.rs new file mode 100644 index 000000000000..12b8c7a6829c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0424.rs @@ -0,0 +1,22 @@ +struct Foo; + +impl Foo { + fn bar(self) {} + + fn foo() { + self.bar(); // { dg-error ".E0424." "" { target *-*-* } } + } + + fn baz(_: i32) { + self.bar(); // { dg-error ".E0424." "" { target *-*-* } } + } + + fn qux() { + let _ = || self.bar(); // { dg-error ".E0424." "" { target *-*-* } } + } +} + +fn main () { + let self = "self"; // { dg-error ".E0424." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0425.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0425.rs new file mode 100644 index 000000000000..0030f4cf5167 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0425.rs @@ -0,0 +1,9 @@ +trait Foo { + fn bar() { + elf; // { dg-error ".E0425." "" { target *-*-* } } + } +} + +fn main () { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0426.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0426.rs new file mode 100644 index 000000000000..417f3786935b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0426.rs @@ -0,0 +1,7 @@ +fn main () { + loop { + break 'a; +// { dg-error ".E0426." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0428.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0428.rs new file mode 100644 index 000000000000..6b5c1c869282 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0428.rs @@ -0,0 +1,6 @@ +struct Bar; // { dg-error "" "" { target *-*-* } } +struct Bar; // { dg-error ".E0428." "" { target *-*-* } } + +fn main () { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0429.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0429.rs new file mode 100644 index 000000000000..e5f171d32696 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0429.rs @@ -0,0 +1,5 @@ +use std::fmt::self; // { dg-error ".E0429." "" { target *-*-* } } + +fn main () { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0430.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0430.rs new file mode 100644 index 000000000000..e3080873bb3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0430.rs @@ -0,0 +1,6 @@ +use std::fmt::{self, self}; // { dg-error ".E0252." "" { target *-*-* } } +// { dg-error ".E0252." "" { target *-*-* } .-1 } + +fn main () { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0431.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0431.rs new file mode 100644 index 000000000000..bb8668965892 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0431.rs @@ -0,0 +1,5 @@ +use {self}; // { dg-error ".E0431." "" { target *-*-* } } + +fn main () { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0432.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0432.rs new file mode 100644 index 000000000000..b955ce6a6cf5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0432.rs @@ -0,0 +1,5 @@ +use something::Foo; // { dg-error ".E0432." "" { target *-*-* } } + +fn main () { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0433.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0433.rs new file mode 100644 index 000000000000..3f3ef515d104 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0433.rs @@ -0,0 +1,4 @@ +fn main () { + let map = NonExistingMap::new(); // { dg-error ".E0433." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0434.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0434.rs new file mode 100644 index 000000000000..962e9545846c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0434.rs @@ -0,0 +1,10 @@ +fn foo() { + let y = 5; + fn bar() -> u32 { + y // { dg-error ".E0434." "" { target *-*-* } } + } +} + +fn main () { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0435.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0435.rs new file mode 100644 index 000000000000..2aeba087ca10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0435.rs @@ -0,0 +1,5 @@ +fn main () { + let foo = 42u32; + let _: [u8; foo]; // { dg-error ".E0435." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0437.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0437.rs new file mode 100644 index 000000000000..5531698fb0fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0437.rs @@ -0,0 +1,9 @@ +trait Foo {} + +impl Foo for i32 { + type Bar = bool; // { dg-error ".E0437." "" { target *-*-* } } +} + +fn main () { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0438.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0438.rs new file mode 100644 index 000000000000..9c1c70e92b83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0438.rs @@ -0,0 +1,9 @@ +trait Bar {} + +impl Bar for i32 { + const BAR: bool = true; // { dg-error ".E0438." "" { target *-*-* } } +} + +fn main () { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0439.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0439.rs new file mode 100644 index 000000000000..4ef59f582e7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0439.rs @@ -0,0 +1,9 @@ +#![feature(platform_intrinsics)] + +extern "platform-intrinsic" { + fn simd_shuffle(a: A, b: A, c: [u32; 8]) -> B; // { dg-error ".E0439." "" { target *-*-* } } +} + +fn main () { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0445.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0445.rs new file mode 100644 index 000000000000..328a1f0148d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0445.rs @@ -0,0 +1,13 @@ +trait Foo { + fn dummy(&self) { } +} + +pub trait Bar : Foo {} +// { dg-error ".E0445." "" { target *-*-* } .-1 } +pub struct Bar2(pub T); +// { dg-error ".E0445." "" { target *-*-* } .-1 } +pub fn foo (t: T) {} +// { dg-error ".E0445." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0446.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0446.rs new file mode 100644 index 000000000000..dd7b4b07d0ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0446.rs @@ -0,0 +1,10 @@ +mod foo { + struct Bar(u32); + + pub fn bar() -> Bar { // { dg-error ".E0446." "" { target *-*-* } } + Bar(0) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0449.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0449.rs new file mode 100644 index 000000000000..7fd6b077c98e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0449.rs @@ -0,0 +1,15 @@ +struct Bar; + +trait Foo { + fn foo(); +} + +pub impl Bar {} // { dg-error ".E0449." "" { target *-*-* } } + +pub impl Foo for Bar { // { dg-error ".E0449." "" { target *-*-* } } + pub fn foo() {} // { dg-error ".E0449." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0451.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0451.rs new file mode 100644 index 000000000000..428a57e7b242 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0451.rs @@ -0,0 +1,20 @@ +mod bar { + pub struct Foo { + pub a: isize, + b: isize, + } + + pub struct FooTuple ( + pub isize, + isize, + ); +} + +fn pat_match(foo: bar::Foo) { + let bar::Foo{a, b} = foo; // { dg-error ".E0451." "" { target *-*-* } } +} + +fn main() { + let f = bar::Foo{ a: 0, b: 0 }; // { dg-error ".E0451." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0452.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0452.rs new file mode 100644 index 000000000000..8eb11823253c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0452.rs @@ -0,0 +1,9 @@ +#![allow(foo = "")] // { dg-error ".E0452." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-error "" "" { target *-*-* } .-6 } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0453.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0453.rs new file mode 100644 index 000000000000..b3077c6826cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0453.rs @@ -0,0 +1,9 @@ +#![forbid(non_snake_case)] + +#[allow(non_snake_case)] +// { dg-error ".E0453." "" { target *-*-* } .-1 } +// { dg-error ".E0453." "" { target *-*-* } .-2 } +// { dg-error ".E0453." "" { target *-*-* } .-3 } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0454.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0454.rs new file mode 100644 index 000000000000..a27d99d0546e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0454.rs @@ -0,0 +1,6 @@ +#[link(name = "")] extern {} +// { dg-error ".E0454." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0458.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0458.rs new file mode 100644 index 000000000000..7efc278009ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0458.rs @@ -0,0 +1,6 @@ +#[link(kind = "wonderful_unicorn")] extern {} // { dg-error ".E0459." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0459.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0459.rs new file mode 100644 index 000000000000..cf3fd81b96f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0459.rs @@ -0,0 +1,5 @@ +#[link(kind = "dylib")] extern {} // { dg-error ".E0459." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0463.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0463.rs new file mode 100644 index 000000000000..ac3bc05e97bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0463.rs @@ -0,0 +1,8 @@ +#![feature(plugin)] +#![plugin(cookie_monster)] +// { dg-error ".E0463." "" { target *-*-* } .-1 } +extern crate cake_is_a_lie; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0478.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0478.rs new file mode 100644 index 000000000000..e5eb7639e8a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0478.rs @@ -0,0 +1,9 @@ +trait Wedding<'t>: 't { } + +struct Prince<'kiss, 'SnowWhite> { + child: Box + 'SnowWhite>, // { dg-error ".E0478." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0490.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0490.rs new file mode 100644 index 000000000000..7e2ef50b852c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0490.rs @@ -0,0 +1,9 @@ +fn f<'a, 'b>(y: &'b ()) { + let x: &'a _ = &y; +// { dg-error ".E0495." "" { target *-*-* } .-1 } +// { dg-error ".E0495." "" { target *-*-* } .-2 } +// { dg-error ".E0495." "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0492.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0492.rs new file mode 100644 index 000000000000..eaca90d9f746 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0492.rs @@ -0,0 +1,8 @@ +use std::sync::atomic::AtomicUsize; + +const A: AtomicUsize = AtomicUsize::new(0); +static B: &'static AtomicUsize = &A; // { dg-error ".E0492." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0496.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0496.rs new file mode 100644 index 000000000000..76a237315ace --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0496.rs @@ -0,0 +1,12 @@ +struct Foo<'a> { + a: &'a i32, +} + +impl<'a> Foo<'a> { + fn f<'a>(x: &'a i32) { // { dg-error ".E0496." "" { target *-*-* } } + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0499.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0499.rs new file mode 100644 index 000000000000..73f98722d123 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0499.rs @@ -0,0 +1,11 @@ +fn main() { + let mut i = 0; + let mut x = &mut i; + let mut a = &mut i; // { dg-error ".E0499." "" { target *-*-* } } + a.use_mut(); + x.use_mut(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0501.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0501.rs new file mode 100644 index 000000000000..d0959c595233 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0501.rs @@ -0,0 +1,25 @@ +fn inside_closure(x: &mut i32) { +} + +fn outside_closure_1(x: &mut i32) { +} + +fn outside_closure_2(x: &i32) { +} + +fn foo(a: &mut i32) { + let bar = || { + inside_closure(a) + }; + outside_closure_1(a); +// { dg-error ".E0501." "" { target *-*-* } .-1 } + + outside_closure_2(a); +// { dg-error ".E0501." "" { target *-*-* } .-1 } + + drop(bar); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0502.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0502.rs new file mode 100644 index 000000000000..3af5fafba895 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0502.rs @@ -0,0 +1,13 @@ +fn bar(x: &mut i32) {} +fn foo(a: &mut i32) { + let ref y = a; + bar(a); // { dg-error ".E0502." "" { target *-*-* } } + y.use_ref(); +} + +fn main() { +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0503.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0503.rs new file mode 100644 index 000000000000..29272c1c7a39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0503.rs @@ -0,0 +1,10 @@ +fn main() { + let mut value = 3; + let _borrow = &mut value; + let _sum = value + 1; // { dg-error ".E0503." "" { target *-*-* } } + _borrow.use_mut(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0504.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0504.rs new file mode 100644 index 000000000000..89c0a2f92551 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0504.rs @@ -0,0 +1,16 @@ +struct FancyNum { + num: u8, +} + +fn main() { + let fancy_num = FancyNum { num: 5 }; + let fancy_ref = &fancy_num; + + let x = move || { // { dg-error ".E0505." "" { target *-*-* } } + println!("child function: {}", fancy_num.num); + }; + + x(); + println!("main function: {}", fancy_ref.num); +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0505.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0505.rs new file mode 100644 index 000000000000..3a01ac47e830 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0505.rs @@ -0,0 +1,16 @@ +struct Value {} + +fn eat(val: Value) {} + +fn main() { + let x = Value{}; + { + let _ref_to_val: &Value = &x; + eat(x); // { dg-error ".E0505." "" { target *-*-* } } + _ref_to_val.use_ref(); + } +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0506.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0506.rs new file mode 100644 index 000000000000..b4b80e54f04d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0506.rs @@ -0,0 +1,12 @@ +struct FancyNum { + num: u8, +} + +fn main() { + let mut fancy_num = FancyNum { num: 5 }; + let fancy_ref = &fancy_num; + fancy_num = FancyNum { num: 6 }; // { dg-error ".E0506." "" { target *-*-* } } + + println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num); +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0507.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0507.rs new file mode 100644 index 000000000000..a07a5f7b43dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0507.rs @@ -0,0 +1,14 @@ +use std::cell::RefCell; + +struct TheDarkKnight; + +impl TheDarkKnight { + fn nothing_is_true(self) {} +} + +fn main() { + let x = RefCell::new(TheDarkKnight); + + x.borrow().nothing_is_true(); // { dg-error ".E0507." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0508-fail.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0508-fail.rs new file mode 100644 index 000000000000..6e6c5af95070 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0508-fail.rs @@ -0,0 +1,7 @@ +struct NonCopy; + +fn main() { + let array = [NonCopy; 1]; + let _value = array[0]; // { dg-error ".E0508." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0508.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0508.rs new file mode 100644 index 000000000000..6e6c5af95070 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0508.rs @@ -0,0 +1,7 @@ +struct NonCopy; + +fn main() { + let array = [NonCopy; 1]; + let _value = array[0]; // { dg-error ".E0508." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0509.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0509.rs new file mode 100644 index 000000000000..5bc6e0902d9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0509.rs @@ -0,0 +1,19 @@ +struct FancyNum { + num: usize +} + +struct DropStruct { + fancy: FancyNum +} + +impl Drop for DropStruct { + fn drop(&mut self) { + } +} + +fn main() { + let drop_struct = DropStruct{fancy: FancyNum{num: 5}}; + let fancy_field = drop_struct.fancy; // { dg-error ".E0509." "" { target *-*-* } } + println!("Fancy: {}", fancy_field.num); +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0511.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0511.rs new file mode 100644 index 000000000000..5f22d25b0036 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0511.rs @@ -0,0 +1,12 @@ +// build-fail + +#![feature(platform_intrinsics)] + +extern "platform-intrinsic" { + fn simd_add(a: T, b: T) -> T; +} + +fn main() { + unsafe { simd_add(0, 1); } // { dg-error ".E0511." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0512.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0512.rs new file mode 100644 index 000000000000..5d76e5ccf2b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0512.rs @@ -0,0 +1,6 @@ +fn takes_u8(_: u8) {} + +fn main() { + unsafe { takes_u8(::std::mem::transmute(0u16)); } // { dg-error ".E0512." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0516.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0516.rs new file mode 100644 index 000000000000..f8646baa3825 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0516.rs @@ -0,0 +1,5 @@ +fn main() { + let x: typeof(92) = 92; // { dg-error ".E0516." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0517.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0517.rs new file mode 100644 index 000000000000..6c963a9a1f18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0517.rs @@ -0,0 +1,16 @@ +#[repr(C)] // { dg-error ".E0517." "" { target *-*-* } } +type Foo = u8; + +#[repr(packed)] // { dg-error ".E0517." "" { target *-*-* } } +enum Foo2 {Bar, Baz} + +#[repr(u8)] // { dg-error ".E0517." "" { target *-*-* } } +struct Foo3 {bar: bool, baz: bool} + +#[repr(C)] // { dg-error ".E0517." "" { target *-*-* } } +impl Foo3 { +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0518.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0518.rs new file mode 100644 index 000000000000..92d1438d10e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0518.rs @@ -0,0 +1,10 @@ +#[inline(always)] // { dg-error ".E0518." "" { target *-*-* } } +struct Foo; + +#[inline(never)] // { dg-error ".E0518." "" { target *-*-* } } +impl Foo { +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0520.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0520.rs new file mode 100644 index 000000000000..b2d78cda498a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0520.rs @@ -0,0 +1,23 @@ +#![feature(specialization)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait SpaceLlama { + fn fly(&self); +} + +impl SpaceLlama for T { + default fn fly(&self) {} +} + +impl SpaceLlama for T { + fn fly(&self) {} +} + +impl SpaceLlama for i32 { + default fn fly(&self) {} +// { dg-error ".E0520." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0522.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0522.rs new file mode 100644 index 000000000000..f8115f4dbba1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0522.rs @@ -0,0 +1,10 @@ +#![feature(lang_items)] + +#[lang = "cookie"] +fn cookie() -> ! { +// { dg-error ".E0522." "" { target *-*-* } .-2 } + loop {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0527.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0527.rs new file mode 100644 index 000000000000..cd12fa38246e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0527.rs @@ -0,0 +1,10 @@ +fn main() { + let r = &[1, 2, 3, 4]; + match r { + &[a, b] => { +// { dg-error ".E0527." "" { target *-*-* } .-1 } + println!("a={}, b={}", a, b); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0528.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0528.rs new file mode 100644 index 000000000000..e9f2f5a051d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0528.rs @@ -0,0 +1,9 @@ +fn main() { + let r = &[1, 2]; + match r { + &[a, b, c, rest @ ..] => { +// { dg-error ".E0528." "" { target *-*-* } .-1 } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0529.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0529.rs new file mode 100644 index 000000000000..c571707b16f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0529.rs @@ -0,0 +1,9 @@ +fn main() { + let r: f32 = 1.0; + match r { + [a, b] => { +// { dg-error ".E0529." "" { target *-*-* } .-1 } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0530.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0530.rs new file mode 100644 index 000000000000..7f4b08c27b36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0530.rs @@ -0,0 +1,9 @@ +fn main() { + static TEST: i32 = 0; + + let r: (i32, i32) = (0, 0); + match r { + TEST => {} // { dg-error ".E0530." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0532.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0532.rs new file mode 100644 index 000000000000..dc51cecd8210 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0532.rs @@ -0,0 +1,15 @@ +fn main() { + let value = 1; + + match SomeStruct(value) { + StructConst1(_) => { }, +// { dg-error ".E0532." "" { target *-*-* } .-1 } + _ => { }, + } + + struct SomeStruct(u8); + + const StructConst1 : SomeStruct = SomeStruct(1); + const StructConst2 : SomeStruct = SomeStruct(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0534.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0534.rs new file mode 100644 index 000000000000..fbabbeb15457 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0534.rs @@ -0,0 +1,7 @@ +#[inline()] // { dg-error ".E0534." "" { target *-*-* } } +pub fn something() {} + +fn main() { + something(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0559.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0559.rs new file mode 100644 index 000000000000..a259a8b02976 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0559.rs @@ -0,0 +1,9 @@ +enum Field { + Fool { x: u32 }, +} + +fn main() { + let s = Field::Fool { joke: 0 }; +// { dg-error ".E0559." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0560.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0560.rs new file mode 100644 index 000000000000..59878d92f9b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0560.rs @@ -0,0 +1,9 @@ +struct Simba { + mother: u32, +} + +fn main() { + let s = Simba { mother: 1, father: 0 }; +// { dg-error ".E0560." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0565-1.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0565-1.rs new file mode 100644 index 000000000000..03e1de9e75a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0565-1.rs @@ -0,0 +1,6 @@ +// deprecated doesn't currently support literals +#[deprecated("since")] // { dg-error ".E0565." "" { target *-*-* } } +fn f() { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0565-2.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0565-2.rs new file mode 100644 index 000000000000..d18fa7105858 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0565-2.rs @@ -0,0 +1,6 @@ +// repr currently doesn't support literals +#[deprecated(since = b"1.29", note = "hi")] // { dg-error ".E0565." "" { target *-*-* } } +struct A { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0565.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0565.rs new file mode 100644 index 000000000000..1d292a2e6318 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0565.rs @@ -0,0 +1,7 @@ +// repr currently doesn't support literals +#[repr("C")] // { dg-error ".E0565." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +struct A { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0572.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0572.rs new file mode 100644 index 000000000000..b134b886c370 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0572.rs @@ -0,0 +1,4 @@ +const FOO: u32 = return 0; // { dg-error ".E0572." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0582.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0582.rs new file mode 100644 index 000000000000..cb2fb9c6d919 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0582.rs @@ -0,0 +1,43 @@ +// This test was derived from the wasm and parsell crates. They +// stopped compiling when #32330 is fixed. + +#![allow(dead_code, unused_variables)] + +use std::str::Chars; + +pub trait HasOutput { + type Output; +} + +#[derive(Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Debug)] +pub enum Token<'a> { + Begin(&'a str) +} + +fn mk_unexpected_char_err<'a>() -> Option<&'a i32> { + unimplemented!() +} + +fn foo<'a>(data: &mut Chars<'a>) { + bar(mk_unexpected_char_err) +} + +fn bar(t: F) + // No type can satisfy this requirement, since `'a` does not + // appear in any of the input types: + where F: for<'a> Fn() -> Option<&'a i32> +// { dg-error ".E0582." "" { target *-*-* } .-1 } +{ +} + +fn baz(t: F) + // No type can satisfy this requirement, since `'a` does not + // appear in any of the input types: + where F: for<'a> Iterator +// { dg-error ".E0582." "" { target *-*-* } .-1 } +{ +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0583.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0583.rs new file mode 100644 index 000000000000..b0b707dcbc5a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0583.rs @@ -0,0 +1,5 @@ +mod module_that_doesnt_exist; // { dg-error ".E0583." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0585.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0585.rs new file mode 100644 index 000000000000..9a9ca7efad71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0585.rs @@ -0,0 +1,5 @@ +fn main() { + /// Hello! I'm useless... +// { dg-error ".E0585." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0586.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0586.rs new file mode 100644 index 000000000000..89d661e63aef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0586.rs @@ -0,0 +1,5 @@ +fn main() { + let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1]; + let x = &tmp[1..=]; // { dg-error ".E0586." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0594.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0594.rs new file mode 100644 index 000000000000..a45ae93ee0bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0594.rs @@ -0,0 +1,6 @@ +static NUM: i32 = 18; + +fn main() { + NUM = 20; // { dg-error ".E0594." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0596.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0596.rs new file mode 100644 index 000000000000..700e38977bce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0596.rs @@ -0,0 +1,5 @@ +fn main() { + let x = 1; + let y = &mut x; // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0597.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0597.rs new file mode 100644 index 000000000000..78bc60f22002 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0597.rs @@ -0,0 +1,13 @@ +struct Foo<'a> { + x: Option<&'a u32>, +} + +fn main() { + let mut x = Foo { x: None }; + let y = 0; + x.x = Some(&y); +// { dg-error ".E0597." "" { target *-*-* } .-1 } +} + +impl<'a> Drop for Foo<'a> { fn drop(&mut self) { } } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0599.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0599.rs new file mode 100644 index 000000000000..97cd328a822b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0599.rs @@ -0,0 +1,6 @@ +struct Foo; + +fn main() { + || if let Foo::NotEvenReal() = Foo {}; // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0600.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0600.rs new file mode 100644 index 000000000000..96ec587e0182 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0600.rs @@ -0,0 +1,4 @@ +fn main() { + !"a"; // { dg-error ".E0600." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0601.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0601.rs new file mode 100644 index 000000000000..b8caf8ff5f2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0601.rs @@ -0,0 +1,2 @@ +// { dg-error ".E0601." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0602.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0602.rs new file mode 100644 index 000000000000..27be9ece528f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0602.rs @@ -0,0 +1,7 @@ +// compile-flags:-D bogus + +// error-pattern:E0602 +// error-pattern:requested on the command line with `-D bogus` + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0603.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0603.rs new file mode 100644 index 000000000000..1abb3ff162aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0603.rs @@ -0,0 +1,8 @@ +mod SomeModule { + const PRIVATE: u32 = 0x_a_bad_1dea_u32; +} + +fn main() { + SomeModule::PRIVATE; // { dg-error ".E0603." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0604.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0604.rs new file mode 100644 index 000000000000..d0620c0c12db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0604.rs @@ -0,0 +1,4 @@ +fn main() { + 1u32 as char; // { dg-error ".E0604." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0605.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0605.rs new file mode 100644 index 000000000000..317e7b557956 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0605.rs @@ -0,0 +1,8 @@ +fn main() { + let x = 0u8; + x as Vec; // { dg-error ".E0605." "" { target *-*-* } } + + let v = std::ptr::null::(); + v as &u8; // { dg-error ".E0605." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0606.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0606.rs new file mode 100644 index 000000000000..84d887f1affb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0606.rs @@ -0,0 +1,4 @@ +fn main() { + &0u8 as u8; // { dg-error ".E0606." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0607.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0607.rs new file mode 100644 index 000000000000..8f5090979f0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0607.rs @@ -0,0 +1,5 @@ +fn main() { + let v = core::ptr::null::(); + v as *const [u8]; // { dg-error ".E0607." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0608.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0608.rs new file mode 100644 index 000000000000..0713fa92ef11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0608.rs @@ -0,0 +1,4 @@ +fn main() { + 0u8[2]; // { dg-error ".E0608." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0609.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0609.rs new file mode 100644 index 000000000000..7431f9680e0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0609.rs @@ -0,0 +1,13 @@ +struct Foo { + x: u32, +} +struct Bar; + +fn main() { + let x = Foo { x: 0 }; + let _ = x.foo; // { dg-error ".E0609." "" { target *-*-* } } + + let y = Bar; + y.1; // { dg-error ".E0609." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0610.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0610.rs new file mode 100644 index 000000000000..783720a538db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0610.rs @@ -0,0 +1,5 @@ +fn main() { + let x = 0; + let _ = x.foo; // { dg-error ".E0610." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0614.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0614.rs new file mode 100644 index 000000000000..2411a8734f64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0614.rs @@ -0,0 +1,5 @@ +fn main() { + let y = 0u32; + *y; // { dg-error ".E0614." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0615.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0615.rs new file mode 100644 index 000000000000..014295603e28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0615.rs @@ -0,0 +1,13 @@ +struct Foo { + x: u32, +} + +impl Foo { + fn method(&self) {} +} + +fn main() { + let f = Foo { x: 0 }; + f.method; // { dg-error ".E0615." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0616.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0616.rs new file mode 100644 index 000000000000..43bef2d1dbcc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0616.rs @@ -0,0 +1,15 @@ +mod a { + pub struct Foo { + x: u32, + } + + impl Foo { + pub fn new() -> Foo { Foo { x: 0 } } + } +} + +fn main() { + let f = a::Foo::new(); + f.x; // { dg-error ".E0616." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0617.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0617.rs new file mode 100644 index 000000000000..7a0ce1ab4a32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0617.rs @@ -0,0 +1,27 @@ +extern { + fn printf(c: *const i8, ...); +} + +fn main() { + unsafe { + printf(::std::ptr::null(), 0f32); +// { dg-error ".E0617." "" { target *-*-* } .-1 } +// { help ".E0617." "" { target *-*-* } .-2 } + printf(::std::ptr::null(), 0i8); +// { dg-error ".E0617." "" { target *-*-* } .-1 } +// { help ".E0617." "" { target *-*-* } .-2 } + printf(::std::ptr::null(), 0i16); +// { dg-error ".E0617." "" { target *-*-* } .-1 } +// { help ".E0617." "" { target *-*-* } .-2 } + printf(::std::ptr::null(), 0u8); +// { dg-error ".E0617." "" { target *-*-* } .-1 } +// { help ".E0617." "" { target *-*-* } .-2 } + printf(::std::ptr::null(), 0u16); +// { dg-error ".E0617." "" { target *-*-* } .-1 } +// { help ".E0617." "" { target *-*-* } .-2 } + printf(::std::ptr::null(), printf); +// { dg-error ".E0617." "" { target *-*-* } .-1 } +// { help ".E0617." "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0618.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0618.rs new file mode 100644 index 000000000000..9d7039283ff7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0618.rs @@ -0,0 +1,12 @@ +enum X { + Entry, +} + +fn main() { + X::Entry(); +// { dg-error ".E0618." "" { target *-*-* } .-1 } + let x = 0i32; + x(); +// { dg-error ".E0618." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0620.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0620.rs new file mode 100644 index 000000000000..71219b0735d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0620.rs @@ -0,0 +1,4 @@ +fn main() { + let _foo = &[1_usize, 2] as [usize]; // { dg-error ".E0620." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0621-does-not-trigger-for-closures.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0621-does-not-trigger-for-closures.rs new file mode 100644 index 000000000000..dad9bbacc318 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0621-does-not-trigger-for-closures.rs @@ -0,0 +1,17 @@ +// Test that we give the generic error when one of the free regions is +// bound in a closure (rather than suggesting a change to the signature +// of the closure, which is not specified in `foo` but rather in `invoke`). + +fn invoke<'a, F>(x: &'a i32, f: F) -> &'a i32 +where F: FnOnce(&'a i32, &i32) -> &'a i32 +{ + let y = 22; + f(x, &y) +} + +fn foo<'a>(x: &'a i32) { + invoke(&x, |a, b| if a > b { a } else { b }); // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0622.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0622.rs new file mode 100644 index 000000000000..ab468732eb83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0622.rs @@ -0,0 +1,7 @@ +#![feature(intrinsics)] +extern "rust-intrinsic" { + pub static breakpoint : unsafe extern "rust-intrinsic" fn(); +// { dg-error ".E0622." "" { target *-*-* } .-1 } +} +fn main() { unsafe { breakpoint(); } } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0624.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0624.rs new file mode 100644 index 000000000000..b2426c6c1670 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0624.rs @@ -0,0 +1,13 @@ +mod inner { + pub struct Foo; + + impl Foo { + fn method(&self) {} + } +} + +fn main() { + let foo = inner::Foo; + foo.method(); // { dg-error ".E0624." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0637.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0637.rs new file mode 100644 index 000000000000..d906bd442ff7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0637.rs @@ -0,0 +1,10 @@ +struct Foo<'a: '_>(&'a u8); // { dg-error ".E0637." "" { target *-*-* } } +fn foo<'a: '_>(_: &'a u8) {} // { dg-error ".E0637." "" { target *-*-* } } + +struct Bar<'a>(&'a u8); +impl<'a: '_> Bar<'a> { // { dg-error ".E0637." "" { target *-*-* } } + fn bar() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0642.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0642.rs new file mode 100644 index 000000000000..7424911fd3e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0642.rs @@ -0,0 +1,21 @@ +// run-rustfix + +#![allow(unused)] // for rustfix + +#[derive(Clone, Copy)] +struct S; + +trait T { + fn foo((x, y): (i32, i32)); // { dg-error ".E0642." "" { target *-*-* } } + + fn bar((x, y): (i32, i32)) {} // { dg-error ".E0642." "" { target *-*-* } } + + fn method(S { .. }: S) {} // { dg-error ".E0642." "" { target *-*-* } } + + fn f(&ident: &S) {} // ok + fn g(&&ident: &&S) {} // ok + fn h(mut ident: S) {} // ok +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0646.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0646.rs new file mode 100644 index 000000000000..00cab1f1a4eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0646.rs @@ -0,0 +1,2 @@ +fn main() where (): Copy {} // { dg-error ".E0646." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0647.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0647.rs new file mode 100644 index 000000000000..3a3fdadb442f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0647.rs @@ -0,0 +1,10 @@ +#![no_std] +#![feature(start)] + +extern crate std; + +#[start] +fn start(_: isize, _: *const *const u8) -> isize where (): Copy { // { dg-error ".E0647." "" { target *-*-* } } + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0648.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0648.rs new file mode 100644 index 000000000000..4cab1dc1a92b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0648.rs @@ -0,0 +1,5 @@ +#[export_name="\0foo"] // { dg-error ".E0648." "" { target *-*-* } } +pub fn bar() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0657.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0657.rs new file mode 100644 index 000000000000..51d79f394ade --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0657.rs @@ -0,0 +1,27 @@ +#![allow(warnings)] + +trait Id {} +trait Lt<'a> {} + +impl<'a> Lt<'a> for () {} +impl Id for T {} + +fn free_fn_capture_hrtb_in_impl_trait() + -> Box Id>> +// { dg-error ".E0657." "" { target *-*-* } .-1 } +{ + Box::new(()) +} + +struct Foo; +impl Foo { + fn impl_fn_capture_hrtb_in_impl_trait() + -> Box Id>> +// { dg-error ".E0657." "" { target *-*-* } .-1 } + { + Box::new(()) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0658.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0658.rs new file mode 100644 index 000000000000..47c2b7ff1d04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0658.rs @@ -0,0 +1,7 @@ +#[repr(u128)] +enum Foo { // { dg-error ".E0658." "" { target *-*-* } } + Bar(u64), +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0659.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0659.rs new file mode 100644 index 000000000000..eff4c3f6d4c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0659.rs @@ -0,0 +1,17 @@ +mod moon { + pub fn foo() {} +} + +mod earth { + pub fn foo() {} +} + +mod collider { + pub use moon::*; + pub use earth::*; +} + +fn main() { + collider::foo(); // { dg-error ".E0659." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0660.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0660.rs new file mode 100644 index 000000000000..92265ea81d31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0660.rs @@ -0,0 +1,10 @@ +#![feature(llvm_asm)] + +fn main() { + let a; + llvm_asm!("nop" "nop"); +// { dg-error ".E0660." "" { target *-*-* } .-1 } + llvm_asm!("nop" "nop" : "=r"(a)); +// { dg-error ".E0660." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0661.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0661.rs new file mode 100644 index 000000000000..ac956e34aafb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0661.rs @@ -0,0 +1,10 @@ +// ignore-emscripten + +#![feature(llvm_asm)] + +fn main() { + let a; // { dg-error ".E0282." "" { target *-*-* } } + llvm_asm!("nop" : "r"(a)); +// { dg-error ".E0661." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0662.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0662.rs new file mode 100644 index 000000000000..40e527abc10a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0662.rs @@ -0,0 +1,11 @@ +// ignore-emscripten + +#![feature(llvm_asm)] + +fn main() { + llvm_asm!("xor %eax, %eax" + : + : "=test"("a") // { dg-error ".E0662." "" { target *-*-* } } + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0663.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0663.rs new file mode 100644 index 000000000000..a73fd3fe0320 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0663.rs @@ -0,0 +1,11 @@ +// ignore-emscripten + +#![feature(llvm_asm)] + +fn main() { + llvm_asm!("xor %eax, %eax" + : + : "+test"("a") // { dg-error ".E0663." "" { target *-*-* } } + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0664.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0664.rs new file mode 100644 index 000000000000..ccb14d024622 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0664.rs @@ -0,0 +1,12 @@ +// ignore-emscripten + +#![feature(llvm_asm)] + +fn main() { + llvm_asm!("mov $$0x200, %eax" + : + : + : "{eax}" // { dg-error ".E0664." "" { target *-*-* } } + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0665.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0665.rs new file mode 100644 index 000000000000..c8d8449743e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0665.rs @@ -0,0 +1,9 @@ +#[derive(Default)] // { dg-error ".E0665." "" { target *-*-* } } +enum Food { + Sweet, + Salty, +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0705.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0705.rs new file mode 100644 index 000000000000..0e35a02bf01b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0705.rs @@ -0,0 +1,11 @@ +// check-pass + +// This is a stub feature that doesn't control anything, so to make tidy happy, +// gate-test-test_2018_feature + +#![feature(test_2018_feature)] +// { dg-warning "" "" { target *-*-* } .-1 } +#![feature(rust_2018_preview)] + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0718.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0718.rs new file mode 100644 index 000000000000..9526455ef3aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0718.rs @@ -0,0 +1,8 @@ +#![feature(lang_items)] + +// Box is expected to be a struct, so this will error. +#[lang = "owned_box"] // { dg-error ".E0718." "" { target *-*-* } } +static X: u32 = 42; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0719.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0719.rs new file mode 100644 index 000000000000..1547565ffa0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0719.rs @@ -0,0 +1,15 @@ +trait Foo: Iterator {} +// { dg-error ".E0719." "" { target *-*-* } .-1 } + +type Unit = (); + +fn test() -> Box> { +// { dg-error ".E0719." "" { target *-*-* } .-1 } + Box::new(None.into_iter()) +} + +fn main() { + let _: &dyn Iterator; + test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0730.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0730.rs new file mode 100644 index 000000000000..7d5ee87290aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0730.rs @@ -0,0 +1,12 @@ +#![feature(const_generics)] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn is_123(x: [u32; N]) -> bool { + match x { + [1, 2, ..] => true, // { dg-error ".E0730." "" { target *-*-* } } + _ => false + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0746.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0746.rs new file mode 100644 index 000000000000..57950743e37a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0746.rs @@ -0,0 +1,19 @@ +// run-rustfix +#![allow(dead_code)] +struct Struct; +trait Trait {} +impl Trait for Struct {} +impl Trait for u32 {} + +fn foo() -> dyn Trait { Struct } +// { dg-error ".E0746." "" { target *-*-* } .-1 } + +fn bar() -> dyn Trait { // { dg-error ".E0746." "" { target *-*-* } } + if true { + return 0; + } + 42 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0767.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0767.rs new file mode 100644 index 000000000000..b4c47e923f2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0767.rs @@ -0,0 +1,8 @@ +fn main () { + 'a: loop { + || { + loop { break 'a; } // { dg-error ".E0767." "" { target *-*-* } } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0771.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0771.rs new file mode 100644 index 000000000000..2819134da72b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0771.rs @@ -0,0 +1,9 @@ +#![feature(const_generics)] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn function_with_str<'a, const STRING: &'a str>() {} // { dg-error ".E0771." "" { target *-*-* } } + +fn main() { + function_with_str::<"Hello, world!">() +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0777.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0777.rs new file mode 100644 index 000000000000..2e252c70f36b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0777.rs @@ -0,0 +1,8 @@ +#[derive("Clone")] // { dg-error ".E0777." "" { target *-*-* } } +#[derive("Clone +")] +// { dg-error ".E0777." "" { target *-*-* } .-2 } +struct Foo; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0778.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0778.rs new file mode 100644 index 000000000000..24b7532b0a41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0778.rs @@ -0,0 +1,9 @@ +#![feature(isa_attribute)] + +#[instruction_set()] // { dg-error ".E0778." "" { target *-*-* } } +fn no_isa_defined() { +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/E0779.rs b/gcc/testsuite/rust/rustc/ui/error-codes/E0779.rs new file mode 100644 index 000000000000..7c72f148efa1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/E0779.rs @@ -0,0 +1,7 @@ +#![feature(isa_attribute)] + +#[instruction_set(arm::magic)] // { dg-error ".E0779." "" { target *-*-* } } +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/e0119/auxiliary/complex_impl_support.rs b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/auxiliary/complex_impl_support.rs new file mode 100644 index 000000000000..3dcfca89c48c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/auxiliary/complex_impl_support.rs @@ -0,0 +1,23 @@ +use std::marker::PhantomData; + +pub trait External {} + +pub struct M<'a, 'b, 'c, T, U, V> { + a: PhantomData<&'a ()>, + b: PhantomData<&'b ()>, + c: PhantomData<&'c ()>, + d: PhantomData, + e: PhantomData, + f: PhantomData, +} + +impl<'a, 'b, 'c, T, U, V, W> External for (T, M<'a, 'b, 'c, Box, V, W>) +where + 'b: 'a, + T: 'a, + U: (FnOnce(T) -> V) + 'static, + V: Iterator + Clone, + W: std::ops::Add, + W::Output: Copy, +{} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/e0119/auxiliary/issue-23563-a.rs b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/auxiliary/issue-23563-a.rs new file mode 100644 index 000000000000..0406727f3095 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/auxiliary/issue-23563-a.rs @@ -0,0 +1,26 @@ +// Ref: https://github.com/rust-lang/rust/issues/23563#issuecomment-260751672 + +pub trait LolTo { + fn convert_to(&self) -> T; +} + +pub trait LolInto: Sized { + fn convert_into(self) -> T; +} + +pub trait LolFrom { + fn from(_: T) -> Self; +} + +impl<'a, T: ?Sized, U> LolInto for &'a T where T: LolTo { + fn convert_into(self) -> U { + self.convert_to() + } +} + +impl LolFrom for U where T: LolInto { + fn from(t: T) -> U { + t.convert_into() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/e0119/complex-impl.rs b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/complex-impl.rs new file mode 100644 index 000000000000..251034d7babb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/complex-impl.rs @@ -0,0 +1,13 @@ +// aux-build:complex_impl_support.rs + +extern crate complex_impl_support; + +use complex_impl_support::{External, M}; + +struct Q; + +impl External for (Q, R) {} // { dg-error ".E0117." "" { target *-*-* } } +// { dg-error ".E0117." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/e0119/conflict-with-std.rs b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/conflict-with-std.rs new file mode 100644 index 000000000000..cff4347c7fc4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/conflict-with-std.rs @@ -0,0 +1,27 @@ +use std::marker::PhantomData; +use std::convert::{TryFrom, AsRef}; + +struct Q; +impl AsRef for Box { // { dg-error ".E0119." "" { target *-*-* } } + fn as_ref(&self) -> &Q { + &**self + } +} + +struct S; +impl From for S { // { dg-error ".E0119." "" { target *-*-* } } + fn from(s: S) -> S { + s + } +} + +struct X; +impl TryFrom for X { // { dg-error ".E0119." "" { target *-*-* } } + type Error = (); + fn try_from(u: X) -> Result { + Ok(u) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/e0119/issue-23563.rs b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/issue-23563.rs new file mode 100644 index 000000000000..b07666cc4c8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/issue-23563.rs @@ -0,0 +1,30 @@ +// aux-build:issue-23563-a.rs + +// Ref: https://github.com/rust-lang/rust/issues/23563#issuecomment-260751672 + +extern crate issue_23563_a as a; + +use a::LolFrom; +use a::LolInto; +use a::LolTo; + +struct LocalType(Option); + +impl<'a, T> LolFrom<&'a [T]> for LocalType { // { dg-error ".E0119." "" { target *-*-* } } + fn from(_: &'a [T]) -> LocalType { LocalType(None) } +} + +impl LolInto> for LocalType { + fn convert_into(self) -> LocalType { + self + } +} + +impl LolTo> for [u8] { + fn convert_to(&self) -> LocalType { + LocalType(None) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/e0119/issue-27403.rs b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/issue-27403.rs new file mode 100644 index 000000000000..9031972f93a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/issue-27403.rs @@ -0,0 +1,12 @@ +pub struct GenX { + inner: S, +} + +impl Into for GenX { // { dg-error ".E0119." "" { target *-*-* } } + fn into(self) -> S { + self.inner + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/e0119/issue-28981.rs b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/issue-28981.rs new file mode 100644 index 000000000000..60086e481b97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/issue-28981.rs @@ -0,0 +1,9 @@ +use std::ops::Deref; + +struct Foo; + +impl Deref for Foo { } // { dg-error ".E0210." "" { target *-*-* } } +// { dg-error ".E0210." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/e0119/so-37347311.rs b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/so-37347311.rs new file mode 100644 index 000000000000..cf781dc454eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/e0119/so-37347311.rs @@ -0,0 +1,18 @@ +// Ref: https://stackoverflow.com/q/37347311 + +trait Storage { + type Error; +} + +enum MyError { + StorageProblem(S::Error), +} + +impl From for MyError { // { dg-error ".E0119." "" { target *-*-* } } + fn from(error: S::Error) -> MyError { + MyError::StorageProblem(error) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/ex-E0611.rs b/gcc/testsuite/rust/rustc/ui/error-codes/ex-E0611.rs new file mode 100644 index 000000000000..45815220a1f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/ex-E0611.rs @@ -0,0 +1,13 @@ +mod a { + pub struct Foo(u32); + + impl Foo { + pub fn new() -> Foo { Foo(0) } + } +} + +fn main() { + let y = a::Foo::new(); + y.0; // { dg-error ".E0616." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-codes/ex-E0612.rs b/gcc/testsuite/rust/rustc/ui/error-codes/ex-E0612.rs new file mode 100644 index 000000000000..8100e876b30c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-codes/ex-E0612.rs @@ -0,0 +1,7 @@ +struct Foo(u32); + +fn main() { + let y = Foo(0); + y.1; // { dg-error ".E0609." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-festival.rs b/gcc/testsuite/rust/rustc/ui/error-festival.rs new file mode 100644 index 000000000000..d4adb61353c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-festival.rs @@ -0,0 +1,44 @@ +enum Question { + Yes, + No, +} + +mod foo { + const FOO: u32 = 0; +} + +fn main() { + let x = "a"; + x += 2; +// { dg-error ".E0368." "" { target *-*-* } .-1 } + y = 2; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + x.z(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + + !Question::Yes; +// { dg-error ".E0600." "" { target *-*-* } .-1 } + + foo::FOO; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + + 0u32 as char; +// { dg-error ".E0604." "" { target *-*-* } .-1 } + + let x = 0u8; + x as Vec; +// { dg-error ".E0605." "" { target *-*-* } .-1 } + + let x = 5; + let x_is_nonzero = x as bool; +// { dg-error ".E0054." "" { target *-*-* } .-1 } + + let x = &0u8; + let y: u32 = x as u32; +// { dg-error ".E0606." "" { target *-*-* } .-1 } + + let v = core::ptr::null::(); + v as *const [u8]; +// { dg-error ".E0607." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/error-should-say-copy-not-pod.rs b/gcc/testsuite/rust/rustc/ui/error-should-say-copy-not-pod.rs new file mode 100644 index 000000000000..700393bdaea8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/error-should-say-copy-not-pod.rs @@ -0,0 +1,8 @@ +// Tests that the error message uses the word Copy, not Pod. + +fn check_bound(_: T) {} + +fn main() { + check_bound("nocopy".to_string()); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/estr-subtyping.rs b/gcc/testsuite/rust/rustc/ui/estr-subtyping.rs new file mode 100644 index 000000000000..187ddce90f00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/estr-subtyping.rs @@ -0,0 +1,16 @@ +fn wants_uniq(x: String) { } +fn wants_slice(x: &str) { } + +fn has_uniq(x: String) { + wants_uniq(x); + wants_slice(&*x); +} + +fn has_slice(x: &str) { + wants_uniq(x); // { dg-error ".E0308." "" { target *-*-* } } + wants_slice(x); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/estr-uniq.rs b/gcc/testsuite/rust/rustc/ui/estr-uniq.rs new file mode 100644 index 000000000000..9eb03d727ebe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/estr-uniq.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(unused_assignments)] +#![allow(unknown_lints)] + +#![allow(dead_assignment)] + +pub fn main() { + let x : String = "hello".to_string(); + let _y : String = "there".to_string(); + let mut z = "thing".to_string(); + z = x; + assert_eq!(z.as_bytes()[0], ('h' as u8)); + assert_eq!(z.as_bytes()[4], ('o' as u8)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/eval-enum.rs b/gcc/testsuite/rust/rustc/ui/eval-enum.rs new file mode 100644 index 000000000000..e0509103ee36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/eval-enum.rs @@ -0,0 +1,11 @@ +enum Test { + DivZero = 1/0, +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } + RemZero = 1%0, +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/exclusive-drop-and-copy.rs b/gcc/testsuite/rust/rustc/ui/exclusive-drop-and-copy.rs new file mode 100644 index 000000000000..d4e1e81da770 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/exclusive-drop-and-copy.rs @@ -0,0 +1,18 @@ +// issue #20126 + +#[derive(Copy, Clone)] // { dg-error ".E0184." "" { target *-*-* } } +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) {} +} + +#[derive(Copy, Clone)] // { dg-error ".E0184." "" { target *-*-* } } +struct Bar(::std::marker::PhantomData); + +impl Drop for Bar { + fn drop(&mut self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/exec-env.rs b/gcc/testsuite/rust/rustc/ui/exec-env.rs new file mode 100644 index 000000000000..cb3b80e34f60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/exec-env.rs @@ -0,0 +1,12 @@ +// run-pass +// exec-env:TEST_EXEC_ENV=22 +// ignore-cloudabi no env vars +// ignore-emscripten FIXME: issue #31622 +// ignore-sgx unsupported + +use std::env; + +pub fn main() { + assert_eq!(env::var("TEST_EXEC_ENV"), Ok("22".to_string())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/expanded-cfg.rs b/gcc/testsuite/rust/rustc/ui/expanded-cfg.rs new file mode 100644 index 000000000000..e7682b59e292 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expanded-cfg.rs @@ -0,0 +1,22 @@ +// check-pass + +macro_rules! mac { + {} => { + #[cfg(attr)] + mod m { + #[lang_item] + fn f() {} + + #[cfg_attr(target_thread_local, custom)] + fn g() {} + } + + #[cfg(attr)] + unconfigured_invocation!(); + } +} + +mac! {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/explain.rs b/gcc/testsuite/rust/rustc/ui/explain.rs new file mode 100644 index 000000000000..3a4c755f249e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/explain.rs @@ -0,0 +1,3 @@ +// compile-flags: --explain E0591 +// check-pass + diff --git a/gcc/testsuite/rust/rustc/ui/explicit-i-suffix.rs b/gcc/testsuite/rust/rustc/ui/explicit-i-suffix.rs new file mode 100644 index 000000000000..d8e227799762 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/explicit-i-suffix.rs @@ -0,0 +1,15 @@ +// run-pass + +#![allow(unused_must_use)] +// pretty-expanded FIXME #23616 + +pub fn main() { + let x: isize = 8; + let y = 9; + x + y; + + let q: isize = -8; + let r = -9; + q + r; +} + diff --git a/gcc/testsuite/rust/rustc/ui/explicit/explicit-call-to-dtor.rs b/gcc/testsuite/rust/rustc/ui/explicit/explicit-call-to-dtor.rs new file mode 100644 index 000000000000..3154163e2eba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/explicit/explicit-call-to-dtor.rs @@ -0,0 +1,15 @@ +struct Foo { + x: isize +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("kaboom"); + } +} + +fn main() { + let x = Foo { x: 3 }; + x.drop(); // { dg-error ".E0040." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/explicit/explicit-call-to-supertrait-dtor.rs b/gcc/testsuite/rust/rustc/ui/explicit/explicit-call-to-supertrait-dtor.rs new file mode 100644 index 000000000000..0c45b8d45fdf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/explicit/explicit-call-to-supertrait-dtor.rs @@ -0,0 +1,24 @@ +struct Foo { + x: isize +} + +trait Bar : Drop { + fn blah(&self); +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("kaboom"); + } +} + +impl Bar for Foo { + fn blah(&self) { + self.drop(); // { dg-error ".E0040." "" { target *-*-* } } + } +} + +fn main() { + let x = Foo { x: 3 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/explicit/explicit-self-lifetime-mismatch.rs b/gcc/testsuite/rust/rustc/ui/explicit/explicit-self-lifetime-mismatch.rs new file mode 100644 index 000000000000..add0befc5d1e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/explicit/explicit-self-lifetime-mismatch.rs @@ -0,0 +1,21 @@ +struct Foo<'a,'b> { + x: &'a isize, + y: &'b isize, +} + +impl<'a,'b> Foo<'a,'b> { + fn bar(self: + Foo<'b,'a> +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } +// { dg-error ".E0308." "" { target *-*-* } .-6 } +// { dg-error ".E0308." "" { target *-*-* } .-7 } +// { dg-error ".E0308." "" { target *-*-* } .-8 } + ) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/explore-issue-38412.rs b/gcc/testsuite/rust/rustc/ui/explore-issue-38412.rs new file mode 100644 index 000000000000..75eb50d1e41c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/explore-issue-38412.rs @@ -0,0 +1,67 @@ +// aux-build:pub-and-stability.rs + +#![feature(unused_feature)] + +// A big point of this test is that we *declare* `unstable_declared`, +// but do *not* declare `unstable_undeclared`. This way we can check +// that the compiler is letting in uses of declared feature-gated +// stuff but still rejecting uses of undeclared feature-gated stuff. +#![feature(unstable_declared)] + +extern crate pub_and_stability; +use pub_and_stability::{Record, Trait, Tuple}; + +fn main() { + // Okay + let Record { .. } = Record::new(); + + // Okay + let Record { a_stable_pub: _, a_unstable_declared_pub: _, .. } = Record::new(); + + let Record { a_stable_pub: _, a_unstable_declared_pub: _, a_unstable_undeclared_pub: _, .. } = + Record::new(); +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + let r = Record::new(); + let t = Tuple::new(); + + r.a_stable_pub; + r.a_unstable_declared_pub; + r.a_unstable_undeclared_pub; // { dg-error ".E0658." "" { target *-*-* } } + r.b_crate; // { dg-error ".E0616." "" { target *-*-* } } + r.c_mod; // { dg-error ".E0616." "" { target *-*-* } } + r.d_priv; // { dg-error ".E0616." "" { target *-*-* } } + + t.0; + t.1; + t.2; // { dg-error ".E0658." "" { target *-*-* } } + t.3; // { dg-error ".E0616." "" { target *-*-* } } + t.4; // { dg-error ".E0616." "" { target *-*-* } } + t.5; // { dg-error ".E0616." "" { target *-*-* } } + + r.stable_trait_method(); + r.unstable_declared_trait_method(); + r.unstable_undeclared_trait_method(); // { dg-error ".E0658." "" { target *-*-* } } + + r.stable(); + r.unstable_declared(); + r.unstable_undeclared(); // { dg-error ".E0658." "" { target *-*-* } } + + r.pub_crate(); // { dg-error ".E0624." "" { target *-*-* } } + r.pub_mod(); // { dg-error ".E0624." "" { target *-*-* } } + r.private(); // { dg-error ".E0624." "" { target *-*-* } } + + let t = Tuple::new(); + t.stable_trait_method(); + t.unstable_declared_trait_method(); + t.unstable_undeclared_trait_method(); // { dg-error ".E0658." "" { target *-*-* } } + + t.stable(); + t.unstable_declared(); + t.unstable_undeclared(); // { dg-error ".E0658." "" { target *-*-* } } + + t.pub_crate(); // { dg-error ".E0624." "" { target *-*-* } } + t.pub_mod(); // { dg-error ".E0624." "" { target *-*-* } } + t.private(); // { dg-error ".E0624." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/export-fully-qualified.rs b/gcc/testsuite/rust/rustc/ui/export-fully-qualified.rs new file mode 100644 index 000000000000..ee4c373a73cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/export-fully-qualified.rs @@ -0,0 +1,14 @@ +// ignore-tidy-linelength + +// In this test baz isn't resolved when called as foo.baz even though +// it's called from inside foo. This is somewhat surprising and may +// want to change eventually. + +mod foo { + pub fn bar() { foo::baz(); } // { dg-error ".E0433." "" { target *-*-* } } + + fn baz() { } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/export-glob-imports-target.rs b/gcc/testsuite/rust/rustc/ui/export-glob-imports-target.rs new file mode 100644 index 000000000000..bf820408a6d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/export-glob-imports-target.rs @@ -0,0 +1,23 @@ +// run-pass + +#![allow(non_upper_case_globals)] +#![allow(dead_code)] +// Test that a glob-export functions as an import +// when referenced within its own local scope. + +// Modified to not use export since it's going away. --pcw + +// pretty-expanded FIXME #23616 + +mod foo { + use foo::bar::*; + pub mod bar { + pub static a : isize = 10; + } + pub fn zum() { + let _b = a; + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/export-import.rs b/gcc/testsuite/rust/rustc/ui/export-import.rs new file mode 100644 index 000000000000..909cc96140f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/export-import.rs @@ -0,0 +1,12 @@ +use m::unexported; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + +mod m { + pub fn exported() { } + + fn unexported() { } +} + + +fn main() { unexported(); } + diff --git a/gcc/testsuite/rust/rustc/ui/export-multi.rs b/gcc/testsuite/rust/rustc/ui/export-multi.rs new file mode 100644 index 000000000000..aa6cf065cead --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/export-multi.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +use m::f; +use m::g; + +mod m { + pub fn f() { } + pub fn g() { } +} + +pub fn main() { f(); g(); m::f(); m::g(); } + diff --git a/gcc/testsuite/rust/rustc/ui/export-non-interference2.rs b/gcc/testsuite/rust/rustc/ui/export-non-interference2.rs new file mode 100644 index 000000000000..1deb285a7516 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/export-non-interference2.rs @@ -0,0 +1,12 @@ +// run-pass + +mod foo { + pub mod bar { + pub fn y() { super::super::foo::x(); } + } + + pub fn x() { println!("x"); } +} + +pub fn main() { self::foo::bar::y(); } + diff --git a/gcc/testsuite/rust/rustc/ui/export-non-interference3.rs b/gcc/testsuite/rust/rustc/ui/export-non-interference3.rs new file mode 100644 index 000000000000..ad86b92ff3dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/export-non-interference3.rs @@ -0,0 +1,12 @@ +// run-pass + +pub mod foo { + pub fn x() { ::bar::x(); } +} + +pub mod bar { + pub fn x() { println!("x"); } +} + +pub fn main() { foo::x(); } + diff --git a/gcc/testsuite/rust/rustc/ui/export-tag-variant.rs b/gcc/testsuite/rust/rustc/ui/export-tag-variant.rs new file mode 100644 index 000000000000..400cbf273c1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/export-tag-variant.rs @@ -0,0 +1,8 @@ +mod foo { + pub fn x() { } + + enum Y { Y1 } +} + +fn main() { let z = foo::Y::Y1; } // { dg-error ".E0603." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/export.rs b/gcc/testsuite/rust/rustc/ui/export.rs new file mode 100644 index 000000000000..88e71da20f8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/export.rs @@ -0,0 +1,11 @@ +mod foo { + pub fn x(y: isize) { log(debug, y); } +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { dg-error ".E0425." "" { target *-*-* } .-2 } + fn z(y: isize) { log(debug, y); } +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { dg-error ".E0425." "" { target *-*-* } .-2 } +} + +fn main() { foo::z(10); } // { dg-error ".E0603." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/export2.rs b/gcc/testsuite/rust/rustc/ui/export2.rs new file mode 100644 index 000000000000..b829a0a64eed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/export2.rs @@ -0,0 +1,12 @@ +mod foo { + pub fn x() { bar::x(); } // { dg-error ".E0433." "" { target *-*-* } } +} + +mod bar { + fn x() { println!("x"); } + + pub fn y() { } +} + +fn main() { foo::x(); } + diff --git a/gcc/testsuite/rust/rustc/ui/expr-block-fn.rs b/gcc/testsuite/rust/rustc/ui/expr-block-fn.rs new file mode 100644 index 000000000000..d5c1e3fa6496 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-block-fn.rs @@ -0,0 +1,10 @@ +// run-pass + +fn test_fn() { + fn ten() -> isize { return 10; } + let rs = ten; + assert_eq!(rs(), 10); +} + +pub fn main() { test_fn(); } + diff --git a/gcc/testsuite/rust/rustc/ui/expr-block-generic-unique1.rs b/gcc/testsuite/rust/rustc/ui/expr-block-generic-unique1.rs new file mode 100644 index 000000000000..72bd1a14fcf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-block-generic-unique1.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(unused_braces)] +#![feature(box_syntax)] + +fn test_generic(expected: Box, eq: F) where T: Clone, F: FnOnce(Box, Box) -> bool { + let actual: Box = { expected.clone() }; + assert!(eq(expected, actual)); +} + +fn test_box() { + fn compare_box(b1: Box, b2: Box) -> bool { + println!("{}", *b1); + println!("{}", *b2); + return *b1 == *b2; + } + test_generic::(box true, compare_box); +} + +pub fn main() { test_box(); } + diff --git a/gcc/testsuite/rust/rustc/ui/expr-block-generic-unique2.rs b/gcc/testsuite/rust/rustc/ui/expr-block-generic-unique2.rs new file mode 100644 index 000000000000..f23fe0fc2464 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-block-generic-unique2.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(unused_braces)] +#![feature(box_syntax)] + +fn test_generic(expected: T, eq: F) where T: Clone, F: FnOnce(T, T) -> bool { + let actual: T = { expected.clone() }; + assert!(eq(expected, actual)); +} + +fn test_vec() { + fn compare_vec(v1: Box, v2: Box) -> bool { return v1 == v2; } + test_generic::, _>(box 1, compare_vec); +} + +pub fn main() { test_vec(); } + diff --git a/gcc/testsuite/rust/rustc/ui/expr-block-generic.rs b/gcc/testsuite/rust/rustc/ui/expr-block-generic.rs new file mode 100644 index 000000000000..39580796d5b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-block-generic.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(unused_braces)] + +fn test_generic(expected: T, eq: F) where F: FnOnce(T, T) -> bool { + let actual: T = { expected.clone() }; + assert!(eq(expected, actual)); +} + +fn test_bool() { + fn compare_bool(b1: bool, b2: bool) -> bool { return b1 == b2; } + test_generic::(true, compare_bool); +} + +#[derive(Clone)] +struct Pair { + a: isize, + b: isize, +} + +fn test_rec() { + fn compare_rec(t1: Pair, t2: Pair) -> bool { + t1.a == t2.a && t1.b == t2.b + } + test_generic::(Pair {a: 1, b: 2}, compare_rec); +} + +pub fn main() { test_bool(); test_rec(); } + diff --git a/gcc/testsuite/rust/rustc/ui/expr-block-slot.rs b/gcc/testsuite/rust/rustc/ui/expr-block-slot.rs new file mode 100644 index 000000000000..7b7e95367271 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-block-slot.rs @@ -0,0 +1,14 @@ +// run-pass +// Regression test for issue #377 + + +struct A { a: isize } +struct V { v: isize } + +pub fn main() { + let a = { let b = A {a: 3}; b }; + assert_eq!(a.a, 3); + let c = { let d = V {v: 3}; d }; + assert_eq!(c.v, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/expr-block-unique.rs b/gcc/testsuite/rust/rustc/ui/expr-block-unique.rs new file mode 100644 index 000000000000..e6385417dc8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-block-unique.rs @@ -0,0 +1,6 @@ +// run-pass +#![allow(unused_braces)] +#![feature(box_syntax)] + +pub fn main() { let x: Box<_> = { box 100 }; assert_eq!(*x, 100); } + diff --git a/gcc/testsuite/rust/rustc/ui/expr-block.rs b/gcc/testsuite/rust/rustc/ui/expr-block.rs new file mode 100644 index 000000000000..dc2c272a2a7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-block.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_braces)] +#![allow(dead_code)] + +// Tests for standalone blocks as expressions + +fn test_basic() { let rs: bool = { true }; assert!((rs)); } + +struct RS { v1: isize, v2: isize } + +fn test_rec() { let rs = { RS {v1: 10, v2: 20} }; assert_eq!(rs.v2, 20); } + +fn test_filled_with_stuff() { + let rs = { let mut a = 0; while a < 10 { a += 1; } a }; + assert_eq!(rs, 10); +} + +pub fn main() { test_basic(); test_rec(); test_filled_with_stuff(); } + diff --git a/gcc/testsuite/rust/rustc/ui/expr-copy.rs b/gcc/testsuite/rust/rustc/ui/expr-copy.rs new file mode 100644 index 000000000000..04c161da19ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-copy.rs @@ -0,0 +1,19 @@ +// run-pass + +fn f(arg: &mut A) { + arg.a = 100; +} + +#[derive(Copy, Clone)] +struct A { a: isize } + +pub fn main() { + let mut x = A {a: 10}; + f(&mut x); + assert_eq!(x.a, 100); + x.a = 20; + let mut y = x; + f(&mut y); + assert_eq!(x.a, 20); +} + diff --git a/gcc/testsuite/rust/rustc/ui/expr-empty-ret.rs b/gcc/testsuite/rust/rustc/ui/expr-empty-ret.rs new file mode 100644 index 000000000000..56c85d597de0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-empty-ret.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(dead_code)] +// Issue #521 + +// pretty-expanded FIXME #23616 + +fn f() { + let _x = match true { + true => { 10 } + false => { return } + }; +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/expr-fn.rs b/gcc/testsuite/rust/rustc/ui/expr-fn.rs new file mode 100644 index 000000000000..06445ecd9f77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-fn.rs @@ -0,0 +1,63 @@ +// run-pass +#![allow(unused_braces)] + +fn test_int() { + fn f() -> isize { 10 } + assert_eq!(f(), 10); +} + +fn test_vec() { + fn f() -> Vec { vec![10, 11] } + let vect = f(); + assert_eq!(vect[1], 11); +} + +fn test_generic() { + fn f(t: T) -> T { t } + assert_eq!(f(10), 10); +} + +fn test_alt() { + fn f() -> isize { match true { false => { 10 } true => { 20 } } } + assert_eq!(f(), 20); +} + +fn test_if() { + fn f() -> isize { if true { 10 } else { 20 } } + assert_eq!(f(), 10); +} + +fn test_block() { + fn f() -> isize { { 10 } } + assert_eq!(f(), 10); +} + +fn test_ret() { + fn f() -> isize { + return 10 // no semi + + } + assert_eq!(f(), 10); +} + + +// From issue #372 +fn test_372() { + fn f() -> isize { let x = { 3 }; x } + assert_eq!(f(), 3); +} + +fn test_nil() { () } + +pub fn main() { + test_int(); + test_vec(); + test_generic(); + test_alt(); + test_if(); + test_block(); + test_ret(); + test_372(); + test_nil(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/expr-if-generic.rs b/gcc/testsuite/rust/rustc/ui/expr-if-generic.rs new file mode 100644 index 000000000000..264e53c937ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-if-generic.rs @@ -0,0 +1,30 @@ +// run-pass + +fn test_generic(expected: T, not_expected: T, eq: F) where + T: Clone, + F: FnOnce(T, T) -> bool, +{ + let actual: T = if true { expected.clone() } else { not_expected }; + assert!(eq(expected, actual)); +} + +fn test_bool() { + fn compare_bool(b1: bool, b2: bool) -> bool { return b1 == b2; } + test_generic::(true, false, compare_bool); +} + +#[derive(Clone)] +struct Pair { + a: isize, + b: isize, +} + +fn test_rec() { + fn compare_rec(t1: Pair, t2: Pair) -> bool { + t1.a == t2.a && t1.b == t2.b + } + test_generic::(Pair{a: 1, b: 2}, Pair{a: 2, b: 3}, compare_rec); +} + +pub fn main() { test_bool(); test_rec(); } + diff --git a/gcc/testsuite/rust/rustc/ui/expr-if-panic-all.rs b/gcc/testsuite/rust/rustc/ui/expr-if-panic-all.rs new file mode 100644 index 000000000000..d9c7d7ad1b70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-if-panic-all.rs @@ -0,0 +1,12 @@ +// run-pass +// When all branches of an if expression result in panic, the entire if +// expression results in panic. + +pub fn main() { + let _x = if true { + 10 + } else { + if true { panic!() } else { panic!() } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/expr-if-panic.rs b/gcc/testsuite/rust/rustc/ui/expr-if-panic.rs new file mode 100644 index 000000000000..438052647083 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-if-panic.rs @@ -0,0 +1,19 @@ +// run-pass + +fn test_if_panic() { + let x = if false { panic!() } else { 10 }; + assert_eq!(x, 10); +} + +fn test_else_panic() { + let x = if true { 10 } else { panic!() }; + assert_eq!(x, 10); +} + +fn test_elseif_panic() { + let x = if false { 0 } else if false { panic!() } else { 10 }; + assert_eq!(x, 10); +} + +pub fn main() { test_if_panic(); test_else_panic(); test_elseif_panic(); } + diff --git a/gcc/testsuite/rust/rustc/ui/expr-if-unique.rs b/gcc/testsuite/rust/rustc/ui/expr-if-unique.rs new file mode 100644 index 000000000000..1c7f96f409a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-if-unique.rs @@ -0,0 +1,12 @@ +// run-pass + +#![feature(box_syntax)] + +// Tests for if as expressions returning boxed types +fn test_box() { + let rs: Box<_> = if true { box 100 } else { box 101 }; + assert_eq!(*rs, 100); +} + +pub fn main() { test_box(); } + diff --git a/gcc/testsuite/rust/rustc/ui/expr-if.rs b/gcc/testsuite/rust/rustc/ui/expr-if.rs new file mode 100644 index 000000000000..347f9d5dc3b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-if.rs @@ -0,0 +1,53 @@ +// run-pass +// Tests for if as expressions + +fn test_if() { let rs: bool = if true { true } else { false }; assert!((rs)); } + +fn test_else() { + let rs: bool = if false { false } else { true }; + assert!((rs)); +} + +fn test_elseif1() { + let rs: bool = if true { true } else if true { false } else { false }; + assert!((rs)); +} + +fn test_elseif2() { + let rs: bool = if false { false } else if true { true } else { false }; + assert!((rs)); +} + +fn test_elseif3() { + let rs: bool = if false { false } else if false { false } else { true }; + assert!((rs)); +} + +fn test_inferrence() { + let rs = if true { true } else { false }; + assert!((rs)); +} + +fn test_if_as_if_condition() { + let rs1 = if if false { false } else { true } { true } else { false }; + assert!((rs1)); + let rs2 = if if true { false } else { true } { false } else { true }; + assert!((rs2)); +} + +fn test_if_as_block_result() { + let rs = if true { if false { false } else { true } } else { false }; + assert!((rs)); +} + +pub fn main() { + test_if(); + test_else(); + test_elseif1(); + test_elseif2(); + test_elseif3(); + test_inferrence(); + test_if_as_if_condition(); + test_if_as_block_result(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/expr-scope.rs b/gcc/testsuite/rust/rustc/ui/expr-scope.rs new file mode 100644 index 000000000000..5964f76bed6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr-scope.rs @@ -0,0 +1,8 @@ +// run-pass +// Regression test for issue #762 + +// pretty-expanded FIXME #23616 + +pub fn f() { } +pub fn main() { return ::f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/expr_attr_paren_order.rs b/gcc/testsuite/rust/rustc/ui/expr_attr_paren_order.rs new file mode 100644 index 000000000000..e158d3d6430f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/expr_attr_paren_order.rs @@ -0,0 +1,25 @@ +#![feature(stmt_expr_attributes)] + +fn main() { + + // Test that attributes on parens get concatenated + // in the expected order in the hir folder. + + #[deny(non_snake_case)] ( + #![allow(non_snake_case)] + { + let X = 0; + let _ = X; + } + ); + + #[allow(non_snake_case)] ( + #![deny(non_snake_case)] + { + let X = 0; // { dg-error "" "" { target *-*-* } } + let _ = X; + } + ); + +} + diff --git a/gcc/testsuite/rust/rustc/ui/ext-expand-inner-exprs.rs b/gcc/testsuite/rust/rustc/ui/ext-expand-inner-exprs.rs new file mode 100644 index 000000000000..bf32bc53b54c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ext-expand-inner-exprs.rs @@ -0,0 +1,8 @@ +// run-pass + +static FOO : &'static str = concat!(concat!("hel", "lo"), "world"); + +pub fn main() { + assert_eq!(FOO, "helloworld"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/ext-nonexistent.rs b/gcc/testsuite/rust/rustc/ui/ext-nonexistent.rs new file mode 100644 index 000000000000..d1d00a70e2a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ext-nonexistent.rs @@ -0,0 +1,3 @@ +// error-pattern:cannot find macro +fn main() { iamnotanextensionthatexists!(""); } + diff --git a/gcc/testsuite/rust/rustc/ui/extend-for-unit.rs b/gcc/testsuite/rust/rustc/ui/extend-for-unit.rs new file mode 100644 index 000000000000..2df82270980a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extend-for-unit.rs @@ -0,0 +1,13 @@ +// run-pass + +pub fn main() { + let mut x = 0; + { + let iter = (0..5).map(|_| { + x += 1; + }); + ().extend(iter); + } + assert_eq!(x, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extenv/extenv-arg-2-not-string-literal.rs b/gcc/testsuite/rust/rustc/ui/extenv/extenv-arg-2-not-string-literal.rs new file mode 100644 index 000000000000..03e8523ccd45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extenv/extenv-arg-2-not-string-literal.rs @@ -0,0 +1,2 @@ +fn main() { env!("one", 10); } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/extenv/extenv-no-args.rs b/gcc/testsuite/rust/rustc/ui/extenv/extenv-no-args.rs new file mode 100644 index 000000000000..14e3fc80f225 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extenv/extenv-no-args.rs @@ -0,0 +1,2 @@ +fn main() { env!(); } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/extenv/extenv-not-defined-custom.rs b/gcc/testsuite/rust/rustc/ui/extenv/extenv-not-defined-custom.rs new file mode 100644 index 000000000000..de3db33645e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extenv/extenv-not-defined-custom.rs @@ -0,0 +1,2 @@ +fn main() { env!("__HOPEFULLY_NOT_DEFINED__", "my error message"); } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/extenv/extenv-not-defined-default.rs b/gcc/testsuite/rust/rustc/ui/extenv/extenv-not-defined-default.rs new file mode 100644 index 000000000000..36764029ce16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extenv/extenv-not-defined-default.rs @@ -0,0 +1,5 @@ +fn main() { + env!("__HOPEFULLY_NOT_DEFINED__"); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/extenv/extenv-not-string-literal.rs b/gcc/testsuite/rust/rustc/ui/extenv/extenv-not-string-literal.rs new file mode 100644 index 000000000000..a8608cc9478e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extenv/extenv-not-string-literal.rs @@ -0,0 +1,2 @@ +fn main() { env!(10, "two"); } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/extenv/extenv-too-many-args.rs b/gcc/testsuite/rust/rustc/ui/extenv/extenv-too-many-args.rs new file mode 100644 index 000000000000..281ad497d056 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extenv/extenv-too-many-args.rs @@ -0,0 +1,2 @@ +fn main() { env!("one", "two", "three"); } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/extenv/issue-55897.rs b/gcc/testsuite/rust/rustc/ui/extenv/issue-55897.rs new file mode 100644 index 000000000000..d7fcbc220ff3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extenv/issue-55897.rs @@ -0,0 +1,21 @@ +use prelude::*; // { dg-error ".E0432." "" { target *-*-* } } + +mod unresolved_env { + use env; // { dg-error ".E0432." "" { target *-*-* } } + + include!(concat!(env!("NON_EXISTENT"), "/data.rs")); +// { dg-error "" "" { target *-*-* } .-1 } +} + +mod nonexistent_env { + include!(concat!(env!("NON_EXISTENT"), "/data.rs")); +// { dg-error "" "" { target *-*-* } .-1 } +} + +mod erroneous_literal { + include!(concat!("NON_EXISTENT"suffix, "/data.rs")); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern-flag/auxiliary/somedep.rs b/gcc/testsuite/rust/rustc/ui/extern-flag/auxiliary/somedep.rs new file mode 100644 index 000000000000..f9ef784a7dcb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern-flag/auxiliary/somedep.rs @@ -0,0 +1,4 @@ +pub fn somefun() {} + +pub struct S; + diff --git a/gcc/testsuite/rust/rustc/ui/extern-flag/multiple-opts.rs b/gcc/testsuite/rust/rustc/ui/extern-flag/multiple-opts.rs new file mode 100644 index 000000000000..d502220d45af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern-flag/multiple-opts.rs @@ -0,0 +1,21 @@ +// aux-crate:priv,noprelude:somedep=somedep.rs +// compile-flags: -Zunstable-options +// edition:2018 + +// Test for multiple options to --extern. Can't test for errors from both +// options at the same time, so this only checks that noprelude is honored. + +#![warn(exported_private_dependencies)] + +// Module to avoid adding to prelude. +pub mod m { + extern crate somedep; + pub struct PublicType { + pub field: somedep::S, + } +} + +fn main() { + somedep::somefun(); // { dg-error ".E0433." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern-flag/noprelude-and-prelude.rs b/gcc/testsuite/rust/rustc/ui/extern-flag/noprelude-and-prelude.rs new file mode 100644 index 000000000000..75ef6950a3ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern-flag/noprelude-and-prelude.rs @@ -0,0 +1,11 @@ +// check-pass +// aux-crate:noprelude:somedep=somedep.rs +// compile-flags: -Zunstable-options --extern somedep +// edition:2018 + +// Having a flag with `noprelude` and one without, will add to the prelude. + +fn main() { + somedep::somefun(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern-flag/noprelude-resolves.rs b/gcc/testsuite/rust/rustc/ui/extern-flag/noprelude-resolves.rs new file mode 100644 index 000000000000..9f5a9a682a8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern-flag/noprelude-resolves.rs @@ -0,0 +1,12 @@ +// check-pass +// aux-crate:noprelude:somedep=somedep.rs +// compile-flags: -Zunstable-options +// edition:2018 + +// `extern crate` can be used to add to prelude. +extern crate somedep; + +fn main() { + somedep::somefun(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern-flag/noprelude.rs b/gcc/testsuite/rust/rustc/ui/extern-flag/noprelude.rs new file mode 100644 index 000000000000..e88132d519fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern-flag/noprelude.rs @@ -0,0 +1,8 @@ +// aux-crate:noprelude:somedep=somedep.rs +// compile-flags: -Zunstable-options +// edition:2018 + +fn main() { + somedep::somefun(); // { dg-error ".E0433." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern-flag/public-and-private.rs b/gcc/testsuite/rust/rustc/ui/extern-flag/public-and-private.rs new file mode 100644 index 000000000000..93880a9bfe5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern-flag/public-and-private.rs @@ -0,0 +1,14 @@ +// aux-crate:priv:somedep=somedep.rs +// compile-flags: -Zunstable-options --extern somedep +// edition:2018 + +#![deny(exported_private_dependencies)] + +// Having a flag with `priv` and one without, will remain private (it is sticky). + +pub struct PublicType { + pub field: somedep::S, // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern-prelude-fail.rs b/gcc/testsuite/rust/rustc/ui/extern-prelude-fail.rs new file mode 100644 index 000000000000..7ea8727884a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern-prelude-fail.rs @@ -0,0 +1,10 @@ +// compile-flags:--extern extern_prelude +// aux-build:extern-prelude.rs + +// Extern prelude names are not available by absolute paths + +fn main() { + use extern_prelude::S; // { dg-error ".E0432." "" { target *-*-* } } + let s = ::extern_prelude::S; // { dg-error ".E0433." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern-prelude.rs b/gcc/testsuite/rust/rustc/ui/extern-prelude.rs new file mode 100644 index 000000000000..5547a9be140b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern-prelude.rs @@ -0,0 +1,32 @@ +// build-pass (FIXME(62277): could be check-pass?) +// compile-flags:--extern extern_prelude --extern Vec +// aux-build:extern-prelude.rs +// aux-build:extern-prelude-vec.rs + +fn basic() { + // It works + let s = extern_prelude::S; + s.external(); +} + +fn shadow_mod() { + // Local module shadows `extern_prelude` from extern prelude + mod extern_prelude { + pub struct S; + + impl S { + pub fn internal(&self) {} + } + } + + let s = extern_prelude::S; + s.internal(); // OK +} + +fn shadow_prelude() { + // Extern prelude shadows standard library prelude + let x = Vec::new(0f32, ()); // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern-take-value.rs b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern-take-value.rs new file mode 100644 index 000000000000..1f1a0debd72a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern-take-value.rs @@ -0,0 +1,6 @@ +pub extern fn f() -> i32 { 1 } +pub extern fn g() -> i32 { 2 } + +pub fn get_f() -> extern fn() -> i32 { f } +pub fn get_g() -> extern fn() -> i32 { g } + diff --git a/gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern-types-inherent-impl.rs b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern-types-inherent-impl.rs new file mode 100644 index 000000000000..8bb4085da208 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern-types-inherent-impl.rs @@ -0,0 +1,10 @@ +#![feature(extern_types)] + +extern "C" { + pub type CrossCrate; +} + +impl CrossCrate { + pub fn foo(&self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern_calling_convention.rs b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern_calling_convention.rs new file mode 100644 index 000000000000..699511d39603 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern_calling_convention.rs @@ -0,0 +1,27 @@ +// Make sure Rust generates the correct calling convention for extern +// functions. + +#[inline(never)] +#[cfg(target_arch = "x86_64")] +pub extern "win64" fn foo(a: isize, b: isize, c: isize, d: isize) { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + assert_eq!(d, 4); + + println!("a: {}, b: {}, c: {}, d: {}", + a, b, c, d) +} + +#[inline(never)] +#[cfg(not(target_arch = "x86_64"))] +pub extern fn foo(a: isize, b: isize, c: isize, d: isize) { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + assert_eq!(d, 4); + + println!("a: {}, b: {}, c: {}, d: {}", + a, b, c, d) +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern_mod_ordering_lib.rs b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern_mod_ordering_lib.rs new file mode 100644 index 000000000000..54ded2a69c56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/extern_mod_ordering_lib.rs @@ -0,0 +1,6 @@ +#![crate_type="lib"] + +pub mod extern_mod_ordering_lib { + pub fn f() {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/auxiliary/fat_drop.rs b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/fat_drop.rs new file mode 100644 index 000000000000..7c98daa526e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/fat_drop.rs @@ -0,0 +1,14 @@ +pub static mut DROPPED: bool = false; + +pub struct S { + _unsized: [u8] +} + +impl Drop for S { + fn drop(&mut self) { + unsafe { + DROPPED = true; + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/auxiliary/m1.rs b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/m1.rs new file mode 100644 index 000000000000..44e36138cbda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/m1.rs @@ -0,0 +1,2 @@ +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/auxiliary/m2.rs b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/m2.rs new file mode 100644 index 000000000000..b243a4754802 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/auxiliary/m2.rs @@ -0,0 +1,2 @@ +pub fn bar() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-1.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-1.rs new file mode 100644 index 000000000000..2d80c85b9055 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-1.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +extern fn f() { +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-calling-convention-test.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-calling-convention-test.rs new file mode 100644 index 000000000000..358c9eb2ffd7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-calling-convention-test.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:extern_calling_convention.rs + +// pretty-expanded FIXME #23616 + +extern crate extern_calling_convention; + +use extern_calling_convention::foo; + +pub fn main() { + foo(1, 2, 3, 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-compare-with-return-type.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-compare-with-return-type.rs new file mode 100644 index 000000000000..5ac05e50b6ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-compare-with-return-type.rs @@ -0,0 +1,26 @@ +// run-pass +// Tests that we can compare various kinds of extern fn signatures. +#![allow(non_camel_case_types)] + +extern fn voidret1() {} +extern fn voidret2() {} + +extern fn uintret() -> usize { 22 } + +extern fn uintvoidret(_x: usize) {} + +extern fn uintuintuintuintret(x: usize, y: usize, z: usize) -> usize { x+y+z } +type uintuintuintuintret = extern fn(usize,usize,usize) -> usize; + +pub fn main() { + assert!(voidret1 as extern fn() == voidret1 as extern fn()); + assert!(voidret1 as extern fn() != voidret2 as extern fn()); + + assert!(uintret as extern fn() -> usize == uintret as extern fn() -> usize); + + assert!(uintvoidret as extern fn(usize) == uintvoidret as extern fn(usize)); + + assert!(uintuintuintuintret as uintuintuintuintret == + uintuintuintuintret as uintuintuintuintret); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-const.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-const.rs new file mode 100644 index 000000000000..8dd25f2be8fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-const.rs @@ -0,0 +1,27 @@ +// Check extern items cannot be const + `rustfix` suggests using +// extern static. +// +// #54388: an unused reference to an undefined static may or may not +// compile. To sidestep this by using one that *is* defined. + +// run-rustfix +// ignore-wasm32-bare no external library to link to. +// ignore-asmjs wasm2js does not support source maps yet +// compile-flags: -g +#![feature(rustc_private)] +extern crate libc; + +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + const rust_dbg_static_mut: libc::c_int; // { dg-error "" "" { target *-*-* } } +} + +fn main() { + // We suggest turning the (illegal) extern `const` into an extern `static`, + // but this also requires `unsafe` (a deny-by-default lint at comment time, + // future error; Issue #36247) + unsafe { + let _x = rust_dbg_static_mut; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-crate-rename.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-crate-rename.rs new file mode 100644 index 000000000000..32fc4cb9e318 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-crate-rename.rs @@ -0,0 +1,9 @@ +// aux-build:m1.rs +// aux-build:m2.rs + + +extern crate m1; +extern crate m2 as m1; // { dg-error ".E0259." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-crate-visibility.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-crate-visibility.rs new file mode 100644 index 000000000000..dd353472d0d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-crate-visibility.rs @@ -0,0 +1,25 @@ +mod foo { + extern crate core; +} + +// Check that private crates can be used from outside their modules, albeit with warnings +use foo::core::cell; // { dg-error ".E0603." "" { target *-*-* } } + +fn f() { + foo::core::cell::Cell::new(0); // { dg-error ".E0603." "" { target *-*-* } } + + use foo::*; + mod core {} // Check that private crates are not glob imported +} + +mod bar { + pub extern crate core; +} + +mod baz { + pub use bar::*; + use self::core::cell; // Check that public extern crates are glob imported +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-ffi-fn-with-body.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-ffi-fn-with-body.rs new file mode 100644 index 000000000000..4810c8905bfa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-ffi-fn-with-body.rs @@ -0,0 +1,12 @@ +extern "C" { + fn foo() -> i32 { // { dg-error "" "" { target *-*-* } } + return 0; + } +} + +extern "C" fn bar() -> i32 { + return 0; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-foreign-crate.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-foreign-crate.rs new file mode 100644 index 000000000000..6ff21f87cbe4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-foreign-crate.rs @@ -0,0 +1,7 @@ +// run-pass +// pretty-expanded FIXME #23616 + +extern crate std as mystd; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-macro.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-macro.rs new file mode 100644 index 000000000000..fd459abb074a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-macro.rs @@ -0,0 +1,7 @@ +// #41719 + +fn main() { + enum Foo {} + let _ = Foo::bar!(); // { dg-error ".E0433." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-main-fn.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-main-fn.rs new file mode 100644 index 000000000000..604b59898c28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-main-fn.rs @@ -0,0 +1,2 @@ +extern fn main() {} // { dg-error ".E0580." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-methods.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-methods.rs new file mode 100644 index 000000000000..2f703a9d49df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-methods.rs @@ -0,0 +1,32 @@ +// run-pass +// ignore-arm +// ignore-aarch64 +// ignore-riscv64 fastcall isn't supported + +trait A { + extern "fastcall" fn test1(i: i32); + extern fn test2(i: i32); +} + +struct S; +impl S { + extern "stdcall" fn test3(i: i32) { + assert_eq!(i, 3); + } +} + +impl A for S { + extern "fastcall" fn test1(i: i32) { + assert_eq!(i, 1); + } + extern fn test2(i: i32) { + assert_eq!(i, 2); + } +} + +fn main() { + ::test1(1); + ::test2(2); + S::test3(3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-mod-abi.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-mod-abi.rs new file mode 100644 index 000000000000..506dcdaa6d47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-mod-abi.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +extern "C" { + fn pow(x: f64, y: f64) -> f64; +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-mod-ordering-exe.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-mod-ordering-exe.rs new file mode 100644 index 000000000000..894ef0b16aff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-mod-ordering-exe.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:extern_mod_ordering_lib.rs + +// pretty-expanded FIXME #23616 + +extern crate extern_mod_ordering_lib; + +use extern_mod_ordering_lib::extern_mod_ordering_lib as the_lib; + +pub fn main() { + the_lib::f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-prelude-core.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-prelude-core.rs new file mode 100644 index 000000000000..58c92ac74c16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-prelude-core.rs @@ -0,0 +1,19 @@ +// run-pass +#![feature(lang_items, start)] +#![no_std] + +extern crate std as other; + +mod foo { + pub fn test() { + let x = core::cmp::min(2, 3); + assert_eq!(x, 2); + } +} + +#[start] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + foo::test(); + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-prelude-no-speculative.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-prelude-no-speculative.rs new file mode 100644 index 000000000000..866e894be6c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-prelude-no-speculative.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(unused_variables)] +// compile-flags: --extern LooksLikeExternCrate=/path/to/nowhere + +mod m { + pub struct LooksLikeExternCrate; +} + +fn main() { + // OK, speculative resolution for `unused_qualifications` doesn't try + // to resolve this as an extern crate and load that crate + let s = m::LooksLikeExternCrate {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-prelude-std.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-prelude-std.rs new file mode 100644 index 000000000000..e683df8a1608 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-prelude-std.rs @@ -0,0 +1,13 @@ +// run-pass + +mod foo { + pub fn test() { + let x = std::cmp::min(2, 3); + assert_eq!(x, 2); + } +} + +fn main() { + foo::test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-pub.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-pub.rs new file mode 100644 index 000000000000..dc82f35c22a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-pub.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +extern { + pub fn free(p: *const u8); +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-rust.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-rust.rs new file mode 100644 index 000000000000..a9f0ff8a8c6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-rust.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#[repr(C)] +pub struct Foo(u32); + +// ICE trigger, bad handling of differing types between rust and external ABIs +pub extern fn bar() -> Foo { + Foo(0) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-take-value.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-take-value.rs new file mode 100644 index 000000000000..ac9f895799b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-take-value.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:extern-take-value.rs + +extern crate extern_take_value; + +pub fn main() { + let a: extern "C" fn() -> i32 = extern_take_value::get_f(); + let b: extern "C" fn() -> i32 = extern_take_value::get_f(); + let c: extern "C" fn() -> i32 = extern_take_value::get_g(); + + assert!(a == b); + assert!(a != c); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-thiscall.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-thiscall.rs new file mode 100644 index 000000000000..dbe7d31daf2e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-thiscall.rs @@ -0,0 +1,28 @@ +// run-pass +// ignore-arm +// ignore-aarch64 +// ignore-riscv64 thiscall isn't supported + +#![feature(abi_thiscall)] + +trait A { + extern "thiscall" fn test1(i: i32); +} + +struct S; + +impl A for S { + extern "thiscall" fn test1(i: i32) { + assert_eq!(i, 1); + } +} + +extern "thiscall" fn test2(i: i32) { + assert_eq!(i, 2); +} + +fn main() { + ::test1(1); + test2(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-types-distinct-types.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-types-distinct-types.rs new file mode 100644 index 000000000000..27ab5dd4942c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-types-distinct-types.rs @@ -0,0 +1,13 @@ +#![feature(extern_types)] + +extern { + type A; + type B; +} + +fn foo(r: &A) -> &B { + r // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-types-inherent-impl.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-types-inherent-impl.rs new file mode 100644 index 000000000000..252ebbce345d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-types-inherent-impl.rs @@ -0,0 +1,27 @@ +// Test that inherent impls can be defined for extern types. + +// check-pass +// aux-build:extern-types-inherent-impl.rs + +#![feature(extern_types)] + +extern crate extern_types_inherent_impl; +use extern_types_inherent_impl::CrossCrate; + +extern "C" { + type Local; +} + +impl Local { + fn foo(&self) {} +} + +fn use_foo(x: &Local, y: &CrossCrate) { + Local::foo(x); + x.foo(); + CrossCrate::foo(y); + y.foo(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-types-manual-sync-send.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-types-manual-sync-send.rs new file mode 100644 index 000000000000..e643b9c56b6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-types-manual-sync-send.rs @@ -0,0 +1,20 @@ +// run-pass +// Test that unsafe impl for Sync/Send can be provided for extern types. + +#![feature(extern_types)] + +extern { + type A; +} + +unsafe impl Sync for A { } +unsafe impl Send for A { } + +fn assert_sync() { } +fn assert_send() { } + +fn main() { + assert_sync::(); + assert_send::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-types-not-sync-send.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-types-not-sync-send.rs new file mode 100644 index 000000000000..8906a62e3f0b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-types-not-sync-send.rs @@ -0,0 +1,19 @@ +// Make sure extern types are !Sync and !Send. + +#![feature(extern_types)] + +extern { + type A; +} + +fn assert_sync() { } +fn assert_send() { } + +fn main() { + assert_sync::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + assert_send::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-types-pointer-cast.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-types-pointer-cast.rs new file mode 100644 index 000000000000..2004dd9794b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-types-pointer-cast.rs @@ -0,0 +1,33 @@ +// run-pass +#![allow(dead_code)] +// Test that pointers to extern types can be cast from/to usize, +// despite being !Sized. + +#![feature(extern_types)] + +extern { + type A; +} + +struct Foo { + x: u8, + tail: A, +} + +struct Bar { + x: u8, + tail: T, +} + +#[cfg(target_pointer_width = "32")] +const MAGIC: usize = 0xdeadbeef; +#[cfg(target_pointer_width = "64")] +const MAGIC: usize = 0x12345678deadbeef; + +fn main() { + assert_eq!((MAGIC as *const A) as usize, MAGIC); + assert_eq!((MAGIC as *const Foo) as usize, MAGIC); + assert_eq!((MAGIC as *const Bar) as usize, MAGIC); + assert_eq!((MAGIC as *const Bar>) as usize, MAGIC); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-types-size_of_val.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-types-size_of_val.rs new file mode 100644 index 000000000000..9be694d4e14d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-types-size_of_val.rs @@ -0,0 +1,18 @@ +// run-pass +#![feature(extern_types)] + +use std::mem::{size_of_val, align_of_val}; + +extern { + type A; +} + +fn main() { + let x: &A = unsafe { + &*(1usize as *const A) + }; + + assert_eq!(size_of_val(x), 0); + assert_eq!(align_of_val(x), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-types-thin-pointer.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-types-thin-pointer.rs new file mode 100644 index 000000000000..cd20fd5ffb8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-types-thin-pointer.rs @@ -0,0 +1,44 @@ +// run-pass +#![allow(dead_code)] +// Test that pointers and references to extern types are thin, ie they have the same size and +// alignment as a pointer to (). + +#![feature(extern_types)] + +use std::mem::{align_of, size_of}; + +extern { + type A; +} + +struct Foo { + x: u8, + tail: A, +} + +struct Bar { + x: u8, + tail: T, +} + +fn assert_thin() { + assert_eq!(size_of::<*const T>(), size_of::<*const ()>()); + assert_eq!(align_of::<*const T>(), align_of::<*const ()>()); + + assert_eq!(size_of::<*mut T>(), size_of::<*mut ()>()); + assert_eq!(align_of::<*mut T>(), align_of::<*mut ()>()); + + assert_eq!(size_of::<&T>(), size_of::<&()>()); + assert_eq!(align_of::<&T>(), align_of::<&()>()); + + assert_eq!(size_of::<&mut T>(), size_of::<&mut ()>()); + assert_eq!(align_of::<&mut T>(), align_of::<&mut ()>()); +} + +fn main() { + assert_thin::(); + assert_thin::(); + assert_thin::>(); + assert_thin::>>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-types-trait-impl.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-types-trait-impl.rs new file mode 100644 index 000000000000..1a4a7cb4d3c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-types-trait-impl.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(dead_code)] +// Test that traits can be implemented for extern types. + +#![feature(extern_types)] + +extern { + type A; +} + +trait Foo { + fn foo(&self) { } +} + +impl Foo for A { + fn foo(&self) { } +} + +fn assert_foo() { } + +fn use_foo(x: &dyn Foo) { + x.foo(); +} + +fn main() { + assert_foo::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-types-unsized.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-types-unsized.rs new file mode 100644 index 000000000000..24e777853d56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-types-unsized.rs @@ -0,0 +1,34 @@ +// Make sure extern types are !Sized. + +#![feature(extern_types)] + +extern { + type A; +} + +struct Foo { + x: u8, + tail: A, +} + +struct Bar { + x: u8, + tail: T, +} + +fn assert_sized() { } + +fn main() { + assert_sized::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + assert_sized::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + assert_sized::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + assert_sized::>>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-vectorcall.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-vectorcall.rs new file mode 100644 index 000000000000..8358ba41f0d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-vectorcall.rs @@ -0,0 +1,28 @@ +// run-pass +// ignore-arm +// ignore-aarch64 +// ignore-riscv64 vectorcall isn't supported + +#![feature(abi_vectorcall)] + +trait A { + extern "vectorcall" fn test1(i: i32); +} + +struct S; + +impl A for S { + extern "vectorcall" fn test1(i: i32) { + assert_eq!(i, 1); + } +} + +extern "vectorcall" fn test2(i: i32) { + assert_eq!(i, 2); +} + +fn main() { + ::test1(1); + test2(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-with-type-bounds.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-with-type-bounds.rs new file mode 100644 index 000000000000..a155dcfca0c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-with-type-bounds.rs @@ -0,0 +1,21 @@ +#![feature(intrinsics)] + +extern "rust-intrinsic" { + // Real example from libcore + fn type_id() -> u64; + + // Silent bounds made explicit to make sure they are actually + // resolved. + fn transmute(val: T) -> U; + + // Bounds aren't checked right now, so this should work + // even though it's incorrect. + fn size_of() -> usize; + + // Unresolved bounds should still error. + fn align_of() -> usize; +// { dg-error ".E0405." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern-wrong-value-type.rs b/gcc/testsuite/rust/rustc/ui/extern/extern-wrong-value-type.rs new file mode 100644 index 000000000000..c61424ff1c23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern-wrong-value-type.rs @@ -0,0 +1,12 @@ +extern fn f() { +} + +fn is_fn(_: F) where F: Fn() {} + +fn main() { + // extern functions are extern "C" fn + let _x: extern "C" fn() = f; // OK + is_fn(f); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/extern_fat_drop.rs b/gcc/testsuite/rust/rustc/ui/extern/extern_fat_drop.rs new file mode 100644 index 000000000000..e506bc07ceb5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/extern_fat_drop.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:fat_drop.rs + +extern crate fat_drop; + +fn main() { + unsafe { + let data: &mut [u8] = &mut [0]; + let s: &mut fat_drop::S = std::mem::transmute::<&mut [u8], _>(data); + std::ptr::drop_in_place(s); + assert!(fat_drop::DROPPED); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/external-doc-error.rs b/gcc/testsuite/rust/rustc/ui/extern/external-doc-error.rs new file mode 100644 index 000000000000..f6bff97dc197 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/external-doc-error.rs @@ -0,0 +1,32 @@ +// normalize-stderr-test: "not-a-file.md:.*\(" -> "not-a-file.md: $$FILE_NOT_FOUND_MSG (" + +#![feature(external_doc)] + +#[doc(include = "not-a-file.md")] +// { dg-error "" "" { target *-*-* } .-1 } + +#[doc(include = "auxiliary/invalid-utf8.txt")] +// { dg-error "" "" { target *-*-* } .-1 } + +#[doc(include)] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +#[doc(include("../README.md"))] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +#[doc(include = 123)] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +#[doc(include(123))] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/issue-36122-accessing-externed-dst.rs b/gcc/testsuite/rust/rustc/ui/extern/issue-36122-accessing-externed-dst.rs new file mode 100644 index 000000000000..5db1d18876ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/issue-36122-accessing-externed-dst.rs @@ -0,0 +1,7 @@ +fn main() { + extern { + static symbol: [usize]; // { dg-error ".E0277." "" { target *-*-* } } + } + println!("{}", symbol[0]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs b/gcc/testsuite/rust/rustc/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs new file mode 100644 index 000000000000..582d9b0f5772 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs @@ -0,0 +1,65 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default +// ignore-emscripten no threads support + +// rust-lang/rust#64655: with panic=unwind, a panic from a subroutine +// should still run destructors as it unwinds the stack. However, +// bugs with how the nounwind LLVM attribute was applied led to this +// simple case being mishandled *if* you had fat LTO turned on. + +// Unlike issue-64655-extern-rust-must-allow-unwind.rs, the issue +// embodied in this test cropped up regardless of optimization level. +// Therefore it seemed worthy of being enshrined as a dedicated unit +// test. + +// LTO settings cannot be combined with -C prefer-dynamic +// no-prefer-dynamic + +// The revisions just enumerate lto settings (the opt-level appeared irrelevant in practice) + +// revisions: no thin fat +//[no]compile-flags: -C lto=no +//[thin]compile-flags: -C lto=thin +//[fat]compile-flags: -C lto=fat + +#![feature(core_panic)] + +// (For some reason, reproducing the LTO issue requires pulling in std +// explicitly this way.) +#![no_std] +extern crate std; + +fn main() { + use std::sync::atomic::{AtomicUsize, Ordering}; + use std::boxed::Box; + + static SHARED: AtomicUsize = AtomicUsize::new(0); + + assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 0); + + let old_hook = std::panic::take_hook(); + + std::panic::set_hook(Box::new(|_| { } )); // no-op on panic. + + let handle = std::thread::spawn(|| { + struct Droppable; + impl Drop for Droppable { + fn drop(&mut self) { + SHARED.fetch_add(1, Ordering::SeqCst); + } + } + + let _guard = Droppable; + core::panicking::panic("???"); + }); + + let wait = handle.join(); + + // Reinstate handler to ease observation of assertion failures. + std::panic::set_hook(old_hook); + + assert!(wait.is_err()); + + assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs b/gcc/testsuite/rust/rustc/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs new file mode 100644 index 000000000000..e6389e5cf2d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs @@ -0,0 +1,84 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default +// ignore-emscripten no threads support + +// rust-lang/rust#64655: with panic=unwind, a panic from a subroutine +// should still run destructors as it unwinds the stack. However, +// bugs with how the nounwind LLVM attribute was applied led to this +// simple case being mishandled *if* you had optimization *and* fat +// LTO turned on. + +// This test is the closest thing to a "regression test" we can do +// without actually spawning subprocesses and comparing stderr +// results. +// +// This test takes the code from the above issue and adapts it to +// better fit our test infrastructure: +// +// * Instead of relying on `println!` to observe whether the destructor +// is run, we instead run the code in a spawned thread and +// communicate the destructor's operation via a synchronous atomic +// in static memory. +// +// * To keep the output from confusing a casual user, we override the +// panic hook to be a no-op (rather than printing a message to +// stderr). +// +// (pnkfelix has confirmed by hand that these additions do not mask +// the underlying bug.) + +// LTO settings cannot be combined with -C prefer-dynamic +// no-prefer-dynamic + +// The revisions combine each lto setting with each optimization +// setting; pnkfelix observed three differing behaviors at opt-levels +// 0/1/2+3 for this test, so it seems prudent to be thorough. + +// revisions: no0 no1 no2 no3 thin0 thin1 thin2 thin3 fat0 fat1 fat2 fat3 + +//[no0]compile-flags: -C opt-level=0 -C lto=no +//[no1]compile-flags: -C opt-level=1 -C lto=no +//[no2]compile-flags: -C opt-level=2 -C lto=no +//[no3]compile-flags: -C opt-level=3 -C lto=no +//[thin0]compile-flags: -C opt-level=0 -C lto=thin +//[thin1]compile-flags: -C opt-level=1 -C lto=thin +//[thin2]compile-flags: -C opt-level=2 -C lto=thin +//[thin3]compile-flags: -C opt-level=3 -C lto=thin +//[fat0]compile-flags: -C opt-level=0 -C lto=fat +//[fat1]compile-flags: -C opt-level=1 -C lto=fat +//[fat2]compile-flags: -C opt-level=2 -C lto=fat +//[fat3]compile-flags: -C opt-level=3 -C lto=fat + +fn main() { + use std::sync::atomic::{AtomicUsize, Ordering}; + + static SHARED: AtomicUsize = AtomicUsize::new(0); + + assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 0); + + let old_hook = std::panic::take_hook(); + + std::panic::set_hook(Box::new(|_| { } )); // no-op on panic. + + let handle = std::thread::spawn(|| { + struct Droppable; + impl Drop for Droppable { + fn drop(&mut self) { + SHARED.fetch_add(1, Ordering::SeqCst); + } + } + + let _guard = Droppable; + None::<()>.expect("???"); + }); + + let wait = handle.join(); + + // reinstate handler to ease observation of assertion failures. + std::panic::set_hook(old_hook); + + assert!(wait.is_err()); + + assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extoption_env-no-args.rs b/gcc/testsuite/rust/rustc/ui/extoption_env-no-args.rs new file mode 100644 index 000000000000..04c52729a317 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extoption_env-no-args.rs @@ -0,0 +1,2 @@ +fn main() { option_env!(); } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/extoption_env-not-defined.rs b/gcc/testsuite/rust/rustc/ui/extoption_env-not-defined.rs new file mode 100644 index 000000000000..37a6bd9a1405 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extoption_env-not-defined.rs @@ -0,0 +1,6 @@ +// run-pass + +pub fn main() { + assert!(option_env!("__HOPEFULLY_DOESNT_EXIST__").is_none()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/extoption_env-not-string-literal.rs b/gcc/testsuite/rust/rustc/ui/extoption_env-not-string-literal.rs new file mode 100644 index 000000000000..7ab4c145fefb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extoption_env-not-string-literal.rs @@ -0,0 +1,2 @@ +fn main() { option_env!(10); } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/extoption_env-too-many-args.rs b/gcc/testsuite/rust/rustc/ui/extoption_env-too-many-args.rs new file mode 100644 index 000000000000..b05f180c978f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/extoption_env-too-many-args.rs @@ -0,0 +1,2 @@ +fn main() { option_env!("one", "two"); } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/fact.rs b/gcc/testsuite/rust/rustc/ui/fact.rs new file mode 100644 index 000000000000..d70a19a2a649 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fact.rs @@ -0,0 +1,27 @@ +// run-pass + +fn f(x: isize) -> isize { + // println!("in f:"); + + println!("{}", x); + if x == 1 { + // println!("bottoming out"); + + return 1; + } else { + // println!("recurring"); + + let y: isize = x * f(x - 1); + // println!("returned"); + + println!("{}", y); + return y; + } +} + +pub fn main() { + assert_eq!(f(5), 120); + // println!("all done"); + +} + diff --git a/gcc/testsuite/rust/rustc/ui/fail-simple.rs b/gcc/testsuite/rust/rustc/ui/fail-simple.rs new file mode 100644 index 000000000000..84f827679b35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fail-simple.rs @@ -0,0 +1,4 @@ +fn main() { + panic!(@); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/fat-lto.rs b/gcc/testsuite/rust/rustc/ui/fat-lto.rs new file mode 100644 index 000000000000..73075b6c8df3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fat-lto.rs @@ -0,0 +1,8 @@ +// run-pass +// compile-flags: -Clto=fat +// no-prefer-dynamic + +fn main() { + println!("hello!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/fat-ptr-cast-rpass.rs b/gcc/testsuite/rust/rustc/ui/fat-ptr-cast-rpass.rs new file mode 100644 index 000000000000..c59ee14e1459 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fat-ptr-cast-rpass.rs @@ -0,0 +1,42 @@ +// run-pass + +#![feature(raw)] + +use std::mem; +use std::raw; + +trait Foo { + fn foo(&self) {} +} + +struct Bar; + +impl Foo for Bar {} + +fn main() { + // Test we can turn a fat pointer to array back into a thin pointer. + let a: *const [i32] = &[1, 2, 3]; + let b = a as *const [i32; 2]; + unsafe { + assert_eq!(*b, [1, 2]); + } + + // Test conversion to an address (usize). + let a: *const [i32; 3] = &[1, 2, 3]; + let b: *const [i32] = a; + assert_eq!(a as usize, b as *const () as usize); + + // And conversion to a void pointer/address for trait objects too. + let a: *mut dyn Foo = &mut Bar; + let b = a as *mut (); + let c = a as *const () as usize; + let d = unsafe { + let r: raw::TraitObject = mem::transmute(a); + r.data + }; + + assert_eq!(b, d); + assert_eq!(c, d as usize); + +} + diff --git a/gcc/testsuite/rust/rustc/ui/fat-ptr-cast.rs b/gcc/testsuite/rust/rustc/ui/fat-ptr-cast.rs new file mode 100644 index 000000000000..b62c13580050 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fat-ptr-cast.rs @@ -0,0 +1,25 @@ +trait Trait {} + +// Make sure casts between thin-pointer <-> fat pointer obey RFC401 +fn main() { + let a: &[i32] = &[1, 2, 3]; + let b: Box<[i32]> = Box::new([1, 2, 3]); + let p = a as *const [i32]; + let q = a.as_ptr(); + + a as usize; // { dg-error ".E0606." "" { target *-*-* } } + a as isize; // { dg-error ".E0606." "" { target *-*-* } } + a as i16; // { dg-error ".E0606." "" { target *-*-* } } + a as u32; // { dg-error ".E0606." "" { target *-*-* } } + b as usize; // { dg-error ".E0605." "" { target *-*-* } } + p as usize; +// { dg-error ".E0606." "" { target *-*-* } .-1 } + + // #22955 + q as *const [i32]; // { dg-error ".E0607." "" { target *-*-* } } + + // #21397 + let t: *mut (dyn Trait + 'static) = 0 as *mut _; // { dg-error ".E0606." "" { target *-*-* } } + let mut fail: *const str = 0 as *const str; // { dg-error ".E0606." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/fds-are-cloexec.rs b/gcc/testsuite/rust/rustc/ui/fds-are-cloexec.rs new file mode 100644 index 000000000000..fb20e4236db7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fds-are-cloexec.rs @@ -0,0 +1,84 @@ +// run-pass +// ignore-windows +// ignore-android +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-haiku +// ignore-sgx no processes + +#![feature(rustc_private)] + +extern crate libc; + +use std::env; +use std::fs::File; +use std::io; +use std::net::{TcpListener, TcpStream, UdpSocket}; +use std::os::unix::prelude::*; +use std::process::{Command, Stdio}; +use std::thread; + +fn main() { + let args = env::args().collect::>(); + if args.len() == 1 { + parent() + } else { + child(&args) + } +} + +fn parent() { + let file = File::open(env::current_exe().unwrap()).unwrap(); + let tcp1 = TcpListener::bind("127.0.0.1:0").unwrap(); + let tcp2 = tcp1.try_clone().unwrap(); + let addr = tcp1.local_addr().unwrap(); + let t = thread::spawn(move || TcpStream::connect(addr).unwrap()); + let tcp3 = tcp1.accept().unwrap().0; + let tcp4 = t.join().unwrap(); + let tcp5 = tcp3.try_clone().unwrap(); + let tcp6 = tcp4.try_clone().unwrap(); + let udp1 = UdpSocket::bind("127.0.0.1:0").unwrap(); + let udp2 = udp1.try_clone().unwrap(); + + let mut child = Command::new(env::args().next().unwrap()) + .arg("100") + .stdout(Stdio::piped()) + .stdin(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn().unwrap(); + let pipe1 = child.stdin.take().unwrap(); + let pipe2 = child.stdout.take().unwrap(); + let pipe3 = child.stderr.take().unwrap(); + + + let status = Command::new(env::args().next().unwrap()) + .arg(file.as_raw_fd().to_string()) + .arg(tcp1.as_raw_fd().to_string()) + .arg(tcp2.as_raw_fd().to_string()) + .arg(tcp3.as_raw_fd().to_string()) + .arg(tcp4.as_raw_fd().to_string()) + .arg(tcp5.as_raw_fd().to_string()) + .arg(tcp6.as_raw_fd().to_string()) + .arg(udp1.as_raw_fd().to_string()) + .arg(udp2.as_raw_fd().to_string()) + .arg(pipe1.as_raw_fd().to_string()) + .arg(pipe2.as_raw_fd().to_string()) + .arg(pipe3.as_raw_fd().to_string()) + .status() + .unwrap(); + assert!(status.success()); + child.wait().unwrap(); +} + +fn child(args: &[String]) { + let mut b = [0u8; 2]; + for arg in &args[1..] { + let fd: libc::c_int = arg.parse().unwrap(); + unsafe { + assert_eq!(libc::read(fd, b.as_mut_ptr() as *mut _, 2), -1); + assert_eq!(io::Error::last_os_error().raw_os_error(), + Some(libc::EBADF)); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate-inline_const.rs b/gcc/testsuite/rust/rustc/ui/feature-gate-inline_const.rs new file mode 100644 index 000000000000..40434902d19c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate-inline_const.rs @@ -0,0 +1,7 @@ +fn main() { + let _ = const { +// { dg-error ".E0658." "" { target *-*-* } .-1 } + true + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate-isa_attribute.rs b/gcc/testsuite/rust/rustc/ui/feature-gate-isa_attribute.rs new file mode 100644 index 000000000000..41b7c7270dda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate-isa_attribute.rs @@ -0,0 +1,7 @@ +#[instruction_set] +// { dg-error ".E0778." "" { target *-*-* } .-1 } +// { dg-error ".E0778." "" { target *-*-* } .-2 } +// { dg-error ".E0778." "" { target *-*-* } .-3 } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate-optimize_attribute.rs b/gcc/testsuite/rust/rustc/ui/feature-gate-optimize_attribute.rs new file mode 100644 index 000000000000..d6500491ad11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate-optimize_attribute.rs @@ -0,0 +1,19 @@ +#![crate_type="rlib"] +#![optimize(speed)] // { dg-error ".E0658." "" { target *-*-* } } + +#[optimize(size)] // { dg-error ".E0658." "" { target *-*-* } } +mod module { + +#[optimize(size)] // { dg-error ".E0658." "" { target *-*-* } } +fn size() {} + +#[optimize(speed)] // { dg-error ".E0658." "" { target *-*-* } } +fn speed() {} + +#[optimize(banana)] +// { dg-error ".E0722." "" { target *-*-* } .-1 } +// { dg-error ".E0722." "" { target *-*-* } .-2 } +fn not_known() {} + +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/allow-features-empty.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/allow-features-empty.rs new file mode 100644 index 000000000000..236720cf404c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/allow-features-empty.rs @@ -0,0 +1,9 @@ +// compile-flags: -Z allow_features= +// Note: This test uses rustc internal flags because they will never stabilize. + +#![feature(lang_items)] // { dg-error ".E0725." "" { target *-*-* } } + +#![feature(unknown_stdlib_feature)] // { dg-error ".E0725." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/allow-features.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/allow-features.rs new file mode 100644 index 000000000000..31864f9a0b19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/allow-features.rs @@ -0,0 +1,9 @@ +// compile-flags: -Z allow_features=lang_items +// Note: This test uses rustc internal flags because they will never stabilize. + +#![feature(lang_items)] + +#![feature(unknown_stdlib_feature)] // { dg-error ".E0725." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/duplicate-features.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/duplicate-features.rs new file mode 100644 index 000000000000..0c2979cdf771 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/duplicate-features.rs @@ -0,0 +1,10 @@ +#![allow(stable_features)] + +#![feature(rust1)] +#![feature(rust1)] // { dg-error ".E0636." "" { target *-*-* } } + +#![feature(if_let)] +#![feature(if_let)] // { dg-error ".E0636." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/feature-gate-c_variadic.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/feature-gate-c_variadic.rs new file mode 100644 index 000000000000..cdf0ff56a5c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/feature-gate-c_variadic.rs @@ -0,0 +1,5 @@ +#![crate_type="lib"] + +pub unsafe extern "C" fn test(_: i32, ap: ...) { } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/feature-gate-static-nobundle-2.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/feature-gate-static-nobundle-2.rs new file mode 100644 index 000000000000..b03b5ce7a949 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/feature-gate-static-nobundle-2.rs @@ -0,0 +1,7 @@ +// { dg-error "" "" { target *-*-* } } +// Test the behavior of rustc when non-existent library is statically linked + +// compile-flags: -l static-nobundle=nonexistent + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-bench.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-bench.rs new file mode 100644 index 000000000000..bc6b1cca939b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-bench.rs @@ -0,0 +1,11 @@ +// The non-crate level cases are in issue-43106-gating-of-builtin-attrs.rs. +// See issue-12997-1.rs and issue-12997-2.rs to see how `#[bench]` is +// handled in "weird places" when `--test` is passed. + +#![feature(custom_inner_attributes)] + +#![bench = "4100"] +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.rs new file mode 100644 index 000000000000..ea18db43fc44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-builtin-attrs-error.rs @@ -0,0 +1,147 @@ +// { dg-note "" "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// This is testing whether various builtin attributes signals an +// error or warning when put in "weird" places. +// +// (This file sits on its own because it actually signals an error, +// which would mess up the treatment of other cases in +// issue-43106-gating-of-builtin-attrs.rs) + +// ignore-tidy-linelength + +#![macro_export] +// { dg-error "" "" { target *-*-* } .-1 } +#![main] +// { dg-error "" "" { target *-*-* } .-1 } +#![start] +// { dg-error "" "" { target *-*-* } .-1 } +#![repr()] +// { dg-error "" "" { target *-*-* } .-1 } +#![path = "3800"] +// { dg-error "" "" { target *-*-* } .-1 } +#![automatically_derived] +// { dg-error "" "" { target *-*-* } .-1 } +#![no_mangle] +#![no_link] +// { dg-error "" "" { target *-*-* } .-1 } +#![export_name = "2200"] +// { dg-error "" "" { target *-*-* } .-1 } +#![inline] +// { dg-error ".E0518." "" { target *-*-* } .-1 } +#[inline] +// { dg-error ".E0518." "" { target *-*-* } .-1 } +mod inline { +// { dg-note "" "" { target *-*-* } .-1 } + + mod inner { #![inline] } +// { dg-error ".E0518." "" { target *-*-* } .-1 } +// { dg-note ".E0518." "" { target *-*-* } .-2 } + + #[inline = "2100"] fn f() { } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +// { dg-note "" "" { target *-*-* } .-4 } + + #[inline] struct S; +// { dg-error ".E0518." "" { target *-*-* } .-1 } +// { dg-note ".E0518." "" { target *-*-* } .-2 } + + #[inline] type T = S; +// { dg-error ".E0518." "" { target *-*-* } .-1 } +// { dg-note ".E0518." "" { target *-*-* } .-2 } + + #[inline] impl S { } +// { dg-error ".E0518." "" { target *-*-* } .-1 } +// { dg-note ".E0518." "" { target *-*-* } .-2 } +} + +#[no_link] +// { dg-error "" "" { target *-*-* } .-1 } +mod no_link { +// { dg-note "" "" { target *-*-* } .-1 } + + mod inner { #![no_link] } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + + #[no_link] fn f() { } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + + #[no_link] struct S; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + + #[no_link]type T = S; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + + #[no_link] impl S { } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +} + +#[export_name = "2200"] +// { dg-error "" "" { target *-*-* } .-1 } +mod export_name { +// { dg-note "" "" { target *-*-* } .-1 } + + mod inner { #![export_name="2200"] } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + + #[export_name = "2200"] fn f() { } + + #[export_name = "2200"] struct S; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + + #[export_name = "2200"] type T = S; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + + #[export_name = "2200"] impl S { } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +} + +#[main] +// { dg-error "" "" { target *-*-* } .-1 } +mod main { + mod inner { #![main] } +// { dg-error "" "" { target *-*-* } .-1 } + + // for `fn f()` case, see feature-gate-main.rs + + #[main] struct S; +// { dg-error "" "" { target *-*-* } .-1 } + + #[main] type T = S; +// { dg-error "" "" { target *-*-* } .-1 } + + #[main] impl S { } +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[start] +// { dg-error "" "" { target *-*-* } .-1 } +mod start { + mod inner { #![start] } +// { dg-error "" "" { target *-*-* } .-1 } + + // for `fn f()` case, see feature-gate-start.rs + + #[start] struct S; +// { dg-error "" "" { target *-*-* } .-1 } + + #[start] type T = S; +// { dg-error "" "" { target *-*-* } .-1 } + + #[start] impl S { } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs new file mode 100644 index 000000000000..89b063674efc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs @@ -0,0 +1,824 @@ +// { dg-note "" "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// This test enumerates as many compiler-builtin ungated attributes as +// possible (that is, all the mutually compatible ones), and checks +// that we get "expected" (*) warnings for each in the various weird +// places that users might put them in the syntax. +// +// (*): The word "expected" is in quotes above because the cases where +// warnings are and are not emitted might not match a user's intuition +// nor the rustc developers' intent. I am really just trying to +// capture today's behavior in a test, not so that it become enshrined +// as the absolute behavior going forward, but rather so that we do +// not change the behavior in the future without even being *aware* of +// the change when it happens. +// +// At the time of authoring, the attributes here are listed in the +// order that they occur in `librustc_feature`. +// +// Any builtin attributes that: +// +// - are not stable, or +// +// - could not be included here covering the same cases as the other +// attributes without raising an *error* from rustc (note though +// that warnings are of course expected) +// +// have their own test case referenced by filename in an inline +// comment. +// +// The test feeds numeric inputs to each attribute that accepts them +// without error. We do this for two reasons: (1.) to exercise how +// inputs are handled by each, and (2.) to ease searching for related +// occurrences in the source text. + +// check-pass +// ignore-tidy-linelength + +#![feature(test, plugin_registrar)] +#![warn(unused_attributes, unknown_lints)] +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + +// Exception, a gated and deprecated attribute. + +#![plugin_registrar] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } + +// UNGATED WHITE-LISTED BUILT-IN ATTRIBUTES + +#![warn(x5400)] // { dg-warning "" "" { target *-*-* } } +#![allow(x5300)] // { dg-warning "" "" { target *-*-* } } +#![forbid(x5200)] // { dg-warning "" "" { target *-*-* } } +#![deny(x5100)] // { dg-warning "" "" { target *-*-* } } +#![macro_use] // (allowed if no argument; see issue-43160-gating-of-macro_use.rs) +// skipping testing of cfg +// skipping testing of cfg_attr +#![should_panic] // { dg-warning "" "" { target *-*-* } } +#![ignore] // { dg-warning "" "" { target *-*-* } } +#![no_implicit_prelude] +#![reexport_test_harness_main = "2900"] +// see gated-link-args.rs +// see issue-43106-gating-of-macro_escape.rs for crate-level; but non crate-level is below at "2700" +// (cannot easily test gating of crate-level #[no_std]; but non crate-level is below at "2600") +#![proc_macro_derive()] // { dg-warning "" "" { target *-*-* } } +#![doc = "2400"] +#![cold] // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +// see issue-43106-gating-of-builtin-attrs-error.rs +#![link()] +#![link_name = "1900"] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +#![link_section = "1800"] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// see issue-43106-gating-of-rustc_deprecated.rs +#![must_use] +// see issue-43106-gating-of-stable.rs +// see issue-43106-gating-of-unstable.rs +// see issue-43106-gating-of-deprecated.rs +#![windows_subsystem = "windows"] + +// UNGATED CRATE-LEVEL BUILT-IN ATTRIBUTES + +#![crate_name = "0900"] +#![crate_type = "bin"] // cannot pass "0800" here + +#![crate_id = "10"] +// { dg-warning "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + +// FIXME(#44232) we should warn that this isn't used. +#![feature(rust1)] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + +#![no_start] +// { dg-warning "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + +// (cannot easily gating state of crate-level #[no_main]; but non crate-level is below at "0400") +#![no_builtins] +#![recursion_limit = "0200"] +#![type_length_limit = "0100"] + +// USES OF BUILT-IN ATTRIBUTES IN OTHER ("UNUSUAL") PLACES + +#[warn(x5400)] +// { dg-warning "" "" { target *-*-* } .-1 } +mod warn { + mod inner { #![warn(x5400)] } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[warn(x5400)] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[warn(x5400)] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[warn(x5400)] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[warn(x5400)] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +#[allow(x5300)] +// { dg-warning "" "" { target *-*-* } .-1 } +mod allow { + mod inner { #![allow(x5300)] } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[allow(x5300)] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[allow(x5300)] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[allow(x5300)] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[allow(x5300)] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +#[forbid(x5200)] +// { dg-warning "" "" { target *-*-* } .-1 } +mod forbid { + mod inner { #![forbid(x5200)] } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[forbid(x5200)] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[forbid(x5200)] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[forbid(x5200)] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[forbid(x5200)] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +#[deny(x5100)] +// { dg-warning "" "" { target *-*-* } .-1 } +mod deny { + mod inner { #![deny(x5100)] } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[deny(x5100)] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[deny(x5100)] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[deny(x5100)] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[deny(x5100)] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +#[macro_use] +mod macro_use { + mod inner { #![macro_use] } + + #[macro_use] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[macro_use] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[macro_use] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[macro_use] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +#[macro_export] +// { dg-warning "" "" { target *-*-* } .-1 } +mod macro_export { + mod inner { #![macro_export] } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[macro_export] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[macro_export] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[macro_export] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[macro_export] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +#[plugin_registrar] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +mod plugin_registrar { + mod inner { #![plugin_registrar] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +// { dg-note "" "" { target *-*-* } .-4 } + + // for `fn f()` case, see gated-plugin_registrar.rs + + #[plugin_registrar] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } + + #[plugin_registrar] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } + + #[plugin_registrar] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +} + +// At time of unit test authorship, if compiling without `--test` then +// non-crate-level #[test] attributes seem to be ignored. + +#[test] +mod test { mod inner { #![test] } + + fn f() { } + + struct S; + + type T = S; + + impl S { } +} + +// At time of unit test authorship, if compiling without `--test` then +// non-crate-level #[bench] attributes seem to be ignored. + +#[bench] +mod bench { + mod inner { #![bench] } + + #[bench] + struct S; + + #[bench] + type T = S; + + #[bench] + impl S { } +} + +#[repr()] +mod repr { + mod inner { #![repr()] } + + #[repr()] fn f() { } + + struct S; + + #[repr()] type T = S; + + #[repr()] impl S { } +} + +#[path = "3800"] +mod path { + mod inner { #![path="3800"] } + + #[path = "3800"] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[path = "3800"] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[path = "3800"] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[path = "3800"] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +#[automatically_derived] +// { dg-warning "" "" { target *-*-* } .-1 } +mod automatically_derived { + mod inner { #![automatically_derived] } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[automatically_derived] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[automatically_derived] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[automatically_derived] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[automatically_derived] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +#[no_mangle] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +mod no_mangle { +// { dg-note "" "" { target *-*-* } .-1 } + mod inner { #![no_mangle] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[no_mangle] fn f() { } + + #[no_mangle] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[no_mangle] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[no_mangle] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +} + +#[should_panic] +// { dg-warning "" "" { target *-*-* } .-1 } +mod should_panic { + mod inner { #![should_panic] } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[should_panic] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[should_panic] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[should_panic] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[should_panic] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +#[ignore] +// { dg-warning "" "" { target *-*-* } .-1 } +mod ignore { + mod inner { #![ignore] } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[ignore] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[ignore] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[ignore] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[ignore] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +#[no_implicit_prelude] +// { dg-warning "" "" { target *-*-* } .-1 } +mod no_implicit_prelude { + mod inner { #![no_implicit_prelude] } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[no_implicit_prelude] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[no_implicit_prelude] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[no_implicit_prelude] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[no_implicit_prelude] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +#[reexport_test_harness_main = "2900"] +// { dg-warning "" "" { target *-*-* } .-1 } +mod reexport_test_harness_main { + mod inner { #![reexport_test_harness_main="2900"] } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[reexport_test_harness_main = "2900"] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[reexport_test_harness_main = "2900"] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[reexport_test_harness_main = "2900"] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[reexport_test_harness_main = "2900"] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +// Cannot feed "2700" to `#[macro_escape]` without signaling an error. +#[macro_escape] +// { dg-warning "" "" { target *-*-* } .-1 } +mod macro_escape { + mod inner { #![macro_escape] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + + #[macro_escape] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } + + #[macro_escape] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[macro_escape] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } + + #[macro_escape] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +#[no_std] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +mod no_std { + mod inner { #![no_std] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[no_std] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[no_std] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[no_std] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[no_std] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +// At time of authorship, #[proc_macro_derive = "2500"] signals error +// when it occurs on a mod (apart from crate-level). Therefore it goes +// into its own file; see issue-43106-gating-of-proc_macro_derive.rs + +#[doc = "2400"] +mod doc { + mod inner { #![doc="2400"] } + + #[doc = "2400"] fn f() { } + + #[doc = "2400"] struct S; + + #[doc = "2400"] type T = S; + + #[doc = "2400"] impl S { } +} + +#[cold] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +mod cold { +// { dg-note "" "" { target *-*-* } .-1 } + + mod inner { #![cold] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[cold] fn f() { } + + #[cold] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[cold] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[cold] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +} + +#[link_name = "1900"] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +mod link_name { +// { dg-note "" "" { target *-*-* } .-1 } + + #[link_name = "1900"] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } + extern { } +// { dg-note "" "" { target *-*-* } .-1 } + + mod inner { #![link_name="1900"] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[link_name = "1900"] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[link_name = "1900"] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[link_name = "1900"] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[link_name = "1900"] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +} + +#[link_section = "1800"] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +mod link_section { +// { dg-note "" "" { target *-*-* } .-1 } + + mod inner { #![link_section="1800"] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[link_section = "1800"] fn f() { } + + #[link_section = "1800"] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[link_section = "1800"] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + + #[link_section = "1800"] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +} + + +// Note that this is a `check-pass` test, so it +// will never invoke the linker. These are here nonetheless to point +// out that we allow them at non-crate-level (though I do not know +// whether they have the same effect here as at crate-level). + +#[link()] +mod link { + mod inner { #![link()] } + + #[link()] fn f() { } + + #[link()] struct S; + + #[link()] type T = S; + + #[link()] impl S { } +} + +struct StructForDeprecated; + +#[deprecated] +mod deprecated { + mod inner { #![deprecated] } + + #[deprecated] fn f() { } + + #[deprecated] struct S1; + + #[deprecated] type T = super::StructForDeprecated; + + #[deprecated] impl super::StructForDeprecated { } +} + +#[must_use] +mod must_use { + mod inner { #![must_use] } + + #[must_use] fn f() { } + + #[must_use] struct S; + + #[must_use] type T = S; + + #[must_use] impl S { } +} + +#[windows_subsystem = "windows"] +mod windows_subsystem { + mod inner { #![windows_subsystem="windows"] } + + #[windows_subsystem = "windows"] fn f() { } + + #[windows_subsystem = "windows"] struct S; + + #[windows_subsystem = "windows"] type T = S; + + #[windows_subsystem = "windows"] impl S { } +} + +// BROKEN USES OF CRATE-LEVEL BUILT-IN ATTRIBUTES + +#[crate_name = "0900"] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +mod crate_name { + mod inner { #![crate_name="0900"] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[crate_name = "0900"] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[crate_name = "0900"] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[crate_name = "0900"] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[crate_name = "0900"] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +#[crate_type = "0800"] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +mod crate_type { + mod inner { #![crate_type="0800"] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[crate_type = "0800"] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[crate_type = "0800"] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[crate_type = "0800"] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[crate_type = "0800"] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +#[feature(x0600)] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +mod feature { + mod inner { #![feature(x0600)] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[feature(x0600)] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[feature(x0600)] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[feature(x0600)] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[feature(x0600)] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + + +#[no_main] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +mod no_main_1 { + mod inner { #![no_main] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[no_main] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[no_main] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[no_main] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[no_main] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +#[no_builtins] +mod no_builtins { + mod inner { #![no_builtins] } + + #[no_builtins] fn f() { } + + #[no_builtins] struct S; + + #[no_builtins] type T = S; + + #[no_builtins] impl S { } +} + +#[recursion_limit="0200"] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +mod recursion_limit { + mod inner { #![recursion_limit="0200"] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[recursion_limit="0200"] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[recursion_limit="0200"] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[recursion_limit="0200"] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[recursion_limit="0200"] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +#[type_length_limit="0100"] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +mod type_length_limit { + mod inner { #![type_length_limit="0100"] } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[type_length_limit="0100"] fn f() { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[type_length_limit="0100"] struct S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[type_length_limit="0100"] type T = S; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + #[type_length_limit="0100"] impl S { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-deprecated.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-deprecated.rs new file mode 100644 index 000000000000..7c3af491223a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-deprecated.rs @@ -0,0 +1,13 @@ +// This test just shows that a crate-level `#![deprecated]` does not +// signal a warning or error. (This file sits on its own because a +// crate-level `#![deprecated]` causes all that crate's item +// definitions to be deprecated, which is a pain to work with.) +// +// (For non-crate-level cases, see issue-43106-gating-of-builtin-attrs.rs) + +// check-pass + +#![deprecated] + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-derive-2.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-derive-2.rs new file mode 100644 index 000000000000..dbbb6314c937 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-derive-2.rs @@ -0,0 +1,21 @@ +// This test checks cases where the derive-macro does not exist. + +mod derive { + #[derive(x3300)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + union U { f: i32 } + + #[derive(x3300)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + enum E { } + + #[derive(x3300)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + struct S; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-derive.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-derive.rs new file mode 100644 index 000000000000..c54ace96adc6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-derive.rs @@ -0,0 +1,33 @@ +// `#![derive]` raises errors when it occurs at contexts other than ADT +// definitions. + +#[derive(Debug)] +// { dg-error ".E0774." "" { target *-*-* } .-1 } +mod derive { + mod inner { #![derive(Debug)] } +// { dg-error ".E0774." "" { target *-*-* } .-1 } + + #[derive(Debug)] +// { dg-error ".E0774." "" { target *-*-* } .-1 } + fn derive() { } + + #[derive(Copy, Clone)] // (can't derive Debug for unions) + union U { f: i32 } + + #[derive(Debug)] + struct S; + + #[derive(Debug)] + enum E { } + + #[derive(Debug)] +// { dg-error ".E0774." "" { target *-*-* } .-1 } + type T = S; + + #[derive(Debug)] +// { dg-error ".E0774." "" { target *-*-* } .-1 } + impl S { } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-macro_escape.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-macro_escape.rs new file mode 100644 index 000000000000..678388f10a5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-macro_escape.rs @@ -0,0 +1,12 @@ +// Testing that crate-level `#![macro_escape]` is not gated beyond a +// depecation warning. This file sits on its own, because crate-level +// `#![macro_escape]` is incompatible with crate-level `#![macro_use]` +// already present in issue-43106-gating-of-builtin-attrs. + +// check-pass + +#![macro_escape] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-macro_use.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-macro_use.rs new file mode 100644 index 000000000000..cb2be3a3d3be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-macro_use.rs @@ -0,0 +1,26 @@ +// This is just a check-list of the cases where feeding arguments to +// `#[macro_use]` is rejected. (The cases where no error is emitted +// corresponds to cases where the attribute is currently unused, so we +// get that warning; see issue-43106-gating-of-builtin-attrs.rs + +#![macro_use(my_macro)] +// { dg-error "" "" { target *-*-* } .-1 } + +#[macro_use(my_macro)] +// { dg-error "" "" { target *-*-* } .-1 } +mod macro_escape { + mod inner { #![macro_use(my_macro)] } +// { dg-error "" "" { target *-*-* } .-1 } + + #[macro_use = "2700"] struct S; +// { dg-error "" "" { target *-*-* } .-1 } + + #[macro_use] fn f() { } + + #[macro_use] type T = S; + + #[macro_use] impl S { } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.rs new file mode 100644 index 000000000000..1a11b01e51c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.rs @@ -0,0 +1,35 @@ +// At time of authorship, #[proc_macro_derive = "2500"] will emit an +// error when it occurs on a mod (apart from crate-level), but will +// not descend further into the mod for other occurrences of the same +// error. +// +// This file sits on its own because the "weird" occurrences here +// signal errors, making it incompatible with the "warnings only" +// nature of issue-43106-gating-of-builtin-attrs.rs + +#[proc_macro_derive()] +// { dg-error "" "" { target *-*-* } .-1 } +mod proc_macro_derive1 { + mod inner { #![proc_macro_derive()] } + // (no error issued here if there was one on outer module) +} + +mod proc_macro_derive2 { + mod inner { #![proc_macro_derive()] } +// { dg-error "" "" { target *-*-* } .-1 } + + #[proc_macro_derive()] fn f() { } +// { dg-error "" "" { target *-*-* } .-1 } + + #[proc_macro_derive()] struct S; +// { dg-error "" "" { target *-*-* } .-1 } + + #[proc_macro_derive()] type T = S; +// { dg-error "" "" { target *-*-* } .-1 } + + #[proc_macro_derive()] impl S { } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs new file mode 100644 index 000000000000..0a4eb6c1bfc0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs @@ -0,0 +1,31 @@ +// Testing gating of `#[rustc_deprecated]` in "weird" places. +// +// This file sits on its own because these signal errors, making +// this test incompatible with the "warnings only" nature of +// issue-43106-gating-of-builtin-attrs.rs + +#![rustc_deprecated()] +// { dg-error ".E0734." "" { target *-*-* } .-1 } + +#[rustc_deprecated()] +// { dg-error ".E0734." "" { target *-*-* } .-1 } +mod rustc_deprecated { + mod inner { #![rustc_deprecated()] } +// { dg-error ".E0734." "" { target *-*-* } .-1 } + + #[rustc_deprecated()] fn f() { } +// { dg-error ".E0734." "" { target *-*-* } .-1 } + + #[rustc_deprecated()] struct S; +// { dg-error ".E0734." "" { target *-*-* } .-1 } +// { dg-error ".E0734." "" { target *-*-* } .-2 } + + #[rustc_deprecated()] type T = S; +// { dg-error ".E0734." "" { target *-*-* } .-1 } + + #[rustc_deprecated()] impl S { } +// { dg-error ".E0734." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-stable.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-stable.rs new file mode 100644 index 000000000000..37ac6adea68d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-stable.rs @@ -0,0 +1,31 @@ +// Testing gating of `#[stable]` in "weird" places. +// +// This file sits on its own because these signal errors, making +// this test incompatible with the "warnings only" nature of +// issue-43106-gating-of-builtin-attrs.rs + +#![stable()] +// { dg-error ".E0734." "" { target *-*-* } .-1 } + +#[stable()] +// { dg-error ".E0734." "" { target *-*-* } .-1 } +mod stable { + mod inner { #![stable()] } +// { dg-error ".E0734." "" { target *-*-* } .-1 } + + #[stable()] fn f() { } +// { dg-error ".E0734." "" { target *-*-* } .-1 } + + #[stable()] struct S; +// { dg-error ".E0734." "" { target *-*-* } .-1 } +// { dg-error ".E0734." "" { target *-*-* } .-2 } + + #[stable()] type T = S; +// { dg-error ".E0734." "" { target *-*-* } .-1 } + + #[stable()] impl S { } +// { dg-error ".E0734." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-test.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-test.rs new file mode 100644 index 000000000000..b30810ce416d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-test.rs @@ -0,0 +1,7 @@ +// The non-crate level cases are in issue-43106-gating-of-builtin-attrs.rs. + +#![test = "4200"] +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-unstable.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-unstable.rs new file mode 100644 index 000000000000..a5ab24582e57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-43106-gating-of-unstable.rs @@ -0,0 +1,31 @@ +// Testing gating of `#[unstable]` in "weird" places. +// +// This file sits on its own because these signal errors, making +// this test incompatible with the "warnings only" nature of +// issue-43106-gating-of-builtin-attrs.rs + +#![unstable()] +// { dg-error ".E0734." "" { target *-*-* } .-1 } + +#[unstable()] +// { dg-error ".E0734." "" { target *-*-* } .-1 } +mod unstable { + mod inner { #![unstable()] } +// { dg-error ".E0734." "" { target *-*-* } .-1 } + + #[unstable()] fn f() { } +// { dg-error ".E0734." "" { target *-*-* } .-1 } + + #[unstable()] struct S; +// { dg-error ".E0734." "" { target *-*-* } .-1 } +// { dg-error ".E0734." "" { target *-*-* } .-2 } + + #[unstable()] type T = S; +// { dg-error ".E0734." "" { target *-*-* } .-1 } + + #[unstable()] impl S { } +// { dg-error ".E0734." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/issue-49983-see-issue-0.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-49983-see-issue-0.rs new file mode 100644 index 000000000000..5d9cda9378b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/issue-49983-see-issue-0.rs @@ -0,0 +1,7 @@ +extern crate core; + +// error should not say "(see issue #0)" +#[allow(unused_imports)] use core::ptr::Unique; // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/rustc-private.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/rustc-private.rs new file mode 100644 index 000000000000..341a955a55a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/rustc-private.rs @@ -0,0 +1,6 @@ +// gate-test-rustc_private + +extern crate libc; // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/stability-attribute-consistency.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/stability-attribute-consistency.rs new file mode 100644 index 000000000000..810d49265002 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/stability-attribute-consistency.rs @@ -0,0 +1,17 @@ +#![stable(feature = "stable_test_feature", since = "1.0.0")] + +#![feature(staged_api)] + +#[stable(feature = "foo", since = "1.0.0")] +fn foo_stable_1_0_0() {} + +#[stable(feature = "foo", since = "1.29.0")] +// { dg-error ".E0711." "" { target *-*-* } .-1 } +fn foo_stable_1_29_0() {} + +#[unstable(feature = "foo", issue = "none")] +// { dg-error ".E0711." "" { target *-*-* } .-1 } +fn foo_unstable() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/unknown-feature.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/unknown-feature.rs new file mode 100644 index 000000000000..7033ad6fc5d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/unknown-feature.rs @@ -0,0 +1,4 @@ +#![feature(unknown_rust_feature)] // { dg-error ".E0635." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gate/unstable-attribute-allow-issue-0.rs b/gcc/testsuite/rust/rustc/ui/feature-gate/unstable-attribute-allow-issue-0.rs new file mode 100644 index 000000000000..7ac29718bb00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gate/unstable-attribute-allow-issue-0.rs @@ -0,0 +1,14 @@ +// Check that an issue value can be explicitly set to "0" instead of "none" +#![crate_type = "lib"] +#![feature(staged_api)] +#![stable(feature = "stable_test_feature", since = "1.0.0")] + +#[unstable(feature = "unstable_test_feature", issue = "0")] +// { dg-error ".E0545." "" { target *-*-* } .-1 } + +#[unstable(feature = "unstable_test_feature", issue = "none")] +fn unstable_issue_none() {} + +#[unstable(feature = "unstable_test_feature", issue = "something")] +// { dg-error ".E0545." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gated-feature-in-macro-arg.rs b/gcc/testsuite/rust/rustc/ui/feature-gated-feature-in-macro-arg.rs new file mode 100644 index 000000000000..6fa223cf62a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gated-feature-in-macro-arg.rs @@ -0,0 +1,15 @@ +// tests that input to a macro is checked for use of gated features. If this +// test succeeds due to the acceptance of a feature, pick a new feature to +// test. Not ideal, but oh well :( + +fn main() { + let a = &[1, 2, 3]; + println!("{}", { + extern "rust-intrinsic" { // { dg-error ".E0658." "" { target *-*-* } } + fn atomic_fence(); + } + atomic_fence(); + 42 + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/auxiliary/cfg-target-thread-local.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/auxiliary/cfg-target-thread-local.rs new file mode 100644 index 000000000000..7f8d0aad9e73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/auxiliary/cfg-target-thread-local.rs @@ -0,0 +1,8 @@ +#![feature(thread_local)] +#![feature(cfg_target_thread_local)] +#![crate_type = "lib"] + +#[no_mangle] +#[cfg_attr(target_thread_local, thread_local)] +pub static FOO: u32 = 3; + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/auxiliary/pub_dep.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/auxiliary/pub_dep.rs new file mode 100644 index 000000000000..68fd575d8c8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/auxiliary/pub_dep.rs @@ -0,0 +1,2 @@ +pub struct PubType; + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/auxiliary/re_rebalance_coherence_lib.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/auxiliary/re_rebalance_coherence_lib.rs new file mode 100644 index 000000000000..722d96872989 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/auxiliary/re_rebalance_coherence_lib.rs @@ -0,0 +1,23 @@ +pub trait Backend {} +pub trait SupportsDefaultKeyword {} + +impl SupportsDefaultKeyword for Postgres {} + +pub struct Postgres; + +impl Backend for Postgres {} + +pub struct AstPass(::std::marker::PhantomData); + +pub trait QueryFragment {} + + +#[derive(Debug, Clone, Copy)] +pub struct BatchInsert<'a, T: 'a, Tab> { + _marker: ::std::marker::PhantomData<(&'a T, Tab)>, +} + +impl<'a, T:'a, Tab, DB> QueryFragment for BatchInsert<'a, T, Tab> +where DB: SupportsDefaultKeyword + Backend, +{} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/bench.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/bench.rs new file mode 100644 index 000000000000..6b31cec6c45c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/bench.rs @@ -0,0 +1,10 @@ +// edition:2018 + +#[bench] // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +fn bench() {} + +use bench as _; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi-avr-interrupt.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi-avr-interrupt.rs new file mode 100644 index 000000000000..dbcaa7dbacb8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi-avr-interrupt.rs @@ -0,0 +1,10 @@ +// Test that the AVR interrupt ABI cannot be used when avr_interrupt +// feature gate is not used. + +extern "avr-interrupt" fn foo() {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs new file mode 100644 index 000000000000..157842b92643 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi-msp430-interrupt.rs @@ -0,0 +1,12 @@ +// Test that the MSP430 interrupt ABI cannot be used when msp430_interrupt +// feature gate is not used. + +// ignore-riscv64 msp430 is not supported + +extern "msp430-interrupt" fn foo() {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi.rs new file mode 100644 index 000000000000..fbb745e7597b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi.rs @@ -0,0 +1,110 @@ +// only-x86_64 +// ignore-tidy-linelength +// gate-test-intrinsics +// gate-test-platform_intrinsics +// gate-test-abi_vectorcall +// gate-test-abi_thiscall +// gate-test-abi_ptx +// gate-test-abi_x86_interrupt +// gate-test-abi_amdgpu_kernel +// gate-test-abi_efiapi + +// Functions +extern "rust-intrinsic" fn f1() {} // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +extern "platform-intrinsic" fn f2() {} // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +extern "vectorcall" fn f3() {} // { dg-error ".E0658." "" { target *-*-* } } +extern "rust-call" fn f4() {} // { dg-error ".E0658." "" { target *-*-* } } +extern "msp430-interrupt" fn f5() {} // { dg-error ".E0658." "" { target *-*-* } } +extern "ptx-kernel" fn f6() {} // { dg-error ".E0658." "" { target *-*-* } } +extern "x86-interrupt" fn f7() {} // { dg-error ".E0658." "" { target *-*-* } } +extern "thiscall" fn f8() {} // { dg-error ".E0658." "" { target *-*-* } } +extern "amdgpu-kernel" fn f9() {} // { dg-error ".E0658." "" { target *-*-* } } +extern "efiapi" fn f10() {} // { dg-error ".E0658." "" { target *-*-* } } + +// Methods in trait definition +trait Tr { + extern "rust-intrinsic" fn m1(); // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + extern "platform-intrinsic" fn m2(); // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + extern "vectorcall" fn m3(); // { dg-error ".E0658." "" { target *-*-* } } + extern "rust-call" fn m4(); // { dg-error ".E0658." "" { target *-*-* } } + extern "msp430-interrupt" fn m5(); // { dg-error ".E0658." "" { target *-*-* } } + extern "ptx-kernel" fn m6(); // { dg-error ".E0658." "" { target *-*-* } } + extern "x86-interrupt" fn m7(); // { dg-error ".E0658." "" { target *-*-* } } + extern "thiscall" fn m8(); // { dg-error ".E0658." "" { target *-*-* } } + extern "amdgpu-kernel" fn m9(); // { dg-error ".E0658." "" { target *-*-* } } + extern "efiapi" fn m10(); // { dg-error ".E0658." "" { target *-*-* } } + + extern "vectorcall" fn dm3() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "rust-call" fn dm4() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "msp430-interrupt" fn dm5() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "ptx-kernel" fn dm6() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "x86-interrupt" fn dm7() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "thiscall" fn dm8() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "amdgpu-kernel" fn dm9() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "efiapi" fn dm10() {} // { dg-error ".E0658." "" { target *-*-* } } +} + +struct S; + +// Methods in trait impl +impl Tr for S { + extern "rust-intrinsic" fn m1() {} // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + extern "platform-intrinsic" fn m2() {} // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + extern "vectorcall" fn m3() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "rust-call" fn m4() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "msp430-interrupt" fn m5() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "ptx-kernel" fn m6() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "x86-interrupt" fn m7() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "thiscall" fn m8() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "amdgpu-kernel" fn m9() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "efiapi" fn m10() {} // { dg-error ".E0658." "" { target *-*-* } } +} + +// Methods in inherent impl +impl S { + extern "rust-intrinsic" fn im1() {} // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + extern "platform-intrinsic" fn im2() {} // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + extern "vectorcall" fn im3() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "rust-call" fn im4() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "msp430-interrupt" fn im5() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "ptx-kernel" fn im6() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "x86-interrupt" fn im7() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "thiscall" fn im8() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "amdgpu-kernel" fn im9() {} // { dg-error ".E0658." "" { target *-*-* } } + extern "efiapi" fn im10() {} // { dg-error ".E0658." "" { target *-*-* } } +} + +// Function pointer types +type A1 = extern "rust-intrinsic" fn(); // { dg-error ".E0658." "" { target *-*-* } } +type A2 = extern "platform-intrinsic" fn(); // { dg-error ".E0658." "" { target *-*-* } } +type A3 = extern "vectorcall" fn(); // { dg-error ".E0658." "" { target *-*-* } } +type A4 = extern "rust-call" fn(); // { dg-error ".E0658." "" { target *-*-* } } +type A5 = extern "msp430-interrupt" fn(); // { dg-error ".E0658." "" { target *-*-* } } +type A6 = extern "ptx-kernel" fn (); // { dg-error ".E0658." "" { target *-*-* } } +type A7 = extern "x86-interrupt" fn(); // { dg-error ".E0658." "" { target *-*-* } } +type A8 = extern "thiscall" fn(); // { dg-error ".E0658." "" { target *-*-* } } +type A9 = extern "amdgpu-kernel" fn(); // { dg-error ".E0658." "" { target *-*-* } } +type A10 = extern "efiapi" fn(); // { dg-error ".E0658." "" { target *-*-* } } + +// Foreign modules +extern "rust-intrinsic" {} // { dg-error ".E0658." "" { target *-*-* } } +extern "platform-intrinsic" {} // { dg-error ".E0658." "" { target *-*-* } } +extern "vectorcall" {} // { dg-error ".E0658." "" { target *-*-* } } +extern "rust-call" {} // { dg-error ".E0658." "" { target *-*-* } } +extern "msp430-interrupt" {} // { dg-error ".E0658." "" { target *-*-* } } +extern "ptx-kernel" {} // { dg-error ".E0658." "" { target *-*-* } } +extern "x86-interrupt" {} // { dg-error ".E0658." "" { target *-*-* } } +extern "thiscall" {} // { dg-error ".E0658." "" { target *-*-* } } +extern "amdgpu-kernel" {} // { dg-error ".E0658." "" { target *-*-* } } +extern "efiapi" {} // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi_unadjusted.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi_unadjusted.rs new file mode 100644 index 000000000000..cb9828e37f86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-abi_unadjusted.rs @@ -0,0 +1,8 @@ +extern "unadjusted" fn foo() { +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-alloc-error-handler.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-alloc-error-handler.rs new file mode 100644 index 000000000000..9db074046590 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-alloc-error-handler.rs @@ -0,0 +1,15 @@ +// compile-flags:-C panic=abort + +#![no_std] +#![no_main] + +use core::alloc::Layout; + +#[alloc_error_handler] // { dg-error ".E0658." "" { target *-*-* } } +fn oom(info: Layout) -> ! { + loop {} +} + +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allocator_internals.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allocator_internals.rs new file mode 100644 index 000000000000..b6c71a8cb8e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allocator_internals.rs @@ -0,0 +1,4 @@ +#![default_lib_allocator] // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.rs new file mode 100644 index 000000000000..cb0afa4acf58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unsafe-nested-macro.rs @@ -0,0 +1,18 @@ +// gate-test-allow_internal_unsafe + +#![allow(unused_macros)] + +macro_rules! bar { + () => { + // more layers don't help: + #[allow_internal_unsafe] // { dg-error ".E0658." "" { target *-*-* } } + macro_rules! baz { + () => {} + } + } +} + +bar!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.rs new file mode 100644 index 000000000000..5ecaa4750624 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable-nested-macro.rs @@ -0,0 +1,18 @@ +// gate-test-allow_internal_unstable + +#![allow(unused_macros)] + +macro_rules! bar { + () => { + // more layers don't help: + #[allow_internal_unstable()] // { dg-error ".E0658." "" { target *-*-* } } + macro_rules! baz { + () => {} + } + } +} + +bar!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable-struct.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable-struct.rs new file mode 100644 index 000000000000..9be1fbaa7ee8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable-struct.rs @@ -0,0 +1,9 @@ +// checks that this attribute is caught on non-macro items. +// this needs a different test since this is done after expansion + +#[allow_internal_unstable()] // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +struct S; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable.rs new file mode 100644 index 000000000000..62cb35e23747 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow-internal-unstable.rs @@ -0,0 +1,9 @@ +#![allow(unused_macros)] + +#[allow_internal_unstable()] // { dg-error ".E0658." "" { target *-*-* } } +macro_rules! foo { + () => {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow_fail.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow_fail.rs new file mode 100644 index 000000000000..f5ca2acbe7fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-allow_fail.rs @@ -0,0 +1,9 @@ +// check that #[allow_fail] is feature-gated + +#[allow_fail] // { dg-error ".E0658." "" { target *-*-* } } +fn ok_to_fail() { + assert!(false); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-arbitrary-self-types.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-arbitrary-self-types.rs new file mode 100644 index 000000000000..09bec585cc54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-arbitrary-self-types.rs @@ -0,0 +1,30 @@ +use std::{ + ops::Deref, +}; + +struct Ptr(Box); + +impl Deref for Ptr { + type Target = T; + + fn deref(&self) -> &T { + &*self.0 + } +} + +trait Foo { + fn foo(self: Ptr); // { dg-error ".E0658." "" { target *-*-* } } +} + +struct Bar; + +impl Foo for Bar { + fn foo(self: Ptr) {} // { dg-error ".E0658." "" { target *-*-* } } +} + +impl Bar { + fn bar(self: Box>) {} // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.rs new file mode 100644 index 000000000000..62b0aebb0be2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-arbitrary_self_types-raw-pointer.rs @@ -0,0 +1,19 @@ +struct Foo; + +impl Foo { + fn foo(self: *const Self) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +trait Bar { + fn bar(self: *const Self); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +impl Bar for () { + fn bar(self: *const Self) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-asm.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-asm.rs new file mode 100644 index 000000000000..584670745e08 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-asm.rs @@ -0,0 +1,11 @@ +// only-x86_64 + +fn main() { + unsafe { + asm!(""); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + llvm_asm!(""); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-asm2.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-asm2.rs new file mode 100644 index 000000000000..7fefac025b53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-asm2.rs @@ -0,0 +1,11 @@ +// only-x86_64 + +fn main() { + unsafe { + println!("{:?}", asm!("")); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + println!("{:?}", llvm_asm!("")); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-assoc-type-defaults.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-assoc-type-defaults.rs new file mode 100644 index 000000000000..b341281974c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-assoc-type-defaults.rs @@ -0,0 +1,8 @@ +// gate-test-associated_type_defaults + +trait Foo { + type Bar = u8; // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-associated_type_bounds.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-associated_type_bounds.rs new file mode 100644 index 000000000000..f0e9d01f11c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-associated_type_bounds.rs @@ -0,0 +1,77 @@ +// compile-flags: -Zsave-analysis +// This is also a regression test for #69415 and the above flag is needed. + +#![feature(untagged_unions)] + +trait Tr1 { type As1: Copy; } +trait Tr2 { type As2: Copy; } + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; } + +trait _Tr3 { + type A: Iterator; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + + type B: Iterator; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +struct _St1> { +// { dg-error ".E0658." "" { target *-*-* } .-1 } + outest: T, + outer: T::As1, + inner: ::As2, +} + +enum _En1> { +// { dg-error ".E0658." "" { target *-*-* } .-1 } + Outest(T), + Outer(T::As1), + Inner(::As2), +} + +union _Un1> { +// { dg-error ".E0658." "" { target *-*-* } .-1 } + outest: std::mem::ManuallyDrop, + outer: T::As1, + inner: ::As2, +} + +type _TaWhere1 where T: Iterator = T; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn _apit(_: impl Tr1) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn _apit_dyn(_: &dyn Tr1) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn _rpit() -> impl Tr1 { S1 } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn _rpit_dyn() -> Box> { Box::new(S1) } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +const _cdef: impl Tr1 = S1; +// { dg-error ".E0562." "" { target *-*-* } .-1 } +// { dg-error ".E0562." "" { target *-*-* } .-2 } +// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. +// const _cdef_dyn: &dyn Tr1 = &S1; + +static _sdef: impl Tr1 = S1; +// { dg-error ".E0562." "" { target *-*-* } .-1 } +// { dg-error ".E0562." "" { target *-*-* } .-2 } +// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. +// static _sdef_dyn: &dyn Tr1 = &S1; + +fn main() { + let _: impl Tr1 = S1; +// { dg-error ".E0562." "" { target *-*-* } .-1 } +// { dg-error ".E0562." "" { target *-*-* } .-2 } + // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. + // let _: &dyn Tr1 = &S1; +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-box-expr.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-box-expr.rs new file mode 100644 index 000000000000..a6140d3d9de3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-box-expr.rs @@ -0,0 +1,15 @@ +// gate-test-box_syntax + +// Check that `box EXPR` is feature-gated. +// +// See also feature-gate-placement-expr.rs +// +// (Note that the two tests are separated since the checks appear to +// be performed at distinct phases, with an abort_if_errors call +// separating them.) + +fn main() { + let x = box 'c'; // { dg-error ".E0658." "" { target *-*-* } } + println!("x: {}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-box_patterns.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-box_patterns.rs new file mode 100644 index 000000000000..a7ddf2f646e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-box_patterns.rs @@ -0,0 +1,5 @@ +fn main() { + let box x = Box::new('c'); // { dg-error ".E0658." "" { target *-*-* } } + println!("x: {}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-box_syntax.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-box_syntax.rs new file mode 100644 index 000000000000..bd60ddcc1e1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-box_syntax.rs @@ -0,0 +1,7 @@ +// Test that the use of the box syntax is gated by `box_syntax` feature gate. + +fn main() { + let x = box 3; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-panic.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-panic.rs new file mode 100644 index 000000000000..f8528fcbf24b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-panic.rs @@ -0,0 +1,12 @@ +#[cfg(panic = "unwind")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn foo() -> bool { true } +#[cfg(not(panic = "unwind"))] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn foo() -> bool { false } + + +fn main() { + assert!(foo()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-target-has-atomic.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-target-has-atomic.rs new file mode 100644 index 000000000000..d6e6e4e0881d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-target-has-atomic.rs @@ -0,0 +1,119 @@ +#![feature(intrinsics, lang_items, no_core, rustc_attrs)] + +#![crate_type="rlib"] +#![no_core] + +extern "rust-intrinsic" { + fn atomic_xadd(dst: *mut T, src: T) -> T; +} + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +#[cfg(target_has_atomic = "8")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +pub unsafe fn atomic_u8(x: *mut u8) { + atomic_xadd(x, 1); + atomic_xadd(x, 1); +} +#[cfg(target_has_atomic = "8")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +pub unsafe fn atomic_i8(x: *mut i8) { + atomic_xadd(x, 1); +} +#[cfg(target_has_atomic = "16")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +pub unsafe fn atomic_u16(x: *mut u16) { + atomic_xadd(x, 1); +} +#[cfg(target_has_atomic = "16")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +pub unsafe fn atomic_i16(x: *mut i16) { + atomic_xadd(x, 1); +} +#[cfg(target_has_atomic = "32")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +pub unsafe fn atomic_u32(x: *mut u32) { + atomic_xadd(x, 1); +} +#[cfg(target_has_atomic = "32")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +pub unsafe fn atomic_i32(x: *mut i32) { + atomic_xadd(x, 1); +} +#[cfg(target_has_atomic = "64")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +pub unsafe fn atomic_u64(x: *mut u64) { + atomic_xadd(x, 1); +} +#[cfg(target_has_atomic = "64")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +pub unsafe fn atomic_i64(x: *mut i64) { + atomic_xadd(x, 1); +} +#[cfg(target_has_atomic = "128")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +pub unsafe fn atomic_u128(x: *mut u128) { + atomic_xadd(x, 1); +} +#[cfg(target_has_atomic = "128")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +pub unsafe fn atomic_i128(x: *mut i128) { + atomic_xadd(x, 1); +} +#[cfg(target_has_atomic = "ptr")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +pub unsafe fn atomic_usize(x: *mut usize) { + atomic_xadd(x, 1); +} +#[cfg(target_has_atomic = "ptr")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +pub unsafe fn atomic_isize(x: *mut isize) { + atomic_xadd(x, 1); +} + +fn main() { + cfg!(target_has_atomic = "8"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic = "16"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic = "32"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic = "64"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic = "128"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic = "ptr"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic_load_store = "8"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic_load_store = "16"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic_load_store = "32"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic_load_store = "64"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic_load_store = "128"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic_load_store = "ptr"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic_equal_alignment = "8"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic_equal_alignment = "16"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic_equal_alignment = "32"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic_equal_alignment = "64"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic_equal_alignment = "128"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + cfg!(target_has_atomic_equal_alignment = "ptr"); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +#[macro_export] +#[rustc_builtin_macro] +macro_rules! cfg { () => () } + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-target-thread-local.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-target-thread-local.rs new file mode 100644 index 000000000000..ea58ceb872ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-target-thread-local.rs @@ -0,0 +1,18 @@ +// ignore-windows +// aux-build:cfg-target-thread-local.rs + +#![feature(thread_local)] + +extern crate cfg_target_thread_local; + +extern { + #[cfg_attr(target_thread_local, thread_local)] +// { dg-error ".E0658." "" { target *-*-* } .-1 } + + static FOO: u32; +} + +fn main() { + assert_eq!(FOO, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-version.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-version.rs new file mode 100644 index 000000000000..72582ae5a474 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg-version.rs @@ -0,0 +1,42 @@ +#[cfg(version("1.44"))] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn foo() -> bool { true } +#[cfg(not(version("1.44")))] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn foo() -> bool { false } + +#[cfg(version("1.43", "1.44", "1.45"))] // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn bar() -> bool { false } +#[cfg(version(false))] // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn bar() -> bool { false } +#[cfg(version("foo"))] // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn bar() -> bool { false } +#[cfg(version("999"))] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn bar() -> bool { false } +#[cfg(version("-1"))] // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn bar() -> bool { false } +#[cfg(version("65536"))] // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn bar() -> bool { false } +#[cfg(version("0"))] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn bar() -> bool { true } + +#[cfg(version("1.65536.2"))] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn version_check_bug() {} + +fn main() { + // This should fail but due to a bug in version_check `1.65536.2` is interpreted as `1.2`. + // See https://github.com/SergioBenitez/version_check/issues/11 + version_check_bug(); + assert!(foo()); + assert!(bar()); + assert!(cfg!(version("1.42"))); // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg_sanitize.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg_sanitize.rs new file mode 100644 index 000000000000..5ec4ec768898 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-cfg_sanitize.rs @@ -0,0 +1,4 @@ +#[cfg(not(sanitize = "thread"))] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-compiler-builtins.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-compiler-builtins.rs new file mode 100644 index 000000000000..807b8407d351 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-compiler-builtins.rs @@ -0,0 +1,4 @@ +#![compiler_builtins] // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-concat_idents.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-concat_idents.rs new file mode 100644 index 000000000000..383d02272882 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-concat_idents.rs @@ -0,0 +1,10 @@ +const XY_1: i32 = 10; + +fn main() { + const XY_2: i32 = 20; + let a = concat_idents!(X, Y_1); // { dg-error ".E0658." "" { target *-*-* } } + let b = concat_idents!(X, Y_2); // { dg-error ".E0658." "" { target *-*-* } } + assert_eq!(a, 10); + assert_eq!(b, 20); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-concat_idents2.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-concat_idents2.rs new file mode 100644 index 000000000000..5bd56801e488 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-concat_idents2.rs @@ -0,0 +1,5 @@ +fn main() { + concat_idents!(a, b); // { dg-error ".E0425." "" { target *-*-* } } +// { dg-error ".E0425." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-concat_idents3.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-concat_idents3.rs new file mode 100644 index 000000000000..be91996e3b0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-concat_idents3.rs @@ -0,0 +1,8 @@ +const XY_1: i32 = 10; + +fn main() { + const XY_2: i32 = 20; + assert_eq!(10, concat_idents!(X, Y_1)); // { dg-error ".E0658." "" { target *-*-* } } + assert_eq!(20, concat_idents!(X, Y_2)); // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const-indexing.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const-indexing.rs new file mode 100644 index 000000000000..8e0fb276b63c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const-indexing.rs @@ -0,0 +1,9 @@ +// build-pass (FIXME(62277): could be check-pass?) + +fn main() { + const ARR: [i32; 6] = [42, 43, 44, 45, 46, 47]; + const IDX: usize = 3; + const VAL: i32 = ARR[IDX]; + const BLUB: [i32; (ARR[0] - 41) as usize] = [5]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_fn.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_fn.rs new file mode 100644 index 000000000000..f0839972a879 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_fn.rs @@ -0,0 +1,38 @@ +// Test use of advanced const fn without the `const_fn` feature gate. + +const fn foo() -> usize { 0 } // ok + +trait Foo { + const fn foo() -> u32; // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0379." "" { target *-*-* } .-2 } + const fn bar() -> u32 { 0 } // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0379." "" { target *-*-* } .-2 } +} + +impl Foo for u32 { + const fn foo() -> u32 { 0 } // { dg-error ".E0379." "" { target *-*-* } } +} + +trait Bar {} + +impl dyn Bar { + const fn baz() -> u32 { 0 } // ok +} + +static FOO: usize = foo(); +const BAR: usize = foo(); + +macro_rules! constant { + ($n:ident: $t:ty = $v:expr) => { + const $n: $t = $v; + } +} + +constant! { + BAZ: usize = foo() +} + +fn main() { + let x: [usize; foo()] = []; +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_fn_transmute.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_fn_transmute.rs new file mode 100644 index 000000000000..781a9c210ee7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_fn_transmute.rs @@ -0,0 +1,39 @@ +use std::mem; + +#[repr(transparent)] +struct Foo(u32); + +const TRANSMUTED_U32: u32 = unsafe { mem::transmute(Foo(3)) }; + +const fn transmute_fn() -> u32 { unsafe { mem::transmute(Foo(3)) } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +const fn transmute_fn_intrinsic() -> u32 { unsafe { std::intrinsics::transmute(Foo(3)) } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +const fn transmute_fn_core_intrinsic() -> u32 { unsafe { core::intrinsics::transmute(Foo(3)) } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +const unsafe fn unsafe_transmute_fn() -> u32 { mem::transmute(Foo(3)) } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +const unsafe fn unsafe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +const unsafe fn unsafe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) } +// { dg-error ".E0133." "" { target *-*-* } .-1 } +// { dg-error ".E0133." "" { target *-*-* } .-2 } + +const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) } +// { dg-error ".E0133." "" { target *-*-* } .-1 } +// { dg-error ".E0133." "" { target *-*-* } .-2 } + +const fn safe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) } +// { dg-error ".E0133." "" { target *-*-* } .-1 } +// { dg-error ".E0133." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_generics-ptr.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_generics-ptr.rs new file mode 100644 index 000000000000..c6db3f4e5cee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_generics-ptr.rs @@ -0,0 +1,10 @@ +struct ConstFn; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + +struct ConstPtr; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_generics.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_generics.rs new file mode 100644 index 000000000000..8718479c1adf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_generics.rs @@ -0,0 +1,6 @@ +fn foo() {} // { dg-error ".E0658." "" { target *-*-* } } + +struct Foo([(); X]); // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.rs new file mode 100644 index 000000000000..4070a0fcdaaa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-const_in_array_repeat_expressions.rs @@ -0,0 +1,18 @@ +#![allow(warnings)] + +struct Bar; + +// This function would compile with the feature gate, and tests that it is suggested. +fn foo() { + let arr: [Option; 2] = [None::; 2]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +// This function would not compile with the feature gate, and tests that it is not suggested. +fn bar() { + let arr: [Option; 2] = [Some("foo".to_string()); 2]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-crate_visibility_modifier.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-crate_visibility_modifier.rs new file mode 100644 index 000000000000..190c4067a311 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-crate_visibility_modifier.rs @@ -0,0 +1,9 @@ +crate struct Bender { // { dg-error ".E0658." "" { target *-*-* } } + earth: bool, + fire: bool, + air: bool, + water: bool, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-custom_attribute.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-custom_attribute.rs new file mode 100644 index 000000000000..e8fc60aa4f43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-custom_attribute.rs @@ -0,0 +1,19 @@ +// Check that literals in attributes parse just fine. + +#[fake_attr] // { dg-error "" "" { target *-*-* } } +#[fake_attr(100)] // { dg-error "" "" { target *-*-* } } +#[fake_attr(1, 2, 3)] // { dg-error "" "" { target *-*-* } } +#[fake_attr("hello")] // { dg-error "" "" { target *-*-* } } +#[fake_attr(name = "hello")] // { dg-error "" "" { target *-*-* } } +#[fake_attr(1, "hi", key = 12, true, false)] // { dg-error "" "" { target *-*-* } } +#[fake_attr(key = "hello", val = 10)] // { dg-error "" "" { target *-*-* } } +#[fake_attr(key("hello"), val(10))] // { dg-error "" "" { target *-*-* } } +#[fake_attr(enabled = true, disabled = false)] // { dg-error "" "" { target *-*-* } } +#[fake_attr(true)] // { dg-error "" "" { target *-*-* } } +#[fake_attr(pi = 3.14159)] // { dg-error "" "" { target *-*-* } } +#[fake_attr(b"hi")] // { dg-error "" "" { target *-*-* } } +#[fake_doc(r"doc")] // { dg-error "" "" { target *-*-* } } +struct Q {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-custom_attribute2.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-custom_attribute2.rs new file mode 100644 index 000000000000..8facc8af4cd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-custom_attribute2.rs @@ -0,0 +1,59 @@ +// This test ensures that attributes on formals in generic parameter +// lists are included when we are checking for unstable attributes. + +struct StLt<#[lt_struct] 'a>(&'a u32); +// { dg-error "" "" { target *-*-* } .-1 } +struct StTy<#[ty_struct] I>(I); +// { dg-error "" "" { target *-*-* } .-1 } + +enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } +// { dg-error "" "" { target *-*-* } .-1 } +enum EnTy<#[ty_enum] J> { A(J), B } +// { dg-error "" "" { target *-*-* } .-1 } + +trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } +// { dg-error "" "" { target *-*-* } .-1 } +trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } +// { dg-error "" "" { target *-*-* } .-1 } + +type TyLt<#[lt_type] 'd> = &'d u32; +// { dg-error "" "" { target *-*-* } .-1 } +type TyTy<#[ty_type] L> = (L, ); +// { dg-error "" "" { target *-*-* } .-1 } + +impl<#[lt_inherent] 'e> StLt<'e> { } +// { dg-error "" "" { target *-*-* } .-1 } +impl<#[ty_inherent] M> StTy { } +// { dg-error "" "" { target *-*-* } .-1 } + +impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { +// { dg-error "" "" { target *-*-* } .-1 } + fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } } +} +impl<#[ty_impl_for] N> TrTy for StTy { +// { dg-error "" "" { target *-*-* } .-1 } + fn foo(&self, _: N) { } +} + +fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } +// { dg-error "" "" { target *-*-* } .-1 } +fn f_ty<#[ty_fn] O>(_: O) { } +// { dg-error "" "" { target *-*-* } .-1 } + +impl StTy { + fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } +// { dg-error "" "" { target *-*-* } .-1 } + fn m_ty<#[ty_meth] P>(_: P) { } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn hof_lt(_: Q) + where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 +// { dg-error "" "" { target *-*-* } .-1 } +{ +} + +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-custom_test_frameworks.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-custom_test_frameworks.rs new file mode 100644 index 000000000000..5b2c202dc21f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-custom_test_frameworks.rs @@ -0,0 +1,7 @@ +#![test_runner(main)] // { dg-error ".E0658." "" { target *-*-* } } + +#[test_case] // { dg-error ".E0658." "" { target *-*-* } } +fn f() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-decl_macro.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-decl_macro.rs new file mode 100644 index 000000000000..7007e22624d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-decl_macro.rs @@ -0,0 +1,6 @@ +#![allow(unused_macros)] + +macro m() {} // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-default_type_parameter_fallback.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-default_type_parameter_fallback.rs new file mode 100644 index 000000000000..82a85b3d9178 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-default_type_parameter_fallback.rs @@ -0,0 +1,13 @@ +#![allow(unused)] + +fn avg(_: T) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +struct S(T); +impl S {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-destructuring_assignment.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-destructuring_assignment.rs new file mode 100644 index 000000000000..cf6a1249904b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-destructuring_assignment.rs @@ -0,0 +1,5 @@ +fn main() { + let (a, b) = (0, 1); + (a, b) = (2, 3); // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_cfg.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_cfg.rs new file mode 100644 index 000000000000..0fe56b8c0f27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_cfg.rs @@ -0,0 +1,3 @@ +#[doc(cfg(unix))] // { dg-error ".E0658." "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_keyword.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_keyword.rs new file mode 100644 index 000000000000..761bc5a9393c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_keyword.rs @@ -0,0 +1,6 @@ +#[doc(keyword = "match")] // { dg-error ".E0658." "" { target *-*-* } } +/// wonderful +mod foo{} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_masked.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_masked.rs new file mode 100644 index 000000000000..0909d134fb95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_masked.rs @@ -0,0 +1,5 @@ +#[doc(masked)] // { dg-error ".E0658." "" { target *-*-* } } +extern crate std as realstd; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_spotlight.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_spotlight.rs new file mode 100644 index 000000000000..875ea22aa126 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-doc_spotlight.rs @@ -0,0 +1,5 @@ +#[doc(spotlight)] // { dg-error ".E0658." "" { target *-*-* } } +trait SomeTrait {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-exclusive-range-pattern.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-exclusive-range-pattern.rs new file mode 100644 index 000000000000..7fcff9715164 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-exclusive-range-pattern.rs @@ -0,0 +1,7 @@ +pub fn main() { + match 22 { + 0 .. 3 => {} // { dg-error ".E0658." "" { target *-*-* } } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-exhaustive-patterns.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-exhaustive-patterns.rs new file mode 100644 index 000000000000..3da78f5418eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-exhaustive-patterns.rs @@ -0,0 +1,10 @@ +#![feature(never_type)] + +fn foo() -> Result { + Ok(123) +} + +fn main() { + let Ok(_x) = foo(); // { dg-error ".E0005." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-extern_absolute_paths.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-extern_absolute_paths.rs new file mode 100644 index 000000000000..9874799edb6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-extern_absolute_paths.rs @@ -0,0 +1,6 @@ +use core::default; // { dg-error ".E0432." "" { target *-*-* } } + +fn main() { + let _: u8 = ::core::default::Default(); // { dg-error ".E0433." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-extern_prelude.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-extern_prelude.rs new file mode 100644 index 000000000000..3a27567e09bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-extern_prelude.rs @@ -0,0 +1,2 @@ +can-only-test-this-in-run-make-fulldeps // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-extern_types.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-extern_types.rs new file mode 100644 index 000000000000..e85dc1d4ca8a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-extern_types.rs @@ -0,0 +1,6 @@ +extern { + type T; // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-external_doc.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-external_doc.rs new file mode 100644 index 000000000000..445838eab192 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-external_doc.rs @@ -0,0 +1,4 @@ +#[doc(include="asdf.md")] // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-feature-gate.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-feature-gate.rs new file mode 100644 index 000000000000..c12d8fd3f7ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-feature-gate.rs @@ -0,0 +1,5 @@ +#![forbid(unstable_features)] +#![feature(intrinsics)] // { dg-error "" "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-ffi_const.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-ffi_const.rs new file mode 100644 index 000000000000..778765982107 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-ffi_const.rs @@ -0,0 +1,7 @@ +#![crate_type = "lib"] + +extern { + #[ffi_const] // { dg-error ".E0658." "" { target *-*-* } } + pub fn foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-ffi_pure.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-ffi_pure.rs new file mode 100644 index 000000000000..ce7a4020aa2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-ffi_pure.rs @@ -0,0 +1,7 @@ +#![crate_type = "lib"] + +extern { + #[ffi_pure] // { dg-error ".E0658." "" { target *-*-* } } + pub fn foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-ffi_returns_twice.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-ffi_returns_twice.rs new file mode 100644 index 000000000000..b5fa69dc9f07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-ffi_returns_twice.rs @@ -0,0 +1,7 @@ +#![crate_type = "lib"] + +extern { + #[ffi_returns_twice] // { dg-error ".E0658." "" { target *-*-* } } + pub fn foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-format_args_nl.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-format_args_nl.rs new file mode 100644 index 000000000000..735f3538400b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-format_args_nl.rs @@ -0,0 +1,4 @@ +fn main() { + format_args_nl!(""); // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-fundamental.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-fundamental.rs new file mode 100644 index 000000000000..66ff5651a32e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-fundamental.rs @@ -0,0 +1,5 @@ +#[fundamental] // { dg-error ".E0658." "" { target *-*-* } } +struct Fundamental; + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-generators.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-generators.rs new file mode 100644 index 000000000000..c750db495856 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-generators.rs @@ -0,0 +1,11 @@ +fn main() { + yield true; // { dg-error ".E0627." "" { target *-*-* } } +// { dg-error ".E0627." "" { target *-*-* } .-1 } +} + +#[cfg(FALSE)] +fn foo() { + yield; // { dg-error ".E0658." "" { target *-*-* } } + yield 0; // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-generic_associated_types.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-generic_associated_types.rs new file mode 100644 index 000000000000..5fd2d7293cd5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-generic_associated_types.rs @@ -0,0 +1,32 @@ +use std::ops::Deref; + +trait PointerFamily { + type Pointer: Deref; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + type Pointer2: Deref where T: Clone, U: Clone; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +} + +struct Foo; + +impl PointerFamily for Foo { + type Pointer = Box; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + type Pointer2 = Box; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + +trait Bar { + type Assoc where Self: Sized; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +impl Bar for Foo { + type Assoc where Self: Sized = Foo; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-global_asm.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-global_asm.rs new file mode 100644 index 000000000000..7cec099598d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-global_asm.rs @@ -0,0 +1,4 @@ +global_asm!(""); // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-impl_trait_in_bindings.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-impl_trait_in_bindings.rs new file mode 100644 index 000000000000..c7349e9e4c7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-impl_trait_in_bindings.rs @@ -0,0 +1,12 @@ +const FOO: impl Copy = 42; +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +static BAR: impl Copy = 42; +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +fn main() { + let foo = impl Copy = 42; +// { dg-error "" "" { target *-*-* } .-1 } + let foo: impl Copy = 42; +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-in_band_lifetimes.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-in_band_lifetimes.rs new file mode 100644 index 000000000000..cc2fd7dcb7a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-in_band_lifetimes.rs @@ -0,0 +1,63 @@ +#![allow(warnings)] + +fn foo(x: &'x u8) -> &'x u8 { x } +// { dg-error ".E0261." "" { target *-*-* } .-1 } +// { dg-error ".E0261." "" { target *-*-* } .-2 } + +struct X<'a>(&'a u8); + +impl<'a> X<'a> { + fn inner(&self) -> &'a u8 { + self.0 + } +} + +impl<'a> X<'b> { +// { dg-error ".E0261." "" { target *-*-* } .-1 } + fn inner_2(&self) -> &'b u8 { +// { dg-error ".E0261." "" { target *-*-* } .-1 } + self.0 + } +} + +impl X<'b> { +// { dg-error ".E0261." "" { target *-*-* } .-1 } + fn inner_3(&self) -> &'b u8 { +// { dg-error ".E0261." "" { target *-*-* } .-1 } + self.0 + } +} + +struct Y(T); + +impl Y<&'a u8> { +// { dg-error ".E0261." "" { target *-*-* } .-1 } + fn inner(&self) -> &'a u8 { +// { dg-error ".E0261." "" { target *-*-* } .-1 } + self.0 + } +} + +trait MyTrait<'a> { + fn my_lifetime(&self) -> &'a u8; + fn any_lifetime() -> &'b u8; +// { dg-error ".E0261." "" { target *-*-* } .-1 } + fn borrowed_lifetime(&'b self) -> &'b u8; +// { dg-error ".E0261." "" { target *-*-* } .-1 } +// { dg-error ".E0261." "" { target *-*-* } .-2 } +} + +impl MyTrait<'a> for Y<&'a u8> { +// { dg-error ".E0261." "" { target *-*-* } .-1 } +// { dg-error ".E0261." "" { target *-*-* } .-2 } + fn my_lifetime(&self) -> &'a u8 { self.0 } +// { dg-error ".E0261." "" { target *-*-* } .-1 } + fn any_lifetime() -> &'b u8 { &0 } +// { dg-error ".E0261." "" { target *-*-* } .-1 } + fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 } +// { dg-error ".E0261." "" { target *-*-* } .-1 } +// { dg-error ".E0261." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-infer_static_outlives_requirements.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-infer_static_outlives_requirements.rs new file mode 100644 index 000000000000..2923e20f9811 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-infer_static_outlives_requirements.rs @@ -0,0 +1,13 @@ +// Needs an explicit where clause stating outlives condition. (RFC 2093) + +// Type T needs to outlive lifetime 'static. +struct Foo { + bar: Bar // { dg-error ".E0310." "" { target *-*-* } } +} +struct Bar { + x: T, +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-intrinsics.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-intrinsics.rs new file mode 100644 index 000000000000..1bf4a5ec43f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-intrinsics.rs @@ -0,0 +1,9 @@ +extern "rust-intrinsic" { // { dg-error ".E0658." "" { target *-*-* } } + fn bar(); // { dg-error ".E0093." "" { target *-*-* } } +} + +extern "rust-intrinsic" fn baz() {} // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-is_sorted.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-is_sorted.rs new file mode 100644 index 000000000000..9a034fdc9f0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-is_sorted.rs @@ -0,0 +1,14 @@ +fn main() { + // Assert `Iterator` methods are unstable + assert!([1, 2, 2, 9].iter().is_sorted()); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + + // Assert `[T]` methods are unstable + assert!([1, 2, 2, 9].is_sorted()); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-label_break_value.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-label_break_value.rs new file mode 100644 index 000000000000..a3b5a6d847d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-label_break_value.rs @@ -0,0 +1,6 @@ +pub fn main() { + 'a: { // { dg-error ".E0658." "" { target *-*-* } } + break 'a; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-lang-items.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-lang-items.rs new file mode 100644 index 000000000000..abce0b8ec419 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-lang-items.rs @@ -0,0 +1,6 @@ +#[lang = "foo"] // { dg-error ".E0522." "" { target *-*-* } } +// { dg-error ".E0522." "" { target *-*-* } .-1 } +trait Foo {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-link_args.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-link_args.rs new file mode 100644 index 000000000000..6533ebefe761 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-link_args.rs @@ -0,0 +1,19 @@ +// Test that `#[link_args]` attribute is gated by `link_args` +// feature gate, both when it occurs where expected (atop +// `extern { }` blocks) and where unexpected. + +// sidestep warning (which is correct, but misleading for +// purposes of this test) +#![allow(unused_attributes)] + +#![link_args = "-l unexpected_use_as_inner_attr_on_mod"] +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +#[link_args = "-l expected_use_case"] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +extern {} + +#[link_args = "-l unexected_use_on_non_extern_item"] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-link_cfg.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-link_cfg.rs new file mode 100644 index 000000000000..eb644c0d3a00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-link_cfg.rs @@ -0,0 +1,6 @@ +#[link(name = "foo", cfg(foo))] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +extern {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-link_llvm_intrinsics.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-link_llvm_intrinsics.rs new file mode 100644 index 000000000000..048a51322c98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-link_llvm_intrinsics.rs @@ -0,0 +1,9 @@ +extern { + #[link_name = "llvm.sqrt.f32"] + fn sqrt(x: f32) -> f32; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +fn main(){ +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-linkage.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-linkage.rs new file mode 100644 index 000000000000..fb0eeccb8f82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-linkage.rs @@ -0,0 +1,7 @@ +extern { + #[linkage = "extern_weak"] static foo: isize; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-lint-reasons.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-lint-reasons.rs new file mode 100644 index 000000000000..e852e979301c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-lint-reasons.rs @@ -0,0 +1,7 @@ +#![warn(nonstandard_style, reason = "the standard should be respected")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-log_syntax.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-log_syntax.rs new file mode 100644 index 000000000000..767975b6af37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-log_syntax.rs @@ -0,0 +1,4 @@ +fn main() { + log_syntax!() // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-log_syntax2.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-log_syntax2.rs new file mode 100644 index 000000000000..10dd14750419 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-log_syntax2.rs @@ -0,0 +1,4 @@ +fn main() { + println!("{:?}", log_syntax!()); // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-main.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-main.rs new file mode 100644 index 000000000000..73c72c86efb6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-main.rs @@ -0,0 +1,3 @@ +#[main] +fn foo() {} // { dg-error ".E0658." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-marker_trait_attr.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-marker_trait_attr.rs new file mode 100644 index 000000000000..497f36e0fd94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-marker_trait_attr.rs @@ -0,0 +1,10 @@ +use std::fmt::{Debug, Display}; + +#[marker] trait ExplicitMarker {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +impl ExplicitMarker for T {} +impl ExplicitMarker for T {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-may-dangle.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-may-dangle.rs new file mode 100644 index 000000000000..11f2a3131a11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-may-dangle.rs @@ -0,0 +1,12 @@ +// gate-test-dropck_eyepatch + +// Check that `may_dangle` is rejected if `dropck_eyepatch` feature gate is absent. + +struct Pt(A); +unsafe impl<#[may_dangle] A> Drop for Pt { +// { dg-error ".E0658." "" { target *-*-* } .-1 } + fn drop(&mut self) { } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-member-constraints.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-member-constraints.rs new file mode 100644 index 000000000000..401634cd307d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-member-constraints.rs @@ -0,0 +1,11 @@ +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} + +fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + (x, y) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-min_const_fn.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-min_const_fn.rs new file mode 100644 index 000000000000..08ccc4c887e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-min_const_fn.rs @@ -0,0 +1,38 @@ +// Test use of min_const_fn without feature gate. + +const fn foo() -> usize { 0 } // stabilized + +trait Foo { + const fn foo() -> u32; // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0379." "" { target *-*-* } .-2 } + const fn bar() -> u32 { 0 } // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0379." "" { target *-*-* } .-2 } +} + +impl Foo for u32 { + const fn foo() -> u32 { 0 } // { dg-error ".E0379." "" { target *-*-* } } +} + +trait Bar {} + +impl dyn Bar { + const fn baz() -> u32 { 0 } // stabilized +} + +static FOO: usize = foo(); +const BAR: usize = foo(); + +macro_rules! constant { + ($n:ident: $t:ty = $v:expr) => { + const $n: $t = $v; + } +} + +constant! { + BAZ: usize = foo() +} + +fn main() { + let x: [usize; foo()] = []; +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-naked_functions.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-naked_functions.rs new file mode 100644 index 000000000000..1ae1d2499467 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-naked_functions.rs @@ -0,0 +1,12 @@ +#[naked] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn naked() {} + +#[naked] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn naked_2() -> isize { + 0 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-needs-allocator.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-needs-allocator.rs new file mode 100644 index 000000000000..58af83ff9914 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-needs-allocator.rs @@ -0,0 +1,4 @@ +#![needs_allocator] // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-negate-unsigned.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-negate-unsigned.rs new file mode 100644 index 000000000000..c1567cd4ecb5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-negate-unsigned.rs @@ -0,0 +1,19 @@ +// Test that negating unsigned integers doesn't compile + +struct S; +impl std::ops::Neg for S { + type Output = u32; + fn neg(self) -> u32 { 0 } +} + +fn main() { + let _max: usize = -1; +// { dg-error ".E0600." "" { target *-*-* } .-1 } + + let x = 5u8; + let _y = -x; +// { dg-error ".E0600." "" { target *-*-* } .-1 } + + -S; // should not trigger the gate; issue 26840 +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-never_type.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-never_type.rs new file mode 100644 index 000000000000..778c289d4f60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-never_type.rs @@ -0,0 +1,18 @@ +// Test that ! errors when used in illegal positions with feature(never_type) disabled + +trait Foo { + type Wub; +} + +type Ma = (u32, !, i32); // { dg-error ".E0658." "" { target *-*-* } } +type Meeshka = Vec; // { dg-error ".E0658." "" { target *-*-* } } +type Mow = &'static fn(!) -> !; // { dg-error ".E0658." "" { target *-*-* } } +type Skwoz = &'static mut !; // { dg-error ".E0658." "" { target *-*-* } } + +impl Foo for Meeshka { + type Wub = !; // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-nll.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-nll.rs new file mode 100644 index 000000000000..f6c46a89bf36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-nll.rs @@ -0,0 +1,19 @@ +// There isn't a great way to test feature(nll), since it just disables migrate +// mode and changes some error messages. + +// FIXME(Centril): This test is probably obsolete now and `nll` should become +// `accepted`. + +// Don't use compare-mode=nll, since that turns on NLL. +// ignore-compare-mode-nll +// ignore-compare-mode-polonius + +fn main() { + let mut x = (33, &0); + + let m = &mut x; + let p = &*x.1; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + m; +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-no_core.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-no_core.rs new file mode 100644 index 000000000000..83fd3bf8f959 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-no_core.rs @@ -0,0 +1,6 @@ +#![crate_type = "rlib"] + +#![no_core] // { dg-error ".E0658." "" { target *-*-* } } + +pub struct S {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-no_sanitize.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-no_sanitize.rs new file mode 100644 index 000000000000..f574bfe693b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-no_sanitize.rs @@ -0,0 +1,5 @@ +#[no_sanitize(address)] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-non_ascii_idents.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-non_ascii_idents.rs new file mode 100644 index 000000000000..1814d3294599 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-non_ascii_idents.rs @@ -0,0 +1,34 @@ +extern crate core as bäz; // { dg-error ".E0658." "" { target *-*-* } } + +use föö::bar; // { dg-error ".E0658." "" { target *-*-* } } + +mod föö { // { dg-error ".E0658." "" { target *-*-* } } + pub fn bar() {} +} + +fn bär( // { dg-error ".E0658." "" { target *-*-* } } + bäz: isize // { dg-error ".E0658." "" { target *-*-* } } + ) { + let _ö: isize; // { dg-error ".E0658." "" { target *-*-* } } + + match (1, 2) { + (_ä, _) => {} // { dg-error ".E0658." "" { target *-*-* } } + } +} + +struct Föö { // { dg-error ".E0658." "" { target *-*-* } } + föö: isize // { dg-error ".E0658." "" { target *-*-* } } +} + +enum Bär { // { dg-error ".E0658." "" { target *-*-* } } + Bäz { // { dg-error ".E0658." "" { target *-*-* } } + qüx: isize // { dg-error ".E0658." "" { target *-*-* } } + } +} + +extern { + fn qüx(); // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs new file mode 100644 index 000000000000..fd9b7750fb19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs @@ -0,0 +1,42 @@ +// Test that the use of the non object-safe trait objects +// are gated by `object_safe_for_dispatch` feature gate. + +trait NonObjectSafe1: Sized {} + +trait NonObjectSafe2 { + fn static_fn() {} +} + +trait NonObjectSafe3 { + fn foo(&self); +} + +trait NonObjectSafe4 { + fn foo(&self, &Self); +} + +fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { +// { dg-error ".E0038." "" { target *-*-* } .-1 } +} + +fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 { +// { dg-error ".E0038." "" { target *-*-* } .-1 } + loop {} +} + +fn takes_non_object_safe_box(obj: Box) { +// { dg-error ".E0038." "" { target *-*-* } .-1 } +} + +fn return_non_object_safe_rc() -> std::rc::Rc { +// { dg-error ".E0038." "" { target *-*-* } .-1 } + loop {} +} + +trait Trait {} + +impl Trait for dyn NonObjectSafe1 {} +// { dg-error ".E0038." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.rs new file mode 100644 index 000000000000..292d229f610f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-omit-gdb-pretty-printer-section.rs @@ -0,0 +1,3 @@ +#[omit_gdb_pretty_printer_section] // { dg-error ".E0658." "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-optin-builtin-traits.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-optin-builtin-traits.rs new file mode 100644 index 000000000000..72ba235a63a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-optin-builtin-traits.rs @@ -0,0 +1,13 @@ +// Test that default and negative trait implementations are gated by +// `optin_builtin_traits` feature gate + +struct DummyStruct; + +auto trait AutoDummyTrait {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +impl !AutoDummyTrait for DummyStruct {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-overlapping_marker_traits.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-overlapping_marker_traits.rs new file mode 100644 index 000000000000..f0d4e257defa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-overlapping_marker_traits.rs @@ -0,0 +1,10 @@ +use std::fmt::{Debug, Display}; + +trait MyMarker {} + +impl MyMarker for T {} +impl MyMarker for T {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-plugin_registrar.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-plugin_registrar.rs new file mode 100644 index 000000000000..9566548ca558 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-plugin_registrar.rs @@ -0,0 +1,12 @@ +// Test that `#[plugin_registrar]` attribute is gated by `plugin_registrar` +// feature gate. + +// the registration function isn't typechecked yet +#[plugin_registrar] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-warning ".E0658." "" { target *-*-* } .-2 } +pub fn registrar() {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs new file mode 100644 index 000000000000..5c22a5f456f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-precise_pointer_size_matching.rs @@ -0,0 +1,15 @@ +#![feature(exclusive_range_pattern)] + +use std::usize::MAX; + +fn main() { + match 0usize { // { dg-error ".E0004." "" { target *-*-* } } + 0..=MAX => {} + } + + match 0isize { // { dg-error ".E0004." "" { target *-*-* } } + 1..=20 => {} + -5..3 => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-prelude_import.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-prelude_import.rs new file mode 100644 index 000000000000..b09f0921e04f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-prelude_import.rs @@ -0,0 +1,5 @@ +#[prelude_import] // { dg-error ".E0658." "" { target *-*-* } } +use std::prelude::v1::*; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-profiler-runtime.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-profiler-runtime.rs new file mode 100644 index 000000000000..19ed499530f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-profiler-runtime.rs @@ -0,0 +1,4 @@ +#![profiler_runtime] // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-public_private_dependencies.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-public_private_dependencies.rs new file mode 100644 index 000000000000..707debd9ddd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-public_private_dependencies.rs @@ -0,0 +1,21 @@ +// This test is different from other feature gate tests. +// Instead of checking that an error occurs without the feature gate, +// it checks that *no* errors/warnings occurs without the feature gate. +// This is due to the fact that 'public_private_dependencies' just enables +// a lint, so disabling it shouldn't cause any code to stop compiling. + +// run-pass +// aux-build:pub_dep.rs + +// Without ![feature(public_private_dependencies)], +// this should do nothing/ +#![deny(exported_private_dependencies)] + +extern crate pub_dep; + +pub struct Foo { + pub field: pub_dep::PubType +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-register_attr.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-register_attr.rs new file mode 100644 index 000000000000..bb09c9452cae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-register_attr.rs @@ -0,0 +1,4 @@ +#![register_attr(attr)] // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-register_tool.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-register_tool.rs new file mode 100644 index 000000000000..88e3bffc5e75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-register_tool.rs @@ -0,0 +1,4 @@ +#![register_tool(tool)] // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-repr-simd.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-repr-simd.rs new file mode 100644 index 000000000000..affb08d84e1e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-repr-simd.rs @@ -0,0 +1,10 @@ +#[repr(simd)] // { dg-error ".E0658." "" { target *-*-* } } +struct Foo(u64, u64); + +#[repr(C)] // { dg-error ".E0566." "" { target *-*-* } } +// { dg-warning ".E0566." "" { target *-*-* } .-1 } +#[repr(simd)] // { dg-error ".E0658." "" { target *-*-* } } +struct Bar(u64, u64); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-repr128.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-repr128.rs new file mode 100644 index 000000000000..ccef01fe4ae8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-repr128.rs @@ -0,0 +1,7 @@ +#[repr(u128)] +enum A { // { dg-error ".E0658." "" { target *-*-* } } + A(u64) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.rs new file mode 100644 index 000000000000..de3d1315638b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc-allow-const-fn-unstable.rs @@ -0,0 +1,7 @@ +#![allow(unused_macros)] + +#[rustc_allow_const_fn_unstable()] // { dg-error ".E0658." "" { target *-*-* } } +const fn foo() { } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc-attrs-1.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc-attrs-1.rs new file mode 100644 index 000000000000..01c425428c5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc-attrs-1.rs @@ -0,0 +1,10 @@ +// ignore-tidy-linelength + +// Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate. + +#[rustc_variance] // { dg-error ".E0658." "" { target *-*-* } } +#[rustc_error] // { dg-error ".E0658." "" { target *-*-* } } +#[rustc_nonnull_optimization_guaranteed] // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc-attrs.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc-attrs.rs new file mode 100644 index 000000000000..29c76a6f52da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc-attrs.rs @@ -0,0 +1,24 @@ +// Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate. + +#![feature(decl_macro)] + +mod rustc { pub macro unknown() {} } +mod unknown { pub macro rustc() {} } + +#[rustc::unknown] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +fn f() {} + +#[unknown::rustc] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +fn g() {} + +#[rustc_dummy] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +#[rustc_unknown] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc_const_unstable.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc_const_unstable.rs new file mode 100644 index 000000000000..efbc78561591 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-rustc_const_unstable.rs @@ -0,0 +1,10 @@ +// Test internal const fn feature gate. + +#![feature(const_fn)] + +#[rustc_const_unstable(feature="fzzzzzt")] // { dg-error ".E0734." "" { target *-*-* } } +pub const fn bazinga() {} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-simd-ffi.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-simd-ffi.rs new file mode 100644 index 000000000000..f989975edd07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-simd-ffi.rs @@ -0,0 +1,14 @@ +#![feature(repr_simd)] +#![allow(dead_code)] + +#[repr(simd)] +#[derive(Copy, Clone)] +struct LocalSimd(u8, u8); + +extern { + fn baz() -> LocalSimd; // { dg-error "" "" { target *-*-* } } + fn qux(x: LocalSimd); // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-simd.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-simd.rs new file mode 100644 index 000000000000..bfe5ab256cac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-simd.rs @@ -0,0 +1,12 @@ +// pretty-expanded FIXME #23616 + +#[repr(simd)] // { dg-error ".E0658." "" { target *-*-* } } +struct RGBA { + r: f32, + g: f32, + b: f32, + a: f32 +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-staged_api.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-staged_api.rs new file mode 100644 index 000000000000..28be09163399 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-staged_api.rs @@ -0,0 +1,15 @@ +#![stable(feature = "a", since = "b")] +// { dg-error ".E0734." "" { target *-*-* } .-1 } +mod inner_private_module { + // UnnameableTypeAlias isn't marked as reachable, so no stability annotation is required here + pub type UnnameableTypeAlias = u8; +} + +#[stable(feature = "a", since = "b")] +// { dg-error ".E0734." "" { target *-*-* } .-1 } +pub fn f() -> inner_private_module::UnnameableTypeAlias { + 0 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-start.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-start.rs new file mode 100644 index 000000000000..e6508be21788 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-start.rs @@ -0,0 +1,4 @@ +#[start] +fn foo(_: isize, _: *const *const u8) -> isize { 0 } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-static-nobundle.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-static-nobundle.rs new file mode 100644 index 000000000000..f847232b7fb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-static-nobundle.rs @@ -0,0 +1,6 @@ +#[link(name="foo", kind="static-nobundle")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +extern {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-stmt_expr_attributes.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-stmt_expr_attributes.rs new file mode 100644 index 000000000000..fe7896c91d93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-stmt_expr_attributes.rs @@ -0,0 +1,5 @@ +const X: i32 = #[allow(dead_code)] 8; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-thread_local.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-thread_local.rs new file mode 100644 index 000000000000..c7150d74c946 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-thread_local.rs @@ -0,0 +1,12 @@ +// Test that `#[thread_local]` attribute is gated by `thread_local` +// feature gate. +// +// (Note that the `thread_local!` macro is explicitly *not* gated; it +// is given permission to expand into this unstable attribute even +// when the surrounding context does not have permission to use it.) + +#[thread_local] // { dg-error ".E0658." "" { target *-*-* } } +static FOO: i32 = 3; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trace_macros.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trace_macros.rs new file mode 100644 index 000000000000..0fc3f472c073 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trace_macros.rs @@ -0,0 +1,4 @@ +fn main() { + trace_macros!(true); // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trait-alias.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trait-alias.rs new file mode 100644 index 000000000000..a51b30e0672a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trait-alias.rs @@ -0,0 +1,5 @@ +trait Foo = Default; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-transparent_unions.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-transparent_unions.rs new file mode 100644 index 000000000000..1aa5113ec825 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-transparent_unions.rs @@ -0,0 +1,8 @@ +#[repr(transparent)] +union OkButUnstableUnion { // { dg-error ".E0658." "" { target *-*-* } } + field: u8, + zst: (), +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trivial_bounds-lint.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trivial_bounds-lint.rs new file mode 100644 index 000000000000..36a17db512cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trivial_bounds-lint.rs @@ -0,0 +1,9 @@ +// run-pass + +#![allow(unused)] +#![deny(trivial_bounds)] // Ignored without the trivial_bounds feature flag. + +struct A where i32: Copy; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trivial_bounds.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trivial_bounds.rs new file mode 100644 index 000000000000..6f7c33e24b70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-trivial_bounds.rs @@ -0,0 +1,70 @@ +#![allow(unused)] +#![allow(type_alias_bounds)] + +pub trait Foo { + fn test(&self); +} + +fn generic_function(x: X) {} + +enum E where i32: Foo { V } // { dg-error ".E0277." "" { target *-*-* } } + +struct S where i32: Foo; // { dg-error ".E0277." "" { target *-*-* } } + +trait T where i32: Foo {} // { dg-error ".E0277." "" { target *-*-* } } + +union U where i32: Foo { f: i32 } // { dg-error ".E0277." "" { target *-*-* } } + +type Y where i32: Foo = (); // OK - bound is ignored + +impl Foo for () where i32: Foo { // { dg-error ".E0277." "" { target *-*-* } } + fn test(&self) { + 3i32.test(); + Foo::test(&4i32); + generic_function(5i32); + } +} + +fn f() where i32: Foo // { dg-error ".E0277." "" { target *-*-* } } +{ + let s = S; + 3i32.test(); + Foo::test(&4i32); + generic_function(5i32); +} + +fn use_op(s: String) -> String where String: ::std::ops::Neg { // { dg-error ".E0277." "" { target *-*-* } } + -s +} + +fn use_for() where i32: Iterator { // { dg-error ".E0277." "" { target *-*-* } } + for _ in 2i32 {} +} + +trait A {} + +impl A for i32 {} + +struct Dst { + x: X, +} + +struct TwoStrs(str, str) where str: Sized; // { dg-error ".E0277." "" { target *-*-* } } + + +fn unsized_local() where Dst: Sized { // { dg-error ".E0277." "" { target *-*-* } } + let x: Dst = *(Box::new(Dst { x: 1 }) as Box>); +} + +fn return_str() -> str where str: Sized { // { dg-error ".E0277." "" { target *-*-* } } + *"Sized".to_string().into_boxed_str() +} + +// This is currently accepted because the function pointer isn't +// considered global. +fn global_hr(x: fn(&())) where fn(&()): Foo { // OK + x.test(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-try_blocks.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-try_blocks.rs new file mode 100644 index 000000000000..70ad1cf5a064 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-try_blocks.rs @@ -0,0 +1,10 @@ +// compile-flags: --edition 2018 + +pub fn main() { + let try_result: Option<_> = try { // { dg-error ".E0658." "" { target *-*-* } } + let x = 5; + x + }; + assert_eq!(try_result, Some(5)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-try_reserve.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-try_reserve.rs new file mode 100644 index 000000000000..360cc6c9a2a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-try_reserve.rs @@ -0,0 +1,5 @@ +fn main() { + let v = Vec::new(); + v.try_reserve(10); // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-type_alias_impl_trait.rs new file mode 100644 index 000000000000..cf1b4c30b9d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-type_alias_impl_trait.rs @@ -0,0 +1,51 @@ +// ignore-compare-mode-chalk +use std::fmt::Debug; + +type Foo = impl Debug; // { dg-error ".E0658." "" { target *-*-* } } + +trait Bar { + type Baa: Debug; + fn define() -> Self::Baa; +} + +impl Bar for () { + type Baa = impl Debug; // { dg-error ".E0658." "" { target *-*-* } } + fn define() -> Self::Baa { + 0 + } +} + +fn define() -> Foo { + 0 +} + +trait TraitWithDefault { + type Assoc = impl Debug; +// { dg-error ".E0562." "" { target *-*-* } .-1 } +// { dg-error ".E0562." "" { target *-*-* } .-2 } +// { dg-error ".E0562." "" { target *-*-* } .-3 } +} + +type NestedFree = (Vec, impl Debug, impl Iterator); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +// { dg-error ".E0658." "" { target *-*-* } .-4 } + +fn define_multiple() -> NestedFree { + (vec![true], 0u8, 0i32..1) +} + +impl Bar for u8 { + type Baa = (Vec, impl Debug, impl Iterator + Debug); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +// { dg-error ".E0658." "" { target *-*-* } .-4 } + fn define() -> Self::Baa { + (vec![true], 0u8, 0i32..1) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-type_ascription.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-type_ascription.rs new file mode 100644 index 000000000000..d2a41d47cd24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-type_ascription.rs @@ -0,0 +1,6 @@ +// Type ascription is unstable + +fn main() { + let a = 10: u8; // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs new file mode 100644 index 000000000000..fe0c7373f127 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.rs @@ -0,0 +1,38 @@ +// Test that manual impls of the `Fn` traits are not possible without +// a feature gate. In fact, the specialized check for these cases +// never triggers (yet), because they encounter other problems around +// angle bracket vs parentheses notation. + +#![feature(fn_traits)] + +struct Foo; +impl Fn<()> for Foo { +// { dg-error ".E0183." "" { target *-*-* } .-1 } +// { dg-error ".E0183." "" { target *-*-* } .-2 } + extern "rust-call" fn call(self, args: ()) -> () {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} +struct Foo1; +impl FnOnce() for Foo1 { +// { dg-error ".E0183." "" { target *-*-* } .-1 } +// { dg-error ".E0183." "" { target *-*-* } .-2 } + extern "rust-call" fn call_once(self, args: ()) -> () {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} +struct Bar; +impl FnMut<()> for Bar { +// { dg-error ".E0183." "" { target *-*-* } .-1 } +// { dg-error ".E0183." "" { target *-*-* } .-2 } + extern "rust-call" fn call_mut(&self, args: ()) -> () {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} +struct Baz; +impl FnOnce<()> for Baz { +// { dg-error ".E0183." "" { target *-*-* } .-1 } +// { dg-error ".E0183." "" { target *-*-* } .-2 } + extern "rust-call" fn call_once(&self, args: ()) -> () {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-method-calls.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-method-calls.rs new file mode 100644 index 000000000000..e8b2f32b2f08 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-method-calls.rs @@ -0,0 +1,10 @@ +#![allow(dead_code)] + +fn foo(mut f: F) { + f.call(()); // { dg-error ".E0658." "" { target *-*-* } } + f.call_mut(()); // { dg-error ".E0658." "" { target *-*-* } } + f.call_once(()); // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-ufcs-calls.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-ufcs-calls.rs new file mode 100644 index 000000000000..8a1023f0f13f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures-ufcs-calls.rs @@ -0,0 +1,10 @@ +#![allow(dead_code)] + +fn foo(mut f: F) { + Fn::call(&f, ()); // { dg-error ".E0658." "" { target *-*-* } } + FnMut::call_mut(&mut f, ()); // { dg-error ".E0658." "" { target *-*-* } } + FnOnce::call_once(f, ()); // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures.rs new file mode 100644 index 000000000000..08d6e6c98734 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unboxed-closures.rs @@ -0,0 +1,19 @@ +#![feature(fn_traits)] + +struct Test; + +impl FnOnce<(u32, u32)> for Test { +// { dg-error ".E0183." "" { target *-*-* } .-1 } +// { dg-error ".E0183." "" { target *-*-* } .-2 } + type Output = u32; + + extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 { + a + b + } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +} + +fn main() { + assert_eq!(Test(1u32, 2u32), 3u32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsafe_block_in_unsafe_fn.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsafe_block_in_unsafe_fn.rs new file mode 100644 index 000000000000..9c5b0c75053b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsafe_block_in_unsafe_fn.rs @@ -0,0 +1,7 @@ +#![deny(unsafe_op_in_unsafe_fn)] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsized_fn_params.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsized_fn_params.rs new file mode 100644 index 000000000000..630cb83e9b6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsized_fn_params.rs @@ -0,0 +1,27 @@ +#[repr(align(256))] +#[allow(dead_code)] +struct A { + v: u8, +} + +trait Foo { + fn foo(&self); +} + +impl Foo for A { + fn foo(&self) { + assert_eq!(self as *const A as usize % 256, 0); + } +} + +fn foo(x: dyn Foo) { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + x.foo() +} + +fn main() { + let x: Box = Box::new(A { v: 22 }); + foo(*x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsized_locals.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsized_locals.rs new file mode 100644 index 000000000000..be3ad4da950d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsized_locals.rs @@ -0,0 +1,6 @@ +fn f(f: dyn FnOnce()) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs new file mode 100644 index 000000000000..767baf6bbe6c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs @@ -0,0 +1,5 @@ +fn main() { + let _ : &(dyn Send,) = &((),); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-untagged_unions.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-untagged_unions.rs new file mode 100644 index 000000000000..692b07938cf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-untagged_unions.rs @@ -0,0 +1,36 @@ +// ignore-tidy-linelength + +union U1 { // OK + a: u8, +} + +union U2 { // OK + a: T, +} + +union U22 { // OK + a: std::mem::ManuallyDrop, +} + +union U3 { + a: String, // { dg-error ".E0740." "" { target *-*-* } } +} + +union U32 { // field that does not drop but is not `Copy`, either -- this is the real feature gate test! + a: std::cell::RefCell, // { dg-error ".E0658." "" { target *-*-* } } +} + +union U4 { + a: T, // { dg-error ".E0740." "" { target *-*-* } } +} + +union U5 { // Having a drop impl is OK + a: u8, +} + +impl Drop for U5 { + fn drop(&mut self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unwind-attributes.rs b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unwind-attributes.rs new file mode 100644 index 000000000000..7246efac7082 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/feature-gates/feature-gate-unwind-attributes.rs @@ -0,0 +1,20 @@ +// ignore-wasm32-bare compiled with panic=abort by default +// compile-flags: -C no-prepopulate-passes -Cpasses=name-anon-globals + +#![crate_type = "lib"] + +extern { +// CHECK: Function Attrs: nounwind +// CHECK-NEXT: declare void @extern_fn + fn extern_fn(); +// CHECK-NOT: Function Attrs: nounwind +// CHECK: declare void @unwinding_extern_fn + #[unwind(allowed)] // { dg-error ".E0658." "" { target *-*-* } } + fn unwinding_extern_fn(); +} + +pub unsafe fn force_declare() { + extern_fn(); + unwinding_extern_fn(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/ffi_const.rs b/gcc/testsuite/rust/rustc/ui/ffi_const.rs new file mode 100644 index 000000000000..7445cf81d38e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ffi_const.rs @@ -0,0 +1,6 @@ +#![feature(ffi_const)] +#![crate_type = "lib"] + +#[ffi_const] // { dg-error ".E0756." "" { target *-*-* } } +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/ffi_const2.rs b/gcc/testsuite/rust/rustc/ui/ffi_const2.rs new file mode 100644 index 000000000000..ca72e93262da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ffi_const2.rs @@ -0,0 +1,12 @@ +#![feature(ffi_const, ffi_pure)] + +extern { + #[ffi_pure] // { dg-error ".E0757." "" { target *-*-* } } + #[ffi_const] + pub fn baz(); +} + +fn main() { + unsafe { baz() }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/ffi_pure.rs b/gcc/testsuite/rust/rustc/ui/ffi_pure.rs new file mode 100644 index 000000000000..dcd26328e941 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ffi_pure.rs @@ -0,0 +1,6 @@ +#![feature(ffi_pure)] +#![crate_type = "lib"] + +#[ffi_pure] // { dg-error ".E0755." "" { target *-*-* } } +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/ffi_returns_twice.rs b/gcc/testsuite/rust/rustc/ui/ffi_returns_twice.rs new file mode 100644 index 000000000000..c12eba7bf148 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ffi_returns_twice.rs @@ -0,0 +1,6 @@ +#![feature(ffi_returns_twice)] +#![crate_type = "lib"] + +#[ffi_returns_twice] // { dg-error ".E0724." "" { target *-*-* } } +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/filter-block-view-items.rs b/gcc/testsuite/rust/rustc/ui/filter-block-view-items.rs new file mode 100644 index 000000000000..109e61fb6a71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/filter-block-view-items.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + // Make sure that this view item is filtered out because otherwise it would + // trigger a compilation error + #[cfg(not_present)] use bar as foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/fixup-deref-mut.rs b/gcc/testsuite/rust/rustc/ui/fixup-deref-mut.rs new file mode 100644 index 000000000000..e473df0f36aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fixup-deref-mut.rs @@ -0,0 +1,51 @@ +// run-pass + +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +use std::ops::{Deref, DerefMut}; + +// Generic unique/owned smaht pointer. +struct Own { + value: *mut T +} + +impl Deref for Own { + type Target = T; + + fn deref<'a>(&'a self) -> &'a T { + unsafe { &*self.value } + } +} + +impl DerefMut for Own { + fn deref_mut<'a>(&'a mut self) -> &'a mut T { + unsafe { &mut *self.value } + } +} + +struct Point { + x: isize, + y: isize +} + +impl Point { + fn get(&mut self) -> (isize, isize) { + (self.x, self.y) + } +} + +fn test0(mut x: Own) { + let _ = x.get(); +} + +fn test1(mut x: Own>>) { + let _ = x.get(); +} + +fn test2(mut x: Own>>) { + let _ = (**x).get(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/float-literal-inference-restrictions.rs b/gcc/testsuite/rust/rustc/ui/float-literal-inference-restrictions.rs new file mode 100644 index 000000000000..8ae93c9b8029 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/float-literal-inference-restrictions.rs @@ -0,0 +1,5 @@ +fn main() { + let x: f32 = 1; // { dg-error ".E0308." "" { target *-*-* } } + let y: f32 = 1f64; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/fmt/feature-gate-format-args-capture.rs b/gcc/testsuite/rust/rustc/ui/fmt/feature-gate-format-args-capture.rs new file mode 100644 index 000000000000..f23dd5a8a86d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fmt/feature-gate-format-args-capture.rs @@ -0,0 +1,7 @@ +fn main() { + format!("{foo}"); // { dg-error "" "" { target *-*-* } } + + // panic! doesn't hit format_args! unless there are two or more arguments. + panic!("{foo} {bar}", bar=1); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/fmt/format-args-capture-macro-hygiene.rs b/gcc/testsuite/rust/rustc/ui/fmt/format-args-capture-macro-hygiene.rs new file mode 100644 index 000000000000..287aacf0bada --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fmt/format-args-capture-macro-hygiene.rs @@ -0,0 +1,7 @@ +#![feature(format_args_capture)] + +fn main() { + format!(concat!("{foo}")); // { dg-error "" "" { target *-*-* } } + format!(concat!("{ba", "r} {}"), 1); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/fmt/format-args-capture-missing-variables.rs b/gcc/testsuite/rust/rustc/ui/fmt/format-args-capture-missing-variables.rs new file mode 100644 index 000000000000..81ff7bea9cd4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fmt/format-args-capture-missing-variables.rs @@ -0,0 +1,23 @@ +#![feature(format_args_capture)] + +fn main() { + format!("{} {foo} {} {bar} {}", 1, 2, 3); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { dg-error ".E0425." "" { target *-*-* } .-2 } + + format!("{foo}"); // { dg-error ".E0425." "" { target *-*-* } } + + format!("{valuea} {valueb}", valuea=5, valuec=7); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { dg-error ".E0425." "" { target *-*-* } .-2 } + + format!(r##" + + {foo} + + "##); +// { dg-error ".E0425." "" { target *-*-* } .-3 } + + panic!("{foo} {bar}", bar=1); // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/fmt/format-args-capture.rs b/gcc/testsuite/rust/rustc/ui/fmt/format-args-capture.rs new file mode 100644 index 000000000000..9de2099a561f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fmt/format-args-capture.rs @@ -0,0 +1,70 @@ +// run-pass +#![feature(format_args_capture)] +#![feature(cfg_panic)] + +fn main() { + named_argument_takes_precedence_to_captured(); + formatting_parameters_can_be_captured(); + + #[cfg(panic = "unwind")] + { + panic_with_single_argument_does_not_get_formatted(); + panic_with_multiple_arguments_is_formatted(); + } +} + +fn named_argument_takes_precedence_to_captured() { + let foo = "captured"; + let s = format!("{foo}", foo="named"); + assert_eq!(&s, "named"); + + let s = format!("{foo}-{foo}-{foo}", foo="named"); + assert_eq!(&s, "named-named-named"); + + let s = format!("{}-{bar}-{foo}", "positional", bar="named"); + assert_eq!(&s, "positional-named-captured"); +} + +#[cfg(panic = "unwind")] +fn panic_with_single_argument_does_not_get_formatted() { + // panic! with a single argument does not perform string formatting. + // RFC #2795 suggests that this may need to change so that captured arguments are formatted. + // For stability reasons this will need to part of an edition change. + + let msg = std::panic::catch_unwind(|| { + panic!("{foo}"); + }).unwrap_err(); + + assert_eq!(msg.downcast_ref::<&str>(), Some(&"{foo}")) +} + +#[cfg(panic = "unwind")] +fn panic_with_multiple_arguments_is_formatted() { + let foo = "captured"; + + let msg = std::panic::catch_unwind(|| { + panic!("{}-{bar}-{foo}", "positional", bar="named"); + }).unwrap_err(); + + assert_eq!(msg.downcast_ref::(), Some(&"positional-named-captured".to_string())) +} + +fn formatting_parameters_can_be_captured() { + let width = 9; + let precision = 3; + + let x = 7.0; + + let s = format!("{x:width$}"); + assert_eq!(&s, " 7"); + + let s = format!("{x:(_: T) {} +fn sync(_: T) {} + +fn main() { + // `Cell` is not `Sync`, so `&Cell` is neither `Sync` nor `Send`, + // `std::fmt::Arguments` used to forget this... + let c = std::cell::Cell::new(42); + send(format_args!("{:?}", c)); // { dg-error ".E0277." "" { target *-*-* } } + sync(format_args!("{:?}", c)); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/fn-in-pat.rs b/gcc/testsuite/rust/rustc/ui/fn-in-pat.rs new file mode 100644 index 000000000000..25e5399b949a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fn-in-pat.rs @@ -0,0 +1,17 @@ +struct A {} + +impl A { + fn new() {} +} + +fn hof(_: F) where F: FnMut(()) {} + +fn ice() { + hof(|c| match c { + A::new() => (), // { dg-error ".E0164." "" { target *-*-* } } + _ => () + }) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/fn/dyn-fn-alignment.rs b/gcc/testsuite/rust/rustc/ui/fn/dyn-fn-alignment.rs new file mode 100644 index 000000000000..c93f102ec12e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fn/dyn-fn-alignment.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(dead_code)] +#[repr(align(256))] +struct A { + v: u8, +} + +impl A { + fn f(&self) -> *const A { + self + } +} + +fn f2(v: u8) -> Box *const A> { + let a = A { v }; + Box::new(move || a.f()) +} + +fn main() { + let addr = f2(0)(); + assert_eq!(addr as usize % 256, 0, "addr: {:?}", addr); +} + diff --git a/gcc/testsuite/rust/rustc/ui/fn/expr-fn-panic.rs b/gcc/testsuite/rust/rustc/ui/fn/expr-fn-panic.rs new file mode 100644 index 000000000000..c7fc1c06d02f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fn/expr-fn-panic.rs @@ -0,0 +1,12 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn f() -> ! { + panic!() +} + +fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/fn/fn-bad-block-type.rs b/gcc/testsuite/rust/rustc/ui/fn/fn-bad-block-type.rs new file mode 100644 index 000000000000..2c208e1150ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fn/fn-bad-block-type.rs @@ -0,0 +1,6 @@ +// error-pattern:mismatched types + +fn f() -> isize { true } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/fn/fn-closure-mutable-capture.rs b/gcc/testsuite/rust/rustc/ui/fn/fn-closure-mutable-capture.rs new file mode 100644 index 000000000000..c5e5faf4c5f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fn/fn-closure-mutable-capture.rs @@ -0,0 +1,12 @@ +pub fn bar(_f: F) {} // { dg-note "" "" { target *-*-* } } + +pub fn foo() { + let mut x = 0; + bar(move || x = 1); +// { dg-error ".E0594." "" { target *-*-* } .-1 } +// { dg-note ".E0594." "" { target *-*-* } .-2 } +// { dg-note ".E0594." "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/fn/fn-compare-mismatch.rs b/gcc/testsuite/rust/rustc/ui/fn/fn-compare-mismatch.rs new file mode 100644 index 000000000000..92cb37433989 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fn/fn-compare-mismatch.rs @@ -0,0 +1,8 @@ +fn main() { + fn f() { } + fn g() { } + let x = f == g; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/fn/fn-item-type.rs b/gcc/testsuite/rust/rustc/ui/fn/fn-item-type.rs new file mode 100644 index 000000000000..1608b7979632 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fn/fn-item-type.rs @@ -0,0 +1,56 @@ +// Test that the types of distinct fn items are not compatible by +// default. See also `run-pass/fn-item-type-*.rs`. + +fn foo(x: isize) -> isize { x * 2 } +fn bar(x: isize) -> isize { x * 4 } + +fn eq(x: T, y: T) { } + +trait Foo { fn foo() { /* this is a default fn */ } } +impl Foo for T { /* `foo` is still default here */ } + +fn main() { + eq(foo::, bar::); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } +// { dg-error ".E0308." "" { target *-*-* } .-6 } +// { dg-error ".E0308." "" { target *-*-* } .-7 } + + eq(foo::, foo::); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } + + eq(bar::, bar::>); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } +// { dg-error ".E0308." "" { target *-*-* } .-6 } +// { dg-error ".E0308." "" { target *-*-* } .-7 } + + // Make sure we distinguish between trait methods correctly. + eq(::foo, ::foo); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } + + eq(foo::, bar:: as fn(isize) -> isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } +// { dg-error ".E0308." "" { target *-*-* } .-6 } + + eq(foo:: as fn(isize) -> isize, bar::); // ok! +} + diff --git a/gcc/testsuite/rust/rustc/ui/fn/fn-trait-formatting.rs b/gcc/testsuite/rust/rustc/ui/fn/fn-trait-formatting.rs new file mode 100644 index 000000000000..a2edccd3c8d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fn/fn-trait-formatting.rs @@ -0,0 +1,22 @@ +#![feature(box_syntax)] + +fn needs_fn(x: F) where F: Fn(isize) -> isize {} + +fn main() { + let _: () = (box |_: isize| {}) as Box; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + let _: () = (box |_: isize, isize| {}) as Box; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + let _: () = (box || -> isize { unimplemented!() }) as Box isize>; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + + needs_fn(1); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/fn_must_use.rs b/gcc/testsuite/rust/rustc/ui/fn_must_use.rs new file mode 100644 index 000000000000..3dc7f457aeab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fn_must_use.rs @@ -0,0 +1,77 @@ +// check-pass + +#![warn(unused_must_use)] + +#[derive(PartialEq, Eq)] +struct MyStruct { + n: usize, +} + +impl MyStruct { + #[must_use] + fn need_to_use_this_method_value(&self) -> usize { + self.n + } + + #[must_use] + fn need_to_use_this_associated_function_value() -> isize { + -1 + } +} + +trait EvenNature { + #[must_use = "no side effects"] + fn is_even(&self) -> bool; +} + +impl EvenNature for MyStruct { + fn is_even(&self) -> bool { + self.n % 2 == 0 + } +} + +trait Replaceable { + fn replace(&mut self, substitute: usize) -> usize; +} + +impl Replaceable for MyStruct { + // ↓ N.b.: `#[must_use]` attribute on a particular trait implementation + // method won't work; the attribute should be on the method signature in + // the trait's definition. + #[must_use] + fn replace(&mut self, substitute: usize) -> usize { + let previously = self.n; + self.n = substitute; + previously + } +} + +#[must_use = "it's important"] +fn need_to_use_this_value() -> bool { + false +} + +fn main() { + need_to_use_this_value(); // { dg-warning "" "" { target *-*-* } } + + let mut m = MyStruct { n: 2 }; + let n = MyStruct { n: 3 }; + + m.need_to_use_this_method_value(); // { dg-warning "" "" { target *-*-* } } + m.is_even(); // trait method! +// { dg-warning "" "" { target *-*-* } .-1 } + + MyStruct::need_to_use_this_associated_function_value(); +// { dg-warning "" "" { target *-*-* } .-1 } + + m.replace(3); // won't warn (annotation needs to be in trait definition) + + // comparison methods are `must_use` + 2.eq(&3); // { dg-warning "" "" { target *-*-* } } + m.eq(&n); // { dg-warning "" "" { target *-*-* } } + + // lint includes comparison operators + 2 == 3; // { dg-warning "" "" { target *-*-* } } + m == n; // { dg-warning "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/auto-loop.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/auto-loop.rs new file mode 100644 index 000000000000..d1583a72d182 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/auto-loop.rs @@ -0,0 +1,11 @@ +// run-pass + +pub fn main() { + let mut sum = 0; + let xs = vec![1, 2, 3, 4, 5]; + for x in &xs { + sum += *x; + } + assert_eq!(sum, 15); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/break-value.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/break-value.rs new file mode 100644 index 000000000000..414d931e75b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/break-value.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(unreachable_code)] +// pretty-expanded FIXME #23616 + +fn int_id(x: isize) -> isize { return x; } + +pub fn main() { loop { int_id(break); } } + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/break.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/break.rs new file mode 100644 index 000000000000..932f7bd439a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/break.rs @@ -0,0 +1,26 @@ +// run-pass + +pub fn main() { + let mut i = 0; + while i < 20 { i += 1; if i == 10 { break; } } + assert_eq!(i, 10); + loop { i += 1; if i == 20 { break; } } + assert_eq!(i, 20); + let xs = [1, 2, 3, 4, 5, 6]; + for x in &xs { + if *x == 3 { break; } assert!((*x <= 3)); + } + i = 0; + while i < 10 { i += 1; if i % 2 == 0 { continue; } assert!((i % 2 != 0)); } + i = 0; + loop { + i += 1; if i % 2 == 0 { continue; } assert!((i % 2 != 0)); + if i >= 10 { break; } + } + let ys = vec![1, 2, 3, 4, 5, 6]; + for x in &ys { + if *x % 2 == 0 { continue; } + assert!((*x % 2 != 0)); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/for-destruct.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-destruct.rs new file mode 100644 index 000000000000..7715ce403dbd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-destruct.rs @@ -0,0 +1,10 @@ +// run-pass + +struct Pair { x: isize, y: isize } + +pub fn main() { + for elt in &(vec![Pair {x: 10, y: 20}, Pair {x: 30, y: 0}]) { + assert_eq!(elt.x + elt.y, 30); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-goofiness.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-goofiness.rs new file mode 100644 index 000000000000..38a4adee1eb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-goofiness.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] + +enum BogusOption { + None, + Some(T), +} + +type Iterator = isize; + +pub fn main() { + let x = [ 3, 3, 3 ]; + for i in &x { + assert_eq!(*i, 3); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-has-unit-body.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-has-unit-body.rs new file mode 100644 index 000000000000..adcd6bf3fa6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-has-unit-body.rs @@ -0,0 +1,14 @@ +// run-pass +fn main() { + // Check that the tail statement in the body unifies with something + for _ in 0..3 { + // `()` is fine to zero-initialize as it is zero sized and inhabited. + unsafe { std::mem::zeroed() } + } + + // Check that the tail statement in the body can be unit + for _ in 0..3 { + () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-into-iterator.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-into-iterator.rs new file mode 100644 index 000000000000..0fc2ff2344a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-into-iterator.rs @@ -0,0 +1,20 @@ +// run-pass +// Test that for loops can do what RFC #235 claims + + +fn main() { + let mut v = vec![1]; + + for x in &v { + assert_eq!(x, &1); + } + + for x in &mut v { + assert_eq!(x, &mut 1); + } + + for x in v { + assert_eq!(x, 1); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-lifetime-of-unbound-values.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-lifetime-of-unbound-values.rs new file mode 100644 index 000000000000..6caa2d99660a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-lifetime-of-unbound-values.rs @@ -0,0 +1,35 @@ +// run-pass +// Test when destructors run in a for loop. The intention is +// that the value for each iteration is dropped *after* the loop +// body has executed. This is true even when the value is assigned +// to a `_` pattern (and hence ignored). + +use std::cell::Cell; + +struct Flag<'a>(&'a Cell); + +impl<'a> Drop for Flag<'a> { + fn drop(&mut self) { + self.0.set(false) + } +} + +fn main() { + let alive2 = Cell::new(true); + for _i in std::iter::once(Flag(&alive2)) { + // The Flag value should be alive in the for loop body + assert_eq!(alive2.get(), true); + } + // The Flag value should be dead outside of the loop + assert_eq!(alive2.get(), false); + + let alive = Cell::new(true); + for _ in std::iter::once(Flag(&alive)) { + // The Flag value should be alive in the for loop body even if it wasn't + // bound by the for loop + assert_eq!(alive.get(), true); + } + // The Flag value should be dead outside of the loop + assert_eq!(alive.get(), false); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-macro.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-macro.rs new file mode 100644 index 000000000000..ab91e3a331b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-macro.rs @@ -0,0 +1,12 @@ +// run-pass +macro_rules! var { + ( $name:ident ) => ( $name ); +} + +pub fn main() { + let x = [ 3, 3, 3 ]; + for var!(i) in &x { + assert_eq!(*i, 3); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-mut-ref-element.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-mut-ref-element.rs new file mode 100644 index 000000000000..8982ab31aa0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-mut-ref-element.rs @@ -0,0 +1,7 @@ +// run-pass +// Tests that for loops can bind elements as mutable references + +fn main() { + for ref mut _a in std::iter::once(true) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-no-std.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-no-std.rs new file mode 100644 index 000000000000..0f048e5b17cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-no-std.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(unused_imports)] +#![feature(lang_items, start)] +#![no_std] + +extern crate std as other; + +#[macro_use] extern crate alloc; + +#[start] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + for _ in [1,2,3].iter() { } + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-panic.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-panic.rs new file mode 100644 index 000000000000..f50a485e231c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-panic.rs @@ -0,0 +1,5 @@ +// run-pass + + +pub fn main() { let x: Vec = Vec::new(); for _ in &x { panic!("moop"); } } + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs new file mode 100644 index 000000000000..ae77d996e13b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/for-loop-unconstrained-element-type-i32-fallback.rs @@ -0,0 +1,12 @@ +// run-pass +// Test that the type of `sum` falls back to `i32` here, +// and that the for loop desugaring doesn't interfere with +// that. + +fn main() { + let mut sum = 0; + for i in Vec::new() { + sum += &i; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-break.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-break.rs new file mode 100644 index 000000000000..a003f3a2dd20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-break.rs @@ -0,0 +1,14 @@ +// run-pass + +pub fn main() { + let x = [1; 100]; + let mut y = 0; + for i in &x[..] { + if y > 10 { + break; + } + y += *i; + } + assert_eq!(y, 11); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs new file mode 100644 index 000000000000..8bbf77bb91e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-hashmap-break-restart.rs @@ -0,0 +1,34 @@ +// run-pass + +use std::collections::HashMap; + +// This is a fancy one: it uses an external iterator established +// outside the loop, breaks, then _picks back up_ and continues +// iterating with it. + +pub fn main() { + let mut h = HashMap::new(); + let kvs = [(1, 10), (2, 20), (3, 30)]; + for &(k,v) in &kvs { + h.insert(k,v); + } + let mut x = 0; + let mut y = 0; + + let mut i = h.iter(); + + for (&k,&v) in i.by_ref() { + x += k; + y += v; + break; + } + + for (&k,&v) in i { + x += k; + y += v; + } + + assert_eq!(x, 6); + assert_eq!(y, 60); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-hashmap.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-hashmap.rs new file mode 100644 index 000000000000..6f6ae19a8d7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-hashmap.rs @@ -0,0 +1,20 @@ +// run-pass + +use std::collections::HashMap; + +pub fn main() { + let mut h = HashMap::new(); + let kvs = [(1, 10), (2, 20), (3, 30)]; + for &(k,v) in &kvs { + h.insert(k,v); + } + let mut x = 0; + let mut y = 0; + for (&k,&v) in &h { + x += k; + y += v; + } + assert_eq!(x, 6); + assert_eq!(y, 60); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-loop.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-loop.rs new file mode 100644 index 000000000000..77d6e4d6061b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-loop.rs @@ -0,0 +1,14 @@ +// run-pass + +pub fn main() { + let x = [1; 100]; + let mut y = 0; + for (n,i) in x.iter().enumerate() { + if n < 10 { + continue; + } + y += *i; + } + assert_eq!(y, 90); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-nested.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-nested.rs new file mode 100644 index 000000000000..ec00bdf3f88a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators-nested.rs @@ -0,0 +1,16 @@ +// run-pass + +pub fn main() { + let x = [1; 100]; + let y = [2; 100]; + let mut p = 0; + let mut q = 0; + for i in &x[..] { + for j in &y[..] { + p += *j; + } + q += *i + p; + } + assert_eq!(q, 1010100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators.rs new file mode 100644 index 000000000000..ea488b2384a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-external-iterators.rs @@ -0,0 +1,11 @@ +// run-pass + +pub fn main() { + let x = [1; 100]; + let mut y = 0; + for i in &x[..] { + y += *i + } + assert_eq!(y, 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-nested.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-nested.rs new file mode 100644 index 000000000000..8a17b08e0d54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-nested.rs @@ -0,0 +1,17 @@ +// run-pass + + +fn two(mut it: F) where F: FnMut(isize) { it(0); it(1); } + +pub fn main() { + let mut a: Vec = vec![-1, -1, -1, -1]; + let mut p: isize = 0; + two(|i| { + two(|j| { a[p as usize] = 10 * i + j; p += 1; }) + }); + assert_eq!(a[0], 0); + assert_eq!(a[1], 1); + assert_eq!(a[2], 10); + assert_eq!(a[3], 11); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-put-structured.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-put-structured.rs new file mode 100644 index 000000000000..93d6adb25693 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-put-structured.rs @@ -0,0 +1,23 @@ +// run-pass + + +fn pairs(mut it: F) where F: FnMut((isize, isize)) { + let mut i: isize = 0; + let mut j: isize = 0; + while i < 10 { it((i, j)); i += 1; j += i; } +} + +pub fn main() { + let mut i: isize = 10; + let mut j: isize = 0; + pairs(|p| { + let (_0, _1) = p; + println!("{}", _0); + println!("{}", _1); + assert_eq!(_0 + 10, i); + i += 1; + j = _1; + }); + assert_eq!(j, 45); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-simple-outer-slot.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-simple-outer-slot.rs new file mode 100644 index 000000000000..9afd74bff42e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/foreach-simple-outer-slot.rs @@ -0,0 +1,17 @@ +// run-pass + + + +pub fn main() { + let mut sum: isize = 0; + first_ten(|i| { println!("main"); println!("{}", i); sum = sum + i; }); + println!("sum"); + println!("{}", sum); + assert_eq!(sum, 45); +} + +fn first_ten(mut it: F) where F: FnMut(isize) { + let mut i: isize = 0; + while i < 10 { println!("first_ten"); it(i); i = i + 1; } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/label_break_value.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/label_break_value.rs new file mode 100644 index 000000000000..7f57ee30bb83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/label_break_value.rs @@ -0,0 +1,117 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_assignments)] +#![feature(label_break_value)] + +// Test control flow to follow label_break_value semantics +fn label_break(a: bool, b: bool) -> u32 { + let mut v = 0; + 'b: { + v = 1; + if a { + break 'b; + } + v = 2; + if b { + break 'b; + } + v = 3; + } + return v; +} + +// Test that values can be returned +fn break_value(a: bool, b: bool) -> u32 { + let result = 'block: { + if a { break 'block 1; } + if b { break 'block 2; } + 3 + }; + result +} + +// Test nesting of labeled blocks +// here we only check that it compiles +fn label_break_nested() { + 'b: { + println!("hi"); + if false { + break 'b; + } + 'c: { + if false { + break 'b; + } + break 'c; + } + println!("hello"); + if true { + break 'b; + } + } +} + +// Tests for mixing labeled blocks with loop constructs +// This function should be the identity function +fn label_break_mixed(v: u32) -> u32 { + let mut r = 0; + 'b: { + // Unlabeled break still works + // (only crossing boundaries is an error) + loop { + break; + } + if v == 0 { + break 'b; + } + // Labeled breaking an inner loop still works + 'c: loop { + if r == 1 { + break 'c; + } + r += 1; + } + assert_eq!(r, 1); + if v == 1 { + break 'b; + } + // Labeled breaking an outer loop still works + 'd: loop { + { + if v == r { + break 'b; + } + if r == 5 { + break 'd; + } + r += 1; + } + } + assert_eq!(r, 5); + assert!(v > r); + // Here we test return from inside a labeled block + return v; + } + r +} + +pub fn main() { + assert_eq!(label_break(true, false), 1); + assert_eq!(label_break(false, true), 2); + assert_eq!(label_break(false, false), 3); + + assert_eq!(break_value(true, false), 1); + assert_eq!(break_value(false, true), 2); + assert_eq!(break_value(false, false), 3); + + assert_eq!(label_break_mixed(0), 0); + assert_eq!(label_break_mixed(1), 1); + assert_eq!(label_break_mixed(2), 2); + assert_eq!(label_break_mixed(3), 3); + assert_eq!(label_break_mixed(4), 4); + assert_eq!(label_break_mixed(5), 5); + assert_eq!(label_break_mixed(6), 6); + + // FIXME: ensure that labeled blocks work if produced by macros and in match arms +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/labeled-break.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/labeled-break.rs new file mode 100644 index 000000000000..f5fc02dc90fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/labeled-break.rs @@ -0,0 +1,23 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + 'foo: loop { + loop { + break 'foo; + } + } + + 'bar: for _ in 0..100 { + loop { + break 'bar; + } + } + + 'foobar: while 1 + 1 == 2 { + loop { + break 'foobar; + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/linear-for-loop.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/linear-for-loop.rs new file mode 100644 index 000000000000..c00fadbfaac3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/linear-for-loop.rs @@ -0,0 +1,24 @@ +// run-pass +pub fn main() { + let x = vec![1, 2, 3]; + let mut y = 0; + for i in &x { println!("{}", *i); y += *i; } + println!("{}", y); + assert_eq!(y, 6); + let s = "hello there".to_string(); + let mut i: isize = 0; + for c in s.bytes() { + if i == 0 { assert_eq!(c, 'h' as u8); } + if i == 1 { assert_eq!(c, 'e' as u8); } + if i == 2 { assert_eq!(c, 'l' as u8); } + if i == 3 { assert_eq!(c, 'l' as u8); } + if i == 4 { assert_eq!(c, 'o' as u8); } + // ... + + i += 1; + println!("{}", i); + println!("{}", c); + } + assert_eq!(i, 11); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs new file mode 100644 index 000000000000..93423d84cec0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/liveness-assign-imm-local-after-loop.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_assignments)] +// pretty-expanded FIXME #23616 + +#![allow(unreachable_code)] +#![allow(unused_variables)] + +fn test(_cond: bool) { + let v: isize; + v = 1; + loop { } // loop never terminates, so no error is reported + v = 2; +} + +pub fn main() { + // note: don't call test()... :) +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/liveness-loop-break.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/liveness-loop-break.rs new file mode 100644 index 000000000000..fdf24a3a35a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/liveness-loop-break.rs @@ -0,0 +1,14 @@ +// run-pass +fn test() { + let v; + loop { + v = 3; + break; + } + println!("{}", v); +} + +pub fn main() { + test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/liveness-move-in-loop.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/liveness-move-in-loop.rs new file mode 100644 index 000000000000..3ff744b98532 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/liveness-move-in-loop.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] + +// pretty-expanded FIXME #23616 + +fn take(x: isize) -> isize {x} + +fn the_loop() { + let mut list = Vec::new(); + loop { + let x = 5; + if x > 3 { + list.push(take(x)); + } else { + break; + } + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-break-cont-1.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-break-cont-1.rs new file mode 100644 index 000000000000..42331b225b01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-break-cont-1.rs @@ -0,0 +1,10 @@ +// run-pass + +pub fn main() { + let _i = 0_usize; + loop { + break; + } + assert!(true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-break-cont.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-break-cont.rs new file mode 100644 index 000000000000..92bc7ea400de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-break-cont.rs @@ -0,0 +1,40 @@ +// run-pass +pub fn main() { + let mut i = 0_usize; + loop { + println!("a"); + i += 1_usize; + if i == 10_usize { + break; + } + } + assert_eq!(i, 10_usize); + let mut is_even = false; + loop { + if i == 21_usize { + break; + } + println!("b"); + is_even = false; + i += 1_usize; + if i % 2_usize != 0_usize { + continue; + } + is_even = true; + } + assert!(!is_even); + loop { + println!("c"); + if i == 22_usize { + break; + } + is_even = false; + i += 1_usize; + if i % 2_usize != 0_usize { + continue; + } + is_even = true; + } + assert!(is_even); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-break-value.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-break-value.rs new file mode 100644 index 000000000000..7a138d577928 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-break-value.rs @@ -0,0 +1,140 @@ +// run-pass + +#![allow(unreachable_code)] +#![feature(never_type)] + +#[allow(unused)] +fn never_returns() { + loop { + break loop {}; + } +} + +pub fn main() { + let value = 'outer: loop { + if 1 == 1 { + break 13; + } else { + let _never: ! = loop { + break loop { + break 'outer panic!(); + } + }; + } + }; + assert_eq!(value, 13); + + let x = [1, 3u32, 5]; + let y = [17]; + let z = []; + let coerced: &[_] = loop { + match 2 { + 1 => break &x, + 2 => break &y, + 3 => break &z, + _ => (), + } + }; + assert_eq!(coerced, &[17u32]); + + let trait_unified = loop { + break if true { + break Default::default() + } else { + break [13, 14] + }; + }; + assert_eq!(trait_unified, [0, 0]); + + let trait_unified_2 = loop { + if false { + break [String::from("Hello")] + } else { + break Default::default() + }; + }; + assert_eq!(trait_unified_2, [""]); + + let trait_unified_3 = loop { + break if false { + break [String::from("Hello")] + } else { + ["Yes".into()] + }; + }; + assert_eq!(trait_unified_3, ["Yes"]); + + let regular_break = loop { + if true { + break; + } else { + break break Default::default(); + } + }; + assert_eq!(regular_break, ()); + + let regular_break_2 = loop { + if true { + break Default::default(); + } else { + break; + } + }; + assert_eq!(regular_break_2, ()); + + let regular_break_3 = loop { + break if true { + Default::default() + } else { + break; + } + }; + assert_eq!(regular_break_3, ()); + + let regular_break_4 = loop { + break (); + break; + }; + assert_eq!(regular_break_4, ()); + + let regular_break_5 = loop { + break; + break (); + }; + assert_eq!(regular_break_5, ()); + + let nested_break_value = 'outer2: loop { + let _a: u32 = 'inner: loop { + if true { + break 'outer2 "hello"; + } else { + break 'inner 17; + } + }; + panic!(); + }; + assert_eq!(nested_break_value, "hello"); + + let break_from_while_cond = loop { + 'inner_loop: while break 'inner_loop { + panic!(); + } + break 123; + }; + assert_eq!(break_from_while_cond, 123); + + let break_from_while_to_outer = 'outer_loop: loop { + while break 'outer_loop 567 { + panic!("from_inner"); + } + panic!("from outer"); + }; + assert_eq!(break_from_while_to_outer, 567); + + let rust = true; + let value = loop { + break rust; + }; + assert!(value); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-diverges.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-diverges.rs new file mode 100644 index 000000000000..e88240126c83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-diverges.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(unused_parens)] +// pretty-expanded FIXME #23616 + +/* Make sure a loop{} can be the tailexpr in the body +of a diverging function */ + +fn forever() -> ! { + loop{} +} + +pub fn main() { + if (1 == 2) { forever(); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-label-shadowing.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-label-shadowing.rs new file mode 100644 index 000000000000..e8ec5f90926f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-label-shadowing.rs @@ -0,0 +1,13 @@ +// run-pass +// Issue #12512. + +// pretty-expanded FIXME #23616 + +fn main() { + let mut foo = Vec::new(); + #[allow(unused_labels)] + 'foo: for i in &[1, 2, 3] { + foo.push(*i); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-labeled-break-value.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-labeled-break-value.rs new file mode 100644 index 000000000000..00537787e7ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-labeled-break-value.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + 'outer: loop { + let _: i32 = loop { break 'outer }; + } + 'outer2: loop { + let _: i32 = loop { loop { break 'outer2 } }; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs new file mode 100644 index 000000000000..2ae0a66ca3c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-no-reinit-needed-post-bot.rs @@ -0,0 +1,35 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct S; +// Ensure S is moved, not copied, on assignment. +impl Drop for S { fn drop(&mut self) { } } + +// user-defined function "returning" bottom (i.e., no return at all). +fn my_panic() -> ! { loop {} } + +pub fn step(f: bool) { + let mut g = S; + let mut i = 0; + loop + { + if i > 10 { break; } else { i += 1; } + + let _g = g; + + if f { + // re-initialize g, but only before restarting loop. + g = S; + continue; + } + + my_panic(); + + // we never get here, so we do not need to re-initialize g. + } +} + +pub fn main() { + step(true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-scope.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-scope.rs new file mode 100644 index 000000000000..670a78545e5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/loop-scope.rs @@ -0,0 +1,9 @@ +// run-pass + +pub fn main() { + let x = vec![10, 20, 30]; + let mut sum = 0; + for x in &x { sum += *x; } + assert_eq!(sum, 60); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/while-cont.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-cont.rs new file mode 100644 index 000000000000..d0891558bbb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-cont.rs @@ -0,0 +1,12 @@ +// run-pass +// Issue #825: Should recheck the loop condition after continuing +pub fn main() { + let mut i = 1; + while i > 0 { + assert!((i > 0)); + println!("{}", i); + i -= 1; + continue; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/while-flow-graph.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-flow-graph.rs new file mode 100644 index 000000000000..816c5ce26165 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-flow-graph.rs @@ -0,0 +1,7 @@ +// run-pass + + +// pretty-expanded FIXME #23616 + +pub fn main() { let x: isize = 10; while x == 10 && x == 11 { let _y = 0xf00_usize; } } + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/while-label.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-label.rs new file mode 100644 index 000000000000..385699addd33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-label.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(unreachable_code)] + + +pub fn main() { + let mut i = 100; + 'w: while 1 + 1 == 2 { + i -= 1; + if i == 95 { + break 'w; + panic!("Should have broken out of loop"); + } + } + assert_eq!(i, 95); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/while-let.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-let.rs new file mode 100644 index 000000000000..9e3224690615 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-let.rs @@ -0,0 +1,47 @@ +// run-pass + +use std::collections::BinaryHeap; + +fn make_pq() -> BinaryHeap { + BinaryHeap::from(vec![1,2,3]) +} + +pub fn main() { + let mut pq = make_pq(); + let mut sum = 0; + while let Some(x) = pq.pop() { + sum += x; + } + assert_eq!(sum, 6); + + pq = make_pq(); + sum = 0; + 'a: while let Some(x) = pq.pop() { + sum += x; + if x == 2 { + break 'a; + } + } + assert_eq!(sum, 5); + + pq = make_pq(); + sum = 0; + 'a2: while let Some(x) = pq.pop() { + if x == 3 { + continue 'a2; + } + sum += x; + } + assert_eq!(sum, 3); + + let mut pq1 = make_pq(); + sum = 0; + while let Some(x) = pq1.pop() { + let mut pq2 = make_pq(); + while let Some(y) = pq2.pop() { + sum += x * y; + } + } + assert_eq!(sum, 6 + 12 + 18); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/while-loop-constraints-2.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-loop-constraints-2.rs new file mode 100644 index 000000000000..a0b41830b258 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-loop-constraints-2.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(unused_assignments)] +#![allow(unused_variables)] + +pub fn main() { + let mut y: isize = 42; + let mut z: isize = 42; + let mut x: isize; + while z < 50 { + z += 1; + while false { x = y; y = z; } + println!("{}", y); + } + assert!((y == 42 && z == 50)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/while-prelude-drop.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-prelude-drop.rs new file mode 100644 index 000000000000..8baa9c1400a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-prelude-drop.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(non_camel_case_types)] + +use std::string::String; + +#[derive(PartialEq)] +enum t { a, b(String), } + +fn make(i: isize) -> t { + if i > 10 { return t::a; } + let mut s = String::from("hello"); + // Ensure s is non-const. + + s.push_str("there"); + return t::b(s); +} + +pub fn main() { + let mut i = 0; + + + // The auto slot for the result of make(i) should not leak. + while make(i) != t::a { i += 1; } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/while-with-break.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-with-break.rs new file mode 100644 index 000000000000..1bafb0fb5a95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/while-with-break.rs @@ -0,0 +1,18 @@ +// run-pass + +pub fn main() { + let mut i: isize = 90; + while i < 100 { + println!("{}", i); + i = i + 1; + if i == 95 { + let _v: Vec = + vec![1, 2, 3, 4, 5]; // we check that it is freed by break + + println!("breaking"); + break; + } + } + assert_eq!(i, 95); +} + diff --git a/gcc/testsuite/rust/rustc/ui/for-loop-while/while.rs b/gcc/testsuite/rust/rustc/ui/for-loop-while/while.rs new file mode 100644 index 000000000000..8d1843d68529 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for-loop-while/while.rs @@ -0,0 +1,14 @@ +// run-pass + + +pub fn main() { + let mut x: isize = 10; + let mut y: isize = 0; + while y < x { println!("{}", y); println!("hello"); y = y + 1; } + while x > 0 { + println!("goodbye"); + x = x - 1; + println!("{}", x); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for/for-c-in-str.rs b/gcc/testsuite/rust/rustc/ui/for/for-c-in-str.rs new file mode 100644 index 000000000000..0c07a4eae4ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for/for-c-in-str.rs @@ -0,0 +1,17 @@ +// E0277 should point exclusively at line 6, not the entire for loop span + +fn main() { + for c in "asdf" { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-note ".E0277." "" { target *-*-* } .-2 } +// { help ".E0277." "" { target *-*-* } .-3 } +// { dg-note ".E0277." "" { target *-*-* } .-4 } +// { dg-note ".E0277." "" { target *-*-* } .-5 } +// { dg-note ".E0277." "" { target *-*-* } .-6 } +// { dg-note ".E0277." "" { target *-*-* } .-7 } +// { dg-note ".E0277." "" { target *-*-* } .-8 } +// { dg-note ".E0277." "" { target *-*-* } .-9 } + println!(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for/for-expn.rs b/gcc/testsuite/rust/rustc/ui/for/for-expn.rs new file mode 100644 index 000000000000..f247a53eacf4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for/for-expn.rs @@ -0,0 +1,10 @@ +// Test that an error on a sub-expresson in a for loop has the correct span. + +fn main() { + // Odd formatting to make sure we get the right span. + for t in & + foo // { dg-error ".E0425." "" { target *-*-* } } + { + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for/for-loop-bogosity.rs b/gcc/testsuite/rust/rustc/ui/for/for-loop-bogosity.rs new file mode 100644 index 000000000000..14ccc9a5f132 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for/for-loop-bogosity.rs @@ -0,0 +1,22 @@ +struct MyStruct { + x: isize, + y: isize, +} + +impl MyStruct { + fn next(&mut self) -> Option { + Some(self.x) + } +} + +pub fn main() { + let mut bogus = MyStruct { + x: 1, + y: 2, + }; + for x in bogus { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + drop(x); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for/for-loop-refutable-pattern-error-message.rs b/gcc/testsuite/rust/rustc/ui/for/for-loop-refutable-pattern-error-message.rs new file mode 100644 index 000000000000..98de3d82683f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for/for-loop-refutable-pattern-error-message.rs @@ -0,0 +1,4 @@ +fn main() { + for &1 in [1].iter() {} // { dg-error ".E0005." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/for/for-loop-type-error.rs b/gcc/testsuite/rust/rustc/ui/for/for-loop-type-error.rs new file mode 100644 index 000000000000..e2087e46c833 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for/for-loop-type-error.rs @@ -0,0 +1,7 @@ +pub fn main() { + let x = () + (); // { dg-error ".E0369." "" { target *-*-* } } + + // this shouldn't have a flow-on error: + for _ in x {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/for/for-loop-unconstrained-element-type.rs b/gcc/testsuite/rust/rustc/ui/for/for-loop-unconstrained-element-type.rs new file mode 100644 index 000000000000..4dbd7a1ca053 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/for/for-loop-unconstrained-element-type.rs @@ -0,0 +1,10 @@ +// Test that `for` loops don't introduce artificial +// constraints on the type of the binding (`i`). +// Subtle changes in the desugaring can cause the +// type of elements in the vector to (incorrectly) +// fallback to `!` or `()`. + +fn main() { + for i in Vec::new() { } // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/foreign-fn-return-lifetime.rs b/gcc/testsuite/rust/rustc/ui/foreign-fn-return-lifetime.rs new file mode 100644 index 000000000000..549a6d0fade5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/foreign-fn-return-lifetime.rs @@ -0,0 +1,9 @@ +// run-rustfix + +extern "C" { + pub fn g(_: &u8) -> &u8; // OK + pub fn f() -> &u8; // { dg-error ".E0106." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/foreign-unsafe-fn-called.rs b/gcc/testsuite/rust/rustc/ui/foreign-unsafe-fn-called.rs new file mode 100644 index 000000000000..1cba811997bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/foreign-unsafe-fn-called.rs @@ -0,0 +1,11 @@ +mod test { + extern { + pub fn free(); + } +} + +fn main() { + test::free(); +// { dg-error ".E0133." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/foreign/auxiliary/fn-abi.rs b/gcc/testsuite/rust/rustc/ui/foreign/auxiliary/fn-abi.rs new file mode 100644 index 000000000000..b53af324d40a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/foreign/auxiliary/fn-abi.rs @@ -0,0 +1,3 @@ +#[no_mangle] +pub extern fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/foreign/foreign-fn-linkname.rs b/gcc/testsuite/rust/rustc/ui/foreign/foreign-fn-linkname.rs new file mode 100644 index 000000000000..668545d91ee9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/foreign/foreign-fn-linkname.rs @@ -0,0 +1,31 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with +// ignore-sgx no libc + +#![feature(rustc_private)] + +extern crate libc; +use std::ffi::CString; + +mod mlibc { + use libc::{c_char, size_t}; + + extern { + #[link_name = "strlen"] + pub fn my_strlen(str: *const c_char) -> size_t; + } +} + +fn strlen(str: String) -> usize { + // C string is terminated with a zero + let s = CString::new(str).unwrap(); + unsafe { + mlibc::my_strlen(s.as_ptr()) as usize + } +} + +pub fn main() { + let len = strlen("Rust".to_string()); + assert_eq!(len, 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/foreign/foreign-int-types.rs b/gcc/testsuite/rust/rustc/ui/foreign/foreign-int-types.rs new file mode 100644 index 000000000000..c18ee7cf27fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/foreign/foreign-int-types.rs @@ -0,0 +1,14 @@ +// run-pass +#![forbid(improper_ctypes)] +#![allow(dead_code)] + +mod xx { + extern { + pub fn strlen(str: *const u8) -> usize; + pub fn foo(x: isize, y: usize); + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/foreign/foreign-mod-src/inner.rs b/gcc/testsuite/rust/rustc/ui/foreign/foreign-mod-src/inner.rs new file mode 100644 index 000000000000..bf4fee9004f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/foreign/foreign-mod-src/inner.rs @@ -0,0 +1,15 @@ +// run-pass + + + +pub fn main() { + let f = "Makefile"; + let s = rustrt.str_buf(f); + let buf = libc.malloc(1024); + let fd = libc.open(s, 0, 0); + libc.read(fd, buf, 1024); + libc.write(1, buf, 1024); + libc.close(fd); + libc.free(buf); +} + diff --git a/gcc/testsuite/rust/rustc/ui/foreign/foreign-mod-unused-const.rs b/gcc/testsuite/rust/rustc/ui/foreign/foreign-mod-unused-const.rs new file mode 100644 index 000000000000..23b2833afd12 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/foreign/foreign-mod-unused-const.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +mod foo { + extern { + pub static errno: u32; + } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/foreign/foreign-src/foreign.rs b/gcc/testsuite/rust/rustc/ui/foreign/foreign-src/foreign.rs new file mode 100644 index 000000000000..5477c40021dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/foreign/foreign-src/foreign.rs @@ -0,0 +1,10 @@ +// run-pass + + + +pub fn main() { + libc.puts(rustrt.str_buf("hello, extern world 1")); + libc.puts(rustrt.str_buf("hello, extern world 2")); + libc.puts(rustrt.str_buf("hello, extern world 3")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/foreign/foreign-truncated-arguments.rs b/gcc/testsuite/rust/rustc/ui/foreign/foreign-truncated-arguments.rs new file mode 100644 index 000000000000..5fde7120d1dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/foreign/foreign-truncated-arguments.rs @@ -0,0 +1,21 @@ +// run-pass +// compile-flags: -O +// Regression test for https://github.com/rust-lang/rust/issues/33868 + +#[repr(C)] +pub struct S { + a: u32, + b: f32, + c: u32 +} + +#[no_mangle] +#[inline(never)] +pub extern "C" fn test(s: S) -> u32 { + s.c +} + +fn main() { + assert_eq!(test(S{a: 0, b: 0.0, c: 42}), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/foreign/foreign2.rs b/gcc/testsuite/rust/rustc/ui/foreign/foreign2.rs new file mode 100644 index 000000000000..2783902d8050 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/foreign/foreign2.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(dead_code)] +// ignore-wasm32-bare no libc to test ffi with +// pretty-expanded FIXME #23616 + +#![feature(rustc_private)] + +extern crate libc; + +mod bar { + extern {} +} + +mod zed { + extern {} +} + +mod mlibc { + use libc::{c_int, c_void, size_t, ssize_t}; + + extern { + pub fn write(fd: c_int, buf: *const c_void, count: size_t) -> ssize_t; + } +} + +mod baz { + extern {} +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/foreign/issue-74120-lowering-of-ffi-block-bodies.rs b/gcc/testsuite/rust/rustc/ui/foreign/issue-74120-lowering-of-ffi-block-bodies.rs new file mode 100644 index 000000000000..a0794c915abc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/foreign/issue-74120-lowering-of-ffi-block-bodies.rs @@ -0,0 +1,12 @@ +// Previously this ICE'd because `fn g()` would be lowered, but the block associated with `fn f()` +// wasn't. + +// compile-flags: --crate-type=lib + +extern "C" { + fn f() { +// { dg-error "" "" { target *-*-* } .-1 } + fn g() {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/format-no-std.rs b/gcc/testsuite/rust/rustc/ui/format-no-std.rs new file mode 100644 index 000000000000..4bd69dd12018 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/format-no-std.rs @@ -0,0 +1,29 @@ +// run-pass +// ignore-emscripten no no_std executables + +#![feature(lang_items, start)] +#![no_std] + +extern crate std as other; + +#[macro_use] extern crate alloc; + +use alloc::string::ToString; + +#[start] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + let s = format!("{}", 1_isize); + assert_eq!(s, "1".to_string()); + + let s = format!("test"); + assert_eq!(s, "test".to_string()); + + let s = format!("{test}", test=3_isize); + assert_eq!(s, "3".to_string()); + + let s = format!("hello {}", "world"); + assert_eq!(s, "hello world".to_string()); + + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/fsu-moves-and-copies.rs b/gcc/testsuite/rust/rustc/ui/fsu-moves-and-copies.rs new file mode 100644 index 000000000000..f9d33c10ad47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fsu-moves-and-copies.rs @@ -0,0 +1,96 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(stable_features)] +// Issue 4691: Ensure that functional-struct-updates operates +// correctly and moves rather than copy when appropriate. + +#![feature(box_syntax, core)] + +struct ncint { v: isize } +fn ncint(v: isize) -> ncint { ncint { v: v } } + +struct NoFoo { copied: isize, nocopy: ncint, } +impl NoFoo { + fn new(x:isize,y:isize) -> NoFoo { NoFoo { copied: x, nocopy: ncint(y) } } +} + +struct MoveFoo { copied: isize, moved: Box, } +impl MoveFoo { + fn new(x:isize,y:isize) -> MoveFoo { MoveFoo { copied: x, moved: box y } } +} + +struct DropNoFoo { inner: NoFoo } +impl DropNoFoo { + fn new(x:isize,y:isize) -> DropNoFoo { DropNoFoo { inner: NoFoo::new(x,y) } } +} +impl Drop for DropNoFoo { fn drop(&mut self) { } } + +struct DropMoveFoo { inner: MoveFoo } +impl DropMoveFoo { + fn new(x:isize,y:isize) -> DropMoveFoo { DropMoveFoo { inner: MoveFoo::new(x,y) } } +} +impl Drop for DropMoveFoo { fn drop(&mut self) { } } + + +fn test0() { + // just copy implicitly copyable fields from `f`, no moves + // (and thus it is okay that these are Drop; compare against + // compile-fail test: borrowck-struct-update-with-dtor.rs). + + // Case 1: Nocopyable + let f = DropNoFoo::new(1, 2); + let b = DropNoFoo { inner: NoFoo { nocopy: ncint(3), ..f.inner }}; + let c = DropNoFoo { inner: NoFoo { nocopy: ncint(4), ..f.inner }}; + assert_eq!(f.inner.copied, 1); + assert_eq!(f.inner.nocopy.v, 2); + + assert_eq!(b.inner.copied, 1); + assert_eq!(b.inner.nocopy.v, 3); + + assert_eq!(c.inner.copied, 1); + assert_eq!(c.inner.nocopy.v, 4); + + // Case 2: Owned + let f = DropMoveFoo::new(5, 6); + let b = DropMoveFoo { inner: MoveFoo { moved: box 7, ..f.inner }}; + let c = DropMoveFoo { inner: MoveFoo { moved: box 8, ..f.inner }}; + assert_eq!(f.inner.copied, 5); + assert_eq!(*f.inner.moved, 6); + + assert_eq!(b.inner.copied, 5); + assert_eq!(*b.inner.moved, 7); + + assert_eq!(c.inner.copied, 5); + assert_eq!(*c.inner.moved, 8); +} + +fn test1() { + // copying move-by-default fields from `f`, so it moves: + let f = MoveFoo::new(11, 12); + + let b = MoveFoo {moved: box 13, ..f}; + let c = MoveFoo {copied: 14, ..f}; + assert_eq!(b.copied, 11); + assert_eq!(*b.moved, 13); + assert_eq!(c.copied, 14); + assert_eq!(*c.moved, 12); +} + +fn test2() { + // move non-copyable field + let f = NoFoo::new(21, 22); + let b = NoFoo {nocopy: ncint(23), ..f}; + let c = NoFoo {copied: 24, ..f}; + assert_eq!(b.copied, 21); + assert_eq!(b.nocopy.v, 23); + assert_eq!(c.copied, 24); + assert_eq!(c.nocopy.v, 22); +} + +pub fn main() { + test0(); + test1(); + test2(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/fully-qualified-type/fully-qualified-type-name1.rs b/gcc/testsuite/rust/rustc/ui/fully-qualified-type/fully-qualified-type-name1.rs new file mode 100644 index 000000000000..b57233577926 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fully-qualified-type/fully-qualified-type-name1.rs @@ -0,0 +1,11 @@ +// Test that we use fully-qualified type names in error messages. + +fn main() { + let x: Option; + x = 5; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/fully-qualified-type/fully-qualified-type-name2.rs b/gcc/testsuite/rust/rustc/ui/fully-qualified-type/fully-qualified-type-name2.rs new file mode 100644 index 000000000000..f79536a60635 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fully-qualified-type/fully-qualified-type-name2.rs @@ -0,0 +1,19 @@ +// Test that we use fully-qualified type names in error messages. + +mod x { + pub enum Foo { } +} + +mod y { + pub enum Foo { } +} + +fn bar(x: x::Foo) -> y::Foo { + return x; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/fully-qualified-type/fully-qualified-type-name4.rs b/gcc/testsuite/rust/rustc/ui/fully-qualified-type/fully-qualified-type-name4.rs new file mode 100644 index 000000000000..b05d46ba5ee0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fully-qualified-type/fully-qualified-type-name4.rs @@ -0,0 +1,15 @@ +// Test that we use fully-qualified type names in error messages. + +use std::option::Option; + +fn bar(x: usize) -> Option { + return x; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/fun-call-variants.rs b/gcc/testsuite/rust/rustc/ui/fun-call-variants.rs new file mode 100644 index 000000000000..61bc36d0aaf9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fun-call-variants.rs @@ -0,0 +1,13 @@ +// run-pass + +fn ho(f: F) -> isize where F: FnOnce(isize) -> isize { let n: isize = f(3); return n; } + +fn direct(x: isize) -> isize { return x + 1; } + +pub fn main() { + let a: isize = direct(3); // direct + let b: isize = ho(direct); // indirect unbound + + assert_eq!(a, b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/fun-indirect-call.rs b/gcc/testsuite/rust/rustc/ui/fun-indirect-call.rs new file mode 100644 index 000000000000..da8d058fe92f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/fun-indirect-call.rs @@ -0,0 +1,10 @@ +// run-pass + +fn f() -> isize { return 42; } + +pub fn main() { + let g: fn() -> isize = f; + let i: isize = g(); + assert_eq!(i, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functional-struct-update/functional-struct-update-noncopyable.rs b/gcc/testsuite/rust/rustc/ui/functional-struct-update/functional-struct-update-noncopyable.rs new file mode 100644 index 000000000000..69fecae0f725 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functional-struct-update/functional-struct-update-noncopyable.rs @@ -0,0 +1,15 @@ +// issue 7327 + +use std::sync::Arc; + +struct A { y: Arc, x: Arc } + +impl Drop for A { + fn drop(&mut self) { println!("x={}", *self.x); } +} +fn main() { + let a = A { y: Arc::new(1), x: Arc::new(2) }; + let _b = A { y: Arc::new(3), ..a }; // { dg-error ".E0509." "" { target *-*-* } } + let _c = a; +} + diff --git a/gcc/testsuite/rust/rustc/ui/functional-struct-update/functional-struct-update-respects-privacy.rs b/gcc/testsuite/rust/rustc/ui/functional-struct-update/functional-struct-update-respects-privacy.rs new file mode 100644 index 000000000000..4b7d4cb4a5e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functional-struct-update/functional-struct-update-respects-privacy.rs @@ -0,0 +1,33 @@ +// RFC 736 (and Issue 21407): functional struct update should respect privacy. + +// The `foo` module attempts to maintains an invariant that each `S` +// has a unique `u64` id. +use self::foo::S; +mod foo { + use std::cell::{UnsafeCell}; + + static mut COUNT : UnsafeCell = UnsafeCell::new(1); + + pub struct S { pub a: u8, pub b: String, secret_uid: u64 } + + pub fn make_secrets(a: u8, b: String) -> S { + let val = unsafe { let p = COUNT.get(); let val = *p; *p = val + 1; val }; + println!("creating {}, uid {}", b, val); + S { a: a, b: b, secret_uid: val } + } + + impl Drop for S { + fn drop(&mut self) { + println!("dropping {}, uid {}", self.b, self.secret_uid); + } + } +} + +fn main() { + let s_1 = foo::make_secrets(3, format!("ess one")); + let s_2 = foo::S { b: format!("ess two"), ..s_1 }; // FRU ... +// { dg-error ".E0451." "" { target *-*-* } .-1 } + println!("main forged an S named: {}", s_2.b); + // at end of scope, ... both s_1 *and* s_2 get dropped. Boom! +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/auxiliary/fn-abi.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/auxiliary/fn-abi.rs new file mode 100644 index 000000000000..b53af324d40a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/auxiliary/fn-abi.rs @@ -0,0 +1,3 @@ +#[no_mangle] +pub extern fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/call-closure-from-overloaded-op.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/call-closure-from-overloaded-op.rs new file mode 100644 index 000000000000..09731b235769 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/call-closure-from-overloaded-op.rs @@ -0,0 +1,10 @@ +// run-pass + +fn foo() -> isize { 22 } + +pub fn main() { + let mut x: Vec isize> = Vec::new(); + x.push(foo); + assert_eq!((x[0])(), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/capture-clauses-boxed-closures.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/capture-clauses-boxed-closures.rs new file mode 100644 index 000000000000..5c2f5b1c942f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/capture-clauses-boxed-closures.rs @@ -0,0 +1,15 @@ +// run-pass + +fn each(x: &[T], mut f: F) where F: FnMut(&T) { + for val in x { + f(val) + } +} + +fn main() { + let mut sum = 0_usize; + let elems = [ 1_usize, 2, 3, 4, 5 ]; + each(&elems, |val| sum += *val); + assert_eq!(sum, 15); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/capture-clauses-unboxed-closures.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/capture-clauses-unboxed-closures.rs new file mode 100644 index 000000000000..dc5eb0d10b14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/capture-clauses-unboxed-closures.rs @@ -0,0 +1,14 @@ +// run-pass +fn each<'a,T,F:FnMut(&'a T)>(x: &'a [T], mut f: F) { + for val in x { + f(val) + } +} + +fn main() { + let mut sum = 0; + let elems = [ 1, 2, 3, 4, 5 ]; + each(&elems, |val: &usize| sum += *val); + assert_eq!(sum, 15); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/clone-closure.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/clone-closure.rs new file mode 100644 index 000000000000..e14532d54d95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/clone-closure.rs @@ -0,0 +1,19 @@ +// run-pass +// Check that closures implement `Clone`. + +#[derive(Clone)] +struct S(i32); + +fn main() { + let mut a = S(5); + let mut hello = move || { + a.0 += 1; + println!("Hello {}", a.0); + a.0 + }; + + let mut hello2 = hello.clone(); + assert_eq!(6, hello2()); + assert_eq!(6, hello()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/closure-bounds-can-capture-chan.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-bounds-can-capture-chan.rs new file mode 100644 index 000000000000..55fcddddd7ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-bounds-can-capture-chan.rs @@ -0,0 +1,17 @@ +// run-pass +// pretty-expanded FIXME #23616 + +use std::sync::mpsc::channel; + +fn foo(blk: F) { + blk(); +} + +pub fn main() { + let (tx, rx) = channel(); + foo(move || { + tx.send(()).unwrap(); + }); + rx.recv().unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs new file mode 100644 index 000000000000..f2287935a88b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/expect-infer-supply-two-infers.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +fn with_closure(_: F) + where F: FnOnce(Vec, A) +{ +} + +fn expect_free_supply_free<'x>(x: &'x u32) { + with_closure(|mut x: Vec<_>, y| { + // Shows that the call to `x.push()` is influencing type of `y`... + x.push(22_u32); + + // ...since we now know the type of `y` and can resolve the method call. + let _ = y.wrapping_add(1); + }); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/issue-38714.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/issue-38714.rs new file mode 100644 index 000000000000..c6427f525bed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/issue-38714.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +struct UsizeRef<'a> { + a: &'a usize +} + +type RefTo = Box Fn(&'r Vec) -> UsizeRef<'r>>; + +fn ref_to<'a>(vec: &'a Vec) -> UsizeRef<'a> { + UsizeRef{ a: &vec[0]} +} + +fn main() { + // Regression test: this was causing ICEs; it should compile. + let a: RefTo = Box::new(|vec: &Vec| { + UsizeRef{ a: &vec[0] } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/supply-just-return-type.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/supply-just-return-type.rs new file mode 100644 index 000000000000..79f69d260a47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/supply-just-return-type.rs @@ -0,0 +1,27 @@ +// run-pass +fn with_closure(f: F) -> Result + where F: FnOnce(&char) -> Result, +{ + f(&'a') +} + +fn main() { + // Test that supplying the `-> Result` manually here + // (which is needed to constrain `R`) still allows us to figure + // out that the type of `x` is `&'a char` where `'a` is bound in + // the closure (if we didn't, we'd get a type-error because + // `with_closure` requires a bound region). + // + // This pattern was found in the wild. + let z = with_closure(|x| -> Result { Ok(*x) }); + assert_eq!(z.unwrap(), 'a'); + + // It also works with `_`: + let z = with_closure(|x: _| -> Result { Ok(*x) }); + assert_eq!(z.unwrap(), 'a'); + + // It also works with `&_`: + let z = with_closure(|x: &_| -> Result { Ok(*x) }); + assert_eq!(z.unwrap(), 'a'); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/supply-nothing.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/supply-nothing.rs new file mode 100644 index 000000000000..71d829ce2480 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-expected-type/supply-nothing.rs @@ -0,0 +1,12 @@ +// run-pass +fn with_closure(f: F) -> u32 + where F: FnOnce(&u32, &u32) -> u32 +{ + f(&22, &44) +} + +fn main() { + let z = with_closure(|x, y| x + y).wrapping_add(1); + assert_eq!(z, 22 + 44 + 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/closure-immediate.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-immediate.rs new file mode 100644 index 000000000000..0f92897321c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-immediate.rs @@ -0,0 +1,14 @@ +// run-pass + +// After the work to reoptimize structs, it became possible for immediate logic to fail. +// This test verifies that it actually works. + +fn main() { + let c = |a: u8, b: u16, c: u8| { + assert_eq!(a, 1); + assert_eq!(b, 2); + assert_eq!(c, 3); + }; + c(1, 2, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/closure-inference.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-inference.rs new file mode 100644 index 000000000000..b0d723a46de8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-inference.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(unused_braces)] + +fn foo(i: isize) -> isize { i + 1 } + +fn apply(f: F, v: A) -> A where F: FnOnce(A) -> A { f(v) } + +pub fn main() { + let f = {|i| foo(i)}; + assert_eq!(apply(f, 2), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/closure-inference2.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-inference2.rs new file mode 100644 index 000000000000..654357faec8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-inference2.rs @@ -0,0 +1,10 @@ +// run-pass +// Test a rather underspecified example: +#![allow(unused_braces)] + +pub fn main() { + let f = {|i| i}; + assert_eq!(f(2), 2); + assert_eq!(f(5), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/closure-reform.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-reform.rs new file mode 100644 index 000000000000..09a76fc0ff3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-reform.rs @@ -0,0 +1,57 @@ +// run-pass +#![allow(unused_variables)] +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +fn call_it(f: F) + where F : FnOnce(String) -> String +{ + println!("{}", f("Fred".to_string())) +} + +fn call_a_thunk(f: F) where F: FnOnce() { + f(); +} + +fn call_this(f: F) where F: FnOnce(&str) + Send { + f("Hello!"); +} + +fn call_bare(f: fn(&str)) { + f("Hello world!") +} + +fn call_bare_again(f: extern "Rust" fn(&str)) { + f("Goodbye world!") +} + +pub fn main() { + // Procs + + let greeting = "Hello ".to_string(); + call_it(|s| { + format!("{}{}", greeting, s) + }); + + let greeting = "Goodbye ".to_string(); + call_it(|s| format!("{}{}", greeting, s)); + + let greeting = "How's life, ".to_string(); + call_it(|s: String| -> String { + format!("{}{}", greeting, s) + }); + + // Closures + + call_a_thunk(|| println!("Hello world!")); + + call_this(|s| println!("{}", s)); + + // External functions + + fn foo(s: &str) {} + call_bare(foo); + + call_bare_again(foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/closure-returning-closure.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-returning-closure.rs new file mode 100644 index 000000000000..3bb0fcee4f96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-returning-closure.rs @@ -0,0 +1,6 @@ +// run-pass +fn main() { + let f = |_||x, y| x+y; + assert_eq!(f(())(1, 2), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/closure-to-fn-coercion.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-to-fn-coercion.rs new file mode 100644 index 000000000000..ae071386afb2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/closure-to-fn-coercion.rs @@ -0,0 +1,36 @@ +// run-pass +use std::mem; + +const FOO: fn(u8) -> u8 = |v: u8| { v }; + +const BAR: [fn(&mut u32); 5] = [ + |_: &mut u32| {}, + |v: &mut u32| *v += 1, + |v: &mut u32| *v += 2, + |v: &mut u32| *v += 3, + |v: &mut u32| *v += 4, +]; +fn func_specific() -> fn() -> u32 { + || return 42 +} + +fn generic(_: T) -> fn() -> usize { + || mem::size_of::() +} + +fn main() { + // Items + assert_eq!(func_specific()(), 42); + let foo: fn(u8) -> u8 = |v: u8| { v }; + assert_eq!(foo(31), 31); + // Constants + assert_eq!(FOO(31), 31); + let mut a: u32 = 0; + assert_eq!({ BAR[0](&mut a); a }, 0); + assert_eq!({ BAR[1](&mut a); a }, 1); + assert_eq!({ BAR[2](&mut a); a }, 3); + assert_eq!({ BAR[3](&mut a); a }, 6); + assert_eq!({ BAR[4](&mut a); a }, 10); + assert_eq!(generic(0i8)(), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/closure_to_fn_coercion-expected-types.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/closure_to_fn_coercion-expected-types.rs new file mode 100644 index 000000000000..da80978c3410 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/closure_to_fn_coercion-expected-types.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(unused_variables)] +// Ensure that we deduce expected argument types when a `fn()` type is expected (#41755) + +fn foo(f: fn(Vec) -> usize) { } + +fn main() { + foo(|x| x.len()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/copy-closure.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/copy-closure.rs new file mode 100644 index 000000000000..2482e6dd27a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/copy-closure.rs @@ -0,0 +1,17 @@ +// run-pass +// Check that closures implement `Copy`. + +fn call T>(f: F) -> T { f() } + +fn main() { + let a = 5; + let hello = || { + println!("Hello {}", a); + a + }; + + assert_eq!(5, call(hello.clone())); + assert_eq!(5, call(hello)); + assert_eq!(5, call(hello)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/fn-abi.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-abi.rs new file mode 100644 index 000000000000..0ec486ab75e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-abi.rs @@ -0,0 +1,19 @@ +// run-pass +// Ensure that declarations and types which use `extern fn` both have the same +// ABI (#9309). + +// pretty-expanded FIXME #23616 +// aux-build:fn-abi.rs + +extern crate fn_abi; + +extern { + fn foo(); +} + +pub fn main() { + // Will only type check if the type of _p and the decl of foo use the + // same ABI + let _p: unsafe extern fn() = foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-assign.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-assign.rs new file mode 100644 index 000000000000..c6b48930e53e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-assign.rs @@ -0,0 +1,18 @@ +// run-pass + +fn f(i: isize, called: &mut bool) { + assert_eq!(i, 10); + *called = true; +} + +fn g(f: fn(isize, v: &mut bool), called: &mut bool) { + f(10, called); +} + +pub fn main() { + let mut called = false; + let h = f; + g(h, &mut called); + assert_eq!(called, true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-coerce-to-block.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-coerce-to-block.rs new file mode 100644 index 000000000000..77804725d514 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-coerce-to-block.rs @@ -0,0 +1,11 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn bare() {} + +fn likes_block(f: F) where F: FnOnce() { f() } + +pub fn main() { + likes_block(bare); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-item.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-item.rs new file mode 100644 index 000000000000..f22978794707 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-item.rs @@ -0,0 +1,9 @@ +// run-pass +fn f() { + println!("This is a bare function"); +} + +pub fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-size.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-size.rs new file mode 100644 index 000000000000..0d0db5b75877 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-size.rs @@ -0,0 +1,9 @@ +// run-pass + +use std::mem; + +pub fn main() { + // Bare functions should just be a pointer + assert_eq!(mem::size_of::(), mem::size_of::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-spawn.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-spawn.rs new file mode 100644 index 000000000000..36dd697f3b46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-bare-spawn.rs @@ -0,0 +1,16 @@ +// run-pass +// This is what the signature to spawn should look like with bare functions + + +fn spawn(val: T, f: fn(T)) { + f(val); +} + +fn f(i: isize) { + assert_eq!(i, 100); +} + +pub fn main() { + spawn(100, f); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/fn-coerce-field.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-coerce-field.rs new file mode 100644 index 000000000000..c6f86562e498 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-coerce-field.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 +#![allow(non_camel_case_types)] + +struct r where F: FnOnce() { + field: F, +} + +pub fn main() { + fn f() {} + let _i: r = r {field: f as fn()}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/fn-item-type-cast.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-item-type-cast.rs new file mode 100644 index 000000000000..626405cdeb78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-item-type-cast.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test explicit coercions from a fn item type to a fn pointer type. + + +fn foo(x: isize) -> isize { x * 2 } +fn bar(x: isize) -> isize { x * 4 } +type IntMap = fn(isize) -> isize; + +fn eq(x: T, y: T) { } + +static TEST: Option = Some(foo as IntMap); + +fn main() { + let f = foo as IntMap; + + let f = if true { foo as IntMap } else { bar as IntMap }; + assert_eq!(f(4), 8); + + eq(foo as IntMap, bar as IntMap); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/fn-item-type-coerce.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-item-type-coerce.rs new file mode 100644 index 000000000000..687b6eafab49 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-item-type-coerce.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(unused_variables)] +// Test implicit coercions from a fn item type to a fn pointer type. + +// pretty-expanded FIXME #23616 + +fn foo(x: isize) -> isize { x * 2 } +fn bar(x: isize) -> isize { x * 4 } +type IntMap = fn(isize) -> isize; + +fn eq(x: T, y: T) { } + +fn main() { + let f: IntMap = foo; + + eq::(foo, bar); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/fn-item-type-zero-sized.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-item-type-zero-sized.rs new file mode 100644 index 000000000000..7bc4522f662b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-item-type-zero-sized.rs @@ -0,0 +1,14 @@ +// run-pass +// Test that fn item types are zero-sized. + +use std::mem::{size_of, size_of_val}; + +fn main() { + assert_eq!(size_of_val(&main), 0); + + let (a, b) = (size_of::, size_of::); + assert_eq!(size_of_val(&a), 0); + assert_eq!(size_of_val(&b), 0); + assert_eq!((a(), b()), (1, 2)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/fn-lval.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-lval.rs new file mode 100644 index 000000000000..59663ae75f71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-lval.rs @@ -0,0 +1,12 @@ +// run-pass + + + +// pretty-expanded FIXME #23616 + +fn foo(_f: fn(isize) -> isize) { } + +fn id(x: isize) -> isize { return x; } + +pub fn main() { foo(id); } + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/fn-type-infer.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-type-infer.rs new file mode 100644 index 000000000000..f8dbc060f2a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/fn-type-infer.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![allow(unused_variables)] + +pub fn main() { + // We should be able to type infer inside of ||s. + let _f = || { + let i = 10; + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/implied-bounds-closure-arg-outlives.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/implied-bounds-closure-arg-outlives.rs new file mode 100644 index 000000000000..966e1121512b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/implied-bounds-closure-arg-outlives.rs @@ -0,0 +1,36 @@ +// run-pass +// Test that we are able to handle the relationships between free +// regions bound in a closure callback. + +#[derive(Copy, Clone)] +struct MyCx<'short, 'long: 'short> { + short: &'short u32, + long: &'long u32, +} + +impl<'short, 'long> MyCx<'short, 'long> { + fn short(self) -> &'short u32 { self.short } + fn long(self) -> &'long u32 { self.long } + fn set_short(&mut self, v: &'short u32) { self.short = v; } +} + +fn with(op: F) -> R +where + F: for<'short, 'long> FnOnce(MyCx<'short, 'long>) -> R, +{ + op(MyCx { + short: &22, + long: &22, + }) +} + +fn main() { + with(|mut cx| { + // For this to type-check, we need to be able to deduce that + // the lifetime of `l` can be `'short`, even though it has + // input from `'long`. + let l = if true { cx.long() } else { cx.short() }; + cx.set_short(l); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/nullable-pointer-opt-closures.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/nullable-pointer-opt-closures.rs new file mode 100644 index 000000000000..62004c3142c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/nullable-pointer-opt-closures.rs @@ -0,0 +1,35 @@ +// run-pass + +use std::mem; + +pub fn main() { + // By Ref Capture + let a = 10i32; + let b = Some(|| println!("{}", a)); + // When we capture by reference we can use any of the + // captures as the discriminant since they're all + // behind a pointer. + assert_eq!(mem::size_of_val(&b), mem::size_of::()); + + // By Value Capture + let a = Box::new(12i32); + let b = Some(move || println!("{}", a)); + // We captured `a` by value and since it's a `Box` we can use it + // as the discriminant. + assert_eq!(mem::size_of_val(&b), mem::size_of::>()); + + // By Value Capture - Transitive case + let a = "Hello".to_string(); // String -> Vec -> Unique -> NonZero + let b = Some(move || println!("{}", a)); + // We captured `a` by value and since down the chain it contains + // a `NonZero` field, we can use it as the discriminant. + assert_eq!(mem::size_of_val(&b), mem::size_of::()); + + // By Value - No Optimization + let a = 14i32; + let b = Some(move || println!("{}", a)); + // We captured `a` by value but we can't use it as the discriminant + // thus we end up with an extra field for the discriminant + assert_eq!(mem::size_of_val(&b), mem::size_of::<(i32, i32)>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/parallel-codegen-closures.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/parallel-codegen-closures.rs new file mode 100644 index 000000000000..00866dae8684 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/parallel-codegen-closures.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(stable_features)] + +// Tests parallel codegen - this can fail if the symbol for the anonymous +// closure in `sum` pollutes the second codegen unit from the first. + +// compile-flags: -C codegen_units=2 + +#![feature(iter_arith)] + +mod a { + fn foo() { + let x = ["a", "bob", "c"]; + let len: usize = x.iter().map(|s| s.len()).sum(); + } +} + +mod b { + fn bar() { + let x = ["a", "bob", "c"]; + let len: usize = x.iter().map(|s| s.len()).sum(); + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/functions-closures/return-from-closure.rs b/gcc/testsuite/rust/rustc/ui/functions-closures/return-from-closure.rs new file mode 100644 index 000000000000..f43a64ec5b14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/functions-closures/return-from-closure.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(non_upper_case_globals)] +// just to make sure that `return` is only returning from the closure, +// not the surrounding function. + +static mut calls: usize = 0; + +fn surrounding() { + let return_works = |n: isize| { + unsafe { calls += 1 } + + if n >= 0 { return; } + panic!() + }; + + return_works(10); + return_works(20); + + let return_works_proc = |n: isize| { + unsafe { calls += 1 } + + if n >= 0 { return; } + panic!() + }; + + return_works_proc(10); +} + +pub fn main() { + surrounding(); + + assert_eq!(unsafe {calls}, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/future-incompatible-lint-group.rs b/gcc/testsuite/rust/rustc/ui/future-incompatible-lint-group.rs new file mode 100644 index 000000000000..613e2848327b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/future-incompatible-lint-group.rs @@ -0,0 +1,9 @@ +#![deny(future_incompatible)] + +trait Tr { + fn f(u8) {} // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/gated-bad-feature.rs b/gcc/testsuite/rust/rustc/ui/gated-bad-feature.rs new file mode 100644 index 000000000000..a1b2eb082644 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/gated-bad-feature.rs @@ -0,0 +1,11 @@ +#![feature(foo_bar_baz, foo(bar), foo = "baz", foo)] +// { dg-error ".E0556." "" { target *-*-* } .-1 } +// { dg-error ".E0556." "" { target *-*-* } .-2 } + +#![feature] // { dg-error "" "" { target *-*-* } } +#![feature = "foo"] // { dg-error "" "" { target *-*-* } } + +#![feature(test_removed_feature)] // { dg-error ".E0557." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/addassign-yield.rs b/gcc/testsuite/rust/rustc/ui/generator/addassign-yield.rs new file mode 100644 index 000000000000..fd2f2dd556e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/addassign-yield.rs @@ -0,0 +1,36 @@ +// run-pass +// Regression test for broken MIR error (#61442) +// Due to the two possible evaluation orders for +// a '+=' expression (depending on whether or not the 'AddAssign' trait +// is being used), we were failing to account for all types that might +// possibly be live across a yield point. + +#![feature(generators)] + +fn foo() { + let _x = static || { + let mut s = String::new(); + s += { yield; "" }; + }; + + let _y = static || { + let x = &mut 0; + *{ yield; x } += match String::new() { _ => 0 }; + }; + + // Please don't ever actually write something like this + let _z = static || { + let x = &mut 0; + *{ + let inner = &mut 1; + *{ yield (); inner } += match String::new() { _ => 1}; + yield; + x + } += match String::new() { _ => 2 }; + }; +} + +fn main() { + foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/async-generator-issue-67158.rs b/gcc/testsuite/rust/rustc/ui/generator/async-generator-issue-67158.rs new file mode 100644 index 000000000000..aaa6183d7ebd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/async-generator-issue-67158.rs @@ -0,0 +1,7 @@ +#![feature(generators)] +// edition:2018 +// Regression test for #67158. +fn main() { + async { yield print!(":C") }; // { dg-error ".E0727." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/auto-trait-regions.rs b/gcc/testsuite/rust/rustc/ui/generator/auto-trait-regions.rs new file mode 100644 index 000000000000..28165e1e04fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/auto-trait-regions.rs @@ -0,0 +1,54 @@ +#![feature(generators)] +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +auto trait Foo {} + +struct No; + +impl !Foo for No {} + +struct A<'a, 'b>(&'a mut bool, &'b mut bool, No); + +impl<'a, 'b: 'a> Foo for A<'a, 'b> {} + +struct OnlyFooIfStaticRef(No); +impl Foo for &'static OnlyFooIfStaticRef {} + +struct OnlyFooIfRef(No); +impl<'a> Foo for &'a OnlyFooIfRef {} + +fn assert_foo(f: T) {} + +fn main() { + // Make sure 'static is erased for generator interiors so we can't match it in trait selection + let x: &'static _ = &OnlyFooIfStaticRef(No); + let gen = || { + let x = x; + yield; + assert_foo(x); + }; + assert_foo(gen); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + // Allow impls which matches any lifetime + let x = &OnlyFooIfRef(No); + let gen = || { + let x = x; + yield; + assert_foo(x); + }; + assert_foo(gen); // ok + + // Disallow impls which relates lifetimes in the generator interior + let gen = || { + let a = A(&mut true, &mut true, No); + yield; + assert_foo(a); + }; + assert_foo(gen); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/auxiliary/xcrate-reachable.rs b/gcc/testsuite/rust/rustc/ui/generator/auxiliary/xcrate-reachable.rs new file mode 100644 index 000000000000..396213ff9592 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/auxiliary/xcrate-reachable.rs @@ -0,0 +1,15 @@ +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +fn msg() -> u32 { + 0 +} + +pub fn foo() -> impl Generator<(), Yield=(), Return=u32> { + || { + yield; + return msg(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/auxiliary/xcrate.rs b/gcc/testsuite/rust/rustc/ui/generator/auxiliary/xcrate.rs new file mode 100644 index 000000000000..15f4251dc1db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/auxiliary/xcrate.rs @@ -0,0 +1,19 @@ +#![feature(generators, generator_trait)] + +use std::marker::Unpin; +use std::ops::Generator; + +pub fn foo() -> impl Generator<(), Yield = (), Return = ()> { + || { + if false { + yield; + } + } +} + +pub fn bar(t: T) -> Box + Unpin> { + Box::new(|| { + yield t; + }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/borrow-in-tail-expr.rs b/gcc/testsuite/rust/rustc/ui/generator/borrow-in-tail-expr.rs new file mode 100644 index 000000000000..fcae82576939 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/borrow-in-tail-expr.rs @@ -0,0 +1,12 @@ +// run-pass + +#![feature(generators)] + +fn main() { + let _a = || { + yield; + let a = String::new(); + a.len() + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/borrowing.rs b/gcc/testsuite/rust/rustc/ui/generator/borrowing.rs new file mode 100644 index 000000000000..d4d6b0e4da46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/borrowing.rs @@ -0,0 +1,21 @@ +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::pin::Pin; + +fn main() { + let _b = { + let a = 3; + Pin::new(&mut || yield &a).resume(()) +// { dg-error ".E0597." "" { target *-*-* } .-1 } + }; + + let _b = { + let a = 3; + || { + yield &a +// { dg-error ".E0597." "" { target *-*-* } .-1 } + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/conditional-drop.rs b/gcc/testsuite/rust/rustc/ui/generator/conditional-drop.rs new file mode 100644 index 000000000000..edbb4978b4c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/conditional-drop.rs @@ -0,0 +1,62 @@ +// run-pass + +// revisions: default nomiropt +//[nomiropt]compile-flags: -Z mir-opt-level=0 + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::pin::Pin; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static A: AtomicUsize = AtomicUsize::new(0); + +struct B; + +impl Drop for B { + fn drop(&mut self) { + A.fetch_add(1, Ordering::SeqCst); + } +} + + +fn test() -> bool { true } +fn test2() -> bool { false } + +fn main() { + t1(); + t2(); +} + +fn t1() { + let mut a = || { + let b = B; + if test() { + drop(b); + } + yield; + }; + + let n = A.load(Ordering::SeqCst); + Pin::new(&mut a).resume(()); + assert_eq!(A.load(Ordering::SeqCst), n + 1); + Pin::new(&mut a).resume(()); + assert_eq!(A.load(Ordering::SeqCst), n + 1); +} + +fn t2() { + let mut a = || { + let b = B; + if test2() { + drop(b); + } + yield; + }; + + let n = A.load(Ordering::SeqCst); + Pin::new(&mut a).resume(()); + assert_eq!(A.load(Ordering::SeqCst), n); + Pin::new(&mut a).resume(()); + assert_eq!(A.load(Ordering::SeqCst), n + 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/control-flow.rs b/gcc/testsuite/rust/rustc/ui/generator/control-flow.rs new file mode 100644 index 000000000000..063c8b011bcd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/control-flow.rs @@ -0,0 +1,54 @@ +// run-pass + +// revisions: default nomiropt +//[nomiropt]compile-flags: -Z mir-opt-level=0 + +#![feature(generators, generator_trait)] + +use std::marker::Unpin; +use std::ops::{GeneratorState, Generator}; +use std::pin::Pin; + +fn finish(mut amt: usize, mut t: T) -> T::Return + where T: Generator<(), Yield = ()> + Unpin, +{ + loop { + match Pin::new(&mut t).resume(()) { + GeneratorState::Yielded(()) => amt = amt.checked_sub(1).unwrap(), + GeneratorState::Complete(ret) => { + assert_eq!(amt, 0); + return ret + } + } + } + +} + +fn main() { + finish(1, || yield); + finish(8, || { + for _ in 0..8 { + yield; + } + }); + finish(1, || { + if true { + yield; + } else { + } + }); + finish(1, || { + if false { + } else { + yield; + } + }); + finish(2, || { + if { yield; false } { + yield; + panic!() + } + yield + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/discriminant.rs b/gcc/testsuite/rust/rustc/ui/generator/discriminant.rs new file mode 100644 index 000000000000..b43c7108726d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/discriminant.rs @@ -0,0 +1,138 @@ +//! Tests that generator discriminant sizes and ranges are chosen optimally and that they are +//! reflected in the output of `mem::discriminant`. + +// run-pass + +#![feature(generators, generator_trait, core_intrinsics, discriminant_kind)] + +use std::intrinsics::discriminant_value; +use std::marker::{Unpin, DiscriminantKind}; +use std::mem::size_of_val; +use std::{cmp, ops::*}; + +macro_rules! yield25 { + ($e:expr) => { + yield $e; + yield $e; + yield $e; + yield $e; + yield $e; + + yield $e; + yield $e; + yield $e; + yield $e; + yield $e; + + yield $e; + yield $e; + yield $e; + yield $e; + yield $e; + + yield $e; + yield $e; + yield $e; + yield $e; + yield $e; + + yield $e; + yield $e; + yield $e; + yield $e; + yield $e; + }; +} + +/// Yields 250 times. +macro_rules! yield250 { + () => { + yield250!(()) + }; + + ($e:expr) => { + yield25!($e); + yield25!($e); + yield25!($e); + yield25!($e); + yield25!($e); + + yield25!($e); + yield25!($e); + yield25!($e); + yield25!($e); + yield25!($e); + }; +} + +fn cycle( + gen: impl Generator<()> + Unpin + DiscriminantKind, + expected_max_discr: u32 +) { + let mut gen = Box::pin(gen); + let mut max_discr = 0; + loop { + max_discr = cmp::max(max_discr, discriminant_value(gen.as_mut().get_mut())); + match gen.as_mut().resume(()) { + GeneratorState::Yielded(_) => {} + GeneratorState::Complete(_) => { + assert_eq!(max_discr, expected_max_discr); + return; + } + } + } +} + +fn main() { + // Has only one invalid discr. value. + let gen_u8_tiny_niche = || { + || { + // 3 reserved variants + + yield250!(); // 253 variants + + yield; // 254 + yield; // 255 + } + }; + + // Uses all values in the u8 discriminant. + let gen_u8_full = || { + || { + // 3 reserved variants + + yield250!(); // 253 variants + + yield; // 254 + yield; // 255 + yield; // 256 + } + }; + + // Barely needs a u16 discriminant. + let gen_u16 = || { + || { + // 3 reserved variants + + yield250!(); // 253 variants + + yield; // 254 + yield; // 255 + yield; // 256 + yield; // 257 + } + }; + + assert_eq!(size_of_val(&gen_u8_tiny_niche()), 1); + assert_eq!(size_of_val(&Some(gen_u8_tiny_niche())), 1); // uses niche + assert_eq!(size_of_val(&Some(Some(gen_u8_tiny_niche()))), 2); // cannot use niche anymore + assert_eq!(size_of_val(&gen_u8_full()), 1); + assert_eq!(size_of_val(&Some(gen_u8_full())), 2); // cannot use niche + assert_eq!(size_of_val(&gen_u16()), 2); + assert_eq!(size_of_val(&Some(gen_u16())), 2); // uses niche + + cycle(gen_u8_tiny_niche(), 254); + cycle(gen_u8_full(), 255); + cycle(gen_u16(), 256); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/drop-and-replace.rs b/gcc/testsuite/rust/rustc/ui/generator/drop-and-replace.rs new file mode 100644 index 000000000000..571a80b05bda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/drop-and-replace.rs @@ -0,0 +1,46 @@ +// run-pass +// Regression test for incorrect DropAndReplace behavior introduced in #60840 +// and fixed in #61373. When combined with the optimization implemented in +// #60187, this produced incorrect code for generators when a saved local was +// re-assigned. + +#![feature(generators, generator_trait)] + +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; + +#[derive(Debug, PartialEq)] +struct Foo(i32); + +impl Drop for Foo { + fn drop(&mut self) { } +} + +fn main() { + let mut a = || { + let mut x = Foo(4); + yield; + assert_eq!(x.0, 4); + + // At one point this tricked our dataflow analysis into thinking `x` was + // StorageDead after the assignment. + x = Foo(5); + assert_eq!(x.0, 5); + + { + let y = Foo(6); + yield; + assert_eq!(y.0, 6); + } + + assert_eq!(x.0, 5); + }; + + loop { + match Pin::new(&mut a).resume(()) { + GeneratorState::Complete(()) => break, + _ => (), + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/drop-env.rs b/gcc/testsuite/rust/rustc/ui/generator/drop-env.rs new file mode 100644 index 000000000000..a6aacc008561 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/drop-env.rs @@ -0,0 +1,67 @@ +// run-pass + +// revisions: default nomiropt +//[nomiropt]compile-flags: -Z mir-opt-level=0 + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::pin::Pin; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static A: AtomicUsize = AtomicUsize::new(0); + +struct B; + +impl Drop for B { + fn drop(&mut self) { + A.fetch_add(1, Ordering::SeqCst); + } +} + +fn main() { + t1(); + t2(); + t3(); +} + +fn t1() { + let b = B; + let mut foo = || { + yield; + drop(b); + }; + + let n = A.load(Ordering::SeqCst); + drop(Pin::new(&mut foo).resume(())); + assert_eq!(A.load(Ordering::SeqCst), n); + drop(foo); + assert_eq!(A.load(Ordering::SeqCst), n + 1); +} + +fn t2() { + let b = B; + let mut foo = || { + yield b; + }; + + let n = A.load(Ordering::SeqCst); + drop(Pin::new(&mut foo).resume(())); + assert_eq!(A.load(Ordering::SeqCst), n + 1); + drop(foo); + assert_eq!(A.load(Ordering::SeqCst), n + 1); +} + +fn t3() { + let b = B; + let foo = || { + yield; + drop(b); + }; + + let n = A.load(Ordering::SeqCst); + assert_eq!(A.load(Ordering::SeqCst), n); + drop(foo); + assert_eq!(A.load(Ordering::SeqCst), n + 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/dropck-resume.rs b/gcc/testsuite/rust/rustc/ui/generator/dropck-resume.rs new file mode 100644 index 000000000000..6302cf78a979 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/dropck-resume.rs @@ -0,0 +1,34 @@ +#![feature(generators, generator_trait)] + +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; + +struct SetToNone<'a: 'b, 'b>(&'b mut Option<&'a i32>); + +impl<'a, 'b> Drop for SetToNone<'a, 'b> { + fn drop(&mut self) { + *self.0 = None; + } +} + +fn drop_using_generator() -> i32 { + let mut y = Some(&0); + let z = &mut y; + let r; + { + let mut g = move |r| { + let _s = SetToNone(r); + yield; + }; + let mut g = Pin::new(&mut g); + g.as_mut().resume(z); + r = y.as_ref().unwrap(); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + } + **r +} + +fn main() { + println!("{}", drop_using_generator()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/dropck.rs b/gcc/testsuite/rust/rustc/ui/generator/dropck.rs new file mode 100644 index 000000000000..c76ebe0d9702 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/dropck.rs @@ -0,0 +1,21 @@ +#![feature(generators, generator_trait, box_leak)] + +use std::cell::RefCell; +use std::ops::Generator; +use std::pin::Pin; + +fn main() { + let (mut gen, cell); + cell = Box::new(RefCell::new(0)); + let ref_ = Box::leak(Box::new(Some(cell.borrow_mut()))); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + // the upvar is the non-dropck `&mut Option>`. + gen = || { + // but the generator can use it to drop a `Ref<'a, i32>`. + let _d = ref_.take(); // { dg-error ".E0597." "" { target *-*-* } } + yield; + }; + Pin::new(&mut gen).resume(()); + // drops the RefCell and then the Ref, leading to use-after-free +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/generator-region-requirements.rs b/gcc/testsuite/rust/rustc/ui/generator/generator-region-requirements.rs new file mode 100644 index 000000000000..4e693457cfe4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/generator-region-requirements.rs @@ -0,0 +1,20 @@ +#![feature(generators, generator_trait)] +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; + +fn dangle(x: &mut i32) -> &'static mut i32 { + let mut g = || { + yield; + x + }; + loop { + match Pin::new(&mut g).resume(()) { + GeneratorState::Complete(c) => return c, +// { dg-error ".E0621." "" { target *-*-* } .-1 } + GeneratorState::Yielded(_) => (), + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/generator-resume-after-panic.rs b/gcc/testsuite/rust/rustc/ui/generator/generator-resume-after-panic.rs new file mode 100644 index 000000000000..f0037b1e4926 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/generator-resume-after-panic.rs @@ -0,0 +1,25 @@ +// run-fail +// error-pattern:generator resumed after panicking +// ignore-emscripten no processes + +// Test that we get the correct message for resuming a panicked generator. + +#![feature(generators, generator_trait)] + +use std::{ + ops::Generator, + pin::Pin, + panic, +}; + +fn main() { + let mut g = || { + panic!(); + yield; + }; + panic::catch_unwind(panic::AssertUnwindSafe(|| { + let x = Pin::new(&mut g).resume(()); + })); + Pin::new(&mut g).resume(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/generator-with-nll.rs b/gcc/testsuite/rust/rustc/ui/generator/generator-with-nll.rs new file mode 100644 index 000000000000..f903288eb7cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/generator-with-nll.rs @@ -0,0 +1,13 @@ +#![feature(generators)] + +fn main() { + || { + // The reference in `_a` is a Legal with NLL since it ends before the yield + let _a = &mut true; + let b = &mut true; +// { dg-error ".E0626." "" { target *-*-* } .-1 } + yield (); + println!("{}", b); + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/generator-yielding-or-returning-itself.rs b/gcc/testsuite/rust/rustc/ui/generator/generator-yielding-or-returning-itself.rs new file mode 100644 index 000000000000..e562d3681820 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/generator-yielding-or-returning-itself.rs @@ -0,0 +1,36 @@ +#![feature(generator_trait)] +#![feature(generators)] + +// Test that we cannot create a generator that returns a value of its +// own type. + +use std::ops::Generator; + +pub fn want_cyclic_generator_return(_: T) + where T: Generator +{ +} + +fn supply_cyclic_generator_return() { + want_cyclic_generator_return(|| { +// { dg-error ".E0271." "" { target *-*-* } .-1 } + if false { yield None.unwrap(); } + None.unwrap() + }) +} + +pub fn want_cyclic_generator_yield(_: T) + where T: Generator +{ +} + +fn supply_cyclic_generator_yield() { + want_cyclic_generator_yield(|| { +// { dg-error ".E0271." "" { target *-*-* } .-1 } + if false { yield None.unwrap(); } + None.unwrap() + }) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-44197.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-44197.rs new file mode 100644 index 000000000000..cf84ecf2c867 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-44197.rs @@ -0,0 +1,37 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; + +fn foo(_: &str) -> String { + String::new() +} + +fn bar(baz: String) -> impl Generator<(), Yield = String, Return = ()> { + move || { + yield foo(&baz); + } +} + +fn foo2(_: &str) -> Result { + Err(()) +} + +fn bar2(baz: String) -> impl Generator<(), Yield = String, Return = ()> { + move || { + if let Ok(quux) = foo2(&baz) { + yield quux; + } + } +} + +fn main() { + assert_eq!( + Pin::new(&mut bar(String::new())).resume(()), + GeneratorState::Yielded(String::new()) + ); + assert_eq!(Pin::new(&mut bar2(String::new())).resume(()), GeneratorState::Complete(())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-48048.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-48048.rs new file mode 100644 index 000000000000..643e8d2e713f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-48048.rs @@ -0,0 +1,14 @@ +#![feature(generators)] + +fn main() { + let x = (|_| {},); + + || { + let x = x; + + x.0({ // { dg-error ".E0626." "" { target *-*-* } } + yield; + }); + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-52398.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-52398.rs new file mode 100644 index 000000000000..7708238b9631 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-52398.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(unused_variables)] + +#![feature(generators)] + +use std::cell::RefCell; + +struct A; + +impl A { + fn test(&self, a: ()) {} +} + +fn main() { + // Test that the MIR local with type &A created for the auto-borrow adjustment + // is caught by typeck + move || { // { dg-warning "" "" { target *-*-* } } + A.test(yield); + }; + + // Test that the std::cell::Ref temporary returned from the `borrow` call + // is caught by typeck + let y = RefCell::new(true); + static move || { // { dg-warning "" "" { target *-*-* } } + yield *y.borrow(); + return "Done"; + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-53548-1.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-53548-1.rs new file mode 100644 index 000000000000..8e6d109c57f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-53548-1.rs @@ -0,0 +1,21 @@ +// A variant of #53548 that does not actually require generators, +// but which encountered the same ICE/error. See `issue-53548.rs` +// for details. +// +// check-pass + +use std::cell::RefCell; +use std::rc::Rc; + +trait Trait: 'static {} + +struct Store { + inner: Rc>>, +} + +fn main() { + let store = Store:: fn(&(dyn Trait + 'a))>> { + inner: Default::default(), + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-53548.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-53548.rs new file mode 100644 index 000000000000..e52e8ab8ab7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-53548.rs @@ -0,0 +1,39 @@ +// Regression test for #53548. The `Box` type below is +// expanded to `Box`, but the generator "witness" +// that results is `for<'r> { Box }`. The WF code was +// encountering an ICE (when debug-assertions were enabled) and an +// unexpected compilation error (without debug-asserions) when trying +// to process this `'r` region bound. In particular, to be WF, the +// region bound must meet the requirements of the trait, and hence we +// got `for<'r> { 'r: 'static }`. This would ICE because the `Binder` +// constructor we were using was assering that no higher-ranked +// regions were involved (because the WF code is supposed to skip +// those). The error (if debug-asserions were disabled) came because +// we obviously cannot prove that `'r: 'static` for any region `'r`. +// Pursuant with our "lazy WF" strategy for higher-ranked regions, the +// fix is not to require that `for<'r> { 'r: 'static }` holds (this is +// also analogous to what we would do for higher-ranked regions +// appearing within the trait in other positions). +// +// check-pass + +#![feature(generators)] + +use std::cell::RefCell; +use std::rc::Rc; + +trait Trait: 'static {} + +struct Store { + inner: Rc>>, +} + +fn main() { + Box::new(static move || { + let store = Store::> { + inner: Default::default(), + }; + yield (); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-57084.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-57084.rs new file mode 100644 index 000000000000..f198e34f96ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-57084.rs @@ -0,0 +1,29 @@ +// This issue reproduces an ICE on compile (E.g. fails on 2018-12-19 nightly). +// "cannot relate bound region: ReLateBound(DebruijnIndex(1), BrAnon(1)) <= '_#1r" +// run-pass +// edition:2018 +#![feature(generators,generator_trait)] +use std::ops::Generator; + +fn with(f: F) -> impl Generator +where F: Fn() -> () +{ + move || { + loop { + match f() { + _ => yield, + } + } + } +} + +fn main() { + let data = &vec![1]; + || { // { dg-warning "" "" { target *-*-* } } + let _to_pin = with(move || println!("{:p}", data)); + loop { + yield + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-58888.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-58888.rs new file mode 100644 index 000000000000..8df747843151 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-58888.rs @@ -0,0 +1,29 @@ +// run-pass +// compile-flags: -g +// ignore-asmjs wasm2js does not support source maps yet + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +struct Database; + +impl Database { + fn get_connection(&self) -> impl Iterator { + Some(()).into_iter() + } + + fn check_connection(&self) -> impl Generator + '_ { + move || { + let iter = self.get_connection(); + for i in iter { + yield i + } + } + } +} + +fn main() { + Database.check_connection(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-61442-stmt-expr-with-drop.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-61442-stmt-expr-with-drop.rs new file mode 100644 index 000000000000..21e22404c78f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-61442-stmt-expr-with-drop.rs @@ -0,0 +1,33 @@ +// Test that we don't consider temporaries for statement expressions as live +// across yields + +// check-pass +// edition:2018 + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +async fn drop_and_await() { + async {}; + async {}.await; +} + +fn drop_and_yield() { + let x = || { + String::new(); + yield; + }; + Box::pin(x).as_mut().resume(()); + let y = static || { + String::new(); + yield; + }; + Box::pin(y).as_mut().resume(()); +} + +fn main() { + drop_and_await(); + drop_and_yield(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-62506-two_awaits.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-62506-two_awaits.rs new file mode 100644 index 000000000000..edb501ab5deb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-62506-two_awaits.rs @@ -0,0 +1,18 @@ +// Output = String caused an ICE whereas Output = &'static str compiled successfully. +// Broken MIR: generator contains type std::string::String in MIR, +// but typeck only knows about {::Future, ()} +// check-pass +// edition:2018 + +use std::future::Future; + +pub trait T { + type Future: Future; + fn bar() -> Self::Future; +} +pub async fn foo() where S: T { + S::bar().await; + S::bar().await; +} +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-64620-yield-array-element.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-64620-yield-array-element.rs new file mode 100644 index 000000000000..d383f5f82c84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-64620-yield-array-element.rs @@ -0,0 +1,10 @@ +// Regression test for #64620 + +#![feature(generators)] + +pub fn crash(arr: [usize; 1]) { + yield arr[0]; // { dg-error ".E0627." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-68112.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-68112.rs new file mode 100644 index 000000000000..bf83e7f5cb83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-68112.rs @@ -0,0 +1,57 @@ +#![feature(generators, generator_trait)] + +use std::{ + cell::RefCell, + sync::Arc, + pin::Pin, + ops::{Generator, GeneratorState}, +}; + +pub struct Ready(Option); +impl Generator<()> for Ready { + type Return = T; + type Yield = (); + fn resume(mut self: Pin<&mut Self>, _args: ()) -> GeneratorState<(), T> { + GeneratorState::Complete(self.0.take().unwrap()) + } +} +pub fn make_gen1(t: T) -> Ready { + Ready(Some(t)) +} + +fn require_send(_: impl Send) {} + +fn make_non_send_generator() -> impl Generator>> { + make_gen1(Arc::new(RefCell::new(0))) +} + +fn test1() { + let send_gen = || { + let _non_send_gen = make_non_send_generator(); + yield; + }; + require_send(send_gen); +// { dg-error "" "" { target *-*-* } .-1 } +} + +pub fn make_gen2(t: T) -> impl Generator { + || { + yield; + t + } +} +fn make_non_send_generator2() -> impl Generator>> { + make_gen2(Arc::new(RefCell::new(0))) +} + +fn test2() { + let send_gen = || { + let _non_send_gen = make_non_send_generator2(); + yield; + }; + require_send(send_gen); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-69017.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-69017.rs new file mode 100644 index 000000000000..c7be8d8410be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-69017.rs @@ -0,0 +1,19 @@ +// This issue reproduces an ICE on compile +// Fails on 2020-02-08 nightly +// regressed commit: https://github.com/rust-lang/rust/commit/f8fd4624474a68bd26694eff3536b9f3a127b2d3 +// +// check-pass + +#![feature(generator_trait)] +#![feature(generators)] + +use std::ops::Generator; + +fn gen() -> impl Generator { + |_: usize| { + println!("-> {}", yield); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/issue-69039.rs b/gcc/testsuite/rust/rustc/ui/generator/issue-69039.rs new file mode 100644 index 000000000000..a5aa0084e185 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/issue-69039.rs @@ -0,0 +1,35 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::ops::{Generator, GeneratorState}; + +fn mkstr(my_name: String, my_mood: String) -> String { + format!("{} is {}", my_name.trim(), my_mood.trim()) +} + +fn my_scenario() -> impl Generator { + |_arg: String| { + let my_name = yield "What is your name?"; + let my_mood = yield "How are you feeling?"; + mkstr(my_name, my_mood) + } +} + +fn main() { + let mut my_session = Box::pin(my_scenario()); + + assert_eq!( + my_session.as_mut().resume("_arg".to_string()), + GeneratorState::Yielded("What is your name?") + ); + assert_eq!( + my_session.as_mut().resume("Your Name".to_string()), + GeneratorState::Yielded("How are you feeling?") + ); + assert_eq!( + my_session.as_mut().resume("Sensory Organs".to_string()), + GeneratorState::Complete("Your Name is Sensory Organs".to_string()) + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/iterator-count.rs b/gcc/testsuite/rust/rustc/ui/generator/iterator-count.rs new file mode 100644 index 000000000000..be5301e9bb29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/iterator-count.rs @@ -0,0 +1,45 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::marker::Unpin; +use std::ops::{GeneratorState, Generator}; +use std::pin::Pin; + +struct W(T); + +// This impl isn't safe in general, but the generator used in this test is movable +// so it won't cause problems. +impl + Unpin> Iterator for W { + type Item = T::Yield; + + fn next(&mut self) -> Option { + match Pin::new(&mut self.0).resume(()) { + GeneratorState::Complete(..) => None, + GeneratorState::Yielded(v) => Some(v), + } + } +} + +fn test() -> impl Generator<(), Return=(), Yield=u8> + Unpin { + || { + for i in 1..6 { + yield i + } + } +} + +fn main() { + let end = 11; + + let closure_test = |start| { + move || { + for i in start..end { + yield i + } + } + }; + + assert!(W(test()).chain(W(closure_test(6))).eq(1..11)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/live-upvar-across-yield.rs b/gcc/testsuite/rust/rustc/ui/generator/live-upvar-across-yield.rs new file mode 100644 index 000000000000..eae9eb478180 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/live-upvar-across-yield.rs @@ -0,0 +1,15 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::pin::Pin; + +fn main() { + let b = |_| 3; + let mut a = || { + b(yield); + }; + Pin::new(&mut a).resume(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/match-bindings.rs b/gcc/testsuite/rust/rustc/ui/generator/match-bindings.rs new file mode 100644 index 000000000000..91bd2ccfe28f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/match-bindings.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] + +#![feature(generators)] + +enum Enum { + A(String), + B +} + +fn main() { + || { // { dg-warning "" "" { target *-*-* } } + loop { + if let true = true { + match Enum::A(String::new()) { + Enum::A(_var) => {} + Enum::B => {} + } + } + yield; + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/nested_generators.rs b/gcc/testsuite/rust/rustc/ui/generator/nested_generators.rs new file mode 100644 index 000000000000..f39171e93786 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/nested_generators.rs @@ -0,0 +1,22 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; + +fn main() { + let _generator = || { + let mut sub_generator = || { + yield 2; + }; + + match Pin::new(&mut sub_generator).resume(()) { + GeneratorState::Yielded(x) => { + yield x; + } + _ => panic!(), + }; + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/niche-in-generator.rs b/gcc/testsuite/rust/rustc/ui/generator/niche-in-generator.rs new file mode 100644 index 000000000000..d751bcc3757a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/niche-in-generator.rs @@ -0,0 +1,20 @@ +// Test that niche finding works with captured generator upvars. + +// run-pass + +#![feature(generators)] + +use std::mem::size_of_val; + +fn take(_: T) {} + +fn main() { + let x = false; + let gen1 = || { + yield; + take(x); + }; + + assert_eq!(size_of_val(&gen1), size_of_val(&Some(gen1))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/non-static-is-unpin.rs b/gcc/testsuite/rust/rustc/ui/generator/non-static-is-unpin.rs new file mode 100644 index 000000000000..393a177b1f1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/non-static-is-unpin.rs @@ -0,0 +1,19 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::marker::{PhantomPinned, Unpin}; + +fn assert_unpin(_: G) { +} + +fn main() { + // Even though this generator holds a `PhantomPinned` in its environment, it + // remains `Unpin`. + assert_unpin(|| { + let pinned = PhantomPinned; + yield; + drop(pinned); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/not-send-sync.rs b/gcc/testsuite/rust/rustc/ui/generator/not-send-sync.rs new file mode 100644 index 000000000000..9107909924ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/not-send-sync.rs @@ -0,0 +1,22 @@ +#![feature(generators)] + +use std::cell::Cell; + +fn main() { + fn assert_sync(_: T) {} + fn assert_send(_: T) {} + + assert_sync(|| { +// { dg-error "" "" { target *-*-* } .-1 } + let a = Cell::new(2); + yield; + }); + + let a = Cell::new(2); + assert_send(|| { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + drop(&a); + yield; + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/overlap-locals.rs b/gcc/testsuite/rust/rustc/ui/generator/overlap-locals.rs new file mode 100644 index 000000000000..78b775f36d6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/overlap-locals.rs @@ -0,0 +1,30 @@ +// run-pass + +#![feature(generators)] + +fn main() { + let a = || { + { + let w: i32 = 4; + yield; + println!("{:?}", w); + } + { + let x: i32 = 5; + yield; + println!("{:?}", x); + } + { + let y: i32 = 6; + yield; + println!("{:?}", y); + } + { + let z: i32 = 7; + yield; + println!("{:?}", z); + } + }; + assert_eq!(8, std::mem::size_of_val(&a)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/panic-drops-resume.rs b/gcc/testsuite/rust/rustc/ui/generator/panic-drops-resume.rs new file mode 100644 index 000000000000..e520f9664320 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/panic-drops-resume.rs @@ -0,0 +1,38 @@ +//! Tests that panics inside a generator will correctly drop the initial resume argument. + +// run-pass +// ignore-wasm no unwind support +// ignore-emscripten no unwind support + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::panic::{catch_unwind, AssertUnwindSafe}; +use std::pin::Pin; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static DROP: AtomicUsize = AtomicUsize::new(0); + +struct Dropper {} + +impl Drop for Dropper { + fn drop(&mut self) { + DROP.fetch_add(1, Ordering::SeqCst); + } +} + +fn main() { + let mut gen = |_arg| { + if true { + panic!(); + } + yield (); + }; + let mut gen = Pin::new(&mut gen); + + assert_eq!(DROP.load(Ordering::Acquire), 0); + let res = catch_unwind(AssertUnwindSafe(|| gen.as_mut().resume(Dropper {}))); + assert!(res.is_err()); + assert_eq!(DROP.load(Ordering::Acquire), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/panic-drops.rs b/gcc/testsuite/rust/rustc/ui/generator/panic-drops.rs new file mode 100644 index 000000000000..44687d49bc54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/panic-drops.rs @@ -0,0 +1,58 @@ +// run-pass + +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::panic; +use std::pin::Pin; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static A: AtomicUsize = AtomicUsize::new(0); + +struct B; + +impl Drop for B { + fn drop(&mut self) { + A.fetch_add(1, Ordering::SeqCst); + } +} + +fn bool_true() -> bool { + true +} + +fn main() { + let b = B; + let mut foo = || { + if bool_true() { + panic!(); + } + drop(b); + yield; + }; + + assert_eq!(A.load(Ordering::SeqCst), 0); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + Pin::new(&mut foo).resume(()) + })); + assert!(res.is_err()); + assert_eq!(A.load(Ordering::SeqCst), 1); + + let mut foo = || { + if bool_true() { + panic!(); + } + drop(B); + yield; + }; + + assert_eq!(A.load(Ordering::SeqCst), 1); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + Pin::new(&mut foo).resume(()) + })); + assert!(res.is_err()); + assert_eq!(A.load(Ordering::SeqCst), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/panic-safe.rs b/gcc/testsuite/rust/rustc/ui/generator/panic-safe.rs new file mode 100644 index 000000000000..047fc3b1216a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/panic-safe.rs @@ -0,0 +1,31 @@ +// run-pass + +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::pin::Pin; +use std::panic; + +fn main() { + let mut foo = || { + if true { + panic!(); + } + yield; + }; + + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + Pin::new(&mut foo).resume(()) + })); + assert!(res.is_err()); + + for _ in 0..10 { + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { + Pin::new(&mut foo).resume(()) + })); + assert!(res.is_err()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/partial-initialization-across-yield.rs b/gcc/testsuite/rust/rustc/ui/generator/partial-initialization-across-yield.rs new file mode 100644 index 000000000000..abb4b0ff9914 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/partial-initialization-across-yield.rs @@ -0,0 +1,47 @@ +// Test that we don't allow yielding from a generator while a local is partially +// initialized. + +#![feature(generators)] + +struct S { x: i32, y: i32 } +struct T(i32, i32); + +fn test_tuple() { + let _ = || { + let mut t: (i32, i32); + t.0 = 42; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + yield; + t.1 = 88; + let _ = t; + }; +} + +fn test_tuple_struct() { + let _ = || { + let mut t: T; + t.0 = 42; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + yield; + t.1 = 88; + let _ = t; + }; +} + +fn test_struct() { + let _ = || { + let mut t: S; + t.x = 42; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + yield; + t.y = 88; + let _ = t; + }; +} + +fn main() { + test_tuple(); + test_tuple_struct(); + test_struct(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/pattern-borrow.rs b/gcc/testsuite/rust/rustc/ui/generator/pattern-borrow.rs new file mode 100644 index 000000000000..9ad667d71060 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/pattern-borrow.rs @@ -0,0 +1,18 @@ +#![feature(generators)] + +enum Test { A(i32), B, } + +fn main() { } + +fn fun(test: Test) { + move || { + if let Test::A(ref _a) = test { // { dg-error ".E0626." "" { target *-*-* } } + yield (); + _a.use_ref(); + } + }; +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/generator/pin-box-generator.rs b/gcc/testsuite/rust/rustc/ui/generator/pin-box-generator.rs new file mode 100644 index 000000000000..0d8d2c346865 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/pin-box-generator.rs @@ -0,0 +1,14 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +fn assert_generator(_: G) { +} + +fn main() { + assert_generator(static || yield); + assert_generator(Box::pin(static || yield)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/print/generator-print-verbose-1.rs b/gcc/testsuite/rust/rustc/ui/generator/print/generator-print-verbose-1.rs new file mode 100644 index 000000000000..efd508044c05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/print/generator-print-verbose-1.rs @@ -0,0 +1,61 @@ +// compile-flags: -Zverbose + +// Same as: src/test/ui/generator/issue-68112.stderr + +#![feature(generators, generator_trait)] + +use std::{ + cell::RefCell, + sync::Arc, + pin::Pin, + ops::{Generator, GeneratorState}, +}; + +pub struct Ready(Option); +impl Generator<()> for Ready { + type Return = T; + type Yield = (); + fn resume(mut self: Pin<&mut Self>, _args: ()) -> GeneratorState<(), T> { + GeneratorState::Complete(self.0.take().unwrap()) + } +} +pub fn make_gen1(t: T) -> Ready { + Ready(Some(t)) +} + +fn require_send(_: impl Send) {} + +fn make_non_send_generator() -> impl Generator>> { + make_gen1(Arc::new(RefCell::new(0))) +} + +fn test1() { + let send_gen = || { + let _non_send_gen = make_non_send_generator(); + yield; + }; + require_send(send_gen); +// { dg-error "" "" { target *-*-* } .-1 } +} + +pub fn make_gen2(t: T) -> impl Generator { + || { + yield; + t + } +} +fn make_non_send_generator2() -> impl Generator>> { + make_gen2(Arc::new(RefCell::new(0))) +} + +fn test2() { + let send_gen = || { + let _non_send_gen = make_non_send_generator2(); + yield; + }; + require_send(send_gen); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/print/generator-print-verbose-2.rs b/gcc/testsuite/rust/rustc/ui/generator/print/generator-print-verbose-2.rs new file mode 100644 index 000000000000..1659c6848d84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/print/generator-print-verbose-2.rs @@ -0,0 +1,25 @@ +// compile-flags: -Zverbose + +// Same as test/ui/generator/not-send-sync.rs +#![feature(generators)] + +use std::cell::Cell; + +fn main() { + fn assert_sync(_: T) {} + fn assert_send(_: T) {} + + assert_sync(|| { +// { dg-error "" "" { target *-*-* } .-1 } + let a = Cell::new(2); + yield; + }); + + let a = Cell::new(2); + assert_send(|| { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + drop(&a); + yield; + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/print/generator-print-verbose-3.rs b/gcc/testsuite/rust/rustc/ui/generator/print/generator-print-verbose-3.rs new file mode 100644 index 000000000000..31d17e19494c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/print/generator-print-verbose-3.rs @@ -0,0 +1,13 @@ +// compile-flags: -Zverbose + +#![feature(generators, generator_trait)] + +fn main() { + let x = "Type mismatch test"; + let generator :() = || { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + yield 1i32; + return x + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/reborrow-mut-upvar.rs b/gcc/testsuite/rust/rustc/ui/generator/reborrow-mut-upvar.rs new file mode 100644 index 000000000000..e26a715160c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/reborrow-mut-upvar.rs @@ -0,0 +1,17 @@ +// run-pass + +#![feature(generators)] + +fn _run(bar: &mut i32) { + || { // { dg-warning "" "" { target *-*-* } } + { + let _baz = &*bar; + yield; + } + + *bar = 2; + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/ref-escapes-but-not-over-yield.rs b/gcc/testsuite/rust/rustc/ui/generator/ref-escapes-but-not-over-yield.rs new file mode 100644 index 000000000000..a1aeaee66cec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/ref-escapes-but-not-over-yield.rs @@ -0,0 +1,17 @@ +#![feature(generators)] + +fn foo(x: &i32) { + // In this case, a reference to `b` escapes the generator, but not + // because of a yield. We see that there is no yield in the scope of + // `b` and give the more generic error message. + let mut a = &3; + let mut b = move || { + yield(); + let b = 5; + a = &b; +// { dg-error ".E0521." "" { target *-*-* } .-1 } + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/generator/resume-after-return.rs b/gcc/testsuite/rust/rustc/ui/generator/resume-after-return.rs new file mode 100644 index 000000000000..0ec3ddc62a51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/resume-after-return.rs @@ -0,0 +1,29 @@ +// run-pass + +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(generators, generator_trait)] + +use std::ops::{GeneratorState, Generator}; +use std::pin::Pin; +use std::panic; + +fn main() { + let mut foo = || { + if true { + return + } + yield; + }; + + match Pin::new(&mut foo).resume(()) { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } + + match panic::catch_unwind(move || Pin::new(&mut foo).resume(())) { + Ok(_) => panic!("generator successfully resumed"), + Err(_) => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/resume-arg-late-bound.rs b/gcc/testsuite/rust/rustc/ui/generator/resume-arg-late-bound.rs new file mode 100644 index 000000000000..f81b20e0c4df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/resume-arg-late-bound.rs @@ -0,0 +1,19 @@ +//! Tests that we cannot produce a generator that accepts a resume argument +//! with any lifetime and then stores it across a `yield`. + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +fn test(a: impl for<'a> Generator<&'a mut bool>) {} + +fn main() { + let gen = |arg: &mut bool| { + yield (); + *arg = true; + }; + test(gen); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/resume-arg-size.rs b/gcc/testsuite/rust/rustc/ui/generator/resume-arg-size.rs new file mode 100644 index 000000000000..d98ac475c658 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/resume-arg-size.rs @@ -0,0 +1,29 @@ +#![feature(generators)] + +// run-pass + +use std::mem::size_of_val; + +fn main() { + // Generator taking a `Copy`able resume arg. + let gen_copy = |mut x: usize| { + loop { + drop(x); + x = yield; + } + }; + + // Generator taking a non-`Copy` resume arg. + let gen_move = |mut x: Box| { + loop { + drop(x); + x = yield; + } + }; + + // Neither of these generators have the resume arg live across the `yield`, so they should be + // 1 Byte in size (only storing the discriminant) + assert_eq!(size_of_val(&gen_copy), 1); + assert_eq!(size_of_val(&gen_move), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/resume-live-across-yield.rs b/gcc/testsuite/rust/rustc/ui/generator/resume-live-across-yield.rs new file mode 100644 index 000000000000..fdcbb96606ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/resume-live-across-yield.rs @@ -0,0 +1,46 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static DROP: AtomicUsize = AtomicUsize::new(0); + +#[derive(PartialEq, Eq, Debug)] +struct Dropper(String); + +impl Drop for Dropper { + fn drop(&mut self) { + DROP.fetch_add(1, Ordering::SeqCst); + } +} + +fn main() { + let mut g = |mut _d| { + _d = yield; + _d + }; + + let mut g = Pin::new(&mut g); + + assert_eq!( + g.as_mut().resume(Dropper(String::from("Hello world!"))), + GeneratorState::Yielded(()) + ); + assert_eq!(DROP.load(Ordering::Acquire), 0); + match g.as_mut().resume(Dropper(String::from("Number Two"))) { + GeneratorState::Complete(dropper) => { + assert_eq!(DROP.load(Ordering::Acquire), 1); + assert_eq!(dropper.0, "Number Two"); + drop(dropper); + assert_eq!(DROP.load(Ordering::Acquire), 2); + } + _ => unreachable!(), + } + + drop(g); + assert_eq!(DROP.load(Ordering::Acquire), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/retain-resume-ref.rs b/gcc/testsuite/rust/rustc/ui/generator/retain-resume-ref.rs new file mode 100644 index 000000000000..3301730c212c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/retain-resume-ref.rs @@ -0,0 +1,26 @@ +//! This test ensures that a mutable reference cannot be passed as a resume argument twice. + +#![feature(generators, generator_trait)] + +use std::marker::Unpin; +use std::ops::{ + Generator, + GeneratorState::{self, *}, +}; +use std::pin::Pin; + +fn main() { + let mut thing = String::from("hello"); + + let mut gen = |r| { + if false { + yield r; + } + }; + + let mut gen = Pin::new(&mut gen); + gen.as_mut().resume(&mut thing); + gen.as_mut().resume(&mut thing); +// { dg-error ".E0499." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/size-moved-locals.rs b/gcc/testsuite/rust/rustc/ui/generator/size-moved-locals.rs new file mode 100644 index 000000000000..95a05c5b96ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/size-moved-locals.rs @@ -0,0 +1,78 @@ +// run-pass +// Test that we don't duplicate storage for a variable that is moved to another +// binding. This used to happen in the presence of unwind and drop edges (see +// `complex` below.) +// +// The exact sizes here can change (we'd like to know when they do). What we +// don't want to see is the `complex` generator size being upwards of 2048 bytes +// (which would indicate it is reserving space for two copies of Foo.) +// +// See issue #59123 for a full explanation. + +// edition:2018 +// ignore-wasm32 issue #62807 +// ignore-asmjs issue #62807 + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +const FOO_SIZE: usize = 1024; +struct Foo([u8; FOO_SIZE]); + +impl Drop for Foo { + fn drop(&mut self) {} +} + +fn move_before_yield() -> impl Generator { + static || { + let first = Foo([0; FOO_SIZE]); + let _second = first; + yield; + // _second dropped here + } +} + +fn noop() {} + +fn move_before_yield_with_noop() -> impl Generator { + static || { + let first = Foo([0; FOO_SIZE]); + noop(); + let _second = first; + yield; + // _second dropped here + } +} + +// Today we don't have NRVO (we allocate space for both `first` and `second`,) +// but we can overlap `first` with `_third`. +fn overlap_move_points() -> impl Generator { + static || { + let first = Foo([0; FOO_SIZE]); + yield; + let second = first; + yield; + let _third = second; + yield; + } +} + +fn overlap_x_and_y() -> impl Generator { + static || { + let x = Foo([0; FOO_SIZE]); + yield; + drop(x); + let y = Foo([0; FOO_SIZE]); + yield; + drop(y); + } +} + +fn main() { + assert_eq!(1025, std::mem::size_of_val(&move_before_yield())); + assert_eq!(1026, std::mem::size_of_val(&move_before_yield_with_noop())); + assert_eq!(2051, std::mem::size_of_val(&overlap_move_points())); + assert_eq!(1026, std::mem::size_of_val(&overlap_x_and_y())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/sized-yield.rs b/gcc/testsuite/rust/rustc/ui/generator/sized-yield.rs new file mode 100644 index 000000000000..9a29f60d80e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/sized-yield.rs @@ -0,0 +1,15 @@ +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::pin::Pin; + +fn main() { + let s = String::from("foo"); + let mut gen = move || { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + yield s[..]; + }; + Pin::new(&mut gen).resume(()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/smoke-resume-args.rs b/gcc/testsuite/rust/rustc/ui/generator/smoke-resume-args.rs new file mode 100644 index 000000000000..880d58047290 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/smoke-resume-args.rs @@ -0,0 +1,101 @@ +// run-pass + +// revisions: default nomiropt +//[nomiropt]compile-flags: -Z mir-opt-level=0 + +#![feature(generators, generator_trait)] + +use std::fmt::Debug; +use std::marker::Unpin; +use std::ops::{ + Generator, + GeneratorState::{self, *}, +}; +use std::pin::Pin; +use std::sync::atomic::{AtomicUsize, Ordering}; + +fn drain + Unpin, R, Y>( + gen: &mut G, + inout: Vec<(R, GeneratorState)>, +) where + Y: Debug + PartialEq, + G::Return: Debug + PartialEq, +{ + let mut gen = Pin::new(gen); + + for (input, out) in inout { + assert_eq!(gen.as_mut().resume(input), out); + } +} + +static DROPS: AtomicUsize = AtomicUsize::new(0); + +#[derive(Debug, PartialEq)] +struct DropMe; + +impl Drop for DropMe { + fn drop(&mut self) { + DROPS.fetch_add(1, Ordering::SeqCst); + } +} + +fn expect_drops(expected_drops: usize, f: impl FnOnce() -> T) -> T { + DROPS.store(0, Ordering::SeqCst); + + let res = f(); + + let actual_drops = DROPS.load(Ordering::SeqCst); + assert_eq!(actual_drops, expected_drops); + res +} + +fn main() { + drain( + &mut |mut b| { + while b != 0 { + b = yield (b + 1); + } + -1 + }, + vec![(1, Yielded(2)), (-45, Yielded(-44)), (500, Yielded(501)), (0, Complete(-1))], + ); + + expect_drops(2, || drain(&mut |a| yield a, vec![(DropMe, Yielded(DropMe))])); + + expect_drops(6, || { + drain( + &mut |a| yield yield a, + vec![(DropMe, Yielded(DropMe)), (DropMe, Yielded(DropMe)), (DropMe, Complete(DropMe))], + ) + }); + + #[allow(unreachable_code)] + expect_drops(2, || drain(&mut |a| yield return a, vec![(DropMe, Complete(DropMe))])); + + expect_drops(2, || { + drain( + &mut |a: DropMe| { + if false { yield () } else { a } + }, + vec![(DropMe, Complete(DropMe))], + ) + }); + + expect_drops(4, || { + drain( + #[allow(unused_assignments, unused_variables)] + &mut |mut a: DropMe| { + a = yield; + a = yield; + a = yield; + }, + vec![ + (DropMe, Yielded(())), + (DropMe, Yielded(())), + (DropMe, Yielded(())), + (DropMe, Complete(())), + ], + ) + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/smoke.rs b/gcc/testsuite/rust/rustc/ui/generator/smoke.rs new file mode 100644 index 000000000000..de20b42ed362 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/smoke.rs @@ -0,0 +1,178 @@ +// run-pass + +// revisions: default nomiropt +//[nomiropt]compile-flags: -Z mir-opt-level=0 + +// ignore-emscripten no threads support +// compile-flags: --test + +#![feature(generators, generator_trait)] + +use std::ops::{GeneratorState, Generator}; +use std::pin::Pin; +use std::thread; + +#[test] +fn simple() { + let mut foo = || { + if false { + yield; + } + }; + + match Pin::new(&mut foo).resume(()) { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn return_capture() { + let a = String::from("foo"); + let mut foo = || { + if false { + yield; + } + a + }; + + match Pin::new(&mut foo).resume(()) { + GeneratorState::Complete(ref s) if *s == "foo" => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn simple_yield() { + let mut foo = || { + yield; + }; + + match Pin::new(&mut foo).resume(()) { + GeneratorState::Yielded(()) => {} + s => panic!("bad state: {:?}", s), + } + match Pin::new(&mut foo).resume(()) { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn yield_capture() { + let b = String::from("foo"); + let mut foo = || { + yield b; + }; + + match Pin::new(&mut foo).resume(()) { + GeneratorState::Yielded(ref s) if *s == "foo" => {} + s => panic!("bad state: {:?}", s), + } + match Pin::new(&mut foo).resume(()) { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn simple_yield_value() { + let mut foo = || { + yield String::from("bar"); + return String::from("foo") + }; + + match Pin::new(&mut foo).resume(()) { + GeneratorState::Yielded(ref s) if *s == "bar" => {} + s => panic!("bad state: {:?}", s), + } + match Pin::new(&mut foo).resume(()) { + GeneratorState::Complete(ref s) if *s == "foo" => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn return_after_yield() { + let a = String::from("foo"); + let mut foo = || { + yield; + return a + }; + + match Pin::new(&mut foo).resume(()) { + GeneratorState::Yielded(()) => {} + s => panic!("bad state: {:?}", s), + } + match Pin::new(&mut foo).resume(()) { + GeneratorState::Complete(ref s) if *s == "foo" => {} + s => panic!("bad state: {:?}", s), + } +} + +#[test] +fn send_and_sync() { + assert_send_sync(|| { + yield + }); + assert_send_sync(|| { + yield String::from("foo"); + }); + assert_send_sync(|| { + yield; + return String::from("foo"); + }); + let a = 3; + assert_send_sync(|| { + yield a; + return + }); + let a = 3; + assert_send_sync(move || { + yield a; + return + }); + let a = String::from("a"); + assert_send_sync(|| { + yield ; + drop(a); + return + }); + let a = String::from("a"); + assert_send_sync(move || { + yield ; + drop(a); + return + }); + + fn assert_send_sync(_: T) {} +} + +#[test] +fn send_over_threads() { + let mut foo = || { yield }; + thread::spawn(move || { + match Pin::new(&mut foo).resume(()) { + GeneratorState::Yielded(()) => {} + s => panic!("bad state: {:?}", s), + } + match Pin::new(&mut foo).resume(()) { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } + }).join().unwrap(); + + let a = String::from("a"); + let mut foo = || { yield a }; + thread::spawn(move || { + match Pin::new(&mut foo).resume(()) { + GeneratorState::Yielded(ref s) if *s == "a" => {} + s => panic!("bad state: {:?}", s), + } + match Pin::new(&mut foo).resume(()) { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } + }).join().unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/static-generators.rs b/gcc/testsuite/rust/rustc/ui/generator/static-generators.rs new file mode 100644 index 000000000000..9b43e5023178 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/static-generators.rs @@ -0,0 +1,21 @@ +// run-pass + +#![feature(generators, generator_trait)] + +use std::pin::Pin; +use std::ops::{Generator, GeneratorState}; + +fn main() { + let mut generator = static || { + let a = true; + let b = &a; + yield; + assert_eq!(b as *const _, &a as *const _); + }; + // SAFETY: We shadow the original generator variable so have no safe API to + // move it after this point. + let mut generator = unsafe { Pin::new_unchecked(&mut generator) }; + assert_eq!(generator.as_mut().resume(()), GeneratorState::Yielded(())); + assert_eq!(generator.as_mut().resume(()), GeneratorState::Complete(())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/static-mut-reference-across-yield.rs b/gcc/testsuite/rust/rustc/ui/generator/static-mut-reference-across-yield.rs new file mode 100644 index 000000000000..197fbdf8a915 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/static-mut-reference-across-yield.rs @@ -0,0 +1,30 @@ +// build-pass +#![feature(generators)] + +static mut A: [i32; 5] = [1, 2, 3, 4, 5]; + +fn is_send_sync(_: T) {} + +fn main() { + unsafe { + let gen_index = static || { + let u = A[{ + yield; + 1 + }]; + }; + let gen_match = static || match A { + i if { + yield; + true + } => + { + () + } + _ => (), + }; + is_send_sync(gen_index); + is_send_sync(gen_match); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/static-not-unpin.rs b/gcc/testsuite/rust/rustc/ui/generator/static-not-unpin.rs new file mode 100644 index 000000000000..0028df4637b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/static-not-unpin.rs @@ -0,0 +1,16 @@ +#![feature(generators)] + +// normalize-stderr-test "std::pin::Unpin" -> "std::marker::Unpin" + +use std::marker::Unpin; + +fn assert_unpin(_: T) { +} + +fn main() { + let mut generator = static || { + yield; + }; + assert_unpin(generator); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/static-reference-across-yield.rs b/gcc/testsuite/rust/rustc/ui/generator/static-reference-across-yield.rs new file mode 100644 index 000000000000..5f97f96c8a75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/static-reference-across-yield.rs @@ -0,0 +1,17 @@ +// build-pass +#![feature(generators)] + +static A: [i32; 5] = [1, 2, 3, 4, 5]; + +fn main() { + static || { + let u = A[{yield; 1}]; + }; + static || { + match A { + i if { yield; true } => (), + _ => (), + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/too-live-local-in-immovable-gen.rs b/gcc/testsuite/rust/rustc/ui/generator/too-live-local-in-immovable-gen.rs new file mode 100644 index 000000000000..33f5c136a7c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/too-live-local-in-immovable-gen.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(unused_unsafe)] + +#![feature(generators)] + +fn main() { + unsafe { + static move || { // { dg-warning "" "" { target *-*-* } } + // Tests that the generator transformation finds out that `a` is not live + // during the yield expression. Type checking will also compute liveness + // and it should also find out that `a` is not live. + // The compiler will panic if the generator transformation finds that + // `a` is live and type checking finds it dead. + let a = { + yield (); + 4i32 + }; + &a; + }; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/too-many-parameters.rs b/gcc/testsuite/rust/rustc/ui/generator/too-many-parameters.rs new file mode 100644 index 000000000000..2812fe605373 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/too-many-parameters.rs @@ -0,0 +1,9 @@ +#![feature(generators)] + +fn main() { + |(), ()| { +// { dg-error ".E0628." "" { target *-*-* } .-1 } + yield; + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/type-mismatch-error.rs b/gcc/testsuite/rust/rustc/ui/generator/type-mismatch-error.rs new file mode 100644 index 000000000000..a379c08abad9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/type-mismatch-error.rs @@ -0,0 +1,23 @@ +//! Test that we get the expected type mismatch error instead of "closure is expected to take 0 +//! arguments" (which got introduced after implementing resume arguments). + +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +fn f(_: G, _: G::Return) {} + +fn main() { + f( + |a: u8| { + if false { + yield (); + } else { + a +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } + }, + 0u8, + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/type-mismatch-signature-deduction.rs b/gcc/testsuite/rust/rustc/ui/generator/type-mismatch-signature-deduction.rs new file mode 100644 index 000000000000..58a2e6426688 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/type-mismatch-signature-deduction.rs @@ -0,0 +1,18 @@ +#![feature(generators, generator_trait)] + +use std::ops::Generator; + +fn foo() -> impl Generator { // { dg-error ".E0271." "" { target *-*-* } } + || { + if false { + return Ok(6); + } + + yield (); + + 5 // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/xcrate-reachable.rs b/gcc/testsuite/rust/rustc/ui/generator/xcrate-reachable.rs new file mode 100644 index 000000000000..3b41c94c0413 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/xcrate-reachable.rs @@ -0,0 +1,15 @@ +// run-pass + +// aux-build:xcrate-reachable.rs + +#![feature(generator_trait)] + +extern crate xcrate_reachable as foo; + +use std::ops::Generator; +use std::pin::Pin; + +fn main() { + Pin::new(&mut foo::foo()).resume(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/xcrate.rs b/gcc/testsuite/rust/rustc/ui/generator/xcrate.rs new file mode 100644 index 000000000000..dd89938b0750 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/xcrate.rs @@ -0,0 +1,31 @@ +// run-pass + +// aux-build:xcrate.rs + +#![feature(generators, generator_trait)] + +extern crate xcrate; + +use std::ops::{GeneratorState, Generator}; +use std::pin::Pin; + +fn main() { + let mut foo = xcrate::foo(); + + match Pin::new(&mut foo).resume(()) { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } + + let mut foo = xcrate::bar(3); + + match Pin::new(&mut foo).resume(()) { + GeneratorState::Yielded(3) => {} + s => panic!("bad state: {:?}", s), + } + match Pin::new(&mut foo).resume(()) { + GeneratorState::Complete(()) => {} + s => panic!("bad state: {:?}", s), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/yield-in-args-rev.rs b/gcc/testsuite/rust/rustc/ui/generator/yield-in-args-rev.rs new file mode 100644 index 000000000000..adfad357c78c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/yield-in-args-rev.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] + +// Test that a borrow that occurs after a yield in the same +// argument list is not treated as live across the yield by +// type-checking. + +#![feature(generators)] + +fn foo(_a: (), _b: &bool) {} + +fn bar() { + || { // { dg-warning "" "" { target *-*-* } } + let b = true; + foo(yield, &b); + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/generator/yield-in-args.rs b/gcc/testsuite/rust/rustc/ui/generator/yield-in-args.rs new file mode 100644 index 000000000000..fcd413aa2c9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/yield-in-args.rs @@ -0,0 +1,11 @@ +#![feature(generators)] + +fn foo(_b: &bool, _a: ()) {} + +fn main() { + || { + let b = true; + foo(&b, yield); // { dg-error ".E0626." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/yield-in-box.rs b/gcc/testsuite/rust/rustc/ui/generator/yield-in-box.rs new file mode 100644 index 000000000000..91f95a700a22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/yield-in-box.rs @@ -0,0 +1,19 @@ +// run-pass + +// Test that box-statements with yields in them work. + +#![feature(generators, box_syntax)] + +fn main() { + let x = 0i32; + || { // { dg-warning "" "" { target *-*-* } } + let y = 2u32; + { + let _t = box (&x, yield 0, &y); + } + match box (&x, yield 0, &y) { + _t => {} + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/yield-in-const.rs b/gcc/testsuite/rust/rustc/ui/generator/yield-in-const.rs new file mode 100644 index 000000000000..ee8f8462cd5a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/yield-in-const.rs @@ -0,0 +1,7 @@ +#![feature(generators)] + +const A: u8 = { yield 3u8; 3u8}; +// { dg-error ".E0627." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/yield-in-function.rs b/gcc/testsuite/rust/rustc/ui/generator/yield-in-function.rs new file mode 100644 index 000000000000..04462dd456d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/yield-in-function.rs @@ -0,0 +1,5 @@ +#![feature(generators)] + +fn main() { yield; } +// { dg-error ".E0627." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/generator/yield-in-initializer.rs b/gcc/testsuite/rust/rustc/ui/generator/yield-in-initializer.rs new file mode 100644 index 000000000000..f34fa1fbcfd9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/yield-in-initializer.rs @@ -0,0 +1,18 @@ +// run-pass + +#![feature(generators)] + +fn main() { + static || { // { dg-warning "" "" { target *-*-* } } + loop { + // Test that `opt` is not live across the yield, even when borrowed in a loop + // See https://github.com/rust-lang/rust/issues/52792 + let opt = { + yield; + true + }; + &opt; + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/yield-in-static.rs b/gcc/testsuite/rust/rustc/ui/generator/yield-in-static.rs new file mode 100644 index 000000000000..3de50a2a7e22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/yield-in-static.rs @@ -0,0 +1,7 @@ +#![feature(generators)] + +static B: u8 = { yield 3u8; 3u8}; +// { dg-error ".E0627." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/yield-subtype.rs b/gcc/testsuite/rust/rustc/ui/generator/yield-subtype.rs new file mode 100644 index 000000000000..e187bfe77e90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/yield-subtype.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +#![allow(dead_code)] + +#![feature(generators)] + +fn bar<'a>() { + let a: &'static str = "hi"; + let b: &'a str = a; + + || { // { dg-warning "" "" { target *-*-* } } + yield a; + yield b; + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generator/yield-while-iterating.rs b/gcc/testsuite/rust/rustc/ui/generator/yield-while-iterating.rs new file mode 100644 index 000000000000..0af1296f8d02 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/yield-while-iterating.rs @@ -0,0 +1,76 @@ +#![feature(generators, generator_trait)] + +use std::ops::{GeneratorState, Generator}; +use std::cell::Cell; +use std::pin::Pin; + +fn yield_during_iter_owned_data(x: Vec) { + // The generator owns `x`, so we error out when yielding with a + // reference to it. This winds up becoming a rather confusing + // regionck error -- in particular, we would freeze with the + // reference in scope, and it doesn't live long enough. + let _b = move || { + for p in &x { // { dg-error ".E0626." "" { target *-*-* } } + yield(); + } + }; +} + +fn yield_during_iter_borrowed_slice(x: &[i32]) { + let _b = move || { + for p in x { + yield(); + } + }; +} + +fn yield_during_iter_borrowed_slice_2() { + let mut x = vec![22_i32]; + let _b = || { + for p in &x { + yield(); + } + }; + println!("{:?}", x); +} + +fn yield_during_iter_borrowed_slice_3() { + // OK to take a mutable ref to `x` and yield + // up pointers from it: + let mut x = vec![22_i32]; + let mut b = || { + for p in &mut x { + yield p; + } + }; + Pin::new(&mut b).resume(()); +} + +fn yield_during_iter_borrowed_slice_4() { + // ...but not OK to do that while reading + // from `x` too + let mut x = vec![22_i32]; + let mut b = || { + for p in &mut x { + yield p; + } + }; + println!("{}", x[0]); // { dg-error ".E0502." "" { target *-*-* } } + Pin::new(&mut b).resume(()); +} + +fn yield_during_range_iter() { + // Should be OK. + let mut b = || { + let v = vec![1,2,3]; + let len = v.len(); + for i in 0..len { + let x = v[i]; + yield x; + } + }; + Pin::new(&mut b).resume(()); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/generator/yield-while-local-borrowed.rs b/gcc/testsuite/rust/rustc/ui/generator/yield-while-local-borrowed.rs new file mode 100644 index 000000000000..95180df69bdf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/yield-while-local-borrowed.rs @@ -0,0 +1,50 @@ +#![feature(generators, generator_trait)] + +use std::ops::{GeneratorState, Generator}; +use std::cell::Cell; +use std::pin::Pin; + +fn borrow_local_inline() { + // Not OK to yield with a borrow of a temporary. + // + // (This error occurs because the region shows up in the type of + // `b` and gets extended by region inference.) + let mut b = move || { + let a = &mut 3; +// { dg-error ".E0626." "" { target *-*-* } .-1 } + yield(); + println!("{}", a); + }; + Pin::new(&mut b).resume(()); +} + +fn borrow_local_inline_done() { + // No error here -- `a` is not in scope at the point of `yield`. + let mut b = move || { + { + let a = &mut 3; + } + yield(); + }; + Pin::new(&mut b).resume(()); +} + +fn borrow_local() { + // Not OK to yield with a borrow of a temporary. + // + // (This error occurs because the region shows up in the type of + // `b` and gets extended by region inference.) + let mut b = move || { + let a = 3; + { + let b = &a; +// { dg-error ".E0626." "" { target *-*-* } .-1 } + yield(); + println!("{}", b); + } + }; + Pin::new(&mut b).resume(()); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/generator/yield-while-ref-reborrowed.rs b/gcc/testsuite/rust/rustc/ui/generator/yield-while-ref-reborrowed.rs new file mode 100644 index 000000000000..1f829b2ab614 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/yield-while-ref-reborrowed.rs @@ -0,0 +1,41 @@ +#![feature(generators, generator_trait)] + +use std::ops::{GeneratorState, Generator}; +use std::cell::Cell; +use std::pin::Pin; + +fn reborrow_shared_ref(x: &i32) { + // This is OK -- we have a borrow live over the yield, but it's of + // data that outlives the generator. + let mut b = move || { + let a = &*x; + yield(); + println!("{}", a); + }; + Pin::new(&mut b).resume(()); +} + +fn reborrow_mutable_ref(x: &mut i32) { + // This is OK -- we have a borrow live over the yield, but it's of + // data that outlives the generator. + let mut b = move || { + let a = &mut *x; + yield(); + println!("{}", a); + }; + Pin::new(&mut b).resume(()); +} + +fn reborrow_mutable_ref_2(x: &mut i32) { + // ...but not OK to go on using `x`. + let mut b = || { + let a = &mut *x; + yield(); + println!("{}", a); + }; + println!("{}", x); // { dg-error ".E0501." "" { target *-*-* } } + Pin::new(&mut b).resume(()); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/generator/yielding-in-match-guards.rs b/gcc/testsuite/rust/rustc/ui/generator/yielding-in-match-guards.rs new file mode 100644 index 000000000000..f1a634e45e24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generator/yielding-in-match-guards.rs @@ -0,0 +1,44 @@ +// build-pass +// edition:2018 + +// This test is derived from +// https://github.com/rust-lang/rust/issues/72651#issuecomment-668720468 + +// This test demonstrates that, in `async fn g()`, +// indeed a temporary borrow `y` from `x` is live +// while `f().await` is being evaluated. +// Thus, `&'_ u8` should be included in type signature +// of the underlying generator. + +async fn f() -> u8 { 1 } +async fn foo() -> [bool; 10] { [false; 10] } + +pub async fn g(x: u8) { + match x { + y if f().await == y => (), + _ => (), + } +} + +// #78366: check the reference to the binding is recorded even if the binding is not autorefed + +async fn h(x: usize) { + match x { + y if foo().await[y] => (), + _ => (), + } +} + +async fn i(x: u8) { + match x { + y if f().await == y + 1 => (), + _ => (), + } +} + +fn main() { + let _ = g(10); + let _ = h(9); + let _ = i(8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/auxiliary/foo_defn.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/auxiliary/foo_defn.rs new file mode 100644 index 000000000000..d4215b81fc1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/auxiliary/foo_defn.rs @@ -0,0 +1,9 @@ +#![feature(generic_associated_types)] + +use std::{future::Future, pin::Pin}; + +pub trait Foo { + type Bar: AsRef<()>; + fn foo(&self) -> Pin + '_>>; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/collections-project-default.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/collections-project-default.rs new file mode 100644 index 000000000000..552e6dca5538 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/collections-project-default.rs @@ -0,0 +1,73 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] +#![feature(associated_type_defaults)] + +// A Collection trait and collection families. Based on +// http://smallcultfollowing.com/babysteps/blog/2016/11/03/ +// associated-type-constructors-part-2-family-traits/ + +// check that we don't normalize with trait defaults. + +trait Collection { + type Iter<'iter>: Iterator where T: 'iter; + type Family: CollectionFamily; + // Test associated type defaults with parameters + type Sibling: Collection = + <>::Family as CollectionFamily>::Member; + + fn empty() -> Self; + + fn add(&mut self, value: T); + + fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; +} + +trait CollectionFamily { + type Member: Collection; +} + +struct VecFamily; + +impl CollectionFamily for VecFamily { + type Member = Vec; +} + +impl Collection for Vec { + type Iter<'iter> where T: 'iter = std::slice::Iter<'iter, T>; + type Family = VecFamily; + + fn empty() -> Self { + Vec::new() + } + + fn add(&mut self, value: T) { + self.push(value) + } + + fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> { + self.iter() + } +} + +fn floatify_sibling(ints: &C) -> >::Sibling +where + C: Collection, +{ + let mut res = ::Member::::empty(); + for &v in ints.iterate() { + res.add(v as f32); + } + res +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn use_floatify() { + let a = vec![1i32, 2, 3]; + let c = floatify_sibling(&a); + assert_eq!(Some(&1.0), c.iterate().next()); +} + +fn main() { + use_floatify(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/collections.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/collections.rs new file mode 100644 index 000000000000..a229b5387c1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/collections.rs @@ -0,0 +1,72 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] +#![feature(associated_type_defaults)] + +// A Collection trait and collection families. Based on +// http://smallcultfollowing.com/babysteps/blog/2016/11/03/ +// associated-type-constructors-part-2-family-traits/ + +// run-pass + +trait Collection { + type Iter<'iter>: Iterator where T: 'iter; + type Family: CollectionFamily; + // Test associated type defaults with parameters + type Sibling: Collection = + <>::Family as CollectionFamily>::Member; + + fn empty() -> Self; + + fn add(&mut self, value: T); + + fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; +} + +trait CollectionFamily { + type Member: Collection; +} + +struct VecFamily; + +impl CollectionFamily for VecFamily { + type Member = Vec; +} + +impl Collection for Vec { + type Iter<'iter> where T: 'iter = std::slice::Iter<'iter, T>; + type Family = VecFamily; + + fn empty() -> Self { + Vec::new() + } + + fn add(&mut self, value: T) { + self.push(value) + } + + fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> { + self.iter() + } +} + +fn floatify(ints: &C) -> <>::Family as CollectionFamily>::Member +where + C: Collection, +{ + let mut res = ::Member::::empty(); + for &v in ints.iterate() { + res.add(v as f32); + } + res +} + +fn use_floatify() { + let a = vec![1, 2, 3]; + let b = floatify(&a); + assert_eq!(Some(&1.0), b.iterate().next()); +} + +fn main() { + use_floatify(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/construct_with_other_type.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/construct_with_other_type.rs new file mode 100644 index 000000000000..afed0997b0cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/construct_with_other_type.rs @@ -0,0 +1,26 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +// check-pass + +use std::ops::Deref; + +trait Foo { + type Bar<'a, 'b>; +} + +trait Baz { + type Quux<'a>: Foo where Self: 'a; + + // This weird type tests that we can use universal function call syntax to access the Item on + type Baa<'a>: Deref as Foo>::Bar<'a, 'static>> where Self: 'a; +} + +impl Baz for T where T: Foo { + type Quux<'a> where T: 'a = T; + + type Baa<'a> where T: 'a = &'a ::Bar<'a, 'static>; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/cross-crate-bounds.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/cross-crate-bounds.rs new file mode 100644 index 000000000000..b1a4cccf9bab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/cross-crate-bounds.rs @@ -0,0 +1,33 @@ +// regression test for #73816 +// We handled bounds differently when `feature(generic_associated_types)` was enabled + +// edition:2018 +// aux-build:foo_defn.rs + +extern crate foo_defn; + +use foo_defn::Foo; +use std::{future::Future, pin::Pin}; + +pub struct FooImpl; + +impl Foo for FooImpl { + type Bar = (); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + fn foo(&self) -> Pin + '_>> { + panic!() + } +} + +async fn foo() { + bar(&FooImpl).await; +} + +async fn bar(foo: &F) { + foo.foo().await.as_ref(); +} + +fn main() { + // futures::executor::block_on(foo()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/empty_generics.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/empty_generics.rs new file mode 100644 index 000000000000..61840f88092c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/empty_generics.rs @@ -0,0 +1,10 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +trait Foo { + type Bar<,>; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs new file mode 100644 index 000000000000..d76a98f94e59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs @@ -0,0 +1,17 @@ +// rust-lang/rust#60654: Do not ICE on an attempt to use GATs that is +// missing the feature gate. + +struct Foo; + +trait MyTrait { + type Item; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +impl MyTrait for Foo { + type Item = T; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs new file mode 100644 index 000000000000..95125d15cd6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs @@ -0,0 +1,17 @@ +// rust-lang/rust#60654: Do not ICE on an attempt to use GATs that is +// missing the feature gate. + +struct Foo; + +impl Iterator for Foo { + type Item<'b> = &'b Foo; +// { dg-error ".E0195." "" { target *-*-* } .-1 } +// { dg-error ".E0195." "" { target *-*-* } .-2 } + + fn next(&mut self) -> Option { + None + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/gat-incomplete-warning.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/gat-incomplete-warning.rs new file mode 100644 index 000000000000..6f52a42e223a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/gat-incomplete-warning.rs @@ -0,0 +1,7 @@ +// run-pass + +#![feature(generic_associated_types)] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/generic-associated-types-where.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/generic-associated-types-where.rs new file mode 100644 index 000000000000..370aac87d4a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/generic-associated-types-where.rs @@ -0,0 +1,30 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +// Checking the interaction with this other feature +#![feature(associated_type_defaults)] + +use std::fmt::{Display, Debug}; + +trait Foo { + type Assoc where Self: Sized; + type Assoc2 where T: Display; + type Assoc3; + type WithDefault<'a, T: Debug + 'a>: ?Sized = dyn Iterator; + type NoGenerics; +} + +struct Bar; + +impl Foo for Bar { + type Assoc = usize; + type Assoc2 = Vec; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + type Assoc3 where T: Iterator = Vec; +// { dg-error ".E0276." "" { target *-*-* } .-1 } + type WithDefault<'a, T: Debug + 'a> = &'a dyn Iterator; + type NoGenerics = ::std::cell::Cell; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs new file mode 100644 index 000000000000..5162a9cab0ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs @@ -0,0 +1,17 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +use std::ops::Deref; + +trait Iterable { + type Item<'a>; + type Iter<'a>: Iterator> + + Deref>; +// { dg-error ".E0261." "" { target *-*-* } .-1 } + + fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; +// { dg-error ".E0261." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/impl_bounds.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/impl_bounds.rs new file mode 100644 index 000000000000..a73b9892f000 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/impl_bounds.rs @@ -0,0 +1,25 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] +#![feature(associated_type_defaults)] + +trait Foo { + type A<'a> where Self: 'a; + type B<'a, 'b> where 'a: 'b; + type C where Self: Clone; +} + +#[derive(Copy, Clone)] +struct Fooy(T); + +impl Foo for Fooy { + type A<'a> where Self: 'static = (&'a ()); +// { dg-error ".E0310." "" { target *-*-* } .-1 } + type B<'a, 'b> where 'b: 'a = (&'a(), &'b ()); +// { dg-error ".E0478." "" { target *-*-* } .-1 } +// { dg-error ".E0478." "" { target *-*-* } .-2 } + type C where Self: Copy = String; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/impl_bounds_ok.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/impl_bounds_ok.rs new file mode 100644 index 000000000000..22bace86b4af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/impl_bounds_ok.rs @@ -0,0 +1,32 @@ +// check-pass + +#![allow(incomplete_features)] +#![feature(generic_associated_types)] +#![feature(associated_type_defaults)] + +trait Foo { + type A<'a> where Self: 'a; + type B<'a, 'b> where 'a: 'b; + type C where Self: Clone; +} + +#[derive(Clone)] +struct Fooy; + +impl Foo for Fooy { + type A<'a> = (&'a ()); + type B<'a: 'b, 'b> = (&'a(), &'b ()); + type C = String; +} + +#[derive(Clone)] +struct Fooer(T); + +impl Foo for Fooer { + type A<'x> where T: 'x = (&'x ()); + type B<'u, 'v> where 'u: 'v = (&'v &'u ()); + type C where Self: Clone + ToOwned = String; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-47206-where-clause.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-47206-where-clause.rs new file mode 100644 index 000000000000..56d7417137da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-47206-where-clause.rs @@ -0,0 +1,18 @@ +// Check that this program doesn't cause the compiler to error without output. + +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +trait Foo { + type Assoc3; +} + +struct Bar; + +impl Foo for Bar { + type Assoc3 where T: Iterator = Vec; +// { dg-error ".E0276." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs new file mode 100644 index 000000000000..35e2b026f20f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs @@ -0,0 +1,11 @@ +// check-pass + +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +trait Cert { + type PublicKey<'a>: From<&'a [u8]>; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs new file mode 100644 index 000000000000..024f95cd4ba2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs @@ -0,0 +1,15 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +// check-pass + +trait Iterator { + type Item<'a>: 'a; +} + +impl Iterator for () { + type Item<'a> = &'a (); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-67424.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-67424.rs new file mode 100644 index 000000000000..9f1d1b718232 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-67424.rs @@ -0,0 +1,13 @@ +// Fixed by #67160 + +trait Trait1 { + type A; +} + +trait Trait2 { + type Type1: Trait1; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68641-check-gat-bounds.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68641-check-gat-bounds.rs new file mode 100644 index 000000000000..49bbc62c3703 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68641-check-gat-bounds.rs @@ -0,0 +1,33 @@ +// Regression test for #68641 + +#![feature(generic_associated_types)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait UnsafeCopy { + type Item<'a>: Copy; + + fn copy<'a>(item: &Self::Item<'a>) -> Self::Item<'a> { + *item + } +} + +impl UnsafeCopy for T { + type Item<'a> = T; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { + let mut s = String::from("Hello world!"); + + let copy = String::copy(&s); + + // Do we indeed point to the samme memory? + assert!(s.as_ptr() == copy.as_ptr()); + + // Any use of `copy` is certeinly UB after this + drop(s); + + // UB UB UB UB UB!! + println!("{}", copy); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs new file mode 100644 index 000000000000..39bdfc1d207b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68642-broken-llvm-ir.rs @@ -0,0 +1,22 @@ +// Regression test for #68642 + +#![feature(generic_associated_types)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait Fun { + type F<'a>: Fn() -> u32; + + fn callme<'a>(f: Self::F<'a>) -> u32 { + f() + } +} + +impl Fun for T { + type F<'a> = Self; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { + usize>::callme(|| 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68643-broken-mir.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68643-broken-mir.rs new file mode 100644 index 000000000000..4acf9a765e1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68643-broken-mir.rs @@ -0,0 +1,22 @@ +// Regression test for #68643 + +#![feature(generic_associated_types)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait Fun { + type F<'a>: Fn() -> u32; + + fn callme<'a>(f: Self::F<'a>) -> u32 { + f() + } +} + +impl Fun for T { + type F<'a> = Self; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +pub fn main() { + ::callme(|| {}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68644-codegen-selection.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68644-codegen-selection.rs new file mode 100644 index 000000000000..782470ed68c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68644-codegen-selection.rs @@ -0,0 +1,22 @@ +// Regression test for #68644 + +#![feature(generic_associated_types)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait Fun { + type F<'a>: Fn() -> u32; + + fn callme<'a>(f: Self::F<'a>) -> u32 { + f() + } +} + +impl Fun for T { + type F<'a> = Self; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { + ::callme(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs new file mode 100644 index 000000000000..47bbc370d89e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68645-codegen-fulfillment.rs @@ -0,0 +1,22 @@ +// Regression test for #68645 + +#![feature(generic_associated_types)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait Fun { + type F<'a>: Fn() -> u32; + + fn callme<'a>(f: Self::F<'a>) -> u32 { + f() + } +} + +impl Fun for T { + type F<'a> = Self; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { + <&dyn Iterator>::callme(&std::iter::once(1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68653.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68653.rs new file mode 100644 index 000000000000..b1f7fd0f02d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68653.rs @@ -0,0 +1,17 @@ +// A regression test for #68653, which was fixed by #68938. + +// check-pass + +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +trait Fun { + type F<'a: 'a>; +} + +impl Fun for T { + type F<'a> = Self; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68656-unsized-values.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68656-unsized-values.rs new file mode 100644 index 000000000000..8b5d10bef20d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-68656-unsized-values.rs @@ -0,0 +1,23 @@ +// Regression test for #68656 + +#![feature(generic_associated_types)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait UnsafeCopy { + type Item<'a>: std::ops::Deref; + + fn bug<'a>(item: &Self::Item<'a>) -> () { + let x: T = **item; + &x as *const _; + } +} + +impl UnsafeCopy for T { + type Item<'a> = T; +// { dg-error ".E0271." "" { target *-*-* } .-1 } +} + +fn main() { + <&'static str>::bug(&""); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-74816.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-74816.rs new file mode 100644 index 000000000000..3dd8fec1881c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/issue-74816.rs @@ -0,0 +1,24 @@ +#![feature(associated_type_defaults)] +#![feature(generic_associated_types)] +#![allow(incomplete_features)] + +trait Trait1 { + fn foo(); +} + +trait Trait2 { + type Associated: Trait1 = Self; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + +impl Trait2 for () {} + +fn call_foo() { + T::Associated::foo() +} + +fn main() { + call_foo::<()>() +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/iterable.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/iterable.rs new file mode 100644 index 000000000000..3b8dde6b0f59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/iterable.rs @@ -0,0 +1,48 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +// run-pass + +trait Iterable { + type Item<'a> where Self: 'a; + type Iter<'a>: Iterator> where Self: 'a; + + fn iter<'a>(&'a self) -> Self::Iter<'a>; +} + +// Impl for struct type +impl Iterable for Vec { + type Item<'a> where T: 'a = as Iterator>::Item; + type Iter<'a> where T: 'a = std::slice::Iter<'a, T>; + + fn iter<'a>(&'a self) -> Self::Iter<'a> { + self[..].iter() + } +} + +// Impl for a primitive type +impl Iterable for [T] { + type Item<'a> where T: 'a = as Iterator>::Item; + type Iter<'a> where T: 'a = std::slice::Iter<'a, T>; + + fn iter<'a>(&'a self) -> Self::Iter<'a> { + self.iter() + } +} + +fn make_iter<'a, I: Iterable + ?Sized>(it: &'a I) -> I::Iter<'a> { + it.iter() +} + +fn get_first<'a, I: Iterable + ?Sized>(it: &'a I) -> Option> { + it.iter().next() +} + +fn main() { + let v = vec![1, 2, 3]; + assert_eq!(v, make_iter(&v).copied().collect::>()); + assert_eq!(v, make_iter(&*v).copied().collect::>()); + assert_eq!(Some(&1), get_first(&v)); + assert_eq!(Some(&1), get_first(&*v)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/missing-bounds.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/missing-bounds.rs new file mode 100644 index 000000000000..a7a685d95e9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/missing-bounds.rs @@ -0,0 +1,46 @@ +// run-rustfix + +use std::ops::Add; + +struct A(B); + +impl Add for A where B: Add { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + A(self.0 + rhs.0) // { dg-error ".E0308." "" { target *-*-* } } + } +} + +struct C(B); + +impl Add for C { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + Self(self.0 + rhs.0) // { dg-error ".E0308." "" { target *-*-* } } + } +} + +struct D(B); + +impl Add for D { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + Self(self.0 + rhs.0) // { dg-error ".E0369." "" { target *-*-* } } + } +} + +struct E(B); + +impl Add for E where B: Add { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + Self(self.0 + rhs.0) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/parameter_number_and_kind.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/parameter_number_and_kind.rs new file mode 100644 index 000000000000..c4ce37309c3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/parameter_number_and_kind.rs @@ -0,0 +1,21 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] +#![feature(associated_type_defaults)] + +trait Foo { + type A<'a>; + type B<'a, 'b>; + type C; + type D; + type E<'a, T>; + // Test parameters in default values + type FOk = Self::E<'static, T>; + type FErr1 = Self::E<'static, 'static>; +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } + type FErr2 = Self::E<'static, T, u32>; +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/parameter_number_and_kind_impl.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/parameter_number_and_kind_impl.rs new file mode 100644 index 000000000000..8fffe02d7838 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/parameter_number_and_kind_impl.rs @@ -0,0 +1,36 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] +#![feature(associated_type_defaults)] + +// FIXME(#44265) add tests for type-generic and const-genertic associated types. + +trait Foo { + type A<'a>; + type B<'a, 'b>; + type C; +} + +struct Fooy; + +impl Foo for Fooy { + type A = u32; +// { dg-error ".E0195." "" { target *-*-* } .-1 } + type B<'a, T> = Vec; +// { dg-error ".E0049." "" { target *-*-* } .-1 } + type C<'a> = u32; +// { dg-error ".E0195." "" { target *-*-* } .-1 } +} + +struct Fooer; + +impl Foo for Fooer { + type A = u32; +// { dg-error ".E0049." "" { target *-*-* } .-1 } + type B<'a> = u32; +// { dg-error ".E0195." "" { target *-*-* } .-1 } + type C = T; +// { dg-error ".E0049." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/parse/in-trait-impl.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/parse/in-trait-impl.rs new file mode 100644 index 000000000000..5ea21301b8f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/parse/in-trait-impl.rs @@ -0,0 +1,11 @@ +// check-pass +// compile-flags: -Z parse-only + +#![feature(generic_associated_types)] + +impl Baz for T where T: Foo { + type Quux<'a> = ::Bar<'a, 'static>; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/parse/in-trait.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/parse/in-trait.rs new file mode 100644 index 000000000000..0b530b2121a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/parse/in-trait.rs @@ -0,0 +1,25 @@ +// check-pass +// compile-flags: -Z parse-only + +#![feature(generic_associated_types)] + +use std::ops::Deref; +use std::fmt::Debug; + +trait Foo { + type Bar<'a>; + type Bar<'a, 'b>; + type Bar<'a, 'b,>; + type Bar<'a, 'b, T>; + type Bar<'a, 'b, T, U>; + type Bar<'a, 'b, T, U,>; + type Bar<'a, 'b, T: Debug, U,>; + type Bar<'a, 'b, T: Debug, U,>: Debug; + type Bar<'a, 'b, T: Debug, U,>: Deref + Into; + type Bar<'a, 'b, T: Debug, U,> where T: Deref, U: Into; + type Bar<'a, 'b, T: Debug, U,>: Deref + Into + where T: Deref, U: Into; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/pointer_family.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/pointer_family.rs new file mode 100644 index 000000000000..678ee4fada14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/pointer_family.rs @@ -0,0 +1,38 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +// check-pass + +use std::rc::Rc; +use std::sync::Arc; +use std::ops::Deref; + +trait PointerFamily { + type Pointer: Deref; + fn new(value: T) -> Self::Pointer; +} + +struct ArcFamily; + +impl PointerFamily for ArcFamily { + type Pointer = Arc; + fn new(value: T) -> Self::Pointer { + Arc::new(value) + } +} + +struct RcFamily; + +impl PointerFamily for RcFamily { + type Pointer = Rc; + fn new(value: T) -> Self::Pointer { + Rc::new(value) + } +} + +struct Foo { + bar: P::Pointer, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/projection-bound-cycle-generic.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/projection-bound-cycle-generic.rs new file mode 100644 index 000000000000..2fb18c142eb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/projection-bound-cycle-generic.rs @@ -0,0 +1,63 @@ +// Like `projection-bound-cycle.rs` but this avoids using +// `feature(trivial_bounds)`. + +#![feature(generic_associated_types)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait Print { + fn print(); +} + +trait Foo { + type Item: Sized where ::Item: Sized; +} + +struct Number { t: T } + +impl Foo for Number { + // Well-formedness checks require that the following + // goal is true: + // ``` + // if ([T]: Sized) { # if the where clauses hold + // [T]: Sized # then the bound on the associated type hold + // } + // ``` + // which it is :) + type Item where [T]: Sized = [T]; +} + +struct OnlySized where T: Sized { f: T } +impl Print for OnlySized { + fn print() { + println!("{}", std::mem::size_of::()); + } +} + +trait Bar { + type Assoc: Print; +} + +impl Bar for T where T: Foo { + // This is not ok, we need to prove `wf(::Item)`, which requires + // knowing that `::Item: Sized` to satisfy the where clause. We + // can use the bound on `Foo::Item` for this, but that requires + // `wf(::Item)`, which is an invalid cycle. + type Assoc = OnlySized<::Item>; +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} + +fn foo() { + T::print() // oops, in fact `T = OnlySized` which is ill-formed +} + +fn bar() { + // we have `FromEnv(T: Bar)` hence + // `::Assoc` is well-formed and + // `Implemented(::Assoc: Print)` hold + foo::<::Assoc>() +} + +fn main() { + bar::>() +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/projection-bound-cycle.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/projection-bound-cycle.rs new file mode 100644 index 000000000000..de0e3d8d32a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/projection-bound-cycle.rs @@ -0,0 +1,65 @@ +// Test case from Chalk. +// Make sure that we make sure that we don't allow arbitrary bounds to be +// proven when a bound and a where clause of an associated type are the same. + +#![feature(generic_associated_types)] +// { dg-warning "" "" { target *-*-* } .-1 } +#![feature(trivial_bounds)] + +trait Print { + fn print(); +} + +trait Foo { + type Item: Sized where ::Item: Sized; +} + +struct Number { } + +impl Foo for Number { + // Well-formedness checks require that the following + // goal is true: + // ``` + // if (str: Sized) { # if the where clauses hold + // str: Sized # then the bound on the associated type hold + // } + // ``` + // which it is :) + type Item where str: Sized = str; +} + +struct OnlySized where T: Sized { f: T } +impl Print for OnlySized { + fn print() { + println!("{}", std::mem::size_of::()); + } +} + +trait Bar { + type Assoc: Print; +} + +impl Bar for T where T: Foo { + // This is not ok, we need to prove `wf(::Item)`, which requires + // knowing that `::Item: Sized` to satisfy the where clause. We + // can use the bound on `Foo::Item` for this, but that requires + // `wf(::Item)`, which is an invalid cycle. + type Assoc = OnlySized<::Item>; +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} + +fn foo() { + T::print() // oops, in fact `T = OnlySized` which is ill-formed +} + +fn bar() { + // we have `FromEnv(T: Bar)` hence + // `::Assoc` is well-formed and + // `Implemented(::Assoc: Print)` hold + foo::<::Assoc>() +} + +fn main() { + bar::() +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/shadowing.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/shadowing.rs new file mode 100644 index 000000000000..0e714208b5af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/shadowing.rs @@ -0,0 +1,33 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +trait Shadow<'a> { + type Bar<'a>; +// { dg-error ".E0496." "" { target *-*-* } .-1 } +} + +trait NoShadow<'a> { + type Bar<'b>; // OK +} + +impl<'a> NoShadow<'a> for &'a u32 { + type Bar<'a> = i32; +// { dg-error ".E0496." "" { target *-*-* } .-1 } +} + +trait ShadowT { + type Bar; +// { dg-error ".E0403." "" { target *-*-* } .-1 } +} + +trait NoShadowT { + type Bar; // OK +} + +impl NoShadowT for Option { + type Bar = i32; +// { dg-error ".E0403." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/streaming_iterator.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/streaming_iterator.rs new file mode 100644 index 000000000000..8b0a1464d0f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/streaming_iterator.rs @@ -0,0 +1,78 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +use std::fmt::Display; + +trait StreamingIterator { + type Item<'a>; + // Applying the lifetime parameter `'a` to `Self::Item` inside the trait. + fn next<'a>(&'a mut self) -> Option>; +} + +struct Foo { + // Applying a concrete lifetime to the constructor outside the trait. + bar: ::Item<'static>, +} + +// Users can bound parameters by the type constructed by that trait's associated type constructor +// of a trait using HRTB. Both type equality bounds and trait bounds of this kind are valid: +//FIXME(#44265): This next line should parse and be valid +//fn foo StreamingIterator=&'a [i32]>>(_iter: T) { /* ... */ } +fn _foo(_iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ } + +// Full example of enumerate iterator + +#[must_use = "iterators are lazy and do nothing unless consumed"] +struct StreamEnumerate { + iter: I, + count: usize, +} + +impl StreamingIterator for StreamEnumerate { + type Item<'a> = (usize, I::Item<'a>); + fn next<'a>(&'a mut self) -> Option> { + match self.iter.next() { + None => None, + Some(val) => { + let r = Some((self.count, val)); + self.count += 1; + r + } + } + } +} + +impl StreamingIterator for I { + type Item<'a> = ::Item; + fn next(&mut self) -> Option<::Item<'_>> { + Iterator::next(self) + } +} + +impl StreamEnumerate { + pub fn new(iter: I) -> Self { + StreamEnumerate { + count: 0, + iter, + } + } +} + +fn test_stream_enumerate() { + let v = vec!["a", "b", "c"]; + let mut se = StreamEnumerate::new(v.iter()); + while let Some(item) = se.next() { + assert_eq!(v[item.0], *item.1); + } + let x = Foo::> { + bar: &0u32, + }; + assert_eq!(*x.bar, 0u32); +} + +fn main() { + test_stream_enumerate(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generic-associated-types/unsatisfied-outlives-bound.rs b/gcc/testsuite/rust/rustc/ui/generic-associated-types/unsatisfied-outlives-bound.rs new file mode 100644 index 000000000000..690adf7a2935 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generic-associated-types/unsatisfied-outlives-bound.rs @@ -0,0 +1,23 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +trait ATy { + type Item<'a>: 'a; +} + +impl<'b> ATy for &'b () { + type Item<'a> = &'b (); +// { dg-error ".E0477." "" { target *-*-* } .-1 } +} + +trait StaticTy { + type Item<'a>: 'static; +} + +impl StaticTy for () { + type Item<'a> = &'a (); +// { dg-error ".E0477." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/auxiliary/default_type_params_xc.rs b/gcc/testsuite/rust/rustc/ui/generics/auxiliary/default_type_params_xc.rs new file mode 100644 index 000000000000..08c82a907e86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/auxiliary/default_type_params_xc.rs @@ -0,0 +1,6 @@ +pub struct Heap; + +pub struct FakeHeap; + +pub struct FakeVec { pub f: Option<(T,A)> } + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-alias-unique.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-alias-unique.rs new file mode 100644 index 000000000000..6ff45975a80f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-alias-unique.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(box_syntax)] + +fn id(t: T) -> T { return t; } + +pub fn main() { + let expected: Box<_> = box 100; + let actual = id::>(expected.clone()); + println!("{}", *actual); + assert_eq!(*expected, *actual); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-arg-mismatch-recover.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-arg-mismatch-recover.rs new file mode 100644 index 000000000000..8701b9869a76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-arg-mismatch-recover.rs @@ -0,0 +1,11 @@ +struct Foo<'a, T: 'a>(&'a T); + +struct Bar<'a>(&'a ()); + +fn main() { + Foo::<'static, 'static, ()>(&0); // { dg-error ".E0107." "" { target *-*-* } } + + Bar::<'static, 'static, ()>(&()); // { dg-error ".E0107." "" { target *-*-* } } +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-default-type-params-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-default-type-params-cross-crate.rs new file mode 100644 index 000000000000..a92e66157aed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-default-type-params-cross-crate.rs @@ -0,0 +1,18 @@ +// run-pass +// aux-build:default_type_params_xc.rs + +// pretty-expanded FIXME #23616 + +extern crate default_type_params_xc; + +struct Vec(Option<(T,A)>); + +struct Foo; + +fn main() { + let _a = Vec::(None); + let _b = Vec::(None); + let _c = default_type_params_xc::FakeVec:: { f: None }; + let _d = default_type_params_xc::FakeVec:: { f: None }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-default-type-params.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-default-type-params.rs new file mode 100644 index 000000000000..327ad1813dce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-default-type-params.rs @@ -0,0 +1,54 @@ +// run-pass +struct Foo { + a: A +} + +impl Foo { + fn bar_int(&self) -> isize { + self.a + } +} + +impl Foo { + fn bar_char(&self) -> char { + self.a + } +} + +impl Foo { + fn bar(&self) { + let (i, c): (isize, char) = self.a; + assert_eq!(Foo { a: i }.bar_int(), i); + assert_eq!(Foo { a: c }.bar_char(), c); + } +} + +impl Foo { + fn baz(&self) -> A { + self.a.clone() + } +} + +fn default_foo(x: Foo) { + let (i, c): (isize, char) = x.a; + assert_eq!(i, 1); + assert_eq!(c, 'a'); + + x.bar(); + assert_eq!(x.baz(), (1, 'a')); +} + +#[derive(PartialEq, Debug)] +struct BazHelper(T); + +#[derive(PartialEq, Debug)] +// Ensure that we can use previous type parameters in defaults. +struct Baz, V = Option>(T, U, V); + +fn main() { + default_foo(Foo { a: (1, 'a') }); + + let x: Baz = Baz(true, BazHelper(false), Some(BazHelper(true))); + assert_eq!(x, Baz(true, BazHelper(false), Some(BazHelper(true)))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-derived-type.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-derived-type.rs new file mode 100644 index 000000000000..561ca218244d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-derived-type.rs @@ -0,0 +1,22 @@ +// run-pass +fn g(x: X) -> X { return x; } + +#[derive(Clone)] +struct Pair { + a: T, + b: T +} + +fn f(t: T) -> Pair { + let x: Pair = Pair {a: t.clone(), b: t}; + return g::>(x); +} + +pub fn main() { + let b = f::(10); + println!("{}" ,b.a); + println!("{}", b.b); + assert_eq!(b.a, 10); + assert_eq!(b.b, 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-exterior-unique.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-exterior-unique.rs new file mode 100644 index 000000000000..5c0810153719 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-exterior-unique.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(box_syntax)] + +struct Recbox {x: Box} + +fn reclift(t: T) -> Recbox { return Recbox {x: box t}; } + +pub fn main() { + let foo: isize = 17; + let rbfoo: Recbox = reclift::(foo); + assert_eq!(*rbfoo.x, foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-extern-lifetime.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-extern-lifetime.rs new file mode 100644 index 000000000000..d5a906981aa5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-extern-lifetime.rs @@ -0,0 +1,16 @@ +// Test to make sure the names of the lifetimes are correctly resolved +// in extern blocks. + +extern { + pub fn life<'a>(x:&'a i32); + pub fn life2<'b>(x:&'a i32, y:&'b i32); // { dg-error ".E0261." "" { target *-*-* } } + pub fn life3<'a>(x:&'a i32, y:&i32) -> &'a i32; + pub fn life4<'b>(x: for<'c> fn(&'a i32)); // { dg-error ".E0261." "" { target *-*-* } } + pub fn life5<'b>(x: for<'c> fn(&'b i32)); + pub fn life6<'b>(x: for<'c> fn(&'c i32)); + pub fn life7<'b>() -> for<'c> fn(&'a i32); // { dg-error ".E0261." "" { target *-*-* } } + pub fn life8<'b>() -> for<'c> fn(&'b i32); + pub fn life9<'b>() -> for<'c> fn(&'c i32); +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-extern-mangle.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-extern-mangle.rs new file mode 100644 index 000000000000..25a244680f2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-extern-mangle.rs @@ -0,0 +1,10 @@ +// run-pass +use std::ops::Add; + +extern "C" fn foo(a: T, b: T) -> T::Output { a + b } + +fn main() { + assert_eq!(100u8, foo(0u8, 100u8)); + assert_eq!(100u16, foo(0u16, 100u16)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-extern.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-extern.rs new file mode 100644 index 000000000000..4488ec0e5263 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-extern.rs @@ -0,0 +1,8 @@ +extern { + fn foo(); // { dg-error ".E0044." "" { target *-*-* } } +} + +fn main() { + foo::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-fn-infer.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-fn-infer.rs new file mode 100644 index 000000000000..c9db56475f59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-fn-infer.rs @@ -0,0 +1,11 @@ +// run-pass + + + + +// Issue #45: infer type parameters in function applications + +fn id(x: T) -> T { return x; } + +pub fn main() { let x: isize = 42; let y: isize = id(x); assert_eq!(x, y); } + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-fn-twice.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-fn-twice.rs new file mode 100644 index 000000000000..d2e3b14deb57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-fn-twice.rs @@ -0,0 +1,12 @@ +// run-pass + + + +// pretty-expanded FIXME #23616 + +mod foomod { + pub fn foo() { } +} + +pub fn main() { foomod::foo::(); foomod::foo::(); } + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-fn-unique.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-fn-unique.rs new file mode 100644 index 000000000000..b72b70b4d3b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-fn-unique.rs @@ -0,0 +1,7 @@ +// run-pass +#![feature(box_syntax)] + +fn f(x: Box) -> Box { return x; } + +pub fn main() { let x = f(box 3); println!("{}", *x); } + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-fn.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-fn.rs new file mode 100644 index 000000000000..0d9ec6d986f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-fn.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_assignments)] + +fn id(x: T) -> T { return x; } + +#[derive(Copy, Clone)] +struct Triple {x: isize, y: isize, z: isize} + +pub fn main() { + let mut x = 62; + let mut y = 63; + let a = 'a'; + let mut b = 'b'; + let p: Triple = Triple {x: 65, y: 66, z: 67}; + let mut q: Triple = Triple {x: 68, y: 69, z: 70}; + y = id::(x); + println!("{}", y); + assert_eq!(x, y); + b = id::(a); + println!("{}", b); + assert_eq!(a, b); + q = id::(p); + x = p.z; + y = q.z; + println!("{}", y); + assert_eq!(x, y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-impl-less-params-with-defaults.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-impl-less-params-with-defaults.rs new file mode 100644 index 000000000000..69bc07300658 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-impl-less-params-with-defaults.rs @@ -0,0 +1,14 @@ +use std::marker; + +struct Foo( + marker::PhantomData<(A,B,C)>); + +impl Foo { + fn new() -> Foo {Foo(marker::PhantomData)} +} + +fn main() { + Foo::::new(); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-impl-more-params-with-defaults.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-impl-more-params-with-defaults.rs new file mode 100644 index 000000000000..066c9ea0940f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-impl-more-params-with-defaults.rs @@ -0,0 +1,16 @@ +use std::marker; + +struct Heap; + +struct Vec( + marker::PhantomData<(T,A)>); + +impl Vec { + fn new() -> Vec {Vec(marker::PhantomData)} +} + +fn main() { + Vec::::new(); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-ivec-leak.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-ivec-leak.rs new file mode 100644 index 000000000000..fb3951a9c541 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-ivec-leak.rs @@ -0,0 +1,6 @@ +// run-pass +#![allow(non_camel_case_types)] +enum wrapper { wrapped(T), } + +pub fn main() { let _w = wrapper::wrapped(vec![1, 2, 3, 4, 5]); } + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-lifetime-trait-impl.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-lifetime-trait-impl.rs new file mode 100644 index 000000000000..3359716de779 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-lifetime-trait-impl.rs @@ -0,0 +1,24 @@ +// This code used to produce an ICE on the definition of trait Bar +// with the following message: +// +// Type parameter out of range when substituting in region 'a (root +// type=fn(Self) -> 'astr) (space=FnSpace, index=0) +// +// Regression test for issue #16218. + +trait Bar<'a> { + fn dummy(&'a self); +} + +trait Foo<'a> { + fn dummy(&'a self) { } + fn bar<'b, T: Bar<'b>>(self) -> &'b str; +} + +impl<'a> Foo<'a> for &'a str { + fn bar>(self) -> &'a str { panic!() } // { dg-error ".E0195." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-newtype-struct.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-newtype-struct.rs new file mode 100644 index 000000000000..b77d1f72238b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-newtype-struct.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct S(T); + +pub fn main() { + let _s = S(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-no-mangle.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-no-mangle.rs new file mode 100644 index 000000000000..e6e1b65d19c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-no-mangle.rs @@ -0,0 +1,18 @@ +// run-rustfix + +#![deny(no_mangle_generic_items)] + +#[no_mangle] +pub fn foo() {} // { dg-error "" "" { target *-*-* } } + +#[no_mangle] +pub extern fn bar() {} // { dg-error "" "" { target *-*-* } } + +#[no_mangle] +pub fn baz(x: &i32) -> &i32 { x } + +#[no_mangle] +pub fn qux<'a>(x: &'a i32) -> &i32 { x } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-non-trailing-defaults.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-non-trailing-defaults.rs new file mode 100644 index 000000000000..acdbb7e40937 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-non-trailing-defaults.rs @@ -0,0 +1,11 @@ +struct Heap; + +struct Vec(A, T); +// { dg-error "" "" { target *-*-* } .-1 } + +struct Foo, C>(A, B, C); +// { dg-error ".E0128." "" { target *-*-* } .-1 } +// { dg-error ".E0128." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-object.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-object.rs new file mode 100644 index 000000000000..bd688ab80c7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-object.rs @@ -0,0 +1,23 @@ +// run-pass +#![feature(box_syntax)] + +trait Foo { + fn get(&self) -> T; +} + +struct S { + x: isize +} + +impl Foo for S { + fn get(&self) -> isize { + self.x + } +} + +pub fn main() { + let x = box S { x: 1 }; + let y = x as Box>; + assert_eq!(y.get(), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-param-attrs.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-param-attrs.rs new file mode 100644 index 000000000000..a5d7b51746ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-param-attrs.rs @@ -0,0 +1,39 @@ +// This test previously ensured that attributes on formals in generic parameter +// lists are rejected without a feature gate. + +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(rustc_attrs)] + +struct StLt<#[rustc_dummy] 'a>(&'a u32); +struct StTy<#[rustc_dummy] I>(I); +enum EnLt<#[rustc_dummy] 'b> { A(&'b u32), B } +enum EnTy<#[rustc_dummy] J> { A(J), B } +trait TrLt<#[rustc_dummy] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } +trait TrTy<#[rustc_dummy] K> { fn foo(&self, _: K); } +type TyLt<#[rustc_dummy] 'd> = &'d u32; +type TyTy<#[rustc_dummy] L> = (L, ); + +impl<#[rustc_dummy] 'e> StLt<'e> { } +impl<#[rustc_dummy] M> StTy { } +impl<#[rustc_dummy] 'f> TrLt<'f> for StLt<'f> { + fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } } +} +impl<#[rustc_dummy] N> TrTy for StTy { + fn foo(&self, _: N) { } +} + +fn f_lt<#[rustc_dummy] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } +fn f_ty<#[rustc_dummy] O>(_: O) { } + +impl StTy { + fn m_lt<#[rustc_dummy] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } + fn m_ty<#[rustc_dummy] P>(_: P) { } +} + +fn hof_lt(_: Q) + where Q: for <#[rustc_dummy] 'i> Fn(&'i [u32]) -> &'i u32 +{} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-recursive-tag.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-recursive-tag.rs new file mode 100644 index 000000000000..ae80c16f05cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-recursive-tag.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(non_camel_case_types)] +#![feature(box_syntax)] + +enum list { cons(Box, Box>), nil, } + +pub fn main() { + let _a: list = + list::cons::(box 10, + box list::cons::(box 12, + box list::cons::(box 13, + box list::nil::))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-static-methods.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-static-methods.rs new file mode 100644 index 000000000000..1631fe27a04a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-static-methods.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(non_camel_case_types)] + + +trait vec_utils { + fn map_(x: &Self, f: F) -> Vec where F: FnMut(&T) -> U; +} + +impl vec_utils for Vec { + fn map_(x: &Vec , mut f: F) -> Vec where F: FnMut(&T) -> U { + let mut r = Vec::new(); + for elt in x { + r.push(f(elt)); + } + r + } +} + +pub fn main() { + assert_eq!(vec_utils::map_(&vec![1,2,3], |&x| x+1), [2,3,4]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-tag-corruption.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-tag-corruption.rs new file mode 100644 index 000000000000..b2a9ba9401fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-tag-corruption.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(non_camel_case_types)] + + +// This used to cause memory corruption in stage 0. +// pretty-expanded FIXME #23616 + +enum thing { some(K), } + +pub fn main() { let _x = thing::some("hi".to_string()); } + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-tag-local.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-tag-local.rs new file mode 100644 index 000000000000..54a59dfbefe7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-tag-local.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +enum clam { a(T), } + +pub fn main() { let _c = clam::a(3); } + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-tag-match.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-tag-match.rs new file mode 100644 index 000000000000..92b5d65fe69b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-tag-match.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(unused_assignments)] +#![allow(non_camel_case_types)] + +enum foo { arm(T), } + +fn altfoo(f: foo) { + let mut hit = false; + match f { foo::arm::(_x) => { println!("in arm"); hit = true; } } + assert!((hit)); +} + +pub fn main() { altfoo::(foo::arm::(10)); } + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-tag-values.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-tag-values.rs new file mode 100644 index 000000000000..8508e659ed35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-tag-values.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(non_camel_case_types)] + +enum noption { some(T), } + +struct Pair { x: isize, y: isize } + +pub fn main() { + let nop: noption = noption::some::(5); + match nop { noption::some::(n) => { println!("{}", n); assert_eq!(n, 5); } } + let nop2: noption = noption::some(Pair{x: 17, y: 42}); + match nop2 { + noption::some(t) => { + println!("{}", t.x); + println!("{}", t.y); + assert_eq!(t.x, 17); + assert_eq!(t.y, 42); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-tag.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-tag.rs new file mode 100644 index 000000000000..6ee81cf267a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-tag.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(unused_assignments)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +#![allow(unused_variables)] +#![feature(box_syntax)] + +enum option { some(Box), none, } + +pub fn main() { + let mut a: option = option::some::(box 10); + a = option::none::; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-temporary.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-temporary.rs new file mode 100644 index 000000000000..3626356297f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-temporary.rs @@ -0,0 +1,17 @@ +// run-pass + +fn mk() -> isize { return 1; } + +fn chk(a: isize) { println!("{}", a); assert_eq!(a, 1); } + +fn apply(produce: fn() -> T, + consume: fn(T)) { + consume(produce()); +} + +pub fn main() { + let produce: fn() -> isize = mk; + let consume: fn(v: isize) = chk; + apply::(produce, consume); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-tup.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-tup.rs new file mode 100644 index 000000000000..b0cea9907114 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-tup.rs @@ -0,0 +1,9 @@ +// run-pass +fn get_third(t: (T, T, T)) -> T { let (_, _, x) = t; return x; } + +pub fn main() { + println!("{}", get_third((1, 2, 3))); + assert_eq!(get_third((1, 2, 3)), 3); + assert_eq!(get_third((5u8, 6u8, 7u8)), 7u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-type-less-params-with-defaults.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-type-less-params-with-defaults.rs new file mode 100644 index 000000000000..1ff053d12ba3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-type-less-params-with-defaults.rs @@ -0,0 +1,12 @@ +use std::marker; + +struct Heap; + +struct Vec( + marker::PhantomData<(T,A)>); + +fn main() { + let _: Vec; +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-type-more-params-with-defaults.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-type-more-params-with-defaults.rs new file mode 100644 index 000000000000..36d87f83c51d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-type-more-params-with-defaults.rs @@ -0,0 +1,12 @@ +use std::marker; + +struct Heap; + +struct Vec( + marker::PhantomData<(T,A)>); + +fn main() { + let _: Vec; +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-type-params-forward-mention.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-type-params-forward-mention.rs new file mode 100644 index 000000000000..44a1c6c066e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-type-params-forward-mention.rs @@ -0,0 +1,7 @@ +// Ensure that we get an error and not an ICE for this problematic case. +struct Foo, U = bool>(T, U); +// { dg-error ".E0128." "" { target *-*-* } .-1 } +fn main() { + let x: Foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-type-params-name-repr.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-type-params-name-repr.rs new file mode 100644 index 000000000000..6742c646c781 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-type-params-name-repr.rs @@ -0,0 +1,52 @@ +use std::marker; + +struct A; +struct B; +struct C; +struct Foo(marker::PhantomData<(T,U,V)>); + +struct Hash(marker::PhantomData); +struct HashMap>(marker::PhantomData<(K,V,H)>); + +fn main() { + // Ensure that the printed type doesn't include the default type params... + let _: Foo = (); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + // ...even when they're present, but the same types as the defaults. + let _: Foo = (); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + // Including cases where the default is using previous type params. + let _: HashMap = (); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + let _: HashMap> = (); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + // But not when there's a different type in between. + let _: Foo = (); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + // And don't print <> at all when there's just defaults. + let _: Foo = (); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-type-synonym.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-type-synonym.rs new file mode 100644 index 000000000000..8e573e7c06fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-type-synonym.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] + + +// pretty-expanded FIXME #23616 + +struct Foo { + a: T +} + +type Bar = Foo; + +fn takebar(_b: Bar) { } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-type.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-type.rs new file mode 100644 index 000000000000..6fa3d60c98a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-type.rs @@ -0,0 +1,12 @@ +// run-pass + + + +struct Pair {x: T, y: T} + +pub fn main() { + let x: Pair = Pair {x: 10, y: 12}; + assert_eq!(x.x, 10); + assert_eq!(x.y, 12); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/generic-unique.rs b/gcc/testsuite/rust/rustc/ui/generics/generic-unique.rs new file mode 100644 index 000000000000..297e97561333 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/generic-unique.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +#![feature(box_syntax)] + +struct Triple { x: T, y: T, z: T } + +fn box_it(x: Triple) -> Box> { return box x; } + +pub fn main() { + let x: Box> = box_it::(Triple{x: 1, y: 2, z: 3}); + assert_eq!(x.y, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.rs b/gcc/testsuite/rust/rustc/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.rs new file mode 100644 index 000000000000..bba5990bb4d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/issue-61631-default-type-param-can-reference-self-in-trait.rs @@ -0,0 +1,21 @@ +#![crate_type="lib"] + +// rust-lang/rust#61631: The use of `Self` in the defaults of generic +// types in a *trait* definition are allowed. +// +// It *must* be accepted; we have used this pattern extensively since +// Rust 1.0 (see e.g. `trait Add`). +trait Tnobound

{} + +impl Tnobound for () { } + +// This variant is accepted at the definition site; but it will be +// rejected at every possible usage site (such as the one immediately +// below). Maybe one day we will attempt to catch it at the definition +// site, but today this is accepted due to compiler implementation +// limitations. +trait Tsized {} + +impl Tsized for () {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/generics/issue-61631-default-type-param-cannot-reference-self.rs b/gcc/testsuite/rust/rustc/ui/generics/issue-61631-default-type-param-cannot-reference-self.rs new file mode 100644 index 000000000000..a285333fd796 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/issue-61631-default-type-param-cannot-reference-self.rs @@ -0,0 +1,46 @@ +#![crate_type="lib"] + +// rust-lang/rust#61631: Uses of `Self` in the defaults of generic +// types for ADT's are not allowed. We justify this because the `Self` +// type could be considered the "final" type parameter, that is only +// well-defined after all of the other type parameters on the ADT have +// been instantiated. +// +// These were previously were ICE'ing at the usage point anyway (see +// `demo_usages` below), so there should not be any backwards +// compatibility concern. + +struct Snobound<'a, P = Self> { x: Option<&'a P> } +// { dg-error ".E0735." "" { target *-*-* } .-1 } + +enum Enobound<'a, P = Self> { A, B(Option<&'a P>) } +// { dg-error ".E0735." "" { target *-*-* } .-1 } + +union Unobound<'a, P = Self> { x: i32, y: Option<&'a P> } +// { dg-error ".E0735." "" { target *-*-* } .-1 } + +// Disallowing `Self` in defaults sidesteps need to check the bounds +// on the defaults in cases like these. + +struct Ssized<'a, P: Sized = [Self]> { x: Option<&'a P> } +// { dg-error ".E0735." "" { target *-*-* } .-1 } + +enum Esized<'a, P: Sized = [Self]> { A, B(Option<&'a P>) } +// { dg-error ".E0735." "" { target *-*-* } .-1 } + +union Usized<'a, P: Sized = [Self]> { x: i32, y: Option<&'a P> } +// { dg-error ".E0735." "" { target *-*-* } .-1 } + +fn demo_usages() { + // An ICE means you only get the error from the first line of the + // demo; comment each out to observe the other ICEs when trying + // this out on older versions of Rust. + + let _ice: Snobound; + let _ice: Enobound; + let _ice: Unobound; + let _ice: Ssized; + let _ice: Esized; + let _ice: Usized; +} + diff --git a/gcc/testsuite/rust/rustc/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs b/gcc/testsuite/rust/rustc/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs new file mode 100644 index 000000000000..1bbc426f4cda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs @@ -0,0 +1,15 @@ +#![crate_type="lib"] + +struct Nested(K); + +fn should_error() where T : Into<&u32> {} +// { dg-error ".E0637." "" { target *-*-* } .-1 } + +trait X<'a, K: 'a> { + fn foo<'b, L: X<&'b Nested>>(); +// { dg-error ".E0106." "" { target *-*-* } .-1 } +} + +fn bar<'b, L: X<&'b Nested>>(){} +// { dg-error ".E0106." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/generics/param-in-ct-in-ty-param-default.rs b/gcc/testsuite/rust/rustc/ui/generics/param-in-ct-in-ty-param-default.rs new file mode 100644 index 000000000000..88833e006b80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/generics/param-in-ct-in-ty-param-default.rs @@ -0,0 +1,5 @@ +struct Foo()]>(T, U); +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/glob-cycles.rs b/gcc/testsuite/rust/rustc/ui/glob-cycles.rs new file mode 100644 index 000000000000..abd2d20d3e37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/glob-cycles.rs @@ -0,0 +1,19 @@ +// check-pass + +mod foo { + pub use bar::*; + pub use main as f; +} + +mod bar { + pub use foo::*; +} + +pub use foo::*; +pub use baz::*; +mod baz { + pub use super::*; +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/glob-resolve1.rs b/gcc/testsuite/rust/rustc/ui/glob-resolve1.rs new file mode 100644 index 000000000000..f1ee1cc7001e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/glob-resolve1.rs @@ -0,0 +1,36 @@ +// Make sure that globs only bring in public things. + +use bar::*; + +mod bar { + use self::fpriv as import; + fn fpriv() {} + extern { + fn epriv(); + } + enum A { A1 } + pub enum B { B1 } + + struct C; + + type D = isize; +} + +fn foo() {} + +fn main() { + fpriv(); // { dg-error ".E0425." "" { target *-*-* } } + epriv(); // { dg-error ".E0425." "" { target *-*-* } } + B; // { dg-error ".E0423." "" { target *-*-* } } + C; // { dg-error ".E0425." "" { target *-*-* } } + import(); // { dg-error ".E0425." "" { target *-*-* } } + + foo::(); // { dg-error ".E0412." "" { target *-*-* } } + foo::(); // { dg-error ".E0412." "" { target *-*-* } } + foo::(); // { dg-error ".E0412." "" { target *-*-* } } +} + +mod other { + pub fn import() {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/global-scope.rs b/gcc/testsuite/rust/rustc/ui/global-scope.rs new file mode 100644 index 000000000000..0fb3841ca459 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/global-scope.rs @@ -0,0 +1,14 @@ +// run-pass + +pub fn f() -> isize { return 1; } + +pub mod foo { + pub fn f() -> isize { return 2; } + pub fn g() { + assert_eq!(f(), 2); + assert_eq!(::f(), 1); + } +} + +pub fn main() { return foo::g(); } + diff --git a/gcc/testsuite/rust/rustc/ui/guards.rs b/gcc/testsuite/rust/rustc/ui/guards.rs new file mode 100644 index 000000000000..91d2f65d94f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/guards.rs @@ -0,0 +1,21 @@ +// run-pass + +#![allow(non_shorthand_field_patterns)] + +#[derive(Copy, Clone)] +struct Pair { x: isize, y: isize } + +pub fn main() { + let a: isize = + match 10 { x if x < 7 => { 1 } x if x < 11 => { 2 } 10 => { 3 } _ => { 4 } }; + assert_eq!(a, 2); + + let b: isize = + match (Pair {x: 10, y: 20}) { + x if x.x < 5 && x.y < 5 => { 1 } + Pair {x: x, y: y} if x == 10 && y == 20 => { 2 } + Pair {x: _x, y: _y} => { 3 } + }; + assert_eq!(b, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs new file mode 100644 index 000000000000..5a3420388c77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision.rs @@ -0,0 +1,11 @@ +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() { + match [5..4, 99..105, 43..44] { + [_, 99.., _] => {}, +// { dg-error ".E0308." "" { target *-*-* } .-1 } + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs new file mode 100644 index 000000000000..1de567d05202 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision2.rs @@ -0,0 +1,12 @@ +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() { + match [5..4, 99..105, 43..44] { + [_, 99..] => {}, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs new file mode 100644 index 000000000000..988f00c26554 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/exclusive_range_pattern_syntax_collision3.rs @@ -0,0 +1,13 @@ +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() { + match [5..4, 99..105, 43..44] { + [..9, 99..100, _] => {}, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs new file mode 100644 index 000000000000..85639608ed40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/feature-gate-half-open-range-patterns.rs @@ -0,0 +1,23 @@ +#![feature(exclusive_range_pattern)] + +fn main() {} + +#[cfg(FALSE)] +fn foo() { + if let ..=5 = 0 {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + if let ...5 = 0 {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + if let ..5 = 0 {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + if let 5.. = 0 {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + if let 5..= = 0 {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + if let 5... = 0 {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs new file mode 100644 index 000000000000..141a25752a2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-bad-types.rs @@ -0,0 +1,9 @@ +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() { + let "a".. = "a"; // { dg-error ".E0029." "" { target *-*-* } } + let .."a" = "a"; // { dg-error ".E0029." "" { target *-*-* } } + let ..="a" = "a"; // { dg-error ".E0029." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs new file mode 100644 index 000000000000..199dbbfd6cac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-exhaustive-fail.rs @@ -0,0 +1,169 @@ +// Test various non-exhaustive matches for `X..`, `..=X` and `..X` ranges. + +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] +#![allow(illegal_floating_point_literal_pattern)] + +fn main() {} + +macro_rules! m { + ($s:expr, $($t:tt)+) => { + match $s { $($t)+ => {} } + } +} + +fn floats() { + m!(0f32, core::f32::NEG_INFINITY..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0f32, ..core::f32::INFINITY); // { dg-error ".E0004." "" { target *-*-* } } +} + +fn khar() { + const ALMOST_MAX: char = '\u{10fffe}'; + const ALMOST_MIN: char = '\u{1}'; + const VAL: char = 'a'; + const VAL_1: char = 'b'; + const VAL_2: char = 'c'; + m!('a', ..core::char::MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!('a', ..ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!('a', ALMOST_MIN..); // { dg-error ".E0004." "" { target *-*-* } } + m!('a', ..=ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!('a', ..=VAL | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + m!('a', ..VAL_1 | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } +} + +mod unsigned { + fn u8() { + const ALMOST_MAX: u8 = core::u8::MAX - 1; + const ALMOST_MIN: u8 = core::u8::MIN + 1; + const VAL: u8 = 42; + const VAL_1: u8 = VAL + 1; + const VAL_2: u8 = VAL + 2; + m!(0, ..core::u8::MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ALMOST_MIN..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=VAL | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..VAL_1 | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + } + fn u16() { + const ALMOST_MAX: u16 = core::u16::MAX - 1; + const ALMOST_MIN: u16 = core::u16::MIN + 1; + const VAL: u16 = 42; + const VAL_1: u16 = VAL + 1; + const VAL_2: u16 = VAL + 2; + m!(0, ..core::u16::MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ALMOST_MIN..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=VAL | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..VAL_1 | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + } + fn u32() { + const ALMOST_MAX: u32 = core::u32::MAX - 1; + const ALMOST_MIN: u32 = core::u32::MIN + 1; + const VAL: u32 = 42; + const VAL_1: u32 = VAL + 1; + const VAL_2: u32 = VAL + 2; + m!(0, ..core::u32::MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ALMOST_MIN..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=VAL | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..VAL_1 | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + } + fn u64() { + const ALMOST_MAX: u64 = core::u64::MAX - 1; + const ALMOST_MIN: u64 = core::u64::MIN + 1; + const VAL: u64 = 42; + const VAL_1: u64 = VAL + 1; + const VAL_2: u64 = VAL + 2; + m!(0, ..core::u64::MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ALMOST_MIN..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=VAL | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..VAL_1 | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + } + fn u128() { + const ALMOST_MAX: u128 = core::u128::MAX - 1; + const ALMOST_MIN: u128 = core::u128::MIN + 1; + const VAL: u128 = 42; + const VAL_1: u128 = VAL + 1; + const VAL_2: u128 = VAL + 2; + m!(0, ..core::u128::MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ALMOST_MIN..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=VAL | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..VAL_1 | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + } +} + +mod signed { + fn i8() { + const ALMOST_MAX: i8 = core::i8::MAX - 1; + const ALMOST_MIN: i8 = core::i8::MIN + 1; + const VAL: i8 = 42; + const VAL_1: i8 = VAL + 1; + const VAL_2: i8 = VAL + 2; + m!(0, ..core::i8::MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ALMOST_MIN..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=VAL | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..VAL_1 | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + } + fn i16() { + const ALMOST_MAX: i16 = core::i16::MAX - 1; + const ALMOST_MIN: i16 = core::i16::MIN + 1; + const VAL: i16 = 42; + const VAL_1: i16 = VAL + 1; + const VAL_2: i16 = VAL + 2; + m!(0, ..core::i16::MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ALMOST_MIN..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=VAL | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..VAL_1 | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + } + fn i32() { + const ALMOST_MAX: i32 = core::i32::MAX - 1; + const ALMOST_MIN: i32 = core::i32::MIN + 1; + const VAL: i32 = 42; + const VAL_1: i32 = VAL + 1; + const VAL_2: i32 = VAL + 2; + m!(0, ..core::i32::MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ALMOST_MIN..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=VAL | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..VAL_1 | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + } + fn i64() { + const ALMOST_MAX: i64 = core::i64::MAX - 1; + const ALMOST_MIN: i64 = core::i64::MIN + 1; + const VAL: i64 = 42; + const VAL_1: i64 = VAL + 1; + const VAL_2: i64 = VAL + 2; + m!(0, ..core::i64::MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ALMOST_MIN..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=VAL | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..VAL_1 | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + } + fn i128() { + const ALMOST_MAX: i128 = core::i128::MAX - 1; + const ALMOST_MIN: i128 = core::i128::MIN + 1; + const VAL: i128 = 42; + const VAL_1: i128 = VAL + 1; + const VAL_2: i128 = VAL + 2; + m!(0, ..core::i128::MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ALMOST_MIN..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=ALMOST_MAX); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..=VAL | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + m!(0, ..VAL_1 | VAL_2..); // { dg-error ".E0004." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs new file mode 100644 index 000000000000..7297d0733864 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-exhaustive-pass.rs @@ -0,0 +1,50 @@ +// check-pass + +// Test various exhaustive matches for `X..`, `..=X` and `..X` ranges. + +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() {} + +macro_rules! m { + ($s:expr, $($t:tt)+) => { + match $s { $($t)+ => {} } + } +} + +macro_rules! test_int { + ($s:expr, $min:path, $max:path) => { + m!($s, $min..); + m!($s, $min..5 | 5..); + m!($s, ..5 | 5..); + m!($s, ..=4 | 5..); + m!($s, ..=$max); + m!($s, ..$max | $max); + m!(($s, true), (..5, true) | (5.., true) | ($min.., false)); + } +} + +fn unsigned_int() { + test_int!(0u8, core::u8::MIN, core::u8::MAX); + test_int!(0u16, core::u16::MIN, core::u16::MAX); + test_int!(0u32, core::u32::MIN, core::u32::MAX); + test_int!(0u64, core::u64::MIN, core::u64::MAX); + test_int!(0u128, core::u128::MIN, core::u128::MAX); +} + +fn signed_int() { + test_int!(0i8, core::i8::MIN, core::i8::MAX); + test_int!(0i16, core::i16::MIN, core::i16::MAX); + test_int!(0i32, core::i32::MIN, core::i32::MAX); + test_int!(0i64, core::i64::MIN, core::i64::MAX); + test_int!(0i128, core::i128::MIN, core::i128::MAX); +} + +fn khar() { + m!('a', ..=core::char::MAX); + m!('a', '\u{0}'..); + m!('a', ..='\u{D7FF}' | '\u{E000}'..); + m!('a', ..'\u{D7FF}' | '\u{D7FF}' | '\u{E000}'..); +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs new file mode 100644 index 000000000000..a8673cb41519 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs @@ -0,0 +1,33 @@ +// Test that `...X` range-to patterns are syntactically invalid. +// +// See https://github.com/rust-lang/rust/pull/67258#issuecomment-565656155 +// for the reason why. To summarize, we might want to introduce `...expr` as +// an expression form for splatting (or "untupling") in an expression context. +// While there is no syntactic ambiguity with `...X` in a pattern context, +// there's a potential confusion factor here, and we would prefer to keep patterns +// and expressions in-sync. As such, we do not allow `...X` in patterns either. + +#![feature(half_open_range_patterns)] + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + match scrutinee { + ...X => {} // { dg-error "" "" { target *-*-* } } + ...0 => {} // { dg-error "" "" { target *-*-* } } + ...'a' => {} // { dg-error "" "" { target *-*-* } } + ...0.0f32 => {} // { dg-error "" "" { target *-*-* } } + } +} + +fn syntax2() { + macro_rules! mac { + ($e:expr) => { + let ...$e; // { dg-error "" "" { target *-*-* } } + } + } + + mac!(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs new file mode 100644 index 000000000000..2e7c198ed474 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs @@ -0,0 +1,27 @@ +// Test `X...` and `X..=` range patterns not being allowed syntactically. +// FIXME(Centril): perhaps these should be semantic restrictions. + +#![feature(half_open_range_patterns)] + +fn main() {} + +#[cfg(FALSE)] +fn foo() { + if let 0... = 1 {} // { dg-error ".E0586." "" { target *-*-* } } + if let 0..= = 1 {} // { dg-error ".E0586." "" { target *-*-* } } + const X: u8 = 0; + if let X... = 1 {} // { dg-error ".E0586." "" { target *-*-* } } + if let X..= = 1 {} // { dg-error ".E0586." "" { target *-*-* } } +} + +fn bar() { + macro_rules! mac { + ($e:expr) => { + let $e...; // { dg-error ".E0586." "" { target *-*-* } } + let $e..=; // { dg-error ".E0586." "" { target *-*-* } } + } + } + + mac!(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs new file mode 100644 index 000000000000..9a904e252b42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-ref-ambiguous-interp.rs @@ -0,0 +1,27 @@ +#![feature(half_open_range_patterns)] + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + match &0 { + &0.. | _ => {} +// { dg-error "" "" { target *-*-* } .-1 } + &0..= | _ => {} +// { dg-error ".E0586." "" { target *-*-* } .-1 } +// { dg-error ".E0586." "" { target *-*-* } .-2 } + &0... | _ => {} +// { dg-error ".E0586." "" { target *-*-* } .-1 } + } + + match &0 { + &..0 | _ => {} +// { dg-error "" "" { target *-*-* } .-1 } + &..=0 | _ => {} +// { dg-error "" "" { target *-*-* } .-1 } + &...0 | _ => {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-semantics.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-semantics.rs new file mode 100644 index 000000000000..613d7c5207f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-semantics.rs @@ -0,0 +1,161 @@ +// run-pass + +// Test half-open range patterns against their expression equivalents +// via `.contains(...)` and make sure the dynamic semantics match. + +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] +#![allow(illegal_floating_point_literal_pattern)] +#![allow(unreachable_patterns)] + +macro_rules! yes { + ($scrutinee:expr, $($t:tt)+) => { + { + let m = match $scrutinee { $($t)+ => true, _ => false, }; + let c = ($($t)+).contains(&$scrutinee); + assert_eq!(m, c); + m + } + } +} + +fn range_to_inclusive() { + // `..=X` (`RangeToInclusive`-equivalent): + //--------------------------------------- + + // u8; `..=X` + assert!(yes!(core::u8::MIN, ..=core::u8::MIN)); + assert!(yes!(core::u8::MIN, ..=5)); + assert!(yes!(5u8, ..=5)); + assert!(!yes!(6u8, ..=5)); + + // i16; `..=X` + assert!(yes!(core::i16::MIN, ..=core::i16::MIN)); + assert!(yes!(core::i16::MIN, ..=0)); + assert!(yes!(core::i16::MIN, ..=-5)); + assert!(yes!(-5, ..=-5)); + assert!(!yes!(-4, ..=-5)); + + // char; `..=X` + assert!(yes!('\u{0}', ..='\u{0}')); + assert!(yes!('\u{0}', ..='a')); + assert!(yes!('a', ..='a')); + assert!(!yes!('b', ..='a')); + + // f32; `..=X` + assert!(yes!(core::f32::NEG_INFINITY, ..=core::f32::NEG_INFINITY)); + assert!(yes!(core::f32::NEG_INFINITY, ..=1.0f32)); + assert!(yes!(1.5f32, ..=1.5f32)); + assert!(!yes!(1.6f32, ..=-1.5f32)); + + // f64; `..=X` + assert!(yes!(core::f64::NEG_INFINITY, ..=core::f64::NEG_INFINITY)); + assert!(yes!(core::f64::NEG_INFINITY, ..=1.0f64)); + assert!(yes!(1.5f64, ..=1.5f64)); + assert!(!yes!(1.6f64, ..=-1.5f64)); +} + +fn range_to() { + // `..X` (`RangeTo`-equivalent): + //----------------------------- + + // u8; `..X` + assert!(yes!(0u8, ..1)); + assert!(yes!(0u8, ..5)); + assert!(!yes!(5u8, ..5)); + assert!(!yes!(6u8, ..5)); + + // u8; `..X` + const NU8: u8 = core::u8::MIN + 1; + assert!(yes!(core::u8::MIN, ..NU8)); + assert!(yes!(0u8, ..5)); + assert!(!yes!(5u8, ..5)); + assert!(!yes!(6u8, ..5)); + + // i16; `..X` + const NI16: i16 = core::i16::MIN + 1; + assert!(yes!(core::i16::MIN, ..NI16)); + assert!(yes!(core::i16::MIN, ..5)); + assert!(yes!(-6, ..-5)); + assert!(!yes!(-5, ..-5)); + + // char; `..X` + assert!(yes!('\u{0}', ..'\u{1}')); + assert!(yes!('\u{0}', ..'a')); + assert!(yes!('a', ..'b')); + assert!(!yes!('a', ..'a')); + assert!(!yes!('b', ..'a')); + + // f32; `..X` + assert!(yes!(core::f32::NEG_INFINITY, ..1.0f32)); + assert!(!yes!(1.5f32, ..1.5f32)); + const E32: f32 = 1.5f32 + core::f32::EPSILON; + assert!(yes!(1.5f32, ..E32)); + assert!(!yes!(1.6f32, ..1.5f32)); + + // f64; `..X` + assert!(yes!(core::f64::NEG_INFINITY, ..1.0f64)); + assert!(!yes!(1.5f64, ..1.5f64)); + const E64: f64 = 1.5f64 + core::f64::EPSILON; + assert!(yes!(1.5f64, ..E64)); + assert!(!yes!(1.6f64, ..1.5f64)); +} + +fn range_from() { + // `X..` (`RangeFrom`-equivalent): + //-------------------------------- + + // u8; `X..` + assert!(yes!(core::u8::MIN, core::u8::MIN..)); + assert!(yes!(core::u8::MAX, core::u8::MIN..)); + assert!(!yes!(core::u8::MIN, 1..)); + assert!(!yes!(4, 5..)); + assert!(yes!(5, 5..)); + assert!(yes!(6, 5..)); + assert!(yes!(core::u8::MAX, core::u8::MAX..)); + + // i16; `X..` + assert!(yes!(core::i16::MIN, core::i16::MIN..)); + assert!(yes!(core::i16::MAX, core::i16::MIN..)); + const NI16: i16 = core::i16::MIN + 1; + assert!(!yes!(core::i16::MIN, NI16..)); + assert!(!yes!(-4, 5..)); + assert!(yes!(-4, -4..)); + assert!(yes!(-3, -4..)); + assert!(yes!(core::i16::MAX, core::i16::MAX..)); + + // char; `X..` + assert!(yes!('\u{0}', '\u{0}'..)); + assert!(yes!(core::char::MAX, '\u{0}'..)); + assert!(yes!('a', 'a'..)); + assert!(yes!('b', 'a'..)); + assert!(!yes!('a', 'b'..)); + assert!(yes!(core::char::MAX, core::char::MAX..)); + + // f32; `X..` + assert!(yes!(core::f32::NEG_INFINITY, core::f32::NEG_INFINITY..)); + assert!(yes!(core::f32::INFINITY, core::f32::NEG_INFINITY..)); + assert!(!yes!(core::f32::NEG_INFINITY, 1.0f32..)); + assert!(yes!(core::f32::INFINITY, 1.0f32..)); + assert!(!yes!(1.0f32 - core::f32::EPSILON, 1.0f32..)); + assert!(yes!(1.0f32, 1.0f32..)); + assert!(yes!(core::f32::INFINITY, 1.0f32..)); + assert!(yes!(core::f32::INFINITY, core::f32::INFINITY..)); + + // f64; `X..` + assert!(yes!(core::f64::NEG_INFINITY, core::f64::NEG_INFINITY..)); + assert!(yes!(core::f64::INFINITY, core::f64::NEG_INFINITY..)); + assert!(!yes!(core::f64::NEG_INFINITY, 1.0f64..)); + assert!(yes!(core::f64::INFINITY, 1.0f64..)); + assert!(!yes!(1.0f64 - core::f64::EPSILON, 1.0f64..)); + assert!(yes!(1.0f64, 1.0f64..)); + assert!(yes!(core::f64::INFINITY, 1.0f64..)); + assert!(yes!(core::f64::INFINITY, core::f64::INFINITY..)); +} + +fn main() { + range_to_inclusive(); + range_to(); + range_from(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs new file mode 100644 index 000000000000..fc058b3b4e0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-syntactic-pass.rs @@ -0,0 +1,31 @@ +// check-pass + +// Test the parsing of half-open ranges. + +#![feature(exclusive_range_pattern)] +#![feature(half_open_range_patterns)] + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + match scrutinee { + X.. | 0.. | 'a'.. | 0.0f32.. => {} + ..=X | ..X => {} + ..=0 | ..0 => {} + ..='a' | ..'a' => {} + ..=0.0f32 | ..0.0f32 => {} + } +} + +fn syntax2() { + macro_rules! mac { + ($e:expr) => { + match 0u8 { ..$e => {}, _ => {} } + match 0u8 { ..=$e => {}, _ => {} } + match 0u8 { $e.. => {}, _ => {} } + } + } + mac!(42u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs new file mode 100644 index 000000000000..00e4b01489e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/half-open-range-pats-thir-lower-empty.rs @@ -0,0 +1,55 @@ +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] +#![allow(illegal_floating_point_literal_pattern)] + +macro_rules! m { + ($s:expr, $($t:tt)+) => { + match $s { $($t)+ => {} } + } +} + +fn main() { + m!(0, ..core::u8::MIN); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + m!(0, ..core::u16::MIN); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + m!(0, ..core::u32::MIN); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + m!(0, ..core::u64::MIN); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + m!(0, ..core::u128::MIN); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + + m!(0, ..core::i8::MIN); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + m!(0, ..core::i16::MIN); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + m!(0, ..core::i32::MIN); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + m!(0, ..core::i64::MIN); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + m!(0, ..core::i128::MIN); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + + m!(0f32, ..core::f32::NEG_INFINITY); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + m!(0f64, ..core::f64::NEG_INFINITY); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + + m!('a', ..'\u{0}'); +// { dg-error ".E0579." "" { target *-*-* } .-1 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/pat-tuple-4.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/pat-tuple-4.rs new file mode 100644 index 000000000000..bb8d83fa0505 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/pat-tuple-4.rs @@ -0,0 +1,14 @@ +// check-pass + +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() { + const PAT: u8 = 1; + + match 0 { + (.. PAT) => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/pat-tuple-5.rs b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/pat-tuple-5.rs new file mode 100644 index 000000000000..e23d534ad505 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/half-open-range-patterns/pat-tuple-5.rs @@ -0,0 +1,11 @@ +#![feature(half_open_range_patterns)] +#![feature(exclusive_range_pattern)] + +fn main() { + const PAT: u8 = 1; + + match (0, 1) { + (PAT ..) => {} // { dg-error ".E0308." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hashmap/hashmap-capacity-overflow.rs b/gcc/testsuite/rust/rustc/ui/hashmap/hashmap-capacity-overflow.rs new file mode 100644 index 000000000000..62740559b5bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hashmap/hashmap-capacity-overflow.rs @@ -0,0 +1,14 @@ +// run-fail +// error-pattern:capacity overflow +// ignore-emscripten no processes + +use std::collections::hash_map::HashMap; +use std::usize; +use std::mem::size_of; + +fn main() { + let threshold = usize::MAX / size_of::<(u64, u64, u64)>(); + let mut h = HashMap::::with_capacity(threshold + 100); + h.insert(0, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hashmap/hashmap-iter-value-lifetime.rs b/gcc/testsuite/rust/rustc/ui/hashmap/hashmap-iter-value-lifetime.rs new file mode 100644 index 000000000000..a894decafc51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hashmap/hashmap-iter-value-lifetime.rs @@ -0,0 +1,11 @@ +fn main() { + let mut my_stuff = std::collections::HashMap::new(); + my_stuff.insert(0, 42); + + let (_, thing) = my_stuff.iter().next().unwrap(); + + my_stuff.clear(); // { dg-error ".E0502." "" { target *-*-* } } + + println!("{}", *thing); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hashmap/hashmap-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/hashmap/hashmap-lifetimes.rs new file mode 100644 index 000000000000..ba8f16850991 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hashmap/hashmap-lifetimes.rs @@ -0,0 +1,9 @@ +fn main() { + let mut my_stuff = std::collections::HashMap::new(); + my_stuff.insert(0, 42); + + let mut it = my_stuff.iter(); + my_stuff.insert(1, 43); // { dg-error ".E0502." "" { target *-*-* } } + it; +} + diff --git a/gcc/testsuite/rust/rustc/ui/hashmap/hashmap-memory.rs b/gcc/testsuite/rust/rustc/ui/hashmap/hashmap-memory.rs new file mode 100644 index 000000000000..866bd4283f36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hashmap/hashmap-memory.rs @@ -0,0 +1,95 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +#![allow(unused_mut)] +// ignore-emscripten No support for threads + +/** + A somewhat reduced test case to expose some Valgrind issues. + + This originally came from the word-count benchmark. +*/ + +pub fn map(filename: String, mut emit: map_reduce::putter) { + emit(filename, "1".to_string()); +} + +mod map_reduce { + use std::collections::HashMap; + use std::sync::mpsc::{channel, Sender}; + use std::str; + use std::thread; + + pub type putter<'a> = Box; + + pub type mapper = extern fn(String, putter); + + enum ctrl_proto { find_reducer(Vec, Sender), mapper_done, } + + fn start_mappers(ctrl: Sender, inputs: Vec) { + for i in &inputs { + let ctrl = ctrl.clone(); + let i = i.clone(); + thread::spawn(move|| map_task(ctrl.clone(), i.clone()) ); + } + } + + fn map_task(ctrl: Sender, input: String) { + let mut intermediates = HashMap::new(); + + fn emit(im: &mut HashMap, + ctrl: Sender, key: String, + _val: String) { + if im.contains_key(&key) { + return; + } + let (tx, rx) = channel(); + println!("sending find_reducer"); + ctrl.send(ctrl_proto::find_reducer(key.as_bytes().to_vec(), tx)).unwrap(); + println!("receiving"); + let c = rx.recv().unwrap(); + println!("{}", c); + im.insert(key, c); + } + + let ctrl_clone = ctrl.clone(); + ::map(input, Box::new(|a,b| emit(&mut intermediates, ctrl.clone(), a, b))); + ctrl_clone.send(ctrl_proto::mapper_done).unwrap(); + } + + pub fn map_reduce(inputs: Vec) { + let (tx, rx) = channel(); + + // This thread becomes the master control thread. It spawns others + // to do the rest. + + let mut reducers: HashMap; + + reducers = HashMap::new(); + + start_mappers(tx, inputs.clone()); + + let mut num_mappers = inputs.len() as isize; + + while num_mappers > 0 { + match rx.recv().unwrap() { + ctrl_proto::mapper_done => { num_mappers -= 1; } + ctrl_proto::find_reducer(k, cc) => { + let mut c; + match reducers.get(&str::from_utf8(&k).unwrap().to_string()) { + Some(&_c) => { c = _c; } + None => { c = 0; } + } + cc.send(c).unwrap(); + } + } + } + } +} + +pub fn main() { + map_reduce::map_reduce( + vec!["../src/test/run-pass/hashmap-memory.rs".to_string()]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hello.rs b/gcc/testsuite/rust/rustc/ui/hello.rs new file mode 100644 index 000000000000..8377e8396c97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hello.rs @@ -0,0 +1,6 @@ +// run-pass + +pub fn main() { + println!("hello, world"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hello_world/main.rs b/gcc/testsuite/rust/rustc/ui/hello_world/main.rs new file mode 100644 index 000000000000..b2c657e4ac6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hello_world/main.rs @@ -0,0 +1,8 @@ +// build-pass (FIXME(62277): could be check-pass?) + +// Test that compiling hello world succeeds with no output of any kind. + +fn main() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hidden-rt-injection.rs b/gcc/testsuite/rust/rustc/ui/hidden-rt-injection.rs new file mode 100644 index 000000000000..03383275a004 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hidden-rt-injection.rs @@ -0,0 +1,9 @@ +// This is testing that users can't access the runtime crate. + +mod m { + // The rt has been called both 'native' and 'rt' + use native; // { dg-error ".E0432." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/hidden-rt-injection2.rs b/gcc/testsuite/rust/rustc/ui/hidden-rt-injection2.rs new file mode 100644 index 000000000000..f59661323873 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hidden-rt-injection2.rs @@ -0,0 +1,9 @@ +// This is testing that users can't access the runtime crate. + +mod m { + // The rt has been called both 'native' and 'rt' + use rt; // { dg-error ".E0432." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/higher-lifetime-bounds.rs b/gcc/testsuite/rust/rustc/ui/higher-lifetime-bounds.rs new file mode 100644 index 000000000000..35ae3cb141b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-lifetime-bounds.rs @@ -0,0 +1,70 @@ +#![allow(dead_code, non_camel_case_types)] + +// Test that bounds on higher-kinded lifetime binders are rejected. + +fn bar1<'a, 'b>( + x: &'a i32, + y: &'b i32, + f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32) +// { dg-error "" "" { target *-*-* } .-1 } +{ + // If the bound in f's type would matter, the call below would (have to) + // be rejected. + f(x, y); +} + +fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>( +// { dg-error "" "" { target *-*-* } .-1 } + x: &'a i32, + y: &'b i32, + f: F) +{ + // If the bound in f's type would matter, the call below would (have to) + // be rejected. + f(x, y); +} + +fn bar3<'a, 'b, F>( + x: &'a i32, + y: &'b i32, + f: F) + where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32 +// { dg-error "" "" { target *-*-* } .-1 } +{ + // If the bound in f's type would matter, the call below would (have to) + // be rejected. + f(x, y); +} + +fn bar4<'a, 'b, F>( + x: &'a i32, + y: &'b i32, + f: F) + where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32 +// { dg-error "" "" { target *-*-* } .-1 } +{ + // If the bound in f's type would matter, the call below would (have to) + // be rejected. + f(x, y); +} + +struct S1 Fn(&'xa i32, &'xb i32) -> &'xa i32>(F); +// { dg-error "" "" { target *-*-* } .-1 } +struct S2(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32; +// { dg-error "" "" { target *-*-* } .-1 } +struct S3(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32; +// { dg-error "" "" { target *-*-* } .-1 } + +struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32); +// { dg-error "" "" { target *-*-* } .-1 } + +type T1 = Box Fn(&'xa i32, &'xb i32) -> &'xa i32>; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + let _ : Option fn(&'xa i32, &'xb i32) -> &'xa i32> = None; +// { dg-error "" "" { target *-*-* } .-1 } + let _ : Option Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs new file mode 100644 index 000000000000..562794354dec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-binder-levels-in-object-types.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test that we handle binder levels in object types correctly. +// Initially, the reference to `'tcx` in the object type +// `&Typer<'tcx>` was getting an incorrect binder level, yielding +// weird compilation ICEs and so forth. + +// pretty-expanded FIXME #23616 + +trait Typer<'tcx> { + fn method(&self, data: &'tcx isize) -> &'tcx isize { data } +} + +struct Tcx<'tcx> { + fields: &'tcx isize +} + +impl<'tcx> Typer<'tcx> for Tcx<'tcx> { +} + +fn g<'tcx>(typer: &dyn Typer<'tcx>) { +} + +fn check_static_type<'x>(tcx: &Tcx<'x>) { + g(tcx) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs new file mode 100644 index 000000000000..828348a022db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-debruijn-object-types-in-closures.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait Typer<'tcx> { + fn method(&self, data: &'tcx isize) -> &'tcx isize { data } + fn dummy(&self) { } +} + +fn g(_: F) where F: FnOnce(&dyn Typer) {} + +fn h() { + g(|typer| typer.dummy()) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs new file mode 100644 index 000000000000..05947c421420 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-fn-like-trait-object.rs @@ -0,0 +1,28 @@ +// run-pass +// A basic test of using a higher-ranked trait bound. + + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +type FnObject<'b> = dyn for<'a> FnLike<&'a isize, &'a isize> + 'b; + +struct Identity; + +impl<'a, T> FnLike<&'a T, &'a T> for Identity { + fn call(&self, arg: &'a T) -> &'a T { + arg + } +} + +fn call_repeatedly(f: &FnObject) { + let x = 3; + let y = f.call(&x); + assert_eq!(3, *y); +} + +fn main() { + call_repeatedly(&Identity); +} + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs new file mode 100644 index 000000000000..8d8caa3d3951 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-fn-like-trait.rs @@ -0,0 +1,28 @@ +// run-pass +// A basic test of using a higher-ranked trait bound. + + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +struct Identity; + +impl<'a, T> FnLike<&'a T, &'a T> for Identity { + fn call(&self, arg: &'a T) -> &'a T { + arg + } +} + +fn call_repeatedly(f: F) + where F : for<'a> FnLike<&'a isize, &'a isize> +{ + let x = 3; + let y = f.call(&x); + assert_eq!(3, *y); +} + +fn main() { + call_repeatedly(Identity); +} + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs new file mode 100644 index 000000000000..d80a71ceed14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-opt-in-copy.rs @@ -0,0 +1,29 @@ +// run-pass +// Test that we handle binder levels correctly when checking whether a +// type can implement `Copy`. In particular, we had a bug where we failed to +// liberate the late-bound regions from the impl, and thus wound up +// searching for an impl of `for<'tcx> Foo<&'tcx T>`. The impl that +// exists however is `impl Copy for Foo` and the current rules +// did not consider that a match (something I would like to revise in +// a later PR). + +#![allow(dead_code)] + +use std::marker::PhantomData; + +#[derive(Copy, Clone)] +struct Foo { x: T } + +type Ty<'tcx> = &'tcx TyS<'tcx>; + +enum TyS<'tcx> { + Boop(PhantomData<*mut &'tcx ()>) +} + +#[derive(Copy, Clone)] +enum Bar<'tcx> { + Baz(Foo>) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-parse.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-parse.rs new file mode 100644 index 000000000000..38e043163ecc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-parse.rs @@ -0,0 +1,37 @@ +// run-pass +// Test that we can parse all the various places that a `for` keyword +// can appear representing universal quantification. + +// pretty-expanded FIXME #23616 + +#![allow(unused_variables)] +#![allow(dead_code)] + +trait Get { + fn get(&self, arg: A) -> R; +} + +// Parse HRTB with explicit `for` in a where-clause: + +fn foo00(t: T) + where T : for<'a> Get<&'a i32, &'a i32> +{ +} + +fn foo01 Get<&'a i32, &'a i32>>(t: T) +{ +} + +// Parse HRTB with explicit `for` in various sorts of types: + +fn foo10(t: Box Get>) { } +fn foo11(t: Box Fn(i32) -> i32>) { } + +fn foo20(t: for<'a> fn(i32) -> i32) { } +fn foo21(t: for<'a> unsafe fn(i32) -> i32) { } +fn foo22(t: for<'a> extern "C" fn(i32) -> i32) { } +fn foo23(t: for<'a> unsafe extern "C" fn(i32) -> i32) { } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs new file mode 100644 index 000000000000..83193aa88f9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus-where-clause.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +// Test that `F : Fn(isize) -> isize + Send` is interpreted as two +// distinct bounds on `F`. + +fn foo1(f: F) + where F : FnOnce(isize) -> isize + Send +{ + bar(f); +} + +fn foo2(f: F) + where F : FnOnce(isize) -> isize + Send +{ + baz(f); +} + +fn bar(f: F) { } + +fn baz isize>(f: F) { } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs new file mode 100644 index 000000000000..c2aef8c5f767 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-precedence-of-plus.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +// Test that `Fn(isize) -> isize + 'static` parses as `(Fn(isize) -> isize) + +// 'static` and not `Fn(isize) -> (isize + 'static)`. The latter would +// cause a compilation error. Issue #18772. + +fn adder(y: isize) -> Box isize + 'static> { + Box::new(move |x| y + x) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs new file mode 100644 index 000000000000..64800e74d6a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-resolve-lifetime.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +// A basic test of using a higher-ranked trait bound. + +// pretty-expanded FIXME #23616 + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +type FnObject<'b> = dyn for<'a> FnLike<&'a isize, &'a isize> + 'b; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs new file mode 100644 index 000000000000..be8b5f84b279 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-trait-object-paren-notation.rs @@ -0,0 +1,27 @@ +// run-pass +// A basic test of using a higher-ranked trait bound. + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +type FnObject<'b> = dyn for<'a> FnLike<(&'a i32,), &'a i32> + 'b; + +struct Identity; + +impl<'a, T> FnLike<(&'a T,), &'a T> for Identity { + fn call(&self, (arg,): (&'a T,)) -> &'a T { + arg + } +} + +fn call_repeatedly(f: &FnObject) { + let x = 3; + let y = f.call((&x,)); + assert_eq!(3, *y); +} + +fn main() { + call_repeatedly(&Identity); +} + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs new file mode 100644 index 000000000000..748e2aaa9258 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-trait-object-passed-to-closure.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +// Test that `&PrinterSupport`, which is really short for `&'a +// PrinterSupport<'b>`, gets properly expanded when it appears in a +// closure type. This used to result in messed up De Bruijn indices. + +// pretty-expanded FIXME #23616 + +trait PrinterSupport<'ast> { + fn ast_map(&self) -> Option<&'ast usize> { None } +} + +struct NoAnn<'ast> { + f: Option<&'ast usize> +} + +impl<'ast> PrinterSupport<'ast> for NoAnn<'ast> { +} + +fn foo<'ast, G>(f: Option<&'ast usize>, g: G) where G: FnOnce(&dyn PrinterSupport) { + let annotation = NoAnn { f: f }; + g(&annotation) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs new file mode 100644 index 000000000000..4d85268d868a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs @@ -0,0 +1,47 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test what happens when a HR obligation is applied to an impl with +// "outlives" bounds. Currently we're pretty conservative here; this +// will probably improve in time. + +trait Foo { + fn foo(&self, x: X) { } +} + +fn want_foo() + where T : for<'a> Foo<&'a isize> +{ +} + +// Expressed as a where clause + +struct SomeStruct { + x: X +} + +impl<'a,X> Foo<&'a isize> for SomeStruct + where X : 'a +{ +} + +fn one() { + want_foo::>(); +} + +// Expressed as shorthand + +struct AnotherStruct { + x: X +} + +impl<'a,X:'a> Foo<&'a isize> for AnotherStruct +{ +} + +fn two() { + want_foo::>(); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs new file mode 100644 index 000000000000..9406529b70ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/hrtb-unboxed-closure-trait.rs @@ -0,0 +1,12 @@ +// run-pass +// Test HRTB used with the `Fn` trait. + +fn foo(f: F) { + let x = 22; + f(&x); +} + +fn main() { + foo(|x: &isize| println!("{}", *x)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/issue-59311.rs b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/issue-59311.rs new file mode 100644 index 000000000000..74347ebb7e60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/higher-rank-trait-bounds/issue-59311.rs @@ -0,0 +1,21 @@ +// Regression test for #59311. The test is taken from +// rust-lang/rust/issues/71546#issuecomment-620638437 +// as they seem to have the same cause. + +// FIXME: It's not clear that this code ought to report +// an error, but the regression test is here to ensure +// that it does not ICE. See discussion on #74889 for details. + +pub trait T { + fn t(&self, _: F) {} +} + +pub fn crash(v: &V) +where + for<'a> &'a V: T + 'static, +{ + v.t(|| {}); // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hr-subtype/hr-subtype.rs b/gcc/testsuite/rust/rustc/ui/hr-subtype/hr-subtype.rs new file mode 100644 index 000000000000..acd1ee7b496f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hr-subtype/hr-subtype.rs @@ -0,0 +1,113 @@ +// Targeted tests for the higher-ranked subtyping code. + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +// revisions: bound_a_vs_bound_a +// revisions: bound_a_vs_bound_b +// revisions: bound_inv_a_vs_bound_inv_b +// revisions: bound_co_a_vs_bound_co_b +// revisions: bound_a_vs_free_x +// revisions: free_x_vs_free_x +// revisions: free_x_vs_free_y +// revisions: free_inv_x_vs_free_inv_y +// revisions: bound_a_b_vs_bound_a +// revisions: bound_co_a_b_vs_bound_co_a +// revisions: bound_contra_a_contra_b_ret_co_a +// revisions: bound_co_a_co_b_ret_contra_a +// revisions: bound_inv_a_b_vs_bound_inv_a +// revisions: bound_a_b_ret_a_vs_bound_a_ret_a + +fn gimme(_: Option) {} + +struct Inv<'a> { + x: *mut &'a u32, +} + +struct Co<'a> { + x: fn(&'a u32), +} + +struct Contra<'a> { + x: &'a u32, +} + +macro_rules! check { + ($rev:ident: ($t1:ty, $t2:ty)) => { + #[cfg($rev)] + fn subtype<'x, 'y: 'x, 'z: 'y>() { + gimme::<$t2>(None::<$t1>); +// { dg-error "" "" { target *-*-* } .-1 } + } + + #[cfg($rev)] + fn supertype<'x, 'y: 'x, 'z: 'y>() { + gimme::<$t1>(None::<$t2>); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } + } + }; +} + +// If both have bound regions, they are equivalent, regardless of +// variant. +check! { bound_a_vs_bound_a: (for<'a> fn(&'a u32), +for<'a> fn(&'a u32)) } +check! { bound_a_vs_bound_b: (for<'a> fn(&'a u32), +for<'b> fn(&'b u32)) } +check! { bound_inv_a_vs_bound_inv_b: (for<'a> fn(Inv<'a>), +for<'b> fn(Inv<'b>)) } +check! { bound_co_a_vs_bound_co_b: (for<'a> fn(Co<'a>), +for<'b> fn(Co<'b>)) } + +// Bound is a subtype of free. +check! { bound_a_vs_free_x: (for<'a> fn(&'a u32), +fn(&'x u32)) } + +// Two free regions are relatable if subtyping holds. +check! { free_x_vs_free_x: (fn(&'x u32), +fn(&'x u32)) } +check! { free_x_vs_free_y: (fn(&'x u32), +fn(&'y u32)) } +check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), +fn(Inv<'y>)) } + +// Somewhat surprisingly, a fn taking two distinct bound lifetimes and +// a fn taking one bound lifetime can be interchangeable, but only if +// we are co- or contra-variant with respect to both lifetimes. +// +// The reason is: +// - if we are covariant, then 'a and 'b can be set to the call-site +// intersection; +// - if we are contravariant, then 'a can be inferred to 'static. +check! { bound_a_b_vs_bound_a: (for<'a,'b> fn(&'a u32, &'b u32), +for<'a> fn(&'a u32, &'a u32)) } +check! { bound_co_a_b_vs_bound_co_a: (for<'a,'b> fn(Co<'a>, Co<'b>), +for<'a> fn(Co<'a>, Co<'a>)) } +check! { bound_contra_a_contra_b_ret_co_a: (for<'a,'b> fn(Contra<'a>, Contra<'b>) -> Co<'a>, +for<'a> fn(Contra<'a>, Contra<'a>) -> Co<'a>) } +check! { bound_co_a_co_b_ret_contra_a: (for<'a,'b> fn(Co<'a>, Co<'b>) -> Contra<'a>, +for<'a> fn(Co<'a>, Co<'a>) -> Contra<'a>) } + +// If we make those lifetimes invariant, then the two types are not interchangeable. +check! { bound_inv_a_b_vs_bound_inv_a: (for<'a,'b> fn(Inv<'a>, Inv<'b>), +for<'a> fn(Inv<'a>, Inv<'a>)) } +check! { bound_a_b_ret_a_vs_bound_a_ret_a: (for<'a,'b> fn(&'a u32, &'b u32) -> &'a u32, +for<'a> fn(&'a u32, &'a u32) -> &'a u32) } + +#[rustc_error] +fn main() { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-error "" "" { target *-*-* } .-6 } +// { dg-error "" "" { target *-*-* } .-7 } +// { dg-error "" "" { target *-*-* } .-8 } +// { dg-error "" "" { target *-*-* } .-9 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hr-subtype/return-static.rs b/gcc/testsuite/rust/rustc/ui/hr-subtype/return-static.rs new file mode 100644 index 000000000000..016afea72689 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hr-subtype/return-static.rs @@ -0,0 +1,14 @@ +// check-pass + +fn make() -> T { + panic!() +} + +fn take(x: T) {} + +fn main() { + let x: for<'a> fn(&'a u32) -> _ = make(); + let y: &'static u32 = x(&22); + take:: fn(&'b u32) -> &'b u32>(x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/due-to-where-clause.rs b/gcc/testsuite/rust/rustc/ui/hrtb/due-to-where-clause.rs new file mode 100644 index 000000000000..a83d5dcd9b82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/due-to-where-clause.rs @@ -0,0 +1,14 @@ +fn main() { + test::(&mut 42); // { dg-error "" "" { target *-*-* } } +} + +trait Foo<'a> {} + +struct FooS<'a> { + data: &'a mut u32, +} + +impl<'a, 'b: 'a> Foo<'b> for FooS<'a> {} + +fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-cache-issue-54302.rs b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-cache-issue-54302.rs new file mode 100644 index 000000000000..4fc9e9dcad03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-cache-issue-54302.rs @@ -0,0 +1,25 @@ +// Regression test for #54302. +// +// We were incorrectly using the "evaluation cache" (which ignored +// region results) to conclude that `&'static str: Deserialize`, even +// though it would require that `for<'de> 'de: 'static`, which is +// clearly false. + +trait Deserialize<'de> {} + +trait DeserializeOwned: for<'de> Deserialize<'de> {} +impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} + +// Based on this impl, `&'static str` only implements Deserialize<'static>. +// It does not implement for<'de> Deserialize<'de>. +impl<'de: 'a, 'a> Deserialize<'de> for &'a str {} + +fn main() { + fn assert_deserialize_owned() {} + assert_deserialize_owned::<&'static str>(); // { dg-error "" "" { target *-*-* } } + + // It correctly does not implement for<'de> Deserialize<'de>. + // fn assert_hrtb Deserialize<'de>>() {} + // assert_hrtb::<&'static str>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-conflate-regions.rs b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-conflate-regions.rs new file mode 100644 index 000000000000..55fe12a4c7b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-conflate-regions.rs @@ -0,0 +1,30 @@ +// Test that an impl with only one bound region `'a` cannot be used to +// satisfy a constraint where there are two bound regions. + +trait Foo { + fn foo(&self, x: X) { } +} + +fn want_foo2() + where T : for<'a,'b> Foo<(&'a isize, &'b isize)> +{ +} + +fn want_foo1() + where T : for<'z> Foo<(&'z isize, &'z isize)> +{ +} + +// Expressed as a where clause + +struct SomeStruct; + +impl<'a> Foo<(&'a isize, &'a isize)> for SomeStruct +{ +} + +fn a() { want_foo1::(); } // OK -- foo wants just one region +fn b() { want_foo2::(); } // { dg-error "" "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-debruijn-in-receiver.rs b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-debruijn-in-receiver.rs new file mode 100644 index 000000000000..ed22f09234bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-debruijn-in-receiver.rs @@ -0,0 +1,19 @@ +// Test the case where the `Self` type has a bound lifetime that must +// be adjusted in the fn signature. Issue #19537. + +use std::collections::HashMap; + +struct Foo<'a> { + map: HashMap +} + +impl<'a> Foo<'a> { + fn new() -> Foo<'a> { panic!() } + fn insert(&'a mut self) { } +} +fn main() { + let mut foo = Foo::new(); + foo.insert(); + foo.insert(); // { dg-error ".E0499." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-fn.rs b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-fn.rs new file mode 100644 index 000000000000..14aa4ab536f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-fn.rs @@ -0,0 +1,19 @@ +// Test a `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile! +// +// In particular, we test this pattern in trait solving, where it is not connected +// to any part of the source code. + +fn foo<'a>() -> fn(&'a u32) { + panic!() +} + +fn main() { + // Here, proving that `fn(&'a u32) <: for<'b> fn(&'b u32)`: + // + // - instantiates `'b` with a placeholder `!b`, + // - requires that `&!b u32 <: &'a u32` and hence that `!b: 'a`, + // - but we can never know this. + + let _: for<'b> fn(&'b u32) = foo(); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs new file mode 100644 index 000000000000..1cb31721b00e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-trait-contravariant.rs @@ -0,0 +1,37 @@ +// Test a case where variance and higher-ranked types interact in surprising ways. +// +// In particular, we test this pattern in trait solving, where it is not connected +// to any part of the source code. + +trait Trait {} + +fn foo() +where + T: Trait fn(&'b u32)>, +{ +} + +impl<'a> Trait for () {} + +fn main() { + // Here, proving that `(): Trait fn(&'b u32)>` uses the impl: + // + // - The impl provides the clause `forall<'a> { (): Trait }` + // - We instantiate `'a` existentially to get `(): Trait` + // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)` -- this does a + // "bidirectional" subtyping check, so we wind up with: + // - `fn(&?a u32) <: for<'b> fn(&'b u32)` :- + // - `&'!b u32 <: &?a u32` + // - `!'b: ?a` -- solveable if `?a` is inferred to `'empty` + // - `for<'b> fn(&'b u32) <: fn(&?a u32)` :- + // - `&?a u32 u32 <: &?b u32` + // - `?a: ?b` -- solveable if `?b` is also inferred to `'empty` + // - So the subtyping check succeeds, somewhat surprisingly. + // This is because we can use `'empty`. + // + // NB. *However*, the reinstated leak-check gives an error here. + + foo::<()>(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-trait-covariant.rs b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-trait-covariant.rs new file mode 100644 index 000000000000..652919b44920 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-trait-covariant.rs @@ -0,0 +1,38 @@ +// Test a case where variance and higher-ranked types interact in surprising ways. +// +// In particular, we test this pattern in trait solving, where it is not connected +// to any part of the source code. +// +// check-pass + +trait Trait {} + +fn foo() +where + T: Trait fn(fn(&'b u32))>, +{ +} + +impl<'a> Trait for () {} + +fn main() { + // Here, proving that `(): Trait fn(&'b u32)>` uses the impl: + // + // - The impl provides the clause `forall<'a> { (): Trait }` + // - We instantiate `'a` existentially to get `(): Trait` + // - We unify `fn(fn(&?a u32))` with `for<'b> fn(fn(&'b u32))` -- this does a + // "bidirectional" subtyping check, so we wind up with: + // - `fn(fn(&?a u32)) <: for<'b> fn(fn(&'b u32))` :- + // - `fn(&!b u32) <: fn(&?a u32)` + // - `&?a u32 <: &!b u32` + // - `?a: !'b` -- solveable if `?a` is inferred to `'static` + // - `for<'b> fn(fn(&'b u32)) <: fn(fn(&?a u32))` :- + // - `fn(&?a u32) <: fn(&?b u32)` + // - `&?b u32 <: &?a u32` + // - `?b: ?a` -- solveable if `?b` is inferred to `'static` + // - So the subtyping check succeeds, somewhat surprisingly. + // This is because we can use `'static`. + + foo::<()>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-trait-invariant.rs b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-trait-invariant.rs new file mode 100644 index 000000000000..4e13417b152c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-exists-forall-trait-invariant.rs @@ -0,0 +1,30 @@ +// Test a `exists<'a> { forall<'b> { 'a = 'b } }` pattern -- which should not compile! +// +// In particular, we test this pattern in trait solving, where it is not connected +// to any part of the source code. + +use std::cell::Cell; + +trait Trait {} + +fn foo() +where + T: Trait fn(Cell<&'b u32>)>, +{ +} + +impl<'a> Trait)> for () {} + +fn main() { + // Here, proving that `(): Trait fn(&'b u32)>` uses the impl: + // + // - The impl provides the clause `forall<'a> { (): Trait }` + // - We instantiate `'a` existentially to get `(): Trait` + // - We unify `fn(&?a u32)` with `for<'b> fn(&'b u32)` + // - This requires (among other things) instantiating `'b` universally, + // yielding `fn(&!b u32)`, in a fresh universe U1 + // - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`. + + foo::<()>(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.rs b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.rs new file mode 100644 index 000000000000..806b91219cd9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.rs @@ -0,0 +1,51 @@ +// Test HRTB supertraits with several levels of expansion required. + +trait Foo<'tcx> +{ + fn foo(&'tcx self) -> &'tcx isize; +} + +trait Bar<'ccx> + : for<'tcx> Foo<'tcx> +{ + fn bar(&'ccx self) -> &'ccx isize; +} + +trait Baz + : for<'ccx> Bar<'ccx> +{ + fn dummy(&self); +} + +trait Qux + : Bar<'static> +{ + fn dummy(&self); +} + +fn want_foo_for_any_tcx(f: &F) + where F : for<'tcx> Foo<'tcx> +{ +} + +fn want_bar_for_any_ccx(b: &B) + where B : for<'ccx> Bar<'ccx> +{ +} + +fn want_baz(b: &B) + where B : Baz +{ + want_foo_for_any_tcx(b); + want_bar_for_any_ccx(b); +} + +fn want_qux(b: &B) + where B : Qux +{ + want_foo_for_any_tcx(b); + want_bar_for_any_ccx(b); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-higher-ranker-supertraits.rs b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-higher-ranker-supertraits.rs new file mode 100644 index 000000000000..a80a26619e30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-higher-ranker-supertraits.rs @@ -0,0 +1,49 @@ +// Test a trait (`Bar`) with a higher-ranked supertrait. + +trait Foo<'tcx> +{ + fn foo(&'tcx self) -> &'tcx isize; +} + +trait Bar<'ccx> + : for<'tcx> Foo<'tcx> +{ + fn bar(&'ccx self) -> &'ccx isize; +} + +fn want_foo_for_some_tcx<'x,F>(f: &'x F) + where F : Foo<'x> +{ + want_foo_for_some_tcx(f); + want_foo_for_any_tcx(f); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn want_foo_for_any_tcx(f: &F) + where F : for<'tcx> Foo<'tcx> +{ + want_foo_for_some_tcx(f); + want_foo_for_any_tcx(f); +} + +fn want_bar_for_some_ccx<'x,B>(b: &B) + where B : Bar<'x> +{ + want_foo_for_some_tcx(b); + want_foo_for_any_tcx(b); + + want_bar_for_some_ccx(b); + want_bar_for_any_ccx(b); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn want_bar_for_any_ccx(b: &B) + where B : for<'ccx> Bar<'ccx> +{ + want_foo_for_some_tcx(b); + want_foo_for_any_tcx(b); + + want_bar_for_some_ccx(b); + want_bar_for_any_ccx(b); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-identity-fn-borrows.rs b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-identity-fn-borrows.rs new file mode 100644 index 000000000000..0c29116dccd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-identity-fn-borrows.rs @@ -0,0 +1,27 @@ +// Test that the `'a` in the where clause correctly links the region +// of the output to the region of the input. + +trait FnLike { + fn call(&self, arg: A) -> R; +} + +fn call_repeatedly(f: F) + where F : for<'a> FnLike<&'a isize, &'a isize> +{ + // Result is stored: cannot re-assign `x` + let mut x = 3; + let y = f.call(&x); + x = 5; // { dg-error ".E0506." "" { target *-*-* } } + + // Result is not stored: can re-assign `x` + let mut x = 3; + f.call(&x); + f.call(&x); + f.call(&x); + x = 5; + drop(y); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-just-for-static.rs b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-just-for-static.rs new file mode 100644 index 000000000000..4a2377289339 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-just-for-static.rs @@ -0,0 +1,34 @@ +// Test a case where you have an impl of `Foo` for all `X` that +// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730. + +trait Foo { + fn foo(&self, x: X) { } +} + +fn want_hrtb() + where T : for<'a> Foo<&'a isize> +{ +} + +// AnyInt implements Foo<&'a isize> for any 'a, so it is a match. +struct AnyInt; +impl<'a> Foo<&'a isize> for AnyInt { } +fn give_any() { + want_hrtb::() +} + +// StaticInt only implements Foo<&'static isize>, so it is an error. +struct StaticInt; +impl Foo<&'static isize> for StaticInt { } +fn give_static() { + want_hrtb::() // { dg-error "" "" { target *-*-* } } +} + +// AnyInt implements Foo<&'a isize> for any 'a, so it is a match. +impl<'a> Foo<&'a isize> for &'a u32 { } +fn give_some<'a>() { + want_hrtb::<&'a u32>() // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-perfect-forwarding.rs b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-perfect-forwarding.rs new file mode 100644 index 000000000000..bd1b7aa1242a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/hrtb-perfect-forwarding.rs @@ -0,0 +1,58 @@ +// Test a case where you have an impl of `Foo` for all `X` that +// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730. + +trait Foo { + fn foo(&mut self, x: X) { } +} + +trait Bar { + fn bar(&mut self, x: X) { } +} + +impl<'a,X,F> Foo for &'a mut F + where F : Foo + Bar +{ +} + +impl<'a,X,F> Bar for &'a mut F + where F : Bar +{ +} + +fn no_hrtb<'b,T>(mut t: T) + where T : Bar<&'b isize> +{ + // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that + // `&mut T : Bar<&'b isize>`. + no_hrtb(&mut t); +} + +fn bar_hrtb(mut t: T) + where T : for<'b> Bar<&'b isize> +{ + // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above + // ensures that `&mut T : for<'b> Bar<&'b isize>`. This is an + // example of a "perfect forwarding" impl. + bar_hrtb(&mut t); +} + +fn foo_hrtb_bar_not<'b,T>(mut t: T) + where T : for<'a> Foo<&'a isize> + Bar<&'b isize> +{ + // Not OK -- The forwarding impl for `Foo` requires that `Bar` also + // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a + // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where + // clause only specifies `T : Bar<&'b isize>`. + foo_hrtb_bar_not(&mut t); // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn foo_hrtb_bar_hrtb(mut t: T) + where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize> +{ + // OK -- now we have `T : for<'b> Bar&'b isize>`. + foo_hrtb_bar_hrtb(&mut t); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/issue-30786.rs b/gcc/testsuite/rust/rustc/ui/hrtb/issue-30786.rs new file mode 100644 index 000000000000..21420a6ef087 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/issue-30786.rs @@ -0,0 +1,147 @@ +// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream Option; +} + +// Example stream +pub struct Repeat(u64); + +impl<'a> Stream for &'a mut Repeat { + type Item = &'a u64; + fn next(self) -> Option { + Some(&self.0) + } +} + +pub struct Map { + stream: S, + func: F, +} + +impl<'a, A, F, T> Stream for &'a mut Map +where + &'a mut A: Stream, + F: FnMut(<&'a mut A as Stream>::Item) -> T, +{ + type Item = T; + fn next(self) -> Option { + match self.stream.next() { + Some(item) => Some((self.func)(item)), + None => None, + } + } +} + +pub struct Filter { + stream: S, + func: F, +} + +impl<'a, A, F, T> Stream for &'a mut Filter +where + for<'b> &'b mut A: Stream, // <---- BAD + F: FnMut(&T) -> bool, +{ + type Item = <&'a mut A as Stream>::Item; + fn next(self) -> Option { + while let Some(item) = self.stream.next() { + if (self.func)(&item) { + return Some(item); + } + } + None + } +} + +pub trait StreamExt +where + for<'b> &'b mut Self: Stream, +{ + fn mapx(self, func: F) -> Map + where + Self: Sized, + for<'a> &'a mut Map: Stream, + { + Map { func: func, stream: self } + } + + fn filterx(self, func: F) -> Filter + where + Self: Sized, + for<'a> &'a mut Filter: Stream, + { + Filter { func: func, stream: self } + } + + fn countx(mut self) -> usize + where + Self: Sized, + { + let mut count = 0; + while let Some(_) = self.next() { + count += 1; + } + count + } +} + +impl StreamExt for T where for<'a> &'a mut T: Stream {} + +fn identity(x: &T) -> &T { + x +} + +fn variant1() { + let source = Repeat(10); + + // Here, the call to `mapx` returns a type `T` to which `StreamExt` + // is not applicable, because `for<'b> &'b mut T: Stream`) doesn't hold. + // + // More concretely, the type `T` is `Map`, and + // the where clause doesn't hold because the signature of the + // closure gets inferred to a signature like `|&'_ Stream| -> &'_` + // for some specific `'_`, rather than a more generic + // signature. + // + // Why *exactly* we opt for this signature is a bit unclear to me, + // we deduce it somehow from a reuqirement that `Map: Stream` I + // guess. + let map = source.mapx(|x: &_| x); + let filter = map.filterx(|x: &_| true); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn variant2() { + let source = Repeat(10); + + // Here, we use a function, which is not subject to the vagaries + // of closure signature inference. In this case, we get the error + // on `countx` as, I think, the test originally expected. + let map = source.mapx(identity); + let filter = map.filterx(|x: &_| true); + let count = filter.countx(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/issue-46989.rs b/gcc/testsuite/rust/rustc/ui/hrtb/issue-46989.rs new file mode 100644 index 000000000000..f75034f2e1fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/issue-46989.rs @@ -0,0 +1,41 @@ +// Regression test for #46989: +// +// In the move to universes, this test started passing. +// It is not necessarily WRONG to do so, but it was a bit +// surprising. The reason that it passed is that when we were +// asked to prove that +// +// for<'a> fn(&'a i32): Foo +// +// we were able to use the impl below to prove +// +// fn(&'empty i32): Foo +// +// and then we were able to prove that +// +// fn(&'empty i32) = for<'a> fn(&'a i32) +// +// This last fact is somewhat surprising, but essentially "falls out" +// from handling variance correctly. In particular, consider the subtyping +// relations. First: +// +// fn(&'empty i32) <: for<'a> fn(&'a i32) +// +// This holds because -- intuitively -- a fn that takes a reference but doesn't use +// it can be given a reference with any lifetime. Similarly, the opposite direction: +// +// for<'a> fn(&'a i32) <: fn(&'empty i32) +// +// holds because 'a can be instantiated to 'empty. + +trait Foo {} + +impl Foo for fn(A) {} + +fn assert_foo() {} + +fn main() { + assert_foo::(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/issue-57639.rs b/gcc/testsuite/rust/rustc/ui/hrtb/issue-57639.rs new file mode 100644 index 000000000000..7c29622dd84e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/issue-57639.rs @@ -0,0 +1,30 @@ +// Regression test for #57639: +// +// In the move to universes, this test stopped working. The problem +// was that when the trait solver was asked to prove `for<'a> T::Item: +// Foo<'a>` as part of WF checking, it wound up "eagerly committing" +// to the where clause, which says that `T::Item: Foo<'a>`, but it +// should instead have been using the bound found in the trait +// declaration. Pre-universe, this used to work out ok because we got +// "eager errors" due to the leak check. +// +// See [this comment on GitHub][c] for more details. +// +// check-pass +// +// [c]: https://github.com/rust-lang/rust/issues/57639#issuecomment-455685861 + +trait Foo<'a> {} + +trait Bar { + type Item: for<'a> Foo<'a>; +} + +fn foo<'a, T>(_: T) +where + T: Bar, + T::Item: Foo<'a>, +{} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/issue-58451.rs b/gcc/testsuite/rust/rustc/ui/hrtb/issue-58451.rs new file mode 100644 index 000000000000..e676f03b8927 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/issue-58451.rs @@ -0,0 +1,14 @@ +// Regression test for #58451: +// +// Error reporting here encountered an ICE in the shift to universes. + +fn f(i: I) +where + I: IntoIterator, + I::Item: for<'a> Into<&'a ()>, +{} + +fn main() { + f(&[f()]); // { dg-error ".E0061." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hrtb/issue-62203-hrtb-ice.rs b/gcc/testsuite/rust/rustc/ui/hrtb/issue-62203-hrtb-ice.rs new file mode 100644 index 000000000000..7179049bd282 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hrtb/issue-62203-hrtb-ice.rs @@ -0,0 +1,51 @@ +trait T0<'a, A> { + type O; +} + +struct L { + f: T, +} + +// explicitly named variants of what one would normally denote by the +// unit type `()`. Why do this? So that we can differentiate them in +// the diagnostic output. +struct Unit1; +struct Unit2; +struct Unit3; +struct Unit4; + +impl<'a, A, T> T0<'a, A> for L +where + T: FnMut(A) -> Unit3, +{ + type O = T::Output; +} + +trait T1: for<'r> Ty<'r> { + fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1 + where + F: for<'r> T0<'r, (>::V,), O = >::V>, + { + unimplemented!(); + } +} + +trait Ty<'a> { + type V; +} + +fn main() { + let v = Unit2.m( +// { dg-error ".E0271." "" { target *-*-* } .-1 } +// { dg-error ".E0271." "" { target *-*-* } .-2 } + L { + f : |x| { drop(x); Unit4 } + }); +} + +impl<'a> Ty<'a> for Unit2 { + type V = &'a u8; +} + +impl T1 for Unit2 {} + diff --git a/gcc/testsuite/rust/rustc/ui/html-literals.rs b/gcc/testsuite/rust/rustc/ui/html-literals.rs new file mode 100644 index 000000000000..94bbf8fcfd9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/html-literals.rs @@ -0,0 +1,95 @@ +// run-pass + +#![allow(non_camel_case_types)] +// A test of the macro system. Can we do HTML literals? + +/* + +This is an HTML parser written as a macro. It's all CPS, and we have +to carry around a bunch of state. The arguments to macros all look like this: + +{ tag_stack* # expr* # tokens } + +The stack keeps track of where we are in the tree. The expr is a list +of children of the current node. The tokens are everything that's +left. + +*/ +use HTMLFragment::{tag, text}; + +macro_rules! html { + ( $($body:tt)* ) => ( + parse_node!( []; []; $($body)* ) + ) +} + +macro_rules! parse_node { + ( + [:$head:ident ($(:$head_nodes:expr),*) + $(:$tags:ident ($(:$tag_nodes:expr),*))*]; + [$(:$nodes:expr),*]; + $($rest:tt)* + ) => ( + parse_node!( + [$(: $tags ($(:$tag_nodes),*))*]; + [$(:$head_nodes,)* :tag(stringify!($head).to_string(), + vec![$($nodes),*])]; + $($rest)* + ) + ); + + ( + [$(:$tags:ident ($(:$tag_nodes:expr),*) )*]; + [$(:$nodes:expr),*]; + <$tag:ident> $($rest:tt)* + ) => ( + parse_node!( + [:$tag ($(:$nodes)*) $(: $tags ($(:$tag_nodes),*) )*]; + []; + $($rest)* + ) + ); + + ( + [$(:$tags:ident ($(:$tag_nodes:expr),*) )*]; + [$(:$nodes:expr),*]; + . $($rest:tt)* + ) => ( + parse_node!( + [$(: $tags ($(:$tag_nodes),*))*]; + [$(:$nodes,)* :text(".".to_string())]; + $($rest)* + ) + ); + + ( + [$(:$tags:ident ($(:$tag_nodes:expr),*) )*]; + [$(:$nodes:expr),*]; + $word:ident $($rest:tt)* + ) => ( + parse_node!( + [$(: $tags ($(:$tag_nodes),*))*]; + [$(:$nodes,)* :text(stringify!($word).to_string())]; + $($rest)* + ) + ); + + ( []; [:$e:expr]; ) => ( $e ); +} + +pub fn main() { + let _page = html! ( + + This is the title. + +

This is some text

+ + + ); +} + +enum HTMLFragment { + tag(String, Vec ), + text(String), +} + diff --git a/gcc/testsuite/rust/rustc/ui/huge-array-simple-32.rs b/gcc/testsuite/rust/rustc/ui/huge-array-simple-32.rs new file mode 100644 index 000000000000..c31c5c2837a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/huge-array-simple-32.rs @@ -0,0 +1,13 @@ +// ignore-64bit +// build-fail + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +#![allow(arithmetic_overflow)] + +fn main() { + let _fat: [u8; (1<<31)+(1<<15)] = // { dg-error "" "" { target *-*-* } } + [0; (1u32<<31) as usize +(1u32<<15) as usize]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/huge-array-simple-64.rs b/gcc/testsuite/rust/rustc/ui/huge-array-simple-64.rs new file mode 100644 index 000000000000..b5ed5441c691 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/huge-array-simple-64.rs @@ -0,0 +1,13 @@ +// build-fail +// ignore-32bit + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +#![allow(arithmetic_overflow)] + +fn main() { + let _fat: [u8; (1<<61)+(1<<31)] = // { dg-error "" "" { target *-*-* } } + [0; (1u64<<61) as usize +(1u64<<31) as usize]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/huge-array.rs b/gcc/testsuite/rust/rustc/ui/huge-array.rs new file mode 100644 index 000000000000..658dad21f162 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/huge-array.rs @@ -0,0 +1,16 @@ +// FIXME https://github.com/rust-lang/rust/issues/59774 + +// build-fail +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" + +fn generic(t: T) { + let s: [T; 1518600000] = [t; 1518600000]; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + let x: [u8; 1518599999] = [0; 1518599999]; + generic::<[u8; 1518599999]>(x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/huge-enum.rs b/gcc/testsuite/rust/rustc/ui/huge-enum.rs new file mode 100644 index 000000000000..8d47cc1536aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/huge-enum.rs @@ -0,0 +1,19 @@ +// build-fail +// normalize-stderr-test "std::option::Option<\[u32; \d+\]>" -> "TYPE" +// normalize-stderr-test "\[u32; \d+\]" -> "TYPE" + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" + +#[cfg(target_pointer_width = "32")] +type BIG = Option<[u32; (1<<29)-1]>; + +#[cfg(target_pointer_width = "64")] +type BIG = Option<[u32; (1<<45)-1]>; + +fn main() { + let big: BIG = None; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/huge-struct.rs b/gcc/testsuite/rust/rustc/ui/huge-struct.rs new file mode 100644 index 000000000000..33b2b3591421 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/huge-struct.rs @@ -0,0 +1,54 @@ +// build-fail +// normalize-stderr-test "S32" -> "SXX" +// normalize-stderr-test "S1M" -> "SXX" +// error-pattern: too big for the current + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" + +struct S32 { + v0: T, + v1: T, + v2: T, + v3: T, + v4: T, + v5: T, + v6: T, + v7: T, + v8: T, + u9: T, + v10: T, + v11: T, + v12: T, + v13: T, + v14: T, + v15: T, + v16: T, + v17: T, + v18: T, + v19: T, + v20: T, + v21: T, + v22: T, + v23: T, + v24: T, + u25: T, + v26: T, + v27: T, + v28: T, + v29: T, + v30: T, + v31: T, +} + +struct S1k { val: S32> } + +struct S1M { val: S1k> } + +fn main() { + let fat: Option>>> = None; +// { dg-error "" "" { target *-*-* } .-1 } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/arguments.rs b/gcc/testsuite/rust/rustc/ui/hygiene/arguments.rs new file mode 100644 index 000000000000..d54ef2b6c5c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/arguments.rs @@ -0,0 +1,18 @@ +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro)] + +macro m($t:ty, $e:expr) { + mod foo { + #[allow(unused)] + struct S; + pub(super) fn f(_: $t) {} + } + foo::f($e); +} + +fn main() { + struct S; + m!(S, S); // { dg-error ".E0412." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/assoc_item_ctxt.rs b/gcc/testsuite/rust/rustc/ui/hygiene/assoc_item_ctxt.rs new file mode 100644 index 000000000000..8ef97afe35df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/assoc_item_ctxt.rs @@ -0,0 +1,43 @@ +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro)] +#![allow(unused)] + +mod ok { + macro mac_trait_item($method: ident) { + fn $method(); + } + + trait Tr { + mac_trait_item!(method); + } + + macro mac_trait_impl() { + impl Tr for u8 { // OK + fn method() {} // OK + } + } + + mac_trait_impl!(); +} + +mod error { + macro mac_trait_item() { + fn method(); + } + + trait Tr { + mac_trait_item!(); + } + + macro mac_trait_impl() { + impl Tr for u8 { // { dg-error ".E0046." "" { target *-*-* } } + fn method() {} // { dg-error ".E0407." "" { target *-*-* } } + } + } + + mac_trait_impl!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/assoc_ty_bindings.rs b/gcc/testsuite/rust/rustc/ui/hygiene/assoc_ty_bindings.rs new file mode 100644 index 000000000000..333f121dfdb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/assoc_ty_bindings.rs @@ -0,0 +1,39 @@ +// check-pass +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro, associated_type_defaults)] + +trait Base { + type AssocTy; + fn f(); +} +trait Derived: Base { + fn g(); +} + +macro mac() { + type A = dyn Base; + type B = dyn Derived; + + impl Base for u8 { + type AssocTy = u8; + fn f() { + let _: Self::AssocTy; + } + } + impl Derived for u8 { + fn g() { + let _: Self::AssocTy; + } + } + + fn h() { + let _: T::AssocTy; + let _: U::AssocTy; + } +} + +mac!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/codegen-attrs.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/codegen-attrs.rs new file mode 100644 index 000000000000..756242a15644 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/codegen-attrs.rs @@ -0,0 +1,11 @@ +#![feature(decl_macro)] + +macro m($f:ident) { + #[export_name = "export_function_name"] + pub fn $f() -> i32 { + 2 + } +} + +m!(rust_function_name); + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/def-site-async-await.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/def-site-async-await.rs new file mode 100644 index 000000000000..c4dee1877a50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/def-site-async-await.rs @@ -0,0 +1,8 @@ +// edition:2018 + +extern crate opaque_hygiene; + +pub async fn serve() { + opaque_hygiene::make_it!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/intercrate.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/intercrate.rs new file mode 100644 index 000000000000..22fd750c0313 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/intercrate.rs @@ -0,0 +1,47 @@ +#![feature(decl_macro)] + +pub mod foo { + pub use self::bar::m; + mod bar { + fn f() -> u32 { 1 } + pub macro m() { + f(); + } + } +} + +pub struct SomeType; + +// `$crate` +pub macro uses_dollar_crate_modern() { + type Alias = $crate::SomeType; +} + +pub macro define_uses_dollar_crate_modern_nested($uses_dollar_crate_modern_nested: ident) { + macro $uses_dollar_crate_modern_nested() { + type AliasCrateModernNested = $crate::SomeType; + } +} + +#[macro_export] +macro_rules! define_uses_dollar_crate_legacy_nested { + () => { + macro_rules! uses_dollar_crate_legacy_nested { + () => { + type AliasLegacyNested = $crate::SomeType; + } + } + } +} + +// `crate` +pub macro uses_crate_modern() { + type AliasCrate = crate::SomeType; +} + +pub macro define_uses_crate_modern_nested($uses_crate_modern_nested: ident) { + macro $uses_crate_modern_nested() { + type AliasCrateModernNested = crate::SomeType; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/legacy_interaction.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/legacy_interaction.rs new file mode 100644 index 000000000000..ef2e1bfcb938 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/legacy_interaction.rs @@ -0,0 +1,10 @@ +// ignore-pretty pretty-printing is unhygienic + +#[macro_export] +macro_rules! m { + () => { + fn f() {} // (2) + g(); // (1) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/local_inner_macros.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/local_inner_macros.rs new file mode 100644 index 000000000000..dbdb77107f66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/local_inner_macros.rs @@ -0,0 +1,20 @@ +#[macro_export] +macro_rules! helper1 { + () => ( struct S; ) +} + +#[macro_export(local_inner_macros)] +macro_rules! helper2 { + () => ( helper1!(); ) +} + +#[macro_export(local_inner_macros)] +macro_rules! public_macro { + () => ( helper2!(); ) +} + +#[macro_export(local_inner_macros)] +macro_rules! public_macro_dynamic { + ($helper: ident) => ( $helper!(); ) +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/my_crate.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/my_crate.rs new file mode 100644 index 000000000000..530da9f56703 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/my_crate.rs @@ -0,0 +1,2 @@ +pub fn f() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/needs_hygiene.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/needs_hygiene.rs new file mode 100644 index 000000000000..fad09777a4e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/needs_hygiene.rs @@ -0,0 +1,6 @@ +#![feature(decl_macro)] +macro x() { struct MyStruct; } + +x!(); +x!(); + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/nested-dollar-crate.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/nested-dollar-crate.rs new file mode 100644 index 000000000000..ecf7406f8ef6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/nested-dollar-crate.rs @@ -0,0 +1,15 @@ +pub const IN_DEF_CRATE: &str = "In def crate!"; + +macro_rules! make_it { + () => { + #[macro_export] + macro_rules! inner { + () => { + $crate::IN_DEF_CRATE + } + } + } +} + +make_it!(); + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/not-libstd.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/not-libstd.rs new file mode 100644 index 000000000000..bf174de6a404 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/not-libstd.rs @@ -0,0 +1,2 @@ +pub fn not_in_lib_std() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/opaque-hygiene.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/opaque-hygiene.rs new file mode 100644 index 000000000000..f09ed4990b93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/opaque-hygiene.rs @@ -0,0 +1,22 @@ +// force-host +// no-prefer-dynamic + +#![feature(proc_macro_quote)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::{TokenStream, quote}; + +#[proc_macro] +pub fn make_it(input: TokenStream) -> TokenStream { + // `quote!` applies def-site hygiene + quote! { + trait Foo { + fn my_fn(&self) {} + } + + impl Foo for T {} + "a".my_fn(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/stdlib-prelude.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/stdlib-prelude.rs new file mode 100644 index 000000000000..c1d5e2a58271 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/stdlib-prelude.rs @@ -0,0 +1,4 @@ +#![feature(decl_macro)] + +pub macro stdlib_macro() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/transparent-basic.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/transparent-basic.rs new file mode 100644 index 000000000000..19f0a3493a88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/transparent-basic.rs @@ -0,0 +1,7 @@ +#![feature(decl_macro, rustc_attrs)] + +#[rustc_macro_transparency = "transparent"] +pub macro dollar_crate() { + let s = $crate::S; +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/unhygienic_example.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/unhygienic_example.rs new file mode 100644 index 000000000000..80bf8e4870b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/unhygienic_example.rs @@ -0,0 +1,28 @@ +#![crate_type = "lib"] + +extern crate my_crate; + +pub fn g() {} // (a) + +#[macro_export] +macro_rules! unhygienic_macro { + () => { + // (1) unhygienic: depends on `my_crate` in the crate root at the invocation site. + ::my_crate::f(); + + // (2) unhygienic: defines `f` at the invocation site (in addition to the above point). + use my_crate::f; + f(); + + g(); // (3) unhygienic: `g` needs to be in scope at use site. + + $crate::g(); // (4) hygienic: this always resolves to (a) + } +} + +#[allow(unused)] +fn test_unhygienic() { + unhygienic_macro!(); + f(); // `f` was defined at the use site +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/xcrate.rs b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/xcrate.rs new file mode 100644 index 000000000000..ed352d103336 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/auxiliary/xcrate.rs @@ -0,0 +1,29 @@ +#![feature(decl_macro)] +#![allow(unused)] + +pub use bar::test; + +extern crate std as foo; + +pub fn f() {} +use f as f2; + +mod bar { + pub fn g() {} + use baz::h; + + pub macro test() { + use std::mem; + use foo::cell; + ::f(); + ::f2(); + g(); + h(); + ::bar::h(); + } +} + +mod baz { + pub fn h() {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/cross-crate-codegen-attrs.rs b/gcc/testsuite/rust/rustc/ui/hygiene/cross-crate-codegen-attrs.rs new file mode 100644 index 000000000000..66b2c57d2906 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/cross-crate-codegen-attrs.rs @@ -0,0 +1,13 @@ +// Make sure that macro expanded codegen attributes work across crates. +// We used to gensym the identifiers in attributes, which stopped dependent +// crates from seeing them, resulting in linker errors in cases like this one. + +// run-pass +// aux-build:codegen-attrs.rs + +extern crate codegen_attrs; + +fn main() { + assert_eq!(codegen_attrs::rust_function_name(), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/cross_crate_hygiene.rs b/gcc/testsuite/rust/rustc/ui/hygiene/cross_crate_hygiene.rs new file mode 100644 index 000000000000..fe113049a484 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/cross_crate_hygiene.rs @@ -0,0 +1,9 @@ +// check-pass +// aux-build:needs_hygiene.rs + +extern crate needs_hygiene; + +use needs_hygiene::*; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/dollar-crate-modern.rs b/gcc/testsuite/rust/rustc/ui/hygiene/dollar-crate-modern.rs new file mode 100644 index 000000000000..ffe2293f7650 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/dollar-crate-modern.rs @@ -0,0 +1,26 @@ +// Make sure `$crate` and `crate` work in for basic cases of nested macros. + +// check-pass +// aux-build:intercrate.rs + +#![feature(decl_macro)] + +extern crate intercrate; + +// `$crate` +intercrate::uses_dollar_crate_modern!(); + +intercrate::define_uses_dollar_crate_modern_nested!(uses_dollar_crate_modern_nested); +uses_dollar_crate_modern_nested!(); + +intercrate::define_uses_dollar_crate_legacy_nested!(); +uses_dollar_crate_legacy_nested!(); + +// `crate` +intercrate::uses_crate_modern!(); + +intercrate::define_uses_crate_modern_nested!(uses_crate_modern_nested); +uses_crate_modern_nested!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/duplicate_lifetimes.rs b/gcc/testsuite/rust/rustc/ui/hygiene/duplicate_lifetimes.rs new file mode 100644 index 000000000000..41a86b11a270 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/duplicate_lifetimes.rs @@ -0,0 +1,20 @@ +// Ensure that lifetime parameter names are modernized before we check for +// duplicates. + +#![feature(decl_macro, rustc_attrs)] + +#[rustc_macro_transparency = "semitransparent"] +macro m($a:lifetime) { + fn g<$a, 'a>() {} // { dg-error ".E0263." "" { target *-*-* } } +} + +#[rustc_macro_transparency = "transparent"] +macro n($a:lifetime) { + fn h<$a, 'a>() {} // { dg-error ".E0263." "" { target *-*-* } } +} + +m!('a); +n!('a); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/eager-from-opaque-2.rs b/gcc/testsuite/rust/rustc/ui/hygiene/eager-from-opaque-2.rs new file mode 100644 index 000000000000..075095b48408 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/eager-from-opaque-2.rs @@ -0,0 +1,23 @@ +// Regression test for the issue #63460. + +// check-pass + +#[macro_export] +macro_rules! separator { + () => { "/" }; +} + +#[macro_export] +macro_rules! concat_separator { + ( $e:literal, $($other:literal),+ ) => { + concat!($e, $crate::separator!(), $crate::concat_separator!($($other),+)) + }; + ( $e:literal ) => { + $e + } +} + +fn main() { + println!("{}", concat_separator!(2, 3, 4)) +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/eager-from-opaque.rs b/gcc/testsuite/rust/rustc/ui/hygiene/eager-from-opaque.rs new file mode 100644 index 000000000000..e851c47928c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/eager-from-opaque.rs @@ -0,0 +1,21 @@ +// Opaque macro can eagerly expand its input without breaking its resolution. +// Regression test for issue #63685. + +// check-pass + +macro_rules! foo { + () => { + "foo" + }; +} + +macro_rules! bar { + () => { + foo!() + }; +} + +fn main() { + format_args!(bar!()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/expansion-info-reset.rs b/gcc/testsuite/rust/rustc/ui/hygiene/expansion-info-reset.rs new file mode 100644 index 000000000000..ce3d68f58793 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/expansion-info-reset.rs @@ -0,0 +1,5 @@ +fn main() { + format_args!({ #[derive(Clone)] struct S; }); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/extern-prelude-from-opaque-fail.rs b/gcc/testsuite/rust/rustc/ui/hygiene/extern-prelude-from-opaque-fail.rs new file mode 100644 index 000000000000..f212d3fadcc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/extern-prelude-from-opaque-fail.rs @@ -0,0 +1,29 @@ +#![feature(decl_macro)] + +macro a() { + extern crate core as my_core; + mod v { + // Early resolution. + use my_core; // { dg-error ".E0432." "" { target *-*-* } } + } + mod u { + // Late resolution. + fn f() { my_core::mem::drop(0); } +// { dg-error ".E0433." "" { target *-*-* } .-1 } + } +} + +a!(); + +mod v { + // Early resolution. + use my_core; // { dg-error ".E0432." "" { target *-*-* } } +} +mod u { + // Late resolution. + fn f() { my_core::mem::drop(0); } +// { dg-error ".E0433." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/fields-definition.rs b/gcc/testsuite/rust/rustc/ui/hygiene/fields-definition.rs new file mode 100644 index 000000000000..b8a07f7ea520 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/fields-definition.rs @@ -0,0 +1,23 @@ +#![feature(decl_macro)] + +macro modern($a: ident) { + struct Modern { + a: u8, + $a: u8, // OK + } +} + +macro_rules! legacy { + ($a: ident) => { + struct Legacy { + a: u8, + $a: u8, // { dg-error ".E0124." "" { target *-*-* } } + } + } +} + +modern!(a); +legacy!(a); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/fields-move.rs b/gcc/testsuite/rust/rustc/ui/hygiene/fields-move.rs new file mode 100644 index 000000000000..9add4219020c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/fields-move.rs @@ -0,0 +1,31 @@ +// issue #46314 + +#![feature(decl_macro)] + +#[derive(Debug)] +struct NonCopy(String); + +struct Foo { + x: NonCopy, +} + +macro copy_modern($foo: ident) { + $foo.x +} + +macro_rules! copy_legacy { + ($foo: ident) => { + $foo.x // { dg-error ".E0382." "" { target *-*-* } } + } +} + +fn assert_two_copies(a: NonCopy, b: NonCopy) { + println!("Got two copies: {:?}, {:?}", a, b); +} + +fn main() { + let foo = Foo { x: NonCopy("foo".into()) }; + assert_two_copies(copy_modern!(foo), foo.x); // { dg-error ".E0382." "" { target *-*-* } } + assert_two_copies(copy_legacy!(foo), foo.x); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/fields-numeric-borrowck.rs b/gcc/testsuite/rust/rustc/ui/hygiene/fields-numeric-borrowck.rs new file mode 100644 index 000000000000..fad888a9b563 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/fields-numeric-borrowck.rs @@ -0,0 +1,14 @@ +struct S(u8); + +fn main() { + let mut s = S(0); + let borrow1 = &mut s.0; + let S { 0: ref mut borrow2 } = s; +// { dg-error ".E0499." "" { target *-*-* } .-1 } + borrow2.use_mut(); + borrow1.use_mut(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/fields.rs b/gcc/testsuite/rust/rustc/ui/hygiene/fields.rs new file mode 100644 index 000000000000..6499b72e3f06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/fields.rs @@ -0,0 +1,31 @@ +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro)] + +mod foo { + struct S { x: u32 } + struct T(u32); + + pub macro m($S:ident, $x:ident) {{ + struct $S { + $x: u32, + x: i32, + } + + let s = S { x: 0 }; // { dg-error "" "" { target *-*-* } } + let _ = s.x; // { dg-error "" "" { target *-*-* } } + + let t = T(0); // { dg-error "" "" { target *-*-* } } + let _ = t.0; // { dg-error "" "" { target *-*-* } } + + let s = $S { $x: 0, x: 1 }; + assert_eq!((s.$x, s.x), (0, 1)); + s + }} +} + +fn main() { + let s = foo::m!(S, x); + assert_eq!(s.x, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/for-loop.rs b/gcc/testsuite/rust/rustc/ui/hygiene/for-loop.rs new file mode 100644 index 000000000000..4879eb04e4f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/for-loop.rs @@ -0,0 +1,9 @@ +// for-loops are expanded in the front end, and use an `iter` ident in their expansion. Check that +// `iter` is not accessible inside the for loop. + +fn main() { + for _ in 0..10 { + iter.next(); // { dg-error ".E0425." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/format-args.rs b/gcc/testsuite/rust/rustc/ui/hygiene/format-args.rs new file mode 100644 index 000000000000..6d7ef11da1fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/format-args.rs @@ -0,0 +1,13 @@ +// check-pass + +#![allow(non_upper_case_globals)] +#![feature(format_args_nl)] + +static arg0: () = (); + +fn main() { + static arg1: () = (); + format_args!("{} {:?}", 0, 1); + format_args_nl!("{} {:?}", 0, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/generate-mod.rs b/gcc/testsuite/rust/rustc/ui/hygiene/generate-mod.rs new file mode 100644 index 000000000000..e923a7576ee3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/generate-mod.rs @@ -0,0 +1,50 @@ +// This is an equivalent of issue #50504, but for declarative macros. + +#![feature(decl_macro, rustc_attrs)] + +macro genmod($FromOutside: ident, $Outer: ident) { + type A = $FromOutside; + struct $Outer; + mod inner { + type A = $FromOutside; // `FromOutside` shouldn't be available from here + type Inner = $Outer; // `Outer` shouldn't be available from here + } +} + +#[rustc_macro_transparency = "transparent"] +macro genmod_transparent() { + type A = FromOutside; + struct Outer; + mod inner { + type A = FromOutside; // { dg-error ".E0412." "" { target *-*-* } } + type Inner = Outer; // { dg-error ".E0412." "" { target *-*-* } } + } +} + +macro_rules! genmod_legacy { () => { + type A = FromOutside; + struct Outer; + mod inner { + type A = FromOutside; // { dg-error ".E0412." "" { target *-*-* } } + type Inner = Outer; // { dg-error ".E0412." "" { target *-*-* } } + } +}} + +fn check() { + struct FromOutside; + genmod!(FromOutside, Outer); // { dg-error ".E0412." "" { target *-*-* } } +// { dg-error ".E0412." "" { target *-*-* } .-2 } +} + +fn check_transparent() { + struct FromOutside; + genmod_transparent!(); +} + +fn check_legacy() { + struct FromOutside; + genmod_legacy!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/generic_params.rs b/gcc/testsuite/rust/rustc/ui/hygiene/generic_params.rs new file mode 100644 index 000000000000..6d07365e3b78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/generic_params.rs @@ -0,0 +1,106 @@ +// Ensure that generic parameters always have modern hygiene. + +// check-pass +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro, rustc_attrs, const_generics)] +// { dg-warning "" "" { target *-*-* } .-1 } + +mod type_params { + macro m($T:ident) { + fn f<$T: Clone, T: PartialEq>(t1: $T, t2: T) -> ($T, bool) { + (t1.clone(), t2 == t2) + } + } + + #[rustc_macro_transparency = "semitransparent"] + macro n($T:ident) { + fn g<$T: Clone>(t1: $T, t2: T) -> (T, $T) { + (t1.clone(), t2.clone()) + } + fn h(t1: $T, t2: T) -> (T, $T) { + (t1.clone(), t2.clone()) + } + } + + #[rustc_macro_transparency = "transparent"] + macro p($T:ident) { + fn j<$T: Clone>(t1: $T, t2: T) -> (T, $T) { + (t1.clone(), t2.clone()) + } + fn k(t1: $T, t2: T) -> (T, $T) { + (t1.clone(), t2.clone()) + } + } + + m!(T); + n!(T); + p!(T); +} + +mod lifetime_params { + macro m($a:lifetime) { + fn f<'b, 'c, $a: 'b, 'a: 'c>(t1: &$a(), t2: &'a ()) -> (&'b (), &'c ()) { + (t1, t2) + } + } + + #[rustc_macro_transparency = "semitransparent"] + macro n($a:lifetime) { + fn g<$a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) { + (t1, t2) + } + fn h<'a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) { + (t1, t2) + } + } + + #[rustc_macro_transparency = "transparent"] + macro p($a:lifetime) { + fn j<$a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) { + (t1, t2) + } + fn k<'a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) { + (t1, t2) + } + } + + m!('a); + n!('a); + p!('a); +} + +mod const_params { + macro m($C:ident) { + fn f(t1: [(); $C], t2: [(); C]) -> ([(); $C], [(); C]) { + (t1, t2) + } + } + + #[rustc_macro_transparency = "semitransparent"] + macro n($C:ident) { + fn g(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) { + (t1, t2) + } + fn h(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) { + (t1, t2) + } + } + + #[rustc_macro_transparency = "transparent"] + macro p($C:ident) { + fn j(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) { + (t1, t2) + } + fn k(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) { + (t1, t2) + } + } + + m!(C); + n!(C); + p!(C); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/globs.rs b/gcc/testsuite/rust/rustc/ui/hygiene/globs.rs new file mode 100644 index 000000000000..69ca09977e4c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/globs.rs @@ -0,0 +1,73 @@ +#![feature(decl_macro)] + +mod foo { + pub fn f() {} +} + +mod bar { + pub fn g() {} +} + +macro m($($t:tt)*) { + $($t)* + use foo::*; + f(); + g(); // { dg-error ".E0425." "" { target *-*-* } } +} + +fn main() { + m! { + use bar::*; + g(); + f(); // { dg-error ".E0425." "" { target *-*-* } } + } +} + +n!(f); +macro n($i:ident) { + mod foo { + pub fn $i() -> u32 { 0 } + pub fn f() {} + + mod test { + use super::*; + fn g() { + let _: u32 = $i(); + let _: () = f(); + } + } + + macro n($j:ident) { + mod test { + use super::*; + fn g() { + let _: u32 = $i(); + let _: () = f(); + $j(); + } + } + } + macro n_with_super($j:ident) { + mod test { + use super::*; + fn g() { + let _: u32 = $i(); + let _: () = f(); + super::$j(); + } + } + } + + n!(f); // { dg-error ".E0425." "" { target *-*-* } } + n_with_super!(f); + mod test2 { + super::n! { + f // { dg-error ".E0425." "" { target *-*-* } } + } + super::n_with_super! { + f + } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/hir-res-hygiene.rs b/gcc/testsuite/rust/rustc/ui/hygiene/hir-res-hygiene.rs new file mode 100644 index 000000000000..0b52bb0d9625 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/hir-res-hygiene.rs @@ -0,0 +1,19 @@ +// check-pass +// edition:2018 +// aux-build:not-libstd.rs + +// Check that paths created in HIR are not affected by in scope names. + +extern crate not_libstd as std; + +async fn the_future() { + async {}.await; +} + +fn main() -> Result<(), ()> { + for i in 0..10 {} + for j in 0..=10 {} + Ok(())?; + Ok(()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/hygiene-dodging-1.rs b/gcc/testsuite/rust/rustc/ui/hygiene/hygiene-dodging-1.rs new file mode 100644 index 000000000000..7b65fa2e3f71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/hygiene-dodging-1.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(unused_must_use)] + +mod x { + pub fn g() -> usize {14} +} + +pub fn main(){ + // should *not* shadow the module x: + let x = 9; + // use it to avoid warnings: + x+3; + assert_eq!(x::g(),14); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/hygiene.rs b/gcc/testsuite/rust/rustc/ui/hygiene/hygiene.rs new file mode 100644 index 000000000000..b0f50a495a13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/hygiene.rs @@ -0,0 +1,115 @@ +// run-pass +#![allow(unused)] + +fn f() { + let x = 0; + macro_rules! foo { () => { + assert_eq!(x, 0); + } } + + let x = 1; + foo!(); +} + +fn g() { + let x = 0; + macro_rules! m { ($m1:ident, $m2:ident, $x:ident) => { + macro_rules! $m1 { () => { ($x, x) } } + let x = 1; + macro_rules! $m2 { () => { ($x, x) } } + } } + + let x = 2; + m!(m2, m3, x); + + let x = 3; + assert_eq!(m2!(), (2, 0)); + assert_eq!(m3!(), (2, 1)); + + let x = 4; + m!(m4, m5, x); + assert_eq!(m4!(), (4, 0)); + assert_eq!(m5!(), (4, 1)); +} + +mod foo { + macro_rules! m { + ($f:ident : |$x:ident| $e:expr) => { + pub fn $f() -> (i32, i32) { + let x = 0; + let $x = 1; + (x, $e) + } + } + } + + m!(f: |x| x + 10); +} + +fn interpolated_pattern() { + let x = 0; + macro_rules! m { + ($p:pat, $e:expr) => { + let $p = 1; + assert_eq!((x, $e), (0, 1)); + } + } + + m!(x, x); +} + +fn patterns_in_macro_generated_macros() { + let x = 0; + macro_rules! m { + ($a:expr, $b:expr) => { + assert_eq!(x, 0); + let x = $a; + macro_rules! n { + () => { + (x, $b) + } + } + } + } + + let x = 1; + m!(2, x); + + let x = 3; + assert_eq!(n!(), (2, 1)); +} + +fn match_hygiene() { + let x = 0; + + macro_rules! m { + ($p:pat, $e:expr) => { + for result in &[Ok(1), Err(1)] { + match *result { + $p => { assert_eq!(($e, x), (1, 0)); } + Err(x) => { assert_eq!(($e, x), (2, 1)); } + } + } + } + } + + let x = 2; + m!(Ok(x), x); +} + +fn label_hygiene() { + 'a: loop { + macro_rules! m { () => { break 'a; } } + m!(); + } +} + +fn main() { + f(); + g(); + assert_eq!(foo::f(), (0, 11)); + interpolated_pattern(); + patterns_in_macro_generated_macros(); + match_hygiene(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-1.rs b/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-1.rs new file mode 100644 index 000000000000..748950aaee4f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-1.rs @@ -0,0 +1,8 @@ +macro_rules! foo { + () => { break 'x; } // { dg-error ".E0426." "" { target *-*-* } } +} + +pub fn main() { + 'x: loop { foo!() } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-2.rs b/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-2.rs new file mode 100644 index 000000000000..c5ead71b91e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-2.rs @@ -0,0 +1,8 @@ +macro_rules! foo { + ($e: expr) => { 'x: loop { $e } } +} + +pub fn main() { + foo!(break 'x); // { dg-error ".E0426." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-3.rs b/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-3.rs new file mode 100644 index 000000000000..66716fc2b6c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-3.rs @@ -0,0 +1,10 @@ +macro_rules! foo { + () => { break 'x; } // { dg-error ".E0426." "" { target *-*-* } } +} + +pub fn main() { + 'x: for _ in 0..1 { + foo!() + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-4.rs b/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-4.rs new file mode 100644 index 000000000000..8304f830b9a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-label-4.rs @@ -0,0 +1,8 @@ +macro_rules! foo { + ($e: expr) => { 'x: for _ in 0..1 { $e } } +} + +pub fn main() { + foo!(break 'x); // { dg-error ".E0426." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-labels-in-let.rs b/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-labels-in-let.rs new file mode 100644 index 000000000000..6a0a5b9b5e17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-labels-in-let.rs @@ -0,0 +1,105 @@ +// run-pass +#![allow(unreachable_code)] +#![allow(unused_labels)] + +// Test that labels injected by macros do not break hygiene. This +// checks cases where the macros invocations are under the rhs of a +// let statement. + +// Issue #24278: The label/lifetime shadowing checker from #24162 +// conservatively ignores hygiene, and thus issues warnings that are +// both true- and false-positives for this test. + +macro_rules! loop_x { + ($e: expr) => { + // $e shouldn't be able to interact with this 'x + 'x: loop { $e } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + } +} + +macro_rules! while_true { + ($e: expr) => { + // $e shouldn't be able to interact with this 'x + 'x: while 1 + 1 == 2 { $e } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +// { dg-warning "" "" { target *-*-* } .-5 } + } +} + +macro_rules! run_once { + ($e: expr) => { + // ditto + 'x: for _ in 0..1 { $e } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +// { dg-warning "" "" { target *-*-* } .-5 } +// { dg-warning "" "" { target *-*-* } .-6 } +// { dg-warning "" "" { target *-*-* } .-7 } + } +} + +pub fn main() { + let mut i = 0; + + let j: isize = { + 'x: loop { + // this 'x should refer to the outer loop, lexically + loop_x!(break 'x); + i += 1; + } + i + 1 + }; + assert_eq!(j, 1); + + let k: isize = { + 'x: for _ in 0..1 { +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + // ditto + loop_x!(break 'x); + i += 1; + } + i + 1 + }; + assert_eq!(k, 1); + + let l: isize = { + 'x: for _ in 0..1 { +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + // ditto + while_true!(break 'x); + i += 1; + } + i + 1 + }; + assert_eq!(l, 1); + + let n: isize = { + 'x: for _ in 0..1 { +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +// { dg-warning "" "" { target *-*-* } .-5 } +// { dg-warning "" "" { target *-*-* } .-6 } + // ditto + run_once!(continue 'x); + i += 1; + } + i + 1 + }; + assert_eq!(n, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-labels.rs b/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-labels.rs new file mode 100644 index 000000000000..1fdc5bcfa31e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/hygienic-labels.rs @@ -0,0 +1,86 @@ +// run-pass +#![allow(unreachable_code)] +#![allow(unused_labels)] +// Test that labels injected by macros do not break hygiene. + +// Issue #24278: The label/lifetime shadowing checker from #24162 +// conservatively ignores hygiene, and thus issues warnings that are +// both true- and false-positives for this test. + +macro_rules! loop_x { + ($e: expr) => { + // $e shouldn't be able to interact with this 'x + 'x: loop { $e } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + } +} + +macro_rules! run_once { + ($e: expr) => { + // ditto + 'x: for _ in 0..1 { $e } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +// { dg-warning "" "" { target *-*-* } .-5 } +// { dg-warning "" "" { target *-*-* } .-6 } +// { dg-warning "" "" { target *-*-* } .-7 } + } +} + +macro_rules! while_x { + ($e: expr) => { + // ditto + 'x: while 1 + 1 == 2 { $e } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +// { dg-warning "" "" { target *-*-* } .-5 } + } +} + +pub fn main() { + 'x: for _ in 0..1 { + // this 'x should refer to the outer loop, lexically + loop_x!(break 'x); + panic!("break doesn't act hygienically inside for loop"); + } + + 'x: loop { +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + // ditto + loop_x!(break 'x); + panic!("break doesn't act hygienically inside infinite loop"); + } + + 'x: while 1 + 1 == 2 { +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + + while_x!(break 'x); + panic!("break doesn't act hygienically inside infinite while loop"); + } + + 'x: for _ in 0..1 { +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +// { dg-warning "" "" { target *-*-* } .-5 } +// { dg-warning "" "" { target *-*-* } .-6 } + + // ditto + run_once!(continue 'x); + panic!("continue doesn't act hygienically inside for loop"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/impl_items.rs b/gcc/testsuite/rust/rustc/ui/hygiene/impl_items.rs new file mode 100644 index 000000000000..a9a3fb07953a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/impl_items.rs @@ -0,0 +1,35 @@ +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro)] + +mod foo { + struct S; + impl S { + fn f(&self) {} + } + + pub macro m() { + let _: () = S.f(); // { dg-error "" "" { target *-*-* } } + } +} + +struct S; + +macro m($f:ident) { + impl S { + fn f(&self) -> u32 { 0 } + fn $f(&self) -> i32 { 0 } + } + fn f() { + let _: u32 = S.f(); + let _: i32 = S.$f(); + } +} + +m!(f); + +fn main() { + let _: i32 = S.f(); + foo::m!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/intercrate.rs b/gcc/testsuite/rust/rustc/ui/hygiene/intercrate.rs new file mode 100644 index 000000000000..267682d99605 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/intercrate.rs @@ -0,0 +1,13 @@ +// ignore-pretty pretty-printing is unhygienic + +// aux-build:intercrate.rs + +#![feature(decl_macro)] + +extern crate intercrate; + +fn main() { + assert_eq!(intercrate::foo::m!(), 1); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/issue-44128.rs b/gcc/testsuite/rust/rustc/ui/hygiene/issue-44128.rs new file mode 100644 index 000000000000..c7c2c2176e81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/issue-44128.rs @@ -0,0 +1,18 @@ +// check-pass +#![allow(unused_must_use)] +#![feature(decl_macro)] + +pub macro create_struct($a:ident) { + struct $a; + impl Clone for $a { + fn clone(&self) -> Self { + $a + } + } +} + +fn main() { + create_struct!(Test); + Test.clone(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/issue-47311.rs b/gcc/testsuite/rust/rustc/ui/hygiene/issue-47311.rs new file mode 100644 index 000000000000..01b5b43e5714 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/issue-47311.rs @@ -0,0 +1,18 @@ +// check-pass +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro)] +#![allow(unused)] + +macro m($S:ident, $x:ident) { + $S { $x: 0 } +} + +mod foo { + struct S { x: i32 } + + fn f() { ::m!(S, x); } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/issue-47312.rs b/gcc/testsuite/rust/rustc/ui/hygiene/issue-47312.rs new file mode 100644 index 000000000000..8a857ba7ed08 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/issue-47312.rs @@ -0,0 +1,22 @@ +// check-pass +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro)] +#![allow(unused)] + +mod foo { + pub macro m($s:tt, $i:tt) { + $s.$i + } +} + +mod bar { + struct S(i32); + fn f() { + let s = S(0); + ::foo::m!(s, 0); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/issue-61574-const-parameters.rs b/gcc/testsuite/rust/rustc/ui/hygiene/issue-61574-const-parameters.rs new file mode 100644 index 000000000000..938bbf523d64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/issue-61574-const-parameters.rs @@ -0,0 +1,33 @@ +// A more comprehensive test that const parameters have correctly implemented +// hygiene + +// check-pass + +#![feature(const_generics)] // { dg-warning "" "" { target *-*-* } } + +use std::ops::Add; + +struct VectorLike([T; {SIZE}]); + +macro_rules! impl_operator_overload { + ($trait_ident:ident, $method_ident:ident) => { + + impl $trait_ident for VectorLike + where + T: $trait_ident, + { + type Output = VectorLike; + + fn $method_ident(self, _: VectorLike) -> VectorLike { + let _ = SIZE; + unimplemented!() + } + } + + } +} + +impl_operator_overload!(Add, add); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/issue-77523-def-site-async-await.rs b/gcc/testsuite/rust/rustc/ui/hygiene/issue-77523-def-site-async-await.rs new file mode 100644 index 000000000000..5f9a35227350 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/issue-77523-def-site-async-await.rs @@ -0,0 +1,20 @@ +// build-pass +// aux-build:opaque-hygiene.rs +// aux-build:def-site-async-await.rs + +// Regression test for issue #77523 +// Tests that we don't ICE when an unusual combination +// of def-site hygiene and cross-crate monomorphization occurs. + +extern crate def_site_async_await; + +use std::future::Future; + +fn mk_ctxt() -> std::task::Context<'static> { + panic!() +} + +fn main() { + Box::pin(def_site_async_await::serve()).as_mut().poll(&mut mk_ctxt()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/items.rs b/gcc/testsuite/rust/rustc/ui/hygiene/items.rs new file mode 100644 index 000000000000..5fb7102b9c82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/items.rs @@ -0,0 +1,28 @@ +// check-pass +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro)] + +pub macro m($foo:ident, $f:ident, $e:expr) { + mod foo { + pub fn f() -> u32 { 0 } + pub fn $f() -> u64 { 0 } + } + + mod $foo { + pub fn f() -> i32 { 0 } + pub fn $f() -> i64 { 0 } + } + + let _: u32 = foo::f(); + let _: u64 = foo::$f(); + let _: i32 = $foo::f(); + let _: i64 = $foo::$f(); + let _: i64 = $e; +} + +fn main() { + m!(foo, f, foo::f()); + let _: i64 = foo::f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/legacy_interaction.rs b/gcc/testsuite/rust/rustc/ui/hygiene/legacy_interaction.rs new file mode 100644 index 000000000000..0a39916f2912 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/legacy_interaction.rs @@ -0,0 +1,43 @@ +// check-pass +#![allow(dead_code)] +// ignore-pretty pretty-printing is unhygienic + +// aux-build:legacy_interaction.rs + +#![feature(decl_macro)] +#[allow(unused)] + +extern crate legacy_interaction; +// ^ defines +// ```rust +// macro_rules! m { +// () => { +// fn f() {} // (1) +// g() // (2) +// } +// } +// ```rust + +mod def_site { + // Unless this macro opts out of hygiene, it should resolve the same wherever it is invoked. + pub macro m2() { + ::legacy_interaction::m!(); + f(); // This should resolve to (1) + fn g() {} // We want (2) resolve to this, not to (4) + } +} + +mod use_site { + fn test() { + fn f() -> bool { true } // (3) + fn g() -> bool { true } // (4) + + ::def_site::m2!(); + + let _: bool = f(); // This should resolve to (3) + let _: bool = g(); // This should resolve to (4) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/lexical.rs b/gcc/testsuite/rust/rustc/ui/hygiene/lexical.rs new file mode 100644 index 000000000000..6cf412fc67e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/lexical.rs @@ -0,0 +1,25 @@ +// check-pass +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro)] + +mod bar { + mod baz { + pub fn f() {} + } + + pub macro m($f:ident) { + baz::f(); + let _: i32 = $f(); + { + fn $f() -> u32 { 0 } + let _: u32 = $f(); + } + } +} + +fn main() { + fn f() -> i32 { 0 } + bar::m!(f); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/local_inner_macros.rs b/gcc/testsuite/rust/rustc/ui/hygiene/local_inner_macros.rs new file mode 100644 index 000000000000..b4ea1cf3943b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/local_inner_macros.rs @@ -0,0 +1,20 @@ +// check-pass +// aux-build:local_inner_macros.rs + +extern crate local_inner_macros; + +use local_inner_macros::{public_macro, public_macro_dynamic}; + +public_macro!(); + +macro_rules! local_helper { + () => ( struct Z; ) +} + +public_macro_dynamic!(local_helper); + +fn main() { + let s = S; + let z = Z; +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/macro-metavars-legacy.rs b/gcc/testsuite/rust/rustc/ui/hygiene/macro-metavars-legacy.rs new file mode 100644 index 000000000000..b692bc7a114e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/macro-metavars-legacy.rs @@ -0,0 +1,30 @@ +// Ensure macro metavariables are compared with legacy hygiene + +#![feature(rustc_attrs)] + +// run-pass + +macro_rules! make_mac { + ( $($dollar:tt $arg:ident),+ ) => { + macro_rules! mac { + ( $($dollar $arg : ident),+ ) => { + $( $dollar $arg )-+ + } + } + } +} + +macro_rules! show_hygiene { + ( $dollar:tt $arg:ident ) => { + make_mac!($dollar $arg, $dollar arg); + } +} + +show_hygiene!( $arg ); + +fn main() { + let x = 5; + let y = 3; + assert_eq!(2, mac!(x, y)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/macro-metavars-transparent.rs b/gcc/testsuite/rust/rustc/ui/hygiene/macro-metavars-transparent.rs new file mode 100644 index 000000000000..96ccfe584c06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/macro-metavars-transparent.rs @@ -0,0 +1,25 @@ +// Ensure macro metavariables are not compared without removing transparent +// marks. + +#![feature(rustc_attrs)] + +// run-pass + +#[rustc_macro_transparency = "transparent"] +macro_rules! k { + ($($s:tt)*) => { + macro_rules! m { + ($y:tt) => { + $($s)* + } + } + } +} + +k!(1 + $y); + +fn main() { + let x = 2; + assert_eq!(3, m!(x)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/missing-self-diag.rs b/gcc/testsuite/rust/rustc/ui/hygiene/missing-self-diag.rs new file mode 100644 index 000000000000..244f884b0482 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/missing-self-diag.rs @@ -0,0 +1,24 @@ +// Regression test for issue #66898 +// Tests that we don't emit a nonsensical error message +// when a macro invocation tries to access `self` from a function +// that has a 'self' parameter + +pub struct Foo; + +macro_rules! call_bar { + () => { + self.bar(); // { dg-error ".E0424." "" { target *-*-* } } + } +} + +impl Foo { + pub fn foo(&self) { + call_bar!(); + } + + pub fn bar(&self) { + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/nested-dollar-crate.rs b/gcc/testsuite/rust/rustc/ui/hygiene/nested-dollar-crate.rs new file mode 100644 index 000000000000..f00f055c5a7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/nested-dollar-crate.rs @@ -0,0 +1,10 @@ +// aux-build:nested-dollar-crate.rs +// edition:2018 +// run-pass + +extern crate nested_dollar_crate; + +fn main() { + assert_eq!(nested_dollar_crate::inner!(), "In def crate!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/nested_macro_privacy.rs b/gcc/testsuite/rust/rustc/ui/hygiene/nested_macro_privacy.rs new file mode 100644 index 000000000000..26677a3ee330 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/nested_macro_privacy.rs @@ -0,0 +1,18 @@ +#![feature(decl_macro)] + +macro n($foo:ident, $S:ident, $i:ident, $m:ident) { + mod $foo { + #[derive(Default)] + pub struct $S { $i: u32 } + pub macro $m($e:expr) { $e.$i } + } +} + +n!(foo, S, i, m); + +fn main() { + use foo::{S, m}; + S::default().i; // { dg-error ".E0616." "" { target *-*-* } } + m!(S::default()); // ok +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/no_implicit_prelude-2018.rs b/gcc/testsuite/rust/rustc/ui/hygiene/no_implicit_prelude-2018.rs new file mode 100644 index 000000000000..40c622bfb69e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/no_implicit_prelude-2018.rs @@ -0,0 +1,12 @@ +// edition:2018 + +#[no_implicit_prelude] +mod bar { + fn f() { + ::std::print!(""); // OK + print!(); // { dg-error "" "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/no_implicit_prelude.rs b/gcc/testsuite/rust/rustc/ui/hygiene/no_implicit_prelude.rs new file mode 100644 index 000000000000..94eb4389f148 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/no_implicit_prelude.rs @@ -0,0 +1,21 @@ +#![feature(decl_macro)] + +mod foo { + pub macro m() { Vec::new(); ().clone() } + fn f() { ::bar::m!(); } +} + +#[no_implicit_prelude] +mod bar { + pub macro m() { + Vec::new(); // { dg-error ".E0433." "" { target *-*-* } } + ().clone() // { dg-error ".E0599." "" { target *-*-* } } + } + fn f() { + ::foo::m!(); + assert_eq!(0, 0); // { dg-error "" "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/panic-location.rs b/gcc/testsuite/rust/rustc/ui/hygiene/panic-location.rs new file mode 100644 index 000000000000..414610f040b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/panic-location.rs @@ -0,0 +1,11 @@ +// run-fail +// check-run-results +// exec-env:RUST_BACKTRACE=0 +// +// Regression test for issue #70963 +// The captured stderr from this test reports a location +// inside `VecDeque::with_capacity`, instead of `<::core::macros::panic macros>` +fn main() { + std::collections::VecDeque::::with_capacity(!0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/pattern-macro.rs b/gcc/testsuite/rust/rustc/ui/hygiene/pattern-macro.rs new file mode 100644 index 000000000000..858d7dfec747 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/pattern-macro.rs @@ -0,0 +1,7 @@ +macro_rules! foo { () => ( x ) } + +fn main() { + let foo!() = 2; + x + 1; // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/prelude-import-hygiene.rs b/gcc/testsuite/rust/rustc/ui/hygiene/prelude-import-hygiene.rs new file mode 100644 index 000000000000..4f3592d6212d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/prelude-import-hygiene.rs @@ -0,0 +1,30 @@ +// Make sure that attribute used when injecting the prelude are resolved +// hygienically. + +// check-pass +// aux-build:not-libstd.rs + +//revisions: rust2015 rust2018 +//[rust2018] edition:2018 + +// The prelude import shouldn't see these as candidates for when it's trying to +// use the built-in macros. +extern crate core; +use core::prelude::v1::test as prelude_import; +use core::prelude::v1::test as macro_use; + +// Should not be used for the prelude import - not a concern in the 2015 edition +// because `std` is already declared in the crate root. +#[cfg(rust2018)] +extern crate not_libstd as std; + +#[cfg(rust2018)] +mod x { + // The extern crate item should override `std` in the extern prelude. + fn f() { + std::not_in_lib_std(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/privacy-early.rs b/gcc/testsuite/rust/rustc/ui/hygiene/privacy-early.rs new file mode 100644 index 000000000000..2eab88c9b80a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/privacy-early.rs @@ -0,0 +1,18 @@ +// edition:2018 + +#![feature(decl_macro)] + +mod foo { + fn f() {} + macro f() {} + + pub macro m() { + use f as g; // { dg-error ".E0364." "" { target *-*-* } } + f!(); + } +} + +fn main() { + foo::m!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/privacy.rs b/gcc/testsuite/rust/rustc/ui/hygiene/privacy.rs new file mode 100644 index 000000000000..4c2a35a1caf2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/privacy.rs @@ -0,0 +1,19 @@ +#![feature(decl_macro)] + +mod foo { + fn f() {} + + pub macro m($e:expr) { + f(); + self::f(); + ::foo::f(); + $e + } +} + +fn main() { + foo::m!( + foo::f() // { dg-error ".E0603." "" { target *-*-* } } + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/rustc-macro-transparency.rs b/gcc/testsuite/rust/rustc/ui/hygiene/rustc-macro-transparency.rs new file mode 100644 index 000000000000..7f290d668996 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/rustc-macro-transparency.rs @@ -0,0 +1,32 @@ +#![feature(decl_macro, rustc_attrs)] + +#[rustc_macro_transparency = "transparent"] +macro transparent() { + struct Transparent; + let transparent = 0; +} +#[rustc_macro_transparency = "semitransparent"] +macro semitransparent() { + struct SemiTransparent; + let semitransparent = 0; +} +#[rustc_macro_transparency = "opaque"] +macro opaque() { + struct Opaque; + let opaque = 0; +} + +fn main() { + transparent!(); + semitransparent!(); + opaque!(); + + Transparent; // OK + SemiTransparent; // OK + Opaque; // { dg-error ".E0425." "" { target *-*-* } } + + transparent; // OK + semitransparent; // { dg-error ".E0423." "" { target *-*-* } } + opaque; // { dg-error ".E0423." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/specialization.rs b/gcc/testsuite/rust/rustc/ui/hygiene/specialization.rs new file mode 100644 index 000000000000..9ea55e01b90c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/specialization.rs @@ -0,0 +1,26 @@ +// run-pass +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro)] + +trait Tr { + fn f(&self) -> &'static str { + "This shouldn't happen" + } +} + +pub macro m($t:ty) { + impl Tr for $t { + fn f(&self) -> &'static str { + "Run me" + } + } +} + +struct S; +m!(S); + +fn main() { + assert_eq!(S.f(), "Run me"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/stdlib-prelude-from-opaque-early.rs b/gcc/testsuite/rust/rustc/ui/hygiene/stdlib-prelude-from-opaque-early.rs new file mode 100644 index 000000000000..dd159de479d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/stdlib-prelude-from-opaque-early.rs @@ -0,0 +1,22 @@ +// check-pass +// aux-build:stdlib-prelude.rs + +#![feature(decl_macro)] +#![feature(prelude_import)] + +extern crate stdlib_prelude; + +#[prelude_import] +use stdlib_prelude::*; + +macro mac() { + mod m { + use std::mem; // OK (extern prelude) + stdlib_macro!(); // OK (stdlib prelude) + } +} + +mac!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/stdlib-prelude-from-opaque-late.rs b/gcc/testsuite/rust/rustc/ui/hygiene/stdlib-prelude-from-opaque-late.rs new file mode 100644 index 000000000000..e073caa37907 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/stdlib-prelude-from-opaque-late.rs @@ -0,0 +1,17 @@ +// check-pass + +#![feature(decl_macro)] + +macro mac() { + mod m { + fn f() { + std::mem::drop(0); // OK (extern prelude) + drop(0); // OK (stdlib prelude) + } + } +} + +mac!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/trait_items-2.rs b/gcc/testsuite/rust/rustc/ui/hygiene/trait_items-2.rs new file mode 100644 index 000000000000..13ae236c9807 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/trait_items-2.rs @@ -0,0 +1,21 @@ +// check-pass +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro)] + +macro m($T:ident, $f:ident) { + pub trait $T { + fn f(&self) -> u32 { 0 } + fn $f(&self) -> i32 { 0 } + } + impl $T for () {} + + let _: u32 = ().f(); + let _: i32 = ().$f(); +} + +fn main() { + m!(T, f); + let _: i32 = ().f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/trait_items.rs b/gcc/testsuite/rust/rustc/ui/hygiene/trait_items.rs new file mode 100644 index 000000000000..4333a3308f55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/trait_items.rs @@ -0,0 +1,22 @@ +#![feature(decl_macro)] + +mod foo { + pub trait T { + fn f(&self) {} + } + impl T for () {} +} + +mod bar { + use foo::*; + pub macro m() { ().f() } + fn f() { ::baz::m!(); } +} + +mod baz { + pub macro m() { ().f() } // { dg-error ".E0599." "" { target *-*-* } } + fn f() { ::bar::m!(); } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/transparent-basic.rs b/gcc/testsuite/rust/rustc/ui/hygiene/transparent-basic.rs new file mode 100644 index 000000000000..f58d525cbd5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/transparent-basic.rs @@ -0,0 +1,44 @@ +// check-pass +// aux-build:transparent-basic.rs + +#![feature(decl_macro, rustc_attrs)] + +extern crate transparent_basic; + +#[rustc_macro_transparency = "transparent"] +macro binding() { + let x = 10; +} + +#[rustc_macro_transparency = "transparent"] +macro label() { + break 'label +} + +macro_rules! legacy { + () => { + binding!(); + let y = x; + } +} + +fn legacy_interaction1() { + legacy!(); +} + +struct S; + +fn check_dollar_crate() { + // `$crate::S` inside the macro resolves to `S` from this crate. + transparent_basic::dollar_crate!(); +} + +fn main() { + binding!(); + let y = x; + + 'label: loop { + label!(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/unpretty-debug.rs b/gcc/testsuite/rust/rustc/ui/hygiene/unpretty-debug.rs new file mode 100644 index 000000000000..2d9b664afa1e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/unpretty-debug.rs @@ -0,0 +1,21 @@ +// check-pass +// compile-flags: -Zunpretty=expanded,hygiene + +// Don't break whenever Symbol numbering changes +// normalize-stdout-test "\d+#" -> "0#" + +// minimal junk +#![feature(no_core)] +#![no_core] + +macro_rules! foo { + ($x: ident) => { y + $x } +} + +fn bar() { + let x = 1; + foo!(x) +} + +fn y() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/wrap_unhygienic_example.rs b/gcc/testsuite/rust/rustc/ui/hygiene/wrap_unhygienic_example.rs new file mode 100644 index 000000000000..7565ab53df0b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/wrap_unhygienic_example.rs @@ -0,0 +1,35 @@ +// check-pass +// ignore-pretty pretty-printing is unhygienic + +// aux-build:my_crate.rs +// aux-build:unhygienic_example.rs + +#![feature(decl_macro)] + +extern crate unhygienic_example; +extern crate my_crate; // (b) + +// Hygienic version of `unhygienic_macro`. +pub macro hygienic_macro() { + fn g() {} // (c) + ::unhygienic_example::unhygienic_macro!(); + // ^ Even though we invoke an unhygienic macro, `hygienic_macro` remains hygienic. + // In the above expansion: + // (1) `my_crate` always resolves to (b) regardless of invocation site. + // (2) The defined function `f` is only usable inside this macro definition. + // (3) `g` always resolves to (c) regardless of invocation site. + // (4) `$crate::g` remains hygienic and continues to resolve to (a). + + f(); +} + +#[allow(unused)] +fn test_hygienic_macro() { + hygienic_macro!(); + + fn f() {} // (d) no conflict + f(); // resolves to (d) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/hygiene/xcrate.rs b/gcc/testsuite/rust/rustc/ui/hygiene/xcrate.rs new file mode 100644 index 000000000000..892bf24a95f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/hygiene/xcrate.rs @@ -0,0 +1,13 @@ +// run-pass +// ignore-pretty pretty-printing is unhygienic + +// aux-build:xcrate.rs + +#![feature(decl_macro)] + +extern crate xcrate; + +fn main() { + xcrate::test!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/if-attrs/bad-cfg.rs b/gcc/testsuite/rust/rustc/ui/if-attrs/bad-cfg.rs new file mode 100644 index 000000000000..c5b8041e021f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if-attrs/bad-cfg.rs @@ -0,0 +1,6 @@ +#![feature(stmt_expr_attributes)] + +fn main() { + let _ = #[cfg(FALSE)] if true {}; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/if-attrs/builtin-if-attr.rs b/gcc/testsuite/rust/rustc/ui/if-attrs/builtin-if-attr.rs new file mode 100644 index 000000000000..d428c636cac0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if-attrs/builtin-if-attr.rs @@ -0,0 +1,13 @@ +// check-pass + +fn main() { + #[allow(unused_variables)] + if true { + let a = 1; + } else if false { + let b = 1; + } else { + let c = 1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/if-attrs/cfg-false-if-attr.rs b/gcc/testsuite/rust/rustc/ui/if-attrs/cfg-false-if-attr.rs new file mode 100644 index 000000000000..2a3de4e5879a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if-attrs/cfg-false-if-attr.rs @@ -0,0 +1,44 @@ +// check-pass + +#[cfg(FALSE)] +fn simple_attr() { + #[attr] if true {} + #[allow_warnings] if true {} +} + +#[cfg(FALSE)] +fn if_else_chain() { + #[first_attr] if true { + } else if false { + } else { + } +} + +#[cfg(FALSE)] +fn if_let() { + #[attr] if let Some(_) = Some(true) {} +} + +fn bar() { + #[cfg(FALSE)] + if true { + let x: () = true; // Should not error due to the #[cfg(FALSE)] + } + + #[cfg_attr(not(unset_attr), cfg(FALSE))] + if true { + let a: () = true; // Should not error due to the applied #[cfg(FALSE)] + } +} + +macro_rules! custom_macro { + ($expr:expr) => {} +} + +custom_macro! { + #[attr] if true {} +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/if-attrs/else-attrs.rs b/gcc/testsuite/rust/rustc/ui/if-attrs/else-attrs.rs new file mode 100644 index 000000000000..c487df48148d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if-attrs/else-attrs.rs @@ -0,0 +1,26 @@ +#[cfg(FALSE)] +fn if_else_parse_error() { + if true { + } #[attr] else if false { // { dg-error "" "" { target *-*-* } } + } +} + +#[cfg(FALSE)] +fn else_attr_ifparse_error() { + if true { + } else #[attr] if false { // { dg-error "" "" { target *-*-* } } + } else { + } +} + +#[cfg(FALSE)] +fn else_parse_error() { + if true { + } else if false { + } #[attr] else { // { dg-error "" "" { target *-*-* } } + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/if-attrs/gate-whole-expr.rs b/gcc/testsuite/rust/rustc/ui/if-attrs/gate-whole-expr.rs new file mode 100644 index 000000000000..5298062a04f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if-attrs/gate-whole-expr.rs @@ -0,0 +1,16 @@ +// run-pass + +fn main() { + let x = 1; + + #[cfg(FALSE)] + if false { + x = 2; + } else if true { + x = 3; + } else { + x = 4; + } + assert_eq!(x, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/if-attrs/let-chains-attr.rs b/gcc/testsuite/rust/rustc/ui/if-attrs/let-chains-attr.rs new file mode 100644 index 000000000000..8db4e6def0e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if-attrs/let-chains-attr.rs @@ -0,0 +1,14 @@ +// check-pass + +#![feature(let_chains)] // { dg-warning "" "" { target *-*-* } } + +#[cfg(FALSE)] +fn foo() { + #[attr] + if let Some(_) = Some(true) && let Ok(_) = Ok(1) { + } else if let Some(false) = Some(true) { + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/if-attrs/stmt-expr-gated.rs b/gcc/testsuite/rust/rustc/ui/if-attrs/stmt-expr-gated.rs new file mode 100644 index 000000000000..faace9085d2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if-attrs/stmt-expr-gated.rs @@ -0,0 +1,7 @@ +fn main() { + let _ = #[deny(warnings)] if true { // { dg-error ".E0658." "" { target *-*-* } } + } else if false { + } else { + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/if-bot.rs b/gcc/testsuite/rust/rustc/ui/if-bot.rs new file mode 100644 index 000000000000..1fbf9d71b1a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if-bot.rs @@ -0,0 +1,7 @@ +// run-pass + +pub fn main() { + let i: isize = if false { panic!() } else { 5 }; + println!("{}", i); +} + diff --git a/gcc/testsuite/rust/rustc/ui/if-check.rs b/gcc/testsuite/rust/rustc/ui/if-check.rs new file mode 100644 index 000000000000..5347f0f31eaf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if-check.rs @@ -0,0 +1,18 @@ +// run-pass + +fn even(x: usize) -> bool { + if x < 2 { + return false; + } else if x == 2 { return true; } else { return even(x - 2); } +} + +fn foo(x: usize) { + if even(x) { + println!("{}", x); + } else { + panic!(); + } +} + +pub fn main() { foo(2); } + diff --git a/gcc/testsuite/rust/rustc/ui/if-else-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/if-else-type-mismatch.rs new file mode 100644 index 000000000000..f95c9111773e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if-else-type-mismatch.rs @@ -0,0 +1,47 @@ +fn main() { + let _ = if true { + 1i32 + } else { + 2u32 + }; +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let _ = if true { 42i32 } else { 42u32 }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let _ = if true { + 3u32; + } else { + 4u32 + }; +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let _ = if true { + 5u32 + } else { + 6u32; + }; +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let _ = if true { + 7i32; + } else { + 8u32 + }; +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let _ = if true { + 9i32 + } else { + 10u32; + }; +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let _ = if true { + + } else { + 11u32 + }; +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let _ = if true { + 12i32 + } else { + + }; +// { dg-error ".E0308." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/if-ret.rs b/gcc/testsuite/rust/rustc/ui/if-ret.rs new file mode 100644 index 000000000000..443ea21498e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if-ret.rs @@ -0,0 +1,9 @@ +// run-pass + +#![allow(unused_parens)] +// pretty-expanded FIXME #23616 + +fn foo() { if (return) { } } // { dg-warning "" "" { target *-*-* } } + +pub fn main() { foo(); } + diff --git a/gcc/testsuite/rust/rustc/ui/if/expr-if-panic-fn.rs b/gcc/testsuite/rust/rustc/ui/if/expr-if-panic-fn.rs new file mode 100644 index 000000000000..2f316525b0d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/expr-if-panic-fn.rs @@ -0,0 +1,21 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn f() -> ! { + panic!() +} + +fn g() -> isize { + let x = if true { + f() + } else { + 10 + }; + return x; +} + +fn main() { + g(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/expr-if-panic.rs b/gcc/testsuite/rust/rustc/ui/if/expr-if-panic.rs new file mode 100644 index 000000000000..c5aa5890fa14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/expr-if-panic.rs @@ -0,0 +1,14 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn main() { + let _x = if false { + 0 + } else if true { + panic!() + } else { + 10 + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/if-branch-types.rs b/gcc/testsuite/rust/rustc/ui/if/if-branch-types.rs new file mode 100644 index 000000000000..0cc978faa95a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/if-branch-types.rs @@ -0,0 +1,6 @@ +fn main() { + let x = if true { 10i32 } else { 10u32 }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/if-check-panic.rs b/gcc/testsuite/rust/rustc/ui/if/if-check-panic.rs new file mode 100644 index 000000000000..6cbdf4577565 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/if-check-panic.rs @@ -0,0 +1,26 @@ +// run-fail +// error-pattern:Number is odd +// ignore-emscripten no processes + +fn even(x: usize) -> bool { + if x < 2 { + return false; + } else if x == 2 { + return true; + } else { + return even(x - 2); + } +} + +fn foo(x: usize) { + if even(x) { + println!("{}", x); + } else { + panic!("Number is odd"); + } +} + +fn main() { + foo(3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/if-cond-bot.rs b/gcc/testsuite/rust/rustc/ui/if/if-cond-bot.rs new file mode 100644 index 000000000000..a404c3bceb32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/if-cond-bot.rs @@ -0,0 +1,14 @@ +// run-fail +// error-pattern:quux +// ignore-emscripten no processes + +fn my_err(s: String) -> ! { + println!("{}", s); + panic!("quux"); +} + +fn main() { + if my_err("bye".to_string()) { + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/if-let-arm-types.rs b/gcc/testsuite/rust/rustc/ui/if/if-let-arm-types.rs new file mode 100644 index 000000000000..25641414faac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/if-let-arm-types.rs @@ -0,0 +1,12 @@ +fn main() { + if let Some(b) = None { +// { dg-note ".E0308." "" { target *-*-* } .-1 } + () +// { dg-note "" "" { target *-*-* } .-1 } + } else { + 1 + }; +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/if-let.rs b/gcc/testsuite/rust/rustc/ui/if/if-let.rs new file mode 100644 index 000000000000..93b9941dab59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/if-let.rs @@ -0,0 +1,50 @@ +// check-pass + +fn macros() { + macro_rules! foo{ + ($p:pat, $e:expr, $b:block) => {{ + if let $p = $e $b +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + }} + } + macro_rules! bar{ + ($p:pat, $e:expr, $b:block) => {{ + foo!($p, $e, $b) + }} + } + + foo!(a, 1, { + println!("irrefutable pattern"); + }); + bar!(a, 1, { + println!("irrefutable pattern"); + }); +} + +pub fn main() { + if let a = 1 { // { dg-warning "" "" { target *-*-* } } + println!("irrefutable pattern"); + } + + if let a = 1 { // { dg-warning "" "" { target *-*-* } } + println!("irrefutable pattern"); + } else if true { + println!("else-if in irrefutable if-let"); + } else { + println!("else in irrefutable if-let"); + } + + if let 1 = 2 { + println!("refutable pattern"); + } else if let a = 1 { // { dg-warning "" "" { target *-*-* } } + println!("irrefutable pattern"); + } + + if true { + println!("if"); + } else if let a = 1 { // { dg-warning "" "" { target *-*-* } } + println!("irrefutable pattern"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/if-loop.rs b/gcc/testsuite/rust/rustc/ui/if/if-loop.rs new file mode 100644 index 000000000000..f2edbcd99bec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/if-loop.rs @@ -0,0 +1,9 @@ +// check-pass + +// This used to ICE because the "if" being unreachable was not handled correctly +fn err() { + if loop {} {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/if/if-no-match-bindings.rs b/gcc/testsuite/rust/rustc/ui/if/if-no-match-bindings.rs new file mode 100644 index 000000000000..fcf6ea8d9cb6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/if-no-match-bindings.rs @@ -0,0 +1,29 @@ +// Checks for `if` expressions with respect to default match bindings. +// Specifically, we do not accept `if cond { ... }` where `cond: &mut? bool`. +// Meanwhile, `match cond { true => ..., _ => ... }` does accept that. + +// FIXME(@rust-lang/lang-team): consider relaxing this? + +fn b_ref<'a>() -> &'a bool { &true } +fn b_mut_ref<'a>() -> &'a mut bool { &mut true } + +fn main() { + // This is OK: + match b_ref() { true => {}, _ => {} } + match b_mut_ref() { true => {}, _ => {} } + match &true { true => {}, _ => {} } + match &mut true { true => {}, _ => {} } + + // This is NOT: + if b_ref() {} // { dg-error ".E0308." "" { target *-*-* } } + if b_mut_ref() {} // { dg-error ".E0308." "" { target *-*-* } } + if &true {} // { dg-error ".E0308." "" { target *-*-* } } + if &mut true {} // { dg-error ".E0308." "" { target *-*-* } } + + // This is also NOT: + while b_ref() {} // { dg-error ".E0308." "" { target *-*-* } } + while b_mut_ref() {} // { dg-error ".E0308." "" { target *-*-* } } + while &true {} // { dg-error ".E0308." "" { target *-*-* } } + while &mut true {} // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/if-typeck.rs b/gcc/testsuite/rust/rustc/ui/if/if-typeck.rs new file mode 100644 index 000000000000..4588c7b47a18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/if-typeck.rs @@ -0,0 +1,11 @@ +// error-pattern:mismatched types +// issue #513 + +fn f() { } + +fn main() { + + // f is not a bool + if f { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/if-without-block.rs b/gcc/testsuite/rust/rustc/ui/if/if-without-block.rs new file mode 100644 index 000000000000..8cac236bc4e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/if-without-block.rs @@ -0,0 +1,10 @@ +fn main() { + let n = 1; + if 5 == { +// { dg-note "" "" { target *-*-* } .-1 } + println!("five"); + } +} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/if/if-without-else-as-fn-expr.rs b/gcc/testsuite/rust/rustc/ui/if/if-without-else-as-fn-expr.rs new file mode 100644 index 000000000000..690ae918a4a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/if-without-else-as-fn-expr.rs @@ -0,0 +1,50 @@ +fn foo(bar: usize) -> usize { + if bar % 5 == 0 { + return 3; + } +// { dg-error ".E0317." "" { target *-*-* } .-3 } +} + +fn foo2(bar: usize) -> usize { + let x: usize = if bar % 5 == 0 { + return 3; + }; +// { dg-error ".E0317." "" { target *-*-* } .-3 } + x +} + +fn foo3(bar: usize) -> usize { + if bar % 5 == 0 { + 3 + } +// { dg-error ".E0317." "" { target *-*-* } .-3 } +} + +fn foo_let(bar: usize) -> usize { + if let 0 = 1 { + return 3; + } +// { dg-error ".E0317." "" { target *-*-* } .-3 } +} + +fn foo2_let(bar: usize) -> usize { + let x: usize = if let 0 = 1 { + return 3; + }; +// { dg-error ".E0317." "" { target *-*-* } .-3 } + x +} + +fn foo3_let(bar: usize) -> usize { + if let 0 = 1 { + 3 + } +// { dg-error ".E0317." "" { target *-*-* } .-3 } +} + +// FIXME(60254): deduplicate first error in favor of second. + +fn main() { + let _ = foo(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/if-without-else-result.rs b/gcc/testsuite/rust/rustc/ui/if/if-without-else-result.rs new file mode 100644 index 000000000000..f39bc3d0174e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/if-without-else-result.rs @@ -0,0 +1,7 @@ +fn main() { + let a = if true { true }; +// { dg-error ".E0317." "" { target *-*-* } .-1 } +// { dg-error ".E0317." "" { target *-*-* } .-2 } + println!("{}", a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/ifmt-bad-arg.rs b/gcc/testsuite/rust/rustc/ui/if/ifmt-bad-arg.rs new file mode 100644 index 000000000000..d95ea22a2120 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/ifmt-bad-arg.rs @@ -0,0 +1,95 @@ +fn main() { + // bad arguments to the format! call + + // bad number of arguments, see #44954 (originally #15780) + + format!("{}"); +// { dg-error "" "" { target *-*-* } .-1 } + + format!("{1}", 1); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + format!("{} {}"); +// { dg-error "" "" { target *-*-* } .-1 } + + format!("{0} {1}", 1); +// { dg-error "" "" { target *-*-* } .-1 } + + format!("{0} {1} {2}", 1, 2); +// { dg-error "" "" { target *-*-* } .-1 } + + format!("{} {value} {} {}", 1, value=2); +// { dg-error "" "" { target *-*-* } .-1 } + format!("{name} {value} {} {} {} {} {} {}", 0, name=1, value=2); +// { dg-error "" "" { target *-*-* } .-1 } + + format!("{} {foo} {} {bar} {}", 1, 2, 3); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + format!("{foo}"); // { dg-error "" "" { target *-*-* } } + format!("", 1, 2); // { dg-error "" "" { target *-*-* } } + format!("{}", 1, 2); // { dg-error "" "" { target *-*-* } } + format!("{1}", 1, 2); // { dg-error "" "" { target *-*-* } } + format!("{}", 1, foo=2); // { dg-error "" "" { target *-*-* } } + format!("{foo}", 1, foo=2); // { dg-error "" "" { target *-*-* } } + format!("", foo=2); // { dg-error "" "" { target *-*-* } } + format!("{} {}", 1, 2, foo=1, bar=2); // { dg-error "" "" { target *-*-* } } + + format!("{foo}", foo=1, foo=2); // { dg-error "" "" { target *-*-* } } + format!("{foo} {} {}", foo=1, 2); // { dg-error "" "" { target *-*-* } } + + // bad named arguments, #35082 + + format!("{valuea} {valueb}", valuea=5, valuec=7); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + // bad syntax of the format string + + format!("{"); // { dg-error "" "" { target *-*-* } } + + format!("foo } bar"); // { dg-error "" "" { target *-*-* } } + format!("foo }"); // { dg-error "" "" { target *-*-* } } + + format!("foo %s baz", "bar"); // { dg-error "" "" { target *-*-* } } + + format!(r##" + + {foo} + + "##); +// { dg-error "" "" { target *-*-* } .-3 } + + // bad syntax in format string with multiple newlines, #53836 + format!("first number: {} +second number: {} +third number: {} +fourth number: {} +fifth number: {} +sixth number: {} +seventh number: {} +eighth number: {} +ninth number: { +tenth number: {}", + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); +// { dg-error "" "" { target *-*-* } .-2 } + println!("{} {:.*} {}", 1, 3.2, 4); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + println!("{} {:07$.*} {}", 1, 3.2, 4); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + println!("{} {:07$} {}", 1, 3.2, 4); +// { dg-error "" "" { target *-*-* } .-1 } + println!("{:foo}", 1); // { dg-error "" "" { target *-*-* } } + println!("{5} {:4$} {6:7$}", 1); +// { dg-error "" "" { target *-*-* } .-1 } + + // We used to ICE here because we tried to unconditionally access the first argument, which + // doesn't exist. + println!("{:.*}"); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/ifmt-bad-format-args.rs b/gcc/testsuite/rust/rustc/ui/if/ifmt-bad-format-args.rs new file mode 100644 index 000000000000..38fb6b90ec1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/ifmt-bad-format-args.rs @@ -0,0 +1,5 @@ +fn main() { + format_args!(); // { dg-error "" "" { target *-*-* } } + format_args!(|| {}); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/ifmt-unimpl.rs b/gcc/testsuite/rust/rustc/ui/if/ifmt-unimpl.rs new file mode 100644 index 000000000000..0a6c84222a87 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/ifmt-unimpl.rs @@ -0,0 +1,5 @@ +fn main() { + format!("{:X}", "3"); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/if/ifmt-unknown-trait.rs b/gcc/testsuite/rust/rustc/ui/if/ifmt-unknown-trait.rs new file mode 100644 index 000000000000..4d86d8147601 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/if/ifmt-unknown-trait.rs @@ -0,0 +1,5 @@ +fn main() { + format!("{:notimplemented}", "3"); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/ignore-all-the-things.rs b/gcc/testsuite/rust/rustc/ui/ignore-all-the-things.rs new file mode 100644 index 000000000000..3346d4f83356 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ignore-all-the-things.rs @@ -0,0 +1,45 @@ +// run-pass + +#![allow(non_shorthand_field_patterns)] +#![allow(dead_code)] +#![allow(unused_variables)] + +struct Foo(isize, isize, isize, isize); +struct Bar{a: isize, b: isize, c: isize, d: isize} + +pub fn main() { + let Foo(..) = Foo(5, 5, 5, 5); + let Foo(..) = Foo(5, 5, 5, 5); + let Bar{..} = Bar{a: 5, b: 5, c: 5, d: 5}; + let (..) = (5, 5, 5, 5); + let Foo(a, b, ..) = Foo(5, 5, 5, 5); + let Foo(.., d) = Foo(5, 5, 5, 5); + let (a, b, ..) = (5, 5, 5, 5); + let (.., c, d) = (5, 5, 5, 5); + let Bar{b: b, ..} = Bar{a: 5, b: 5, c: 5, d: 5}; + match [5, 5, 5, 5] { + [..] => { } + } + match [5, 5, 5, 5] { + [a, ..] => { } + } + match [5, 5, 5, 5] { + [.., b] => { } + } + match [5, 5, 5, 5] { + [a, .., b] => { } + } + match [5, 5, 5] { + [..] => { } + } + match [5, 5, 5] { + [a, ..] => { } + } + match [5, 5, 5] { + [.., a] => { } + } + match [5, 5, 5] { + [a, .., b] => { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/illegal-ufcs-drop.rs b/gcc/testsuite/rust/rustc/ui/illegal-ufcs-drop.rs new file mode 100644 index 000000000000..16e8a8e3ecb6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/illegal-ufcs-drop.rs @@ -0,0 +1,10 @@ +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) {} +} + +fn main() { + Drop::drop(&mut Foo) // { dg-error ".E0040." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/immut-function-arguments.rs b/gcc/testsuite/rust/rustc/ui/immut-function-arguments.rs new file mode 100644 index 000000000000..babd56aa0419 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/immut-function-arguments.rs @@ -0,0 +1,10 @@ +fn f(y: Box) { + *y = 5; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn g() { + let _frob = |q: Box| { *q = 2; }; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-bounds-checking.rs b/gcc/testsuite/rust/rustc/ui/impl-bounds-checking.rs new file mode 100644 index 000000000000..6d39ceb066d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-bounds-checking.rs @@ -0,0 +1,15 @@ +pub trait Clone2 { + fn clone(&self) -> Self; +} + + +trait Getter { + fn get(&self) -> T; +} + +impl Getter for isize { // { dg-error ".E0277." "" { target *-*-* } } + fn get(&self) -> isize { *self } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-duplicate-methods.rs b/gcc/testsuite/rust/rustc/ui/impl-duplicate-methods.rs new file mode 100644 index 000000000000..68345d0d132b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-duplicate-methods.rs @@ -0,0 +1,10 @@ +struct Foo; + +impl Foo { + fn orange(&self) {} + fn orange(&self) {} +// { dg-error ".E0201." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/assoc-type.rs b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/assoc-type.rs new file mode 100644 index 000000000000..4a9c85a3fd7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/assoc-type.rs @@ -0,0 +1,26 @@ +// Test that we do not yet support elision in associated types, even +// when there is just one name we could take from the impl header. + +#![allow(warnings)] + +trait MyTrait { + type Output; +} + +impl MyTrait for &i32 { + type Output = &i32; +// { dg-error ".E0106." "" { target *-*-* } .-1 } +} + +impl MyTrait for &u32 { + type Output = &'_ i32; +// { dg-error ".E0106." "" { target *-*-* } .-1 } +} + +// This is what you have to do: +impl<'a> MyTrait for &'a f32 { + type Output = &'a f32; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/dyn-trait.rs b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/dyn-trait.rs new file mode 100644 index 000000000000..fd68bae26c9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/dyn-trait.rs @@ -0,0 +1,32 @@ +// Test that `impl MyTrait<'_> for &i32` is equivalent to `impl<'a, +// 'b> MyTrait<'a> for &'b i32`. + +#![allow(warnings)] + +use std::fmt::Debug; + +// Equivalent to `Box`: +trait StaticTrait { } +impl StaticTrait for Box { } + +// Equivalent to `Box`: +trait NotStaticTrait { } +impl NotStaticTrait for Box { } + +fn static_val(_: T) { +} + +fn with_dyn_debug_static<'a>(x: Box) { + static_val(x); // { dg-error ".E0759." "" { target *-*-* } } +} + +fn not_static_val(_: T) { +} + +fn with_dyn_debug_not_static<'a>(x: Box) { + not_static_val(x); // OK +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/explicit-and-elided-same-header.rs b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/explicit-and-elided-same-header.rs new file mode 100644 index 000000000000..09e241b2e435 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/explicit-and-elided-same-header.rs @@ -0,0 +1,14 @@ +// run-pass + +#![allow(warnings)] + +// This works for functions... +fn foo<'a>(x: &str, y: &'a str) {} + +// ...so this should work for impls +impl<'a> Foo<&str> for &'a str {} +trait Foo {} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/inherent-impl.rs b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/inherent-impl.rs new file mode 100644 index 000000000000..54ecb38a5858 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/inherent-impl.rs @@ -0,0 +1,10 @@ +// build-pass (FIXME(62277): could be check-pass?) + +struct Foo<'a>(&'a u8); + +impl Foo<'_> { + fn x() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/path-elided.rs b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/path-elided.rs new file mode 100644 index 000000000000..4911064b1ca7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/path-elided.rs @@ -0,0 +1,12 @@ +#![allow(warnings)] + +trait MyTrait { } + +struct Foo<'a> { x: &'a u32 } + +impl MyTrait for Foo { +// { dg-error ".E0726." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/path-underscore.rs b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/path-underscore.rs new file mode 100644 index 000000000000..af2e468f609f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/path-underscore.rs @@ -0,0 +1,35 @@ +// Test that `impl MyTrait for Foo<'_>` works. + +// run-pass + +#![allow(warnings)] + +trait MyTrait { } + +struct Foo<'a> { x: &'a u32 } + +impl MyTrait for Foo<'_> { +} + +fn impls_my_trait() { } + +fn impls_my_trait_val(_: T) { + impls_my_trait::(); +} + +fn random_where_clause() +where for<'a> Foo<'a>: MyTrait { } + +fn main() { + let x = 22; + let f = Foo { x: &x }; + + // This type is `Foo<'x>` for a local lifetime `'x`; so the impl + // must apply to any lifetime to apply to this. + impls_my_trait_val(f); + + impls_my_trait::>(); + + random_where_clause(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/ref-underscore.rs b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/ref-underscore.rs new file mode 100644 index 000000000000..debfc5337535 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/ref-underscore.rs @@ -0,0 +1,31 @@ +// Test that `impl MyTrait for &i32` works and is equivalent to any lifetime. + +// run-pass + +#![allow(warnings)] + +trait MyTrait { } + +impl MyTrait for &i32 { +} + +fn impls_my_trait() { } + +fn impls_my_trait_val(_: T) { + impls_my_trait::(); +} + +fn random_where_clause() +where for<'a> &'a i32: MyTrait { } + +fn main() { + let x = 22; + let f = &x; + + impls_my_trait_val(f); + + impls_my_trait::<&'static i32>(); + + random_where_clause(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/trait-elided.rs b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/trait-elided.rs new file mode 100644 index 000000000000..125072bc2641 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/trait-elided.rs @@ -0,0 +1,10 @@ +#![allow(warnings)] + +trait MyTrait<'a> { } + +impl MyTrait for u32 { +// { dg-error ".E0726." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/trait-underscore.rs b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/trait-underscore.rs new file mode 100644 index 000000000000..772801212f1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-header-lifetime-elision/trait-underscore.rs @@ -0,0 +1,36 @@ +// Test that `impl MyTrait<'_> for &i32` is equivalent to `impl<'a, +// 'b> MyTrait<'a> for &'b i32`. +// +// run-pass + +#![allow(warnings)] + +trait MyTrait<'a> { } + +// This is equivalent to `MyTrait<'a> for &'b i32`, which is proven by +// the code below. +impl MyTrait<'_> for &i32 { +} + +// When called, T will be `&'x i32` for some `'x`, so since we can +// prove that `&'x i32: for<'a> MyTrait<'a>, then we know that the +// lifetime parameter above is disconnected. +fn impls_my_trait MyTrait<'a>>() { } + +fn impls_my_trait_val MyTrait<'a>>(_: T) { + impls_my_trait::(); +} + +fn random_where_clause() +where for<'a, 'b> &'a i32: MyTrait<'b> { } + +fn main() { + let x = 22; + let f = &x; + impls_my_trait_val(f); + + impls_my_trait::<&'static i32>(); + + random_where_clause(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-inherent-non-conflict.rs b/gcc/testsuite/rust/rustc/ui/impl-inherent-non-conflict.rs new file mode 100644 index 000000000000..85dd1bcf568e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-inherent-non-conflict.rs @@ -0,0 +1,24 @@ +// run-pass +// Ensure that a user-defined type admits multiple inherent methods +// with the same name, which can be called on values that have a +// precise enough type to allow distinguishing between the methods. + + +struct Foo(T); + +impl Foo { + fn bar(&self) -> i32 { self.0 as i32 } +} + +impl Foo { + fn bar(&self) -> i32 { -(self.0 as i32) } +} + +fn main() { + let foo_u = Foo::(5); + assert_eq!(foo_u.bar(), 5); + + let foo_i = Foo::(3); + assert_eq!(foo_i.bar(), -3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-not-adjacent-to-type.rs b/gcc/testsuite/rust/rustc/ui/impl-not-adjacent-to-type.rs new file mode 100644 index 000000000000..030c20b07186 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-not-adjacent-to-type.rs @@ -0,0 +1,17 @@ +// run-pass + +mod foo { + pub struct Point { + pub x: i32, + pub y: i32, + } +} + +impl foo::Point { + fn x(&self) -> i32 { self.x } +} + +fn main() { + assert_eq!((foo::Point { x: 1, y: 3}).x(), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-privacy-xc-1.rs b/gcc/testsuite/rust/rustc/ui/impl-privacy-xc-1.rs new file mode 100644 index 000000000000..2251e5d6f09f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-privacy-xc-1.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:impl_privacy_xc_1.rs + +// pretty-expanded FIXME #23616 + +extern crate impl_privacy_xc_1; + +pub fn main() { + let fish = impl_privacy_xc_1::Fish { x: 1 }; + fish.swim(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-privacy-xc-2.rs b/gcc/testsuite/rust/rustc/ui/impl-privacy-xc-2.rs new file mode 100644 index 000000000000..3ec2eb6dc0a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-privacy-xc-2.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:impl_privacy_xc_2.rs + +extern crate impl_privacy_xc_2; + +pub fn main() { + let fish1 = impl_privacy_xc_2::Fish { x: 1 }; + let fish2 = impl_privacy_xc_2::Fish { x: 2 }; + if fish1.eq(&fish2) { println!("yes") } else { println!("no") }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait-in-bindings-issue-73003.rs b/gcc/testsuite/rust/rustc/ui/impl-trait-in-bindings-issue-73003.rs new file mode 100644 index 000000000000..c6253c6b1ec7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait-in-bindings-issue-73003.rs @@ -0,0 +1,9 @@ +// check-pass + +#![feature(impl_trait_in_bindings)] +// { dg-warning "" "" { target *-*-* } .-1 } + +const _: impl Fn() = ||(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait-in-bindings.rs b/gcc/testsuite/rust/rustc/ui/impl-trait-in-bindings.rs new file mode 100644 index 000000000000..da7f48ce71a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait-in-bindings.rs @@ -0,0 +1,50 @@ +// run-pass + +#![feature(impl_trait_in_bindings)] +// { dg-warning "" "" { target *-*-* } .-1 } + +use std::fmt::Debug; + +const FOO: impl Debug + Clone + PartialEq = 42; + +static BAR: impl Debug + Clone + PartialEq = 42; + +fn a(x: T) { + let y: impl Clone = x; + let _ = y.clone(); +} + +fn b(x: T) { + let f = move || { + let y: impl Clone = x; + let _ = y.clone(); + }; + f(); +} + +trait Foo { + fn a(x: T) { + let y: impl Clone = x; + let _ = y.clone(); + } +} + +impl Foo for i32 { + fn a(x: T) { + let y: impl Clone = x; + let _ = y.clone(); + } +} + +fn main() { + let foo: impl Debug + Clone + PartialEq = 42; + + assert_eq!(FOO.clone(), 42); + assert_eq!(BAR.clone(), 42); + assert_eq!(foo.clone(), 42); + + a(42); + b(42); + i32::a(42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/associated-impl-trait-type-generic-trait.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/associated-impl-trait-type-generic-trait.rs new file mode 100644 index 000000000000..397003942c33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/associated-impl-trait-type-generic-trait.rs @@ -0,0 +1,31 @@ +#![feature(type_alias_impl_trait)] +// build-pass (FIXME(62277): could be check-pass?) + +trait Bar {} +struct Dummy(U); +impl Bar for Dummy {} + +trait Foo { + type Assoc: Bar; + fn foo(t: T) -> Self::Assoc; +} + +impl Foo for i32 { + type Assoc = impl Bar; + fn foo(w: W) -> Self::Assoc { + Dummy(w) + } +} + +struct NonGeneric; +impl Bar for NonGeneric {} + +impl Foo for u32 { + type Assoc = impl Bar; + fn foo(_: W) -> Self::Assoc { + NonGeneric + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/associated-impl-trait-type-trivial.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/associated-impl-trait-type-trivial.rs new file mode 100644 index 000000000000..cbb69768a051 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/associated-impl-trait-type-trivial.rs @@ -0,0 +1,21 @@ +#![feature(type_alias_impl_trait)] +// build-pass (FIXME(62277): could be check-pass?) + +trait Bar {} +struct Dummy; +impl Bar for Dummy {} + +trait Foo { + type Assoc: Bar; + fn foo() -> Self::Assoc; +} + +impl Foo for i32 { + type Assoc = impl Bar; + fn foo() -> Self::Assoc { + Dummy + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/associated-impl-trait-type.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/associated-impl-trait-type.rs new file mode 100644 index 000000000000..74e35f463f82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/associated-impl-trait-type.rs @@ -0,0 +1,25 @@ +#![feature(type_alias_impl_trait)] +// build-pass (FIXME(62277): could be check-pass?) + +trait Bar {} +struct Dummy; +impl Bar for Dummy {} + +trait Foo { + type Assoc: Bar; + fn foo() -> Self::Assoc; + fn bar() -> Self::Assoc; +} + +impl Foo for i32 { + type Assoc = impl Bar; + fn foo() -> Self::Assoc { + Dummy + } + fn bar() -> Self::Assoc { + Dummy + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait-leak-rpass.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait-leak-rpass.rs new file mode 100644 index 000000000000..02789bd49c9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait-leak-rpass.rs @@ -0,0 +1,22 @@ +// run-pass + +// Fast path, main can see the concrete type returned. +fn before() -> impl FnMut(i32) { + let mut p = Box::new(0); + move |x| *p = x +} + +fn send(_: T) {} + +fn main() { + send(before()); + send(after()); +} + +// Deferred path, main has to wait until typeck finishes, +// to check if the return type of after is Send. +fn after() -> impl FnMut(i32) { + let mut p = Box::new(0); + move |x| *p = x +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait-leak.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait-leak.rs new file mode 100644 index 000000000000..8ca199545e71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait-leak.rs @@ -0,0 +1,25 @@ +use std::cell::Cell; +use std::rc::Rc; + +fn send(_: T) {} + +fn main() { +} + +// Cycles should work as the deferred obligations are +// independently resolved and only require the concrete +// return type, which can't depend on the obligation. +fn cycle1() -> impl Clone { +// { dg-error ".E0391." "" { target *-*-* } .-1 } + send(cycle2().clone()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + Rc::new(Cell::new(5)) +} + +fn cycle2() -> impl Clone { + send(cycle1().clone()); + + Rc::new(String::from("foo")) +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait-leak2.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait-leak2.rs new file mode 100644 index 000000000000..6d5e622ce630 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait-leak2.rs @@ -0,0 +1,26 @@ +use std::cell::Cell; +use std::rc::Rc; + +// Fast path, main can see the concrete type returned. +fn before() -> impl Fn(i32) { + let p = Rc::new(Cell::new(0)); + move |x| p.set(x) +} + +fn send(_: T) {} + +fn main() { + send(before()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + send(after()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +// Deferred path, main has to wait until typeck finishes, +// to check if the return type of after is Send. +fn after() -> impl Fn(i32) { + let p = Rc::new(Cell::new(0)); + move |x| p.set(x) +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait.rs new file mode 100644 index 000000000000..77cfca411a5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/auto-trait.rs @@ -0,0 +1,26 @@ +// Tests that type alias impls traits do not leak auto-traits for +// the purposes of coherence checking +#![feature(type_alias_impl_trait)] + +trait OpaqueTrait {} +impl OpaqueTrait for T {} +type OpaqueType = impl OpaqueTrait; +fn mk_opaque() -> OpaqueType { + () +} + +#[derive(Debug)] +struct D(T); + +trait AnotherTrait {} +impl AnotherTrait for T {} + +// This is in error, because we cannot assume that `OpaqueType: !Send`. +// (We treat opaque types as "foreign types" that could grow more impls +// in the future.) +impl AnotherTrait for D { +// { dg-error ".E0119." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/auxiliary/extra-item.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/auxiliary/extra-item.rs new file mode 100644 index 000000000000..dab3b3af5856 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/auxiliary/extra-item.rs @@ -0,0 +1,2 @@ +pub trait MyTrait {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/auxiliary/no_method_suggested_traits.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/auxiliary/no_method_suggested_traits.rs new file mode 100644 index 000000000000..815ddbeafcdd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/auxiliary/no_method_suggested_traits.rs @@ -0,0 +1,37 @@ +pub use reexport::Reexported; + +pub struct Foo; +pub enum Bar { X } + +pub mod foo { + pub trait PubPub { + fn method(&self) {} + + fn method3(&self) {} + } + + impl PubPub for u32 {} + impl PubPub for i32 {} +} +pub mod bar { + trait PubPriv { + fn method(&self); + } +} +mod qux { + pub trait PrivPub { + fn method(&self); + } +} +mod quz { + trait PrivPriv { + fn method(&self); + } +} + +mod reexport { + pub trait Reexported { + fn method(&self); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/auxiliary/xcrate.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/auxiliary/xcrate.rs new file mode 100644 index 000000000000..d2018debcdcf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/auxiliary/xcrate.rs @@ -0,0 +1,24 @@ +// NOTE commented out due to issue #45994 +//pub fn fourway_add(a: i32) -> impl Fn(i32) -> impl Fn(i32) -> impl Fn(i32) -> i32 { +// move |b| move |c| move |d| a + b + c + d +//} + +fn some_internal_fn() -> u32 { + 1 +} + +fn other_internal_fn() -> u32 { + 1 +} + +// See #40839 +pub fn return_closure_accessing_internal_fn() -> impl Fn() -> u32 { + || { + some_internal_fn() + 1 + } +} + +pub fn return_internal_fn() -> impl Fn() -> u32 { + other_internal_fn +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/binding-without-value.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/binding-without-value.rs new file mode 100644 index 000000000000..a2d553bfa316 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/binding-without-value.rs @@ -0,0 +1,10 @@ +#![allow(incomplete_features)] +#![feature(impl_trait_in_bindings)] + +fn foo() { + let _ : impl Copy; +// { dg-error ".E0720." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/bindings-opaque.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/bindings-opaque.rs new file mode 100644 index 000000000000..01c593543d37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/bindings-opaque.rs @@ -0,0 +1,18 @@ +#![feature(impl_trait_in_bindings)] +// { dg-warning "" "" { target *-*-* } .-1 } + +const FOO: impl Copy = 42; + +static BAR: impl Copy = 42; + +fn main() { + let foo: impl Copy = 42; + + let _ = FOO.count_ones(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + let _ = BAR.count_ones(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + let _ = foo.count_ones(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/bindings.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/bindings.rs new file mode 100644 index 000000000000..e2b6b17674cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/bindings.rs @@ -0,0 +1,31 @@ +#![feature(impl_trait_in_bindings)] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn a(x: T) { + const foo: impl Clone = x; +// { dg-error ".E0435." "" { target *-*-* } .-1 } +} + +fn b(x: T) { + let _ = move || { + const foo: impl Clone = x; +// { dg-error ".E0435." "" { target *-*-* } .-1 } + }; +} + +trait Foo { + fn a(x: T) { + const foo: impl Clone = x; +// { dg-error ".E0435." "" { target *-*-* } .-1 } + } +} + +impl Foo for i32 { + fn a(x: T) { + const foo: impl Clone = x; +// { dg-error ".E0435." "" { target *-*-* } .-1 } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/bound-normalization-fail.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/bound-normalization-fail.rs new file mode 100644 index 000000000000..0ffc7dd0e724 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/bound-normalization-fail.rs @@ -0,0 +1,51 @@ +// ignore-tidy-linelength +// edition:2018 + +#![feature(impl_trait_in_bindings)] +// { dg-warning "" "" { target *-*-* } .-1 } + +// See issue 60414 + +// Reduction to `impl Trait` + +struct Foo(T); + +trait FooLike { type Output; } + +impl FooLike for Foo { + type Output = T; +} + +mod impl_trait { + use super::*; + + trait Trait { + type Assoc; + } + + /// `T::Assoc` can't be normalized any further here. + fn foo_fail() -> impl FooLike { +// { dg-error ".E0271." "" { target *-*-* } .-1 } + Foo(()) + } +} + +// Same with lifetimes in the trait + +mod lifetimes { + use super::*; + + trait Trait<'a> { + type Assoc; + } + + /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further. + fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { +// { dg-error ".E0271." "" { target *-*-* } .-1 } +// { dg-error ".E0271." "" { target *-*-* } .-2 } + Foo(()) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/bound-normalization-pass.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/bound-normalization-pass.rs new file mode 100644 index 000000000000..463cb5c84b55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/bound-normalization-pass.rs @@ -0,0 +1,108 @@ +// check-pass +// edition:2018 +// revisions: default sa +//[sa] compile-flags: -Z save-analysis +//-^ To make this the regression test for #75962. + +#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_bindings)] +// { dg-warning "" "" { target *-*-* } .-1 } + +// See issue 60414 + +// Reduction to `impl Trait` + +struct Foo(T); + +trait FooLike { type Output; } + +impl FooLike for Foo { + type Output = T; +} + +mod impl_trait { + use super::*; + + trait Trait { + type Assoc; + } + + /// `T::Assoc` should be normalized to `()` here. + fn foo_pass>() -> impl FooLike { + Foo(()) + } +} + +// Same with lifetimes in the trait + +mod lifetimes { + use super::*; + + trait Trait<'a> { + type Assoc; + } + + /// Like above. + /// + /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here + fn foo2_pass<'a, T: Trait<'a, Assoc=()> + 'a>( + ) -> impl FooLike>::Assoc> + 'a { + Foo(()) + } + + /// Normalization to type containing bound region. + /// + /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here + fn foo2_pass2<'a, T: Trait<'a, Assoc=&'a ()> + 'a>( + ) -> impl FooLike>::Assoc> + 'a { + Foo(&()) + } +} + +// Reduction using `impl Trait` in bindings + +mod impl_trait_in_bindings { + struct Foo; + + trait FooLike { type Output; } + + impl FooLike for Foo { + type Output = u32; + } + + trait Trait { + type Assoc; + } + + fn foo>() { + let _: impl FooLike = Foo; + } +} + +// The same applied to `type Foo = impl Bar`s + +mod opaque_types { + trait Implemented { + type Assoc; + } + impl Implemented for T { + type Assoc = u8; + } + + trait Trait { + type Out; + } + + impl Trait for () { + type Out = u8; + } + + type Ex = impl Trait::Assoc>; + + fn define() -> Ex { + () + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/bounds_regression.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/bounds_regression.rs new file mode 100644 index 000000000000..5131dc3f4cb2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/bounds_regression.rs @@ -0,0 +1,25 @@ +// run-pass + +pub trait FakeGenerator { + type Yield; + type Return; +} + +pub trait FakeFuture { + type Output; +} + +pub fn future_from_generator< + T: FakeGenerator +>(x: T) -> impl FakeFuture { + GenFuture(x) +} + +struct GenFuture>(T); + +impl> FakeFuture for GenFuture { + type Output = T::Return; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/can-return-unconstrained-closure.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/can-return-unconstrained-closure.rs new file mode 100644 index 000000000000..7b47348c0aab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/can-return-unconstrained-closure.rs @@ -0,0 +1,24 @@ +// Test that we are special casing "outlives" for opaque types. +// +// The return type of a closure is not required to outlive the closure. As such +// the following code would not compile if we used a standard outlives check +// when checking the return type, because the return type of the closure would +// be `&ReEmpty i32`, and we don't allow `ReEmpty` to occur in the concrete +// type used for an opaque type. +// +// However, opaque types are special cased to include check all regions in the +// concrete type against the bound, which forces the return type to be +// `&'static i32` here. + +// build-pass (FIXME(62277): could be check-pass?) + +fn make_identity() -> impl Sized { + |x: &'static i32| x +} + +fn make_identity_static() -> impl Sized + 'static { + |x: &'static i32| x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/closure-calling-parent-fn.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/closure-calling-parent-fn.rs new file mode 100644 index 000000000000..607587e88951 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/closure-calling-parent-fn.rs @@ -0,0 +1,13 @@ +// Regression test for #54593: the MIR type checker was going wrong +// when a closure returns the `impl Copy` from its parent fn. It was +// (incorrectly) replacing the `impl Copy` in its return type with the +// hidden type (`()`) but that type resulted from a recursive call to +// `foo` and hence is treated opaquely within the closure body. This +// resulted in a failed subtype relationship. +// +// check-pass + +fn foo() -> impl Copy { || foo(); } +fn bar() -> impl Copy { || bar(); } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/closure-in-impl-trait-arg.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/closure-in-impl-trait-arg.rs new file mode 100644 index 000000000000..a23303f38a7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/closure-in-impl-trait-arg.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(unused_must_use)] +fn bug(_: impl Iterator) {} + +fn main() { + bug(std::iter::empty()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/closure-in-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/closure-in-impl-trait.rs new file mode 100644 index 000000000000..659f0bfe9dd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/closure-in-impl-trait.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(unused_must_use)] +fn bug() -> impl Iterator { + std::iter::empty() +} + +fn ok() -> Box> { + Box::new(std::iter::empty()) +} + +fn main() { + for _item in ok::() {} + for _item in bug::() {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/deprecated_annotation.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/deprecated_annotation.rs new file mode 100644 index 000000000000..1cd58de697ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/deprecated_annotation.rs @@ -0,0 +1,20 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![deny(warnings)] + +#[deprecated] +trait Deprecated {} + +#[deprecated] +struct DeprecatedTy; + +#[allow(deprecated)] +impl Deprecated for DeprecatedTy {} + +#[allow(deprecated)] +fn foo() -> impl Deprecated { DeprecatedTy } + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/does-not-live-long-enough.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/does-not-live-long-enough.rs new file mode 100644 index 000000000000..2cee7ea3dc00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/does-not-live-long-enough.rs @@ -0,0 +1,12 @@ +struct List { + data: Vec, +} +impl List { + fn started_with<'a>(&'a self, prefix: &'a str) -> impl Iterator { + self.data.iter().filter(|s| s.starts_with(prefix)).map(|s| s.as_ref()) +// { dg-error ".E0373." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-assoc.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-assoc.rs new file mode 100644 index 000000000000..da4d7bc83f2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-assoc.rs @@ -0,0 +1,17 @@ +// Test that we don't get an error with `dyn Bar` in an impl Trait +// when there are multiple inputs. The `dyn Bar` should default to `+ +// 'static`. This used to erroneously generate an error (cc #62517). +// +// check-pass + +trait Foo { type Item: ?Sized; } +trait Bar { } + +impl Foo for T { + type Item = dyn Bar; +} + +fn foo(x: &str, y: &str) -> impl Foo { () } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-param.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-param.rs new file mode 100644 index 000000000000..544d2f66520f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-param.rs @@ -0,0 +1,12 @@ +// Test that we don't get an error with `dyn Object` in an impl Trait +// when there are multiple inputs. The `dyn Object` should default to `+ +// 'static`. This used to erroneously generate an error (cc #62517). +// +// check-pass + +trait Alpha {} +trait Object {} +impl Alpha for T {} +fn alpha(x: &str, y: &str) -> impl Alpha { () } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs new file mode 100644 index 000000000000..6d9d8920648b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-ref-assoc.rs @@ -0,0 +1,28 @@ +// Test that we don't get an error with `dyn Bar` in an impl Trait +// when there are multiple inputs. The `dyn Bar` should default to `+ +// 'static`. This used to erroneously generate an error (cc #62517). +// +// check-pass + +trait Foo { + type Item: ?Sized; + + fn item(&self) -> Box { panic!() } +} + +trait Bar { } + +impl Foo for T { + type Item = dyn Bar; +} + +fn is_static(_: T) where T: 'static { } + +fn bar(x: &str) -> &impl Foo { &() } + +fn main() { + let s = format!("foo"); + let r = bar(&s); + is_static(r.item()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-ref-param.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-ref-param.rs new file mode 100644 index 000000000000..903af29cf4ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-elided-two-inputs-ref-param.rs @@ -0,0 +1,24 @@ +// Test that `impl Alpha` resets the object-lifetime +// default to `'static`. +// +// check-pass + +trait Alpha { + fn item(&self) -> Box { + panic!() + } +} + +trait Object {} +impl Alpha for T {} +fn alpha(x: &str, y: &str) -> impl Alpha { () } +fn is_static(_: T) where T: 'static { } + +fn bar(x: &str) -> &impl Alpha { &() } + +fn main() { + let s = format!("foo"); + let r = bar(&s); + is_static(r.item()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs new file mode 100644 index 000000000000..24cb55f93aae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs @@ -0,0 +1,75 @@ +#![allow(bare_trait_objects)] +struct Struct; +trait Trait {} +impl Trait for Struct {} +impl Trait for u32 {} + +fn fuz() -> (usize, Trait) { (42, Struct) } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +fn bar() -> (usize, dyn Trait) { (42, Struct) } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +fn bap() -> Trait { Struct } +// { dg-error ".E0746." "" { target *-*-* } .-1 } +fn ban() -> dyn Trait { Struct } +// { dg-error ".E0746." "" { target *-*-* } .-1 } +fn bak() -> dyn Trait { unimplemented!() } // { dg-error ".E0746." "" { target *-*-* } } +// Suggest using `Box` +fn bal() -> dyn Trait { // { dg-error ".E0746." "" { target *-*-* } } + if true { + return Struct; + } + 42 +} +fn bax() -> dyn Trait { // { dg-error ".E0746." "" { target *-*-* } } + if true { + Struct + } else { + 42 // { dg-error ".E0308." "" { target *-*-* } } + } +} +fn bam() -> Box { + if true { + return Struct; // { dg-error ".E0308." "" { target *-*-* } } + } + 42 // { dg-error ".E0308." "" { target *-*-* } } +} +fn baq() -> Box { + if true { + return 0; // { dg-error ".E0308." "" { target *-*-* } } + } + 42 // { dg-error ".E0308." "" { target *-*-* } } +} +fn baz() -> Box { + if true { + Struct // { dg-error ".E0308." "" { target *-*-* } } + } else { + 42 // { dg-error ".E0308." "" { target *-*-* } } + } +} +fn baw() -> Box { + if true { + 0 // { dg-error ".E0308." "" { target *-*-* } } + } else { + 42 // { dg-error ".E0308." "" { target *-*-* } } + } +} + +// Suggest using `impl Trait` +fn bat() -> dyn Trait { // { dg-error ".E0746." "" { target *-*-* } } + if true { + return 0; + } + 42 +} +fn bay() -> dyn Trait { // { dg-error ".E0746." "" { target *-*-* } } + if true { + 0 + } else { + 42 + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/equal-hidden-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/equal-hidden-lifetimes.rs new file mode 100644 index 000000000000..fd8659a318ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/equal-hidden-lifetimes.rs @@ -0,0 +1,50 @@ +// Test that we consider equal regions when checking for hidden regions in +// opaque types + +// check-pass + +// `'a == 'static` so `&'a i32` is fine as the return type +fn equal_regions_static<'a: 'static>(x: &'a i32) -> impl Sized { +// { dg-warning "" "" { target *-*-* } .-1 } + x +} + +// `'a == 'b` so `&'b i32` is fine as the return type +fn equal_regions<'a: 'b, 'b: 'a>(x: &'b i32) -> impl Sized + 'a { + let y: &'a i32 = x; + let z: &'b i32 = y; + x +} + +// `'a == 'b` so `&'a i32` is fine as the return type +fn equal_regions_rev<'a: 'b, 'b: 'a>(x: &'a i32) -> impl Sized + 'b { + let y: &'a i32 = x; + let z: &'b i32 = y; + x +} + +// `'a == 'b` so `*mut &'b i32` is fine as the return type +fn equal_regions_inv<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { + let y: *mut &'a i32 = x; + let z: *mut &'b i32 = y; + x +} + +// `'a == 'b` so `*mut &'a i32` is fine as the return type +fn equal_regions_inv_rev<'a: 'b, 'b: 'a>(x: *mut &'a i32) -> impl Sized + 'b { + let y: *mut &'a i32 = x; + let z: *mut &'b i32 = y; + x +} + +// Should be able to infer `fn(&'static ())` as the return type. +fn contravariant_lub<'a, 'b: 'a, 'c: 'a, 'd: 'b + 'c>( + x: fn(&'b ()), + y: fn(&'c ()), + c: bool, +) -> impl Sized + 'a { + if c { x } else { y } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/equality-rpass.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/equality-rpass.rs new file mode 100644 index 000000000000..5eb7f160b135 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/equality-rpass.rs @@ -0,0 +1,49 @@ +// run-pass + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Foo: std::fmt::Debug + Eq {} + +impl Foo for T {} + +fn hide(x: T) -> impl Foo { + x +} + +trait Leak: Sized { + fn leak(self) -> T; +} +impl Leak for U { + default fn leak(self) -> T { panic!("type mismatch") } +} +impl Leak for T { + fn leak(self) -> T { self } +} + +trait CheckIfSend: Sized { + type T: Default; + fn check(self) -> Self::T { Default::default() } +} +impl CheckIfSend for T { + default type T = (); +} +impl CheckIfSend for T { + type T = bool; +} + +fn lucky_seven() -> impl Fn(usize) -> u8 { + let a = [1, 2, 3, 4, 5, 6, 7]; + move |i| a[i] +} + +fn main() { + assert_eq!(hide(42), hide(42)); + + assert_eq!(std::mem::size_of_val(&hide([0_u8; 5])), 5); + assert_eq!(std::mem::size_of_val(&lucky_seven()), 7); + + assert_eq!(Leak::::leak(hide(5_i32)), 5_i32); + + assert_eq!(CheckIfSend::check(hide(0_i32)), false); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/equality.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/equality.rs new file mode 100644 index 000000000000..fbca7ab0837d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/equality.rs @@ -0,0 +1,44 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Foo: Copy + ToString {} + +impl Foo for T {} + +fn hide(x: T) -> impl Foo { + x +} + +fn two(x: bool) -> impl Foo { + if x { + return 1_i32; + } + 0_u32 +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn sum_to(n: u32) -> impl Foo { + if n == 0 { + 0 + } else { + n + sum_to(n - 1) +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } +} + +trait Leak: Sized { + type T; + fn leak(self) -> Self::T; +} +impl Leak for T { + default type T = (); + default fn leak(self) -> Self::T { panic!() } +} +impl Leak for i32 { + type T = i32; + fn leak(self) -> i32 { self } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/equality2.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/equality2.rs new file mode 100644 index 000000000000..bbbc1c0805b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/equality2.rs @@ -0,0 +1,45 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Foo: Copy + ToString {} + +impl Foo for T {} + +fn hide(x: T) -> impl Foo { + x +} + +trait Leak: Sized { + type T; + fn leak(self) -> Self::T; +} +impl Leak for T { + default type T = (); + default fn leak(self) -> Self::T { panic!() } +} +impl Leak for i32 { + type T = i32; + fn leak(self) -> i32 { self } +} + +fn main() { + let _: u32 = hide(0_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + let _: i32 = Leak::leak(hide(0_i32)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + let mut x = (hide(0_u32), hide(0_i32)); + x = (x.1, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + x.0); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/example-calendar.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/example-calendar.rs new file mode 100644 index 000000000000..2cb8f7518999 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/example-calendar.rs @@ -0,0 +1,843 @@ +// run-pass +// ignore-compare-mode-chalk + +#![feature(fn_traits, + step_trait, + step_trait_ext, + unboxed_closures, +)] + +//! Derived from: . +//! +//! Originally converted to Rust by [Daniel Keep](https://github.com/DanielKeep). + +use std::fmt::Write; + +/// Date representation. +#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +struct NaiveDate(i32, u32, u32); + +impl NaiveDate { + pub fn from_ymd(y: i32, m: u32, d: u32) -> NaiveDate { + assert!(1 <= m && m <= 12, "m = {:?}", m); + assert!(1 <= d && d <= NaiveDate(y, m, 1).days_in_month(), "d = {:?}", d); + NaiveDate(y, m, d) + } + + pub fn year(&self) -> i32 { + self.0 + } + + pub fn month(&self) -> u32 { + self.1 + } + + pub fn day(&self) -> u32 { + self.2 + } + + pub fn succ(&self) -> NaiveDate { + let (mut y, mut m, mut d, n) = ( + self.year(), self.month(), self.day()+1, self.days_in_month()); + if d > n { + d = 1; + m += 1; + } + if m > 12 { + m = 1; + y += 1; + } + NaiveDate::from_ymd(y, m, d) + } + + pub fn weekday(&self) -> Weekday { + use Weekday::*; + + // 0 = Sunday + let year = self.year(); + let dow_jan_1 = (year*365 + ((year-1) / 4) - ((year-1) / 100) + ((year-1) / 400)) % 7; + let dow = (dow_jan_1 + (self.day_of_year() as i32 - 1)) % 7; + [Sun, Mon, Tue, Wed, Thu, Fri, Sat][dow as usize] + } + + pub fn isoweekdate(&self) -> (i32, u32, Weekday) { + let first_dow_mon_0 = self.year_first_day_of_week().num_days_from_monday(); + + // Work out this date's DOtY and week number, not including year adjustment. + let doy_0 = self.day_of_year() - 1; + let mut week_mon_0: i32 = ((first_dow_mon_0 + doy_0) / 7) as i32; + + if self.first_week_in_prev_year() { + week_mon_0 -= 1; + } + + let weeks_in_year = self.last_week_number(); + + // Work out the final result. + // If the week is `-1` or `>= weeks_in_year`, we will need to adjust the year. + let year = self.year(); + let wd = self.weekday(); + + if week_mon_0 < 0 { + (year - 1, NaiveDate::from_ymd(year - 1, 1, 1).last_week_number(), wd) + } else if week_mon_0 >= weeks_in_year as i32 { + (year + 1, (week_mon_0 + 1 - weeks_in_year as i32) as u32, wd) + } else { + (year, (week_mon_0 + 1) as u32, wd) + } + } + + fn first_week_in_prev_year(&self) -> bool { + let first_dow_mon_0 = self.year_first_day_of_week().num_days_from_monday(); + + // Any day in the year *before* the first Monday of that year + // is considered to be in the last week of the previous year, + // assuming the first week has *less* than four days in it. + // Adjust the week appropriately. + ((7 - first_dow_mon_0) % 7) < 4 + } + + fn year_first_day_of_week(&self) -> Weekday { + NaiveDate::from_ymd(self.year(), 1, 1).weekday() + } + + fn weeks_in_year(&self) -> u32 { + let days_in_last_week = self.year_first_day_of_week().num_days_from_monday() + 1; + if days_in_last_week >= 4 { 53 } else { 52 } + } + + fn last_week_number(&self) -> u32 { + let wiy = self.weeks_in_year(); + if self.first_week_in_prev_year() { wiy - 1 } else { wiy } + } + + fn day_of_year(&self) -> u32 { + (1..self.1).map(|m| NaiveDate::from_ymd(self.year(), m, 1).days_in_month()) + .fold(0, |a,b| a+b) + self.day() + } + + fn is_leap_year(&self) -> bool { + let year = self.year(); + if year % 4 != 0 { + return false + } else if year % 100 != 0 { + return true + } else if year % 400 != 0 { + return false + } else { + return true + } + } + + fn days_in_month(&self) -> u32 { + match self.month() { + /* Jan */ 1 => 31, + /* Feb */ 2 => if self.is_leap_year() { 29 } else { 28 }, + /* Mar */ 3 => 31, + /* Apr */ 4 => 30, + /* May */ 5 => 31, + /* Jun */ 6 => 30, + /* Jul */ 7 => 31, + /* Aug */ 8 => 31, + /* Sep */ 9 => 30, + /* Oct */ 10 => 31, + /* Nov */ 11 => 30, + /* Dec */ 12 => 31, + _ => unreachable!() + } + } +} + +impl<'a, 'b> std::ops::Add<&'b NaiveDate> for &'a NaiveDate { + type Output = NaiveDate; + + fn add(self, other: &'b NaiveDate) -> NaiveDate { + assert_eq!(*other, NaiveDate(0, 0, 1)); + self.succ() + } +} + +unsafe impl std::iter::Step for NaiveDate { + fn steps_between(_: &Self, _: &Self) -> Option { + unimplemented!() + } + + fn forward_checked(start: Self, n: usize) -> Option { + Some((0..n).fold(start, |x, _| x.succ())) + } + + fn backward_checked(_: Self, _: usize) -> Option { + unimplemented!() + } +} + +#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum Weekday { + Mon, + Tue, + Wed, + Thu, + Fri, + Sat, + Sun, +} + +impl Weekday { + pub fn num_days_from_monday(&self) -> u32 { + use Weekday::*; + match *self { + Mon => 0, + Tue => 1, + Wed => 2, + Thu => 3, + Fri => 4, + Sat => 5, + Sun => 6, + } + } + + pub fn num_days_from_sunday(&self) -> u32 { + use Weekday::*; + match *self { + Sun => 0, + Mon => 1, + Tue => 2, + Wed => 3, + Thu => 4, + Fri => 5, + Sat => 6, + } + } +} + +/// `GroupBy` implementation. +struct GroupBy { + it: std::iter::Peekable, + f: F, +} + +impl Clone for GroupBy +where + It: Iterator + Clone, + It::Item: Clone, + F: Clone, +{ + fn clone(&self) -> Self { + GroupBy { + it: self.it.clone(), + f: self.f.clone(), + } + } +} + +impl<'a, G, It: 'a, F: 'a> Iterator for GroupBy +where It: Iterator + Clone, + It::Item: Clone, + F: Clone + FnMut(&It::Item) -> G, + G: Eq + Clone +{ + type Item = (G, InGroup, F, G>); + + fn next(&mut self) -> Option { + self.it.peek().map(&mut self.f).map(|key| { + let start = self.it.clone(); + while let Some(k) = self.it.peek().map(&mut self.f) { + if key != k { + break; + } + self.it.next(); + } + + (key.clone(), InGroup { + it: start, + f: self.f.clone(), + g: key + }) + }) + } +} + +#[derive(Copy, Clone)] +struct InGroup { + it: It, + f: F, + g: G +} + +impl G, G: Eq> Iterator for InGroup { + type Item = It::Item; + + fn next(&mut self) -> Option { + self.it.next().and_then(|x| { + if (self.f)(&x) == self.g { Some(x) } else { None } + }) + } +} + +trait IteratorExt: Iterator + Sized { + fn group_by(self, f: F) -> GroupBy + where F: Clone + FnMut(&Self::Item) -> G, + G: Eq + { + GroupBy { it: self.peekable(), f } + } + + fn join(mut self, sep: &str) -> String + where Self::Item: std::fmt::Display { + let mut s = String::new(); + if let Some(e) = self.next() { + write!(s, "{}", e).unwrap(); + for e in self { + s.push_str(sep); + write!(s, "{}", e).unwrap(); + } + } + s + } + + // HACK(eddyb): only needed because `impl Trait` can't be + // used with trait methods: `.foo()` becomes `.__(foo)`. + fn __(self, f: F) -> R + where F: FnOnce(Self) -> R { + f(self) + } +} + +impl IteratorExt for It where It: Iterator {} + +/// Generates an iterator that yields exactly `n` spaces. +fn spaces(n: usize) -> std::iter::Take> { + std::iter::repeat(' ').take(n) +} + +fn test_spaces() { + assert_eq!(spaces(0).collect::(), ""); + assert_eq!(spaces(10).collect::(), " ") +} + +/// Returns an iterator of dates in a given year. +fn dates_in_year(year: i32) -> impl Iterator+Clone { + InGroup { + it: NaiveDate::from_ymd(year, 1, 1).., + f: |d: &NaiveDate| d.year(), + g: year + } +} + +fn test_dates_in_year() { + { + let mut dates = dates_in_year(2013); + assert_eq!(dates.next(), Some(NaiveDate::from_ymd(2013, 1, 1))); + + // Check increment. + assert_eq!(dates.next(), Some(NaiveDate::from_ymd(2013, 1, 2))); + + // Check monthly roll-over. + for _ in 3..31 { + assert!(dates.next() != None); + } + + assert_eq!(dates.next(), Some(NaiveDate::from_ymd(2013, 1, 31))); + assert_eq!(dates.next(), Some(NaiveDate::from_ymd(2013, 2, 1))); + } + + { + // Check length of year. + let mut dates = dates_in_year(2013); + for _ in 0..365 { + assert!(dates.next() != None); + } + assert_eq!(dates.next(), None); + } + + { + // Check length of leap year. + let mut dates = dates_in_year(1984); + for _ in 0..366 { + assert!(dates.next() != None); + } + assert_eq!(dates.next(), None); + } +} + +/// Convenience trait for verifying that a given type iterates over +/// `NaiveDate`s. +trait DateIterator: Iterator + Clone {} +impl DateIterator for It where It: Iterator + Clone {} + +fn test_group_by() { + let input = [ + [1, 1], + [1, 1], + [1, 2], + [2, 2], + [2, 3], + [2, 3], + [3, 3] + ]; + + let by_x = input.iter().cloned().group_by(|a| a[0]); + let expected_1: &[&[[i32; 2]]] = &[ + &[[1, 1], [1, 1], [1, 2]], + &[[2, 2], [2, 3], [2, 3]], + &[[3, 3]] + ]; + for ((_, a), b) in by_x.zip(expected_1.iter().cloned()) { + assert_eq!(&a.collect::>()[..], b); + } + + let by_y = input.iter().cloned().group_by(|a| a[1]); + let expected_2: &[&[[i32; 2]]] = &[ + &[[1, 1], [1, 1]], + &[[1, 2], [2, 2]], + &[[2, 3], [2, 3], [3, 3]] + ]; + for ((_, a), b) in by_y.zip(expected_2.iter().cloned()) { + assert_eq!(&a.collect::>()[..], b); + } +} + +/// Groups an iterator of dates by month. +fn by_month(it: impl Iterator + Clone) + -> impl Iterator + Clone)> + Clone +{ + it.group_by(|d| d.month()) +} + +fn test_by_month() { + let mut months = dates_in_year(2013).__(by_month); + for (month, (_, mut date)) in (1..13).zip(&mut months) { + assert_eq!(date.nth(0).unwrap(), NaiveDate::from_ymd(2013, month, 1)); + } + assert!(months.next().is_none()); +} + +/// Groups an iterator of dates by week. +fn by_week(it: impl DateIterator) + -> impl Iterator + Clone +{ + // We go forward one day because `isoweekdate` considers the week to start on a Monday. + it.group_by(|d| d.succ().isoweekdate().1) +} + +fn test_isoweekdate() { + fn weeks_uniq(year: i32) -> Vec<((i32, u32), u32)> { + let mut weeks = dates_in_year(year).map(|d| d.isoweekdate()) + .map(|(y,w,_)| (y,w)); + let mut result = vec![]; + let mut accum = (weeks.next().unwrap(), 1); + for yw in weeks { + if accum.0 == yw { + accum.1 += 1; + } else { + result.push(accum); + accum = (yw, 1); + } + } + result.push(accum); + result + } + + let wu_1984 = weeks_uniq(1984); + assert_eq!(&wu_1984[..2], &[((1983, 52), 1), ((1984, 1), 7)]); + assert_eq!(&wu_1984[wu_1984.len()-2..], &[((1984, 52), 7), ((1985, 1), 1)]); + + let wu_2013 = weeks_uniq(2013); + assert_eq!(&wu_2013[..2], &[((2013, 1), 6), ((2013, 2), 7)]); + assert_eq!(&wu_2013[wu_2013.len()-2..], &[((2013, 52), 7), ((2014, 1), 2)]); + + let wu_2015 = weeks_uniq(2015); + assert_eq!(&wu_2015[..2], &[((2015, 1), 4), ((2015, 2), 7)]); + assert_eq!(&wu_2015[wu_2015.len()-2..], &[((2015, 52), 7), ((2015, 53), 4)]); +} + +fn test_by_week() { + let mut weeks = dates_in_year(2013).__(by_week); + assert_eq!( + &*weeks.next().unwrap().1.collect::>(), + &[ + NaiveDate::from_ymd(2013, 1, 1), + NaiveDate::from_ymd(2013, 1, 2), + NaiveDate::from_ymd(2013, 1, 3), + NaiveDate::from_ymd(2013, 1, 4), + NaiveDate::from_ymd(2013, 1, 5), + ] + ); + assert_eq!( + &*weeks.next().unwrap().1.collect::>(), + &[ + NaiveDate::from_ymd(2013, 1, 6), + NaiveDate::from_ymd(2013, 1, 7), + NaiveDate::from_ymd(2013, 1, 8), + NaiveDate::from_ymd(2013, 1, 9), + NaiveDate::from_ymd(2013, 1, 10), + NaiveDate::from_ymd(2013, 1, 11), + NaiveDate::from_ymd(2013, 1, 12), + ] + ); + assert_eq!(weeks.next().unwrap().1.nth(0).unwrap(), NaiveDate::from_ymd(2013, 1, 13)); +} + +/// The number of columns per day in the formatted output. +const COLS_PER_DAY: u32 = 3; + +/// The number of columns per week in the formatted output. +const COLS_PER_WEEK: u32 = 7 * COLS_PER_DAY; + +/// Formats an iterator of weeks into an iterator of strings. +fn format_weeks(it: impl Iterator) -> impl Iterator { + it.map(|week| { + let mut buf = String::with_capacity((COLS_PER_DAY * COLS_PER_WEEK + 2) as usize); + + // Format each day into its own cell and append to target string. + let mut last_day = 0; + let mut first = true; + for d in week { + last_day = d.weekday().num_days_from_sunday(); + + // Insert enough filler to align the first day with its respective day-of-week. + if first { + buf.extend(spaces((COLS_PER_DAY * last_day) as usize)); + first = false; + } + + write!(buf, " {:>2}", d.day()).unwrap(); + } + + // Insert more filler at the end to fill up the remainder of the week, + // if its a short week (e.g., at the end of the month). + buf.extend(spaces((COLS_PER_DAY * (6 - last_day)) as usize)); + buf + }) +} + +fn test_format_weeks() { + let jan_2013 = dates_in_year(2013) + .__(by_month).next() // pick January 2013 for testing purposes + // NOTE: This `map` is because `next` returns an `Option<_>`. + .map(|(_, month)| + month.__(by_week) + .map(|(_, weeks)| weeks) + .__(format_weeks) + .join("\n")); + + assert_eq!( + jan_2013.as_ref().map(|s| &**s), + Some(" 1 2 3 4 5\n\ + \x20 6 7 8 9 10 11 12\n\ + \x2013 14 15 16 17 18 19\n\ + \x2020 21 22 23 24 25 26\n\ + \x2027 28 29 30 31 ") + ); +} + +/// Formats the name of a month, centered on `COLS_PER_WEEK`. +fn month_title(month: u32) -> String { + const MONTH_NAMES: &'static [&'static str] = &[ + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + ]; + assert_eq!(MONTH_NAMES.len(), 12); + + // Determine how many spaces before and after the month name + // we need to center it over the formatted weeks in the month. + let name = MONTH_NAMES[(month - 1) as usize]; + assert!(name.len() < COLS_PER_WEEK as usize); + let before = (COLS_PER_WEEK as usize - name.len()) / 2; + let after = COLS_PER_WEEK as usize - name.len() - before; + + // Note: being slightly more verbose to avoid extra allocations. + let mut result = String::with_capacity(COLS_PER_WEEK as usize); + result.extend(spaces(before)); + result.push_str(name); + result.extend(spaces(after)); + result +} + +fn test_month_title() { + assert_eq!(month_title(1).len(), COLS_PER_WEEK as usize); +} + +/// Formats a month. +fn format_month(it: impl DateIterator) -> impl Iterator { + let mut month_days = it.peekable(); + let title = month_title(month_days.peek().unwrap().month()); + + Some(title).into_iter() + .chain(month_days.__(by_week) + .map(|(_, week)| week) + .__(format_weeks)) +} + +fn test_format_month() { + let month_fmt = dates_in_year(2013) + .__(by_month).next() // Pick January as a test case + .map(|(_, days)| days.into_iter() + .__(format_month) + .join("\n")); + + assert_eq!( + month_fmt.as_ref().map(|s| &**s), + Some(" January \n\ + \x20 1 2 3 4 5\n\ + \x20 6 7 8 9 10 11 12\n\ + \x2013 14 15 16 17 18 19\n\ + \x2020 21 22 23 24 25 26\n\ + \x2027 28 29 30 31 ") + ); +} + +/// Formats an iterator of months. +fn format_months(it: impl Iterator) + -> impl Iterator> +{ + it.map(format_month) +} + +/// Takes an iterator of iterators of strings; the sub-iterators are consumed +/// in lock-step, with their elements joined together. +trait PasteBlocks: Iterator + Sized +where Self::Item: Iterator { + fn paste_blocks(self, sep_width: usize) -> PasteBlocksIter { + PasteBlocksIter { + iters: self.collect(), + cache: vec![], + col_widths: None, + sep_width: sep_width, + } + } +} + +impl PasteBlocks for It where It: Iterator, It::Item: Iterator {} + +struct PasteBlocksIter +where StrIt: Iterator { + iters: Vec, + cache: Vec>, + col_widths: Option>, + sep_width: usize, +} + +impl Iterator for PasteBlocksIter +where StrIt: Iterator { + type Item = String; + + fn next(&mut self) -> Option { + self.cache.clear(); + + // `cache` is now the next line from each iterator. + self.cache.extend(self.iters.iter_mut().map(|it| it.next())); + + // If every line in `cache` is `None`, we have nothing further to do. + if self.cache.iter().all(|e| e.is_none()) { return None } + + // Get the column widths if we haven't already. + let col_widths = match self.col_widths { + Some(ref v) => &**v, + None => { + self.col_widths = Some(self.cache.iter() + .map(|ms| ms.as_ref().map(|s| s.len()).unwrap_or(0)) + .collect()); + &**self.col_widths.as_ref().unwrap() + } + }; + + // Fill in any `None`s with spaces. + let mut parts = col_widths.iter().cloned().zip(self.cache.iter_mut()) + .map(|(w,ms)| ms.take().unwrap_or_else(|| spaces(w).collect())); + + // Join them all together. + let first = parts.next().unwrap_or(String::new()); + let sep_width = self.sep_width; + Some(parts.fold(first, |mut accum, next| { + accum.extend(spaces(sep_width)); + accum.push_str(&next); + accum + })) + } +} + +fn test_paste_blocks() { + let row = dates_in_year(2013) + .__(by_month).map(|(_, days)| days) + .take(3) + .__(format_months) + .paste_blocks(1) + .join("\n"); + assert_eq!( + &*row, + " January February March \n\ + \x20 1 2 3 4 5 1 2 1 2\n\ + \x20 6 7 8 9 10 11 12 3 4 5 6 7 8 9 3 4 5 6 7 8 9\n\ + \x2013 14 15 16 17 18 19 10 11 12 13 14 15 16 10 11 12 13 14 15 16\n\ + \x2020 21 22 23 24 25 26 17 18 19 20 21 22 23 17 18 19 20 21 22 23\n\ + \x2027 28 29 30 31 24 25 26 27 28 24 25 26 27 28 29 30\n\ + \x20 31 " + ); +} + +/// Produces an iterator that yields `n` elements at a time. +trait Chunks: Iterator + Sized { + fn chunks(self, n: usize) -> ChunksIter { + assert!(n > 0); + ChunksIter { + it: self, + n: n, + } + } +} + +impl Chunks for It where It: Iterator {} + +struct ChunksIter +where It: Iterator { + it: It, + n: usize, +} + +// Note: `chunks` in Rust is more-or-less impossible without overhead of some kind. +// Aliasing rules mean you need to add dynamic borrow checking, and the design of +// `Iterator` means that you need to have the iterator's state kept in an allocation +// that is jointly owned by the iterator itself and the sub-iterator. +// As such, I've chosen to cop-out and just heap-allocate each chunk. + +impl Iterator for ChunksIter +where It: Iterator { + type Item = Vec; + + fn next(&mut self) -> Option> { + let first = self.it.next()?; + + let mut result = Vec::with_capacity(self.n); + result.push(first); + + Some((&mut self.it).take(self.n-1) + .fold(result, |mut acc, next| { acc.push(next); acc })) + } +} + +fn test_chunks() { + let r = &[1, 2, 3, 4, 5, 6, 7]; + let c = r.iter().cloned().chunks(3).collect::>(); + assert_eq!(&*c, &[vec![1, 2, 3], vec![4, 5, 6], vec![7]]); +} + +/// Formats a year. +fn format_year(year: i32, months_per_row: usize) -> String { + const COL_SPACING: usize = 1; + + // Start by generating all dates for the given year. + dates_in_year(year) + + // Group them by month and throw away month number. + .__(by_month).map(|(_, days)| days) + + // Group the months into horizontal rows. + .chunks(months_per_row) + + // Format each row... + .map(|r| r.into_iter() + // ... by formatting each month ... + .__(format_months) + + // ... and horizontally pasting each respective month's lines together. + .paste_blocks(COL_SPACING) + .join("\n") + ) + + // Insert a blank line between each row. + .join("\n\n") +} + +fn test_format_year() { + const MONTHS_PER_ROW: usize = 3; + + macro_rules! assert_eq_cal { + ($lhs:expr, $rhs:expr) => { + if $lhs != $rhs { + println!("got:\n```\n{}\n```\n", $lhs.replace(" ", ".")); + println!("expected:\n```\n{}\n```", $rhs.replace(" ", ".")); + panic!("calendars didn't match!"); + } + } + } + + assert_eq_cal!(&format_year(1984, MONTHS_PER_ROW), "\ +\x20 January February March \n\ +\x20 1 2 3 4 5 6 7 1 2 3 4 1 2 3\n\ +\x20 8 9 10 11 12 13 14 5 6 7 8 9 10 11 4 5 6 7 8 9 10\n\ +\x2015 16 17 18 19 20 21 12 13 14 15 16 17 18 11 12 13 14 15 16 17\n\ +\x2022 23 24 25 26 27 28 19 20 21 22 23 24 25 18 19 20 21 22 23 24\n\ +\x2029 30 31 26 27 28 29 25 26 27 28 29 30 31\n\ +\n\ +\x20 April May June \n\ +\x20 1 2 3 4 5 6 7 1 2 3 4 5 1 2\n\ +\x20 8 9 10 11 12 13 14 6 7 8 9 10 11 12 3 4 5 6 7 8 9\n\ +\x2015 16 17 18 19 20 21 13 14 15 16 17 18 19 10 11 12 13 14 15 16\n\ +\x2022 23 24 25 26 27 28 20 21 22 23 24 25 26 17 18 19 20 21 22 23\n\ +\x2029 30 27 28 29 30 31 24 25 26 27 28 29 30\n\ +\n\ +\x20 July August September \n\ +\x20 1 2 3 4 5 6 7 1 2 3 4 1\n\ +\x20 8 9 10 11 12 13 14 5 6 7 8 9 10 11 2 3 4 5 6 7 8\n\ +\x2015 16 17 18 19 20 21 12 13 14 15 16 17 18 9 10 11 12 13 14 15\n\ +\x2022 23 24 25 26 27 28 19 20 21 22 23 24 25 16 17 18 19 20 21 22\n\ +\x2029 30 31 26 27 28 29 30 31 23 24 25 26 27 28 29\n\ +\x20 30 \n\ +\n\ +\x20 October November December \n\ +\x20 1 2 3 4 5 6 1 2 3 1\n\ +\x20 7 8 9 10 11 12 13 4 5 6 7 8 9 10 2 3 4 5 6 7 8\n\ +\x2014 15 16 17 18 19 20 11 12 13 14 15 16 17 9 10 11 12 13 14 15\n\ +\x2021 22 23 24 25 26 27 18 19 20 21 22 23 24 16 17 18 19 20 21 22\n\ +\x2028 29 30 31 25 26 27 28 29 30 23 24 25 26 27 28 29\n\ +\x20 30 31 "); + + assert_eq_cal!(&format_year(2015, MONTHS_PER_ROW), "\ +\x20 January February March \n\ +\x20 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 6 7\n\ +\x20 4 5 6 7 8 9 10 8 9 10 11 12 13 14 8 9 10 11 12 13 14\n\ +\x2011 12 13 14 15 16 17 15 16 17 18 19 20 21 15 16 17 18 19 20 21\n\ +\x2018 19 20 21 22 23 24 22 23 24 25 26 27 28 22 23 24 25 26 27 28\n\ +\x2025 26 27 28 29 30 31 29 30 31 \n\ +\n\ +\x20 April May June \n\ +\x20 1 2 3 4 1 2 1 2 3 4 5 6\n\ +\x20 5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13\n\ +\x2012 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20\n\ +\x2019 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27\n\ +\x2026 27 28 29 30 24 25 26 27 28 29 30 28 29 30 \n\ +\x20 31 \n\ +\n\ +\x20 July August September \n\ +\x20 1 2 3 4 1 1 2 3 4 5\n\ +\x20 5 6 7 8 9 10 11 2 3 4 5 6 7 8 6 7 8 9 10 11 12\n\ +\x2012 13 14 15 16 17 18 9 10 11 12 13 14 15 13 14 15 16 17 18 19\n\ +\x2019 20 21 22 23 24 25 16 17 18 19 20 21 22 20 21 22 23 24 25 26\n\ +\x2026 27 28 29 30 31 23 24 25 26 27 28 29 27 28 29 30 \n\ +\x20 30 31 \n\ +\n\ +\x20 October November December \n\ +\x20 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5\n\ +\x20 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12\n\ +\x2011 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19\n\ +\x2018 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26\n\ +\x2025 26 27 28 29 30 31 29 30 27 28 29 30 31 "); +} + +fn main() { + // Run tests. + test_spaces(); + test_dates_in_year(); + test_group_by(); + test_by_month(); + test_isoweekdate(); + test_by_week(); + test_format_weeks(); + test_month_title(); + test_format_month(); + test_paste_blocks(); + test_chunks(); + test_format_year(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/example-st.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/example-st.rs new file mode 100644 index 000000000000..7effaaeed6ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/example-st.rs @@ -0,0 +1,31 @@ +// run-pass + +struct State; +type Error = (); + +trait Bind { + type Output; + fn bind(self, f: F) -> Self::Output; +} + +fn bind(mut a: A, mut f: F) + -> impl FnMut(&mut State) -> Result +where F: FnMut(T) -> B, + A: FnMut(&mut State) -> Result, + B: FnMut(&mut State) -> Result +{ + move |state | { + let r = a(state)?; + f(r)(state) + } +} + +fn atom(x: T) -> impl FnMut(&mut State) -> Result { + let mut x = Some(x); + move |_| x.take().map_or(Err(()), Ok) +} + +fn main() { + assert_eq!(bind(atom(5), |x| atom(x > 4))(&mut State), Ok(true)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/extra-item.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/extra-item.rs new file mode 100644 index 000000000000..c21b2e188dea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/extra-item.rs @@ -0,0 +1,11 @@ +// aux-build:extra-item.rs +// compile-flags:--extern extra_item + +struct S; + +impl extra_item::MyTrait for S { + fn extra() {} // { dg-error ".E0407." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/hidden-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/hidden-lifetimes.rs new file mode 100644 index 000000000000..1e3aa5568262 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/hidden-lifetimes.rs @@ -0,0 +1,64 @@ +// Test to show what happens if we were not careful and allowed invariant +// lifetimes to escape though an impl trait. +// +// Specifically we swap a long lived and short lived reference, giving us a +// dangling pointer. + +use std::cell::RefCell; +use std::rc::Rc; + +trait Swap: Sized { + fn swap(self, other: Self); +} + +impl Swap for &mut T { + fn swap(self, other: Self) { + std::mem::swap(self, other); + } +} + +impl Swap for Rc> { + fn swap(self, other: Self) { + >::swap(&self, &other); + } +} + +// Here we are hiding `'b` making the caller believe that `&'a mut &'s T` and +// `&'a mut &'l T` are the same type. +fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a { +// { dg-error ".E0700." "" { target *-*-* } .-1 } + x +} + +fn dangle_ref() -> &'static [i32; 3] { + let mut res = &[4, 5, 6]; + let x = [1, 2, 3]; + hide_ref(&mut res).swap(hide_ref(&mut &x)); + res +} + +// Here we are hiding `'b` making the caller believe that `Rc>` +// and `Rc>` are the same type. +// +// This is different to the previous example because the concrete return type +// only has a single lifetime. +fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc>) -> impl Swap + 'a { +// { dg-error ".E0700." "" { target *-*-* } .-1 } + x +} + +fn dangle_rc_refcell() -> &'static [i32; 3] { + let long = Rc::new(RefCell::new(&[4, 5, 6])); + let x = [1, 2, 3]; + let short = Rc::new(RefCell::new(&x)); + hide_rc_refcell(long.clone()).swap(hide_rc_refcell(short)); + let res: &'static [i32; 3] = *long.borrow(); + res +} + +fn main() { + // both will print nonsense values. + println!("{:?}", dangle_ref()); + println!("{:?}", dangle_rc_refcell()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/impl-generic-mismatch-ab.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/impl-generic-mismatch-ab.rs new file mode 100644 index 000000000000..7b6fe83d0246 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/impl-generic-mismatch-ab.rs @@ -0,0 +1,13 @@ +use std::fmt::Debug; + +trait Foo { + fn foo(&self, a: &A, b: &impl Debug); +} + +impl Foo for () { + fn foo(&self, a: &impl Debug, b: &B) { } +// { dg-error ".E0053." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/impl-generic-mismatch.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/impl-generic-mismatch.rs new file mode 100644 index 000000000000..012fc8eca91a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/impl-generic-mismatch.rs @@ -0,0 +1,33 @@ +use std::fmt::Debug; + +trait Foo { + fn foo(&self, _: &impl Debug); +} + +impl Foo for () { + fn foo(&self, _: &U) { } +// { dg-error ".E0643." "" { target *-*-* } .-1 } +} + +trait Bar { + fn bar(&self, _: &U); +} + +impl Bar for () { + fn bar(&self, _: &impl Debug) { } +// { dg-error ".E0643." "" { target *-*-* } .-1 } +} + +// With non-local trait (#49841): + +use std::hash::{Hash, Hasher}; + +struct X; + +impl Hash for X { + fn hash(&self, hasher: &mut impl Hasher) {} +// { dg-error ".E0643." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/impl-trait-plus-priority.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/impl-trait-plus-priority.rs new file mode 100644 index 000000000000..a12d351984e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/impl-trait-plus-priority.rs @@ -0,0 +1,50 @@ +// compile-flags: -Z parse-only + +fn f() -> impl A + {} // OK +fn f() -> impl A + B {} // OK +fn f() -> dyn A + B {} // OK +fn f() -> A + B {} // OK + +impl S { + fn f(self) -> impl A + { // OK + let _ = |a, b| -> impl A + {}; // OK + } + fn f(self) -> impl A + B { // OK + let _ = |a, b| -> impl A + B {}; // OK + } + fn f(self) -> dyn A + B { // OK + let _ = |a, b| -> dyn A + B {}; // OK + } + fn f(self) -> A + B { // OK + let _ = |a, b| -> A + B {}; // OK + } +} + +type A = fn() -> impl A +; +// { dg-error "" "" { target *-*-* } .-1 } +type A = fn() -> impl A + B; +// { dg-error "" "" { target *-*-* } .-1 } +type A = fn() -> dyn A + B; +// { dg-error "" "" { target *-*-* } .-1 } +type A = fn() -> A + B; +// { dg-error ".E0178." "" { target *-*-* } .-1 } + +type A = Fn() -> impl A +; +// { dg-error "" "" { target *-*-* } .-1 } +type A = Fn() -> impl A + B; +// { dg-error "" "" { target *-*-* } .-1 } +type A = Fn() -> dyn A + B; +// { dg-error "" "" { target *-*-* } .-1 } +type A = Fn() -> A + B; // OK, interpreted as `(Fn() -> A) + B` for compatibility + +type A = &impl A +; +// { dg-error "" "" { target *-*-* } .-1 } +type A = &impl A + B; +// { dg-error "" "" { target *-*-* } .-1 } +type A = &dyn A + B; +// { dg-error "" "" { target *-*-* } .-1 } +type A = &A + B; +// { dg-error ".E0178." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/impl_trait_projections.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/impl_trait_projections.rs new file mode 100644 index 000000000000..92292b26c5cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/impl_trait_projections.rs @@ -0,0 +1,40 @@ +use std::fmt::Debug; +use std::option; + +fn parametrized_type_is_allowed() -> Option { + Some(5i32) +} + +fn path_parametrized_type_is_allowed() -> option::Option { + Some(5i32) +} + +fn projection_is_disallowed(x: impl Iterator) -> ::Item { +// { dg-error ".E0223." "" { target *-*-* } .-1 } +// { dg-error ".E0223." "" { target *-*-* } .-2 } + x.next().unwrap() +} + +fn projection_with_named_trait_is_disallowed(x: impl Iterator) + -> ::Item +// { dg-error ".E0667." "" { target *-*-* } .-1 } +{ + x.next().unwrap() +} + +fn projection_with_named_trait_inside_path_is_disallowed() + -> <::std::ops::Range as Iterator>::Item +// { dg-error ".E0667." "" { target *-*-* } .-1 } +{ + (1i32..100).next().unwrap() +} + +fn projection_from_impl_trait_inside_dyn_trait_is_disallowed() + -> as Iterator>::Item +// { dg-error ".E0667." "" { target *-*-* } .-1 } +{ + panic!() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issue-55872-1.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-55872-1.rs new file mode 100644 index 000000000000..78d64bef8382 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-55872-1.rs @@ -0,0 +1,23 @@ +// ignore-tidy-linelength +#![feature(type_alias_impl_trait)] + +pub trait Bar { + type E: Copy; + + fn foo() -> Self::E; +} + +impl Bar for S { + type E = impl Copy; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + + fn foo() -> Self::E { +// { dg-error ".E0276." "" { target *-*-* } .-1 } +// { dg-error ".E0276." "" { target *-*-* } .-2 } + (S::default(), T::default()) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issue-55872-2.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-55872-2.rs new file mode 100644 index 000000000000..651ed581af40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-55872-2.rs @@ -0,0 +1,23 @@ +// edition:2018 +// ignore-tidy-linelength +// ignore-compare-mode-chalk + +#![feature(type_alias_impl_trait)] + +pub trait Bar { + type E: Copy; + + fn foo() -> Self::E; +} + +impl Bar for S { + type E = impl std::marker::Copy; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + fn foo() -> Self::E { +// { dg-error "" "" { target *-*-* } .-1 } + async {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issue-55872.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-55872.rs new file mode 100644 index 000000000000..cd6e42b7639d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-55872.rs @@ -0,0 +1,21 @@ +// ignore-tidy-linelength +// ignore-compare-mode-chalk +#![feature(type_alias_impl_trait)] + +pub trait Bar { + type E: Copy; + + fn foo() -> Self::E; +} + +impl Bar for S { + type E = impl Copy; + + fn foo() -> Self::E { +// { dg-error "" "" { target *-*-* } .-1 } + || () + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issue-56445.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-56445.rs new file mode 100644 index 000000000000..09fa00d5875c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-56445.rs @@ -0,0 +1,26 @@ +// Regression test for https://github.com/rust-lang/rust/issues/56445#issuecomment-629426939 +// check-pass + +#![crate_type = "lib"] + +use std::marker::PhantomData; + +pub struct S<'a> { + pub m1: PhantomData<&'a u8>, + pub m2: [u8; S::size()], +} + +impl<'a> S<'a> +{ + pub const fn size() -> usize { 1 } + + pub fn new() -> Self + { + Self + { + m1: PhantomData, + m2: [0; Self::size()], + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issue-57200.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-57200.rs new file mode 100644 index 000000000000..7a8190cd99ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-57200.rs @@ -0,0 +1,16 @@ +// Regression test for #57200 +// FIXME: The error is temporary hack, we'll revisit here at some point. + +#![feature(impl_trait_in_bindings)] +#![allow(incomplete_features)] + +fn bug<'a, 'b, T>() +where + 'a: 'b, +{ + let f: impl Fn(&'a T) -> &'b T = |x| x; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issue-57201.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-57201.rs new file mode 100644 index 000000000000..33fa406dd01e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-57201.rs @@ -0,0 +1,16 @@ +// Regression test for #57201 +// FIXME: The error is temporary hack, we'll revisit here at some point. + +#![feature(impl_trait_in_bindings)] +#![allow(incomplete_features)] + +fn bug<'a, 'b, T>() +where + 'a: 'b, +{ + let f: &impl Fn(&'a T) -> &'b T = &|x| x; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issue-60473.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-60473.rs new file mode 100644 index 000000000000..72d403e47c7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-60473.rs @@ -0,0 +1,16 @@ +// Regression test for #60473 + +#![feature(impl_trait_in_bindings)] +#![allow(incomplete_features)] + +struct A<'a>(&'a ()); + +trait Trait {} + +impl Trait for () {} + +fn main() { + let x: impl Trait = (); +// { dg-error ".E0106." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issue-67166.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-67166.rs new file mode 100644 index 000000000000..4eb4a252da66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-67166.rs @@ -0,0 +1,12 @@ +// Regression test for #67166 + +#![feature(impl_trait_in_bindings)] +#![allow(incomplete_features)] + +pub fn run() { + let _foo: Box = Box::new(()); +// { dg-error ".E0106." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issue-68532.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-68532.rs new file mode 100644 index 000000000000..ba2e0de7f9f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-68532.rs @@ -0,0 +1,14 @@ +// check-pass + +pub struct A<'a>(&'a ()); + +impl<'a> A<'a> { + const N: usize = 68; + + pub fn foo(&self) { + let _b = [0; Self::N]; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issue-69840.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-69840.rs new file mode 100644 index 000000000000..8af733422bd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-69840.rs @@ -0,0 +1,17 @@ +// check-pass + +#![feature(impl_trait_in_bindings)] +#![allow(incomplete_features)] + +struct A<'a>(&'a ()); + +trait Trait {} + +impl Trait for () {} + +pub fn foo<'a>() { + let _x: impl Trait> = (); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issue-72911.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-72911.rs new file mode 100644 index 000000000000..19bff7fa8c81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issue-72911.rs @@ -0,0 +1,23 @@ +// Regression test for #72911. + +pub struct Lint {} + +impl Lint {} + +pub fn gather_all() -> impl Iterator { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + lint_files().flat_map(|f| gather_from_file(&f)) +} + +fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator { +// { dg-error ".E0433." "" { target *-*-* } .-1 } + unimplemented!() +} + +fn lint_files() -> impl Iterator { +// { dg-error ".E0433." "" { target *-*-* } .-1 } + unimplemented!() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs new file mode 100644 index 000000000000..ba929f472d6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs @@ -0,0 +1,26 @@ +// Test that attempts to construct infinite types via impl trait fail +// in a graceful way. +// +// Regression test for #38064. + +trait Quux {} + +fn foo() -> impl Quux { // { dg-error ".E0720." "" { target *-*-* } } + struct Foo(T); + impl Quux for Foo {} + Foo(bar()) +} + +fn bar() -> impl Quux { // { dg-error ".E0720." "" { target *-*-* } } + struct Bar(T); + impl Quux for Bar {} + Bar(foo()) +} + +// effectively: +// struct Foo(Bar); +// struct Bar(Foo); +// should produce an error about infinite size + +fn main() { foo(); } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.rs new file mode 100644 index 000000000000..2a4c322fe7ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.rs @@ -0,0 +1,23 @@ +trait Foo { + fn foo(&self, a: A) -> A { + a + } +} + +trait NotRelevant { + fn nr(&self, a: A) -> A { + a + } +} + +struct Bar; + +impl NotRelevant for Bar {} + +fn main() { + let f1 = Bar; + + f1.foo(1usize); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-42479.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-42479.rs new file mode 100644 index 000000000000..e93b79c37980 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-42479.rs @@ -0,0 +1,18 @@ +// check-pass + +use std::iter::once; + +struct Foo { + x: i32, +} + +impl Foo { + fn inside(&self) -> impl Iterator { + once(&self.x) + } +} + +fn main() { + println!("hi"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-49376.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-49376.rs new file mode 100644 index 000000000000..5321617673ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-49376.rs @@ -0,0 +1,24 @@ +// check-pass + +// Tests for nested self-reference which caused a stack overflow. + +use std::fmt::Debug; +use std::ops::*; + +fn gen() -> impl PartialOrd + PartialEq + Debug { } + +struct Bar {} +trait Foo {} +trait FooNested> {} +impl Foo for Bar {} +impl FooNested for Bar {} + +fn foo() -> impl Foo + FooNested { + Bar {} +} + +fn test_impl_ops() -> impl Add + Sub + Mul + Div { 1 } +fn test_impl_assign_ops() -> impl AddAssign + SubAssign + MulAssign + DivAssign { 1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-52128.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-52128.rs new file mode 100644 index 000000000000..7ee4175b899c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-52128.rs @@ -0,0 +1,26 @@ +// check-pass + +#![deny(warnings)] + +use std::collections::BTreeMap; + +pub struct RangeMap { + map: BTreeMap, +} + +#[derive(Eq, PartialEq, Ord, PartialOrd)] +struct Range; + +impl RangeMap { + fn iter_with_range<'a>(&'a self) -> impl Iterator + 'a { + self.map.range(Range..Range) + } + + pub fn iter<'a>(&'a self) -> impl Iterator + 'a { + self.iter_with_range().map(|(_, data)| data) + } + +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-53457.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-53457.rs new file mode 100644 index 000000000000..71448487dc79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-53457.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +type X = impl Clone; + +fn bar(f: F) -> F { + f +} + +fn foo() -> X { + bar(|_| ()) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-55608-captures-empty-region.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-55608-captures-empty-region.rs new file mode 100644 index 000000000000..5397b7e64c0b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-55608-captures-empty-region.rs @@ -0,0 +1,23 @@ +// This used to ICE because it creates an `impl Trait` that captures a +// hidden empty region. + +// check-pass + +fn server() -> impl FilterBase2 { + segment2(|| { loop { } }).map2(|| "") +} + +trait FilterBase2 { + fn map2(self, _fn: F) -> Map2 where Self: Sized { loop { } } +} + +struct Map2 { _func: F } + +impl FilterBase2 for Map2 { } + +fn segment2(_fn: F) -> Map2 where F: Fn() -> Result<(), ()> { + loop { } +} + +fn main() { server(); } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57464-unexpected-regions.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57464-unexpected-regions.rs new file mode 100644 index 000000000000..540d921a89da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57464-unexpected-regions.rs @@ -0,0 +1,30 @@ +// Regression test for issue 57464. +// +// Closure are (surprisingly) allowed to outlive their signature. As such it +// was possible to end up with `ReScope`s appearing in the concrete type of an +// opaque type. As all regions are now required to outlive the bound in an +// opaque type we avoid the issue here. + +// check-pass + +struct A(F); + +unsafe impl <'a, 'b, F: Fn(&'a i32) -> &'b i32> Send for A {} + +fn wrapped_closure() -> impl Sized { + let f = |x| x; + f(&0); + A(f) +} + +fn wrapped_closure_with_bound() -> impl Sized + 'static { + let f = |x| x; + f(&0); + A(f) +} + +fn main() { + let x: Box = Box::new(wrapped_closure()); + let y: Box = Box::new(wrapped_closure_with_bound()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs new file mode 100644 index 000000000000..d787580303d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs @@ -0,0 +1,18 @@ +// rust-lang/rust#57979 : the initial support for `impl Trait` didn't +// properly check syntax hidden behind an associated type projection, +// but it did catch *some cases*. This is checking that we continue to +// properly emit errors for those. +// +// issue-57979-nested-impl-trait-in-assoc-proj.rs shows the main case +// that we were previously failing to catch. + +struct Deeper(T); + +pub trait Foo { } +pub trait Bar { } +pub trait Quux { type Assoc; } +pub fn demo(_: impl Quux>>) { } +// { dg-error ".E0666." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs new file mode 100644 index 000000000000..05471fe0b4d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs @@ -0,0 +1,13 @@ +// rust-lang/rust#57979 : the initial support for `impl Trait` didn't +// properly check syntax hidden behind an associated type projection. +// Here we test behavior of occurrences of `impl Trait` within a path +// component in that context. + +pub trait Bar { } +pub trait Quux { type Assoc; } +pub fn demo(_: impl Quux<(), Assoc=<() as Quux>::Assoc>) { } +// { dg-error ".E0667." "" { target *-*-* } .-1 } +impl Quux for () { type Assoc = u32; } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs new file mode 100644 index 000000000000..b969ddd64715 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs @@ -0,0 +1,13 @@ +// rust-lang/rust#57979 : the initial support for `impl Trait` didn't +// properly check syntax hidden behind an associated type projection. +// Here we test behavior of occurrences of `impl Trait` within an +// `impl Trait` in that context. + +pub trait Foo { } +pub trait Bar { } +pub trait Quux { type Assoc; } +pub fn demo(_: impl Quux>) { } +// { dg-error ".E0666." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-65581.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-65581.rs new file mode 100644 index 000000000000..c293eab63448 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-65581.rs @@ -0,0 +1,34 @@ +// check-pass + +#![allow(dead_code)] + +trait Trait1 { + fn f1(self) -> U; +} + +trait Trait2 { + type T; + type U: Trait2; + fn f2(f: impl FnOnce(&Self::U)); +} + +fn f3() -> impl Trait1 { + Struct1 +} + +struct Struct1; + +impl Trait1 for Struct1 { + fn f1(self) -> T::T { + unimplemented!() + } +} + +fn f4() { + T::f2(|_| { + f3::().f1(); + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-70877.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-70877.rs new file mode 100644 index 000000000000..a94f206b3b09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/issue-70877.rs @@ -0,0 +1,39 @@ +#![feature(type_alias_impl_trait)] +#![feature(impl_trait_in_bindings)] +#![allow(incomplete_features)] + +type FooArg<'a> = &'a dyn ToString; +type FooRet = impl std::fmt::Debug; + +type FooItem = Box FooRet>; +type Foo = impl Iterator; // { dg-error ".E0271." "" { target *-*-* } } + +#[repr(C)] +struct Bar(u8); + +impl Iterator for Bar { + type Item = FooItem; + + fn next(&mut self) -> Option { + Some(Box::new(quux)) + } +} + +fn quux(st: FooArg) -> FooRet { + Some(st.to_string()) +} + +fn ham() -> Foo { + Bar(1) +} + +fn oof() -> impl std::fmt::Debug { + let mut bar = ham(); + let func = bar.next().unwrap(); + return func(&"oof"); +} + +fn main() { + let _ = oof(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/universal-issue-48703.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/universal-issue-48703.rs new file mode 100644 index 000000000000..7809aa559f38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/universal-issue-48703.rs @@ -0,0 +1,10 @@ +#![feature(universal_impl_trait)] + +use std::fmt::Debug; + +fn foo(x: impl Debug) { } + +fn main() { + foo::('a'); // { dg-error ".E0632." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs new file mode 100644 index 000000000000..aae684e2fb48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/issues/universal-turbofish-in-method-issue-50950.rs @@ -0,0 +1,18 @@ +use std::any::Any; +pub struct EventHandler { +} + +impl EventHandler +{ + pub fn handle_event(&mut self, _efunc: impl FnMut(T)) {} +} + +struct TestEvent(i32); + +fn main() { + let mut evt = EventHandler {}; + evt.handle_event::(|_evt| { +// { dg-error ".E0632." "" { target *-*-* } .-1 } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/lifetimes.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/lifetimes.rs new file mode 100644 index 000000000000..fe650b78b35b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/lifetimes.rs @@ -0,0 +1,124 @@ +// run-pass + +#![allow(warnings)] +#![feature(generators)] + +use std::fmt::Debug; + +fn any_lifetime<'a>() -> &'a u32 { &5 } + +fn static_lifetime() -> &'static u32 { &5 } + +fn any_lifetime_as_static_impl_trait() -> impl Debug { + any_lifetime() +} + +fn lifetimes_as_static_impl_trait() -> impl Debug { + static_lifetime() +} + +fn no_params_or_lifetimes_is_static() -> impl Debug + 'static { + lifetimes_as_static_impl_trait() +} + +fn static_input_type_is_static(x: T) -> impl Debug + 'static { x } + +fn type_outlives_reference_lifetime<'a, T: Debug>(x: &'a T) -> impl Debug + 'a { x } +fn type_outlives_reference_lifetime_elided(x: &T) -> impl Debug + '_ { x } + +trait SingleRegionTrait<'a> {} +impl<'a> SingleRegionTrait<'a> for u32 {} +impl<'a> SingleRegionTrait<'a> for &'a u32 {} +struct SingleRegionStruct<'a>(&'a u32); + +fn simple_type_hrtb<'b>() -> impl for<'a> SingleRegionTrait<'a> { 5 } +fn elision_single_region_trait(x: &u32) -> impl SingleRegionTrait { x } +fn elision_single_region_struct(x: SingleRegionStruct) -> impl Into { x } + +fn closure_hrtb() -> impl for<'a> Fn(&'a u32) { |_| () } +fn closure_hr_elided() -> impl Fn(&u32) { |_| () } +fn closure_hr_elided_return() -> impl Fn(&u32) -> &u32 { |x| x } +fn closure_pass_through_elided_return(x: impl Fn(&u32) -> &u32) -> impl Fn(&u32) -> &u32 { x } +fn closure_pass_through_reference_elided(x: &impl Fn(&u32) -> &u32) -> &impl Fn(&u32) -> &u32 { x } + +fn nested_lifetime<'a>(input: &'a str) + -> impl Iterator + 'a> + 'a +{ + input.lines().map(|line| { + line.split_whitespace().map(|cell| cell.parse().unwrap()) + }) +} + +fn pass_through_elision(x: &u32) -> impl Into<&u32> { x } +fn pass_through_elision_with_fn_ptr(x: &fn(&u32) -> &u32) -> impl Into<&fn(&u32) -> &u32> { x } + +fn pass_through_elision_with_fn_path &u32>( + x: &T +) -> &impl Fn(&u32) -> &u32 { x } + +fn foo(x: &impl Debug) -> &impl Debug { x } +fn foo_explicit_lifetime<'a>(x: &'a impl Debug) -> &'a impl Debug { x } +fn foo_explicit_arg(x: &T) -> &impl Debug { x } + +fn mixed_lifetimes<'a>() -> impl for<'b> Fn(&'b &'a u32) { |_| () } +fn mixed_as_static() -> impl Fn(&'static &'static u32) { mixed_lifetimes() } + +trait MultiRegionTrait<'a, 'b>: Debug {} + +#[derive(Debug)] +struct MultiRegionStruct<'a, 'b>(&'a u32, &'b u32); +impl<'a, 'b> MultiRegionTrait<'a, 'b> for MultiRegionStruct<'a, 'b> {} + +#[derive(Debug)] +struct NoRegionStruct; +impl<'a, 'b> MultiRegionTrait<'a, 'b> for NoRegionStruct {} + +fn finds_least_region<'a: 'b, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { + MultiRegionStruct(x, y) +} + +fn finds_explicit_bound<'a: 'b, 'b> + (x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> + 'b +{ + MultiRegionStruct(x, y) +} + +fn finds_explicit_bound_even_without_least_region<'a, 'b> + (x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> + 'b +{ + NoRegionStruct +} + +/* FIXME: `impl Trait<'a> + 'b` should live as long as 'b, even if 'b outlives 'a +fn outlives_bounds_even_with_contained_regions<'a, 'b> + (x: &'a u32, y: &'b u32) -> impl Debug + 'b +{ + finds_explicit_bound_even_without_least_region(x, y) +} +*/ + +fn unnamed_lifetimes_arent_contained_in_impl_trait_and_will_unify<'a, 'b> + (x: &'a u32, y: &'b u32) -> impl Debug +{ + fn deref<'lt>(x: &'lt u32) -> impl Debug { *x } + + if true { deref(x) } else { deref(y) } +} + +fn can_add_region_bound_to_static_type<'a, 'b>(_: &'a u32) -> impl Debug + 'a { 5 } + +struct MyVec(Vec>); + +impl<'unnecessary_lifetime> MyVec { + fn iter_doesnt_capture_unnecessary_lifetime<'s>(&'s self) -> impl Iterator { + self.0.iter().flat_map(|inner_vec| inner_vec.iter()) + } + + fn generator_doesnt_capture_unnecessary_lifetime<'s: 's>() -> impl Sized { + || yield + } +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/method-suggestion-no-duplication.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/method-suggestion-no-duplication.rs new file mode 100644 index 000000000000..fb20dcc0f5f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/method-suggestion-no-duplication.rs @@ -0,0 +1,10 @@ +// issue #21405 +struct Foo; + +fn foo(f: F) where F: FnMut(Foo) {} + +fn main() { + foo(|s| s.is_empty()); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes.rs new file mode 100644 index 000000000000..cf674f0fa4e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes.rs @@ -0,0 +1,13 @@ +// Test that multiple liftimes are allowed in impl trait types. +// build-pass (FIXME(62277): could be check-pass?) + +trait X<'x>: Sized {} + +impl X<'_> for U {} + +fn multiple_lifeteimes<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl X<'b> + 'a { + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/error-handling-2.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/error-handling-2.rs new file mode 100644 index 000000000000..0659b30f4d64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/error-handling-2.rs @@ -0,0 +1,30 @@ +// compile-flags:-Zborrowck=mir + +#![feature(member_constraints)] +#![feature(type_alias_impl_trait)] + +#[derive(Clone)] +struct CopyIfEq(T, U); + +impl Copy for CopyIfEq {} + +type E<'a, 'b> = impl Sized; + +fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { +// { dg-error ".E0700." "" { target *-*-* } .-1 } + let v = CopyIfEq::<*mut _, *mut _>(&mut { x }, &mut y); + + // This assignment requires that `x` and `y` have the same type due to the + // `Copy` impl. The reason why we are using a copy to create a constraint + // is that only borrow checking (not regionck in type checking) enforces + // this bound. + let u = v; + let _: *mut &'a i32 = u.1; + unsafe { + let _: &'b i32 = *u.0; + } + u.0 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/error-handling.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/error-handling.rs new file mode 100644 index 000000000000..c047fc441826 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/error-handling.rs @@ -0,0 +1,30 @@ +// compile-flags:-Zborrowck=mir + +#![feature(member_constraints)] +#![feature(type_alias_impl_trait)] + +#[derive(Clone)] +struct CopyIfEq(T, U); + +impl Copy for CopyIfEq {} + +type E<'a, 'b> = impl Sized; + +fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { + let v = CopyIfEq::<*mut _, *mut _>(&mut { x }, &mut y); + + // This assignment requires that `x` and `y` have the same type due to the + // `Copy` impl. The reason why we are using a copy to create a constraint + // is that only borrow checking (not regionck in type checking) enforces + // this bound. + let u = v; + let _: *mut &'a i32 = u.1; + unsafe { + let _: &'b i32 = *u.0; +// { dg-error "" "" { target *-*-* } .-1 } + } + u.0 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs new file mode 100644 index 000000000000..d48a6729802f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs @@ -0,0 +1,55 @@ +// edition:2018 +// check-pass +// revisions: migrate mir +//[mir]compile-flags: -Z borrowck=mir + +#![feature(member_constraints)] + +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} + +// `Invert<'a> <: Invert<'b>` if `'b: 'a`, unlike most types. +// +// I am purposefully avoiding the terms co- and contra-variant because +// their application to regions depends on how you interpreted Rust +// regions. -nikomatsakis +struct Invert<'a>(fn(&'a u8)); + +fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Invert<'a>, b: Invert<'b>) -> impl Trait<'d, 'e> +where + 'c: 'a, + 'c: 'b, + 'd: 'c, +{ + // Representing the where clauses as a graph, where `A: B` is an + // edge `B -> A`: + // + // ``` + // 'a -> 'c -> 'd + // ^ + // | + // 'b + // ``` + // + // Meanwhile we return a value &'0 u8 where we have the constraints: + // + // ``` + // '0: 'a + // '0: 'b + // '0 in ['d, 'e] + // ``` + // + // Here, ignoring the "in" constraint, the minimal choice for `'0` + // is `'c`, but that is not in the "in set". Still, that reduces + // the range of options in the "in set" to just `'d` (`'e: 'c` + // does not hold). + let p = if condition() { a } else { b }; + p +} + +fn condition() -> bool { + true +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs new file mode 100644 index 000000000000..075dfe85b2b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-elided.rs @@ -0,0 +1,30 @@ +// edition:2018 +// build-pass (FIXME(62277): could be check-pass?) +// revisions: migrate mir +//[mir]compile-flags: -Z borrowck=mir + +#![feature(member_constraints)] + +trait Trait<'a, 'b> { } +impl Trait<'_, '_> for T { } + +// Test case where we have elision in the impl trait and we have to +// pick the right region. + +// Ultimately `Trait<'x, 'static>`. +fn upper_bounds1(a: &u8) -> impl Trait<'_, 'static> { + (a, a) +} + +// Ultimately `Trait<'x, 'x>`, so not really multiple bounds. +fn upper_bounds2(a: &u8) -> impl Trait<'_, '_> { + (a, a) +} + +// Kind of a weird annoying case. +fn upper_bounds3<'b>(a: &u8) -> impl Trait<'_, 'b> { + (a, a) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs new file mode 100644 index 000000000000..8647d496f11e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original-type-alias-impl-trait.rs @@ -0,0 +1,33 @@ +// edition:2018 +// check-pass +// revisions: migrate mir +//[mir]compile-flags: -Z borrowck=mir + +#![feature(member_constraints)] +#![feature(type_alias_impl_trait)] + +trait Trait<'a, 'b> { } +impl Trait<'_, '_> for T { } + +// Here we wind up selecting `'a` and `'b` in the hidden type because +// those are the types that appear in the original values. + +type Foo<'a, 'b> = impl Trait<'a, 'b>; + +fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> Foo<'a, 'b> { + // In this simple case, you have a hidden type `(&'0 u8, &'1 u8)` and constraints like + // + // ``` + // 'a: '0 + // 'b: '1 + // '0 in ['a, 'b] + // '1 in ['a, 'b] + // ``` + // + // We use the fact that `'a: 0'` must hold (combined with the in + // constraint) to determine that `'0 = 'a` must be the answer. + (a, b) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs new file mode 100644 index 000000000000..d8531dd4b920 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-original.rs @@ -0,0 +1,30 @@ +// edition:2018 +// build-pass (FIXME(62277): could be check-pass?) +// revisions: migrate mir +//[mir]compile-flags: -Z borrowck=mir + +#![feature(member_constraints)] + +trait Trait<'a, 'b> { } +impl Trait<'_, '_> for T { } + +// Here we wind up selecting `'a` and `'b` in the hidden type because +// those are the types that appear in the original values. + +fn upper_bounds<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { + // In this simple case, you have a hidden type `(&'0 u8, &'1 u8)` and constraints like + // + // ``` + // 'a: '0 + // 'b: '1 + // '0 in ['a, 'b] + // '1 in ['a, 'b] + // ``` + // + // We use the fact that `'a: 0'` must hold (combined with the in + // constraint) to determine that `'0 = 'a` must be the answer. + (a, b) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs new file mode 100644 index 000000000000..6289fbf0e30f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-pick-other.rs @@ -0,0 +1,47 @@ +// edition:2018 +// build-pass (FIXME(62277): could be check-pass?) +// revisions: migrate mir +//[mir]compile-flags: -Z borrowck=mir + +#![feature(member_constraints)] + +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} + +// `Ordinary<'a> <: Ordinary<'b>` if `'a: 'b`, as with most types. +// +// I am purposefully avoiding the terms co- and contra-variant because +// their application to regions depends on how you interpreted Rust +// regions. -nikomatsakis +struct Ordinary<'a>(&'a u8); + +// Here we wind up selecting `'e` in the hidden type because +// we need something outlived by both `'a` and `'b` and only `'e` applies. + +fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> +where + 'a: 'e, + 'b: 'e, + 'a: 'd, +{ + // We return a value: + // + // ``` + // 'a: '0 + // 'b: '1 + // '0 in ['d, 'e] + // ``` + // + // but we don't have it. + // + // We are forced to pick that '0 = 'e, because only 'e is outlived by *both* 'a and 'b. + let p = if condition() { a } else { b }; + p +} + +fn condition() -> bool { + true +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs new file mode 100644 index 000000000000..a4363cf11645 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs @@ -0,0 +1,39 @@ +// edition:2018 + +#![feature(member_constraints)] + +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} + +// `Ordinary<'a> <: Ordinary<'b>` if `'a: 'b`, as with most types. +// +// I am purposefully avoiding the terms co- and contra-variant because +// their application to regions depends on how you interpreted Rust +// regions. -nikomatsakis +struct Ordinary<'a>(&'a u8); + +// Here we get an error because none of our choices (either `'d` nor `'e`) are outlived +// by both `'a` and `'b`. + +fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> +// { dg-error ".E0700." "" { target *-*-* } .-1 } +where + 'a: 'e, + 'b: 'd, +{ + // Hidden type `Ordinary<'0>` with constraints: + // + // ``` + // 'a: '0 + // 'b: '0 + // 'a in ['d, 'e] + // ``` + if condition() { a } else { b } +} + +fn condition() -> bool { + true +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs new file mode 100644 index 000000000000..a974914ace16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs @@ -0,0 +1,42 @@ +// edition:2018 + +#![feature(member_constraints)] + +trait Trait<'a, 'b> {} +impl Trait<'_, '_> for T {} + +// `Ordinary<'a> <: Ordinary<'b>` if `'a: 'b`, as with most types. +// +// I am purposefully avoiding the terms co- and contra-variant because +// their application to regions depends on how you interpreted Rust +// regions. -nikomatsakis +struct Ordinary<'a>(&'a u8); + +// Here we need something outlived by `'a` *and* outlived by `'b`, but +// we can only name `'a` and `'b` (and neither suits). So we get an +// error. Somewhat unfortunate, though, since the caller would have to +// consider the loans for both `'a` and `'b` alive. + +fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> +// { dg-error ".E0700." "" { target *-*-* } .-1 } +{ + // We return a value: + // + // ``` + // 'a: '0 + // 'b: '1 + // '0 in ['a, 'b] + // ``` + // + // but we don't have it. + // + // We are forced to pick that '0 = 'e, because only 'e is outlived by *both* 'a and 'b. + if condition() { a } else { b } +} + +fn condition() -> bool { + true +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/must_outlive_least_region_or_bound.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/must_outlive_least_region_or_bound.rs new file mode 100644 index 000000000000..267b3293997f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/must_outlive_least_region_or_bound.rs @@ -0,0 +1,43 @@ +use std::fmt::Debug; + +fn elided(x: &i32) -> impl Copy { x } // { dg-error ".E0759." "" { target *-*-* } } + +fn explicit<'a>(x: &'a i32) -> impl Copy { x } // { dg-error ".E0759." "" { target *-*-* } } + +fn elided2(x: &i32) -> impl Copy + 'static { x } // { dg-error ".E0759." "" { target *-*-* } } + +fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } // { dg-error ".E0759." "" { target *-*-* } } + +fn foo<'a>(x: &i32) -> impl Copy + 'a { x } +// { dg-error ".E0621." "" { target *-*-* } .-1 } + +fn elided3(x: &i32) -> Box { Box::new(x) } // { dg-error ".E0759." "" { target *-*-* } } + +fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } // { dg-error ".E0759." "" { target *-*-* } } + +fn elided4(x: &i32) -> Box { Box::new(x) } // { dg-error ".E0759." "" { target *-*-* } } + +fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } // { dg-error ".E0759." "" { target *-*-* } } + +fn elided5(x: &i32) -> (Box, impl Debug) { (Box::new(x), x) } // { dg-error ".E0759." "" { target *-*-* } } +// { dg-error ".E0759." "" { target *-*-* } .-1 } + +trait LifetimeTrait<'a> {} +impl<'a> LifetimeTrait<'a> for &'a i32 {} + +fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } // { dg-error ".E0759." "" { target *-*-* } } + +// Tests that a closure type containing 'b cannot be returned from a type where +// only 'a was expected. +fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { +// { dg-error ".E0623." "" { target *-*-* } .-1 } + move |_| println!("{}", y) +} + +fn ty_param_wont_outlive_static(x: T) -> impl Debug + 'static { +// { dg-error ".E0310." "" { target *-*-* } .-1 } + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/needs_least_region_or_bound.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/needs_least_region_or_bound.rs new file mode 100644 index 000000000000..97c69beb6d81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/needs_least_region_or_bound.rs @@ -0,0 +1,24 @@ +// check-pass + +#![feature(member_constraints)] + +trait MultiRegionTrait<'a, 'b> {} +impl<'a, 'b> MultiRegionTrait<'a, 'b> for (&'a u32, &'b u32) {} + +fn no_least_region<'a, 'b>(x: &'a u32, y: &'b u32) -> impl MultiRegionTrait<'a, 'b> { + // Here we have a constraint that: + // + // (x, y) has type (&'0 u32, &'1 u32) + // + // where + // + // 'a: '0 + // + // then we require that `('0 u32, &'1 u32): MultiRegionTrait<'a, + // 'b>`, which winds up imposing a requirement that `'0 = 'a` and + // `'1 = 'b`. + (x, y) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/negative-reasoning.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/negative-reasoning.rs new file mode 100644 index 000000000000..15138d2e8852 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/negative-reasoning.rs @@ -0,0 +1,24 @@ +// Tests that we cannot assume that an opaque type does *not* implement some +// other trait +#![feature(type_alias_impl_trait)] + +trait OpaqueTrait {} +impl OpaqueTrait for T {} +type OpaqueType = impl OpaqueTrait; +fn mk_opaque() -> OpaqueType { + () +} + +#[derive(Debug)] +struct D(T); + +trait AnotherTrait {} +impl AnotherTrait for T {} + +// This is in error, because we cannot assume that `OpaqueType: !Debug` +impl AnotherTrait for D { +// { dg-error ".E0119." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/nested-return-type.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/nested-return-type.rs new file mode 100644 index 000000000000..7d513be5ce38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/nested-return-type.rs @@ -0,0 +1,17 @@ +// Check that nested impl Trait items work in functions with generic parameters. +// check-pass + +trait Captures<'a> {} + +impl Captures<'_> for T {} + +fn nested_assoc_type<'a: 'a, T>() -> impl Iterator { + [1].iter() +} + +fn nested_assoc_lifetime<'a: 'a, T>() -> impl Iterator> { + [1].iter() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/nesting.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/nesting.rs new file mode 100644 index 000000000000..4cfb614bf65b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/nesting.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] + +fn foo(t: T) -> impl Into<[T; { const FOO: usize = 1; FOO }]> { + [t] +} + +fn bar() -> impl Into<[u8; { const FOO: usize = 1; FOO }]> { + [99] +} + +fn main() { + println!("{:?}", foo(42).into()); + println!("{:?}", bar().into()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/no-method-suggested-traits.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/no-method-suggested-traits.rs new file mode 100644 index 000000000000..016fdc88e920 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/no-method-suggested-traits.rs @@ -0,0 +1,78 @@ +// aux-build:no_method_suggested_traits.rs +extern crate no_method_suggested_traits; + +struct Foo; +enum Bar { X } + +mod foo { + pub trait Bar { + fn method(&self) {} + + fn method2(&self) {} + } + + impl Bar for u32 {} + + impl Bar for char {} +} + +fn main() { + // test the values themselves, and autoderef. + + + 1u32.method(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +// { dg-error ".E0599." "" { target *-*-* } .-2 } + std::rc::Rc::new(&mut Box::new(&1u32)).method(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +// { dg-error ".E0599." "" { target *-*-* } .-2 } + + 'a'.method(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + std::rc::Rc::new(&mut Box::new(&'a')).method(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + + 1i32.method(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + std::rc::Rc::new(&mut Box::new(&1i32)).method(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + + Foo.method(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + std::rc::Rc::new(&mut Box::new(&Foo)).method(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + + 1u64.method2(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + std::rc::Rc::new(&mut Box::new(&1u64)).method2(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + + no_method_suggested_traits::Foo.method2(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + no_method_suggested_traits::Bar::X.method2(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + + Foo.method3(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + std::rc::Rc::new(&mut Box::new(&Foo)).method3(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + Bar::X.method3(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + + // should have no help: + 1_usize.method3(); // { dg-error ".E0599." "" { target *-*-* } } + std::rc::Rc::new(&mut Box::new(&1_usize)).method3(); // { dg-error ".E0599." "" { target *-*-* } } + no_method_suggested_traits::Foo.method3(); // { dg-error ".E0599." "" { target *-*-* } } + std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + no_method_suggested_traits::Bar::X.method3(); // { dg-error ".E0599." "" { target *-*-* } } + std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/no-trait.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/no-trait.rs new file mode 100644 index 000000000000..116f0586e92a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/no-trait.rs @@ -0,0 +1,4 @@ +fn f() -> impl 'static {} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs new file mode 100644 index 000000000000..e59d1da2b9d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs @@ -0,0 +1,36 @@ +#![allow(bare_trait_objects)] +trait NotObjectSafe { + fn foo() -> Self; +} + +struct A; +struct B; + +impl NotObjectSafe for A { + fn foo() -> Self { + A + } +} + +impl NotObjectSafe for B { + fn foo() -> Self { + B + } +} + +fn car() -> dyn NotObjectSafe { // { dg-error ".E0038." "" { target *-*-* } } + if true { + return A; + } + B +} + +fn cat() -> Box { // { dg-error ".E0038." "" { target *-*-* } } + if true { + return Box::new(A); + } + Box::new(B) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs new file mode 100644 index 000000000000..25766092ed8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs @@ -0,0 +1,47 @@ +trait NotObjectSafe { + fn foo() -> Self; +} + +trait ObjectSafe { + fn bar(&self); +} + +struct A; +struct B; + +impl NotObjectSafe for A { + fn foo() -> Self { + A + } +} + +impl NotObjectSafe for B { + fn foo() -> Self { + B + } +} + +impl ObjectSafe for A { + fn bar(&self) {} +} + +impl ObjectSafe for B { + fn bar(&self) {} +} + +fn can() -> impl NotObjectSafe { + if true { + return A; + } + B // { dg-error ".E0308." "" { target *-*-* } } +} + +fn cat() -> impl ObjectSafe { + if true { + return A; + } + B // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/recursive-impl-trait-type-direct.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/recursive-impl-trait-type-direct.rs new file mode 100644 index 000000000000..ce5d3af920d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/recursive-impl-trait-type-direct.rs @@ -0,0 +1,11 @@ +// Test that an `impl Trait` type that expands to itself is an error. + +#![allow(unconditional_recursion)] + +fn test() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + test() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/recursive-impl-trait-type-indirect.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/recursive-impl-trait-type-indirect.rs new file mode 100644 index 000000000000..35f2cb883a1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/recursive-impl-trait-type-indirect.rs @@ -0,0 +1,97 @@ +// Test that impl trait does not allow creating recursive types that are +// otherwise forbidden. + +#![feature(generators)] +#![allow(unconditional_recursion)] + +fn option(i: i32) -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + if i < 0 { None } else { Some((option(i - 1), i)) } +} + +fn tuple() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + (tuple(),) +} + +fn array() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + [array()] +} + +fn ptr() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + &ptr() as *const _ +} + +fn fn_ptr() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + fn_ptr as fn() -> _ +} + +fn closure_capture() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + let x = closure_capture(); + move || { + x; + } +} + +fn closure_ref_capture() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + let x = closure_ref_capture(); + move || { + &x; + } +} + +fn closure_sig() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + || closure_sig() +} + +fn generator_sig() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + || generator_sig() +} + +fn generator_capture() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + let x = generator_capture(); + move || { + yield; + x; + } +} + +fn substs_change() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + (substs_change::<&T>(),) +} + +fn generator_hold() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + move || { + let x = generator_hold(); + yield; + x; + } +} + +fn use_fn_ptr() -> impl Sized { + // OK, error already reported + fn_ptr() +} + +fn mutual_recursion() -> impl Sync { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + mutual_recursion_b() +} + +fn mutual_recursion_b() -> impl Sized { +// { dg-error ".E0720." "" { target *-*-* } .-1 } + mutual_recursion() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs new file mode 100644 index 000000000000..c774b9eda4f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/recursive-impl-trait-type-through-non-recursive.rs @@ -0,0 +1,26 @@ +// Test that impl trait does not allow creating recursive types that are +// otherwise forbidden. Even when there's an opaque type in another crate +// hiding this. + +fn id(t: T) -> impl Sized { t } + +fn recursive_id() -> impl Sized { // { dg-error ".E0720." "" { target *-*-* } } + id(recursive_id2()) +} + +fn recursive_id2() -> impl Sized { // { dg-error ".E0720." "" { target *-*-* } } + id(recursive_id()) +} + +fn wrap(t: T) -> impl Sized { (t,) } + +fn recursive_wrap() -> impl Sized { // { dg-error ".E0720." "" { target *-*-* } } + wrap(recursive_wrap2()) +} + +fn recursive_wrap2() -> impl Sized { // { dg-error ".E0720." "" { target *-*-* } } + wrap(recursive_wrap()) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs new file mode 100644 index 000000000000..a84963417dec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs @@ -0,0 +1,20 @@ +// In contrast to `region-escape-via-bound-invariant`, in this case we +// *can* return a value of type `&'x u32`, even though `'x` does not +// appear in the bounds. This is because `&` is contravariant, and so +// we are *actually* returning a `&'y u32`. +// +// See https://github.com/rust-lang/rust/issues/46541 for more details. + +// run-pass + +#![allow(dead_code)] +#![feature(in_band_lifetimes)] + +fn foo(x: &'x u32) -> impl Fn() -> &'y u32 +where 'x: 'y +{ + move || x +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/region-escape-via-bound-contravariant.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/region-escape-via-bound-contravariant.rs new file mode 100644 index 000000000000..41dda2ca7956 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/region-escape-via-bound-contravariant.rs @@ -0,0 +1,24 @@ +// In contrast to `region-escape-via-bound-invariant`, in this case we +// *can* return a value of type `&'x u32`, even though `'x` does not +// appear in the bounds. This is because `&` is contravariant, and so +// we are *actually* returning a `&'y u32`. +// +// See https://github.com/rust-lang/rust/issues/46541 for more details. + +// run-pass + +#![allow(dead_code)] +#![feature(in_band_lifetimes)] + +trait Trait<'a> { } + +impl Trait<'b> for &'a u32 { } + +fn foo(x: &'x u32) -> impl Trait<'y> +where 'x: 'y +{ + x +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/region-escape-via-bound.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/region-escape-via-bound.rs new file mode 100644 index 000000000000..3a44e0109311 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/region-escape-via-bound.rs @@ -0,0 +1,23 @@ +// Test that we do not allow the region `'x` to escape in the impl +// trait **even though** `'y` escapes, which outlives `'x`. +// +// See https://github.com/rust-lang/rust/issues/46541 for more details. + +#![allow(dead_code)] +#![feature(in_band_lifetimes)] + +use std::cell::Cell; + +trait Trait<'a> { } + +impl Trait<'b> for Cell<&'a u32> { } + +fn foo(x: Cell<&'x u32>) -> impl Trait<'y> +// { dg-error ".E0700." "" { target *-*-* } .-1 } +where 'x: 'y +{ + x +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/return-position-impl-trait-minimal.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/return-position-impl-trait-minimal.rs new file mode 100644 index 000000000000..f5caf053c2d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/return-position-impl-trait-minimal.rs @@ -0,0 +1,6 @@ +// build-pass (FIXME(62277): could be check-pass?) + +fn main() {} + +fn foo() -> impl std::fmt::Debug { "cake" } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/static-return-lifetime-infered.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/static-return-lifetime-infered.rs new file mode 100644 index 000000000000..fa842d9b0af8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/static-return-lifetime-infered.rs @@ -0,0 +1,15 @@ +struct A { + x: [(u32, u32); 10] +} + +impl A { + fn iter_values_anon(&self) -> impl Iterator { + self.x.iter().map(|a| a.0) // { dg-error ".E0759." "" { target *-*-* } } + } + fn iter_values<'a>(&'a self) -> impl Iterator { + self.x.iter().map(|a| a.0) // { dg-error ".E0759." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/trait_type.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/trait_type.rs new file mode 100644 index 000000000000..68e6991da340 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/trait_type.rs @@ -0,0 +1,25 @@ +struct MyType; +struct MyType2; +struct MyType3; +struct MyType4; + +impl std::fmt::Display for MyType { + fn fmt(&self, x: &str) -> () { } +// { dg-error ".E0053." "" { target *-*-* } .-1 } +} + +impl std::fmt::Display for MyType2 { + fn fmt(&self) -> () { } +// { dg-error ".E0050." "" { target *-*-* } .-1 } +} + +impl std::fmt::Display for MyType3 { + fn fmt() -> () { } +// { dg-error ".E0186." "" { target *-*-* } .-1 } +} + +impl std::fmt::Display for MyType4 {} +// { dg-error ".E0046." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/type-alias-generic-param.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/type-alias-generic-param.rs new file mode 100644 index 000000000000..4bad8887e1d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/type-alias-generic-param.rs @@ -0,0 +1,23 @@ +// Regression test for issue #59342 +// Checks that we properly detect defining uses of opaque +// types in 'item' position when generic parameters are involved +// +// run-pass +#![feature(type_alias_impl_trait)] + +trait Meow { + type MeowType; + fn meow(self) -> Self::MeowType; +} + +impl Meow for I + where I: Iterator +{ + type MeowType = impl Iterator; + fn meow(self) -> Self::MeowType { + self + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs new file mode 100644 index 000000000000..97b817e078f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/type-alias-impl-trait-in-fn-body.rs @@ -0,0 +1,13 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() { + type Existential = impl Debug; + + fn f() -> Existential {} + println!("{:?}", f()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/type_parameters_captured.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/type_parameters_captured.rs new file mode 100644 index 000000000000..31476b0cf8b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/type_parameters_captured.rs @@ -0,0 +1,13 @@ +use std::fmt::Debug; + +trait Any {} +impl Any for T {} + +// Check that type parameters are captured and not considered 'static +fn foo(x: T) -> impl Any + 'static { +// { dg-error ".E0310." "" { target *-*-* } .-1 } + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/universal-mismatched-type.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/universal-mismatched-type.rs new file mode 100644 index 000000000000..0a2e6a2cdfba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/universal-mismatched-type.rs @@ -0,0 +1,8 @@ +use std::fmt::Debug; + +fn foo(x: impl Debug) -> String { + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/universal-two-impl-traits.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/universal-two-impl-traits.rs new file mode 100644 index 000000000000..a2cd0fa23067 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/universal-two-impl-traits.rs @@ -0,0 +1,10 @@ +use std::fmt::Debug; + +fn foo(x: impl Debug, y: impl Debug) -> String { + let mut a = x; + a = y; // { dg-error ".E0308." "" { target *-*-* } } + format!("{:?}", a) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/universal_hrtb_anon.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_hrtb_anon.rs new file mode 100644 index 000000000000..594e10c3a9ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_hrtb_anon.rs @@ -0,0 +1,11 @@ +// run-pass + +fn hrtb(f: impl Fn(&u32) -> u32) -> u32 { + f(&22) + f(&44) +} + +fn main() { + let sum = hrtb(|x| x * 2); + assert_eq!(sum, 22*2 + 44*2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/universal_hrtb_named.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_hrtb_named.rs new file mode 100644 index 000000000000..e08f1dd1d320 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_hrtb_named.rs @@ -0,0 +1,11 @@ +// run-pass + +fn hrtb(f: impl for<'a> Fn(&'a u32) -> &'a u32) -> u32 { + f(&22) + f(&44) +} + +fn main() { + let sum = hrtb(|x| x); + assert_eq!(sum, 22 + 44); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/universal_in_adt_in_parameters.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_in_adt_in_parameters.rs new file mode 100644 index 000000000000..9e4288df833d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_in_adt_in_parameters.rs @@ -0,0 +1,23 @@ +// run-pass + +use std::fmt::Display; + +fn check_display_eq(iter: &Vec) { + let mut collected = String::new(); + for it in iter { + let disp = format!("{} ", it); + collected.push_str(&disp); + } + assert_eq!("0 3 27 823 4891 1 0", collected.trim()); +} + +fn main() { + let i32_list_vec = vec![0i32, 3, 27, 823, 4891, 1, 0]; + let u32_list_vec = vec![0u32, 3, 27, 823, 4891, 1, 0]; + let str_list_vec = vec!["0", "3", "27", "823", "4891", "1", "0"]; + + check_display_eq(&i32_list_vec); + check_display_eq(&u32_list_vec); + check_display_eq(&str_list_vec); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/universal_in_impl_trait_in_parameters.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_in_impl_trait_in_parameters.rs new file mode 100644 index 000000000000..401c17d2c4fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_in_impl_trait_in_parameters.rs @@ -0,0 +1,31 @@ +// run-pass + +use std::fmt::Display; + +fn check_display_eq(iter: impl IntoIterator) { + let mut collected = String::new(); + for it in iter { + let disp = format!("{} ", it); + collected.push_str(&disp); + } + assert_eq!("0 3 27 823 4891 1 0", collected.trim()); +} + +fn main() { + let i32_list = [0i32, 3, 27, 823, 4891, 1, 0]; + let i32_list_vec = vec![0i32, 3, 27, 823, 4891, 1, 0]; + let u32_list = [0u32, 3, 27, 823, 4891, 1, 0]; + let u32_list_vec = vec![0u32, 3, 27, 823, 4891, 1, 0]; + let u16_list = [0u16, 3, 27, 823, 4891, 1, 0]; + let str_list = ["0", "3", "27", "823", "4891", "1", "0"]; + let str_list_vec = vec!["0", "3", "27", "823", "4891", "1", "0"]; + + check_display_eq(&i32_list); + check_display_eq(i32_list_vec); + check_display_eq(&u32_list); + check_display_eq(u32_list_vec); + check_display_eq(&u16_list); + check_display_eq(&str_list); + check_display_eq(str_list_vec); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/universal_in_trait_defn_parameters.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_in_trait_defn_parameters.rs new file mode 100644 index 000000000000..2c55320494d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_in_trait_defn_parameters.rs @@ -0,0 +1,19 @@ +// run-pass + +use std::fmt::Debug; + +trait InTraitDefnParameters { + fn in_parameters(_: impl Debug) -> String; +} + +impl InTraitDefnParameters for () { + fn in_parameters(v: impl Debug) -> String { + format!("() + {:?}", v) + } +} + +fn main() { + let s = <() as InTraitDefnParameters>::in_parameters(22); + assert_eq!(s, "() + 22"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/universal_multiple_bounds.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_multiple_bounds.rs new file mode 100644 index 000000000000..7c71e27635c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_multiple_bounds.rs @@ -0,0 +1,14 @@ +// run-pass + +use std::fmt::Display; + +fn foo(f: impl Display + Clone) -> String { + let g = f.clone(); + format!("{} + {}", f, g) +} + +fn main() { + let sum = foo(format!("22")); + assert_eq!(sum, r"22 + 22"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/universal_wrong_bounds.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_wrong_bounds.rs new file mode 100644 index 000000000000..866d624583d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/universal_wrong_bounds.rs @@ -0,0 +1,14 @@ +use std::fmt::Display; + +fn foo(f: impl Display + Clone) -> String { + wants_debug(f); + wants_display(f); + wants_clone(f); +} + +fn wants_debug(g: impl Debug) { } // { dg-error ".E0404." "" { target *-*-* } } +fn wants_display(g: impl Debug) { } // { dg-error ".E0404." "" { target *-*-* } } +fn wants_clone(g: impl Clone) { } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/unsafety-checking-cycle.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/unsafety-checking-cycle.rs new file mode 100644 index 000000000000..3f2008fc9ec8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/unsafety-checking-cycle.rs @@ -0,0 +1,33 @@ +// Ensure that we don't get a cycle error from trying to determine whether an +// opaque type implements `Freeze` in safety checking, when it doesn't matter. + +// check-pass + +#![feature(rustc_attrs)] + +struct AnyValue(T); + +// No need to check for `Freeze` here, there's no +// `rustc_layout_scalar_valid_range_start` involved. +fn not_restricted(c: bool) -> impl Sized { + if c { + let x = AnyValue(not_restricted(false)); + &x.0; + } + 2u32 +} + +#[rustc_layout_scalar_valid_range_start(1)] +struct NonZero(T); + +// No need to check for `Freeze` here, we're not borrowing the field. +fn not_field(c: bool) -> impl Sized { + if c { + let x = unsafe { NonZero(not_field(false)) }; + &x; + } + 5u32 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/wf-eval-order.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/wf-eval-order.rs new file mode 100644 index 000000000000..9cae8b350f2e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/wf-eval-order.rs @@ -0,0 +1,40 @@ +// Check that we handle evaluating `wf` predicates correctly. + +// check-pass + +struct X(T) +where + T::V: Clone; + +fn hide(t: T) -> impl Sized { + t +} + +trait A { + type U; +} + +impl A for T { + type U = T; +} + +trait B { + type V; +} + +impl, T> B for S { + type V = T; +} + +fn main() { + // Evaluating `typeof(x): Sized` requires + // + // - `wf(typeof(x))` because we use a projection candidate. + // - `::V: Clone` because that's a bound on the trait. + // - `::V` normalizes to `_#1` where `::U == _#1` + // + // This all works if we evaluate `::U == _#1` before + // `::V`, but we previously had the opposite order. + let x = hide(X(0)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/where-allowed-2.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/where-allowed-2.rs new file mode 100644 index 000000000000..010cad083ab2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/where-allowed-2.rs @@ -0,0 +1,9 @@ +//! Ideally, these tests would go in `where-allowed.rs`, but we bail out +//! too early to display them. +use std::fmt::Debug; + +// Disallowed +fn in_adt_in_return() -> Vec { panic!() } // { dg-error ".E0720." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/where-allowed.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/where-allowed.rs new file mode 100644 index 000000000000..4aae6902c5ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/where-allowed.rs @@ -0,0 +1,227 @@ +//! A simple test for testing many permutations of allowedness of +//! impl Trait +use std::fmt::Debug; + +// Allowed +fn in_parameters(_: impl Debug) { panic!() } + +// Allowed +fn in_return() -> impl Debug { panic!() } + +// Allowed +fn in_adt_in_parameters(_: Vec) { panic!() } + +// Disallowed +fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } +// { dg-error ".E0562." "" { target *-*-* } .-1 } +// { dg-error ".E0562." "" { target *-*-* } .-2 } + +// Disallowed +fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } +// { dg-error ".E0720." "" { target *-*-* } .-1 } +// { dg-error ".E0720." "" { target *-*-* } .-2 } +// { dg-error ".E0720." "" { target *-*-* } .-3 } + +// Disallowed +fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() } +// { dg-error ".E0720." "" { target *-*-* } .-1 } +// { dg-error ".E0720." "" { target *-*-* } .-2 } + +// Disallowed +fn in_Fn_parameter_in_generics (_: F) { panic!() } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +fn in_Fn_return_in_generics impl Debug> (_: F) { panic!() } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + + +// Allowed +fn in_impl_Trait_in_parameters(_: impl Iterator) { panic!() } + +// Allowed +fn in_impl_Trait_in_return() -> impl IntoIterator { + vec![vec![0; 10], vec![12; 7], vec![8; 3]] +} + +// Disallowed +struct InBraceStructField { x: impl Debug } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +struct InAdtInBraceStructField { x: Vec } +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +struct InTupleStructField(impl Debug); +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +// Disallowed +enum InEnum { + InBraceVariant { x: impl Debug }, +// { dg-error ".E0562." "" { target *-*-* } .-1 } + InTupleVariant(impl Debug), +// { dg-error ".E0562." "" { target *-*-* } .-1 } +} + +// Allowed +trait InTraitDefnParameters { + fn in_parameters(_: impl Debug); +} + +// Disallowed +trait InTraitDefnReturn { + fn in_return() -> impl Debug; +// { dg-error ".E0562." "" { target *-*-* } .-1 } +} + +// Allowed and disallowed in trait impls +trait DummyTrait { + type Out; + fn in_trait_impl_parameter(_: impl Debug); + fn in_trait_impl_return() -> Self::Out; +} +impl DummyTrait for () { + type Out = impl Debug; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + fn in_trait_impl_parameter(_: impl Debug) { } + // Allowed + + fn in_trait_impl_return() -> impl Debug { () } +// { dg-error ".E0562." "" { target *-*-* } .-1 } +} + +// Allowed +struct DummyType; +impl DummyType { + fn in_inherent_impl_parameters(_: impl Debug) { } + fn in_inherent_impl_return() -> impl Debug { () } +} + +// Disallowed +extern "C" { + fn in_foreign_parameters(_: impl Debug); +// { dg-error ".E0562." "" { target *-*-* } .-1 } + + fn in_foreign_return() -> impl Debug; +// { dg-error ".E0562." "" { target *-*-* } .-1 } +} + +// Allowed +extern "C" fn in_extern_fn_parameters(_: impl Debug) { +} + +// Allowed +extern "C" fn in_extern_fn_return() -> impl Debug { + 22 +} + +type InTypeAlias = impl Debug; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + +type InReturnInTypeAlias = fn() -> impl Debug; +// { dg-error ".E0562." "" { target *-*-* } .-1 } +// { dg-error ".E0562." "" { target *-*-* } .-2 } + +// Disallowed in impl headers +impl PartialEq for () { +// { dg-error ".E0562." "" { target *-*-* } .-1 } +} + +// Disallowed in impl headers +impl PartialEq<()> for impl Debug { +// { dg-error ".E0562." "" { target *-*-* } .-1 } +} + +// Disallowed in inherent impls +impl impl Debug { +// { dg-error ".E0562." "" { target *-*-* } .-1 } +} + +// Disallowed in inherent impls +struct InInherentImplAdt { t: T } +impl InInherentImplAdt { +// { dg-error ".E0562." "" { target *-*-* } .-1 } +} + +// Disallowed in where clauses +fn in_fn_where_clause() + where impl Debug: Debug +// { dg-error ".E0562." "" { target *-*-* } .-1 } +{ +} + +// Disallowed in where clauses +fn in_adt_in_fn_where_clause() + where Vec: Debug +// { dg-error ".E0562." "" { target *-*-* } .-1 } +{ +} + +// Disallowed +fn in_trait_parameter_in_fn_where_clause() + where T: PartialEq +// { dg-error ".E0562." "" { target *-*-* } .-1 } +{ +} + +// Disallowed +fn in_Fn_parameter_in_fn_where_clause() + where T: Fn(impl Debug) +// { dg-error ".E0562." "" { target *-*-* } .-1 } +{ +} + +// Disallowed +fn in_Fn_return_in_fn_where_clause() + where T: Fn() -> impl Debug +// { dg-error ".E0562." "" { target *-*-* } .-1 } +{ +} + +fn main() { + let _in_local_variable: impl Fn() = || {}; +// { dg-error ".E0562." "" { target *-*-* } .-1 } + let _in_return_in_local_variable = || -> impl Fn() { || {} }; +// { dg-error ".E0562." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/xcrate.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/xcrate.rs new file mode 100644 index 000000000000..77e3f8611d40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/xcrate.rs @@ -0,0 +1,12 @@ +// run-pass + +// aux-build:xcrate.rs + +extern crate xcrate; + +fn main() { +// NOTE line below commeted out due to issue #45994 +// assert_eq!(xcrate::fourway_add(1)(2)(3)(4), 10); + xcrate::return_closure_accessing_internal_fn()(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-trait/xcrate_simple.rs b/gcc/testsuite/rust/rustc/ui/impl-trait/xcrate_simple.rs new file mode 100644 index 000000000000..1df9d0b60453 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-trait/xcrate_simple.rs @@ -0,0 +1,10 @@ +// run-pass + +// aux-build:xcrate.rs + +extern crate xcrate; + +fn main() { + xcrate::return_internal_fn()(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impl-unused-rps-in-assoc-type.rs b/gcc/testsuite/rust/rustc/ui/impl-unused-rps-in-assoc-type.rs new file mode 100644 index 000000000000..32fb014729f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-unused-rps-in-assoc-type.rs @@ -0,0 +1,19 @@ +// Test that lifetime parameters must be constrained if they appear in +// an associated type def'n. Issue #22077. + +trait Fun { + type Output; + fn call<'x>(&'x self) -> Self::Output; +} + +struct Holder { x: String } + +impl<'a> Fun for Holder { // { dg-error ".E0207." "" { target *-*-* } } + type Output = &'a str; + fn call<'b>(&'b self) -> &'b str { + &self.x[..] + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-unused-tps-inherent.rs b/gcc/testsuite/rust/rustc/ui/impl-unused-tps-inherent.rs new file mode 100644 index 000000000000..bf83f4966f9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-unused-tps-inherent.rs @@ -0,0 +1,26 @@ +struct MyType; + +struct MyType1(T); + +trait Bar { + type Out; +} + +impl MyType { +// { dg-error ".E0207." "" { target *-*-* } .-1 } +} + +impl MyType1 { + // OK, T is used in `Foo`. +} + +impl MyType1 { +// { dg-error ".E0207." "" { target *-*-* } .-1 } +} + +impl MyType1 where T: Bar { + // OK, T is used in `Foo`. +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/impl-unused-tps.rs b/gcc/testsuite/rust/rustc/ui/impl-unused-tps.rs new file mode 100644 index 000000000000..c9184b41dac1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impl-unused-tps.rs @@ -0,0 +1,63 @@ +trait Foo { + fn get(&self, A: &A) { } +} + +trait Bar { + type Out; +} + +impl Foo for [isize;0] { + // OK, T is used in `Foo`. +} + +impl Foo for [isize;1] { +// { dg-error ".E0207." "" { target *-*-* } .-1 } +} + +impl Foo for [isize;2] where T : Bar { + // OK, `U` is now constrained by the output type parameter. +} + +impl,U> Foo for [isize;3] { + // OK, same as above but written differently. +} + +impl Foo for U { + // OK, T, U are used everywhere. Note that the coherence check + // hasn't executed yet, so no errors about overlap. +} + +impl Bar for T { +// { dg-error ".E0207." "" { target *-*-* } .-1 } + + type Out = U; + + // Using `U` in an associated type within the impl is not good enough! +} + +impl Bar for T + where T : Bar +{ +// { dg-error ".E0207." "" { target *-*-* } .-3 } + + // This crafty self-referential attempt is still no good. +} + +impl Foo for T + where (T,U): Bar +{ +// { dg-error ".E0207." "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-2 } + + // Here, `V` is bound by an output type parameter, but the inputs + // are not themselves constrained. +} + +impl Foo<(T,U)> for T + where (T,U): Bar +{ + // As above, but both T and U ARE constrained. +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/implicit-method-bind.rs b/gcc/testsuite/rust/rustc/ui/implicit-method-bind.rs new file mode 100644 index 000000000000..27c295693f38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/implicit-method-bind.rs @@ -0,0 +1,4 @@ +fn main() { + let _f = 10i32.abs; // { dg-error ".E0615." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/import.rs b/gcc/testsuite/rust/rustc/ui/import.rs new file mode 100644 index 000000000000..66104a2f2a7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/import.rs @@ -0,0 +1,18 @@ +use zed::bar; +use zed::baz; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +// { suggestion "" "" { target *-*-* } .-4 } + + +mod zed { + pub fn bar() { println!("bar"); } + use foo; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-1 } +} + +fn main() { + zed::foo(); // { dg-error ".E0603." "" { target *-*-* } } + bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/import2.rs b/gcc/testsuite/rust/rustc/ui/import2.rs new file mode 100644 index 000000000000..024c548ec94c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/import2.rs @@ -0,0 +1,11 @@ +use baz::zed::bar; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +mod baz {} +mod zed { + pub fn bar() { println!("bar3"); } +} +fn main() { + bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/import3.rs b/gcc/testsuite/rust/rustc/ui/import3.rs new file mode 100644 index 000000000000..d3ef7441bbb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/import3.rs @@ -0,0 +1,5 @@ +// error-pattern: unresolved +use main::bar; + +fn main() { println!("foo"); } + diff --git a/gcc/testsuite/rust/rustc/ui/import4.rs b/gcc/testsuite/rust/rustc/ui/import4.rs new file mode 100644 index 000000000000..dd209a504dc6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/import4.rs @@ -0,0 +1,8 @@ +// error-pattern: import + + +mod a { pub use b::foo; } +mod b { pub use a::foo; } + +fn main() { println!("loop"); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/auxiliary/gensymed.rs b/gcc/testsuite/rust/rustc/ui/imports/auxiliary/gensymed.rs new file mode 100644 index 000000000000..e68599cd7533 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/auxiliary/gensymed.rs @@ -0,0 +1,4 @@ +// edition:2018 + +mod std {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/auxiliary/glob-conflict.rs b/gcc/testsuite/rust/rustc/ui/imports/auxiliary/glob-conflict.rs new file mode 100644 index 000000000000..ef6c58cbd52a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/auxiliary/glob-conflict.rs @@ -0,0 +1,14 @@ +mod m1 { + pub fn f() {} +} +mod m2 { + pub fn f(_: u8) {} +} + +pub use m1::*; +pub use m2::*; + +pub mod glob { + pub use *; +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/auxiliary/import_crate_var.rs b/gcc/testsuite/rust/rustc/ui/imports/auxiliary/import_crate_var.rs new file mode 100644 index 000000000000..1c8ae41542ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/auxiliary/import_crate_var.rs @@ -0,0 +1,8 @@ +pub fn f() {} + +#[macro_export] +macro_rules! m { () => { + use $crate; + import_crate_var::f(); +} } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/auxiliary/issue-55811.rs b/gcc/testsuite/rust/rustc/ui/imports/auxiliary/issue-55811.rs new file mode 100644 index 000000000000..a4ff022a245e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/auxiliary/issue-55811.rs @@ -0,0 +1,6 @@ +mod m {} + +// These two imports should not conflict when this crate is loaded from some other crate. +use m::{}; +use m::{}; + diff --git a/gcc/testsuite/rust/rustc/ui/imports/auxiliary/issue-56125.rs b/gcc/testsuite/rust/rustc/ui/imports/auxiliary/issue-56125.rs new file mode 100644 index 000000000000..0f0a11269eee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/auxiliary/issue-56125.rs @@ -0,0 +1,12 @@ +pub mod issue_56125 {} + +pub mod last_segment { + pub mod issue_56125 {} +} + +pub mod non_last_segment { + pub mod non_last_segment { + pub mod issue_56125 {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/auxiliary/two_macros.rs b/gcc/testsuite/rust/rustc/ui/imports/auxiliary/two_macros.rs new file mode 100644 index 000000000000..c55555a8852b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/auxiliary/two_macros.rs @@ -0,0 +1,6 @@ +#[macro_export] +macro_rules! m { ($($t:tt)*) => { $($t)* } } + +#[macro_export] +macro_rules! n { ($($t:tt)*) => { $($t)* } } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/duplicate.rs b/gcc/testsuite/rust/rustc/ui/imports/duplicate.rs new file mode 100644 index 000000000000..5ccf01e7420e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/duplicate.rs @@ -0,0 +1,52 @@ +mod a { + pub fn foo() {} +} + +mod b { + pub fn foo() {} +} + +mod c { + pub use a::foo; +} + +mod d { + use a::foo; + use a::foo; // { dg-error ".E0252." "" { target *-*-* } } +} + +mod e { + pub use a::*; + pub use c::*; // ok +} + +mod f { + pub use a::*; + pub use b::*; +} + +mod g { + pub use a::*; + pub use f::*; +} + +fn main() { + e::foo(); + f::foo(); // { dg-error ".E0659." "" { target *-*-* } } + g::foo(); +} + +mod ambiguous_module_errors { + pub mod m1 { pub use super::m1 as foo; pub fn bar() {} } + pub mod m2 { pub use super::m2 as foo; } + + use self::m1::*; + use self::m2::*; + + use self::foo::bar; // { dg-error ".E0659." "" { target *-*-* } } + + fn f() { + foo::bar(); // { dg-error ".E0659." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-fail.rs b/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-fail.rs new file mode 100644 index 000000000000..8af7eaf7fe0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-fail.rs @@ -0,0 +1,7 @@ +extern crate self; // { dg-error "" "" { target *-*-* } } + +#[macro_use] // { dg-error "" "" { target *-*-* } } +extern crate self as foo; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-alias.rs b/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-alias.rs new file mode 100644 index 000000000000..fc5b738d5cac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-alias.rs @@ -0,0 +1,17 @@ +// run-pass + +// Test that a macro can correctly expand the alias +// in an `extern crate self as ALIAS` item. + +fn the_answer() -> usize { 42 } + +macro_rules! alias_self { + ($alias:ident) => { extern crate self as $alias; } +} + +alias_self!(the_alias); + +fn main() { + assert_eq!(the_alias::the_answer(), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs b/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs new file mode 100644 index 000000000000..0cb3f1d57001 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-item.rs @@ -0,0 +1,13 @@ +// build-pass (FIXME(62277): could be check-pass?) + +// Test that `extern crate self;` is accepted +// syntactically as an item for use in a macro. + +macro_rules! accept_item { ($x:item) => {} } + +accept_item! { + extern crate self; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-self.rs b/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-self.rs new file mode 100644 index 000000000000..f141a1509fad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-macro-self.rs @@ -0,0 +1,17 @@ +// run-pass + +// Test that a macro can correctly expand `self` in +// an `extern crate self as ALIAS` item. + +fn the_answer() -> usize { 42 } + +macro_rules! extern_something { + ($alias:ident) => { extern crate $alias as the_alias; } +} + +extern_something!(self); + +fn main() { + assert_eq!(the_alias::the_answer(), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-pass.rs b/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-pass.rs new file mode 100644 index 000000000000..d1a0f9c1be19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/extern-crate-self/extern-crate-self-pass.rs @@ -0,0 +1,14 @@ +// build-pass (FIXME(62277): could be check-pass?) + +extern crate self as foo; + +struct S; + +mod m { + fn check() { + foo::S; // OK + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/extern-crate-used.rs b/gcc/testsuite/rust/rustc/ui/imports/extern-crate-used.rs new file mode 100644 index 000000000000..b0f4b4d1cbfe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/extern-crate-used.rs @@ -0,0 +1,33 @@ +// Extern crate items are marked as used if they are used +// through extern prelude entries introduced by them. + +// edition:2018 + +#![deny(unused_extern_crates)] + +// Shouldn't suggest changing to `use`, as new name +// would no longer be added to the prelude which could cause +// compilation errors for imports that use the new name in +// other modules. See #57672. +extern crate core as iso1; +extern crate core as iso2; +extern crate core as iso3; +extern crate core as iso4; + +// Doesn't introduce its extern prelude entry, so it's still considered unused. +extern crate core; // { dg-error "" "" { target *-*-* } } + +mod m { + use iso1::any as are_you_okay1; + use ::iso2::any as are_you_okay2; + type AreYouOkay1 = dyn iso3::any::Any; + type AreYouOkay2 = dyn (::iso4::any::Any); + + use core::any as are_you_okay3; + use ::core::any as are_you_okay4; + type AreYouOkay3 = dyn core::any::Any; + type AreYouOkay4 = dyn (::core::any::Any); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs b/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs new file mode 100644 index 000000000000..03bf9fd698a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs @@ -0,0 +1,17 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 + +macro_rules! define_iso { () => { + extern crate std as iso; +}} + +::iso::thread_local! { + static S: u8 = 0; +} + +define_iso!(); + +fn main() { + let s = S; +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-cfg.rs b/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-cfg.rs new file mode 100644 index 000000000000..9249214ff8e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-cfg.rs @@ -0,0 +1,17 @@ +// build-pass (FIXME(62277): could be check-pass?) +// compile-flags:--cfg my_feature + +#![no_std] + +#[cfg(my_feature)] +extern crate std; + +mod m { + #[cfg(my_feature)] + fn conditional() { + std::vec::Vec::::new(); // OK + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-fail.rs b/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-fail.rs new file mode 100644 index 000000000000..7ba6a77b27a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-fail.rs @@ -0,0 +1,25 @@ +// ignore-tidy-linelength + +// aux-build:two_macros.rs +// compile-flags:--extern non_existent + +mod n { + extern crate two_macros; +} + +mod m { + fn check() { + two_macros::m!(); // { dg-error ".E0433." "" { target *-*-* } } + } +} + +macro_rules! define_std_as_non_existent { + () => { + extern crate std as non_existent; +// { dg-error "" "" { target *-*-* } .-1 } + } +} +define_std_as_non_existent!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-pass.rs b/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-pass.rs new file mode 100644 index 000000000000..71bc72d16c61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-pass.rs @@ -0,0 +1,13 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:two_macros.rs + +extern crate two_macros; + +mod m { + fn check() { + two_macros::m!(); // OK + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs b/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs new file mode 100644 index 000000000000..e423ed3a313e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs @@ -0,0 +1,27 @@ +// aux-build:two_macros.rs + +macro_rules! define_vec { + () => { + extern crate std as Vec; + } +} + +define_vec!(); + +mod m { + fn check() { + Vec::panic!(); // { dg-error ".E0659." "" { target *-*-* } } + } +} + +macro_rules! define_other_core { + () => { + extern crate std as core; +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +define_other_core!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-shadowing.rs b/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-shadowing.rs new file mode 100644 index 000000000000..ea68d3462662 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/extern-prelude-extern-crate-shadowing.rs @@ -0,0 +1,13 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:two_macros.rs + +extern crate two_macros as core; + +mod m { + fn check() { + core::m!(); // OK + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/gensymed.rs b/gcc/testsuite/rust/rustc/ui/imports/gensymed.rs new file mode 100644 index 000000000000..0733b50830e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/gensymed.rs @@ -0,0 +1,10 @@ +// check-pass +// edition:2018 +// aux-build:gensymed.rs + +extern crate gensymed; + +use gensymed::*; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/glob-conflict-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/imports/glob-conflict-cross-crate.rs new file mode 100644 index 000000000000..6533ba07f2a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/glob-conflict-cross-crate.rs @@ -0,0 +1,9 @@ +// aux-build:glob-conflict.rs + +extern crate glob_conflict; + +fn main() { + glob_conflict::f(); // { dg-error ".E0425." "" { target *-*-* } } + glob_conflict::glob::f(); // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/glob-shadowing.rs b/gcc/testsuite/rust/rustc/ui/imports/glob-shadowing.rs new file mode 100644 index 000000000000..abd3aa219d12 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/glob-shadowing.rs @@ -0,0 +1,35 @@ +#![feature(decl_macro)] + +mod m { + pub macro env($e: expr) { $e } + pub macro fenv() { 0 } +} + +mod glob_in_normal_module { + use m::*; + fn check() { + let x = env!("PATH"); // { dg-error ".E0659." "" { target *-*-* } } + } +} + +mod glob_in_block_module { + fn block() { + use m::*; + fn check() { + let x = env!("PATH"); // { dg-error ".E0659." "" { target *-*-* } } + } + } +} + +mod glob_shadows_item { + pub macro fenv($e: expr) { $e } + fn block() { + use m::*; + fn check() { + let x = fenv!(); // { dg-error ".E0659." "" { target *-*-* } } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/glob-use-std.rs b/gcc/testsuite/rust/rustc/ui/imports/glob-use-std.rs new file mode 100644 index 000000000000..3bec2229eb7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/glob-use-std.rs @@ -0,0 +1,12 @@ +// Issue #7580 + +// run-fail +// error-pattern:panic works +// ignore-emscripten no processes + +use std::*; + +fn main() { + panic!("panic works") +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-crate-var.rs b/gcc/testsuite/rust/rustc/ui/imports/import-crate-var.rs new file mode 100644 index 000000000000..da9e02465d9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-crate-var.rs @@ -0,0 +1,9 @@ +// aux-build:import_crate_var.rs + +#[macro_use] extern crate import_crate_var; + +fn main() { + m!(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs b/gcc/testsuite/rust/rustc/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs new file mode 100644 index 000000000000..baa1f345c973 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs @@ -0,0 +1,21 @@ +#![crate_type = "rlib"] +// no-prefer-dynamic + +// compile-flags: -g + +#[macro_use] +mod crate_with_invalid_spans_macros; + +pub fn exported_generic(x: T, y: u32) -> (T, u32) { + // Using the add1 macro will produce an invalid span, because the `y` passed + // to the macro will have a span from this file, but the rest of the code + // generated from the macro will have spans from the macro-defining file. + // The AST node for the (1 + y) expression generated by the macro will then + // take it's `lo` span bound from the `1` literal in the macro-defining file + // and it's `hi` bound from `y` in this file, which should be lower than the + // `lo` and even lower than the lower bound of the SourceFile it is supposedly + // contained in because the SourceFile for this file was allocated earlier than + // the SourceFile of the macro-defining file. + return (x, add1!(y)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs b/gcc/testsuite/rust/rustc/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs new file mode 100644 index 000000000000..ace5f229de68 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs @@ -0,0 +1,8 @@ +macro_rules! add1 { + ($e:expr) => ({ + let a = 1 + $e; + let b = $e + 1; + a + b - 1 + }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-crate-with-invalid-spans/main.rs b/gcc/testsuite/rust/rustc/ui/imports/import-crate-with-invalid-spans/main.rs new file mode 100644 index 000000000000..bee4eadc3c00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-crate-with-invalid-spans/main.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:crate_with_invalid_spans.rs + +// pretty-expanded FIXME #23616 + +extern crate crate_with_invalid_spans; + +fn main() { + // The AST of `exported_generic` stored in crate_with_invalid_spans's + // metadata should contain an invalid span where span.lo() > span.hi(). + // Let's make sure the compiler doesn't crash when encountering this. + let _ = crate_with_invalid_spans::exported_generic(32u32, 7u32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-from-missing.rs b/gcc/testsuite/rust/rustc/ui/imports/import-from-missing.rs new file mode 100644 index 000000000000..7f85d2b797df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-from-missing.rs @@ -0,0 +1,13 @@ +use spam::{ham, eggs}; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +mod spam { + pub fn ham() { } +} + +fn main() { + ham(); + // Expect eggs to pass because the compiler inserts a fake name for it + eggs(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-from.rs b/gcc/testsuite/rust/rustc/ui/imports/import-from.rs new file mode 100644 index 000000000000..8bb1e89f25c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-from.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +use spam::{ham, eggs}; + +mod spam { + pub fn ham() { } + pub fn eggs() { } +} + +pub fn main() { ham(); eggs(); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-glob-0-rpass.rs b/gcc/testsuite/rust/rustc/ui/imports/import-glob-0-rpass.rs new file mode 100644 index 000000000000..ac10879590fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-glob-0-rpass.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(dead_code)] +use module_of_many_things::*; +use dug::too::greedily::and::too::deep::*; + +mod module_of_many_things { + pub fn f1() { println!("f1"); } + pub fn f2() { println!("f2"); } + fn f3() { println!("f3"); } + pub fn f4() { println!("f4"); } +} + +mod dug { + pub mod too { + pub mod greedily { + pub mod and { + pub mod too { + pub mod deep { + pub fn nameless_fear() { println!("Boo!"); } + pub fn also_redstone() { println!("Whatever."); } + } + } + } + } + } +} + + +pub fn main() { f1(); f2(); f4(); nameless_fear(); also_redstone(); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-glob-0.rs b/gcc/testsuite/rust/rustc/ui/imports/import-glob-0.rs new file mode 100644 index 000000000000..a5f65cbd3326 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-glob-0.rs @@ -0,0 +1,17 @@ +use module_of_many_things::*; + +mod module_of_many_things { + pub fn f1() { println!("f1"); } + pub fn f2() { println!("f2"); } + fn f3() { println!("f3"); } + pub fn f4() { println!("f4"); } +} + + +fn main() { + f1(); + f2(); + f999(); // { dg-error ".E0425." "" { target *-*-* } } + f4(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-glob-1.rs b/gcc/testsuite/rust/rustc/ui/imports/import-glob-1.rs new file mode 100644 index 000000000000..ec214a4ca5d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-glob-1.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_imports)] +// This should resolve fine. Prior to fix, the last import +// was being tried too early, and marked as unrsolved before +// the glob import had a chance to be resolved. + +mod bar { + pub use self::middle::*; + + mod middle { + pub use self::baz::Baz; + + mod baz { + pub enum Baz { + Baz1, + Baz2 + } + } + } +} + +mod foo { + use bar::Baz::{Baz1, Baz2}; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-glob-circular.rs b/gcc/testsuite/rust/rustc/ui/imports/import-glob-circular.rs new file mode 100644 index 000000000000..f3854c5cba96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-glob-circular.rs @@ -0,0 +1,20 @@ +mod circ1 { + pub use circ2::f2; + pub fn f1() { println!("f1"); } + pub fn common() -> usize { return 0; } +} + +mod circ2 { + pub use circ1::f1; + pub fn f2() { println!("f2"); } + pub fn common() -> usize { return 1; } +} + +mod test { + use circ1::*; + + fn test() { f1066(); } // { dg-error ".E0425." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-glob-crate.rs b/gcc/testsuite/rust/rustc/ui/imports/import-glob-crate.rs new file mode 100644 index 000000000000..d763751092d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-glob-crate.rs @@ -0,0 +1,20 @@ +// run-pass +use std::mem::*; + +pub fn main() { + assert_eq!(size_of::(), 1); + let (mut x, mut y) = (1, 2); + swap(&mut x, &mut y); + assert_eq!(x, 2); + assert_eq!(y, 1); +} + +#[allow(unused)] +fn f() { + mod foo { pub use *; } + mod bar { pub use ::*; } + + foo::main(); + bar::main(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-in-block.rs b/gcc/testsuite/rust/rustc/ui/imports/import-in-block.rs new file mode 100644 index 000000000000..352840653112 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-in-block.rs @@ -0,0 +1,14 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + use std::mem::replace; + let mut x = 5; + let _ = replace(&mut x, 6); + { + use std::mem::*; + let mut y = 6; + swap(&mut x, &mut y); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-loop-2.rs b/gcc/testsuite/rust/rustc/ui/imports/import-loop-2.rs new file mode 100644 index 000000000000..2f04b6aae0d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-loop-2.rs @@ -0,0 +1,14 @@ +// error-pattern:import + +mod a { + pub use b::x; +} + +mod b { + pub use a::x; + + fn main() { let y = x; } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-loop.rs b/gcc/testsuite/rust/rustc/ui/imports/import-loop.rs new file mode 100644 index 000000000000..27b4da4c82a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-loop.rs @@ -0,0 +1,10 @@ +// error-pattern:import + +use y::x; + +mod y { + pub use y::x; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-prefix-macro-1.rs b/gcc/testsuite/rust/rustc/ui/imports/import-prefix-macro-1.rs new file mode 100644 index 000000000000..1dfc45bf6c7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-prefix-macro-1.rs @@ -0,0 +1,17 @@ +mod a { + pub mod b { + pub mod c { + pub struct S; + pub struct Z; + } + } +} + +macro_rules! import { + ($p: path) => (use $p {S, Z}); // { dg-error "" "" { target *-*-* } } +} + +import! { a::b::c } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-prefix-macro-2.rs b/gcc/testsuite/rust/rustc/ui/imports/import-prefix-macro-2.rs new file mode 100644 index 000000000000..8dde244176c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-prefix-macro-2.rs @@ -0,0 +1,17 @@ +mod a { + pub mod b { + pub mod c { + pub struct S; + pub struct Z; + } + } +} + +macro_rules! import { + ($p: path) => (use ::$p {S, Z}); // { dg-error "" "" { target *-*-* } } +} + +import! { a::b::c } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-prefix-macro.rs b/gcc/testsuite/rust/rustc/ui/imports/import-prefix-macro.rs new file mode 100644 index 000000000000..12de8259bf48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-prefix-macro.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(unused_variables)] +mod a { + pub mod b { + pub mod c { + pub struct S; + pub struct Z; + } + pub struct W; + } +} + +macro_rules! import { + (1 $p: path) => (use $p;); + (2 $p: path) => (use $p::{Z};); + (3 $p: path) => (use $p::*;); +} + +import! { 1 a::b::c::S } +import! { 2 a::b::c } +import! { 3 a::b } + +fn main() { + let s = S; + let z = Z; + let w = W; +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-rename.rs b/gcc/testsuite/rust/rustc/ui/imports/import-rename.rs new file mode 100644 index 000000000000..e71ffe887117 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-rename.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(unused_variables)] +use foo::{x, y as fooy}; +use Maybe::{Yes as MaybeYes}; + +pub enum Maybe { Yes, No } +mod foo { + use super::Maybe::{self as MaybeFoo}; + pub fn x(a: MaybeFoo) {} + pub fn y(a: i32) { println!("{}", a); } +} + +pub fn main() { x(MaybeYes); fooy(10); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-trailing-comma.rs b/gcc/testsuite/rust/rustc/ui/imports/import-trailing-comma.rs new file mode 100644 index 000000000000..2198cee55887 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-trailing-comma.rs @@ -0,0 +1,14 @@ +// run-pass +// pretty-expanded FIXME #23616 + +use foo::bar::{baz, quux,}; + +mod foo { + pub mod bar { + pub fn baz() { } + pub fn quux() { } + } +} + +pub fn main() { baz(); quux(); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import-trait-method.rs b/gcc/testsuite/rust/rustc/ui/imports/import-trait-method.rs new file mode 100644 index 000000000000..3fcb6cb9c397 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import-trait-method.rs @@ -0,0 +1,8 @@ +trait Foo { + fn foo(); +} + +use Foo::foo; // { dg-error ".E0253." "" { target *-*-* } } + +fn main() { foo(); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import.rs b/gcc/testsuite/rust/rustc/ui/imports/import.rs new file mode 100644 index 000000000000..02b26bec43c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import.rs @@ -0,0 +1,13 @@ +// run-pass +mod foo { + pub fn x(y: isize) { println!("{}", y); } +} + +mod bar { + use foo::x; + use foo::x as z; + pub fn thing() { x(10); z(10); } +} + +pub fn main() { bar::thing(); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import2.rs b/gcc/testsuite/rust/rustc/ui/imports/import2.rs new file mode 100644 index 000000000000..8fa64dbcb13e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import2.rs @@ -0,0 +1,10 @@ +// run-pass + +use zed::bar; + +mod zed { + pub fn bar() { println!("bar"); } +} + +pub fn main() { bar(); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import3.rs b/gcc/testsuite/rust/rustc/ui/imports/import3.rs new file mode 100644 index 000000000000..7cd03977774b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import3.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(unused_imports)] + +use baz::zed; +use baz::zed::bar; + +mod baz { + pub mod zed { + pub fn bar() { println!("bar2"); } + } +} + +pub fn main() { bar(); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import4.rs b/gcc/testsuite/rust/rustc/ui/imports/import4.rs new file mode 100644 index 000000000000..d63fd73baad0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import4.rs @@ -0,0 +1,10 @@ +// run-pass + +use zed::bar; + +mod zed { + pub fn bar() { println!("bar"); } +} + +pub fn main() { let _zed = 42; bar(); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import5.rs b/gcc/testsuite/rust/rustc/ui/imports/import5.rs new file mode 100644 index 000000000000..dd5e788d69b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import5.rs @@ -0,0 +1,11 @@ +// run-pass +use foo::bar; +mod foo { + pub use foo::zed::bar; + pub mod zed { + pub fn bar() { println!("foo"); } + } +} + +pub fn main() { bar(); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import6.rs b/gcc/testsuite/rust/rustc/ui/imports/import6.rs new file mode 100644 index 000000000000..20c570e67c72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import6.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(unused_imports)] + +use foo::zed; +use bar::baz; + +mod foo { + pub mod zed { + pub fn baz() { println!("baz"); } + } +} +mod bar { + pub use foo::zed::baz; +} +pub fn main() { baz(); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import7.rs b/gcc/testsuite/rust/rustc/ui/imports/import7.rs new file mode 100644 index 000000000000..042839a83e99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import7.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_imports)] + +use foo::zed; +use bar::baz; + +mod foo { + pub mod zed { + pub fn baz() { println!("baz"); } + } +} +mod bar { + pub use foo::zed::baz; + pub mod foo { + pub mod zed {} + } +} +pub fn main() { baz(); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/import8.rs b/gcc/testsuite/rust/rustc/ui/imports/import8.rs new file mode 100644 index 000000000000..78cc85bcf758 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/import8.rs @@ -0,0 +1,11 @@ +// run-pass + +use foo::x; +use foo::x as z; + +mod foo { + pub fn x(y: isize) { println!("{}", y); } +} + +pub fn main() { x(10); z(10); } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/imports.rs b/gcc/testsuite/rust/rustc/ui/imports/imports.rs new file mode 100644 index 000000000000..a86e1814eee0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/imports.rs @@ -0,0 +1,67 @@ +// run-pass +#![allow(unused)] + +// Like other items, private imports can be imported and used non-lexically in paths. +mod a { + use a as foo; + use self::foo::foo as bar; + + mod b { + use super::bar; + } +} + +mod foo { pub fn f() {} } +mod bar { pub fn f() {} } + +pub fn f() -> bool { true } + +// Items and explicit imports shadow globs. +fn g() { + use foo::*; + use bar::*; + fn f() -> bool { true } + let _: bool = f(); +} + +fn h() { + use foo::*; + use bar::*; + use f; + let _: bool = f(); +} + +// Here, there appears to be shadowing but isn't because of namespaces. +mod b { + use foo::*; // This imports `f` in the value namespace. + use super::b as f; // This imports `f` only in the type namespace, + fn test() { self::f(); } // so the glob isn't shadowed. +} + +// Here, there is shadowing in one namespace, but not the other. +mod c { + mod test { + pub fn f() {} + pub mod f {} + } + use self::test::*; // This glob-imports `f` in both namespaces. + mod f { pub fn f() {} } // This shadows the glob only in the value namespace. + + fn test() { + self::f(); // Check that the glob-imported value isn't shadowed. + self::f::f(); // Check that the glob-imported module is shadowed. + } +} + +// Unused names can be ambiguous. +mod d { + pub use foo::*; // This imports `f` in the value namespace. + pub use bar::*; // This also imports `f` in the value namespace. +} + +mod e { + pub use d::*; // n.b. Since `e::f` is not used, this is not considered to be a use of `d::f`. +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/issue-53140.rs b/gcc/testsuite/rust/rustc/ui/imports/issue-53140.rs new file mode 100644 index 000000000000..e0e9a1314105 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/issue-53140.rs @@ -0,0 +1,12 @@ +// check-pass + +mod m { + pub struct S(u8); + + use S as Z; +} + +use m::*; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/issue-53269.rs b/gcc/testsuite/rust/rustc/ui/imports/issue-53269.rs new file mode 100644 index 000000000000..0bcf46e711aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/issue-53269.rs @@ -0,0 +1,12 @@ +// Ambiguity between a `macro_rules` macro and a non-existent import recovered as `Res::Err` + +macro_rules! mac { () => () } + +mod m { + use nonexistent_module::mac; // { dg-error ".E0432." "" { target *-*-* } } + + mac!(); // { dg-error ".E0659." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/issue-53512.rs b/gcc/testsuite/rust/rustc/ui/imports/issue-53512.rs new file mode 100644 index 000000000000..ac502afcd071 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/issue-53512.rs @@ -0,0 +1,9 @@ +// Macro from prelude is shadowed by non-existent import recovered as `Res::Err`. + +mod m {} +use m::assert; // { dg-error ".E0432." "" { target *-*-* } } + +fn main() { + assert!(true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/issue-55457.rs b/gcc/testsuite/rust/rustc/ui/imports/issue-55457.rs new file mode 100644 index 000000000000..954a09234359 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/issue-55457.rs @@ -0,0 +1,11 @@ +use NonExistent; // { dg-error ".E0432." "" { target *-*-* } } +use non_existent::non_existent; // { dg-error ".E0432." "" { target *-*-* } } + +#[non_existent] // { dg-error "" "" { target *-*-* } } +#[derive(NonExistent)] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +struct S; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/issue-55811.rs b/gcc/testsuite/rust/rustc/ui/imports/issue-55811.rs new file mode 100644 index 000000000000..a92b5eb66c40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/issue-55811.rs @@ -0,0 +1,7 @@ +// check-pass +// aux-build:issue-55811.rs + +extern crate issue_55811; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/issue-55884-1.rs b/gcc/testsuite/rust/rustc/ui/imports/issue-55884-1.rs new file mode 100644 index 000000000000..071a0d6b9ec2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/issue-55884-1.rs @@ -0,0 +1,22 @@ +mod m { + mod m1 { + pub struct S {} + } + mod m2 { + // Note this derive, it makes this struct macro-expanded, + // so it doesn't appear in time to participate in the initial resolution of `use m::S`, + // only in the later validation pass. + #[derive(Default)] + pub struct S {} + } + + // Create a glob vs glob ambiguity + pub use self::m1::*; + pub use self::m2::*; +} + +fn main() { + use m::S; // { dg-error ".E0659." "" { target *-*-* } } + let s = S {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/issue-55884-2.rs b/gcc/testsuite/rust/rustc/ui/imports/issue-55884-2.rs new file mode 100644 index 000000000000..12360c463002 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/issue-55884-2.rs @@ -0,0 +1,15 @@ +mod options { + pub struct ParseOptions {} +} + +mod parser { + pub use options::*; + // Private single import shadows public glob import, but arrives too late for initial + // resolution of `use parser::ParseOptions` because it depends on that resolution itself. + use ParseOptions; +} + +pub use parser::ParseOptions; // { dg-error ".E0603." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/issue-56125.rs b/gcc/testsuite/rust/rustc/ui/imports/issue-56125.rs new file mode 100644 index 000000000000..9ce00c6aa2c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/issue-56125.rs @@ -0,0 +1,22 @@ +// edition:2018 +// compile-flags:--extern issue_56125 +// aux-build:issue-56125.rs + +mod m1 { + use issue_56125::last_segment::*; +// { dg-error ".E0659." "" { target *-*-* } .-1 } +} + +mod m2 { + use issue_56125::non_last_segment::non_last_segment::*; +// { dg-error ".E0659." "" { target *-*-* } .-1 } +} + +mod m3 { + mod empty {} + use empty::issue_56125; // { dg-error ".E0432." "" { target *-*-* } } + use issue_56125::*; // { dg-error ".E0659." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/issue-56263.rs b/gcc/testsuite/rust/rustc/ui/imports/issue-56263.rs new file mode 100644 index 000000000000..30c105e8ea13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/issue-56263.rs @@ -0,0 +1,9 @@ +// check-pass +// edition:2018 + +use ::std; + +fn main() { + let std = 10; +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/issue-57015.rs b/gcc/testsuite/rust/rustc/ui/imports/issue-57015.rs new file mode 100644 index 000000000000..4629ce71aad7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/issue-57015.rs @@ -0,0 +1,14 @@ +mod glob_ok { + pub mod something { + pub mod something_else {} + } +} + +mod single_err {} + +use glob_ok::*; // glob_ok::something +use single_err::something; // { dg-error ".E0432." "" { target *-*-* } } +use something::something_else; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/issue-57539.rs b/gcc/testsuite/rust/rustc/ui/imports/issue-57539.rs new file mode 100644 index 000000000000..e3cf5213bacd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/issue-57539.rs @@ -0,0 +1,9 @@ +// edition:2018 + +mod core { + use core; // { dg-error ".E0659." "" { target *-*-* } } + use crate::*; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/issue-62767.rs b/gcc/testsuite/rust/rustc/ui/imports/issue-62767.rs new file mode 100644 index 000000000000..71ac9b2db9d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/issue-62767.rs @@ -0,0 +1,31 @@ +// check-pass + +// Minimized case from #62767. +mod m { + pub enum Same { + Same, + } +} + +use m::*; + +// The variant `Same` introduced by this import is also considered when resolving the prefix +// `Same::` during import validation to avoid effects similar to time travel (#74556). +use Same::Same; + +// Case from #74556. +mod foo { + pub mod bar { + pub mod bar { + pub fn foobar() {} + } + } +} + +use foo::*; +use bar::bar; + +use bar::foobar; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-fail-1.rs b/gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-fail-1.rs new file mode 100644 index 000000000000..a5fd0ab8b267 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-fail-1.rs @@ -0,0 +1,48 @@ +#![feature(decl_macro)] + +macro_rules! define_exported { () => { + #[macro_export] + macro_rules! exported { + () => () + } +}} +macro_rules! define_panic { () => { + #[macro_export] + macro_rules! panic { + () => () + } +}} +macro_rules! define_include { () => { + #[macro_export] + macro_rules! include { + () => () + } +}} + +use inner1::*; + +mod inner1 { + pub macro exported() {} +} + +exported!(); // { dg-error ".E0659." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + +mod inner2 { + define_exported!(); +} + +fn main() { + panic!(); // { dg-error ".E0659." "" { target *-*-* } } +} + +mod inner3 { + define_panic!(); +} + +mod inner4 { + define_include!(); +} + +include!(); // { dg-error ".E0659." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-fail-2.rs b/gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-fail-2.rs new file mode 100644 index 000000000000..535eabc78039 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-fail-2.rs @@ -0,0 +1,49 @@ +// `#[macro_export] macro_rules` that doesn't originate from macro expansions can be placed +// into the root module soon enough to act as usual items and shadow globs and preludes. + +#![feature(decl_macro)] + +// `macro_export` shadows globs +use inner1::*; + +mod inner1 { + pub macro exported() {} +} + +exported!(); + +mod deep { + fn deep() { + type Deeper = [u8; { + #[macro_export] + macro_rules! exported { + () => ( struct Б; ) // { dg-error ".E0658." "" { target *-*-* } } + } + + 0 + }]; + } +} + +// `macro_export` shadows std prelude +fn main() { + panic!(); +} + +mod inner3 { + #[macro_export] + macro_rules! panic { + () => ( struct Г; ) // { dg-error ".E0658." "" { target *-*-* } } + } +} + +// `macro_export` shadows builtin macros +include!(); + +mod inner4 { + #[macro_export] + macro_rules! include { + () => ( struct Д; ) // { dg-error ".E0658." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-fail-3.rs b/gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-fail-3.rs new file mode 100644 index 000000000000..971c66a1b1ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-fail-3.rs @@ -0,0 +1,23 @@ +// Crate-local macro expanded `macro_export` macros cannot be accessed with module-relative paths. + +macro_rules! define_exported { () => { + #[macro_export] + macro_rules! exported { + () => () + } +}} + +define_exported!(); + +mod m { + use exported; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() { + ::exported!(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-pass.rs b/gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-pass.rs new file mode 100644 index 000000000000..ddba890a8047 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/local-modularized-tricky-pass.rs @@ -0,0 +1,20 @@ +// build-pass (FIXME(62277): could be check-pass?) + +macro_rules! define_exported { () => { + #[macro_export] + macro_rules! exported { + () => () + } +}} + +mod inner1 { + use super::*; + exported!(); +} + +mod inner2 { + define_exported!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/local-modularized.rs b/gcc/testsuite/rust/rustc/ui/imports/local-modularized.rs new file mode 100644 index 000000000000..c393775c348c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/local-modularized.rs @@ -0,0 +1,36 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#[macro_export(local_inner_macros)] +macro_rules! dollar_crate_exported { + (1) => { $crate::exported!(); }; + (2) => { exported!(); }; +} + +// Before `exported` is defined +exported!(); + +mod inner { + + ::exported!(); + crate::exported!(); + dollar_crate_exported!(1); + dollar_crate_exported!(2); + + mod inner_inner { + #[macro_export] + macro_rules! exported { + () => () + } + } + + // After `exported` is defined + ::exported!(); + crate::exported!(); + dollar_crate_exported!(1); + dollar_crate_exported!(2); +} + +exported!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/macro-paths.rs b/gcc/testsuite/rust/rustc/ui/imports/macro-paths.rs new file mode 100644 index 000000000000..5b7643d0f707 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/macro-paths.rs @@ -0,0 +1,29 @@ +// aux-build:two_macros.rs + +extern crate two_macros; + +mod foo { + pub mod bar { + pub use two_macros::m; + } +} + +fn f() { + use foo::*; + bar::m! { // { dg-error ".E0659." "" { target *-*-* } } + mod bar { pub use two_macros::m; } + } +} + +pub mod baz { + pub use two_macros::m; +} + +fn g() { + baz::m! { // { dg-error ".E0659." "" { target *-*-* } } + mod baz { pub use two_macros::m; } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/macros.rs b/gcc/testsuite/rust/rustc/ui/imports/macros.rs new file mode 100644 index 000000000000..f12b865c159e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/macros.rs @@ -0,0 +1,43 @@ +// aux-build:two_macros.rs + +extern crate two_macros; // two identity macros `m` and `n` + +mod foo { + pub use two_macros::n as m; +} + +mod m1 { + m!(use two_macros::*;); + use foo::m; // This shadows the glob import +} + +mod m2 { + use two_macros::*; + m! { // { dg-error ".E0659." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + use foo::m; + } +} + +mod m3 { + use two_macros::m; + fn f() { + use two_macros::n as m; // This shadows the above import + m!(); + } + + fn g() { + m! { // { dg-error ".E0659." "" { target *-*-* } } + use two_macros::n as m; + } + } +} + +mod m4 { + macro_rules! m { () => {} } + use two_macros::m; + m!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/reexports.rs b/gcc/testsuite/rust/rustc/ui/imports/reexports.rs new file mode 100644 index 000000000000..8b1a79f6f53f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/reexports.rs @@ -0,0 +1,38 @@ +#![warn(unused_imports)] + +mod a { + fn foo() {} + mod foo {} + + mod a { + pub use super::foo; // { dg-error ".E0364." "" { target *-*-* } } + pub use super::*; +// { dg-warning "" "" { target *-*-* } .-1 } + } +} + +mod b { + pub fn foo() {} + mod foo { + pub struct S; + } + + pub mod a { + pub use super::foo; // This is OK since the value `foo` is visible enough. + fn f(_: foo::S) {} // `foo` is imported in the type namespace (but not `pub` re-exported). + } + + pub mod b { + pub use super::*; // This is also OK since the value `foo` is visible enough. + fn f(_: foo::S) {} // Again, the module `foo` is imported (but not `pub` re-exported). + } +} + +mod c { + // Test that `foo` is not re-exported. + use b::a::foo::S; // { dg-error ".E0603." "" { target *-*-* } } + use b::b::foo::S as T; // { dg-error ".E0603." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/rfc-1560-warning-cycle.rs b/gcc/testsuite/rust/rustc/ui/imports/rfc-1560-warning-cycle.rs new file mode 100644 index 000000000000..5b6ad6a6cdc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/rfc-1560-warning-cycle.rs @@ -0,0 +1,14 @@ +pub struct Foo; + +mod bar { + struct Foo; + + mod baz { + use *; + use bar::*; + fn f(_: Foo) {} // { dg-error ".E0659." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/shadow_builtin_macros.rs b/gcc/testsuite/rust/rustc/ui/imports/shadow_builtin_macros.rs new file mode 100644 index 000000000000..ec113b6c058a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/shadow_builtin_macros.rs @@ -0,0 +1,53 @@ +// aux-build:two_macros.rs + +mod foo { + extern crate two_macros; + pub use self::two_macros::m as panic; +} + +mod m1 { + use foo::panic; // ok + fn f() { panic!(); } +} + +mod m2 { + use foo::*; + fn f() { panic!(); } // { dg-error ".E0659." "" { target *-*-* } } +} + +mod m3 { + ::two_macros::m!(use foo::panic;); + fn f() { panic!(); } // { dg-error ".E0659." "" { target *-*-* } } +} + +mod m4 { + macro_rules! panic { () => {} } // ok + panic!(); +} + +mod m5 { + macro_rules! m { () => { + macro_rules! panic { () => {} } + } } + m!(); + panic!(); // { dg-error ".E0659." "" { target *-*-* } } +} + +#[macro_use(n)] +extern crate two_macros; +mod bar { + pub use two_macros::m as n; +} + +mod m6 { + use bar::n; // ok + n!(); +} + +mod m7 { + use bar::*; + n!(); // { dg-error ".E0659." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/unresolved-imports-used.rs b/gcc/testsuite/rust/rustc/ui/imports/unresolved-imports-used.rs new file mode 100644 index 000000000000..c7b0eec56f09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/unresolved-imports-used.rs @@ -0,0 +1,19 @@ +// There should be *one* unused import error. +#![deny(unused_imports)] + +mod qux { + fn quz() {} + pub fn quy() {} +} + +use qux::quz; // { dg-error ".E0603." "" { target *-*-* } } +use qux::bar; // { dg-error ".E0432." "" { target *-*-* } } +use foo::bar; // { dg-error ".E0432." "" { target *-*-* } } +use baz::*; // { dg-error ".E0432." "" { target *-*-* } } +use qux::bar2; // { dg-error ".E0432." "" { target *-*-* } } +use foo2::bar2;// { dg-error ".E0432." "" { target *-*-* } } +use baz2::*; // { dg-error ".E0432." "" { target *-*-* } } +use qux::quy; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/unused-macro-use.rs b/gcc/testsuite/rust/rustc/ui/imports/unused-macro-use.rs new file mode 100644 index 000000000000..87a7d52ebeae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/unused-macro-use.rs @@ -0,0 +1,12 @@ +#![deny(unused)] + +#[macro_use] // { dg-error "" "" { target *-*-* } } +extern crate core; + +#[macro_use( + panic // { dg-error "" "" { target *-*-* } } +)] +extern crate core as core_2; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/imports/unused.rs b/gcc/testsuite/rust/rustc/ui/imports/unused.rs new file mode 100644 index 000000000000..d099a2c836e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/imports/unused.rs @@ -0,0 +1,28 @@ +#![deny(unused)] + +mod foo { + fn f() {} + + mod m1 { + pub(super) use super::f; // { dg-error "" "" { target *-*-* } } + } + + mod m2 { + #[allow(unused)] + use super::m1::*; // (despite this glob import) + } + + mod m3 { + pub(super) use super::f; // Check that this is counted as used (cf. issue #36249). + } + + pub mod m4 { + use super::m3::*; + pub fn g() { f(); } + } +} + +fn main() { + foo::m4::g(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/impossible_range.rs b/gcc/testsuite/rust/rustc/ui/impossible_range.rs new file mode 100644 index 000000000000..116a8af63d42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/impossible_range.rs @@ -0,0 +1,21 @@ +// run-rustfix +// Make sure that invalid ranges generate an error during parsing, not an ICE + +#![allow(path_statements)] + +pub fn main() { + ..; + 0..; + ..1; + 0..1; + ..=; // { dg-error ".E0586." "" { target *-*-* } } +// { help ".E0586." "" { target *-*-* } .-1 } +} + +fn _foo1() { + ..=1; + 0..=1; + 0..=; // { dg-error ".E0586." "" { target *-*-* } } +// { help ".E0586." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes.rs new file mode 100644 index 000000000000..8a0cb2bcab3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes.rs @@ -0,0 +1,97 @@ +// run-pass + +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +fn foo(x: &'x u8) -> &'x u8 { x } +fn foo2(x: &'a u8, y: &u8) -> &'a u8 { x } + +fn check_in_band_can_be_late_bound() { + let _: for<'x> fn(&'x u8, &u8) -> &'x u8 = foo2; +} + +struct ForInherentNoParams; + +impl ForInherentNoParams { + fn foo(x: &'a u32, y: &u32) -> &'a u32 { x } +} + +struct X<'a>(&'a u8); + +impl<'a> X<'a> { + fn inner(&self) -> &'a u8 { + self.0 + } + + fn same_lifetime_as_parameter(&mut self, x: &'a u8) { + self.0 = x; + } +} + +impl X<'b> { + fn inner_2(&self) -> &'b u8 { + self.0 + } + + fn reference_already_introduced_in_band_from_method_with_explicit_binders<'a>( + &'b self, x: &'a u32 + ) {} +} + +struct Y(T); + +impl Y<&'a u8> { + fn inner(&self) -> &'a u8 { + self.0 + } +} + +trait MyTrait<'a> { + fn my_lifetime(&self) -> &'a u8; + fn any_lifetime() -> &'b u8; + fn borrowed_lifetime(&'b self) -> &'b u8; + fn default_impl(&self, x: &'b u32, y: &u32) -> &'b u32 { x } + fn in_band_def_explicit_impl(&self, x: &'b u8); +} + +impl MyTrait<'a> for Y<&'a u8> { + fn my_lifetime(&self) -> &'a u8 { self.0 } + fn any_lifetime() -> &'b u8 { &0 } + fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 } + fn in_band_def_explicit_impl<'b>(&self, x: &'b u8) {} +} + +fn test_hrtb_defined_lifetime_where(_: F) where for<'a> F: Fn(&'a u8) {} +fn test_hrtb_defined_lifetime_polytraitref(_: F) where F: for<'a> Fn(&'a u8) {} + +fn reference_in_band_from_locals(x: &'test u32) -> &'test u32 { + let y: &'test u32 = x; + y +} + +fn in_generics_in_band>(x: &T) {} +fn where_clause_in_band(x: &T) where T: MyTrait<'a> {} +fn impl_trait_in_band(x: &impl MyTrait<'a>) {} + +// Tests around using in-band lifetimes within existential traits. + +trait FunkyTrait<'a> { } +impl<'a, T> FunkyTrait<'a> for T { } +fn ret_pos_impl_trait_in_band_outlives(x: &'a u32) -> impl ::std::fmt::Debug + 'a { + x +} +fn ret_pos_impl_trait_in_band_param(x: &'a u32) -> impl FunkyTrait<'a> { + x +} +fn ret_pos_impl_trait_in_band_param_static(x: &'a u32) -> impl FunkyTrait<'static> + 'a { + x +} +fn ret_pos_impl_trait_in_band_param_outlives(x: &'a u32) -> impl FunkyTrait<'a> + 'a { + x +} +fn ret_pos_impl_trait_in_band_higher_ranked(x: &'a u32) -> impl for<'b> FunkyTrait<'b> + 'a { + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/E0687.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/E0687.rs new file mode 100644 index 000000000000..863588962a96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/E0687.rs @@ -0,0 +1,17 @@ +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +fn foo(x: fn(&'a u32)) {} // { dg-error ".E0687." "" { target *-*-* } } + +fn bar(x: &Fn(&'a u32)) {} // { dg-error ".E0687." "" { target *-*-* } } + +fn baz(x: fn(&'a u32), y: &'a u32) {} // { dg-error ".E0687." "" { target *-*-* } } + +struct Foo<'a> { x: &'a u32 } + +impl Foo<'a> { + fn bar(&self, x: fn(&'a u32)) {} // { dg-error ".E0687." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/E0687_where.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/E0687_where.rs new file mode 100644 index 000000000000..e3b15197e8e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/E0687_where.rs @@ -0,0 +1,9 @@ +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +fn bar(x: &F) where F: Fn(&'a u32) {} // { dg-error ".E0687." "" { target *-*-* } } + +fn baz(x: &impl Fn(&'a u32)) {} // { dg-error ".E0687." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/E0688.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/E0688.rs new file mode 100644 index 000000000000..0a8d1d22e972 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/E0688.rs @@ -0,0 +1,17 @@ +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +fn foo<'a>(x: &'a u32, y: &'b u32) {} // { dg-error ".E0688." "" { target *-*-* } } + +struct Foo<'a> { x: &'a u32 } + +impl Foo<'a> { + fn bar<'b>(x: &'a u32, y: &'b u32, z: &'c u32) {} // { dg-error ".E0688." "" { target *-*-* } } +} + +impl<'b> Foo<'a> { // { dg-error ".E0688." "" { target *-*-* } } + fn baz() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/elided-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/elided-lifetimes.rs new file mode 100644 index 000000000000..dfe9a17de7a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/elided-lifetimes.rs @@ -0,0 +1,88 @@ +// run-rustfix +// edition:2018 + +#![allow(unused)] +#![deny(elided_lifetimes_in_paths)] +// { dg-note "" "" { target *-*-* } .-1 } + +use std::cell::{RefCell, Ref}; + + +struct Foo<'a> { x: &'a u32 } + +fn foo(x: &Foo) { +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +} + +fn bar(x: &Foo<'_>) {} + + +struct Wrapped<'a>(&'a str); + +struct WrappedWithBow<'a> { + gift: &'a str +} + +struct MatchedSet<'a, 'b> { + one: &'a str, + another: &'b str, +} + +fn wrap_gift(gift: &str) -> Wrapped { +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + Wrapped(gift) +} + +fn wrap_gift_with_bow(gift: &str) -> WrappedWithBow { +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + WrappedWithBow { gift } +} + +fn inspect_matched_set(set: MatchedSet) { +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + println!("{} {}", set.one, set.another); +} + +macro_rules! autowrapper { + ($type_name:ident, $fn_name:ident, $lt:lifetime) => { + struct $type_name<$lt> { + gift: &$lt str + } + + fn $fn_name(gift: &str) -> $type_name { +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + $type_name { gift } + } + } +} + +autowrapper!(Autowrapped, autowrap_gift, 'a); +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + +macro_rules! anytuple_ref_ty { + ($($types:ty),*) => { + Ref<($($types),*)> +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + } +} + +fn main() { + let honesty = RefCell::new((4, 'e')); + let loyalty: Ref<(u32, char)> = honesty.borrow(); +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + let generosity = Ref::map(loyalty, |t| &t.0); + + let laughter = RefCell::new((true, "magic")); + let yellow: anytuple_ref_ty!(bool, &str) = laughter.borrow(); +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.rs new file mode 100644 index 000000000000..f013ad11eb8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/issue-61124-anon-lifetime-in-struct-declaration.rs @@ -0,0 +1,11 @@ +#![deny(elided_lifetimes_in_paths)] + +// Previously, the elided-lifetimes-in-path lint would fire, but we don't want +// that, because `'_` isn't legal in struct declarations. + +struct Betrayal<'a> { x: &'a u8 } + +struct Heartbreak(Betrayal); // { dg-error ".E0106." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched.rs new file mode 100644 index 000000000000..3a9c7d3888d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched.rs @@ -0,0 +1,9 @@ +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +fn foo(x: &'a u32, y: &u32) -> &'a u32 { y } // { dg-error ".E0621." "" { target *-*-* } } + +fn foo2(x: &'a u32, y: &'b u32) -> &'a u32 { y } // { dg-error ".E0623." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched_trait.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched_trait.rs new file mode 100644 index 000000000000..9aa3f8c8aa42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched_trait.rs @@ -0,0 +1,11 @@ +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +trait Get { + fn baz(&self, x: &'a u32, y: &u32) -> &'a u32 { + y // { dg-error ".E0621." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched_trait_impl-2.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched_trait_impl-2.rs new file mode 100644 index 000000000000..ae0dafce2b3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched_trait_impl-2.rs @@ -0,0 +1,15 @@ +use std::ops::Deref; +trait Trait {} + +struct Struct; + +impl Deref for Struct { + type Target = dyn Trait; + fn deref(&self) -> &dyn Trait { +// { dg-error "" "" { target *-*-* } .-1 } + unimplemented!(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched_trait_impl.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched_trait_impl.rs new file mode 100644 index 000000000000..9feaf08223f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mismatched_trait_impl.rs @@ -0,0 +1,15 @@ +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +trait Get { + fn foo(&self, x: &'a u32, y: &u32) -> &'a u32; +} + +impl Get for i32 { + fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { // { dg-error "" "" { target *-*-* } } + x // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mut_while_borrow.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mut_while_borrow.rs new file mode 100644 index 000000000000..4b98f31c5060 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/mut_while_borrow.rs @@ -0,0 +1,12 @@ +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +fn foo(x: &'a u32) -> &'a u32 { x } + +fn main() { + let mut p = 3; + let r = foo(&p); + p += 1; // { dg-error ".E0506." "" { target *-*-* } } + println!("{}", r); +} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/nested-items.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/nested-items.rs new file mode 100644 index 000000000000..08c737b7a71f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/nested-items.rs @@ -0,0 +1,21 @@ +// Test that the `'a` from the impl doesn't +// prevent us from creating a `'a` parameter +// on the `blah` function. +// +// check-pass + +#![feature(in_band_lifetimes)] + +struct Foo<'a> { + x: &'a u32 + +} + +impl Foo<'a> { + fn method(&self) { + fn blah(f: Foo<'a>) { } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/no_in_band_in_struct.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/no_in_band_in_struct.rs new file mode 100644 index 000000000000..da4370e8c9dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/no_in_band_in_struct.rs @@ -0,0 +1,13 @@ +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +struct Foo { + x: &'test u32, // { dg-error ".E0261." "" { target *-*-* } } +} + +enum Bar { + Baz(&'test u32), // { dg-error ".E0261." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/no_introducing_in_band_in_locals.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/no_introducing_in_band_in_locals.rs new file mode 100644 index 000000000000..4c34128fd05e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/no_introducing_in_band_in_locals.rs @@ -0,0 +1,14 @@ +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +fn foo(x: &u32) { + let y: &'test u32 = x; // { dg-error ".E0261." "" { target *-*-* } } +} + +fn foo2(x: &u32) {} +fn bar() { + let y: fn(&'test u32) = foo2; // { dg-error ".E0261." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/shadow.rs b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/shadow.rs new file mode 100644 index 000000000000..41bfd3411c02 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/in-band-lifetimes/shadow.rs @@ -0,0 +1,12 @@ +#![allow(warnings)] +#![feature(in_band_lifetimes)] + +struct Foo(T); + +impl Foo<&'s u8> { + fn bar<'s>(&self, x: &'s u8) {} // { dg-error ".E0496." "" { target *-*-* } } + fn baz(x: for<'s> fn(&'s u32)) {} // { dg-error ".E0496." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/inc-range-pat.rs b/gcc/testsuite/rust/rustc/ui/inc-range-pat.rs new file mode 100644 index 000000000000..3cedf4ae0932 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inc-range-pat.rs @@ -0,0 +1,13 @@ +// run-pass +// Test old and new syntax for inclusive range patterns. + +#![allow(ellipsis_inclusive_range_patterns)] + +fn main() { + assert!(match 42 { 0 ... 100 => true, _ => false }); + assert!(match 42 { 0 ..= 100 => true, _ => false }); + + assert!(match 'x' { 'a' ... 'z' => true, _ => false }); + assert!(match 'x' { 'a' ..= 'z' => true, _ => false }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/include-macros/mismatched-types.rs b/gcc/testsuite/rust/rustc/ui/include-macros/mismatched-types.rs new file mode 100644 index 000000000000..eef8e8d4ebfb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/include-macros/mismatched-types.rs @@ -0,0 +1,5 @@ +fn main() { + let b: &[u8] = include_str!("file.txt"); // { dg-error ".E0308." "" { target *-*-* } } + let s: &str = include_bytes!("file.txt"); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/include-macros/normalization.rs b/gcc/testsuite/rust/rustc/ui/include-macros/normalization.rs new file mode 100644 index 000000000000..838bbacc90a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/include-macros/normalization.rs @@ -0,0 +1,13 @@ +// run-pass + +fn main() { + assert_eq!( + &include_bytes!("data.bin")[..], + &b"\xEF\xBB\xBFThis file starts with BOM.\r\nLines are separated by \\r\\n.\r\n"[..], + ); + assert_eq!( + include_str!("data.bin"), + "\u{FEFF}This file starts with BOM.\r\nLines are separated by \\r\\n.\r\n", + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/include-single-expr-helper-1.rs b/gcc/testsuite/rust/rustc/ui/include-single-expr-helper-1.rs new file mode 100644 index 000000000000..5c625a2a54be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/include-single-expr-helper-1.rs @@ -0,0 +1,6 @@ +// ignore-test auxiliary file for include-single-expr.rs + +0 + +// trailing comment permitted + diff --git a/gcc/testsuite/rust/rustc/ui/include-single-expr-helper.rs b/gcc/testsuite/rust/rustc/ui/include-single-expr-helper.rs new file mode 100644 index 000000000000..641aa87f81d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/include-single-expr-helper.rs @@ -0,0 +1,6 @@ +// ignore-test auxiliary file for include-single-expr.rs + +0 +10 +100 + diff --git a/gcc/testsuite/rust/rustc/ui/include-single-expr.rs b/gcc/testsuite/rust/rustc/ui/include-single-expr.rs new file mode 100644 index 000000000000..680a7378d75e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/include-single-expr.rs @@ -0,0 +1,7 @@ +// error-pattern include macro expected single expression + +fn main() { + include!("include-single-expr-helper.rs"); + include!("include-single-expr-helper-1.rs"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/index-bot.rs b/gcc/testsuite/rust/rustc/ui/index-bot.rs new file mode 100644 index 000000000000..403299c6e653 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/index-bot.rs @@ -0,0 +1,4 @@ +fn main() { + (return)[0]; // { dg-error ".E0608." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/index-help.rs b/gcc/testsuite/rust/rustc/ui/index-help.rs new file mode 100644 index 000000000000..8dfa4d6bc1e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/index-help.rs @@ -0,0 +1,5 @@ +fn main() { + let x = vec![1]; + x[0i32]; // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/index_message.rs b/gcc/testsuite/rust/rustc/ui/index_message.rs new file mode 100644 index 000000000000..f4b43176ae5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/index_message.rs @@ -0,0 +1,5 @@ +fn main() { + let z = (); + let _ = z[0]; // { dg-error ".E0608." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/indexing-requires-a-uint.rs b/gcc/testsuite/rust/rustc/ui/indexing-requires-a-uint.rs new file mode 100644 index 000000000000..0823b381abf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/indexing-requires-a-uint.rs @@ -0,0 +1,15 @@ +// Make sure that indexing an array is only valid with a `usize`, not any other +// integral type. + +fn main() { + fn bar(_: T) {} + [0][0u8]; // { dg-error ".E0277." "" { target *-*-* } } + + [0][0]; // should infer to be a usize + + let i = 0; // i is an IntVar + [0][i]; // i should be locked to usize + bar::(i); // i should not be re-coerced back to an isize +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/infer-fn-tail-expr.rs b/gcc/testsuite/rust/rustc/ui/infer-fn-tail-expr.rs new file mode 100644 index 000000000000..052b297c3aeb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/infer-fn-tail-expr.rs @@ -0,0 +1,12 @@ +// run-pass + +#![allow(dead_code)] +// issue #680 + + +// pretty-expanded FIXME #23616 + +fn f() -> Vec { Vec::new() } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/inference/auxiliary/inference_unstable_iterator.rs b/gcc/testsuite/rust/rustc/ui/inference/auxiliary/inference_unstable_iterator.rs new file mode 100644 index 000000000000..7ce496a759c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inference/auxiliary/inference_unstable_iterator.rs @@ -0,0 +1,15 @@ +#![feature(staged_api)] + +#![stable(feature = "ipu_iterator", since = "1.0.0")] + +#[stable(feature = "ipu_iterator", since = "1.0.0")] +pub trait IpuIterator { + #[unstable(feature = "ipu_flatten", issue = "99999")] + fn ipu_flatten(&self) -> u32 { + 0 + } +} + +#[stable(feature = "ipu_iterator", since = "1.0.0")] +impl IpuIterator for char {} + diff --git a/gcc/testsuite/rust/rustc/ui/inference/auxiliary/inference_unstable_itertools.rs b/gcc/testsuite/rust/rustc/ui/inference/auxiliary/inference_unstable_itertools.rs new file mode 100644 index 000000000000..6ad27cb7ee84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inference/auxiliary/inference_unstable_itertools.rs @@ -0,0 +1,8 @@ +pub trait IpuItertools { + fn ipu_flatten(&self) -> u32 { + 1 + } +} + +impl IpuItertools for char {} + diff --git a/gcc/testsuite/rust/rustc/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs b/gcc/testsuite/rust/rustc/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs new file mode 100644 index 000000000000..044273bb6504 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs @@ -0,0 +1,18 @@ +// edition:2018 +#![feature(impl_trait_in_bindings)] +// { dg-warning "" "" { target *-*-* } .-1 } + +use std::io::Error; + +fn make_unit() -> Result<(), Error> { + Ok(()) +} + +fn main() { + let fut = async { + make_unit()?; // { dg-error ".E0282." "" { target *-*-* } } + + Ok(()) + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/inference/cannot-infer-async.rs b/gcc/testsuite/rust/rustc/ui/inference/cannot-infer-async.rs new file mode 100644 index 000000000000..6e6e74d64fa2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inference/cannot-infer-async.rs @@ -0,0 +1,16 @@ +// edition:2018 + +use std::io::Error; + +fn make_unit() -> Result<(), Error> { + Ok(()) +} + +fn main() { + let fut = async { + make_unit()?; // { dg-error ".E0282." "" { target *-*-* } } + + Ok(()) + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/inference/cannot-infer-closure.rs b/gcc/testsuite/rust/rustc/ui/inference/cannot-infer-closure.rs new file mode 100644 index 000000000000..4f2f2adbc4ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inference/cannot-infer-closure.rs @@ -0,0 +1,7 @@ +fn main() { + let x = |a: (), b: ()| { + Err(a)?; // { dg-error ".E0282." "" { target *-*-* } } + Ok(b) + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/inference/infer-binary-operand-behind-reference.rs b/gcc/testsuite/rust/rustc/ui/inference/infer-binary-operand-behind-reference.rs new file mode 100644 index 000000000000..004c3db5517a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inference/infer-binary-operand-behind-reference.rs @@ -0,0 +1,31 @@ +// check-pass + +fn main() { + // Test that we can infer the type of binary operands when + // references are involved, on various types and operators. + let _: u8 = 0 + 0; + let _: u8 = 0 + &0; + let _: u8 = &0 + 0; + let _: u8 = &0 + &0; + + let _: f32 = 0.0 + 0.0; + let _: f32 = 0.0 + &0.0; + let _: f32 = &0.0 + 0.0; + let _: f32 = &0.0 + &0.0; + + let _: u8 = 0 << 0; + let _: u8 = 0 << &0; + let _: u8 = &0 << 0; + let _: u8 = &0 << &0; + + // Test type inference when variable types are indirectly inferred. + let a = 22; + let _: usize = a + &44; + + // When we have no expected type, the types of the operands is the default type. + let _ = 0 + 0; + let _ = 0 + &0; + let _ = &0 + 0; + let _ = &0 + &0; +} + diff --git a/gcc/testsuite/rust/rustc/ui/inference/inference-variable-behind-raw-pointer.rs b/gcc/testsuite/rust/rustc/ui/inference/inference-variable-behind-raw-pointer.rs new file mode 100644 index 000000000000..db9157088a4f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inference/inference-variable-behind-raw-pointer.rs @@ -0,0 +1,12 @@ +// check-pass + +// tests that the following code compiles, but produces a future-compatibility warning + +fn main() { + let data = std::ptr::null(); + let _ = &data as *const *const (); + if data.is_null() {} +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/inference/inference_unstable.rs b/gcc/testsuite/rust/rustc/ui/inference/inference_unstable.rs new file mode 100644 index 000000000000..7d63b7c86693 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inference/inference_unstable.rs @@ -0,0 +1,20 @@ +// Ensures #[unstable] functions without opting in the corresponding #![feature] +// will not break inference. + +// aux-build:inference_unstable_iterator.rs +// aux-build:inference_unstable_itertools.rs +// run-pass + +extern crate inference_unstable_iterator; +extern crate inference_unstable_itertools; + +#[allow(unused_imports)] +use inference_unstable_iterator::IpuIterator; +use inference_unstable_itertools::IpuItertools; + +fn main() { + assert_eq!('x'.ipu_flatten(), 1); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/inference/inference_unstable_featured.rs b/gcc/testsuite/rust/rustc/ui/inference/inference_unstable_featured.rs new file mode 100644 index 000000000000..32e2a2c3db66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inference/inference_unstable_featured.rs @@ -0,0 +1,18 @@ +// There should be E0034 "multiple applicable items in scope" if we opt-in for +// the feature. + +// aux-build:inference_unstable_iterator.rs +// aux-build:inference_unstable_itertools.rs + +#![feature(ipu_flatten)] + +extern crate inference_unstable_iterator; +extern crate inference_unstable_itertools; + +use inference_unstable_iterator::IpuIterator; +use inference_unstable_itertools::IpuItertools; + +fn main() { + assert_eq!('x'.ipu_flatten(), 0); // { dg-error ".E0034." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/inference/inference_unstable_forced.rs b/gcc/testsuite/rust/rustc/ui/inference/inference_unstable_forced.rs new file mode 100644 index 000000000000..371ad70560ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inference/inference_unstable_forced.rs @@ -0,0 +1,13 @@ +// If the unstable API is the only possible solution, +// still emit E0658 "use of unstable library feature". + +// aux-build:inference_unstable_iterator.rs + +extern crate inference_unstable_iterator; + +use inference_unstable_iterator::IpuIterator; + +fn main() { + assert_eq!('x'.ipu_flatten(), 0); // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/inference/issue-71732.rs b/gcc/testsuite/rust/rustc/ui/inference/issue-71732.rs new file mode 100644 index 000000000000..4df3500b4ff1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inference/issue-71732.rs @@ -0,0 +1,24 @@ +// Regression test for #71732, it used to emit incorrect diagnostics, like: +// error[E0283]: type annotations needed +// --> src/main.rs:5:10 +// | +// 5 | .get(&"key".into()) +// | ^^^ cannot infer type for struct `String` +// | +// = note: cannot satisfy `String: Borrow<_>` +// help: consider specifying the type argument in the method call +// | +// 5 | .get::(&"key".into()) +// | + +use std::collections::hash_map::HashMap; + +fn foo(parameters: &HashMap) -> bool { + parameters + .get(&"key".into()) // { dg-error ".E0283." "" { target *-*-* } } + .and_then(|found: &String| Some(false)) + .unwrap_or(false) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/inference/issue-72616.rs b/gcc/testsuite/rust/rustc/ui/inference/issue-72616.rs new file mode 100644 index 000000000000..51101ad0f42a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inference/issue-72616.rs @@ -0,0 +1,30 @@ +// Regression test for #72616, it used to emit incorrect diagnostics, like: +// error[E0283]: type annotations needed for `String` +// --> src/main.rs:8:30 +// | +// 5 | let _: String = "".to_owned().try_into().unwrap(); +// | - consider giving this pattern a type +// ... +// 8 | if String::from("a") == "a".try_into().unwrap() {} +// | ^^ cannot infer type for struct `String` +// | +// = note: cannot satisfy `String: PartialEq<_>` + +use std::convert::TryInto; + +pub fn main() { + { + let _: String = "".to_owned().try_into().unwrap(); + } + { + if String::from("a") == "a".try_into().unwrap() {} +// { dg-error ".E0283." "" { target *-*-* } .-1 } + } + { + let _: String = match "_".try_into() { + Ok(a) => a, + Err(_) => "".into(), + }; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/infinite/infinite-autoderef.rs b/gcc/testsuite/rust/rustc/ui/infinite/infinite-autoderef.rs new file mode 100644 index 000000000000..76d1a89dbe2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/infinite/infinite-autoderef.rs @@ -0,0 +1,28 @@ +// error-pattern: reached the recursion limit while auto-dereferencing + +#![feature(box_syntax)] + +use std::ops::Deref; + +struct Foo; + +impl Deref for Foo { + type Target = Foo; + + fn deref(&self) -> &Foo { + self + } +} + +pub fn main() { + let mut x; + loop { + x = box x; + x.foo; + x.bar(); + } + + Foo.foo; + Foo.bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/infinite/infinite-instantiation.rs b/gcc/testsuite/rust/rustc/ui/infinite/infinite-instantiation.rs new file mode 100644 index 000000000000..6d2267108a5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/infinite/infinite-instantiation.rs @@ -0,0 +1,30 @@ +// build-fail +// normalize-stderr-test: ".nll/" -> "/" + +trait ToOpt: Sized { + fn to_option(&self) -> Option; +} + +impl ToOpt for usize { + fn to_option(&self) -> Option { + Some(*self) + } +} + +impl ToOpt for Option { + fn to_option(&self) -> Option> { + Some((*self).clone()) + } +} + +fn function(counter: usize, t: T) { + if counter > 0 { + function(counter - 1, t.to_option()); +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +fn main() { + function(22, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/infinite/infinite-macro-expansion.rs b/gcc/testsuite/rust/rustc/ui/infinite/infinite-macro-expansion.rs new file mode 100644 index 000000000000..e918c2afac40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/infinite/infinite-macro-expansion.rs @@ -0,0 +1,8 @@ +macro_rules! recursive { + () => (recursive!()) // { dg-error "" "" { target *-*-* } } +} + +fn main() { + recursive!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/infinite/infinite-recursion-const-fn.rs b/gcc/testsuite/rust/rustc/ui/infinite/infinite-recursion-const-fn.rs new file mode 100644 index 000000000000..57dca002e9a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/infinite/infinite-recursion-const-fn.rs @@ -0,0 +1,13 @@ +//https://github.com/rust-lang/rust/issues/31364 + +const fn a() -> usize { +// { dg-error ".E0391." "" { target *-*-* } .-1 } + b() +} +const fn b() -> usize { + a() +} +const ARR: [i32; a()] = [5; 6]; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/infinite/infinite-tag-type-recursion.rs b/gcc/testsuite/rust/rustc/ui/infinite/infinite-tag-type-recursion.rs new file mode 100644 index 000000000000..2502be88786d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/infinite/infinite-tag-type-recursion.rs @@ -0,0 +1,6 @@ +enum MList { Cons(isize, MList), Nil } +// { dg-error ".E0391." "" { target *-*-* } .-1 } +// { dg-error ".E0391." "" { target *-*-* } .-2 } + +fn main() { let a = MList::Cons(10, MList::Cons(11, MList::Nil)); } + diff --git a/gcc/testsuite/rust/rustc/ui/infinite/infinite-vec-type-recursion.rs b/gcc/testsuite/rust/rustc/ui/infinite/infinite-vec-type-recursion.rs new file mode 100644 index 000000000000..e71bbc7d55c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/infinite/infinite-vec-type-recursion.rs @@ -0,0 +1,5 @@ +type X = Vec; +// { dg-error ".E0391." "" { target *-*-* } .-1 } + +fn main() { let b: X = Vec::new(); } + diff --git a/gcc/testsuite/rust/rustc/ui/inherit-env.rs b/gcc/testsuite/rust/rustc/ui/inherit-env.rs new file mode 100644 index 000000000000..adbcf1898056 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inherit-env.rs @@ -0,0 +1,27 @@ +// run-pass +// ignore-emscripten +// ignore-wasm32 +// ignore-sgx no processes + +use std::env; +use std::process::Command; + +fn main() { + if env::args().nth(1).map(|s| s == "print").unwrap_or(false) { + for (k, v) in env::vars() { + println!("{}={}", k, v); + } + return + } + + let me = env::current_exe().unwrap(); + let result = Command::new(me).arg("print").output().unwrap(); + let output = String::from_utf8(result.stdout).unwrap(); + + for (k, v) in env::vars() { + assert!(output.contains(&format!("{}={}", k, v)), + "output doesn't contain `{}={}`\n{}", + k, v, output); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/init-large-type.rs b/gcc/testsuite/rust/rustc/ui/init-large-type.rs new file mode 100644 index 000000000000..8b01190854de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/init-large-type.rs @@ -0,0 +1,24 @@ +// compile-flags: -O +// run-pass + +#![allow(unused_must_use)] +// Makes sure that zero-initializing large types is reasonably fast, +// Doing it incorrectly causes massive slowdown in LLVM during +// optimisation. + +// pretty-expanded FIXME #23616 +// ignore-emscripten no threads support + +#![feature(intrinsics)] + +use std::{mem, thread}; + +const SIZE: usize = 1024 * 1024; + +fn main() { + // do the test in a new thread to avoid (spurious?) stack overflows + thread::spawn(|| { + let _memory: [u8; SIZE] = unsafe { mem::zeroed() }; + }).join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/init-res-into-things.rs b/gcc/testsuite/rust/rustc/ui/init-res-into-things.rs new file mode 100644 index 000000000000..cce378121591 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/init-res-into-things.rs @@ -0,0 +1,83 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +#![feature(box_syntax)] + +use std::cell::Cell; + +// Resources can't be copied, but storing into data structures counts +// as a move unless the stored thing is used afterwards. + +struct r<'a> { + i: &'a Cell, +} + +struct BoxR<'a> { x: r<'a> } + +impl<'a> Drop for r<'a> { + fn drop(&mut self) { + self.i.set(self.i.get() + 1) + } +} + +fn r(i: &Cell) -> r { + r { + i: i + } +} + +fn test_rec() { + let i = &Cell::new(0); + { + let _a = BoxR {x: r(i)}; + } + assert_eq!(i.get(), 1); +} + +fn test_tag() { + enum t<'a> { + t0(r<'a>), + } + + let i = &Cell::new(0); + { + let _a = t::t0(r(i)); + } + assert_eq!(i.get(), 1); +} + +fn test_tup() { + let i = &Cell::new(0); + { + let _a = (r(i), 0); + } + assert_eq!(i.get(), 1); +} + +fn test_unique() { + let i = &Cell::new(0); + { + let _a: Box<_> = box r(i); + } + assert_eq!(i.get(), 1); +} + +fn test_unique_rec() { + let i = &Cell::new(0); + { + let _a: Box<_> = box BoxR { + x: r(i) + }; + } + assert_eq!(i.get(), 1); +} + +pub fn main() { + test_rec(); + test_tag(); + test_tup(); + test_unique(); + test_unique_rec(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/inline-asm-bad-constraint.rs b/gcc/testsuite/rust/rustc/ui/inline-asm-bad-constraint.rs new file mode 100644 index 000000000000..a427433a17f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inline-asm-bad-constraint.rs @@ -0,0 +1,41 @@ +// Test that the compiler will catch invalid inline assembly constraints. + +// build-fail +// ignore-emscripten + +#![feature(llvm_asm)] + +extern "C" { + fn foo(a: usize); +} + +fn main() { + bad_register_constraint(); + bad_input(); + wrong_size_output(); +} + +// Issue #54130 +fn bad_register_constraint() { + let rax: u64; + unsafe { + llvm_asm!("" :"={rax"(rax)) // { dg-error ".E0668." "" { target *-*-* } } + }; + println!("Accumulator is: {}", rax); +} + +// Issue #54376 +fn bad_input() { + unsafe { + llvm_asm!("callq $0" : : "0"(foo)) // { dg-error ".E0668." "" { target *-*-* } } + }; +} + +fn wrong_size_output() { + let rax: u64 = 0; + unsafe { + llvm_asm!("addb $1, $0" : "={rax}"((0i32, rax))); // { dg-error ".E0668." "" { target *-*-* } } + } + println!("rax: {}", rax); +} + diff --git a/gcc/testsuite/rust/rustc/ui/inline-asm-bad-operand.rs b/gcc/testsuite/rust/rustc/ui/inline-asm-bad-operand.rs new file mode 100644 index 000000000000..f49380ba03a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inline-asm-bad-operand.rs @@ -0,0 +1,60 @@ +// Test that the compiler will catch passing invalid values to inline assembly +// operands. + +// build-fail +// ignore-emscripten + +#![feature(llvm_asm)] + +#[repr(C)] +struct MyPtr(usize); + +fn main() { + issue_37433(); + issue_37437(); + issue_40187(); + issue_54067(); + multiple_errors(); +} + +fn issue_37433() { + unsafe { + llvm_asm!("" :: "r"("")); // { dg-error ".E0669." "" { target *-*-* } } + } + + unsafe { + let target = MyPtr(0); + llvm_asm!("ret" : : "{rdi}"(target)); // { dg-error ".E0669." "" { target *-*-* } } + } +} + +fn issue_37437() { + let hello: &str = "hello"; + // this should fail... + unsafe { llvm_asm!("" :: "i"(hello)) }; // { dg-error ".E0669." "" { target *-*-* } } + // but this should succeed. + unsafe { llvm_asm!("" :: "r"(hello.as_ptr())) }; +} + +fn issue_40187() { + let arr: [u8; 1] = [0; 1]; + unsafe { + llvm_asm!("movups $1, %xmm0"::"m"(arr)); // { dg-error ".E0669." "" { target *-*-* } } + } +} + +fn issue_54067() { + let addr: Option = Some(123); + unsafe { + llvm_asm!("mov sp, $0"::"r"(addr)); // { dg-error ".E0669." "" { target *-*-* } } + } +} + +fn multiple_errors() { + let addr: (u32, u32) = (1, 2); + unsafe { + llvm_asm!("mov sp, $0"::"r"(addr), // { dg-error ".E0669." "" { target *-*-* } } + "r"("hello e0669")); // { dg-error ".E0669." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/inline-const/const-expr-array-init.rs b/gcc/testsuite/rust/rustc/ui/inline-const/const-expr-array-init.rs new file mode 100644 index 000000000000..94195b9207fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inline-const/const-expr-array-init.rs @@ -0,0 +1,11 @@ +// build-pass + +#![allow(incomplete_features)] +#![feature(inline_const)] + +use std::cell::Cell; + +fn main() { + let _x = [const { Cell::new(0) }; 20]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/inline-const/const-expr-basic.rs b/gcc/testsuite/rust/rustc/ui/inline-const/const-expr-basic.rs new file mode 100644 index 000000000000..ea4607083bcf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inline-const/const-expr-basic.rs @@ -0,0 +1,15 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(inline_const)] +fn foo() -> i32 { + const { + let x = 5 + 10; + x / 3 + } +} + +fn main() { + assert_eq!(5, foo()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/inline-const/const-expr-macro.rs b/gcc/testsuite/rust/rustc/ui/inline-const/const-expr-macro.rs new file mode 100644 index 000000000000..c33ca188f80f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inline-const/const-expr-macro.rs @@ -0,0 +1,13 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(inline_const)] +macro_rules! do_const_block{ + ($val:block) => { const $val } +} + +fn main() { + let s = do_const_block!({ 22 }); + assert_eq!(s, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/inline-const/const-expr-reference.rs b/gcc/testsuite/rust/rustc/ui/inline-const/const-expr-reference.rs new file mode 100644 index 000000000000..6353e49f16c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inline-const/const-expr-reference.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(inline_const)] + +const fn bar() -> i32 { + const { + 2 + 3 + } +} + +fn main() { + let x: &'static i32 = &const{bar()}; + assert_eq!(&5, x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/inline-const/const-match-pat-range.rs b/gcc/testsuite/rust/rustc/ui/inline-const/const-match-pat-range.rs new file mode 100644 index 000000000000..a855e06ff37d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inline-const/const-match-pat-range.rs @@ -0,0 +1,39 @@ +// build-pass + +#![allow(incomplete_features)] +#![feature(inline_const, half_open_range_patterns, exclusive_range_pattern)] +fn main() { + const N: u32 = 10; + let x: u32 = 3; + + match x { + 1 ..= const { N + 1 } => {}, + _ => {}, + } + + match x { + const { N - 1 } ..= 10 => {}, + _ => {}, + } + + match x { + const { N - 1 } ..= const { N + 1 } => {}, + _ => {}, + } + + match x { + .. const { N + 1 } => {}, + _ => {}, + } + + match x { + const { N - 1 } .. => {}, + _ => {}, + } + + match x { + ..= const { N + 1 } => {}, + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/inline-const/const-match-pat.rs b/gcc/testsuite/rust/rustc/ui/inline-const/const-match-pat.rs new file mode 100644 index 000000000000..7f9b68c7a636 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inline-const/const-match-pat.rs @@ -0,0 +1,22 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(inline_const)] +const MMIO_BIT1: u8 = 4; +const MMIO_BIT2: u8 = 5; + +fn main() { + let s = match read_mmio() { + 0 => "FOO", + const { 1 << MMIO_BIT1 } => "BAR", + const { 1 << MMIO_BIT2 } => "BAZ", + _ => unreachable!(), + }; + + assert_eq!("BAZ", s); +} + +fn read_mmio() -> i32 { + 1 << 5 +} + diff --git a/gcc/testsuite/rust/rustc/ui/inline-const/macro-with-const.rs b/gcc/testsuite/rust/rustc/ui/inline-const/macro-with-const.rs new file mode 100644 index 000000000000..f90ec20367b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inline-const/macro-with-const.rs @@ -0,0 +1,21 @@ +// check-pass + +macro_rules! exp { + (const $n:expr) => { + $n + }; +} + +macro_rules! stmt { + (exp $e:expr) => { + $e + }; + (exp $($t:tt)+) => { + exp!($($t)+) + }; +} + +fn main() { + stmt!(exp const 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/inline-disallow-on-variant.rs b/gcc/testsuite/rust/rustc/ui/inline-disallow-on-variant.rs new file mode 100644 index 000000000000..fd1a35934e51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inline-disallow-on-variant.rs @@ -0,0 +1,8 @@ +enum Foo { + #[inline] +// { dg-error ".E0518." "" { target *-*-* } .-1 } + Variant, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/inlined-main.rs b/gcc/testsuite/rust/rustc/ui/inlined-main.rs new file mode 100644 index 000000000000..3834118ebc0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inlined-main.rs @@ -0,0 +1,5 @@ +// run-pass + +#[inline(always)] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/inner-attrs-on-impl.rs b/gcc/testsuite/rust/rustc/ui/inner-attrs-on-impl.rs new file mode 100644 index 000000000000..5a5ae719b9df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inner-attrs-on-impl.rs @@ -0,0 +1,25 @@ +// run-pass + +struct Foo; + +impl Foo { + #![cfg(cfg_that_surely_doesnt_exist)] + + fn method(&self) -> bool { false } +} + +impl Foo { + #![cfg(not(cfg_that_surely_doesnt_exist))] + + // check that we don't eat attributes too eagerly. + #[cfg(cfg_that_surely_doesnt_exist)] + fn method(&self) -> bool { false } + + fn method(&self) -> bool { true } +} + + +pub fn main() { + assert!(Foo.method()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/inner-module.rs b/gcc/testsuite/rust/rustc/ui/inner-module.rs new file mode 100644 index 000000000000..cb47c1c173eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inner-module.rs @@ -0,0 +1,11 @@ +// run-pass + +mod inner { + pub mod inner2 { + pub fn hello() { println!("hello, modular world"); } + } + pub fn hello() { inner2::hello(); } +} + +pub fn main() { inner::hello(); inner::inner2::hello(); } + diff --git a/gcc/testsuite/rust/rustc/ui/inner-static-type-parameter.rs b/gcc/testsuite/rust/rustc/ui/inner-static-type-parameter.rs new file mode 100644 index 000000000000..8f45f775f867 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inner-static-type-parameter.rs @@ -0,0 +1,12 @@ +// see #9186 + +enum Bar { What } // { dg-error ".E0392." "" { target *-*-* } } + +fn foo() { + static a: Bar = Bar::What; +// { dg-error ".E0401." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/inner-static.rs b/gcc/testsuite/rust/rustc/ui/inner-static.rs new file mode 100644 index 000000000000..dd74a19941b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/inner-static.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:inner_static.rs + + +extern crate inner_static; + +pub fn main() { + let a = inner_static::A::<()> { v: () }; + let b = inner_static::B::<()> { v: () }; + let c = inner_static::test::A::<()> { v: () }; + assert_eq!(a.bar(), 2); + assert_eq!(b.bar(), 4); + assert_eq!(c.bar(), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/instantiable.rs b/gcc/testsuite/rust/rustc/ui/instantiable.rs new file mode 100644 index 000000000000..b0aac8224b83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/instantiable.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +use std::ptr; + +// check that we do not report a type like this as uninstantiable, +// even though it would be if the nxt field had type @foo: +struct foo(X); + +struct X { x: usize, nxt: *const foo } + +pub fn main() { + let _x = foo(X {x: 0, nxt: ptr::null()}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/integer-literal-suffix-inference.rs b/gcc/testsuite/rust/rustc/ui/integer-literal-suffix-inference.rs new file mode 100644 index 000000000000..a6bf5d866879 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/integer-literal-suffix-inference.rs @@ -0,0 +1,221 @@ +fn main() { + + // the smallest positive values that need these types + let a8: i8 = 8; + let a16: i16 = 128; + let a32: i32 = 32_768; + let a64: i64 = 2_147_483_648; + + // the smallest negative values that need these types + let c8: i8 = -9; + let c16: i16 = -129; + let c32: i32 = -32_769; + let c64: i64 = -2_147_483_649; + + fn id_i8(n: i8) -> i8 { n } + fn id_i16(n: i16) -> i16 { n } + fn id_i32(n: i32) -> i32 { n } + fn id_i64(n: i64) -> i64 { n } + fn id_isize(n: isize) -> isize { n } + + // the smallest values that need these types + let b8: u8 = 16; + let b16: u16 = 256; + let b32: u32 = 65_536; + let b64: u64 = 4_294_967_296; + + fn id_u8(n: u8) -> u8 { n } + fn id_u16(n: u16) -> u16 { n } + fn id_u32(n: u32) -> u32 { n } + fn id_u64(n: u64) -> u64 { n } + fn id_usize(n: usize) -> usize { n } + + // Values for testing *size + let asize: isize = 1; + let bsize: usize = 3; + + id_i8(a8); // ok + id_i8(a16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i8(a32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i8(a64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i8(asize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + id_i16(a8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i16(a16); // ok + id_i16(a32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i16(a64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i16(asize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + id_i32(a8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i32(a16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i32(a32); // ok + id_i32(a64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i32(asize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + id_i64(a8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i64(a16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i64(a32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i64(a64); // ok + id_i64(asize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + id_isize(a8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_isize(a16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_isize(a32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_isize(a64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_isize(asize); //ok + + id_i8(c8); // ok + id_i8(c16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i8(c32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i8(c64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + id_i16(c8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i16(c16); // ok + id_i16(c32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i16(c64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + id_i32(c8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i32(c16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i32(c32); // ok + id_i32(c64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + id_i64(a8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i64(a16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i64(a32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_i64(a64); // ok + + id_u8(b8); // ok + id_u8(b16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_u8(b32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_u8(b64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_u8(bsize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + id_u16(b8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_u16(b16); // ok + id_u16(b32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_u16(b64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_u16(bsize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + id_u32(b8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_u32(b16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_u32(b32); // ok + id_u32(b64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_u32(bsize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + id_u64(b8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_u64(b16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_u64(b32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_u64(b64); // ok + id_u64(bsize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + id_usize(b8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_usize(b16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_usize(b32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_usize(b64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + id_usize(bsize); //ok +} + diff --git a/gcc/testsuite/rust/rustc/ui/integral-indexing.rs b/gcc/testsuite/rust/rustc/ui/integral-indexing.rs new file mode 100644 index 000000000000..a6a4a39ec2de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/integral-indexing.rs @@ -0,0 +1,17 @@ +pub fn main() { + let v: Vec = vec![0, 1, 2, 3, 4, 5]; + let s: String = "abcdef".to_string(); + v[3_usize]; + v[3]; + v[3u8]; // { dg-error ".E0277." "" { target *-*-* } } + v[3i8]; // { dg-error ".E0277." "" { target *-*-* } } + v[3u32]; // { dg-error ".E0277." "" { target *-*-* } } + v[3i32]; // { dg-error ".E0277." "" { target *-*-* } } + s.as_bytes()[3_usize]; + s.as_bytes()[3]; + s.as_bytes()[3u8]; // { dg-error ".E0277." "" { target *-*-* } } + s.as_bytes()[3i8]; // { dg-error ".E0277." "" { target *-*-* } } + s.as_bytes()[3u32]; // { dg-error ".E0277." "" { target *-*-* } } + s.as_bytes()[3i32]; // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/integral-variable-unification-error.rs b/gcc/testsuite/rust/rustc/ui/integral-variable-unification-error.rs new file mode 100644 index 000000000000..29f263cebe79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/integral-variable-unification-error.rs @@ -0,0 +1,7 @@ +fn main() { + let mut x = 2; + x = 5.0; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/interior-mutability/interior-mutability.rs b/gcc/testsuite/rust/rustc/ui/interior-mutability/interior-mutability.rs new file mode 100644 index 000000000000..0a62f69da801 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/interior-mutability/interior-mutability.rs @@ -0,0 +1,8 @@ +use std::cell::Cell; +use std::panic::catch_unwind; +fn main() { + let mut x = Cell::new(22); + catch_unwind(|| { x.set(23); }); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/internal/auxiliary/internal_unstable.rs b/gcc/testsuite/rust/rustc/ui/internal/auxiliary/internal_unstable.rs new file mode 100644 index 000000000000..3a5e0c6dfae8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/internal/auxiliary/internal_unstable.rs @@ -0,0 +1,102 @@ +#![feature(staged_api, allow_internal_unstable)] +#![stable(feature = "stable", since = "1.0.0")] + +#[unstable(feature = "function", issue = "none")] +pub fn unstable() {} + + +#[stable(feature = "stable", since = "1.0.0")] +pub struct Foo { + #[unstable(feature = "struct_field", issue = "none")] + pub x: u8 +} + +impl Foo { + #[unstable(feature = "method", issue = "none")] + pub fn method(&self) {} +} + +#[stable(feature = "stable", since = "1.0.0")] +pub struct Bar { + #[unstable(feature = "struct2_field", issue = "none")] + pub x: u8 +} + +#[stable(feature = "stable", since = "1.0.0")] +#[allow_internal_unstable(function)] +#[macro_export] +macro_rules! call_unstable_allow { + () => { $crate::unstable() } +} + +#[stable(feature = "stable", since = "1.0.0")] +#[allow_internal_unstable(struct_field)] +#[macro_export] +macro_rules! construct_unstable_allow { + ($e: expr) => { + $crate::Foo { x: $e } + } +} + +#[stable(feature = "stable", since = "1.0.0")] +#[allow_internal_unstable(method)] +#[macro_export] +macro_rules! call_method_allow { + ($e: expr) => { $e.method() } +} + +#[stable(feature = "stable", since = "1.0.0")] +#[allow_internal_unstable(struct_field, struct2_field)] +#[macro_export] +macro_rules! access_field_allow { + ($e: expr) => { $e.x } +} + +// regression test for #77088 +#[stable(feature = "stable", since = "1.0.0")] +#[allow_internal_unstable(struct_field)] +#[allow_internal_unstable(struct2_field)] +#[macro_export] +macro_rules! access_field_allow2 { + ($e: expr) => { $e.x } +} + +#[stable(feature = "stable", since = "1.0.0")] +#[allow_internal_unstable()] +#[macro_export] +macro_rules! pass_through_allow { + ($e: expr) => { $e } +} + +#[stable(feature = "stable", since = "1.0.0")] +#[macro_export] +macro_rules! call_unstable_noallow { + () => { $crate::unstable() } +} + +#[stable(feature = "stable", since = "1.0.0")] +#[macro_export] +macro_rules! construct_unstable_noallow { + ($e: expr) => { + $crate::Foo { x: $e } + } +} + +#[stable(feature = "stable", since = "1.0.0")] +#[macro_export] +macro_rules! call_method_noallow { + ($e: expr) => { $e.method() } +} + +#[stable(feature = "stable", since = "1.0.0")] +#[macro_export] +macro_rules! access_field_noallow { + ($e: expr) => { $e.x } +} + +#[stable(feature = "stable", since = "1.0.0")] +#[macro_export] +macro_rules! pass_through_noallow { + ($e: expr) => { $e } +} + diff --git a/gcc/testsuite/rust/rustc/ui/internal/internal-unstable-const.rs b/gcc/testsuite/rust/rustc/ui/internal/internal-unstable-const.rs new file mode 100644 index 000000000000..67f6572c04af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/internal/internal-unstable-const.rs @@ -0,0 +1,15 @@ +// Don't allow unstable features in stable functions without `allow_internal_unstable`. + +#![stable(feature = "rust1", since = "1.0.0")] + +#![feature(staged_api)] +#![feature(const_transmute, const_fn)] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +pub const fn foo() -> i32 { + unsafe { std::mem::transmute(4u32) } // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/internal/internal-unstable-noallow.rs b/gcc/testsuite/rust/rustc/ui/internal/internal-unstable-noallow.rs new file mode 100644 index 000000000000..2cb571cfcbdb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/internal/internal-unstable-noallow.rs @@ -0,0 +1,24 @@ +// this has to be separate to internal-unstable.rs because these tests +// have error messages pointing deep into the internals of the +// cross-crate macros, and hence need to use error-pattern instead of +// the // ~ form. + +// aux-build:internal_unstable.rs +// error-pattern:use of unstable library feature 'function' +// error-pattern:use of unstable library feature 'struct_field' +// error-pattern:use of unstable library feature 'method' +// error-pattern:use of unstable library feature 'struct2_field' + +#[macro_use] +extern crate internal_unstable; + +fn main() { + call_unstable_noallow!(); + + construct_unstable_noallow!(0); + + |x: internal_unstable::Foo| { call_method_noallow!(x) }; + + |x: internal_unstable::Bar| { access_field_noallow!(x) }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/internal/internal-unstable-thread-local.rs b/gcc/testsuite/rust/rustc/ui/internal/internal-unstable-thread-local.rs new file mode 100644 index 000000000000..9873a16785ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/internal/internal-unstable-thread-local.rs @@ -0,0 +1,12 @@ +// aux-build:internal_unstable.rs + +#![allow(dead_code)] + +extern crate internal_unstable; + + +thread_local!(static FOO: () = ()); +thread_local!(static BAR: () = internal_unstable::unstable()); // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/internal/internal-unstable.rs b/gcc/testsuite/rust/rustc/ui/internal/internal-unstable.rs new file mode 100644 index 000000000000..da9af4de7379 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/internal/internal-unstable.rs @@ -0,0 +1,44 @@ +// aux-build:internal_unstable.rs + +#![feature(allow_internal_unstable)] + +#[macro_use] +extern crate internal_unstable; + +macro_rules! foo { + ($e: expr, $f: expr) => {{ + $e; + $f; + internal_unstable::unstable(); // { dg-error ".E0658." "" { target *-*-* } } + }} +} + +#[allow_internal_unstable(function)] +macro_rules! bar { + ($e: expr) => {{ + foo!($e, + internal_unstable::unstable()); + internal_unstable::unstable(); + }} +} + +fn main() { + // ok, the instability is contained. + call_unstable_allow!(); + construct_unstable_allow!(0); + |x: internal_unstable::Foo| { call_method_allow!(x) }; + |x: internal_unstable::Bar| { access_field_allow!(x) }; + |x: internal_unstable::Bar| { access_field_allow2!(x) }; // regression test for #77088 + + // bad. + pass_through_allow!(internal_unstable::unstable()); // { dg-error ".E0658." "" { target *-*-* } } + + pass_through_noallow!(internal_unstable::unstable()); // { dg-error ".E0658." "" { target *-*-* } } + + + + println!("{:?}", internal_unstable::unstable()); // { dg-error ".E0658." "" { target *-*-* } } + + bar!(internal_unstable::unstable()); // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics-always-extern.rs b/gcc/testsuite/rust/rustc/ui/intrinsics-always-extern.rs new file mode 100644 index 000000000000..cc9484605edf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics-always-extern.rs @@ -0,0 +1,17 @@ +#![feature(intrinsics)] + +trait Foo { + extern "rust-intrinsic" fn foo(&self); // { dg-error "" "" { target *-*-* } } +} + +impl Foo for () { + extern "rust-intrinsic" fn foo(&self) { // { dg-error "" "" { target *-*-* } } + } +} + +extern "rust-intrinsic" fn hello() {// { dg-error "" "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/auxiliary/cci_intrinsic.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/auxiliary/cci_intrinsic.rs new file mode 100644 index 000000000000..0b79bc04b3bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/auxiliary/cci_intrinsic.rs @@ -0,0 +1,15 @@ +#![feature(intrinsics)] + +pub mod rusti { + extern "rust-intrinsic" { + pub fn atomic_xchg(dst: *mut T, src: T) -> T; + } +} + +#[inline(always)] +pub fn atomic_xchg(dst: *mut isize, src: isize) -> isize { + unsafe { + rusti::atomic_xchg(dst, src) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-alignment.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-alignment.rs new file mode 100644 index 000000000000..0675b0b9b7de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-alignment.rs @@ -0,0 +1,66 @@ +// run-pass +// ignore-wasm32-bare seems not important to test here + +#![feature(intrinsics, main)] + +mod rusti { + extern "rust-intrinsic" { + pub fn pref_align_of() -> usize; + pub fn min_align_of() -> usize; + } +} + +#[cfg(any(target_os = "android", + target_os = "cloudabi", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "vxworks"))] +mod m { + #[main] + #[cfg(target_arch = "x86")] + pub fn main() { + unsafe { + assert_eq!(::rusti::pref_align_of::(), 8); + assert_eq!(::rusti::min_align_of::(), 4); + } + } + + #[main] + #[cfg(not(target_arch = "x86"))] + pub fn main() { + unsafe { + assert_eq!(::rusti::pref_align_of::(), 8); + assert_eq!(::rusti::min_align_of::(), 8); + } + } +} + +#[cfg(target_env = "sgx")] +mod m { + #[main] + #[cfg(target_arch = "x86_64")] + pub fn main() { + unsafe { + assert_eq!(::rusti::pref_align_of::(), 8); + assert_eq!(::rusti::min_align_of::(), 8); + } + } +} + +#[cfg(target_os = "windows")] +mod m { + #[main] + pub fn main() { + unsafe { + assert_eq!(::rusti::pref_align_of::(), 8); + assert_eq!(::rusti::min_align_of::(), 8); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-assume.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-assume.rs new file mode 100644 index 000000000000..3ad91ea1d4a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-assume.rs @@ -0,0 +1,18 @@ +// run-pass +#![feature(core_intrinsics)] + +use std::intrinsics::assume; + +unsafe fn f(x: i32) -> i32 { + assume(x == 34); + match x { + 34 => 42, + _ => 30 + } +} + +fn main() { + let x = unsafe { f(34) }; + assert_eq!(x, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-atomics-cc.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-atomics-cc.rs new file mode 100644 index 000000000000..5a0d79915cc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-atomics-cc.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:cci_intrinsic.rs + + +extern crate cci_intrinsic; +use cci_intrinsic::atomic_xchg; + +pub fn main() { + let mut x = 1; + atomic_xchg(&mut x, 5); + assert_eq!(x, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-atomics.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-atomics.rs new file mode 100644 index 000000000000..f4b73b24bbd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-atomics.rs @@ -0,0 +1,104 @@ +// run-pass +#![feature(box_syntax)] +#![feature(intrinsics)] + +mod rusti { + extern "rust-intrinsic" { + pub fn atomic_cxchg(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchg_acq(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchg_rel(dst: *mut T, old: T, src: T) -> (T, bool); + + pub fn atomic_cxchgweak(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchgweak_acq(dst: *mut T, old: T, src: T) -> (T, bool); + pub fn atomic_cxchgweak_rel(dst: *mut T, old: T, src: T) -> (T, bool); + + pub fn atomic_load(src: *const T) -> T; + pub fn atomic_load_acq(src: *const T) -> T; + + pub fn atomic_store(dst: *mut T, val: T); + pub fn atomic_store_rel(dst: *mut T, val: T); + + pub fn atomic_xchg(dst: *mut T, src: T) -> T; + pub fn atomic_xchg_acq(dst: *mut T, src: T) -> T; + pub fn atomic_xchg_rel(dst: *mut T, src: T) -> T; + + pub fn atomic_xadd(dst: *mut T, src: T) -> T; + pub fn atomic_xadd_acq(dst: *mut T, src: T) -> T; + pub fn atomic_xadd_rel(dst: *mut T, src: T) -> T; + + pub fn atomic_xsub(dst: *mut T, src: T) -> T; + pub fn atomic_xsub_acq(dst: *mut T, src: T) -> T; + pub fn atomic_xsub_rel(dst: *mut T, src: T) -> T; + } +} + +pub fn main() { + unsafe { + let mut x: Box<_> = box 1; + + assert_eq!(rusti::atomic_load(&*x), 1); + *x = 5; + assert_eq!(rusti::atomic_load_acq(&*x), 5); + + rusti::atomic_store(&mut *x,3); + assert_eq!(*x, 3); + rusti::atomic_store_rel(&mut *x,1); + assert_eq!(*x, 1); + + assert_eq!(rusti::atomic_cxchg(&mut *x, 1, 2), (1, true)); + assert_eq!(*x, 2); + + assert_eq!(rusti::atomic_cxchg_acq(&mut *x, 1, 3), (2, false)); + assert_eq!(*x, 2); + + assert_eq!(rusti::atomic_cxchg_rel(&mut *x, 2, 1), (2, true)); + assert_eq!(*x, 1); + + assert_eq!(rusti::atomic_xchg(&mut *x, 0), 1); + assert_eq!(*x, 0); + + assert_eq!(rusti::atomic_xchg_acq(&mut *x, 1), 0); + assert_eq!(*x, 1); + + assert_eq!(rusti::atomic_xchg_rel(&mut *x, 0), 1); + assert_eq!(*x, 0); + + assert_eq!(rusti::atomic_xadd(&mut *x, 1), 0); + assert_eq!(rusti::atomic_xadd_acq(&mut *x, 1), 1); + assert_eq!(rusti::atomic_xadd_rel(&mut *x, 1), 2); + assert_eq!(*x, 3); + + assert_eq!(rusti::atomic_xsub(&mut *x, 1), 3); + assert_eq!(rusti::atomic_xsub_acq(&mut *x, 1), 2); + assert_eq!(rusti::atomic_xsub_rel(&mut *x, 1), 1); + assert_eq!(*x, 0); + + loop { + let res = rusti::atomic_cxchgweak(&mut *x, 0, 1); + assert_eq!(res.0, 0); + if res.1 { + break; + } + } + assert_eq!(*x, 1); + + loop { + let res = rusti::atomic_cxchgweak_acq(&mut *x, 1, 2); + assert_eq!(res.0, 1); + if res.1 { + break; + } + } + assert_eq!(*x, 2); + + loop { + let res = rusti::atomic_cxchgweak_rel(&mut *x, 2, 3); + assert_eq!(res.0, 2); + if res.1 { + break; + } + } + assert_eq!(*x, 3); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-move-val-cleanups.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-move-val-cleanups.rs new file mode 100644 index 000000000000..2ad7eb336c10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-move-val-cleanups.rs @@ -0,0 +1,192 @@ +// run-pass +#![allow(unused_braces)] +#![allow(unused_unsafe)] +#![allow(unreachable_code)] +// ignore-emscripten no threads support +#![allow(stable_features)] + +// This test is checking that the move_val_init intrinsic is +// respecting cleanups for both of its argument expressions. +// +// In other words, if either DEST or SOURCE in +// +// `intrinsics::move_val_init(DEST, SOURCE) +// +// introduce temporaries that require cleanup, and SOURCE panics, then +// make sure the cleanups still occur. + +#![feature(core_intrinsics, sync_poison)] + +use std::cell::RefCell; +use std::intrinsics; +use std::sync::{Arc, LockResult, Mutex, MutexGuard}; +use std::thread; + +type LogEntry = (&'static str, i32); +type Guarded = RefCell>; +#[derive(Clone)] +struct Log(Arc>); +struct Acquired<'a>(MutexGuard<'a, Guarded>); +type LogState = (MutexWas, &'static [LogEntry]); + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +enum MutexWas { Poisoned, NotPoisoned } + +impl Log { + fn lock(&self) -> LockResult>>> { self.0.lock() } + fn acquire(&self) -> Acquired { Acquired(self.0.lock().unwrap()) } +} + +impl<'a> Acquired<'a> { + fn log(&self, s: &'static str, i: i32) { self.0.borrow_mut().push((s, i)); } +} + +const TEST1_EXPECT: LogState = (MutexWas::NotPoisoned, + &[("double-check non-poisoning path", 1) + ]); + +fn test1(log: Log) { + { + let acq = log.acquire(); + acq.log("double-check non-poisoning path", 1); + } + panic!("every test ends in a panic"); +} + +const TEST2_EXPECT: LogState = (MutexWas::Poisoned, + &[("double-check poisoning path", 1), + ("and multiple log entries", 2), + ]); +fn test2(log: Log) { + let acq = log.acquire(); + acq.log("double-check poisoning path", 1); + acq.log("and multiple log entries", 2); + panic!("every test ends in a panic"); +} + +struct LogOnDrop<'a>(&'a Acquired<'a>, &'static str, i32); +impl<'a> Drop for LogOnDrop<'a> { + fn drop(&mut self) { + self.0.log(self.1, self.2); + } +} + +const TEST3_EXPECT: LogState = (MutexWas::Poisoned, + &[("double-check destructors can log", 1), + ("drop d2", 2), + ("drop d1", 3), + ]); +fn test3(log: Log) { + let acq = log.acquire(); + acq.log("double-check destructors can log", 1); + let _d1 = LogOnDrop(&acq, "drop d1", 3); + let _d2 = LogOnDrop(&acq, "drop d2", 2); + panic!("every test ends in a panic"); +} + +// The *real* tests of panic-handling for move_val_init intrinsic +// start here. + +const TEST4_EXPECT: LogState = (MutexWas::Poisoned, + &[("neither arg panics", 1), + ("drop temp LOD", 2), + ("drop temp LOD", 3), + ("drop dest_b", 4), + ("drop dest_a", 5), + ]); +fn test4(log: Log) { + let acq = log.acquire(); + acq.log("neither arg panics", 1); + let mut dest_a = LogOnDrop(&acq, "a will be overwritten, not dropped", 0); + let mut dest_b = LogOnDrop(&acq, "b will be overwritten, not dropped", 0); + unsafe { + intrinsics::move_val_init({ LogOnDrop(&acq, "drop temp LOD", 2); &mut dest_a }, + LogOnDrop(&acq, "drop dest_a", 5)); + intrinsics::move_val_init(&mut dest_b, { LogOnDrop(&acq, "drop temp LOD", 3); + LogOnDrop(&acq, "drop dest_b", 4) }); + } + panic!("every test ends in a panic"); +} + + +// Check that move_val_init(PANIC, SOURCE_EXPR) never evaluates SOURCE_EXPR +const TEST5_EXPECT: LogState = (MutexWas::Poisoned, + &[("first arg panics", 1), + ("drop orig dest_a", 2), + ]); +fn test5(log: Log) { + let acq = log.acquire(); + acq.log("first arg panics", 1); + let mut _dest_a = LogOnDrop(&acq, "drop orig dest_a", 2); + unsafe { + intrinsics::move_val_init({ panic!("every test ends in a panic") }, + LogOnDrop(&acq, "we never get here", 0)); + } +} + +// Check that move_val_init(DEST_EXPR, PANIC) cleans up temps from DEST_EXPR. +const TEST6_EXPECT: LogState = (MutexWas::Poisoned, + &[("second arg panics", 1), + ("drop temp LOD", 2), + ("drop orig dest_a", 3), + ]); +fn test6(log: Log) { + let acq = log.acquire(); + acq.log("second arg panics", 1); + let mut dest_a = LogOnDrop(&acq, "drop orig dest_a", 3); + unsafe { + intrinsics::move_val_init({ LogOnDrop(&acq, "drop temp LOD", 2); &mut dest_a }, + { panic!("every test ends in a panic"); }); + } +} + +// Check that move_val_init(DEST_EXPR, COMPLEX_PANIC) cleans up temps from COMPLEX_PANIC. +const TEST7_EXPECT: LogState = (MutexWas::Poisoned, + &[("second arg panics", 1), + ("drop temp LOD", 2), + ("drop temp LOD", 3), + ("drop orig dest_a", 4), + ]); +fn test7(log: Log) { + let acq = log.acquire(); + acq.log("second arg panics", 1); + let mut dest_a = LogOnDrop(&acq, "drop orig dest_a", 4); + unsafe { + intrinsics::move_val_init({ LogOnDrop(&acq, "drop temp LOD", 2); &mut dest_a }, + { LogOnDrop(&acq, "drop temp LOD", 3); + panic!("every test ends in a panic"); }); + } +} + +const TEST_SUITE: &'static [(&'static str, fn (Log), LogState)] = + &[("test1", test1, TEST1_EXPECT), + ("test2", test2, TEST2_EXPECT), + ("test3", test3, TEST3_EXPECT), + ("test4", test4, TEST4_EXPECT), + ("test5", test5, TEST5_EXPECT), + ("test6", test6, TEST6_EXPECT), + ("test7", test7, TEST7_EXPECT), + ]; + +fn main() { + for &(name, test, expect) in TEST_SUITE { + let log = Log(Arc::new(Mutex::new(RefCell::new(Vec::new())))); + let ret = { let log = log.clone(); thread::spawn(move || test(log)).join() }; + assert!(ret.is_err(), "{} must end with panic", name); + { + let l = log.lock(); + match l { + Ok(acq) => { + assert_eq!((MutexWas::NotPoisoned, &acq.borrow()[..]), expect); + println!("{} (unpoisoned) log: {:?}", name, *acq); + } + Err(e) => { + let acq = e.into_inner(); + assert_eq!((MutexWas::Poisoned, &acq.borrow()[..]), expect); + println!("{} (poisoned) log: {:?}", name, *acq); + } + } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-move-val.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-move-val.rs new file mode 100644 index 000000000000..b50148741425 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-move-val.rs @@ -0,0 +1,82 @@ +// run-pass + +#![feature(box_syntax)] +#![feature(intrinsics)] + +mod rusti { + extern "rust-intrinsic" { + pub fn move_val_init(dst: *mut T, src: T); + } +} + +pub fn main() { + unsafe { + // sanity check + check_drops_state(0, None); + + let mut x: Option> = Some(box D(1)); + assert_eq!(x.as_ref().unwrap().0, 1); + + // A normal overwrite, to demonstrate `check_drops_state`. + x = Some(box D(2)); + + // At this point, one destructor has run, because the + // overwrite of `x` drops its initial value. + check_drops_state(1, Some(1)); + + let mut y: Option> = std::mem::zeroed(); + + // An initial binding does not overwrite anything. + check_drops_state(1, Some(1)); + + // Since `y` has been initialized via the `init` intrinsic, it + // would be unsound to directly overwrite its value via normal + // assignment. + // + // The code currently generated by the compiler is overly + // accepting, however, in that it will check if `y` is itself + // null and thus avoid the unsound action of attempting to + // free null. In other words, if we were to do a normal + // assignment like `y = box D(4);` here, it probably would not + // crash today. But the plan is that it may well crash in the + // future, (I believe). + + // `x` is moved here; the manner in which this is tracked by the + // compiler is hidden. + rusti::move_val_init(&mut y, x); + + // But what we *can* observe is how many times the destructor + // for `D` is invoked, and what the last value we saw was + // during such a destructor call. We do so after the end of + // this scope. + + assert_eq!(y.as_ref().unwrap().0, 2); + y.as_mut().unwrap().0 = 3; + assert_eq!(y.as_ref().unwrap().0, 3); + + check_drops_state(1, Some(1)); + } + + check_drops_state(2, Some(3)); +} + +static mut NUM_DROPS: i32 = 0; +static mut LAST_DROPPED: Option = None; + +fn check_drops_state(num_drops: i32, last_dropped: Option) { + unsafe { + assert_eq!(NUM_DROPS, num_drops); + assert_eq!(LAST_DROPPED, last_dropped); + } +} + +struct D(i32); +impl Drop for D { + fn drop(&mut self) { + unsafe { + NUM_DROPS += 1; + LAST_DROPPED = Some(self.0); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-nearby.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-nearby.rs new file mode 100644 index 000000000000..5e5f0e86ad77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-nearby.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(core_intrinsics)] + +use std::intrinsics::*; + +fn main() { + unsafe { + assert_eq!(nearbyintf32(5.234f32), 5f32); + assert_eq!(nearbyintf64(6.777f64), 7f64); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-unreachable.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-unreachable.rs new file mode 100644 index 000000000000..9d966f75619b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-unreachable.rs @@ -0,0 +1,18 @@ +// run-pass +#![feature(core_intrinsics)] + +use std::intrinsics; + +// See also src/test/run-make/intrinsic-unreachable. + +unsafe fn f(x: usize) -> usize { + match x { + 17 => 23, + _ => intrinsics::unreachable(), + } +} + +fn main() { + assert_eq!(unsafe { f(17) }, 23); +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-volatile.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-volatile.rs new file mode 100644 index 000000000000..241791cb18ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsic-volatile.rs @@ -0,0 +1,45 @@ +// run-pass + +#![feature(core_intrinsics)] + +use std::intrinsics::*; + +pub fn main() { + unsafe { + let mut x: Box = Box::new(0); + let mut y: Box = Box::new(0); + + // test volatile load + assert_eq!(volatile_load(&*x), 0); + *x = 1; + assert_eq!(volatile_load(&*x), 1); + + // test volatile store + volatile_store(&mut *x, 2); + assert_eq!(*x, 2); + + // test volatile copy memory + volatile_copy_memory(&mut *y, &*x, 1); + assert_eq!(*y, 2); + + // test volatile copy non-overlapping memory + *x = 3; + volatile_copy_nonoverlapping_memory(&mut *y, &*x, 1); + assert_eq!(*y, 3); + + // test volatile set memory + volatile_set_memory(&mut *x, 4, 1); + assert_eq!(*x, 4); + + // test unaligned volatile load + let arr: [u8; 3] = [1, 2, 3]; + let ptr = arr[1..].as_ptr() as *const u16; + assert_eq!(unaligned_volatile_load(ptr), u16::from_ne_bytes([arr[1], arr[2]])); + + // test unaligned volatile store + let ptr = arr[1..].as_ptr() as *mut u16; + unaligned_volatile_store(ptr, 0); + assert_eq!(arr, [1, 0, 0]); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsics-integer.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsics-integer.rs new file mode 100644 index 000000000000..59f2b7d09316 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsics-integer.rs @@ -0,0 +1,172 @@ +// run-pass + +#![feature(intrinsics)] + +mod rusti { + extern "rust-intrinsic" { + pub fn ctpop(x: T) -> T; + pub fn ctlz(x: T) -> T; + pub fn ctlz_nonzero(x: T) -> T; + pub fn cttz(x: T) -> T; + pub fn cttz_nonzero(x: T) -> T; + pub fn bswap(x: T) -> T; + pub fn bitreverse(x: T) -> T; + } +} + +pub fn main() { + use rusti::*; + + assert_eq!(ctpop(0u8), 0); assert_eq!(ctpop(0i8), 0); + assert_eq!(ctpop(0u16), 0); assert_eq!(ctpop(0i16), 0); + assert_eq!(ctpop(0u32), 0); assert_eq!(ctpop(0i32), 0); + assert_eq!(ctpop(0u64), 0); assert_eq!(ctpop(0i64), 0); + assert_eq!(ctpop(0u128), 0); assert_eq!(ctpop(0i128), 0); + + assert_eq!(ctpop(1u8), 1); assert_eq!(ctpop(1i8), 1); + assert_eq!(ctpop(1u16), 1); assert_eq!(ctpop(1i16), 1); + assert_eq!(ctpop(1u32), 1); assert_eq!(ctpop(1i32), 1); + assert_eq!(ctpop(1u64), 1); assert_eq!(ctpop(1i64), 1); + assert_eq!(ctpop(1u128), 1); assert_eq!(ctpop(1i128), 1); + + assert_eq!(ctpop(10u8), 2); assert_eq!(ctpop(10i8), 2); + assert_eq!(ctpop(10u16), 2); assert_eq!(ctpop(10i16), 2); + assert_eq!(ctpop(10u32), 2); assert_eq!(ctpop(10i32), 2); + assert_eq!(ctpop(10u64), 2); assert_eq!(ctpop(10i64), 2); + assert_eq!(ctpop(10u128), 2); assert_eq!(ctpop(10i128), 2); + + assert_eq!(ctpop(100u8), 3); assert_eq!(ctpop(100i8), 3); + assert_eq!(ctpop(100u16), 3); assert_eq!(ctpop(100i16), 3); + assert_eq!(ctpop(100u32), 3); assert_eq!(ctpop(100i32), 3); + assert_eq!(ctpop(100u64), 3); assert_eq!(ctpop(100i64), 3); + assert_eq!(ctpop(100u128), 3); assert_eq!(ctpop(100i128), 3); + + assert_eq!(ctpop(-1i8 as u8), 8); assert_eq!(ctpop(-1i8), 8); + assert_eq!(ctpop(-1i16 as u16), 16); assert_eq!(ctpop(-1i16), 16); + assert_eq!(ctpop(-1i32 as u32), 32); assert_eq!(ctpop(-1i32), 32); + assert_eq!(ctpop(-1i64 as u64), 64); assert_eq!(ctpop(-1i64), 64); + assert_eq!(ctpop(-1i128 as u128), 128); assert_eq!(ctpop(-1i128), 128); + + assert_eq!(ctlz(0u8), 8); assert_eq!(ctlz(0i8), 8); + assert_eq!(ctlz(0u16), 16); assert_eq!(ctlz(0i16), 16); + assert_eq!(ctlz(0u32), 32); assert_eq!(ctlz(0i32), 32); + assert_eq!(ctlz(0u64), 64); assert_eq!(ctlz(0i64), 64); + assert_eq!(ctlz(0u128), 128); assert_eq!(ctlz(0i128), 128); + + assert_eq!(ctlz(1u8), 7); assert_eq!(ctlz(1i8), 7); + assert_eq!(ctlz(1u16), 15); assert_eq!(ctlz(1i16), 15); + assert_eq!(ctlz(1u32), 31); assert_eq!(ctlz(1i32), 31); + assert_eq!(ctlz(1u64), 63); assert_eq!(ctlz(1i64), 63); + assert_eq!(ctlz(1u128), 127); assert_eq!(ctlz(1i128), 127); + + assert_eq!(ctlz(10u8), 4); assert_eq!(ctlz(10i8), 4); + assert_eq!(ctlz(10u16), 12); assert_eq!(ctlz(10i16), 12); + assert_eq!(ctlz(10u32), 28); assert_eq!(ctlz(10i32), 28); + assert_eq!(ctlz(10u64), 60); assert_eq!(ctlz(10i64), 60); + assert_eq!(ctlz(10u128), 124); assert_eq!(ctlz(10i128), 124); + + assert_eq!(ctlz(100u8), 1); assert_eq!(ctlz(100i8), 1); + assert_eq!(ctlz(100u16), 9); assert_eq!(ctlz(100i16), 9); + assert_eq!(ctlz(100u32), 25); assert_eq!(ctlz(100i32), 25); + assert_eq!(ctlz(100u64), 57); assert_eq!(ctlz(100i64), 57); + assert_eq!(ctlz(100u128), 121); assert_eq!(ctlz(100i128), 121); + + unsafe { + assert_eq!(ctlz_nonzero(1u8), 7); assert_eq!(ctlz_nonzero(1i8), 7); + assert_eq!(ctlz_nonzero(1u16), 15); assert_eq!(ctlz_nonzero(1i16), 15); + assert_eq!(ctlz_nonzero(1u32), 31); assert_eq!(ctlz_nonzero(1i32), 31); + assert_eq!(ctlz_nonzero(1u64), 63); assert_eq!(ctlz_nonzero(1i64), 63); + assert_eq!(ctlz_nonzero(1u128), 127); assert_eq!(ctlz_nonzero(1i128), 127); + + assert_eq!(ctlz_nonzero(10u8), 4); assert_eq!(ctlz_nonzero(10i8), 4); + assert_eq!(ctlz_nonzero(10u16), 12); assert_eq!(ctlz_nonzero(10i16), 12); + assert_eq!(ctlz_nonzero(10u32), 28); assert_eq!(ctlz_nonzero(10i32), 28); + assert_eq!(ctlz_nonzero(10u64), 60); assert_eq!(ctlz_nonzero(10i64), 60); + assert_eq!(ctlz_nonzero(10u128), 124); assert_eq!(ctlz_nonzero(10i128), 124); + + assert_eq!(ctlz_nonzero(100u8), 1); assert_eq!(ctlz_nonzero(100i8), 1); + assert_eq!(ctlz_nonzero(100u16), 9); assert_eq!(ctlz_nonzero(100i16), 9); + assert_eq!(ctlz_nonzero(100u32), 25); assert_eq!(ctlz_nonzero(100i32), 25); + assert_eq!(ctlz_nonzero(100u64), 57); assert_eq!(ctlz_nonzero(100i64), 57); + assert_eq!(ctlz_nonzero(100u128), 121); assert_eq!(ctlz_nonzero(100i128), 121); + } + + assert_eq!(cttz(-1i8 as u8), 0); assert_eq!(cttz(-1i8), 0); + assert_eq!(cttz(-1i16 as u16), 0); assert_eq!(cttz(-1i16), 0); + assert_eq!(cttz(-1i32 as u32), 0); assert_eq!(cttz(-1i32), 0); + assert_eq!(cttz(-1i64 as u64), 0); assert_eq!(cttz(-1i64), 0); + assert_eq!(cttz(-1i128 as u128), 0); assert_eq!(cttz(-1i128), 0); + + assert_eq!(cttz(0u8), 8); assert_eq!(cttz(0i8), 8); + assert_eq!(cttz(0u16), 16); assert_eq!(cttz(0i16), 16); + assert_eq!(cttz(0u32), 32); assert_eq!(cttz(0i32), 32); + assert_eq!(cttz(0u64), 64); assert_eq!(cttz(0i64), 64); + assert_eq!(cttz(0u128), 128); assert_eq!(cttz(0i128), 128); + + assert_eq!(cttz(1u8), 0); assert_eq!(cttz(1i8), 0); + assert_eq!(cttz(1u16), 0); assert_eq!(cttz(1i16), 0); + assert_eq!(cttz(1u32), 0); assert_eq!(cttz(1i32), 0); + assert_eq!(cttz(1u64), 0); assert_eq!(cttz(1i64), 0); + assert_eq!(cttz(1u128), 0); assert_eq!(cttz(1i128), 0); + + assert_eq!(cttz(10u8), 1); assert_eq!(cttz(10i8), 1); + assert_eq!(cttz(10u16), 1); assert_eq!(cttz(10i16), 1); + assert_eq!(cttz(10u32), 1); assert_eq!(cttz(10i32), 1); + assert_eq!(cttz(10u64), 1); assert_eq!(cttz(10i64), 1); + assert_eq!(cttz(10u128), 1); assert_eq!(cttz(10i128), 1); + + assert_eq!(cttz(100u8), 2); assert_eq!(cttz(100i8), 2); + assert_eq!(cttz(100u16), 2); assert_eq!(cttz(100i16), 2); + assert_eq!(cttz(100u32), 2); assert_eq!(cttz(100i32), 2); + assert_eq!(cttz(100u64), 2); assert_eq!(cttz(100i64), 2); + assert_eq!(cttz(100u128), 2); assert_eq!(cttz(100i128), 2); + + unsafe { + assert_eq!(cttz_nonzero(-1i8 as u8), 0); assert_eq!(cttz_nonzero(-1i8), 0); + assert_eq!(cttz_nonzero(-1i16 as u16), 0); assert_eq!(cttz_nonzero(-1i16), 0); + assert_eq!(cttz_nonzero(-1i32 as u32), 0); assert_eq!(cttz_nonzero(-1i32), 0); + assert_eq!(cttz_nonzero(-1i64 as u64), 0); assert_eq!(cttz_nonzero(-1i64), 0); + assert_eq!(cttz_nonzero(-1i128 as u128), 0); assert_eq!(cttz_nonzero(-1i128), 0); + + assert_eq!(cttz_nonzero(1u8), 0); assert_eq!(cttz_nonzero(1i8), 0); + assert_eq!(cttz_nonzero(1u16), 0); assert_eq!(cttz_nonzero(1i16), 0); + assert_eq!(cttz_nonzero(1u32), 0); assert_eq!(cttz_nonzero(1i32), 0); + assert_eq!(cttz_nonzero(1u64), 0); assert_eq!(cttz_nonzero(1i64), 0); + assert_eq!(cttz_nonzero(1u128), 0); assert_eq!(cttz_nonzero(1i128), 0); + + assert_eq!(cttz_nonzero(10u8), 1); assert_eq!(cttz_nonzero(10i8), 1); + assert_eq!(cttz_nonzero(10u16), 1); assert_eq!(cttz_nonzero(10i16), 1); + assert_eq!(cttz_nonzero(10u32), 1); assert_eq!(cttz_nonzero(10i32), 1); + assert_eq!(cttz_nonzero(10u64), 1); assert_eq!(cttz_nonzero(10i64), 1); + assert_eq!(cttz_nonzero(10u128), 1); assert_eq!(cttz_nonzero(10i128), 1); + + assert_eq!(cttz_nonzero(100u8), 2); assert_eq!(cttz_nonzero(100i8), 2); + assert_eq!(cttz_nonzero(100u16), 2); assert_eq!(cttz_nonzero(100i16), 2); + assert_eq!(cttz_nonzero(100u32), 2); assert_eq!(cttz_nonzero(100i32), 2); + assert_eq!(cttz_nonzero(100u64), 2); assert_eq!(cttz_nonzero(100i64), 2); + assert_eq!(cttz_nonzero(100u128), 2); assert_eq!(cttz_nonzero(100i128), 2); + } + + assert_eq!(bswap(0x0Au8), 0x0A); // no-op + assert_eq!(bswap(0x0Ai8), 0x0A); // no-op + assert_eq!(bswap(0x0A0Bu16), 0x0B0A); + assert_eq!(bswap(0x0A0Bi16), 0x0B0A); + assert_eq!(bswap(0x0ABBCC0Du32), 0x0DCCBB0A); + assert_eq!(bswap(0x0ABBCC0Di32), 0x0DCCBB0A); + assert_eq!(bswap(0x0122334455667708u64), 0x0877665544332201); + assert_eq!(bswap(0x0122334455667708i64), 0x0877665544332201); + assert_eq!(bswap(0x0122334455667708u128), 0x08776655443322010000000000000000); + assert_eq!(bswap(0x0122334455667708i128), 0x08776655443322010000000000000000); + + assert_eq!(bitreverse(0x0Au8), 0x50); + assert_eq!(bitreverse(0x0Ai8), 0x50); + assert_eq!(bitreverse(0x0A0Cu16), 0x3050); + assert_eq!(bitreverse(0x0A0Ci16), 0x3050); + assert_eq!(bitreverse(0x0ABBCC0Eu32), 0x7033DD50); + assert_eq!(bitreverse(0x0ABBCC0Ei32), 0x7033DD50); + assert_eq!(bitreverse(0x0122334455667708u64), 0x10EE66AA22CC4480); + assert_eq!(bitreverse(0x0122334455667708i64), 0x10EE66AA22CC4480); + assert_eq!(bitreverse(0x0122334455667708u128), 0x10EE66AA22CC44800000000000000000); + assert_eq!(bitreverse(0x0122334455667708i128), 0x10EE66AA22CC44800000000000000000); +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsics-math.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsics-math.rs new file mode 100644 index 000000000000..f03fa8b3ab25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/intrinsics-math.rs @@ -0,0 +1,61 @@ +// run-pass +// ignore-emscripten fma not implemented in emscripten + +macro_rules! assert_approx_eq { + ($a:expr, $b:expr) => ({ + let (a, b) = (&$a, &$b); + assert!((*a - *b).abs() < 1.0e-6, + "{} is not approximately equal to {}", *a, *b); + }) +} + +pub fn main() { + use std::f32; + use std::f64; + + assert_approx_eq!(64f32.sqrt(), 8f32); + assert_approx_eq!(64f64.sqrt(), 8f64); + + assert_approx_eq!(25f32.powi(-2), 0.0016f32); + assert_approx_eq!(23.2f64.powi(2), 538.24f64); + + assert_approx_eq!(0f32.sin(), 0f32); + assert_approx_eq!((f64::consts::PI / 2f64).sin(), 1f64); + + assert_approx_eq!(0f32.cos(), 1f32); + assert_approx_eq!((f64::consts::PI * 2f64).cos(), 1f64); + + assert_approx_eq!(25f32.powf(-2f32), 0.0016f32); + assert_approx_eq!(400f64.powf(0.5f64), 20f64); + + assert_approx_eq!((1f32.exp() - f32::consts::E).abs(), 0f32); + assert_approx_eq!(1f64.exp(), f64::consts::E); + + assert_approx_eq!(10f32.exp2(), 1024f32); + assert_approx_eq!(50f64.exp2(), 1125899906842624f64); + + assert_approx_eq!((f32::consts::E.ln() - 1f32).abs(), 0f32); + assert_approx_eq!(1f64.ln(), 0f64); + + assert_approx_eq!(10f32.log10(), 1f32); + assert_approx_eq!(f64::consts::E.log10(), f64::consts::LOG10_E); + + assert_approx_eq!(8f32.log2(), 3f32); + assert_approx_eq!(f64::consts::E.log2(), f64::consts::LOG2_E); + + assert_approx_eq!(1.0f32.mul_add(2.0f32, 5.0f32), 7.0f32); + assert_approx_eq!(0.0f64.mul_add(-2.0f64, f64::consts::E), f64::consts::E); + + assert_approx_eq!((-1.0f32).abs(), 1.0f32); + assert_approx_eq!(34.2f64.abs(), 34.2f64); + + assert_approx_eq!(3.8f32.floor(), 3.0f32); + assert_approx_eq!((-1.1f64).floor(), -2.0f64); + + assert_approx_eq!((-2.3f32).ceil(), -2.0f32); + assert_approx_eq!(3.8f64.ceil(), 4.0f64); + + assert_approx_eq!(0.1f32.trunc(), 0.0f32); + assert_approx_eq!((-0.1f64).trunc(), 0.0f64); +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/issue-28575.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/issue-28575.rs new file mode 100644 index 000000000000..26d6f31dacfa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/issue-28575.rs @@ -0,0 +1,10 @@ +#![feature(intrinsics)] + +extern "C" { + pub static FOO: extern "rust-intrinsic" fn(); +} + +fn main() { + FOO() // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/panic-uninitialized-zeroed.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/panic-uninitialized-zeroed.rs new file mode 100644 index 000000000000..dcb491c52a6c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/panic-uninitialized-zeroed.rs @@ -0,0 +1,207 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default + +// This test checks panic emitted from `mem::{uninitialized,zeroed}`. + +#![feature(never_type, arbitrary_enum_discriminant)] +#![allow(deprecated, invalid_value)] + +use std::{ + mem::{self, MaybeUninit, ManuallyDrop}, + panic, + ptr::NonNull, + num, +}; + +#[allow(dead_code)] +struct Foo { + x: u8, + y: !, +} + +enum Bar {} + +#[allow(dead_code)] +enum OneVariant { Variant(i32) } + +#[allow(dead_code, non_camel_case_types)] +enum OneVariant_NonZero { + Variant(i32, i32, num::NonZeroI32), + DeadVariant(Bar), +} + +// An `Aggregate` abi enum where 0 is not a valid discriminant. +#[allow(dead_code)] +#[repr(i32)] +enum NoNullVariant { + Variant1(i32, i32) = 1, + Variant2(i32, i32) = 2, +} + +// An enum with ScalarPair layout +#[allow(dead_code)] +enum LR { + Left(i64), + Right(i64), +} +#[allow(dead_code, non_camel_case_types)] +enum LR_NonZero { + Left(num::NonZeroI64), + Right(num::NonZeroI64), +} + +fn test_panic_msg(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) { + let err = panic::catch_unwind(op).err(); + assert_eq!( + err.as_ref().and_then(|a| a.downcast_ref::<&str>()), + Some(&msg) + ); +} + +fn main() { + unsafe { + // Uninhabited types + test_panic_msg( + || mem::uninitialized::(), + "attempted to instantiate uninhabited type `!`" + ); + test_panic_msg( + || mem::zeroed::(), + "attempted to instantiate uninhabited type `!`" + ); + test_panic_msg( + || MaybeUninit::::uninit().assume_init(), + "attempted to instantiate uninhabited type `!`" + ); + + test_panic_msg( + || mem::uninitialized::(), + "attempted to instantiate uninhabited type `Foo`" + ); + test_panic_msg( + || mem::zeroed::(), + "attempted to instantiate uninhabited type `Foo`" + ); + test_panic_msg( + || MaybeUninit::::uninit().assume_init(), + "attempted to instantiate uninhabited type `Foo`" + ); + + test_panic_msg( + || mem::uninitialized::(), + "attempted to instantiate uninhabited type `Bar`" + ); + test_panic_msg( + || mem::zeroed::(), + "attempted to instantiate uninhabited type `Bar`" + ); + test_panic_msg( + || MaybeUninit::::uninit().assume_init(), + "attempted to instantiate uninhabited type `Bar`" + ); + + // Types that do not like zero-initialziation + test_panic_msg( + || mem::uninitialized::(), + "attempted to leave type `fn()` uninitialized, which is invalid" + ); + test_panic_msg( + || mem::zeroed::(), + "attempted to zero-initialize type `fn()`, which is invalid" + ); + + test_panic_msg( + || mem::uninitialized::<*const dyn Send>(), + "attempted to leave type `*const dyn std::marker::Send` uninitialized, which is invalid" + ); + test_panic_msg( + || mem::zeroed::<*const dyn Send>(), + "attempted to zero-initialize type `*const dyn std::marker::Send`, which is invalid" + ); + + /* FIXME(#66151) we conservatively do not error here yet. + test_panic_msg( + || mem::uninitialized::(), + "attempted to leave type `LR_NonZero` uninitialized, which is invalid" + ); + test_panic_msg( + || mem::zeroed::(), + "attempted to zero-initialize type `LR_NonZero`, which is invalid" + ); + + test_panic_msg( + || mem::uninitialized::>(), + "attempted to leave type `std::mem::ManuallyDrop` uninitialized, \ + which is invalid" + ); + test_panic_msg( + || mem::zeroed::>(), + "attempted to zero-initialize type `std::mem::ManuallyDrop`, \ + which is invalid" + ); + */ + + test_panic_msg( + || mem::uninitialized::<(NonNull, u32, u32)>(), + "attempted to leave type `(std::ptr::NonNull, u32, u32)` uninitialized, \ + which is invalid" + ); + test_panic_msg( + || mem::zeroed::<(NonNull, u32, u32)>(), + "attempted to zero-initialize type `(std::ptr::NonNull, u32, u32)`, \ + which is invalid" + ); + + test_panic_msg( + || mem::uninitialized::(), + "attempted to leave type `OneVariant_NonZero` uninitialized, \ + which is invalid" + ); + test_panic_msg( + || mem::zeroed::(), + "attempted to zero-initialize type `OneVariant_NonZero`, \ + which is invalid" + ); + + test_panic_msg( + || mem::uninitialized::(), + "attempted to leave type `NoNullVariant` uninitialized, \ + which is invalid" + ); + test_panic_msg( + || mem::zeroed::(), + "attempted to zero-initialize type `NoNullVariant`, \ + which is invalid" + ); + + // Types that can be zero, but not uninit. + test_panic_msg( + || mem::uninitialized::(), + "attempted to leave type `bool` uninitialized, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::(), + "attempted to leave type `LR` uninitialized, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::>(), + "attempted to leave type `std::mem::ManuallyDrop` uninitialized, which is invalid" + ); + + // Some things that should work. + let _val = mem::zeroed::(); + let _val = mem::zeroed::(); + let _val = mem::zeroed::>(); + let _val = mem::zeroed::(); + let _val = mem::zeroed::>(); + let _val = mem::zeroed::>>(); + let _val = mem::uninitialized::>(); + + // These are UB because they have not been officially blessed, but we await the resolution + // of before doing + // anything about that. + let _val = mem::uninitialized::(); + let _val = mem::uninitialized::<*const ()>(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/unchecked_math_unsafe.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/unchecked_math_unsafe.rs new file mode 100644 index 000000000000..f8a82e2d3042 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/unchecked_math_unsafe.rs @@ -0,0 +1,9 @@ +#![feature(core_intrinsics)] + +fn main() { + let (x, y) = (1u32, 2u32); + let add = std::intrinsics::unchecked_add(x, y); // { dg-error ".E0133." "" { target *-*-* } } + let sub = std::intrinsics::unchecked_sub(x, y); // { dg-error ".E0133." "" { target *-*-* } } + let mul = std::intrinsics::unchecked_mul(x, y); // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/intrinsics/unchecked_math_unstable.rs b/gcc/testsuite/rust/rustc/ui/intrinsics/unchecked_math_unstable.rs new file mode 100644 index 000000000000..b1f1fd59982a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/intrinsics/unchecked_math_unstable.rs @@ -0,0 +1,9 @@ +fn main() { + let (x, y) = (1u32, 2u32); + unsafe { + let add = std::intrinsics::unchecked_add(x, y); // { dg-error ".E0658." "" { target *-*-* } } + let sub = std::intrinsics::unchecked_sub(x, y); // { dg-error ".E0658." "" { target *-*-* } } + let mul = std::intrinsics::unchecked_mul(x, y); // { dg-error ".E0658." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/invalid-module-declaration/auxiliary/foo/bar.rs b/gcc/testsuite/rust/rustc/ui/invalid-module-declaration/auxiliary/foo/bar.rs new file mode 100644 index 000000000000..dd041640470e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid-module-declaration/auxiliary/foo/bar.rs @@ -0,0 +1,2 @@ +pub mod baz; + diff --git a/gcc/testsuite/rust/rustc/ui/invalid-module-declaration/auxiliary/foo/mod.rs b/gcc/testsuite/rust/rustc/ui/invalid-module-declaration/auxiliary/foo/mod.rs new file mode 100644 index 000000000000..998b02010fb5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid-module-declaration/auxiliary/foo/mod.rs @@ -0,0 +1,2 @@ +pub mod bar; + diff --git a/gcc/testsuite/rust/rustc/ui/invalid-module-declaration/invalid-module-declaration.rs b/gcc/testsuite/rust/rustc/ui/invalid-module-declaration/invalid-module-declaration.rs new file mode 100644 index 000000000000..5b6f63f83aa6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid-module-declaration/invalid-module-declaration.rs @@ -0,0 +1,6 @@ +mod auxiliary { + mod foo; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/invalid-rustc_args_required_const-arguments.rs b/gcc/testsuite/rust/rustc/ui/invalid-rustc_args_required_const-arguments.rs new file mode 100644 index 000000000000..0077efa3cea7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid-rustc_args_required_const-arguments.rs @@ -0,0 +1,27 @@ +#![feature(rustc_attrs)] + +#[rustc_args_required_const(0)] // { dg-error "" "" { target *-*-* } } +fn foo1() {} + +#[rustc_args_required_const(1)] // { dg-error "" "" { target *-*-* } } +fn foo2(_: u8) {} + +#[rustc_args_required_const(a)] // { dg-error "" "" { target *-*-* } } +fn foo4() {} + +#[rustc_args_required_const(1, a, 2, b)] // { dg-error "" "" { target *-*-* } } +fn foo5(_: u8, _: u8, _: u8) {} + +#[rustc_args_required_const(0)] // { dg-error "" "" { target *-*-* } } +struct S; + +#[rustc_args_required_const(0usize)] // { dg-error "" "" { target *-*-* } } +fn foo6(_: u8) {} + +extern { + #[rustc_args_required_const(1)] // { dg-error "" "" { target *-*-* } } + fn foo7(_: u8); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/invalid-self-argument/bare-fn-start.rs b/gcc/testsuite/rust/rustc/ui/invalid-self-argument/bare-fn-start.rs new file mode 100644 index 000000000000..31b52a841952 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid-self-argument/bare-fn-start.rs @@ -0,0 +1,7 @@ +fn a(&self) { } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/invalid-self-argument/bare-fn.rs b/gcc/testsuite/rust/rustc/ui/invalid-self-argument/bare-fn.rs new file mode 100644 index 000000000000..f0c2fdf275a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid-self-argument/bare-fn.rs @@ -0,0 +1,6 @@ +fn b(foo: u32, &mut self) { } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/invalid-self-argument/trait-fn.rs b/gcc/testsuite/rust/rustc/ui/invalid-self-argument/trait-fn.rs new file mode 100644 index 000000000000..0b88874efb82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid-self-argument/trait-fn.rs @@ -0,0 +1,12 @@ +struct Foo {} + +impl Foo { + fn c(foo: u32, self) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + + fn good(&mut self, foo: u32) {} +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/invalid/invalid-crate-type.rs b/gcc/testsuite/rust/rustc/ui/invalid/invalid-crate-type.rs new file mode 100644 index 000000000000..30ba68c3a29c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid/invalid-crate-type.rs @@ -0,0 +1,49 @@ +// regression test for issue 11256 +#![crate_type="foo"] // { dg-error "" "" { target *-*-* } } + +// Tests for suggestions (#53958) + +#![crate_type="statoclib"] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +#![crate_type="procmacro"] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +#![crate_type="static-lib"] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +#![crate_type="drylib"] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +#![crate_type="dlib"] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +#![crate_type="lob"] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +#![crate_type="bon"] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +#![crate_type="cdalib"] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +fn main() { + return +} + diff --git a/gcc/testsuite/rust/rustc/ui/invalid/invalid-inline.rs b/gcc/testsuite/rust/rustc/ui/invalid/invalid-inline.rs new file mode 100644 index 000000000000..81ce04519c1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid/invalid-inline.rs @@ -0,0 +1,20 @@ +#![allow(dead_code)] + +#[inline(please_no)] // { dg-error ".E0535." "" { target *-*-* } } +fn a() { +} + +#[inline(please,no)] // { dg-error ".E0534." "" { target *-*-* } } +fn b() { +} + +#[inline()] // { dg-error ".E0534." "" { target *-*-* } } +fn c() { +} + +fn main() { + a(); + b(); + c(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/invalid/invalid-macro-matcher.rs b/gcc/testsuite/rust/rustc/ui/invalid/invalid-macro-matcher.rs new file mode 100644 index 000000000000..38faf52fb66c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid/invalid-macro-matcher.rs @@ -0,0 +1,9 @@ +#![allow(unused_macros)] + +macro_rules! invalid { + _ => (); // { dg-error "" "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/invalid/invalid-no-sanitize.rs b/gcc/testsuite/rust/rustc/ui/invalid/invalid-no-sanitize.rs new file mode 100644 index 000000000000..d6ff0dc97968 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid/invalid-no-sanitize.rs @@ -0,0 +1,6 @@ +#![feature(no_sanitize)] + +#[no_sanitize(brontosaurus)] // { dg-error "" "" { target *-*-* } } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/invalid/invalid-path-in-const.rs b/gcc/testsuite/rust/rustc/ui/invalid/invalid-path-in-const.rs new file mode 100644 index 000000000000..a7d3cdcb63f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid/invalid-path-in-const.rs @@ -0,0 +1,5 @@ +fn main() { + fn f(a: [u8; u32::DOESNOTEXIST]) {} +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/invalid/invalid-plugin-attr.rs b/gcc/testsuite/rust/rustc/ui/invalid/invalid-plugin-attr.rs new file mode 100644 index 000000000000..fb11bc5644e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid/invalid-plugin-attr.rs @@ -0,0 +1,9 @@ +#![deny(unused_attributes)] +#![feature(plugin)] + +#[plugin(bla)] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/invalid_crate_type_syntax.rs b/gcc/testsuite/rust/rustc/ui/invalid_crate_type_syntax.rs new file mode 100644 index 000000000000..e0c6343740d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid_crate_type_syntax.rs @@ -0,0 +1,7 @@ +// regression test for issue 16974 +#![crate_type(lib)] // { dg-error "" "" { target *-*-* } } + +fn my_lib_fn() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/invalid_dispatch_from_dyn_impls.rs b/gcc/testsuite/rust/rustc/ui/invalid_dispatch_from_dyn_impls.rs new file mode 100644 index 000000000000..709f54ff1b8b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/invalid_dispatch_from_dyn_impls.rs @@ -0,0 +1,52 @@ +#![feature(unsize, dispatch_from_dyn)] + +use std::{ + ops::DispatchFromDyn, + marker::{Unsize, PhantomData}, +}; + +struct WrapperWithExtraField(T, i32); + +impl DispatchFromDyn> for WrapperWithExtraField +where + T: DispatchFromDyn, +// { dg-error ".E0378." "" { target *-*-* } .-3 } + + +struct MultiplePointers{ + ptr1: *const T, + ptr2: *const T, +} + +impl DispatchFromDyn> for MultiplePointers +where + T: Unsize, +// { dg-error ".E0378." "" { target *-*-* } .-3 } + + +struct NothingToCoerce { + data: PhantomData, +} + +impl DispatchFromDyn> for NothingToCoerce {} +// { dg-error ".E0378." "" { target *-*-* } .-1 } + +#[repr(C)] +struct HasReprC(Box); + +impl DispatchFromDyn> for HasReprC +where + T: Unsize, +// { dg-error ".E0378." "" { target *-*-* } .-3 } + +#[repr(align(64))] +struct OverAlignedZst; +struct OverAligned(Box, OverAlignedZst); + +impl DispatchFromDyn> for OverAligned + where + T: Unsize, +// { dg-error ".E0378." "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issue-72470-llvm-dominate.rs b/gcc/testsuite/rust/rustc/ui/issue-72470-llvm-dominate.rs new file mode 100644 index 000000000000..c63d1c095f47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issue-72470-llvm-dominate.rs @@ -0,0 +1,67 @@ +// compile-flags: -C opt-level=3 +// aux-build: issue-72470-lib.rs +// edition:2018 +// build-pass + +// Regression test for issue #72470, using the minimization +// in https://github.com/jonas-schievink/llvm-error + +extern crate issue_72470_lib; + +use std::future::Future; +use std::pin::Pin; +use std::sync::Mutex; +use std::task::Poll::{Pending, Ready}; + +#[allow(dead_code)] +enum Msg { + A(Vec<()>), + B, +} + +#[allow(dead_code)] +enum Out { + _0(Option), + Disabled, +} + +#[allow(unused_must_use)] +fn main() { + let mut rx = issue_72470_lib::unbounded_channel::(); + let entity = Mutex::new(()); + issue_72470_lib::run(async move { + { + let output = { + let mut fut = rx.recv(); + issue_72470_lib::poll_fn(|cx| { + loop { + let fut = unsafe { Pin::new_unchecked(&mut fut) }; + let out = match fut.poll(cx) { + Ready(out) => out, + Pending => { + break; + } + }; + #[allow(unused_variables)] + match &out { + Some(_msg) => {} + _ => break, + } + return Ready(Out::_0(out)); + } + Ready(Out::_0(None)) + }) + .await + }; + match output { + Out::_0(Some(_msg)) => { + entity.lock(); + } + Out::_0(None) => unreachable!(), + _ => unreachable!(), + } + } + entity.lock(); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issue-73914.rs b/gcc/testsuite/rust/rustc/ui/issue-73914.rs new file mode 100644 index 000000000000..af840a5f6516 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issue-73914.rs @@ -0,0 +1,31 @@ +// build-pass +// compile-flags:-Copt-level=0 +// edition:2018 + +struct S(std::marker::PhantomData); + +impl std::ops::Deref for S { + type Target = T; + + fn deref(&self) -> &Self::Target { + todo!() + } +} +impl std::ops::DerefMut for S { + fn deref_mut(&mut self) -> &mut Self::Target { + todo!() + } +} + +async fn new() -> S { + todo!() +} + +async fn crash() { + *new().await = 1 + 1; +} + +fn main() { + let _ = crash(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issue-74047.rs b/gcc/testsuite/rust/rustc/ui/issue-74047.rs new file mode 100644 index 000000000000..3f49150e521a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issue-74047.rs @@ -0,0 +1,18 @@ +// edition:2018 + +use std::convert::{TryFrom, TryInto}; +use std::io; + +pub struct MyStream; +pub struct OtherStream; + +pub async fn connect() -> io::Result { + let stream: MyStream = OtherStream.try_into()?; + Ok(stream) +} + +impl TryFrom for MyStream {} +// { dg-error ".E0046." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issue-76387-llvm-miscompile.rs b/gcc/testsuite/rust/rustc/ui/issue-76387-llvm-miscompile.rs new file mode 100644 index 000000000000..fa161aaaace5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issue-76387-llvm-miscompile.rs @@ -0,0 +1,23 @@ +// no-system-llvm +// compile-flags: -C opt-level=3 +// aux-build: issue-76387.rs +// run-pass + +// Regression test for issue #76387 +// Tests that LLVM doesn't miscompile this + +extern crate issue_76387; + +use issue_76387::FatPtr; + +fn print(data: &[u8]) { + println!("{:#?}", data); +} + +fn main() { + let ptr = FatPtr::new(20); + let data = unsafe { std::slice::from_raw_parts(ptr.as_ptr(), ptr.len()) }; + + print(data); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issue-76597.rs b/gcc/testsuite/rust/rustc/ui/issue-76597.rs new file mode 100644 index 000000000000..badf378141be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issue-76597.rs @@ -0,0 +1,12 @@ +// run-rustfix + +#![allow(dead_code)] +#![allow(unused_variables)] +fn f( + x: u8 + y: u8, +) {} +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues-71798.rs b/gcc/testsuite/rust/rustc/ui/issues-71798.rs new file mode 100644 index 000000000000..7f7a18b8a9c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues-71798.rs @@ -0,0 +1,8 @@ +fn test_ref(x: &u32) -> impl std::future::Future + '_ { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { + let _ = test_ref & u; // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/cgu_test.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/cgu_test.rs new file mode 100644 index 000000000000..4c00e01fd8d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/cgu_test.rs @@ -0,0 +1,7 @@ +// no-prefer-dynamic +// compile-flags: --crate-type=lib + +pub fn id(t: T) -> T { + t +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/cgu_test_a.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/cgu_test_a.rs new file mode 100644 index 000000000000..d1d568b028c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/cgu_test_a.rs @@ -0,0 +1,16 @@ +// no-prefer-dynamic +// compile-flags: -Ccodegen-units=2 --crate-type=lib + +extern crate cgu_test; + +pub mod a { + pub fn a() { + ::cgu_test::id(0); + } +} +pub mod b { + pub fn a() { + ::cgu_test::id(0); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/cgu_test_b.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/cgu_test_b.rs new file mode 100644 index 000000000000..d1d568b028c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/cgu_test_b.rs @@ -0,0 +1,16 @@ +// no-prefer-dynamic +// compile-flags: -Ccodegen-units=2 --crate-type=lib + +extern crate cgu_test; + +pub mod a { + pub fn a() { + ::cgu_test::id(0); + } +} +pub mod b { + pub fn a() { + ::cgu_test::id(0); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/empty-struct.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/empty-struct.rs new file mode 100644 index 000000000000..8972f6e406ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/empty-struct.rs @@ -0,0 +1,10 @@ +pub struct XEmpty1 {} +pub struct XEmpty2; +pub struct XEmpty6(); + +pub enum XE { + XEmpty3 {}, + XEmpty4, + XEmpty5(), +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/i8.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/i8.rs new file mode 100644 index 000000000000..c8401651ef1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/i8.rs @@ -0,0 +1,4 @@ +// A crate named after a built-in type. + +pub struct Test; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/iss.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/iss.rs new file mode 100644 index 000000000000..5723ab89d13e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/iss.rs @@ -0,0 +1,13 @@ +#![crate_name="issue6919_3"] + +// part of issue-6919.rs + +pub struct C where K: FnOnce() { + pub k: K, +} + +fn no_op() { } +pub const D : C = C { + k: no_op as fn() +}; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-10028.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-10028.rs new file mode 100644 index 000000000000..c7d3fb2f18ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-10028.rs @@ -0,0 +1,10 @@ +pub struct ZeroLengthThingWithDestructor; +impl Drop for ZeroLengthThingWithDestructor { + fn drop(&mut self) {} +} +impl ZeroLengthThingWithDestructor { + pub fn new() -> ZeroLengthThingWithDestructor { + ZeroLengthThingWithDestructor + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-10031-aux.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-10031-aux.rs new file mode 100644 index 000000000000..ca7c25e682d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-10031-aux.rs @@ -0,0 +1,2 @@ +pub struct Wrap(pub A); + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11224.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11224.rs new file mode 100644 index 000000000000..c2e42badd1ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11224.rs @@ -0,0 +1,17 @@ +#![deny(dead_code)] + +mod inner { + pub trait Trait { + fn f(&self) { f(); } + } + + impl Trait for isize {} + + fn f() {} +} + +pub fn foo() { + let a = &1isize as &inner::Trait; + a.f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11225-1.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11225-1.rs new file mode 100644 index 000000000000..07d92fea625e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11225-1.rs @@ -0,0 +1,19 @@ +mod inner { + pub trait Trait { + fn f(&self) { f(); } + fn f_ufcs(&self) { f_ufcs(); } + } + + impl Trait for isize {} + + fn f() {} + fn f_ufcs() {} +} + +pub fn foo(t: T) { + t.f(); +} +pub fn foo_ufcs(t: T) { + T::f_ufcs(&t); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11225-2.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11225-2.rs new file mode 100644 index 000000000000..16d01194656a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11225-2.rs @@ -0,0 +1,29 @@ +use inner::Trait; + +mod inner { + pub struct Foo; + pub trait Trait { + fn f(&self); + fn f_ufcs(&self); + } + + impl Trait for Foo { + fn f(&self) { } + fn f_ufcs(&self) { } + } +} + +pub trait Outer { + fn foo(&self, t: T) { t.f(); } + fn foo_ufcs(&self, t: T) { T::f(&t); } +} + +impl Outer for isize {} + +pub fn foo(t: T) { + t.foo(inner::Foo); +} +pub fn foo_ufcs(t: T) { + T::foo_ufcs(&t, inner::Foo) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11225-3.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11225-3.rs new file mode 100644 index 000000000000..5876da1c462e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11225-3.rs @@ -0,0 +1,29 @@ +trait PrivateTrait { + fn private_trait_method(&self); + fn private_trait_method_ufcs(&self); +} + +struct PrivateStruct; + +impl PrivateStruct { + fn private_inherent_method(&self) { } + fn private_inherent_method_ufcs(&self) { } +} + +impl PrivateTrait for PrivateStruct { + fn private_trait_method(&self) { } + fn private_trait_method_ufcs(&self) { } +} + +#[inline] +pub fn public_inlinable_function() { + PrivateStruct.private_trait_method(); + PrivateStruct.private_inherent_method(); +} + +#[inline] +pub fn public_inlinable_function_ufcs() { + PrivateStruct::private_trait_method(&PrivateStruct); + PrivateStruct::private_inherent_method(&PrivateStruct); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11508.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11508.rs new file mode 100644 index 000000000000..4379f682b4cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11508.rs @@ -0,0 +1,11 @@ +pub struct Closed01(pub F); + +pub trait Bar { fn new() -> Self; } + +impl Bar for Closed01 { + fn new() -> Closed01 { Closed01(Bar::new()) } +} +impl Bar for f32 { fn new() -> f32 { 1.0 } } + +pub fn random() -> T { Bar::new() } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11529.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11529.rs new file mode 100644 index 000000000000..15fcf887d2d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11529.rs @@ -0,0 +1,2 @@ +pub struct A<'a>(pub &'a isize); + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11680.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11680.rs new file mode 100644 index 000000000000..e93833beb012 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-11680.rs @@ -0,0 +1,10 @@ +enum Foo { + Bar(isize) +} + +pub mod test { + enum Foo { + Bar(isize) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12133-dylib.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12133-dylib.rs new file mode 100644 index 000000000000..e989d944d251 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12133-dylib.rs @@ -0,0 +1,2 @@ +#![crate_type = "dylib"] + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12133-dylib2.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12133-dylib2.rs new file mode 100644 index 000000000000..962cd427c303 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12133-dylib2.rs @@ -0,0 +1,7 @@ +// no-prefer-dynamic + +#![crate_type = "dylib"] + +extern crate issue_12133_rlib as a; +extern crate issue_12133_dylib as b; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12133-rlib.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12133-rlib.rs new file mode 100644 index 000000000000..89588437fc99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12133-rlib.rs @@ -0,0 +1,4 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12612-1.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12612-1.rs new file mode 100644 index 000000000000..9e4521e4f0f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12612-1.rs @@ -0,0 +1,4 @@ +pub mod bar { + pub fn foo() {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12612-2.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12612-2.rs new file mode 100644 index 000000000000..0bc0b7e829da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12612-2.rs @@ -0,0 +1,2 @@ +pub fn baz() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12660-aux.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12660-aux.rs new file mode 100644 index 000000000000..693121dc3cb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-12660-aux.rs @@ -0,0 +1,12 @@ +#![crate_type="lib"] +#![crate_name="issue12660aux"] + +pub use my_mod::{MyStruct, my_fn}; + +mod my_mod { + pub struct MyStruct; + + pub fn my_fn(my_struct: MyStruct) { + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13507.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13507.rs new file mode 100644 index 000000000000..5907464ca481 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13507.rs @@ -0,0 +1,88 @@ +pub mod testtypes { + use std::any::TypeId; + + pub fn type_ids() -> Vec { + vec![ + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::() + ] + } + + // Tests Bool + pub type FooBool = bool; + + // Tests Char + pub type FooChar = char; + + // Tests Int (does not test all variants of IntTy) + pub type FooInt = isize; + + // Tests Uint (does not test all variants of UintTy) + pub type FooUint = usize; + + // Tests Float (does not test all variants of FloatTy) + pub type FooFloat = f64; + + // Tests Str + pub type FooStr = str; + + // Tests Array + pub type FooArray = [u8; 1]; + + // Tests Slice + pub type FooSlice = [u8]; + + // Tests Box (of u8) + pub type FooBox = Box; + + // Tests RawPtr + pub type FooPtr = *const u8; + + // Tests Ref + pub type FooRef = &'static u8; + + // Tests FnPtr + pub type FooFnPtr = fn(u8) -> bool; + + // Tests Dynamic + pub trait FooTrait { + fn foo_method(&self) -> usize; + } + + // Tests struct + pub struct FooStruct { + pub pub_foo_field: usize, + foo_field: usize + } + + // Tests enum + pub enum FooEnum { + VarA(usize), + VarB(usize, usize) + } + + // Tests Tuple + pub type FooNil = (); + pub type FooTuple = (u8, i8, bool); + + // Skipping Param + + // Skipping Infer + + // Skipping Error +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13620-1.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13620-1.rs new file mode 100644 index 000000000000..ff3e3a7dca04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13620-1.rs @@ -0,0 +1,10 @@ +pub struct Foo { + pub foo: extern fn() +} + +extern fn the_foo() {} + +pub const FOO: Foo = Foo { + foo: the_foo +}; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13620-2.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13620-2.rs new file mode 100644 index 000000000000..2ebc4b169d26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13620-2.rs @@ -0,0 +1,4 @@ +extern crate issue_13620_1 as crate1; + +pub static FOO2: crate1::Foo = crate1::FOO; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13872-1.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13872-1.rs new file mode 100644 index 000000000000..9eeb7f5f45d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13872-1.rs @@ -0,0 +1,2 @@ +pub enum A { B } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13872-2.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13872-2.rs new file mode 100644 index 000000000000..bbddc965fedf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13872-2.rs @@ -0,0 +1,4 @@ +extern crate issue_13872_1 as foo; + +pub use foo::A::B; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13872-3.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13872-3.rs new file mode 100644 index 000000000000..73a3cebabc13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-13872-3.rs @@ -0,0 +1,10 @@ +extern crate issue_13872_2 as bar; + +use bar::B; + +pub fn foo() { + match B { + B => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14344-1.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14344-1.rs new file mode 100644 index 000000000000..a17f57c352dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14344-1.rs @@ -0,0 +1,6 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14344-2.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14344-2.rs new file mode 100644 index 000000000000..16af1891cb44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14344-2.rs @@ -0,0 +1,4 @@ +extern crate issue_14344_1; + +pub fn bar() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14421.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14421.rs new file mode 100644 index 000000000000..06821a8cf713 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14421.rs @@ -0,0 +1,26 @@ +#![crate_type="lib"] +#![deny(warnings)] +#![allow(dead_code)] + +pub use src::aliases::B; +pub use src::hidden_core::make; + +mod src { + pub mod aliases { + use super::hidden_core::A; + pub type B = A; + } + + pub mod hidden_core { + use super::aliases::B; + + pub struct A { t: T } + + pub fn make() -> B { A { t: 1.0 } } + + impl A { + pub fn foo(&mut self) { println!("called foo"); } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14422.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14422.rs new file mode 100644 index 000000000000..cb2a492364d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-14422.rs @@ -0,0 +1,26 @@ +#![crate_type="lib"] +#![deny(warnings)] + +pub use src::aliases::B; +pub use src::hidden_core::make; + +mod src { + pub mod aliases { + use super::hidden_core::A; + pub type B = A; + } + + pub mod hidden_core { + use super::aliases::B; + + #[derive(Copy, Clone)] + pub struct A; + + pub fn make() -> B { A } + + impl A { + pub fn foo(&mut self) { println!("called foo"); } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-15562.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-15562.rs new file mode 100644 index 000000000000..04c75552b50a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-15562.rs @@ -0,0 +1,6 @@ +#![crate_type = "lib"] + +extern { + pub fn transmute(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-16643.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-16643.rs new file mode 100644 index 000000000000..d6708061ca6b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-16643.rs @@ -0,0 +1,20 @@ +#![crate_type = "lib"] + +pub struct TreeBuilder { pub h: H } + +impl TreeBuilder { + pub fn process_token(&mut self) { + match self { + _ => for _y in self.by_ref() {} + } + } +} + +impl Iterator for TreeBuilder { + type Item = H; + + fn next(&mut self) -> Option { + None + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-16725.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-16725.rs new file mode 100644 index 000000000000..6a9f4a3cf55a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-16725.rs @@ -0,0 +1,4 @@ +extern { + fn bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-17662.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-17662.rs new file mode 100644 index 000000000000..950dedc65305 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-17662.rs @@ -0,0 +1,13 @@ +#![crate_type = "lib"] + +pub trait Foo<'a, T> { + fn foo(&'a self) -> T; +} + +pub fn foo<'a, T>(x: &'a Foo<'a, T>) -> T { + let x: &'a Foo = x; + // ^ the lifetime parameter of Foo is left to be inferred. + x.foo() + // ^ encoding this method call in metadata triggers an ICE. +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-17718-aux.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-17718-aux.rs new file mode 100644 index 000000000000..1cba9709f911 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-17718-aux.rs @@ -0,0 +1,11 @@ +use std::sync::atomic; + +pub const C1: usize = 1; +pub const C2: atomic::AtomicUsize = atomic::AtomicUsize::new(0); +pub const C3: fn() = { fn foo() {} foo }; +pub const C4: usize = C1 * C1 + C1 / C1; +pub const C5: &'static usize = &C4; + +pub static S1: usize = 3; +pub static S2: atomic::AtomicUsize = atomic::AtomicUsize::new(0); + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-17718-const-privacy.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-17718-const-privacy.rs new file mode 100644 index 000000000000..b8487ae94e0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-17718-const-privacy.rs @@ -0,0 +1,9 @@ +pub use foo::FOO2; + +pub const FOO: usize = 3; +const BAR: usize = 3; + +mod foo { + pub const FOO2: usize = 3; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18501.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18501.rs new file mode 100644 index 000000000000..8890a0882094 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18501.rs @@ -0,0 +1,18 @@ +#![crate_type = "rlib"] +struct Foo; + +trait Tr { + fn tr(&self); +} + +impl Tr for Foo { + fn tr(&self) {} +} + +fn take_method(f: fn(&T), t: &T) {} + +#[inline] +pub fn pass_method() { + take_method(Tr::tr, &Foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18514.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18514.rs new file mode 100644 index 000000000000..ac37236819ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18514.rs @@ -0,0 +1,18 @@ +#![crate_type = "rlib"] + +pub trait Tr { + fn tr(&self); +} + +pub struct St(pub Vec); + +impl Tr for St { + fn tr(&self) { + match self { + &St(ref v) => { + v.iter(); + } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18711.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18711.rs new file mode 100644 index 000000000000..d78bb6a79397 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18711.rs @@ -0,0 +1,6 @@ +#![crate_type = "rlib"] + +pub fn inner(f: F) -> F { + (move || f)() +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18913-1.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18913-1.rs new file mode 100644 index 000000000000..3f3c94d2acc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18913-1.rs @@ -0,0 +1,7 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] +#![crate_name = "foo"] + +pub fn foo() -> i32 { 0 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18913-2.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18913-2.rs new file mode 100644 index 000000000000..a9ab3f5b6e20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-18913-2.rs @@ -0,0 +1,7 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] +#![crate_name = "foo"] + +pub fn foo() -> i32 { 1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-19163.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-19163.rs new file mode 100644 index 000000000000..c4b7a856be87 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-19163.rs @@ -0,0 +1,7 @@ +#![crate_type = "lib"] + +#[macro_export] +macro_rules! mywrite { + ($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*))) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-1920.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-1920.rs new file mode 100644 index 000000000000..14a8c4254253 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-1920.rs @@ -0,0 +1,5 @@ +// Just exporting some type to test for correct diagnostics when this +// crate is pulled in at a non-root location in client crate. + +pub struct S; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-19293.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-19293.rs new file mode 100644 index 000000000000..012362b97cc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-19293.rs @@ -0,0 +1,5 @@ +pub struct Foo (pub isize); +pub enum MyEnum { + Foo(Foo), +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-19340-1.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-19340-1.rs new file mode 100644 index 000000000000..a82a0b501481 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-19340-1.rs @@ -0,0 +1,4 @@ +pub enum Homura { + Madoka { name: String }, +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-20389.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-20389.rs new file mode 100644 index 000000000000..6b763e15b9a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-20389.rs @@ -0,0 +1,5 @@ +pub trait T { + type C; + fn dummy(&self) { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-21146-inc.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-21146-inc.rs new file mode 100644 index 000000000000..cab211b8df28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-21146-inc.rs @@ -0,0 +1,4 @@ +// include file for issue-21146.rs + +parse_error + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-21202.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-21202.rs new file mode 100644 index 000000000000..1a96088fc08a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-21202.rs @@ -0,0 +1,7 @@ +pub mod A { + pub struct Foo; + impl Foo { + fn foo(&self) { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2170-lib.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2170-lib.rs new file mode 100644 index 000000000000..fd41b4e14e77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2170-lib.rs @@ -0,0 +1,19 @@ +fn foo(_x: i32) { +} + +pub struct rsrc { + x: i32, +} + +impl Drop for rsrc { + fn drop(&mut self) { + foo(self.x); + } +} + +pub fn rsrc(x: i32) -> rsrc { + rsrc { + x: x + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2316-a.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2316-a.rs new file mode 100644 index 000000000000..cdaef4c1cd9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2316-a.rs @@ -0,0 +1,4 @@ +enum cat { + tabby, calico, tortoiseshell +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2316-b.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2316-b.rs new file mode 100644 index 000000000000..ca49f12e3faf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2316-b.rs @@ -0,0 +1,12 @@ +#![allow(unused_imports)] + +extern crate issue_2316_a; + +pub mod cloth { + use issue_2316_a::*; + + pub enum fabric { + gingham, flannel, calico + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2380.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2380.rs new file mode 100644 index 000000000000..d8cf573bf042 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2380.rs @@ -0,0 +1,16 @@ +#![crate_name="a"] +#![crate_type = "lib"] + +#![feature(box_syntax)] + +pub trait i +{ + fn dummy(&self, t: T) -> T { panic!() } +} + +pub fn f() -> Box+'static> { + impl i for () { } + + box () as Box+'static> +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2414-a.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2414-a.rs new file mode 100644 index 000000000000..5ce52ebe313e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2414-a.rs @@ -0,0 +1,13 @@ +#![crate_name="a"] +#![crate_type = "lib"] + +type t1 = usize; + +trait foo { + fn foo(&self); +} + +impl foo for String { + fn foo(&self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2414-b.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2414-b.rs new file mode 100644 index 000000000000..b791be002228 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2414-b.rs @@ -0,0 +1,5 @@ +#![crate_name="b"] +#![crate_type = "lib"] + +extern crate a; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2472-b.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2472-b.rs new file mode 100644 index 000000000000..935decec6b42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2472-b.rs @@ -0,0 +1,14 @@ +pub struct S(pub ()); + +impl S { + pub fn foo(&self) { } +} + +pub trait T { + fn bar(&self); +} + +impl T for S { + fn bar(&self) { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-25185-1.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-25185-1.rs new file mode 100644 index 000000000000..40a7e164cc6b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-25185-1.rs @@ -0,0 +1,9 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + pub fn rust_dbg_extern_identity_u32(u: u32) -> u32; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-25185-2.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-25185-2.rs new file mode 100644 index 000000000000..0cc17d0c8d1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-25185-2.rs @@ -0,0 +1,4 @@ +extern crate issue_25185_1; + +pub use issue_25185_1::rust_dbg_extern_identity_u32; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2526.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2526.rs new file mode 100644 index 000000000000..979a084eff4d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2526.rs @@ -0,0 +1,45 @@ +#![crate_name="issue_2526"] +#![crate_type = "lib"] + +use std::marker; + +pub struct arc_destruct { + _data: isize, + _marker: marker::PhantomData +} + +impl Drop for arc_destruct { + fn drop(&mut self) {} +} + +fn arc_destruct(data: isize) -> arc_destruct { + arc_destruct { + _data: data, + _marker: marker::PhantomData + } +} + +fn arc(_data: T) -> arc_destruct { + arc_destruct(0) +} + +fn init() -> arc_destruct { + arc(context_res()) +} + +pub struct context_res { + ctx : isize, +} + +impl Drop for context_res { + fn drop(&mut self) {} +} + +fn context_res() -> context_res { + context_res { + ctx: 0 + } +} + +pub type context = arc_destruct; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-25467.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-25467.rs new file mode 100644 index 000000000000..2a641436994d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-25467.rs @@ -0,0 +1,11 @@ +#![crate_type="lib"] + +pub trait Trait { + // the issue is sensitive to interning order - so use names + // unlikely to appear in libstd. + type Issue25467FooT; + type Issue25467BarT; +} + +pub type Object = Option>>; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2631-a.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2631-a.rs new file mode 100644 index 000000000000..b203afe12d0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2631-a.rs @@ -0,0 +1,15 @@ +#![crate_name="req"] +#![crate_type = "lib"] + +use std::cell::RefCell; +use std::collections::HashMap; +use std::rc::Rc; + +pub type header_map = HashMap>>>>; + +// the unused ty param is necessary so this gets monomorphized +pub fn request(req: &header_map) { + let data = req[&"METHOD".to_string()].clone(); + let _x = data.borrow().clone()[0].clone(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2723-a.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2723-a.rs new file mode 100644 index 000000000000..9423d9645aa8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-2723-a.rs @@ -0,0 +1,4 @@ +pub unsafe fn f(xs: Vec ) { + xs.iter().map(|_x| { unsafe fn q() { panic!(); } }).collect::>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-29181.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-29181.rs new file mode 100644 index 000000000000..7478dc5ee96b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-29181.rs @@ -0,0 +1,6 @@ +#![crate_type="lib"] + +pub mod foo { + pub use super::*; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-29265.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-29265.rs new file mode 100644 index 000000000000..fb3c50b17461 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-29265.rs @@ -0,0 +1,10 @@ +#![crate_type = "lib"] + +pub struct SomeType { + pub some_member: usize, +} + +pub static SOME_VALUE: SomeType = SomeType { + some_member: 1, +}; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-29485.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-29485.rs new file mode 100644 index 000000000000..5ffd180b65e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-29485.rs @@ -0,0 +1,17 @@ +#![crate_name="a"] +#![crate_type = "lib"] + +pub struct X(pub u8); + +impl Drop for X { + fn drop(&mut self) { + assert_eq!(self.0, 1) + } +} + +pub fn f(x: &mut X, g: fn()) { + x.0 = 1; + g(); + x.0 = 0; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-3012-1.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-3012-1.rs new file mode 100644 index 000000000000..cb907b9a516c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-3012-1.rs @@ -0,0 +1,21 @@ +#![crate_name="socketlib"] +#![crate_type = "lib"] + +pub mod socket { + pub struct socket_handle { + sockfd: u32, + } + + impl Drop for socket_handle { + fn drop(&mut self) { + /* c::close(self.sockfd); */ + } + } + + pub fn socket_handle(x: u32) -> socket_handle { + socket_handle { + sockfd: x + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-30123-aux.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-30123-aux.rs new file mode 100644 index 000000000000..a13bed77e2b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-30123-aux.rs @@ -0,0 +1,24 @@ +use std::marker::PhantomData; + +pub struct Directed; +pub struct Undirected; + +pub struct Graph { + nodes: Vec>, + edges: Vec>, + ty: PhantomData, +} + + +impl Graph { + pub fn new() -> Self { + Graph{nodes: Vec::new(), edges: Vec::new(), ty: PhantomData} + } +} + +impl Graph { + pub fn new_undirected() -> Self { + Graph{nodes: Vec::new(), edges: Vec::new(), ty: PhantomData} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-30535.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-30535.rs new file mode 100644 index 000000000000..bc857612569c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-30535.rs @@ -0,0 +1,6 @@ +#![crate_type="lib"] + +pub enum Foo { + FooV { data: () } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-3136-a.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-3136-a.rs new file mode 100644 index 000000000000..3c2280d630f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-3136-a.rs @@ -0,0 +1,15 @@ +trait x { + fn use_x(&self); +} +struct y(()); +impl x for y { + fn use_x(&self) { + struct foo { // { dg-error "" "" { target *-*-* } } + i: () + } + fn new_foo(i: ()) -> foo { + foo { i: i } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-31702-1.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-31702-1.rs new file mode 100644 index 000000000000..66bf30d91552 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-31702-1.rs @@ -0,0 +1,17 @@ +#[derive(Copy)] +pub struct U256(pub [u64; 4]); + +impl Clone for U256 { + fn clone(&self) -> U256 { + *self + } +} + +impl U256 { + pub fn new(value: u64) -> U256 { + let mut ret = [0; 4]; + ret[0] = value; + U256(ret) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-31702-2.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-31702-2.rs new file mode 100644 index 000000000000..ffc2070f00f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-31702-2.rs @@ -0,0 +1,21 @@ +// compile-flags: -g + +extern crate issue_31702_1; + +use std::collections::HashMap; +use issue_31702_1::U256; + +pub struct Ethash { + engine_params: fn() -> Option<&'static Vec>, + u256_params: HashMap, +} + +impl Ethash { + pub fn u256_param(&mut self, name: &str) -> U256 { + let engine = self.engine_params; + *self.u256_params.entry(name.to_owned()).or_insert_with(|| { + engine().map_or(U256::new(0u64), |_a| loop {}) + }) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-34796-aux.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-34796-aux.rs new file mode 100644 index 000000000000..7499168a2ec2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-34796-aux.rs @@ -0,0 +1,21 @@ +#![crate_type = "lib"] +pub trait Future { + type Item; + type Error; +} + +impl Future for u32 { + type Item = (); + type Error = Box<()>; +} + +fn foo() -> Box>> { + Box::new(0u32) +} + +pub fn bar(_s: F) + where F: Fn(A) -> B, +{ + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-36708.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-36708.rs new file mode 100644 index 000000000000..96de0036c6e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-36708.rs @@ -0,0 +1,6 @@ +#![crate_type = "lib"] + +pub trait Foo { + fn foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-36881-aux.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-36881-aux.rs new file mode 100644 index 000000000000..64be4375d161 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-36881-aux.rs @@ -0,0 +1,2 @@ +pub trait Foo {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-36954.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-36954.rs new file mode 100644 index 000000000000..607db5e167bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-36954.rs @@ -0,0 +1,8 @@ +#![crate_type = "lib"] + +const fn foo(i: i32) -> i32 { + i +} + +pub const FOO: i32 = foo(1); + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-38190.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-38190.rs new file mode 100644 index 000000000000..237a1919c1ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-38190.rs @@ -0,0 +1,3 @@ +#[macro_export] +macro_rules! m { ([$i:item]) => {} } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-38226-aux.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-38226-aux.rs new file mode 100644 index 000000000000..5dfb5c13d35a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-38226-aux.rs @@ -0,0 +1,24 @@ +#![crate_type="rlib"] + +#[inline(never)] +pub fn foo() { + let _: Box = Box::new(SomeTraitImpl); +} + +pub fn bar() { + SomeTraitImpl.bar(); +} + +mod submod { + pub trait SomeTrait { + fn bar(&self) { + panic!("NO") + } + } +} + +use self::submod::SomeTrait; + +pub struct SomeTraitImpl; +impl SomeTrait for SomeTraitImpl {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-3979-traits.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-3979-traits.rs new file mode 100644 index 000000000000..a7a665ce717f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-3979-traits.rs @@ -0,0 +1,16 @@ +#![crate_name="issue_3979_traits"] + +#![crate_type = "lib"] + +pub trait Positioned { + fn SetX(&mut self, _: isize); + fn X(&self) -> isize; +} + +pub trait Movable: Positioned { + fn translate(&mut self, dx: isize) { + let x = self.X() + dx; + self.SetX(x); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-39823.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-39823.rs new file mode 100644 index 000000000000..ef5bae57bf4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-39823.rs @@ -0,0 +1,8 @@ +#![crate_type="rlib"] + +#[derive(Debug, PartialEq)] +pub struct RemoteC(pub u32); + +#[derive(Debug, PartialEq)] +pub struct RemoteG(pub T); + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-40469.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-40469.rs new file mode 100644 index 000000000000..ca67dafd6dee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-40469.rs @@ -0,0 +1,2 @@ +macro_rules! m { () => { $crate::main(); } } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-41053.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-41053.rs new file mode 100644 index 000000000000..049eca6bb2e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-41053.rs @@ -0,0 +1,2 @@ +pub struct Test; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-41394.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-41394.rs new file mode 100644 index 000000000000..14f156cad06e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-41394.rs @@ -0,0 +1,17 @@ +#![crate_type = "lib"] + +#[repr(u32)] +pub enum Foo { + Foo = Private::Variant as u32 +} + +#[repr(u8)] +enum Private { + Variant = 42 +} + +#[inline(always)] +pub fn foo() -> Foo { + Foo::Foo +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-41549.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-41549.rs new file mode 100644 index 000000000000..bfca9f566d39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-41549.rs @@ -0,0 +1,4 @@ +pub trait Trait { + const CONST: u32; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-42007-s.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-42007-s.rs new file mode 100644 index 000000000000..b81b3c416081 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-42007-s.rs @@ -0,0 +1,5 @@ +#[repr(u8)] +pub enum E { + B = 1 as u8, +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-4208-cc.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-4208-cc.rs new file mode 100644 index 000000000000..69b0b39c32f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-4208-cc.rs @@ -0,0 +1,11 @@ +#![crate_name="numeric"] +#![crate_type = "lib"] + +pub trait Trig { + fn sin(&self) -> T; +} + +pub fn sin, R>(theta: &T) -> R { theta.sin() } + +pub trait Angle: Trig {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-4545.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-4545.rs new file mode 100644 index 000000000000..dec9d6ffb5ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-4545.rs @@ -0,0 +1,3 @@ +pub struct S(Option); +pub fn mk() -> S { S(None) } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-48984-aux.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-48984-aux.rs new file mode 100644 index 000000000000..130d88218c0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-48984-aux.rs @@ -0,0 +1,7 @@ +#![crate_type = "lib"] +#![crate_name = "issue48984aux"] + +pub trait Foo { type Item; } + +pub trait Bar: Foo { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-49544.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-49544.rs new file mode 100644 index 000000000000..ea718609bb6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-49544.rs @@ -0,0 +1,8 @@ +#![crate_type = "lib"] + +pub fn foo() -> Vec { + std::env::args() + .skip(1) + .collect() +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-51798.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-51798.rs new file mode 100644 index 000000000000..d489a9ecb0a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-51798.rs @@ -0,0 +1,4 @@ +#![crate_type = "lib"] + +pub fn vec() -> Vec { vec![] } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-52489.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-52489.rs new file mode 100644 index 000000000000..c046f1ffd074 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-52489.rs @@ -0,0 +1,4 @@ +#![crate_type = "lib"] +#![unstable(feature = "issue_52489_unstable", issue = "none")] +#![feature(staged_api)] + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-52891.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-52891.rs new file mode 100644 index 000000000000..b800a7dedd9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-52891.rs @@ -0,0 +1,34 @@ +pub mod a { + pub mod inner { + } +} + +pub mod b { + pub mod inner { + } +} + +pub mod c {} + +pub mod d {} + +pub mod e {} + +pub mod f {} + +pub mod g {} + +pub mod h {} + +pub mod i {} + +pub mod j {} + +pub mod k {} + +pub mod l {} + +pub mod m {} + +pub mod n {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-5518.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-5518.rs new file mode 100644 index 000000000000..08ab1b642e9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-5518.rs @@ -0,0 +1,5 @@ +trait A<'a, T> { + fn f(&mut self) -> &'a mut T; + fn p() -> T; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-5521.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-5521.rs new file mode 100644 index 000000000000..777dbab1fb3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-5521.rs @@ -0,0 +1,4 @@ +use std::collections::HashMap; + +pub type map = Box>; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-56943.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-56943.rs new file mode 100644 index 000000000000..b337b89a47ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-56943.rs @@ -0,0 +1,4 @@ +pub struct S; +mod m { pub struct S; } +pub use crate::m::S as S2; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-57271-lib.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-57271-lib.rs new file mode 100644 index 000000000000..f4c98679b10c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-57271-lib.rs @@ -0,0 +1,12 @@ +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub enum BaseType { + Byte, + Char, + Double, + Float, + Int, + Long, + Short, + Boolean, +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-5844-aux.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-5844-aux.rs new file mode 100644 index 000000000000..f45a5bcf137a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-5844-aux.rs @@ -0,0 +1,4 @@ +extern "C" { + pub fn rand() -> u32; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-59764.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-59764.rs new file mode 100644 index 000000000000..f30d47714252 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-59764.rs @@ -0,0 +1,19 @@ +pub mod foo { + #[macro_export] + macro_rules! makro { + ($foo:ident) => { + fn $foo() { } + } + } + + pub fn baz() {} + + pub fn foobar() {} + + pub mod barbaz { + pub fn barfoo() {} + } +} + +pub fn foobaz() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-69725.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-69725.rs new file mode 100644 index 000000000000..b1cb33f5193d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-69725.rs @@ -0,0 +1,9 @@ +#[derive(Clone)] +pub struct Struct(A); + +impl Struct { + pub fn new() -> Self { + todo!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-7178.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-7178.rs new file mode 100644 index 000000000000..eac3f96824c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-7178.rs @@ -0,0 +1,8 @@ +pub struct Foo<'a, A:'a>(&'a A); + +impl<'a, A> Foo<'a, A> { + pub fn new(a: &'a A) -> Foo<'a, A> { + Foo(a) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-73112.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-73112.rs new file mode 100644 index 000000000000..eedb36d5dfda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-73112.rs @@ -0,0 +1,11 @@ +#[repr(transparent)] +pub struct PageTableEntry { + entry: u64, +} + +#[repr(align(4096))] +#[repr(C)] +pub struct PageTable { + entries: [PageTableEntry; 512], +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-75907.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-75907.rs new file mode 100644 index 000000000000..f33abf51404f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-75907.rs @@ -0,0 +1,6 @@ +pub struct Bar(pub u8, u8, u8); + +pub fn make_bar() -> Bar { + Bar(1, 12, 10) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-7899.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-7899.rs new file mode 100644 index 000000000000..8371a4faacb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-7899.rs @@ -0,0 +1,2 @@ +pub struct V2(pub T, pub T); + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-8044.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-8044.rs new file mode 100644 index 000000000000..a8c87b94f51c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-8044.rs @@ -0,0 +1,16 @@ +pub struct BTree { + pub node: TreeItem, +} + +pub enum TreeItem { + TreeLeaf { value: V }, +} + +pub fn leaf(value: V) -> TreeItem { + TreeItem::TreeLeaf { value: value } +} + +fn main() { + BTree:: { node: leaf(1) }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-8259.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-8259.rs new file mode 100644 index 000000000000..bbec0b30637d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-8259.rs @@ -0,0 +1,5 @@ +pub enum Foo<'a> { + A, + B(&'a str), +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-8401.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-8401.rs new file mode 100644 index 000000000000..1bec2afa0e82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-8401.rs @@ -0,0 +1,17 @@ +// for this issue, this code must be built in a library + +use std::mem; + +trait A { + fn dummy(&self) { } +} +struct B; +impl A for B {} + +fn bar(_: &mut A, _: &T) {} + +fn foo(t: &T) { + let mut b = B; + bar(&mut b as &mut A, t) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9123.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9123.rs new file mode 100644 index 000000000000..67e0b6680bd5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9123.rs @@ -0,0 +1,10 @@ +#![crate_type = "lib"] + +pub trait X { + fn x() { + fn f() { } + f(); + } + fn dummy(&self) { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9155.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9155.rs new file mode 100644 index 000000000000..b70ebce503ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9155.rs @@ -0,0 +1,8 @@ +pub struct Foo(T); + +impl Foo { + pub fn new(t: T) -> Foo { + Foo(t) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9188.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9188.rs new file mode 100644 index 000000000000..fd921a0ca2f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9188.rs @@ -0,0 +1,14 @@ +pub fn foo() -> &'static isize { + if false { + static a: isize = 4; + return &a; + } else { + static a: isize = 5; + return &a; + } +} + +pub fn bar() -> &'static isize { + foo::() +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9906.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9906.rs new file mode 100644 index 000000000000..28467fd6877c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9906.rs @@ -0,0 +1,16 @@ +pub use other::FooBar; +pub use other::foo; + +mod other { + pub struct FooBar{value: isize} + impl FooBar{ + pub fn new(val: isize) -> FooBar { + FooBar{value: val} + } + } + + pub fn foo(){ + 1+1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9968.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9968.rs new file mode 100644 index 000000000000..09cd383df0fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/issue-9968.rs @@ -0,0 +1,23 @@ +pub use internal::core::{Trait, Struct}; + +mod internal { + pub mod core { + pub struct Struct; + impl Struct { + pub fn init() -> Struct { + Struct + } + } + + pub trait Trait { + fn test(&self) { + private(); + } + } + + impl Trait for Struct {} + + fn private() { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/lint-stability.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/lint-stability.rs new file mode 100644 index 000000000000..6e8d41ed1aa7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/lint-stability.rs @@ -0,0 +1,189 @@ +#![crate_name="lint_stability"] +#![crate_type = "lib"] +#![feature(staged_api)] +#![feature(associated_type_defaults)] +#![stable(feature = "lint_stability", since = "1.0.0")] + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub fn deprecated() {} +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub fn deprecated_text() {} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "99.99.99", reason = "text")] +pub fn deprecated_future() {} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub fn deprecated_unstable() {} +#[unstable(feature = "unstable_test_feature", issue = "none")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub fn deprecated_unstable_text() {} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub fn unstable() {} +#[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] +pub fn unstable_text() {} + +#[stable(feature = "rust1", since = "1.0.0")] +pub fn stable() {} +#[stable(feature = "rust1", since = "1.0.0")] +pub fn stable_text() {} + +#[stable(feature = "rust1", since = "1.0.0")] +pub struct MethodTester; + +impl MethodTester { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated(&self) {} + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated_unstable_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub fn method_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + pub fn method_unstable_text(&self) {} + + #[stable(feature = "rust1", since = "1.0.0")] + pub fn method_stable(&self) {} + #[stable(feature = "rust1", since = "1.0.0")] + pub fn method_stable_text(&self) {} +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub trait Trait { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated(&self) {} + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated_unstable_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + fn trait_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + fn trait_unstable_text(&self) {} + + #[stable(feature = "rust1", since = "1.0.0")] + fn trait_stable(&self) {} + #[stable(feature = "rust1", since = "1.0.0")] + fn trait_stable_text(&self) {} +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub trait TraitWithAssociatedTypes { + #[unstable(feature = "unstable_test_feature", issue = "none")] + type TypeUnstable = u8; + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + type TypeDeprecated = u8; +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +impl Trait for MethodTester {} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub trait UnstableTrait { fn dummy(&self) { } } + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub trait DeprecatedTrait { + #[stable(feature = "stable_test_feature", since = "1.0.0")] fn dummy(&self) { } +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct DeprecatedStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize +} +#[unstable(feature = "unstable_test_feature", issue = "none")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct DeprecatedUnstableStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize +} +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct UnstableStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize +} +#[stable(feature = "rust1", since = "1.0.0")] +pub struct StableStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize +} +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub enum UnstableEnum {} +#[stable(feature = "rust1", since = "1.0.0")] +pub enum StableEnum {} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct DeprecatedUnitStruct; +#[unstable(feature = "unstable_test_feature", issue = "none")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct DeprecatedUnstableUnitStruct; +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct UnstableUnitStruct; +#[stable(feature = "rust1", since = "1.0.0")] +pub struct StableUnitStruct; + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub enum Enum { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + DeprecatedVariant, + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + DeprecatedUnstableVariant, + #[unstable(feature = "unstable_test_feature", issue = "none")] + UnstableVariant, + + #[stable(feature = "rust1", since = "1.0.0")] + StableVariant, +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct DeprecatedTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize); +#[unstable(feature = "unstable_test_feature", issue = "none")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct DeprecatedUnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize); +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct UnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize); +#[stable(feature = "rust1", since = "1.0.0")] +pub struct StableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize); + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[macro_export] +macro_rules! macro_test { + () => (deprecated()); +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[macro_export] +macro_rules! macro_test_arg { + ($func:expr) => ($func); +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[macro_export] +macro_rules! macro_test_arg_nested { + ($func:ident) => (macro_test_arg!($func())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/private-trait-xc.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/private-trait-xc.rs new file mode 100644 index 000000000000..97be747cd36e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/private-trait-xc.rs @@ -0,0 +1,2 @@ +trait Foo {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/reexported-trait.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/reexported-trait.rs new file mode 100644 index 000000000000..e99d1428267b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/reexported-trait.rs @@ -0,0 +1,18 @@ +mod private { + pub trait Trait { + fn trait_method(&self) { + } + } + pub trait TraitB { + fn trait_method_b(&self) { + } + } +} + +pub struct FooStruct; +pub use crate::private::Trait; +impl crate::private::Trait for FooStruct {} + +pub use crate::private::TraitB as TraitBRename; +impl crate::private::TraitB for FooStruct {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-43189-a.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-43189-a.rs new file mode 100644 index 000000000000..e5fce945b46f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-43189-a.rs @@ -0,0 +1,8 @@ +#![crate_type="lib"] + + +pub trait A { + fn a(&self) {} +} +impl A for () {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-43189-b.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-43189-b.rs new file mode 100644 index 000000000000..4463fff438ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-43189-b.rs @@ -0,0 +1,4 @@ +#![crate_type="lib"] + +pub extern crate xcrate_issue_43189_a; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-46112-rexport-core.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-46112-rexport-core.rs new file mode 100644 index 000000000000..c5a80353741f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-46112-rexport-core.rs @@ -0,0 +1,4 @@ +#![crate_type="lib"] + +pub extern crate core; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-61711-b.rs b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-61711-b.rs new file mode 100644 index 000000000000..45f60e4c74c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/auxiliary/xcrate-issue-61711-b.rs @@ -0,0 +1,6 @@ +// edition:2018 +#![crate_type="lib"] +#![crate_name="xcrate_issue_61711_b"] +pub struct Struct; +pub use crate as alias; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10025.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10025.rs new file mode 100644 index 000000000000..f6584594f95c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10025.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +unsafe extern fn foo() {} +unsafe extern "C" fn bar() {} + +fn main() { + let _a: unsafe extern fn() = foo; + let _a: unsafe extern "C" fn() = foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10028.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10028.rs new file mode 100644 index 000000000000..1347e239683d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10028.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(dead_code)] +// aux-build:issue-10028.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_10028 as issue10028; + +use issue10028::ZeroLengthThingWithDestructor; + +struct Foo { + zero_length_thing: ZeroLengthThingWithDestructor +} + +fn make_foo() -> Foo { + Foo { zero_length_thing: ZeroLengthThingWithDestructor::new() } +} + +fn main() { + let _f:Foo = make_foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10031.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10031.rs new file mode 100644 index 000000000000..101b67e174dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10031.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:issue-10031-aux.rs +// pretty-expanded FIXME #23616 + +extern crate issue_10031_aux; + +pub fn main() { + let _ = issue_10031_aux::Wrap(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10176.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10176.rs new file mode 100644 index 000000000000..fcecaa264775 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10176.rs @@ -0,0 +1,10 @@ +fn f() -> isize { + (return 1, return 2) +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10200.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10200.rs new file mode 100644 index 000000000000..06615c3b95b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10200.rs @@ -0,0 +1,10 @@ +struct Foo(bool); +fn foo(_: usize) -> Foo { Foo(false) } + +fn main() { + match Foo(true) { + foo(x) // { dg-error ".E0532." "" { target *-*-* } } + => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10228.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10228.rs new file mode 100644 index 000000000000..0f479626a704 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10228.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +enum StdioContainer { + CreatePipe(bool) +} + +struct Test<'a> { + args: &'a [String], + io: &'a [StdioContainer] +} + +pub fn main() { + let test = Test { + args: &[], + io: &[StdioContainer::CreatePipe(true)] + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10291.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10291.rs new file mode 100644 index 000000000000..ae01909646c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10291.rs @@ -0,0 +1,8 @@ +fn test<'x>(x: &'x isize) { + drop:: FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { + x // { dg-error ".E0312." "" { target *-*-* } } + })); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10392.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10392.rs new file mode 100644 index 000000000000..3a2e08550f31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10392.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(unused_variables)] + +struct A { foo: isize } +struct B { a: isize, b: isize, c: isize } + +fn mka() -> A { panic!() } +fn mkb() -> B { panic!() } + +fn test() { + let A { foo, } = mka(); + let A { + foo, + } = mka(); + + let B { a, b, c, } = mkb(); + + match mka() { + A { foo: _foo, } => {} + } + + match Some(mka()) { + Some(A { foo: _foo, }) => {} + None => {} + } +} + +pub fn main() { + if false { test() } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10396.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10396.rs new file mode 100644 index 000000000000..e945d35701bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10396.rs @@ -0,0 +1,15 @@ +// check-pass +#![allow(dead_code)] +#[derive(Debug)] +enum Foo<'s> { + V(&'s str) +} + +fn f(arr: &[&Foo]) { + for &f in arr { + println!("{:?}", f); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10398.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10398.rs new file mode 100644 index 000000000000..23559d14bb41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10398.rs @@ -0,0 +1,12 @@ +#![feature(box_syntax)] + +fn main() { + let x: Box<_> = box 1; + let f = move|| { + let _a = x; + drop(x); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + }; + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10401.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10401.rs new file mode 100644 index 000000000000..958deea9ced8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10401.rs @@ -0,0 +1,6 @@ +fn main() { + let mut a = "a"; + a += { "b" }; +// { dg-error ".E0368." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10412.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10412.rs new file mode 100644 index 000000000000..3a3e62e088d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10412.rs @@ -0,0 +1,24 @@ +trait Serializable<'self, T> { // { dg-error "" "" { target *-*-* } } + fn serialize(val : &'self T) -> Vec; // { dg-error "" "" { target *-*-* } } + fn deserialize(repr : &[u8]) -> &'self T; // { dg-error "" "" { target *-*-* } } +} + +impl<'self> Serializable for &'self str { // { dg-error ".E0277." "" { target *-*-* } } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } + fn serialize(val : &'self str) -> Vec { // { dg-error "" "" { target *-*-* } } + vec![1] + } + fn deserialize(repr: &[u8]) -> &'self str { // { dg-error "" "" { target *-*-* } } + "hi" + } +} + +fn main() { + println!("hello"); + let x = "foo".to_string(); + let y = x; + println!("{}", y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10436.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10436.rs new file mode 100644 index 000000000000..b75a689b13c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10436.rs @@ -0,0 +1,12 @@ +// run-pass +fn works(x: T) -> Vec { vec![x] } + +fn also_works(x: T) -> Vec { vec![x] } + +fn main() { + let _: Vec = works(0); + let _: Vec = also_works(0); + let _ = works(0); + let _ = also_works(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10456.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10456.rs new file mode 100644 index 000000000000..a9add0f67063 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10456.rs @@ -0,0 +1,26 @@ +// check-pass +// pretty-expanded FIXME #23616 + +pub struct Foo; + +pub trait Bar { + fn bar(&self); +} + +pub trait Baz { + fn baz(&self) { } +} + +impl Bar for T { + fn bar(&self) {} +} + +impl Baz for Foo {} + +pub fn foo(t: Box) { + t.bar(); // ~Foo doesn't implement Baz + (*t).bar(); // ok b/c Foo implements Baz +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10465.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10465.rs new file mode 100644 index 000000000000..a41075c06979 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10465.rs @@ -0,0 +1,24 @@ +pub mod a { + pub trait A { + fn foo(&self); + } + +} +pub mod b { + use a::A; + + pub struct B; + impl A for B { fn foo(&self) {} } + + pub mod c { + use b::B; + + fn foo(b: &B) { + b.foo(); // { dg-error ".E0599." "" { target *-*-* } } + } + } + +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10536.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10536.rs new file mode 100644 index 000000000000..a1618d41a48e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10536.rs @@ -0,0 +1,20 @@ +// We only want to assert that this doesn't ICE, we don't particularly care +// about whether it nor it fails to compile. + +macro_rules! foo{ + () => {{ + macro_rules! bar{() => (())} + 1 + }} +} + +pub fn main() { + foo!(); + + assert!({one! two()}); // { dg-error "" "" { target *-*-* } } + + // regardless of whether nested macro_rules works, the following should at + // least throw a conventional error. + assert!({one! two}); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10545.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10545.rs new file mode 100644 index 000000000000..9bc35c71e19e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10545.rs @@ -0,0 +1,10 @@ +mod a { + struct S; + impl S { } +} + +fn foo(_: a::S) { // { dg-error ".E0603." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10626.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10626.rs new file mode 100644 index 000000000000..4440e2bd6f1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10626.rs @@ -0,0 +1,28 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +// Make sure that if a process doesn't have its stdio/stderr descriptors set up +// that we don't die in a large ball of fire + +use std::env; +use std::process::{Command, Stdio}; + +pub fn main () { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "child" { + for _ in 0..1000 { + println!("hello?"); + } + for _ in 0..1000 { + println!("hello?"); + } + return; + } + + let mut p = Command::new(&args[0]); + p.arg("child").stdout(Stdio::null()).stderr(Stdio::null()); + println!("{:?}", p.spawn().unwrap().wait()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10638.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10638.rs new file mode 100644 index 000000000000..e36758d69d2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10638.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + //// I am not a doc comment! + ////////////////// still not a doc comment + /////**** nope, me neither */ + /*** And neither am I! */ + 5; + /*****! certainly not I */ +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10656.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10656.rs new file mode 100644 index 000000000000..4edcf7f99de8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10656.rs @@ -0,0 +1,4 @@ +#![deny(missing_docs)] +#![crate_type="lib"] +// { dg-error "" "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10682.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10682.rs new file mode 100644 index 000000000000..3d1c39d2b2fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10682.rs @@ -0,0 +1,16 @@ +// run-pass +// Regression test for issue #10682 +// Nested `proc` usage can't use outer owned data + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +fn work(_: Box) {} +fn foo(_: F) {} + +pub fn main() { + let a = box 1; + foo(move|| { foo(move|| { work(a) }) }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10683.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10683.rs new file mode 100644 index 000000000000..ea6e615f579e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10683.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +static NAME: &'static str = "hello world"; + +fn main() { + match &*NAME.to_ascii_lowercase() { + "foo" => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10718.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10718.rs new file mode 100644 index 000000000000..5267666bf96c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10718.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn f(p: F) { + p(); +} + +pub fn main() { + let p = || (); + f(p); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10734.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10734.rs new file mode 100644 index 000000000000..e2be628b2b5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10734.rs @@ -0,0 +1,37 @@ +// run-pass +#![allow(non_upper_case_globals)] + +static mut drop_count: usize = 0; + +struct Foo { + dropped: bool +} + +impl Drop for Foo { + fn drop(&mut self) { + // Test to make sure we haven't dropped already + assert!(!self.dropped); + self.dropped = true; + // And record the fact that we dropped for verification later + unsafe { drop_count += 1; } + } +} + +pub fn main() { + // An `if true { expr }` statement should compile the same as `{ expr }`. + if true { + let _a = Foo{ dropped: false }; + } + // Check that we dropped already (as expected from a `{ expr }`). + unsafe { assert_eq!(drop_count, 1); } + + // An `if false {} else { expr }` statement should compile the same as `{ expr }`. + if false { + panic!(); + } else { + let _a = Foo{ dropped: false }; + } + // Check that we dropped already (as expected from a `{ expr }`). + unsafe { assert_eq!(drop_count, 2); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10763.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10763.rs new file mode 100644 index 000000000000..e364b8a1cc63 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10763.rs @@ -0,0 +1,8 @@ +// build-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +extern "Rust" fn foo() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10764-rpass.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10764-rpass.rs new file mode 100644 index 000000000000..393f8b6f4670 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10764-rpass.rs @@ -0,0 +1,5 @@ +// run-pass +// pretty-expanded FIXME #23616 + +extern "Rust" fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10764.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10764.rs new file mode 100644 index 000000000000..274303fd9fa5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10764.rs @@ -0,0 +1,6 @@ +fn f(_: extern "Rust" fn()) {} +extern fn bar() {} + +fn main() { f(bar) } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10767.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10767.rs new file mode 100644 index 000000000000..eb39bd890f89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10767.rs @@ -0,0 +1,11 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { + fn f() { + }; + let _: Box = box (f as fn()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10802.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10802.rs new file mode 100644 index 000000000000..bbd0eb36b05a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10802.rs @@ -0,0 +1,47 @@ +// run-pass +#![allow(dead_code)] +#![feature(box_syntax)] + +struct DroppableStruct; +enum DroppableEnum { + DroppableVariant1, DroppableVariant2 +} + +static mut DROPPED: bool = false; + +impl Drop for DroppableStruct { + fn drop(&mut self) { + unsafe { DROPPED = true; } + } +} +impl Drop for DroppableEnum { + fn drop(&mut self) { + unsafe { DROPPED = true; } + } +} + +trait MyTrait { fn dummy(&self) { } } +impl MyTrait for Box {} +impl MyTrait for Box {} + +struct Whatever { w: Box } +impl Whatever { + fn new(w: Box) -> Whatever { + Whatever { w: w } + } +} + +fn main() { + { + let f: Box<_> = box DroppableStruct; + let _a = Whatever::new(box f as Box); + } + assert!(unsafe { DROPPED }); + unsafe { DROPPED = false; } + { + let f: Box<_> = box DroppableEnum::DroppableVariant1; + let _a = Whatever::new(box f as Box); + } + assert!(unsafe { DROPPED }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10806.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10806.rs new file mode 100644 index 000000000000..86b0fbc348e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10806.rs @@ -0,0 +1,39 @@ +// run-pass +#![allow(unused_imports)] + +// pretty-expanded FIXME #23616 + +pub fn foo() -> isize { + 3 +} +pub fn bar() -> isize { + 4 +} + +pub mod baz { + use {foo, bar}; + pub fn quux() -> isize { + foo() + bar() + } +} + +pub mod grault { + use {foo}; + pub fn garply() -> isize { + foo() + } +} + +pub mod waldo { + use {}; + pub fn plugh() -> isize { + 0 + } +} + +pub fn main() { + let _x = baz::quux(); + let _y = grault::garply(); + let _z = waldo::plugh(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10853.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10853.rs new file mode 100644 index 000000000000..80eb504c36c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10853.rs @@ -0,0 +1,16 @@ +// check-pass +// pretty-expanded FIXME #23616 + +#![deny(missing_docs)] +#![doc="module"] + +#[doc="struct"] +pub struct Foo; + +pub fn foo() { + #![doc="fn"] +} + +#[doc="main"] +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10877.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10877.rs new file mode 100644 index 000000000000..3eb6d6d0e6fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10877.rs @@ -0,0 +1,15 @@ +struct Foo { x: isize } +extern { + fn foo(1: ()); +// { dg-error ".E0130." "" { target *-*-* } .-1 } + fn bar((): isize); +// { dg-error ".E0130." "" { target *-*-* } .-1 } + fn baz(Foo { x }: isize); +// { dg-error ".E0130." "" { target *-*-* } .-1 } + fn qux((x,y): ()); +// { dg-error ".E0130." "" { target *-*-* } .-1 } + fn this_is_actually_ok(a: usize); + fn and_so_is_this(_: usize); +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10902.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10902.rs new file mode 100644 index 000000000000..28b734492ee4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10902.rs @@ -0,0 +1,22 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +pub mod two_tuple { + pub trait T { fn dummy(&self) { } } + pub struct P<'a>(&'a (dyn T + 'a), &'a (dyn T + 'a)); + pub fn f<'a>(car: &'a dyn T, cdr: &'a dyn T) -> P<'a> { + P(car, cdr) + } +} + +pub mod two_fields { + pub trait T { fn dummy(&self) { } } + pub struct P<'a> { car: &'a (dyn T + 'a), cdr: &'a (dyn T + 'a) } + pub fn f<'a>(car: &'a dyn T, cdr: &'a dyn T) -> P<'a> { + P{ car: car, cdr: cdr } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10969.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10969.rs new file mode 100644 index 000000000000..27332b428cea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10969.rs @@ -0,0 +1,8 @@ +fn func(i: i32) { + i(); // { dg-error ".E0618." "" { target *-*-* } } +} +fn main() { + let i = 0i32; + i(); // { dg-error ".E0618." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-10991.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-10991.rs new file mode 100644 index 000000000000..385323d691d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-10991.rs @@ -0,0 +1,5 @@ +fn main() { + let nil = (); + let _t = nil as usize; // { dg-error ".E0605." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11004.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11004.rs new file mode 100644 index 000000000000..b6169183d46d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11004.rs @@ -0,0 +1,28 @@ +use std::mem; + +struct A { x: i32, y: f64 } + +#[cfg(not(works))] +unsafe fn access(n:*mut A) -> (i32, f64) { + let x : i32 = n.x; // { dg-error ".E0609." "" { target *-*-* } } + let y : f64 = n.y; // { dg-error ".E0609." "" { target *-*-* } } + (x, y) +} + +#[cfg(works)] +unsafe fn access(n:*mut A) -> (i32, f64) { + let x : i32 = (*n).x; + let y : f64 = (*n).y; + (x, y) +} + +fn main() { + let a : A = A { x: 3, y: 3.14 }; + let p : &A = &a; + let (x,y) = unsafe { + let n : *mut A = mem::transmute(p); + access(n) + }; + println!("x: {}, y: {}", x, y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11047.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11047.rs new file mode 100644 index 000000000000..f20949ded635 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11047.rs @@ -0,0 +1,27 @@ +// run-pass +// Test that static methods can be invoked on `type` aliases + +#![allow(unused_variables)] + +pub mod foo { + pub mod bar { + pub mod baz { + pub struct Qux; + + impl Qux { + pub fn new() {} + } + } + } +} + +fn main() { + + type Ham = foo::bar::baz::Qux; + let foo = foo::bar::baz::Qux::new(); // invoke directly + let bar = Ham::new(); // invoke via type alias + + type StringVec = Vec; + let sv = StringVec::new(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11085.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11085.rs new file mode 100644 index 000000000000..292c327137e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11085.rs @@ -0,0 +1,47 @@ +// run-pass +#![allow(dead_code)] +// compile-flags: --cfg foo + +// pretty-expanded FIXME #23616 + +struct Foo { + #[cfg(fail)] + bar: baz, + foo: isize, +} + +struct Foo2 { + #[cfg(foo)] + foo: isize, +} + +enum Bar1 { + Bar1_1, + #[cfg(fail)] + Bar1_2(NotAType), +} + +enum Bar2 { + #[cfg(fail)] + Bar2_1(NotAType), +} + +enum Bar3 { + Bar3_1 { + #[cfg(fail)] + foo: isize, + bar: isize, + } +} + +pub fn main() { + let _f = Foo { foo: 3 }; + let _f = Foo2 { foo: 3 }; + + match Bar1::Bar1_1 { + Bar1::Bar1_1 => {} + } + + let _f = Bar3::Bar3_1 { bar: 3 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1112.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1112.rs new file mode 100644 index 000000000000..f31c01458fba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1112.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(dead_code)] +// Issue #1112 +// Alignment of interior pointers to dynamic-size types + + +struct X { + a: T, + b: u8, + c: bool, + d: u8, + e: u16, + f: u8, + g: u8 +} + +pub fn main() { + let x: X = X { + a: 12345678, + b: 9, + c: true, + d: 10, + e: 11, + f: 12, + g: 13 + }; + bar(x); +} + +fn bar(x: X) { + assert_eq!(x.b, 9); + assert_eq!(x.c, true); + assert_eq!(x.d, 10); + assert_eq!(x.e, 11); + assert_eq!(x.f, 12); + assert_eq!(x.g, 13); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11154.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11154.rs new file mode 100644 index 000000000000..76adec35907a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11154.rs @@ -0,0 +1,7 @@ +// build-fail +// compile-flags: -C lto -C prefer-dynamic + +// error-pattern: cannot prefer dynamic linking + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11192.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11192.rs new file mode 100644 index 000000000000..86cea1541382 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11192.rs @@ -0,0 +1,23 @@ +#![feature(box_syntax)] + +struct Foo { + x: isize +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("drop {}", self.x); + } +} + +fn main() { + let mut ptr: Box<_> = box Foo { x: 0 }; + let mut test = |foo: &Foo| { + println!("access {}", foo.x); + ptr = box Foo { x: ptr.x + 1 }; + println!("access {}", foo.x); + }; + test(&*ptr); +// { dg-error ".E0502." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11205.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11205.rs new file mode 100644 index 000000000000..e16549150e6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11205.rs @@ -0,0 +1,86 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +trait Foo { fn dummy(&self) { } } +impl Foo for isize {} +fn foo(_: [&dyn Foo; 2]) {} +fn foos(_: &[&dyn Foo]) {} +fn foog(_: &[T], _: &[T]) {} + +fn bar(_: [Box; 2]) {} +fn bars(_: &[Box]) {} + +fn main() { + let x: [&dyn Foo; 2] = [&1, &2]; + foo(x); + foo([&1, &2]); + + let r = &1; + let x: [&dyn Foo; 2] = [r; 2]; + foo(x); + foo([&1; 2]); + + let x: &[&dyn Foo] = &[&1, &2]; + foos(x); + foos(&[&1, &2]); + + let x: &[&dyn Foo] = &[&1, &2]; + let r = &1; + foog(x, &[r]); + + let x: [Box; 2] = [Box::new(1), Box::new(2)]; + bar(x); + bar([Box::new(1), Box::new(2)]); + + let x: &[Box] = &[Box::new(1), Box::new(2)]; + bars(x); + bars(&[Box::new(1), Box::new(2)]); + + let x: &[Box] = &[Box::new(1), Box::new(2)]; + foog(x, &[Box::new(1)]); + + struct T<'a> { + t: [&'a (dyn Foo+'a); 2] + } + let _n = T { + t: [&1, &2] + }; + let r = &1; + let _n = T { + t: [r; 2] + }; + let x: [&dyn Foo; 2] = [&1, &2]; + let _n = T { + t: x + }; + + struct F<'b> { + t: &'b [&'b (dyn Foo+'b)] + } + let _n = F { + t: &[&1, &2] + }; + let r = &1; + let r: [&dyn Foo; 2] = [r; 2]; + let _n = F { + t: &r + }; + let x: [&dyn Foo; 2] = [&1, &2]; + let _n = F { + t: &x + }; + + struct M<'a> { + t: &'a [Box] + } + let _n = M { + t: &[Box::new(1), Box::new(2)] + }; + let x: [Box; 2] = [Box::new(1), Box::new(2)]; + let _n = M { + t: &x + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11224.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11224.rs new file mode 100644 index 000000000000..364b36196204 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11224.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:issue-11224.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_11224 as unused; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11225-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11225-1.rs new file mode 100644 index 000000000000..ebce8acfaaf0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11225-1.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-11225-1.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_11225_1 as foo; + +pub fn main() { + foo::foo(1); + foo::foo_ufcs(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11225-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11225-2.rs new file mode 100644 index 000000000000..27111e240002 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11225-2.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-11225-2.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_11225_2 as foo; + +pub fn main() { + foo::foo(1); + foo::foo_ufcs(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11225-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11225-3.rs new file mode 100644 index 000000000000..8cae21cb9823 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11225-3.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-11225-3.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_11225_3; + +pub fn main() { + issue_11225_3::public_inlinable_function(); + issue_11225_3::public_inlinable_function_ufcs(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11267.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11267.rs new file mode 100644 index 000000000000..77b32b0a1ec2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11267.rs @@ -0,0 +1,20 @@ +// run-pass +// Tests that unary structs can be mutably borrowed. + +struct Empty; + +trait T { + fn next(&mut self) -> Option; +} +impl T for Empty { + fn next(&mut self) -> Option { None } +} + +fn do_something_with(a : &mut dyn T) { + println!("{:?}", a.next()) +} + +pub fn main() { + do_something_with(&mut Empty); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11319.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11319.rs new file mode 100644 index 000000000000..005438124f60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11319.rs @@ -0,0 +1,14 @@ +fn main() { + match Some(10) { +// { dg-note ".E0308." "" { target *-*-* } .-1 } + Some(5) => false, +// { dg-note "" "" { target *-*-* } .-1 } + Some(2) => true, +// { dg-note "" "" { target *-*-* } .-1 } + None => (), +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } + _ => true + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11374.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11374.rs new file mode 100644 index 000000000000..c53a755b0f86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11374.rs @@ -0,0 +1,28 @@ +use std::io::{self, Read}; +use std::vec; + +pub struct Container<'a> { + reader: &'a mut dyn Read +} + +impl<'a> Container<'a> { + pub fn wrap<'s>(reader: &'s mut dyn io::Read) -> Container<'s> { + Container { reader: reader } + } + + pub fn read_to(&mut self, vec: &mut [u8]) { + self.reader.read(vec); + } +} + +pub fn for_stdin<'a>() -> Container<'a> { + let mut r = io::stdin(); + Container::wrap(&mut r as &mut dyn io::Read) +} + +fn main() { + let mut c = for_stdin(); + let mut v = Vec::new(); + c.read_to(v); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11382.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11382.rs new file mode 100644 index 000000000000..c20645ba9704 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11382.rs @@ -0,0 +1,5 @@ +// run-pass +fn main() { + println!("{}", 1.2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11384.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11384.rs new file mode 100644 index 000000000000..9351265bdbb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11384.rs @@ -0,0 +1,11 @@ +// check-pass +// pretty-expanded FIXME #23616 + +trait Common { fn dummy(&self) { } } + +impl<'t, T> Common for (T, &'t T) {} + +impl<'t, T> Common for (&'t T, T) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11493.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11493.rs new file mode 100644 index 000000000000..8da88e8f3d52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11493.rs @@ -0,0 +1,8 @@ +fn id(x: T) -> T { x } + +fn main() { + let x = Some(3); + let y = x.as_ref().unwrap_or(&id(5)); // { dg-error ".E0716." "" { target *-*-* } } + &y; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11508.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11508.rs new file mode 100644 index 000000000000..b864a66855fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11508.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-11508.rs + +extern crate issue_11508 as rand; + +use rand::{Closed01, random}; + +fn main() { + let Closed01(val) = random::>(); + println!("{}", val); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11515.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11515.rs new file mode 100644 index 000000000000..a9411b1b8bec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11515.rs @@ -0,0 +1,11 @@ +#![feature(box_syntax)] + +struct Test { + func: Box +} + +fn main() { + let closure: Box = Box::new(|| ()); + let test = box Test { func: closure }; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11529.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11529.rs new file mode 100644 index 000000000000..04e3a0b10a64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11529.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-11529.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_11529 as a; + +fn main() { + let one = 1; + let _a = a::A(&one); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11552.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11552.rs new file mode 100644 index 000000000000..5f5bb35cb587 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11552.rs @@ -0,0 +1,23 @@ +// run-pass +#![feature(box_patterns)] +#![feature(box_syntax)] + +#[derive(Clone)] +enum Noun +{ + Atom(isize), + Cell(Box, Box) +} + +fn fas(n: &Noun) -> Noun +{ + match n { + &Noun::Cell(box Noun::Atom(2), box Noun::Cell(ref a, _)) => (**a).clone(), + _ => panic!("Invalid fas pattern") + } +} + +pub fn main() { + fas(&Noun::Cell(box Noun::Atom(2), box Noun::Cell(box Noun::Atom(2), box Noun::Atom(3)))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11577.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11577.rs new file mode 100644 index 000000000000..7a4139309c52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11577.rs @@ -0,0 +1,19 @@ +// run-pass +// Destructuring struct variants would ICE where regular structs wouldn't + +enum Foo { + VBar { num: isize } +} + +struct SBar { num: isize } + +pub fn main() { + let vbar = Foo::VBar { num: 1 }; + let Foo::VBar { num } = vbar; + assert_eq!(num, 1); + + let sbar = SBar { num: 2 }; + let SBar { num } = sbar; + assert_eq!(num, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11592.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11592.rs new file mode 100644 index 000000000000..49740dbbb57c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11592.rs @@ -0,0 +1,12 @@ +// check-pass +//! Ensure the private trait Bar isn't complained about. + +#![deny(missing_docs)] + +mod foo { + trait Bar { fn bar(&self) { } } + impl Bar for i8 { fn bar(&self) { } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11593.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11593.rs new file mode 100644 index 000000000000..506fbedcb4c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11593.rs @@ -0,0 +1,11 @@ +// aux-build:private-trait-xc.rs + +extern crate private_trait_xc; + +struct Bar; + +impl private_trait_xc::Foo for Bar {} +// { dg-error ".E0603." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11612.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11612.rs new file mode 100644 index 000000000000..87dafce4896b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11612.rs @@ -0,0 +1,25 @@ +// check-pass +#![allow(dead_code)] +// #11612 +// We weren't updating the auto adjustments with all the resolved +// type information after type check. + +// pretty-expanded FIXME #23616 + +trait A { fn dummy(&self) { } } + +struct B<'a, T:'a> { + f: &'a T +} + +impl<'a, T> A for B<'a, T> {} + +fn foo(_: &dyn A) {} + +fn bar(b: &B) { + foo(b); // Coercion should work + foo(b as &dyn A); // Explicit cast should work as well +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11677.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11677.rs new file mode 100644 index 000000000000..5c6c0fc8cd4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11677.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(unused_imports)] + +#![allow(dead_code)] + +// this code used to cause an ICE + +use std::marker; + +trait X { + fn dummy(&self) -> T { panic!() } +} + +struct S {f: Box+'static>, + g: Box+'static>} + +struct F; +impl X for F { +} + +fn main() { + S {f: Box::new(F), g: Box::new(F) }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11680.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11680.rs new file mode 100644 index 000000000000..b027418fdd7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11680.rs @@ -0,0 +1,12 @@ +// aux-build:issue-11680.rs + +extern crate issue_11680 as other; + +fn main() { + let _b = other::Foo::Bar(1); +// { dg-error ".E0603." "" { target *-*-* } .-1 } + + let _b = other::test::Foo::Bar(1); +// { dg-error ".E0603." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11681.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11681.rs new file mode 100644 index 000000000000..74a6011be59b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11681.rs @@ -0,0 +1,20 @@ +// This tests verifies that unary structs and enum variants +// are treated as rvalues and their lifetime is not bounded to +// the static scope. + +struct Test; + +impl Drop for Test { + fn drop (&mut self) {} +} + +fn createTest<'a>() -> &'a Test { + let testValue = &Test; + return testValue; // { dg-error ".E0515." "" { target *-*-* } } +} + + +pub fn main() { + createTest(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11692-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11692-1.rs new file mode 100644 index 000000000000..d1981f97be77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11692-1.rs @@ -0,0 +1,4 @@ +fn main() { + print!(testo!()); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11692-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11692-2.rs new file mode 100644 index 000000000000..aec582c9a6d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11692-2.rs @@ -0,0 +1,4 @@ +fn main() { + concat!(test!()); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11709.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11709.rs new file mode 100644 index 000000000000..28acf59a5520 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11709.rs @@ -0,0 +1,39 @@ +// run-pass +#![allow(dead_code)] +// ignore-pretty issue #37199 + +// Don't panic on blocks without results +// There are several tests in this run-pass that raised +// when this bug was opened. The cases where the compiler +// panics before the fix have a comment. + +struct S {x:()} + +fn test(slot: &mut Option Box>>) -> () { + let a = slot.take(); + let _a = match a { + // `{let .. a(); }` would break + Some(mut a) => { let _a = a(); }, + None => (), + }; +} + +fn not(b: bool) -> bool { + if b { + !b + } else { + // `panic!(...)` would break + panic!("Break the compiler"); + } +} + +pub fn main() { + // {} would break + let _r = {}; + let mut slot = None; + // `{ test(...); }` would break + let _s : S = S{ x: { test(&mut slot); } }; + + let _b = not(true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11740.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11740.rs new file mode 100644 index 000000000000..94aec98fcebc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11740.rs @@ -0,0 +1,27 @@ +// check-pass + +struct Attr { + name: String, + value: String, +} + +struct Element { + attrs: Vec>, +} + +impl Element { + pub unsafe fn get_attr<'a>(&'a self, name: &str) { + self.attrs + .iter() + .find(|attr| { + let attr: &&Box = std::mem::transmute(attr); + true + }); + } +} + +fn main() { + let element = Element { attrs: Vec::new() }; + let _ = unsafe { element.get_attr("foo") }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11771.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11771.rs new file mode 100644 index 000000000000..402412689cb8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11771.rs @@ -0,0 +1,12 @@ +fn main() { + let x = (); + 1 + +// { dg-error ".E0277." "" { target *-*-* } .-1 } + ; + + let x: () = (); + 1 + +// { dg-error ".E0277." "" { target *-*-* } .-1 } + ; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11820.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11820.rs new file mode 100644 index 000000000000..6b638d63aee7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11820.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct NoClone; + +fn main() { + let rnc = &NoClone; + let rsnc = &Some(NoClone); + + let _: &NoClone = rnc.clone(); + let _: &Option = rsnc.clone(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11844.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11844.rs new file mode 100644 index 000000000000..fd1f34b10f88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11844.rs @@ -0,0 +1,11 @@ +#![feature(box_syntax)] + +fn main() { + let a = Some(box 1); + match a { + Ok(a) => // { dg-error ".E0308." "" { target *-*-* } } + println!("{}",a), + None => panic!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11869.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11869.rs new file mode 100644 index 000000000000..b0c867a020b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11869.rs @@ -0,0 +1,18 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct A { + a: String +} + +fn borrow<'a>(binding: &'a A) -> &'a str { + match &*binding.a { + "in" => "in_", + "ref" => "ref_", + ident => ident + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11873.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11873.rs new file mode 100644 index 000000000000..5d06a6487ddd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11873.rs @@ -0,0 +1,8 @@ +fn main() { + let mut v = vec![1]; + let mut f = || v.push(2); + let _w = v; // { dg-error ".E0505." "" { target *-*-* } } + + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11940.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11940.rs new file mode 100644 index 000000000000..359cd136757b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11940.rs @@ -0,0 +1,12 @@ +// run-pass + +const TEST_STR: &'static str = "abcd"; + +fn main() { + let s = "abcd"; + match s { + TEST_STR => (), + _ => unreachable!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-11958.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-11958.rs new file mode 100644 index 000000000000..41bc69aa88d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-11958.rs @@ -0,0 +1,12 @@ +// run-pass + +// We shouldn't need to rebind a moved upvar as mut if it's already +// marked as mut + +pub fn main() { + let mut x = 1; + let _thunk = Box::new(move|| { x = 2; }); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12028.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12028.rs new file mode 100644 index 000000000000..e6cf672c23f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12028.rs @@ -0,0 +1,39 @@ +// Test an example where we fail to infer the type parameter H. This +// is because there is really nothing constraining it. At one time, we +// would infer based on the where clauses in scope, but that no longer +// works. + +trait Hash { + fn hash2(&self, hasher: &H) -> u64; +} + +trait Stream { + fn input(&mut self, bytes: &[u8]); + fn result(&self) -> u64; +} + +trait StreamHasher { + type S : Stream; + fn stream(&self) -> Self::S; +} + +trait StreamHash: Hash { + fn input_stream(&self, stream: &mut H::S); +} + +impl Hash for u8 { + fn hash2(&self, hasher: &H) -> u64 { + let mut stream = hasher.stream(); + self.input_stream(&mut stream); // { dg-error ".E0284." "" { target *-*-* } } + Stream::result(&stream) + } +} + +impl StreamHash for u8 { + fn input_stream(&self, stream: &mut H::S) { + Stream::input(stream, &[*self]); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12033.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12033.rs new file mode 100644 index 000000000000..c4ef74f3a710 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12033.rs @@ -0,0 +1,8 @@ +// run-pass +use std::cell::RefCell; + +fn main() { + let x = RefCell::new(0); + if *x.borrow() == 0 {} else {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12041.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12041.rs new file mode 100644 index 000000000000..dd210259d7f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12041.rs @@ -0,0 +1,14 @@ +use std::sync::mpsc::channel; +use std::thread; + +fn main() { + let (tx, rx) = channel(); + let _t = thread::spawn(move|| -> () { + loop { + let tx = tx; +// { dg-error ".E0382." "" { target *-*-* } .-1 } + tx.send(1); + } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12116.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12116.rs new file mode 100644 index 000000000000..784763a2ca35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12116.rs @@ -0,0 +1,22 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] +#![allow(dead_code)] +#![allow(unused_variables)] +#![deny(unreachable_patterns)] + +enum IntList { + Cons(isize, Box), + Nil +} + +fn tail(source_list: &IntList) -> IntList { + match source_list { + &IntList::Cons(val, box ref next_list) => tail(next_list), + &IntList::Cons(val, box IntList::Nil) => IntList::Cons(val, box IntList::Nil), +// { dg-error "" "" { target *-*-* } .-1 } + _ => panic!() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12127.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12127.rs new file mode 100644 index 000000000000..81d698a3e13e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12127.rs @@ -0,0 +1,15 @@ +#![feature(box_syntax, unboxed_closures)] + +fn to_fn_once>(f: F) -> F { f } +fn do_it(x: &isize) { } + +fn main() { + let x: Box<_> = box 22; + let f = to_fn_once(move|| do_it(&*x)); + to_fn_once(move|| { + f(); + f(); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + })() +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12133-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12133-1.rs new file mode 100644 index 000000000000..e4242b54acc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12133-1.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:issue-12133-rlib.rs +// aux-build:issue-12133-dylib.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_12133_rlib as a; +extern crate issue_12133_dylib as b; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12133-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12133-2.rs new file mode 100644 index 000000000000..b03799f93b20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12133-2.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-12133-rlib.rs +// aux-build:issue-12133-dylib.rs +// no-prefer-dynamic + +// pretty-expanded FIXME #23616 + +extern crate issue_12133_rlib as a; +extern crate issue_12133_dylib as b; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12133-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12133-3.rs new file mode 100644 index 000000000000..9b4368b01a65 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12133-3.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:issue-12133-rlib.rs +// aux-build:issue-12133-dylib.rs +// aux-build:issue-12133-dylib2.rs +// ignore-cloudabi no dylib support +// ignore-emscripten no dylib support +// ignore-musl +// ignore-sgx no dylib support + +// pretty-expanded FIXME #23616 + +extern crate issue_12133_dylib2 as other; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12187-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12187-1.rs new file mode 100644 index 000000000000..5e7a3b82c19b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12187-1.rs @@ -0,0 +1,9 @@ +fn new() -> &'static T { + panic!() +} + +fn main() { + let &v = new(); +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12187-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12187-2.rs new file mode 100644 index 000000000000..33097c2b0ba2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12187-2.rs @@ -0,0 +1,9 @@ +fn new<'r, T>() -> &'r T { + panic!() +} + +fn main() { + let &v = new(); +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12285.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12285.rs new file mode 100644 index 000000000000..68887373cbcc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12285.rs @@ -0,0 +1,15 @@ +// run-pass + +struct S; + +fn main() { + match Some(&S) { + Some(&S) => {}, + _x => unreachable!() + } + match Some(&S) { + Some(&S) => {}, + None => unreachable!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12369.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12369.rs new file mode 100644 index 000000000000..1ab9bb1512f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12369.rs @@ -0,0 +1,12 @@ +#![deny(unreachable_patterns)] + +fn main() { + let sl = vec![1,2,3]; + let v: isize = match &*sl { + &[] => 0, + &[a,b,c] => 3, + &[a, ref rest @ ..] => a, + &[10,a, ref rest @ ..] => 10 // { dg-error "" "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12470.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12470.rs new file mode 100644 index 000000000000..9294d608ad42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12470.rs @@ -0,0 +1,35 @@ +#![feature(box_syntax)] + +trait X { + fn get_i(&self) -> isize; +} + + +struct B { + i: isize +} + +impl X for B { + fn get_i(&self) -> isize { + self.i + } +} + +struct A<'a> { + p: &'a (dyn X + 'a) +} + +fn make_a<'a>(p: &'a dyn X) -> A<'a> { + A { p: p } +} + +fn make_make_a<'a>() -> A<'a> { + let b: Box = box B {i:1}; + let bb: &B = &*b; + make_a(bb) // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() { + let _a = make_make_a(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1251.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1251.rs new file mode 100644 index 000000000000..844555fc33d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1251.rs @@ -0,0 +1,18 @@ +// build-pass +#![allow(unused_attributes)] +#![allow(dead_code)] +// pretty-expanded FIXME #23616 +// ignore-wasm32-bare no libc to test ffi with + +#![feature(rustc_private)] + +mod rustrt { + extern crate libc; + + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12511.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12511.rs new file mode 100644 index 000000000000..aa53a3f5a865 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12511.rs @@ -0,0 +1,9 @@ +trait T1 : T2 { +// { dg-error ".E0391." "" { target *-*-* } .-1 } +} + +trait T2 : T1 { +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12552.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12552.rs new file mode 100644 index 000000000000..0c28f8ca8995 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12552.rs @@ -0,0 +1,12 @@ +// this code used to cause an ICE + +fn main() { + let t = Err(0); + match t { + Some(k) => match k { // { dg-error ".E0308." "" { target *-*-* } } + a => println!("{}", a) + }, + None => () // { dg-error ".E0308." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12567.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12567.rs new file mode 100644 index 000000000000..145697a5311d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12567.rs @@ -0,0 +1,14 @@ +fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) { + match (l1, l2) { +// { dg-error ".E0508." "" { target *-*-* } .-1 } +// { dg-error ".E0508." "" { target *-*-* } .-2 } + (&[], &[]) => println!("both empty"), + (&[], &[hd, ..]) | (&[hd, ..], &[]) + => println!("one empty"), + (&[hd1, ..], &[hd2, ..]) + => println!("both nonempty"), + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1257.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1257.rs new file mode 100644 index 000000000000..e37100faa9b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1257.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main () { + let mut line = "".to_string(); + let mut i = 0; + while line != "exit".to_string() { + line = if i == 9 { "exit".to_string() } else { "notexit".to_string() }; + i += 1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12582.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12582.rs new file mode 100644 index 000000000000..8ef0ea82018e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12582.rs @@ -0,0 +1,22 @@ +// run-pass + +pub fn main() { + let x = 1; + let y = 2; + + assert_eq!(3, match (x, y) { + (1, 1) => 1, + (2, 2) => 2, + (1..=2, 2) => 3, + _ => 4, + }); + + // nested tuple + assert_eq!(3, match ((x, y),) { + ((1, 1),) => 1, + ((2, 2),) => 2, + ((1..=2, 2),) => 3, + _ => 4, + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12612.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12612.rs new file mode 100644 index 000000000000..ee577ad49cb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12612.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(unused_imports)] +// aux-build:issue-12612-1.rs +// aux-build:issue-12612-2.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_12612_1 as foo; +extern crate issue_12612_2 as bar; + +mod test { + use bar::baz; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12660.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12660.rs new file mode 100644 index 000000000000..67b5d66f9bf2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12660.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:issue-12660-aux.rs + +// pretty-expanded FIXME #23616 + +extern crate issue12660aux; + +use issue12660aux::{my_fn, MyStruct}; + +#[allow(path_statements)] +fn main() { + my_fn(MyStruct); + MyStruct; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12677.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12677.rs new file mode 100644 index 000000000000..7c579391873a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12677.rs @@ -0,0 +1,10 @@ +// run-pass + +fn main() { + let s = "Hello"; + let first = s.bytes(); + let second = first.clone(); + + assert_eq!(first.collect::>(), second.collect::>()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12699.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12699.rs new file mode 100644 index 000000000000..4c624e84d466 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12699.rs @@ -0,0 +1,11 @@ +// run-pass +// ignore-wasm32-bare can't block the thread +// ignore-sgx not supported +#![allow(deprecated)] + +use std::thread; + +fn main() { + thread::sleep_ms(250); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12729.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12729.rs new file mode 100644 index 000000000000..5920b5aedfcc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12729.rs @@ -0,0 +1,15 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +pub struct Foo; + +mod bar { + use Foo; + + impl Foo { + fn baz(&self) {} + } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12744.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12744.rs new file mode 100644 index 000000000000..fe8ca636c124 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12744.rs @@ -0,0 +1,6 @@ +// run-pass +fn main() { + fn test() -> Box { Box::new(1) } + println!("{:?}", test()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12796.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12796.rs new file mode 100644 index 000000000000..1bdeb60e97e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12796.rs @@ -0,0 +1,10 @@ +trait Trait { + fn outer(&self) { + fn inner(_: &Self) { +// { dg-error ".E0401." "" { target *-*-* } .-1 } + } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12860.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12860.rs new file mode 100644 index 000000000000..3bc8f80e09ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12860.rs @@ -0,0 +1,50 @@ +// run-pass +use std::collections::HashSet; + +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +struct XYZ { + x: isize, + y: isize, + z: isize +} + +fn main() { + let mut connected = HashSet::new(); + let mut border = HashSet::new(); + + let middle = XYZ{x: 0, y: 0, z: 0}; + border.insert(middle); + + while !border.is_empty() && connected.len() < 10000 { + let choice = *(border.iter().next().unwrap()); + border.remove(&choice); + connected.insert(choice); + + let cxp = XYZ{x: choice.x + 1, y: choice.y, z: choice.z}; + let cxm = XYZ{x: choice.x - 1, y: choice.y, z: choice.z}; + let cyp = XYZ{x: choice.x, y: choice.y + 1, z: choice.z}; + let cym = XYZ{x: choice.x, y: choice.y - 1, z: choice.z}; + let czp = XYZ{x: choice.x, y: choice.y, z: choice.z + 1}; + let czm = XYZ{x: choice.x, y: choice.y, z: choice.z - 1}; + + if !connected.contains(&cxp) { + border.insert(cxp); + } + if !connected.contains(&cxm){ + border.insert(cxm); + } + if !connected.contains(&cyp){ + border.insert(cyp); + } + if !connected.contains(&cym) { + border.insert(cym); + } + if !connected.contains(&czp){ + border.insert(czp); + } + if !connected.contains(&czm) { + border.insert(czm); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12863.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12863.rs new file mode 100644 index 000000000000..ea20bac9da67 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12863.rs @@ -0,0 +1,9 @@ +mod foo { pub fn bar() {} } + +fn main() { + match () { + foo::bar => {} +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12909.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12909.rs new file mode 100644 index 000000000000..0eb48d17b506 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12909.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +use std::collections::HashMap; + +fn copy(&x: &T) -> T { + x +} + +fn main() { + let arr = [(1, 1), (2, 2), (3, 3)]; + + let v1: Vec<&_> = arr.iter().collect(); + let v2: Vec<_> = arr.iter().map(copy).collect(); + + let m1: HashMap<_, _> = arr.iter().map(copy).collect(); + let m2: HashMap = arr.iter().map(copy).collect(); + let m3: HashMap<_, usize> = arr.iter().map(copy).collect(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12920.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12920.rs new file mode 100644 index 000000000000..b8e5e8a7f88f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12920.rs @@ -0,0 +1,9 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +pub fn main() { + panic!(); + println!("{}", 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12997-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12997-1.rs new file mode 100644 index 000000000000..a3a26daae9cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12997-1.rs @@ -0,0 +1,12 @@ +// compile-flags: --test + +//! Test that makes sure wrongly-typed bench functions aren't ignored + +#![feature(test)] + +#[bench] +fn foo() { } // { dg-error "" "" { target *-*-* } } + +#[bench] +fn bar(x: isize, y: isize) { } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-12997-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-12997-2.rs new file mode 100644 index 000000000000..6fdac7e1ebdd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-12997-2.rs @@ -0,0 +1,10 @@ +// compile-flags: --test + +//! Test that makes sure wrongly-typed bench functions are rejected + +#![feature(test)] + +#[bench] +fn bar(x: isize) { } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13027.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13027.rs new file mode 100644 index 000000000000..2ade93e46191 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13027.rs @@ -0,0 +1,179 @@ +// run-pass + +// Tests that match expression handles overlapped literal and range +// properly in the presence of guard function. + +fn val() -> usize { 1 } + +static CONST: usize = 1; + +pub fn main() { + lit_shadow_range(); + range_shadow_lit(); + range_shadow_range(); + multi_pats_shadow_lit(); + multi_pats_shadow_range(); + lit_shadow_multi_pats(); + range_shadow_multi_pats(); + misc(); +} + +fn lit_shadow_range() { + assert_eq!(2, match 1 { + 1 if false => 1, + 1..=2 => 2, + _ => 3 + }); + + let x = 0; + assert_eq!(2, match x+1 { + 0 => 0, + 1 if false => 1, + 1..=2 => 2, + _ => 3 + }); + + assert_eq!(2, match val() { + 1 if false => 1, + 1..=2 => 2, + _ => 3 + }); + + assert_eq!(2, match CONST { + 0 => 0, + 1 if false => 1, + 1..=2 => 2, + _ => 3 + }); + + // value is out of the range of second arm, should match wildcard pattern + assert_eq!(3, match 3 { + 1 if false => 1, + 1..=2 => 2, + _ => 3 + }); +} + +fn range_shadow_lit() { + assert_eq!(2, match 1 { + 1..=2 if false => 1, + 1 => 2, + _ => 3 + }); + + let x = 0; + assert_eq!(2, match x+1 { + 0 => 0, + 1..=2 if false => 1, + 1 => 2, + _ => 3 + }); + + assert_eq!(2, match val() { + 1..=2 if false => 1, + 1 => 2, + _ => 3 + }); + + assert_eq!(2, match CONST { + 0 => 0, + 1..=2 if false => 1, + 1 => 2, + _ => 3 + }); + + // ditto + assert_eq!(3, match 3 { + 1..=2 if false => 1, + 1 => 2, + _ => 3 + }); +} + +fn range_shadow_range() { + assert_eq!(2, match 1 { + 0..=2 if false => 1, + 1..=3 => 2, + _ => 3, + }); + + let x = 0; + assert_eq!(2, match x+1 { + 100 => 0, + 0..=2 if false => 1, + 1..=3 => 2, + _ => 3, + }); + + assert_eq!(2, match val() { + 0..=2 if false => 1, + 1..=3 => 2, + _ => 3, + }); + + assert_eq!(2, match CONST { + 100 => 0, + 0..=2 if false => 1, + 1..=3 => 2, + _ => 3, + }); + + // ditto + assert_eq!(3, match 5 { + 0..=2 if false => 1, + 1..=3 => 2, + _ => 3, + }); +} + +fn multi_pats_shadow_lit() { + assert_eq!(2, match 1 { + 100 => 0, + 0 | 1..=10 if false => 1, + 1 => 2, + _ => 3, + }); +} + +fn multi_pats_shadow_range() { + assert_eq!(2, match 1 { + 100 => 0, + 0 | 1..=10 if false => 1, + 1..=3 => 2, + _ => 3, + }); +} + +fn lit_shadow_multi_pats() { + assert_eq!(2, match 1 { + 100 => 0, + 1 if false => 1, + 0 | 1..=10 => 2, + _ => 3, + }); +} + +fn range_shadow_multi_pats() { + assert_eq!(2, match 1 { + 100 => 0, + 1..=3 if false => 1, + 0 | 1..=10 => 2, + _ => 3, + }); +} + +fn misc() { + enum Foo { + Bar(usize, bool) + } + // This test basically mimics how trace_macros! macro is implemented, + // which is a rare combination of vector patterns, multiple wild-card + // patterns and guard functions. + let r = match [Foo::Bar(0, false)] { + [Foo::Bar(_, pred)] if pred => 1, + [Foo::Bar(_, pred)] if !pred => 2, + _ => 0, + }; + assert_eq!(2, r); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13033.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13033.rs new file mode 100644 index 000000000000..a283ef108d9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13033.rs @@ -0,0 +1,15 @@ +trait Foo { + fn bar(&mut self, other: &mut dyn Foo); +} + +struct Baz; + +impl Foo for Baz { + fn bar(&mut self, other: &dyn Foo) {} +// { dg-error ".E0053." "" { target *-*-* } .-1 } +// { dg-error ".E0053." "" { target *-*-* } .-2 } +// { dg-error ".E0053." "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13058.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13058.rs new file mode 100644 index 000000000000..8f6681af4b04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13058.rs @@ -0,0 +1,28 @@ +use std::ops::Range; + +trait Itble<'r, T, I: Iterator> { fn iter(&'r self) -> I; } + +impl<'r> Itble<'r, usize, Range> for (usize, usize) { + fn iter(&'r self) -> Range { + let &(min, max) = self; + min..max + } +} + +fn check<'r, I: Iterator, T: Itble<'r, usize, I>>(cont: &T) -> bool +{ + let cont_iter = cont.iter(); +// { dg-error ".E0621." "" { target *-*-* } .-1 } + let result = cont_iter.fold(Some(0), |state, val| { + state.map_or(None, |mask| { + let bit = 1 << val; + if mask & bit == 0 {Some(mask|bit)} else {None} + }) + }); + result.is_some() +} + +fn main() { + check(&(3, 5)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13105.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13105.rs new file mode 100644 index 000000000000..b92b18f29cde --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13105.rs @@ -0,0 +1,10 @@ +// check-pass +// pretty-expanded FIXME #23616 + +trait Foo { + #[allow(anonymous_parameters)] + fn quux(u8) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13167.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13167.rs new file mode 100644 index 000000000000..bb8d0a3d29c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13167.rs @@ -0,0 +1,23 @@ +// check-pass +// pretty-expanded FIXME #23616 + +use std::slice; + +pub struct PhfMapEntries<'a, T: 'a> { + iter: slice::Iter<'a, (&'static str, T)>, +} + +impl<'a, T> Iterator for PhfMapEntries<'a, T> { + type Item = (&'static str, &'a T); + + fn next(&mut self) -> Option<(&'static str, &'a T)> { + self.iter.by_ref().map(|&(key, ref value)| (key, value)).next() + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13202.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13202.rs new file mode 100644 index 000000000000..fe261e0485d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13202.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:bad input +// ignore-emscripten no processes + +fn main() { + Some("foo").unwrap_or(panic!("bad input")).to_string(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13204.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13204.rs new file mode 100644 index 000000000000..410abfeefdb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13204.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(unused_mut)] +// Test that when instantiating trait default methods, typeck handles +// lifetime parameters defined on the method bound correctly. + + +pub trait Foo { + fn bar<'a, I: Iterator>(&self, it: I) -> usize { + let mut xs = it.filter(|_| true); + xs.count() + } +} + +pub struct Baz; + +impl Foo for Baz { + // When instantiating `Foo::bar` for `Baz` here, typeck used to + // ICE due to the lifetime parameter of `bar`. +} + +fn main() { + let x = Baz; + let y = vec![(), (), ()]; + assert_eq!(x.bar(y.iter()), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13214.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13214.rs new file mode 100644 index 000000000000..447f7c211efe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13214.rs @@ -0,0 +1,24 @@ +// build-pass +#![allow(dead_code)] +// defining static with struct that contains enum +// with &'static str variant used to cause ICE + +// pretty-expanded FIXME #23616 + +pub enum Foo { + Bar, + Baz(&'static str), +} + +pub static TEST: Test = Test { + foo: Foo::Bar, + c: 'a' +}; + +pub struct Test { + foo: Foo, + c: char, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13259-windows-tcb-trash.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13259-windows-tcb-trash.rs new file mode 100644 index 000000000000..3b60146b7fef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13259-windows-tcb-trash.rs @@ -0,0 +1,43 @@ +// run-pass +#![feature(rustc_private)] + +extern crate libc; + +#[cfg(windows)] +mod imp { + type LPVOID = *mut u8; + type DWORD = u32; + type LPWSTR = *mut u16; + + extern "system" { + fn FormatMessageW(flags: DWORD, + lpSrc: LPVOID, + msgId: DWORD, + langId: DWORD, + buf: LPWSTR, + nsize: DWORD, + args: *const u8) + -> DWORD; + } + + pub fn test() { + let mut buf: [u16; 50] = [0; 50]; + let ret = unsafe { + FormatMessageW(0x1000, core::ptr::null_mut(), 1, 0x400, + buf.as_mut_ptr(), buf.len() as u32, core::ptr::null()) + }; + // On some 32-bit Windowses (Win7-8 at least) this will panic with segmented + // stacks taking control of pvArbitrary + assert!(ret != 0); + } +} + +#[cfg(not(windows))] +mod imp { + pub fn test() { } +} + +fn main() { + imp::test() +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13264.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13264.rs new file mode 100644 index 000000000000..8165e972c173 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13264.rs @@ -0,0 +1,75 @@ +// run-pass +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +use std::ops::Deref; + +struct Root { + jsref: JSRef +} + +impl Deref for Root { + type Target = JSRef; + + fn deref<'a>(&'a self) -> &'a JSRef { + &self.jsref + } +} + +#[derive(Copy, Clone)] +struct JSRef { + node: *const Node +} + +impl Deref for JSRef { + type Target = Node; + + fn deref<'a>(&'a self) -> &'a Node { + self.get() + } +} + +trait INode { + fn RemoveChild(&self); +} + +impl INode for JSRef { + fn RemoveChild(&self) { + self.get().RemoveChild(0) + } +} + +impl JSRef { + fn AddChild(&self) { + self.get().AddChild(0); + } + + fn get<'a>(&'a self) -> &'a Node { + unsafe { + &*self.node + } + } +} + +struct Node; + +impl Node { + fn RemoveChild(&self, _a: usize) { + } + + fn AddChild(&self, _a: usize) { + } +} + +fn main() { + let n = Node; + let jsref = JSRef { node: &n }; + let root = Root { jsref: jsref }; + + root.AddChild(); + jsref.AddChild(); + + root.RemoveChild(); + jsref.RemoveChild(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13304.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13304.rs new file mode 100644 index 000000000000..df09fcd539d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13304.rs @@ -0,0 +1,41 @@ +// run-pass +#![allow(unused_mut)] +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::env; +use std::io::prelude::*; +use std::io; +use std::process::{Command, Stdio}; +use std::str; + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "child" { + child(); + } else { + parent(); + } +} + +fn parent() { + let args: Vec = env::args().collect(); + let mut p = Command::new(&args[0]).arg("child") + .stdout(Stdio::piped()) + .stdin(Stdio::piped()) + .spawn().unwrap(); + p.stdin.as_mut().unwrap().write_all(b"test1\ntest2\ntest3").unwrap(); + let out = p.wait_with_output().unwrap(); + assert!(out.status.success()); + let s = str::from_utf8(&out.stdout).unwrap(); + assert_eq!(s, "test1\ntest2\ntest3\n"); +} + +fn child() { + let mut stdin = io::stdin(); + for line in stdin.lock().lines() { + println!("{}", line.unwrap()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13323.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13323.rs new file mode 100644 index 000000000000..ca11d0811b55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13323.rs @@ -0,0 +1,60 @@ +// run-pass +#![feature(box_syntax)] + +struct StrWrap { + s: String +} + +impl StrWrap { + fn new(s: &str) -> StrWrap { + StrWrap { s: s.to_string() } + } + + fn get_s<'a>(&'a self) -> &'a str { + &self.s + } +} + +struct MyStruct { + s: StrWrap +} + +impl MyStruct { + fn new(s: &str) -> MyStruct { + MyStruct { s: StrWrap::new(s) } + } + + fn get_str_wrap<'a>(&'a self) -> &'a StrWrap { + &self.s + } +} + +trait Matcher { + fn matches(&self, actual: T) -> bool; +} + +fn assert_that>(actual: T, matcher: &U) { + assert!(matcher.matches(actual)); +} + +struct EqualTo { + expected: T +} + +impl Matcher for EqualTo { + fn matches(&self, actual: T) -> bool { + self.expected.eq(&actual) + } +} + +fn equal_to(expected: T) -> Box> { + box EqualTo { expected: expected } +} + +pub fn main() { + let my_struct = MyStruct::new("zomg"); + let s = my_struct.get_str_wrap(); + + assert_that(s.get_s(), &*equal_to("zomg")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13359.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13359.rs new file mode 100644 index 000000000000..1a7d8bcbf174 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13359.rs @@ -0,0 +1,14 @@ +fn foo(_s: i16) { } + +fn bar(_s: u32) { } + +fn main() { + foo(1*(1 as isize)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + bar(1*(1 as usize)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13404.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13404.rs new file mode 100644 index 000000000000..2ffcd068fbe3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13404.rs @@ -0,0 +1,11 @@ +use a::f; +use b::f; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +mod a { pub fn f() {} } +mod b { } + +fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13405.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13405.rs new file mode 100644 index 000000000000..c9705bea78a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13405.rs @@ -0,0 +1,21 @@ +// check-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +struct Foo<'a> { + i: &'a bool, + j: Option<&'a isize>, +} + +impl<'a> Foo<'a> { + fn bar(&mut self, j: &isize) { + let child = Foo { + i: self.i, + j: Some(j) + }; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13407.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13407.rs new file mode 100644 index 000000000000..52645044262c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13407.rs @@ -0,0 +1,11 @@ +mod A { + struct C; +} + +fn main() { + A::C = 1; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13434.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13434.rs new file mode 100644 index 000000000000..9bde77f5e31b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13434.rs @@ -0,0 +1,22 @@ +// run-pass +#[derive(Debug)] +struct MyStruct; + +trait Repro { + fn repro(self, s: MyStruct) -> String; +} + +impl Repro for F where F: FnOnce(MyStruct) -> String { + fn repro(self, s: MyStruct) -> String { + self(s) + } +} + +fn do_stuff(r: R) -> String { + r.repro(MyStruct) +} + +pub fn main() { + assert_eq!("MyStruct".to_string(), do_stuff(|s: MyStruct| format!("{:?}", s))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13446.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13446.rs new file mode 100644 index 000000000000..c4ff66b04de5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13446.rs @@ -0,0 +1,7 @@ +// Used to cause ICE + +static VEC: [u32; 256] = vec![]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13466.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13466.rs new file mode 100644 index 000000000000..ffaafcffc084 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13466.rs @@ -0,0 +1,21 @@ +// Regression test for #13466 + +pub fn main() { + // The expected arm type `Option` has one type parameter, while + // the actual arm `Result` has two. typeck should not be + // tricked into looking up a non-existing second type parameter. + let _x: usize = match Some(1) { + Ok(u) => u, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + Err(e) => panic!(e) +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13482-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13482-2.rs new file mode 100644 index 000000000000..9ca5862b914b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13482-2.rs @@ -0,0 +1,10 @@ +// compile-flags:-Z verbose + +fn main() { + let x = [1,2]; + let y = match x { + [] => None, // { dg-error ".E0527." "" { target *-*-* } } + [a,_] => Some(a) + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13482.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13482.rs new file mode 100644 index 000000000000..fa4d59da4707 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13482.rs @@ -0,0 +1,8 @@ +fn main() { + let x = [1,2]; + let y = match x { + [] => None, // { dg-error ".E0527." "" { target *-*-* } } + [a,_] => Some(a) + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13483.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13483.rs new file mode 100644 index 000000000000..ca9dae8df8da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13483.rs @@ -0,0 +1,18 @@ +fn main() { + if true { + } else if { // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } else { + } +} + +fn foo() { + if true { + } else if { // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } + bar(); +} + +fn bar() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13497-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13497-2.rs new file mode 100644 index 000000000000..49ee0a7ae53c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13497-2.rs @@ -0,0 +1,8 @@ +fn read_lines_borrowed<'a>() -> Vec<&'a str> { + let rawLines: Vec = vec!["foo ".to_string(), " bar".to_string()]; + rawLines // { dg-error ".E0515." "" { target *-*-* } } + .iter().map(|l| l.trim()).collect() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13497.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13497.rs new file mode 100644 index 000000000000..fcb53044a85a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13497.rs @@ -0,0 +1,9 @@ +fn read_lines_borrowed1() -> Vec< + &str // { dg-error ".E0106." "" { target *-*-* } } +> { + let rawLines: Vec = vec!["foo ".to_string(), " bar".to_string()]; + rawLines.iter().map(|l| l.trim()).collect() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13507-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13507-2.rs new file mode 100644 index 000000000000..8ea7165d626f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13507-2.rs @@ -0,0 +1,37 @@ +// run-pass +#![allow(unused_imports)] +// aux-build:issue-13507.rs + +extern crate issue_13507; +use issue_13507::testtypes; + +use std::any::TypeId; + +pub fn type_ids() -> Vec { + use issue_13507::testtypes::*; + vec![ + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::(), + TypeId::of::() + ] +} + +pub fn main() { + let othercrate = issue_13507::testtypes::type_ids(); + let thiscrate = type_ids(); + assert_eq!(thiscrate, othercrate); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1362.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1362.rs new file mode 100644 index 000000000000..ea13b8e0c730 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1362.rs @@ -0,0 +1,9 @@ +// Regression test for issue #1362 - without that fix the span will be bogus +// no-reformat +fn main() { + let x: u32 = 20i32; // { dg-error ".E0308." "" { target *-*-* } } +} +// NOTE: Do not add any extra lines as the line number the error is +// on is significant; an error later in the source file might not +// trigger the bug. + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13620.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13620.rs new file mode 100644 index 000000000000..816b2f25ab6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13620.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-13620-1.rs +// aux-build:issue-13620-2.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_13620_2 as crate2; + +fn main() { + (crate2::FOO2.foo)(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13641.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13641.rs new file mode 100644 index 000000000000..ec98bbf78848 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13641.rs @@ -0,0 +1,14 @@ +mod a { + struct Foo; + impl Foo { pub fn new() {} } + enum Bar {} + impl Bar { pub fn new() {} } +} + +fn main() { + a::Foo::new(); +// { dg-error ".E0603." "" { target *-*-* } .-1 } + a::Bar::new(); +// { dg-error ".E0603." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13655.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13655.rs new file mode 100644 index 000000000000..9fe9b6224753 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13655.rs @@ -0,0 +1,33 @@ +// run-pass +#![feature(fn_traits, unboxed_closures)] +use std::ops::Fn; + +struct Foo(T); + +impl Fn<()> for Foo { + extern "rust-call" fn call(&self, _: ()) -> T { + match *self { + Foo(t) => t + } + } +} + +impl FnMut<()> for Foo { + extern "rust-call" fn call_mut(&mut self, _: ()) -> T { + self.call(()) + } +} + +impl FnOnce<()> for Foo { + type Output = T; + + extern "rust-call" fn call_once(self, _: ()) -> T { + self.call(()) + } +} + +fn main() { + let t: u8 = 1; + println!("{}", Foo(t)()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13665.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13665.rs new file mode 100644 index 000000000000..60f5a73b3c7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13665.rs @@ -0,0 +1,16 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn foo<'r>() { + let maybe_value_ref: Option<&'r u8> = None; + + let _ = maybe_value_ref.map(|& ref v| v); + let _ = maybe_value_ref.map(|& ref v| -> &'r u8 {v}); + let _ = maybe_value_ref.map(|& ref v: &'r u8| -> &'r u8 {v}); + let _ = maybe_value_ref.map(|& ref v: &'r u8| {v}); +} + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13703.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13703.rs new file mode 100644 index 000000000000..f2e1ac0ddab6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13703.rs @@ -0,0 +1,7 @@ +// check-pass +// pretty-expanded FIXME #23616 + +pub struct Foo<'a, 'b: 'a> { foo: &'a &'b isize } +pub fn foo<'a, 'b>(x: Foo<'a, 'b>, _o: Option<& & ()>) { let _y = x.foo; } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13727.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13727.rs new file mode 100644 index 000000000000..75eb7d0fb469 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13727.rs @@ -0,0 +1,16 @@ +#![allow(overflowing_literals)] +#![deny(unreachable_patterns)] + +fn test(val: u8) { + match val { + 256 => print!("0b1110\n"), + 512 => print!("0b1111\n"), +// { dg-error "" "" { target *-*-* } .-1 } + _ => print!("fail\n"), + } +} + +fn main() { + test(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13763.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13763.rs new file mode 100644 index 000000000000..3ac70ad2ea98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13763.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +mod u8 { + pub const BITS: usize = 8; +} + +const NUM: usize = u8::BITS; + +struct MyStruct { nums: [usize; 8] } + +fn main() { + let _s = MyStruct { nums: [0; NUM] }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13775.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13775.rs new file mode 100644 index 000000000000..00ec778b9666 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13775.rs @@ -0,0 +1,10 @@ +// check-pass +// pretty-expanded FIXME #23616 + +trait Foo { + #[allow(anonymous_parameters)] + fn bar(&self, isize) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13808.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13808.rs new file mode 100644 index 000000000000..f95217b4e5ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13808.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +struct Foo<'a> { + listener: Box, +} + +impl<'a> Foo<'a> { + fn new(listener: F) -> Foo<'a> where F: FnMut() + 'a { + Foo { listener: Box::new(listener) } + } +} + +fn main() { + let a = Foo::new(|| {}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13837.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13837.rs new file mode 100644 index 000000000000..ba964aaad7ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13837.rs @@ -0,0 +1,14 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct TestStruct { + x: *const [isize; 2] +} + +unsafe impl Sync for TestStruct {} + +static TEST_VALUE : TestStruct = TestStruct{x: 0x1234 as *const [isize; 2]}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13847.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13847.rs new file mode 100644 index 000000000000..9c81844ae3fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13847.rs @@ -0,0 +1,4 @@ +fn main() { + return.is_failure // { dg-error ".E0609." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13853-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13853-2.rs new file mode 100644 index 000000000000..e6240ce28d17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13853-2.rs @@ -0,0 +1,7 @@ +trait FromStructReader<'a> { } +trait ResponseHook { + fn get(&self); +} +fn foo(res : Box) { res.get } // { dg-error ".E0615." "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13853-5.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13853-5.rs new file mode 100644 index 000000000000..d87e30a54575 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13853-5.rs @@ -0,0 +1,14 @@ +trait Deserializer<'a> { } + +trait Deserializable { + fn deserialize_token<'a, D: Deserializer<'a>>(_: D, _: &'a str) -> Self; +} + +impl<'a, T: Deserializable> Deserializable for &'a str { +// { dg-error ".E0207." "" { target *-*-* } .-1 } + fn deserialize_token>(_x: D, _y: &'a str) -> &'a str { + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13853.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13853.rs new file mode 100644 index 000000000000..10b8730d5f01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13853.rs @@ -0,0 +1,39 @@ +trait Node { + fn zomg(); +} + +trait Graph { + fn nodes<'a, I: Iterator>(&'a self) -> I + where N: 'a; +} + +impl Graph for Vec { + fn nodes<'a, I: Iterator>(&self) -> I + where N: 'a + { + self.iter() // { dg-error ".E0308." "" { target *-*-* } } + } +} + +struct Stuff; + +impl Node for Stuff { + fn zomg() { + println!("zomg"); + } +} + +fn iterate>(graph: &G) { + for node in graph.iter() { // { dg-error ".E0599." "" { target *-*-* } } + node.zomg(); + } +} + +pub fn main() { + let graph = Vec::new(); + + graph.push(Stuff); + + iterate(graph); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13867.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13867.rs new file mode 100644 index 000000000000..e5f754b40906 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13867.rs @@ -0,0 +1,49 @@ +// run-pass +// Test that codegen works correctly when there are multiple refutable +// patterns in match expression. + +enum Foo { + FooUint(usize), + FooNullary, +} + +fn main() { + let r = match (Foo::FooNullary, 'a') { + (Foo::FooUint(..), 'a'..='z') => 1, + (Foo::FooNullary, 'x') => 2, + _ => 0 + }; + assert_eq!(r, 0); + + let r = match (Foo::FooUint(0), 'a') { + (Foo::FooUint(1), 'a'..='z') => 1, + (Foo::FooUint(..), 'x') => 2, + (Foo::FooNullary, 'a') => 3, + _ => 0 + }; + assert_eq!(r, 0); + + let r = match ('a', Foo::FooUint(0)) { + ('a'..='z', Foo::FooUint(1)) => 1, + ('x', Foo::FooUint(..)) => 2, + ('a', Foo::FooNullary) => 3, + _ => 0 + }; + assert_eq!(r, 0); + + let r = match ('a', 'a') { + ('a'..='z', 'b') => 1, + ('x', 'a'..='z') => 2, + _ => 0 + }; + assert_eq!(r, 0); + + let r = match ('a', 'a') { + ('a'..='z', 'b') => 1, + ('x', 'a'..='z') => 2, + ('a', 'a') => 3, + _ => 0 + }; + assert_eq!(r, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13872.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13872.rs new file mode 100644 index 000000000000..b1e388bbdf31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13872.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:issue-13872-1.rs +// aux-build:issue-13872-2.rs +// aux-build:issue-13872-3.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_13872_3 as other; + +fn main() { + other::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-13902.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-13902.rs new file mode 100644 index 000000000000..cda901426d6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-13902.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +const JSVAL_TAG_CLEAR: u32 = 0xFFFFFF80; +const JSVAL_TYPE_INT32: u8 = 0x01; +const JSVAL_TYPE_UNDEFINED: u8 = 0x02; +#[repr(u32)] +enum ValueTag { + JSVAL_TAG_INT32 = JSVAL_TAG_CLEAR | (JSVAL_TYPE_INT32 as u32), + JSVAL_TAG_UNDEFINED = JSVAL_TAG_CLEAR | (JSVAL_TYPE_UNDEFINED as u32), +} + +fn main() { + let _ = ValueTag::JSVAL_TAG_INT32; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14082.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14082.rs new file mode 100644 index 000000000000..6aa824ec60c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14082.rs @@ -0,0 +1,21 @@ +// check-pass +// pretty-expanded FIXME #23616 + +#![allow(unused_imports, dead_code)] + +use foo::Foo; + +mod foo { + pub use m::Foo; // this should shadow d::Foo +} + +mod m { + pub struct Foo; +} + +mod d { + pub struct Foo; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14091-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14091-2.rs new file mode 100644 index 000000000000..8a269a4c347f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14091-2.rs @@ -0,0 +1,18 @@ +// + +// Very + +// sensitive +pub struct BytePos(pub u32); + +// to particular + +// line numberings / offsets + +fn main() { + let x = BytePos(1); + + assert!(x, x); +// { dg-error ".E0600." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14091.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14091.rs new file mode 100644 index 000000000000..cb27d5f16cc9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14091.rs @@ -0,0 +1,5 @@ +fn main(){ + assert!(1,1); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14092.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14092.rs new file mode 100644 index 000000000000..fc9fec349a58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14092.rs @@ -0,0 +1,5 @@ +fn fn1(0: Box) {} +// { dg-error ".E0107." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14221.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14221.rs new file mode 100644 index 000000000000..6ba597feffd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14221.rs @@ -0,0 +1,22 @@ +#![deny(unreachable_patterns)] +#![allow(unused_variables)] +#![allow(non_snake_case)] + +pub enum E { + A, + B, +} + +pub mod b { + pub fn key(e: ::E) -> &'static str { + match e { + A => "A", +// { dg-warning "" "" { target *-*-* } .-1 } + B => "B", // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14227.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14227.rs new file mode 100644 index 000000000000..f6381d7d73c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14227.rs @@ -0,0 +1,8 @@ +extern { + pub static symbol: u32; +} +static CRASH: u32 = symbol; +// { dg-error ".E0133." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14229.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14229.rs new file mode 100644 index 000000000000..5cf8158b9715 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14229.rs @@ -0,0 +1,22 @@ +// run-pass +trait Foo: Sized { + fn foo(self) {} +} + +trait Bar: Sized { + fn bar(self) {} +} + +struct S; + +impl<'l> Foo for &'l S {} + +impl Bar for T {} + +fn main() { + let s = S; + s.foo(); + (&s).bar(); + s.bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14254.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14254.rs new file mode 100644 index 000000000000..0c3dde226b38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14254.rs @@ -0,0 +1,94 @@ +// check-pass +// pretty-expanded FIXME #23616 + +trait Foo: Sized { + fn bar(&self); + fn baz(&self) { } + fn bah(_: Option) { } +} + +struct BarTy { + x : isize, + y : f64, +} + +impl BarTy { + fn a() {} + fn b(&self) {} +} + +// If these fail, it's necessary to update rustc_resolve and the cfail tests. +impl Foo for *const BarTy { + fn bar(&self) { + self.baz(); + BarTy::a(); + Foo::bah(None::<*const BarTy>); + } +} + +// If these fail, it's necessary to update rustc_resolve and the cfail tests. +impl<'a> Foo for &'a BarTy { + fn bar(&self) { + self.baz(); + self.x; + self.y; + BarTy::a(); + Foo::bah(None::<&BarTy>); + self.b(); + } +} + +// If these fail, it's necessary to update rustc_resolve and the cfail tests. +impl<'a> Foo for &'a mut BarTy { + fn bar(&self) { + self.baz(); + self.x; + self.y; + BarTy::a(); + Foo::bah(None::<&mut BarTy>); + self.b(); + } +} + +// If these fail, it's necessary to update rustc_resolve and the cfail tests. +impl Foo for Box { + fn bar(&self) { + self.baz(); + Foo::bah(None::>); + } +} + +// If these fail, it's necessary to update rustc_resolve and the cfail tests. +impl Foo for *const isize { + fn bar(&self) { + self.baz(); + Foo::bah(None::<*const isize>); + } +} + +// If these fail, it's necessary to update rustc_resolve and the cfail tests. +impl<'a> Foo for &'a isize { + fn bar(&self) { + self.baz(); + Foo::bah(None::<&isize>); + } +} + +// If these fail, it's necessary to update rustc_resolve and the cfail tests. +impl<'a> Foo for &'a mut isize { + fn bar(&self) { + self.baz(); + Foo::bah(None::<&mut isize>); + } +} + +// If these fail, it's necessary to update rustc_resolve and the cfail tests. +impl Foo for Box { + fn bar(&self) { + self.baz(); + Foo::bah(None::>); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14285.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14285.rs new file mode 100644 index 000000000000..b4b319e03c0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14285.rs @@ -0,0 +1,18 @@ +trait Foo { + fn dummy(&self) { } +} + +struct A; + +impl Foo for A {} + +struct B<'a>(&'a (dyn Foo + 'a)); + +fn foo<'a>(a: &dyn Foo) -> B<'a> { + B(a) // { dg-error ".E0621." "" { target *-*-* } } +} + +fn main() { + let _test = foo(&A); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14308.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14308.rs new file mode 100644 index 000000000000..eebb97eaa238 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14308.rs @@ -0,0 +1,16 @@ +// run-pass + +struct A(isize); + +fn main() { + let x = match A(3) { + A(..) => 1 + }; + assert_eq!(x, 1); + let x = match A(4) { + A(1) => 1, + A(..) => 2 + }; + assert_eq!(x, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14309.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14309.rs new file mode 100644 index 000000000000..08c4c3a54c3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14309.rs @@ -0,0 +1,40 @@ +#![deny(improper_ctypes)] +#![allow(dead_code)] + +struct A { + x: i32 +} + +#[repr(C, packed)] +struct B { + x: i32, + y: A +} + +#[repr(C)] +struct C { + x: i32 +} + +type A2 = A; +type B2 = B; +type C2 = C; + +#[repr(C)] +struct D { + x: C, + y: A +} + +extern "C" { + fn foo(x: A); // { dg-error "" "" { target *-*-* } } + fn bar(x: B); // { dg-error "" "" { target *-*-* } } + fn baz(x: C); + fn qux(x: A2); // { dg-error "" "" { target *-*-* } } + fn quux(x: B2); // { dg-error "" "" { target *-*-* } } + fn corge(x: C2); + fn fred(x: D); // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14330.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14330.rs new file mode 100644 index 000000000000..2321f5c580f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14330.rs @@ -0,0 +1,8 @@ +// check-pass +#![allow(unused_imports)] +// pretty-expanded FIXME #23616 + +#[macro_use] extern crate std as std2; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14344.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14344.rs new file mode 100644 index 000000000000..d9da0e9b6080 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14344.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-14344-1.rs +// aux-build:issue-14344-2.rs + +extern crate issue_14344_1; +extern crate issue_14344_2; + +fn main() { + issue_14344_1::foo(); + issue_14344_2::bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14366.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14366.rs new file mode 100644 index 000000000000..59aa7ef19f5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14366.rs @@ -0,0 +1,5 @@ +fn main() { + let _x = "test" as &dyn (::std::any::Any); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14382.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14382.rs new file mode 100644 index 000000000000..106779aa74fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14382.rs @@ -0,0 +1,16 @@ +// run-pass +#[derive(Debug)] +struct Matrix4(S); +trait POrd {} + +fn translate>(s: S) -> Matrix4 { Matrix4(s) } + +impl POrd for f32 {} +impl POrd for f64 {} + +fn main() { + let x = 1.0; + let m : Matrix4 = translate(x); + println!("m: {:?}", m); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14393.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14393.rs new file mode 100644 index 000000000000..39760213b241 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14393.rs @@ -0,0 +1,11 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + match ("", 1_usize) { + (_, 42_usize) => (), + ("", _) => (), + _ => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14399.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14399.rs new file mode 100644 index 000000000000..9c7c8de94922 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14399.rs @@ -0,0 +1,21 @@ +// run-pass +// #14399 +// We'd previously ICE if we had a method call whose return +// value was coerced to a trait object. (v.clone() returns Box +// which is coerced to Box). + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +#[derive(Clone)] +struct B1; + +trait A { fn foo(&self) {} } +impl A for B1 {} + +fn main() { + let v: Box<_> = box B1; + let _c: Box = v.clone(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14421.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14421.rs new file mode 100644 index 000000000000..4009da541176 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14421.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(non_snake_case)] + +// aux-build:issue-14421.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_14421 as bug_lib; + +use bug_lib::B; +use bug_lib::make; + +pub fn main() { + let mut an_A: B = make(); + an_A.foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14422.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14422.rs new file mode 100644 index 000000000000..edfcb8aa9b95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14422.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(non_snake_case)] + +// aux-build:issue-14422.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_14422 as bug_lib; + +use bug_lib::B; +use bug_lib::make; + +pub fn main() { + let mut an_A: B = make(); + an_A.foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14456.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14456.rs new file mode 100644 index 000000000000..48b68f837002 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14456.rs @@ -0,0 +1,39 @@ +// run-pass +#![allow(unused_mut)] +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::env; +use std::io::prelude::*; +use std::io; +use std::process::{Command, Stdio}; + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "child" { + return child() + } + + test(); +} + +fn child() { + writeln!(&mut io::stdout(), "foo").unwrap(); + writeln!(&mut io::stderr(), "bar").unwrap(); + let mut stdin = io::stdin(); + let mut s = String::new(); + stdin.lock().read_line(&mut s).unwrap(); + assert_eq!(s.len(), 0); +} + +fn test() { + let args: Vec = env::args().collect(); + let mut p = Command::new(&args[0]).arg("child") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn().unwrap(); + assert!(p.wait().unwrap().success()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1448-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1448-2.rs new file mode 100644 index 000000000000..52f13186f630 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1448-2.rs @@ -0,0 +1,8 @@ +// Regression test for issue #1448 and #1386 + +fn foo(a: u32) -> u32 { a } + +fn main() { + println!("{}", foo(10i32)); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1451.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1451.rs new file mode 100644 index 000000000000..2a25bbb41ffc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1451.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 +#![allow(non_snake_case)] +#![allow(unused_variables)] + +struct T { f: extern "Rust" fn() } +struct S { f: extern "Rust" fn() } + +fn fooS(t: S) { +} + +fn fooT(t: T) { +} + +fn bar() { +} + +pub fn main() { + let x: extern "Rust" fn() = bar; + fooS(S {f: x}); + fooS(S {f: bar}); + + let x: extern "Rust" fn() = bar; + fooT(T {f: x}); + fooT(T {f: bar}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14541.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14541.rs new file mode 100644 index 000000000000..93a3acaf1b37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14541.rs @@ -0,0 +1,11 @@ +struct Vec2 { y: f32 } +struct Vec3 { y: f32, z: f32 } + +fn make(v: Vec2) { + let Vec3 { y: _, z: _ } = v; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14589.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14589.rs new file mode 100644 index 000000000000..44f8dc3f868f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14589.rs @@ -0,0 +1,25 @@ +// run-pass +// All 3 expressions should work in that the argument gets +// coerced to a trait object + +// pretty-expanded FIXME #23616 + +fn main() { + send::>(Box::new(Output(0))); + Test::>::foo(Box::new(Output(0))); + Test::>::new().send(Box::new(Output(0))); +} + +fn send(_: T) {} + +struct Test { marker: std::marker::PhantomData } +impl Test { + fn new() -> Test { Test { marker: ::std::marker::PhantomData } } + fn foo(_: T) {} + fn send(&self, _: T) {} +} + +trait Foo { fn dummy(&self) { }} +struct Output(isize); +impl Foo for Output {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1460.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1460.rs new file mode 100644 index 000000000000..61f8fbab9b1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1460.rs @@ -0,0 +1,8 @@ +// run-pass + +// pretty-expanded FIXME #23616 + +pub fn main() { + {|i: u32| if 1 == i { }}; // { dg-warning "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14721.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14721.rs new file mode 100644 index 000000000000..181f917e2acc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14721.rs @@ -0,0 +1,5 @@ +fn main() { + let foo = "str"; + println!("{}", foo.desc); // { dg-error ".E0609." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1476.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1476.rs new file mode 100644 index 000000000000..d6150b50eaa4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1476.rs @@ -0,0 +1,4 @@ +fn main() { + println!("{}", x); // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14772.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14772.rs new file mode 100644 index 000000000000..699fd742725f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14772.rs @@ -0,0 +1,7 @@ +// compile-flags: --test + +#[test] +mod foo {} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14821.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14821.rs new file mode 100644 index 000000000000..f9b2d4861fa0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14821.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +trait SomeTrait {} +struct Meow; +impl SomeTrait for Meow {} + +struct Foo<'a> { + x: &'a dyn SomeTrait, + y: &'a dyn SomeTrait, +} + +impl<'a> Foo<'a> { + pub fn new<'b>(x: &'b dyn SomeTrait, y: &'b dyn SomeTrait) -> Foo<'b> { Foo { x: x, y: y } } +} + +fn main() { + let r = Meow; + let s = Meow; + let q = Foo::new(&r as &dyn SomeTrait, &s as &dyn SomeTrait); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14837.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14837.rs new file mode 100644 index 000000000000..bf77e5113ab1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14837.rs @@ -0,0 +1,12 @@ +// check-pass +// pretty-expanded FIXME #23616 + +#[deny(dead_code)] +pub enum Foo { + Bar { + baz: isize + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14845.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14845.rs new file mode 100644 index 000000000000..6ccf25fdf2a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14845.rs @@ -0,0 +1,12 @@ +struct X { + a: [u8; 1] +} + +fn main() { + let x = X { a: [0] }; + let _f = &x.a as *mut u8; // { dg-error ".E0606." "" { target *-*-* } } + + let local: [u8; 1] = [0]; + let _v = &local as *mut u8; // { dg-error ".E0606." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14853.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14853.rs new file mode 100644 index 000000000000..d89b280b874e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14853.rs @@ -0,0 +1,21 @@ +use std::fmt::Debug; + +trait Str {} + +trait Something: Sized { + fn yay(_: Option, thing: &[T]); +} + +struct X { data: u32 } + +impl Something for X { + fn yay(_:Option, thing: &[T]) { +// { dg-error ".E0276." "" { target *-*-* } .-1 } + } +} + +fn main() { + let arr = &["one", "two", "three"]; + println!("{:?}", Something::yay(None::, arr)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14865.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14865.rs new file mode 100644 index 000000000000..1a41575339c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14865.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] + +enum X { + Foo(usize), + Bar(bool) +} + +fn main() { + let x = match X::Foo(42) { + X::Foo(..) => 1, + _ if true => 0, + X::Bar(..) => panic!("Oh dear") + }; + assert_eq!(x, 1); + + let x = match X::Foo(42) { + _ if true => 0, + X::Foo(..) => 1, + X::Bar(..) => panic!("Oh dear") + }; + assert_eq!(x, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14875.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14875.rs new file mode 100644 index 000000000000..8dd730ff9d5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14875.rs @@ -0,0 +1,36 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default + +// Check that values are not leaked when a dtor panics (#14875) + +use std::panic::{self, UnwindSafe}; + +struct SetInnerOnDrop<'a>(&'a mut bool); + +impl<'a> UnwindSafe for SetInnerOnDrop<'a> {} + +impl<'a> Drop for SetInnerOnDrop<'a> { + fn drop(&mut self) { + *self.0 = true; + } +} + +struct PanicOnDrop; +impl Drop for PanicOnDrop { + fn drop(&mut self) { + panic!("test panic"); + } +} + +fn main() { + let mut set_on_drop = false; + { + let set_inner_on_drop = SetInnerOnDrop(&mut set_on_drop); + let _ = panic::catch_unwind(|| { + let _set_inner_on_drop = set_inner_on_drop; + let _panic_on_drop = PanicOnDrop; + }); + } + assert!(set_on_drop); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14901.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14901.rs new file mode 100644 index 000000000000..e40f894417b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14901.rs @@ -0,0 +1,19 @@ +// check-pass +pub trait Reader {} + +enum Wrapper<'a> { + WrapReader(&'a (dyn Reader + 'a)) +} + +trait Wrap<'a> { + fn wrap(self) -> Wrapper<'a>; +} + +impl<'a, R: Reader> Wrap<'a> for &'a mut R { + fn wrap(self) -> Wrapper<'a> { + Wrapper::WrapReader(self as &'a mut dyn Reader) + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14915.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14915.rs new file mode 100644 index 000000000000..6471bab9468d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14915.rs @@ -0,0 +1,9 @@ +#![feature(box_syntax)] + +fn main() { + let x: Box = box 0; + + println!("{}", x + 1); +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14919.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14919.rs new file mode 100644 index 000000000000..4ba5a1de8708 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14919.rs @@ -0,0 +1,56 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait Matcher { + fn next_match(&mut self) -> Option<(usize, usize)>; +} + +struct CharPredMatcher<'a, 'b> { + str: &'a str, + pred: Box bool + 'b>, +} + +impl<'a, 'b> Matcher for CharPredMatcher<'a, 'b> { + fn next_match(&mut self) -> Option<(usize, usize)> { + None + } +} + +trait IntoMatcher<'a, T> { + fn into_matcher(self, _: &'a str) -> T; +} + +impl<'a, 'b, F> IntoMatcher<'a, CharPredMatcher<'a, 'b>> for F where F: FnMut(char) -> bool + 'b { + fn into_matcher(self, s: &'a str) -> CharPredMatcher<'a, 'b> { + CharPredMatcher { + str: s, + pred: Box::new(self), + } + } +} + +struct MatchIndices { + matcher: M +} + +impl Iterator for MatchIndices { + type Item = (usize, usize); + + fn next(&mut self) -> Option<(usize, usize)> { + self.matcher.next_match() + } +} + +fn match_indices<'a, M, T: IntoMatcher<'a, M>>(s: &'a str, from: T) -> MatchIndices { + let string_matcher = from.into_matcher(s); + MatchIndices { matcher: string_matcher } +} + +fn main() { + let s = "abcbdef"; + match_indices(s, |c: char| c == 'b') + .collect::>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14933.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14933.rs new file mode 100644 index 000000000000..387e4c9efc4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14933.rs @@ -0,0 +1,7 @@ +// check-pass +// pretty-expanded FIXME #23616 + +pub type BigRat = T; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14936.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14936.rs new file mode 100644 index 000000000000..d45816fad707 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14936.rs @@ -0,0 +1,49 @@ +// build-pass +#![allow(unused_macros)] +#![allow(dead_code)] +#![feature(llvm_asm)] + +type History = Vec<&'static str>; + +fn wrap(x:A, which: &'static str, history: &mut History) -> A { + history.push(which); + x +} + +macro_rules! demo { + ( $output_constraint:tt ) => { + { + let mut x: isize = 0; + let y: isize = 1; + + let mut history: History = vec![]; + unsafe { + llvm_asm!("mov ($1), $0" + : $output_constraint (*wrap(&mut x, "out", &mut history)) + : "r"(&wrap(y, "in", &mut history)) + :: "volatile"); + } + assert_eq!((x,y), (1,1)); + let b: &[_] = &["out", "in"]; + assert_eq!(history, b); + } + } +} + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +fn main() { + fn out_write_only_expr_then_in_expr() { + demo!("=r") + } + + fn out_read_write_expr_then_in_expr() { + demo!("+r") + } + + out_write_only_expr_then_in_expr(); + out_read_write_expr_then_in_expr(); +} + +#[cfg(all(not(target_arch = "x86"), not(target_arch = "x86_64")))] +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14940.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14940.rs new file mode 100644 index 000000000000..75e57fb9e396 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14940.rs @@ -0,0 +1,21 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::env; +use std::process::Command; +use std::io::{self, Write}; + +fn main() { + let mut args = env::args(); + if args.len() > 1 { + let mut out = io::stdout(); + out.write(&['a' as u8; 128 * 1024]).unwrap(); + } else { + let out = Command::new(&args.next().unwrap()).arg("child").output(); + let out = out.unwrap(); + assert!(out.status.success()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14958.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14958.rs new file mode 100644 index 000000000000..ed8a71f78bab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14958.rs @@ -0,0 +1,32 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(fn_traits, unboxed_closures)] + +trait Foo { fn dummy(&self) { }} + +struct Bar; + +impl<'a> std::ops::Fn<(&'a (dyn Foo+'a),)> for Bar { + extern "rust-call" fn call(&self, _: (&'a dyn Foo,)) {} +} + +impl<'a> std::ops::FnMut<(&'a (dyn Foo+'a),)> for Bar { + extern "rust-call" fn call_mut(&mut self, a: (&'a dyn Foo,)) { self.call(a) } +} + +impl<'a> std::ops::FnOnce<(&'a (dyn Foo+'a),)> for Bar { + type Output = (); + extern "rust-call" fn call_once(self, a: (&'a dyn Foo,)) { self.call(a) } +} + +struct Baz; + +impl Foo for Baz {} + +fn main() { + let bar = Bar; + let baz = &Baz; + bar(baz); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-14959.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-14959.rs new file mode 100644 index 000000000000..22406dc68d11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-14959.rs @@ -0,0 +1,56 @@ +// check-pass +// pretty-expanded FIXME #23616 + +#![feature(fn_traits, unboxed_closures)] + +use std::ops::Fn; + +trait Response { fn dummy(&self) { } } +trait Request { fn dummy(&self) { } } +trait Ingot { + fn enter(&mut self, _: &mut R, _: &mut S, a: &mut Alloy) -> Status; +} + +#[allow(dead_code)] +struct HelloWorld; + +struct SendFile; +struct Alloy; +enum Status { + Continue +} + +impl Alloy { + fn find(&self) -> Option { + None + } +} + +impl<'b> Fn<(&'b mut (dyn Response + 'b),)> for SendFile { + extern "rust-call" fn call(&self, (_res,): (&'b mut (dyn Response + 'b),)) {} +} + +impl<'b> FnMut<(&'b mut (dyn Response + 'b),)> for SendFile { + extern "rust-call" fn call_mut(&mut self, (_res,): (&'b mut (dyn Response+'b),)) { + self.call((_res,)) + } +} + +impl<'b> FnOnce<(&'b mut (dyn Response + 'b),)> for SendFile { + type Output = (); + + extern "rust-call" fn call_once(self, (_res,): (&'b mut (dyn Response+'b),)) { + self.call((_res,)) + } +} + +impl Ingot for HelloWorld { + fn enter(&mut self, _req: &mut Rq, res: &mut Rs, alloy: &mut Alloy) -> Status { + let send_file = alloy.find::().unwrap(); + send_file(res); + Status::Continue + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15034.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15034.rs new file mode 100644 index 000000000000..726cd42822cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15034.rs @@ -0,0 +1,23 @@ +pub struct Lexer<'a> { + input: &'a str, +} + +impl<'a> Lexer<'a> { + pub fn new(input: &'a str) -> Lexer<'a> { + Lexer { input: input } + } +} + +struct Parser<'a> { + lexer: &'a mut Lexer<'a>, +} + +impl<'a> Parser<'a> { + pub fn new(lexer: &'a mut Lexer) -> Parser<'a> { + Parser { lexer: lexer } +// { dg-error ".E0621." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15043.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15043.rs new file mode 100644 index 000000000000..a0fc4c4a243f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15043.rs @@ -0,0 +1,15 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![allow(warnings)] + +struct S(T); + +static s1: S>=S(S(0)); +static s2: S=S(0); + +fn main() { + let foo: S>=S(S(0)); + let foo: S=S(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15063.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15063.rs new file mode 100644 index 000000000000..e82b0aa4179d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15063.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +enum Two { A, B} +impl Drop for Two { + fn drop(&mut self) { + println!("Dropping!"); + } +} +fn main() { + let k = Two::A; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15080.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15080.rs new file mode 100644 index 000000000000..a3b30990642e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15080.rs @@ -0,0 +1,23 @@ +// run-pass + +fn main() { + let mut x: &[_] = &[1, 2, 3, 4]; + + let mut result = vec![]; + loop { + x = match *x { + [1, n, 3, ref rest @ ..] => { + result.push(n); + rest + } + [n, ref rest @ ..] => { + result.push(n); + rest + } + [] => + break + } + } + assert_eq!(result, [2, 4]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15094.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15094.rs new file mode 100644 index 000000000000..bb5c66a3c94f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15094.rs @@ -0,0 +1,27 @@ +#![feature(fn_traits, unboxed_closures)] + +use std::{fmt, ops}; + +struct Debuger { + x: T +} + +impl ops::FnOnce<(),> for Debuger { + type Output = (); + fn call_once(self, _args: ()) { +// { dg-error ".E0053." "" { target *-*-* } .-1 } +// { dg-error ".E0053." "" { target *-*-* } .-2 } +// { dg-error ".E0053." "" { target *-*-* } .-3 } + println!("{:?}", self.x); + } +} + +fn make_shower(x: T) -> Debuger { + Debuger { x: x } +} + +pub fn main() { + let show3 = make_shower(3); + show3(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15104.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15104.rs new file mode 100644 index 000000000000..197dfb14e2b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15104.rs @@ -0,0 +1,14 @@ +// run-pass + +fn main() { + assert_eq!(count_members(&[1, 2, 3, 4]), 4); +} + +fn count_members(v: &[usize]) -> usize { + match *v { + [] => 0, + [_] => 1, + [_, ref xs @ ..] => 1 + count_members(xs) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15129-rpass.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15129-rpass.rs new file mode 100644 index 000000000000..dc62ec982711 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15129-rpass.rs @@ -0,0 +1,26 @@ +// run-pass + +pub enum T { + T1(()), + T2(()) +} + +pub enum V { + V1(isize), + V2(bool) +} + +fn foo(x: (T, V)) -> String { + match x { + (T::T1(()), V::V1(i)) => format!("T1(()), V1({})", i), + (T::T2(()), V::V2(b)) => format!("T2(()), V2({})", b), + _ => String::new() + } +} + + +fn main() { + assert_eq!(foo((T::T1(()), V::V1(99))), "T1(()), V1(99)".to_string()); + assert_eq!(foo((T::T2(()), V::V2(true))), "T2(()), V2(true)".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15129.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15129.rs new file mode 100644 index 000000000000..b8aa734a0816 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15129.rs @@ -0,0 +1,18 @@ +pub enum T { + T1(()), + T2(()) +} + +pub enum V { + V1(isize), + V2(bool) +} + +fn main() { + match (T::T1(()), V::V2(true)) { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + (T::T1(()), V::V1(i)) => (), + (T::T2(()), V::V2(b)) => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15155.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15155.rs new file mode 100644 index 000000000000..f214977c688d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15155.rs @@ -0,0 +1,22 @@ +// run-pass +trait TraitWithSend: Send {} +trait IndirectTraitWithSend: TraitWithSend {} + +// Check struct instantiation (Box will only have Send if TraitWithSend has Send) +#[allow(dead_code)] +struct Blah { x: Box } +impl TraitWithSend for Blah {} + +// Struct instantiation 2-levels deep +#[allow(dead_code)] +struct IndirectBlah { x: Box } +impl TraitWithSend for IndirectBlah {} +impl IndirectTraitWithSend for IndirectBlah {} + +fn test_trait() { println!("got here!") } + +fn main() { + test_trait::(); + test_trait::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15167.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15167.rs new file mode 100644 index 000000000000..a00774d26bea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15167.rs @@ -0,0 +1,27 @@ +// macro f should not be able to inject a reference to 'n'. + +macro_rules! f { () => (n) } +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { dg-error ".E0425." "" { target *-*-* } .-2 } +// { dg-error ".E0425." "" { target *-*-* } .-3 } +// { dg-error ".E0425." "" { target *-*-* } .-4 } + +fn main() -> (){ + for n in 0..1 { + println!("{}", f!()); + } + + if let Some(n) = None { + println!("{}", f!()); + } + + if false { + } else if let Some(n) = None { + println!("{}", f!()); + } + + while let Some(n) = None { + println!("{}", f!()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15189.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15189.rs new file mode 100644 index 000000000000..b0f2631c1df7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15189.rs @@ -0,0 +1,11 @@ +// run-pass +macro_rules! third { + ($e:expr) => ({let x = 2; $e[x]}) +} + +fn main() { + let x = vec![10_usize,11_usize,12_usize,13_usize]; + let t = third!(x); + assert_eq!(t,12_usize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15207.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15207.rs new file mode 100644 index 000000000000..7226849e2c66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15207.rs @@ -0,0 +1,7 @@ +fn main() { + loop { + break.push(1) // { dg-error ".E0599." "" { target *-*-* } } + ; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15221.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15221.rs new file mode 100644 index 000000000000..fb3601b8f686 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15221.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(path_statements)] +// pretty-expanded FIXME #23616 + +macro_rules! inner { + ($e:pat ) => ($e) +} + +macro_rules! outer { + ($e:pat ) => (inner!($e)) +} + +fn main() { + let outer!(g1) = 13; + g1; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15260.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15260.rs new file mode 100644 index 000000000000..ff51717eef34 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15260.rs @@ -0,0 +1,26 @@ +struct Foo { + a: usize, +} + +fn main() { + let Foo { + a: _, + a: _ +// { dg-error ".E0025." "" { target *-*-* } .-1 } + } = Foo { a: 29 }; + + let Foo { + a, + a: _ +// { dg-error ".E0025." "" { target *-*-* } .-1 } + } = Foo { a: 29 }; + + let Foo { + a, + a: _, +// { dg-error ".E0025." "" { target *-*-* } .-1 } + a: x +// { dg-error ".E0025." "" { target *-*-* } .-1 } + } = Foo { a: 29 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15261.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15261.rs new file mode 100644 index 000000000000..42eefc6aa91b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15261.rs @@ -0,0 +1,12 @@ +// build-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +// pretty-expanded FIXME #23616 + +static mut n_mut: usize = 0; + +static n: &'static usize = unsafe{ &n_mut }; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15381.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15381.rs new file mode 100644 index 000000000000..252272c8b4f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15381.rs @@ -0,0 +1,9 @@ +fn main() { + let values: Vec = vec![1,2,3,4,5,6,7,8]; + + for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) { +// { dg-error ".E0005." "" { target *-*-* } .-1 } + println!("y={}", y); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15444.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15444.rs new file mode 100644 index 000000000000..6de4689dcf59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15444.rs @@ -0,0 +1,24 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait MyTrait { + fn foo(&self); +} + +impl MyTrait for fn(A, B) -> C { + fn foo(&self) {} +} + +fn bar(t: &T) { + t.foo() +} + +fn thing(a: isize, b: isize) -> isize { + a + b +} + +fn main() { + let thing: fn(isize, isize) -> isize = thing; // coerce to fn type + bar(&thing); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15487.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15487.rs new file mode 100644 index 000000000000..434157bb9357 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15487.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(unused_attributes)] +// ignore-windows +// ignore-wasm32-bare no libs to link +// ignore-sgx no libs to link + +#![feature(link_args)] + +#[link_args="-lc -lm"] +#[link_args=" -lc"] +#[link_args="-lc "] +extern {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15523-big.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15523-big.rs new file mode 100644 index 000000000000..a29420cae666 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15523-big.rs @@ -0,0 +1,40 @@ +// run-pass +// Issue 15523: derive(PartialOrd) should use the provided +// discriminant values for the derived ordering. +// +// This test is checking corner cases that arise when you have +// 64-bit values in the variants. + +#[derive(PartialEq, PartialOrd)] +#[repr(u64)] +enum Eu64 { + Pos2 = 2, + PosMax = !0, + Pos1 = 1, +} + +#[derive(PartialEq, PartialOrd)] +#[repr(i64)] +enum Ei64 { + Pos2 = 2, + Neg1 = -1, + NegMin = 1 << 63, + PosMax = !(1 << 63), + Pos1 = 1, +} + +fn main() { + assert!(Eu64::Pos2 > Eu64::Pos1); + assert!(Eu64::Pos2 < Eu64::PosMax); + assert!(Eu64::Pos1 < Eu64::PosMax); + + + assert!(Ei64::Pos2 > Ei64::Pos1); + assert!(Ei64::Pos2 > Ei64::Neg1); + assert!(Ei64::Pos1 > Ei64::Neg1); + assert!(Ei64::Pos2 > Ei64::NegMin); + assert!(Ei64::Pos1 > Ei64::NegMin); + assert!(Ei64::Pos2 < Ei64::PosMax); + assert!(Ei64::Pos1 < Ei64::PosMax); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15523.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15523.rs new file mode 100644 index 000000000000..bb5d9da3cb45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15523.rs @@ -0,0 +1,43 @@ +// run-pass +// Issue 15523: derive(PartialOrd) should use the provided +// discriminant values for the derived ordering. +// +// This is checking the basic functionality. + +#[derive(PartialEq, PartialOrd)] +enum E1 { + Pos2 = 2, + Neg1 = -1, + Pos1 = 1, +} + +#[derive(PartialEq, PartialOrd)] +#[repr(u8)] +enum E2 { + Pos2 = 2, + PosMax = !0 as u8, + Pos1 = 1, +} + +#[derive(PartialEq, PartialOrd)] +#[repr(i8)] +enum E3 { + Pos2 = 2, + Neg1 = -1_i8, + Pos1 = 1, +} + +fn main() { + assert!(E1::Pos2 > E1::Pos1); + assert!(E1::Pos1 > E1::Neg1); + assert!(E1::Pos2 > E1::Neg1); + + assert!(E2::Pos2 > E2::Pos1); + assert!(E2::Pos1 < E2::PosMax); + assert!(E2::Pos2 < E2::PosMax); + + assert!(E3::Pos2 > E3::Pos1); + assert!(E3::Pos1 > E3::Neg1); + assert!(E3::Pos2 > E3::Neg1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15524.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15524.rs new file mode 100644 index 000000000000..e497fb63aeab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15524.rs @@ -0,0 +1,17 @@ +const N: isize = 1; + +enum Foo { + A = 1, + B = 1, +// { dg-error ".E0081." "" { target *-*-* } .-1 } + C = 0, + D, +// { dg-error ".E0081." "" { target *-*-* } .-1 } + + E = N, +// { dg-error ".E0081." "" { target *-*-* } .-1 } + +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15562.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15562.rs new file mode 100644 index 000000000000..75cb9b629a1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15562.rs @@ -0,0 +1,20 @@ +// run-pass +// aux-build:issue-15562.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_15562 as i; + +pub fn main() { + unsafe { + transmute(); + i::transmute(); + } +} + +// We declare this so we don't run into unresolved symbol errors +// The above extern is NOT `extern "rust-intrinsic"` and thus +// means it'll try to find a corresponding symbol to link to. +#[no_mangle] +pub extern fn transmute() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15571.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15571.rs new file mode 100644 index 000000000000..06c7db56fecb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15571.rs @@ -0,0 +1,59 @@ +// run-pass +#![feature(box_syntax)] + +fn match_on_local() { + let mut foo: Option> = Some(box 5); + match foo { + None => {}, + Some(x) => { + foo = Some(x); + } + } + println!("'{}'", foo.unwrap()); +} + +fn match_on_arg(mut foo: Option>) { + match foo { + None => {} + Some(x) => { + foo = Some(x); + } + } + println!("'{}'", foo.unwrap()); +} + +fn match_on_binding() { + match Some(Box::new(7)) { + mut foo => { + match foo { + None => {}, + Some(x) => { + foo = Some(x); + } + } + println!("'{}'", foo.unwrap()); + } + } +} + +fn match_on_upvar() { + let mut foo: Option> = Some(box 8); + let f = move|| { + match foo { + None => {}, + Some(x) => { + foo = Some(x); + } + } + println!("'{}'", foo.unwrap()); + }; + f(); +} + +fn main() { + match_on_local(); + match_on_arg(Some(box 6)); + match_on_binding(); + match_on_upvar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15673.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15673.rs new file mode 100644 index 000000000000..ab548c845e60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15673.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(stable_features)] + +#![feature(iter_arith)] + +fn main() { + let x: [u64; 3] = [1, 2, 3]; + assert_eq!(6, (0..3).map(|i| x[i]).sum::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15689-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15689-1.rs new file mode 100644 index 000000000000..931b259aadca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15689-1.rs @@ -0,0 +1,11 @@ +// run-pass + +#[derive(PartialEq, Debug)] +enum Test<'a> { + Slice(&'a isize) +} + +fn main() { + assert_eq!(Test::Slice(&1), Test::Slice(&1)) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15689-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15689-2.rs new file mode 100644 index 000000000000..fe43e6eae445 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15689-2.rs @@ -0,0 +1,11 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#[derive(Clone)] +enum Test<'a> { + Slice(&'a isize) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15730.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15730.rs new file mode 100644 index 000000000000..64c8dbf85139 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15730.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(unused_mut)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +fn main() { + let mut array = [1, 2, 3]; + let pie_slice = &array[1..2]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15734.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15734.rs new file mode 100644 index 000000000000..0f8b8ec8c9a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15734.rs @@ -0,0 +1,59 @@ +// run-pass +// If `Index` used an associated type for its output, this test would +// work more smoothly. + +use std::ops::Index; + +struct Mat { data: Vec, cols: usize, } + +impl Mat { + fn new(data: Vec, cols: usize) -> Mat { + Mat { data: data, cols: cols } + } + fn row<'a>(&'a self, row: usize) -> Row<&'a Mat> { + Row { mat: self, row: row, } + } +} + +impl Index<(usize, usize)> for Mat { + type Output = T; + + fn index<'a>(&'a self, (row, col): (usize, usize)) -> &'a T { + &self.data[row * self.cols + col] + } +} + +impl<'a, T> Index<(usize, usize)> for &'a Mat { + type Output = T; + + fn index<'b>(&'b self, index: (usize, usize)) -> &'b T { + (*self).index(index) + } +} + +struct Row { mat: M, row: usize, } + +impl> Index for Row { + type Output = T; + + fn index<'a>(&'a self, col: usize) -> &'a T { + &self.mat[(self.row, col)] + } +} + +fn main() { + let m = Mat::new(vec![1, 2, 3, 4, 5, 6], 3); + let r = m.row(1); + + assert_eq!(r.index(2), &6); + assert_eq!(r[2], 6); + assert_eq!(r[2], 6); + assert_eq!(6, r[2]); + + let e = r[2]; + assert_eq!(e, 6); + + let e: usize = r[2]; + assert_eq!(e, 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15735.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15735.rs new file mode 100644 index 000000000000..6ecfe5d68499 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15735.rs @@ -0,0 +1,18 @@ +// check-pass +#![allow(dead_code)] +struct A<'a> { + a: &'a i32, + b: &'a i32, +} + +impl <'a> A<'a> { + fn foo<'b>(&'b self) { + A { + a: self.a, + b: self.b, + }; + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15756.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15756.rs new file mode 100644 index 000000000000..787a5fc6e05c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15756.rs @@ -0,0 +1,15 @@ +use std::slice::Chunks; +use std::slice::ChunksMut; + +fn dft_iter<'a, T>(arg1: Chunks<'a,T>, arg2: ChunksMut<'a,T>) +{ + for + &mut something +// { dg-error ".E0277." "" { target *-*-* } .-1 } + in arg2 + { + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15763.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15763.rs new file mode 100644 index 000000000000..a2d99dfbc69b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15763.rs @@ -0,0 +1,90 @@ +// run-pass +#![allow(unreachable_code)] +#![feature(box_syntax)] + +#[derive(PartialEq, Debug)] +struct Bar { + x: isize +} +impl Drop for Bar { + fn drop(&mut self) { + assert_eq!(self.x, 22); + } +} + +#[derive(PartialEq, Debug)] +struct Foo { + x: Bar, + a: isize +} + +fn foo() -> Result { + return Ok(Foo { + x: Bar { x: 22 }, + a: return Err(32) + }); +} + +fn baz() -> Result { + Ok(Foo { + x: Bar { x: 22 }, + a: return Err(32) + }) +} + +// explicit immediate return +fn aa() -> isize { + return 3; +} + +// implicit immediate return +fn bb() -> isize { + 3 +} + +// implicit outptr return +fn cc() -> Result { + Ok(3) +} + +// explicit outptr return +fn dd() -> Result { + return Ok(3); +} + +trait A { + fn aaa(&self) -> isize { + 3 + } + fn bbb(&self) -> isize { + return 3; + } + fn ccc(&self) -> Result { + Ok(3) + } + fn ddd(&self) -> Result { + return Ok(3); + } +} + +impl A for isize {} + +fn main() { + assert_eq!(foo(), Err(32)); + assert_eq!(baz(), Err(32)); + + assert_eq!(aa(), 3); + assert_eq!(bb(), 3); + assert_eq!(cc().unwrap(), 3); + assert_eq!(dd().unwrap(), 3); + + let i = box 32isize as Box; + assert_eq!(i.aaa(), 3); + let i = box 32isize as Box; + assert_eq!(i.bbb(), 3); + let i = box 32isize as Box; + assert_eq!(i.ccc().unwrap(), 3); + let i = box 32isize as Box; + assert_eq!(i.ddd().unwrap(), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15774.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15774.rs new file mode 100644 index 000000000000..f4631c9ba8e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15774.rs @@ -0,0 +1,26 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![deny(warnings)] +#![allow(unused_imports)] + +pub enum Foo { A } +mod bar { + pub fn normal(x: ::Foo) { + use Foo::A; + match x { + A => {} + } + } + pub fn wrong(x: ::Foo) { + match x { + ::Foo::A => {} + } + } +} + +pub fn main() { + bar::normal(Foo::A); + bar::wrong(Foo::A); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15783.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15783.rs new file mode 100644 index 000000000000..471ee7cd94c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15783.rs @@ -0,0 +1,15 @@ +pub fn foo(params: Option<&[&str]>) -> usize { + params.unwrap().first().unwrap().len() +} + +fn main() { + let name = "Foo"; + let x = Some(&[name]); + let msg = foo(x); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + assert_eq!(msg, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15793.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15793.rs new file mode 100644 index 000000000000..eba92690fada --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15793.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(dead_code)] + +enum NestedEnum { + First, + Second, + Third +} +enum Enum { + Variant1(bool), + Variant2(NestedEnum) +} + +#[inline(never)] +fn foo(x: Enum) -> isize { + match x { + Enum::Variant1(true) => 1, + Enum::Variant1(false) => 2, + Enum::Variant2(NestedEnum::Second) => 3, + Enum::Variant2(NestedEnum::Third) => 4, + Enum::Variant2(NestedEnum::First) => 5 + } +} + +fn main() { + assert_eq!(foo(Enum::Variant2(NestedEnum::Third)), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15858.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15858.rs new file mode 100644 index 000000000000..ec528649cecc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15858.rs @@ -0,0 +1,34 @@ +// run-pass +static mut DROP_RAN: bool = false; + +trait Bar { + fn do_something(&mut self); +} + +struct BarImpl; + +impl Bar for BarImpl { + fn do_something(&mut self) {} +} + + +struct Foo(B); + +impl Drop for Foo { + fn drop(&mut self) { + unsafe { + DROP_RAN = true; + } + } +} + + +fn main() { + { + let _x: Foo = Foo(BarImpl); + } + unsafe { + assert_eq!(DROP_RAN, true); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15881-model-lexer-dotdotdot.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15881-model-lexer-dotdotdot.rs new file mode 100644 index 000000000000..eb8eeca6b639 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15881-model-lexer-dotdotdot.rs @@ -0,0 +1,39 @@ +// run-pass +#![allow(illegal_floating_point_literal_pattern)] // FIXME #41620 +#![allow(ellipsis_inclusive_range_patterns)] + +// regression test for the model lexer handling the DOTDOTDOT syntax (#15877) + + +pub fn main() { + match 5_usize { + 1_usize...5_usize => {} + _ => panic!("should match range"), + } + match 5_usize { + 6_usize...7_usize => panic!("shouldn't match range"), + _ => {} + } + match 5_usize { + 1_usize => panic!("should match non-first range"), + 2_usize...6_usize => {} + _ => panic!("math is broken") + } + match 'c' { + 'a'...'z' => {} + _ => panic!("should support char ranges") + } + match -3_isize { + -7...5 => {} + _ => panic!("should match signed range") + } + match 3.0f64 { + 1.0...5.0 => {} + _ => panic!("should match float range") + } + match -1.5f64 { + -3.6...3.6 => {} + _ => panic!("should match negative float range") + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15896.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15896.rs new file mode 100644 index 000000000000..16d828e37638 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15896.rs @@ -0,0 +1,16 @@ +// Regression test for #15896. It used to ICE rustc. + +fn main() { + enum R { REB(()) } + struct Tau { t: usize } + enum E { B(R, Tau) } + + let e = E::B(R::REB(()), Tau { t: 3 }); + let u = match e { + E::B( + Tau{t: x}, +// { dg-error ".E0308." "" { target *-*-* } .-1 } + _) => x, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15919-32.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15919-32.rs new file mode 100644 index 000000000000..7d7d8db84887 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15919-32.rs @@ -0,0 +1,14 @@ +// ignore-64bit +// build-fail + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" + +fn main() { + let x = [0usize; 0xffff_ffff]; // { dg-error "" "" { target *-*-* } } +} + +// This and the -64 version of this test need to have different literals, as we can't rely on +// conditional compilation for them while retaining the same spans/lines. + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15919-64.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15919-64.rs new file mode 100644 index 000000000000..74dee69e5cb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15919-64.rs @@ -0,0 +1,14 @@ +// build-fail +// ignore-32bit + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" + +fn main() { + let x = [0usize; 0xffff_ffff_ffff_ffff]; // { dg-error "" "" { target *-*-* } } +} + +// This and the -32 version of this test need to have different literals, as we can't rely on +// conditional compilation for them while retaining the same spans/lines. + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-15965.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-15965.rs new file mode 100644 index 000000000000..bba88f143dfe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-15965.rs @@ -0,0 +1,8 @@ +fn main() { + return + { return () } +// { dg-error ".E0282." "" { target *-*-* } .-1 } + () + ; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16048.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16048.rs new file mode 100644 index 000000000000..81f3d56b75a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16048.rs @@ -0,0 +1,31 @@ +trait NoLifetime { + fn get<'p, T : Test<'p>>(&self) -> T; +// { dg-note "" "" { target *-*-* } .-1 } +} + +trait Test<'p> { + fn new(buf: &'p mut [u8]) -> Self; +} + +struct Foo<'a> { + buf: &'a mut [u8], +} + +impl<'a> Test<'a> for Foo<'a> { + fn new(buf: &'a mut [u8]) -> Foo<'a> { + Foo { buf: buf } + } +} + +impl<'a> NoLifetime for Foo<'a> { + fn get<'p, T: Test<'a> + From>>(&self) -> T { +// { dg-error ".E0195." "" { target *-*-* } .-1 } +// { dg-note ".E0195." "" { target *-*-* } .-2 } + return *self as T; +// { dg-error ".E0605." "" { target *-*-* } .-1 } +// { dg-note ".E0605." "" { target *-*-* } .-2 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16098.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16098.rs new file mode 100644 index 000000000000..6817d65bcb9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16098.rs @@ -0,0 +1,17 @@ +macro_rules! prob1 { + (0) => { + 0 + }; + ($n:expr) => { + if ($n % 3 == 0) || ($n % 5 == 0) { + $n + prob1!($n - 1); // { dg-error "" "" { target *-*-* } } + } else { + prob1!($n - 1); + } + }; +} + +fn main() { + println!("Problem 1: {}", prob1!(1000)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16149.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16149.rs new file mode 100644 index 000000000000..17e2c2869aad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16149.rs @@ -0,0 +1,12 @@ +extern { + static externalValue: isize; +} + +fn main() { + let boolValue = match 42 { + externalValue => true, +// { dg-error ".E0530." "" { target *-*-* } .-1 } + _ => false + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16151.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16151.rs new file mode 100644 index 000000000000..515b7f5867c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16151.rs @@ -0,0 +1,30 @@ +// run-pass + +use std::mem; + +static mut DROP_COUNT: usize = 0; + +struct Fragment; + +impl Drop for Fragment { + fn drop(&mut self) { + unsafe { + DROP_COUNT += 1; + } + } +} + +fn main() { + { + let mut fragments = vec![Fragment, Fragment, Fragment]; + let _new_fragments: Vec = mem::replace(&mut fragments, vec![]) + .into_iter() + .skip_while(|_fragment| { + true + }).collect(); + } + unsafe { + assert_eq!(DROP_COUNT, 3); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16250.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16250.rs new file mode 100644 index 000000000000..75d6015b596c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16250.rs @@ -0,0 +1,11 @@ +#![deny(warnings)] + +pub struct Foo; + +extern { + pub fn foo(x: (Foo)); // { dg-error "" "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16256.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16256.rs new file mode 100644 index 000000000000..433bafc1c93a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16256.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + let mut buf = Vec::new(); + |c: u8| buf.push(c); // { dg-warning "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16272.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16272.rs new file mode 100644 index 000000000000..64a9cbb75eb7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16272.rs @@ -0,0 +1,25 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::process::Command; +use std::env; + +fn main() { + let len = env::args().len(); + + if len == 1 { + test(); + } else { + assert_eq!(len, 3); + } +} + +fn test() { + let status = Command::new(&env::current_exe().unwrap()) + .arg("foo").arg("") + .status().unwrap(); + assert!(status.success()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16278.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16278.rs new file mode 100644 index 000000000000..bad9b63a9f42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16278.rs @@ -0,0 +1,11 @@ +// run-pass +// ignore-tidy-cr + +// this file has some special \r\n endings (use xxd to see them) + +fn main() {assert_eq!(b"", b"\ + "); +assert_eq!(b"\n", b" +"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16338.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16338.rs new file mode 100644 index 000000000000..64c7792f82ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16338.rs @@ -0,0 +1,11 @@ +struct Slice { + data: *const T, + len: usize, +} + +fn main() { + let Slice { data: data, len: len } = "foo"; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16401.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16401.rs new file mode 100644 index 000000000000..2fe5ca7cda8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16401.rs @@ -0,0 +1,16 @@ +struct Slice { + data: *const T, + len: usize, +} + +fn main() { + match () { + Slice { data: data, len: len } => (), +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + _ => unreachable!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16441.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16441.rs new file mode 100644 index 000000000000..5c5e1d2da8ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16441.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct Empty; + +// This used to cause an ICE +#[allow(improper_ctypes_definitions)] +extern "C" fn ice(_a: Empty) {} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16452.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16452.rs new file mode 100644 index 000000000000..d2872f3378d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16452.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn main() { + if true { return } + match () { + () => { static MAGIC: usize = 0; } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16492.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16492.rs new file mode 100644 index 000000000000..a4bf3bb3c336 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16492.rs @@ -0,0 +1,68 @@ +// run-pass +#![allow(non_snake_case)] + +use std::rc::Rc; +use std::cell::Cell; + +struct Field { + number: usize, + state: Rc> +} + +impl Field { + fn new(number: usize, state: Rc>) -> Field { + Field { + number: number, + state: state + } + } +} + +impl Drop for Field { + fn drop(&mut self) { + println!("Dropping field {}", self.number); + assert_eq!(self.state.get(), self.number); + self.state.set(self.state.get()+1); + } +} + +struct NoDropImpl { + _one: Field, + _two: Field, + _three: Field +} + +struct HasDropImpl { + _one: Field, + _two: Field, + _three: Field +} + +impl Drop for HasDropImpl { + fn drop(&mut self) { + println!("HasDropImpl.drop()"); + assert_eq!(self._one.state.get(), 0); + self._one.state.set(1); + } +} + +pub fn main() { + let state = Rc::new(Cell::new(1)); + let noImpl = NoDropImpl { + _one: Field::new(1, state.clone()), + _two: Field::new(2, state.clone()), + _three: Field::new(3, state.clone()) + }; + drop(noImpl); + assert_eq!(state.get(), 4); + + state.set(0); + let hasImpl = HasDropImpl { + _one: Field::new(1, state.clone()), + _two: Field::new(2, state.clone()), + _three: Field::new(3, state.clone()) + }; + drop(hasImpl); + assert_eq!(state.get(), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16530.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16530.rs new file mode 100644 index 000000000000..27d7de503f97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16530.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(deprecated)] + +use std::hash::{SipHasher, Hasher, Hash}; + +#[derive(Hash)] +struct Empty; + +pub fn main() { + let mut s1 = SipHasher::new(); + Empty.hash(&mut s1); + let mut s2 = SipHasher::new(); + Empty.hash(&mut s2); + assert_eq!(s1.finish(), s2.finish()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16538.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16538.rs new file mode 100644 index 000000000000..1435df601f24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16538.rs @@ -0,0 +1,17 @@ +mod Y { + pub type X = usize; + extern { + pub static x: *const usize; + } + pub fn foo(value: *const X) -> *const X { + value + } +} + +static foo: *const Y::X = Y::foo(Y::x as *const Y::X); +// { dg-error ".E0133." "" { target *-*-* } .-1 } +// { dg-error ".E0133." "" { target *-*-* } .-2 } +// { dg-error ".E0133." "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16560.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16560.rs new file mode 100644 index 000000000000..a4a8cff4ca93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16560.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_variables)] +// ignore-emscripten no threads support + +use std::thread; +use std::mem; + +fn main() { + let y = 0u8; + let closure = move |x: u8| y + x; + + // Check that both closures are capturing by value + assert_eq!(1, mem::size_of_val(&closure)); + + thread::spawn(move|| { + let ok = closure; + }).join().ok().unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16562.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16562.rs new file mode 100644 index 000000000000..126b6fea9757 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16562.rs @@ -0,0 +1,18 @@ +trait MatrixShape {} + +struct Col { + data: D, + col: C, +} + +trait Collection { fn len(&self) -> usize; } + +impl Collection for Col { +// { dg-error ".E0207." "" { target *-*-* } .-1 } + fn len(&self) -> usize { + unimplemented!() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16596.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16596.rs new file mode 100644 index 000000000000..afaad5891444 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16596.rs @@ -0,0 +1,23 @@ +// check-pass +#![allow(dead_code)] + +trait MatrixRow { fn dummy(&self) { }} + +struct Mat; + +impl<'a> MatrixRow for &'a Mat {} + +struct Rows { + mat: M, +} + +impl<'a> Iterator for Rows<&'a Mat> { + type Item = (); + + fn next(&mut self) -> Option<()> { + unimplemented!() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16597-empty.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16597-empty.rs new file mode 100644 index 000000000000..97fc3b46977f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16597-empty.rs @@ -0,0 +1,6 @@ +// run-pass +// compile-flags:--test + +// This verifies that the test generation doesn't crash when we have +// no tests - for more information, see PR #16892. + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16597.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16597.rs new file mode 100644 index 000000000000..7782735cf7c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16597.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_imports)] +// compile-flags:--test + +mod tests { + use super::*; + + #[test] + pub fn test(){} +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1660.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1660.rs new file mode 100644 index 000000000000..00f1f64b5927 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1660.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(non_upper_case_globals)] + +// pretty-expanded FIXME #23616 + +pub fn main() { + static _x: isize = 1<<2; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16602-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16602-1.rs new file mode 100644 index 000000000000..eaf5ea5e836f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16602-1.rs @@ -0,0 +1,7 @@ +// run-pass +fn main() { + let mut t = [1; 2]; + t = [t[1] * 2, t[0] * 2]; + assert_eq!(&t[..], &[2, 2]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16602-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16602-2.rs new file mode 100644 index 000000000000..049d440d75d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16602-2.rs @@ -0,0 +1,13 @@ +// run-pass +struct A { + pub x: u32, + pub y: u32, +} + +fn main() { + let mut a = A { x: 1, y: 1 }; + a = A { x: a.y * 2, y: a.x * 2 }; + assert_eq!(a.x, 2); + assert_eq!(a.y, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16602-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16602-3.rs new file mode 100644 index 000000000000..2a54aecb7ba7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16602-3.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(unused_variables)] +#![allow(unused_assignments)] +#[derive(Debug)] +enum Foo { + Bar(u32, u32), + Baz(&'static u32, &'static u32) +} + +static NUM: u32 = 100; + +fn main () { + let mut b = Foo::Baz(&NUM, &NUM); + b = Foo::Bar(f(&b), g(&b)); +} + +static FNUM: u32 = 1; + +fn f (b: &Foo) -> u32 { + FNUM +} + +static GNUM: u32 = 2; + +fn g (b: &Foo) -> u32 { + GNUM +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16643.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16643.rs new file mode 100644 index 000000000000..f269cde7a954 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16643.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:issue-16643.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_16643 as i; + +pub fn main() { + i::TreeBuilder { h: 3 }.process_token(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16648.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16648.rs new file mode 100644 index 000000000000..0d6e72b9b40b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16648.rs @@ -0,0 +1,12 @@ +// run-pass +fn main() { + let x: (isize, &[isize]) = (2, &[1, 2]); + assert_eq!(match x { + (0, &[_, _]) => 0, + (1, _) => 1, + (2, &[_, _]) => 2, + (2, _) => 3, + _ => 4 + }, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16668.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16668.rs new file mode 100644 index 000000000000..a7a716963252 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16668.rs @@ -0,0 +1,21 @@ +// check-pass +#![allow(dead_code)] +struct Parser<'a, I, O> { + parse: Box Result + 'a> +} + +impl<'a, I: 'a, O: 'a> Parser<'a, I, O> { + fn compose(mut self, mut rhs: Parser<'a, O, K>) -> Parser<'a, I, K> { + Parser { + parse: Box::new(move |x: I| { + match (self.parse)(x) { + Ok(r) => (rhs.parse)(r), + Err(e) => Err(e) + } + }) + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16671.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16671.rs new file mode 100644 index 000000000000..c10489fe69ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16671.rs @@ -0,0 +1,13 @@ +// run-pass + +#![deny(warnings)] + +fn foo(_f: F) { } + +fn main() { + let mut var = Vec::new(); + foo(move|| { + var.push(1); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16683.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16683.rs new file mode 100644 index 000000000000..72613bc3122a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16683.rs @@ -0,0 +1,9 @@ +trait T<'a> { + fn a(&'a self) -> &'a bool; + fn b(&self) { + self.a(); // { dg-error ".E0495." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16725.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16725.rs new file mode 100644 index 000000000000..b16ec87a66c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16725.rs @@ -0,0 +1,9 @@ +// aux-build:issue-16725.rs + +extern crate issue_16725 as foo; + +fn main() { + unsafe { foo::bar(); } +// { dg-error ".E0603." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16739.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16739.rs new file mode 100644 index 000000000000..61d95439a7a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16739.rs @@ -0,0 +1,47 @@ +// run-pass +#![feature(box_syntax)] +#![feature(unboxed_closures, fn_traits)] + +// Test that unboxing shim for calling rust-call ABI methods through a +// trait box works and does not cause an ICE. + +struct Foo { foo: u32 } + +impl FnMut<()> for Foo { + extern "rust-call" fn call_mut(&mut self, _: ()) -> u32 { self.foo } +} + +impl FnOnce<()> for Foo { + type Output = u32; + extern "rust-call" fn call_once(mut self, _: ()) -> u32 { self.call_mut(()) } +} + +impl FnMut<(u32,)> for Foo { + extern "rust-call" fn call_mut(&mut self, (x,): (u32,)) -> u32 { self.foo + x } +} + +impl FnOnce<(u32,)> for Foo { + type Output = u32; + extern "rust-call" fn call_once(mut self, args: (u32,)) -> u32 { self.call_mut(args) } +} + +impl FnMut<(u32,u32)> for Foo { + extern "rust-call" fn call_mut(&mut self, (x, y): (u32, u32)) -> u32 { self.foo + x + y } +} + +impl FnOnce<(u32,u32)> for Foo { + type Output = u32; + extern "rust-call" fn call_once(mut self, args: (u32,u32)) -> u32 { self.call_mut(args) } +} + +fn main() { + let mut f = box Foo { foo: 42 } as Box u32>; + assert_eq!(f.call_mut(()), 42); + + let mut f = box Foo { foo: 40 } as Box u32>; + assert_eq!(f.call_mut((2,)), 42); + + let mut f = box Foo { foo: 40 } as Box u32>; + assert_eq!(f.call_mut((1, 1)), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16745.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16745.rs new file mode 100644 index 000000000000..f001d380d1b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16745.rs @@ -0,0 +1,12 @@ +// run-pass +fn main() { + const X: u8 = 0; + let out: u8 = match 0u8 { + X => 99, + b'\t' => 1, + 1u8 => 2, + _ => 3, + }; + assert_eq!(out, 99); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16774.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16774.rs new file mode 100644 index 000000000000..47046f139c63 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16774.rs @@ -0,0 +1,47 @@ +// run-pass +#![feature(box_syntax)] +#![feature(box_patterns)] + +use std::ops::{Deref, DerefMut}; + +struct X(Box); + +static mut DESTRUCTOR_RAN: bool = false; + +impl Drop for X { + fn drop(&mut self) { + unsafe { + assert!(!DESTRUCTOR_RAN); + DESTRUCTOR_RAN = true; + } + } +} + +impl Deref for X { + type Target = isize; + + fn deref(&self) -> &isize { + let &X(box ref x) = self; + x + } +} + +impl DerefMut for X { + fn deref_mut(&mut self) -> &mut isize { + let &mut X(box ref mut x) = self; + x + } +} + +fn main() { + { + let mut test = X(box 5); + { + let mut change = || { *test = 10 }; + change(); + } + assert_eq!(*test, 10); + } + assert!(unsafe { DESTRUCTOR_RAN }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16783.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16783.rs new file mode 100644 index 000000000000..4ac291955f70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16783.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +pub fn main() { + let x = [1, 2, 3]; + let y = x; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16819.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16819.rs new file mode 100644 index 000000000000..63bd7c71d69e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16819.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(unused_variables)] +// `#[cfg]` on struct field permits empty unusable struct + +struct S { + #[cfg(untrue)] + a: int, +} + +fn main() { + let s = S {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16922-rpass.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16922-rpass.rs new file mode 100644 index 000000000000..4ae33f1795b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16922-rpass.rs @@ -0,0 +1,12 @@ +// run-pass +// pretty-expanded FIXME #23616 + +use std::any::Any; + +fn foo(_: &u8) { +} + +fn main() { + let _ = &foo as &dyn Any; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16922.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16922.rs new file mode 100644 index 000000000000..bd4812a79fa3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16922.rs @@ -0,0 +1,10 @@ +use std::any::Any; + +fn foo(value: &T) -> Box { + Box::new(value) as Box // { dg-error ".E0759." "" { target *-*-* } } +} + +fn main() { + let _ = foo(&5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16939.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16939.rs new file mode 100644 index 000000000000..263c54541d43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16939.rs @@ -0,0 +1,9 @@ +// Make sure we don't ICE when making an overloaded call with the +// wrong arity. + +fn _foo (f: F) { + |t| f(t); // { dg-error ".E0057." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1696.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1696.rs new file mode 100644 index 000000000000..284576593791 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1696.rs @@ -0,0 +1,9 @@ +// run-pass +use std::collections::HashMap; + +pub fn main() { + let mut m = HashMap::new(); + m.insert(b"foo".to_vec(), b"bar".to_vec()); + println!("{:?}", m); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16966.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16966.rs new file mode 100644 index 000000000000..8c29148ab36f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16966.rs @@ -0,0 +1,5 @@ +fn main() { + panic!(std::default::Default::default()); +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1697.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1697.rs new file mode 100644 index 000000000000..37d02f9f3291 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1697.rs @@ -0,0 +1,7 @@ +// Testing that we don't fail abnormally after hitting the errors + +use unresolved::*; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-16994.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-16994.rs new file mode 100644 index 000000000000..1062b12068c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-16994.rs @@ -0,0 +1,10 @@ +// check-pass + +fn cb<'a,T>(_x: Box, bool))) -> T>) -> T { + panic!() +} + +fn main() { + cb(Box::new(|(k, &(ref v, b))| (*k, v.clone(), b))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17001.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17001.rs new file mode 100644 index 000000000000..b9e723fd6b7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17001.rs @@ -0,0 +1,6 @@ +mod foo {} + +fn main() { + let p = foo { x: () }; // { dg-error ".E0574." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1701.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1701.rs new file mode 100644 index 000000000000..7a5e99eca255 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1701.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + + +enum pattern { tabby, tortoiseshell, calico } +enum breed { beagle, rottweiler, pug } +type name = String; +enum ear_kind { lop, upright } +enum animal { cat(pattern), dog(breed), rabbit(name, ear_kind), tiger } + +fn noise(a: animal) -> Option { + match a { + animal::cat(..) => { Some("meow".to_string()) } + animal::dog(..) => { Some("woof".to_string()) } + animal::rabbit(..) => { None } + animal::tiger => { Some("roar".to_string()) } + } +} + +pub fn main() { + assert_eq!(noise(animal::cat(pattern::tabby)), Some("meow".to_string())); + assert_eq!(noise(animal::dog(breed::pug)), Some("woof".to_string())); + assert_eq!(noise(animal::rabbit("Hilbert".to_string(), ear_kind::upright)), None); + assert_eq!(noise(animal::tiger), Some("roar".to_string())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17033.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17033.rs new file mode 100644 index 000000000000..7a47a1db047e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17033.rs @@ -0,0 +1,7 @@ +fn f<'r>(p: &'r mut fn(p: &mut ())) { + (*p)(()) // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17068.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17068.rs new file mode 100644 index 000000000000..3b7b30abb5f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17068.rs @@ -0,0 +1,13 @@ +// run-pass +// Test that regionck creates the right region links in the pattern +// binding of a for loop + +fn foo<'a>(v: &'a [usize]) -> &'a usize { + for &ref x in v { return x; } + unreachable!() +} + +fn main() { + assert_eq!(foo(&[0]), &0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17074.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17074.rs new file mode 100644 index 000000000000..410e8fa9f204 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17074.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] + +static X2: u64 = !0 as u16 as u64; +static Y2: u64 = !0 as u32 as u64; +const X: u64 = !0 as u16 as u64; +const Y: u64 = !0 as u32 as u64; + +fn main() { + assert_eq!(match 1 { + X => unreachable!(), + Y => unreachable!(), + _ => 1 + }, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17121.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17121.rs new file mode 100644 index 000000000000..6392382be257 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17121.rs @@ -0,0 +1,33 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 +// ignore-cloudabi no std::fs + +use std::fs::File; +use std::io::{self, BufReader, Read}; + +struct Lexer +{ + reader: BufReader, +} + +impl Lexer +{ + pub fn new_from_reader(r: R) -> Lexer + { + Lexer{reader: BufReader::new(r)} + } + + pub fn new_from_file(p: &str) -> io::Result> + { + Ok(Lexer::new_from_reader(File::open(p)?)) + } + + pub fn new_from_str<'a>(s: &'a str) -> Lexer<&'a [u8]> + { + Lexer::new_from_reader(s.as_bytes()) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17170.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17170.rs new file mode 100644 index 000000000000..17d5048c8277 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17170.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(repr_simd)] + +#[repr(simd)] +struct T(f64, f64, f64); + +static X: T = T(0.0, 0.0, 0.0); + +fn main() { + let _ = X; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17216.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17216.rs new file mode 100644 index 000000000000..f589518a006a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17216.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(unused_variables)] +struct Leak<'a> { + dropped: &'a mut bool +} + +impl<'a> Drop for Leak<'a> { + fn drop(&mut self) { + *self.dropped = true; + } +} + +fn main() { + let mut dropped = false; + { + let leak = Leak { dropped: &mut dropped }; + for ((), leaked) in Some(((), leak)).into_iter() {} + } + + assert!(dropped); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17233.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17233.rs new file mode 100644 index 000000000000..ff0b0300eb4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17233.rs @@ -0,0 +1,18 @@ +// run-pass + +const X1: &'static [u8] = &[b'1']; +const X2: &'static [u8] = b"1"; +const X3: &'static [u8; 1] = &[b'1']; +const X4: &'static [u8; 1] = b"1"; + +static Y1: u8 = X1[0]; +static Y2: u8 = X2[0]; +static Y3: u8 = X3[0]; +static Y4: u8 = X4[0]; + +fn main() { + assert_eq!(Y1, Y2); + assert_eq!(Y1, Y3); + assert_eq!(Y1, Y4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17252.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17252.rs new file mode 100644 index 000000000000..7f8e608f092f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17252.rs @@ -0,0 +1,11 @@ +const FOO: usize = FOO; // { dg-error "" "" { target *-*-* } } + +fn main() { + let _x: [u8; FOO]; // caused stack overflow prior to fix + let _y: usize = 1 + { + const BAR: usize = BAR; + let _z: [u8; BAR]; // caused stack overflow prior to fix + 1 + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17263.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17263.rs new file mode 100644 index 000000000000..1ee62b3ac40a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17263.rs @@ -0,0 +1,26 @@ +// check-pass + +#![feature(box_syntax)] + +struct Foo { a: isize, b: isize } + +fn main() { + let mut x: Box<_> = box Foo { a: 1, b: 2 }; + let (a, b) = (&mut x.a, &mut x.b); + + let mut foo: Box<_> = box Foo { a: 1, b: 2 }; + let (c, d) = (&mut foo.a, &foo.b); + + // We explicitly use the references created above to illustrate that the + // borrow checker is accepting this code *not* because of artificially + // short lifetimes, but rather because it understands that all the + // references are of disjoint parts of memory. + use_imm(d); + use_mut(c); + use_mut(b); + use_mut(a); +} + +fn use_mut(_: &mut T) { } +fn use_imm(_: &T) { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17302.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17302.rs new file mode 100644 index 000000000000..617f146ae042 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17302.rs @@ -0,0 +1,27 @@ +// run-pass + +static mut DROPPED: [bool; 2] = [false, false]; + +struct A(usize); +struct Foo { _a: A, _b: isize } + +impl Drop for A { + fn drop(&mut self) { + let A(i) = *self; + unsafe { DROPPED[i] = true; } + } +} + +fn main() { + { + Foo { + _a: A(0), + ..Foo { _a: A(1), _b: 2 } + }; + } + unsafe { + assert!(DROPPED[0]); + assert!(DROPPED[1]); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17322.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17322.rs new file mode 100644 index 000000000000..3633a58c3d99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17322.rs @@ -0,0 +1,16 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +use std::io::{self, Write}; + +fn f(wr: &mut dyn Write) { + wr.write_all(b"hello").ok().expect("failed"); +} + +fn main() { + let mut wr = box io::stdout() as Box; + f(&mut wr); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17336.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17336.rs new file mode 100644 index 000000000000..b592338f0eb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17336.rs @@ -0,0 +1,10 @@ +// build-pass +#![allow(unused_must_use)] +#[allow(dead_code)] +fn check(a: &str) { + let x = a as *const str; + x == x; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17337.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17337.rs new file mode 100644 index 000000000000..428505eec380 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17337.rs @@ -0,0 +1,18 @@ +#![feature(staged_api)] +#![deny(deprecated)] + +#![unstable(feature = "unstable_test_feature", issue = "none")] + +struct Foo; + +impl Foo { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn foo(self) {} +} + +fn main() { + Foo + .foo(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17351.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17351.rs new file mode 100644 index 000000000000..a05a67c14ff7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17351.rs @@ -0,0 +1,11 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Str { fn foo(&self) {} } +impl Str for str {} +impl<'a, S: ?Sized> Str for &'a S where S: Str {} + +fn main() { + let _: &dyn Str = &"x"; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17361.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17361.rs new file mode 100644 index 000000000000..98de21ce5f69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17361.rs @@ -0,0 +1,10 @@ +// run-pass +// Test that astconv doesn't forget about mutability of &mut str + +// pretty-expanded FIXME #23616 + +fn main() { + fn foo(_: &mut T) {} + let _f: fn(&mut str) = foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17373.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17373.rs new file mode 100644 index 000000000000..a411dc3e83d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17373.rs @@ -0,0 +1,5 @@ +fn main() { + *return // { dg-error ".E0614." "" { target *-*-* } } + ; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17385.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17385.rs new file mode 100644 index 000000000000..c0640cab18f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17385.rs @@ -0,0 +1,30 @@ +struct X(isize); + +enum Enum { + Variant1, + Variant2 +} + +impl Drop for X { + fn drop(&mut self) {} +} +impl Drop for Enum { + fn drop(&mut self) {} +} + +fn main() { + let foo = X(1); + drop(foo); + match foo { + X(1) => (), // { dg-error ".E0382." "" { target *-*-* } } + _ => unreachable!() + } + + let e = Enum::Variant2; + drop(e); + match e { // { dg-error ".E0382." "" { target *-*-* } } + Enum::Variant1 => unreachable!(), + Enum::Variant2 => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17405.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17405.rs new file mode 100644 index 000000000000..d06eeeec266e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17405.rs @@ -0,0 +1,10 @@ +enum Foo { + Bar(isize) +} + +fn main() { + match Foo::Bar(1) { + Foo { i } => () // { dg-error ".E0574." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17431-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-1.rs new file mode 100644 index 000000000000..d953a0ec90c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-1.rs @@ -0,0 +1,7 @@ +struct Foo { foo: Option> } +// { dg-error ".E0072." "" { target *-*-* } .-1 } + +impl Foo { fn bar(&self) {} } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17431-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-2.rs new file mode 100644 index 000000000000..241ec64eda62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-2.rs @@ -0,0 +1,10 @@ +struct Baz { q: Option } +// { dg-error ".E0072." "" { target *-*-* } .-1 } + +struct Foo { q: Option } +// { dg-error ".E0072." "" { target *-*-* } .-1 } + +impl Foo { fn bar(&self) {} } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17431-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-3.rs new file mode 100644 index 000000000000..5cdbb5e73d83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-3.rs @@ -0,0 +1,9 @@ +use std::sync::Mutex; + +struct Foo { foo: Mutex> } +// { dg-error ".E0072." "" { target *-*-* } .-1 } + +impl Foo { fn bar(&self) {} } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17431-4.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-4.rs new file mode 100644 index 000000000000..3fda08dd2529 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-4.rs @@ -0,0 +1,9 @@ +use std::marker; + +struct Foo { foo: Option>>, marker: marker::PhantomData } +// { dg-error ".E0072." "" { target *-*-* } .-1 } + +impl Foo { fn bar(&self) {} } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17431-5.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-5.rs new file mode 100644 index 000000000000..2bb10a5cb82d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-5.rs @@ -0,0 +1,12 @@ +use std::marker; + +struct Foo { foo: Bar } + +struct Bar { x: Bar , marker: marker::PhantomData } +// { dg-error ".E0072." "" { target *-*-* } .-1 } + +impl Foo { fn foo(&self) {} } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17431-6.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-6.rs new file mode 100644 index 000000000000..92f148bd15d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-6.rs @@ -0,0 +1,9 @@ +use std::sync::Mutex; + +enum Foo { X(Mutex>) } +// { dg-error ".E0072." "" { target *-*-* } .-1 } + +impl Foo { fn bar(self) {} } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17431-7.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-7.rs new file mode 100644 index 000000000000..a4168a951861 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17431-7.rs @@ -0,0 +1,7 @@ +enum Foo { Voo(Option>) } +// { dg-error ".E0072." "" { target *-*-* } .-1 } + +impl Foo { fn bar(&self) {} } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17441.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17441.rs new file mode 100644 index 000000000000..a75dee59e585 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17441.rs @@ -0,0 +1,14 @@ +fn main() { + let _foo = &[1_usize, 2] as [usize]; +// { dg-error ".E0620." "" { target *-*-* } .-1 } + + let _bar = Box::new(1_usize) as dyn std::fmt::Debug; +// { dg-error ".E0620." "" { target *-*-* } .-1 } + + let _baz = 1_usize as dyn std::fmt::Debug; +// { dg-error ".E0620." "" { target *-*-* } .-1 } + + let _quux = [1_usize, 2] as [usize]; +// { dg-error ".E0620." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17444.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17444.rs new file mode 100644 index 000000000000..41bdcadea763 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17444.rs @@ -0,0 +1,9 @@ +enum Test { + Foo = 0 +} + +fn main() { + let _x = Test::Foo as *const isize; +// { dg-error ".E0606." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17450.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17450.rs new file mode 100644 index 000000000000..18d226808ebc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17450.rs @@ -0,0 +1,8 @@ +// build-pass +#![allow(dead_code, warnings)] + +static mut x: isize = 3; +static mut y: isize = unsafe { x }; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17458.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17458.rs new file mode 100644 index 000000000000..b2a47c104ad7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17458.rs @@ -0,0 +1,7 @@ +static X: usize = unsafe { core::ptr::null::() as usize }; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() { + assert_eq!(X, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17503.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17503.rs new file mode 100644 index 000000000000..14cd7c4e2276 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17503.rs @@ -0,0 +1,11 @@ +// run-pass +fn main() { + let s: &[isize] = &[0, 1, 2, 3, 4]; + let ss: &&[isize] = &s; + let sss: &&&[isize] = &ss; + + println!("{:?}", &s[..3]); + println!("{:?}", &ss[3..]); + println!("{:?}", &sss[2..4]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17545.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17545.rs new file mode 100644 index 000000000000..b3df260077d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17545.rs @@ -0,0 +1,11 @@ +#![feature(fn_traits)] + +fn id(x: T) -> T { x } + +pub fn foo<'a, F: Fn(&'a ())>(bar: F) { + bar.call(( + &id(()), // { dg-error ".E0716." "" { target *-*-* } } + )); +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17546.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17546.rs new file mode 100644 index 000000000000..36dce87b5631 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17546.rs @@ -0,0 +1,43 @@ +// ignore-sgx std::os::fortanix_sgx::usercalls::raw::Result changes compiler suggestions + +use foo::MyEnum::Result; +use foo::NoResult; // Through a re-export + +mod foo { + pub use self::MyEnum::NoResult; + + pub enum MyEnum { + Result, + NoResult + } + + fn new() -> NoResult { +// { dg-error ".E0573." "" { target *-*-* } .-1 } + unimplemented!() + } +} + +mod bar { + use foo::MyEnum::Result; + use foo; + + fn new() -> Result { +// { dg-error ".E0573." "" { target *-*-* } .-1 } + unimplemented!() + } +} + +fn new() -> Result { +// { dg-error ".E0573." "" { target *-*-* } .-1 } + unimplemented!() +} + +fn newer() -> NoResult { +// { dg-error ".E0573." "" { target *-*-* } .-1 } + unimplemented!() +} + +fn main() { + let _ = new(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17551.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17551.rs new file mode 100644 index 000000000000..1b66f14dcd47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17551.rs @@ -0,0 +1,9 @@ +use std::marker; + +struct B(marker::PhantomData); + +fn main() { + let foo = B(marker::PhantomData); // { dg-error ".E0282." "" { target *-*-* } } + let closure = || foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17651.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17651.rs new file mode 100644 index 000000000000..f022d189feaa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17651.rs @@ -0,0 +1,9 @@ +// Test that moves of unsized values within closures are caught +// and rejected. + +fn main() { + (|| Box::new(*(&[0][..])))(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17662.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17662.rs new file mode 100644 index 000000000000..51856ae2ac19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17662.rs @@ -0,0 +1,18 @@ +// run-pass +// aux-build:issue-17662.rs + + +extern crate issue_17662 as i; + +use std::marker; + +struct Bar<'a> { m: marker::PhantomData<&'a ()> } + +impl<'a> i::Foo<'a, usize> for Bar<'a> { + fn foo(&self) -> usize { 5 } +} + +pub fn main() { + assert_eq!(i::foo(&Bar { m: marker::PhantomData }), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-borrow-interior.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-borrow-interior.rs new file mode 100644 index 000000000000..044964605805 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-borrow-interior.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +struct S { a: usize } + +static A: S = S { a: 3 }; +static B: &'static usize = &A.a; +static C: &'static usize = &(A.a); + +static D: [usize; 1] = [1]; +static E: usize = D[0]; +static F: &'static usize = &D[0]; + +fn main() { + assert_eq!(*B, A.a); + assert_eq!(*B, A.a); + + assert_eq!(E, D[0]); + assert_eq!(*F, D[0]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-bad-values.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-bad-values.rs new file mode 100644 index 000000000000..51716496cca9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-bad-values.rs @@ -0,0 +1,11 @@ +const C1: &'static mut [usize] = &mut []; +// { dg-error ".E0764." "" { target *-*-* } .-1 } + +static mut S: usize = 3; +const C2: &'static mut usize = unsafe { &mut S }; +// { dg-error ".E0764." "" { target *-*-* } .-1 } +// { dg-error ".E0764." "" { target *-*-* } .-2 } +// { dg-error ".E0764." "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-borrow.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-borrow.rs new file mode 100644 index 000000000000..3821b5bfa8af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-borrow.rs @@ -0,0 +1,15 @@ +use std::cell::UnsafeCell; + +const A: UnsafeCell = UnsafeCell::new(1); +const B: &'static UnsafeCell = &A; +// { dg-error ".E0492." "" { target *-*-* } .-1 } + +struct C { a: UnsafeCell } +const D: C = C { a: UnsafeCell::new(1) }; +const E: &'static UnsafeCell = &D.a; +// { dg-error ".E0492." "" { target *-*-* } .-1 } +const F: &'static C = &D; +// { dg-error ".E0492." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-destructors.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-destructors.rs new file mode 100644 index 000000000000..8868b935bd8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-destructors.rs @@ -0,0 +1,11 @@ +// check-pass +#![allow(dead_code)] +struct A; +impl Drop for A { + fn drop(&mut self) {} +} + +const FOO: A = A; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-naming.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-naming.rs new file mode 100644 index 000000000000..5c518ec2aa0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-naming.rs @@ -0,0 +1,9 @@ +#![warn(unused)] +#![deny(warnings)] + +const foo: isize = 3; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-privacy.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-privacy.rs new file mode 100644 index 000000000000..827851cfba6c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-const-privacy.rs @@ -0,0 +1,17 @@ +// aux-build:issue-17718-const-privacy.rs + +extern crate issue_17718_const_privacy as other; + +use a::B; // { dg-error ".E0603." "" { target *-*-* } } +use other::{ + FOO, + BAR, // { dg-error ".E0603." "" { target *-*-* } } + FOO2, +}; + +mod a { + const B: usize = 3; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-constants-not-static.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-constants-not-static.rs new file mode 100644 index 000000000000..619a2419fc18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-constants-not-static.rs @@ -0,0 +1,10 @@ +fn id(x: T) -> T { x } + +const FOO: usize = 3; + +fn foo() -> &'static usize { &id(FOO) } +// { dg-error ".E0515." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-parse-const.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-parse-const.rs new file mode 100644 index 000000000000..29b283b89adb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-parse-const.rs @@ -0,0 +1,8 @@ +// run-pass + +const FOO: usize = 3; + +fn main() { + assert_eq!(FOO, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-patterns.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-patterns.rs new file mode 100644 index 000000000000..fd6a16364712 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-patterns.rs @@ -0,0 +1,13 @@ +static A1: usize = 1; +static mut A2: usize = 1; +const A3: usize = 1; + +fn main() { + match 1 { + A1 => {} // { dg-error ".E0530." "" { target *-*-* } } + A2 => {} // { dg-error ".E0530." "" { target *-*-* } } + A3 => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-references.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-references.rs new file mode 100644 index 000000000000..3dc743993751 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-references.rs @@ -0,0 +1,25 @@ +#![allow(warnings)] + +struct Struct { a: usize } + +const C: usize = 1; +static S: usize = 1; + +const T1: &'static usize = &C; +const T2: &'static usize = &S; // { dg-error ".E0013." "" { target *-*-* } } +static T3: &'static usize = &C; +static T4: &'static usize = &S; + +const T5: usize = C; +const T6: usize = S; // { dg-error ".E0013." "" { target *-*-* } } +static T7: usize = C; +static T8: usize = S; + +const T9: Struct = Struct { a: C }; +const T10: Struct = Struct { a: S }; +// { dg-error ".E0013." "" { target *-*-* } .-1 } +static T11: Struct = Struct { a: C }; +static T12: Struct = Struct { a: S }; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-static-move.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-static-move.rs new file mode 100644 index 000000000000..3a641e81e9c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-static-move.rs @@ -0,0 +1,8 @@ +struct Foo; +const INIT: Foo = Foo; +static FOO: Foo = INIT; + +fn main() { + let _a = FOO; // { dg-error ".E0507." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-static-sync.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-static-sync.rs new file mode 100644 index 000000000000..d83ed94d79bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-static-sync.rs @@ -0,0 +1,13 @@ +#![feature(negative_impls)] + +use std::marker::Sync; + +struct Foo; +impl !Sync for Foo {} + +static FOO: usize = 3; +static BAR: Foo = Foo; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718-static-unsafe-interior.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-static-unsafe-interior.rs new file mode 100644 index 000000000000..57ced14f7762 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718-static-unsafe-interior.rs @@ -0,0 +1,53 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_imports)] +// pretty-expanded FIXME #23616 + +use std::marker; +use std::cell::UnsafeCell; + +struct MyUnsafePack(UnsafeCell); + +unsafe impl Sync for MyUnsafePack {} + +struct MyUnsafe { + value: MyUnsafePack +} + +impl MyUnsafe { + fn forbidden(&self) {} +} + +unsafe impl Sync for MyUnsafe {} + +enum UnsafeEnum { + VariantSafe, + VariantUnsafe(UnsafeCell) +} + +unsafe impl Sync for UnsafeEnum {} + +static STATIC1: UnsafeEnum = UnsafeEnum::VariantSafe; + +static STATIC2: MyUnsafePack = MyUnsafePack(UnsafeCell::new(1)); +const CONST: MyUnsafePack = MyUnsafePack(UnsafeCell::new(1)); +static STATIC3: MyUnsafe = MyUnsafe{value: CONST}; + +static STATIC4: &'static MyUnsafePack = &STATIC2; + +struct Wrap { + value: T +} + +unsafe impl Sync for Wrap {} + +static UNSAFE: MyUnsafePack = MyUnsafePack(UnsafeCell::new(2)); +static WRAPPED_UNSAFE: Wrap<&'static MyUnsafePack> = Wrap { value: &UNSAFE }; + +fn main() { + let a = &STATIC1; + + STATIC3.forbidden() +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17718.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17718.rs new file mode 100644 index 000000000000..ec27e0a7c3be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17718.rs @@ -0,0 +1,76 @@ +// run-pass +#![allow(dead_code)] +// aux-build:issue-17718-aux.rs + +extern crate issue_17718_aux as other; + +use std::sync::atomic::{AtomicUsize, Ordering}; + +const C1: usize = 1; +const C2: AtomicUsize = AtomicUsize::new(0); +const C3: fn() = foo; +const C4: usize = C1 * C1 + C1 / C1; +const C5: &'static usize = &C4; +const C6: usize = { + const C: usize = 3; + C +}; + +static S1: usize = 3; +static S2: AtomicUsize = AtomicUsize::new(0); + +mod test { + static A: usize = 4; + static B: &'static usize = &A; + static C: &'static usize = &(A); +} + +fn foo() {} + +fn main() { + assert_eq!(C1, 1); + assert_eq!(C3(), ()); + assert_eq!(C2.fetch_add(1, Ordering::SeqCst), 0); + assert_eq!(C2.fetch_add(1, Ordering::SeqCst), 0); + assert_eq!(C4, 2); + assert_eq!(*C5, 2); + assert_eq!(C6, 3); + assert_eq!(S1, 3); + assert_eq!(S2.fetch_add(1, Ordering::SeqCst), 0); + assert_eq!(S2.fetch_add(1, Ordering::SeqCst), 1); + + match 1 { + C1 => {} + _ => unreachable!(), + } + + let _a = C1; + let _a = C2; + let _a = C3; + let _a = C4; + let _a = C5; + let _a = C6; + let _a = S1; + + assert_eq!(other::C1, 1); + assert_eq!(other::C3(), ()); + assert_eq!(other::C2.fetch_add(1, Ordering::SeqCst), 0); + assert_eq!(other::C2.fetch_add(1, Ordering::SeqCst), 0); + assert_eq!(other::C4, 2); + assert_eq!(*other::C5, 2); + assert_eq!(other::S1, 3); + assert_eq!(other::S2.fetch_add(1, Ordering::SeqCst), 0); + assert_eq!(other::S2.fetch_add(1, Ordering::SeqCst), 1); + + let _a = other::C1; + let _a = other::C2; + let _a = other::C3; + let _a = other::C4; + let _a = other::C5; + + match 1 { + other::C1 => {} + _ => unreachable!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17728.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17728.rs new file mode 100644 index 000000000000..1e4bd1b94bfb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17728.rs @@ -0,0 +1,124 @@ +use std::fmt::{Debug, Formatter, Error}; +use std::collections::HashMap; + +trait HasInventory { + fn getInventory<'s>(&'s self) -> &'s mut Inventory; + fn addToInventory(&self, item: &Item); + fn removeFromInventory(&self, itemName: &str) -> bool; +} + +trait TraversesWorld { + fn attemptTraverse(&self, room: &Room, directionStr: &str) -> Result<&Room, &str> { + let direction = str_to_direction(directionStr); + let maybe_room = room.direction_to_room.get(&direction); + match maybe_room { + Some(entry) => Ok(entry), +// { dg-error ".E0623." "" { target *-*-* } .-1 } + _ => Err("Direction does not exist in room.") + } + } +} + + +#[derive(Debug, Eq, PartialEq, Hash)] +enum RoomDirection { + West, + East, + North, + South, + Up, + Down, + In, + Out, + + None +} + +struct Room { + description: String, + items: Vec, + direction_to_room: HashMap, +} + +impl Room { + fn new(description: &'static str) -> Room { + Room { + description: description.to_string(), + items: Vec::new(), + direction_to_room: HashMap::new() + } + } + + fn add_direction(&mut self, direction: RoomDirection, room: Room) { + self.direction_to_room.insert(direction, room); + } +} + +struct Item { + name: String, +} + +struct Inventory { + items: Vec, +} + +impl Inventory { + fn new() -> Inventory { + Inventory { + items: Vec::new() + } + } +} + +struct Player { + name: String, + inventory: Inventory, +} + +impl Player { + fn new(name: &'static str) -> Player { + Player { + name: name.to_string(), + inventory: Inventory::new() + } + } +} + +impl TraversesWorld for Player { +} + +impl Debug for Player { + fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> { + formatter.write_str("Player{ name:"); + formatter.write_str(&self.name); + formatter.write_str(" }"); + Ok(()) + } +} + +fn str_to_direction(to_parse: &str) -> RoomDirection { + match to_parse { + "w" | "west" => RoomDirection::West, + "e" | "east" => RoomDirection::East, + "n" | "north" => RoomDirection::North, + "s" | "south" => RoomDirection::South, + "in" => RoomDirection::In, + "out" => RoomDirection::Out, + "up" => RoomDirection::Up, + "down" => RoomDirection::Down, + _ => None + } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn main() { + let mut player = Player::new("Test player"); + let mut room = Room::new("A test room"); + println!("Made a player: {:?}", player); + println!("Direction parse: {:?}", str_to_direction("east")); + match player.attemptTraverse(&room, "west") { + Ok(_) => println!("Was able to move west"), + Err(msg) => println!("Not able to move west: {}", msg) + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17732.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17732.rs new file mode 100644 index 000000000000..3d9081f2fcc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17732.rs @@ -0,0 +1,14 @@ +// check-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +// pretty-expanded FIXME #23616 + +trait Person { + type string; + fn dummy(&self) { } +} + +struct Someone(std::marker::PhantomData

(P); + +impl<'b, P> Wrap<'b> for Wrapper

+where P: Process<'b>, +

>::Item: Iterator { + fn foo(&mut self) {} +} + + +pub trait Process<'a> { + type Item; + fn bar(&'a self); +} + +fn push_process

(process: P) where P: Process<'static> { + let _: Box Wrap<'b>> = Box::new(Wrapper(process)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22874.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22874.rs new file mode 100644 index 000000000000..187b0684abeb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22874.rs @@ -0,0 +1,11 @@ +struct Table { + rows: [[String]], +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn f(table: &Table) -> &[String] { + &table.rows[0] +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2288.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2288.rs new file mode 100644 index 000000000000..d608394eb0fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2288.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(non_camel_case_types)] + +#![feature(box_syntax)] + +trait clam { + fn chowder(&self, y: A); +} + +#[derive(Copy, Clone)] +struct foo { + x: A, +} + +impl clam for foo { + fn chowder(&self, _y: A) { + } +} + +fn foo(b: A) -> foo { + foo { + x: b + } +} + +fn f(x: Box>, a: A) { + x.chowder(a); +} + +pub fn main() { + + let c = foo(42); + let d: Box> = box c as Box>; + f(d, c.x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22886.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22886.rs new file mode 100644 index 000000000000..2b2c00228ce1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22886.rs @@ -0,0 +1,22 @@ +// Regression test for #22886. + +fn crash_please() { + let mut iter = Newtype(Some(Box::new(0))); + let saved = iter.next().unwrap(); + println!("{}", saved); + iter.0 = None; + println!("{}", saved); +} + +struct Newtype(Option>); + +impl<'a> Iterator for Newtype { // { dg-error ".E0207." "" { target *-*-* } } + type Item = &'a Box; + + fn next(&mut self) -> Option<&Box> { + self.0.as_ref() + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22894.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22894.rs new file mode 100644 index 000000000000..178a582b3378 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22894.rs @@ -0,0 +1,5 @@ +// build-pass +#[allow(dead_code)] +static X: &'static str = &*""; +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22933-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22933-1.rs new file mode 100644 index 000000000000..08b3ba69bd25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22933-1.rs @@ -0,0 +1,24 @@ +// check-pass + +struct CNFParser { + token: char, +} + +impl CNFParser { + fn is_whitespace(c: char) -> bool { + c == ' ' || c == '\n' + } + + fn consume_whitespace(&mut self) { + self.consume_while(&(CNFParser::is_whitespace)) + } + + fn consume_while(&mut self, p: &dyn Fn(char) -> bool) { + while p(self.token) { + return + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22933-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22933-2.rs new file mode 100644 index 000000000000..eafc44fa74c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22933-2.rs @@ -0,0 +1,9 @@ +enum Delicious { + Pie = 0x1, + Apple = 0x2, + ApplePie = Delicious::Apple as isize | Delicious::PIE as isize, +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22992-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22992-2.rs new file mode 100644 index 000000000000..e21c30e183ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22992-2.rs @@ -0,0 +1,19 @@ +// run-pass +struct A(B); +struct B; + +use std::ops::Deref; + +impl Deref for A { + type Target = B; + fn deref(&self) -> &B { &self.0 } +} + +impl B { + fn foo(&self) {} +} + +fn main() { + A(B).foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22992.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22992.rs new file mode 100644 index 000000000000..1e88b0218f13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22992.rs @@ -0,0 +1,77 @@ +// run-pass +// ignore-pretty issue #37201 + +struct X { val: i32 } +impl std::ops::Deref for X { + type Target = i32; + fn deref(&self) -> &i32 { &self.val } +} + + +trait M { fn m(self); } +impl M for i32 { fn m(self) { println!("i32::m()"); } } +impl M for X { fn m(self) { println!("X::m()"); } } +impl<'a> M for &'a X { fn m(self) { println!("&X::m()"); } } +impl<'a, 'b> M for &'a &'b X { fn m(self) { println!("&&X::m()"); } } +impl<'a, 'b, 'c> M for &'a &'b &'c X { fn m(self) { println!("&&&X::m()"); } } + +trait RefM { fn refm(&self); } +impl RefM for i32 { fn refm(&self) { println!("i32::refm()"); } } +impl RefM for X { fn refm(&self) { println!("X::refm()"); } } +impl<'a> RefM for &'a X { fn refm(&self) { println!("&X::refm()"); } } +impl<'a, 'b> RefM for &'a &'b X { fn refm(&self) { println!("&&X::refm()"); } } +impl<'a, 'b, 'c> RefM for &'a &'b &'c X { fn refm(&self) { println!("&&&X::refm()"); } } + +struct Y { val: i32 } +impl std::ops::Deref for Y { + type Target = i32; + fn deref(&self) -> &i32 { &self.val } +} + +struct Z { val: Y } +impl std::ops::Deref for Z { + type Target = Y; + fn deref(&self) -> &Y { &self.val } +} + +struct A; +impl std::marker::Copy for A {} +impl Clone for A { fn clone(&self) -> Self { *self } } +impl M for A { fn m(self) { println!("A::m()"); } } +impl<'a, 'b, 'c> M for &'a &'b &'c A { fn m(self) { println!("&&&A::m()"); } } +impl RefM for A { fn refm(&self) { println!("A::refm()"); } } +impl<'a, 'b, 'c> RefM for &'a &'b &'c A { fn refm(&self) { println!("&&&A::refm()"); } } + +fn main() { + // I'll use @ to denote left side of the dot operator + (*X{val:42}).m(); // i32::refm() , self == @ + X{val:42}.m(); // X::m() , self == @ + (&X{val:42}).m(); // &X::m() , self == @ + (&&X{val:42}).m(); // &&X::m() , self == @ + (&&&X{val:42}).m(); // &&&X:m() , self == @ + (&&&&X{val:42}).m(); // &&&X::m() , self == *@ + (&&&&&X{val:42}).m(); // &&&X::m() , self == **@ + + (*X{val:42}).refm(); // i32::refm() , self == @ + X{val:42}.refm(); // X::refm() , self == @ + (&X{val:42}).refm(); // X::refm() , self == *@ + (&&X{val:42}).refm(); // &X::refm() , self == *@ + (&&&X{val:42}).refm(); // &&X::refm() , self == *@ + (&&&&X{val:42}).refm(); // &&&X::refm(), self == *@ + (&&&&&X{val:42}).refm(); // &&&X::refm(), self == **@ + + Y{val:42}.refm(); // i32::refm() , self == *@ + Z{val:Y{val:42}}.refm(); // i32::refm() , self == **@ + + A.m(); // A::m() , self == @ + // without the Copy trait, (&A).m() would be a compilation error: + // cannot move out of borrowed content + (&A).m(); // A::m() , self == *@ + (&&A).m(); // &&&A::m() , self == &@ + (&&&A).m(); // &&&A::m() , self == @ + A.refm(); // A::refm() , self == @ + (&A).refm(); // A::refm() , self == *@ + (&&A).refm(); // A::refm() , self == **@ + (&&&A).refm(); // &&&A::refm(), self == @ +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23024.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23024.rs new file mode 100644 index 000000000000..d9ab853c0f0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23024.rs @@ -0,0 +1,14 @@ +#![feature(box_syntax)] +use std::any::Any; + +fn main() +{ + fn h(x:i32) -> i32 {3*x} + let mut vfnfer:Vec> = vec![]; + vfnfer.push(box h); + println!("{:?}",(vfnfer[0] as dyn Fn)(3)); +// { dg-error ".E0191." "" { target *-*-* } .-1 } +// { dg-error ".E0191." "" { target *-*-* } .-2 } +// { dg-error ".E0191." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23036.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23036.rs new file mode 100644 index 000000000000..22511f9cecbe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23036.rs @@ -0,0 +1,12 @@ +// run-pass +// ignore-cloudabi no std::path + +use std::collections::HashMap; +use std::path::Path; + +fn main() { + let mut map = HashMap::new(); + map.insert(Path::new("a"), 0); + map.get(Path::new("a")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23041.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23041.rs new file mode 100644 index 000000000000..f1b2a85021a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23041.rs @@ -0,0 +1,8 @@ +use std::any::Any; +fn main() +{ + fn bar(x:i32) ->i32 { 3*x }; + let b:Box = Box::new(bar as fn(_)->_); + b.downcast_ref::_>(); // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23046.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23046.rs new file mode 100644 index 000000000000..c449dee9cf8b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23046.rs @@ -0,0 +1,21 @@ +pub enum Expr<'var, VAR> { + Let(Box>, + Box Fn(Expr<'v, VAR>) -> Expr<'v, VAR> + 'var>) +} + +pub fn add<'var, VAR> + (a: Expr<'var, VAR>, b: Expr<'var, VAR>) -> Expr<'var, VAR> { + loop {} +} + +pub fn let_<'var, VAR, F: for<'v> Fn(Expr<'v, VAR>) -> Expr<'v, VAR>> + (a: Expr<'var, VAR>, b: F) -> Expr<'var, VAR> { + loop {} +} + +fn main() { + let ex = |x| { // { dg-error ".E0282." "" { target *-*-* } } + let_(add(x,x), |y| { + let_(add(x, x), |x|x)})}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23073.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23073.rs new file mode 100644 index 000000000000..f2dcfdbcba64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23073.rs @@ -0,0 +1,10 @@ +#![feature(associated_type_defaults)] + +trait Foo { type T; } +trait Bar { + type Foo: Foo; + type FooT = <::Foo>::T; // { dg-error ".E0223." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2311-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2311-2.rs new file mode 100644 index 000000000000..6b2575b64d26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2311-2.rs @@ -0,0 +1,27 @@ +// check-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + + +trait clam { + fn get(self) -> A; +} + +struct foo { + x: A, +} + +impl foo { + pub fn bar>(&self, _c: C) -> B { + panic!(); + } +} + +fn foo(b: A) -> foo { + foo { + x: b + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2311.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2311.rs new file mode 100644 index 000000000000..f792b2e3a3a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2311.rs @@ -0,0 +1,12 @@ +// check-pass +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +trait clam { fn get(self) -> A; } +trait foo { + fn bar>(&self, c: C) -> B; +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2312.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2312.rs new file mode 100644 index 000000000000..7306c416777b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2312.rs @@ -0,0 +1,17 @@ +// check-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// Testing that the B's are resolved + + +trait clam { fn get(self) -> A; } + +struct foo(isize); + +impl foo { + pub fn bar>(&self, _c: C) -> B { panic!(); } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23122-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23122-1.rs new file mode 100644 index 000000000000..421f5d1bacea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23122-1.rs @@ -0,0 +1,15 @@ +// ignore-compare-mode-chalk + +trait Next { + type Next: Next; +} + +struct GetNext { t: T } + +impl Next for GetNext { + type Next = as Next>::Next; +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23122-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23122-2.rs new file mode 100644 index 000000000000..400278ecbde1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23122-2.rs @@ -0,0 +1,14 @@ +// ignore-compare-mode-chalk +trait Next { + type Next: Next; +} + +struct GetNext { t: T } + +impl Next for GetNext { + type Next = as Next>::Next; +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2316-c.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2316-c.rs new file mode 100644 index 000000000000..56d304ccbc91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2316-c.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:issue-2316-a.rs +// aux-build:issue-2316-b.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_2316_b; +use issue_2316_b::cloth; + +pub fn main() { + let _c: cloth::fabric = cloth::fabric::calico; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23173.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23173.rs new file mode 100644 index 000000000000..72b90ad17524 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23173.rs @@ -0,0 +1,14 @@ +enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ } +struct Struct { + a: usize, +} + +fn use_token(token: &Token) { unimplemented!() } + +fn main() { + use_token(&Token::Homura); // { dg-error ".E0599." "" { target *-*-* } } + Struct::method(); // { dg-error ".E0599." "" { target *-*-* } } + Struct::method; // { dg-error ".E0599." "" { target *-*-* } } + Struct::Assoc; // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23189.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23189.rs new file mode 100644 index 000000000000..cc2ff5963ad6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23189.rs @@ -0,0 +1,6 @@ +mod module {} + +fn main() { + let _ = module { x: 0 }; // { dg-error ".E0574." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23208.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23208.rs new file mode 100644 index 000000000000..bed37288f728 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23208.rs @@ -0,0 +1,27 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-23217.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23217.rs new file mode 100644 index 000000000000..d35f00ae2ee4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23217.rs @@ -0,0 +1,6 @@ +pub enum SomeEnum { + B = SomeEnum::A, // { dg-error ".E0599." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23253.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23253.rs new file mode 100644 index 000000000000..df4e8d9733d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23253.rs @@ -0,0 +1,7 @@ +enum Foo { Bar } + +fn main() { + Foo::Bar.a; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23261.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23261.rs new file mode 100644 index 000000000000..adc1c68d4de6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23261.rs @@ -0,0 +1,62 @@ +// run-pass +// Matching on a DST struct should not trigger an LLVM assertion. + +struct Foo { + a: i32, + inner: T +} + +trait Get { + fn get(&self) -> i32; +} + +impl Get for i32 { + fn get(&self) -> i32 { + *self + } +} + +fn check_val(val: &Foo<[u8]>) { + match *val { + Foo { a, .. } => { + assert_eq!(a, 32); + } + } +} + +fn check_dst_val(val: &Foo<[u8]>) { + match *val { + Foo { ref inner, .. } => { + assert_eq!(inner, [1, 2, 3]); + } + } +} + +fn check_both(val: &Foo<[u8]>) { + match *val { + Foo { a, ref inner } => { + assert_eq!(a, 32); + assert_eq!(inner, [1, 2, 3]); + } + } +} + +fn check_trait_obj(val: &Foo) { + match *val { + Foo { a, ref inner } => { + assert_eq!(a, 32); + assert_eq!(inner.get(), 32); + } + } +} + +fn main() { + let foo: &Foo<[u8]> = &Foo { a: 32, inner: [1, 2, 3] }; + check_val(foo); + check_dst_val(foo); + check_both(foo); + + let foo: &Foo = &Foo { a: 32, inner: 32 }; + check_trait_obj(foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23281.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23281.rs new file mode 100644 index 000000000000..ba3a8cc40965 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23281.rs @@ -0,0 +1,13 @@ +pub struct Struct; + +impl Struct { + pub fn function(funs: Vec ()>) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +struct Vec { + t: T, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2330.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2330.rs new file mode 100644 index 000000000000..6cd43d880e20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2330.rs @@ -0,0 +1,14 @@ +enum Chan { } + +trait Channel { + fn send(&self, v: T); +} + +// `Chan` is not a trait, it's an enum +impl Chan for isize { // { dg-error ".E0404." "" { target *-*-* } } + fn send(&self, v: isize) { panic!() } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23302-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23302-1.rs new file mode 100644 index 000000000000..92b3119d2c84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23302-1.rs @@ -0,0 +1,8 @@ +// Check that an enum with recursion in the discriminant throws +// the appropriate error (rather than, say, blowing the stack). +enum X { + A = X::A as isize, // { dg-error ".E0391." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23302-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23302-2.rs new file mode 100644 index 000000000000..e83d62628cc3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23302-2.rs @@ -0,0 +1,9 @@ +// Since `Y::B` here defaults to `Y::A+1`, this is also a +// recursive definition. +enum Y { + A = Y::B as isize, // { dg-error ".E0391." "" { target *-*-* } } + B, +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23302-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23302-3.rs new file mode 100644 index 000000000000..8750add827fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23302-3.rs @@ -0,0 +1,6 @@ +const A: i32 = B; // { dg-error ".E0391." "" { target *-*-* } } + +const B: i32 = A; + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23304-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23304-1.rs new file mode 100644 index 000000000000..a9d3c5625825 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23304-1.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] + +#[repr(u8)] +#[allow(dead_code)] +enum ValueType { + DOUBLE = 0x00, + INT32 = 0x01, +} + +#[repr(u32)] +enum ValueTag { + INT32 = 0x1FFF0u32 | (ValueType::INT32 as u32), + X, +} + +#[repr(u64)] +enum ValueShiftedTag { + INT32 = ValueTag::INT32 as u64, + X, +} + +fn main() { + println!("{}", ValueTag::INT32 as u32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23304-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23304-2.rs new file mode 100644 index 000000000000..6f4aaa725193 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23304-2.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] + +enum X { A = 42 as isize } + +enum Y { A = X::A as isize } + +fn main() { + let x = X::A; + let x = x as isize; + assert_eq!(x, 42); + assert_eq!(Y::A as isize, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23311.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23311.rs new file mode 100644 index 000000000000..730d7150a0ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23311.rs @@ -0,0 +1,12 @@ +// run-pass + +// Test that we do not ICE when pattern matching an array against a slice. + +fn main() { + match "foo".as_bytes() { + b"food" => (), + &[b'f', ..] => (), + _ => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23336.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23336.rs new file mode 100644 index 000000000000..d4773465298a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23336.rs @@ -0,0 +1,12 @@ +// run-pass +pub trait Data { fn doit(&self) {} } +impl Data for T {} +pub trait UnaryLogic { type D: Data; } +impl UnaryLogic for () { type D = i32; } + +pub fn crashes(t: T::D) { + t.doit(); +} + +fn main() { crashes::<()>(0); } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23338-ensure-param-drop-order.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23338-ensure-param-drop-order.rs new file mode 100644 index 000000000000..d5b384f6e809 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23338-ensure-param-drop-order.rs @@ -0,0 +1,165 @@ +// run-pass +#![allow(non_upper_case_globals)] + +// ignore-pretty issue #37201 + +// This test is ensuring that parameters are indeed dropped after +// temporaries in a fn body. + +use std::cell::RefCell; + +use self::d::D; + +pub fn main() { + let log = RefCell::new(vec![]); + d::println("created empty log"); + test(&log); + + assert_eq!(&log.borrow()[..], + [ + // created empty log + // +-- Make D(da_0, 0) + // | +-- Make D(de_1, 1) + // | | calling foo + // | | entered foo + // | | +-- Make D(de_2, 2) + // | | | +-- Make D(da_1, 3) + // | | | | +-- Make D(de_3, 4) + // | | | | | +-- Make D(de_4, 5) + 3, // | | | +-- Drop D(da_1, 3) + // | | | | | + 4, // | | | +-- Drop D(de_3, 4) + // | | | | + // | | | | eval tail of foo + // | | | +-- Make D(de_5, 6) + // | | | | +-- Make D(de_6, 7) + 5, // | | | | | +-- Drop D(de_4, 5) + // | | | | | + 2, // | | +-- Drop D(de_2, 2) + // | | | | + 6, // | | +-- Drop D(de_5, 6) + // | | | + 1, // | +-- Drop D(de_1, 1) + // | | + 0, // +-- Drop D(da_0, 0) + // | + // | result D(de_6, 7) + 7 // +-- Drop D(de_6, 7) + + ]); +} + +fn test<'a>(log: d::Log<'a>) { + let da = D::new("da", 0, log); + let de = D::new("de", 1, log); + d::println("calling foo"); + let result = foo(da, de); + d::println(&format!("result {}", result)); +} + +fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> { + d::println("entered foo"); + let de2 = de1.incr(); // creates D(de_2, 2) + let de4 = { + let _da1 = da0.incr(); // creates D(da_1, 3) + de2.incr().incr() // creates D(de_3, 4) and D(de_4, 5) + }; + d::println("eval tail of foo"); + de4.incr().incr() // creates D(de_5, 6) and D(de_6, 7) +} + +// This module provides simultaneous printouts of the dynamic extents +// of all of the D values, in addition to logging the order that each +// is dropped. + +const PREF_INDENT: u32 = 16; + +pub mod d { + #![allow(unused_parens)] + use std::fmt; + use std::mem; + use std::cell::RefCell; + + static mut counter: u32 = 0; + static mut trails: u64 = 0; + + pub type Log<'a> = &'a RefCell>; + + pub fn current_width() -> u32 { + unsafe { max_width() - trails.leading_zeros() } + } + + pub fn max_width() -> u32 { + unsafe { + (mem::size_of_val(&trails)*8) as u32 + } + } + + pub fn indent_println(my_trails: u32, s: &str) { + let mut indent: String = String::new(); + for i in 0..my_trails { + unsafe { + if trails & (1 << i) != 0 { + indent = indent + "| "; + } else { + indent = indent + " "; + } + } + } + println!("{}{}", indent, s); + } + + pub fn println(s: &str) { + indent_println(super::PREF_INDENT, s); + } + + fn first_avail() -> u32 { + unsafe { + for i in 0..64 { + if trails & (1 << i) == 0 { + return i; + } + } + } + panic!("exhausted trails"); + } + + pub struct D<'a> { + name: &'static str, i: u32, uid: u32, trail: u32, log: Log<'a> + } + + impl<'a> fmt::Display for D<'a> { + fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { + write!(w, "D({}_{}, {})", self.name, self.i, self.uid) + } + } + + impl<'a> D<'a> { + pub fn new(name: &'static str, i: u32, log: Log<'a>) -> D<'a> { + unsafe { + let trail = first_avail(); + let ctr = counter; + counter += 1; + trails |= (1 << trail); + let ret = D { + name: name, i: i, log: log, uid: ctr, trail: trail + }; + indent_println(trail, &format!("+-- Make {}", ret)); + ret + } + } + pub fn incr(&self) -> D<'a> { + D::new(self.name, self.i + 1, self.log) + } + } + + impl<'a> Drop for D<'a> { + fn drop(&mut self) { + unsafe { trails &= !(1 << self.trail); }; + self.log.borrow_mut().push(self.uid); + indent_println(self.trail, &format!("+-- Drop {}", self)); + indent_println(::PREF_INDENT, ""); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23338-params-outlive-temps-of-body.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23338-params-outlive-temps-of-body.rs new file mode 100644 index 000000000000..7a2578951cf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23338-params-outlive-temps-of-body.rs @@ -0,0 +1,31 @@ +// run-pass +// This is largely checking that we now accept code where temp values +// are borrowing from the input parameters (the `foo` case below). +// +// Compare to run-pass/issue-23338-params-outlive-temps-of-body.rs +// +// (The `foo2` case is just for parity with the above test, which +// shows what happens when you move the `y`-binding to the inside of +// the inner block.) + +use std::cell::RefCell; + +fn foo(x: RefCell) -> String { + x.borrow().clone() +} + +fn foo2(x: RefCell) -> String { + let y = x; + let ret = { + y.borrow().clone() + }; + ret +} + +pub fn main() { + let r = RefCell::new(format!("data")); + assert_eq!(foo(r), "data"); + let r = RefCell::new(format!("data")); + assert_eq!(foo2(r), "data"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23354-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23354-2.rs new file mode 100644 index 000000000000..78d88307b6cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23354-2.rs @@ -0,0 +1,10 @@ +// run-fail +// error-pattern:panic evaluated +// ignore-emscripten no processes + +#[allow(unused_variables)] +fn main() { + // This used to trigger an LLVM assertion during compilation + let x = [panic!("panic evaluated"); 2]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23354.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23354.rs new file mode 100644 index 000000000000..bfd723359f39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23354.rs @@ -0,0 +1,9 @@ +// run-fail +// error-pattern:panic evaluated +// ignore-emscripten no processes + +#[allow(unused_variables)] +fn main() { + let x = [panic!("panic evaluated"); 0]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23406.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23406.rs new file mode 100644 index 000000000000..47883c2620c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23406.rs @@ -0,0 +1,16 @@ +// build-pass +#![allow(dead_code)] +trait Inner { + type T; +} + +impl<'a> Inner for &'a i32 { + type T = i32; +} + +fn f<'a>(x: &'a i32) -> <&'a i32 as Inner>::T { + *x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23433.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23433.rs new file mode 100644 index 000000000000..4c794725c7e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23433.rs @@ -0,0 +1,14 @@ +// run-pass +// Don't fail if we encounter a NonNull where T is an unsized type + +use std::ptr::NonNull; + +fn main() { + let mut a = [0u8; 5]; + let b: Option> = Some(NonNull::from(&mut a)); + match b { + Some(_) => println!("Got `Some`"), + None => panic!("Unexpected `None`"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23442.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23442.rs new file mode 100644 index 000000000000..199843c9da6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23442.rs @@ -0,0 +1,24 @@ +// check-pass +#![allow(dead_code)] +use std::marker::PhantomData; + +pub struct UnionedKeys<'a,K> + where K: UnifyKey + 'a +{ + table: &'a mut UnificationTable, + root_key: K, + stack: Vec, +} + +pub trait UnifyKey { + type Value; +} + +pub struct UnificationTable { + values: Delegate, +} + +pub struct Delegate(PhantomData); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23458.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23458.rs new file mode 100644 index 000000000000..1303149f843e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23458.rs @@ -0,0 +1,12 @@ +#![feature(llvm_asm)] + +// build-fail +// only-x86_64 + +fn main() { + unsafe { + llvm_asm!("int $3"); // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23477.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23477.rs new file mode 100644 index 000000000000..8cf54be856b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23477.rs @@ -0,0 +1,17 @@ +// build-pass +// ignore-asmjs wasm2js does not support source maps yet +// compile-flags: -g + +pub struct Dst { + pub a: (), + pub b: (), + pub data: [u8], +} + +pub unsafe fn borrow(bytes: &[u8]) -> &Dst { + let dst: &Dst = std::mem::transmute((bytes.as_ptr(), bytes.len())); + dst +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23485.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23485.rs new file mode 100644 index 000000000000..6dbe9cb7376e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23485.rs @@ -0,0 +1,51 @@ +// run-pass +#![allow(unused_imports)] +// Test for an ICE that occurred when a default method implementation +// was applied to a type that did not meet the prerequisites. The +// problem occurred specifically because normalizing +// `Self::Item::Target` was impossible in this case. + +use std::boxed::Box; +use std::marker::Sized; +use std::clone::Clone; +use std::ops::Deref; +use std::option::Option; +use std::option::Option::{Some,None}; + +trait Iterator { + type Item; + + fn next(&mut self) -> Option; + + fn clone_first(mut self) -> Option<::Target> where + Self: Sized, + Self::Item: Deref, + ::Target: Clone, + { + self.next().map(|x| x.clone()) + } +} + +struct Counter { + value: i32 +} + +struct Token { + value: i32 +} + +impl Iterator for Counter { + type Item = Token; + + fn next(&mut self) -> Option { + let x = self.value; + self.value += 1; + Some(Token { value: x }) + } +} + +fn main() { + let mut x: Box> = Box::new(Counter { value: 22 }); + assert_eq!(x.next().unwrap().value, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23491.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23491.rs new file mode 100644 index 000000000000..f2d322bae18f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23491.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(unused_variables)] +#![feature(box_syntax)] + +struct Node(T); + +fn main() { + let x: Box> = box Node([]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23543.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23543.rs new file mode 100644 index 000000000000..70aab0c6579f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23543.rs @@ -0,0 +1,12 @@ +pub trait A: Copy {} + +struct Foo; + +pub trait D { + fn f(self) + where T: A; +// { dg-error ".E0229." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23544.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23544.rs new file mode 100644 index 000000000000..c211f93c10e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23544.rs @@ -0,0 +1,10 @@ +pub trait A: Copy {} + +pub trait D { + fn f(self) + where T: A; +// { dg-error ".E0229." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23550.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23550.rs new file mode 100644 index 000000000000..b6ac72724009 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23550.rs @@ -0,0 +1,23 @@ +// build-pass +#![feature(core_intrinsics)] +#![allow(warnings)] + +use std::intrinsics; + +#[derive(Copy, Clone)] +struct Wrap(i64); + +// These volatile intrinsics used to cause an ICE + +unsafe fn test_bool(p: &mut bool, v: bool) { + intrinsics::volatile_load(p); + intrinsics::volatile_store(p, v); +} + +unsafe fn test_immediate_fca(p: &mut Wrap, v: Wrap) { + intrinsics::volatile_load(p); + intrinsics::volatile_store(p, v); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23589.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23589.rs new file mode 100644 index 000000000000..401651ac6490 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23589.rs @@ -0,0 +1,6 @@ +fn main() { + let v: Vec(&str) = vec!['1', '2']; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23595-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23595-2.rs new file mode 100644 index 000000000000..7e39b14389d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23595-2.rs @@ -0,0 +1,11 @@ +#![feature(associated_type_defaults)] + +pub struct C {a:AType} + +pub trait A { + type B = C; +// { dg-error ".E0220." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23611-enum-swap-in-drop.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23611-enum-swap-in-drop.rs new file mode 100644 index 000000000000..4640eedcce83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23611-enum-swap-in-drop.rs @@ -0,0 +1,260 @@ +// run-pass +#![allow(non_upper_case_globals)] + +// Issue 23611: this test is ensuring that, for an instance `X` of the +// enum `E`, if you swap in a different variant during the execution +// of the `::drop`, then the appropriate substructure will +// be torn down after the `::drop` method returns. + +use std::cell::RefCell; +use std::mem; + +use self::d::D; + +pub fn main() { + let log = RefCell::new(vec![]); + d::println("created empty log"); + test(&log); + + // println!("log: {:?}", &log.borrow()[..]); + assert_eq!( + &log.borrow()[..], + [ + // created empty log + // +-- Make D(test_1, 10000000) + // | +-- Make D(g_b_5, 50000001) + // | | in g_B(b2b0) from E::drop, b=b4b0 + // | +-- Drop D(g_b_5, 50000001) + 50000001, + // | + // | +-- Make D(drop_6, 60000002) + // | | +-- Make D(g_b_5, 50000003) + // | | | in g_B(b2b0) from E::drop, b=b4b1 + // | | +-- Drop D(g_b_5, 50000003) + 50000003, + // | | + // | | +-- Make D(GaspB::drop_3, 30000004) + // | | | +-- Make D(g_b_5, 50000005) + // | | | | in g_B(b4b2) from GaspB::drop + // | | | +-- Drop D(g_b_5, 50000005) + 50000005, + // | | | + // | | +-- Drop D(GaspB::drop_3, 30000004) + 30000004, + // | | + // +-- Drop D(test_1, 10000000) + 10000000, + // | + // +-- Make D(GaspA::drop_2, 20000006) + // | | +-- Make D(f_a_4, 40000007) + // | | | in f_A(a3a0) from GaspA::drop + // | | +-- Drop D(f_a_4, 40000007) + 40000007, + // | | + // +-- Drop D(GaspA::drop_2, 20000006) + 20000006, + // | + // +-- Drop D(drop_6, 60000002) + 60000002 + // + ]); + + // For reference purposes, the old (incorrect) behavior would produce the following + // output, which you can compare to the above: + // + // created empty log + // +-- Make D(test_1, 10000000) + // | +-- Make D(g_b_5, 50000001) + // | | in g_B(b2b0) from E::drop, b=b4b0 + // | +-- Drop D(g_b_5, 50000001) + // | + // | +-- Make D(drop_6, 60000002) + // | | +-- Make D(g_b_5, 50000003) + // | | | in g_B(b2b0) from E::drop, b=b4b1 + // | | +-- Drop D(g_b_5, 50000003) + // | | + // | | +-- Make D(GaspB::drop_3, 30000004) + // | | | +-- Make D(g_b_5, 50000005) + // | | | | in g_B(b4b2) from GaspB::drop + // | | | +-- Drop D(g_b_5, 50000005) + // | | | + // | | +-- Drop D(GaspB::drop_3, 30000004) + // | | + // +-- Drop D(test_1, 10000000) + // | + // +-- Make D(GaspB::drop_3, 30000006) + // | | +-- Make D(f_a_4, 40000007) + // | | | in f_A(a3a0) from GaspB::drop + // | | +-- Drop D(f_a_4, 40000007) + // | | + // +-- Drop D(GaspB::drop_3, 30000006) + // | + // +-- Drop D(drop_6, 60000002) + + // Note that this calls f_A from GaspB::drop (and thus creates a D + // with a uid incorporating the origin of GaspB's drop that + // surrounds the f_A invocation), but the code as written only + // ever hands f_A off to instances of GaspA, and thus one should + // be able to prove the invariant that f_A is *only* invoked from + // from an instance of GaspA (either via the GaspA drop + // implementation or the E drop implementaton). Yet the old (bad) + // behavior allowed a call to f_A to leak in while we are tearing + // down a value of type GaspB. +} + +fn test<'a>(log: d::Log<'a>) { + let _e = E::B(GaspB(g_b, 0xB4B0, log, D::new("test", 1, log)), true); +} + +struct GaspA<'a>(for <'b> fn(u32, &'b str, d::Log<'a>), u32, d::Log<'a>, d::D<'a>); +struct GaspB<'a>(for <'b> fn(u32, &'b str, d::Log<'a>), u32, d::Log<'a>, d::D<'a>); + +impl<'a> Drop for GaspA<'a> { + fn drop(&mut self) { + let _d = d::D::new("GaspA::drop", 2, self.2); + (self.0)(self.1, "GaspA::drop", self.2); + } +} + +impl<'a> Drop for GaspB<'a> { + fn drop(&mut self) { + let _d = d::D::new("GaspB::drop", 3, self.2); + (self.0)(self.1, "GaspB::drop", self.2); + } +} + +enum E<'a> { + A(GaspA<'a>, bool), B(GaspB<'a>, bool), +} + +fn f_a(x: u32, ctxt: &str, log: d::Log) { + let _d = d::D::new("f_a", 4, log); + d::println(&format!("in f_A({:x}) from {}", x, ctxt)); +} +fn g_b(y: u32, ctxt: &str, log: d::Log) { + let _d = d::D::new("g_b", 5, log); + d::println(&format!("in g_B({:x}) from {}", y, ctxt)); +} + +impl<'a> Drop for E<'a> { + fn drop(&mut self) { + let (do_drop, log) = match *self { + E::A(GaspA(ref f, ref mut val_a, log, ref _d_a), ref mut do_drop) => { + f(0xA1A0, &format!("E::drop, a={:x}", val_a), log); + *val_a += 1; + // swap in do_drop := false to avoid infinite dtor regress + (mem::replace(do_drop, false), log) + } + E::B(GaspB(ref g, ref mut val_b, log, ref _d_b), ref mut do_drop) => { + g(0xB2B0, &format!("E::drop, b={:x}", val_b), log); + *val_b += 1; + // swap in do_drop := false to avoid infinite dtor regress + (mem::replace(do_drop, false), log) + } + }; + + #[allow(unused_must_use)] + if do_drop { + mem::replace(self, E::A(GaspA(f_a, 0xA3A0, log, D::new("drop", 6, log)), true)); + } + } +} + +// This module provides simultaneous printouts of the dynamic extents +// of all of the D values, in addition to logging the order that each +// is dropped. +// +// This code is similar to a support code module embedded within +// test/run-pass/issue-123338-ensure-param-drop-order.rs; however, +// that (slightly simpler) code only identifies objects in the log via +// (creation) time-stamps; this incorporates both timestamping and the +// point of origin within the source code into the unique ID (uid). + +const PREF_INDENT: u32 = 20; + +pub mod d { + #![allow(unused_parens)] + use std::fmt; + use std::mem; + use std::cell::RefCell; + + static mut counter: u16 = 0; + static mut trails: u64 = 0; + + pub type Log<'a> = &'a RefCell>; + + pub fn current_width() -> u32 { + unsafe { max_width() - trails.leading_zeros() } + } + + pub fn max_width() -> u32 { + unsafe { + (mem::size_of_val(&trails)*8) as u32 + } + } + + pub fn indent_println(my_trails: u32, s: &str) { + let mut indent: String = String::new(); + for i in 0..my_trails { + unsafe { + if trails & (1 << i) != 0 { + indent = indent + "| "; + } else { + indent = indent + " "; + } + } + } + println!("{}{}", indent, s); + } + + pub fn println(s: &str) { + indent_println(super::PREF_INDENT, s); + } + + fn first_avail() -> u32 { + unsafe { + for i in 0..64 { + if trails & (1 << i) == 0 { + return i; + } + } + } + panic!("exhausted trails"); + } + + pub struct D<'a> { + name: &'static str, i: u8, uid: u32, trail: u32, log: Log<'a> + } + + impl<'a> fmt::Display for D<'a> { + fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { + write!(w, "D({}_{}, {})", self.name, self.i, self.uid) + } + } + + impl<'a> D<'a> { + pub fn new(name: &'static str, i: u8, log: Log<'a>) -> D<'a> { + unsafe { + let trail = first_avail(); + let ctr = ((i as u32) * 10_000_000) + (counter as u32); + counter += 1; + trails |= (1 << trail); + let ret = D { + name: name, i: i, log: log, uid: ctr, trail: trail + }; + indent_println(trail, &format!("+-- Make {}", ret)); + ret + } + } + } + + impl<'a> Drop for D<'a> { + fn drop(&mut self) { + unsafe { trails &= !(1 << self.trail); }; + self.log.borrow_mut().push(self.uid); + indent_println(self.trail, &format!("+-- Drop {}", self)); + indent_println(::PREF_INDENT, ""); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23649-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23649-1.rs new file mode 100644 index 000000000000..0f51f61eb5a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23649-1.rs @@ -0,0 +1,13 @@ +// run-pass +use std::mem; + +pub struct X([u8]); + +fn _f(x: &X) -> usize { match *x { X(ref x) => { x.len() } } } + +fn main() { + let b: &[u8] = &[11; 42]; + let v: &X = unsafe { mem::transmute(b) }; + assert_eq!(_f(v), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23649-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23649-2.rs new file mode 100644 index 000000000000..0c410591336f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23649-2.rs @@ -0,0 +1,12 @@ +// run-pass +// ignore-cloudabi no std::path + +use std::collections::HashMap; +use std::path::{Path, PathBuf}; + +fn main() { + let m: HashMap = HashMap::new(); + let k = Path::new("foo"); + println!("{:?}", m.get(k)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23649-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23649-3.rs new file mode 100644 index 000000000000..a8e9c99c2d46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23649-3.rs @@ -0,0 +1,6 @@ +// build-pass +#[derive(PartialEq)] +struct Slice { slice: [u8] } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23699.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23699.rs new file mode 100644 index 000000000000..11b65d7a67ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23699.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(unused_variables)] +fn gimme_a_raw_pointer(_: *const T) { } + +fn test(t: T) { } + +fn main() { + // Clearly `pointer` must be of type `*const ()`. + let pointer = &() as *const _; + gimme_a_raw_pointer(pointer); + + let t = test as fn (i32); + t(0i32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23716.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23716.rs new file mode 100644 index 000000000000..93b0c2f2f1f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23716.rs @@ -0,0 +1,18 @@ +static foo: i32 = 0; + +fn bar(foo: i32) {} +// { dg-error ".E0530." "" { target *-*-* } .-1 } +// { dg-error ".E0530." "" { target *-*-* } .-2 } + +mod submod { + pub static answer: i32 = 42; +} + +use self::submod::answer; + +fn question(answer: i32) {} +// { dg-error ".E0530." "" { target *-*-* } .-1 } +// { dg-error ".E0530." "" { target *-*-* } .-2 } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23781.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23781.rs new file mode 100644 index 000000000000..2590ca58639a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23781.rs @@ -0,0 +1,30 @@ +// run-pass +use std::fmt; + +struct Foo; +impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + println!("::fmt()"); + + write!(fmt, "") + } +} + +fn test1() { + let foo_str = format!("{:?}", Foo); + + println!("{}", foo_str); +} + +fn test2() { + println!("{:?}", Foo); +} + +fn main() { + // This works fine + test1(); + + // This fails + test2(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2380-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2380-b.rs new file mode 100644 index 000000000000..2a00a5f47d33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2380-b.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:issue-2380.rs + +// pretty-expanded FIXME #23616 + +extern crate a; + +pub fn main() { + a::f::<()>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23808.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23808.rs new file mode 100644 index 000000000000..6c275014b5dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23808.rs @@ -0,0 +1,60 @@ +// run-pass + +#![deny(dead_code)] + +// use different types / traits to test all combinations + +trait Const { + const C: (); +} + +trait StaticFn { + fn sfn(); +} + +struct ConstStruct; +struct StaticFnStruct; + +enum ConstEnum {} +enum StaticFnEnum {} + +struct AliasedConstStruct; +struct AliasedStaticFnStruct; + +enum AliasedConstEnum {} +enum AliasedStaticFnEnum {} + +type AliasConstStruct = AliasedConstStruct; +type AliasStaticFnStruct = AliasedStaticFnStruct; +type AliasConstEnum = AliasedConstEnum; +type AliasStaticFnEnum = AliasedStaticFnEnum; + +macro_rules! impl_Const {($($T:ident),*) => {$( + impl Const for $T { + const C: () = (); + } +)*}} + +macro_rules! impl_StaticFn {($($T:ident),*) => {$( + impl StaticFn for $T { + fn sfn() {} + } +)*}} + +impl_Const!(ConstStruct, ConstEnum, AliasedConstStruct, AliasedConstEnum); +impl_StaticFn!(StaticFnStruct, StaticFnEnum, AliasedStaticFnStruct, AliasedStaticFnEnum); + +fn main() { + let _ = ConstStruct::C; + let _ = ConstEnum::C; + + StaticFnStruct::sfn(); + StaticFnEnum::sfn(); + + let _ = AliasConstStruct::C; + let _ = AliasConstEnum::C; + + AliasStaticFnStruct::sfn(); + AliasStaticFnEnum::sfn(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23825.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23825.rs new file mode 100644 index 000000000000..dbf85a496fb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23825.rs @@ -0,0 +1,22 @@ +// run-pass +trait Stringify { + fn to_string(&self) -> String; +} + +impl Stringify for u32 { + fn to_string(&self) -> String { format!("u32: {}", *self) } +} + +impl Stringify for f32 { + fn to_string(&self) -> String { format!("f32: {}", *self) } +} + +fn print(x: T) -> String { + x.to_string() +} + +fn main() { + assert_eq!(&print(5), "u32: 5"); + assert_eq!(&print(5.0), "f32: 5"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2383.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2383.rs new file mode 100644 index 000000000000..f15526fbff3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2383.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +use std::collections::VecDeque; + +pub fn main() { + let mut q = VecDeque::new(); + q.push_front(10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23833.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23833.rs new file mode 100644 index 000000000000..157c00fb00de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23833.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(unused_imports)] +use std::fmt; +use std::{i8, i16, i32, i64, isize}; +use std::{u8, u16, u32, u64, usize}; + +const A_I8_T + : [u32; (i8::MAX as i8 - 1i8) as usize] + = [0; (i8::MAX as usize) - 1]; + +fn main() { + foo(&A_I8_T[..]); +} + +fn foo(x: T) { + println!("{:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23891.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23891.rs new file mode 100644 index 000000000000..1124c1bd8e4c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23891.rs @@ -0,0 +1,12 @@ +// run-pass +macro_rules! id { + ($s: pat) => ($s); +} + +fn main() { + match (Some(123), Some(456)) { + (id!(Some(a)), _) | (_, id!(Some(a))) => println!("{}", a), + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23898.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23898.rs new file mode 100644 index 000000000000..fdea6b46f684 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23898.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(unused_parens)] +#![allow(non_camel_case_types)] + +// Note: This test was used to demonstrate #5873 (now #23898). + +enum State { ST_NULL, ST_WHITESPACE } + +fn main() { + [State::ST_NULL; (State::ST_WHITESPACE as usize)]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23958.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23958.rs new file mode 100644 index 000000000000..0e6e5cb435c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23958.rs @@ -0,0 +1,14 @@ +// run-pass +trait Collection where for<'a> &'a Self: IntoIterator { + fn my_iter(&self) -> <&Self as IntoIterator>::IntoIter { + self.into_iter() + } +} + +impl Collection for [T] { } + +fn main() { + let v = [0usize]; + let _ = v.my_iter(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23966.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23966.rs new file mode 100644 index 000000000000..41bbb1ece8c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23966.rs @@ -0,0 +1,5 @@ +fn main() { + "".chars().fold(|_, _| (), ()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23968-const-not-overflow.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23968-const-not-overflow.rs new file mode 100644 index 000000000000..d67214c870a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23968-const-not-overflow.rs @@ -0,0 +1,13 @@ +// run-pass +const U8_MAX_HALF: u8 = !0u8 / 2; +const U16_MAX_HALF: u16 = !0u16 / 2; +const U32_MAX_HALF: u32 = !0u32 / 2; +const U64_MAX_HALF: u64 = !0u64 / 2; + +fn main() { + assert_eq!(U8_MAX_HALF, 0x7f); + assert_eq!(U16_MAX_HALF, 0x7fff); + assert_eq!(U32_MAX_HALF, 0x7fff_ffff); + assert_eq!(U64_MAX_HALF, 0x7fff_ffff_ffff_ffff); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-23992.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-23992.rs new file mode 100644 index 000000000000..651d50790d7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-23992.rs @@ -0,0 +1,20 @@ +// run-pass +pub struct Outer(T); +pub struct Inner<'a> { value: &'a bool } + +pub trait Trait { + type Error; + fn ready(self) -> Self::Error; +} + +impl<'a> Trait for Inner<'a> { + type Error = Outer>; + fn ready(self) -> Outer> { Outer(self) } +} + +fn main() { + let value = true; + let inner = Inner { value: &value }; + assert_eq!(inner.ready().0.value, &value); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24010.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24010.rs new file mode 100644 index 000000000000..7a5e11139aa4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24010.rs @@ -0,0 +1,15 @@ +// run-pass + +trait Foo: Fn(i32) -> i32 + Send {} + +impl i32 + Send> Foo for T {} + +fn wants_foo(f: Box) -> i32 { + f(42) +} + +fn main() { + let f = Box::new(|x| x); + assert_eq!(wants_foo(f), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24013.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24013.rs new file mode 100644 index 000000000000..1aeab386d024 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24013.rs @@ -0,0 +1,8 @@ +fn main() { + use std::mem::{transmute, swap}; + let a = 1; + let b = 2; + unsafe {swap::<&mut _>(transmute(&a), transmute(&b))}; +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24036.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24036.rs new file mode 100644 index 000000000000..157a72ebac4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24036.rs @@ -0,0 +1,17 @@ +fn closure_to_loc() { + let mut x = |c| c + 1; + x = |c| c + 1; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn closure_from_match() { + let x = match 1usize { + 1 => |c| c + 1, + 2 => |c| c - 1, + _ => |c| c - 1 + }; +// { dg-error ".E0282." "" { target *-*-* } .-4 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24081.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24081.rs new file mode 100644 index 000000000000..8304931d302d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24081.rs @@ -0,0 +1,19 @@ +use std::ops::Add; +use std::ops::Sub; +use std::ops::Mul; +use std::ops::Div; +use std::ops::Rem; + +type Add = bool; // { dg-error ".E0255." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +struct Sub { x: f32 } // { dg-error ".E0255." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +enum Mul { A, B } // { dg-error ".E0255." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +mod Div { } // { dg-error ".E0255." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +trait Rem { } // { dg-error ".E0255." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24085.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24085.rs new file mode 100644 index 000000000000..9f743681f7c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24085.rs @@ -0,0 +1,20 @@ +// check-pass +#![allow(dead_code)] +// Regression test for #24085. Errors were occurring in region +// inference due to the requirement that `'a:b'`, which was getting +// incorrectly codegened in connection with the closure below. + +#[derive(Copy,Clone)] +struct Path<'a:'b, 'b> { + x: &'a i32, + tail: Option<&'b Path<'a, 'b>> +} + +#[allow(dead_code, unconditional_recursion)] +fn foo<'a,'b,F>(p: Path<'a, 'b>, mut f: F) + where F: for<'c> FnMut(Path<'a, 'c>) { + foo(p, |x| f(x)) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24086.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24086.rs new file mode 100644 index 000000000000..6f737c10fa94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24086.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_mut)] +#![allow(unused_variables)] +pub struct Registry<'a> { + listener: &'a mut (), +} + +pub struct Listener<'a> { + pub announce: Option>, + pub remove: Option>, +} + +impl<'a> Drop for Registry<'a> { + fn drop(&mut self) {} +} + +fn main() { + let mut registry_listener = Listener { + announce: None, + remove: None, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2414-c.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2414-c.rs new file mode 100644 index 000000000000..3dc89d964484 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2414-c.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:issue-2414-a.rs +// aux-build:issue-2414-b.rs + +// pretty-expanded FIXME #23616 + +extern crate b; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24161.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24161.rs new file mode 100644 index 000000000000..60e0554950ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24161.rs @@ -0,0 +1,12 @@ +// check-pass +#![allow(dead_code)] +#[derive(Copy,Clone)] +struct Functions { + a: fn(u32) -> u32, + b: extern "C" fn(u32) -> u32, + c: unsafe fn(u32) -> u32, + d: unsafe extern "C" fn(u32) -> u32 +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24204.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24204.rs new file mode 100644 index 000000000000..a491742361f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24204.rs @@ -0,0 +1,26 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-24227.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24227.rs new file mode 100644 index 000000000000..b5bd0802e35b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24227.rs @@ -0,0 +1,19 @@ +// check-pass +// This resulted in an ICE. Test for future-proofing +// Issue #24227 + +#![allow(unused)] + +struct Foo<'a> { + x: &'a u8 +} + +impl<'a> Foo<'a> { + fn foo() { + let mut tmp: Self; + } + +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24267-flow-exit.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24267-flow-exit.rs new file mode 100644 index 000000000000..7e5b8d1b68a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24267-flow-exit.rs @@ -0,0 +1,20 @@ +// Ensure that we reject code when a nonlocal exit (`break`, +// `continue`) causes us to pop over a needed assignment. + +pub fn main() { + foo1(); + foo2(); +} + +pub fn foo1() { + let x: i32; + loop { x = break; } + println!("{}", x); // { dg-error ".E0381." "" { target *-*-* } } +} + +pub fn foo2() { + let x: i32; + for _ in 0..10 { x = continue; } + println!("{}", x); // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2428.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2428.rs new file mode 100644 index 000000000000..4f8c55738259 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2428.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(non_upper_case_globals)] + + +pub fn main() { + let _foo = 100; + const quux: isize = 5; + + enum Stuff { + Bar = quux + } + + assert_eq!(Stuff::Bar as isize, quux); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24308.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24308.rs new file mode 100644 index 000000000000..02310670bafe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24308.rs @@ -0,0 +1,18 @@ +// run-pass +pub trait Foo { + fn method1() {} + fn method2(); +} + +struct Slice<'a, T: 'a>(&'a [T]); + +impl<'a, T: 'a> Foo for Slice<'a, T> { + fn method2() { + ::method1(); + } +} + +fn main() { + as Foo>::method2(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24313.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24313.rs new file mode 100644 index 000000000000..d8713a759151 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24313.rs @@ -0,0 +1,34 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no threads +// ignore-sgx no processes + +use std::thread; +use std::env; +use std::process::Command; + +struct Handle(i32); + +impl Drop for Handle { + fn drop(&mut self) { panic!(); } +} + +thread_local!(static HANDLE: Handle = Handle(0)); + +fn main() { + let args = env::args().collect::>(); + if args.len() == 1 { + let out = Command::new(&args[0]).arg("test").output().unwrap(); + let stderr = std::str::from_utf8(&out.stderr).unwrap(); + assert!(stderr.contains("panicked at 'explicit panic'"), + "bad failure message:\n{}\n", stderr); + } else { + // TLS dtors are not always run on process exit + thread::spawn(|| { + HANDLE.with(|h| { + println!("{}", h.0); + }); + }).join().unwrap(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24322.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24322.rs new file mode 100644 index 000000000000..ac3d0f2503f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24322.rs @@ -0,0 +1,10 @@ +struct B; + +impl B { + fn func(&self) -> u32 { 42 } +} + +fn main() { + let x: &fn(&B) -> u32 = &B::func; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24338.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24338.rs new file mode 100644 index 000000000000..182906b7dcc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24338.rs @@ -0,0 +1,22 @@ +// +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-24352.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24352.rs new file mode 100644 index 000000000000..a23d3200ab07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24352.rs @@ -0,0 +1,5 @@ +fn main() { + 1.0f64 - 1.0; + 1.0f64 - 1 // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24353.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24353.rs new file mode 100644 index 000000000000..bd2b91fc0829 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24353.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(unreachable_code)] +fn main() { + return (); + + let x = (); + x +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24357.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24357.rs new file mode 100644 index 000000000000..03a46d777893 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24357.rs @@ -0,0 +1,12 @@ +struct NoCopy; +fn main() { + let x = NoCopy; +// { dg-note "" "" { target *-*-* } .-1 } + let f = move || { let y = x; }; +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + let z = x; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-note ".E0382." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24363.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24363.rs new file mode 100644 index 000000000000..d84b7bacec64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24363.rs @@ -0,0 +1,7 @@ +fn main() { + 1.create_a_type_error[ // { dg-error ".E0610." "" { target *-*-* } } + ()+() // { dg-error ".E0369." "" { target *-*-* } } + // ^ ensure that we typeck the inner expression ^ + ]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24365.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24365.rs new file mode 100644 index 000000000000..b4e951ddd7e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24365.rs @@ -0,0 +1,20 @@ +pub enum Attribute { + Code {attr_name_idx: u16}, +} + +pub enum Foo { + Bar +} + +fn test(a: Foo) { + println!("{}", a.b); // { dg-error ".E0609." "" { target *-*-* } } +} + +fn main() { + let x = Attribute::Code { + attr_name_idx: 42, + }; + let z = (&x).attr_name_idx; // { dg-error ".E0609." "" { target *-*-* } } + let y = x.attr_name_idx; // { dg-error ".E0609." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24389.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24389.rs new file mode 100644 index 000000000000..3b10770720d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24389.rs @@ -0,0 +1,12 @@ +// check-pass +#![allow(dead_code)] + +struct Foo; + +impl Foo { + fn new() -> Self { Foo } + fn bar() { Self::new(); } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24424.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24424.rs new file mode 100644 index 000000000000..90155a0f069c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24424.rs @@ -0,0 +1,8 @@ +trait Trait1<'l0, T0> {} +trait Trait0<'l0> {} + +impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {} +// { dg-error ".E0283." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24434.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24434.rs new file mode 100644 index 000000000000..5680dc6cf468 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24434.rs @@ -0,0 +1,8 @@ +// check-pass +// compile-flags:--cfg set1 + +#![cfg_attr(set1, feature(rustc_attrs))] +#![rustc_dummy] + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2444.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2444.rs new file mode 100644 index 000000000000..ffccf3673b45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2444.rs @@ -0,0 +1,18 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +use std::sync::Arc; + +enum Err { + Errr(Arc), +} + +fn foo() -> Err { + panic!(); +} + +fn main() { + let _f = foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24446.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24446.rs new file mode 100644 index 000000000000..c9bbae306109 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24446.rs @@ -0,0 +1,7 @@ +fn main() { + static foo: dyn Fn() -> u32 = || -> u32 { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + 0 + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2445-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2445-b.rs new file mode 100644 index 000000000000..437a07a8bfe8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2445-b.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +struct c1 { + x: T, +} + +impl c1 { + pub fn f1(&self, _x: isize) { + } +} + +fn c1(x: T) -> c1 { + c1 { + x: x + } +} + +impl c1 { + pub fn f2(&self, _x: isize) { + } +} + + +pub fn main() { + c1::(3).f1(4); + c1::(3).f2(4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2445.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2445.rs new file mode 100644 index 000000000000..3e3be299e3a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2445.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +struct c1 { + x: T, +} + +impl c1 { + pub fn f1(&self, _x: T) {} +} + +fn c1(x: T) -> c1 { + c1 { + x: x + } +} + +impl c1 { + pub fn f2(&self, _x: T) {} +} + + +pub fn main() { + c1::(3).f1(4); + c1::(3).f2(4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24533.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24533.rs new file mode 100644 index 000000000000..53e12e6008ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24533.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(unused_must_use)] +use std::slice::Iter; +use std::io::{Error, ErrorKind, Result}; +use std::vec::*; + +fn foo(it: &mut Iter) -> Result { + Ok(*it.next().unwrap()) +} + +fn bar() -> Result { + let data: Vec = Vec::new(); + + if true { + return Err(Error::new(ErrorKind::NotFound, "msg")); + } + + let mut it = data.iter(); + foo(&mut it) +} + +fn main() { + bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs new file mode 100644 index 000000000000..8068a3d5a542 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs @@ -0,0 +1,56 @@ +// run-pass +// This test illustrates that under NLL, we can remove our overly +// conservative approach for disallowing mutations of match inputs. + +// See further discussion on rust-lang/rust#24535, +// rust-lang/rfcs#1006, and rust-lang/rfcs#107 + +fn main() { + rust_issue_24535(); + rfcs_issue_1006_1(); + rfcs_issue_1006_2(); +} + +fn rust_issue_24535() { + fn compare(a: &u8, b: &mut u8) -> bool { + a == b + } + + let a = 3u8; + + match a { + 0 => panic!("nope"), + 3 if compare(&a, &mut 3) => (), + _ => panic!("nope"), + } +} + +fn rfcs_issue_1006_1() { + let v = vec!["1".to_string(), "2".to_string(), "3".to_string()]; + match Some(&v) { + Some(iv) if iv.iter().any(|x| &x[..]=="2") => true, + _ => panic!("nope"), + }; +} + +fn rfcs_issue_1006_2() { + #[inline(always)] + fn check<'a, I: Iterator>(mut i: I) -> bool { + i.any(|&x| x == 2) + } + + let slice = [1, 2, 3]; + + match 42 { + _ if slice.iter().any(|&x| x == 2) => { true }, + _ => { panic!("nope"); } + }; + + // (This match is just illustrating how easy it was to circumvent + // the checking performed for the previous `match`.) + match 42 { + _ if check(slice.iter()) => { true }, + _ => { panic!("nope"); } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24589.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24589.rs new file mode 100644 index 000000000000..8495c06f6025 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24589.rs @@ -0,0 +1,18 @@ +// run-pass +pub struct _X([u8]); + +impl std::ops::Deref for _X { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + &self.0 + } +} + +pub fn _g(x: &_X) -> &[u8] { + x +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2463.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2463.rs new file mode 100644 index 000000000000..4b829bdf4aff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2463.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct Pair { f: isize, g: isize } + +pub fn main() { + + let x = Pair { + f: 0, + g: 0, + }; + + let _y = Pair { + f: 1, + g: 1, + .. x + }; + + let _z = Pair { + f: 1, + .. x + }; + +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24682.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24682.rs new file mode 100644 index 000000000000..f8770e30ff00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24682.rs @@ -0,0 +1,22 @@ +trait A: Sized { + type N; + fn x() -> + Self< + N= // { dg-error ".E0229." "" { target *-*-* } } + Self::N> { + loop {} + } + fn y(&self) -> + std + // { dg-error ".E0229." "" { target *-*-* } } + ::option::Option<()> + { None } + fn z(&self) -> + u32 // { dg-error ".E0229." "" { target *-*-* } } + { 42 } + +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs new file mode 100644 index 000000000000..2275a8da696d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-lib.rs @@ -0,0 +1,11 @@ +#![crate_type="lib"] + +// This is a file that pulls in a separate file as a submodule, where +// that separate file has many multi-byte characters, to try to +// encourage the compiler to trip on them. + +#[path = "issue-24687-mbcs-in-comments.rs"] +mod issue_24687_mbcs_in_comments; + +pub use issue_24687_mbcs_in_comments::D; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs new file mode 100644 index 000000000000..fe35d15b5c0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24687-embed-debuginfo/auxiliary/issue-24687-mbcs-in-comments.rs @@ -0,0 +1,28 @@ +use std::fmt; + +// This ia file with many multi-byte characters, to try to encourage +// the compiler to trip on them. The Drop implementation below will +// need to have its source location embedded into the debug info for +// the output file. + +// αααααααααααααααααααααααααααααααααααααααααααααααααααααααααααααααααααααα +// ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ +// γγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγγ +// δδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδ +// εεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεεε + +// ζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζζ +// ηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηηη +// θθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθθ +// ιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιιι +// κκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκκ + +pub struct D(pub X); + +impl Drop for D { + fn drop(&mut self) { + // λλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλλ + println!("Dropping D({:?})", self.0); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24687-embed-debuginfo/main.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24687-embed-debuginfo/main.rs new file mode 100644 index 000000000000..191779e18b37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24687-embed-debuginfo/main.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:issue-24687-lib.rs +// compile-flags:-g +// ignore-asmjs wasm2js does not support source maps yet + +extern crate issue_24687_lib as d; + +fn main() { + // Create a `D`, which has a destructor whose body will be codegen'ed + // into the generated code here, and thus the local debuginfo will + // need references into the original source locations from + // `importer` above. + let _d = d::D("Hi"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2470-bounds-check-overflow.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2470-bounds-check-overflow.rs new file mode 100644 index 000000000000..b346568d3f48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2470-bounds-check-overflow.rs @@ -0,0 +1,28 @@ +// run-fail +// error-pattern:index out of bounds +// ignore-emscripten no processes + +use std::mem; + +fn main() { + + // This should cause a bounds-check panic, but may not if we do our + // bounds checking by comparing the scaled index to the vector's + // address-bounds, since we've scaled the index to wrap around to the + // address of the 0th cell in the array (even though the index is + // huge). + + let x = vec![1_usize, 2_usize, 3_usize]; + + let base = x.as_ptr() as usize; + let idx = base / mem::size_of::(); + println!("ov1 base = 0x{:x}", base); + println!("ov1 idx = 0x{:x}", idx); + println!("ov1 sizeof::() = 0x{:x}", mem::size_of::()); + println!("ov1 idx * sizeof::() = 0x{:x}", + idx * mem::size_of::()); + + // This should panic. + println!("ov1 0x{:x}", x[idx]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2472.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2472.rs new file mode 100644 index 000000000000..054a02dbbc44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2472.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:issue-2472-b.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_2472_b; + +use issue_2472_b::{S, T}; + +pub fn main() { + let s = S(()); + s.foo(); + s.bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24779.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24779.rs new file mode 100644 index 000000000000..0426a76946d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24779.rs @@ -0,0 +1,5 @@ +// run-pass +fn main() { + assert_eq!((||||42)()(), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24805-dropck-itemless.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24805-dropck-itemless.rs new file mode 100644 index 000000000000..93c65ac216d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24805-dropck-itemless.rs @@ -0,0 +1,78 @@ +// run-pass + +// Check that item-less traits do not cause dropck to inject extra +// region constraints. + +#![allow(non_camel_case_types)] + +#![feature(dropck_eyepatch)] + +trait UserDefined { } + +impl UserDefined for i32 { } +impl<'a, T> UserDefined for &'a T { } + +// e.g., `impl_drop!(Send, D_Send)` expands to: +// ```rust +// struct D_Send(T); +// impl Drop for D_Send { fn drop(&mut self) { } } +// ``` +macro_rules! impl_drop { + ($Bound:ident, $Id:ident) => { + struct $Id(T); + unsafe impl <#[may_dangle] T: $Bound> Drop for $Id { + fn drop(&mut self) { } + } + } +} + +impl_drop!{Send, D_Send} +impl_drop!{Sized, D_Sized} + +// See note below regarding Issue 24895 +// impl_drop!{Copy, D_Copy} + +impl_drop!{Sync, D_Sync} +impl_drop!{UserDefined, D_UserDefined} + +macro_rules! body { + ($id:ident) => { { + // `_d` and `d1` are assigned the *same* lifetime by region inference ... + let (_d, d1); + + d1 = $id(1); + // ... we store a reference to `d1` within `_d` ... + _d = $id(&d1); + + // ... a *conservative* dropck will thus complain, because it + // thinks Drop of _d could access the already dropped `d1`. + } } +} + +fn f_send() { body!(D_Send) } +fn f_sized() { body!(D_Sized) } +fn f_sync() { body!(D_Sync) } + +// Issue 24895: Copy: Clone implies `impl Drop for ...` can +// access a user-defined clone() method, which causes this test case +// to fail. +// +// If 24895 is resolved by removing the `Copy: Clone` relationship, +// then this definition and the call below should be uncommented. If +// it is resolved by deciding to keep the `Copy: Clone` relationship, +// then this comment and the associated bits of code can all be +// removed. + +// fn f_copy() { body!(D_Copy) } + +fn f_userdefined() { body!(D_UserDefined) } + +fn main() { + f_send(); + f_sized(); + // See note above regarding Issue 24895. + // f_copy(); + f_sync(); + f_userdefined(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24819.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24819.rs new file mode 100644 index 000000000000..12648b862193 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24819.rs @@ -0,0 +1,12 @@ +use std::collections::HashSet; + +fn main() { + let mut v = Vec::new(); + foo(&mut v); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn foo(h: &mut HashSet) { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2487-a.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2487-a.rs new file mode 100644 index 000000000000..777c0d074ab3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2487-a.rs @@ -0,0 +1,33 @@ +// build-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +struct socket { + sock: isize, + +} + +impl Drop for socket { + fn drop(&mut self) {} +} + +impl socket { + pub fn set_identity(&self) { + closure(|| setsockopt_bytes(self.sock.clone())) + } +} + +fn socket() -> socket { + socket { + sock: 1 + } +} + +fn closure(f: F) where F: FnOnce() { f() } + +fn setsockopt_bytes(_sock: isize) { } + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24883.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24883.rs new file mode 100644 index 000000000000..d1e0c6151920 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24883.rs @@ -0,0 +1,18 @@ +// check-pass + +mod a { + pub mod b { pub struct Foo; } + + pub mod c { + use super::b; + pub struct Bar(pub b::Foo); + } + + pub use self::c::*; +} + +fn main() { + let _ = a::c::Bar(a::b::Foo); + let _ = a::Bar(a::b::Foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24945-repeat-dash-opts.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24945-repeat-dash-opts.rs new file mode 100644 index 000000000000..feac4cbe0982 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24945-repeat-dash-opts.rs @@ -0,0 +1,11 @@ +// run-pass +// This test is just checking that we continue to accept `-g -g -O -O` +// as options to the compiler. + +// compile-flags:-g -g -O -O +// ignore-asmjs wasm2js does not support source maps yet + +fn main() { + assert_eq!(1, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24947.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24947.rs new file mode 100644 index 000000000000..486fbe9e3849 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24947.rs @@ -0,0 +1,26 @@ +// run-pass +// #24947 ICE using a trait-associated const in an array size + + +struct Foo; + +impl Foo { + const SIZE: usize = 8; +} + +trait Bar { + const BAR_SIZE: usize; +} + +impl Bar for Foo { + const BAR_SIZE: usize = 12; +} + +#[allow(unused_variables)] +fn main() { + let w: [u8; 12] = [0u8; ::BAR_SIZE]; + let x: [u8; 12] = [0u8; ::BAR_SIZE]; + let y: [u8; 8] = [0u8; ::SIZE]; + let z: [u8; 8] = [0u8; Foo::SIZE]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-24954.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-24954.rs new file mode 100644 index 000000000000..632cc1b514f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-24954.rs @@ -0,0 +1,14 @@ +// run-pass +macro_rules! foo { + ($y:expr) => ({ + $y = 2; + }) +} + +#[allow(unused_variables)] +#[allow(unused_assignments)] +fn main() { + let mut x = 1; + foo!(x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2502.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2502.rs new file mode 100644 index 000000000000..17121d0a0ba2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2502.rs @@ -0,0 +1,25 @@ +// check-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + + +// pretty-expanded FIXME #23616 + +struct font<'a> { + fontbuf: &'a Vec , +} + +impl<'a> font<'a> { + pub fn buf(&self) -> &'a Vec { + self.fontbuf + } +} + +fn font(fontbuf: &Vec ) -> font { + font { + fontbuf: fontbuf + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25076.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25076.rs new file mode 100644 index 000000000000..e569a4369f3b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25076.rs @@ -0,0 +1,12 @@ +struct S; + +trait InOut { type Out; } + +fn do_fold>(init: B, f: F) {} + +fn bot() -> T { loop {} } + +fn main() { + do_fold(bot(), ()); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25089.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25089.rs new file mode 100644 index 000000000000..d4ed925a2cf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25089.rs @@ -0,0 +1,34 @@ +// run-pass +// ignore-emscripten no threads support + +use std::thread; + +struct Foo(i32); + +impl Drop for Foo { + fn drop(&mut self) { + static mut DROPPED: bool = false; + unsafe { + assert!(!DROPPED); + DROPPED = true; + } + } +} + +struct Empty; + +fn empty() -> Empty { Empty } + +fn should_panic(_: Foo, _: Empty) { + panic!("test panic"); +} + +fn test() { + should_panic(Foo(1), empty()); +} + +fn main() { + let ret = thread::spawn(test).join(); + assert!(ret.is_err()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25145.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25145.rs new file mode 100644 index 000000000000..ec43b1e751be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25145.rs @@ -0,0 +1,14 @@ +// run-pass + +struct S; + +impl S { + const N: usize = 3; +} + +static STUFF: [u8; S::N] = [0; S::N]; + +fn main() { + assert_eq!(STUFF, [0; 3]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25180.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25180.rs new file mode 100644 index 000000000000..94f4ee3e5711 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25180.rs @@ -0,0 +1,8 @@ +// check-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +const x: &'static dyn Fn() = &|| println!("ICE here"); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25185.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25185.rs new file mode 100644 index 000000000000..7060e555d10b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25185.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:issue-25185-1.rs +// aux-build:issue-25185-2.rs +// ignore-wasm32-bare no libc for ffi testing + +extern crate issue_25185_2; + +fn main() { + let x = unsafe { + issue_25185_2::rust_dbg_extern_identity_u32(1) + }; + assert_eq!(x, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2526-a.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2526-a.rs new file mode 100644 index 000000000000..bb930fa90825 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2526-a.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-2526.rs + +// pretty-expanded FIXME #23616 + +#![allow(unused_imports)] + +extern crate issue_2526; +use issue_2526::*; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25279.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25279.rs new file mode 100644 index 000000000000..3b3b6cdf153e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25279.rs @@ -0,0 +1,17 @@ +// run-pass +struct S<'a>(&'a ()); + +impl<'a> S<'a> { + fn foo(self) -> &'a () { + ::bar(self) + } + + fn bar(self) -> &'a () { + self.0 + } +} + +fn main() { + S(&()).foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25339.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25339.rs new file mode 100644 index 000000000000..3969d5f3b060 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25339.rs @@ -0,0 +1,32 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-25343.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25343.rs new file mode 100644 index 000000000000..c1fb5795e586 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25343.rs @@ -0,0 +1,23 @@ +// run-pass +#[allow(unused)] +fn main() { + || { + 'label: loop { + } + }; + + // More cases added from issue 31754 + + 'label2: loop { + break; + } + + let closure = || { + 'label2: loop {} + }; + + fn inner_fn() { + 'label2: loop {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25368.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25368.rs new file mode 100644 index 000000000000..9e0abf33aef7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25368.rs @@ -0,0 +1,14 @@ +use std::sync::mpsc::channel; +use std::thread::spawn; +use std::marker::PhantomData; + +struct Foo {foo: PhantomData} + +fn main() { + let (tx, rx) = channel(); + + spawn(move || { + tx.send(Foo{ foo: PhantomData }); // { dg-error ".E0282." "" { target *-*-* } } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25385.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25385.rs new file mode 100644 index 000000000000..6aa6dd48fcce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25385.rs @@ -0,0 +1,13 @@ +macro_rules! foo { + ($e:expr) => { $e.foo() } +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + +fn main() { + let a = 1i32; + foo!(a); + + foo!(1i32.foo()); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25386.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25386.rs new file mode 100644 index 000000000000..97e83558248c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25386.rs @@ -0,0 +1,29 @@ +mod stuff { + pub struct Item { + c_object: Box, + } + pub struct CObj { + name: Option, + } + impl Item { + pub fn new() -> Item { + Item { + c_object: Box::new(CObj { name: None }), + } + } + } +} + +macro_rules! check_ptr_exist { + ($var:expr, $member:ident) => ( + (*$var.c_object).$member.is_some() +// { dg-error ".E0616." "" { target *-*-* } .-1 } + ); +} + +fn main() { + let item = stuff::Item::new(); + println!("{}", check_ptr_exist!(item, name)); +// { dg-error ".E0616." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25394.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25394.rs new file mode 100644 index 000000000000..f42ff8c9b5a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25394.rs @@ -0,0 +1,7 @@ +// check-pass +#![allow(dead_code)] +#[derive(Debug)] +struct Row([T]); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25396.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25396.rs new file mode 100644 index 000000000000..31b94bf7766c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25396.rs @@ -0,0 +1,30 @@ +#![allow(non_camel_case_types)] + +use foo::baz; +use bar::baz; // { dg-error ".E0252." "" { target *-*-* } } + +use foo::Quux; +use bar::Quux; // { dg-error ".E0252." "" { target *-*-* } } + +use foo::blah; +use bar::blah; // { dg-error ".E0252." "" { target *-*-* } } + +use foo::WOMP; +use bar::WOMP; // { dg-error ".E0252." "" { target *-*-* } } + +fn main() {} + +mod foo { + pub mod baz {} + pub trait Quux { } + pub type blah = (f64, u32); + pub const WOMP: u8 = 5; +} + +mod bar { + pub mod baz {} + pub type Quux = i32; + pub struct blah { x: i8 } + pub const WOMP: i8 = -5; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25439.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25439.rs new file mode 100644 index 000000000000..5528cd83ca04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25439.rs @@ -0,0 +1,10 @@ +struct Helper<'a, F: 'a>(&'a F); + +fn fix(f: F) -> i32 where F: Fn(Helper, i32) -> i32 { + f(Helper(&f), 8) +} + +fn main() { + fix(|_, x| x); // { dg-error ".E0644." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25467.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25467.rs new file mode 100644 index 000000000000..a67972349619 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25467.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(unused_variables)] +// aux-build:issue-25467.rs + +pub type Issue25467BarT = (); +pub type Issue25467FooT = (); + +extern crate issue_25467 as aux; + +fn main() { + let o: aux::Object = None; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25497.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25497.rs new file mode 100644 index 000000000000..cd30cf6d15ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25497.rs @@ -0,0 +1,20 @@ +// run-pass +#[derive(Clone, Debug, PartialEq)] +enum Expression { + Dummy, + Add(Box), +} + +use Expression::*; + +fn simplify(exp: Expression) -> Expression { + match exp { + Add(n) => *n.clone(), + _ => Dummy + } +} + +fn main() { + assert_eq!(simplify(Add(Box::new(Dummy))), Dummy); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2550.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2550.rs new file mode 100644 index 000000000000..b41ab1602ce9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2550.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_snake_case)] + +// pretty-expanded FIXME #23616 + +struct C { + x: usize, +} + +fn C(x: usize) -> C { + C { + x: x + } +} + +fn f(_x: T) { +} + +pub fn main() { + f(C(1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25515.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25515.rs new file mode 100644 index 000000000000..6897fc7ff593 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25515.rs @@ -0,0 +1,21 @@ +// run-pass +use std::rc::Rc; + +struct Foo<'r>(&'r mut i32); + +impl<'r> Drop for Foo<'r> { + fn drop(&mut self) { + *self.0 += 1; + } +} + +fn main() { + let mut drops = 0; + + { + let _: Rc = Rc::new(Foo(&mut drops)); + } + + assert_eq!(1, drops); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25549-multiple-drop.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25549-multiple-drop.rs new file mode 100644 index 000000000000..eed50319bdac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25549-multiple-drop.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(unused_variables)] +struct Foo<'r>(&'r mut i32); + +impl<'r> Drop for Foo<'r> { + fn drop(&mut self) { + *self.0 += 1; + } +} + +trait Trait {} +impl<'r> Trait for Foo<'r> {} + +struct Holder(T); + +fn main() { + let mut drops = 0; + + { + let y = &Holder([Foo(&mut drops)]) as &Holder<[Foo]>; + // this used to cause an extra drop of the Foo instance + let x = &y.0; + } + assert_eq!(1, drops); + + drops = 0; + { + let y = &Holder(Foo(&mut drops)) as &Holder; + // this used to cause an extra drop of the Foo instance + let x = &y.0; + } + assert_eq!(1, drops); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25579.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25579.rs new file mode 100644 index 000000000000..5020432b36d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25579.rs @@ -0,0 +1,21 @@ +// check-pass + +enum Sexpression { + Num(()), + Cons(&'static mut Sexpression) +} + +fn causes_error_in_ast(mut l: &mut Sexpression) { + loop { match l { + &mut Sexpression::Num(ref mut n) => {}, + &mut Sexpression::Cons(ref mut expr) => { + l = &mut **expr; + } + }} +} + + +fn main() { + causes_error_in_ast(&mut Sexpression::Num(())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25679.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25679.rs new file mode 100644 index 000000000000..4aa38461a275 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25679.rs @@ -0,0 +1,20 @@ +// run-pass +trait Device { + type Resources; +} +struct Foo(D, R); + +impl 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/gcc/testsuite/rust/rustc/ui/issues/issue-25693.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25693.rs new file mode 100644 index 000000000000..cbd2318703c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25693.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(unused_variables)] +pub trait Parameters { type SelfRef; } + +struct RP<'a> { _marker: std::marker::PhantomData<&'a ()> } +struct BP; + +impl<'a> Parameters for RP<'a> { type SelfRef = &'a X>; } +impl Parameters for BP { type SelfRef = Box>; } + +pub struct Y; +pub enum X { + Nothing, + SameAgain(P::SelfRef, Y) +} + +fn main() { + let bnil: Box> = Box::new(X::Nothing); + let bx: Box> = Box::new(X::SameAgain(bnil, Y)); + let rnil: X = X::Nothing; + let rx: X = X::SameAgain(&rnil, Y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25700-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25700-1.rs new file mode 100644 index 000000000000..69dde2b73cc0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25700-1.rs @@ -0,0 +1,14 @@ +// run-pass +struct S(Option<&'static T>); + +trait Tr { type Out; } +impl Tr for T { type Out = T; } + +impl Copy for S where S: Tr {} +impl Clone for S where S: Tr { + fn clone(&self) -> Self { *self } +} +fn main() { + S::<()>(None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25700-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25700-2.rs new file mode 100644 index 000000000000..2b25549367d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25700-2.rs @@ -0,0 +1,23 @@ +// run-pass +pub trait Parser { + type Input; +} + +pub struct Iter(P, P::Input); + +pub struct Map(P, F); +impl Parser for Map where F: FnMut(P) { + type Input = u8; +} + +trait AstId { type Untyped; } +impl AstId for u32 { type Untyped = u32; } + +fn record_type(i: Id::Untyped) -> u8 { + Iter(Map(i, |_: Id::Untyped| {}), 42).1 +} + +pub fn main() { + assert_eq!(record_type::(3), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25700.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25700.rs new file mode 100644 index 000000000000..3789f2abbf77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25700.rs @@ -0,0 +1,15 @@ +struct S(Option<&'static T>); + +trait Tr { type Out; } +impl Tr for T { type Out = T; } + +impl Copy for S where S: Tr {} +impl Clone for S where S: Tr { + fn clone(&self) -> Self { *self } +} +fn main() { + let t = S::<()>(None); + drop(t); + drop(t); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25746-bool-transmute.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25746-bool-transmute.rs new file mode 100644 index 000000000000..2913b2c5284b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25746-bool-transmute.rs @@ -0,0 +1,12 @@ +// run-pass +use std::mem::transmute; + +fn main() { + unsafe { + let _: i8 = transmute(false); + let _: i8 = transmute(true); + let _: bool = transmute(0u8); + let _: bool = transmute(1u8); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25757.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25757.rs new file mode 100644 index 000000000000..6fe87538227e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25757.rs @@ -0,0 +1,19 @@ +// run-pass +struct Foo { + a: u32 +} + +impl Foo { + fn x(&mut self) { + self.a = 5; + } +} + +const FUNC: &'static dyn Fn(&mut Foo) -> () = &Foo::x; + +fn main() { + let mut foo = Foo { a: 137 }; + FUNC(&mut foo); + assert_eq!(foo.a, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25793.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25793.rs new file mode 100644 index 000000000000..f4de43bc5c57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25793.rs @@ -0,0 +1,27 @@ +#![feature(rustc_attrs)] +macro_rules! width( + ($this:expr) => { + $this.width.unwrap() +// { dg-error ".E0503." "" { target *-*-* } .-1 } + } +); + +struct HasInfo { + width: Option +} + +impl HasInfo { + fn get_size(&mut self, n: usize) -> usize { + n + } + + fn get_other(&mut self) -> usize { + let r = &mut *self; + r.get_size(width!(self)) + } + // Above is like `self.get_size(width!(self))`, but it + // deliberately avoids NLL's two phase borrow feature. +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25810.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25810.rs new file mode 100644 index 000000000000..3efe1c4bac2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25810.rs @@ -0,0 +1,29 @@ +// run-pass +fn main() { + let x = X(15); + let y = x.foo(); + println!("{:?}",y); +} + +trait Foo + where for<'a> &'a Self: Bar +{ + fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output; +} + +trait Bar { + type Output; +} + +struct X(i32); + +impl<'a> Bar for &'a X { + type Output = &'a i32; +} + +impl Foo for X { + fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output { + &self.0 + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25826.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25826.rs new file mode 100644 index 000000000000..5454ed650c9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25826.rs @@ -0,0 +1,7 @@ +fn id(t: T) -> T { t } +fn main() { + const A: bool = unsafe { id:: as *const () < id:: as *const () }; +// { dg-error "" "" { target *-*-* } .-1 } + println!("{}", A); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2590.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2590.rs new file mode 100644 index 000000000000..64da93999d04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2590.rs @@ -0,0 +1,16 @@ +struct Parser { + tokens: Vec , +} + +trait Parse { + fn parse(&self) -> Vec ; +} + +impl Parse for Parser { + fn parse(&self) -> Vec { + self.tokens // { dg-error ".E0507." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25901.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25901.rs new file mode 100644 index 000000000000..b4bd26091982 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25901.rs @@ -0,0 +1,15 @@ +struct A; +struct B; + +static S: &'static B = &A; +// { dg-error ".E0015." "" { target *-*-* } .-1 } + +use std::ops::Deref; + +impl Deref for A { + type Target = B; + fn deref(&self)->&B { static B_: B = B; &B_ } +} + +fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-25916.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-25916.rs new file mode 100644 index 000000000000..4e31ddeaaf45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-25916.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(unused_must_use)] + +fn main() { + macro_rules! f { + () => { 0 + 0 } + } + // 16 per line + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); + f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!();f!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26056.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26056.rs new file mode 100644 index 000000000000..957a37e2222f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26056.rs @@ -0,0 +1,23 @@ +trait MapLookup { + type MapValue; +} + +impl MapLookup for K { + type MapValue = K; +} + +trait Map: MapLookup<::Key> { + type Key; +} + +impl Map for K { + type Key = K; +} + + +fn main() { + let _ = &() + as &dyn Map; +// { dg-error ".E0038." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26093.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26093.rs new file mode 100644 index 000000000000..276e4e84e571 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26093.rs @@ -0,0 +1,13 @@ +macro_rules! not_a_place { + ($thing:expr) => { + $thing = 42; +// { dg-error ".E0067." "" { target *-*-* } .-1 } + $thing += 42; +// { dg-error ".E0067." "" { target *-*-* } .-1 } + } +} + +fn main() { + not_a_place!(99); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26094.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26094.rs new file mode 100644 index 000000000000..c58a293988dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26094.rs @@ -0,0 +1,14 @@ +macro_rules! some_macro { + ($other: expr) => ({ + $other(None) // { dg-note "" "" { target *-*-* } } + }) +} + +fn some_function() {} // { dg-note "" "" { target *-*-* } } + +fn main() { + some_macro!(some_function); +// { dg-error ".E0061." "" { target *-*-* } .-1 } +// { dg-note ".E0061." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26095.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26095.rs new file mode 100644 index 000000000000..8df68d5de773 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26095.rs @@ -0,0 +1,24 @@ +// check-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + + +trait HasNumber { + const Number: usize; +} + +enum One {} +enum Two {} + +enum Foo {} + +impl HasNumber for One { + const Number: usize = 1; +} + +impl HasNumber for Two { + const Number: usize = 2; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2611-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2611-3.rs new file mode 100644 index 000000000000..ba44aabda2df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2611-3.rs @@ -0,0 +1,20 @@ +// check-pass +#![allow(dead_code)] +// Tests that impls are allowed to have looser, more permissive bounds +// than the traits require. + + +trait A { + fn b(&self, x: C) -> C; +} + +struct E { + f: isize +} + +impl A for E { + fn b(&self, _x: F) -> F { panic!() } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26127.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26127.rs new file mode 100644 index 000000000000..44f8185e4f8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26127.rs @@ -0,0 +1,13 @@ +// run-pass +trait Tr { type T; } +impl Tr for u8 { type T=(); } +struct S(I::T); + +fn foo(i: I::T) { + S::(i); +} + +fn main() { + foo::(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26205.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26205.rs new file mode 100644 index 000000000000..771e4240234c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26205.rs @@ -0,0 +1,32 @@ +// check-pass +#![allow(dead_code)] +use std::ops::{Deref, DerefMut}; + +struct Foo; + +impl Foo { + fn foo_mut(&mut self) {} +} + +struct Bar(Foo); + +impl Deref for Bar { + type Target = Foo; + + fn deref(&self) -> &Foo { + &self.0 + } +} + +impl DerefMut for Bar { + fn deref_mut(&mut self) -> &mut Foo { + &mut self.0 + } +} + +fn test(mut bar: Box) { + bar.foo_mut(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26217.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26217.rs new file mode 100644 index 000000000000..2a0562d8b1ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26217.rs @@ -0,0 +1,11 @@ +fn foo() where for<'a> T: 'a {} + +fn bar<'a>() { + foo::<&'a i32>(); +// { dg-error ".E0477." "" { target *-*-* } .-1 } +} + +fn main() { + bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26237.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26237.rs new file mode 100644 index 000000000000..8fd63e46e2e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26237.rs @@ -0,0 +1,13 @@ +macro_rules! macro_panic { + ($not_a_function:expr, $some_argument:ident) => { + $not_a_function($some_argument) + } +} + +fn main() { + let mut value_a = 0; + let mut value_b = 0; + macro_panic!(value_a, value_b); +// { dg-error ".E0618." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26251.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26251.rs new file mode 100644 index 000000000000..b8e2ba417092 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26251.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(overlapping_patterns)] + +fn main() { + let x = 'a'; + + let y = match x { + 'a'..='b' if false => "one", + 'a' => "two", + 'a'..='b' => "three", + _ => panic!("what?"), + }; + + assert_eq!(y, "two"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26262.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26262.rs new file mode 100644 index 000000000000..e5a621bb47ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26262.rs @@ -0,0 +1,23 @@ +// Check that projections don't count as constraining type parameters. + +struct S(T); + +trait Tr { type Assoc; fn test(); } + +impl S { +// { dg-error ".E0207." "" { target *-*-* } .-1 } + fn foo(self, _: T) { + T::test(); + } +} + +trait Trait1 { type Bar; } +trait Trait2<'x> { type Foo; } + +impl<'a,T: Trait2<'a>> Trait1<>::Foo> for T { +// { dg-error ".E0207." "" { target *-*-* } .-1 } + type Bar = &'a (); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2631-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2631-b.rs new file mode 100644 index 000000000000..288e36ebaddb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2631-b.rs @@ -0,0 +1,18 @@ +// run-pass + +// aux-build:issue-2631-a.rs + +extern crate req; + +use req::request; +use std::cell::RefCell; +use std::collections::HashMap; +use std::rc::Rc; + +pub fn main() { + let v = vec![Rc::new("hi".to_string())]; + let mut m: req::header_map = HashMap::new(); + m.insert("METHOD".to_string(), Rc::new(RefCell::new(v))); + request::(&m); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26322.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26322.rs new file mode 100644 index 000000000000..2650136a34d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26322.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +macro_rules! columnline { + () => ( + (column!(), line!()) + ) +} + +macro_rules! indirectcolumnline { + () => ( + (||{ columnline!() })() + ) +} + +fn main() { + let closure = || { + columnline!() + }; + let iflet = if let Some(_) = Some(0) { + columnline!() + } else { (0, 0) }; + let cl = columnline!(); + assert_eq!(closure(), (9, 19)); + assert_eq!(iflet, (9, 22)); + assert_eq!(cl, (14, 24)); + let indirect = indirectcolumnline!(); + assert_eq!(indirect, (20, 28)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2633-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2633-2.rs new file mode 100644 index 000000000000..b372f4412f97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2633-2.rs @@ -0,0 +1,15 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + + +fn a_val(x: Box, y: Box) -> isize { + *x + *y +} + +pub fn main() { + let z: Box<_> = box 22; + a_val(z.clone(), z.clone()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2633.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2633.rs new file mode 100644 index 000000000000..7e7b63621cb8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2633.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +#[derive(Copy, Clone)] +struct cat { + meow: extern "Rust" fn(), +} + +fn meow() { + println!("meow") +} + +fn cat() -> cat { + cat { + meow: meow, + } +} + +#[derive(Copy, Clone)] +struct KittyInfo {kitty: cat} + +// Code compiles and runs successfully if we add a + before the first arg +fn nyan(kitty: cat, _kitty_info: KittyInfo) { + (kitty.meow)(); +} + +pub fn main() { + let kitty = cat(); + nyan(kitty, KittyInfo {kitty: kitty}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2642.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2642.rs new file mode 100644 index 000000000000..8df4ba6dbf5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2642.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn f() { + let _x: usize = loop { loop { break; } }; +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26448-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26448-1.rs new file mode 100644 index 000000000000..88df6b1535c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26448-1.rs @@ -0,0 +1,14 @@ +// run-pass + +pub trait Foo { + fn foo(self) -> T; +} + +impl<'a, T> Foo for &'a str where &'a str: Into { + fn foo(self) -> T { + panic!(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26448-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26448-2.rs new file mode 100644 index 000000000000..95affcc33f13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26448-2.rs @@ -0,0 +1,22 @@ +// check-pass + +pub struct Bar { + items: Vec<&'static str>, + inner: T, +} + +pub trait IntoBar { + fn into_bar(self) -> Bar; +} + +impl<'a, T> IntoBar for &'a str where &'a str: Into { + fn into_bar(self) -> Bar { + Bar { + items: Vec::new(), + inner: self.into(), + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26448-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26448-3.rs new file mode 100644 index 000000000000..59679420a159 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26448-3.rs @@ -0,0 +1,26 @@ +// check-pass + +pub struct Item { + _inner: &'static str, +} + +pub struct Bar { + items: Vec, + inner: T, +} + +pub trait IntoBar { + fn into_bar(self) -> Bar; +} + +impl<'a, T> IntoBar for &'a str where &'a str: Into { + fn into_bar(self) -> Bar { + Bar { + items: Vec::new(), + inner: self.into(), + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26459.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26459.rs new file mode 100644 index 000000000000..6dddda9deb98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26459.rs @@ -0,0 +1,9 @@ +// compile-flags: -Zsave-analysis + +fn main() { + match 'a' { + char{ch} => true +// { dg-error ".E0574." "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26468.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26468.rs new file mode 100644 index 000000000000..58b2727a6d5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26468.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(dead_code)] + +enum FooMode { + Check = 0x1001, +} + +enum BarMode { + Check = 0x2001, +} + +enum Mode { + Foo(FooMode), + Bar(BarMode), +} + +#[inline(never)] +fn broken(mode: &Mode) -> u32 { + for _ in 0..1 { + if let Mode::Foo(FooMode::Check) = *mode { return 17 } + if let Mode::Bar(BarMode::Check) = *mode { return 19 } + } + return 42; +} + +fn main() { + let mode = Mode::Bar(BarMode::Check); + assert_eq!(broken(&mode), 19); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26472.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26472.rs new file mode 100644 index 000000000000..17e22e26c35f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26472.rs @@ -0,0 +1,14 @@ +mod sub { + pub struct S { len: usize } + impl S { + pub fn new() -> S { S { len: 0 } } + pub fn len(&self) -> usize { self.len } + } +} + +fn main() { + let s = sub::S::new(); + let v = s.len; // { dg-error ".E0616." "" { target *-*-* } } + s.len = v; // { dg-error ".E0616." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26484.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26484.rs new file mode 100644 index 000000000000..7f7b85d6df54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26484.rs @@ -0,0 +1,13 @@ +// run-pass +// compile-flags:-g +// ignore-asmjs wasm2js does not support source maps yet + +fn helper bool>(_f: F) { + print!(""); +} + +fn main() { + let cond = 0; + helper(|v| v == cond) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26545.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26545.rs new file mode 100644 index 000000000000..b58dcddc85dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26545.rs @@ -0,0 +1,13 @@ +mod foo { + pub struct B(pub ()); +} + +mod baz { + fn foo() { + B(()); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26614.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26614.rs new file mode 100644 index 000000000000..9e9009950a31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26614.rs @@ -0,0 +1,15 @@ +// check-pass + +trait Mirror { + type It; +} + +impl Mirror for T { + type It = Self; +} + +fn main() { + let c: ::It = 5; + const CCCC: ::It = 5; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26619.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26619.rs new file mode 100644 index 000000000000..dbfe7d23f074 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26619.rs @@ -0,0 +1,23 @@ +pub struct History<'a> { pub _s: &'a str } + +impl<'a> History<'a> { + pub fn get_page(&self) { + for s in vec!["1|2".to_string()].into_iter().filter_map(|ref line| self.make_entry(line)) { +// { dg-error ".E0515." "" { target *-*-* } .-1 } + println!("{:?}", s); + } + } + + fn make_entry(&self, s: &'a String) -> Option<&str> { + let parts: Vec<_> = s.split('|').collect(); + println!("{:?} -> {:?}", s, parts); + + if let [commit, ..] = &parts[..] { Some(commit) } else { None } + } +} + +fn main() { + let h = History{ _s: "" }; + h.get_page(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26638.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26638.rs new file mode 100644 index 000000000000..0db6ed0f373e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26638.rs @@ -0,0 +1,11 @@ +fn parse_type(iter: Box+'static>) -> &str { iter.next() } +// { dg-error ".E0106." "" { target *-*-* } .-1 } + +fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } +// { dg-error ".E0106." "" { target *-*-* } .-1 } + +fn parse_type_3() -> &str { unimplemented!() } +// { dg-error ".E0106." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26641.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26641.rs new file mode 100644 index 000000000000..090b61637947 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26641.rs @@ -0,0 +1,7 @@ +// run-pass +struct Parser<'a>(Box); + +fn main() { + let _x = Parser(Box::new(|_|{})); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26646.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26646.rs new file mode 100644 index 000000000000..0d588d9e981d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26646.rs @@ -0,0 +1,13 @@ +// check-pass +#![deny(unused_attributes)] + +#[repr(C)] +#[repr(packed)] +pub struct Foo; + +#[repr(packed)] +#[repr(C)] +pub struct Bar; + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26655.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26655.rs new file mode 100644 index 000000000000..785cdc1cd190 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26655.rs @@ -0,0 +1,26 @@ +// run-pass +// ignore-emscripten no threads support + +// Check that the destructors of simple enums are run on unwinding + +use std::sync::atomic::{Ordering, AtomicUsize}; +use std::thread; + +static LOG: AtomicUsize = AtomicUsize::new(0); + +enum WithDtor { Val } +impl Drop for WithDtor { + fn drop(&mut self) { + LOG.store(LOG.load(Ordering::SeqCst)+1,Ordering::SeqCst); + } +} + +pub fn main() { + thread::spawn(move|| { + let _e: WithDtor = WithDtor::Val; + panic!("fail"); + }).join().unwrap_err(); + + assert_eq!(LOG.load(Ordering::SeqCst), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26709.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26709.rs new file mode 100644 index 000000000000..f1de02a6957f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26709.rs @@ -0,0 +1,18 @@ +// run-pass +struct Wrapper<'a, T: ?Sized>(&'a mut i32, T); + +impl<'a, T: ?Sized> Drop for Wrapper<'a, T> { + fn drop(&mut self) { + *self.0 = 432; + } +} + +fn main() { + let mut x = 0; + { + let wrapper = Box::new(Wrapper(&mut x, 123)); + let _: Box> = wrapper; + } + assert_eq!(432, x) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26802.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26802.rs new file mode 100644 index 000000000000..82910624b1e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26802.rs @@ -0,0 +1,15 @@ +// run-pass +trait Foo<'a> { + fn bar<'b>(&self, x: &'b u8) -> u8 where 'a: 'b { *x+7 } +} + +pub struct FooBar; +impl Foo<'static> for FooBar {} +fn test(foobar: FooBar) -> Box> { + Box::new(foobar) +} + +fn main() { + assert_eq!(test(FooBar).bar(&4), 11); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26805.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26805.rs new file mode 100644 index 000000000000..a3ca3c9604be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26805.rs @@ -0,0 +1,7 @@ +// run-pass +struct NonOrd; + +fn main() { + let _: Box> = Box::new(vec![NonOrd].into_iter()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26812.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26812.rs new file mode 100644 index 000000000000..a11598492a07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26812.rs @@ -0,0 +1,7 @@ +#![feature(default_type_parameter_fallback)] + +fn avg(_: T) {} +// { dg-error ".E0128." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile.rs new file mode 100644 index 000000000000..e949e2bd2814 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_imports)] +#![allow(non_snake_case)] + +// ignore-pretty issue #37195 + +#[path = "issue-26873-multifile/mod.rs"] +mod multifile; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/A/B.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/A/B.rs new file mode 100644 index 000000000000..d1b802ff3cd4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/A/B.rs @@ -0,0 +1,5 @@ +// run-pass +use super::*; + +pub struct S; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/A/C.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/A/C.rs new file mode 100644 index 000000000000..88f3eb04afbd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/A/C.rs @@ -0,0 +1,7 @@ +// run-pass +use super::*; + +use super::B::S; + +pub struct T { i: i32 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/A/mod.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/A/mod.rs new file mode 100644 index 000000000000..20f40a06782a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/A/mod.rs @@ -0,0 +1,6 @@ +// run-pass +pub mod B; +pub mod C; + +pub use self::C::T; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/mod.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/mod.rs new file mode 100644 index 000000000000..52deea79a20c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26873-multifile/mod.rs @@ -0,0 +1,5 @@ +// run-pass +mod A; + +use self::A::*; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26873-onefile.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26873-onefile.rs new file mode 100644 index 000000000000..4cfffb08e8f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26873-onefile.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_imports)] +#![allow(non_snake_case)] + +mod A { + pub mod B { + use super::*; + + pub struct S; + } + + pub mod C { + use super::*; + use super::B::S; + + pub struct T; + } + + pub use self::C::T; +} + +use A::*; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26886.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26886.rs new file mode 100644 index 000000000000..9ceb5818737e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26886.rs @@ -0,0 +1,9 @@ +use std::sync::{self, Arc}; +use std::sync::Arc; // { dg-error ".E0252." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +use std::sync; // { dg-error ".E0252." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26905-rpass.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26905-rpass.rs new file mode 100644 index 000000000000..33decec4a86e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26905-rpass.rs @@ -0,0 +1,22 @@ +// run-pass +#![feature(unsize, coerce_unsized)] + +// Verfies that PhantomData is ignored for DST coercions + +use std::marker::{Unsize, PhantomData}; +use std::ops::CoerceUnsized; + +struct MyRc { + _ptr: *const T, + _boo: PhantomData, +} + +impl, U: ?Sized> CoerceUnsized> for MyRc{ } + +fn main() { + let data = [1, 2, 3]; + let iter = data.iter(); + let x = MyRc { _ptr: &iter, _boo: PhantomData }; + let _y: MyRc> = x; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26905.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26905.rs new file mode 100644 index 000000000000..ca9f2e917d4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26905.rs @@ -0,0 +1,24 @@ +#![feature(unsize, coerce_unsized)] + +// Verfies that non-PhantomData ZSTs still cause coercions to fail. +// They might have additional semantics that we don't want to bulldoze. + +use std::marker::{Unsize, PhantomData}; +use std::ops::CoerceUnsized; + +struct NotPhantomData(PhantomData); + +struct MyRc { + _ptr: *const T, + _boo: NotPhantomData, +} + +impl, U: ?Sized> CoerceUnsized> for MyRc{ } // { dg-error ".E0375." "" { target *-*-* } } + +fn main() { + let data = [1, 2, 3]; + let iter = data.iter(); + let x = MyRc { _ptr: &iter, _boo: NotPhantomData(PhantomData) }; + let _y: MyRc> = x; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26930.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26930.rs new file mode 100644 index 000000000000..215c723c9632 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26930.rs @@ -0,0 +1,9 @@ +// check-pass + +extern crate core; +use core as core_export; +use self::x::*; +mod x {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26948.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26948.rs new file mode 100644 index 000000000000..19b08f0d4658 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26948.rs @@ -0,0 +1,7 @@ +fn main() { + enum Foo { A { x: u32 } } + let orig = Foo::A { x: 5 }; + Foo::A { x: 6, ..orig }; +// { dg-error ".E0436." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26996.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26996.rs new file mode 100644 index 000000000000..fb129c5b3809 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26996.rs @@ -0,0 +1,25 @@ +// run-pass + +// This test is bogus (i.e., should be compile-fail) during the period +// where #54986 is implemented and #54987 is *not* implemented. For +// now: just ignore it +// +// ignore-test + +// This test is checking that the write to `c.0` (which has been moved out of) +// won't overwrite the state in `c2`. +// +// That's a fine thing to test when this code is accepted by the +// compiler, and this code is being transcribed accordingly into +// the ui test issue-21232-partial-init-and-use.rs + +fn main() { + let mut c = (1, "".to_owned()); + match c { + c2 => { + c.0 = 2; + assert_eq!(c2.0, 1); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-26997.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-26997.rs new file mode 100644 index 000000000000..206d226b21f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-26997.rs @@ -0,0 +1,16 @@ +// build-pass +#![allow(dead_code)] +pub struct Foo { + x: isize, + y: isize +} + +impl Foo { + #[allow(improper_ctypes_definitions)] + pub extern fn foo_new() -> Foo { + Foo { x: 21, y: 33 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27008.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27008.rs new file mode 100644 index 000000000000..861d25142838 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27008.rs @@ -0,0 +1,8 @@ +struct S; + +fn main() { + let b = [0; S]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27021.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27021.rs new file mode 100644 index 000000000000..7efe6ae9d3d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27021.rs @@ -0,0 +1,29 @@ +// run-pass + +// This test is bogus (i.e., should be compile-fail) during the period +// where #54986 is implemented and #54987 is *not* implemented. For +// now: just ignore it +// +// ignore-test + +// These are variants of issue-26996.rs. In all cases we are writing +// into a record field that has been moved out of, and ensuring that +// such a write won't overwrite the state of the thing it was moved +// into. +// +// That's a fine thing to test when this code is accepted by the +// compiler, and this code is being transcribed accordingly into +// the ui test issue-21232-partial-init-and-use.rs + +fn main() { + let mut c = (1, (1, "".to_owned())); + match c { + c2 => { (c.1).0 = 2; assert_eq!((c2.1).0, 1); } + } + + let mut c = (1, (1, (1, "".to_owned()))); + match c.1 { + c2 => { ((c.1).1).0 = 3; assert_eq!((c2.1).0, 1); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27033.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27033.rs new file mode 100644 index 000000000000..e3c6931a4ff6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27033.rs @@ -0,0 +1,13 @@ +fn main() { + match Some(1) { + None @ _ => {} // { dg-error ".E0530." "" { target *-*-* } } + }; + const C: u8 = 1; + match 1 { + C @ 2 => { // { dg-error ".E0530." "" { target *-*-* } } + println!("{}", C); + } + _ => {} + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27042.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27042.rs new file mode 100644 index 000000000000..2a2415b5cbfe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27042.rs @@ -0,0 +1,18 @@ +// Regression test for #27042. Test that a loop's label is included in its span. + +fn main() { + let _: i32 = + 'a: // in this case, the citation is just the `break`: + loop { break }; // { dg-error ".E0308." "" { target *-*-* } } + let _: i32 = + 'b: // { dg-error ".E0308." "" { target *-*-* } } +// { dg-warning ".E0308." "" { target *-*-* } .-1 } + while true { break }; // but here we cite the whole loop + let _: i32 = + 'c: // { dg-error ".E0308." "" { target *-*-* } } + for _ in None { break }; // but here we cite the whole loop + let _: i32 = + 'd: // { dg-error ".E0308." "" { target *-*-* } } + while let Some(_) = None { break }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27054-primitive-binary-ops.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27054-primitive-binary-ops.rs new file mode 100644 index 000000000000..e14ce45d25e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27054-primitive-binary-ops.rs @@ -0,0 +1,6 @@ +// run-pass +fn main() { + let x = &mut 1; + assert_eq!(*x + { *x=2; 1 }, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27060-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27060-2.rs new file mode 100644 index 000000000000..be3228cca4f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27060-2.rs @@ -0,0 +1,7 @@ +#[repr(packed)] +pub struct Bad { + data: T, // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27060-rpass.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27060-rpass.rs new file mode 100644 index 000000000000..5ddaf4569b23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27060-rpass.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +#[repr(packed)] +pub struct Good { + data: &'static u32, + data2: [&'static u32; 2], + aligned: [u8; 32], +} + +// kill this test when that turns to a hard error +#[allow(safe_packed_borrows)] +fn main() { + let good = Good { data: &0, data2: [&0, &0], aligned: [0; 32] }; + + unsafe { + let _ = &good.data; // ok + let _ = &good.data2[0]; // ok + } + + let _ = &good.data; + let _ = &good.data2[0]; + let _ = &*good.data; // ok, behind a pointer + let _ = &good.aligned; // ok, has align 1 + let _ = &good.aligned[2]; // ok, has align 1 +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27060.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27060.rs new file mode 100644 index 000000000000..218d7dfdd09e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27060.rs @@ -0,0 +1,29 @@ +#[repr(packed)] +pub struct Good { + data: &'static u32, + data2: [&'static u32; 2], + aligned: [u8; 32], +} + +#[deny(safe_packed_borrows)] +fn main() { + let good = Good { + data: &0, + data2: [&0, &0], + aligned: [0; 32] + }; + + unsafe { + let _ = &good.data; // ok + let _ = &good.data2[0]; // ok + } + + let _ = &good.data; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + let _ = &good.data2[0]; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + let _ = &*good.data; // ok, behind a pointer + let _ = &good.aligned; // ok, has align 1 + let _ = &good.aligned[2]; // ok, has align 1 +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27078.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27078.rs new file mode 100644 index 000000000000..dbe3d82b7576 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27078.rs @@ -0,0 +1,12 @@ +#![feature(associated_consts)] + +trait Foo { + const BAR: i32; + fn foo(self) -> &'static i32 { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + &::BAR + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2708.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2708.rs new file mode 100644 index 000000000000..3fcb52e4fbc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2708.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_snake_case)] + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +struct Font { + fontbuf: usize, + cairo_font: usize, + font_dtor: usize, + +} + +impl Drop for Font { + fn drop(&mut self) {} +} + +fn Font() -> Font { + Font { + fontbuf: 0, + cairo_font: 0, + font_dtor: 0 + } +} + +pub fn main() { + let _f: Box<_> = box Font(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27105.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27105.rs new file mode 100644 index 000000000000..d2fd77efa95f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27105.rs @@ -0,0 +1,16 @@ +// check-pass +use std::cell::RefCell; +use std::rc::Rc; + +pub struct Callbacks { + callbacks: Vec>>, +} + +impl Callbacks { + pub fn register(&mut self, callback: F) { + self.callbacks.push(Rc::new(RefCell::new(callback))); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2718-a.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2718-a.rs new file mode 100644 index 000000000000..dd8b53936cb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2718-a.rs @@ -0,0 +1,13 @@ +pub struct SendPacket { + p: T +} + +mod pingpong { + use SendPacket; + pub type Ping = SendPacket; + pub struct Pong(SendPacket); +// { dg-error ".E0072." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2718.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2718.rs new file mode 100644 index 000000000000..d6e7f08efcca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2718.rs @@ -0,0 +1,328 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_unsafe)] +#![allow(unused_imports)] +#![allow(non_camel_case_types)] + +pub type Task = isize; + +// tjc: I don't know why +pub mod pipes { + use self::state::{empty, full, blocked, terminated}; + use super::Task; + use std::mem::{forget, transmute}; + use std::mem::{replace, swap}; + use std::mem; + use std::thread; + use std::marker::Send; + + pub struct Stuff { + state: state, + blocked_task: Option, + payload: Option + } + + #[derive(PartialEq, Debug)] + #[repr(isize)] + pub enum state { + empty, + full, + blocked, + terminated + } + + pub struct packet { + state: state, + blocked_task: Option, + payload: Option + } + + unsafe impl Send for packet {} + + pub fn packet() -> *const packet { + unsafe { + let p: *const packet = mem::transmute(Box::new(Stuff{ + state: empty, + blocked_task: None::, + payload: None:: + })); + p + } + } + + mod rusti { + pub fn atomic_xchg(_dst: &mut isize, _src: isize) -> isize { panic!(); } + pub fn atomic_xchg_acq(_dst: &mut isize, _src: isize) -> isize { panic!(); } + pub fn atomic_xchg_rel(_dst: &mut isize, _src: isize) -> isize { panic!(); } + } + + // We should consider moving this to ::std::unsafe, although I + // suspect graydon would want us to use void pointers instead. + pub unsafe fn uniquify(x: *const T) -> Box { + mem::transmute(x) + } + + pub fn swap_state_acq(dst: &mut state, src: state) -> state { + unsafe { + transmute(rusti::atomic_xchg_acq(transmute(dst), src as isize)) + } + } + + pub fn swap_state_rel(dst: &mut state, src: state) -> state { + unsafe { + transmute(rusti::atomic_xchg_rel(transmute(dst), src as isize)) + } + } + + pub fn send(mut p: send_packet, payload: T) { + let p = p.unwrap(); + let mut p = unsafe { uniquify(p) }; + assert!((*p).payload.is_none()); + (*p).payload = Some(payload); + let old_state = swap_state_rel(&mut (*p).state, full); + match old_state { + empty => { + // Yay, fastpath. + + // The receiver will eventually clean this up. + unsafe { forget(p); } + } + full => { panic!("duplicate send") } + blocked => { + + // The receiver will eventually clean this up. + unsafe { forget(p); } + } + terminated => { + // The receiver will never receive this. Rely on drop_glue + // to clean everything up. + } + } + } + + pub fn recv(mut p: recv_packet) -> Option { + let p = p.unwrap(); + let mut p = unsafe { uniquify(p) }; + loop { + let old_state = swap_state_acq(&mut (*p).state, + blocked); + match old_state { + empty | blocked => { thread::yield_now(); } + full => { + let payload = replace(&mut p.payload, None); + return Some(payload.unwrap()) + } + terminated => { + assert_eq!(old_state, terminated); + return None; + } + } + } + } + + pub fn sender_terminate(p: *const packet) { + let mut p = unsafe { uniquify(p) }; + match swap_state_rel(&mut (*p).state, terminated) { + empty | blocked => { + // The receiver will eventually clean up. + unsafe { forget(p) } + } + full => { + // This is impossible + panic!("you dun goofed") + } + terminated => { + // I have to clean up, use drop_glue + } + } + } + + pub fn receiver_terminate(p: *const packet) { + let mut p = unsafe { uniquify(p) }; + match swap_state_rel(&mut (*p).state, terminated) { + empty => { + // the sender will clean up + unsafe { forget(p) } + } + blocked => { + // this shouldn't happen. + panic!("terminating a blocked packet") + } + terminated | full => { + // I have to clean up, use drop_glue + } + } + } + + pub struct send_packet { + p: Option<*const packet>, + } + + impl Drop for send_packet { + fn drop(&mut self) { + unsafe { + if self.p != None { + let self_p: &mut Option<*const packet> = + mem::transmute(&mut self.p); + let p = replace(self_p, None); + sender_terminate(p.unwrap()) + } + } + } + } + + impl send_packet { + pub fn unwrap(&mut self) -> *const packet { + replace(&mut self.p, None).unwrap() + } + } + + pub fn send_packet(p: *const packet) -> send_packet { + send_packet { + p: Some(p) + } + } + + pub struct recv_packet { + p: Option<*const packet>, + } + + impl Drop for recv_packet { + fn drop(&mut self) { + unsafe { + if self.p != None { + let self_p: &mut Option<*const packet> = + mem::transmute(&mut self.p); + let p = replace(self_p, None); + receiver_terminate(p.unwrap()) + } + } + } + } + + impl recv_packet { + pub fn unwrap(&mut self) -> *const packet { + replace(&mut self.p, None).unwrap() + } + } + + pub fn recv_packet(p: *const packet) -> recv_packet { + recv_packet { + p: Some(p) + } + } + + pub fn entangle() -> (send_packet, recv_packet) { + let p = packet(); + (send_packet(p), recv_packet(p)) + } +} + +pub mod pingpong { + use std::mem; + + pub struct ping(::pipes::send_packet); + + unsafe impl Send for ping {} + + pub struct pong(::pipes::send_packet); + + unsafe impl Send for pong {} + + pub fn liberate_ping(p: ping) -> ::pipes::send_packet { + unsafe { + let _addr : *const ::pipes::send_packet = match &p { + &ping(ref x) => { mem::transmute(x) } + }; + panic!() + } + } + + pub fn liberate_pong(p: pong) -> ::pipes::send_packet { + unsafe { + let _addr : *const ::pipes::send_packet = match &p { + &pong(ref x) => { mem::transmute(x) } + }; + panic!() + } + } + + pub fn init() -> (client::ping, server::ping) { + ::pipes::entangle() + } + + pub mod client { + use pingpong; + + pub type ping = ::pipes::send_packet; + pub type pong = ::pipes::recv_packet; + + pub fn do_ping(c: ping) -> pong { + let (sp, rp) = ::pipes::entangle(); + + ::pipes::send(c, pingpong::ping(sp)); + rp + } + + pub fn do_pong(c: pong) -> (ping, ()) { + let packet = ::pipes::recv(c); + if packet.is_none() { + panic!("sender closed the connection") + } + (pingpong::liberate_pong(packet.unwrap()), ()) + } + } + + pub mod server { + use pingpong; + + pub type ping = ::pipes::recv_packet; + pub type pong = ::pipes::send_packet; + + pub fn do_ping(c: ping) -> (pong, ()) { + let packet = ::pipes::recv(c); + if packet.is_none() { + panic!("sender closed the connection") + } + (pingpong::liberate_ping(packet.unwrap()), ()) + } + + pub fn do_pong(c: pong) -> ping { + let (sp, rp) = ::pipes::entangle(); + ::pipes::send(c, pingpong::pong(sp)); + rp + } + } +} + +fn client(chan: pingpong::client::ping) { + let chan = pingpong::client::do_ping(chan); + println!("Sent ping"); + let (_chan, _data) = pingpong::client::do_pong(chan); + println!("Received pong"); +} + +fn server(chan: pingpong::server::ping) { + let (chan, _data) = pingpong::server::do_ping(chan); + println!("Received ping"); + let _chan = pingpong::server::do_pong(chan); + println!("Sent pong"); +} + +pub fn main() { + /* +// Commented out because of option::get error + + let (client_, server_) = pingpong::init(); + + task::spawn {|client_| + let client__ = client_.take(); + client(client__); + }; + task::spawn {|server_| + let server__ = server_.take(); + server(server_ˊ); + }; + */ +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2723-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2723-b.rs new file mode 100644 index 000000000000..d9da974e50a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2723-b.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-2723-a.rs + +extern crate issue_2723_a; +use issue_2723_a::f; + +pub fn main() { + unsafe { + f(vec![2]); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27240.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27240.rs new file mode 100644 index 000000000000..696e59957ac6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27240.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(unused_assignments)] +#![allow(unused_variables)] +use std::fmt; +struct NoisyDrop(T); +impl Drop for NoisyDrop { + fn drop(&mut self) {} +} + +struct Bar([*const NoisyDrop; 2]); + +fn fine() { + let (u,b); + u = vec![43]; + b = Bar([&NoisyDrop(&u), &NoisyDrop(&u)]); +} + +struct Bar2(*const NoisyDrop, *const NoisyDrop); + +fn lolwut() { + let (u,v); + u = vec![43]; + v = Bar2(&NoisyDrop(&u), &NoisyDrop(&u)); +} + +fn main() { fine(); lolwut() } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27268.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27268.rs new file mode 100644 index 000000000000..e2fa83bb7996 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27268.rs @@ -0,0 +1,5 @@ +// run-pass +fn main() { + const _C: &'static dyn Fn() = &||{}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27281.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27281.rs new file mode 100644 index 000000000000..423f678b3ad6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27281.rs @@ -0,0 +1,18 @@ +// check-pass +pub trait Trait<'a> { + type T; + type U; + fn foo(&self, s: &'a ()) -> &'a (); +} + +impl<'a> Trait<'a> for () { + type T = &'a (); + type U = Self::T; + + fn foo(&self, s: &'a ()) -> &'a () { + let t: Self::T = s; t + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27282-move-match-input-into-guard.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27282-move-match-input-into-guard.rs new file mode 100644 index 000000000000..493ffc378017 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27282-move-match-input-into-guard.rs @@ -0,0 +1,21 @@ +// Issue 27282: Example 2: This sidesteps the AST checks disallowing +// mutable borrows in match guards by hiding the mutable borrow in a +// guard behind a move (of the mutably borrowed match input) within a +// closure. +// +// This example is not rejected by AST borrowck (and then reliably +// reaches the panic code when executed, despite the compiler warning +// about that match arm being unreachable. + +fn main() { + let b = &mut true; + match b { + &mut false => {}, + _ if { (|| { let bar = b; *bar = false; })(); + false } => { }, + &mut true => { println!("You might think we should get here"); }, +// { dg-error ".E0382." "" { target *-*-* } .-1 } + _ => panic!("surely we could never get here, since rustc warns it is unreachable."), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27282-move-ref-mut-into-guard.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27282-move-ref-mut-into-guard.rs new file mode 100644 index 000000000000..a1f0fa2f309f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27282-move-ref-mut-into-guard.rs @@ -0,0 +1,14 @@ +// Issue 27282: Example 1: This sidesteps the AST checks disallowing +// mutable borrows in match guards by hiding the mutable borrow in a +// guard behind a move (of the ref mut pattern id) within a closure. + +fn main() { + match Some(&4) { + None => {}, + ref mut foo + if { (|| { let bar = foo; bar.take() })(); false } => {}, +// { dg-error ".E0507." "" { target *-*-* } .-1 } + Some(s) => std::process::exit(*s), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-1.rs new file mode 100644 index 000000000000..6f98d2633e8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-1.rs @@ -0,0 +1,32 @@ +// This is testing an attempt to corrupt the discriminant of the match +// arm in a guard, followed by an attempt to continue matching on that +// corrupted discriminant in the remaining match arms. +// +// Basically this is testing that our new NLL feature of emitting a +// fake read on each match arm is catching cases like this. +// +// This case is interesting because it includes a guard that +// diverges, and therefore a single final fake-read at the very end +// after the final match arm would not suffice. + +struct ForceFnOnce; + +fn main() { + let mut x = &mut Some(&2); + let force_fn_once = ForceFnOnce; + match x { + &mut None => panic!("unreachable"), + &mut Some(&_) if { + // ForceFnOnce needed to exploit #27282 + (|| { *x = None; drop(force_fn_once); })(); +// { dg-error ".E0510." "" { target *-*-* } .-1 } + false + } => {} + &mut Some(&a) if { // this binds to garbage if we've corrupted discriminant + println!("{}", a); + panic!() + } => {} + _ => panic!("unreachable"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-2.rs new file mode 100644 index 000000000000..c373cd0992f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-2.rs @@ -0,0 +1,41 @@ +// This is testing an attempt to corrupt the discriminant of the match +// arm in a guard, followed by an attempt to continue matching on that +// corrupted discriminant in the remaining match arms. +// +// Basically this is testing that our new NLL feature of emitting a +// fake read on each match arm is catching cases like this. +// +// This case is interesting because it includes a guard that +// diverges, and therefore a single final fake-read at the very end +// after the final match arm would not suffice. +// +// It is also interesting because the access to the corrupted data +// occurs in the pattern-match itself, and not in the guard +// expression. + +struct ForceFnOnce; + +fn main() { + let mut x = &mut Some(&2); + let force_fn_once = ForceFnOnce; + match x { + &mut None => panic!("unreachable"), + &mut Some(&_) + if { + // ForceFnOnce needed to exploit #27282 + (|| { *x = None; drop(force_fn_once); })(); +// { dg-error ".E0510." "" { target *-*-* } .-1 } + false + } => {} + + // this segfaults if we corrupted the discriminant, because + // the compiler gets to *assume* that it cannot be the `None` + // case, even though that was the effect of the guard. + &mut Some(&2) + if { + panic!() + } => {} + _ => panic!("unreachable"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-3.rs new file mode 100644 index 000000000000..7fd1314c066b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27282-mutate-before-diverging-arm-3.rs @@ -0,0 +1,31 @@ +// This is testing an attempt to corrupt the discriminant of the match +// arm in a guard, followed by an attempt to continue matching on that +// corrupted discriminant in the remaining match arms. +// +// Basically this is testing that our new NLL feature of emitting a +// fake read on each match arm is catching cases like this. +// +// This case is interesting because a borrow of **x is untracked, because **x is +// immutable. However, for matches we care that **x refers to the same value +// until we have chosen a match arm. + +struct ForceFnOnce; +fn main() { + let mut x = &mut &Some(&2); + let force_fn_once = ForceFnOnce; + match **x { + None => panic!("unreachable"), + Some(&_) if { + // ForceFnOnce needed to exploit #27282 + (|| { *x = &None; drop(force_fn_once); })(); +// { dg-error ".E0510." "" { target *-*-* } .-1 } + false + } => {} + Some(&a) if { // this binds to garbage if we've corrupted discriminant + println!("{}", a); + panic!() + } => {} + _ => panic!("unreachable"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs new file mode 100644 index 000000000000..0e8db7de0982 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs @@ -0,0 +1,19 @@ +// Issue 27282: This is a variation on issue-27282-move-ref-mut-into-guard.rs +// +// It reborrows instead of moving the `ref mut` pattern borrow. This +// means that our conservative check for mutation in guards will +// reject it. But I want to make sure that we continue to reject it +// (under NLL) even when that conservaive check goes away. + +fn main() { + let mut b = &mut true; + match b { + &mut false => {}, + ref mut r if { (|| { let bar = &mut *r; **bar = false; })(); +// { dg-error ".E0596." "" { target *-*-* } .-1 } + false } => { &mut *r; }, + &mut true => { println!("You might think we should get here"); }, + _ => panic!("surely we could never get here, since rustc warns it is unreachable."), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27320.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27320.rs new file mode 100644 index 000000000000..696d1b488edc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27320.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(unused_variables)] +#![allow(dead_code)] + +macro_rules! piece( + ($piece:pat) => ($piece); +); + +enum Piece {A, B} + +fn main() { + match Piece::A { + piece!(pt@ Piece::A) | piece!(pt@ Piece::B) => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2734.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2734.rs new file mode 100644 index 000000000000..500a4f3abf9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2734.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +trait hax { + fn dummy(&self) { } +} +impl hax for A { } + +fn perform_hax(x: Box) -> Box { + box x as Box +} + +fn deadcode() { + perform_hax(box "deadcode".to_string()); +} + +pub fn main() { + let _ = perform_hax(box 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27340.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27340.rs new file mode 100644 index 000000000000..87b326f8e655 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27340.rs @@ -0,0 +1,7 @@ +struct Foo; +#[derive(Copy, Clone)] +// { dg-error ".E0204." "" { target *-*-* } .-1 } +struct Bar(Foo); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2735-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2735-2.rs new file mode 100644 index 000000000000..b88548752f77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2735-2.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(non_camel_case_types)] + +use std::cell::Cell; + +// This test should behave exactly like issue-2735-3 +struct defer<'a> { + b: &'a Cell, +} + +impl<'a> Drop for defer<'a> { + fn drop(&mut self) { + self.b.set(true); + } +} + +fn defer(b: &Cell) -> defer { + defer { + b: b + } +} + +pub fn main() { + let dtor_ran = &Cell::new(false); + let _ = defer(dtor_ran); + assert!(dtor_ran.get()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2735-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2735-3.rs new file mode 100644 index 000000000000..246830a6013f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2735-3.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(non_camel_case_types)] + +use std::cell::Cell; + +// This test should behave exactly like issue-2735-2 +struct defer<'a> { + b: &'a Cell, +} + +impl<'a> Drop for defer<'a> { + fn drop(&mut self) { + self.b.set(true); + } +} + +fn defer(b: &Cell) -> defer { + defer { + b: b + } +} + +pub fn main() { + let dtor_ran = &Cell::new(false); + defer(dtor_ran); + assert!(dtor_ran.get()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2735.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2735.rs new file mode 100644 index 000000000000..0dd939cc776e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2735.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +trait hax { + fn dummy(&self) { } +} +impl hax for A { } + +fn perform_hax(x: Box) -> Box { + box x as Box +} + +fn deadcode() { + perform_hax(box "deadcode".to_string()); +} + +pub fn main() { + perform_hax(box 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27401-dropflag-reinit.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27401-dropflag-reinit.rs new file mode 100644 index 000000000000..a88949cb8b8b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27401-dropflag-reinit.rs @@ -0,0 +1,28 @@ +// run-pass +// ignore-pretty issue #37201 + +// Check that when a `let`-binding occurs in a loop, its associated +// drop-flag is reinitialized (to indicate "needs-drop" at the end of +// the owning variable's scope). + +struct A<'a>(&'a mut i32); + +impl<'a> Drop for A<'a> { + fn drop(&mut self) { + *self.0 += 1; + } +} + +fn main() { + let mut cnt = 0; + for i in 0..2 { + let a = A(&mut cnt); + if i == 1 { // Note that + break; // both this break + } // and also + drop(a); // this move of `a` + // are necessary to expose the bug + } + assert_eq!(cnt, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27433.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27433.rs new file mode 100644 index 000000000000..ab95612d8675 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27433.rs @@ -0,0 +1,6 @@ +fn main() { + let foo = 42u32; + const FOO : u32 = foo; +// { dg-error ".E0435." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2748-a.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2748-a.rs new file mode 100644 index 000000000000..c682c7b8d400 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2748-a.rs @@ -0,0 +1,18 @@ +// build-pass +#![allow(dead_code)] +#![allow(non_snake_case)] + +// pretty-expanded FIXME #23616 + +struct CMap<'a> { + buf: &'a [u8], +} + +fn CMap(buf: &[u8]) -> CMap { + CMap { + buf: buf + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2748-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2748-b.rs new file mode 100644 index 000000000000..aa44bb342b1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2748-b.rs @@ -0,0 +1,12 @@ +// run-pass + +fn thing<'r>(x: &'r [isize]) -> &'r [isize] { x } + +pub fn main() { + let x = &[1,2,3]; + let y = x; + let z = thing(x); + assert_eq!(z[2], x[2]); + assert_eq!(z[1], y[1]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27583.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27583.rs new file mode 100644 index 000000000000..a502af2dd895 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27583.rs @@ -0,0 +1,48 @@ +// check-pass +// Regression test for issue #27583. Unclear how useful this will be +// going forward, since the issue in question was EXTREMELY sensitive +// to compiler internals (like the precise numbering of nodes), but +// what the hey. + +#![allow(warnings)] + +use std::cell::Cell; +use std::marker::PhantomData; + +pub trait Delegate<'tcx> { } + +pub struct InferCtxt<'a, 'tcx: 'a> { + x: PhantomData<&'a Cell<&'tcx ()>> +} + +pub struct MemCategorizationContext<'t, 'a: 't, 'tcx : 'a> { + x: &'t InferCtxt<'a, 'tcx>, +} + +pub struct ExprUseVisitor<'d, 't, 'a: 't, 'tcx:'a+'d> { + typer: &'t InferCtxt<'a, 'tcx>, + mc: MemCategorizationContext<'t, 'a, 'tcx>, + delegate: &'d mut (Delegate<'tcx>+'d), +} + +impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { + pub fn new(delegate: &'d mut Delegate<'tcx>, + typer: &'t InferCtxt<'a, 'tcx>) + -> ExprUseVisitor<'d,'t,'a,'tcx> + { + ExprUseVisitor { + typer: typer, + mc: MemCategorizationContext::new(typer), + delegate: delegate, + } + } +} + +impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> { + pub fn new(typer: &'t InferCtxt<'a, 'tcx>) -> MemCategorizationContext<'t, 'a, 'tcx> { + MemCategorizationContext { x: typer } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27592.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27592.rs new file mode 100644 index 000000000000..560eca3805ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27592.rs @@ -0,0 +1,20 @@ +// Regression test for issue #27592. + +fn write<'a, F: ::std::ops::FnOnce()->::std::fmt::Arguments<'a> + 'a>(fcn: F) { + use std::fmt::Write; + let _ = match fcn() { a => write!(&mut Stream, "{}", a), }; +} + +struct Stream; +impl ::std::fmt::Write for Stream { + fn write_str(&mut self, _s: &str) -> ::std::fmt::Result { + Ok( () ) + } +} + +fn main() { + write(|| format_args!("{}", String::from("Hello world"))); +// { dg-error ".E0515." "" { target *-*-* } .-1 } +// { dg-error ".E0515." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2761.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2761.rs new file mode 100644 index 000000000000..addd0898bbd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2761.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:custom message +// ignore-emscripten no processes + +fn main() { + assert!(false, "custom message"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27639.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27639.rs new file mode 100644 index 000000000000..6c0733f31e96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27639.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +fn main() { + const iter: i32 = 0; + + for i in 1..10 { + println!("{}", i); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27697.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27697.rs new file mode 100644 index 000000000000..cc6c30cff675 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27697.rs @@ -0,0 +1,22 @@ +// check-pass + +use std::ops::Deref; + +trait MyTrait { + fn do_something(&self); + fn as_str(&self) -> &str; +} + +impl Deref for dyn MyTrait { + type Target = str; + fn deref(&self) -> &Self::Target { + self.as_str() + } +} + +fn trait_object_does_something(t: &dyn MyTrait) { + t.do_something() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27815.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27815.rs new file mode 100644 index 000000000000..78442b882db2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27815.rs @@ -0,0 +1,13 @@ +mod A {} + +fn main() { + let u = A { x: 1 }; // { dg-error ".E0574." "" { target *-*-* } } + let v = u32 { x: 1 }; // { dg-error ".E0574." "" { target *-*-* } } + match () { + A { x: 1 } => {} +// { dg-error ".E0574." "" { target *-*-* } .-1 } + u32 { x: 1 } => {} +// { dg-error ".E0574." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27842.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27842.rs new file mode 100644 index 000000000000..9591ad964ce6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27842.rs @@ -0,0 +1,12 @@ +fn main() { + let tup = (0, 1, 2); + // the case where we show a suggestion + let _ = tup[0]; +// { dg-error ".E0608." "" { target *-*-* } .-1 } + + // the case where we show just a general hint + let i = 0_usize; + let _ = tup[i]; +// { dg-error ".E0608." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27859.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27859.rs new file mode 100644 index 000000000000..6921dc5bccea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27859.rs @@ -0,0 +1,22 @@ +// run-pass +// ignore-cloudabi no std::env +// ignore-wasm32 issue 42629 + +#[inline(never)] +fn foo(a: f32, b: f32) -> f32 { + a % b +} + +#[inline(never)] +fn bar(a: f32, b: f32) -> f32 { + ((a as f64) % (b as f64)) as f32 +} + +fn main() { + let unknown_float = std::env::args().len(); + println!("{}", foo(4.0, unknown_float as f32)); + println!("{}", foo(5.0, (unknown_float as f32) + 1.0)); + println!("{}", bar(6.0, (unknown_float as f32) + 2.0)); + println!("{}", bar(7.0, (unknown_float as f32) + 3.0)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27889.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27889.rs new file mode 100644 index 000000000000..aca39426ebc4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27889.rs @@ -0,0 +1,24 @@ +// check-pass +#![allow(unused_assignments)] +#![allow(unused_variables)] +// Test that a field can have the same name in different variants +// of an enum + +pub enum Foo { + X { foo: u32 }, + Y { foo: u32 } +} + +pub fn foo(mut x: Foo) { + let mut y = None; + let mut z = None; + if let Foo::X { ref foo } = x { + z = Some(foo); + } + if let Foo::Y { ref mut foo } = x { + y = Some(foo); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27890.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27890.rs new file mode 100644 index 000000000000..46e9ebb594d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27890.rs @@ -0,0 +1,8 @@ +// run-pass +static PLUS_ONE: &'static (dyn Fn(i32) -> i32 + Sync) = (&|x: i32| { x + 1 }) + as &'static (dyn Fn(i32) -> i32 + Sync); + +fn main() { + assert_eq!(PLUS_ONE(2), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27895.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27895.rs new file mode 100644 index 000000000000..df5e5ad00dad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27895.rs @@ -0,0 +1,11 @@ +fn main() { + let i = 5; + let index = 6; + + match i { + 0..=index => println!("winner"), +// { dg-error ".E0080." "" { target *-*-* } .-1 } + _ => println!("hello"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27901.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27901.rs new file mode 100644 index 000000000000..d08a72873ade --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27901.rs @@ -0,0 +1,12 @@ +// run-pass +trait Stream { type Item; } +impl<'a> Stream for &'a str { type Item = u8; } +fn f<'s>(s: &'s str) -> (&'s str, <&'s str as Stream>::Item) { + (s, 42) +} + +fn main() { + let fx = f as for<'t> fn(&'t str) -> (&'t str, <&'t str as Stream>::Item); + assert_eq!(fx("hi"), ("hi", 42)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27942.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27942.rs new file mode 100644 index 000000000000..133ec0028671 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27942.rs @@ -0,0 +1,15 @@ +pub trait Resources<'a> {} + +pub trait Buffer<'a, R: Resources<'a>> { + + fn select(&self) -> BufferViewHandle; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + +pub struct BufferViewHandle<'a, R: 'a+Resources<'a>>(&'a R); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27949.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27949.rs new file mode 100644 index 000000000000..3361eeb4743f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27949.rs @@ -0,0 +1,42 @@ +// run-pass +// +// At one time, the `==` operator (and other binary operators) did not +// support subtyping during type checking, and would therefore require +// LHS and RHS to be exactly identical--i.e. to have the same lifetimes. +// +// This was fixed in 1a7fb7dc78439a704f024609ce3dc0beb1386552. + +#[derive(Copy, Clone)] +struct Input<'a> { + foo: &'a u32 +} + +impl <'a> std::cmp::PartialEq> for Input<'a> { + fn eq(&self, other: &Input<'a>) -> bool { + self.foo == other.foo + } + + fn ne(&self, other: &Input<'a>) -> bool { + self.foo != other.foo + } +} + + +fn check_equal<'a, 'b>(x: Input<'a>, y: Input<'b>) -> bool { + // Type checking error due to 'a != 'b prior to 1a7fb7dc78 + x == y +} + +fn main() { + let i = 1u32; + let j = 1u32; + let k = 2u32; + + let input_i = Input { foo: &i }; + let input_j = Input { foo: &j }; + let input_k = Input { foo: &k }; + assert!(check_equal(input_i, input_i)); + assert!(check_equal(input_i, input_j)); + assert!(!check_equal(input_i, input_k)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-27997.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-27997.rs new file mode 100644 index 000000000000..8bda325f54c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-27997.rs @@ -0,0 +1,38 @@ +// run-pass +use std::sync::atomic::{Ordering, AtomicUsize}; + +use std::mem; +struct S { + _u: U, + size_of_u: usize, + _v: V, + size_of_v: usize +} + +impl S { + fn new(u: U, v: V) -> Self { + S { + _u: u, + size_of_u: mem::size_of::(), + _v: v, + size_of_v: mem::size_of::() + } + } +} + +static COUNT: AtomicUsize = AtomicUsize::new(0); + +impl Drop for S { + fn drop(&mut self) { + assert_eq!(mem::size_of::(), self.size_of_u); + assert_eq!(mem::size_of::(), self.size_of_v); + COUNT.store(COUNT.load(Ordering::SeqCst)+1, Ordering::SeqCst); + } +} + +fn main() { + assert_eq!(COUNT.load(Ordering::SeqCst), 0); + { S::new(0u8, 1u16); } + assert_eq!(COUNT.load(Ordering::SeqCst), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2804-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2804-2.rs new file mode 100644 index 000000000000..13fda5f1b1e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2804-2.rs @@ -0,0 +1,13 @@ +// check-pass +#![allow(dead_code)] +// Minimized version of issue-2804.rs. Both check that callee IDs don't +// clobber the previous node ID in a macro expr + +use std::collections::HashMap; + +fn add_interfaces(managed_ip: String, device: HashMap) { + println!("{}, {}", managed_ip, device["interfaces"]); +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28075.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28075.rs new file mode 100644 index 000000000000..844804a9ccaa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28075.rs @@ -0,0 +1,14 @@ +// Unstable entities should be caught in import lists + +// aux-build:lint-stability.rs + +#![allow(warnings)] + +extern crate lint_stability; + +use lint_stability::{unstable, deprecated}; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28098.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28098.rs new file mode 100644 index 000000000000..7358855ba408 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28098.rs @@ -0,0 +1,28 @@ +fn main() { + let _ = Iterator::next(&mut ()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + + for _ in false {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + let _ = Iterator::next(&mut ()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + other() +} + +pub fn other() { + // check errors are still reported globally + + let _ = Iterator::next(&mut ()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + + let _ = Iterator::next(&mut ()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + for _ in false {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28105.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28105.rs new file mode 100644 index 000000000000..3c7c57c286b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28105.rs @@ -0,0 +1,9 @@ +// Make sure that a continue span actually contains the keyword. + +fn main() { + continue // { dg-error ".E0268." "" { target *-*-* } } + ; + break // { dg-error ".E0268." "" { target *-*-* } } + ; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28109.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28109.rs new file mode 100644 index 000000000000..35efc742b290 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28109.rs @@ -0,0 +1,13 @@ +// Make sure that label for continue and break is spanned correctly + +fn main() { + loop { + continue + 'b // { dg-error ".E0426." "" { target *-*-* } } + ; + break + 'c // { dg-error ".E0426." "" { target *-*-* } } + ; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28113.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28113.rs new file mode 100644 index 000000000000..300c27d275ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28113.rs @@ -0,0 +1,9 @@ +#![allow(warnings)] + +const X: u8 = + || -> u8 { 5 }() +// { dg-error ".E0015." "" { target *-*-* } .-1 } +; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28134.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28134.rs new file mode 100644 index 000000000000..06531ad1c824 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28134.rs @@ -0,0 +1,4 @@ +// compile-flags: --test + +#![test] // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28181.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28181.rs new file mode 100644 index 000000000000..8c9b1aa2de9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28181.rs @@ -0,0 +1,7 @@ +// run-pass +fn bar(f: F) -> usize where F: Fn([usize; 1]) -> usize { f([2]) } + +fn main() { + bar(|u| { u[0] }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2823.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2823.rs new file mode 100644 index 000000000000..d0628d331fe6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2823.rs @@ -0,0 +1,15 @@ +struct C { + x: isize, +} + +impl Drop for C { + fn drop(&mut self) { + println!("dropping: {}", self.x); + } +} + +fn main() { + let c = C{ x: 2}; + let _d = c.clone(); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28279.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28279.rs new file mode 100644 index 000000000000..53c9ca260dd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28279.rs @@ -0,0 +1,22 @@ +// check-pass +#![allow(dead_code)] +use std::rc::Rc; + +fn test1() -> Rc Fn(&'a usize) + 'static> { + if let Some(_) = Some(1) { + loop{} + } else { + loop{} + } +} + +fn test2() -> *mut (dyn for<'a> Fn(&'a usize) + 'static) { + if let Some(_) = Some(1) { + loop{} + } else { + loop{} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28324.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28324.rs new file mode 100644 index 000000000000..e790ff21f0a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28324.rs @@ -0,0 +1,9 @@ +extern { + static error_message_count: u32; +} + +pub static BAZ: u32 = *&error_message_count; +// { dg-error ".E0133." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28344.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28344.rs new file mode 100644 index 000000000000..583edf263608 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28344.rs @@ -0,0 +1,12 @@ +use std::ops::BitXor; + +fn main() { + let x: u8 = BitXor::bitor(0 as u8, 0 as u8); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +// { dg-error ".E0599." "" { target *-*-* } .-2 } + + let g = BitXor::bitor; +// { dg-error ".E0599." "" { target *-*-* } .-1 } +// { dg-error ".E0599." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28388-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28388-1.rs new file mode 100644 index 000000000000..0f0d19d03c07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28388-1.rs @@ -0,0 +1,6 @@ +// Prefix in imports with empty braces should be resolved and checked privacy, stability, etc. + +use foo::{}; // { dg-error ".E0432." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28388-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28388-2.rs new file mode 100644 index 000000000000..a4b98681593e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28388-2.rs @@ -0,0 +1,11 @@ +// Prefix in imports with empty braces should be resolved and checked privacy, stability, etc. + +mod m { + mod n {} +} + +use m::n::{}; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28388-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28388-3.rs new file mode 100644 index 000000000000..cb41a1ead58a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28388-3.rs @@ -0,0 +1,12 @@ +// Prefix in imports with empty braces should be resolved and checked privacy, stability, etc. + +// aux-build:lint-stability.rs + +extern crate lint_stability; + +use lint_stability::UnstableEnum::{}; +// { dg-error ".E0658." "" { target *-*-* } .-1 } +use lint_stability::StableEnum::{}; // OK + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28433.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28433.rs new file mode 100644 index 000000000000..b9357fb743f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28433.rs @@ -0,0 +1,13 @@ +enum Bird { + pub Duck, +// { dg-error ".E0449." "" { target *-*-* } .-1 } + Goose, + pub(crate) Dove +// { dg-error ".E0449." "" { target *-*-* } .-1 } +} + + +fn main() { + let y = Bird::Goose; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28472.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28472.rs new file mode 100644 index 000000000000..0e9ea04e7293 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28472.rs @@ -0,0 +1,15 @@ +// Check that the visibility modifier is included in the span of foreign items. + +extern { + fn foo(); + + pub // { dg-error ".E0428." "" { target *-*-* } } + fn foo(); + + pub // { dg-error ".E0428." "" { target *-*-* } } + static mut foo: u32; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2848.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2848.rs new file mode 100644 index 000000000000..6a2e7ec06407 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2848.rs @@ -0,0 +1,18 @@ +#[allow(non_camel_case_types)] + +mod bar { + pub enum foo { + alpha, + beta, + charlie + } +} + +fn main() { + use bar::foo::{alpha, charlie}; + match alpha { + alpha | beta => {} // { dg-error ".E0408." "" { target *-*-* } } + charlie => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2849.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2849.rs new file mode 100644 index 000000000000..6f3cc4aff01d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2849.rs @@ -0,0 +1,9 @@ +enum Foo { Alpha, Beta(isize) } + +fn main() { + match Foo::Alpha { + Foo::Alpha | Foo::Beta(i) => {} +// { dg-error ".E0408." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28498-must-work-ex1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28498-must-work-ex1.rs new file mode 100644 index 000000000000..33dfd7b2cf05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28498-must-work-ex1.rs @@ -0,0 +1,19 @@ +// run-pass +// Example taken from RFC 1238 text + +// https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md +// #examples-of-code-that-must-continue-to-work + +use std::cell::Cell; + +struct Concrete<'a>(u32, Cell>>); + +fn main() { + let mut data = Vec::new(); + data.push(Concrete(0, Cell::new(None))); + data.push(Concrete(0, Cell::new(None))); + + data[0].1.set(Some(&data[1])); + data[1].1.set(Some(&data[0])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28498-must-work-ex2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28498-must-work-ex2.rs new file mode 100644 index 000000000000..17111308555d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28498-must-work-ex2.rs @@ -0,0 +1,21 @@ +// run-pass +// Example taken from RFC 1238 text + +// https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md +// #examples-of-code-that-must-continue-to-work + +use std::cell::Cell; + +struct Concrete<'a>(u32, Cell>>); + +struct Foo { data: Vec } + +fn main() { + let mut foo = Foo { data: Vec::new() }; + foo.data.push(Concrete(0, Cell::new(None))); + foo.data.push(Concrete(0, Cell::new(None))); + + foo.data[0].1.set(Some(&foo.data[1])); + foo.data[1].1.set(Some(&foo.data[0])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-ex1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-ex1.rs new file mode 100644 index 000000000000..93ac16aa4177 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-ex1.rs @@ -0,0 +1,28 @@ +// run-pass + +// Example taken from RFC 1238 text + +// https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md +// #example-of-the-unguarded-escape-hatch + +#![feature(dropck_eyepatch)] +use std::cell::Cell; + +struct Concrete<'a>(u32, Cell>>); + +struct Foo { data: Vec } + +// Below is the UGEH attribute +unsafe impl<#[may_dangle] T> Drop for Foo { + fn drop(&mut self) { } +} + +fn main() { + let mut foo = Foo { data: Vec::new() }; + foo.data.push(Concrete(0, Cell::new(None))); + foo.data.push(Concrete(0, Cell::new(None))); + + foo.data[0].1.set(Some(&foo.data[1])); + foo.data[1].1.set(Some(&foo.data[0])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-with-lifetime-param.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-with-lifetime-param.rs new file mode 100644 index 000000000000..b4cd6f8e4014 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-with-lifetime-param.rs @@ -0,0 +1,39 @@ +// run-pass + +// Demonstrate the use of the unguarded escape hatch with a lifetime param +// to assert that destructor will not access any dead data. +// +// Compare with compile-fail/issue28498-reject-lifetime-param.rs + +#![feature(dropck_eyepatch)] + +#[derive(Debug)] +struct ScribbleOnDrop(String); + +impl Drop for ScribbleOnDrop { + fn drop(&mut self) { + self.0 = format!("DROPPED"); + } +} + +struct Foo<'a>(u32, &'a ScribbleOnDrop); + +unsafe impl<#[may_dangle] 'a> Drop for Foo<'a> { + fn drop(&mut self) { + // Use of `may_dangle` is sound, because destructor never accesses `self.1`. + println!("Dropping Foo({}, _)", self.0); + } +} + +fn main() { + let (last_dropped, foo0); + let (foo1, first_dropped); + + last_dropped = ScribbleOnDrop(format!("last")); + first_dropped = ScribbleOnDrop(format!("first")); + foo0 = Foo(0, &last_dropped); + foo1 = Foo(1, &first_dropped); + + println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs new file mode 100644 index 000000000000..daba76b6e848 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-with-passed-to-fn.rs @@ -0,0 +1,47 @@ +// run-pass + +// Demonstrate the use of the unguarded escape hatch with a type param in negative position +// to assert that destructor will not access any dead data. +// +// Compare with compile-fail/issue28498-reject-lifetime-param.rs + +// Demonstrate that a type param in negative position causes dropck to reject code +// that might indirectly access previously dropped value. +// +// Compare with run-pass/issue28498-ugeh-with-passed-to-fn.rs + +#![feature(dropck_eyepatch)] + +#[derive(Debug)] +struct ScribbleOnDrop(String); + +impl Drop for ScribbleOnDrop { + fn drop(&mut self) { + self.0 = format!("DROPPED"); + } +} + +struct Foo(u32, T, Box fn(&'r T) -> String>); + +unsafe impl<#[may_dangle] T> Drop for Foo { + fn drop(&mut self) { + // Use of `may_dangle` is sound, because destructor never passes a `self.1` + // to the callback (in `self.2`) despite having it available. + println!("Dropping Foo({}, _)", self.0); + } +} + +fn callback(s: & &ScribbleOnDrop) -> String { format!("{:?}", s) } + +fn main() { + let (last_dropped, foo0); + let (foo1, first_dropped); + + last_dropped = ScribbleOnDrop(format!("last")); + first_dropped = ScribbleOnDrop(format!("first")); + foo0 = Foo(0, &last_dropped, Box::new(callback)); + foo1 = Foo(1, &first_dropped, Box::new(callback)); + + println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-with-trait-bound.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-with-trait-bound.rs new file mode 100644 index 000000000000..cf9128db9ddb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28498-ugeh-with-trait-bound.rs @@ -0,0 +1,42 @@ +// run-pass + +// Demonstrate the use of the unguarded escape hatch with a trait bound +// to assert that destructor will not access any dead data. +// +// Compare with compile-fail/issue28498-reject-trait-bound.rs + +#![feature(dropck_eyepatch)] + +use std::fmt; + +#[derive(Debug)] +struct ScribbleOnDrop(String); + +impl Drop for ScribbleOnDrop { + fn drop(&mut self) { + self.0 = format!("DROPPED"); + } +} + +struct Foo(u32, T); + +unsafe impl<#[may_dangle] T: fmt::Debug> Drop for Foo { + fn drop(&mut self) { + // Use of `may_dangle` is sound, because destructor never accesses + // the `Debug::fmt` method of `T`, despite having it available. + println!("Dropping Foo({}, _)", self.0); + } +} + +fn main() { + let (last_dropped, foo0); + let (foo1, first_dropped); + + last_dropped = ScribbleOnDrop(format!("last")); + first_dropped = ScribbleOnDrop(format!("first")); + foo0 = Foo(0, &last_dropped); + foo1 = Foo(1, &first_dropped); + + println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28550.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28550.rs new file mode 100644 index 000000000000..7ebc04378924 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28550.rs @@ -0,0 +1,17 @@ +// run-pass +struct AT,T>(F::Output); +struct BT,T>(A); + +// Removing Option causes it to compile. +fn fooT>(f: F) -> Option> { + Some(B(A(f()))) +} + +fn main() { + let v = (|| foo(||4))(); + match v { + Some(B(A(4))) => {}, + _ => unreachable!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28561.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28561.rs new file mode 100644 index 000000000000..4488f98ed832 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28561.rs @@ -0,0 +1,113 @@ +// check-pass +// ignore-compare-mode-chalk +#[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +struct Array { + f00: [T; 00], + f01: [T; 01], + f02: [T; 02], + f03: [T; 03], + f04: [T; 04], + f05: [T; 05], + f06: [T; 06], + f07: [T; 07], + f08: [T; 08], + f09: [T; 09], + f10: [T; 10], + f11: [T; 11], + f12: [T; 12], + f13: [T; 13], + f14: [T; 14], + f15: [T; 15], + f16: [T; 16], + f17: [T; 17], + f18: [T; 18], + f19: [T; 19], + f20: [T; 20], + f21: [T; 21], + f22: [T; 22], + f23: [T; 23], + f24: [T; 24], + f25: [T; 25], + f26: [T; 26], + f27: [T; 27], + f28: [T; 28], + f29: [T; 29], + f30: [T; 30], + f31: [T; 31], + f32: [T; 32], +} + +// FIXME(#44580): merge with `Array` once `[T; N]: Clone` where `T: Clone` +#[derive(Clone, Copy)] +struct CopyArray { + f00: [T; 00], + f01: [T; 01], + f02: [T; 02], + f03: [T; 03], + f04: [T; 04], + f05: [T; 05], + f06: [T; 06], + f07: [T; 07], + f08: [T; 08], + f09: [T; 09], + f10: [T; 10], + f11: [T; 11], + f12: [T; 12], + f13: [T; 13], + f14: [T; 14], + f15: [T; 15], + f16: [T; 16], + f17: [T; 17], + f18: [T; 18], + f19: [T; 19], + f20: [T; 20], + f21: [T; 21], + f22: [T; 22], + f23: [T; 23], + f24: [T; 24], + f25: [T; 25], + f26: [T; 26], + f27: [T; 27], + f28: [T; 28], + f29: [T; 29], + f30: [T; 30], + f31: [T; 31], + f32: [T; 32], +} + +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +struct Fn { + f00: fn(), + f01: fn(A), + f02: fn(A, B), + f03: fn(A, B, C), + f04: fn(A, B, C, D), + f05: fn(A, B, C, D, E), + f06: fn(A, B, C, D, E, F), + f07: fn(A, B, C, D, E, F, G), + f08: fn(A, B, C, D, E, F, G, H), + f09: fn(A, B, C, D, E, F, G, H, I), + f10: fn(A, B, C, D, E, F, G, H, I, J), + f11: fn(A, B, C, D, E, F, G, H, I, J, K), + f12: fn(A, B, C, D, E, F, G, H, I, J, K, L), +} + +#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +struct Tuple { + f00: (), + f01: (A), + f02: (A, B), + f03: (A, B, C), + f04: (A, B, C, D), + f05: (A, B, C, D, E), + f06: (A, B, C, D, E, F), + f07: (A, B, C, D, E, F, G), + f08: (A, B, C, D, E, F, G, H), + f09: (A, B, C, D, E, F, G, H, I), + f10: (A, B, C, D, E, F, G, H, I, J), + f11: (A, B, C, D, E, F, G, H, I, J, K), + f12: (A, B, C, D, E, F, G, H, I, J, K, L), +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28568.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28568.rs new file mode 100644 index 000000000000..edc220557c7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28568.rs @@ -0,0 +1,13 @@ +struct MyStruct; + +impl Drop for MyStruct { + fn drop(&mut self) { } +} + +impl Drop for MyStruct { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + fn drop(&mut self) { } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28576.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28576.rs new file mode 100644 index 000000000000..d06b0df3f79f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28576.rs @@ -0,0 +1,13 @@ +pub trait Foo { + type Assoc; +} + +pub trait Bar: Foo { + fn new(&self, b: & + dyn Bar // { dg-error ".E0038." "" { target *-*-* } } + + ); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28586.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28586.rs new file mode 100644 index 000000000000..ca6151ae4a09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28586.rs @@ -0,0 +1,8 @@ +// Regression test for issue #28586 + +pub trait Foo {} +impl Foo for [u8; usize::BYTES] {} +// { dg-error ".E0599." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28600.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28600.rs new file mode 100644 index 000000000000..a52ad81280a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28600.rs @@ -0,0 +1,16 @@ +// build-pass +// #28600 ICE: pub extern fn with parameter type &str inside struct impl + +struct Test; + +impl Test { + #[allow(dead_code)] + #[allow(unused_variables)] + #[allow(improper_ctypes_definitions)] + pub extern fn test(val: &str) { + + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28625.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28625.rs new file mode 100644 index 000000000000..dc1f0e88fb6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28625.rs @@ -0,0 +1,23 @@ +// normalize-stderr-test "\d+ bits" -> "N bits" + +trait Bar { + type Bar; +} + +struct ArrayPeano { + data: T::Bar, +} + +fn foo(a: &ArrayPeano) -> &[T] where T: Bar { + unsafe { std::mem::transmute(a) } // { dg-error ".E0512." "" { target *-*-* } } +} + +impl Bar for () { + type Bar = (); +} + +fn main() { + let x: ArrayPeano<()> = ArrayPeano { data: () }; + foo(&x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28676.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28676.rs new file mode 100644 index 000000000000..ba615223f60c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28676.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(dead_code)] +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +#[derive(Copy, Clone)] +pub struct Quad { a: u64, b: u64, c: u64, d: u64 } + +mod rustrt { + use super::Quad; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn get_c_many_params(_: *const (), _: *const (), + _: *const (), _: *const (), f: Quad) -> u64; + } +} + +fn test() { + unsafe { + let null = std::ptr::null(); + let q = Quad { + a: 1, + b: 2, + c: 3, + d: 4 + }; + assert_eq!(rustrt::get_c_many_params(null, null, null, null, q), q.c); + } +} + +pub fn main() { + test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28776.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28776.rs new file mode 100644 index 000000000000..f3ede8967e84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28776.rs @@ -0,0 +1,7 @@ +use std::ptr; + +fn main() { + (&ptr::write)(1 as *mut _, 42); +// { dg-error ".E0133." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28777.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28777.rs new file mode 100644 index 000000000000..4e929b0b8828 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28777.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(unused_braces)] +fn main() { + let v1 = { 1 + {2} * {3} }; + let v2 = 1 + {2} * {3} ; + + assert_eq!(7, v1); + assert_eq!(7, v2); + + let v3; + v3 = { 1 + {2} * {3} }; + let v4; + v4 = 1 + {2} * {3}; + assert_eq!(7, v3); + assert_eq!(7, v4); + + let v5 = { 1 + {2} * 3 }; + assert_eq!(7, v5); + + let v9 = { 1 + if 1 > 2 {1} else {2} * {3} }; + assert_eq!(7, v9); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28822.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28822.rs new file mode 100644 index 000000000000..4800d625115d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28822.rs @@ -0,0 +1,8 @@ +// check-pass +#![allow(dead_code)] + +fn main() {} + +const fn size_ofs(_: usize) {} +const fn size_ofs2(_foo: usize) {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28828.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28828.rs new file mode 100644 index 000000000000..40e05fda180b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28828.rs @@ -0,0 +1,19 @@ +// run-pass +pub trait Foo { + type Out; +} + +impl Foo for () { + type Out = bool; +} + +fn main() { + type Bool = <() as Foo>::Out; + + let x: Bool = true; + assert!(x); + + let y: Option = None; + assert_eq!(y, None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28837.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28837.rs new file mode 100644 index 000000000000..81f913f7b6fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28837.rs @@ -0,0 +1,36 @@ +struct A; + +fn main() { + let a = A; + + a + a; // { dg-error ".E0369." "" { target *-*-* } } + + a - a; // { dg-error ".E0369." "" { target *-*-* } } + + a * a; // { dg-error ".E0369." "" { target *-*-* } } + + a / a; // { dg-error ".E0369." "" { target *-*-* } } + + a % a; // { dg-error ".E0369." "" { target *-*-* } } + + a & a; // { dg-error ".E0369." "" { target *-*-* } } + + a | a; // { dg-error ".E0369." "" { target *-*-* } } + + a << a; // { dg-error ".E0369." "" { target *-*-* } } + + a >> a; // { dg-error ".E0369." "" { target *-*-* } } + + a == a; // { dg-error ".E0369." "" { target *-*-* } } + + a != a; // { dg-error ".E0369." "" { target *-*-* } } + + a < a; // { dg-error ".E0369." "" { target *-*-* } } + + a <= a; // { dg-error ".E0369." "" { target *-*-* } } + + a > a; // { dg-error ".E0369." "" { target *-*-* } } + + a >= a; // { dg-error ".E0369." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28839.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28839.rs new file mode 100644 index 000000000000..df9b89fb6613 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28839.rs @@ -0,0 +1,16 @@ +// run-pass +// ignore-pretty issue #37199 + +pub struct Foo; + +pub fn get_foo2<'a>(foo: &'a mut Option<&'a mut Foo>) -> &'a mut Foo { + match foo { + // Ensure that this is not considered a move, but rather a reborrow. + &mut Some(ref mut x) => *x, + &mut None => panic!(), + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28848.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28848.rs new file mode 100644 index 000000000000..9bb064829b8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28848.rs @@ -0,0 +1,14 @@ +struct Foo<'a, 'b: 'a>(&'a &'b ()); + +impl<'a, 'b> Foo<'a, 'b> { + fn xmute(a: &'b ()) -> &'a () { + unreachable!() + } +} + +pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { + Foo::<'a, 'b>::xmute(u) // { dg-error ".E0478." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28871.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28871.rs new file mode 100644 index 000000000000..23758adef344 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28871.rs @@ -0,0 +1,25 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-28934.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28934.rs new file mode 100644 index 000000000000..6be42c74b702 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28934.rs @@ -0,0 +1,26 @@ +// Regression test: issue had to do with "givens" in region inference, +// which were not being considered during the contraction phase. + +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +struct Parser<'i: 't, 't>(&'i u8, &'t u8); + +impl<'i, 't> Parser<'i, 't> { + fn parse_nested_block(&mut self, parse: F) -> Result + where for<'tt> F: FnOnce(&mut Parser<'i, 'tt>) -> T + { + panic!() + } + + fn expect_exhausted(&mut self) -> Result<(), ()> { + Ok(()) + } +} + +fn main() { + let x = 0u8; + Parser(&x, &x).parse_nested_block(|input| input.expect_exhausted()).unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28936.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28936.rs new file mode 100644 index 000000000000..f01bc9a2de18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28936.rs @@ -0,0 +1,28 @@ +// check-pass +pub type Session = i32; +pub struct StreamParser<'a, T> { + _tokens: T, + _session: &'a mut Session, +} + +impl<'a, T> StreamParser<'a, T> { + pub fn thing(&mut self) -> bool { true } +} + +pub fn parse_stream, U, F>( + _session: &mut Session, _tokens: T, _f: F) -> U + where F: Fn(&mut StreamParser) -> U { panic!(); } + +pub fn thing(session: &mut Session) { + let mut stream = vec![1, 2, 3].into_iter(); + + let _b = parse_stream(session, + stream.by_ref(), + // replacing the above with the following fixes it + //&mut stream, + |p| p.thing()); + +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2895.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2895.rs new file mode 100644 index 000000000000..db48262e26e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2895.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] + +use std::mem; + +struct Cat { + x: isize +} + +struct Kitty { + x: isize, +} + +impl Drop for Kitty { + fn drop(&mut self) {} +} + +#[cfg(target_pointer_width = "64")] +pub fn main() { + assert_eq!(mem::size_of::(), 8 as usize); + assert_eq!(mem::size_of::(), 8 as usize); +} + +#[cfg(target_pointer_width = "32")] +pub fn main() { + assert_eq!(mem::size_of::(), 4 as usize); + assert_eq!(mem::size_of::(), 4 as usize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28950.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28950.rs new file mode 100644 index 000000000000..df4f13ab33c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28950.rs @@ -0,0 +1,23 @@ +// run-pass +// ignore-emscripten no threads +// compile-flags: -O + +// Tests that the `vec!` macro does not overflow the stack when it is +// given data larger than the stack. + +// FIXME(eddyb) Improve unoptimized codegen to avoid the temporary, +// and thus run successfully even when compiled at -C opt-level=0. + +const LEN: usize = 1 << 15; + +use std::thread::Builder; + +fn main() { + assert!(Builder::new().stack_size(LEN / 2).spawn(|| { + // FIXME(eddyb) this can be vec![[0: LEN]] pending + // https://llvm.org/bugs/show_bug.cgi?id=28987 + let vec = vec![unsafe { std::mem::zeroed::<[u8; LEN]>() }]; + assert_eq!(vec.len(), 1); + }).unwrap().join().is_ok()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28971.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28971.rs new file mode 100644 index 000000000000..654b7b1a1948 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28971.rs @@ -0,0 +1,17 @@ +enum Foo { + Bar(u8) +} +fn main(){ + foo(|| { + match Foo::Bar(1) { + Foo::Baz(..) => (), +// { dg-error ".E0599." "" { target *-*-* } .-1 } + _ => (), + } + }); +} + +fn foo(f: F) where F: FnMut() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28983.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28983.rs new file mode 100644 index 000000000000..82eff363a1dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28983.rs @@ -0,0 +1,23 @@ +// run-pass +pub trait Test { type T; } + +impl Test for u32 { + type T = i32; +} + +pub mod export { + #[no_mangle] + pub extern "C" fn issue_28983(t: ::T) -> i32 { t*3 } +} + +// to test both exporting and importing functions, import +// a function from ourselves. +extern "C" { + fn issue_28983(t: ::T) -> i32; +} + +fn main() { + assert_eq!(export::issue_28983(2), 6); + assert_eq!(unsafe { issue_28983(3) }, 9); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28992-empty.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28992-empty.rs new file mode 100644 index 000000000000..98fbf5802df8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28992-empty.rs @@ -0,0 +1,17 @@ +// Can't use constants as tuple struct patterns + + +const C1: i32 = 0; + +struct S; + +impl S { + const C2: i32 = 0; +} + +fn main() { + if let C1(..) = 0 {} // { dg-error ".E0532." "" { target *-*-* } } + if let S::C2(..) = 0 {} +// { dg-error ".E0164." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-28999.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-28999.rs new file mode 100644 index 000000000000..443d1652de89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-28999.rs @@ -0,0 +1,12 @@ +// check-pass +pub struct Xyz<'a, V> { + pub v: (V, &'a u32), +} + +pub fn eq<'a, 's, 't, V>(this: &'s Xyz<'a, V>, other: &'t Xyz<'a, V>) -> bool + where V: PartialEq { + this.v == other.v +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29030.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29030.rs new file mode 100644 index 000000000000..5b932ee245d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29030.rs @@ -0,0 +1,10 @@ +// check-pass +#![allow(dead_code)] +#[derive(Debug)] +struct Message<'a, P: 'a = &'a [u8]> { + header: &'a [u8], + payload: P, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29037.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29037.rs new file mode 100644 index 000000000000..3b13c7836d0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29037.rs @@ -0,0 +1,25 @@ +// check-pass +#![allow(dead_code)] +// This test ensures that each pointer type `P` is covariant in `X`. + +use std::rc::Rc; +use std::sync::Arc; + +fn a<'r>(x: Box<&'static str>) -> Box<&'r str> { + x +} + +fn b<'r, 'w>(x: &'w &'static str) -> &'w &'r str { + x +} + +fn c<'r>(x: Arc<&'static str>) -> Arc<&'r str> { + x +} + +fn d<'r>(x: Rc<&'static str>) -> Rc<&'r str> { + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2904.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2904.rs new file mode 100644 index 000000000000..e0cf44c591fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2904.rs @@ -0,0 +1,80 @@ +// build-pass +#![allow(unused_must_use)] +#![allow(dead_code)] +#![allow(unused_mut)] +#![allow(non_camel_case_types)] + +// Map representation + +use std::fmt; +use std::io::prelude::*; +use square::{bot, wall, rock, lambda, closed_lift, open_lift, earth, empty}; + +enum square { + bot, + wall, + rock, + lambda, + closed_lift, + open_lift, + earth, + empty +} + +impl fmt::Debug for square { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", match *self { + bot => { "R".to_string() } + wall => { "#".to_string() } + rock => { "*".to_string() } + lambda => { "\\".to_string() } + closed_lift => { "L".to_string() } + open_lift => { "O".to_string() } + earth => { ".".to_string() } + empty => { " ".to_string() } + }) + } +} + +fn square_from_char(c: char) -> square { + match c { + 'R' => { bot } + '#' => { wall } + '*' => { rock } + '\\' => { lambda } + 'L' => { closed_lift } + 'O' => { open_lift } + '.' => { earth } + ' ' => { empty } + _ => { + println!("invalid square: {}", c); + panic!() + } + } +} + +fn read_board_grid(mut input: rdr) + -> Vec> { + let mut input: &mut dyn Read = &mut input; + let mut grid = Vec::new(); + let mut line = [0; 10]; + input.read(&mut line); + let mut row = Vec::new(); + for c in &line { + row.push(square_from_char(*c as char)) + } + grid.push(row); + let width = grid[0].len(); + for row in &grid { assert_eq!(row.len(), width) } + grid +} + +mod test { + #[test] + pub fn trivial_to_string() { + assert_eq!(lambda.to_string(), "\\") + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29048.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29048.rs new file mode 100644 index 000000000000..02c21d97066d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29048.rs @@ -0,0 +1,13 @@ +// check-pass +pub struct Chan; +pub struct ChanSelect<'c, T> { + chans: Vec<(&'c Chan, T)>, +} +impl<'c, T> ChanSelect<'c, T> { + pub fn add_recv_ret(&mut self, chan: &'c Chan, ret: T) + { + self.chans.push((chan, ret)); + } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29053.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29053.rs new file mode 100644 index 000000000000..2e3472062daf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29053.rs @@ -0,0 +1,13 @@ +// run-pass +fn main() { + let x: &'static str = "x"; + + { + let y = "y".to_string(); + let ref mut x = &*x; + *x = &*y; + } + + assert_eq!(x, "x"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29071-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29071-2.rs new file mode 100644 index 000000000000..ca8eddb345cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29071-2.rs @@ -0,0 +1,33 @@ +// run-pass +#![allow(dead_code)] +fn t1() -> u32 { + let x; + x = if true { [1, 2, 3] } else { [2, 3, 4] }[0]; + x +} + +fn t2() -> [u32; 1] { + if true { [1, 2, 3]; } else { [2, 3, 4]; } + [0] +} + +fn t3() -> u32 { + let x; + x = if true { i1 as F } else { i2 as F }(); + x +} + +fn t4() -> () { + if true { i1 as F; } else { i2 as F; } + () +} + +type F = fn() -> u32; +fn i1() -> u32 { 1 } +fn i2() -> u32 { 2 } + +fn main() { + assert_eq!(t1(), 1); + assert_eq!(t3(), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29071.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29071.rs new file mode 100644 index 000000000000..cd885f81cdf5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29071.rs @@ -0,0 +1,17 @@ +// check-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +fn ret() -> u32 { + static x: u32 = 10; + x & if true { 10u32 } else { 20u32 } & x +} + +fn ret2() -> &'static u32 { + static x: u32 = 10; + if true { 10u32; } else { 20u32; } + &x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29084.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29084.rs new file mode 100644 index 000000000000..d358433c4a72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29084.rs @@ -0,0 +1,14 @@ +macro_rules! foo { + ($d:expr) => {{ + fn bar(d: u8) { } + bar(&mut $d); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + }} +} + +fn main() { + foo!(0u8); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29092.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29092.rs new file mode 100644 index 000000000000..b09f9bf2ee5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29092.rs @@ -0,0 +1,27 @@ +// run-pass +// Regression test for Issue #29092. +// +// (Possibly redundant with regression test run-pass/issue-30530.rs) + +use self::Term::*; + +#[derive(Clone)] +pub enum Term { + Dummy, + A(Box), + B(Box), +} + +// a small-step evaluator +pub fn small_eval(v: Term) -> Term { + match v { + A(t) => *t.clone(), + B(t) => *t.clone(), + _ => Dummy, + } +} + +fn main() { + small_eval(Dummy); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29124.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29124.rs new file mode 100644 index 000000000000..0c60bf478559 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29124.rs @@ -0,0 +1,20 @@ +struct Ret; +struct Obj; + +impl Obj { + fn func() -> Ret { + Ret + } +} + +fn func() -> Ret { + Ret +} + +fn main() { + Obj::func.x(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + func.x(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29147-rpass.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29147-rpass.rs new file mode 100644 index 000000000000..d741a0470727 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29147-rpass.rs @@ -0,0 +1,28 @@ +// run-pass +#![recursion_limit="1024"] + +use std::mem; + +pub struct S0(T,T); +pub struct S1(Option>>>,Option>>>); +pub struct S2(Option>>>,Option>>>); +pub struct S3(Option>>>,Option>>>); +pub struct S4(Option>>>,Option>>>); +pub struct S5(Option>>>,Option>>>,Option); + +trait Foo { fn xxx(&self); } +/// some local of #[fundamental] trait +trait Bar {} + +impl Foo for T where T: Bar, T: Sync { + fn xxx(&self) {} +} + +impl Foo for S5 { fn xxx(&self) {} } + +fn main() { + let s = S5(None,None,None); + s.xxx(); + assert_eq!(mem::size_of_val(&s.2), mem::size_of::>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29147.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29147.rs new file mode 100644 index 000000000000..95f109f49abb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29147.rs @@ -0,0 +1,23 @@ +#![recursion_limit="1024"] + +pub struct S0(T,T); +pub struct S1(Option>>>,Option>>>); +pub struct S2(Option>>>,Option>>>); +pub struct S3(Option>>>,Option>>>); +pub struct S4(Option>>>,Option>>>); +pub struct S5(Option>>>,Option>>>,Option); + +trait Foo { fn xxx(&self); } +trait Bar {} // anything local or #[fundamental] + +impl Foo for T where T: Bar, T: Sync { + fn xxx(&self) {} +} + +impl Foo for S5 { fn xxx(&self) {} } +impl Foo for S5 { fn xxx(&self) {} } + +fn main() { + let _ = >::xxx; // { dg-error ".E0283." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29161.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29161.rs new file mode 100644 index 000000000000..1a46f3558eed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29161.rs @@ -0,0 +1,16 @@ +mod a { + struct A; + + impl Default for A { + pub fn default() -> A { // { dg-error ".E0449." "" { target *-*-* } } + A + } + } +} + + +fn main() { + a::A::default(); +// { dg-error ".E0603." "" { target *-*-* } .-1 } + } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29166.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29166.rs new file mode 100644 index 000000000000..1f8c718945f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29166.rs @@ -0,0 +1,22 @@ +// run-pass +// This test ensures that vec.into_iter does not overconstrain element lifetime. + +pub fn main() { + original_report(); + revision_1(); + revision_2(); +} + +fn original_report() { + drop(vec![&()].into_iter()) +} + +fn revision_1() { + // below is what above `vec!` expands into at time of this writing. + drop(<[_]>::into_vec(::std::boxed::Box::new([&()])).into_iter()) +} + +fn revision_2() { + drop((match (Vec::new(), &()) { (mut v, b) => { v.push(b); v } }).into_iter()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29181.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29181.rs new file mode 100644 index 000000000000..dc1df5df9580 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29181.rs @@ -0,0 +1,10 @@ +// aux-build:issue-29181.rs + +extern crate issue_29181 as foo; + +fn main() { + 0.homura(); // { dg-error ".E0599." "" { target *-*-* } } + // Issue #47759, detect existing method on the fundamental impl: + let _ = |x: f64| x * 2.0.exp(); // { dg-error ".E0689." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29184.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29184.rs new file mode 100644 index 000000000000..7c6076008ad0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29184.rs @@ -0,0 +1,4 @@ +fn main() { + let x: typeof(92) = 92; // { dg-error ".E0516." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29227.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29227.rs new file mode 100644 index 000000000000..0999f74f142c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29227.rs @@ -0,0 +1,143 @@ +// run-pass +// ignore-tidy-linelength + +// Regression test for #29227. The problem here was that MIR +// construction for these gigantic match expressions was very +// inefficient. + +pub trait CharExt : Sized + Copy { + fn is_unicode_uppercase_letter(self) -> bool { false } + fn is_unicode_lowercase_letter(self) -> bool { false } + fn is_unicode_titlecase_letter(self) -> bool { false } + fn is_unicode_modifier_letter(self) -> bool { false } + fn is_unicode_other_letter(self) -> bool { false } + fn is_unicode_letter_number(self) -> bool { false } + fn is_unicode_nonspacing_mark(self) -> bool { false } + fn is_unicode_combining_spacing_mark(self) -> bool { false } + fn is_unicode_decimal_number(self) -> bool{ false } + fn is_unicode_connector_punctiation(self) -> bool { false } + fn is_unicode_space_separator(self) -> bool { false } + + fn is_es_identifier_start(self) -> bool { false } + fn is_es_identifier_part(self) -> bool { false } + fn is_es_whitespace(self) -> bool { false } + fn is_es_line_terminator(self) -> bool { false } + + fn is_unicode_letter(self) -> bool { + self.is_unicode_uppercase_letter() + || self.is_unicode_lowercase_letter() + || self.is_unicode_titlecase_letter() + || self.is_unicode_modifier_letter() + || self.is_unicode_modifier_letter() + || self.is_unicode_letter_number() + } + +} + + +macro_rules! match_char_class { + ($thing:expr, $($c:expr),*) => { + match $thing { + $($c)|* => true, + _ => false + } + } +} + +impl CharExt for char { + fn is_unicode_uppercase_letter(self) -> bool { + match_char_class!(self, + '\u{0041}', '\u{0042}', '\u{0043}', '\u{0044}', '\u{0045}', '\u{0046}', '\u{0047}', '\u{0048}', '\u{0049}', '\u{004A}', '\u{004B}', '\u{004C}', '\u{004D}', '\u{004E}', '\u{004F}', '\u{0050}', '\u{0051}', '\u{0052}', '\u{0053}', '\u{0054}', '\u{0055}', '\u{0056}', '\u{0057}', '\u{0058}', '\u{0059}', '\u{005A}', '\u{00C0}', '\u{00C1}', '\u{00C2}', '\u{00C3}', '\u{00C4}', '\u{00C5}', '\u{00C6}', '\u{00C7}', '\u{00C8}', '\u{00C9}', '\u{00CA}', '\u{00CB}', '\u{00CC}', '\u{00CD}', '\u{00CE}', '\u{00CF}', '\u{00D0}', '\u{00D1}', '\u{00D2}', '\u{00D3}', '\u{00D4}', '\u{00D5}', '\u{00D6}', '\u{00D8}', '\u{00D9}', '\u{00DA}', '\u{00DB}', '\u{00DC}', '\u{00DD}', '\u{00DE}', '\u{0100}', '\u{0102}', '\u{0104}', '\u{0106}', '\u{0108}', '\u{010A}', '\u{010C}', '\u{010E}', '\u{0110}', '\u{0112}', '\u{0114}', '\u{0116}', '\u{0118}', '\u{011A}', '\u{011C}', '\u{011E}', '\u{0120}', '\u{0122}', '\u{0124}', '\u{0126}', '\u{0128}', '\u{012A}', '\u{012C}', '\u{012E}', '\u{0130}', '\u{0132}', '\u{0134}', '\u{0136}', '\u{0139}', '\u{013B}', '\u{013D}', '\u{013F}', '\u{0141}', '\u{0143}', '\u{0145}', '\u{0147}', '\u{014A}', '\u{014C}', '\u{014E}', '\u{0150}', '\u{0152}', '\u{0154}', '\u{0156}', '\u{0158}', '\u{015A}', '\u{015C}', '\u{015E}', '\u{0160}', '\u{0162}', '\u{0164}', '\u{0166}', '\u{0168}', '\u{016A}', '\u{016C}', '\u{016E}', '\u{0170}', '\u{0172}', '\u{0174}', '\u{0176}', '\u{0178}', '\u{0179}', '\u{017B}', '\u{017D}', '\u{0181}', '\u{0182}', '\u{0184}', '\u{0186}', '\u{0187}', '\u{0189}', '\u{018A}', '\u{018B}', '\u{018E}', '\u{018F}', '\u{0190}', '\u{0191}', '\u{0193}', '\u{0194}', '\u{0196}', '\u{0197}', '\u{0198}', '\u{019C}', '\u{019D}', '\u{019F}', '\u{01A0}', '\u{01A2}', '\u{01A4}', '\u{01A6}', '\u{01A7}', '\u{01A9}', '\u{01AC}', '\u{01AE}', '\u{01AF}', '\u{01B1}', '\u{01B2}', '\u{01B3}', '\u{01B5}', '\u{01B7}', '\u{01B8}', '\u{01BC}', '\u{01C4}', '\u{01C7}', '\u{01CA}', '\u{01CD}', '\u{01CF}', '\u{01D1}', '\u{01D3}', '\u{01D5}', '\u{01D7}', '\u{01D9}', '\u{01DB}', '\u{01DE}', '\u{01E0}', '\u{01E2}', '\u{01E4}', '\u{01E6}', '\u{01E8}', '\u{01EA}', '\u{01EC}', '\u{01EE}', '\u{01F1}', '\u{01F4}', '\u{01F6}', '\u{01F7}', '\u{01F8}', '\u{01FA}', '\u{01FC}', '\u{01FE}', '\u{0200}', '\u{0202}', '\u{0204}', '\u{0206}', '\u{0208}', '\u{020A}', '\u{020C}', '\u{020E}', '\u{0210}', '\u{0212}', '\u{0214}', '\u{0216}', '\u{0218}', '\u{021A}', '\u{021C}', '\u{021E}', '\u{0220}', '\u{0222}', '\u{0224}', '\u{0226}', '\u{0228}', '\u{022A}', '\u{022C}', '\u{022E}', '\u{0230}', '\u{0232}', '\u{023A}', '\u{023B}', '\u{023D}', '\u{023E}', '\u{0241}', '\u{0243}', '\u{0244}', '\u{0245}', '\u{0246}', '\u{0248}', '\u{024A}', '\u{024C}', '\u{024E}', '\u{0370}', '\u{0372}', '\u{0376}', '\u{0386}', '\u{0388}', '\u{0389}', '\u{038A}', '\u{038C}', '\u{038E}', '\u{038F}', '\u{0391}', '\u{0392}', '\u{0393}', '\u{0394}', '\u{0395}', '\u{0396}', '\u{0397}', '\u{0398}', '\u{0399}', '\u{039A}', '\u{039B}', '\u{039C}', '\u{039D}', '\u{039E}', '\u{039F}', '\u{03A0}', '\u{03A1}', '\u{03A3}', '\u{03A4}', '\u{03A5}', '\u{03A6}', '\u{03A7}', '\u{03A8}', '\u{03A9}', '\u{03AA}', '\u{03AB}', '\u{03CF}', '\u{03D2}', '\u{03D3}', '\u{03D4}', '\u{03D8}', '\u{03DA}', '\u{03DC}', '\u{03DE}', '\u{03E0}', '\u{03E2}', '\u{03E4}', '\u{03E6}', '\u{03E8}', '\u{03EA}', '\u{03EC}', '\u{03EE}', '\u{03F4}', '\u{03F7}', '\u{03F9}', '\u{03FA}', '\u{03FD}', '\u{03FE}', '\u{03FF}', '\u{0400}', '\u{0401}', '\u{0402}', '\u{0403}', '\u{0404}', '\u{0405}', '\u{0406}', '\u{0407}', '\u{0408}', '\u{0409}', '\u{040A}', '\u{040B}', '\u{040C}', '\u{040D}', '\u{040E}', '\u{040F}', '\u{0410}', '\u{0411}', '\u{0412}', '\u{0413}', '\u{0414}', '\u{0415}', '\u{0416}', '\u{0417}', '\u{0418}', '\u{0419}', '\u{041A}', '\u{041B}', '\u{041C}', '\u{041D}', '\u{041E}', '\u{041F}', '\u{0420}', '\u{0421}', '\u{0422}', '\u{0423}', '\u{0424}', '\u{0425}', '\u{0426}', '\u{0427}', '\u{0428}', '\u{0429}', '\u{042A}', '\u{042B}', '\u{042C}', '\u{042D}', '\u{042E}', '\u{042F}', '\u{0460}', '\u{0462}', '\u{0464}', '\u{0466}', '\u{0468}', '\u{046A}', '\u{046C}', '\u{046E}', '\u{0470}', '\u{0472}', '\u{0474}', '\u{0476}', '\u{0478}', '\u{047A}', '\u{047C}', '\u{047E}', '\u{0480}', '\u{048A}', '\u{048C}', '\u{048E}', '\u{0490}', '\u{0492}', '\u{0494}', '\u{0496}', '\u{0498}', '\u{049A}', '\u{049C}', '\u{049E}', '\u{04A0}', '\u{04A2}', '\u{04A4}', '\u{04A6}', '\u{04A8}', '\u{04AA}', '\u{04AC}', '\u{04AE}', '\u{04B0}', '\u{04B2}', '\u{04B4}', '\u{04B6}', '\u{04B8}', '\u{04BA}', '\u{04BC}', '\u{04BE}', '\u{04C0}', '\u{04C1}', '\u{04C3}', '\u{04C5}', '\u{04C7}', '\u{04C9}', '\u{04CB}', '\u{04CD}', '\u{04D0}', '\u{04D2}', '\u{04D4}', '\u{04D6}', '\u{04D8}', '\u{04DA}', '\u{04DC}', '\u{04DE}', '\u{04E0}', '\u{04E2}', '\u{04E4}', '\u{04E6}', '\u{04E8}', '\u{04EA}', '\u{04EC}', '\u{04EE}', '\u{04F0}', '\u{04F2}', '\u{04F4}', '\u{04F6}', '\u{04F8}', '\u{04FA}', '\u{04FC}', '\u{04FE}', '\u{0500}', '\u{0502}', '\u{0504}', '\u{0506}', '\u{0508}', '\u{050A}', '\u{050C}', '\u{050E}', '\u{0510}', '\u{0512}', '\u{0514}', '\u{0516}', '\u{0518}', '\u{051A}', '\u{051C}', '\u{051E}', '\u{0520}', '\u{0522}', '\u{0531}', '\u{0532}', '\u{0533}', '\u{0534}', '\u{0535}', '\u{0536}', '\u{0537}', '\u{0538}', '\u{0539}', '\u{053A}', '\u{053B}', '\u{053C}', '\u{053D}', '\u{053E}', '\u{053F}', '\u{0540}', '\u{0541}', '\u{0542}', '\u{0543}', '\u{0544}', '\u{0545}', '\u{0546}', '\u{0547}', '\u{0548}', '\u{0549}', '\u{054A}', '\u{054B}', '\u{054C}', '\u{054D}', '\u{054E}', '\u{054F}', '\u{0550}', '\u{0551}', '\u{0552}', '\u{0553}', '\u{0554}', '\u{0555}', '\u{0556}', '\u{10A0}', '\u{10A1}', '\u{10A2}', '\u{10A3}', '\u{10A4}', '\u{10A5}', '\u{10A6}', '\u{10A7}', '\u{10A8}', '\u{10A9}', '\u{10AA}', '\u{10AB}', '\u{10AC}', '\u{10AD}', '\u{10AE}', '\u{10AF}', '\u{10B0}', '\u{10B1}', '\u{10B2}', '\u{10B3}', '\u{10B4}', '\u{10B5}', '\u{10B6}', '\u{10B7}', '\u{10B8}', '\u{10B9}', '\u{10BA}', '\u{10BB}', '\u{10BC}', '\u{10BD}', '\u{10BE}', '\u{10BF}', '\u{10C0}', '\u{10C1}', '\u{10C2}', '\u{10C3}', '\u{10C4}', '\u{10C5}', '\u{1E00}', '\u{1E02}', '\u{1E04}', '\u{1E06}', '\u{1E08}', '\u{1E0A}', '\u{1E0C}', '\u{1E0E}', '\u{1E10}', '\u{1E12}', '\u{1E14}', '\u{1E16}', '\u{1E18}', '\u{1E1A}', '\u{1E1C}', '\u{1E1E}', '\u{1E20}', '\u{1E22}', '\u{1E24}', '\u{1E26}', '\u{1E28}', '\u{1E2A}', '\u{1E2C}', '\u{1E2E}', '\u{1E30}', '\u{1E32}', '\u{1E34}', '\u{1E36}', '\u{1E38}', '\u{1E3A}', '\u{1E3C}', '\u{1E3E}', '\u{1E40}', '\u{1E42}', '\u{1E44}', '\u{1E46}', '\u{1E48}', '\u{1E4A}', '\u{1E4C}', '\u{1E4E}', '\u{1E50}', '\u{1E52}', '\u{1E54}', '\u{1E56}', '\u{1E58}', '\u{1E5A}', '\u{1E5C}', '\u{1E5E}', '\u{1E60}', '\u{1E62}', '\u{1E64}', '\u{1E66}', '\u{1E68}', '\u{1E6A}', '\u{1E6C}', '\u{1E6E}', '\u{1E70}', '\u{1E72}', '\u{1E74}', '\u{1E76}', '\u{1E78}', '\u{1E7A}', '\u{1E7C}', '\u{1E7E}', '\u{1E80}', '\u{1E82}', '\u{1E84}', '\u{1E86}', '\u{1E88}', '\u{1E8A}', '\u{1E8C}', '\u{1E8E}', '\u{1E90}', '\u{1E92}', '\u{1E94}', '\u{1E9E}', '\u{1EA0}', '\u{1EA2}', '\u{1EA4}', '\u{1EA6}', '\u{1EA8}', '\u{1EAA}', '\u{1EAC}', '\u{1EAE}', '\u{1EB0}', '\u{1EB2}', '\u{1EB4}', '\u{1EB6}', '\u{1EB8}', '\u{1EBA}', '\u{1EBC}', '\u{1EBE}', '\u{1EC0}', '\u{1EC2}', '\u{1EC4}', '\u{1EC6}', '\u{1EC8}', '\u{1ECA}', '\u{1ECC}', '\u{1ECE}', '\u{1ED0}', '\u{1ED2}', '\u{1ED4}', '\u{1ED6}', '\u{1ED8}', '\u{1EDA}', '\u{1EDC}', '\u{1EDE}', '\u{1EE0}', '\u{1EE2}', '\u{1EE4}', '\u{1EE6}', '\u{1EE8}', '\u{1EEA}', '\u{1EEC}', '\u{1EEE}', '\u{1EF0}', '\u{1EF2}', '\u{1EF4}', '\u{1EF6}', '\u{1EF8}', '\u{1EFA}', '\u{1EFC}', '\u{1EFE}', '\u{1F08}', '\u{1F09}', '\u{1F0A}', '\u{1F0B}', '\u{1F0C}', '\u{1F0D}', '\u{1F0E}', '\u{1F0F}', '\u{1F18}', '\u{1F19}', '\u{1F1A}', '\u{1F1B}', '\u{1F1C}', '\u{1F1D}', '\u{1F28}', '\u{1F29}', '\u{1F2A}', '\u{1F2B}', '\u{1F2C}', '\u{1F2D}', '\u{1F2E}', '\u{1F2F}', '\u{1F38}', '\u{1F39}', '\u{1F3A}', '\u{1F3B}', '\u{1F3C}', '\u{1F3D}', '\u{1F3E}', '\u{1F3F}', '\u{1F48}', '\u{1F49}', '\u{1F4A}', '\u{1F4B}', '\u{1F4C}', '\u{1F4D}', '\u{1F59}', '\u{1F5B}', '\u{1F5D}', '\u{1F5F}', '\u{1F68}', '\u{1F69}', '\u{1F6A}', '\u{1F6B}', '\u{1F6C}', '\u{1F6D}', '\u{1F6E}', '\u{1F6F}', '\u{1FB8}', '\u{1FB9}', '\u{1FBA}', '\u{1FBB}', '\u{1FC8}', '\u{1FC9}', '\u{1FCA}', '\u{1FCB}', '\u{1FD8}', '\u{1FD9}', '\u{1FDA}', '\u{1FDB}', '\u{1FE8}', '\u{1FE9}', '\u{1FEA}', '\u{1FEB}', '\u{1FEC}', '\u{1FF8}', '\u{1FF9}', '\u{1FFA}', '\u{1FFB}', '\u{2102}', '\u{2107}', '\u{210B}', '\u{210C}', '\u{210D}', '\u{2110}', '\u{2111}', '\u{2112}', '\u{2115}', '\u{2119}', '\u{211A}', '\u{211B}', '\u{211C}', '\u{211D}', '\u{2124}', '\u{2126}', '\u{2128}', '\u{212A}', '\u{212B}', '\u{212C}', '\u{212D}', '\u{2130}', '\u{2131}', '\u{2132}', '\u{2133}', '\u{213E}', '\u{213F}', '\u{2145}', '\u{2183}', '\u{2C00}', '\u{2C01}', '\u{2C02}', '\u{2C03}', '\u{2C04}', '\u{2C05}', '\u{2C06}', '\u{2C07}', '\u{2C08}', '\u{2C09}', '\u{2C0A}', '\u{2C0B}', '\u{2C0C}', '\u{2C0D}', '\u{2C0E}', '\u{2C0F}', '\u{2C10}', '\u{2C11}', '\u{2C12}', '\u{2C13}', '\u{2C14}', '\u{2C15}', '\u{2C16}', '\u{2C17}', '\u{2C18}', '\u{2C19}', '\u{2C1A}', '\u{2C1B}', '\u{2C1C}', '\u{2C1D}', '\u{2C1E}', '\u{2C1F}', '\u{2C20}', '\u{2C21}', '\u{2C22}', '\u{2C23}', '\u{2C24}', '\u{2C25}', '\u{2C26}', '\u{2C27}', '\u{2C28}', '\u{2C29}', '\u{2C2A}', '\u{2C2B}', '\u{2C2C}', '\u{2C2D}', '\u{2C2E}', '\u{2C60}', '\u{2C62}', '\u{2C63}', '\u{2C64}', '\u{2C67}', '\u{2C69}', '\u{2C6B}', '\u{2C6D}', '\u{2C6E}', '\u{2C6F}', '\u{2C72}', '\u{2C75}', '\u{2C80}', '\u{2C82}', '\u{2C84}', '\u{2C86}', '\u{2C88}', '\u{2C8A}', '\u{2C8C}', '\u{2C8E}', '\u{2C90}', '\u{2C92}', '\u{2C94}', '\u{2C96}', '\u{2C98}', '\u{2C9A}', '\u{2C9C}', '\u{2C9E}', '\u{2CA0}', '\u{2CA2}', '\u{2CA4}', '\u{2CA6}', '\u{2CA8}', '\u{2CAA}', '\u{2CAC}', '\u{2CAE}', '\u{2CB0}', '\u{2CB2}', '\u{2CB4}', '\u{2CB6}', '\u{2CB8}', '\u{2CBA}', '\u{2CBC}', '\u{2CBE}', '\u{2CC0}', '\u{2CC2}', '\u{2CC4}', '\u{2CC6}', '\u{2CC8}', '\u{2CCA}', '\u{2CCC}', '\u{2CCE}', '\u{2CD0}', '\u{2CD2}', '\u{2CD4}', '\u{2CD6}', '\u{2CD8}', '\u{2CDA}', '\u{2CDC}', '\u{2CDE}', '\u{2CE0}', '\u{2CE2}', '\u{A640}', '\u{A642}', '\u{A644}', '\u{A646}', '\u{A648}', '\u{A64A}', '\u{A64C}', '\u{A64E}', '\u{A650}', '\u{A652}', '\u{A654}', '\u{A656}', '\u{A658}', '\u{A65A}', '\u{A65C}', '\u{A65E}', '\u{A662}', '\u{A664}', '\u{A666}', '\u{A668}', '\u{A66A}', '\u{A66C}', '\u{A680}', '\u{A682}', '\u{A684}', '\u{A686}', '\u{A688}', '\u{A68A}', '\u{A68C}', '\u{A68E}', '\u{A690}', '\u{A692}', '\u{A694}', '\u{A696}', '\u{A722}', '\u{A724}', '\u{A726}', '\u{A728}', '\u{A72A}', '\u{A72C}', '\u{A72E}', '\u{A732}', '\u{A734}', '\u{A736}', '\u{A738}', '\u{A73A}', '\u{A73C}', '\u{A73E}', '\u{A740}', '\u{A742}', '\u{A744}', '\u{A746}', '\u{A748}', '\u{A74A}', '\u{A74C}', '\u{A74E}', '\u{A750}', '\u{A752}', '\u{A754}', '\u{A756}', '\u{A758}', '\u{A75A}', '\u{A75C}', '\u{A75E}', '\u{A760}', '\u{A762}', '\u{A764}', '\u{A766}', '\u{A768}', '\u{A76A}', '\u{A76C}', '\u{A76E}', '\u{A779}', '\u{A77B}', '\u{A77D}', '\u{A77E}', '\u{A780}', '\u{A782}', '\u{A784}', '\u{A786}', '\u{A78B}', '\u{FF21}', '\u{FF22}', '\u{FF23}', '\u{FF24}', '\u{FF25}', '\u{FF26}', '\u{FF27}', '\u{FF28}', '\u{FF29}', '\u{FF2A}', '\u{FF2B}', '\u{FF2C}', '\u{FF2D}', '\u{FF2E}', '\u{FF2F}', '\u{FF30}', '\u{FF31}', '\u{FF32}', '\u{FF33}', '\u{FF34}', '\u{FF35}', '\u{FF36}', '\u{FF37}', '\u{FF38}', '\u{FF39}', '\u{FF3A}') + } + + fn is_unicode_lowercase_letter(self) -> bool { + match_char_class!(self, + '\u{0061}', '\u{0062}', '\u{0063}', '\u{0064}', '\u{0065}', '\u{0066}', '\u{0067}', '\u{0068}', '\u{0069}', '\u{006A}', '\u{006B}', '\u{006C}', '\u{006D}', '\u{006E}', '\u{006F}', '\u{0070}', '\u{0071}', '\u{0072}', '\u{0073}', '\u{0074}', '\u{0075}', '\u{0076}', '\u{0077}', '\u{0078}', '\u{0079}', '\u{007A}', '\u{00AA}', '\u{00B5}', '\u{00BA}', '\u{00DF}', '\u{00E0}', '\u{00E1}', '\u{00E2}', '\u{00E3}', '\u{00E4}', '\u{00E5}', '\u{00E6}', '\u{00E7}', '\u{00E8}', '\u{00E9}', '\u{00EA}', '\u{00EB}', '\u{00EC}', '\u{00ED}', '\u{00EE}', '\u{00EF}', '\u{00F0}', '\u{00F1}', '\u{00F2}', '\u{00F3}', '\u{00F4}', '\u{00F5}', '\u{00F6}', '\u{00F8}', '\u{00F9}', '\u{00FA}', '\u{00FB}', '\u{00FC}', '\u{00FD}', '\u{00FE}', '\u{00FF}', '\u{0101}', '\u{0103}', '\u{0105}', '\u{0107}', '\u{0109}', '\u{010B}', '\u{010D}', '\u{010F}', '\u{0111}', '\u{0113}', '\u{0115}', '\u{0117}', '\u{0119}', '\u{011B}', '\u{011D}', '\u{011F}', '\u{0121}', '\u{0123}', '\u{0125}', '\u{0127}', '\u{0129}', '\u{012B}', '\u{012D}', '\u{012F}', '\u{0131}', '\u{0133}', '\u{0135}', '\u{0137}', '\u{0138}', '\u{013A}', '\u{013C}', '\u{013E}', '\u{0140}', '\u{0142}', '\u{0144}', '\u{0146}', '\u{0148}', '\u{0149}', '\u{014B}', '\u{014D}', '\u{014F}', '\u{0151}', '\u{0153}', '\u{0155}', '\u{0157}', '\u{0159}', '\u{015B}', '\u{015D}', '\u{015F}', '\u{0161}', '\u{0163}', '\u{0165}', '\u{0167}', '\u{0169}', '\u{016B}', '\u{016D}', '\u{016F}', '\u{0171}', '\u{0173}', '\u{0175}', '\u{0177}', '\u{017A}', '\u{017C}', '\u{017E}', '\u{017F}', '\u{0180}', '\u{0183}', '\u{0185}', '\u{0188}', '\u{018C}', '\u{018D}', '\u{0192}', '\u{0195}', '\u{0199}', '\u{019A}', '\u{019B}', '\u{019E}', '\u{01A1}', '\u{01A3}', '\u{01A5}', '\u{01A8}', '\u{01AA}', '\u{01AB}', '\u{01AD}', '\u{01B0}', '\u{01B4}', '\u{01B6}', '\u{01B9}', '\u{01BA}', '\u{01BD}', '\u{01BE}', '\u{01BF}', '\u{01C6}', '\u{01C9}', '\u{01CC}', '\u{01CE}', '\u{01D0}', '\u{01D2}', '\u{01D4}', '\u{01D6}', '\u{01D8}', '\u{01DA}', '\u{01DC}', '\u{01DD}', '\u{01DF}', '\u{01E1}', '\u{01E3}', '\u{01E5}', '\u{01E7}', '\u{01E9}', '\u{01EB}', '\u{01ED}', '\u{01EF}', '\u{01F0}', '\u{01F3}', '\u{01F5}', '\u{01F9}', '\u{01FB}', '\u{01FD}', '\u{01FF}', '\u{0201}', '\u{0203}', '\u{0205}', '\u{0207}', '\u{0209}', '\u{020B}', '\u{020D}', '\u{020F}', '\u{0211}', '\u{0213}', '\u{0215}', '\u{0217}', '\u{0219}', '\u{021B}', '\u{021D}', '\u{021F}', '\u{0221}', '\u{0223}', '\u{0225}', '\u{0227}', '\u{0229}', '\u{022B}', '\u{022D}', '\u{022F}', '\u{0231}', '\u{0233}', '\u{0234}', '\u{0235}', '\u{0236}', '\u{0237}', '\u{0238}', '\u{0239}', '\u{023C}', '\u{023F}', '\u{0240}', '\u{0242}', '\u{0247}', '\u{0249}', '\u{024B}', '\u{024D}', '\u{024F}', '\u{0250}', '\u{0251}', '\u{0252}', '\u{0253}', '\u{0254}', '\u{0255}', '\u{0256}', '\u{0257}', '\u{0258}', '\u{0259}', '\u{025A}', '\u{025B}', '\u{025C}', '\u{025D}', '\u{025E}', '\u{025F}', '\u{0260}', '\u{0261}', '\u{0262}', '\u{0263}', '\u{0264}', '\u{0265}', '\u{0266}', '\u{0267}', '\u{0268}', '\u{0269}', '\u{026A}', '\u{026B}', '\u{026C}', '\u{026D}', '\u{026E}', '\u{026F}', '\u{0270}', '\u{0271}', '\u{0272}', '\u{0273}', '\u{0274}', '\u{0275}', '\u{0276}', '\u{0277}', '\u{0278}', '\u{0279}', '\u{027A}', '\u{027B}', '\u{027C}', '\u{027D}', '\u{027E}', '\u{027F}', '\u{0280}', '\u{0281}', '\u{0282}', '\u{0283}', '\u{0284}', '\u{0285}', '\u{0286}', '\u{0287}', '\u{0288}', '\u{0289}', '\u{028A}', '\u{028B}', '\u{028C}', '\u{028D}', '\u{028E}', '\u{028F}', '\u{0290}', '\u{0291}', '\u{0292}', '\u{0293}', '\u{0295}', '\u{0296}', '\u{0297}', '\u{0298}', '\u{0299}', '\u{029A}', '\u{029B}', '\u{029C}', '\u{029D}', '\u{029E}', '\u{029F}', '\u{02A0}', '\u{02A1}', '\u{02A2}', '\u{02A3}', '\u{02A4}', '\u{02A5}', '\u{02A6}', '\u{02A7}', '\u{02A8}', '\u{02A9}', '\u{02AA}', '\u{02AB}', '\u{02AC}', '\u{02AD}', '\u{02AE}', '\u{02AF}', '\u{0371}', '\u{0373}', '\u{0377}', '\u{037B}', '\u{037C}', '\u{037D}', '\u{0390}', '\u{03AC}', '\u{03AD}', '\u{03AE}', '\u{03AF}', '\u{03B0}', '\u{03B1}', '\u{03B2}', '\u{03B3}', '\u{03B4}', '\u{03B5}', '\u{03B6}', '\u{03B7}', '\u{03B8}', '\u{03B9}', '\u{03BA}', '\u{03BB}', '\u{03BC}', '\u{03BD}', '\u{03BE}', '\u{03BF}', '\u{03C0}', '\u{03C1}', '\u{03C2}', '\u{03C3}', '\u{03C4}', '\u{03C5}', '\u{03C6}', '\u{03C7}', '\u{03C8}', '\u{03C9}', '\u{03CA}', '\u{03CB}', '\u{03CC}', '\u{03CD}', '\u{03CE}', '\u{03D0}', '\u{03D1}', '\u{03D5}', '\u{03D6}', '\u{03D7}', '\u{03D9}', '\u{03DB}', '\u{03DD}', '\u{03DF}', '\u{03E1}', '\u{03E3}', '\u{03E5}', '\u{03E7}', '\u{03E9}', '\u{03EB}', '\u{03ED}', '\u{03EF}', '\u{03F0}', '\u{03F1}', '\u{03F2}', '\u{03F3}', '\u{03F5}', '\u{03F8}', '\u{03FB}', '\u{03FC}', '\u{0430}', '\u{0431}', '\u{0432}', '\u{0433}', '\u{0434}', '\u{0435}', '\u{0436}', '\u{0437}', '\u{0438}', '\u{0439}', '\u{043A}', '\u{043B}', '\u{043C}', '\u{043D}', '\u{043E}', '\u{043F}', '\u{0440}', '\u{0441}', '\u{0442}', '\u{0443}', '\u{0444}', '\u{0445}', '\u{0446}', '\u{0447}', '\u{0448}', '\u{0449}', '\u{044A}', '\u{044B}', '\u{044C}', '\u{044D}', '\u{044E}', '\u{044F}', '\u{0450}', '\u{0451}', '\u{0452}', '\u{0453}', '\u{0454}', '\u{0455}', '\u{0456}', '\u{0457}', '\u{0458}', '\u{0459}', '\u{045A}', '\u{045B}', '\u{045C}', '\u{045D}', '\u{045E}', '\u{045F}', '\u{0461}', '\u{0463}', '\u{0465}', '\u{0467}', '\u{0469}', '\u{046B}', '\u{046D}', '\u{046F}', '\u{0471}', '\u{0473}', '\u{0475}', '\u{0477}', '\u{0479}', '\u{047B}', '\u{047D}', '\u{047F}', '\u{0481}', '\u{048B}', '\u{048D}', '\u{048F}', '\u{0491}', '\u{0493}', '\u{0495}', '\u{0497}', '\u{0499}', '\u{049B}', '\u{049D}', '\u{049F}', '\u{04A1}', '\u{04A3}', '\u{04A5}', '\u{04A7}', '\u{04A9}', '\u{04AB}', '\u{04AD}', '\u{04AF}', '\u{04B1}', '\u{04B3}', '\u{04B5}', '\u{04B7}', '\u{04B9}', '\u{04BB}', '\u{04BD}', '\u{04BF}', '\u{04C2}', '\u{04C4}', '\u{04C6}', '\u{04C8}', '\u{04CA}', '\u{04CC}', '\u{04CE}', '\u{04CF}', '\u{04D1}', '\u{04D3}', '\u{04D5}', '\u{04D7}', '\u{04D9}', '\u{04DB}', '\u{04DD}', '\u{04DF}', '\u{04E1}', '\u{04E3}', '\u{04E5}', '\u{04E7}', '\u{04E9}', '\u{04EB}', '\u{04ED}', '\u{04EF}', '\u{04F1}', '\u{04F3}', '\u{04F5}', '\u{04F7}', '\u{04F9}', '\u{04FB}', '\u{04FD}', '\u{04FF}', '\u{0501}', '\u{0503}', '\u{0505}', '\u{0507}', '\u{0509}', '\u{050B}', '\u{050D}', '\u{050F}', '\u{0511}', '\u{0513}', '\u{0515}', '\u{0517}', '\u{0519}', '\u{051B}', '\u{051D}', '\u{051F}', '\u{0521}', '\u{0523}', '\u{0561}', '\u{0562}', '\u{0563}', '\u{0564}', '\u{0565}', '\u{0566}', '\u{0567}', '\u{0568}', '\u{0569}', '\u{056A}', '\u{056B}', '\u{056C}', '\u{056D}', '\u{056E}', '\u{056F}', '\u{0570}', '\u{0571}', '\u{0572}', '\u{0573}', '\u{0574}', '\u{0575}', '\u{0576}', '\u{0577}', '\u{0578}', '\u{0579}', '\u{057A}', '\u{057B}', '\u{057C}', '\u{057D}', '\u{057E}', '\u{057F}', '\u{0580}', '\u{0581}', '\u{0582}', '\u{0583}', '\u{0584}', '\u{0585}', '\u{0586}', '\u{0587}', '\u{1D00}', '\u{1D01}', '\u{1D02}', '\u{1D03}', '\u{1D04}', '\u{1D05}', '\u{1D06}', '\u{1D07}', '\u{1D08}', '\u{1D09}', '\u{1D0A}', '\u{1D0B}', '\u{1D0C}', '\u{1D0D}', '\u{1D0E}', '\u{1D0F}', '\u{1D10}', '\u{1D11}', '\u{1D12}', '\u{1D13}', '\u{1D14}', '\u{1D15}', '\u{1D16}', '\u{1D17}', '\u{1D18}', '\u{1D19}', '\u{1D1A}', '\u{1D1B}', '\u{1D1C}', '\u{1D1D}', '\u{1D1E}', '\u{1D1F}', '\u{1D20}', '\u{1D21}', '\u{1D22}', '\u{1D23}', '\u{1D24}', '\u{1D25}', '\u{1D26}', '\u{1D27}', '\u{1D28}', '\u{1D29}', '\u{1D2A}', '\u{1D2B}', '\u{1D62}', '\u{1D63}', '\u{1D64}', '\u{1D65}', '\u{1D66}', '\u{1D67}', '\u{1D68}', '\u{1D69}', '\u{1D6A}', '\u{1D6B}', '\u{1D6C}', '\u{1D6D}', '\u{1D6E}', '\u{1D6F}', '\u{1D70}', '\u{1D71}', '\u{1D72}', '\u{1D73}', '\u{1D74}', '\u{1D75}', '\u{1D76}', '\u{1D77}', '\u{1D79}', '\u{1D7A}', '\u{1D7B}', '\u{1D7C}', '\u{1D7D}', '\u{1D7E}', '\u{1D7F}', '\u{1D80}', '\u{1D81}', '\u{1D82}', '\u{1D83}', '\u{1D84}', '\u{1D85}', '\u{1D86}', '\u{1D87}', '\u{1D88}', '\u{1D89}', '\u{1D8A}', '\u{1D8B}', '\u{1D8C}', '\u{1D8D}', '\u{1D8E}', '\u{1D8F}', '\u{1D90}', '\u{1D91}', '\u{1D92}', '\u{1D93}', '\u{1D94}', '\u{1D95}', '\u{1D96}', '\u{1D97}', '\u{1D98}', '\u{1D99}', '\u{1D9A}', '\u{1E01}', '\u{1E03}', '\u{1E05}', '\u{1E07}', '\u{1E09}', '\u{1E0B}', '\u{1E0D}', '\u{1E0F}', '\u{1E11}', '\u{1E13}', '\u{1E15}', '\u{1E17}', '\u{1E19}', '\u{1E1B}', '\u{1E1D}', '\u{1E1F}', '\u{1E21}', '\u{1E23}', '\u{1E25}', '\u{1E27}', '\u{1E29}', '\u{1E2B}', '\u{1E2D}', '\u{1E2F}', '\u{1E31}', '\u{1E33}', '\u{1E35}', '\u{1E37}', '\u{1E39}', '\u{1E3B}', '\u{1E3D}', '\u{1E3F}', '\u{1E41}', '\u{1E43}', '\u{1E45}', '\u{1E47}', '\u{1E49}', '\u{1E4B}', '\u{1E4D}', '\u{1E4F}', '\u{1E51}', '\u{1E53}', '\u{1E55}', '\u{1E57}', '\u{1E59}', '\u{1E5B}', '\u{1E5D}', '\u{1E5F}', '\u{1E61}', '\u{1E63}', '\u{1E65}', '\u{1E67}', '\u{1E69}', '\u{1E6B}', '\u{1E6D}', '\u{1E6F}', '\u{1E71}', '\u{1E73}', '\u{1E75}', '\u{1E77}', '\u{1E79}', '\u{1E7B}', '\u{1E7D}', '\u{1E7F}', '\u{1E81}', '\u{1E83}', '\u{1E85}', '\u{1E87}', '\u{1E89}', '\u{1E8B}', '\u{1E8D}', '\u{1E8F}', '\u{1E91}', '\u{1E93}', '\u{1E95}', '\u{1E96}', '\u{1E97}', '\u{1E98}', '\u{1E99}', '\u{1E9A}', '\u{1E9B}', '\u{1E9C}', '\u{1E9D}', '\u{1E9F}', '\u{1EA1}', '\u{1EA3}', '\u{1EA5}', '\u{1EA7}', '\u{1EA9}', '\u{1EAB}', '\u{1EAD}', '\u{1EAF}', '\u{1EB1}', '\u{1EB3}', '\u{1EB5}', '\u{1EB7}', '\u{1EB9}', '\u{1EBB}', '\u{1EBD}', '\u{1EBF}', '\u{1EC1}', '\u{1EC3}', '\u{1EC5}', '\u{1EC7}', '\u{1EC9}', '\u{1ECB}', '\u{1ECD}', '\u{1ECF}', '\u{1ED1}', '\u{1ED3}', '\u{1ED5}', '\u{1ED7}', '\u{1ED9}', '\u{1EDB}', '\u{1EDD}', '\u{1EDF}', '\u{1EE1}', '\u{1EE3}', '\u{1EE5}', '\u{1EE7}', '\u{1EE9}', '\u{1EEB}', '\u{1EED}', '\u{1EEF}', '\u{1EF1}', '\u{1EF3}', '\u{1EF5}', '\u{1EF7}', '\u{1EF9}', '\u{1EFB}', '\u{1EFD}', '\u{1EFF}', '\u{1F00}', '\u{1F01}', '\u{1F02}', '\u{1F03}', '\u{1F04}', '\u{1F05}', '\u{1F06}', '\u{1F07}', '\u{1F10}', '\u{1F11}', '\u{1F12}', '\u{1F13}', '\u{1F14}', '\u{1F15}', '\u{1F20}', '\u{1F21}', '\u{1F22}', '\u{1F23}', '\u{1F24}', '\u{1F25}', '\u{1F26}', '\u{1F27}', '\u{1F30}', '\u{1F31}', '\u{1F32}', '\u{1F33}', '\u{1F34}', '\u{1F35}', '\u{1F36}', '\u{1F37}', '\u{1F40}', '\u{1F41}', '\u{1F42}', '\u{1F43}', '\u{1F44}', '\u{1F45}', '\u{1F50}', '\u{1F51}', '\u{1F52}', '\u{1F53}', '\u{1F54}', '\u{1F55}', '\u{1F56}', '\u{1F57}', '\u{1F60}', '\u{1F61}', '\u{1F62}', '\u{1F63}', '\u{1F64}', '\u{1F65}', '\u{1F66}', '\u{1F67}', '\u{1F70}', '\u{1F71}', '\u{1F72}', '\u{1F73}', '\u{1F74}', '\u{1F75}', '\u{1F76}', '\u{1F77}', '\u{1F78}', '\u{1F79}', '\u{1F7A}', '\u{1F7B}', '\u{1F7C}', '\u{1F7D}', '\u{1F80}', '\u{1F81}', '\u{1F82}', '\u{1F83}', '\u{1F84}', '\u{1F85}', '\u{1F86}', '\u{1F87}', '\u{1F90}', '\u{1F91}', '\u{1F92}', '\u{1F93}', '\u{1F94}', '\u{1F95}', '\u{1F96}', '\u{1F97}', '\u{1FA0}', '\u{1FA1}', '\u{1FA2}', '\u{1FA3}', '\u{1FA4}', '\u{1FA5}', '\u{1FA6}', '\u{1FA7}', '\u{1FB0}', '\u{1FB1}', '\u{1FB2}', '\u{1FB3}', '\u{1FB4}', '\u{1FB6}', '\u{1FB7}', '\u{1FBE}', '\u{1FC2}', '\u{1FC3}', '\u{1FC4}', '\u{1FC6}', '\u{1FC7}', '\u{1FD0}', '\u{1FD1}', '\u{1FD2}', '\u{1FD3}', '\u{1FD6}', '\u{1FD7}', '\u{1FE0}', '\u{1FE1}', '\u{1FE2}', '\u{1FE3}', '\u{1FE4}', '\u{1FE5}', '\u{1FE6}', '\u{1FE7}', '\u{1FF2}', '\u{1FF3}', '\u{1FF4}', '\u{1FF6}', '\u{1FF7}', '\u{2071}', '\u{207F}', '\u{210A}', '\u{210E}', '\u{210F}', '\u{2113}', '\u{212F}', '\u{2134}', '\u{2139}', '\u{213C}', '\u{213D}', '\u{2146}', '\u{2147}', '\u{2148}', '\u{2149}', '\u{214E}', '\u{2184}', '\u{2C30}', '\u{2C31}', '\u{2C32}', '\u{2C33}', '\u{2C34}', '\u{2C35}', '\u{2C36}', '\u{2C37}', '\u{2C38}', '\u{2C39}', '\u{2C3A}', '\u{2C3B}', '\u{2C3C}', '\u{2C3D}', '\u{2C3E}', '\u{2C3F}', '\u{2C40}', '\u{2C41}', '\u{2C42}', '\u{2C43}', '\u{2C44}', '\u{2C45}', '\u{2C46}', '\u{2C47}', '\u{2C48}', '\u{2C49}', '\u{2C4A}', '\u{2C4B}', '\u{2C4C}', '\u{2C4D}', '\u{2C4E}', '\u{2C4F}', '\u{2C50}', '\u{2C51}', '\u{2C52}', '\u{2C53}', '\u{2C54}', '\u{2C55}', '\u{2C56}', '\u{2C57}', '\u{2C58}', '\u{2C59}', '\u{2C5A}', '\u{2C5B}', '\u{2C5C}', '\u{2C5D}', '\u{2C5E}', '\u{2C61}', '\u{2C65}', '\u{2C66}', '\u{2C68}', '\u{2C6A}', '\u{2C6C}', '\u{2C71}', '\u{2C73}', '\u{2C74}', '\u{2C76}', '\u{2C77}', '\u{2C78}', '\u{2C79}', '\u{2C7A}', '\u{2C7B}', '\u{2C7C}', '\u{2C81}', '\u{2C83}', '\u{2C85}', '\u{2C87}', '\u{2C89}', '\u{2C8B}', '\u{2C8D}', '\u{2C8F}', '\u{2C91}', '\u{2C93}', '\u{2C95}', '\u{2C97}', '\u{2C99}', '\u{2C9B}', '\u{2C9D}', '\u{2C9F}', '\u{2CA1}', '\u{2CA3}', '\u{2CA5}', '\u{2CA7}', '\u{2CA9}', '\u{2CAB}', '\u{2CAD}', '\u{2CAF}', '\u{2CB1}', '\u{2CB3}', '\u{2CB5}', '\u{2CB7}', '\u{2CB9}', '\u{2CBB}', '\u{2CBD}', '\u{2CBF}', '\u{2CC1}', '\u{2CC3}', '\u{2CC5}', '\u{2CC7}', '\u{2CC9}', '\u{2CCB}', '\u{2CCD}', '\u{2CCF}', '\u{2CD1}', '\u{2CD3}', '\u{2CD5}', '\u{2CD7}', '\u{2CD9}', '\u{2CDB}', '\u{2CDD}', '\u{2CDF}', '\u{2CE1}', '\u{2CE3}', '\u{2CE4}', '\u{2D00}', '\u{2D01}', '\u{2D02}', '\u{2D03}', '\u{2D04}', '\u{2D05}', '\u{2D06}', '\u{2D07}', '\u{2D08}', '\u{2D09}', '\u{2D0A}', '\u{2D0B}', '\u{2D0C}', '\u{2D0D}', '\u{2D0E}', '\u{2D0F}', '\u{2D10}', '\u{2D11}', '\u{2D12}', '\u{2D13}', '\u{2D14}', '\u{2D15}', '\u{2D16}', '\u{2D17}', '\u{2D18}', '\u{2D19}', '\u{2D1A}', '\u{2D1B}', '\u{2D1C}', '\u{2D1D}', '\u{2D1E}', '\u{2D1F}', '\u{2D20}', '\u{2D21}', '\u{2D22}', '\u{2D23}', '\u{2D24}', '\u{2D25}', '\u{A641}', '\u{A643}', '\u{A645}', '\u{A647}', '\u{A649}', '\u{A64B}', '\u{A64D}', '\u{A64F}', '\u{A651}', '\u{A653}', '\u{A655}', '\u{A657}', '\u{A659}', '\u{A65B}', '\u{A65D}', '\u{A65F}', '\u{A663}', '\u{A665}', '\u{A667}', '\u{A669}', '\u{A66B}', '\u{A66D}', '\u{A681}', '\u{A683}', '\u{A685}', '\u{A687}', '\u{A689}', '\u{A68B}', '\u{A68D}', '\u{A68F}', '\u{A691}', '\u{A693}', '\u{A695}', '\u{A697}', '\u{A723}', '\u{A725}', '\u{A727}', '\u{A729}', '\u{A72B}', '\u{A72D}', '\u{A72F}', '\u{A730}', '\u{A731}', '\u{A733}', '\u{A735}', '\u{A737}', '\u{A739}', '\u{A73B}', '\u{A73D}', '\u{A73F}', '\u{A741}', '\u{A743}', '\u{A745}', '\u{A747}', '\u{A749}', '\u{A74B}', '\u{A74D}', '\u{A74F}', '\u{A751}', '\u{A753}', '\u{A755}', '\u{A757}', '\u{A759}', '\u{A75B}', '\u{A75D}', '\u{A75F}', '\u{A761}', '\u{A763}', '\u{A765}', '\u{A767}', '\u{A769}', '\u{A76B}', '\u{A76D}', '\u{A76F}', '\u{A771}', '\u{A772}', '\u{A773}', '\u{A774}', '\u{A775}', '\u{A776}', '\u{A777}', '\u{A778}', '\u{A77A}', '\u{A77C}', '\u{A77F}', '\u{A781}', '\u{A783}', '\u{A785}', '\u{A787}', '\u{A78C}', '\u{FB00}', '\u{FB01}', '\u{FB02}', '\u{FB03}', '\u{FB04}', '\u{FB05}', '\u{FB06}', '\u{FB13}', '\u{FB14}', '\u{FB15}', '\u{FB16}', '\u{FB17}', '\u{FF41}', '\u{FF42}', '\u{FF43}', '\u{FF44}', '\u{FF45}', '\u{FF46}', '\u{FF47}', '\u{FF48}', '\u{FF49}', '\u{FF4A}', '\u{FF4B}', '\u{FF4C}', '\u{FF4D}', '\u{FF4E}', '\u{FF4F}', '\u{FF50}', '\u{FF51}', '\u{FF52}', '\u{FF53}', '\u{FF54}', '\u{FF55}', '\u{FF56}', '\u{FF57}', '\u{FF58}', '\u{FF59}', '\u{FF5A}') + + } + + fn is_unicode_titlecase_letter(self) -> bool { + match_char_class!(self, + '\u{01C5}', '\u{01C8}', '\u{01CB}', '\u{01F2}', '\u{1F88}', '\u{1F89}', '\u{1F8A}', '\u{1F8B}', '\u{1F8C}', '\u{1F8D}', '\u{1F8E}', '\u{1F8F}', '\u{1F98}', '\u{1F99}', '\u{1F9A}', '\u{1F9B}', '\u{1F9C}', '\u{1F9D}', '\u{1F9E}', '\u{1F9F}', '\u{1FA8}', '\u{1FA9}', '\u{1FAA}', '\u{1FAB}', '\u{1FAC}', '\u{1FAD}', '\u{1FAE}', '\u{1FAF}', '\u{1FBC}', '\u{1FCC}') + } + + fn is_unicode_modifier_letter(self) -> bool { + match_char_class!(self, + '\u{02B0}', '\u{02B1}', '\u{02B2}', '\u{02B3}', '\u{02B4}', '\u{02B5}', '\u{02B6}', '\u{02B7}', '\u{02B8}', '\u{02B9}', '\u{02BA}', '\u{02BB}', '\u{02BC}', '\u{02BD}', '\u{02BE}', '\u{02BF}', '\u{02C0}', '\u{02C1}', '\u{02C6}', '\u{02C7}', '\u{02C8}', '\u{02C9}', '\u{02CA}', '\u{02CB}', '\u{02CC}', '\u{02CD}', '\u{02CE}', '\u{02CF}', '\u{02D0}', '\u{02D1}', '\u{02E0}', '\u{02E1}', '\u{02E2}', '\u{02E3}', '\u{02E4}', '\u{02EC}', '\u{02EE}', '\u{0374}', '\u{037A}', '\u{0559}', '\u{0640}', '\u{06E5}', '\u{06E6}', '\u{07F4}', '\u{07F5}', '\u{07FA}', '\u{0971}', '\u{0E46}', '\u{0EC6}', '\u{10FC}', '\u{17D7}', '\u{1843}', '\u{1C78}', '\u{1C79}', '\u{1C7A}', '\u{1C7B}', '\u{1C7C}', '\u{1C7D}', '\u{1D2C}', '\u{1D2D}', '\u{1D2E}', '\u{1D2F}', '\u{1D30}', '\u{1D31}', '\u{1D32}', '\u{1D33}', '\u{1D34}', '\u{1D35}', '\u{1D36}', '\u{1D37}', '\u{1D38}', '\u{1D39}', '\u{1D3A}', '\u{1D3B}', '\u{1D3C}', '\u{1D3D}', '\u{1D3E}', '\u{1D3F}', '\u{1D40}', '\u{1D41}', '\u{1D42}', '\u{1D43}', '\u{1D44}', '\u{1D45}', '\u{1D46}', '\u{1D47}', '\u{1D48}', '\u{1D49}', '\u{1D4A}', '\u{1D4B}', '\u{1D4C}', '\u{1D4D}', '\u{1D4E}', '\u{1D4F}', '\u{1D50}', '\u{1D51}', '\u{1D52}', '\u{1D53}', '\u{1D54}', '\u{1D55}', '\u{1D56}', '\u{1D57}', '\u{1D58}', '\u{1D59}', '\u{1D5A}', '\u{1D5B}', '\u{1D5C}', '\u{1D5D}', '\u{1D5E}', '\u{1D5F}', '\u{1D60}', '\u{1D61}', '\u{1D78}', '\u{1D9B}', '\u{1D9C}', '\u{1D9D}', '\u{1D9E}', '\u{1D9F}', '\u{1DA0}', '\u{1DA1}', '\u{1DA2}', '\u{1DA3}', '\u{1DA4}', '\u{1DA5}', '\u{1DA6}', '\u{1DA7}', '\u{1DA8}', '\u{1DA9}', '\u{1DAA}', '\u{1DAB}', '\u{1DAC}', '\u{1DAD}', '\u{1DAE}', '\u{1DAF}', '\u{1DB0}', '\u{1DB1}', '\u{1DB2}', '\u{1DB3}', '\u{1DB4}', '\u{1DB5}', '\u{1DB6}', '\u{1DB7}', '\u{1DB8}', '\u{1DB9}', '\u{1DBA}', '\u{1DBB}', '\u{1DBC}', '\u{1DBD}', '\u{1DBE}', '\u{1DBF}', '\u{2090}', '\u{2091}', '\u{2092}', '\u{2093}', '\u{2094}', '\u{2C7D}', '\u{2D6F}', '\u{2E2F}', '\u{3005}', '\u{3031}', '\u{3032}', '\u{3033}', '\u{3034}', '\u{3035}', '\u{303B}', '\u{309D}', '\u{309E}', '\u{30FC}', '\u{30FD}', '\u{30FE}', '\u{A015}', '\u{A60C}', '\u{A67F}', '\u{A717}', '\u{A718}', '\u{A719}', '\u{A71A}', '\u{A71B}', '\u{A71C}', '\u{A71D}', '\u{A71E}', '\u{A71F}', '\u{A770}', '\u{A788}', '\u{FF70}', '\u{FF9E}', '\u{FF9F}') + } + + fn is_unicode_other_letter(self) -> bool { + match_char_class!(self, + '\u{01BB}', '\u{01C0}', '\u{01C1}', '\u{01C2}', '\u{01C3}', '\u{0294}', '\u{05D0}', '\u{05D1}', '\u{05D2}', '\u{05D3}', '\u{05D4}', '\u{05D5}', '\u{05D6}', '\u{05D7}', '\u{05D8}', '\u{05D9}', '\u{05DA}', '\u{05DB}', '\u{05DC}', '\u{05DD}', '\u{05DE}', '\u{05DF}', '\u{05E0}', '\u{05E1}', '\u{05E2}', '\u{05E3}', '\u{05E4}', '\u{05E5}', '\u{05E6}', '\u{05E7}', '\u{05E8}', '\u{05E9}', '\u{05EA}', '\u{05F0}', '\u{05F1}', '\u{05F2}', '\u{0621}', '\u{0622}', '\u{0623}', '\u{0624}', '\u{0625}', '\u{0626}', '\u{0627}', '\u{0628}', '\u{0629}', '\u{062A}', '\u{062B}', '\u{062C}', '\u{062D}', '\u{062E}', '\u{062F}', '\u{0630}', '\u{0631}', '\u{0632}', '\u{0633}', '\u{0634}', '\u{0635}', '\u{0636}', '\u{0637}', '\u{0638}', '\u{0639}', '\u{063A}', '\u{063B}', '\u{063C}', '\u{063D}', '\u{063E}', '\u{063F}', '\u{0641}', '\u{0642}', '\u{0643}', '\u{0644}', '\u{0645}', '\u{0646}', '\u{0647}', '\u{0648}', '\u{0649}', '\u{064A}', '\u{066E}', '\u{066F}', '\u{0671}', '\u{0672}', '\u{0673}', '\u{0674}', '\u{0675}', '\u{0676}', '\u{0677}', '\u{0678}', '\u{0679}', '\u{067A}', '\u{067B}', '\u{067C}', '\u{067D}', '\u{067E}', '\u{067F}', '\u{0680}', '\u{0681}', '\u{0682}', '\u{0683}', '\u{0684}', '\u{0685}', '\u{0686}', '\u{0687}', '\u{0688}', '\u{0689}', '\u{068A}', '\u{068B}', '\u{068C}', '\u{068D}', '\u{068E}', '\u{068F}', '\u{0690}', '\u{0691}', '\u{0692}', '\u{0693}', '\u{0694}', '\u{0695}', '\u{0696}', '\u{0697}', '\u{0698}', '\u{0699}', '\u{069A}', '\u{069B}', '\u{069C}', '\u{069D}', '\u{069E}', '\u{069F}', '\u{06A0}', '\u{06A1}', '\u{06A2}', '\u{06A3}', '\u{06A4}', '\u{06A5}', '\u{06A6}', '\u{06A7}', '\u{06A8}', '\u{06A9}', '\u{06AA}', '\u{06AB}', '\u{06AC}', '\u{06AD}', '\u{06AE}', '\u{06AF}', '\u{06B0}', '\u{06B1}', '\u{06B2}', '\u{06B3}', '\u{06B4}', '\u{06B5}', '\u{06B6}', '\u{06B7}', '\u{06B8}', '\u{06B9}', '\u{06BA}', '\u{06BB}', '\u{06BC}', '\u{06BD}', '\u{06BE}', '\u{06BF}', '\u{06C0}', '\u{06C1}', '\u{06C2}', '\u{06C3}', '\u{06C4}', '\u{06C5}', '\u{06C6}', '\u{06C7}', '\u{06C8}', '\u{06C9}', '\u{06CA}', '\u{06CB}', '\u{06CC}', '\u{06CD}', '\u{06CE}', '\u{06CF}', '\u{06D0}', '\u{06D1}', '\u{06D2}', '\u{06D3}', '\u{06D5}', '\u{06EE}', '\u{06EF}', '\u{06FA}', '\u{06FB}', '\u{06FC}', '\u{06FF}', '\u{0710}', '\u{0712}', '\u{0713}', '\u{0714}', '\u{0715}', '\u{0716}', '\u{0717}', '\u{0718}', '\u{0719}', '\u{071A}', '\u{071B}', '\u{071C}', '\u{071D}', '\u{071E}', '\u{071F}', '\u{0720}', '\u{0721}', '\u{0722}', '\u{0723}', '\u{0724}', '\u{0725}', '\u{0726}', '\u{0727}', '\u{0728}', '\u{0729}', '\u{072A}', '\u{072B}', '\u{072C}', '\u{072D}', '\u{072E}', '\u{072F}', '\u{074D}', '\u{074E}', '\u{074F}', '\u{0750}', '\u{0751}', '\u{0752}', '\u{0753}', '\u{0754}', '\u{0755}', '\u{0756}', '\u{0757}', '\u{0758}', '\u{0759}', '\u{075A}', '\u{075B}', '\u{075C}', '\u{075D}', '\u{075E}', '\u{075F}', '\u{0760}', '\u{0761}', '\u{0762}', '\u{0763}', '\u{0764}', '\u{0765}', '\u{0766}', '\u{0767}', '\u{0768}', '\u{0769}', '\u{076A}', '\u{076B}', '\u{076C}', '\u{076D}', '\u{076E}', '\u{076F}', '\u{0770}', '\u{0771}', '\u{0772}', '\u{0773}', '\u{0774}', '\u{0775}', '\u{0776}', '\u{0777}', '\u{0778}', '\u{0779}', '\u{077A}', '\u{077B}', '\u{077C}', '\u{077D}', '\u{077E}', '\u{077F}', '\u{0780}', '\u{0781}', '\u{0782}', '\u{0783}', '\u{0784}', '\u{0785}', '\u{0786}', '\u{0787}', '\u{0788}', '\u{0789}', '\u{078A}', '\u{078B}', '\u{078C}', '\u{078D}', '\u{078E}', '\u{078F}', '\u{0790}', '\u{0791}', '\u{0792}', '\u{0793}', '\u{0794}', '\u{0795}', '\u{0796}', '\u{0797}', '\u{0798}', '\u{0799}', '\u{079A}', '\u{079B}', '\u{079C}', '\u{079D}', '\u{079E}', '\u{079F}', '\u{07A0}', '\u{07A1}', '\u{07A2}', '\u{07A3}', '\u{07A4}', '\u{07A5}', '\u{07B1}', '\u{07CA}', '\u{07CB}', '\u{07CC}', '\u{07CD}', '\u{07CE}', '\u{07CF}', '\u{07D0}', '\u{07D1}', '\u{07D2}', '\u{07D3}', '\u{07D4}', '\u{07D5}', '\u{07D6}', '\u{07D7}', '\u{07D8}', '\u{07D9}', '\u{07DA}', '\u{07DB}', '\u{07DC}', '\u{07DD}', '\u{07DE}', '\u{07DF}', '\u{07E0}', '\u{07E1}', '\u{07E2}', '\u{07E3}', '\u{07E4}', '\u{07E5}', '\u{07E6}', '\u{07E7}', '\u{07E8}', '\u{07E9}', '\u{07EA}', '\u{0904}', '\u{0905}', '\u{0906}', '\u{0907}', '\u{0908}', '\u{0909}', '\u{090A}', '\u{090B}', '\u{090C}', '\u{090D}', '\u{090E}', '\u{090F}', '\u{0910}', '\u{0911}', '\u{0912}', '\u{0913}', '\u{0914}', '\u{0915}', '\u{0916}', '\u{0917}', '\u{0918}', '\u{0919}', '\u{091A}', '\u{091B}', '\u{091C}', '\u{091D}', '\u{091E}', '\u{091F}', '\u{0920}', '\u{0921}', '\u{0922}', '\u{0923}', '\u{0924}', '\u{0925}', '\u{0926}', '\u{0927}', '\u{0928}', '\u{0929}', '\u{092A}', '\u{092B}', '\u{092C}', '\u{092D}', '\u{092E}', '\u{092F}', '\u{0930}', '\u{0931}', '\u{0932}', '\u{0933}', '\u{0934}', '\u{0935}', '\u{0936}', '\u{0937}', '\u{0938}', '\u{0939}', '\u{093D}', '\u{0950}', '\u{0958}', '\u{0959}', '\u{095A}', '\u{095B}', '\u{095C}', '\u{095D}', '\u{095E}', '\u{095F}', '\u{0960}', '\u{0961}', '\u{0972}', '\u{097B}', '\u{097C}', '\u{097D}', '\u{097E}', '\u{097F}', '\u{0985}', '\u{0986}', '\u{0987}', '\u{0988}', '\u{0989}', '\u{098A}', '\u{098B}', '\u{098C}', '\u{098F}', '\u{0990}', '\u{0993}', '\u{0994}', '\u{0995}', '\u{0996}', '\u{0997}', '\u{0998}', '\u{0999}', '\u{099A}', '\u{099B}', '\u{099C}', '\u{099D}', '\u{099E}', '\u{099F}', '\u{09A0}', '\u{09A1}', '\u{09A2}', '\u{09A3}', '\u{09A4}', '\u{09A5}', '\u{09A6}', '\u{09A7}', '\u{09A8}', '\u{09AA}', '\u{09AB}', '\u{09AC}', '\u{09AD}', '\u{09AE}', '\u{09AF}', '\u{09B0}', '\u{09B2}', '\u{09B6}', '\u{09B7}', '\u{09B8}', '\u{09B9}', '\u{09BD}', '\u{09CE}', '\u{09DC}', '\u{09DD}', '\u{09DF}', '\u{09E0}', '\u{09E1}', '\u{09F0}', '\u{09F1}', '\u{0A05}', '\u{0A06}', '\u{0A07}', '\u{0A08}', '\u{0A09}', '\u{0A0A}', '\u{0A0F}', '\u{0A10}', '\u{0A13}', '\u{0A14}', '\u{0A15}', '\u{0A16}', '\u{0A17}', '\u{0A18}', '\u{0A19}', '\u{0A1A}', '\u{0A1B}', '\u{0A1C}', '\u{0A1D}', '\u{0A1E}', '\u{0A1F}', '\u{0A20}', '\u{0A21}', '\u{0A22}', '\u{0A23}', '\u{0A24}', '\u{0A25}', '\u{0A26}', '\u{0A27}', '\u{0A28}', '\u{0A2A}', '\u{0A2B}', '\u{0A2C}', '\u{0A2D}', '\u{0A2E}', '\u{0A2F}', '\u{0A30}', '\u{0A32}', '\u{0A33}', '\u{0A35}', '\u{0A36}', '\u{0A38}', '\u{0A39}', '\u{0A59}', '\u{0A5A}', '\u{0A5B}', '\u{0A5C}', '\u{0A5E}', '\u{0A72}', '\u{0A73}', '\u{0A74}', '\u{0A85}', '\u{0A86}', '\u{0A87}', '\u{0A88}', '\u{0A89}', '\u{0A8A}', '\u{0A8B}', '\u{0A8C}', '\u{0A8D}', '\u{0A8F}', '\u{0A90}', '\u{0A91}', '\u{0A93}', '\u{0A94}', '\u{0A95}', '\u{0A96}', '\u{0A97}', '\u{0A98}', '\u{0A99}', '\u{0A9A}', '\u{0A9B}', '\u{0A9C}', '\u{0A9D}', '\u{0A9E}', '\u{0A9F}', '\u{0AA0}', '\u{0AA1}', '\u{0AA2}', '\u{0AA3}', '\u{0AA4}', '\u{0AA5}', '\u{0AA6}', '\u{0AA7}', '\u{0AA8}', '\u{0AAA}', '\u{0AAB}', '\u{0AAC}', '\u{0AAD}', '\u{0AAE}', '\u{0AAF}', '\u{0AB0}', '\u{0AB2}', '\u{0AB3}', '\u{0AB5}', '\u{0AB6}', '\u{0AB7}', '\u{0AB8}', '\u{0AB9}', '\u{0ABD}', '\u{0AD0}', '\u{0AE0}', '\u{0AE1}', '\u{0B05}', '\u{0B06}', '\u{0B07}', '\u{0B08}', '\u{0B09}', '\u{0B0A}', '\u{0B0B}', '\u{0B0C}', '\u{0B0F}', '\u{0B10}', '\u{0B13}', '\u{0B14}', '\u{0B15}', '\u{0B16}', '\u{0B17}', '\u{0B18}', '\u{0B19}', '\u{0B1A}', '\u{0B1B}', '\u{0B1C}', '\u{0B1D}', '\u{0B1E}', '\u{0B1F}', '\u{0B20}', '\u{0B21}', '\u{0B22}', '\u{0B23}', '\u{0B24}', '\u{0B25}', '\u{0B26}', '\u{0B27}', '\u{0B28}', '\u{0B2A}', '\u{0B2B}', '\u{0B2C}', '\u{0B2D}', '\u{0B2E}', '\u{0B2F}', '\u{0B30}', '\u{0B32}', '\u{0B33}', '\u{0B35}', '\u{0B36}', '\u{0B37}', '\u{0B38}', '\u{0B39}', '\u{0B3D}', '\u{0B5C}', '\u{0B5D}', '\u{0B5F}', '\u{0B60}', '\u{0B61}', '\u{0B71}', '\u{0B83}', '\u{0B85}', '\u{0B86}', '\u{0B87}', '\u{0B88}', '\u{0B89}', '\u{0B8A}', '\u{0B8E}', '\u{0B8F}', '\u{0B90}', '\u{0B92}', '\u{0B93}', '\u{0B94}', '\u{0B95}', '\u{0B99}', '\u{0B9A}', '\u{0B9C}', '\u{0B9E}', '\u{0B9F}', '\u{0BA3}', '\u{0BA4}', '\u{0BA8}', '\u{0BA9}', '\u{0BAA}', '\u{0BAE}', '\u{0BAF}', '\u{0BB0}', '\u{0BB1}', '\u{0BB2}', '\u{0BB3}', '\u{0BB4}', '\u{0BB5}', '\u{0BB6}', '\u{0BB7}', '\u{0BB8}', '\u{0BB9}', '\u{0BD0}', '\u{0C05}', '\u{0C06}', '\u{0C07}', '\u{0C08}', '\u{0C09}', '\u{0C0A}', '\u{0C0B}', '\u{0C0C}', '\u{0C0E}', '\u{0C0F}', '\u{0C10}', '\u{0C12}', '\u{0C13}', '\u{0C14}', '\u{0C15}', '\u{0C16}', '\u{0C17}', '\u{0C18}', '\u{0C19}', '\u{0C1A}', '\u{0C1B}', '\u{0C1C}', '\u{0C1D}', '\u{0C1E}', '\u{0C1F}', '\u{0C20}', '\u{0C21}', '\u{0C22}', '\u{0C23}', '\u{0C24}', '\u{0C25}', '\u{0C26}', '\u{0C27}', '\u{0C28}', '\u{0C2A}', '\u{0C2B}', '\u{0C2C}', '\u{0C2D}', '\u{0C2E}', '\u{0C2F}', '\u{0C30}', '\u{0C31}', '\u{0C32}', '\u{0C33}', '\u{0C35}', '\u{0C36}', '\u{0C37}', '\u{0C38}', '\u{0C39}', '\u{0C3D}', '\u{0C58}', '\u{0C59}', '\u{0C60}', '\u{0C61}', '\u{0C85}', '\u{0C86}', '\u{0C87}', '\u{0C88}', '\u{0C89}', '\u{0C8A}', '\u{0C8B}', '\u{0C8C}', '\u{0C8E}', '\u{0C8F}', '\u{0C90}', '\u{0C92}', '\u{0C93}', '\u{0C94}', '\u{0C95}', '\u{0C96}', '\u{0C97}', '\u{0C98}', '\u{0C99}', '\u{0C9A}', '\u{0C9B}', '\u{0C9C}', '\u{0C9D}', '\u{0C9E}', '\u{0C9F}', '\u{0CA0}', '\u{0CA1}', '\u{0CA2}', '\u{0CA3}', '\u{0CA4}', '\u{0CA5}', '\u{0CA6}', '\u{0CA7}', '\u{0CA8}', '\u{0CAA}', '\u{0CAB}', '\u{0CAC}', '\u{0CAD}', '\u{0CAE}', '\u{0CAF}', '\u{0CB0}', '\u{0CB1}', '\u{0CB2}', '\u{0CB3}', '\u{0CB5}', '\u{0CB6}', '\u{0CB7}', '\u{0CB8}', '\u{0CB9}', '\u{0CBD}', '\u{0CDE}', '\u{0CE0}', '\u{0CE1}', '\u{0D05}', '\u{0D06}', '\u{0D07}', '\u{0D08}', '\u{0D09}', '\u{0D0A}', '\u{0D0B}', '\u{0D0C}', '\u{0D0E}', '\u{0D0F}', '\u{0D10}', '\u{0D12}', '\u{0D13}', '\u{0D14}', '\u{0D15}', '\u{0D16}', '\u{0D17}', '\u{0D18}', '\u{0D19}', '\u{0D1A}', '\u{0D1B}', '\u{0D1C}', '\u{0D1D}', '\u{0D1E}', '\u{0D1F}', '\u{0D20}', '\u{0D21}', '\u{0D22}', '\u{0D23}', '\u{0D24}', '\u{0D25}', '\u{0D26}', '\u{0D27}', '\u{0D28}', '\u{0D2A}', '\u{0D2B}', '\u{0D2C}', '\u{0D2D}', '\u{0D2E}', '\u{0D2F}', '\u{0D30}', '\u{0D31}', '\u{0D32}', '\u{0D33}', '\u{0D34}', '\u{0D35}', '\u{0D36}', '\u{0D37}', '\u{0D38}', '\u{0D39}', '\u{0D3D}', '\u{0D60}', '\u{0D61}', '\u{0D7A}', '\u{0D7B}', '\u{0D7C}', '\u{0D7D}', '\u{0D7E}', '\u{0D7F}', '\u{0D85}', '\u{0D86}', '\u{0D87}', '\u{0D88}', '\u{0D89}', '\u{0D8A}', '\u{0D8B}', '\u{0D8C}', '\u{0D8D}', '\u{0D8E}', '\u{0D8F}', '\u{0D90}', '\u{0D91}', '\u{0D92}', '\u{0D93}', '\u{0D94}', '\u{0D95}', '\u{0D96}', '\u{0D9A}', '\u{0D9B}', '\u{0D9C}', '\u{0D9D}', '\u{0D9E}', '\u{0D9F}', '\u{0DA0}', '\u{0DA1}', '\u{0DA2}', '\u{0DA3}', '\u{0DA4}', '\u{0DA5}', '\u{0DA6}', '\u{0DA7}', '\u{0DA8}', '\u{0DA9}', '\u{0DAA}', '\u{0DAB}', '\u{0DAC}', '\u{0DAD}', '\u{0DAE}', '\u{0DAF}', '\u{0DB0}', '\u{0DB1}', '\u{0DB3}', '\u{0DB4}', '\u{0DB5}', '\u{0DB6}', '\u{0DB7}', '\u{0DB8}', '\u{0DB9}', '\u{0DBA}', '\u{0DBB}', '\u{0DBD}', '\u{0DC0}', '\u{0DC1}', '\u{0DC2}', '\u{0DC3}', '\u{0DC4}', '\u{0DC5}', '\u{0DC6}', '\u{0E01}', '\u{0E02}', '\u{0E03}', '\u{0E04}', '\u{0E05}', '\u{0E06}', '\u{0E07}', '\u{0E08}', '\u{0E09}', '\u{0E0A}', '\u{0E0B}', '\u{0E0C}', '\u{0E0D}', '\u{0E0E}', '\u{0E0F}', '\u{0E10}', '\u{0E11}', '\u{0E12}', '\u{0E13}', '\u{0E14}', '\u{0E15}', '\u{0E16}', '\u{0E17}', '\u{0E18}', '\u{0E19}', '\u{0E1A}', '\u{0E1B}', '\u{0E1C}', '\u{0E1D}', '\u{0E1E}', '\u{0E1F}', '\u{0E20}', '\u{0E21}', '\u{0E22}', '\u{0E23}', '\u{0E24}', '\u{0E25}', '\u{0E26}', '\u{0E27}', '\u{0E28}', '\u{0E29}', '\u{0E2A}', '\u{0E2B}', '\u{0E2C}', '\u{0E2D}', '\u{0E2E}', '\u{0E2F}', '\u{0E30}', '\u{0E32}', '\u{0E33}', '\u{0E40}', '\u{0E41}', '\u{0E42}', '\u{0E43}', '\u{0E44}', '\u{0E45}', '\u{0E81}', '\u{0E82}', '\u{0E84}', '\u{0E87}', '\u{0E88}', '\u{0E8A}', '\u{0E8D}', '\u{0E94}', '\u{0E95}', '\u{0E96}', '\u{0E97}', '\u{0E99}', '\u{0E9A}', '\u{0E9B}', '\u{0E9C}', '\u{0E9D}', '\u{0E9E}', '\u{0E9F}', '\u{0EA1}', '\u{0EA2}', '\u{0EA3}', '\u{0EA5}', '\u{0EA7}', '\u{0EAA}', '\u{0EAB}', '\u{0EAD}', '\u{0EAE}', '\u{0EAF}', '\u{0EB0}', '\u{0EB2}', '\u{0EB3}', '\u{0EBD}', '\u{0EC0}', '\u{0EC1}', '\u{0EC2}', '\u{0EC3}', '\u{0EC4}', '\u{0EDC}', '\u{0EDD}', '\u{0F00}', '\u{0F40}', '\u{0F41}', '\u{0F42}', '\u{0F43}', '\u{0F44}', '\u{0F45}', '\u{0F46}', '\u{0F47}', '\u{0F49}', '\u{0F4A}', '\u{0F4B}', '\u{0F4C}', '\u{0F4D}', '\u{0F4E}', '\u{0F4F}', '\u{0F50}', '\u{0F51}', '\u{0F52}', '\u{0F53}', '\u{0F54}', '\u{0F55}', '\u{0F56}', '\u{0F57}', '\u{0F58}', '\u{0F59}', '\u{0F5A}', '\u{0F5B}', '\u{0F5C}', '\u{0F5D}', '\u{0F5E}', '\u{0F5F}', '\u{0F60}', '\u{0F61}', '\u{0F62}', '\u{0F63}', '\u{0F64}', '\u{0F65}', '\u{0F66}', '\u{0F67}', '\u{0F68}', '\u{0F69}', '\u{0F6A}', '\u{0F6B}', '\u{0F6C}', '\u{0F88}', '\u{0F89}', '\u{0F8A}', '\u{0F8B}', '\u{1000}', '\u{1001}', '\u{1002}', '\u{1003}', '\u{1004}', '\u{1005}', '\u{1006}', '\u{1007}', '\u{1008}', '\u{1009}', '\u{100A}', '\u{100B}', '\u{100C}', '\u{100D}', '\u{100E}', '\u{100F}', '\u{1010}', '\u{1011}', '\u{1012}', '\u{1013}', '\u{1014}', '\u{1015}', '\u{1016}', '\u{1017}', '\u{1018}', '\u{1019}', '\u{101A}', '\u{101B}', '\u{101C}', '\u{101D}', '\u{101E}', '\u{101F}', '\u{1020}', '\u{1021}', '\u{1022}', '\u{1023}', '\u{1024}', '\u{1025}', '\u{1026}', '\u{1027}', '\u{1028}', '\u{1029}', '\u{102A}', '\u{103F}', '\u{1050}', '\u{1051}', '\u{1052}', '\u{1053}', '\u{1054}', '\u{1055}', '\u{105A}', '\u{105B}', '\u{105C}', '\u{105D}', '\u{1061}', '\u{1065}', '\u{1066}', '\u{106E}', '\u{106F}', '\u{1070}', '\u{1075}', '\u{1076}', '\u{1077}', '\u{1078}', '\u{1079}', '\u{107A}', '\u{107B}', '\u{107C}', '\u{107D}', '\u{107E}', '\u{107F}', '\u{1080}', '\u{1081}', '\u{108E}', '\u{10D0}', '\u{10D1}', '\u{10D2}', '\u{10D3}', '\u{10D4}', '\u{10D5}', '\u{10D6}', '\u{10D7}', '\u{10D8}', '\u{10D9}', '\u{10DA}', '\u{10DB}', '\u{10DC}', '\u{10DD}', '\u{10DE}', '\u{10DF}', '\u{10E0}', '\u{10E1}', '\u{10E2}', '\u{10E3}', '\u{10E4}', '\u{10E5}', '\u{10E6}', '\u{10E7}', '\u{10E8}', '\u{10E9}', '\u{10EA}', '\u{10EB}', '\u{10EC}', '\u{10ED}', '\u{10EE}', '\u{10EF}', '\u{10F0}', '\u{10F1}', '\u{10F2}', '\u{10F3}', '\u{10F4}', '\u{10F5}', '\u{10F6}', '\u{10F7}', '\u{10F8}', '\u{10F9}', '\u{10FA}', '\u{1100}', '\u{1101}', '\u{1102}', '\u{1103}', '\u{1104}', '\u{1105}', '\u{1106}', '\u{1107}', '\u{1108}', '\u{1109}', '\u{110A}', '\u{110B}', '\u{110C}', '\u{110D}', '\u{110E}', '\u{110F}', '\u{1110}', '\u{1111}', '\u{1112}', '\u{1113}', '\u{1114}', '\u{1115}', '\u{1116}', '\u{1117}', '\u{1118}', '\u{1119}', '\u{111A}', '\u{111B}', '\u{111C}', '\u{111D}', '\u{111E}', '\u{111F}', '\u{1120}', '\u{1121}', '\u{1122}', '\u{1123}', '\u{1124}', '\u{1125}', '\u{1126}', '\u{1127}', '\u{1128}', '\u{1129}', '\u{112A}', '\u{112B}', '\u{112C}', '\u{112D}', '\u{112E}', '\u{112F}', '\u{1130}', '\u{1131}', '\u{1132}', '\u{1133}', '\u{1134}', '\u{1135}', '\u{1136}', '\u{1137}', '\u{1138}', '\u{1139}', '\u{113A}', '\u{113B}', '\u{113C}', '\u{113D}', '\u{113E}', '\u{113F}', '\u{1140}', '\u{1141}', '\u{1142}', '\u{1143}', '\u{1144}', '\u{1145}', '\u{1146}', '\u{1147}', '\u{1148}', '\u{1149}', '\u{114A}', '\u{114B}', '\u{114C}', '\u{114D}', '\u{114E}', '\u{114F}', '\u{1150}', '\u{1151}', '\u{1152}', '\u{1153}', '\u{1154}', '\u{1155}', '\u{1156}', '\u{1157}', '\u{1158}', '\u{1159}', '\u{115F}', '\u{1160}', '\u{1161}', '\u{1162}', '\u{1163}', '\u{1164}', '\u{1165}', '\u{1166}', '\u{1167}', '\u{1168}', '\u{1169}', '\u{116A}', '\u{116B}', '\u{116C}', '\u{116D}', '\u{116E}', '\u{116F}', '\u{1170}', '\u{1171}', '\u{1172}', '\u{1173}', '\u{1174}', '\u{1175}', '\u{1176}', '\u{1177}', '\u{1178}', '\u{1179}', '\u{117A}', '\u{117B}', '\u{117C}', '\u{117D}', '\u{117E}', '\u{117F}', '\u{1180}', '\u{1181}', '\u{1182}', '\u{1183}', '\u{1184}', '\u{1185}', '\u{1186}', '\u{1187}', '\u{1188}', '\u{1189}', '\u{118A}', '\u{118B}', '\u{118C}', '\u{118D}', '\u{118E}', '\u{118F}', '\u{1190}', '\u{1191}', '\u{1192}', '\u{1193}', '\u{1194}', '\u{1195}', '\u{1196}', '\u{1197}', '\u{1198}', '\u{1199}', '\u{119A}', '\u{119B}', '\u{119C}', '\u{119D}', '\u{119E}', '\u{119F}', '\u{11A0}', '\u{11A1}', '\u{11A2}', '\u{11A8}', '\u{11A9}', '\u{11AA}', '\u{11AB}', '\u{11AC}', '\u{11AD}', '\u{11AE}', '\u{11AF}', '\u{11B0}', '\u{11B1}', '\u{11B2}', '\u{11B3}', '\u{11B4}', '\u{11B5}', '\u{11B6}', '\u{11B7}', '\u{11B8}', '\u{11B9}', '\u{11BA}', '\u{11BB}', '\u{11BC}', '\u{11BD}', '\u{11BE}', '\u{11BF}', '\u{11C0}', '\u{11C1}', '\u{11C2}', '\u{11C3}', '\u{11C4}', '\u{11C5}', '\u{11C6}', '\u{11C7}', '\u{11C8}', '\u{11C9}', '\u{11CA}', '\u{11CB}', '\u{11CC}', '\u{11CD}', '\u{11CE}', '\u{11CF}', '\u{11D0}', '\u{11D1}', '\u{11D2}', '\u{11D3}', '\u{11D4}', '\u{11D5}', '\u{11D6}', '\u{11D7}', '\u{11D8}', '\u{11D9}', '\u{11DA}', '\u{11DB}', '\u{11DC}', '\u{11DD}', '\u{11DE}', '\u{11DF}', '\u{11E0}', '\u{11E1}', '\u{11E2}', '\u{11E3}', '\u{11E4}', '\u{11E5}', '\u{11E6}', '\u{11E7}', '\u{11E8}', '\u{11E9}', '\u{11EA}', '\u{11EB}', '\u{11EC}', '\u{11ED}', '\u{11EE}', '\u{11EF}', '\u{11F0}', '\u{11F1}', '\u{11F2}', '\u{11F3}', '\u{11F4}', '\u{11F5}', '\u{11F6}', '\u{11F7}', '\u{11F8}', '\u{11F9}', '\u{1200}', '\u{1201}', '\u{1202}', '\u{1203}', '\u{1204}', '\u{1205}', '\u{1206}', '\u{1207}', '\u{1208}', '\u{1209}', '\u{120A}', '\u{120B}', '\u{120C}', '\u{120D}', '\u{120E}', '\u{120F}', '\u{1210}', '\u{1211}', '\u{1212}', '\u{1213}', '\u{1214}', '\u{1215}', '\u{1216}', '\u{1217}', '\u{1218}', '\u{1219}', '\u{121A}', '\u{121B}', '\u{121C}', '\u{121D}', '\u{121E}', '\u{121F}', '\u{1220}', '\u{1221}', '\u{1222}', '\u{1223}', '\u{1224}', '\u{1225}', '\u{1226}', '\u{1227}', '\u{1228}', '\u{1229}', '\u{122A}', '\u{122B}', '\u{122C}', '\u{122D}', '\u{122E}', '\u{122F}', '\u{1230}', '\u{1231}', '\u{1232}', '\u{1233}', '\u{1234}', '\u{1235}', '\u{1236}', '\u{1237}', '\u{1238}', '\u{1239}', '\u{123A}', '\u{123B}', '\u{123C}', '\u{123D}', '\u{123E}', '\u{123F}', '\u{1240}', '\u{1241}', '\u{1242}', '\u{1243}', '\u{1244}', '\u{1245}', '\u{1246}', '\u{1247}', '\u{1248}', '\u{124A}', '\u{124B}', '\u{124C}', '\u{124D}', '\u{1250}', '\u{1251}', '\u{1252}', '\u{1253}', '\u{1254}', '\u{1255}', '\u{1256}', '\u{1258}', '\u{125A}', '\u{125B}', '\u{125C}', '\u{125D}', '\u{1260}', '\u{1261}', '\u{1262}', '\u{1263}', '\u{1264}', '\u{1265}', '\u{1266}', '\u{1267}', '\u{1268}', '\u{1269}', '\u{126A}', '\u{126B}', '\u{126C}', '\u{126D}', '\u{126E}', '\u{126F}', '\u{1270}', '\u{1271}', '\u{1272}', '\u{1273}', '\u{1274}', '\u{1275}', '\u{1276}', '\u{1277}', '\u{1278}', '\u{1279}', '\u{127A}', '\u{127B}', '\u{127C}', '\u{127D}', '\u{127E}', '\u{127F}', '\u{1280}', '\u{1281}', '\u{1282}', '\u{1283}', '\u{1284}', '\u{1285}', '\u{1286}', '\u{1287}', '\u{1288}', '\u{128A}', '\u{128B}', '\u{128C}', '\u{128D}', '\u{1290}', '\u{1291}', '\u{1292}', '\u{1293}', '\u{1294}', '\u{1295}', '\u{1296}', '\u{1297}', '\u{1298}', '\u{1299}', '\u{129A}', '\u{129B}', '\u{129C}', '\u{129D}', '\u{129E}', '\u{129F}', '\u{12A0}', '\u{12A1}', '\u{12A2}', '\u{12A3}', '\u{12A4}', '\u{12A5}', '\u{12A6}', '\u{12A7}', '\u{12A8}', '\u{12A9}', '\u{12AA}', '\u{12AB}', '\u{12AC}', '\u{12AD}', '\u{12AE}', '\u{12AF}', '\u{12B0}', '\u{12B2}', '\u{12B3}', '\u{12B4}', '\u{12B5}', '\u{12B8}', '\u{12B9}', '\u{12BA}', '\u{12BB}', '\u{12BC}', '\u{12BD}', '\u{12BE}', '\u{12C0}', '\u{12C2}', '\u{12C3}', '\u{12C4}', '\u{12C5}', '\u{12C8}', '\u{12C9}', '\u{12CA}', '\u{12CB}', '\u{12CC}', '\u{12CD}', '\u{12CE}', '\u{12CF}', '\u{12D0}', '\u{12D1}', '\u{12D2}', '\u{12D3}', '\u{12D4}', '\u{12D5}', '\u{12D6}', '\u{12D8}', '\u{12D9}', '\u{12DA}', '\u{12DB}', '\u{12DC}', '\u{12DD}', '\u{12DE}', '\u{12DF}', '\u{12E0}', '\u{12E1}', '\u{12E2}', '\u{12E3}', '\u{12E4}', '\u{12E5}', '\u{12E6}', '\u{12E7}', '\u{12E8}', '\u{12E9}', '\u{12EA}', '\u{12EB}', '\u{12EC}', '\u{12ED}', '\u{12EE}', '\u{12EF}', '\u{12F0}', '\u{12F1}', '\u{12F2}', '\u{12F3}', '\u{12F4}', '\u{12F5}', '\u{12F6}', '\u{12F7}', '\u{12F8}', '\u{12F9}', '\u{12FA}', '\u{12FB}', '\u{12FC}', '\u{12FD}', '\u{12FE}', '\u{12FF}', '\u{1300}', '\u{1301}', '\u{1302}', '\u{1303}', '\u{1304}', '\u{1305}', '\u{1306}', '\u{1307}', '\u{1308}', '\u{1309}', '\u{130A}', '\u{130B}', '\u{130C}', '\u{130D}', '\u{130E}', '\u{130F}', '\u{1310}', '\u{1312}', '\u{1313}', '\u{1314}', '\u{1315}', '\u{1318}', '\u{1319}', '\u{131A}', '\u{131B}', '\u{131C}', '\u{131D}', '\u{131E}', '\u{131F}', '\u{1320}', '\u{1321}', '\u{1322}', '\u{1323}', '\u{1324}', '\u{1325}', '\u{1326}', '\u{1327}', '\u{1328}', '\u{1329}', '\u{132A}', '\u{132B}', '\u{132C}', '\u{132D}', '\u{132E}', '\u{132F}', '\u{1330}', '\u{1331}', '\u{1332}', '\u{1333}', '\u{1334}', '\u{1335}', '\u{1336}', '\u{1337}', '\u{1338}', '\u{1339}', '\u{133A}', '\u{133B}', '\u{133C}', '\u{133D}', '\u{133E}', '\u{133F}', '\u{1340}', '\u{1341}', '\u{1342}', '\u{1343}', '\u{1344}', '\u{1345}', '\u{1346}', '\u{1347}', '\u{1348}', '\u{1349}', '\u{134A}', '\u{134B}', '\u{134C}', '\u{134D}', '\u{134E}', '\u{134F}', '\u{1350}', '\u{1351}', '\u{1352}', '\u{1353}', '\u{1354}', '\u{1355}', '\u{1356}', '\u{1357}', '\u{1358}', '\u{1359}', '\u{135A}', '\u{1380}', '\u{1381}', '\u{1382}', '\u{1383}', '\u{1384}', '\u{1385}', '\u{1386}', '\u{1387}', '\u{1388}', '\u{1389}', '\u{138A}', '\u{138B}', '\u{138C}', '\u{138D}', '\u{138E}', '\u{138F}', '\u{13A0}', '\u{13A1}', '\u{13A2}', '\u{13A3}', '\u{13A4}', '\u{13A5}', '\u{13A6}', '\u{13A7}', '\u{13A8}', '\u{13A9}', '\u{13AA}', '\u{13AB}', '\u{13AC}', '\u{13AD}', '\u{13AE}', '\u{13AF}', '\u{13B0}', '\u{13B1}', '\u{13B2}', '\u{13B3}', '\u{13B4}', '\u{13B5}', '\u{13B6}', '\u{13B7}', '\u{13B8}', '\u{13B9}', '\u{13BA}', '\u{13BB}', '\u{13BC}', '\u{13BD}', '\u{13BE}', '\u{13BF}', '\u{13C0}', '\u{13C1}', '\u{13C2}', '\u{13C3}', '\u{13C4}', '\u{13C5}', '\u{13C6}', '\u{13C7}', '\u{13C8}', '\u{13C9}', '\u{13CA}', '\u{13CB}', '\u{13CC}', '\u{13CD}', '\u{13CE}', '\u{13CF}', '\u{13D0}', '\u{13D1}', '\u{13D2}', '\u{13D3}', '\u{13D4}', '\u{13D5}', '\u{13D6}', '\u{13D7}', '\u{13D8}', '\u{13D9}', '\u{13DA}', '\u{13DB}', '\u{13DC}', '\u{13DD}', '\u{13DE}', '\u{13DF}', '\u{13E0}', '\u{13E1}', '\u{13E2}', '\u{13E3}', '\u{13E4}', '\u{13E5}', '\u{13E6}', '\u{13E7}', '\u{13E8}', '\u{13E9}', '\u{13EA}', '\u{13EB}', '\u{13EC}', '\u{13ED}', '\u{13EE}', '\u{13EF}', '\u{13F0}', '\u{13F1}', '\u{13F2}', '\u{13F3}', '\u{13F4}', '\u{1401}', '\u{1402}', '\u{1403}', '\u{1404}', '\u{1405}', '\u{1406}', '\u{1407}', '\u{1408}', '\u{1409}', '\u{140A}', '\u{140B}', '\u{140C}', '\u{140D}', '\u{140E}', '\u{140F}', '\u{1410}', '\u{1411}', '\u{1412}', '\u{1413}', '\u{1414}', '\u{1415}', '\u{1416}', '\u{1417}', '\u{1418}', '\u{1419}', '\u{141A}', '\u{141B}', '\u{141C}', '\u{141D}', '\u{141E}', '\u{141F}', '\u{1420}', '\u{1421}', '\u{1422}', '\u{1423}', '\u{1424}', '\u{1425}', '\u{1426}', '\u{1427}', '\u{1428}', '\u{1429}', '\u{142A}', '\u{142B}', '\u{142C}', '\u{142D}', '\u{142E}', '\u{142F}', '\u{1430}', '\u{1431}', '\u{1432}', '\u{1433}', '\u{1434}', '\u{1435}', '\u{1436}', '\u{1437}', '\u{1438}', '\u{1439}', '\u{143A}', '\u{143B}', '\u{143C}', '\u{143D}', '\u{143E}', '\u{143F}', '\u{1440}', '\u{1441}', '\u{1442}', '\u{1443}', '\u{1444}', '\u{1445}', '\u{1446}', '\u{1447}', '\u{1448}', '\u{1449}', '\u{144A}', '\u{144B}', '\u{144C}', '\u{144D}', '\u{144E}', '\u{144F}', '\u{1450}', '\u{1451}', '\u{1452}', '\u{1453}', '\u{1454}', '\u{1455}', '\u{1456}', '\u{1457}', '\u{1458}', '\u{1459}', '\u{145A}', '\u{145B}', '\u{145C}', '\u{145D}', '\u{145E}', '\u{145F}', '\u{1460}', '\u{1461}', '\u{1462}', '\u{1463}', '\u{1464}', '\u{1465}', '\u{1466}', '\u{1467}', '\u{1468}', '\u{1469}', '\u{146A}', '\u{146B}', '\u{146C}', '\u{146D}', '\u{146E}', '\u{146F}', '\u{1470}', '\u{1471}', '\u{1472}', '\u{1473}', '\u{1474}', '\u{1475}', '\u{1476}', '\u{1477}', '\u{1478}', '\u{1479}', '\u{147A}', '\u{147B}', '\u{147C}', '\u{147D}', '\u{147E}', '\u{147F}', '\u{1480}', '\u{1481}', '\u{1482}', '\u{1483}', '\u{1484}', '\u{1485}', '\u{1486}', '\u{1487}', '\u{1488}', '\u{1489}', '\u{148A}', '\u{148B}', '\u{148C}', '\u{148D}', '\u{148E}', '\u{148F}', '\u{1490}', '\u{1491}', '\u{1492}', '\u{1493}', '\u{1494}', '\u{1495}', '\u{1496}', '\u{1497}', '\u{1498}', '\u{1499}', '\u{149A}', '\u{149B}', '\u{149C}', '\u{149D}', '\u{149E}', '\u{149F}', '\u{14A0}', '\u{14A1}', '\u{14A2}', '\u{14A3}', '\u{14A4}', '\u{14A5}', '\u{14A6}', '\u{14A7}', '\u{14A8}', '\u{14A9}', '\u{14AA}', '\u{14AB}', '\u{14AC}', '\u{14AD}', '\u{14AE}', '\u{14AF}', '\u{14B0}', '\u{14B1}', '\u{14B2}', '\u{14B3}', '\u{14B4}', '\u{14B5}', '\u{14B6}', '\u{14B7}', '\u{14B8}', '\u{14B9}', '\u{14BA}', '\u{14BB}', '\u{14BC}', '\u{14BD}', '\u{14BE}', '\u{14BF}', '\u{14C0}', '\u{14C1}', '\u{14C2}', '\u{14C3}', '\u{14C4}', '\u{14C5}', '\u{14C6}', '\u{14C7}', '\u{14C8}', '\u{14C9}', '\u{14CA}', '\u{14CB}', '\u{14CC}', '\u{14CD}', '\u{14CE}', '\u{14CF}', '\u{14D0}', '\u{14D1}', '\u{14D2}', '\u{14D3}', '\u{14D4}', '\u{14D5}', '\u{14D6}', '\u{14D7}', '\u{14D8}', '\u{14D9}', '\u{14DA}', '\u{14DB}', '\u{14DC}', '\u{14DD}', '\u{14DE}', '\u{14DF}', '\u{14E0}', '\u{14E1}', '\u{14E2}', '\u{14E3}', '\u{14E4}', '\u{14E5}', '\u{14E6}', '\u{14E7}', '\u{14E8}', '\u{14E9}', '\u{14EA}', '\u{14EB}', '\u{14EC}', '\u{14ED}', '\u{14EE}', '\u{14EF}', '\u{14F0}', '\u{14F1}', '\u{14F2}', '\u{14F3}', '\u{14F4}', '\u{14F5}', '\u{14F6}', '\u{14F7}', '\u{14F8}', '\u{14F9}', '\u{14FA}', '\u{14FB}', '\u{14FC}', '\u{14FD}', '\u{14FE}', '\u{14FF}', '\u{1500}', '\u{1501}', '\u{1502}', '\u{1503}', '\u{1504}', '\u{1505}', '\u{1506}', '\u{1507}', '\u{1508}', '\u{1509}', '\u{150A}', '\u{150B}', '\u{150C}', '\u{150D}', '\u{150E}', '\u{150F}', '\u{1510}', '\u{1511}', '\u{1512}', '\u{1513}', '\u{1514}', '\u{1515}', '\u{1516}', '\u{1517}', '\u{1518}', '\u{1519}', '\u{151A}', '\u{151B}', '\u{151C}', '\u{151D}', '\u{151E}', '\u{151F}', '\u{1520}', '\u{1521}', '\u{1522}', '\u{1523}', '\u{1524}', '\u{1525}', '\u{1526}', '\u{1527}', '\u{1528}', '\u{1529}', '\u{152A}', '\u{152B}', '\u{152C}', '\u{152D}', '\u{152E}', '\u{152F}', '\u{1530}', '\u{1531}', '\u{1532}', '\u{1533}', '\u{1534}', '\u{1535}', '\u{1536}', '\u{1537}', '\u{1538}', '\u{1539}', '\u{153A}', '\u{153B}', '\u{153C}', '\u{153D}', '\u{153E}', '\u{153F}', '\u{1540}', '\u{1541}', '\u{1542}', '\u{1543}', '\u{1544}', '\u{1545}', '\u{1546}', '\u{1547}', '\u{1548}', '\u{1549}', '\u{154A}', '\u{154B}', '\u{154C}', '\u{154D}', '\u{154E}', '\u{154F}', '\u{1550}', '\u{1551}', '\u{1552}', '\u{1553}', '\u{1554}', '\u{1555}', '\u{1556}', '\u{1557}', '\u{1558}', '\u{1559}', '\u{155A}', '\u{155B}', '\u{155C}', '\u{155D}', '\u{155E}', '\u{155F}', '\u{1560}', '\u{1561}', '\u{1562}', '\u{1563}', '\u{1564}', '\u{1565}', '\u{1566}', '\u{1567}', '\u{1568}', '\u{1569}', '\u{156A}', '\u{156B}', '\u{156C}', '\u{156D}', '\u{156E}', '\u{156F}', '\u{1570}', '\u{1571}', '\u{1572}', '\u{1573}', '\u{1574}', '\u{1575}', '\u{1576}', '\u{1577}', '\u{1578}', '\u{1579}', '\u{157A}', '\u{157B}', '\u{157C}', '\u{157D}', '\u{157E}', '\u{157F}', '\u{1580}', '\u{1581}', '\u{1582}', '\u{1583}', '\u{1584}', '\u{1585}', '\u{1586}', '\u{1587}', '\u{1588}', '\u{1589}', '\u{158A}', '\u{158B}', '\u{158C}', '\u{158D}', '\u{158E}', '\u{158F}', '\u{1590}', '\u{1591}', '\u{1592}', '\u{1593}', '\u{1594}', '\u{1595}', '\u{1596}', '\u{1597}', '\u{1598}', '\u{1599}', '\u{159A}', '\u{159B}', '\u{159C}', '\u{159D}', '\u{159E}', '\u{159F}', '\u{15A0}', '\u{15A1}', '\u{15A2}', '\u{15A3}', '\u{15A4}', '\u{15A5}', '\u{15A6}', '\u{15A7}', '\u{15A8}', '\u{15A9}', '\u{15AA}', '\u{15AB}', '\u{15AC}', '\u{15AD}', '\u{15AE}', '\u{15AF}', '\u{15B0}', '\u{15B1}', '\u{15B2}', '\u{15B3}', '\u{15B4}', '\u{15B5}', '\u{15B6}', '\u{15B7}', '\u{15B8}', '\u{15B9}', '\u{15BA}', '\u{15BB}', '\u{15BC}', '\u{15BD}', '\u{15BE}', '\u{15BF}', '\u{15C0}', '\u{15C1}', '\u{15C2}', '\u{15C3}', '\u{15C4}', '\u{15C5}', '\u{15C6}', '\u{15C7}', '\u{15C8}', '\u{15C9}', '\u{15CA}', '\u{15CB}', '\u{15CC}', '\u{15CD}', '\u{15CE}', '\u{15CF}', '\u{15D0}', '\u{15D1}', '\u{15D2}', '\u{15D3}', '\u{15D4}', '\u{15D5}', '\u{15D6}', '\u{15D7}', '\u{15D8}', '\u{15D9}', '\u{15DA}', '\u{15DB}', '\u{15DC}', '\u{15DD}', '\u{15DE}', '\u{15DF}', '\u{15E0}', '\u{15E1}', '\u{15E2}', '\u{15E3}', '\u{15E4}', '\u{15E5}', '\u{15E6}', '\u{15E7}', '\u{15E8}', '\u{15E9}', '\u{15EA}', '\u{15EB}', '\u{15EC}', '\u{15ED}', '\u{15EE}', '\u{15EF}', '\u{15F0}', '\u{15F1}', '\u{15F2}', '\u{15F3}', '\u{15F4}', '\u{15F5}', '\u{15F6}', '\u{15F7}', '\u{15F8}', '\u{15F9}', '\u{15FA}', '\u{15FB}', '\u{15FC}', '\u{15FD}', '\u{15FE}', '\u{15FF}', '\u{1600}', '\u{1601}', '\u{1602}', '\u{1603}', '\u{1604}', '\u{1605}', '\u{1606}', '\u{1607}', '\u{1608}', '\u{1609}', '\u{160A}', '\u{160B}', '\u{160C}', '\u{160D}', '\u{160E}', '\u{160F}', '\u{1610}', '\u{1611}', '\u{1612}', '\u{1613}', '\u{1614}', '\u{1615}', '\u{1616}', '\u{1617}', '\u{1618}', '\u{1619}', '\u{161A}', '\u{161B}', '\u{161C}', '\u{161D}', '\u{161E}', '\u{161F}', '\u{1620}', '\u{1621}', '\u{1622}', '\u{1623}', '\u{1624}', '\u{1625}', '\u{1626}', '\u{1627}', '\u{1628}', '\u{1629}', '\u{162A}', '\u{162B}', '\u{162C}', '\u{162D}', '\u{162E}', '\u{162F}', '\u{1630}', '\u{1631}', '\u{1632}', '\u{1633}', '\u{1634}', '\u{1635}', '\u{1636}', '\u{1637}', '\u{1638}', '\u{1639}', '\u{163A}', '\u{163B}', '\u{163C}', '\u{163D}', '\u{163E}', '\u{163F}', '\u{1640}', '\u{1641}', '\u{1642}', '\u{1643}', '\u{1644}', '\u{1645}', '\u{1646}', '\u{1647}', '\u{1648}', '\u{1649}', '\u{164A}', '\u{164B}', '\u{164C}', '\u{164D}', '\u{164E}', '\u{164F}', '\u{1650}', '\u{1651}', '\u{1652}', '\u{1653}', '\u{1654}', '\u{1655}', '\u{1656}', '\u{1657}', '\u{1658}', '\u{1659}', '\u{165A}', '\u{165B}', '\u{165C}', '\u{165D}', '\u{165E}', '\u{165F}', '\u{1660}', '\u{1661}', '\u{1662}', '\u{1663}', '\u{1664}', '\u{1665}', '\u{1666}', '\u{1667}', '\u{1668}', '\u{1669}', '\u{166A}', '\u{166B}', '\u{166C}', '\u{166F}', '\u{1670}', '\u{1671}', '\u{1672}', '\u{1673}', '\u{1674}', '\u{1675}', '\u{1676}', '\u{1681}', '\u{1682}', '\u{1683}', '\u{1684}', '\u{1685}', '\u{1686}', '\u{1687}', '\u{1688}', '\u{1689}', '\u{168A}', '\u{168B}', '\u{168C}', '\u{168D}', '\u{168E}', '\u{168F}', '\u{1690}', '\u{1691}', '\u{1692}', '\u{1693}', '\u{1694}', '\u{1695}', '\u{1696}', '\u{1697}', '\u{1698}', '\u{1699}', '\u{169A}', '\u{16A0}', '\u{16A1}', '\u{16A2}', '\u{16A3}', '\u{16A4}', '\u{16A5}', '\u{16A6}', '\u{16A7}', '\u{16A8}', '\u{16A9}', '\u{16AA}', '\u{16AB}', '\u{16AC}', '\u{16AD}', '\u{16AE}', '\u{16AF}', '\u{16B0}', '\u{16B1}', '\u{16B2}', '\u{16B3}', '\u{16B4}', '\u{16B5}', '\u{16B6}', '\u{16B7}', '\u{16B8}', '\u{16B9}', '\u{16BA}', '\u{16BB}', '\u{16BC}', '\u{16BD}', '\u{16BE}', '\u{16BF}', '\u{16C0}', '\u{16C1}', '\u{16C2}', '\u{16C3}', '\u{16C4}', '\u{16C5}', '\u{16C6}', '\u{16C7}', '\u{16C8}', '\u{16C9}', '\u{16CA}', '\u{16CB}', '\u{16CC}', '\u{16CD}', '\u{16CE}', '\u{16CF}', '\u{16D0}', '\u{16D1}', '\u{16D2}', '\u{16D3}', '\u{16D4}', '\u{16D5}', '\u{16D6}', '\u{16D7}', '\u{16D8}', '\u{16D9}', '\u{16DA}', '\u{16DB}', '\u{16DC}', '\u{16DD}', '\u{16DE}', '\u{16DF}', '\u{16E0}', '\u{16E1}', '\u{16E2}', '\u{16E3}', '\u{16E4}', '\u{16E5}', '\u{16E6}', '\u{16E7}', '\u{16E8}', '\u{16E9}', '\u{16EA}', '\u{1700}', '\u{1701}', '\u{1702}', '\u{1703}', '\u{1704}', '\u{1705}', '\u{1706}', '\u{1707}', '\u{1708}', '\u{1709}', '\u{170A}', '\u{170B}', '\u{170C}', '\u{170E}', '\u{170F}', '\u{1710}', '\u{1711}', '\u{1720}', '\u{1721}', '\u{1722}', '\u{1723}', '\u{1724}', '\u{1725}', '\u{1726}', '\u{1727}', '\u{1728}', '\u{1729}', '\u{172A}', '\u{172B}', '\u{172C}', '\u{172D}', '\u{172E}', '\u{172F}', '\u{1730}', '\u{1731}', '\u{1740}', '\u{1741}', '\u{1742}', '\u{1743}', '\u{1744}', '\u{1745}', '\u{1746}', '\u{1747}', '\u{1748}', '\u{1749}', '\u{174A}', '\u{174B}', '\u{174C}', '\u{174D}', '\u{174E}', '\u{174F}', '\u{1750}', '\u{1751}', '\u{1760}', '\u{1761}', '\u{1762}', '\u{1763}', '\u{1764}', '\u{1765}', '\u{1766}', '\u{1767}', '\u{1768}', '\u{1769}', '\u{176A}', '\u{176B}', '\u{176C}', '\u{176E}', '\u{176F}', '\u{1770}', '\u{1780}', '\u{1781}', '\u{1782}', '\u{1783}', '\u{1784}', '\u{1785}', '\u{1786}', '\u{1787}', '\u{1788}', '\u{1789}', '\u{178A}', '\u{178B}', '\u{178C}', '\u{178D}', '\u{178E}', '\u{178F}', '\u{1790}', '\u{1791}', '\u{1792}', '\u{1793}', '\u{1794}', '\u{1795}', '\u{1796}', '\u{1797}', '\u{1798}', '\u{1799}', '\u{179A}', '\u{179B}', '\u{179C}', '\u{179D}', '\u{179E}', '\u{179F}', '\u{17A0}', '\u{17A1}', '\u{17A2}', '\u{17A3}', '\u{17A4}', '\u{17A5}', '\u{17A6}', '\u{17A7}', '\u{17A8}', '\u{17A9}', '\u{17AA}', '\u{17AB}', '\u{17AC}', '\u{17AD}', '\u{17AE}', '\u{17AF}', '\u{17B0}', '\u{17B1}', '\u{17B2}', '\u{17B3}', '\u{17DC}', '\u{1820}', '\u{1821}', '\u{1822}', '\u{1823}', '\u{1824}', '\u{1825}', '\u{1826}', '\u{1827}', '\u{1828}', '\u{1829}', '\u{182A}', '\u{182B}', '\u{182C}', '\u{182D}', '\u{182E}', '\u{182F}', '\u{1830}', '\u{1831}', '\u{1832}', '\u{1833}', '\u{1834}', '\u{1835}', '\u{1836}', '\u{1837}', '\u{1838}', '\u{1839}', '\u{183A}', '\u{183B}', '\u{183C}', '\u{183D}', '\u{183E}', '\u{183F}', '\u{1840}', '\u{1841}', '\u{1842}', '\u{1844}', '\u{1845}', '\u{1846}', '\u{1847}', '\u{1848}', '\u{1849}', '\u{184A}', '\u{184B}', '\u{184C}', '\u{184D}', '\u{184E}', '\u{184F}', '\u{1850}', '\u{1851}', '\u{1852}', '\u{1853}', '\u{1854}', '\u{1855}', '\u{1856}', '\u{1857}', '\u{1858}', '\u{1859}', '\u{185A}', '\u{185B}', '\u{185C}', '\u{185D}', '\u{185E}', '\u{185F}', '\u{1860}', '\u{1861}', '\u{1862}', '\u{1863}', '\u{1864}', '\u{1865}', '\u{1866}', '\u{1867}', '\u{1868}', '\u{1869}', '\u{186A}', '\u{186B}', '\u{186C}', '\u{186D}', '\u{186E}', '\u{186F}', '\u{1870}', '\u{1871}', '\u{1872}', '\u{1873}', '\u{1874}', '\u{1875}', '\u{1876}', '\u{1877}', '\u{1880}', '\u{1881}', '\u{1882}', '\u{1883}', '\u{1884}', '\u{1885}', '\u{1886}', '\u{1887}', '\u{1888}', '\u{1889}', '\u{188A}', '\u{188B}', '\u{188C}', '\u{188D}', '\u{188E}', '\u{188F}', '\u{1890}', '\u{1891}', '\u{1892}', '\u{1893}', '\u{1894}', '\u{1895}', '\u{1896}', '\u{1897}', '\u{1898}', '\u{1899}', '\u{189A}', '\u{189B}', '\u{189C}', '\u{189D}', '\u{189E}', '\u{189F}', '\u{18A0}', '\u{18A1}', '\u{18A2}', '\u{18A3}', '\u{18A4}', '\u{18A5}', '\u{18A6}', '\u{18A7}', '\u{18A8}', '\u{18AA}', '\u{1900}', '\u{1901}', '\u{1902}', '\u{1903}', '\u{1904}', '\u{1905}', '\u{1906}', '\u{1907}', '\u{1908}', '\u{1909}', '\u{190A}', '\u{190B}', '\u{190C}', '\u{190D}', '\u{190E}', '\u{190F}', '\u{1910}', '\u{1911}', '\u{1912}', '\u{1913}', '\u{1914}', '\u{1915}', '\u{1916}', '\u{1917}', '\u{1918}', '\u{1919}', '\u{191A}', '\u{191B}', '\u{191C}', '\u{1950}', '\u{1951}', '\u{1952}', '\u{1953}', '\u{1954}', '\u{1955}', '\u{1956}', '\u{1957}', '\u{1958}', '\u{1959}', '\u{195A}', '\u{195B}', '\u{195C}', '\u{195D}', '\u{195E}', '\u{195F}', '\u{1960}', '\u{1961}', '\u{1962}', '\u{1963}', '\u{1964}', '\u{1965}', '\u{1966}', '\u{1967}', '\u{1968}', '\u{1969}', '\u{196A}', '\u{196B}', '\u{196C}', '\u{196D}', '\u{1970}', '\u{1971}', '\u{1972}', '\u{1973}', '\u{1974}', '\u{1980}', '\u{1981}', '\u{1982}', '\u{1983}', '\u{1984}', '\u{1985}', '\u{1986}', '\u{1987}', '\u{1988}', '\u{1989}', '\u{198A}', '\u{198B}', '\u{198C}', '\u{198D}', '\u{198E}', '\u{198F}', '\u{1990}', '\u{1991}', '\u{1992}', '\u{1993}', '\u{1994}', '\u{1995}', '\u{1996}', '\u{1997}', '\u{1998}', '\u{1999}', '\u{199A}', '\u{199B}', '\u{199C}', '\u{199D}', '\u{199E}', '\u{199F}', '\u{19A0}', '\u{19A1}', '\u{19A2}', '\u{19A3}', '\u{19A4}', '\u{19A5}', '\u{19A6}', '\u{19A7}', '\u{19A8}', '\u{19A9}', '\u{19C1}', '\u{19C2}', '\u{19C3}', '\u{19C4}', '\u{19C5}', '\u{19C6}', '\u{19C7}', '\u{1A00}', '\u{1A01}', '\u{1A02}', '\u{1A03}', '\u{1A04}', '\u{1A05}', '\u{1A06}', '\u{1A07}', '\u{1A08}', '\u{1A09}', '\u{1A0A}', '\u{1A0B}', '\u{1A0C}', '\u{1A0D}', '\u{1A0E}', '\u{1A0F}', '\u{1A10}', '\u{1A11}', '\u{1A12}', '\u{1A13}', '\u{1A14}', '\u{1A15}', '\u{1A16}', '\u{1B05}', '\u{1B06}', '\u{1B07}', '\u{1B08}', '\u{1B09}', '\u{1B0A}', '\u{1B0B}', '\u{1B0C}', '\u{1B0D}', '\u{1B0E}', '\u{1B0F}', '\u{1B10}', '\u{1B11}', '\u{1B12}', '\u{1B13}', '\u{1B14}', '\u{1B15}', '\u{1B16}', '\u{1B17}', '\u{1B18}', '\u{1B19}', '\u{1B1A}', '\u{1B1B}', '\u{1B1C}', '\u{1B1D}', '\u{1B1E}', '\u{1B1F}', '\u{1B20}', '\u{1B21}', '\u{1B22}', '\u{1B23}', '\u{1B24}', '\u{1B25}', '\u{1B26}', '\u{1B27}', '\u{1B28}', '\u{1B29}', '\u{1B2A}', '\u{1B2B}', '\u{1B2C}', '\u{1B2D}', '\u{1B2E}', '\u{1B2F}', '\u{1B30}', '\u{1B31}', '\u{1B32}', '\u{1B33}', '\u{1B45}', '\u{1B46}', '\u{1B47}', '\u{1B48}', '\u{1B49}', '\u{1B4A}', '\u{1B4B}', '\u{1B83}', '\u{1B84}', '\u{1B85}', '\u{1B86}', '\u{1B87}', '\u{1B88}', '\u{1B89}', '\u{1B8A}', '\u{1B8B}', '\u{1B8C}', '\u{1B8D}', '\u{1B8E}', '\u{1B8F}', '\u{1B90}', '\u{1B91}', '\u{1B92}', '\u{1B93}', '\u{1B94}', '\u{1B95}', '\u{1B96}', '\u{1B97}', '\u{1B98}', '\u{1B99}', '\u{1B9A}', '\u{1B9B}', '\u{1B9C}', '\u{1B9D}', '\u{1B9E}', '\u{1B9F}', '\u{1BA0}', '\u{1BAE}', '\u{1BAF}', '\u{1C00}', '\u{1C01}', '\u{1C02}', '\u{1C03}', '\u{1C04}', '\u{1C05}', '\u{1C06}', '\u{1C07}', '\u{1C08}', '\u{1C09}', '\u{1C0A}', '\u{1C0B}', '\u{1C0C}', '\u{1C0D}', '\u{1C0E}', '\u{1C0F}', '\u{1C10}', '\u{1C11}', '\u{1C12}', '\u{1C13}', '\u{1C14}', '\u{1C15}', '\u{1C16}', '\u{1C17}', '\u{1C18}', '\u{1C19}', '\u{1C1A}', '\u{1C1B}', '\u{1C1C}', '\u{1C1D}', '\u{1C1E}', '\u{1C1F}', '\u{1C20}', '\u{1C21}', '\u{1C22}', '\u{1C23}', '\u{1C4D}', '\u{1C4E}', '\u{1C4F}', '\u{1C5A}', '\u{1C5B}', '\u{1C5C}', '\u{1C5D}', '\u{1C5E}', '\u{1C5F}', '\u{1C60}', '\u{1C61}', '\u{1C62}', '\u{1C63}', '\u{1C64}', '\u{1C65}', '\u{1C66}', '\u{1C67}', '\u{1C68}', '\u{1C69}', '\u{1C6A}', '\u{1C6B}', '\u{1C6C}', '\u{1C6D}', '\u{1C6E}', '\u{1C6F}', '\u{1C70}', '\u{1C71}', '\u{1C72}', '\u{1C73}', '\u{1C74}', '\u{1C75}', '\u{1C76}', '\u{1C77}', '\u{2135}', '\u{2136}', '\u{2137}', '\u{2138}', '\u{2D30}', '\u{2D31}', '\u{2D32}', '\u{2D33}', '\u{2D34}', '\u{2D35}', '\u{2D36}', '\u{2D37}', '\u{2D38}', '\u{2D39}', '\u{2D3A}', '\u{2D3B}', '\u{2D3C}', '\u{2D3D}', '\u{2D3E}', '\u{2D3F}', '\u{2D40}', '\u{2D41}', '\u{2D42}', '\u{2D43}', '\u{2D44}', '\u{2D45}', '\u{2D46}', '\u{2D47}', '\u{2D48}', '\u{2D49}', '\u{2D4A}', '\u{2D4B}', '\u{2D4C}', '\u{2D4D}', '\u{2D4E}', '\u{2D4F}', '\u{2D50}', '\u{2D51}', '\u{2D52}', '\u{2D53}', '\u{2D54}', '\u{2D55}', '\u{2D56}', '\u{2D57}', '\u{2D58}', '\u{2D59}', '\u{2D5A}', '\u{2D5B}', '\u{2D5C}', '\u{2D5D}', '\u{2D5E}', '\u{2D5F}', '\u{2D60}', '\u{2D61}', '\u{2D62}', '\u{2D63}', '\u{2D64}', '\u{2D65}', '\u{2D80}', '\u{2D81}', '\u{2D82}', '\u{2D83}', '\u{2D84}', '\u{2D85}', '\u{2D86}', '\u{2D87}', '\u{2D88}', '\u{2D89}', '\u{2D8A}', '\u{2D8B}', '\u{2D8C}', '\u{2D8D}', '\u{2D8E}', '\u{2D8F}', '\u{2D90}', '\u{2D91}', '\u{2D92}', '\u{2D93}', '\u{2D94}', '\u{2D95}', '\u{2D96}', '\u{2DA0}', '\u{2DA1}', '\u{2DA2}', '\u{2DA3}', '\u{2DA4}', '\u{2DA5}', '\u{2DA6}', '\u{2DA8}', '\u{2DA9}', '\u{2DAA}', '\u{2DAB}', '\u{2DAC}', '\u{2DAD}', '\u{2DAE}', '\u{2DB0}', '\u{2DB1}', '\u{2DB2}', '\u{2DB3}', '\u{2DB4}', '\u{2DB5}', '\u{2DB6}', '\u{2DB8}', '\u{2DB9}', '\u{2DBA}', '\u{2DBB}', '\u{2DBC}', '\u{2DBD}', '\u{2DBE}', '\u{2DC0}', '\u{2DC1}', '\u{2DC2}', '\u{2DC3}', '\u{2DC4}', '\u{2DC5}', '\u{2DC6}', '\u{2DC8}', '\u{2DC9}', '\u{2DCA}', '\u{2DCB}', '\u{2DCC}', '\u{2DCD}', '\u{2DCE}', '\u{2DD0}', '\u{2DD1}', '\u{2DD2}', '\u{2DD3}', '\u{2DD4}', '\u{2DD5}', '\u{2DD6}', '\u{2DD8}', '\u{2DD9}', '\u{2DDA}', '\u{2DDB}', '\u{2DDC}', '\u{2DDD}', '\u{2DDE}', '\u{3006}', '\u{303C}', '\u{3041}', '\u{3042}', '\u{3043}', '\u{3044}', '\u{3045}', '\u{3046}', '\u{3047}', '\u{3048}', '\u{3049}', '\u{304A}', '\u{304B}', '\u{304C}', '\u{304D}', '\u{304E}', '\u{304F}', '\u{3050}', '\u{3051}', '\u{3052}', '\u{3053}', '\u{3054}', '\u{3055}', '\u{3056}', '\u{3057}', '\u{3058}', '\u{3059}', '\u{305A}', '\u{305B}', '\u{305C}', '\u{305D}', '\u{305E}', '\u{305F}', '\u{3060}', '\u{3061}', '\u{3062}', '\u{3063}', '\u{3064}', '\u{3065}', '\u{3066}', '\u{3067}', '\u{3068}', '\u{3069}', '\u{306A}', '\u{306B}', '\u{306C}', '\u{306D}', '\u{306E}', '\u{306F}', '\u{3070}', '\u{3071}', '\u{3072}', '\u{3073}', '\u{3074}', '\u{3075}', '\u{3076}', '\u{3077}', '\u{3078}', '\u{3079}', '\u{307A}', '\u{307B}', '\u{307C}', '\u{307D}', '\u{307E}', '\u{307F}', '\u{3080}', '\u{3081}', '\u{3082}', '\u{3083}', '\u{3084}', '\u{3085}', '\u{3086}', '\u{3087}', '\u{3088}', '\u{3089}', '\u{308A}', '\u{308B}', '\u{308C}', '\u{308D}', '\u{308E}', '\u{308F}', '\u{3090}', '\u{3091}', '\u{3092}', '\u{3093}', '\u{3094}', '\u{3095}', '\u{3096}', '\u{309F}', '\u{30A1}', '\u{30A2}', '\u{30A3}', '\u{30A4}', '\u{30A5}', '\u{30A6}', '\u{30A7}', '\u{30A8}', '\u{30A9}', '\u{30AA}', '\u{30AB}', '\u{30AC}', '\u{30AD}', '\u{30AE}', '\u{30AF}', '\u{30B0}', '\u{30B1}', '\u{30B2}', '\u{30B3}', '\u{30B4}', '\u{30B5}', '\u{30B6}', '\u{30B7}', '\u{30B8}', '\u{30B9}', '\u{30BA}', '\u{30BB}', '\u{30BC}', '\u{30BD}', '\u{30BE}', '\u{30BF}', '\u{30C0}', '\u{30C1}', '\u{30C2}', '\u{30C3}', '\u{30C4}', '\u{30C5}', '\u{30C6}', '\u{30C7}', '\u{30C8}', '\u{30C9}', '\u{30CA}', '\u{30CB}', '\u{30CC}', '\u{30CD}', '\u{30CE}', '\u{30CF}', '\u{30D0}', '\u{30D1}', '\u{30D2}', '\u{30D3}', '\u{30D4}', '\u{30D5}', '\u{30D6}', '\u{30D7}', '\u{30D8}', '\u{30D9}', '\u{30DA}', '\u{30DB}', '\u{30DC}', '\u{30DD}', '\u{30DE}', '\u{30DF}', '\u{30E0}', '\u{30E1}', '\u{30E2}', '\u{30E3}', '\u{30E4}', '\u{30E5}', '\u{30E6}', '\u{30E7}', '\u{30E8}', '\u{30E9}', '\u{30EA}', '\u{30EB}', '\u{30EC}', '\u{30ED}', '\u{30EE}', '\u{30EF}', '\u{30F0}', '\u{30F1}', '\u{30F2}', '\u{30F3}', '\u{30F4}', '\u{30F5}', '\u{30F6}', '\u{30F7}', '\u{30F8}', '\u{30F9}', '\u{30FA}', '\u{30FF}', '\u{3105}', '\u{3106}', '\u{3107}', '\u{3108}', '\u{3109}', '\u{310A}', '\u{310B}', '\u{310C}', '\u{310D}', '\u{310E}', '\u{310F}', '\u{3110}', '\u{3111}', '\u{3112}', '\u{3113}', '\u{3114}', '\u{3115}', '\u{3116}', '\u{3117}', '\u{3118}', '\u{3119}', '\u{311A}', '\u{311B}', '\u{311C}', '\u{311D}', '\u{311E}', '\u{311F}', '\u{3120}', '\u{3121}', '\u{3122}', '\u{3123}', '\u{3124}', '\u{3125}', '\u{3126}', '\u{3127}', '\u{3128}', '\u{3129}', '\u{312A}', '\u{312B}', '\u{312C}', '\u{312D}', '\u{3131}', '\u{3132}', '\u{3133}', '\u{3134}', '\u{3135}', '\u{3136}', '\u{3137}', '\u{3138}', '\u{3139}', '\u{313A}', '\u{313B}', '\u{313C}', '\u{313D}', '\u{313E}', '\u{313F}', '\u{3140}', '\u{3141}', '\u{3142}', '\u{3143}', '\u{3144}', '\u{3145}', '\u{3146}', '\u{3147}', '\u{3148}', '\u{3149}', '\u{314A}', '\u{314B}', '\u{314C}', '\u{314D}', '\u{314E}', '\u{314F}', '\u{3150}', '\u{3151}', '\u{3152}', '\u{3153}', '\u{3154}', '\u{3155}', '\u{3156}', '\u{3157}', '\u{3158}', '\u{3159}', '\u{315A}', '\u{315B}', '\u{315C}', '\u{315D}', '\u{315E}', '\u{315F}', '\u{3160}', '\u{3161}', '\u{3162}', '\u{3163}', '\u{3164}', '\u{3165}', '\u{3166}', '\u{3167}', '\u{3168}', '\u{3169}', '\u{316A}', '\u{316B}', '\u{316C}', '\u{316D}', '\u{316E}', '\u{316F}', '\u{3170}', '\u{3171}', '\u{3172}', '\u{3173}', '\u{3174}', '\u{3175}', '\u{3176}', '\u{3177}', '\u{3178}', '\u{3179}', '\u{317A}', '\u{317B}', '\u{317C}', '\u{317D}', '\u{317E}', '\u{317F}', '\u{3180}', '\u{3181}', '\u{3182}', '\u{3183}', '\u{3184}', '\u{3185}', '\u{3186}', '\u{3187}', '\u{3188}', '\u{3189}', '\u{318A}', '\u{318B}', '\u{318C}', '\u{318D}', '\u{318E}', '\u{31A0}', '\u{31A1}', '\u{31A2}', '\u{31A3}', '\u{31A4}', '\u{31A5}', '\u{31A6}', '\u{31A7}', '\u{31A8}', '\u{31A9}', '\u{31AA}', '\u{31AB}', '\u{31AC}', '\u{31AD}', '\u{31AE}', '\u{31AF}', '\u{31B0}', '\u{31B1}', '\u{31B2}', '\u{31B3}', '\u{31B4}', '\u{31B5}', '\u{31B6}', '\u{31B7}', '\u{31F0}', '\u{31F1}', '\u{31F2}', '\u{31F3}', '\u{31F4}', '\u{31F5}', '\u{31F6}', '\u{31F7}', '\u{31F8}', '\u{31F9}', '\u{31FA}', '\u{31FB}', '\u{31FC}', '\u{31FD}', '\u{31FE}', '\u{31FF}', '\u{3400}', '\u{4DB5}', '\u{4E00}', '\u{9FC3}', '\u{A000}', '\u{A001}', '\u{A002}', '\u{A003}', '\u{A004}', '\u{A005}', '\u{A006}', '\u{A007}', '\u{A008}', '\u{A009}', '\u{A00A}', '\u{A00B}', '\u{A00C}', '\u{A00D}', '\u{A00E}', '\u{A00F}', '\u{A010}', '\u{A011}', '\u{A012}', '\u{A013}', '\u{A014}', '\u{A016}', '\u{A017}', '\u{A018}', '\u{A019}', '\u{A01A}', '\u{A01B}', '\u{A01C}', '\u{A01D}', '\u{A01E}', '\u{A01F}', '\u{A020}', '\u{A021}', '\u{A022}', '\u{A023}', '\u{A024}', '\u{A025}', '\u{A026}', '\u{A027}', '\u{A028}', '\u{A029}', '\u{A02A}', '\u{A02B}', '\u{A02C}', '\u{A02D}', '\u{A02E}', '\u{A02F}', '\u{A030}', '\u{A031}', '\u{A032}', '\u{A033}', '\u{A034}', '\u{A035}', '\u{A036}', '\u{A037}', '\u{A038}', '\u{A039}', '\u{A03A}', '\u{A03B}', '\u{A03C}', '\u{A03D}', '\u{A03E}', '\u{A03F}', '\u{A040}', '\u{A041}', '\u{A042}', '\u{A043}', '\u{A044}', '\u{A045}', '\u{A046}', '\u{A047}', '\u{A048}', '\u{A049}', '\u{A04A}', '\u{A04B}', '\u{A04C}', '\u{A04D}', '\u{A04E}', '\u{A04F}', '\u{A050}', '\u{A051}', '\u{A052}', '\u{A053}', '\u{A054}', '\u{A055}', '\u{A056}', '\u{A057}', '\u{A058}', '\u{A059}', '\u{A05A}', '\u{A05B}', '\u{A05C}', '\u{A05D}', '\u{A05E}', '\u{A05F}', '\u{A060}', '\u{A061}', '\u{A062}', '\u{A063}', '\u{A064}', '\u{A065}', '\u{A066}', '\u{A067}', '\u{A068}', '\u{A069}', '\u{A06A}', '\u{A06B}', '\u{A06C}', '\u{A06D}', '\u{A06E}', '\u{A06F}', '\u{A070}', '\u{A071}', '\u{A072}', '\u{A073}', '\u{A074}', '\u{A075}', '\u{A076}', '\u{A077}', '\u{A078}', '\u{A079}', '\u{A07A}', '\u{A07B}', '\u{A07C}', '\u{A07D}', '\u{A07E}', '\u{A07F}', '\u{A080}', '\u{A081}', '\u{A082}', '\u{A083}', '\u{A084}', '\u{A085}', '\u{A086}', '\u{A087}', '\u{A088}', '\u{A089}', '\u{A08A}', '\u{A08B}', '\u{A08C}', '\u{A08D}', '\u{A08E}', '\u{A08F}', '\u{A090}', '\u{A091}', '\u{A092}', '\u{A093}', '\u{A094}', '\u{A095}', '\u{A096}', '\u{A097}', '\u{A098}', '\u{A099}', '\u{A09A}', '\u{A09B}', '\u{A09C}', '\u{A09D}', '\u{A09E}', '\u{A09F}', '\u{A0A0}', '\u{A0A1}', '\u{A0A2}', '\u{A0A3}', '\u{A0A4}', '\u{A0A5}', '\u{A0A6}', '\u{A0A7}', '\u{A0A8}', '\u{A0A9}', '\u{A0AA}', '\u{A0AB}', '\u{A0AC}', '\u{A0AD}', '\u{A0AE}', '\u{A0AF}', '\u{A0B0}', '\u{A0B1}', '\u{A0B2}', '\u{A0B3}', '\u{A0B4}', '\u{A0B5}', '\u{A0B6}', '\u{A0B7}', '\u{A0B8}', '\u{A0B9}', '\u{A0BA}', '\u{A0BB}', '\u{A0BC}', '\u{A0BD}', '\u{A0BE}', '\u{A0BF}', '\u{A0C0}', '\u{A0C1}', '\u{A0C2}', '\u{A0C3}', '\u{A0C4}', '\u{A0C5}', '\u{A0C6}', '\u{A0C7}', '\u{A0C8}', '\u{A0C9}', '\u{A0CA}', '\u{A0CB}', '\u{A0CC}', '\u{A0CD}', '\u{A0CE}', '\u{A0CF}', '\u{A0D0}', '\u{A0D1}', '\u{A0D2}', '\u{A0D3}', '\u{A0D4}', '\u{A0D5}', '\u{A0D6}', '\u{A0D7}', '\u{A0D8}', '\u{A0D9}', '\u{A0DA}', '\u{A0DB}', '\u{A0DC}', '\u{A0DD}', '\u{A0DE}', '\u{A0DF}', '\u{A0E0}', '\u{A0E1}', '\u{A0E2}', '\u{A0E3}', '\u{A0E4}', '\u{A0E5}', '\u{A0E6}', '\u{A0E7}', '\u{A0E8}', '\u{A0E9}', '\u{A0EA}', '\u{A0EB}', '\u{A0EC}', '\u{A0ED}', '\u{A0EE}', '\u{A0EF}', '\u{A0F0}', '\u{A0F1}', '\u{A0F2}', '\u{A0F3}', '\u{A0F4}', '\u{A0F5}', '\u{A0F6}', '\u{A0F7}', '\u{A0F8}', '\u{A0F9}', '\u{A0FA}', '\u{A0FB}', '\u{A0FC}', '\u{A0FD}', '\u{A0FE}', '\u{A0FF}', '\u{A100}', '\u{A101}', '\u{A102}', '\u{A103}', '\u{A104}', '\u{A105}', '\u{A106}', '\u{A107}', '\u{A108}', '\u{A109}', '\u{A10A}', '\u{A10B}', '\u{A10C}', '\u{A10D}', '\u{A10E}', '\u{A10F}', '\u{A110}', '\u{A111}', '\u{A112}', '\u{A113}', '\u{A114}', '\u{A115}', '\u{A116}', '\u{A117}', '\u{A118}', '\u{A119}', '\u{A11A}', '\u{A11B}', '\u{A11C}', '\u{A11D}', '\u{A11E}', '\u{A11F}', '\u{A120}', '\u{A121}', '\u{A122}', '\u{A123}', '\u{A124}', '\u{A125}', '\u{A126}', '\u{A127}', '\u{A128}', '\u{A129}', '\u{A12A}', '\u{A12B}', '\u{A12C}', '\u{A12D}', '\u{A12E}', '\u{A12F}', '\u{A130}', '\u{A131}', '\u{A132}', '\u{A133}', '\u{A134}', '\u{A135}', '\u{A136}', '\u{A137}', '\u{A138}', '\u{A139}', '\u{A13A}', '\u{A13B}', '\u{A13C}', '\u{A13D}', '\u{A13E}', '\u{A13F}', '\u{A140}', '\u{A141}', '\u{A142}', '\u{A143}', '\u{A144}', '\u{A145}', '\u{A146}', '\u{A147}', '\u{A148}', '\u{A149}', '\u{A14A}', '\u{A14B}', '\u{A14C}', '\u{A14D}', '\u{A14E}', '\u{A14F}', '\u{A150}', '\u{A151}', '\u{A152}', '\u{A153}', '\u{A154}', '\u{A155}', '\u{A156}', '\u{A157}', '\u{A158}', '\u{A159}', '\u{A15A}', '\u{A15B}', '\u{A15C}', '\u{A15D}', '\u{A15E}', '\u{A15F}', '\u{A160}', '\u{A161}', '\u{A162}', '\u{A163}', '\u{A164}', '\u{A165}', '\u{A166}', '\u{A167}', '\u{A168}', '\u{A169}', '\u{A16A}', '\u{A16B}', '\u{A16C}', '\u{A16D}', '\u{A16E}', '\u{A16F}', '\u{A170}', '\u{A171}', '\u{A172}', '\u{A173}', '\u{A174}', '\u{A175}', '\u{A176}', '\u{A177}', '\u{A178}', '\u{A179}', '\u{A17A}', '\u{A17B}', '\u{A17C}', '\u{A17D}', '\u{A17E}', '\u{A17F}', '\u{A180}', '\u{A181}', '\u{A182}', '\u{A183}', '\u{A184}', '\u{A185}', '\u{A186}', '\u{A187}', '\u{A188}', '\u{A189}', '\u{A18A}', '\u{A18B}', '\u{A18C}', '\u{A18D}', '\u{A18E}', '\u{A18F}', '\u{A190}', '\u{A191}', '\u{A192}', '\u{A193}', '\u{A194}', '\u{A195}', '\u{A196}', '\u{A197}', '\u{A198}', '\u{A199}', '\u{A19A}', '\u{A19B}', '\u{A19C}', '\u{A19D}', '\u{A19E}', '\u{A19F}', '\u{A1A0}', '\u{A1A1}', '\u{A1A2}', '\u{A1A3}', '\u{A1A4}', '\u{A1A5}', '\u{A1A6}', '\u{A1A7}', '\u{A1A8}', '\u{A1A9}', '\u{A1AA}', '\u{A1AB}', '\u{A1AC}', '\u{A1AD}', '\u{A1AE}', '\u{A1AF}') + } + + fn is_unicode_letter_number(self) -> bool { + match_char_class!(self, + '\u{16EE}', '\u{16EF}', '\u{16F0}', '\u{2160}', '\u{2161}', '\u{2162}', '\u{2163}', '\u{2164}', '\u{2165}', '\u{2166}', '\u{2167}', '\u{2168}', '\u{2169}', '\u{216A}', '\u{216B}', '\u{216C}', '\u{216D}', '\u{216E}', '\u{216F}', '\u{2170}', '\u{2171}', '\u{2172}', '\u{2173}', '\u{2174}', '\u{2175}', '\u{2176}', '\u{2177}', '\u{2178}', '\u{2179}', '\u{217A}', '\u{217B}', '\u{217C}', '\u{217D}', '\u{217E}', '\u{217F}', '\u{2180}', '\u{2181}', '\u{2182}', '\u{2185}', '\u{2186}', '\u{2187}', '\u{2188}', '\u{3007}', '\u{3021}', '\u{3022}', '\u{3023}', '\u{3024}', '\u{3025}', '\u{3026}', '\u{3027}', '\u{3028}', '\u{3029}', '\u{3038}', '\u{3039}', '\u{303A}') + } + + fn is_unicode_nonspacing_mark(self) -> bool { + match_char_class!(self, + '\u{0300}', '\u{0301}', '\u{0302}', '\u{0303}', '\u{0304}', '\u{0305}', '\u{0306}', '\u{0307}', '\u{0308}', '\u{0309}', '\u{030A}', '\u{030B}', '\u{030C}', '\u{030D}', '\u{030E}', '\u{030F}', '\u{0310}', '\u{0311}', '\u{0312}', '\u{0313}', '\u{0314}', '\u{0315}', '\u{0316}', '\u{0317}', '\u{0318}', '\u{0319}', '\u{031A}', '\u{031B}', '\u{031C}', '\u{031D}', '\u{031E}', '\u{031F}', '\u{0320}', '\u{0321}', '\u{0322}', '\u{0323}', '\u{0324}', '\u{0325}', '\u{0326}', '\u{0327}', '\u{0328}', '\u{0329}', '\u{032A}', '\u{032B}', '\u{032C}', '\u{032D}', '\u{032E}', '\u{032F}', '\u{0330}', '\u{0331}', '\u{0332}', '\u{0333}', '\u{0334}', '\u{0335}', '\u{0336}', '\u{0337}', '\u{0338}', '\u{0339}', '\u{033A}', '\u{033B}', '\u{033C}', '\u{033D}', '\u{033E}', '\u{033F}', '\u{0340}', '\u{0341}', '\u{0342}', '\u{0343}', '\u{0344}', '\u{0345}', '\u{0346}', '\u{0347}', '\u{0348}', '\u{0349}', '\u{034A}', '\u{034B}', '\u{034C}', '\u{034D}', '\u{034E}', '\u{034F}', '\u{0350}', '\u{0351}', '\u{0352}', '\u{0353}', '\u{0354}', '\u{0355}', '\u{0356}', '\u{0357}', '\u{0358}', '\u{0359}', '\u{035A}', '\u{035B}', '\u{035C}', '\u{035D}', '\u{035E}', '\u{035F}', '\u{0360}', '\u{0361}', '\u{0362}', '\u{0363}', '\u{0364}', '\u{0365}', '\u{0366}', '\u{0367}', '\u{0368}', '\u{0369}', '\u{036A}', '\u{036B}', '\u{036C}', '\u{036D}', '\u{036E}', '\u{036F}', '\u{0483}', '\u{0484}', '\u{0485}', '\u{0486}', '\u{0487}', '\u{0591}', '\u{0592}', '\u{0593}', '\u{0594}', '\u{0595}', '\u{0596}', '\u{0597}', '\u{0598}', '\u{0599}', '\u{059A}', '\u{059B}', '\u{059C}', '\u{059D}', '\u{059E}', '\u{059F}', '\u{05A0}', '\u{05A1}', '\u{05A2}', '\u{05A3}', '\u{05A4}', '\u{05A5}', '\u{05A6}', '\u{05A7}', '\u{05A8}', '\u{05A9}', '\u{05AA}', '\u{05AB}', '\u{05AC}', '\u{05AD}', '\u{05AE}', '\u{05AF}', '\u{05B0}', '\u{05B1}', '\u{05B2}', '\u{05B3}', '\u{05B4}', '\u{05B5}', '\u{05B6}', '\u{05B7}', '\u{05B8}', '\u{05B9}', '\u{05BA}', '\u{05BB}', '\u{05BC}', '\u{05BD}', '\u{05BF}', '\u{05C1}', '\u{05C2}', '\u{05C4}', '\u{05C5}', '\u{05C7}', '\u{0610}', '\u{0611}', '\u{0612}', '\u{0613}', '\u{0614}', '\u{0615}', '\u{0616}', '\u{0617}', '\u{0618}', '\u{0619}', '\u{061A}', '\u{064B}', '\u{064C}', '\u{064D}', '\u{064E}', '\u{064F}', '\u{0650}', '\u{0651}', '\u{0652}', '\u{0653}', '\u{0654}', '\u{0655}', '\u{0656}', '\u{0657}', '\u{0658}', '\u{0659}', '\u{065A}', '\u{065B}', '\u{065C}', '\u{065D}', '\u{065E}', '\u{0670}', '\u{06D6}', '\u{06D7}', '\u{06D8}', '\u{06D9}', '\u{06DA}', '\u{06DB}', '\u{06DC}', '\u{06DF}', '\u{06E0}', '\u{06E1}', '\u{06E2}', '\u{06E3}', '\u{06E4}', '\u{06E7}', '\u{06E8}', '\u{06EA}', '\u{06EB}', '\u{06EC}', '\u{06ED}', '\u{0711}', '\u{0730}', '\u{0731}', '\u{0732}', '\u{0733}', '\u{0734}', '\u{0735}', '\u{0736}', '\u{0737}', '\u{0738}', '\u{0739}', '\u{073A}', '\u{073B}', '\u{073C}', '\u{073D}', '\u{073E}', '\u{073F}', '\u{0740}', '\u{0741}', '\u{0742}', '\u{0743}', '\u{0744}', '\u{0745}', '\u{0746}', '\u{0747}', '\u{0748}', '\u{0749}', '\u{074A}', '\u{07A6}', '\u{07A7}', '\u{07A8}', '\u{07A9}', '\u{07AA}', '\u{07AB}', '\u{07AC}', '\u{07AD}', '\u{07AE}', '\u{07AF}', '\u{07B0}', '\u{07EB}', '\u{07EC}', '\u{07ED}', '\u{07EE}', '\u{07EF}', '\u{07F0}', '\u{07F1}', '\u{07F2}', '\u{07F3}', '\u{0901}', '\u{0902}', '\u{093C}', '\u{0941}', '\u{0942}', '\u{0943}', '\u{0944}', '\u{0945}', '\u{0946}', '\u{0947}', '\u{0948}', '\u{094D}', '\u{0951}', '\u{0952}', '\u{0953}', '\u{0954}', '\u{0962}', '\u{0963}', '\u{0981}', '\u{09BC}', '\u{09C1}', '\u{09C2}', '\u{09C3}', '\u{09C4}', '\u{09CD}', '\u{09E2}', '\u{09E3}', '\u{0A01}', '\u{0A02}', '\u{0A3C}', '\u{0A41}', '\u{0A42}', '\u{0A47}', '\u{0A48}', '\u{0A4B}', '\u{0A4C}', '\u{0A4D}', '\u{0A51}', '\u{0A70}', '\u{0A71}', '\u{0A75}', '\u{0A81}', '\u{0A82}', '\u{0ABC}', '\u{0AC1}', '\u{0AC2}', '\u{0AC3}', '\u{0AC4}', '\u{0AC5}', '\u{0AC7}', '\u{0AC8}', '\u{0ACD}', '\u{0AE2}', '\u{0AE3}', '\u{0B01}', '\u{0B3C}', '\u{0B3F}', '\u{0B41}', '\u{0B42}', '\u{0B43}', '\u{0B44}', '\u{0B4D}', '\u{0B56}', '\u{0B62}', '\u{0B63}', '\u{0B82}', '\u{0BC0}', '\u{0BCD}', '\u{0C3E}', '\u{0C3F}', '\u{0C40}', '\u{0C46}', '\u{0C47}', '\u{0C48}', '\u{0C4A}', '\u{0C4B}', '\u{0C4C}', '\u{0C4D}', '\u{0C55}', '\u{0C56}', '\u{0C62}', '\u{0C63}', '\u{0CBC}', '\u{0CBF}', '\u{0CC6}', '\u{0CCC}', '\u{0CCD}', '\u{0CE2}', '\u{0CE3}', '\u{0D41}', '\u{0D42}', '\u{0D43}', '\u{0D44}', '\u{0D4D}', '\u{0D62}', '\u{0D63}', '\u{0DCA}', '\u{0DD2}', '\u{0DD3}', '\u{0DD4}', '\u{0DD6}', '\u{0E31}', '\u{0E34}', '\u{0E35}', '\u{0E36}', '\u{0E37}', '\u{0E38}', '\u{0E39}', '\u{0E3A}', '\u{0E47}', '\u{0E48}', '\u{0E49}', '\u{0E4A}', '\u{0E4B}', '\u{0E4C}', '\u{0E4D}', '\u{0E4E}', '\u{0EB1}', '\u{0EB4}', '\u{0EB5}', '\u{0EB6}', '\u{0EB7}', '\u{0EB8}', '\u{0EB9}', '\u{0EBB}', '\u{0EBC}', '\u{0EC8}', '\u{0EC9}', '\u{0ECA}', '\u{0ECB}', '\u{0ECC}', '\u{0ECD}', '\u{0F18}', '\u{0F19}', '\u{0F35}', '\u{0F37}', '\u{0F39}', '\u{0F71}', '\u{0F72}', '\u{0F73}', '\u{0F74}', '\u{0F75}', '\u{0F76}', '\u{0F77}', '\u{0F78}', '\u{0F79}', '\u{0F7A}', '\u{0F7B}', '\u{0F7C}', '\u{0F7D}', '\u{0F7E}', '\u{0F80}', '\u{0F81}', '\u{0F82}', '\u{0F83}', '\u{0F84}', '\u{0F86}', '\u{0F87}', '\u{0F90}', '\u{0F91}', '\u{0F92}', '\u{0F93}', '\u{0F94}', '\u{0F95}', '\u{0F96}', '\u{0F97}', '\u{0F99}', '\u{0F9A}', '\u{0F9B}', '\u{0F9C}', '\u{0F9D}', '\u{0F9E}', '\u{0F9F}', '\u{0FA0}', '\u{0FA1}', '\u{0FA2}', '\u{0FA3}', '\u{0FA4}', '\u{0FA5}', '\u{0FA6}', '\u{0FA7}', '\u{0FA8}', '\u{0FA9}', '\u{0FAA}', '\u{0FAB}', '\u{0FAC}', '\u{0FAD}', '\u{0FAE}', '\u{0FAF}', '\u{0FB0}', '\u{0FB1}', '\u{0FB2}', '\u{0FB3}', '\u{0FB4}', '\u{0FB5}', '\u{0FB6}', '\u{0FB7}', '\u{0FB8}', '\u{0FB9}', '\u{0FBA}', '\u{0FBB}', '\u{0FBC}', '\u{0FC6}', '\u{102D}', '\u{102E}', '\u{102F}', '\u{1030}', '\u{1032}', '\u{1033}', '\u{1034}', '\u{1035}', '\u{1036}', '\u{1037}', '\u{1039}', '\u{103A}', '\u{103D}', '\u{103E}', '\u{1058}', '\u{1059}', '\u{105E}', '\u{105F}', '\u{1060}', '\u{1071}', '\u{1072}', '\u{1073}', '\u{1074}', '\u{1082}', '\u{1085}', '\u{1086}', '\u{108D}', '\u{135F}', '\u{1712}', '\u{1713}', '\u{1714}', '\u{1732}', '\u{1733}', '\u{1734}', '\u{1752}', '\u{1753}', '\u{1772}', '\u{1773}', '\u{17B7}', '\u{17B8}', '\u{17B9}', '\u{17BA}', '\u{17BB}', '\u{17BC}', '\u{17BD}', '\u{17C6}', '\u{17C9}', '\u{17CA}', '\u{17CB}', '\u{17CC}', '\u{17CD}', '\u{17CE}', '\u{17CF}', '\u{17D0}', '\u{17D1}', '\u{17D2}', '\u{17D3}', '\u{17DD}', '\u{180B}', '\u{180C}', '\u{180D}', '\u{18A9}', '\u{1920}', '\u{1921}', '\u{1922}', '\u{1927}', '\u{1928}', '\u{1932}', '\u{1939}', '\u{193A}', '\u{193B}', '\u{1A17}', '\u{1A18}', '\u{1B00}', '\u{1B01}', '\u{1B02}', '\u{1B03}', '\u{1B34}', '\u{1B36}', '\u{1B37}', '\u{1B38}', '\u{1B39}', '\u{1B3A}', '\u{1B3C}', '\u{1B42}', '\u{1B6B}', '\u{1B6C}', '\u{1B6D}', '\u{1B6E}', '\u{1B6F}', '\u{1B70}', '\u{1B71}', '\u{1B72}', '\u{1B73}', '\u{1B80}', '\u{1B81}', '\u{1BA2}', '\u{1BA3}', '\u{1BA4}', '\u{1BA5}', '\u{1BA8}', '\u{1BA9}', '\u{1C2C}', '\u{1C2D}', '\u{1C2E}', '\u{1C2F}', '\u{1C30}', '\u{1C31}', '\u{1C32}', '\u{1C33}', '\u{1C36}', '\u{1C37}', '\u{1DC0}', '\u{1DC1}', '\u{1DC2}', '\u{1DC3}', '\u{1DC4}', '\u{1DC5}', '\u{1DC6}', '\u{1DC7}', '\u{1DC8}', '\u{1DC9}', '\u{1DCA}', '\u{1DCB}', '\u{1DCC}', '\u{1DCD}', '\u{1DCE}', '\u{1DCF}', '\u{1DD0}', '\u{1DD1}', '\u{1DD2}', '\u{1DD3}', '\u{1DD4}', '\u{1DD5}', '\u{1DD6}', '\u{1DD7}', '\u{1DD8}', '\u{1DD9}', '\u{1DDA}', '\u{1DDB}', '\u{1DDC}', '\u{1DDD}', '\u{1DDE}', '\u{1DDF}', '\u{1DE0}', '\u{1DE1}', '\u{1DE2}', '\u{1DE3}', '\u{1DE4}', '\u{1DE5}', '\u{1DE6}', '\u{1DFE}', '\u{1DFF}', '\u{20D0}', '\u{20D1}', '\u{20D2}', '\u{20D3}', '\u{20D4}', '\u{20D5}', '\u{20D6}', '\u{20D7}', '\u{20D8}', '\u{20D9}', '\u{20DA}', '\u{20DB}', '\u{20DC}', '\u{20E1}', '\u{20E5}', '\u{20E6}', '\u{20E7}', '\u{20E8}', '\u{20E9}', '\u{20EA}', '\u{20EB}', '\u{20EC}', '\u{20ED}', '\u{20EE}', '\u{20EF}', '\u{20F0}', '\u{2DE0}', '\u{2DE1}', '\u{2DE2}', '\u{2DE3}', '\u{2DE4}', '\u{2DE5}', '\u{2DE6}', '\u{2DE7}', '\u{2DE8}', '\u{2DE9}', '\u{2DEA}', '\u{2DEB}', '\u{2DEC}', '\u{2DED}', '\u{2DEE}', '\u{2DEF}', '\u{2DF0}', '\u{2DF1}', '\u{2DF2}', '\u{2DF3}', '\u{2DF4}', '\u{2DF5}', '\u{2DF6}', '\u{2DF7}', '\u{2DF8}', '\u{2DF9}', '\u{2DFA}', '\u{2DFB}', '\u{2DFC}', '\u{2DFD}', '\u{2DFE}', '\u{2DFF}', '\u{302A}', '\u{302B}', '\u{302C}', '\u{302D}', '\u{302E}', '\u{302F}', '\u{3099}', '\u{309A}', '\u{A66F}', '\u{A67C}', '\u{A67D}', '\u{A802}', '\u{A806}', '\u{A80B}', '\u{A825}', '\u{A826}', '\u{A8C4}', '\u{A926}', '\u{A927}', '\u{A928}', '\u{A929}', '\u{A92A}', '\u{A92B}', '\u{A92C}', '\u{A92D}', '\u{A947}', '\u{A948}', '\u{A949}', '\u{A94A}', '\u{A94B}', '\u{A94C}', '\u{A94D}', '\u{A94E}', '\u{A94F}', '\u{A950}', '\u{A951}', '\u{AA29}', '\u{AA2A}', '\u{AA2B}', '\u{AA2C}', '\u{AA2D}', '\u{AA2E}', '\u{AA31}', '\u{AA32}', '\u{AA35}', '\u{AA36}', '\u{AA43}', '\u{AA4C}', '\u{FB1E}', '\u{FE00}', '\u{FE01}', '\u{FE02}', '\u{FE03}', '\u{FE04}', '\u{FE05}', '\u{FE06}', '\u{FE07}', '\u{FE08}', '\u{FE09}', '\u{FE0A}', '\u{FE0B}', '\u{FE0C}', '\u{FE0D}', '\u{FE0E}', '\u{FE0F}', '\u{FE20}', '\u{FE21}', '\u{FE22}', '\u{FE23}', '\u{FE24}', '\u{FE25}', '\u{FE26}', '\u{01BB}', '\u{01C0}', '\u{01C1}', '\u{01C2}', '\u{01C3}', '\u{0294}', '\u{05D0}', '\u{05D1}', '\u{05D2}', '\u{05D3}', '\u{05D4}', '\u{05D5}', '\u{05D6}', '\u{05D7}', '\u{05D8}', '\u{05D9}', '\u{05DA}', '\u{05DB}', '\u{05DC}', '\u{05DD}', '\u{05DE}', '\u{05DF}', '\u{05E0}', '\u{05E1}', '\u{05E2}', '\u{05E3}', '\u{05E4}', '\u{05E5}', '\u{05E6}', '\u{05E7}', '\u{05E8}', '\u{05E9}', '\u{05EA}', '\u{05F0}', '\u{05F1}', '\u{05F2}', '\u{0621}', '\u{0622}', '\u{0623}', '\u{0624}', '\u{0625}', '\u{0626}', '\u{0627}', '\u{0628}', '\u{0629}', '\u{062A}', '\u{062B}', '\u{062C}', '\u{062D}', '\u{062E}', '\u{062F}', '\u{0630}', '\u{0631}', '\u{0632}', '\u{0633}', '\u{0634}', '\u{0635}', '\u{0636}', '\u{0637}', '\u{0638}', '\u{0639}', '\u{063A}', '\u{063B}', '\u{063C}', '\u{063D}', '\u{063E}', '\u{063F}', '\u{0641}', '\u{0642}', '\u{0643}', '\u{0644}', '\u{0645}', '\u{0646}', '\u{0647}', '\u{0648}', '\u{0649}', '\u{064A}', '\u{066E}', '\u{066F}', '\u{0671}', '\u{0672}', '\u{0673}', '\u{0674}', '\u{0675}', '\u{0676}', '\u{0677}', '\u{0678}', '\u{0679}', '\u{067A}', '\u{067B}', '\u{067C}', '\u{067D}', '\u{067E}', '\u{067F}', '\u{0680}', '\u{0681}', '\u{0682}', '\u{0683}', '\u{0684}', '\u{0685}', '\u{0686}', '\u{0687}', '\u{0688}', '\u{0689}', '\u{068A}', '\u{068B}', '\u{068C}', '\u{068D}', '\u{068E}', '\u{068F}', '\u{0690}', '\u{0691}', '\u{0692}', '\u{0693}', '\u{0694}', '\u{0695}', '\u{0696}', '\u{0697}', '\u{0698}', '\u{0699}', '\u{069A}', '\u{069B}', '\u{069C}', '\u{069D}', '\u{069E}', '\u{069F}', '\u{06A0}', '\u{06A1}', '\u{06A2}', '\u{06A3}', '\u{06A4}', '\u{06A5}', '\u{06A6}', '\u{06A7}', '\u{06A8}', '\u{06A9}', '\u{06AA}', '\u{06AB}', '\u{06AC}', '\u{06AD}', '\u{06AE}', '\u{06AF}', '\u{06B0}', '\u{06B1}', '\u{06B2}', '\u{06B3}', '\u{06B4}', '\u{06B5}', '\u{06B6}', '\u{06B7}', '\u{06B8}', '\u{06B9}', '\u{06BA}', '\u{06BB}', '\u{06BC}', '\u{06BD}', '\u{06BE}', '\u{06BF}', '\u{06C0}', '\u{06C1}', '\u{06C2}', '\u{06C3}', '\u{06C4}', '\u{06C5}', '\u{06C6}', '\u{06C7}', '\u{06C8}', '\u{06C9}', '\u{06CA}', '\u{06CB}', '\u{06CC}', '\u{06CD}', '\u{06CE}', '\u{06CF}', '\u{06D0}', '\u{06D1}', '\u{06D2}', '\u{06D3}', '\u{06D5}', '\u{06EE}', '\u{06EF}', '\u{06FA}', '\u{06FB}', '\u{06FC}', '\u{06FF}', '\u{0710}', '\u{0712}', '\u{0713}', '\u{0714}', '\u{0715}', '\u{0716}', '\u{0717}', '\u{0718}', '\u{0719}', '\u{071A}', '\u{071B}', '\u{071C}', '\u{071D}', '\u{071E}', '\u{071F}', '\u{0720}', '\u{0721}', '\u{0722}', '\u{0723}', '\u{0724}', '\u{0725}', '\u{0726}', '\u{0727}', '\u{0728}', '\u{0729}', '\u{072A}', '\u{072B}', '\u{072C}', '\u{072D}', '\u{072E}', '\u{072F}', '\u{074D}', '\u{074E}', '\u{074F}', '\u{0750}', '\u{0751}', '\u{0752}', '\u{0753}', '\u{0754}', '\u{0755}', '\u{0756}', '\u{0757}', '\u{0758}', '\u{0759}', '\u{075A}', '\u{075B}', '\u{075C}', '\u{075D}', '\u{075E}', '\u{075F}', '\u{0760}', '\u{0761}', '\u{0762}', '\u{0763}', '\u{0764}', '\u{0765}', '\u{0766}', '\u{0767}', '\u{0768}', '\u{0769}', '\u{076A}', '\u{076B}', '\u{076C}', '\u{076D}', '\u{076E}', '\u{076F}', '\u{0770}', '\u{0771}', '\u{0772}', '\u{0773}', '\u{0774}', '\u{0775}', '\u{0776}', '\u{0777}', '\u{0778}', '\u{0779}', '\u{077A}', '\u{077B}', '\u{077C}', '\u{077D}', '\u{077E}', '\u{077F}', '\u{0780}', '\u{0781}', '\u{0782}', '\u{0783}', '\u{0784}', '\u{0785}', '\u{0786}', '\u{0787}', '\u{0788}', '\u{0789}', '\u{078A}', '\u{078B}', '\u{078C}', '\u{078D}', '\u{078E}', '\u{078F}', '\u{0790}', '\u{0791}', '\u{0792}', '\u{0793}', '\u{0794}', '\u{0795}', '\u{0796}', '\u{0797}', '\u{0798}', '\u{0799}', '\u{079A}', '\u{079B}', '\u{079C}', '\u{079D}', '\u{079E}', '\u{079F}', '\u{07A0}', '\u{07A1}', '\u{07A2}', '\u{07A3}', '\u{07A4}', '\u{07A5}', '\u{07B1}', '\u{07CA}', '\u{07CB}', '\u{07CC}', '\u{07CD}', '\u{07CE}', '\u{07CF}', '\u{07D0}', '\u{07D1}', '\u{07D2}', '\u{07D3}', '\u{07D4}', '\u{07D5}', '\u{07D6}', '\u{07D7}', '\u{07D8}', '\u{07D9}', '\u{07DA}', '\u{07DB}', '\u{07DC}', '\u{07DD}', '\u{07DE}', '\u{07DF}', '\u{07E0}', '\u{07E1}', '\u{07E2}', '\u{07E3}', '\u{07E4}', '\u{07E5}', '\u{07E6}', '\u{07E7}', '\u{07E8}', '\u{07E9}', '\u{07EA}', '\u{0904}', '\u{0905}', '\u{0906}', '\u{0907}', '\u{0908}', '\u{0909}', '\u{090A}', '\u{090B}', '\u{090C}', '\u{090D}', '\u{090E}', '\u{090F}', '\u{0910}', '\u{0911}', '\u{0912}', '\u{0913}', '\u{0914}', '\u{0915}', '\u{0916}', '\u{0917}', '\u{0918}', '\u{0919}', '\u{091A}', '\u{091B}', '\u{091C}', '\u{091D}', '\u{091E}', '\u{091F}', '\u{0920}', '\u{0921}', '\u{0922}', '\u{0923}', '\u{0924}', '\u{0925}', '\u{0926}', '\u{0927}', '\u{0928}', '\u{0929}', '\u{092A}', '\u{092B}', '\u{092C}', '\u{092D}', '\u{092E}', '\u{092F}', '\u{0930}', '\u{0931}', '\u{0932}', '\u{0933}', '\u{0934}', '\u{0935}', '\u{0936}', '\u{0937}', '\u{0938}', '\u{0939}', '\u{093D}', '\u{0950}', '\u{0958}', '\u{0959}', '\u{095A}', '\u{095B}', '\u{095C}', '\u{095D}', '\u{095E}', '\u{095F}', '\u{0960}', '\u{0961}', '\u{0972}', '\u{097B}', '\u{097C}', '\u{097D}', '\u{097E}', '\u{097F}', '\u{0985}', '\u{0986}', '\u{0987}', '\u{0988}', '\u{0989}', '\u{098A}', '\u{098B}', '\u{098C}', '\u{098F}', '\u{0990}', '\u{0993}', '\u{0994}', '\u{0995}', '\u{0996}', '\u{0997}', '\u{0998}', '\u{0999}', '\u{099A}', '\u{099B}', '\u{099C}', '\u{099D}', '\u{099E}', '\u{099F}', '\u{09A0}', '\u{09A1}', '\u{09A2}', '\u{09A3}', '\u{09A4}', '\u{09A5}', '\u{09A6}', '\u{09A7}', '\u{09A8}', '\u{09AA}', '\u{09AB}', '\u{09AC}', '\u{09AD}', '\u{09AE}', '\u{09AF}', '\u{09B0}', '\u{09B2}', '\u{09B6}', '\u{09B7}', '\u{09B8}', '\u{09B9}', '\u{09BD}', '\u{09CE}', '\u{09DC}', '\u{09DD}', '\u{09DF}', '\u{09E0}', '\u{09E1}', '\u{09F0}', '\u{09F1}', '\u{0A05}', '\u{0A06}', '\u{0A07}', '\u{0A08}', '\u{0A09}', '\u{0A0A}', '\u{0A0F}', '\u{0A10}', '\u{0A13}', '\u{0A14}', '\u{0A15}', '\u{0A16}', '\u{0A17}', '\u{0A18}', '\u{0A19}', '\u{0A1A}', '\u{0A1B}', '\u{0A1C}', '\u{0A1D}', '\u{0A1E}', '\u{0A1F}', '\u{0A20}', '\u{0A21}', '\u{0A22}', '\u{0A23}', '\u{0A24}', '\u{0A25}', '\u{0A26}', '\u{0A27}', '\u{0A28}', '\u{0A2A}', '\u{0A2B}', '\u{0A2C}', '\u{0A2D}', '\u{0A2E}', '\u{0A2F}', '\u{0A30}', '\u{0A32}', '\u{0A33}', '\u{0A35}', '\u{0A36}', '\u{0A38}', '\u{0A39}', '\u{0A59}', '\u{0A5A}', '\u{0A5B}', '\u{0A5C}', '\u{0A5E}', '\u{0A72}', '\u{0A73}', '\u{0A74}', '\u{0A85}', '\u{0A86}', '\u{0A87}', '\u{0A88}', '\u{0A89}', '\u{0A8A}', '\u{0A8B}', '\u{0A8C}', '\u{0A8D}', '\u{0A8F}', '\u{0A90}', '\u{0A91}', '\u{0A93}', '\u{0A94}', '\u{0A95}', '\u{0A96}', '\u{0A97}', '\u{0A98}', '\u{0A99}', '\u{0A9A}', '\u{0A9B}', '\u{0A9C}', '\u{0A9D}', '\u{0A9E}', '\u{0A9F}', '\u{0AA0}', '\u{0AA1}', '\u{0AA2}', '\u{0AA3}', '\u{0AA4}', '\u{0AA5}', '\u{0AA6}', '\u{0AA7}', '\u{0AA8}', '\u{0AAA}', '\u{0AAB}', '\u{0AAC}', '\u{0AAD}', '\u{0AAE}', '\u{0AAF}', '\u{0AB0}', '\u{0AB2}', '\u{0AB3}', '\u{0AB5}', '\u{0AB6}', '\u{0AB7}', '\u{0AB8}', '\u{0AB9}', '\u{0ABD}', '\u{0AD0}', '\u{0AE0}', '\u{0AE1}', '\u{0B05}', '\u{0B06}', '\u{0B07}', '\u{0B08}', '\u{0B09}', '\u{0B0A}', '\u{0B0B}', '\u{0B0C}', '\u{0B0F}', '\u{0B10}', '\u{0B13}', '\u{0B14}', '\u{0B15}', '\u{0B16}', '\u{0B17}', '\u{0B18}', '\u{0B19}', '\u{0B1A}', '\u{0B1B}', '\u{0B1C}', '\u{0B1D}', '\u{0B1E}', '\u{0B1F}', '\u{0B20}', '\u{0B21}', '\u{0B22}', '\u{0B23}', '\u{0B24}', '\u{0B25}', '\u{0B26}', '\u{0B27}', '\u{0B28}', '\u{0B2A}', '\u{0B2B}', '\u{0B2C}', '\u{0B2D}', '\u{0B2E}', '\u{0B2F}', '\u{0B30}', '\u{0B32}', '\u{0B33}', '\u{0B35}', '\u{0B36}', '\u{0B37}', '\u{0B38}', '\u{0B39}', '\u{0B3D}', '\u{0B5C}', '\u{0B5D}', '\u{0B5F}', '\u{0B60}', '\u{0B61}', '\u{0B71}', '\u{0B83}', '\u{0B85}', '\u{0B86}', '\u{0B87}', '\u{0B88}', '\u{0B89}', '\u{0B8A}', '\u{0B8E}', '\u{0B8F}', '\u{0B90}', '\u{0B92}', '\u{0B93}', '\u{0B94}', '\u{0B95}', '\u{0B99}', '\u{0B9A}', '\u{0B9C}', '\u{0B9E}', '\u{0B9F}', '\u{0BA3}', '\u{0BA4}', '\u{0BA8}', '\u{0BA9}', '\u{0BAA}', '\u{0BAE}', '\u{0BAF}', '\u{0BB0}', '\u{0BB1}', '\u{0BB2}', '\u{0BB3}', '\u{0BB4}', '\u{0BB5}', '\u{0BB6}', '\u{0BB7}', '\u{0BB8}', '\u{0BB9}', '\u{0BD0}', '\u{0C05}', '\u{0C06}', '\u{0C07}', '\u{0C08}', '\u{0C09}', '\u{0C0A}', '\u{0C0B}', '\u{0C0C}', '\u{0C0E}', '\u{0C0F}', '\u{0C10}', '\u{0C12}', '\u{0C13}', '\u{0C14}', '\u{0C15}', '\u{0C16}', '\u{0C17}', '\u{0C18}', '\u{0C19}', '\u{0C1A}', '\u{0C1B}', '\u{0C1C}', '\u{0C1D}', '\u{0C1E}', '\u{0C1F}', '\u{0C20}', '\u{0C21}', '\u{0C22}', '\u{0C23}', '\u{0C24}', '\u{0C25}', '\u{0C26}', '\u{0C27}', '\u{0C28}', '\u{0C2A}', '\u{0C2B}', '\u{0C2C}', '\u{0C2D}', '\u{0C2E}', '\u{0C2F}', '\u{0C30}', '\u{0C31}', '\u{0C32}', '\u{0C33}', '\u{0C35}', '\u{0C36}', '\u{0C37}', '\u{0C38}', '\u{0C39}', '\u{0C3D}', '\u{0C58}', '\u{0C59}', '\u{0C60}', '\u{0C61}', '\u{0C85}', '\u{0C86}', '\u{0C87}', '\u{0C88}', '\u{0C89}', '\u{0C8A}', '\u{0C8B}', '\u{0C8C}', '\u{0C8E}', '\u{0C8F}', '\u{0C90}', '\u{0C92}', '\u{0C93}', '\u{0C94}', '\u{0C95}', '\u{0C96}', '\u{0C97}', '\u{0C98}', '\u{0C99}', '\u{0C9A}', '\u{0C9B}', '\u{0C9C}', '\u{0C9D}', '\u{0C9E}', '\u{0C9F}', '\u{0CA0}', '\u{0CA1}', '\u{0CA2}', '\u{0CA3}', '\u{0CA4}', '\u{0CA5}', '\u{0CA6}', '\u{0CA7}', '\u{0CA8}', '\u{0CAA}', '\u{0CAB}', '\u{0CAC}', '\u{0CAD}', '\u{0CAE}', '\u{0CAF}', '\u{0CB0}', '\u{0CB1}', '\u{0CB2}', '\u{0CB3}', '\u{0CB5}', '\u{0CB6}', '\u{0CB7}', '\u{0CB8}', '\u{0CB9}', '\u{0CBD}', '\u{0CDE}', '\u{0CE0}', '\u{0CE1}', '\u{0D05}', '\u{0D06}', '\u{0D07}', '\u{0D08}', '\u{0D09}', '\u{0D0A}', '\u{0D0B}', '\u{0D0C}', '\u{0D0E}', '\u{0D0F}', '\u{0D10}', '\u{0D12}', '\u{0D13}', '\u{0D14}', '\u{0D15}', '\u{0D16}', '\u{0D17}', '\u{0D18}', '\u{0D19}', '\u{0D1A}', '\u{0D1B}', '\u{0D1C}', '\u{0D1D}', '\u{0D1E}', '\u{0D1F}', '\u{0D20}', '\u{0D21}', '\u{0D22}', '\u{0D23}', '\u{0D24}', '\u{0D25}', '\u{0D26}', '\u{0D27}', '\u{0D28}', '\u{0D2A}', '\u{0D2B}', '\u{0D2C}', '\u{0D2D}', '\u{0D2E}', '\u{0D2F}', '\u{0D30}', '\u{0D31}', '\u{0D32}', '\u{0D33}', '\u{0D34}', '\u{0D35}', '\u{0D36}', '\u{0D37}', '\u{0D38}', '\u{0D39}', '\u{0D3D}', '\u{0D60}', '\u{0D61}', '\u{0D7A}', '\u{0D7B}', '\u{0D7C}', '\u{0D7D}', '\u{0D7E}', '\u{0D7F}', '\u{0D85}', '\u{0D86}', '\u{0D87}', '\u{0D88}', '\u{0D89}', '\u{0D8A}', '\u{0D8B}', '\u{0D8C}', '\u{0D8D}', '\u{0D8E}', '\u{0D8F}', '\u{0D90}', '\u{0D91}', '\u{0D92}', '\u{0D93}', '\u{0D94}', '\u{0D95}', '\u{0D96}', '\u{0D9A}', '\u{0D9B}', '\u{0D9C}', '\u{0D9D}', '\u{0D9E}', '\u{0D9F}', '\u{0DA0}', '\u{0DA1}', '\u{0DA2}', '\u{0DA3}', '\u{0DA4}', '\u{0DA5}', '\u{0DA6}', '\u{0DA7}', '\u{0DA8}', '\u{0DA9}', '\u{0DAA}', '\u{0DAB}', '\u{0DAC}', '\u{0DAD}', '\u{0DAE}', '\u{0DAF}', '\u{0DB0}', '\u{0DB1}', '\u{0DB3}', '\u{0DB4}', '\u{0DB5}', '\u{0DB6}', '\u{0DB7}', '\u{0DB8}', '\u{0DB9}', '\u{0DBA}', '\u{0DBB}', '\u{0DBD}', '\u{0DC0}', '\u{0DC1}', '\u{0DC2}', '\u{0DC3}', '\u{0DC4}', '\u{0DC5}', '\u{0DC6}', '\u{0E01}', '\u{0E02}', '\u{0E03}', '\u{0E04}', '\u{0E05}', '\u{0E06}', '\u{0E07}', '\u{0E08}', '\u{0E09}', '\u{0E0A}', '\u{0E0B}', '\u{0E0C}', '\u{0E0D}', '\u{0E0E}', '\u{0E0F}', '\u{0E10}', '\u{0E11}', '\u{0E12}', '\u{0E13}', '\u{0E14}', '\u{0E15}', '\u{0E16}', '\u{0E17}', '\u{0E18}', '\u{0E19}', '\u{0E1A}', '\u{0E1B}', '\u{0E1C}', '\u{0E1D}', '\u{0E1E}', '\u{0E1F}', '\u{0E20}', '\u{0E21}', '\u{0E22}', '\u{0E23}', '\u{0E24}', '\u{0E25}', '\u{0E26}', '\u{0E27}', '\u{0E28}', '\u{0E29}', '\u{0E2A}', '\u{0E2B}', '\u{0E2C}', '\u{0E2D}', '\u{0E2E}', '\u{0E2F}', '\u{0E30}', '\u{0E32}', '\u{0E33}', '\u{0E40}', '\u{0E41}', '\u{0E42}', '\u{0E43}', '\u{0E44}', '\u{0E45}', '\u{0E81}', '\u{0E82}', '\u{0E84}', '\u{0E87}', '\u{0E88}', '\u{0E8A}', '\u{0E8D}', '\u{0E94}', '\u{0E95}', '\u{0E96}', '\u{0E97}', '\u{0E99}', '\u{0E9A}', '\u{0E9B}', '\u{0E9C}', '\u{0E9D}', '\u{0E9E}', '\u{0E9F}', '\u{0EA1}', '\u{0EA2}', '\u{0EA3}', '\u{0EA5}', '\u{0EA7}', '\u{0EAA}', '\u{0EAB}', '\u{0EAD}', '\u{0EAE}', '\u{0EAF}', '\u{0EB0}', '\u{0EB2}', '\u{0EB3}', '\u{0EBD}', '\u{0EC0}', '\u{0EC1}', '\u{0EC2}', '\u{0EC3}', '\u{0EC4}', '\u{0EDC}', '\u{0EDD}', '\u{0F00}', '\u{0F40}', '\u{0F41}', '\u{0F42}', '\u{0F43}', '\u{0F44}', '\u{0F45}', '\u{0F46}', '\u{0F47}', '\u{0F49}', '\u{0F4A}', '\u{0F4B}', '\u{0F4C}', '\u{0F4D}', '\u{0F4E}', '\u{0F4F}', '\u{0F50}', '\u{0F51}', '\u{0F52}', '\u{0F53}', '\u{0F54}', '\u{0F55}', '\u{0F56}', '\u{0F57}', '\u{0F58}', '\u{0F59}', '\u{0F5A}', '\u{0F5B}', '\u{0F5C}', '\u{0F5D}', '\u{0F5E}', '\u{0F5F}', '\u{0F60}', '\u{0F61}', '\u{0F62}', '\u{0F63}', '\u{0F64}', '\u{0F65}', '\u{0F66}', '\u{0F67}', '\u{0F68}', '\u{0F69}', '\u{0F6A}', '\u{0F6B}', '\u{0F6C}', '\u{0F88}', '\u{0F89}', '\u{0F8A}', '\u{0F8B}', '\u{1000}', '\u{1001}', '\u{1002}', '\u{1003}', '\u{1004}', '\u{1005}', '\u{1006}', '\u{1007}', '\u{1008}', '\u{1009}', '\u{100A}', '\u{100B}', '\u{100C}', '\u{100D}', '\u{100E}', '\u{100F}', '\u{1010}', '\u{1011}', '\u{1012}', '\u{1013}', '\u{1014}', '\u{1015}', '\u{1016}', '\u{1017}', '\u{1018}', '\u{1019}', '\u{101A}', '\u{101B}', '\u{101C}', '\u{101D}', '\u{101E}', '\u{101F}', '\u{1020}', '\u{1021}', '\u{1022}', '\u{1023}', '\u{1024}', '\u{1025}', '\u{1026}', '\u{1027}', '\u{1028}', '\u{1029}', '\u{102A}', '\u{103F}', '\u{1050}', '\u{1051}', '\u{1052}', '\u{1053}', '\u{1054}', '\u{1055}', '\u{105A}', '\u{105B}', '\u{105C}', '\u{105D}', '\u{1061}', '\u{1065}', '\u{1066}', '\u{106E}', '\u{106F}', '\u{1070}', '\u{1075}', '\u{1076}', '\u{1077}', '\u{1078}', '\u{1079}', '\u{107A}', '\u{107B}', '\u{107C}', '\u{107D}', '\u{107E}', '\u{107F}', '\u{1080}', '\u{1081}', '\u{108E}', '\u{10D0}', '\u{10D1}', '\u{10D2}', '\u{10D3}', '\u{10D4}', '\u{10D5}', '\u{10D6}', '\u{10D7}', '\u{10D8}', '\u{10D9}', '\u{10DA}', '\u{10DB}', '\u{10DC}', '\u{10DD}', '\u{10DE}', '\u{10DF}', '\u{10E0}', '\u{10E1}', '\u{10E2}', '\u{10E3}', '\u{10E4}', '\u{10E5}', '\u{10E6}', '\u{10E7}', '\u{10E8}', '\u{10E9}', '\u{10EA}', '\u{10EB}', '\u{10EC}', '\u{10ED}', '\u{10EE}', '\u{10EF}', '\u{10F0}', '\u{10F1}', '\u{10F2}', '\u{10F3}', '\u{10F4}', '\u{10F5}', '\u{10F6}', '\u{10F7}', '\u{10F8}', '\u{10F9}', '\u{10FA}', '\u{1100}', '\u{1101}', '\u{1102}', '\u{1103}', '\u{1104}', '\u{1105}', '\u{1106}', '\u{1107}', '\u{1108}', '\u{1109}', '\u{110A}', '\u{110B}', '\u{110C}', '\u{110D}', '\u{110E}', '\u{110F}', '\u{1110}', '\u{1111}', '\u{1112}', '\u{1113}', '\u{1114}', '\u{1115}', '\u{1116}', '\u{1117}', '\u{1118}', '\u{1119}', '\u{111A}', '\u{111B}', '\u{111C}', '\u{111D}', '\u{111E}', '\u{111F}', '\u{1120}', '\u{1121}', '\u{1122}', '\u{1123}', '\u{1124}', '\u{1125}', '\u{1126}', '\u{1127}', '\u{1128}', '\u{1129}', '\u{112A}', '\u{112B}', '\u{112C}', '\u{112D}', '\u{112E}', '\u{112F}', '\u{1130}', '\u{1131}', '\u{1132}', '\u{1133}', '\u{1134}', '\u{1135}', '\u{1136}', '\u{1137}', '\u{1138}', '\u{1139}', '\u{113A}', '\u{113B}', '\u{113C}', '\u{113D}', '\u{113E}', '\u{113F}', '\u{1140}', '\u{1141}', '\u{1142}', '\u{1143}', '\u{1144}', '\u{1145}', '\u{1146}', '\u{1147}', '\u{1148}', '\u{1149}', '\u{114A}', '\u{114B}', '\u{114C}', '\u{114D}', '\u{114E}', '\u{114F}', '\u{1150}', '\u{1151}', '\u{1152}', '\u{1153}', '\u{1154}', '\u{1155}', '\u{1156}', '\u{1157}', '\u{1158}', '\u{1159}', '\u{115F}', '\u{1160}', '\u{1161}', '\u{1162}', '\u{1163}', '\u{1164}', '\u{1165}', '\u{1166}', '\u{1167}', '\u{1168}', '\u{1169}', '\u{116A}', '\u{116B}', '\u{116C}', '\u{116D}', '\u{116E}', '\u{116F}', '\u{1170}', '\u{1171}', '\u{1172}', '\u{1173}', '\u{1174}', '\u{1175}', '\u{1176}', '\u{1177}', '\u{1178}', '\u{1179}', '\u{117A}', '\u{117B}', '\u{117C}', '\u{117D}', '\u{117E}', '\u{117F}', '\u{1180}', '\u{1181}', '\u{1182}', '\u{1183}', '\u{1184}', '\u{1185}', '\u{1186}', '\u{1187}', '\u{1188}', '\u{1189}', '\u{118A}', '\u{118B}', '\u{118C}', '\u{118D}', '\u{118E}', '\u{118F}', '\u{1190}', '\u{1191}', '\u{1192}', '\u{1193}', '\u{1194}', '\u{1195}', '\u{1196}', '\u{1197}', '\u{1198}', '\u{1199}', '\u{119A}', '\u{119B}', '\u{119C}', '\u{119D}', '\u{119E}', '\u{119F}', '\u{11A0}', '\u{11A1}', '\u{11A2}', '\u{11A8}', '\u{11A9}', '\u{11AA}', '\u{11AB}', '\u{11AC}', '\u{11AD}', '\u{11AE}', '\u{11AF}', '\u{11B0}', '\u{11B1}', '\u{11B2}', '\u{11B3}', '\u{11B4}', '\u{11B5}', '\u{11B6}', '\u{11B7}', '\u{11B8}', '\u{11B9}', '\u{11BA}', '\u{11BB}', '\u{11BC}', '\u{11BD}', '\u{11BE}', '\u{11BF}', '\u{11C0}', '\u{11C1}', '\u{11C2}', '\u{11C3}', '\u{11C4}', '\u{11C5}', '\u{11C6}', '\u{11C7}', '\u{11C8}', '\u{11C9}', '\u{11CA}', '\u{11CB}', '\u{11CC}', '\u{11CD}', '\u{11CE}', '\u{11CF}', '\u{11D0}', '\u{11D1}', '\u{11D2}', '\u{11D3}', '\u{11D4}', '\u{11D5}', '\u{11D6}', '\u{11D7}', '\u{11D8}', '\u{11D9}', '\u{11DA}', '\u{11DB}', '\u{11DC}', '\u{11DD}', '\u{11DE}', '\u{11DF}', '\u{11E0}', '\u{11E1}', '\u{11E2}', '\u{11E3}', '\u{11E4}', '\u{11E5}', '\u{11E6}', '\u{11E7}', '\u{11E8}', '\u{11E9}', '\u{11EA}', '\u{11EB}', '\u{11EC}', '\u{11ED}', '\u{11EE}', '\u{11EF}', '\u{11F0}', '\u{11F1}', '\u{11F2}', '\u{11F3}', '\u{11F4}', '\u{11F5}', '\u{11F6}', '\u{11F7}', '\u{11F8}', '\u{11F9}', '\u{1200}', '\u{1201}', '\u{1202}', '\u{1203}', '\u{1204}', '\u{1205}', '\u{1206}', '\u{1207}', '\u{1208}', '\u{1209}', '\u{120A}', '\u{120B}', '\u{120C}', '\u{120D}', '\u{120E}', '\u{120F}', '\u{1210}', '\u{1211}', '\u{1212}', '\u{1213}', '\u{1214}', '\u{1215}', '\u{1216}', '\u{1217}', '\u{1218}', '\u{1219}', '\u{121A}', '\u{121B}', '\u{121C}', '\u{121D}', '\u{121E}', '\u{121F}', '\u{1220}', '\u{1221}', '\u{1222}', '\u{1223}', '\u{1224}', '\u{1225}', '\u{1226}', '\u{1227}', '\u{1228}', '\u{1229}', '\u{122A}', '\u{122B}', '\u{122C}', '\u{122D}', '\u{122E}', '\u{122F}', '\u{1230}', '\u{1231}', '\u{1232}', '\u{1233}', '\u{1234}', '\u{1235}', '\u{1236}', '\u{1237}', '\u{1238}', '\u{1239}', '\u{123A}', '\u{123B}', '\u{123C}', '\u{123D}', '\u{123E}', '\u{123F}', '\u{1240}', '\u{1241}', '\u{1242}', '\u{1243}', '\u{1244}', '\u{1245}', '\u{1246}', '\u{1247}', '\u{1248}', '\u{124A}', '\u{124B}', '\u{124C}', '\u{124D}', '\u{1250}', '\u{1251}', '\u{1252}', '\u{1253}', '\u{1254}', '\u{1255}', '\u{1256}', '\u{1258}', '\u{125A}', '\u{125B}', '\u{125C}', '\u{125D}', '\u{1260}', '\u{1261}', '\u{1262}', '\u{1263}', '\u{1264}', '\u{1265}', '\u{1266}', '\u{1267}', '\u{1268}', '\u{1269}', '\u{126A}', '\u{126B}', '\u{126C}', '\u{126D}', '\u{126E}', '\u{126F}', '\u{1270}', '\u{1271}', '\u{1272}', '\u{1273}', '\u{1274}', '\u{1275}', '\u{1276}', '\u{1277}', '\u{1278}', '\u{1279}', '\u{127A}', '\u{127B}', '\u{127C}', '\u{127D}', '\u{127E}', '\u{127F}', '\u{1280}', '\u{1281}', '\u{1282}', '\u{1283}', '\u{1284}', '\u{1285}', '\u{1286}', '\u{1287}', '\u{1288}', '\u{128A}', '\u{128B}', '\u{128C}', '\u{128D}', '\u{1290}', '\u{1291}', '\u{1292}', '\u{1293}', '\u{1294}', '\u{1295}', '\u{1296}', '\u{1297}', '\u{1298}', '\u{1299}', '\u{129A}', '\u{129B}', '\u{129C}', '\u{129D}', '\u{129E}', '\u{129F}', '\u{12A0}', '\u{12A1}', '\u{12A2}', '\u{12A3}', '\u{12A4}', '\u{12A5}', '\u{12A6}', '\u{12A7}', '\u{12A8}', '\u{12A9}', '\u{12AA}', '\u{12AB}', '\u{12AC}', '\u{12AD}', '\u{12AE}', '\u{12AF}', '\u{12B0}', '\u{12B2}', '\u{12B3}', '\u{12B4}', '\u{12B5}', '\u{12B8}', '\u{12B9}', '\u{12BA}', '\u{12BB}', '\u{12BC}', '\u{12BD}', '\u{12BE}', '\u{12C0}', '\u{12C2}', '\u{12C3}', '\u{12C4}', '\u{12C5}', '\u{12C8}', '\u{12C9}', '\u{12CA}', '\u{12CB}', '\u{12CC}', '\u{12CD}', '\u{12CE}', '\u{12CF}', '\u{12D0}', '\u{12D1}', '\u{12D2}', '\u{12D3}', '\u{12D4}', '\u{12D5}', '\u{12D6}', '\u{12D8}', '\u{12D9}', '\u{12DA}', '\u{12DB}', '\u{12DC}', '\u{12DD}', '\u{12DE}', '\u{12DF}', '\u{12E0}', '\u{12E1}', '\u{12E2}', '\u{12E3}', '\u{12E4}', '\u{12E5}', '\u{12E6}', '\u{12E7}', '\u{12E8}', '\u{12E9}', '\u{12EA}', '\u{12EB}', '\u{12EC}', '\u{12ED}', '\u{12EE}', '\u{12EF}', '\u{12F0}', '\u{12F1}', '\u{12F2}', '\u{12F3}', '\u{12F4}', '\u{12F5}', '\u{12F6}', '\u{12F7}', '\u{12F8}', '\u{12F9}', '\u{12FA}', '\u{12FB}', '\u{12FC}', '\u{12FD}', '\u{12FE}', '\u{12FF}', '\u{1300}', '\u{1301}', '\u{1302}', '\u{1303}', '\u{1304}', '\u{1305}', '\u{1306}', '\u{1307}', '\u{1308}', '\u{1309}', '\u{130A}', '\u{130B}', '\u{130C}', '\u{130D}', '\u{130E}', '\u{130F}', '\u{1310}', '\u{1312}', '\u{1313}', '\u{1314}', '\u{1315}', '\u{1318}', '\u{1319}', '\u{131A}', '\u{131B}', '\u{131C}', '\u{131D}', '\u{131E}', '\u{131F}', '\u{1320}', '\u{1321}', '\u{1322}', '\u{1323}', '\u{1324}', '\u{1325}', '\u{1326}', '\u{1327}', '\u{1328}', '\u{1329}', '\u{132A}', '\u{132B}', '\u{132C}', '\u{132D}', '\u{132E}', '\u{132F}', '\u{1330}', '\u{1331}', '\u{1332}', '\u{1333}', '\u{1334}', '\u{1335}', '\u{1336}', '\u{1337}', '\u{1338}', '\u{1339}', '\u{133A}', '\u{133B}', '\u{133C}', '\u{133D}', '\u{133E}', '\u{133F}', '\u{1340}', '\u{1341}', '\u{1342}', '\u{1343}', '\u{1344}', '\u{1345}', '\u{1346}', '\u{1347}', '\u{1348}', '\u{1349}', '\u{134A}', '\u{134B}', '\u{134C}', '\u{134D}', '\u{134E}', '\u{134F}', '\u{1350}', '\u{1351}', '\u{1352}', '\u{1353}', '\u{1354}', '\u{1355}', '\u{1356}', '\u{1357}', '\u{1358}', '\u{1359}', '\u{135A}', '\u{1380}', '\u{1381}', '\u{1382}', '\u{1383}', '\u{1384}', '\u{1385}', '\u{1386}', '\u{1387}', '\u{1388}', '\u{1389}', '\u{138A}', '\u{138B}', '\u{138C}', '\u{138D}', '\u{138E}', '\u{138F}', '\u{13A0}', '\u{13A1}', '\u{13A2}', '\u{13A3}', '\u{13A4}', '\u{13A5}', '\u{13A6}', '\u{13A7}', '\u{13A8}', '\u{13A9}', '\u{13AA}', '\u{13AB}', '\u{13AC}', '\u{13AD}', '\u{13AE}', '\u{13AF}', '\u{13B0}', '\u{13B1}', '\u{13B2}', '\u{13B3}', '\u{13B4}', '\u{13B5}', '\u{13B6}', '\u{13B7}', '\u{13B8}', '\u{13B9}', '\u{13BA}', '\u{13BB}', '\u{13BC}', '\u{13BD}', '\u{13BE}', '\u{13BF}', '\u{13C0}', '\u{13C1}', '\u{13C2}', '\u{13C3}', '\u{13C4}', '\u{13C5}', '\u{13C6}', '\u{13C7}', '\u{13C8}', '\u{13C9}', '\u{13CA}', '\u{13CB}', '\u{13CC}', '\u{13CD}', '\u{13CE}', '\u{13CF}', '\u{13D0}', '\u{13D1}', '\u{13D2}', '\u{13D3}', '\u{13D4}', '\u{13D5}', '\u{13D6}', '\u{13D7}', '\u{13D8}', '\u{13D9}', '\u{13DA}', '\u{13DB}', '\u{13DC}', '\u{13DD}', '\u{13DE}', '\u{13DF}', '\u{13E0}', '\u{13E1}', '\u{13E2}', '\u{13E3}', '\u{13E4}', '\u{13E5}', '\u{13E6}', '\u{13E7}', '\u{13E8}', '\u{13E9}', '\u{13EA}', '\u{13EB}', '\u{13EC}', '\u{13ED}', '\u{13EE}', '\u{13EF}', '\u{13F0}', '\u{13F1}', '\u{13F2}', '\u{13F3}', '\u{13F4}', '\u{1401}', '\u{1402}', '\u{1403}', '\u{1404}', '\u{1405}', '\u{1406}', '\u{1407}', '\u{1408}', '\u{1409}', '\u{140A}', '\u{140B}', '\u{140C}', '\u{140D}', '\u{140E}', '\u{140F}', '\u{1410}', '\u{1411}', '\u{1412}', '\u{1413}', '\u{1414}', '\u{1415}', '\u{1416}', '\u{1417}', '\u{1418}', '\u{1419}', '\u{141A}', '\u{141B}', '\u{141C}', '\u{141D}', '\u{141E}', '\u{141F}', '\u{1420}', '\u{1421}', '\u{1422}', '\u{1423}', '\u{1424}', '\u{1425}', '\u{1426}', '\u{1427}', '\u{1428}', '\u{1429}', '\u{142A}', '\u{142B}', '\u{142C}', '\u{142D}', '\u{142E}', '\u{142F}', '\u{1430}', '\u{1431}', '\u{1432}', '\u{1433}', '\u{1434}', '\u{1435}', '\u{1436}', '\u{1437}', '\u{1438}', '\u{1439}', '\u{143A}', '\u{143B}', '\u{143C}', '\u{143D}', '\u{143E}', '\u{143F}', '\u{1440}', '\u{1441}', '\u{1442}', '\u{1443}', '\u{1444}', '\u{1445}', '\u{1446}', '\u{1447}', '\u{1448}', '\u{1449}', '\u{144A}', '\u{144B}', '\u{144C}', '\u{144D}', '\u{144E}', '\u{144F}', '\u{1450}', '\u{1451}', '\u{1452}', '\u{1453}', '\u{1454}', '\u{1455}', '\u{1456}', '\u{1457}', '\u{1458}', '\u{1459}', '\u{145A}', '\u{145B}', '\u{145C}', '\u{145D}', '\u{145E}', '\u{145F}', '\u{1460}', '\u{1461}', '\u{1462}', '\u{1463}', '\u{1464}', '\u{1465}', '\u{1466}', '\u{1467}', '\u{1468}', '\u{1469}', '\u{146A}', '\u{146B}', '\u{146C}', '\u{146D}', '\u{146E}', '\u{146F}', '\u{1470}', '\u{1471}', '\u{1472}', '\u{1473}', '\u{1474}', '\u{1475}', '\u{1476}', '\u{1477}', '\u{1478}', '\u{1479}', '\u{147A}', '\u{147B}', '\u{147C}', '\u{147D}', '\u{147E}', '\u{147F}', '\u{1480}', '\u{1481}', '\u{1482}', '\u{1483}', '\u{1484}', '\u{1485}', '\u{1486}', '\u{1487}', '\u{1488}', '\u{1489}', '\u{148A}', '\u{148B}', '\u{148C}', '\u{148D}', '\u{148E}', '\u{148F}', '\u{1490}', '\u{1491}', '\u{1492}', '\u{1493}', '\u{1494}', '\u{1495}', '\u{1496}', '\u{1497}', '\u{1498}', '\u{1499}', '\u{149A}', '\u{149B}', '\u{149C}', '\u{149D}', '\u{149E}', '\u{149F}', '\u{14A0}', '\u{14A1}', '\u{14A2}', '\u{14A3}', '\u{14A4}', '\u{14A5}', '\u{14A6}', '\u{14A7}', '\u{14A8}', '\u{14A9}', '\u{14AA}', '\u{14AB}', '\u{14AC}', '\u{14AD}', '\u{14AE}', '\u{14AF}', '\u{14B0}', '\u{14B1}', '\u{14B2}', '\u{14B3}', '\u{14B4}', '\u{14B5}', '\u{14B6}', '\u{14B7}', '\u{14B8}', '\u{14B9}', '\u{14BA}', '\u{14BB}', '\u{14BC}', '\u{14BD}', '\u{14BE}', '\u{14BF}', '\u{14C0}', '\u{14C1}', '\u{14C2}', '\u{14C3}', '\u{14C4}', '\u{14C5}', '\u{14C6}', '\u{14C7}', '\u{14C8}', '\u{14C9}', '\u{14CA}', '\u{14CB}', '\u{14CC}', '\u{14CD}', '\u{14CE}', '\u{14CF}', '\u{14D0}', '\u{14D1}', '\u{14D2}', '\u{14D3}', '\u{14D4}', '\u{14D5}', '\u{14D6}', '\u{14D7}', '\u{14D8}', '\u{14D9}', '\u{14DA}', '\u{14DB}', '\u{14DC}', '\u{14DD}', '\u{14DE}', '\u{14DF}', '\u{14E0}', '\u{14E1}', '\u{14E2}', '\u{14E3}', '\u{14E4}', '\u{14E5}', '\u{14E6}', '\u{14E7}', '\u{14E8}', '\u{14E9}', '\u{14EA}', '\u{14EB}', '\u{14EC}', '\u{14ED}', '\u{14EE}', '\u{14EF}', '\u{14F0}', '\u{14F1}', '\u{14F2}', '\u{14F3}', '\u{14F4}', '\u{14F5}', '\u{14F6}', '\u{14F7}', '\u{14F8}', '\u{14F9}', '\u{14FA}', '\u{14FB}', '\u{14FC}', '\u{14FD}', '\u{14FE}', '\u{14FF}', '\u{1500}', '\u{1501}', '\u{1502}', '\u{1503}', '\u{1504}', '\u{1505}', '\u{1506}', '\u{1507}', '\u{1508}', '\u{1509}', '\u{150A}', '\u{150B}', '\u{150C}', '\u{150D}', '\u{150E}', '\u{150F}', '\u{1510}', '\u{1511}', '\u{1512}', '\u{1513}', '\u{1514}', '\u{1515}', '\u{1516}', '\u{1517}', '\u{1518}', '\u{1519}', '\u{151A}', '\u{151B}', '\u{151C}', '\u{151D}', '\u{151E}', '\u{151F}', '\u{1520}', '\u{1521}', '\u{1522}', '\u{1523}', '\u{1524}', '\u{1525}', '\u{1526}', '\u{1527}', '\u{1528}', '\u{1529}', '\u{152A}', '\u{152B}', '\u{152C}', '\u{152D}', '\u{152E}', '\u{152F}', '\u{1530}', '\u{1531}', '\u{1532}', '\u{1533}', '\u{1534}', '\u{1535}', '\u{1536}', '\u{1537}', '\u{1538}', '\u{1539}', '\u{153A}', '\u{153B}', '\u{153C}', '\u{153D}', '\u{153E}', '\u{153F}', '\u{1540}', '\u{1541}', '\u{1542}', '\u{1543}', '\u{1544}', '\u{1545}', '\u{1546}', '\u{1547}', '\u{1548}', '\u{1549}', '\u{154A}', '\u{154B}', '\u{154C}', '\u{154D}', '\u{154E}', '\u{154F}', '\u{1550}', '\u{1551}', '\u{1552}', '\u{1553}', '\u{1554}', '\u{1555}', '\u{1556}', '\u{1557}', '\u{1558}', '\u{1559}', '\u{155A}', '\u{155B}', '\u{155C}', '\u{155D}', '\u{155E}', '\u{155F}', '\u{1560}', '\u{1561}', '\u{1562}', '\u{1563}', '\u{1564}', '\u{1565}', '\u{1566}', '\u{1567}', '\u{1568}', '\u{1569}', '\u{156A}', '\u{156B}', '\u{156C}', '\u{156D}', '\u{156E}', '\u{156F}', '\u{1570}', '\u{1571}', '\u{1572}', '\u{1573}', '\u{1574}', '\u{1575}', '\u{1576}', '\u{1577}', '\u{1578}', '\u{1579}', '\u{157A}', '\u{157B}', '\u{157C}', '\u{157D}', '\u{157E}', '\u{157F}', '\u{1580}', '\u{1581}', '\u{1582}', '\u{1583}', '\u{1584}', '\u{1585}', '\u{1586}', '\u{1587}', '\u{1588}', '\u{1589}', '\u{158A}', '\u{158B}', '\u{158C}', '\u{158D}', '\u{158E}', '\u{158F}', '\u{1590}', '\u{1591}', '\u{1592}', '\u{1593}', '\u{1594}', '\u{1595}', '\u{1596}', '\u{1597}', '\u{1598}', '\u{1599}', '\u{159A}', '\u{159B}', '\u{159C}', '\u{159D}', '\u{159E}', '\u{159F}', '\u{15A0}', '\u{15A1}', '\u{15A2}', '\u{15A3}', '\u{15A4}', '\u{15A5}', '\u{15A6}', '\u{15A7}', '\u{15A8}', '\u{15A9}', '\u{15AA}', '\u{15AB}', '\u{15AC}', '\u{15AD}', '\u{15AE}', '\u{15AF}', '\u{15B0}', '\u{15B1}', '\u{15B2}', '\u{15B3}', '\u{15B4}', '\u{15B5}', '\u{15B6}', '\u{15B7}', '\u{15B8}', '\u{15B9}', '\u{15BA}', '\u{15BB}', '\u{15BC}', '\u{15BD}', '\u{15BE}', '\u{15BF}', '\u{15C0}', '\u{15C1}', '\u{15C2}', '\u{15C3}', '\u{15C4}', '\u{15C5}', '\u{15C6}', '\u{15C7}', '\u{15C8}', '\u{15C9}', '\u{15CA}', '\u{15CB}', '\u{15CC}', '\u{15CD}', '\u{15CE}', '\u{15CF}', '\u{15D0}', '\u{15D1}', '\u{15D2}', '\u{15D3}', '\u{15D4}', '\u{15D5}', '\u{15D6}', '\u{15D7}', '\u{15D8}', '\u{15D9}', '\u{15DA}', '\u{15DB}', '\u{15DC}', '\u{15DD}', '\u{15DE}', '\u{15DF}', '\u{15E0}', '\u{15E1}', '\u{15E2}', '\u{15E3}', '\u{15E4}', '\u{15E5}', '\u{15E6}', '\u{15E7}', '\u{15E8}', '\u{15E9}', '\u{15EA}', '\u{15EB}', '\u{15EC}', '\u{15ED}', '\u{15EE}', '\u{15EF}', '\u{15F0}', '\u{15F1}', '\u{15F2}', '\u{15F3}', '\u{15F4}', '\u{15F5}', '\u{15F6}', '\u{15F7}', '\u{15F8}', '\u{15F9}', '\u{15FA}', '\u{15FB}', '\u{15FC}', '\u{15FD}', '\u{15FE}', '\u{15FF}', '\u{1600}', '\u{1601}', '\u{1602}', '\u{1603}', '\u{1604}', '\u{1605}', '\u{1606}', '\u{1607}', '\u{1608}', '\u{1609}', '\u{160A}', '\u{160B}', '\u{160C}', '\u{160D}', '\u{160E}', '\u{160F}', '\u{1610}', '\u{1611}', '\u{1612}', '\u{1613}', '\u{1614}', '\u{1615}', '\u{1616}', '\u{1617}', '\u{1618}', '\u{1619}', '\u{161A}', '\u{161B}', '\u{161C}', '\u{161D}', '\u{161E}', '\u{161F}', '\u{1620}', '\u{1621}', '\u{1622}', '\u{1623}', '\u{1624}', '\u{1625}', '\u{1626}', '\u{1627}', '\u{1628}', '\u{1629}', '\u{162A}', '\u{162B}', '\u{162C}', '\u{162D}', '\u{162E}', '\u{162F}', '\u{1630}', '\u{1631}', '\u{1632}', '\u{1633}', '\u{1634}', '\u{1635}', '\u{1636}', '\u{1637}', '\u{1638}', '\u{1639}', '\u{163A}', '\u{163B}', '\u{163C}', '\u{163D}', '\u{163E}', '\u{163F}', '\u{1640}', '\u{1641}', '\u{1642}', '\u{1643}', '\u{1644}', '\u{1645}', '\u{1646}', '\u{1647}', '\u{1648}', '\u{1649}', '\u{164A}', '\u{164B}', '\u{164C}', '\u{164D}', '\u{164E}', '\u{164F}', '\u{1650}', '\u{1651}', '\u{1652}', '\u{1653}', '\u{1654}', '\u{1655}', '\u{1656}', '\u{1657}', '\u{1658}', '\u{1659}', '\u{165A}', '\u{165B}', '\u{165C}', '\u{165D}', '\u{165E}', '\u{165F}', '\u{1660}', '\u{1661}', '\u{1662}', '\u{1663}', '\u{1664}', '\u{1665}', '\u{1666}', '\u{1667}', '\u{1668}', '\u{1669}', '\u{166A}', '\u{166B}', '\u{166C}', '\u{166F}', '\u{1670}', '\u{1671}', '\u{1672}', '\u{1673}', '\u{1674}', '\u{1675}', '\u{1676}', '\u{1681}', '\u{1682}', '\u{1683}', '\u{1684}', '\u{1685}', '\u{1686}', '\u{1687}', '\u{1688}', '\u{1689}', '\u{168A}', '\u{168B}', '\u{168C}', '\u{168D}', '\u{168E}', '\u{168F}', '\u{1690}', '\u{1691}', '\u{1692}', '\u{1693}', '\u{1694}', '\u{1695}', '\u{1696}', '\u{1697}', '\u{1698}', '\u{1699}', '\u{169A}', '\u{16A0}', '\u{16A1}', '\u{16A2}', '\u{16A3}', '\u{16A4}', '\u{16A5}', '\u{16A6}', '\u{16A7}', '\u{16A8}', '\u{16A9}', '\u{16AA}', '\u{16AB}', '\u{16AC}', '\u{16AD}', '\u{16AE}', '\u{16AF}', '\u{16B0}', '\u{16B1}', '\u{16B2}', '\u{16B3}', '\u{16B4}', '\u{16B5}', '\u{16B6}', '\u{16B7}', '\u{16B8}', '\u{16B9}', '\u{16BA}', '\u{16BB}', '\u{16BC}', '\u{16BD}', '\u{16BE}', '\u{16BF}', '\u{16C0}', '\u{16C1}', '\u{16C2}', '\u{16C3}', '\u{16C4}', '\u{16C5}', '\u{16C6}', '\u{16C7}', '\u{16C8}', '\u{16C9}', '\u{16CA}', '\u{16CB}', '\u{16CC}', '\u{16CD}', '\u{16CE}', '\u{16CF}', '\u{16D0}', '\u{16D1}', '\u{16D2}', '\u{16D3}', '\u{16D4}', '\u{16D5}', '\u{16D6}', '\u{16D7}', '\u{16D8}', '\u{16D9}', '\u{16DA}', '\u{16DB}', '\u{16DC}', '\u{16DD}', '\u{16DE}', '\u{16DF}', '\u{16E0}', '\u{16E1}', '\u{16E2}', '\u{16E3}', '\u{16E4}', '\u{16E5}', '\u{16E6}', '\u{16E7}', '\u{16E8}', '\u{16E9}', '\u{16EA}', '\u{1700}', '\u{1701}', '\u{1702}', '\u{1703}', '\u{1704}', '\u{1705}', '\u{1706}', '\u{1707}', '\u{1708}', '\u{1709}', '\u{170A}', '\u{170B}', '\u{170C}', '\u{170E}', '\u{170F}', '\u{1710}', '\u{1711}', '\u{1720}', '\u{1721}', '\u{1722}', '\u{1723}', '\u{1724}', '\u{1725}', '\u{1726}', '\u{1727}', '\u{1728}', '\u{1729}', '\u{172A}', '\u{172B}', '\u{172C}', '\u{172D}', '\u{172E}', '\u{172F}', '\u{1730}', '\u{1731}', '\u{1740}', '\u{1741}', '\u{1742}', '\u{1743}', '\u{1744}', '\u{1745}', '\u{1746}', '\u{1747}', '\u{1748}', '\u{1749}', '\u{174A}', '\u{174B}', '\u{174C}', '\u{174D}', '\u{174E}', '\u{174F}', '\u{1750}', '\u{1751}', '\u{1760}', '\u{1761}', '\u{1762}', '\u{1763}', '\u{1764}', '\u{1765}', '\u{1766}', '\u{1767}', '\u{1768}', '\u{1769}', '\u{176A}', '\u{176B}', '\u{176C}', '\u{176E}', '\u{176F}', '\u{1770}', '\u{1780}', '\u{1781}', '\u{1782}', '\u{1783}', '\u{1784}', '\u{1785}', '\u{1786}', '\u{1787}', '\u{1788}', '\u{1789}', '\u{178A}', '\u{178B}', '\u{178C}', '\u{178D}', '\u{178E}', '\u{178F}', '\u{1790}', '\u{1791}', '\u{1792}', '\u{1793}', '\u{1794}', '\u{1795}', '\u{1796}', '\u{1797}', '\u{1798}', '\u{1799}', '\u{179A}', '\u{179B}', '\u{179C}', '\u{179D}', '\u{179E}', '\u{179F}', '\u{17A0}', '\u{17A1}', '\u{17A2}', '\u{17A3}', '\u{17A4}', '\u{17A5}', '\u{17A6}', '\u{17A7}', '\u{17A8}', '\u{17A9}', '\u{17AA}', '\u{17AB}', '\u{17AC}', '\u{17AD}', '\u{17AE}', '\u{17AF}', '\u{17B0}', '\u{17B1}', '\u{17B2}', '\u{17B3}', '\u{17DC}', '\u{1820}', '\u{1821}', '\u{1822}', '\u{1823}', '\u{1824}', '\u{1825}', '\u{1826}', '\u{1827}', '\u{1828}', '\u{1829}', '\u{182A}', '\u{182B}', '\u{182C}', '\u{182D}', '\u{182E}', '\u{182F}', '\u{1830}', '\u{1831}', '\u{1832}', '\u{1833}', '\u{1834}', '\u{1835}', '\u{1836}', '\u{1837}', '\u{1838}', '\u{1839}', '\u{183A}', '\u{183B}', '\u{183C}', '\u{183D}', '\u{183E}', '\u{183F}', '\u{1840}', '\u{1841}', '\u{1842}', '\u{1844}', '\u{1845}', '\u{1846}', '\u{1847}', '\u{1848}', '\u{1849}', '\u{184A}', '\u{184B}', '\u{184C}', '\u{184D}', '\u{184E}', '\u{184F}', '\u{1850}', '\u{1851}', '\u{1852}', '\u{1853}', '\u{1854}', '\u{1855}', '\u{1856}', '\u{1857}', '\u{1858}', '\u{1859}', '\u{185A}', '\u{185B}', '\u{185C}', '\u{185D}', '\u{185E}', '\u{185F}', '\u{1860}', '\u{1861}', '\u{1862}', '\u{1863}', '\u{1864}', '\u{1865}', '\u{1866}', '\u{1867}', '\u{1868}', '\u{1869}', '\u{186A}', '\u{186B}', '\u{186C}', '\u{186D}', '\u{186E}', '\u{186F}', '\u{1870}', '\u{1871}', '\u{1872}', '\u{1873}', '\u{1874}', '\u{1875}', '\u{1876}', '\u{1877}', '\u{1880}', '\u{1881}', '\u{1882}', '\u{1883}', '\u{1884}', '\u{1885}', '\u{1886}', '\u{1887}', '\u{1888}', '\u{1889}', '\u{188A}', '\u{188B}', '\u{188C}', '\u{188D}', '\u{188E}', '\u{188F}', '\u{1890}', '\u{1891}', '\u{1892}', '\u{1893}', '\u{1894}', '\u{1895}', '\u{1896}', '\u{1897}', '\u{1898}', '\u{1899}', '\u{189A}', '\u{189B}', '\u{189C}', '\u{189D}', '\u{189E}', '\u{189F}', '\u{18A0}', '\u{18A1}', '\u{18A2}', '\u{18A3}', '\u{18A4}', '\u{18A5}', '\u{18A6}', '\u{18A7}', '\u{18A8}', '\u{18AA}', '\u{1900}', '\u{1901}', '\u{1902}', '\u{1903}', '\u{1904}', '\u{1905}', '\u{1906}', '\u{1907}', '\u{1908}', '\u{1909}', '\u{190A}', '\u{190B}', '\u{190C}', '\u{190D}', '\u{190E}', '\u{190F}', '\u{1910}', '\u{1911}', '\u{1912}', '\u{1913}', '\u{1914}', '\u{1915}', '\u{1916}', '\u{1917}', '\u{1918}', '\u{1919}', '\u{191A}', '\u{191B}', '\u{191C}', '\u{1950}', '\u{1951}', '\u{1952}', '\u{1953}', '\u{1954}', '\u{1955}', '\u{1956}', '\u{1957}', '\u{1958}', '\u{1959}', '\u{195A}', '\u{195B}', '\u{195C}', '\u{195D}', '\u{195E}', '\u{195F}', '\u{1960}', '\u{1961}', '\u{1962}', '\u{1963}', '\u{1964}', '\u{1965}', '\u{1966}', '\u{1967}', '\u{1968}', '\u{1969}', '\u{196A}', '\u{196B}', '\u{196C}', '\u{196D}', '\u{1970}', '\u{1971}', '\u{1972}', '\u{1973}', '\u{1974}', '\u{1980}', '\u{1981}', '\u{1982}', '\u{1983}', '\u{1984}', '\u{1985}', '\u{1986}', '\u{1987}', '\u{1988}', '\u{1989}', '\u{198A}', '\u{198B}', '\u{198C}', '\u{198D}', '\u{198E}', '\u{198F}', '\u{1990}', '\u{1991}', '\u{1992}', '\u{1993}', '\u{1994}', '\u{1995}', '\u{1996}', '\u{1997}', '\u{1998}', '\u{1999}', '\u{199A}', '\u{199B}', '\u{199C}', '\u{199D}', '\u{199E}', '\u{199F}', '\u{19A0}', '\u{19A1}', '\u{19A2}', '\u{19A3}', '\u{19A4}', '\u{19A5}', '\u{19A6}', '\u{19A7}', '\u{19A8}', '\u{19A9}', '\u{19C1}', '\u{19C2}', '\u{19C3}', '\u{19C4}', '\u{19C5}', '\u{19C6}', '\u{19C7}', '\u{1A00}', '\u{1A01}', '\u{1A02}', '\u{1A03}', '\u{1A04}', '\u{1A05}', '\u{1A06}', '\u{1A07}', '\u{1A08}', '\u{1A09}', '\u{1A0A}', '\u{1A0B}', '\u{1A0C}', '\u{1A0D}', '\u{1A0E}', '\u{1A0F}', '\u{1A10}', '\u{1A11}', '\u{1A12}', '\u{1A13}', '\u{1A14}', '\u{1A15}', '\u{1A16}', '\u{1B05}', '\u{1B06}', '\u{1B07}', '\u{1B08}', '\u{1B09}', '\u{1B0A}', '\u{1B0B}', '\u{1B0C}', '\u{1B0D}', '\u{1B0E}', '\u{1B0F}', '\u{1B10}', '\u{1B11}', '\u{1B12}', '\u{1B13}', '\u{1B14}', '\u{1B15}', '\u{1B16}', '\u{1B17}', '\u{1B18}', '\u{1B19}', '\u{1B1A}', '\u{1B1B}', '\u{1B1C}', '\u{1B1D}', '\u{1B1E}', '\u{1B1F}', '\u{1B20}', '\u{1B21}', '\u{1B22}', '\u{1B23}', '\u{1B24}', '\u{1B25}', '\u{1B26}', '\u{1B27}', '\u{1B28}', '\u{1B29}', '\u{1B2A}', '\u{1B2B}', '\u{1B2C}', '\u{1B2D}', '\u{1B2E}', '\u{1B2F}', '\u{1B30}', '\u{1B31}', '\u{1B32}', '\u{1B33}', '\u{1B45}', '\u{1B46}', '\u{1B47}', '\u{1B48}', '\u{1B49}', '\u{1B4A}', '\u{1B4B}', '\u{1B83}', '\u{1B84}', '\u{1B85}', '\u{1B86}', '\u{1B87}', '\u{1B88}', '\u{1B89}', '\u{1B8A}', '\u{1B8B}', '\u{1B8C}', '\u{1B8D}', '\u{1B8E}', '\u{1B8F}', '\u{1B90}', '\u{1B91}', '\u{1B92}', '\u{1B93}', '\u{1B94}', '\u{1B95}', '\u{1B96}', '\u{1B97}', '\u{1B98}', '\u{1B99}', '\u{1B9A}', '\u{1B9B}', '\u{1B9C}', '\u{1B9D}', '\u{1B9E}', '\u{1B9F}', '\u{1BA0}', '\u{1BAE}', '\u{1BAF}', '\u{1C00}', '\u{1C01}', '\u{1C02}', '\u{1C03}', '\u{1C04}', '\u{1C05}', '\u{1C06}', '\u{1C07}', '\u{1C08}', '\u{1C09}', '\u{1C0A}', '\u{1C0B}', '\u{1C0C}', '\u{1C0D}', '\u{1C0E}', '\u{1C0F}', '\u{1C10}', '\u{1C11}', '\u{1C12}', '\u{1C13}', '\u{1C14}', '\u{1C15}', '\u{1C16}', '\u{1C17}', '\u{1C18}', '\u{1C19}', '\u{1C1A}', '\u{1C1B}', '\u{1C1C}', '\u{1C1D}', '\u{1C1E}', '\u{1C1F}', '\u{1C20}', '\u{1C21}', '\u{1C22}', '\u{1C23}', '\u{1C4D}', '\u{1C4E}', '\u{1C4F}', '\u{1C5A}', '\u{1C5B}', '\u{1C5C}', '\u{1C5D}', '\u{1C5E}', '\u{1C5F}', '\u{1C60}', '\u{1C61}', '\u{1C62}', '\u{1C63}', '\u{1C64}', '\u{1C65}', '\u{1C66}', '\u{1C67}', '\u{1C68}', '\u{1C69}', '\u{1C6A}', '\u{1C6B}', '\u{1C6C}', '\u{1C6D}', '\u{1C6E}', '\u{1C6F}', '\u{1C70}', '\u{1C71}', '\u{1C72}', '\u{1C73}', '\u{1C74}', '\u{1C75}', '\u{1C76}', '\u{1C77}', '\u{2135}', '\u{2136}', '\u{2137}', '\u{2138}', '\u{2D30}', '\u{2D31}', '\u{2D32}', '\u{2D33}', '\u{2D34}', '\u{2D35}', '\u{2D36}', '\u{2D37}', '\u{2D38}', '\u{2D39}', '\u{2D3A}', '\u{2D3B}', '\u{2D3C}', '\u{2D3D}', '\u{2D3E}', '\u{2D3F}', '\u{2D40}', '\u{2D41}', '\u{2D42}', '\u{2D43}', '\u{2D44}', '\u{2D45}', '\u{2D46}', '\u{2D47}', '\u{2D48}', '\u{2D49}', '\u{2D4A}', '\u{2D4B}', '\u{2D4C}', '\u{2D4D}', '\u{2D4E}', '\u{2D4F}', '\u{2D50}', '\u{2D51}', '\u{2D52}', '\u{2D53}', '\u{2D54}', '\u{2D55}', '\u{2D56}', '\u{2D57}', '\u{2D58}', '\u{2D59}', '\u{2D5A}', '\u{2D5B}', '\u{2D5C}', '\u{2D5D}', '\u{2D5E}', '\u{2D5F}', '\u{2D60}', '\u{2D61}', '\u{2D62}', '\u{2D63}', '\u{2D64}', '\u{2D65}', '\u{2D80}', '\u{2D81}', '\u{2D82}', '\u{2D83}', '\u{2D84}', '\u{2D85}', '\u{2D86}', '\u{2D87}', '\u{2D88}', '\u{2D89}', '\u{2D8A}', '\u{2D8B}', '\u{2D8C}', '\u{2D8D}', '\u{2D8E}', '\u{2D8F}', '\u{2D90}', '\u{2D91}', '\u{2D92}', '\u{2D93}', '\u{2D94}', '\u{2D95}', '\u{2D96}', '\u{2DA0}', '\u{2DA1}', '\u{2DA2}', '\u{2DA3}', '\u{2DA4}', '\u{2DA5}', '\u{2DA6}', '\u{2DA8}', '\u{2DA9}', '\u{2DAA}', '\u{2DAB}', '\u{2DAC}', '\u{2DAD}', '\u{2DAE}', '\u{2DB0}', '\u{2DB1}', '\u{2DB2}', '\u{2DB3}', '\u{2DB4}', '\u{2DB5}', '\u{2DB6}', '\u{2DB8}', '\u{2DB9}', '\u{2DBA}', '\u{2DBB}', '\u{2DBC}', '\u{2DBD}', '\u{2DBE}', '\u{2DC0}', '\u{2DC1}', '\u{2DC2}', '\u{2DC3}', '\u{2DC4}', '\u{2DC5}', '\u{2DC6}', '\u{2DC8}', '\u{2DC9}', '\u{2DCA}', '\u{2DCB}', '\u{2DCC}', '\u{2DCD}', '\u{2DCE}', '\u{2DD0}', '\u{2DD1}', '\u{2DD2}', '\u{2DD3}', '\u{2DD4}', '\u{2DD5}', '\u{2DD6}', '\u{2DD8}', '\u{2DD9}', '\u{2DDA}', '\u{2DDB}', '\u{2DDC}', '\u{2DDD}', '\u{2DDE}', '\u{3006}', '\u{303C}', '\u{3041}', '\u{3042}', '\u{3043}', '\u{3044}', '\u{3045}', '\u{3046}', '\u{3047}', '\u{3048}', '\u{3049}', '\u{304A}', '\u{304B}', '\u{304C}', '\u{304D}', '\u{304E}', '\u{304F}', '\u{3050}', '\u{3051}', '\u{3052}', '\u{3053}', '\u{3054}', '\u{3055}', '\u{3056}', '\u{3057}', '\u{3058}', '\u{3059}', '\u{305A}', '\u{305B}', '\u{305C}', '\u{305D}', '\u{305E}', '\u{305F}', '\u{3060}', '\u{3061}', '\u{3062}', '\u{3063}', '\u{3064}', '\u{3065}', '\u{3066}', '\u{3067}', '\u{3068}', '\u{3069}', '\u{306A}', '\u{306B}', '\u{306C}', '\u{306D}', '\u{306E}', '\u{306F}', '\u{3070}', '\u{3071}', '\u{3072}', '\u{3073}', '\u{3074}', '\u{3075}', '\u{3076}', '\u{3077}', '\u{3078}', '\u{3079}', '\u{307A}', '\u{307B}', '\u{307C}', '\u{307D}', '\u{307E}', '\u{307F}', '\u{3080}', '\u{3081}', '\u{3082}', '\u{3083}', '\u{3084}', '\u{3085}', '\u{3086}', '\u{3087}', '\u{3088}', '\u{3089}', '\u{308A}', '\u{308B}', '\u{308C}', '\u{308D}', '\u{308E}', '\u{308F}', '\u{3090}', '\u{3091}', '\u{3092}', '\u{3093}', '\u{3094}', '\u{3095}', '\u{3096}', '\u{309F}', '\u{30A1}', '\u{30A2}', '\u{30A3}', '\u{30A4}', '\u{30A5}', '\u{30A6}', '\u{30A7}', '\u{30A8}', '\u{30A9}', '\u{30AA}', '\u{30AB}', '\u{30AC}', '\u{30AD}', '\u{30AE}', '\u{30AF}', '\u{30B0}', '\u{30B1}', '\u{30B2}', '\u{30B3}', '\u{30B4}', '\u{30B5}', '\u{30B6}', '\u{30B7}', '\u{30B8}', '\u{30B9}', '\u{30BA}', '\u{30BB}', '\u{30BC}', '\u{30BD}', '\u{30BE}', '\u{30BF}', '\u{30C0}', '\u{30C1}', '\u{30C2}', '\u{30C3}', '\u{30C4}', '\u{30C5}', '\u{30C6}', '\u{30C7}', '\u{30C8}', '\u{30C9}', '\u{30CA}', '\u{30CB}', '\u{30CC}', '\u{30CD}', '\u{30CE}', '\u{30CF}', '\u{30D0}', '\u{30D1}', '\u{30D2}', '\u{30D3}', '\u{30D4}', '\u{30D5}', '\u{30D6}', '\u{30D7}', '\u{30D8}', '\u{30D9}', '\u{30DA}', '\u{30DB}', '\u{30DC}', '\u{30DD}', '\u{30DE}', '\u{30DF}', '\u{30E0}', '\u{30E1}', '\u{30E2}', '\u{30E3}', '\u{30E4}', '\u{30E5}', '\u{30E6}', '\u{30E7}', '\u{30E8}', '\u{30E9}', '\u{30EA}', '\u{30EB}', '\u{30EC}', '\u{30ED}', '\u{30EE}', '\u{30EF}', '\u{30F0}', '\u{30F1}', '\u{30F2}', '\u{30F3}', '\u{30F4}', '\u{30F5}', '\u{30F6}', '\u{30F7}', '\u{30F8}', '\u{30F9}', '\u{30FA}', '\u{30FF}', '\u{3105}', '\u{3106}', '\u{3107}', '\u{3108}', '\u{3109}', '\u{310A}', '\u{310B}', '\u{310C}', '\u{310D}', '\u{310E}', '\u{310F}', '\u{3110}', '\u{3111}', '\u{3112}', '\u{3113}', '\u{3114}', '\u{3115}', '\u{3116}', '\u{3117}', '\u{3118}', '\u{3119}', '\u{311A}', '\u{311B}', '\u{311C}', '\u{311D}', '\u{311E}', '\u{311F}', '\u{3120}', '\u{3121}', '\u{3122}', '\u{3123}', '\u{3124}', '\u{3125}', '\u{3126}', '\u{3127}', '\u{3128}', '\u{3129}', '\u{312A}', '\u{312B}', '\u{312C}', '\u{312D}', '\u{3131}', '\u{3132}', '\u{3133}', '\u{3134}', '\u{3135}', '\u{3136}', '\u{3137}', '\u{3138}', '\u{3139}', '\u{313A}', '\u{313B}', '\u{313C}', '\u{313D}', '\u{313E}', '\u{313F}', '\u{3140}', '\u{3141}', '\u{3142}', '\u{3143}', '\u{3144}', '\u{3145}', '\u{3146}', '\u{3147}', '\u{3148}', '\u{3149}', '\u{314A}', '\u{314B}', '\u{314C}', '\u{314D}', '\u{314E}', '\u{314F}', '\u{3150}', '\u{3151}', '\u{3152}', '\u{3153}', '\u{3154}', '\u{3155}', '\u{3156}', '\u{3157}', '\u{3158}', '\u{3159}', '\u{315A}', '\u{315B}', '\u{315C}', '\u{315D}', '\u{315E}', '\u{315F}', '\u{3160}', '\u{3161}', '\u{3162}', '\u{3163}', '\u{3164}', '\u{3165}', '\u{3166}', '\u{3167}', '\u{3168}', '\u{3169}', '\u{316A}', '\u{316B}', '\u{316C}', '\u{316D}', '\u{316E}', '\u{316F}', '\u{3170}', '\u{3171}', '\u{3172}', '\u{3173}', '\u{3174}', '\u{3175}', '\u{3176}', '\u{3177}', '\u{3178}', '\u{3179}', '\u{317A}', '\u{317B}', '\u{317C}', '\u{317D}', '\u{317E}', '\u{317F}', '\u{3180}', '\u{3181}', '\u{3182}', '\u{3183}', '\u{3184}', '\u{3185}', '\u{3186}', '\u{3187}', '\u{3188}', '\u{3189}', '\u{318A}', '\u{318B}', '\u{318C}', '\u{318D}', '\u{318E}', '\u{31A0}', '\u{31A1}', '\u{31A2}', '\u{31A3}', '\u{31A4}', '\u{31A5}', '\u{31A6}', '\u{31A7}', '\u{31A8}', '\u{31A9}', '\u{31AA}', '\u{31AB}', '\u{31AC}', '\u{31AD}', '\u{31AE}', '\u{31AF}', '\u{31B0}', '\u{31B1}', '\u{31B2}', '\u{31B3}', '\u{31B4}', '\u{31B5}', '\u{31B6}', '\u{31B7}', '\u{31F0}', '\u{31F1}', '\u{31F2}', '\u{31F3}', '\u{31F4}', '\u{31F5}', '\u{31F6}', '\u{31F7}', '\u{31F8}', '\u{31F9}', '\u{31FA}', '\u{31FB}', '\u{31FC}', '\u{31FD}', '\u{31FE}', '\u{31FF}', '\u{3400}', '\u{4DB5}', '\u{4E00}', '\u{9FC3}', '\u{A000}', '\u{A001}', '\u{A002}', '\u{A003}', '\u{A004}', '\u{A005}', '\u{A006}', '\u{A007}', '\u{A008}', '\u{A009}', '\u{A00A}', '\u{A00B}', '\u{A00C}', '\u{A00D}', '\u{A00E}', '\u{A00F}', '\u{A010}', '\u{A011}', '\u{A012}', '\u{A013}', '\u{A014}', '\u{A016}', '\u{A017}', '\u{A018}', '\u{A019}', '\u{A01A}', '\u{A01B}', '\u{A01C}', '\u{A01D}', '\u{A01E}', '\u{A01F}', '\u{A020}', '\u{A021}', '\u{A022}', '\u{A023}', '\u{A024}', '\u{A025}', '\u{A026}', '\u{A027}', '\u{A028}', '\u{A029}', '\u{A02A}', '\u{A02B}', '\u{A02C}', '\u{A02D}', '\u{A02E}', '\u{A02F}', '\u{A030}', '\u{A031}', '\u{A032}', '\u{A033}', '\u{A034}', '\u{A035}', '\u{A036}', '\u{A037}', '\u{A038}', '\u{A039}', '\u{A03A}', '\u{A03B}', '\u{A03C}', '\u{A03D}', '\u{A03E}', '\u{A03F}', '\u{A040}', '\u{A041}', '\u{A042}', '\u{A043}', '\u{A044}', '\u{A045}', '\u{A046}', '\u{A047}', '\u{A048}', '\u{A049}', '\u{A04A}', '\u{A04B}', '\u{A04C}', '\u{A04D}', '\u{A04E}', '\u{A04F}', '\u{A050}', '\u{A051}', '\u{A052}', '\u{A053}', '\u{A054}', '\u{A055}', '\u{A056}', '\u{A057}', '\u{A058}', '\u{A059}', '\u{A05A}', '\u{A05B}', '\u{A05C}', '\u{A05D}', '\u{A05E}', '\u{A05F}', '\u{A060}', '\u{A061}', '\u{A062}', '\u{A063}', '\u{A064}', '\u{A065}', '\u{A066}', '\u{A067}', '\u{A068}', '\u{A069}', '\u{A06A}', '\u{A06B}', '\u{A06C}', '\u{A06D}', '\u{A06E}', '\u{A06F}', '\u{A070}', '\u{A071}', '\u{A072}', '\u{A073}', '\u{A074}', '\u{A075}', '\u{A076}', '\u{A077}', '\u{A078}', '\u{A079}', '\u{A07A}', '\u{A07B}', '\u{A07C}', '\u{A07D}', '\u{A07E}', '\u{A07F}', '\u{A080}', '\u{A081}', '\u{A082}', '\u{A083}', '\u{A084}', '\u{A085}', '\u{A086}', '\u{A087}', '\u{A088}', '\u{A089}', '\u{A08A}', '\u{A08B}', '\u{A08C}', '\u{A08D}', '\u{A08E}', '\u{A08F}', '\u{A090}', '\u{A091}', '\u{A092}', '\u{A093}', '\u{A094}', '\u{A095}', '\u{A096}', '\u{A097}', '\u{A098}', '\u{A099}', '\u{A09A}', '\u{A09B}', '\u{A09C}', '\u{A09D}', '\u{A09E}', '\u{A09F}', '\u{A0A0}', '\u{A0A1}', '\u{A0A2}', '\u{A0A3}', '\u{A0A4}', '\u{A0A5}', '\u{A0A6}', '\u{A0A7}', '\u{A0A8}', '\u{A0A9}', '\u{A0AA}', '\u{A0AB}', '\u{A0AC}', '\u{A0AD}', '\u{A0AE}', '\u{A0AF}', '\u{A0B0}', '\u{A0B1}', '\u{A0B2}', '\u{A0B3}', '\u{A0B4}', '\u{A0B5}', '\u{A0B6}', '\u{A0B7}', '\u{A0B8}', '\u{A0B9}', '\u{A0BA}', '\u{A0BB}', '\u{A0BC}', '\u{A0BD}', '\u{A0BE}', '\u{A0BF}', '\u{A0C0}', '\u{A0C1}', '\u{A0C2}', '\u{A0C3}', '\u{A0C4}', '\u{A0C5}', '\u{A0C6}', '\u{A0C7}', '\u{A0C8}', '\u{A0C9}', '\u{A0CA}', '\u{A0CB}', '\u{A0CC}', '\u{A0CD}', '\u{A0CE}', '\u{A0CF}', '\u{A0D0}', '\u{A0D1}', '\u{A0D2}', '\u{A0D3}', '\u{A0D4}', '\u{A0D5}', '\u{A0D6}', '\u{A0D7}', '\u{A0D8}', '\u{A0D9}', '\u{A0DA}', '\u{A0DB}', '\u{A0DC}', '\u{A0DD}', '\u{A0DE}', '\u{A0DF}', '\u{A0E0}', '\u{A0E1}', '\u{A0E2}', '\u{A0E3}', '\u{A0E4}', '\u{A0E5}', '\u{A0E6}', '\u{A0E7}', '\u{A0E8}', '\u{A0E9}', '\u{A0EA}', '\u{A0EB}', '\u{A0EC}', '\u{A0ED}', '\u{A0EE}', '\u{A0EF}', '\u{A0F0}', '\u{A0F1}', '\u{A0F2}', '\u{A0F3}', '\u{A0F4}', '\u{A0F5}', '\u{A0F6}', '\u{A0F7}', '\u{A0F8}', '\u{A0F9}', '\u{A0FA}', '\u{A0FB}', '\u{A0FC}', '\u{A0FD}', '\u{A0FE}', '\u{A0FF}', '\u{A100}', '\u{A101}', '\u{A102}', '\u{A103}', '\u{A104}', '\u{A105}', '\u{A106}', '\u{A107}', '\u{A108}', '\u{A109}', '\u{A10A}', '\u{A10B}', '\u{A10C}', '\u{A10D}', '\u{A10E}', '\u{A10F}', '\u{A110}', '\u{A111}', '\u{A112}', '\u{A113}', '\u{A114}', '\u{A115}', '\u{A116}', '\u{A117}', '\u{A118}', '\u{A119}', '\u{A11A}', '\u{A11B}', '\u{A11C}', '\u{A11D}', '\u{A11E}', '\u{A11F}', '\u{A120}', '\u{A121}', '\u{A122}', '\u{A123}', '\u{A124}', '\u{A125}', '\u{A126}', '\u{A127}', '\u{A128}', '\u{A129}', '\u{A12A}', '\u{A12B}', '\u{A12C}', '\u{A12D}', '\u{A12E}', '\u{A12F}', '\u{A130}', '\u{A131}', '\u{A132}', '\u{A133}', '\u{A134}', '\u{A135}', '\u{A136}', '\u{A137}', '\u{A138}', '\u{A139}', '\u{A13A}', '\u{A13B}', '\u{A13C}', '\u{A13D}', '\u{A13E}', '\u{A13F}', '\u{A140}', '\u{A141}', '\u{A142}', '\u{A143}', '\u{A144}', '\u{A145}', '\u{A146}', '\u{A147}', '\u{A148}', '\u{A149}', '\u{A14A}', '\u{A14B}', '\u{A14C}', '\u{A14D}', '\u{A14E}', '\u{A14F}', '\u{A150}', '\u{A151}', '\u{A152}', '\u{A153}', '\u{A154}', '\u{A155}', '\u{A156}', '\u{A157}', '\u{A158}', '\u{A159}', '\u{A15A}', '\u{A15B}', '\u{A15C}', '\u{A15D}', '\u{A15E}', '\u{A15F}', '\u{A160}', '\u{A161}', '\u{A162}', '\u{A163}', '\u{A164}', '\u{A165}', '\u{A166}', '\u{A167}', '\u{A168}', '\u{A169}', '\u{A16A}', '\u{A16B}', '\u{A16C}', '\u{A16D}', '\u{A16E}', '\u{A16F}', '\u{A170}', '\u{A171}', '\u{A172}', '\u{A173}', '\u{A174}', '\u{A175}', '\u{A176}', '\u{A177}', '\u{A178}', '\u{A179}', '\u{A17A}', '\u{A17B}', '\u{A17C}', '\u{A17D}', '\u{A17E}', '\u{A17F}', '\u{A180}', '\u{A181}', '\u{A182}', '\u{A183}', '\u{A184}', '\u{A185}', '\u{A186}', '\u{A187}', '\u{A188}', '\u{A189}', '\u{A18A}', '\u{A18B}', '\u{A18C}', '\u{A18D}', '\u{A18E}', '\u{A18F}', '\u{A190}', '\u{A191}', '\u{A192}', '\u{A193}', '\u{A194}', '\u{A195}', '\u{A196}', '\u{A197}', '\u{A198}', '\u{A199}', '\u{A19A}', '\u{A19B}', '\u{A19C}', '\u{A19D}', '\u{A19E}', '\u{A19F}', '\u{A1A0}', '\u{A1A1}', '\u{A1A2}', '\u{A1A3}', '\u{A1A4}', '\u{A1A5}', '\u{A1A6}', '\u{A1A7}', '\u{A1A8}', '\u{A1A9}', '\u{A1AA}', '\u{A1AB}', '\u{A1AC}', '\u{A1AD}', '\u{A1AE}', '\u{A1AF}') + } + + fn is_unicode_combining_spacing_mark(self) -> bool { + match_char_class!(self, + '\u{0903}', '\u{093E}', '\u{093F}', '\u{0940}', '\u{0949}', '\u{094A}', '\u{094B}', '\u{094C}', '\u{0982}', '\u{0983}', '\u{09BE}', '\u{09BF}', '\u{09C0}', '\u{09C7}', '\u{09C8}', '\u{09CB}', '\u{09CC}', '\u{09D7}', '\u{0A03}', '\u{0A3E}', '\u{0A3F}', '\u{0A40}', '\u{0A83}', '\u{0ABE}', '\u{0ABF}', '\u{0AC0}', '\u{0AC9}', '\u{0ACB}', '\u{0ACC}', '\u{0B02}', '\u{0B03}', '\u{0B3E}', '\u{0B40}', '\u{0B47}', '\u{0B48}', '\u{0B4B}', '\u{0B4C}', '\u{0B57}', '\u{0BBE}', '\u{0BBF}', '\u{0BC1}', '\u{0BC2}', '\u{0BC6}', '\u{0BC7}', '\u{0BC8}', '\u{0BCA}', '\u{0BCB}', '\u{0BCC}', '\u{0BD7}', '\u{0C01}', '\u{0C02}', '\u{0C03}', '\u{0C41}', '\u{0C42}', '\u{0C43}', '\u{0C44}', '\u{0C82}', '\u{0C83}', '\u{0CBE}', '\u{0CC0}', '\u{0CC1}', '\u{0CC2}', '\u{0CC3}', '\u{0CC4}', '\u{0CC7}', '\u{0CC8}', '\u{0CCA}', '\u{0CCB}', '\u{0CD5}', '\u{0CD6}', '\u{0D02}', '\u{0D03}', '\u{0D3E}', '\u{0D3F}', '\u{0D40}', '\u{0D46}', '\u{0D47}', '\u{0D48}', '\u{0D4A}', '\u{0D4B}', '\u{0D4C}', '\u{0D57}', '\u{0D82}', '\u{0D83}', '\u{0DCF}', '\u{0DD0}', '\u{0DD1}', '\u{0DD8}', '\u{0DD9}', '\u{0DDA}', '\u{0DDB}', '\u{0DDC}', '\u{0DDD}', '\u{0DDE}', '\u{0DDF}', '\u{0DF2}', '\u{0DF3}', '\u{0F3E}', '\u{0F3F}', '\u{0F7F}', '\u{102B}', '\u{102C}', '\u{1031}', '\u{1038}', '\u{103B}', '\u{103C}', '\u{1056}', '\u{1057}', '\u{1062}', '\u{1063}', '\u{1064}', '\u{1067}', '\u{1068}', '\u{1069}', '\u{106A}', '\u{106B}', '\u{106C}', '\u{106D}', '\u{1083}', '\u{1084}', '\u{1087}', '\u{1088}', '\u{1089}', '\u{108A}', '\u{108B}', '\u{108C}', '\u{108F}', '\u{17B6}', '\u{17BE}', '\u{17BF}', '\u{17C0}', '\u{17C1}', '\u{17C2}', '\u{17C3}', '\u{17C4}', '\u{17C5}', '\u{17C7}', '\u{17C8}', '\u{1923}', '\u{1924}', '\u{1925}', '\u{1926}', '\u{1929}', '\u{192A}', '\u{192B}', '\u{1930}', '\u{1931}', '\u{1933}', '\u{1934}', '\u{1935}', '\u{1936}', '\u{1937}', '\u{1938}', '\u{19B0}', '\u{19B1}', '\u{19B2}', '\u{19B3}', '\u{19B4}', '\u{19B5}', '\u{19B6}', '\u{19B7}', '\u{19B8}', '\u{19B9}', '\u{19BA}', '\u{19BB}', '\u{19BC}', '\u{19BD}', '\u{19BE}', '\u{19BF}', '\u{19C0}', '\u{19C8}', '\u{19C9}', '\u{1A19}', '\u{1A1A}', '\u{1A1B}', '\u{1B04}', '\u{1B35}', '\u{1B3B}', '\u{1B3D}', '\u{1B3E}', '\u{1B3F}', '\u{1B40}', '\u{1B41}', '\u{1B43}', '\u{1B44}', '\u{1B82}', '\u{1BA1}', '\u{1BA6}', '\u{1BA7}', '\u{1BAA}', '\u{1C24}', '\u{1C25}', '\u{1C26}', '\u{1C27}', '\u{1C28}', '\u{1C29}', '\u{1C2A}', '\u{1C2B}', '\u{1C34}', '\u{1C35}', '\u{A823}', '\u{A824}', '\u{A827}', '\u{A880}', '\u{A881}', '\u{A8B4}', '\u{A8B5}', '\u{A8B6}', '\u{A8B7}', '\u{A8B8}', '\u{A8B9}', '\u{A8BA}', '\u{A8BB}', '\u{A8BC}', '\u{A8BD}', '\u{A8BE}', '\u{A8BF}', '\u{A8C0}', '\u{A8C1}', '\u{A8C2}', '\u{A8C3}', '\u{A952}', '\u{A953}', '\u{AA2F}', '\u{AA30}', '\u{AA33}', '\u{AA34}', '\u{AA4D}') + } + + fn is_unicode_decimal_number(self) -> bool { + match_char_class!(self, + '\u{0030}', '\u{0031}', '\u{0032}', '\u{0033}', '\u{0034}', '\u{0035}', '\u{0036}', '\u{0037}', '\u{0038}', '\u{0039}', '\u{0660}', '\u{0661}', '\u{0662}', '\u{0663}', '\u{0664}', '\u{0665}', '\u{0666}', '\u{0667}', '\u{0668}', '\u{0669}', '\u{06F0}', '\u{06F1}', '\u{06F2}', '\u{06F3}', '\u{06F4}', '\u{06F5}', '\u{06F6}', '\u{06F7}', '\u{06F8}', '\u{06F9}', '\u{07C0}', '\u{07C1}', '\u{07C2}', '\u{07C3}', '\u{07C4}', '\u{07C5}', '\u{07C6}', '\u{07C7}', '\u{07C8}', '\u{07C9}', '\u{0966}', '\u{0967}', '\u{0968}', '\u{0969}', '\u{096A}', '\u{096B}', '\u{096C}', '\u{096D}', '\u{096E}', '\u{096F}', '\u{09E6}', '\u{09E7}', '\u{09E8}', '\u{09E9}', '\u{09EA}', '\u{09EB}', '\u{09EC}', '\u{09ED}', '\u{09EE}', '\u{09EF}', '\u{0A66}', '\u{0A67}', '\u{0A68}', '\u{0A69}', '\u{0A6A}', '\u{0A6B}', '\u{0A6C}', '\u{0A6D}', '\u{0A6E}', '\u{0A6F}', '\u{0AE6}', '\u{0AE7}', '\u{0AE8}', '\u{0AE9}', '\u{0AEA}', '\u{0AEB}', '\u{0AEC}', '\u{0AED}', '\u{0AEE}', '\u{0AEF}', '\u{0B66}', '\u{0B67}', '\u{0B68}', '\u{0B69}', '\u{0B6A}', '\u{0B6B}', '\u{0B6C}', '\u{0B6D}', '\u{0B6E}', '\u{0B6F}', '\u{0BE6}', '\u{0BE7}', '\u{0BE8}', '\u{0BE9}', '\u{0BEA}', '\u{0BEB}', '\u{0BEC}', '\u{0BED}', '\u{0BEE}', '\u{0BEF}', '\u{0C66}', '\u{0C67}', '\u{0C68}', '\u{0C69}', '\u{0C6A}', '\u{0C6B}', '\u{0C6C}', '\u{0C6D}', '\u{0C6E}', '\u{0C6F}', '\u{0CE6}', '\u{0CE7}', '\u{0CE8}', '\u{0CE9}', '\u{0CEA}', '\u{0CEB}', '\u{0CEC}', '\u{0CED}', '\u{0CEE}', '\u{0CEF}', '\u{0D66}', '\u{0D67}', '\u{0D68}', '\u{0D69}', '\u{0D6A}', '\u{0D6B}', '\u{0D6C}', '\u{0D6D}', '\u{0D6E}', '\u{0D6F}', '\u{0E50}', '\u{0E51}', '\u{0E52}', '\u{0E53}', '\u{0E54}', '\u{0E55}', '\u{0E56}', '\u{0E57}', '\u{0E58}', '\u{0E59}', '\u{0ED0}', '\u{0ED1}', '\u{0ED2}', '\u{0ED3}', '\u{0ED4}', '\u{0ED5}', '\u{0ED6}', '\u{0ED7}', '\u{0ED8}', '\u{0ED9}', '\u{0F20}', '\u{0F21}', '\u{0F22}', '\u{0F23}', '\u{0F24}', '\u{0F25}', '\u{0F26}', '\u{0F27}', '\u{0F28}', '\u{0F29}', '\u{1040}', '\u{1041}', '\u{1042}', '\u{1043}', '\u{1044}', '\u{1045}', '\u{1046}', '\u{1047}', '\u{1048}', '\u{1049}', '\u{1090}', '\u{1091}', '\u{1092}', '\u{1093}', '\u{1094}', '\u{1095}', '\u{1096}', '\u{1097}', '\u{1098}', '\u{1099}', '\u{17E0}', '\u{17E1}', '\u{17E2}', '\u{17E3}', '\u{17E4}', '\u{17E5}', '\u{17E6}', '\u{17E7}', '\u{17E8}', '\u{17E9}', '\u{1810}', '\u{1811}', '\u{1812}', '\u{1813}', '\u{1814}', '\u{1815}', '\u{1816}', '\u{1817}', '\u{1818}', '\u{1819}', '\u{1946}', '\u{1947}', '\u{1948}', '\u{1949}', '\u{194A}', '\u{194B}', '\u{194C}', '\u{194D}', '\u{194E}', '\u{194F}', '\u{19D0}', '\u{19D1}', '\u{19D2}', '\u{19D3}', '\u{19D4}', '\u{19D5}', '\u{19D6}', '\u{19D7}', '\u{19D8}', '\u{19D9}', '\u{1B50}', '\u{1B51}', '\u{1B52}', '\u{1B53}', '\u{1B54}', '\u{1B55}', '\u{1B56}', '\u{1B57}', '\u{1B58}', '\u{1B59}', '\u{1BB0}', '\u{1BB1}', '\u{1BB2}', '\u{1BB3}', '\u{1BB4}', '\u{1BB5}', '\u{1BB6}', '\u{1BB7}', '\u{1BB8}', '\u{1BB9}', '\u{1C40}', '\u{1C41}', '\u{1C42}', '\u{1C43}', '\u{1C44}', '\u{1C45}', '\u{1C46}', '\u{1C47}', '\u{1C48}', '\u{1C49}', '\u{1C50}', '\u{1C51}', '\u{1C52}', '\u{1C53}', '\u{1C54}', '\u{1C55}', '\u{1C56}', '\u{1C57}', '\u{1C58}', '\u{1C59}', '\u{A620}', '\u{A621}', '\u{A622}', '\u{A623}', '\u{A624}', '\u{A625}', '\u{A626}', '\u{A627}', '\u{A628}', '\u{A629}', '\u{A8D0}', '\u{A8D1}', '\u{A8D2}', '\u{A8D3}', '\u{A8D4}', '\u{A8D5}', '\u{A8D6}', '\u{A8D7}', '\u{A8D8}', '\u{A8D9}', '\u{A900}', '\u{A901}', '\u{A902}', '\u{A903}', '\u{A904}', '\u{A905}', '\u{A906}', '\u{A907}', '\u{A908}', '\u{A909}', '\u{AA50}', '\u{AA51}', '\u{AA52}', '\u{AA53}', '\u{AA54}', '\u{AA55}', '\u{AA56}', '\u{AA57}', '\u{AA58}', '\u{AA59}', '\u{FF10}', '\u{FF11}', '\u{FF12}', '\u{FF13}', '\u{FF14}', '\u{FF15}', '\u{FF16}', '\u{FF17}', '\u{FF18}', '\u{FF19}') + } + + fn is_unicode_connector_punctiation(self) -> bool { + match_char_class!(self, + '\u{005F}', '\u{203F}', '\u{2040}', '\u{2054}', '\u{FE33}', '\u{FE34}', '\u{FE4D}', '\u{FE4E}', '\u{FE4F}', '\u{FF3F}') + } + + fn is_unicode_space_separator(self) -> bool { + match_char_class!(self, + '\u{0020}', '\u{00A0}', '\u{1680}', '\u{2000}', '\u{2001}', '\u{2002}', '\u{2003}', '\u{2004}', '\u{2005}', '\u{2006}', '\u{2007}', '\u{2008}', '\u{2009}', '\u{200A}', '\u{202F}', '\u{205F}', '\u{3000}') + } + + fn is_es_identifier_start(self) -> bool { + match self { + '$' | '_' | '\\' => true, + c if c.is_unicode_letter() => true, + _ => false + } + } + + // see section 7.6 + fn is_es_identifier_part(self) -> bool { + match self { + '\u{200C}' | '\u{200D}' => true, + c if c.is_es_identifier_start() => true, + c if c.is_unicode_combining_spacing_mark() => true, + c if c.is_unicode_nonspacing_mark() => true, + c if c.is_unicode_decimal_number() => true, + c if c.is_unicode_connector_punctiation() => true, + _ => false + } + } + + fn is_es_whitespace(self) -> bool { + match self { + '\t' | '\u{000B}' | '\u{000C}' | '\u{0020}' | '\u{00A0}' | '\u{FEFF}' => true, + c => c.is_unicode_space_separator() + } + } + + fn is_es_line_terminator(self) -> bool { + match self { + '\n' | '\r' | '\u{2028}' | '\u{2029}' => true, + _ => false + } + } +} + +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29265.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29265.rs new file mode 100644 index 000000000000..7e834c38dab4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29265.rs @@ -0,0 +1,11 @@ +// aux-build:issue-29265.rs +// check-pass + +extern crate issue_29265 as lib; + +static _UNUSED: &'static lib::SomeType = &lib::SOME_VALUE; + +fn main() { + vec![0u8; lib::SOME_VALUE.some_member]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29276.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29276.rs new file mode 100644 index 000000000000..a628bff71260 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29276.rs @@ -0,0 +1,6 @@ +// check-pass +#![allow(dead_code)] +struct S([u8; { struct Z; 0 }]); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2935.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2935.rs new file mode 100644 index 000000000000..d1c071890035 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2935.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +#![feature(box_syntax)] + +//type t = { a: isize }; +// type t = { a: bool }; +type t = bool; + +trait it { + fn f(&self); +} + +impl it for t { + fn f(&self) { } +} + +pub fn main() { + // let x = ({a: 4} as it); + // let y = box ({a: 4}); + // let z = box ({a: 4} as it); + // let z = box ({a: true} as it); + let z: Box<_> = box (box true as Box); + // x.f(); + // y.f(); + // (*z).f(); + println!("ok so far..."); + z.f(); //segfault +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2936.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2936.rs new file mode 100644 index 000000000000..6d1cd6338399 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2936.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(non_camel_case_types)] + +trait bar { + fn get_bar(&self) -> T; +} + +fn foo>(b: U) -> T { + b.get_bar() +} + +struct cbar { + x: isize, +} + +impl bar for cbar { + fn get_bar(&self) -> isize { + self.x + } +} + +fn cbar(x: isize) -> cbar { + cbar { + x: x + } +} + +pub fn main() { + let x: isize = foo::(cbar(5)); + assert_eq!(x, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2937.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2937.rs new file mode 100644 index 000000000000..e6dd8f660644 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2937.rs @@ -0,0 +1,7 @@ +use m::f as x; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +mod m {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29466.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29466.rs new file mode 100644 index 000000000000..f29cb8a35288 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29466.rs @@ -0,0 +1,3604 @@ +// ignore-tidy-filelength +// +// run-pass + +#![allow(unused_variables)] + +macro_rules! m( + ($e1:expr => $e2:expr) => ({ $e1 }) +); + +fn main() { + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + let x = m!(1 => 2); + + println!("{}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29485.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29485.rs new file mode 100644 index 000000000000..f5874c11791c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29485.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_attributes)] +// aux-build:issue-29485.rs +// ignore-emscripten no threads + +#[feature(recover)] + +extern crate a; + +fn main() { + let _ = std::thread::spawn(move || { + a::f(&mut a::X(0), g); + }).join(); +} + +fn g() { + panic!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29488.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29488.rs new file mode 100644 index 000000000000..c7ee3a110ec5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29488.rs @@ -0,0 +1,24 @@ +// run-pass +// ignore-emscripten no threads support + +use std::thread; + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) { + println!("test2"); + } +} + +thread_local!(static FOO: Foo = Foo); + +fn main() { + // Off the main thread due to #28129, be sure to initialize FOO first before + // calling `println!` + thread::spawn(|| { + FOO.with(|_| {}); + println!("test1"); + }).join().unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2951.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2951.rs new file mode 100644 index 000000000000..1b80bfb464d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2951.rs @@ -0,0 +1,12 @@ +fn foo(x: T, y: U) { + let mut xx = x; + xx = y; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29516.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29516.rs new file mode 100644 index 000000000000..d63f54006e1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29516.rs @@ -0,0 +1,21 @@ +// check-pass +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +auto trait NotSame {} + +impl !NotSame for (A, A) {} + +trait OneOfEach {} + +impl OneOfEach for (A,) {} + +impl OneOfEach for (A, B) +where + (B,): OneOfEach, + (A, B): NotSame, +{ +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29522.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29522.rs new file mode 100644 index 000000000000..341b80c8ce0b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29522.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(unused_variables)] +// check that we don't accidentally capture upvars just because their name +// occurs in a path + +fn assert_static(_t: T) {} + +mod foo { + pub fn scope() {} +} + +fn main() { + let scope = &mut 0; + assert_static(|| { + foo::scope(); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29540.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29540.rs new file mode 100644 index 000000000000..8bc964d5f7c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29540.rs @@ -0,0 +1,493 @@ +// build-pass +#[derive(Debug)] +pub struct Config { + pub name: String, + pub cluster: String, + pub debug_none: String, + pub debug_lockdep: String, + pub debug_context: String, + pub debug_crush: String, + pub debug_mds: String, + pub debug_mds_balancer: String, + pub debug_mds_locker: String, + pub debug_mds_log: String, + pub debug_mds_log_expire: String, + pub debug_mds_migrator: String, + pub debug_buffer: String, + pub debug_timer: String, + pub debug_filer: String, + pub debug_striper: String, + pub debug_objecter: String, + pub debug_rados: String, + pub debug_rbd: String, + pub debug_journaler: String, + pub debug_objectcacher: String, + pub debug_client: String, + pub debug_osd: String, + pub debug_optracker: String, + pub debug_objclass: String, + pub debug_filestore: String, + pub debug_keyvaluestore: String, + pub debug_journal: String, + pub debug_ms: String, + pub debug_mon: String, + pub debug_monc: String, + pub debug_paxos: String, + pub debug_tp: String, + pub debug_auth: String, + pub debug_crypto: String, + pub debug_finisher: String, + pub debug_heartbeatmap: String, + pub debug_perfcounter: String, + pub debug_rgw: String, + pub debug_civetweb: String, + pub debug_javaclient: String, + pub debug_asok: String, + pub debug_throttle: String, + pub host: String, + pub fsid: String, + pub public_addr: String, + pub cluster_addr: String, + pub public_network: String, + pub cluster_network: String, + pub num_client: String, + pub monmap: String, + pub mon_host: String, + pub lockdep: String, + pub run_dir: String, + pub admin_socket: String, + pub daemonize: String, + pub pid_file: String, + pub chdir: String, + pub max_open_files: String, + pub restapi_log_level: String, + pub restapi_base_url: String, + pub fatal_signal_handlers: String, + pub log_file: String, + pub log_max_new: String, + pub log_max_recent: String, + pub log_to_stderr: String, + pub err_to_stderr: String, + pub log_to_syslog: String, + pub err_to_syslog: String, + pub log_flush_on_exit: String, + pub log_stop_at_utilization: String, + pub clog_to_monitors: String, + pub clog_to_syslog: String, + pub clog_to_syslog_level: String, + pub clog_to_syslog_facility: String, + pub mon_cluster_log_to_syslog: String, + pub mon_cluster_log_to_syslog_level: String, + pub mon_cluster_log_to_syslog_facility: String, + pub mon_cluster_log_file: String, + pub mon_cluster_log_file_level: String, + pub key: String, + pub keyfile: String, + pub keyring: String, + pub heartbeat_interval: String, + pub heartbeat_file: String, + pub heartbeat_inject_failure: String, + pub perf: String, + pub ms_tcp_nodelay: String, + pub ms_tcp_rcvbuf: String, + pub ms_initial_backoff: String, + pub ms_max_backoff: String, + pub ms_nocrc: String, + pub ms_die_on_bad_msg: String, + pub ms_die_on_unhandled_msg: String, + pub ms_die_on_old_message: String, + pub ms_dispatch_throttle_bytes: String, + pub ms_bind_ipv6: String, + pub ms_bind_port_min: String, + pub ms_bind_port_max: String, + pub ms_rwthread_stack_bytes: String, + pub ms_tcp_read_timeout: String, + pub ms_pq_max_tokens_per_priority: String, + pub ms_pq_min_cost: String, + pub ms_inject_socket_failures: String, + pub ms_inject_delay_type: String, + pub ms_inject_delay_msg_type: String, + pub ms_inject_delay_max: String, + pub ms_inject_delay_probability: String, + pub ms_inject_internal_delays: String, + pub ms_dump_on_send: String, + pub inject_early_sigterm: String, + pub mon_data: String, + pub mon_initial_members: String, + pub mon_sync_fs_threshold: String, + pub mon_compact_on_start: String, + pub mon_compact_on_bootstrap: String, + pub mon_compact_on_trim: String, + pub mon_tick_interval: String, + pub mon_subscribe_interval: String, + pub mon_delta_reset_interval: String, + pub mon_osd_laggy_halflife: String, + pub mon_osd_laggy_weight: String, + pub mon_osd_adjust_heartbeat_grace: String, + pub mon_osd_adjust_down_out_interval: String, + pub mon_osd_auto_mark_in: String, + pub mon_osd_auto_mark_auto_out_in: String, + pub mon_osd_auto_mark_new_in: String, + pub mon_osd_down_out_interval: String, + pub mon_osd_down_out_subtree_limit: String, + pub mon_osd_min_up_ratio: String, + pub mon_osd_min_in_ratio: String, + pub mon_osd_max_op_age: String, + pub mon_osd_max_split_count: String, + pub mon_osd_allow_primary_temp: String, + pub mon_osd_allow_primary_affinity: String, + pub mon_stat_smooth_intervals: String, + pub mon_lease: String, + pub mon_lease_renew_interval: String, + pub mon_lease_ack_timeout: String, + pub mon_clock_drift_allowed: String, + pub mon_clock_drift_warn_backoff: String, + pub mon_timecheck_interval: String, + pub mon_accept_timeout: String, + pub mon_pg_create_interval: String, + pub mon_pg_stuck_threshold: String, + pub mon_pg_warn_min_per_osd: String, + pub mon_pg_warn_max_object_skew: String, + pub mon_pg_warn_min_objects: String, + pub mon_pg_warn_min_pool_objects: String, + pub mon_cache_target_full_warn_ratio: String, + pub mon_osd_full_ratio: String, + pub mon_osd_nearfull_ratio: String, + pub mon_globalid_prealloc: String, + pub mon_osd_report_timeout: String, + pub mon_force_standby_active: String, + pub mon_warn_on_old_mons: String, + pub mon_warn_on_legacy_crush_tunables: String, + pub mon_warn_on_osd_down_out_interval_zero: String, + pub mon_warn_on_cache_pools_without_hit_sets: String, + pub mon_min_osdmap_epochs: String, + pub mon_max_pgmap_epochs: String, + pub mon_max_log_epochs: String, + pub mon_max_mdsmap_epochs: String, + pub mon_max_osd: String, + pub mon_probe_timeout: String, + pub mon_slurp_timeout: String, + pub mon_slurp_bytes: String, + pub mon_client_bytes: String, + pub mon_daemon_bytes: String, + pub mon_max_log_entries_per_event: String, + pub mon_health_data_update_interval: String, + pub mon_data_avail_crit: String, + pub mon_data_avail_warn: String, + pub mon_config_key_max_entry_size: String, + pub mon_sync_timeout: String, + pub mon_sync_max_payload_size: String, + pub mon_sync_debug: String, + pub mon_sync_debug_leader: String, + pub mon_sync_debug_provider: String, + pub mon_sync_debug_provider_fallback: String, + pub mon_inject_sync_get_chunk_delay: String, + pub mon_osd_min_down_reporters: String, + pub mon_osd_min_down_reports: String, + pub mon_osd_force_trim_to: String, + pub mon_mds_force_trim_to: String, + pub mon_advanced_debug_mode: String, + pub mon_debug_dump_transactions: String, + pub mon_debug_dump_location: String, + pub mon_sync_provider_kill_at: String, + pub mon_sync_requester_kill_at: String, + pub mon_leveldb_write_buffer_size: String, + pub mon_leveldb_cache_size: String, + pub mon_leveldb_block_size: String, + pub mon_leveldb_bloom_size: String, + pub mon_leveldb_max_open_files: String, + pub mon_leveldb_compression: String, + pub mon_leveldb_paranoid: String, + pub mon_leveldb_log: String, + pub mon_leveldb_size_warn: String, + pub mon_force_quorum_join: String, + pub paxos_stash_full_interval: String, + pub paxos_max_join_drift: String, + pub paxos_propose_interval: String, + pub paxos_min_wait: String, + pub paxos_min: String, + pub paxos_trim_min: String, + pub paxos_trim_max: String, + pub paxos_service_trim_min: String, + pub paxos_service_trim_max: String, + pub paxos_kill_at: String, + pub clock_offset: String, + pub auth_cluster_required: String, + pub auth_service_required: String, + pub auth_client_required: String, + pub auth_supported: String, + pub cephx_require_signatures: String, + pub cephx_cluster_require_signatures: String, + pub cephx_service_require_signatures: String, + pub cephx_sign_messages: String, + pub auth_mon_ticket_ttl: String, + pub auth_service_ticket_ttl: String, + pub auth_debug: String, + pub mon_client_hunt_interval: String, + pub mon_client_ping_interval: String, + pub mon_client_ping_timeout: String, + pub mon_client_hunt_interval_backoff: String, + pub mon_client_hunt_interval_max_multiple: String, + pub mon_client_max_log_entries_per_message: String, + pub mon_max_pool_pg_num: String, + pub mon_pool_quota_warn_threshold: String, + pub mon_pool_quota_crit_threshold: String, + pub client_cache_size: String, + pub client_cache_mid: String, + pub client_use_random_mds: String, + pub client_mount_timeout: String, + pub client_tick_interval: String, + pub client_trace: String, + pub client_readahead_min: String, + pub client_readahead_max_bytes: String, + pub client_readahead_max_periods: String, + pub client_snapdir: String, + pub client_mountpoint: String, + pub client_notify_timeout: String, + pub osd_client_watch_timeout: String, + pub client_caps_release_delay: String, + pub client_oc: String, + pub client_oc_size: String, + pub client_oc_max_dirty: String, + pub client_oc_target_dirty: String, + pub client_oc_max_dirty_age: String, + pub client_oc_max_objects: String, + pub client_debug_force_sync_read: String, + pub client_debug_inject_tick_delay: String, + pub client_max_inline_size: String, + pub fuse_use_invalidate_cb: String, + pub fuse_allow_other: String, + pub fuse_default_permissions: String, + pub fuse_big_writes: String, + pub fuse_atomic_o_trunc: String, + pub fuse_debug: String, + pub fuse_multithreaded: String, + pub crush_location: String, + pub objecter_tick_interval: String, + pub objecter_timeout: String, + pub objecter_inflight_op_bytes: String, + pub objecter_inflight_ops: String, + pub journaler_allow_split_entries: String, + pub journaler_write_head_interval: String, + pub journaler_prefetch_periods: String, + pub journaler_prezero_periods: String, + pub journaler_batch_interval: String, + pub journaler_batch_max: String, + pub mds_data: String, + pub mds_max_file_size: String, + pub mds_cache_size: String, + pub mds_cache_mid: String, + pub mds_mem_max: String, + pub mds_dir_max_commit_size: String, + pub mds_decay_halflife: String, + pub mds_beacon_interval: String, + pub mds_beacon_grace: String, + pub mds_enforce_unique_name: String, + pub mds_interval: String, + pub mds_session_timeout: String, + pub mds_freeze_tree_timeout: String, + pub mds_session_autoclose: String, + pub mds_reconnect_timeout: String, + pub mds_tick_interval: String, + pub mds_dirstat_min_interval: String, + pub mds_scatter_nudge_interval: String, + pub mds_client_prealloc_inos: String, + pub mds_early_reply: String, + pub mds_default_dir_hash: String, + pub mds_log: String, + pub mds_log_skip_corrupt_events: String, + pub mds_log_max_events: String, + pub mds_log_segment_size: String, + pub mds_log_max_segments: String, + pub mds_log_max_expiring: String, + pub mds_bal_sample_interval: String, + pub mds_bal_replicate_threshold: String, + pub mds_bal_unreplicate_threshold: String, + pub mds_bal_frag: String, + pub mds_bal_split_size: String, + pub mds_bal_split_rd: String, + pub mds_bal_split_wr: String, + pub mds_bal_split_bits: String, + pub mds_bal_merge_size: String, + pub mds_bal_merge_rd: String, + pub mds_bal_merge_wr: String, + pub mds_bal_interval: String, + pub mds_bal_fragment_interval: String, + pub mds_bal_idle_threshold: String, + pub mds_bal_max: String, + pub mds_bal_max_until: String, + pub mds_bal_mode: String, + pub mds_bal_min_rebalance: String, + pub mds_bal_min_start: String, + pub mds_bal_need_min: String, + pub mds_bal_need_max: String, + pub mds_bal_midchunk: String, + pub mds_bal_minchunk: String, + pub mds_bal_target_removal_min: String, + pub mds_bal_target_removal_max: String, + pub mds_replay_interval: String, + pub mds_shutdown_check: String, + pub mds_thrash_exports: String, + pub mds_thrash_fragments: String, + pub mds_dump_cache_on_map: String, + pub mds_dump_cache_after_rejoin: String, + pub mds_verify_scatter: String, + pub mds_debug_scatterstat: String, + pub mds_debug_frag: String, + pub mds_debug_auth_pins: String, + pub mds_debug_subtrees: String, + pub mds_kill_mdstable_at: String, + pub mds_kill_export_at: String, + pub mds_kill_import_at: String, + pub mds_kill_link_at: String, + pub mds_kill_rename_at: String, + pub mds_kill_openc_at: String, + pub mds_kill_journal_at: String, + pub mds_kill_journal_expire_at: String, + pub mds_kill_journal_replay_at: String, + pub mds_kill_create_at: String, + pub mds_open_remote_link_mode: String, + pub mds_inject_traceless_reply_probability: String, + pub mds_wipe_sessions: String, + pub mds_wipe_ino_prealloc: String, + pub mds_skip_ino: String, + pub max_mds: String, + pub mds_standby_for_name: String, + pub mds_standby_for_rank: String, + pub mds_standby_replay: String, + pub osd_compact_leveldb_on_mount: String, + pub osd_max_backfills: String, + pub osd_backfill_full_ratio: String, + pub osd_backfill_retry_interval: String, + pub osd_agent_max_ops: String, + pub osd_agent_min_evict_effort: String, + pub osd_agent_quantize_effort: String, + pub osd_agent_delay_time: String, + pub osd_agent_hist_halflife: String, + pub osd_agent_slop: String, + pub osd_uuid: String, + pub osd_data: String, + pub osd_journal: String, + pub osd_journal_size: String, + pub osd_max_write_size: String, + pub osd_max_pgls: String, + pub osd_client_message_size_cap: String, + pub osd_client_message_cap: String, + pub osd_pg_bits: String, + pub osd_pgp_bits: String, + pub osd_crush_chooseleaf_type: String, + pub osd_pool_default_crush_rule: String, + pub osd_pool_default_crush_replicated_ruleset: String, + pub osd_pool_erasure_code_stripe_width: String, + pub osd_pool_default_size: String, + pub osd_pool_default_min_size: String, + pub osd_pool_default_pg_num: String, + pub osd_pool_default_pgp_num: String, + pub osd_pool_default_erasure_code_directory: String, + pub osd_pool_default_erasure_code_profile: String, + pub osd_erasure_code_plugins: String, + pub osd_pool_default_flags: String, + pub osd_pool_default_flag_hashpspool: String, + pub osd_pool_default_hit_set_bloom_fpp: String, + pub osd_pool_default_cache_target_dirty_ratio: String, + pub osd_pool_default_cache_target_full_ratio: String, + pub osd_pool_default_cache_min_flush_age: String, + pub osd_pool_default_cache_min_evict_age: String, + pub osd_hit_set_min_size: String, + pub osd_hit_set_max_size: String, + pub osd_hit_set_namespace: String, + pub osd_tier_default_cache_mode: String, + pub osd_tier_default_cache_hit_set_count: String, + pub osd_tier_default_cache_hit_set_period: String, + pub osd_tier_default_cache_hit_set_type: String, + pub osd_map_dedup: String, + pub osd_map_max_advance: String, + pub osd_map_cache_size: String, + pub osd_map_message_max: String, + pub osd_map_share_max_epochs: String, + pub osd_op_threads: String, + pub osd_peering_wq_batch_size: String, + pub osd_op_pq_max_tokens_per_priority: String, + pub osd_op_pq_min_cost: String, + pub osd_disk_threads: String, + pub osd_disk_thread_ioprio_class: String, + pub osd_disk_thread_ioprio_priority: String, + pub osd_recovery_threads: String, + pub osd_recover_clone_overlap: String, + pub osd_recover_clone_overlap_limit: String, + pub osd_backfill_scan_min: String, + pub osd_backfill_scan_max: String, + pub osd_op_thread_timeout: String, + pub osd_recovery_thread_timeout: String, + pub osd_snap_trim_thread_timeout: String, + pub osd_snap_trim_sleep: String, + pub osd_scrub_thread_timeout: String, + pub osd_scrub_finalize_thread_timeout: String, + pub osd_scrub_invalid_stats: String, + pub osd_remove_thread_timeout: String, + pub osd_command_thread_timeout: String, + pub osd_age: String, + pub osd_age_time: String, + pub osd_heartbeat_addr: String, + pub osd_heartbeat_interval: String, + pub osd_heartbeat_grace: String, + pub osd_heartbeat_min_peers: String, + pub osd_pg_max_concurrent_snap_trims: String, + pub osd_heartbeat_min_healthy_ratio: String, + pub osd_mon_heartbeat_interval: String, + pub osd_mon_report_interval_max: String, + pub osd_mon_report_interval_min: String, + pub osd_pg_stat_report_interval_max: String, + pub osd_mon_ack_timeout: String, + pub osd_default_data_pool_replay_window: String, + pub osd_preserve_trimmed_log: String, + pub osd_auto_mark_unfound_lost: String, + pub osd_recovery_delay_start: String, + pub osd_recovery_max_active: String, + pub osd_recovery_max_single_start: String, + pub osd_recovery_max_chunk: String, + pub osd_copyfrom_max_chunk: String, + pub osd_push_per_object_cost: String, + pub osd_max_push_cost: String, + pub osd_max_push_objects: String, + pub osd_recovery_forget_lost_objects: String, + pub osd_max_scrubs: String, + pub osd_scrub_load_threshold: String, + pub osd_scrub_min_interval: String, + pub osd_scrub_max_interval: String, + pub osd_scrub_chunk_min: String, + pub osd_scrub_chunk_max: String, + pub osd_scrub_sleep: String, + pub osd_deep_scrub_interval: String, + pub osd_deep_scrub_stride: String, + pub osd_scan_list_ping_tp_interval: String, + pub osd_auto_weight: String, + pub osd_class_dir: String, + pub osd_open_classes_on_start: String, + pub osd_check_for_log_corruption: String, + pub osd_use_stale_snap: String, + pub osd_rollback_to_cluster_snap: String, + pub osd_default_notify_timeout: String, + pub osd_kill_backfill_at: String, + pub osd_pg_epoch_persisted_max_stale: String, + pub osd_min_pg_log_entries: String, + pub osd_max_pg_log_entries: String, + pub osd_op_complaint_time: String, + pub osd_command_max_records: String, + pub osd_op_log_threshold: String, + pub osd_verify_sparse_read_holes: String, + pub osd_debug_drop_ping_probability: String, + pub osd_debug_drop_ping_duration: String, + pub osd_debug_drop_pg_create_probability: String, + pub osd_debug_drop_pg_create_duration: String, + pub osd_debug_drop_op_probability: String, + pub osd_debug_op_order: String, + pub osd_debug_verify_snaps_on_info: String, + pub osd_debug_verify_stray_on_activate: String, + pub osd_debug_skip_full_check_in_backfill_reservation: String, + pub osd_debug_reject_backfill_probability: String, + pub osd_enable_op_tracker: String, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29663.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29663.rs new file mode 100644 index 000000000000..34c68180dcff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29663.rs @@ -0,0 +1,57 @@ +// run-pass +#![allow(stable_features)] +// write_volatile causes an LLVM assert with composite types + +#![feature(volatile)] +use std::ptr::{read_volatile, write_volatile}; + +#[derive(Debug, Eq, PartialEq)] +struct A(u32); +#[derive(Debug, Eq, PartialEq)] +struct B(u64); +#[derive(Debug, Eq, PartialEq)] +struct C(u32, u32); +#[derive(Debug, Eq, PartialEq)] +struct D(u64, u64); +#[derive(Debug, Eq, PartialEq)] +struct E([u64; 32]); + +fn main() { + unsafe { + let mut x: u32 = 0; + write_volatile(&mut x, 1); + assert_eq!(read_volatile(&x), 1); + assert_eq!(x, 1); + + let mut x: u64 = 0; + write_volatile(&mut x, 1); + assert_eq!(read_volatile(&x), 1); + assert_eq!(x, 1); + + let mut x = A(0); + write_volatile(&mut x, A(1)); + assert_eq!(read_volatile(&x), A(1)); + assert_eq!(x, A(1)); + + let mut x = B(0); + write_volatile(&mut x, B(1)); + assert_eq!(read_volatile(&x), B(1)); + assert_eq!(x, B(1)); + + let mut x = C(0, 0); + write_volatile(&mut x, C(1, 1)); + assert_eq!(read_volatile(&x), C(1, 1)); + assert_eq!(x, C(1, 1)); + + let mut x = D(0, 0); + write_volatile(&mut x, D(1, 1)); + assert_eq!(read_volatile(&x), D(1, 1)); + assert_eq!(x, D(1, 1)); + + let mut x = E([0; 32]); + write_volatile(&mut x, E([1; 32])); + assert_eq!(read_volatile(&x), E([1; 32])); + assert_eq!(x, E([1; 32])); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29668.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29668.rs new file mode 100644 index 000000000000..758469c814e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29668.rs @@ -0,0 +1,17 @@ +// run-pass +// Functions can return unnameable types + +mod m1 { + mod m2 { + #[derive(Debug)] + pub struct A; + } + use self::m2::A; + pub fn x() -> A { A } +} + +fn main() { + let x = m1::x(); + println!("{:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29710.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29710.rs new file mode 100644 index 000000000000..12a6de402bfb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29710.rs @@ -0,0 +1,12 @@ +// check-pass +#![deny(unused_results)] +#![allow(dead_code)] + +#[derive(Debug)] +struct A(usize); + +#[derive(Debug)] +struct B { a: usize } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29723.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29723.rs new file mode 100644 index 000000000000..90faa85cf366 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29723.rs @@ -0,0 +1,15 @@ +// test for https://github.com/rust-lang/rust/issues/29723 + +fn main() { + let s = String::new(); + let _s = match 0 { + 0 if { drop(s); false } => String::from("oops"), + _ => { + // This should trigger an error, + // s could have been moved from. + s +// { dg-error ".E0382." "" { target *-*-* } .-1 } + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29740.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29740.rs new file mode 100644 index 000000000000..dbab68616514 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29740.rs @@ -0,0 +1,318 @@ +// check-pass +#![allow(dead_code)] +// Regression test for #29740. Inefficient MIR matching algorithms +// generated way too much code for this sort of case, leading to OOM. +#![allow(non_snake_case)] + +pub mod KeyboardEventConstants { + pub const DOM_KEY_LOCATION_STANDARD: u32 = 0; + pub const DOM_KEY_LOCATION_LEFT: u32 = 1; + pub const DOM_KEY_LOCATION_RIGHT: u32 = 2; + pub const DOM_KEY_LOCATION_NUMPAD: u32 = 3; +} // mod KeyboardEventConstants + +pub enum Key { + Space, + Apostrophe, + Comma, + Minus, + Period, + Slash, + Num0, + Num1, + Num2, + Num3, + Num4, + Num5, + Num6, + Num7, + Num8, + Num9, + Semicolon, + Equal, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + LeftBracket, + Backslash, + RightBracket, + GraveAccent, + World1, + World2, + + Escape, + Enter, + Tab, + Backspace, + Insert, + Delete, + Right, + Left, + Down, + Up, + PageUp, + PageDown, + Home, + End, + CapsLock, + ScrollLock, + NumLock, + PrintScreen, + Pause, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + F13, + F14, + F15, + F16, + F17, + F18, + F19, + F20, + F21, + F22, + F23, + F24, + F25, + Kp0, + Kp1, + Kp2, + Kp3, + Kp4, + Kp5, + Kp6, + Kp7, + Kp8, + Kp9, + KpDecimal, + KpDivide, + KpMultiply, + KpSubtract, + KpAdd, + KpEnter, + KpEqual, + LeftShift, + LeftControl, + LeftAlt, + LeftSuper, + RightShift, + RightControl, + RightAlt, + RightSuper, + Menu, +} + +fn key_from_string(key_string: &str, location: u32) -> Option { + match key_string { + " " => Some(Key::Space), + "\"" => Some(Key::Apostrophe), + "'" => Some(Key::Apostrophe), + "<" => Some(Key::Comma), + "," => Some(Key::Comma), + "_" => Some(Key::Minus), + "-" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Minus), + ">" => Some(Key::Period), + "." if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Period), + "?" => Some(Key::Slash), + "/" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Slash), + "~" => Some(Key::GraveAccent), + "`" => Some(Key::GraveAccent), + ")" => Some(Key::Num0), + "0" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num0), + "!" => Some(Key::Num1), + "1" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num1), + "@" => Some(Key::Num2), + "2" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num2), + "#" => Some(Key::Num3), + "3" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num3), + "$" => Some(Key::Num4), + "4" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num4), + "%" => Some(Key::Num5), + "5" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num5), + "^" => Some(Key::Num6), + "6" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num6), + "&" => Some(Key::Num7), + "7" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num7), + "*" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num8), + "8" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num8), + "(" => Some(Key::Num9), + "9" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num9), + ":" => Some(Key::Semicolon), + ";" => Some(Key::Semicolon), + "+" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Equal), + "=" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Equal), + "A" => Some(Key::A), + "a" => Some(Key::A), + "B" => Some(Key::B), + "b" => Some(Key::B), + "C" => Some(Key::C), + "c" => Some(Key::C), + "D" => Some(Key::D), + "d" => Some(Key::D), + "E" => Some(Key::E), + "e" => Some(Key::E), + "F" => Some(Key::F), + "f" => Some(Key::F), + "G" => Some(Key::G), + "g" => Some(Key::G), + "H" => Some(Key::H), + "h" => Some(Key::H), + "I" => Some(Key::I), + "i" => Some(Key::I), + "J" => Some(Key::J), + "j" => Some(Key::J), + "K" => Some(Key::K), + "k" => Some(Key::K), + "L" => Some(Key::L), + "l" => Some(Key::L), + "M" => Some(Key::M), + "m" => Some(Key::M), + "N" => Some(Key::N), + "n" => Some(Key::N), + "O" => Some(Key::O), + "o" => Some(Key::O), + "P" => Some(Key::P), + "p" => Some(Key::P), + "Q" => Some(Key::Q), + "q" => Some(Key::Q), + "R" => Some(Key::R), + "r" => Some(Key::R), + "S" => Some(Key::S), + "s" => Some(Key::S), + "T" => Some(Key::T), + "t" => Some(Key::T), + "U" => Some(Key::U), + "u" => Some(Key::U), + "V" => Some(Key::V), + "v" => Some(Key::V), + "W" => Some(Key::W), + "w" => Some(Key::W), + "X" => Some(Key::X), + "x" => Some(Key::X), + "Y" => Some(Key::Y), + "y" => Some(Key::Y), + "Z" => Some(Key::Z), + "z" => Some(Key::Z), + "{" => Some(Key::LeftBracket), + "[" => Some(Key::LeftBracket), + "|" => Some(Key::Backslash), + "\\" => Some(Key::Backslash), + "}" => Some(Key::RightBracket), + "]" => Some(Key::RightBracket), + "Escape" => Some(Key::Escape), + "Enter" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD + => Some(Key::Enter), + "Tab" => Some(Key::Tab), + "Backspace" => Some(Key::Backspace), + "Insert" => Some(Key::Insert), + "Delete" => Some(Key::Delete), + "ArrowRight" => Some(Key::Right), + "ArrowLeft" => Some(Key::Left), + "ArrowDown" => Some(Key::Down), + "ArrowUp" => Some(Key::Up), + "PageUp" => Some(Key::PageUp), + "PageDown" => Some(Key::PageDown), + "Home" => Some(Key::Home), + "End" => Some(Key::End), + "CapsLock" => Some(Key::CapsLock), + "ScrollLock" => Some(Key::ScrollLock), + "NumLock" => Some(Key::NumLock), + "PrintScreen" => Some(Key::PrintScreen), + "Pause" => Some(Key::Pause), + "F1" => Some(Key::F1), + "F2" => Some(Key::F2), + "F3" => Some(Key::F3), + "F4" => Some(Key::F4), + "F5" => Some(Key::F5), + "F6" => Some(Key::F6), + "F7" => Some(Key::F7), + "F8" => Some(Key::F8), + "F9" => Some(Key::F9), + "F10" => Some(Key::F10), + "F11" => Some(Key::F11), + "F12" => Some(Key::F12), + "F13" => Some(Key::F13), + "F14" => Some(Key::F14), + "F15" => Some(Key::F15), + "F16" => Some(Key::F16), + "F17" => Some(Key::F17), + "F18" => Some(Key::F18), + "F19" => Some(Key::F19), + "F20" => Some(Key::F20), + "F21" => Some(Key::F21), + "F22" => Some(Key::F22), + "F23" => Some(Key::F23), + "F24" => Some(Key::F24), + "F25" => Some(Key::F25), + "0" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp0), + "1" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp1), + "2" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp2), + "3" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp3), + "4" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp4), + "5" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp5), + "6" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp6), + "7" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp7), + "8" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp8), + "9" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp9), + "." if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpDecimal), + "/" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpDivide), + "*" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpMultiply), + "-" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpSubtract), + "+" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpAdd), + "Enter" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD + => Some(Key::KpEnter), + "=" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpEqual), + "Shift" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT + => Some(Key::LeftShift), + "Control" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT + => Some(Key::LeftControl), + "Alt" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT => Some(Key::LeftAlt), + "Super" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT + => Some(Key::LeftSuper), + "Shift" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT + => Some(Key::RightShift), + "Control" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT + => Some(Key::RightControl), + "Alt" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT => Some(Key::RightAlt), + "Super" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT + => Some(Key::RightSuper), + "ContextMenu" => Some(Key::Menu), + _ => None + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29743.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29743.rs new file mode 100644 index 000000000000..aab1a91b608d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29743.rs @@ -0,0 +1,8 @@ +// check-pass + +fn main() { + let mut i = [1, 2, 3]; + i[i[0]] = 0; + i[i[0] - 1] = 0; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29746.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29746.rs new file mode 100644 index 000000000000..627c91a11154 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29746.rs @@ -0,0 +1,37 @@ +// run-pass +// zip!(a1,a2,a3,a4) is equivalent to: +// a1.zip(a2).zip(a3).zip(a4).map(|(((x1,x2),x3),x4)| (x1,x2,x3,x4)) +macro_rules! zip { + // Entry point + ([$a:expr, $b:expr, $($rest:expr),*]) => { + zip!([$($rest),*], $a.zip($b), (x,y), [x,y]) + }; + + // Intermediate steps to build the zipped expression, the match pattern, and + // and the output tuple of the closure, using macro hygiene to repeatedly + // introduce new variables named 'x'. + ([$a:expr, $($rest:expr),*], $zip:expr, $pat:pat, [$($flat:expr),*]) => { + zip!([$($rest),*], $zip.zip($a), ($pat,x), [$($flat),*, x]) + }; + + // Final step + ([], $zip:expr, $pat:pat, [$($flat:expr),+]) => { + $zip.map(|$pat| ($($flat),+)) + }; + + // Comma + ([$a:expr], $zip:expr, $pat:pat, [$($flat:expr),*]) => { + zip!([$a,], $zip, $pat, [$($flat),*]) + }; +} + +fn main() { + let p1 = vec![1i32, 2].into_iter(); + let p2 = vec!["10", "20"].into_iter(); + let p3 = vec![100u16, 200].into_iter(); + let p4 = vec![1000i64, 2000].into_iter(); + + let e = zip!([p1,p2,p3,p4]).collect::>(); + assert_eq!(e[0], (1i32,"10",100u16,1000i64)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29798.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29798.rs new file mode 100644 index 000000000000..f4eb5a115fcc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29798.rs @@ -0,0 +1,12 @@ +// run-fail +// error-pattern:index out of bounds: the len is 5 but the index is 5 +// ignore-emscripten no processes + +const fn test(x: usize) -> i32 { + [42;5][x] +} + +fn main () { + let _ = test(5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29844.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29844.rs new file mode 100644 index 000000000000..a5158a6d10cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29844.rs @@ -0,0 +1,25 @@ +// run-pass +use std::sync::Arc; + +pub struct DescriptorSet<'a> { + pub slots: Vec> +} + +pub trait ResourcesTrait<'r>: Sized { + type DescriptorSet: 'r; +} + +pub struct Resources; + +impl<'a> ResourcesTrait<'a> for Resources { + type DescriptorSet = DescriptorSet<'a>; +} + +pub enum AttachInfo<'a, R: ResourcesTrait<'a>> { + NextDescriptorSet(Arc) +} + +fn main() { + let _x = DescriptorSet {slots: Vec::new()}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29857.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29857.rs new file mode 100644 index 000000000000..e01c5590dfbc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29857.rs @@ -0,0 +1,20 @@ +// check-pass + +use std::marker::PhantomData; + +pub trait Foo

{} + +impl > Foo

for Option {} + +pub struct Qux (PhantomData<*mut T>); + +impl Foo<*mut T> for Option> {} + +pub trait Bar { + type Output: 'static; +} + +impl> Foo<*mut T> for W {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29861.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29861.rs new file mode 100644 index 000000000000..48d51276f4e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29861.rs @@ -0,0 +1,21 @@ +pub trait MakeRef<'a> { + type Ref; +} +impl<'a, T: 'a> MakeRef<'a> for T { + type Ref = &'a T; +} + +pub trait MakeRef2 { + type Ref2; +} +impl<'a, T: 'a> MakeRef2 for T { +// { dg-error ".E0207." "" { target *-*-* } .-1 } + type Ref2 = >::Ref; +} + +fn foo() -> ::Ref2 { &String::from("foo") } + +fn main() { + println!("{}", foo()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2989.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2989.rs new file mode 100644 index 000000000000..3fa84b67e089 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2989.rs @@ -0,0 +1,37 @@ +// run-pass +#![allow(non_camel_case_types)] + +trait methods { + fn to_bytes(&self) -> Vec ; +} + +impl methods for () { + fn to_bytes(&self) -> Vec { + Vec::new() + } +} + +// the position of this function is significant! - if it comes before methods +// then it works, if it comes after it then it doesn't! +fn to_bools(bitv: Storage) -> Vec { + (0..8).map(|i| { + let w = i / 64; + let b = i % 64; + let x = 1 & (bitv.storage[w] >> b); + x == 1 + }).collect() +} + +struct Storage { storage: Vec } + +pub fn main() { + let bools = vec![false, false, true, false, false, true, true, false]; + let bools2 = to_bools(Storage{storage: vec![0b01100100]}); + + for i in 0..8 { + println!("{} => {} vs {}", i, bools[i], bools2[i]); + } + + assert_eq!(bools, bools2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29914-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29914-2.rs new file mode 100644 index 000000000000..3976419a36d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29914-2.rs @@ -0,0 +1,7 @@ +// run-pass +const ARR: [usize; 5] = [5, 4, 3, 2, 1]; + +fn main() { + assert_eq!(3, ARR[ARR[3]]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29914-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29914-3.rs new file mode 100644 index 000000000000..4eee1817fb29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29914-3.rs @@ -0,0 +1,8 @@ +// run-pass +const ARR: [usize; 5] = [5, 4, 3, 2, 1]; +const BLA: usize = ARR[ARR[3]]; + +fn main() { + assert_eq!(3, BLA); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29914.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29914.rs new file mode 100644 index 000000000000..c51d94978c62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29914.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(stable_features)] + +#![feature(const_indexing)] + +const ARR: [usize; 5] = [5, 4, 3, 2, 1]; + +fn main() { + assert_eq!(3, ARR[ARR[3]]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29927-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29927-1.rs new file mode 100644 index 000000000000..6cd07da933b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29927-1.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +const fn f() -> usize { + 5 +} +struct A { + field: usize, +} +fn main() { + let _ = [0; f()]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29927.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29927.rs new file mode 100644 index 000000000000..c4689fd3ad72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29927.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +struct A { + field: usize, +} +const fn f() -> usize { + 5 +} +fn main() { + let _ = [0; f()]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-29948.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-29948.rs new file mode 100644 index 000000000000..890e004628c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-29948.rs @@ -0,0 +1,41 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default + +use std::panic; + +impl<'a> panic::UnwindSafe for Foo<'a> {} +impl<'a> panic::RefUnwindSafe for Foo<'a> {} + +struct Foo<'a>(&'a mut bool); + +impl<'a> Drop for Foo<'a> { + fn drop(&mut self) { + *self.0 = true; + } +} + +fn f(t: T) { + t() +} + +fn main() { + let mut ran_drop = false; + { + let x = Foo(&mut ran_drop); + let x = move || { let _ = x; }; + f(x); + } + assert!(ran_drop); + + let mut ran_drop = false; + { + let x = Foo(&mut ran_drop); + let result = panic::catch_unwind(move || { + let x = move || { let _ = x; panic!() }; + f(x); + }); + assert!(result.is_err()); + } + assert!(ran_drop); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2995.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2995.rs new file mode 100644 index 000000000000..05027368cd14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2995.rs @@ -0,0 +1,6 @@ +fn bad (p: *const isize) { + let _q: &isize = p as &isize; // { dg-error ".E0605." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30007.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30007.rs new file mode 100644 index 000000000000..ba78e4b2976c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30007.rs @@ -0,0 +1,8 @@ +macro_rules! t { + () => ( String ; ); // { dg-error "" "" { target *-*-* } } +} + +fn main() { + let i: Vec; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30018-nopanic.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30018-nopanic.rs new file mode 100644 index 000000000000..14e4a4e5f309 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30018-nopanic.rs @@ -0,0 +1,104 @@ +// run-pass +#![allow(unreachable_code)] +// More thorough regression test for Issues #30018 and #30822. This +// attempts to explore different ways that array element construction +// (for both scratch arrays and non-scratch ones) interacts with +// breaks in the control-flow, in terms of the order of evaluation of +// the destructors (which may change; see RFC Issue 744) and the +// number of times that the destructor evaluates for each value (which +// should never exceed 1; this latter case is what #30822 is about). + +use std::cell::RefCell; + +struct D<'a>(&'a RefCell>, i32); + +impl<'a> Drop for D<'a> { + fn drop(&mut self) { + println!("Dropping D({})", self.1); + (self.0).borrow_mut().push(self.1); + } +} + +fn main() { + println!("Start"); + break_during_elem(); + break_after_whole(); + println!("Finis"); +} + +fn break_during_elem() { + let log = &RefCell::new(Vec::new()); + + // CASE 1: Fixed-size array itself is stored in _r slot. + loop { + let _r = [D(log, 10), + D(log, 11), + { D(log, 12); break; }, + D(log, 13)]; + } + assert_eq!(&log.borrow()[..], &[12, 11, 10]); + log.borrow_mut().clear(); + + // CASE 2: Slice (borrow of array) is stored in _r slot. + // This is the case that is actually being reported in #30018. + loop { + let _r = &[D(log, 20), + D(log, 21), + { D(log, 22); break; }, + D(log, 23)]; + } + assert_eq!(&log.borrow()[..], &[22, 21, 20]); + log.borrow_mut().clear(); + + // CASE 3: (Borrow of) slice-index of array is stored in _r slot. + loop { + let _r = &[D(log, 30), + D(log, 31), + { D(log, 32); break; }, + D(log, 33)][..]; + } + assert_eq!(&log.borrow()[..], &[32, 31, 30]); + log.borrow_mut().clear(); +} + +// The purpose of these functions is to test what happens when we +// panic after an array has been constructed in its entirety. +// +// It is meant to act as proof that we still need to continue +// scheduling the destruction of an array even after we've scheduling +// drop for its elements during construction; the latter is tested by +// `fn break_during_elem()`. +fn break_after_whole() { + let log = &RefCell::new(Vec::new()); + + // CASE 1: Fixed-size array itself is stored in _r slot. + loop { + let _r = [D(log, 10), + D(log, 11), + D(log, 12)]; + break; + } + assert_eq!(&log.borrow()[..], &[10, 11, 12]); + log.borrow_mut().clear(); + + // CASE 2: Slice (borrow of array) is stored in _r slot. + loop { + let _r = &[D(log, 20), + D(log, 21), + D(log, 22)]; + break; + } + assert_eq!(&log.borrow()[..], &[20, 21, 22]); + log.borrow_mut().clear(); + + // CASE 3: (Borrow of) slice-index of array is stored in _r slot. + loop { + let _r = &[D(log, 30), + D(log, 31), + D(log, 32)][..]; + break; + } + assert_eq!(&log.borrow()[..], &[30, 31, 32]); + log.borrow_mut().clear(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30018-panic.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30018-panic.rs new file mode 100644 index 000000000000..d410088a4e91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30018-panic.rs @@ -0,0 +1,26 @@ +// run-pass +// Regression test for Issue #30018. This is very similar to the +// original reported test, except that the panic is wrapped in a +// spawned thread to isolate the expected error result from the +// SIGTRAP injected by the drop-flag consistency checking. + +// ignore-emscripten no threads support + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) {} +} + +fn foo() -> Foo { + panic!(); +} + +fn main() { + use std::thread; + let handle = thread::spawn(|| { + let _ = &[foo()]; + }); + let _ = handle.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30079.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30079.rs new file mode 100644 index 000000000000..bd3ee4d1a59c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30079.rs @@ -0,0 +1,40 @@ +struct SemiPriv; + +mod m1 { + struct Priv; + impl ::SemiPriv { + pub fn f(_: Priv) {} // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + } + + impl Priv { + pub fn f(_: Priv) {} // ok + } +} + +mod m2 { + struct Priv; + impl ::std::ops::Deref for ::SemiPriv { + type Target = Priv; // { dg-error ".E0446." "" { target *-*-* } } + fn deref(&self) -> &Self::Target { unimplemented!() } + } + + impl ::std::ops::Deref for Priv { + type Target = Priv; // ok + fn deref(&self) -> &Self::Target { unimplemented!() } + } +} + +trait SemiPrivTrait { + type Assoc; +} + +mod m3 { + struct Priv; + impl ::SemiPrivTrait for () { + type Assoc = Priv; // { dg-error ".E0446." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3008-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3008-1.rs new file mode 100644 index 000000000000..6f9702aa2d06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3008-1.rs @@ -0,0 +1,13 @@ +enum Foo { + Foo_(Bar) +} + +enum Bar { +// { dg-error ".E0072." "" { target *-*-* } .-1 } + BarNone, + BarSome(Bar) +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3008-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3008-2.rs new file mode 100644 index 000000000000..d81b3bd6d9fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3008-2.rs @@ -0,0 +1,7 @@ +enum Foo { Foo_(Bar) } +struct Bar { x: Bar } +// { dg-error ".E0072." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3008-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3008-3.rs new file mode 100644 index 000000000000..cde59a813b1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3008-3.rs @@ -0,0 +1,11 @@ +use std::marker; + +enum E1 { V1(E2), } +enum E2 { V2(E2, marker::PhantomData), } +// { dg-error ".E0072." "" { target *-*-* } .-1 } + +impl E1 { fn foo(&self) {} } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30081.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30081.rs new file mode 100644 index 000000000000..c23b8f1c62b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30081.rs @@ -0,0 +1,16 @@ +// run-pass +// This used to segfault #30081 + +pub enum Instruction { + Increment(i8), + Loop(Box>), +} + +fn main() { + let instrs: Option<(u8, Box)> = None; + instrs.into_iter() + .map(|(_, instr)| instr) + .map(|instr| match *instr { _other => {} }) + .last(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3012-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3012-2.rs new file mode 100644 index 000000000000..cd883fc1e571 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3012-2.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:issue-3012-1.rs + +// pretty-expanded FIXME #23616 + +extern crate socketlib; + +use socketlib::socket; + +pub fn main() { + let fd: u32 = 1 as u32; + let _sock: Box<_> = Box::new(socket::socket_handle(fd)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30123.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30123.rs new file mode 100644 index 000000000000..1f9c70b5336c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30123.rs @@ -0,0 +1,10 @@ +// aux-build:issue-30123-aux.rs + +extern crate issue_30123_aux; +use issue_30123_aux::*; + +fn main() { + let ug = Graph::::new_undirected(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3021-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3021-b.rs new file mode 100644 index 000000000000..de03d4df6f84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3021-b.rs @@ -0,0 +1,15 @@ +fn siphash(k0 : u64) { + + struct SipHash { + v0: u64, + } + + impl SipHash { + pub fn reset(&mut self) { + self.v0 = k0 ^ 0x736f6d6570736575; // { dg-error ".E0434." "" { target *-*-* } } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3021-c.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3021-c.rs new file mode 100644 index 000000000000..0d45f04f02e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3021-c.rs @@ -0,0 +1,10 @@ +fn siphash() { + + trait U { + fn g(&self, x: T) -> T; // { dg-error ".E0401." "" { target *-*-* } } +// { dg-error ".E0401." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3021-d.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3021-d.rs new file mode 100644 index 000000000000..5a938513ab95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3021-d.rs @@ -0,0 +1,29 @@ +trait SipHash { + fn result(&self) -> u64; + fn reset(&self); +} + +fn siphash(k0 : u64, k1 : u64) { + struct SipState { + v0: u64, + v1: u64, + } + + fn mk_result(st : &SipState) -> u64 { + + let v0 = st.v0; + let v1 = st.v1; + return v0 ^ v1; + } + + impl SipHash for SipState { + fn reset(&self) { + self.v0 = k0 ^ 0x736f6d6570736575; // { dg-error ".E0434." "" { target *-*-* } } + self.v1 = k1 ^ 0x646f72616e646f6d; // { dg-error ".E0434." "" { target *-*-* } } + } + fn result(&self) -> u64 { return mk_result(self); } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3021.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3021.rs new file mode 100644 index 000000000000..46092c229f2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3021.rs @@ -0,0 +1,19 @@ +trait SipHash { + fn reset(&self); +} + +fn siphash(k0 : u64) { + struct SipState { + v0: u64, + } + + impl SipHash for SipState { + fn reset(&self) { + self.v0 = k0 ^ 0x736f6d6570736575; // { dg-error ".E0434." "" { target *-*-* } } + } + } + panic!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30225.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30225.rs new file mode 100644 index 000000000000..51435e16b59b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30225.rs @@ -0,0 +1,39 @@ +// Regression test for #30225, which was an ICE that would trigger as +// a result of a poor interaction between trait result caching and +// type inference. Specifically, at that time, unification could cause +// unrelated type variables to become instantiated, if subtyping +// relationships existed. These relationships are now propagated +// through obligations and hence everything works out fine. + +trait Foo : Sized { + fn foo(self, u: Option, v: Option) {} +} + +struct A; +struct B; + +impl Foo for () {} // impl A +impl Foo for u32 {} // impl B, creating ambiguity + +fn toxic() { + // cache the resolution <() as Foo<$0,$1>> = impl A + let u = None; + let v = None; + Foo::foo((), u, v); +} + +fn bomb() { + let mut u = None; // type is Option<$0> + let mut v = None; // type is Option<$1> + let mut x = None; // type is Option<$2> + + Foo::foo(x.unwrap(),u,v); // register <$2 as Foo<$0, $1>> + u = v; // mark $0 and $1 in a subtype relationship +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x = Some(()); // set $2 = (), allowing impl selection + // to proceed for <() as Foo<$0, $1>> = impl A. + // kaboom, this *used* to trigge an ICE +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30236.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30236.rs new file mode 100644 index 000000000000..cb8a358fbc28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30236.rs @@ -0,0 +1,8 @@ +type Foo< + Unused // { dg-error ".E0091." "" { target *-*-* } } + > = u8; + +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30240-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30240-b.rs new file mode 100644 index 000000000000..17947c731338 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30240-b.rs @@ -0,0 +1,16 @@ +#![deny(unreachable_patterns)] + +fn main() { + match "world" { + "hello" => {} + _ => {}, + } + + match "world" { + ref _x if false => {} + "hello" => {} + "hello" => {} // { dg-error "" "" { target *-*-* } } + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30240-rpass.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30240-rpass.rs new file mode 100644 index 000000000000..99af5aacca05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30240-rpass.rs @@ -0,0 +1,15 @@ +// run-pass +fn main() { + let &ref a = &[0i32] as &[_]; + assert_eq!(a, &[0i32] as &[_]); + + let &ref a = "hello"; + assert_eq!(a, "hello"); + + match "foo" { + "fool" => unreachable!(), + "foo" => {}, + ref _x => unreachable!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30240.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30240.rs new file mode 100644 index 000000000000..950384bad0df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30240.rs @@ -0,0 +1,11 @@ +fn main() { + match "world" { // { dg-error ".E0004." "" { target *-*-* } } + "hello" => {} + } + + match "world" { // { dg-error ".E0004." "" { target *-*-* } } + ref _x if false => {} + "hello" => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30255.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30255.rs new file mode 100644 index 000000000000..272cc076ad07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30255.rs @@ -0,0 +1,25 @@ +// +// Test that lifetime elision error messages correctly omit parameters +// with no elided lifetimes + +struct S<'a> { + field: &'a i32, +} + +fn f(a: &S, b: i32) -> &i32 { +// { dg-error ".E0106." "" { target *-*-* } .-1 } + panic!(); +} + +fn g(a: &S, b: bool, c: &i32) -> &i32 { +// { dg-error ".E0106." "" { target *-*-* } .-1 } + panic!(); +} + +fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { +// { dg-error ".E0106." "" { target *-*-* } .-1 } + panic!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3026.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3026.rs new file mode 100644 index 000000000000..f26e34b00407 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3026.rs @@ -0,0 +1,14 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +use std::collections::HashMap; + +pub fn main() { + let x: Box<_>; + let mut buggy_map: HashMap = HashMap::new(); + x = box 1; + buggy_map.insert(42, &*x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3029.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3029.rs new file mode 100644 index 000000000000..57e75973bfed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3029.rs @@ -0,0 +1,15 @@ +// run-fail +// error-pattern:so long +// ignore-emscripten no processes + +#![allow(unused_allocation)] +#![allow(unreachable_code)] +#![allow(unused_variables)] + +fn main() { + let mut x = Vec::new(); + let y = vec![3]; + panic!("so long"); + x.extend(y.into_iter()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30302.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30302.rs new file mode 100644 index 000000000000..5856658db0cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30302.rs @@ -0,0 +1,21 @@ +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(non_snake_case)] +#![deny(unreachable_patterns)] + +enum Stack { + Nil, + Cons(T, Box>) +} + +fn is_empty(s: Stack) -> bool { + match s { + Nil => true, +// { dg-warning "" "" { target *-*-* } .-1 } + _ => false +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30355.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30355.rs new file mode 100644 index 000000000000..2bc9b1068a56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30355.rs @@ -0,0 +1,10 @@ +pub struct X([u8]); + +pub static Y: &'static X = { + const Y: &'static [u8] = b""; + &X(*Y) +// { dg-error ".E0277." "" { target *-*-* } .-1 } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3037.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3037.rs new file mode 100644 index 000000000000..52c4d74cb423 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3037.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 +#![allow(non_camel_case_types)] + +enum what { } + +fn what_to_string(x: what) -> String +{ + match x { + } +} + +pub fn main() +{ +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30371.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30371.rs new file mode 100644 index 000000000000..093d4b8c1192 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30371.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unreachable_code)] +#![allow(unused_mut)] // rust-lang/rust#54586 +#![deny(unused_variables)] + +fn main() { + for _ in match return () { + () => Some(0), + } {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3038.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3038.rs new file mode 100644 index 000000000000..24efbd9b7b88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3038.rs @@ -0,0 +1,27 @@ +enum F { G(isize, isize) } + +enum H { I(J, K) } + +enum J { L(isize, isize) } +enum K { M(isize, isize) } + +fn main() +{ + + let _z = match F::G(1, 2) { + F::G(x, x) => { println!("{}", x + x); } +// { dg-error ".E0416." "" { target *-*-* } .-1 } + }; + + let _z = match H::I(J::L(1, 2), K::M(3, 4)) { + H::I(J::L(x, _), K::M(_, x)) +// { dg-error ".E0416." "" { target *-*-* } .-1 } + => { println!("{}", x + x); } + }; + + let _z = match (1, 2) { + (x, x) => { x } // { dg-error ".E0416." "" { target *-*-* } } + }; + +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30380.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30380.rs new file mode 100644 index 000000000000..0990be2b9a9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30380.rs @@ -0,0 +1,37 @@ +// check that panics in destructors during assignment do not leave +// destroyed values lying around for other destructors to observe. + +// run-fail +// error-pattern:panicking destructors ftw! +// ignore-emscripten no processes + +struct Observer<'a>(&'a mut FilledOnDrop); + +struct FilledOnDrop(u32); +impl Drop for FilledOnDrop { + fn drop(&mut self) { + if self.0 == 0 { + // this is only set during the destructor - safe + // code should not be able to observe this. + self.0 = 0x1c1c1c1c; + panic!("panicking destructors ftw!"); + } + } +} + +impl<'a> Drop for Observer<'a> { + fn drop(&mut self) { + assert_eq!(self.0 .0, 1); + } +} + +fn foo(b: &mut Observer) { + *b.0 = FilledOnDrop(1); +} + +fn main() { + let mut bomb = FilledOnDrop(0); + let mut observer = Observer(&mut bomb); + foo(&mut observer); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30438-a.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30438-a.rs new file mode 100644 index 000000000000..64ea00201c6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30438-a.rs @@ -0,0 +1,24 @@ +// Original regression test for Issue #30438. + +use std::ops::Index; + +struct Test<'a> { + s: &'a String +} + +impl <'a> Index for Test<'a> { + type Output = Test<'a>; + fn index(&self, _: usize) -> &Self::Output { + return &Test { s: &self.s}; +// { dg-error ".E0515." "" { target *-*-* } .-1 } + } +} + +fn main() { + let s = "Hello World".to_string(); + let test = Test{s: &s}; + let r = &test[0]; + println!("{}", test.s); // OK since test is valid + println!("{}", r.s); // Segfault since value pointed by r has already been dropped +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30438-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30438-b.rs new file mode 100644 index 000000000000..09359c442990 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30438-b.rs @@ -0,0 +1,25 @@ +// Modified regression test for Issue #30438 that exposed an +// independent issue (see discussion on ticket). + +use std::ops::Index; + +struct Test<'a> { + s: &'a String +} + +impl <'a> Index for Test<'a> { + type Output = Test<'a>; + fn index(&self, _: usize) -> &Self::Output { + &Test { s: &self.s} +// { dg-error ".E0515." "" { target *-*-* } .-1 } + } +} + +fn main() { + let s = "Hello World".to_string(); + let test = Test{s: &s}; + let r = &test[0]; + println!("{}", test.s); // OK since test is valid + println!("{}", r.s); // Segfault since value pointed by r has already been dropped +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30438-c.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30438-c.rs new file mode 100644 index 000000000000..3d64eb7cb6e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30438-c.rs @@ -0,0 +1,21 @@ +// Simplified regression test for #30438, inspired by arielb1. + +trait Trait { type Out; } + +struct Test<'a> { s: &'a str } + +fn silly<'y, 'z>(_s: &'y Test<'z>) -> &'y as Trait>::Out where 'z: 'static { + let x = Test { s: "this cannot last" }; + &x +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +impl<'b> Trait for Test<'b> { type Out = Test<'b>; } + +fn main() { + let orig = Test { s: "Hello World" }; + let r = silly(&orig); + println!("{}", orig.s); // OK since `orig` is valid + println!("{}", r.s); // Segfault (method does not return a sane value) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3044.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3044.rs new file mode 100644 index 000000000000..0c8b46fd0259 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3044.rs @@ -0,0 +1,7 @@ +fn main() { + let needlesArr: Vec = vec!['a', 'f']; + needlesArr.iter().fold(|x, y| { + }); +// { dg-error ".E0061." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30490.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30490.rs new file mode 100644 index 000000000000..e1b0ad72a082 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30490.rs @@ -0,0 +1,103 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +// Previously libstd would set stdio descriptors of a child process +// by `dup`ing the requested descriptors to inherit directly into the +// stdio descriptors. This, however, would incorrectly handle cases +// where the descriptors to inherit were already stdio descriptors. +// This test checks to avoid that regression. + +#![cfg_attr(unix, feature(rustc_private))] +#![cfg_attr(windows, allow(unused_imports))] + +#[cfg(unix)] +extern crate libc; + +use std::fs::File; +use std::io::{Read, Write}; +use std::io::{stdout, stderr}; +use std::process::{Command, Stdio}; + +#[cfg(unix)] +use std::os::unix::io::FromRawFd; + +#[cfg(not(unix))] +fn main() { + // Bug not present in Windows +} + +#[cfg(unix)] +fn main() { + let mut args = std::env::args(); + let name = args.next().unwrap(); + let args: Vec = args.collect(); + if let Some("--child") = args.get(0).map(|s| &**s) { + return child(); + } else if !args.is_empty() { + panic!("unknown options"); + } + + let stdout_backup = unsafe { libc::dup(libc::STDOUT_FILENO) }; + let stderr_backup = unsafe { libc::dup(libc::STDERR_FILENO) }; + assert!(stdout_backup > -1); + assert!(stderr_backup > -1); + + let (stdout_reader, stdout_writer) = pipe(); + let (stderr_reader, stderr_writer) = pipe(); + assert!(unsafe { libc::dup2(stdout_writer, libc::STDOUT_FILENO) } > -1); + assert!(unsafe { libc::dup2(stderr_writer, libc::STDERR_FILENO) } > -1); + + // Make sure we close any duplicates of the writer end of the pipe, + // otherwise we can get stuck reading from the pipe which has open + // writers but no one supplying any input + assert_eq!(unsafe { libc::close(stdout_writer) }, 0); + assert_eq!(unsafe { libc::close(stderr_writer) }, 0); + + stdout().write_all("parent stdout\n".as_bytes()).expect("failed to write to stdout"); + stderr().write_all("parent stderr\n".as_bytes()).expect("failed to write to stderr"); + + let child = { + Command::new(name) + .arg("--child") + .stdin(Stdio::inherit()) + .stdout(unsafe { Stdio::from_raw_fd(libc::STDERR_FILENO) }) + .stderr(unsafe { Stdio::from_raw_fd(libc::STDOUT_FILENO) }) + .spawn() + }; + + // The Stdio passed into the Command took over (and closed) std{out, err} + // so we should restore them as they were. + assert!(unsafe { libc::dup2(stdout_backup, libc::STDOUT_FILENO) } > -1); + assert!(unsafe { libc::dup2(stderr_backup, libc::STDERR_FILENO) } > -1); + + // Using File as a shim around the descriptor + let mut read = String::new(); + let mut f: File = unsafe { FromRawFd::from_raw_fd(stdout_reader) }; + f.read_to_string(&mut read).expect("failed to read from stdout file"); + assert_eq!(read, "parent stdout\nchild stderr\n"); + + // Using File as a shim around the descriptor + read.clear(); + let mut f: File = unsafe { FromRawFd::from_raw_fd(stderr_reader) }; + f.read_to_string(&mut read).expect("failed to read from stderr file"); + assert_eq!(read, "parent stderr\nchild stdout\n"); + + assert!(child.expect("failed to execute child process").wait().unwrap().success()); +} + +#[cfg(unix)] +fn child() { + stdout().write_all("child stdout\n".as_bytes()).expect("child failed to write to stdout"); + stderr().write_all("child stderr\n".as_bytes()).expect("child failed to write to stderr"); +} + +#[cfg(unix)] +/// Returns a pipe (reader, writer combo) +fn pipe() -> (i32, i32) { + let mut fds = [0; 2]; + assert_eq!(unsafe { libc::pipe(fds.as_mut_ptr()) }, 0); + (fds[0], fds[1]) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3052.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3052.rs new file mode 100644 index 000000000000..7b5861518410 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3052.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +type Connection = Box) + 'static>; + +fn f() -> Option { + let mock_connection: Connection = Box::new(|_| {}); + Some(mock_connection) +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30530.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30530.rs new file mode 100644 index 000000000000..36fec04a8003 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30530.rs @@ -0,0 +1,29 @@ +// run-pass +// Regression test for Issue #30530: alloca's created for storing +// intermediate scratch values during brace-less match arms need to be +// initialized with their drop-flag set to "dropped" (or else we end +// up running the destructors on garbage data at the end of the +// function). + +pub enum Handler { + Default, + #[allow(dead_code)] + Custom(*mut Box), +} + +fn main() { + #[allow(unused_must_use)] { + take(Handler::Default, Box::new(main)); + } +} + +#[inline(never)] +pub fn take(h: Handler, f: Box) -> Box { + unsafe { + match h { + Handler::Custom(ptr) => *Box::from_raw(ptr), + Handler::Default => f, + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30535.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30535.rs new file mode 100644 index 000000000000..ece86ea8fb7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30535.rs @@ -0,0 +1,10 @@ +// aux-build:issue-30535.rs + +extern crate issue_30535 as foo; + +fn bar( + _: foo::Foo::FooV // { dg-error ".E0573." "" { target *-*-* } } +) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30560.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30560.rs new file mode 100644 index 000000000000..15d72e9e7c48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30560.rs @@ -0,0 +1,10 @@ +type Alias = (); +use Alias::*; // { dg-error ".E0432." "" { target *-*-* } } + +use std::io::Result::*; // { dg-error ".E0432." "" { target *-*-* } } + +trait T {} +use T::*; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30589.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30589.rs new file mode 100644 index 000000000000..a5017c2cb947 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30589.rs @@ -0,0 +1,10 @@ +use std::fmt; + +impl fmt::Display for DecoderError { // { dg-error ".E0412." "" { target *-*-* } } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Missing data: {}", self.0) + } +} +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30615.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30615.rs new file mode 100644 index 000000000000..e8a8991ab3d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30615.rs @@ -0,0 +1,6 @@ +// run-pass +fn main() { + &0u8 as *const u8 as *const dyn PartialEq; + &[0u8] as *const [u8; 1] as *const [u8]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30730.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30730.rs new file mode 100644 index 000000000000..287dcbe81785 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30730.rs @@ -0,0 +1,6 @@ +#![warn(unused)] +#![deny(warnings)] +use std::thread; +// { dg-error "" "" { target *-*-* } .-1 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30756.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30756.rs new file mode 100644 index 000000000000..b1c81d6af0ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30756.rs @@ -0,0 +1,8 @@ +// run-pass +#![forbid(unsafe_code)] + +thread_local!(static FOO: u8 = 1); + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3080.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3080.rs new file mode 100644 index 000000000000..dec5cc9becaa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3080.rs @@ -0,0 +1,9 @@ +struct X(()); +impl X { + pub unsafe fn with(&self) { } +} + +fn main() { + X(()).with(); // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-30891.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-30891.rs new file mode 100644 index 000000000000..e27f8e2ceed7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-30891.rs @@ -0,0 +1,11 @@ +// run-pass +const ERROR_CONST: bool = true; + +fn get() -> bool { + false || ERROR_CONST +} + +pub fn main() { + assert_eq!(get(), true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3091.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3091.rs new file mode 100644 index 000000000000..0e3540d77661 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3091.rs @@ -0,0 +1,8 @@ +// run-pass + +pub fn main() { + let x = 1; + let y = 1; + assert_eq!(&x, &y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3096-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3096-1.rs new file mode 100644 index 000000000000..429a246c747d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3096-1.rs @@ -0,0 +1,4 @@ +fn main() { + match () { } // { dg-error ".E0004." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3096-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3096-2.rs new file mode 100644 index 000000000000..8399aa50232c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3096-2.rs @@ -0,0 +1,7 @@ +enum Bottom { } + +fn main() { + let x = &() as *const () as *const Bottom; + match x { } // { dg-error ".E0004." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3099-a.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3099-a.rs new file mode 100644 index 000000000000..c7e2d596e607 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3099-a.rs @@ -0,0 +1,6 @@ +enum A { B, C } + +enum A { D, E } // { dg-error ".E0428." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3099-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3099-b.rs new file mode 100644 index 000000000000..ebfb1bc1a73d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3099-b.rs @@ -0,0 +1,6 @@ +pub mod a {} + +pub mod a {} // { dg-error ".E0428." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3099.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3099.rs new file mode 100644 index 000000000000..523bc750b85a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3099.rs @@ -0,0 +1,12 @@ +fn a(x: String) -> String { + format!("First function with {}", x) +} + +fn a(x: String, y: String) -> String { // { dg-error ".E0428." "" { target *-*-* } } + format!("Second function with {} and {}", x, y) +} + +fn main() { + println!("Result: "); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31011.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31011.rs new file mode 100644 index 000000000000..dc82ab0d4f42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31011.rs @@ -0,0 +1,30 @@ +macro_rules! log { + ( $ctx:expr, $( $args:expr),* ) => { + if $ctx.trace { +// { dg-error ".E0609." "" { target *-*-* } .-1 } + println!( $( $args, )* ); + } + } +} + +// Create a structure. +struct Foo { + trace: bool, +} + +// Generic wrapper calls log! with a structure. +fn wrap(context: &T) -> () +{ + log!(context, "entered wrapper"); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + // Create a structure. + let x = Foo { trace: true }; + log!(x, "run started"); + // Apply a closure which accesses internal fields. + wrap(&x); + log!(x, "run finished"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31076.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31076.rs new file mode 100644 index 000000000000..c5d21c3cec7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31076.rs @@ -0,0 +1,18 @@ +#![feature(no_core, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized {} + +#[lang="add"] +trait Add {} + +impl Add for i32 {} + +fn main() { + let x = 5 + 6; +// { dg-error ".E0369." "" { target *-*-* } .-1 } + let y = 5i32 + 6i32; +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3109.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3109.rs new file mode 100644 index 000000000000..553c94d85521 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3109.rs @@ -0,0 +1,5 @@ +// run-pass +pub fn main() { + println!("{:?}", ("hi there!", "you")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31109.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31109.rs new file mode 100644 index 000000000000..6d6d4a3cb7c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31109.rs @@ -0,0 +1,7 @@ +fn main() { + // FIXME(#31407) this error should go away, but in the meantime we test that it + // is accompanied by a somewhat useful error message. + let _: f64 = 1234567890123456789012345678901234567890e-340; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31173.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31173.rs new file mode 100644 index 000000000000..5415c6343276 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31173.rs @@ -0,0 +1,18 @@ +use std::vec::IntoIter; + +pub fn get_tok(it: &mut IntoIter) { + let mut found_e = false; + + let temp: Vec = it.take_while(|&x| { + found_e = true; + false + }) + .cloned() +// { dg-error ".E0271." "" { target *-*-* } .-1 } +// { dg-error ".E0271." "" { target *-*-* } .-2 } +// { dg-error ".E0271." "" { target *-*-* } .-3 } + .collect(); // { dg-error ".E0599." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3121.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3121.rs new file mode 100644 index 000000000000..1384f620874d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3121.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +#![feature(box_syntax)] + +#[derive(Copy, Clone)] +enum side { mayo, catsup, vinegar } +#[derive(Copy, Clone)] +enum order { hamburger, fries(side), shake } +#[derive(Copy, Clone)] +enum meal { to_go(order), for_here(order) } + +fn foo(m: Box, cond: bool) { + match *m { + meal::to_go(_) => { } + meal::for_here(_) if cond => {} + meal::for_here(order::hamburger) => {} + meal::for_here(order::fries(_s)) => {} + meal::for_here(order::shake) => {} + } +} + +pub fn main() { + foo(box meal::for_here(order::hamburger), true) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31212.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31212.rs new file mode 100644 index 000000000000..e8ade33e6d74 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31212.rs @@ -0,0 +1,11 @@ +// This checks that a path that cannot be resolved because of an indeterminate import +// does not trigger an ICE. + +mod foo { + pub use self::*; // { dg-error ".E0432." "" { target *-*-* } } +} + +fn main() { + foo::f(); // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31221.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31221.rs new file mode 100644 index 000000000000..5a7a04629f96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31221.rs @@ -0,0 +1,35 @@ +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(non_snake_case)] +#![deny(unreachable_patterns)] + +#[derive(Clone, Copy)] +enum Enum { + Var1, + Var2, +} + +fn main() { + use Enum::*; + let s = Var1; + match s { + Var1 => (), + Var3 => (), + Var2 => (), +// { dg-error "" "" { target *-*-* } .-1 } + }; + match &s { + &Var1 => (), + &Var3 => (), + &Var2 => (), +// { dg-error "" "" { target *-*-* } .-1 } + }; + let t = (Var1, Var1); + match t { + (Var1, b) => (), + (c, d) => (), + anything => () +// { dg-error "" "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31260.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31260.rs new file mode 100644 index 000000000000..2aa7152e1ece --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31260.rs @@ -0,0 +1,16 @@ +// check-pass +#![allow(dead_code)] +pub struct Struct { + pub field: K, +} + +static STRUCT: Struct<&'static [u8]> = Struct { + field: {&[1]} +}; + +static STRUCT2: Struct<&'static [u8]> = Struct { + field: &[1] +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31267-additional.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31267-additional.rs new file mode 100644 index 000000000000..4221f2df017c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31267-additional.rs @@ -0,0 +1,21 @@ +// run-pass + +#[derive(Clone, Copy, Debug)] +struct Bar; + +const BAZ: Bar = Bar; + +#[derive(Debug)] +struct Foo([Bar; 1]); + +struct Biz; + +impl Biz { + const BAZ: Foo = Foo([BAZ; 1]); +} + +fn main() { + let foo = Biz::BAZ; + println!("{:?}", foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31267.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31267.rs new file mode 100644 index 000000000000..2cfa3324cab2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31267.rs @@ -0,0 +1,15 @@ +// run-pass +// Regression test for issue #31267 + + +struct Foo; + +impl Foo { + const FOO: [i32; 3] = [0; 3]; +} + +pub fn main() { + let foo = Foo::FOO; + assert_eq!(foo, [0i32, 0, 0]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31299.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31299.rs new file mode 100644 index 000000000000..3daa2d371548 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31299.rs @@ -0,0 +1,35 @@ +// run-pass +// Regression test for #31299. This was generating an overflow error +// because of eager normalization: +// +// proving `M: Sized` requires +// - proving `PtrBack>: Sized` requires +// - normalizing `Vec< as Front>::Back>>: Sized` requires +// - proving `Vec: Front` requires +// - `M: Sized` <-- cycle! +// +// If we skip the normalization step, though, everything goes fine. +// +// This could be fixed by implementing lazy normalization everywhere. +// +// However, we want this to work before then. For that, when checking +// whether a type is Sized we only check that the tails are Sized. As +// PtrBack does not have a tail, we don't need to normalize anything +// and this compiles + +trait Front { + type Back; +} + +impl Front for Vec { + type Back = Vec; +} + +struct PtrBack(Vec); + +struct M(PtrBack>); + +fn main() { + std::mem::size_of::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3136-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3136-b.rs new file mode 100644 index 000000000000..6ddbd69e92da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3136-b.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:issue-3136-a.rc + +// pretty-expanded FIXME #23616 + +extern crate issue_3136_a; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3149.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3149.rs new file mode 100644 index 000000000000..3336f276097e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3149.rs @@ -0,0 +1,27 @@ +// check-pass +#![allow(dead_code)] +#![allow(non_snake_case)] +// pretty-expanded FIXME #23616 + +fn Matrix4(m11: T, m12: T, m13: T, m14: T, + m21: T, m22: T, m23: T, m24: T, + m31: T, m32: T, m33: T, m34: T, + m41: T, m42: T, m43: T, m44: T) + -> Matrix4 { + Matrix4 { + m11: m11, m12: m12, m13: m13, m14: m14, + m21: m21, m22: m22, m23: m23, m24: m24, + m31: m31, m32: m32, m33: m33, m34: m34, + m41: m41, m42: m42, m43: m43, m44: m44 + } +} + +struct Matrix4 { + m11: T, m12: T, m13: T, m14: T, + m21: T, m22: T, m23: T, m24: T, + m31: T, m32: T, m33: T, m34: T, + m41: T, m42: T, m43: T, m44: T, +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31511.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31511.rs new file mode 100644 index 000000000000..f67452cd4bf5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31511.rs @@ -0,0 +1,7 @@ +fn cast_thin_to_fat(x: *const ()) { + x as *const [u8]; +// { dg-error ".E0607." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3154.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3154.rs new file mode 100644 index 000000000000..84eb421dedb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3154.rs @@ -0,0 +1,12 @@ +struct Thing<'a, Q:'a> { + x: &'a Q +} + +fn thing<'a,Q>(x: &Q) -> Thing<'a,Q> { + Thing { x: x } // { dg-error ".E0621." "" { target *-*-* } } +} + +fn main() { + thing(&()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31561.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31561.rs new file mode 100644 index 000000000000..7f913a5eee52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31561.rs @@ -0,0 +1,11 @@ +enum Thing { + Foo(u8), + Bar, + Baz +} + +fn main() { + let Thing::Foo(y) = Thing::Foo(1); +// { dg-error ".E0005." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31597.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31597.rs new file mode 100644 index 000000000000..45e66e2107a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31597.rs @@ -0,0 +1,30 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-31702.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31702.rs new file mode 100644 index 000000000000..024297622585 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31702.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:issue-31702-1.rs +// aux-build:issue-31702-2.rs + +// this test is actually entirely in the linked library crates + +extern crate issue_31702_1; +extern crate issue_31702_2; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31769.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31769.rs new file mode 100644 index 000000000000..7a68c68ef4e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31769.rs @@ -0,0 +1,5 @@ +fn main() { + #[inline] struct Foo; // { dg-error ".E0518." "" { target *-*-* } } + #[repr(C)] fn foo() {} // { dg-error ".E0517." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31776.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31776.rs new file mode 100644 index 000000000000..559719a44a12 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31776.rs @@ -0,0 +1,56 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Various scenarios in which `pub` is required in blocks + +struct S; + +mod m { + fn f() { + impl ::S { + pub fn s(&self) {} + } + } +} + +// Scenario 1 + +pub trait Tr { + type A; +} +pub struct S1; + +fn f() { + pub struct Z; + + impl ::Tr for ::S1 { + type A = Z; // Private-in-public error unless `struct Z` is pub + } +} + +// Scenario 2 + +trait Tr1 { + type A; + fn pull(&self) -> Self::A; +} +struct S2; + +mod m1 { + fn f() { + pub struct Z { + pub field: u8 + } + + impl ::Tr1 for ::S2 { + type A = Z; + fn pull(&self) -> Self::A { Z{field: 10} } + } + } +} + +fn main() { + S.s(); // Privacy error, unless `fn s` is pub + let a = S2.pull().field; // Privacy error unless `field: u8` is pub +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31804.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31804.rs new file mode 100644 index 000000000000..0b7cbd552dc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31804.rs @@ -0,0 +1,7 @@ +// Test that error recovery in the parser to an EOF does not give an infinite +// spew of errors. + +fn main() { + let +} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31845.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31845.rs new file mode 100644 index 000000000000..136e9a4a904b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31845.rs @@ -0,0 +1,13 @@ +// Checks lexical scopes cannot see through normal module boundaries + +fn f() { + fn g() {} + mod foo { + fn h() { + g(); // { dg-error ".E0425." "" { target *-*-* } } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31910.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31910.rs new file mode 100644 index 000000000000..6fdf321d88d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31910.rs @@ -0,0 +1,12 @@ +enum Enum { + X = Trait::Number, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +trait Trait { + const Number: i32 = 1; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-31924-non-snake-ffi.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-31924-non-snake-ffi.rs new file mode 100644 index 000000000000..27bc8185bed8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-31924-non-snake-ffi.rs @@ -0,0 +1,9 @@ +// check-pass + +#![deny(non_snake_case)] + +#[no_mangle] +pub extern "C" fn SparklingGenerationForeignFunctionInterface() {} // OK + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32004.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32004.rs new file mode 100644 index 000000000000..e230002c92fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32004.rs @@ -0,0 +1,20 @@ +enum Foo { + Bar(i32), + Baz +} + +struct S; + +fn main() { + match Foo::Baz { + Foo::Bar => {} +// { dg-error ".E0532." "" { target *-*-* } .-1 } + _ => {} + } + + match S { + S(()) => {} +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32008.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32008.rs new file mode 100644 index 000000000000..5525474c08f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32008.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Tests that binary operators allow subtyping on both the LHS and RHS, +// and as such do not introduce unnecessarily strict lifetime constraints. + +use std::ops::Add; + +struct Foo; + +impl<'a> Add<&'a Foo> for &'a Foo { + type Output = (); + fn add(self, rhs: &'a Foo) {} +} + +fn try_to_add(input: &Foo) { + let local = Foo; + + // Manual reborrow worked even with invariant trait search. + &*input + &local; + + // Direct use of the reference on the LHS requires additional + // subtyping before searching (invariantly) for `LHS: Add`. + input + &local; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32086.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32086.rs new file mode 100644 index 000000000000..a96967d0c48f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32086.rs @@ -0,0 +1,8 @@ +struct S(u8); +const C: S = S(10); + +fn main() { + let C(a) = S(11); // { dg-error ".E0532." "" { target *-*-* } } + let C(..) = S(11); // { dg-error ".E0532." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3211.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3211.rs new file mode 100644 index 000000000000..e093f2c95a45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3211.rs @@ -0,0 +1,8 @@ +// run-pass +pub fn main() { + let mut x = 0; + for _ in 0..4096 { x += 1; } + assert_eq!(x, 4096); + println!("x = {}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32119.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32119.rs new file mode 100644 index 000000000000..4265639dae5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32119.rs @@ -0,0 +1,18 @@ +// check-pass + +pub type T = (); +mod foo { pub use super::T; } +mod bar { pub use super::T; } + +pub use foo::*; +pub use bar::*; + +mod baz { + pub type T = (); + mod foo { pub use super::T as S; } + mod bar { pub use super::foo::S as T; } + pub use self::bar::*; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32122-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32122-1.rs new file mode 100644 index 000000000000..9830a6b65d33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32122-1.rs @@ -0,0 +1,18 @@ +// run-rustfix +use std::ops::Deref; + +struct Foo(u8); + +impl Deref for Foo { + type Target = u8; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +fn main() { + let a = Foo(0); + // Should suggest `&*` when coercing &ty to *const ty + let _: *const u8 = &a; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32122-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32122-2.rs new file mode 100644 index 000000000000..c1db054dd0a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32122-2.rs @@ -0,0 +1,29 @@ +// run-rustfix +use std::ops::Deref; +struct Bar(u8); +struct Foo(Bar); +struct Emm(Foo); +impl Deref for Bar{ + type Target = u8; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Foo { + type Target = Bar; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Emm { + type Target = Foo; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +fn main() { + let a = Emm(Foo(Bar(0))); + // Should suggest `&***` even when deref is pretty deep + let _: *const u8 = &a; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3214.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3214.rs new file mode 100644 index 000000000000..2597d4b92a74 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3214.rs @@ -0,0 +1,15 @@ +// ignore-tidy-linelength + +fn foo() { + struct Foo { + x: T, // { dg-error ".E0401." "" { target *-*-* } } + } + + impl Drop for Foo { +// { dg-error ".E0207." "" { target *-*-* } .-1 } +// { dg-error ".E0207." "" { target *-*-* } .-2 } + fn drop(&mut self) {} + } +} +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3220.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3220.rs new file mode 100644 index 000000000000..1f2244e371d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3220.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +// pretty-expanded FIXME #23616 + +struct thing { x: isize, } + +impl Drop for thing { + fn drop(&mut self) {} +} + +fn thing() -> thing { + thing { + x: 0 + } +} + +impl thing { + pub fn f(self) {} +} + +pub fn main() { + let z = thing(); + (z).f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32201.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32201.rs new file mode 100644 index 000000000000..b6410115309b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32201.rs @@ -0,0 +1,14 @@ +extern { + fn foo(a: i32, ...); +} + +fn bar(_: *const u8) {} + +fn main() { + unsafe { + foo(0, bar); +// { dg-error ".E0617." "" { target *-*-* } .-1 } +// { help ".E0617." "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32222.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32222.rs new file mode 100644 index 000000000000..7b4bed70c43b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32222.rs @@ -0,0 +1,23 @@ +// check-pass + +mod foo { + pub fn bar() {} +} + +pub use foo::*; +use b::bar; + +mod foobar { + use super::*; +} + +mod a { + pub mod bar {} +} + +mod b { + pub use a::bar; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32292.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32292.rs new file mode 100644 index 000000000000..7cd46449daca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32292.rs @@ -0,0 +1,10 @@ +// run-pass +#![deny(warnings)] + +#[derive(Hash, Ord, PartialOrd, Eq, PartialEq, Debug, Clone, Copy)] +struct Foo; + +fn main() { + let _ = Foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32323.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32323.rs new file mode 100644 index 000000000000..501572405629 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32323.rs @@ -0,0 +1,9 @@ +pub trait Tr<'a> { + type Out; +} + +pub fn f<'a, T: Tr<'a>>() -> >::Out {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32324.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32324.rs new file mode 100644 index 000000000000..36a13e80147e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32324.rs @@ -0,0 +1,25 @@ +// check-pass +#![allow(dead_code)] + +trait Resources { + type Buffer: Copy; +} + +#[derive(Copy, Clone)] +struct ConstantBufferSet( + pub R::Buffer +); + +#[derive(Copy, Clone)] +enum It {} +impl Resources for It { + type Buffer = u8; +} + +#[derive(Copy, Clone)] +enum Command { + BindConstantBuffers(ConstantBufferSet) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32326.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32326.rs new file mode 100644 index 000000000000..40f1ed82456b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32326.rs @@ -0,0 +1,11 @@ +// Regression test for #32326. We ran out of memory because we +// attempted to expand this case up to the recursion limit, and 2^N is +// too big. + +enum Expr { // { dg-error ".E0072." "" { target *-*-* } } + Plus(Expr, Expr), + Literal(i64), +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32354-suggest-import-rename.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32354-suggest-import-rename.rs new file mode 100644 index 000000000000..b0e6726b6180 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32354-suggest-import-rename.rs @@ -0,0 +1,17 @@ +// run-rustfix + +#![allow(unused_imports)] + +pub mod extension1 { + pub trait ConstructorExtension {} +} + +pub mod extension2 { + pub trait ConstructorExtension {} +} + +use extension1::ConstructorExtension; +use extension2::ConstructorExtension; // { dg-error ".E0252." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32377.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32377.rs new file mode 100644 index 000000000000..dfcc50082cab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32377.rs @@ -0,0 +1,20 @@ +// normalize-stderr-test "\d+ bits" -> "N bits" + +use std::mem; +use std::marker::PhantomData; + +trait Foo { + type Error; +} + +struct Bar { + stream: PhantomData, +} + +fn foo(x: [usize; 2]) -> Bar { + unsafe { mem::transmute(x) } +// { dg-error ".E0512." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32389.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32389.rs new file mode 100644 index 000000000000..d83c358095ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32389.rs @@ -0,0 +1,12 @@ +// run-pass +fn foo() -> T { loop {} } + +fn test() { + let ref mut a: &mut dyn FnMut((i8,), i16) = foo(); + a((0,), 0); +} + +fn main() { + let _ = test; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32518.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32518.rs new file mode 100644 index 000000000000..550ec54c27ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32518.rs @@ -0,0 +1,14 @@ +// run-pass +// no-prefer-dynamic +// aux-build:cgu_test.rs +// aux-build:cgu_test_a.rs +// aux-build:cgu_test_b.rs + +extern crate cgu_test_a; +extern crate cgu_test_b; + +fn main() { + cgu_test_a::a::a(); + cgu_test_b::a::a(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32655.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32655.rs new file mode 100644 index 000000000000..a929d62ff49c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32655.rs @@ -0,0 +1,20 @@ +macro_rules! foo ( + () => ( + #[derive_Clone] // { dg-error "" "" { target *-*-* } } + struct T; + ); +); + +macro_rules! bar ( + ($e:item) => ($e) +); + +foo!(); + +bar!( + #[derive_Clone] // { dg-error "" "" { target *-*-* } } + struct S; +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32709.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32709.rs new file mode 100644 index 000000000000..42662aecfd89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32709.rs @@ -0,0 +1,9 @@ +// Make sure that the span of try shorthand does not include the trailing +// semicolon; +fn a() -> Result { + Err(5)?; // { dg-error ".E0277." "" { target *-*-* } } + Ok(1) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32782.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32782.rs new file mode 100644 index 000000000000..97ba78b842a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32782.rs @@ -0,0 +1,14 @@ +macro_rules! bar ( + () => () +); + +macro_rules! foo ( + () => ( + #[allow_internal_unstable] // { dg-error ".E0658." "" { target *-*-* } } + bar!(); + ); +); + +foo!(); +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32797.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32797.rs new file mode 100644 index 000000000000..58fece442c54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32797.rs @@ -0,0 +1,14 @@ +// check-pass + +pub use bar::*; +mod bar { + pub use super::*; +} + +pub use baz::*; +mod baz { + pub use main as f; +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32805.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32805.rs new file mode 100644 index 000000000000..56117044ba16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32805.rs @@ -0,0 +1,11 @@ +// run-pass +fn const_mir() -> f32 { 9007199791611905.0 } + +fn main() { + let original = "9007199791611905.0"; // (1<<53)+(1<<29)+1 + let expected = "9007200000000000"; + + assert_eq!(const_mir().to_string(), expected); + assert_eq!(original.parse::().unwrap().to_string(), expected); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32829-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32829-2.rs new file mode 100644 index 000000000000..d14ea092cc7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32829-2.rs @@ -0,0 +1,74 @@ +// ignore-tidy-linelength + +const bad : u32 = { + { + 5; + 0 + } +}; + +const bad_two : u32 = { + { + invalid(); +// { dg-error ".E0015." "" { target *-*-* } .-1 } + 0 + } +}; + +const bad_three : u32 = { + { + valid(); + 0 + } +}; + +static bad_four : u32 = { + { + 5; + 0 + } +}; + +static bad_five : u32 = { + { + invalid(); +// { dg-error ".E0015." "" { target *-*-* } .-1 } + 0 + } +}; + +static bad_six : u32 = { + { + valid(); + 0 + } +}; + +static mut bad_seven : u32 = { + { + 5; + 0 + } +}; + +static mut bad_eight : u32 = { + { + invalid(); +// { dg-error ".E0015." "" { target *-*-* } .-1 } + 0 + } +}; + +static mut bad_nine : u32 = { + { + valid(); + 0 + } +}; + + +fn invalid() {} +const fn valid() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32829.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32829.rs new file mode 100644 index 000000000000..210ba594c555 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32829.rs @@ -0,0 +1,7 @@ +static S : u64 = { { panic!("foo"); 0 } }; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() { + println!("{:?}", S); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32833.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32833.rs new file mode 100644 index 000000000000..a424be8ef5c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32833.rs @@ -0,0 +1,8 @@ +use bar::Foo; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-1 } +mod bar { + use Foo; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3290.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3290.rs new file mode 100644 index 000000000000..706fc1e57aa8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3290.rs @@ -0,0 +1,9 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let mut x: Box<_> = box 3; + x = x; + assert_eq!(*x, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32922.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32922.rs new file mode 100644 index 000000000000..923dd7da024e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32922.rs @@ -0,0 +1,30 @@ +// check-pass + +macro_rules! foo { () => { + let x = 1; + macro_rules! bar { () => {x} } + let _ = bar!(); +}} + +macro_rules! m { // test issue #31856 + ($n:ident) => ( + let a = 1; + let $n = a; + ) +} + +macro_rules! baz { + ($i:ident) => { + let mut $i = 2; + $i = $i + 1; + } +} + +fn main() { + foo! {}; + bar! {}; + + let mut a = true; + baz!(a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32947.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32947.rs new file mode 100644 index 000000000000..227b74264eda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32947.rs @@ -0,0 +1,25 @@ +// run-pass +// ignore-emscripten FIXME(#45351) + +#![feature(repr_simd, test)] + +extern crate test; + +#[repr(simd)] +pub struct Mu64(pub u64, pub u64, pub u64, pub u64); + +fn main() { + // This ensures an unaligned pointer even in optimized builds, though LLVM + // gets enough type information to actually not mess things up in that case, + // but at the time of writing this, it's enough to trigger the bug in + // non-optimized builds + unsafe { + let memory = &mut [0u64; 8] as *mut _ as *mut u8; + let misaligned_ptr: &mut [u8; 32] = { + std::mem::transmute(memory.offset(1)) + }; + *misaligned_ptr = std::mem::transmute(Mu64(1, 1, 1, 1)); + test::black_box(memory); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32950.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32950.rs new file mode 100644 index 000000000000..13ffbcba7fde --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32950.rs @@ -0,0 +1,10 @@ +#![feature(concat_idents)] + +#[derive(Debug)] +struct Baz( + concat_idents!(Foo, Bar) // { dg-error ".E0412." "" { target *-*-* } } +// { dg-error ".E0412." "" { target *-*-* } .-1 } +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32963.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32963.rs new file mode 100644 index 000000000000..74885aac9a0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32963.rs @@ -0,0 +1,13 @@ +use std::mem; + +trait Misc {} + +fn size_of_copy() -> usize { mem::size_of::() } + +fn main() { + size_of_copy::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32995-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32995-2.rs new file mode 100644 index 000000000000..47222fde8563 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32995-2.rs @@ -0,0 +1,14 @@ +fn main() { + { fn f() {} } +// { dg-error ".E0214." "" { target *-*-* } .-1 } + + { fn f() -> impl ::std::marker()::Send { } } +// { dg-error ".E0214." "" { target *-*-* } .-1 } +} + +#[derive(Clone)] +struct X; + +impl ::std::marker()::Copy for X {} +// { dg-error ".E0214." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-32995.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-32995.rs new file mode 100644 index 000000000000..36c19f03655c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-32995.rs @@ -0,0 +1,25 @@ +fn main() { + let x: usize() = 1; +// { dg-error ".E0214." "" { target *-*-* } .-1 } + + let b: ::std::boxed()::Box<_> = Box::new(1); +// { dg-error ".E0214." "" { target *-*-* } .-1 } + + let p = ::std::str::()::from_utf8(b"foo").unwrap(); +// { dg-error ".E0214." "" { target *-*-* } .-1 } + + let p = ::std::str::from_utf8::()(b"foo").unwrap(); +// { dg-error ".E0214." "" { target *-*-* } .-1 } + + let o : Box = Box::new(1); +// { dg-error ".E0214." "" { target *-*-* } .-1 } + + let o : Box = Box::new(1); +// { dg-error ".E0214." "" { target *-*-* } .-1 } +} + +fn foo() { + let d : X() = Default::default(); +// { dg-error ".E0214." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33096.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33096.rs new file mode 100644 index 000000000000..05fb451f2dd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33096.rs @@ -0,0 +1,20 @@ +// run-pass +// compile-flags: -g +// ignore-asmjs wasm2js does not support source maps yet + +use std::ops::Deref; + +trait Foo { + fn foo() {} +} + +impl Foo for u8 {} + +fn bar() where T::Target: Foo { + <::Target as Foo>::foo() +} + +fn main() { + bar::<&u8>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33140-hack-boundaries.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33140-hack-boundaries.rs new file mode 100644 index 000000000000..81c69e7e90ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33140-hack-boundaries.rs @@ -0,0 +1,71 @@ +#![feature(negative_impls)] +#![allow(order_dependent_trait_objects)] + +// Check that the issue #33140 hack does not allow unintended things. + +// OK +trait Trait0 {} + +impl Trait0 for dyn Send {} +impl Trait0 for dyn Send {} + +// Problem 1: associated types +trait Trait1 { + fn my_fn(&self) {} +} + +impl Trait1 for dyn Send {} +impl Trait1 for dyn Send {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +// Problem 2: negative impl +trait Trait2 {} + +impl Trait2 for dyn Send {} +impl !Trait2 for dyn Send {} +// { dg-error ".E0751." "" { target *-*-* } .-1 } + +// Problem 3: type parameter +trait Trait3 {} + +impl Trait3 for dyn Send {} +impl Trait3 for dyn Send {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +// Problem 4a: not a trait object - generic +trait Trait4a {} + +impl Trait4a for T {} +impl Trait4a for dyn Send {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +// Problem 4b: not a trait object - misc +trait Trait4b {} + +impl Trait4b for () {} +impl Trait4b for () {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +// Problem 4c: not a principal-less trait object +trait Trait4c {} + +impl Trait4c for dyn Trait1 + Send {} +impl Trait4c for dyn Trait1 + Send {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +// Problem 4d: lifetimes +trait Trait4d {} + +impl<'a> Trait4d for dyn Send + 'a {} +impl<'a> Trait4d for dyn Send + 'a {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +// Problem 5: where-clauses +trait Trait5 {} + +impl Trait5 for dyn Send {} +impl Trait5 for dyn Send where u32: Copy {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33140-traitobject-crate.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33140-traitobject-crate.rs new file mode 100644 index 000000000000..f389757bc52f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33140-traitobject-crate.rs @@ -0,0 +1,108 @@ +// check-pass + +#![warn(order_dependent_trait_objects)] + +// Check that traitobject 0.1.0 compiles + +//! # traitobject +//! +//! Unsafe helpers for working with raw TraitObjects. + +/// A trait implemented for all trait objects. +/// +/// Implementations for all traits in std are provided. +pub unsafe trait Trait {} + +unsafe impl Trait for dyn (::std::any::Any) + Send { } +unsafe impl Trait for dyn (::std::any::Any) + Sync { } +unsafe impl Trait for dyn (::std::any::Any) + Send + Sync { } +unsafe impl Trait for dyn (::std::borrow::Borrow) + Send { } +unsafe impl Trait for dyn (::std::borrow::Borrow) + Sync { } +unsafe impl Trait for dyn (::std::borrow::Borrow) + Send + Sync { } +unsafe impl Trait for dyn (::std::borrow::BorrowMut) + Send { } +unsafe impl Trait for dyn (::std::borrow::BorrowMut) + Sync { } +unsafe impl Trait for dyn (::std::borrow::BorrowMut) + Send + Sync { } +unsafe impl Trait for dyn (::std::convert::AsMut) + Send { } +unsafe impl Trait for dyn (::std::convert::AsMut) + Sync { } +unsafe impl Trait for dyn (::std::convert::AsMut) + Send + Sync { } +unsafe impl Trait for dyn (::std::convert::AsRef) + Send { } +unsafe impl Trait for dyn (::std::convert::AsRef) + Sync { } +unsafe impl Trait for dyn (::std::convert::AsRef) + Send + Sync { } +unsafe impl Trait for dyn (::std::error::Error) + Send { } +unsafe impl Trait for dyn (::std::error::Error) + Sync { } +unsafe impl Trait for dyn (::std::error::Error) + Send + Sync { } +unsafe impl Trait for dyn (::std::fmt::Binary) + Send { } +unsafe impl Trait for dyn (::std::fmt::Binary) + Sync { } +unsafe impl Trait for dyn (::std::fmt::Binary) + Send + Sync { } +unsafe impl Trait for dyn (::std::fmt::Debug) + Send { } +unsafe impl Trait for dyn (::std::fmt::Debug) + Sync { } +unsafe impl Trait for dyn (::std::fmt::Debug) + Send + Sync { } +unsafe impl Trait for dyn (::std::fmt::Display) + Send { } +unsafe impl Trait for dyn (::std::fmt::Display) + Sync { } +unsafe impl Trait for dyn (::std::fmt::Display) + Send + Sync { } +unsafe impl Trait for dyn (::std::fmt::LowerExp) + Send { } +unsafe impl Trait for dyn (::std::fmt::LowerExp) + Sync { } +unsafe impl Trait for dyn (::std::fmt::LowerExp) + Send + Sync { } +unsafe impl Trait for dyn (::std::fmt::LowerHex) + Send { } +unsafe impl Trait for dyn (::std::fmt::LowerHex) + Sync { } +unsafe impl Trait for dyn (::std::fmt::LowerHex) + Send + Sync { } +unsafe impl Trait for dyn (::std::fmt::Octal) + Send { } +unsafe impl Trait for dyn (::std::fmt::Octal) + Sync { } +unsafe impl Trait for dyn (::std::fmt::Octal) + Send + Sync { } +unsafe impl Trait for dyn (::std::fmt::Pointer) + Send { } +unsafe impl Trait for dyn (::std::fmt::Pointer) + Sync { } +unsafe impl Trait for dyn (::std::fmt::Pointer) + Send + Sync { } +unsafe impl Trait for dyn (::std::fmt::UpperExp) + Send { } +unsafe impl Trait for dyn (::std::fmt::UpperExp) + Sync { } +unsafe impl Trait for dyn (::std::fmt::UpperExp) + Send + Sync { } +unsafe impl Trait for dyn (::std::fmt::UpperHex) + Send { } +unsafe impl Trait for dyn (::std::fmt::UpperHex) + Sync { } +unsafe impl Trait for dyn (::std::fmt::UpperHex) + Send + Sync { } +unsafe impl Trait for dyn (::std::fmt::Write) + Send { } +unsafe impl Trait for dyn (::std::fmt::Write) + Sync { } +unsafe impl Trait for dyn (::std::fmt::Write) + Send + Sync { } +unsafe impl Trait for dyn (::std::hash::Hasher) + Send { } +unsafe impl Trait for dyn (::std::hash::Hasher) + Sync { } +unsafe impl Trait for dyn (::std::hash::Hasher) + Send + Sync { } +unsafe impl Trait for dyn (::std::io::BufRead) + Send { } +unsafe impl Trait for dyn (::std::io::BufRead) + Sync { } +unsafe impl Trait for dyn (::std::io::BufRead) + Send + Sync { } +unsafe impl Trait for dyn (::std::io::Read) + Send { } +unsafe impl Trait for dyn (::std::io::Read) + Sync { } +unsafe impl Trait for dyn (::std::io::Read) + Send + Sync { } +unsafe impl Trait for dyn (::std::io::Seek) + Send { } +unsafe impl Trait for dyn (::std::io::Seek) + Sync { } +unsafe impl Trait for dyn (::std::io::Seek) + Send + Sync { } +unsafe impl Trait for dyn (::std::io::Write) + Send { } +unsafe impl Trait for dyn (::std::io::Write) + Sync { } +unsafe impl Trait for dyn (::std::io::Write) + Send + Sync { } +unsafe impl Trait for dyn (::std::iter::IntoIterator) { } +unsafe impl Trait for dyn (::std::iter::Iterator) + Send { } +unsafe impl Trait for dyn (::std::iter::Iterator) + Sync { } +unsafe impl Trait for dyn (::std::iter::Iterator) + Send + Sync { } +unsafe impl Trait for dyn (::std::marker::Send) + Send { } +unsafe impl Trait for dyn (::std::marker::Send) + Sync { } +unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +unsafe impl Trait for dyn (::std::marker::Sync) + Send { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +unsafe impl Trait for dyn (::std::marker::Sync) + Sync { } +unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +unsafe impl Trait for dyn (::std::ops::Drop) + Send { } +unsafe impl Trait for dyn (::std::ops::Drop) + Sync { } +unsafe impl Trait for dyn (::std::ops::Drop) + Send + Sync { } +unsafe impl Trait for dyn (::std::string::ToString) + Send { } +unsafe impl Trait for dyn (::std::string::ToString) + Sync { } +unsafe impl Trait for dyn (::std::string::ToString) + Send + Sync { } +fn assert_trait() {} + +fn main() { + assert_trait::(); + assert_trait::(); + assert_trait::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33140.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33140.rs new file mode 100644 index 000000000000..6dac2b06dac9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33140.rs @@ -0,0 +1,48 @@ +trait Trait { + fn xyz() -> bool; +} + +impl Trait for dyn Send + Sync { + fn xyz() -> bool { false } +} + +impl Trait for dyn Sync + Send { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + fn xyz() -> bool { true } +} + +trait Trait2 { + fn uvw() -> bool; +} + +impl Trait2 for dyn Send + Sync { + fn uvw() -> bool { false } +} + +impl Trait2 for dyn Sync + Send + Sync { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + fn uvw() -> bool { true } +} + +struct Foo(T); +impl Foo { + fn abc() -> bool { // { dg-error ".E0592." "" { target *-*-* } } + false + } +} + +impl Foo { + fn abc() -> bool { + true + } +} + +fn main() { + assert_eq!(::xyz(), false); + assert_eq!(::xyz(), true); + assert_eq!(::uvw(), false); + assert_eq!(::uvw(), true); + assert_eq!(>::abc(), false); + assert_eq!(>::abc(), true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33185.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33185.rs new file mode 100644 index 000000000000..c75ae3cb14b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33185.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] + +#[macro_export] +macro_rules! state { + ( $( $name:ident : $field:ty )* ) => ( + #[derive(Default)] + struct State { + $($name : $field),* + } + ) +} + +state! { x: i64 } + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33187.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33187.rs new file mode 100644 index 000000000000..6428605c1f43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33187.rs @@ -0,0 +1,20 @@ +// run-pass +// ignore-compare-mode-chalk +struct Foo(::Data); + +impl Copy for Foo where ::Data: Copy { } +impl Clone for Foo where ::Data: Clone { + fn clone(&self) -> Self { Foo(self.0.clone()) } +} + +trait Repr { + type Data; +} + +impl Repr for A { + type Data = u32; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33202.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33202.rs new file mode 100644 index 000000000000..a8f07790af4f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33202.rs @@ -0,0 +1,10 @@ +// run-pass +#[repr(C)] +pub enum CPOption { + PSome(T), +} + +fn main() { + println!("sizeof CPOption {}", std::mem::size_of::>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33241.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33241.rs new file mode 100644 index 000000000000..b91531ff3418 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33241.rs @@ -0,0 +1,13 @@ +// check-pass + +use std::fmt; + +// CoerceUnsized is not implemented for tuples. You can still create +// an unsized tuple by transmuting a trait object. +fn any() -> T { unreachable!() } + +fn main() { + let t: &(u8, dyn fmt::Debug) = any(); + println!("{:?}", &t.1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33264.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33264.rs new file mode 100644 index 000000000000..60a6f8f0cb23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33264.rs @@ -0,0 +1,30 @@ +// build-pass +// only-x86_64 + +#![allow(dead_code, non_upper_case_globals)] +#![feature(llvm_asm)] + +#[repr(C)] +pub struct D32x4(f32,f32,f32,f32); + +impl D32x4 { + fn add(&self, vec: Self) -> Self { + unsafe { + let ret: Self; + llvm_asm!(" + movaps $1, %xmm1 + movaps $2, %xmm2 + addps %xmm1, %xmm2 + movaps $xmm1, $0 + " + : "=r"(ret) + : "1"(self), "2"(vec) + : "xmm1", "xmm2" + ); + ret + } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33287.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33287.rs new file mode 100644 index 000000000000..b935fb1689b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33287.rs @@ -0,0 +1,11 @@ +// build-pass +#![allow(dead_code)] +#![allow(unused_variables)] +const A: [u32; 1] = [0]; + +fn test() { + let range = A[1]..; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33293.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33293.rs new file mode 100644 index 000000000000..c7afc3714fc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33293.rs @@ -0,0 +1,7 @@ +fn main() { + match 0 { + aaa::bbb(_) => () +// { dg-error ".E0433." "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-333.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-333.rs new file mode 100644 index 000000000000..9fd7d3b28c95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-333.rs @@ -0,0 +1,8 @@ +// run-pass + +fn quux(x: T) -> T { let f = id::; return f(x); } + +fn id(x: T) -> T { return x; } + +pub fn main() { assert_eq!(quux(10), 10); } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33387.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33387.rs new file mode 100644 index 000000000000..42ad6b2963ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33387.rs @@ -0,0 +1,33 @@ +// run-pass +#![feature(rustc_attrs)] + +use std::sync::Arc; + +trait Foo { + fn get(&self) -> [u8; 2]; +} + +impl Foo for [u8; 2] { + fn get(&self) -> [u8; 2] { + *self + } +} + +struct Bar(T); + +fn unsize_fat_ptr<'a>(x: &'a Bar) -> &'a Bar { + x +} + +fn unsize_nested_fat_ptr(x: Arc) -> Arc { + x +} + +fn main() { + let x: Box> = Box::new(Bar([1,2])); + assert_eq!(unsize_fat_ptr(&*x).0.get(), [1, 2]); + + let x: Arc = Arc::new([3, 4]); + assert_eq!(unsize_nested_fat_ptr(x).get(), [3, 4]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3344.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3344.rs new file mode 100644 index 000000000000..673d72bc1288 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3344.rs @@ -0,0 +1,8 @@ +#[derive(PartialEq)] +struct Thing(usize); +impl PartialOrd for Thing { // { dg-error ".E0046." "" { target *-*-* } } + fn le(&self, other: &Thing) -> bool { true } + fn ge(&self, other: &Thing) -> bool { true } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33461.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33461.rs new file mode 100644 index 000000000000..d030acda2090 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33461.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(unused_variables)] +use std::marker::PhantomData; + +struct TheType { + t: PhantomData +} + +pub trait TheTrait { + type TheAssociatedType; +} + +impl TheTrait for () { + type TheAssociatedType = (); +} + +pub trait Shape { + fn doit(&self) { + } +} + +impl Shape

for TheType { +} + +fn main() { + let ball = TheType { t: PhantomData }; + let handle: &dyn Shape<()> = &ball; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33464.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33464.rs new file mode 100644 index 000000000000..46c40224acd4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33464.rs @@ -0,0 +1,11 @@ +// Make sure that the spans of import errors are correct. + +use abc::one_el; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +use abc::{a, bbb, cccccc}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +use a_very_long_name::{el, el2}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33498.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33498.rs new file mode 100644 index 000000000000..11fd7f490f5a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33498.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(unused_variables)] +pub fn main() { + let x = (0, 2); + + match x { + (0, ref y) => {} + (y, 0) => {} + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33504.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33504.rs new file mode 100644 index 000000000000..0228e6431bca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33504.rs @@ -0,0 +1,10 @@ +// Shadowing a unit-like enum in a closure + +struct Test; + +fn main() { + || { + let Test = 1; // { dg-error ".E0308." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33525.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33525.rs new file mode 100644 index 000000000000..c801da173716 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33525.rs @@ -0,0 +1,6 @@ +fn main() { + a; // { dg-error ".E0425." "" { target *-*-* } } + "".lorem; // { dg-error ".E0609." "" { target *-*-* } } + "".ipsum; // { dg-error ".E0609." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33537.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33537.rs new file mode 100644 index 000000000000..949b28a7ccd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33537.rs @@ -0,0 +1,15 @@ +// run-pass + +const fn foo() -> *const i8 { + b"foo" as *const _ as *const i8 +} + +const fn bar() -> i32 { + *&{(1, 2, 3).1} +} + +fn main() { + assert_eq!(foo(), b"foo" as *const _ as *const i8); + assert_eq!(bar(), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33571.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33571.rs new file mode 100644 index 000000000000..0b6b5c7995c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33571.rs @@ -0,0 +1,8 @@ +#[derive(Clone, + Sync, // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + Copy)] +enum Foo {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33575.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33575.rs new file mode 100644 index 000000000000..b08143cdc51a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33575.rs @@ -0,0 +1,5 @@ +fn main() { + let baz = ().foo(); // { dg-error ".E0599." "" { target *-*-* } } + ::from_str(&baz); // No complaints about `str` being unsized +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33687.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33687.rs new file mode 100644 index 000000000000..c486141ba4d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33687.rs @@ -0,0 +1,18 @@ +// run-pass +#![feature(unboxed_closures)] +#![feature(fn_traits)] + +struct Test; + +impl FnOnce<(u32, u32)> for Test { + type Output = u32; + + extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 { + a + b + } +} + +fn main() { + assert_eq!(Test(1u32, 2u32), 3u32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33770.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33770.rs new file mode 100644 index 000000000000..03d7c31c0dab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33770.rs @@ -0,0 +1,96 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::process::{Command, Stdio}; +use std::env; +use std::sync::{Mutex, RwLock}; +use std::time::Duration; +use std::thread; + +fn test_mutex() { + let m = Mutex::new(0); + let _g = m.lock().unwrap(); + let _g2 = m.lock().unwrap(); +} + +fn test_try_mutex() { + let m = Mutex::new(0); + let _g = m.lock().unwrap(); + let _g2 = m.try_lock().unwrap(); +} + +fn test_rwlock_ww() { + let m = RwLock::new(0); + let _g = m.write().unwrap(); + let _g2 = m.write().unwrap(); +} + +fn test_try_rwlock_ww() { + let m = RwLock::new(0); + let _g = m.write().unwrap(); + let _g2 = m.try_write().unwrap(); +} + +fn test_rwlock_rw() { + let m = RwLock::new(0); + let _g = m.read().unwrap(); + let _g2 = m.write().unwrap(); +} + +fn test_try_rwlock_rw() { + let m = RwLock::new(0); + let _g = m.read().unwrap(); + let _g2 = m.try_write().unwrap(); +} + +fn test_rwlock_wr() { + let m = RwLock::new(0); + let _g = m.write().unwrap(); + let _g2 = m.read().unwrap(); +} + +fn test_try_rwlock_wr() { + let m = RwLock::new(0); + let _g = m.write().unwrap(); + let _g2 = m.try_read().unwrap(); +} + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 { + match &*args[1] { + "mutex" => test_mutex(), + "try_mutex" => test_try_mutex(), + "rwlock_ww" => test_rwlock_ww(), + "try_rwlock_ww" => test_try_rwlock_ww(), + "rwlock_rw" => test_rwlock_rw(), + "try_rwlock_rw" => test_try_rwlock_rw(), + "rwlock_wr" => test_rwlock_wr(), + "try_rwlock_wr" => test_try_rwlock_wr(), + _ => unreachable!(), + } + // If we reach this point then the test failed + println!("TEST FAILED: {}", args[1]); + } else { + let mut v = vec![]; + v.push(Command::new(&args[0]).arg("mutex").stderr(Stdio::null()).spawn().unwrap()); + v.push(Command::new(&args[0]).arg("try_mutex").stderr(Stdio::null()).spawn().unwrap()); + v.push(Command::new(&args[0]).arg("rwlock_ww").stderr(Stdio::null()).spawn().unwrap()); + v.push(Command::new(&args[0]).arg("try_rwlock_ww").stderr(Stdio::null()).spawn().unwrap()); + v.push(Command::new(&args[0]).arg("rwlock_rw").stderr(Stdio::null()).spawn().unwrap()); + v.push(Command::new(&args[0]).arg("try_rwlock_rw").stderr(Stdio::null()).spawn().unwrap()); + v.push(Command::new(&args[0]).arg("rwlock_wr").stderr(Stdio::null()).spawn().unwrap()); + v.push(Command::new(&args[0]).arg("try_rwlock_wr").stderr(Stdio::null()).spawn().unwrap()); + + thread::sleep(Duration::new(1, 0)); + + // Make sure all subprocesses either panicked or were killed because they deadlocked + for mut c in v { + c.kill().ok(); + assert!(!c.wait().unwrap().success()); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33819.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33819.rs new file mode 100644 index 000000000000..2e222f86ca59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33819.rs @@ -0,0 +1,9 @@ +fn main() { + let mut op = Some(2); + match op { + Some(ref v) => { let a = &mut v; }, +// { dg-error ".E0596." "" { target *-*-* } .-1 } + None => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3389.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3389.rs new file mode 100644 index 000000000000..2395cac3ac85 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3389.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +struct trie_node { + content: Vec , + children: Vec , +} + +fn print_str_vector(vector: Vec ) { + for string in &vector { + println!("{}", *string); + } +} + +pub fn main() { + let mut node: trie_node = trie_node { + content: Vec::new(), + children: Vec::new() + }; + let v = vec!["123".to_string(), "abc".to_string()]; + node.content = vec!["123".to_string(), "abc".to_string()]; + print_str_vector(v); + print_str_vector(node.content.clone()); + +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33903.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33903.rs new file mode 100644 index 000000000000..c88a4a4f0ab5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33903.rs @@ -0,0 +1,11 @@ +// check-pass +#![allow(dead_code)] +// Issue 33903: +// Built-in indexing should be used even when the index is not +// trivially an integer +// Only built-in indexing can be used in constant expressions + +const FOO: i32 = [12, 34][0 + 1]; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33941.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33941.rs new file mode 100644 index 000000000000..44761b2e1dc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33941.rs @@ -0,0 +1,8 @@ +use std::collections::HashMap; + +fn main() { + for _ in HashMap::new().iter().cloned() {} // { dg-error ".E0271." "" { target *-*-* } } +// { dg-error ".E0271." "" { target *-*-* } .-1 } +// { dg-error ".E0271." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-33992.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-33992.rs new file mode 100644 index 000000000000..20195adaf45a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-33992.rs @@ -0,0 +1,33 @@ +// run-pass +// ignore-windows +// ignore-macos +// ignore-emscripten common linkage not implemented right now + +#![feature(linkage)] + +#[linkage = "common"] +pub static mut TEST1: u32 = 0u32; + +#[linkage = "external"] +pub static TEST2: bool = true; + +#[linkage = "internal"] +pub static TEST3: bool = true; + +#[linkage = "linkonce"] +pub static TEST4: bool = true; + +#[linkage = "linkonce_odr"] +pub static TEST5: bool = true; + +#[linkage = "private"] +pub static TEST6: bool = true; + +#[linkage = "weak"] +pub static TEST7: bool = true; + +#[linkage = "weak_odr"] +pub static TEST8: bool = true; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34028.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34028.rs new file mode 100644 index 000000000000..aa7d2c21f33f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34028.rs @@ -0,0 +1,11 @@ +// check-pass + +macro_rules! m { + () => { #[cfg(any())] fn f() {} } +} + +trait T {} +impl T for () { m!(); } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34047.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34047.rs new file mode 100644 index 000000000000..4be851fefe2e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34047.rs @@ -0,0 +1,9 @@ +const C: u8 = 0; + +fn main() { + match 1u8 { + mut C => {} // { dg-error ".E0530." "" { target *-*-* } } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34053.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34053.rs new file mode 100644 index 000000000000..678f6ea726a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34053.rs @@ -0,0 +1,31 @@ +// run-pass +use std::sync::atomic::{AtomicUsize, Ordering}; + +static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); + +struct A(i32); + +impl Drop for A { + fn drop(&mut self) { + // update global drop count + DROP_COUNTER.fetch_add(1, Ordering::SeqCst); + } +} + +static FOO: A = A(123); +const BAR: A = A(456); + +impl A { + const BAZ: A = A(789); +} + +fn main() { + assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0); + assert_eq!(&FOO.0, &123); + assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0); + assert_eq!(BAR.0, 456); + assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 1); + assert_eq!(A::BAZ.0, 789); + assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34074.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34074.rs new file mode 100644 index 000000000000..65ec40966897 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34074.rs @@ -0,0 +1,11 @@ +// run-pass +// Make sure several unnamed function parameters don't conflict with each other + +trait Tr { + #[allow(anonymous_parameters)] + fn f(u8, u8) {} +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34171.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34171.rs new file mode 100644 index 000000000000..4d65525be333 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34171.rs @@ -0,0 +1,11 @@ +// check-pass + +macro_rules! null { ($i:tt) => {} } +macro_rules! apply_null { + ($i:item) => { null! { $i } } +} + +fn main() { + apply_null!(#[cfg(all())] fn f() {}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34194.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34194.rs new file mode 100644 index 000000000000..820e3e9e9cfe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34194.rs @@ -0,0 +1,12 @@ +// build-pass +#![allow(dead_code)] + +struct A { + a: &'static (), +} + +static B: &'static A = &A { a: &() }; +static C: &'static A = &B; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34209.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34209.rs new file mode 100644 index 000000000000..648665eb7921 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34209.rs @@ -0,0 +1,12 @@ +enum S { + A, +} + +fn bug(l: S) { + match l { + S::B {} => {}, // { dg-error ".E0599." "" { target *-*-* } } + } +} + +fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34222-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34222-1.rs new file mode 100644 index 000000000000..8145e97173c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34222-1.rs @@ -0,0 +1,4 @@ +fn main() { + /// comment // { dg-error ".E0585." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34229.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34229.rs new file mode 100644 index 000000000000..85ee663ce4f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34229.rs @@ -0,0 +1,10 @@ +#[derive(PartialEq)] struct Comparable; +#[derive(PartialEq, PartialOrd)] struct Nope(Comparable); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3424.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3424.rs new file mode 100644 index 000000000000..197191096847 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3424.rs @@ -0,0 +1,21 @@ +// check-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +// rustc --test ignores2.rs && ./ignores2 + +pub struct Path; + +type rsrc_loader = Box Result>; + +fn tester() +{ + let mut loader: rsrc_loader = Box::new(move |_path| { + Ok("more blah".to_string()) + }); + + let path = Path; + assert!(loader(&path).is_ok()); +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34255-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34255-1.rs new file mode 100644 index 000000000000..951a1513dc42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34255-1.rs @@ -0,0 +1,11 @@ +enum Test { + Drill { + field: i32, + } +} + +fn main() { + Test::Drill(field: 42); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3429.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3429.rs new file mode 100644 index 000000000000..394378f94063 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3429.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + let x = 1_usize; + let y = || x; + let _z = y(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34334.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34334.rs new file mode 100644 index 000000000000..127d49491896 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34334.rs @@ -0,0 +1,7 @@ +fn main () { + let sr: Vec<(u32, _, _) = vec![]; +// { dg-error "" "" { target *-*-* } .-1 } + let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34349.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34349.rs new file mode 100644 index 000000000000..332a9911b946 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34349.rs @@ -0,0 +1,23 @@ +// This is a regression test for a problem encountered around upvar +// inference and trait caching: in particular, we were entering a +// temporary closure kind during inference, and then caching results +// based on that temporary kind, which led to no error being reported +// in this particular test. + +fn main() { + let inc = || {}; + inc(); + + fn apply(f: F) where F: Fn() { + f() + } + + let mut farewell = "goodbye".to_owned(); + let diary = || { // { dg-error ".E0525." "" { target *-*-* } } + farewell.push_str("!!!"); + println!("Then I screamed {}.", farewell); + }; + + apply(diary); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34373.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34373.rs new file mode 100644 index 000000000000..7243815972bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34373.rs @@ -0,0 +1,12 @@ +#![allow(warnings)] + +trait Trait { + fn foo(_: T) {} +} + +pub struct Foo>>; // { dg-error ".E0391." "" { target *-*-* } } +type DefaultFoo = Foo; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34418.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34418.rs new file mode 100644 index 000000000000..2daecde00db8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34418.rs @@ -0,0 +1,20 @@ +// check-pass + +macro_rules! make_item { + () => { fn f() {} } +} + +macro_rules! make_stmt { + () => { let x = 0; } +} + +fn f() { + make_item! {} +} + +fn g() { + make_stmt! {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34427.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34427.rs new file mode 100644 index 000000000000..2f0501fadac9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34427.rs @@ -0,0 +1,18 @@ +// run-pass +// Issue #34427: On ARM, the code in `foo` at one time was generating +// a machine code instruction of the form: `str r0, [r0, rN]!` (for +// some N), which is not legal because the source register and base +// register cannot be identical in the preindexed form signalled by +// the `!`. +// +// See LLVM bug: https://llvm.org/bugs/show_bug.cgi?id=28809 + +#[inline(never)] +fn foo(n: usize) -> Vec> { + (0..n).map(|_| None).collect() +} + +fn main() { + let _ = (foo(10), foo(32)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3447.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3447.rs new file mode 100644 index 000000000000..c52e9b6b0b0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3447.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_snake_case)] +#![allow(non_camel_case_types)] +#![feature(box_syntax)] + +use std::cell::RefCell; + +static S: &'static str = "str"; + +struct list { + element: T, + next: Option>>> +} + +impl list { + pub fn addEnd(&mut self, element: T) { + let newList = list { + element: element, + next: None + }; + + self.next = Some(box RefCell::new(newList)); + } +} + +pub fn main() { + let ls = list { + element: S, + next: None + }; + println!("{}", ls.element); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34503.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34503.rs new file mode 100644 index 000000000000..097c669b9802 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34503.rs @@ -0,0 +1,12 @@ +// run-pass +fn main() { + struct X; + trait Foo { + fn foo(&self) where (T, Option): Ord {} + fn bar(&self, x: &Option) -> bool + where Option: Ord { *x < *x } + } + impl Foo for () {} + let _ = &() as &dyn Foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34569.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34569.rs new file mode 100644 index 000000000000..e231d05208de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34569.rs @@ -0,0 +1,19 @@ +// run-pass +// compile-flags:-g +// ignore-asmjs wasm2js does not support source maps yet + +// In this test we just want to make sure that the code below does not lead to +// a debuginfo verification assertion during compilation. This was caused by the +// closure in the guard being codegened twice due to how match expressions are +// handled. +// +// See https://github.com/rust-lang/rust/issues/34569 for details. + +fn main() { + match 0 { + e if (|| { e == 0 })() => {}, + 1 => {}, + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34571.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34571.rs new file mode 100644 index 000000000000..c6bf35cb1f73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34571.rs @@ -0,0 +1,12 @@ +// run-pass +#[repr(u8)] +enum Foo { + Foo(u8), +} + +fn main() { + match Foo::Foo(1) { + _ => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34721.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34721.rs new file mode 100644 index 000000000000..fc99f79e6fe9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34721.rs @@ -0,0 +1,35 @@ +// run-rustfix + +pub trait Foo { + fn zero(self) -> Self; +} + +impl Foo for u32 { + fn zero(self) -> u32 { 0u32 } +} + +pub mod bar { + pub use Foo; + pub fn bar(x: T) -> T { + x.zero() + } +} + +mod baz { + use bar; + use Foo; + pub fn baz(x: T) -> T { + if 0 == 1 { + bar::bar(x.zero()) + } else { + x.zero() + }; + x.zero() +// { dg-error ".E0382." "" { target *-*-* } .-1 } + } +} + +fn main() { + let _ = baz::baz(0u32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34751.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34751.rs new file mode 100644 index 000000000000..198a8762650d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34751.rs @@ -0,0 +1,12 @@ +// check-pass +#![allow(dead_code)] +// #34751 ICE: 'rustc' panicked at 'assertion failed: !substs.has_regions_escaping_depth(0)' + +#[allow(dead_code)] + +use std::marker::PhantomData; + +fn f<'a>(PhantomData::<&'a u8>: PhantomData<&'a u8>) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3477.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3477.rs new file mode 100644 index 000000000000..5c138c4bc440 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3477.rs @@ -0,0 +1,6 @@ +fn main() { + let _p: char = 100; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34780.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34780.rs new file mode 100644 index 000000000000..c9b0fc76881c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34780.rs @@ -0,0 +1,12 @@ +// check-pass +#![allow(stable_features)] +#![feature(associated_consts)] + +use std::marker::PhantomData; + +trait Tr<'a> { + const C: PhantomData<&'a u8> = PhantomData::<&'a u8>; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34784.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34784.rs new file mode 100644 index 000000000000..5e8a7740ead1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34784.rs @@ -0,0 +1,22 @@ +// run-pass + +#![warn(pointer_structural_match)] +#![allow(dead_code)] +const C: *const u8 = &0; + +fn foo(x: *const u8) { + match x { + C => {} + _ => {} + } +} + +const D: *const [u8; 4] = b"abcd"; + +fn main() { + match D { + D => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34796.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34796.rs new file mode 100644 index 000000000000..a81c9eef5468 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34796.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] +// This test case exposes conditions where the encoding of a trait object type +// with projection predicates would differ between this crate and the upstream +// crate, because the predicates were encoded in different order within each +// crate. This led to different symbol hashes of functions using these type, +// which in turn led to linker errors because the two crates would not agree on +// the symbol name. +// The fix was to make the order in which predicates get encoded stable. + +// aux-build:issue-34796-aux.rs +extern crate issue_34796_aux; + +fn mk() -> T { loop {} } + +struct Data { + data: T, + error: E, +} + +fn main() { + issue_34796_aux::bar(|()| { + Data::<(), std::io::Error> { + data: mk(), + error: mk(), + } + }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34798.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34798.rs new file mode 100644 index 000000000000..2a9447b899d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34798.rs @@ -0,0 +1,26 @@ +// run-pass +#![forbid(improper_ctypes)] +#![allow(dead_code)] + +#[repr(C)] +pub struct Foo { + size: u8, + __value: ::std::marker::PhantomData, +} + +#[repr(C)] +pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData); + +#[repr(C)] +pub struct Bar { + size: u8, + baz: ZeroSizeWithPhantomData, +} + +extern "C" { + pub fn bar(_: *mut Foo, _: *mut Bar); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34839.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34839.rs new file mode 100644 index 000000000000..df082aa11f6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34839.rs @@ -0,0 +1,20 @@ +// check-pass + +trait RegularExpression: Sized { + type Text; +} + +struct ExecNoSyncStr<'a>(&'a u8); + +impl<'c> RegularExpression for ExecNoSyncStr<'c> { + type Text = u8; +} + +struct FindCaptures<'t, R>(&'t R::Text) where R: RegularExpression, R::Text: 't; + +enum FindCapturesInner<'r, 't> { + Dynamic(FindCaptures<'t, ExecNoSyncStr<'r>>), +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-34932.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-34932.rs new file mode 100644 index 000000000000..945749d27395 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-34932.rs @@ -0,0 +1,12 @@ +// run-pass +// compile-flags:--test +#![cfg(any())] // This test should be configured away +#![feature(rustc_attrs)] // Test that this is allowed on stable/beta +#![feature(iter_arith_traits)] // Test that this is not unused +#![deny(unused_features)] + +#[test] +fn dummy() { + let () = "this should not reach type-checking"; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3500.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3500.rs new file mode 100644 index 000000000000..5b50bfcf5803 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3500.rs @@ -0,0 +1,11 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + let x = &Some(1); + match x { + &Some(_) => (), + &None => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35075.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35075.rs new file mode 100644 index 000000000000..3141e0b4c614 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35075.rs @@ -0,0 +1,10 @@ +struct Bar { + inner: Foo // { dg-error ".E0412." "" { target *-*-* } } +} + +enum Baz { + Foo(Foo) // { dg-error ".E0412." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35139.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35139.rs new file mode 100644 index 000000000000..b880da2e8a61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35139.rs @@ -0,0 +1,27 @@ +use std::fmt; + +pub trait MethodType { + type GetProp: ?Sized; +} + +pub struct MTFn; + +impl<'a> MethodType for MTFn { // { dg-error ".E0207." "" { target *-*-* } } + type GetProp = dyn fmt::Debug + 'a; +} + +fn bad(a: Box<::GetProp>) -> Box { + a +} + +fn dangling(a: &str) -> Box { + bad(Box::new(a)) +} + +fn main() { + let mut s = "hello".to_string(); + let x = dangling(&s); + s = String::new(); + println!("{:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3521-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3521-2.rs new file mode 100644 index 000000000000..46baa58fdbf6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3521-2.rs @@ -0,0 +1,9 @@ +fn main() { + let foo = 100; + + static y: isize = foo + 1; +// { dg-error ".E0435." "" { target *-*-* } .-1 } + + println!("{}", y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3521.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3521.rs new file mode 100644 index 000000000000..f79e46098070 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3521.rs @@ -0,0 +1,12 @@ +fn main() { + let foo = 100; + + #[derive(Debug)] + enum Stuff { + Bar = foo +// { dg-error ".E0435." "" { target *-*-* } .-1 } + } + + println!("{:?}", Stuff::Bar); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35241.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35241.rs new file mode 100644 index 000000000000..5a3c52ba1b69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35241.rs @@ -0,0 +1,6 @@ +struct Foo(u32); + +fn test() -> Foo { Foo } // { dg-error ".E0308." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35376.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35376.rs new file mode 100644 index 000000000000..c1d994b20eb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35376.rs @@ -0,0 +1,44 @@ +// check-pass +#![feature(specialization)] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + +pub trait Alpha { } + +pub trait Beta { + type Event; +} + +pub trait Delta { + type Handle; + fn process(&self); +} + +pub struct Parent(A, T); + +impl Delta for Parent +where A: Alpha, + T: Delta, + T::Handle: Beta::Event> { + type Handle = Handle; + default fn process(&self) { + unimplemented!() + } +} + +impl Delta for Parent +where A: Alpha + Alpha, + T: Delta, + T::Handle: Beta::Event> { + fn process(&self) { + unimplemented!() + } +} + +pub struct Handle; + +impl Beta for Handle { + type Event = (); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35423.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35423.rs new file mode 100644 index 000000000000..b9cf84921b25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35423.rs @@ -0,0 +1,10 @@ +// run-pass +fn main () { + let x = 4; + match x { + ref r if *r < 0 => println!("got negative num {} < 0", r), + e @ 1 ..= 100 => println!("got number within range [1,100] {}", e), + _ => println!("no"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35450.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35450.rs new file mode 100644 index 000000000000..59ffe1899dd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35450.rs @@ -0,0 +1,6 @@ +macro_rules! m { ($($t:tt)*) => { $($t)* } } + +fn main() { + m!($t); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35546.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35546.rs new file mode 100644 index 000000000000..0587b346fff0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35546.rs @@ -0,0 +1,21 @@ +// build-pass +#![allow(dead_code)] +// Regression test for #35546. Check that we are able to codegen +// this. Before we had problems because of the drop glue signature +// around dropping a trait object (specifically, when dropping the +// `value` field of `Node`). + +struct Node { + next: Option>>, + value: T, +} + +fn clear(head: &mut Option>>) { + match head.take() { + Some(node) => *head = node.next, + None => (), + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3556.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3556.rs new file mode 100644 index 000000000000..4fa872ea1b1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3556.rs @@ -0,0 +1,37 @@ +// run-pass +#![allow(dead_code)] + +#[derive(Debug)] +enum Token { + Text(String), + ETag(Vec, String), + UTag(Vec, String), + Section(Vec, bool, Vec, String, + String, String, String, String), + IncompleteSection(Vec, bool, String, bool), + Partial(String, String, String), +} + +fn check_strs(actual: &str, expected: &str) -> bool +{ + if actual != expected + { + println!("Found {}, but expected {}", actual, expected); + return false; + } + return true; +} + +pub fn main() +{ + let t = Token::Text("foo".to_string()); + let u = Token::Section(vec!["alpha".to_string()], + true, + vec![t], + "foo".to_string(), + "foo".to_string(), "foo".to_string(), "foo".to_string(), + "foo".to_string()); + let v = format!("{:?}", u); // this is the line that causes the seg fault + assert!(!v.is_empty()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35570.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35570.rs new file mode 100644 index 000000000000..fa46a4dcb86e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35570.rs @@ -0,0 +1,30 @@ +// check-pass + +use std::mem; + +trait Trait1 {} +trait Trait2<'a> { + type Ty; +} + +fn _ice(param: Box Trait1<<() as Trait2<'a>>::Ty>>) { + let _e: (usize, usize) = unsafe{mem::transmute(param)}; +} + +trait Lifetime<'a> { + type Out; +} +impl<'a> Lifetime<'a> for () { + type Out = &'a (); +} +fn foo<'a>(x: &'a ()) -> <() as Lifetime<'a>>::Out { + x +} + +fn takes_lifetime(_f: for<'a> fn(&'a ()) -> <() as Lifetime<'a>>::Out) { +} + +fn main() { + takes_lifetime(foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3559.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3559.rs new file mode 100644 index 000000000000..a5d1a9ffa549 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3559.rs @@ -0,0 +1,19 @@ +// run-pass +use std::collections::HashMap; + +fn check_strs(actual: &str, expected: &str) -> bool { + if actual != expected { + println!("Found {}, but expected {}", actual, expected); + return false; + } + return true; +} + +pub fn main() { + let mut table = HashMap::new(); + table.insert("one".to_string(), 1); + table.insert("two".to_string(), 2); + assert!(check_strs(&format!("{:?}", table), "{\"one\": 1, \"two\": 2}") || + check_strs(&format!("{:?}", table), "{\"two\": 2, \"one\": 1}")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35600.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35600.rs new file mode 100644 index 000000000000..d41ca82d702a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35600.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(non_camel_case_types)] +#![allow(unused_variables)] + +trait Foo { + type bar; + fn bar(); +} + +impl Foo for () { + type bar = (); + fn bar() {} +} + +fn main() { + let x: <() as Foo>::bar = (); + <()>::bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3563-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3563-2.rs new file mode 100644 index 000000000000..82f5fb05c302 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3563-2.rs @@ -0,0 +1,15 @@ +// check-pass +// pretty-expanded FIXME #23616 + +trait Canvas { + fn add_point(&self, point: &isize); + fn add_points(&self, shapes: &[isize]) { + for pt in shapes { + self.add_point(pt) + } + } + +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3563-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3563-3.rs new file mode 100644 index 000000000000..bccf855b9e98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3563-3.rs @@ -0,0 +1,181 @@ +// run-pass +#![allow(unused_imports)] +#![allow(non_snake_case)] + +// ASCII art shape renderer. Demonstrates traits, impls, operator overloading, +// non-copyable struct, unit testing. To run execute: rustc --test shapes.rs && +// ./shapes + +// Rust's std library is tightly bound to the language itself so it is +// automatically linked in. However the extra library is designed to be +// optional (for code that must run on constrained environments like embedded +// devices or special environments like kernel code) so it must be explicitly +// linked in. + +// Extern mod controls linkage. Use controls the visibility of names to modules +// that are already linked in. Using WriterUtil allows us to use the write_line +// method. + +use std::fmt; +use std::iter::repeat; +use std::slice; + +// Represents a position on a canvas. +#[derive(Copy, Clone)] +struct Point { + x: isize, + y: isize, +} + +// Represents an offset on a canvas. (This has the same structure as a Point. +// but different semantics). +#[derive(Copy, Clone)] +struct Size { + width: isize, + height: isize, +} + +#[derive(Copy, Clone)] +struct Rect { + top_left: Point, + size: Size, +} + +// Contains the information needed to do shape rendering via ASCII art. +struct AsciiArt { + width: usize, + height: usize, + fill: char, + lines: Vec > , + + // This struct can be quite large so we'll disable copying: developers need + // to either pass these structs around via references or move them. +} + +impl Drop for AsciiArt { + fn drop(&mut self) {} +} + +// It's common to define a constructor sort of function to create struct instances. +// If there is a canonical constructor it is typically named the same as the type. +// Other constructor sort of functions are typically named from_foo, from_bar, etc. +fn AsciiArt(width: usize, height: usize, fill: char) -> AsciiArt { + // Build a vector of vectors containing blank characters for each position in + // our canvas. + let lines = vec![vec!['.'; width]; height]; + + // Rust code often returns values by omitting the trailing semi-colon + // instead of using an explicit return statement. + AsciiArt {width: width, height: height, fill: fill, lines: lines} +} + +// Methods particular to the AsciiArt struct. +impl AsciiArt { + fn add_pt(&mut self, x: isize, y: isize) { + if x >= 0 && x < self.width as isize { + if y >= 0 && y < self.height as isize { + // Note that numeric types don't implicitly convert to each other. + let v = y as usize; + let h = x as usize; + + // Vector subscripting will normally copy the element, but &v[i] + // will return a reference which is what we need because the + // element is: + // 1) potentially large + // 2) needs to be modified + let row = &mut self.lines[v]; + row[h] = self.fill; + } + } + } +} + +// Allows AsciiArt to be converted to a string using the libcore ToString trait. +// Note that the %s fmt! specifier will not call this automatically. +impl fmt::Display for AsciiArt { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Convert each line into a string. + let lines = self.lines.iter() + .map(|line| line.iter().cloned().collect()) + .collect::>(); + + // Concatenate the lines together using a new-line. + write!(f, "{}", lines.join("\n")) + } +} + +// This is similar to an interface in other languages: it defines a protocol which +// developers can implement for arbitrary concrete types. +trait Canvas { + fn add_point(&mut self, shape: Point); + fn add_rect(&mut self, shape: Rect); + + // Unlike interfaces traits support default implementations. + // Got an ICE as soon as I added this method. + fn add_points(&mut self, shapes: &[Point]) { + for pt in shapes {self.add_point(*pt)}; + } +} + +// Here we provide an implementation of the Canvas methods for AsciiArt. +// Other implementations could also be provided (e.g., for PDF or Apple's Quartz) +// and code can use them polymorphically via the Canvas trait. +impl Canvas for AsciiArt { + fn add_point(&mut self, shape: Point) { + self.add_pt(shape.x, shape.y); + } + + fn add_rect(&mut self, shape: Rect) { + // Add the top and bottom lines. + for x in shape.top_left.x..shape.top_left.x + shape.size.width { + self.add_pt(x, shape.top_left.y); + self.add_pt(x, shape.top_left.y + shape.size.height - 1); + } + + // Add the left and right lines. + for y in shape.top_left.y..shape.top_left.y + shape.size.height { + self.add_pt(shape.top_left.x, y); + self.add_pt(shape.top_left.x + shape.size.width - 1, y); + } + } +} + +// Rust's unit testing framework is currently a bit under-developed so we'll use +// this little helper. +pub fn check_strs(actual: &str, expected: &str) -> bool { + if actual != expected { + println!("Found:\n{}\nbut expected\n{}", actual, expected); + return false; + } + return true; +} + + +fn test_ascii_art_ctor() { + let art = AsciiArt(3, 3, '*'); + assert!(check_strs(&art.to_string(), "...\n...\n...")); +} + + +fn test_add_pt() { + let mut art = AsciiArt(3, 3, '*'); + art.add_pt(0, 0); + art.add_pt(0, -10); + art.add_pt(1, 2); + assert!(check_strs(&art.to_string(), "*..\n...\n.*.")); +} + + +fn test_shapes() { + let mut art = AsciiArt(4, 4, '*'); + art.add_rect(Rect {top_left: Point {x: 0, y: 0}, size: Size {width: 4, height: 4}}); + art.add_point(Point {x: 2, y: 2}); + assert!(check_strs(&art.to_string(), "****\n*..*\n*.**\n****")); +} + +pub fn main() { + test_ascii_art_ctor(); + test_add_pt(); + test_shapes(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35668.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35668.rs new file mode 100644 index 000000000000..41369707c78e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35668.rs @@ -0,0 +1,13 @@ +fn func<'a, T>(a: &'a [T]) -> impl Iterator { + a.iter().map(|a| a*a) +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} + +fn main() { + let a = (0..30).collect::>(); + + for k in func(&a) { + println!("{}", k); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35675.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35675.rs new file mode 100644 index 000000000000..9f766e6dbe05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35675.rs @@ -0,0 +1,43 @@ +// these two HELPs are actually in a new line between this line and the `enum Fruit` line +enum Fruit { + Apple(i64), + Orange(i64), +} + +fn should_return_fruit() -> Apple { +// { dg-error ".E0412." "" { target *-*-* } .-1 } + Apple(5) +// { dg-error ".E0425." "" { target *-*-* } .-1 } +} + +fn should_return_fruit_too() -> Fruit::Apple { +// { dg-error ".E0573." "" { target *-*-* } .-1 } + Apple(5) +// { dg-error ".E0425." "" { target *-*-* } .-1 } +} + +fn foo() -> Ok { +// { dg-error ".E0573." "" { target *-*-* } .-1 } + Ok(()) +} + +fn bar() -> Variant3 { +// { dg-error ".E0412." "" { target *-*-* } .-1 } +} + +fn qux() -> Some { +// { dg-error ".E0573." "" { target *-*-* } .-1 } + Some(1) +} + +fn main() {} + +mod x { + pub enum Enum { + Variant1, + Variant2(), + Variant3(usize), + Variant4 {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35677.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35677.rs new file mode 100644 index 000000000000..8d680b649a39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35677.rs @@ -0,0 +1,9 @@ +use std::collections::HashSet; + +fn is_subset(this: &HashSet, other: &HashSet) -> bool { + this.is_subset(other) +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3574.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3574.rs new file mode 100644 index 000000000000..4d33dedf86de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3574.rs @@ -0,0 +1,15 @@ +// run-pass +// rustc --test match_borrowed_str.rs.rs && ./match_borrowed_str.rs + + +fn compare(x: &str, y: &str) -> bool { + match x { + "foo" => y == "foo", + _ => y == "bar", + } +} + +pub fn main() { + assert!(compare("foo", "foo")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35815.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35815.rs new file mode 100644 index 000000000000..8311cbc2274d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35815.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +use std::mem; + +struct Foo { + a: i64, + b: bool, + c: T, +} + +fn main() { + let foo: &Foo = &Foo { a: 1, b: false, c: 2i32 }; + let foo_unsized: &Foo = foo; + assert_eq!(mem::size_of_val(foo), mem::size_of_val(foo_unsized)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35869.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35869.rs new file mode 100644 index 000000000000..b7aa9d2e8b6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35869.rs @@ -0,0 +1,22 @@ +trait Foo { + fn foo(_: fn(u8) -> ()); + fn bar(_: Option); + fn baz(_: (u8, u16)); + fn qux() -> u8; +} + +struct Bar; + +impl Foo for Bar { + fn foo(_: fn(u16) -> ()) {} +// { dg-error ".E0053." "" { target *-*-* } .-1 } + fn bar(_: Option) {} +// { dg-error ".E0053." "" { target *-*-* } .-1 } + fn baz(_: (u16, u16)) {} +// { dg-error ".E0053." "" { target *-*-* } .-1 } + fn qux() -> u16 { 5u16 } +// { dg-error ".E0053." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35976.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35976.rs new file mode 100644 index 000000000000..35295469deda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35976.rs @@ -0,0 +1,21 @@ +mod private { + pub trait Future { + fn wait(&self) where Self: Sized; + } + + impl Future for Box { + fn wait(&self) { } + } +} + +//use private::Future; + +fn bar(arg: Box) { + arg.wait(); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-35988.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-35988.rs new file mode 100644 index 000000000000..c8f8102dd1b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-35988.rs @@ -0,0 +1,7 @@ +enum E { + V([Box]), +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3601.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3601.rs new file mode 100644 index 000000000000..210581b3637b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3601.rs @@ -0,0 +1,35 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] + +struct HTMLImageData { + image: Option +} + +struct ElementData { + kind: Box +} + +enum ElementKind { + HTMLImageElement(HTMLImageData) +} + +enum NodeKind { + Element(ElementData) +} + +struct NodeData { + kind: Box, +} + +fn main() { + let mut id = HTMLImageData { image: None }; + let ed = ElementData { kind: box ElementKind::HTMLImageElement(id) }; + let n = NodeData {kind : box NodeKind::Element(ed)}; + // n.b. span could be better + match n.kind { + box NodeKind::Element(ed) => match ed.kind { // { dg-error ".E0004." "" { target *-*-* } } + box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true } + }, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36023.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36023.rs new file mode 100644 index 000000000000..3aba9baf9f7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36023.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(unused_variables)] +use std::ops::Deref; + +fn main() { + if env_var("FOOBAR").as_ref().map(Deref::deref).ok() == Some("yes") { + panic!() + } + + let env_home: Result = Ok("foo-bar-baz".to_string()); + let env_home = env_home.as_ref().map(Deref::deref).ok(); + + if env_home == Some("") { panic!() } +} + +#[inline(never)] +fn env_var(s: &str) -> Result { + Err(VarError::NotPresent) +} + +pub enum VarError { + NotPresent, + NotUnicode(String), +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36036-associated-type-layout.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36036-associated-type-layout.rs new file mode 100644 index 000000000000..1f4b71ed97b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36036-associated-type-layout.rs @@ -0,0 +1,28 @@ +// run-pass +// Issue 36036: computing the layout of a type composed from another +// trait's associated type caused compiler to ICE when the associated +// type was allowed to be unsized, even though the known instantiated +// type is itself sized. + +#![allow(dead_code)] + +trait Context { + type Container: ?Sized; +} + +impl Context for u16 { + type Container = u8; +} + +struct Wrapper { + container: &'static C::Container +} + +fn foobar(_: Wrapper) {} + +static VALUE: u8 = 0; + +fn main() { + foobar(Wrapper { container: &VALUE }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36053.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36053.rs new file mode 100644 index 000000000000..9c6e4fd754ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36053.rs @@ -0,0 +1,23 @@ +// run-pass +// Regression test for #36053. ICE was caused due to obligations being +// added to a special, dedicated fulfillment cx during a +// probe. Problem seems to be related to the particular definition of +// `FusedIterator` in std but I was not able to isolate that into an +// external crate. + +use std::iter::FusedIterator; + +struct Thing<'a>(&'a str); +impl<'a> Iterator for Thing<'a> { + type Item = &'a str; + fn next(&mut self) -> Option<&'a str> { + None + } +} + +impl<'a> FusedIterator for Thing<'a> {} + +fn main() { + Thing("test").fuse().filter(|_| true).count(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36075.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36075.rs new file mode 100644 index 000000000000..6bf105889cb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36075.rs @@ -0,0 +1,15 @@ +// check-pass +#![allow(dead_code)] +trait DeclarationParser { + type Declaration; +} + +struct DeclarationListParser<'i, I, P> + where P: DeclarationParser +{ + input: &'i (), + parser: P +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36082.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36082.rs new file mode 100644 index 000000000000..bcd66068091c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36082.rs @@ -0,0 +1,16 @@ +use std::cell::RefCell; + +fn main() { + let mut r = 0; + let s = 0; + let x = RefCell::new((&mut r,s)); + + let val: &_ = x.borrow().0; +// { dg-error ".E0716." "" { target *-*-* } .-1 } +// { dg-note ".E0716." "" { target *-*-* } .-2 } +// { dg-note ".E0716." "" { target *-*-* } .-3 } +// { dg-note ".E0716." "" { target *-*-* } .-4 } + println!("{}", val); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3609.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3609.rs new file mode 100644 index 000000000000..d72231766357 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3609.rs @@ -0,0 +1,31 @@ +// check-pass +#![allow(unused_must_use)] +#![allow(dead_code)] +#![allow(unused_mut)] +use std::thread; +use std::sync::mpsc::Sender; + +type RingBuffer = Vec ; +type SamplesFn = Box; + +enum Msg +{ + GetSamples(String, SamplesFn), // sample set name, callback which receives samples +} + +fn foo(name: String, samples_chan: Sender) { + thread::spawn(move|| { + let mut samples_chan = samples_chan; + + let callback: SamplesFn = Box::new(move |buffer| { + for i in 0..buffer.len() { + println!("{}: {}", i, buffer[i]) + } + }); + + samples_chan.send(Msg::GetSamples(name.clone(), callback)); + }).join(); +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36116.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36116.rs new file mode 100644 index 000000000000..4189bf5f7cb2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36116.rs @@ -0,0 +1,26 @@ +// Unnecessary path disambiguator is ok + +// check-pass + +macro_rules! m { + ($p: path) => { + let _ = $p(0); + let _: $p; + } +} + +struct Foo { + _a: T, +} + +struct S(T); + +fn f() { + let f = Some(Foo { _a: 42 }).map(|a| a as Foo::); + let g: Foo:: = Foo { _a: 42 }; + + m!(S::); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36139-normalize-closure-sig.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36139-normalize-closure-sig.rs new file mode 100644 index 000000000000..829ecd5622e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36139-normalize-closure-sig.rs @@ -0,0 +1,20 @@ +// run-pass +// Previously the closure's argument would be inferred to +// >::Item, causing an error in MIR type +// checking + +trait ITrait<'a> {type Item;} + +struct S {} + +impl<'a> ITrait<'a> for S { type Item = &'a mut usize; } + +fn m(_: F) + where I: for<'a> ITrait<'a>, + F: for<'a> FnMut(>::Item) { } + + +fn main() { + m::(|x| { *x += 1; }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36163.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36163.rs new file mode 100644 index 000000000000..fb419e0e0ab8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36163.rs @@ -0,0 +1,8 @@ +const A: isize = Foo::B as isize; + +enum Foo { + B = A, // { dg-error ".E0391." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36260.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36260.rs new file mode 100644 index 000000000000..2e0ef17562b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36260.rs @@ -0,0 +1,14 @@ +// run-pass +// Make sure this compiles without getting a linker error because of missing +// drop-glue because the collector missed adding drop-glue for the closure: + +fn create_fn() -> Box { + let text = String::new(); + + Box::new(move || { let _ = &text; }) +} + +fn main() { + let _ = create_fn(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36278-prefix-nesting.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36278-prefix-nesting.rs new file mode 100644 index 000000000000..b3cf55287dee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36278-prefix-nesting.rs @@ -0,0 +1,20 @@ +// run-pass +// Issue 36278: On an unsized struct with >1 level of nontrivial +// nesting, ensure we are computing dynamic size of prefix correctly. + +use std::mem; + +const SZ: usize = 100; +struct P([u8; SZ], T); + +type Ack = P>; + +fn main() { + let size_of_sized; let size_of_unsized; + let x: Box> = Box::new(P([0; SZ], P([0; SZ], [0; 0]))); + size_of_sized = mem::size_of_val::>(&x); + let y: Box> = x; + size_of_unsized = mem::size_of_val::>(&y); + assert_eq!(size_of_sized, size_of_unsized); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36299.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36299.rs new file mode 100644 index 000000000000..f478287b5cdc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36299.rs @@ -0,0 +1,6 @@ +struct Foo<'a, A> {} +// { dg-error ".E0392." "" { target *-*-* } .-1 } +// { dg-error ".E0392." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36379.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36379.rs new file mode 100644 index 000000000000..3e5752b592a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36379.rs @@ -0,0 +1,6 @@ +// check-pass + +fn _test() -> impl Default { } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36381.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36381.rs new file mode 100644 index 000000000000..fcf589204d55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36381.rs @@ -0,0 +1,26 @@ +// run-pass +// Regression test for #36381. The monomorphization collector was asserting that +// there are no projection types, but the `<&str as +// StreamOnce>::Position` projection contained a late-bound region, +// and we don't currently normalize in that case until the function is +// actually invoked. + +pub trait StreamOnce { + type Position; +} + +impl<'a> StreamOnce for &'a str { + type Position = usize; +} + +pub fn parser(_: F) { +} + +fn follow(_: &str) -> <&str as StreamOnce>::Position { + panic!() +} + +fn main() { + parser(follow); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36400.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36400.rs new file mode 100644 index 000000000000..bac426bf0024 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36400.rs @@ -0,0 +1,7 @@ +fn f(x: &mut u32) {} + +fn main() { + let x = Box::new(3); + f(&mut *x); // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36401.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36401.rs new file mode 100644 index 000000000000..3adf8ef97884 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36401.rs @@ -0,0 +1,17 @@ +// run-pass +#[derive(Debug)] +pub enum Event { + Key(u8), + Resize, + Unknown(u16), +} + +static XTERM_SINGLE_BYTES : [(u8, Event); 1] = [(1, Event::Resize)]; + +fn main() { + match XTERM_SINGLE_BYTES[0] { + (1, Event::Resize) => {}, + ref bad => panic!("unexpected {:?}", bad) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36474.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36474.rs new file mode 100644 index 000000000000..484a6c3eaad3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36474.rs @@ -0,0 +1,32 @@ +// run-pass +fn main() { + remove_axis(&3, 0); +} + +trait Dimension { + fn slice(&self) -> &[usize]; +} + +impl Dimension for () { + fn slice(&self) -> &[usize] { &[] } +} + +impl Dimension for usize { + fn slice(&self) -> &[usize] { + unsafe { + ::std::slice::from_raw_parts(self, 1) + } + } +} + +fn remove_axis(value: &usize, axis: usize) -> () { + let tup = (); + let mut it = tup.slice().iter(); + for (i, _) in value.slice().iter().enumerate() { + if i == axis { + continue; + } + it.next(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3656.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3656.rs new file mode 100644 index 000000000000..0e3b890f939b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3656.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(dead_code)] +#![allow(improper_ctypes)] + +// Issue #3656 +// Incorrect struct size computation in the FFI, because of not taking +// the alignment of elements into account. + +// pretty-expanded FIXME #23616 +// ignore-wasm32-bare no libc to test with + +#![feature(rustc_private)] + +extern crate libc; +use libc::{c_uint, c_void}; + +pub struct KEYGEN { + hash_algorithm: [c_uint; 2], + count: u32, + salt: *const c_void, + salt_size: u32, +} + +extern { + // Bogus signature, just need to test if it compiles. + pub fn malloc(data: KEYGEN); +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36617.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36617.rs new file mode 100644 index 000000000000..98e5c56f7447 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36617.rs @@ -0,0 +1,6 @@ +#![derive(Copy)] // { dg-error ".E0774." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36638.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36638.rs new file mode 100644 index 000000000000..ae3a5f79b0e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36638.rs @@ -0,0 +1,9 @@ +struct Foo(Self); +// { dg-error ".E0392." "" { target *-*-* } .-1 } +// { dg-error ".E0392." "" { target *-*-* } .-2 } + +trait Bar {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3668-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3668-2.rs new file mode 100644 index 000000000000..617b5e9650e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3668-2.rs @@ -0,0 +1,7 @@ +fn f(x:isize) { + static child: isize = x + 1; +// { dg-error ".E0435." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3668.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3668.rs new file mode 100644 index 000000000000..efc634fbfa2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3668.rs @@ -0,0 +1,15 @@ +struct P { child: Option> } +trait PTrait { + fn getChildOption(&self) -> Option>; +} + +impl PTrait for P { + fn getChildOption(&self) -> Option> { + static childVal: Box

= self.child.get(); +// { dg-error ".E0435." "" { target *-*-* } .-1 } + panic!(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36708.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36708.rs new file mode 100644 index 000000000000..97d0e12f2d0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36708.rs @@ -0,0 +1,13 @@ +// aux-build:issue-36708.rs + +extern crate issue_36708 as lib; + +struct Bar; + +impl lib::Foo for Bar { + fn foo() {} +// { dg-error ".E0049." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36744-bitcast-args-if-needed.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36744-bitcast-args-if-needed.rs new file mode 100644 index 000000000000..f98472c79d60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36744-bitcast-args-if-needed.rs @@ -0,0 +1,24 @@ +// run-pass +// This tests for an ICE (and, if ignored, subsequent LLVM abort) when +// a lifetime-parametric fn is passed into a context whose expected +// type has a differing lifetime parameterization. + +struct A<'a> { + _a: &'a i32, +} + +fn call(s: T, functions: &Vec fn(&'n T)>) { + for function in functions { + function(&s); + } +} + +fn f(a: &A) { println!("a holds {}", a._a); } + +fn main() { + let a = A { _a: &10 }; + + let vec: Vec fn(&'u A<'v>)> = vec![f]; + call(a, &vec); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36744-without-calls.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36744-without-calls.rs new file mode 100644 index 000000000000..556b918656a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36744-without-calls.rs @@ -0,0 +1,14 @@ +// build-pass +// Tests for an LLVM abort when storing a lifetime-parametric fn into +// context that is expecting one that is not lifetime-parametric +// (i.e., has no `for <'_>`). + +pub struct A<'a>(&'a ()); +pub struct S(T); + +pub fn bad<'s>(v: &mut S)>, y: S fn(A<'b>)>) { + *v = y; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36768.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36768.rs new file mode 100644 index 000000000000..a638d299fb1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36768.rs @@ -0,0 +1,10 @@ +// run-pass +// compile-flags:--test +#![deny(private_in_public)] + +#[test] fn foo() {} +mod foo {} + +#[test] fn core() {} +extern crate core; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36786-resolve-call.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36786-resolve-call.rs new file mode 100644 index 000000000000..0320241ebd42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36786-resolve-call.rs @@ -0,0 +1,9 @@ +// run-pass +// Ensure that types that rely on obligations are autoderefed +// correctly + +fn main() { + let x : Vec> = vec![Box::new(|| ())]; + x[0]() +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36792.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36792.rs new file mode 100644 index 000000000000..4f15acaa1370 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36792.rs @@ -0,0 +1,8 @@ +// run-pass +fn foo() -> impl Copy { + foo +} +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3680.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3680.rs new file mode 100644 index 000000000000..925a26a79249 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3680.rs @@ -0,0 +1,10 @@ +fn main() { + match None { + Err(_) => () +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36816.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36816.rs new file mode 100644 index 000000000000..3780cf0cc757 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36816.rs @@ -0,0 +1,8 @@ +// run-pass +macro_rules! m { () => { 1 } } +macro_rules! n { () => { 1 + m!() } } + +fn main() { + let _: [u32; n!()] = [0, 0]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3683.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3683.rs new file mode 100644 index 000000000000..3488f456fcb2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3683.rs @@ -0,0 +1,19 @@ +// run-pass + +trait Foo { + fn a(&self) -> isize; + fn b(&self) -> isize { + self.a() + 2 + } +} + +impl Foo for isize { + fn a(&self) -> isize { + 3 + } +} + +pub fn main() { + assert_eq!(3.b(), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36836.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36836.rs new file mode 100644 index 000000000000..57732f073af8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36836.rs @@ -0,0 +1,16 @@ +// Previously, in addition to the real cause of the problem as seen below, +// the compiler would tell the user: +// +// ``` +// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or +// predicates +// ``` +// +// With this test, we check that only the relevant error is emitted. + +trait Foo {} + +impl Foo for Bar {} // { dg-error ".E0412." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36839.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36839.rs new file mode 100644 index 000000000000..9a2b236be420 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36839.rs @@ -0,0 +1,22 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-36856.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36856.rs new file mode 100644 index 000000000000..62f8fa6462f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36856.rs @@ -0,0 +1,17 @@ +// run-pass +// Regression test for #36856. + +// compile-flags:-g +// ignore-asmjs wasm2js does not support source maps yet + +fn g() -> bool { + false +} + +pub fn main() { + let a = !g(); + if a != !g() { + panic!(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36881.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36881.rs new file mode 100644 index 000000000000..bf33e4981e91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36881.rs @@ -0,0 +1,7 @@ +// aux-build:issue-36881-aux.rs + +fn main() { + extern crate issue_36881_aux; + use issue_36881_aux::Foo; // { dg-error ".E0432." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36936.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36936.rs new file mode 100644 index 000000000000..23bc34a3a837 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36936.rs @@ -0,0 +1,27 @@ +// run-pass +// check that casts are not being treated as lexprs. + +fn main() { + let mut a = 0i32; + let b = &(a as i32); + a = 1; + assert_ne!(&a as *const i32, b as *const i32); + assert_eq!(*b, 0); + + assert_eq!(issue_36936(), 1); +} + + +struct A(u32); + +impl Drop for A { + fn drop(&mut self) { + self.0 = 0; + } +} + +fn issue_36936() -> u32 { + let a = &(A(1) as A); + a.0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-36954.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-36954.rs new file mode 100644 index 000000000000..977834218ee5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-36954.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:issue-36954.rs + +extern crate issue_36954 as lib; + +fn main() { + let _ = lib::FOO; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3702-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3702-2.rs new file mode 100644 index 000000000000..9566aa15d2f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3702-2.rs @@ -0,0 +1,21 @@ +pub trait ToPrimitive { + fn to_int(&self) -> isize { 0 } +} + +impl ToPrimitive for i32 {} +impl ToPrimitive for isize {} + +trait Add { + fn to_int(&self) -> isize; + fn add_dynamic(&self, other: &dyn Add) -> isize; +} + +impl Add for isize { + fn to_int(&self) -> isize { *self } + fn add_dynamic(&self, other: &dyn Add) -> isize { + self.to_int() + other.to_int() // { dg-error ".E0034." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3702.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3702.rs new file mode 100644 index 000000000000..e044a54c6c49 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3702.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] + +pub fn main() { + trait Text { + fn to_string(&self) -> String; + } + + fn to_string(t: Box) { + println!("{}", (*t).to_string()); + } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37026.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37026.rs new file mode 100644 index 000000000000..a401024cdebc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37026.rs @@ -0,0 +1,9 @@ +// aux-build:empty-struct.rs + +extern crate empty_struct; + +fn main() { + let empty_struct::XEmpty2 = (); // { dg-error ".E0308." "" { target *-*-* } } + let empty_struct::XEmpty6(..) = (); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37051.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37051.rs new file mode 100644 index 000000000000..add4cffa1bd4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37051.rs @@ -0,0 +1,20 @@ +// check-pass +// ignore-compare-mode-chalk + +#![feature(associated_type_defaults)] + +trait State: Sized { + type NextState: State = StateMachineEnded; + fn execute(self) -> Option; +} + +struct StateMachineEnded; + +impl State for StateMachineEnded { + fn execute(self) -> Option { + None + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3707.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3707.rs new file mode 100644 index 000000000000..832fbff1bc4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3707.rs @@ -0,0 +1,19 @@ +struct Obj { + member: usize +} + +impl Obj { + pub fn boom() -> bool { + return 1+1 == 2 + } + pub fn chirp(&self) { + self.boom(); // { dg-error ".E0599." "" { target *-*-* } } + } +} + +fn main() { + let o = Obj { member: 0 }; + o.chirp(); + 1 + 1; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37109.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37109.rs new file mode 100644 index 000000000000..8fc91992a550 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37109.rs @@ -0,0 +1,17 @@ +// run-pass +trait ToRef<'a> { + type Ref: 'a; +} + +impl<'a, U: 'a> ToRef<'a> for U { + type Ref = &'a U; +} + +fn example<'a, T>(value: &'a T) -> (>::Ref, u32) { + (value, 0) +} + +fn main() { + example(&0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37131.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37131.rs new file mode 100644 index 000000000000..5936916d56b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37131.rs @@ -0,0 +1,10 @@ +// Tests that compiling for a target which is not installed will result in a helpful +// error message. + +// compile-flags: --target=thumbv6m-none-eabi +// ignore-arm +// needs-llvm-components: arm + +// error-pattern:target may not be installed +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37175.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37175.rs new file mode 100644 index 000000000000..851ba7382c05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37175.rs @@ -0,0 +1,6 @@ +// run-pass +macro_rules! m { (<$t:ty>) => { stringify!($t) } } +fn main() { + println!("{}", m!(>)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37222.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37222.rs new file mode 100644 index 000000000000..838d084532ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37222.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +#[derive(Debug, PartialEq)] +enum Bar { + A(i64), + B(i32), + C, +} + +#[derive(Debug, PartialEq)] +struct Foo(Bar, u8); + +static FOO: [Foo; 2] = [Foo(Bar::C, 0), Foo(Bar::C, 0xFF)]; + +fn main() { + assert_eq!(&FOO[1], &Foo(Bar::C, 0xFF)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37291/auxiliary/lib.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37291/auxiliary/lib.rs new file mode 100644 index 000000000000..4767ae16a583 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37291/auxiliary/lib.rs @@ -0,0 +1,43 @@ +#![crate_type = "lib"] + +use std::ops::Mul; + +pub trait A {} +pub trait B { + type AT: A; +} +pub trait C { + type BT: B; +} + +pub struct AV; +impl A for AV {} + +pub struct BV; +impl B for BV { + type AT = AV; +} + +pub struct CV; +impl C for CV { + type BT = BV; +} + +pub struct WrapperB(pub T); +pub struct WrapperC(pub T); + +impl Mul::AT>> for WrapperC + where C1: C +{ + type Output = u8; + fn mul(self, _: WrapperB<::AT>) -> Self::Output { + loop {} + } +} +impl Mul> for WrapperC { + type Output = u8; + fn mul(self, _: WrapperC) -> Self::Output { + loop {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37291/main.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37291/main.rs new file mode 100644 index 000000000000..6390088d85bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37291/main.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(unused_imports)] +// aux-build:lib.rs + +// Regression test for #37291. The problem was that the starting +// environment for a specialization check was not including the +// where-clauses from the impl when attempting to normalize the impl's +// trait-ref, so things like `::Item` could not resolve, +// since the `C: Foo` trait bound was not included in the environment. + +extern crate lib; + +use lib::{CV, WrapperB, WrapperC}; + +fn main() { + let a = WrapperC(CV); + let b = WrapperC(CV); + if false { + let _ = a * b; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37311-type-length-limit/issue-37311.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37311-type-length-limit/issue-37311.rs new file mode 100644 index 000000000000..11c23bdc8b37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37311-type-length-limit/issue-37311.rs @@ -0,0 +1,24 @@ +// build-fail +// normalize-stderr-test: ".nll/" -> "/" + +trait Mirror { + type Image; +} + +impl Mirror for T { type Image = T; } + +trait Foo { + fn recurse(&self); +} + +impl Foo for T { + #[allow(unconditional_recursion)] + fn recurse(&self) { + (self, self).recurse(); // { dg-error "" "" { target *-*-* } } + } +} + +fn main() { + ().recurse(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37323.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37323.rs new file mode 100644 index 000000000000..cfbaec7c272c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37323.rs @@ -0,0 +1,21 @@ +// check-pass +// compile-flags: -Zsave-analysis + +#![feature(rustc_attrs)] +#![allow(warnings)] + +#[derive(Debug)] +struct Point { +} + +struct NestedA<'a, 'b> { + x: &'a NestedB<'b> +} + +struct NestedB<'a> { + x: &'a i32, +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37366.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37366.rs new file mode 100644 index 000000000000..53fcc03f256b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37366.rs @@ -0,0 +1,16 @@ +// check-pass +// ignore-emscripten + +#![feature(llvm_asm)] + +macro_rules! interrupt_handler { + () => { + unsafe fn _interrupt_handler() { + llvm_asm!("pop eax" :::: "intel"); + } + } +} +interrupt_handler!{} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3743.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3743.rs new file mode 100644 index 000000000000..382f8ac9bca5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3743.rs @@ -0,0 +1,56 @@ +// run-pass +// If `Mul` used an associated type for its output, this test would +// work more smoothly. + +use std::ops::Mul; + +#[derive(Copy, Clone)] +struct Vec2 { + x: f64, + y: f64 +} + +// methods we want to export as methods as well as operators +impl Vec2 { +#[inline(always)] + fn vmul(self, other: f64) -> Vec2 { + Vec2 { x: self.x * other, y: self.y * other } + } +} + +// Right-hand-side operator visitor pattern +trait RhsOfVec2Mul { + type Result; + + fn mul_vec2_by(&self, lhs: &Vec2) -> Self::Result; +} + +// Vec2's implementation of Mul "from the other side" using the above trait +impl> Mul for Vec2 { + type Output = Res; + + fn mul(self, rhs: Rhs) -> Res { rhs.mul_vec2_by(&self) } +} + +// Implementation of 'f64 as right-hand-side of Vec2::Mul' +impl RhsOfVec2Mul for f64 { + type Result = Vec2; + + fn mul_vec2_by(&self, lhs: &Vec2) -> Vec2 { lhs.vmul(*self) } +} + +// Usage with failing inference +pub fn main() { + let a = Vec2 { x: 3.0f64, y: 4.0f64 }; + + // the following compiles and works properly + let v1: Vec2 = a * 3.0f64; + println!("{} {}", v1.x, v1.y); + + // the following compiles but v2 will not be Vec2 yet and + // using it later will cause an error that the type of v2 + // must be known + let v2 = a * 3.0f64; + println!("{} {}", v2.x, v2.y); // error regarding v2's type +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37433.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37433.rs new file mode 100644 index 000000000000..af9d4b0a6d22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37433.rs @@ -0,0 +1,12 @@ +// build-fail +// ignore-emscripten no llvm_asm! support + +#![feature(llvm_asm)] + +fn main() { + unsafe { + llvm_asm!("" :: "r"("")); +// { dg-error ".E0669." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37510.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37510.rs new file mode 100644 index 000000000000..6743ee4e0476 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37510.rs @@ -0,0 +1,15 @@ +// check-pass + +fn foo(_: &mut i32) -> bool { true } + +fn main() { + let opt = Some(92); + let mut x = 62; + + if let Some(_) = opt { + + } else if foo(&mut x) { + + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37515.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37515.rs new file mode 100644 index 000000000000..aaf89fdd56e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37515.rs @@ -0,0 +1,9 @@ +// check-pass + +#![warn(unused)] + +type Z = dyn for<'x> Send; +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3753.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3753.rs new file mode 100644 index 000000000000..447b5e3aca45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3753.rs @@ -0,0 +1,33 @@ +// run-pass +// Issue #3656 +// Issue Name: pub method preceded by attribute can't be parsed +// Abstract: Visibility parsing failed when compiler parsing + +use std::f64; + +#[derive(Copy, Clone)] +pub struct Point { + x: f64, + y: f64 +} + +#[derive(Copy, Clone)] +pub enum Shape { + Circle(Point, f64), + Rectangle(Point, Point) +} + +impl Shape { + pub fn area(&self, sh: Shape) -> f64 { + match sh { + Shape::Circle(_, size) => f64::consts::PI * size * size, + Shape::Rectangle(Point {x, y}, Point {x: x2, y: y2}) => (x2 - x) * (y2 - y) + } + } +} + +pub fn main(){ + let s = Shape::Circle(Point { x: 1.0, y: 2.0 }, 3.0); + println!("{}", s.area(s)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37534.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37534.rs new file mode 100644 index 000000000000..e8fe0750a5a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37534.rs @@ -0,0 +1,7 @@ +struct Foo { } +// { dg-error ".E0392." "" { target *-*-* } .-1 } +// { dg-error ".E0392." "" { target *-*-* } .-2 } +// { dg-warning ".E0392." "" { target *-*-* } .-3 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37550.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37550.rs new file mode 100644 index 000000000000..0e5d94976b99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37550.rs @@ -0,0 +1,7 @@ +const fn x() { + let t = true; + let x = || t; // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37576.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37576.rs new file mode 100644 index 000000000000..632949c7db44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37576.rs @@ -0,0 +1,46 @@ +fn main() { + 'test_1: while break 'test_1 {} + while break {} +// { dg-error ".E0590." "" { target *-*-* } .-1 } + + 'test_2: while let true = break 'test_2 {} + while let true = break {} +// { dg-error ".E0590." "" { target *-*-* } .-1 } + + loop { 'test_3: while break 'test_3 {} } + loop { while break {} } +// { dg-error ".E0590." "" { target *-*-* } .-1 } + + loop { + 'test_4: while break 'test_4 {} + break; + } + loop { + while break {} +// { dg-error ".E0590." "" { target *-*-* } .-1 } + break; + } + + 'test_5: while continue 'test_5 {} + while continue {} +// { dg-error ".E0590." "" { target *-*-* } .-1 } + + 'test_6: while let true = continue 'test_6 {} + while let true = continue {} +// { dg-error ".E0590." "" { target *-*-* } .-1 } + + loop { 'test_7: while continue 'test_7 {} } + loop { while continue {} } +// { dg-error ".E0590." "" { target *-*-* } .-1 } + + loop { + 'test_8: while continue 'test_8 {} + continue; + } + loop { + while continue {} +// { dg-error ".E0590." "" { target *-*-* } .-1 } + continue; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37598.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37598.rs new file mode 100644 index 000000000000..b4ad4546682a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37598.rs @@ -0,0 +1,12 @@ +// check-pass + +fn check(list: &[u8]) { + match list { + &[] => {}, + &[_u1, _u2, ref _next @ ..] => {}, + &[_u1] => {}, + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3763.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3763.rs new file mode 100644 index 000000000000..3a1fc803b6f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3763.rs @@ -0,0 +1,30 @@ +// compile-flags: -Zsave-analysis +// Also regression test for #69416 + +mod my_mod { + pub struct MyStruct { + priv_field: isize + } + pub fn MyStruct () -> MyStruct { + MyStruct {priv_field: 4} + } + impl MyStruct { + fn happyfun(&self) {} + } +} + +fn main() { + let my_struct = my_mod::MyStruct(); + let _woohoo = (&my_struct).priv_field; +// { dg-error ".E0616." "" { target *-*-* } .-1 } + + let _woohoo = (Box::new(my_struct)).priv_field; +// { dg-error ".E0616." "" { target *-*-* } .-1 } + + (&my_struct).happyfun(); // { dg-error ".E0624." "" { target *-*-* } } + + (Box::new(my_struct)).happyfun(); // { dg-error ".E0624." "" { target *-*-* } } + let nope = my_struct.priv_field; +// { dg-error ".E0616." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37655.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37655.rs new file mode 100644 index 000000000000..eda9bc8dee37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37655.rs @@ -0,0 +1,38 @@ +// check-pass +// Regression test for #37655. The problem was a false edge created by +// coercion that wound up requiring that `'a` (in `split()`) outlive +// `'b`, which shouldn't be necessary. + +#![allow(warnings)] + +trait SliceExt { + type Item; + + fn get_me(&self, index: I) -> &I::Output + where I: SliceIndex; +} + +impl SliceExt for [T] { + type Item = T; + + fn get_me(&self, index: I) -> &I::Output + where I: SliceIndex + { + panic!() + } +} + +pub trait SliceIndex { + type Output: ?Sized; +} + +impl SliceIndex for usize { + type Output = T; +} + +fn foo<'a, 'b>(split: &'b [&'a [u8]]) -> &'a [u8] { + split.get_me(0) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37665.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37665.rs new file mode 100644 index 000000000000..722f514d7a75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37665.rs @@ -0,0 +1,12 @@ +// compile-flags: -Z unpretty=mir +// ignore-cloudabi no std::path + +use std::path::MAIN_SEPARATOR; + +fn main() { + let mut foo : String = "hello".to_string(); + foo.push(MAIN_SEPARATOR); + println!("{}", foo); + let x: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37686.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37686.rs new file mode 100644 index 000000000000..093d0d6d2be5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37686.rs @@ -0,0 +1,8 @@ +// run-pass +fn main() { + match (0, 0) { + (std::usize::MIN, std::usize::MAX) => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37725.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37725.rs new file mode 100644 index 000000000000..af058812e8ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37725.rs @@ -0,0 +1,11 @@ +// build-pass +#![allow(dead_code)] +trait Foo { + fn foo(&self); +} + +fn foo<'a>(s: &'a mut ()) where &'a mut (): Foo { + s.foo(); +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37733.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37733.rs new file mode 100644 index 000000000000..25757c1f0e5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37733.rs @@ -0,0 +1,8 @@ +// build-pass +#![allow(dead_code)] +type A = for<> fn(); + +type B = for<'a,> fn(); + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3779.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3779.rs new file mode 100644 index 000000000000..27602b9a5d99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3779.rs @@ -0,0 +1,9 @@ +struct S { +// { dg-error ".E0072." "" { target *-*-* } .-1 } + element: Option +} + +fn main() { + let x = S { element: None }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37884.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37884.rs new file mode 100644 index 000000000000..5e1f9d1c4c9a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37884.rs @@ -0,0 +1,15 @@ +struct RepeatMut<'a, T>(T, &'a ()); + +impl<'a, T: 'a> Iterator for RepeatMut<'a, T> { + + type Item = &'a mut T; + fn next(&'a mut self) -> Option +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + { + Some(&mut self.0) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37887.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37887.rs new file mode 100644 index 000000000000..e941022c82b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37887.rs @@ -0,0 +1,5 @@ +fn main() { + extern crate libc; // { dg-error ".E0658." "" { target *-*-* } } + use libc::*; // { dg-error ".E0432." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3794.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3794.rs new file mode 100644 index 000000000000..634d565b6f75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3794.rs @@ -0,0 +1,33 @@ +// run-pass +#![feature(box_syntax)] + +trait T { + fn print(&self); +} + +#[derive(Debug)] +struct S { + s: isize, +} + +impl T for S { + fn print(&self) { + println!("{:?}", self); + } +} + +fn print_t(t: &dyn T) { + t.print(); +} + +fn print_s(s: &S) { + s.print(); +} + +pub fn main() { + let s: Box = box S { s: 5 }; + print_s(&*s); + let t: Box = s as Box; + print_t(&*t); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-37991.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-37991.rs new file mode 100644 index 000000000000..5f025a066776 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-37991.rs @@ -0,0 +1,18 @@ +// run-pass + +const fn foo() -> i64 { + 3 +} + +const fn bar(x: i64) -> i64 { + x*2 +} + +fn main() { + let val = &(foo() % 2); + assert_eq!(*val, 1); + + let val2 = &(bar(1+1) % 3); + assert_eq!(*val2, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38002.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38002.rs new file mode 100644 index 000000000000..5879232a1402 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38002.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(dead_code)] +// Check that constant ADTs are codegened OK, part k of N. + +enum Bar { + C +} + +enum Foo { + A {}, + B { + y: usize, + z: Bar + }, +} + +const LIST: [(usize, Foo); 2] = [ + (51, Foo::B { y: 42, z: Bar::C }), + (52, Foo::B { y: 45, z: Bar::C }), +]; + +pub fn main() { + match LIST { + [ + (51, Foo::B { y: 42, z: Bar::C }), + (52, Foo::B { y: 45, z: Bar::C }) + ] => {} + _ => { + // I would want to print the enum here, but if + // the discriminant is garbage this causes an + // `unreachable` and silent process exit. + panic!("trivial match failed") + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38033.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38033.rs new file mode 100644 index 000000000000..fefe1a4d717e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38033.rs @@ -0,0 +1,80 @@ +// run-pass +use std::marker; +use std::mem; + +fn main() { + let workers = (0..0).map(|_| result::()); + drop(join_all(workers).poll()); +} + +trait Future { + type Item; + type Error; + + fn poll(&mut self) -> Result; +} + +trait IntoFuture { + type Future: Future; + type Item; + type Error; + + fn into_future(self) -> Self::Future; +} + +impl IntoFuture for F { + type Future = F; + type Item = F::Item; + type Error = F::Error; + + fn into_future(self) -> F { + self + } +} + +struct FutureResult { + _inner: marker::PhantomData<(T, E)>, +} + +fn result() -> FutureResult { + loop {} +} + +impl Future for FutureResult { + type Item = T; + type Error = E; + + fn poll(&mut self) -> Result { + loop {} + } +} + +struct JoinAll + where I: IntoIterator, + I::Item: IntoFuture, +{ + elems: Vec<::Item>, +} + +fn join_all(_: I) -> JoinAll + where I: IntoIterator, + I::Item: IntoFuture, +{ + JoinAll { elems: vec![] } +} + +impl Future for JoinAll + where I: IntoIterator, + I::Item: IntoFuture, +{ + type Item = Vec<::Item>; + type Error = ::Error; + + fn poll(&mut self) -> Result { + let elems = mem::replace(&mut self.elems, Vec::new()); + Ok(elems.into_iter().map(|e| { + e + }).collect::>()) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38074.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38074.rs new file mode 100644 index 000000000000..c6b7631ad890 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38074.rs @@ -0,0 +1,21 @@ +// run-pass +// ignore-emscripten FIXME(#45351) + +#![feature(platform_intrinsics, repr_simd)] + +extern "platform-intrinsic" { + fn simd_shuffle2(x: T, y: T, idx: [u32; 2]) -> U; +} + +#[repr(simd)] +#[derive(Clone, Copy)] +#[allow(non_camel_case_types)] +struct u64x2(u64, u64); + +fn main() { + let a = u64x2(1, 2); + let r: u64x2 = unsafe { simd_shuffle2(a, a, [0-0, 0-0]) }; + assert_eq!(r.0, 1); + assert_eq!(r.1, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38160.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38160.rs new file mode 100644 index 000000000000..54735f75c638 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38160.rs @@ -0,0 +1,20 @@ +// check-pass + +trait MyTrait { + const MY_CONST: &'static str; +} + +macro_rules! my_macro { + () => { + struct MyStruct; + + impl MyTrait for MyStruct { + const MY_CONST: &'static str = stringify!(abc); + } + } +} + +my_macro!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38190.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38190.rs new file mode 100644 index 000000000000..2b34d4ea866a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38190.rs @@ -0,0 +1,16 @@ +// run-pass +// aux-build:issue-38190.rs +// ignore-pretty issue #37195 + +#[macro_use] +extern crate issue_38190; + +mod auxiliary { + m!([ + #[path = "issue-38190.rs"] + mod issue_38190; + ]); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3820.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3820.rs new file mode 100644 index 000000000000..e4de80d1fe98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3820.rs @@ -0,0 +1,16 @@ +struct Thing { + x: isize +} + +impl Thing { + fn mul(&self, c: &isize) -> Thing { + Thing {x: self.x * *c} + } +} + +fn main() { + let u = Thing {x: 2}; + let _v = u.mul(&3); // This is ok + let w = u * 3; // { dg-error ".E0369." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38226.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38226.rs new file mode 100644 index 000000000000..11493ef656ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38226.rs @@ -0,0 +1,16 @@ +// run-pass +// This test makes sure that we don't run into a linker error because of the +// middle::reachable pass missing trait methods with default impls. + +// aux-build:issue-38226-aux.rs + +// Need -Cno-prepopulate-passes to really disable inlining, otherwise the faulty +// code gets optimized out: +// compile-flags: -Cno-prepopulate-passes -Cpasses=name-anon-globals + +extern crate issue_38226_aux; + +fn main() { + issue_38226_aux::foo::<()>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38293.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38293.rs new file mode 100644 index 000000000000..5e2d63b0eac8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38293.rs @@ -0,0 +1,17 @@ +// Test that `fn foo::bar::{self}` only imports `bar` in the type namespace. + +mod foo { + pub fn f() { } +} +use foo::f::{self}; // { dg-error ".E0432." "" { target *-*-* } } + +mod bar { + pub fn baz() {} + pub mod baz {} +} +use bar::baz::{self}; + +fn main() { + baz(); // { dg-error ".E0423." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38381.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38381.rs new file mode 100644 index 000000000000..c2adae1674da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38381.rs @@ -0,0 +1,8 @@ +// check-pass + +use std::ops::Deref; + +fn main() { + let _x: fn(&i32) -> <&i32 as Deref>::Target = unimplemented!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38404.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38404.rs new file mode 100644 index 000000000000..313d4a8d0df7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38404.rs @@ -0,0 +1,7 @@ +trait A: std::ops::Add + Sized {} +trait B: A {} +trait C: A> {} +// { dg-error ".E0038." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38412.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38412.rs new file mode 100644 index 000000000000..1ad827ec5a17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38412.rs @@ -0,0 +1,11 @@ +fn main() { + let Box(a) = loop { }; +// { dg-error ".E0532." "" { target *-*-* } .-1 } + + // (The below is a trick to allow compiler to infer a type for + // variable `a` without attempting to ascribe a type to the + // pattern or otherwise attempting to name the Box type, which + // would run afoul of issue #22207) + let _b: *mut i32 = *a; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38437.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38437.rs new file mode 100644 index 000000000000..e850876e086e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38437.rs @@ -0,0 +1,47 @@ +// run-pass +#![allow(dead_code)] +// Check that drop elaboration clears the "master" discriminant +// drop flag even if it protects no fields. + +struct Good(usize); +impl Drop for Good { + #[inline(never)] + fn drop(&mut self) { + println!("dropping Good({})", self.0); + } +} + +struct Void; +impl Drop for Void { + #[inline(never)] + fn drop(&mut self) { + panic!("Suddenly, a Void appears."); + } +} + +enum E { + Never(Void), + Fine(Good) +} + +fn main() { + let mut go = true; + + loop { + let next; + match go { + true => next = E::Fine(Good(123)), + false => return, + } + + match next { + E::Never(_) => return, + E::Fine(_good) => go = false, + } + + // `next` is dropped and StorageDead'd here. We must reset the + // discriminant's drop flag to avoid random variants being + // dropped. + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38458.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38458.rs new file mode 100644 index 000000000000..652c7ac4ad2e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38458.rs @@ -0,0 +1,6 @@ +const x: () = { + return; // { dg-error ".E0572." "" { target *-*-* } } +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3847.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3847.rs new file mode 100644 index 000000000000..d43d8919a20c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3847.rs @@ -0,0 +1,14 @@ +// run-pass +mod buildings { + pub struct Tower { pub height: usize } +} + +pub fn main() { + let sears = buildings::Tower { height: 1451 }; + let h: usize = match sears { + buildings::Tower { height: h } => { h } + }; + + println!("{}", h); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38556.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38556.rs new file mode 100644 index 000000000000..7fc138649b43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38556.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +pub struct Foo; + +macro_rules! reexport { + () => { use Foo as Bar; } +} + +reexport!(); + +fn main() { + fn f(_: Bar) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38604.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38604.rs new file mode 100644 index 000000000000..df6e1d3a46c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38604.rs @@ -0,0 +1,17 @@ +trait Q {} +trait Foo where u32: Q { + fn foo(&self); +} + +impl Q<()> for u32 {} +impl Foo for () { + fn foo(&self) { + println!("foo!"); + } +} + +fn main() { + let _f: Box = // { dg-error ".E0038." "" { target *-*-* } } + Box::new(()); // { dg-error ".E0038." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38715.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38715.rs new file mode 100644 index 000000000000..b9b03bb9dd36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38715.rs @@ -0,0 +1,8 @@ +#[macro_export] +macro_rules! foo { ($i:ident) => {} } + +#[macro_export] +macro_rules! foo { () => {} } // { dg-error ".E0428." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38727.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38727.rs new file mode 100644 index 000000000000..cf3a99f75347 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38727.rs @@ -0,0 +1,14 @@ +// build-pass +#![allow(dead_code)] +#[repr(u64)] +enum A { + A = 0u64, + B = !0u64, +} + +fn cmp() -> A { + A::B +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3874.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3874.rs new file mode 100644 index 000000000000..36891e68b05b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3874.rs @@ -0,0 +1,13 @@ +// build-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +enum PureCounter { PureCounterVariant(usize) } + +fn each(thing: PureCounter, blk: F) where F: FnOnce(&usize) { + let PureCounter::PureCounterVariant(ref x) = thing; + blk(x); +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38763.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38763.rs new file mode 100644 index 000000000000..3c2501f0d6e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38763.rs @@ -0,0 +1,14 @@ +// run-pass +// ignore-emscripten + +#[repr(C)] +pub struct Foo(i128); + +#[no_mangle] +#[allow(improper_ctypes_definitions)] +pub extern "C" fn foo(x: Foo) -> Foo { x } + +fn main() { + foo(Foo(1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3878.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3878.rs new file mode 100644 index 000000000000..67eadb03b963 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3878.rs @@ -0,0 +1,11 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![allow(path_statements)] +#![feature(box_syntax)] + +pub fn main() { + let y: Box<_> = box 1; + y; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38821.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38821.rs new file mode 100644 index 000000000000..1768e120093a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38821.rs @@ -0,0 +1,34 @@ +pub struct Nullable(T); + +pub trait NotNull {} + +pub trait IntoNullable { + type Nullable; +} + +impl IntoNullable for T { + type Nullable = Nullable; +} + +impl IntoNullable for Nullable { + type Nullable = Nullable; +} + +pub trait Expression { + type SqlType; +} + +pub trait Column: Expression {} + +#[derive(Debug, Copy, Clone)] +// { dg-error ".E0277." "" { target *-*-* } .-1 } +pub enum ColumnInsertValue where + Col: Column, + Expr: Expression::Nullable>, +{ + Expression(Col, Expr), + Default(Col), +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38857.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38857.rs new file mode 100644 index 000000000000..0dc62e02ed16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38857.rs @@ -0,0 +1,6 @@ +fn main() { + let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; +// { dg-error ".E0603." "" { target *-*-* } .-1 } +// { dg-error ".E0603." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38868.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38868.rs new file mode 100644 index 000000000000..c93655631b35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38868.rs @@ -0,0 +1,14 @@ +pub struct List { + head: T, +} + +impl Drop for List { // { dg-error ".E0366." "" { target *-*-* } } + fn drop(&mut self) { + panic!() + } +} + +fn main() { + List { head: 0 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38875/auxiliary/issue-38875-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38875/auxiliary/issue-38875-b.rs new file mode 100644 index 000000000000..3f6f801a5c90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38875/auxiliary/issue-38875-b.rs @@ -0,0 +1,2 @@ +pub const FOO: usize = *&0; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38875/issue-38875.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38875/issue-38875.rs new file mode 100644 index 000000000000..0a7ca2cbe27a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38875/issue-38875.rs @@ -0,0 +1,9 @@ +// aux-build:issue-38875-b.rs +// check-pass + +extern crate issue_38875_b; + +fn main() { + let test_x = [0; issue_38875_b::FOO]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3888-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3888-2.rs new file mode 100644 index 000000000000..db724ddac9e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3888-2.rs @@ -0,0 +1,10 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn vec_peek<'r, T>(v: &'r [T]) -> &'r [T] { + &v[1..5] +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38919.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38919.rs new file mode 100644 index 000000000000..01b271e5735f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38919.rs @@ -0,0 +1,6 @@ +fn foo() { + T::Item; // { dg-error ".E0599." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38940.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38940.rs new file mode 100644 index 000000000000..930aaddabce0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38940.rs @@ -0,0 +1,47 @@ +// issue-38940: error printed twice for deref recursion limit exceeded +// Test that the recursion limit can be changed. In this case, we have +// deeply nested types that will fail the `Send` check by overflow +// when the recursion limit is set very low. +#![allow(dead_code)] +#![recursion_limit="10"] +macro_rules! link { + ($outer:ident, $inner:ident) => { + struct $outer($inner); + impl $outer { + fn new() -> $outer { + $outer($inner::new()) + } + } + impl std::ops::Deref for $outer { + type Target = $inner; + fn deref(&self) -> &$inner { + &self.0 + } + } + } +} +struct Bottom; +impl Bottom { + fn new() -> Bottom { + Bottom + } +} +link!(Top, A); +link!(A, B); +link!(B, C); +link!(C, D); +link!(D, E); +link!(E, F); +link!(F, G); +link!(G, H); +link!(H, I); +link!(I, J); +link!(J, K); +link!(K, Bottom); +fn main() { + let t = Top::new(); + let x: &Bottom = &t; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38942.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38942.rs new file mode 100644 index 000000000000..2b187b314a69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38942.rs @@ -0,0 +1,18 @@ +// run-pass +// See https://github.com/rust-lang/rust/issues/38942 + +#[repr(u64)] +pub enum NSEventType { + NSEventTypePressure, +} + +pub const A: u64 = NSEventType::NSEventTypePressure as u64; + +fn banana() -> u64 { + A +} + +fn main() { + println!("banana! {}", banana()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3895.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3895.rs new file mode 100644 index 000000000000..7aa71f9b08f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3895.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] + +pub fn main() { + enum State { BadChar, BadSyntax } + + match State::BadChar { + _ if true => State::BadChar, + State::BadChar | State::BadSyntax => panic!() , + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38954.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38954.rs new file mode 100644 index 000000000000..2bb9d62972ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38954.rs @@ -0,0 +1,5 @@ +fn _test(ref _p: str) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-38987.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-38987.rs new file mode 100644 index 000000000000..134489de00f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-38987.rs @@ -0,0 +1,5 @@ +// run-pass +fn main() { + let _ = -0x8000_0000_0000_0000_0000_0000_0000_0000i128; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3904.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3904.rs new file mode 100644 index 000000000000..9e9ddcd393ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3904.rs @@ -0,0 +1,26 @@ +// run-pass +fn example_err(prog: &str, arg: &str) { + println!("{}: {}", prog, arg) +} + +fn exit(print: F, prog: &str, arg: &str) where F: FnOnce(&str, &str) { + print(prog, arg); +} + +struct X where F: FnOnce(&str, &str) { + err: F, +} + +impl X where F: FnOnce(&str, &str) { + pub fn boom(self) { + exit(self.err, "prog", "arg"); + } +} + +pub fn main(){ + let val = X { + err: example_err, + }; + val.boom(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39089.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39089.rs new file mode 100644 index 000000000000..91fb25ae38f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39089.rs @@ -0,0 +1,6 @@ +// check-pass +#![allow(dead_code)] +fn f Sized>() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39175.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39175.rs new file mode 100644 index 000000000000..bd300628f008 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39175.rs @@ -0,0 +1,18 @@ +// This test ignores some platforms as the particular extension trait used +// to demonstrate the issue is only available on unix. This is fine as +// the fix to suggested paths is not platform-dependent and will apply on +// these platforms also. + +// ignore-windows +// ignore-cloudabi +// ignore-emscripten +// ignore-sgx no processes + +use std::process::Command; +// use std::os::unix::process::CommandExt; + +fn main() { + Command::new("echo").arg("hello").exec(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39211.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39211.rs new file mode 100644 index 000000000000..7b413efe90e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39211.rs @@ -0,0 +1,16 @@ +#![feature(associated_consts)] + +trait VecN { + const DIM: usize; +} +trait Mat { + type Row: VecN; +} + +fn m() { + let a = [3; M::Row::DIM]; +// { dg-error "" "" { target *-*-* } .-1 } +} +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39292.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39292.rs new file mode 100644 index 000000000000..b4e50ea2d662 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39292.rs @@ -0,0 +1,18 @@ +// run-pass +// Regression test for issue #39292. The object vtable was being +// incorrectly left with a null pointer. + +trait Foo { + fn print<'a>(&'a self) where T: 'a { println!("foo"); } +} + +impl<'a> Foo<&'a ()> for () { } + +trait Bar: for<'a> Foo<&'a ()> { } + +impl Bar for () {} + +fn main() { + (&() as &dyn Bar).print(); // Segfault +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3935.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3935.rs new file mode 100644 index 000000000000..6457db5e778d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3935.rs @@ -0,0 +1,14 @@ +// run-pass + +#[derive(PartialEq)] +struct Bike { + name: String, +} + +pub fn main() { + let town_bike = Bike { name: "schwinn".to_string() }; + let my_bike = Bike { name: "surly".to_string() }; + + assert!(town_bike != my_bike); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39362.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39362.rs new file mode 100644 index 000000000000..284fd8a5dbc0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39362.rs @@ -0,0 +1,19 @@ +enum Foo { + Bar { bar: Bar, id: usize } +} + +enum Bar { + A, B, C, D, E, F +} + +fn test(f: Foo) { + match f { +// { dg-error ".E0004." "" { target *-*-* } .-1 } +// { dg-error ".E0004." "" { target *-*-* } .-2 } + Foo::Bar { bar: Bar::A, .. } => (), + Foo::Bar { bar: Bar::B, .. } => (), + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39367.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39367.rs new file mode 100644 index 000000000000..d325d0583db8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39367.rs @@ -0,0 +1,40 @@ +// run-pass +use std::ops::Deref; + +struct ArenaSet::Target>(U, &'static V) + where V: 'static + ?Sized; + +static Z: [u8; 4] = [1,2,3,4]; + +fn arena() -> &'static ArenaSet> { + fn __static_ref_initialize() -> ArenaSet> { + ArenaSet(vec![], &Z) + } + unsafe { + use std::sync::Once; + fn require_sync(_: &T) { } + unsafe fn __stability() -> &'static ArenaSet> { + use std::mem::transmute; + static mut DATA: *const ArenaSet> = std::ptr::null_mut(); + + static mut ONCE: Once = Once::new(); + ONCE.call_once(|| { + DATA = transmute + ::>>, *const ArenaSet>> + (Box::new(__static_ref_initialize())); + }); + + &*DATA + } + let static_ref = __stability(); + require_sync(static_ref); + static_ref + } +} + +fn main() { + let &ArenaSet(ref u, v) = arena(); + assert!(u.is_empty()); + assert_eq!(v, Z); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39388.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39388.rs new file mode 100644 index 000000000000..acd62d1550ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39388.rs @@ -0,0 +1,10 @@ +#![allow(unused_macros)] + +macro_rules! assign { + (($($a:tt)*) = ($($b:tt))*) => { // { dg-error "" "" { target *-*-* } } + $($a)* = $($b)* + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39467.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39467.rs new file mode 100644 index 000000000000..2fcbb70371ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39467.rs @@ -0,0 +1,12 @@ +// check-pass +#![allow(dead_code)] +macro_rules! expr { () => { () } } + +enum A {} + +impl A { + const A: () = expr!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39548.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39548.rs new file mode 100644 index 000000000000..f77a2998dffa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39548.rs @@ -0,0 +1,7 @@ +// run-pass +type Array = [(); ((1 < 2) == false) as usize]; + +fn main() { + let _: Array = []; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39559-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39559-2.rs new file mode 100644 index 000000000000..9f153b2223d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39559-2.rs @@ -0,0 +1,21 @@ +trait Dim { + fn dim() -> usize; +} + +enum Dim3 {} + +impl Dim for Dim3 { + fn dim() -> usize { + 3 + } +} + +fn main() { + let array: [usize; Dim3::dim()] +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } + = [0; Dim3::dim()]; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39559.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39559.rs new file mode 100644 index 000000000000..5ee6bb87ad3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39559.rs @@ -0,0 +1,20 @@ +trait Dim { + fn dim() -> usize; +} + +enum Dim3 {} + +impl Dim for Dim3 { + fn dim() -> usize { + 3 + } +} + +pub struct Vector { + entries: [T; D::dim()], +// { dg-error ".E0599." "" { target *-*-* } .-1 } + _dummy: D, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39616.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39616.rs new file mode 100644 index 000000000000..8fe1805d2b15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39616.rs @@ -0,0 +1,4 @@ +fn foo(a: [0; 1]) {} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39687.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39687.rs new file mode 100644 index 000000000000..496a2d7bf0e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39687.rs @@ -0,0 +1,7 @@ +#![feature(fn_traits)] + +fn main() { + ::call; +// { dg-error ".E0229." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39709.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39709.rs new file mode 100644 index 000000000000..8ea49c2082b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39709.rs @@ -0,0 +1,6 @@ +// run-pass +#![allow(unused_macros)] +fn main() { + println!("{}", { macro_rules! x { ($(t:tt)*) => {} } 33 }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39720.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39720.rs new file mode 100644 index 000000000000..037141281b66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39720.rs @@ -0,0 +1,23 @@ +// run-pass +// ignore-emscripten FIXME(#45351) + +#![feature(repr_simd, platform_intrinsics)] + +#[repr(simd)] +#[derive(Copy, Clone, Debug)] +pub struct Char3(pub i8, pub i8, pub i8); + +#[repr(simd)] +#[derive(Copy, Clone, Debug)] +pub struct Short3(pub i16, pub i16, pub i16); + +extern "platform-intrinsic" { + fn simd_cast(x: T) -> U; +} + +fn main() { + let cast: Short3 = unsafe { simd_cast(Char3(10, -3, -9)) }; + + println!("{:?}", cast); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3973.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3973.rs new file mode 100644 index 000000000000..b59bac3ef56f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3973.rs @@ -0,0 +1,26 @@ +struct Point { + x: f64, + y: f64, +} + +trait ToString_ { + fn to_string(&self) -> String; +} + +impl ToString_ for Point { + fn new(x: f64, y: f64) -> Point { +// { dg-error ".E0407." "" { target *-*-* } .-1 } + Point { x: x, y: y } + } + + fn to_string(&self) -> String { + format!("({}, {})", self.x, self.y) + } +} + +fn main() { + let p = Point::new(0.0, 0.0); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + println!("{}", p.to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3979-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3979-2.rs new file mode 100644 index 000000000000..a10ca8ff35f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3979-2.rs @@ -0,0 +1,19 @@ +// check-pass +// pretty-expanded FIXME #23616 + +trait A { + fn a_method(&self); +} + +trait B: A { + fn b_method(&self); +} + +trait C: B { + fn c_method(&self) { + self.a_method(); + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3979-generics.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3979-generics.rs new file mode 100644 index 000000000000..83b812e02c49 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3979-generics.rs @@ -0,0 +1,37 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_snake_case)] + +use std::ops::Add; + +trait Positioned { + fn SetX(&mut self, _: S); + fn X(&self) -> S; +} + +trait Movable>: Positioned { + fn translate(&mut self, dx: S) { + let x = self.X() + dx; + self.SetX(x); + } +} + +struct Point { x: isize, y: isize } + +impl Positioned for Point { + fn SetX(&mut self, x: isize) { + self.x = x; + } + fn X(&self) -> isize { + self.x + } +} + +impl Movable for Point {} + +pub fn main() { + let mut p = Point{ x: 1, y: 2}; + p.translate(3); + assert_eq!(p.X(), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3979-xcrate.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3979-xcrate.rs new file mode 100644 index 000000000000..5582bdd9c152 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3979-xcrate.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +// aux-build:issue-3979-traits.rs + +extern crate issue_3979_traits; +use issue_3979_traits::{Positioned, Movable}; + +struct Point { x: isize, y: isize } + +impl Positioned for Point { + fn SetX(&mut self, x: isize) { + self.x = x; + } + fn X(&self) -> isize { + self.x + } +} + +impl Movable for Point {} + +pub fn main() { + let mut p = Point{ x: 1, y: 2}; + p.translate(3); + assert_eq!(p.X(), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3979.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3979.rs new file mode 100644 index 000000000000..99489c4d2dcf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3979.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_snake_case)] + +trait Positioned { + fn SetX(&mut self, _: isize); + fn X(&self) -> isize; +} + +trait Movable: Positioned { + fn translate(&mut self, dx: isize) { + let x = self.X(); + self.SetX(x + dx); + } +} + +struct Point { x: isize, y: isize } + +impl Positioned for Point { + fn SetX(&mut self, x: isize) { + self.x = x; + } + fn X(&self) -> isize { + self.x + } +} + +impl Movable for Point {} + +pub fn main() { + let mut p = Point{ x: 1, y: 2}; + p.translate(3); + assert_eq!(p.X(), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39808.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39808.rs new file mode 100644 index 000000000000..e98efe10c42c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39808.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(unreachable_code)] + +// Regression test for #39808. The type parameter of `Owned` was +// considered to be "unconstrained" because the type resulting from +// `format!` (`String`) was not being propagated upward, owing to the +// fact that the expression diverges. + +use std::borrow::Cow; + +fn main() { + let _ = if false { + Cow::Owned(format!("{:?}", panic!())) + } else { + Cow::Borrowed("") + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39823.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39823.rs new file mode 100644 index 000000000000..3d49026ce32b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39823.rs @@ -0,0 +1,26 @@ +// run-pass +// aux-build:issue-39823.rs + +extern crate issue_39823; +use issue_39823::{RemoteC, RemoteG}; + +#[derive(Debug, PartialEq)] +struct LocalC(u32); + +#[derive(Debug, PartialEq)] +struct LocalG(T); + +fn main() { + let virtual_localc : &dyn Fn(_) -> LocalC = &LocalC; + assert_eq!(virtual_localc(1), LocalC(1)); + + let virtual_localg : &dyn Fn(_) -> LocalG = &LocalG; + assert_eq!(virtual_localg(1), LocalG(1)); + + let virtual_remotec : &dyn Fn(_) -> RemoteC = &RemoteC; + assert_eq!(virtual_remotec(1), RemoteC(1)); + + let virtual_remoteg : &dyn Fn(_) -> RemoteG = &RemoteG; + assert_eq!(virtual_remoteg(1), RemoteG(1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39827.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39827.rs new file mode 100644 index 000000000000..94551a47cf4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39827.rs @@ -0,0 +1,35 @@ +// run-pass +#![feature(core_intrinsics)] + +use std::intrinsics::{ volatile_copy_memory, volatile_store, volatile_load, + volatile_copy_nonoverlapping_memory, + volatile_set_memory }; + +// +// This test ensures that volatile intrinsics can be specialised with +// zero-sized types and, in case of copy/set functions, can accept +// number of elements equal to zero. +// +fn main () { + let mut dst_pair = (1, 2); + let src_pair = (3, 4); + let mut dst_empty = (); + let src_empty = (); + + const COUNT_0: usize = 0; + const COUNT_100: usize = 100; + + unsafe { + volatile_copy_memory(&mut dst_pair, &dst_pair, COUNT_0); + volatile_copy_nonoverlapping_memory(&mut dst_pair, &src_pair, 0); + volatile_copy_memory(&mut dst_empty, &dst_empty, 100); + volatile_copy_nonoverlapping_memory(&mut dst_empty, &src_empty, + COUNT_100); + volatile_set_memory(&mut dst_empty, 0, COUNT_100); + volatile_set_memory(&mut dst_pair, 0, COUNT_0); + volatile_store(&mut dst_empty, ()); + volatile_store(&mut dst_empty, src_empty); + volatile_load(&src_empty); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39848.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39848.rs new file mode 100644 index 000000000000..eaedfac399ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39848.rs @@ -0,0 +1,10 @@ +macro_rules! get_opt { + ($tgt:expr, $field:ident) => { + if $tgt.has_$field() {} // { dg-error "" "" { target *-*-* } } + } +} + +fn main() { + get_opt!(bar, foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3991.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3991.rs new file mode 100644 index 000000000000..233e40a74301 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3991.rs @@ -0,0 +1,17 @@ +// check-pass +#![allow(dead_code)] + +// pretty-expanded FIXME #23616 + +struct HasNested { + nest: Vec > , +} + +impl HasNested { + fn method_push_local(&mut self) { + self.nest[0].push(0); + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-3993.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-3993.rs new file mode 100644 index 000000000000..ccdb81d36f0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-3993.rs @@ -0,0 +1,11 @@ +use zoo::fly; // { dg-error ".E0603." "" { target *-*-* } } + +mod zoo { + fn fly() {} +} + + +fn main() { + fly(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39970.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39970.rs new file mode 100644 index 000000000000..b61331bb99c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39970.rs @@ -0,0 +1,22 @@ +trait Array<'a> { + type Element: 'a; +} + +trait Visit { + fn visit() {} +} + +impl<'a> Array<'a> for () { + type Element = &'a (); +} + +impl Visit for () where + //(): for<'a> Array<'a, Element=&'a ()>, // No ICE + (): for<'a> Array<'a, Element=()>, // ICE +{} + +fn main() { + <() as Visit>::visit(); +// { dg-error ".E0271." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39974.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39974.rs new file mode 100644 index 000000000000..0be22d1287c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39974.rs @@ -0,0 +1,12 @@ +const LENGTH: f64 = 2; + +struct Thing { + f: [[f64; 2]; LENGTH], +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn main() { + let _t = Thing { f: [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]] }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-39984.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-39984.rs new file mode 100644 index 000000000000..6ac44ec984af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-39984.rs @@ -0,0 +1,15 @@ +// check-pass +#![allow(dead_code)] +#![allow(unreachable_code)] +// Regression test for issue #39984. +// +// The key here is that the error type of the `Ok` call ought to be +// constrained to `String`, even though it is dead-code. + +fn main() {} + +fn t() -> Result<(), String> { + return Err("".into()); + Ok(()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40000.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40000.rs new file mode 100644 index 000000000000..c386bc1f60ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40000.rs @@ -0,0 +1,8 @@ +fn main() { + let bar: fn(&mut u32) = |_| {}; + + fn foo(x: Box) {} + let bar = Box::new(|x: &i32| {}) as Box; + foo(bar); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40003.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40003.rs new file mode 100644 index 000000000000..a30f0f1408b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40003.rs @@ -0,0 +1,179 @@ +// run-pass +#![allow(unused_must_use)] +fn main() { + if false { test(); } +} + +fn test() { + let rx = Err::, u32>(1).into_future(); + + rx.map(|l: Vec| stream::iter(l.into_iter().map(|i| Ok(i)))) + .flatten_stream() + .chunks(50) + .buffer_unordered(5); +} + +use future::{Future, IntoFuture}; +mod future { + use std::result; + + use {stream, Stream}; + + pub trait Future { + type Item; + type Error; + + fn map(self, _: F) -> Map + where F: FnOnce(Self::Item) -> U, + Self: Sized, + { + panic!() + } + + fn flatten_stream(self) -> FlattenStream + where ::Item: stream::Stream, + Self: Sized + { + panic!() + } + } + + pub trait IntoFuture { + type Future: Future; + type Item; + type Error; + fn into_future(self) -> Self::Future; + } + + impl IntoFuture for F { + type Future = F; + type Item = F::Item; + type Error = F::Error; + + fn into_future(self) -> F { + panic!() + } + } + + impl IntoFuture for result::Result { + type Future = FutureResult; + type Item = T; + type Error = E; + + fn into_future(self) -> FutureResult { + panic!() + } + } + + pub struct Map { + _a: (A, F), + } + + impl Future for Map + where A: Future, + F: FnOnce(A::Item) -> U, + { + type Item = U; + type Error = A::Error; + } + + pub struct FlattenStream { + _f: F, + } + + impl Stream for FlattenStream + where F: Future, + ::Item: Stream, + { + type Item = ::Item; + type Error = ::Error; + } + + pub struct FutureResult { + _inner: (T, E), + } + + impl Future for FutureResult { + type Item = T; + type Error = E; + } +} + +mod stream { + use IntoFuture; + + pub trait Stream { + type Item; + type Error; + + fn buffer_unordered(self, amt: usize) -> BufferUnordered + where Self::Item: IntoFuture::Error>, + Self: Sized + { + new(self, amt) + } + + fn chunks(self, _capacity: usize) -> Chunks + where Self: Sized + { + panic!() + } + } + + pub struct IterStream { + _iter: I, + } + + pub fn iter(_: J) -> IterStream + where J: IntoIterator>, + { + panic!() + } + + impl Stream for IterStream + where I: Iterator>, + { + type Item = T; + type Error = E; + } + + pub struct Chunks { + _stream: S + } + + impl Stream for Chunks + where S: Stream + { + type Item = Result::Item>, u32>; + type Error = ::Error; + } + + pub struct BufferUnordered { + _stream: S, + } + + enum Slot { + Next(usize), + _Data { _a: T }, + } + + fn new(_s: S, _amt: usize) -> BufferUnordered + where S: Stream, + S::Item: IntoFuture::Error>, + { + (0..0).map(|_| { + Slot::Next::<::Future>(1) + }).collect::>(); + panic!() + } + + impl Stream for BufferUnordered + where S: Stream, + S::Item: IntoFuture::Error>, + { + type Item = ::Item; + type Error = ::Error; + } +} +use stream::Stream; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40085.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40085.rs new file mode 100644 index 000000000000..99093e9546f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40085.rs @@ -0,0 +1,14 @@ +// run-pass +use std::ops::Index; +fn bar() {} +static UNIT: () = (); +struct S; +impl Index for S { + type Output = (); + fn index(&self, _: fn()) -> &() { &UNIT } +} +fn main() { + S.index(bar); + S[bar]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40136.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40136.rs new file mode 100644 index 000000000000..963ebf3d2f57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40136.rs @@ -0,0 +1,16 @@ +// check-pass +#![allow(dead_code)] + +macro_rules! m { () => { 0 } } + +trait T { + const C: i32 = m!(); +} + +struct S; +impl S { + const C: i32 = m!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40231-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40231-1.rs new file mode 100644 index 000000000000..b4a47557f842 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40231-1.rs @@ -0,0 +1,55 @@ +// check-pass + +#![allow(dead_code)] + +trait Structure: Sized where E: Encoding { + type RefTarget: ?Sized; + type FfiPtr; + unsafe fn borrow_from_ffi_ptr<'a>(ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget>; +} + +enum Slice {} + +impl Structure for Slice where E: Encoding { + type RefTarget = [E::Unit]; + type FfiPtr = (*const E::FfiUnit, usize); + unsafe fn borrow_from_ffi_ptr<'a>(_ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget> { + panic!() + } +} + +trait Encoding { + type Unit: Unit; + type FfiUnit; +} + +trait Unit {} + +enum Utf16 {} + +impl Encoding for Utf16 { + type Unit = Utf16Unit; + type FfiUnit = u16; +} + +struct Utf16Unit(pub u16); + +impl Unit for Utf16Unit {} + +type SUtf16Str = SeStr; + +struct SeStr where S: Structure, E: Encoding { + _data: S::RefTarget, +} + +impl SeStr where S: Structure, E: Encoding { + pub unsafe fn from_ptr<'a>(_ptr: S::FfiPtr) -> Option<&'a Self> { + panic!() + } +} + +fn main() { + const TEXT_U16: &'static [u16] = &[]; + let _ = unsafe { SUtf16Str::from_ptr((TEXT_U16.as_ptr(), TEXT_U16.len())).unwrap() }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40231-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40231-2.rs new file mode 100644 index 000000000000..400cd28c14f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40231-2.rs @@ -0,0 +1,55 @@ +// check-pass + +#![allow(dead_code)] + +trait Structure: Sized where E: Encoding { + type RefTarget: ?Sized; + type FfiPtr; + unsafe fn borrow_from_ffi_ptr<'a>(ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget>; +} + +enum Slice {} + +impl Structure for Slice where E: Encoding { + type RefTarget = [E::Unit]; + type FfiPtr = (*const E::FfiUnit, usize); + unsafe fn borrow_from_ffi_ptr<'a>(_ptr: Self::FfiPtr) -> Option<&'a Self::RefTarget> { + panic!() + } +} + +trait Encoding { + type Unit: Unit; + type FfiUnit; +} + +trait Unit {} + +enum Utf16 {} + +impl Encoding for Utf16 { + type Unit = Utf16Unit; + type FfiUnit = u16; +} + +struct Utf16Unit(pub u16); + +impl Unit for Utf16Unit {} + +struct SUtf16Str { + _data: >::RefTarget, +} + +impl SUtf16Str { + pub unsafe fn from_ptr<'a>(ptr: >::FfiPtr) + -> Option<&'a Self> { + std::mem::transmute::::Unit]>, _>( + >::borrow_from_ffi_ptr(ptr)) + } +} + +fn main() { + const TEXT_U16: &'static [u16] = &[]; + let _ = unsafe { SUtf16Str::from_ptr((TEXT_U16.as_ptr(), TEXT_U16.len())).unwrap() }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40235.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40235.rs new file mode 100644 index 000000000000..1b34a385d47e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40235.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(unused_variables)] +fn foo() {} + +fn main() { + while let Some(foo) = Some(1) { break } + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4025.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4025.rs new file mode 100644 index 000000000000..3a20a80f2007 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4025.rs @@ -0,0 +1,26 @@ +// check-pass +#![allow(dead_code)] +#![allow(unused_mut)] +/* +# if b { x } else { y } requires identical types for x and y +*/ + +fn print1(b: bool, s1: &str, s2: &str) { + println!("{}", if b { s1 } else { s2 }); +} +fn print2<'a, 'b>(b: bool, s1: &'a str, s2: &'b str) { + println!("{}", if b { s1 } else { s2 }); +} +fn print3(b: bool, s1: &str, s2: &str) { + let mut s: &str; + if b { s = s1; } else { s = s2; } + println!("{}", s); +} +fn print4<'a, 'b>(b: bool, s1: &'a str, s2: &'b str) { + let mut s: &str; + if b { s = s1; } else { s = s2; } + println!("{}", s); +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40288-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40288-2.rs new file mode 100644 index 000000000000..7f0e9f708a8a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40288-2.rs @@ -0,0 +1,32 @@ +fn prove_static(_: &'static T) {} + +fn lifetime_transmute_slice<'a, T: ?Sized>(x: &'a T, y: &T) -> &'a T { + let mut out = [x]; + { + let slice: &mut [_] = &mut out; + slice[0] = y; + } + out[0] +// { dg-error ".E0621." "" { target *-*-* } .-1 } +} + +struct Struct { + head: T, + _tail: U +} + +fn lifetime_transmute_struct<'a, T: ?Sized>(x: &'a T, y: &T) -> &'a T { + let mut out = Struct { head: x, _tail: [()] }; + { + let dst: &mut Struct<_, [()]> = &mut out; + dst.head = y; + } + out.head +// { dg-error ".E0621." "" { target *-*-* } .-1 } +} + +fn main() { + prove_static(lifetime_transmute_slice("", &String::from("foo"))); + prove_static(lifetime_transmute_struct("", &String::from("bar"))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40288.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40288.rs new file mode 100644 index 000000000000..44640998f636 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40288.rs @@ -0,0 +1,21 @@ +fn save_ref<'a>(refr: &'a i32, to: &mut [&'a i32]) { + for val in &mut *to { + *val = refr; + } +} + +fn main() { + let ref init = 0i32; + let ref mut refr = 1i32; + + let mut out = [init]; + + save_ref(&*refr, &mut out); + + // This shouldn't be allowed as `refr` is borrowed + *refr = 3; // { dg-error ".E0506." "" { target *-*-* } } + + // Prints 3?! + println!("{:?}", out[0]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40350.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40350.rs new file mode 100644 index 000000000000..4ad89c094164 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40350.rs @@ -0,0 +1,11 @@ +// check-pass + +enum E { + A = { + enum F { B } + 0 + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40402-ref-hints/issue-40402-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40402-ref-hints/issue-40402-1.rs new file mode 100644 index 000000000000..4607dd472035 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40402-ref-hints/issue-40402-1.rs @@ -0,0 +1,11 @@ +// Check that we do not suggest `ref f` here in the `main()` function. +struct Foo { + pub v: Vec, +} + +fn main() { + let mut f = Foo { v: Vec::new() }; + f.v.push("hello".to_string()); + let e = f.v[0]; // { dg-error ".E0507." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40402-ref-hints/issue-40402-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40402-ref-hints/issue-40402-2.rs new file mode 100644 index 000000000000..bea616304f22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40402-ref-hints/issue-40402-2.rs @@ -0,0 +1,7 @@ +// Check that we do suggest `(ref a, ref b)` here, since `a` and `b` +// are nested within a pattern +fn main() { + let x = vec![(String::new(), String::new())]; + let (a, b) = x[0]; // { dg-error ".E0507." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40408.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40408.rs new file mode 100644 index 000000000000..45e2c5e6678a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40408.rs @@ -0,0 +1,8 @@ +// run-pass +fn main() { + println!("{}", 0E+10); + println!("{}", 0e+10); + println!("{}", 00e+10); + println!("{}", 00E+10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40469.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40469.rs new file mode 100644 index 000000000000..0a55690b6d21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40469.rs @@ -0,0 +1,10 @@ +// run-pass +// ignore-pretty issue #37195 + +#![allow(dead_code)] + +include!("auxiliary/issue-40469.rs"); +fn f() { m!(); } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40510-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40510-1.rs new file mode 100644 index 000000000000..dc6e471595b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40510-1.rs @@ -0,0 +1,13 @@ +#![allow(unused)] + +fn f() { + let mut x: Box<()> = Box::new(()); + + || { + &mut x + }; +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40510-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40510-2.rs new file mode 100644 index 000000000000..d3e0ee3fa7ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40510-2.rs @@ -0,0 +1,14 @@ +// check-pass +#![allow(unused)] + +fn f() { + let x: Box<()> = Box::new(()); + + || { + &x + }; +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40510-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40510-3.rs new file mode 100644 index 000000000000..0ea8034a815f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40510-3.rs @@ -0,0 +1,15 @@ +#![allow(unused)] + +fn f() { + let mut x: Vec<()> = Vec::new(); + + || { + || { + x.push(()) + } +// { dg-error "" "" { target *-*-* } .-3 } + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40510-4.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40510-4.rs new file mode 100644 index 000000000000..29c824c1326f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40510-4.rs @@ -0,0 +1,16 @@ +// check-pass +#![allow(unused)] + +fn f() { + let x: Vec<()> = Vec::new(); + + || { + || { + x.len() + } + }; +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40610.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40610.rs new file mode 100644 index 000000000000..1da392ebd07a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40610.rs @@ -0,0 +1,7 @@ +fn f(_: &[f32]) {} + +fn main() { + () + f(&[1.0]); +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40749.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40749.rs new file mode 100644 index 000000000000..f41cced1d83e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40749.rs @@ -0,0 +1,7 @@ +fn main() { + [0; ..10]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40770.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40770.rs new file mode 100644 index 000000000000..bb4ac0830a9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40770.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(unused_macros)] +macro_rules! m { + ($e:expr) => { + macro_rules! n { () => { $e } } + } +} + +fn main() { + m!(foo!()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40782.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40782.rs new file mode 100644 index 000000000000..e8beb8d2edbc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40782.rs @@ -0,0 +1,9 @@ +// run-rustfix + +fn main() { + for _i 0..2 { // { dg-error "" "" { target *-*-* } } + } + for _i of 0..2 { // { dg-error "" "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40827.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40827.rs new file mode 100644 index 000000000000..f32aedc563f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40827.rs @@ -0,0 +1,18 @@ +use std::rc::Rc; +use std::sync::Arc; + +struct Foo(Arc); + +enum Bar { + A(Rc), + B(Option), +} + +fn f(_: T) {} + +fn main() { + f(Foo(Arc::new(Bar::B(None)))); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40845.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40845.rs new file mode 100644 index 000000000000..8df71d9b6e30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40845.rs @@ -0,0 +1,7 @@ +trait T { m!(); } // { dg-error "" "" { target *-*-* } } + +struct S; +impl S { m!(); } // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40847.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40847.rs new file mode 100644 index 000000000000..47ec785bd11f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40847.rs @@ -0,0 +1,18 @@ +// run-pass +macro_rules! gen { + ($name:ident ( $($dol:tt $var:ident)* ) $($body:tt)*) => { + macro_rules! $name { + ($($dol $var:ident)*) => { + $($body)* + } + } + } +} + +gen!(m($var) $var); + +fn main() { + let x = 1; + assert_eq!(m!(x), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40861.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40861.rs new file mode 100644 index 000000000000..292a78bb2797 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40861.rs @@ -0,0 +1,7 @@ +fn f(_: &[f32]) {} + +fn main() { + ()[f(&[1.0])]; +// { dg-error ".E0608." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40883.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40883.rs new file mode 100644 index 000000000000..a36ad50b79d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40883.rs @@ -0,0 +1,95 @@ +// run-pass +#![allow(dead_code)] +// check that we don't have linear stack usage with multiple calls to `push` + +#![feature(test)] + +extern crate test; +use std::mem; + +fn meal() -> Big { + if test::black_box(false) { + panic!() + } + Big { drop_me: [ + None, None, None, None, None, None, None, None, + None, None, None, None, None, None, None, None, + None, None, None, None, None, None, None, None, + None, None, None, None, None, None, None, None, + None, None, None, None, None, None, None, None, + None, None, None, None, None, None, None, None, + ]} +} + +pub struct Big { + drop_me: [Option>; 48], +} + +#[inline] +fn push(out: &mut Vec) { + out.push(meal()); +} + +#[inline(never)] +pub fn supersize_me(out: &mut Vec) { + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); // 16 calls to `push` + + verify_stack_usage(out); + + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); + push(out); // 16 calls to `push` +} + +#[inline(never)] +fn verify_stack_usage(before_ptr: *mut Vec) { + // To check stack usage, create locals before and after + // and check the difference in addresses between them. + let mut stack_var: Vec = vec![]; + test::black_box(&mut stack_var); + let stack_usage = isize::abs( + (&mut stack_var as *mut _ as isize) - + (before_ptr as isize)) as usize; + // Give space for 2 copies of `Big` + 272 "misc" bytes + // (value observed on x86_64-pc-windows-gnu). + if stack_usage > mem::size_of::() * 2 + 272 { + panic!("used {} bytes of stack, but `struct Big` is only {} bytes", + stack_usage, mem::size_of::()); + } + +} + +pub fn main() { + let mut v = vec![]; + test::black_box(&mut v); + supersize_me(&mut v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40951.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40951.rs new file mode 100644 index 000000000000..b0900fbeb851 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40951.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(unused_variables)] +// Regression test for #40951. + +const FOO: [&'static str; 1] = ["foo"]; + +fn find(t: &[T], element: &T) { } + +fn main() { + let x = format!("hi"); + find(&FOO, &&*x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-40962.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-40962.rs new file mode 100644 index 000000000000..52dc877dd9b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-40962.rs @@ -0,0 +1,12 @@ +// check-pass +macro_rules! m { + ($i:meta) => { + #[derive($i)] + struct S; + } +} + +m!(Clone); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41053.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41053.rs new file mode 100644 index 000000000000..46cac6b51441 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41053.rs @@ -0,0 +1,22 @@ +// run-pass +// aux-build:issue-41053.rs + +pub trait Trait { fn foo(&self) {} } + +pub struct Foo; + +impl Iterator for Foo { + type Item = Box; + fn next(&mut self) -> Option> { + extern crate issue_41053; + impl ::Trait for issue_41053::Test { + fn foo(&self) {} + } + Some(Box::new(issue_41053::Test)) + } +} + +fn main() { + Foo.next().unwrap().foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4107.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4107.rs new file mode 100644 index 000000000000..976788d98771 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4107.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] + +pub fn main() { + let _id: &Mat2 = &Matrix::identity(1.0); +} + +pub trait Index { fn get(&self, _: Index) -> Result { panic!() } } +pub trait Dimensional: Index { } + +pub struct Mat2 { x: T } +pub struct Vec2 { x: T } + +impl Dimensional> for Mat2 { } +impl Index> for Mat2 { } + +impl Dimensional for Vec2 { } +impl Index for Vec2 { } + +pub trait Matrix: Dimensional { + fn identity(t:T) -> Self; +} + +impl Matrix> for Mat2 { + fn identity(t:T) -> Mat2 { Mat2{ x: t } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41139.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41139.rs new file mode 100644 index 000000000000..aa2affe77131 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41139.rs @@ -0,0 +1,13 @@ +trait Trait {} + +fn get_function<'a>() -> &'a dyn Fn() -> dyn Trait { + panic!("") +} + +fn main() { + // This isn't great. The issue here is that `dyn Trait` is not sized, so + // `dyn Fn() -> dyn Trait` is not well-formed. + let t: &dyn Trait = &get_function()(); +// { dg-error ".E0618." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41213.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41213.rs new file mode 100644 index 000000000000..54e0f7c1cce2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41213.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] +enum A { + A1, + A2, + A3, +} + +enum B { + B1(String, String), + B2(String, String), +} + +fn main() { + let a = A::A1; + loop { + let _ctor = match a { + A::A3 => break, + A::A1 => B::B1, + A::A2 => B::B2, + }; + break; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41229-ref-str.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41229-ref-str.rs new file mode 100644 index 000000000000..a1735cdb8b59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41229-ref-str.rs @@ -0,0 +1,5 @@ +pub fn example(ref s: str) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41255.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41255.rs new file mode 100644 index 000000000000..8299c1efd98b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41255.rs @@ -0,0 +1,76 @@ +// Matching against float literals should result in a linter error + +#![feature(exclusive_range_pattern)] +#![feature(half_open_range_patterns)] +#![allow(unused)] +#![forbid(illegal_floating_point_literal_pattern)] + +fn main() { + let x = 42.0; + match x { + 5.0 => {}, // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + 5.0f32 => {}, // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + -5.0 => {}, // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + 1.0 .. 33.0 => {}, // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-warning "" "" { target *-*-* } .-6 } +// { dg-error "" "" { target *-*-* } .-7 } +// { dg-warning "" "" { target *-*-* } .-8 } + 39.0 ..= 70.0 => {}, // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-warning "" "" { target *-*-* } .-6 } +// { dg-warning "" "" { target *-*-* } .-7 } +// { dg-warning "" "" { target *-*-* } .-8 } + + ..71.0 => {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + ..=72.0 => {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + 71.0.. => {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + _ => {}, + }; + let y = 5.0; + // Same for tuples + match (x, 5) { + (3.14, 1) => {}, // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + _ => {}, + } + // Or structs + struct Foo { x: f32 }; + match (Foo { x }) { + Foo { x: 2.0 } => {}, // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41272.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41272.rs new file mode 100644 index 000000000000..912cf1d9369b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41272.rs @@ -0,0 +1,22 @@ +// check-pass +#![allow(dead_code)] +struct Foo; + +impl Foo { + fn bar(&mut self) -> bool { true } +} + +fn error(foo: &mut Foo) { + if let Some(_) = Some(true) { + } else if foo.bar() {} +} + +fn ok(foo: &mut Foo) { + if let Some(_) = Some(true) { + } else { + if foo.bar() {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41298.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41298.rs new file mode 100644 index 000000000000..62c6f250e784 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41298.rs @@ -0,0 +1,9 @@ +// check-pass +#![allow(dead_code)] +struct Function { t: T, f: F } + +impl Function R> { fn foo() { } } +impl Function R> { fn bar() { } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41394-rpass.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41394-rpass.rs new file mode 100644 index 000000000000..26c4aea851c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41394-rpass.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:issue-41394.rs + +extern crate issue_41394 as lib; + +fn main() { + assert_eq!(lib::foo() as u32, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41394.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41394.rs new file mode 100644 index 000000000000..aa3d1504db21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41394.rs @@ -0,0 +1,11 @@ +enum Foo { + A = "" + 1 +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} + +enum Bar { + A = Foo::A as isize +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41479.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41479.rs new file mode 100644 index 000000000000..4b53e89aef65 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41479.rs @@ -0,0 +1,10 @@ +// run-pass +fn split(pair: (A, B)) { + let _a = pair.0; + let _b = pair.1; +} + +fn main() { + split(((), ((), ()))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41498.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41498.rs new file mode 100644 index 000000000000..d371a99f10d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41498.rs @@ -0,0 +1,18 @@ +// run-pass +// regression test for issue #41498. + +struct S; +impl S { + fn mutate(&mut self) {} +} + +fn call_and_ref T>(x: &mut Option, f: F) -> &mut T { + *x = Some(f()); + x.as_mut().unwrap() +} + +fn main() { + let mut n = None; + call_and_ref(&mut n, || [S])[0].mutate(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41549.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41549.rs new file mode 100644 index 000000000000..3d0d6bfbb84b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41549.rs @@ -0,0 +1,13 @@ +// aux-build:issue-41549.rs + + +extern crate issue_41549; + +struct S; + +impl issue_41549::Trait for S { + const CONST: () = (); // { dg-error ".E0326." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41604.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41604.rs new file mode 100644 index 000000000000..43825f39a908 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41604.rs @@ -0,0 +1,12 @@ +// run-pass +struct B; + +impl B { + fn init(&mut self) {} +} + +fn main() { + let mut b = [B]; + b[1-1].init(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41628.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41628.rs new file mode 100644 index 000000000000..e481c56441df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41628.rs @@ -0,0 +1,8 @@ +// check-pass +#![deny(dead_code)] + +#[used] +static FOO: u32 = 0; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41652/auxiliary/issue-41652-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41652/auxiliary/issue-41652-b.rs new file mode 100644 index 000000000000..56748ba6bb50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41652/auxiliary/issue-41652-b.rs @@ -0,0 +1,7 @@ +pub trait Tr { + // Note: The function needs to be declared over multiple lines to reproduce + // the crash. DO NOT reformat. + fn f() + where Self: Sized; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41652/issue-41652.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41652/issue-41652.rs new file mode 100644 index 000000000000..b663a95288f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41652/issue-41652.rs @@ -0,0 +1,15 @@ +// aux-build:issue-41652-b.rs + +extern crate issue_41652_b; + +struct S; + +impl issue_41652_b::Tr for S { + fn f() { + 3.f() +// { dg-error ".E0689." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41677.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41677.rs new file mode 100644 index 000000000000..192dfb29ca30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41677.rs @@ -0,0 +1,29 @@ +// run-pass +// Regression test for #41677. The local variable was winding up with +// a type `Receiver` where `?T` was unconstrained, because we +// failed to enforce the WF obligations and `?T` is a bivariant type +// parameter position. + +#![allow(unused_variables, dead_code)] + +use std::marker::PhantomData; + +trait Handle { + type Inner; +} + +struct ResizingHandle(PhantomData); +impl Handle for ResizingHandle { + type Inner = H; +} + +struct Receiver>(PhantomData); + +fn channel(size: usize) -> Receiver> { + let rx = Receiver(PhantomData); + rx +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41696.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41696.rs new file mode 100644 index 000000000000..740a2e2b0d0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41696.rs @@ -0,0 +1,55 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![recursion_limit = "128"] +// this used to cause exponential code-size blowup during LLVM passes. + +#![feature(test)] + +extern crate test; + +struct MayUnwind; + +impl Drop for MayUnwind { + fn drop(&mut self) { + if test::black_box(false) { + panic!() + } + } +} + +struct DS { + may_unwind: MayUnwind, + name: String, + next: U, +} + +fn add(ds: DS, name: String) -> DS> { + DS { + may_unwind: MayUnwind, + name: "?".to_owned(), + next: ds, + } +} + +fn main() { + let deserializers = DS { may_unwind: MayUnwind, name: "?".to_owned(), next: () }; + let deserializers = add(deserializers, "?".to_owned()); + let deserializers = add(deserializers, "?".to_owned()); + let deserializers = add(deserializers, "?".to_owned()); + let deserializers = add(deserializers, "?".to_owned()); + let deserializers = add(deserializers, "?".to_owned()); + let deserializers = add(deserializers, "?".to_owned()); + let deserializers = add(deserializers, "?".to_owned()); // 0.7s + let deserializers = add(deserializers, "?".to_owned()); // 1.3s + let deserializers = add(deserializers, "?".to_owned()); // 2.4s + let deserializers = add(deserializers, "?".to_owned()); // 6.7s + let deserializers = add(deserializers, "?".to_owned()); // 26.0s + let deserializers = add(deserializers, "?".to_owned()); // 114.0s + let deserializers = add(deserializers, "?".to_owned()); // 228.0s + let deserializers = add(deserializers, "?".to_owned()); // 400.0s + let deserializers = add(deserializers, "?".to_owned()); // 800.0s + let deserializers = add(deserializers, "?".to_owned()); // 1600.0s + let deserializers = add(deserializers, "?".to_owned()); // 3200.0s +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41726.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41726.rs new file mode 100644 index 000000000000..83d9ee52cf7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41726.rs @@ -0,0 +1,8 @@ +use std::collections::HashMap; +fn main() { + let things: HashMap> = HashMap::new(); + for src in things.keys() { + things[src.as_str()].sort(); // { dg-error ".E0596." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41742.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41742.rs new file mode 100644 index 000000000000..8cd46125300b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41742.rs @@ -0,0 +1,26 @@ +use std::ops::{Index, IndexMut}; + +struct S; +struct H; + +impl S { + fn f(&mut self) {} +} + +impl Index for H { + type Output = S; + fn index(&self, index: u32) -> &S { + unimplemented!() + } +} + +impl IndexMut for H { + fn index_mut(&mut self, index: u32) -> &mut S { + unimplemented!() + } +} + +fn main() { + H["?"].f(); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41744.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41744.rs new file mode 100644 index 000000000000..8936fa70070a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41744.rs @@ -0,0 +1,8 @@ +// run-pass +trait Tc {} +impl Tc for bool {} + +fn main() { + let _: &[&dyn Tc] = &[&true]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41776.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41776.rs new file mode 100644 index 000000000000..e7d5415dfdd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41776.rs @@ -0,0 +1,4 @@ +fn main() { + include!(line!()); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41803.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41803.rs new file mode 100644 index 000000000000..a56d9fc47f5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41803.rs @@ -0,0 +1,22 @@ +// run-pass +/// A compile-time map from identifiers to arbitrary (heterogeneous) expressions +macro_rules! ident_map { + ( $name:ident = { $($key:ident => $e:expr,)* } ) => { + macro_rules! $name { + $( + ( $key ) => { $e }; + )* + // Empty invocation expands to nothing. Needed when the map is empty. + () => {}; + } + }; +} + +ident_map!(my_map = { + main => 0, +}); + +fn main() { + my_map!(main); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41849-variance-req.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41849-variance-req.rs new file mode 100644 index 000000000000..ba0ea02400ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41849-variance-req.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(dead_code)] +// Regression test for #41849. + +use std::ops::Mul; + +const C: usize = 1; +const CAPACITY: usize = 1 * C; + +struct A { + f: [X; CAPACITY], +} + +struct B { + f: T, +} + +impl Mul for B { + type Output = Self; + fn mul(self, _rhs: B) -> Self::Output { + self + } +} + +impl Mul for B { + type Output = Self; + fn mul(self, _rhs: usize) -> Self::Output { + self + } +} + +fn main() { + let a = A { f: [1] }; + let _ = B { f: a }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41880.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41880.rs new file mode 100644 index 000000000000..c56daf1a9356 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41880.rs @@ -0,0 +1,30 @@ +fn iterate(initial: T, f: F) -> Iterate { + Iterate { + state: initial, + f: f, + } +} + +pub struct Iterate { + state: T, + f: F +} + +impl Iterator for Iterate where F: Fn(&T) -> T { + type Item = T; + + #[inline] + fn next(&mut self) -> Option { + self.state = (self.f)(&self.state); + Some(self.state.clone()) + } + #[inline] + fn size_hint(&self) -> (usize, Option) { (std::usize::MAX, None) } +} + +fn main() { + let a = iterate(0, |x| x+1); + println!("{:?}", a.iter().take(10).collect::>()); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41888.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41888.rs new file mode 100644 index 000000000000..7d26c90f637d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41888.rs @@ -0,0 +1,35 @@ +// run-pass +fn main() { let _ = g(Some(E::F(K))); } + +type R = Result<(), ()>; +struct K; + +enum E { + F(K), // must not be built-in type + #[allow(dead_code)] + G(Box, Box), +} + +fn translate(x: R) -> R { x } + +fn g(mut status: Option) -> R { + loop { + match status { + Some(infix_or_postfix) => match infix_or_postfix { + E::F(_op) => { // <- must be captured by value + match Ok(()) { + Err(err) => return Err(err), + Ok(_) => {}, + }; + } + _ => (), + }, + _ => match translate(Err(())) { + Err(err) => return Err(err), + Ok(_) => {}, + } + } + status = None; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs new file mode 100644 index 000000000000..f4b6408a3ad3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs @@ -0,0 +1,31 @@ +// check-pass +#![allow(dead_code)] +// Regression test for #41936. The coerce-unsized trait check in +// coherence was using subtyping, which triggered variance +// computation, which failed because it required type info for fields +// that had not (yet) been computed. + +#![feature(unsize)] +#![feature(coerce_unsized)] + +use std::{marker,ops}; + +// Change the array to a non-array, and error disappears +// Adding a new field to the end keeps the error +struct LogDataBuf([u8;8]); + +struct Aref +{ + // Inner structure triggers the error, removing the inner removes the message. + ptr: Box>, +} +impl, U: ?Sized> ops::CoerceUnsized> for Aref {} + +struct ArefInner +{ + // Even with this field commented out, the error is raised. + data: T, +} + +fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41974.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41974.rs new file mode 100644 index 000000000000..a2d7fd08ed8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41974.rs @@ -0,0 +1,15 @@ +#[derive(Copy, Clone)] +struct Flags; + +trait A { +} + +impl Drop for T where T: A { // { dg-error ".E0210." "" { target *-*-* } } +// { dg-error ".E0210." "" { target *-*-* } .-1 } +// { dg-error ".E0210." "" { target *-*-* } .-2 } + fn drop(&mut self) { + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-41998.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-41998.rs new file mode 100644 index 000000000000..a6406379e40c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-41998.rs @@ -0,0 +1,11 @@ +// check-pass + + +fn main() { + if ('x' as char) < ('y' as char) { + print!("x"); + } else { + print!("y"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42007.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42007.rs new file mode 100644 index 000000000000..b54c4fca497d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42007.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +// aux-build:issue-42007-s.rs + +extern crate issue_42007_s; + +enum I { + E(issue_42007_s::E), +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4201.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4201.rs new file mode 100644 index 000000000000..0a02c6d89934 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4201.rs @@ -0,0 +1,10 @@ +fn main() { + let a = if true { + 0 + } else if false { +// { dg-error ".E0317." "" { target *-*-* } .-1 } +// { dg-error ".E0317." "" { target *-*-* } .-2 } + 1 + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42060.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42060.rs new file mode 100644 index 000000000000..067d16278b3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42060.rs @@ -0,0 +1,12 @@ +fn main() { + let thing = (); + let other: typeof(thing) = thing; // { dg-error ".E0516." "" { target *-*-* } } +// { dg-error ".E0516." "" { target *-*-* } .-1 } +} + +fn f(){ + let q = 1; + ::N // { dg-error ".E0516." "" { target *-*-* } } +// { dg-error ".E0516." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4208.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4208.rs new file mode 100644 index 000000000000..0c6d3840ed39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4208.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +// aux-build:issue-4208-cc.rs + +// pretty-expanded FIXME #23616 + +extern crate numeric; +use numeric::{sin, Angle}; + +fn foo>(theta: A) -> T { sin(&theta) } + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42106.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42106.rs new file mode 100644 index 000000000000..81aca419e58c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42106.rs @@ -0,0 +1,11 @@ +fn do_something(collection: &mut Vec) { + let _a = &collection; + collection.swap(1, 2); // { dg-error ".E0502." "" { target *-*-* } } + _a.use_ref(); +} + +fn main() { } + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42148.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42148.rs new file mode 100644 index 000000000000..46b8bad0e660 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42148.rs @@ -0,0 +1,7 @@ +// run-pass +struct Zst; + +fn main() { + unsafe { ::std::ptr::write_volatile(1 as *mut Zst, Zst) } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42210.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42210.rs new file mode 100644 index 000000000000..6c0e36a5b3b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42210.rs @@ -0,0 +1,22 @@ +// run-pass +// Regression test for #42210. + +// compile-flags: -g +// ignore-asmjs wasm2js does not support source maps yet + +trait Foo { + fn foo() { } +} + +struct Bar; + +trait Baz { +} + +impl Foo for (Bar, dyn Baz) { } + + +fn main() { + <(Bar, dyn Baz) as Foo>::foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4228.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4228.rs new file mode 100644 index 000000000000..f24db682f548 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4228.rs @@ -0,0 +1,17 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct Foo; + +impl Foo { + fn first() {} +} +impl Foo { + fn second() {} +} + +pub fn main() { + Foo::first(); + Foo::second(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42312.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42312.rs new file mode 100644 index 000000000000..cf64a9e03423 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42312.rs @@ -0,0 +1,12 @@ +use std::ops::Deref; + +pub trait Foo { + fn baz(_: Self::Target) where Self: Deref {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +pub fn f(_: dyn ToString) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42344.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42344.rs new file mode 100644 index 000000000000..44532526d2f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42344.rs @@ -0,0 +1,9 @@ +static TAB: [&mut [u8]; 0] = []; + +pub unsafe fn test() { + TAB[0].iter_mut(); +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42453.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42453.rs new file mode 100644 index 000000000000..bea441c2bea3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42453.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +#[derive(Debug)] +struct builder; + +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42463.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42463.rs new file mode 100644 index 000000000000..f52cf7a7654e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42463.rs @@ -0,0 +1,33 @@ +// run-pass +use std::ops::{Deref, DerefMut}; + +struct CheckedDeref { + value: T, + check: F +} + +impl bool, T> Deref for CheckedDeref { + type Target = T; + fn deref(&self) -> &T { + assert!((self.check)(&self.value)); + &self.value + } +} + +impl bool, T> DerefMut for CheckedDeref { + fn deref_mut(&mut self) -> &mut T { + assert!((self.check)(&self.value)); + &mut self.value + } +} + + +fn main() { + let mut v = CheckedDeref { + value: vec![0], + check: |v: &Vec<_>| !v.is_empty() + }; + v.push(1); + assert_eq!(*v, vec![0, 1]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42467.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42467.rs new file mode 100644 index 000000000000..a40dfde4082d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42467.rs @@ -0,0 +1,25 @@ +// check-pass +#![allow(dead_code)] +struct Foo(T); + +struct IntoIter(T); + +impl<'a, T: 'a> Iterator for IntoIter { + type Item = (); + + fn next(&mut self) -> Option<()> { + None + } +} + +impl IntoIterator for Foo { + type Item = (); + type IntoIter = IntoIter; + + fn into_iter(self) -> IntoIter { + IntoIter(self.0) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4252.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4252.rs new file mode 100644 index 000000000000..3964f1db3dcf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4252.rs @@ -0,0 +1,34 @@ +// run-pass +trait X { + fn call(&self, x: &T); + fn default_method(&self, x: &T) { + println!("X::default_method {:?}", x); + } +} + +#[derive(Debug)] +struct Y(isize); + +#[derive(Debug)] +struct Z { + x: T +} + +impl X for Y { + fn call(&self, x: &T) { + println!("X::call {:?} {:?}", self, x); + } +} + +impl Drop for Z { + fn drop(&mut self) { + // These statements used to cause an ICE. + self.x.call(self); + self.x.default_method(self); + } +} + +pub fn main() { + let _z = Z {x: Y(42)}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42552.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42552.rs new file mode 100644 index 000000000000..50c718852950 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42552.rs @@ -0,0 +1,32 @@ +// run-pass +// Regression test for an obscure issue with the projection cache. + +fn into_iter(a: &I) -> Groups { + Groups { _a: a } +} + +pub struct Groups<'a, I: 'a> { + _a: &'a I, +} + +impl<'a, I: Iterator> Iterator for Groups<'a, I> { + type Item = Group<'a, I>; + fn next(&mut self) -> Option { + None + } +} + +pub struct Group<'a, I: Iterator + 'a> + where I::Item: 'a // <-- needed to trigger ICE! +{ + _phantom: &'a (), + _ice_trigger: I::Item, // <-- needed to trigger ICE! +} + + +fn main() { + let _ = into_iter(&[0].iter().map(|_| 0)).map(|grp| { + let _g = grp; + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4265.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4265.rs new file mode 100644 index 000000000000..1c37f7aebfd4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4265.rs @@ -0,0 +1,15 @@ +struct Foo { + baz: usize +} + +impl Foo { + fn bar() { + Foo { baz: 0 }.bar(); + } + + fn bar() { // { dg-error ".E0201." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42679.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42679.rs new file mode 100644 index 000000000000..ee3f30a48bd8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42679.rs @@ -0,0 +1,23 @@ +// run-pass +#![feature(box_syntax)] +#![feature(box_patterns)] + +#[derive(Debug, PartialEq)] +enum Test { + Foo(usize), + Bar(isize), +} + +fn main() { + let a = box Test::Foo(10); + let b = box Test::Bar(-20); + match (a, b) { + (_, box Test::Foo(_)) => unreachable!(), + (box Test::Foo(x), b) => { + assert_eq!(x, 10); + assert_eq!(b, box Test::Bar(-20)); + }, + _ => unreachable!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42747.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42747.rs new file mode 100644 index 000000000000..936ff16900e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42747.rs @@ -0,0 +1,47 @@ +// run-pass +macro_rules! fooN { + ($cur:ident $prev:ty) => { + #[allow(dead_code)] + enum $cur { + Empty, + First($prev), + Second($prev), + Third($prev), + Fourth($prev), + } + } +} + +fooN!(Foo0 ()); +fooN!(Foo1 Foo0); +fooN!(Foo2 Foo1); +fooN!(Foo3 Foo2); +fooN!(Foo4 Foo3); +fooN!(Foo5 Foo4); +fooN!(Foo6 Foo5); +fooN!(Foo7 Foo6); +fooN!(Foo8 Foo7); +fooN!(Foo9 Foo8); +fooN!(Foo10 Foo9); +fooN!(Foo11 Foo10); +fooN!(Foo12 Foo11); +fooN!(Foo13 Foo12); +fooN!(Foo14 Foo13); +fooN!(Foo15 Foo14); +fooN!(Foo16 Foo15); +fooN!(Foo17 Foo16); +fooN!(Foo18 Foo17); +fooN!(Foo19 Foo18); +fooN!(Foo20 Foo19); +fooN!(Foo21 Foo20); +fooN!(Foo22 Foo21); +fooN!(Foo23 Foo22); +fooN!(Foo24 Foo23); +fooN!(Foo25 Foo24); +fooN!(Foo26 Foo25); +fooN!(Foo27 Foo26); + +fn main() { + let _foo = Foo27::Empty; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42755.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42755.rs new file mode 100644 index 000000000000..d26d5628ee90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42755.rs @@ -0,0 +1,8 @@ +macro_rules! foo { + ($($p:vis)*) => {} // { dg-error "" "" { target *-*-* } } +} + +foo!(a); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42796.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42796.rs new file mode 100644 index 000000000000..2773eb90363b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42796.rs @@ -0,0 +1,20 @@ +pub trait Mirror { + type Image; +} + +impl Mirror for T { + type Image = T; +} + +pub fn poison(victim: String) where >::Image: Copy { + loop { drop(victim); } +} + +fn main() { + let s = "Hello!".to_owned(); + let mut s_copy = s; + s_copy.push_str("World!"); + "0wned!".to_owned(); + println!("{}", s); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42880.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42880.rs new file mode 100644 index 000000000000..9688ec6f4359 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42880.rs @@ -0,0 +1,9 @@ +type Value = String; + +fn main() { + let f = |&Value::String(_)| (); // { dg-error ".E0599." "" { target *-*-* } } + + let vec: Vec = Vec::new(); + vec.last().map(f); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42944.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42944.rs new file mode 100644 index 000000000000..51ad3e5b3b91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42944.rs @@ -0,0 +1,22 @@ +mod foo { + pub struct Bx(()); +} + +mod bar { + use foo::Bx; + + fn foo() { + Bx(()); +// { dg-error ".E0423." "" { target *-*-* } .-1 } + } +} + +mod baz { + fn foo() { + Bx(()); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42954.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42954.rs new file mode 100644 index 000000000000..e4a9821ae14a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42954.rs @@ -0,0 +1,15 @@ +// run-rustfix + +#![allow(unused_must_use, unused_comparisons)] + +macro_rules! is_plainly_printable { + ($i: ident) => { + $i as u32 < 0 // { dg-error "" "" { target *-*-* } } + }; +} + +fn main() { + let c = 'a'; + is_plainly_printable!(c); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-42956.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-42956.rs new file mode 100644 index 000000000000..0a54fabb4286 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-42956.rs @@ -0,0 +1,27 @@ +// check-pass +#![allow(dead_code)] +#![allow(stable_features)] +#![feature(associated_consts)] + +impl A for i32 { + type Foo = u32; +} +impl B for u32 { + const BAR: i32 = 0; +} + +trait A { + type Foo: B; +} + +trait B { + const BAR: i32; +} + +fn generic() { + // This panics if the universal function call syntax is used as well + println!("{}", T::Foo::BAR); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43023.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43023.rs new file mode 100644 index 000000000000..fa9602e8379e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43023.rs @@ -0,0 +1,21 @@ +struct S; + +impl S { + #[derive(Debug)] // { dg-error ".E0774." "" { target *-*-* } } + fn f() { + file!(); + } +} + +trait Tr1 { + #[derive(Debug)] // { dg-error ".E0774." "" { target *-*-* } } + fn f(); +} + +trait Tr2 { + #[derive(Debug)] // { dg-error ".E0774." "" { target *-*-* } } + type F; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43057.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43057.rs new file mode 100644 index 000000000000..908f1c8ec751 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43057.rs @@ -0,0 +1,15 @@ +// check-pass +#![allow(unused)] + +macro_rules! column { + ($i:ident) => { + $i + }; +} + +fn foo() -> ! { + panic!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43105.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43105.rs new file mode 100644 index 000000000000..728507ec659a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43105.rs @@ -0,0 +1,15 @@ +fn xyz() -> u8 { 42 } + +const NUM: u8 = xyz(); +// { dg-error ".E0015." "" { target *-*-* } .-1 } +// { dg-error ".E0015." "" { target *-*-* } .-2 } + +fn main() { + match 1 { + NUM => unimplemented!(), +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + _ => unimplemented!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43132.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43132.rs new file mode 100644 index 000000000000..ae43bd8125f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43132.rs @@ -0,0 +1,66 @@ +// run-pass +#![allow(unused)] + +fn main() { +} + +fn foo() { + let b = mk::< + Forward<(Box>,)>, + >(); + b.map_err(|_| ()).join(); +} + +fn mk() -> T { + loop {} +} + +impl, E> Future for (I,) { + type Error = E; +} + +struct Forward { + _a: T, +} + +impl Future for Forward +where + T::Error: From, +{ + type Error = T::Error; +} + +trait Future { + type Error; + + fn map_err(self, _: F) -> (Self, F) + where + F: FnOnce(Self::Error) -> E, + Self: Sized, + { + loop {} + } + + fn join(self) -> (MaybeDone, ()) + where + Self: Sized, + { + loop {} + } +} + +impl Future for Box { + type Error = S::Error; +} + +enum MaybeDone { + _Done(A::Error), +} + +impl Future for (A, F) +where + F: FnOnce(A::Error) -> U, +{ + type Error = U; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43162.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43162.rs new file mode 100644 index 000000000000..131d3596c65e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43162.rs @@ -0,0 +1,9 @@ +fn foo() -> bool { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + break true; // { dg-error ".E0268." "" { target *-*-* } } +} + +fn main() { + break {}; // { dg-error ".E0268." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43189.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43189.rs new file mode 100644 index 000000000000..4387abb83ffb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43189.rs @@ -0,0 +1,13 @@ +// Issue 46112: An extern crate pub re-exporting libcore was causing +// paths rooted from `std` to be misrendered in the diagnostic output. + +// ignore-windows +// aux-build:xcrate-issue-43189-a.rs +// aux-build:xcrate-issue-43189-b.rs + +extern crate xcrate_issue_43189_b; +fn main() { + ().a(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43196.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43196.rs new file mode 100644 index 000000000000..d889fc9c59b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43196.rs @@ -0,0 +1,7 @@ +fn main() { + | +} +// { dg-error "" "" { target *-*-* } .-1 } +| +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43205.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43205.rs new file mode 100644 index 000000000000..aff937914d5a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43205.rs @@ -0,0 +1,6 @@ +// run-pass +fn main() { + &&[()][0]; + println!("{:?}", &[(),()][1]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4321.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4321.rs new file mode 100644 index 000000000000..d46ae5943c37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4321.rs @@ -0,0 +1,9 @@ +fn main() { + let tup = (true, true); + println!("foo {:}", match tup { // { dg-error ".E0004." "" { target *-*-* } } + (false, false) => "foo", + (false, true) => "bar", + (true, true) => "baz" + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43250.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43250.rs new file mode 100644 index 000000000000..fbe0e89768e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43250.rs @@ -0,0 +1,14 @@ +fn main() { + let mut y; + const C: u32 = 0; + macro_rules! m { + ($a:expr) => { + let $a = 0; + } + } + m!(y); +// { dg-error "" "" { target *-*-* } .-1 } + m!(C); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43291.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43291.rs new file mode 100644 index 000000000000..be3391a006d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43291.rs @@ -0,0 +1,10 @@ +// run-pass +pub fn main() { + assert_eq!(!0usize as *const (), foo(0, 1)); + assert_eq!(!0usize as *const (), (0i8 - 1) as *const ()); +} + +pub fn foo(a: i8, b: i8) -> *const () { + (a - b) as *const () +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4333.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4333.rs new file mode 100644 index 000000000000..9002568aeee7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4333.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_must_use)] +// pretty-expanded FIXME #23616 + +use std::io; + +pub fn main() { + let stdout = &mut io::stdout() as &mut dyn io::Write; + stdout.write(b"Hello!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4335.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4335.rs new file mode 100644 index 000000000000..d684bc1a2581 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4335.rs @@ -0,0 +1,14 @@ +#![feature(fn_traits)] + +fn id(t: T) -> T { t } + +fn f<'r, T>(v: &'r T) -> Box T + 'r> { + id(Box::new(|| *v)) +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + +fn main() { + let v = &5; + println!("{}", f(v).call_mut(())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43355.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43355.rs new file mode 100644 index 000000000000..844d8dc9874a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43355.rs @@ -0,0 +1,20 @@ +pub trait Trait1 { + type Output; +} + +pub trait Trait2 {} + +pub struct A; + +impl Trait1 for T where T: Trait2 { + type Output = (); +} + +impl Trait1> for A { +// { dg-error ".E0119." "" { target *-*-* } .-1 } +// { dg-error ".E0119." "" { target *-*-* } .-2 } + type Output = i32; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43357.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43357.rs new file mode 100644 index 000000000000..78e02796c7f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43357.rs @@ -0,0 +1,12 @@ +// check-pass +#![allow(dead_code)] +trait Trait { + type Output; +} + +fn f() { + std::mem::size_of::(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43398.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43398.rs new file mode 100644 index 000000000000..57b099d8d007 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43398.rs @@ -0,0 +1,15 @@ +// run-pass + +#![feature(core_intrinsics)] +#![feature(repr128)] +// { dg-warning "" "" { target *-*-* } .-1 } + +#[repr(i128)] +enum Big { A, B } + +fn main() { + println!("{} {:?}", + std::intrinsics::discriminant_value(&Big::A), + std::mem::discriminant(&Big::B)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43420-no-over-suggest.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43420-no-over-suggest.rs new file mode 100644 index 000000000000..0a40e21a49aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43420-no-over-suggest.rs @@ -0,0 +1,10 @@ +// check that we substitute type parameters before we suggest anything - otherwise +// we would suggest function such as `as_slice` for the `&[u16]`. + +fn foo(b: &[u16]) {} + +fn main() { + let a: Vec = Vec::new(); + foo(&a); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43424.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43424.rs new file mode 100644 index 000000000000..af02dd3ece98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43424.rs @@ -0,0 +1,13 @@ +#![allow(unused)] + +macro_rules! m { + ($attr_path: path) => { + #[$attr_path] + fn f() {} + } +} + +m!(inline); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43431.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43431.rs new file mode 100644 index 000000000000..3c8d4ee21d29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43431.rs @@ -0,0 +1,15 @@ +#![feature(fn_traits)] + +trait CallSingle { + fn call(&self, a: A) -> B where Self: Sized, Self: Fn(A) -> B; +} + +impl B> CallSingle for F { + fn call(&self, a: A) -> B { + B>::call(self, (a,)) +// { dg-error ".E0229." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43483.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43483.rs new file mode 100644 index 000000000000..4ede4fdf7c7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43483.rs @@ -0,0 +1,17 @@ +// check-pass +#![allow(dead_code)] +#![allow(unused_variables)] +trait VecN { + const DIM: usize; +} + +trait Mat { + type Row: VecN; +} + +fn m() { + let x = M::Row::DIM; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43623.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43623.rs new file mode 100644 index 000000000000..b260985be4a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43623.rs @@ -0,0 +1,21 @@ +pub trait Trait<'a> { + type Assoc; +} + +pub struct Type; + +impl<'a> Trait<'a> for Type { + type Assoc = (); +} + +pub fn break_me(f: F) +where + T: for<'b> Trait<'b>, + F: for<'b> FnMut(>::Assoc), +{ + break_me::; +// { dg-error ".E0631." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4366-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4366-2.rs new file mode 100644 index 000000000000..14d4580198f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4366-2.rs @@ -0,0 +1,27 @@ +// ensures that 'use foo:*' doesn't import non-public item + +use m1::*; + +mod foo { + pub fn foo() {} +} +mod a { + pub mod b { + use foo::foo; + type Bar = isize; + } + pub mod sub { + use a::b::*; + fn sub() -> Bar { 1 } +// { dg-error ".E0412." "" { target *-*-* } .-1 } + } +} + +mod m1 { + fn foo() {} +} + +fn main() { + foo(); // { dg-error ".E0423." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4366.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4366.rs new file mode 100644 index 000000000000..6579ff5d4714 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4366.rs @@ -0,0 +1,27 @@ +// regression test for issue 4366 + +// ensures that 'use foo:*' doesn't import non-public 'use' statements in the +// module 'foo' + +use m1::*; + +mod foo { + pub fn foo() {} +} +mod a { + pub mod b { + use foo::foo; + type Bar = isize; + } + pub mod sub { + use a::b::*; + fn sub() -> isize { foo(); 1 } // { dg-error ".E0425." "" { target *-*-* } } + } +} + +mod m1 { + fn foo() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43692.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43692.rs new file mode 100644 index 000000000000..d90270b97656 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43692.rs @@ -0,0 +1,6 @@ +// run-pass +fn main() { + assert_eq!('\u{10__FFFF}', '\u{10FFFF}'); + assert_eq!("\u{10_F0FF__}foo\u{1_0_0_0__}", "\u{10F0FF}foo\u{1000}"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43733.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43733.rs new file mode 100644 index 000000000000..a5d92b19f810 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43733.rs @@ -0,0 +1,32 @@ +#![feature(const_fn)] +#![feature(thread_local)] +#![feature(cfg_target_thread_local, thread_local_internals)] + +type Foo = std::cell::RefCell; + +#[cfg(target_thread_local)] +#[thread_local] +static __KEY: std::thread::__FastLocalKeyInner = + std::thread::__FastLocalKeyInner::new(); + +#[cfg(not(target_thread_local))] +static __KEY: std::thread::__OsLocalKeyInner = + std::thread::__OsLocalKeyInner::new(); + +fn __getit() -> std::option::Option<&'static Foo> +{ + __KEY.get(Default::default) // { dg-error ".E0133." "" { target *-*-* } } +} + +static FOO: std::thread::LocalKey = + std::thread::LocalKey::new(__getit); +// { dg-error ".E0133." "" { target *-*-* } .-1 } + +fn main() { + FOO.with(|foo| println!("{}", foo.borrow())); + std::thread::spawn(|| { + FOO.with(|foo| *foo.borrow_mut() += "foo"); + }).join().unwrap(); + FOO.with(|foo| println!("{}", foo.borrow())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43784-associated-type.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43784-associated-type.rs new file mode 100644 index 000000000000..c7765f7b4a0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43784-associated-type.rs @@ -0,0 +1,18 @@ +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; // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43784-supertrait.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43784-supertrait.rs new file mode 100644 index 000000000000..79e516384556 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43784-supertrait.rs @@ -0,0 +1,11 @@ +pub trait Partial: Copy { +} + +pub trait Complete: Partial { +} + +impl Partial for T where T: Complete {} +impl Complete for T {} // { dg-error ".E0277." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43806.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43806.rs new file mode 100644 index 000000000000..cd96d672e4df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43806.rs @@ -0,0 +1,24 @@ +// check-pass + +#![deny(unused_results)] + +enum Void {} + +fn foo() {} + +fn bar() -> ! { + loop {} +} + +fn baz() -> Void { + loop {} +} + +fn qux() { + foo(); + bar(); + baz(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43853.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43853.rs new file mode 100644 index 000000000000..bb8c4f9c7618 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43853.rs @@ -0,0 +1,18 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default + +use std::panic; + +fn test() { + wait(|| panic!()); +} + +fn wait T>(f: F) -> F::Output { + From::from(f()) +} + +fn main() { + let result = panic::catch_unwind(move || test()); + assert!(result.is_err()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4387.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4387.rs new file mode 100644 index 000000000000..d528d7b88f60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4387.rs @@ -0,0 +1,7 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + let _foo = [0; 2*4]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43910.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43910.rs new file mode 100644 index 000000000000..0446616b79e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43910.rs @@ -0,0 +1,8 @@ +// run-pass +#![deny(unused_variables)] + +fn main() { + #[allow(unused_variables)] + let x = 12; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43923.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43923.rs new file mode 100644 index 000000000000..3b6cb1855463 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43923.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +struct A { ptr: T } + +fn foo(x: &A<[T]>) {} + +fn main() { + let a = foo; + let b = A { ptr: [a, a, a] }; + a(&A { ptr: [()] }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43925.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43925.rs new file mode 100644 index 000000000000..41d827c58bc0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43925.rs @@ -0,0 +1,5 @@ +#[link(name="foo", cfg("rlib"))] // { dg-error "" "" { target *-*-* } } +extern {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43926.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43926.rs new file mode 100644 index 000000000000..7114d29afc41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43926.rs @@ -0,0 +1,5 @@ +#[link(name="foo", cfg())] // { dg-error "" "" { target *-*-* } } +extern {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-43988.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-43988.rs new file mode 100644 index 000000000000..55367c575903 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-43988.rs @@ -0,0 +1,37 @@ +#![feature(stmt_expr_attributes)] + +fn main() { + + #[inline] + let _a = 4; +// { dg-error ".E0518." "" { target *-*-* } .-2 } + + + #[inline(XYZ)] + let _b = 4; +// { dg-error ".E0518." "" { target *-*-* } .-2 } + + #[repr(nothing)] + let _x = 0; +// { dg-error ".E0517." "" { target *-*-* } .-2 } + + #[repr(something_not_real)] + loop { + () + }; +// { dg-error ".E0517." "" { target *-*-* } .-4 } + + #[repr] + let _y = "123"; +// { dg-error "" "" { target *-*-* } .-2 } + + fn foo() {} + + #[inline(ABC)] + foo(); +// { dg-error ".E0518." "" { target *-*-* } .-2 } + + let _z = #[repr] 1; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44005.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44005.rs new file mode 100644 index 000000000000..da68175c3421 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44005.rs @@ -0,0 +1,30 @@ +// build-pass +pub trait Foo<'a> { + type Bar; + fn foo(&'a self) -> Self::Bar; +} + +impl<'a, 'b, T: 'a> Foo<'a> for &'b T { + type Bar = &'a T; + fn foo(&'a self) -> &'a T { + self + } +} + +pub fn uncallable(x: T, f: F) + where T: for<'a> Foo<'a>, + F: for<'a> Fn(>::Bar) +{ + f(x.foo()); +} + +pub fn catalyst(x: &i32) { + broken(x, |_| {}) +} + +pub fn broken(x: &i32, f: F) { + uncallable(x, |y| f(y)); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4401.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4401.rs new file mode 100644 index 000000000000..6c9b12ec2c26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4401.rs @@ -0,0 +1,8 @@ +// run-pass +pub fn main() { + let mut count = 0; + for _ in 0..999_999 { count += 1; } + assert_eq!(count, 999_999); + println!("{}", count); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44021.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44021.rs new file mode 100644 index 000000000000..b57fb290c8fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44021.rs @@ -0,0 +1,7 @@ +struct MyStruct; +impl MyStruct { + fn f() {|x, y} // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44023.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44023.rs new file mode 100644 index 000000000000..941613bd2666 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44023.rs @@ -0,0 +1,7 @@ +#![feature(non_ascii_idents)] + +pub fn main () {} + +fn საჭმელად_გემრიელი_სადილი ( ) -> isize { // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44056.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44056.rs new file mode 100644 index 000000000000..bcd70983bd67 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44056.rs @@ -0,0 +1,7 @@ +// build-pass (FIXME(55996): should be run on targets supporting avx) +// only-x86_64 +// no-prefer-dynamic +// compile-flags: -Ctarget-feature=+avx -Clto + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44078.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44078.rs new file mode 100644 index 000000000000..358dadc32ccf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44078.rs @@ -0,0 +1,4 @@ +fn main() { + "😊""; // { dg-error ".E0765." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44127.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44127.rs new file mode 100644 index 000000000000..2d26b8aa6cd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44127.rs @@ -0,0 +1,18 @@ +// run-pass + +#![feature(decl_macro)] + +pub struct Foo { + bar: u32, +} +pub macro pattern($a:pat) { + Foo { bar: $a } +} + +fn main() { + match (Foo { bar: 3 }) { + pattern!(3) => println!("Test OK"), + _ => unreachable!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44216-add-instant.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44216-add-instant.rs new file mode 100644 index 000000000000..1ae34e3c8040 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44216-add-instant.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:overflow +// ignore-emscripten no processes + +use std::time::{Instant, Duration}; + +fn main() { + let now = Instant::now(); + let _ = now + Duration::from_secs(u64::MAX); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44216-add-system-time.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44216-add-system-time.rs new file mode 100644 index 000000000000..650a5c4bfb21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44216-add-system-time.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:overflow +// ignore-emscripten no processes + +use std::time::{Duration, SystemTime}; + +fn main() { + let now = SystemTime::now(); + let _ = now + Duration::from_secs(u64::MAX); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44216-sub-instant.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44216-sub-instant.rs new file mode 100644 index 000000000000..ac752e62fe24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44216-sub-instant.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:overflow +// ignore-emscripten no processes + +use std::time::{Instant, Duration}; + +fn main() { + let now = Instant::now(); + let _ = now - Duration::from_secs(u64::MAX); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44216-sub-system-time.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44216-sub-system-time.rs new file mode 100644 index 000000000000..64c13559ce9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44216-sub-system-time.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:overflow +// ignore-emscripten no processes + +use std::time::{Duration, SystemTime}; + +fn main() { + let now = SystemTime::now(); + let _ = now - Duration::from_secs(u64::MAX); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44239.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44239.rs new file mode 100644 index 000000000000..bcc9a864bc86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44239.rs @@ -0,0 +1,10 @@ +fn main() { + let n = 0; + + struct Foo; + impl Foo { + const N: usize = n; +// { dg-error ".E0435." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44247.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44247.rs new file mode 100644 index 000000000000..e76f19c6f780 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44247.rs @@ -0,0 +1,20 @@ +// check-pass +#![allow(dead_code)] +trait T { + type X; + const X: Self::X; +} +fn foo() { + let _: X::X = X::X; +} + +trait S { + const X: Self::X; + type X; +} +fn bar() { + let _: X::X = X::X; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44255.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44255.rs new file mode 100644 index 000000000000..932be5c44a85 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44255.rs @@ -0,0 +1,30 @@ +// run-pass + +use std::marker::PhantomData; + +fn main() { + let _arr = [1; >::VAL]; +} + +trait TypeVal { + const VAL: T; +} + +struct Five; + +impl TypeVal for Five { + const VAL: usize = 5; +} + +struct Multiply { + _n: PhantomData, + _m: PhantomData, +} + +impl TypeVal for Multiply + where N: TypeVal, + M: TypeVal, +{ + const VAL: usize = N::VAL * M::VAL; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44373-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44373-2.rs new file mode 100644 index 000000000000..7b843d228841 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44373-2.rs @@ -0,0 +1,12 @@ +// check-pass +#![allow(dead_code)] + +struct Foo(bool); + +struct Container(&'static [&'static Foo]); + +static FOO: Foo = Foo(true); +static CONTAINER: Container = Container(&[&FOO]); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44373.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44373.rs new file mode 100644 index 000000000000..340b042bfa0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44373.rs @@ -0,0 +1,6 @@ +static FOO: u32 = 50; + +fn main() { + let _val: &'static [&'static u32] = &[&FOO]; // { dg-error ".E0716." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44405.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44405.rs new file mode 100644 index 000000000000..3a24a39add98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44405.rs @@ -0,0 +1,23 @@ +use std::ops::Index; + +struct Test; +struct Container(Test); + +impl Test { + fn test(&mut self) {} +} + +impl<'a> Index<&'a bool> for Container { + type Output = Test; + + fn index(&self, _index: &'a bool) -> &Test { + &self.0 + } +} + +fn main() { + let container = Container(Test); + let mut val = true; + container[&mut val].test(); // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44406.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44406.rs new file mode 100644 index 000000000000..bdd854d71889 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44406.rs @@ -0,0 +1,11 @@ +macro_rules! foo { + ($rest: tt) => { + bar(baz: $rest) + } +} + +fn main() { + foo!(true); // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4446.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4446.rs new file mode 100644 index 000000000000..1547583d46da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4446.rs @@ -0,0 +1,16 @@ +// run-pass +// ignore-emscripten no threads support + +use std::sync::mpsc::channel; +use std::thread; + +pub fn main() { + let (tx, rx) = channel(); + + tx.send("hello, world").unwrap(); + + thread::spawn(move|| { + println!("{}", rx.recv().unwrap()); + }).join().ok().unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4448.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4448.rs new file mode 100644 index 000000000000..d4da94f716f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4448.rs @@ -0,0 +1,17 @@ +// run-pass +// ignore-emscripten no threads support + +use std::sync::mpsc::channel; +use std::thread; + +pub fn main() { + let (tx, rx) = channel::<&'static str>(); + + let t = thread::spawn(move|| { + assert_eq!(rx.recv().unwrap(), "hello, world"); + }); + + tx.send("hello, world").unwrap(); + t.join().ok().unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4464.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4464.rs new file mode 100644 index 000000000000..f997d1b64cd8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4464.rs @@ -0,0 +1,8 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn broken(v: &[u8], i: usize, j: usize) -> &[u8] { &v[i..j] } + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44730.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44730.rs new file mode 100644 index 000000000000..f8a348621db4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44730.rs @@ -0,0 +1,16 @@ +// check-pass +//! dox + +#![deny(missing_docs)] + +macro_rules! doc { + ($e:expr) => ( + #[doc = $e] + pub struct Foo; + ) +} + +doc!("a"); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-44851.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-44851.rs new file mode 100644 index 000000000000..3477f26f6b88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-44851.rs @@ -0,0 +1,16 @@ +// check-pass +macro_rules! a { + () => { "a" } +} + +macro_rules! b { + ($doc:expr) => { + #[doc = $doc] + pub struct B; + } +} + +b!(a!()); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45087-unreachable-unsafe.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45087-unreachable-unsafe.rs new file mode 100644 index 000000000000..0e4046bc177e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45087-unreachable-unsafe.rs @@ -0,0 +1,6 @@ +fn main() { + return; + *(1 as *mut u32) = 42; +// { dg-error ".E0133." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45107-unnecessary-unsafe-in-closure.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45107-unnecessary-unsafe-in-closure.rs new file mode 100644 index 000000000000..64d9931f1baf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45107-unnecessary-unsafe-in-closure.rs @@ -0,0 +1,26 @@ +#[deny(unused_unsafe)] +fn main() { + let mut v = Vec::::with_capacity(24); + + unsafe { + let f = |v: &mut Vec<_>| { + unsafe { // { dg-error "" "" { target *-*-* } } + v.set_len(24); + |w: &mut Vec| { unsafe { // { dg-error "" "" { target *-*-* } } + w.set_len(32); + } }; + } + |x: &mut Vec| { unsafe { // { dg-error "" "" { target *-*-* } } + x.set_len(40); + } }; + }; + + v.set_len(0); + f(&mut v); + } + + |y: &mut Vec| { unsafe { + y.set_len(48); + } }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45124.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45124.rs new file mode 100644 index 000000000000..4d0d5f92075e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45124.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unreachable_code)] +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +fn main() { + let mut a = 0; + let () = { + let _: Result<(), ()> = try { + let _ = Err(())?; + return + }; + a += 1; + }; + a += 2; + assert_eq!(a, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45152.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45152.rs new file mode 100644 index 000000000000..fad4496a21ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45152.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![feature(unsize, coerce_unsized)] + +#[repr(packed)] +struct UnalignedPtr<'a, T: ?Sized> + where T: 'a, +{ + data: &'a T, +} + +fn main() { + + impl<'a, T, U> std::ops::CoerceUnsized> for UnalignedPtr<'a, T> + where + T: std::marker::Unsize + ?Sized, + U: ?Sized, + { } + + let arr = [1, 2, 3]; + let arr_unaligned: UnalignedPtr<[i32; 3]> = UnalignedPtr { data: &arr }; + let arr_unaligned: UnalignedPtr<[i32]> = arr_unaligned; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45157.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45157.rs new file mode 100644 index 000000000000..e6b1ebd0029d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45157.rs @@ -0,0 +1,33 @@ +#![allow(unused)] + +// ignore-tidy-linelength + +#[derive(Clone, Copy, Default)] +struct S { + a: u8, + b: u8, +} +#[derive(Clone, Copy, Default)] +struct Z { + c: u8, + d: u8, +} + +union U { + s: S, + z: Z, +} + +fn main() { + unsafe { + let mut u = U { s: Default::default() }; + + let mref = &mut u.s.a; + *mref = 22; + + let nref = &u.z.c; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + println!("{} {}", mref, nref) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4517.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4517.rs new file mode 100644 index 000000000000..b74c0163f242 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4517.rs @@ -0,0 +1,9 @@ +fn bar(int_param: usize) {} + +fn main() { + let foo: [u8; 4] = [1; 4]; + bar(foo); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45199.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45199.rs new file mode 100644 index 000000000000..75747b4fc1fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45199.rs @@ -0,0 +1,25 @@ +fn test_drop_replace() { + let b: Box; +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + b = Box::new(1); // { dg-note "" "" { target *-*-* } } + b = Box::new(2); // { dg-error ".E0384." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } +} + +fn test_call() { + let b = Box::new(1); // { dg-note "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + b = Box::new(2); // { dg-error ".E0384." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } +} + +fn test_args(b: Box) { // { help "" "" { target *-*-* } } +// { suggestion "" "" { target *-*-* } .-2 } + b = Box::new(2); // { dg-error ".E0384." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45296.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45296.rs new file mode 100644 index 000000000000..953b8e7a33c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45296.rs @@ -0,0 +1,6 @@ +fn main() { + let unused = (); + + #![allow(unused_variables)] // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4541.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4541.rs new file mode 100644 index 000000000000..d28e8c57cbce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4541.rs @@ -0,0 +1,24 @@ +// run-pass +// ignore-cloudabi no std::env + +fn parse_args() -> String { + let args: Vec<_> = ::std::env::args().collect(); + let mut n = 0; + + while n < args.len() { + match &*args[n] { + "-v" => (), + s => { + return s.to_string(); + } + } + n += 1; + } + + return "".to_string() +} + +pub fn main() { + println!("{}", parse_args()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4542.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4542.rs new file mode 100644 index 000000000000..619ca30d0ac1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4542.rs @@ -0,0 +1,14 @@ +// run-pass +// pretty-expanded FIXME #23616 +// ignore-cloudabi no std::env + +use std::env; + +pub fn main() { + for arg in env::args() { + match arg.clone() { + _s => { } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45425.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45425.rs new file mode 100644 index 000000000000..cf250fa1b7ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45425.rs @@ -0,0 +1,13 @@ +// check-pass +#![allow(dead_code)] +use std::ops::Add; + +fn ref_add(a: &T, b: &T) -> T +where + for<'x> &'x T: Add<&'x T, Output = T>, +{ + a + b +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4545.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4545.rs new file mode 100644 index 000000000000..ccc2472a68b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4545.rs @@ -0,0 +1,8 @@ +// run-pass +// aux-build:issue-4545.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_4545 as somelib; +pub fn main() { somelib::mk::(); } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45510.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45510.rs new file mode 100644 index 000000000000..e615b6476bf8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45510.rs @@ -0,0 +1,33 @@ +// Test overloaded resolution of fn_traits. +// run-pass + +#![feature(fn_traits)] +#![feature(unboxed_closures)] + +#[derive(Debug, PartialEq, Eq)] +struct Ishmael; +#[derive(Debug, PartialEq, Eq)] +struct Maybe; +struct CallMe; + +impl FnOnce<(Ishmael,)> for CallMe { + type Output = Ishmael; + extern "rust-call" fn call_once(self, _args: (Ishmael,)) -> Ishmael { + println!("Split your lungs with blood and thunder!"); + Ishmael + } +} + +impl FnOnce<(Maybe,)> for CallMe { + type Output = Maybe; + extern "rust-call" fn call_once(self, _args: (Maybe,)) -> Maybe { + println!("So we just met, and this is crazy"); + Maybe + } +} + +fn main() { + assert_eq!(CallMe(Ishmael), Ishmael); + assert_eq!(CallMe(Maybe), Maybe); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45562.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45562.rs new file mode 100644 index 000000000000..36df47fd7d61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45562.rs @@ -0,0 +1,7 @@ +// run-rustfix + +#[no_mangle] pub const RAH: usize = 5; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45696-long-live-borrows-in-boxes.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45696-long-live-borrows-in-boxes.rs new file mode 100644 index 000000000000..88f5bfd00d03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45696-long-live-borrows-in-boxes.rs @@ -0,0 +1,115 @@ +// rust-lang/rust#45696: This test is checking that we can return +// mutable borrows owned by boxes even when the boxes are dropped. + +// run-pass + +// This function shows quite directly what is going on: We have a +// reborrow of contents within the box. +fn return_borrow_from_dropped_box_1(x: Box<&mut u32>) -> &mut u32 { &mut **x } + +// This function is the way you'll probably see this in practice (the +// reborrow is now implicit). +fn return_borrow_from_dropped_box_2(x: Box<&mut u32>) -> &mut u32 { *x } + +// For the remaining tests we just add some fields or other +// indirection to ensure that the compiler isn't just special-casing +// the above `Box<&mut T>` as the only type that would work. + +// Here we add a tuple of indirection between the box and the +// reference. +type BoxedTup<'a, 'b> = Box<(&'a mut u32, &'b mut u32)>; + +fn return_borrow_of_field_from_dropped_box_1<'a>(x: BoxedTup<'a, '_>) -> &'a mut u32 { + &mut *x.0 +} + +fn return_borrow_of_field_from_dropped_box_2<'a>(x: BoxedTup<'a, '_>) -> &'a mut u32 { + x.0 +} + +fn return_borrow_from_dropped_tupled_box_1<'a>(x: (BoxedTup<'a, '_>, &mut u32)) -> &'a mut u32 { + &mut *(x.0).0 +} + +fn return_borrow_from_dropped_tupled_box_2<'a>(x: (BoxedTup<'a, '_>, &mut u32)) -> &'a mut u32 { + (x.0).0 +} + +fn basic_tests() { + let mut x = 2; + let mut y = 3; + let mut z = 4; + *return_borrow_from_dropped_box_1(Box::new(&mut x)) += 10; + assert_eq!((x, y, z), (12, 3, 4)); + *return_borrow_from_dropped_box_2(Box::new(&mut x)) += 10; + assert_eq!((x, y, z), (22, 3, 4)); + *return_borrow_of_field_from_dropped_box_1(Box::new((&mut x, &mut y))) += 10; + assert_eq!((x, y, z), (32, 3, 4)); + *return_borrow_of_field_from_dropped_box_2(Box::new((&mut x, &mut y))) += 10; + assert_eq!((x, y, z), (42, 3, 4)); + *return_borrow_from_dropped_tupled_box_1((Box::new((&mut x, &mut y)), &mut z)) += 10; + assert_eq!((x, y, z), (52, 3, 4)); + *return_borrow_from_dropped_tupled_box_2((Box::new((&mut x, &mut y)), &mut z)) += 10; + assert_eq!((x, y, z), (62, 3, 4)); +} + +// These scribbling tests have been transcribed from +// issue-45696-scribble-on-boxed-borrow.rs +// +// In the context of that file, these tests are meant to show cases +// that should be *accepted* by the compiler, so here we are actually +// checking that the code we get when they are compiled matches our +// expectations. + +struct Scribble<'a>(&'a mut u32); + +impl<'a> Drop for Scribble<'a> { fn drop(&mut self) { *self.0 = 42; } } + +// this is okay, in both AST-borrowck and NLL: The `Scribble` here *has* +// to strictly outlive `'a` +fn borrowed_scribble<'a>(s: &'a mut Scribble) -> &'a mut u32 { + &mut *s.0 +} + +// this, by analogy to previous case, is also okay. +fn boxed_borrowed_scribble<'a>(s: Box<&'a mut Scribble>) -> &'a mut u32 { + &mut *(*s).0 +} + +// this, by analogy to previous case, is also okay. +fn boxed_boxed_borrowed_scribble<'a>(s: Box>) -> &'a mut u32 { + &mut *(**s).0 +} + +fn scribbling_tests() { + let mut x = 1; + { + let mut long_lived = Scribble(&mut x); + *borrowed_scribble(&mut long_lived) += 10; + assert_eq!(*long_lived.0, 11); + // (Scribble dtor runs here, after `&mut`-borrow above ends) + } + assert_eq!(x, 42); + x = 1; + { + let mut long_lived = Scribble(&mut x); + *boxed_borrowed_scribble(Box::new(&mut long_lived)) += 10; + assert_eq!(*long_lived.0, 11); + // (Scribble dtor runs here, after `&mut`-borrow above ends) + } + assert_eq!(x, 42); + x = 1; + { + let mut long_lived = Scribble(&mut x); + *boxed_boxed_borrowed_scribble(Box::new(Box::new(&mut long_lived))) += 10; + assert_eq!(*long_lived.0, 11); + // (Scribble dtor runs here, after `&mut`-borrow above ends) + } + assert_eq!(x, 42); +} + +fn main() { + basic_tests(); + scribbling_tests(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45696-no-variant-box-recur.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45696-no-variant-box-recur.rs new file mode 100644 index 000000000000..245156497954 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45696-no-variant-box-recur.rs @@ -0,0 +1,51 @@ +// rust-lang/rust#45696: This test checks the compiler won't infinite loop when +// you declare a variable of type `struct A(Box, ...);` (which is impossible +// to construct but *is* possible to declare; see also issues #4287, #44933, +// and #52852). +// +// We will explicitly test NLL, and migration modes; thus we will also skip the +// automated compare-mode=nll. + +// run-pass + +// This test has structs and functions that are by definition unusable +// all over the place, so just go ahead and allow dead_code +#![allow(dead_code)] + +// direct regular recursion with indirect ownership via box +struct C { field: Box } + +// direct non-regular recursion with indirect ownership via box +struct D { field: Box<(D, D)> } + +// indirect regular recursion with indirect ownership via box. +struct E { field: F } +struct F { field: Box } + +// indirect non-regular recursion with indirect ownership via box. +struct G { field: (H, H) } +struct H { field: Box } + +// These enums are cases that are not currently hit by the +// `visit_terminator_drop` recursion down a type's structural +// definition. +// +// But it seems prudent to include them in this test as variants on +// the above, in that they are similarly non-constructable data types +// with destructors that would diverge. +enum I { One(Box) } +enum J { One(Box), Two(Box) } + +fn impossible_to_call_c(_c: C) { } +fn impossible_to_call_d(_d: D) { } +fn impossible_to_call_e(_e: E) { } +fn impossible_to_call_f(_f: F) { } +fn impossible_to_call_g(_g: G) { } +fn impossible_to_call_h(_h: H) { } +fn impossible_to_call_i(_i: I) { } +fn impossible_to_call_j(_j: J) { } + +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45696-scribble-on-boxed-borrow.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45696-scribble-on-boxed-borrow.rs new file mode 100644 index 000000000000..751942bdad11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45696-scribble-on-boxed-borrow.rs @@ -0,0 +1,68 @@ +// rust-lang/rust#45696: This test is checking that we *cannot* return +// mutable borrows that would be scribbled over by destructors before +// the return occurs. + +// ignore-compare-mode-polonius + +struct Scribble<'a>(&'a mut u32); + +impl<'a> Drop for Scribble<'a> { fn drop(&mut self) { *self.0 = 42; } } + +// this is okay: The `Scribble` here *has* to strictly outlive `'a` +fn borrowed_scribble<'a>(s: &'a mut Scribble) -> &'a mut u32 { + &mut *s.0 +} + +// this, by analogy to previous case, is also okay. +fn boxed_borrowed_scribble<'a>(s: Box<&'a mut Scribble>) -> &'a mut u32 { + &mut *(*s).0 +} + +// this, by analogy to previous case, is also okay. +fn boxed_boxed_borrowed_scribble<'a>(s: Box>) -> &'a mut u32 { + &mut *(**s).0 +} + +// this is not okay: in between the time that we take the mutable +// borrow and the caller receives it as a return value, the drop of +// `s` will scribble on it, violating our aliasing guarantees. +// +// * (Maybe in the future the two-phase borrows system will be +// extended to support this case. But for now, it is an error in +// NLL, even with two-phase borrows.) +fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 { + &mut *s.0 // { dg-error ".E0713." "" { target *-*-* } } +} + +// This, by analogy to previous case, is *also* not okay. +fn boxed_scribbled<'a>(s: Box>) -> &'a mut u32 { + &mut *(*s).0 // { dg-error ".E0713." "" { target *-*-* } } +} + +// This, by analogy to previous case, is *also* not okay. +fn boxed_boxed_scribbled<'a>(s: Box>>) -> &'a mut u32 { + &mut *(**s).0 // { dg-error ".E0713." "" { target *-*-* } } +} + +fn main() { + let mut x = 1; + { + let mut long_lived = Scribble(&mut x); + *borrowed_scribble(&mut long_lived) += 10; + // (Scribble dtor runs here, after `&mut`-borrow above ends) + } + { + let mut long_lived = Scribble(&mut x); + *boxed_borrowed_scribble(Box::new(&mut long_lived)) += 10; + // (Scribble dtor runs here, after `&mut`-borrow above ends) + } + { + let mut long_lived = Scribble(&mut x); + *boxed_boxed_borrowed_scribble(Box::new(Box::new(&mut long_lived))) += 10; + // (Scribble dtor runs here, after `&mut`-borrow above ends) + } + *scribbled(Scribble(&mut x)) += 10; + *boxed_scribbled(Box::new(Scribble(&mut x))) += 10; + *boxed_boxed_scribbled(Box::new(Box::new(Scribble(&mut x)))) += 10; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45697-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45697-1.rs new file mode 100644 index 000000000000..03e095dd12cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45697-1.rs @@ -0,0 +1,26 @@ +// Test that assignments to an `&mut` pointer which is found in a +// borrowed (but otherwise non-aliasable) location is illegal. + +// compile-flags: -C overflow-checks=on + +struct S<'a> { + pointer: &'a mut isize +} + +fn copy_borrowed_ptr<'a>(p: &'a mut S<'a>) -> S<'a> { + S { pointer: &mut *p.pointer } +} + +fn main() { + let mut x = 1; + + { + let mut y = S { pointer: &mut x }; + let z = copy_borrowed_ptr(&mut y); + *y.pointer += 1; +// { dg-error ".E0506." "" { target *-*-* } .-1 } +// { dg-error ".E0506." "" { target *-*-* } .-2 } + *z.pointer += 1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45697.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45697.rs new file mode 100644 index 000000000000..98dbfc76e3a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45697.rs @@ -0,0 +1,26 @@ +// Test that assignments to an `&mut` pointer which is found in a +// borrowed (but otherwise non-aliasable) location is illegal. + +// compile-flags: -C overflow-checks=off + +struct S<'a> { + pointer: &'a mut isize +} + +fn copy_borrowed_ptr<'a>(p: &'a mut S<'a>) -> S<'a> { + S { pointer: &mut *p.pointer } +} + +fn main() { + let mut x = 1; + + { + let mut y = S { pointer: &mut x }; + let z = copy_borrowed_ptr(&mut y); + *y.pointer += 1; +// { dg-error ".E0506." "" { target *-*-* } .-1 } +// { dg-error ".E0506." "" { target *-*-* } .-2 } + *z.pointer += 1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45729-unsafe-in-generator.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45729-unsafe-in-generator.rs new file mode 100644 index 000000000000..bfd789f40cc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45729-unsafe-in-generator.rs @@ -0,0 +1,10 @@ +#![feature(generators)] + +fn main() { + let _ = || { + *(1 as *mut u32) = 42; +// { dg-error ".E0133." "" { target *-*-* } .-1 } + yield; + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45730.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45730.rs new file mode 100644 index 000000000000..f8b35fb10c31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45730.rs @@ -0,0 +1,10 @@ +use std::fmt; +fn main() { + let x: *const _ = 0 as _; // { dg-error ".E0641." "" { target *-*-* } } + + let x: *const _ = 0 as *const _; // { dg-error ".E0641." "" { target *-*-* } } + let y: Option<*const dyn fmt::Debug> = Some(x) as _; + + let x = 0 as *const i32 as *const _ as *mut _; // { dg-error ".E0641." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45731.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45731.rs new file mode 100644 index 000000000000..757f05cc9ea3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45731.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(unused_variables)] +// compile-flags:--test -g +// ignore-asmjs wasm2js does not support source maps yet + +#[cfg(target_os = "macos")] +#[test] +fn simple_test() { + use std::{env, panic, fs}; + + // Find our dSYM and replace the DWARF binary with an empty file + let mut dsym_path = env::current_exe().unwrap(); + let executable_name = dsym_path.file_name().unwrap().to_str().unwrap().to_string(); + assert!(dsym_path.pop()); // Pop executable + dsym_path.push(format!("{}.dSYM/Contents/Resources/DWARF/{0}", executable_name)); + { + let file = fs::OpenOptions::new().read(false).write(true).truncate(true).create(false) + .open(&dsym_path).unwrap(); + } + + env::set_var("RUST_BACKTRACE", "1"); + + // We don't need to die of panic, just trigger a backtrace + let _ = panic::catch_unwind(|| { + assert!(false); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs new file mode 100644 index 000000000000..0c001558a269 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45799-bad-extern-crate-rename-suggestion-formatting.rs @@ -0,0 +1,6 @@ +// run-rustfix + +extern crate std; +fn main() {} +// { dg-error ".E0259." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45801.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45801.rs new file mode 100644 index 000000000000..68bc58c5e6b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45801.rs @@ -0,0 +1,26 @@ +struct Params; + +pub trait Plugin { + type Error; +} + +pub trait Pluggable { + fn get_ref>(&mut self) -> Option { + None + } +} + +struct Foo; +impl Plugin for Params { + type Error = (); +} + +impl Pluggable for T {} + +fn handle(req: &mut i32) { + req.get_ref::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45829/auxiliary/issue-45829-a.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/auxiliary/issue-45829-a.rs new file mode 100644 index 000000000000..3f6f801a5c90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/auxiliary/issue-45829-a.rs @@ -0,0 +1,2 @@ +pub const FOO: usize = *&0; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45829/auxiliary/issue-45829-b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/auxiliary/issue-45829-b.rs new file mode 100644 index 000000000000..3f6f801a5c90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/auxiliary/issue-45829-b.rs @@ -0,0 +1,2 @@ +pub const FOO: usize = *&0; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45829/import-self.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/import-self.rs new file mode 100644 index 000000000000..6549d17b67e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/import-self.rs @@ -0,0 +1,20 @@ +mod foo { + pub struct A; + pub struct B; +} + +use foo::{self}; +// { dg-error ".E0255." "" { target *-*-* } .-1 } + +use foo as self; +// { dg-error "" "" { target *-*-* } .-1 } + +use foo::self; // { dg-error ".E0255." "" { target *-*-* } } +// { dg-error ".E0255." "" { target *-*-* } .-1 } + +use foo::A; +use foo::{self as A}; +// { dg-error ".E0252." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45829/import-twice.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/import-twice.rs new file mode 100644 index 000000000000..fb3fecc252de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/import-twice.rs @@ -0,0 +1,10 @@ +mod foo { + pub struct A; + pub struct B; +} + +use foo::{A, A}; +// { dg-error ".E0252." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45829/issue-45829.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/issue-45829.rs new file mode 100644 index 000000000000..923e75f26715 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/issue-45829.rs @@ -0,0 +1,10 @@ +mod foo { + pub struct A; + pub struct B; +} + +use foo::{A, B as A}; +// { dg-error ".E0252." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-extern-vs-use.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-extern-vs-use.rs new file mode 100644 index 000000000000..70ea512d9e06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-extern-vs-use.rs @@ -0,0 +1,12 @@ +// aux-build:issue-45829-b.rs + +mod foo { + pub mod bar {} +} + +use foo::bar; +extern crate issue_45829_b as bar; +// { dg-error ".E0254." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-extern-with-tab.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-extern-with-tab.rs new file mode 100644 index 000000000000..6efdcfa54d7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-extern-with-tab.rs @@ -0,0 +1,9 @@ +// aux-build:issue-45829-a.rs +// aux-build:issue-45829-b.rs + +extern crate issue_45829_a; +extern crate issue_45829_b as issue_45829_a; +// { dg-error ".E0259." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-extern.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-extern.rs new file mode 100644 index 000000000000..8b96591dd273 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-extern.rs @@ -0,0 +1,9 @@ +// aux-build:issue-45829-a.rs +// aux-build:issue-45829-b.rs + +extern crate issue_45829_a; +extern crate issue_45829_b as issue_45829_a; +// { dg-error ".E0259." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-use-vs-extern.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-use-vs-extern.rs new file mode 100644 index 000000000000..3d44d698e13f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-use-vs-extern.rs @@ -0,0 +1,8 @@ +// aux-build:issue-45829-b.rs + +extern crate issue_45829_b; +use std as issue_45829_b; +// { dg-error ".E0254." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-use-with-tabs.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-use-with-tabs.rs new file mode 100644 index 000000000000..4aa672a3e028 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-use-with-tabs.rs @@ -0,0 +1,13 @@ +mod foo { + pub struct A; + + pub mod bar { + pub struct B; + } +} + +use foo::{A, bar::B as A}; +// { dg-error ".E0252." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-with-path.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-with-path.rs new file mode 100644 index 000000000000..da17ed5d341f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename-with-path.rs @@ -0,0 +1,5 @@ +use std::{collections::HashMap as A, sync::Arc as A}; +// { dg-error ".E0252." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename.rs new file mode 100644 index 000000000000..ca515101ae08 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45829/rename.rs @@ -0,0 +1,8 @@ +use core; +use std as core; +// { dg-error ".E0252." "" { target *-*-* } .-1 } + +fn main() { + 1 + 1; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-45965.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-45965.rs new file mode 100644 index 000000000000..4e811528a76e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-45965.rs @@ -0,0 +1,5 @@ +fn main() { + let a = |r: f64| if r != 0.0(r != 0.0) { 1.0 } else { 0.0 }; +// { dg-error ".E0618." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46023.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46023.rs new file mode 100644 index 000000000000..cc16f4a00f84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46023.rs @@ -0,0 +1,9 @@ +fn main() { + let x = 0; + + (move || { + x = 1; +// { dg-error ".E0594." "" { target *-*-* } .-1 } + })() +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46036.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46036.rs new file mode 100644 index 000000000000..53ef54c8ca3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46036.rs @@ -0,0 +1,13 @@ +// Issue 46036: [NLL] false edges on infinite loops +// Infinite loops should create false edges to the cleanup block. + +struct Foo { x: &'static u32 } + +fn foo() { + let a = 3; + let foo = Foo { x: &a }; // { dg-error ".E0597." "" { target *-*-* } } + loop { } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46069.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46069.rs new file mode 100644 index 000000000000..79dbbd7707ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46069.rs @@ -0,0 +1,24 @@ +// run-pass +use std::iter::{Fuse, Cloned}; +use std::slice::Iter; + +struct Foo<'a, T: 'a>(&'a T); +impl<'a, T: 'a> Copy for Foo<'a, T> {} +impl<'a, T: 'a> Clone for Foo<'a, T> { + fn clone(&self) -> Self { *self } +} + +fn copy_ex() { + let s = 2; + let k1 = || s; + let upvar = Foo(&k1); + let k = || upvar; + k(); +} + +fn main() { + let _f: *mut >> as Iterator>::Item = std::ptr::null_mut(); + + copy_ex(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46095.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46095.rs new file mode 100644 index 000000000000..a08e1dacaec4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46095.rs @@ -0,0 +1,31 @@ +// run-pass +struct A; + +impl A { + fn take_mutably(&mut self) {} +} + +fn identity(t: T) -> T { + t +} + +// Issue 46095 +// Built-in indexing should be used even when the index is not +// trivially an integer +// Overloaded indexing would cause wrapped to be borrowed mutably + +fn main() { + let mut a1 = A; + let mut a2 = A; + + let wrapped = [&mut a1, &mut a2]; + + { + wrapped[0 + 1 - 1].take_mutably(); + } + + { + wrapped[identity(0)].take_mutably(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46101.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46101.rs new file mode 100644 index 000000000000..6b04c06b5916 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46101.rs @@ -0,0 +1,8 @@ +#![feature(use_extern_macros)] +trait Foo {} +#[derive(Foo::Anything)] // { dg-error ".E0433." "" { target *-*-* } } +// { dg-error ".E0433." "" { target *-*-* } .-2 } +struct S; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46112.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46112.rs new file mode 100644 index 000000000000..523e51d1030b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46112.rs @@ -0,0 +1,11 @@ +// Issue 46112: An extern crate pub re-exporting libcore was causing +// paths rooted from `std` to be misrendered in the diagnostic output. + +// ignore-windows +// aux-build:xcrate-issue-46112-rexport-core.rs + +extern crate xcrate_issue_46112_rexport_core; +fn test(r: Result, &'static str>) { } +fn main() { test(Ok(())); } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46186.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46186.rs new file mode 100644 index 000000000000..667f557310d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46186.rs @@ -0,0 +1,9 @@ +// run-rustfix + +pub struct Struct { + pub a: usize, +}; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46302.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46302.rs new file mode 100644 index 000000000000..db521545a2df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46302.rs @@ -0,0 +1,10 @@ +fn foo() { + let s = "abc"; + let u: &str = if true { s[..2] } else { s }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46311.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46311.rs new file mode 100644 index 000000000000..3bbdbd0cea77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46311.rs @@ -0,0 +1,5 @@ +fn main() { + 'break: loop { // { dg-error "" "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46332.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46332.rs new file mode 100644 index 000000000000..ac6018c27145 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46332.rs @@ -0,0 +1,12 @@ +// Original Levenshtein distance for both of this is 1. We improved accuracy with +// additional case insensitive comparison. + +struct TyUint {} + +struct TyInt {} + +fn main() { + TyUInt {}; +// { dg-error ".E0422." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46438.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46438.rs new file mode 100644 index 000000000000..dfeacf1583c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46438.rs @@ -0,0 +1,14 @@ +macro_rules! m { + ($my_type: ty) => { + impl $my_type for u8 {} + } +} + +trait Tr {} + +m!(Tr); + +m!(&'static u8); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46471-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46471-1.rs new file mode 100644 index 000000000000..0498e97d0275 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46471-1.rs @@ -0,0 +1,9 @@ +fn main() { + let y = { + let mut z = 0; + &mut z + }; +// { dg-error ".E0597." "" { target *-*-* } .-2 } + println!("{}", y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46471.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46471.rs new file mode 100644 index 000000000000..ba9c218f906c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46471.rs @@ -0,0 +1,8 @@ +fn foo() -> &'static u32 { + let x = 0; + &x +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46472.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46472.rs new file mode 100644 index 000000000000..1dcbde09c994 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46472.rs @@ -0,0 +1,7 @@ +fn bar<'a>() -> &'a mut u32 { + &mut 4 +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46519.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46519.rs new file mode 100644 index 000000000000..93d9d8357894 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46519.rs @@ -0,0 +1,31 @@ +// run-pass +// compile-flags:--test -O + +// ignore-wasm32-bare compiled with panic=abort by default + +#[test] +#[should_panic(expected = "creating inhabited type")] +fn test() { + FontLanguageOverride::system_font(SystemFont::new()); +} + +pub enum FontLanguageOverride { + Normal, + Override(&'static str), + System(SystemFont) +} + +pub enum SystemFont {} + +impl FontLanguageOverride { + fn system_font(f: SystemFont) -> Self { + FontLanguageOverride::System(f) + } +} + +impl SystemFont { + fn new() -> Self { + panic!("creating inhabited type") + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46553.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46553.rs new file mode 100644 index 000000000000..1a6d8bc5b69d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46553.rs @@ -0,0 +1,24 @@ +// run-pass +#![feature(const_fn_fn_ptr_basics)] +#![deny(const_err)] + +pub struct Data { + function: fn() -> T, +} + +impl Data { + pub const fn new(function: fn() -> T) -> Data { + Data { + function: function, + } + } +} + +pub static DATA: Data = Data::new(|| { + 413i32 +}); + +fn main() { + print!("{:?}", (DATA.function)()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46576.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46576.rs new file mode 100644 index 000000000000..6a123b31c5dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46576.rs @@ -0,0 +1,24 @@ +// ignore-cloudabi no std::fs support + +#![allow(dead_code)] +#![deny(unused_imports)] + +use std::fs::File; +use std::io::{BufRead, BufReader, Read}; +// { dg-error "" "" { target *-*-* } .-1 } + +pub fn read_from_file(path: &str) { + let file = File::open(&path).unwrap(); + let mut reader = BufReader::new(file); + let mut s = String::new(); + reader.read_to_string(&mut s).unwrap(); +} + +pub fn read_lines(s: &str) { + for _line in s.lines() { + + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46604.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46604.rs new file mode 100644 index 000000000000..d1622836cd6b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46604.rs @@ -0,0 +1,8 @@ +static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; // { dg-error ".E0764." "" { target *-*-* } } +fn write>(buffer: T) { } + +fn main() { + write(&buf); + buf[0]=2; // { dg-error ".E0594." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.rs new file mode 100644 index 000000000000..08f929f1f3e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.rs @@ -0,0 +1,17 @@ +// run-rustfix + +#![allow(unused)] + +fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize { + and_yet + 1 +} + +fn main() { + let behold: isize = 2; + let with_tears: usize = 3; + light_flows_our_war_of_mocking_words(behold as usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + light_flows_our_war_of_mocking_words(with_tears + 4); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46771.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46771.rs new file mode 100644 index 000000000000..2c726e103e9a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46771.rs @@ -0,0 +1,5 @@ +fn main() { + struct Foo; + (1 .. 2).find(|_| Foo(0) == 0); // { dg-error ".E0618." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46845.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46845.rs new file mode 100644 index 000000000000..ed8c6829f0c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46845.rs @@ -0,0 +1,33 @@ +// run-pass +// To work around #46855 +// compile-flags: -Z mir-opt-level=0 +// Regression test for the inhabitedness of unions with uninhabited variants, issue #46845 + +use std::mem; + +#[derive(Copy, Clone)] +enum Never { } + +// A single uninhabited variant shouldn't make the whole union uninhabited. +union Foo { + a: u64, + _b: Never +} + +// If all the variants are uninhabited, however, the union should be uninhabited. +// NOTE(#49298) the union being uninhabited shouldn't change its size. +union Bar { + _a: (Never, u64), + _b: (u64, Never) +} + +fn main() { + assert_eq!(mem::size_of::(), 8); + // See the note on `Bar`'s definition for why this isn't `0`. + assert_eq!(mem::size_of::(), 8); + + let f = [Foo { a: 42 }, Foo { a: 10 }]; + println!("{}", unsafe { f[0].a }); + assert_eq!(unsafe { f[1].a }, 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46855.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46855.rs new file mode 100644 index 000000000000..368d9818f4f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46855.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] +// compile-flags: -Zmir-opt-level=1 + +use std::mem; + +#[derive(Copy, Clone)] +enum Never {} + +union Foo { + a: u64, + b: Never +} + +fn foo(xs: [(Never, u32); 1]) -> u32 { xs[0].1 } + +fn bar([(_, x)]: [(Never, u32); 1]) -> u32 { x } + +fn main() { + println!("{}", mem::size_of::()); + + let f = [Foo { a: 42 }, Foo { a: 10 }]; + println!("{:?}", unsafe { f[0].a }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46920-byte-array-patterns.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46920-byte-array-patterns.rs new file mode 100644 index 000000000000..456fad5ac59a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46920-byte-array-patterns.rs @@ -0,0 +1,29 @@ +// run-pass +const CURSOR_PARTITION_LABEL: &'static [u8] = b"partition"; +const CURSOR_EVENT_TYPE_LABEL: &'static [u8] = b"event_type"; +const BYTE_PATTERN: &'static [u8; 5] = b"hello"; + +fn match_slice(x: &[u8]) -> u32 { + match x { + CURSOR_PARTITION_LABEL => 0, + CURSOR_EVENT_TYPE_LABEL => 1, + _ => 2, + } +} + +fn match_array(x: &[u8; 5]) -> bool { + match x { + BYTE_PATTERN => true, + _ => false + } +} + +fn main() { + assert_eq!(match_slice(b"abcde"), 2); + assert_eq!(match_slice(b"event_type"), 1); + assert_eq!(match_slice(b"partition"), 0); + + assert_eq!(match_array(b"hello"), true); + assert_eq!(match_array(b"hella"), false); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46959.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46959.rs new file mode 100644 index 000000000000..e3606e0dc75c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46959.rs @@ -0,0 +1,10 @@ +// check-pass +#![deny(non_camel_case_types)] + +#[allow(dead_code)] +fn qqq(lol: impl Iterator) -> impl Iterator { + lol.map(|x|x as u64) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46964.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46964.rs new file mode 100644 index 000000000000..7fa1b7ffd44b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46964.rs @@ -0,0 +1,20 @@ +// check-pass +mod my_mod { + #[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] + pub struct Name<'a> { + source: &'a str, + } + + pub const JSON: Name = Name { source: "JSON" }; +} + +pub fn crash() -> bool { + match (my_mod::JSON, None) { + (_, Some(my_mod::JSON)) => true, + (my_mod::JSON, None) => true, + _ => false, + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-46983.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-46983.rs new file mode 100644 index 000000000000..e55fb6bd904d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-46983.rs @@ -0,0 +1,7 @@ +fn foo(x: &u32) -> &'static u32 { + &*x +// { dg-error ".E0621." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47073-zero-padded-tuple-struct-indices.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47073-zero-padded-tuple-struct-indices.rs new file mode 100644 index 000000000000..c2359daeb6cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47073-zero-padded-tuple-struct-indices.rs @@ -0,0 +1,13 @@ +type Guilty = bool; +type FineDollars = u32; + +struct Verdict(Guilty, Option); + +fn main() { + let justice = Verdict(true, Some(2718)); + let _condemned = justice.00; +// { dg-error ".E0609." "" { target *-*-* } .-1 } + let _punishment = justice.001; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47094.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47094.rs new file mode 100644 index 000000000000..44e8eda704ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47094.rs @@ -0,0 +1,17 @@ +#[repr(C, u8)] // { dg-error ".E0566." "" { target *-*-* } } +// { dg-warning ".E0566." "" { target *-*-* } .-1 } +enum Foo { + A, + B, +} + +#[repr(C)] // { dg-error ".E0566." "" { target *-*-* } } +// { dg-warning ".E0566." "" { target *-*-* } .-1 } +#[repr(u8)] +enum Bar { + A, + B, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47139-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47139-1.rs new file mode 100644 index 000000000000..eaa6ee0e30dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47139-1.rs @@ -0,0 +1,79 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-47139-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47139-2.rs new file mode 100644 index 000000000000..23232f9f0202 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47139-2.rs @@ -0,0 +1,67 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-47184.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47184.rs new file mode 100644 index 000000000000..b1a61206cb03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47184.rs @@ -0,0 +1,5 @@ +fn main() { + let _vec: Vec<&'static String> = vec![&String::new()]; +// { dg-error ".E0716." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47309.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47309.rs new file mode 100644 index 000000000000..1ea1efa48be1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47309.rs @@ -0,0 +1,22 @@ +// Make sure that the mono-item collector does not crash when trying to +// instantiate a default impl of a method with lifetime parameters. +// See https://github.com/rust-lang/rust/issues/47309 + +// compile-flags:-Clink-dead-code +// build-pass + +#![crate_type="rlib"] + +pub trait EnvFuture { + type Item; + + fn boxed_result<'a>(self) where Self: Sized, Self::Item: 'a, { + } +} + +struct Foo; + +impl<'a> EnvFuture for &'a Foo { + type Item = (); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4734.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4734.rs new file mode 100644 index 000000000000..4eb5aeef6f5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4734.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(dead_code)] +// Ensures that destructors are run for expressions of the form "e;" where +// `e` is a type which requires a destructor. + + +#![allow(path_statements)] + +struct A { n: isize } +struct B; + +static mut NUM_DROPS: usize = 0; + +impl Drop for A { + fn drop(&mut self) { + unsafe { NUM_DROPS += 1; } + } +} + +impl Drop for B { + fn drop(&mut self) { + unsafe { NUM_DROPS += 1; } + } +} + +fn main() { + assert_eq!(unsafe { NUM_DROPS }, 0); + { let _a = A { n: 1 }; } + assert_eq!(unsafe { NUM_DROPS }, 1); + { A { n: 3 }; } + assert_eq!(unsafe { NUM_DROPS }, 2); + + { let _b = B; } + assert_eq!(unsafe { NUM_DROPS }, 3); + { B; } + assert_eq!(unsafe { NUM_DROPS }, 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4735.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4735.rs new file mode 100644 index 000000000000..bc9133c95977 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4735.rs @@ -0,0 +1,20 @@ +// run-pass +// pretty-expanded FIXME #23616 + +use std::mem::transmute; + +struct NonCopyable(*const u8); + +impl Drop for NonCopyable { + fn drop(&mut self) { + let NonCopyable(p) = *self; + let _v = unsafe { transmute::<*const u8, Box>(p) }; + } +} + +pub fn main() { + let t = Box::new(0); + let p = unsafe { transmute::, *const u8>(t) }; + let _z = NonCopyable(p); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4736.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4736.rs new file mode 100644 index 000000000000..ac8c0bed39fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4736.rs @@ -0,0 +1,6 @@ +struct NonCopyable(()); + +fn main() { + let z = NonCopyable{ p: () }; // { dg-error ".E0560." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47364.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47364.rs new file mode 100644 index 000000000000..6b495e5c57d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47364.rs @@ -0,0 +1,60 @@ +// run-pass +#![allow(unused_variables)] +// compile-flags: -C codegen-units=8 -O +#![allow(non_snake_case)] + +fn main() { + nom_sql::selection(b"x "); +} + +pub enum Err

{ + Position(P), + NodePosition(u32), +} + +pub enum IResult { + Done(I,O), + Error(Err), + Incomplete(u32, u64) +} + +pub fn multispace(input: T) -> ::IResult { + ::IResult::Done(0, 0) +} + +mod nom_sql { + fn where_clause(i: &[u8]) -> ::IResult<&[u8], Option> { + let X = match ::multispace(i) { + ::IResult::Done(..) => ::IResult::Done(i, None::), + _ => ::IResult::Error(::Err::NodePosition(0)), + }; + match X { + ::IResult::Done(_, _) => ::IResult::Done(i, None), + _ => X + } + } + + pub fn selection(i: &[u8]) { + let Y = match { + match { + where_clause(i) + } { + ::IResult::Done(_, o) => ::IResult::Done(i, Some(o)), + ::IResult::Error(_) => ::IResult::Done(i, None), + _ => ::IResult::Incomplete(0, 0), + } + } { + ::IResult::Done(z, _) => ::IResult::Done(z, None::), + _ => return () + }; + match Y { + ::IResult::Done(x, _) => { + let bytes = b"; "; + let len = x.len(); + bytes[len]; + } + _ => () + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47377.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47377.rs new file mode 100644 index 000000000000..84bc54a7809b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47377.rs @@ -0,0 +1,7 @@ +// ignore-tidy-tab +fn main() { + let b = "hello"; + let _a = b + ", World!"; +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47380.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47380.rs new file mode 100644 index 000000000000..62e5194e551b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47380.rs @@ -0,0 +1,6 @@ +fn main() { + let b = "hello"; + println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47412.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47412.rs new file mode 100644 index 000000000000..c3195d832dc6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47412.rs @@ -0,0 +1,22 @@ +#[derive(Copy, Clone)] +enum Void {} + +// Tests that we detect unsafe places (specifically, union fields and +// raw pointer dereferences), even when they're matched on while having +// an uninhabited type (equivalent to `std::intrinsics::unreachable()`). + +fn union_field() { + union Union { unit: (), void: Void } + let u = Union { unit: () }; + match u.void {} +// { dg-error ".E0133." "" { target *-*-* } .-1 } +} + +fn raw_ptr_deref() { + let ptr = std::ptr::null::(); + match *ptr {} +// { dg-error ".E0133." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47486.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47486.rs new file mode 100644 index 000000000000..07a3cdc6df9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47486.rs @@ -0,0 +1,5 @@ +fn main() { + () < std::mem::size_of::<_>(); // { dg-error ".E0308." "" { target *-*-* } } + [0u8; std::mem::size_of::<_>()]; // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47511.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47511.rs new file mode 100644 index 000000000000..e40c0e3b088e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47511.rs @@ -0,0 +1,26 @@ +// Regression test for #47511: anonymous lifetimes can appear +// unconstrained in a return type, but only if they appear just once +// in the input, as the input to a projection. + +fn f(_: X) -> X { +// { dg-error ".E0581." "" { target *-*-* } .-1 } + unimplemented!() +} + +fn g<'a>(_: X<'a>) -> X<'a> { +// { dg-error ".E0581." "" { target *-*-* } .-1 } + unimplemented!() +} + +type X<'a> = <&'a () as Trait>::Value; + +trait Trait { + type Value; +} + +impl<'a> Trait for &'a () { + type Value = (); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4759-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4759-1.rs new file mode 100644 index 000000000000..0119a26c015f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4759-1.rs @@ -0,0 +1,5 @@ +// run-pass +trait U { fn f(self); } +impl U for isize { fn f(self) {} } +pub fn main() { 4.f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4759.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4759.rs new file mode 100644 index 000000000000..bdba7a169d98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4759.rs @@ -0,0 +1,21 @@ +// run-pass +// pretty-expanded FIXME #23616 +#![allow(non_shorthand_field_patterns)] + +#![feature(box_syntax)] + +struct T { a: Box } + +trait U { + fn f(self); +} + +impl U for Box { + fn f(self) { } +} + +pub fn main() { + let T { a: a } = T { a: box 0 }; + a.f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47623.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47623.rs new file mode 100644 index 000000000000..7e8d1386083d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47623.rs @@ -0,0 +1,4 @@ +use self; // { dg-error ".E0429." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47638.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47638.rs new file mode 100644 index 000000000000..57e8712a41b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47638.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_variables)] +fn id<'c, 'b>(f: &'c &'b dyn Fn(&i32)) -> &'c &'b dyn Fn(&'static i32) { + f +} + +fn main() { + let f: &dyn Fn(&i32) = &|x| {}; + id(&f); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47646.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47646.rs new file mode 100644 index 000000000000..ef929d362a10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47646.rs @@ -0,0 +1,14 @@ +use std::collections::BinaryHeap; + +fn main() { + let mut heap: BinaryHeap = BinaryHeap::new(); + let borrow = heap.peek_mut(); + + match (borrow, ()) { + (Some(_), ()) => { + println!("{:?}", heap); // { dg-error ".E0502." "" { target *-*-* } } + } + _ => {} + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47673.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47673.rs new file mode 100644 index 000000000000..b60697a19bc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47673.rs @@ -0,0 +1,7 @@ +// check-pass +#![allow(unused_imports)] + +use {{}, {}}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47703-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47703-1.rs new file mode 100644 index 000000000000..99e58b332eed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47703-1.rs @@ -0,0 +1,24 @@ +// check-pass + +struct AtomicRefMut<'a> { + value: &'a mut i32, + borrow: AtomicBorrowRefMut, +} + +struct AtomicBorrowRefMut { +} + +impl Drop for AtomicBorrowRefMut { + fn drop(&mut self) { + } +} + +fn map(orig: AtomicRefMut) -> AtomicRefMut { + AtomicRefMut { + value: orig.value, + borrow: orig.borrow, + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47703-tuple.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47703-tuple.rs new file mode 100644 index 000000000000..61d008aa50d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47703-tuple.rs @@ -0,0 +1,12 @@ +// check-pass + +struct WithDrop; + +impl Drop for WithDrop { + fn drop(&mut self) {} +} + +fn consume(x: (&mut (), WithDrop)) -> &mut () { x.0 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47703.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47703.rs new file mode 100644 index 000000000000..76f2b32308bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47703.rs @@ -0,0 +1,19 @@ +// check-pass + +struct MyStruct<'a> { + field: &'a mut (), + field2: WithDrop +} + +struct WithDrop; + +impl Drop for WithDrop { + fn drop(&mut self) {} +} + +impl<'a> MyStruct<'a> { + fn consume(self) -> &'a mut () { self.field } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47706-trait.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47706-trait.rs new file mode 100644 index 000000000000..99b689599b8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47706-trait.rs @@ -0,0 +1,9 @@ +trait T { + fn f(&self, _: ()) { + None::<()>.map(Self::f); + } +// { dg-error ".E0593." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47706.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47706.rs new file mode 100644 index 000000000000..ad1a596ec993 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47706.rs @@ -0,0 +1,30 @@ +pub struct Foo { + foo: Option, +} + +impl Foo { + pub fn new(foo: Option, _: ()) -> Foo { + Foo { foo } + } + + pub fn map(self) -> Option { + self.foo.map(Foo::new) + } +// { dg-error ".E0593." "" { target *-*-* } .-2 } +} + +enum Qux { + Bar(i32), +} + +fn foo(f: F) +where + F: Fn(), +{ +} + +fn main() { + foo(Qux::Bar); +} +// { dg-error ".E0593." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47715.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47715.rs new file mode 100644 index 000000000000..60fc76a5d4d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47715.rs @@ -0,0 +1,29 @@ +trait Foo {} + +trait Bar {} + +trait Iterable { + type Item; +} + +struct Container> { +// { dg-error ".E0562." "" { target *-*-* } .-1 } + field: T +} + +enum Enum> { +// { dg-error ".E0562." "" { target *-*-* } .-1 } + A(T), +} + +union Union + Copy> { +// { dg-error ".E0562." "" { target *-*-* } .-1 } + x: T, +} + +type Type> = T; +// { dg-error ".E0562." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47722.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47722.rs new file mode 100644 index 000000000000..cd3d58fa3044 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47722.rs @@ -0,0 +1,18 @@ +// check-pass + +// Tests that automatic coercions from &mut T to *mut T +// allow borrows of T to expire immediately - essentially, that +// they work identically to 'foo as *mut T' + +struct SelfReference { + self_reference: *mut SelfReference, +} + +impl SelfReference { + fn set_self_ref(&mut self) { + self.self_reference = self; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47725.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47725.rs new file mode 100644 index 000000000000..9ef546eeea3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47725.rs @@ -0,0 +1,30 @@ +// ignore-tidy-linelength +#![warn(unused_attributes)] // { dg-note "" "" { target *-*-* } } + +#[link_name = "foo"] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +struct Foo; // { dg-note "" "" { target *-*-* } } + +#[link_name = "foobar"] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +extern "C" { + fn foo() -> u32; +} +// { dg-note "" "" { target *-*-* } .-3 } + +#[link_name] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +// { help "" "" { target *-*-* } .-5 } +extern "C" { + fn bar() -> u32; +} +// { dg-note "" "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-47789.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-47789.rs new file mode 100644 index 000000000000..03c0cfb844a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-47789.rs @@ -0,0 +1,11 @@ +// check-pass +#![allow(non_upper_case_globals)] + +static mut x: &'static u32 = &0; + +fn foo() { + unsafe { x = &1; } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48006.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48006.rs new file mode 100644 index 000000000000..081cf08b3184 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48006.rs @@ -0,0 +1,16 @@ +// run-pass + +#![feature(step_trait)] + +use std::iter::Step; + +#[cfg(target_pointer_width = "16")] +fn main() { + assert!(Step::steps_between(&0u32, &::std::u32::MAX).is_none()); +} + +#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] +fn main() { + assert!(Step::steps_between(&0u32, &::std::u32::MAX).is_some()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48131.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48131.rs new file mode 100644 index 000000000000..547036dd1d6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48131.rs @@ -0,0 +1,31 @@ +// This note is annotated because the purpose of the test +// is to ensure that certain other notes are not generated. +#![deny(unused_unsafe)] // { dg-note "" "" { target *-*-* } } + + +// (test that no note is generated on this unsafe fn) +pub unsafe fn a() { + fn inner() { + unsafe { /* unnecessary */ } // { dg-error "" "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-1 } + } + + inner() +} + +pub fn b() { + // (test that no note is generated on this unsafe block) + unsafe { + fn inner() { + unsafe { /* unnecessary */ } // { dg-error "" "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-1 } + } + // `()` is fine to zero-initialize as it is zero sized and inhabited. + let () = ::std::mem::zeroed(); + + inner() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48132.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48132.rs new file mode 100644 index 000000000000..f9e70371d635 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48132.rs @@ -0,0 +1,32 @@ +// Regression test for #48132. This was failing due to problems around +// the projection caching and dropck type enumeration. + +// run-pass + +#![allow(dead_code)] + +struct Inner { + iterator: I, + item: V, +} + +struct Outer { + inner: Inner, +} + +fn outer(iterator: I) -> Outer +where I: Iterator, + I::Item: Default, +{ + Outer { + inner: Inner { + iterator: iterator, + item: Default::default(), + } + } +} + +fn main() { + outer(std::iter::once(&1).cloned()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48159.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48159.rs new file mode 100644 index 000000000000..d9d591907620 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48159.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(non_camel_case_types)] + +use std::mem; + +pub enum c_void {} + +type uintptr_t = usize; +type int16_t = u16; +type uint16_t = int16_t; +type uint32_t = u32; +type intptr_t = uintptr_t; + +#[repr(C)] +#[repr(packed(4))] +pub struct kevent { + pub ident: uintptr_t, + pub filter: int16_t, + pub flags: uint16_t, + pub fflags: uint32_t, + pub data: intptr_t, + pub udata: *mut c_void, +} + +fn main() { + assert_eq!(mem::align_of::(), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48179.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48179.rs new file mode 100644 index 000000000000..25559d80a6fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48179.rs @@ -0,0 +1,39 @@ +// Regression test for #48132. This was failing due to problems around +// the projection caching and dropck type enumeration. + +// check-pass + +pub struct Container { + value: Option, +} + +impl Container { + pub fn new(iter: T) -> Self { + panic!() + } +} + +pub struct Wrapper<'a> { + content: &'a Content, +} + +impl<'a, 'de> Wrapper<'a> { + pub fn new(content: &'a Content) -> Self { + Wrapper { + content: content, + } + } +} + +pub struct Content; + +fn crash_it(content: Content) { + let items = vec![content]; + let map = items.iter().map(|ref o| Wrapper::new(o)); + + let mut map_visitor = Container::new(map); + +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48276.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48276.rs new file mode 100644 index 000000000000..8585e2bd6241 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48276.rs @@ -0,0 +1,34 @@ +// Regression test for issue #48276 - ICE when self type does not match what is +// required by a trait and regions are involved. + +trait MyFrom { + fn from(a: A) -> Self; +} + +struct A; + +impl<'a, 'b> MyFrom for &'a str { + fn from(self: &'a Self) -> &'b str { +// { dg-error ".E0185." "" { target *-*-* } .-1 } + "asdf" + } +} + +struct B; + +impl From for B { + fn from(&self) -> B { +// { dg-error ".E0185." "" { target *-*-* } .-1 } + B + } +} + +impl From for &'static str { + fn from(&self) -> &'static str { +// { dg-error ".E0185." "" { target *-*-* } .-1 } + "" + } +} + +fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4830.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4830.rs new file mode 100644 index 000000000000..90fedd99a216 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4830.rs @@ -0,0 +1,12 @@ +// check-pass +#![allow(dead_code)] + +// pretty-expanded FIXME #23616 + +pub struct Scheduler { + /// The event loop used to drive the scheduler and perform I/O + event_loop: Box +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48364.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48364.rs new file mode 100644 index 000000000000..f3dda6571ef3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48364.rs @@ -0,0 +1,7 @@ +fn foo() -> bool { + b"".starts_with(stringify!(foo)) +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48508-aux.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48508-aux.rs new file mode 100644 index 000000000000..ab036e886051 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48508-aux.rs @@ -0,0 +1,8 @@ +// run-pass +// ignore-test Not a test. Used by issue-48508.rs + +pub fn other() -> f64 { + let µ = 1.0; + µ +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48508.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48508.rs new file mode 100644 index 000000000000..6770b0bd488f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48508.rs @@ -0,0 +1,22 @@ +// run-pass +// Regression test for issue #48508: +// +// Confusion between global and local file offsets caused incorrect handling of multibyte character +// spans when compiling multiple files. One visible effect was an ICE generating debug information +// when a multibyte character is at the end of a scope. The problematic code is actually in +// issue-48508-aux.rs + +// compile-flags:-g +// ignore-pretty issue #37195 +// ignore-asmjs wasm2js does not support source maps yet + +#![feature(non_ascii_idents)] +#![allow(uncommon_codepoints)] + +#[path = "issue-48508-aux.rs"] +mod other_file; + +fn main() { + other_file::other(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48551.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48551.rs new file mode 100644 index 000000000000..0c533aa2ddaf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48551.rs @@ -0,0 +1,35 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-48636.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48636.rs new file mode 100644 index 000000000000..859c38fff36e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48636.rs @@ -0,0 +1,13 @@ +// run-rustfix + +#![allow(dead_code)] + +struct S { + x: u8 + /// The ID of the parent core + y: u8, +} +// { dg-error ".E0585." "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4865-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4865-1.rs new file mode 100644 index 000000000000..86ff74033d33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4865-1.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(unused_imports)] +// This should resolve fine. +// Prior to fix, the crossed imports between a and b +// would block on the glob import, itself never being resolved +// because these previous imports were not resolved. + +pub mod a { + use b::fn_b; + use c::*; + + pub fn fn_a(){ + } +} + +pub mod b { + use a::fn_a; + use c::*; + + pub fn fn_b(){ + } +} + +pub mod c{ + pub fn fn_c(){ + } +} + +use a::fn_a; +use b::fn_b; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4865-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4865-2.rs new file mode 100644 index 000000000000..7eb6ccd33dd7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4865-2.rs @@ -0,0 +1,25 @@ +// run-pass +// Previously, this would have failed to resolve due to the circular +// block between `use say` and `pub use hello::*`. +// +// Now, as `use say` is not `pub`, the glob import can resolve +// without any problem and this resolves fine. + +pub use hello::*; + +pub mod say { + pub fn hello() { println!("hello"); } +} + +pub mod hello { + use say; + + pub fn hello() { + say::hello(); + } +} + +fn main() { + hello(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4865-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4865-3.rs new file mode 100644 index 000000000000..7c7307db9a43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4865-3.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(unused_imports)] +// This should resolve fine even with the circular imports as +// they are not `pub`. + +pub mod a { + use b::*; +} + +pub mod b { + use a::*; +} + +use a::*; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48728.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48728.rs new file mode 100644 index 000000000000..a515f0383bb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48728.rs @@ -0,0 +1,14 @@ +// Regression test for #48728, an ICE that occurred computing +// coherence "help" information. + +#[derive(Clone)] // { dg-error ".E0119." "" { target *-*-* } } +struct Node(Box); + +impl Clone for Node<[T]> { + fn clone(&self) -> Self { + Node(Box::clone(&self.0)) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4875.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4875.rs new file mode 100644 index 000000000000..3e598017a5da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4875.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +// regression test for issue 4875 + +// pretty-expanded FIXME #23616 + +pub struct Foo { + data: T, +} + +fn foo(Foo{..}: Foo) { +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48803.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48803.rs new file mode 100644 index 000000000000..db900caedd3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48803.rs @@ -0,0 +1,14 @@ +fn flatten<'a, 'b, T>(x: &'a &'b T) -> &'a T { + x +} + +fn main() { + let mut x = "original"; + let y = &x; + let z = &y; + let w = flatten(z); + x = "modified"; +// { dg-error ".E0506." "" { target *-*-* } .-1 } + println!("{}", w); // prints "modified" +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48838.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48838.rs new file mode 100644 index 000000000000..d2d1245f795f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48838.rs @@ -0,0 +1,6 @@ +enum Functions { + Square = |x| x, // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48962.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48962.rs new file mode 100644 index 000000000000..0c43dd8bb53b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48962.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(unused_must_use)] +// Test that we are able to reinitialize box with moved referent +static mut ORDER: [usize; 3] = [0, 0, 0]; +static mut INDEX: usize = 0; + +struct Dropee (usize); + +impl Drop for Dropee { + fn drop(&mut self) { + unsafe { + ORDER[INDEX] = self.0; + INDEX = INDEX + 1; + } + } +} + +fn add_sentintel() { + unsafe { + ORDER[INDEX] = 2; + INDEX = INDEX + 1; + } +} + +fn main() { + let mut x = Box::new(Dropee(1)); + *x; // move out from `*x` + add_sentintel(); + *x = Dropee(3); // re-initialize `*x` + {x}; // drop value + unsafe { + assert_eq!(ORDER, [1, 2, 3]); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-48984.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-48984.rs new file mode 100644 index 000000000000..4fb021e804b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-48984.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(dead_code)] +// aux-build:issue-48984-aux.rs +extern crate issue48984aux; +use issue48984aux::Bar; + +fn do_thing() { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49040.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49040.rs new file mode 100644 index 000000000000..d0cdb7b266ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49040.rs @@ -0,0 +1,4 @@ +#![allow(unused_variables)]; // { dg-error ".E0601." "" { target *-*-* } } +// { dg-error ".E0601." "" { target *-*-* } .-1 } +fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49074.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49074.rs new file mode 100644 index 000000000000..60cda5e37840 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49074.rs @@ -0,0 +1,14 @@ +// Check that unknown attribute error is shown even if there are unresolved macros. + +#[marco_use] // typo +// { dg-error "" "" { target *-*-* } .-1 } +mod foo { + macro_rules! bar { + () => (); + } +} + +fn main() { + bar!(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49257.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49257.rs new file mode 100644 index 000000000000..6cb83d356ad4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49257.rs @@ -0,0 +1,15 @@ +// Test for #49257: +// emits good diagnostics for `..` pattern fragments not in the last position. + +#![allow(unused)] + +struct Point { x: u8, y: u8 } + +fn main() { + let p = Point { x: 0, y: 0 }; + let Point { .., y, } = p; // { dg-error "" "" { target *-*-* } } + let Point { .., y } = p; // { dg-error "" "" { target *-*-* } } + let Point { .., } = p; // { dg-error "" "" { target *-*-* } } + let Point { .. } = p; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49298.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49298.rs new file mode 100644 index 000000000000..f05c12444dab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49298.rs @@ -0,0 +1,43 @@ +// run-pass +#![feature(test)] +#![allow(unused_mut)] // under NLL we get warning about `x` below: rust-lang/rust#54499 + +// This test is bogus (i.e., should be compile-fail) during the period +// where #54986 is implemented and #54987 is *not* implemented. For +// now: just ignore it +// +// ignore-test + +// This test is checking that the space allocated for `x.1` does not +// overlap with `y`. (The reason why such a thing happened at one +// point was because `x.0: Void` and thus the whole type of `x` was +// uninhabited, and so the compiler thought it was safe to use the +// space of `x.1` to hold `y`.) +// +// That's a fine thing to test when this code is accepted by the +// compiler, and this code is being transcribed accordingly into +// the ui test issue-21232-partial-init-and-use.rs + +extern crate test; + +enum Void {} + +fn main() { + let mut x: (Void, usize); + let mut y = 42; + x.1 = 13; + + // Make sure `y` stays on the stack. + test::black_box(&mut y); + + // Check that the write to `x.1` did not overwrite `y`. + // Note that this doesn't fail with optimizations enabled, + // because we can't keep `x.1` on the stack, like we can `y`, + // as we can't borrow partially initialized variables. + assert_eq!(y.to_string(), "42"); + + // Check that `(Void, usize)` has space for the `usize` field. + assert_eq!(std::mem::size_of::<(Void, usize)>(), + std::mem::size_of::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4935.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4935.rs new file mode 100644 index 000000000000..ff5d3064219f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4935.rs @@ -0,0 +1,7 @@ +// Regression test for issue #4935 + +fn foo(a: usize) {} +// { dg-error "" "" { target *-*-* } .-1 } +fn main() { foo(5, 6) } +// { dg-error ".E0061." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49544.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49544.rs new file mode 100644 index 000000000000..bfd6736e8958 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49544.rs @@ -0,0 +1,10 @@ +// aux-build:issue-49544.rs +// check-pass + +extern crate issue_49544; +use issue_49544::foo; + +fn main() { + let _ = foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49556.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49556.rs new file mode 100644 index 000000000000..23d2f99d8060 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49556.rs @@ -0,0 +1,14 @@ +// check-pass +fn iter<'a>(data: &'a [usize]) -> impl Iterator + 'a { + data.iter() + .map( + |x| x // fn(&'a usize) -> &'a usize + ) + .map( + |x| *x // fn(&'a usize) -> usize + ) +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49579.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49579.rs new file mode 100644 index 000000000000..c7cf4754c5fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49579.rs @@ -0,0 +1,15 @@ +// check-pass + +fn fibs(n: u32) -> impl Iterator { + (0 .. n) + .scan((0, 1), |st, _| { + *st = (st.1, st.0 + st.1); + Some(*st) + }) + .map(&|(f, _)| f) +} + +fn main() { + println!("{:?}", fibs(10).collect::>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs new file mode 100644 index 000000000000..536483f4a652 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(unused_variables)] +#![deny(non_shorthand_field_patterns)] + +pub struct Value { pub value: A } + +#[macro_export] +macro_rules! pat { + ($a:pat) => { + Value { value: $a } + }; +} + +fn main() { + let pat!(value) = Value { value: () }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49632.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49632.rs new file mode 100644 index 000000000000..904a69d01b60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49632.rs @@ -0,0 +1,9 @@ +// run-pass +#![feature(stmt_expr_attributes)] + +pub fn main() { + let _x = #[inline(always)] || {}; + let _y = #[inline(never)] || {}; + let _z = #[inline] || {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4968.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4968.rs new file mode 100644 index 000000000000..cf1b09861512 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4968.rs @@ -0,0 +1,11 @@ +// Regression test for issue #4968 + +const A: (isize,isize) = (4,2); +fn main() { + match 42 { A => () } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49685.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49685.rs new file mode 100644 index 000000000000..8c21be4bd75f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49685.rs @@ -0,0 +1,14 @@ +// run-pass +// Regression test for #49685: drop elaboration was not revealing the +// value of `impl Trait` returns, leading to an ICE. + +fn main() { + let _ = Some(()) + .into_iter() + .flat_map(|_| Some(()).into_iter().flat_map(func)); +} + +fn func(_: ()) -> impl Iterator { + Some(()).into_iter().flat_map(|_| vec![]) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-4972.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-4972.rs new file mode 100644 index 000000000000..0323a5addc29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-4972.rs @@ -0,0 +1,19 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] + +trait MyTrait { + fn dummy(&self) {} +} + +pub enum TraitWrapper { + A(Box), +} + +fn get_tw_map(tw: &TraitWrapper) -> &dyn MyTrait { + match *tw { + TraitWrapper::A(box ref map) => map, // { dg-error ".E0033." "" { target *-*-* } } + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49824.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49824.rs new file mode 100644 index 000000000000..f52417469091 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49824.rs @@ -0,0 +1,10 @@ +fn main() { + let mut x = 0; + || { + || { +// { dg-error "" "" { target *-*-* } .-1 } + let _y = &mut x; + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49851/compiler-builtins-error.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49851/compiler-builtins-error.rs new file mode 100644 index 000000000000..216b1bb97bc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49851/compiler-builtins-error.rs @@ -0,0 +1,10 @@ +// { dg-error "" "" { target *-*-* } } + +// compile-flags: --target thumbv7em-none-eabihf +// needs-llvm-components: arm +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_std] + +extern crate cortex_m; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49854.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49854.rs new file mode 100644 index 000000000000..d13e453d5138 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49854.rs @@ -0,0 +1,10 @@ +// run-pass +use std::ffi::OsString; + +fn main() { + let os_str = OsString::from("Hello Rust!"); + + assert_eq!(os_str, "Hello Rust!"); + assert_eq!("Hello Rust!", os_str); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49919.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49919.rs new file mode 100644 index 000000000000..d83a1ab17873 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49919.rs @@ -0,0 +1,8 @@ +fn foo<'a, T: 'a>(t: T) -> Box &'a T + 'a> { + let foo: Box Fn() -> &'c T> = Box::new(move || &t); +// { dg-error ".E0582." "" { target *-*-* } .-1 } + unimplemented!() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49934-errors.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49934-errors.rs new file mode 100644 index 000000000000..87ce19ccde24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49934-errors.rs @@ -0,0 +1,14 @@ +fn foo<#[derive(Debug)] T>() { +// { dg-error ".E0774." "" { target *-*-* } .-1 } +// { dg-error ".E0774." "" { target *-*-* } .-2 } + match 0 { + #[derive(Debug)] +// { dg-error ".E0774." "" { target *-*-* } .-1 } +// { dg-error ".E0774." "" { target *-*-* } .-2 } + _ => (), + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49934.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49934.rs new file mode 100644 index 000000000000..7fe7b531b6ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49934.rs @@ -0,0 +1,36 @@ +// check-pass + +#![feature(stmt_expr_attributes)] +#![warn(unused_attributes)] // { dg-note "" "" { target *-*-* } } + +fn main() { + // fold_stmt (Item) + #[allow(dead_code)] + #[derive(Debug)] // should not warn + struct Foo; + + // fold_stmt (Mac) + #[derive(Debug)] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + println!("Hello, world!"); + + // fold_stmt (Semi) + #[derive(Debug)] // { dg-warning "" "" { target *-*-* } } + "Hello, world!"; + + // fold_stmt (Local) + #[derive(Debug)] // { dg-warning "" "" { target *-*-* } } + let _ = "Hello, world!"; + + // visit_expr + let _ = #[derive(Debug)] "Hello, world!"; +// { dg-warning "" "" { target *-*-* } .-1 } + + let _ = [ + // filter_map_expr + #[derive(Debug)] // { dg-warning "" "" { target *-*-* } } + "Hello, world!" + ]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49955-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49955-2.rs new file mode 100644 index 000000000000..af59934a681c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49955-2.rs @@ -0,0 +1,20 @@ +// run-pass +// compile-flags: -Z borrowck=mir + +use std::cell::Cell; + +const FIVE: Cell = Cell::new(5); + +#[inline(never)] +fn tuple_field() -> &'static u32 { + // This test is MIR-borrowck-only because the old borrowck + // doesn't agree that borrows of "frozen" (i.e., without any + // interior mutability) fields of non-frozen temporaries, + // should be promoted, while MIR promotion does promote them. + &(FIVE, 42).1 +} + +fn main() { + assert_eq!(tuple_field().to_string(), "42"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49955.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49955.rs new file mode 100644 index 000000000000..2213630a45b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49955.rs @@ -0,0 +1,21 @@ +// run-pass + +const ALL_THE_NUMS: [u32; 1] = [ + 1 +]; + +#[inline(never)] +fn array(i: usize) -> &'static u32 { + return &ALL_THE_NUMS[i]; +} + +#[inline(never)] +fn tuple_field() -> &'static u32 { + &(42,).0 +} + +fn main() { + assert_eq!(tuple_field().to_string(), "42"); + assert_eq!(array(0).to_string(), "1"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-49973.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-49973.rs new file mode 100644 index 000000000000..d2f21a4c333f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-49973.rs @@ -0,0 +1,12 @@ +// run-pass +#[derive(Debug)] +#[repr(i32)] +enum E { + Min = -2147483648i32, + _Max = 2147483647i32, +} + +fn main() { + assert_eq!(Some(E::Min).unwrap() as i32, -2147483648i32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5008-borrowed-traitobject-method-call.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5008-borrowed-traitobject-method-call.rs new file mode 100644 index 000000000000..29997e055f6a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5008-borrowed-traitobject-method-call.rs @@ -0,0 +1,35 @@ +// run-pass +/* + +#5008 cast to &Trait causes code to segfault on method call + +It fixes itself if the &Trait is changed to @Trait. +*/ + +trait Debuggable { + fn debug_name(&self) -> String; +} + +#[derive(Clone)] +struct Thing { + name: String, +} + +impl Thing { + fn new() -> Thing { Thing { name: "dummy".to_string() } } +} + +impl Debuggable for Thing { + fn debug_name(&self) -> String { self.name.clone() } +} + +fn print_name(x: &dyn Debuggable) +{ + println!("debug_name = {}", x.debug_name()); +} + +pub fn main() { + let thing = Thing::new(); + print_name(&thing as &dyn Debuggable); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50187.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50187.rs new file mode 100644 index 000000000000..2a6b09878c04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50187.rs @@ -0,0 +1,40 @@ +// check-pass + +#![feature(decl_macro)] + +mod type_ns { + pub type A = u8; +} +mod value_ns { + pub const A: u8 = 0; +} +mod macro_ns { + pub macro A() {} +} + +mod merge2 { + pub use type_ns::A; + pub use value_ns::A; +} +mod merge3 { + pub use type_ns::A; + pub use value_ns::A; + pub use macro_ns::A; +} + +mod use2 { + pub use merge2::A; +} +mod use3 { + pub use merge3::A; +} + +fn main() { + type B2 = use2::A; + let a2 = use2::A; + + type B3 = use3::A; + let a3 = use3::A; + use3::A!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs new file mode 100644 index 000000000000..c30f871cedbf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs @@ -0,0 +1,5 @@ +fn main() { + let _result = &Some(42).as_deref(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs new file mode 100644 index 000000000000..56388345e30c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs @@ -0,0 +1,5 @@ +fn main() { + let _result = &mut Some(42).as_deref_mut(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs new file mode 100644 index 000000000000..d2bb02c8d5df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs @@ -0,0 +1,5 @@ +fn main() { + let _result = &Ok(42).as_deref(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs new file mode 100644 index 000000000000..7157adfe6a33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs @@ -0,0 +1,5 @@ +fn main() { + let _result = &mut Ok(42).as_deref_mut(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50301.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50301.rs new file mode 100644 index 000000000000..13a81130bfc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50301.rs @@ -0,0 +1,33 @@ +// Tests that HRTBs are correctly accepted -- https://github.com/rust-lang/rust/issues/50301 +// check-pass +// ignore-compare-mode-chalk +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/gcc/testsuite/rust/rustc/ui/issues/issue-50403.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50403.rs new file mode 100644 index 000000000000..b23e24a3881d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50403.rs @@ -0,0 +1,6 @@ +#![feature(concat_idents)] + +fn main() { + let x = concat_idents!(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50411.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50411.rs new file mode 100644 index 000000000000..d1134262bc06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50411.rs @@ -0,0 +1,12 @@ +// Regression test for #50411: the MIR inliner was causing problems +// here because it would inline promoted code (which had already had +// elaborate-drops invoked on it) and then try to elaboate drops a +// second time. Uncool. + +// compile-flags:-Zmir-opt-level=3 +// build-pass + +fn main() { + let _ = (0 .. 1).filter(|_| [1].iter().all(|_| true)).count(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50415.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50415.rs new file mode 100644 index 000000000000..fcacb8798065 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50415.rs @@ -0,0 +1,17 @@ +// run-pass +fn main() { + // Simplified test case + let _ = || 0..=1; + + // Original test case + let full_length = 1024; + let range = { + // do some stuff, omit here + None + }; + + let range = range.map(|(s, t)| s..=t).unwrap_or(0..=(full_length-1)); + + assert_eq!(range, 0..=1023); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50442.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50442.rs new file mode 100644 index 000000000000..c1bc02106928 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50442.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +enum Void {} + +enum Foo { + A(i32), + B(Void), + C(i32) +} + +fn main() { + let _foo = Foo::A(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50471.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50471.rs new file mode 100644 index 000000000000..58609192bd3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50471.rs @@ -0,0 +1,10 @@ +// check-pass + +fn main() { + assert!({false}); + + assert!(r"\u{41}" == "A"); + + assert!(r"\u{".is_empty()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50480.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50480.rs new file mode 100644 index 000000000000..4d234062385f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50480.rs @@ -0,0 +1,9 @@ +#[derive(Clone, Copy)] +// { dg-error ".E0204." "" { target *-*-* } .-1 } +struct Foo(NotDefined, ::Item, Vec, String); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50518.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50518.rs new file mode 100644 index 000000000000..9f54e3ffa89f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50518.rs @@ -0,0 +1,41 @@ +// check-pass +use std::marker::PhantomData; + +struct Meta { + value: i32, + type_: PhantomData +} + +trait MetaTrait { + fn get_value(&self) -> i32; +} + +impl MetaTrait for Meta { + fn get_value(&self) -> i32 { self.value } +} + +trait Bar { + fn get_const(&self) -> &dyn MetaTrait; +} + +struct Foo { + _value: A +} + +impl Foo { + const CONST: &'static dyn MetaTrait = &Meta:: { + value: 10, + type_: PhantomData + }; +} + +impl Bar for Foo { + fn get_const(&self) -> &dyn MetaTrait { Self::CONST } +} + +fn main() { + let foo = Foo:: { _value: 10 }; + let bar: &dyn Bar = &foo; + println!("const {}", bar.get_const().get_value()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50571.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50571.rs new file mode 100644 index 000000000000..720d15761c24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50571.rs @@ -0,0 +1,9 @@ +// run-rustfix + +trait Foo { + fn foo([a, b]: [i32; 2]) {} +// { dg-error ".E0642." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50576.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50576.rs new file mode 100644 index 000000000000..be8ad75473af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50576.rs @@ -0,0 +1,7 @@ +fn main() { + |bool: [u8; break 'L]| 0; +// { dg-error ".E0268." "" { target *-*-* } .-1 } +// { dg-error ".E0268." "" { target *-*-* } .-2 } + Vec::<[u8; break]>::new(); // { dg-error ".E0268." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50581.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50581.rs new file mode 100644 index 000000000000..3f30b1605389 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50581.rs @@ -0,0 +1,4 @@ +fn main() { + |_: [u8; break]| (); // { dg-error ".E0268." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50582.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50582.rs new file mode 100644 index 000000000000..3c4b7d6f84ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50582.rs @@ -0,0 +1,6 @@ +fn main() { + Vec::<[(); 1 + for x in 0..1 {}]>::new(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50585.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50585.rs new file mode 100644 index 000000000000..3f1a17ab387b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50585.rs @@ -0,0 +1,6 @@ +fn main() { + |y: Vec<[(); for x in 0..2 {}]>| {}; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50599.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50599.rs new file mode 100644 index 000000000000..4ee7e42b0a62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50599.rs @@ -0,0 +1,6 @@ +fn main() { + const N: u32 = 1_000; + const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; // { dg-error ".E0425." "" { target *-*-* } } + let mut digits = [0u32; M]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5060.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5060.rs new file mode 100644 index 000000000000..418f21da78e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5060.rs @@ -0,0 +1,17 @@ +// run-pass +macro_rules! print_hd_tl { + ($field_hd:ident, $($field_tl:ident),+) => ({ + print!("{}", stringify!($field_hd)); + print!("::["); + $( + print!("{}", stringify!($field_tl)); + print!(", "); + )+ + print!("]\n"); + }) +} + +pub fn main() { + print_hd_tl!(x, y, z, w) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50600.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50600.rs new file mode 100644 index 000000000000..749b8b408d33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50600.rs @@ -0,0 +1,6 @@ +struct Foo ( + fn([u8; |x: u8| {}]), // { dg-error ".E0308." "" { target *-*-* } } +); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50618.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50618.rs new file mode 100644 index 000000000000..548ddfbf9e6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50618.rs @@ -0,0 +1,20 @@ +struct Point { + pub x: u64, + pub y: u64, +} + +const TEMPLATE: Point = Point { + x: 0, + y: 0 +}; + +fn main() { + let _ = || { + Point { + nonexistent: 0, +// { dg-error ".E0560." "" { target *-*-* } .-1 } + ..TEMPLATE + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5062.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5062.rs new file mode 100644 index 000000000000..874ee0da74e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5062.rs @@ -0,0 +1,3 @@ +fn main() { format!("{:?}", None); } +// { dg-error ".E0282." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5067.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5067.rs new file mode 100644 index 000000000000..f72bfba7a086 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5067.rs @@ -0,0 +1,76 @@ +#![allow(unused_macros)] + +// Tests that repetition matchers cannot match the empty token tree (since that would be +// ambiguous). + +// edition:2018 + +macro_rules! foo { + ( $()* ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( $()+ ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( $()? ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( $(),* ) => {}; // PASS + ( $(),+ ) => {}; // PASS + // `?` cannot have a separator... + ( [$()*] ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( [$()+] ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( [$()?] ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( [$(),*] ) => {}; // PASS + ( [$(),+] ) => {}; // PASS + // `?` cannot have a separator... + ( $($()* $(),* $(a)* $(a),* )* ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( $($()* $(),* $(a)* $(a),* )+ ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( $($()* $(),* $(a)* $(a),* )? ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( $($()? $(),* $(a)? $(a),* )* ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( $($()? $(),* $(a)? $(a),* )+ ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( $($()? $(),* $(a)? $(a),* )? ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( $(a $(),* $(a)* $(a),* )* ) => {}; // PASS + ( $($(a)+ $(),* $(a)* $(a),* )+ ) => {}; // PASS + ( $($(a)+ $(),* $(a)* $(a),* )? ) => {}; // PASS + + ( $(a $(),* $(a)? $(a),* )* ) => {}; // PASS + ( $($(a)+ $(),* $(a)? $(a),* )+ ) => {}; // PASS + ( $($(a)+ $(),* $(a)? $(a),* )? ) => {}; // PASS + + ( $(a $()+)* ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( $(a $()*)+ ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( $(a $()+)? ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } + ( $(a $()?)+ ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +// Original Issue + +macro_rules! make_vec { + (a $e1:expr $($(, a $e2:expr)*)*) => ([$e1 $($(, $e2)*)*]); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + let _ = make_vec![a 1, a 2, a 3]; +} + +// Minified Issue + +macro_rules! m { + ( $()* ) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +m!(); + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50687-ice-on-borrow.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50687-ice-on-borrow.rs new file mode 100644 index 000000000000..cf66a9a72152 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50687-ice-on-borrow.rs @@ -0,0 +1,42 @@ +// This previously caused an ICE at: +// librustc/traits/structural_impls.rs:180: impossible case reached + +#![no_main] + +use std::borrow::Borrow; +use std::io; +use std::io::Write; + +trait Constraint {} + +struct Container { + t: T, +} + +struct Borrowed; +struct Owned; + +impl<'a, T> Write for &'a Container +where + T: Constraint, + &'a T: Write, +{ + fn write(&mut self, buf: &[u8]) -> io::Result { + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Borrow for Owned { + fn borrow(&self) -> &Borrowed { + &Borrowed + } +} + +fn func(owned: Owned) { + let _: () = Borrow::borrow(&owned); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50688.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50688.rs new file mode 100644 index 000000000000..d0516a4fbc84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50688.rs @@ -0,0 +1,4 @@ +fn main() { + [1; || {}]; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50689.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50689.rs new file mode 100644 index 000000000000..81a500427340 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50689.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(unused_variables)] +enum Foo { + Bar = (|x: i32| { }, 42).1, +} + +fn main() { + assert_eq!(Foo::Bar as usize, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50714-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50714-1.rs new file mode 100644 index 000000000000..c7f7ef7b0e72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50714-1.rs @@ -0,0 +1,12 @@ +// Regression test for issue 50714, make sure that this isn't a linker error. + +#![no_std] +#![feature(start)] + +extern crate std; + +#[start] +fn start(_: isize, _: *const *const u8) -> isize where fn(&()): Eq { // { dg-error ".E0647." "" { target *-*-* } } + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50714.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50714.rs new file mode 100644 index 000000000000..7254905151ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50714.rs @@ -0,0 +1,4 @@ +// Regression test for issue 50714, make sure that this isn't a linker error. + +fn main() where fn(&()): Eq {} // { dg-error ".E0646." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50731.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50731.rs new file mode 100644 index 000000000000..5eabdff76e17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50731.rs @@ -0,0 +1,7 @@ +// run-pass +enum Void {} +fn foo(_: Result<(Void, u32), (Void, String)>) {} +fn main() { + let _: fn(_) = foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50761.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50761.rs new file mode 100644 index 000000000000..8178f4c2198b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50761.rs @@ -0,0 +1,24 @@ +// Confirm that we don't accidentally divide or mod by zero in llvm_type + +// build-pass + +mod a { + pub trait A {} +} + +mod b { + pub struct Builder {} + + pub fn new() -> Builder { + Builder {} + } + + impl Builder { + pub fn with_a(&mut self, _a: fn() -> dyn (::a::A)) {} + } +} + +pub use self::b::new; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50781.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50781.rs new file mode 100644 index 000000000000..3d837aa2a025 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50781.rs @@ -0,0 +1,20 @@ +#![deny(where_clauses_object_safety)] + +trait Trait {} + +trait X { + fn foo(&self) where Self: Trait; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +impl X for () { + fn foo(&self) {} +} + +impl Trait for dyn X {} + +pub fn main() { + // Check that this does not segfault. + ::foo(&()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50802.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50802.rs new file mode 100644 index 000000000000..8a6045944662 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50802.rs @@ -0,0 +1,9 @@ +#[allow(unreachable_code)] + +fn main() { + loop { + break while continue { // { dg-error ".E0590." "" { target *-*-* } } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50811.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50811.rs new file mode 100644 index 000000000000..8e41ed62b5a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50811.rs @@ -0,0 +1,57 @@ +// run-pass +#![feature(test)] + +extern crate test; + +use std::f64::{NAN, NEG_INFINITY, INFINITY, MAX}; +use std::mem::size_of; +use test::black_box; + +// Ensure the const-eval result and runtime result of float comparison are equivalent. + +macro_rules! compare { + ($op:tt) => { + compare!( + [NEG_INFINITY, -MAX, -1.0, -0.0, 0.0, 1.0, MAX, INFINITY, NAN], + $op + ); + }; + ([$($lhs:expr),+], $op:tt) => { + $(compare!( + $lhs, + $op, + [NEG_INFINITY, -MAX, -1.0, -0.0, 0.0, 1.0, MAX, INFINITY, NAN] + );)+ + }; + ($lhs:expr, $op:tt, [$($rhs:expr),+]) => { + $({ + // Wrap the check in its own function to reduce time needed to borrowck. + fn check() { + static CONST_EVAL: bool = $lhs $op $rhs; + let runtime_eval = black_box($lhs) $op black_box($rhs); + assert_eq!(CONST_EVAL, runtime_eval, stringify!($lhs $op $rhs)); + assert_eq!( + size_of::<[u8; ($lhs $op $rhs) as usize]>(), + runtime_eval as usize, + stringify!($lhs $op $rhs (forced const eval)) + ); + } + check(); + })+ + }; +} + +fn main() { + assert_eq!(0.0/0.0 < 0.0/0.0, false); + assert_eq!(0.0/0.0 > 0.0/0.0, false); + assert_eq!(NAN < NAN, false); + assert_eq!(NAN > NAN, false); + + compare!(==); + compare!(!=); + compare!(<); + compare!(<=); + compare!(>); + compare!(>=); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50825-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50825-1.rs new file mode 100644 index 000000000000..6dcb15001131 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50825-1.rs @@ -0,0 +1,23 @@ +// run-pass +// regression test for issue #50825 +// Make sure that the `impl` bound (): X is preferred over +// the (): X bound in the where clause. + +trait X { + type T; +} + +trait Y: X { + fn foo(x: &Self::T); +} + +impl X for () { + type T = (); +} + +impl Y> for () where (): Y { + fn foo(_x: &()) {} +} + +fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50825.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50825.rs new file mode 100644 index 000000000000..e628533864fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50825.rs @@ -0,0 +1,16 @@ +// run-pass +// regression test for issue #50825 +// Make sure that the built-in bound {integer}: Sized is preferred over +// the u64: Sized bound in the where clause. + +fn foo(y: &[()]) +where + u64: Sized, +{ + y[0] +} + +fn main () { + foo(&[()]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs new file mode 100644 index 000000000000..6b5ff049f7ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50865-private-impl-trait/auxiliary/lib.rs @@ -0,0 +1,19 @@ +// revisions: default miropt +//[miropt]compile-flags: -Z mir-opt-level=2 +// ~^ This flag is for #77668, it used to be ICE. + +#![crate_type = "lib"] + +pub fn bar

( // Error won't happen if "bar" is not generic + _baz: P, +) { + hide_foo()(); +} + +fn hide_foo() -> impl Fn() { // Error won't happen if "iterate" hasn't impl Trait or has generics + foo +} + +fn foo() { // Error won't happen if "foo" isn't used in "iterate" or has generics +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50865-private-impl-trait/main.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50865-private-impl-trait/main.rs new file mode 100644 index 000000000000..913f86e1df03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50865-private-impl-trait/main.rs @@ -0,0 +1,17 @@ +// run-pass +// aux-build:lib.rs + +// Regression test for #50865. +// When using generics or specifying the type directly, this example +// codegens `foo` internally. However, when using a private `impl Trait` +// function which references another private item, `foo` (in this case) +// wouldn't be codegenned until main.rs used `bar`, as with impl Trait +// it is not cast to `fn()` automatically to satisfy e.g. +// `fn foo() -> fn() { ... }`. + +extern crate lib; + +fn main() { + lib::bar(()); // Error won't happen if bar is called from same crate +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5099.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5099.rs new file mode 100644 index 000000000000..886505df925d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5099.rs @@ -0,0 +1,14 @@ +trait B { + fn a() -> A { + this.a // { dg-error ".E0425." "" { target *-*-* } } + } + fn b(x: i32) { + this.b(x); // { dg-error ".E0425." "" { target *-*-* } } + } + fn c() { + let _ = || this.a; // { dg-error ".E0425." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-50993.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-50993.rs new file mode 100644 index 000000000000..f28ce7957d5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-50993.rs @@ -0,0 +1,10 @@ +// compile-flags: --crate-type dylib --target thumbv7em-none-eabihf +// needs-llvm-components: arm +// build-pass +// error-pattern: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf` + +#![feature(no_core)] + +#![no_std] +#![no_core] + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5100.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5100.rs new file mode 100644 index 000000000000..685cb62045e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5100.rs @@ -0,0 +1,58 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] + +enum A { B, C } + +fn main() { + match (true, false) { + A::B => (), +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + _ => () + } + + match (true, false) { + (true, false, false) => () +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + } + + match (true, false) { + (true, false, false) => () +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + } + + match (true, false) { + box (true, false) => () +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + } + + match (true, false) { + &(true, false) => () +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + } + + + let v = [('a', 'b') // { dg-error ".E0618." "" { target *-*-* } } + ('c', 'd'), + ('e', 'f')]; + + for &(x,y) in &v {} // should be OK + + // Make sure none of the errors above were fatal + let x: char = true; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51022.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51022.rs new file mode 100644 index 000000000000..2dd4ed2f2a59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51022.rs @@ -0,0 +1,3 @@ +fn main<'a>() { } +// { dg-error ".E0131." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51044.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51044.rs new file mode 100644 index 000000000000..2c1c68044d94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51044.rs @@ -0,0 +1,31 @@ +// run-pass +// regression test for issue #50825 +// Check that the feature gate normalizes associated types. + +#![allow(dead_code)] +struct Foo(T); +struct Duck; +struct Quack; + +trait Hello where A: Animal { +} + +trait Animal { + type Noise; +} + +trait Loud { +} + +impl Loud for f32 { +} + +impl Animal for Duck { + type Noise = Quack; +} + +impl Hello for Foo where f32: Loud<::Noise> { +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51102.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51102.rs new file mode 100644 index 000000000000..0de709f4ef7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51102.rs @@ -0,0 +1,39 @@ +enum SimpleEnum { + NoState, +} + +struct SimpleStruct { + no_state_here: u64, +} + +fn main() { + let _ = |simple| { + match simple { + SimpleStruct { + state: 0, +// { dg-error ".E0026." "" { target *-*-* } .-1 } + .. + } => (), + } + }; + + let _ = |simple| { + match simple { + SimpleStruct { + no_state_here: 0, + no_state_here: 1 +// { dg-error ".E0025." "" { target *-*-* } .-1 } + } => (), + } + }; + + let _ = |simple| { + match simple { + SimpleEnum::NoState { + state: 0 +// { dg-error ".E0026." "" { target *-*-* } .-1 } + } => (), + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51116.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51116.rs new file mode 100644 index 000000000000..4a0c6a9a7eba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51116.rs @@ -0,0 +1,15 @@ +fn main() { + let tiles = Default::default(); + for row in &mut tiles { + for tile in row { +// { dg-note "" "" { target *-*-* } .-1 } + *tile = 0; +// { dg-error ".E0282." "" { target *-*-* } .-1 } +// { dg-note ".E0282." "" { target *-*-* } .-2 } +// { dg-note ".E0282." "" { target *-*-* } .-3 } + } + } + + let tiles: [[usize; 3]; 3] = tiles; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51154.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51154.rs new file mode 100644 index 000000000000..4f098241f8d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51154.rs @@ -0,0 +1,7 @@ +fn foo() { + let _: Box = Box::new(|| ()); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51185.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51185.rs new file mode 100644 index 000000000000..5ad1e2eefd51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51185.rs @@ -0,0 +1,9 @@ +// run-pass +fn foo() -> impl Into fn(&'a ())> { + (|_| {}) as for<'a> fn(&'a ()) +} + +fn main() { + foo().into()(&()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51244.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51244.rs new file mode 100644 index 000000000000..5f1efeb9c595 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51244.rs @@ -0,0 +1,5 @@ +fn main() { + let ref my_ref @ _ = 0; + *my_ref = 0; // { dg-error ".E0594." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51301.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51301.rs new file mode 100644 index 000000000000..5ccc87f4d882 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51301.rs @@ -0,0 +1,36 @@ +use std::any::TypeId; +use std::collections::HashMap; +use std::hash::Hash; + +trait State { + type EventType; + fn get_type_id_of_state(&self) -> TypeId; +} + +struct StateMachine { + current_state: Box>, + transition_table: + HashMap Box>>>, +} + +impl StateMachine { + fn inner_process_event(&mut self, event: EventType) -> Result<(), i8> { + let new_state_creation_function = self + .transition_table + .iter() + .find(|(&event_typeid, _)| event_typeid == self.current_state.get_type_id_of_state()) + .ok_or(1)? + .1 + .iter() + .find(|(&event_type, _)| event == event_type) +// { dg-error ".E0507." "" { target *-*-* } .-1 } + .ok_or(2)? + .1; + + self.current_state = new_state_creation_function(); + Ok(()) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51345-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51345-2.rs new file mode 100644 index 000000000000..755ec760dc24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51345-2.rs @@ -0,0 +1,9 @@ +// run-fail +// error-pattern: thread 'main' panicked at 'explicit panic' +// ignore-emscripten no processes + +fn main() { + let mut vec = vec![]; + vec.push((vec.len(), panic!())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51345.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51345.rs new file mode 100644 index 000000000000..358d6a406196 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51345.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(unreachable_code)] + +fn main() { + let mut v = Vec::new(); + + loop { v.push(break) } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51515.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51515.rs new file mode 100644 index 000000000000..56e23c21b206 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51515.rs @@ -0,0 +1,13 @@ +fn main() { + let foo = &16; +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + *foo = 32; +// { dg-error ".E0594." "" { target *-*-* } .-1 } + let bar = foo; +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + *bar = 64; +// { dg-error ".E0594." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5153.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5153.rs new file mode 100644 index 000000000000..ad29cd2a4f88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5153.rs @@ -0,0 +1,13 @@ +trait Foo { + fn foo(self: Box); +} + +impl Foo for isize { + fn foo(self: Box) { } +} + +fn main() { + (&5isize as &dyn Foo).foo(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51582.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51582.rs new file mode 100644 index 000000000000..217acca72b29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51582.rs @@ -0,0 +1,19 @@ +// run-pass +#![feature(core_intrinsics)] + +#[repr(i8)] +pub enum Enum { + VariantA, + VariantB, +} + +fn make_b() -> Enum { Enum::VariantB } + +fn main() { + assert_eq!(1, make_b() as i8); + assert_eq!(1, make_b() as u8); + assert_eq!(1, make_b() as i32); + assert_eq!(1, make_b() as u32); + assert_eq!(1, std::intrinsics::discriminant_value(&make_b())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51602.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51602.rs new file mode 100644 index 000000000000..b9d3838d127b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51602.rs @@ -0,0 +1,7 @@ +fn main(){ + if i in 1..10 { +// { dg-error "" "" { target *-*-* } .-1 } + break; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51632-try-desugar-incompatible-types.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51632-try-desugar-incompatible-types.rs new file mode 100644 index 000000000000..be9bb1231c57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51632-try-desugar-incompatible-types.rs @@ -0,0 +1,13 @@ +#![allow(dead_code)] + +fn missing_discourses() -> Result { + Ok(1) +} + +fn forbidden_narratives() -> Result { + missing_discourses()? +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51655.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51655.rs new file mode 100644 index 000000000000..4ba0ba7679a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51655.rs @@ -0,0 +1,15 @@ +// check-pass +#![allow(dead_code)] + +const PATH_DOT: &[u8] = &[b'.']; + +fn match_slice(element: &[u8]) { + match element { + &[] => {} + PATH_DOT => {} + _ => {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51714.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51714.rs new file mode 100644 index 000000000000..d0cc94d7d747 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51714.rs @@ -0,0 +1,14 @@ +fn main() { + |_: [_; return || {}] | {}; +// { dg-error ".E0572." "" { target *-*-* } .-1 } + + [(); return || {}]; +// { dg-error ".E0572." "" { target *-*-* } .-1 } + + [(); return |ice| {}]; +// { dg-error ".E0572." "" { target *-*-* } .-1 } + + [(); return while let Some(n) = Some(0) {}]; +// { dg-error ".E0572." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51770.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51770.rs new file mode 100644 index 000000000000..92c922ecc24e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51770.rs @@ -0,0 +1,21 @@ +// check-pass + +#![crate_type = "lib"] + +// In an older version, when NLL was still a feature, the following previously did not compile +// #![feature(nll)] + +use std::ops::Index; + +pub struct Test { + a: T, +} + +impl Index for Test { + type Output = T; + + fn index(&self, _index: usize) -> &Self::Output { + &self.a + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51798.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51798.rs new file mode 100644 index 000000000000..2ffa14a65771 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51798.rs @@ -0,0 +1,15 @@ +// edition:2018 +// aux-build:issue-51798.rs +// check-pass + +extern crate issue_51798; + +mod server { + fn f() { + let mut v = issue_51798::vec(); + v.clear(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51848.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51848.rs new file mode 100644 index 000000000000..20555eb42982 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51848.rs @@ -0,0 +1,21 @@ +// In case of macro expansion, the errors should be matched using the deepest callsite in the +// macro call stack whose span is in the current file + +macro_rules! macro_with_error { + ( ) => { + println!("{"); // { dg-error "" "" { target *-*-* } } + }; +} + +fn foo() { + +} + +fn main() { + macro_with_error!(); + //^ In case of a local macro we want the error to be matched in the macro definition, not here + + println!("}"); // { dg-error "" "" { target *-*-* } } + //^ In case of an external macro we want the error to be matched here +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51874.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51874.rs new file mode 100644 index 000000000000..aefa501dd15c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51874.rs @@ -0,0 +1,4 @@ +fn main() { + let a = (1.0).pow(1.0); // { dg-error ".E0689." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51907.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51907.rs new file mode 100644 index 000000000000..d1606050aafc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51907.rs @@ -0,0 +1,20 @@ +// run-pass +trait Foo { + extern fn borrow(&self); + extern fn take(self: Box); +} + +struct Bar; +impl Foo for Bar { + #[allow(improper_ctypes_definitions)] + extern fn borrow(&self) {} + #[allow(improper_ctypes_definitions)] + extern fn take(self: Box) {} +} + +fn main() { + let foo: Box = Box::new(Bar); + foo.borrow(); + foo.take() +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5192.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5192.rs new file mode 100644 index 000000000000..c5c1f829db5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5192.rs @@ -0,0 +1,42 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub trait EventLoop { + fn dummy(&self) { } +} + +pub struct UvEventLoop { + uvio: isize +} + +impl UvEventLoop { + pub fn new() -> UvEventLoop { + UvEventLoop { + uvio: 0 + } + } +} + +impl EventLoop for UvEventLoop { +} + +pub struct Scheduler { + event_loop: Box, +} + +impl Scheduler { + + pub fn new(event_loop: Box) -> Scheduler { + Scheduler { + event_loop: event_loop, + } + } +} + +pub fn main() { + let _sched = Scheduler::new(box UvEventLoop::new() as Box); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-51947.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-51947.rs new file mode 100644 index 000000000000..061293658e0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-51947.rs @@ -0,0 +1,18 @@ +// build-pass + +#![crate_type = "lib"] +#![feature(linkage)] + +// MergeFunctions will merge these via an anonymous internal +// backing function, which must be named if ThinLTO buffers are used + +#[linkage = "weak"] +pub fn fn1(a: u32, b: u32, c: u32) -> u32 { + a + b + c +} + +#[linkage = "weak"] +pub fn fn2(a: u32, b: u32, c: u32) -> u32 { + a + b + c +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52023-array-size-pointer-cast.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52023-array-size-pointer-cast.rs new file mode 100644 index 000000000000..1091713c408f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52023-array-size-pointer-cast.rs @@ -0,0 +1,5 @@ +fn main() { + let _ = [0; (&0 as *const i32) as usize]; // { dg-error ".E0080." "" { target *-*-* } } +// { dg-error ".E0080." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52049.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52049.rs new file mode 100644 index 000000000000..df1d462fa100 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52049.rs @@ -0,0 +1,9 @@ +fn foo(_: &'static u32) {} + +fn unpromotable(t: T) -> T { t } + +fn main() { + foo(&unpromotable(5u32)); +} +// { dg-error ".E0716." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52057.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52057.rs new file mode 100644 index 000000000000..71497063b0ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52057.rs @@ -0,0 +1,23 @@ +// Regression test for #52057. There is an implied bound +// that `I: 'a` where `'a` is the lifetime of `self` in `parse_first`; +// but to observe that, one must normalize first. +// +// run-pass + +pub trait Parser { + type Input; + + fn parse_first(input: &mut Self::Input); +} + +impl<'a, I, P: ?Sized> Parser for &'a mut P +where + P: Parser, +{ + type Input = I; + + fn parse_first(_: &mut Self::Input) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52060.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52060.rs new file mode 100644 index 000000000000..794eaa8ca154 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52060.rs @@ -0,0 +1,9 @@ +// Regression test for https://github.com/rust-lang/rust/issues/52060 +// The compiler shouldn't ICE in this case +static A: &'static [u32] = &[1]; +static B: [u32; 1] = [0; A.len()]; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +// { dg-error ".E0080." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52126-assign-op-invariance.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52126-assign-op-invariance.rs new file mode 100644 index 000000000000..655fc9dffbe0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52126-assign-op-invariance.rs @@ -0,0 +1,50 @@ +// Issue 52126: With respect to variance, the assign-op's like += were +// accidentally lumped together with other binary op's. In both cases +// we were coercing the LHS of the op to the expected supertype. +// +// The problem is that since the LHS of += is modified, we need the +// parameter to be invariant with respect to the overall type, not +// covariant. + +use std::collections::HashMap; +use std::ops::AddAssign; + +pub fn main() { + panics(); +} + +pub struct Counter<'l> { + map: HashMap<&'l str, usize>, +} + +impl<'l> AddAssign for Counter<'l> +{ + fn add_assign(&mut self, rhs: Counter<'l>) { + rhs.map.into_iter().for_each(|(key, val)| { + let count = self.map.entry(key).or_insert(0); + *count += val; + }); + } +} + +/// Often crashes, if not prints invalid strings. +pub fn panics() { + let mut acc = Counter{map: HashMap::new()}; + for line in vec!["123456789".to_string(), "12345678".to_string()] { + let v: Vec<&str> = line.split_whitespace().collect(); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + // println!("accumulator before add_assign {:?}", acc.map); + let mut map = HashMap::new(); + for str_ref in v { + let e = map.entry(str_ref); + println!("entry: {:?}", e); + let count = e.or_insert(0); + *count += 1; + } + let cnt2 = Counter{map}; + acc += cnt2; + // println!("accumulator after add_assign {:?}", acc.map); + // line gets dropped here but references are kept in acc.map + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52140/auxiliary/some_crate.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52140/auxiliary/some_crate.rs new file mode 100644 index 000000000000..cb2af5e8c0d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52140/auxiliary/some_crate.rs @@ -0,0 +1,6 @@ +#![crate_type = "lib"] + +pub fn hello() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52140/main.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52140/main.rs new file mode 100644 index 000000000000..56827934b1ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52140/main.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:some_crate.rs +// compile-flags:--extern some_crate +// edition:2018 + +mod foo { + pub use some_crate; +} + +fn main() { + ::some_crate::hello(); + foo::some_crate::hello(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52141/auxiliary/some_crate.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52141/auxiliary/some_crate.rs new file mode 100644 index 000000000000..cb2af5e8c0d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52141/auxiliary/some_crate.rs @@ -0,0 +1,6 @@ +#![crate_type = "lib"] + +pub fn hello() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52141/main.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52141/main.rs new file mode 100644 index 000000000000..954f7a5aa127 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52141/main.rs @@ -0,0 +1,17 @@ +// run-pass +// aux-build:some_crate.rs +// compile-flags:--extern some_crate +// edition:2018 + +use some_crate as some_name; + +mod foo { + pub use crate::some_name::*; +} + +fn main() { + ::some_crate::hello(); + some_name::hello(); + foo::hello(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5216.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5216.rs new file mode 100644 index 000000000000..cb7daa733dbb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5216.rs @@ -0,0 +1,11 @@ +fn f() { } +struct S(Box); +pub static C: S = S(f); // { dg-error ".E0308." "" { target *-*-* } } + + +fn g() { } +type T = Box; +pub static D: T = g; // { dg-error ".E0308." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52169.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52169.rs new file mode 100644 index 000000000000..ec776a413c21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52169.rs @@ -0,0 +1,15 @@ +// run-pass + +macro_rules! a { + ($i:literal) => { "right" }; + ($i:tt) => { "wrong" }; +} + +macro_rules! b { + ($i:literal) => { a!($i) }; +} + +fn main() { + assert_eq!(b!(0), "right"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52213.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52213.rs new file mode 100644 index 000000000000..c9d5de86e175 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52213.rs @@ -0,0 +1,15 @@ +fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T { + match (&t,) { // { dg-error ".E0495." "" { target *-*-* } } + ((u,),) => u, + } +} + +fn main() { + let x = { + let y = Box::new((42,)); + transmute_lifetime(&y) + }; + + println!("{}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52240.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52240.rs new file mode 100644 index 000000000000..846e446ebd97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52240.rs @@ -0,0 +1,17 @@ +// issue-52240: Can turn immutable into mut with `ref mut` + +enum Foo { + Bar(i32), +} + +fn main() { + let arr = vec!(Foo::Bar(0)); + if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) { +// { dg-error ".E0596." "" { target *-*-* } .-1 } + *val = 9001; + } + match arr[0] { + Foo::Bar(ref s) => println!("{}", s) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52262.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52262.rs new file mode 100644 index 000000000000..b6aa7cc0dad4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52262.rs @@ -0,0 +1,26 @@ +// compile-flags:-Ztreat-err-as-bug=5 +#[derive(Debug)] +enum MyError { + NotFound { key: Vec }, + Err41, +} + +impl std::error::Error for MyError {} + +impl std::fmt::Display for MyError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + MyError::NotFound { key } => write!( + f, + "unknown error with code {}.", + String::from_utf8(*key).unwrap() +// { dg-error ".E0507." "" { target *-*-* } .-1 } + ), + MyError::Err41 => write!(f, "Sit by a lake"), + } + } +} +fn main() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5239-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5239-1.rs new file mode 100644 index 000000000000..7c675ff4aac6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5239-1.rs @@ -0,0 +1,7 @@ +// Regression test for issue #5239 + +fn main() { + let x = |ref x: isize| { x += 1; }; +// { dg-error ".E0368." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5239-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5239-2.rs new file mode 100644 index 000000000000..2a53e1a654bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5239-2.rs @@ -0,0 +1,10 @@ +// run-pass +// Regression test for issue #5239 + + +pub fn main() { + let _f = |ref x: isize| { *x }; + let foo = 10; + assert_eq!(_f(foo), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5243.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5243.rs new file mode 100644 index 000000000000..d56bd075a2e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5243.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +// Check that merely having lifetime parameters is not +// enough for codegen to consider this as non-monomorphic, +// which led to various assertions and failures in turn. + +// pretty-expanded FIXME #23616 + +struct S<'a> { + v: &'a isize +} + +fn f<'lt>(_s: &'lt S<'lt>) {} + +pub fn main() { + f(& S { v: &42 }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52489.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52489.rs new file mode 100644 index 000000000000..103b70cae074 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52489.rs @@ -0,0 +1,9 @@ +// edition:2018 +// aux-build:issue-52489.rs +// compile-flags:--extern issue_52489 + +use issue_52489; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52496.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52496.rs new file mode 100644 index 000000000000..bd9836fdd826 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52496.rs @@ -0,0 +1,13 @@ +struct Foo { bar: f64, baz: i64, bat: i64 } + +fn main() { + let _ = Foo { bar: .5, baz: 42 }; +// { dg-error ".E0063." "" { target *-*-* } .-1 } +// { dg-error ".E0063." "" { target *-*-* } .-2 } + let bar = 1.5f32; + let _ = Foo { bar.into(), bat: -1, . }; +// { dg-error ".E0063." "" { target *-*-* } .-1 } +// { dg-error ".E0063." "" { target *-*-* } .-2 } +// { dg-error ".E0063." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52533-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52533-1.rs new file mode 100644 index 000000000000..299b1c001cbb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52533-1.rs @@ -0,0 +1,12 @@ +#![allow(warnings)] + +struct Foo<'a, 'b, T: 'a + 'b> { x: &'a T, y: &'b T } + +fn gimme(_: impl for<'a, 'b, 'c> FnOnce(&'a Foo<'a, 'b, u32>, + &'a Foo<'a, 'c, u32>) -> &'a Foo<'a, 'b, u32>) { } + +fn main() { + gimme(|x, y| y) +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52533.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52533.rs new file mode 100644 index 000000000000..0411f5ec2a2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52533.rs @@ -0,0 +1,8 @@ +fn foo(_: impl for<'a> FnOnce(&'a u32, &u32) -> &'a u32) { +} + +fn main() { + foo(|a, b| b) +// { dg-error ".E0312." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52557.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52557.rs new file mode 100644 index 000000000000..238c700cd9c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52557.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(unused_imports)] +// This test checks for namespace pollution by private tests. +// Tests used to marked as public causing name conflicts with normal +// functions only in test builds. + +// compile-flags: --test + +mod a { + pub fn foo() -> bool { + true + } +} + +mod b { + #[test] + fn foo() { + local_name(); // ensure the local name still works + } + + #[test] + fn local_name() {} +} + +use a::*; +use b::*; + +pub fn conflict() { + let _: bool = foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52705/auxiliary/png2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52705/auxiliary/png2.rs new file mode 100644 index 000000000000..f4eb7749d83d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52705/auxiliary/png2.rs @@ -0,0 +1,4 @@ +#![crate_type = "lib"] + +pub struct DecodingError; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52705/main.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52705/main.rs new file mode 100644 index 000000000000..280b8e1507e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52705/main.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +// aux-build:png2.rs +// compile-flags:--extern png2 +// edition:2018 + +mod png { + use png2 as png_ext; + + fn foo() -> png_ext::DecodingError { unimplemented!() } +} + +fn main() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52717.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52717.rs new file mode 100644 index 000000000000..49952c800774 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52717.rs @@ -0,0 +1,14 @@ +enum A { + A { + foo: usize, + } +} + +fn main() { + let x = A::A { foo: 3 }; + match x { + A::A { fob } => { println!("{}", fob); } +// { dg-error ".E0026." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5280.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5280.rs new file mode 100644 index 000000000000..2191ace1a3b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5280.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] + +type FontTableTag = u32; + +trait FontTableTagConversions { + fn tag_to_string(self); +} + +impl FontTableTagConversions for FontTableTag { + fn tag_to_string(self) { + &self; + } +} + +pub fn main() { + 5.tag_to_string(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52891.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52891.rs new file mode 100644 index 000000000000..3311e0723757 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52891.rs @@ -0,0 +1,39 @@ +// aux-build:issue-52891.rs +// run-rustfix + +#![allow(warnings)] + +extern crate issue_52891; + +// Check that we don't suggest renaming duplicate imports but instead +// suggest removing one. + +use issue_52891::a; +use issue_52891::a; // { dg-error ".E0252." "" { target *-*-* } } + +use issue_52891::{a, b, c}; // { dg-error ".E0252." "" { target *-*-* } } +use issue_52891::{d, a, e}; // { dg-error ".E0252." "" { target *-*-* } } +use issue_52891::{f, g, a}; // { dg-error ".E0252." "" { target *-*-* } } + +use issue_52891::{a, // { dg-error ".E0252." "" { target *-*-* } } + h, + i}; +use issue_52891::{j, + a, // { dg-error ".E0252." "" { target *-*-* } } + k}; +use issue_52891::{l, + m, + a}; // { dg-error ".E0252." "" { target *-*-* } } + +use issue_52891::a::inner; +use issue_52891::b::inner; // { dg-error ".E0252." "" { target *-*-* } } + +use issue_52891::{self}; +// { dg-error ".E0254." "" { target *-*-* } .-1 } + +use issue_52891::n; +#[macro_use] +use issue_52891::n; // { dg-error ".E0252." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-52992.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-52992.rs new file mode 100644 index 000000000000..2b5b5800a2cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-52992.rs @@ -0,0 +1,26 @@ +// Regression test for an NLL-related ICE (#52992) -- computing +// implied bounds was causing outlives relations that were not +// properly handled. +// +// check-pass + +fn main() {} + +fn fail<'a>() -> Struct<'a, Generic<()>> { + Struct(&Generic(())) +} + +struct Struct<'a, T>(&'a T) where + T: Trait + 'a, + T::AT: 'a; // only fails with this bound + +struct Generic(T); + +trait Trait { + type AT; +} + +impl Trait for Generic { + type AT = T; // only fails with a generic AT +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5315.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5315.rs new file mode 100644 index 000000000000..29c9cb5c9446 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5315.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct A(bool); + +pub fn main() { + let f = A; + f(true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5321-immediates-with-bare-self.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5321-immediates-with-bare-self.rs new file mode 100644 index 000000000000..c05bb224e83f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5321-immediates-with-bare-self.rs @@ -0,0 +1,16 @@ +// run-pass + +trait Fooable { + fn yes(self); +} + +impl Fooable for usize { + fn yes(self) { + for _ in 0..self { println!("yes"); } + } +} + +pub fn main() { + 2.yes(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53251.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53251.rs new file mode 100644 index 000000000000..2eb0bf0f67a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53251.rs @@ -0,0 +1,22 @@ +struct S; + +impl S { + fn f() {} +} + +macro_rules! impl_add { + ($($n:ident)*) => { + $( + fn $n() { + S::f::(); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } + } + )* + } +} + +impl_add!(a b); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53275.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53275.rs new file mode 100644 index 000000000000..7a4640c96384 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53275.rs @@ -0,0 +1,10 @@ +// build-pass + +#![crate_type = "lib"] +#![allow(unconditional_panic)] +struct S(u8); + +pub fn ice() { + S([][0]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53300.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53300.rs new file mode 100644 index 000000000000..0bccf7e038fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53300.rs @@ -0,0 +1,13 @@ +// issue 53300 + +pub trait A { + fn add(&self, b: i32) -> i32; +} + +fn addition() -> Wrapper {} +// { dg-error ".E0412." "" { target *-*-* } .-1 } + +fn main() { + let res = addition(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53333.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53333.rs new file mode 100644 index 000000000000..e9a29e993b81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53333.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(unused_imports)] +// edition:2018 + +fn main() { + use std; + let std = "std"; + println!("{}", std); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53348.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53348.rs new file mode 100644 index 000000000000..155d1c7430f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53348.rs @@ -0,0 +1,16 @@ +fn main() { + let mut v = vec!["hello", "this", "is", "a", "test"]; + + let v2 = Vec::new(); + + v.into_iter().map(|s|s.to_owned()).collect::>(); + + let mut a = String::new(); + for i in v { + a = *i.to_string(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } + v2.push(a); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53419.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53419.rs new file mode 100644 index 000000000000..5c7c43aa370e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53419.rs @@ -0,0 +1,9 @@ +// check-pass + +struct Foo { + bar: dyn for<'r> Fn(usize, &'r dyn FnMut()) +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53498.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53498.rs new file mode 100644 index 000000000000..c2e1bd4ec20b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53498.rs @@ -0,0 +1,18 @@ +pub mod test { + pub struct A; + pub struct B; + pub struct Foo(T); + + impl Foo { + fn foo() {} + } + + impl Foo { + fn foo() {} + } +} + +fn main() { + test::Foo::::foo(); // { dg-error ".E0624." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5353.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5353.rs new file mode 100644 index 000000000000..d10416c71424 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5353.rs @@ -0,0 +1,19 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +const INVALID_ENUM : u32 = 0; +const INVALID_VALUE : u32 = 1; + +fn gl_err_str(err: u32) -> String +{ + match err + { + INVALID_ENUM => { "Invalid enum".to_string() }, + INVALID_VALUE => { "Invalid value".to_string() }, + _ => { "Unknown error".to_string() } + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53565.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53565.rs new file mode 100644 index 000000000000..fb765db672ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53565.rs @@ -0,0 +1,8 @@ +use std::time::{foo, bar, buzz}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +use std::time::{abc, def}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +fn main(){ + println!("Hello World!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53568.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53568.rs new file mode 100644 index 000000000000..b6ff38a96def --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53568.rs @@ -0,0 +1,48 @@ +// Regression test for an NLL-related ICE (#53568) -- we failed to +// resolve inference variables in "custom type-ops". +// +// check-pass + +trait Future { + type Item; +} + +impl Future for F +where F: Fn() -> T +{ + type Item = T; +} + +trait Connect {} + +struct Connector { + handler: H, +} + +impl Connect for Connector +where + T: 'static, + H: Future +{ +} + +struct Client { + connector: C, +} + +fn build(_connector: C) -> Client { + unimplemented!() +} + +fn client(handler: H) -> Client +where H: Fn() + Copy +{ + let connector = Connector { + handler, + }; + let client = build(connector); + client +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5358-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5358-1.rs new file mode 100644 index 000000000000..a1aefc81912d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5358-1.rs @@ -0,0 +1,14 @@ +enum Either { Left(T), Right(U) } +struct S(Either); + +fn main() { + match S(Either::Left(5)) { + Either::Right(_) => {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53675-a-test-called-panic.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53675-a-test-called-panic.rs new file mode 100644 index 000000000000..4afc39e1bc50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53675-a-test-called-panic.rs @@ -0,0 +1,37 @@ +// rust-lang/rust#53675: At one point the compiler errored when a test +// named `panic` used the `assert!` macro in expression position. + +// check-pass +// compile-flags: --test + +mod in_expression_position { + #[test] + fn panic() { + assert!(true) + } +} + +mod in_statement_position { + #[test] + fn panic() { + assert!(true); + } +} + +mod what_if_we_use_panic_directly_in_expr { + #[test] + #[should_panic] + fn panic() { + panic!("in expr") + } +} + + +mod what_if_we_use_panic_directly_in_stmt { + #[test] + #[should_panic] + fn panic() { + panic!("in stmt"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53692.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53692.rs new file mode 100644 index 000000000000..b738a3f1a353 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53692.rs @@ -0,0 +1,18 @@ +fn main() { + let items = vec![1, 2, 3]; + let ref_items: &[i32] = &items; + let items_clone: Vec = ref_items.clone(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + // in that case no suggestion will be triggered + let items_clone_2:Vec = items.clone(); + + let s = "hi"; + let string: String = s.clone(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + // in that case no suggestion will be triggered + let s2 = "hi"; + let string_2: String = s2.to_string(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53712.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53712.rs new file mode 100644 index 000000000000..f0a0a5ede639 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53712.rs @@ -0,0 +1,10 @@ +// issue #53712: make the error generated by using tuple indexing on an array more specific + +fn main() { + let arr = [10, 20, 30, 40, 50]; + arr.0; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +// { help ".E0609." "" { target *-*-* } .-2 } +// { suggestion ".E0609." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53728.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53728.rs new file mode 100644 index 000000000000..fc429e3c7b69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53728.rs @@ -0,0 +1,20 @@ +// run-pass + +#![allow(dead_code)] +#[repr(u16)] +enum DeviceKind { + Nil = 0, +} + +#[repr(packed)] +struct DeviceInfo { + endianness: u8, + device_kind: DeviceKind, +} + +fn main() { + let _x = None::<(DeviceInfo, u8)>; + let _y = None::<(DeviceInfo, u16)>; + let _z = None::<(DeviceInfo, u64)>; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53787-inline-assembler-macro.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53787-inline-assembler-macro.rs new file mode 100644 index 000000000000..8daa8cf8fbea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53787-inline-assembler-macro.rs @@ -0,0 +1,27 @@ +// Regression test for Issue #53787: Fix ICE when creating a label in inline assembler with macros. + +// build-fail +// ignore-emscripten + +#![feature(llvm_asm)] + +macro_rules! fake_jump { + ($id:expr) => { + unsafe { + llvm_asm!( + " + jmp $0 + lea eax, [ebx] + xor eax, 0xDEADBEEF + retn + $0: + "::"0"($id)::"volatile", "intel"); + } + }; +} + +fn main() { + fake_jump!("FirstFunc"); // { dg-error ".E0669." "" { target *-*-* } } + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53843.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53843.rs new file mode 100644 index 000000000000..37c7ba025538 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53843.rs @@ -0,0 +1,27 @@ +// run-pass + +use std::ops::Deref; + +pub struct Pin

(P); + +impl Deref for Pin

+where + P: Deref, +{ + type Target = T; + + fn deref(&self) -> &T { + &*self.0 + } +} + +impl

Pin

{ + fn poll(self) {} +} + +fn main() { + let mut unit = (); + let pin = Pin(&mut unit); + pin.poll(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-53912.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-53912.rs new file mode 100644 index 000000000000..c2f21c0aa228 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-53912.rs @@ -0,0 +1,38 @@ +// build-pass + +// This test is the same code as in ui/symbol-names/issue-60925.rs but this checks that the +// reproduction compiles successfully and doesn't segfault, whereas that test just checks that the +// symbol mangling fix produces the correct result. + +fn dummy() {} + +mod llvm { + pub(crate) struct Foo; +} +mod foo { + pub(crate) struct Foo(T); + + impl Foo<::llvm::Foo> { + pub(crate) fn foo() { + for _ in 0..0 { + for _ in &[::dummy()] { + ::dummy(); + ::dummy(); + ::dummy(); + } + } + } + } + + pub(crate) fn foo() { + Foo::foo(); + Foo::foo(); + } +} + +pub fn foo() { + foo::foo(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54044.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54044.rs new file mode 100644 index 000000000000..614df7ff6f6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54044.rs @@ -0,0 +1,15 @@ +// ignore-tidy-linelength +#![deny(unused_attributes)] // { dg-note "" "" { target *-*-* } } + +#[cold] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +struct Foo; // { dg-note "" "" { target *-*-* } } + +fn main() { + #[cold] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + 5; // { dg-note "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54062.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54062.rs new file mode 100644 index 000000000000..aebe9324cdee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54062.rs @@ -0,0 +1,13 @@ +use std::sync::Mutex; + +struct Test { + comps: Mutex, +} + +fn main() {} + +fn testing(test: Test) { + let _ = test.comps.inner.try_lock(); +// { dg-error ".E0616." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54094.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54094.rs new file mode 100644 index 000000000000..dbf4bf9301f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54094.rs @@ -0,0 +1,15 @@ +// check-pass +trait Zoo { + type X; +} + +impl Zoo for u16 { + type X = usize; +} + +fn foo(abc: ::X) {} + +fn main() { + let x: *const u8 = foo as _; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54189.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54189.rs new file mode 100644 index 000000000000..2527a5dc6fde --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54189.rs @@ -0,0 +1,7 @@ +fn bug() -> impl for <'r> Fn() -> &'r () { || { &() } } +// { dg-error ".E0582." "" { target *-*-* } .-1 } + +fn main() { + let f = bug(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54302-cases.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54302-cases.rs new file mode 100644 index 000000000000..e7e10b55a268 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54302-cases.rs @@ -0,0 +1,86 @@ +trait Mirror { + type Image; + fn coerce(self) -> Self::Image; +} + +impl Mirror for T { + type Image = T; + fn coerce(self) -> Self { self } +} + +trait Foo<'x, T> { + fn foo(self) -> &'x T; +} + +impl<'s, 'x, T: 'x> Foo<'x, T> for &'s T where &'s T: Foo2<'x, T> { + fn foo(self) -> &'x T { self.foo2() } +} + +trait Foo2<'x, T> { + fn foo2(self) -> &'x T; +} + +// example 1 - fails leak check +impl<'x> Foo2<'x, u32> for &'x u32 +{ + fn foo2(self) -> &'x u32 { self } +} + +// example 2 - OK with this issue +impl<'x, 'a: 'x> Foo2<'x, i32> for &'a i32 +{ + fn foo2(self) -> &'x i32 { self } +} + +// example 3 - fails due to issue #XYZ + Leak-check +impl<'x, T> Foo2<'x, u64> for T + where T: Mirror +{ + fn foo2(self) -> &'x u64 { self.coerce() } +} + +// example 4 - fails due to issue #XYZ +impl<'x, 'a: 'x, T> Foo2<'x, i64> for T + where T: Mirror +{ + fn foo2(self) -> &'x i64 { self.coerce() } +} + + +trait RefFoo { + fn ref_foo(&self) -> &'static T; +} + +impl RefFoo for T where for<'a> &'a T: Foo<'static, T> { + fn ref_foo(&self) -> &'static T { + self.foo() + } +} + + +fn coerce_lifetime1(a: &u32) -> &'static u32 +{ + >::ref_foo(a) +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn coerce_lifetime2(a: &i32) -> &'static i32 +{ + >::ref_foo(a) +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn coerce_lifetime3(a: &u64) -> &'static u64 +{ + >::ref_foo(a) +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn coerce_lifetime4(a: &i64) -> &'static i64 +{ + >::ref_foo(a) +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54302.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54302.rs new file mode 100644 index 000000000000..3c4ce68d4366 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54302.rs @@ -0,0 +1,20 @@ +trait Deserialize<'de> {} + +trait DeserializeOwned: for<'de> Deserialize<'de> {} +impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} + +// Based on this impl, `&'static str` only implements Deserialize<'static>. +// It does not implement for<'de> Deserialize<'de>. +impl<'de: 'a, 'a> Deserialize<'de> for &'a str {} + +fn main() { + // Then why does it implement DeserializeOwned? This compiles. + fn assert_deserialize_owned() {} + assert_deserialize_owned::<&'static str>(); +// { dg-error "" "" { target *-*-* } .-1 } + + // It correctly does not implement for<'de> Deserialize<'de>. + //fn assert_hrtb Deserialize<'de>>() {} + //assert_hrtb::<&'static str>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54348.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54348.rs new file mode 100644 index 000000000000..4702d0bda0d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54348.rs @@ -0,0 +1,8 @@ +// build-fail + +fn main() { + [1][0u64 as usize]; + [1][1.5 as usize]; // { dg-error "" "" { target *-*-* } } + [1][1u64 as usize]; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54387.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54387.rs new file mode 100644 index 000000000000..fe7622d7a1bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54387.rs @@ -0,0 +1,13 @@ +// check-pass + +pub struct GstRc { + _obj: *const (), + _borrowed: bool, +} + +const FOO: Option = None; + +fn main() { + let _meh = FOO; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5439.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5439.rs new file mode 100644 index 000000000000..66c73d2f2ece --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5439.rs @@ -0,0 +1,22 @@ +#![feature(box_syntax)] + +struct Foo { + foo: isize, +} + +struct Bar { + bar: isize, +} + +impl Bar { + fn make_foo (&self, i: isize) -> Box { + return box Foo { nonexistent: self, foo: i }; // { dg-error ".E0560." "" { target *-*-* } } + } +} + +fn main () { + let bar = Bar { bar: 1 }; + let foo = bar.make_foo(2); + println!("{}", foo.foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54410.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54410.rs new file mode 100644 index 000000000000..63d985e76511 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54410.rs @@ -0,0 +1,9 @@ +extern "C" { + pub static mut symbol: [i8]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { + println!("{:p}", unsafe { &symbol }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54462-mutable-noalias-correctness.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54462-mutable-noalias-correctness.rs new file mode 100644 index 000000000000..72dd2b84c51d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54462-mutable-noalias-correctness.rs @@ -0,0 +1,26 @@ +// run-pass +// +// compile-flags: -Ccodegen-units=1 -O + +fn linidx(row: usize, col: usize) -> usize { + row * 1 + col * 3 +} + +fn main() { + let mut mat = [1.0f32, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0]; + + for i in 0..2 { + for j in i+1..3 { + if mat[linidx(j, 3)] > mat[linidx(i, 3)] { + for k in 0..4 { + let (x, rest) = mat.split_at_mut(linidx(i, k) + 1); + let a = x.last_mut().unwrap(); + let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap(); + ::std::mem::swap(a, b); + } + } + } + } + assert_eq!([9.0, 5.0, 1.0, 10.0, 6.0, 2.0, 11.0, 7.0, 3.0, 12.0, 8.0, 4.0], mat); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54467.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54467.rs new file mode 100644 index 000000000000..ff66d51cdcc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54467.rs @@ -0,0 +1,47 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-54477-reduced-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54477-reduced-2.rs new file mode 100644 index 000000000000..c3a581b8fd8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54477-reduced-2.rs @@ -0,0 +1,27 @@ +// run-pass +// rust-lang/rust#54477: runtime bug in the VecDeque library that was +// exposed by this test case, derived from test suite of crates.io +// `collection` crate. + +use std::collections::VecDeque; + +fn main() { + let mut vecdeque_13 = VecDeque::from(vec![ ]); + let mut vecdeque_29 = VecDeque::from(vec![ 0 ]); + vecdeque_29.insert(0, 30 ); + vecdeque_29.insert(1, 31 ); + vecdeque_29.insert(2, 32 ); + vecdeque_29.insert(3, 33 ); + vecdeque_29.insert(4, 34 ); + vecdeque_29.insert(5, 35 ); + // println!("vecdeque_13: {:?}", vecdeque_13); + // println!("vecdeque_29: {:?}", vecdeque_29); + + // println!("Invoking: `vecdeque_13.append(&mut vecdeque_29)`"); + vecdeque_13.append(&mut vecdeque_29); + + // println!("vecdeque_13: {:?}", vecdeque_13); + + assert_eq!(vecdeque_13, VecDeque::from(vec![30, 31, 32, 33, 34, 35, 0])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54521-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54521-1.rs new file mode 100644 index 000000000000..4b4b9fabd325 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54521-1.rs @@ -0,0 +1,17 @@ +// check-pass + +// This test checks that the `remove extra angle brackets` error doesn't happen for some +// potential edge-cases.. + +struct X { + len: u32, +} + +fn main() { + let x = X { len: 3 }; + + let _ = x.len > (3); + + let _ = x.len >> (3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54521-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54521-2.rs new file mode 100644 index 000000000000..47a26d2c5119 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54521-2.rs @@ -0,0 +1,23 @@ +// run-rustfix + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = Vec::>>::new(); +// ^^ help: remove extra angle brackets +// ``` + +fn main() { + let _ = Vec::>>>>::new(); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = Vec::>>>::new(); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = Vec::>>::new(); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = Vec::>::new(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54521.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54521.rs new file mode 100644 index 000000000000..659213c1bd25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54521.rs @@ -0,0 +1,23 @@ +// run-rustfix + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = vec![1, 2, 3].into_iter().collect::>>>(); +// ^^ help: remove extra angle brackets +// ``` + +fn main() { + let _ = vec![1, 2, 3].into_iter().collect::>>>>>(); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = vec![1, 2, 3].into_iter().collect::>>>>(); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = vec![1, 2, 3].into_iter().collect::>>>(); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = vec![1, 2, 3].into_iter().collect::>>(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54582.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54582.rs new file mode 100644 index 000000000000..5ec4656ad275 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54582.rs @@ -0,0 +1,17 @@ +// run-pass + +pub trait Stage: Sync {} + +pub enum Enum { + A, + B, +} + +impl Stage for Enum {} + +pub static ARRAY: [(&dyn Stage, &str); 1] = [ + (&Enum::A, ""), +]; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54696.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54696.rs new file mode 100644 index 000000000000..dc9f28774839 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54696.rs @@ -0,0 +1,9 @@ +// run-pass + +fn main() { + // We shouldn't promote this + &(main as fn() == main as fn()); + // Also check nested case + &(&(main as fn()) == &(main as fn())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54943-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54943-1.rs new file mode 100644 index 000000000000..f242106a4e81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54943-1.rs @@ -0,0 +1,14 @@ +// This test is a minimal version of an ICE in the dropck-eyepatch tests +// found in the fix for #54943. + +// check-pass + +fn foo(_t: T) { +} + +fn main() { + struct A<'a, B: 'a>(&'a B); + let (a1, a2): (String, A<_>) = (String::from("auto"), A(&"this")); + foo((a1, a2)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54943-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54943-2.rs new file mode 100644 index 000000000000..08fea6120ef2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54943-2.rs @@ -0,0 +1,17 @@ +// This test is a minimal version of an ICE in the dropck-eyepatch tests +// found in the fix for #54943. In particular, this test is in unreachable +// code as the initial fix for this ICE only worked if the code was reachable. + +// check-pass + +fn foo(_t: T) { +} + +fn main() { + return; + + struct A<'a, B: 'a>(&'a B); + let (a1, a2): (String, A<_>) = (String::from("auto"), A(&"this")); + foo((a1, a2)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54943-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54943-3.rs new file mode 100644 index 000000000000..4b1942010e63 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54943-3.rs @@ -0,0 +1,21 @@ +// check-pass +// FIXME(#54943) This test targets the scenario where proving the WF requirements requires +// knowing the value of the `_` type present in the user type annotation - unfortunately, figuring +// out the value of that `_` requires type-checking the surrounding code, but that code is dead, +// so our NLL region checker doesn't have access to it. This test should actually fail to compile. + +#![feature(nll)] +#![allow(warnings)] + +use std::fmt::Debug; + +fn foo(_: T) { } + +fn bar<'a>() { + return; + + let _x = foo::>(Vec::<&'a u32>::new()); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54943.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54943.rs new file mode 100644 index 000000000000..3247afa10541 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54943.rs @@ -0,0 +1,11 @@ +fn foo() { } + +fn boo<'a>() { + return; + + let x = foo::<&'a u32>(); +// { dg-error ".E0477." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54954.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54954.rs new file mode 100644 index 000000000000..f6b0b5a2efa6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54954.rs @@ -0,0 +1,20 @@ +#![feature(const_fn)] + +const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); +// { dg-error ".E0283." "" { target *-*-* } .-1 } + +trait Tt { + const fn const_val() -> usize { +// { dg-error ".E0379." "" { target *-*-* } .-1 } + core::mem::size_of::() + } +} + +fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { + z +} + +fn main() { + let _ = f([1f32; ARR_LEN]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-54966.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-54966.rs new file mode 100644 index 000000000000..c73dde898882 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-54966.rs @@ -0,0 +1,7 @@ +// issue-54966: ICE returning an unknown type with impl FnMut + +fn generate_duration() -> Oper {} +// { dg-error ".E0412." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5500-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5500-1.rs new file mode 100644 index 000000000000..72a83858a915 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5500-1.rs @@ -0,0 +1,16 @@ +// MIR doesn't generate an error because the assignment isn't reachable. This +// is OK because the test is here to check that the compiler doesn't ICE (cf. +// #5500). + +// check-pass + +struct TrieMapIterator<'a> { + node: &'a usize +} + +fn main() { + let a = 5; + let _iter = TrieMapIterator{node: &a}; + _iter.node = &panic!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5518.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5518.rs new file mode 100644 index 000000000000..a7846bab126e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5518.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:issue-5518.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_5518 as other; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5521.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5521.rs new file mode 100644 index 000000000000..8ea97bbddbf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5521.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +// aux-build:issue-5521.rs + + + +extern crate issue_5521 as foo; + +fn bar(a: foo::map) { + if false { + panic!(); + } else { + let _b = &(*a)[&2]; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5530.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5530.rs new file mode 100644 index 000000000000..aa273f800ec1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5530.rs @@ -0,0 +1,41 @@ +// run-pass +#![allow(dead_code)] + +enum Enum { + Foo { foo: usize }, + Bar { bar: usize } +} + +fn fun1(e1: &Enum, e2: &Enum) -> usize { + match (e1, e2) { + (&Enum::Foo { foo: _ }, &Enum::Foo { foo: _ }) => 0, + (&Enum::Foo { foo: _ }, &Enum::Bar { bar: _ }) => 1, + (&Enum::Bar { bar: _ }, &Enum::Bar { bar: _ }) => 2, + (&Enum::Bar { bar: _ }, &Enum::Foo { foo: _ }) => 3, + } +} + +fn fun2(e1: &Enum, e2: &Enum) -> usize { + match (e1, e2) { + (&Enum::Foo { foo: _ }, &Enum::Foo { foo: _ }) => 0, + (&Enum::Foo { foo: _ }, _ ) => 1, + (&Enum::Bar { bar: _ }, &Enum::Bar { bar: _ }) => 2, + (&Enum::Bar { bar: _ }, _ ) => 3, + } +} + +pub fn main() { + let foo = Enum::Foo { foo: 1 }; + let bar = Enum::Bar { bar: 1 }; + + assert_eq!(fun1(&foo, &foo), 0); + assert_eq!(fun1(&foo, &bar), 1); + assert_eq!(fun1(&bar, &bar), 2); + assert_eq!(fun1(&bar, &foo), 3); + + assert_eq!(fun2(&foo, &foo), 0); + assert_eq!(fun2(&foo, &bar), 1); // fun2 returns 0 + assert_eq!(fun2(&bar, &bar), 2); + assert_eq!(fun2(&bar, &foo), 3); // fun2 returns 2 +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-55376.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-55376.rs new file mode 100644 index 000000000000..87e952a89f89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-55376.rs @@ -0,0 +1,17 @@ +// run-pass +// Tests that paths in `pub(...)` don't fail HIR verification. + +#![allow(unused_imports)] +#![allow(dead_code)] + +pub(self) use self::my_mod::Foo; + +mod my_mod { + pub(super) use self::Foo as Bar; + pub(in super::my_mod) use self::Foo as Baz; + + pub struct Foo; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-55380.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-55380.rs new file mode 100644 index 000000000000..d009586df275 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-55380.rs @@ -0,0 +1,29 @@ +// run-pass +#![feature(specialization)] +// { dg-warning "" "" { target *-*-* } .-1 } + +pub trait Foo { + fn abc() -> u32; + fn def() -> u32; +} + +pub trait Marker {} + +impl Marker for () {} + +impl Foo for T { + default fn abc() -> u32 { 16 } + default fn def() -> u32 { 42 } +} + +impl Foo for T { + fn def() -> u32 { + Self::abc() + } +} + +fn main() { + assert_eq!(<()>::def(), 16); + assert_eq!(::def(), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5550.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5550.rs new file mode 100644 index 000000000000..c76a3afc1467 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5550.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(unused_assignments)] +// pretty-expanded FIXME #23616 + +pub fn main() { + let s: String = "foobar".to_string(); + let mut t: &str = &s; + t = &t[0..3]; // for master: str::view(t, 0, 3) maybe +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-55511.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-55511.rs new file mode 100644 index 000000000000..b06777c94d14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-55511.rs @@ -0,0 +1,20 @@ +#![warn(indirect_structural_match)] +use std::cell::Cell; +trait Foo<'a> { + const C: Option>; +} + +impl<'a, T> Foo<'a> for T { + const C: Option> = None; +} + +fn main() { + let a = 22; + let b = Some(Cell::new(&a)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + match b { + <() as Foo<'static>>::C => { } + _ => { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5554.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5554.rs new file mode 100644 index 000000000000..91b65c67326c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5554.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +use std::default::Default; + +pub struct X { + a: T, +} + +// reordering these bounds stops the ICE +// +// nmatsakis: This test used to have the bounds Default + PartialEq + +// Default, but having duplicate bounds became illegal. +impl Default for X { + fn default() -> X { + X { a: Default::default() } + } +} + +macro_rules! constants { + () => { + let _ : X = Default::default(); + } +} + +pub fn main() { + constants!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-55587.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-55587.rs new file mode 100644 index 000000000000..a876db95c19a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-55587.rs @@ -0,0 +1,6 @@ +use std::path::Path; + +fn main() { + let Path::new(); // { dg-error ".E0164." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5572.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5572.rs new file mode 100644 index 000000000000..b6619b6d3630 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5572.rs @@ -0,0 +1,8 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn foo(_t: T) { } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-55731.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-55731.rs new file mode 100644 index 000000000000..c1f751511983 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-55731.rs @@ -0,0 +1,53 @@ +use std::marker::PhantomData; + +trait DistributedIterator { + fn reduce(self) + where + Self: Sized, + { + unreachable!() + } +} + +trait DistributedIteratorMulti { + type Item; +} + +struct Connect(PhantomData); +impl DistributedIteratorMulti<&'a ()>> DistributedIterator for Connect where {} + +struct Cloned(PhantomData); +impl<'a, Source> DistributedIteratorMulti<&'a Source> for Cloned<&'a Source> { + type Item = (); +} + +struct Map { + i: I, + f: F, +} +impl, F, Source> DistributedIteratorMulti for Map +where + F: A<>::Item>, +{ + type Item = (); +} + +trait A {} + +struct X; +impl A<()> for X {} + +fn multi(_reducer: I) +where + I: for<'a> DistributedIteratorMulti<&'a ()>, +{ + DistributedIterator::reduce(Connect::(PhantomData)) +} + +fn main() { + multi(Map { // { dg-error "" "" { target *-*-* } } + i: Cloned(PhantomData), + f: X, + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-55796.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-55796.rs new file mode 100644 index 000000000000..77ac2c388785 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-55796.rs @@ -0,0 +1,29 @@ +// ignore-compare-mode-chalk + +pub trait EdgeTrait { + fn target(&self) -> N; +} + +pub trait Graph<'a> { + type Node; + type Edge: EdgeTrait; + type NodesIter: Iterator + 'a; + type EdgesIter: Iterator + 'a; + + fn nodes(&'a self) -> Self::NodesIter; + fn out_edges(&'a self, u: &Self::Node) -> Self::EdgesIter; + fn in_edges(&'a self, u: &Self::Node) -> Self::EdgesIter; + + fn out_neighbors(&'a self, u: &Self::Node) -> Box> { + Box::new(self.out_edges(u).map(|e| e.target())) +// { dg-error ".E0495." "" { target *-*-* } .-1 } + } + + fn in_neighbors(&'a self, u: &Self::Node) -> Box> { + Box::new(self.in_edges(u).map(|e| e.target())) +// { dg-error ".E0495." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-55846.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-55846.rs new file mode 100644 index 000000000000..12856e8b7a11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-55846.rs @@ -0,0 +1,40 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-56031.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56031.rs new file mode 100644 index 000000000000..17a79c492de3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56031.rs @@ -0,0 +1,7 @@ +struct T; + +impl for T {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56128.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56128.rs new file mode 100644 index 000000000000..bbe4e49bf013 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56128.rs @@ -0,0 +1,16 @@ +// Regression test for #56128. When this `pub(super) use...` gets +// exploded in the HIR, we were not handling ids correctly. +// +// check-pass + +mod bar { + pub(super) use self::baz::{x, y}; + + mod baz { + pub fn x() { } + pub fn y() { } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56175.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56175.rs new file mode 100644 index 000000000000..b388fb0a6154 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56175.rs @@ -0,0 +1,10 @@ +// edition:2018 +// aux-crate:reexported_trait=reexported-trait.rs + +fn main() { + reexported_trait::FooStruct.trait_method(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + reexported_trait::FooStruct.trait_method_b(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56199.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56199.rs new file mode 100644 index 000000000000..1a49a7e2556d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56199.rs @@ -0,0 +1,23 @@ +enum Foo {} +struct Bar {} + +impl Foo { + fn foo() { + let _ = Self; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = Self(); +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +impl Bar { + fn bar() { + let _ = Self; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = Self(); +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56202.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56202.rs new file mode 100644 index 000000000000..b38ca0677e6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56202.rs @@ -0,0 +1,18 @@ +// build-pass + +trait FooTrait {} + +trait BarTrait { + fn foo(_: T) -> Self; +} + +struct FooStruct(u32); + +impl BarTrait for FooStruct { + fn foo(_: T) -> Self { + Self(u32::default()) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56229.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56229.rs new file mode 100644 index 000000000000..e8630dd0c4d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56229.rs @@ -0,0 +1,36 @@ +// check-pass + +trait Mirror { + type Other; +} + +#[derive(Debug)] +struct Even(usize); +struct Odd; + +impl Mirror for Even { + type Other = Odd; +} + +impl Mirror for Odd { + type Other = Even; +} + +trait Dyn: AsRef<::Other> {} + +impl Dyn for Even {} + +impl AsRef for Even { + fn as_ref(&self) -> &Even { + self + } +} + +fn code(d: &dyn Dyn) -> &T::Other { + d.as_ref() +} + +fn main() { + println!("{:?}", code(&Even(22))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56237.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56237.rs new file mode 100644 index 000000000000..82e5206b176e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56237.rs @@ -0,0 +1,14 @@ +// run-pass + +use std::ops::Deref; + +fn foo

(_value:

::Target) +where + P: Deref, +

::Target: Sized, +{} + +fn main() { + foo::>(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56411-aux.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56411-aux.rs new file mode 100644 index 000000000000..8575104676bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56411-aux.rs @@ -0,0 +1,6 @@ +// check-pass + +struct T {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56411.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56411.rs new file mode 100644 index 000000000000..01e455b0cbfd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56411.rs @@ -0,0 +1,19 @@ +macro_rules! import { + ( $(($path:expr, $name:ident)),* ) => { + $( + #[path = $path] + mod $name; + pub use self::$name; +// { dg-error ".E0365." "" { target *-*-* } .-1 } +// { dg-error ".E0365." "" { target *-*-* } .-2 } + + )* + } +} + +import!(("issue-56411-aux.rs", issue_56411_aux)); + +fn main() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56488.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56488.rs new file mode 100644 index 000000000000..655fffe3829e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56488.rs @@ -0,0 +1,14 @@ +// run-pass + +#![feature(trait_alias)] + +mod alpha { + pub trait A {} + pub trait C = A; +} + +#[allow(unused_imports)] +use alpha::C; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5666.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5666.rs new file mode 100644 index 000000000000..94e80821b4f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5666.rs @@ -0,0 +1,28 @@ +// run-pass +#![feature(box_syntax)] + +struct Dog { + name : String +} + +trait Barks { + fn bark(&self) -> String; +} + +impl Barks for Dog { + fn bark(&self) -> String { + return format!("woof! (I'm {})", self.name); + } +} + + +pub fn main() { + let snoopy = box Dog{name: "snoopy".to_string()}; + let bubbles = box Dog{name: "bubbles".to_string()}; + let barker = [snoopy as Box, bubbles as Box]; + + for pup in &barker { + println!("{}", pup.bark()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56685.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56685.rs new file mode 100644 index 000000000000..5b99edd7be6b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56685.rs @@ -0,0 +1,45 @@ +#![allow(dead_code)] +#![deny(unused_variables)] + +// This test aims to check that unused variable suggestions update bindings in all +// match arms. + +fn main() { + enum E { + A(i32,), + B(i32,), + } + + match E::A(1) { + E::A(x) | E::B(x) => {} +// { dg-error "" "" { target *-*-* } .-1 } + } + + enum F { + A(i32, i32,), + B(i32, i32,), + C(i32, i32,), + } + + let _ = match F::A(1, 2) { + F::A(x, y) | F::B(x, y) => { y }, +// { dg-error "" "" { target *-*-* } .-1 } + F::C(a, b) => { 3 } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + }; + + let _ = if let F::A(x, y) | F::B(x, y) = F::A(1, 2) { +// { dg-error "" "" { target *-*-* } .-1 } + y + } else { + 3 + }; + + while let F::A(x, y) | F::B(x, y) = F::A(1, 2) { +// { dg-error "" "" { target *-*-* } .-1 } + let _ = y; + break; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56762.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56762.rs new file mode 100644 index 000000000000..e8d64d9b58db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56762.rs @@ -0,0 +1,25 @@ +// only-x86_64 + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +const HUGE_SIZE: usize = !0usize / 8; + + +pub struct TooBigArray { + arr: [u8; HUGE_SIZE], +} + +impl TooBigArray { + pub const fn new() -> Self { + TooBigArray { arr: [0x00; HUGE_SIZE], } + } +} + +static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new(); +// { dg-error ".E0080." "" { target *-*-* } .-1 } +static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE]; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56806.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56806.rs new file mode 100644 index 000000000000..eca9dd10c618 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56806.rs @@ -0,0 +1,7 @@ +pub trait Trait { + fn dyn_instead_of_self(self: Box); +// { dg-error ".E0307." "" { target *-*-* } .-1 } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56835.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56835.rs new file mode 100644 index 000000000000..5a5ee494f497 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56835.rs @@ -0,0 +1,10 @@ +pub struct Foo {} + +impl Foo { + fn bar(Self(foo): Self) {} +// { dg-error ".E0164." "" { target *-*-* } .-1 } +// { dg-error ".E0164." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56870.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56870.rs new file mode 100644 index 000000000000..4d80fed7f803 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56870.rs @@ -0,0 +1,39 @@ +// build-pass +// Regression test for #56870: Internal compiler error (traits & associated consts) + +use std::fmt::Debug; + +pub trait Foo { + const FOO: *const u8; +} + +impl Foo for dyn Debug { + const FOO: *const u8 = ::fmt as *const u8; +} + +pub trait Bar { + const BAR: *const u8; +} + +pub trait Baz { + type Data: Debug; +} + +pub struct BarStruct(S); + +impl Bar for BarStruct { + const BAR: *const u8 = ::Data>>::FOO; +} + +struct AnotherStruct; +#[derive(Debug)] +struct SomeStruct; + +impl Baz for AnotherStruct { + type Data = SomeStruct; +} + +fn main() { + let _x = as Bar>::BAR; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5688.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5688.rs new file mode 100644 index 000000000000..349e9b00e71f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5688.rs @@ -0,0 +1,21 @@ +// run-pass +/* +# Corrupted initialization in the static struct + +...should print &[1, 2, 3] but instead prints something like +&[4492532864, 24]. It is pretty evident that the compiler messed up +with the representation of [isize; n] and [isize] somehow, or at least +failed to typecheck correctly. +*/ + +#[derive(Copy, Clone)] +struct X { vec: &'static [isize] } + +static V: &'static [X] = &[X { vec: &[1, 2, 3] }]; + +pub fn main() { + for &v in V { + println!("{:?}", v.vec); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-56943.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-56943.rs new file mode 100644 index 000000000000..2b3335e931e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-56943.rs @@ -0,0 +1,9 @@ +// aux-build:issue-56943.rs + +extern crate issue_56943; + +fn main() { + let _: issue_56943::S = issue_56943::S2; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5708.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5708.rs new file mode 100644 index 000000000000..27727bb0c8cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5708.rs @@ -0,0 +1,56 @@ +// run-pass +#![allow(unused_variables)] +/* +# ICE when returning struct with reference to trait + +A function which takes a reference to a trait and returns a +struct with that reference results in an ICE. + +This does not occur with concrete types, only with references +to traits. +*/ + + +// original +trait Inner { + fn print(&self); +} + +impl Inner for isize { + fn print(&self) { print!("Inner: {}\n", *self); } +} + +struct Outer<'a> { + inner: &'a (dyn Inner+'a) +} + +impl<'a> Outer<'a> { + fn new(inner: &dyn Inner) -> Outer { + Outer { + inner: inner + } + } +} + +pub fn main() { + let inner: isize = 5; + let outer = Outer::new(&inner as &dyn Inner); + outer.inner.print(); +} + + +// minimal +pub trait MyTrait { + fn dummy(&self, t: T) -> T { panic!() } +} + +pub struct MyContainer<'a, T:'a> { + foos: Vec<&'a (dyn MyTrait+'a)> , +} + +impl<'a, T> MyContainer<'a, T> { + pub fn add (&mut self, foo: &'a dyn MyTrait) { + self.foos.push(foo); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57156.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57156.rs new file mode 100644 index 000000000000..955dd3678a1e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57156.rs @@ -0,0 +1,24 @@ +// check-pass + +trait Foo { + type Output; +} + +trait Bar<'a, T>: for<'s> Foo<&'s T, Output=bool> { + fn cb(&self) -> Box>; +} + +impl<'s> Foo<&'s ()> for () { + type Output = bool; +} + +impl<'a> Bar<'a, ()> for () { + fn cb(&self) -> Box> { + Box::new(*self) + } +} + +fn main() { + let _t = ().cb(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57162.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57162.rs new file mode 100644 index 000000000000..67afbd35886e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57162.rs @@ -0,0 +1,8 @@ +// check-pass + +trait Foo {} +impl Foo for dyn Send {} + +impl Foo for T {} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5718.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5718.rs new file mode 100644 index 000000000000..040b025386c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5718.rs @@ -0,0 +1,27 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +struct Element; + +macro_rules! foo { + ($tag: expr, $string: expr) => { + if $tag == $string { + let element: Box<_> = box Element; + unsafe { + return std::mem::transmute::<_, usize>(element); + } + } + } +} + +fn bar() -> usize { + foo!("a", "b"); + 0 +} + +fn main() { + bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57198-pass.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57198-pass.rs new file mode 100644 index 000000000000..361051fbf331 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57198-pass.rs @@ -0,0 +1,10 @@ +// run-pass + +mod m { + pub fn r#for() {} +} + +fn main() { + m::r#for(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57198.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57198.rs new file mode 100644 index 000000000000..8c4ab037913e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57198.rs @@ -0,0 +1,9 @@ +mod m { + pub fn r#for() {} +} + +fn main() { + m::for(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57271.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57271.rs new file mode 100644 index 000000000000..da9f6c0c5c8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57271.rs @@ -0,0 +1,25 @@ +// aux-build:issue-57271-lib.rs + +extern crate issue_57271_lib; + +use issue_57271_lib::BaseType; + +pub enum ObjectType { // { dg-error ".E0072." "" { target *-*-* } } + Class(ClassTypeSignature), + Array(TypeSignature), + TypeVariable(()), +} + +pub struct ClassTypeSignature { + pub package: (), + pub class: (), + pub inner: (), +} + +pub enum TypeSignature { // { dg-error ".E0072." "" { target *-*-* } } + Base(BaseType), + Object(ObjectType), +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57362-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57362-1.rs new file mode 100644 index 000000000000..2b72f93acf4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57362-1.rs @@ -0,0 +1,24 @@ +// Test for issue #57362, ensuring that the self ty is shown in cases of higher-ranked lifetimes +// conflicts: the `expected` and `found` trait refs would otherwise be printed the same, leading +// to confusing notes such as: +// = note: expected type `Trait` +// found type `Trait` + +// from issue #57362 +trait Trait { + fn f(self); +} + +impl Trait for fn(&T) { + fn f(self) { + println!("f"); + } +} + +fn f() { + let a: fn(_) = |_: &u8| {}; + a.f(); // { dg-error ".E0599." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57362-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57362-2.rs new file mode 100644 index 000000000000..caf262fae683 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57362-2.rs @@ -0,0 +1,26 @@ +// Test for issue #57362, ensuring that the self ty is shown in cases of higher-ranked lifetimes +// conflicts: the `expected` and `found` trait refs would otherwise be printed the same, leading +// to confusing notes such as: +// = note: expected type `Trait` +// found type `Trait` + +// extracted from a similar issue: #57642 +trait X { + type G; + fn make_g() -> Self::G; +} + +impl<'a> X for fn(&'a ()) { + type G = &'a (); + + fn make_g() -> Self::G { + &() + } +} + +fn g() { + let x = ::make_g(); // { dg-error ".E0599." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57399-self-return-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57399-self-return-impl-trait.rs new file mode 100644 index 000000000000..b62151209f0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57399-self-return-impl-trait.rs @@ -0,0 +1,23 @@ +// check-pass + +trait T { + type T; +} + +impl T for i32 { + type T = u32; +} + +struct S { + a: A, +} + + +impl From for S<::T> { + fn from(a: u32) -> Self { + Self { a } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5741.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5741.rs new file mode 100644 index 000000000000..61cdfc3cc768 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5741.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 +#![allow(while_true)] +#![allow(unreachable_code)] + +pub fn main() { + return; + while true {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57410-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57410-1.rs new file mode 100644 index 000000000000..4d88a5c1c11f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57410-1.rs @@ -0,0 +1,19 @@ +// check-pass + +// Originally from #53925. +// Tests that the `unreachable_pub` lint doesn't fire for `pub self::bar::Bar`. + +#![deny(unreachable_pub)] + +mod foo { + mod bar { + pub struct Bar; + } + + pub use self::bar::Bar; +} + +pub use foo::Bar; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57410.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57410.rs new file mode 100644 index 000000000000..08d72f0b244c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57410.rs @@ -0,0 +1,18 @@ +// check-pass + +// Tests that the `unreachable_pub` lint doesn't fire for `pub self::imp::f`. + +#![deny(unreachable_pub)] + +mod m { + mod imp { + pub fn f() {} + } + + pub use self::imp::f; +} + +pub use self::m::f; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57472.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57472.rs new file mode 100644 index 000000000000..fdea425427fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57472.rs @@ -0,0 +1,36 @@ +#![crate_type="lib"] +#![deny(unreachable_patterns)] + +mod test_struct { + // Test the exact copy of the minimal example + // posted in the issue. + pub struct Punned { + foo: [u8; 1], + bar: [u8; 1], + } + + pub fn test(punned: Punned) { + match punned { + Punned { foo: [_], .. } => println!("foo"), + Punned { bar: [_], .. } => println!("bar"), +// { dg-error "" "" { target *-*-* } .-1 } + } + } +} + +mod test_union { + // Test the same thing using a union. + pub union Punned { + foo: [u8; 1], + bar: [u8; 1], + } + + pub fn test(punned: Punned) { + match punned { + Punned { foo: [_] } => println!("foo"), + Punned { bar: [_] } => println!("bar"), +// { dg-error "" "" { target *-*-* } .-1 } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5754.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5754.rs new file mode 100644 index 000000000000..1e28f58d0044 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5754.rs @@ -0,0 +1,17 @@ +// build-pass +#![allow(dead_code)] +#![allow(improper_ctypes)] + +// pretty-expanded FIXME #23616 + +struct TwoDoubles { + r: f64, + i: f64 +} + +extern "C" { + fn rust_dbg_extern_identity_TwoDoubles(arg1: TwoDoubles) -> TwoDoubles; +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57597.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57597.rs new file mode 100644 index 000000000000..27862665f105 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57597.rs @@ -0,0 +1,81 @@ +// Regression test for #57597. +// +// Make sure that nested matchers work correctly rather than causing an infinite loop or crash. + +// edition:2018 + +macro_rules! foo1 { + ($($($i:ident)?)+) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! foo2 { + ($($($i:ident)?)*) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! foo3 { + ($($($i:ident)?)?) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! foo4 { + ($($($($i:ident)?)?)?) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! foo5 { + ($($($($i:ident)*)?)?) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! foo6 { + ($($($($i:ident)?)*)?) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! foo7 { + ($($($($i:ident)?)?)*) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! foo8 { + ($($($($i:ident)*)*)?) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! foo9 { + ($($($($i:ident)?)*)*) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! foo10 { + ($($($($i:ident)?)*)+) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! foo11 { + ($($($($i:ident)+)?)*) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! foo12 { + ($($($($i:ident)+)*)?) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + foo1!(); + foo2!(); + foo3!(); + foo4!(); + foo5!(); + foo6!(); + foo7!(); + foo8!(); + foo9!(); + foo10!(); + foo11!(); + foo12!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57684.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57684.rs new file mode 100644 index 000000000000..a3bf54b47e78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57684.rs @@ -0,0 +1,38 @@ +// run-rustfix + +#![allow(warnings)] + +// This test checks that the following error is emitted when a `=` character is used to initialize +// a struct field when a `:` is expected. +// +// ``` +// error: struct fields are initialized with a colon +// --> $DIR/issue-57684.rs:12:20 +// | +// LL | let _ = X { f1 = 5 }; +// | ^ help: replace equals symbol with a colon: `:` +// ``` + +struct X { + f1: i32, +} + +struct Y { + f1: i32, + f2: i32, + f3: i32, +} + +fn main() { + let _ = X { f1 = 5 }; +// { dg-error "" "" { target *-*-* } .-1 } + + let f3 = 3; + let _ = Y { + f1 = 5, +// { dg-error "" "" { target *-*-* } .-1 } + f2: 4, + f3, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57741-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57741-1.rs new file mode 100644 index 000000000000..0a695ff4fa18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57741-1.rs @@ -0,0 +1,19 @@ +#![allow(warnings)] + +// This tests that the `help: consider dereferencing the boxed value` suggestion isn't made +// because the box doesn't deref to the type of the arm. + +enum S { + A { a: usize }, + B { b: usize }, +} + +fn main() { + let x = Box::new(3u32); + let y = match x { + S::A { a } | S::B { b: a } => a, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57741.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57741.rs new file mode 100644 index 000000000000..0616e7d90406 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57741.rs @@ -0,0 +1,32 @@ +// run-rustfix + +#![allow(warnings)] + +// This tests that the `help: consider dereferencing the boxed value` suggestion is made and works. + +enum S { + A { a: usize }, + B { b: usize }, +} + +enum T { + A(usize), + B(usize), +} + +fn main() { + let x = Box::new(T::A(3)); + let y = match x { + T::A(a) | T::B(a) => a, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + }; + + let x = Box::new(S::A { a: 3 }); + let y = match x { + S::A { a } | S::B { b: a } => a, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57781.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57781.rs new file mode 100644 index 000000000000..53665e170931 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57781.rs @@ -0,0 +1,21 @@ +// run-pass + +use std::cell::UnsafeCell; +use std::collections::HashMap; + +struct OnceCell { + _value: UnsafeCell>, +} + +impl OnceCell { + const INIT: OnceCell = OnceCell { + _value: UnsafeCell::new(None), + }; +} + +pub fn crash() { + let _ = OnceCell::>::INIT; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57819.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57819.rs new file mode 100644 index 000000000000..d0d66151208c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57819.rs @@ -0,0 +1,48 @@ +// run-rustfix + +#![allow(warnings)] + +// This test checks that the following error is emitted and the suggestion works: +// +// ``` +// let _ = vec![1, 2, 3].into_iter().collect::<<>(); +// ^^ help: remove extra angle brackets +// ``` + +trait Foo { + type Output; +} + +fn foo() { + // More complex cases with more than one correct leading `<` character: + + bar::<<<<::Output>(); +// { dg-error "" "" { target *-*-* } .-1 } + + bar::<<<::Output>(); +// { dg-error "" "" { target *-*-* } .-1 } + + bar::<<::Output>(); +// { dg-error "" "" { target *-*-* } .-1 } + + bar::<::Output>(); +} + +fn bar() {} + +fn main() { + let _ = vec![1, 2, 3].into_iter().collect::<<<<>(); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = vec![1, 2, 3].into_iter().collect::<<<>(); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = vec![1, 2, 3].into_iter().collect::<<>(); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = vec![1, 2, 3].into_iter().collect::<>(); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = vec![1, 2, 3].into_iter().collect::>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57843.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57843.rs new file mode 100644 index 000000000000..8c96858d9175 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57843.rs @@ -0,0 +1,25 @@ +// Regression test for an ICE that occurred with the universes code: +// +// The signature of the closure `|_|` was being inferred to +// `exists<'r> fn(&'r u8)`. This should result in a type error since +// the signature `for<'r> fn(&'r u8)` is required. However, due to a +// bug in the type variable generalization code, the placeholder for +// `'r` was leaking out into the writeback phase, causing an ICE. + +trait ClonableFn { + fn clone(&self) -> Box; +} + +impl ClonableFn for F +where F: Fn(T) + Clone { + fn clone(&self) -> Box { + Box::new(self.clone()) + } +} + +struct Foo(Box ClonableFn<&'a bool>>); + +fn main() { + Foo(Box::new(|_| ())); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5791.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5791.rs new file mode 100644 index 000000000000..f783ffd51262 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5791.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +#![warn(clashing_extern_declarations)] +// pretty-expanded FIXME #23616 + +extern { + #[link_name = "malloc"] + fn malloc1(len: i32) -> *const u8; + #[link_name = "malloc"] +// { dg-warning "" "" { target *-*-* } .-1 } + fn malloc2(len: i32, foo: i32) -> *const u8; +} + +pub fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-57924.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-57924.rs new file mode 100644 index 000000000000..4155e14a5037 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-57924.rs @@ -0,0 +1,11 @@ +pub struct Gcm(E); + +impl Gcm { + pub fn crash(e: E) -> Self { + Self::(e) +// { dg-error ".E0109." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-58022.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-58022.rs new file mode 100644 index 000000000000..b9c055a548d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-58022.rs @@ -0,0 +1,20 @@ +pub trait Foo: Sized { + const SIZE: usize; + + fn new(slice: &[u8; Foo::SIZE]) -> Self; +// { dg-error ".E0283." "" { target *-*-* } .-1 } +} + +pub struct Bar(T); + +impl Bar<[u8]> { + const SIZE: usize = 32; + + fn new(slice: &[u8; Self::SIZE]) -> Self { + Foo(Box::new(*slice)) +// { dg-error ".E0423." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-58212.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-58212.rs new file mode 100644 index 000000000000..0b8cdf272530 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-58212.rs @@ -0,0 +1,16 @@ +// check-pass + +trait FromUnchecked { + fn from_unchecked(); +} + +impl FromUnchecked for [u8; 1] { + fn from_unchecked() { + let mut array: Self = [0; 1]; + let _ptr = &mut array as *mut [u8] as *mut u8; + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-58319.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-58319.rs new file mode 100644 index 000000000000..6d5067fe279a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-58319.rs @@ -0,0 +1,622 @@ +// run-pass +fn main() {} +#[derive(Clone)] +pub struct Little; +#[derive(Clone)] +pub struct Big( + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, + Little, +); + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-58344.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-58344.rs new file mode 100644 index 000000000000..9f32fc5654a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-58344.rs @@ -0,0 +1,51 @@ +// check-pass + +use std::ops::Add; + +trait Trait { + fn get(self) -> T; +} + +struct Holder(T); + +impl Trait for Holder { + fn get(self) -> T { + self.0 + } +} + +enum Either { + Left(L), + Right(R), +} + +impl Either { + fn converge(self) -> T + where + L: Trait, + R: Trait, + { + match self { + Either::Left(val) => val.get(), + Either::Right(val) => val.get(), + } + } +} + +fn add_generic, B>( + lhs: A, + rhs: B, +) -> Either>::Output>, impl Trait<>::Output>> { + if true { Either::Left(Holder(lhs + rhs)) } else { Either::Right(Holder(lhs + rhs)) } +} + +fn add_one( + value: u32, +) -> Either>::Output>, impl Trait<>::Output>> { + add_generic(value, 1u32) +} + +pub fn main() { + add_one(3).converge(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-58375-monomorphize-default-impls.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-58375-monomorphize-default-impls.rs new file mode 100644 index 000000000000..820df4810ad6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-58375-monomorphize-default-impls.rs @@ -0,0 +1,25 @@ +// Make sure that the mono-item collector does not crash when trying to +// instantiate a default impl for DecodeUtf16<::Item> +// See https://github.com/rust-lang/rust/issues/58375 + +// build-pass +// compile-flags:-C link-dead-code + +#![crate_type = "rlib"] + +pub struct DecodeUtf16(I); + +pub trait Arbitrary { + fn arbitrary() {} +} + +pub trait A { + type Item; +} + +impl A for u8 { + type Item = char; +} + +impl Arbitrary for DecodeUtf16<::Item> {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-58435-ice-with-assoc-const.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-58435-ice-with-assoc-const.rs new file mode 100644 index 000000000000..182cd1afff22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-58435-ice-with-assoc-const.rs @@ -0,0 +1,19 @@ +// run-pass +// The const-evaluator was at one point ICE'ing while trying to +// evaluate the body of `fn id` during the `s.id()` call in main. + +struct S(T); + +impl S { + const ID: fn(&S) -> &S = |s| s; + pub fn id(&self) -> &Self { + Self::ID(self) // This, plus call below ... + } +} + +fn main() { + let s = S(10u32); + assert!(S::::ID(&s).0 == 10); // Works fine + assert!(s.id().0 == 10); // ... causes compiler to panic +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5844.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5844.rs new file mode 100644 index 000000000000..fd91fbd06e6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5844.rs @@ -0,0 +1,8 @@ +//aux-build:issue-5844-aux.rs + +extern crate issue_5844_aux; + +fn main () { + issue_5844_aux::rand(); // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-58463.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-58463.rs new file mode 100644 index 000000000000..e4d0f4e40fae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-58463.rs @@ -0,0 +1,11 @@ +// run-pass +// compile-flags:-C debuginfo=2 +// ignore-asmjs wasm2js does not support source maps yet + +fn foo() -> impl Copy { + foo +} +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-58712.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-58712.rs new file mode 100644 index 000000000000..344ccc82a230 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-58712.rs @@ -0,0 +1,15 @@ +struct AddrVec { + h: H, + a: A, +} + +impl AddrVec { +// { dg-error ".E0412." "" { target *-*-* } .-1 } + pub fn device(&self) -> DeviceId { +// { dg-error ".E0412." "" { target *-*-* } .-1 } + self.tail() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-58734.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-58734.rs new file mode 100644 index 000000000000..ed4e0e04f912 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-58734.rs @@ -0,0 +1,23 @@ +trait Trait { + fn exists(self) -> (); + + fn not_object_safe() -> Self; +} + +impl Trait for () { + fn exists(self) -> () { + } + + fn not_object_safe() -> Self { + () + } +} + +fn main() { + // object-safe or not, this call is OK + Trait::exists(()); + // no object safety error + Trait::nonexistent(()); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5883.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5883.rs new file mode 100644 index 000000000000..dc8c755a702b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5883.rs @@ -0,0 +1,14 @@ +trait A {} + +struct Struct { + r: dyn A + 'static +} + +fn new_struct(r: dyn A + 'static) +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + Struct { r: r } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5884.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5884.rs new file mode 100644 index 000000000000..eb71b77ed2a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5884.rs @@ -0,0 +1,21 @@ +// build-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub struct Foo { + a: isize, +} + +struct Bar<'a> { + a: Box>, + b: &'a Foo, +} + +fn check(a: Box) { + let _ic = Bar{ b: &*a, a: box None }; +} + +pub fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-58856-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-58856-1.rs new file mode 100644 index 000000000000..e96c664872da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-58856-1.rs @@ -0,0 +1,9 @@ +impl A { +// { dg-error ".E0412." "" { target *-*-* } .-1 } + fn b(self> +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-58856-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-58856-2.rs new file mode 100644 index 000000000000..30458e827530 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-58856-2.rs @@ -0,0 +1,15 @@ +struct Empty; + +trait Howness {} + +impl Howness for () { + fn how_are_you(&self -> Empty { +// { dg-error ".E0407." "" { target *-*-* } .-1 } +// { dg-error ".E0407." "" { target *-*-* } .-2 } + Empty + } +} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-58857.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-58857.rs new file mode 100644 index 000000000000..a7caa45ee06c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-58857.rs @@ -0,0 +1,8 @@ +struct Conj {a : A} +trait Valid {} + +impl Conj{} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5900.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5900.rs new file mode 100644 index 000000000000..f8df482a28be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5900.rs @@ -0,0 +1,16 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +pub mod foo { + use super::Bar; + + pub struct FooStruct { bar : Bar } +} + +pub enum Bar { + Bar0 = 0 as isize +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-59020.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-59020.rs new file mode 100644 index 000000000000..6f6fb4c6f2f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-59020.rs @@ -0,0 +1,28 @@ +// edition:2018 +// run-pass +// ignore-emscripten no threads support + +use std::thread; +use std::time::Duration; + +fn main() { + let t1 = thread::spawn(|| { + let sleep = Duration::new(0,100_000); + for _ in 0..100 { + println!("Parking1"); + thread::park_timeout(sleep); + } + }); + + let t2 = thread::spawn(|| { + let sleep = Duration::new(0,100_000); + for _ in 0..100 { + println!("Parking2"); + thread::park_timeout(sleep); + } + }); + + t1.join().expect("Couldn't join thread 1"); + t2.join().expect("Couldn't join thread 2"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-59029-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-59029-1.rs new file mode 100644 index 000000000000..39cdf50d1e89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-59029-1.rs @@ -0,0 +1,10 @@ +#![feature(trait_alias)] + +trait Svc { type Res; } + +trait MkSvc = Svc where Self::Res: Svc; +// { dg-error ".E0220." "" { target *-*-* } .-1 } +// { dg-error ".E0220." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-59029-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-59029-2.rs new file mode 100644 index 000000000000..8415aaec9f90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-59029-2.rs @@ -0,0 +1,9 @@ +// run-pass +#![feature(trait_alias)] + +trait Svc { type Res; } + +trait MkSvc = Svc where >::Res: Svc; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5917.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5917.rs new file mode 100644 index 000000000000..f5f2d1a2639b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5917.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(non_upper_case_globals)] + +struct T (&'static [isize]); +static t : T = T (&[5, 4, 3]); +pub fn main () { + let T(ref v) = t; + assert_eq!(v[0], 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5927.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5927.rs new file mode 100644 index 000000000000..97b235fe1199 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5927.rs @@ -0,0 +1,8 @@ +fn main() { + let z = match 3 { + x(1) => x(1) // { dg-error ".E0425." "" { target *-*-* } } +// { dg-error ".E0425." "" { target *-*-* } .-1 } + }; + assert!(z == 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-59326.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-59326.rs new file mode 100644 index 000000000000..828897a96e17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-59326.rs @@ -0,0 +1,27 @@ +// check-pass +trait Service { + type S; +} + +trait Framing { + type F; +} + +impl Framing for () { + type F = (); +} + +trait HttpService: Service {} + +type BoxService = Box>; + +fn build_server BoxService>(_: F) {} + +fn make_server() -> Box> { + unimplemented!() +} + +fn main() { + build_server(|| make_server()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-59488.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-59488.rs new file mode 100644 index 000000000000..2af15ae76f22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-59488.rs @@ -0,0 +1,35 @@ +fn foo() -> i32 { + 42 +} + +fn bar(a: i64) -> i64 { + 43 +} + +enum Foo { + Bar(usize), +} + +fn main() { + foo > 12; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + bar > 13; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + foo > foo; +// { dg-error ".E0369." "" { target *-*-* } .-1 } + + foo > bar; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + let i = Foo::Bar; + assert_eq!(Foo::Bar, i); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-59494.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-59494.rs new file mode 100644 index 000000000000..ecc2480962f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-59494.rs @@ -0,0 +1,24 @@ +fn t7p(f: impl Fn(B) -> C, g: impl Fn(A) -> B) -> impl Fn(A) -> C { + move |a: A| -> C { f(g(a)) } +} + +fn t8n(f: impl Fn(A) -> B, g: impl Fn(A) -> C) -> impl Fn(A) -> (B, C) +where + A: Copy, +{ + move |a: A| -> (B, C) { + let b = a; + let fa = f(a); + let ga = g(b); + (fa, ga) + } +} + +fn main() { + let f = |(_, _)| {}; + let g = |(a, _)| a; + let t7 = |env| |a| |b| t7p(f, g)(((env, a), b)); + let t8 = t8n(t7, t7p(f, g)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5950.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5950.rs new file mode 100644 index 000000000000..b44261d9ee14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5950.rs @@ -0,0 +1,10 @@ +// check-pass + +// pretty-expanded FIXME #23616 + +pub use local as local_alias; + +pub mod local { } + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-59508-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-59508-1.rs new file mode 100644 index 000000000000..784e78f0f085 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-59508-1.rs @@ -0,0 +1,19 @@ +#![allow(dead_code)] +#![feature(const_generics)] +// { dg-warning "" "" { target *-*-* } .-1 } + +// This test checks that generic parameter re-ordering diagnostic suggestions mention that +// consts come after types and lifetimes when the `const_generics` feature is enabled. +// We cannot run rustfix on this test because of the above const generics warning. + +struct A; + +impl A { + pub fn do_things() { +// { dg-error "" "" { target *-*-* } .-1 } + println!("panic"); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-59508.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-59508.rs new file mode 100644 index 000000000000..120d5aa74a35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-59508.rs @@ -0,0 +1,17 @@ +// run-rustfix + +#![allow(dead_code)] + +// This test checks that generic parameter re-ordering diagnostic suggestions contain bounds. + +struct A; + +impl A { + pub fn do_things() { +// { dg-error "" "" { target *-*-* } .-1 } + println!("panic"); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-59756.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-59756.rs new file mode 100644 index 000000000000..32d02471f420 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-59756.rs @@ -0,0 +1,22 @@ +// run-rustfix +// ignore-test +// +// FIXME: Re-enable this test once we support choosing +// between multiple mutually exclusive suggestions for the same span + +#![allow(warnings)] + +struct A; +struct B; + +fn foo() -> Result { + Ok(A) +} + +fn bar() -> Result { + foo()? +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-59764.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-59764.rs new file mode 100644 index 000000000000..4150e0c78077 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-59764.rs @@ -0,0 +1,137 @@ +// aux-build:issue-59764.rs +// compile-flags:--extern issue_59764 +// edition:2018 + +#![allow(warnings)] + +// This tests the suggestion to import macros from the root of a crate. This aims to capture +// the case where a user attempts to import a macro from the definition location instead of the +// root of the crate and the macro is annotated with `#![macro_export]`. + +// Edge cases.. + +mod multiple_imports_same_line_at_end { + use issue_59764::foo::{baz, makro}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +} + +mod multiple_imports_multiline_at_end_trailing_comma { + use issue_59764::foo::{ + baz, + makro, // { dg-error ".E0432." "" { target *-*-* } } + }; +} + +mod multiple_imports_multiline_at_end { + use issue_59764::foo::{ + baz, + makro // { dg-error ".E0432." "" { target *-*-* } } + }; +} + +mod multiple_imports_same_line_in_middle { + use issue_59764::foo::{baz, makro, foobar}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +} + +mod multiple_imports_multiline_in_middle_trailing_comma { + use issue_59764::foo::{ + baz, + makro, // { dg-error ".E0432." "" { target *-*-* } } + foobar, + }; +} + +mod multiple_imports_multiline_in_middle { + use issue_59764::foo::{ + baz, + makro, // { dg-error ".E0432." "" { target *-*-* } } + foobar + }; +} + +mod nested_imports { + use issue_59764::{foobaz, foo::makro}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +} + +mod nested_multiple_imports { + use issue_59764::{foobaz, foo::{baz, makro}}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +} + +mod nested_multiline_multiple_imports_trailing_comma { + use issue_59764::{ + foobaz, + foo::{ + baz, + makro, // { dg-error ".E0432." "" { target *-*-* } } + }, + }; +} + +mod nested_multiline_multiple_imports { + use issue_59764::{ + foobaz, + foo::{ + baz, + makro // { dg-error ".E0432." "" { target *-*-* } } + } + }; +} + +mod doubly_nested_multiple_imports { + use issue_59764::{foobaz, foo::{baz, makro, barbaz::{barfoo}}}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +} + +mod doubly_multiline_nested_multiple_imports { + use issue_59764::{ + foobaz, + foo::{ + baz, + makro, // { dg-error ".E0432." "" { target *-*-* } } + barbaz::{ + barfoo, + } + } + }; +} + +mod renamed_import { + use issue_59764::foo::makro as baz; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +} + +mod renamed_multiple_imports { + use issue_59764::foo::{baz, makro as foobar}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +} + +mod lots_of_whitespace { + use + issue_59764::{ + + foobaz, + + + foo::{baz, + + makro as foobar} // { dg-error ".E0432." "" { target *-*-* } } + + }; +} + +// Simple case.. + +use issue_59764::foo::makro; +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +makro!(bar); +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + bar(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5988.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5988.rs new file mode 100644 index 000000000000..3f3637f15b2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5988.rs @@ -0,0 +1,25 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait B { + fn f(&self); +} + +trait T : B { +} + +struct A; + +impl B for U { + fn f(&self) { } +} + +impl T for A { +} + +fn main() { + let a = A; + let br = &a as &dyn B; + br.f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-59896.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-59896.rs new file mode 100644 index 000000000000..ddfddb6f0b2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-59896.rs @@ -0,0 +1,10 @@ +#![deny(unused_imports)] + +struct S; + +fn main() { + use S; // { dg-error "" "" { target *-*-* } } + + let _s = S; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5997-enum.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5997-enum.rs new file mode 100644 index 000000000000..f50bd0b72433 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5997-enum.rs @@ -0,0 +1,11 @@ +fn f() -> bool { + enum E { V(Z) } +// { dg-error ".E0401." "" { target *-*-* } .-1 } + true +} + +fn main() { + let b = f::(); + assert!(b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5997-struct.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5997-struct.rs new file mode 100644 index 000000000000..6fe07463b502 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5997-struct.rs @@ -0,0 +1,11 @@ +fn f() -> bool { + struct S(T); // { dg-error ".E0401." "" { target *-*-* } } + + true +} + +fn main() { + let b = f::(); + assert!(b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-5997.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-5997.rs new file mode 100644 index 000000000000..a4dd86754fda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-5997.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] + +fn f() -> bool { + enum E { V(T) } + + struct S(T); + + true +} + +fn main() { + let b = f::(); + assert!(b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-60057.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-60057.rs new file mode 100644 index 000000000000..c650a3187355 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-60057.rs @@ -0,0 +1,20 @@ +struct A { + banana: u8, +} + +impl A { + fn new(peach: u8) -> A { + A { + banana: banana // { dg-error ".E0425." "" { target *-*-* } } + } + } + + fn foo(&self, peach: u8) -> A { + A { + banana: banana // { dg-error ".E0425." "" { target *-*-* } } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-60075.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-60075.rs new file mode 100644 index 000000000000..ca750a9eaeea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-60075.rs @@ -0,0 +1,12 @@ +fn main() {} + +trait T { + fn qux() -> Option { + let _ = if true { + }); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + Some(4) + } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-60218.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-60218.rs new file mode 100644 index 000000000000..54d12f0c8a0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-60218.rs @@ -0,0 +1,20 @@ +// Regression test for #60218 +// +// This was reported to cause ICEs. + +use std::iter::Map; + +pub trait Foo {} + +pub fn trigger_error(iterable: I, functor: F) +where + for<'t> &'t I: IntoIterator, +for<'t> Map<<&'t I as IntoIterator>::IntoIter, F>: Iterator, +for<'t> ::IntoIter, F> as Iterator>::Item: Foo, +{ +} + +fn main() { + trigger_error(vec![], |x: &u32| x) // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-60283.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-60283.rs new file mode 100644 index 000000000000..3de51e945084 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-60283.rs @@ -0,0 +1,21 @@ +pub trait Trait<'a> { + type Item; +} + +impl<'a> Trait<'a> for () { + type Item = (); +} + +pub fn foo(_: T, _: F) +where + T: for<'a> Trait<'a>, + F: for<'a> FnMut(>::Item), +{ +} + +fn main() { + foo((), drop) +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-60622.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-60622.rs new file mode 100644 index 000000000000..90779e3e98d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-60622.rs @@ -0,0 +1,19 @@ +// ignore-tidy-linelength + +#![deny(warnings)] + +struct Borked {} + +impl Borked { + fn a(&self) {} +} + +fn run_wild(b: &Borked) { + b.a::<'_, T>(); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +// { dg-warning ".E0107." "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-60662.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-60662.rs new file mode 100644 index 000000000000..44862b23022d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-60662.rs @@ -0,0 +1,12 @@ +// check-pass +// compile-flags: -Z unpretty=hir + +#![feature(type_alias_impl_trait)] + +trait Animal { +} + +fn main() { + pub type ServeFut = impl Animal; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-60989.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-60989.rs new file mode 100644 index 000000000000..d7c5e8953646 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-60989.rs @@ -0,0 +1,19 @@ +struct A {} +struct B {} + +impl From for B { + fn from(a: A) -> B { + B{} + } +} + +fn main() { + let c1 = (); + c1::<()>; +// { dg-error ".E0109." "" { target *-*-* } .-1 } + + let c1 = A {}; + c1::>; +// { dg-error ".E0109." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-61106.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-61106.rs new file mode 100644 index 000000000000..deb4026d0215 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-61106.rs @@ -0,0 +1,7 @@ +fn main() { + let x = String::new(); + foo(x.clone()); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn foo(_: &str) {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-61108.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-61108.rs new file mode 100644 index 000000000000..71e5094b3ab9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-61108.rs @@ -0,0 +1,8 @@ +fn main() { + let mut bad_letters = vec!['e', 't', 'o', 'i']; + for l in bad_letters { + // something here + } + bad_letters.push('s'); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6117.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6117.rs new file mode 100644 index 000000000000..167577717b76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6117.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +enum Either { Left(T), Right(U) } + +pub fn main() { + match Either::Left(Box::new(17)) { + Either::Right(()) => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6128.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6128.rs new file mode 100644 index 000000000000..364167d43e72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6128.rs @@ -0,0 +1,25 @@ +// run-pass + +#![feature(box_syntax)] + +use std::collections::HashMap; + +trait Graph { + fn f(&self, _: Edge); + fn g(&self, _: Node); +} + +impl Graph for HashMap { + fn f(&self, _e: E) { + panic!(); + } + fn g(&self, _e: isize) { + panic!(); + } +} + +pub fn main() { + let g : Box> = box HashMap::new(); + let _g2 : Box> = g as Box>; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6130.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6130.rs new file mode 100644 index 000000000000..5649c1452922 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6130.rs @@ -0,0 +1,11 @@ +// run-pass + +pub fn main() { + let i: usize = 0; + assert!(i <= 0xFFFF_FFFF); + + let i: isize = 0; + assert!(i >= -0x8000_0000); + assert!(i <= 0x7FFF_FFFF); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-61475.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-61475.rs new file mode 100644 index 000000000000..361fbe175811 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-61475.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] + +enum E { + A, B +} + +fn main() { + match &&E::A { + &&E::A => { + } + &&E::B => { + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6153.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6153.rs new file mode 100644 index 000000000000..a3ce576df820 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6153.rs @@ -0,0 +1,14 @@ +// run-pass + + +fn swap(f: F) -> Vec where F: FnOnce(Vec) -> Vec { + let x = vec![1, 2, 3]; + f(x) +} + +pub fn main() { + let v = swap(|mut x| { x.push(4); x }); + let w = swap(|mut x| { x.push(4); x }); + assert_eq!(v, w); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6157.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6157.rs new file mode 100644 index 000000000000..0158b4344929 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6157.rs @@ -0,0 +1,24 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub trait OpInt { fn call(&mut self, _: isize, _: isize) -> isize; } + +impl OpInt for F where F: FnMut(isize, isize) -> isize { + fn call(&mut self, a:isize, b:isize) -> isize { + (*self)(a, b) + } +} + +fn squarei<'a>(x: isize, op: &'a mut dyn OpInt) -> isize { op.call(x, x) } + +fn muli(x:isize, y:isize) -> isize { x * y } + +pub fn main() { + let mut f = |x, y| muli(x, y); + { + let g = &mut f; + let h = g as &mut dyn OpInt; + squarei(3, h); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-61623.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-61623.rs new file mode 100644 index 000000000000..4888b7c4c813 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-61623.rs @@ -0,0 +1,12 @@ +fn f1<'a>(_: &'a mut ()) {} + +fn f2

(_: P, _: ()) {} + +fn f3<'a>(x: &'a ((), &'a mut ())) { + f2(|| x.0, f1(x.1)) +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-61696.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-61696.rs new file mode 100644 index 000000000000..8cf2a70566b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-61696.rs @@ -0,0 +1,67 @@ +// run-pass + +pub enum Infallible {} + +// The check that the `bool` field of `V1` is encoding a "niche variant" +// (i.e. not `V1`, so `V3` or `V4`) used to be mathematically incorrect, +// causing valid `V1` values to be interpreted as other variants. +pub enum E1 { + V1 { f: bool }, + V2 { f: Infallible }, + V3, + V4, +} + +// Computing the discriminant used to be done using the niche type (here `u8`, +// from the `bool` field of `V1`), overflowing for variants with large enough +// indices (`V3` and `V4`), causing them to be interpreted as other variants. +pub enum E2 { + V1 { f: bool }, + + /*_00*/ _01(X), _02(X), _03(X), _04(X), _05(X), _06(X), _07(X), + _08(X), _09(X), _0A(X), _0B(X), _0C(X), _0D(X), _0E(X), _0F(X), + _10(X), _11(X), _12(X), _13(X), _14(X), _15(X), _16(X), _17(X), + _18(X), _19(X), _1A(X), _1B(X), _1C(X), _1D(X), _1E(X), _1F(X), + _20(X), _21(X), _22(X), _23(X), _24(X), _25(X), _26(X), _27(X), + _28(X), _29(X), _2A(X), _2B(X), _2C(X), _2D(X), _2E(X), _2F(X), + _30(X), _31(X), _32(X), _33(X), _34(X), _35(X), _36(X), _37(X), + _38(X), _39(X), _3A(X), _3B(X), _3C(X), _3D(X), _3E(X), _3F(X), + _40(X), _41(X), _42(X), _43(X), _44(X), _45(X), _46(X), _47(X), + _48(X), _49(X), _4A(X), _4B(X), _4C(X), _4D(X), _4E(X), _4F(X), + _50(X), _51(X), _52(X), _53(X), _54(X), _55(X), _56(X), _57(X), + _58(X), _59(X), _5A(X), _5B(X), _5C(X), _5D(X), _5E(X), _5F(X), + _60(X), _61(X), _62(X), _63(X), _64(X), _65(X), _66(X), _67(X), + _68(X), _69(X), _6A(X), _6B(X), _6C(X), _6D(X), _6E(X), _6F(X), + _70(X), _71(X), _72(X), _73(X), _74(X), _75(X), _76(X), _77(X), + _78(X), _79(X), _7A(X), _7B(X), _7C(X), _7D(X), _7E(X), _7F(X), + _80(X), _81(X), _82(X), _83(X), _84(X), _85(X), _86(X), _87(X), + _88(X), _89(X), _8A(X), _8B(X), _8C(X), _8D(X), _8E(X), _8F(X), + _90(X), _91(X), _92(X), _93(X), _94(X), _95(X), _96(X), _97(X), + _98(X), _99(X), _9A(X), _9B(X), _9C(X), _9D(X), _9E(X), _9F(X), + _A0(X), _A1(X), _A2(X), _A3(X), _A4(X), _A5(X), _A6(X), _A7(X), + _A8(X), _A9(X), _AA(X), _AB(X), _AC(X), _AD(X), _AE(X), _AF(X), + _B0(X), _B1(X), _B2(X), _B3(X), _B4(X), _B5(X), _B6(X), _B7(X), + _B8(X), _B9(X), _BA(X), _BB(X), _BC(X), _BD(X), _BE(X), _BF(X), + _C0(X), _C1(X), _C2(X), _C3(X), _C4(X), _C5(X), _C6(X), _C7(X), + _C8(X), _C9(X), _CA(X), _CB(X), _CC(X), _CD(X), _CE(X), _CF(X), + _D0(X), _D1(X), _D2(X), _D3(X), _D4(X), _D5(X), _D6(X), _D7(X), + _D8(X), _D9(X), _DA(X), _DB(X), _DC(X), _DD(X), _DE(X), _DF(X), + _E0(X), _E1(X), _E2(X), _E3(X), _E4(X), _E5(X), _E6(X), _E7(X), + _E8(X), _E9(X), _EA(X), _EB(X), _EC(X), _ED(X), _EE(X), _EF(X), + _F0(X), _F1(X), _F2(X), _F3(X), _F4(X), _F5(X), _F6(X), _F7(X), + _F8(X), _F9(X), _FA(X), _FB(X), _FC(X), _FD(X), _FE(X), _FF(X), + + V3, + V4, +} + +fn main() { + if let E1::V2 { .. } = (E1::V1 { f: true }) { + unreachable!() + } + + if let E2::V1 { .. } = E2::V3:: { + unreachable!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs new file mode 100644 index 000000000000..ab33897b1fdf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs @@ -0,0 +1,12 @@ +// Issue 61711: A crate pub re-exporting `crate` was causing an +// infinite loop. + +// edition:2018 +// aux-build:xcrate-issue-61711-b.rs +// compile-flags:--extern xcrate_issue_61711_b + +// build-pass + +fn f(_: F) { } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-61858.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-61858.rs new file mode 100644 index 000000000000..e3467365d568 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-61858.rs @@ -0,0 +1,4 @@ +fn main() { + (if foobar) // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-61882-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-61882-2.rs new file mode 100644 index 000000000000..818c980b2eef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-61882-2.rs @@ -0,0 +1,12 @@ +struct A(T); + +impl A<&'static u8> { + fn f() { + let x = 0; + Self(&x); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-61882.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-61882.rs new file mode 100644 index 000000000000..fb6bc6a74a84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-61882.rs @@ -0,0 +1,10 @@ +struct A(T); + +impl A { + const B: A = Self(0); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-61894.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-61894.rs new file mode 100644 index 000000000000..3ee2bb8262b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-61894.rs @@ -0,0 +1,22 @@ +// run-pass + +#![feature(core_intrinsics)] + +use std::any::type_name; + +struct Bar(M); + +impl Bar { + fn foo(&self) -> &'static str { + fn f() {} + fn type_name_of(_: T) -> &'static str { + type_name::() + } + type_name_of(f) + } +} + +fn main() { + assert_eq!(Bar(()).foo(), "issue_61894::Bar<_>::foo::f"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-62375.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-62375.rs new file mode 100644 index 000000000000..88218a01c4e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-62375.rs @@ -0,0 +1,10 @@ +enum A { + Value(()) +} + +fn main() { + let a = A::Value(()); + a == A::Value; +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-62480.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-62480.rs new file mode 100644 index 000000000000..f5545bf7053f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-62480.rs @@ -0,0 +1,13 @@ +#![feature(label_break_value)] + +fn main() { + // This used to ICE during liveness check because `target_id` passed to + // `propagate_through_expr` would be the closure and not the `loop`, which wouldn't be found in + // `self.break_ln`. (#62480) + 'a: { + || break 'a +// { dg-error ".E0267." "" { target *-*-* } .-1 } +// { dg-error ".E0267." "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-62554.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-62554.rs new file mode 100644 index 000000000000..dec00f7ea4f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-62554.rs @@ -0,0 +1,7 @@ +// error-pattern:this file contains an unclosed delimiter +// error-pattern:xpected `{`, found `macro_rules` + +fn main() {} + +fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6318.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6318.rs new file mode 100644 index 000000000000..71096ba65eb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6318.rs @@ -0,0 +1,23 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub enum Thing { + A(Box) +} + +pub trait Foo { + fn dummy(&self) { } +} + +pub struct Struct; + +impl Foo for Struct {} + +pub fn main() { + match Thing::A(box Struct as Box) { + Thing::A(_a) => 0, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6334.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6334.rs new file mode 100644 index 000000000000..ccdca7221424 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6334.rs @@ -0,0 +1,47 @@ +// run-pass +// Tests that everything still compiles and runs fine even when +// we reorder the bounds. + + +trait A { + fn a(&self) -> usize; +} + +trait B { + fn b(&self) -> usize; +} + +trait C { + fn combine(&self, t: &T) -> usize; +} + +struct Foo; + +impl A for Foo { + fn a(&self) -> usize { 1 } +} + +impl B for Foo { + fn b(&self) -> usize { 2 } +} + +struct Bar; + +impl C for Bar { + // Note below: bounds in impl decl are in reverse order. + fn combine(&self, t: &T) -> usize { + (t.a() * 100) + t.b() + } +} + +fn use_c(s: &S, t: &T) -> usize { + s.combine(t) +} + +pub fn main() { + let foo = Foo; + let bar = Bar; + let r = use_c(&bar, &foo); + assert_eq!(r, 102); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-63364.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-63364.rs new file mode 100644 index 000000000000..65a333a79864 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-63364.rs @@ -0,0 +1,11 @@ +fn part(_: u16) -> u32 { + 1 +} + +fn main() { + for n in 100_000.. { +// { dg-error "" "" { target *-*-* } .-1 } + let _ = part(n); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6341.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6341.rs new file mode 100644 index 000000000000..0582b289254a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6341.rs @@ -0,0 +1,12 @@ +// check-pass +// pretty-expanded FIXME #23616 + +#[derive(PartialEq)] +struct A { x: usize } + +impl Drop for A { + fn drop(&mut self) {} +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6344-let.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6344-let.rs new file mode 100644 index 000000000000..7377e600c4e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6344-let.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(non_shorthand_field_patterns)] + +struct A { x: usize } + +impl Drop for A { + fn drop(&mut self) {} +} + +pub fn main() { + let a = A { x: 0 }; + + let A { x: ref x } = a; + println!("{}", x) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6344-match.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6344-match.rs new file mode 100644 index 000000000000..62d24cc30890 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6344-match.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(non_shorthand_field_patterns)] + +struct A { x: usize } + +impl Drop for A { + fn drop(&mut self) {} +} + +pub fn main() { + let a = A { x: 0 }; + + match a { + A { x : ref x } => { + println!("{}", x) + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-63983.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-63983.rs new file mode 100644 index 000000000000..17a7c30e1810 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-63983.rs @@ -0,0 +1,16 @@ +enum MyEnum { + Tuple(i32), + Struct{ s: i32 }, +} + +fn foo(en: MyEnum) { + match en { + MyEnum::Tuple => "", +// { dg-error ".E0532." "" { target *-*-* } .-1 } + MyEnum::Struct => "", +// { dg-error ".E0532." "" { target *-*-* } .-1 } + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-64430.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-64430.rs new file mode 100644 index 000000000000..b93facc8e16f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-64430.rs @@ -0,0 +1,15 @@ +// compile-flags:-C panic=abort + +#![no_std] +pub struct Foo; + +fn main() { + Foo.bar() +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop{} +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6449.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6449.rs new file mode 100644 index 000000000000..edd94bb299b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6449.rs @@ -0,0 +1,45 @@ +// run-pass +#![allow(dead_code)] + +enum Foo { + Bar(isize), + Baz, +} + +enum Other { + Other1(Foo), + Other2(Foo, Foo), +} + +fn main() { + match Foo::Baz { + ::Foo::Bar(3) => panic!(), + ::Foo::Bar(_) if false => panic!(), + ::Foo::Bar(..) if false => panic!(), + ::Foo::Bar(_n) => panic!(), + ::Foo::Baz => {} + } + match Foo::Bar(3) { + ::Foo::Bar(3) => {} + ::Foo::Bar(_) if false => panic!(), + ::Foo::Bar(..) if false => panic!(), + ::Foo::Bar(_n) => panic!(), + ::Foo::Baz => panic!(), + } + match Foo::Bar(4) { + ::Foo::Bar(3) => panic!(), + ::Foo::Bar(_) if false => panic!(), + ::Foo::Bar(..) if false => panic!(), + ::Foo::Bar(n) => assert_eq!(n, 4), + ::Foo::Baz => panic!(), + } + + match Other::Other1(Foo::Baz) { + ::Other::Other1(::Foo::Baz) => {} + ::Other::Other1(::Foo::Bar(_)) => {} + ::Other::Other2(::Foo::Baz, ::Foo::Bar(_)) => {} + ::Other::Other2(::Foo::Bar(..), ::Foo::Baz) => {} + ::Other::Other2(..) => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-64559.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-64559.rs new file mode 100644 index 000000000000..12c18c4d9f69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-64559.rs @@ -0,0 +1,7 @@ +fn main() { + let orig = vec![true]; + for _val in orig {} + let _closure = || orig; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6458-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6458-1.rs new file mode 100644 index 000000000000..93534cc19002 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6458-1.rs @@ -0,0 +1,9 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn foo(t: T) {} +fn main() { + foo(panic!()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6458-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6458-2.rs new file mode 100644 index 000000000000..a4aa56c1d448 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6458-2.rs @@ -0,0 +1,6 @@ +fn main() { + // Unconstrained type: + format!("{:?}", None); +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6458-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6458-3.rs new file mode 100644 index 000000000000..ff03c04bd5cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6458-3.rs @@ -0,0 +1,7 @@ +use std::mem; + +fn main() { + mem::transmute(0); +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6458-4.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6458-4.rs new file mode 100644 index 000000000000..4f239e8a9941 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6458-4.rs @@ -0,0 +1,8 @@ +fn foo(b: bool) -> Result { // { dg-error ".E0308." "" { target *-*-* } } + Err("bar".to_string()); +} + +fn main() { + foo(false); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6458.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6458.rs new file mode 100644 index 000000000000..ac78223dcdc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6458.rs @@ -0,0 +1,15 @@ +use std::marker; + +pub struct TypeWithState(marker::PhantomData); +pub struct MyState; + +pub fn foo(_: TypeWithState) {} + +pub fn bar() { + foo(TypeWithState(marker::PhantomData)); +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-64593.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-64593.rs new file mode 100644 index 000000000000..b918f5ef4bf4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-64593.rs @@ -0,0 +1,13 @@ +// check-pass +#![deny(improper_ctypes)] + +pub struct Error(std::num::NonZeroU32); + +extern "Rust" { + fn foo(dest: &mut [u8]) -> Result<(), Error>; +} + +fn main() { + let _ = unsafe { foo(&mut []) }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-64620.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-64620.rs new file mode 100644 index 000000000000..b6d8bdcde50e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-64620.rs @@ -0,0 +1,6 @@ +enum Bug { + V1 = return [0][0] // { dg-error ".E0572." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6470.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6470.rs new file mode 100644 index 000000000000..8bd55fbd4fc6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6470.rs @@ -0,0 +1,19 @@ +// build-pass +#![allow(dead_code)] +#![allow(improper_ctypes)] + +// pretty-expanded FIXME #23616 +#![allow(non_snake_case)] + +pub mod Bar { + pub struct Foo { + v: isize, + } + + extern { + pub fn foo(v: *const Foo) -> Foo; + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-64732.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-64732.rs new file mode 100644 index 000000000000..b360f8ea4728 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-64732.rs @@ -0,0 +1,10 @@ +#![allow(unused)] +fn main() { + let _foo = b'hello\0'; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + let _bar = 'hello'; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-64792-bad-unicode-ctor.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-64792-bad-unicode-ctor.rs new file mode 100644 index 000000000000..1cb8aa897998 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-64792-bad-unicode-ctor.rs @@ -0,0 +1,6 @@ +struct X {} + +const Y: X = X("ö"); // { dg-error ".E0423." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-65131.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-65131.rs new file mode 100644 index 000000000000..4db96b52d1b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-65131.rs @@ -0,0 +1,19 @@ +fn get_pair(_a: &mut u32, _b: &mut u32) {} + +macro_rules! x10 { + ($($t:tt)*) => { + $($t)* $($t)* $($t)* $($t)* $($t)* + $($t)* $($t)* $($t)* $($t)* $($t)* + } +} + +#[allow(unused_assignments)] +fn main() { + let mut x = 1; + + get_pair(&mut x, &mut x); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + + x10! { x10!{ x10!{ if x > 0 { x += 2 } else { x += 1 } } } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-65284-suggest-generic-trait-bound.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-65284-suggest-generic-trait-bound.rs new file mode 100644 index 000000000000..a2bbb2c6499a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-65284-suggest-generic-trait-bound.rs @@ -0,0 +1,12 @@ +trait Foo { + fn foo(&self); +} + +trait Bar {} + +fn do_stuff(t : T) { + t.foo() // { dg-error ".E0599." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-65462.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-65462.rs new file mode 100644 index 000000000000..1b57e0378c19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-65462.rs @@ -0,0 +1,16 @@ +// build-pass + +enum Empty {} +enum Enum { + Empty( Empty ) +} + +fn foobar() -> Option< Enum > { + let value: Option< Empty > = None; + Some( Enum::Empty( value? ) ) +} + +fn main() { + foobar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6557.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6557.rs new file mode 100644 index 000000000000..83c37a3f6e2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6557.rs @@ -0,0 +1,11 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#![feature(box_patterns)] +#![feature(box_syntax)] + +fn foo(box (_x, _y): Box<(isize, isize)>) {} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-65611.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-65611.rs new file mode 100644 index 000000000000..728c03bf1797 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-65611.rs @@ -0,0 +1,64 @@ +use std::mem::MaybeUninit; +use std::ops::Deref; + +pub unsafe trait Array { + /// The array’s element type + type Item; + #[doc(hidden)] + /// The smallest index type that indexes the array. + type Index: Index; + #[doc(hidden)] + fn as_ptr(&self) -> *const Self::Item; + #[doc(hidden)] + fn as_mut_ptr(&mut self) -> *mut Self::Item; + #[doc(hidden)] + fn capacity() -> usize; +} + +pub trait Index : PartialEq + Copy { + fn to_usize(self) -> usize; + fn from(usize) -> Self; +} + +impl Index for usize { + fn to_usize(self) -> usize { self } + fn from(val: usize) -> Self { + val + } +} + +unsafe impl Array for [T; 1] { + type Item = T; + type Index = usize; + fn as_ptr(&self) -> *const T { self as *const _ as *const _ } + fn as_mut_ptr(&mut self) -> *mut T { self as *mut _ as *mut _} + fn capacity() -> usize { 1 } +} + +impl Deref for ArrayVec { + type Target = [A::Item]; + #[inline] + fn deref(&self) -> &[A::Item] { + panic!() + } +} + +pub struct ArrayVec { + xs: MaybeUninit, + len: usize, +} + +impl ArrayVec { + pub fn new() -> ArrayVec { + panic!() + } +} + +fn main() { + let mut buffer = ArrayVec::new(); + let x = buffer.last().unwrap().0.clone(); +// { dg-error ".E0609." "" { target *-*-* } .-1 } +// { dg-error ".E0609." "" { target *-*-* } .-2 } + buffer.reverse(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-65634-raw-ident-suggestion.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-65634-raw-ident-suggestion.rs new file mode 100644 index 000000000000..06be60fa71c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-65634-raw-ident-suggestion.rs @@ -0,0 +1,23 @@ +#![allow(non_camel_case_types)] + +trait r#async { + fn r#struct(&self) { + println!("async"); + } +} + +trait r#await { + fn r#struct(&self) { + println!("await"); + } +} + +struct r#fn {} + +impl r#async for r#fn {} +impl r#await for r#fn {} + +fn main() { + r#fn {}.r#struct(); // { dg-error ".E0034." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-65673.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-65673.rs new file mode 100644 index 000000000000..40ad9ef08cea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-65673.rs @@ -0,0 +1,13 @@ +#![feature(trait_alias)] // Enabled to reduce stderr output, but can be triggered even if disabled. +trait Trait {} +trait WithType { + type Ctx; +} +trait Alias = where T: Trait; + +impl WithType for T { + type Ctx = dyn Alias; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6596-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6596-1.rs new file mode 100644 index 000000000000..366deff19112 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6596-1.rs @@ -0,0 +1,11 @@ +macro_rules! e { + ($inp:ident) => ( + $nonexistent +// { dg-error "" "" { target *-*-* } .-1 } + ); +} + +fn main() { + e!(foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6596-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6596-2.rs new file mode 100644 index 000000000000..ad1d66f3c5a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6596-2.rs @@ -0,0 +1,14 @@ +#![feature(macro_rules)] + +macro_rules! g { + ($inp:ident) => ( + { $inp $nonexistent } +// { dg-error "" "" { target *-*-* } .-1 } + ); +} + +fn main() { + let foo = 0; + g!(foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-66308.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-66308.rs new file mode 100644 index 000000000000..8561b857c511 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-66308.rs @@ -0,0 +1,9 @@ +// build-pass +// compile-flags: --crate-type lib -C opt-level=0 + +// Regression test for LLVM crash affecting Emscripten targets + +pub fn foo() { + (0..0).rev().next(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-66353.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-66353.rs new file mode 100644 index 000000000000..c381086ac249 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-66353.rs @@ -0,0 +1,16 @@ +// #66353: ICE when trying to recover from incorrect associated type + +trait _Func { + fn func(_: Self); +} + +trait _A { + type AssocT; +} + +fn main() { + _Func::< <() as _A>::AssocT >::func(()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6642.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6642.rs new file mode 100644 index 000000000000..1434a0a07f07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6642.rs @@ -0,0 +1,10 @@ +struct A; +impl A { + fn m(&self) { + fn x() { + self.m() // { dg-error ".E0434." "" { target *-*-* } } + } + } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-66473.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-66473.rs new file mode 100644 index 0000000000000000000000000000000000000000..f97027b7f8d4c28eb16a8c0279d603aa7049be91 GIT binary patch literal 128 zcmZX~F%Cdb3sRa0HigCo%ixFK39mdAp4f;@acTRqa&l sF?zrjgsq~Ke^IVYrjQw?@;$B?=HP)FEOzJ&?wF{4?({=N*_9~~z0nvWf&c&j literal 0 HcmV?d00001 diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-66667-function-cmp-cycle.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-66667-function-cmp-cycle.rs new file mode 100644 index 000000000000..720ff1f6feca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-66667-function-cmp-cycle.rs @@ -0,0 +1,17 @@ +fn first() { + second == 1 // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn second() { + first == 1 // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn bar() { + bar == 1 // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-66702-break-outside-loop-val.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-66702-break-outside-loop-val.rs new file mode 100644 index 000000000000..d2a3adccf862 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-66702-break-outside-loop-val.rs @@ -0,0 +1,10 @@ +// Breaks with values inside closures used to ICE (#66863) + +fn main() { + 'some_label: loop { + || break 'some_label (); +// { dg-error ".E0267." "" { target *-*-* } .-1 } +// { dg-error ".E0267." "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-66706.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-66706.rs new file mode 100644 index 000000000000..e0ed7127fe0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-66706.rs @@ -0,0 +1,26 @@ +fn a() { + [0; [|_: _ &_| ()].len()] +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +} + +fn b() { + [0; [|f @ &ref _| {} ; 0 ].len() ]; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn c() { + [0; [|&_: _ &_| {}; 0 ].len()] +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn d() { + [0; match [|f @ &ref _| () ] {} ] +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-66768.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-66768.rs new file mode 100644 index 000000000000..7d422675586d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-66768.rs @@ -0,0 +1,206 @@ +// Regression test for #66768. +// check-pass +#![allow(dead_code)] +//-^ "dead code" is needed to reproduce the issue. + +use std::marker::PhantomData; +use std::ops::{Add, Mul}; + +fn problematic_function(material_surface_element: Edge2dElement) +where + DefaultAllocator: FiniteElementAllocator, +{ + let _: Point2 = material_surface_element.map_reference_coords().into(); +} + +impl ArrayLength for UTerm { + type ArrayType = (); +} +impl> ArrayLength for UInt { + type ArrayType = GenericArrayImplEven; +} +impl> ArrayLength for UInt { + type ArrayType = GenericArrayImplOdd; +} +impl Add for UTerm { + type Output = U; + fn add(self, _: U) -> Self::Output { + unimplemented!() + } +} +impl Add> for UInt +where + Ul: Add, +{ + type Output = UInt, B1>; + fn add(self, _: UInt) -> Self::Output { + unimplemented!() + } +} +impl Mul for UTerm { + type Output = UTerm; + fn mul(self, _: U) -> Self { + unimplemented!() + } +} +impl Mul> for UInt +where + Ul: Mul>, +{ + type Output = UInt>, B0>; + fn mul(self, _: UInt) -> Self::Output { + unimplemented!() + } +} +impl Mul> for UInt +where + Ul: Mul>, + UInt>, B0>: Add>, +{ + type Output = Sum>, B0>, UInt>; + fn mul(self, _: UInt) -> Self::Output { + unimplemented!() + } +} +impl Allocator for DefaultAllocator +where + R: DimName, + C: DimName, + R::Value: Mul, + Prod: ArrayLength, +{ + type Buffer = ArrayStorage; + fn allocate_uninitialized(_: R, _: C) -> Self::Buffer { + unimplemented!() + } + fn allocate_from_iterator(_: R, _: C, _: I) -> Self::Buffer { + unimplemented!() + } +} +impl Allocator for DefaultAllocator { + type Buffer = VecStorage; + fn allocate_uninitialized(_: Dynamic, _: C) -> Self::Buffer { + unimplemented!() + } + fn allocate_from_iterator(_: Dynamic, _: C, _: I) -> Self::Buffer { + unimplemented!() + } +} +impl DimName for DimU1 { + type Value = U1; + fn name() -> Self { + unimplemented!() + } +} +impl DimName for DimU2 { + type Value = U2; + fn name() -> Self { + unimplemented!() + } +} +impl From> for Point +where + DefaultAllocator: Allocator, +{ + fn from(_: VectorN) -> Self { + unimplemented!() + } +} +impl FiniteElementAllocator for DefaultAllocator where + DefaultAllocator: Allocator + Allocator +{ +} +impl ReferenceFiniteElement for Edge2dElement { + type NodalDim = DimU1; +} +impl FiniteElement for Edge2dElement { + fn map_reference_coords(&self) -> Vector2 { + unimplemented!() + } +} + +type Owned = >::Buffer; +type MatrixMN = Matrix>; +type VectorN = MatrixMN; +type Vector2 = VectorN; +type Point2 = Point; +type U1 = UInt; +type U2 = UInt, B0>; +type Sum = >::Output; +type Prod = >::Output; + +struct GenericArray> { + _data: U::ArrayType, +} +struct GenericArrayImplEven { + _parent2: U, + _marker: T, +} +struct GenericArrayImplOdd { + _parent2: U, + _data: T, +} +struct B0; +struct B1; +struct UTerm; +struct UInt { + _marker: PhantomData<(U, B)>, +} +struct DefaultAllocator; +struct Dynamic; +struct DimU1; +struct DimU2; +struct Matrix { + _data: S, + _phantoms: PhantomData<(N, R, C)>, +} +struct ArrayStorage +where + R: DimName, + C: DimName, + R::Value: Mul, + Prod: ArrayLength, +{ + _data: GenericArray>, +} +struct VecStorage { + _data: N, + _nrows: R, + _ncols: C, +} +struct Point +where + DefaultAllocator: Allocator, +{ + _coords: VectorN, +} +struct Edge2dElement; + +trait ArrayLength { + type ArrayType; +} +trait Allocator { + type Buffer; + fn allocate_uninitialized(nrows: R, ncols: C) -> Self::Buffer; + fn allocate_from_iterator(nrows: R, ncols: C, iter: I) -> Self::Buffer; +} +trait DimName { + type Value; + fn name() -> Self; +} +trait FiniteElementAllocator: + Allocator + Allocator +{ +} +trait ReferenceFiniteElement { + type NodalDim; +} +trait FiniteElement: ReferenceFiniteElement +where + DefaultAllocator: FiniteElementAllocator, +{ + fn map_reference_coords(&self) -> VectorN; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-66851.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-66851.rs new file mode 100644 index 000000000000..6d4ae4ab1b65 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-66851.rs @@ -0,0 +1,21 @@ +// This used to mis-compile because the mir-opt `SimplifyArmIdentity` +// did not check that the types matched up in the `Ok(r)` branch. +// +// run-pass +// compile-flags: -Zmir-opt-level=2 + +#[derive(Debug, PartialEq, Eq)] +enum SpecialsRes { Res(u64) } + +fn e103() -> SpecialsRes { + if let Ok(r) = "1".parse() { + SpecialsRes::Res(r) + } else { + SpecialsRes::Res(42) + } +} + +fn main() { + assert_eq!(e103(), SpecialsRes::Res(1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-66923-show-error-for-correct-call.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-66923-show-error-for-correct-call.rs new file mode 100644 index 000000000000..9377e8fda35f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-66923-show-error-for-correct-call.rs @@ -0,0 +1,16 @@ +// This test checks that errors are showed for lines with `collect` rather than `push` method. + +fn main() { + let v = vec![1_f64, 2.2_f64]; + let mut fft: Vec> = vec![]; + + let x1: &[f64] = &v; + let x2: Vec = x1.into_iter().collect(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + fft.push(x2); + + let x3 = x1.into_iter().collect::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + fft.push(x3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs new file mode 100644 index 000000000000..8d86a19f38dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs @@ -0,0 +1,22 @@ +// Regression test for #67037. +// +// In type checking patterns, E0023 occurs when the tuple pattern and the expected +// tuple pattern have different number of fields. For example, as below, `P()`, +// the tuple struct pattern, has 0 fields, but requires 1 field. +// +// In emitting E0023, we try to see if this is a case of e.g., `Some(a, b, c)` but where +// the scrutinee was of type `Some((a, b, c))`, and suggest that parenthesis be added. +// +// However, we did not account for the expected type being different than the tuple pattern type. +// This caused an issue when the tuple pattern type (`P`) was generic. +// Specifically, we tried deriving the 0th field's type using the `substs` of the expected type. +// When attempting to substitute `T`, there was no such substitution, so "out of range" occurred. + +struct U {} // 0 type parameters offered +struct P(T); // 1 type parameter wanted + +fn main() { + let P() = U {}; // { dg-error ".E0023." "" { target *-*-* } } +// { dg-error ".E0023." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-67039-unsound-pin-partialeq.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-67039-unsound-pin-partialeq.rs new file mode 100644 index 000000000000..06ade3a04a2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-67039-unsound-pin-partialeq.rs @@ -0,0 +1,28 @@ +// Pin's PartialEq implementation allowed to access the pointer allowing for +// unsoundness by using Rc::get_mut to move value within Rc. +// See https://internals.rust-lang.org/t/unsoundness-in-pin/11311/73 for more details. + +use std::ops::Deref; +use std::pin::Pin; +use std::rc::Rc; + +struct Apple; + +impl Deref for Apple { + type Target = Apple; + fn deref(&self) -> &Apple { + &Apple + } +} + +impl PartialEq> for Apple { + fn eq(&self, _rc: &Rc) -> bool { + unreachable!() + } +} + +fn main() { + let _ = Pin::new(Apple) == Rc::pin(Apple); +// { dg-error ".E0271." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6738.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6738.rs new file mode 100644 index 000000000000..e0b50bab2ec7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6738.rs @@ -0,0 +1,11 @@ +struct Foo { + x: T, +} +impl Foo { + fn add(&mut self, v: Foo){ + self.x += v.x; +// { dg-error ".E0368." "" { target *-*-* } .-1 } + } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-67552.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-67552.rs new file mode 100644 index 000000000000..2b137397b082 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-67552.rs @@ -0,0 +1,32 @@ +// build-fail +// normalize-stderr-test: ".nll/" -> "/" + +fn main() { + rec(Empty); +} + +struct Empty; + +impl Iterator for Empty { + type Item = (); + fn next<'a>(&'a mut self) -> core::option::Option<()> { + None + } +} + +fn identity(x: T) -> T { + x +} + +fn rec(mut it: T) +where + T: Iterator, +{ + if () == () { + T::count(it); + } else { + rec(identity(&mut it)) +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs new file mode 100644 index 000000000000..a7862a5c0b8b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-68000-unicode-ident-after-missing-comma.rs @@ -0,0 +1,7 @@ +pub struct Foo { + pub bar: Vecö +// { dg-error "" "" { target *-*-* } .-1 } +} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6801.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6801.rs new file mode 100644 index 000000000000..a6d968e1cd90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6801.rs @@ -0,0 +1,22 @@ +// Creating a stack closure which references a box and then +// transferring ownership of the box before invoking the stack +// closure results in a crash. + +#![feature(box_syntax)] + +fn twice(x: Box) -> usize { + *x * 2 +} + +fn invoke(f: F) where F: FnOnce() -> usize { + f(); +} + +fn main() { + let x : Box = box 9; + let sq = || { *x * *x }; + + twice(x); // { dg-error ".E0505." "" { target *-*-* } } + invoke(sq); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-68010-large-zst-consts.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-68010-large-zst-consts.rs new file mode 100644 index 000000000000..10351090920c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-68010-large-zst-consts.rs @@ -0,0 +1,6 @@ +// build-pass + +fn main() { + println!("{}", [(); std::usize::MAX].len()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6804.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6804.rs new file mode 100644 index 000000000000..801f1fe183e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6804.rs @@ -0,0 +1,26 @@ +// Matching against NaN should result in a warning + +#![allow(unused)] +#![deny(illegal_floating_point_literal_pattern)] + +use std::f64::NAN; + +fn main() { + let x = NAN; + match x { + NAN => {}, // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + _ => {}, + }; + + match [x, 1.0] { + [NAN, _] => {}, // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + _ => {}, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-68091-unicode-ident-after-if.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-68091-unicode-ident-after-if.rs new file mode 100644 index 000000000000..5e1df57cf987 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-68091-unicode-ident-after-if.rs @@ -0,0 +1,10 @@ +macro_rules! x { + ($($c:tt)*) => { + $($c)ö* {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn main() { + x!(if); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs new file mode 100644 index 000000000000..fed1fd8ba41a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-68092-unicode-ident-after-incomplete-expr.rs @@ -0,0 +1,10 @@ +macro_rules! x { + ($($c:tt)*) => { + $($c)ö* // { dg-error "" "" { target *-*-* } } + }; +} + +fn main() { + x!(!); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-68103.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-68103.rs new file mode 100644 index 000000000000..ef3587e0903c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-68103.rs @@ -0,0 +1,7 @@ +// check-pass + +pub extern crate self as name; +pub use name::name as bug; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-68696-catch-during-unwind.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-68696-catch-during-unwind.rs new file mode 100644 index 000000000000..211f32660d55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-68696-catch-during-unwind.rs @@ -0,0 +1,27 @@ +// Checks that catch_unwind can be used if unwinding is already in progress. +// Used to fail when standard library had been compiled with debug assertions, +// due to incorrect assumption that a current thread is not panicking when +// entering the catch_unwind. +// +// run-pass +#![feature(cfg_panic)] + +use std::panic::catch_unwind; + +#[derive(Default)] +struct Guard; + +impl Drop for Guard { + fn drop(&mut self) { + let _ = catch_unwind(|| {}); + } +} + +fn main() { + #[cfg(panic = "unwind")] + let _ = catch_unwind(|| { + let _guard = Guard::default(); + panic!(); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6892.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6892.rs new file mode 100644 index 000000000000..47777c0e1e14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6892.rs @@ -0,0 +1,59 @@ +// run-pass +#![allow(dead_code)] +// Ensures that destructors are run for expressions of the form "let _ = e;" +// where `e` is a type which requires a destructor. + + +struct Foo; +struct Bar { x: isize } +struct Baz(isize); +enum FooBar { _Foo(Foo), _Bar(usize) } + +static mut NUM_DROPS: usize = 0; + +impl Drop for Foo { + fn drop(&mut self) { + unsafe { NUM_DROPS += 1; } + } +} +impl Drop for Bar { + fn drop(&mut self) { + unsafe { NUM_DROPS += 1; } + } +} +impl Drop for Baz { + fn drop(&mut self) { + unsafe { NUM_DROPS += 1; } + } +} +impl Drop for FooBar { + fn drop(&mut self) { + unsafe { NUM_DROPS += 1; } + } +} + +fn main() { + assert_eq!(unsafe { NUM_DROPS }, 0); + { let _x = Foo; } + assert_eq!(unsafe { NUM_DROPS }, 1); + { let _x = Bar { x: 21 }; } + assert_eq!(unsafe { NUM_DROPS }, 2); + { let _x = Baz(21); } + assert_eq!(unsafe { NUM_DROPS }, 3); + { let _x = FooBar::_Foo(Foo); } + assert_eq!(unsafe { NUM_DROPS }, 5); + { let _x = FooBar::_Bar(42); } + assert_eq!(unsafe { NUM_DROPS }, 6); + + { let _ = Foo; } + assert_eq!(unsafe { NUM_DROPS }, 7); + { let _ = Bar { x: 21 }; } + assert_eq!(unsafe { NUM_DROPS }, 8); + { let _ = Baz(21); } + assert_eq!(unsafe { NUM_DROPS }, 9); + { let _ = FooBar::_Foo(Foo); } + assert_eq!(unsafe { NUM_DROPS }, 11); + { let _ = FooBar::_Bar(42); } + assert_eq!(unsafe { NUM_DROPS }, 12); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-68951.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-68951.rs new file mode 100644 index 000000000000..d800a0445e48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-68951.rs @@ -0,0 +1,10 @@ +// check-pass + +fn main() { + let array = [0x42u8; 10]; + for b in &array { + let lo = b & 0xf; + let hi = (b >> 4) & 0xf; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6898.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6898.rs new file mode 100644 index 000000000000..5905064f67dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6898.rs @@ -0,0 +1,34 @@ +// check-pass +// pretty-expanded FIXME #23616 + +use std::mem; + +/// Returns the size of a type +pub fn size_of() -> usize { + TypeInfo::size_of(None::) +} + +/// Returns the size of the type that `val` points to +pub fn size_of_val(val: &T) -> usize { + val.size_of_val() +} + +pub trait TypeInfo: Sized { + fn size_of(_lame_type_hint: Option) -> usize; + fn size_of_val(&self) -> usize; +} + +impl TypeInfo for T { + /// The size of the type in bytes. + fn size_of(_lame_type_hint: Option) -> usize { + mem::size_of::() + } + + /// Returns the size of the type of `self` in bytes. + fn size_of_val(&self) -> usize { + TypeInfo::size_of(None::) + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-69130.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-69130.rs new file mode 100644 index 000000000000..687953f20dfd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-69130.rs @@ -0,0 +1,8 @@ +// Issue 69130: character indexing bug in rustc_errors::CodeSuggestion::splice_lines(). + +enum F { +M (§& u8)} +// { dg-error ".E0106." "" { target *-*-* } .-1 } +// { dg-error ".E0106." "" { target *-*-* } .-2 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6919.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6919.rs new file mode 100644 index 000000000000..599321b7f7a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6919.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(unused_attributes)] +// aux-build:iss.rs + +// pretty-expanded FIXME #23616 + +extern crate issue6919_3; + +pub fn main() { + let _ = issue6919_3::D.k; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-69225-SCEVAddExpr-wrap-flag.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-69225-SCEVAddExpr-wrap-flag.rs new file mode 100644 index 000000000000..5b6cb9340ad3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-69225-SCEVAddExpr-wrap-flag.rs @@ -0,0 +1,34 @@ +// run-fail +// compile-flags: -C opt-level=3 +// error-pattern: index out of bounds: the len is 0 but the index is 16777216 +// ignore-wasm no panic or subprocess support +// ignore-emscripten no panic or subprocess support + +fn do_test(x: usize) { + let mut arr = vec![vec![0u8; 3]]; + + let mut z = vec![0]; + for arr_ref in arr.iter_mut() { + for y in 0..x { + for _ in 0..1 { + z.reserve_exact(x); + let iterator = std::iter::repeat(0).take(x); + let mut cnt = 0; + iterator.for_each(|_| { + z[0] = 0; + cnt += 1; + }); + let a = y * x; + let b = (y + 1) * x - 1; + let slice = &mut arr_ref[a..b]; + slice[1 << 24] += 1; + } + } + } +} + +fn main() { + do_test(1); + do_test(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-69225-layout-repeated-checked-add.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-69225-layout-repeated-checked-add.rs new file mode 100644 index 000000000000..d679aa240424 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-69225-layout-repeated-checked-add.rs @@ -0,0 +1,32 @@ +// Ensure we appropriately error instead of overflowing a calculation when creating a new Alloc +// Layout + +// run-fail +// compile-flags: -C opt-level=3 +// error-pattern: index out of bounds: the len is 0 but the index is 16777216 +// ignore-wasm no panic or subprocess support +// ignore-emscripten no panic or subprocess support + +fn do_test(x: usize) { + let arr = vec![vec![0u8; 3]]; + + let mut z = Vec::new(); + for arr_ref in arr { + for y in 0..x { + for _ in 0..1 { + z.extend(std::iter::repeat(0).take(x)); + let a = y * x; + let b = (y + 1) * x - 1; + let slice = &arr_ref[a..b]; + eprintln!("{} {} {} {}", a, b, arr_ref.len(), slice.len()); + eprintln!("{:?}", slice[1 << 24]); + } + } + } +} + +fn main() { + do_test(1); + do_test(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-69306.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-69306.rs new file mode 100644 index 000000000000..2fb5853f2f30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-69306.rs @@ -0,0 +1,46 @@ +fn main() {} + +struct S0(T); +impl S0 { + const C: S0 = Self(0); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + fn foo() { + Self(0); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } +} + +// Testing normalization. +trait Fun { + type Out; +} +impl Fun for S0 { + type Out = Self; +} +trait Foo { + fn foo(); +} +impl Foo for as Fun>::Out { + fn foo() { + Self(0); // { dg-error ".E0308." "" { target *-*-* } } + } +} + +struct S1(T, U); +impl S1 { + const C: S1 = Self(0, 1); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +struct S2(T); +impl S2 { + fn map(x: U) -> S2 { + Self(x) +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6936.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6936.rs new file mode 100644 index 000000000000..ae8fb793dd23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6936.rs @@ -0,0 +1,35 @@ +struct T; + +mod t1 { + type Foo = ::T; + mod Foo {} // { dg-error ".E0428." "" { target *-*-* } } +} + +mod t2 { + type Foo = ::T; + struct Foo; // { dg-error ".E0428." "" { target *-*-* } } +} + +mod t3 { + type Foo = ::T; + enum Foo {} // { dg-error ".E0428." "" { target *-*-* } } +} + +mod t4 { + type Foo = ::T; + fn Foo() {} // ok +} + +mod t5 { + type Bar = T; + mod Bar {} // { dg-error ".E0428." "" { target *-*-* } } +} + +mod t6 { + type Foo = ::T; + impl Foo {} // ok +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-69396-const-no-type-in-macro.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-69396-const-no-type-in-macro.rs new file mode 100644 index 000000000000..3d87cf2df428 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-69396-const-no-type-in-macro.rs @@ -0,0 +1,18 @@ +macro_rules! suite { + ( $( $fn:ident; )* ) => { + $( + const A = "A".$fn(); +// { dg-error ".E0121." "" { target *-*-* } .-1 } +// { dg-error ".E0121." "" { target *-*-* } .-2 } +// { dg-error ".E0121." "" { target *-*-* } .-3 } + )* + } +} + +suite! { + len; + is_empty; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-69455.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-69455.rs new file mode 100644 index 000000000000..4c9b1237bdc3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-69455.rs @@ -0,0 +1,31 @@ +// Regression test for #69455: projection predicate was not satisfied. +// Compiler should indicate the correct location of the +// unsatisfied projection predicate + +pub trait Test { + type Output; + + fn test(self, rhs: Rhs) -> Self::Output; +} + +impl Test for u64 { + type Output = u64; + + fn test(self, other: u32) -> u64 { + self + (other as u64) + } +} + +impl Test for u64 { + type Output = u64; + + fn test(self, other: u64) -> u64 { + (self + other) as u64 + } +} + +fn main() { + let xs: Vec = vec![1, 2, 3]; + println!("{}", 23u64.test(xs.iter().sum())); // { dg-error ".E0284." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-69532.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-69532.rs new file mode 100644 index 000000000000..d220a8bd1381 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-69532.rs @@ -0,0 +1,25 @@ +// run-pass +#![feature(const_fn_transmute)] + +const fn make_nans() -> (f64, f64, f32, f32) { + let nan1: f64 = unsafe { std::mem::transmute(0x7FF0_0001_0000_0001u64) }; + let nan2: f64 = unsafe { std::mem::transmute(0x7FF0_0000_0000_0001u64) }; + + let nan1_32 = nan1 as f32; + let nan2_32 = nan2 as f32; + + (nan1, nan2, nan1_32, nan2_32) +} + +static NANS: (f64, f64, f32, f32) = make_nans(); + +fn main() { + let (nan1, nan2, nan1_32, nan2_32) = NANS; + + assert!(nan1.is_nan()); + assert!(nan2.is_nan()); + + assert!(nan1_32.is_nan()); + assert!(nan2_32.is_nan()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-69602-type-err-during-codegen-ice.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-69602-type-err-during-codegen-ice.rs new file mode 100644 index 000000000000..1edb64a8ebb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-69602-type-err-during-codegen-ice.rs @@ -0,0 +1,23 @@ +trait TraitA { + const VALUE: usize; +} + +struct A; +impl TraitA for A { + const VALUE: usize = 0; +} + +trait TraitB { + type MyA: TraitA; + const VALUE: usize = Self::MyA::VALUE; +} + +struct B; +impl TraitB for B { // { dg-error ".E0046." "" { target *-*-* } } + type M = A; // { dg-error ".E0437." "" { target *-*-* } } +} + +fn main() { + let _ = [0; B::VALUE]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-69683.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-69683.rs new file mode 100644 index 000000000000..3e2ae963d121 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-69683.rs @@ -0,0 +1,33 @@ +pub trait Element { + type Array; +} + +impl Element<()> for T { + type Array = T; +} + +impl, S> Element<[S; 3]> for T { + type Array = [T::Array; 3]; +} + +trait Foo +where + u8: Element, +{ + fn foo(self, x: >::Array); +} + +impl Foo for u16 +where + u8: Element, +{ + fn foo(self, _: >::Array) {} +} + +fn main() { + let b: [u8; 3] = [0u8; 3]; + + 0u16.foo(b); // { dg-error ".E0284." "" { target *-*-* } } + //>::foo(0u16, b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-69725.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-69725.rs new file mode 100644 index 000000000000..243ce032adc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-69725.rs @@ -0,0 +1,12 @@ +// aux-build:issue-69725.rs + +extern crate issue_69725; +use issue_69725::Struct; + +fn crash() { + let _ = Struct::::new().clone(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-69841.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-69841.rs new file mode 100644 index 000000000000..eb9398cf7b64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-69841.rs @@ -0,0 +1,32 @@ +// This is a regression test for issue rust-lang/rust#69841, which exposed an +// LLVM bug which needed a fix to be backported. + +// run-pass +// no-system-llvm + +fn main() { + let buffer = [49u8, 10]; + let mut a : u64 = 0; + 'read: loop { + for c in &buffer { + match c { + 48..=57 => { + a*= 10; + a+= *c as u64 - 48; + } + 10 => { + break 'read; + } + _ => { + unsafe { std::hint::unreachable_unchecked() }; + } + } + } + } + if a == 1 { + println!("What did you expect?"); + } else { + panic!("this should be unreachable."); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-6991.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-6991.rs new file mode 100644 index 000000000000..d594bcbaa9b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-6991.rs @@ -0,0 +1,9 @@ +// check-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +static x: &'static usize = &1; +static y: usize = *x; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-70041.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-70041.rs new file mode 100644 index 000000000000..bec70034fa53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-70041.rs @@ -0,0 +1,14 @@ +// compile-flags: --edition=2018 +// run-pass + +macro_rules! regex { +// { dg-warning "" "" { target *-*-* } .-1 } + () => {}; +} + +#[allow(dead_code)] +use regex; +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-70093.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-70093.rs new file mode 100644 index 000000000000..4ac5b29bc9b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-70093.rs @@ -0,0 +1,9 @@ +// run-pass +// compile-flags: -Zlink-native-libraries=no -Cdefault-linker-libraries=yes +// ignore-windows - this will probably only work on unixish systems + +#[link(name = "some-random-non-existent-library", kind = "static")] +extern "C" {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7012.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7012.rs new file mode 100644 index 000000000000..d53a8450611d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7012.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] + +/* +# Comparison of static arrays + +The expected behaviour would be that `test == test1`, therefore 'true' +would be printed, however the below prints false. +*/ + +struct signature<'a> { pattern : &'a [u32] } + +static test1: signature<'static> = signature { + pattern: &[0x243f6a88,0x85a308d3,0x13198a2e,0x03707344,0xa4093822,0x299f31d0] +}; + +pub fn main() { + let test: &[u32] = &[0x243f6a88,0x85a308d3,0x13198a2e, + 0x03707344,0xa4093822,0x299f31d0]; + println!("{}",test==test1.pattern); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7013.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7013.rs new file mode 100644 index 000000000000..f09d504d5746 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7013.rs @@ -0,0 +1,29 @@ +#![feature(box_syntax)] + +use std::cell::RefCell; +use std::rc::Rc; + +trait Foo { + fn set(&mut self, v: Rc>); +} + +struct B { + v: Option>> +} + +impl Foo for B { + fn set(&mut self, v: Rc>) + { + self.v = Some(v); + } +} + +struct A { + v: Box, +} + +fn main() { + let a = A {v: box B{v: None} as Box}; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-70381.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-70381.rs new file mode 100644 index 000000000000..bb2e4bcca947 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-70381.rs @@ -0,0 +1,7 @@ +// Test that multi-byte unicode characters with missing parameters do not ICE. + +fn main() { + println!("\r¡{}") +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7044.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7044.rs new file mode 100644 index 000000000000..5233265de95b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7044.rs @@ -0,0 +1,5 @@ +static X: isize = 0; +struct X; // { dg-error ".E0428." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7061.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7061.rs new file mode 100644 index 000000000000..c54cbfd0f6c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7061.rs @@ -0,0 +1,11 @@ +struct BarStruct; + +impl<'a> BarStruct { + fn foo(&'a mut self) -> Box { self } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-70673.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-70673.rs new file mode 100644 index 000000000000..01f1a02a5177 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-70673.rs @@ -0,0 +1,13 @@ +// Regression test for https://github.com/rust-lang/rust/issues/70673. + +// run-pass + +#![feature(thread_local)] + +#[thread_local] +static A: &u8 = &42; + +fn main() { + dbg!(*A); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs new file mode 100644 index 000000000000..030848d1fac0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs @@ -0,0 +1,11 @@ +fn a() -> i32 { + 3 +} + +pub fn main() { + assert_eq!(a, 0); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-70746.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-70746.rs new file mode 100644 index 000000000000..9424be3e0734 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-70746.rs @@ -0,0 +1,30 @@ +// check-pass + +pub trait Trait1 { + type C; +} + +struct T1; +impl Trait1 for T1 { + type C = usize; +} +pub trait Callback: FnMut(::C) {} +impl::C)> Callback for F {} + +pub struct State { + callback: Option>>, +} +impl State { + fn new() -> Self { + Self { callback: None } + } + fn test_cb(&mut self, d: ::C) { + (self.callback.as_mut().unwrap())(d) + } +} + +fn main() { + let mut s = State::::new(); + s.test_cb(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7092.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7092.rs new file mode 100644 index 000000000000..51120a5a04ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7092.rs @@ -0,0 +1,16 @@ +enum Whatever { +} + +fn foo(x: Whatever) { + match x { + Some(field) => +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + field.access(), + } +} + +fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-71036.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-71036.rs new file mode 100644 index 000000000000..f4cff004054d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-71036.rs @@ -0,0 +1,18 @@ +#![feature(unsize, dispatch_from_dyn)] + +use std::marker::Unsize; +use std::ops::DispatchFromDyn; + +#[allow(unused)] +struct Foo<'a, T: ?Sized> { + _inner: &'a &'a T, +} + +impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn> for Foo<'a, T> {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-note ".E0277." "" { target *-*-* } .-2 } +// { dg-note ".E0277." "" { target *-*-* } .-3 } +// { dg-note ".E0277." "" { target *-*-* } .-4 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-71406.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-71406.rs new file mode 100644 index 000000000000..7067b8fa1726 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-71406.rs @@ -0,0 +1,7 @@ +use std::sync::mpsc; + +fn main() { + let (tx, rx) = mpsc::channel::new(1); +// { dg-error ".E0433." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-71584.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-71584.rs new file mode 100644 index 000000000000..7ed630ea523c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-71584.rs @@ -0,0 +1,6 @@ +fn main() { + let n: u32 = 1; + let mut d: u64 = 2; + d = d % n.into(); // { dg-error ".E0284." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-71676-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-71676-1.rs new file mode 100644 index 000000000000..87aa1bce9fc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-71676-1.rs @@ -0,0 +1,54 @@ +// run-rustfix +use std::ops::Deref; +use std::ops::DerefMut; +struct Bar(u8); +struct Foo(Bar); +struct Emm(Foo); +impl Deref for Bar{ + type Target = u8; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Foo { + type Target = Bar; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Emm { + type Target = Foo; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl DerefMut for Bar{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl DerefMut for Foo { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl DerefMut for Emm { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +fn main() { + // Suggest dereference with arbitrary mutability + let a = Emm(Foo(Bar(0))); + let _: *const u8 = &a; // { dg-error ".E0308." "" { target *-*-* } } + + let mut a = Emm(Foo(Bar(0))); + let _: *mut u8 = &a; // { dg-error ".E0308." "" { target *-*-* } } + + let a = Emm(Foo(Bar(0))); + let _: *const u8 = &mut a; // { dg-error ".E0308." "" { target *-*-* } } + + let mut a = Emm(Foo(Bar(0))); + let _: *mut u8 = &mut a; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-71676-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-71676-2.rs new file mode 100644 index 000000000000..b279940771dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-71676-2.rs @@ -0,0 +1,43 @@ +use std::ops::Deref; +use std::ops::DerefMut; +struct Bar(u8); +struct Foo(Bar); +struct Emm(Foo); +impl Deref for Bar{ + type Target = u8; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Foo { + type Target = Bar; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Emm { + type Target = Foo; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl DerefMut for Bar{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl DerefMut for Foo { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl DerefMut for Emm { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +fn main() { + let a = Emm(Foo(Bar(0))); + let _: *mut u8 = &a; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7178.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7178.rs new file mode 100644 index 000000000000..8da37db20a00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7178.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:issue-7178.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_7178 as cross_crate_self; + +pub fn main() { + let _ = cross_crate_self::Foo::new(&1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-72002.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-72002.rs new file mode 100644 index 000000000000..47c8141526e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-72002.rs @@ -0,0 +1,30 @@ +// check-pass +struct Indexable; + +impl Indexable { + fn boo(&mut self) {} +} + +impl std::ops::Index<&str> for Indexable { + type Output = Indexable; + + fn index(&self, field: &str) -> &Indexable { + self + } +} + +impl std::ops::IndexMut<&str> for Indexable { + fn index_mut(&mut self, field: &str) -> &mut Indexable { + self + } +} + +fn main() { + let mut v = Indexable; + let field = "hello".to_string(); + + v[field.as_str()].boo(); + + v[&field].boo(); // < This should work +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-72076.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-72076.rs new file mode 100644 index 000000000000..ab40375ba767 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-72076.rs @@ -0,0 +1,7 @@ +trait X { + type S; + fn f() -> Self::S {} // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7222.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7222.rs new file mode 100644 index 000000000000..dd91614e84f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7222.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 +#![allow(illegal_floating_point_literal_pattern)] // FIXME #41620 + +pub fn main() { + const FOO: f64 = 10.0; + + match 0.0 { + 0.0 ..= FOO => (), + _ => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-72253.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-72253.rs new file mode 100644 index 000000000000..9d05d453c54c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-72253.rs @@ -0,0 +1,7 @@ +fn main() { + let a = std::process::Command::new("echo") + .arg("1") + ,arg("2") // { dg-error "" "" { target *-*-* } } + .output(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-72278.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-72278.rs new file mode 100644 index 000000000000..fd1874c11ec0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-72278.rs @@ -0,0 +1,20 @@ +// run-pass + +#![allow(unused)] + +struct S; + +impl S { + fn func<'a, U>(&'a self) -> U { + todo!() + } +} + +fn dont_crash<'a, U>() -> U { + S.func::<'a, U>() +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-72373.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-72373.rs new file mode 100644 index 000000000000..663a9bef6d41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-72373.rs @@ -0,0 +1,10 @@ +fn foo(c: &[u32], n: u32) -> u32 { + match *c { + [h, ..] if h > n => 0, + [h, ..] if h == n => 1, + [h, ref ts..] => foo(c, n - h) + foo(ts, n), +// { dg-error "" "" { target *-*-* } .-1 } + [] => 0, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-72455.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-72455.rs new file mode 100644 index 000000000000..bc3cd5edc7a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-72455.rs @@ -0,0 +1,28 @@ +// check-pass + +pub trait ResultExt { + type Ok; + fn err_eprint_and_ignore(self) -> Option; +} + +impl ResultExt for std::result::Result +where + E: std::error::Error, +{ + type Ok = O; + fn err_eprint_and_ignore(self) -> Option + where + Self: , + { + match self { + Err(e) => { + eprintln!("{}", e); + None + } + Ok(o) => Some(o), + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7246.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7246.rs new file mode 100644 index 000000000000..03d91c6252cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7246.rs @@ -0,0 +1,11 @@ +#![deny(unreachable_code)] +#![allow(dead_code)] + +use std::ptr; +pub unsafe fn g() { + return; + if *ptr::null() {}; // { dg-error "" "" { target *-*-* } } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-72554.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-72554.rs new file mode 100644 index 000000000000..67b12ccdb87d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-72554.rs @@ -0,0 +1,21 @@ +use std::collections::BTreeSet; + +#[derive(Hash)] +pub enum ElemDerived { // { dg-error ".E0072." "" { target *-*-* } } + A(ElemDerived) +} + +pub enum Elem { + Derived(ElemDerived) +} + +pub struct Set(BTreeSet); + +impl Set { + pub fn into_iter(self) -> impl Iterator { + self.0.into_iter() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-72574-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-72574-1.rs new file mode 100644 index 000000000000..9d245d6dd9be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-72574-1.rs @@ -0,0 +1,11 @@ +fn main() { + let x = (1, 2, 3); + match x { + (_a, _x @ ..) => {} + _ => {} + } +} +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-72574-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-72574-2.rs new file mode 100644 index 000000000000..0bc65ce90a66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-72574-2.rs @@ -0,0 +1,13 @@ +struct Binder(i32, i32, i32); + +fn main() { + let x = Binder(1, 2, 3); + match x { + Binder(_a, _x @ ..) => {} + _ => {} + } +} +// { dg-error ".E0023." "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error ".E0023." "" { target *-*-* } .-3 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7268.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7268.rs new file mode 100644 index 000000000000..1f947e1b37a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7268.rs @@ -0,0 +1,11 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn foo(_: T) {} + +fn bar(x: &'static T) { + foo(x); +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-72690.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-72690.rs new file mode 100644 index 000000000000..4ed8364bd942 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-72690.rs @@ -0,0 +1,63 @@ +fn no_err() { + |x: String| x; + let _ = String::from("x"); +} + +fn err() { + String::from("x".as_ref()); // { dg-error ".E0283." "" { target *-*-* } } +} + +fn arg_pat_closure_err() { + |x| String::from("x".as_ref()); // { dg-error ".E0283." "" { target *-*-* } } +} + +fn local_pat_closure_err() { + let _ = "x".as_ref(); // { dg-error ".E0283." "" { target *-*-* } } +} + +fn err_first_arg_pat() { + String::from("x".as_ref()); // { dg-error ".E0283." "" { target *-*-* } } + |x: String| x; +} + +fn err_second_arg_pat() { + |x: String| x; + String::from("x".as_ref()); // { dg-error ".E0283." "" { target *-*-* } } +} + +fn err_mid_arg_pat() { + |x: String| x; + |x: String| x; + |x: String| x; + |x: String| x; + String::from("x".as_ref()); // { dg-error ".E0283." "" { target *-*-* } } + |x: String| x; + |x: String| x; + |x: String| x; + |x: String| x; +} + +fn err_first_local_pat() { + String::from("x".as_ref()); // { dg-error ".E0283." "" { target *-*-* } } + let _ = String::from("x"); +} + +fn err_second_local_pat() { + let _ = String::from("x"); + String::from("x".as_ref()); // { dg-error ".E0283." "" { target *-*-* } } +} + +fn err_mid_local_pat() { + let _ = String::from("x"); + let _ = String::from("x"); + let _ = String::from("x"); + let _ = String::from("x"); + String::from("x".as_ref()); // { dg-error ".E0283." "" { target *-*-* } } + let _ = String::from("x"); + let _ = String::from("x"); + let _ = String::from("x"); + let _ = String::from("x"); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-72839-error-overflow.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-72839-error-overflow.rs new file mode 100644 index 000000000000..f5eb86ffff49 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-72839-error-overflow.rs @@ -0,0 +1,20 @@ +// Regression test for issue #72839 +// Tests that we do not overflow during trait selection after +// a type error occurs +use std::ops::Rem; +trait Foo {} +struct MyStruct(T); + +impl Rem> for MyStruct where MyStruct: Rem> { + type Output = u8; + fn rem(self, _: MyStruct) -> Self::Output { + panic!() + } +} + +fn main() {} + +fn foo() { + if missing_var % 8 == 0 {} // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-72933-match-stack-overflow.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-72933-match-stack-overflow.rs new file mode 100644 index 000000000000..8646c338511c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-72933-match-stack-overflow.rs @@ -0,0 +1,5209 @@ +// build-pass +// ignore-tidy-filelength +#![crate_type="rlib"] + +fn banana(v: &str) -> u32 { + match v { + "0" => 0, + "1" => 1, + "2" => 2, + "3" => 3, + "4" => 4, + "5" => 5, + "6" => 6, + "7" => 7, + "8" => 8, + "9" => 9, + "10" => 10, + "11" => 11, + "12" => 12, + "13" => 13, + "14" => 14, + "15" => 15, + "16" => 16, + "17" => 17, + "18" => 18, + "19" => 19, + "20" => 20, + "21" => 21, + "22" => 22, + "23" => 23, + "24" => 24, + "25" => 25, + "26" => 26, + "27" => 27, + "28" => 28, + "29" => 29, + "30" => 30, + "31" => 31, + "32" => 32, + "33" => 33, + "34" => 34, + "35" => 35, + "36" => 36, + "37" => 37, + "38" => 38, + "39" => 39, + "40" => 40, + "41" => 41, + "42" => 42, + "43" => 43, + "44" => 44, + "45" => 45, + "46" => 46, + "47" => 47, + "48" => 48, + "49" => 49, + "50" => 50, + "51" => 51, + "52" => 52, + "53" => 53, + "54" => 54, + "55" => 55, + "56" => 56, + "57" => 57, + "58" => 58, + "59" => 59, + "60" => 60, + "61" => 61, + "62" => 62, + "63" => 63, + "64" => 64, + "65" => 65, + "66" => 66, + "67" => 67, + "68" => 68, + "69" => 69, + "70" => 70, + "71" => 71, + "72" => 72, + "73" => 73, + "74" => 74, + "75" => 75, + "76" => 76, + "77" => 77, + "78" => 78, + "79" => 79, + "80" => 80, + "81" => 81, + "82" => 82, + "83" => 83, + "84" => 84, + "85" => 85, + "86" => 86, + "87" => 87, + "88" => 88, + "89" => 89, + "90" => 90, + "91" => 91, + "92" => 92, + "93" => 93, + "94" => 94, + "95" => 95, + "96" => 96, + "97" => 97, + "98" => 98, + "99" => 99, + "100" => 100, + "101" => 101, + "102" => 102, + "103" => 103, + "104" => 104, + "105" => 105, + "106" => 106, + "107" => 107, + "108" => 108, + "109" => 109, + "110" => 110, + "111" => 111, + "112" => 112, + "113" => 113, + "114" => 114, + "115" => 115, + "116" => 116, + "117" => 117, + "118" => 118, + "119" => 119, + "120" => 120, + "121" => 121, + "122" => 122, + "123" => 123, + "124" => 124, + "125" => 125, + "126" => 126, + "127" => 127, + "128" => 128, + "129" => 129, + "130" => 130, + "131" => 131, + "132" => 132, + "133" => 133, + "134" => 134, + "135" => 135, + "136" => 136, + "137" => 137, + "138" => 138, + "139" => 139, + "140" => 140, + "141" => 141, + "142" => 142, + "143" => 143, + "144" => 144, + "145" => 145, + "146" => 146, + "147" => 147, + "148" => 148, + "149" => 149, + "150" => 150, + "151" => 151, + "152" => 152, + "153" => 153, + "154" => 154, + "155" => 155, + "156" => 156, + "157" => 157, + "158" => 158, + "159" => 159, + "160" => 160, + "161" => 161, + "162" => 162, + "163" => 163, + "164" => 164, + "165" => 165, + "166" => 166, + "167" => 167, + "168" => 168, + "169" => 169, + "170" => 170, + "171" => 171, + "172" => 172, + "173" => 173, + "174" => 174, + "175" => 175, + "176" => 176, + "177" => 177, + "178" => 178, + "179" => 179, + "180" => 180, + "181" => 181, + "182" => 182, + "183" => 183, + "184" => 184, + "185" => 185, + "186" => 186, + "187" => 187, + "188" => 188, + "189" => 189, + "190" => 190, + "191" => 191, + "192" => 192, + "193" => 193, + "194" => 194, + "195" => 195, + "196" => 196, + "197" => 197, + "198" => 198, + "199" => 199, + "200" => 200, + "201" => 201, + "202" => 202, + "203" => 203, + "204" => 204, + "205" => 205, + "206" => 206, + "207" => 207, + "208" => 208, + "209" => 209, + "210" => 210, + "211" => 211, + "212" => 212, + "213" => 213, + "214" => 214, + "215" => 215, + "216" => 216, + "217" => 217, + "218" => 218, + "219" => 219, + "220" => 220, + "221" => 221, + "222" => 222, + "223" => 223, + "224" => 224, + "225" => 225, + "226" => 226, + "227" => 227, + "228" => 228, + "229" => 229, + "230" => 230, + "231" => 231, + "232" => 232, + "233" => 233, + "234" => 234, + "235" => 235, + "236" => 236, + "237" => 237, + "238" => 238, + "239" => 239, + "240" => 240, + "241" => 241, + "242" => 242, + "243" => 243, + "244" => 244, + "245" => 245, + "246" => 246, + "247" => 247, + "248" => 248, + "249" => 249, + "250" => 250, + "251" => 251, + "252" => 252, + "253" => 253, + "254" => 254, + "255" => 255, + "256" => 256, + "257" => 257, + "258" => 258, + "259" => 259, + "260" => 260, + "261" => 261, + "262" => 262, + "263" => 263, + "264" => 264, + "265" => 265, + "266" => 266, + "267" => 267, + "268" => 268, + "269" => 269, + "270" => 270, + "271" => 271, + "272" => 272, + "273" => 273, + "274" => 274, + "275" => 275, + "276" => 276, + "277" => 277, + "278" => 278, + "279" => 279, + "280" => 280, + "281" => 281, + "282" => 282, + "283" => 283, + "284" => 284, + "285" => 285, + "286" => 286, + "287" => 287, + "288" => 288, + "289" => 289, + "290" => 290, + "291" => 291, + "292" => 292, + "293" => 293, + "294" => 294, + "295" => 295, + "296" => 296, + "297" => 297, + "298" => 298, + "299" => 299, + "300" => 300, + "301" => 301, + "302" => 302, + "303" => 303, + "304" => 304, + "305" => 305, + "306" => 306, + "307" => 307, + "308" => 308, + "309" => 309, + "310" => 310, + "311" => 311, + "312" => 312, + "313" => 313, + "314" => 314, + "315" => 315, + "316" => 316, + "317" => 317, + "318" => 318, + "319" => 319, + "320" => 320, + "321" => 321, + "322" => 322, + "323" => 323, + "324" => 324, + "325" => 325, + "326" => 326, + "327" => 327, + "328" => 328, + "329" => 329, + "330" => 330, + "331" => 331, + "332" => 332, + "333" => 333, + "334" => 334, + "335" => 335, + "336" => 336, + "337" => 337, + "338" => 338, + "339" => 339, + "340" => 340, + "341" => 341, + "342" => 342, + "343" => 343, + "344" => 344, + "345" => 345, + "346" => 346, + "347" => 347, + "348" => 348, + "349" => 349, + "350" => 350, + "351" => 351, + "352" => 352, + "353" => 353, + "354" => 354, + "355" => 355, + "356" => 356, + "357" => 357, + "358" => 358, + "359" => 359, + "360" => 360, + "361" => 361, + "362" => 362, + "363" => 363, + "364" => 364, + "365" => 365, + "366" => 366, + "367" => 367, + "368" => 368, + "369" => 369, + "370" => 370, + "371" => 371, + "372" => 372, + "373" => 373, + "374" => 374, + "375" => 375, + "376" => 376, + "377" => 377, + "378" => 378, + "379" => 379, + "380" => 380, + "381" => 381, + "382" => 382, + "383" => 383, + "384" => 384, + "385" => 385, + "386" => 386, + "387" => 387, + "388" => 388, + "389" => 389, + "390" => 390, + "391" => 391, + "392" => 392, + "393" => 393, + "394" => 394, + "395" => 395, + "396" => 396, + "397" => 397, + "398" => 398, + "399" => 399, + "400" => 400, + "401" => 401, + "402" => 402, + "403" => 403, + "404" => 404, + "405" => 405, + "406" => 406, + "407" => 407, + "408" => 408, + "409" => 409, + "410" => 410, + "411" => 411, + "412" => 412, + "413" => 413, + "414" => 414, + "415" => 415, + "416" => 416, + "417" => 417, + "418" => 418, + "419" => 419, + "420" => 420, + "421" => 421, + "422" => 422, + "423" => 423, + "424" => 424, + "425" => 425, + "426" => 426, + "427" => 427, + "428" => 428, + "429" => 429, + "430" => 430, + "431" => 431, + "432" => 432, + "433" => 433, + "434" => 434, + "435" => 435, + "436" => 436, + "437" => 437, + "438" => 438, + "439" => 439, + "440" => 440, + "441" => 441, + "442" => 442, + "443" => 443, + "444" => 444, + "445" => 445, + "446" => 446, + "447" => 447, + "448" => 448, + "449" => 449, + "450" => 450, + "451" => 451, + "452" => 452, + "453" => 453, + "454" => 454, + "455" => 455, + "456" => 456, + "457" => 457, + "458" => 458, + "459" => 459, + "460" => 460, + "461" => 461, + "462" => 462, + "463" => 463, + "464" => 464, + "465" => 465, + "466" => 466, + "467" => 467, + "468" => 468, + "469" => 469, + "470" => 470, + "471" => 471, + "472" => 472, + "473" => 473, + "474" => 474, + "475" => 475, + "476" => 476, + "477" => 477, + "478" => 478, + "479" => 479, + "480" => 480, + "481" => 481, + "482" => 482, + "483" => 483, + "484" => 484, + "485" => 485, + "486" => 486, + "487" => 487, + "488" => 488, + "489" => 489, + "490" => 490, + "491" => 491, + "492" => 492, + "493" => 493, + "494" => 494, + "495" => 495, + "496" => 496, + "497" => 497, + "498" => 498, + "499" => 499, + "500" => 500, + "501" => 501, + "502" => 502, + "503" => 503, + "504" => 504, + "505" => 505, + "506" => 506, + "507" => 507, + "508" => 508, + "509" => 509, + "510" => 510, + "511" => 511, + "512" => 512, + "513" => 513, + "514" => 514, + "515" => 515, + "516" => 516, + "517" => 517, + "518" => 518, + "519" => 519, + "520" => 520, + "521" => 521, + "522" => 522, + "523" => 523, + "524" => 524, + "525" => 525, + "526" => 526, + "527" => 527, + "528" => 528, + "529" => 529, + "530" => 530, + "531" => 531, + "532" => 532, + "533" => 533, + "534" => 534, + "535" => 535, + "536" => 536, + "537" => 537, + "538" => 538, + "539" => 539, + "540" => 540, + "541" => 541, + "542" => 542, + "543" => 543, + "544" => 544, + "545" => 545, + "546" => 546, + "547" => 547, + "548" => 548, + "549" => 549, + "550" => 550, + "551" => 551, + "552" => 552, + "553" => 553, + "554" => 554, + "555" => 555, + "556" => 556, + "557" => 557, + "558" => 558, + "559" => 559, + "560" => 560, + "561" => 561, + "562" => 562, + "563" => 563, + "564" => 564, + "565" => 565, + "566" => 566, + "567" => 567, + "568" => 568, + "569" => 569, + "570" => 570, + "571" => 571, + "572" => 572, + "573" => 573, + "574" => 574, + "575" => 575, + "576" => 576, + "577" => 577, + "578" => 578, + "579" => 579, + "580" => 580, + "581" => 581, + "582" => 582, + "583" => 583, + "584" => 584, + "585" => 585, + "586" => 586, + "587" => 587, + "588" => 588, + "589" => 589, + "590" => 590, + "591" => 591, + "592" => 592, + "593" => 593, + "594" => 594, + "595" => 595, + "596" => 596, + "597" => 597, + "598" => 598, + "599" => 599, + "600" => 600, + "601" => 601, + "602" => 602, + "603" => 603, + "604" => 604, + "605" => 605, + "606" => 606, + "607" => 607, + "608" => 608, + "609" => 609, + "610" => 610, + "611" => 611, + "612" => 612, + "613" => 613, + "614" => 614, + "615" => 615, + "616" => 616, + "617" => 617, + "618" => 618, + "619" => 619, + "620" => 620, + "621" => 621, + "622" => 622, + "623" => 623, + "624" => 624, + "625" => 625, + "626" => 626, + "627" => 627, + "628" => 628, + "629" => 629, + "630" => 630, + "631" => 631, + "632" => 632, + "633" => 633, + "634" => 634, + "635" => 635, + "636" => 636, + "637" => 637, + "638" => 638, + "639" => 639, + "640" => 640, + "641" => 641, + "642" => 642, + "643" => 643, + "644" => 644, + "645" => 645, + "646" => 646, + "647" => 647, + "648" => 648, + "649" => 649, + "650" => 650, + "651" => 651, + "652" => 652, + "653" => 653, + "654" => 654, + "655" => 655, + "656" => 656, + "657" => 657, + "658" => 658, + "659" => 659, + "660" => 660, + "661" => 661, + "662" => 662, + "663" => 663, + "664" => 664, + "665" => 665, + "666" => 666, + "667" => 667, + "668" => 668, + "669" => 669, + "670" => 670, + "671" => 671, + "672" => 672, + "673" => 673, + "674" => 674, + "675" => 675, + "676" => 676, + "677" => 677, + "678" => 678, + "679" => 679, + "680" => 680, + "681" => 681, + "682" => 682, + "683" => 683, + "684" => 684, + "685" => 685, + "686" => 686, + "687" => 687, + "688" => 688, + "689" => 689, + "690" => 690, + "691" => 691, + "692" => 692, + "693" => 693, + "694" => 694, + "695" => 695, + "696" => 696, + "697" => 697, + "698" => 698, + "699" => 699, + "700" => 700, + "701" => 701, + "702" => 702, + "703" => 703, + "704" => 704, + "705" => 705, + "706" => 706, + "707" => 707, + "708" => 708, + "709" => 709, + "710" => 710, + "711" => 711, + "712" => 712, + "713" => 713, + "714" => 714, + "715" => 715, + "716" => 716, + "717" => 717, + "718" => 718, + "719" => 719, + "720" => 720, + "721" => 721, + "722" => 722, + "723" => 723, + "724" => 724, + "725" => 725, + "726" => 726, + "727" => 727, + "728" => 728, + "729" => 729, + "730" => 730, + "731" => 731, + "732" => 732, + "733" => 733, + "734" => 734, + "735" => 735, + "736" => 736, + "737" => 737, + "738" => 738, + "739" => 739, + "740" => 740, + "741" => 741, + "742" => 742, + "743" => 743, + "744" => 744, + "745" => 745, + "746" => 746, + "747" => 747, + "748" => 748, + "749" => 749, + "750" => 750, + "751" => 751, + "752" => 752, + "753" => 753, + "754" => 754, + "755" => 755, + "756" => 756, + "757" => 757, + "758" => 758, + "759" => 759, + "760" => 760, + "761" => 761, + "762" => 762, + "763" => 763, + "764" => 764, + "765" => 765, + "766" => 766, + "767" => 767, + "768" => 768, + "769" => 769, + "770" => 770, + "771" => 771, + "772" => 772, + "773" => 773, + "774" => 774, + "775" => 775, + "776" => 776, + "777" => 777, + "778" => 778, + "779" => 779, + "780" => 780, + "781" => 781, + "782" => 782, + "783" => 783, + "784" => 784, + "785" => 785, + "786" => 786, + "787" => 787, + "788" => 788, + "789" => 789, + "790" => 790, + "791" => 791, + "792" => 792, + "793" => 793, + "794" => 794, + "795" => 795, + "796" => 796, + "797" => 797, + "798" => 798, + "799" => 799, + "800" => 800, + "801" => 801, + "802" => 802, + "803" => 803, + "804" => 804, + "805" => 805, + "806" => 806, + "807" => 807, + "808" => 808, + "809" => 809, + "810" => 810, + "811" => 811, + "812" => 812, + "813" => 813, + "814" => 814, + "815" => 815, + "816" => 816, + "817" => 817, + "818" => 818, + "819" => 819, + "820" => 820, + "821" => 821, + "822" => 822, + "823" => 823, + "824" => 824, + "825" => 825, + "826" => 826, + "827" => 827, + "828" => 828, + "829" => 829, + "830" => 830, + "831" => 831, + "832" => 832, + "833" => 833, + "834" => 834, + "835" => 835, + "836" => 836, + "837" => 837, + "838" => 838, + "839" => 839, + "840" => 840, + "841" => 841, + "842" => 842, + "843" => 843, + "844" => 844, + "845" => 845, + "846" => 846, + "847" => 847, + "848" => 848, + "849" => 849, + "850" => 850, + "851" => 851, + "852" => 852, + "853" => 853, + "854" => 854, + "855" => 855, + "856" => 856, + "857" => 857, + "858" => 858, + "859" => 859, + "860" => 860, + "861" => 861, + "862" => 862, + "863" => 863, + "864" => 864, + "865" => 865, + "866" => 866, + "867" => 867, + "868" => 868, + "869" => 869, + "870" => 870, + "871" => 871, + "872" => 872, + "873" => 873, + "874" => 874, + "875" => 875, + "876" => 876, + "877" => 877, + "878" => 878, + "879" => 879, + "880" => 880, + "881" => 881, + "882" => 882, + "883" => 883, + "884" => 884, + "885" => 885, + "886" => 886, + "887" => 887, + "888" => 888, + "889" => 889, + "890" => 890, + "891" => 891, + "892" => 892, + "893" => 893, + "894" => 894, + "895" => 895, + "896" => 896, + "897" => 897, + "898" => 898, + "899" => 899, + "900" => 900, + "901" => 901, + "902" => 902, + "903" => 903, + "904" => 904, + "905" => 905, + "906" => 906, + "907" => 907, + "908" => 908, + "909" => 909, + "910" => 910, + "911" => 911, + "912" => 912, + "913" => 913, + "914" => 914, + "915" => 915, + "916" => 916, + "917" => 917, + "918" => 918, + "919" => 919, + "920" => 920, + "921" => 921, + "922" => 922, + "923" => 923, + "924" => 924, + "925" => 925, + "926" => 926, + "927" => 927, + "928" => 928, + "929" => 929, + "930" => 930, + "931" => 931, + "932" => 932, + "933" => 933, + "934" => 934, + "935" => 935, + "936" => 936, + "937" => 937, + "938" => 938, + "939" => 939, + "940" => 940, + "941" => 941, + "942" => 942, + "943" => 943, + "944" => 944, + "945" => 945, + "946" => 946, + "947" => 947, + "948" => 948, + "949" => 949, + "950" => 950, + "951" => 951, + "952" => 952, + "953" => 953, + "954" => 954, + "955" => 955, + "956" => 956, + "957" => 957, + "958" => 958, + "959" => 959, + "960" => 960, + "961" => 961, + "962" => 962, + "963" => 963, + "964" => 964, + "965" => 965, + "966" => 966, + "967" => 967, + "968" => 968, + "969" => 969, + "970" => 970, + "971" => 971, + "972" => 972, + "973" => 973, + "974" => 974, + "975" => 975, + "976" => 976, + "977" => 977, + "978" => 978, + "979" => 979, + "980" => 980, + "981" => 981, + "982" => 982, + "983" => 983, + "984" => 984, + "985" => 985, + "986" => 986, + "987" => 987, + "988" => 988, + "989" => 989, + "990" => 990, + "991" => 991, + "992" => 992, + "993" => 993, + "994" => 994, + "995" => 995, + "996" => 996, + "997" => 997, + "998" => 998, + "999" => 999, + "1000" => 1000, + "1001" => 1001, + "1002" => 1002, + "1003" => 1003, + "1004" => 1004, + "1005" => 1005, + "1006" => 1006, + "1007" => 1007, + "1008" => 1008, + "1009" => 1009, + "1010" => 1010, + "1011" => 1011, + "1012" => 1012, + "1013" => 1013, + "1014" => 1014, + "1015" => 1015, + "1016" => 1016, + "1017" => 1017, + "1018" => 1018, + "1019" => 1019, + "1020" => 1020, + "1021" => 1021, + "1022" => 1022, + "1023" => 1023, + "1024" => 1024, + "1025" => 1025, + "1026" => 1026, + "1027" => 1027, + "1028" => 1028, + "1029" => 1029, + "1030" => 1030, + "1031" => 1031, + "1032" => 1032, + "1033" => 1033, + "1034" => 1034, + "1035" => 1035, + "1036" => 1036, + "1037" => 1037, + "1038" => 1038, + "1039" => 1039, + "1040" => 1040, + "1041" => 1041, + "1042" => 1042, + "1043" => 1043, + "1044" => 1044, + "1045" => 1045, + "1046" => 1046, + "1047" => 1047, + "1048" => 1048, + "1049" => 1049, + "1050" => 1050, + "1051" => 1051, + "1052" => 1052, + "1053" => 1053, + "1054" => 1054, + "1055" => 1055, + "1056" => 1056, + "1057" => 1057, + "1058" => 1058, + "1059" => 1059, + "1060" => 1060, + "1061" => 1061, + "1062" => 1062, + "1063" => 1063, + "1064" => 1064, + "1065" => 1065, + "1066" => 1066, + "1067" => 1067, + "1068" => 1068, + "1069" => 1069, + "1070" => 1070, + "1071" => 1071, + "1072" => 1072, + "1073" => 1073, + "1074" => 1074, + "1075" => 1075, + "1076" => 1076, + "1077" => 1077, + "1078" => 1078, + "1079" => 1079, + "1080" => 1080, + "1081" => 1081, + "1082" => 1082, + "1083" => 1083, + "1084" => 1084, + "1085" => 1085, + "1086" => 1086, + "1087" => 1087, + "1088" => 1088, + "1089" => 1089, + "1090" => 1090, + "1091" => 1091, + "1092" => 1092, + "1093" => 1093, + "1094" => 1094, + "1095" => 1095, + "1096" => 1096, + "1097" => 1097, + "1098" => 1098, + "1099" => 1099, + "1100" => 1100, + "1101" => 1101, + "1102" => 1102, + "1103" => 1103, + "1104" => 1104, + "1105" => 1105, + "1106" => 1106, + "1107" => 1107, + "1108" => 1108, + "1109" => 1109, + "1110" => 1110, + "1111" => 1111, + "1112" => 1112, + "1113" => 1113, + "1114" => 1114, + "1115" => 1115, + "1116" => 1116, + "1117" => 1117, + "1118" => 1118, + "1119" => 1119, + "1120" => 1120, + "1121" => 1121, + "1122" => 1122, + "1123" => 1123, + "1124" => 1124, + "1125" => 1125, + "1126" => 1126, + "1127" => 1127, + "1128" => 1128, + "1129" => 1129, + "1130" => 1130, + "1131" => 1131, + "1132" => 1132, + "1133" => 1133, + "1134" => 1134, + "1135" => 1135, + "1136" => 1136, + "1137" => 1137, + "1138" => 1138, + "1139" => 1139, + "1140" => 1140, + "1141" => 1141, + "1142" => 1142, + "1143" => 1143, + "1144" => 1144, + "1145" => 1145, + "1146" => 1146, + "1147" => 1147, + "1148" => 1148, + "1149" => 1149, + "1150" => 1150, + "1151" => 1151, + "1152" => 1152, + "1153" => 1153, + "1154" => 1154, + "1155" => 1155, + "1156" => 1156, + "1157" => 1157, + "1158" => 1158, + "1159" => 1159, + "1160" => 1160, + "1161" => 1161, + "1162" => 1162, + "1163" => 1163, + "1164" => 1164, + "1165" => 1165, + "1166" => 1166, + "1167" => 1167, + "1168" => 1168, + "1169" => 1169, + "1170" => 1170, + "1171" => 1171, + "1172" => 1172, + "1173" => 1173, + "1174" => 1174, + "1175" => 1175, + "1176" => 1176, + "1177" => 1177, + "1178" => 1178, + "1179" => 1179, + "1180" => 1180, + "1181" => 1181, + "1182" => 1182, + "1183" => 1183, + "1184" => 1184, + "1185" => 1185, + "1186" => 1186, + "1187" => 1187, + "1188" => 1188, + "1189" => 1189, + "1190" => 1190, + "1191" => 1191, + "1192" => 1192, + "1193" => 1193, + "1194" => 1194, + "1195" => 1195, + "1196" => 1196, + "1197" => 1197, + "1198" => 1198, + "1199" => 1199, + "1200" => 1200, + "1201" => 1201, + "1202" => 1202, + "1203" => 1203, + "1204" => 1204, + "1205" => 1205, + "1206" => 1206, + "1207" => 1207, + "1208" => 1208, + "1209" => 1209, + "1210" => 1210, + "1211" => 1211, + "1212" => 1212, + "1213" => 1213, + "1214" => 1214, + "1215" => 1215, + "1216" => 1216, + "1217" => 1217, + "1218" => 1218, + "1219" => 1219, + "1220" => 1220, + "1221" => 1221, + "1222" => 1222, + "1223" => 1223, + "1224" => 1224, + "1225" => 1225, + "1226" => 1226, + "1227" => 1227, + "1228" => 1228, + "1229" => 1229, + "1230" => 1230, + "1231" => 1231, + "1232" => 1232, + "1233" => 1233, + "1234" => 1234, + "1235" => 1235, + "1236" => 1236, + "1237" => 1237, + "1238" => 1238, + "1239" => 1239, + "1240" => 1240, + "1241" => 1241, + "1242" => 1242, + "1243" => 1243, + "1244" => 1244, + "1245" => 1245, + "1246" => 1246, + "1247" => 1247, + "1248" => 1248, + "1249" => 1249, + "1250" => 1250, + "1251" => 1251, + "1252" => 1252, + "1253" => 1253, + "1254" => 1254, + "1255" => 1255, + "1256" => 1256, + "1257" => 1257, + "1258" => 1258, + "1259" => 1259, + "1260" => 1260, + "1261" => 1261, + "1262" => 1262, + "1263" => 1263, + "1264" => 1264, + "1265" => 1265, + "1266" => 1266, + "1267" => 1267, + "1268" => 1268, + "1269" => 1269, + "1270" => 1270, + "1271" => 1271, + "1272" => 1272, + "1273" => 1273, + "1274" => 1274, + "1275" => 1275, + "1276" => 1276, + "1277" => 1277, + "1278" => 1278, + "1279" => 1279, + "1280" => 1280, + "1281" => 1281, + "1282" => 1282, + "1283" => 1283, + "1284" => 1284, + "1285" => 1285, + "1286" => 1286, + "1287" => 1287, + "1288" => 1288, + "1289" => 1289, + "1290" => 1290, + "1291" => 1291, + "1292" => 1292, + "1293" => 1293, + "1294" => 1294, + "1295" => 1295, + "1296" => 1296, + "1297" => 1297, + "1298" => 1298, + "1299" => 1299, + "1300" => 1300, + "1301" => 1301, + "1302" => 1302, + "1303" => 1303, + "1304" => 1304, + "1305" => 1305, + "1306" => 1306, + "1307" => 1307, + "1308" => 1308, + "1309" => 1309, + "1310" => 1310, + "1311" => 1311, + "1312" => 1312, + "1313" => 1313, + "1314" => 1314, + "1315" => 1315, + "1316" => 1316, + "1317" => 1317, + "1318" => 1318, + "1319" => 1319, + "1320" => 1320, + "1321" => 1321, + "1322" => 1322, + "1323" => 1323, + "1324" => 1324, + "1325" => 1325, + "1326" => 1326, + "1327" => 1327, + "1328" => 1328, + "1329" => 1329, + "1330" => 1330, + "1331" => 1331, + "1332" => 1332, + "1333" => 1333, + "1334" => 1334, + "1335" => 1335, + "1336" => 1336, + "1337" => 1337, + "1338" => 1338, + "1339" => 1339, + "1340" => 1340, + "1341" => 1341, + "1342" => 1342, + "1343" => 1343, + "1344" => 1344, + "1345" => 1345, + "1346" => 1346, + "1347" => 1347, + "1348" => 1348, + "1349" => 1349, + "1350" => 1350, + "1351" => 1351, + "1352" => 1352, + "1353" => 1353, + "1354" => 1354, + "1355" => 1355, + "1356" => 1356, + "1357" => 1357, + "1358" => 1358, + "1359" => 1359, + "1360" => 1360, + "1361" => 1361, + "1362" => 1362, + "1363" => 1363, + "1364" => 1364, + "1365" => 1365, + "1366" => 1366, + "1367" => 1367, + "1368" => 1368, + "1369" => 1369, + "1370" => 1370, + "1371" => 1371, + "1372" => 1372, + "1373" => 1373, + "1374" => 1374, + "1375" => 1375, + "1376" => 1376, + "1377" => 1377, + "1378" => 1378, + "1379" => 1379, + "1380" => 1380, + "1381" => 1381, + "1382" => 1382, + "1383" => 1383, + "1384" => 1384, + "1385" => 1385, + "1386" => 1386, + "1387" => 1387, + "1388" => 1388, + "1389" => 1389, + "1390" => 1390, + "1391" => 1391, + "1392" => 1392, + "1393" => 1393, + "1394" => 1394, + "1395" => 1395, + "1396" => 1396, + "1397" => 1397, + "1398" => 1398, + "1399" => 1399, + "1400" => 1400, + "1401" => 1401, + "1402" => 1402, + "1403" => 1403, + "1404" => 1404, + "1405" => 1405, + "1406" => 1406, + "1407" => 1407, + "1408" => 1408, + "1409" => 1409, + "1410" => 1410, + "1411" => 1411, + "1412" => 1412, + "1413" => 1413, + "1414" => 1414, + "1415" => 1415, + "1416" => 1416, + "1417" => 1417, + "1418" => 1418, + "1419" => 1419, + "1420" => 1420, + "1421" => 1421, + "1422" => 1422, + "1423" => 1423, + "1424" => 1424, + "1425" => 1425, + "1426" => 1426, + "1427" => 1427, + "1428" => 1428, + "1429" => 1429, + "1430" => 1430, + "1431" => 1431, + "1432" => 1432, + "1433" => 1433, + "1434" => 1434, + "1435" => 1435, + "1436" => 1436, + "1437" => 1437, + "1438" => 1438, + "1439" => 1439, + "1440" => 1440, + "1441" => 1441, + "1442" => 1442, + "1443" => 1443, + "1444" => 1444, + "1445" => 1445, + "1446" => 1446, + "1447" => 1447, + "1448" => 1448, + "1449" => 1449, + "1450" => 1450, + "1451" => 1451, + "1452" => 1452, + "1453" => 1453, + "1454" => 1454, + "1455" => 1455, + "1456" => 1456, + "1457" => 1457, + "1458" => 1458, + "1459" => 1459, + "1460" => 1460, + "1461" => 1461, + "1462" => 1462, + "1463" => 1463, + "1464" => 1464, + "1465" => 1465, + "1466" => 1466, + "1467" => 1467, + "1468" => 1468, + "1469" => 1469, + "1470" => 1470, + "1471" => 1471, + "1472" => 1472, + "1473" => 1473, + "1474" => 1474, + "1475" => 1475, + "1476" => 1476, + "1477" => 1477, + "1478" => 1478, + "1479" => 1479, + "1480" => 1480, + "1481" => 1481, + "1482" => 1482, + "1483" => 1483, + "1484" => 1484, + "1485" => 1485, + "1486" => 1486, + "1487" => 1487, + "1488" => 1488, + "1489" => 1489, + "1490" => 1490, + "1491" => 1491, + "1492" => 1492, + "1493" => 1493, + "1494" => 1494, + "1495" => 1495, + "1496" => 1496, + "1497" => 1497, + "1498" => 1498, + "1499" => 1499, + "1500" => 1500, + "1501" => 1501, + "1502" => 1502, + "1503" => 1503, + "1504" => 1504, + "1505" => 1505, + "1506" => 1506, + "1507" => 1507, + "1508" => 1508, + "1509" => 1509, + "1510" => 1510, + "1511" => 1511, + "1512" => 1512, + "1513" => 1513, + "1514" => 1514, + "1515" => 1515, + "1516" => 1516, + "1517" => 1517, + "1518" => 1518, + "1519" => 1519, + "1520" => 1520, + "1521" => 1521, + "1522" => 1522, + "1523" => 1523, + "1524" => 1524, + "1525" => 1525, + "1526" => 1526, + "1527" => 1527, + "1528" => 1528, + "1529" => 1529, + "1530" => 1530, + "1531" => 1531, + "1532" => 1532, + "1533" => 1533, + "1534" => 1534, + "1535" => 1535, + "1536" => 1536, + "1537" => 1537, + "1538" => 1538, + "1539" => 1539, + "1540" => 1540, + "1541" => 1541, + "1542" => 1542, + "1543" => 1543, + "1544" => 1544, + "1545" => 1545, + "1546" => 1546, + "1547" => 1547, + "1548" => 1548, + "1549" => 1549, + "1550" => 1550, + "1551" => 1551, + "1552" => 1552, + "1553" => 1553, + "1554" => 1554, + "1555" => 1555, + "1556" => 1556, + "1557" => 1557, + "1558" => 1558, + "1559" => 1559, + "1560" => 1560, + "1561" => 1561, + "1562" => 1562, + "1563" => 1563, + "1564" => 1564, + "1565" => 1565, + "1566" => 1566, + "1567" => 1567, + "1568" => 1568, + "1569" => 1569, + "1570" => 1570, + "1571" => 1571, + "1572" => 1572, + "1573" => 1573, + "1574" => 1574, + "1575" => 1575, + "1576" => 1576, + "1577" => 1577, + "1578" => 1578, + "1579" => 1579, + "1580" => 1580, + "1581" => 1581, + "1582" => 1582, + "1583" => 1583, + "1584" => 1584, + "1585" => 1585, + "1586" => 1586, + "1587" => 1587, + "1588" => 1588, + "1589" => 1589, + "1590" => 1590, + "1591" => 1591, + "1592" => 1592, + "1593" => 1593, + "1594" => 1594, + "1595" => 1595, + "1596" => 1596, + "1597" => 1597, + "1598" => 1598, + "1599" => 1599, + "1600" => 1600, + "1601" => 1601, + "1602" => 1602, + "1603" => 1603, + "1604" => 1604, + "1605" => 1605, + "1606" => 1606, + "1607" => 1607, + "1608" => 1608, + "1609" => 1609, + "1610" => 1610, + "1611" => 1611, + "1612" => 1612, + "1613" => 1613, + "1614" => 1614, + "1615" => 1615, + "1616" => 1616, + "1617" => 1617, + "1618" => 1618, + "1619" => 1619, + "1620" => 1620, + "1621" => 1621, + "1622" => 1622, + "1623" => 1623, + "1624" => 1624, + "1625" => 1625, + "1626" => 1626, + "1627" => 1627, + "1628" => 1628, + "1629" => 1629, + "1630" => 1630, + "1631" => 1631, + "1632" => 1632, + "1633" => 1633, + "1634" => 1634, + "1635" => 1635, + "1636" => 1636, + "1637" => 1637, + "1638" => 1638, + "1639" => 1639, + "1640" => 1640, + "1641" => 1641, + "1642" => 1642, + "1643" => 1643, + "1644" => 1644, + "1645" => 1645, + "1646" => 1646, + "1647" => 1647, + "1648" => 1648, + "1649" => 1649, + "1650" => 1650, + "1651" => 1651, + "1652" => 1652, + "1653" => 1653, + "1654" => 1654, + "1655" => 1655, + "1656" => 1656, + "1657" => 1657, + "1658" => 1658, + "1659" => 1659, + "1660" => 1660, + "1661" => 1661, + "1662" => 1662, + "1663" => 1663, + "1664" => 1664, + "1665" => 1665, + "1666" => 1666, + "1667" => 1667, + "1668" => 1668, + "1669" => 1669, + "1670" => 1670, + "1671" => 1671, + "1672" => 1672, + "1673" => 1673, + "1674" => 1674, + "1675" => 1675, + "1676" => 1676, + "1677" => 1677, + "1678" => 1678, + "1679" => 1679, + "1680" => 1680, + "1681" => 1681, + "1682" => 1682, + "1683" => 1683, + "1684" => 1684, + "1685" => 1685, + "1686" => 1686, + "1687" => 1687, + "1688" => 1688, + "1689" => 1689, + "1690" => 1690, + "1691" => 1691, + "1692" => 1692, + "1693" => 1693, + "1694" => 1694, + "1695" => 1695, + "1696" => 1696, + "1697" => 1697, + "1698" => 1698, + "1699" => 1699, + "1700" => 1700, + "1701" => 1701, + "1702" => 1702, + "1703" => 1703, + "1704" => 1704, + "1705" => 1705, + "1706" => 1706, + "1707" => 1707, + "1708" => 1708, + "1709" => 1709, + "1710" => 1710, + "1711" => 1711, + "1712" => 1712, + "1713" => 1713, + "1714" => 1714, + "1715" => 1715, + "1716" => 1716, + "1717" => 1717, + "1718" => 1718, + "1719" => 1719, + "1720" => 1720, + "1721" => 1721, + "1722" => 1722, + "1723" => 1723, + "1724" => 1724, + "1725" => 1725, + "1726" => 1726, + "1727" => 1727, + "1728" => 1728, + "1729" => 1729, + "1730" => 1730, + "1731" => 1731, + "1732" => 1732, + "1733" => 1733, + "1734" => 1734, + "1735" => 1735, + "1736" => 1736, + "1737" => 1737, + "1738" => 1738, + "1739" => 1739, + "1740" => 1740, + "1741" => 1741, + "1742" => 1742, + "1743" => 1743, + "1744" => 1744, + "1745" => 1745, + "1746" => 1746, + "1747" => 1747, + "1748" => 1748, + "1749" => 1749, + "1750" => 1750, + "1751" => 1751, + "1752" => 1752, + "1753" => 1753, + "1754" => 1754, + "1755" => 1755, + "1756" => 1756, + "1757" => 1757, + "1758" => 1758, + "1759" => 1759, + "1760" => 1760, + "1761" => 1761, + "1762" => 1762, + "1763" => 1763, + "1764" => 1764, + "1765" => 1765, + "1766" => 1766, + "1767" => 1767, + "1768" => 1768, + "1769" => 1769, + "1770" => 1770, + "1771" => 1771, + "1772" => 1772, + "1773" => 1773, + "1774" => 1774, + "1775" => 1775, + "1776" => 1776, + "1777" => 1777, + "1778" => 1778, + "1779" => 1779, + "1780" => 1780, + "1781" => 1781, + "1782" => 1782, + "1783" => 1783, + "1784" => 1784, + "1785" => 1785, + "1786" => 1786, + "1787" => 1787, + "1788" => 1788, + "1789" => 1789, + "1790" => 1790, + "1791" => 1791, + "1792" => 1792, + "1793" => 1793, + "1794" => 1794, + "1795" => 1795, + "1796" => 1796, + "1797" => 1797, + "1798" => 1798, + "1799" => 1799, + "1800" => 1800, + "1801" => 1801, + "1802" => 1802, + "1803" => 1803, + "1804" => 1804, + "1805" => 1805, + "1806" => 1806, + "1807" => 1807, + "1808" => 1808, + "1809" => 1809, + "1810" => 1810, + "1811" => 1811, + "1812" => 1812, + "1813" => 1813, + "1814" => 1814, + "1815" => 1815, + "1816" => 1816, + "1817" => 1817, + "1818" => 1818, + "1819" => 1819, + "1820" => 1820, + "1821" => 1821, + "1822" => 1822, + "1823" => 1823, + "1824" => 1824, + "1825" => 1825, + "1826" => 1826, + "1827" => 1827, + "1828" => 1828, + "1829" => 1829, + "1830" => 1830, + "1831" => 1831, + "1832" => 1832, + "1833" => 1833, + "1834" => 1834, + "1835" => 1835, + "1836" => 1836, + "1837" => 1837, + "1838" => 1838, + "1839" => 1839, + "1840" => 1840, + "1841" => 1841, + "1842" => 1842, + "1843" => 1843, + "1844" => 1844, + "1845" => 1845, + "1846" => 1846, + "1847" => 1847, + "1848" => 1848, + "1849" => 1849, + "1850" => 1850, + "1851" => 1851, + "1852" => 1852, + "1853" => 1853, + "1854" => 1854, + "1855" => 1855, + "1856" => 1856, + "1857" => 1857, + "1858" => 1858, + "1859" => 1859, + "1860" => 1860, + "1861" => 1861, + "1862" => 1862, + "1863" => 1863, + "1864" => 1864, + "1865" => 1865, + "1866" => 1866, + "1867" => 1867, + "1868" => 1868, + "1869" => 1869, + "1870" => 1870, + "1871" => 1871, + "1872" => 1872, + "1873" => 1873, + "1874" => 1874, + "1875" => 1875, + "1876" => 1876, + "1877" => 1877, + "1878" => 1878, + "1879" => 1879, + "1880" => 1880, + "1881" => 1881, + "1882" => 1882, + "1883" => 1883, + "1884" => 1884, + "1885" => 1885, + "1886" => 1886, + "1887" => 1887, + "1888" => 1888, + "1889" => 1889, + "1890" => 1890, + "1891" => 1891, + "1892" => 1892, + "1893" => 1893, + "1894" => 1894, + "1895" => 1895, + "1896" => 1896, + "1897" => 1897, + "1898" => 1898, + "1899" => 1899, + "1900" => 1900, + "1901" => 1901, + "1902" => 1902, + "1903" => 1903, + "1904" => 1904, + "1905" => 1905, + "1906" => 1906, + "1907" => 1907, + "1908" => 1908, + "1909" => 1909, + "1910" => 1910, + "1911" => 1911, + "1912" => 1912, + "1913" => 1913, + "1914" => 1914, + "1915" => 1915, + "1916" => 1916, + "1917" => 1917, + "1918" => 1918, + "1919" => 1919, + "1920" => 1920, + "1921" => 1921, + "1922" => 1922, + "1923" => 1923, + "1924" => 1924, + "1925" => 1925, + "1926" => 1926, + "1927" => 1927, + "1928" => 1928, + "1929" => 1929, + "1930" => 1930, + "1931" => 1931, + "1932" => 1932, + "1933" => 1933, + "1934" => 1934, + "1935" => 1935, + "1936" => 1936, + "1937" => 1937, + "1938" => 1938, + "1939" => 1939, + "1940" => 1940, + "1941" => 1941, + "1942" => 1942, + "1943" => 1943, + "1944" => 1944, + "1945" => 1945, + "1946" => 1946, + "1947" => 1947, + "1948" => 1948, + "1949" => 1949, + "1950" => 1950, + "1951" => 1951, + "1952" => 1952, + "1953" => 1953, + "1954" => 1954, + "1955" => 1955, + "1956" => 1956, + "1957" => 1957, + "1958" => 1958, + "1959" => 1959, + "1960" => 1960, + "1961" => 1961, + "1962" => 1962, + "1963" => 1963, + "1964" => 1964, + "1965" => 1965, + "1966" => 1966, + "1967" => 1967, + "1968" => 1968, + "1969" => 1969, + "1970" => 1970, + "1971" => 1971, + "1972" => 1972, + "1973" => 1973, + "1974" => 1974, + "1975" => 1975, + "1976" => 1976, + "1977" => 1977, + "1978" => 1978, + "1979" => 1979, + "1980" => 1980, + "1981" => 1981, + "1982" => 1982, + "1983" => 1983, + "1984" => 1984, + "1985" => 1985, + "1986" => 1986, + "1987" => 1987, + "1988" => 1988, + "1989" => 1989, + "1990" => 1990, + "1991" => 1991, + "1992" => 1992, + "1993" => 1993, + "1994" => 1994, + "1995" => 1995, + "1996" => 1996, + "1997" => 1997, + "1998" => 1998, + "1999" => 1999, + "2000" => 2000, + "2001" => 2001, + "2002" => 2002, + "2003" => 2003, + "2004" => 2004, + "2005" => 2005, + "2006" => 2006, + "2007" => 2007, + "2008" => 2008, + "2009" => 2009, + "2010" => 2010, + "2011" => 2011, + "2012" => 2012, + "2013" => 2013, + "2014" => 2014, + "2015" => 2015, + "2016" => 2016, + "2017" => 2017, + "2018" => 2018, + "2019" => 2019, + "2020" => 2020, + "2021" => 2021, + "2022" => 2022, + "2023" => 2023, + "2024" => 2024, + "2025" => 2025, + "2026" => 2026, + "2027" => 2027, + "2028" => 2028, + "2029" => 2029, + "2030" => 2030, + "2031" => 2031, + "2032" => 2032, + "2033" => 2033, + "2034" => 2034, + "2035" => 2035, + "2036" => 2036, + "2037" => 2037, + "2038" => 2038, + "2039" => 2039, + "2040" => 2040, + "2041" => 2041, + "2042" => 2042, + "2043" => 2043, + "2044" => 2044, + "2045" => 2045, + "2046" => 2046, + "2047" => 2047, + "2048" => 2048, + "2049" => 2049, + "2050" => 2050, + "2051" => 2051, + "2052" => 2052, + "2053" => 2053, + "2054" => 2054, + "2055" => 2055, + "2056" => 2056, + "2057" => 2057, + "2058" => 2058, + "2059" => 2059, + "2060" => 2060, + "2061" => 2061, + "2062" => 2062, + "2063" => 2063, + "2064" => 2064, + "2065" => 2065, + "2066" => 2066, + "2067" => 2067, + "2068" => 2068, + "2069" => 2069, + "2070" => 2070, + "2071" => 2071, + "2072" => 2072, + "2073" => 2073, + "2074" => 2074, + "2075" => 2075, + "2076" => 2076, + "2077" => 2077, + "2078" => 2078, + "2079" => 2079, + "2080" => 2080, + "2081" => 2081, + "2082" => 2082, + "2083" => 2083, + "2084" => 2084, + "2085" => 2085, + "2086" => 2086, + "2087" => 2087, + "2088" => 2088, + "2089" => 2089, + "2090" => 2090, + "2091" => 2091, + "2092" => 2092, + "2093" => 2093, + "2094" => 2094, + "2095" => 2095, + "2096" => 2096, + "2097" => 2097, + "2098" => 2098, + "2099" => 2099, + "2100" => 2100, + "2101" => 2101, + "2102" => 2102, + "2103" => 2103, + "2104" => 2104, + "2105" => 2105, + "2106" => 2106, + "2107" => 2107, + "2108" => 2108, + "2109" => 2109, + "2110" => 2110, + "2111" => 2111, + "2112" => 2112, + "2113" => 2113, + "2114" => 2114, + "2115" => 2115, + "2116" => 2116, + "2117" => 2117, + "2118" => 2118, + "2119" => 2119, + "2120" => 2120, + "2121" => 2121, + "2122" => 2122, + "2123" => 2123, + "2124" => 2124, + "2125" => 2125, + "2126" => 2126, + "2127" => 2127, + "2128" => 2128, + "2129" => 2129, + "2130" => 2130, + "2131" => 2131, + "2132" => 2132, + "2133" => 2133, + "2134" => 2134, + "2135" => 2135, + "2136" => 2136, + "2137" => 2137, + "2138" => 2138, + "2139" => 2139, + "2140" => 2140, + "2141" => 2141, + "2142" => 2142, + "2143" => 2143, + "2144" => 2144, + "2145" => 2145, + "2146" => 2146, + "2147" => 2147, + "2148" => 2148, + "2149" => 2149, + "2150" => 2150, + "2151" => 2151, + "2152" => 2152, + "2153" => 2153, + "2154" => 2154, + "2155" => 2155, + "2156" => 2156, + "2157" => 2157, + "2158" => 2158, + "2159" => 2159, + "2160" => 2160, + "2161" => 2161, + "2162" => 2162, + "2163" => 2163, + "2164" => 2164, + "2165" => 2165, + "2166" => 2166, + "2167" => 2167, + "2168" => 2168, + "2169" => 2169, + "2170" => 2170, + "2171" => 2171, + "2172" => 2172, + "2173" => 2173, + "2174" => 2174, + "2175" => 2175, + "2176" => 2176, + "2177" => 2177, + "2178" => 2178, + "2179" => 2179, + "2180" => 2180, + "2181" => 2181, + "2182" => 2182, + "2183" => 2183, + "2184" => 2184, + "2185" => 2185, + "2186" => 2186, + "2187" => 2187, + "2188" => 2188, + "2189" => 2189, + "2190" => 2190, + "2191" => 2191, + "2192" => 2192, + "2193" => 2193, + "2194" => 2194, + "2195" => 2195, + "2196" => 2196, + "2197" => 2197, + "2198" => 2198, + "2199" => 2199, + "2200" => 2200, + "2201" => 2201, + "2202" => 2202, + "2203" => 2203, + "2204" => 2204, + "2205" => 2205, + "2206" => 2206, + "2207" => 2207, + "2208" => 2208, + "2209" => 2209, + "2210" => 2210, + "2211" => 2211, + "2212" => 2212, + "2213" => 2213, + "2214" => 2214, + "2215" => 2215, + "2216" => 2216, + "2217" => 2217, + "2218" => 2218, + "2219" => 2219, + "2220" => 2220, + "2221" => 2221, + "2222" => 2222, + "2223" => 2223, + "2224" => 2224, + "2225" => 2225, + "2226" => 2226, + "2227" => 2227, + "2228" => 2228, + "2229" => 2229, + "2230" => 2230, + "2231" => 2231, + "2232" => 2232, + "2233" => 2233, + "2234" => 2234, + "2235" => 2235, + "2236" => 2236, + "2237" => 2237, + "2238" => 2238, + "2239" => 2239, + "2240" => 2240, + "2241" => 2241, + "2242" => 2242, + "2243" => 2243, + "2244" => 2244, + "2245" => 2245, + "2246" => 2246, + "2247" => 2247, + "2248" => 2248, + "2249" => 2249, + "2250" => 2250, + "2251" => 2251, + "2252" => 2252, + "2253" => 2253, + "2254" => 2254, + "2255" => 2255, + "2256" => 2256, + "2257" => 2257, + "2258" => 2258, + "2259" => 2259, + "2260" => 2260, + "2261" => 2261, + "2262" => 2262, + "2263" => 2263, + "2264" => 2264, + "2265" => 2265, + "2266" => 2266, + "2267" => 2267, + "2268" => 2268, + "2269" => 2269, + "2270" => 2270, + "2271" => 2271, + "2272" => 2272, + "2273" => 2273, + "2274" => 2274, + "2275" => 2275, + "2276" => 2276, + "2277" => 2277, + "2278" => 2278, + "2279" => 2279, + "2280" => 2280, + "2281" => 2281, + "2282" => 2282, + "2283" => 2283, + "2284" => 2284, + "2285" => 2285, + "2286" => 2286, + "2287" => 2287, + "2288" => 2288, + "2289" => 2289, + "2290" => 2290, + "2291" => 2291, + "2292" => 2292, + "2293" => 2293, + "2294" => 2294, + "2295" => 2295, + "2296" => 2296, + "2297" => 2297, + "2298" => 2298, + "2299" => 2299, + "2300" => 2300, + "2301" => 2301, + "2302" => 2302, + "2303" => 2303, + "2304" => 2304, + "2305" => 2305, + "2306" => 2306, + "2307" => 2307, + "2308" => 2308, + "2309" => 2309, + "2310" => 2310, + "2311" => 2311, + "2312" => 2312, + "2313" => 2313, + "2314" => 2314, + "2315" => 2315, + "2316" => 2316, + "2317" => 2317, + "2318" => 2318, + "2319" => 2319, + "2320" => 2320, + "2321" => 2321, + "2322" => 2322, + "2323" => 2323, + "2324" => 2324, + "2325" => 2325, + "2326" => 2326, + "2327" => 2327, + "2328" => 2328, + "2329" => 2329, + "2330" => 2330, + "2331" => 2331, + "2332" => 2332, + "2333" => 2333, + "2334" => 2334, + "2335" => 2335, + "2336" => 2336, + "2337" => 2337, + "2338" => 2338, + "2339" => 2339, + "2340" => 2340, + "2341" => 2341, + "2342" => 2342, + "2343" => 2343, + "2344" => 2344, + "2345" => 2345, + "2346" => 2346, + "2347" => 2347, + "2348" => 2348, + "2349" => 2349, + "2350" => 2350, + "2351" => 2351, + "2352" => 2352, + "2353" => 2353, + "2354" => 2354, + "2355" => 2355, + "2356" => 2356, + "2357" => 2357, + "2358" => 2358, + "2359" => 2359, + "2360" => 2360, + "2361" => 2361, + "2362" => 2362, + "2363" => 2363, + "2364" => 2364, + "2365" => 2365, + "2366" => 2366, + "2367" => 2367, + "2368" => 2368, + "2369" => 2369, + "2370" => 2370, + "2371" => 2371, + "2372" => 2372, + "2373" => 2373, + "2374" => 2374, + "2375" => 2375, + "2376" => 2376, + "2377" => 2377, + "2378" => 2378, + "2379" => 2379, + "2380" => 2380, + "2381" => 2381, + "2382" => 2382, + "2383" => 2383, + "2384" => 2384, + "2385" => 2385, + "2386" => 2386, + "2387" => 2387, + "2388" => 2388, + "2389" => 2389, + "2390" => 2390, + "2391" => 2391, + "2392" => 2392, + "2393" => 2393, + "2394" => 2394, + "2395" => 2395, + "2396" => 2396, + "2397" => 2397, + "2398" => 2398, + "2399" => 2399, + "2400" => 2400, + "2401" => 2401, + "2402" => 2402, + "2403" => 2403, + "2404" => 2404, + "2405" => 2405, + "2406" => 2406, + "2407" => 2407, + "2408" => 2408, + "2409" => 2409, + "2410" => 2410, + "2411" => 2411, + "2412" => 2412, + "2413" => 2413, + "2414" => 2414, + "2415" => 2415, + "2416" => 2416, + "2417" => 2417, + "2418" => 2418, + "2419" => 2419, + "2420" => 2420, + "2421" => 2421, + "2422" => 2422, + "2423" => 2423, + "2424" => 2424, + "2425" => 2425, + "2426" => 2426, + "2427" => 2427, + "2428" => 2428, + "2429" => 2429, + "2430" => 2430, + "2431" => 2431, + "2432" => 2432, + "2433" => 2433, + "2434" => 2434, + "2435" => 2435, + "2436" => 2436, + "2437" => 2437, + "2438" => 2438, + "2439" => 2439, + "2440" => 2440, + "2441" => 2441, + "2442" => 2442, + "2443" => 2443, + "2444" => 2444, + "2445" => 2445, + "2446" => 2446, + "2447" => 2447, + "2448" => 2448, + "2449" => 2449, + "2450" => 2450, + "2451" => 2451, + "2452" => 2452, + "2453" => 2453, + "2454" => 2454, + "2455" => 2455, + "2456" => 2456, + "2457" => 2457, + "2458" => 2458, + "2459" => 2459, + "2460" => 2460, + "2461" => 2461, + "2462" => 2462, + "2463" => 2463, + "2464" => 2464, + "2465" => 2465, + "2466" => 2466, + "2467" => 2467, + "2468" => 2468, + "2469" => 2469, + "2470" => 2470, + "2471" => 2471, + "2472" => 2472, + "2473" => 2473, + "2474" => 2474, + "2475" => 2475, + "2476" => 2476, + "2477" => 2477, + "2478" => 2478, + "2479" => 2479, + "2480" => 2480, + "2481" => 2481, + "2482" => 2482, + "2483" => 2483, + "2484" => 2484, + "2485" => 2485, + "2486" => 2486, + "2487" => 2487, + "2488" => 2488, + "2489" => 2489, + "2490" => 2490, + "2491" => 2491, + "2492" => 2492, + "2493" => 2493, + "2494" => 2494, + "2495" => 2495, + "2496" => 2496, + "2497" => 2497, + "2498" => 2498, + "2499" => 2499, + "2500" => 2500, + "2501" => 2501, + "2502" => 2502, + "2503" => 2503, + "2504" => 2504, + "2505" => 2505, + "2506" => 2506, + "2507" => 2507, + "2508" => 2508, + "2509" => 2509, + "2510" => 2510, + "2511" => 2511, + "2512" => 2512, + "2513" => 2513, + "2514" => 2514, + "2515" => 2515, + "2516" => 2516, + "2517" => 2517, + "2518" => 2518, + "2519" => 2519, + "2520" => 2520, + "2521" => 2521, + "2522" => 2522, + "2523" => 2523, + "2524" => 2524, + "2525" => 2525, + "2526" => 2526, + "2527" => 2527, + "2528" => 2528, + "2529" => 2529, + "2530" => 2530, + "2531" => 2531, + "2532" => 2532, + "2533" => 2533, + "2534" => 2534, + "2535" => 2535, + "2536" => 2536, + "2537" => 2537, + "2538" => 2538, + "2539" => 2539, + "2540" => 2540, + "2541" => 2541, + "2542" => 2542, + "2543" => 2543, + "2544" => 2544, + "2545" => 2545, + "2546" => 2546, + "2547" => 2547, + "2548" => 2548, + "2549" => 2549, + "2550" => 2550, + "2551" => 2551, + "2552" => 2552, + "2553" => 2553, + "2554" => 2554, + "2555" => 2555, + "2556" => 2556, + "2557" => 2557, + "2558" => 2558, + "2559" => 2559, + "2560" => 2560, + "2561" => 2561, + "2562" => 2562, + "2563" => 2563, + "2564" => 2564, + "2565" => 2565, + "2566" => 2566, + "2567" => 2567, + "2568" => 2568, + "2569" => 2569, + "2570" => 2570, + "2571" => 2571, + "2572" => 2572, + "2573" => 2573, + "2574" => 2574, + "2575" => 2575, + "2576" => 2576, + "2577" => 2577, + "2578" => 2578, + "2579" => 2579, + "2580" => 2580, + "2581" => 2581, + "2582" => 2582, + "2583" => 2583, + "2584" => 2584, + "2585" => 2585, + "2586" => 2586, + "2587" => 2587, + "2588" => 2588, + "2589" => 2589, + "2590" => 2590, + "2591" => 2591, + "2592" => 2592, + "2593" => 2593, + "2594" => 2594, + "2595" => 2595, + "2596" => 2596, + "2597" => 2597, + "2598" => 2598, + "2599" => 2599, + "2600" => 2600, + "2601" => 2601, + "2602" => 2602, + "2603" => 2603, + "2604" => 2604, + "2605" => 2605, + "2606" => 2606, + "2607" => 2607, + "2608" => 2608, + "2609" => 2609, + "2610" => 2610, + "2611" => 2611, + "2612" => 2612, + "2613" => 2613, + "2614" => 2614, + "2615" => 2615, + "2616" => 2616, + "2617" => 2617, + "2618" => 2618, + "2619" => 2619, + "2620" => 2620, + "2621" => 2621, + "2622" => 2622, + "2623" => 2623, + "2624" => 2624, + "2625" => 2625, + "2626" => 2626, + "2627" => 2627, + "2628" => 2628, + "2629" => 2629, + "2630" => 2630, + "2631" => 2631, + "2632" => 2632, + "2633" => 2633, + "2634" => 2634, + "2635" => 2635, + "2636" => 2636, + "2637" => 2637, + "2638" => 2638, + "2639" => 2639, + "2640" => 2640, + "2641" => 2641, + "2642" => 2642, + "2643" => 2643, + "2644" => 2644, + "2645" => 2645, + "2646" => 2646, + "2647" => 2647, + "2648" => 2648, + "2649" => 2649, + "2650" => 2650, + "2651" => 2651, + "2652" => 2652, + "2653" => 2653, + "2654" => 2654, + "2655" => 2655, + "2656" => 2656, + "2657" => 2657, + "2658" => 2658, + "2659" => 2659, + "2660" => 2660, + "2661" => 2661, + "2662" => 2662, + "2663" => 2663, + "2664" => 2664, + "2665" => 2665, + "2666" => 2666, + "2667" => 2667, + "2668" => 2668, + "2669" => 2669, + "2670" => 2670, + "2671" => 2671, + "2672" => 2672, + "2673" => 2673, + "2674" => 2674, + "2675" => 2675, + "2676" => 2676, + "2677" => 2677, + "2678" => 2678, + "2679" => 2679, + "2680" => 2680, + "2681" => 2681, + "2682" => 2682, + "2683" => 2683, + "2684" => 2684, + "2685" => 2685, + "2686" => 2686, + "2687" => 2687, + "2688" => 2688, + "2689" => 2689, + "2690" => 2690, + "2691" => 2691, + "2692" => 2692, + "2693" => 2693, + "2694" => 2694, + "2695" => 2695, + "2696" => 2696, + "2697" => 2697, + "2698" => 2698, + "2699" => 2699, + "2700" => 2700, + "2701" => 2701, + "2702" => 2702, + "2703" => 2703, + "2704" => 2704, + "2705" => 2705, + "2706" => 2706, + "2707" => 2707, + "2708" => 2708, + "2709" => 2709, + "2710" => 2710, + "2711" => 2711, + "2712" => 2712, + "2713" => 2713, + "2714" => 2714, + "2715" => 2715, + "2716" => 2716, + "2717" => 2717, + "2718" => 2718, + "2719" => 2719, + "2720" => 2720, + "2721" => 2721, + "2722" => 2722, + "2723" => 2723, + "2724" => 2724, + "2725" => 2725, + "2726" => 2726, + "2727" => 2727, + "2728" => 2728, + "2729" => 2729, + "2730" => 2730, + "2731" => 2731, + "2732" => 2732, + "2733" => 2733, + "2734" => 2734, + "2735" => 2735, + "2736" => 2736, + "2737" => 2737, + "2738" => 2738, + "2739" => 2739, + "2740" => 2740, + "2741" => 2741, + "2742" => 2742, + "2743" => 2743, + "2744" => 2744, + "2745" => 2745, + "2746" => 2746, + "2747" => 2747, + "2748" => 2748, + "2749" => 2749, + "2750" => 2750, + "2751" => 2751, + "2752" => 2752, + "2753" => 2753, + "2754" => 2754, + "2755" => 2755, + "2756" => 2756, + "2757" => 2757, + "2758" => 2758, + "2759" => 2759, + "2760" => 2760, + "2761" => 2761, + "2762" => 2762, + "2763" => 2763, + "2764" => 2764, + "2765" => 2765, + "2766" => 2766, + "2767" => 2767, + "2768" => 2768, + "2769" => 2769, + "2770" => 2770, + "2771" => 2771, + "2772" => 2772, + "2773" => 2773, + "2774" => 2774, + "2775" => 2775, + "2776" => 2776, + "2777" => 2777, + "2778" => 2778, + "2779" => 2779, + "2780" => 2780, + "2781" => 2781, + "2782" => 2782, + "2783" => 2783, + "2784" => 2784, + "2785" => 2785, + "2786" => 2786, + "2787" => 2787, + "2788" => 2788, + "2789" => 2789, + "2790" => 2790, + "2791" => 2791, + "2792" => 2792, + "2793" => 2793, + "2794" => 2794, + "2795" => 2795, + "2796" => 2796, + "2797" => 2797, + "2798" => 2798, + "2799" => 2799, + "2800" => 2800, + "2801" => 2801, + "2802" => 2802, + "2803" => 2803, + "2804" => 2804, + "2805" => 2805, + "2806" => 2806, + "2807" => 2807, + "2808" => 2808, + "2809" => 2809, + "2810" => 2810, + "2811" => 2811, + "2812" => 2812, + "2813" => 2813, + "2814" => 2814, + "2815" => 2815, + "2816" => 2816, + "2817" => 2817, + "2818" => 2818, + "2819" => 2819, + "2820" => 2820, + "2821" => 2821, + "2822" => 2822, + "2823" => 2823, + "2824" => 2824, + "2825" => 2825, + "2826" => 2826, + "2827" => 2827, + "2828" => 2828, + "2829" => 2829, + "2830" => 2830, + "2831" => 2831, + "2832" => 2832, + "2833" => 2833, + "2834" => 2834, + "2835" => 2835, + "2836" => 2836, + "2837" => 2837, + "2838" => 2838, + "2839" => 2839, + "2840" => 2840, + "2841" => 2841, + "2842" => 2842, + "2843" => 2843, + "2844" => 2844, + "2845" => 2845, + "2846" => 2846, + "2847" => 2847, + "2848" => 2848, + "2849" => 2849, + "2850" => 2850, + "2851" => 2851, + "2852" => 2852, + "2853" => 2853, + "2854" => 2854, + "2855" => 2855, + "2856" => 2856, + "2857" => 2857, + "2858" => 2858, + "2859" => 2859, + "2860" => 2860, + "2861" => 2861, + "2862" => 2862, + "2863" => 2863, + "2864" => 2864, + "2865" => 2865, + "2866" => 2866, + "2867" => 2867, + "2868" => 2868, + "2869" => 2869, + "2870" => 2870, + "2871" => 2871, + "2872" => 2872, + "2873" => 2873, + "2874" => 2874, + "2875" => 2875, + "2876" => 2876, + "2877" => 2877, + "2878" => 2878, + "2879" => 2879, + "2880" => 2880, + "2881" => 2881, + "2882" => 2882, + "2883" => 2883, + "2884" => 2884, + "2885" => 2885, + "2886" => 2886, + "2887" => 2887, + "2888" => 2888, + "2889" => 2889, + "2890" => 2890, + "2891" => 2891, + "2892" => 2892, + "2893" => 2893, + "2894" => 2894, + "2895" => 2895, + "2896" => 2896, + "2897" => 2897, + "2898" => 2898, + "2899" => 2899, + "2900" => 2900, + "2901" => 2901, + "2902" => 2902, + "2903" => 2903, + "2904" => 2904, + "2905" => 2905, + "2906" => 2906, + "2907" => 2907, + "2908" => 2908, + "2909" => 2909, + "2910" => 2910, + "2911" => 2911, + "2912" => 2912, + "2913" => 2913, + "2914" => 2914, + "2915" => 2915, + "2916" => 2916, + "2917" => 2917, + "2918" => 2918, + "2919" => 2919, + "2920" => 2920, + "2921" => 2921, + "2922" => 2922, + "2923" => 2923, + "2924" => 2924, + "2925" => 2925, + "2926" => 2926, + "2927" => 2927, + "2928" => 2928, + "2929" => 2929, + "2930" => 2930, + "2931" => 2931, + "2932" => 2932, + "2933" => 2933, + "2934" => 2934, + "2935" => 2935, + "2936" => 2936, + "2937" => 2937, + "2938" => 2938, + "2939" => 2939, + "2940" => 2940, + "2941" => 2941, + "2942" => 2942, + "2943" => 2943, + "2944" => 2944, + "2945" => 2945, + "2946" => 2946, + "2947" => 2947, + "2948" => 2948, + "2949" => 2949, + "2950" => 2950, + "2951" => 2951, + "2952" => 2952, + "2953" => 2953, + "2954" => 2954, + "2955" => 2955, + "2956" => 2956, + "2957" => 2957, + "2958" => 2958, + "2959" => 2959, + "2960" => 2960, + "2961" => 2961, + "2962" => 2962, + "2963" => 2963, + "2964" => 2964, + "2965" => 2965, + "2966" => 2966, + "2967" => 2967, + "2968" => 2968, + "2969" => 2969, + "2970" => 2970, + "2971" => 2971, + "2972" => 2972, + "2973" => 2973, + "2974" => 2974, + "2975" => 2975, + "2976" => 2976, + "2977" => 2977, + "2978" => 2978, + "2979" => 2979, + "2980" => 2980, + "2981" => 2981, + "2982" => 2982, + "2983" => 2983, + "2984" => 2984, + "2985" => 2985, + "2986" => 2986, + "2987" => 2987, + "2988" => 2988, + "2989" => 2989, + "2990" => 2990, + "2991" => 2991, + "2992" => 2992, + "2993" => 2993, + "2994" => 2994, + "2995" => 2995, + "2996" => 2996, + "2997" => 2997, + "2998" => 2998, + "2999" => 2999, + "3000" => 3000, + "3001" => 3001, + "3002" => 3002, + "3003" => 3003, + "3004" => 3004, + "3005" => 3005, + "3006" => 3006, + "3007" => 3007, + "3008" => 3008, + "3009" => 3009, + "3010" => 3010, + "3011" => 3011, + "3012" => 3012, + "3013" => 3013, + "3014" => 3014, + "3015" => 3015, + "3016" => 3016, + "3017" => 3017, + "3018" => 3018, + "3019" => 3019, + "3020" => 3020, + "3021" => 3021, + "3022" => 3022, + "3023" => 3023, + "3024" => 3024, + "3025" => 3025, + "3026" => 3026, + "3027" => 3027, + "3028" => 3028, + "3029" => 3029, + "3030" => 3030, + "3031" => 3031, + "3032" => 3032, + "3033" => 3033, + "3034" => 3034, + "3035" => 3035, + "3036" => 3036, + "3037" => 3037, + "3038" => 3038, + "3039" => 3039, + "3040" => 3040, + "3041" => 3041, + "3042" => 3042, + "3043" => 3043, + "3044" => 3044, + "3045" => 3045, + "3046" => 3046, + "3047" => 3047, + "3048" => 3048, + "3049" => 3049, + "3050" => 3050, + "3051" => 3051, + "3052" => 3052, + "3053" => 3053, + "3054" => 3054, + "3055" => 3055, + "3056" => 3056, + "3057" => 3057, + "3058" => 3058, + "3059" => 3059, + "3060" => 3060, + "3061" => 3061, + "3062" => 3062, + "3063" => 3063, + "3064" => 3064, + "3065" => 3065, + "3066" => 3066, + "3067" => 3067, + "3068" => 3068, + "3069" => 3069, + "3070" => 3070, + "3071" => 3071, + "3072" => 3072, + "3073" => 3073, + "3074" => 3074, + "3075" => 3075, + "3076" => 3076, + "3077" => 3077, + "3078" => 3078, + "3079" => 3079, + "3080" => 3080, + "3081" => 3081, + "3082" => 3082, + "3083" => 3083, + "3084" => 3084, + "3085" => 3085, + "3086" => 3086, + "3087" => 3087, + "3088" => 3088, + "3089" => 3089, + "3090" => 3090, + "3091" => 3091, + "3092" => 3092, + "3093" => 3093, + "3094" => 3094, + "3095" => 3095, + "3096" => 3096, + "3097" => 3097, + "3098" => 3098, + "3099" => 3099, + "3100" => 3100, + "3101" => 3101, + "3102" => 3102, + "3103" => 3103, + "3104" => 3104, + "3105" => 3105, + "3106" => 3106, + "3107" => 3107, + "3108" => 3108, + "3109" => 3109, + "3110" => 3110, + "3111" => 3111, + "3112" => 3112, + "3113" => 3113, + "3114" => 3114, + "3115" => 3115, + "3116" => 3116, + "3117" => 3117, + "3118" => 3118, + "3119" => 3119, + "3120" => 3120, + "3121" => 3121, + "3122" => 3122, + "3123" => 3123, + "3124" => 3124, + "3125" => 3125, + "3126" => 3126, + "3127" => 3127, + "3128" => 3128, + "3129" => 3129, + "3130" => 3130, + "3131" => 3131, + "3132" => 3132, + "3133" => 3133, + "3134" => 3134, + "3135" => 3135, + "3136" => 3136, + "3137" => 3137, + "3138" => 3138, + "3139" => 3139, + "3140" => 3140, + "3141" => 3141, + "3142" => 3142, + "3143" => 3143, + "3144" => 3144, + "3145" => 3145, + "3146" => 3146, + "3147" => 3147, + "3148" => 3148, + "3149" => 3149, + "3150" => 3150, + "3151" => 3151, + "3152" => 3152, + "3153" => 3153, + "3154" => 3154, + "3155" => 3155, + "3156" => 3156, + "3157" => 3157, + "3158" => 3158, + "3159" => 3159, + "3160" => 3160, + "3161" => 3161, + "3162" => 3162, + "3163" => 3163, + "3164" => 3164, + "3165" => 3165, + "3166" => 3166, + "3167" => 3167, + "3168" => 3168, + "3169" => 3169, + "3170" => 3170, + "3171" => 3171, + "3172" => 3172, + "3173" => 3173, + "3174" => 3174, + "3175" => 3175, + "3176" => 3176, + "3177" => 3177, + "3178" => 3178, + "3179" => 3179, + "3180" => 3180, + "3181" => 3181, + "3182" => 3182, + "3183" => 3183, + "3184" => 3184, + "3185" => 3185, + "3186" => 3186, + "3187" => 3187, + "3188" => 3188, + "3189" => 3189, + "3190" => 3190, + "3191" => 3191, + "3192" => 3192, + "3193" => 3193, + "3194" => 3194, + "3195" => 3195, + "3196" => 3196, + "3197" => 3197, + "3198" => 3198, + "3199" => 3199, + "3200" => 3200, + "3201" => 3201, + "3202" => 3202, + "3203" => 3203, + "3204" => 3204, + "3205" => 3205, + "3206" => 3206, + "3207" => 3207, + "3208" => 3208, + "3209" => 3209, + "3210" => 3210, + "3211" => 3211, + "3212" => 3212, + "3213" => 3213, + "3214" => 3214, + "3215" => 3215, + "3216" => 3216, + "3217" => 3217, + "3218" => 3218, + "3219" => 3219, + "3220" => 3220, + "3221" => 3221, + "3222" => 3222, + "3223" => 3223, + "3224" => 3224, + "3225" => 3225, + "3226" => 3226, + "3227" => 3227, + "3228" => 3228, + "3229" => 3229, + "3230" => 3230, + "3231" => 3231, + "3232" => 3232, + "3233" => 3233, + "3234" => 3234, + "3235" => 3235, + "3236" => 3236, + "3237" => 3237, + "3238" => 3238, + "3239" => 3239, + "3240" => 3240, + "3241" => 3241, + "3242" => 3242, + "3243" => 3243, + "3244" => 3244, + "3245" => 3245, + "3246" => 3246, + "3247" => 3247, + "3248" => 3248, + "3249" => 3249, + "3250" => 3250, + "3251" => 3251, + "3252" => 3252, + "3253" => 3253, + "3254" => 3254, + "3255" => 3255, + "3256" => 3256, + "3257" => 3257, + "3258" => 3258, + "3259" => 3259, + "3260" => 3260, + "3261" => 3261, + "3262" => 3262, + "3263" => 3263, + "3264" => 3264, + "3265" => 3265, + "3266" => 3266, + "3267" => 3267, + "3268" => 3268, + "3269" => 3269, + "3270" => 3270, + "3271" => 3271, + "3272" => 3272, + "3273" => 3273, + "3274" => 3274, + "3275" => 3275, + "3276" => 3276, + "3277" => 3277, + "3278" => 3278, + "3279" => 3279, + "3280" => 3280, + "3281" => 3281, + "3282" => 3282, + "3283" => 3283, + "3284" => 3284, + "3285" => 3285, + "3286" => 3286, + "3287" => 3287, + "3288" => 3288, + "3289" => 3289, + "3290" => 3290, + "3291" => 3291, + "3292" => 3292, + "3293" => 3293, + "3294" => 3294, + "3295" => 3295, + "3296" => 3296, + "3297" => 3297, + "3298" => 3298, + "3299" => 3299, + "3300" => 3300, + "3301" => 3301, + "3302" => 3302, + "3303" => 3303, + "3304" => 3304, + "3305" => 3305, + "3306" => 3306, + "3307" => 3307, + "3308" => 3308, + "3309" => 3309, + "3310" => 3310, + "3311" => 3311, + "3312" => 3312, + "3313" => 3313, + "3314" => 3314, + "3315" => 3315, + "3316" => 3316, + "3317" => 3317, + "3318" => 3318, + "3319" => 3319, + "3320" => 3320, + "3321" => 3321, + "3322" => 3322, + "3323" => 3323, + "3324" => 3324, + "3325" => 3325, + "3326" => 3326, + "3327" => 3327, + "3328" => 3328, + "3329" => 3329, + "3330" => 3330, + "3331" => 3331, + "3332" => 3332, + "3333" => 3333, + "3334" => 3334, + "3335" => 3335, + "3336" => 3336, + "3337" => 3337, + "3338" => 3338, + "3339" => 3339, + "3340" => 3340, + "3341" => 3341, + "3342" => 3342, + "3343" => 3343, + "3344" => 3344, + "3345" => 3345, + "3346" => 3346, + "3347" => 3347, + "3348" => 3348, + "3349" => 3349, + "3350" => 3350, + "3351" => 3351, + "3352" => 3352, + "3353" => 3353, + "3354" => 3354, + "3355" => 3355, + "3356" => 3356, + "3357" => 3357, + "3358" => 3358, + "3359" => 3359, + "3360" => 3360, + "3361" => 3361, + "3362" => 3362, + "3363" => 3363, + "3364" => 3364, + "3365" => 3365, + "3366" => 3366, + "3367" => 3367, + "3368" => 3368, + "3369" => 3369, + "3370" => 3370, + "3371" => 3371, + "3372" => 3372, + "3373" => 3373, + "3374" => 3374, + "3375" => 3375, + "3376" => 3376, + "3377" => 3377, + "3378" => 3378, + "3379" => 3379, + "3380" => 3380, + "3381" => 3381, + "3382" => 3382, + "3383" => 3383, + "3384" => 3384, + "3385" => 3385, + "3386" => 3386, + "3387" => 3387, + "3388" => 3388, + "3389" => 3389, + "3390" => 3390, + "3391" => 3391, + "3392" => 3392, + "3393" => 3393, + "3394" => 3394, + "3395" => 3395, + "3396" => 3396, + "3397" => 3397, + "3398" => 3398, + "3399" => 3399, + "3400" => 3400, + "3401" => 3401, + "3402" => 3402, + "3403" => 3403, + "3404" => 3404, + "3405" => 3405, + "3406" => 3406, + "3407" => 3407, + "3408" => 3408, + "3409" => 3409, + "3410" => 3410, + "3411" => 3411, + "3412" => 3412, + "3413" => 3413, + "3414" => 3414, + "3415" => 3415, + "3416" => 3416, + "3417" => 3417, + "3418" => 3418, + "3419" => 3419, + "3420" => 3420, + "3421" => 3421, + "3422" => 3422, + "3423" => 3423, + "3424" => 3424, + "3425" => 3425, + "3426" => 3426, + "3427" => 3427, + "3428" => 3428, + "3429" => 3429, + "3430" => 3430, + "3431" => 3431, + "3432" => 3432, + "3433" => 3433, + "3434" => 3434, + "3435" => 3435, + "3436" => 3436, + "3437" => 3437, + "3438" => 3438, + "3439" => 3439, + "3440" => 3440, + "3441" => 3441, + "3442" => 3442, + "3443" => 3443, + "3444" => 3444, + "3445" => 3445, + "3446" => 3446, + "3447" => 3447, + "3448" => 3448, + "3449" => 3449, + "3450" => 3450, + "3451" => 3451, + "3452" => 3452, + "3453" => 3453, + "3454" => 3454, + "3455" => 3455, + "3456" => 3456, + "3457" => 3457, + "3458" => 3458, + "3459" => 3459, + "3460" => 3460, + "3461" => 3461, + "3462" => 3462, + "3463" => 3463, + "3464" => 3464, + "3465" => 3465, + "3466" => 3466, + "3467" => 3467, + "3468" => 3468, + "3469" => 3469, + "3470" => 3470, + "3471" => 3471, + "3472" => 3472, + "3473" => 3473, + "3474" => 3474, + "3475" => 3475, + "3476" => 3476, + "3477" => 3477, + "3478" => 3478, + "3479" => 3479, + "3480" => 3480, + "3481" => 3481, + "3482" => 3482, + "3483" => 3483, + "3484" => 3484, + "3485" => 3485, + "3486" => 3486, + "3487" => 3487, + "3488" => 3488, + "3489" => 3489, + "3490" => 3490, + "3491" => 3491, + "3492" => 3492, + "3493" => 3493, + "3494" => 3494, + "3495" => 3495, + "3496" => 3496, + "3497" => 3497, + "3498" => 3498, + "3499" => 3499, + "3500" => 3500, + "3501" => 3501, + "3502" => 3502, + "3503" => 3503, + "3504" => 3504, + "3505" => 3505, + "3506" => 3506, + "3507" => 3507, + "3508" => 3508, + "3509" => 3509, + "3510" => 3510, + "3511" => 3511, + "3512" => 3512, + "3513" => 3513, + "3514" => 3514, + "3515" => 3515, + "3516" => 3516, + "3517" => 3517, + "3518" => 3518, + "3519" => 3519, + "3520" => 3520, + "3521" => 3521, + "3522" => 3522, + "3523" => 3523, + "3524" => 3524, + "3525" => 3525, + "3526" => 3526, + "3527" => 3527, + "3528" => 3528, + "3529" => 3529, + "3530" => 3530, + "3531" => 3531, + "3532" => 3532, + "3533" => 3533, + "3534" => 3534, + "3535" => 3535, + "3536" => 3536, + "3537" => 3537, + "3538" => 3538, + "3539" => 3539, + "3540" => 3540, + "3541" => 3541, + "3542" => 3542, + "3543" => 3543, + "3544" => 3544, + "3545" => 3545, + "3546" => 3546, + "3547" => 3547, + "3548" => 3548, + "3549" => 3549, + "3550" => 3550, + "3551" => 3551, + "3552" => 3552, + "3553" => 3553, + "3554" => 3554, + "3555" => 3555, + "3556" => 3556, + "3557" => 3557, + "3558" => 3558, + "3559" => 3559, + "3560" => 3560, + "3561" => 3561, + "3562" => 3562, + "3563" => 3563, + "3564" => 3564, + "3565" => 3565, + "3566" => 3566, + "3567" => 3567, + "3568" => 3568, + "3569" => 3569, + "3570" => 3570, + "3571" => 3571, + "3572" => 3572, + "3573" => 3573, + "3574" => 3574, + "3575" => 3575, + "3576" => 3576, + "3577" => 3577, + "3578" => 3578, + "3579" => 3579, + "3580" => 3580, + "3581" => 3581, + "3582" => 3582, + "3583" => 3583, + "3584" => 3584, + "3585" => 3585, + "3586" => 3586, + "3587" => 3587, + "3588" => 3588, + "3589" => 3589, + "3590" => 3590, + "3591" => 3591, + "3592" => 3592, + "3593" => 3593, + "3594" => 3594, + "3595" => 3595, + "3596" => 3596, + "3597" => 3597, + "3598" => 3598, + "3599" => 3599, + "3600" => 3600, + "3601" => 3601, + "3602" => 3602, + "3603" => 3603, + "3604" => 3604, + "3605" => 3605, + "3606" => 3606, + "3607" => 3607, + "3608" => 3608, + "3609" => 3609, + "3610" => 3610, + "3611" => 3611, + "3612" => 3612, + "3613" => 3613, + "3614" => 3614, + "3615" => 3615, + "3616" => 3616, + "3617" => 3617, + "3618" => 3618, + "3619" => 3619, + "3620" => 3620, + "3621" => 3621, + "3622" => 3622, + "3623" => 3623, + "3624" => 3624, + "3625" => 3625, + "3626" => 3626, + "3627" => 3627, + "3628" => 3628, + "3629" => 3629, + "3630" => 3630, + "3631" => 3631, + "3632" => 3632, + "3633" => 3633, + "3634" => 3634, + "3635" => 3635, + "3636" => 3636, + "3637" => 3637, + "3638" => 3638, + "3639" => 3639, + "3640" => 3640, + "3641" => 3641, + "3642" => 3642, + "3643" => 3643, + "3644" => 3644, + "3645" => 3645, + "3646" => 3646, + "3647" => 3647, + "3648" => 3648, + "3649" => 3649, + "3650" => 3650, + "3651" => 3651, + "3652" => 3652, + "3653" => 3653, + "3654" => 3654, + "3655" => 3655, + "3656" => 3656, + "3657" => 3657, + "3658" => 3658, + "3659" => 3659, + "3660" => 3660, + "3661" => 3661, + "3662" => 3662, + "3663" => 3663, + "3664" => 3664, + "3665" => 3665, + "3666" => 3666, + "3667" => 3667, + "3668" => 3668, + "3669" => 3669, + "3670" => 3670, + "3671" => 3671, + "3672" => 3672, + "3673" => 3673, + "3674" => 3674, + "3675" => 3675, + "3676" => 3676, + "3677" => 3677, + "3678" => 3678, + "3679" => 3679, + "3680" => 3680, + "3681" => 3681, + "3682" => 3682, + "3683" => 3683, + "3684" => 3684, + "3685" => 3685, + "3686" => 3686, + "3687" => 3687, + "3688" => 3688, + "3689" => 3689, + "3690" => 3690, + "3691" => 3691, + "3692" => 3692, + "3693" => 3693, + "3694" => 3694, + "3695" => 3695, + "3696" => 3696, + "3697" => 3697, + "3698" => 3698, + "3699" => 3699, + "3700" => 3700, + "3701" => 3701, + "3702" => 3702, + "3703" => 3703, + "3704" => 3704, + "3705" => 3705, + "3706" => 3706, + "3707" => 3707, + "3708" => 3708, + "3709" => 3709, + "3710" => 3710, + "3711" => 3711, + "3712" => 3712, + "3713" => 3713, + "3714" => 3714, + "3715" => 3715, + "3716" => 3716, + "3717" => 3717, + "3718" => 3718, + "3719" => 3719, + "3720" => 3720, + "3721" => 3721, + "3722" => 3722, + "3723" => 3723, + "3724" => 3724, + "3725" => 3725, + "3726" => 3726, + "3727" => 3727, + "3728" => 3728, + "3729" => 3729, + "3730" => 3730, + "3731" => 3731, + "3732" => 3732, + "3733" => 3733, + "3734" => 3734, + "3735" => 3735, + "3736" => 3736, + "3737" => 3737, + "3738" => 3738, + "3739" => 3739, + "3740" => 3740, + "3741" => 3741, + "3742" => 3742, + "3743" => 3743, + "3744" => 3744, + "3745" => 3745, + "3746" => 3746, + "3747" => 3747, + "3748" => 3748, + "3749" => 3749, + "3750" => 3750, + "3751" => 3751, + "3752" => 3752, + "3753" => 3753, + "3754" => 3754, + "3755" => 3755, + "3756" => 3756, + "3757" => 3757, + "3758" => 3758, + "3759" => 3759, + "3760" => 3760, + "3761" => 3761, + "3762" => 3762, + "3763" => 3763, + "3764" => 3764, + "3765" => 3765, + "3766" => 3766, + "3767" => 3767, + "3768" => 3768, + "3769" => 3769, + "3770" => 3770, + "3771" => 3771, + "3772" => 3772, + "3773" => 3773, + "3774" => 3774, + "3775" => 3775, + "3776" => 3776, + "3777" => 3777, + "3778" => 3778, + "3779" => 3779, + "3780" => 3780, + "3781" => 3781, + "3782" => 3782, + "3783" => 3783, + "3784" => 3784, + "3785" => 3785, + "3786" => 3786, + "3787" => 3787, + "3788" => 3788, + "3789" => 3789, + "3790" => 3790, + "3791" => 3791, + "3792" => 3792, + "3793" => 3793, + "3794" => 3794, + "3795" => 3795, + "3796" => 3796, + "3797" => 3797, + "3798" => 3798, + "3799" => 3799, + "3800" => 3800, + "3801" => 3801, + "3802" => 3802, + "3803" => 3803, + "3804" => 3804, + "3805" => 3805, + "3806" => 3806, + "3807" => 3807, + "3808" => 3808, + "3809" => 3809, + "3810" => 3810, + "3811" => 3811, + "3812" => 3812, + "3813" => 3813, + "3814" => 3814, + "3815" => 3815, + "3816" => 3816, + "3817" => 3817, + "3818" => 3818, + "3819" => 3819, + "3820" => 3820, + "3821" => 3821, + "3822" => 3822, + "3823" => 3823, + "3824" => 3824, + "3825" => 3825, + "3826" => 3826, + "3827" => 3827, + "3828" => 3828, + "3829" => 3829, + "3830" => 3830, + "3831" => 3831, + "3832" => 3832, + "3833" => 3833, + "3834" => 3834, + "3835" => 3835, + "3836" => 3836, + "3837" => 3837, + "3838" => 3838, + "3839" => 3839, + "3840" => 3840, + "3841" => 3841, + "3842" => 3842, + "3843" => 3843, + "3844" => 3844, + "3845" => 3845, + "3846" => 3846, + "3847" => 3847, + "3848" => 3848, + "3849" => 3849, + "3850" => 3850, + "3851" => 3851, + "3852" => 3852, + "3853" => 3853, + "3854" => 3854, + "3855" => 3855, + "3856" => 3856, + "3857" => 3857, + "3858" => 3858, + "3859" => 3859, + "3860" => 3860, + "3861" => 3861, + "3862" => 3862, + "3863" => 3863, + "3864" => 3864, + "3865" => 3865, + "3866" => 3866, + "3867" => 3867, + "3868" => 3868, + "3869" => 3869, + "3870" => 3870, + "3871" => 3871, + "3872" => 3872, + "3873" => 3873, + "3874" => 3874, + "3875" => 3875, + "3876" => 3876, + "3877" => 3877, + "3878" => 3878, + "3879" => 3879, + "3880" => 3880, + "3881" => 3881, + "3882" => 3882, + "3883" => 3883, + "3884" => 3884, + "3885" => 3885, + "3886" => 3886, + "3887" => 3887, + "3888" => 3888, + "3889" => 3889, + "3890" => 3890, + "3891" => 3891, + "3892" => 3892, + "3893" => 3893, + "3894" => 3894, + "3895" => 3895, + "3896" => 3896, + "3897" => 3897, + "3898" => 3898, + "3899" => 3899, + "3900" => 3900, + "3901" => 3901, + "3902" => 3902, + "3903" => 3903, + "3904" => 3904, + "3905" => 3905, + "3906" => 3906, + "3907" => 3907, + "3908" => 3908, + "3909" => 3909, + "3910" => 3910, + "3911" => 3911, + "3912" => 3912, + "3913" => 3913, + "3914" => 3914, + "3915" => 3915, + "3916" => 3916, + "3917" => 3917, + "3918" => 3918, + "3919" => 3919, + "3920" => 3920, + "3921" => 3921, + "3922" => 3922, + "3923" => 3923, + "3924" => 3924, + "3925" => 3925, + "3926" => 3926, + "3927" => 3927, + "3928" => 3928, + "3929" => 3929, + "3930" => 3930, + "3931" => 3931, + "3932" => 3932, + "3933" => 3933, + "3934" => 3934, + "3935" => 3935, + "3936" => 3936, + "3937" => 3937, + "3938" => 3938, + "3939" => 3939, + "3940" => 3940, + "3941" => 3941, + "3942" => 3942, + "3943" => 3943, + "3944" => 3944, + "3945" => 3945, + "3946" => 3946, + "3947" => 3947, + "3948" => 3948, + "3949" => 3949, + "3950" => 3950, + "3951" => 3951, + "3952" => 3952, + "3953" => 3953, + "3954" => 3954, + "3955" => 3955, + "3956" => 3956, + "3957" => 3957, + "3958" => 3958, + "3959" => 3959, + "3960" => 3960, + "3961" => 3961, + "3962" => 3962, + "3963" => 3963, + "3964" => 3964, + "3965" => 3965, + "3966" => 3966, + "3967" => 3967, + "3968" => 3968, + "3969" => 3969, + "3970" => 3970, + "3971" => 3971, + "3972" => 3972, + "3973" => 3973, + "3974" => 3974, + "3975" => 3975, + "3976" => 3976, + "3977" => 3977, + "3978" => 3978, + "3979" => 3979, + "3980" => 3980, + "3981" => 3981, + "3982" => 3982, + "3983" => 3983, + "3984" => 3984, + "3985" => 3985, + "3986" => 3986, + "3987" => 3987, + "3988" => 3988, + "3989" => 3989, + "3990" => 3990, + "3991" => 3991, + "3992" => 3992, + "3993" => 3993, + "3994" => 3994, + "3995" => 3995, + "3996" => 3996, + "3997" => 3997, + "3998" => 3998, + "3999" => 3999, + "4000" => 4000, + "4001" => 4001, + "4002" => 4002, + "4003" => 4003, + "4004" => 4004, + "4005" => 4005, + "4006" => 4006, + "4007" => 4007, + "4008" => 4008, + "4009" => 4009, + "4010" => 4010, + "4011" => 4011, + "4012" => 4012, + "4013" => 4013, + "4014" => 4014, + "4015" => 4015, + "4016" => 4016, + "4017" => 4017, + "4018" => 4018, + "4019" => 4019, + "4020" => 4020, + "4021" => 4021, + "4022" => 4022, + "4023" => 4023, + "4024" => 4024, + "4025" => 4025, + "4026" => 4026, + "4027" => 4027, + "4028" => 4028, + "4029" => 4029, + "4030" => 4030, + "4031" => 4031, + "4032" => 4032, + "4033" => 4033, + "4034" => 4034, + "4035" => 4035, + "4036" => 4036, + "4037" => 4037, + "4038" => 4038, + "4039" => 4039, + "4040" => 4040, + "4041" => 4041, + "4042" => 4042, + "4043" => 4043, + "4044" => 4044, + "4045" => 4045, + "4046" => 4046, + "4047" => 4047, + "4048" => 4048, + "4049" => 4049, + "4050" => 4050, + "4051" => 4051, + "4052" => 4052, + "4053" => 4053, + "4054" => 4054, + "4055" => 4055, + "4056" => 4056, + "4057" => 4057, + "4058" => 4058, + "4059" => 4059, + "4060" => 4060, + "4061" => 4061, + "4062" => 4062, + "4063" => 4063, + "4064" => 4064, + "4065" => 4065, + "4066" => 4066, + "4067" => 4067, + "4068" => 4068, + "4069" => 4069, + "4070" => 4070, + "4071" => 4071, + "4072" => 4072, + "4073" => 4073, + "4074" => 4074, + "4075" => 4075, + "4076" => 4076, + "4077" => 4077, + "4078" => 4078, + "4079" => 4079, + "4080" => 4080, + "4081" => 4081, + "4082" => 4082, + "4083" => 4083, + "4084" => 4084, + "4085" => 4085, + "4086" => 4086, + "4087" => 4087, + "4088" => 4088, + "4089" => 4089, + "4090" => 4090, + "4091" => 4091, + "4092" => 4092, + "4093" => 4093, + "4094" => 4094, + "4095" => 4095, + "4096" => 4096, + "4097" => 4097, + "4098" => 4098, + "4099" => 4099, + "4100" => 4100, + "4101" => 4101, + "4102" => 4102, + "4103" => 4103, + "4104" => 4104, + "4105" => 4105, + "4106" => 4106, + "4107" => 4107, + "4108" => 4108, + "4109" => 4109, + "4110" => 4110, + "4111" => 4111, + "4112" => 4112, + "4113" => 4113, + "4114" => 4114, + "4115" => 4115, + "4116" => 4116, + "4117" => 4117, + "4118" => 4118, + "4119" => 4119, + "4120" => 4120, + "4121" => 4121, + "4122" => 4122, + "4123" => 4123, + "4124" => 4124, + "4125" => 4125, + "4126" => 4126, + "4127" => 4127, + "4128" => 4128, + "4129" => 4129, + "4130" => 4130, + "4131" => 4131, + "4132" => 4132, + "4133" => 4133, + "4134" => 4134, + "4135" => 4135, + "4136" => 4136, + "4137" => 4137, + "4138" => 4138, + "4139" => 4139, + "4140" => 4140, + "4141" => 4141, + "4142" => 4142, + "4143" => 4143, + "4144" => 4144, + "4145" => 4145, + "4146" => 4146, + "4147" => 4147, + "4148" => 4148, + "4149" => 4149, + "4150" => 4150, + "4151" => 4151, + "4152" => 4152, + "4153" => 4153, + "4154" => 4154, + "4155" => 4155, + "4156" => 4156, + "4157" => 4157, + "4158" => 4158, + "4159" => 4159, + "4160" => 4160, + "4161" => 4161, + "4162" => 4162, + "4163" => 4163, + "4164" => 4164, + "4165" => 4165, + "4166" => 4166, + "4167" => 4167, + "4168" => 4168, + "4169" => 4169, + "4170" => 4170, + "4171" => 4171, + "4172" => 4172, + "4173" => 4173, + "4174" => 4174, + "4175" => 4175, + "4176" => 4176, + "4177" => 4177, + "4178" => 4178, + "4179" => 4179, + "4180" => 4180, + "4181" => 4181, + "4182" => 4182, + "4183" => 4183, + "4184" => 4184, + "4185" => 4185, + "4186" => 4186, + "4187" => 4187, + "4188" => 4188, + "4189" => 4189, + "4190" => 4190, + "4191" => 4191, + "4192" => 4192, + "4193" => 4193, + "4194" => 4194, + "4195" => 4195, + "4196" => 4196, + "4197" => 4197, + "4198" => 4198, + "4199" => 4199, + "4200" => 4200, + "4201" => 4201, + "4202" => 4202, + "4203" => 4203, + "4204" => 4204, + "4205" => 4205, + "4206" => 4206, + "4207" => 4207, + "4208" => 4208, + "4209" => 4209, + "4210" => 4210, + "4211" => 4211, + "4212" => 4212, + "4213" => 4213, + "4214" => 4214, + "4215" => 4215, + "4216" => 4216, + "4217" => 4217, + "4218" => 4218, + "4219" => 4219, + "4220" => 4220, + "4221" => 4221, + "4222" => 4222, + "4223" => 4223, + "4224" => 4224, + "4225" => 4225, + "4226" => 4226, + "4227" => 4227, + "4228" => 4228, + "4229" => 4229, + "4230" => 4230, + "4231" => 4231, + "4232" => 4232, + "4233" => 4233, + "4234" => 4234, + "4235" => 4235, + "4236" => 4236, + "4237" => 4237, + "4238" => 4238, + "4239" => 4239, + "4240" => 4240, + "4241" => 4241, + "4242" => 4242, + "4243" => 4243, + "4244" => 4244, + "4245" => 4245, + "4246" => 4246, + "4247" => 4247, + "4248" => 4248, + "4249" => 4249, + "4250" => 4250, + "4251" => 4251, + "4252" => 4252, + "4253" => 4253, + "4254" => 4254, + "4255" => 4255, + "4256" => 4256, + "4257" => 4257, + "4258" => 4258, + "4259" => 4259, + "4260" => 4260, + "4261" => 4261, + "4262" => 4262, + "4263" => 4263, + "4264" => 4264, + "4265" => 4265, + "4266" => 4266, + "4267" => 4267, + "4268" => 4268, + "4269" => 4269, + "4270" => 4270, + "4271" => 4271, + "4272" => 4272, + "4273" => 4273, + "4274" => 4274, + "4275" => 4275, + "4276" => 4276, + "4277" => 4277, + "4278" => 4278, + "4279" => 4279, + "4280" => 4280, + "4281" => 4281, + "4282" => 4282, + "4283" => 4283, + "4284" => 4284, + "4285" => 4285, + "4286" => 4286, + "4287" => 4287, + "4288" => 4288, + "4289" => 4289, + "4290" => 4290, + "4291" => 4291, + "4292" => 4292, + "4293" => 4293, + "4294" => 4294, + "4295" => 4295, + "4296" => 4296, + "4297" => 4297, + "4298" => 4298, + "4299" => 4299, + "4300" => 4300, + "4301" => 4301, + "4302" => 4302, + "4303" => 4303, + "4304" => 4304, + "4305" => 4305, + "4306" => 4306, + "4307" => 4307, + "4308" => 4308, + "4309" => 4309, + "4310" => 4310, + "4311" => 4311, + "4312" => 4312, + "4313" => 4313, + "4314" => 4314, + "4315" => 4315, + "4316" => 4316, + "4317" => 4317, + "4318" => 4318, + "4319" => 4319, + "4320" => 4320, + "4321" => 4321, + "4322" => 4322, + "4323" => 4323, + "4324" => 4324, + "4325" => 4325, + "4326" => 4326, + "4327" => 4327, + "4328" => 4328, + "4329" => 4329, + "4330" => 4330, + "4331" => 4331, + "4332" => 4332, + "4333" => 4333, + "4334" => 4334, + "4335" => 4335, + "4336" => 4336, + "4337" => 4337, + "4338" => 4338, + "4339" => 4339, + "4340" => 4340, + "4341" => 4341, + "4342" => 4342, + "4343" => 4343, + "4344" => 4344, + "4345" => 4345, + "4346" => 4346, + "4347" => 4347, + "4348" => 4348, + "4349" => 4349, + "4350" => 4350, + "4351" => 4351, + "4352" => 4352, + "4353" => 4353, + "4354" => 4354, + "4355" => 4355, + "4356" => 4356, + "4357" => 4357, + "4358" => 4358, + "4359" => 4359, + "4360" => 4360, + "4361" => 4361, + "4362" => 4362, + "4363" => 4363, + "4364" => 4364, + "4365" => 4365, + "4366" => 4366, + "4367" => 4367, + "4368" => 4368, + "4369" => 4369, + "4370" => 4370, + "4371" => 4371, + "4372" => 4372, + "4373" => 4373, + "4374" => 4374, + "4375" => 4375, + "4376" => 4376, + "4377" => 4377, + "4378" => 4378, + "4379" => 4379, + "4380" => 4380, + "4381" => 4381, + "4382" => 4382, + "4383" => 4383, + "4384" => 4384, + "4385" => 4385, + "4386" => 4386, + "4387" => 4387, + "4388" => 4388, + "4389" => 4389, + "4390" => 4390, + "4391" => 4391, + "4392" => 4392, + "4393" => 4393, + "4394" => 4394, + "4395" => 4395, + "4396" => 4396, + "4397" => 4397, + "4398" => 4398, + "4399" => 4399, + "4400" => 4400, + "4401" => 4401, + "4402" => 4402, + "4403" => 4403, + "4404" => 4404, + "4405" => 4405, + "4406" => 4406, + "4407" => 4407, + "4408" => 4408, + "4409" => 4409, + "4410" => 4410, + "4411" => 4411, + "4412" => 4412, + "4413" => 4413, + "4414" => 4414, + "4415" => 4415, + "4416" => 4416, + "4417" => 4417, + "4418" => 4418, + "4419" => 4419, + "4420" => 4420, + "4421" => 4421, + "4422" => 4422, + "4423" => 4423, + "4424" => 4424, + "4425" => 4425, + "4426" => 4426, + "4427" => 4427, + "4428" => 4428, + "4429" => 4429, + "4430" => 4430, + "4431" => 4431, + "4432" => 4432, + "4433" => 4433, + "4434" => 4434, + "4435" => 4435, + "4436" => 4436, + "4437" => 4437, + "4438" => 4438, + "4439" => 4439, + "4440" => 4440, + "4441" => 4441, + "4442" => 4442, + "4443" => 4443, + "4444" => 4444, + "4445" => 4445, + "4446" => 4446, + "4447" => 4447, + "4448" => 4448, + "4449" => 4449, + "4450" => 4450, + "4451" => 4451, + "4452" => 4452, + "4453" => 4453, + "4454" => 4454, + "4455" => 4455, + "4456" => 4456, + "4457" => 4457, + "4458" => 4458, + "4459" => 4459, + "4460" => 4460, + "4461" => 4461, + "4462" => 4462, + "4463" => 4463, + "4464" => 4464, + "4465" => 4465, + "4466" => 4466, + "4467" => 4467, + "4468" => 4468, + "4469" => 4469, + "4470" => 4470, + "4471" => 4471, + "4472" => 4472, + "4473" => 4473, + "4474" => 4474, + "4475" => 4475, + "4476" => 4476, + "4477" => 4477, + "4478" => 4478, + "4479" => 4479, + "4480" => 4480, + "4481" => 4481, + "4482" => 4482, + "4483" => 4483, + "4484" => 4484, + "4485" => 4485, + "4486" => 4486, + "4487" => 4487, + "4488" => 4488, + "4489" => 4489, + "4490" => 4490, + "4491" => 4491, + "4492" => 4492, + "4493" => 4493, + "4494" => 4494, + "4495" => 4495, + "4496" => 4496, + "4497" => 4497, + "4498" => 4498, + "4499" => 4499, + "4500" => 4500, + "4501" => 4501, + "4502" => 4502, + "4503" => 4503, + "4504" => 4504, + "4505" => 4505, + "4506" => 4506, + "4507" => 4507, + "4508" => 4508, + "4509" => 4509, + "4510" => 4510, + "4511" => 4511, + "4512" => 4512, + "4513" => 4513, + "4514" => 4514, + "4515" => 4515, + "4516" => 4516, + "4517" => 4517, + "4518" => 4518, + "4519" => 4519, + "4520" => 4520, + "4521" => 4521, + "4522" => 4522, + "4523" => 4523, + "4524" => 4524, + "4525" => 4525, + "4526" => 4526, + "4527" => 4527, + "4528" => 4528, + "4529" => 4529, + "4530" => 4530, + "4531" => 4531, + "4532" => 4532, + "4533" => 4533, + "4534" => 4534, + "4535" => 4535, + "4536" => 4536, + "4537" => 4537, + "4538" => 4538, + "4539" => 4539, + "4540" => 4540, + "4541" => 4541, + "4542" => 4542, + "4543" => 4543, + "4544" => 4544, + "4545" => 4545, + "4546" => 4546, + "4547" => 4547, + "4548" => 4548, + "4549" => 4549, + "4550" => 4550, + "4551" => 4551, + "4552" => 4552, + "4553" => 4553, + "4554" => 4554, + "4555" => 4555, + "4556" => 4556, + "4557" => 4557, + "4558" => 4558, + "4559" => 4559, + "4560" => 4560, + "4561" => 4561, + "4562" => 4562, + "4563" => 4563, + "4564" => 4564, + "4565" => 4565, + "4566" => 4566, + "4567" => 4567, + "4568" => 4568, + "4569" => 4569, + "4570" => 4570, + "4571" => 4571, + "4572" => 4572, + "4573" => 4573, + "4574" => 4574, + "4575" => 4575, + "4576" => 4576, + "4577" => 4577, + "4578" => 4578, + "4579" => 4579, + "4580" => 4580, + "4581" => 4581, + "4582" => 4582, + "4583" => 4583, + "4584" => 4584, + "4585" => 4585, + "4586" => 4586, + "4587" => 4587, + "4588" => 4588, + "4589" => 4589, + "4590" => 4590, + "4591" => 4591, + "4592" => 4592, + "4593" => 4593, + "4594" => 4594, + "4595" => 4595, + "4596" => 4596, + "4597" => 4597, + "4598" => 4598, + "4599" => 4599, + "4600" => 4600, + "4601" => 4601, + "4602" => 4602, + "4603" => 4603, + "4604" => 4604, + "4605" => 4605, + "4606" => 4606, + "4607" => 4607, + "4608" => 4608, + "4609" => 4609, + "4610" => 4610, + "4611" => 4611, + "4612" => 4612, + "4613" => 4613, + "4614" => 4614, + "4615" => 4615, + "4616" => 4616, + "4617" => 4617, + "4618" => 4618, + "4619" => 4619, + "4620" => 4620, + "4621" => 4621, + "4622" => 4622, + "4623" => 4623, + "4624" => 4624, + "4625" => 4625, + "4626" => 4626, + "4627" => 4627, + "4628" => 4628, + "4629" => 4629, + "4630" => 4630, + "4631" => 4631, + "4632" => 4632, + "4633" => 4633, + "4634" => 4634, + "4635" => 4635, + "4636" => 4636, + "4637" => 4637, + "4638" => 4638, + "4639" => 4639, + "4640" => 4640, + "4641" => 4641, + "4642" => 4642, + "4643" => 4643, + "4644" => 4644, + "4645" => 4645, + "4646" => 4646, + "4647" => 4647, + "4648" => 4648, + "4649" => 4649, + "4650" => 4650, + "4651" => 4651, + "4652" => 4652, + "4653" => 4653, + "4654" => 4654, + "4655" => 4655, + "4656" => 4656, + "4657" => 4657, + "4658" => 4658, + "4659" => 4659, + "4660" => 4660, + "4661" => 4661, + "4662" => 4662, + "4663" => 4663, + "4664" => 4664, + "4665" => 4665, + "4666" => 4666, + "4667" => 4667, + "4668" => 4668, + "4669" => 4669, + "4670" => 4670, + "4671" => 4671, + "4672" => 4672, + "4673" => 4673, + "4674" => 4674, + "4675" => 4675, + "4676" => 4676, + "4677" => 4677, + "4678" => 4678, + "4679" => 4679, + "4680" => 4680, + "4681" => 4681, + "4682" => 4682, + "4683" => 4683, + "4684" => 4684, + "4685" => 4685, + "4686" => 4686, + "4687" => 4687, + "4688" => 4688, + "4689" => 4689, + "4690" => 4690, + "4691" => 4691, + "4692" => 4692, + "4693" => 4693, + "4694" => 4694, + "4695" => 4695, + "4696" => 4696, + "4697" => 4697, + "4698" => 4698, + "4699" => 4699, + "4700" => 4700, + "4701" => 4701, + "4702" => 4702, + "4703" => 4703, + "4704" => 4704, + "4705" => 4705, + "4706" => 4706, + "4707" => 4707, + "4708" => 4708, + "4709" => 4709, + "4710" => 4710, + "4711" => 4711, + "4712" => 4712, + "4713" => 4713, + "4714" => 4714, + "4715" => 4715, + "4716" => 4716, + "4717" => 4717, + "4718" => 4718, + "4719" => 4719, + "4720" => 4720, + "4721" => 4721, + "4722" => 4722, + "4723" => 4723, + "4724" => 4724, + "4725" => 4725, + "4726" => 4726, + "4727" => 4727, + "4728" => 4728, + "4729" => 4729, + "4730" => 4730, + "4731" => 4731, + "4732" => 4732, + "4733" => 4733, + "4734" => 4734, + "4735" => 4735, + "4736" => 4736, + "4737" => 4737, + "4738" => 4738, + "4739" => 4739, + "4740" => 4740, + "4741" => 4741, + "4742" => 4742, + "4743" => 4743, + "4744" => 4744, + "4745" => 4745, + "4746" => 4746, + "4747" => 4747, + "4748" => 4748, + "4749" => 4749, + "4750" => 4750, + "4751" => 4751, + "4752" => 4752, + "4753" => 4753, + "4754" => 4754, + "4755" => 4755, + "4756" => 4756, + "4757" => 4757, + "4758" => 4758, + "4759" => 4759, + "4760" => 4760, + "4761" => 4761, + "4762" => 4762, + "4763" => 4763, + "4764" => 4764, + "4765" => 4765, + "4766" => 4766, + "4767" => 4767, + "4768" => 4768, + "4769" => 4769, + "4770" => 4770, + "4771" => 4771, + "4772" => 4772, + "4773" => 4773, + "4774" => 4774, + "4775" => 4775, + "4776" => 4776, + "4777" => 4777, + "4778" => 4778, + "4779" => 4779, + "4780" => 4780, + "4781" => 4781, + "4782" => 4782, + "4783" => 4783, + "4784" => 4784, + "4785" => 4785, + "4786" => 4786, + "4787" => 4787, + "4788" => 4788, + "4789" => 4789, + "4790" => 4790, + "4791" => 4791, + "4792" => 4792, + "4793" => 4793, + "4794" => 4794, + "4795" => 4795, + "4796" => 4796, + "4797" => 4797, + "4798" => 4798, + "4799" => 4799, + "4800" => 4800, + "4801" => 4801, + "4802" => 4802, + "4803" => 4803, + "4804" => 4804, + "4805" => 4805, + "4806" => 4806, + "4807" => 4807, + "4808" => 4808, + "4809" => 4809, + "4810" => 4810, + "4811" => 4811, + "4812" => 4812, + "4813" => 4813, + "4814" => 4814, + "4815" => 4815, + "4816" => 4816, + "4817" => 4817, + "4818" => 4818, + "4819" => 4819, + "4820" => 4820, + "4821" => 4821, + "4822" => 4822, + "4823" => 4823, + "4824" => 4824, + "4825" => 4825, + "4826" => 4826, + "4827" => 4827, + "4828" => 4828, + "4829" => 4829, + "4830" => 4830, + "4831" => 4831, + "4832" => 4832, + "4833" => 4833, + "4834" => 4834, + "4835" => 4835, + "4836" => 4836, + "4837" => 4837, + "4838" => 4838, + "4839" => 4839, + "4840" => 4840, + "4841" => 4841, + "4842" => 4842, + "4843" => 4843, + "4844" => 4844, + "4845" => 4845, + "4846" => 4846, + "4847" => 4847, + "4848" => 4848, + "4849" => 4849, + "4850" => 4850, + "4851" => 4851, + "4852" => 4852, + "4853" => 4853, + "4854" => 4854, + "4855" => 4855, + "4856" => 4856, + "4857" => 4857, + "4858" => 4858, + "4859" => 4859, + "4860" => 4860, + "4861" => 4861, + "4862" => 4862, + "4863" => 4863, + "4864" => 4864, + "4865" => 4865, + "4866" => 4866, + "4867" => 4867, + "4868" => 4868, + "4869" => 4869, + "4870" => 4870, + "4871" => 4871, + "4872" => 4872, + "4873" => 4873, + "4874" => 4874, + "4875" => 4875, + "4876" => 4876, + "4877" => 4877, + "4878" => 4878, + "4879" => 4879, + "4880" => 4880, + "4881" => 4881, + "4882" => 4882, + "4883" => 4883, + "4884" => 4884, + "4885" => 4885, + "4886" => 4886, + "4887" => 4887, + "4888" => 4888, + "4889" => 4889, + "4890" => 4890, + "4891" => 4891, + "4892" => 4892, + "4893" => 4893, + "4894" => 4894, + "4895" => 4895, + "4896" => 4896, + "4897" => 4897, + "4898" => 4898, + "4899" => 4899, + "4900" => 4900, + "4901" => 4901, + "4902" => 4902, + "4903" => 4903, + "4904" => 4904, + "4905" => 4905, + "4906" => 4906, + "4907" => 4907, + "4908" => 4908, + "4909" => 4909, + "4910" => 4910, + "4911" => 4911, + "4912" => 4912, + "4913" => 4913, + "4914" => 4914, + "4915" => 4915, + "4916" => 4916, + "4917" => 4917, + "4918" => 4918, + "4919" => 4919, + "4920" => 4920, + "4921" => 4921, + "4922" => 4922, + "4923" => 4923, + "4924" => 4924, + "4925" => 4925, + "4926" => 4926, + "4927" => 4927, + "4928" => 4928, + "4929" => 4929, + "4930" => 4930, + "4931" => 4931, + "4932" => 4932, + "4933" => 4933, + "4934" => 4934, + "4935" => 4935, + "4936" => 4936, + "4937" => 4937, + "4938" => 4938, + "4939" => 4939, + "4940" => 4940, + "4941" => 4941, + "4942" => 4942, + "4943" => 4943, + "4944" => 4944, + "4945" => 4945, + "4946" => 4946, + "4947" => 4947, + "4948" => 4948, + "4949" => 4949, + "4950" => 4950, + "4951" => 4951, + "4952" => 4952, + "4953" => 4953, + "4954" => 4954, + "4955" => 4955, + "4956" => 4956, + "4957" => 4957, + "4958" => 4958, + "4959" => 4959, + "4960" => 4960, + "4961" => 4961, + "4962" => 4962, + "4963" => 4963, + "4964" => 4964, + "4965" => 4965, + "4966" => 4966, + "4967" => 4967, + "4968" => 4968, + "4969" => 4969, + "4970" => 4970, + "4971" => 4971, + "4972" => 4972, + "4973" => 4973, + "4974" => 4974, + "4975" => 4975, + "4976" => 4976, + "4977" => 4977, + "4978" => 4978, + "4979" => 4979, + "4980" => 4980, + "4981" => 4981, + "4982" => 4982, + "4983" => 4983, + "4984" => 4984, + "4985" => 4985, + "4986" => 4986, + "4987" => 4987, + "4988" => 4988, + "4989" => 4989, + "4990" => 4990, + "4991" => 4991, + "4992" => 4992, + "4993" => 4993, + "4994" => 4994, + "4995" => 4995, + "4996" => 4996, + "4997" => 4997, + "4998" => 4998, + "4999" => 4999, + "5000" => 5000, + "5001" => 5001, + "5002" => 5002, + "5003" => 5003, + "5004" => 5004, + "5005" => 5005, + "5006" => 5006, + "5007" => 5007, + "5008" => 5008, + "5009" => 5009, + "5010" => 5010, + "5011" => 5011, + "5012" => 5012, + "5013" => 5013, + "5014" => 5014, + "5015" => 5015, + "5016" => 5016, + "5017" => 5017, + "5018" => 5018, + "5019" => 5019, + "5020" => 5020, + "5021" => 5021, + "5022" => 5022, + "5023" => 5023, + "5024" => 5024, + "5025" => 5025, + "5026" => 5026, + "5027" => 5027, + "5028" => 5028, + "5029" => 5029, + "5030" => 5030, + "5031" => 5031, + "5032" => 5032, + "5033" => 5033, + "5034" => 5034, + "5035" => 5035, + "5036" => 5036, + "5037" => 5037, + "5038" => 5038, + "5039" => 5039, + "5040" => 5040, + "5041" => 5041, + "5042" => 5042, + "5043" => 5043, + "5044" => 5044, + "5045" => 5045, + "5046" => 5046, + "5047" => 5047, + "5048" => 5048, + "5049" => 5049, + "5050" => 5050, + "5051" => 5051, + "5052" => 5052, + "5053" => 5053, + "5054" => 5054, + "5055" => 5055, + "5056" => 5056, + "5057" => 5057, + "5058" => 5058, + "5059" => 5059, + "5060" => 5060, + "5061" => 5061, + "5062" => 5062, + "5063" => 5063, + "5064" => 5064, + "5065" => 5065, + "5066" => 5066, + "5067" => 5067, + "5068" => 5068, + "5069" => 5069, + "5070" => 5070, + "5071" => 5071, + "5072" => 5072, + "5073" => 5073, + "5074" => 5074, + "5075" => 5075, + "5076" => 5076, + "5077" => 5077, + "5078" => 5078, + "5079" => 5079, + "5080" => 5080, + "5081" => 5081, + "5082" => 5082, + "5083" => 5083, + "5084" => 5084, + "5085" => 5085, + "5086" => 5086, + "5087" => 5087, + "5088" => 5088, + "5089" => 5089, + "5090" => 5090, + "5091" => 5091, + "5092" => 5092, + "5093" => 5093, + "5094" => 5094, + "5095" => 5095, + "5096" => 5096, + "5097" => 5097, + "5098" => 5098, + "5099" => 5099, + "5100" => 5100, + "5101" => 5101, + "5102" => 5102, + "5103" => 5103, + "5104" => 5104, + "5105" => 5105, + "5106" => 5106, + "5107" => 5107, + "5108" => 5108, + "5109" => 5109, + "5110" => 5110, + "5111" => 5111, + "5112" => 5112, + "5113" => 5113, + "5114" => 5114, + "5115" => 5115, + "5116" => 5116, + "5117" => 5117, + "5118" => 5118, + "5119" => 5119, + "5120" => 5120, + "5121" => 5121, + "5122" => 5122, + "5123" => 5123, + "5124" => 5124, + "5125" => 5125, + "5126" => 5126, + "5127" => 5127, + "5128" => 5128, + "5129" => 5129, + "5130" => 5130, + "5131" => 5131, + "5132" => 5132, + "5133" => 5133, + "5134" => 5134, + "5135" => 5135, + "5136" => 5136, + "5137" => 5137, + "5138" => 5138, + "5139" => 5139, + "5140" => 5140, + "5141" => 5141, + "5142" => 5142, + "5143" => 5143, + "5144" => 5144, + "5145" => 5145, + "5146" => 5146, + "5147" => 5147, + "5148" => 5148, + "5149" => 5149, + "5150" => 5150, + "5151" => 5151, + "5152" => 5152, + "5153" => 5153, + "5154" => 5154, + "5155" => 5155, + "5156" => 5156, + "5157" => 5157, + "5158" => 5158, + "5159" => 5159, + "5160" => 5160, + "5161" => 5161, + "5162" => 5162, + "5163" => 5163, + "5164" => 5164, + "5165" => 5165, + "5166" => 5166, + "5167" => 5167, + "5168" => 5168, + "5169" => 5169, + "5170" => 5170, + "5171" => 5171, + "5172" => 5172, + "5173" => 5173, + "5174" => 5174, + "5175" => 5175, + "5176" => 5176, + "5177" => 5177, + "5178" => 5178, + "5179" => 5179, + "5180" => 5180, + "5181" => 5181, + "5182" => 5182, + "5183" => 5183, + "5184" => 5184, + "5185" => 5185, + "5186" => 5186, + "5187" => 5187, + "5188" => 5188, + "5189" => 5189, + "5190" => 5190, + "5191" => 5191, + "5192" => 5192, + "5193" => 5193, + "5194" => 5194, + "5195" => 5195, + "5196" => 5196, + "5197" => 5197, + "5198" => 5198, + _ => 5199, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-73112.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-73112.rs new file mode 100644 index 000000000000..bda12acd2097 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-73112.rs @@ -0,0 +1,14 @@ +// aux-build:issue-73112.rs + +extern crate issue_73112; + +fn main() { + use issue_73112::PageTable; + + #[repr(C, packed)] + struct SomeStruct { +// { dg-error ".E0588." "" { target *-*-* } .-1 } + page_table: PageTable, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-73229.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-73229.rs new file mode 100644 index 000000000000..14b2b04d5407 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-73229.rs @@ -0,0 +1,34 @@ +// check-pass + +fn any() -> T { + loop {} +} + +trait Foo { + type V; +} + +trait Callback: Fn(&T, &T::V) {} +impl Callback for F {} + +struct Bar { + callback: Box>, +} + +impl Bar { + fn event(&self) { + (self.callback)(any(), any()); + } +} + +struct A; +struct B; +impl Foo for A { + type V = B; +} + +fn main() { + let foo = Bar:: { callback: Box::new(|_: &A, _: &B| ()) }; + foo.event(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-73427.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-73427.rs new file mode 100644 index 000000000000..1adbb451b172 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-73427.rs @@ -0,0 +1,45 @@ +enum A { + StructWithFields { x: () }, + TupleWithFields(()), + Struct {}, + Tuple(), + Unit, +} + +enum B { + StructWithFields { x: () }, + TupleWithFields(()), +} + +enum C { + StructWithFields { x: () }, + TupleWithFields(()), + Unit, +} + +enum D { + TupleWithFields(()), + Unit, +} + +fn main() { + // Only variants without fields are suggested (and others mentioned in a note) where an enum + // is used rather than a variant. + + A.foo(); +// { dg-error ".E0423." "" { target *-*-* } .-1 } + B.foo(); +// { dg-error ".E0423." "" { target *-*-* } .-1 } + C.foo(); +// { dg-error ".E0423." "" { target *-*-* } .-1 } + D.foo(); +// { dg-error ".E0423." "" { target *-*-* } .-1 } + + // Only tuple variants are suggested in calls or tuple struct pattern matching. + + let x = A(3); +// { dg-error ".E0423." "" { target *-*-* } .-1 } + if let A(3) = x { } +// { dg-error ".E0532." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7344.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7344.rs new file mode 100644 index 000000000000..718ed38b3cf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7344.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(unused_must_use)] +// pretty-expanded FIXME #23616 + +#![allow(unreachable_code)] + +fn foo() -> bool { false } + +fn bar() { + return; + !foo(); +} + +fn baz() { + return; + if "" == "" {} +} + +pub fn main() { + bar(); + baz(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-73541-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-73541-1.rs new file mode 100644 index 000000000000..8745e43ea3a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-73541-1.rs @@ -0,0 +1,13 @@ +// edition:2018 + +fn main() { + 'a: loop { + async { + loop { + continue 'a +// { dg-error ".E0767." "" { target *-*-* } .-1 } + } + }; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-73541-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-73541-2.rs new file mode 100644 index 000000000000..5a2015169492 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-73541-2.rs @@ -0,0 +1,21 @@ +// edition:2018 + +async fn c() { + 'a: loop { + macro_rules! b { + () => { + continue 'a +// { dg-error ".E0767." "" { target *-*-* } .-1 } + } + } + + async { + loop { + b!(); + } + }; + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-73541-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-73541-3.rs new file mode 100644 index 000000000000..c65284d307dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-73541-3.rs @@ -0,0 +1,10 @@ +fn main() { + 'aaaaab: loop { + || { + loop { continue 'aaaaaa } +// { dg-error ".E0426." "" { target *-*-* } .-1 } + }; + + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-73541.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-73541.rs new file mode 100644 index 000000000000..5c521d90565e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-73541.rs @@ -0,0 +1,10 @@ +fn main() { + 'a: loop { + || { + loop { continue 'a } +// { dg-error ".E0767." "" { target *-*-* } .-1 } + }; + + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7364.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7364.rs new file mode 100644 index 000000000000..24d4529c8571 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7364.rs @@ -0,0 +1,11 @@ +#![feature(box_syntax)] + +use std::cell::RefCell; + +// Regression test for issue 7364 +static boxed: Box> = box RefCell::new(0); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-73886.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-73886.rs new file mode 100644 index 000000000000..4ba289126c84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-73886.rs @@ -0,0 +1,7 @@ +fn main() { + let _ = &&[0] as &[_]; +// { dg-error ".E0605." "" { target *-*-* } .-1 } + let _ = 7u32 as Option<_>; +// { dg-error ".E0605." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-74082.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-74082.rs new file mode 100644 index 000000000000..42f58a034237 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-74082.rs @@ -0,0 +1,10 @@ +#![allow(dead_code)] + +#[repr(i128)] // { dg-error ".E0517." "" { target *-*-* } } +struct Foo; + +#[repr(u128)] // { dg-error ".E0517." "" { target *-*-* } } +struct Bar; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-74086.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-74086.rs new file mode 100644 index 000000000000..2760502e855e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-74086.rs @@ -0,0 +1,5 @@ +fn main() { + static BUG: fn(_) -> u8 = |_| 8; +// { dg-error ".E0121." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-74236/auxiliary/dep.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-74236/auxiliary/dep.rs new file mode 100644 index 000000000000..ce6b96b01e69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-74236/auxiliary/dep.rs @@ -0,0 +1,9 @@ +// edition:2018 + +mod private { pub struct Pub; } + +// Reexport built-in attribute without a DefId (requires Rust 2018). +pub use cfg_attr as attr; +// This export needs to be after the built-in attribute to trigger the bug. +pub use private::Pub as Renamed; + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-74236/main.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-74236/main.rs new file mode 100644 index 000000000000..259c2ee4dbc4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-74236/main.rs @@ -0,0 +1,10 @@ +// edition:2018 +// aux-build:dep.rs +// compile-flags:--extern dep + +fn main() { + // Trigger an error that will print the path of dep::private::Pub (as "dep::Renamed"). + let () = dep::Renamed; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-74564-if-expr-stack-overflow.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-74564-if-expr-stack-overflow.rs new file mode 100644 index 000000000000..1d32cc710973 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-74564-if-expr-stack-overflow.rs @@ -0,0 +1,10421 @@ +// build-pass +// ignore-tidy-filelength +// ignore-compare-mode-chalk +#![crate_type = "rlib"] + +fn banana(v: &str) -> u32 { + if v == "1" { + 1 + } else if v == "2" { + 2 + } else if v == "3" { + 3 + } else if v == "4" { + 4 + } else if v == "5" { + 5 + } else if v == "6" { + 6 + } else if v == "7" { + 7 + } else if v == "8" { + 8 + } else if v == "9" { + 9 + } else if v == "10" { + 10 + } else if v == "11" { + 11 + } else if v == "12" { + 12 + } else if v == "13" { + 13 + } else if v == "14" { + 14 + } else if v == "15" { + 15 + } else if v == "16" { + 16 + } else if v == "17" { + 17 + } else if v == "18" { + 18 + } else if v == "19" { + 19 + } else if v == "20" { + 20 + } else if v == "21" { + 21 + } else if v == "22" { + 22 + } else if v == "23" { + 23 + } else if v == "24" { + 24 + } else if v == "25" { + 25 + } else if v == "26" { + 26 + } else if v == "27" { + 27 + } else if v == "28" { + 28 + } else if v == "29" { + 29 + } else if v == "30" { + 30 + } else if v == "31" { + 31 + } else if v == "32" { + 32 + } else if v == "33" { + 33 + } else if v == "34" { + 34 + } else if v == "35" { + 35 + } else if v == "36" { + 36 + } else if v == "37" { + 37 + } else if v == "38" { + 38 + } else if v == "39" { + 39 + } else if v == "40" { + 40 + } else if v == "41" { + 41 + } else if v == "42" { + 42 + } else if v == "43" { + 43 + } else if v == "44" { + 44 + } else if v == "45" { + 45 + } else if v == "46" { + 46 + } else if v == "47" { + 47 + } else if v == "48" { + 48 + } else if v == "49" { + 49 + } else if v == "50" { + 50 + } else if v == "51" { + 51 + } else if v == "52" { + 52 + } else if v == "53" { + 53 + } else if v == "54" { + 54 + } else if v == "55" { + 55 + } else if v == "56" { + 56 + } else if v == "57" { + 57 + } else if v == "58" { + 58 + } else if v == "59" { + 59 + } else if v == "60" { + 60 + } else if v == "61" { + 61 + } else if v == "62" { + 62 + } else if v == "63" { + 63 + } else if v == "64" { + 64 + } else if v == "65" { + 65 + } else if v == "66" { + 66 + } else if v == "67" { + 67 + } else if v == "68" { + 68 + } else if v == "69" { + 69 + } else if v == "70" { + 70 + } else if v == "71" { + 71 + } else if v == "72" { + 72 + } else if v == "73" { + 73 + } else if v == "74" { + 74 + } else if v == "75" { + 75 + } else if v == "76" { + 76 + } else if v == "77" { + 77 + } else if v == "78" { + 78 + } else if v == "79" { + 79 + } else if v == "80" { + 80 + } else if v == "81" { + 81 + } else if v == "82" { + 82 + } else if v == "83" { + 83 + } else if v == "84" { + 84 + } else if v == "85" { + 85 + } else if v == "86" { + 86 + } else if v == "87" { + 87 + } else if v == "88" { + 88 + } else if v == "89" { + 89 + } else if v == "90" { + 90 + } else if v == "91" { + 91 + } else if v == "92" { + 92 + } else if v == "93" { + 93 + } else if v == "94" { + 94 + } else if v == "95" { + 95 + } else if v == "96" { + 96 + } else if v == "97" { + 97 + } else if v == "98" { + 98 + } else if v == "99" { + 99 + } else if v == "100" { + 100 + } else if v == "101" { + 101 + } else if v == "102" { + 102 + } else if v == "103" { + 103 + } else if v == "104" { + 104 + } else if v == "105" { + 105 + } else if v == "106" { + 106 + } else if v == "107" { + 107 + } else if v == "108" { + 108 + } else if v == "109" { + 109 + } else if v == "110" { + 110 + } else if v == "111" { + 111 + } else if v == "112" { + 112 + } else if v == "113" { + 113 + } else if v == "114" { + 114 + } else if v == "115" { + 115 + } else if v == "116" { + 116 + } else if v == "117" { + 117 + } else if v == "118" { + 118 + } else if v == "119" { + 119 + } else if v == "120" { + 120 + } else if v == "121" { + 121 + } else if v == "122" { + 122 + } else if v == "123" { + 123 + } else if v == "124" { + 124 + } else if v == "125" { + 125 + } else if v == "126" { + 126 + } else if v == "127" { + 127 + } else if v == "128" { + 128 + } else if v == "129" { + 129 + } else if v == "130" { + 130 + } else if v == "131" { + 131 + } else if v == "132" { + 132 + } else if v == "133" { + 133 + } else if v == "134" { + 134 + } else if v == "135" { + 135 + } else if v == "136" { + 136 + } else if v == "137" { + 137 + } else if v == "138" { + 138 + } else if v == "139" { + 139 + } else if v == "140" { + 140 + } else if v == "141" { + 141 + } else if v == "142" { + 142 + } else if v == "143" { + 143 + } else if v == "144" { + 144 + } else if v == "145" { + 145 + } else if v == "146" { + 146 + } else if v == "147" { + 147 + } else if v == "148" { + 148 + } else if v == "149" { + 149 + } else if v == "150" { + 150 + } else if v == "151" { + 151 + } else if v == "152" { + 152 + } else if v == "153" { + 153 + } else if v == "154" { + 154 + } else if v == "155" { + 155 + } else if v == "156" { + 156 + } else if v == "157" { + 157 + } else if v == "158" { + 158 + } else if v == "159" { + 159 + } else if v == "160" { + 160 + } else if v == "161" { + 161 + } else if v == "162" { + 162 + } else if v == "163" { + 163 + } else if v == "164" { + 164 + } else if v == "165" { + 165 + } else if v == "166" { + 166 + } else if v == "167" { + 167 + } else if v == "168" { + 168 + } else if v == "169" { + 169 + } else if v == "170" { + 170 + } else if v == "171" { + 171 + } else if v == "172" { + 172 + } else if v == "173" { + 173 + } else if v == "174" { + 174 + } else if v == "175" { + 175 + } else if v == "176" { + 176 + } else if v == "177" { + 177 + } else if v == "178" { + 178 + } else if v == "179" { + 179 + } else if v == "180" { + 180 + } else if v == "181" { + 181 + } else if v == "182" { + 182 + } else if v == "183" { + 183 + } else if v == "184" { + 184 + } else if v == "185" { + 185 + } else if v == "186" { + 186 + } else if v == "187" { + 187 + } else if v == "188" { + 188 + } else if v == "189" { + 189 + } else if v == "190" { + 190 + } else if v == "191" { + 191 + } else if v == "192" { + 192 + } else if v == "193" { + 193 + } else if v == "194" { + 194 + } else if v == "195" { + 195 + } else if v == "196" { + 196 + } else if v == "197" { + 197 + } else if v == "198" { + 198 + } else if v == "199" { + 199 + } else if v == "200" { + 200 + } else if v == "201" { + 201 + } else if v == "202" { + 202 + } else if v == "203" { + 203 + } else if v == "204" { + 204 + } else if v == "205" { + 205 + } else if v == "206" { + 206 + } else if v == "207" { + 207 + } else if v == "208" { + 208 + } else if v == "209" { + 209 + } else if v == "210" { + 210 + } else if v == "211" { + 211 + } else if v == "212" { + 212 + } else if v == "213" { + 213 + } else if v == "214" { + 214 + } else if v == "215" { + 215 + } else if v == "216" { + 216 + } else if v == "217" { + 217 + } else if v == "218" { + 218 + } else if v == "219" { + 219 + } else if v == "220" { + 220 + } else if v == "221" { + 221 + } else if v == "222" { + 222 + } else if v == "223" { + 223 + } else if v == "224" { + 224 + } else if v == "225" { + 225 + } else if v == "226" { + 226 + } else if v == "227" { + 227 + } else if v == "228" { + 228 + } else if v == "229" { + 229 + } else if v == "230" { + 230 + } else if v == "231" { + 231 + } else if v == "232" { + 232 + } else if v == "233" { + 233 + } else if v == "234" { + 234 + } else if v == "235" { + 235 + } else if v == "236" { + 236 + } else if v == "237" { + 237 + } else if v == "238" { + 238 + } else if v == "239" { + 239 + } else if v == "240" { + 240 + } else if v == "241" { + 241 + } else if v == "242" { + 242 + } else if v == "243" { + 243 + } else if v == "244" { + 244 + } else if v == "245" { + 245 + } else if v == "246" { + 246 + } else if v == "247" { + 247 + } else if v == "248" { + 248 + } else if v == "249" { + 249 + } else if v == "250" { + 250 + } else if v == "251" { + 251 + } else if v == "252" { + 252 + } else if v == "253" { + 253 + } else if v == "254" { + 254 + } else if v == "255" { + 255 + } else if v == "256" { + 256 + } else if v == "257" { + 257 + } else if v == "258" { + 258 + } else if v == "259" { + 259 + } else if v == "260" { + 260 + } else if v == "261" { + 261 + } else if v == "262" { + 262 + } else if v == "263" { + 263 + } else if v == "264" { + 264 + } else if v == "265" { + 265 + } else if v == "266" { + 266 + } else if v == "267" { + 267 + } else if v == "268" { + 268 + } else if v == "269" { + 269 + } else if v == "270" { + 270 + } else if v == "271" { + 271 + } else if v == "272" { + 272 + } else if v == "273" { + 273 + } else if v == "274" { + 274 + } else if v == "275" { + 275 + } else if v == "276" { + 276 + } else if v == "277" { + 277 + } else if v == "278" { + 278 + } else if v == "279" { + 279 + } else if v == "280" { + 280 + } else if v == "281" { + 281 + } else if v == "282" { + 282 + } else if v == "283" { + 283 + } else if v == "284" { + 284 + } else if v == "285" { + 285 + } else if v == "286" { + 286 + } else if v == "287" { + 287 + } else if v == "288" { + 288 + } else if v == "289" { + 289 + } else if v == "290" { + 290 + } else if v == "291" { + 291 + } else if v == "292" { + 292 + } else if v == "293" { + 293 + } else if v == "294" { + 294 + } else if v == "295" { + 295 + } else if v == "296" { + 296 + } else if v == "297" { + 297 + } else if v == "298" { + 298 + } else if v == "299" { + 299 + } else if v == "300" { + 300 + } else if v == "301" { + 301 + } else if v == "302" { + 302 + } else if v == "303" { + 303 + } else if v == "304" { + 304 + } else if v == "305" { + 305 + } else if v == "306" { + 306 + } else if v == "307" { + 307 + } else if v == "308" { + 308 + } else if v == "309" { + 309 + } else if v == "310" { + 310 + } else if v == "311" { + 311 + } else if v == "312" { + 312 + } else if v == "313" { + 313 + } else if v == "314" { + 314 + } else if v == "315" { + 315 + } else if v == "316" { + 316 + } else if v == "317" { + 317 + } else if v == "318" { + 318 + } else if v == "319" { + 319 + } else if v == "320" { + 320 + } else if v == "321" { + 321 + } else if v == "322" { + 322 + } else if v == "323" { + 323 + } else if v == "324" { + 324 + } else if v == "325" { + 325 + } else if v == "326" { + 326 + } else if v == "327" { + 327 + } else if v == "328" { + 328 + } else if v == "329" { + 329 + } else if v == "330" { + 330 + } else if v == "331" { + 331 + } else if v == "332" { + 332 + } else if v == "333" { + 333 + } else if v == "334" { + 334 + } else if v == "335" { + 335 + } else if v == "336" { + 336 + } else if v == "337" { + 337 + } else if v == "338" { + 338 + } else if v == "339" { + 339 + } else if v == "340" { + 340 + } else if v == "341" { + 341 + } else if v == "342" { + 342 + } else if v == "343" { + 343 + } else if v == "344" { + 344 + } else if v == "345" { + 345 + } else if v == "346" { + 346 + } else if v == "347" { + 347 + } else if v == "348" { + 348 + } else if v == "349" { + 349 + } else if v == "350" { + 350 + } else if v == "351" { + 351 + } else if v == "352" { + 352 + } else if v == "353" { + 353 + } else if v == "354" { + 354 + } else if v == "355" { + 355 + } else if v == "356" { + 356 + } else if v == "357" { + 357 + } else if v == "358" { + 358 + } else if v == "359" { + 359 + } else if v == "360" { + 360 + } else if v == "361" { + 361 + } else if v == "362" { + 362 + } else if v == "363" { + 363 + } else if v == "364" { + 364 + } else if v == "365" { + 365 + } else if v == "366" { + 366 + } else if v == "367" { + 367 + } else if v == "368" { + 368 + } else if v == "369" { + 369 + } else if v == "370" { + 370 + } else if v == "371" { + 371 + } else if v == "372" { + 372 + } else if v == "373" { + 373 + } else if v == "374" { + 374 + } else if v == "375" { + 375 + } else if v == "376" { + 376 + } else if v == "377" { + 377 + } else if v == "378" { + 378 + } else if v == "379" { + 379 + } else if v == "380" { + 380 + } else if v == "381" { + 381 + } else if v == "382" { + 382 + } else if v == "383" { + 383 + } else if v == "384" { + 384 + } else if v == "385" { + 385 + } else if v == "386" { + 386 + } else if v == "387" { + 387 + } else if v == "388" { + 388 + } else if v == "389" { + 389 + } else if v == "390" { + 390 + } else if v == "391" { + 391 + } else if v == "392" { + 392 + } else if v == "393" { + 393 + } else if v == "394" { + 394 + } else if v == "395" { + 395 + } else if v == "396" { + 396 + } else if v == "397" { + 397 + } else if v == "398" { + 398 + } else if v == "399" { + 399 + } else if v == "400" { + 400 + } else if v == "401" { + 401 + } else if v == "402" { + 402 + } else if v == "403" { + 403 + } else if v == "404" { + 404 + } else if v == "405" { + 405 + } else if v == "406" { + 406 + } else if v == "407" { + 407 + } else if v == "408" { + 408 + } else if v == "409" { + 409 + } else if v == "410" { + 410 + } else if v == "411" { + 411 + } else if v == "412" { + 412 + } else if v == "413" { + 413 + } else if v == "414" { + 414 + } else if v == "415" { + 415 + } else if v == "416" { + 416 + } else if v == "417" { + 417 + } else if v == "418" { + 418 + } else if v == "419" { + 419 + } else if v == "420" { + 420 + } else if v == "421" { + 421 + } else if v == "422" { + 422 + } else if v == "423" { + 423 + } else if v == "424" { + 424 + } else if v == "425" { + 425 + } else if v == "426" { + 426 + } else if v == "427" { + 427 + } else if v == "428" { + 428 + } else if v == "429" { + 429 + } else if v == "430" { + 430 + } else if v == "431" { + 431 + } else if v == "432" { + 432 + } else if v == "433" { + 433 + } else if v == "434" { + 434 + } else if v == "435" { + 435 + } else if v == "436" { + 436 + } else if v == "437" { + 437 + } else if v == "438" { + 438 + } else if v == "439" { + 439 + } else if v == "440" { + 440 + } else if v == "441" { + 441 + } else if v == "442" { + 442 + } else if v == "443" { + 443 + } else if v == "444" { + 444 + } else if v == "445" { + 445 + } else if v == "446" { + 446 + } else if v == "447" { + 447 + } else if v == "448" { + 448 + } else if v == "449" { + 449 + } else if v == "450" { + 450 + } else if v == "451" { + 451 + } else if v == "452" { + 452 + } else if v == "453" { + 453 + } else if v == "454" { + 454 + } else if v == "455" { + 455 + } else if v == "456" { + 456 + } else if v == "457" { + 457 + } else if v == "458" { + 458 + } else if v == "459" { + 459 + } else if v == "460" { + 460 + } else if v == "461" { + 461 + } else if v == "462" { + 462 + } else if v == "463" { + 463 + } else if v == "464" { + 464 + } else if v == "465" { + 465 + } else if v == "466" { + 466 + } else if v == "467" { + 467 + } else if v == "468" { + 468 + } else if v == "469" { + 469 + } else if v == "470" { + 470 + } else if v == "471" { + 471 + } else if v == "472" { + 472 + } else if v == "473" { + 473 + } else if v == "474" { + 474 + } else if v == "475" { + 475 + } else if v == "476" { + 476 + } else if v == "477" { + 477 + } else if v == "478" { + 478 + } else if v == "479" { + 479 + } else if v == "480" { + 480 + } else if v == "481" { + 481 + } else if v == "482" { + 482 + } else if v == "483" { + 483 + } else if v == "484" { + 484 + } else if v == "485" { + 485 + } else if v == "486" { + 486 + } else if v == "487" { + 487 + } else if v == "488" { + 488 + } else if v == "489" { + 489 + } else if v == "490" { + 490 + } else if v == "491" { + 491 + } else if v == "492" { + 492 + } else if v == "493" { + 493 + } else if v == "494" { + 494 + } else if v == "495" { + 495 + } else if v == "496" { + 496 + } else if v == "497" { + 497 + } else if v == "498" { + 498 + } else if v == "499" { + 499 + } else if v == "500" { + 500 + } else if v == "501" { + 501 + } else if v == "502" { + 502 + } else if v == "503" { + 503 + } else if v == "504" { + 504 + } else if v == "505" { + 505 + } else if v == "506" { + 506 + } else if v == "507" { + 507 + } else if v == "508" { + 508 + } else if v == "509" { + 509 + } else if v == "510" { + 510 + } else if v == "511" { + 511 + } else if v == "512" { + 512 + } else if v == "513" { + 513 + } else if v == "514" { + 514 + } else if v == "515" { + 515 + } else if v == "516" { + 516 + } else if v == "517" { + 517 + } else if v == "518" { + 518 + } else if v == "519" { + 519 + } else if v == "520" { + 520 + } else if v == "521" { + 521 + } else if v == "522" { + 522 + } else if v == "523" { + 523 + } else if v == "524" { + 524 + } else if v == "525" { + 525 + } else if v == "526" { + 526 + } else if v == "527" { + 527 + } else if v == "528" { + 528 + } else if v == "529" { + 529 + } else if v == "530" { + 530 + } else if v == "531" { + 531 + } else if v == "532" { + 532 + } else if v == "533" { + 533 + } else if v == "534" { + 534 + } else if v == "535" { + 535 + } else if v == "536" { + 536 + } else if v == "537" { + 537 + } else if v == "538" { + 538 + } else if v == "539" { + 539 + } else if v == "540" { + 540 + } else if v == "541" { + 541 + } else if v == "542" { + 542 + } else if v == "543" { + 543 + } else if v == "544" { + 544 + } else if v == "545" { + 545 + } else if v == "546" { + 546 + } else if v == "547" { + 547 + } else if v == "548" { + 548 + } else if v == "549" { + 549 + } else if v == "550" { + 550 + } else if v == "551" { + 551 + } else if v == "552" { + 552 + } else if v == "553" { + 553 + } else if v == "554" { + 554 + } else if v == "555" { + 555 + } else if v == "556" { + 556 + } else if v == "557" { + 557 + } else if v == "558" { + 558 + } else if v == "559" { + 559 + } else if v == "560" { + 560 + } else if v == "561" { + 561 + } else if v == "562" { + 562 + } else if v == "563" { + 563 + } else if v == "564" { + 564 + } else if v == "565" { + 565 + } else if v == "566" { + 566 + } else if v == "567" { + 567 + } else if v == "568" { + 568 + } else if v == "569" { + 569 + } else if v == "570" { + 570 + } else if v == "571" { + 571 + } else if v == "572" { + 572 + } else if v == "573" { + 573 + } else if v == "574" { + 574 + } else if v == "575" { + 575 + } else if v == "576" { + 576 + } else if v == "577" { + 577 + } else if v == "578" { + 578 + } else if v == "579" { + 579 + } else if v == "580" { + 580 + } else if v == "581" { + 581 + } else if v == "582" { + 582 + } else if v == "583" { + 583 + } else if v == "584" { + 584 + } else if v == "585" { + 585 + } else if v == "586" { + 586 + } else if v == "587" { + 587 + } else if v == "588" { + 588 + } else if v == "589" { + 589 + } else if v == "590" { + 590 + } else if v == "591" { + 591 + } else if v == "592" { + 592 + } else if v == "593" { + 593 + } else if v == "594" { + 594 + } else if v == "595" { + 595 + } else if v == "596" { + 596 + } else if v == "597" { + 597 + } else if v == "598" { + 598 + } else if v == "599" { + 599 + } else if v == "600" { + 600 + } else if v == "601" { + 601 + } else if v == "602" { + 602 + } else if v == "603" { + 603 + } else if v == "604" { + 604 + } else if v == "605" { + 605 + } else if v == "606" { + 606 + } else if v == "607" { + 607 + } else if v == "608" { + 608 + } else if v == "609" { + 609 + } else if v == "610" { + 610 + } else if v == "611" { + 611 + } else if v == "612" { + 612 + } else if v == "613" { + 613 + } else if v == "614" { + 614 + } else if v == "615" { + 615 + } else if v == "616" { + 616 + } else if v == "617" { + 617 + } else if v == "618" { + 618 + } else if v == "619" { + 619 + } else if v == "620" { + 620 + } else if v == "621" { + 621 + } else if v == "622" { + 622 + } else if v == "623" { + 623 + } else if v == "624" { + 624 + } else if v == "625" { + 625 + } else if v == "626" { + 626 + } else if v == "627" { + 627 + } else if v == "628" { + 628 + } else if v == "629" { + 629 + } else if v == "630" { + 630 + } else if v == "631" { + 631 + } else if v == "632" { + 632 + } else if v == "633" { + 633 + } else if v == "634" { + 634 + } else if v == "635" { + 635 + } else if v == "636" { + 636 + } else if v == "637" { + 637 + } else if v == "638" { + 638 + } else if v == "639" { + 639 + } else if v == "640" { + 640 + } else if v == "641" { + 641 + } else if v == "642" { + 642 + } else if v == "643" { + 643 + } else if v == "644" { + 644 + } else if v == "645" { + 645 + } else if v == "646" { + 646 + } else if v == "647" { + 647 + } else if v == "648" { + 648 + } else if v == "649" { + 649 + } else if v == "650" { + 650 + } else if v == "651" { + 651 + } else if v == "652" { + 652 + } else if v == "653" { + 653 + } else if v == "654" { + 654 + } else if v == "655" { + 655 + } else if v == "656" { + 656 + } else if v == "657" { + 657 + } else if v == "658" { + 658 + } else if v == "659" { + 659 + } else if v == "660" { + 660 + } else if v == "661" { + 661 + } else if v == "662" { + 662 + } else if v == "663" { + 663 + } else if v == "664" { + 664 + } else if v == "665" { + 665 + } else if v == "666" { + 666 + } else if v == "667" { + 667 + } else if v == "668" { + 668 + } else if v == "669" { + 669 + } else if v == "670" { + 670 + } else if v == "671" { + 671 + } else if v == "672" { + 672 + } else if v == "673" { + 673 + } else if v == "674" { + 674 + } else if v == "675" { + 675 + } else if v == "676" { + 676 + } else if v == "677" { + 677 + } else if v == "678" { + 678 + } else if v == "679" { + 679 + } else if v == "680" { + 680 + } else if v == "681" { + 681 + } else if v == "682" { + 682 + } else if v == "683" { + 683 + } else if v == "684" { + 684 + } else if v == "685" { + 685 + } else if v == "686" { + 686 + } else if v == "687" { + 687 + } else if v == "688" { + 688 + } else if v == "689" { + 689 + } else if v == "690" { + 690 + } else if v == "691" { + 691 + } else if v == "692" { + 692 + } else if v == "693" { + 693 + } else if v == "694" { + 694 + } else if v == "695" { + 695 + } else if v == "696" { + 696 + } else if v == "697" { + 697 + } else if v == "698" { + 698 + } else if v == "699" { + 699 + } else if v == "700" { + 700 + } else if v == "701" { + 701 + } else if v == "702" { + 702 + } else if v == "703" { + 703 + } else if v == "704" { + 704 + } else if v == "705" { + 705 + } else if v == "706" { + 706 + } else if v == "707" { + 707 + } else if v == "708" { + 708 + } else if v == "709" { + 709 + } else if v == "710" { + 710 + } else if v == "711" { + 711 + } else if v == "712" { + 712 + } else if v == "713" { + 713 + } else if v == "714" { + 714 + } else if v == "715" { + 715 + } else if v == "716" { + 716 + } else if v == "717" { + 717 + } else if v == "718" { + 718 + } else if v == "719" { + 719 + } else if v == "720" { + 720 + } else if v == "721" { + 721 + } else if v == "722" { + 722 + } else if v == "723" { + 723 + } else if v == "724" { + 724 + } else if v == "725" { + 725 + } else if v == "726" { + 726 + } else if v == "727" { + 727 + } else if v == "728" { + 728 + } else if v == "729" { + 729 + } else if v == "730" { + 730 + } else if v == "731" { + 731 + } else if v == "732" { + 732 + } else if v == "733" { + 733 + } else if v == "734" { + 734 + } else if v == "735" { + 735 + } else if v == "736" { + 736 + } else if v == "737" { + 737 + } else if v == "738" { + 738 + } else if v == "739" { + 739 + } else if v == "740" { + 740 + } else if v == "741" { + 741 + } else if v == "742" { + 742 + } else if v == "743" { + 743 + } else if v == "744" { + 744 + } else if v == "745" { + 745 + } else if v == "746" { + 746 + } else if v == "747" { + 747 + } else if v == "748" { + 748 + } else if v == "749" { + 749 + } else if v == "750" { + 750 + } else if v == "751" { + 751 + } else if v == "752" { + 752 + } else if v == "753" { + 753 + } else if v == "754" { + 754 + } else if v == "755" { + 755 + } else if v == "756" { + 756 + } else if v == "757" { + 757 + } else if v == "758" { + 758 + } else if v == "759" { + 759 + } else if v == "760" { + 760 + } else if v == "761" { + 761 + } else if v == "762" { + 762 + } else if v == "763" { + 763 + } else if v == "764" { + 764 + } else if v == "765" { + 765 + } else if v == "766" { + 766 + } else if v == "767" { + 767 + } else if v == "768" { + 768 + } else if v == "769" { + 769 + } else if v == "770" { + 770 + } else if v == "771" { + 771 + } else if v == "772" { + 772 + } else if v == "773" { + 773 + } else if v == "774" { + 774 + } else if v == "775" { + 775 + } else if v == "776" { + 776 + } else if v == "777" { + 777 + } else if v == "778" { + 778 + } else if v == "779" { + 779 + } else if v == "780" { + 780 + } else if v == "781" { + 781 + } else if v == "782" { + 782 + } else if v == "783" { + 783 + } else if v == "784" { + 784 + } else if v == "785" { + 785 + } else if v == "786" { + 786 + } else if v == "787" { + 787 + } else if v == "788" { + 788 + } else if v == "789" { + 789 + } else if v == "790" { + 790 + } else if v == "791" { + 791 + } else if v == "792" { + 792 + } else if v == "793" { + 793 + } else if v == "794" { + 794 + } else if v == "795" { + 795 + } else if v == "796" { + 796 + } else if v == "797" { + 797 + } else if v == "798" { + 798 + } else if v == "799" { + 799 + } else if v == "800" { + 800 + } else if v == "801" { + 801 + } else if v == "802" { + 802 + } else if v == "803" { + 803 + } else if v == "804" { + 804 + } else if v == "805" { + 805 + } else if v == "806" { + 806 + } else if v == "807" { + 807 + } else if v == "808" { + 808 + } else if v == "809" { + 809 + } else if v == "810" { + 810 + } else if v == "811" { + 811 + } else if v == "812" { + 812 + } else if v == "813" { + 813 + } else if v == "814" { + 814 + } else if v == "815" { + 815 + } else if v == "816" { + 816 + } else if v == "817" { + 817 + } else if v == "818" { + 818 + } else if v == "819" { + 819 + } else if v == "820" { + 820 + } else if v == "821" { + 821 + } else if v == "822" { + 822 + } else if v == "823" { + 823 + } else if v == "824" { + 824 + } else if v == "825" { + 825 + } else if v == "826" { + 826 + } else if v == "827" { + 827 + } else if v == "828" { + 828 + } else if v == "829" { + 829 + } else if v == "830" { + 830 + } else if v == "831" { + 831 + } else if v == "832" { + 832 + } else if v == "833" { + 833 + } else if v == "834" { + 834 + } else if v == "835" { + 835 + } else if v == "836" { + 836 + } else if v == "837" { + 837 + } else if v == "838" { + 838 + } else if v == "839" { + 839 + } else if v == "840" { + 840 + } else if v == "841" { + 841 + } else if v == "842" { + 842 + } else if v == "843" { + 843 + } else if v == "844" { + 844 + } else if v == "845" { + 845 + } else if v == "846" { + 846 + } else if v == "847" { + 847 + } else if v == "848" { + 848 + } else if v == "849" { + 849 + } else if v == "850" { + 850 + } else if v == "851" { + 851 + } else if v == "852" { + 852 + } else if v == "853" { + 853 + } else if v == "854" { + 854 + } else if v == "855" { + 855 + } else if v == "856" { + 856 + } else if v == "857" { + 857 + } else if v == "858" { + 858 + } else if v == "859" { + 859 + } else if v == "860" { + 860 + } else if v == "861" { + 861 + } else if v == "862" { + 862 + } else if v == "863" { + 863 + } else if v == "864" { + 864 + } else if v == "865" { + 865 + } else if v == "866" { + 866 + } else if v == "867" { + 867 + } else if v == "868" { + 868 + } else if v == "869" { + 869 + } else if v == "870" { + 870 + } else if v == "871" { + 871 + } else if v == "872" { + 872 + } else if v == "873" { + 873 + } else if v == "874" { + 874 + } else if v == "875" { + 875 + } else if v == "876" { + 876 + } else if v == "877" { + 877 + } else if v == "878" { + 878 + } else if v == "879" { + 879 + } else if v == "880" { + 880 + } else if v == "881" { + 881 + } else if v == "882" { + 882 + } else if v == "883" { + 883 + } else if v == "884" { + 884 + } else if v == "885" { + 885 + } else if v == "886" { + 886 + } else if v == "887" { + 887 + } else if v == "888" { + 888 + } else if v == "889" { + 889 + } else if v == "890" { + 890 + } else if v == "891" { + 891 + } else if v == "892" { + 892 + } else if v == "893" { + 893 + } else if v == "894" { + 894 + } else if v == "895" { + 895 + } else if v == "896" { + 896 + } else if v == "897" { + 897 + } else if v == "898" { + 898 + } else if v == "899" { + 899 + } else if v == "900" { + 900 + } else if v == "901" { + 901 + } else if v == "902" { + 902 + } else if v == "903" { + 903 + } else if v == "904" { + 904 + } else if v == "905" { + 905 + } else if v == "906" { + 906 + } else if v == "907" { + 907 + } else if v == "908" { + 908 + } else if v == "909" { + 909 + } else if v == "910" { + 910 + } else if v == "911" { + 911 + } else if v == "912" { + 912 + } else if v == "913" { + 913 + } else if v == "914" { + 914 + } else if v == "915" { + 915 + } else if v == "916" { + 916 + } else if v == "917" { + 917 + } else if v == "918" { + 918 + } else if v == "919" { + 919 + } else if v == "920" { + 920 + } else if v == "921" { + 921 + } else if v == "922" { + 922 + } else if v == "923" { + 923 + } else if v == "924" { + 924 + } else if v == "925" { + 925 + } else if v == "926" { + 926 + } else if v == "927" { + 927 + } else if v == "928" { + 928 + } else if v == "929" { + 929 + } else if v == "930" { + 930 + } else if v == "931" { + 931 + } else if v == "932" { + 932 + } else if v == "933" { + 933 + } else if v == "934" { + 934 + } else if v == "935" { + 935 + } else if v == "936" { + 936 + } else if v == "937" { + 937 + } else if v == "938" { + 938 + } else if v == "939" { + 939 + } else if v == "940" { + 940 + } else if v == "941" { + 941 + } else if v == "942" { + 942 + } else if v == "943" { + 943 + } else if v == "944" { + 944 + } else if v == "945" { + 945 + } else if v == "946" { + 946 + } else if v == "947" { + 947 + } else if v == "948" { + 948 + } else if v == "949" { + 949 + } else if v == "950" { + 950 + } else if v == "951" { + 951 + } else if v == "952" { + 952 + } else if v == "953" { + 953 + } else if v == "954" { + 954 + } else if v == "955" { + 955 + } else if v == "956" { + 956 + } else if v == "957" { + 957 + } else if v == "958" { + 958 + } else if v == "959" { + 959 + } else if v == "960" { + 960 + } else if v == "961" { + 961 + } else if v == "962" { + 962 + } else if v == "963" { + 963 + } else if v == "964" { + 964 + } else if v == "965" { + 965 + } else if v == "966" { + 966 + } else if v == "967" { + 967 + } else if v == "968" { + 968 + } else if v == "969" { + 969 + } else if v == "970" { + 970 + } else if v == "971" { + 971 + } else if v == "972" { + 972 + } else if v == "973" { + 973 + } else if v == "974" { + 974 + } else if v == "975" { + 975 + } else if v == "976" { + 976 + } else if v == "977" { + 977 + } else if v == "978" { + 978 + } else if v == "979" { + 979 + } else if v == "980" { + 980 + } else if v == "981" { + 981 + } else if v == "982" { + 982 + } else if v == "983" { + 983 + } else if v == "984" { + 984 + } else if v == "985" { + 985 + } else if v == "986" { + 986 + } else if v == "987" { + 987 + } else if v == "988" { + 988 + } else if v == "989" { + 989 + } else if v == "990" { + 990 + } else if v == "991" { + 991 + } else if v == "992" { + 992 + } else if v == "993" { + 993 + } else if v == "994" { + 994 + } else if v == "995" { + 995 + } else if v == "996" { + 996 + } else if v == "997" { + 997 + } else if v == "998" { + 998 + } else if v == "999" { + 999 + } else if v == "1000" { + 1000 + } else if v == "1001" { + 1001 + } else if v == "1002" { + 1002 + } else if v == "1003" { + 1003 + } else if v == "1004" { + 1004 + } else if v == "1005" { + 1005 + } else if v == "1006" { + 1006 + } else if v == "1007" { + 1007 + } else if v == "1008" { + 1008 + } else if v == "1009" { + 1009 + } else if v == "1010" { + 1010 + } else if v == "1011" { + 1011 + } else if v == "1012" { + 1012 + } else if v == "1013" { + 1013 + } else if v == "1014" { + 1014 + } else if v == "1015" { + 1015 + } else if v == "1016" { + 1016 + } else if v == "1017" { + 1017 + } else if v == "1018" { + 1018 + } else if v == "1019" { + 1019 + } else if v == "1020" { + 1020 + } else if v == "1021" { + 1021 + } else if v == "1022" { + 1022 + } else if v == "1023" { + 1023 + } else if v == "1024" { + 1024 + } else if v == "1025" { + 1025 + } else if v == "1026" { + 1026 + } else if v == "1027" { + 1027 + } else if v == "1028" { + 1028 + } else if v == "1029" { + 1029 + } else if v == "1030" { + 1030 + } else if v == "1031" { + 1031 + } else if v == "1032" { + 1032 + } else if v == "1033" { + 1033 + } else if v == "1034" { + 1034 + } else if v == "1035" { + 1035 + } else if v == "1036" { + 1036 + } else if v == "1037" { + 1037 + } else if v == "1038" { + 1038 + } else if v == "1039" { + 1039 + } else if v == "1040" { + 1040 + } else if v == "1041" { + 1041 + } else if v == "1042" { + 1042 + } else if v == "1043" { + 1043 + } else if v == "1044" { + 1044 + } else if v == "1045" { + 1045 + } else if v == "1046" { + 1046 + } else if v == "1047" { + 1047 + } else if v == "1048" { + 1048 + } else if v == "1049" { + 1049 + } else if v == "1050" { + 1050 + } else if v == "1051" { + 1051 + } else if v == "1052" { + 1052 + } else if v == "1053" { + 1053 + } else if v == "1054" { + 1054 + } else if v == "1055" { + 1055 + } else if v == "1056" { + 1056 + } else if v == "1057" { + 1057 + } else if v == "1058" { + 1058 + } else if v == "1059" { + 1059 + } else if v == "1060" { + 1060 + } else if v == "1061" { + 1061 + } else if v == "1062" { + 1062 + } else if v == "1063" { + 1063 + } else if v == "1064" { + 1064 + } else if v == "1065" { + 1065 + } else if v == "1066" { + 1066 + } else if v == "1067" { + 1067 + } else if v == "1068" { + 1068 + } else if v == "1069" { + 1069 + } else if v == "1070" { + 1070 + } else if v == "1071" { + 1071 + } else if v == "1072" { + 1072 + } else if v == "1073" { + 1073 + } else if v == "1074" { + 1074 + } else if v == "1075" { + 1075 + } else if v == "1076" { + 1076 + } else if v == "1077" { + 1077 + } else if v == "1078" { + 1078 + } else if v == "1079" { + 1079 + } else if v == "1080" { + 1080 + } else if v == "1081" { + 1081 + } else if v == "1082" { + 1082 + } else if v == "1083" { + 1083 + } else if v == "1084" { + 1084 + } else if v == "1085" { + 1085 + } else if v == "1086" { + 1086 + } else if v == "1087" { + 1087 + } else if v == "1088" { + 1088 + } else if v == "1089" { + 1089 + } else if v == "1090" { + 1090 + } else if v == "1091" { + 1091 + } else if v == "1092" { + 1092 + } else if v == "1093" { + 1093 + } else if v == "1094" { + 1094 + } else if v == "1095" { + 1095 + } else if v == "1096" { + 1096 + } else if v == "1097" { + 1097 + } else if v == "1098" { + 1098 + } else if v == "1099" { + 1099 + } else if v == "1100" { + 1100 + } else if v == "1101" { + 1101 + } else if v == "1102" { + 1102 + } else if v == "1103" { + 1103 + } else if v == "1104" { + 1104 + } else if v == "1105" { + 1105 + } else if v == "1106" { + 1106 + } else if v == "1107" { + 1107 + } else if v == "1108" { + 1108 + } else if v == "1109" { + 1109 + } else if v == "1110" { + 1110 + } else if v == "1111" { + 1111 + } else if v == "1112" { + 1112 + } else if v == "1113" { + 1113 + } else if v == "1114" { + 1114 + } else if v == "1115" { + 1115 + } else if v == "1116" { + 1116 + } else if v == "1117" { + 1117 + } else if v == "1118" { + 1118 + } else if v == "1119" { + 1119 + } else if v == "1120" { + 1120 + } else if v == "1121" { + 1121 + } else if v == "1122" { + 1122 + } else if v == "1123" { + 1123 + } else if v == "1124" { + 1124 + } else if v == "1125" { + 1125 + } else if v == "1126" { + 1126 + } else if v == "1127" { + 1127 + } else if v == "1128" { + 1128 + } else if v == "1129" { + 1129 + } else if v == "1130" { + 1130 + } else if v == "1131" { + 1131 + } else if v == "1132" { + 1132 + } else if v == "1133" { + 1133 + } else if v == "1134" { + 1134 + } else if v == "1135" { + 1135 + } else if v == "1136" { + 1136 + } else if v == "1137" { + 1137 + } else if v == "1138" { + 1138 + } else if v == "1139" { + 1139 + } else if v == "1140" { + 1140 + } else if v == "1141" { + 1141 + } else if v == "1142" { + 1142 + } else if v == "1143" { + 1143 + } else if v == "1144" { + 1144 + } else if v == "1145" { + 1145 + } else if v == "1146" { + 1146 + } else if v == "1147" { + 1147 + } else if v == "1148" { + 1148 + } else if v == "1149" { + 1149 + } else if v == "1150" { + 1150 + } else if v == "1151" { + 1151 + } else if v == "1152" { + 1152 + } else if v == "1153" { + 1153 + } else if v == "1154" { + 1154 + } else if v == "1155" { + 1155 + } else if v == "1156" { + 1156 + } else if v == "1157" { + 1157 + } else if v == "1158" { + 1158 + } else if v == "1159" { + 1159 + } else if v == "1160" { + 1160 + } else if v == "1161" { + 1161 + } else if v == "1162" { + 1162 + } else if v == "1163" { + 1163 + } else if v == "1164" { + 1164 + } else if v == "1165" { + 1165 + } else if v == "1166" { + 1166 + } else if v == "1167" { + 1167 + } else if v == "1168" { + 1168 + } else if v == "1169" { + 1169 + } else if v == "1170" { + 1170 + } else if v == "1171" { + 1171 + } else if v == "1172" { + 1172 + } else if v == "1173" { + 1173 + } else if v == "1174" { + 1174 + } else if v == "1175" { + 1175 + } else if v == "1176" { + 1176 + } else if v == "1177" { + 1177 + } else if v == "1178" { + 1178 + } else if v == "1179" { + 1179 + } else if v == "1180" { + 1180 + } else if v == "1181" { + 1181 + } else if v == "1182" { + 1182 + } else if v == "1183" { + 1183 + } else if v == "1184" { + 1184 + } else if v == "1185" { + 1185 + } else if v == "1186" { + 1186 + } else if v == "1187" { + 1187 + } else if v == "1188" { + 1188 + } else if v == "1189" { + 1189 + } else if v == "1190" { + 1190 + } else if v == "1191" { + 1191 + } else if v == "1192" { + 1192 + } else if v == "1193" { + 1193 + } else if v == "1194" { + 1194 + } else if v == "1195" { + 1195 + } else if v == "1196" { + 1196 + } else if v == "1197" { + 1197 + } else if v == "1198" { + 1198 + } else if v == "1199" { + 1199 + } else if v == "1200" { + 1200 + } else if v == "1201" { + 1201 + } else if v == "1202" { + 1202 + } else if v == "1203" { + 1203 + } else if v == "1204" { + 1204 + } else if v == "1205" { + 1205 + } else if v == "1206" { + 1206 + } else if v == "1207" { + 1207 + } else if v == "1208" { + 1208 + } else if v == "1209" { + 1209 + } else if v == "1210" { + 1210 + } else if v == "1211" { + 1211 + } else if v == "1212" { + 1212 + } else if v == "1213" { + 1213 + } else if v == "1214" { + 1214 + } else if v == "1215" { + 1215 + } else if v == "1216" { + 1216 + } else if v == "1217" { + 1217 + } else if v == "1218" { + 1218 + } else if v == "1219" { + 1219 + } else if v == "1220" { + 1220 + } else if v == "1221" { + 1221 + } else if v == "1222" { + 1222 + } else if v == "1223" { + 1223 + } else if v == "1224" { + 1224 + } else if v == "1225" { + 1225 + } else if v == "1226" { + 1226 + } else if v == "1227" { + 1227 + } else if v == "1228" { + 1228 + } else if v == "1229" { + 1229 + } else if v == "1230" { + 1230 + } else if v == "1231" { + 1231 + } else if v == "1232" { + 1232 + } else if v == "1233" { + 1233 + } else if v == "1234" { + 1234 + } else if v == "1235" { + 1235 + } else if v == "1236" { + 1236 + } else if v == "1237" { + 1237 + } else if v == "1238" { + 1238 + } else if v == "1239" { + 1239 + } else if v == "1240" { + 1240 + } else if v == "1241" { + 1241 + } else if v == "1242" { + 1242 + } else if v == "1243" { + 1243 + } else if v == "1244" { + 1244 + } else if v == "1245" { + 1245 + } else if v == "1246" { + 1246 + } else if v == "1247" { + 1247 + } else if v == "1248" { + 1248 + } else if v == "1249" { + 1249 + } else if v == "1250" { + 1250 + } else if v == "1251" { + 1251 + } else if v == "1252" { + 1252 + } else if v == "1253" { + 1253 + } else if v == "1254" { + 1254 + } else if v == "1255" { + 1255 + } else if v == "1256" { + 1256 + } else if v == "1257" { + 1257 + } else if v == "1258" { + 1258 + } else if v == "1259" { + 1259 + } else if v == "1260" { + 1260 + } else if v == "1261" { + 1261 + } else if v == "1262" { + 1262 + } else if v == "1263" { + 1263 + } else if v == "1264" { + 1264 + } else if v == "1265" { + 1265 + } else if v == "1266" { + 1266 + } else if v == "1267" { + 1267 + } else if v == "1268" { + 1268 + } else if v == "1269" { + 1269 + } else if v == "1270" { + 1270 + } else if v == "1271" { + 1271 + } else if v == "1272" { + 1272 + } else if v == "1273" { + 1273 + } else if v == "1274" { + 1274 + } else if v == "1275" { + 1275 + } else if v == "1276" { + 1276 + } else if v == "1277" { + 1277 + } else if v == "1278" { + 1278 + } else if v == "1279" { + 1279 + } else if v == "1280" { + 1280 + } else if v == "1281" { + 1281 + } else if v == "1282" { + 1282 + } else if v == "1283" { + 1283 + } else if v == "1284" { + 1284 + } else if v == "1285" { + 1285 + } else if v == "1286" { + 1286 + } else if v == "1287" { + 1287 + } else if v == "1288" { + 1288 + } else if v == "1289" { + 1289 + } else if v == "1290" { + 1290 + } else if v == "1291" { + 1291 + } else if v == "1292" { + 1292 + } else if v == "1293" { + 1293 + } else if v == "1294" { + 1294 + } else if v == "1295" { + 1295 + } else if v == "1296" { + 1296 + } else if v == "1297" { + 1297 + } else if v == "1298" { + 1298 + } else if v == "1299" { + 1299 + } else if v == "1300" { + 1300 + } else if v == "1301" { + 1301 + } else if v == "1302" { + 1302 + } else if v == "1303" { + 1303 + } else if v == "1304" { + 1304 + } else if v == "1305" { + 1305 + } else if v == "1306" { + 1306 + } else if v == "1307" { + 1307 + } else if v == "1308" { + 1308 + } else if v == "1309" { + 1309 + } else if v == "1310" { + 1310 + } else if v == "1311" { + 1311 + } else if v == "1312" { + 1312 + } else if v == "1313" { + 1313 + } else if v == "1314" { + 1314 + } else if v == "1315" { + 1315 + } else if v == "1316" { + 1316 + } else if v == "1317" { + 1317 + } else if v == "1318" { + 1318 + } else if v == "1319" { + 1319 + } else if v == "1320" { + 1320 + } else if v == "1321" { + 1321 + } else if v == "1322" { + 1322 + } else if v == "1323" { + 1323 + } else if v == "1324" { + 1324 + } else if v == "1325" { + 1325 + } else if v == "1326" { + 1326 + } else if v == "1327" { + 1327 + } else if v == "1328" { + 1328 + } else if v == "1329" { + 1329 + } else if v == "1330" { + 1330 + } else if v == "1331" { + 1331 + } else if v == "1332" { + 1332 + } else if v == "1333" { + 1333 + } else if v == "1334" { + 1334 + } else if v == "1335" { + 1335 + } else if v == "1336" { + 1336 + } else if v == "1337" { + 1337 + } else if v == "1338" { + 1338 + } else if v == "1339" { + 1339 + } else if v == "1340" { + 1340 + } else if v == "1341" { + 1341 + } else if v == "1342" { + 1342 + } else if v == "1343" { + 1343 + } else if v == "1344" { + 1344 + } else if v == "1345" { + 1345 + } else if v == "1346" { + 1346 + } else if v == "1347" { + 1347 + } else if v == "1348" { + 1348 + } else if v == "1349" { + 1349 + } else if v == "1350" { + 1350 + } else if v == "1351" { + 1351 + } else if v == "1352" { + 1352 + } else if v == "1353" { + 1353 + } else if v == "1354" { + 1354 + } else if v == "1355" { + 1355 + } else if v == "1356" { + 1356 + } else if v == "1357" { + 1357 + } else if v == "1358" { + 1358 + } else if v == "1359" { + 1359 + } else if v == "1360" { + 1360 + } else if v == "1361" { + 1361 + } else if v == "1362" { + 1362 + } else if v == "1363" { + 1363 + } else if v == "1364" { + 1364 + } else if v == "1365" { + 1365 + } else if v == "1366" { + 1366 + } else if v == "1367" { + 1367 + } else if v == "1368" { + 1368 + } else if v == "1369" { + 1369 + } else if v == "1370" { + 1370 + } else if v == "1371" { + 1371 + } else if v == "1372" { + 1372 + } else if v == "1373" { + 1373 + } else if v == "1374" { + 1374 + } else if v == "1375" { + 1375 + } else if v == "1376" { + 1376 + } else if v == "1377" { + 1377 + } else if v == "1378" { + 1378 + } else if v == "1379" { + 1379 + } else if v == "1380" { + 1380 + } else if v == "1381" { + 1381 + } else if v == "1382" { + 1382 + } else if v == "1383" { + 1383 + } else if v == "1384" { + 1384 + } else if v == "1385" { + 1385 + } else if v == "1386" { + 1386 + } else if v == "1387" { + 1387 + } else if v == "1388" { + 1388 + } else if v == "1389" { + 1389 + } else if v == "1390" { + 1390 + } else if v == "1391" { + 1391 + } else if v == "1392" { + 1392 + } else if v == "1393" { + 1393 + } else if v == "1394" { + 1394 + } else if v == "1395" { + 1395 + } else if v == "1396" { + 1396 + } else if v == "1397" { + 1397 + } else if v == "1398" { + 1398 + } else if v == "1399" { + 1399 + } else if v == "1400" { + 1400 + } else if v == "1401" { + 1401 + } else if v == "1402" { + 1402 + } else if v == "1403" { + 1403 + } else if v == "1404" { + 1404 + } else if v == "1405" { + 1405 + } else if v == "1406" { + 1406 + } else if v == "1407" { + 1407 + } else if v == "1408" { + 1408 + } else if v == "1409" { + 1409 + } else if v == "1410" { + 1410 + } else if v == "1411" { + 1411 + } else if v == "1412" { + 1412 + } else if v == "1413" { + 1413 + } else if v == "1414" { + 1414 + } else if v == "1415" { + 1415 + } else if v == "1416" { + 1416 + } else if v == "1417" { + 1417 + } else if v == "1418" { + 1418 + } else if v == "1419" { + 1419 + } else if v == "1420" { + 1420 + } else if v == "1421" { + 1421 + } else if v == "1422" { + 1422 + } else if v == "1423" { + 1423 + } else if v == "1424" { + 1424 + } else if v == "1425" { + 1425 + } else if v == "1426" { + 1426 + } else if v == "1427" { + 1427 + } else if v == "1428" { + 1428 + } else if v == "1429" { + 1429 + } else if v == "1430" { + 1430 + } else if v == "1431" { + 1431 + } else if v == "1432" { + 1432 + } else if v == "1433" { + 1433 + } else if v == "1434" { + 1434 + } else if v == "1435" { + 1435 + } else if v == "1436" { + 1436 + } else if v == "1437" { + 1437 + } else if v == "1438" { + 1438 + } else if v == "1439" { + 1439 + } else if v == "1440" { + 1440 + } else if v == "1441" { + 1441 + } else if v == "1442" { + 1442 + } else if v == "1443" { + 1443 + } else if v == "1444" { + 1444 + } else if v == "1445" { + 1445 + } else if v == "1446" { + 1446 + } else if v == "1447" { + 1447 + } else if v == "1448" { + 1448 + } else if v == "1449" { + 1449 + } else if v == "1450" { + 1450 + } else if v == "1451" { + 1451 + } else if v == "1452" { + 1452 + } else if v == "1453" { + 1453 + } else if v == "1454" { + 1454 + } else if v == "1455" { + 1455 + } else if v == "1456" { + 1456 + } else if v == "1457" { + 1457 + } else if v == "1458" { + 1458 + } else if v == "1459" { + 1459 + } else if v == "1460" { + 1460 + } else if v == "1461" { + 1461 + } else if v == "1462" { + 1462 + } else if v == "1463" { + 1463 + } else if v == "1464" { + 1464 + } else if v == "1465" { + 1465 + } else if v == "1466" { + 1466 + } else if v == "1467" { + 1467 + } else if v == "1468" { + 1468 + } else if v == "1469" { + 1469 + } else if v == "1470" { + 1470 + } else if v == "1471" { + 1471 + } else if v == "1472" { + 1472 + } else if v == "1473" { + 1473 + } else if v == "1474" { + 1474 + } else if v == "1475" { + 1475 + } else if v == "1476" { + 1476 + } else if v == "1477" { + 1477 + } else if v == "1478" { + 1478 + } else if v == "1479" { + 1479 + } else if v == "1480" { + 1480 + } else if v == "1481" { + 1481 + } else if v == "1482" { + 1482 + } else if v == "1483" { + 1483 + } else if v == "1484" { + 1484 + } else if v == "1485" { + 1485 + } else if v == "1486" { + 1486 + } else if v == "1487" { + 1487 + } else if v == "1488" { + 1488 + } else if v == "1489" { + 1489 + } else if v == "1490" { + 1490 + } else if v == "1491" { + 1491 + } else if v == "1492" { + 1492 + } else if v == "1493" { + 1493 + } else if v == "1494" { + 1494 + } else if v == "1495" { + 1495 + } else if v == "1496" { + 1496 + } else if v == "1497" { + 1497 + } else if v == "1498" { + 1498 + } else if v == "1499" { + 1499 + } else if v == "1500" { + 1500 + } else if v == "1501" { + 1501 + } else if v == "1502" { + 1502 + } else if v == "1503" { + 1503 + } else if v == "1504" { + 1504 + } else if v == "1505" { + 1505 + } else if v == "1506" { + 1506 + } else if v == "1507" { + 1507 + } else if v == "1508" { + 1508 + } else if v == "1509" { + 1509 + } else if v == "1510" { + 1510 + } else if v == "1511" { + 1511 + } else if v == "1512" { + 1512 + } else if v == "1513" { + 1513 + } else if v == "1514" { + 1514 + } else if v == "1515" { + 1515 + } else if v == "1516" { + 1516 + } else if v == "1517" { + 1517 + } else if v == "1518" { + 1518 + } else if v == "1519" { + 1519 + } else if v == "1520" { + 1520 + } else if v == "1521" { + 1521 + } else if v == "1522" { + 1522 + } else if v == "1523" { + 1523 + } else if v == "1524" { + 1524 + } else if v == "1525" { + 1525 + } else if v == "1526" { + 1526 + } else if v == "1527" { + 1527 + } else if v == "1528" { + 1528 + } else if v == "1529" { + 1529 + } else if v == "1530" { + 1530 + } else if v == "1531" { + 1531 + } else if v == "1532" { + 1532 + } else if v == "1533" { + 1533 + } else if v == "1534" { + 1534 + } else if v == "1535" { + 1535 + } else if v == "1536" { + 1536 + } else if v == "1537" { + 1537 + } else if v == "1538" { + 1538 + } else if v == "1539" { + 1539 + } else if v == "1540" { + 1540 + } else if v == "1541" { + 1541 + } else if v == "1542" { + 1542 + } else if v == "1543" { + 1543 + } else if v == "1544" { + 1544 + } else if v == "1545" { + 1545 + } else if v == "1546" { + 1546 + } else if v == "1547" { + 1547 + } else if v == "1548" { + 1548 + } else if v == "1549" { + 1549 + } else if v == "1550" { + 1550 + } else if v == "1551" { + 1551 + } else if v == "1552" { + 1552 + } else if v == "1553" { + 1553 + } else if v == "1554" { + 1554 + } else if v == "1555" { + 1555 + } else if v == "1556" { + 1556 + } else if v == "1557" { + 1557 + } else if v == "1558" { + 1558 + } else if v == "1559" { + 1559 + } else if v == "1560" { + 1560 + } else if v == "1561" { + 1561 + } else if v == "1562" { + 1562 + } else if v == "1563" { + 1563 + } else if v == "1564" { + 1564 + } else if v == "1565" { + 1565 + } else if v == "1566" { + 1566 + } else if v == "1567" { + 1567 + } else if v == "1568" { + 1568 + } else if v == "1569" { + 1569 + } else if v == "1570" { + 1570 + } else if v == "1571" { + 1571 + } else if v == "1572" { + 1572 + } else if v == "1573" { + 1573 + } else if v == "1574" { + 1574 + } else if v == "1575" { + 1575 + } else if v == "1576" { + 1576 + } else if v == "1577" { + 1577 + } else if v == "1578" { + 1578 + } else if v == "1579" { + 1579 + } else if v == "1580" { + 1580 + } else if v == "1581" { + 1581 + } else if v == "1582" { + 1582 + } else if v == "1583" { + 1583 + } else if v == "1584" { + 1584 + } else if v == "1585" { + 1585 + } else if v == "1586" { + 1586 + } else if v == "1587" { + 1587 + } else if v == "1588" { + 1588 + } else if v == "1589" { + 1589 + } else if v == "1590" { + 1590 + } else if v == "1591" { + 1591 + } else if v == "1592" { + 1592 + } else if v == "1593" { + 1593 + } else if v == "1594" { + 1594 + } else if v == "1595" { + 1595 + } else if v == "1596" { + 1596 + } else if v == "1597" { + 1597 + } else if v == "1598" { + 1598 + } else if v == "1599" { + 1599 + } else if v == "1600" { + 1600 + } else if v == "1601" { + 1601 + } else if v == "1602" { + 1602 + } else if v == "1603" { + 1603 + } else if v == "1604" { + 1604 + } else if v == "1605" { + 1605 + } else if v == "1606" { + 1606 + } else if v == "1607" { + 1607 + } else if v == "1608" { + 1608 + } else if v == "1609" { + 1609 + } else if v == "1610" { + 1610 + } else if v == "1611" { + 1611 + } else if v == "1612" { + 1612 + } else if v == "1613" { + 1613 + } else if v == "1614" { + 1614 + } else if v == "1615" { + 1615 + } else if v == "1616" { + 1616 + } else if v == "1617" { + 1617 + } else if v == "1618" { + 1618 + } else if v == "1619" { + 1619 + } else if v == "1620" { + 1620 + } else if v == "1621" { + 1621 + } else if v == "1622" { + 1622 + } else if v == "1623" { + 1623 + } else if v == "1624" { + 1624 + } else if v == "1625" { + 1625 + } else if v == "1626" { + 1626 + } else if v == "1627" { + 1627 + } else if v == "1628" { + 1628 + } else if v == "1629" { + 1629 + } else if v == "1630" { + 1630 + } else if v == "1631" { + 1631 + } else if v == "1632" { + 1632 + } else if v == "1633" { + 1633 + } else if v == "1634" { + 1634 + } else if v == "1635" { + 1635 + } else if v == "1636" { + 1636 + } else if v == "1637" { + 1637 + } else if v == "1638" { + 1638 + } else if v == "1639" { + 1639 + } else if v == "1640" { + 1640 + } else if v == "1641" { + 1641 + } else if v == "1642" { + 1642 + } else if v == "1643" { + 1643 + } else if v == "1644" { + 1644 + } else if v == "1645" { + 1645 + } else if v == "1646" { + 1646 + } else if v == "1647" { + 1647 + } else if v == "1648" { + 1648 + } else if v == "1649" { + 1649 + } else if v == "1650" { + 1650 + } else if v == "1651" { + 1651 + } else if v == "1652" { + 1652 + } else if v == "1653" { + 1653 + } else if v == "1654" { + 1654 + } else if v == "1655" { + 1655 + } else if v == "1656" { + 1656 + } else if v == "1657" { + 1657 + } else if v == "1658" { + 1658 + } else if v == "1659" { + 1659 + } else if v == "1660" { + 1660 + } else if v == "1661" { + 1661 + } else if v == "1662" { + 1662 + } else if v == "1663" { + 1663 + } else if v == "1664" { + 1664 + } else if v == "1665" { + 1665 + } else if v == "1666" { + 1666 + } else if v == "1667" { + 1667 + } else if v == "1668" { + 1668 + } else if v == "1669" { + 1669 + } else if v == "1670" { + 1670 + } else if v == "1671" { + 1671 + } else if v == "1672" { + 1672 + } else if v == "1673" { + 1673 + } else if v == "1674" { + 1674 + } else if v == "1675" { + 1675 + } else if v == "1676" { + 1676 + } else if v == "1677" { + 1677 + } else if v == "1678" { + 1678 + } else if v == "1679" { + 1679 + } else if v == "1680" { + 1680 + } else if v == "1681" { + 1681 + } else if v == "1682" { + 1682 + } else if v == "1683" { + 1683 + } else if v == "1684" { + 1684 + } else if v == "1685" { + 1685 + } else if v == "1686" { + 1686 + } else if v == "1687" { + 1687 + } else if v == "1688" { + 1688 + } else if v == "1689" { + 1689 + } else if v == "1690" { + 1690 + } else if v == "1691" { + 1691 + } else if v == "1692" { + 1692 + } else if v == "1693" { + 1693 + } else if v == "1694" { + 1694 + } else if v == "1695" { + 1695 + } else if v == "1696" { + 1696 + } else if v == "1697" { + 1697 + } else if v == "1698" { + 1698 + } else if v == "1699" { + 1699 + } else if v == "1700" { + 1700 + } else if v == "1701" { + 1701 + } else if v == "1702" { + 1702 + } else if v == "1703" { + 1703 + } else if v == "1704" { + 1704 + } else if v == "1705" { + 1705 + } else if v == "1706" { + 1706 + } else if v == "1707" { + 1707 + } else if v == "1708" { + 1708 + } else if v == "1709" { + 1709 + } else if v == "1710" { + 1710 + } else if v == "1711" { + 1711 + } else if v == "1712" { + 1712 + } else if v == "1713" { + 1713 + } else if v == "1714" { + 1714 + } else if v == "1715" { + 1715 + } else if v == "1716" { + 1716 + } else if v == "1717" { + 1717 + } else if v == "1718" { + 1718 + } else if v == "1719" { + 1719 + } else if v == "1720" { + 1720 + } else if v == "1721" { + 1721 + } else if v == "1722" { + 1722 + } else if v == "1723" { + 1723 + } else if v == "1724" { + 1724 + } else if v == "1725" { + 1725 + } else if v == "1726" { + 1726 + } else if v == "1727" { + 1727 + } else if v == "1728" { + 1728 + } else if v == "1729" { + 1729 + } else if v == "1730" { + 1730 + } else if v == "1731" { + 1731 + } else if v == "1732" { + 1732 + } else if v == "1733" { + 1733 + } else if v == "1734" { + 1734 + } else if v == "1735" { + 1735 + } else if v == "1736" { + 1736 + } else if v == "1737" { + 1737 + } else if v == "1738" { + 1738 + } else if v == "1739" { + 1739 + } else if v == "1740" { + 1740 + } else if v == "1741" { + 1741 + } else if v == "1742" { + 1742 + } else if v == "1743" { + 1743 + } else if v == "1744" { + 1744 + } else if v == "1745" { + 1745 + } else if v == "1746" { + 1746 + } else if v == "1747" { + 1747 + } else if v == "1748" { + 1748 + } else if v == "1749" { + 1749 + } else if v == "1750" { + 1750 + } else if v == "1751" { + 1751 + } else if v == "1752" { + 1752 + } else if v == "1753" { + 1753 + } else if v == "1754" { + 1754 + } else if v == "1755" { + 1755 + } else if v == "1756" { + 1756 + } else if v == "1757" { + 1757 + } else if v == "1758" { + 1758 + } else if v == "1759" { + 1759 + } else if v == "1760" { + 1760 + } else if v == "1761" { + 1761 + } else if v == "1762" { + 1762 + } else if v == "1763" { + 1763 + } else if v == "1764" { + 1764 + } else if v == "1765" { + 1765 + } else if v == "1766" { + 1766 + } else if v == "1767" { + 1767 + } else if v == "1768" { + 1768 + } else if v == "1769" { + 1769 + } else if v == "1770" { + 1770 + } else if v == "1771" { + 1771 + } else if v == "1772" { + 1772 + } else if v == "1773" { + 1773 + } else if v == "1774" { + 1774 + } else if v == "1775" { + 1775 + } else if v == "1776" { + 1776 + } else if v == "1777" { + 1777 + } else if v == "1778" { + 1778 + } else if v == "1779" { + 1779 + } else if v == "1780" { + 1780 + } else if v == "1781" { + 1781 + } else if v == "1782" { + 1782 + } else if v == "1783" { + 1783 + } else if v == "1784" { + 1784 + } else if v == "1785" { + 1785 + } else if v == "1786" { + 1786 + } else if v == "1787" { + 1787 + } else if v == "1788" { + 1788 + } else if v == "1789" { + 1789 + } else if v == "1790" { + 1790 + } else if v == "1791" { + 1791 + } else if v == "1792" { + 1792 + } else if v == "1793" { + 1793 + } else if v == "1794" { + 1794 + } else if v == "1795" { + 1795 + } else if v == "1796" { + 1796 + } else if v == "1797" { + 1797 + } else if v == "1798" { + 1798 + } else if v == "1799" { + 1799 + } else if v == "1800" { + 1800 + } else if v == "1801" { + 1801 + } else if v == "1802" { + 1802 + } else if v == "1803" { + 1803 + } else if v == "1804" { + 1804 + } else if v == "1805" { + 1805 + } else if v == "1806" { + 1806 + } else if v == "1807" { + 1807 + } else if v == "1808" { + 1808 + } else if v == "1809" { + 1809 + } else if v == "1810" { + 1810 + } else if v == "1811" { + 1811 + } else if v == "1812" { + 1812 + } else if v == "1813" { + 1813 + } else if v == "1814" { + 1814 + } else if v == "1815" { + 1815 + } else if v == "1816" { + 1816 + } else if v == "1817" { + 1817 + } else if v == "1818" { + 1818 + } else if v == "1819" { + 1819 + } else if v == "1820" { + 1820 + } else if v == "1821" { + 1821 + } else if v == "1822" { + 1822 + } else if v == "1823" { + 1823 + } else if v == "1824" { + 1824 + } else if v == "1825" { + 1825 + } else if v == "1826" { + 1826 + } else if v == "1827" { + 1827 + } else if v == "1828" { + 1828 + } else if v == "1829" { + 1829 + } else if v == "1830" { + 1830 + } else if v == "1831" { + 1831 + } else if v == "1832" { + 1832 + } else if v == "1833" { + 1833 + } else if v == "1834" { + 1834 + } else if v == "1835" { + 1835 + } else if v == "1836" { + 1836 + } else if v == "1837" { + 1837 + } else if v == "1838" { + 1838 + } else if v == "1839" { + 1839 + } else if v == "1840" { + 1840 + } else if v == "1841" { + 1841 + } else if v == "1842" { + 1842 + } else if v == "1843" { + 1843 + } else if v == "1844" { + 1844 + } else if v == "1845" { + 1845 + } else if v == "1846" { + 1846 + } else if v == "1847" { + 1847 + } else if v == "1848" { + 1848 + } else if v == "1849" { + 1849 + } else if v == "1850" { + 1850 + } else if v == "1851" { + 1851 + } else if v == "1852" { + 1852 + } else if v == "1853" { + 1853 + } else if v == "1854" { + 1854 + } else if v == "1855" { + 1855 + } else if v == "1856" { + 1856 + } else if v == "1857" { + 1857 + } else if v == "1858" { + 1858 + } else if v == "1859" { + 1859 + } else if v == "1860" { + 1860 + } else if v == "1861" { + 1861 + } else if v == "1862" { + 1862 + } else if v == "1863" { + 1863 + } else if v == "1864" { + 1864 + } else if v == "1865" { + 1865 + } else if v == "1866" { + 1866 + } else if v == "1867" { + 1867 + } else if v == "1868" { + 1868 + } else if v == "1869" { + 1869 + } else if v == "1870" { + 1870 + } else if v == "1871" { + 1871 + } else if v == "1872" { + 1872 + } else if v == "1873" { + 1873 + } else if v == "1874" { + 1874 + } else if v == "1875" { + 1875 + } else if v == "1876" { + 1876 + } else if v == "1877" { + 1877 + } else if v == "1878" { + 1878 + } else if v == "1879" { + 1879 + } else if v == "1880" { + 1880 + } else if v == "1881" { + 1881 + } else if v == "1882" { + 1882 + } else if v == "1883" { + 1883 + } else if v == "1884" { + 1884 + } else if v == "1885" { + 1885 + } else if v == "1886" { + 1886 + } else if v == "1887" { + 1887 + } else if v == "1888" { + 1888 + } else if v == "1889" { + 1889 + } else if v == "1890" { + 1890 + } else if v == "1891" { + 1891 + } else if v == "1892" { + 1892 + } else if v == "1893" { + 1893 + } else if v == "1894" { + 1894 + } else if v == "1895" { + 1895 + } else if v == "1896" { + 1896 + } else if v == "1897" { + 1897 + } else if v == "1898" { + 1898 + } else if v == "1899" { + 1899 + } else if v == "1900" { + 1900 + } else if v == "1901" { + 1901 + } else if v == "1902" { + 1902 + } else if v == "1903" { + 1903 + } else if v == "1904" { + 1904 + } else if v == "1905" { + 1905 + } else if v == "1906" { + 1906 + } else if v == "1907" { + 1907 + } else if v == "1908" { + 1908 + } else if v == "1909" { + 1909 + } else if v == "1910" { + 1910 + } else if v == "1911" { + 1911 + } else if v == "1912" { + 1912 + } else if v == "1913" { + 1913 + } else if v == "1914" { + 1914 + } else if v == "1915" { + 1915 + } else if v == "1916" { + 1916 + } else if v == "1917" { + 1917 + } else if v == "1918" { + 1918 + } else if v == "1919" { + 1919 + } else if v == "1920" { + 1920 + } else if v == "1921" { + 1921 + } else if v == "1922" { + 1922 + } else if v == "1923" { + 1923 + } else if v == "1924" { + 1924 + } else if v == "1925" { + 1925 + } else if v == "1926" { + 1926 + } else if v == "1927" { + 1927 + } else if v == "1928" { + 1928 + } else if v == "1929" { + 1929 + } else if v == "1930" { + 1930 + } else if v == "1931" { + 1931 + } else if v == "1932" { + 1932 + } else if v == "1933" { + 1933 + } else if v == "1934" { + 1934 + } else if v == "1935" { + 1935 + } else if v == "1936" { + 1936 + } else if v == "1937" { + 1937 + } else if v == "1938" { + 1938 + } else if v == "1939" { + 1939 + } else if v == "1940" { + 1940 + } else if v == "1941" { + 1941 + } else if v == "1942" { + 1942 + } else if v == "1943" { + 1943 + } else if v == "1944" { + 1944 + } else if v == "1945" { + 1945 + } else if v == "1946" { + 1946 + } else if v == "1947" { + 1947 + } else if v == "1948" { + 1948 + } else if v == "1949" { + 1949 + } else if v == "1950" { + 1950 + } else if v == "1951" { + 1951 + } else if v == "1952" { + 1952 + } else if v == "1953" { + 1953 + } else if v == "1954" { + 1954 + } else if v == "1955" { + 1955 + } else if v == "1956" { + 1956 + } else if v == "1957" { + 1957 + } else if v == "1958" { + 1958 + } else if v == "1959" { + 1959 + } else if v == "1960" { + 1960 + } else if v == "1961" { + 1961 + } else if v == "1962" { + 1962 + } else if v == "1963" { + 1963 + } else if v == "1964" { + 1964 + } else if v == "1965" { + 1965 + } else if v == "1966" { + 1966 + } else if v == "1967" { + 1967 + } else if v == "1968" { + 1968 + } else if v == "1969" { + 1969 + } else if v == "1970" { + 1970 + } else if v == "1971" { + 1971 + } else if v == "1972" { + 1972 + } else if v == "1973" { + 1973 + } else if v == "1974" { + 1974 + } else if v == "1975" { + 1975 + } else if v == "1976" { + 1976 + } else if v == "1977" { + 1977 + } else if v == "1978" { + 1978 + } else if v == "1979" { + 1979 + } else if v == "1980" { + 1980 + } else if v == "1981" { + 1981 + } else if v == "1982" { + 1982 + } else if v == "1983" { + 1983 + } else if v == "1984" { + 1984 + } else if v == "1985" { + 1985 + } else if v == "1986" { + 1986 + } else if v == "1987" { + 1987 + } else if v == "1988" { + 1988 + } else if v == "1989" { + 1989 + } else if v == "1990" { + 1990 + } else if v == "1991" { + 1991 + } else if v == "1992" { + 1992 + } else if v == "1993" { + 1993 + } else if v == "1994" { + 1994 + } else if v == "1995" { + 1995 + } else if v == "1996" { + 1996 + } else if v == "1997" { + 1997 + } else if v == "1998" { + 1998 + } else if v == "1999" { + 1999 + } else if v == "2000" { + 2000 + } else if v == "2001" { + 2001 + } else if v == "2002" { + 2002 + } else if v == "2003" { + 2003 + } else if v == "2004" { + 2004 + } else if v == "2005" { + 2005 + } else if v == "2006" { + 2006 + } else if v == "2007" { + 2007 + } else if v == "2008" { + 2008 + } else if v == "2009" { + 2009 + } else if v == "2010" { + 2010 + } else if v == "2011" { + 2011 + } else if v == "2012" { + 2012 + } else if v == "2013" { + 2013 + } else if v == "2014" { + 2014 + } else if v == "2015" { + 2015 + } else if v == "2016" { + 2016 + } else if v == "2017" { + 2017 + } else if v == "2018" { + 2018 + } else if v == "2019" { + 2019 + } else if v == "2020" { + 2020 + } else if v == "2021" { + 2021 + } else if v == "2022" { + 2022 + } else if v == "2023" { + 2023 + } else if v == "2024" { + 2024 + } else if v == "2025" { + 2025 + } else if v == "2026" { + 2026 + } else if v == "2027" { + 2027 + } else if v == "2028" { + 2028 + } else if v == "2029" { + 2029 + } else if v == "2030" { + 2030 + } else if v == "2031" { + 2031 + } else if v == "2032" { + 2032 + } else if v == "2033" { + 2033 + } else if v == "2034" { + 2034 + } else if v == "2035" { + 2035 + } else if v == "2036" { + 2036 + } else if v == "2037" { + 2037 + } else if v == "2038" { + 2038 + } else if v == "2039" { + 2039 + } else if v == "2040" { + 2040 + } else if v == "2041" { + 2041 + } else if v == "2042" { + 2042 + } else if v == "2043" { + 2043 + } else if v == "2044" { + 2044 + } else if v == "2045" { + 2045 + } else if v == "2046" { + 2046 + } else if v == "2047" { + 2047 + } else if v == "2048" { + 2048 + } else if v == "2049" { + 2049 + } else if v == "2050" { + 2050 + } else if v == "2051" { + 2051 + } else if v == "2052" { + 2052 + } else if v == "2053" { + 2053 + } else if v == "2054" { + 2054 + } else if v == "2055" { + 2055 + } else if v == "2056" { + 2056 + } else if v == "2057" { + 2057 + } else if v == "2058" { + 2058 + } else if v == "2059" { + 2059 + } else if v == "2060" { + 2060 + } else if v == "2061" { + 2061 + } else if v == "2062" { + 2062 + } else if v == "2063" { + 2063 + } else if v == "2064" { + 2064 + } else if v == "2065" { + 2065 + } else if v == "2066" { + 2066 + } else if v == "2067" { + 2067 + } else if v == "2068" { + 2068 + } else if v == "2069" { + 2069 + } else if v == "2070" { + 2070 + } else if v == "2071" { + 2071 + } else if v == "2072" { + 2072 + } else if v == "2073" { + 2073 + } else if v == "2074" { + 2074 + } else if v == "2075" { + 2075 + } else if v == "2076" { + 2076 + } else if v == "2077" { + 2077 + } else if v == "2078" { + 2078 + } else if v == "2079" { + 2079 + } else if v == "2080" { + 2080 + } else if v == "2081" { + 2081 + } else if v == "2082" { + 2082 + } else if v == "2083" { + 2083 + } else if v == "2084" { + 2084 + } else if v == "2085" { + 2085 + } else if v == "2086" { + 2086 + } else if v == "2087" { + 2087 + } else if v == "2088" { + 2088 + } else if v == "2089" { + 2089 + } else if v == "2090" { + 2090 + } else if v == "2091" { + 2091 + } else if v == "2092" { + 2092 + } else if v == "2093" { + 2093 + } else if v == "2094" { + 2094 + } else if v == "2095" { + 2095 + } else if v == "2096" { + 2096 + } else if v == "2097" { + 2097 + } else if v == "2098" { + 2098 + } else if v == "2099" { + 2099 + } else if v == "2100" { + 2100 + } else if v == "2101" { + 2101 + } else if v == "2102" { + 2102 + } else if v == "2103" { + 2103 + } else if v == "2104" { + 2104 + } else if v == "2105" { + 2105 + } else if v == "2106" { + 2106 + } else if v == "2107" { + 2107 + } else if v == "2108" { + 2108 + } else if v == "2109" { + 2109 + } else if v == "2110" { + 2110 + } else if v == "2111" { + 2111 + } else if v == "2112" { + 2112 + } else if v == "2113" { + 2113 + } else if v == "2114" { + 2114 + } else if v == "2115" { + 2115 + } else if v == "2116" { + 2116 + } else if v == "2117" { + 2117 + } else if v == "2118" { + 2118 + } else if v == "2119" { + 2119 + } else if v == "2120" { + 2120 + } else if v == "2121" { + 2121 + } else if v == "2122" { + 2122 + } else if v == "2123" { + 2123 + } else if v == "2124" { + 2124 + } else if v == "2125" { + 2125 + } else if v == "2126" { + 2126 + } else if v == "2127" { + 2127 + } else if v == "2128" { + 2128 + } else if v == "2129" { + 2129 + } else if v == "2130" { + 2130 + } else if v == "2131" { + 2131 + } else if v == "2132" { + 2132 + } else if v == "2133" { + 2133 + } else if v == "2134" { + 2134 + } else if v == "2135" { + 2135 + } else if v == "2136" { + 2136 + } else if v == "2137" { + 2137 + } else if v == "2138" { + 2138 + } else if v == "2139" { + 2139 + } else if v == "2140" { + 2140 + } else if v == "2141" { + 2141 + } else if v == "2142" { + 2142 + } else if v == "2143" { + 2143 + } else if v == "2144" { + 2144 + } else if v == "2145" { + 2145 + } else if v == "2146" { + 2146 + } else if v == "2147" { + 2147 + } else if v == "2148" { + 2148 + } else if v == "2149" { + 2149 + } else if v == "2150" { + 2150 + } else if v == "2151" { + 2151 + } else if v == "2152" { + 2152 + } else if v == "2153" { + 2153 + } else if v == "2154" { + 2154 + } else if v == "2155" { + 2155 + } else if v == "2156" { + 2156 + } else if v == "2157" { + 2157 + } else if v == "2158" { + 2158 + } else if v == "2159" { + 2159 + } else if v == "2160" { + 2160 + } else if v == "2161" { + 2161 + } else if v == "2162" { + 2162 + } else if v == "2163" { + 2163 + } else if v == "2164" { + 2164 + } else if v == "2165" { + 2165 + } else if v == "2166" { + 2166 + } else if v == "2167" { + 2167 + } else if v == "2168" { + 2168 + } else if v == "2169" { + 2169 + } else if v == "2170" { + 2170 + } else if v == "2171" { + 2171 + } else if v == "2172" { + 2172 + } else if v == "2173" { + 2173 + } else if v == "2174" { + 2174 + } else if v == "2175" { + 2175 + } else if v == "2176" { + 2176 + } else if v == "2177" { + 2177 + } else if v == "2178" { + 2178 + } else if v == "2179" { + 2179 + } else if v == "2180" { + 2180 + } else if v == "2181" { + 2181 + } else if v == "2182" { + 2182 + } else if v == "2183" { + 2183 + } else if v == "2184" { + 2184 + } else if v == "2185" { + 2185 + } else if v == "2186" { + 2186 + } else if v == "2187" { + 2187 + } else if v == "2188" { + 2188 + } else if v == "2189" { + 2189 + } else if v == "2190" { + 2190 + } else if v == "2191" { + 2191 + } else if v == "2192" { + 2192 + } else if v == "2193" { + 2193 + } else if v == "2194" { + 2194 + } else if v == "2195" { + 2195 + } else if v == "2196" { + 2196 + } else if v == "2197" { + 2197 + } else if v == "2198" { + 2198 + } else if v == "2199" { + 2199 + } else if v == "2200" { + 2200 + } else if v == "2201" { + 2201 + } else if v == "2202" { + 2202 + } else if v == "2203" { + 2203 + } else if v == "2204" { + 2204 + } else if v == "2205" { + 2205 + } else if v == "2206" { + 2206 + } else if v == "2207" { + 2207 + } else if v == "2208" { + 2208 + } else if v == "2209" { + 2209 + } else if v == "2210" { + 2210 + } else if v == "2211" { + 2211 + } else if v == "2212" { + 2212 + } else if v == "2213" { + 2213 + } else if v == "2214" { + 2214 + } else if v == "2215" { + 2215 + } else if v == "2216" { + 2216 + } else if v == "2217" { + 2217 + } else if v == "2218" { + 2218 + } else if v == "2219" { + 2219 + } else if v == "2220" { + 2220 + } else if v == "2221" { + 2221 + } else if v == "2222" { + 2222 + } else if v == "2223" { + 2223 + } else if v == "2224" { + 2224 + } else if v == "2225" { + 2225 + } else if v == "2226" { + 2226 + } else if v == "2227" { + 2227 + } else if v == "2228" { + 2228 + } else if v == "2229" { + 2229 + } else if v == "2230" { + 2230 + } else if v == "2231" { + 2231 + } else if v == "2232" { + 2232 + } else if v == "2233" { + 2233 + } else if v == "2234" { + 2234 + } else if v == "2235" { + 2235 + } else if v == "2236" { + 2236 + } else if v == "2237" { + 2237 + } else if v == "2238" { + 2238 + } else if v == "2239" { + 2239 + } else if v == "2240" { + 2240 + } else if v == "2241" { + 2241 + } else if v == "2242" { + 2242 + } else if v == "2243" { + 2243 + } else if v == "2244" { + 2244 + } else if v == "2245" { + 2245 + } else if v == "2246" { + 2246 + } else if v == "2247" { + 2247 + } else if v == "2248" { + 2248 + } else if v == "2249" { + 2249 + } else if v == "2250" { + 2250 + } else if v == "2251" { + 2251 + } else if v == "2252" { + 2252 + } else if v == "2253" { + 2253 + } else if v == "2254" { + 2254 + } else if v == "2255" { + 2255 + } else if v == "2256" { + 2256 + } else if v == "2257" { + 2257 + } else if v == "2258" { + 2258 + } else if v == "2259" { + 2259 + } else if v == "2260" { + 2260 + } else if v == "2261" { + 2261 + } else if v == "2262" { + 2262 + } else if v == "2263" { + 2263 + } else if v == "2264" { + 2264 + } else if v == "2265" { + 2265 + } else if v == "2266" { + 2266 + } else if v == "2267" { + 2267 + } else if v == "2268" { + 2268 + } else if v == "2269" { + 2269 + } else if v == "2270" { + 2270 + } else if v == "2271" { + 2271 + } else if v == "2272" { + 2272 + } else if v == "2273" { + 2273 + } else if v == "2274" { + 2274 + } else if v == "2275" { + 2275 + } else if v == "2276" { + 2276 + } else if v == "2277" { + 2277 + } else if v == "2278" { + 2278 + } else if v == "2279" { + 2279 + } else if v == "2280" { + 2280 + } else if v == "2281" { + 2281 + } else if v == "2282" { + 2282 + } else if v == "2283" { + 2283 + } else if v == "2284" { + 2284 + } else if v == "2285" { + 2285 + } else if v == "2286" { + 2286 + } else if v == "2287" { + 2287 + } else if v == "2288" { + 2288 + } else if v == "2289" { + 2289 + } else if v == "2290" { + 2290 + } else if v == "2291" { + 2291 + } else if v == "2292" { + 2292 + } else if v == "2293" { + 2293 + } else if v == "2294" { + 2294 + } else if v == "2295" { + 2295 + } else if v == "2296" { + 2296 + } else if v == "2297" { + 2297 + } else if v == "2298" { + 2298 + } else if v == "2299" { + 2299 + } else if v == "2300" { + 2300 + } else if v == "2301" { + 2301 + } else if v == "2302" { + 2302 + } else if v == "2303" { + 2303 + } else if v == "2304" { + 2304 + } else if v == "2305" { + 2305 + } else if v == "2306" { + 2306 + } else if v == "2307" { + 2307 + } else if v == "2308" { + 2308 + } else if v == "2309" { + 2309 + } else if v == "2310" { + 2310 + } else if v == "2311" { + 2311 + } else if v == "2312" { + 2312 + } else if v == "2313" { + 2313 + } else if v == "2314" { + 2314 + } else if v == "2315" { + 2315 + } else if v == "2316" { + 2316 + } else if v == "2317" { + 2317 + } else if v == "2318" { + 2318 + } else if v == "2319" { + 2319 + } else if v == "2320" { + 2320 + } else if v == "2321" { + 2321 + } else if v == "2322" { + 2322 + } else if v == "2323" { + 2323 + } else if v == "2324" { + 2324 + } else if v == "2325" { + 2325 + } else if v == "2326" { + 2326 + } else if v == "2327" { + 2327 + } else if v == "2328" { + 2328 + } else if v == "2329" { + 2329 + } else if v == "2330" { + 2330 + } else if v == "2331" { + 2331 + } else if v == "2332" { + 2332 + } else if v == "2333" { + 2333 + } else if v == "2334" { + 2334 + } else if v == "2335" { + 2335 + } else if v == "2336" { + 2336 + } else if v == "2337" { + 2337 + } else if v == "2338" { + 2338 + } else if v == "2339" { + 2339 + } else if v == "2340" { + 2340 + } else if v == "2341" { + 2341 + } else if v == "2342" { + 2342 + } else if v == "2343" { + 2343 + } else if v == "2344" { + 2344 + } else if v == "2345" { + 2345 + } else if v == "2346" { + 2346 + } else if v == "2347" { + 2347 + } else if v == "2348" { + 2348 + } else if v == "2349" { + 2349 + } else if v == "2350" { + 2350 + } else if v == "2351" { + 2351 + } else if v == "2352" { + 2352 + } else if v == "2353" { + 2353 + } else if v == "2354" { + 2354 + } else if v == "2355" { + 2355 + } else if v == "2356" { + 2356 + } else if v == "2357" { + 2357 + } else if v == "2358" { + 2358 + } else if v == "2359" { + 2359 + } else if v == "2360" { + 2360 + } else if v == "2361" { + 2361 + } else if v == "2362" { + 2362 + } else if v == "2363" { + 2363 + } else if v == "2364" { + 2364 + } else if v == "2365" { + 2365 + } else if v == "2366" { + 2366 + } else if v == "2367" { + 2367 + } else if v == "2368" { + 2368 + } else if v == "2369" { + 2369 + } else if v == "2370" { + 2370 + } else if v == "2371" { + 2371 + } else if v == "2372" { + 2372 + } else if v == "2373" { + 2373 + } else if v == "2374" { + 2374 + } else if v == "2375" { + 2375 + } else if v == "2376" { + 2376 + } else if v == "2377" { + 2377 + } else if v == "2378" { + 2378 + } else if v == "2379" { + 2379 + } else if v == "2380" { + 2380 + } else if v == "2381" { + 2381 + } else if v == "2382" { + 2382 + } else if v == "2383" { + 2383 + } else if v == "2384" { + 2384 + } else if v == "2385" { + 2385 + } else if v == "2386" { + 2386 + } else if v == "2387" { + 2387 + } else if v == "2388" { + 2388 + } else if v == "2389" { + 2389 + } else if v == "2390" { + 2390 + } else if v == "2391" { + 2391 + } else if v == "2392" { + 2392 + } else if v == "2393" { + 2393 + } else if v == "2394" { + 2394 + } else if v == "2395" { + 2395 + } else if v == "2396" { + 2396 + } else if v == "2397" { + 2397 + } else if v == "2398" { + 2398 + } else if v == "2399" { + 2399 + } else if v == "2400" { + 2400 + } else if v == "2401" { + 2401 + } else if v == "2402" { + 2402 + } else if v == "2403" { + 2403 + } else if v == "2404" { + 2404 + } else if v == "2405" { + 2405 + } else if v == "2406" { + 2406 + } else if v == "2407" { + 2407 + } else if v == "2408" { + 2408 + } else if v == "2409" { + 2409 + } else if v == "2410" { + 2410 + } else if v == "2411" { + 2411 + } else if v == "2412" { + 2412 + } else if v == "2413" { + 2413 + } else if v == "2414" { + 2414 + } else if v == "2415" { + 2415 + } else if v == "2416" { + 2416 + } else if v == "2417" { + 2417 + } else if v == "2418" { + 2418 + } else if v == "2419" { + 2419 + } else if v == "2420" { + 2420 + } else if v == "2421" { + 2421 + } else if v == "2422" { + 2422 + } else if v == "2423" { + 2423 + } else if v == "2424" { + 2424 + } else if v == "2425" { + 2425 + } else if v == "2426" { + 2426 + } else if v == "2427" { + 2427 + } else if v == "2428" { + 2428 + } else if v == "2429" { + 2429 + } else if v == "2430" { + 2430 + } else if v == "2431" { + 2431 + } else if v == "2432" { + 2432 + } else if v == "2433" { + 2433 + } else if v == "2434" { + 2434 + } else if v == "2435" { + 2435 + } else if v == "2436" { + 2436 + } else if v == "2437" { + 2437 + } else if v == "2438" { + 2438 + } else if v == "2439" { + 2439 + } else if v == "2440" { + 2440 + } else if v == "2441" { + 2441 + } else if v == "2442" { + 2442 + } else if v == "2443" { + 2443 + } else if v == "2444" { + 2444 + } else if v == "2445" { + 2445 + } else if v == "2446" { + 2446 + } else if v == "2447" { + 2447 + } else if v == "2448" { + 2448 + } else if v == "2449" { + 2449 + } else if v == "2450" { + 2450 + } else if v == "2451" { + 2451 + } else if v == "2452" { + 2452 + } else if v == "2453" { + 2453 + } else if v == "2454" { + 2454 + } else if v == "2455" { + 2455 + } else if v == "2456" { + 2456 + } else if v == "2457" { + 2457 + } else if v == "2458" { + 2458 + } else if v == "2459" { + 2459 + } else if v == "2460" { + 2460 + } else if v == "2461" { + 2461 + } else if v == "2462" { + 2462 + } else if v == "2463" { + 2463 + } else if v == "2464" { + 2464 + } else if v == "2465" { + 2465 + } else if v == "2466" { + 2466 + } else if v == "2467" { + 2467 + } else if v == "2468" { + 2468 + } else if v == "2469" { + 2469 + } else if v == "2470" { + 2470 + } else if v == "2471" { + 2471 + } else if v == "2472" { + 2472 + } else if v == "2473" { + 2473 + } else if v == "2474" { + 2474 + } else if v == "2475" { + 2475 + } else if v == "2476" { + 2476 + } else if v == "2477" { + 2477 + } else if v == "2478" { + 2478 + } else if v == "2479" { + 2479 + } else if v == "2480" { + 2480 + } else if v == "2481" { + 2481 + } else if v == "2482" { + 2482 + } else if v == "2483" { + 2483 + } else if v == "2484" { + 2484 + } else if v == "2485" { + 2485 + } else if v == "2486" { + 2486 + } else if v == "2487" { + 2487 + } else if v == "2488" { + 2488 + } else if v == "2489" { + 2489 + } else if v == "2490" { + 2490 + } else if v == "2491" { + 2491 + } else if v == "2492" { + 2492 + } else if v == "2493" { + 2493 + } else if v == "2494" { + 2494 + } else if v == "2495" { + 2495 + } else if v == "2496" { + 2496 + } else if v == "2497" { + 2497 + } else if v == "2498" { + 2498 + } else if v == "2499" { + 2499 + } else if v == "2500" { + 2500 + } else if v == "2501" { + 2501 + } else if v == "2502" { + 2502 + } else if v == "2503" { + 2503 + } else if v == "2504" { + 2504 + } else if v == "2505" { + 2505 + } else if v == "2506" { + 2506 + } else if v == "2507" { + 2507 + } else if v == "2508" { + 2508 + } else if v == "2509" { + 2509 + } else if v == "2510" { + 2510 + } else if v == "2511" { + 2511 + } else if v == "2512" { + 2512 + } else if v == "2513" { + 2513 + } else if v == "2514" { + 2514 + } else if v == "2515" { + 2515 + } else if v == "2516" { + 2516 + } else if v == "2517" { + 2517 + } else if v == "2518" { + 2518 + } else if v == "2519" { + 2519 + } else if v == "2520" { + 2520 + } else if v == "2521" { + 2521 + } else if v == "2522" { + 2522 + } else if v == "2523" { + 2523 + } else if v == "2524" { + 2524 + } else if v == "2525" { + 2525 + } else if v == "2526" { + 2526 + } else if v == "2527" { + 2527 + } else if v == "2528" { + 2528 + } else if v == "2529" { + 2529 + } else if v == "2530" { + 2530 + } else if v == "2531" { + 2531 + } else if v == "2532" { + 2532 + } else if v == "2533" { + 2533 + } else if v == "2534" { + 2534 + } else if v == "2535" { + 2535 + } else if v == "2536" { + 2536 + } else if v == "2537" { + 2537 + } else if v == "2538" { + 2538 + } else if v == "2539" { + 2539 + } else if v == "2540" { + 2540 + } else if v == "2541" { + 2541 + } else if v == "2542" { + 2542 + } else if v == "2543" { + 2543 + } else if v == "2544" { + 2544 + } else if v == "2545" { + 2545 + } else if v == "2546" { + 2546 + } else if v == "2547" { + 2547 + } else if v == "2548" { + 2548 + } else if v == "2549" { + 2549 + } else if v == "2550" { + 2550 + } else if v == "2551" { + 2551 + } else if v == "2552" { + 2552 + } else if v == "2553" { + 2553 + } else if v == "2554" { + 2554 + } else if v == "2555" { + 2555 + } else if v == "2556" { + 2556 + } else if v == "2557" { + 2557 + } else if v == "2558" { + 2558 + } else if v == "2559" { + 2559 + } else if v == "2560" { + 2560 + } else if v == "2561" { + 2561 + } else if v == "2562" { + 2562 + } else if v == "2563" { + 2563 + } else if v == "2564" { + 2564 + } else if v == "2565" { + 2565 + } else if v == "2566" { + 2566 + } else if v == "2567" { + 2567 + } else if v == "2568" { + 2568 + } else if v == "2569" { + 2569 + } else if v == "2570" { + 2570 + } else if v == "2571" { + 2571 + } else if v == "2572" { + 2572 + } else if v == "2573" { + 2573 + } else if v == "2574" { + 2574 + } else if v == "2575" { + 2575 + } else if v == "2576" { + 2576 + } else if v == "2577" { + 2577 + } else if v == "2578" { + 2578 + } else if v == "2579" { + 2579 + } else if v == "2580" { + 2580 + } else if v == "2581" { + 2581 + } else if v == "2582" { + 2582 + } else if v == "2583" { + 2583 + } else if v == "2584" { + 2584 + } else if v == "2585" { + 2585 + } else if v == "2586" { + 2586 + } else if v == "2587" { + 2587 + } else if v == "2588" { + 2588 + } else if v == "2589" { + 2589 + } else if v == "2590" { + 2590 + } else if v == "2591" { + 2591 + } else if v == "2592" { + 2592 + } else if v == "2593" { + 2593 + } else if v == "2594" { + 2594 + } else if v == "2595" { + 2595 + } else if v == "2596" { + 2596 + } else if v == "2597" { + 2597 + } else if v == "2598" { + 2598 + } else if v == "2599" { + 2599 + } else if v == "2600" { + 2600 + } else if v == "2601" { + 2601 + } else if v == "2602" { + 2602 + } else if v == "2603" { + 2603 + } else if v == "2604" { + 2604 + } else if v == "2605" { + 2605 + } else if v == "2606" { + 2606 + } else if v == "2607" { + 2607 + } else if v == "2608" { + 2608 + } else if v == "2609" { + 2609 + } else if v == "2610" { + 2610 + } else if v == "2611" { + 2611 + } else if v == "2612" { + 2612 + } else if v == "2613" { + 2613 + } else if v == "2614" { + 2614 + } else if v == "2615" { + 2615 + } else if v == "2616" { + 2616 + } else if v == "2617" { + 2617 + } else if v == "2618" { + 2618 + } else if v == "2619" { + 2619 + } else if v == "2620" { + 2620 + } else if v == "2621" { + 2621 + } else if v == "2622" { + 2622 + } else if v == "2623" { + 2623 + } else if v == "2624" { + 2624 + } else if v == "2625" { + 2625 + } else if v == "2626" { + 2626 + } else if v == "2627" { + 2627 + } else if v == "2628" { + 2628 + } else if v == "2629" { + 2629 + } else if v == "2630" { + 2630 + } else if v == "2631" { + 2631 + } else if v == "2632" { + 2632 + } else if v == "2633" { + 2633 + } else if v == "2634" { + 2634 + } else if v == "2635" { + 2635 + } else if v == "2636" { + 2636 + } else if v == "2637" { + 2637 + } else if v == "2638" { + 2638 + } else if v == "2639" { + 2639 + } else if v == "2640" { + 2640 + } else if v == "2641" { + 2641 + } else if v == "2642" { + 2642 + } else if v == "2643" { + 2643 + } else if v == "2644" { + 2644 + } else if v == "2645" { + 2645 + } else if v == "2646" { + 2646 + } else if v == "2647" { + 2647 + } else if v == "2648" { + 2648 + } else if v == "2649" { + 2649 + } else if v == "2650" { + 2650 + } else if v == "2651" { + 2651 + } else if v == "2652" { + 2652 + } else if v == "2653" { + 2653 + } else if v == "2654" { + 2654 + } else if v == "2655" { + 2655 + } else if v == "2656" { + 2656 + } else if v == "2657" { + 2657 + } else if v == "2658" { + 2658 + } else if v == "2659" { + 2659 + } else if v == "2660" { + 2660 + } else if v == "2661" { + 2661 + } else if v == "2662" { + 2662 + } else if v == "2663" { + 2663 + } else if v == "2664" { + 2664 + } else if v == "2665" { + 2665 + } else if v == "2666" { + 2666 + } else if v == "2667" { + 2667 + } else if v == "2668" { + 2668 + } else if v == "2669" { + 2669 + } else if v == "2670" { + 2670 + } else if v == "2671" { + 2671 + } else if v == "2672" { + 2672 + } else if v == "2673" { + 2673 + } else if v == "2674" { + 2674 + } else if v == "2675" { + 2675 + } else if v == "2676" { + 2676 + } else if v == "2677" { + 2677 + } else if v == "2678" { + 2678 + } else if v == "2679" { + 2679 + } else if v == "2680" { + 2680 + } else if v == "2681" { + 2681 + } else if v == "2682" { + 2682 + } else if v == "2683" { + 2683 + } else if v == "2684" { + 2684 + } else if v == "2685" { + 2685 + } else if v == "2686" { + 2686 + } else if v == "2687" { + 2687 + } else if v == "2688" { + 2688 + } else if v == "2689" { + 2689 + } else if v == "2690" { + 2690 + } else if v == "2691" { + 2691 + } else if v == "2692" { + 2692 + } else if v == "2693" { + 2693 + } else if v == "2694" { + 2694 + } else if v == "2695" { + 2695 + } else if v == "2696" { + 2696 + } else if v == "2697" { + 2697 + } else if v == "2698" { + 2698 + } else if v == "2699" { + 2699 + } else if v == "2700" { + 2700 + } else if v == "2701" { + 2701 + } else if v == "2702" { + 2702 + } else if v == "2703" { + 2703 + } else if v == "2704" { + 2704 + } else if v == "2705" { + 2705 + } else if v == "2706" { + 2706 + } else if v == "2707" { + 2707 + } else if v == "2708" { + 2708 + } else if v == "2709" { + 2709 + } else if v == "2710" { + 2710 + } else if v == "2711" { + 2711 + } else if v == "2712" { + 2712 + } else if v == "2713" { + 2713 + } else if v == "2714" { + 2714 + } else if v == "2715" { + 2715 + } else if v == "2716" { + 2716 + } else if v == "2717" { + 2717 + } else if v == "2718" { + 2718 + } else if v == "2719" { + 2719 + } else if v == "2720" { + 2720 + } else if v == "2721" { + 2721 + } else if v == "2722" { + 2722 + } else if v == "2723" { + 2723 + } else if v == "2724" { + 2724 + } else if v == "2725" { + 2725 + } else if v == "2726" { + 2726 + } else if v == "2727" { + 2727 + } else if v == "2728" { + 2728 + } else if v == "2729" { + 2729 + } else if v == "2730" { + 2730 + } else if v == "2731" { + 2731 + } else if v == "2732" { + 2732 + } else if v == "2733" { + 2733 + } else if v == "2734" { + 2734 + } else if v == "2735" { + 2735 + } else if v == "2736" { + 2736 + } else if v == "2737" { + 2737 + } else if v == "2738" { + 2738 + } else if v == "2739" { + 2739 + } else if v == "2740" { + 2740 + } else if v == "2741" { + 2741 + } else if v == "2742" { + 2742 + } else if v == "2743" { + 2743 + } else if v == "2744" { + 2744 + } else if v == "2745" { + 2745 + } else if v == "2746" { + 2746 + } else if v == "2747" { + 2747 + } else if v == "2748" { + 2748 + } else if v == "2749" { + 2749 + } else if v == "2750" { + 2750 + } else if v == "2751" { + 2751 + } else if v == "2752" { + 2752 + } else if v == "2753" { + 2753 + } else if v == "2754" { + 2754 + } else if v == "2755" { + 2755 + } else if v == "2756" { + 2756 + } else if v == "2757" { + 2757 + } else if v == "2758" { + 2758 + } else if v == "2759" { + 2759 + } else if v == "2760" { + 2760 + } else if v == "2761" { + 2761 + } else if v == "2762" { + 2762 + } else if v == "2763" { + 2763 + } else if v == "2764" { + 2764 + } else if v == "2765" { + 2765 + } else if v == "2766" { + 2766 + } else if v == "2767" { + 2767 + } else if v == "2768" { + 2768 + } else if v == "2769" { + 2769 + } else if v == "2770" { + 2770 + } else if v == "2771" { + 2771 + } else if v == "2772" { + 2772 + } else if v == "2773" { + 2773 + } else if v == "2774" { + 2774 + } else if v == "2775" { + 2775 + } else if v == "2776" { + 2776 + } else if v == "2777" { + 2777 + } else if v == "2778" { + 2778 + } else if v == "2779" { + 2779 + } else if v == "2780" { + 2780 + } else if v == "2781" { + 2781 + } else if v == "2782" { + 2782 + } else if v == "2783" { + 2783 + } else if v == "2784" { + 2784 + } else if v == "2785" { + 2785 + } else if v == "2786" { + 2786 + } else if v == "2787" { + 2787 + } else if v == "2788" { + 2788 + } else if v == "2789" { + 2789 + } else if v == "2790" { + 2790 + } else if v == "2791" { + 2791 + } else if v == "2792" { + 2792 + } else if v == "2793" { + 2793 + } else if v == "2794" { + 2794 + } else if v == "2795" { + 2795 + } else if v == "2796" { + 2796 + } else if v == "2797" { + 2797 + } else if v == "2798" { + 2798 + } else if v == "2799" { + 2799 + } else if v == "2800" { + 2800 + } else if v == "2801" { + 2801 + } else if v == "2802" { + 2802 + } else if v == "2803" { + 2803 + } else if v == "2804" { + 2804 + } else if v == "2805" { + 2805 + } else if v == "2806" { + 2806 + } else if v == "2807" { + 2807 + } else if v == "2808" { + 2808 + } else if v == "2809" { + 2809 + } else if v == "2810" { + 2810 + } else if v == "2811" { + 2811 + } else if v == "2812" { + 2812 + } else if v == "2813" { + 2813 + } else if v == "2814" { + 2814 + } else if v == "2815" { + 2815 + } else if v == "2816" { + 2816 + } else if v == "2817" { + 2817 + } else if v == "2818" { + 2818 + } else if v == "2819" { + 2819 + } else if v == "2820" { + 2820 + } else if v == "2821" { + 2821 + } else if v == "2822" { + 2822 + } else if v == "2823" { + 2823 + } else if v == "2824" { + 2824 + } else if v == "2825" { + 2825 + } else if v == "2826" { + 2826 + } else if v == "2827" { + 2827 + } else if v == "2828" { + 2828 + } else if v == "2829" { + 2829 + } else if v == "2830" { + 2830 + } else if v == "2831" { + 2831 + } else if v == "2832" { + 2832 + } else if v == "2833" { + 2833 + } else if v == "2834" { + 2834 + } else if v == "2835" { + 2835 + } else if v == "2836" { + 2836 + } else if v == "2837" { + 2837 + } else if v == "2838" { + 2838 + } else if v == "2839" { + 2839 + } else if v == "2840" { + 2840 + } else if v == "2841" { + 2841 + } else if v == "2842" { + 2842 + } else if v == "2843" { + 2843 + } else if v == "2844" { + 2844 + } else if v == "2845" { + 2845 + } else if v == "2846" { + 2846 + } else if v == "2847" { + 2847 + } else if v == "2848" { + 2848 + } else if v == "2849" { + 2849 + } else if v == "2850" { + 2850 + } else if v == "2851" { + 2851 + } else if v == "2852" { + 2852 + } else if v == "2853" { + 2853 + } else if v == "2854" { + 2854 + } else if v == "2855" { + 2855 + } else if v == "2856" { + 2856 + } else if v == "2857" { + 2857 + } else if v == "2858" { + 2858 + } else if v == "2859" { + 2859 + } else if v == "2860" { + 2860 + } else if v == "2861" { + 2861 + } else if v == "2862" { + 2862 + } else if v == "2863" { + 2863 + } else if v == "2864" { + 2864 + } else if v == "2865" { + 2865 + } else if v == "2866" { + 2866 + } else if v == "2867" { + 2867 + } else if v == "2868" { + 2868 + } else if v == "2869" { + 2869 + } else if v == "2870" { + 2870 + } else if v == "2871" { + 2871 + } else if v == "2872" { + 2872 + } else if v == "2873" { + 2873 + } else if v == "2874" { + 2874 + } else if v == "2875" { + 2875 + } else if v == "2876" { + 2876 + } else if v == "2877" { + 2877 + } else if v == "2878" { + 2878 + } else if v == "2879" { + 2879 + } else if v == "2880" { + 2880 + } else if v == "2881" { + 2881 + } else if v == "2882" { + 2882 + } else if v == "2883" { + 2883 + } else if v == "2884" { + 2884 + } else if v == "2885" { + 2885 + } else if v == "2886" { + 2886 + } else if v == "2887" { + 2887 + } else if v == "2888" { + 2888 + } else if v == "2889" { + 2889 + } else if v == "2890" { + 2890 + } else if v == "2891" { + 2891 + } else if v == "2892" { + 2892 + } else if v == "2893" { + 2893 + } else if v == "2894" { + 2894 + } else if v == "2895" { + 2895 + } else if v == "2896" { + 2896 + } else if v == "2897" { + 2897 + } else if v == "2898" { + 2898 + } else if v == "2899" { + 2899 + } else if v == "2900" { + 2900 + } else if v == "2901" { + 2901 + } else if v == "2902" { + 2902 + } else if v == "2903" { + 2903 + } else if v == "2904" { + 2904 + } else if v == "2905" { + 2905 + } else if v == "2906" { + 2906 + } else if v == "2907" { + 2907 + } else if v == "2908" { + 2908 + } else if v == "2909" { + 2909 + } else if v == "2910" { + 2910 + } else if v == "2911" { + 2911 + } else if v == "2912" { + 2912 + } else if v == "2913" { + 2913 + } else if v == "2914" { + 2914 + } else if v == "2915" { + 2915 + } else if v == "2916" { + 2916 + } else if v == "2917" { + 2917 + } else if v == "2918" { + 2918 + } else if v == "2919" { + 2919 + } else if v == "2920" { + 2920 + } else if v == "2921" { + 2921 + } else if v == "2922" { + 2922 + } else if v == "2923" { + 2923 + } else if v == "2924" { + 2924 + } else if v == "2925" { + 2925 + } else if v == "2926" { + 2926 + } else if v == "2927" { + 2927 + } else if v == "2928" { + 2928 + } else if v == "2929" { + 2929 + } else if v == "2930" { + 2930 + } else if v == "2931" { + 2931 + } else if v == "2932" { + 2932 + } else if v == "2933" { + 2933 + } else if v == "2934" { + 2934 + } else if v == "2935" { + 2935 + } else if v == "2936" { + 2936 + } else if v == "2937" { + 2937 + } else if v == "2938" { + 2938 + } else if v == "2939" { + 2939 + } else if v == "2940" { + 2940 + } else if v == "2941" { + 2941 + } else if v == "2942" { + 2942 + } else if v == "2943" { + 2943 + } else if v == "2944" { + 2944 + } else if v == "2945" { + 2945 + } else if v == "2946" { + 2946 + } else if v == "2947" { + 2947 + } else if v == "2948" { + 2948 + } else if v == "2949" { + 2949 + } else if v == "2950" { + 2950 + } else if v == "2951" { + 2951 + } else if v == "2952" { + 2952 + } else if v == "2953" { + 2953 + } else if v == "2954" { + 2954 + } else if v == "2955" { + 2955 + } else if v == "2956" { + 2956 + } else if v == "2957" { + 2957 + } else if v == "2958" { + 2958 + } else if v == "2959" { + 2959 + } else if v == "2960" { + 2960 + } else if v == "2961" { + 2961 + } else if v == "2962" { + 2962 + } else if v == "2963" { + 2963 + } else if v == "2964" { + 2964 + } else if v == "2965" { + 2965 + } else if v == "2966" { + 2966 + } else if v == "2967" { + 2967 + } else if v == "2968" { + 2968 + } else if v == "2969" { + 2969 + } else if v == "2970" { + 2970 + } else if v == "2971" { + 2971 + } else if v == "2972" { + 2972 + } else if v == "2973" { + 2973 + } else if v == "2974" { + 2974 + } else if v == "2975" { + 2975 + } else if v == "2976" { + 2976 + } else if v == "2977" { + 2977 + } else if v == "2978" { + 2978 + } else if v == "2979" { + 2979 + } else if v == "2980" { + 2980 + } else if v == "2981" { + 2981 + } else if v == "2982" { + 2982 + } else if v == "2983" { + 2983 + } else if v == "2984" { + 2984 + } else if v == "2985" { + 2985 + } else if v == "2986" { + 2986 + } else if v == "2987" { + 2987 + } else if v == "2988" { + 2988 + } else if v == "2989" { + 2989 + } else if v == "2990" { + 2990 + } else if v == "2991" { + 2991 + } else if v == "2992" { + 2992 + } else if v == "2993" { + 2993 + } else if v == "2994" { + 2994 + } else if v == "2995" { + 2995 + } else if v == "2996" { + 2996 + } else if v == "2997" { + 2997 + } else if v == "2998" { + 2998 + } else if v == "2999" { + 2999 + } else if v == "3000" { + 3000 + } else if v == "3001" { + 3001 + } else if v == "3002" { + 3002 + } else if v == "3003" { + 3003 + } else if v == "3004" { + 3004 + } else if v == "3005" { + 3005 + } else if v == "3006" { + 3006 + } else if v == "3007" { + 3007 + } else if v == "3008" { + 3008 + } else if v == "3009" { + 3009 + } else if v == "3010" { + 3010 + } else if v == "3011" { + 3011 + } else if v == "3012" { + 3012 + } else if v == "3013" { + 3013 + } else if v == "3014" { + 3014 + } else if v == "3015" { + 3015 + } else if v == "3016" { + 3016 + } else if v == "3017" { + 3017 + } else if v == "3018" { + 3018 + } else if v == "3019" { + 3019 + } else if v == "3020" { + 3020 + } else if v == "3021" { + 3021 + } else if v == "3022" { + 3022 + } else if v == "3023" { + 3023 + } else if v == "3024" { + 3024 + } else if v == "3025" { + 3025 + } else if v == "3026" { + 3026 + } else if v == "3027" { + 3027 + } else if v == "3028" { + 3028 + } else if v == "3029" { + 3029 + } else if v == "3030" { + 3030 + } else if v == "3031" { + 3031 + } else if v == "3032" { + 3032 + } else if v == "3033" { + 3033 + } else if v == "3034" { + 3034 + } else if v == "3035" { + 3035 + } else if v == "3036" { + 3036 + } else if v == "3037" { + 3037 + } else if v == "3038" { + 3038 + } else if v == "3039" { + 3039 + } else if v == "3040" { + 3040 + } else if v == "3041" { + 3041 + } else if v == "3042" { + 3042 + } else if v == "3043" { + 3043 + } else if v == "3044" { + 3044 + } else if v == "3045" { + 3045 + } else if v == "3046" { + 3046 + } else if v == "3047" { + 3047 + } else if v == "3048" { + 3048 + } else if v == "3049" { + 3049 + } else if v == "3050" { + 3050 + } else if v == "3051" { + 3051 + } else if v == "3052" { + 3052 + } else if v == "3053" { + 3053 + } else if v == "3054" { + 3054 + } else if v == "3055" { + 3055 + } else if v == "3056" { + 3056 + } else if v == "3057" { + 3057 + } else if v == "3058" { + 3058 + } else if v == "3059" { + 3059 + } else if v == "3060" { + 3060 + } else if v == "3061" { + 3061 + } else if v == "3062" { + 3062 + } else if v == "3063" { + 3063 + } else if v == "3064" { + 3064 + } else if v == "3065" { + 3065 + } else if v == "3066" { + 3066 + } else if v == "3067" { + 3067 + } else if v == "3068" { + 3068 + } else if v == "3069" { + 3069 + } else if v == "3070" { + 3070 + } else if v == "3071" { + 3071 + } else if v == "3072" { + 3072 + } else if v == "3073" { + 3073 + } else if v == "3074" { + 3074 + } else if v == "3075" { + 3075 + } else if v == "3076" { + 3076 + } else if v == "3077" { + 3077 + } else if v == "3078" { + 3078 + } else if v == "3079" { + 3079 + } else if v == "3080" { + 3080 + } else if v == "3081" { + 3081 + } else if v == "3082" { + 3082 + } else if v == "3083" { + 3083 + } else if v == "3084" { + 3084 + } else if v == "3085" { + 3085 + } else if v == "3086" { + 3086 + } else if v == "3087" { + 3087 + } else if v == "3088" { + 3088 + } else if v == "3089" { + 3089 + } else if v == "3090" { + 3090 + } else if v == "3091" { + 3091 + } else if v == "3092" { + 3092 + } else if v == "3093" { + 3093 + } else if v == "3094" { + 3094 + } else if v == "3095" { + 3095 + } else if v == "3096" { + 3096 + } else if v == "3097" { + 3097 + } else if v == "3098" { + 3098 + } else if v == "3099" { + 3099 + } else if v == "3100" { + 3100 + } else if v == "3101" { + 3101 + } else if v == "3102" { + 3102 + } else if v == "3103" { + 3103 + } else if v == "3104" { + 3104 + } else if v == "3105" { + 3105 + } else if v == "3106" { + 3106 + } else if v == "3107" { + 3107 + } else if v == "3108" { + 3108 + } else if v == "3109" { + 3109 + } else if v == "3110" { + 3110 + } else if v == "3111" { + 3111 + } else if v == "3112" { + 3112 + } else if v == "3113" { + 3113 + } else if v == "3114" { + 3114 + } else if v == "3115" { + 3115 + } else if v == "3116" { + 3116 + } else if v == "3117" { + 3117 + } else if v == "3118" { + 3118 + } else if v == "3119" { + 3119 + } else if v == "3120" { + 3120 + } else if v == "3121" { + 3121 + } else if v == "3122" { + 3122 + } else if v == "3123" { + 3123 + } else if v == "3124" { + 3124 + } else if v == "3125" { + 3125 + } else if v == "3126" { + 3126 + } else if v == "3127" { + 3127 + } else if v == "3128" { + 3128 + } else if v == "3129" { + 3129 + } else if v == "3130" { + 3130 + } else if v == "3131" { + 3131 + } else if v == "3132" { + 3132 + } else if v == "3133" { + 3133 + } else if v == "3134" { + 3134 + } else if v == "3135" { + 3135 + } else if v == "3136" { + 3136 + } else if v == "3137" { + 3137 + } else if v == "3138" { + 3138 + } else if v == "3139" { + 3139 + } else if v == "3140" { + 3140 + } else if v == "3141" { + 3141 + } else if v == "3142" { + 3142 + } else if v == "3143" { + 3143 + } else if v == "3144" { + 3144 + } else if v == "3145" { + 3145 + } else if v == "3146" { + 3146 + } else if v == "3147" { + 3147 + } else if v == "3148" { + 3148 + } else if v == "3149" { + 3149 + } else if v == "3150" { + 3150 + } else if v == "3151" { + 3151 + } else if v == "3152" { + 3152 + } else if v == "3153" { + 3153 + } else if v == "3154" { + 3154 + } else if v == "3155" { + 3155 + } else if v == "3156" { + 3156 + } else if v == "3157" { + 3157 + } else if v == "3158" { + 3158 + } else if v == "3159" { + 3159 + } else if v == "3160" { + 3160 + } else if v == "3161" { + 3161 + } else if v == "3162" { + 3162 + } else if v == "3163" { + 3163 + } else if v == "3164" { + 3164 + } else if v == "3165" { + 3165 + } else if v == "3166" { + 3166 + } else if v == "3167" { + 3167 + } else if v == "3168" { + 3168 + } else if v == "3169" { + 3169 + } else if v == "3170" { + 3170 + } else if v == "3171" { + 3171 + } else if v == "3172" { + 3172 + } else if v == "3173" { + 3173 + } else if v == "3174" { + 3174 + } else if v == "3175" { + 3175 + } else if v == "3176" { + 3176 + } else if v == "3177" { + 3177 + } else if v == "3178" { + 3178 + } else if v == "3179" { + 3179 + } else if v == "3180" { + 3180 + } else if v == "3181" { + 3181 + } else if v == "3182" { + 3182 + } else if v == "3183" { + 3183 + } else if v == "3184" { + 3184 + } else if v == "3185" { + 3185 + } else if v == "3186" { + 3186 + } else if v == "3187" { + 3187 + } else if v == "3188" { + 3188 + } else if v == "3189" { + 3189 + } else if v == "3190" { + 3190 + } else if v == "3191" { + 3191 + } else if v == "3192" { + 3192 + } else if v == "3193" { + 3193 + } else if v == "3194" { + 3194 + } else if v == "3195" { + 3195 + } else if v == "3196" { + 3196 + } else if v == "3197" { + 3197 + } else if v == "3198" { + 3198 + } else if v == "3199" { + 3199 + } else if v == "3200" { + 3200 + } else if v == "3201" { + 3201 + } else if v == "3202" { + 3202 + } else if v == "3203" { + 3203 + } else if v == "3204" { + 3204 + } else if v == "3205" { + 3205 + } else if v == "3206" { + 3206 + } else if v == "3207" { + 3207 + } else if v == "3208" { + 3208 + } else if v == "3209" { + 3209 + } else if v == "3210" { + 3210 + } else if v == "3211" { + 3211 + } else if v == "3212" { + 3212 + } else if v == "3213" { + 3213 + } else if v == "3214" { + 3214 + } else if v == "3215" { + 3215 + } else if v == "3216" { + 3216 + } else if v == "3217" { + 3217 + } else if v == "3218" { + 3218 + } else if v == "3219" { + 3219 + } else if v == "3220" { + 3220 + } else if v == "3221" { + 3221 + } else if v == "3222" { + 3222 + } else if v == "3223" { + 3223 + } else if v == "3224" { + 3224 + } else if v == "3225" { + 3225 + } else if v == "3226" { + 3226 + } else if v == "3227" { + 3227 + } else if v == "3228" { + 3228 + } else if v == "3229" { + 3229 + } else if v == "3230" { + 3230 + } else if v == "3231" { + 3231 + } else if v == "3232" { + 3232 + } else if v == "3233" { + 3233 + } else if v == "3234" { + 3234 + } else if v == "3235" { + 3235 + } else if v == "3236" { + 3236 + } else if v == "3237" { + 3237 + } else if v == "3238" { + 3238 + } else if v == "3239" { + 3239 + } else if v == "3240" { + 3240 + } else if v == "3241" { + 3241 + } else if v == "3242" { + 3242 + } else if v == "3243" { + 3243 + } else if v == "3244" { + 3244 + } else if v == "3245" { + 3245 + } else if v == "3246" { + 3246 + } else if v == "3247" { + 3247 + } else if v == "3248" { + 3248 + } else if v == "3249" { + 3249 + } else if v == "3250" { + 3250 + } else if v == "3251" { + 3251 + } else if v == "3252" { + 3252 + } else if v == "3253" { + 3253 + } else if v == "3254" { + 3254 + } else if v == "3255" { + 3255 + } else if v == "3256" { + 3256 + } else if v == "3257" { + 3257 + } else if v == "3258" { + 3258 + } else if v == "3259" { + 3259 + } else if v == "3260" { + 3260 + } else if v == "3261" { + 3261 + } else if v == "3262" { + 3262 + } else if v == "3263" { + 3263 + } else if v == "3264" { + 3264 + } else if v == "3265" { + 3265 + } else if v == "3266" { + 3266 + } else if v == "3267" { + 3267 + } else if v == "3268" { + 3268 + } else if v == "3269" { + 3269 + } else if v == "3270" { + 3270 + } else if v == "3271" { + 3271 + } else if v == "3272" { + 3272 + } else if v == "3273" { + 3273 + } else if v == "3274" { + 3274 + } else if v == "3275" { + 3275 + } else if v == "3276" { + 3276 + } else if v == "3277" { + 3277 + } else if v == "3278" { + 3278 + } else if v == "3279" { + 3279 + } else if v == "3280" { + 3280 + } else if v == "3281" { + 3281 + } else if v == "3282" { + 3282 + } else if v == "3283" { + 3283 + } else if v == "3284" { + 3284 + } else if v == "3285" { + 3285 + } else if v == "3286" { + 3286 + } else if v == "3287" { + 3287 + } else if v == "3288" { + 3288 + } else if v == "3289" { + 3289 + } else if v == "3290" { + 3290 + } else if v == "3291" { + 3291 + } else if v == "3292" { + 3292 + } else if v == "3293" { + 3293 + } else if v == "3294" { + 3294 + } else if v == "3295" { + 3295 + } else if v == "3296" { + 3296 + } else if v == "3297" { + 3297 + } else if v == "3298" { + 3298 + } else if v == "3299" { + 3299 + } else if v == "3300" { + 3300 + } else if v == "3301" { + 3301 + } else if v == "3302" { + 3302 + } else if v == "3303" { + 3303 + } else if v == "3304" { + 3304 + } else if v == "3305" { + 3305 + } else if v == "3306" { + 3306 + } else if v == "3307" { + 3307 + } else if v == "3308" { + 3308 + } else if v == "3309" { + 3309 + } else if v == "3310" { + 3310 + } else if v == "3311" { + 3311 + } else if v == "3312" { + 3312 + } else if v == "3313" { + 3313 + } else if v == "3314" { + 3314 + } else if v == "3315" { + 3315 + } else if v == "3316" { + 3316 + } else if v == "3317" { + 3317 + } else if v == "3318" { + 3318 + } else if v == "3319" { + 3319 + } else if v == "3320" { + 3320 + } else if v == "3321" { + 3321 + } else if v == "3322" { + 3322 + } else if v == "3323" { + 3323 + } else if v == "3324" { + 3324 + } else if v == "3325" { + 3325 + } else if v == "3326" { + 3326 + } else if v == "3327" { + 3327 + } else if v == "3328" { + 3328 + } else if v == "3329" { + 3329 + } else if v == "3330" { + 3330 + } else if v == "3331" { + 3331 + } else if v == "3332" { + 3332 + } else if v == "3333" { + 3333 + } else if v == "3334" { + 3334 + } else if v == "3335" { + 3335 + } else if v == "3336" { + 3336 + } else if v == "3337" { + 3337 + } else if v == "3338" { + 3338 + } else if v == "3339" { + 3339 + } else if v == "3340" { + 3340 + } else if v == "3341" { + 3341 + } else if v == "3342" { + 3342 + } else if v == "3343" { + 3343 + } else if v == "3344" { + 3344 + } else if v == "3345" { + 3345 + } else if v == "3346" { + 3346 + } else if v == "3347" { + 3347 + } else if v == "3348" { + 3348 + } else if v == "3349" { + 3349 + } else if v == "3350" { + 3350 + } else if v == "3351" { + 3351 + } else if v == "3352" { + 3352 + } else if v == "3353" { + 3353 + } else if v == "3354" { + 3354 + } else if v == "3355" { + 3355 + } else if v == "3356" { + 3356 + } else if v == "3357" { + 3357 + } else if v == "3358" { + 3358 + } else if v == "3359" { + 3359 + } else if v == "3360" { + 3360 + } else if v == "3361" { + 3361 + } else if v == "3362" { + 3362 + } else if v == "3363" { + 3363 + } else if v == "3364" { + 3364 + } else if v == "3365" { + 3365 + } else if v == "3366" { + 3366 + } else if v == "3367" { + 3367 + } else if v == "3368" { + 3368 + } else if v == "3369" { + 3369 + } else if v == "3370" { + 3370 + } else if v == "3371" { + 3371 + } else if v == "3372" { + 3372 + } else if v == "3373" { + 3373 + } else if v == "3374" { + 3374 + } else if v == "3375" { + 3375 + } else if v == "3376" { + 3376 + } else if v == "3377" { + 3377 + } else if v == "3378" { + 3378 + } else if v == "3379" { + 3379 + } else if v == "3380" { + 3380 + } else if v == "3381" { + 3381 + } else if v == "3382" { + 3382 + } else if v == "3383" { + 3383 + } else if v == "3384" { + 3384 + } else if v == "3385" { + 3385 + } else if v == "3386" { + 3386 + } else if v == "3387" { + 3387 + } else if v == "3388" { + 3388 + } else if v == "3389" { + 3389 + } else if v == "3390" { + 3390 + } else if v == "3391" { + 3391 + } else if v == "3392" { + 3392 + } else if v == "3393" { + 3393 + } else if v == "3394" { + 3394 + } else if v == "3395" { + 3395 + } else if v == "3396" { + 3396 + } else if v == "3397" { + 3397 + } else if v == "3398" { + 3398 + } else if v == "3399" { + 3399 + } else if v == "3400" { + 3400 + } else if v == "3401" { + 3401 + } else if v == "3402" { + 3402 + } else if v == "3403" { + 3403 + } else if v == "3404" { + 3404 + } else if v == "3405" { + 3405 + } else if v == "3406" { + 3406 + } else if v == "3407" { + 3407 + } else if v == "3408" { + 3408 + } else if v == "3409" { + 3409 + } else if v == "3410" { + 3410 + } else if v == "3411" { + 3411 + } else if v == "3412" { + 3412 + } else if v == "3413" { + 3413 + } else if v == "3414" { + 3414 + } else if v == "3415" { + 3415 + } else if v == "3416" { + 3416 + } else if v == "3417" { + 3417 + } else if v == "3418" { + 3418 + } else if v == "3419" { + 3419 + } else if v == "3420" { + 3420 + } else if v == "3421" { + 3421 + } else if v == "3422" { + 3422 + } else if v == "3423" { + 3423 + } else if v == "3424" { + 3424 + } else if v == "3425" { + 3425 + } else if v == "3426" { + 3426 + } else if v == "3427" { + 3427 + } else if v == "3428" { + 3428 + } else if v == "3429" { + 3429 + } else if v == "3430" { + 3430 + } else if v == "3431" { + 3431 + } else if v == "3432" { + 3432 + } else if v == "3433" { + 3433 + } else if v == "3434" { + 3434 + } else if v == "3435" { + 3435 + } else if v == "3436" { + 3436 + } else if v == "3437" { + 3437 + } else if v == "3438" { + 3438 + } else if v == "3439" { + 3439 + } else if v == "3440" { + 3440 + } else if v == "3441" { + 3441 + } else if v == "3442" { + 3442 + } else if v == "3443" { + 3443 + } else if v == "3444" { + 3444 + } else if v == "3445" { + 3445 + } else if v == "3446" { + 3446 + } else if v == "3447" { + 3447 + } else if v == "3448" { + 3448 + } else if v == "3449" { + 3449 + } else if v == "3450" { + 3450 + } else if v == "3451" { + 3451 + } else if v == "3452" { + 3452 + } else if v == "3453" { + 3453 + } else if v == "3454" { + 3454 + } else if v == "3455" { + 3455 + } else if v == "3456" { + 3456 + } else if v == "3457" { + 3457 + } else if v == "3458" { + 3458 + } else if v == "3459" { + 3459 + } else if v == "3460" { + 3460 + } else if v == "3461" { + 3461 + } else if v == "3462" { + 3462 + } else if v == "3463" { + 3463 + } else if v == "3464" { + 3464 + } else if v == "3465" { + 3465 + } else if v == "3466" { + 3466 + } else if v == "3467" { + 3467 + } else if v == "3468" { + 3468 + } else if v == "3469" { + 3469 + } else if v == "3470" { + 3470 + } else if v == "3471" { + 3471 + } else if v == "3472" { + 3472 + } else if v == "3473" { + 3473 + } else if v == "3474" { + 3474 + } else if v == "3475" { + 3475 + } else if v == "3476" { + 3476 + } else if v == "3477" { + 3477 + } else if v == "3478" { + 3478 + } else if v == "3479" { + 3479 + } else if v == "3480" { + 3480 + } else if v == "3481" { + 3481 + } else if v == "3482" { + 3482 + } else if v == "3483" { + 3483 + } else if v == "3484" { + 3484 + } else if v == "3485" { + 3485 + } else if v == "3486" { + 3486 + } else if v == "3487" { + 3487 + } else if v == "3488" { + 3488 + } else if v == "3489" { + 3489 + } else if v == "3490" { + 3490 + } else if v == "3491" { + 3491 + } else if v == "3492" { + 3492 + } else if v == "3493" { + 3493 + } else if v == "3494" { + 3494 + } else if v == "3495" { + 3495 + } else if v == "3496" { + 3496 + } else if v == "3497" { + 3497 + } else if v == "3498" { + 3498 + } else if v == "3499" { + 3499 + } else if v == "3500" { + 3500 + } else if v == "3501" { + 3501 + } else if v == "3502" { + 3502 + } else if v == "3503" { + 3503 + } else if v == "3504" { + 3504 + } else if v == "3505" { + 3505 + } else if v == "3506" { + 3506 + } else if v == "3507" { + 3507 + } else if v == "3508" { + 3508 + } else if v == "3509" { + 3509 + } else if v == "3510" { + 3510 + } else if v == "3511" { + 3511 + } else if v == "3512" { + 3512 + } else if v == "3513" { + 3513 + } else if v == "3514" { + 3514 + } else if v == "3515" { + 3515 + } else if v == "3516" { + 3516 + } else if v == "3517" { + 3517 + } else if v == "3518" { + 3518 + } else if v == "3519" { + 3519 + } else if v == "3520" { + 3520 + } else if v == "3521" { + 3521 + } else if v == "3522" { + 3522 + } else if v == "3523" { + 3523 + } else if v == "3524" { + 3524 + } else if v == "3525" { + 3525 + } else if v == "3526" { + 3526 + } else if v == "3527" { + 3527 + } else if v == "3528" { + 3528 + } else if v == "3529" { + 3529 + } else if v == "3530" { + 3530 + } else if v == "3531" { + 3531 + } else if v == "3532" { + 3532 + } else if v == "3533" { + 3533 + } else if v == "3534" { + 3534 + } else if v == "3535" { + 3535 + } else if v == "3536" { + 3536 + } else if v == "3537" { + 3537 + } else if v == "3538" { + 3538 + } else if v == "3539" { + 3539 + } else if v == "3540" { + 3540 + } else if v == "3541" { + 3541 + } else if v == "3542" { + 3542 + } else if v == "3543" { + 3543 + } else if v == "3544" { + 3544 + } else if v == "3545" { + 3545 + } else if v == "3546" { + 3546 + } else if v == "3547" { + 3547 + } else if v == "3548" { + 3548 + } else if v == "3549" { + 3549 + } else if v == "3550" { + 3550 + } else if v == "3551" { + 3551 + } else if v == "3552" { + 3552 + } else if v == "3553" { + 3553 + } else if v == "3554" { + 3554 + } else if v == "3555" { + 3555 + } else if v == "3556" { + 3556 + } else if v == "3557" { + 3557 + } else if v == "3558" { + 3558 + } else if v == "3559" { + 3559 + } else if v == "3560" { + 3560 + } else if v == "3561" { + 3561 + } else if v == "3562" { + 3562 + } else if v == "3563" { + 3563 + } else if v == "3564" { + 3564 + } else if v == "3565" { + 3565 + } else if v == "3566" { + 3566 + } else if v == "3567" { + 3567 + } else if v == "3568" { + 3568 + } else if v == "3569" { + 3569 + } else if v == "3570" { + 3570 + } else if v == "3571" { + 3571 + } else if v == "3572" { + 3572 + } else if v == "3573" { + 3573 + } else if v == "3574" { + 3574 + } else if v == "3575" { + 3575 + } else if v == "3576" { + 3576 + } else if v == "3577" { + 3577 + } else if v == "3578" { + 3578 + } else if v == "3579" { + 3579 + } else if v == "3580" { + 3580 + } else if v == "3581" { + 3581 + } else if v == "3582" { + 3582 + } else if v == "3583" { + 3583 + } else if v == "3584" { + 3584 + } else if v == "3585" { + 3585 + } else if v == "3586" { + 3586 + } else if v == "3587" { + 3587 + } else if v == "3588" { + 3588 + } else if v == "3589" { + 3589 + } else if v == "3590" { + 3590 + } else if v == "3591" { + 3591 + } else if v == "3592" { + 3592 + } else if v == "3593" { + 3593 + } else if v == "3594" { + 3594 + } else if v == "3595" { + 3595 + } else if v == "3596" { + 3596 + } else if v == "3597" { + 3597 + } else if v == "3598" { + 3598 + } else if v == "3599" { + 3599 + } else if v == "3600" { + 3600 + } else if v == "3601" { + 3601 + } else if v == "3602" { + 3602 + } else if v == "3603" { + 3603 + } else if v == "3604" { + 3604 + } else if v == "3605" { + 3605 + } else if v == "3606" { + 3606 + } else if v == "3607" { + 3607 + } else if v == "3608" { + 3608 + } else if v == "3609" { + 3609 + } else if v == "3610" { + 3610 + } else if v == "3611" { + 3611 + } else if v == "3612" { + 3612 + } else if v == "3613" { + 3613 + } else if v == "3614" { + 3614 + } else if v == "3615" { + 3615 + } else if v == "3616" { + 3616 + } else if v == "3617" { + 3617 + } else if v == "3618" { + 3618 + } else if v == "3619" { + 3619 + } else if v == "3620" { + 3620 + } else if v == "3621" { + 3621 + } else if v == "3622" { + 3622 + } else if v == "3623" { + 3623 + } else if v == "3624" { + 3624 + } else if v == "3625" { + 3625 + } else if v == "3626" { + 3626 + } else if v == "3627" { + 3627 + } else if v == "3628" { + 3628 + } else if v == "3629" { + 3629 + } else if v == "3630" { + 3630 + } else if v == "3631" { + 3631 + } else if v == "3632" { + 3632 + } else if v == "3633" { + 3633 + } else if v == "3634" { + 3634 + } else if v == "3635" { + 3635 + } else if v == "3636" { + 3636 + } else if v == "3637" { + 3637 + } else if v == "3638" { + 3638 + } else if v == "3639" { + 3639 + } else if v == "3640" { + 3640 + } else if v == "3641" { + 3641 + } else if v == "3642" { + 3642 + } else if v == "3643" { + 3643 + } else if v == "3644" { + 3644 + } else if v == "3645" { + 3645 + } else if v == "3646" { + 3646 + } else if v == "3647" { + 3647 + } else if v == "3648" { + 3648 + } else if v == "3649" { + 3649 + } else if v == "3650" { + 3650 + } else if v == "3651" { + 3651 + } else if v == "3652" { + 3652 + } else if v == "3653" { + 3653 + } else if v == "3654" { + 3654 + } else if v == "3655" { + 3655 + } else if v == "3656" { + 3656 + } else if v == "3657" { + 3657 + } else if v == "3658" { + 3658 + } else if v == "3659" { + 3659 + } else if v == "3660" { + 3660 + } else if v == "3661" { + 3661 + } else if v == "3662" { + 3662 + } else if v == "3663" { + 3663 + } else if v == "3664" { + 3664 + } else if v == "3665" { + 3665 + } else if v == "3666" { + 3666 + } else if v == "3667" { + 3667 + } else if v == "3668" { + 3668 + } else if v == "3669" { + 3669 + } else if v == "3670" { + 3670 + } else if v == "3671" { + 3671 + } else if v == "3672" { + 3672 + } else if v == "3673" { + 3673 + } else if v == "3674" { + 3674 + } else if v == "3675" { + 3675 + } else if v == "3676" { + 3676 + } else if v == "3677" { + 3677 + } else if v == "3678" { + 3678 + } else if v == "3679" { + 3679 + } else if v == "3680" { + 3680 + } else if v == "3681" { + 3681 + } else if v == "3682" { + 3682 + } else if v == "3683" { + 3683 + } else if v == "3684" { + 3684 + } else if v == "3685" { + 3685 + } else if v == "3686" { + 3686 + } else if v == "3687" { + 3687 + } else if v == "3688" { + 3688 + } else if v == "3689" { + 3689 + } else if v == "3690" { + 3690 + } else if v == "3691" { + 3691 + } else if v == "3692" { + 3692 + } else if v == "3693" { + 3693 + } else if v == "3694" { + 3694 + } else if v == "3695" { + 3695 + } else if v == "3696" { + 3696 + } else if v == "3697" { + 3697 + } else if v == "3698" { + 3698 + } else if v == "3699" { + 3699 + } else if v == "3700" { + 3700 + } else if v == "3701" { + 3701 + } else if v == "3702" { + 3702 + } else if v == "3703" { + 3703 + } else if v == "3704" { + 3704 + } else if v == "3705" { + 3705 + } else if v == "3706" { + 3706 + } else if v == "3707" { + 3707 + } else if v == "3708" { + 3708 + } else if v == "3709" { + 3709 + } else if v == "3710" { + 3710 + } else if v == "3711" { + 3711 + } else if v == "3712" { + 3712 + } else if v == "3713" { + 3713 + } else if v == "3714" { + 3714 + } else if v == "3715" { + 3715 + } else if v == "3716" { + 3716 + } else if v == "3717" { + 3717 + } else if v == "3718" { + 3718 + } else if v == "3719" { + 3719 + } else if v == "3720" { + 3720 + } else if v == "3721" { + 3721 + } else if v == "3722" { + 3722 + } else if v == "3723" { + 3723 + } else if v == "3724" { + 3724 + } else if v == "3725" { + 3725 + } else if v == "3726" { + 3726 + } else if v == "3727" { + 3727 + } else if v == "3728" { + 3728 + } else if v == "3729" { + 3729 + } else if v == "3730" { + 3730 + } else if v == "3731" { + 3731 + } else if v == "3732" { + 3732 + } else if v == "3733" { + 3733 + } else if v == "3734" { + 3734 + } else if v == "3735" { + 3735 + } else if v == "3736" { + 3736 + } else if v == "3737" { + 3737 + } else if v == "3738" { + 3738 + } else if v == "3739" { + 3739 + } else if v == "3740" { + 3740 + } else if v == "3741" { + 3741 + } else if v == "3742" { + 3742 + } else if v == "3743" { + 3743 + } else if v == "3744" { + 3744 + } else if v == "3745" { + 3745 + } else if v == "3746" { + 3746 + } else if v == "3747" { + 3747 + } else if v == "3748" { + 3748 + } else if v == "3749" { + 3749 + } else if v == "3750" { + 3750 + } else if v == "3751" { + 3751 + } else if v == "3752" { + 3752 + } else if v == "3753" { + 3753 + } else if v == "3754" { + 3754 + } else if v == "3755" { + 3755 + } else if v == "3756" { + 3756 + } else if v == "3757" { + 3757 + } else if v == "3758" { + 3758 + } else if v == "3759" { + 3759 + } else if v == "3760" { + 3760 + } else if v == "3761" { + 3761 + } else if v == "3762" { + 3762 + } else if v == "3763" { + 3763 + } else if v == "3764" { + 3764 + } else if v == "3765" { + 3765 + } else if v == "3766" { + 3766 + } else if v == "3767" { + 3767 + } else if v == "3768" { + 3768 + } else if v == "3769" { + 3769 + } else if v == "3770" { + 3770 + } else if v == "3771" { + 3771 + } else if v == "3772" { + 3772 + } else if v == "3773" { + 3773 + } else if v == "3774" { + 3774 + } else if v == "3775" { + 3775 + } else if v == "3776" { + 3776 + } else if v == "3777" { + 3777 + } else if v == "3778" { + 3778 + } else if v == "3779" { + 3779 + } else if v == "3780" { + 3780 + } else if v == "3781" { + 3781 + } else if v == "3782" { + 3782 + } else if v == "3783" { + 3783 + } else if v == "3784" { + 3784 + } else if v == "3785" { + 3785 + } else if v == "3786" { + 3786 + } else if v == "3787" { + 3787 + } else if v == "3788" { + 3788 + } else if v == "3789" { + 3789 + } else if v == "3790" { + 3790 + } else if v == "3791" { + 3791 + } else if v == "3792" { + 3792 + } else if v == "3793" { + 3793 + } else if v == "3794" { + 3794 + } else if v == "3795" { + 3795 + } else if v == "3796" { + 3796 + } else if v == "3797" { + 3797 + } else if v == "3798" { + 3798 + } else if v == "3799" { + 3799 + } else if v == "3800" { + 3800 + } else if v == "3801" { + 3801 + } else if v == "3802" { + 3802 + } else if v == "3803" { + 3803 + } else if v == "3804" { + 3804 + } else if v == "3805" { + 3805 + } else if v == "3806" { + 3806 + } else if v == "3807" { + 3807 + } else if v == "3808" { + 3808 + } else if v == "3809" { + 3809 + } else if v == "3810" { + 3810 + } else if v == "3811" { + 3811 + } else if v == "3812" { + 3812 + } else if v == "3813" { + 3813 + } else if v == "3814" { + 3814 + } else if v == "3815" { + 3815 + } else if v == "3816" { + 3816 + } else if v == "3817" { + 3817 + } else if v == "3818" { + 3818 + } else if v == "3819" { + 3819 + } else if v == "3820" { + 3820 + } else if v == "3821" { + 3821 + } else if v == "3822" { + 3822 + } else if v == "3823" { + 3823 + } else if v == "3824" { + 3824 + } else if v == "3825" { + 3825 + } else if v == "3826" { + 3826 + } else if v == "3827" { + 3827 + } else if v == "3828" { + 3828 + } else if v == "3829" { + 3829 + } else if v == "3830" { + 3830 + } else if v == "3831" { + 3831 + } else if v == "3832" { + 3832 + } else if v == "3833" { + 3833 + } else if v == "3834" { + 3834 + } else if v == "3835" { + 3835 + } else if v == "3836" { + 3836 + } else if v == "3837" { + 3837 + } else if v == "3838" { + 3838 + } else if v == "3839" { + 3839 + } else if v == "3840" { + 3840 + } else if v == "3841" { + 3841 + } else if v == "3842" { + 3842 + } else if v == "3843" { + 3843 + } else if v == "3844" { + 3844 + } else if v == "3845" { + 3845 + } else if v == "3846" { + 3846 + } else if v == "3847" { + 3847 + } else if v == "3848" { + 3848 + } else if v == "3849" { + 3849 + } else if v == "3850" { + 3850 + } else if v == "3851" { + 3851 + } else if v == "3852" { + 3852 + } else if v == "3853" { + 3853 + } else if v == "3854" { + 3854 + } else if v == "3855" { + 3855 + } else if v == "3856" { + 3856 + } else if v == "3857" { + 3857 + } else if v == "3858" { + 3858 + } else if v == "3859" { + 3859 + } else if v == "3860" { + 3860 + } else if v == "3861" { + 3861 + } else if v == "3862" { + 3862 + } else if v == "3863" { + 3863 + } else if v == "3864" { + 3864 + } else if v == "3865" { + 3865 + } else if v == "3866" { + 3866 + } else if v == "3867" { + 3867 + } else if v == "3868" { + 3868 + } else if v == "3869" { + 3869 + } else if v == "3870" { + 3870 + } else if v == "3871" { + 3871 + } else if v == "3872" { + 3872 + } else if v == "3873" { + 3873 + } else if v == "3874" { + 3874 + } else if v == "3875" { + 3875 + } else if v == "3876" { + 3876 + } else if v == "3877" { + 3877 + } else if v == "3878" { + 3878 + } else if v == "3879" { + 3879 + } else if v == "3880" { + 3880 + } else if v == "3881" { + 3881 + } else if v == "3882" { + 3882 + } else if v == "3883" { + 3883 + } else if v == "3884" { + 3884 + } else if v == "3885" { + 3885 + } else if v == "3886" { + 3886 + } else if v == "3887" { + 3887 + } else if v == "3888" { + 3888 + } else if v == "3889" { + 3889 + } else if v == "3890" { + 3890 + } else if v == "3891" { + 3891 + } else if v == "3892" { + 3892 + } else if v == "3893" { + 3893 + } else if v == "3894" { + 3894 + } else if v == "3895" { + 3895 + } else if v == "3896" { + 3896 + } else if v == "3897" { + 3897 + } else if v == "3898" { + 3898 + } else if v == "3899" { + 3899 + } else if v == "3900" { + 3900 + } else if v == "3901" { + 3901 + } else if v == "3902" { + 3902 + } else if v == "3903" { + 3903 + } else if v == "3904" { + 3904 + } else if v == "3905" { + 3905 + } else if v == "3906" { + 3906 + } else if v == "3907" { + 3907 + } else if v == "3908" { + 3908 + } else if v == "3909" { + 3909 + } else if v == "3910" { + 3910 + } else if v == "3911" { + 3911 + } else if v == "3912" { + 3912 + } else if v == "3913" { + 3913 + } else if v == "3914" { + 3914 + } else if v == "3915" { + 3915 + } else if v == "3916" { + 3916 + } else if v == "3917" { + 3917 + } else if v == "3918" { + 3918 + } else if v == "3919" { + 3919 + } else if v == "3920" { + 3920 + } else if v == "3921" { + 3921 + } else if v == "3922" { + 3922 + } else if v == "3923" { + 3923 + } else if v == "3924" { + 3924 + } else if v == "3925" { + 3925 + } else if v == "3926" { + 3926 + } else if v == "3927" { + 3927 + } else if v == "3928" { + 3928 + } else if v == "3929" { + 3929 + } else if v == "3930" { + 3930 + } else if v == "3931" { + 3931 + } else if v == "3932" { + 3932 + } else if v == "3933" { + 3933 + } else if v == "3934" { + 3934 + } else if v == "3935" { + 3935 + } else if v == "3936" { + 3936 + } else if v == "3937" { + 3937 + } else if v == "3938" { + 3938 + } else if v == "3939" { + 3939 + } else if v == "3940" { + 3940 + } else if v == "3941" { + 3941 + } else if v == "3942" { + 3942 + } else if v == "3943" { + 3943 + } else if v == "3944" { + 3944 + } else if v == "3945" { + 3945 + } else if v == "3946" { + 3946 + } else if v == "3947" { + 3947 + } else if v == "3948" { + 3948 + } else if v == "3949" { + 3949 + } else if v == "3950" { + 3950 + } else if v == "3951" { + 3951 + } else if v == "3952" { + 3952 + } else if v == "3953" { + 3953 + } else if v == "3954" { + 3954 + } else if v == "3955" { + 3955 + } else if v == "3956" { + 3956 + } else if v == "3957" { + 3957 + } else if v == "3958" { + 3958 + } else if v == "3959" { + 3959 + } else if v == "3960" { + 3960 + } else if v == "3961" { + 3961 + } else if v == "3962" { + 3962 + } else if v == "3963" { + 3963 + } else if v == "3964" { + 3964 + } else if v == "3965" { + 3965 + } else if v == "3966" { + 3966 + } else if v == "3967" { + 3967 + } else if v == "3968" { + 3968 + } else if v == "3969" { + 3969 + } else if v == "3970" { + 3970 + } else if v == "3971" { + 3971 + } else if v == "3972" { + 3972 + } else if v == "3973" { + 3973 + } else if v == "3974" { + 3974 + } else if v == "3975" { + 3975 + } else if v == "3976" { + 3976 + } else if v == "3977" { + 3977 + } else if v == "3978" { + 3978 + } else if v == "3979" { + 3979 + } else if v == "3980" { + 3980 + } else if v == "3981" { + 3981 + } else if v == "3982" { + 3982 + } else if v == "3983" { + 3983 + } else if v == "3984" { + 3984 + } else if v == "3985" { + 3985 + } else if v == "3986" { + 3986 + } else if v == "3987" { + 3987 + } else if v == "3988" { + 3988 + } else if v == "3989" { + 3989 + } else if v == "3990" { + 3990 + } else if v == "3991" { + 3991 + } else if v == "3992" { + 3992 + } else if v == "3993" { + 3993 + } else if v == "3994" { + 3994 + } else if v == "3995" { + 3995 + } else if v == "3996" { + 3996 + } else if v == "3997" { + 3997 + } else if v == "3998" { + 3998 + } else if v == "3999" { + 3999 + } else if v == "4000" { + 4000 + } else if v == "4001" { + 4001 + } else if v == "4002" { + 4002 + } else if v == "4003" { + 4003 + } else if v == "4004" { + 4004 + } else if v == "4005" { + 4005 + } else if v == "4006" { + 4006 + } else if v == "4007" { + 4007 + } else if v == "4008" { + 4008 + } else if v == "4009" { + 4009 + } else if v == "4010" { + 4010 + } else if v == "4011" { + 4011 + } else if v == "4012" { + 4012 + } else if v == "4013" { + 4013 + } else if v == "4014" { + 4014 + } else if v == "4015" { + 4015 + } else if v == "4016" { + 4016 + } else if v == "4017" { + 4017 + } else if v == "4018" { + 4018 + } else if v == "4019" { + 4019 + } else if v == "4020" { + 4020 + } else if v == "4021" { + 4021 + } else if v == "4022" { + 4022 + } else if v == "4023" { + 4023 + } else if v == "4024" { + 4024 + } else if v == "4025" { + 4025 + } else if v == "4026" { + 4026 + } else if v == "4027" { + 4027 + } else if v == "4028" { + 4028 + } else if v == "4029" { + 4029 + } else if v == "4030" { + 4030 + } else if v == "4031" { + 4031 + } else if v == "4032" { + 4032 + } else if v == "4033" { + 4033 + } else if v == "4034" { + 4034 + } else if v == "4035" { + 4035 + } else if v == "4036" { + 4036 + } else if v == "4037" { + 4037 + } else if v == "4038" { + 4038 + } else if v == "4039" { + 4039 + } else if v == "4040" { + 4040 + } else if v == "4041" { + 4041 + } else if v == "4042" { + 4042 + } else if v == "4043" { + 4043 + } else if v == "4044" { + 4044 + } else if v == "4045" { + 4045 + } else if v == "4046" { + 4046 + } else if v == "4047" { + 4047 + } else if v == "4048" { + 4048 + } else if v == "4049" { + 4049 + } else if v == "4050" { + 4050 + } else if v == "4051" { + 4051 + } else if v == "4052" { + 4052 + } else if v == "4053" { + 4053 + } else if v == "4054" { + 4054 + } else if v == "4055" { + 4055 + } else if v == "4056" { + 4056 + } else if v == "4057" { + 4057 + } else if v == "4058" { + 4058 + } else if v == "4059" { + 4059 + } else if v == "4060" { + 4060 + } else if v == "4061" { + 4061 + } else if v == "4062" { + 4062 + } else if v == "4063" { + 4063 + } else if v == "4064" { + 4064 + } else if v == "4065" { + 4065 + } else if v == "4066" { + 4066 + } else if v == "4067" { + 4067 + } else if v == "4068" { + 4068 + } else if v == "4069" { + 4069 + } else if v == "4070" { + 4070 + } else if v == "4071" { + 4071 + } else if v == "4072" { + 4072 + } else if v == "4073" { + 4073 + } else if v == "4074" { + 4074 + } else if v == "4075" { + 4075 + } else if v == "4076" { + 4076 + } else if v == "4077" { + 4077 + } else if v == "4078" { + 4078 + } else if v == "4079" { + 4079 + } else if v == "4080" { + 4080 + } else if v == "4081" { + 4081 + } else if v == "4082" { + 4082 + } else if v == "4083" { + 4083 + } else if v == "4084" { + 4084 + } else if v == "4085" { + 4085 + } else if v == "4086" { + 4086 + } else if v == "4087" { + 4087 + } else if v == "4088" { + 4088 + } else if v == "4089" { + 4089 + } else if v == "4090" { + 4090 + } else if v == "4091" { + 4091 + } else if v == "4092" { + 4092 + } else if v == "4093" { + 4093 + } else if v == "4094" { + 4094 + } else if v == "4095" { + 4095 + } else if v == "4096" { + 4096 + } else if v == "4097" { + 4097 + } else if v == "4098" { + 4098 + } else if v == "4099" { + 4099 + } else if v == "4100" { + 4100 + } else if v == "4101" { + 4101 + } else if v == "4102" { + 4102 + } else if v == "4103" { + 4103 + } else if v == "4104" { + 4104 + } else if v == "4105" { + 4105 + } else if v == "4106" { + 4106 + } else if v == "4107" { + 4107 + } else if v == "4108" { + 4108 + } else if v == "4109" { + 4109 + } else if v == "4110" { + 4110 + } else if v == "4111" { + 4111 + } else if v == "4112" { + 4112 + } else if v == "4113" { + 4113 + } else if v == "4114" { + 4114 + } else if v == "4115" { + 4115 + } else if v == "4116" { + 4116 + } else if v == "4117" { + 4117 + } else if v == "4118" { + 4118 + } else if v == "4119" { + 4119 + } else if v == "4120" { + 4120 + } else if v == "4121" { + 4121 + } else if v == "4122" { + 4122 + } else if v == "4123" { + 4123 + } else if v == "4124" { + 4124 + } else if v == "4125" { + 4125 + } else if v == "4126" { + 4126 + } else if v == "4127" { + 4127 + } else if v == "4128" { + 4128 + } else if v == "4129" { + 4129 + } else if v == "4130" { + 4130 + } else if v == "4131" { + 4131 + } else if v == "4132" { + 4132 + } else if v == "4133" { + 4133 + } else if v == "4134" { + 4134 + } else if v == "4135" { + 4135 + } else if v == "4136" { + 4136 + } else if v == "4137" { + 4137 + } else if v == "4138" { + 4138 + } else if v == "4139" { + 4139 + } else if v == "4140" { + 4140 + } else if v == "4141" { + 4141 + } else if v == "4142" { + 4142 + } else if v == "4143" { + 4143 + } else if v == "4144" { + 4144 + } else if v == "4145" { + 4145 + } else if v == "4146" { + 4146 + } else if v == "4147" { + 4147 + } else if v == "4148" { + 4148 + } else if v == "4149" { + 4149 + } else if v == "4150" { + 4150 + } else if v == "4151" { + 4151 + } else if v == "4152" { + 4152 + } else if v == "4153" { + 4153 + } else if v == "4154" { + 4154 + } else if v == "4155" { + 4155 + } else if v == "4156" { + 4156 + } else if v == "4157" { + 4157 + } else if v == "4158" { + 4158 + } else if v == "4159" { + 4159 + } else if v == "4160" { + 4160 + } else if v == "4161" { + 4161 + } else if v == "4162" { + 4162 + } else if v == "4163" { + 4163 + } else if v == "4164" { + 4164 + } else if v == "4165" { + 4165 + } else if v == "4166" { + 4166 + } else if v == "4167" { + 4167 + } else if v == "4168" { + 4168 + } else if v == "4169" { + 4169 + } else if v == "4170" { + 4170 + } else if v == "4171" { + 4171 + } else if v == "4172" { + 4172 + } else if v == "4173" { + 4173 + } else if v == "4174" { + 4174 + } else if v == "4175" { + 4175 + } else if v == "4176" { + 4176 + } else if v == "4177" { + 4177 + } else if v == "4178" { + 4178 + } else if v == "4179" { + 4179 + } else if v == "4180" { + 4180 + } else if v == "4181" { + 4181 + } else if v == "4182" { + 4182 + } else if v == "4183" { + 4183 + } else if v == "4184" { + 4184 + } else if v == "4185" { + 4185 + } else if v == "4186" { + 4186 + } else if v == "4187" { + 4187 + } else if v == "4188" { + 4188 + } else if v == "4189" { + 4189 + } else if v == "4190" { + 4190 + } else if v == "4191" { + 4191 + } else if v == "4192" { + 4192 + } else if v == "4193" { + 4193 + } else if v == "4194" { + 4194 + } else if v == "4195" { + 4195 + } else if v == "4196" { + 4196 + } else if v == "4197" { + 4197 + } else if v == "4198" { + 4198 + } else if v == "4199" { + 4199 + } else if v == "4200" { + 4200 + } else if v == "4201" { + 4201 + } else if v == "4202" { + 4202 + } else if v == "4203" { + 4203 + } else if v == "4204" { + 4204 + } else if v == "4205" { + 4205 + } else if v == "4206" { + 4206 + } else if v == "4207" { + 4207 + } else if v == "4208" { + 4208 + } else if v == "4209" { + 4209 + } else if v == "4210" { + 4210 + } else if v == "4211" { + 4211 + } else if v == "4212" { + 4212 + } else if v == "4213" { + 4213 + } else if v == "4214" { + 4214 + } else if v == "4215" { + 4215 + } else if v == "4216" { + 4216 + } else if v == "4217" { + 4217 + } else if v == "4218" { + 4218 + } else if v == "4219" { + 4219 + } else if v == "4220" { + 4220 + } else if v == "4221" { + 4221 + } else if v == "4222" { + 4222 + } else if v == "4223" { + 4223 + } else if v == "4224" { + 4224 + } else if v == "4225" { + 4225 + } else if v == "4226" { + 4226 + } else if v == "4227" { + 4227 + } else if v == "4228" { + 4228 + } else if v == "4229" { + 4229 + } else if v == "4230" { + 4230 + } else if v == "4231" { + 4231 + } else if v == "4232" { + 4232 + } else if v == "4233" { + 4233 + } else if v == "4234" { + 4234 + } else if v == "4235" { + 4235 + } else if v == "4236" { + 4236 + } else if v == "4237" { + 4237 + } else if v == "4238" { + 4238 + } else if v == "4239" { + 4239 + } else if v == "4240" { + 4240 + } else if v == "4241" { + 4241 + } else if v == "4242" { + 4242 + } else if v == "4243" { + 4243 + } else if v == "4244" { + 4244 + } else if v == "4245" { + 4245 + } else if v == "4246" { + 4246 + } else if v == "4247" { + 4247 + } else if v == "4248" { + 4248 + } else if v == "4249" { + 4249 + } else if v == "4250" { + 4250 + } else if v == "4251" { + 4251 + } else if v == "4252" { + 4252 + } else if v == "4253" { + 4253 + } else if v == "4254" { + 4254 + } else if v == "4255" { + 4255 + } else if v == "4256" { + 4256 + } else if v == "4257" { + 4257 + } else if v == "4258" { + 4258 + } else if v == "4259" { + 4259 + } else if v == "4260" { + 4260 + } else if v == "4261" { + 4261 + } else if v == "4262" { + 4262 + } else if v == "4263" { + 4263 + } else if v == "4264" { + 4264 + } else if v == "4265" { + 4265 + } else if v == "4266" { + 4266 + } else if v == "4267" { + 4267 + } else if v == "4268" { + 4268 + } else if v == "4269" { + 4269 + } else if v == "4270" { + 4270 + } else if v == "4271" { + 4271 + } else if v == "4272" { + 4272 + } else if v == "4273" { + 4273 + } else if v == "4274" { + 4274 + } else if v == "4275" { + 4275 + } else if v == "4276" { + 4276 + } else if v == "4277" { + 4277 + } else if v == "4278" { + 4278 + } else if v == "4279" { + 4279 + } else if v == "4280" { + 4280 + } else if v == "4281" { + 4281 + } else if v == "4282" { + 4282 + } else if v == "4283" { + 4283 + } else if v == "4284" { + 4284 + } else if v == "4285" { + 4285 + } else if v == "4286" { + 4286 + } else if v == "4287" { + 4287 + } else if v == "4288" { + 4288 + } else if v == "4289" { + 4289 + } else if v == "4290" { + 4290 + } else if v == "4291" { + 4291 + } else if v == "4292" { + 4292 + } else if v == "4293" { + 4293 + } else if v == "4294" { + 4294 + } else if v == "4295" { + 4295 + } else if v == "4296" { + 4296 + } else if v == "4297" { + 4297 + } else if v == "4298" { + 4298 + } else if v == "4299" { + 4299 + } else if v == "4300" { + 4300 + } else if v == "4301" { + 4301 + } else if v == "4302" { + 4302 + } else if v == "4303" { + 4303 + } else if v == "4304" { + 4304 + } else if v == "4305" { + 4305 + } else if v == "4306" { + 4306 + } else if v == "4307" { + 4307 + } else if v == "4308" { + 4308 + } else if v == "4309" { + 4309 + } else if v == "4310" { + 4310 + } else if v == "4311" { + 4311 + } else if v == "4312" { + 4312 + } else if v == "4313" { + 4313 + } else if v == "4314" { + 4314 + } else if v == "4315" { + 4315 + } else if v == "4316" { + 4316 + } else if v == "4317" { + 4317 + } else if v == "4318" { + 4318 + } else if v == "4319" { + 4319 + } else if v == "4320" { + 4320 + } else if v == "4321" { + 4321 + } else if v == "4322" { + 4322 + } else if v == "4323" { + 4323 + } else if v == "4324" { + 4324 + } else if v == "4325" { + 4325 + } else if v == "4326" { + 4326 + } else if v == "4327" { + 4327 + } else if v == "4328" { + 4328 + } else if v == "4329" { + 4329 + } else if v == "4330" { + 4330 + } else if v == "4331" { + 4331 + } else if v == "4332" { + 4332 + } else if v == "4333" { + 4333 + } else if v == "4334" { + 4334 + } else if v == "4335" { + 4335 + } else if v == "4336" { + 4336 + } else if v == "4337" { + 4337 + } else if v == "4338" { + 4338 + } else if v == "4339" { + 4339 + } else if v == "4340" { + 4340 + } else if v == "4341" { + 4341 + } else if v == "4342" { + 4342 + } else if v == "4343" { + 4343 + } else if v == "4344" { + 4344 + } else if v == "4345" { + 4345 + } else if v == "4346" { + 4346 + } else if v == "4347" { + 4347 + } else if v == "4348" { + 4348 + } else if v == "4349" { + 4349 + } else if v == "4350" { + 4350 + } else if v == "4351" { + 4351 + } else if v == "4352" { + 4352 + } else if v == "4353" { + 4353 + } else if v == "4354" { + 4354 + } else if v == "4355" { + 4355 + } else if v == "4356" { + 4356 + } else if v == "4357" { + 4357 + } else if v == "4358" { + 4358 + } else if v == "4359" { + 4359 + } else if v == "4360" { + 4360 + } else if v == "4361" { + 4361 + } else if v == "4362" { + 4362 + } else if v == "4363" { + 4363 + } else if v == "4364" { + 4364 + } else if v == "4365" { + 4365 + } else if v == "4366" { + 4366 + } else if v == "4367" { + 4367 + } else if v == "4368" { + 4368 + } else if v == "4369" { + 4369 + } else if v == "4370" { + 4370 + } else if v == "4371" { + 4371 + } else if v == "4372" { + 4372 + } else if v == "4373" { + 4373 + } else if v == "4374" { + 4374 + } else if v == "4375" { + 4375 + } else if v == "4376" { + 4376 + } else if v == "4377" { + 4377 + } else if v == "4378" { + 4378 + } else if v == "4379" { + 4379 + } else if v == "4380" { + 4380 + } else if v == "4381" { + 4381 + } else if v == "4382" { + 4382 + } else if v == "4383" { + 4383 + } else if v == "4384" { + 4384 + } else if v == "4385" { + 4385 + } else if v == "4386" { + 4386 + } else if v == "4387" { + 4387 + } else if v == "4388" { + 4388 + } else if v == "4389" { + 4389 + } else if v == "4390" { + 4390 + } else if v == "4391" { + 4391 + } else if v == "4392" { + 4392 + } else if v == "4393" { + 4393 + } else if v == "4394" { + 4394 + } else if v == "4395" { + 4395 + } else if v == "4396" { + 4396 + } else if v == "4397" { + 4397 + } else if v == "4398" { + 4398 + } else if v == "4399" { + 4399 + } else if v == "4400" { + 4400 + } else if v == "4401" { + 4401 + } else if v == "4402" { + 4402 + } else if v == "4403" { + 4403 + } else if v == "4404" { + 4404 + } else if v == "4405" { + 4405 + } else if v == "4406" { + 4406 + } else if v == "4407" { + 4407 + } else if v == "4408" { + 4408 + } else if v == "4409" { + 4409 + } else if v == "4410" { + 4410 + } else if v == "4411" { + 4411 + } else if v == "4412" { + 4412 + } else if v == "4413" { + 4413 + } else if v == "4414" { + 4414 + } else if v == "4415" { + 4415 + } else if v == "4416" { + 4416 + } else if v == "4417" { + 4417 + } else if v == "4418" { + 4418 + } else if v == "4419" { + 4419 + } else if v == "4420" { + 4420 + } else if v == "4421" { + 4421 + } else if v == "4422" { + 4422 + } else if v == "4423" { + 4423 + } else if v == "4424" { + 4424 + } else if v == "4425" { + 4425 + } else if v == "4426" { + 4426 + } else if v == "4427" { + 4427 + } else if v == "4428" { + 4428 + } else if v == "4429" { + 4429 + } else if v == "4430" { + 4430 + } else if v == "4431" { + 4431 + } else if v == "4432" { + 4432 + } else if v == "4433" { + 4433 + } else if v == "4434" { + 4434 + } else if v == "4435" { + 4435 + } else if v == "4436" { + 4436 + } else if v == "4437" { + 4437 + } else if v == "4438" { + 4438 + } else if v == "4439" { + 4439 + } else if v == "4440" { + 4440 + } else if v == "4441" { + 4441 + } else if v == "4442" { + 4442 + } else if v == "4443" { + 4443 + } else if v == "4444" { + 4444 + } else if v == "4445" { + 4445 + } else if v == "4446" { + 4446 + } else if v == "4447" { + 4447 + } else if v == "4448" { + 4448 + } else if v == "4449" { + 4449 + } else if v == "4450" { + 4450 + } else if v == "4451" { + 4451 + } else if v == "4452" { + 4452 + } else if v == "4453" { + 4453 + } else if v == "4454" { + 4454 + } else if v == "4455" { + 4455 + } else if v == "4456" { + 4456 + } else if v == "4457" { + 4457 + } else if v == "4458" { + 4458 + } else if v == "4459" { + 4459 + } else if v == "4460" { + 4460 + } else if v == "4461" { + 4461 + } else if v == "4462" { + 4462 + } else if v == "4463" { + 4463 + } else if v == "4464" { + 4464 + } else if v == "4465" { + 4465 + } else if v == "4466" { + 4466 + } else if v == "4467" { + 4467 + } else if v == "4468" { + 4468 + } else if v == "4469" { + 4469 + } else if v == "4470" { + 4470 + } else if v == "4471" { + 4471 + } else if v == "4472" { + 4472 + } else if v == "4473" { + 4473 + } else if v == "4474" { + 4474 + } else if v == "4475" { + 4475 + } else if v == "4476" { + 4476 + } else if v == "4477" { + 4477 + } else if v == "4478" { + 4478 + } else if v == "4479" { + 4479 + } else if v == "4480" { + 4480 + } else if v == "4481" { + 4481 + } else if v == "4482" { + 4482 + } else if v == "4483" { + 4483 + } else if v == "4484" { + 4484 + } else if v == "4485" { + 4485 + } else if v == "4486" { + 4486 + } else if v == "4487" { + 4487 + } else if v == "4488" { + 4488 + } else if v == "4489" { + 4489 + } else if v == "4490" { + 4490 + } else if v == "4491" { + 4491 + } else if v == "4492" { + 4492 + } else if v == "4493" { + 4493 + } else if v == "4494" { + 4494 + } else if v == "4495" { + 4495 + } else if v == "4496" { + 4496 + } else if v == "4497" { + 4497 + } else if v == "4498" { + 4498 + } else if v == "4499" { + 4499 + } else if v == "4500" { + 4500 + } else if v == "4501" { + 4501 + } else if v == "4502" { + 4502 + } else if v == "4503" { + 4503 + } else if v == "4504" { + 4504 + } else if v == "4505" { + 4505 + } else if v == "4506" { + 4506 + } else if v == "4507" { + 4507 + } else if v == "4508" { + 4508 + } else if v == "4509" { + 4509 + } else if v == "4510" { + 4510 + } else if v == "4511" { + 4511 + } else if v == "4512" { + 4512 + } else if v == "4513" { + 4513 + } else if v == "4514" { + 4514 + } else if v == "4515" { + 4515 + } else if v == "4516" { + 4516 + } else if v == "4517" { + 4517 + } else if v == "4518" { + 4518 + } else if v == "4519" { + 4519 + } else if v == "4520" { + 4520 + } else if v == "4521" { + 4521 + } else if v == "4522" { + 4522 + } else if v == "4523" { + 4523 + } else if v == "4524" { + 4524 + } else if v == "4525" { + 4525 + } else if v == "4526" { + 4526 + } else if v == "4527" { + 4527 + } else if v == "4528" { + 4528 + } else if v == "4529" { + 4529 + } else if v == "4530" { + 4530 + } else if v == "4531" { + 4531 + } else if v == "4532" { + 4532 + } else if v == "4533" { + 4533 + } else if v == "4534" { + 4534 + } else if v == "4535" { + 4535 + } else if v == "4536" { + 4536 + } else if v == "4537" { + 4537 + } else if v == "4538" { + 4538 + } else if v == "4539" { + 4539 + } else if v == "4540" { + 4540 + } else if v == "4541" { + 4541 + } else if v == "4542" { + 4542 + } else if v == "4543" { + 4543 + } else if v == "4544" { + 4544 + } else if v == "4545" { + 4545 + } else if v == "4546" { + 4546 + } else if v == "4547" { + 4547 + } else if v == "4548" { + 4548 + } else if v == "4549" { + 4549 + } else if v == "4550" { + 4550 + } else if v == "4551" { + 4551 + } else if v == "4552" { + 4552 + } else if v == "4553" { + 4553 + } else if v == "4554" { + 4554 + } else if v == "4555" { + 4555 + } else if v == "4556" { + 4556 + } else if v == "4557" { + 4557 + } else if v == "4558" { + 4558 + } else if v == "4559" { + 4559 + } else if v == "4560" { + 4560 + } else if v == "4561" { + 4561 + } else if v == "4562" { + 4562 + } else if v == "4563" { + 4563 + } else if v == "4564" { + 4564 + } else if v == "4565" { + 4565 + } else if v == "4566" { + 4566 + } else if v == "4567" { + 4567 + } else if v == "4568" { + 4568 + } else if v == "4569" { + 4569 + } else if v == "4570" { + 4570 + } else if v == "4571" { + 4571 + } else if v == "4572" { + 4572 + } else if v == "4573" { + 4573 + } else if v == "4574" { + 4574 + } else if v == "4575" { + 4575 + } else if v == "4576" { + 4576 + } else if v == "4577" { + 4577 + } else if v == "4578" { + 4578 + } else if v == "4579" { + 4579 + } else if v == "4580" { + 4580 + } else if v == "4581" { + 4581 + } else if v == "4582" { + 4582 + } else if v == "4583" { + 4583 + } else if v == "4584" { + 4584 + } else if v == "4585" { + 4585 + } else if v == "4586" { + 4586 + } else if v == "4587" { + 4587 + } else if v == "4588" { + 4588 + } else if v == "4589" { + 4589 + } else if v == "4590" { + 4590 + } else if v == "4591" { + 4591 + } else if v == "4592" { + 4592 + } else if v == "4593" { + 4593 + } else if v == "4594" { + 4594 + } else if v == "4595" { + 4595 + } else if v == "4596" { + 4596 + } else if v == "4597" { + 4597 + } else if v == "4598" { + 4598 + } else if v == "4599" { + 4599 + } else if v == "4600" { + 4600 + } else if v == "4601" { + 4601 + } else if v == "4602" { + 4602 + } else if v == "4603" { + 4603 + } else if v == "4604" { + 4604 + } else if v == "4605" { + 4605 + } else if v == "4606" { + 4606 + } else if v == "4607" { + 4607 + } else if v == "4608" { + 4608 + } else if v == "4609" { + 4609 + } else if v == "4610" { + 4610 + } else if v == "4611" { + 4611 + } else if v == "4612" { + 4612 + } else if v == "4613" { + 4613 + } else if v == "4614" { + 4614 + } else if v == "4615" { + 4615 + } else if v == "4616" { + 4616 + } else if v == "4617" { + 4617 + } else if v == "4618" { + 4618 + } else if v == "4619" { + 4619 + } else if v == "4620" { + 4620 + } else if v == "4621" { + 4621 + } else if v == "4622" { + 4622 + } else if v == "4623" { + 4623 + } else if v == "4624" { + 4624 + } else if v == "4625" { + 4625 + } else if v == "4626" { + 4626 + } else if v == "4627" { + 4627 + } else if v == "4628" { + 4628 + } else if v == "4629" { + 4629 + } else if v == "4630" { + 4630 + } else if v == "4631" { + 4631 + } else if v == "4632" { + 4632 + } else if v == "4633" { + 4633 + } else if v == "4634" { + 4634 + } else if v == "4635" { + 4635 + } else if v == "4636" { + 4636 + } else if v == "4637" { + 4637 + } else if v == "4638" { + 4638 + } else if v == "4639" { + 4639 + } else if v == "4640" { + 4640 + } else if v == "4641" { + 4641 + } else if v == "4642" { + 4642 + } else if v == "4643" { + 4643 + } else if v == "4644" { + 4644 + } else if v == "4645" { + 4645 + } else if v == "4646" { + 4646 + } else if v == "4647" { + 4647 + } else if v == "4648" { + 4648 + } else if v == "4649" { + 4649 + } else if v == "4650" { + 4650 + } else if v == "4651" { + 4651 + } else if v == "4652" { + 4652 + } else if v == "4653" { + 4653 + } else if v == "4654" { + 4654 + } else if v == "4655" { + 4655 + } else if v == "4656" { + 4656 + } else if v == "4657" { + 4657 + } else if v == "4658" { + 4658 + } else if v == "4659" { + 4659 + } else if v == "4660" { + 4660 + } else if v == "4661" { + 4661 + } else if v == "4662" { + 4662 + } else if v == "4663" { + 4663 + } else if v == "4664" { + 4664 + } else if v == "4665" { + 4665 + } else if v == "4666" { + 4666 + } else if v == "4667" { + 4667 + } else if v == "4668" { + 4668 + } else if v == "4669" { + 4669 + } else if v == "4670" { + 4670 + } else if v == "4671" { + 4671 + } else if v == "4672" { + 4672 + } else if v == "4673" { + 4673 + } else if v == "4674" { + 4674 + } else if v == "4675" { + 4675 + } else if v == "4676" { + 4676 + } else if v == "4677" { + 4677 + } else if v == "4678" { + 4678 + } else if v == "4679" { + 4679 + } else if v == "4680" { + 4680 + } else if v == "4681" { + 4681 + } else if v == "4682" { + 4682 + } else if v == "4683" { + 4683 + } else if v == "4684" { + 4684 + } else if v == "4685" { + 4685 + } else if v == "4686" { + 4686 + } else if v == "4687" { + 4687 + } else if v == "4688" { + 4688 + } else if v == "4689" { + 4689 + } else if v == "4690" { + 4690 + } else if v == "4691" { + 4691 + } else if v == "4692" { + 4692 + } else if v == "4693" { + 4693 + } else if v == "4694" { + 4694 + } else if v == "4695" { + 4695 + } else if v == "4696" { + 4696 + } else if v == "4697" { + 4697 + } else if v == "4698" { + 4698 + } else if v == "4699" { + 4699 + } else if v == "4700" { + 4700 + } else if v == "4701" { + 4701 + } else if v == "4702" { + 4702 + } else if v == "4703" { + 4703 + } else if v == "4704" { + 4704 + } else if v == "4705" { + 4705 + } else if v == "4706" { + 4706 + } else if v == "4707" { + 4707 + } else if v == "4708" { + 4708 + } else if v == "4709" { + 4709 + } else if v == "4710" { + 4710 + } else if v == "4711" { + 4711 + } else if v == "4712" { + 4712 + } else if v == "4713" { + 4713 + } else if v == "4714" { + 4714 + } else if v == "4715" { + 4715 + } else if v == "4716" { + 4716 + } else if v == "4717" { + 4717 + } else if v == "4718" { + 4718 + } else if v == "4719" { + 4719 + } else if v == "4720" { + 4720 + } else if v == "4721" { + 4721 + } else if v == "4722" { + 4722 + } else if v == "4723" { + 4723 + } else if v == "4724" { + 4724 + } else if v == "4725" { + 4725 + } else if v == "4726" { + 4726 + } else if v == "4727" { + 4727 + } else if v == "4728" { + 4728 + } else if v == "4729" { + 4729 + } else if v == "4730" { + 4730 + } else if v == "4731" { + 4731 + } else if v == "4732" { + 4732 + } else if v == "4733" { + 4733 + } else if v == "4734" { + 4734 + } else if v == "4735" { + 4735 + } else if v == "4736" { + 4736 + } else if v == "4737" { + 4737 + } else if v == "4738" { + 4738 + } else if v == "4739" { + 4739 + } else if v == "4740" { + 4740 + } else if v == "4741" { + 4741 + } else if v == "4742" { + 4742 + } else if v == "4743" { + 4743 + } else if v == "4744" { + 4744 + } else if v == "4745" { + 4745 + } else if v == "4746" { + 4746 + } else if v == "4747" { + 4747 + } else if v == "4748" { + 4748 + } else if v == "4749" { + 4749 + } else if v == "4750" { + 4750 + } else if v == "4751" { + 4751 + } else if v == "4752" { + 4752 + } else if v == "4753" { + 4753 + } else if v == "4754" { + 4754 + } else if v == "4755" { + 4755 + } else if v == "4756" { + 4756 + } else if v == "4757" { + 4757 + } else if v == "4758" { + 4758 + } else if v == "4759" { + 4759 + } else if v == "4760" { + 4760 + } else if v == "4761" { + 4761 + } else if v == "4762" { + 4762 + } else if v == "4763" { + 4763 + } else if v == "4764" { + 4764 + } else if v == "4765" { + 4765 + } else if v == "4766" { + 4766 + } else if v == "4767" { + 4767 + } else if v == "4768" { + 4768 + } else if v == "4769" { + 4769 + } else if v == "4770" { + 4770 + } else if v == "4771" { + 4771 + } else if v == "4772" { + 4772 + } else if v == "4773" { + 4773 + } else if v == "4774" { + 4774 + } else if v == "4775" { + 4775 + } else if v == "4776" { + 4776 + } else if v == "4777" { + 4777 + } else if v == "4778" { + 4778 + } else if v == "4779" { + 4779 + } else if v == "4780" { + 4780 + } else if v == "4781" { + 4781 + } else if v == "4782" { + 4782 + } else if v == "4783" { + 4783 + } else if v == "4784" { + 4784 + } else if v == "4785" { + 4785 + } else if v == "4786" { + 4786 + } else if v == "4787" { + 4787 + } else if v == "4788" { + 4788 + } else if v == "4789" { + 4789 + } else if v == "4790" { + 4790 + } else if v == "4791" { + 4791 + } else if v == "4792" { + 4792 + } else if v == "4793" { + 4793 + } else if v == "4794" { + 4794 + } else if v == "4795" { + 4795 + } else if v == "4796" { + 4796 + } else if v == "4797" { + 4797 + } else if v == "4798" { + 4798 + } else if v == "4799" { + 4799 + } else if v == "4800" { + 4800 + } else if v == "4801" { + 4801 + } else if v == "4802" { + 4802 + } else if v == "4803" { + 4803 + } else if v == "4804" { + 4804 + } else if v == "4805" { + 4805 + } else if v == "4806" { + 4806 + } else if v == "4807" { + 4807 + } else if v == "4808" { + 4808 + } else if v == "4809" { + 4809 + } else if v == "4810" { + 4810 + } else if v == "4811" { + 4811 + } else if v == "4812" { + 4812 + } else if v == "4813" { + 4813 + } else if v == "4814" { + 4814 + } else if v == "4815" { + 4815 + } else if v == "4816" { + 4816 + } else if v == "4817" { + 4817 + } else if v == "4818" { + 4818 + } else if v == "4819" { + 4819 + } else if v == "4820" { + 4820 + } else if v == "4821" { + 4821 + } else if v == "4822" { + 4822 + } else if v == "4823" { + 4823 + } else if v == "4824" { + 4824 + } else if v == "4825" { + 4825 + } else if v == "4826" { + 4826 + } else if v == "4827" { + 4827 + } else if v == "4828" { + 4828 + } else if v == "4829" { + 4829 + } else if v == "4830" { + 4830 + } else if v == "4831" { + 4831 + } else if v == "4832" { + 4832 + } else if v == "4833" { + 4833 + } else if v == "4834" { + 4834 + } else if v == "4835" { + 4835 + } else if v == "4836" { + 4836 + } else if v == "4837" { + 4837 + } else if v == "4838" { + 4838 + } else if v == "4839" { + 4839 + } else if v == "4840" { + 4840 + } else if v == "4841" { + 4841 + } else if v == "4842" { + 4842 + } else if v == "4843" { + 4843 + } else if v == "4844" { + 4844 + } else if v == "4845" { + 4845 + } else if v == "4846" { + 4846 + } else if v == "4847" { + 4847 + } else if v == "4848" { + 4848 + } else if v == "4849" { + 4849 + } else if v == "4850" { + 4850 + } else if v == "4851" { + 4851 + } else if v == "4852" { + 4852 + } else if v == "4853" { + 4853 + } else if v == "4854" { + 4854 + } else if v == "4855" { + 4855 + } else if v == "4856" { + 4856 + } else if v == "4857" { + 4857 + } else if v == "4858" { + 4858 + } else if v == "4859" { + 4859 + } else if v == "4860" { + 4860 + } else if v == "4861" { + 4861 + } else if v == "4862" { + 4862 + } else if v == "4863" { + 4863 + } else if v == "4864" { + 4864 + } else if v == "4865" { + 4865 + } else if v == "4866" { + 4866 + } else if v == "4867" { + 4867 + } else if v == "4868" { + 4868 + } else if v == "4869" { + 4869 + } else if v == "4870" { + 4870 + } else if v == "4871" { + 4871 + } else if v == "4872" { + 4872 + } else if v == "4873" { + 4873 + } else if v == "4874" { + 4874 + } else if v == "4875" { + 4875 + } else if v == "4876" { + 4876 + } else if v == "4877" { + 4877 + } else if v == "4878" { + 4878 + } else if v == "4879" { + 4879 + } else if v == "4880" { + 4880 + } else if v == "4881" { + 4881 + } else if v == "4882" { + 4882 + } else if v == "4883" { + 4883 + } else if v == "4884" { + 4884 + } else if v == "4885" { + 4885 + } else if v == "4886" { + 4886 + } else if v == "4887" { + 4887 + } else if v == "4888" { + 4888 + } else if v == "4889" { + 4889 + } else if v == "4890" { + 4890 + } else if v == "4891" { + 4891 + } else if v == "4892" { + 4892 + } else if v == "4893" { + 4893 + } else if v == "4894" { + 4894 + } else if v == "4895" { + 4895 + } else if v == "4896" { + 4896 + } else if v == "4897" { + 4897 + } else if v == "4898" { + 4898 + } else if v == "4899" { + 4899 + } else if v == "4900" { + 4900 + } else if v == "4901" { + 4901 + } else if v == "4902" { + 4902 + } else if v == "4903" { + 4903 + } else if v == "4904" { + 4904 + } else if v == "4905" { + 4905 + } else if v == "4906" { + 4906 + } else if v == "4907" { + 4907 + } else if v == "4908" { + 4908 + } else if v == "4909" { + 4909 + } else if v == "4910" { + 4910 + } else if v == "4911" { + 4911 + } else if v == "4912" { + 4912 + } else if v == "4913" { + 4913 + } else if v == "4914" { + 4914 + } else if v == "4915" { + 4915 + } else if v == "4916" { + 4916 + } else if v == "4917" { + 4917 + } else if v == "4918" { + 4918 + } else if v == "4919" { + 4919 + } else if v == "4920" { + 4920 + } else if v == "4921" { + 4921 + } else if v == "4922" { + 4922 + } else if v == "4923" { + 4923 + } else if v == "4924" { + 4924 + } else if v == "4925" { + 4925 + } else if v == "4926" { + 4926 + } else if v == "4927" { + 4927 + } else if v == "4928" { + 4928 + } else if v == "4929" { + 4929 + } else if v == "4930" { + 4930 + } else if v == "4931" { + 4931 + } else if v == "4932" { + 4932 + } else if v == "4933" { + 4933 + } else if v == "4934" { + 4934 + } else if v == "4935" { + 4935 + } else if v == "4936" { + 4936 + } else if v == "4937" { + 4937 + } else if v == "4938" { + 4938 + } else if v == "4939" { + 4939 + } else if v == "4940" { + 4940 + } else if v == "4941" { + 4941 + } else if v == "4942" { + 4942 + } else if v == "4943" { + 4943 + } else if v == "4944" { + 4944 + } else if v == "4945" { + 4945 + } else if v == "4946" { + 4946 + } else if v == "4947" { + 4947 + } else if v == "4948" { + 4948 + } else if v == "4949" { + 4949 + } else if v == "4950" { + 4950 + } else if v == "4951" { + 4951 + } else if v == "4952" { + 4952 + } else if v == "4953" { + 4953 + } else if v == "4954" { + 4954 + } else if v == "4955" { + 4955 + } else if v == "4956" { + 4956 + } else if v == "4957" { + 4957 + } else if v == "4958" { + 4958 + } else if v == "4959" { + 4959 + } else if v == "4960" { + 4960 + } else if v == "4961" { + 4961 + } else if v == "4962" { + 4962 + } else if v == "4963" { + 4963 + } else if v == "4964" { + 4964 + } else if v == "4965" { + 4965 + } else if v == "4966" { + 4966 + } else if v == "4967" { + 4967 + } else if v == "4968" { + 4968 + } else if v == "4969" { + 4969 + } else if v == "4970" { + 4970 + } else if v == "4971" { + 4971 + } else if v == "4972" { + 4972 + } else if v == "4973" { + 4973 + } else if v == "4974" { + 4974 + } else if v == "4975" { + 4975 + } else if v == "4976" { + 4976 + } else if v == "4977" { + 4977 + } else if v == "4978" { + 4978 + } else if v == "4979" { + 4979 + } else if v == "4980" { + 4980 + } else if v == "4981" { + 4981 + } else if v == "4982" { + 4982 + } else if v == "4983" { + 4983 + } else if v == "4984" { + 4984 + } else if v == "4985" { + 4985 + } else if v == "4986" { + 4986 + } else if v == "4987" { + 4987 + } else if v == "4988" { + 4988 + } else if v == "4989" { + 4989 + } else if v == "4990" { + 4990 + } else if v == "4991" { + 4991 + } else if v == "4992" { + 4992 + } else if v == "4993" { + 4993 + } else if v == "4994" { + 4994 + } else if v == "4995" { + 4995 + } else if v == "4996" { + 4996 + } else if v == "4997" { + 4997 + } else if v == "4998" { + 4998 + } else if v == "4999" { + 4999 + } else if v == "5000" { + 5000 + } else if v == "5001" { + 5001 + } else if v == "5002" { + 5002 + } else if v == "5003" { + 5003 + } else if v == "5004" { + 5004 + } else if v == "5005" { + 5005 + } else if v == "5006" { + 5006 + } else if v == "5007" { + 5007 + } else if v == "5008" { + 5008 + } else if v == "5009" { + 5009 + } else if v == "5010" { + 5010 + } else if v == "5011" { + 5011 + } else if v == "5012" { + 5012 + } else if v == "5013" { + 5013 + } else if v == "5014" { + 5014 + } else if v == "5015" { + 5015 + } else if v == "5016" { + 5016 + } else if v == "5017" { + 5017 + } else if v == "5018" { + 5018 + } else if v == "5019" { + 5019 + } else if v == "5020" { + 5020 + } else if v == "5021" { + 5021 + } else if v == "5022" { + 5022 + } else if v == "5023" { + 5023 + } else if v == "5024" { + 5024 + } else if v == "5025" { + 5025 + } else if v == "5026" { + 5026 + } else if v == "5027" { + 5027 + } else if v == "5028" { + 5028 + } else if v == "5029" { + 5029 + } else if v == "5030" { + 5030 + } else if v == "5031" { + 5031 + } else if v == "5032" { + 5032 + } else if v == "5033" { + 5033 + } else if v == "5034" { + 5034 + } else if v == "5035" { + 5035 + } else if v == "5036" { + 5036 + } else if v == "5037" { + 5037 + } else if v == "5038" { + 5038 + } else if v == "5039" { + 5039 + } else if v == "5040" { + 5040 + } else if v == "5041" { + 5041 + } else if v == "5042" { + 5042 + } else if v == "5043" { + 5043 + } else if v == "5044" { + 5044 + } else if v == "5045" { + 5045 + } else if v == "5046" { + 5046 + } else if v == "5047" { + 5047 + } else if v == "5048" { + 5048 + } else if v == "5049" { + 5049 + } else if v == "5050" { + 5050 + } else if v == "5051" { + 5051 + } else if v == "5052" { + 5052 + } else if v == "5053" { + 5053 + } else if v == "5054" { + 5054 + } else if v == "5055" { + 5055 + } else if v == "5056" { + 5056 + } else if v == "5057" { + 5057 + } else if v == "5058" { + 5058 + } else if v == "5059" { + 5059 + } else if v == "5060" { + 5060 + } else if v == "5061" { + 5061 + } else if v == "5062" { + 5062 + } else if v == "5063" { + 5063 + } else if v == "5064" { + 5064 + } else if v == "5065" { + 5065 + } else if v == "5066" { + 5066 + } else if v == "5067" { + 5067 + } else if v == "5068" { + 5068 + } else if v == "5069" { + 5069 + } else if v == "5070" { + 5070 + } else if v == "5071" { + 5071 + } else if v == "5072" { + 5072 + } else if v == "5073" { + 5073 + } else if v == "5074" { + 5074 + } else if v == "5075" { + 5075 + } else if v == "5076" { + 5076 + } else if v == "5077" { + 5077 + } else if v == "5078" { + 5078 + } else if v == "5079" { + 5079 + } else if v == "5080" { + 5080 + } else if v == "5081" { + 5081 + } else if v == "5082" { + 5082 + } else if v == "5083" { + 5083 + } else if v == "5084" { + 5084 + } else if v == "5085" { + 5085 + } else if v == "5086" { + 5086 + } else if v == "5087" { + 5087 + } else if v == "5088" { + 5088 + } else if v == "5089" { + 5089 + } else if v == "5090" { + 5090 + } else if v == "5091" { + 5091 + } else if v == "5092" { + 5092 + } else if v == "5093" { + 5093 + } else if v == "5094" { + 5094 + } else if v == "5095" { + 5095 + } else if v == "5096" { + 5096 + } else if v == "5097" { + 5097 + } else if v == "5098" { + 5098 + } else if v == "5099" { + 5099 + } else if v == "5100" { + 5100 + } else if v == "5101" { + 5101 + } else if v == "5102" { + 5102 + } else if v == "5103" { + 5103 + } else if v == "5104" { + 5104 + } else if v == "5105" { + 5105 + } else if v == "5106" { + 5106 + } else if v == "5107" { + 5107 + } else if v == "5108" { + 5108 + } else if v == "5109" { + 5109 + } else if v == "5110" { + 5110 + } else if v == "5111" { + 5111 + } else if v == "5112" { + 5112 + } else if v == "5113" { + 5113 + } else if v == "5114" { + 5114 + } else if v == "5115" { + 5115 + } else if v == "5116" { + 5116 + } else if v == "5117" { + 5117 + } else if v == "5118" { + 5118 + } else if v == "5119" { + 5119 + } else if v == "5120" { + 5120 + } else if v == "5121" { + 5121 + } else if v == "5122" { + 5122 + } else if v == "5123" { + 5123 + } else if v == "5124" { + 5124 + } else if v == "5125" { + 5125 + } else if v == "5126" { + 5126 + } else if v == "5127" { + 5127 + } else if v == "5128" { + 5128 + } else if v == "5129" { + 5129 + } else if v == "5130" { + 5130 + } else if v == "5131" { + 5131 + } else if v == "5132" { + 5132 + } else if v == "5133" { + 5133 + } else if v == "5134" { + 5134 + } else if v == "5135" { + 5135 + } else if v == "5136" { + 5136 + } else if v == "5137" { + 5137 + } else if v == "5138" { + 5138 + } else if v == "5139" { + 5139 + } else if v == "5140" { + 5140 + } else if v == "5141" { + 5141 + } else if v == "5142" { + 5142 + } else if v == "5143" { + 5143 + } else if v == "5144" { + 5144 + } else if v == "5145" { + 5145 + } else if v == "5146" { + 5146 + } else if v == "5147" { + 5147 + } else if v == "5148" { + 5148 + } else if v == "5149" { + 5149 + } else if v == "5150" { + 5150 + } else if v == "5151" { + 5151 + } else if v == "5152" { + 5152 + } else if v == "5153" { + 5153 + } else if v == "5154" { + 5154 + } else if v == "5155" { + 5155 + } else if v == "5156" { + 5156 + } else if v == "5157" { + 5157 + } else if v == "5158" { + 5158 + } else if v == "5159" { + 5159 + } else if v == "5160" { + 5160 + } else if v == "5161" { + 5161 + } else if v == "5162" { + 5162 + } else if v == "5163" { + 5163 + } else if v == "5164" { + 5164 + } else if v == "5165" { + 5165 + } else if v == "5166" { + 5166 + } else if v == "5167" { + 5167 + } else if v == "5168" { + 5168 + } else if v == "5169" { + 5169 + } else if v == "5170" { + 5170 + } else if v == "5171" { + 5171 + } else if v == "5172" { + 5172 + } else if v == "5173" { + 5173 + } else if v == "5174" { + 5174 + } else if v == "5175" { + 5175 + } else if v == "5176" { + 5176 + } else if v == "5177" { + 5177 + } else if v == "5178" { + 5178 + } else if v == "5179" { + 5179 + } else if v == "5180" { + 5180 + } else if v == "5181" { + 5181 + } else if v == "5182" { + 5182 + } else if v == "5183" { + 5183 + } else if v == "5184" { + 5184 + } else if v == "5185" { + 5185 + } else if v == "5186" { + 5186 + } else if v == "5187" { + 5187 + } else if v == "5188" { + 5188 + } else if v == "5189" { + 5189 + } else if v == "5190" { + 5190 + } else if v == "5191" { + 5191 + } else if v == "5192" { + 5192 + } else if v == "5193" { + 5193 + } else if v == "5194" { + 5194 + } else if v == "5195" { + 5195 + } else if v == "5196" { + 5196 + } else if v == "5197" { + 5197 + } else if v == "5198" { + 5198 + } else if v == "5199" { + 5199 + } else if v == "5200" { + 5200 + } else if v == "5201" { + 5201 + } else if v == "5202" { + 5202 + } else if v == "5203" { + 5203 + } else if v == "5204" { + 5204 + } else if v == "5205" { + 5205 + } else { + 5206 + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-74614.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-74614.rs new file mode 100644 index 000000000000..f0204f57c8a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-74614.rs @@ -0,0 +1,19 @@ +// compile-flags:-Zpolymorphize=on +// build-pass + +fn test() { + std::mem::size_of::(); +} + +pub fn foo(_: T) -> &'static fn() { + &(test:: as fn()) +} + +fn outer() { + foo(|| ()); +} + +fn main() { + outer::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-74739.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-74739.rs new file mode 100644 index 000000000000..e2984d364d72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-74739.rs @@ -0,0 +1,15 @@ +// compile-flags: -O +// run-pass + +struct Foo { + x: i32, +} + +pub fn main() { + let mut foo = Foo { x: 42 }; + let x = &mut foo.x; + *x = 13; + let y = foo; + assert_eq!(y.x, 13); // used to print 42 due to mir-opt bug +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7519-match-unit-in-arg.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7519-match-unit-in-arg.rs new file mode 100644 index 000000000000..c73d0a4f2afb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7519-match-unit-in-arg.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +/* +#7519 ICE pattern matching unit in function argument +*/ + +fn foo(():()) { } + +pub fn main() { + foo(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-75283.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-75283.rs new file mode 100644 index 000000000000..2780346173ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-75283.rs @@ -0,0 +1,7 @@ +extern "C" { + fn lol() { // { dg-error "" "" { target *-*-* } } + println!(""); + } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-75307.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-75307.rs new file mode 100644 index 000000000000..61302f4c3612 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-75307.rs @@ -0,0 +1,4 @@ +fn main() { + format!(r"{}{}{}", named_arg=1); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-75599.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-75599.rs new file mode 100644 index 000000000000..66f502fe8c26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-75599.rs @@ -0,0 +1,25 @@ +// check-pass +#![allow(non_upper_case_globals)] + +const or: usize = 1; +const and: usize = 2; + +mod or { + pub const X: usize = 3; +} + +mod and { + pub const X: usize = 4; +} + +fn main() { + match 0 { + 0 => {} + or => {} + and => {} + or::X => {} + and::X => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7563.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7563.rs new file mode 100644 index 000000000000..945ca95ad2e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7563.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] +trait IDummy { + fn do_nothing(&self); +} + +#[derive(Debug)] +struct A { a: isize } +#[derive(Debug)] +struct B<'a> { b: isize, pa: &'a A } + + impl IDummy for A { + fn do_nothing(&self) { + println!("A::do_nothing() is called"); + } + } + +impl<'a> B<'a> { + fn get_pa(&self) -> &'a dyn IDummy { self.pa as &'a dyn IDummy } +} + +pub fn main() { + let sa = A { a: 100 }; + let sb = B { b: 200, pa: &sa }; + + println!("sa is {:?}", sa); + println!("sb is {:?}", sb); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-75704.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-75704.rs new file mode 100644 index 000000000000..08120e5fb304 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-75704.rs @@ -0,0 +1,8 @@ +// Caused an infinite loop during SimlifyCfg MIR transform previously. +// +// build-pass + +fn main() { + loop { continue; } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7575.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7575.rs new file mode 100644 index 000000000000..f438e37bd133 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7575.rs @@ -0,0 +1,18 @@ +// run-pass + +trait Foo { + fn new() -> bool { false } + fn dummy(&self) { } +} + +trait Bar { + fn new(&self) -> bool { true } +} + +impl Bar for isize {} +impl Foo for isize {} + +fn main() { + assert!(1.new()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-75763.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-75763.rs new file mode 100644 index 000000000000..cb25ea02e624 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-75763.rs @@ -0,0 +1,16 @@ +// build-pass + +#![allow(incomplete_features)] +#![feature(const_generics)] + +struct Bug; + +fn main() { + let b: Bug::<{ + unsafe { + // FIXME(const_generics): Decide on how to deal with invalid values as const params. + std::mem::transmute::<&[u8], &str>(&[0xC0, 0xC1, 0xF5]) + } + }>; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-75777.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-75777.rs new file mode 100644 index 000000000000..3502524df439 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-75777.rs @@ -0,0 +1,18 @@ +// Regression test for #75777. +// Checks that a boxed future can be properly constructed. + +#![feature(future_readiness_fns)] + +use std::future::{self, Future}; +use std::pin::Pin; + +type BoxFuture<'a, T> = Pin + 'a + Send>>; + +fn inject<'a, Env: 'a, A: 'a + Send>(v: A) -> Box BoxFuture<'a, A>> { + let fut: BoxFuture<'a, A> = Box::pin(future::ready(v)); + Box::new(move |_| fut) +// { dg-error ".E0495." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-75906.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-75906.rs new file mode 100644 index 000000000000..224938c6a15c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-75906.rs @@ -0,0 +1,14 @@ +mod m { + pub struct Foo { x: u8 } + + pub struct Bar(u8); +} + +use m::{Foo, Bar}; + +fn main() { + let x = Foo { x: 12 }; + let y = Bar(12); +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-75907.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-75907.rs new file mode 100644 index 000000000000..52263b2cf244 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-75907.rs @@ -0,0 +1,19 @@ +// Test for for diagnostic improvement issue #75907 + +mod foo { + pub(crate) struct Foo(u8); + pub(crate) struct Bar(pub u8, u8, Foo); + + pub(crate) fn make_bar() -> Bar { + Bar(1, 12, Foo(10)) + } +} + +use foo::{make_bar, Bar, Foo}; + +fn main() { + let Bar(x, y, Foo(z)) = make_bar(); +// { dg-error ".E0532." "" { target *-*-* } .-1 } +// { dg-error ".E0532." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-75907_b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-75907_b.rs new file mode 100644 index 000000000000..114088f975ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-75907_b.rs @@ -0,0 +1,12 @@ +// Test for for diagnostic improvement issue #75907, extern crate +// aux-build:issue-75907.rs + +extern crate issue_75907 as a; + +use a::{make_bar, Bar}; + +fn main() { + let Bar(x, y, z) = make_bar(); +// { dg-error ".E0532." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7607-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7607-1.rs new file mode 100644 index 000000000000..c901f3cba938 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7607-1.rs @@ -0,0 +1,10 @@ +struct Foo { + x: isize +} + +impl Fo { // { dg-error ".E0412." "" { target *-*-* } } + fn foo() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7607-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7607-2.rs new file mode 100644 index 000000000000..2ceb000288c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7607-2.rs @@ -0,0 +1,17 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +pub mod a { + pub struct Foo { a: usize } +} + +pub mod b { + use a::Foo; + impl Foo { + fn bar(&self) { } + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-76077-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-76077-1.rs new file mode 100644 index 000000000000..ed47f8185206 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-76077-1.rs @@ -0,0 +1,19 @@ +// run-rustfix +#![allow(dead_code, unused_variables)] + +pub mod foo { + #[derive(Default)] + pub struct Foo { invisible: bool, } + + #[derive(Default)] + pub struct Bar { pub visible: bool, invisible: bool, } +} + +fn main() { + let foo::Foo {} = foo::Foo::default(); +// { dg-error "" "" { target *-*-* } .-1 } + + let foo::Bar { visible } = foo::Bar::default(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-76077.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-76077.rs new file mode 100644 index 000000000000..081090ffc244 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-76077.rs @@ -0,0 +1,11 @@ +pub mod foo { + pub struct Foo { + you_cant_use_this_field: bool, + } +} + +fn main() { + foo::Foo {}; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-76179.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-76179.rs new file mode 100644 index 000000000000..33c8be1968c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-76179.rs @@ -0,0 +1,20 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-76191.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-76191.rs new file mode 100644 index 000000000000..24f64baf334b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-76191.rs @@ -0,0 +1,20 @@ +// Regression test for diagnostic issue #76191 +#![allow(non_snake_case)] + +use std::ops::RangeInclusive; + +const RANGE: RangeInclusive = 0..=255; + +const RANGE2: RangeInclusive = panic!(); + +fn main() { + let n: i32 = 1; + match n { + RANGE => {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } + RANGE2 => {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-76547.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-76547.rs new file mode 100644 index 000000000000..b6467b447806 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-76547.rs @@ -0,0 +1,39 @@ +// Test for diagnostic improvement issue #76547 +// edition:2018 + +use std::{ + future::Future, + task::{Context, Poll} +}; +use std::pin::Pin; + +pub struct ListFut<'a>(&'a mut [&'a mut [u8]]); +impl<'a> Future for ListFut<'a> { + type Output = (); + + fn poll(self: Pin<&mut Self>, _cx: &mut Context) -> Poll { + unimplemented!() + } +} + +async fn fut(bufs: &mut [&mut [u8]]) { + ListFut(bufs).await +// { dg-error ".E0623." "" { target *-*-* } .-1 } +} + +pub struct ListFut2<'a>(&'a mut [&'a mut [u8]]); +impl<'a> Future for ListFut2<'a> { + type Output = i32; + + fn poll(self: Pin<&mut Self>, _cx: &mut Context) -> Poll { + unimplemented!() + } +} + +async fn fut2(bufs: &mut [&mut [u8]]) -> i32 { + ListFut2(bufs).await +// { dg-error ".E0623." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7660.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7660.rs new file mode 100644 index 000000000000..01b12f5ab669 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7660.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_variables)] +// Regression test for issue 7660 +// rvalue lifetime too short when equivalent `match` works + +// pretty-expanded FIXME #23616 + +use std::collections::HashMap; + +struct A(isize, isize); + +pub fn main() { + let mut m: HashMap = HashMap::new(); + m.insert(1, A(0, 0)); + + let A(ref _a, ref _b) = m[&1]; + let (a, b) = match m[&1] { A(ref _a, ref _b) => (_a, _b) }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7663.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7663.rs new file mode 100644 index 000000000000..ebb457d3f851 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7663.rs @@ -0,0 +1,33 @@ +// run-pass + +#![allow(unused_imports, dead_code)] + +mod test1 { + + mod foo { pub fn p() -> isize { 1 } } + mod bar { pub fn p() -> isize { 2 } } + + pub mod baz { + use test1::bar::p; + + pub fn my_main() { assert_eq!(p(), 2); } + } +} + +mod test2 { + + mod foo { pub fn p() -> isize { 1 } } + mod bar { pub fn p() -> isize { 2 } } + + pub mod baz { + use test2::bar::p; + + pub fn my_main() { assert_eq!(p(), 2); } + } +} + +fn main() { + test1::baz::my_main(); + test2::baz::my_main(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7673-cast-generically-implemented-trait.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7673-cast-generically-implemented-trait.rs new file mode 100644 index 000000000000..f507ec55fa03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7673-cast-generically-implemented-trait.rs @@ -0,0 +1,23 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +/* + +#7673 Polymorphically creating traits barely works + +*/ + +#![feature(box_syntax)] + +pub fn main() {} + +trait A { + fn dummy(&self) { } +} + +impl A for T {} + +fn owned2(a: Box) { a as Box; } +fn owned3(a: Box) { box a as Box; } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-77002.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-77002.rs new file mode 100644 index 000000000000..360ffb008ad7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-77002.rs @@ -0,0 +1,17 @@ +// compile-flags: -Zmir-opt-level=2 -Copt-level=0 +// run-pass + +type M = [i64; 2]; + +fn f(a: &M) -> M { + let mut b: M = M::default(); + b[0] = a[0] * a[0]; + b +} + +fn main() { + let mut a: M = [1, 1]; + a = f(&a); + assert_eq!(a[0], 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-77218.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-77218.rs new file mode 100644 index 000000000000..5a81d7a13522 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-77218.rs @@ -0,0 +1,12 @@ +fn main() { + let value = [7u8]; + while Some(0) = value.get(0) { // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0070." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + // FIXME The following diagnostic should also be emitted + // HELP you might have meant to use pattern matching + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7784.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7784.rs new file mode 100644 index 000000000000..067d58400f97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7784.rs @@ -0,0 +1,31 @@ +// run-pass + +use std::ops::Add; + +fn foo + Clone>([x, y, z]: [T; 3]) -> (T, T, T) { + (x.clone(), x.clone() + y.clone(), x + y + z) +} +fn bar(a: &'static str, b: &'static str) -> [&'static str; 4] { + [a, b, b, a] +} + +fn main() { + assert_eq!(foo([1, 2, 3]), (1, 3, 6)); + + let [a, b, c, d] = bar("foo", "bar"); + assert_eq!(a, "foo"); + assert_eq!(b, "bar"); + assert_eq!(c, "bar"); + assert_eq!(d, "foo"); + + let [a, _, _, d] = bar("baz", "foo"); + assert_eq!(a, "baz"); + assert_eq!(d, "baz"); + + let out = bar("baz", "foo"); + let [a, xs @ .., d] = out; + assert_eq!(a, "baz"); + assert_eq!(xs, ["foo", "foo"]); + assert_eq!(d, "baz"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-77919.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-77919.rs new file mode 100644 index 000000000000..efb6170a9221 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-77919.rs @@ -0,0 +1,14 @@ +fn main() { + [1; >::VAL]; // { dg-error ".E0080." "" { target *-*-* } } +} +trait TypeVal { + const VAL: T; // { dg-error "" "" { target *-*-* } } +} +struct Five; +struct Multiply { + _n: PhantomData, // { dg-error ".E0412." "" { target *-*-* } } +} +impl TypeVal for Multiply where N: TypeVal {} +// { dg-error ".E0046." "" { target *-*-* } .-1 } +// { dg-error ".E0046." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-77993-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-77993-1.rs new file mode 100644 index 000000000000..9a75e38b46fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-77993-1.rs @@ -0,0 +1,13 @@ +#[derive(Clone)] +struct InGroup { + it: It, +// { dg-error ".E0412." "" { target *-*-* } .-1 } + f: F, +} +fn dates_in_year() -> impl Clone { + InGroup { f: |d| d } +// { dg-error ".E0063." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-77993-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-77993-2.rs new file mode 100644 index 000000000000..c7d1928883b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-77993-2.rs @@ -0,0 +1,10 @@ +// edition:2018 + +async fn test() -> Result<(), Box> { + macro!(); +// { dg-error "" "" { target *-*-* } .-1 } + Ok(()) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-78115.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-78115.rs new file mode 100644 index 000000000000..0601433ae2af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-78115.rs @@ -0,0 +1,20 @@ +// Regression test for issue #78115: "ICE: variable should be placed in scope earlier" + +// check-pass +// edition:2018 + +#[allow(dead_code)] +struct Foo { + a: () +} + +async fn _bar() { + let foo = Foo { a: () }; + match foo { + Foo { a: _a } | Foo { a: _a } if true => {} + _ => {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7813.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7813.rs new file mode 100644 index 000000000000..cca153e31293 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7813.rs @@ -0,0 +1,5 @@ +fn main() { + let v = &[]; // { dg-error ".E0282." "" { target *-*-* } } + let it = v.iter(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-78192.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-78192.rs new file mode 100644 index 000000000000..d1028bf459ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-78192.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(unused_assignments)] + +fn main() { + let a = 1u32; + let b = 2u32; + + let mut c: *const u32 = &a; + let d: &u32 = &b; + + let x = unsafe { &*c }; + c = d; + let z = *x; + + assert_eq!(1, z); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-78372.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-78372.rs new file mode 100644 index 000000000000..dcf252653e77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-78372.rs @@ -0,0 +1,15 @@ +use std::ops::DispatchFromDyn; // { dg-error ".E0658." "" { target *-*-* } } +struct Smaht(PhantomData); // { dg-error ".E0412." "" { target *-*-* } } +impl DispatchFromDyn> for T {} // { dg-error ".E0210." "" { target *-*-* } } +// { dg-error ".E0210." "" { target *-*-* } .-1 } +// { dg-error ".E0210." "" { target *-*-* } .-2 } +// { dg-error ".E0210." "" { target *-*-* } .-3 } +// { dg-error ".E0210." "" { target *-*-* } .-4 } +trait Foo: X {} +trait X { + fn foo(self: Smaht); +} +trait Marker {} +impl Marker for dyn Foo {} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-78622.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-78622.rs new file mode 100644 index 000000000000..a7d86d1f5991 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-78622.rs @@ -0,0 +1,8 @@ +#![crate_type = "lib"] + +struct S; +fn f() { + S::A:: {} +// { dg-error ".E0223." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7867.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7867.rs new file mode 100644 index 000000000000..6e02ed22d546 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7867.rs @@ -0,0 +1,15 @@ +enum A { B, C } + +mod foo { pub fn bar() {} } + +fn main() { + match (true, false) { + A::B => (), +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + _ => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7899.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7899.rs new file mode 100644 index 000000000000..e4c9a8fa568c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7899.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(unused_variables)] +// aux-build:issue-7899.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_7899 as testcrate; + +fn main() { + let f = testcrate::V2(1.0f32, 2.0f32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7911.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7911.rs new file mode 100644 index 000000000000..e6f350d33846 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7911.rs @@ -0,0 +1,38 @@ +// run-pass +// (Closes #7911) Test that we can use the same self expression +// with different mutability in macro in two methods + +#![allow(unused_variables)] // unused foobar_immut + foobar_mut +trait FooBar { + fn dummy(&self) { } +} +struct Bar(i32); +struct Foo { bar: Bar } + +impl FooBar for Bar {} + +trait Test { + fn get_immut(&self) -> &dyn FooBar; + fn get_mut(&mut self) -> &mut dyn FooBar; +} + +macro_rules! generate_test { ($type_:path, $slf:ident, $field:expr) => ( + impl Test for $type_ { + fn get_immut(&$slf) -> &dyn FooBar { + &$field as &dyn FooBar + } + + fn get_mut(&mut $slf) -> &mut dyn FooBar { + &mut $field as &mut dyn FooBar + } + } +)} + +generate_test!(Foo, self, self.bar); + +pub fn main() { + let mut foo: Foo = Foo { bar: Bar(42) }; + { let foobar_immut = foo.get_immut(); } + { let foobar_mut = foo.get_mut(); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7950.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7950.rs new file mode 100644 index 000000000000..ac59718cd053 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7950.rs @@ -0,0 +1,9 @@ +// tests the good error message, not "missing module Foo" or something else unexpected + +struct Foo; + +fn main() { + Foo::bar(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7970a.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7970a.rs new file mode 100644 index 000000000000..ee56e00cc282 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7970a.rs @@ -0,0 +1,9 @@ +macro_rules! one_arg_macro { + ($fmt:expr) => (print!(concat!($fmt, "\n"))); +} + +fn main() { + one_arg_macro!(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-7970b.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-7970b.rs new file mode 100644 index 000000000000..72b06fcf0b93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-7970b.rs @@ -0,0 +1,5 @@ +fn main() {} + +macro_rules! test {} +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8044.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8044.rs new file mode 100644 index 000000000000..a4c3e86f8c95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8044.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-8044.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_8044 as minimal; +use minimal::{BTree, leaf}; + +pub fn main() { + BTree:: { node: leaf(1) }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-811.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-811.rs new file mode 100644 index 000000000000..7e6ed8ae66fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-811.rs @@ -0,0 +1,27 @@ +// run-fail +// error-pattern:quux +// ignore-emscripten no processes + +use std::marker::PhantomData; + +fn test00_start(ch: Chan, message: isize) { + send(ch, message); +} + +type TaskId = isize; +type PortId = isize; + +struct Chan { + task: TaskId, + port: PortId, + marker: PhantomData<*mut T>, +} + +fn send(_ch: Chan, _data: T) { + panic!(); +} + +fn main() { + panic!("quux"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8153.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8153.rs new file mode 100644 index 000000000000..3cac82740220 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8153.rs @@ -0,0 +1,17 @@ +// Test that duplicate methods in impls are not allowed + +struct Foo; + +trait Bar { + fn bar(&self) -> isize; +} + +impl Bar for Foo { + fn bar(&self) -> isize {1} + fn bar(&self) -> isize {2} // { dg-error ".E0201." "" { target *-*-* } } +} + +fn main() { + println!("{}", Foo.bar()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs new file mode 100644 index 000000000000..1baefa8e77db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs @@ -0,0 +1,20 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +/* + +#8171 Self is not recognised as implementing kinds in default method implementations + +*/ + +fn require_send(_: T){} + +trait TragicallySelfIsNotSend: Send + Sized { + fn x(self) { + require_send(self); + } +} + +pub fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8208.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8208.rs new file mode 100644 index 000000000000..e2ce6287cab1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8208.rs @@ -0,0 +1,18 @@ +use self::*; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +mod foo { + use foo::*; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-1 } + + mod bar { + use super::bar::*; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +// { dg-error ".E0432." "" { target *-*-* } .-2 } + } + +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8248.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8248.rs new file mode 100644 index 000000000000..7ee728e29750 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8248.rs @@ -0,0 +1,16 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait A { + fn dummy(&self) { } +} +struct B; +impl A for B {} + +fn foo(_: &mut dyn A) {} + +pub fn main() { + let mut b = B; + foo(&mut b as &mut dyn A); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8249.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8249.rs new file mode 100644 index 000000000000..26a6e929b270 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8249.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait A { + fn dummy(&self) { } +} +struct B; +impl A for B {} + +struct C<'a> { + foo: &'a mut (dyn A+'a), +} + +fn foo(a: &mut dyn A) { + C{ foo: a }; +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8259.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8259.rs new file mode 100644 index 000000000000..0c004603f480 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8259.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +// aux-build:issue-8259.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_8259 as other; +static a: other::Foo<'static> = other::Foo::A; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8351-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8351-1.rs new file mode 100644 index 000000000000..aa771dd8068f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8351-1.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] + +enum E { + Foo{f: isize}, + Bar, +} + +pub fn main() { + let e = E::Foo{f: 0}; + match e { + E::Foo{f: 1} => panic!(), + E::Foo{..} => (), + _ => panic!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8351-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8351-2.rs new file mode 100644 index 000000000000..d7c3cf90d6cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8351-2.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] + +enum E { + Foo{f: isize, b: bool}, + Bar, +} + +pub fn main() { + let e = E::Foo{f: 0, b: false}; + match e { + E::Foo{f: 1, b: true} => panic!(), + E::Foo{b: false, f: 0} => (), + _ => panic!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8391.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8391.rs new file mode 100644 index 000000000000..034e45a2e4e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8391.rs @@ -0,0 +1,10 @@ +// run-pass + +fn main() { + let x = match Some(1) { + ref _y @ Some(_) => 1, + None => 2, + }; + assert_eq!(x, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8398.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8398.rs new file mode 100644 index 000000000000..1f69e319b166 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8398.rs @@ -0,0 +1,14 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +pub trait Writer { + fn write(&mut self, b: &[u8]) -> Result<(), ()>; +} + +fn foo(a: &mut dyn Writer) { + a.write(&[]).unwrap(); +} + +pub fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8401.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8401.rs new file mode 100644 index 000000000000..cdac4d231d79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8401.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:issue-8401.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_8401; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8460-const.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8460-const.rs new file mode 100644 index 000000000000..d666ec79771d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8460-const.rs @@ -0,0 +1,63 @@ +// revisions: noopt opt opt_with_overflow_checks +//[noopt]compile-flags: -C opt-level=0 +//[opt]compile-flags: -O +//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O + +// build-fail + +#![deny(const_err)] + +use std::{isize, i8, i16, i32, i64, i128}; +use std::thread; + +fn main() { + assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { i128::MIN / -1; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { 1i128 / 0; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { i128::MIN % -1; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } + assert!(thread::spawn(move|| { 1i128 % 0; }).join().is_err()); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8460.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8460.rs new file mode 100644 index 000000000000..843e0116b66b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8460.rs @@ -0,0 +1,52 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support +#![feature(rustc_attrs)] + +use std::thread; + +trait Int { + fn zero() -> Self; + fn one() -> Self; +} +macro_rules! doit { + ($($t:ident)*) => ($(impl Int for $t { + fn zero() -> Self { 0 } + fn one() -> Self { 1 } + })*) +} +doit! { i8 i16 i32 i64 isize } + +macro_rules! check { + ($($e:expr),*) => { + $(assert!(thread::spawn({ + move|| { $e; } + }).join().is_err());)* + } +} + +fn main() { + check![ + isize::MIN / -isize::one(), + i8::MIN / -i8::one(), + i16::MIN / -i16::one(), + i32::MIN / -i32::one(), + i64::MIN / -i64::one(), + 1isize / isize::zero(), + 1i8 / i8::zero(), + 1i16 / i16::zero(), + 1i32 / i32::zero(), + 1i64 / i64::zero(), + isize::MIN % -isize::one(), + i8::MIN % -i8::one(), + i16::MIN % -i16::one(), + i32::MIN % -i32::one(), + i64::MIN % -i64::one(), + 1isize % isize::zero(), + 1i8 % i8::zero(), + 1i16 % i16::zero(), + 1i32 % i32::zero(), + 1i64 % i64::zero() + ]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8498.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8498.rs new file mode 100644 index 000000000000..69271a1b6aae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8498.rs @@ -0,0 +1,28 @@ +// run-pass + +pub fn main() { + match &[(Box::new(5),Box::new(7))] { + ps => { + let (ref y, _) = ps[0]; + assert_eq!(**y, 5); + } + } + + match Some(&[(Box::new(5),)]) { + Some(ps) => { + let (ref y,) = ps[0]; + assert_eq!(**y, 5); + } + None => () + } + + match Some(&[(Box::new(5),Box::new(7))]) { + Some(ps) => { + let (ref y, ref z) = ps[0]; + assert_eq!(**y, 5); + assert_eq!(**z, 7); + } + None => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8506.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8506.rs new file mode 100644 index 000000000000..2683466b92ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8506.rs @@ -0,0 +1,15 @@ +// run-pass +// pretty-expanded FIXME #23616 +#![allow(non_upper_case_globals)] + +#![allow(dead_code)] + +enum Either { + One, + Other(String,String) +} + +static one : Either = Either::One; + +pub fn main () { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8521.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8521.rs new file mode 100644 index 000000000000..c7a3e99ec194 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8521.rs @@ -0,0 +1,26 @@ +// check-pass +trait Foo1 {} + +trait A {} + +macro_rules! foo1(($t:path) => { + impl Foo1 for T {} +}); + +foo1!(A); + +trait Foo2 {} + +trait B {} + +#[allow(unused)] +struct C {} + +macro_rules! foo2(($t:path) => { + impl Foo2 for T {} +}); + +foo2!(B); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8578.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8578.rs new file mode 100644 index 000000000000..bcec97674e04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8578.rs @@ -0,0 +1,21 @@ +// check-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] +// pretty-expanded FIXME #23616 + +pub struct UninterpretedOption_NamePart { + name_part: Option, +} + +impl<'a> UninterpretedOption_NamePart { + pub fn default_instance() -> &'static UninterpretedOption_NamePart { + static instance: UninterpretedOption_NamePart = UninterpretedOption_NamePart { + name_part: None, + }; + &instance + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8640.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8640.rs new file mode 100644 index 000000000000..d3bffe67ca7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8640.rs @@ -0,0 +1,11 @@ +#[allow(unused_imports)] + +mod foo { + use baz::bar; + mod bar {} +// { dg-error ".E0255." "" { target *-*-* } .-1 } +} +mod baz { pub mod bar {} } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-868.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-868.rs new file mode 100644 index 000000000000..58b115de4645 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-868.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_parens)] +// pretty-expanded FIXME #23616 + +fn f(g: F) -> T where F: FnOnce() -> T { g() } + +pub fn main() { + let _x = f( | | { 10 }); + // used to be: cannot determine a type for this expression + f(| | { }); + // ditto + f( | | { ()}); + // always worked + let _: () = f(| | { }); + // empty block with no type info should compile too + let _ = f(||{}); + let _ = (||{}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8709.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8709.rs new file mode 100644 index 000000000000..07078ba0b307 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8709.rs @@ -0,0 +1,15 @@ +// run-pass + +macro_rules! sty { + ($t:ty) => (stringify!($t)) +} + +macro_rules! spath { + ($t:path) => (stringify!($t)) +} + +fn main() { + assert_eq!(sty!(isize), "isize"); + assert_eq!(spath!(std::option), "std::option"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8727.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8727.rs new file mode 100644 index 000000000000..5740bd179098 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8727.rs @@ -0,0 +1,17 @@ +// Verify the compiler fails with an error on infinite function +// recursions. + +// build-fail +// normalize-stderr-test: ".nll/" -> "/" + +fn generic() { // { dg-warning "" "" { target *-*-* } } + generic::>(); +} +// { dg-error "" "" { target *-*-* } .-2 } + + +fn main () { + // Use generic at least once to trigger instantiation. + generic::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8761.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8761.rs new file mode 100644 index 000000000000..f5098099bf55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8761.rs @@ -0,0 +1,11 @@ +enum Foo { + A = 1i64, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + B = 2u8 +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8767.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8767.rs new file mode 100644 index 000000000000..0e94f05ad638 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8767.rs @@ -0,0 +1,6 @@ +impl B { // { dg-error ".E0412." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8783.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8783.rs new file mode 100644 index 000000000000..5f08d513ff27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8783.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +use std::default::Default; + +struct X { pub x: usize } +impl Default for X { + fn default() -> X { + X { x: 42 } + } +} + +struct Y { pub y: T } +impl Default for Y { + fn default() -> Y { + Y { y: Default::default() } + } +} + +fn main() { + let X { x: _ } = Default::default(); + let Y { y: X { x } } = Default::default(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8827.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8827.rs new file mode 100644 index 000000000000..75ed2e420665 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8827.rs @@ -0,0 +1,54 @@ +// run-pass +// ignore-emscripten no threads support + +use std::thread; +use std::sync::mpsc::{channel, Receiver}; + +fn periodical(n: isize) -> Receiver { + let (chan, port) = channel(); + thread::spawn(move|| { + loop { + for _ in 1..n { + match chan.send(false) { + Ok(()) => {} + Err(..) => break, + } + } + match chan.send(true) { + Ok(()) => {} + Err(..) => break + } + } + }); + return port; +} + +fn integers() -> Receiver { + let (chan, port) = channel(); + thread::spawn(move|| { + let mut i = 1; + loop { + match chan.send(i) { + Ok(()) => {} + Err(..) => break, + } + i = i + 1; + } + }); + return port; +} + +fn main() { + let ints = integers(); + let threes = periodical(3); + let fives = periodical(5); + for _ in 1..100 { + match (ints.recv().unwrap(), threes.recv().unwrap(), fives.recv().unwrap()) { + (_, true, true) => println!("FizzBuzz"), + (_, true, false) => println!("Fizz"), + (_, false, true) => println!("Buzz"), + (i, false, false) => println!("{}", i) + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8851.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8851.rs new file mode 100644 index 000000000000..81adda99f283 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8851.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(dead_code)] +// after fixing #9384 and implementing hygiene for match bindings, +// this now fails because the insertion of the 'y' into the match +// doesn't cause capture. Making this macro hygienic (as I've done) +// could very well make this test case completely pointless.... + +// pretty-expanded FIXME #23616 + +enum T { + A(isize), + B(usize) +} + +macro_rules! test { + ($id:ident, $e:expr) => ( + fn foo(t: T) -> isize { + match t { + T::A($id) => $e, + T::B($id) => $e + } + } + ) +} + +test!(y, 10 + (y as isize)); + +pub fn main() { + foo(T::A(20)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8860.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8860.rs new file mode 100644 index 000000000000..654101fd5f27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8860.rs @@ -0,0 +1,50 @@ +// run-pass +#![allow(dead_code)] + +static mut DROP: isize = 0; +static mut DROP_S: isize = 0; +static mut DROP_T: isize = 0; + +struct S; +impl Drop for S { + fn drop(&mut self) { + unsafe { + DROP_S += 1; + DROP += 1; + } + } +} +fn f(ref _s: S) {} + +struct T { i: isize } +impl Drop for T { + fn drop(&mut self) { + unsafe { + DROP_T += 1; + DROP += 1; + } + } +} +fn g(ref _t: T) {} + +fn do_test() { + let s = S; + f(s); + unsafe { + assert_eq!(1, DROP); + assert_eq!(1, DROP_S); + } + let t = T { i: 1 }; + g(t); + unsafe { assert_eq!(1, DROP_T); } +} + +fn main() { + do_test(); + unsafe { + assert_eq!(2, DROP); + assert_eq!(1, DROP_S); + assert_eq!(1, DROP_T); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-8898.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-8898.rs new file mode 100644 index 000000000000..c8626975ddc9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-8898.rs @@ -0,0 +1,19 @@ +// run-pass + +fn assert_repr_eq(obj : T, expected : String) { + assert_eq!(expected, format!("{:?}", obj)); +} + +pub fn main() { + let abc = [1, 2, 3]; + let tf = [true, false]; + let x = [(), ()]; + let slice = &x[..1]; + + assert_repr_eq(&abc[..], "[1, 2, 3]".to_string()); + assert_repr_eq(&tf[..], "[true, false]".to_string()); + assert_repr_eq(&x[..], "[(), ()]".to_string()); + assert_repr_eq(slice, "[()]".to_string()); + assert_repr_eq(&x[..], "[(), ()]".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9047.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9047.rs new file mode 100644 index 000000000000..b82c84f4be33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9047.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(unused_mut)] +#![allow(unused_variables)] +fn decode() -> String { + 'outer: loop { + let mut ch_start: usize; + break 'outer; + } + "".to_string() +} + +pub fn main() { + println!("{}", decode()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9110.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9110.rs new file mode 100644 index 000000000000..484385e5e91b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9110.rs @@ -0,0 +1,18 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 +#![allow(non_snake_case)] + +macro_rules! silly_macro { + () => ( + pub mod Qux { + pub struct Foo { x : u8 } + pub fn bar(_foo : Foo) {} + } + ); +} + +silly_macro!(); + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9123.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9123.rs new file mode 100644 index 000000000000..696e4f979318 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9123.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:issue-9123.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_9123; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9129.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9129.rs new file mode 100644 index 000000000000..fb2c0e01409d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9129.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +// ignore-pretty unreported + +#![feature(box_syntax)] + +pub trait bomb { fn boom(&self, _: Ident); } +pub struct S; +impl bomb for S { fn boom(&self, _: Ident) { } } + +pub struct Ident { name: usize } + +// macro_rules! int3 { () => ( unsafe { llvm_asm!( "int3" ); } ) } +macro_rules! int3 { () => ( { } ) } + +fn Ident_new() -> Ident { + int3!(); + Ident {name: 0x6789ABCD } +} + +pub fn light_fuse(fld: Box) { + int3!(); + let f = || { + int3!(); + fld.boom(Ident_new()); // *** 1 + }; + f(); +} + +pub fn main() { + let b = box S as Box; + light_fuse(b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9155.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9155.rs new file mode 100644 index 000000000000..cb5d1bafc39c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9155.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:issue-9155.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_9155; + +struct Baz; + +pub fn main() { + issue_9155::Foo::new(Baz); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9188.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9188.rs new file mode 100644 index 000000000000..3c1a1b0dc60d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9188.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-9188.rs + + +extern crate issue_9188; + +pub fn main() { + let a = issue_9188::bar(); + let b = issue_9188::foo::(); + assert_eq!(*a, *b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9243.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9243.rs new file mode 100644 index 000000000000..c3a987210003 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9243.rs @@ -0,0 +1,17 @@ +// build-pass +#![allow(dead_code)] +// Regression test for issue 9243 +#![allow(non_upper_case_globals)] + +pub struct Test { + mem: isize, +} + +pub static g_test: Test = Test {mem: 0}; + +impl Drop for Test { + fn drop(&mut self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9249.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9249.rs new file mode 100644 index 000000000000..18fb8b5c44fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9249.rs @@ -0,0 +1,7 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +static DATA:&'static [&'static str] = &["my string"]; +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9259.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9259.rs new file mode 100644 index 000000000000..8076cccf98cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9259.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] + +struct A<'a> { + a: &'a [String], + b: Option<&'a [String]>, +} + +pub fn main() { + let b: &[String] = &["foo".to_string()]; + let a = A { + a: &["test".to_string()], + b: Some(b), + }; + assert_eq!(a.b.as_ref().unwrap()[0], "foo"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9382.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9382.rs new file mode 100644 index 000000000000..0541737d58e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9382.rs @@ -0,0 +1,42 @@ +// pretty-expanded FIXME #23616 + + +// run-pass +#![allow(dead_code)] +#![feature(box_syntax)] + +// Tests for a previous bug that occurred due to an interaction +// between struct field initialization and the auto-coercion +// from a vector to a slice. The drop glue was being invoked on +// the temporary slice with a wrong type, triggering an LLVM assert. + + +struct Thing1<'a> { + baz: &'a [Box], + bar: Box, +} + +struct Thing2<'a> { + baz: &'a [Box], + bar: u64, +} + +pub fn main() { + let _t1_fixed = Thing1 { + baz: &[], + bar: box 32, + }; + Thing1 { + baz: &Vec::new(), + bar: box 32, + }; + let _t2_fixed = Thing2 { + baz: &[], + bar: 32, + }; + Thing2 { + baz: &Vec::new(), + bar: 32, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9394-inherited-trait-calls.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9394-inherited-trait-calls.rs new file mode 100644 index 000000000000..b71f40594851 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9394-inherited-trait-calls.rs @@ -0,0 +1,63 @@ +// run-pass + +trait Base: Base2 + Base3{ + fn foo(&self) -> String; + fn foo1(&self) -> String; + fn foo2(&self) -> String{ + "base foo2".to_string() + } +} + +trait Base2: Base3{ + fn baz(&self) -> String; +} + +trait Base3{ + fn root(&self) -> String; +} + +trait Super: Base{ + fn bar(&self) -> String; +} + +struct X; + +impl Base for X { + fn foo(&self) -> String{ + "base foo".to_string() + } + fn foo1(&self) -> String{ + "base foo1".to_string() + } + +} + +impl Base2 for X { + fn baz(&self) -> String{ + "base2 baz".to_string() + } +} + +impl Base3 for X { + fn root(&self) -> String{ + "base3 root".to_string() + } +} + +impl Super for X { + fn bar(&self) -> String{ + "super bar".to_string() + } +} + +pub fn main() { + let n = X; + let s = &n as &dyn Super; + assert_eq!(s.bar(),"super bar".to_string()); + assert_eq!(s.foo(),"base foo".to_string()); + assert_eq!(s.foo1(),"base foo1".to_string()); + assert_eq!(s.foo2(),"base foo2".to_string()); + assert_eq!(s.baz(),"base2 baz".to_string()); + assert_eq!(s.root(),"base3 root".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9396.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9396.rs new file mode 100644 index 000000000000..01046c1bc2fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9396.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(deprecated)] +// ignore-emscripten no threads support + +use std::sync::mpsc::{TryRecvError, channel}; +use std::thread; + +pub fn main() { + let (tx, rx) = channel(); + let t = thread::spawn(move||{ + thread::sleep_ms(10); + tx.send(()).unwrap(); + }); + loop { + match rx.try_recv() { + Ok(()) => break, + Err(TryRecvError::Empty) => {} + Err(TryRecvError::Disconnected) => unreachable!() + } + } + t.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9446.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9446.rs new file mode 100644 index 000000000000..2ae8d5024e2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9446.rs @@ -0,0 +1,31 @@ +// run-pass +struct Wrapper(String); + +impl Wrapper { + pub fn new(wrapped: String) -> Wrapper { + Wrapper(wrapped) + } + + pub fn say_hi(&self) { + let Wrapper(ref s) = *self; + println!("hello {}", *s); + } +} + +impl Drop for Wrapper { + fn drop(&mut self) {} +} + +pub fn main() { + { + // This runs without complaint. + let x = Wrapper::new("Bob".to_string()); + x.say_hi(); + } + { + // This fails to compile, circa 0.8-89-gc635fba. + // error: internal compiler error: drop_ty_immediate: non-box ty + Wrapper::new("Bob".to_string()).say_hi(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-948.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-948.rs new file mode 100644 index 000000000000..7be2388e5d4f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-948.rs @@ -0,0 +1,16 @@ +// run-fail +// error-pattern:beep boop +// ignore-emscripten no processes + +#![allow(unused_variables)] + +struct Point { + x: isize, + y: isize, +} + +fn main() { + let origin = Point { x: 0, y: 0 }; + let f: Point = Point { x: (panic!("beep boop")), ..origin }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9575.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9575.rs new file mode 100644 index 000000000000..626a6100bfda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9575.rs @@ -0,0 +1,8 @@ +#![feature(start)] + +#[start] +fn start(argc: isize, argv: *const *const u8, crate_map: *const u8) -> isize { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9719.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9719.rs new file mode 100644 index 000000000000..f94952e7fb02 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9719.rs @@ -0,0 +1,42 @@ +// build-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +mod a { + pub enum Enum { + A(T), + } + + pub trait X { + fn dummy(&self) { } + } + impl X for isize {} + + pub struct Z<'a>(Enum<&'a (dyn X + 'a)>); + fn foo() { let x: isize = 42; let z = Z(Enum::A(&x as &dyn X)); let _ = z; } +} + +mod b { + trait X { + fn dummy(&self) { } + } + impl X for isize {} + struct Y<'a>{ + x:Option<&'a (dyn X + 'a)>, + } + + fn bar() { + let x: isize = 42; + let _y = Y { x: Some(&x as &dyn X) }; + } +} + +mod c { + pub trait X { fn f(&self); } + impl X for isize { fn f(&self) {} } + pub struct Z<'a>(Option<&'a (dyn X + 'a)>); + fn main() { let x: isize = 42; let z = Z(Some(&x as &dyn X)); let _ = z; } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9725.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9725.rs new file mode 100644 index 000000000000..cdca5bfa72ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9725.rs @@ -0,0 +1,8 @@ +struct A { foo: isize } + +fn main() { + let A { foo, foo } = A { foo: 3 }; +// { dg-error ".E0025." "" { target *-*-* } .-1 } +// { dg-error ".E0025." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9737.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9737.rs new file mode 100644 index 000000000000..fbd7a509c99d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9737.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_variables)] +macro_rules! f { + (v: $x:expr) => ( println!("{}", $x) ) +} + +fn main () { + let v = 5; + f!(v: 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-979.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-979.rs new file mode 100644 index 000000000000..49e172a22463 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-979.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(non_camel_case_types)] + +use std::cell::Cell; + +struct r<'a> { + b: &'a Cell, +} + +impl<'a> Drop for r<'a> { + fn drop(&mut self) { + self.b.set(self.b.get() + 1); + } +} + +fn r(b: &Cell) -> r { + r { + b: b + } +} + +pub fn main() { + let b = &Cell::new(0); + { + let _p = Some(r(b)); + } + + assert_eq!(b.get(), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9814.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9814.rs new file mode 100644 index 000000000000..4ffbfaca2cc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9814.rs @@ -0,0 +1,9 @@ +// Verify that single-variant enums can't be de-referenced +// Regression test for issue #9814 + +enum Foo { Bar(isize) } + +fn main() { + let _ = *Foo::Bar(2); // { dg-error ".E0614." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9837.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9837.rs new file mode 100644 index 000000000000..1e5087cefb69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9837.rs @@ -0,0 +1,12 @@ +// run-pass +const C1: i32 = 0x12345678; +const C2: isize = C1 as i16 as isize; + +enum E { + V = C2 +} + +fn main() { + assert_eq!(C2 as u64, E::V as u64); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9906.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9906.rs new file mode 100644 index 000000000000..9436d2bbb2dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9906.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:issue-9906.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_9906 as testmod; + +pub fn main() { + testmod::foo(); + testmod::FooBar::new(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9918.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9918.rs new file mode 100644 index 000000000000..9871deeef59a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9918.rs @@ -0,0 +1,6 @@ +// run-pass + +pub fn main() { + assert_eq!((0 + 0u8) as char, '\0'); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9942.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9942.rs new file mode 100644 index 000000000000..c6ef0922429a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9942.rs @@ -0,0 +1,7 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + const S: usize = 23 as usize; [0; S]; () +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9951.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9951.rs new file mode 100644 index 000000000000..f215ca6dd6a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9951.rs @@ -0,0 +1,22 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![allow(unused_variables)] + +trait Bar { + fn noop(&self); +} +impl Bar for u8 { + fn noop(&self) {} +} + +fn main() { + let (a, b) = (&5u8 as &dyn Bar, &9u8 as &dyn Bar); + let (c, d): (&dyn Bar, &dyn Bar) = (a, b); + + let (a, b) = (Box::new(5u8) as Box, Box::new(9u8) as Box); + let (c, d): (&dyn Bar, &dyn Bar) = (&*a, &*b); + + let (c, d): (&dyn Bar, &dyn Bar) = (&5, &9); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-9968.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-9968.rs new file mode 100644 index 000000000000..6de6033e7bd9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-9968.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:issue-9968.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_9968 as lib; + +use lib::{Trait, Struct}; + +pub fn main() +{ + Struct::init().test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-pr29383.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-pr29383.rs new file mode 100644 index 000000000000..1576c7d4beb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-pr29383.rs @@ -0,0 +1,15 @@ +enum E { + A, + B, +} + +fn main() { + match None { + None => {} + Some(E::A(..)) => {} +// { dg-error ".E0532." "" { target *-*-* } .-1 } + Some(E::B(..)) => {} +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/type-arg-mismatch-due-to-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/issues/type-arg-mismatch-due-to-impl-trait.rs new file mode 100644 index 000000000000..f611b667758c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/type-arg-mismatch-due-to-impl-trait.rs @@ -0,0 +1,17 @@ +trait Foo { + type T; + fn foo(&self, t: Self::T); +// { dg-note "" "" { target *-*-* } .-1 } +} + +impl Foo for u32 { + type T = (); + + fn foo(&self, t: impl Clone) {} +// { dg-error ".E0049." "" { target *-*-* } .-1 } +// { dg-note ".E0049." "" { target *-*-* } .-2 } +// { dg-note ".E0049." "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/istr.rs b/gcc/testsuite/rust/rustc/ui/istr.rs new file mode 100644 index 000000000000..51bc9a85a1aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/istr.rs @@ -0,0 +1,54 @@ +// run-pass + +use std::string::String; + +fn test_stack_assign() { + let s: String = "a".to_string(); + println!("{}", s.clone()); + let t: String = "a".to_string(); + assert_eq!(s, t); + let u: String = "b".to_string(); + assert!((s != u)); +} + +fn test_heap_lit() { "a big string".to_string(); } + +fn test_heap_assign() { + let s: String = "a big ol' string".to_string(); + let t: String = "a big ol' string".to_string(); + assert_eq!(s, t); + let u: String = "a bad ol' string".to_string(); + assert!((s != u)); +} + +fn test_heap_log() { + let s = "a big ol' string".to_string(); + println!("{}", s); +} + +fn test_append() { + let mut s = String::new(); + s.push_str("a"); + assert_eq!(s, "a"); + + let mut s = String::from("a"); + s.push_str("b"); + println!("{}", s.clone()); + assert_eq!(s, "ab"); + + let mut s = String::from("c"); + s.push_str("offee"); + assert_eq!(s, "coffee"); + + s.push_str("&tea"); + assert_eq!(s, "coffee&tea"); +} + +pub fn main() { + test_stack_assign(); + test_heap_lit(); + test_heap_assign(); + test_heap_log(); + test_append(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/item-name-overload.rs b/gcc/testsuite/rust/rustc/ui/item-name-overload.rs new file mode 100644 index 000000000000..ca924e2af81c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/item-name-overload.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(dead_code)] + + + +// pretty-expanded FIXME #23616 + +mod foo { + pub fn baz() { } +} + +mod bar { + pub fn baz() { } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/array-of-ranges.rs b/gcc/testsuite/rust/rustc/ui/iterators/array-of-ranges.rs new file mode 100644 index 000000000000..3bb3d73a74b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/array-of-ranges.rs @@ -0,0 +1,24 @@ +fn main() { + for _ in [0..1] {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in [0..=1] {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in [0..] {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in [..1] {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in [..=1] {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let start = 0; + let end = 0; + for _ in [start..end] {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let array_of_range = [start..end]; + for _ in array_of_range {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in [0..1, 2..3] {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in [0..=1] {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/array.rs b/gcc/testsuite/rust/rustc/ui/iterators/array.rs new file mode 100644 index 000000000000..803ae37e73a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/array.rs @@ -0,0 +1,10 @@ +fn main() { + for _ in [1, 2] {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let x = [1, 2]; + for _ in x {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in [1.0, 2.0] {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/bound.rs b/gcc/testsuite/rust/rustc/ui/iterators/bound.rs new file mode 100644 index 000000000000..e442d68c1777 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/bound.rs @@ -0,0 +1,5 @@ +struct S(I); +struct T(S); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/integral.rs b/gcc/testsuite/rust/rustc/ui/iterators/integral.rs new file mode 100644 index 000000000000..697783d57e63 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/integral.rs @@ -0,0 +1,27 @@ +fn main() { + for _ in 42 {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in 42 as u8 {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in 42 as i8 {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in 42 as u16 {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in 42 as i16 {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in 42 as u32 {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in 42 as i32 {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in 42 as u64 {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in 42 as i64 {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in 42 as usize {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in 42 as isize {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in 42.0 {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/into-iter-on-arrays-lint.rs b/gcc/testsuite/rust/rustc/ui/iterators/into-iter-on-arrays-lint.rs new file mode 100644 index 000000000000..8505392da149 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/into-iter-on-arrays-lint.rs @@ -0,0 +1,62 @@ +// run-pass +// run-rustfix + +fn main() { + let small = [1, 2]; + let big = [0u8; 33]; + + // Expressions that should trigger the lint + small.into_iter(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + [1, 2].into_iter(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + big.into_iter(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + [0u8; 33].into_iter(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + Box::new(small).into_iter(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + Box::new([1, 2]).into_iter(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + Box::new(big).into_iter(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + Box::new([0u8; 33]).into_iter(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + Box::new(Box::new(small)).into_iter(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + Box::new(Box::new([1, 2])).into_iter(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + Box::new(Box::new(big)).into_iter(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + Box::new(Box::new([0u8; 33])).into_iter(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + // Expressions that should not + (&[1, 2]).into_iter(); + (&small).into_iter(); + (&[0u8; 33]).into_iter(); + (&big).into_iter(); + + for _ in &[1, 2] {} + (&small as &[_]).into_iter(); + small[..].into_iter(); + std::iter::IntoIterator::into_iter(&[1, 2]); + + #[allow(array_into_iter)] + [0, 1].into_iter(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/into-iterator-type-inference-shift.rs b/gcc/testsuite/rust/rustc/ui/iterators/into-iterator-type-inference-shift.rs new file mode 100644 index 000000000000..92e164a56e3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/into-iterator-type-inference-shift.rs @@ -0,0 +1,37 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(dead_code)] +#![allow(unused_mut)] +#![allow(unused_variables)] +// Regression test for type inference failure around shifting. In this +// case, the iteration yields an isize, but we hadn't run the full type +// propagation yet, and so we just saw a type variable, yielding an +// error. + +// pretty-expanded FIXME #23616 + +trait IntoIterator { + type Iter: Iterator; + + fn into_iter(self) -> Self::Iter; +} + +impl IntoIterator for I where I: Iterator { + type Iter = I; + + fn into_iter(self) -> I { + self + } +} + +fn desugared_for_loop_bad(byte: u8) -> u8 { + let mut result = 0; + let mut x = IntoIterator::into_iter(0..8); + let mut y = Iterator::next(&mut x); + let mut z = y.unwrap(); + byte >> z; + 1 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/issue-58952-filter-type-length.rs b/gcc/testsuite/rust/rustc/ui/iterators/issue-58952-filter-type-length.rs new file mode 100644 index 000000000000..1eb3584115cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/issue-58952-filter-type-length.rs @@ -0,0 +1,33 @@ +// run-pass +//! This snippet causes the type length to blowup exponentially, +//! so check that we don't accidentially exceed the type length limit. +// FIXME: Once the size of iterator adaptors is further reduced, +// increase the complexity of this test. +use std::collections::VecDeque; + +fn main() { + let c = 2; + let bv = vec![2]; + let b = bv + .iter() + .filter(|a| **a == c); + + let _a = vec![1, 2, 3] + .into_iter() + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .filter(|a| b.clone().any(|b| *b == *a)) + .collect::>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/iter-cloned-type-inference.rs b/gcc/testsuite/rust/rustc/ui/iterators/iter-cloned-type-inference.rs new file mode 100644 index 000000000000..0a4f9caf82c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/iter-cloned-type-inference.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(stable_features)] + +// Test to see that the element type of .cloned() can be inferred +// properly. Previously this would fail to deduce the type of `sum`. + +#![feature(iter_arith)] + +fn square_sum(v: &[i64]) -> i64 { + let sum: i64 = v.iter().cloned().sum(); + sum * sum +} + +fn main() { + assert_eq!(36, square_sum(&[1,2,3])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/iter-count-overflow-debug.rs b/gcc/testsuite/rust/rustc/ui/iterators/iter-count-overflow-debug.rs new file mode 100644 index 000000000000..3017ea4efb11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/iter-count-overflow-debug.rs @@ -0,0 +1,17 @@ +// run-pass +// only-32bit too impatient for 2⁶⁴ items +// ignore-wasm32-bare compiled with panic=abort by default +// compile-flags: -C debug_assertions=yes -C opt-level=3 + +use std::panic; +use std::usize::MAX; + +fn main() { + assert_eq!((0..MAX).by_ref().count(), MAX); + + let r = panic::catch_unwind(|| { + (0..=MAX).by_ref().count() + }); + assert!(r.is_err()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/iter-count-overflow-ndebug.rs b/gcc/testsuite/rust/rustc/ui/iterators/iter-count-overflow-ndebug.rs new file mode 100644 index 000000000000..efb98c908262 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/iter-count-overflow-ndebug.rs @@ -0,0 +1,12 @@ +// run-pass +// only-32bit too impatient for 2⁶⁴ items +// compile-flags: -C debug_assertions=no -C opt-level=3 + +use std::panic; +use std::usize::MAX; + +fn main() { + assert_eq!((0..MAX).by_ref().count(), MAX); + assert_eq!((0..=MAX).by_ref().count(), 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/iter-map-fold-type-length.rs b/gcc/testsuite/rust/rustc/ui/iterators/iter-map-fold-type-length.rs new file mode 100644 index 000000000000..3419ad117d09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/iter-map-fold-type-length.rs @@ -0,0 +1,39 @@ +// run-pass +//! Check that type lengths don't explode with `Map` folds. +//! +//! The normal limit is a million, and this test used to exceed 1.5 million, but +//! now we can survive an even tighter limit. Still seems excessive though... +#![type_length_limit = "256000"] + +// Custom wrapper so Iterator methods aren't specialized. +struct Iter(I); + +impl Iterator for Iter +where + I: Iterator +{ + type Item = I::Item; + + fn next(&mut self) -> Option { + self.0.next() + } +} + +fn main() { + let c = Iter(0i32..10) + .map(|x| x) + .map(|x| x) + .map(|x| x) + .map(|x| x) + .map(|x| x) + .map(|x| x) + .map(|x| x) + .map(|x| x) + .map(|x| x) + .map(|x| x) + .map(|x| x) + .map(|x| x) + .count(); + assert_eq!(c, 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/iter-position-overflow-debug.rs b/gcc/testsuite/rust/rustc/ui/iterators/iter-position-overflow-debug.rs new file mode 100644 index 000000000000..a209c9d21309 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/iter-position-overflow-debug.rs @@ -0,0 +1,23 @@ +// run-pass +// only-32bit too impatient for 2⁶⁴ items +// ignore-wasm32-bare compiled with panic=abort by default +// compile-flags: -C debug_assertions=yes -C opt-level=3 + +use std::panic; +use std::usize::MAX; + +fn main() { + let n = MAX as u64; + assert_eq!((0..).by_ref().position(|i| i >= n), Some(MAX)); + + let r = panic::catch_unwind(|| { + (0..).by_ref().position(|i| i > n) + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + (0..=n + 1).by_ref().position(|_| false) + }); + assert!(r.is_err()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/iter-position-overflow-ndebug.rs b/gcc/testsuite/rust/rustc/ui/iterators/iter-position-overflow-ndebug.rs new file mode 100644 index 000000000000..2396205158ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/iter-position-overflow-ndebug.rs @@ -0,0 +1,14 @@ +// run-pass +// only-32bit too impatient for 2⁶⁴ items +// compile-flags: -C debug_assertions=no -C opt-level=3 + +use std::panic; +use std::usize::MAX; + +fn main() { + let n = MAX as u64; + assert_eq!((0..).by_ref().position(|i| i >= n), Some(MAX)); + assert_eq!((0..).by_ref().position(|i| i > n), Some(0)); + assert_eq!((0..=n + 1).by_ref().position(|_| false), None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/iter-range.rs b/gcc/testsuite/rust/rustc/ui/iterators/iter-range.rs new file mode 100644 index 000000000000..767d47fa5cae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/iter-range.rs @@ -0,0 +1,15 @@ +// run-pass + + +fn range_(a: isize, b: isize, mut it: F) where F: FnMut(isize) { + assert!((a < b)); + let mut i: isize = a; + while i < b { it(i); i += 1; } +} + +pub fn main() { + let mut sum: isize = 0; + range_(0, 100, |x| sum += x ); + println!("{}", sum); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/iter-step-overflow-debug.rs b/gcc/testsuite/rust/rustc/ui/iterators/iter-step-overflow-debug.rs new file mode 100644 index 000000000000..27995f1196c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/iter-step-overflow-debug.rs @@ -0,0 +1,22 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default +// compile-flags: -C debug_assertions=yes + +use std::panic; + +fn main() { + let r = panic::catch_unwind(|| { + let mut it = u8::MAX..; + it.next().unwrap(); // 255 + it.next().unwrap(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + let mut it = i8::MAX..; + it.next().unwrap(); // 127 + it.next().unwrap(); + }); + assert!(r.is_err()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/iter-step-overflow-ndebug.rs b/gcc/testsuite/rust/rustc/ui/iterators/iter-step-overflow-ndebug.rs new file mode 100644 index 000000000000..0cded194827f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/iter-step-overflow-ndebug.rs @@ -0,0 +1,13 @@ +// run-pass +// compile-flags: -C debug_assertions=no + +fn main() { + let mut it = u8::MAX..; + assert_eq!(it.next().unwrap(), 255); + assert_eq!(it.next().unwrap(), u8::MIN); + + let mut it = i8::MAX..; + assert_eq!(it.next().unwrap(), 127); + assert_eq!(it.next().unwrap(), i8::MIN); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/iter-sum-overflow-debug.rs b/gcc/testsuite/rust/rustc/ui/iterators/iter-sum-overflow-debug.rs new file mode 100644 index 000000000000..f37a1ba61701 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/iter-sum-overflow-debug.rs @@ -0,0 +1,28 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default +// compile-flags: -C debug_assertions=yes + +use std::panic; + +fn main() { + let r = panic::catch_unwind(|| { + [1, i32::MAX].iter().sum::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [2, i32::MAX].iter().product::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [1, i32::MAX].iter().cloned().sum::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [2, i32::MAX].iter().cloned().product::(); + }); + assert!(r.is_err()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/iter-sum-overflow-ndebug.rs b/gcc/testsuite/rust/rustc/ui/iterators/iter-sum-overflow-ndebug.rs new file mode 100644 index 000000000000..174a938ac060 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/iter-sum-overflow-ndebug.rs @@ -0,0 +1,15 @@ +// run-pass +// compile-flags: -C debug_assertions=no + +fn main() { + assert_eq!([1i32, i32::MAX].iter().sum::(), + 1i32.wrapping_add(i32::MAX)); + assert_eq!([2i32, i32::MAX].iter().product::(), + 2i32.wrapping_mul(i32::MAX)); + + assert_eq!([1i32, i32::MAX].iter().cloned().sum::(), + 1i32.wrapping_add(i32::MAX)); + assert_eq!([2i32, i32::MAX].iter().cloned().product::(), + 2i32.wrapping_mul(i32::MAX)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/iter-sum-overflow-overflow-checks.rs b/gcc/testsuite/rust/rustc/ui/iterators/iter-sum-overflow-overflow-checks.rs new file mode 100644 index 000000000000..56193292f616 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/iter-sum-overflow-overflow-checks.rs @@ -0,0 +1,28 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default +// compile-flags: -C overflow-checks + +use std::panic; + +fn main() { + let r = panic::catch_unwind(|| { + [1, i32::MAX].iter().sum::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [2, i32::MAX].iter().product::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [1, i32::MAX].iter().cloned().sum::(); + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + [2, i32::MAX].iter().cloned().product::(); + }); + assert!(r.is_err()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/ranges.rs b/gcc/testsuite/rust/rustc/ui/iterators/ranges.rs new file mode 100644 index 000000000000..a5a356325a5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/ranges.rs @@ -0,0 +1,10 @@ +fn main() { + for _ in ..10 {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in ..=10 {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in 0..10 {} + for _ in 0..=10 {} + for _ in 0.. {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/skip-count-overflow.rs b/gcc/testsuite/rust/rustc/ui/iterators/skip-count-overflow.rs new file mode 100644 index 000000000000..7af770f8d8fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/skip-count-overflow.rs @@ -0,0 +1,9 @@ +// run-pass +// only-32bit too impatient for 2⁶⁴ items +// compile-flags: -C overflow-checks -C opt-level=3 + +fn main() { + let i = (0..usize::MAX).chain(0..10).skip(usize::MAX); + assert_eq!(i.count(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/iterators/string.rs b/gcc/testsuite/rust/rustc/ui/iterators/string.rs new file mode 100644 index 000000000000..ea3edfc5e0c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/iterators/string.rs @@ -0,0 +1,7 @@ +fn main() { + for _ in "".to_owned() {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + for _ in "" {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/json-and-color.rs b/gcc/testsuite/rust/rustc/ui/json-and-color.rs new file mode 100644 index 000000000000..3d12867fe724 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/json-and-color.rs @@ -0,0 +1,4 @@ +// compile-flags: --json=artifacts --error-format=json --color never + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/json-and-error-format.rs b/gcc/testsuite/rust/rustc/ui/json-and-error-format.rs new file mode 100644 index 000000000000..de1a12aa122f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/json-and-error-format.rs @@ -0,0 +1,4 @@ +// compile-flags: --json=artifacts --error-format=short + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/json-bom-plus-crlf-multifile-aux.rs b/gcc/testsuite/rust/rustc/ui/json-bom-plus-crlf-multifile-aux.rs new file mode 100644 index 000000000000..c41dfbbbd726 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/json-bom-plus-crlf-multifile-aux.rs @@ -0,0 +1,28 @@ +// (This line has BOM so it's ignored by compiletest for directives) +// +// ignore-test Not a test. Used by other tests +// ignore-tidy-cr + +// For easier verifying, the byte offsets in this file should match those +// in the json-bom-plus-crlf.rs - given the actual fn is identical (just with +// a different, but equally sized name), the easiest way to do this is to +// ensure the two files are of equal size on disk. +// Padding............................ + +// N.B., this file needs CRLF line endings. The .gitattributes file in +// this directory should enforce it. + +pub fn test() { + + let s : String = 1; // Error in the middle of line. + + let s : String = 1 + ; // Error before the newline. + + let s : String = +1; // Error after the newline. + + let s : String = ( + ); // Error spanning the newline. +} + diff --git a/gcc/testsuite/rust/rustc/ui/json-bom-plus-crlf-multifile.rs b/gcc/testsuite/rust/rustc/ui/json-bom-plus-crlf-multifile.rs new file mode 100644 index 000000000000..f1844493afca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/json-bom-plus-crlf-multifile.rs @@ -0,0 +1,12 @@ +// (This line has BOM so it's ignored by compiletest for directives) +// +// compile-flags: --json=diagnostic-short --error-format=json +// ignore-tidy-cr + +#[path = "json-bom-plus-crlf-multifile-aux.rs"] +mod json_bom_plus_crlf_multifile_aux; + +fn main() { + json_bom_plus_crlf_multifile_aux::test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/json-bom-plus-crlf.rs b/gcc/testsuite/rust/rustc/ui/json-bom-plus-crlf.rs new file mode 100644 index 000000000000..a786acfdc53c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/json-bom-plus-crlf.rs @@ -0,0 +1,27 @@ +// (This line has BOM so it's ignored by compiletest for directives) +// +// compile-flags: --json=diagnostic-short --error-format=json +// ignore-tidy-cr + +// For easier verifying, the byte offsets in this file should match those +// in the json_bom_plus_crlf_multifile_aux.rs - given the actual fn is +// identical (just with a different, but equally sized name), the easiest way +// to do this is to ensure the two files are of equal size on disk. + +// N.B., this file needs CRLF line endings. The .gitattributes file in +// this directory should enforce it. + +fn main() { + + let s : String = 1; // Error in the middle of line. + + let s : String = 1 + ; // Error before the newline. + + let s : String = +1; // Error after the newline. + + let s : String = ( + ); // Error spanning the newline. +} + diff --git a/gcc/testsuite/rust/rustc/ui/json-invalid.rs b/gcc/testsuite/rust/rustc/ui/json-invalid.rs new file mode 100644 index 000000000000..ccc0838489bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/json-invalid.rs @@ -0,0 +1,4 @@ +// compile-flags: --json=foo --error-format=json + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/json-multiple.rs b/gcc/testsuite/rust/rustc/ui/json-multiple.rs new file mode 100644 index 000000000000..2092f3925aae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/json-multiple.rs @@ -0,0 +1,6 @@ +// build-pass +// ignore-pass (different metadata emitted in different modes) +// compile-flags: --json=diagnostic-short --json artifacts --error-format=json + +#![crate_type = "lib"] + diff --git a/gcc/testsuite/rust/rustc/ui/json-options.rs b/gcc/testsuite/rust/rustc/ui/json-options.rs new file mode 100644 index 000000000000..d721262cf29a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/json-options.rs @@ -0,0 +1,6 @@ +// build-pass +// ignore-pass (different metadata emitted in different modes) +// compile-flags: --json=diagnostic-short,artifacts --error-format=json + +#![crate_type = "lib"] + diff --git a/gcc/testsuite/rust/rustc/ui/json-short.rs b/gcc/testsuite/rust/rustc/ui/json-short.rs new file mode 100644 index 000000000000..8925f08dad51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/json-short.rs @@ -0,0 +1,2 @@ +// compile-flags: --json=diagnostic-short --error-format=json + diff --git a/gcc/testsuite/rust/rustc/ui/keyword-changes-2012-07-31.rs b/gcc/testsuite/rust/rustc/ui/keyword-changes-2012-07-31.rs new file mode 100644 index 000000000000..3ef4dee52ef9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/keyword-changes-2012-07-31.rs @@ -0,0 +1,21 @@ +// run-pass + +#![allow(dead_code)] +// return -> return +// mod -> module +// match -> match + +// pretty-expanded FIXME #23616 + +pub fn main() { +} + +mod foo { +} + +fn bar() -> isize { + match 0 { + _ => { 0 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-expr.rs b/gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-expr.rs new file mode 100644 index 000000000000..332a31a818b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-expr.rs @@ -0,0 +1,4 @@ +fn main() { + let s = extern::foo::Bar; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-pat.rs b/gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-pat.rs new file mode 100644 index 000000000000..6e280aead9a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-pat.rs @@ -0,0 +1,4 @@ +fn main() { + let extern = 0; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-type.rs b/gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-type.rs new file mode 100644 index 000000000000..b0bbffb9301f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-type.rs @@ -0,0 +1,4 @@ +type A = extern::foo::bar; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-use.rs b/gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-use.rs new file mode 100644 index 000000000000..5db495fd1fab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/keyword/extern/keyword-extern-as-identifier-use.rs @@ -0,0 +1,5 @@ +use extern::foo; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/keyword/keyword-false-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/keyword/keyword-false-as-identifier.rs new file mode 100644 index 000000000000..ac51ee912f88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/keyword/keyword-false-as-identifier.rs @@ -0,0 +1,4 @@ +fn main() { + let false = 22; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/keyword/keyword-self-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/keyword/keyword-self-as-identifier.rs new file mode 100644 index 000000000000..620660e9be71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/keyword/keyword-self-as-identifier.rs @@ -0,0 +1,4 @@ +fn main() { + let Self = 22; // { dg-error ".E0531." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/keyword/keyword-super-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/keyword/keyword-super-as-identifier.rs new file mode 100644 index 000000000000..876224282384 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/keyword/keyword-super-as-identifier.rs @@ -0,0 +1,4 @@ +fn main() { + let super = 22; // { dg-error ".E0433." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/keyword/keyword-super.rs b/gcc/testsuite/rust/rustc/ui/keyword/keyword-super.rs new file mode 100644 index 000000000000..5d0aa9cfb073 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/keyword/keyword-super.rs @@ -0,0 +1,4 @@ +fn main() { + let super: isize; // { dg-error ".E0433." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/keyword/keyword-true-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/keyword/keyword-true-as-identifier.rs new file mode 100644 index 000000000000..eb8762d733c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/keyword/keyword-true-as-identifier.rs @@ -0,0 +1,4 @@ +fn main() { + let true = 22; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/kindck-implicit-close-over-mut-var.rs b/gcc/testsuite/rust/rustc/ui/kindck-implicit-close-over-mut-var.rs new file mode 100644 index 000000000000..65a6f3e16081 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/kindck-implicit-close-over-mut-var.rs @@ -0,0 +1,50 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(dead_code)] +use std::thread; + +fn user(_i: isize) {} + +fn foo() { + // Here, i is *copied* into the proc (heap closure). + // Requires allocation. The proc's copy is not mutable. + let mut i = 0; + let t = thread::spawn(move|| { + user(i); + println!("spawned {}", i) + }); + i += 1; + println!("original {}", i); + t.join(); +} + +fn bar() { + // Here, the original i has not been moved, only copied, so is still + // mutable outside of the proc. + let mut i = 0; + while i < 10 { + let t = thread::spawn(move|| { + user(i); + }); + i += 1; + t.join(); + } +} + +fn car() { + // Here, i must be shadowed in the proc to be mutable. + let mut i = 0; + while i < 10 { + let t = thread::spawn(move|| { + let mut i = i; + i += 1; + user(i); + }); + i += 1; + t.join(); + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/kindck/kindck-copy.rs b/gcc/testsuite/rust/rustc/ui/kindck/kindck-copy.rs new file mode 100644 index 000000000000..f3069eaedd8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/kindck/kindck-copy.rs @@ -0,0 +1,72 @@ +// Test which of the builtin types are considered POD. + +use std::rc::Rc; + +fn assert_copy() { } + +trait Dummy { } + +#[derive(Copy, Clone)] +struct MyStruct { + x: isize, + y: isize, +} + +struct MyNoncopyStruct { + x: Box, +} + +fn test<'a,T,U:Copy>(_: &'a isize) { + // lifetime pointers are ok... + assert_copy::<&'static isize>(); + assert_copy::<&'a isize>(); + assert_copy::<&'a str>(); + assert_copy::<&'a [isize]>(); + + // ...unless they are mutable + assert_copy::<&'static mut isize>(); // { dg-error ".E0277." "" { target *-*-* } } + assert_copy::<&'a mut isize>(); // { dg-error ".E0277." "" { target *-*-* } } + + // boxes are not ok + assert_copy::>(); // { dg-error ".E0277." "" { target *-*-* } } + assert_copy::(); // { dg-error ".E0277." "" { target *-*-* } } + assert_copy:: >(); // { dg-error ".E0277." "" { target *-*-* } } + assert_copy::>(); // { dg-error ".E0277." "" { target *-*-* } } + + // borrowed object types are generally ok + assert_copy::<&'a dyn Dummy>(); + assert_copy::<&'a (dyn Dummy + Send)>(); + assert_copy::<&'static (dyn Dummy + Send)>(); + + // owned object types are not ok + assert_copy::>(); // { dg-error ".E0277." "" { target *-*-* } } + assert_copy::>(); // { dg-error ".E0277." "" { target *-*-* } } + + // mutable object types are not ok + assert_copy::<&'a mut (dyn Dummy + Send)>(); // { dg-error ".E0277." "" { target *-*-* } } + + // unsafe ptrs are ok + assert_copy::<*const isize>(); + assert_copy::<*const &'a mut isize>(); + + // regular old ints and such are ok + assert_copy::(); + assert_copy::(); + assert_copy::<()>(); + + // tuples are ok + assert_copy::<(isize,isize)>(); + + // structs of POD are ok + assert_copy::(); + + // structs containing non-POD are not ok + assert_copy::(); // { dg-error ".E0277." "" { target *-*-* } } + + // ref counted types are not ok + assert_copy::>(); // { dg-error ".E0277." "" { target *-*-* } } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/kindck/kindck-impl-type-params-2.rs b/gcc/testsuite/rust/rustc/ui/kindck/kindck-impl-type-params-2.rs new file mode 100644 index 000000000000..0466bbb88749 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/kindck/kindck-impl-type-params-2.rs @@ -0,0 +1,16 @@ +#![feature(box_syntax)] + +trait Foo { +} + +impl Foo for T { +} + +fn take_param(foo: &T) { } + +fn main() { + let x: Box<_> = box 3; + take_param(&x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/kindck/kindck-impl-type-params.rs b/gcc/testsuite/rust/rustc/ui/kindck/kindck-impl-type-params.rs new file mode 100644 index 000000000000..3b148b5220af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/kindck/kindck-impl-type-params.rs @@ -0,0 +1,51 @@ +// Issue #14061: tests the interaction between generic implementation +// parameter bounds and trait objects. + +#![feature(box_syntax)] + +use std::marker; + +struct S(marker::PhantomData); + +trait Gettable { + fn get(&self) -> T { panic!() } +} + +impl Gettable for S {} + +fn f(val: T) { + let t: S = S(marker::PhantomData); + let a = &t as &dyn Gettable; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + +fn g(val: T) { + let t: S = S(marker::PhantomData); + let a: &dyn Gettable = &t; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + +fn foo<'a>() { + let t: S<&'a isize> = S(marker::PhantomData); + let a = &t as &dyn Gettable<&'a isize>; +// { dg-error ".E0477." "" { target *-*-* } .-1 } +} + +fn foo2<'a>() { + let t: Box> = box S(marker::PhantomData); + let a = t as Box>; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn foo3<'a>() { + struct Foo; // does not impl Copy + + let t: Box> = box S(marker::PhantomData); + let a: Box> = t; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/kindck/kindck-inherited-copy-bound.rs b/gcc/testsuite/rust/rustc/ui/kindck/kindck-inherited-copy-bound.rs new file mode 100644 index 000000000000..680684daf54b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/kindck/kindck-inherited-copy-bound.rs @@ -0,0 +1,35 @@ +// Test that Copy bounds inherited by trait are checked. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] +#![feature(box_syntax)] + +use std::any::Any; + +trait Foo : Copy { + fn foo(&self) {} +} + +impl Foo for T { +} + +fn take_param(foo: &T) { } + +fn a() { + let x: Box<_> = box 3; + take_param(&x); // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn b() { + let x: Box<_> = box 3; + let y = &x; + let z = &x as &dyn Foo; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/kindck/kindck-nonsendable-1.rs b/gcc/testsuite/rust/rustc/ui/kindck/kindck-nonsendable-1.rs new file mode 100644 index 000000000000..373dc6b17960 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/kindck/kindck-nonsendable-1.rs @@ -0,0 +1,12 @@ +use std::rc::Rc; + +fn foo(_x: Rc) {} + +fn bar(_: F) { } + +fn main() { + let x = Rc::new(3); + bar(move|| foo(x)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-object.rs b/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-object.rs new file mode 100644 index 000000000000..f2f05b7af976 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-object.rs @@ -0,0 +1,27 @@ +// Test which of the builtin types are considered sendable. The tests +// in this file all test the "kind" violates detected during kindck. +// See all `regions-bounded-by-send.rs` + +fn assert_send() { } +trait Dummy { } +trait Message : Send { } + +// careful with object types, who knows what they close over... + +fn object_ref_with_static_bound_not_ok() { + assert_send::<&'static (dyn Dummy + 'static)>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn box_object_with_no_bound_not_ok<'a>() { + assert_send::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn object_with_send_bound_ok() { + assert_send::<&'static (dyn Dummy + Sync)>(); + assert_send::>(); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-object1.rs b/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-object1.rs new file mode 100644 index 000000000000..ed83d21772a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-object1.rs @@ -0,0 +1,34 @@ +// Test which object types are considered sendable. This test +// is broken into two parts because some errors occur in distinct +// phases in the compiler. See kindck-send-object2.rs as well! + +fn assert_send() { } +trait Dummy { } + +// careful with object types, who knows what they close over... +fn test51<'a>() { + assert_send::<&'a dyn Dummy>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} +fn test52<'a>() { + assert_send::<&'a (dyn Dummy + Sync)>(); +// { dg-error ".E0477." "" { target *-*-* } .-1 } +} + +// ...unless they are properly bounded +fn test60() { + assert_send::<&'static (dyn Dummy + Sync)>(); +} +fn test61() { + assert_send::>(); +} + +// closure and object types can have lifetime bounds which make +// them not ok +fn test_71<'a>() { + assert_send::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-object2.rs b/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-object2.rs new file mode 100644 index 000000000000..25d210a67722 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-object2.rs @@ -0,0 +1,25 @@ +// Continue kindck-send-object1.rs. + +fn assert_send() { } +trait Dummy { } + +fn test50() { + assert_send::<&'static dyn Dummy>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn test53() { + assert_send::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +// ...unless they are properly bounded +fn test60() { + assert_send::<&'static (dyn Dummy + Sync)>(); +} +fn test61() { + assert_send::>(); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-owned.rs b/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-owned.rs new file mode 100644 index 000000000000..6f3a42611388 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-owned.rs @@ -0,0 +1,17 @@ +// Test which of the builtin types are considered sendable. + +fn assert_send() { } + +// owned content are ok +fn test30() { assert_send::>(); } +fn test31() { assert_send::(); } +fn test32() { assert_send:: >(); } + +// but not if they own a bad thing +fn test40() { + assert_send::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-unsafe.rs b/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-unsafe.rs new file mode 100644 index 000000000000..d118b553d2f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/kindck/kindck-send-unsafe.rs @@ -0,0 +1,12 @@ +extern crate core; + +fn assert_send() { } + +fn test71<'a>() { + assert_send::<*mut &'a isize>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/kinds-in-metadata.rs b/gcc/testsuite/rust/rustc/ui/kinds-in-metadata.rs new file mode 100644 index 000000000000..bdf60678512a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/kinds-in-metadata.rs @@ -0,0 +1,18 @@ +// run-pass +// aux-build:kinds_in_metadata.rs + +// pretty-expanded FIXME #23616 + +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Tests that metadata serialization works for the `Copy` kind. + +extern crate kinds_in_metadata; + +use kinds_in_metadata::f; + +pub fn main() { + f::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/label/label-beginning-with-underscore.rs b/gcc/testsuite/rust/rustc/ui/label/label-beginning-with-underscore.rs new file mode 100644 index 000000000000..3c9fe9d7dc35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/label/label-beginning-with-underscore.rs @@ -0,0 +1,11 @@ +// check-pass + +#![deny(unused_labels)] + +fn main() { + // `unused_label` shouldn't warn labels beginning with `_` + '_unused: loop { + break; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/label/label-static.rs b/gcc/testsuite/rust/rustc/ui/label/label-static.rs new file mode 100644 index 000000000000..61332ade8def --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/label/label-static.rs @@ -0,0 +1,6 @@ +fn main() { + 'static: loop { // { dg-error "" "" { target *-*-* } } + break 'static // { dg-error "" "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/label/label-underscore.rs b/gcc/testsuite/rust/rustc/ui/label/label-underscore.rs new file mode 100644 index 000000000000..8e1e7c73e675 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/label/label-underscore.rs @@ -0,0 +1,6 @@ +fn main() { + '_: loop { // { dg-error "" "" { target *-*-* } } + break '_ // { dg-error "" "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/label/label_break_value_continue.rs b/gcc/testsuite/rust/rustc/ui/label/label_break_value_continue.rs new file mode 100644 index 000000000000..dbd7ea343185 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/label/label_break_value_continue.rs @@ -0,0 +1,28 @@ +#![feature(label_break_value)] +#![allow(unused_labels)] + +// Simple continue pointing to an unlabeled break should yield in an error +fn continue_simple() { + 'b: { + continue; // { dg-error ".E0695." "" { target *-*-* } } + } +} + +// Labeled continue pointing to an unlabeled break should yield in an error +fn continue_labeled() { + 'b: { + continue 'b; // { dg-error ".E0696." "" { target *-*-* } } + } +} + +// Simple continue that would cross a labeled block should yield in an error +fn continue_crossing() { + loop { + 'b: { + continue; // { dg-error ".E0695." "" { target *-*-* } } + } + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/label/label_break_value_desugared_break.rs b/gcc/testsuite/rust/rustc/ui/label/label_break_value_desugared_break.rs new file mode 100644 index 000000000000..1fc2da367a06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/label/label_break_value_desugared_break.rs @@ -0,0 +1,13 @@ +// compile-flags: --edition 2018 +#![feature(label_break_value, try_blocks)] + +// run-pass +fn main() { + let _: Result<(), ()> = try { + 'foo: { + Err(())?; + break 'foo; + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/label/label_break_value_illegal_uses.rs b/gcc/testsuite/rust/rustc/ui/label/label_break_value_illegal_uses.rs new file mode 100644 index 000000000000..dd66467fc058 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/label/label_break_value_illegal_uses.rs @@ -0,0 +1,22 @@ +#![feature(label_break_value)] + +// These are forbidden occurrences of label-break-value + +fn labeled_unsafe() { + unsafe 'b: {} // { dg-error "" "" { target *-*-* } } +} + +fn labeled_if() { + if true 'b: {} // { dg-error "" "" { target *-*-* } } +} + +fn labeled_else() { + if true {} else 'b: {} // { dg-error "" "" { target *-*-* } } +} + +fn labeled_match() { + match false 'b: {} // { dg-error "" "" { target *-*-* } } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/label/label_break_value_unlabeled_break.rs b/gcc/testsuite/rust/rustc/ui/label/label_break_value_unlabeled_break.rs new file mode 100644 index 000000000000..179211e56a5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/label/label_break_value_unlabeled_break.rs @@ -0,0 +1,21 @@ +#![feature(label_break_value)] +#![allow(unused_labels)] + +// Simple unlabeled break should yield in an error +fn unlabeled_break_simple() { + 'b: { + break; // { dg-error ".E0695." "" { target *-*-* } } + } +} + +// Unlabeled break that would cross a labeled block should yield in an error +fn unlabeled_break_crossing() { + loop { + 'b: { + break; // { dg-error ".E0695." "" { target *-*-* } } + } + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lambda-infer-unresolved.rs b/gcc/testsuite/rust/rustc/ui/lambda-infer-unresolved.rs new file mode 100644 index 000000000000..8ffd407cf46f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lambda-infer-unresolved.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(unused_mut)] +// This should typecheck even though the type of e is not fully +// resolved when we finish typechecking the ||. + + +struct Refs { refs: Vec , n: isize } + +pub fn main() { + let mut e = Refs{refs: vec![], n: 0}; + let _f = || println!("{}", e.n); + let x: &[isize] = &e.refs; + assert_eq!(x.len(), 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lambda-var-hygiene.rs b/gcc/testsuite/rust/rustc/ui/lambda-var-hygiene.rs new file mode 100644 index 000000000000..620580dbbb0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lambda-var-hygiene.rs @@ -0,0 +1,13 @@ +// run-pass +// shouldn't affect evaluation of $ex: +macro_rules! bad_macro { + ($ex:expr) => ({(|_x| { $ex }) (9) }) +} + +fn takes_x(_x : isize) { + assert_eq!(bad_macro!(_x),8); +} +fn main() { + takes_x(8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lang-item-missing-generator.rs b/gcc/testsuite/rust/rustc/ui/lang-item-missing-generator.rs new file mode 100644 index 000000000000..ce5c558969fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lang-item-missing-generator.rs @@ -0,0 +1,20 @@ +// error-pattern: requires `generator` lang_item +#![feature(no_core, lang_items, unboxed_closures)] +#![no_core] + +#[lang = "sized"] pub trait Sized { } + +#[lang = "fn_once"] +#[rustc_paren_sugar] +pub trait FnOnce { + type Output; + + extern "rust-call" fn call_once(self, args: Args) -> Self::Output; +} + +pub fn abc() -> impl FnOnce(f32) { + |_| {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lang-item-missing.rs b/gcc/testsuite/rust/rustc/ui/lang-item-missing.rs new file mode 100644 index 000000000000..b9ce151aec03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lang-item-missing.rs @@ -0,0 +1,13 @@ +// Test that a missing lang item (in this case `sized`) does not cause an ICE, +// see #17392. + +// error-pattern: requires `sized` lang_item + +#![feature(start, no_core)] +#![no_core] + +#[start] +fn start(argc: isize, argv: *const *const u8) -> isize { + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/large-records.rs b/gcc/testsuite/rust/rustc/ui/large-records.rs new file mode 100644 index 000000000000..900900fa2afd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/large-records.rs @@ -0,0 +1,39 @@ +// run-pass + +#![allow(dead_code)] + + + + +// pretty-expanded FIXME #23616 + +struct Large {a: isize, + b: isize, + c: isize, + d: isize, + e: isize, + f: isize, + g: isize, + h: isize, + i: isize, + j: isize, + k: isize, + l: isize} +fn f() { + let _foo: Large = + Large {a: 0, + b: 0, + c: 0, + d: 0, + e: 0, + f: 0, + g: 0, + h: 0, + i: 0, + j: 0, + k: 0, + l: 0}; +} + +pub fn main() { f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/last-use-in-block.rs b/gcc/testsuite/rust/rustc/ui/last-use-in-block.rs new file mode 100644 index 000000000000..daccb0b1e252 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/last-use-in-block.rs @@ -0,0 +1,22 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_parens)] +// Issue #1818 + + +fn lp(s: String, mut f: F) -> T where F: FnMut(String) -> T { + while false { + let r = f(s); + return (r); + } + panic!(); +} + +fn apply(s: String, mut f: F) -> T where F: FnMut(String) -> T { + fn g(s: String, mut f: F) -> T where F: FnMut(String) -> T {f(s)} + g(s, |v| { let r = f(v); r }) +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/last-use-in-cap-clause.rs b/gcc/testsuite/rust/rustc/ui/last-use-in-cap-clause.rs new file mode 100644 index 000000000000..2321335e184a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/last-use-in-cap-clause.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(dead_code)] +// Make sure #1399 stays fixed + +struct A { a: Box } + +fn foo() -> Box isize + 'static> { + let k: Box<_> = Box::new(22); + let _u = A {a: k.clone()}; + let result = || 22; + Box::new(result) +} + +pub fn main() { + assert_eq!(foo()(), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/last-use-is-capture.rs b/gcc/testsuite/rust/rustc/ui/last-use-is-capture.rs new file mode 100644 index 000000000000..8a5d6bc4304a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/last-use-is-capture.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(dead_code)] +// Make sure #1399 stays fixed + +#![feature(box_syntax)] + +struct A { a: Box } + +pub fn main() { + fn invoke(f: F) where F: FnOnce() { f(); } + let k: Box<_> = box 22; + let _u = A {a: k.clone()}; + invoke(|| println!("{}", k.clone()) ) +} + diff --git a/gcc/testsuite/rust/rustc/ui/layout/debug.rs b/gcc/testsuite/rust/rustc/ui/layout/debug.rs new file mode 100644 index 000000000000..8b412bc9a872 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/layout/debug.rs @@ -0,0 +1,23 @@ +// normalize-stderr-test "pref: Align \{\n *pow2: [1-3],\n *\}" -> "pref: $$PREF_ALIGN" +#![feature(never_type, rustc_attrs, type_alias_impl_trait)] +#![crate_type = "lib"] + +#[rustc_layout(debug)] +enum E { Foo, Bar(!, i32, i32) } // { dg-error "" "" { target *-*-* } } + +#[rustc_layout(debug)] +struct S { f1: i32, f2: (), f3: i32 } // { dg-error "" "" { target *-*-* } } + +#[rustc_layout(debug)] +union U { f1: (i32, i32), f3: i32 } // { dg-error "" "" { target *-*-* } } + +#[rustc_layout(debug)] +type Test = Result; // { dg-error "" "" { target *-*-* } } + +#[rustc_layout(debug)] +type T = impl std::fmt::Debug; // { dg-error "" "" { target *-*-* } } + +fn f() -> T { + 0i32 +} + diff --git a/gcc/testsuite/rust/rustc/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs b/gcc/testsuite/rust/rustc/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs new file mode 100644 index 000000000000..a821fca0ed65 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs @@ -0,0 +1,37 @@ +#![feature(rustc_attrs)] + +// Show that `homogeneous_aggregate` code ignores zero-length C +// arrays. This matches the recent C standard, though not the +// behavior of all older compilers, which sometimes consider `T[0]` to +// be a "flexible array member" (see discussion on #56877 for +// details). + +#[repr(C)] +pub struct Foo { + x: u32 +} + +#[repr(C)] +pub struct Middle { + pub a: f32, + pub foo: [Foo; 0], + pub b: f32, +} + +#[rustc_layout(homogeneous_aggregate)] +pub type TestMiddle = Middle; +// { dg-error "" "" { target *-*-* } .-1 } + +#[repr(C)] +pub struct Final { + pub a: f32, + pub b: f32, + pub foo: [Foo; 0], +} + +#[rustc_layout(homogeneous_aggregate)] +pub type TestFinal = Final; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs b/gcc/testsuite/rust/rustc/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs new file mode 100644 index 000000000000..7c29775ecbcd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/layout/homogeneous-aggr-zero-sized-repr-rust.rs @@ -0,0 +1,74 @@ +#![feature(rustc_attrs)] + +// Regression test for #56877. We want to ensure that the presence of +// `PhantomData` does not prevent `Bar` from being considered a +// homogeneous aggregate. + +#[repr(C)] +pub struct BaseCase { + pub a: f32, + pub b: f32, +} + +#[repr(C)] +pub struct WithPhantomData { + pub a: f32, + pub b: f32, + pub _unit: std::marker::PhantomData<()>, +} + +pub struct EmptyRustStruct { +} + +#[repr(C)] +pub struct WithEmptyRustStruct { + pub a: f32, + pub b: f32, + pub _unit: EmptyRustStruct, +} + +pub struct TransitivelyEmptyRustStruct { + field: EmptyRustStruct, + array: [u32; 0], +} + +#[repr(C)] +pub struct WithTransitivelyEmptyRustStruct { + pub a: f32, + pub b: f32, + pub _unit: TransitivelyEmptyRustStruct, +} + +pub enum EmptyRustEnum { + Dummy, +} + +#[repr(C)] +pub struct WithEmptyRustEnum { + pub a: f32, + pub b: f32, + pub _unit: EmptyRustEnum, +} + +#[rustc_layout(homogeneous_aggregate)] +pub type Test1 = BaseCase; +// { dg-error "" "" { target *-*-* } .-1 } + +#[rustc_layout(homogeneous_aggregate)] +pub type Test2 = WithPhantomData; +// { dg-error "" "" { target *-*-* } .-1 } + +#[rustc_layout(homogeneous_aggregate)] +pub type Test3 = WithEmptyRustStruct; +// { dg-error "" "" { target *-*-* } .-1 } + +#[rustc_layout(homogeneous_aggregate)] +pub type Test4 = WithTransitivelyEmptyRustStruct; +// { dg-error "" "" { target *-*-* } .-1 } + +#[rustc_layout(homogeneous_aggregate)] +pub type Test5 = WithEmptyRustEnum; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/layout/issue-60431-unsized-tail-behind-projection.rs b/gcc/testsuite/rust/rustc/ui/layout/issue-60431-unsized-tail-behind-projection.rs new file mode 100644 index 000000000000..3e3ad30a2d24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/layout/issue-60431-unsized-tail-behind-projection.rs @@ -0,0 +1,36 @@ +// rust-lang/rust#60431: This is a scenario where to determine the size of +// `&Ref`, we need to know the concrete type of the last field in +// `Ref` (i.e. its "struct tail"), and determining that concrete type +// requires normalizing `Obstack::Dyn`. +// +// The old "struct tail" computation did not perform such normalization, and so +// the compiler would ICE when trying to figure out if `Ref` is a +// dynamically-sized type (DST). + +// run-pass + +use std::mem; + +pub trait Arena { + type Dyn : ?Sized; +} + +pub struct DynRef { + _dummy: [()], +} + +pub struct Ref { + _value: u8, + _dyn_arena: A::Dyn, +} + +pub struct Obstack; + +impl Arena for Obstack { + type Dyn = DynRef; +} + +fn main() { + assert_eq!(mem::size_of::<&Ref>(), mem::size_of::<&[()]>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/layout/unsafe-cell-hides-niche.rs b/gcc/testsuite/rust/rustc/ui/layout/unsafe-cell-hides-niche.rs new file mode 100644 index 000000000000..7b23f86c5abf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/layout/unsafe-cell-hides-niche.rs @@ -0,0 +1,33 @@ +// For rust-lang/rust#68303: the contents of `UnsafeCell` cannot +// participate in the niche-optimization for enum discriminants. This +// test checks that an `Option>` has the same +// size in memory as an `Option>` (namely, 8 bytes). + +// run-pass + +#![feature(no_niche)] + +use std::cell::UnsafeCell; +use std::mem::size_of; +use std::num::NonZeroU32 as N32; + +struct Wrapper(T); + +#[repr(transparent)] +struct Transparent(T); + +#[repr(no_niche)] +struct NoNiche(T); + +fn main() { + assert_eq!(size_of::>>(), 8); + assert_eq!(size_of::>>(), 4); + assert_eq!(size_of::>>(), 8); + assert_eq!(size_of::>>(), 4); + assert_eq!(size_of::>>(), 8); + assert_eq!(size_of::>>(), 8); + + assert_eq!(size_of::>>(), 8); + assert_eq!(size_of::>>(), 8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/layout/zero-sized-array-union.rs b/gcc/testsuite/rust/rustc/ui/layout/zero-sized-array-union.rs new file mode 100644 index 000000000000..d38efa7f4c72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/layout/zero-sized-array-union.rs @@ -0,0 +1,96 @@ +#![feature(rustc_attrs)] + +// Various tests around the behavior of zero-sized arrays and +// unions. This matches the behavior of modern C compilers, though +// older compilers (and sometimes clang) treat `T[0]` as a "flexible +// array member". See more +// details in #56877. + +#[derive(Copy, Clone)] +#[repr(C)] +struct Empty { } + +#[derive(Copy, Clone)] +#[repr(C)] +struct Empty2 { + e: Empty +} + +#[derive(Copy, Clone)] +#[repr(C)] +struct Empty3 { + z: [f32; 0], +} + +#[derive(Copy, Clone)] +#[repr(C)] +struct Empty4 { + e: Empty3 +} + +#[repr(C)] +union U1 { + s: Empty +} + +#[repr(C)] +union U2 { + s: Empty2 +} + +#[repr(C)] +union U3 { + s: Empty3 +} + +#[repr(C)] +union U4 { + s: Empty4 +} + +#[repr(C)] +struct Baz1 { + x: f32, + y: f32, + u: U1, +} + +#[rustc_layout(homogeneous_aggregate)] +type TestBaz1 = Baz1; +// { dg-error "" "" { target *-*-* } .-1 } + +#[repr(C)] +struct Baz2 { + x: f32, + y: f32, + u: U2, +} + +#[rustc_layout(homogeneous_aggregate)] +type TestBaz2 = Baz2; +// { dg-error "" "" { target *-*-* } .-1 } + +#[repr(C)] +struct Baz3 { + x: f32, + y: f32, + u: U3, +} + +#[rustc_layout(homogeneous_aggregate)] +type TestBaz3 = Baz3; +// { dg-error "" "" { target *-*-* } .-1 } + +#[repr(C)] +struct Baz4 { + x: f32, + y: f32, + u: U4, +} + +#[rustc_layout(homogeneous_aggregate)] +type TestBaz4 = Baz4; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lazy-and-or.rs b/gcc/testsuite/rust/rustc/ui/lazy-and-or.rs new file mode 100644 index 000000000000..e6eadfbc76ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lazy-and-or.rs @@ -0,0 +1,13 @@ +// run-pass + +fn incr(x: &mut isize) -> bool { *x += 1; assert!((false)); return false; } + +pub fn main() { + let x = 1 == 2 || 3 == 3; + assert!((x)); + let mut y: isize = 10; + println!("{}", x || incr(&mut y)); + assert_eq!(y, 10); + if true && x { assert!((true)); } else { assert!((false)); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lazy-init.rs b/gcc/testsuite/rust/rustc/ui/lazy-init.rs new file mode 100644 index 000000000000..a7176988f268 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lazy-init.rs @@ -0,0 +1,9 @@ +// run-pass + +#![allow(unused_mut)] + + +fn foo(x: isize) { println!("{}", x); } + +pub fn main() { let mut x: isize; if 1 > 2 { x = 12; } else { x = 10; } foo(x); } + diff --git a/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs b/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs new file mode 100644 index 000000000000..c9c978dfb7ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/feature-gate-lazy_normalization_consts.rs @@ -0,0 +1,11 @@ +pub const fn sof() -> usize { + 10 +} + +fn test() { + let _: [u8; sof::()]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/issue-47814.rs b/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/issue-47814.rs new file mode 100644 index 000000000000..787f60b19a94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/issue-47814.rs @@ -0,0 +1,17 @@ +// check-pass +#![feature(lazy_normalization_consts)] +#![allow(incomplete_features)] +pub struct ArpIPv4<'a> { + _s: &'a u8 +} + +impl<'a> ArpIPv4<'a> { + const LENGTH: usize = 20; + + pub fn to_buffer() -> [u8; Self::LENGTH] { + unimplemented!() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/issue-57739.rs b/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/issue-57739.rs new file mode 100644 index 000000000000..aea2b0ca97ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/issue-57739.rs @@ -0,0 +1,18 @@ +#![feature(lazy_normalization_consts)] +// { dg-warning "" "" { target *-*-* } .-1 } +trait ArraySizeTrait { + const SIZE: usize = 0; +} + +impl ArraySizeTrait for T { + const SIZE: usize = 1; +} + +struct SomeArray { + array: [u8; T::SIZE], +// { dg-error "" "" { target *-*-* } .-1 } + phantom: std::marker::PhantomData, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/issue-73980.rs b/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/issue-73980.rs new file mode 100644 index 000000000000..a060645ec9d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/issue-73980.rs @@ -0,0 +1,17 @@ +// check-pass +#![feature(lazy_normalization_consts)] +#![allow(incomplete_features)] + +pub struct X(P, Q); +pub struct L(T); + +impl L { + const S: usize = 1; +} + +impl X::S]> {} +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/trait-resolution-breakage.rs b/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/trait-resolution-breakage.rs new file mode 100644 index 000000000000..4aa910a42a7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/trait-resolution-breakage.rs @@ -0,0 +1,19 @@ +// check-pass + +trait Trait { + const ASSOC_CONST: usize = 0; +} + +impl Trait<()> for u8 {} + +// `u8::ASSOC_CONST` is resolved today, but will be ambiguous +// under lazy normalization. +fn foo() -> [(T, U); u8::ASSOC_CONST] +where + u8: Trait + Trait, +{ + todo!() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/unevaluated-consts.rs b/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/unevaluated-consts.rs new file mode 100644 index 000000000000..c9775e33cb0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lazy_normalization_consts/unevaluated-consts.rs @@ -0,0 +1,19 @@ +// check-pass + +// If we allow the parent generics here without using lazy normalization +// this results in a cycle error. +struct Foo(T, U); + +impl From<[u8; 1 + 1]> for Foo { + fn from(value: [u8; 1 + 1]) -> Foo { + todo!(); + } +} + +fn break_me() +where + [u8; 1 + 1]: From<[u8; 1 + 1]> +{} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/leak-unique-as-tydesc.rs b/gcc/testsuite/rust/rustc/ui/leak-unique-as-tydesc.rs new file mode 100644 index 000000000000..c7d6689fc090 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/leak-unique-as-tydesc.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +fn leaky(_t: T) { } + +pub fn main() { let x = box 10; leaky::>(x); } + diff --git a/gcc/testsuite/rust/rustc/ui/lex-bare-cr-nondoc-comment.rs b/gcc/testsuite/rust/rustc/ui/lex-bare-cr-nondoc-comment.rs new file mode 100644 index 000000000000..95dfefbf054e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lex-bare-cr-nondoc-comment.rs @@ -0,0 +1,10 @@ +// run-pass +// ignore-tidy-cr + +// nondoc comment with bare CR: ' ' +//// nondoc comment with bare CR: ' ' +/* block nondoc comment with bare CR: ' ' */ + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs b/gcc/testsuite/rust/rustc/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs new file mode 100644 index 000000000000..80ab0782cb40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lexer-crlf-line-endings-string-literal-doc-comment.rs @@ -0,0 +1,39 @@ +// run-pass +// ignore-tidy-cr +// ignore-tidy-cr (repeated again because of tidy bug) +// license is ignored because tidy can't handle the CRLF here properly. + +// N.B., this file needs CRLF line endings. The .gitattributes file in +// this directory should enforce it. + +// ignore-pretty issue #37195 + +/// Doc comment that ends in CRLF +pub fn foo() {} + +/** Block doc comment that + * contains CRLF characters + */ +pub fn bar() {} + +fn main() { + let s = "string +literal"; + assert_eq!(s, "string\nliteral"); + + let s = "literal with \ + escaped newline"; + assert_eq!(s, "literal with escaped newline"); + + let s = r"string +literal"; + assert_eq!(s, "string\nliteral"); + let s = br"byte string +literal"; + assert_eq!(s, "byte string\nliteral".as_bytes()); + + // validate that our source file has CRLF endings + let source = include_str!("lexer-crlf-line-endings-string-literal-doc-comment.rs"); + assert!(source.contains("string\r\nliteral")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lexical-scopes.rs b/gcc/testsuite/rust/rustc/ui/lexical-scopes.rs new file mode 100644 index 000000000000..1a2f7fd353f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lexical-scopes.rs @@ -0,0 +1,14 @@ +struct T { i: i32 } +fn f() { + let t = T { i: 0 }; // { dg-error ".E0574." "" { target *-*-* } } +} + +mod Foo { + pub fn f() {} +} +fn g() { + Foo::f(); // { dg-error ".E0599." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lexical-scoping.rs b/gcc/testsuite/rust/rustc/ui/lexical-scoping.rs new file mode 100644 index 000000000000..0049f7e2de75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lexical-scoping.rs @@ -0,0 +1,20 @@ +// run-pass +// Tests that items in subscopes can shadow type parameters and local variables (see issue #23880). + +#![allow(unused)] +struct Foo { x: Box } +impl Foo { + fn foo(&self) { + type Bar = i32; + let _: Bar = 42; + } +} + +fn main() { + let f = 1; + { + fn f() {} + f(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetime-before-type-params.rs b/gcc/testsuite/rust/rustc/ui/lifetime-before-type-params.rs new file mode 100644 index 000000000000..450511671895 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetime-before-type-params.rs @@ -0,0 +1,12 @@ +#![allow(unused)] +fn first() {} +// { dg-error "" "" { target *-*-* } .-1 } +fn second<'a, T, 'b>() {} +// { dg-error "" "" { target *-*-* } .-1 } +fn third() {} +// { dg-error "" "" { target *-*-* } .-1 } +fn fourth<'a, T, 'b, U, 'c, V>() {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetime_starts_expressions.rs b/gcc/testsuite/rust/rustc/ui/lifetime_starts_expressions.rs new file mode 100644 index 000000000000..519e5db4dd8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetime_starts_expressions.rs @@ -0,0 +1,14 @@ +fn foo() -> u32 { + return 'label: loop { break 'label 42; }; +} + +fn bar() -> u32 { + loop { break 'label: loop { break 'label 42; }; } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +pub fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/auxiliary/lifetime_bound_will_change_warning_lib.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/auxiliary/lifetime_bound_will_change_warning_lib.rs new file mode 100644 index 000000000000..154de164f3d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/auxiliary/lifetime_bound_will_change_warning_lib.rs @@ -0,0 +1,12 @@ +#![crate_type = "rlib"] + +// Helper for testing that we get suitable warnings when lifetime +// bound change will cause breakage. + +pub fn just_ref(x: &Fn()) { +} + +pub fn ref_obj(x: &Box) { + // this will change to &Box... +} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/borrowck-let-suggestion.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/borrowck-let-suggestion.rs new file mode 100644 index 000000000000..85fff16f7e54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/borrowck-let-suggestion.rs @@ -0,0 +1,13 @@ +fn f() { + let mut x = vec![1].iter(); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + x.use_mut(); +} + +fn main() { + f(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/issue-34979.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/issue-34979.rs new file mode 100644 index 000000000000..0130f9f51db3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/issue-34979.rs @@ -0,0 +1,10 @@ +trait Foo {} +impl<'a, T> Foo for &'a T {} + +struct Ctx<'a>(&'a ()) +where + &'a (): Foo, // { dg-error ".E0283." "" { target *-*-* } } + &'static (): Foo; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/issue-70917-lifetimes-in-fn-def.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/issue-70917-lifetimes-in-fn-def.rs new file mode 100644 index 000000000000..7411d7f2a51e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/issue-70917-lifetimes-in-fn-def.rs @@ -0,0 +1,14 @@ +// check-pass + +fn assert_static(_: T) {} + +// NOTE(eddyb) the `'a: 'a` may look a bit strange, but we *really* want +// `'a` to be an *early-bound* parameter, otherwise it doesn't matter anyway. +fn capture_lifetime<'a: 'a>() {} + +fn test_lifetime<'a>() { + assert_static(capture_lifetime::<'a>); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-bound-will-change-warning.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-bound-will-change-warning.rs new file mode 100644 index 000000000000..91dcc495d596 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-bound-will-change-warning.rs @@ -0,0 +1,55 @@ +// aux-build:lifetime_bound_will_change_warning_lib.rs + +// Test that various corner cases cause an error. These are tests +// that used to pass before we tweaked object defaults. + +#![allow(dead_code)] +#![allow(unused_variables)] + + +extern crate lifetime_bound_will_change_warning_lib as lib; + +fn just_ref(x: &dyn Fn()) { +} + +fn ref_obj(x: &Box) { + // this will change to &Box... + + // Note: no warning is issued here, because the type of `x` will change to 'static + if false { ref_obj(x); } +} + +fn test1<'a>(x: &'a Box) { + // just_ref will stay the same. + just_ref(&**x) +} + +fn test1cc<'a>(x: &'a Box) { + // same as test1, but cross-crate + lib::just_ref(&**x) +} + +fn test2<'a>(x: &'a Box) { + // but ref_obj will not, so warn. + ref_obj(x) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn test2cc<'a>(x: &'a Box) { + // same as test2, but cross crate + lib::ref_obj(x) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn test3<'a>(x: &'a Box) { + // here, we have a 'static bound, so even when ref_obj changes, no error results + ref_obj(x) +} + +fn test3cc<'a>(x: &'a Box) { + // same as test3, but cross crate + lib::ref_obj(x) +} + + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-doesnt-live-long-enough.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-doesnt-live-long-enough.rs new file mode 100644 index 000000000000..6d8db4a7f8bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-doesnt-live-long-enough.rs @@ -0,0 +1,50 @@ +trait ListItem<'a> { + fn list_name() -> &'a str; +} + +trait Collection { fn len(&self) -> usize; } + +// is now well formed. RFC 2093 +struct List<'a, T: ListItem<'a>> { + slice: &'a [T] +} + +impl<'a, T: ListItem<'a>> Collection for List<'a, T> { + fn len(&self) -> usize { + 0 + } +} + +struct Foo { + foo: &'static T +// { dg-error ".E0310." "" { target *-*-* } .-1 } +} + +trait X: Sized { + fn foo<'a, L: X<&'a Nested>>(); +// { dg-error ".E0309." "" { target *-*-* } .-1 } + + // check that we give a sane error for `Self` + fn bar<'a, L: X<&'a Nested>>(); +// { dg-error ".E0309." "" { target *-*-* } .-1 } + + // check that we give a sane error for nested generics + fn baz<'a, L, M: X<&'a Nested>>() { +// { dg-error ".E0309." "" { target *-*-* } .-1 } + } +} + +trait TraitB {} + +struct Nested(K); +impl Nested { + fn generic_in_parent<'a, L: X<&'a Nested>>() { +// { dg-error ".E0309." "" { target *-*-* } .-1 } + } + fn generic_in_child<'a, 'b, L: X<&'a Nested>, M: 'b>() { +// { dg-error ".E0309." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs new file mode 100644 index 000000000000..f3256da04c72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs @@ -0,0 +1,46 @@ +// Lifetime annotation needed because we have no arguments. +fn f() -> &isize { // { dg-error ".E0106." "" { target *-*-* } } + panic!() +} + +// Lifetime annotation needed because we have two by-reference parameters. +fn g(_x: &isize, _y: &isize) -> &isize { // { dg-error ".E0106." "" { target *-*-* } } + panic!() +} + +struct Foo<'a> { + x: &'a isize, +} + +// Lifetime annotation needed because we have two lifetimes: one as a parameter +// and one on the reference. +fn h(_x: &Foo) -> &isize { // { dg-error ".E0106." "" { target *-*-* } } + panic!() +} + +fn i(_x: isize) -> &isize { // { dg-error ".E0106." "" { target *-*-* } } + panic!() +} + +// Cases which used to work but now don't. + +type StaticStr = &'static str; // hides 'static +trait WithLifetime<'a> { + type Output; // can hide 'a +} + +// This worked because the type of the first argument contains +// 'static, although StaticStr doesn't even have parameters. +fn j(_x: StaticStr) -> &isize { // { dg-error ".E0106." "" { target *-*-* } } + panic!() +} + +// This worked because the compiler resolved the argument type +// to >::Output which has the hidden 'a. +fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize { +// { dg-error ".E0106." "" { target *-*-* } .-1 } + panic!() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-elision-return-type-trait.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-elision-return-type-trait.rs new file mode 100644 index 000000000000..534d3d5efd0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-elision-return-type-trait.rs @@ -0,0 +1,14 @@ +trait Future { + type Item; + type Error; +} + +use std::error::Error; + +fn foo() -> impl Future> { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + Ok(()) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs new file mode 100644 index 000000000000..2dc442e71951 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs @@ -0,0 +1,15 @@ +struct Foo { + field: i32, +} + +fn foo2<'a>(a: &'a Foo, x: &i32) -> &'a i32 { + if true { + let p: &i32 = &a.field; + &*p + } else { + &*x // { dg-error ".E0621." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs new file mode 100644 index 000000000000..3c0be7241499 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs @@ -0,0 +1,21 @@ +#[derive(Clone)] +enum Foo<'a> { + Bar(&'a str), +} + +impl<'a> Foo<'a> { + fn bar(&self, other: Foo) -> Foo<'a> { + match *self { + Foo::Bar(s) => { + if s == "test" { + other // { dg-error ".E0621." "" { target *-*-* } } + } else { + self.clone() + } + } + } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs new file mode 100644 index 000000000000..2583802d7a3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs @@ -0,0 +1,6 @@ +fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { + if x > y { x } else { y } // { dg-error ".E0621." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs new file mode 100644 index 000000000000..01417bb63891 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs @@ -0,0 +1,6 @@ +fn foo<'a>((x, y): (&'a i32, &i32)) -> &'a i32 { + if x > y { x } else { y } // { dg-error ".E0621." "" { target *-*-* } } +} + +fn main () { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs new file mode 100644 index 000000000000..a2f0bc4044cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs @@ -0,0 +1,9 @@ +trait Foo { + +fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { + if x > y { x } else { y } // { dg-error ".E0621." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs new file mode 100644 index 000000000000..6db4c5c5ff24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs @@ -0,0 +1,15 @@ +struct Foo { + field: i32 +} + +impl Foo { + fn foo<'a>(&'a self, x: &i32) -> &i32 { + + if true { &self.field } else { x } // { dg-error ".E0621." "" { target *-*-* } } + + } + +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs new file mode 100644 index 000000000000..e9f7e0a628b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs @@ -0,0 +1,18 @@ +trait Foo { + + fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32; + +} + +impl Foo for () { + + fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { + + if x > y { x } else { y } // { dg-error ".E0623." "" { target *-*-* } } + + } + +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs new file mode 100644 index 000000000000..e84abfe5c87a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs @@ -0,0 +1,6 @@ +fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { + if x > y { x } else { y } // { dg-error ".E0621." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs new file mode 100644 index 000000000000..5a241d05e0c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs @@ -0,0 +1,15 @@ +struct Foo { + field: i32 +} + +impl Foo { + fn foo<'a>(&self, x: &'a i32) -> &i32 { + + x // { dg-error ".E0623." "" { target *-*-* } } + + } + +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs new file mode 100644 index 000000000000..82dfecf70a2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs @@ -0,0 +1,14 @@ +struct Foo { + field: i32, +} + +impl Foo { + fn foo<'a>(&self, x: &'a Foo) -> &'a Foo { + + if true { x } else { self } // { dg-error ".E0623." "" { target *-*-* } } + + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs new file mode 100644 index 000000000000..6bc6fe754a3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs @@ -0,0 +1,6 @@ +fn foo(x: &i32, y: &i32) -> &i32 { // { dg-error ".E0106." "" { target *-*-* } } + if x > y { x } else { y } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs new file mode 100644 index 000000000000..31f506f83dc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs @@ -0,0 +1,10 @@ +struct Ref<'a, T: 'a> { + data: &'a T +} + +fn foo<'a>(x: Ref, y: &mut Vec>) { + y.push(x); // { dg-error ".E0621." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs new file mode 100644 index 000000000000..dff7885dcf77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs @@ -0,0 +1,12 @@ +trait Foo<'a> {} +impl<'a, T> Foo<'a> for T {} + +fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &T) + where i32: Foo<'a>, + u32: Foo<'b> +{ + x.push(y); // { dg-error ".E0621." "" { target *-*-* } } +} +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs new file mode 100644 index 000000000000..945023783b2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs @@ -0,0 +1,10 @@ +struct Ref<'a, T: 'a> { + data: &'a T +} + +fn foo<'a>(x: &mut Vec>, y: Ref) { + x.push(y); // { dg-error ".E0621." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs new file mode 100644 index 000000000000..2f6144d27db1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs @@ -0,0 +1,10 @@ +struct Ref<'a, T: 'a> { + data: &'a T +} + +fn foo(x: &mut Vec>, y: Ref) { + x.push(y); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs new file mode 100644 index 000000000000..9bc5b250cc18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs @@ -0,0 +1,11 @@ +struct Ref<'a, T: 'a> { + data: &'a T +} + +fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + let z = Ref { data: y.data }; + x.push(z); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs new file mode 100644 index 000000000000..91cf100a3831 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs @@ -0,0 +1,12 @@ +struct Ref<'a, T: 'a> { + data: &'a T +} + +fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + let a: &mut Vec> = x; // { dg-error ".E0623." "" { target *-*-* } } + let b = Ref { data: y.data }; + a.push(b); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs new file mode 100644 index 000000000000..8c354471859e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs @@ -0,0 +1,12 @@ +struct Ref<'a, T: 'a> { + data: &'a T +} + +fn foo<'a, 'b, 'c>(x: &'a mut Vec>, y: Ref<'c, i32>) { + let a: &mut Vec> = x; // { dg-error ".E0623." "" { target *-*-* } } + let b = Ref { data: y.data }; + Vec::push(a, b); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs new file mode 100644 index 000000000000..3c7fe62630e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs @@ -0,0 +1,6 @@ +fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) { + *v = x; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs new file mode 100644 index 000000000000..d7b0d3a8d359 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs @@ -0,0 +1,7 @@ +fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { + z.push((x,y)); // { dg-error ".E0623." "" { target *-*-* } } +// { dg-error ".E0623." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs new file mode 100644 index 000000000000..ec10cfb47719 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs @@ -0,0 +1,11 @@ +struct Ref<'a, 'b> { + a: &'a u32, + b: &'b u32, +} + +fn foo(mut x: Ref, y: Ref) { + x.b = y.b; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs new file mode 100644 index 000000000000..6284ae3f0659 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs @@ -0,0 +1,11 @@ +struct Ref<'a, 'b> { + a: &'a u32, + b: &'b u32, +} + +fn foo(mut x: Ref) { + x.a = x.b; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs new file mode 100644 index 000000000000..abe0d4ba17fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs @@ -0,0 +1,13 @@ +struct Ref<'a> { + x: &'a u32, +} + +fn foo<'a, 'b>(mut x: Vec>, y: Ref<'b>) + where &'a (): Sized, + &'b u32: Sized +{ + x.push(y); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs new file mode 100644 index 000000000000..cff379beab86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs @@ -0,0 +1,10 @@ +struct Ref<'a> { + x: &'a u32, +} + +fn foo<'a, 'b>(mut x: Vec>, y: Ref<'b>) { + x.push(y); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs new file mode 100644 index 000000000000..455492286d2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs @@ -0,0 +1,10 @@ +struct Ref<'a> { + x: &'a u32, +} + +fn foo(mut x: Vec, y: Ref) { + x.push(y); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs new file mode 100644 index 000000000000..7f7dc910b0e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs @@ -0,0 +1,6 @@ +fn foo<'a,'b>(x: &mut Vec<&'a u8>, y: &'b u8) { + x.push(y); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs new file mode 100644 index 000000000000..4d488ba4fe71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs @@ -0,0 +1,8 @@ +struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 } + +fn foo(mut x: Ref, y: &u32) { + y = x.b; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs new file mode 100644 index 000000000000..fa0903eac1f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs @@ -0,0 +1,8 @@ +struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 } + +fn foo(mut y: Ref, x: &u32) { + y.b = x; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs new file mode 100644 index 000000000000..fa0903eac1f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs @@ -0,0 +1,8 @@ +struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 } + +fn foo(mut y: Ref, x: &u32) { + y.b = x; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs new file mode 100644 index 000000000000..35252d48148d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs @@ -0,0 +1,11 @@ +struct Ref<'a, 'b> { + a: &'a u32, + b: &'b u32, +} + +fn foo(mut x: Ref, y: &u32) { + x.b = y; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs new file mode 100644 index 000000000000..bfa9dc58e7fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs @@ -0,0 +1,12 @@ +struct Foo { + field: i32 +} + +impl Foo { + fn foo<'a>(&self, x: &i32) -> &i32 { + x // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs new file mode 100644 index 000000000000..595e0c14d423 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs @@ -0,0 +1,12 @@ +struct Foo { + field: i32, +} + +impl Foo { + fn foo<'a>(&self, x: &Foo) -> &Foo { + if true { x } else { self } // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs new file mode 100644 index 000000000000..0fba0106ab16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs @@ -0,0 +1,6 @@ +fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) { + y.push(z); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs new file mode 100644 index 000000000000..06a5c788f88a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs @@ -0,0 +1,10 @@ +trait Foo { + fn foo<'a>(x: &mut Vec<&u8>, y: &u8); +} +impl Foo for () { + fn foo(x: &mut Vec<&u8>, y: &u8) { + x.push(y); // { dg-error ".E0623." "" { target *-*-* } } + } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs new file mode 100644 index 000000000000..6b3a90c55627 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs @@ -0,0 +1,6 @@ +fn foo(x:Box , y: Vec<&u8>, z: &u8) { + y.push(z); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs new file mode 100644 index 000000000000..271d66589004 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs @@ -0,0 +1,6 @@ +fn foo(x: &mut Vec<&u8>, y: &u8) { + x.push(y); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs new file mode 100644 index 000000000000..002ecf73d9e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs @@ -0,0 +1,38 @@ +// Check notes are placed on an assignment that can actually precede the current assignment +// Don't emit a first assignment for assignment in a loop. + +fn test() { + let x; + if true { + x = 1; + } else { + x = 2; + x = 3; // { dg-error ".E0384." "" { target *-*-* } } + } +} + +fn test_in_loop() { + loop { + let x; + if true { + x = 1; + } else { + x = 2; + x = 3; // { dg-error ".E0384." "" { target *-*-* } } + } + } +} + +fn test_using_loop() { + let x; + loop { + if true { + x = 1; // { dg-error ".E0384." "" { target *-*-* } } + } else { + x = 2; // { dg-error ".E0384." "" { target *-*-* } } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs new file mode 100644 index 000000000000..0b8ec2cf9991 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs @@ -0,0 +1,13 @@ +trait Foo { + fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32; +} + +impl Foo for () { + fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { +// { dg-error "" "" { target *-*-* } .-1 } + if x > y { x } else { y } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-no-keyword.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-no-keyword.rs new file mode 100644 index 000000000000..acc3c650c78b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/lifetime-no-keyword.rs @@ -0,0 +1,8 @@ +fn foo<'a>(a: &'a isize) { } +fn bar(a: &'static isize) { } +fn baz<'let>(a: &'let isize) { } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +fn zab<'self>(a: &'self isize) { } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs b/gcc/testsuite/rust/rustc/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs new file mode 100644 index 000000000000..41db891d04b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs @@ -0,0 +1,4 @@ +fn main() { + [0].iter().flat_map(|a| [0].iter().map(|_| &a)); // { dg-error ".E0373." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/link-cfg-works.rs b/gcc/testsuite/rust/rustc/ui/link-cfg-works.rs new file mode 100644 index 000000000000..253878dae0f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/link-cfg-works.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:link-cfg-works-transitive-rlib.rs +// aux-build:link-cfg-works-transitive-dylib.rs + +#![feature(link_cfg)] + +extern crate link_cfg_works_transitive_rlib; +extern crate link_cfg_works_transitive_dylib; + +#[link(name = "foo", cfg(foo))] +extern {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/link-section.rs b/gcc/testsuite/rust/rustc/ui/link-section.rs new file mode 100644 index 000000000000..7fa67efe7df9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/link-section.rs @@ -0,0 +1,38 @@ +// run-pass + +#![allow(non_upper_case_globals)] +#[cfg(not(target_os = "macos"))] +#[link_section=".moretext"] +fn i_live_in_more_text() -> &'static str { + "knock knock" +} + +#[cfg(not(target_os = "macos"))] +#[link_section=".imm"] +static magic: usize = 42; + +#[cfg(not(target_os = "macos"))] +#[link_section=".mut"] +static mut frobulator: usize = 0xdeadbeef; + +#[cfg(target_os = "macos")] +#[link_section="__TEXT,__moretext"] +fn i_live_in_more_text() -> &'static str { + "knock knock" +} + +#[cfg(target_os = "macos")] +#[link_section="__RODATA,__imm"] +static magic: usize = 42; + +#[cfg(target_os = "macos")] +#[link_section="__DATA,__mut"] +static mut frobulator: usize = 0xdeadbeef; + +pub fn main() { + unsafe { + frobulator = 0xcafebabe; + println!("{} {} {}", i_live_in_more_text(), magic, frobulator); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/linkage-attr/auxiliary/def_colliding_external.rs b/gcc/testsuite/rust/rustc/ui/linkage-attr/auxiliary/def_colliding_external.rs new file mode 100644 index 000000000000..63f4151b6808 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/linkage-attr/auxiliary/def_colliding_external.rs @@ -0,0 +1,8 @@ +#![feature(linkage)] +#![crate_type = "lib"] + +extern { + #[linkage="external"] + pub static collision: *const i32; +} + diff --git a/gcc/testsuite/rust/rustc/ui/linkage-attr/auxiliary/def_illtyped_external.rs b/gcc/testsuite/rust/rustc/ui/linkage-attr/auxiliary/def_illtyped_external.rs new file mode 100644 index 000000000000..51cf9b1a6010 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/linkage-attr/auxiliary/def_illtyped_external.rs @@ -0,0 +1,6 @@ +#![feature(linkage)] +#![crate_type = "lib"] + +#[linkage="external"] +pub static EXTERN: u32 = 0; + diff --git a/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage-detect-extern-generated-name-collision.rs b/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage-detect-extern-generated-name-collision.rs new file mode 100644 index 000000000000..146bd5f85958 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage-detect-extern-generated-name-collision.rs @@ -0,0 +1,23 @@ +// rust-lang/rust#61232: We used to ICE when trying to detect a +// collision on the symbol generated for the external linkage item in +// an extern crate. + +// build-fail +// aux-build:def_colliding_external.rs + +extern crate def_colliding_external as dep1; + +#[no_mangle] +pub static _rust_extern_with_linkage_collision: i32 = 0; + +mod dep2 { + #[no_mangle] + pub static collision: usize = 0; +} + +fn main() { + unsafe { + println!("{:p}", &dep1::collision); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage-detect-local-generated-name-collision.rs b/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage-detect-local-generated-name-collision.rs new file mode 100644 index 000000000000..dd442825b7c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage-detect-local-generated-name-collision.rs @@ -0,0 +1,26 @@ +// build-fail + +#![feature(linkage)] + +mod dep1 { + extern { + #[linkage="external"] + #[no_mangle] + pub static collision: *const i32; // { dg-error "" "" { target *-*-* } } + } +} + +#[no_mangle] +pub static _rust_extern_with_linkage_collision: i32 = 0; + +mod dep2 { + #[no_mangle] + pub static collision: usize = 0; +} + +fn main() { + unsafe { + println!("{:p}", &dep1::collision); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage-requires-raw-ptr.rs b/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage-requires-raw-ptr.rs new file mode 100644 index 000000000000..b67f1c49ee01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage-requires-raw-ptr.rs @@ -0,0 +1,12 @@ +// rust-lang/rust#59548: We used to ICE when trying to use a static +// with a type that violated its own `#[linkage]`. + +// build-fail +// aux-build:def_illtyped_external.rs + +extern crate def_illtyped_external as dep; + +fn main() { + println!("{:p}", &dep::EXTERN); +} + diff --git a/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage2.rs b/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage2.rs new file mode 100644 index 000000000000..02f42b70d013 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage2.rs @@ -0,0 +1,18 @@ +// FIXME https://github.com/rust-lang/rust/issues/59774 + +// build-fail +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +// ignore-sgx no weak linkages permitted + +#![feature(linkage)] + +extern { + #[linkage = "extern_weak"] static foo: i32; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + println!("{}", unsafe { foo }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage3.rs b/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage3.rs new file mode 100644 index 000000000000..76fd9add8d04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage3.rs @@ -0,0 +1,17 @@ +// FIXME https://github.com/rust-lang/rust/issues/59774 + +// check-fail +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" + +#![feature(linkage)] + +extern { + #[linkage = "foo"] static foo: *const i32; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + println!("{:?}", unsafe { foo }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage4.rs b/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage4.rs new file mode 100644 index 000000000000..1aa5dabd0f99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/linkage-attr/linkage4.rs @@ -0,0 +1,6 @@ +#[linkage = "external"] +static foo: isize = 0; +// { dg-error ".E0658." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/linkage1.rs b/gcc/testsuite/rust/rustc/ui/linkage1.rs new file mode 100644 index 000000000000..7926dba8ed24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/linkage1.rs @@ -0,0 +1,33 @@ +// run-pass +// ignore-windows +// ignore-macos +// ignore-emscripten doesn't support this linkage +// ignore-sgx weak linkage not permitted +// aux-build:linkage1.rs + +#![feature(linkage)] + +extern crate linkage1 as other; + +extern { + #[linkage = "extern_weak"] + static foo: *const isize; + #[linkage = "extern_weak"] + static something_that_should_never_exist: *mut isize; +} + +fn main() { + // It appears that the --as-needed flag to linkers will not pull in a dynamic + // library unless it satisfies a non weak undefined symbol. The 'other' crate + // is compiled as a dynamic library where it would only be used for a + // weak-symbol as part of an executable, so the dynamic library would be + // discarded. By adding and calling `other::bar`, we get around this problem. + other::bar(); + + unsafe { + assert!(!foo.is_null()); + assert_eq!(*foo, 3); + assert!(something_that_should_never_exist.is_null()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint-cap.rs b/gcc/testsuite/rust/rustc/ui/lint-cap.rs new file mode 100644 index 000000000000..0dc80cc1d7da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint-cap.rs @@ -0,0 +1,9 @@ +// run-pass +// compile-flags: --cap-lints allow + +#![deny(warnings)] + +use std::option; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint-expr-stmt-attrs-for-early-lints.rs b/gcc/testsuite/rust/rustc/ui/lint-expr-stmt-attrs-for-early-lints.rs new file mode 100644 index 000000000000..f0ae022949a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint-expr-stmt-attrs-for-early-lints.rs @@ -0,0 +1,15 @@ +// run-pass + +#![feature(stmt_expr_attributes)] +#![deny(unused_parens)] + +// Tests that lint attributes on statements/expressions are +// correctly applied to non-builtin early (AST) lints + +fn main() { + #[allow(unused_parens)] + { + let _ = (9); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint-unknown-lints-at-crate-level.rs b/gcc/testsuite/rust/rustc/ui/lint-unknown-lints-at-crate-level.rs new file mode 100644 index 000000000000..6bbd742d5e3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint-unknown-lints-at-crate-level.rs @@ -0,0 +1,8 @@ +// run-pass +// compile-flags: -D warnings -D unknown-lints + +#![allow(unknown_lints)] +#![allow(random_lint_name)] + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/external_extern_fn.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/external_extern_fn.rs new file mode 100644 index 000000000000..367d2b5c435c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/external_extern_fn.rs @@ -0,0 +1,4 @@ +extern "C" { + pub fn extern_fn(x: u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/inherited_stability.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/inherited_stability.rs new file mode 100644 index 000000000000..30278c409368 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/inherited_stability.rs @@ -0,0 +1,48 @@ +#![crate_name="inherited_stability"] +#![crate_type = "lib"] +#![unstable(feature = "unstable_test_feature", issue = "none")] +#![feature(staged_api)] + +pub fn unstable() {} + +#[stable(feature = "rust1", since = "1.0.0")] +pub fn stable() {} + +#[stable(feature = "rust1", since = "1.0.0")] +pub mod stable_mod { + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub fn unstable() {} + + #[stable(feature = "rust1", since = "1.0.0")] + pub fn stable() {} +} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub mod unstable_mod { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn deprecated() {} + + pub fn unstable() {} +} + +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Stable { + #[unstable(feature = "unstable_test_feature", issue = "none")] + fn unstable(&self); + + #[stable(feature = "rust1", since = "1.0.0")] + fn stable(&self); +} + +impl Stable for usize { + fn unstable(&self) {} + fn stable(&self) {} +} + +pub enum Unstable { + UnstableVariant, + #[stable(feature = "rust1", since = "1.0.0")] + StableVariant +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_output_format.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_output_format.rs new file mode 100644 index 000000000000..531158f51f70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_output_format.rs @@ -0,0 +1,21 @@ +#![crate_name="lint_output_format"] +#![crate_type = "lib"] +#![feature(staged_api)] +#![unstable(feature = "unstable_test_feature", issue = "none")] + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub fn foo() -> usize { + 20 +} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub fn bar() -> usize { + 40 +} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub fn baz() -> usize { + 30 +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_stability.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_stability.rs new file mode 100644 index 000000000000..6e8d41ed1aa7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_stability.rs @@ -0,0 +1,189 @@ +#![crate_name="lint_stability"] +#![crate_type = "lib"] +#![feature(staged_api)] +#![feature(associated_type_defaults)] +#![stable(feature = "lint_stability", since = "1.0.0")] + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub fn deprecated() {} +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub fn deprecated_text() {} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "99.99.99", reason = "text")] +pub fn deprecated_future() {} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub fn deprecated_unstable() {} +#[unstable(feature = "unstable_test_feature", issue = "none")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub fn deprecated_unstable_text() {} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub fn unstable() {} +#[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] +pub fn unstable_text() {} + +#[stable(feature = "rust1", since = "1.0.0")] +pub fn stable() {} +#[stable(feature = "rust1", since = "1.0.0")] +pub fn stable_text() {} + +#[stable(feature = "rust1", since = "1.0.0")] +pub struct MethodTester; + +impl MethodTester { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated(&self) {} + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated_unstable_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub fn method_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + pub fn method_unstable_text(&self) {} + + #[stable(feature = "rust1", since = "1.0.0")] + pub fn method_stable(&self) {} + #[stable(feature = "rust1", since = "1.0.0")] + pub fn method_stable_text(&self) {} +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub trait Trait { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated(&self) {} + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated_unstable_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + fn trait_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + fn trait_unstable_text(&self) {} + + #[stable(feature = "rust1", since = "1.0.0")] + fn trait_stable(&self) {} + #[stable(feature = "rust1", since = "1.0.0")] + fn trait_stable_text(&self) {} +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub trait TraitWithAssociatedTypes { + #[unstable(feature = "unstable_test_feature", issue = "none")] + type TypeUnstable = u8; + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + type TypeDeprecated = u8; +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +impl Trait for MethodTester {} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub trait UnstableTrait { fn dummy(&self) { } } + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub trait DeprecatedTrait { + #[stable(feature = "stable_test_feature", since = "1.0.0")] fn dummy(&self) { } +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct DeprecatedStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize +} +#[unstable(feature = "unstable_test_feature", issue = "none")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct DeprecatedUnstableStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize +} +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct UnstableStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize +} +#[stable(feature = "rust1", since = "1.0.0")] +pub struct StableStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] pub i: isize +} +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub enum UnstableEnum {} +#[stable(feature = "rust1", since = "1.0.0")] +pub enum StableEnum {} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct DeprecatedUnitStruct; +#[unstable(feature = "unstable_test_feature", issue = "none")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct DeprecatedUnstableUnitStruct; +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct UnstableUnitStruct; +#[stable(feature = "rust1", since = "1.0.0")] +pub struct StableUnitStruct; + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub enum Enum { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + DeprecatedVariant, + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + DeprecatedUnstableVariant, + #[unstable(feature = "unstable_test_feature", issue = "none")] + UnstableVariant, + + #[stable(feature = "rust1", since = "1.0.0")] + StableVariant, +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct DeprecatedTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize); +#[unstable(feature = "unstable_test_feature", issue = "none")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct DeprecatedUnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize); +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct UnstableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize); +#[stable(feature = "rust1", since = "1.0.0")] +pub struct StableTupleStruct(#[stable(feature = "rust1", since = "1.0.0")] pub isize); + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[macro_export] +macro_rules! macro_test { + () => (deprecated()); +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[macro_export] +macro_rules! macro_test_arg { + ($func:expr) => ($func); +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +#[macro_export] +macro_rules! macro_test_arg_nested { + ($func:ident) => (macro_test_arg!($func())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_stability_fields.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_stability_fields.rs new file mode 100644 index 000000000000..87722552b622 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_stability_fields.rs @@ -0,0 +1,52 @@ +#![feature(staged_api)] +#![stable(feature = "rust1", since = "1.0.0")] + +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Stable { + #[stable(feature = "rust1", since = "1.0.0")] + pub inherit: u8, // it's a lie (stable doesn't inherit) + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub override1: u8, + #[rustc_deprecated(since = "1.0.0", reason = "text")] + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub override2: u8, +} + +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Stable2(#[stable(feature = "rust1", since = "1.0.0")] pub u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] pub u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] pub u8); + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct Unstable { + pub inherit: u8, + #[stable(feature = "rust1", since = "1.0.0")] + pub override1: u8, + #[rustc_deprecated(since = "1.0.0", reason = "text")] + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub override2: u8, +} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct Unstable2(pub u8, + #[stable(feature = "rust1", since = "1.0.0")] pub u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] pub u8); + +#[unstable(feature = "unstable_test_feature", issue = "none")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct Deprecated { + pub inherit: u8, + #[stable(feature = "rust1", since = "1.0.0")] + pub override1: u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub override2: u8, +} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +#[rustc_deprecated(since = "1.0.0", reason = "text")] +pub struct Deprecated2(pub u8, + #[stable(feature = "rust1", since = "1.0.0")] pub u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] pub u8); + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate.rs new file mode 100644 index 000000000000..44e36138cbda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate.rs @@ -0,0 +1,2 @@ +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate2.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate2.rs new file mode 100644 index 000000000000..44e36138cbda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate2.rs @@ -0,0 +1,2 @@ +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate3.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate3.rs new file mode 100644 index 000000000000..44e36138cbda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate3.rs @@ -0,0 +1,2 @@ +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate4.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate4.rs new file mode 100644 index 000000000000..c84c7b394dc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate4.rs @@ -0,0 +1,2 @@ +// intentionally empty + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate5.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate5.rs new file mode 100644 index 000000000000..c84c7b394dc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lint_unused_extern_crate5.rs @@ -0,0 +1,2 @@ +// intentionally empty + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lints-in-foreign-macros.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lints-in-foreign-macros.rs new file mode 100644 index 000000000000..41f5caca3a44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/lints-in-foreign-macros.rs @@ -0,0 +1,15 @@ +#[macro_export] +macro_rules! bar { + () => {use std::string::ToString;} +} + +#[macro_export] +macro_rules! baz { + ($i:item) => ($i) +} + +#[macro_export] +macro_rules! baz2 { + ($($i:tt)*) => ($($i)*) +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/stability-cfg2.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/stability-cfg2.rs new file mode 100644 index 000000000000..eaa1d1f9f89c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/stability-cfg2.rs @@ -0,0 +1,6 @@ +// compile-flags:--cfg foo + +#![cfg_attr(foo, unstable(feature = "unstable_test_feature", issue = "none"))] +#![cfg_attr(not(foo), stable(feature = "test_feature", since = "1.0.0"))] +#![feature(staged_api)] + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/stability_cfg1.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/stability_cfg1.rs new file mode 100644 index 000000000000..c0747e4bb963 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/stability_cfg1.rs @@ -0,0 +1,4 @@ +#![cfg_attr(foo, experimental)] +#![cfg_attr(not(foo), stable(feature = "test_feature", since = "1.0.0"))] +#![feature(staged_api)] + diff --git a/gcc/testsuite/rust/rustc/ui/lint/auxiliary/stability_cfg2.rs b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/stability_cfg2.rs new file mode 100644 index 000000000000..eaa1d1f9f89c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/auxiliary/stability_cfg2.rs @@ -0,0 +1,6 @@ +// compile-flags:--cfg foo + +#![cfg_attr(foo, unstable(feature = "unstable_test_feature", issue = "none"))] +#![cfg_attr(not(foo), stable(feature = "test_feature", since = "1.0.0"))] +#![feature(staged_api)] + diff --git a/gcc/testsuite/rust/rustc/ui/lint/clashing-extern-fn-recursion.rs b/gcc/testsuite/rust/rustc/ui/lint/clashing-extern-fn-recursion.rs new file mode 100644 index 000000000000..de7b11c91f26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/clashing-extern-fn-recursion.rs @@ -0,0 +1,120 @@ +// check-pass +// +// This tests checks that clashing_extern_declarations handles types that are recursive through a +// pointer or ref argument. See #75512. + +#![crate_type = "lib"] + +mod raw_ptr_recursion { + mod a { + #[repr(C)] + struct Pointy { + pointy: *const Pointy, + } + + extern "C" { + fn run_pointy(pointy: Pointy); + } + } + mod b { + #[repr(C)] + struct Pointy { + pointy: *const Pointy, + } + + extern "C" { + fn run_pointy(pointy: Pointy); + } + } +} + +mod raw_ptr_recursion_once_removed { + mod a { + #[repr(C)] + struct Pointy1 { + pointy_two: *const Pointy2, + } + + #[repr(C)] + struct Pointy2 { + pointy_one: *const Pointy1, + } + + extern "C" { + fn run_pointy2(pointy: Pointy2); + } + } + + mod b { + #[repr(C)] + struct Pointy1 { + pointy_two: *const Pointy2, + } + + #[repr(C)] + struct Pointy2 { + pointy_one: *const Pointy1, + } + + extern "C" { + fn run_pointy2(pointy: Pointy2); + } + } +} + +mod ref_recursion { + mod a { + #[repr(C)] + struct Reffy<'a> { + reffy: &'a Reffy<'a>, + } + + extern "C" { + fn reffy_recursion(reffy: Reffy); + } + } + mod b { + #[repr(C)] + struct Reffy<'a> { + reffy: &'a Reffy<'a>, + } + + extern "C" { + fn reffy_recursion(reffy: Reffy); + } + } +} + +mod ref_recursion_once_removed { + mod a { + #[repr(C)] + struct Reffy1<'a> { + reffy: &'a Reffy2<'a>, + } + + struct Reffy2<'a> { + reffy: &'a Reffy1<'a>, + } + + extern "C" { + #[allow(improper_ctypes)] + fn reffy_once_removed(reffy: Reffy1); + } + } + mod b { + #[repr(C)] + struct Reffy1<'a> { + reffy: &'a Reffy2<'a>, + } + + struct Reffy2<'a> { + reffy: &'a Reffy1<'a>, + } + + extern "C" { + #[allow(improper_ctypes)] + fn reffy_once_removed(reffy: Reffy1); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/clashing-extern-fn.rs b/gcc/testsuite/rust/rustc/ui/lint/clashing-extern-fn.rs new file mode 100644 index 000000000000..9d37fd1be312 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/clashing-extern-fn.rs @@ -0,0 +1,386 @@ +// check-pass +// aux-build:external_extern_fn.rs +#![crate_type = "lib"] +#![warn(clashing_extern_declarations)] + +mod redeclared_different_signature { + mod a { + extern "C" { + fn clash(x: u8); + } + } + mod b { + extern "C" { + fn clash(x: u64); // { dg-warning "" "" { target *-*-* } } + } + } +} + +mod redeclared_same_signature { + mod a { + extern "C" { + fn no_clash(x: u8); + } + } + mod b { + extern "C" { + fn no_clash(x: u8); + } + } +} + +extern crate external_extern_fn; +mod extern_no_clash { + // Should not clash with external_extern_fn::extern_fn. + extern "C" { + fn extern_fn(x: u8); + } +} + +extern "C" { + fn some_other_new_name(x: i16); + + #[link_name = "extern_link_name"] + fn some_new_name(x: i16); + + #[link_name = "link_name_same"] + fn both_names_different(x: i16); +} + +fn link_name_clash() { + extern "C" { + fn extern_link_name(x: u32); +// { dg-warning "" "" { target *-*-* } .-1 } + + #[link_name = "some_other_new_name"] +// { dg-warning "" "" { target *-*-* } .-1 } + fn some_other_extern_link_name(x: u32); + + #[link_name = "link_name_same"] +// { dg-warning "" "" { target *-*-* } .-1 } + fn other_both_names_different(x: u32); + } +} + +mod a { + extern "C" { + fn different_mod(x: u8); + } +} +mod b { + extern "C" { + fn different_mod(x: u64); // { dg-warning "" "" { target *-*-* } } + } +} + +extern "C" { + fn variadic_decl(x: u8, ...); +} + +fn variadic_clash() { + extern "C" { + fn variadic_decl(x: u8); // { dg-warning "" "" { target *-*-* } } + } +} + +#[no_mangle] +fn no_mangle_name(x: u8) {} + +extern "C" { + #[link_name = "unique_link_name"] + fn link_name_specified(x: u8); +} + +fn tricky_no_clash() { + extern "C" { + // Shouldn't warn, because the declaration above actually declares a different symbol (and + // Rust's name resolution rules around shadowing will handle this gracefully). + fn link_name_specified() -> u32; + + // The case of a no_mangle name colliding with an extern decl (see #28179) is related but + // shouldn't be reported by ClashingExternDeclarations, because this is an example of + // unmangled name clash causing bad behaviour in functions with a defined body. + fn no_mangle_name() -> u32; + } +} + +mod banana { + mod one { + #[repr(C)] + struct Banana { + weight: u32, + length: u16, + } + extern "C" { + fn weigh_banana(count: *const Banana) -> u64; + } + } + + mod two { + #[repr(C)] + struct Banana { + weight: u32, + length: u16, + } // note: distinct type + // This should not trigger the lint because two::Banana is structurally equivalent to + // one::Banana. + extern "C" { + fn weigh_banana(count: *const Banana) -> u64; + } + } + + mod three { + // This _should_ trigger the lint, because repr(packed) should generate a struct that has a + // different layout. + #[repr(packed)] + struct Banana { + weight: u32, + length: u16, + } + #[allow(improper_ctypes)] + extern "C" { + fn weigh_banana(count: *const Banana) -> u64; +// { dg-warning "" "" { target *-*-* } .-1 } + } + } +} + +mod sameish_members { + mod a { + #[repr(C)] + struct Point { + x: i16, + y: i16, + } + + extern "C" { + fn draw_point(p: Point); + } + } + mod b { + #[repr(C)] + struct Point { + coordinates: [i16; 2], + } + + // It's possible we are overconservative for this case, as accessing the elements of the + // coordinates array might end up correctly accessing `.x` and `.y`. However, this may not + // always be the case, for every architecture and situation. This is also a really odd + // thing to do anyway. + extern "C" { + fn draw_point(p: Point); +// { dg-warning "" "" { target *-*-* } .-1 } + } + } +} + +mod same_sized_members_clash { + mod a { + #[repr(C)] + struct Point3 { + x: f32, + y: f32, + z: f32, + } + extern "C" { + fn origin() -> Point3; + } + } + mod b { + #[repr(C)] + struct Point3 { + x: i32, + y: i32, + z: i32, // NOTE: Incorrectly redeclared as i32 + } + extern "C" { + fn origin() -> Point3; // { dg-warning "" "" { target *-*-* } } + } + } +} + +mod transparent { + #[repr(transparent)] + struct T(usize); + mod a { + use super::T; + extern "C" { + fn transparent() -> T; + fn transparent_incorrect() -> T; + } + } + + mod b { + extern "C" { + // Shouldn't warn here, because repr(transparent) guarantees that T's layout is the + // same as just the usize. + fn transparent() -> usize; + + // Should warn, because there's a signedness conversion here: + fn transparent_incorrect() -> isize; +// { dg-warning "" "" { target *-*-* } .-1 } + } + } +} + +mod missing_return_type { + mod a { + extern "C" { + fn missing_return_type() -> usize; + } + } + + mod b { + extern "C" { + // This should output a warning because we can't assume that the first declaration is + // the correct one -- if this one is the correct one, then calling the usize-returning + // version would allow reads into uninitialised memory. + fn missing_return_type(); +// { dg-warning "" "" { target *-*-* } .-1 } + } + } +} + +mod non_zero_and_non_null { + mod a { + extern "C" { + fn non_zero_usize() -> core::num::NonZeroUsize; + fn non_null_ptr() -> core::ptr::NonNull; + } + } + mod b { + extern "C" { + // If there's a clash in either of these cases you're either gaining an incorrect + // invariant that the value is non-zero, or you're missing out on that invariant. Both + // cases are warning for, from both a caller-convenience and optimisation perspective. + fn non_zero_usize() -> usize; +// { dg-warning "" "" { target *-*-* } .-1 } + fn non_null_ptr() -> *const usize; +// { dg-warning "" "" { target *-*-* } .-1 } + } + } +} + +// See #75739 +mod non_zero_transparent { + mod a1 { + use std::num::NonZeroUsize; + extern "C" { + fn f1() -> NonZeroUsize; + } + } + + mod b1 { + #[repr(transparent)] + struct X(NonZeroUsize); + use std::num::NonZeroUsize; + extern "C" { + fn f1() -> X; + } + } + + mod a2 { + use std::num::NonZeroUsize; + extern "C" { + fn f2() -> NonZeroUsize; + } + } + + mod b2 { + #[repr(transparent)] + struct X1(NonZeroUsize); + + #[repr(transparent)] + struct X(X1); + + use std::num::NonZeroUsize; + extern "C" { + // Same case as above, but with two layers of newtyping. + fn f2() -> X; + } + } + + mod a3 { + #[repr(transparent)] + struct X(core::ptr::NonNull); + + use std::num::NonZeroUsize; + extern "C" { + fn f3() -> X; + } + } + + mod b3 { + extern "C" { + fn f3() -> core::ptr::NonNull; + } + } + + mod a4 { + #[repr(transparent)] + enum E { + X(std::num::NonZeroUsize), + } + extern "C" { + fn f4() -> E; + } + } + + mod b4 { + extern "C" { + fn f4() -> std::num::NonZeroUsize; + } + } +} + +mod null_optimised_enums { + mod a { + extern "C" { + fn option_non_zero_usize() -> usize; + fn option_non_zero_isize() -> isize; + fn option_non_null_ptr() -> *const usize; + + fn option_non_zero_usize_incorrect() -> usize; + fn option_non_null_ptr_incorrect() -> *const usize; + } + } + mod b { + extern "C" { + // This should be allowed, because these conversions are guaranteed to be FFI-safe (see + // #60300) + fn option_non_zero_usize() -> Option; + fn option_non_zero_isize() -> Option; + fn option_non_null_ptr() -> Option>; + + // However, these should be incorrect (note isize instead of usize) + fn option_non_zero_usize_incorrect() -> isize; +// { dg-warning "" "" { target *-*-* } .-1 } + fn option_non_null_ptr_incorrect() -> *const isize; +// { dg-warning "" "" { target *-*-* } .-1 } + } + } +} + +#[allow(improper_ctypes)] +mod unknown_layout { + mod a { + extern "C" { + pub fn generic(l: Link); + } + pub struct Link { + pub item: T, + pub next: *const Link, + } + } + + mod b { + extern "C" { + pub fn generic(l: Link); + } + pub struct Link { + pub item: T, + pub next: *const Link, + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-allow.rs b/gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-allow.rs new file mode 100644 index 000000000000..476e9742c4fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-allow.rs @@ -0,0 +1,7 @@ +// compile-flags: -A bad-style +// check-pass + +fn main() { + let _InappropriateCamelCasing = true; +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-deny.rs b/gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-deny.rs new file mode 100644 index 000000000000..5ad32efee2b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-deny.rs @@ -0,0 +1,6 @@ +// compile-flags: -D bad-style + +fn main() { + let _InappropriateCamelCasing = true; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-forbid.rs b/gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-forbid.rs new file mode 100644 index 000000000000..244946ee2eaa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-forbid.rs @@ -0,0 +1,6 @@ +// compile-flags: -F bad-style + +fn main() { + let _InappropriateCamelCasing = true; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-warn.rs b/gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-warn.rs new file mode 100644 index 000000000000..332920252b35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/command-line-lint-group-warn.rs @@ -0,0 +1,8 @@ +// compile-flags: -W bad-style +// check-pass + +fn main() { + let _InappropriateCamelCasing = true; +// { dg-warning "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/crate_level_only_lint.rs b/gcc/testsuite/rust/rustc/ui/lint/crate_level_only_lint.rs new file mode 100644 index 000000000000..19b1f54b9806 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/crate_level_only_lint.rs @@ -0,0 +1,23 @@ +#![deny(uncommon_codepoints, unused_attributes)] + +mod foo { +#![allow(uncommon_codepoints)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + +#[allow(uncommon_codepoints)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +const BAR: f64 = 0.000001; + +} + +#[allow(uncommon_codepoints)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/alias-in-pat.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/alias-in-pat.rs new file mode 100644 index 000000000000..0c43e851b0d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/alias-in-pat.rs @@ -0,0 +1,11 @@ +// run-pass + +#![deny(dead_code)] + +fn main() { + struct Foo { x: T } + type Bar = Foo; + let spam = |Bar { x }| x != 0; + println!("{}", spam(Foo { x: 10 })); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/associated-type.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/associated-type.rs new file mode 100644 index 000000000000..a45f4adfc3e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/associated-type.rs @@ -0,0 +1,20 @@ +// run-pass + +#![deny(dead_code)] + +trait Foo { + type Bar; +} + +struct Used; + +struct Ex; + +impl Foo for Ex { + type Bar = Used; +} + +pub fn main() { + let _x = Ex; +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/basic.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/basic.rs new file mode 100644 index 000000000000..c137d5e51726 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/basic.rs @@ -0,0 +1,16 @@ +#![deny(dead_code)] +#![allow(unreachable_code)] + +fn foo() { // { dg-error "" "" { target *-*-* } } + + // none of these should have any dead_code exposed to the user + panic!(); + + panic!("foo"); + + panic!("bar {}", "baz") +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/closure-bang.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/closure-bang.rs new file mode 100644 index 000000000000..0e5b0017ea23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/closure-bang.rs @@ -0,0 +1,10 @@ +// ignore-test FIXME(#20574) + +#![deny(unreachable_code)] + +fn main() { + let x = || panic!(); + x(); + println!("Foo bar"); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/const-and-self.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/const-and-self.rs new file mode 100644 index 000000000000..2e73b5470549 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/const-and-self.rs @@ -0,0 +1,36 @@ +// check-pass + +#![deny(dead_code)] + +const TLC: usize = 4; + +trait Tr { fn doit(&self); } + +impl Tr for [usize; TLC] { + fn doit(&self) { + println!("called 4"); + } +} + +struct X; +struct Y; +struct Z; + +trait Foo { + type Ty; + fn foo() -> Self::Ty; +} + +impl Foo for X { + type Ty = Z; + fn foo() -> Self::Ty { + unimplemented!() + } +} + +fn main() { + let s = [0,1,2,3]; + s.doit(); + X::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/empty-unused-enum.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/empty-unused-enum.rs new file mode 100644 index 000000000000..f71d37d41ca8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/empty-unused-enum.rs @@ -0,0 +1,6 @@ +#![deny(unused)] + +enum E {} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/empty-unused-public-enum.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/empty-unused-public-enum.rs new file mode 100644 index 000000000000..a8f7da77ee31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/empty-unused-public-enum.rs @@ -0,0 +1,7 @@ +// build-pass +#![deny(unused)] + +pub enum E {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/enum-variants.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/enum-variants.rs new file mode 100644 index 000000000000..549772e11679 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/enum-variants.rs @@ -0,0 +1,15 @@ +// run-pass + +#![deny(dead_code)] + +enum Foo { + A, + B, +} + +pub fn main() { + match Foo::A { + Foo::A | Foo::B => Foo::B + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/impl-trait.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/impl-trait.rs new file mode 100644 index 000000000000..ce9cc6cc6b90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/impl-trait.rs @@ -0,0 +1,19 @@ +#![deny(dead_code)] + +trait Trait { + type Type; +} + +impl Trait for () { + type Type = (); +} + +type Used = (); +type Unused = (); // { dg-error "" "" { target *-*-* } } + +fn foo() -> impl Trait {} + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/leading-underscore.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/leading-underscore.rs new file mode 100644 index 000000000000..46bfed10fad9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/leading-underscore.rs @@ -0,0 +1,32 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![deny(dead_code)] + +static _X: usize = 0; + +fn _foo() {} + +struct _Y { + _z: usize +} + +enum _Z {} + +impl _Y { + fn _bar() {} +} + +type _A = isize; + +mod _bar { + fn _qux() {} +} + +extern { + #[link_name = "abort"] + fn _abort() -> !; +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-1.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-1.rs new file mode 100644 index 000000000000..d447b171952a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-1.rs @@ -0,0 +1,111 @@ +#![no_std] +#![allow(unused_variables)] +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] +#![deny(dead_code)] + +#![crate_type="lib"] + +pub use foo2::Bar2; + +mod foo { + pub struct Bar; // { dg-error "" "" { target *-*-* } } +} + +mod foo2 { + pub struct Bar2; +} + +pub static pub_static: isize = 0; +static priv_static: isize = 0; // { dg-error "" "" { target *-*-* } } +const used_static: isize = 0; +pub static used_static2: isize = used_static; +const USED_STATIC: isize = 0; +const STATIC_USED_IN_ENUM_DISCRIMINANT: isize = 10; + +pub const pub_const: isize = 0; +const priv_const: isize = 0; // { dg-error "" "" { target *-*-* } } +const used_const: isize = 0; +pub const used_const2: isize = used_const; +const USED_CONST: isize = 1; +const CONST_USED_IN_ENUM_DISCRIMINANT: isize = 11; + +pub type typ = *const UsedStruct4; +pub struct PubStruct; +struct PrivStruct; // { dg-error "" "" { target *-*-* } } +struct UsedStruct1 { + #[allow(dead_code)] + x: isize +} +struct UsedStruct2(isize); +struct UsedStruct3; +pub struct UsedStruct4; +// this struct is never used directly, but its method is, so we don't want +// to warn it +struct SemiUsedStruct; +impl SemiUsedStruct { + fn la_la_la() {} +} +struct StructUsedAsField; +pub struct StructUsedInEnum; +struct StructUsedInGeneric; +pub struct PubStruct2 { + #[allow(dead_code)] + struct_used_as_field: *const StructUsedAsField +} + +pub enum pub_enum { foo1, bar1 } +pub enum pub_enum2 { a(*const StructUsedInEnum) } +pub enum pub_enum3 { + Foo = STATIC_USED_IN_ENUM_DISCRIMINANT, + Bar = CONST_USED_IN_ENUM_DISCRIMINANT, +} + +enum priv_enum { foo2, bar2 } // { dg-error "" "" { target *-*-* } } +enum used_enum { + foo3, + bar3 // { dg-error "" "" { target *-*-* } } +} + +fn f() {} + +pub fn pub_fn() { + used_fn(); + let used_struct1 = UsedStruct1 { x: 1 }; + let used_struct2 = UsedStruct2(1); + let used_struct3 = UsedStruct3; + let e = used_enum::foo3; + SemiUsedStruct::la_la_la(); + + let i = 1; + match i { + USED_STATIC => (), + USED_CONST => (), + _ => () + } + f::(); +} +fn priv_fn() { // { dg-error "" "" { target *-*-* } } + let unused_struct = PrivStruct; +} +fn used_fn() {} + +fn foo() { // { dg-error "" "" { target *-*-* } } + bar(); + let unused_enum = priv_enum::foo2; +} + +fn bar() { // { dg-error "" "" { target *-*-* } } + foo(); +} + +fn baz() -> impl Copy { // { dg-error "" "" { target *-*-* } } + "I'm unused, too" +} + +// Code with #[allow(dead_code)] should be marked live (and thus anything it +// calls is marked live) +#[allow(dead_code)] +fn g() { h(); } +fn h() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-2.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-2.rs new file mode 100644 index 000000000000..0160afd8e7be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-2.rs @@ -0,0 +1,42 @@ +#![allow(unused_variables)] +#![deny(dead_code)] +#![feature(main, start)] + +struct Foo; + +trait Bar { + fn bar1(&self); + fn bar2(&self) { + self.bar1(); + } +} + +impl Bar for Foo { + fn bar1(&self) { + live_fn(); + } +} + +fn live_fn() {} + +fn dead_fn() {} // { dg-error "" "" { target *-*-* } } + +#[main] +fn dead_fn2() {} // { dg-error "" "" { target *-*-* } } + +fn used_fn() {} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + used_fn(); + let foo = Foo; + foo.bar2(); + 0 +} + +// this is not main +fn main() { // { dg-error "" "" { target *-*-* } } + dead_fn(); + dead_fn2(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-3.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-3.rs new file mode 100644 index 000000000000..1c8a2262e5b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-3.rs @@ -0,0 +1,80 @@ +#![allow(unused_variables)] +#![allow(non_camel_case_types)] +#![allow(clashing_extern_declarations)] +#![deny(dead_code)] + +#![crate_type="lib"] + + +pub use extern_foo as x; +extern { + pub fn extern_foo(); +} + +struct Foo; // { dg-error "" "" { target *-*-* } } +impl Foo { + fn foo(&self) { // { dg-error "" "" { target *-*-* } } + bar() + } +} + +fn bar() { // { dg-error "" "" { target *-*-* } } + fn baz() {} + + Foo.foo(); + baz(); +} + +// no warning +struct Foo2; +impl Foo2 { fn foo2(&self) { bar2() } } +fn bar2() { + fn baz2() {} + + Foo2.foo2(); + baz2(); +} + +pub fn pub_fn() { + let foo2_struct = Foo2; + foo2_struct.foo2(); + + blah::baz(); +} + +mod blah { + // not warned because it's used in the parameter of `free` and return of + // `malloc` below, which are also used. + enum c_void {} + + extern { + fn free(p: *const c_void); + fn malloc(size: usize) -> *const c_void; + } + + pub fn baz() { + unsafe { free(malloc(4)); } + } +} + +enum c_void {} // { dg-error "" "" { target *-*-* } } +extern { + fn free(p: *const c_void); // { dg-error "" "" { target *-*-* } } +} + +// Check provided method +mod inner { + pub trait Trait { + fn f(&self) { f(); } + } + + impl Trait for isize {} + + fn f() {} +} + +pub fn foo() { + let a: &dyn inner::Trait = &1_isize; + a.f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-4.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-4.rs new file mode 100644 index 000000000000..bbb5f3986834 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-4.rs @@ -0,0 +1,84 @@ +#![allow(unused_variables)] +#![allow(non_camel_case_types)] +#![deny(dead_code)] + +struct Foo { + x: usize, + b: bool, // { dg-error "" "" { target *-*-* } } +} + +fn field_read(f: Foo) -> usize { + f.x.pow(2) +} + +enum XYZ { + X, // { dg-error "" "" { target *-*-* } } + Y { // { dg-error "" "" { target *-*-* } } + a: String, + b: i32, + c: i32, + }, + Z +} + +enum ABC { // { dg-error "" "" { target *-*-* } } + A, + B { + a: String, + b: i32, + c: i32, + }, + C +} + +// ensure struct variants get warning for their fields +enum IJK { + I, // { dg-error "" "" { target *-*-* } } + J { + a: String, + b: i32, // { dg-error "" "" { target *-*-* } } + c: i32, // { dg-error "" "" { target *-*-* } } + }, + K // { dg-error "" "" { target *-*-* } } + +} + +fn struct_variant_partial_use(b: IJK) -> String { + match b { + IJK::J { a, b: _, .. } => a, + _ => "".to_string() + } +} + +fn field_match_in_patterns(b: XYZ) -> String { + match b { + XYZ::Y { a, b: _, .. } => a, + _ => "".to_string() + } +} + +struct Bar { + x: usize, // { dg-error "" "" { target *-*-* } } + b: bool, + c: bool, // { dg-error "" "" { target *-*-* } } + _guard: () +} + +#[repr(C)] +struct Baz { + x: u32, +} + +fn field_match_in_let(f: Bar) -> bool { + let Bar { b, c: _, .. } = f; + b +} + +fn main() { + field_read(Foo { x: 1, b: false }); + field_match_in_patterns(XYZ::Z); + struct_variant_partial_use(IJK::J { a: "".into(), b: 1, c: -1 }); + field_match_in_let(Bar { x: 42, b: true, c: false, _guard: () }); + let _ = Baz { x: 0 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-5.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-5.rs new file mode 100644 index 000000000000..e3cca38bb7e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-5.rs @@ -0,0 +1,51 @@ +#![allow(unused_variables)] +#![deny(dead_code)] + +enum Enum1 { + Variant1(isize), + Variant2 // { dg-error "" "" { target *-*-* } } +} + +enum Enum2 { + Variant3(bool), + #[allow(dead_code)] + Variant4(isize), + Variant5 { _x: isize }, // { dg-error "" "" { target *-*-* } } + Variant6(isize), // { dg-error "" "" { target *-*-* } } + _Variant7, + Variant8 { _field: bool }, + Variant9, + Variant10(usize) +} + +impl Enum2 { + fn new_variant8() -> Enum2 { + Self::Variant8 { _field: true } + } + + fn new_variant9() -> Enum2 { + Self::Variant9 + } + + fn new_variant10() -> Enum2 { + Self::Variant10(10) + } +} + +enum Enum3 { // { dg-error "" "" { target *-*-* } } + Variant8, + Variant9 +} + +fn main() { + let v = Enum1::Variant1(1); + match v { + Enum1::Variant1(_) => (), + Enum1::Variant2 => () + } + let x = Enum2::Variant3(true); + let _ = Enum2::new_variant8(); + let _ = Enum2::new_variant9(); + let _ = Enum2::new_variant10(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-6.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-6.rs new file mode 100644 index 000000000000..3ecfb2cba309 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/lint-dead-code-6.rs @@ -0,0 +1,21 @@ +#![deny(dead_code)] + +struct UnusedStruct; // { dg-error "" "" { target *-*-* } } +impl UnusedStruct { + fn unused_impl_fn_1() { // { dg-error "" "" { target *-*-* } } + println!("blah"); + } + + fn unused_impl_fn_2(var: i32) { // { dg-error "" "" { target *-*-* } } + println!("foo {}", var); + } + + fn unused_impl_fn_3( // { dg-error "" "" { target *-*-* } } + var: i32, + ) { + println!("bar {}", var); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/newline-span.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/newline-span.rs new file mode 100644 index 000000000000..6363d7717405 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/newline-span.rs @@ -0,0 +1,20 @@ +#![deny(dead_code)] + +fn unused() { // { dg-error "" "" { target *-*-* } } + println!("blah"); +} + +fn unused2(var: i32) { // { dg-error "" "" { target *-*-* } } + println!("foo {}", var); +} + +fn unused3( // { dg-error "" "" { target *-*-* } } + var: i32, +) { + println!("bar {}", var); +} + +fn main() { + println!("Hello world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/trait-impl.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/trait-impl.rs new file mode 100644 index 000000000000..a518ea19a43e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/trait-impl.rs @@ -0,0 +1,20 @@ +// check-pass +#![deny(dead_code)] + +enum Foo { + Bar, +} + +fn main() { + let p = [0; 0]; + p.bar(); +} + +trait Bar { + fn bar(&self) -> usize { + 3 + } +} + +impl Bar for [u32; Foo::Bar as usize] {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/tuple-struct-field.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/tuple-struct-field.rs new file mode 100644 index 000000000000..623afb2d417e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/tuple-struct-field.rs @@ -0,0 +1,13 @@ +// check-pass + +#![deny(dead_code)] + +const LEN: usize = 4; + +#[derive(Debug)] +struct Wrapper([u8; LEN]); + +fn main() { + println!("{:?}", Wrapper([0, 1, 2, 3])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/type-alias.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/type-alias.rs new file mode 100644 index 000000000000..80bef4b8b245 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/type-alias.rs @@ -0,0 +1,11 @@ +#![deny(dead_code)] + +type Used = u8; +type Unused = u8; // { dg-error "" "" { target *-*-* } } + +fn id(x: Used) -> Used { x } + +fn main() { + id(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-enum.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-enum.rs new file mode 100644 index 000000000000..a06c32762607 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-enum.rs @@ -0,0 +1,12 @@ +#![deny(unused)] + +struct F; // { dg-error "" "" { target *-*-* } } +struct B; // { dg-error "" "" { target *-*-* } } + +enum E { // { dg-error "" "" { target *-*-* } } + Foo(F), + Bar(B), +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-struct-variant.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-struct-variant.rs new file mode 100644 index 000000000000..e3fc883373a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-struct-variant.rs @@ -0,0 +1,14 @@ +#![deny(unused)] + +struct F; +struct B; + +enum E { + Foo(F), + Bar(B), // { dg-error "" "" { target *-*-* } } +} + +fn main() { + let _ = E::Foo(F); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-variant-pub.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-variant-pub.rs new file mode 100644 index 000000000000..d8cb547322af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-variant-pub.rs @@ -0,0 +1,15 @@ +// build-pass +#![deny(unused)] + +pub struct F; +pub struct B; + +pub enum E { + Foo(F), + Bar(B), +} + +fn main() { + let _ = E::Foo(F); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-variant.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-variant.rs new file mode 100644 index 000000000000..1bed05e04efa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/unused-variant.rs @@ -0,0 +1,13 @@ +#![deny(dead_code)] + +#[derive(Clone)] +enum Enum { + Variant1, // { dg-error "" "" { target *-*-* } } + Variant2, +} + +fn main() { + let e = Enum::Variant2; + e.clone(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/with-core-crate.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/with-core-crate.rs new file mode 100644 index 000000000000..a85f605a6f05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/with-core-crate.rs @@ -0,0 +1,19 @@ +#![deny(dead_code)] +#![allow(unreachable_code)] + +#[macro_use] +extern crate core; + +fn foo() { // { dg-error "" "" { target *-*-* } } + + // none of these should have any dead_code exposed to the user + panic!(); + + panic!("foo"); + + panic!("bar {}", "baz") +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/dead-code/with-impl.rs b/gcc/testsuite/rust/rustc/ui/lint/dead-code/with-impl.rs new file mode 100644 index 000000000000..158412bfbf61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/dead-code/with-impl.rs @@ -0,0 +1,18 @@ +// run-pass + +#![deny(dead_code)] + +pub struct GenericFoo(T); + +type Foo = GenericFoo; + +impl Foo { + fn bar(self) -> u8 { + 0 + } +} + +fn main() { + println!("{}", GenericFoo(0).bar()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/deny-overflowing-literals.rs b/gcc/testsuite/rust/rustc/ui/lint/deny-overflowing-literals.rs new file mode 100644 index 000000000000..2f14666d61dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/deny-overflowing-literals.rs @@ -0,0 +1,8 @@ +fn main() { + let x: u8 = 256; +// { dg-error "" "" { target *-*-* } .-1 } + + for _ in 0..256u8 {} +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/empty-lint-attributes.rs b/gcc/testsuite/rust/rustc/ui/lint/empty-lint-attributes.rs new file mode 100644 index 000000000000..a6c94dc17bbe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/empty-lint-attributes.rs @@ -0,0 +1,18 @@ +#![feature(lint_reasons)] + +// check-pass + +// Empty (and reason-only) lint attributes are legal—although we may want to +// lint them in the future (Issue #55112). + +#![allow()] +#![warn(reason = "observationalism")] + +#[forbid()] +fn devoir() {} + +#[deny(reason = "ultion")] +fn waldgrave() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/expansion-time-include.rs b/gcc/testsuite/rust/rustc/ui/lint/expansion-time-include.rs new file mode 100644 index 000000000000..0c1b29ba262b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/expansion-time-include.rs @@ -0,0 +1,5 @@ +// ignore-test auxiliary file for expansion-time.rs + +1 +2 + diff --git a/gcc/testsuite/rust/rustc/ui/lint/expansion-time.rs b/gcc/testsuite/rust/rustc/ui/lint/expansion-time.rs new file mode 100644 index 000000000000..dd4cf9f8cd68 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/expansion-time.rs @@ -0,0 +1,24 @@ +// check-pass + +#[warn(meta_variable_misuse)] +macro_rules! foo { + ( $($i:ident)* ) => { $($i)+ }; // { dg-warning "" "" { target *-*-* } } +} + +#[warn(missing_fragment_specifier)] +macro_rules! m { ($i) => {} } // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + +#[warn(soft_unstable)] +mod benches { + #[bench] // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + fn foo() {} +} + +#[warn(incomplete_include)] +fn main() { + // WARN see in the stderr file, the warning points to the included file. + include!("expansion-time-include.rs"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/function-item-references.rs b/gcc/testsuite/rust/rustc/ui/lint/function-item-references.rs new file mode 100644 index 000000000000..be79c17c664e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/function-item-references.rs @@ -0,0 +1,170 @@ +// check-pass +#![feature(c_variadic, min_const_generics)] +#![warn(function_item_references)] +use std::fmt::Pointer; +use std::fmt::Formatter; + +fn nop() { } +fn foo() -> u32 { 42 } +fn bar(x: u32) -> u32 { x } +fn baz(x: u32, y: u32) -> u32 { x + y } +unsafe fn unsafe_fn() { } +extern "C" fn c_fn() { } +unsafe extern "C" fn unsafe_c_fn() { } +unsafe extern fn variadic(_x: u32, _args: ...) { } +fn take_generic_ref<'a, T>(_x: &'a T) { } +fn take_generic_array(_x: [T; N]) { } +fn multiple_generic(_x: T, _y: U) { } +fn multiple_generic_arrays(_x: [T; N], _y: [U; M]) { } + +//function references passed to these functions should never lint +fn call_fn(f: &dyn Fn(u32) -> u32, x: u32) { f(x); } +fn parameterized_call_fn u32>(f: &F, x: u32) { f(x); } + +//function references passed to these functions should lint +fn print_ptr(f: F) { println!("{:p}", f); } +fn bound_by_ptr_trait(_f: F) { } +fn bound_by_ptr_trait_tuple(_t: (F, G)) { } +fn implicit_ptr_trait(f: &F) { println!("{:p}", f); } + +//case found in tinyvec that triggered a compiler error in an earlier version of the lint checker +trait HasItem { + type Item; + fn assoc_item(&self) -> Self::Item; +} +fn _format_assoc_item(data: T, f: &mut Formatter) -> std::fmt::Result + where T::Item: Pointer { + //when the arg type bound by `Pointer` is an associated type, we shouldn't attempt to normalize + Pointer::fmt(&data.assoc_item(), f) +} + +//simple test to make sure that calls to `Pointer::fmt` aren't double counted +fn _call_pointer_fmt(f: &mut Formatter) -> std::fmt::Result { + let zst_ref = &foo; + Pointer::fmt(&zst_ref, f) +// { dg-warning "" "" { target *-*-* } .-1 } +} + +fn main() { + //`let` bindings with function references shouldn't lint + let _ = &foo; + let _ = &mut foo; + + let zst_ref = &foo; + let fn_item = foo; + let indirect_ref = &fn_item; + + let _mut_zst_ref = &mut foo; + let mut mut_fn_item = foo; + let _mut_indirect_ref = &mut mut_fn_item; + + let cast_zst_ptr = &foo as *const _; + let coerced_zst_ptr: *const _ = &foo; + + let _mut_cast_zst_ptr = &mut foo as *mut _; + let _mut_coerced_zst_ptr: *mut _ = &mut foo; + + let _cast_zst_ref = &foo as &dyn Fn() -> u32; + let _coerced_zst_ref: &dyn Fn() -> u32 = &foo; + + let _mut_cast_zst_ref = &mut foo as &mut dyn Fn() -> u32; + let _mut_coerced_zst_ref: &mut dyn Fn() -> u32 = &mut foo; + + //the suggested way to cast to a function pointer + let fn_ptr = foo as fn() -> u32; + + //correct ways to print function pointers + println!("{:p}", foo as fn() -> u32); + println!("{:p}", fn_ptr); + + //potential ways to incorrectly try printing function pointers + println!("{:p}", &foo); +// { dg-warning "" "" { target *-*-* } .-1 } + print!("{:p}", &foo); +// { dg-warning "" "" { target *-*-* } .-1 } + format!("{:p}", &foo); +// { dg-warning "" "" { target *-*-* } .-1 } + + println!("{:p}", &foo as *const _); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", zst_ref); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", cast_zst_ptr); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", coerced_zst_ptr); +// { dg-warning "" "" { target *-*-* } .-1 } + + println!("{:p}", &fn_item); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", indirect_ref); +// { dg-warning "" "" { target *-*-* } .-1 } + + println!("{:p}", &nop); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", &bar); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", &baz); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", &unsafe_fn); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", &c_fn); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", &unsafe_c_fn); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", &variadic); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", &take_generic_ref::); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", &take_generic_array::); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", &multiple_generic::); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", &multiple_generic_arrays::); +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{:p}", &std::env::var::); +// { dg-warning "" "" { target *-*-* } .-1 } + + println!("{:p} {:p} {:p}", &nop, &foo, &bar); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + + //using a function reference to call a function shouldn't lint + (&bar)(1); + + //passing a function reference to an arbitrary function shouldn't lint + call_fn(&bar, 1); + parameterized_call_fn(&bar, 1); + std::mem::size_of_val(&foo); + + unsafe { + //potential ways to incorrectly try transmuting function pointers + std::mem::transmute::<_, usize>(&foo); +// { dg-warning "" "" { target *-*-* } .-1 } + std::mem::transmute::<_, (usize, usize)>((&foo, &bar)); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + std::mem::transmute::<_, usize>(&take_generic_ref::); +// { dg-warning "" "" { target *-*-* } .-1 } + + //the correct way to transmute function pointers + std::mem::transmute::<_, usize>(foo as fn() -> u32); + std::mem::transmute::<_, (usize, usize)>((foo as fn() -> u32, bar as fn(u32) -> u32)); + } + + //function references as arguments required to be bound by std::fmt::Pointer should lint + print_ptr(&bar); +// { dg-warning "" "" { target *-*-* } .-1 } + bound_by_ptr_trait(&bar); +// { dg-warning "" "" { target *-*-* } .-1 } + bound_by_ptr_trait_tuple((&foo, &bar)); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + implicit_ptr_trait(&bar); // ignore + + //correct ways to pass function pointers as arguments bound by std::fmt::Pointer + print_ptr(bar as fn(u32) -> u32); + bound_by_ptr_trait(bar as fn(u32) -> u32); + bound_by_ptr_trait_tuple((foo as fn() -> u32, bar as fn(u32) -> u32)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/inclusive-range-pattern-syntax.rs b/gcc/testsuite/rust/rustc/ui/lint/inclusive-range-pattern-syntax.rs new file mode 100644 index 000000000000..76cff43b028b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/inclusive-range-pattern-syntax.rs @@ -0,0 +1,20 @@ +// check-pass +// run-rustfix + +#![warn(ellipsis_inclusive_range_patterns)] + +fn main() { + let despondency = 2; + match despondency { + 1...2 => {} +// { dg-warning "" "" { target *-*-* } .-1 } + _ => {} + } + + match &despondency { + &1...2 => {} +// { dg-warning "" "" { target *-*-* } .-1 } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/inline-trait-and-foreign-items.rs b/gcc/testsuite/rust/rustc/ui/lint/inline-trait-and-foreign-items.rs new file mode 100644 index 000000000000..74e2a207cdf0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/inline-trait-and-foreign-items.rs @@ -0,0 +1,38 @@ +#![feature(extern_types)] +#![feature(type_alias_impl_trait)] + +#![warn(unused_attributes)] + +trait Trait { + #[inline] // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + const X: u32; + + #[inline] // { dg-error ".E0518." "" { target *-*-* } } + type T; + + type U; +} + +impl Trait for () { + #[inline] // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + const X: u32 = 0; + + #[inline] // { dg-error ".E0518." "" { target *-*-* } } + type T = Self; + + #[inline] // { dg-error ".E0518." "" { target *-*-* } } + type U = impl Trait; // { dg-error "" "" { target *-*-* } } +} + +extern { + #[inline] // { dg-error ".E0518." "" { target *-*-* } } + static X: u32; + + #[inline] // { dg-error ".E0518." "" { target *-*-* } } + type T; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/gcc/testsuite/rust/rustc/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs new file mode 100644 index 000000000000..3f06dac2fb5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs @@ -0,0 +1,89 @@ +// check-pass + +#![feature(box_syntax)] +#![feature(box_patterns)] +#![warn(unused)] // UI tests pass `-A unused` (#43896) + +struct SoulHistory { + corridors_of_light: usize, + hours_are_suns: bool, + endless_and_singing: bool +} + +struct LovelyAmbition { + lips: usize, + fire: usize +} + +#[derive(Clone, Copy)] +enum Large { + Suit { case: () } +} + +struct Tuple(Large, ()); + +fn main() { + let i_think_continually = 2; // { dg-warning "" "" { target *-*-* } } + let who_from_the_womb_remembered = SoulHistory { + corridors_of_light: 5, + hours_are_suns: true, + endless_and_singing: true + }; + + let mut mut_unused_var = 1; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + let (mut var, unused_var) = (1, 2); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + // NOTE: `var` comes after `unused_var` lexicographically yet the warning + // for `var` will be emitted before the one for `unused_var`. We use an + // `IndexMap` to ensure this is the case instead of a `BTreeMap`. + + if let SoulHistory { corridors_of_light, // { dg-warning "" "" { target *-*-* } } + mut hours_are_suns, // { dg-warning "" "" { target *-*-* } } + endless_and_singing: true } = who_from_the_womb_remembered { + hours_are_suns = false; // { dg-warning "" "" { target *-*-* } } + } + + let the_spirit = LovelyAmbition { lips: 1, fire: 2 }; + let LovelyAmbition { lips, fire } = the_spirit; // { dg-warning "" "" { target *-*-* } } + println!("{}", lips); + + let bag = Large::Suit { + case: () + }; + + // Plain struct + match bag { + Large::Suit { case } => {} // { dg-warning "" "" { target *-*-* } } + }; + + // Referenced struct + match &bag { + &Large::Suit { case } => {} // { dg-warning "" "" { target *-*-* } } + }; + + // Boxed struct + match box bag { + box Large::Suit { case } => {} // { dg-warning "" "" { target *-*-* } } + }; + + // Tuple with struct + match (bag,) { + (Large::Suit { case },) => {} // { dg-warning "" "" { target *-*-* } } + }; + + // Slice with struct + match [bag] { + [Large::Suit { case }] => {} // { dg-warning "" "" { target *-*-* } } + }; + + // Tuple struct with struct + match Tuple(bag, ()) { + Tuple(Large::Suit { case }, ()) => {} // { dg-warning "" "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs b/gcc/testsuite/rust/rustc/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs new file mode 100644 index 000000000000..006154f0ab40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs @@ -0,0 +1,28 @@ +// check-pass + +#![warn(unused_parens)] + +macro_rules! the_worship_the_heart_lifts_above { + ( @as_expr, $e:expr) => { $e }; + ( @generate_fn, $name:tt) => { + #[allow(dead_code)] fn the_moth_for_the_star<'a>() -> Option<&'a str> { + Some(the_worship_the_heart_lifts_above!( @as_expr, $name )) + } + }; + ( $name:ident ) => { the_worship_the_heart_lifts_above!( @generate_fn, (stringify!($name))); } + // ↑ Notably, this does 𝘯𝘰𝘵 warn: we're declining to lint unused parens in + // function/method arguments inside of nested macros because of situations + // like those reported in Issue #47775 +} + +macro_rules! and_the_heavens_reject_not { + () => { + #[allow(dead_code)] fn the_night_for_the_morrow() -> Option { Some((2)) } + } +} + +the_worship_the_heart_lifts_above!(rah); +and_the_heavens_reject_not!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/issue-54099-camel-case-underscore-types.rs b/gcc/testsuite/rust/rustc/ui/lint/issue-54099-camel-case-underscore-types.rs new file mode 100644 index 000000000000..2c8f6991d079 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/issue-54099-camel-case-underscore-types.rs @@ -0,0 +1,15 @@ +// check-pass + +#![forbid(non_camel_case_types)] +#![allow(dead_code)] + +// None of the following types should generate a warning +struct _X {} +struct __X {} +struct __ {} +struct X_ {} +struct X__ {} +struct X___ {} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/issue-54180-unused-ref-field.rs b/gcc/testsuite/rust/rustc/ui/lint/issue-54180-unused-ref-field.rs new file mode 100644 index 000000000000..78b0c14cfe7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/issue-54180-unused-ref-field.rs @@ -0,0 +1,35 @@ +// run-rustfix + +#![deny(unused)] + +pub struct S { + pub f1: i32, +} + +pub struct Point { + pub x: i32, + pub y: i32, +} + +pub enum E { + Variant { field: String } +} + +pub fn foo(arg: &E) { + match arg { + E::Variant { ref field } => (), // { dg-error "" "" { target *-*-* } } + } +} + +fn main() { + let s = S { f1: 123 }; + let S { ref f1 } = s; // { dg-error "" "" { target *-*-* } } + + let points = vec![Point { x: 1, y: 2 }]; + let _: i32 = points.iter().map(|Point { x, y }| y).sum(); // { dg-error "" "" { target *-*-* } } + + match (Point { x: 1, y: 2 }) { + Point { y, ref mut x } => y, // { dg-error "" "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/issue-54538-unused-parens-lint.rs b/gcc/testsuite/rust/rustc/ui/lint/issue-54538-unused-parens-lint.rs new file mode 100644 index 000000000000..dd65e05b4572 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/issue-54538-unused-parens-lint.rs @@ -0,0 +1,108 @@ +// run-rustfix + +#![feature(box_patterns, stmt_expr_attributes)] +#![feature(or_patterns)] + +#![allow( + dead_code, + ellipsis_inclusive_range_patterns, + irrefutable_let_patterns, + unreachable_patterns, + unused_mut, + unused_variables +)] +#![deny(unused_parens)] + +fn lint_on_top_level() { + let (a) = 0; // { dg-error "" "" { target *-*-* } } + for (a) in 0..1 {} // { dg-error "" "" { target *-*-* } } + if let (a) = 0 {} // { dg-error "" "" { target *-*-* } } + while let (a) = 0 {} // { dg-error "" "" { target *-*-* } } + fn foo((a): u8) {} // { dg-error "" "" { target *-*-* } } + let _ = |(a): u8| 0; // { dg-error "" "" { target *-*-* } } +} + +fn _no_lint_attr() { + let _x = #[allow(dead_code)] (1 + 2); +} + +// Don't lint in these cases (#64106). +fn or_patterns_no_lint() { + match Box::new(0) { + box (0 | 1) => {} // Should not lint as `box 0 | 1` binds as `(box 0) | 1`. + _ => {} + } + + match 0 { + x @ (0 | 1) => {} // Should not lint as `x @ 0 | 1` binds as `(x @ 0) | 1`. + _ => {} + } + + if let &(0 | 1) = &0 {} // Should also not lint. + if let &mut (0 | 1) = &mut 0 {} // Same. + + fn foo((Ok(a) | Err(a)): Result) {} // Doesn't parse if we remove parens for now. + + let _ = |(Ok(a) | Err(a)): Result| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or. +} + +fn or_patterns_will_lint() { + if let (0 | 1) = 0 {} // { dg-error "" "" { target *-*-* } } + if let ((0 | 1),) = (0,) {} // { dg-error "" "" { target *-*-* } } + if let [(0 | 1)] = [0] {} // { dg-error "" "" { target *-*-* } } + if let 0 | (1 | 2) = 0 {} // { dg-error "" "" { target *-*-* } } + struct TS(u8); + if let TS((0 | 1)) = TS(0) {} // { dg-error "" "" { target *-*-* } } + struct NS { f: u8 } + if let NS { f: (0 | 1) } = (NS { f: 0 }) {} // { dg-error "" "" { target *-*-* } } +} + +// Don't lint on `&(mut x)` because `&mut x` means something else (#55342). +fn deref_mut_binding_no_lint() { + let &(mut x) = &0; +} + +fn main() { + match 1 { + (_) => {} // { dg-error "" "" { target *-*-* } } + (y) => {} // { dg-error "" "" { target *-*-* } } + (ref r) => {} // { dg-error "" "" { target *-*-* } } + (e @ 1...2) => {} // { dg-error "" "" { target *-*-* } } + (1...2) => {} // Non ambiguous range pattern should not warn + e @ (3...4) => {} // Non ambiguous range pattern should not warn + } + + match &1 { + (e @ &(1...2)) => {} // { dg-error "" "" { target *-*-* } } + &(_) => {} // { dg-error "" "" { target *-*-* } } + e @ &(1...2) => {} // Ambiguous range pattern should not warn + &(1...2) => {} // Ambiguous range pattern should not warn + } + + match &1 { + e @ &(1...2) | e @ &(3...4) => {} // Complex ambiguous pattern should not warn + &_ => {} + } + + match 1 { + (_) => {} // { dg-error "" "" { target *-*-* } } + (y) => {} // { dg-error "" "" { target *-*-* } } + (ref r) => {} // { dg-error "" "" { target *-*-* } } + (e @ 1..=2) => {} // { dg-error "" "" { target *-*-* } } + (1..=2) => {} // Non ambiguous range pattern should not warn + e @ (3..=4) => {} // Non ambiguous range pattern should not warn + } + + match &1 { + (e @ &(1..=2)) => {} // { dg-error "" "" { target *-*-* } } + &(_) => {} // { dg-error "" "" { target *-*-* } } + e @ &(1..=2) => {} // Ambiguous range pattern should not warn + &(1..=2) => {} // Ambiguous range pattern should not warn + } + + match &1 { + e @ &(1..=2) | e @ &(3..=4) => {} // Complex ambiguous pattern should not warn + &_ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs b/gcc/testsuite/rust/rustc/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs new file mode 100644 index 000000000000..a971eba838c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs @@ -0,0 +1,30 @@ +#![deny(non_snake_case)] +#![allow(unused_variables)] +#![allow(dead_code)] + +enum Foo { + Bad { + lowerCamelCaseName: bool, +// { dg-error "" "" { target *-*-* } .-1 } + }, + Good { + snake_case_name: bool, + }, +} + +fn main() { + let b = Foo::Bad { lowerCamelCaseName: true }; + + match b { + Foo::Bad { lowerCamelCaseName } => {} + Foo::Good { snake_case_name: lowerCamelCaseBinding } => { } +// { dg-error "" "" { target *-*-* } .-1 } + } + + if let Foo::Good { snake_case_name: anotherLowerCamelCaseBinding } = b { } +// { dg-error "" "" { target *-*-* } .-1 } + + if let Foo::Bad { lowerCamelCaseName: yetAnotherLowerCamelCaseBinding } = b { } +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/issue-67691-unused-field-in-or-pattern.rs b/gcc/testsuite/rust/rustc/ui/lint/issue-67691-unused-field-in-or-pattern.rs new file mode 100644 index 000000000000..666fbe09c6c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/issue-67691-unused-field-in-or-pattern.rs @@ -0,0 +1,87 @@ +// FIXME: should be run-rustfix, but rustfix doesn't currently support multipart suggestions, see +// #53934 + +#![feature(or_patterns)] +#![deny(unused)] + +pub enum MyEnum { + A { i: i32, j: i32 }, + B { i: i32, j: i32 }, +} + +pub enum MixedEnum { + A { i: i32 }, + B(i32), +} + +pub fn no_ref(x: MyEnum) { + use MyEnum::*; + + match x { + A { i, j } | B { i, j } => { // { dg-error "" "" { target *-*-* } } + println!("{}", i); + } + } +} + +pub fn with_ref(x: MyEnum) { + use MyEnum::*; + + match x { + A { i, ref j } | B { i, ref j } => { // { dg-error "" "" { target *-*-* } } + println!("{}", i); + } + } +} + +pub fn inner_no_ref(x: Option) { + use MyEnum::*; + + match x { + Some(A { i, j } | B { i, j }) => { // { dg-error "" "" { target *-*-* } } + println!("{}", i); + } + + _ => {} + } +} + +pub fn inner_with_ref(x: Option) { + use MyEnum::*; + + match x { + Some(A { i, ref j } | B { i, ref j }) => { // { dg-error "" "" { target *-*-* } } + println!("{}", i); + } + + _ => {} + } +} + +pub fn mixed_no_ref(x: MixedEnum) { + match x { + MixedEnum::A { i } | MixedEnum::B(i) => { // { dg-error "" "" { target *-*-* } } + println!("match"); + } + } +} + +pub fn mixed_with_ref(x: MixedEnum) { + match x { + MixedEnum::A { ref i } | MixedEnum::B(ref i) => { // { dg-error "" "" { target *-*-* } } + println!("match"); + } + } +} + +pub fn main() { + no_ref(MyEnum::A { i: 1, j: 2 }); + with_ref(MyEnum::A { i: 1, j: 2 }); + + inner_no_ref(Some(MyEnum::A { i: 1, j: 2 })); + inner_with_ref(Some(MyEnum::A { i: 1, j: 2 })); + + mixed_no_ref(MixedEnum::B(5)); + mixed_with_ref(MixedEnum::B(5)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/issue-69485-var-size-diffs-too-large.rs b/gcc/testsuite/rust/rustc/ui/lint/issue-69485-var-size-diffs-too-large.rs new file mode 100644 index 000000000000..4eb057038e58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/issue-69485-var-size-diffs-too-large.rs @@ -0,0 +1,12 @@ +// build-fail +// only-x86_64 +// compile-flags: -Zmir-opt-level=0 + +fn main() { + Bug::V([0; !0]); // { dg-error "" "" { target *-*-* } } +} + +enum Bug { + V([u8; !0]), +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/issue-71290-unused-paren-binop.rs b/gcc/testsuite/rust/rustc/ui/lint/issue-71290-unused-paren-binop.rs new file mode 100644 index 000000000000..4c24af378778 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/issue-71290-unused-paren-binop.rs @@ -0,0 +1,24 @@ +// check-pass +// Make sure unused parens lint doesn't emit a false positive. +// See https://github.com/rust-lang/rust/issues/71290 for details. +#![deny(unused_parens)] + +fn x() -> u8 { + ({ 0 }) + 1 +} + +fn y() -> u8 { + ({ 0 } + 1) +} + +pub fn foo(a: bool, b: bool) -> u8 { + (if a { 1 } else { 0 } + if b { 1 } else { 0 }) +} + +pub fn bar() -> u8 { + // Make sure nested expressions are handled correctly as well + ({ 0 } + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/issue-74883-unused-paren-baren-yield.rs b/gcc/testsuite/rust/rustc/ui/lint/issue-74883-unused-paren-baren-yield.rs new file mode 100644 index 000000000000..dbb2cac23731 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/issue-74883-unused-paren-baren-yield.rs @@ -0,0 +1,27 @@ +#![feature(generator_trait)] +#![feature(generators)] +#![deny(unused_braces, unused_parens)] + +use std::ops::Generator; +use std::pin::Pin; + +fn main() { + let mut x = |_| { + while let Some(_) = (yield) {} + while let Some(_) = {yield} {} + + // Only warn these cases + while let Some(_) = ({yield}) {} // { dg-error "" "" { target *-*-* } } + while let Some(_) = ((yield)) {} // { dg-error "" "" { target *-*-* } } + {{yield}}; // { dg-error "" "" { target *-*-* } } + {( yield )}; // { dg-error "" "" { target *-*-* } } + while let Some(_) = {(yield)} {} // { dg-error "" "" { target *-*-* } } + while let Some(_) = {{yield}} {} // { dg-error "" "" { target *-*-* } } + + // FIXME: It'd be great if we could also warn them. + ((yield)); + ({ yield }); + }; + let _ = Pin::new(&mut x).resume(Some(5)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/issue-78660-cap-lints-future-compat.rs b/gcc/testsuite/rust/rustc/ui/lint/issue-78660-cap-lints-future-compat.rs new file mode 100644 index 000000000000..fc8e206ed34e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/issue-78660-cap-lints-future-compat.rs @@ -0,0 +1,11 @@ +// compile-flags: -D warnings --cap-lints allow +// check-pass + +// Regression test for issue #78660 +// Tests that we don't ICE when a future-incompat-report lint has +// has a command-line source, but is capped to allow + +fn main() { + ["hi"].into_iter(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-attr-non-item-node.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-attr-non-item-node.rs new file mode 100644 index 000000000000..3fc11a1e673c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-attr-non-item-node.rs @@ -0,0 +1,10 @@ +// Checks that lint attributes work on non-item AST nodes + +fn main() { + #[deny(unreachable_code)] + loop { + break; + "unreachable"; // { dg-error "" "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-change-warnings.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-change-warnings.rs new file mode 100644 index 000000000000..a50134b9cc2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-change-warnings.rs @@ -0,0 +1,22 @@ +#![deny(warnings)] +#![allow(dead_code)] + +fn main() { + while true {} // { dg-error "" "" { target *-*-* } } +} + +#[allow(warnings)] +fn foo() { + while true {} +} + +#[warn(warnings)] +fn bar() { + while true {} // { dg-warning "" "" { target *-*-* } } +} + +#[forbid(warnings)] +fn baz() { + while true {} // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-const-item-mutation.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-const-item-mutation.rs new file mode 100644 index 000000000000..37af42165435 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-const-item-mutation.rs @@ -0,0 +1,59 @@ +// check-pass + +struct MyStruct { + field: bool, + inner_array: [char; 1], + raw_ptr: *mut u8 +} +impl MyStruct { + fn use_mut(&mut self) {} +} + +struct Mutable { + msg: &'static str, +} +impl Drop for Mutable { + fn drop(&mut self) { + println!("{}", self.msg); + } +} + +struct Mutable2 { // this one has drop glue but not a Drop impl + msg: &'static str, + other: String, +} + +const ARRAY: [u8; 1] = [25]; +const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw_ptr: 2 as *mut u8 }; +const RAW_PTR: *mut u8 = 1 as *mut u8; +const MUTABLE: Mutable = Mutable { msg: "" }; +const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() }; +const VEC: Vec = Vec::new(); +const PTR: *mut () = 1 as *mut _; + +fn main() { + ARRAY[0] = 5; // { dg-warning "" "" { target *-*-* } } + MY_STRUCT.field = false; // { dg-warning "" "" { target *-*-* } } + MY_STRUCT.inner_array[0] = 'b'; // { dg-warning "" "" { target *-*-* } } + MY_STRUCT.use_mut(); // { dg-warning "" "" { target *-*-* } } + &mut MY_STRUCT; // { dg-warning "" "" { target *-*-* } } + (&mut MY_STRUCT).use_mut(); // { dg-warning "" "" { target *-*-* } } + + // Test that we don't warn when writing through + // a raw pointer + // This is U.B., but this test is check-pass, + // so this never actually executes + unsafe { + *RAW_PTR = 0; + *MY_STRUCT.raw_ptr = 0; + } + + MUTABLE.msg = "wow"; // no warning, because Drop observes the mutation + MUTABLE2.msg = "wow"; // { dg-warning "" "" { target *-*-* } } + VEC.push(0); // { dg-warning "" "" { target *-*-* } } + + // Test that we don't warn when converting a raw pointer + // into a mutable reference + unsafe { &mut *PTR }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-66202.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-66202.rs new file mode 100644 index 000000000000..3a071d07167b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-66202.rs @@ -0,0 +1,18 @@ +// check-pass + +#![deny(improper_ctypes)] + +// This test checks that return types are normalized before being checked for FFI-safety, and that +// transparent newtype wrappers are FFI-safe if the type being wrapped is FFI-safe. + +#[repr(transparent)] +pub struct W(T); + +extern "C" { + pub fn bare() -> (); + pub fn normalize() -> <() as ToOwned>::Owned; + pub fn transparent() -> W<()>; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-1.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-1.rs new file mode 100644 index 000000000000..dc1875f423fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-1.rs @@ -0,0 +1,22 @@ +// check-pass +#![deny(improper_ctypes)] + +pub trait Foo { + type Assoc: 'static; +} + +impl Foo for () { + type Assoc = u32; +} + +extern "C" { + pub fn lint_me(x: Bar<()>); +} + +#[repr(transparent)] +pub struct Bar { + value: &'static ::Assoc, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-2.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-2.rs new file mode 100644 index 000000000000..8106b3ee0255 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-2.rs @@ -0,0 +1,30 @@ +#![feature(type_alias_impl_trait)] +#![deny(improper_ctypes)] + +pub trait Baz { } + +impl Baz for () { } + +type Qux = impl Baz; + +fn assign() -> Qux {} + +pub trait Foo { + type Assoc: 'static; +} + +impl Foo for () { + type Assoc = Qux; +} + +#[repr(transparent)] +pub struct A { + x: &'static ::Assoc, +} + +extern "C" { + pub fn lint_me() -> A<()>; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-3.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-3.rs new file mode 100644 index 000000000000..0fcebb966a68 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-3.rs @@ -0,0 +1,22 @@ +#![feature(type_alias_impl_trait)] +#![deny(improper_ctypes)] + +pub trait Baz { } + +impl Baz for u32 { } + +type Qux = impl Baz; + +fn assign() -> Qux { 3 } + +#[repr(C)] +pub struct A { + x: Qux, +} + +extern "C" { + pub fn lint_me() -> A; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-4.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-4.rs new file mode 100644 index 000000000000..9b7db5a71ad2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-4.rs @@ -0,0 +1,25 @@ +// check-pass +#![deny(improper_ctypes)] + +use std::marker::PhantomData; + +trait Foo { + type Assoc; +} + +impl Foo for () { + type Assoc = PhantomData<()>; +} + +#[repr(transparent)] +struct Wow where T: Foo> { + x: ::Assoc, + v: u32, +} + +extern "C" { + fn test(v: Wow<()>); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-5.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-5.rs new file mode 100644 index 000000000000..608e10d28a73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249-5.rs @@ -0,0 +1,22 @@ +#![feature(type_alias_impl_trait)] +#![deny(improper_ctypes)] + +pub trait Baz { } + +impl Baz for u32 { } + +type Qux = impl Baz; + +fn assign() -> Qux { 3 } + +#[repr(transparent)] +pub struct A { + x: Qux, +} + +extern "C" { + pub fn lint_me() -> A; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249.rs new file mode 100644 index 000000000000..853a38972c45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73249.rs @@ -0,0 +1,22 @@ +// check-pass +#![deny(improper_ctypes)] + +pub trait Foo { + type Assoc; +} + +impl Foo for () { + type Assoc = u32; +} + +extern "C" { + pub fn lint_me(x: Bar<()>); +} + +#[repr(transparent)] +pub struct Bar { + value: ::Assoc, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73251-1.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73251-1.rs new file mode 100644 index 000000000000..e5bdc2764303 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73251-1.rs @@ -0,0 +1,25 @@ +#![feature(type_alias_impl_trait)] +#![deny(improper_ctypes)] + +pub trait Baz { } + +impl Baz for u32 { } + +type Qux = impl Baz; + +pub trait Foo { + type Assoc; +} + +impl Foo for u32 { + type Assoc = Qux; +} + +fn assign() -> Qux { 1 } + +extern "C" { + pub fn lint_me() -> ::Assoc; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73251-2.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73251-2.rs new file mode 100644 index 000000000000..79a65ac5f3b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73251-2.rs @@ -0,0 +1,33 @@ +#![feature(type_alias_impl_trait)] +#![deny(improper_ctypes)] + +pub trait TraitA { + type Assoc; +} + +impl TraitA for u32 { + type Assoc = u32; +} + +pub trait TraitB { + type Assoc; +} + +impl TraitB for T where T: TraitA { + type Assoc = ::Assoc; +} + +type AliasA = impl TraitA; + +type AliasB = impl TraitB; + +fn use_of_a() -> AliasA { 3 } + +fn use_of_b() -> AliasB { 3 } + +extern "C" { + pub fn lint_me() -> ::Assoc; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73251.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73251.rs new file mode 100644 index 000000000000..e5dea8e3910d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73251.rs @@ -0,0 +1,23 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![deny(improper_ctypes)] + +pub trait Foo { + type Assoc; +} + +impl Foo for () { + type Assoc = u32; +} + +type Bar = impl Foo; + +fn assign() -> Bar {} + +extern "C" { + pub fn lint_me() -> ::Assoc; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73747.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73747.rs new file mode 100644 index 000000000000..04430ef88ada --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-73747.rs @@ -0,0 +1,15 @@ +// check-pass + +#[repr(transparent)] +struct NonNullRawComPtr { + inner: std::ptr::NonNull<::VTable>, +} + +trait ComInterface { + type VTable; +} + +extern "C" fn invoke(_: Option>) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-enum.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-enum.rs new file mode 100644 index 000000000000..c8049fa4b416 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-enum.rs @@ -0,0 +1,73 @@ +#![feature(transparent_unions)] +#![feature(ptr_internals)] +#![deny(improper_ctypes)] +#![allow(dead_code)] + +use std::num; + +enum Z { } +enum U { A } +enum B { C, D } +enum T { E, F, G } + +#[repr(C)] +enum ReprC { A, B, C } + +#[repr(u8)] +enum U8 { A, B, C } + +#[repr(isize)] +enum Isize { A, B, C } + +#[repr(transparent)] +struct TransparentStruct(T, std::marker::PhantomData); + +#[repr(transparent)] +enum TransparentEnum { + Variant(T, std::marker::PhantomData), +} + +#[repr(transparent)] +union TransparentUnion { + field: T, +} + +struct Rust(T); + +extern { + fn zf(x: Z); + fn uf(x: U); // { dg-error "" "" { target *-*-* } } + fn bf(x: B); // { dg-error "" "" { target *-*-* } } + fn tf(x: T); // { dg-error "" "" { target *-*-* } } + fn repr_c(x: ReprC); + fn repr_u8(x: U8); + fn repr_isize(x: Isize); + fn option_ref(x: Option<&'static u8>); + fn option_fn(x: Option); + fn nonnull(x: Option>); + fn unique(x: Option>); +// { dg-error "" "" { target *-*-* } .-1 } + fn nonzero_u8(x: Option); + fn nonzero_u16(x: Option); + fn nonzero_u32(x: Option); + fn nonzero_u64(x: Option); + fn nonzero_u128(x: Option); +// { dg-error "" "" { target *-*-* } .-1 } + fn nonzero_usize(x: Option); + fn nonzero_i8(x: Option); + fn nonzero_i16(x: Option); + fn nonzero_i32(x: Option); + fn nonzero_i64(x: Option); + fn nonzero_i128(x: Option); +// { dg-error "" "" { target *-*-* } .-1 } + fn nonzero_isize(x: Option); + fn transparent_struct(x: Option>); + fn transparent_enum(x: Option>); + fn transparent_union(x: Option>); +// { dg-error "" "" { target *-*-* } .-1 } + fn repr_rust(x: Option>); // { dg-error "" "" { target *-*-* } } + fn no_result(x: Result<(), num::NonZeroI32>); // { dg-error "" "" { target *-*-* } } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-fn.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-fn.rs new file mode 100644 index 000000000000..ae231a2ea624 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes-fn.rs @@ -0,0 +1,182 @@ +#![feature(rustc_private)] + +#![allow(private_in_public)] +#![deny(improper_ctypes_definitions)] + +extern crate libc; + +use std::default::Default; +use std::marker::PhantomData; + +trait Mirror { type It: ?Sized; } + +impl Mirror for T { type It = Self; } + +#[repr(C)] +pub struct StructWithProjection(*mut ::It); + +#[repr(C)] +pub struct StructWithProjectionAndLifetime<'a>( + &'a mut as Mirror>::It +); + +pub type I32Pair = (i32, i32); + +#[repr(C)] +pub struct ZeroSize; + +pub type RustFn = fn(); + +pub type RustBadRet = extern fn() -> Box; + +pub type CVoidRet = (); + +pub struct Foo; + +#[repr(transparent)] +pub struct TransparentI128(i128); + +#[repr(transparent)] +pub struct TransparentStr(&'static str); + +#[repr(transparent)] +pub struct TransparentBadFn(RustBadRet); + +#[repr(transparent)] +pub struct TransparentInt(u32); + +#[repr(transparent)] +pub struct TransparentRef<'a>(&'a TransparentInt); + +#[repr(transparent)] +pub struct TransparentLifetime<'a>(*const u8, PhantomData<&'a ()>); + +#[repr(transparent)] +pub struct TransparentUnit(f32, PhantomData); + +#[repr(transparent)] +pub struct TransparentCustomZst(i32, ZeroSize); + +#[repr(C)] +pub struct ZeroSizeWithPhantomData(PhantomData); + +pub extern "C" fn ptr_type1(size: *const Foo) { } + +pub extern "C" fn ptr_type2(size: *const Foo) { } + +pub extern "C" fn slice_type(p: &[u32]) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn str_type(p: &str) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn box_type(p: Box) { } + +pub extern "C" fn opt_box_type(p: Option>) { } + +pub extern "C" fn char_type(p: char) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn i128_type(p: i128) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn u128_type(p: u128) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn tuple_type(p: (i32, i32)) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn tuple_type2(p: I32Pair) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn zero_size(p: ZeroSize) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData { +// { dg-error "" "" { target *-*-* } .-1 } + Default::default() +} + +pub extern "C" fn fn_type(p: RustFn) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn fn_type2(p: fn()) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn fn_contained(p: RustBadRet) { } + +pub extern "C" fn transparent_i128(p: TransparentI128) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn transparent_str(p: TransparentStr) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn transparent_fn(p: TransparentBadFn) { } + +pub extern "C" fn good3(fptr: Option) { } + +pub extern "C" fn good4(aptr: &[u8; 4 as usize]) { } + +pub extern "C" fn good5(s: StructWithProjection) { } + +pub extern "C" fn good6(s: StructWithProjectionAndLifetime) { } + +pub extern "C" fn good7(fptr: extern fn() -> ()) { } + +pub extern "C" fn good8(fptr: extern fn() -> !) { } + +pub extern "C" fn good9() -> () { } + +pub extern "C" fn good10() -> CVoidRet { } + +pub extern "C" fn good11(size: isize) { } + +pub extern "C" fn good12(size: usize) { } + +pub extern "C" fn good13(n: TransparentInt) { } + +pub extern "C" fn good14(p: TransparentRef) { } + +pub extern "C" fn good15(p: TransparentLifetime) { } + +pub extern "C" fn good16(p: TransparentUnit) { } + +pub extern "C" fn good17(p: TransparentCustomZst) { } + +#[allow(improper_ctypes_definitions)] +pub extern "C" fn good18(_: &String) { } + +#[cfg(not(target_arch = "wasm32"))] +pub extern "C" fn good1(size: *const libc::c_int) { } + +#[cfg(not(target_arch = "wasm32"))] +pub extern "C" fn good2(size: *const libc::c_uint) { } + +pub extern "C" fn unused_generic1(size: *const Foo) { } + +pub extern "C" fn unused_generic2() -> PhantomData { +// { dg-error "" "" { target *-*-* } .-1 } + Default::default() +} + +pub extern "C" fn used_generic1(x: T) { } + +pub extern "C" fn used_generic2(x: T, size: *const Foo) { } + +pub extern "C" fn used_generic3() -> T { + Default::default() +} + +pub extern "C" fn used_generic4(x: Vec) { } +// { dg-error "" "" { target *-*-* } .-1 } + +pub extern "C" fn used_generic5() -> Vec { +// { dg-error "" "" { target *-*-* } .-1 } + Default::default() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes.rs new file mode 100644 index 000000000000..e1142635ce02 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-ctypes.rs @@ -0,0 +1,111 @@ +#![feature(rustc_private)] + +#![allow(private_in_public)] +#![deny(improper_ctypes)] + +extern crate libc; + +use std::marker::PhantomData; + +trait Bar { } +trait Mirror { type It: ?Sized; } +impl Mirror for T { type It = Self; } +#[repr(C)] +pub struct StructWithProjection(*mut ::It); +#[repr(C)] +pub struct StructWithProjectionAndLifetime<'a>( + &'a mut as Mirror>::It +); +pub type I32Pair = (i32, i32); +#[repr(C)] +pub struct ZeroSize; +pub type RustFn = fn(); +pub type RustBadRet = extern fn() -> Box; +pub type CVoidRet = (); +pub struct Foo; +#[repr(transparent)] +pub struct TransparentI128(i128); +#[repr(transparent)] +pub struct TransparentStr(&'static str); +#[repr(transparent)] +pub struct TransparentBadFn(RustBadRet); +#[repr(transparent)] +pub struct TransparentInt(u32); +#[repr(transparent)] +pub struct TransparentRef<'a>(&'a TransparentInt); +#[repr(transparent)] +pub struct TransparentLifetime<'a>(*const u8, PhantomData<&'a ()>); +#[repr(transparent)] +pub struct TransparentUnit(f32, PhantomData); +#[repr(transparent)] +pub struct TransparentCustomZst(i32, ZeroSize); + +#[repr(C)] +pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData); + +extern { + pub fn ptr_type1(size: *const Foo); // { dg-error "" "" { target *-*-* } } + pub fn ptr_type2(size: *const Foo); // { dg-error "" "" { target *-*-* } } + pub fn slice_type(p: &[u32]); // { dg-error "" "" { target *-*-* } } + pub fn str_type(p: &str); // { dg-error "" "" { target *-*-* } } + pub fn box_type(p: Box); // { dg-error "" "" { target *-*-* } } + pub fn opt_box_type(p: Option>); +// { dg-error "" "" { target *-*-* } .-1 } + pub fn char_type(p: char); // { dg-error "" "" { target *-*-* } } + pub fn i128_type(p: i128); // { dg-error "" "" { target *-*-* } } + pub fn u128_type(p: u128); // { dg-error "" "" { target *-*-* } } + pub fn trait_type(p: &dyn Bar); // { dg-error "" "" { target *-*-* } } + pub fn tuple_type(p: (i32, i32)); // { dg-error "" "" { target *-*-* } } + pub fn tuple_type2(p: I32Pair); // { dg-error "" "" { target *-*-* } } + pub fn zero_size(p: ZeroSize); // { dg-error "" "" { target *-*-* } } + pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); +// { dg-error "" "" { target *-*-* } .-1 } + pub fn zero_size_phantom_toplevel() + -> ::std::marker::PhantomData; // { dg-error "" "" { target *-*-* } } + pub fn fn_type(p: RustFn); // { dg-error "" "" { target *-*-* } } + pub fn fn_type2(p: fn()); // { dg-error "" "" { target *-*-* } } + pub fn fn_contained(p: RustBadRet); // { dg-error "" "" { target *-*-* } } + pub fn transparent_i128(p: TransparentI128); // { dg-error "" "" { target *-*-* } } + pub fn transparent_str(p: TransparentStr); // { dg-error "" "" { target *-*-* } } + pub fn transparent_fn(p: TransparentBadFn); // { dg-error "" "" { target *-*-* } } + pub fn raw_array(arr: [u8; 8]); // { dg-error "" "" { target *-*-* } } + + pub static static_u128_type: u128; // { dg-error "" "" { target *-*-* } } + pub static static_u128_array_type: [u128; 16]; // { dg-error "" "" { target *-*-* } } + + pub fn good3(fptr: Option); + pub fn good4(aptr: &[u8; 4 as usize]); + pub fn good5(s: StructWithProjection); + pub fn good6(s: StructWithProjectionAndLifetime); + pub fn good7(fptr: extern fn() -> ()); + pub fn good8(fptr: extern fn() -> !); + pub fn good9() -> (); + pub fn good10() -> CVoidRet; + pub fn good11(size: isize); + pub fn good12(size: usize); + pub fn good13(n: TransparentInt); + pub fn good14(p: TransparentRef); + pub fn good15(p: TransparentLifetime); + pub fn good16(p: TransparentUnit); + pub fn good17(p: TransparentCustomZst); + #[allow(improper_ctypes)] + pub fn good18(_: &String); + pub fn good20(arr: *const [u8; 8]); + pub static good21: [u8; 8]; + +} + +#[allow(improper_ctypes)] +extern { + pub fn good19(_: &String); +} + +#[cfg(not(target_arch = "wasm32"))] +extern { + pub fn good1(size: *const libc::c_int); + pub fn good2(size: *const libc::c_uint); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-directives-on-use-items-issue-10534.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-directives-on-use-items-issue-10534.rs new file mode 100644 index 000000000000..585678338c76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-directives-on-use-items-issue-10534.rs @@ -0,0 +1,25 @@ +#![deny(unused_imports)] +#![allow(non_upper_case_globals)] + +// The aim of this test is to ensure that deny/allow/warn directives +// are applied to individual "use" statements instead of silently +// ignored. + +#[allow(dead_code)] +mod a { pub static x: isize = 3; pub static y: isize = 4; } + +mod b { + use a::x; // { dg-error "" "" { target *-*-* } } + #[allow(unused_imports)] + use a::y; // no error here +} + +#[allow(unused_imports)] +mod c { + use a::x; + #[deny(unused_imports)] + use a::y; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-exceeding-bitshifts.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-exceeding-bitshifts.rs new file mode 100644 index 000000000000..7127c227246c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-exceeding-bitshifts.rs @@ -0,0 +1,80 @@ +// revisions: noopt opt opt_with_overflow_checks +//[noopt]compile-flags: -C opt-level=0 +//[opt]compile-flags: -O +//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O +// build-pass +// ignore-pass (test emits codegen-time warnings and verifies that they are not errors) +// normalize-stderr-test "shift left by `(64|32)_usize`, which" -> "shift left by `%BITS%`, which" + +#![crate_type="lib"] +#![warn(arithmetic_overflow, const_err)] + + +pub trait Foo { + const N: i32; +} + +impl Foo for Vec { + const N: i32 = T::N << 42; // { dg-warning "" "" { target *-*-* } } +} + +pub fn foo(x: i32) { + let _ = x << 42; // { dg-warning "" "" { target *-*-* } } +} + +pub fn main() { + let n = 1u8 << 7; + let n = 1u8 << 8; // { dg-warning "" "" { target *-*-* } } + let n = 1u16 << 15; + let n = 1u16 << 16; // { dg-warning "" "" { target *-*-* } } + let n = 1u32 << 31; + let n = 1u32 << 32; // { dg-warning "" "" { target *-*-* } } + let n = 1u64 << 63; + let n = 1u64 << 64; // { dg-warning "" "" { target *-*-* } } + let n = 1i8 << 7; + let n = 1i8 << 8; // { dg-warning "" "" { target *-*-* } } + let n = 1i16 << 15; + let n = 1i16 << 16; // { dg-warning "" "" { target *-*-* } } + let n = 1i32 << 31; + let n = 1i32 << 32; // { dg-warning "" "" { target *-*-* } } + let n = 1i64 << 63; + let n = 1i64 << 64; // { dg-warning "" "" { target *-*-* } } + + let n = 1u8 >> 7; + let n = 1u8 >> 8; // { dg-warning "" "" { target *-*-* } } + let n = 1u16 >> 15; + let n = 1u16 >> 16; // { dg-warning "" "" { target *-*-* } } + let n = 1u32 >> 31; + let n = 1u32 >> 32; // { dg-warning "" "" { target *-*-* } } + let n = 1u64 >> 63; + let n = 1u64 >> 64; // { dg-warning "" "" { target *-*-* } } + let n = 1i8 >> 7; + let n = 1i8 >> 8; // { dg-warning "" "" { target *-*-* } } + let n = 1i16 >> 15; + let n = 1i16 >> 16; // { dg-warning "" "" { target *-*-* } } + let n = 1i32 >> 31; + let n = 1i32 >> 32; // { dg-warning "" "" { target *-*-* } } + let n = 1i64 >> 63; + let n = 1i64 >> 64; // { dg-warning "" "" { target *-*-* } } + + let n = 1u8; + let n = n << 7; + let n = n << 8; // { dg-warning "" "" { target *-*-* } } + + let n = 1u8 << -8; // { dg-warning "" "" { target *-*-* } } + + let n = 1i8<<(1isize+-1); + + let n = 1u8 << (4+3); + let n = 1u8 << (4+4); // { dg-warning "" "" { target *-*-* } } + let n = 1i64 >> [63][0]; + let n = 1i64 >> [64][0]; // { dg-warning "" "" { target *-*-* } } + + #[cfg(target_pointer_width = "32")] + const BITS: usize = 32; + #[cfg(target_pointer_width = "64")] + const BITS: usize = 64; + let n = 1_isize << BITS; // { dg-warning "" "" { target *-*-* } } + let n = 1_usize << BITS; // { dg-warning "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-forbid-attr.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-forbid-attr.rs new file mode 100644 index 000000000000..23ef4ebcee5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-forbid-attr.rs @@ -0,0 +1,9 @@ +#![forbid(deprecated)] + +#[allow(deprecated)] +// { dg-error ".E0453." "" { target *-*-* } .-1 } +// { dg-error ".E0453." "" { target *-*-* } .-2 } +// { dg-error ".E0453." "" { target *-*-* } .-3 } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-forbid-cmdline.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-forbid-cmdline.rs new file mode 100644 index 000000000000..30f809e3bdc9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-forbid-cmdline.rs @@ -0,0 +1,8 @@ +// compile-flags: -F deprecated + +#[allow(deprecated)] // { dg-error ".E0453." "" { target *-*-* } } +// { dg-error ".E0453." "" { target *-*-* } .-2 } +// { dg-error ".E0453." "" { target *-*-* } .-3 } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-forbid-internal-unsafe.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-forbid-internal-unsafe.rs new file mode 100644 index 000000000000..22d73a691f00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-forbid-internal-unsafe.rs @@ -0,0 +1,17 @@ +#![forbid(unsafe_code)] +#![feature(allow_internal_unsafe)] + +#[allow_internal_unsafe] +// { dg-error "" "" { target *-*-* } .-1 } +macro_rules! evil { + ($e:expr) => { + unsafe { + $e + } + } +} + +fn main() { + println!("{}", evil!(*(0 as *const u8))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-group-nonstandard-style.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-group-nonstandard-style.rs new file mode 100644 index 000000000000..e6701b9b80a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-group-nonstandard-style.rs @@ -0,0 +1,27 @@ +#![deny(nonstandard_style)] +#![allow(dead_code)] + +fn CamelCase() {} // { dg-error "" "" { target *-*-* } } + +#[allow(nonstandard_style)] +mod test { + fn CamelCase() {} + + #[forbid(nonstandard_style)] + mod bad { + fn CamelCase() {} // { dg-error "" "" { target *-*-* } } + + static bad: isize = 1; // { dg-error "" "" { target *-*-* } } + } + + mod warn { + #![warn(nonstandard_style)] + + fn CamelCase() {} // { dg-warning "" "" { target *-*-* } } + + struct snake_case; // { dg-warning "" "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-impl-fn.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-impl-fn.rs new file mode 100644 index 000000000000..080f8ec423f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-impl-fn.rs @@ -0,0 +1,34 @@ +#![allow(while_true)] +#![allow(dead_code)] + +struct A(isize); + +impl A { + fn foo(&self) { while true {} } + + #[deny(while_true)] + fn bar(&self) { while true {} } // { dg-error "" "" { target *-*-* } } +} + +#[deny(while_true)] +mod foo { + struct B(isize); + + impl B { + fn foo(&self) { while true {} } // { dg-error "" "" { target *-*-* } } + + #[allow(while_true)] + fn bar(&self) { while true {} } + } +} + +#[deny(while_true)] +fn main() { + while true {} // { dg-error "" "" { target *-*-* } } +} + +#[deny(while_true)] +fn bar() { + while cfg!(unix) {} // no error +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-incoherent-auto-trait-objects.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-incoherent-auto-trait-objects.rs new file mode 100644 index 000000000000..aa4987919056 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-incoherent-auto-trait-objects.rs @@ -0,0 +1,20 @@ +trait Foo {} + +impl Foo for dyn Send {} + +impl Foo for dyn Send + Send {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +impl Foo for dyn Send + Sync {} + +impl Foo for dyn Sync + Send {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +impl Foo for dyn Send + Sync + Send {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-lowercase-static-const-pattern-rename.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-lowercase-static-const-pattern-rename.rs new file mode 100644 index 000000000000..b2866904b7ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-lowercase-static-const-pattern-rename.rs @@ -0,0 +1,64 @@ +// check-pass +// Issue #7526: lowercase static constants in patterns look like bindings + +// This is similar to lint-lowercase-static-const-pattern.rs, except it +// shows the expected usual workaround (choosing a different name for +// the static definition) and also demonstrates that one can work +// around this problem locally by renaming the constant in the `use` +// form to an uppercase identifier that placates the lint. + +#![deny(non_upper_case_globals)] + +pub const A : isize = 97; + +fn f() { + let r = match (0,0) { + (0, A) => 0, + (x, y) => 1 + x + y, + }; + assert_eq!(r, 1); + let r = match (0,97) { + (0, A) => 0, + (x, y) => 1 + x + y, + }; + assert_eq!(r, 0); +} + +mod m { + #[allow(non_upper_case_globals)] + pub const aha : isize = 7; +} + +fn g() { + use self::m::aha as AHA; + let r = match (0,0) { + (0, AHA) => 0, + (x, y) => 1 + x + y, + }; + assert_eq!(r, 1); + let r = match (0,7) { + (0, AHA) => 0, + (x, y) => 1 + x + y, + }; + assert_eq!(r, 0); +} + +fn h() { + let r = match (0,0) { + (0, self::m::aha) => 0, + (x, y) => 1 + x + y, + }; + assert_eq!(r, 1); + let r = match (0,7) { + (0, self::m::aha) => 0, + (x, y) => 1 + x + y, + }; + assert_eq!(r, 0); +} + +pub fn main () { + f(); + g(); + h(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-lowercase-static-const-pattern.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-lowercase-static-const-pattern.rs new file mode 100644 index 000000000000..8aa2382bcf5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-lowercase-static-const-pattern.rs @@ -0,0 +1,52 @@ +// Issue #7526: lowercase static constants in patterns look like bindings + +#![allow(dead_code)] +#![deny(non_upper_case_globals)] + +#[allow(non_upper_case_globals)] +pub const a : isize = 97; + +fn f() { + let r = match (0,0) { + (0, a) => 0, +// { dg-error "" "" { target *-*-* } .-1 } + (x, y) => 1 + x + y, + }; + assert_eq!(r, 1); +} + +mod m { + #[allow(non_upper_case_globals)] + pub const aha : isize = 7; +} + +fn g() { + use self::m::aha; + let r = match (0,0) { + (0, aha) => 0, +// { dg-error "" "" { target *-*-* } .-1 } + (x, y) => 1 + x + y, + }; + assert_eq!(r, 1); +} + +mod n { + pub const OKAY : isize = 8; +} + +fn h() { + use self::n::OKAY as not_okay; + let r = match (0,0) { + (0, not_okay) => 0, +// { dg-error "" "" { target *-*-* } .-1 } + (x, y) => 1 + x + y, + }; + assert_eq!(r, 1); +} + +fn main () { + f(); + g(); + h(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-malformed.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-malformed.rs new file mode 100644 index 000000000000..1f2b751bbafd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-malformed.rs @@ -0,0 +1,9 @@ +#![deny = "foo"] // { dg-error "" "" { target *-*-* } } +#![allow(bar = "baz")] // { dg-error ".E0452." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-error "" "" { target *-*-* } .-6 } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-match-arms.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-match-arms.rs new file mode 100644 index 000000000000..8960af57d0d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-match-arms.rs @@ -0,0 +1,19 @@ +fn deny_on_arm() { + match 0 { + #[deny(unused_variables)] +// { dg-note "" "" { target *-*-* } .-1 } + y => (), +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +#[deny(unused_variables)] +fn allow_on_arm() { + match 0 { + #[allow(unused_variables)] + y => (), // OK + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-misplaced-attr.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-misplaced-attr.rs new file mode 100644 index 000000000000..01338ebc1018 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-misplaced-attr.rs @@ -0,0 +1,13 @@ +// When denying at the crate level, be sure to not get random warnings from the +// injected intrinsics by the compiler. + +#![deny(unused_attributes)] + +mod a { + #![crate_type = "bin"] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[crate_type = "bin"] fn main() {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-missing-copy-implementations.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-missing-copy-implementations.rs new file mode 100644 index 000000000000..eee3608edbba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-missing-copy-implementations.rs @@ -0,0 +1,16 @@ +// See issue 19712 + +#![deny(missing_copy_implementations)] + +mod inner { + pub struct Foo { // { dg-error "" "" { target *-*-* } } + pub field: i32 + } +} + +pub fn foo() -> inner::Foo { + inner::Foo { field: 42 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-missing-doc.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-missing-doc.rs new file mode 100644 index 000000000000..57ca7aea7857 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-missing-doc.rs @@ -0,0 +1,204 @@ +// When denying at the crate level, be sure to not get random warnings from the +// injected intrinsics by the compiler. +#![deny(missing_docs)] +#![allow(dead_code)] +#![feature(associated_type_defaults, extern_types)] + +//! Some garbage docs for the crate here +#![doc="More garbage"] + +type Typedef = String; +pub type PubTypedef = String; // { dg-error "" "" { target *-*-* } } + +struct Foo { + a: isize, + b: isize, +} + +pub struct PubFoo { // { dg-error "" "" { target *-*-* } } + pub a: isize, // { dg-error "" "" { target *-*-* } } + b: isize, +} + +#[allow(missing_docs)] +pub struct PubFoo2 { + pub a: isize, + pub c: isize, +} + +mod module_no_dox {} +pub mod pub_module_no_dox {} // { dg-error "" "" { target *-*-* } } + +/// dox +pub fn foo() {} +pub fn foo2() {} // { dg-error "" "" { target *-*-* } } +fn foo3() {} +#[allow(missing_docs)] pub fn foo4() {} + +/// dox +pub trait A { + /// dox + fn foo(&self); + /// dox + fn foo_with_impl(&self) {} +} + +#[allow(missing_docs)] +trait B { + fn foo(&self); + fn foo_with_impl(&self) {} +} + +pub trait C { // { dg-error "" "" { target *-*-* } } + fn foo(&self); // { dg-error "" "" { target *-*-* } } + fn foo_with_impl(&self) {} // { dg-error "" "" { target *-*-* } } +} + +#[allow(missing_docs)] +pub trait D { + fn dummy(&self) { } +} + +/// dox +pub trait E: Sized { + type AssociatedType; // { dg-error "" "" { target *-*-* } } + type AssociatedTypeDef = Self; // { dg-error "" "" { target *-*-* } } + + /// dox + type DocumentedType; + /// dox + type DocumentedTypeDef = Self; + /// dox + fn dummy(&self) {} +} + +impl Foo { + pub fn foo() {} + fn bar() {} +} + +impl PubFoo { + pub fn foo() {} // { dg-error "" "" { target *-*-* } } + /// dox + pub fn foo1() {} + fn foo2() {} + #[allow(missing_docs)] pub fn foo3() {} +} + +#[allow(missing_docs)] +trait F { + fn a(); + fn b(&self); +} + +// should need to redefine documentation for implementations of traits +impl F for Foo { + fn a() {} + fn b(&self) {} +} + +// It sure is nice if doc(hidden) implies allow(missing_docs), and that it +// applies recursively +#[doc(hidden)] +mod a { + pub fn baz() {} + pub mod b { + pub fn baz() {} + } +} + +enum Baz { + BazA { + a: isize, + b: isize + }, + BarB +} + +pub enum PubBaz { // { dg-error "" "" { target *-*-* } } + PubBazA { // { dg-error "" "" { target *-*-* } } + a: isize, // { dg-error "" "" { target *-*-* } } + }, +} + +/// dox +pub enum PubBaz2 { + /// dox + PubBaz2A { + /// dox + a: isize, + }, +} + +#[allow(missing_docs)] +pub enum PubBaz3 { + PubBaz3A { + b: isize + }, +} + +#[doc(hidden)] +pub fn baz() {} + + +const FOO: u32 = 0; +/// dox +pub const FOO1: u32 = 0; +#[allow(missing_docs)] +pub const FOO2: u32 = 0; +#[doc(hidden)] +pub const FOO3: u32 = 0; +pub const FOO4: u32 = 0; // { dg-error "" "" { target *-*-* } } + + +static BAR: u32 = 0; +/// dox +pub static BAR1: u32 = 0; +#[allow(missing_docs)] +pub static BAR2: u32 = 0; +#[doc(hidden)] +pub static BAR3: u32 = 0; +pub static BAR4: u32 = 0; // { dg-error "" "" { target *-*-* } } + + +mod internal_impl { + /// dox + pub fn documented() {} + pub fn undocumented1() {} // { dg-error "" "" { target *-*-* } } + pub fn undocumented2() {} // { dg-error "" "" { target *-*-* } } + fn undocumented3() {} + /// dox + pub mod globbed { + /// dox + pub fn also_documented() {} + pub fn also_undocumented1() {} // { dg-error "" "" { target *-*-* } } + fn also_undocumented2() {} + } +} +/// dox +pub mod public_interface { + pub use internal_impl::documented as foo; + pub use internal_impl::undocumented1 as bar; + pub use internal_impl::{documented, undocumented2}; + pub use internal_impl::globbed::*; +} + +extern "C" { + /// dox + pub fn extern_fn_documented(f: f32) -> f32; + pub fn extern_fn_undocumented(f: f32) -> f32; +// { dg-error "" "" { target *-*-* } .-1 } + + /// dox + pub static EXTERN_STATIC_DOCUMENTED: u8; + pub static EXTERN_STATIC_UNDOCUMENTED: u8; +// { dg-error "" "" { target *-*-* } .-1 } + + /// dox + pub type ExternTyDocumented; + pub type ExternTyUndocumented; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-non-camel-case-types.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-non-camel-case-types.rs new file mode 100644 index 000000000000..cfc07c2467e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-non-camel-case-types.rs @@ -0,0 +1,38 @@ +#![forbid(non_camel_case_types)] +#![allow(dead_code)] + +struct ONE_TWO_THREE; +// { dg-error "" "" { target *-*-* } .-1 } + +struct foo { // { dg-error "" "" { target *-*-* } } + bar: isize, +} + +enum foo2 { // { dg-error "" "" { target *-*-* } } + Bar +} + +struct foo3 { // { dg-error "" "" { target *-*-* } } + bar: isize +} + +type foo4 = isize; // { dg-error "" "" { target *-*-* } } + +enum Foo5 { + bar // { dg-error "" "" { target *-*-* } } +} + +trait foo6 { // { dg-error "" "" { target *-*-* } } + type foo7; // { dg-error "" "" { target *-*-* } } + fn dummy(&self) { } +} + +fn f(_: ty) {} // { dg-error "" "" { target *-*-* } } + +#[repr(C)] +struct foo7 { + bar: isize, +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-non-camel-case-variant.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-non-camel-case-variant.rs new file mode 100644 index 000000000000..6092dfe2dd22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-non-camel-case-variant.rs @@ -0,0 +1,11 @@ +// check-pass + +#![deny(non_camel_case_types)] + +pub enum Foo { + #[allow(non_camel_case_types)] + bar +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-non-camel-case-with-trailing-underscores.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-non-camel-case-with-trailing-underscores.rs new file mode 100644 index 000000000000..aeb866123b32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-non-camel-case-with-trailing-underscores.rs @@ -0,0 +1,12 @@ +// check-pass + +#![allow(dead_code)] +// This is ok because we often use the trailing underscore to mean 'prime' + +// pretty-expanded FIXME #23616 + +#[forbid(non_camel_case_types)] +type Foo_ = isize; + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-crate-2.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-crate-2.rs new file mode 100644 index 000000000000..9a22372c3370 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-crate-2.rs @@ -0,0 +1,7 @@ +// compile-flags: --crate-name NonSnakeCase +// error-pattern: crate `NonSnakeCase` should have a snake case name + +#![deny(non_snake_case)] + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-crate.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-crate.rs new file mode 100644 index 000000000000..9c9fd74f0d3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-crate.rs @@ -0,0 +1,6 @@ +#![crate_name = "NonSnakeCase"] +// { dg-error "" "" { target *-*-* } .-1 } +#![deny(non_snake_case)] + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-functions.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-functions.rs new file mode 100644 index 000000000000..3d3a837f1fd8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-functions.rs @@ -0,0 +1,45 @@ +#![deny(non_snake_case)] +#![allow(dead_code)] + +struct Foo; + +impl Foo { + fn Foo_Method() {} +// { dg-error "" "" { target *-*-* } .-1 } + + // Don't allow two underscores in a row + fn foo__method(&self) {} +// { dg-error "" "" { target *-*-* } .-1 } + + pub fn xyZ(&mut self) {} +// { dg-error "" "" { target *-*-* } .-1 } + + fn render_HTML() {} +// { dg-error "" "" { target *-*-* } .-1 } +} + +trait X { + fn ABC(); +// { dg-error "" "" { target *-*-* } .-1 } + + fn a_b_C(&self) {} +// { dg-error "" "" { target *-*-* } .-1 } + + fn something__else(&mut self); +// { dg-error "" "" { target *-*-* } .-1 } +} + +impl X for Foo { + // These errors should be caught at the trait definition not the impl + fn ABC() {} + fn something__else(&mut self) {} +} + +fn Cookie() {} +// { dg-error "" "" { target *-*-* } .-1 } + +pub fn bi_S_Cuit() {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-lifetimes.rs new file mode 100644 index 000000000000..ee2cdc052f4c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-lifetimes.rs @@ -0,0 +1,9 @@ +#![deny(non_snake_case)] +#![allow(dead_code)] + +fn f<'FooBar>( // { dg-error "" "" { target *-*-* } } + _: &'FooBar () +) {} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-modules.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-modules.rs new file mode 100644 index 000000000000..2595d76638a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-modules.rs @@ -0,0 +1,11 @@ +#![deny(non_snake_case)] +#![allow(dead_code)] + +mod FooBar { // { dg-error "" "" { target *-*-* } } + pub struct S; +} + +fn f(_: FooBar::S) { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs new file mode 100644 index 000000000000..cf1331b88360 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-non-snake-case-no-lowercase-equivalent.rs @@ -0,0 +1,13 @@ +// check-pass + +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#![feature(non_ascii_idents)] +#![deny(non_snake_case)] + +// This name is neither upper nor lower case +fn 你好() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-non-uppercase-associated-const.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-non-uppercase-associated-const.rs new file mode 100644 index 000000000000..dbdc72bae744 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-non-uppercase-associated-const.rs @@ -0,0 +1,12 @@ +#![deny(non_upper_case_globals)] +#![allow(dead_code)] + +struct Foo; + +impl Foo { + const not_upper: bool = true; +} +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-non-uppercase-statics.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-non-uppercase-statics.rs new file mode 100644 index 000000000000..e50fb49a1c4d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-non-uppercase-statics.rs @@ -0,0 +1,12 @@ +#![forbid(non_upper_case_globals)] +#![allow(dead_code)] + +static foo: isize = 1; // { dg-error "" "" { target *-*-* } } + +static mut bar: isize = 1; // { dg-error "" "" { target *-*-* } } + +#[no_mangle] +pub static extern_foo: isize = 1; // OK, because #[no_mangle] supersedes the warning + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-nonstandard-style-unicode-1.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-nonstandard-style-unicode-1.rs new file mode 100644 index 000000000000..a99d0e46a75f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-nonstandard-style-unicode-1.rs @@ -0,0 +1,51 @@ +#![allow(dead_code)] + +#![forbid(non_camel_case_types)] +#![feature(non_ascii_idents)] + +// Some scripts (e.g., hiragana) don't have a concept of +// upper/lowercase + +// 1. non_camel_case_types + +// Can start with non-lowercase letter +struct Θχ; +struct ヒa; + +struct χa; +// { dg-error "" "" { target *-*-* } .-1 } + +// If there's already leading or trailing underscores, they get trimmed before checking. +// This is fine: +struct _ヒb; + +// This is not: +struct __χa; +// { dg-error "" "" { target *-*-* } .-1 } + +// Besides this, we cannot have two continuous underscores in the middle. + +struct 对__否; +// { dg-error "" "" { target *-*-* } .-1 } + +struct ヒ__χ; +// { dg-error "" "" { target *-*-* } .-1 } + +// also cannot have lowercase letter next to a underscore. +// so this triggers the lint: + +struct Hello_你好; +// { dg-error "" "" { target *-*-* } .-1 } + +struct Hello_World; +// { dg-error "" "" { target *-*-* } .-1 } + +struct 你_ӟ; +// { dg-error "" "" { target *-*-* } .-1 } + +// and this is ok: + +struct 你_好; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-nonstandard-style-unicode-2.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-nonstandard-style-unicode-2.rs new file mode 100644 index 000000000000..a2b878eee3dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-nonstandard-style-unicode-2.rs @@ -0,0 +1,31 @@ +#![allow(dead_code)] + +#![forbid(non_snake_case)] +#![feature(non_ascii_idents)] + +// Some scripts (e.g., hiragana) don't have a concept of +// upper/lowercase + +// 2. non_snake_case + +// Can only use non-uppercase letters. +// So this works: + +fn 编程() {} + +// but this doesn't: + +fn Ц() {} +// { dg-error "" "" { target *-*-* } .-1 } + +// besides this, you cannot use continuous underscores in the middle + +fn 分__隔() {} +// { dg-error "" "" { target *-*-* } .-1 } + +// but you can use them both at the beginning and at the end. + +fn _______不_连_续_的_存_在_______() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-nonstandard-style-unicode-3.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-nonstandard-style-unicode-3.rs new file mode 100644 index 000000000000..dc176cf0a54a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-nonstandard-style-unicode-3.rs @@ -0,0 +1,26 @@ +#![allow(dead_code)] + +#![forbid(non_upper_case_globals)] +#![feature(non_ascii_idents)] + +// Some scripts (e.g., hiragana) don't have a concept of +// upper/lowercase + +// 3. non_upper_case_globals + +// Can only use non-lowercase letters. +// So this works: + +static ラ: usize = 0; + +// but this doesn't: + +static τεχ: f32 = 3.14159265; +// { dg-error "" "" { target *-*-* } .-1 } + +// This has no limit at all on underscore usages. + +static __密__封__线__内__禁__止__答__题__: bool = true; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-output-format-2.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-output-format-2.rs new file mode 100644 index 000000000000..f5f5bdd3ae42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-output-format-2.rs @@ -0,0 +1,16 @@ +// aux-build:lint_output_format.rs + +#![feature(unstable_test_feature)] +// check-pass + +extern crate lint_output_format; +use lint_output_format::{foo, bar}; +// { dg-warning "" "" { target *-*-* } .-1 } + + +fn main() { + let _x = foo(); +// { dg-warning "" "" { target *-*-* } .-1 } + let _y = bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-output-format.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-output-format.rs new file mode 100644 index 000000000000..ec919f73a330 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-output-format.rs @@ -0,0 +1,13 @@ +// compile-flags: -F unused_features +// aux-build:lint_output_format.rs + +#![allow(deprecated)] + +extern crate lint_output_format; // { dg-error ".E0658." "" { target *-*-* } } +use lint_output_format::{foo, bar}; // { dg-error ".E0658." "" { target *-*-* } } + +fn main() { + let _x = foo(); + let _y = bar(); // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-owned-heap-memory.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-owned-heap-memory.rs new file mode 100644 index 000000000000..8fb4ce024a7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-owned-heap-memory.rs @@ -0,0 +1,13 @@ +#![allow(dead_code)] +#![forbid(box_pointers)] +#![feature(box_syntax)] + +struct Foo { + x: Box // { dg-error "" "" { target *-*-* } } +} + +fn main() { + let _x : Foo = Foo {x : box 10}; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-pre-expansion-extern-module.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-pre-expansion-extern-module.rs new file mode 100644 index 000000000000..062e52543d71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-pre-expansion-extern-module.rs @@ -0,0 +1,8 @@ +// check-pass +// compile-flags: -W rust-2018-compatibility +// error-pattern: `try` is a keyword in the 2018 edition + +fn main() {} + +mod lint_pre_expansion_extern_module_aux; + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-qualification.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-qualification.rs new file mode 100644 index 000000000000..e96da8ca3c72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-qualification.rs @@ -0,0 +1,21 @@ +#![deny(unused_qualifications)] +#![allow(deprecated)] + +mod foo { + pub fn bar() {} +} + +fn main() { + use foo::bar; + foo::bar(); // { dg-error "" "" { target *-*-* } } + bar(); + + let _ = || -> Result<(), ()> { try!(Ok(())); Ok(()) }; // issue #37345 + + macro_rules! m { () => { + $crate::foo::bar(); // issue #37357 + ::foo::bar(); // issue #38682 + } } + m!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-range-endpoint-overflow.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-range-endpoint-overflow.rs new file mode 100644 index 000000000000..12c2ff4b40cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-range-endpoint-overflow.rs @@ -0,0 +1,18 @@ +#![deny(overflowing_literals)] + +fn main() { + let range_a = 0..256; // { dg-error "" "" { target *-*-* } } + let range_b = 0..=255; // ok + let range_c = 0..=256; // { dg-error "" "" { target *-*-* } } + let range_d = 256..5; // { dg-error "" "" { target *-*-* } } + let range_e = 0..257; // { dg-error "" "" { target *-*-* } } + let _range_f = 0..256u8; // { dg-error "" "" { target *-*-* } } + let _range_g = 0..128i8; // { dg-error "" "" { target *-*-* } } + + range_a.collect::>(); + range_b.collect::>(); + range_c.collect::>(); + range_d.collect::>(); + range_e.collect::>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-removed-allow.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-removed-allow.rs new file mode 100644 index 000000000000..14fddee56537 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-removed-allow.rs @@ -0,0 +1,9 @@ +// No warnings about removed lint when +// allow(renamed_and_removed_lints) + +#![allow(renamed_and_removed_lints)] + +#[deny(raw_pointer_derive)] +#[deny(unused_variables)] +fn main() { let unused = (); } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-removed-cmdline.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-removed-cmdline.rs new file mode 100644 index 000000000000..d4ab813af9d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-removed-cmdline.rs @@ -0,0 +1,13 @@ +// The raw_pointer_derived lint warns about its removal +// cc #30346 + +// compile-flags:-D raw_pointer_derive + +// error-pattern:lint `raw_pointer_derive` has been removed +// error-pattern:requested on the command line with `-D raw_pointer_derive` + +#![warn(unused)] + +#[deny(warnings)] +fn main() { let unused = (); } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-removed.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-removed.rs new file mode 100644 index 000000000000..e0ea14a5af6a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-removed.rs @@ -0,0 +1,9 @@ +// The raw_pointer_derived lint was removed, but is now reported by +// the renamed_and_removed_lints lint, which means it's a warning by +// default, and allowed in cargo dependency builds. +// cc #30346 + +#[deny(raw_pointer_derive)] // { dg-warning "" "" { target *-*-* } } +#[deny(unused_variables)] +fn main() { let unused = (); } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-renamed-allow.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-renamed-allow.rs new file mode 100644 index 000000000000..8044136c95bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-renamed-allow.rs @@ -0,0 +1,9 @@ +// No warnings about renamed lint when +// allow(renamed_and_removed_lints) + +#![allow(renamed_and_removed_lints)] + +#[deny(single_use_lifetime)] +#[deny(unused)] +fn main() { let unused = (); } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-renamed-cmdline.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-renamed-cmdline.rs new file mode 100644 index 000000000000..562c09348fd5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-renamed-cmdline.rs @@ -0,0 +1,9 @@ +// compile-flags:-D bare_trait_object + +// error-pattern:lint `bare_trait_object` has been renamed to `bare_trait_objects` +// error-pattern:requested on the command line with `-D bare_trait_object` +// error-pattern:unused + +#[deny(unused)] +fn main() { let unused = (); } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-renamed.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-renamed.rs new file mode 100644 index 000000000000..b25da4a4b441 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-renamed.rs @@ -0,0 +1,5 @@ +#[deny(bare_trait_object)] +// { dg-warning "" "" { target *-*-* } .-1 } +#[deny(unused)] +fn main() { let unused = (); } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-shorthand-field.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-shorthand-field.rs new file mode 100644 index 000000000000..3a557d468f91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-shorthand-field.rs @@ -0,0 +1,71 @@ +// run-rustfix + +#![allow(nonstandard_style, unused_variables, unused_mut)] +#![deny(non_shorthand_field_patterns)] + +struct Foo { + x: isize, + y: isize, +} + +fn main() { + { + let Foo { + x: x, // { dg-error "" "" { target *-*-* } } + y: ref y, // { dg-error "" "" { target *-*-* } } + } = Foo { x: 0, y: 0 }; + + let Foo { + x, + ref y, + } = Foo { x: 0, y: 0 }; + } + + { + const x: isize = 1; + + match (Foo { x: 1, y: 1 }) { + Foo { x: x, ..} => {}, + _ => {}, + } + } + + { + struct Bar { + x: x, + } + + struct x; + + match (Bar { x: x }) { + Bar { x: x } => {}, + } + } + + { + struct Bar { + x: Foo, + } + + enum Foo { x } + + match (Bar { x: Foo::x }) { + Bar { x: Foo::x } => {}, + } + } + + { + struct Baz { + x: isize, + y: isize, + z: isize, + } + + let Baz { + x: mut x, // { dg-error "" "" { target *-*-* } } + y: ref y, // { dg-error "" "" { target *-*-* } } + z: ref mut z, // { dg-error "" "" { target *-*-* } } + } = Baz { x: 0, y: 0, z: 0 }; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-stability-2.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-stability-2.rs new file mode 100644 index 000000000000..545debc976b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-stability-2.rs @@ -0,0 +1,414 @@ +// aux-build:lint_stability.rs +// aux-build:stability_cfg1.rs + +#![allow(deprecated)] +#![allow(dead_code)] +#![feature(staged_api)] + +#![stable(feature = "rust1", since = "1.0.0")] + +#[macro_use] +extern crate lint_stability; + +mod cross_crate { + extern crate stability_cfg1; + + use lint_stability::*; + + fn test() { + type Foo = MethodTester; + let foo = MethodTester; + + deprecated(); + foo.method_deprecated(); + Foo::method_deprecated(&foo); + ::method_deprecated(&foo); + foo.trait_deprecated(); + Trait::trait_deprecated(&foo); + ::trait_deprecated(&foo); + ::trait_deprecated(&foo); + + deprecated_text(); + foo.method_deprecated_text(); + Foo::method_deprecated_text(&foo); + ::method_deprecated_text(&foo); + foo.trait_deprecated_text(); + Trait::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + + foo.method_deprecated_unstable(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + Foo::method_deprecated_unstable(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::method_deprecated_unstable(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + foo.trait_deprecated_unstable(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::trait_deprecated_unstable(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + + foo.method_deprecated_unstable_text(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + Foo::method_deprecated_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::method_deprecated_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + foo.trait_deprecated_unstable_text(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::trait_deprecated_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + + foo.method_unstable(); // { dg-error ".E0658." "" { target *-*-* } } + Foo::method_unstable(&foo); // { dg-error ".E0658." "" { target *-*-* } } + ::method_unstable(&foo); // { dg-error ".E0658." "" { target *-*-* } } + foo.trait_unstable(); // { dg-error ".E0658." "" { target *-*-* } } + ::trait_unstable(&foo); // { dg-error ".E0658." "" { target *-*-* } } + + foo.method_unstable_text(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + Foo::method_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::method_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + foo.trait_unstable_text(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::trait_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + + stable(); + foo.method_stable(); + Foo::method_stable(&foo); + ::method_stable(&foo); + foo.trait_stable(); + Trait::trait_stable(&foo); + ::trait_stable(&foo); + ::trait_stable(&foo); + + stable_text(); + foo.method_stable_text(); + Foo::method_stable_text(&foo); + ::method_stable_text(&foo); + foo.trait_stable_text(); + Trait::trait_stable_text(&foo); + ::trait_stable_text(&foo); + ::trait_stable_text(&foo); + + struct S2(T::TypeDeprecated); + + let _ = DeprecatedStruct { + i: 0 + }; + let _ = StableStruct { i: 0 }; + + let _ = DeprecatedUnitStruct; + let _ = StableUnitStruct; + + let _ = Enum::DeprecatedVariant; + let _ = Enum::StableVariant; + + let _ = DeprecatedTupleStruct (1); + let _ = StableTupleStruct (1); + + // At the moment, the lint checker only checks stability in + // in the arguments of macros. + // Eventually, we will want to lint the contents of the + // macro in the module *defining* it. Also, stability levels + // on macros themselves are not yet linted. + macro_test_arg!(deprecated_text()); + macro_test_arg!(macro_test_arg!(deprecated_text())); + } + + fn test_method_param(foo: Foo) { + foo.trait_deprecated(); + Trait::trait_deprecated(&foo); + ::trait_deprecated(&foo); + ::trait_deprecated(&foo); + foo.trait_deprecated_text(); + Trait::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + foo.trait_deprecated_unstable(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::trait_deprecated_unstable(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + foo.trait_deprecated_unstable_text(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::trait_deprecated_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + foo.trait_unstable(); // { dg-error ".E0658." "" { target *-*-* } } + ::trait_unstable(&foo); // { dg-error ".E0658." "" { target *-*-* } } + foo.trait_unstable_text(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::trait_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + foo.trait_stable(); + Trait::trait_stable(&foo); + ::trait_stable(&foo); + ::trait_stable(&foo); + } + + fn test_method_object(foo: &dyn Trait) { + foo.trait_deprecated(); + foo.trait_deprecated_text(); + foo.trait_deprecated_unstable(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + foo.trait_deprecated_unstable_text(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + foo.trait_unstable(); // { dg-error ".E0658." "" { target *-*-* } } + foo.trait_unstable_text(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + foo.trait_stable(); + } + + struct S; + + impl DeprecatedTrait for S {} + trait LocalTrait2 : DeprecatedTrait { } +} + +mod this_crate { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn deprecated() {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn deprecated_text() {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub fn unstable() {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + pub fn unstable_text() {} + + #[stable(feature = "rust1", since = "1.0.0")] + pub fn stable() {} + #[stable(feature = "rust1", since = "1.0.0")] + pub fn stable_text() {} + + #[stable(feature = "rust1", since = "1.0.0")] + pub struct MethodTester; + + impl MethodTester { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated(&self) {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub fn method_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + pub fn method_unstable_text(&self) {} + + #[stable(feature = "rust1", since = "1.0.0")] + pub fn method_stable(&self) {} + #[stable(feature = "rust1", since = "1.0.0")] + pub fn method_stable_text(&self) {} + } + + pub trait Trait { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated(&self) {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + fn trait_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + fn trait_unstable_text(&self) {} + + #[stable(feature = "rust1", since = "1.0.0")] + fn trait_stable(&self) {} + #[stable(feature = "rust1", since = "1.0.0")] + fn trait_stable_text(&self) {} + } + + impl Trait for MethodTester {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub struct DeprecatedStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize + } + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub struct UnstableStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize + } + #[stable(feature = "rust1", since = "1.0.0")] + pub struct StableStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub struct DeprecatedUnitStruct; + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub struct UnstableUnitStruct; + #[stable(feature = "rust1", since = "1.0.0")] + pub struct StableUnitStruct; + + pub enum Enum { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + DeprecatedVariant, + #[unstable(feature = "unstable_test_feature", issue = "none")] + UnstableVariant, + + #[stable(feature = "rust1", since = "1.0.0")] + StableVariant, + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub struct DeprecatedTupleStruct(isize); + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub struct UnstableTupleStruct(isize); + #[stable(feature = "rust1", since = "1.0.0")] + pub struct StableTupleStruct(isize); + + fn test() { + // Only the deprecated cases of the following should generate + // errors, because other stability attributes now have meaning + // only *across* crates, not within a single crate. + + type Foo = MethodTester; + let foo = MethodTester; + + deprecated(); + foo.method_deprecated(); + Foo::method_deprecated(&foo); + ::method_deprecated(&foo); + foo.trait_deprecated(); + Trait::trait_deprecated(&foo); + ::trait_deprecated(&foo); + ::trait_deprecated(&foo); + + deprecated_text(); + foo.method_deprecated_text(); + Foo::method_deprecated_text(&foo); + ::method_deprecated_text(&foo); + foo.trait_deprecated_text(); + Trait::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + + unstable(); + foo.method_unstable(); + Foo::method_unstable(&foo); + ::method_unstable(&foo); + foo.trait_unstable(); + Trait::trait_unstable(&foo); + ::trait_unstable(&foo); + ::trait_unstable(&foo); + + unstable_text(); + foo.method_unstable_text(); + Foo::method_unstable_text(&foo); + ::method_unstable_text(&foo); + foo.trait_unstable_text(); + Trait::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + + stable(); + foo.method_stable(); + Foo::method_stable(&foo); + ::method_stable(&foo); + foo.trait_stable(); + Trait::trait_stable(&foo); + ::trait_stable(&foo); + ::trait_stable(&foo); + + stable_text(); + foo.method_stable_text(); + Foo::method_stable_text(&foo); + ::method_stable_text(&foo); + foo.trait_stable_text(); + Trait::trait_stable_text(&foo); + ::trait_stable_text(&foo); + ::trait_stable_text(&foo); + + let _ = DeprecatedStruct { + i: 0 + }; + let _ = UnstableStruct { i: 0 }; + let _ = StableStruct { i: 0 }; + + let _ = DeprecatedUnitStruct; + let _ = UnstableUnitStruct; + let _ = StableUnitStruct; + + let _ = Enum::DeprecatedVariant; + let _ = Enum::UnstableVariant; + let _ = Enum::StableVariant; + + let _ = DeprecatedTupleStruct (1); + let _ = UnstableTupleStruct (1); + let _ = StableTupleStruct (1); + } + + fn test_method_param(foo: Foo) { + foo.trait_deprecated(); + Trait::trait_deprecated(&foo); + ::trait_deprecated(&foo); + ::trait_deprecated(&foo); + foo.trait_deprecated_text(); + Trait::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + foo.trait_unstable(); + Trait::trait_unstable(&foo); + ::trait_unstable(&foo); + ::trait_unstable(&foo); + foo.trait_unstable_text(); + Trait::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + foo.trait_stable(); + Trait::trait_stable(&foo); + ::trait_stable(&foo); + ::trait_stable(&foo); + } + + fn test_method_object(foo: &dyn Trait) { + foo.trait_deprecated(); + foo.trait_deprecated_text(); + foo.trait_unstable(); + foo.trait_unstable_text(); + foo.trait_stable(); + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn test_fn_body() { + fn fn_in_body() {} + fn_in_body(); + } + + impl MethodTester { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn test_method_body(&self) { + fn fn_in_body() {} + fn_in_body(); + } + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub trait DeprecatedTrait { + fn dummy(&self) { } + } + + struct S; + + impl DeprecatedTrait for S { } + + trait LocalTrait : DeprecatedTrait { } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-stability-deprecated.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-stability-deprecated.rs new file mode 100644 index 000000000000..29c7d10572ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-stability-deprecated.rs @@ -0,0 +1,466 @@ +// check-pass +// aux-build:lint_stability.rs +// aux-build:inherited_stability.rs +// aux-build:stability_cfg1.rs +// aux-build:stability-cfg2.rs +// ignore-tidy-linelength +#![warn(deprecated)] +#![feature(staged_api, unstable_test_feature)] + +#![stable(feature = "rust1", since = "1.0.0")] + +#[macro_use] +extern crate lint_stability; + +mod cross_crate { + extern crate stability_cfg1; + extern crate stability_cfg2; + + use lint_stability::*; + + fn test() { + type Foo = MethodTester; + let foo = MethodTester; + + deprecated(); // { dg-warning "" "" { target *-*-* } } + foo.method_deprecated(); // { dg-warning "" "" { target *-*-* } } + Foo::method_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + ::method_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated(); // { dg-warning "" "" { target *-*-* } } + Trait::trait_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + + deprecated_text(); // { dg-warning "" "" { target *-*-* } } + foo.method_deprecated_text(); // { dg-warning "" "" { target *-*-* } } + Foo::method_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::method_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated_text(); // { dg-warning "" "" { target *-*-* } } + Trait::trait_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + + deprecated_unstable(); // { dg-warning "" "" { target *-*-* } } + foo.method_deprecated_unstable(); // { dg-warning "" "" { target *-*-* } } + Foo::method_deprecated_unstable(&foo); // { dg-warning "" "" { target *-*-* } } + ::method_deprecated_unstable(&foo); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated_unstable(); // { dg-warning "" "" { target *-*-* } } + Trait::trait_deprecated_unstable(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_unstable(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_unstable(&foo); // { dg-warning "" "" { target *-*-* } } + + deprecated_unstable_text(); // { dg-warning "" "" { target *-*-* } } + foo.method_deprecated_unstable_text(); // { dg-warning "" "" { target *-*-* } } + Foo::method_deprecated_unstable_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::method_deprecated_unstable_text(&foo); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated_unstable_text(); // { dg-warning "" "" { target *-*-* } } + Trait::trait_deprecated_unstable_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_unstable_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_unstable_text(&foo); // { dg-warning "" "" { target *-*-* } } + + unstable(); + foo.method_unstable(); + Foo::method_unstable(&foo); + ::method_unstable(&foo); + foo.trait_unstable(); + Trait::trait_unstable(&foo); + ::trait_unstable(&foo); + ::trait_unstable(&foo); + + unstable_text(); + foo.method_unstable_text(); + Foo::method_unstable_text(&foo); + ::method_unstable_text(&foo); + foo.trait_unstable_text(); + Trait::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + + stable(); + foo.method_stable(); + Foo::method_stable(&foo); + ::method_stable(&foo); + foo.trait_stable(); + Trait::trait_stable(&foo); + ::trait_stable(&foo); + ::trait_stable(&foo); + + stable_text(); + foo.method_stable_text(); + Foo::method_stable_text(&foo); + ::method_stable_text(&foo); + foo.trait_stable_text(); + Trait::trait_stable_text(&foo); + ::trait_stable_text(&foo); + ::trait_stable_text(&foo); + + struct S1(T::TypeUnstable); + struct S2(T::TypeDeprecated); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + type A = dyn TraitWithAssociatedTypes< + TypeUnstable = u8, + TypeDeprecated = u16, +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + >; + + let _ = DeprecatedStruct { // { dg-warning "" "" { target *-*-* } } + i: 0 // { dg-warning "" "" { target *-*-* } } + }; + let _ = DeprecatedUnstableStruct { +// { dg-warning "" "" { target *-*-* } .-1 } + i: 0 // { dg-warning "" "" { target *-*-* } } + }; + let _ = UnstableStruct { i: 0 }; + let _ = StableStruct { i: 0 }; + + let _ = DeprecatedUnitStruct; // { dg-warning "" "" { target *-*-* } } + let _ = DeprecatedUnstableUnitStruct; // { dg-warning "" "" { target *-*-* } } + let _ = UnstableUnitStruct; + let _ = StableUnitStruct; + + let _ = Enum::DeprecatedVariant; // { dg-warning "" "" { target *-*-* } } + let _ = Enum::DeprecatedUnstableVariant; // { dg-warning "" "" { target *-*-* } } + let _ = Enum::UnstableVariant; + let _ = Enum::StableVariant; + + let _ = DeprecatedTupleStruct (1); // { dg-warning "" "" { target *-*-* } } + let _ = DeprecatedUnstableTupleStruct (1); // { dg-warning "" "" { target *-*-* } } + let _ = UnstableTupleStruct (1); + let _ = StableTupleStruct (1); + + // At the moment, the lint checker only checks stability in + // in the arguments of macros. + // Eventually, we will want to lint the contents of the + // macro in the module *defining* it. Also, stability levels + // on macros themselves are not yet linted. + macro_test_arg!(deprecated_text()); // { dg-warning "" "" { target *-*-* } } + macro_test_arg!(deprecated_unstable_text()); // { dg-warning "" "" { target *-*-* } } + macro_test_arg!(macro_test_arg!(deprecated_text())); // { dg-warning "" "" { target *-*-* } } + } + + fn test_method_param(foo: Foo) { + foo.trait_deprecated(); // { dg-warning "" "" { target *-*-* } } + Trait::trait_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated_text(); // { dg-warning "" "" { target *-*-* } } + Trait::trait_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated_unstable(); // { dg-warning "" "" { target *-*-* } } + Trait::trait_deprecated_unstable(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_unstable(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_unstable(&foo); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated_unstable_text(); // { dg-warning "" "" { target *-*-* } } + Trait::trait_deprecated_unstable_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_unstable_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_unstable_text(&foo); // { dg-warning "" "" { target *-*-* } } + foo.trait_unstable(); + Trait::trait_unstable(&foo); + ::trait_unstable(&foo); + ::trait_unstable(&foo); + foo.trait_unstable_text(); + Trait::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + foo.trait_stable(); + Trait::trait_stable(&foo); + ::trait_stable(&foo); + ::trait_stable(&foo); + } + + fn test_method_object(foo: &dyn Trait) { + foo.trait_deprecated(); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated_text(); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated_unstable(); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated_unstable_text(); // { dg-warning "" "" { target *-*-* } } + foo.trait_unstable(); + foo.trait_unstable_text(); + foo.trait_stable(); + } + + struct S; + + impl UnstableTrait for S { } + impl DeprecatedTrait for S {} // { dg-warning "" "" { target *-*-* } } + trait LocalTrait : UnstableTrait { } + trait LocalTrait2 : DeprecatedTrait { } // { dg-warning "" "" { target *-*-* } } + + impl Trait for S { + fn trait_stable(&self) {} + fn trait_unstable(&self) {} + } +} + +mod inheritance { + extern crate inherited_stability; + use self::inherited_stability::*; + + fn test_inheritance() { + unstable(); + stable(); + + stable_mod::unstable(); + stable_mod::stable(); + + unstable_mod::deprecated(); // { dg-warning "" "" { target *-*-* } } + unstable_mod::unstable(); + + let _ = Unstable::UnstableVariant; + let _ = Unstable::StableVariant; + + let x: usize = 0; + x.unstable(); + x.stable(); + } +} + +mod this_crate { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn deprecated() {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn deprecated_text() {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub fn unstable() {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + pub fn unstable_text() {} + + #[stable(feature = "rust1", since = "1.0.0")] + pub fn stable() {} + #[stable(feature = "rust1", since = "1.0.0")] + pub fn stable_text() {} + + #[stable(feature = "rust1", since = "1.0.0")] + pub struct MethodTester; + + impl MethodTester { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated(&self) {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub fn method_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + pub fn method_unstable_text(&self) {} + + #[stable(feature = "rust1", since = "1.0.0")] + pub fn method_stable(&self) {} + #[stable(feature = "rust1", since = "1.0.0")] + pub fn method_stable_text(&self) {} + } + + pub trait Trait { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated(&self) {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + fn trait_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + fn trait_unstable_text(&self) {} + + #[stable(feature = "rust1", since = "1.0.0")] + fn trait_stable(&self) {} + #[stable(feature = "rust1", since = "1.0.0")] + fn trait_stable_text(&self) {} + } + + impl Trait for MethodTester {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub struct DeprecatedStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize + } + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub struct UnstableStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize + } + #[stable(feature = "rust1", since = "1.0.0")] + pub struct StableStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub struct DeprecatedUnitStruct; + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub struct UnstableUnitStruct; + #[stable(feature = "rust1", since = "1.0.0")] + pub struct StableUnitStruct; + + pub enum Enum { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + DeprecatedVariant, + #[unstable(feature = "unstable_test_feature", issue = "none")] + UnstableVariant, + + #[stable(feature = "rust1", since = "1.0.0")] + StableVariant, + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub struct DeprecatedTupleStruct(isize); + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub struct UnstableTupleStruct(isize); + #[stable(feature = "rust1", since = "1.0.0")] + pub struct StableTupleStruct(isize); + + fn test() { + // Only the deprecated cases of the following should generate + // errors, because other stability attributes now have meaning + // only *across* crates, not within a single crate. + + type Foo = MethodTester; + let foo = MethodTester; + + deprecated(); // { dg-warning "" "" { target *-*-* } } + foo.method_deprecated(); // { dg-warning "" "" { target *-*-* } } + Foo::method_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + ::method_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated(); // { dg-warning "" "" { target *-*-* } } + Trait::trait_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + + deprecated_text(); // { dg-warning "" "" { target *-*-* } } + foo.method_deprecated_text(); // { dg-warning "" "" { target *-*-* } } + Foo::method_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::method_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated_text(); // { dg-warning "" "" { target *-*-* } } + Trait::trait_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + + unstable(); + foo.method_unstable(); + Foo::method_unstable(&foo); + ::method_unstable(&foo); + foo.trait_unstable(); + Trait::trait_unstable(&foo); + ::trait_unstable(&foo); + ::trait_unstable(&foo); + + unstable_text(); + foo.method_unstable_text(); + Foo::method_unstable_text(&foo); + ::method_unstable_text(&foo); + foo.trait_unstable_text(); + Trait::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + + stable(); + foo.method_stable(); + Foo::method_stable(&foo); + ::method_stable(&foo); + foo.trait_stable(); + Trait::trait_stable(&foo); + ::trait_stable(&foo); + ::trait_stable(&foo); + + stable_text(); + foo.method_stable_text(); + Foo::method_stable_text(&foo); + ::method_stable_text(&foo); + foo.trait_stable_text(); + Trait::trait_stable_text(&foo); + ::trait_stable_text(&foo); + ::trait_stable_text(&foo); + + let _ = DeprecatedStruct { +// { dg-warning "" "" { target *-*-* } .-1 } + i: 0 // { dg-warning "" "" { target *-*-* } } + }; + let _ = UnstableStruct { i: 0 }; + let _ = StableStruct { i: 0 }; + + let _ = DeprecatedUnitStruct; // { dg-warning "" "" { target *-*-* } } + let _ = UnstableUnitStruct; + let _ = StableUnitStruct; + + let _ = Enum::DeprecatedVariant; // { dg-warning "" "" { target *-*-* } } + let _ = Enum::UnstableVariant; + let _ = Enum::StableVariant; + + let _ = DeprecatedTupleStruct (1); // { dg-warning "" "" { target *-*-* } } + let _ = UnstableTupleStruct (1); + let _ = StableTupleStruct (1); + } + + fn test_method_param(foo: Foo) { + foo.trait_deprecated(); // { dg-warning "" "" { target *-*-* } } + Trait::trait_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated(&foo); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated_text(); // { dg-warning "" "" { target *-*-* } } + Trait::trait_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + ::trait_deprecated_text(&foo); // { dg-warning "" "" { target *-*-* } } + foo.trait_unstable(); + Trait::trait_unstable(&foo); + ::trait_unstable(&foo); + ::trait_unstable(&foo); + foo.trait_unstable_text(); + Trait::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + foo.trait_stable(); + Trait::trait_stable(&foo); + ::trait_stable(&foo); + ::trait_stable(&foo); + } + + fn test_method_object(foo: &dyn Trait) { + foo.trait_deprecated(); // { dg-warning "" "" { target *-*-* } } + foo.trait_deprecated_text(); // { dg-warning "" "" { target *-*-* } } + foo.trait_unstable(); + foo.trait_unstable_text(); + foo.trait_stable(); + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn test_fn_body() { + fn fn_in_body() {} + fn_in_body(); // { dg-warning "" "" { target *-*-* } } + } + + impl MethodTester { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn test_method_body(&self) { + fn fn_in_body() {} + fn_in_body(); // { dg-warning "" "" { target *-*-* } } + } + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub trait DeprecatedTrait { + fn dummy(&self) { } + } + + struct S; + + impl DeprecatedTrait for S { } // { dg-warning "" "" { target *-*-* } } + + trait LocalTrait : DeprecatedTrait { } // { dg-warning "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-stability-fields-deprecated.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-stability-fields-deprecated.rs new file mode 100644 index 000000000000..ff02e6309935 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-stability-fields-deprecated.rs @@ -0,0 +1,340 @@ +// aux-build:lint_stability_fields.rs + +#![deny(deprecated)] +#![allow(dead_code)] +#![feature(staged_api, unstable_test_feature)] + +#![stable(feature = "rust1", since = "1.0.0")] + +mod cross_crate { + extern crate lint_stability_fields; + + use self::lint_stability_fields::*; + + pub fn foo() { + let x = Stable { + inherit: 1, + override1: 2, + override2: 3, +// { dg-error "" "" { target *-*-* } .-1 } + }; + + let _ = x.inherit; + let _ = x.override1; + let _ = x.override2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Stable { + inherit: _, + override1: _, + override2: _ +// { dg-error "" "" { target *-*-* } .-1 } + } = x; + // all fine + let Stable { .. } = x; + + let x = Stable2(1, 2, 3); + + let _ = x.0; + let _ = x.1; + let _ = x.2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Stable2(_, + _, + _) +// { dg-error "" "" { target *-*-* } .-1 } + = x; + // all fine + let Stable2(..) = x; + + + let x = Unstable { + inherit: 1, + override1: 2, + override2: 3, +// { dg-error "" "" { target *-*-* } .-1 } + }; + + let _ = x.inherit; + let _ = x.override1; + let _ = x.override2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Unstable { + inherit: _, + override1: _, + override2: _ +// { dg-error "" "" { target *-*-* } .-1 } + } = x; + + let Unstable + // the patterns are all fine: + { .. } = x; + + + let x = Unstable2(1, 2, 3); + + let _ = x.0; + let _ = x.1; + let _ = x.2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Unstable2 + (_, + _, + _) +// { dg-error "" "" { target *-*-* } .-1 } + = x; + let Unstable2 + // the patterns are all fine: + (..) = x; + + + let x = Deprecated { +// { dg-error "" "" { target *-*-* } .-1 } + inherit: 1, +// { dg-error "" "" { target *-*-* } .-1 } + override1: 2, +// { dg-error "" "" { target *-*-* } .-1 } + override2: 3, +// { dg-error "" "" { target *-*-* } .-1 } + }; + + let _ = x.inherit; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = x.override1; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = x.override2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Deprecated { +// { dg-error "" "" { target *-*-* } .-1 } + inherit: _, +// { dg-error "" "" { target *-*-* } .-1 } + override1: _, +// { dg-error "" "" { target *-*-* } .-1 } + override2: _ +// { dg-error "" "" { target *-*-* } .-1 } + } = x; + + let Deprecated +// { dg-error "" "" { target *-*-* } .-1 } + // the patterns are all fine: + { .. } = x; + + let x = Deprecated2(1, 2, 3); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = x.0; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = x.1; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = x.2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Deprecated2 +// { dg-error "" "" { target *-*-* } .-1 } + (_, +// { dg-error "" "" { target *-*-* } .-1 } + _, +// { dg-error "" "" { target *-*-* } .-1 } + _) +// { dg-error "" "" { target *-*-* } .-1 } + = x; + let Deprecated2 +// { dg-error "" "" { target *-*-* } .-1 } + // the patterns are all fine: + (..) = x; + } +} + +mod this_crate { + #[stable(feature = "rust1", since = "1.0.0")] + struct Stable { + inherit: u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] + override1: u8, + #[rustc_deprecated(since = "1.0.0", reason = "text")] + #[unstable(feature = "unstable_test_feature", issue = "none")] + override2: u8, + } + + #[stable(feature = "rust1", since = "1.0.0")] + struct Stable2(u8, + #[stable(feature = "rust1", since = "1.0.0")] u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] u8); + + #[unstable(feature = "unstable_test_feature", issue = "none")] + struct Unstable { + inherit: u8, + #[stable(feature = "rust1", since = "1.0.0")] + override1: u8, + #[rustc_deprecated(since = "1.0.0", reason = "text")] + #[unstable(feature = "unstable_test_feature", issue = "none")] + override2: u8, + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + struct Unstable2(u8, + #[stable(feature = "rust1", since = "1.0.0")] u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] u8); + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + struct Deprecated { + inherit: u8, + #[stable(feature = "rust1", since = "1.0.0")] + override1: u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] + override2: u8, + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + struct Deprecated2(u8, + #[stable(feature = "rust1", since = "1.0.0")] u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] u8); + + pub fn foo() { + let x = Stable { + inherit: 1, + override1: 2, + override2: 3, +// { dg-error "" "" { target *-*-* } .-1 } + }; + + let _ = x.inherit; + let _ = x.override1; + let _ = x.override2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Stable { + inherit: _, + override1: _, + override2: _ +// { dg-error "" "" { target *-*-* } .-1 } + } = x; + // all fine + let Stable { .. } = x; + + let x = Stable2(1, 2, 3); + + let _ = x.0; + let _ = x.1; + let _ = x.2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Stable2(_, + _, + _) +// { dg-error "" "" { target *-*-* } .-1 } + = x; + // all fine + let Stable2(..) = x; + + + let x = Unstable { + inherit: 1, + override1: 2, + override2: 3, +// { dg-error "" "" { target *-*-* } .-1 } + }; + + let _ = x.inherit; + let _ = x.override1; + let _ = x.override2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Unstable { + inherit: _, + override1: _, + override2: _ +// { dg-error "" "" { target *-*-* } .-1 } + } = x; + + let Unstable + // the patterns are all fine: + { .. } = x; + + + let x = Unstable2(1, 2, 3); + + let _ = x.0; + let _ = x.1; + let _ = x.2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Unstable2 + (_, + _, + _) +// { dg-error "" "" { target *-*-* } .-1 } + = x; + let Unstable2 + // the patterns are all fine: + (..) = x; + + + let x = Deprecated { +// { dg-error "" "" { target *-*-* } .-1 } + inherit: 1, +// { dg-error "" "" { target *-*-* } .-1 } + override1: 2, +// { dg-error "" "" { target *-*-* } .-1 } + override2: 3, +// { dg-error "" "" { target *-*-* } .-1 } + }; + + let _ = x.inherit; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = x.override1; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = x.override2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Deprecated { +// { dg-error "" "" { target *-*-* } .-1 } + inherit: _, +// { dg-error "" "" { target *-*-* } .-1 } + override1: _, +// { dg-error "" "" { target *-*-* } .-1 } + override2: _ +// { dg-error "" "" { target *-*-* } .-1 } + } = x; + + let Deprecated +// { dg-error "" "" { target *-*-* } .-1 } + // the patterns are all fine: + { .. } = x; + + let x = Deprecated2(1, 2, 3); +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = x.0; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = x.1; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = x.2; +// { dg-error "" "" { target *-*-* } .-1 } + + let Deprecated2 +// { dg-error "" "" { target *-*-* } .-1 } + (_, +// { dg-error "" "" { target *-*-* } .-1 } + _, +// { dg-error "" "" { target *-*-* } .-1 } + _) +// { dg-error "" "" { target *-*-* } .-1 } + = x; + let Deprecated2 +// { dg-error "" "" { target *-*-* } .-1 } + // the patterns are all fine: + (..) = x; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-stability-fields.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-stability-fields.rs new file mode 100644 index 000000000000..c7cf50e3f536 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-stability-fields.rs @@ -0,0 +1,284 @@ +// aux-build:lint_stability_fields.rs +#![allow(deprecated)] +#![allow(dead_code)] +#![feature(staged_api)] + +#![stable(feature = "rust1", since = "1.0.0")] + +mod cross_crate { + extern crate lint_stability_fields; + + mod reexport { + #[stable(feature = "rust1", since = "1.0.0")] + pub use super::lint_stability_fields::*; + } + + use self::lint_stability_fields::*; + + pub fn foo() { + let x = Stable { + inherit: 1, + override1: 2, // { dg-error ".E0658." "" { target *-*-* } } + override2: 3, // { dg-error ".E0658." "" { target *-*-* } } + }; + + let _ = x.inherit; + let _ = x.override1; // { dg-error ".E0658." "" { target *-*-* } } + let _ = x.override2; // { dg-error ".E0658." "" { target *-*-* } } + + let Stable { + inherit: _, + override1: _, // { dg-error ".E0658." "" { target *-*-* } } + override2: _ // { dg-error ".E0658." "" { target *-*-* } } + } = x; + // all fine + let Stable { .. } = x; + + let x = Stable2(1, 2, 3); + + let _ = x.0; + let _ = x.1; // { dg-error ".E0658." "" { target *-*-* } } + let _ = x.2; // { dg-error ".E0658." "" { target *-*-* } } + + let Stable2(_, + _, // { dg-error ".E0658." "" { target *-*-* } } + _) // { dg-error ".E0658." "" { target *-*-* } } + = x; + // all fine + let Stable2(..) = x; + + + let x = Unstable { // { dg-error ".E0658." "" { target *-*-* } } + inherit: 1, // { dg-error ".E0658." "" { target *-*-* } } + override1: 2, + override2: 3, // { dg-error ".E0658." "" { target *-*-* } } + }; + + let _ = x.inherit; // { dg-error ".E0658." "" { target *-*-* } } + let _ = x.override1; + let _ = x.override2; // { dg-error ".E0658." "" { target *-*-* } } + + let Unstable { // { dg-error ".E0658." "" { target *-*-* } } + inherit: _, // { dg-error ".E0658." "" { target *-*-* } } + override1: _, + override2: _ // { dg-error ".E0658." "" { target *-*-* } } + } = x; + + let Unstable // { dg-error ".E0658." "" { target *-*-* } } + // the patterns are all fine: + { .. } = x; + + // Unstable items are still unstable even when used through a stable "pub use". + let x = reexport::Unstable2(1, 2, 3); // { dg-error ".E0658." "" { target *-*-* } } + + let x = Unstable2(1, 2, 3); // { dg-error ".E0658." "" { target *-*-* } } + + let _ = x.0; // { dg-error ".E0658." "" { target *-*-* } } + let _ = x.1; + let _ = x.2; // { dg-error ".E0658." "" { target *-*-* } } + + let Unstable2 // { dg-error ".E0658." "" { target *-*-* } } + (_, // { dg-error ".E0658." "" { target *-*-* } } + _, + _) // { dg-error ".E0658." "" { target *-*-* } } + = x; + let Unstable2 // { dg-error ".E0658." "" { target *-*-* } } + // the patterns are all fine: + (..) = x; + + + let x = Deprecated { // { dg-error ".E0658." "" { target *-*-* } } + inherit: 1, // { dg-error ".E0658." "" { target *-*-* } } + override1: 2, + override2: 3, // { dg-error ".E0658." "" { target *-*-* } } + }; + + let _ = x.inherit; // { dg-error ".E0658." "" { target *-*-* } } + let _ = x.override1; + let _ = x.override2; // { dg-error ".E0658." "" { target *-*-* } } + + let Deprecated { // { dg-error ".E0658." "" { target *-*-* } } + inherit: _, // { dg-error ".E0658." "" { target *-*-* } } + override1: _, + override2: _ // { dg-error ".E0658." "" { target *-*-* } } + } = x; + + let Deprecated // { dg-error ".E0658." "" { target *-*-* } } + // the patterns are all fine: + { .. } = x; + + let x = Deprecated2(1, 2, 3); // { dg-error ".E0658." "" { target *-*-* } } + + let _ = x.0; // { dg-error ".E0658." "" { target *-*-* } } + let _ = x.1; + let _ = x.2; // { dg-error ".E0658." "" { target *-*-* } } + + let Deprecated2 // { dg-error ".E0658." "" { target *-*-* } } + (_, // { dg-error ".E0658." "" { target *-*-* } } + _, + _) // { dg-error ".E0658." "" { target *-*-* } } + = x; + let Deprecated2 // { dg-error ".E0658." "" { target *-*-* } } + // the patterns are all fine: + (..) = x; + } +} + +mod this_crate { + #[stable(feature = "rust1", since = "1.0.0")] + struct Stable { + inherit: u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] + override1: u8, + #[rustc_deprecated(since = "1.0.0", reason = "text")] + #[unstable(feature = "unstable_test_feature", issue = "none")] + override2: u8, + } + + #[stable(feature = "rust1", since = "1.0.0")] + struct Stable2(u8, + #[stable(feature = "rust1", since = "1.0.0")] u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] u8); + + #[unstable(feature = "unstable_test_feature", issue = "none")] + struct Unstable { + inherit: u8, + #[stable(feature = "rust1", since = "1.0.0")] + override1: u8, + #[rustc_deprecated(since = "1.0.0", reason = "text")] + #[unstable(feature = "unstable_test_feature", issue = "none")] + override2: u8, + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + struct Unstable2(u8, + #[stable(feature = "rust1", since = "1.0.0")] u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] u8); + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + struct Deprecated { + inherit: u8, + #[stable(feature = "rust1", since = "1.0.0")] + override1: u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] + override2: u8, + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + struct Deprecated2(u8, + #[stable(feature = "rust1", since = "1.0.0")] u8, + #[unstable(feature = "unstable_test_feature", issue = "none")] u8); + + pub fn foo() { + let x = Stable { + inherit: 1, + override1: 2, + override2: 3, + }; + + let _ = x.inherit; + let _ = x.override1; + let _ = x.override2; + + let Stable { + inherit: _, + override1: _, + override2: _ + } = x; + // all fine + let Stable { .. } = x; + + let x = Stable2(1, 2, 3); + + let _ = x.0; + let _ = x.1; + let _ = x.2; + + let Stable2(_, + _, + _) + = x; + // all fine + let Stable2(..) = x; + + + let x = Unstable { + inherit: 1, + override1: 2, + override2: 3, + }; + + let _ = x.inherit; + let _ = x.override1; + let _ = x.override2; + + let Unstable { + inherit: _, + override1: _, + override2: _ + } = x; + + let Unstable + // the patterns are all fine: + { .. } = x; + + + let x = Unstable2(1, 2, 3); + + let _ = x.0; + let _ = x.1; + let _ = x.2; + + let Unstable2 + (_, + _, + _) + = x; + let Unstable2 + // the patterns are all fine: + (..) = x; + + + let x = Deprecated { + inherit: 1, + override1: 2, + override2: 3, + }; + + let _ = x.inherit; + let _ = x.override1; + let _ = x.override2; + + let Deprecated { + inherit: _, + override1: _, + override2: _ + } = x; + + let Deprecated + // the patterns are all fine: + { .. } = x; + + let x = Deprecated2(1, 2, 3); + + let _ = x.0; + let _ = x.1; + let _ = x.2; + + let Deprecated2 + (_, + _, + _) + = x; + let Deprecated2 + // the patterns are all fine: + (..) = x; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-stability.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-stability.rs new file mode 100644 index 000000000000..ad8141a447e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-stability.rs @@ -0,0 +1,455 @@ +// aux-build:lint_stability.rs +// aux-build:inherited_stability.rs +// aux-build:stability_cfg1.rs +// aux-build:stability-cfg2.rs + +#![allow(deprecated)] +#![allow(dead_code)] +#![feature(staged_api)] + +#![stable(feature = "rust1", since = "1.0.0")] + +#[macro_use] +extern crate lint_stability; + +mod cross_crate { + extern crate stability_cfg1; + extern crate stability_cfg2; // { dg-error ".E0658." "" { target *-*-* } } + + use lint_stability::*; + + fn test() { + type Foo = MethodTester; + let foo = MethodTester; + + deprecated(); + foo.method_deprecated(); + Foo::method_deprecated(&foo); + ::method_deprecated(&foo); + foo.trait_deprecated(); + Trait::trait_deprecated(&foo); + ::trait_deprecated(&foo); + ::trait_deprecated(&foo); + + deprecated_text(); + foo.method_deprecated_text(); + Foo::method_deprecated_text(&foo); + ::method_deprecated_text(&foo); + foo.trait_deprecated_text(); + Trait::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + + deprecated_future(); // Fine; no error. + + deprecated_unstable(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + Trait::trait_deprecated_unstable(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::trait_deprecated_unstable(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + + deprecated_unstable_text(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + Trait::trait_deprecated_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::trait_deprecated_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + + unstable(); // { dg-error ".E0658." "" { target *-*-* } } + Trait::trait_unstable(&foo); // { dg-error ".E0658." "" { target *-*-* } } + ::trait_unstable(&foo); // { dg-error ".E0658." "" { target *-*-* } } + + unstable_text(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + Trait::trait_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::trait_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + + stable(); + foo.method_stable(); + Foo::method_stable(&foo); + ::method_stable(&foo); + foo.trait_stable(); + Trait::trait_stable(&foo); + ::trait_stable(&foo); + ::trait_stable(&foo); + + stable_text(); + foo.method_stable_text(); + Foo::method_stable_text(&foo); + ::method_stable_text(&foo); + foo.trait_stable_text(); + Trait::trait_stable_text(&foo); + ::trait_stable_text(&foo); + ::trait_stable_text(&foo); + + struct S1(T::TypeUnstable); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + struct S2(T::TypeDeprecated); + type A = dyn TraitWithAssociatedTypes< + TypeUnstable = u8, // { dg-error ".E0658." "" { target *-*-* } } + TypeDeprecated = u16, + >; + + let _ = DeprecatedStruct { + i: 0 + }; + let _ = DeprecatedUnstableStruct { +// { dg-error ".E0658." "" { target *-*-* } .-1 } + i: 0 + }; + let _ = UnstableStruct { i: 0 }; // { dg-error ".E0658." "" { target *-*-* } } + let _ = StableStruct { i: 0 }; + + let _ = DeprecatedUnitStruct; + let _ = DeprecatedUnstableUnitStruct; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + let _ = UnstableUnitStruct; // { dg-error ".E0658." "" { target *-*-* } } + let _ = StableUnitStruct; + + let _ = Enum::DeprecatedVariant; + let _ = Enum::DeprecatedUnstableVariant; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + let _ = Enum::UnstableVariant; // { dg-error ".E0658." "" { target *-*-* } } + let _ = Enum::StableVariant; + + let _ = DeprecatedTupleStruct (1); + let _ = DeprecatedUnstableTupleStruct (1); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + let _ = UnstableTupleStruct (1); // { dg-error ".E0658." "" { target *-*-* } } + let _ = StableTupleStruct (1); + + // At the moment, the lint checker only checks stability in + // in the arguments of macros. + // Eventually, we will want to lint the contents of the + // macro in the module *defining* it. Also, stability levels + // on macros themselves are not yet linted. + macro_test_arg!(deprecated_text()); + macro_test_arg!(deprecated_unstable_text()); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + macro_test_arg!(macro_test_arg!(deprecated_text())); + } + + fn test_method_param(foo: Foo) { + foo.trait_deprecated(); + Trait::trait_deprecated(&foo); + ::trait_deprecated(&foo); + ::trait_deprecated(&foo); + foo.trait_deprecated_text(); + Trait::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + Trait::trait_deprecated_unstable(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::trait_deprecated_unstable(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + Trait::trait_deprecated_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::trait_deprecated_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + Trait::trait_unstable(&foo); // { dg-error ".E0658." "" { target *-*-* } } + ::trait_unstable(&foo); // { dg-error ".E0658." "" { target *-*-* } } + Trait::trait_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + ::trait_unstable_text(&foo); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + foo.trait_stable(); + Trait::trait_stable(&foo); + ::trait_stable(&foo); + ::trait_stable(&foo); + } + + fn test_method_object(foo: &dyn Trait) { + foo.trait_deprecated(); + foo.trait_deprecated_text(); + foo.trait_stable(); + } + + struct S; + + impl UnstableTrait for S { } // { dg-error ".E0658." "" { target *-*-* } } + impl DeprecatedTrait for S {} + trait LocalTrait : UnstableTrait { } // { dg-error ".E0658." "" { target *-*-* } } + trait LocalTrait2 : DeprecatedTrait { } + + impl Trait for S { + fn trait_stable(&self) {} + fn trait_unstable(&self) {} // { dg-error ".E0658." "" { target *-*-* } } + } +} + +mod inheritance { + extern crate inherited_stability; // { dg-error ".E0658." "" { target *-*-* } } + use self::inherited_stability::*; // { dg-error ".E0658." "" { target *-*-* } } + + fn test_inheritance() { + unstable(); // { dg-error ".E0658." "" { target *-*-* } } + stable(); + + stable_mod::unstable(); // { dg-error ".E0658." "" { target *-*-* } } + stable_mod::stable(); + + unstable_mod::deprecated(); + unstable_mod::unstable(); // { dg-error ".E0658." "" { target *-*-* } } + + let _ = Unstable::UnstableVariant; // { dg-error ".E0658." "" { target *-*-* } } + let _ = Unstable::StableVariant; + + let x: usize = 0; + x.stable(); + } +} + +mod this_crate { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn deprecated() {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn deprecated_text() {} + + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_deprecated(since = "99.99.99", reason = "text")] + pub fn deprecated_future() {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub fn unstable() {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + pub fn unstable_text() {} + + #[stable(feature = "rust1", since = "1.0.0")] + pub fn stable() {} + #[stable(feature = "rust1", since = "1.0.0")] + pub fn stable_text() {} + + #[stable(feature = "rust1", since = "1.0.0")] + pub struct MethodTester; + + impl MethodTester { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated(&self) {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub fn method_deprecated_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub fn method_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + pub fn method_unstable_text(&self) {} + + #[stable(feature = "rust1", since = "1.0.0")] + pub fn method_stable(&self) {} + #[stable(feature = "rust1", since = "1.0.0")] + pub fn method_stable_text(&self) {} + } + + pub trait Trait { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated(&self) {} + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn trait_deprecated_text(&self) {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + fn trait_unstable(&self) {} + #[unstable(feature = "unstable_test_feature", reason = "text", issue = "none")] + fn trait_unstable_text(&self) {} + + #[stable(feature = "rust1", since = "1.0.0")] + fn trait_stable(&self) {} + #[stable(feature = "rust1", since = "1.0.0")] + fn trait_stable_text(&self) {} + } + + impl Trait for MethodTester {} + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub struct DeprecatedStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize + } + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub struct UnstableStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize + } + #[stable(feature = "rust1", since = "1.0.0")] + pub struct StableStruct { + #[stable(feature = "stable_test_feature", since = "1.0.0")] i: isize + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub struct DeprecatedUnitStruct; + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub struct UnstableUnitStruct; + #[stable(feature = "rust1", since = "1.0.0")] + pub struct StableUnitStruct; + + pub enum Enum { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + DeprecatedVariant, + #[unstable(feature = "unstable_test_feature", issue = "none")] + UnstableVariant, + + #[stable(feature = "rust1", since = "1.0.0")] + StableVariant, + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub struct DeprecatedTupleStruct(isize); + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub struct UnstableTupleStruct(isize); + #[stable(feature = "rust1", since = "1.0.0")] + pub struct StableTupleStruct(isize); + + fn test() { + // Only the deprecated cases of the following should generate + // errors, because other stability attributes now have meaning + // only *across* crates, not within a single crate. + + type Foo = MethodTester; + let foo = MethodTester; + + deprecated(); + foo.method_deprecated(); + Foo::method_deprecated(&foo); + ::method_deprecated(&foo); + foo.trait_deprecated(); + Trait::trait_deprecated(&foo); + ::trait_deprecated(&foo); + ::trait_deprecated(&foo); + + deprecated_text(); + foo.method_deprecated_text(); + Foo::method_deprecated_text(&foo); + ::method_deprecated_text(&foo); + foo.trait_deprecated_text(); + Trait::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + + deprecated_future(); + + unstable(); + foo.method_unstable(); + Foo::method_unstable(&foo); + ::method_unstable(&foo); + foo.trait_unstable(); + Trait::trait_unstable(&foo); + ::trait_unstable(&foo); + ::trait_unstable(&foo); + + unstable_text(); + foo.method_unstable_text(); + Foo::method_unstable_text(&foo); + ::method_unstable_text(&foo); + foo.trait_unstable_text(); + Trait::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + + stable(); + foo.method_stable(); + Foo::method_stable(&foo); + ::method_stable(&foo); + foo.trait_stable(); + Trait::trait_stable(&foo); + ::trait_stable(&foo); + ::trait_stable(&foo); + + stable_text(); + foo.method_stable_text(); + Foo::method_stable_text(&foo); + ::method_stable_text(&foo); + foo.trait_stable_text(); + Trait::trait_stable_text(&foo); + ::trait_stable_text(&foo); + ::trait_stable_text(&foo); + + let _ = DeprecatedStruct { + i: 0 + }; + let _ = UnstableStruct { i: 0 }; + let _ = StableStruct { i: 0 }; + + let _ = DeprecatedUnitStruct; + let _ = UnstableUnitStruct; + let _ = StableUnitStruct; + + let _ = Enum::DeprecatedVariant; + let _ = Enum::UnstableVariant; + let _ = Enum::StableVariant; + + let _ = DeprecatedTupleStruct (1); + let _ = UnstableTupleStruct (1); + let _ = StableTupleStruct (1); + } + + fn test_method_param(foo: Foo) { + foo.trait_deprecated(); + Trait::trait_deprecated(&foo); + ::trait_deprecated(&foo); + ::trait_deprecated(&foo); + foo.trait_deprecated_text(); + Trait::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + ::trait_deprecated_text(&foo); + foo.trait_unstable(); + Trait::trait_unstable(&foo); + ::trait_unstable(&foo); + ::trait_unstable(&foo); + foo.trait_unstable_text(); + Trait::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + ::trait_unstable_text(&foo); + foo.trait_stable(); + Trait::trait_stable(&foo); + ::trait_stable(&foo); + ::trait_stable(&foo); + } + + fn test_method_object(foo: &dyn Trait) { + foo.trait_deprecated(); + foo.trait_deprecated_text(); + foo.trait_unstable(); + foo.trait_unstable_text(); + foo.trait_stable(); + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn test_fn_body() { + fn fn_in_body() {} + fn_in_body(); + } + + impl MethodTester { + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + fn test_method_body(&self) { + fn fn_in_body() {} + fn_in_body(); + } + } + + #[unstable(feature = "unstable_test_feature", issue = "none")] + #[rustc_deprecated(since = "1.0.0", reason = "text")] + pub trait DeprecatedTrait { + fn dummy(&self) { } + } + + struct S; + + impl DeprecatedTrait for S { } + + trait LocalTrait : DeprecatedTrait { } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-stability2.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-stability2.rs new file mode 100644 index 000000000000..73f8c9139cea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-stability2.rs @@ -0,0 +1,14 @@ +// aux-build:lint_stability.rs +// error-pattern: use of deprecated function + +#![deny(deprecated)] + +#[macro_use] +extern crate lint_stability; + +use lint_stability::*; + +fn main() { + macro_test!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-stability3.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-stability3.rs new file mode 100644 index 000000000000..32c09b30efbd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-stability3.rs @@ -0,0 +1,15 @@ +// aux-build:lint_stability.rs +// error-pattern: use of deprecated function + +#![deny(deprecated)] +#![allow(warnings)] + +#[macro_use] +extern crate lint_stability; + +use lint_stability::*; + +fn main() { + macro_test_arg_nested!(deprecated_text); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-temporary-cstring-as-param.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-temporary-cstring-as-param.rs new file mode 100644 index 000000000000..05434086151b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-temporary-cstring-as-param.rs @@ -0,0 +1,12 @@ +#![deny(temporary_cstring_as_ptr)] + +use std::ffi::CString; +use std::os::raw::c_char; + +fn some_function(data: *const c_char) {} + +fn main() { + some_function(CString::new("").unwrap().as_ptr()); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-temporary-cstring-as-ptr.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-temporary-cstring-as-ptr.rs new file mode 100644 index 000000000000..e5149bcb51ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-temporary-cstring-as-ptr.rs @@ -0,0 +1,10 @@ +// this program is not technically incorrect, but is an obscure enough style to be worth linting +#![deny(temporary_cstring_as_ptr)] + +use std::ffi::CString; + +fn main() { + let s = CString::new("some text").unwrap().as_ptr(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-type-limits.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-type-limits.rs new file mode 100644 index 000000000000..7eb1912f32f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-type-limits.rs @@ -0,0 +1,28 @@ +#![allow(dead_code)] + +// compile-flags: -D unused-comparisons +fn main() { } + +fn foo() { + let mut i = 100_usize; + while i >= 0 { // { dg-error "" "" { target *-*-* } } + i -= 1; + } +} + +fn bar() -> i8 { + return 123; +} + +fn bleh() { + let u = 42u8; + let _ = u > 255; // { dg-error "" "" { target *-*-* } } + let _ = 255 < u; // { dg-error "" "" { target *-*-* } } + let _ = u < 0; // { dg-error "" "" { target *-*-* } } + let _ = 0 > u; // { dg-error "" "" { target *-*-* } } + let _ = u <= 255; // { dg-error "" "" { target *-*-* } } + let _ = 255 >= u; // { dg-error "" "" { target *-*-* } } + let _ = u >= 0; // { dg-error "" "" { target *-*-* } } + let _ = 0 <= u; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-type-limits2.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-type-limits2.rs new file mode 100644 index 000000000000..ae8ee9ae5d79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-type-limits2.rs @@ -0,0 +1,16 @@ +#![allow(dead_code)] +#![warn(overflowing_literals)] + +// compile-flags: -D unused-comparisons +fn main() { } + + +fn bar() -> i8 { + return 123; +} + +fn baz() -> bool { + 128 > bar() // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-type-limits3.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-type-limits3.rs new file mode 100644 index 000000000000..23ab862158cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-type-limits3.rs @@ -0,0 +1,14 @@ +#![allow(dead_code)] +#![warn(overflowing_literals)] + +// compile-flags: -D unused-comparisons +fn main() { } + +fn qux() { + let mut i = 1i8; + while 200 != i { // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + i += 1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-type-overflow.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-type-overflow.rs new file mode 100644 index 000000000000..3e4f204fbf3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-type-overflow.rs @@ -0,0 +1,46 @@ +#![deny(overflowing_literals)] + +fn test(x: i8) { + println!("x {}", x); +} + +#[allow(unused_variables)] +fn main() { + let x1: u8 = 255; // should be OK + let x1: u8 = 256; // { dg-error "" "" { target *-*-* } } + + let x1 = 255_u8; // should be OK + let x1 = 256_u8; // { dg-error "" "" { target *-*-* } } + + let x2: i8 = -128; // should be OK + let x1: i8 = 128; // { dg-error "" "" { target *-*-* } } + + let x3: i8 = -129; // { dg-error "" "" { target *-*-* } } + let x3: i8 = -(129); // { dg-error "" "" { target *-*-* } } + let x3: i8 = -{129}; // { dg-error "" "" { target *-*-* } } + + test(1000); // { dg-error "" "" { target *-*-* } } + + let x = 128_i8; // { dg-error "" "" { target *-*-* } } + let x = 127_i8; + let x = -128_i8; + let x = -(128_i8); + let x = -129_i8; // { dg-error "" "" { target *-*-* } } + + let x: i32 = 2147483647; // should be OK + let x = 2147483647_i32; // should be OK + let x: i32 = 2147483648; // { dg-error "" "" { target *-*-* } } + let x = 2147483648_i32; // { dg-error "" "" { target *-*-* } } + let x: i32 = -2147483648; // should be OK + let x = -2147483648_i32; // should be OK + let x: i32 = -2147483649; // { dg-error "" "" { target *-*-* } } + let x = -2147483649_i32; // { dg-error "" "" { target *-*-* } } + let x = 2147483648; // { dg-error "" "" { target *-*-* } } + + let x = 9223372036854775808_i64; // { dg-error "" "" { target *-*-* } } + let x = -9223372036854775808_i64; // should be OK + let x = 18446744073709551615_i64; // { dg-error "" "" { target *-*-* } } + let x: i64 = -9223372036854775809; // { dg-error "" "" { target *-*-* } } + let x = -9223372036854775809_i64; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-type-overflow2.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-type-overflow2.rs new file mode 100644 index 000000000000..385c5abc92ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-type-overflow2.rs @@ -0,0 +1,14 @@ +// compile-flags: -O + +#![deny(overflowing_literals)] +#![deny(const_err)] + +fn main() { + let x2: i8 = --128; // { dg-error "" "" { target *-*-* } } + + let x = -3.40282357e+38_f32; // { dg-error "" "" { target *-*-* } } + let x = 3.40282357e+38_f32; // { dg-error "" "" { target *-*-* } } + let x = -1.7976931348623159e+308_f64; // { dg-error "" "" { target *-*-* } } + let x = 1.7976931348623159e+308_f64; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unconditional-recursion.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unconditional-recursion.rs new file mode 100644 index 000000000000..e77eab239aff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unconditional-recursion.rs @@ -0,0 +1,153 @@ +#![deny(unconditional_recursion)] + +#![allow(dead_code)] +fn foo() { // { dg-error "" "" { target *-*-* } } + foo(); +} + +fn bar() { + if true { + bar() + } +} + +fn baz() { // { dg-error "" "" { target *-*-* } } + if true { + baz() + } else { + baz() + } +} + +fn qux() { + loop {} +} + +fn quz() -> bool { // { dg-error "" "" { target *-*-* } } + if true { + while quz() {} + true + } else { + loop { quz(); } + } +} + +// Trait method calls. +trait Foo { + fn bar(&self) { // { dg-error "" "" { target *-*-* } } + self.bar() + } +} + +impl Foo for Box { + fn bar(&self) { // { dg-error "" "" { target *-*-* } } + loop { + self.bar() + } + } +} + +// Trait method call with integer fallback after method resolution. +impl Foo for i32 { + fn bar(&self) { // { dg-error "" "" { target *-*-* } } + 0.bar() + } +} + +impl Foo for u32 { + fn bar(&self) { + 0.bar() + } +} + +// Trait method calls via paths. +trait Foo2 { + fn bar(&self) { // { dg-error "" "" { target *-*-* } } + Foo2::bar(self) + } +} + +impl Foo2 for Box { + fn bar(&self) { // { dg-error "" "" { target *-*-* } } + loop { + Foo2::bar(self) + } + } +} + +struct Baz; +impl Baz { + // Inherent method call. + fn qux(&self) { // { dg-error "" "" { target *-*-* } } + self.qux(); + } + + // Inherent method call via path. + fn as_ref(&self) -> &Self { // { dg-error "" "" { target *-*-* } } + Baz::as_ref(self) + } +} + +// Trait method calls to impls via paths. +impl Default for Baz { + fn default() -> Baz { // { dg-error "" "" { target *-*-* } } + let x = Default::default(); + x + } +} + +// Overloaded operators. +impl std::ops::Deref for Baz { + type Target = (); + fn deref(&self) -> &() { // { dg-error "" "" { target *-*-* } } + &**self + } +} + +impl std::ops::Index for Baz { + type Output = Baz; + fn index(&self, x: usize) -> &Baz { // { dg-error "" "" { target *-*-* } } + &self[x] + } +} + +// Overloaded autoderef. +struct Quux; +impl std::ops::Deref for Quux { + type Target = Baz; + fn deref(&self) -> &Baz { // { dg-error "" "" { target *-*-* } } + self.as_ref() + } +} + +fn all_fine() { + let _f = all_fine; +} + +// issue 26333 +trait Bar { + fn method(&self, x: &T) { + x.method(x) + } +} + +// Do not trigger on functions that may diverge instead of self-recursing (#54444) + +pub fn loops(x: bool) { + if x { + loops(x); + } else { + loop {} + } +} + +pub fn panics(x: bool) { + if x { + panics(!x); + } else { + panic!("panics"); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unexported-no-mangle.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unexported-no-mangle.rs new file mode 100644 index 000000000000..9cfeabeb5bf7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unexported-no-mangle.rs @@ -0,0 +1,30 @@ +// compile-flags:-F private_no_mangle_fns -F no_mangle_const_items -F private_no_mangle_statics + +#[no_mangle] +fn foo() { +} + +#[allow(dead_code)] +#[no_mangle] +const FOO: u64 = 1; // { dg-error "" "" { target *-*-* } } + +#[no_mangle] +pub const PUB_FOO: u64 = 1; // { dg-error "" "" { target *-*-* } } + +#[no_mangle] +pub fn bar() { +} + +#[no_mangle] +pub static BAR: u64 = 1; + +#[allow(dead_code)] +#[no_mangle] +static PRIVATE_BAR: u64 = 1; + + +fn main() { + foo(); + bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unknown-feature-default.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unknown-feature-default.rs new file mode 100644 index 000000000000..bdbfceef3180 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unknown-feature-default.rs @@ -0,0 +1,11 @@ +// Tests the default for the unused_features lint + +#![allow(stable_features)] +// FIXME(#44232) we should warn that this isn't used. +#![feature(rust1)] + +// build-pass (FIXME(62277): could be check-pass?) + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unknown-feature.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unknown-feature.rs new file mode 100644 index 000000000000..30605a94f815 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unknown-feature.rs @@ -0,0 +1,11 @@ +#![warn(unused_features)] + +#![allow(stable_features)] +// FIXME(#44232) we should warn that this isn't used. +#![feature(rust1)] + +// build-pass (FIXME(62277): could be check-pass?) + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unknown-lint-cmdline.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unknown-lint-cmdline.rs new file mode 100644 index 000000000000..c24e52f72678 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unknown-lint-cmdline.rs @@ -0,0 +1,10 @@ +// compile-flags:-D bogus -D dead_cod + +// error-pattern:unknown lint: `bogus` +// error-pattern:requested on the command line with `-D bogus` +// error-pattern:unknown lint: `dead_cod` +// error-pattern:requested on the command line with `-D dead_cod` +// error-pattern:did you mean: `dead_code` + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unknown-lint.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unknown-lint.rs new file mode 100644 index 000000000000..741ec6528227 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unknown-lint.rs @@ -0,0 +1,10 @@ +#![deny(unknown_lints)] + +#![allow(not_a_real_lint)] // { dg-error "" "" { target *-*-* } } + +#![deny(dead_cod)] // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unnecessary-import-braces.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unnecessary-import-braces.rs new file mode 100644 index 000000000000..9c7c629c2466 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unnecessary-import-braces.rs @@ -0,0 +1,12 @@ +#![deny(unused_import_braces)] + +use test::{A}; // { dg-error "" "" { target *-*-* } } + +mod test { + use test::{self}; // OK + use test::{self as rename}; // OK + pub struct A; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unnecessary-parens.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unnecessary-parens.rs new file mode 100644 index 000000000000..903a181bb464 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unnecessary-parens.rs @@ -0,0 +1,82 @@ +// run-rustfix + +#![deny(unused_parens)] +#![allow(while_true)] // for rustfix + +#[derive(Eq, PartialEq)] +struct X { y: bool } +impl X { + fn foo(&self, conjunct: bool) -> bool { self.y && conjunct } +} + +fn foo() -> isize { + return (1); // { dg-error "" "" { target *-*-* } } +} +fn bar(y: bool) -> X { + return (X { y }); // { dg-error "" "" { target *-*-* } } +} + +pub fn unused_parens_around_return_type() -> (u32) { // { dg-error "" "" { target *-*-* } } + panic!() +} + +pub fn unused_parens_around_block_return() -> u32 { + let _foo = { + (5) // { dg-error "" "" { target *-*-* } } + }; + (5) // { dg-error "" "" { target *-*-* } } +} + +pub trait Trait { + fn test(&self); +} + +pub fn passes_unused_parens_lint() -> &'static (dyn Trait) { + panic!() +} + +macro_rules! baz { + ($($foo:expr),+) => { + ($($foo),*) + } +} + +pub const CONST_ITEM: usize = (10); // { dg-error "" "" { target *-*-* } } +pub static STATIC_ITEM: usize = (10); // { dg-error "" "" { target *-*-* } } + +fn main() { + foo(); + bar((true)); // { dg-error "" "" { target *-*-* } } + + if (true) {} // { dg-error "" "" { target *-*-* } } + while (true) {} // { dg-error "" "" { target *-*-* } } + match (true) { // { dg-error "" "" { target *-*-* } } + _ => {} + } + if let 1 = (1) {} // { dg-error "" "" { target *-*-* } } + while let 1 = (2) {} // { dg-error "" "" { target *-*-* } } + let v = X { y: false }; + // struct lits needs parens, so these shouldn't warn. + if (v == X { y: true }) {} + if (X { y: true } == v) {} + if (X { y: false }.y) {} + // this shouldn't warn, because the parens are necessary to disambiguate let chains + if let true = (true && false) {} + + while (X { y: false }.foo(true)) {} + while (true | X { y: false }.y) {} + + match (X { y: false }) { + _ => {} + } + + X { y: false }.foo((true)); // { dg-error "" "" { target *-*-* } } + + let mut _a = (0); // { dg-error "" "" { target *-*-* } } + _a = (0); // { dg-error "" "" { target *-*-* } } + _a += (1); // { dg-error "" "" { target *-*-* } } + + let _a = baz!(3, 4); + let _b = baz!(3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unsafe-code.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unsafe-code.rs new file mode 100644 index 000000000000..14583068fbca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unsafe-code.rs @@ -0,0 +1,90 @@ +#![allow(unused_unsafe)] +#![allow(dead_code)] +#![deny(unsafe_code)] + +struct Bar; +struct Bar2; +struct Bar3; + +#[allow(unsafe_code)] +mod allowed_unsafe { + fn allowed() { unsafe {} } + unsafe fn also_allowed() {} + unsafe trait AllowedUnsafe { } + unsafe impl AllowedUnsafe for super::Bar {} +} + +macro_rules! unsafe_in_macro { + () => { + unsafe {} // { dg-error "" "" { target *-*-* } } + } +} + +unsafe fn baz() {} // { dg-error "" "" { target *-*-* } } +unsafe trait Foo {} // { dg-error "" "" { target *-*-* } } +unsafe impl Foo for Bar {} // { dg-error "" "" { target *-*-* } } + +trait Baz { + unsafe fn baz(&self); // { dg-error "" "" { target *-*-* } } + unsafe fn provided(&self) {} // { dg-error "" "" { target *-*-* } } + unsafe fn provided_override(&self) {} // { dg-error "" "" { target *-*-* } } +} + +impl Baz for Bar { + unsafe fn baz(&self) {} // { dg-error "" "" { target *-*-* } } + unsafe fn provided_override(&self) {} // { dg-error "" "" { target *-*-* } } +} + + +#[allow(unsafe_code)] +trait A { + unsafe fn allowed_unsafe(&self); + unsafe fn allowed_unsafe_provided(&self) {} +} + +#[allow(unsafe_code)] +impl Baz for Bar2 { + unsafe fn baz(&self) {} + unsafe fn provided_override(&self) {} +} + +impl Baz for Bar3 { + #[allow(unsafe_code)] + unsafe fn baz(&self) {} + unsafe fn provided_override(&self) {} // { dg-error "" "" { target *-*-* } } +} + +#[allow(unsafe_code)] +unsafe trait B { + fn dummy(&self) {} +} + +trait C { + #[allow(unsafe_code)] + unsafe fn baz(&self); + unsafe fn provided(&self) {} // { dg-error "" "" { target *-*-* } } +} + +impl C for Bar { + #[allow(unsafe_code)] + unsafe fn baz(&self) {} + unsafe fn provided(&self) {} // { dg-error "" "" { target *-*-* } } +} + +impl C for Bar2 { + unsafe fn baz(&self) {} // { dg-error "" "" { target *-*-* } } +} + +trait D { + #[allow(unsafe_code)] + unsafe fn unsafe_provided(&self) {} +} + +impl D for Bar {} + +fn main() { + unsafe {} // { dg-error "" "" { target *-*-* } } + + unsafe_in_macro!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unused-extern-crate.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unused-extern-crate.rs new file mode 100644 index 000000000000..2323710f3397 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unused-extern-crate.rs @@ -0,0 +1,36 @@ +// aux-build:lint_unused_extern_crate.rs +// aux-build:lint_unused_extern_crate2.rs +// aux-build:lint_unused_extern_crate3.rs +// aux-build:lint_unused_extern_crate4.rs +// aux-build:lint_unused_extern_crate5.rs + +#![deny(unused_extern_crates)] +#![allow(unused_variables)] +#![allow(deprecated)] + +extern crate lint_unused_extern_crate5; // { dg-error "" "" { target *-*-* } } + +pub extern crate lint_unused_extern_crate4; // no error, it is re-exported + +extern crate lint_unused_extern_crate3; // no error, it is used + +extern crate lint_unused_extern_crate2; // no error, the use marks it as used + // even if imported objects aren't used + +extern crate lint_unused_extern_crate as other; // no error, the use * marks it as used + +#[allow(unused_imports)] +use lint_unused_extern_crate2::foo as bar; + +use other::*; + +mod foo { + // Test that this is unused even though an earlier `extern crate` is used. + extern crate lint_unused_extern_crate2; // { dg-error "" "" { target *-*-* } } +} + +fn main() { + lint_unused_extern_crate3::foo(); + let y = foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unused-imports.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unused-imports.rs new file mode 100644 index 000000000000..17867673b2b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unused-imports.rs @@ -0,0 +1,91 @@ +#![deny(unused_imports)] +#![allow(dead_code)] + +use bar::c::cc as cal; + +use std::mem::*; // shouldn't get errors for not using + // everything imported +use std::fmt::{}; +// { dg-error "" "" { target *-*-* } .-1 } + +// Should get errors for both 'Some' and 'None' +use std::option::Option::{Some, None}; +// { dg-error "" "" { target *-*-* } .-1 } + +use test::A; // { dg-error "" "" { target *-*-* } } +// Be sure that if we just bring some methods into scope that they're also +// counted as being used. +use test::B; +// But only when actually used: do not get confused by the method with the same name. +use test::B2; // { dg-error "" "" { target *-*-* } } + +// Make sure this import is warned about when at least one of its imported names +// is unused +use test2::{foo, bar}; // { dg-error "" "" { target *-*-* } } + +mod test2 { + pub fn foo() {} + pub fn bar() {} +} + +mod test { + pub trait A { fn a(&self) {} } + pub trait B { fn b(&self) {} } + pub trait B2 { fn b(&self) {} } + pub struct C; + impl A for C {} + impl B for C {} +} + +mod foo { + pub struct Point{pub x: isize, pub y: isize} + pub struct Square{pub p: Point, pub h: usize, pub w: usize} +} + +mod bar { + // Don't ignore on 'pub use' because we're not sure if it's used or not + pub use std::cmp::PartialEq; + pub struct Square; + + pub mod c { + use foo::Point; + use foo::Square; // { dg-error "" "" { target *-*-* } } + pub fn cc(_p: Point) -> super::Square { + fn f() -> super::Square { + super::Square + } + f() + } + } + + #[allow(unused_imports)] + mod foo { + use std::cmp::PartialEq; + } +} + +fn g() { + use self::g; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + fn f() { + self::g(); + } +} + +// cf. issue #35135. +#[allow(unused_variables)] +fn h() { + use test2::foo; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + let foo = 0; +} + +fn main() { + cal(foo::Point{x:3, y:9}); + let mut a = 3; + let mut b = 4; + swap(&mut a, &mut b); + test::C.b(); + let _a = foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unused-mut-self.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unused-mut-self.rs new file mode 100644 index 000000000000..69a65b20e82c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unused-mut-self.rs @@ -0,0 +1,15 @@ +// run-rustfix + +#![allow(unused_assignments)] +#![allow(unused_variables)] +#![allow(dead_code)] +#![deny(unused_mut)] + +struct Foo; +impl Foo { + fn foo(mut self) {} // { dg-error "" "" { target *-*-* } } + fn bar(mut self: Box) {} // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unused-mut-variables.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unused-mut-variables.rs new file mode 100644 index 000000000000..a7ecd63e58e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unused-mut-variables.rs @@ -0,0 +1,208 @@ +// edition:2018 + +// Exercise the unused_mut attribute in some positive and negative cases + +#![warn(unused_mut)] +#![feature(async_closure, raw_ref_op)] + +async fn baz_async( + mut a: i32, +// { dg-warning "" "" { target *-*-* } .-1 } + #[allow(unused_mut)] mut b: i32, +) {} +fn baz( + mut a: i32, +// { dg-warning "" "" { target *-*-* } .-1 } + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) +) {} + +struct RefStruct {} +impl RefStruct { + async fn baz_async( + mut a: i32, +// { dg-warning "" "" { target *-*-* } .-1 } + #[allow(unused_mut)] mut b: i32, + ) {} + fn baz( + &self, + mut a: i32, +// { dg-warning "" "" { target *-*-* } .-1 } + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) + ) {} +} + +trait RefTrait { + fn baz( + &self, + mut a: i32, +// { dg-warning "" "" { target *-*-* } .-1 } + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) + ) {} +} +impl RefTrait for () { + fn baz( + &self, + mut a: i32, +// { dg-warning "" "" { target *-*-* } .-1 } + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) + ) {} +} + +fn main() { + let _ = async move | + mut a: i32, +// { dg-warning "" "" { target *-*-* } .-1 } + #[allow(unused_mut)] mut b: i32, + | {}; + let _ = | + mut a: i32, +// { dg-warning "" "" { target *-*-* } .-1 } + #[allow(unused_mut)] mut b: i32, + #[allow(unused_mut)] (mut c, d): (i32, i32) + | {}; + + // negative cases + let mut a = 3; // { dg-warning "" "" { target *-*-* } } + + let mut a = 2; // { dg-warning "" "" { target *-*-* } } + + let mut b = 3; // { dg-warning "" "" { target *-*-* } } + + let mut a = vec![3]; // { dg-warning "" "" { target *-*-* } } + + let (mut a, b) = (1, 2); // { dg-warning "" "" { target *-*-* } } + + let mut a; // { dg-warning "" "" { target *-*-* } } + + a = 3; + + let mut b; // { dg-warning "" "" { target *-*-* } } + + if true { + b = 3; + } else { + b = 4; + } + + match 30 { + mut x => {} // { dg-warning "" "" { target *-*-* } } + + } + + match (30, 2) { + // FIXME: Here's a false positive, + // shouldn't be removed `mut` not to be bound with a different way. + (mut x, 1) | // { dg-warning "" "" { target *-*-* } } + + (mut x, 2) | + (mut x, 3) => { + } + _ => {} + } + + let x = |mut y: isize| 10; // { dg-warning "" "" { target *-*-* } } + + fn what(mut foo: isize) {} // { dg-warning "" "" { target *-*-* } } + + + let mut a = &mut 5; // { dg-warning "" "" { target *-*-* } } + + *a = 4; + + let mut a = 5; + let mut b = (&mut a,); // { dg-warning "" "" { target *-*-* } } + *b.0 = 4; + + let mut x = &mut 1; // { dg-warning "" "" { target *-*-* } } + + let mut f = || { + *x += 1; + }; + f(); + + fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] { +// { dg-warning "" "" { target *-*-* } .-1 } + + } + + let mut v : &mut Vec<()> = &mut vec![]; // { dg-warning "" "" { target *-*-* } } + + v.push(()); + + // positive cases + let mut a = 2; + a = 3; + let mut a = Vec::new(); + a.push(3); + let mut a = Vec::new(); + callback(|| { + a.push(3); + }); + let mut a = Vec::new(); + callback(|| { + callback(|| { + a.push(3); + }); + }); + let (mut a, b) = (1, 2); + a = 34; + + match 30 { + mut x => { + x = 21; + } + } + + match (30, 2) { + (mut x, 1) | + (mut x, 2) | + (mut x, 3) => { + x = 21 + } + _ => {} + } + + // Attribute should be respected on match arms + match 0 { + #[allow(unused_mut)] + mut x => { + let mut y = 1; + }, + } + + let x = |mut y: isize| y = 32; + fn nothing(mut foo: isize) { foo = 37; } + + // leading underscore should avoid the warning, just like the + // unused variable lint. + let mut _allowed = 1; + + let mut raw_address_of_mut = 1; // OK + let mut_ptr = &raw mut raw_address_of_mut; + + let mut raw_address_of_const = 1; // { dg-warning "" "" { target *-*-* } } + let const_ptr = &raw const raw_address_of_const; +} + +fn callback(f: F) where F: FnOnce() {} + +// make sure the lint attribute can be turned off +#[allow(unused_mut)] +fn foo(mut a: isize) { + let mut a = 3; + let mut b = vec![2]; +} + +// make sure the lint attribute can be turned off on let statements +#[deny(unused_mut)] +fn bar() { + #[allow(unused_mut)] + let mut a = 3; + let mut b = vec![2]; // { dg-error "" "" { target *-*-* } } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-unused-variables.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-unused-variables.rs new file mode 100644 index 000000000000..98a780e690b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-unused-variables.rs @@ -0,0 +1,80 @@ +// compile-flags: --cfg something +// edition:2018 + +#![feature(async_closure)] +#![deny(unused_variables)] + +async fn foo_async( + a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[allow(unused_variables)] b: i32, +) {} +fn foo( + #[allow(unused_variables)] a: i32, + b: i32, +// { dg-error "" "" { target *-*-* } .-1 } +) {} + +struct RefStruct {} +impl RefStruct { + async fn bar_async( + &self, + a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[allow(unused_variables)] b: i32, + ) {} + fn bar( + &self, + #[allow(unused_variables)] a: i32, + b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ) {} + fn issue_64682_associated_fn( + #[allow(unused_variables)] a: i32, + b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ) {} +} +trait RefTrait { + fn bar( + &self, + #[allow(unused_variables)] a: i32, + b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ) {} + fn issue_64682_associated_fn( + #[allow(unused_variables)] a: i32, + b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ) {} +} +impl RefTrait for RefStruct { + fn bar( + &self, + #[allow(unused_variables)] a: i32, + b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ) {} + fn issue_64682_associated_fn( + #[allow(unused_variables)] a: i32, + b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ) {} +} + +fn main() { + let _: fn(_, _) = foo; + let a = async move | + a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[allow(unused_variables)] b: i32, + | {}; + let b = | + #[allow(unused_variables)] a: i32, + b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + | {}; + let _ = a(1, 2); + let _ = b(1, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint-uppercase-variables.rs b/gcc/testsuite/rust/rustc/ui/lint/lint-uppercase-variables.rs new file mode 100644 index 000000000000..cd3c81daabf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint-uppercase-variables.rs @@ -0,0 +1,42 @@ +#![warn(unused)] +#![allow(dead_code)] +#![deny(non_snake_case)] + +mod foo { + pub enum Foo { Foo } +} + +struct Something { + X: usize // { dg-error "" "" { target *-*-* } } +} + +fn test(Xx: usize) { // { dg-error "" "" { target *-*-* } } + println!("{}", Xx); +} + +fn main() { + let Test: usize = 0; // { dg-error "" "" { target *-*-* } } + println!("{}", Test); + + match foo::Foo::Foo { + Foo => {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + } + + let Foo = foo::Foo::Foo; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + + fn in_param(Foo: foo::Foo) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + + test(1); + + let _ = Something { X: 0 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lint_pre_expansion_extern_module_aux.rs b/gcc/testsuite/rust/rustc/ui/lint/lint_pre_expansion_extern_module_aux.rs new file mode 100644 index 000000000000..ea55d631ca90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lint_pre_expansion_extern_module_aux.rs @@ -0,0 +1,4 @@ +// ignore-test: not a test + +pub fn try() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/lints-in-foreign-macros.rs b/gcc/testsuite/rust/rustc/ui/lint/lints-in-foreign-macros.rs new file mode 100644 index 000000000000..15a75b36e6c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/lints-in-foreign-macros.rs @@ -0,0 +1,22 @@ +// aux-build:lints-in-foreign-macros.rs +// check-pass + +#![warn(unused_imports)] // { dg-error "" "" { target *-*-* } } +#![warn(missing_docs)] + +#[macro_use] +extern crate lints_in_foreign_macros; + +macro_rules! foo { + () => {use std::string::ToString;} // { dg-warning "" "" { target *-*-* } } +} + +mod a { foo!(); } +mod b { bar!(); } +mod c { baz!(use std::string::ToString;); } // { dg-warning "" "" { target *-*-* } } +mod d { baz2!(use std::string::ToString;); } // { dg-warning "" "" { target *-*-* } } +baz!(pub fn undocumented() {}); // { dg-warning "" "" { target *-*-* } } +baz2!(pub fn undocumented2() {}); // { dg-warning "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/must-use-ops.rs b/gcc/testsuite/rust/rustc/ui/lint/must-use-ops.rs new file mode 100644 index 000000000000..0debfd3d2505 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/must-use-ops.rs @@ -0,0 +1,42 @@ +// Issue #50124 - Test warning for unused operator expressions + +// check-pass + +#![warn(unused_must_use)] + +fn main() { + let val = 1; + let val_pointer = &val; + +// Comparison Operators + val == 1; // { dg-warning "" "" { target *-*-* } } + val < 1; // { dg-warning "" "" { target *-*-* } } + val <= 1; // { dg-warning "" "" { target *-*-* } } + val != 1; // { dg-warning "" "" { target *-*-* } } + val >= 1; // { dg-warning "" "" { target *-*-* } } + val > 1; // { dg-warning "" "" { target *-*-* } } + +// Arithmetic Operators + val + 2; // { dg-warning "" "" { target *-*-* } } + val - 2; // { dg-warning "" "" { target *-*-* } } + val / 2; // { dg-warning "" "" { target *-*-* } } + val * 2; // { dg-warning "" "" { target *-*-* } } + val % 2; // { dg-warning "" "" { target *-*-* } } + +// Logical Operators + true && true; // { dg-warning "" "" { target *-*-* } } + false || true; // { dg-warning "" "" { target *-*-* } } + +// Bitwise Operators + 5 ^ val; // { dg-warning "" "" { target *-*-* } } + 5 & val; // { dg-warning "" "" { target *-*-* } } + 5 | val; // { dg-warning "" "" { target *-*-* } } + 5 << val; // { dg-warning "" "" { target *-*-* } } + 5 >> val; // { dg-warning "" "" { target *-*-* } } + +// Unary Operators + !val; // { dg-warning "" "" { target *-*-* } } + -val; // { dg-warning "" "" { target *-*-* } } + *val_pointer; // { dg-warning "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/must_use-array.rs b/gcc/testsuite/rust/rustc/ui/lint/must_use-array.rs new file mode 100644 index 000000000000..b2e615ce3736 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/must_use-array.rs @@ -0,0 +1,48 @@ +#![deny(unused_must_use)] + +#[must_use] +struct S; + +struct A; + +#[must_use] +trait T {} + +impl T for A {} + +fn empty() -> [S; 0] { + [] +} + +fn singleton() -> [S; 1] { + [S] +} + +fn many() -> [S; 4] { + [S, S, S, S] +} + +fn array_of_impl_trait() -> [impl T; 2] { + [A, A] +} + +fn impl_array() -> [(u8, Box); 2] { + [(0, Box::new(A)), (0, Box::new(A))] +} + +fn array_of_arrays_of_arrays() -> [[[S; 1]; 2]; 1] { + [[[S], [S]]] +} + +fn main() { + empty(); // ok + singleton(); // { dg-error "" "" { target *-*-* } } + many(); // { dg-error "" "" { target *-*-* } } + ([S], 0, ()); // { dg-error "" "" { target *-*-* } } + array_of_impl_trait(); // { dg-error "" "" { target *-*-* } } + impl_array(); +// { dg-error "" "" { target *-*-* } .-1 } + array_of_arrays_of_arrays(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/must_use-trait.rs b/gcc/testsuite/rust/rustc/ui/lint/must_use-trait.rs new file mode 100644 index 000000000000..2d0f3c0396dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/must_use-trait.rs @@ -0,0 +1,40 @@ +#![deny(unused_must_use)] + +#[must_use] +trait Critical {} + +trait NotSoCritical {} + +trait DecidedlyUnimportant {} + +struct Anon; + +impl Critical for Anon {} +impl NotSoCritical for Anon {} +impl DecidedlyUnimportant for Anon {} + +fn get_critical() -> impl NotSoCritical + Critical + DecidedlyUnimportant { + Anon {} +} + +fn get_boxed_critical() -> Box { + Box::new(Anon {}) +} + +fn get_nested_boxed_critical() -> Box> { + Box::new(Box::new(Anon {})) +} + +fn get_critical_tuple() -> (u32, Box, impl Critical, ()) { + (0, get_boxed_critical(), get_critical(), ()) +} + +fn main() { + get_critical(); // { dg-error "" "" { target *-*-* } } + get_boxed_critical(); // { dg-error "" "" { target *-*-* } } + get_nested_boxed_critical(); +// { dg-error "" "" { target *-*-* } .-1 } + get_critical_tuple(); // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/must_use-tuple.rs b/gcc/testsuite/rust/rustc/ui/lint/must_use-tuple.rs new file mode 100644 index 000000000000..f18262985795 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/must_use-tuple.rs @@ -0,0 +1,18 @@ +#![deny(unused_must_use)] + +fn foo() -> (Result<(), ()>, ()) { + (Ok::<(), ()>(()), ()) +} + +fn main() { + (Ok::<(), ()>(()),); // { dg-error "" "" { target *-*-* } } + + (Ok::<(), ()>(()), 0, Ok::<(), ()>(()), 5); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + foo(); // { dg-error "" "" { target *-*-* } } + + ((Err::<(), ()>(()), ()), ()); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/must_use-unit.rs b/gcc/testsuite/rust/rustc/ui/lint/must_use-unit.rs new file mode 100644 index 000000000000..f90a323404de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/must_use-unit.rs @@ -0,0 +1,17 @@ +#![feature(never_type)] +#![deny(unused_must_use)] + +#[must_use] +fn foo() {} + +#[must_use] +fn bar() -> ! { + unimplemented!() +} + +fn main() { + foo(); // { dg-error "" "" { target *-*-* } } + + bar(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/no-unused-parens-return-block.rs b/gcc/testsuite/rust/rustc/ui/lint/no-unused-parens-return-block.rs new file mode 100644 index 000000000000..e4b4029d6d6c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/no-unused-parens-return-block.rs @@ -0,0 +1,10 @@ +// run-pass + +#![deny(unused_parens)] +#![allow(unreachable_code)] + +fn main() { + match (return) {} // ok + if (return) {} // ok +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/not_found.rs b/gcc/testsuite/rust/rustc/ui/lint/not_found.rs new file mode 100644 index 000000000000..e2fb411017db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/not_found.rs @@ -0,0 +1,22 @@ +// check-pass + +// this tests the `unknown_lint` lint, especially the suggestions + +// the suggestion only appears if a lint with the lowercase name exists +#[allow(FOO_BAR)] +// { dg-warning "" "" { target *-*-* } .-1 } + +// the suggestion appears on all-uppercase names +#[warn(DEAD_CODE)] +// { dg-warning "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + +// the suggestion appears also on mixed-case names +#[deny(Warnings)] +// { dg-warning "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + +fn main() { + unimplemented!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/opaque-ty-ffi-unsafe.rs b/gcc/testsuite/rust/rustc/ui/lint/opaque-ty-ffi-unsafe.rs new file mode 100644 index 000000000000..f774986611d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/opaque-ty-ffi-unsafe.rs @@ -0,0 +1,16 @@ +#![feature(type_alias_impl_trait)] +#![deny(improper_ctypes)] + +type A = impl Fn(); + +pub fn ret_closure() -> A { + || {} +} + +extern "C" { + pub fn a(_: A); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/outer-forbid.rs b/gcc/testsuite/rust/rustc/ui/lint/outer-forbid.rs new file mode 100644 index 000000000000..2bff2d782c5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/outer-forbid.rs @@ -0,0 +1,25 @@ +// Forbidding a group (here, `unused`) overrules subsequent allowance of both +// the group, and an individual lint in the group (here, `unused_variables`); +// and, forbidding an individual lint (here, `non_snake_case`) overrules +// subsequent allowance of a lint group containing it (here, `nonstandard_style`). See +// Issue #42873. + +#![forbid(unused, non_snake_case)] + +#[allow(unused_variables)] // { dg-error ".E0453." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +fn foo() {} + +#[allow(unused)] // { dg-error ".E0453." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +fn bar() {} + +#[allow(nonstandard_style)] // { dg-error ".E0453." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +fn main() { + println!("hello forbidden world") +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/reasons-erroneous.rs b/gcc/testsuite/rust/rustc/ui/lint/reasons-erroneous.rs new file mode 100644 index 000000000000..2bcece483118 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/reasons-erroneous.rs @@ -0,0 +1,75 @@ +#![feature(lint_reasons)] + +#![warn(absolute_paths_not_starting_with_crate, reason = 0)] +// { dg-error ".E0452." "" { target *-*-* } .-1 } +// { dg-error ".E0452." "" { target *-*-* } .-2 } +// { dg-error ".E0452." "" { target *-*-* } .-3 } +// { dg-note ".E0452." "" { target *-*-* } .-4 } +// { dg-note ".E0452." "" { target *-*-* } .-5 } +// { dg-note ".E0452." "" { target *-*-* } .-6 } +#![warn(anonymous_parameters, reason = b"consider these, for we have condemned them")] +// { dg-error ".E0452." "" { target *-*-* } .-1 } +// { dg-error ".E0452." "" { target *-*-* } .-2 } +// { dg-error ".E0452." "" { target *-*-* } .-3 } +// { dg-note ".E0452." "" { target *-*-* } .-4 } +// { dg-note ".E0452." "" { target *-*-* } .-5 } +// { dg-note ".E0452." "" { target *-*-* } .-6 } +#![warn(bare_trait_objects, reasons = "leaders to no sure land, guides their bearings lost")] +// { dg-error ".E0452." "" { target *-*-* } .-1 } +// { dg-error ".E0452." "" { target *-*-* } .-2 } +// { dg-error ".E0452." "" { target *-*-* } .-3 } +// { dg-error ".E0452." "" { target *-*-* } .-4 } +// { dg-error ".E0452." "" { target *-*-* } .-5 } +// { dg-error ".E0452." "" { target *-*-* } .-6 } +// { dg-note ".E0452." "" { target *-*-* } .-7 } +// { dg-note ".E0452." "" { target *-*-* } .-8 } +// { dg-note ".E0452." "" { target *-*-* } .-9 } +// { dg-note ".E0452." "" { target *-*-* } .-10 } +// { dg-note ".E0452." "" { target *-*-* } .-11 } +// { dg-note ".E0452." "" { target *-*-* } .-12 } +#![warn(box_pointers, blerp = "or in league with robbers have reversed the signposts")] +// { dg-error ".E0452." "" { target *-*-* } .-1 } +// { dg-error ".E0452." "" { target *-*-* } .-2 } +// { dg-error ".E0452." "" { target *-*-* } .-3 } +// { dg-error ".E0452." "" { target *-*-* } .-4 } +// { dg-error ".E0452." "" { target *-*-* } .-5 } +// { dg-error ".E0452." "" { target *-*-* } .-6 } +// { dg-note ".E0452." "" { target *-*-* } .-7 } +// { dg-note ".E0452." "" { target *-*-* } .-8 } +// { dg-note ".E0452." "" { target *-*-* } .-9 } +// { dg-note ".E0452." "" { target *-*-* } .-10 } +// { dg-note ".E0452." "" { target *-*-* } .-11 } +// { dg-note ".E0452." "" { target *-*-* } .-12 } +#![warn(elided_lifetimes_in_paths, reason("disrespectful to ancestors", "irresponsible to heirs"))] +// { dg-error ".E0452." "" { target *-*-* } .-1 } +// { dg-error ".E0452." "" { target *-*-* } .-2 } +// { dg-error ".E0452." "" { target *-*-* } .-3 } +// { dg-error ".E0452." "" { target *-*-* } .-4 } +// { dg-error ".E0452." "" { target *-*-* } .-5 } +// { dg-error ".E0452." "" { target *-*-* } .-6 } +// { dg-note ".E0452." "" { target *-*-* } .-7 } +// { dg-note ".E0452." "" { target *-*-* } .-8 } +// { dg-note ".E0452." "" { target *-*-* } .-9 } +// { dg-note ".E0452." "" { target *-*-* } .-10 } +// { dg-note ".E0452." "" { target *-*-* } .-11 } +// { dg-note ".E0452." "" { target *-*-* } .-12 } +#![warn(ellipsis_inclusive_range_patterns, reason = "born barren", reason = "a freak growth")] +// { dg-error ".E0452." "" { target *-*-* } .-1 } +// { dg-error ".E0452." "" { target *-*-* } .-2 } +// { dg-error ".E0452." "" { target *-*-* } .-3 } +// { dg-note ".E0452." "" { target *-*-* } .-4 } +// { dg-note ".E0452." "" { target *-*-* } .-5 } +// { dg-note ".E0452." "" { target *-*-* } .-6 } +#![warn(keyword_idents, reason = "root in rubble", macro_use_extern_crate)] +// { dg-error ".E0452." "" { target *-*-* } .-1 } +// { dg-error ".E0452." "" { target *-*-* } .-2 } +// { dg-error ".E0452." "" { target *-*-* } .-3 } +// { dg-note ".E0452." "" { target *-*-* } .-4 } +// { dg-note ".E0452." "" { target *-*-* } .-5 } +// { dg-note ".E0452." "" { target *-*-* } .-6 } +#![warn(missing_copy_implementations, reason)] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/reasons-forbidden.rs b/gcc/testsuite/rust/rustc/ui/lint/reasons-forbidden.rs new file mode 100644 index 000000000000..eb0c2af33b5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/reasons-forbidden.rs @@ -0,0 +1,42 @@ +#![feature(lint_reasons)] + +#![forbid( + unsafe_code, +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +// { dg-note "" "" { target *-*-* } .-4 } +// { dg-note "" "" { target *-*-* } .-5 } +// { dg-note "" "" { target *-*-* } .-6 } + reason = "our errors & omissions insurance policy doesn't cover unsafe Rust" +)] + +use std::ptr; + +fn main() { + let a_billion_dollar_mistake = ptr::null(); + + #[allow(unsafe_code)] +// { dg-error ".E0453." "" { target *-*-* } .-1 } +// { dg-error ".E0453." "" { target *-*-* } .-2 } +// { dg-error ".E0453." "" { target *-*-* } .-3 } +// { dg-error ".E0453." "" { target *-*-* } .-4 } +// { dg-error ".E0453." "" { target *-*-* } .-5 } +// { dg-error ".E0453." "" { target *-*-* } .-6 } +// { dg-note ".E0453." "" { target *-*-* } .-7 } +// { dg-note ".E0453." "" { target *-*-* } .-8 } +// { dg-note ".E0453." "" { target *-*-* } .-9 } +// { dg-note ".E0453." "" { target *-*-* } .-10 } +// { dg-note ".E0453." "" { target *-*-* } .-11 } +// { dg-note ".E0453." "" { target *-*-* } .-12 } +// { dg-note ".E0453." "" { target *-*-* } .-13 } +// { dg-note ".E0453." "" { target *-*-* } .-14 } +// { dg-note ".E0453." "" { target *-*-* } .-15 } +// { dg-note ".E0453." "" { target *-*-* } .-16 } +// { dg-note ".E0453." "" { target *-*-* } .-17 } +// { dg-note ".E0453." "" { target *-*-* } .-18 } + unsafe { + *a_billion_dollar_mistake + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/reasons.rs b/gcc/testsuite/rust/rustc/ui/lint/reasons.rs new file mode 100644 index 000000000000..28a570f0c179 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/reasons.rs @@ -0,0 +1,36 @@ +// check-pass + +#![feature(lint_reasons)] + +#![warn(elided_lifetimes_in_paths, +// { dg-note "" "" { target *-*-* } .-1 } + reason = "explicit anonymous lifetimes aid reasoning about ownership")] +#![warn( + nonstandard_style, +// { dg-note "" "" { target *-*-* } .-1 } + reason = r#"people shouldn't have to change their usual style habits +to contribute to our project"# +)] +#![allow(unused, reason = "unused code has never killed anypony")] + +use std::fmt; + +pub struct CheaterDetectionMechanism {} + +impl fmt::Debug for CheaterDetectionMechanism { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } + fmt.debug_struct("CheaterDetectionMechanism").finish() + } +} + +fn main() { + let Social_exchange_psychology = CheaterDetectionMechanism {}; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +// { help "" "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs b/gcc/testsuite/rust/rustc/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs new file mode 100644 index 000000000000..43641761e70f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/redundant-semicolon/auxiliary/redundant-semi-proc-macro-def.rs @@ -0,0 +1,13 @@ +// force-host +// no-prefer-dynamic +#![crate_type="proc-macro"] +#![crate_name="redundant_semi_proc_macro"] +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn should_preserve_spans(_attr: TokenStream, item: TokenStream) -> TokenStream { + eprintln!("{:?}", item); + item +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs b/gcc/testsuite/rust/rustc/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs new file mode 100644 index 000000000000..fabd8b92b64b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/redundant-semicolon/redundant-semi-proc-macro.rs @@ -0,0 +1,20 @@ +// aux-build:redundant-semi-proc-macro-def.rs + +#![deny(redundant_semicolons)] +extern crate redundant_semi_proc_macro; +use redundant_semi_proc_macro::should_preserve_spans; + +#[should_preserve_spans] +fn span_preservation() { + let tst = 123;; // { dg-error "" "" { target *-*-* } } + match tst { + // Redundant semicolons are parsed as empty tuple exprs + // for the lint, so ensure the lint doesn't affect + // empty tuple exprs explicitly in source. + 123 => (), + _ => () + };;; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs b/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs new file mode 100644 index 000000000000..6f4bc26bd1c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-confusable-idents.rs @@ -0,0 +1,18 @@ +#![feature(non_ascii_idents)] +#![deny(confusable_idents)] +#![allow(uncommon_codepoints, non_upper_case_globals)] + +const s: usize = 42; +const s_s: usize = 42; + +fn main() { + let s = "rust"; // { dg-error "" "" { target *-*-* } } + let s_s = "rust2"; // { dg-error "" "" { target *-*-* } } + not_affected(); +} + +fn not_affected() { + let s1 = 1; + let sl = 'l'; +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables-2.rs b/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables-2.rs new file mode 100644 index 000000000000..b3b5ab1bbcc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables-2.rs @@ -0,0 +1,21 @@ +// check-pass +#![feature(non_ascii_idents)] +#![deny(mixed_script_confusables)] + +struct ΑctuallyNotLatin; + +fn main() { + let λ = 42; // this usage of Greek confirms that Greek is used intentionally. +} + +mod роре { + const エ: &'static str = "アイウ"; + + // this usage of Katakana confirms that Katakana is used intentionally. + fn ニャン() { + let д: usize = 100; // this usage of Cyrillic confirms that Cyrillic is used intentionally. + + println!("meow!"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.rs b/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.rs new file mode 100644 index 000000000000..402ff8d3e11f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.rs @@ -0,0 +1,16 @@ +#![feature(non_ascii_idents)] +#![deny(mixed_script_confusables)] + +struct ΑctuallyNotLatin; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + let v = ΑctuallyNotLatin; +} + +mod роре { +// { dg-error "" "" { target *-*-* } .-1 } + const エ: &'static str = "アイウ"; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs b/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs new file mode 100644 index 000000000000..bf5196186dce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-non-ascii-idents.rs @@ -0,0 +1,14 @@ +#![feature(non_ascii_idents)] +#![deny(non_ascii_idents)] + +const חלודה: usize = 2; // { dg-error "" "" { target *-*-* } } + +fn coöperation() {} // { dg-error "" "" { target *-*-* } } + +fn main() { + let naïveté = 2; // { dg-error "" "" { target *-*-* } } + + // using the same identifier the second time won't trigger the lint. + println!("{}", naïveté); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs b/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs new file mode 100644 index 000000000000..3f5a5f06087b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs @@ -0,0 +1,14 @@ +#![feature(non_ascii_idents)] +#![deny(uncommon_codepoints)] + +const µ: f64 = 0.000001; // { dg-error "" "" { target *-*-* } } + +fn dijkstra() {} // { dg-error "" "" { target *-*-* } } + +fn main() { + let ㇻㇲㇳ = "rust"; // { dg-error "" "" { target *-*-* } } + + // using the same identifier the second time won't trigger the lint. + println!("{}", ㇻㇲㇳ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/suggestions.rs b/gcc/testsuite/rust/rustc/ui/lint/suggestions.rs new file mode 100644 index 000000000000..6ea7f1898295 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/suggestions.rs @@ -0,0 +1,68 @@ +// ignore-tidy-tab +// run-rustfix + +#![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896 + +#[no_mangle] const DISCOVERY: usize = 1; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + +#[no_mangle] +// { help "" "" { target *-*-* } .-1 } +pub fn defiant(_t: T) {} +// { dg-warning "" "" { target *-*-* } .-1 } + +#[no_mangle] +fn rio_grande() {} + +mod badlands { + // The private-no-mangle lints shouldn't suggest inserting `pub` when the + // item is already `pub` (but triggered the lint because, e.g., it's in a + // private module). (Issue #47383) + #[no_mangle] pub const DAUNTLESS: bool = true; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + #[allow(dead_code)] // for rustfix + #[no_mangle] pub fn val_jean() {} +// { dg-warning "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + + // ... but we can suggest just-`pub` instead of restricted + #[no_mangle] pub(crate) const VETAR: bool = true; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + #[allow(dead_code)] // for rustfix + #[no_mangle] pub(crate) fn crossfield() {} +// { dg-warning "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +} + +struct Equinox { + warp_factor: f32, +} + +fn main() { + while true { +// { dg-warning "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + let mut registry_no = (format!("NX-{}", 74205)); +// { dg-warning "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { help "" "" { target *-*-* } .-4 } + // the line after `mut` has a `\t` at the beginning, this is on purpose + let mut + b = 1; +// { dg-warning "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-2 } + let d = Equinox { warp_factor: 9.975 }; + match d { + #[allow(unused_variables)] // for rustfix + Equinox { warp_factor: warp_factor } => {} +// { dg-warning "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + } + println!("{} {}", registry_no, b); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/test-inner-fn.rs b/gcc/testsuite/rust/rustc/ui/lint/test-inner-fn.rs new file mode 100644 index 000000000000..2082a1757710 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/test-inner-fn.rs @@ -0,0 +1,20 @@ +// compile-flags: --test -D unnameable_test_items + +#[test] +fn foo() { + #[test] // { dg-error "" "" { target *-*-* } } + fn bar() {} + bar(); +} + +mod x { + #[test] + fn foo() { + #[test] // { dg-error "" "" { target *-*-* } } + fn bar() {} + bar(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/trivial-casts-featuring-type-ascription.rs b/gcc/testsuite/rust/rustc/ui/lint/trivial-casts-featuring-type-ascription.rs new file mode 100644 index 000000000000..7b838c672410 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/trivial-casts-featuring-type-ascription.rs @@ -0,0 +1,11 @@ +#![deny(trivial_casts, trivial_numeric_casts)] +#![feature(type_ascription)] + +fn main() { + let lugubrious = 12i32 as i32; +// { dg-error "" "" { target *-*-* } .-1 } + let haunted: &u32 = &99; + let _ = haunted as *const u32; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/trivial-casts.rs b/gcc/testsuite/rust/rustc/ui/lint/trivial-casts.rs new file mode 100644 index 000000000000..12d7e62acbb2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/trivial-casts.rs @@ -0,0 +1,10 @@ +#![deny(trivial_casts, trivial_numeric_casts)] + +fn main() { + let lugubrious = 12i32 as i32; +// { dg-error "" "" { target *-*-* } .-1 } + let haunted: &u32 = &99; + let _ = haunted as *const u32; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/type-overflow.rs b/gcc/testsuite/rust/rustc/ui/lint/type-overflow.rs new file mode 100644 index 000000000000..c558e490bf8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/type-overflow.rs @@ -0,0 +1,23 @@ +// check-pass +#![warn(overflowing_literals)] + +fn main() { + let error = 255i8; // { dg-warning "" "" { target *-*-* } } + + let ok = 0b1000_0001; // should be ok -> i32 + let ok = 0b0111_1111i8; // should be ok -> 127i8 + + let fail = 0b1000_0001i8; // { dg-warning "" "" { target *-*-* } } + + let fail = 0x8000_0000_0000_0000i64; // { dg-warning "" "" { target *-*-* } } + + let fail = 0x1_FFFF_FFFFu32; // { dg-warning "" "" { target *-*-* } } + + let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; +// { dg-warning "" "" { target *-*-* } .-1 } + + let fail = 0x8FFF_FFFF_FFFF_FFFE; // { dg-warning "" "" { target *-*-* } } + + let fail = -0b1111_1111i8; // { dg-warning "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/unaligned_references.rs b/gcc/testsuite/rust/rustc/ui/lint/unaligned_references.rs new file mode 100644 index 000000000000..ad32f93ed6c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/unaligned_references.rs @@ -0,0 +1,30 @@ +#![deny(unaligned_references)] + +#[repr(packed)] +pub struct Good { + data: u64, + ptr: &'static u64, + data2: [u64; 2], + aligned: [u8; 32], +} + +fn main() { + unsafe { + let good = Good { data: 0, ptr: &0, data2: [0, 0], aligned: [0; 32] }; + + let _ = &good.ptr; // { dg-error "" "" { target *-*-* } } + let _ = &good.data; // { dg-error "" "" { target *-*-* } } + // Error even when turned into raw pointer immediately. + let _ = &good.data as *const _; // { dg-error "" "" { target *-*-* } } + let _: *const _ = &good.data; // { dg-error "" "" { target *-*-* } } + // Error on method call. + let _ = good.data.clone(); // { dg-error "" "" { target *-*-* } } + // Error for nested fields. + let _ = &good.data2[0]; // { dg-error "" "" { target *-*-* } } + + let _ = &*good.ptr; // ok, behind a pointer + let _ = &good.aligned; // ok, has align 1 + let _ = &good.aligned[2]; // ok, has align 1 + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/uninitialized-zeroed.rs b/gcc/testsuite/rust/rustc/ui/lint/uninitialized-zeroed.rs new file mode 100644 index 000000000000..00d882c8e334 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/uninitialized-zeroed.rs @@ -0,0 +1,120 @@ +// ignore-tidy-linelength +// This test checks that calling `mem::{uninitialized,zeroed}` with certain types results +// in a lint. + +#![feature(never_type, rustc_attrs)] +#![allow(deprecated)] +#![deny(invalid_value)] + +use std::mem::{self, MaybeUninit}; +use std::ptr::NonNull; +use std::num::NonZeroU32; + +enum Void {} + +struct Ref(&'static i32); +struct RefPair((&'static i32, i32)); + +struct Wrap { wrapped: T } +enum WrapEnum { Wrapped(T) } + +#[rustc_layout_scalar_valid_range_start(0)] +#[rustc_layout_scalar_valid_range_end(128)] +#[repr(transparent)] +pub(crate) struct NonBig(u64); + +/// A two-variant enum, thus needs a tag and may not remain uninitialized. +enum Fruit { + Apple, + Banana, +} + +/// Looks like two variants but really only has one. +enum OneFruit { + Apple(!), + Banana, +} + +#[allow(unused)] +fn generic() { + unsafe { + let _val: &'static T = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: &'static T = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: Wrap<&'static T> = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: Wrap<&'static T> = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + } +} + +fn main() { + unsafe { + // Things that cannot even be zero. + let _val: ! = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: ! = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: (i32, !) = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: (i32, !) = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: Void = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: Void = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: &'static i32 = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: &'static i32 = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: Ref = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: Ref = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: fn() = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: fn() = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: Wrap = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: Wrap = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: WrapEnum = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: WrapEnum = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: Wrap<(RefPair, i32)> = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: NonNull = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: NonNull = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: *const dyn Send = mem::zeroed(); // { dg-error "" "" { target *-*-* } } + let _val: *const dyn Send = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + // Things that can be zero, but not uninit. + let _val: bool = mem::zeroed(); + let _val: bool = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: Wrap = mem::zeroed(); + let _val: Wrap = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: NonBig = mem::zeroed(); + let _val: NonBig = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + let _val: Fruit = mem::zeroed(); + let _val: Fruit = mem::uninitialized(); // { dg-error "" "" { target *-*-* } } + + // Transmute-from-0 + let _val: &'static i32 = mem::transmute(0usize); // { dg-error "" "" { target *-*-* } } + let _val: &'static [i32] = mem::transmute((0usize, 0usize)); // { dg-error "" "" { target *-*-* } } + let _val: NonZeroU32 = mem::transmute(0); // { dg-error "" "" { target *-*-* } } + + // `MaybeUninit` cases + let _val: NonNull = MaybeUninit::zeroed().assume_init(); // { dg-error "" "" { target *-*-* } } + let _val: NonNull = MaybeUninit::uninit().assume_init(); // { dg-error "" "" { target *-*-* } } + let _val: bool = MaybeUninit::uninit().assume_init(); // { dg-error "" "" { target *-*-* } } + + // Some more types that should work just fine. + let _val: Option<&'static i32> = mem::zeroed(); + let _val: Option = mem::zeroed(); + let _val: MaybeUninit<&'static i32> = mem::zeroed(); + let _val: i32 = mem::zeroed(); + let _val: bool = MaybeUninit::zeroed().assume_init(); + // Some things that happen to work due to rustc implementation details, + // but are not guaranteed to keep working. + let _val: i32 = mem::uninitialized(); + let _val: OneFruit = mem::uninitialized(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/unreachable-async-fn.rs b/gcc/testsuite/rust/rustc/ui/lint/unreachable-async-fn.rs new file mode 100644 index 000000000000..eb012927839e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/unreachable-async-fn.rs @@ -0,0 +1,10 @@ +// check-pass +// edition:2018 + +#[allow(dead_code)] +async fn foo () { // unreachable lint doesn't trigger + unimplemented!() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/unreachable_pub-pub_crate.rs b/gcc/testsuite/rust/rustc/ui/lint/unreachable_pub-pub_crate.rs new file mode 100644 index 000000000000..b290a03982a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/unreachable_pub-pub_crate.rs @@ -0,0 +1,68 @@ +// This is just like unreachable_pub.rs, but without the +// `crate_visibility_modifier` feature (so that we can test the suggestions to +// use `pub(crate)` that are given when that feature is off, as opposed to the +// suggestions to use `crate` given when it is on). When that feature becomes +// stable, this test can be deleted. + +// check-pass + + +#![warn(unreachable_pub)] + +mod private_mod { + // non-leaked `pub` items in private module should be linted + pub use std::fmt; // { dg-warning "" "" { target *-*-* } } + pub use std::env::{Args}; // braced-use has different item spans than unbraced +// { dg-warning "" "" { target *-*-* } .-1 } + + pub struct Hydrogen { // { dg-warning "" "" { target *-*-* } } + // `pub` struct fields, too + pub neutrons: usize, // { dg-warning "" "" { target *-*-* } } + // (... but not more-restricted fields) + pub(crate) electrons: usize + } + impl Hydrogen { + // impls, too + pub fn count_neutrons(&self) -> usize { self.neutrons } // { dg-warning "" "" { target *-*-* } } + pub(crate) fn count_electrons(&self) -> usize { self.electrons } + } + + pub enum Helium {} // { dg-warning "" "" { target *-*-* } } + pub union Lithium { c1: usize, c2: u8 } // { dg-warning "" "" { target *-*-* } } + pub fn beryllium() {} // { dg-warning "" "" { target *-*-* } } + pub trait Boron {} // { dg-warning "" "" { target *-*-* } } + pub const CARBON: usize = 1; // { dg-warning "" "" { target *-*-* } } + pub static NITROGEN: usize = 2; // { dg-warning "" "" { target *-*-* } } + pub type Oxygen = bool; // { dg-warning "" "" { target *-*-* } } + + macro_rules! define_empty_struct_with_visibility { + ($visibility: vis, $name: ident) => { $visibility struct $name {} } +// { dg-warning "" "" { target *-*-* } .-1 } + } + define_empty_struct_with_visibility!(pub, Fluorine); + + extern { + pub fn catalyze() -> bool; // { dg-warning "" "" { target *-*-* } } + } + + // items leaked through signatures (see `get_neon` below) are OK + pub struct Neon {} + + // crate-visible items are OK + pub(crate) struct Sodium {} +} + +pub mod public_mod { + // module is public: these are OK, too + pub struct Magnesium {} + pub(crate) struct Aluminum {} +} + +pub fn get_neon() -> private_mod::Neon { + private_mod::Neon {} +} + +fn main() { + let _ = get_neon(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/unreachable_pub.rs b/gcc/testsuite/rust/rustc/ui/lint/unreachable_pub.rs new file mode 100644 index 000000000000..491025f7642d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/unreachable_pub.rs @@ -0,0 +1,64 @@ +// check-pass + +#![feature(crate_visibility_modifier)] + +#![allow(unused)] +#![warn(unreachable_pub)] + +mod private_mod { + // non-leaked `pub` items in private module should be linted + pub use std::fmt; // { dg-warning "" "" { target *-*-* } } + pub use std::env::{Args}; // braced-use has different item spans than unbraced +// { dg-warning "" "" { target *-*-* } .-1 } + + pub struct Hydrogen { // { dg-warning "" "" { target *-*-* } } + // `pub` struct fields, too + pub neutrons: usize, // { dg-warning "" "" { target *-*-* } } + // (... but not more-restricted fields) + crate electrons: usize + } + impl Hydrogen { + // impls, too + pub fn count_neutrons(&self) -> usize { self.neutrons } // { dg-warning "" "" { target *-*-* } } + crate fn count_electrons(&self) -> usize { self.electrons } + } + + pub enum Helium {} // { dg-warning "" "" { target *-*-* } } + pub union Lithium { c1: usize, c2: u8 } // { dg-warning "" "" { target *-*-* } } + pub fn beryllium() {} // { dg-warning "" "" { target *-*-* } } + pub trait Boron {} // { dg-warning "" "" { target *-*-* } } + pub const CARBON: usize = 1; // { dg-warning "" "" { target *-*-* } } + pub static NITROGEN: usize = 2; // { dg-warning "" "" { target *-*-* } } + pub type Oxygen = bool; // { dg-warning "" "" { target *-*-* } } + + macro_rules! define_empty_struct_with_visibility { + ($visibility: vis, $name: ident) => { $visibility struct $name {} } +// { dg-warning "" "" { target *-*-* } .-1 } + } + define_empty_struct_with_visibility!(pub, Fluorine); + + extern { + pub fn catalyze() -> bool; // { dg-warning "" "" { target *-*-* } } + } + + // items leaked through signatures (see `get_neon` below) are OK + pub struct Neon {} + + // crate-visible items are OK + crate struct Sodium {} +} + +pub mod public_mod { + // module is public: these are OK, too + pub struct Magnesium {} + crate struct Aluminum {} +} + +pub fn get_neon() -> private_mod::Neon { + private_mod::Neon {} +} + +fn main() { + let _ = get_neon(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/unused-braces-while-let-with-mutable-value.rs b/gcc/testsuite/rust/rustc/ui/lint/unused-braces-while-let-with-mutable-value.rs new file mode 100644 index 000000000000..5d22674b33d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/unused-braces-while-let-with-mutable-value.rs @@ -0,0 +1,13 @@ +// check-pass + +#![deny(unused_braces)] + +fn main() { + let mut a = Some(3); + // Shouldn't warn below `a`. + while let Some(ref mut v) = {a} { + a.as_mut().map(|a| std::mem::swap(a, v)); + break; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/unused_braces.rs b/gcc/testsuite/rust/rustc/ui/lint/unused_braces.rs new file mode 100644 index 000000000000..a747110f1339 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/unused_braces.rs @@ -0,0 +1,54 @@ +// check-pass +// run-rustfix + +#![warn(unused_braces, unused_parens)] +#![allow(unreachable_code, unused_unsafe)] // for rustfix + +fn consume(_: T) {} + +fn main() { + let _ = (7); +// { dg-warning "" "" { target *-*-* } .-1 } + + // Do not emit a lint in these cases, + // as we have to be careful with + // `ref` patterns. + { + let _ = { 7 }; + + if let 7 = { 7 } { } + + match { 7 } { + _ => (), + } + } + + if { true } { +// { dg-warning "" "" { target *-*-* } .-1 } + } + + while { false } { +// { dg-warning "" "" { target *-*-* } .-1 } + } + + let _: [u8; { 3 }]; +// { dg-warning "" "" { target *-*-* } .-1 } + + consume({ 7 }); +// { dg-warning "" "" { target *-*-* } .-1 } + + // Do not emit lint for multiline blocks. + let _ = { + 7 + }; + + // Do not emit lint for unsafe blocks. + let _ = unsafe { 7 }; + + // Do not emit lint, as the `{` would then + // be parsed as part of the `return`. + if { return } { + + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/unused_braces_borrow.rs b/gcc/testsuite/rust/rustc/ui/lint/unused_braces_borrow.rs new file mode 100644 index 000000000000..16bc4d4a58a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/unused_braces_borrow.rs @@ -0,0 +1,27 @@ +// check-pass +// run-rustfix + +#![warn(unused_braces)] + +// changing `&{ expr }` to `&expr` changes the semantic of the program +// so we should not warn this case + +#[repr(packed)] +pub struct A { + pub a: u8, + pub b: u32, +} + +fn consume(_: T) {} + +fn main() { + let a = A { + a: 42, + b: 1729, + }; + + consume(&{ a.b }); + consume({ a.b }); +// { dg-warning "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/unused_import_warning_issue_45268.rs b/gcc/testsuite/rust/rustc/ui/lint/unused_import_warning_issue_45268.rs new file mode 100644 index 000000000000..c632aae89694 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/unused_import_warning_issue_45268.rs @@ -0,0 +1,50 @@ +// check-pass + +#![warn(unused_imports)] // Warning explanation here, it's OK + +mod test { + pub trait A { + fn a(); + } + + impl A for () { + fn a() { } + } + + pub trait B { + fn b(self); + } + + impl B for () { + fn b(self) { } + } + + pub trait Unused { + } +} + +use test::Unused; // This is really unused, so warning is OK +// { dg-warning "" "" { target *-*-* } .-1 } +use test::A; // This is used by the test2::func() through import of super::* +use test::B; // This is used by the test2::func() through import of super::* + +mod test2 { + use super::*; + pub fn func() { + let _ = <()>::a(); + let _ = ().b(); + test3::inner_func(); + } + mod test3 { + use super::*; + pub fn inner_func() { + let _ = <()>::a(); + let _ = ().b(); + } + } +} + +fn main() { + test2::func(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/unused_labels.rs b/gcc/testsuite/rust/rustc/ui/lint/unused_labels.rs new file mode 100644 index 000000000000..f10e2937dfee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/unused_labels.rs @@ -0,0 +1,87 @@ +// The output should warn when a loop label is not used. However, it +// should also deal with the edge cases where a label is shadowed, +// within nested loops + +// check-pass + +#![feature(label_break_value)] +#![warn(unused_labels)] + +fn main() { + 'unused_while_label: while 0 == 0 { +// { dg-warning "" "" { target *-*-* } .-1 } + } + + let opt = Some(0); + 'unused_while_let_label: while let Some(_) = opt { +// { dg-warning "" "" { target *-*-* } .-1 } + } + + 'unused_for_label: for _ in 0..10 { +// { dg-warning "" "" { target *-*-* } .-1 } + } + + 'used_loop_label: loop { + break 'used_loop_label; + } + + 'used_loop_label_outer_1: for _ in 0..10 { + 'used_loop_label_inner_1: for _ in 0..10 { + break 'used_loop_label_inner_1; + } + break 'used_loop_label_outer_1; + } + + 'used_loop_label_outer_2: for _ in 0..10 { + 'unused_loop_label_inner_2: for _ in 0..10 { +// { dg-warning "" "" { target *-*-* } .-1 } + break 'used_loop_label_outer_2; + } + } + + 'unused_loop_label_outer_3: for _ in 0..10 { +// { dg-warning "" "" { target *-*-* } .-1 } + 'used_loop_label_inner_3: for _ in 0..10 { + break 'used_loop_label_inner_3; + } + } + + // You should be able to break the same label many times + 'many_used: loop { + if true { + break 'many_used; + } else { + break 'many_used; + } + } + + // Test breaking many times with the same inner label doesn't break the + // warning on the outer label + 'many_used_shadowed: for _ in 0..10 { +// { dg-warning "" "" { target *-*-* } .-1 } + 'many_used_shadowed: for _ in 0..10 { +// { dg-warning "" "" { target *-*-* } .-1 } + if 1 % 2 == 0 { + break 'many_used_shadowed; + } else { + break 'many_used_shadowed; + } + } + } + + 'unused_loop_label: loop { +// { dg-warning "" "" { target *-*-* } .-1 } + break; + } + + // Make sure unused block labels give warnings... + 'unused_block_label: { +// { dg-warning "" "" { target *-*-* } .-1 } + } + + // ...and that used ones don't: + 'used_block_label: { + break 'used_block_label; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/unused_parens_json_suggestion.rs b/gcc/testsuite/rust/rustc/ui/lint/unused_parens_json_suggestion.rs new file mode 100644 index 000000000000..fe9c05546897 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/unused_parens_json_suggestion.rs @@ -0,0 +1,27 @@ +// compile-flags: --error-format json -Zunstable-options +// run-rustfix + +// The output for humans should just highlight the whole span without showing +// the suggested replacement, but we also want to test that suggested +// replacement only removes one set of parentheses, rather than naïvely +// stripping away any starting or ending parenthesis characters—hence this +// test of the JSON error format. + +#![deny(unused_parens)] +#![allow(unreachable_code)] + +fn main() { + // We want to suggest the properly-balanced expression `1 / (2 + 3)`, not + // the malformed `1 / (2 + 3` + let _a = (1 / (2 + 3)); // { dg-error "" "" { target *-*-* } } + f(); +} + +fn f() -> bool { + loop { + if (break { return true }) { + } + } + false +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/unused_parens_remove_json_suggestion.rs b/gcc/testsuite/rust/rustc/ui/lint/unused_parens_remove_json_suggestion.rs new file mode 100644 index 000000000000..3185d7375393 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/unused_parens_remove_json_suggestion.rs @@ -0,0 +1,62 @@ +// compile-flags: --error-format json -Zunstable-options +// run-rustfix + +// The output for humans should just highlight the whole span without showing +// the suggested replacement, but we also want to test that suggested +// replacement only removes one set of parentheses, rather than naïvely +// stripping away any starting or ending parenthesis characters—hence this +// test of the JSON error format. + +#![deny(unused_parens)] +#![allow(unreachable_code)] + +fn main() { + + let _b = false; + + if (_b) { // { dg-error "" "" { target *-*-* } } + println!("hello"); + } + + f(); + +} + +fn f() -> bool { + let c = false; + + if(c) { // { dg-error "" "" { target *-*-* } } + println!("next"); + } + + if (c){ // { dg-error "" "" { target *-*-* } } + println!("prev"); + } + + while (false && true){ + if (c) { // { dg-error "" "" { target *-*-* } } + println!("norm"); + } + + } + + while(true && false) { // { dg-error "" "" { target *-*-* } } + for _ in (0 .. 3){ // { dg-error "" "" { target *-*-* } } + println!("e~") + } + } + + for _ in (0 .. 3) { // { dg-error "" "" { target *-*-* } } + while (true && false) { // { dg-error "" "" { target *-*-* } } + println!("e~") + } + } + + + loop { + if (break { return true }) { + } + } + false +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/use-redundant.rs b/gcc/testsuite/rust/rustc/ui/lint/use-redundant.rs new file mode 100644 index 000000000000..92db6fb32804 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/use-redundant.rs @@ -0,0 +1,28 @@ +// check-pass +#![warn(unused_imports)] + +use crate::foo::Bar; + +mod foo { + pub type Bar = i32; +} + +fn baz() -> Bar { + 3 +} + +mod m1 { pub struct S {} } +mod m2 { pub struct S {} } + +use m1::*; // { dg-warning "" "" { target *-*-* } } +use m2::*; // { dg-warning "" "" { target *-*-* } } + +fn main() { + use crate::foo::Bar; // { dg-warning "" "" { target *-*-* } } + let _a: Bar = 3; + baz(); + + use m1::S; + let _s = S {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/use_suggestion_json.rs b/gcc/testsuite/rust/rustc/ui/lint/use_suggestion_json.rs new file mode 100644 index 000000000000..406e56c7f1c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/use_suggestion_json.rs @@ -0,0 +1,15 @@ +// ignore-cloudabi +// ignore-windows +// ignore-sgx std::os::fortanix_sgx::usercalls::alloc::Iter changes compiler suggestions +// compile-flags: --error-format pretty-json --json=diagnostic-rendered-ansi + +// The output for humans should just highlight the whole span without showing +// the suggested replacement, but we also want to test that suggested +// replacement only removes one set of parentheses, rather than naïvely +// stripping away any starting or ending parenthesis characters—hence this +// test of the JSON error format. + +fn main() { + let x: Iter; +} + diff --git a/gcc/testsuite/rust/rustc/ui/lint/warn-unused-inline-on-fn-prototypes.rs b/gcc/testsuite/rust/rustc/ui/lint/warn-unused-inline-on-fn-prototypes.rs new file mode 100644 index 000000000000..9028510595a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lint/warn-unused-inline-on-fn-prototypes.rs @@ -0,0 +1,14 @@ +#![deny(unused_attributes)] + +trait Trait { + #[inline] // { dg-error "" "" { target *-*-* } } + fn foo(); +} + +extern { + #[inline] // { dg-error "" "" { target *-*-* } } + fn foo(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/list.rs b/gcc/testsuite/rust/rustc/ui/list.rs new file mode 100644 index 000000000000..c9286f415279 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/list.rs @@ -0,0 +1,11 @@ +// run-pass + +#![allow(non_camel_case_types)] +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +enum list { cons(isize, Box), nil, } + +pub fn main() { list::cons(10, box list::cons(11, box list::cons(12, box list::nil))); } + diff --git a/gcc/testsuite/rust/rustc/ui/liveness-assign-imm-local-after-ret.rs b/gcc/testsuite/rust/rustc/ui/liveness-assign-imm-local-after-ret.rs new file mode 100644 index 000000000000..8bbafaabdfdf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness-assign-imm-local-after-ret.rs @@ -0,0 +1,17 @@ +// run-pass + +#![allow(unreachable_code)] +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +fn test() { + let _v: isize; + _v = 1; + return; + _v = 2; +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-asm.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-asm.rs new file mode 100644 index 000000000000..bb6b3a1436d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-asm.rs @@ -0,0 +1,45 @@ +// Ensure inout asm! operands are marked as used by the liveness pass + +// only-x86_64 +// check-pass + +#![feature(asm)] +#![allow(dead_code)] +#![warn(unused_assignments)] +#![warn(unused_variables)] + +// Test the single inout case +unsafe fn f1(mut src: *const u8) { + asm!("/*{0}*/", inout(reg) src); // { dg-warning "" "" { target *-*-* } } +} + +unsafe fn f2(mut src: *const u8) -> *const u8 { + asm!("/*{0}*/", inout(reg) src); + src +} + +// Test the split inout case +unsafe fn f3(mut src: *const u8) { + asm!("/*{0}*/", inout(reg) src => src); // { dg-warning "" "" { target *-*-* } } +} + +unsafe fn f4(mut src: *const u8) -> *const u8 { + asm!("/*{0}*/", inout(reg) src => src); + src +} + +// Tests the use of field projections +struct S { + field: *mut u8, +} + +unsafe fn f5(src: &mut S) { + asm!("/*{0}*/", inout(reg) src.field); +} + +unsafe fn f6(src: &mut S) { + asm!("/*{0}*/", inout(reg) src.field => src.field); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs new file mode 100644 index 000000000000..635caad4d5d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs @@ -0,0 +1,13 @@ +fn test() { + let v: isize; +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + loop { + v = 1; // { dg-error ".E0384." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs new file mode 100644 index 000000000000..e043bdd4c415 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs @@ -0,0 +1,13 @@ +fn test() { + let v: isize; +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + v = 2; // { dg-note "" "" { target *-*-* } } + v += 1; // { dg-error ".E0384." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } + v.clone(); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs new file mode 100644 index 000000000000..20104075cbbd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs @@ -0,0 +1,13 @@ +fn test() { + let b = Box::new(1); // { dg-note "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + drop(b); + b = Box::new(2); // { dg-error ".E0384." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } + drop(b); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs new file mode 100644 index 000000000000..61eb2bd550d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs @@ -0,0 +1,13 @@ +fn test() { + let v: isize = 1; // { dg-note "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + v.clone(); + v = 2; // { dg-error ".E0384." "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } + v.clone(); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-closure-require-ret.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-closure-require-ret.rs new file mode 100644 index 000000000000..71472e3c0a79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-closure-require-ret.rs @@ -0,0 +1,3 @@ +fn force(f: F) -> isize where F: FnOnce() -> isize { f() } +fn main() { println!("{}", force(|| {})); } // { dg-error ".E0308." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-consts.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-consts.rs new file mode 100644 index 000000000000..d6726a0d5058 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-consts.rs @@ -0,0 +1,64 @@ +// check-pass +#![warn(unused)] +#![allow(unreachable_code)] + +pub static A: i32 = { + let mut i = 0; + let mut a = 0; // { dg-warning "" "" { target *-*-* } } + while i < 10 { + i += 1; + a += 1; + } + i +}; + +pub const B: u32 = { + let mut b = 1; + b += 1; // { dg-warning "" "" { target *-*-* } } + b = 42; + b +}; + +pub enum E { + V1 = { + let e = 1; // { dg-warning "" "" { target *-*-* } } + 1 + }, + V2 = { + let _f = 10; + 2 + } +} + +pub fn f(x: [u8; { let s = 17; 100 }]) -> [u8; { let z = 18; 100 }] { +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + x +} + +pub trait T { + const T: usize = { + let mut t = 10; + t = t + t; // { dg-warning "" "" { target *-*-* } } + 20 + }; +} + +impl T for String { + const T: usize = { + let w = 10; // { dg-warning "" "" { target *-*-* } } + loop { + break; + let _ = w; + } + 44 + }; +} + +fn main() { + let _ = [(); { + let z = 42; // { dg-warning "" "" { target *-*-* } } + 35 + }]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-dead.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-dead.rs new file mode 100644 index 000000000000..12638c331d5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-dead.rs @@ -0,0 +1,40 @@ +#![allow(dead_code)] +#![deny(unused_assignments)] + +fn f1(x: &mut isize) { + *x = 1; // no error +} + +fn f2() { + let mut x: isize = 3; // { dg-error "" "" { target *-*-* } } + x = 4; + x.clone(); +} + +fn f3() { + let mut x: isize = 3; + x.clone(); + x = 4; // { dg-error "" "" { target *-*-* } } +} + +fn f4(mut x: i32) { // { dg-error "" "" { target *-*-* } } + x = 4; + x.clone(); +} + +fn f5(mut x: i32) { + x.clone(); + x = 4; // { dg-error "" "" { target *-*-* } } +} + +// #22630 +fn f6() { + let mut done = false; + while !done { + done = true; // no error + continue; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-derive.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-derive.rs new file mode 100644 index 000000000000..83f7d5040494 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-derive.rs @@ -0,0 +1,39 @@ +// Test for interaction between #[automatically_derived] attribute used by +// built-in derives and lints generated by liveness pass. +// +// edition:2018 +// check-pass +#![warn(unused)] + +pub trait T: Sized { + const N: usize; + fn t(&self) -> Self; +} + +impl T for u32 { + const N: usize = { + let a = 0; // { dg-warning "" "" { target *-*-* } } + 4 + }; + + fn t(&self) -> Self { + let b = 16; // { dg-warning "" "" { target *-*-* } } + 0 + } +} + +#[automatically_derived] +impl T for i32 { + const N: usize = { + let c = 0; + 4 + }; + + fn t(&self) -> Self { + let d = 17; + 0 + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-forgot-ret.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-forgot-ret.rs new file mode 100644 index 000000000000..2b562a603071 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-forgot-ret.rs @@ -0,0 +1,7 @@ +fn god_exists(a: isize) -> bool { return god_exists(a); } + +fn f(a: isize) -> isize { if god_exists(a) { return 5; }; } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + +fn main() { f(12); } + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-issue-2163.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-issue-2163.rs new file mode 100644 index 000000000000..d41a882a8119 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-issue-2163.rs @@ -0,0 +1,9 @@ +use std::vec::Vec; + +fn main() { + let a: Vec = Vec::new(); + a.iter().all(|_| -> bool { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-missing-ret2.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-missing-ret2.rs new file mode 100644 index 000000000000..9c7dd32d242a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-missing-ret2.rs @@ -0,0 +1,8 @@ +fn f() -> isize { // { dg-error ".E0308." "" { target *-*-* } } + // Make sure typestate doesn't interpret this match expression as + // the function result + match true { true => { } _ => {} }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-move-call-arg.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-move-call-arg.rs new file mode 100644 index 000000000000..01b27bf00921 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-move-call-arg.rs @@ -0,0 +1,12 @@ +#![feature(box_syntax)] + +fn take(_x: Box) {} + +fn main() { + + let x: Box = box 25; + loop { + take(x); // { dg-error ".E0382." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-move-in-loop.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-move-in-loop.rs new file mode 100644 index 000000000000..1914e06b0d16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-move-in-loop.rs @@ -0,0 +1,18 @@ +#![feature(box_syntax)] + +fn main() { + let y: Box = box 42; + let mut x: Box; + loop { + println!("{}", y); + loop { + loop { + loop { + x = y; // { dg-error ".E0382." "" { target *-*-* } } + x.clone(); + } + } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-move-in-while.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-move-in-while.rs new file mode 100644 index 000000000000..66ac7244500c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-move-in-while.rs @@ -0,0 +1,14 @@ +#![feature(box_syntax)] + +fn main() { + let y: Box = box 42; + let mut x: Box; + loop { + println!("{}", y); // { dg-error ".E0382." "" { target *-*-* } } + while true { while true { while true { x = y; x.clone(); } } } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-return-last-stmt-semi.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-return-last-stmt-semi.rs new file mode 100644 index 000000000000..08c27df22f16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-return-last-stmt-semi.rs @@ -0,0 +1,20 @@ +// +// regression test for #8005 + +macro_rules! test { () => { fn foo() -> i32 { 1; } } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + +fn no_return() -> i32 {} // { dg-error ".E0308." "" { target *-*-* } } + +fn bar(x: u32) -> u32 { // { dg-error ".E0308." "" { target *-*-* } } + x * 2; +} + +fn baz(x: u64) -> u32 { // { dg-error ".E0308." "" { target *-*-* } } + x * 2; +} + +fn main() { + test!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-unused.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-unused.rs new file mode 100644 index 000000000000..3180df8d9515 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-unused.rs @@ -0,0 +1,142 @@ +#![warn(unused)] +#![deny(unused_variables)] +#![deny(unused_assignments)] +#![allow(dead_code, non_camel_case_types, trivial_numeric_casts)] + +use std::ops::AddAssign; + +fn f1(x: isize) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn f1b(x: &mut isize) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[allow(unused_variables)] +fn f1c(x: isize) {} + +fn f1d() { + let x: isize; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn f2() { + let x = 3; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn f3() { + let mut x = 3; +// { dg-error "" "" { target *-*-* } .-1 } + x += 4; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn f3b() { + let mut z = 3; +// { dg-error "" "" { target *-*-* } .-1 } + loop { + z += 4; + } +} + +#[allow(unused_variables)] +fn f3c() { + let mut z = 3; + loop { z += 4; } +} + +#[allow(unused_variables)] +#[allow(unused_assignments)] +fn f3d() { + let mut x = 3; + x += 4; +} + +fn f4() { + match Some(3) { + Some(i) => { +// { dg-error "" "" { target *-*-* } .-1 } + } + None => {} + } +} + +enum tri { + a(isize), b(isize), c(isize) +} + +fn f4b() -> isize { + match tri::a(3) { + tri::a(i) | tri::b(i) | tri::c(i) => { + i + } + } +} + +fn f5a() { + for x in 1..10 { } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn f5b() { + for (x, _) in [1, 2, 3].iter().enumerate() { } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn f5c() { + for (_, x) in [1, 2, 3].iter().enumerate() { +// { dg-error "" "" { target *-*-* } .-1 } + continue; + drop(*x as i32); // { dg-warning "" "" { target *-*-* } } + } +} + +struct View<'a>(&'a mut [i32]); + +impl<'a> AddAssign for View<'a> { + fn add_assign(&mut self, rhs: i32) { + for lhs in self.0.iter_mut() { + *lhs += rhs; + } + } +} + +fn f6() { + let mut array = [1, 2, 3]; + let mut v = View(&mut array); + + // ensure an error shows up for x even if lhs of an overloaded add assign + + let x; +// { dg-error "" "" { target *-*-* } .-1 } + + *({ + x = 0; // { dg-error "" "" { target *-*-* } } + &mut v + }) += 1; +} + + +struct MutRef<'a>(&'a mut i32); + +impl<'a> AddAssign for MutRef<'a> { + fn add_assign(&mut self, rhs: i32) { + *self.0 += rhs; + } +} + +fn f7() { + let mut a = 1; + { + // `b` does not trigger unused_variables + let mut b = MutRef(&mut a); + b += 1; + } + drop(a); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-upvars.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-upvars.rs new file mode 100644 index 000000000000..5c30aed658a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-upvars.rs @@ -0,0 +1,109 @@ +// edition:2018 +// check-pass +#![warn(unused)] +#![allow(unreachable_code)] + +pub fn unintentional_copy_one() { + let mut last = None; + let mut f = move |s| { + last = Some(s); // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + }; + f("a"); + f("b"); + f("c"); + dbg!(last.unwrap()); +} + +pub fn unintentional_copy_two() { + let mut sum = 0; + (1..10).for_each(move |x| { + sum += x; // { dg-warning "" "" { target *-*-* } } + }); + dbg!(sum); +} + +pub fn f() { + let mut c = 0; + + // Captured by value, but variable is dead on entry. + let _ = move || { + c = 1; // { dg-warning "" "" { target *-*-* } } + println!("{}", c); + }; + let _ = async move { + c = 1; // { dg-warning "" "" { target *-*-* } } + println!("{}", c); + }; + + // Read and written to, but never actually used. + let _ = move || { + c += 1; // { dg-warning "" "" { target *-*-* } } + }; + let _ = async move { + c += 1; // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + }; + + let _ = move || { + println!("{}", c); + // Value is read by closure itself on later invocations. + c += 1; + }; + let b = Box::new(42); + let _ = move || { + println!("{}", c); + // Never read because this is FnOnce closure. + c += 1; // { dg-warning "" "" { target *-*-* } } + drop(b); + }; + let _ = async move { + println!("{}", c); + // Never read because this is a generator. + c += 1; // { dg-warning "" "" { target *-*-* } } + }; +} + +pub fn nested() { + let mut d = None; + let mut e = None; + let _ = || { + let _ = || { + d = Some("d1"); // { dg-warning "" "" { target *-*-* } } + d = Some("d2"); + }; + let _ = move || { + e = Some("e1"); // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + e = Some("e2"); // { dg-warning "" "" { target *-*-* } } + }; + }; +} + +pub fn g(mut v: T) { + let _ = |r| { + if r { + v = T::default(); // { dg-warning "" "" { target *-*-* } } + } else { + drop(v); + } + }; +} + +pub fn h() { + let mut z = T::default(); + let _ = move |b| { + loop { + if b { + z = T::default(); // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + } else { + return; + } + } + dbg!(z); + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-use-after-move.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-use-after-move.rs new file mode 100644 index 000000000000..610df63a2589 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-use-after-move.rs @@ -0,0 +1,9 @@ +#![feature(box_syntax)] + +fn main() { + let x: Box<_> = box 5; + let y = x; + println!("{}", *x); // { dg-error ".E0382." "" { target *-*-* } } + y.clone(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/liveness/liveness-use-after-send.rs b/gcc/testsuite/rust/rustc/ui/liveness/liveness-use-after-send.rs new file mode 100644 index 000000000000..4b5213fb2df6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/liveness/liveness-use-after-send.rs @@ -0,0 +1,20 @@ +use std::marker; + +fn send(ch: Chan, data: T) { + println!("{:?}", ch); + println!("{:?}", data); + panic!(); +} + +#[derive(Debug)] +struct Chan(isize, marker::PhantomData); + +// Tests that "log(debug, message);" is flagged as using +// message after the send deinitializes it +fn test00_start(ch: Chan>, message: Box, _count: Box) { + send(ch, message); + println!("{}", message); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() { panic!(); } + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/issue-51431.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/issue-51431.rs new file mode 100644 index 000000000000..e1926d1f6c85 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/issue-51431.rs @@ -0,0 +1,12 @@ +// build-fail +// ignore-emscripten no llvm_asm! support + +#![feature(llvm_asm)] + +fn main() { + unsafe { + llvm_asm! {"mov $0,$1"::"0"("bx"),"1"(0x00)} +// { dg-error ".E0669." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/issue-54067.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/issue-54067.rs new file mode 100644 index 000000000000..6f1557a4c5ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/issue-54067.rs @@ -0,0 +1,13 @@ +// check-pass +// ignore-emscripten no llvm_asm! support + +#![feature(llvm_asm)] + +pub fn boot(addr: Option) { + unsafe { + llvm_asm!("mov sp, $0"::"r" (addr)); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/issue-62046.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/issue-62046.rs new file mode 100644 index 000000000000..715c50c97d22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/issue-62046.rs @@ -0,0 +1,12 @@ +// build-fail +// ignore-emscripten no asm! support + +#![feature(llvm_asm)] + +fn main() { + unsafe { + llvm_asm!("nop" : "+r"("r15")); +// { dg-error ".E0668." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/issue-69092.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/issue-69092.rs new file mode 100644 index 000000000000..e9b3a2f54d30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/issue-69092.rs @@ -0,0 +1,11 @@ +// build-fail +// ignore-emscripten no asm! support +// Regression test for #69092 + +#![feature(llvm_asm)] + +fn main() { + unsafe { llvm_asm!(".ascii \"Xen\0\""); } +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-bad-clobber.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-bad-clobber.rs new file mode 100644 index 000000000000..93d05c883368 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-bad-clobber.rs @@ -0,0 +1,27 @@ +// ignore-android +// ignore-arm +// ignore-aarch64 +// ignore-s390x +// ignore-emscripten +// ignore-powerpc +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-riscv64 +// ignore-sparc +// ignore-sparc64 +// ignore-mips +// ignore-mips64 + +#![feature(llvm_asm)] + +#[cfg(any(target_arch = "x86", + target_arch = "x86_64"))] + +pub fn main() { + unsafe { + // clobber formatted as register input/output + llvm_asm!("xor %eax, %eax" : : : "{eax}"); +// { dg-error ".E0664." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-concat-src.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-concat-src.rs new file mode 100644 index 000000000000..e180b0e87318 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-concat-src.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 +// ignore-emscripten no asm + +#![feature(llvm_asm)] + +pub fn main() { + unsafe { llvm_asm!(concat!("", "")) }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-in-bad-modifier.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-in-bad-modifier.rs new file mode 100644 index 000000000000..a5cb434f0acc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-in-bad-modifier.rs @@ -0,0 +1,36 @@ +// ignore-s390x +// ignore-emscripten +// ignore-powerpc +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-riscv64 +// ignore-sparc +// ignore-sparc64 +// ignore-mips +// ignore-mips64 + +#![feature(llvm_asm)] + +fn foo(x: isize) { println!("{}", x); } + +#[cfg(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64"))] +pub fn main() { + let x: isize; + let y: isize; + unsafe { + llvm_asm!("mov $1, $0" : "=r"(x) : "=r"(5)); // { dg-error ".E0662." "" { target *-*-* } } + llvm_asm!("mov $1, $0" : "=r"(y) : "+r"(5)); // { dg-error ".E0663." "" { target *-*-* } } + } + foo(x); + foo(y); +} + +#[cfg(not(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64")))] +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-in-moved.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-in-moved.rs new file mode 100644 index 000000000000..bbcb5ff95343 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-in-moved.rs @@ -0,0 +1,32 @@ +// run-pass + +#![feature(llvm_asm)] +#![allow(dead_code)] + +use std::cell::Cell; + +#[repr(C)] +struct NoisyDrop<'a>(&'a Cell<&'static str>); +impl<'a> Drop for NoisyDrop<'a> { + fn drop(&mut self) { + self.0.set("destroyed"); + } +} + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +fn main() { + let status = Cell::new("alive"); + { + let _y: Box; + let x = Box::new(NoisyDrop(&status)); + unsafe { + llvm_asm!("mov $1, $0" : "=r"(_y) : "r"(x)); + } + assert_eq!(status.get(), "alive"); + } + assert_eq!(status.get(), "destroyed"); +} + +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-in-out-operand.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-in-out-operand.rs new file mode 100644 index 000000000000..f14730acc88e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-in-out-operand.rs @@ -0,0 +1,57 @@ +// run-pass + +#![feature(llvm_asm)] + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +unsafe fn next_power_of_2(n: u32) -> u32 { + let mut tmp = n; + llvm_asm!("dec $0" : "+rm"(tmp) :: "cc"); + let mut shift = 1_u32; + while shift <= 16 { + llvm_asm!( + "shr %cl, $2 + or $2, $0 + shl $$1, $1" + : "+&rm"(tmp), "+{ecx}"(shift) : "r"(tmp) : "cc" + ); + } + llvm_asm!("inc $0" : "+rm"(tmp) :: "cc"); + return tmp; +} + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +pub fn main() { + unsafe { + assert_eq!(64, next_power_of_2(37)); + assert_eq!(2147483648, next_power_of_2(2147483647)); + } + + let mut y: isize = 5; + let x: isize; + unsafe { + // Treat the output as initialization. + llvm_asm!( + "shl $2, $1 + add $3, $1 + mov $1, $0" + : "=r"(x), "+r"(y) : "i"(3_usize), "ir"(7_usize) : "cc" + ); + } + assert_eq!(x, 47); + assert_eq!(y, 47); + + let mut x = x + 1; + assert_eq!(x, 48); + + unsafe { + // Assignment to mutable. + // Early clobber "&": + // Forbids the use of a single register by both operands. + llvm_asm!("shr $$2, $1; add $1, $0" : "+&r"(x) : "r"(x) : "cc"); + } + assert_eq!(x, 60); +} + +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-indirect-memory.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-indirect-memory.rs new file mode 100644 index 000000000000..4d666b56716a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-indirect-memory.rs @@ -0,0 +1,44 @@ +// run-pass + +#![feature(llvm_asm)] + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +fn read(ptr: &u32) -> u32 { + let out: u32; + unsafe { + llvm_asm!("mov $1, $0" : "=r" (out) : "*m" (ptr)); + } + out +} + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +fn write(ptr: &mut u32, val: u32) { + unsafe { + llvm_asm!("mov $1, $0" : "=*m" (ptr) : "r" (val)); + } +} + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +fn replace(ptr: &mut u32, val: u32) -> u32 { + let out: u32; + unsafe { + llvm_asm!("mov $0, $1; mov $2, $0" : "+*m" (ptr), "=&r" (out) : "r" (val)); + } + out +} + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +pub fn main() { + let a = 1; + assert_eq!(read(&a), 1); + let mut b = 2; + write(&mut b, 3); + assert_eq!(b, 3); + let mut c = 4; + assert_eq!(replace(&mut c, 5), 4); + assert_eq!(c, 5); +} + +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-literal-escaping.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-literal-escaping.rs new file mode 100644 index 000000000000..eb42865929db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-literal-escaping.rs @@ -0,0 +1,13 @@ +// build-pass +// only-x86_64 + +#![feature(llvm_asm)] + +fn main() { + unsafe { + // "nop" :: "r"(x) : "eax" : "volatile" + let x = 10; + llvm_asm!("\x6Eop" :: "\x72"(x) : "\x65ax" : "\x76olatile"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-misplaced-option.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-misplaced-option.rs new file mode 100644 index 000000000000..7fd179995fd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-misplaced-option.rs @@ -0,0 +1,37 @@ +// check-pass +// ignore-android +// ignore-arm +// ignore-aarch64 +// ignore-s390x +// ignore-emscripten +// ignore-powerpc +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-riscv64 +// ignore-sparc +// ignore-sparc64 +// ignore-mips +// ignore-mips64 + +#![feature(llvm_asm)] + +#[cfg(any(target_arch = "x86", + target_arch = "x86_64"))] +fn main() { + // assignment not dead + let mut x: isize = 0; + unsafe { + // extra colon + llvm_asm!("mov $1, $0" : "=r"(x) : "r"(5_usize), "0"(x) : : "cc"); +// { dg-warning "" "" { target *-*-* } .-1 } + } + assert_eq!(x, 5); + + unsafe { + // comma in place of a colon + llvm_asm!("add $2, $1; mov $1, $0" : "=r"(x) : "r"(x), "r"(8_usize) : "cc", "volatile"); +// { dg-warning "" "" { target *-*-* } .-1 } + } + assert_eq!(x, 13); +} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-assign-imm.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-assign-imm.rs new file mode 100644 index 000000000000..c78e0b925a5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-assign-imm.rs @@ -0,0 +1,36 @@ +// ignore-s390x +// ignore-emscripten +// ignore-powerpc +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-riscv64 +// ignore-sparc +// ignore-sparc64 +// ignore-mips +// ignore-mips64 + +#![feature(llvm_asm)] + +fn foo(x: isize) { println!("{}", x); } + +#[cfg(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64"))] +pub fn main() { + let x: isize; + x = 1; + foo(x); + unsafe { + llvm_asm!("mov $1, $0" : "=r"(x) : "r"(5)); +// { dg-error ".E0384." "" { target *-*-* } .-1 } + } + foo(x); +} + +#[cfg(not(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64")))] +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-assign.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-assign.rs new file mode 100644 index 000000000000..9766e2cba117 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-assign.rs @@ -0,0 +1,26 @@ +// run-pass + +#![feature(llvm_asm)] + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +pub fn main() { + let x: isize; + unsafe { + // Treat the output as initialization. + llvm_asm!("mov $1, $0" : "=r"(x) : "r"(5_usize)); + } + assert_eq!(x, 5); + + let mut x = x + 1; + assert_eq!(x, 6); + + unsafe { + // Assignment to mutable. + llvm_asm!("mov $1, $0" : "=r"(x) : "r"(x + 7)); + } + assert_eq!(x, 13); +} + +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-no-modifier.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-no-modifier.rs new file mode 100644 index 000000000000..f0d6c318f9ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-no-modifier.rs @@ -0,0 +1,33 @@ +// ignore-s390x +// ignore-emscripten +// ignore-powerpc +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-riscv64 +// ignore-sparc +// ignore-sparc64 +// ignore-mips +// ignore-mips64 + +#![feature(llvm_asm)] + +fn foo(x: isize) { println!("{}", x); } + +#[cfg(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64"))] +pub fn main() { + let x: isize; + unsafe { + llvm_asm!("mov $1, $0" : "r"(x) : "r"(5)); // { dg-error ".E0661." "" { target *-*-* } } + } + foo(x); +} + +#[cfg(not(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64")))] +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-read-uninit.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-read-uninit.rs new file mode 100644 index 000000000000..6462a5b0705a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-out-read-uninit.rs @@ -0,0 +1,34 @@ +// ignore-s390x +// ignore-emscripten +// ignore-powerpc +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-riscv64 +// ignore-sparc +// ignore-sparc64 +// ignore-mips +// ignore-mips64 + +#![feature(llvm_asm)] + +fn foo(x: isize) { println!("{}", x); } + +#[cfg(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64"))] +pub fn main() { + let x: isize; + unsafe { + llvm_asm!("mov $1, $0" : "=r"(x) : "r"(x)); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + } + foo(x); +} + +#[cfg(not(any(target_arch = "x86", + target_arch = "x86_64", + target_arch = "arm", + target_arch = "aarch64")))] +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-parse-errors.rs b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-parse-errors.rs new file mode 100644 index 000000000000..1e09e01a286b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-asm/llvm-asm-parse-errors.rs @@ -0,0 +1,16 @@ +#![feature(llvm_asm)] + +fn main() { + llvm_asm!(); // { dg-error "" "" { target *-*-* } } + llvm_asm!("nop" : struct); // { dg-error "" "" { target *-*-* } } + llvm_asm!("mov %eax, $$0x2" : struct); // { dg-error "" "" { target *-*-* } } + llvm_asm!("mov %eax, $$0x2" : "={eax}" struct); // { dg-error "" "" { target *-*-* } } + llvm_asm!("mov %eax, $$0x2" : "={eax}"(struct)); // { dg-error "" "" { target *-*-* } } + llvm_asm!("in %dx, %al" : "={al}"(result) : struct); // { dg-error "" "" { target *-*-* } } + llvm_asm!("in %dx, %al" : "={al}"(result) : "{dx}" struct); // { dg-error "" "" { target *-*-* } } + llvm_asm!("in %dx, %al" : "={al}"(result) : "{dx}"(struct)); // { dg-error "" "" { target *-*-* } } + llvm_asm!("mov $$0x200, %eax" : : : struct); // { dg-error "" "" { target *-*-* } } + llvm_asm!("mov eax, 2" : "={eax}"(foo) : : : struct); // { dg-error "" "" { target *-*-* } } + llvm_asm!(123); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/llvm-pr32379.rs b/gcc/testsuite/rust/rustc/ui/llvm-pr32379.rs new file mode 100644 index 000000000000..19ba3db61dc9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/llvm-pr32379.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:llvm_pr32379.rs + +// LLVM PR #32379 (https://bugs.llvm.org/show_bug.cgi?id=32379), which +// applies to upstream LLVM 3.9.1, is known to cause rustc itself to be +// miscompiled on ARM (Rust issue #40593). Because cross builds don't test +// our *compiler* on ARM, have a test for the miscompilation directly. + +extern crate llvm_pr32379; + +pub fn main() { + let val = llvm_pr32379::pr32379(2, false, false); + assert_eq!(val, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/log-err-phi.rs b/gcc/testsuite/rust/rustc/ui/log-err-phi.rs new file mode 100644 index 000000000000..9846e93caabf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/log-err-phi.rs @@ -0,0 +1,8 @@ +// run-pass + +pub fn main() { + if false { + println!("{}", "foobar"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/log-knows-the-names-of-variants-in-std.rs b/gcc/testsuite/rust/rustc/ui/log-knows-the-names-of-variants-in-std.rs new file mode 100644 index 000000000000..bfcff56bf137 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/log-knows-the-names-of-variants-in-std.rs @@ -0,0 +1,28 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +#[derive(Clone, Debug)] +enum foo { + a(usize), + b(String), +} + +fn check_log(exp: String, v: T) { + assert_eq!(exp, format!("{:?}", v)); +} + +pub fn main() { + let mut x = Some(foo::a(22)); + let exp = "Some(a(22))".to_string(); + let act = format!("{:?}", x); + assert_eq!(act, exp); + check_log(exp, x); + + x = None; + let exp = "None".to_string(); + let act = format!("{:?}", x); + assert_eq!(act, exp); + check_log(exp, x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/log-knows-the-names-of-variants.rs b/gcc/testsuite/rust/rustc/ui/log-knows-the-names-of-variants.rs new file mode 100644 index 000000000000..0f10c0e07198 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/log-knows-the-names-of-variants.rs @@ -0,0 +1,22 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +#[derive(Debug)] +enum foo { + a(usize), + b(String), + c, +} + +#[derive(Debug)] +enum bar { + d, e, f +} + +pub fn main() { + assert_eq!("a(22)".to_string(), format!("{:?}", foo::a(22))); + assert_eq!("c".to_string(), format!("{:?}", foo::c)); + assert_eq!("d".to_string(), format!("{:?}", bar::d)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/log-poly.rs b/gcc/testsuite/rust/rustc/ui/log-poly.rs new file mode 100644 index 000000000000..90d4f8ce38f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/log-poly.rs @@ -0,0 +1,14 @@ +// run-pass + +#[derive(Debug)] +enum Numbers { + Three +} + +pub fn main() { + println!("{:?}", 1); + println!("{:?}", 2.0f64); + println!("{:?}", Numbers::Three); + println!("{:?}", vec![4]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/logging-only-prints-once.rs b/gcc/testsuite/rust/rustc/ui/logging-only-prints-once.rs new file mode 100644 index 000000000000..e90d3fcb6245 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/logging-only-prints-once.rs @@ -0,0 +1,31 @@ +// run-pass +// ignore-windows +// ignore-emscripten no threads support + +use std::cell::Cell; +use std::fmt; +use std::thread; + +struct Foo(Cell); + +impl fmt::Debug for Foo { + fn fmt(&self, _fmt: &mut fmt::Formatter) -> fmt::Result { + let Foo(ref f) = *self; + assert_eq!(f.get(), 0); + f.set(1); + Ok(()) + } +} + +pub fn main() { + thread::spawn(move || { + let mut f = Foo(Cell::new(0)); + println!("{:?}", f); + let Foo(ref mut f) = f; + assert_eq!(f.get(), 1); + }) + .join() + .ok() + .unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/long-while.rs b/gcc/testsuite/rust/rustc/ui/long-while.rs new file mode 100644 index 000000000000..9e6c25885615 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/long-while.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![allow(unused_variables)] + +pub fn main() { + let mut i: isize = 0; + while i < 1000000 { + i += 1; + let x = 3; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/loops/for-each-loop-panic.rs b/gcc/testsuite/rust/rustc/ui/loops/for-each-loop-panic.rs new file mode 100644 index 000000000000..71dd4be0ec09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/loops/for-each-loop-panic.rs @@ -0,0 +1,10 @@ +// run-fail +// error-pattern:moop +// ignore-emscripten no processes + +fn main() { + for _ in 0_usize..10_usize { + panic!("moop"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/loops/loop-break-unsize.rs b/gcc/testsuite/rust/rustc/ui/loops/loop-break-unsize.rs new file mode 100644 index 000000000000..ec5060290fa2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/loops/loop-break-unsize.rs @@ -0,0 +1,9 @@ +// Regression test for #62312 +// check-pass + +fn main() { + let _ = loop { + break Box::new(()) as Box; + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/loops/loop-break-value-no-repeat.rs b/gcc/testsuite/rust/rustc/ui/loops/loop-break-value-no-repeat.rs new file mode 100644 index 000000000000..196cd44ea8e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/loops/loop-break-value-no-repeat.rs @@ -0,0 +1,15 @@ +#![allow(unused_variables)] + +use std::ptr; + +// Test that we only report **one** error here and that is that +// `break` with an expression is illegal in this context. In +// particular, we don't report any mismatched types error, which is +// besides the point. + +fn main() { + for _ in &[1,2,3] { + break 22 // { dg-error ".E0571." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/loops/loop-break-value.rs b/gcc/testsuite/rust/rustc/ui/loops/loop-break-value.rs new file mode 100644 index 000000000000..1624833aa6e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/loops/loop-break-value.rs @@ -0,0 +1,94 @@ +#![feature(never_type)] + +fn main() { + let val: ! = loop { break break; }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + loop { + if true { + break "asdf"; + } else { + break 123; // { dg-error ".E0308." "" { target *-*-* } } + } + }; + + let _: i32 = loop { + break "asdf"; // { dg-error ".E0308." "" { target *-*-* } } + }; + + let _: i32 = 'outer_loop: loop { + loop { + break 'outer_loop "nope"; // { dg-error ".E0308." "" { target *-*-* } } + break "ok"; + }; + }; + + 'while_loop: while true { // { dg-warning "" "" { target *-*-* } } + break; + break (); // { dg-error ".E0571." "" { target *-*-* } } + loop { + break 'while_loop 123; +// { dg-error ".E0571." "" { target *-*-* } .-1 } + break 456; + break 789; + }; + } + + while let Some(_) = Some(()) { + if break () { // { dg-error ".E0571." "" { target *-*-* } } + } + } + + while let Some(_) = Some(()) { + break None; +// { dg-error ".E0571." "" { target *-*-* } .-1 } + } + + 'while_let_loop: while let Some(_) = Some(()) { + loop { + break 'while_let_loop "nope"; +// { dg-error ".E0571." "" { target *-*-* } .-1 } + break 33; + }; + } + + for _ in &[1,2,3] { + break (); // { dg-error ".E0571." "" { target *-*-* } } + break [()]; +// { dg-error ".E0571." "" { target *-*-* } .-1 } + } + + 'for_loop: for _ in &[1,2,3] { + loop { + break Some(3); + break 'for_loop Some(17); +// { dg-error ".E0571." "" { target *-*-* } .-1 } + }; + } + + let _: i32 = 'a: loop { + let _: () = 'b: loop { + break ('c: loop { + break; + break 'c 123; // { dg-error ".E0308." "" { target *-*-* } } + }); + break 'a 123; + }; + }; + + loop { + break (break, break); // { dg-error ".E0308." "" { target *-*-* } } + }; + + loop { + break; + break 2; // { dg-error ".E0308." "" { target *-*-* } } + }; + + loop { + break 2; + break; // { dg-error ".E0308." "" { target *-*-* } } + break 4; + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/loops/loop-labeled-break-value.rs b/gcc/testsuite/rust/rustc/ui/loops/loop-labeled-break-value.rs new file mode 100644 index 000000000000..ce4bd5b4ed44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/loops/loop-labeled-break-value.rs @@ -0,0 +1,12 @@ +fn main() { + loop { + let _: i32 = loop { break }; // { dg-error ".E0308." "" { target *-*-* } } + } + loop { + let _: i32 = 'inner: loop { break 'inner }; // { dg-error ".E0308." "" { target *-*-* } } + } + loop { + let _: i32 = 'inner2: loop { loop { break 'inner2 } }; // { dg-error ".E0308." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/loops/loop-proper-liveness.rs b/gcc/testsuite/rust/rustc/ui/loops/loop-proper-liveness.rs new file mode 100644 index 000000000000..aa10b125a5c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/loops/loop-proper-liveness.rs @@ -0,0 +1,33 @@ +fn test1() { + // In this test the outer 'a loop may terminate without `x` getting initialised. Although the + // `x = loop { ... }` statement is reached, the value itself ends up never being computed and + // thus leaving `x` uninit. + let x: i32; + 'a: loop { + x = loop { break 'a }; + } + println!("{:?}", x); // { dg-error ".E0381." "" { target *-*-* } } +} + +// test2 and test3 should not fail. +fn test2() { + // In this test the `'a` loop will never terminate thus making the use of `x` unreachable. + let x: i32; + 'a: loop { + x = loop { continue 'a }; + } + println!("{:?}", x); +} + +fn test3() { + let x: i32; + // Similarly, the use of variable `x` is unreachable. + 'a: loop { + x = loop { return }; + } + println!("{:?}", x); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/loops/loop-properly-diverging-2.rs b/gcc/testsuite/rust/rustc/ui/loops/loop-properly-diverging-2.rs new file mode 100644 index 000000000000..407eb03c4314 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/loops/loop-properly-diverging-2.rs @@ -0,0 +1,7 @@ +fn forever2() -> i32 { + let x: i32 = loop { break }; // { dg-error ".E0308." "" { target *-*-* } } + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/loops/loops-reject-duplicate-labels-2.rs b/gcc/testsuite/rust/rustc/ui/loops/loops-reject-duplicate-labels-2.rs new file mode 100644 index 000000000000..bcea8a514ff7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/loops/loops-reject-duplicate-labels-2.rs @@ -0,0 +1,36 @@ +// check-pass + +// ignore-tidy-linelength + +// Issue #21633: reject duplicate loop labels in function bodies. +// +// This is testing the generalization (to the whole function body) +// discussed here: +// https://internals.rust-lang.org/t/psa-rejecting-duplicate-loop-labels/1833 + +#[allow(unused_labels)] +pub fn foo() { + { 'fl: for _ in 0..10 { break; } } + { 'fl: loop { break; } } // { dg-warning "" "" { target *-*-* } } + { 'lf: loop { break; } } + { 'lf: for _ in 0..10 { break; } } // { dg-warning "" "" { target *-*-* } } + { 'wl: while 2 > 1 { break; } } + { 'wl: loop { break; } } // { dg-warning "" "" { target *-*-* } } + { 'lw: loop { break; } } + { 'lw: while 2 > 1 { break; } } // { dg-warning "" "" { target *-*-* } } + { 'fw: for _ in 0..10 { break; } } + { 'fw: while 2 > 1 { break; } } // { dg-warning "" "" { target *-*-* } } + { 'wf: while 2 > 1 { break; } } + { 'wf: for _ in 0..10 { break; } } // { dg-warning "" "" { target *-*-* } } + { 'tl: while let Some(_) = None:: { break; } } + { 'tl: loop { break; } } // { dg-warning "" "" { target *-*-* } } + { 'lt: loop { break; } } + { 'lt: while let Some(_) = None:: { break; } } +// { dg-warning "" "" { target *-*-* } .-1 } +} + + +pub fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/loops/loops-reject-duplicate-labels.rs b/gcc/testsuite/rust/rustc/ui/loops/loops-reject-duplicate-labels.rs new file mode 100644 index 000000000000..e1b099b4ea8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/loops/loops-reject-duplicate-labels.rs @@ -0,0 +1,46 @@ +// check-pass + +// ignore-tidy-linelength + +// Issue #21633: reject duplicate loop labels in function bodies. +// This is testing the exact cases that are in the issue description. + +#[allow(unused_labels)] +fn foo() { + 'fl: for _ in 0..10 { break; } + 'fl: loop { break; } // { dg-warning "" "" { target *-*-* } } + + 'lf: loop { break; } + 'lf: for _ in 0..10 { break; } // { dg-warning "" "" { target *-*-* } } + 'wl: while 2 > 1 { break; } + 'wl: loop { break; } // { dg-warning "" "" { target *-*-* } } + 'lw: loop { break; } + 'lw: while 2 > 1 { break; } // { dg-warning "" "" { target *-*-* } } + 'fw: for _ in 0..10 { break; } + 'fw: while 2 > 1 { break; } // { dg-warning "" "" { target *-*-* } } + 'wf: while 2 > 1 { break; } + 'wf: for _ in 0..10 { break; } // { dg-warning "" "" { target *-*-* } } + 'tl: while let Some(_) = None:: { break; } + 'tl: loop { break; } // { dg-warning "" "" { target *-*-* } } + 'lt: loop { break; } + 'lt: while let Some(_) = None:: { break; } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +// Note however that it is okay for the same label to be reused in +// different methods of one impl, as illustrated here. + +struct S; +impl S { + fn m1(&self) { 'okay: loop { break 'okay; } } + fn m2(&self) { 'okay: loop { break 'okay; } } +} + + +pub fn main() { + let s = S; + s.m1(); + s.m2(); + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/loops/loops-reject-labels-shadowing-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/loops/loops-reject-labels-shadowing-lifetimes.rs new file mode 100644 index 000000000000..1c4afee36706 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/loops/loops-reject-labels-shadowing-lifetimes.rs @@ -0,0 +1,110 @@ +// Issue #21633: reject duplicate loop labels in function bodies. +// This is testing interaction between lifetime-params and labels. + +// check-pass + +#![allow(dead_code, unused_variables)] + +fn foo() { + fn foo<'a>() { + 'a: loop { break 'a; } +// { dg-warning "" "" { target *-*-* } .-1 } + } + + struct Struct<'b, 'c> { _f: &'b i8, _g: &'c i8 } + enum Enum<'d, 'e> { A(&'d i8), B(&'e i8) } + + impl<'d, 'e> Struct<'d, 'e> { + fn meth_okay() { + 'a: loop { break 'a; } + 'b: loop { break 'b; } + 'c: loop { break 'c; } + } + } + + impl <'d, 'e> Enum<'d, 'e> { + fn meth_okay() { + 'a: loop { break 'a; } + 'b: loop { break 'b; } + 'c: loop { break 'c; } + } + } + + impl<'bad, 'c> Struct<'bad, 'c> { + fn meth_bad(&self) { + 'bad: loop { break 'bad; } +// { dg-warning "" "" { target *-*-* } .-1 } + } + } + + impl<'b, 'bad> Struct<'b, 'bad> { + fn meth_bad2(&self) { + 'bad: loop { break 'bad; } +// { dg-warning "" "" { target *-*-* } .-1 } + } + } + + impl<'b, 'c> Struct<'b, 'c> { + fn meth_bad3<'bad>(x: &'bad i8) { + 'bad: loop { break 'bad; } +// { dg-warning "" "" { target *-*-* } .-1 } + } + + fn meth_bad4<'a,'bad>(x: &'a i8, y: &'bad i8) { + 'bad: loop { break 'bad; } +// { dg-warning "" "" { target *-*-* } .-1 } + } + } + + impl <'bad, 'e> Enum<'bad, 'e> { + fn meth_bad(&self) { + 'bad: loop { break 'bad; } +// { dg-warning "" "" { target *-*-* } .-1 } + } + } + impl <'d, 'bad> Enum<'d, 'bad> { + fn meth_bad2(&self) { + 'bad: loop { break 'bad; } +// { dg-warning "" "" { target *-*-* } .-1 } + } + } + impl <'d, 'e> Enum<'d, 'e> { + fn meth_bad3<'bad>(x: &'bad i8) { + 'bad: loop { break 'bad; } +// { dg-warning "" "" { target *-*-* } .-1 } + } + + fn meth_bad4<'a,'bad>(x: &'bad i8) { + 'bad: loop { break 'bad; } +// { dg-warning "" "" { target *-*-* } .-1 } + } + } + + trait HasDefaultMethod1<'bad> { + fn meth_okay() { + 'c: loop { break 'c; } + } + fn meth_bad(&self) { + 'bad: loop { break 'bad; } +// { dg-warning "" "" { target *-*-* } .-1 } + } + } + trait HasDefaultMethod2<'a,'bad> { + fn meth_bad(&self) { + 'bad: loop { break 'bad; } +// { dg-warning "" "" { target *-*-* } .-1 } + } + } + trait HasDefaultMethod3<'a,'b> { + fn meth_bad<'bad>(&self) { + 'bad: loop { break 'bad; } +// { dg-warning "" "" { target *-*-* } .-1 } + } + } +} + + +pub fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/loops/loops-reject-lifetime-shadowing-label.rs b/gcc/testsuite/rust/rustc/ui/loops/loops-reject-lifetime-shadowing-label.rs new file mode 100644 index 000000000000..83fcf74265ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/loops/loops-reject-lifetime-shadowing-label.rs @@ -0,0 +1,32 @@ +// check-pass + +#![allow(dead_code, unused_variables)] + +// Issue #21633: reject duplicate loop labels in function bodies. +// +// Test rejection of lifetimes in *expressions* that shadow loop labels. + +fn foo() { + // Reusing lifetime `'a` in function item is okay. + fn foo<'a>(x: &'a i8) -> i8 { *x } + + // So is reusing `'a` in struct item + struct S1<'a> { x: &'a i8 } impl<'a> S1<'a> { fn m(&self) {} } + // and a method item + struct S2; impl S2 { fn m<'a>(&self) {} } + + let z = 3_i8; + + 'a: loop { + let b = Box::new(|x: &i8| *x) as Box Fn(&'a i8) -> i8>; +// { dg-warning "" "" { target *-*-* } .-1 } + assert_eq!((*b)(&z), z); + break 'a; + } +} + + +pub fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/loud_ui.rs b/gcc/testsuite/rust/rustc/ui/loud_ui.rs new file mode 100644 index 000000000000..7f33553fe75c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/loud_ui.rs @@ -0,0 +1,7 @@ +// should-fail + +// this test ensures that when we forget to use +// any `// { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lto-and-no-bitcode-in-rlib.rs b/gcc/testsuite/rust/rustc/ui/lto-and-no-bitcode-in-rlib.rs new file mode 100644 index 000000000000..a7d89e262a64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lto-and-no-bitcode-in-rlib.rs @@ -0,0 +1,4 @@ +// compile-flags: -C lto -C embed-bitcode=no + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lto-duplicate-symbols.rs b/gcc/testsuite/rust/rustc/ui/lto-duplicate-symbols.rs new file mode 100644 index 000000000000..d37acc386e77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lto-duplicate-symbols.rs @@ -0,0 +1,12 @@ +// build-fail +// aux-build:lto-duplicate-symbols1.rs +// aux-build:lto-duplicate-symbols2.rs +// error-pattern:Linking globals named 'foo': symbol multiply defined! +// compile-flags: -C lto +// no-prefer-dynamic + +extern crate lto_duplicate_symbols1; +extern crate lto_duplicate_symbols2; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lto-many-codegen-units.rs b/gcc/testsuite/rust/rustc/ui/lto-many-codegen-units.rs new file mode 100644 index 000000000000..8a2f3e33bdce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lto-many-codegen-units.rs @@ -0,0 +1,7 @@ +// run-pass +// compile-flags: -C lto -C codegen-units=8 +// no-prefer-dynamic + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/lto-opt-level-s.rs b/gcc/testsuite/rust/rustc/ui/lto-opt-level-s.rs new file mode 100644 index 000000000000..9f9e092a07ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lto-opt-level-s.rs @@ -0,0 +1,8 @@ +// compile-flags: -Clinker-plugin-lto -Copt-level=s +// build-pass +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lto-opt-level-z.rs b/gcc/testsuite/rust/rustc/ui/lto-opt-level-z.rs new file mode 100644 index 000000000000..06177d2e8581 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lto-opt-level-z.rs @@ -0,0 +1,8 @@ +// compile-flags: -Clinker-plugin-lto -Copt-level=z +// build-pass +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lto-rustc-loads-linker-plugin.rs b/gcc/testsuite/rust/rustc/ui/lto-rustc-loads-linker-plugin.rs new file mode 100644 index 000000000000..c67be1a27069 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lto-rustc-loads-linker-plugin.rs @@ -0,0 +1,18 @@ +// compile-flags: -C lto +// aux-build:lto-rustc-loads-linker-plugin.rs +// run-pass +// no-prefer-dynamic + +// This test ensures that if a dependency was compiled with +// `-Clinker-plugin-lto` then we can compile with `-Clto` and still link against +// that upstream rlib. This should work because LTO implies we're not actually +// linking against upstream rlibs since we're generating the object code +// locally. This test will fail if rustc can't find bytecode in rlibs compiled +// with `-Clinker-plugin-lto`. + +extern crate lto_rustc_loads_linker_plugin; + +fn main() { + lto_rustc_loads_linker_plugin::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lto-still-runs-thread-dtors.rs b/gcc/testsuite/rust/rustc/ui/lto-still-runs-thread-dtors.rs new file mode 100644 index 000000000000..edceaeadb9ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lto-still-runs-thread-dtors.rs @@ -0,0 +1,33 @@ +// run-pass +// compile-flags: -C lto +// no-prefer-dynamic +// ignore-emscripten no threads support + +use std::thread; + +static mut HIT: usize = 0; + +thread_local!(static A: Foo = Foo); + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) { + unsafe { + HIT += 1; + } + } +} + +fn main() { + unsafe { + assert_eq!(HIT, 0); + thread::spawn(|| { + assert_eq!(HIT, 0); + A.with(|_| ()); + assert_eq!(HIT, 0); + }).join().unwrap(); + assert_eq!(HIT, 1); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/lto-thin-rustc-loads-linker-plugin.rs b/gcc/testsuite/rust/rustc/ui/lto-thin-rustc-loads-linker-plugin.rs new file mode 100644 index 000000000000..1bd82c8e403d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lto-thin-rustc-loads-linker-plugin.rs @@ -0,0 +1,14 @@ +// compile-flags: -C lto=thin +// aux-build:lto-rustc-loads-linker-plugin.rs +// run-pass +// no-prefer-dynamic + +// Same as the adjacent `lto-thin-rustc-loads-linker-plugin.rs` test, only with +// ThinLTO. + +extern crate lto_rustc_loads_linker_plugin; + +fn main() { + lto_rustc_loads_linker_plugin::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lub-glb-with-unbound-infer-var.rs b/gcc/testsuite/rust/rustc/ui/lub-glb-with-unbound-infer-var.rs new file mode 100644 index 000000000000..83ea6ab475f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lub-glb-with-unbound-infer-var.rs @@ -0,0 +1,16 @@ +// run-pass +// Test for a specific corner case: when we compute the LUB of two fn +// types and their parameters have unbound variables. In that case, we +// wind up relating those two variables. This was causing an ICE in an +// in-progress PR. + +fn main() { + let a_f: fn(_) = |_| (); + let b_f: fn(_) = |_| (); + let c_f = match 22 { + 0 => a_f, + _ => b_f, + }; + c_f(4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-hr-eq.rs b/gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-hr-eq.rs new file mode 100644 index 000000000000..bade671d1e13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-hr-eq.rs @@ -0,0 +1,28 @@ +// Test that we give a note when the old LUB/GLB algorithm would have +// succeeded but the new code (which requires equality) gives an +// error. However, now that we handle subtyping correctly, we no +// longer get an error, because we recognize these two types as +// equivalent! +// +// check-pass + +fn foo(x: fn(&u8, &u8), y: for<'a> fn(&'a u8, &'a u8)) { + // The two types above are actually equivalent. With the older + // leak check, though, we didn't consider them as equivalent, and + // hence we gave errors. But now we've fixed that. + let z = match 22 { + 0 => x, + _ => y, + }; +} + +fn foo_cast(x: fn(&u8, &u8), y: for<'a> fn(&'a u8, &'a u8)) { + let z = match 22 { + // No error with an explicit cast: + 0 => x as for<'a> fn(&'a u8, &'a u8), + _ => y, + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-hr-noteq1.rs b/gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-hr-noteq1.rs new file mode 100644 index 000000000000..78f9fb2baa05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-hr-noteq1.rs @@ -0,0 +1,25 @@ +// Test taking the LUB of two function types that are not equatable but where one is more +// general than the other. Test the case where the more general type (`x`) is the first +// match arm specifically. + +fn foo(x: for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8, y: for<'a> fn(&'a u8, &'a u8) -> &'a u8) { + // The two types above are not equivalent. With the older LUB/GLB + // algorithm, this may have worked (I don't remember), but now it + // doesn't because we require equality. + let z = match 22 { + 0 => x, + _ => y, // { dg-error ".E0308." "" { target *-*-* } } + }; +} + +fn foo_cast(x: for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8, y: for<'a> fn(&'a u8, &'a u8) -> &'a u8) { + // But we can *upcast* explicitly the type of `x` and figure + // things out: + let z = match 22 { + 0 => x as for<'a> fn(&'a u8, &'a u8) -> &'a u8, + _ => y, + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-hr-noteq2.rs b/gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-hr-noteq2.rs new file mode 100644 index 000000000000..b76253e48fd5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-hr-noteq2.rs @@ -0,0 +1,34 @@ +// Test taking the LUB of two function types that are not equatable but where +// one is more general than the other. Test the case where the more general type +// (`x`) is the second match arm specifically. +// +// FIXME(#73154) Skip for compare-mode because the pure NLL checker accepts this +// test. (Note that it still errors in old-lub-glb-hr-noteq1.rs). What happens +// is that, due to the ordering of the match arms, we pick the correct "more +// general" fn type, and we ignore the errors from the non-NLL type checker that +// requires equality. The NLL type checker only requires a subtyping +// relationship, and that holds. +// +// ignore-compare-mode-nll + +fn foo(x: for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8, y: for<'a> fn(&'a u8, &'a u8) -> &'a u8) { + // The two types above are not equivalent. With the older LUB/GLB + // algorithm, this may have worked (I don't remember), but now it + // doesn't because we require equality. + let z = match 22 { + 0 => y, + _ => x, // { dg-error ".E0308." "" { target *-*-* } } + }; +} + +fn foo_cast(x: for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8, y: for<'a> fn(&'a u8, &'a u8) -> &'a u8) { + // But we can *upcast* explicitly the type of `x` and figure + // things out: + let z = match 22 { + 0 => x as for<'a> fn(&'a u8, &'a u8) -> &'a u8, + _ => y, + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-object.rs b/gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-object.rs new file mode 100644 index 000000000000..29dfd5d09011 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lub-glb/old-lub-glb-object.rs @@ -0,0 +1,23 @@ +// Test that we give a note when the old LUB/GLB algorithm would have +// succeeded but the new code (which is stricter) gives an error. + +trait Foo {} + +fn foo(x: &dyn for<'a, 'b> Foo<&'a u8, &'b u8>, y: &dyn for<'a> Foo<&'a u8, &'a u8>) { + let z = match 22 { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + 0 => x, + _ => y, + }; +} + +fn bar(x: &dyn for<'a, 'b> Foo<&'a u8, &'b u8>, y: &dyn for<'a> Foo<&'a u8, &'a u8>) { + // Accepted with explicit case: + let z = match 22 { + 0 => x as &dyn for<'a> Foo<&'a u8, &'a u8>, + _ => y, + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lub-if.rs b/gcc/testsuite/rust/rustc/ui/lub-if.rs new file mode 100644 index 000000000000..12b16f794b89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lub-if.rs @@ -0,0 +1,43 @@ +// Test that we correctly consider the type of `match` to be the LUB +// of the various arms, particularly in the case where regions are +// involved. + +pub fn opt_str0<'a>(maybestr: &'a Option) -> &'a str { + if maybestr.is_none() { + "(none)" + } else { + let s: &'a str = maybestr.as_ref().unwrap(); + s + } +} + +pub fn opt_str1<'a>(maybestr: &'a Option) -> &'a str { + if maybestr.is_some() { + let s: &'a str = maybestr.as_ref().unwrap(); + s + } else { + "(none)" + } +} + +pub fn opt_str2<'a>(maybestr: &'a Option) -> &'static str { + if maybestr.is_none() { + "(none)" + } else { + let s: &'a str = maybestr.as_ref().unwrap(); + s // { dg-error ".E0312." "" { target *-*-* } } + } +} + +pub fn opt_str3<'a>(maybestr: &'a Option) -> &'static str { + if maybestr.is_some() { + let s: &'a str = maybestr.as_ref().unwrap(); + s // { dg-error ".E0312." "" { target *-*-* } } + } else { + "(none)" + } +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/lub-match.rs b/gcc/testsuite/rust/rustc/ui/lub-match.rs new file mode 100644 index 000000000000..63aef5365f3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/lub-match.rs @@ -0,0 +1,46 @@ +// Test that we correctly consider the type of `match` to be the LUB +// of the various arms, particularly in the case where regions are +// involved. + +pub fn opt_str0<'a>(maybestr: &'a Option) -> &'a str { + match *maybestr { + Some(ref s) => { + let s: &'a str = s; + s + } + None => "(none)", + } +} + +pub fn opt_str1<'a>(maybestr: &'a Option) -> &'a str { + match *maybestr { + None => "(none)", + Some(ref s) => { + let s: &'a str = s; + s + } + } +} + +pub fn opt_str2<'a>(maybestr: &'a Option) -> &'static str { + match *maybestr { + None => "(none)", + Some(ref s) => { + let s: &'a str = s; + s // { dg-error ".E0312." "" { target *-*-* } } + } + } +} + +pub fn opt_str3<'a>(maybestr: &'a Option) -> &'static str { + match *maybestr { + Some(ref s) => { + let s: &'a str = s; + s // { dg-error ".E0312." "" { target *-*-* } } + } + None => "(none)", + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macro-quote-cond.rs b/gcc/testsuite/rust/rustc/ui/macro-quote-cond.rs new file mode 100644 index 000000000000..f1d08bbbc340 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macro-quote-cond.rs @@ -0,0 +1,47 @@ +// run-pass +// aux-build:cond_plugin.rs + +#![allow(unused_parens)] + +extern crate cond_plugin; + +use cond_plugin::cond; + +fn fact(n : i64) -> i64 { + if n == 0 { + 1 + } else { + n * fact(n - 1) + } +} + +fn fact_cond(n : i64) -> i64 { + cond!( + ((n == 0) 1) + (else (n * fact_cond(n-1))) + ) +} + +fn fib(n : i64) -> i64 { + if n == 0 || n == 1 { + 1 + } else { + fib(n-1) + fib(n-2) + } +} + +fn fib_cond(n : i64) -> i64 { + cond!( + ((n == 0) 1) + ((n == 1) 1) + (else (fib_cond(n-1) + fib_cond(n-2))) + ) +} + +fn main() { + assert_eq!(fact(3), fact_cond(3)); + assert_eq!(fact(5), fact_cond(5)); + assert_eq!(fib(5), fib_cond(5)); + assert_eq!(fib(8), fib_cond(8)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macro-quote-test.rs b/gcc/testsuite/rust/rustc/ui/macro-quote-test.rs new file mode 100644 index 000000000000..66b6f9cac3d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macro-quote-test.rs @@ -0,0 +1,11 @@ +// Test that a macro can emit delimiters with nothing inside - `()`, `{}` + +// run-pass +// aux-build:hello_macro.rs + +extern crate hello_macro; + +fn main() { + hello_macro::hello!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macro_backtrace/auxiliary/ping.rs b/gcc/testsuite/rust/rustc/ui/macro_backtrace/auxiliary/ping.rs new file mode 100644 index 000000000000..efddb209cdaa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macro_backtrace/auxiliary/ping.rs @@ -0,0 +1,31 @@ +// Test that the macro backtrace facility works (supporting file) + +// a non-local macro +#[macro_export] +macro_rules! ping { + () => { + pong!(); + } +} + +#[macro_export] +macro_rules! deep { + () => { + foo!(); + } +} + +#[macro_export] +macro_rules! foo { + () => { + bar!(); + } +} + +#[macro_export] +macro_rules! bar { + () => { + ping!(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macro_backtrace/main.rs b/gcc/testsuite/rust/rustc/ui/macro_backtrace/main.rs new file mode 100644 index 000000000000..514f20569799 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macro_backtrace/main.rs @@ -0,0 +1,24 @@ +// Test that the macro backtrace facility works +// aux-build:ping.rs +// revisions: default -Zmacro-backtrace +//[-Zmacro-backtrace] compile-flags: -Z macro-backtrace + +#[macro_use] extern crate ping; + +// a local macro +macro_rules! pong { + () => { syntax error }; +} +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + +#[allow(non_camel_case_types)] +struct syntax; + +fn main() { + pong!(); + ping!(); + deep!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/ambiguity-legacy-vs-modern.rs b/gcc/testsuite/rust/rustc/ui/macros/ambiguity-legacy-vs-modern.rs new file mode 100644 index 000000000000..6badf06c69c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/ambiguity-legacy-vs-modern.rs @@ -0,0 +1,47 @@ +// Some non-controversial subset of ambiguities "modern macro name" vs "macro_rules" +// is disambiguated to mitigate regressions from macro modularization. +// Scoping for `macro_rules` behaves like scoping for `let` at module level, in general. + +#![feature(decl_macro)] + +fn same_unnamed_mod() { + macro m() { 0 } + + macro_rules! m { () => (()) } + + m!() // OK +} + +fn nested_unnamed_mod() { + macro m() { 0 } + + { + macro_rules! m { () => (()) } + + m!() // OK + } +} + +fn nested_unnamed_mod_fail() { + macro_rules! m { () => (()) } + + { + macro m() { 0 } + + m!() // { dg-error ".E0659." "" { target *-*-* } } + } +} + +fn nexted_named_mod_fail() { + macro m() { 0 } + + #[macro_use] + mod inner { + macro_rules! m { () => (()) } + } + + m!() // { dg-error ".E0659." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert-as-macro.rs b/gcc/testsuite/rust/rustc/ui/macros/assert-as-macro.rs new file mode 100644 index 000000000000..fc9abebe20e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert-as-macro.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:assertion failed: 1 == 2 +// ignore-emscripten no processes + +fn main() { + assert!(1 == 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert-eq-macro-panic.rs b/gcc/testsuite/rust/rustc/ui/macros/assert-eq-macro-panic.rs new file mode 100644 index 000000000000..948fd78bc2df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert-eq-macro-panic.rs @@ -0,0 +1,10 @@ +// run-fail +// error-pattern:assertion failed: `(left == right)` +// error-pattern: left: `14` +// error-pattern:right: `15` +// ignore-emscripten no processes + +fn main() { + assert_eq!(14, 15); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert-eq-macro-success.rs b/gcc/testsuite/rust/rustc/ui/macros/assert-eq-macro-success.rs new file mode 100644 index 000000000000..4d5c9c98772c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert-eq-macro-success.rs @@ -0,0 +1,14 @@ +// run-pass +#[derive(PartialEq, Debug)] +struct Point { x : isize } + +pub fn main() { + assert_eq!(14,14); + assert_eq!("abc".to_string(),"abc".to_string()); + assert_eq!(Box::new(Point{x:34}),Box::new(Point{x:34})); + assert_eq!(&Point{x:34},&Point{x:34}); + assert_eq!(42, 42, "foo bar"); + assert_eq!(42, 42, "a {} c", "b"); + assert_eq!(42, 42, "{x}, {y}, {z}", x = 1, y = 2, z = 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert-eq-macro-unsized.rs b/gcc/testsuite/rust/rustc/ui/macros/assert-eq-macro-unsized.rs new file mode 100644 index 000000000000..d8027d64e5cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert-eq-macro-unsized.rs @@ -0,0 +1,5 @@ +// run-pass +pub fn main() { + assert_eq!([1, 2, 3][..], vec![1, 2, 3][..]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert-macro-explicit.rs b/gcc/testsuite/rust/rustc/ui/macros/assert-macro-explicit.rs new file mode 100644 index 000000000000..61ac6488d58b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert-macro-explicit.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:panicked at 'assertion failed: false' +// ignore-emscripten no processes + +fn main() { + assert!(false); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert-macro-fmt.rs b/gcc/testsuite/rust/rustc/ui/macros/assert-macro-fmt.rs new file mode 100644 index 000000000000..071e1811d43d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert-macro-fmt.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:panicked at 'test-assert-fmt 42 rust' +// ignore-emscripten no processes + +fn main() { + assert!(false, "test-assert-fmt {} {}", 42, "rust"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert-macro-owned.rs b/gcc/testsuite/rust/rustc/ui/macros/assert-macro-owned.rs new file mode 100644 index 000000000000..b9eeef3503f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert-macro-owned.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:panicked at 'test-assert-owned' +// ignore-emscripten no processes + +fn main() { + assert!(false, "test-assert-owned".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert-macro-static.rs b/gcc/testsuite/rust/rustc/ui/macros/assert-macro-static.rs new file mode 100644 index 000000000000..0e062cdacc22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert-macro-static.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:panicked at 'test-assert-static' +// ignore-emscripten no processes + +fn main() { + assert!(false, "test-assert-static"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert-ne-macro-panic.rs b/gcc/testsuite/rust/rustc/ui/macros/assert-ne-macro-panic.rs new file mode 100644 index 000000000000..8fa8fd5a6c2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert-ne-macro-panic.rs @@ -0,0 +1,10 @@ +// run-fail +// error-pattern:assertion failed: `(left != right)` +// error-pattern: left: `14` +// error-pattern:right: `14` +// ignore-emscripten no processes + +fn main() { + assert_ne!(14, 14); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert-ne-macro-success.rs b/gcc/testsuite/rust/rustc/ui/macros/assert-ne-macro-success.rs new file mode 100644 index 000000000000..07481f67b4ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert-ne-macro-success.rs @@ -0,0 +1,14 @@ +// run-pass +#[derive(PartialEq, Debug)] +struct Point { x : isize } + +pub fn main() { + assert_ne!(666,14); + assert_ne!("666".to_string(),"abc".to_string()); + assert_ne!(Box::new(Point{x:666}),Box::new(Point{x:34})); + assert_ne!(&Point{x:666},&Point{x:34}); + assert_ne!(666, 42, "no gods no masters"); + assert_ne!(666, 42, "6 {} 6", "6"); + assert_ne!(666, 42, "{x}, {y}, {z}", x = 6, y = 6, z = 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert-ne-macro-unsized.rs b/gcc/testsuite/rust/rustc/ui/macros/assert-ne-macro-unsized.rs new file mode 100644 index 000000000000..304a8f2c496f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert-ne-macro-unsized.rs @@ -0,0 +1,5 @@ +// run-pass +pub fn main() { + assert_ne!([6, 6, 6][..], vec![1, 2, 3][..]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert-trailing-junk.rs b/gcc/testsuite/rust/rustc/ui/macros/assert-trailing-junk.rs new file mode 100644 index 000000000000..b20d193f3780 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert-trailing-junk.rs @@ -0,0 +1,25 @@ +// Ensure assert macro does not ignore trailing garbage. +// +// See https://github.com/rust-lang/rust/issues/60024 for details. + +fn main() { + assert!(true some extra junk, "whatever"); +// { dg-error "" "" { target *-*-* } .-1 } + + assert!(true some extra junk); +// { dg-error "" "" { target *-*-* } .-1 } + + assert!(true, "whatever" blah); +// { dg-error "" "" { target *-*-* } .-1 } + + assert!(true "whatever" blah); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + assert!(true;); +// { dg-error "" "" { target *-*-* } .-1 } + + assert!(false || true "error message"); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/assert.rs b/gcc/testsuite/rust/rustc/ui/macros/assert.rs new file mode 100644 index 000000000000..a51d1274bcd8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/assert.rs @@ -0,0 +1,7 @@ +fn main() { + assert!(); // { dg-error "" "" { target *-*-* } } + assert!(struct); // { dg-error "" "" { target *-*-* } } + debug_assert!(); // { dg-error "" "" { target *-*-* } } + debug_assert!(struct); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/deprecated-macros.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/deprecated-macros.rs new file mode 100644 index 000000000000..166543289f46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/deprecated-macros.rs @@ -0,0 +1,4 @@ +#[deprecated(since = "1.0.0", note = "deprecation note")] +#[macro_export] +macro_rules! deprecated_macro{ () => () } + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/dollar-crate-nested-encoding.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/dollar-crate-nested-encoding.rs new file mode 100644 index 000000000000..4290fdd6de40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/dollar-crate-nested-encoding.rs @@ -0,0 +1,11 @@ +pub type S = u8; + +macro_rules! generate_exported { () => { + #[macro_export] + macro_rules! exported { + () => ($crate::S) + } +}} + +generate_exported!(); + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/issue-75982.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/issue-75982.rs new file mode 100644 index 000000000000..720b7f1c4dff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/issue-75982.rs @@ -0,0 +1,13 @@ +const _: () = { + #[macro_export] + macro_rules! first_macro { + () => {} + } + mod foo { + #[macro_export] + macro_rules! second_macro { + () => {} + } + } +}; + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-comma-support.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-comma-support.rs new file mode 100644 index 000000000000..e08132948c51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-comma-support.rs @@ -0,0 +1,2 @@ +() + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-in-other-crate.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-in-other-crate.rs new file mode 100644 index 000000000000..c1c47dc9f4fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-in-other-crate.rs @@ -0,0 +1,15 @@ +#[macro_export] +macro_rules! mac { + ($ident:ident) => { let $ident = 42; } +} + +#[macro_export] +macro_rules! inline { + () => () +} + +#[macro_export] +macro_rules! from_prelude { + () => () +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-include-items-expr.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-include-items-expr.rs new file mode 100644 index 000000000000..20a65bddf561 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-include-items-expr.rs @@ -0,0 +1,4 @@ +// ignore-test: this is not a test + +1 + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-include-items-item.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-include-items-item.rs new file mode 100644 index 000000000000..8e4feec9ddf9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro-include-items-item.rs @@ -0,0 +1,4 @@ +// ignore-test: this is not a test + +fn foo() { bar() } + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_crate_def_only.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_crate_def_only.rs new file mode 100644 index 000000000000..5fe8097824f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_crate_def_only.rs @@ -0,0 +1,5 @@ +#[macro_export] +macro_rules! make_a_5 { + () => (5) +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_crate_nonterminal.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_crate_nonterminal.rs new file mode 100644 index 000000000000..b98acc97b3d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_crate_nonterminal.rs @@ -0,0 +1,13 @@ +pub fn increment(x: usize) -> usize { + x + 1 +} + +#[macro_export] +macro_rules! increment { + ($x:expr) => ($crate::increment($x)) +} + +pub fn check_local() { + assert_eq!(increment!(3), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_export_inner_module.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_export_inner_module.rs new file mode 100644 index 000000000000..af600479e1ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_export_inner_module.rs @@ -0,0 +1,7 @@ +pub mod inner { + #[macro_export] + macro_rules! foo { + () => (1) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_with_super_1.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_with_super_1.rs new file mode 100644 index 000000000000..3c562de004bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/macro_with_super_1.rs @@ -0,0 +1,17 @@ +#![crate_type = "lib"] + +#[macro_export] +macro_rules! declare { + () => ( + pub fn aaa() {} + + pub mod bbb { + use super::aaa; + + pub fn ccc() { + aaa(); + } + } + ) +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/proc_macro_sequence.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/proc_macro_sequence.rs new file mode 100644 index 000000000000..f51199da2909 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/proc_macro_sequence.rs @@ -0,0 +1,47 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_span, proc_macro_quote)] + +extern crate proc_macro; + +use proc_macro::{quote, Span, TokenStream, TokenTree}; + +fn assert_same_span(a: Span, b: Span) { + assert_eq!(a.start(), b.start()); + assert_eq!(a.end(), b.end()); +} + +// This macro generates a macro with the same macro definition as `manual_foo` in +// `same-sequence-span.rs` but with the same span for all sequences. +#[proc_macro] +pub fn make_foo(_: TokenStream) -> TokenStream { + let result = quote! { + macro_rules! generated_foo { + (1 $$x:expr $$($$y:tt,)* $$(= $$z:tt)*) => {}; + } + }; + + // Check that all spans are equal. + // FIXME: `quote!` gives def-site spans to idents and literals, + // but leaves (default) call-site spans on groups and punctuation. + let mut span_call = None; + let mut span_def = None; + for tt in result.clone() { + match tt { + TokenTree::Ident(..) | TokenTree::Literal(..) => match span_def { + None => span_def = Some(tt.span()), + Some(span) => assert_same_span(tt.span(), span), + } + TokenTree::Punct(..) | TokenTree::Group(..) => match span_call { + None => span_call = Some(tt.span()), + Some(span) => assert_same_span(tt.span(), span), + } + } + + } + + result +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/two_macros-rpass.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/two_macros-rpass.rs new file mode 100644 index 000000000000..12f9c116da5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/two_macros-rpass.rs @@ -0,0 +1,6 @@ +#[macro_export] +macro_rules! macro_one { ($($t:tt)*) => ($($t)*) } + +#[macro_export] +macro_rules! macro_two { ($($t:tt)*) => ($($t)*) } + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/two_macros.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/two_macros.rs new file mode 100644 index 000000000000..b97cc55cabc3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/two_macros.rs @@ -0,0 +1,6 @@ +#[macro_export] +macro_rules! macro_one { () => ("one") } + +#[macro_export] +macro_rules! macro_two { () => ("two") } + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/unstable-macros.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/unstable-macros.rs new file mode 100644 index 000000000000..a45bd85c4356 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/unstable-macros.rs @@ -0,0 +1,17 @@ +#![feature(decl_macro)] +#![feature(staged_api)] +#![stable(feature = "unit_test", since = "1.0.0")] + +#[unstable(feature = "unstable_macros", issue = "none")] +#[macro_export] +macro_rules! unstable_macro{ () => () } + +#[stable(feature = "deprecated_macros", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "deprecation reason")] +#[macro_export] +macro_rules! deprecated_macro{ () => () } + +// FIXME: Cannot use a `pub` macro 2.0 in a staged API crate due to reachability issues. +// #[unstable(feature = "unstable_macros", issue = "none")] +// pub macro unstable_macro_modern() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/auxiliary/use-macro-self.rs b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/use-macro-self.rs new file mode 100644 index 000000000000..3c4af89614ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/auxiliary/use-macro-self.rs @@ -0,0 +1,7 @@ +pub mod foobarius {} + +#[macro_export] +macro_rules! foobarius { + () => { () } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/bad-concat.rs b/gcc/testsuite/rust/rustc/ui/macros/bad-concat.rs new file mode 100644 index 000000000000..f6ce38dd083d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/bad-concat.rs @@ -0,0 +1,9 @@ +fn main() { + let x: u32 = 42; + let y: f64 = 3.14; + let z = "foo"; + let _ = concat!(x, y, z, "bar"); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/bad_hello.rs b/gcc/testsuite/rust/rustc/ui/macros/bad_hello.rs new file mode 100644 index 000000000000..8d87c5f52226 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/bad_hello.rs @@ -0,0 +1,7 @@ +fn main() { + println!(3 + 4); +// { dg-error "" "" { target *-*-* } .-1 } + println!(3, 4); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/builtin-prelude-no-accidents.rs b/gcc/testsuite/rust/rustc/ui/macros/builtin-prelude-no-accidents.rs new file mode 100644 index 000000000000..7d3d1d51ad9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/builtin-prelude-no-accidents.rs @@ -0,0 +1,9 @@ +// Names of public modules in libstd and libcore don't accidentally get into prelude +// because macros with the same names are in prelude. + +fn main() { + env::current_dir; // { dg-error ".E0433." "" { target *-*-* } } + type A = panic::PanicInfo; // { dg-error ".E0433." "" { target *-*-* } } + type B = vec::Vec; // { dg-error ".E0433." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/builtin-std-paths-fail.rs b/gcc/testsuite/rust/rustc/ui/macros/builtin-std-paths-fail.rs new file mode 100644 index 000000000000..91ce1078ffd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/builtin-std-paths-fail.rs @@ -0,0 +1,26 @@ +#[derive( + core::RustcDecodable, // { dg-error ".E0433." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + core::RustcDecodable, // { dg-error ".E0433." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +)] +#[core::bench] // { dg-error ".E0433." "" { target *-*-* } } +#[core::global_allocator] // { dg-error ".E0433." "" { target *-*-* } } +#[core::test_case] // { dg-error ".E0433." "" { target *-*-* } } +#[core::test] // { dg-error ".E0433." "" { target *-*-* } } +struct Core; + +#[derive( + std::RustcDecodable, // { dg-error ".E0433." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + std::RustcDecodable, // { dg-error ".E0433." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +)] +#[std::bench] // { dg-error ".E0433." "" { target *-*-* } } +#[std::global_allocator] // { dg-error ".E0433." "" { target *-*-* } } +#[std::test_case] // { dg-error ".E0433." "" { target *-*-* } } +#[std::test] // { dg-error ".E0433." "" { target *-*-* } } +struct Std; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/builtin-std-paths.rs b/gcc/testsuite/rust/rustc/ui/macros/builtin-std-paths.rs new file mode 100644 index 000000000000..c17d82885ec4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/builtin-std-paths.rs @@ -0,0 +1,33 @@ +// check-pass + +#[derive( + core::clone::Clone, + core::marker::Copy, + core::fmt::Debug, + core::default::Default, + core::cmp::Eq, + core::hash::Hash, + core::cmp::Ord, + core::cmp::PartialEq, + core::cmp::PartialOrd, +)] +struct Core; + +#[derive( + std::clone::Clone, + std::marker::Copy, + std::fmt::Debug, + std::default::Default, + std::cmp::Eq, + std::hash::Hash, + std::cmp::Ord, + std::cmp::PartialEq, + std::cmp::PartialOrd, +)] +struct Std; + +fn main() { + core::column!(); + std::column!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/cfg.rs b/gcc/testsuite/rust/rustc/ui/macros/cfg.rs new file mode 100644 index 000000000000..8abde69c750d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/cfg.rs @@ -0,0 +1,6 @@ +fn main() { + cfg!(); // { dg-error "" "" { target *-*-* } } + cfg!(123); // { dg-error "" "" { target *-*-* } } + cfg!(foo = 123); // { dg-error ".E0565." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/colorful-write-macros.rs b/gcc/testsuite/rust/rustc/ui/macros/colorful-write-macros.rs new file mode 100644 index 000000000000..6758870d4b74 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/colorful-write-macros.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(dead_code)] +use std::io::Write; +use std::fmt; + +struct Foo<'a> { + writer: &'a mut (dyn Write+'a), + other: &'a str, +} + +struct Bar; + +impl fmt::Write for Bar { + fn write_str(&mut self, _: &str) -> fmt::Result { + Ok(()) + } +} + +fn borrowing_writer_from_struct_and_formatting_struct_field(foo: Foo) { + write!(foo.writer, "{}", foo.other).unwrap(); +} + +fn main() { + let mut w = Vec::new(); + write!(&mut w as &mut dyn Write, "").unwrap(); + write!(&mut w, "").unwrap(); // should coerce + println!("ok"); + + let mut s = Bar; + { + use std::fmt::Write; + write!(&mut s, "test").unwrap(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/conditional-debug-macro-on.rs b/gcc/testsuite/rust/rustc/ui/macros/conditional-debug-macro-on.rs new file mode 100644 index 000000000000..57b3760822cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/conditional-debug-macro-on.rs @@ -0,0 +1,9 @@ +// run-pass +pub fn main() { + // exits early if println! evaluates its arguments, otherwise it + // will hit the panic. + println!("{:?}", { if true { return; } }); + + panic!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/derive-in-eager-expansion-hang.rs b/gcc/testsuite/rust/rustc/ui/macros/derive-in-eager-expansion-hang.rs new file mode 100644 index 000000000000..d59c33d82462 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/derive-in-eager-expansion-hang.rs @@ -0,0 +1,15 @@ +// Regression test for the issue #44692 + +macro_rules! hang { () => { + { // { dg-error "" "" { target *-*-* } } + #[derive(Clone)] + struct S; + + "" + } +}} + +fn main() { + format_args!(hang!()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/die-macro-2.rs b/gcc/testsuite/rust/rustc/ui/macros/die-macro-2.rs new file mode 100644 index 000000000000..dc9d3e475c94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/die-macro-2.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:test +// ignore-emscripten no processes + +fn main() { + panic!("test"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/die-macro-expr.rs b/gcc/testsuite/rust/rustc/ui/macros/die-macro-expr.rs new file mode 100644 index 000000000000..71c31e4fc062 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/die-macro-expr.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:test +// ignore-emscripten no processes + +fn main() { + let __isize: isize = panic!("test"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/die-macro-pure.rs b/gcc/testsuite/rust/rustc/ui/macros/die-macro-pure.rs new file mode 100644 index 000000000000..b7631575ba3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/die-macro-pure.rs @@ -0,0 +1,12 @@ +// run-fail +// error-pattern:test +// ignore-emscripten no processes + +fn f() { + panic!("test"); +} + +fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/die-macro.rs b/gcc/testsuite/rust/rustc/ui/macros/die-macro.rs new file mode 100644 index 000000000000..d5248ac1e49d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/die-macro.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] +// Just testing that panic!() type checks in statement or expr + + +#![allow(unreachable_code)] + +fn f() { + panic!(); + + let _x: isize = panic!(); +} + +pub fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/doc-comment.rs b/gcc/testsuite/rust/rustc/ui/macros/doc-comment.rs new file mode 100644 index 000000000000..463122dbc427 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/doc-comment.rs @@ -0,0 +1,26 @@ +// check-pass +// Tests that we properly handle a nested macro expansion +// involving a `#[doc]` attribute +#![deny(missing_docs)] +//! Crate docs + +macro_rules! doc_comment { + ($x:expr, $($tt:tt)*) => { + #[doc = $x] + $($tt)* + } +} + +macro_rules! make_comment { + () => { + doc_comment!("Function docs", + pub fn bar() {} + ); + } +} + + +make_comment!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/dollar-crate-nested-encoding.rs b/gcc/testsuite/rust/rustc/ui/macros/dollar-crate-nested-encoding.rs new file mode 100644 index 000000000000..9951629e19ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/dollar-crate-nested-encoding.rs @@ -0,0 +1,9 @@ +// check-pass +// aux-build:dollar-crate-nested-encoding.rs + +extern crate dollar_crate_nested_encoding; + +type A = dollar_crate_nested_encoding::exported!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/duplicate-builtin.rs b/gcc/testsuite/rust/rustc/ui/macros/duplicate-builtin.rs new file mode 100644 index 000000000000..3aed254fd7ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/duplicate-builtin.rs @@ -0,0 +1,18 @@ +// compile-flags:--crate-type lib +#![feature(decl_macro)] +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +pub macro test($item:item) { +// { dg-note "" "" { target *-*-* } .-1 } + /* compiler built-in */ +} + +mod inner { + #[rustc_builtin_macro] + pub macro test($item:item) { +// { dg-error ".E0773." "" { target *-*-* } .-1 } + /* compiler built-in */ + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/empty-trailing-stmt.rs b/gcc/testsuite/rust/rustc/ui/macros/empty-trailing-stmt.rs new file mode 100644 index 000000000000..bb18c8e23343 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/empty-trailing-stmt.rs @@ -0,0 +1,11 @@ +macro_rules! empty { + () => { } +} + +fn foo() -> bool { // { dg-error ".E0308." "" { target *-*-* } } + { true } // { dg-error ".E0308." "" { target *-*-* } } + empty!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/format-foreign.rs b/gcc/testsuite/rust/rustc/ui/macros/format-foreign.rs new file mode 100644 index 000000000000..dd51f77be5c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/format-foreign.rs @@ -0,0 +1,18 @@ +fn main() { + println!("%.*3$s %s!\n", "Hello,", "World", 4); // { dg-error "" "" { target *-*-* } } + println!("%1$*2$.*3$f", 123.456); // { dg-error "" "" { target *-*-* } } + println!(r###"%.*3$s + %s!\n +"###, "Hello,", "World", 4); +// { dg-error "" "" { target *-*-* } .-1 } + // correctly account for raw strings in inline suggestions + + // This should *not* produce hints, on the basis that there's equally as + // many "correct" format specifiers. It's *probably* just an actual typo. + println!("{} %f", "one", 2.0); // { dg-error "" "" { target *-*-* } } + + println!("Hi there, $NAME.", NAME="Tim"); // { dg-error "" "" { target *-*-* } } + println!("$1 $0 $$ $NAME", 1, 2, NAME=3); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/format-parse-errors.rs b/gcc/testsuite/rust/rustc/ui/macros/format-parse-errors.rs new file mode 100644 index 000000000000..45a9227e8659 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/format-parse-errors.rs @@ -0,0 +1,18 @@ +fn main() { + let foo = ""; + let bar = ""; + format!(); // { dg-error "" "" { target *-*-* } } + format!(struct); // { dg-error "" "" { target *-*-* } } + format!("s", name =); // { dg-error "" "" { target *-*-* } } + format!( + "s {foo} {} {}", + foo = foo, + bar, // { dg-error "" "" { target *-*-* } } + ); + format!("s {foo}", foo = struct); // { dg-error "" "" { target *-*-* } } + format!("s", struct); // { dg-error "" "" { target *-*-* } } + + // This error should come after parsing errors to ensure they are non-fatal. + format!(123); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/format-unused-lables.rs b/gcc/testsuite/rust/rustc/ui/macros/format-unused-lables.rs new file mode 100644 index 000000000000..4ae0594e663a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/format-unused-lables.rs @@ -0,0 +1,19 @@ +fn main() { + println!("Test", 123, 456, 789); +// { dg-error "" "" { target *-*-* } .-1 } + + println!("Test2", + 123, // { dg-error "" "" { target *-*-* } } + 456, + 789 + ); + + println!("Some stuff", UNUSED="args"); // { dg-error "" "" { target *-*-* } } + + println!("Some more $STUFF", + "woo!", // { dg-error "" "" { target *-*-* } } + STUFF= + "things" + , UNUSED="args"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/global-asm.rs b/gcc/testsuite/rust/rustc/ui/macros/global-asm.rs new file mode 100644 index 000000000000..e40f054a6b95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/global-asm.rs @@ -0,0 +1,8 @@ +#![feature(global_asm)] + +fn main() { + global_asm!(); // { dg-error "" "" { target *-*-* } } + global_asm!(struct); // { dg-error "" "" { target *-*-* } } + global_asm!(123); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-25274.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-25274.rs new file mode 100644 index 000000000000..f2311f15d1fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-25274.rs @@ -0,0 +1,19 @@ +// run-pass + +macro_rules! test { + ( + fn fun() -> Option>; + ) => { + fn fun(x: $t) -> Option> + { Some(Box::new(x)) } + } +} + +test! { + fn fun() -> Option>; +} + +fn main() { + println!("{}", fun(0).unwrap()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-30143.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-30143.rs new file mode 100644 index 000000000000..becfad056bf7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-30143.rs @@ -0,0 +1,12 @@ +use std::fmt::Write; + +fn main() { + println!(0); +// { dg-error "" "" { target *-*-* } .-1 } + eprintln!('a'); +// { dg-error "" "" { target *-*-* } .-1 } + let mut s = String::new(); + writeln!(s, true).unwrap(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-34421-mac-expr-bad-stmt-good-add-semi.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-34421-mac-expr-bad-stmt-good-add-semi.rs new file mode 100644 index 000000000000..6968a9e4bdc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-34421-mac-expr-bad-stmt-good-add-semi.rs @@ -0,0 +1,16 @@ +macro_rules! make_item { + ($a:ident) => { + struct $a; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn a() { + make_item!(A) +} +fn b() { + make_item!(B) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-39404.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-39404.rs new file mode 100644 index 000000000000..988b964f3b56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-39404.rs @@ -0,0 +1,8 @@ +#![allow(unused)] + +macro_rules! m { ($i) => {} } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-54441.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-54441.rs new file mode 100644 index 000000000000..3ef6fd6705cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-54441.rs @@ -0,0 +1,12 @@ +macro_rules! m { + () => { + let // { dg-error "" "" { target *-*-* } } + }; +} + +extern "C" { + m!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-58490.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-58490.rs new file mode 100644 index 000000000000..244074cf0193 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-58490.rs @@ -0,0 +1,27 @@ +// Regression test for #58490 + +macro_rules! a { + ( @1 $i:item ) => { + a! { @2 $i } + }; + ( @2 $i:item ) => { + $i + }; +} +mod b { + a! { + @1 + #[macro_export] + macro_rules! b { () => () } + } + #[macro_export] + macro_rules! b { () => () } +// { dg-error ".E0428." "" { target *-*-* } .-1 } +} +mod c { + #[allow(unused_imports)] + use crate::b; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-61033-1.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-61033-1.rs new file mode 100644 index 000000000000..65d3f176091e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-61033-1.rs @@ -0,0 +1,11 @@ +// Regression test for issue #61033. + +macro_rules! test1 { + ($x:ident, $($tt:tt)*) => { $($tt)+ } // { dg-error "" "" { target *-*-* } } +} + +fn main() { + test1!(x,); + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-61033-2.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-61033-2.rs new file mode 100644 index 000000000000..9a027beb32af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-61033-2.rs @@ -0,0 +1,26 @@ +// Regression test for issue #61033. + +macro_rules! test2 { + ( + $(* $id1:ident)* + $(+ $id2:ident)* + ) => { + $( +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + $id1 + $id2 // $id1 and $id2 may repeat different numbers of times + )* + } +} + +fn main() { + test2! { + * a * b + + a + b + c + } + test2! { + * a * b + + a + b + c + d + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-61053-different-kleene.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-61053-different-kleene.rs new file mode 100644 index 000000000000..f312c45d704d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-61053-different-kleene.rs @@ -0,0 +1,31 @@ +#![deny(meta_variable_misuse)] + +macro_rules! foo { + () => {}; + ( $( $i:ident = $($j:ident),+ );* ) => { $( $( $i = $j; )* )* }; +// { dg-error "" "" { target *-*-* } .-1 } + ( $( $($j:ident),+ );* ) => { $( $( $j; )+ )+ }; // { dg-error "" "" { target *-*-* } } +} + +macro_rules! bar { + () => {}; + (test) => { + macro_rules! nested { + () => {}; + ( $( $i:ident = $($j:ident),+ );* ) => { $( $( $i = $j; )* )* }; +// { dg-error "" "" { target *-*-* } .-1 } + ( $( $($j:ident),+ );* ) => { $( $( $j; )+ )+ }; // { dg-error "" "" { target *-*-* } } + } + }; + ( $( $i:ident = $($j:ident),+ );* ) => { + $(macro_rules! $i { + () => { 0 $( + $j )* }; // { dg-error "" "" { target *-*-* } } + })* + }; +} + +fn main() { + foo!(); + bar!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-61053-duplicate-binder.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-61053-duplicate-binder.rs new file mode 100644 index 000000000000..6844ac1877b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-61053-duplicate-binder.rs @@ -0,0 +1,15 @@ +#![deny(meta_variable_misuse)] + +macro_rules! foo { + () => {}; + (error) => { + macro_rules! bar { + ($x:tt $x:tt) => { $x }; // { dg-error "" "" { target *-*-* } } + } + }; +} + +fn main() { + foo!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-61053-missing-repetition.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-61053-missing-repetition.rs new file mode 100644 index 000000000000..8ea267c4d87d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-61053-missing-repetition.rs @@ -0,0 +1,29 @@ +#![deny(meta_variable_misuse)] + +macro_rules! foo { + () => {}; + ($( $i:ident = $($j:ident),+ );*) => { $( $i = $j; )* }; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! bar { + () => {}; + (test) => { + macro_rules! nested { + () => {}; + ($( $i:ident = $($j:ident),+ );*) => { $( $i = $j; )* }; +// { dg-error "" "" { target *-*-* } .-1 } + } + }; + ( $( $i:ident = $($j:ident),+ );* ) => { + $(macro_rules! $i { + () => { $j }; // { dg-error "" "" { target *-*-* } } + })* + }; +} + +fn main() { + foo!(); + bar!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-61053-unbound.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-61053-unbound.rs new file mode 100644 index 000000000000..e7ef30c70dda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-61053-unbound.rs @@ -0,0 +1,29 @@ +#![deny(meta_variable_misuse)] + +macro_rules! foo { + () => {}; + ($( $i:ident = $($j:ident),+ );*) => { $( $( $i = $k; )+ )* }; +// { dg-error "" "" { target *-*-* } .-1 } +} + +macro_rules! bar { + () => {}; + (test) => { + macro_rules! nested { + () => {}; + ($( $i:ident = $($j:ident),+ );*) => { $( $( $i = $k; )+ )* }; +// { dg-error "" "" { target *-*-* } .-1 } + } + }; + ( $( $i:ident = $($j:ident),+ );* ) => { + $(macro_rules! $i { + () => { $( $i = $k)+ }; // { dg-error "" "" { target *-*-* } } + })* + }; +} + +fn main() { + foo!(); + bar!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-63102.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-63102.rs new file mode 100644 index 000000000000..9f2e1c5673e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-63102.rs @@ -0,0 +1,9 @@ +// check-pass + +#![feature(decl_macro)] +macro foo { + () => {}, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-68058.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-68058.rs new file mode 100644 index 000000000000..97799fa21460 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-68058.rs @@ -0,0 +1,15 @@ +// check-pass + +macro_rules! foo { + ($doc: expr) => { + fn f() { + #[doc = $doc] + () + } + }; +} + +foo!("doc"); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-68060.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-68060.rs new file mode 100644 index 000000000000..8d2714407839 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-68060.rs @@ -0,0 +1,12 @@ +fn main() { + (0..) + .map( + #[target_feature(enable = "")] +// { dg-error "" "" { target *-*-* } .-1 } + #[track_caller] + |_| (), +// { dg-note "" "" { target *-*-* } .-1 } + ) + .next(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-69838-dir/bar.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-69838-dir/bar.rs new file mode 100644 index 000000000000..41e8b26eff01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-69838-dir/bar.rs @@ -0,0 +1,4 @@ +// ignore-test -- this is an auxiliary file as part of another test. + +pub fn i_am_in_bar() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-69838-dir/included.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-69838-dir/included.rs new file mode 100644 index 000000000000..938444def1eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-69838-dir/included.rs @@ -0,0 +1,4 @@ +// ignore-test -- this is an auxiliary file as part of another test. + +pub mod bar; + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-69838-mods-relative-to-included-path.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-69838-mods-relative-to-included-path.rs new file mode 100644 index 000000000000..fd56f8fcddd5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-69838-mods-relative-to-included-path.rs @@ -0,0 +1,8 @@ +// check-pass + +include!("issue-69838-dir/included.rs"); + +fn main() { + bar::i_am_in_bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-70446.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-70446.rs new file mode 100644 index 000000000000..bc8772fa94f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-70446.rs @@ -0,0 +1,14 @@ +// check-pass + +macro_rules! foo { + ($(: $p:path)? $(: $l:lifetime)? ) => { bar! {$(: $p)? $(: $l)? } }; +} + +macro_rules! bar { + ($(: $p:path)? $(: $l:lifetime)? ) => {}; +} + +foo! {: 'a } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-75982-foreign-macro-weird-mod.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-75982-foreign-macro-weird-mod.rs new file mode 100644 index 000000000000..718d835ffd2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-75982-foreign-macro-weird-mod.rs @@ -0,0 +1,14 @@ +// aux-build:issue-75982.rs +// check-pass + +// Regression test for issue #75982 +// Tests that don't ICE when invoking a foreign macro +// that occurs inside a module with a weird parent. + +extern crate issue_75982; + +fn main() { + issue_75982::first_macro!(); + issue_75982::second_macro!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-77475.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-77475.rs new file mode 100644 index 000000000000..8757e3625088 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-77475.rs @@ -0,0 +1,11 @@ +// check-pass +// Regression test of #77475, this used to be ICE. + +#![feature(decl_macro)] + +use crate as _; + +pub macro ice(){} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-78325-inconsistent-resolution.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-78325-inconsistent-resolution.rs new file mode 100644 index 000000000000..0bc0914830b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-78325-inconsistent-resolution.rs @@ -0,0 +1,13 @@ +macro_rules! define_other_core { + ( ) => { + extern crate std as core; +// { dg-error "" "" { target *-*-* } .-1 } + }; +} + +fn main() { + core::panic!(); +} + +define_other_core!(); + diff --git a/gcc/testsuite/rust/rustc/ui/macros/issue-78892-substitution-in-statement-attr.rs b/gcc/testsuite/rust/rustc/ui/macros/issue-78892-substitution-in-statement-attr.rs new file mode 100644 index 000000000000..2b68493abe26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/issue-78892-substitution-in-statement-attr.rs @@ -0,0 +1,15 @@ +// check-pass + +// regression test for #78892 + +macro_rules! mac { + ($lint_name:ident) => {{ + #[allow($lint_name)] + let _ = (); + }}; +} + +fn main() { + mac!(dead_code) +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/local-ambiguity-multiple-parsing-options.rs b/gcc/testsuite/rust/rustc/ui/macros/local-ambiguity-multiple-parsing-options.rs new file mode 100644 index 000000000000..364e121e5bf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/local-ambiguity-multiple-parsing-options.rs @@ -0,0 +1,9 @@ +fn main() {} + +macro_rules! ambiguity { + ($($i:ident)* $j:ident) => {}; +} + +ambiguity!(error); // { dg-error "" "" { target *-*-* } } +ambiguity!(error); // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/macros/log_syntax-trace_macros-macro-locations.rs b/gcc/testsuite/rust/rustc/ui/macros/log_syntax-trace_macros-macro-locations.rs new file mode 100644 index 000000000000..f612a722224c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/log_syntax-trace_macros-macro-locations.rs @@ -0,0 +1,23 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(trace_macros, log_syntax)] + +// make sure these macros can be used as in the various places that +// macros can occur. + +// items +trace_macros!(false); +log_syntax!(); + +fn main() { + + // statements + trace_macros!(false); + log_syntax!(); + + // expressions + (trace_macros!(false), + log_syntax!()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-2.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-2.rs new file mode 100644 index 000000000000..356182254afc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-2.rs @@ -0,0 +1,13 @@ +// run-pass +pub fn main() { + + macro_rules! mylambda_tt { + ($x:ident, $body:expr) => ({ + fn f($x: isize) -> isize { return $body; }; + f + }) + } + + assert_eq!(mylambda_tt!(y, y * 2)(8), 16); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-as-fn-body.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-as-fn-body.rs new file mode 100644 index 000000000000..be17548df749 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-as-fn-body.rs @@ -0,0 +1,34 @@ +// +// run-pass +// +// Description - ensure Interpolated blocks can act as valid function bodies +// Covered cases: free functions, struct methods, and default trait functions + +macro_rules! def_fn { + ($body:block) => { + fn bar() $body + } +} + +trait Foo { + def_fn!({ println!("foo"); }); +} + +struct Baz {} + +impl Foo for Baz {} + +struct Qux {} + +impl Qux { + def_fn!({ println!("qux"); }); +} + +def_fn!({ println!("quux"); }); + +pub fn main() { + Baz::bar(); + Qux::bar(); + bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2015-rpass.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2015-rpass.rs new file mode 100644 index 000000000000..1cc17577dcdc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2015-rpass.rs @@ -0,0 +1,51 @@ +// run-pass + +#![allow(unused_mut)] + +// Check that when `?` is followed by what looks like a Kleene operator (?, +, and *) +// then that `?` is not interpreted as a separator. In other words, `$(pat)?+` matches `pat +` +// or `+` but does not match `pat` or `pat ? pat`. + +// edition:2015 + +macro_rules! foo { + // Check for `?`. + ($($a:ident)? ? $num:expr) => { + foo!($($a)? ; $num); + }; + // Check for `+`. + ($($a:ident)? + $num:expr) => { + foo!($($a)? ; $num); + }; + // Check for `*`. + ($($a:ident)? * $num:expr) => { + foo!($($a)? ; $num); + }; + // Check for `;`, not a kleene operator. + ($($a:ident)? ; $num:expr) => { + let mut x = 0; + + $( + x += $a; + )? + + assert_eq!(x, $num); + }; +} + +pub fn main() { + let a = 1; + + // Accept 0 repetitions. + foo!( ; 0); + foo!( + 0); + foo!( * 0); + foo!( ? 0); + + // Accept 1 repetition. + foo!(a ; 1); + foo!(a + 1); + foo!(a * 1); + foo!(a ? 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2015.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2015.rs new file mode 100644 index 000000000000..77e81acb0d86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2015.rs @@ -0,0 +1,43 @@ +// Tests that `?` is a Kleene op and not a macro separator in the 2015 edition. + +// edition:2015 + +macro_rules! foo { + ($(a)?) => {}; +} + +// The Kleene op `?` does not admit a separator before it. +macro_rules! baz { + ($(a),?) => {}; // { dg-error "" "" { target *-*-* } } +} + +macro_rules! barplus { + ($(a)?+) => {}; // ok. matches "a+" and "+" +} + +macro_rules! barstar { + ($(a)?*) => {}; // ok. matches "a*" and "*" +} + +pub fn main() { + foo!(); + foo!(a); + foo!(a?); // { dg-error "" "" { target *-*-* } } + foo!(a?a); // { dg-error "" "" { target *-*-* } } + foo!(a?a?a); // { dg-error "" "" { target *-*-* } } + + barplus!(); // { dg-error "" "" { target *-*-* } } + barplus!(a); // { dg-error "" "" { target *-*-* } } + barplus!(a?); // { dg-error "" "" { target *-*-* } } + barplus!(a?a); // { dg-error "" "" { target *-*-* } } + barplus!(a+); + barplus!(+); + + barstar!(); // { dg-error "" "" { target *-*-* } } + barstar!(a); // { dg-error "" "" { target *-*-* } } + barstar!(a?); // { dg-error "" "" { target *-*-* } } + barstar!(a?a); // { dg-error "" "" { target *-*-* } } + barstar!(a*); + barstar!(*); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2018-rpass.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2018-rpass.rs new file mode 100644 index 000000000000..fa8037a2252a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2018-rpass.rs @@ -0,0 +1,51 @@ +// run-pass + +#![allow(unused_mut)] + +// Check that when `?` is followed by what looks like a Kleene operator (?, +, and *) +// then that `?` is not interpreted as a separator. In other words, `$(pat)?+` matches `pat +` +// or `+` but does not match `pat` or `pat ? pat`. + +// edition:2018 + +macro_rules! foo { + // Check for `?`. + ($($a:ident)? ? $num:expr) => { + foo!($($a)? ; $num); + }; + // Check for `+`. + ($($a:ident)? + $num:expr) => { + foo!($($a)? ; $num); + }; + // Check for `*`. + ($($a:ident)? * $num:expr) => { + foo!($($a)? ; $num); + }; + // Check for `;`, not a kleene operator. + ($($a:ident)? ; $num:expr) => { + let mut x = 0; + + $( + x += $a; + )? + + assert_eq!(x, $num); + }; +} + +pub fn main() { + let a = 1; + + // Accept 0 repetitions. + foo!( ; 0); + foo!( + 0); + foo!( * 0); + foo!( ? 0); + + // Accept 1 repetition. + foo!(a ; 1); + foo!(a + 1); + foo!(a * 1); + foo!(a ? 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2018.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2018.rs new file mode 100644 index 000000000000..f3e23226201f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-at-most-once-rep-2018.rs @@ -0,0 +1,43 @@ +// Tests that `?` is a Kleene op and not a macro separator in the 2018 edition. + +// edition:2018 + +macro_rules! foo { + ($(a)?) => {}; +} + +// The Kleene op `?` does not admit a separator before it. +macro_rules! baz { + ($(a),?) => {}; // { dg-error "" "" { target *-*-* } } +} + +macro_rules! barplus { + ($(a)?+) => {}; // ok. matches "a+" and "+" +} + +macro_rules! barstar { + ($(a)?*) => {}; // ok. matches "a*" and "*" +} + +pub fn main() { + foo!(); + foo!(a); + foo!(a?); // { dg-error "" "" { target *-*-* } } + foo!(a?a); // { dg-error "" "" { target *-*-* } } + foo!(a?a?a); // { dg-error "" "" { target *-*-* } } + + barplus!(); // { dg-error "" "" { target *-*-* } } + barplus!(a); // { dg-error "" "" { target *-*-* } } + barplus!(a?); // { dg-error "" "" { target *-*-* } } + barplus!(a?a); // { dg-error "" "" { target *-*-* } } + barplus!(a+); + barplus!(+); + + barstar!(); // { dg-error "" "" { target *-*-* } } + barstar!(a); // { dg-error "" "" { target *-*-* } } + barstar!(a?); // { dg-error "" "" { target *-*-* } } + barstar!(a?a); // { dg-error "" "" { target *-*-* } } + barstar!(a*); + barstar!(*); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-attribute-expansion.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-attribute-expansion.rs new file mode 100644 index 000000000000..01c9047775b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-attribute-expansion.rs @@ -0,0 +1,17 @@ +// run-pass +macro_rules! descriptions { + ($name:ident is $desc:expr) => { + // Check that we will correctly expand attributes + #[doc = $desc] + #[allow(dead_code)] + const $name : &'static str = $desc; + } +} + +// item +descriptions! { DOG is "an animal" } +descriptions! { RUST is "a language" } + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-attribute.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-attribute.rs new file mode 100644 index 000000000000..8bd5beba3b55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-attribute.rs @@ -0,0 +1,3 @@ +#[doc = $not_there] // { dg-error "" "" { target *-*-* } } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-attributes.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-attributes.rs new file mode 100644 index 000000000000..be793a510133 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-attributes.rs @@ -0,0 +1,24 @@ +// run-pass + +macro_rules! compiles_fine { + (#[$at:meta]) => { + // test that the different types of attributes work + #[attribute] + /// Documentation! + #[$at] + + // check that the attributes are recognised by requiring this + // to be removed to avoid a compile error + #[cfg(always_remove)] + static MISTYPED: () = "foo"; + } +} + +// item +compiles_fine!(#[foo]); + +pub fn main() { + // statement + compiles_fine!(#[bar]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-backtrace-invalid-internals.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-backtrace-invalid-internals.rs new file mode 100644 index 000000000000..3e0afb99142f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-backtrace-invalid-internals.rs @@ -0,0 +1,62 @@ +// Macros in statement vs expression position handle backtraces differently. + +macro_rules! fake_method_stmt { + () => { + 1.fake() // { dg-error ".E0599." "" { target *-*-* } } + } +} + +macro_rules! fake_field_stmt { + () => { + 1.fake // { dg-error ".E0610." "" { target *-*-* } } + } +} + +macro_rules! fake_anon_field_stmt { + () => { + (1).0 // { dg-error ".E0610." "" { target *-*-* } } + } +} + +macro_rules! fake_method_expr { + () => { + 1.fake() // { dg-error ".E0599." "" { target *-*-* } } + } +} + +macro_rules! fake_field_expr { + () => { + 1.fake // { dg-error ".E0610." "" { target *-*-* } } + } +} + +macro_rules! fake_anon_field_expr { + () => { + (1).0 // { dg-error ".E0610." "" { target *-*-* } } + } +} + +macro_rules! real_method_stmt { + () => { + 2.0.neg() // { dg-error ".E0689." "" { target *-*-* } } + } +} + +macro_rules! real_method_expr { + () => { + 2.0.neg() // { dg-error ".E0689." "" { target *-*-* } } + } +} + +fn main() { + fake_method_stmt!(); + fake_field_stmt!(); + fake_anon_field_stmt!(); + real_method_stmt!(); + + let _ = fake_method_expr!(); + let _ = fake_field_expr!(); + let _ = fake_anon_field_expr!(); + let _ = real_method_expr!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-backtrace-nested.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-backtrace-nested.rs new file mode 100644 index 000000000000..8da20b9b5dd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-backtrace-nested.rs @@ -0,0 +1,21 @@ +// In expression position, but not statement position, when we expand a macro, +// we replace the span of the expanded expression with that of the call site. + +macro_rules! nested_expr { + () => (fake) // { dg-error ".E0425." "" { target *-*-* } } +// { dg-error ".E0425." "" { target *-*-* } .-1 } +} + +macro_rules! call_nested_expr { + () => (nested_expr!()) +} + +macro_rules! call_nested_expr_sum { + () => { 1 + nested_expr!(); } +} + +fn main() { + 1 + call_nested_expr!(); + call_nested_expr_sum!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-backtrace-println.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-backtrace-println.rs new file mode 100644 index 000000000000..00eb2dc6437e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-backtrace-println.rs @@ -0,0 +1,20 @@ +// The `format_args!` syntax extension issues errors before code expansion +// has completed, but we still need a backtrace. + +// This test includes stripped-down versions of `print!` and `println!`, +// because we can't otherwise verify the lines of the backtrace. + +fn print(_args: std::fmt::Arguments) {} + +macro_rules! myprint { + ($($arg:tt)*) => (print(format_args!($($arg)*))); +} + +macro_rules! myprintln { + ($fmt:expr) => (myprint!(concat!($fmt, "\n"))); // { dg-error "" "" { target *-*-* } } +} + +fn main() { + myprintln!("{}"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-block-nonterminal.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-block-nonterminal.rs new file mode 100644 index 000000000000..38dc6265e50b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-block-nonterminal.rs @@ -0,0 +1,12 @@ +// run-pass + +macro_rules! do_block{ + ($val:block) => {$val} +} + +fn main() { + let s; + do_block!({ s = "it works!"; }); + assert_eq!(s, "it works!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-comma-behavior-rpass.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-comma-behavior-rpass.rs new file mode 100644 index 000000000000..58a9a691330f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-comma-behavior-rpass.rs @@ -0,0 +1,93 @@ +// run-pass +#![allow(unused_imports)] +// Ideally, any macro call with a trailing comma should behave +// identically to a call without the comma. +// +// This checks the behavior of macros with trailing commas in key +// places where regressions in behavior seem highly possible (due +// to it being e.g., a place where the addition of an argument +// causes it to go down a code path with subtly different behavior). +// +// There is a companion test in compile-fail. + +// compile-flags: --test -C debug_assertions=yes +// revisions: std core + +// ignore-wasm32-bare compiled with panic=abort by default + +#![cfg_attr(core, no_std)] + +#[cfg(std)] use std::fmt; +#[cfg(core)] use core::fmt; + +// an easy mistake in the implementation of 'assert!' +// would cause this to say "explicit panic" +#[test] +#[should_panic(expected = "assertion failed")] +fn assert_1arg() { + assert!(false,); +} + +// same as 'assert_1arg' +#[test] +#[should_panic(expected = "assertion failed")] +fn debug_assert_1arg() { + debug_assert!(false,); +} + +// make sure we don't accidentally forward to `write!("text")` +#[cfg(std)] +#[test] +fn writeln_1arg() { + use fmt::Write; + + let mut s = String::new(); + writeln!(&mut s,).unwrap(); + assert_eq!(&s, "\n"); +} + +// A number of format_args-like macros have special-case treatment +// for a single message string, which is not formatted. +// +// This test ensures that the addition of a trailing comma does not +// suddenly cause these strings to get formatted when they otherwise +// would not be. This is an easy mistake to make by having such a macro +// accept ", $($tok:tt)*" instead of ", $($tok:tt)+" after its minimal +// set of arguments. +// +// (Example: Issue #48042) +#[test] +fn to_format_or_not_to_format() { + // ("{}" is the easiest string to test because if this gets + // sent to format_args!, it'll simply fail to compile. + // "{{}}" is an example of an input that could compile and + // produce an incorrect program, but testing the panics + // would be burdensome.) + let falsum = || false; + + assert!(true, "{}",); + + // assert_eq!(1, 1, "{}",); // see compile-fail + // assert_ne!(1, 2, "{}",); // see compile-fail + + debug_assert!(true, "{}",); + + // debug_assert_eq!(1, 1, "{}",); // see compile-fail + // debug_assert_ne!(1, 2, "{}",); // see compile-fail + // eprint!("{}",); // see compile-fail + // eprintln!("{}",); // see compile-fail + // format!("{}",); // see compile-fail + // format_args!("{}",); // see compile-fail + + if falsum() { panic!("{}",); } + + // print!("{}",); // see compile-fail + // println!("{}",); // see compile-fail + // unimplemented!("{}",); // see compile-fail + + if falsum() { unreachable!("{}",); } + + // write!(&mut stdout, "{}",); // see compile-fail + // writeln!(&mut stdout, "{}",); // see compile-fail +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-comma-behavior.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-comma-behavior.rs new file mode 100644 index 000000000000..e44e44b928e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-comma-behavior.rs @@ -0,0 +1,96 @@ +// Companion test to the similarly-named file in run-pass. + +// compile-flags: -C debug_assertions=yes +// revisions: std core + +#![feature(lang_items)] +#![cfg_attr(core, no_std)] + +#[cfg(std)] use std::fmt; +#[cfg(core)] use core::fmt; +#[cfg(core)] #[lang = "eh_personality"] fn eh_personality() {} +#[cfg(core)] #[lang = "eh_catch_typeinfo"] static EH_CATCH_TYPEINFO: u8 = 0; +#[cfg(core)] #[lang = "panic_impl"] fn panic_impl(panic: &core::panic::PanicInfo) -> ! { loop {} } + +// (see documentation of the similarly-named test in run-pass) +fn to_format_or_not_to_format() { + let falsum = || false; + + // assert!(true, "{}",); // see run-pass + + assert_eq!(1, 1, "{}",); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + assert_ne!(1, 2, "{}",); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + // debug_assert!(true, "{}",); // see run-pass + + debug_assert_eq!(1, 1, "{}",); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + debug_assert_ne!(1, 2, "{}",); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + #[cfg(std)] { + eprint!("{}",); +// { dg-error "" "" { target *-*-* } .-1 } + } + + #[cfg(std)] { + // FIXME: compile-fail says "expected error not found" even though + // rustc does emit an error + // eprintln!("{}",); + // [std]~^ ERROR no arguments + } + + #[cfg(std)] { + format!("{}",); +// { dg-error "" "" { target *-*-* } .-1 } + } + + format_args!("{}",); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + // if falsum() { panic!("{}",); } // see run-pass + + #[cfg(std)] { + print!("{}",); +// { dg-error "" "" { target *-*-* } .-1 } + } + + #[cfg(std)] { + // FIXME: compile-fail says "expected error not found" even though + // rustc does emit an error + // println!("{}",); + // [std]~^ ERROR no arguments + } + + unimplemented!("{}",); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + // if falsum() { unreachable!("{}",); } // see run-pass + + struct S; + impl fmt::Display for S { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}",)?; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + // FIXME: compile-fail says "expected error not found" even though + // rustc does emit an error + // writeln!(f, "{}",)?; + // [core]~^ ERROR no arguments + // [std]~^^ ERROR no arguments + Ok(()) + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-comma-support-rpass.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-comma-support-rpass.rs new file mode 100644 index 000000000000..e10a52ecc37b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-comma-support-rpass.rs @@ -0,0 +1,350 @@ +// run-pass +// This is meant to be a comprehensive test of invocations with/without +// trailing commas (or other, similar optionally-trailing separators). +// Every macro is accounted for, even those not tested in this file. +// (There will be a note indicating why). + +// std and core are both tested because they may contain separate +// implementations for some macro_rules! macros as an implementation +// detail. + +// ignore-pretty issue #37195 + +// compile-flags: --test -C debug_assertions=yes +// revisions: std core + +#![cfg_attr(core, no_std)] + +#![allow(deprecated)] // for deprecated `try!()` macro +#![feature(concat_idents)] + +#[cfg(std)] use std::fmt; +#[cfg(core)] use core::fmt; + +#[test] +fn assert() { + assert!(true); + assert!(true,); + assert!(true, "hello"); + assert!(true, "hello",); + assert!(true, "hello {}", "world"); + assert!(true, "hello {}", "world",); +} + +#[test] +fn assert_eq() { + assert_eq!(1, 1); + assert_eq!(1, 1,); + assert_eq!(1, 1, "hello"); + assert_eq!(1, 1, "hello",); + assert_eq!(1, 1, "hello {}", "world"); + assert_eq!(1, 1, "hello {}", "world",); +} + +#[test] +fn assert_ne() { + assert_ne!(1, 2); + assert_ne!(1, 2,); + assert_ne!(1, 2, "hello"); + assert_ne!(1, 2, "hello",); + assert_ne!(1, 2, "hello {}", "world"); + assert_ne!(1, 2, "hello {}", "world",); +} + +#[test] +fn cfg() { + let _ = cfg!(pants); + let _ = cfg!(pants,); + let _ = cfg!(pants = "pants"); + let _ = cfg!(pants = "pants",); + let _ = cfg!(all(pants)); + let _ = cfg!(all(pants),); + let _ = cfg!(all(pants,)); + let _ = cfg!(all(pants,),); +} + +#[test] +fn column() { + let _ = column!(); +} + +// compile_error! is in a companion to this test in compile-fail + +#[test] +fn concat() { + let _ = concat!(); + let _ = concat!("hello"); + let _ = concat!("hello",); + let _ = concat!("hello", " world"); + let _ = concat!("hello", " world",); +} + +#[test] +fn concat_idents() { + fn foo() {} + fn foobar() {} + + concat_idents!(foo)(); + concat_idents!(foo,)(); + concat_idents!(foo, bar)(); + concat_idents!(foo, bar,)(); +} + +#[test] +fn debug_assert() { + debug_assert!(true); + debug_assert!(true, ); + debug_assert!(true, "hello"); + debug_assert!(true, "hello",); + debug_assert!(true, "hello {}", "world"); + debug_assert!(true, "hello {}", "world",); +} + +#[test] +fn debug_assert_eq() { + debug_assert_eq!(1, 1); + debug_assert_eq!(1, 1,); + debug_assert_eq!(1, 1, "hello"); + debug_assert_eq!(1, 1, "hello",); + debug_assert_eq!(1, 1, "hello {}", "world"); + debug_assert_eq!(1, 1, "hello {}", "world",); +} + +#[test] +fn debug_assert_ne() { + debug_assert_ne!(1, 2); + debug_assert_ne!(1, 2,); + debug_assert_ne!(1, 2, "hello"); + debug_assert_ne!(1, 2, "hello",); + debug_assert_ne!(1, 2, "hello {}", "world"); + debug_assert_ne!(1, 2, "hello {}", "world",); +} + +#[test] +fn env() { + let _ = env!("PATH"); + let _ = env!("PATH",); + let _ = env!("PATH", "not found"); + let _ = env!("PATH", "not found",); +} + +#[cfg(std)] +#[test] +fn eprint() { + eprint!("hello"); + eprint!("hello",); + eprint!("hello {}", "world"); + eprint!("hello {}", "world",); +} + +#[cfg(std)] +#[test] +fn eprintln() { + eprintln!(); + eprintln!("hello"); + eprintln!("hello",); + eprintln!("hello {}", "world"); + eprintln!("hello {}", "world",); +} + +#[test] +fn file() { + let _ = file!(); +} + +#[cfg(std)] +#[test] +fn format() { + let _ = format!("hello"); + let _ = format!("hello",); + let _ = format!("hello {}", "world"); + let _ = format!("hello {}", "world",); +} + +#[test] +fn format_args() { + let _ = format_args!("hello"); + let _ = format_args!("hello",); + let _ = format_args!("hello {}", "world"); + let _ = format_args!("hello {}", "world",); +} + +#[test] +fn include() { + let _ = include!("auxiliary/macro-comma-support.rs"); + let _ = include!("auxiliary/macro-comma-support.rs",); +} + +#[test] +fn include_bytes() { + let _ = include_bytes!("auxiliary/macro-comma-support.rs"); + let _ = include_bytes!("auxiliary/macro-comma-support.rs",); +} + +#[test] +fn include_str() { + let _ = include_str!("auxiliary/macro-comma-support.rs"); + let _ = include_str!("auxiliary/macro-comma-support.rs",); +} + +#[test] +fn line() { + let _ = line!(); +} + +#[test] +fn module_path() { + let _ = module_path!(); +} + +#[test] +fn option_env() { + let _ = option_env!("PATH"); + let _ = option_env!("PATH",); +} + +#[test] +fn panic() { + // prevent 'unreachable code' warnings + let falsum = || false; + + if falsum() { panic!(); } + if falsum() { panic!("hello"); } + if falsum() { panic!("hello",); } + if falsum() { panic!("hello {}", "world"); } + if falsum() { panic!("hello {}", "world",); } +} + +#[cfg(std)] +#[test] +fn print() { + print!("hello"); + print!("hello",); + print!("hello {}", "world"); + print!("hello {}", "world",); +} + +#[cfg(std)] +#[test] +fn println() { + println!(); + println!("hello"); + println!("hello",); + println!("hello {}", "world"); + println!("hello {}", "world",); +} + +// stringify! is N/A + +#[cfg(std)] +#[test] +fn thread_local() { + // this has an optional trailing *semicolon* + thread_local! { + #[allow(unused)] pub static A: () = () + } + + thread_local! { + #[allow(unused)] pub static AA: () = (); + } + + thread_local! { + #[allow(unused)] pub static AAA: () = (); + #[allow(unused)] pub static AAAA: () = () + } + + thread_local! { + #[allow(unused)] pub static AAAAG: () = (); + #[allow(unused)] pub static AAAAGH: () = (); + } +} + +#[test] +fn try() { + fn inner() -> Result<(), ()> { + try!(Ok(())); + try!(Ok(()),); + Ok(()) + } + + inner().unwrap(); +} + +#[test] +fn unimplemented() { + // prevent 'unreachable code' warnings + let falsum = || false; + + if falsum() { unimplemented!(); } + if falsum() { unimplemented!("hello"); } + if falsum() { unimplemented!("hello",); } + if falsum() { unimplemented!("hello {}", "world"); } + if falsum() { unimplemented!("hello {}", "world",); } +} + +#[test] +fn unreachable() { + // prevent 'unreachable code' warnings + let falsum = || false; + + if falsum() { unreachable!(); } + if falsum() { unreachable!("hello"); } + if falsum() { unreachable!("hello",); } + if falsum() { unreachable!("hello {}", "world"); } + if falsum() { unreachable!("hello {}", "world",); } +} + +#[cfg(std)] +#[test] +fn vec() { + let _: Vec<()> = vec![]; + let _ = vec![0]; + let _ = vec![0,]; + let _ = vec![0, 1]; + let _ = vec![0, 1,]; +} + +// give a test body access to a fmt::Formatter, which seems +// to be the easiest way to use 'write!' on core. +macro_rules! test_with_formatter { + ( + #[test] + fn $fname:ident($f:ident: &mut fmt::Formatter) $block:block + ) => { + #[test] + fn $fname() { + struct Struct; + impl fmt::Display for Struct { + fn fmt(&self, $f: &mut fmt::Formatter) -> fmt::Result { + Ok($block) + } + } + + // suppress "unused" + assert!(true, "{}", Struct); + } + }; +} + +test_with_formatter! { + #[test] + fn write(f: &mut fmt::Formatter) { + let _ = write!(f, "hello"); + let _ = write!(f, "hello",); + let _ = write!(f, "hello {}", "world"); + let _ = write!(f, "hello {}", "world",); + } +} + +test_with_formatter! { + #[test] + fn writeln(f: &mut fmt::Formatter) { + let _ = writeln!(f); + let _ = writeln!(f,); + let _ = writeln!(f, "hello"); + let _ = writeln!(f, "hello",); + let _ = writeln!(f, "hello {}", "world"); + let _ = writeln!(f, "hello {}", "world",); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-comma-support.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-comma-support.rs new file mode 100644 index 000000000000..34bf199971db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-comma-support.rs @@ -0,0 +1,11 @@ +// This is a companion to the similarly-named test in run-pass. +// +// It tests macros that unavoidably produce compile errors. + +fn compile_error() { + compile_error!("lel"); // { dg-error "" "" { target *-*-* } } + compile_error!("lel",); // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-context.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-context.rs new file mode 100644 index 000000000000..907c168cd824 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-context.rs @@ -0,0 +1,20 @@ +// (typeof used because it's surprisingly hard to find an unparsed token after a stmt) +macro_rules! m { + () => ( i ; typeof ); // { dg-error ".E0425." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error ".E0412." "" { target *-*-* } .-5 } +// { dg-error ".E0425." "" { target *-*-* } .-6 } +} + +fn main() { + let a: m!(); + let i = m!(); + match 0 { + m!() => {} + } + + m!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-crate-def-only.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-crate-def-only.rs new file mode 100644 index 000000000000..c7a9c485926e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-crate-def-only.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:macro_crate_def_only.rs + + +#[macro_use] #[no_link] +extern crate macro_crate_def_only; + +pub fn main() { + assert_eq!(5, make_a_5!()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-crate-nonterminal-non-root.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-crate-nonterminal-non-root.rs new file mode 100644 index 000000000000..ccacab84eaba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-crate-nonterminal-non-root.rs @@ -0,0 +1,10 @@ +// aux-build:macro_crate_nonterminal.rs + +mod foo { + #[macro_use] + extern crate macro_crate_nonterminal; // { dg-error ".E0468." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-crate-nonterminal-renamed.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-crate-nonterminal-renamed.rs new file mode 100644 index 000000000000..67c21e76d452 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-crate-nonterminal-renamed.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:macro_crate_nonterminal.rs + +#[macro_use] +extern crate macro_crate_nonterminal as new_name; + +pub fn main() { + new_name::check_local(); + assert_eq!(increment!(5), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-crate-nonterminal.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-crate-nonterminal.rs new file mode 100644 index 000000000000..371522a6c8b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-crate-nonterminal.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:macro_crate_nonterminal.rs + +#[macro_use] +extern crate macro_crate_nonterminal; + +pub fn main() { + macro_crate_nonterminal::check_local(); + assert_eq!(increment!(5), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-crate-use.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-crate-use.rs new file mode 100644 index 000000000000..7f6573078839 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-crate-use.rs @@ -0,0 +1,18 @@ +// run-pass + +pub fn increment(x: usize) -> usize { + x + 1 +} + +#[macro_export] +macro_rules! increment { + ($x:expr) => ({ + use $crate::increment; + increment($x) + }) +} + +fn main() { + assert_eq!(increment!(3), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-deep_expansion.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-deep_expansion.rs new file mode 100644 index 000000000000..26e614d29e13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-deep_expansion.rs @@ -0,0 +1,18 @@ +// run-pass + +macro_rules! foo2 { + () => { + "foo" + } +} + +macro_rules! foo { + () => { + foo2!() + } +} + +fn main() { + assert_eq!(concat!(foo!(), "bar"), "foobar") +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-delimiter-significance.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-delimiter-significance.rs new file mode 100644 index 000000000000..ad296a020501 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-delimiter-significance.rs @@ -0,0 +1,5 @@ +// run-pass +fn main() { + vec![1_usize, 2, 3].len(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-deprecation.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-deprecation.rs new file mode 100644 index 000000000000..a0a781baef59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-deprecation.rs @@ -0,0 +1,14 @@ +// check-pass +// aux-build:deprecated-macros.rs + +#[macro_use] extern crate deprecated_macros; + +#[deprecated(since = "1.0.0", note = "local deprecation note")] +#[macro_export] +macro_rules! local_deprecated{ () => () } + +fn main() { + local_deprecated!(); // { dg-warning "" "" { target *-*-* } } + deprecated_macro!(); // { dg-warning "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-doc-comments.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-doc-comments.rs new file mode 100644 index 000000000000..8872dc8968f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-doc-comments.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(non_snake_case)] + +macro_rules! doc { + ( + $(#[$outer:meta])* + mod $i:ident { + $(#![$inner:meta])* + } + ) => + ( + $(#[$outer])* + pub mod $i { + $(#![$inner])* + } + ) +} + +doc! { + /// Outer doc + mod Foo { + //! Inner doc + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-doc-escapes.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-doc-escapes.rs new file mode 100644 index 000000000000..3e13a3c5d76c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-doc-escapes.rs @@ -0,0 +1,17 @@ +// run-pass +// When expanding a macro, documentation attributes (including documentation comments) must be +// passed "as is" without being parsed. Otherwise, some text will be incorrectly interpreted as +// escape sequences, leading to an ICE. +// +// Related issues: #25929, #25943 + +macro_rules! homura { + (#[$x:meta]) => () +} + +homura! { + /// \madoka \x41 +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-doc-raw-str-hashes.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-doc-raw-str-hashes.rs new file mode 100644 index 000000000000..c56a661c0c68 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-doc-raw-str-hashes.rs @@ -0,0 +1,31 @@ +// run-pass +// The number of `#`s used to wrap the documentation comment should differ regarding the content. +// +// Related issue: #27489 + +macro_rules! homura { + ($x:expr, #[$y:meta]) => (assert_eq!($x, stringify!($y))) +} + +fn main() { + homura! { + r#"doc = r" Madoka""#, + /// Madoka + }; + + homura! { + r##"doc = r#" One quote mark: ["]"#"##, + /// One quote mark: ["] + }; + + homura! { + r##"doc = r#" Two quote marks: [""]"#"##, + /// Two quote marks: [""] + }; + + homura! { + r#####"doc = r####" Raw string ending sequences: ["###]"####"#####, + /// Raw string ending sequences: ["###] + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-error.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-error.rs new file mode 100644 index 000000000000..5915d6749e9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-error.rs @@ -0,0 +1,10 @@ +macro_rules! foo { + ($a:expr) => a; // { dg-error "" "" { target *-*-* } } +} + +fn main() { + foo!(0); // Check that we report errors at macro definition, not expansion. + + let _: cfg!(foo) = (); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-expanded-include/foo/mod.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-expanded-include/foo/mod.rs new file mode 100644 index 000000000000..9ef7d5eaf4f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-expanded-include/foo/mod.rs @@ -0,0 +1,10 @@ +// ignore-test + +macro_rules! m { + () => { include!("file.txt"); } +} + +macro_rules! n { + () => { unsafe { asm!(include_str!("file.txt")); } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-expanded-include/test.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-expanded-include/test.rs new file mode 100644 index 000000000000..13704b93517d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-expanded-include/test.rs @@ -0,0 +1,14 @@ +// ignore-emscripten no llvm_asm! support +// build-pass (FIXME(62277): could be check-pass?) +#![feature(asm)] +#![allow(unused)] + +#[macro_use] +mod foo; + +m!(); +fn f() { n!(); } + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-expansion-tests.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-expansion-tests.rs new file mode 100644 index 000000000000..e48b3e01928d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-expansion-tests.rs @@ -0,0 +1,41 @@ +#![allow(unused_macros)] + +mod macros_cant_escape_fns { + fn f() { + macro_rules! m { () => { 3 + 4 } } + } + fn g() -> i32 { m!() } +// { dg-error "" "" { target *-*-* } .-1 } +} + +mod macros_cant_escape_mods { + mod f { + macro_rules! m { () => { 3 + 4 } } + } + fn g() -> i32 { m!() } +// { dg-error "" "" { target *-*-* } .-1 } +} + +mod macros_can_escape_flattened_mods_test { + #[macro_use] + mod f { + macro_rules! m { () => { 3 + 4 } } + } + fn g() -> i32 { m!() } +} + +fn macro_tokens_should_match() { + macro_rules! m { (a) => { 13 } } + m!(a); +} + +// should be able to use a bound identifier as a literal in a macro definition: +fn self_macro_parsing() { + macro_rules! foo { (zz) => { 287; } } + fn f(zz: i32) { + foo!(zz); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-export-inner-module.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-export-inner-module.rs new file mode 100644 index 000000000000..47888ab0fcb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-export-inner-module.rs @@ -0,0 +1,10 @@ +// run-pass +//aux-build:macro_export_inner_module.rs + +#[macro_use] #[no_link] +extern crate macro_export_inner_module; + +pub fn main() { + assert_eq!(1, foo!()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-first-set.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-first-set.rs new file mode 100644 index 000000000000..dd5d8292c1df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-first-set.rs @@ -0,0 +1,272 @@ +// run-pass + +//{{{ issue 40569 ============================================================== + +macro_rules! my_struct { + ($(#[$meta:meta])* $ident:ident) => { + $(#[$meta])* struct $ident; + } +} + +my_struct!(#[derive(Debug, PartialEq)] Foo40569); + +fn test_40569() { + assert_eq!(Foo40569, Foo40569); +} + +//}}} + +//{{{ issue 26444 ============================================================== + +macro_rules! foo_26444 { + ($($beginning:ident),*; $middle:ident; $($end:ident),*) => { + stringify!($($beginning,)* $middle $(,$end)*) + } +} + +fn test_26444() { + assert_eq!("a, b, c, d, e", foo_26444!(a, b; c; d, e)); + assert_eq!("f", foo_26444!(; f ;)); +} + +macro_rules! pat_26444 { + ($fname:ident $($arg:pat)* =) => {} +} + +pat_26444!(foo 1 2 5...7 =); +pat_26444!(bar Some(ref x) Ok(ref mut y) &(w, z) =); + +//}}} + +//{{{ issue 40984 ============================================================== + +macro_rules! thread_local_40984 { + () => {}; + ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => { + thread_local_40984!($($rest)*); + }; + ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr) => {}; +} + +thread_local_40984! { + // no docs + #[allow(unused)] + static FOO: i32 = 42; + /// docs + pub static BAR: String = String::from("bar"); + + // look at these restrictions!! + pub(crate) static BAZ: usize = 0; + pub(in foo) static QUUX: usize = 0; +} + +//}}} + +//{{{ issue 35650 ============================================================== + +macro_rules! size { + ($ty:ty) => { + std::mem::size_of::<$ty>() + }; + ($size:tt) => { + $size + }; +} + +fn test_35650() { + assert_eq!(size!(u64), 8); + assert_eq!(size!(5), 5); +} + +//}}} + +//{{{ issue 27832 ============================================================== + +macro_rules! m { + ( $i:ident ) => (); + ( $t:tt $j:tt ) => (); +} + +m!(c); +m!(t 9); +m!(0 9); +m!(struct); +m!(struct Foo); + +macro_rules! m2 { + ( $b:expr ) => (); + ( $t:tt $u:tt ) => (); +} + +m2!(3); +m2!(1 2); +m2!(_ 1); +m2!(enum Foo); + +//}}} + +//{{{ issue 39964 ============================================================== + +macro_rules! foo_39964 { + ($a:ident) => {}; + (_) => {}; +} + +foo_39964!(_); + +//}}} + +//{{{ issue 34030 ============================================================== + +macro_rules! foo_34030 { + ($($t:ident),* /) => {}; +} + +foo_34030!(a, b/); +foo_34030!(a/); +foo_34030!(/); + +//}}} + +//{{{ issue 24189 ============================================================== + +macro_rules! foo_24189 { + ( + pub enum $name:ident { + $( #[$attr:meta] )* $var:ident + } + ) => { + pub enum $name { + $( #[$attr] )* $var + } + }; +} + +foo_24189! { + pub enum Foo24189 { + #[doc = "Bar"] Baz + } +} + +macro_rules! serializable { + ( + $(#[$struct_meta:meta])* + pub struct $name:ident { + $( + $(#[$field_meta:meta])* + $field:ident: $type_:ty + ),* , + } + ) => { + $(#[$struct_meta])* + pub struct $name { + $( + $(#[$field_meta])* + $field: $type_ + ),* , + } + } +} + +serializable! { + #[allow(dead_code)] + /// This is a test + pub struct Tester { + #[allow(dead_code)] + name: String, + } +} + +macro_rules! foo_24189_c { + ( $( > )* $x:ident ) => { }; +} +foo_24189_c!( > a ); + +fn test_24189() { + let _ = Foo24189::Baz; + let _ = Tester { name: "".to_owned() }; +} + +//}}} + +//{{{ issue 50903 ============================================================== + +macro_rules! foo_50903 { + ($($lif:lifetime ,)* #) => {}; +} + +foo_50903!('a, 'b, #); +foo_50903!('a, #); +foo_50903!(#); + +//}}} + +//{{{ issue 51477 ============================================================== + +macro_rules! foo_51477 { + ($lifetime:lifetime) => { + "last token is lifetime" + }; + ($other:tt) => { + "last token is other" + }; + ($first:tt $($rest:tt)*) => { + foo_51477!($($rest)*) + }; +} + +fn test_51477() { + assert_eq!("last token is lifetime", foo_51477!('a)); + assert_eq!("last token is other", foo_51477!(@)); + assert_eq!("last token is lifetime", foo_51477!(@ {} 'a)); +} + +//}}} + +//{{{ some more tests ========================================================== + +macro_rules! test_block { + (< $($b:block)* >) => {} +} + +test_block!(<>); +test_block!(<{}>); +test_block!(<{1}{2}>); + +macro_rules! test_ty { + ($($t:ty),* $(,)*) => {} +} + +test_ty!(); +test_ty!(,); +test_ty!(u8); +test_ty!(u8,); + +macro_rules! test_path { + ($($t:path),* $(,)*) => {} +} + +test_path!(); +test_path!(,); +test_path!(::std); +test_path!(std::u8,); +test_path!(any, super, super::super::self::path, X::Z<'a, T=U>); + +macro_rules! test_lifetime { + (1. $($l:lifetime)* $($b:block)*) => {}; + (2. $($b:block)* $($l:lifetime)*) => {}; +} + +test_lifetime!(1. 'a 'b {} {}); +test_lifetime!(2. {} {} 'a 'b); + +//}}} + +fn main() { + test_26444(); + test_40569(); + test_35650(); + test_24189(); + test_51477(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-follow-rpass.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-follow-rpass.rs new file mode 100644 index 000000000000..488339b025dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-follow-rpass.rs @@ -0,0 +1,184 @@ +// run-pass +#![allow(unused_macros)] +// Check the macro follow sets (see corresponding cfail test). + +// FOLLOW(pat) = {FatArrow, Comma, Eq, Or, Ident(if), Ident(in)} +macro_rules! follow_pat { + ($p:pat =>) => {}; + ($p:pat ,) => {}; + ($p:pat =) => {}; + ($p:pat |) => {}; + ($p:pat if) => {}; + ($p:pat in) => {}; +} +// FOLLOW(expr) = {FatArrow, Comma, Semicolon} +macro_rules! follow_expr { + ($e:expr =>) => {}; + ($e:expr ,) => {}; + ($e:expr ;) => {}; +} +// FOLLOW(ty) = {OpenDelim(Brace), Comma, FatArrow, Colon, Eq, Gt, Semi, Or, +// Ident(as), Ident(where), OpenDelim(Bracket), Nonterminal(Block)} +macro_rules! follow_ty { + ($t:ty {}) => {}; + ($t:ty ,) => {}; + ($t:ty =>) => {}; + ($t:ty :) => {}; + ($t:ty =) => {}; + ($t:ty >) => {}; + ($t:ty ;) => {}; + ($t:ty |) => {}; + ($t:ty as) => {}; + ($t:ty where) => {}; + ($t:ty []) => {}; + ($t:ty $b:block) => {}; +} +// FOLLOW(stmt) = FOLLOW(expr) +macro_rules! follow_stmt { + ($s:stmt =>) => {}; + ($s:stmt ,) => {}; + ($s:stmt ;) => {}; +} +// FOLLOW(path) = FOLLOW(ty) +macro_rules! follow_path { + ($p:path {}) => {}; + ($p:path ,) => {}; + ($p:path =>) => {}; + ($p:path :) => {}; + ($p:path =) => {}; + ($p:path >) => {}; + ($p:path ;) => {}; + ($p:path |) => {}; + ($p:path as) => {}; + ($p:path where) => {}; + ($p:path []) => {}; + ($p:path $b:block) => {}; +} +// FOLLOW(block) = any token +macro_rules! follow_block { + ($b:block ()) => {}; + ($b:block []) => {}; + ($b:block {}) => {}; + ($b:block ,) => {}; + ($b:block =>) => {}; + ($b:block :) => {}; + ($b:block =) => {}; + ($b:block >) => {}; + ($b:block ;) => {}; + ($b:block |) => {}; + ($b:block +) => {}; + ($b:block ident) => {}; + ($b:block $p:pat) => {}; + ($b:block $e:expr) => {}; + ($b:block $t:ty) => {}; + ($b:block $s:stmt) => {}; + ($b:block $p:path) => {}; + ($b:block $c:block) => {}; + ($b:block $i:ident) => {}; + ($b:block $t:tt) => {}; + ($b:block $i:item) => {}; + ($b:block $m:meta) => {}; +} +// FOLLOW(ident) = any token +macro_rules! follow_ident { + ($i:ident ()) => {}; + ($i:ident []) => {}; + ($i:ident {}) => {}; + ($i:ident ,) => {}; + ($i:ident =>) => {}; + ($i:ident :) => {}; + ($i:ident =) => {}; + ($i:ident >) => {}; + ($i:ident ;) => {}; + ($i:ident |) => {}; + ($i:ident +) => {}; + ($i:ident ident) => {}; + ($i:ident $p:pat) => {}; + ($i:ident $e:expr) => {}; + ($i:ident $t:ty) => {}; + ($i:ident $s:stmt) => {}; + ($i:ident $p:path) => {}; + ($i:ident $b:block) => {}; + ($i:ident $j:ident) => {}; + ($i:ident $t:tt) => {}; + ($i:ident $j:item) => {}; + ($i:ident $m:meta) => {}; +} +// FOLLOW(tt) = any token +macro_rules! follow_tt { + ($t:tt ()) => {}; + ($t:tt []) => {}; + ($t:tt {}) => {}; + ($t:tt ,) => {}; + ($t:tt =>) => {}; + ($t:tt :) => {}; + ($t:tt =) => {}; + ($t:tt >) => {}; + ($t:tt ;) => {}; + ($t:tt |) => {}; + ($t:tt +) => {}; + ($t:tt ident) => {}; + ($t:tt $p:pat) => {}; + ($t:tt $e:expr) => {}; + ($t:tt $v:ty) => {}; + ($t:tt $s:stmt) => {}; + ($t:tt $p:path) => {}; + ($t:tt $b:block) => {}; + ($t:tt $i:ident) => {}; + ($t:tt $v:tt) => {}; + ($t:tt $i:item) => {}; + ($t:tt $m:meta) => {}; +} +// FOLLOW(item) = any token +macro_rules! follow_item { + ($i:item ()) => {}; + ($i:item []) => {}; + ($i:item {}) => {}; + ($i:item ,) => {}; + ($i:item =>) => {}; + ($i:item :) => {}; + ($i:item =) => {}; + ($i:item >) => {}; + ($i:item ;) => {}; + ($i:item |) => {}; + ($i:item +) => {}; + ($i:item ident) => {}; + ($i:item $p:pat) => {}; + ($i:item $e:expr) => {}; + ($i:item $t:ty) => {}; + ($i:item $s:stmt) => {}; + ($i:item $p:path) => {}; + ($i:item $b:block) => {}; + ($i:item $j:ident) => {}; + ($i:item $t:tt) => {}; + ($i:item $j:item) => {}; + ($i:item $m:meta) => {}; +} +// FOLLOW(meta) = any token +macro_rules! follow_meta { + ($m:meta ()) => {}; + ($m:meta []) => {}; + ($m:meta {}) => {}; + ($m:meta ,) => {}; + ($m:meta =>) => {}; + ($m:meta :) => {}; + ($m:meta =) => {}; + ($m:meta >) => {}; + ($m:meta ;) => {}; + ($m:meta |) => {}; + ($m:meta +) => {}; + ($m:meta ident) => {}; + ($m:meta $p:pat) => {}; + ($m:meta $e:expr) => {}; + ($m:meta $t:ty) => {}; + ($m:meta $s:stmt) => {}; + ($m:meta $p:path) => {}; + ($m:meta $b:block) => {}; + ($m:meta $i:ident) => {}; + ($m:meta $t:tt) => {}; + ($m:meta $i:item) => {}; + ($m:meta $n:meta) => {}; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-follow.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-follow.rs new file mode 100644 index 000000000000..1c85466834b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-follow.rs @@ -0,0 +1,115 @@ +// +// Check the macro follow sets (see corresponding rpass test). + +#![allow(unused_macros)] + +// FOLLOW(pat) = {FatArrow, Comma, Eq, Or, Ident(if), Ident(in)} +macro_rules! follow_pat { + ($p:pat ()) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat []) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat {}) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat :) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat >) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat +) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat ident) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat $q:pat) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat $e:expr) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat $t:ty) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat $s:stmt) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat $q:path) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat $b:block) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat $i:ident) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat $t:tt) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat $i:item) => {}; // { dg-error "" "" { target *-*-* } } + ($p:pat $m:meta) => {}; // { dg-error "" "" { target *-*-* } } +} +// FOLLOW(expr) = {FatArrow, Comma, Semicolon} +macro_rules! follow_expr { + ($e:expr ()) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr []) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr {}) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr =) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr |) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr :) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr >) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr +) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr ident) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr if) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr in) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr $p:pat) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr $f:expr) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr $t:ty) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr $s:stmt) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr $p:path) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr $b:block) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr $i:ident) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr $t:tt) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr $i:item) => {}; // { dg-error "" "" { target *-*-* } } + ($e:expr $m:meta) => {}; // { dg-error "" "" { target *-*-* } } +} +// FOLLOW(ty) = {OpenDelim(Brace), Comma, FatArrow, Colon, Eq, Gt, Semi, Or, +// Ident(as), Ident(where), OpenDelim(Bracket), Nonterminal(Block)} +macro_rules! follow_ty { + ($t:ty ()) => {}; // { dg-error "" "" { target *-*-* } } + ($t:ty []) => {}; // ok (RFC 1462) + ($t:ty +) => {}; // { dg-error "" "" { target *-*-* } } + ($t:ty ident) => {}; // { dg-error "" "" { target *-*-* } } + ($t:ty if) => {}; // { dg-error "" "" { target *-*-* } } + ($t:ty $p:pat) => {}; // { dg-error "" "" { target *-*-* } } + ($t:ty $e:expr) => {}; // { dg-error "" "" { target *-*-* } } + ($t:ty $r:ty) => {}; // { dg-error "" "" { target *-*-* } } + ($t:ty $s:stmt) => {}; // { dg-error "" "" { target *-*-* } } + ($t:ty $p:path) => {}; // { dg-error "" "" { target *-*-* } } + ($t:ty $b:block) => {}; // ok (RFC 1494) + ($t:ty $i:ident) => {}; // { dg-error "" "" { target *-*-* } } + ($t:ty $r:tt) => {}; // { dg-error "" "" { target *-*-* } } + ($t:ty $i:item) => {}; // { dg-error "" "" { target *-*-* } } + ($t:ty $m:meta) => {}; // { dg-error "" "" { target *-*-* } } +} +// FOLLOW(stmt) = FOLLOW(expr) +macro_rules! follow_stmt { + ($s:stmt ()) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt []) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt {}) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt =) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt |) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt :) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt >) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt +) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt ident) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt if) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt in) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt $p:pat) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt $e:expr) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt $t:ty) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt $t:stmt) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt $p:path) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt $b:block) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt $i:ident) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt $t:tt) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt $i:item) => {}; // { dg-error "" "" { target *-*-* } } + ($s:stmt $m:meta) => {}; // { dg-error "" "" { target *-*-* } } +} +// FOLLOW(path) = FOLLOW(ty) +macro_rules! follow_path { + ($p:path ()) => {}; // { dg-error "" "" { target *-*-* } } + ($p:path []) => {}; // ok (RFC 1462) + ($p:path +) => {}; // { dg-error "" "" { target *-*-* } } + ($p:path ident) => {}; // { dg-error "" "" { target *-*-* } } + ($p:path if) => {}; // { dg-error "" "" { target *-*-* } } + ($p:path $q:pat) => {}; // { dg-error "" "" { target *-*-* } } + ($p:path $e:expr) => {}; // { dg-error "" "" { target *-*-* } } + ($p:path $t:ty) => {}; // { dg-error "" "" { target *-*-* } } + ($p:path $s:stmt) => {}; // { dg-error "" "" { target *-*-* } } + ($p:path $q:path) => {}; // { dg-error "" "" { target *-*-* } } + ($p:path $b:block) => {}; // ok (RFC 1494) + ($p:path $i:ident) => {}; // { dg-error "" "" { target *-*-* } } + ($p:path $t:tt) => {}; // { dg-error "" "" { target *-*-* } } + ($p:path $i:item) => {}; // { dg-error "" "" { target *-*-* } } + ($p:path $m:meta) => {}; // { dg-error "" "" { target *-*-* } } +} +// FOLLOW(block) = any token +// FOLLOW(ident) = any token + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-followed-by-seq-bad.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-followed-by-seq-bad.rs new file mode 100644 index 000000000000..e97590880523 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-followed-by-seq-bad.rs @@ -0,0 +1,12 @@ +// Regression test for issue #25436: check that things which can be +// followed by any token also permit X* to come afterwards. + +#![allow(unused_macros)] + +macro_rules! foo { + ( $a:expr $($b:tt)* ) => { }; // { dg-error "" "" { target *-*-* } } + ( $a:ty $($b:tt)* ) => { }; // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-followed-by-seq.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-followed-by-seq.rs new file mode 100644 index 000000000000..3342c996d1c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-followed-by-seq.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(unused_macros)] +// Regression test for issue #25436: check that things which can be +// followed by any token also permit X* to come afterwards. + +macro_rules! foo { + ( $a:tt $($b:tt)* ) => { }; + ( $a:ident $($b:tt)* ) => { }; + ( $a:item $($b:tt)* ) => { }; + ( $a:block $($b:tt)* ) => { }; + ( $a:meta $($b:tt)* ) => { } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-in-expression-context-2.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-in-expression-context-2.rs new file mode 100644 index 000000000000..663972a766b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-in-expression-context-2.rs @@ -0,0 +1,9 @@ +macro_rules! empty { () => () } + +fn main() { + match 42 { + _ => { empty!() } +// { dg-error "" "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-in-expression-context.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-in-expression-context.rs new file mode 100644 index 000000000000..fbf3866abd44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-in-expression-context.rs @@ -0,0 +1,16 @@ +// run-rustfix + +macro_rules! foo { + () => { + assert_eq!("A", "A"); + assert_eq!("B", "B"); + } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-2 } +} + +fn main() { + foo!() +// { dg-note "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-in-fn.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-in-fn.rs new file mode 100644 index 000000000000..d912f302c251 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-in-fn.rs @@ -0,0 +1,9 @@ +// run-pass +#![feature(decl_macro)] + +pub fn moo() { + pub macro ABC() {{}} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-include-items.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-include-items.rs new file mode 100644 index 000000000000..f9e98aceb4fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-include-items.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(non_camel_case_types)] + +// ignore-pretty issue #37195 + +fn bar() {} + +include!(concat!("", "", "auxiliary/", "macro-include-items-item.rs")); + +fn main() { + foo(); + assert_eq!(include!(concat!("", "auxiliary/", "macro-include-items-expr.rs")), 1_usize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-inner-attributes.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-inner-attributes.rs new file mode 100644 index 000000000000..e1449ac5c0fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-inner-attributes.rs @@ -0,0 +1,21 @@ +#![feature(rustc_attrs)] + +macro_rules! test { ($nm:ident, + #[$a:meta], + $i:item) => (mod $nm { #![$a] $i }); } + +test!(a, + #[cfg(qux)], + pub fn bar() { }); + +test!(b, + #[cfg(not(qux))], + pub fn bar() { }); + +#[rustc_dummy] +fn main() { + a::bar(); +// { dg-error ".E0433." "" { target *-*-* } .-1 } + b::bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-input-future-proofing.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-input-future-proofing.rs new file mode 100644 index 000000000000..7d94826adfc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-input-future-proofing.rs @@ -0,0 +1,24 @@ +#![allow(unused_macros)] + +macro_rules! errors_everywhere { + ($ty:ty <) => (); // { dg-error "" "" { target *-*-* } } + ($ty:ty < foo ,) => (); // { dg-error "" "" { target *-*-* } } + ($ty:ty , ) => (); + ( ( $ty:ty ) ) => (); + ( { $ty:ty } ) => (); + ( [ $ty:ty ] ) => (); + ($bl:block < ) => (); + ($pa:pat >) => (); // { dg-error "" "" { target *-*-* } } + ($pa:pat , ) => (); + ($pa:pat $pb:pat $ty:ty ,) => (); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + ($($ty:ty)* -) => (); // { dg-error "" "" { target *-*-* } } + ($($a:ty, $b:ty)* -) => (); // { dg-error "" "" { target *-*-* } } + ($($ty:ty)-+) => (); // { dg-error "" "" { target *-*-* } } + ( $($a:expr)* $($b:tt)* ) => { }; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-interpolation.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-interpolation.rs new file mode 100644 index 000000000000..0b8f83a2b182 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-interpolation.rs @@ -0,0 +1,22 @@ +// run-pass + +macro_rules! overly_complicated { + ($fnname:ident, $arg:ident, $ty:ty, $body:block, $val:expr, $pat:pat, $res:path) => + ({ + fn $fnname($arg: $ty) -> Option<$ty> $body + match $fnname($val) { + Some($pat) => { + $res + } + _ => { panic!(); } + } + }) + +} + +pub fn main() { + assert!(overly_complicated!(f, x, Option, { return Some(x); }, + Some(8), Some(y), y) == 8) + +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-invalid-fragment-spec.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-invalid-fragment-spec.rs new file mode 100644 index 000000000000..07aaf0e72105 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-invalid-fragment-spec.rs @@ -0,0 +1,9 @@ +macro_rules! foo( + ($x:foo) => () +// { dg-error "" "" { target *-*-* } .-1 } +); + +fn main() { + foo!(foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs new file mode 100644 index 000000000000..086e7310962b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-invocation-in-count-expr-fixed-array-type.rs @@ -0,0 +1,11 @@ +// run-pass +// pretty-expanded FIXME #23616 + +macro_rules! four { + () => (4) +} + +fn main() { + let _x: [u16; four!()]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-lifetime-used-with-bound.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-lifetime-used-with-bound.rs new file mode 100644 index 000000000000..c6695d187c4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-lifetime-used-with-bound.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(unused_variables)] +macro_rules! foo { + ($l:lifetime, $l2:lifetime) => { + fn f<$l: $l2, $l2>(arg: &$l str, arg2: &$l2 str) -> &$l str { + arg + } + } +} + +pub fn main() { + foo!('a, 'b); + let x: &'static str = f("hi", "there"); + assert_eq!("hi", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-lifetime-used-with-labels.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-lifetime-used-with-labels.rs new file mode 100644 index 000000000000..ee9037594bca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-lifetime-used-with-labels.rs @@ -0,0 +1,37 @@ +// run-pass +#![allow(stable_features)] +#![allow(unused_labels)] +#![allow(unreachable_code)] + +macro_rules! x { + ($a:lifetime) => { + $a: loop { + break $a; + panic!("failed"); + } + } +} +macro_rules! br { + ($a:lifetime) => { + break $a; + } +} +macro_rules! br2 { + ($b:lifetime) => { + 'b: loop { // { dg-warning "" "" { target *-*-* } } + break $b; // this $b should refer to the outer loop. + } + } +} +fn main() { + x!('a); + 'c: loop { + br!('c); + panic!("failed"); + } + 'b: loop { + br2!('b); + panic!("failed"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-lifetime-used-with-static.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-lifetime-used-with-static.rs new file mode 100644 index 000000000000..2dd10ff95521 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-lifetime-used-with-static.rs @@ -0,0 +1,15 @@ +// run-pass +macro_rules! foo { + ($l:lifetime) => { + fn f(arg: &$l str) -> &$l str { + arg + } + } +} + +pub fn main() { + foo!('static); + let x: &'static str = f("hi"); + assert_eq!("hi", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-lifetime.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-lifetime.rs new file mode 100644 index 000000000000..1302cbdbe5a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-lifetime.rs @@ -0,0 +1,15 @@ +// run-pass +macro_rules! foo { + ($l:lifetime) => { + fn f<$l>(arg: &$l str) -> &$l str { + arg + } + } +} + +pub fn main() { + foo!('a); + let x: &'static str = f("hi"); + assert_eq!("hi", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-literal.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-literal.rs new file mode 100644 index 000000000000..f735984519b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-literal.rs @@ -0,0 +1,134 @@ +// run-pass + +macro_rules! mtester { + ($l:literal) => { + &format!("macro caught literal: {}", $l) + }; + ($e:expr) => { + &format!("macro caught expr: {}", $e) + }; +} + +macro_rules! two_negative_literals { + ($l1:literal $l2:literal) => { + &format!("macro caught literals: {}, {}", $l1, $l2) + }; +} + +macro_rules! only_expr { + ($e:expr) => { + &format!("macro caught expr: {}", $e) + }; +} + +macro_rules! mtester_dbg { + ($l:literal) => { + &format!("macro caught literal: {:?}", $l) + }; + ($e:expr) => { + &format!("macro caught expr: {:?}", $e) + }; +} + +macro_rules! catch_range { + ($s:literal ..= $e:literal) => { + &format!("macro caught literal: {} ..= {}", $s, $e) + }; + (($s:expr) ..= ($e:expr)) => { // Must use ')' before '..=' + &format!("macro caught expr: {} ..= {}", $s, $e) + }; +} + +macro_rules! pat_match { + ($s:literal ..= $e:literal) => { + match 3 { + $s ..= $e => "literal, in range", + _ => "literal, other", + } + }; + ($s:pat) => { + match 3 { + $s => "pat, single", + _ => "pat, other", + } + }; +} + +macro_rules! match_attr { + (#[$attr:meta] $e:literal) => { + "attr matched literal" + }; + (#[$attr:meta] $e:expr) => { + "attr matched expr" + }; +} + +macro_rules! match_produced_attr { + ($lit: literal) => { + // Struct with doc comment passed via $literal + #[doc = $lit] + struct LiteralProduced; + }; + ($expr: expr) => { + struct ExprProduced; + }; +} + +macro_rules! test_user { + ($s:literal, $e:literal) => { + { + let mut v = Vec::new(); + for i in $s .. $e { + v.push(i); + } + "literal" + } + }; + ($s:expr, $e: expr) => { + { + let mut v = Vec::new(); + for i in $s .. $e { + v.push(i); + } + "expr" + } + }; +} + +pub fn main() { + // Cases where 'literal' catches + assert_eq!(mtester!("str"), "macro caught literal: str"); + assert_eq!(mtester!(2), "macro caught literal: 2"); + assert_eq!(mtester!(2.2), "macro caught literal: 2.2"); + assert_eq!(mtester!(1u32), "macro caught literal: 1"); + assert_eq!(mtester!(0x32), "macro caught literal: 50"); + assert_eq!(mtester!('c'), "macro caught literal: c"); + assert_eq!(mtester!(-1.2), "macro caught literal: -1.2"); + assert_eq!(two_negative_literals!(-2 -3), "macro caught literals: -2, -3"); + assert_eq!(catch_range!(2 ..= 3), "macro caught literal: 2 ..= 3"); + assert_eq!(match_attr!(#[attr] 1), "attr matched literal"); + assert_eq!(test_user!(10, 20), "literal"); + assert_eq!(mtester!(false), "macro caught literal: false"); + assert_eq!(mtester!(true), "macro caught literal: true"); + match_produced_attr!("a"); + let _a = LiteralProduced; + assert_eq!(pat_match!(1 ..= 3), "literal, in range"); + assert_eq!(pat_match!(4 ..= 6), "literal, other"); + + // Cases where 'expr' catches + assert_eq!(mtester!((-1.2)), "macro caught expr: -1.2"); + assert_eq!(only_expr!(-1.2), "macro caught expr: -1.2"); + assert_eq!(mtester!((1 + 3)), "macro caught expr: 4"); + assert_eq!(mtester_dbg!(()), "macro caught expr: ()"); + assert_eq!(catch_range!((1 + 1) ..= (2 + 2)), "macro caught expr: 2 ..= 4"); + assert_eq!(match_attr!(#[attr] (1 + 2)), "attr matched expr"); + assert_eq!(test_user!(10, (20 + 2)), "expr"); + + match_produced_attr!((3 + 2)); + let _b = ExprProduced; + + // Cases where 'pat' matched + assert_eq!(pat_match!(3), "pat, single"); + assert_eq!(pat_match!(6), "pat, other"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-local-data-key-priv.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-local-data-key-priv.rs new file mode 100644 index 000000000000..231fbd0e3b9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-local-data-key-priv.rs @@ -0,0 +1,11 @@ +// check that the local data keys are private by default. + +mod bar { + thread_local!(static baz: f64 = 0.0); +} + +fn main() { + bar::baz.with(|_| ()); +// { dg-error ".E0603." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-match-nonterminal.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-match-nonterminal.rs new file mode 100644 index 000000000000..b2eb0c82f9c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-match-nonterminal.rs @@ -0,0 +1,13 @@ +macro_rules! test { + ($a, $b) => { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + () + }; +} + +fn main() { + test!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-meta-items-modern.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-meta-items-modern.rs new file mode 100644 index 000000000000..893f124ad218 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-meta-items-modern.rs @@ -0,0 +1,12 @@ +// check-pass + +macro_rules! check { ($meta:meta) => () } + +check!(meta(a b c d)); +check!(meta[a b c d]); +check!(meta { a b c d }); +check!(meta); +check!(meta = 0); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-meta-items.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-meta-items.rs new file mode 100644 index 000000000000..a21c81772d0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-meta-items.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(dead_code)] +// compile-flags: --cfg foo + +macro_rules! compiles_fine { + ($at:meta) => { + #[cfg($at)] + static MISTYPED: () = "foo"; + } +} +macro_rules! emit { + ($at:meta) => { + #[cfg($at)] + static MISTYPED: &'static str = "foo"; + } +} + +// item +compiles_fine!(bar); +emit!(foo); + +fn foo() { + println!("{}", MISTYPED); +} + +pub fn main() { + // statement + compiles_fine!(baz); + emit!(baz); + println!("{}", MISTYPED); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-method-issue-4621.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-method-issue-4621.rs new file mode 100644 index 000000000000..eb157498d85b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-method-issue-4621.rs @@ -0,0 +1,11 @@ +// run-pass + +struct A; + +macro_rules! make_thirteen_method {() => (fn thirteen(&self)->isize {13})} +impl A { make_thirteen_method!(); } + +fn main() { + assert_eq!(A.thirteen(),13); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-missing-delimiters.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-missing-delimiters.rs new file mode 100644 index 000000000000..592980eb1c3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-missing-delimiters.rs @@ -0,0 +1,8 @@ +macro_rules! baz( + baz => () // { dg-error "" "" { target *-*-* } } +); + +fn main() { + baz!(baz); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-missing-fragment.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-missing-fragment.rs new file mode 100644 index 000000000000..908e9c8aa13f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-missing-fragment.rs @@ -0,0 +1,8 @@ +macro_rules! m { + ( $( any_token $field_rust_type )* ) => {}; // { dg-error "" "" { target *-*-* } } +} + +fn main() { + m!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-multiple-items.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-multiple-items.rs new file mode 100644 index 000000000000..26be52329b5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-multiple-items.rs @@ -0,0 +1,17 @@ +// run-pass +macro_rules! make_foo { + () => ( + struct Foo; + + impl Foo { + fn bar(&self) {} + } + ) +} + +make_foo!(); + +pub fn main() { + Foo.bar() +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-multiple-matcher-bindings.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-multiple-matcher-bindings.rs new file mode 100644 index 000000000000..4d50534bf0f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-multiple-matcher-bindings.rs @@ -0,0 +1,22 @@ +// Test that duplicate matcher binding names are caught at declaration time, rather than at macro +// invocation time. + +#![allow(unused_macros)] + +macro_rules! foo1 { + ($a:ident, $a:ident) => {}; // { dg-error "" "" { target *-*-* } } + ($a:ident, $a:path) => {}; // { dg-error "" "" { target *-*-* } } +} + +macro_rules! foo2 { + ($a:ident) => {}; // OK + ($a:path) => {}; // OK +} + +macro_rules! foo3 { + ($a:ident, $($a:ident),*) => {}; // { dg-error "" "" { target *-*-* } } + ($($a:ident)+ # $($($a:path),+);*) => {}; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-name-typo.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-name-typo.rs new file mode 100644 index 000000000000..d888e08a2952 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-name-typo.rs @@ -0,0 +1,4 @@ +fn main() { + printlx!("oh noes!"); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-named-default.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-named-default.rs new file mode 100644 index 000000000000..149bb4b09c65 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-named-default.rs @@ -0,0 +1,19 @@ +// run-pass +macro_rules! default { + ($($x:tt)*) => { $($x)* } +} + +default! { + struct A; +} + +impl A { + default! { + fn foo(&self) {} + } +} + +fn main() { + A.foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-nested_definition_issue-31946.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-nested_definition_issue-31946.rs new file mode 100644 index 000000000000..a98ac22ff5bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-nested_definition_issue-31946.rs @@ -0,0 +1,10 @@ +// run-pass +fn main() { + println!("{}", { + macro_rules! foo { + ($name:expr) => { concat!("hello ", $name) } + } + foo!("rust") + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-nested_expr.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-nested_expr.rs new file mode 100644 index 000000000000..2f93ffec4abb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-nested_expr.rs @@ -0,0 +1,23 @@ +// run-pass +// #42164 + +#![feature(decl_macro)] +#![allow(dead_code)] + +pub macro m($inner_str:expr) { + #[doc = $inner_str] + struct S; +} + +macro_rules! define_f { + ($name:expr) => { + #[export_name = $name] + fn f() {} + } +} + +fn main() { + define_f!(concat!("exported_", "f")); + m!(stringify!(foo)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-nested_stmt_macros.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-nested_stmt_macros.rs new file mode 100644 index 000000000000..764a665a0b3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-nested_stmt_macros.rs @@ -0,0 +1,24 @@ +// run-pass +macro_rules! foo { + () => { + struct Bar; + struct Baz; + } +} + +macro_rules! grault { + () => { + foo!(); + struct Xyzzy; + } +} + +fn static_assert_exists() { } + +fn main() { + grault!(); + static_assert_exists::(); + static_assert_exists::(); + static_assert_exists::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-non-lifetime.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-non-lifetime.rs new file mode 100644 index 000000000000..22b80a19d03f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-non-lifetime.rs @@ -0,0 +1,11 @@ +// Test for issue #50381: non-lifetime passed to :lifetime. + +#![feature(macro_lifetime_matcher)] + +macro_rules! m { ($x:lifetime) => { } } + +fn main() { + m!(a); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-nt-list.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-nt-list.rs new file mode 100644 index 000000000000..b15838deb08c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-nt-list.rs @@ -0,0 +1,22 @@ +// run-pass +// pretty-expanded FIXME #23616 + +macro_rules! list { + ( ($($id:ident),*) ) => (()); + ( [$($id:ident),*] ) => (()); + ( {$($id:ident),*} ) => (()); +} + +macro_rules! tt_list { + ( ($($tt:tt),*) ) => (()); +} + +pub fn main() { + list!( () ); + list!( [] ); + list!( {} ); + + tt_list!( (a, b, c) ); + tt_list!( () ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-of-higher-order.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-of-higher-order.rs new file mode 100644 index 000000000000..54dfc9b5509c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-of-higher-order.rs @@ -0,0 +1,23 @@ +// run-pass + +macro_rules! higher_order { + (subst $lhs:tt => $rhs:tt) => ({ + macro_rules! anon { $lhs => $rhs } + anon!(1_usize, 2_usize, "foo") + }); +} + +macro_rules! outer { + ($x:expr; $fragment:ident) => { + macro_rules! inner { ($y:$fragment) => { $x + $y } } + } +} + +fn main() { + let val = higher_order!(subst ($x:expr, $y:expr, $foo:expr) => (($x + $y, $foo))); + assert_eq!(val, (3, "foo")); + + outer!(2; expr); + assert_eq!(inner!(3), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-outer-attributes.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-outer-attributes.rs new file mode 100644 index 000000000000..9ab4a7b93c4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-outer-attributes.rs @@ -0,0 +1,21 @@ +#![feature(rustc_attrs)] + +macro_rules! test { ($nm:ident, + #[$a:meta], + $i:item) => (mod $nm { #[$a] $i }); } + +test!(a, + #[cfg(qux)], + pub fn bar() { }); + +test!(b, + #[cfg(not(qux))], + pub fn bar() { }); + +// test1!(#[bar]) +#[rustc_dummy] +fn main() { + a::bar(); // { dg-error ".E0425." "" { target *-*-* } } + b::bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-parameter-span.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-parameter-span.rs new file mode 100644 index 000000000000..d642276386c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-parameter-span.rs @@ -0,0 +1,14 @@ +macro_rules! foo { + ($id: ident) => { + $id + } +} + +// Testing that the error span points to the parameter 'x' in the callsite, +// not to the macro variable '$id' +fn main() { + foo!( + x // { dg-error ".E0425." "" { target *-*-* } } + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-pat-follow.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-pat-follow.rs new file mode 100644 index 000000000000..9f95a662d0be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-pat-follow.rs @@ -0,0 +1,32 @@ +// run-pass +macro_rules! pat_in { + ($p:pat in $e:expr) => {{ + let mut iter = $e.into_iter(); + while let $p = iter.next() {} + }} +} + +macro_rules! pat_if { + ($p:pat if $e:expr) => {{ + match Some(1u8) { + $p if $e => {}, + _ => {} + } + }} +} + +macro_rules! pat_bar { + ($p:pat | $p2:pat) => {{ + match Some(1u8) { + $p | $p2 => {}, + _ => {} + } + }} +} + +fn main() { + pat_in!(Some(_) in 0..10); + pat_if!(Some(x) if x > 0); + pat_bar!(Some(1u8) | None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-pat-neg-lit.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-pat-neg-lit.rs new file mode 100644 index 000000000000..5345df2e84e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-pat-neg-lit.rs @@ -0,0 +1,26 @@ +// run-pass +macro_rules! enum_number { + ($name:ident { $($variant:ident = $value:expr, )* }) => { + enum $name { + $($variant = $value,)* + } + + fn foo(value: i32) -> Option<$name> { + match value { + $( $value => Some($name::$variant), )* + _ => None + } + } + } +} + +enum_number!(Change { + Down = -1, + None = 0, + Up = 1, +}); + +fn main() { + if let Some(Change::Down) = foo(-1) {} else { panic!() } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-pat.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-pat.rs new file mode 100644 index 000000000000..58d020766172 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-pat.rs @@ -0,0 +1,66 @@ +// run-pass + +macro_rules! mypat { + () => ( + Some('y') + ) +} + +macro_rules! char_x { + () => ( + 'x' + ) +} + +macro_rules! some { + ($x:pat) => ( + Some($x) + ) +} + +macro_rules! indirect { + () => ( + some!(char_x!()) + ) +} + +macro_rules! ident_pat { + ($x:ident) => ( + $x + ) +} + +fn f(c: Option) -> usize { + match c { + Some('x') => 1, + mypat!() => 2, + _ => 3, + } +} + +pub fn main() { + assert_eq!(1, f(Some('x'))); + assert_eq!(2, f(Some('y'))); + assert_eq!(3, f(None)); + + assert_eq!(1, match Some('x') { + Some(char_x!()) => 1, + _ => 2, + }); + + assert_eq!(1, match Some('x') { + some!(char_x!()) => 1, + _ => 2, + }); + + assert_eq!(1, match Some('x') { + indirect!() => 1, + _ => 2, + }); + + assert_eq!(3, { + let ident_pat!(x) = 2; + x+1 + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-1.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-1.rs new file mode 100644 index 000000000000..060ba4965c5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-1.rs @@ -0,0 +1,11 @@ +#![feature(extern_prelude)] + +mod m { + fn check() { + Vec::clone!(); // { dg-error ".E0433." "" { target *-*-* } } + u8::clone!(); // { dg-error ".E0433." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-2.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-2.rs new file mode 100644 index 000000000000..1ec51f24e7ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-2.rs @@ -0,0 +1,8 @@ +mod m { + fn check() { + Result::Ok!(); // { dg-error ".E0433." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-3.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-3.rs new file mode 100644 index 000000000000..98b1874f91b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-3.rs @@ -0,0 +1,4 @@ +fn main() { + inline!(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-4.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-4.rs new file mode 100644 index 000000000000..bed859ffa7de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-fail-4.rs @@ -0,0 +1,5 @@ +#[derive(inline)] // { dg-error "" "" { target *-*-* } } +struct S; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-pass.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-pass.rs new file mode 100644 index 000000000000..f761a99239ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-pass.rs @@ -0,0 +1,10 @@ +// check-pass + +mod m { + fn check() { + std::panic!(); // OK + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-shadowing.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-shadowing.rs new file mode 100644 index 000000000000..ca27b4216b75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-path-prelude-shadowing.rs @@ -0,0 +1,34 @@ +// aux-build:macro-in-other-crate.rs + +#![feature(decl_macro, extern_prelude)] + +macro_rules! add_macro_expanded_things_to_macro_prelude {() => { + #[macro_use] + extern crate macro_in_other_crate; +}} + +add_macro_expanded_things_to_macro_prelude!(); + +mod m1 { + fn check() { + inline!(); // OK. Theoretically ambiguous, but we do not consider built-in attributes + // as candidates for non-attribute macro invocations to avoid regressions + // on stable channel + } +} + +mod m2 { + pub mod std { + pub macro panic() {} + } +} + +mod m3 { + use m2::*; // glob-import user-defined `std` + fn check() { + std::panic!(); // { dg-error ".E0659." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-path.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-path.rs new file mode 100644 index 000000000000..dc1a9fc7fcea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-path.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(non_camel_case_types)] + + +mod m { + pub type t = isize; +} + +macro_rules! foo { + ($p:path) => ({ + fn f() -> $p { 10 }; + f() + }) +} + +pub fn main() { + assert_eq!(foo!(m::t), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-pub-matcher.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-pub-matcher.rs new file mode 100644 index 000000000000..9de8b832ec46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-pub-matcher.rs @@ -0,0 +1,119 @@ +// run-pass +#![allow(dead_code, unused_imports)] +#![feature(crate_visibility_modifier)] + +/** +Ensure that `:vis` matches can be captured in existing positions, and passed +through without the need for reparse tricks. +*/ +macro_rules! vis_passthru { + ($vis:vis const $name:ident: $ty:ty = $e:expr;) => { $vis const $name: $ty = $e; }; + ($vis:vis enum $name:ident {}) => { $vis struct $name {} }; + ($vis:vis extern "C" fn $name:ident() {}) => { $vis extern "C" fn $name() {} }; + ($vis:vis fn $name:ident() {}) => { $vis fn $name() {} }; + ($vis:vis mod $name:ident {}) => { $vis mod $name {} }; + ($vis:vis static $name:ident: $ty:ty = $e:expr;) => { $vis static $name: $ty = $e; }; + ($vis:vis struct $name:ident;) => { $vis struct $name; }; + ($vis:vis trait $name:ident {}) => { $vis trait $name {} }; + ($vis:vis type $name:ident = $ty:ty;) => { $vis type $name = $ty; }; + ($vis:vis use $path:ident as $name:ident;) => { $vis use self::$path as $name; }; +} + +mod with_pub { + vis_passthru! { pub const A: i32 = 0; } + vis_passthru! { pub enum B {} } + vis_passthru! { pub extern "C" fn c() {} } + vis_passthru! { pub mod d {} } + vis_passthru! { pub static E: i32 = 0; } + vis_passthru! { pub struct F; } + vis_passthru! { pub trait G {} } + vis_passthru! { pub type H = i32; } + vis_passthru! { pub use A as I; } +} + +mod without_pub { + vis_passthru! { const A: i32 = 0; } + vis_passthru! { enum B {} } + vis_passthru! { extern "C" fn c() {} } + vis_passthru! { mod d {} } + vis_passthru! { static E: i32 = 0; } + vis_passthru! { struct F; } + vis_passthru! { trait G {} } + vis_passthru! { type H = i32; } + vis_passthru! { use A as I; } +} + +mod with_pub_restricted { + vis_passthru! { pub(crate) const A: i32 = 0; } + vis_passthru! { pub(crate) enum B {} } + vis_passthru! { pub(crate) extern "C" fn c() {} } + vis_passthru! { pub(crate) mod d {} } + vis_passthru! { pub(crate) static E: i32 = 0; } + vis_passthru! { pub(crate) struct F; } + vis_passthru! { pub(crate) trait G {} } + vis_passthru! { pub(crate) type H = i32; } + vis_passthru! { pub(crate) use A as I; } +} + +mod with_crate { + vis_passthru! { crate const A: i32 = 0; } + vis_passthru! { crate enum B {} } + vis_passthru! { crate extern "C" fn c() {} } + vis_passthru! { crate mod d {} } + vis_passthru! { crate static E: i32 = 0; } + vis_passthru! { crate struct F; } + vis_passthru! { crate trait G {} } + vis_passthru! { crate type H = i32; } + vis_passthru! { crate use A as I; } +} + +mod garden { + mod with_pub_restricted_path { + vis_passthru! { pub(in garden) const A: i32 = 0; } + vis_passthru! { pub(in garden) enum B {} } + vis_passthru! { pub(in garden) extern "C" fn c() {} } + vis_passthru! { pub(in garden) mod d {} } + vis_passthru! { pub(in garden) static E: i32 = 0; } + vis_passthru! { pub(in garden) struct F; } + vis_passthru! { pub(in garden) trait G {} } + vis_passthru! { pub(in garden) type H = i32; } + vis_passthru! { pub(in garden) use A as I; } + } +} + +/* +Ensure that the `:vis` matcher works in a more complex situation: parsing a +struct definition. +*/ +macro_rules! vis_parse_struct { + ($(#[$($attrs:tt)*])* $vis:vis struct $name:ident {$($body:tt)*}) => { + vis_parse_struct! { @parse_fields $(#[$($attrs)*])*, $vis, $name, $($body)* } + }; + + ($(#[$($attrs:tt)*])* $vis:vis struct $name:ident ($($body:tt)*);) => { + vis_parse_struct! { @parse_tuple $(#[$($attrs)*])*, $vis, $name, $($body)* } + }; + + (@parse_fields + $(#[$attrs:meta])*, $vis:vis, $name:ident, $($fvis:vis $fname:ident: $fty:ty),* $(,)*) => { + $(#[$attrs])* $vis struct $name { $($fvis $fname: $fty,)* } + }; + + (@parse_tuple + $(#[$attrs:meta])*, $vis:vis, $name:ident, $($fvis:vis $fty:ty),* $(,)*) => { + $(#[$attrs])* $vis struct $name ( $($fvis $fty,)* ); + }; +} + +mod test_struct { + vis_parse_struct! { pub(crate) struct A { pub a: i32, b: i32, pub(crate) c: i32 } } + vis_parse_struct! { pub struct B { a: i32, pub(crate) b: i32, pub c: i32 } } + vis_parse_struct! { struct C { pub(crate) a: i32, pub b: i32, c: i32 } } + + vis_parse_struct! { pub(crate) struct D (pub i32, i32, pub(crate) i32); } + vis_parse_struct! { pub struct E (i32, pub(crate) i32, pub i32); } + vis_parse_struct! { struct F (pub(crate) i32, pub i32, i32); } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-reexport-removed.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-reexport-removed.rs new file mode 100644 index 000000000000..aa72ca82b9ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-reexport-removed.rs @@ -0,0 +1,9 @@ +// aux-build:two_macros.rs + +#![feature(macro_reexport)] // { dg-error ".E0557." "" { target *-*-* } } + +#[macro_reexport(macro_one)] // { dg-error "" "" { target *-*-* } } +extern crate two_macros; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-seq-followed-by-seq.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-seq-followed-by-seq.rs new file mode 100644 index 000000000000..2607de1ec313 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-seq-followed-by-seq.rs @@ -0,0 +1,18 @@ +// run-pass +// Test of allowing two sequences repetitions in a row, +// functionality added as byproduct of RFC amendment #1384 +// https://github.com/rust-lang/rfcs/pull/1384 + +// Old version of Rust would reject this macro definition, even though +// there are no local ambiguities (the initial `banana` and `orange` +// tokens are enough for the expander to distinguish which case is +// intended). +macro_rules! foo { + ( $(banana $a:ident)* $(orange $b:tt)* ) => { }; +} + +fn main() { + foo!( banana id1 banana id2 + orange hi orange (hello world) ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-shadowing-relaxed.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-shadowing-relaxed.rs new file mode 100644 index 000000000000..4394c59d4c2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-shadowing-relaxed.rs @@ -0,0 +1,26 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:macro-in-other-crate.rs + +#![feature(decl_macro)] + +macro_rules! my_include {() => { + // Outer + macro m() {} + #[macro_use(from_prelude)] extern crate macro_in_other_crate; + + fn inner() { + // Inner + macro m() {} + macro_rules! from_prelude { () => {} } + + // OK, both `m` and `from_prelude` are macro-expanded, + // but no more macro-expanded than their counterpart from outer scope. + m!(); + from_prelude!(); + } +}} + +my_include!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-shadowing.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-shadowing.rs new file mode 100644 index 000000000000..2698493fa2be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-shadowing.rs @@ -0,0 +1,27 @@ +// aux-build:two_macros.rs + +#![allow(unused_macros)] + +macro_rules! foo { () => {} } +macro_rules! macro_one { () => {} } +#[macro_use(macro_two)] extern crate two_macros; + +macro_rules! m1 { () => { + macro_rules! foo { () => {} } + + #[macro_use] // { dg-error "" "" { target *-*-* } } + extern crate two_macros as __; +}} +m1!(); + +foo!(); // { dg-error ".E0659." "" { target *-*-* } } + +macro_rules! m2 { () => { + macro_rules! foo { () => {} } + foo!(); +}} +m2!(); +//^ Since `foo` is not used outside this expansion, it is not a shadowing error. + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-stability-rpass.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-stability-rpass.rs new file mode 100644 index 000000000000..2cc2dec0931f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-stability-rpass.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:unstable-macros.rs + +#![feature(unstable_macros, local_unstable)] + +#[macro_use] extern crate unstable_macros; + +#[unstable(feature = "local_unstable", issue = "none")] +macro_rules! local_unstable { () => () } + +fn main() { + unstable_macro!(); + local_unstable!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-stability.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-stability.rs new file mode 100644 index 000000000000..ec203c69d2ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-stability.rs @@ -0,0 +1,29 @@ +// aux-build:unstable-macros.rs + +#![feature(decl_macro)] +#![feature(staged_api)] +#[macro_use] extern crate unstable_macros; + +#[unstable(feature = "local_unstable", issue = "none")] +macro_rules! local_unstable { () => () } + +#[unstable(feature = "local_unstable", issue = "none")] +macro local_unstable_modern() {} + +#[stable(feature = "deprecated_macros", since = "1.0.0")] +#[rustc_deprecated(since = "1.0.0", reason = "local deprecation reason")] +#[macro_export] +macro_rules! local_deprecated{ () => () } + +fn main() { + local_unstable!(); // { dg-error ".E0658." "" { target *-*-* } } + local_unstable_modern!(); // { dg-error ".E0658." "" { target *-*-* } } + unstable_macro!(); // { dg-error ".E0658." "" { target *-*-* } } + // unstable_macro_modern!(); // ERROR use of unstable library feature 'unstable_macros' + + deprecated_macro!(); +// { dg-warning "" "" { target *-*-* } .-1 } + local_deprecated!(); +// { dg-warning "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-stmt-matchers.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-stmt-matchers.rs new file mode 100644 index 000000000000..cabab3a3614d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-stmt-matchers.rs @@ -0,0 +1,8 @@ +// build-pass (FIXME(62277): could be check-pass?) + + +fn main() { + macro_rules! m { ($s:stmt;) => { $s } } + m!(vec![].push(0);); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-stmt.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-stmt.rs new file mode 100644 index 000000000000..ab7941eb7ecb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-stmt.rs @@ -0,0 +1,32 @@ +// run-pass +macro_rules! myfn { + ( $f:ident, ( $( $x:ident ),* ), $body:block ) => ( + fn $f( $( $x : isize),* ) -> isize $body + ) +} + +myfn!(add, (a,b), { return a+b; } ); + +pub fn main() { + + macro_rules! mylet { + ($x:ident, $val:expr) => ( + let $x = $val; + ) + } + + mylet!(y, 8*2); + assert_eq!(y, 16); + + myfn!(mult, (a,b), { a*b } ); + + assert_eq!(mult(2, add(4,4)), 16); + + macro_rules! actually_an_expr_macro { + () => ( 16 ) + } + + assert_eq!({ actually_an_expr_macro!() }, 16); + +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-stmt_macro_in_expr_macro.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-stmt_macro_in_expr_macro.rs new file mode 100644 index 000000000000..8dd5abf924ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-stmt_macro_in_expr_macro.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(dead_code)] +macro_rules! foo { + () => { + struct Bar; + struct Baz; + } +} + +macro_rules! grault { + () => {{ + foo!(); + struct Xyzzy; + 0 + }} +} + +fn main() { + let x = grault!(); + assert_eq!(x, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-tt-followed-by-seq.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-tt-followed-by-seq.rs new file mode 100644 index 000000000000..d40ee0c974fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-tt-followed-by-seq.rs @@ -0,0 +1,28 @@ +// run-pass +// Regression test for issue #25436: permit token-trees to be followed +// by sequences, enabling more general parsing. + +use self::Join::*; + +#[derive(Debug)] +enum Join { + Keep(A,B), + Skip(A,B), +} + +macro_rules! parse_list { + ( < $a:expr; > $($b:tt)* ) => { Keep(parse_item!($a),parse_list!($($b)*)) }; + ( $a:tt $($b:tt)* ) => { Skip(parse_item!($a), parse_list!($($b)*)) }; + ( ) => { () }; +} + +macro_rules! parse_item { + ( $x:expr ) => { $x } +} + +fn main() { + let list = parse_list!(<1;> 2 <3;> 4); + assert_eq!("Keep(1, Skip(2, Keep(3, Skip(4, ()))))", + format!("{:?}", list)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-tt-matchers.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-tt-matchers.rs new file mode 100644 index 000000000000..3e21a1678cb5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-tt-matchers.rs @@ -0,0 +1,12 @@ +// build-pass (FIXME(62277): could be check-pass?) +#![allow(dead_code)] + +macro_rules! foo { + ($x:tt) => (type Alias = $x;) +} + +foo!(Box); + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-use-all-and-none.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-use-all-and-none.rs new file mode 100644 index 000000000000..0e70a4840e00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-use-all-and-none.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:two_macros-rpass.rs + +#![warn(unused_attributes)] + +#[macro_use] +#[macro_use()] // { dg-warning "" "" { target *-*-* } } +extern crate two_macros_rpass; + +pub fn main() { + macro_one!(); + macro_two!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-use-all.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-use-all.rs new file mode 100644 index 000000000000..00decf6c15c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-use-all.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:two_macros.rs + +#[macro_use] +extern crate two_macros; + +pub fn main() { + macro_one!(); + macro_two!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-use-bad-args-1.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-use-bad-args-1.rs new file mode 100644 index 000000000000..456b55e6d9aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-use-bad-args-1.rs @@ -0,0 +1,7 @@ +#![no_std] + +#[macro_use(foo(bar))] // { dg-error ".E0466." "" { target *-*-* } } +extern crate std; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-use-bad-args-2.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-use-bad-args-2.rs new file mode 100644 index 000000000000..07540d0d325c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-use-bad-args-2.rs @@ -0,0 +1,7 @@ +#![no_std] + +#[macro_use(foo="bar")] // { dg-error ".E0466." "" { target *-*-* } } +extern crate std; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-use-both.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-use-both.rs new file mode 100644 index 000000000000..7f32ef9198c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-use-both.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:two_macros.rs + +#[macro_use(macro_one, macro_two)] +extern crate two_macros; + +pub fn main() { + macro_one!(); + macro_two!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-use-one.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-use-one.rs new file mode 100644 index 000000000000..4d1936f182e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-use-one.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:two_macros.rs + +#[macro_use(macro_two)] +extern crate two_macros; + +pub fn main() { + macro_two!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-use-scope.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-use-scope.rs new file mode 100644 index 000000000000..6fc06e033f7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-use-scope.rs @@ -0,0 +1,23 @@ +// aux-build:two_macros.rs + +// build-pass (FIXME(62277): could be check-pass?) +#![allow(unused)] + +fn f() { + let _ = macro_one!(); +} +#[macro_use(macro_one)] // Check that this macro is usable in the above function +extern crate two_macros; + +fn g() { + macro_two!(); +} +macro_rules! m { () => { + #[macro_use(macro_two)] // Check that this macro is usable in the above function + extern crate two_macros as _two_macros; +} } +m!(); + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-use-undef.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-use-undef.rs new file mode 100644 index 000000000000..e0c41c08adf7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-use-undef.rs @@ -0,0 +1,9 @@ +// aux-build:two_macros.rs + +#[macro_use(macro_two, no_way)] // { dg-error ".E0469." "" { target *-*-* } } +extern crate two_macros; + +pub fn main() { + macro_two!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-use-wrong-name.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-use-wrong-name.rs new file mode 100644 index 000000000000..dfc73c486688 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-use-wrong-name.rs @@ -0,0 +1,10 @@ +// aux-build:two_macros.rs + +#[macro_use(macro_one)] +extern crate two_macros; + +pub fn main() { + macro_two!(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-with-attrs1.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-with-attrs1.rs new file mode 100644 index 000000000000..20ea3f41bd2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-with-attrs1.rs @@ -0,0 +1,14 @@ +// run-pass +// compile-flags: --cfg foo + + +#[cfg(foo)] +macro_rules! foo { () => (1) } + +#[cfg(not(foo))] +macro_rules! foo { () => (2) } + +pub fn main() { + assert_eq!(foo!(), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-with-attrs2.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-with-attrs2.rs new file mode 100644 index 000000000000..df88ede1afee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-with-attrs2.rs @@ -0,0 +1,12 @@ +// run-pass + +#[cfg(foo)] +macro_rules! foo { () => (1) } + +#[cfg(not(foo))] +macro_rules! foo { () => (2) } + +pub fn main() { + assert_eq!(foo!(), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro-with-braces-in-expr-position.rs b/gcc/testsuite/rust/rustc/ui/macros/macro-with-braces-in-expr-position.rs new file mode 100644 index 000000000000..7b8ab3fff148 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro-with-braces-in-expr-position.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +use std::thread; + +macro_rules! expr { ($e: expr) => { $e } } + +macro_rules! spawn { + ($($code: tt)*) => { + expr!(thread::spawn(move|| {$($code)*}).join()) + } +} + +pub fn main() { + spawn! { + println!("stmt"); + }; + let _ = spawn! { + println!("expr"); + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro_path_as_generic_bound.rs b/gcc/testsuite/rust/rustc/ui/macros/macro_path_as_generic_bound.rs new file mode 100644 index 000000000000..04428ba6ecc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro_path_as_generic_bound.rs @@ -0,0 +1,10 @@ +trait Foo {} + +macro_rules! foo(($t:path) => { + impl Foo for T {} +}); + +foo!(m::m2::A); // { dg-error ".E0433." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro_undefined.rs b/gcc/testsuite/rust/rustc/ui/macros/macro_undefined.rs new file mode 100644 index 000000000000..80c4dc7860e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro_undefined.rs @@ -0,0 +1,14 @@ +// Test macro_undefined issue + +mod m { + #[macro_export] + macro_rules! kl { + () => () + } +} + +fn main() { + k!(); // { dg-error "" "" { target *-*-* } } + kl!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macro_with_super_2.rs b/gcc/testsuite/rust/rustc/ui/macros/macro_with_super_2.rs new file mode 100644 index 000000000000..ad93bb598369 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macro_with_super_2.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:macro_with_super_1.rs + +// pretty-expanded FIXME #23616 + +#[macro_use] +extern crate macro_with_super_1; + +declare!(); + +fn main() { + bbb::ccc(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macros-in-extern.rs b/gcc/testsuite/rust/rustc/ui/macros/macros-in-extern.rs new file mode 100644 index 000000000000..5fb40f9d0fdd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macros-in-extern.rs @@ -0,0 +1,46 @@ +// run-pass +// ignore-wasm32 + +#![feature(decl_macro)] + +macro_rules! returns_isize( + ($ident:ident) => ( + fn $ident() -> isize; + ) +); + +macro takes_u32_returns_u32($ident:ident) { + fn $ident (arg: u32) -> u32; +} + +macro_rules! emits_nothing( + () => () +); + +macro_rules! emits_multiple( + () => { + fn f1() -> u32; + fn f2() -> u32; + } +); + +mod defs { + #[no_mangle] extern fn f1() -> u32 { 1 } + #[no_mangle] extern fn f2() -> u32 { 2 } +} + +fn main() { + assert_eq!(unsafe { rust_get_test_int() }, 1); + assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEFu32); + assert_eq!(unsafe { f1() }, 1); + assert_eq!(unsafe { f2() }, 2); +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + returns_isize!(rust_get_test_int); + takes_u32_returns_u32!(rust_dbg_extern_identity_u32); + emits_nothing!(); + emits_multiple!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/macros-nonfatal-errors.rs b/gcc/testsuite/rust/rustc/ui/macros/macros-nonfatal-errors.rs new file mode 100644 index 000000000000..322b0c599ad1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/macros-nonfatal-errors.rs @@ -0,0 +1,34 @@ +// normalize-stderr-test: "existed:.*\(" -> "existed: $$FILE_NOT_FOUND_MSG (" + +// test that errors in a (selection) of macros don't kill compilation +// immediately, so that we get more errors listed at a time. + +#![feature(asm, llvm_asm)] +#![feature(trace_macros, concat_idents)] + +#[derive(Default)] // { dg-error ".E0665." "" { target *-*-* } } +enum OrDeriveThis {} + +fn main() { + asm!(invalid); // { dg-error "" "" { target *-*-* } } + llvm_asm!(invalid); // { dg-error "" "" { target *-*-* } } + + concat_idents!("not", "idents"); // { dg-error "" "" { target *-*-* } } + + option_env!(invalid); // { dg-error "" "" { target *-*-* } } + env!(invalid); // { dg-error "" "" { target *-*-* } } + env!(foo, abr, baz); // { dg-error "" "" { target *-*-* } } + env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST"); // { dg-error "" "" { target *-*-* } } + + format!(invalid); // { dg-error "" "" { target *-*-* } } + + include!(invalid); // { dg-error "" "" { target *-*-* } } + + include_str!(invalid); // { dg-error "" "" { target *-*-* } } + include_str!("i'd be quite surprised if a file with this name existed"); // { dg-error "" "" { target *-*-* } } + include_bytes!(invalid); // { dg-error "" "" { target *-*-* } } + include_bytes!("i'd be quite surprised if a file with this name existed"); // { dg-error "" "" { target *-*-* } } + + trace_macros!(invalid); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/meta-item-absolute-path.rs b/gcc/testsuite/rust/rustc/ui/macros/meta-item-absolute-path.rs new file mode 100644 index 000000000000..593baced4eb2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/meta-item-absolute-path.rs @@ -0,0 +1,6 @@ +#[derive(::Absolute)] // { dg-error ".E0433." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +struct S; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/meta-variable-misuse.rs b/gcc/testsuite/rust/rustc/ui/macros/meta-variable-misuse.rs new file mode 100644 index 000000000000..b19e393e3eb7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/meta-variable-misuse.rs @@ -0,0 +1,35 @@ +// run-pass +#![deny(meta_variable_misuse)] + +macro_rules! foo { + ($($m:ident $($f:ident $v:tt)+),*) => { + $($(macro_rules! $f { () => { $v } })+)* + $(macro_rules! $m { () => { $(fn $f() -> i32 { $v })+ } })* + } +} + +foo!(m a 1 b 2, n c 3); +m!(); +n!(); + +macro_rules! no_shadow { + ($x:tt) => { macro_rules! bar { ($x:tt) => { 42 }; } }; +} +no_shadow!(z); + +macro_rules! make_plus { + ($n: ident $x:expr) => { macro_rules! $n { ($y:expr) => { $x + $y }; } }; +} +make_plus!(add3 3); + +fn main() { + assert_eq!(a!(), 1); + assert_eq!(b!(), 2); + assert_eq!(c!(), 3); + assert_eq!(a(), 1); + assert_eq!(b(), 2); + assert_eq!(c(), 3); + assert_eq!(bar!(z:tt), 42); + assert_eq!(add3!(9), 12); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/missing-comma.rs b/gcc/testsuite/rust/rustc/ui/macros/missing-comma.rs new file mode 100644 index 000000000000..de44bbc519fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/missing-comma.rs @@ -0,0 +1,35 @@ +macro_rules! foo { + ($a:ident) => (); + ($a:ident, $b:ident) => (); + ($a:ident, $b:ident, $c:ident) => (); + ($a:ident, $b:ident, $c:ident, $d:ident) => (); + ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => (); +} + +macro_rules! bar { + ($lvl:expr, $($arg:tt)+) => {} +} + +macro_rules! check { + ($ty:ty, $expected:expr) => {}; + ($ty_of:expr, $expected:expr) => {}; +} + +fn main() { + println!("{}" a); +// { dg-error "" "" { target *-*-* } .-1 } + foo!(a b); +// { dg-error "" "" { target *-*-* } .-1 } + foo!(a, b, c, d e); +// { dg-error "" "" { target *-*-* } .-1 } + foo!(a, b, c d, e); +// { dg-error "" "" { target *-*-* } .-1 } + foo!(a, b, c d e); +// { dg-error "" "" { target *-*-* } .-1 } + bar!(Level::Error, ); +// { dg-error "" "" { target *-*-* } .-1 } + check!(::fmt, "fmt"); + check!(::fmt, "fmt",); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/must-use-in-macro-55516.rs b/gcc/testsuite/rust/rustc/ui/macros/must-use-in-macro-55516.rs new file mode 100644 index 000000000000..e564f4521be9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/must-use-in-macro-55516.rs @@ -0,0 +1,11 @@ +// check-pass +// compile-flags: -Wunused + +// make sure write!() can't hide its unused Result + +fn main() { + use std::fmt::Write; + let mut example = String::new(); + write!(&mut example, "{}", 42); // { dg-warning "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/nonterminal-matching.rs b/gcc/testsuite/rust/rustc/ui/macros/nonterminal-matching.rs new file mode 100644 index 000000000000..7a519bcd57bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/nonterminal-matching.rs @@ -0,0 +1,27 @@ +// Check that we are refusing to match on complex nonterminals for which tokens are +// unavailable and we'd have to go through AST comparisons. + +#![feature(decl_macro)] + +macro simple_nonterminal($nt_ident: ident, $nt_lifetime: lifetime, $nt_tt: tt) { + macro n(a $nt_ident b $nt_lifetime c $nt_tt d) { + struct S; + } + + n!(a $nt_ident b $nt_lifetime c $nt_tt d); +} + +macro complex_nonterminal($nt_item: item) { + macro n(a $nt_item b) { + struct S; + } + + n!(a $nt_item b); // { dg-error "" "" { target *-*-* } } +} + +simple_nonterminal!(a, 'a, (x, y, z)); // OK + +complex_nonterminal!(enum E {}); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/parse-complex-macro-invoc-op.rs b/gcc/testsuite/rust/rustc/ui/macros/parse-complex-macro-invoc-op.rs new file mode 100644 index 000000000000..9e15db100305 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/parse-complex-macro-invoc-op.rs @@ -0,0 +1,43 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(dead_code)] +#![allow(unused_assignments)] +#![allow(unused_variables)] +#![allow(stable_features)] + +// Test parsing binary operators after macro invocations. + +// pretty-expanded FIXME #23616 + +#![feature(macro_rules)] + +macro_rules! id { + ($e: expr) => { $e } +} + +fn foo() { + id!(1) + 1; + id![1] - 1; + id!(1) * 1; + id![1] / 1; + id!(1) % 1; + + id!(1) & 1; + id![1] | 1; + id!(1) ^ 1; + + let mut x = 1; + id![x] = 2; + id!(x) += 1; + + id!(1f64).clone(); + + id!([1, 2, 3])[1]; + id![drop](1); + + id!(true) && true; + id![true] || true; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/paths-in-macro-invocations.rs b/gcc/testsuite/rust/rustc/ui/macros/paths-in-macro-invocations.rs new file mode 100644 index 000000000000..c6b89c3b0a30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/paths-in-macro-invocations.rs @@ -0,0 +1,37 @@ +// run-pass +#![allow(dead_code)] +// aux-build:two_macros-rpass.rs + +extern crate two_macros_rpass as two_macros; + +::two_macros::macro_one!(); +two_macros::macro_one!(); + +mod foo { pub use two_macros::macro_one as bar; } + +trait T { + foo::bar!(); + ::foo::bar!(); +} + +struct S { + x: foo::bar!(i32), + y: ::foo::bar!(i32), +} + +impl S { + foo::bar!(); + ::foo::bar!(); +} + +fn main() { + foo::bar!(); + ::foo::bar!(); + + let _ = foo::bar!(0); + let _ = ::foo::bar!(0); + + let foo::bar!(_) = 0; + let ::foo::bar!(_) = 0; +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/pub-item-inside-macro.rs b/gcc/testsuite/rust/rustc/ui/macros/pub-item-inside-macro.rs new file mode 100644 index 000000000000..d1374b0fa2bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/pub-item-inside-macro.rs @@ -0,0 +1,19 @@ +// run-pass +// Issue #14660 + +// pretty-expanded FIXME #23616 + +mod bleh { + macro_rules! foo { + () => { + pub fn bar() { } + } + } + + foo!(); +} + +fn main() { + bleh::bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/pub-method-inside-macro.rs b/gcc/testsuite/rust/rustc/ui/macros/pub-method-inside-macro.rs new file mode 100644 index 000000000000..35f5aed62442 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/pub-method-inside-macro.rs @@ -0,0 +1,23 @@ +// run-pass +// Issue #17436 + +// pretty-expanded FIXME #23616 + +mod bleh { + macro_rules! foo { + () => { + pub fn bar(&self) { } + } + } + + pub struct S; + + impl S { + foo!(); + } +} + +fn main() { + bleh::S.bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/restricted-shadowing-legacy.rs b/gcc/testsuite/rust/rustc/ui/macros/restricted-shadowing-legacy.rs new file mode 100644 index 000000000000..53a047fe56bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/restricted-shadowing-legacy.rs @@ -0,0 +1,290 @@ +// Legend: +// `N` - number of combination, from 0 to 4*4*4=64 +// `Outer < Invoc` means that expansion that produced macro definition `Outer` +// is a strict ancestor of expansion that produced macro definition `Inner`. +// `>`, `=` and `Unordered` mean "strict descendant", "same" and +// "not in ordering relation" for parent expansions. +// `+` - possible configuration +// `-` - configuration impossible due to properties of partial ordering +// `-?` - configuration impossible due to block/scope syntax +// `+?` - configuration possible only with legacy scoping + +// N | Outer ~ Invoc | Invoc ~ Inner | Outer ~ Inner | Possible | +// 1 | < | < | < | + | +// 2 | < | < | = | - | +// 3 | < | < | > | - | +// 4 | < | < | Unordered | - | +// 5 | < | = | < | + | +// 6 | < | = | = | - | +// 7 | < | = | > | - | +// 8 | < | = | Unordered | - | +// 9 | < | > | < | + | +// 10 | < | > | = | + | +// 11 | < | > | > | -? | +// 12 | < | > | Unordered | -? | +// 13 | < | Unordered | < | + | +// 14 | < | Unordered | = | - | +// 15 | < | Unordered | > | - | +// 16 | < | Unordered | Unordered | -? | +// 17 | = | < | < | + | +// 18 | = | < | = | - | +// 19 | = | < | > | - | +// 20 | = | < | Unordered | - | +// 21 | = | = | < | - | +// 22 | = | = | = | + | +// 23 | = | = | > | - | +// 24 | = | = | Unordered | - | +// 25 | = | > | < | - | +// 26 | = | > | = | - | +// 27 | = | > | > | -? | +// 28 | = | > | Unordered | - | +// 29 | = | Unordered | < | - | +// 30 | = | Unordered | = | - | +// 31 | = | Unordered | > | - | +// 32 | = | Unordered | Unordered | -? | +// 33 | > | < | < | +? | +// 34 | > | < | = | +? | +// 35 | > | < | > | +? | +// 36 | > | < | Unordered | + | +// 37 | > | = | < | - | +// 38 | > | = | = | - | +// 39 | > | = | > | + | +// 40 | > | = | Unordered | - | +// 41 | > | > | < | - | +// 42 | > | > | = | - | +// 43 | > | > | > | -? | +// 44 | > | > | Unordered | - | +// 45 | > | Unordered | < | - | +// 46 | > | Unordered | = | - | +// 47 | > | Unordered | > | -? | +// 48 | > | Unordered | Unordered | -? | +// 49 | Unordered | < | < | -? | +// 50 | Unordered | < | = | - | +// 51 | Unordered | < | > | - | +// 52 | Unordered | < | Unordered | + | +// 53 | Unordered | = | < | - | +// 54 | Unordered | = | = | - | +// 55 | Unordered | = | > | - | +// 56 | Unordered | = | Unordered | + | +// 57 | Unordered | > | < | - | +// 58 | Unordered | > | = | - | +// 59 | Unordered | > | > | + | +// 60 | Unordered | > | Unordered | + | +// 61 | Unordered | Unordered | < | +? | +// 62 | Unordered | Unordered | = | +? | +// 63 | Unordered | Unordered | > | +? | +// 64 | Unordered | Unordered | Unordered | + | + +#![feature(decl_macro, rustc_attrs)] + +struct Right; +// struct Wrong; // not defined + +macro_rules! include { () => { + macro_rules! gen_outer { () => { + macro_rules! m { () => { Wrong } } + }} + macro_rules! gen_inner { () => { + macro_rules! m { () => { Right } } + }} + macro_rules! gen_invoc { () => { + m!() + }} + + // ----------------------------------------------------------- + + fn check1() { + macro_rules! m { () => {} } + + macro_rules! gen_gen_inner_invoc { () => { + gen_inner!(); + m!(); // { dg-error ".E0659." "" { target *-*-* } } + }} + gen_gen_inner_invoc!(); + } + + fn check5() { + macro_rules! m { () => { Wrong } } + + macro_rules! gen_inner_invoc { () => { + macro_rules! m { () => { Right } } + m!(); // OK + }} + gen_inner_invoc!(); + } + + fn check9() { + macro_rules! m { () => { Wrong } } + + macro_rules! gen_inner_gen_invoc { () => { + macro_rules! m { () => { Right } } + gen_invoc!(); // OK + }} + gen_inner_gen_invoc!(); + } + + fn check10() { + macro_rules! m { () => { Wrong } } + + macro_rules! m { () => { Right } } + + gen_invoc!(); // OK + } + + fn check13() { + macro_rules! m { () => {} } + + gen_inner!(); + + macro_rules! gen_invoc { () => { m!() } } // { dg-error ".E0659." "" { target *-*-* } } + gen_invoc!(); + } + + fn check17() { + macro_rules! m { () => {} } + + gen_inner!(); + + m!(); // { dg-error ".E0659." "" { target *-*-* } } + } + + fn check22() { + macro_rules! m { () => { Wrong } } + + macro_rules! m { () => { Right } } + + m!(); // OK + } + + fn check36() { + gen_outer!(); + + gen_inner!(); + + m!(); // { dg-error ".E0659." "" { target *-*-* } } + } + + fn check39() { + gen_outer!(); + + macro_rules! m { () => { Right } } + + m!(); // OK + } + + fn check52() { + gen_outer!(); + + macro_rules! gen_gen_inner_invoc { () => { + gen_inner!(); + m!(); // { dg-error ".E0659." "" { target *-*-* } } + }} + gen_gen_inner_invoc!(); + } + + fn check56() { + gen_outer!(); + + macro_rules! gen_inner_invoc { () => { + macro_rules! m { () => { Right } } + m!(); // OK + }} + gen_inner_invoc!(); + } + + fn check59() { + gen_outer!(); + + macro_rules! m { () => { Right } } + + gen_invoc!(); // OK + } + + fn check60() { + gen_outer!(); + + macro_rules! gen_inner_gen_invoc { () => { + macro_rules! m { () => { Right } } + gen_invoc!(); // OK + }} + gen_inner_gen_invoc!(); + } + + fn check64() { + gen_outer!(); + + gen_inner!(); + + macro_rules! gen_invoc { () => { m!() } } // { dg-error ".E0659." "" { target *-*-* } } + gen_invoc!(); + } + + // ----------------------------------------------------------- + // These configurations are only possible with legacy macro scoping + + fn check33() { + macro_rules! gen_outer_gen_inner { () => { + macro_rules! m { () => {} } + gen_inner!(); + }} + gen_outer_gen_inner!(); + + m!(); // { dg-error ".E0659." "" { target *-*-* } } + } + + fn check34() { + macro_rules! gen_outer_inner { () => { + macro_rules! m { () => { Wrong } } + macro_rules! m { () => { Right } } + }} + gen_outer_inner!(); + + m!(); // OK + } + + fn check35() { + macro_rules! gen_gen_outer_inner { () => { + gen_outer!(); + macro_rules! m { () => { Right } } + }} + gen_gen_outer_inner!(); + + m!(); // OK + } + + fn check61() { + macro_rules! gen_outer_gen_inner { () => { + macro_rules! m { () => {} } + gen_inner!(); + }} + gen_outer_gen_inner!(); + + macro_rules! gen_invoc { () => { m!() } } // { dg-error ".E0659." "" { target *-*-* } } + gen_invoc!(); + } + + fn check62() { + macro_rules! gen_outer_inner { () => { + macro_rules! m { () => { Wrong } } + macro_rules! m { () => { Right } } + }} + gen_outer_inner!(); + + gen_invoc!(); // OK + } + + fn check63() { + macro_rules! gen_gen_outer_inner { () => { + gen_outer!(); + macro_rules! m { () => { Right } } + }} + gen_gen_outer_inner!(); + + gen_invoc!(); // OK + } +}} + +include!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/restricted-shadowing-modern.rs b/gcc/testsuite/rust/rustc/ui/macros/restricted-shadowing-modern.rs new file mode 100644 index 000000000000..3a23ad611a2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/restricted-shadowing-modern.rs @@ -0,0 +1,242 @@ +// Legend: +// `N` - number of combination, from 0 to 4*4*4=64 +// `Outer < Invoc` means that expansion that produced macro definition `Outer` +// is a strict ancestor of expansion that produced macro definition `Inner`. +// `>`, `=` and `Unordered` mean "strict descendant", "same" and +// "not in ordering relation" for parent expansions. +// `+` - possible configuration +// `-` - configuration impossible due to properties of partial ordering +// `-?` - configuration impossible due to block/scope syntax +// `+?` - configuration possible only with legacy scoping + +// N | Outer ~ Invoc | Invoc ~ Inner | Outer ~ Inner | Possible | +// 1 | < | < | < | + | +// 2 | < | < | = | - | +// 3 | < | < | > | - | +// 4 | < | < | Unordered | - | +// 5 | < | = | < | + | +// 6 | < | = | = | - | +// 7 | < | = | > | - | +// 8 | < | = | Unordered | - | +// 9 | < | > | < | + | +// 10 | < | > | = | + | +// 11 | < | > | > | -? | +// 12 | < | > | Unordered | -? | +// 13 | < | Unordered | < | + | +// 14 | < | Unordered | = | - | +// 15 | < | Unordered | > | - | +// 16 | < | Unordered | Unordered | -? | +// 17 | = | < | < | + | +// 18 | = | < | = | - | +// 19 | = | < | > | - | +// 20 | = | < | Unordered | - | +// 21 | = | = | < | - | +// 22 | = | = | = | + | +// 23 | = | = | > | - | +// 24 | = | = | Unordered | - | +// 25 | = | > | < | - | +// 26 | = | > | = | - | +// 27 | = | > | > | -? | +// 28 | = | > | Unordered | - | +// 29 | = | Unordered | < | - | +// 30 | = | Unordered | = | - | +// 31 | = | Unordered | > | - | +// 32 | = | Unordered | Unordered | -? | +// 33 | > | < | < | -? | +// 34 | > | < | = | -? | +// 35 | > | < | > | -? | +// 36 | > | < | Unordered | + | +// 37 | > | = | < | - | +// 38 | > | = | = | - | +// 39 | > | = | > | + | +// 40 | > | = | Unordered | - | +// 41 | > | > | < | - | +// 42 | > | > | = | - | +// 43 | > | > | > | -? | +// 44 | > | > | Unordered | - | +// 45 | > | Unordered | < | - | +// 46 | > | Unordered | = | - | +// 47 | > | Unordered | > | -? | +// 48 | > | Unordered | Unordered | -? | +// 49 | Unordered | < | < | -? | +// 50 | Unordered | < | = | - | +// 51 | Unordered | < | > | - | +// 52 | Unordered | < | Unordered | + | +// 53 | Unordered | = | < | - | +// 54 | Unordered | = | = | - | +// 55 | Unordered | = | > | - | +// 56 | Unordered | = | Unordered | + | +// 57 | Unordered | > | < | - | +// 58 | Unordered | > | = | - | +// 59 | Unordered | > | > | + | +// 60 | Unordered | > | Unordered | + | +// 61 | Unordered | Unordered | < | -? | +// 62 | Unordered | Unordered | = | -? | +// 63 | Unordered | Unordered | > | -? | +// 64 | Unordered | Unordered | Unordered | + | + +#![feature(decl_macro, rustc_attrs)] + +struct Right; +// struct Wrong; // not defined + +#[rustc_macro_transparency = "transparent"] +macro include() { + #[rustc_macro_transparency = "transparent"] + macro gen_outer() { + macro m() { Wrong } + } + #[rustc_macro_transparency = "transparent"] + macro gen_inner() { + macro m() { Right } + } + #[rustc_macro_transparency = "transparent"] + macro gen_invoc() { + m!() + } + + fn check1() { + macro m() {} + { + #[rustc_macro_transparency = "transparent"] + macro gen_gen_inner_invoc() { + gen_inner!(); + m!(); // { dg-error ".E0659." "" { target *-*-* } } + } + gen_gen_inner_invoc!(); + } + } + + fn check5() { + macro m() { Wrong } + { + #[rustc_macro_transparency = "transparent"] + macro gen_inner_invoc() { + macro m() { Right } + m!(); // OK + } + gen_inner_invoc!(); + } + } + + fn check9() { + macro m() { Wrong } + { + #[rustc_macro_transparency = "transparent"] + macro gen_inner_gen_invoc() { + macro m() { Right } + gen_invoc!(); // OK + } + gen_inner_gen_invoc!(); + } + } + + fn check10() { + macro m() { Wrong } + { + macro m() { Right } + gen_invoc!(); // OK + } + } + + fn check13() { + macro m() {} + { + gen_inner!(); + #[rustc_macro_transparency = "transparent"] + macro gen_invoc() { m!() } // { dg-error ".E0659." "" { target *-*-* } } + gen_invoc!(); + } + } + + fn check17() { + macro m() {} + { + gen_inner!(); + m!(); // { dg-error ".E0659." "" { target *-*-* } } + } + } + + fn check22() { + macro m() { Wrong } + { + macro m() { Right } + m!(); // OK + } + } + + fn check36() { + gen_outer!(); + { + gen_inner!(); + m!(); // { dg-error ".E0659." "" { target *-*-* } } + } + } + + fn check39() { + gen_outer!(); + { + macro m() { Right } + m!(); // OK + } + } + + fn check52() { + gen_outer!(); + { + #[rustc_macro_transparency = "transparent"] + macro gen_gen_inner_invoc() { + gen_inner!(); + m!(); // { dg-error ".E0659." "" { target *-*-* } } + } + gen_gen_inner_invoc!(); + } + } + + fn check56() { + gen_outer!(); + { + #[rustc_macro_transparency = "transparent"] + macro gen_inner_invoc() { + macro m() { Right } + m!(); // OK + } + gen_inner_invoc!(); + } + } + + fn check59() { + gen_outer!(); + { + macro m() { Right } + gen_invoc!(); // OK + } + } + + fn check60() { + gen_outer!(); + { + #[rustc_macro_transparency = "transparent"] + macro gen_inner_gen_invoc() { + macro m() { Right } + gen_invoc!(); // OK + } + gen_inner_gen_invoc!(); + } + } + + fn check64() { + gen_outer!(); + { + gen_inner!(); + #[rustc_macro_transparency = "transparent"] + macro gen_invoc() { m!() } // { dg-error ".E0659." "" { target *-*-* } } + gen_invoc!(); + } + } +} + +include!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/same-sequence-span.rs b/gcc/testsuite/rust/rustc/ui/macros/same-sequence-span.rs new file mode 100644 index 000000000000..ed12800005eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/same-sequence-span.rs @@ -0,0 +1,23 @@ +// aux-build:proc_macro_sequence.rs + +// Regression test for issue #62831: Check that multiple sequences with the same span in the +// left-hand side of a macro definition behave as if they had unique spans, and in particular that +// they don't crash the compiler. + +#![allow(unused_macros)] + +extern crate proc_macro_sequence; + +// When ignoring spans, this macro has the same macro definition as `generated_foo` in +// `proc_macro_sequence.rs`. +macro_rules! manual_foo { + (1 $x:expr $($y:tt,)* // { dg-error "" "" { target *-*-* } } + $(= $z:tt)* // { dg-error "" "" { target *-*-* } } + ) => {}; +} + +proc_macro_sequence::make_foo!(); // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/semi-after-macro-ty.rs b/gcc/testsuite/rust/rustc/ui/macros/semi-after-macro-ty.rs new file mode 100644 index 000000000000..b518fde9d9a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/semi-after-macro-ty.rs @@ -0,0 +1,9 @@ +// run-pass +macro_rules! foo { + ($t:ty; $p:path;) => {} +} + +fn main() { + foo!(i32; i32;); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/span-covering-argument-1.rs b/gcc/testsuite/rust/rustc/ui/macros/span-covering-argument-1.rs new file mode 100644 index 000000000000..b4b5ea57c189 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/span-covering-argument-1.rs @@ -0,0 +1,14 @@ +macro_rules! bad { + ($s:ident whatever) => { + { + let $s = 0; + *&mut $s = 0; +// { dg-error ".E0596." "" { target *-*-* } .-1 } + } + } +} + +fn main() { + bad!(foo whatever); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/stmt_expr_attr_macro_parse.rs b/gcc/testsuite/rust/rustc/ui/macros/stmt_expr_attr_macro_parse.rs new file mode 100644 index 000000000000..068973e11b70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/stmt_expr_attr_macro_parse.rs @@ -0,0 +1,24 @@ +// run-pass +macro_rules! m { + ($e:expr) => { + "expr includes attr" + }; + (#[$attr:meta] $e:expr) => { + "expr excludes attr" + } +} + +macro_rules! n { + (#[$attr:meta] $e:expr) => { + "expr excludes attr" + }; + ($e:expr) => { + "expr includes attr" + } +} + +fn main() { + assert_eq!(m!(#[attr] 1), "expr includes attr"); + assert_eq!(n!(#[attr] 1), "expr excludes attr"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/syntax-extension-cfg.rs b/gcc/testsuite/rust/rustc/ui/macros/syntax-extension-cfg.rs new file mode 100644 index 000000000000..c7c9ad6aa844 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/syntax-extension-cfg.rs @@ -0,0 +1,25 @@ +// run-pass +// compile-flags: --cfg foo --cfg qux="foo" + + +pub fn main() { + // check + if ! cfg!(foo) { panic!() } + if cfg!(not(foo)) { panic!() } + + if ! cfg!(qux="foo") { panic!() } + if cfg!(not(qux="foo")) { panic!() } + + if ! cfg!(all(foo, qux="foo")) { panic!() } + if cfg!(not(all(foo, qux="foo"))) { panic!() } + if cfg!(all(not(all(foo, qux="foo")))) { panic!() } + + if cfg!(not_a_cfg) { panic!() } + if cfg!(all(not_a_cfg, foo, qux="foo")) { panic!() } + if cfg!(all(not_a_cfg, foo, qux="foo")) { panic!() } + if ! cfg!(any(not_a_cfg, foo)) { panic!() } + + if ! cfg!(not(not_a_cfg)) { panic!() } + if ! cfg!(all(not(not_a_cfg), foo, qux="foo")) { panic!() } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/syntax-extension-source-utils.rs b/gcc/testsuite/rust/rustc/ui/macros/syntax-extension-source-utils.rs new file mode 100644 index 000000000000..215d6f7a17b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/syntax-extension-source-utils.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(stable_features)] + +// ignore-pretty issue #37195 + +pub mod m1 { + pub mod m2 { + pub fn where_am_i() -> String { + (module_path!()).to_string() + } + } +} + +macro_rules! indirect_line { () => ( line!() ) } + +pub fn main() { + assert_eq!(line!(), 17); + assert_eq!(column!(), 16); + assert_eq!(indirect_line!(), 19); + assert!((file!().ends_with("syntax-extension-source-utils.rs"))); + assert_eq!(stringify!((2*3) + 5).to_string(), "(2 * 3) + 5".to_string()); + assert!(include!("syntax-extension-source-utils-files/includeme.\ + fragment").to_string() + == "victory robot 6".to_string()); + + assert!( + include_str!("syntax-extension-source-utils-files/includeme.\ + fragment").to_string() + .starts_with("/* this is for ")); + assert!( + include_bytes!("syntax-extension-source-utils-files/includeme.fragment") + [1] == (42 as u8)); // '*' + // The Windows tests are wrapped in an extra module for some reason + assert!((m1::m2::where_am_i().ends_with("m1::m2"))); + + assert_eq!((36, "(2 * 3) + 5"), (line!(), stringify!((2*3) + 5))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/trace-macro.rs b/gcc/testsuite/rust/rustc/ui/macros/trace-macro.rs new file mode 100644 index 000000000000..fc7bbe0fd026 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/trace-macro.rs @@ -0,0 +1,7 @@ +// compile-flags: -Z trace-macros +// build-pass (FIXME(62277): could be check-pass?) + +fn main() { + println!("Hello, World!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/trace_faulty_macros.rs b/gcc/testsuite/rust/rustc/ui/macros/trace_faulty_macros.rs new file mode 100644 index 000000000000..a1933a310cb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/trace_faulty_macros.rs @@ -0,0 +1,44 @@ +// compile-flags: -Z trace-macros + +#![recursion_limit = "4"] + +macro_rules! my_faulty_macro { + () => { + my_faulty_macro!(bcd); // { dg-error "" "" { target *-*-* } } + }; +} + +macro_rules! pat_macro { + () => { + pat_macro!(A{a:a, b:0, c:_, ..}); + }; + ($a:pat) => { + $a // { dg-error "" "" { target *-*-* } } + }; +} + +macro_rules! my_recursive_macro { + () => { + my_recursive_macro!(); // { dg-error "" "" { target *-*-* } } + }; +} + +macro_rules! my_macro { + () => {}; +} + +fn main() { + my_faulty_macro!(); + my_recursive_macro!(); + test!(); + non_exisiting!(); + derive!(Debug); + let a = pat_macro!(); +} + +#[my_macro] +fn use_bang_macro_as_attr() {} + +#[derive(Debug)] // { dg-error ".E0774." "" { target *-*-* } } +fn use_derive_macro_as_attr() {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/try-macro.rs b/gcc/testsuite/rust/rustc/ui/macros/try-macro.rs new file mode 100644 index 000000000000..bd211950f725 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/try-macro.rs @@ -0,0 +1,50 @@ +// run-pass +#![allow(deprecated)] // for deprecated `try!()` macro +use std::num::{ParseFloatError, ParseIntError}; + +fn main() { + assert_eq!(simple(), Ok(1)); + assert_eq!(nested(), Ok(2)); + assert_eq!(merge_ok(), Ok(3.0)); + assert_eq!(merge_int_err(), Err(Error::Int)); + assert_eq!(merge_float_err(), Err(Error::Float)); +} + +fn simple() -> Result { + Ok(try!("1".parse())) +} + +fn nested() -> Result { + Ok(try!(try!("2".parse::()).to_string().parse::())) +} + +fn merge_ok() -> Result { + Ok(try!("1".parse::()) as f32 + try!("2.0".parse::())) +} + +fn merge_int_err() -> Result { + Ok(try!("a".parse::()) as f32 + try!("2.0".parse::())) +} + +fn merge_float_err() -> Result { + Ok(try!("1".parse::()) as f32 + try!("b".parse::())) +} + +#[derive(Debug, PartialEq)] +enum Error { + Int, + Float, +} + +impl From for Error { + fn from(_: ParseIntError) -> Error { + Error::Int + } +} + +impl From for Error { + fn from(_: ParseFloatError) -> Error { + Error::Float + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/two-macro-use.rs b/gcc/testsuite/rust/rustc/ui/macros/two-macro-use.rs new file mode 100644 index 000000000000..9cef9874d3fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/two-macro-use.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:two_macros.rs + +#[macro_use(macro_one)] +#[macro_use(macro_two)] +extern crate two_macros; + +pub fn main() { + macro_one!(); + macro_two!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/type-macros-hlist.rs b/gcc/testsuite/rust/rustc/ui/macros/type-macros-hlist.rs new file mode 100644 index 000000000000..066e8c4e0784 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/type-macros-hlist.rs @@ -0,0 +1,79 @@ +// run-pass +use std::ops::*; + +#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +struct Nil; + // empty HList +#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +struct Cons(H, T); + // cons cell of HList + + // trait to classify valid HLists +trait HList { } +impl HList for Nil { } +impl HList for Cons { } + +// term-level macro for HLists +macro_rules! hlist({ } => { Nil } ; { $ head : expr } => { + Cons ( $ head , Nil ) } ; { + $ head : expr , $ ( $ tail : expr ) , * } => { + Cons ( $ head , hlist ! ( $ ( $ tail ) , * ) ) } ;); + +// type-level macro for HLists +macro_rules! HList({ } => { Nil } ; { $ head : ty } => { + Cons < $ head , Nil > } ; { + $ head : ty , $ ( $ tail : ty ) , * } => { + Cons < $ head , HList ! ( $ ( $ tail ) , * ) > } ;); + +// nil case for HList append +impl Add for Nil { + type + Output + = + Ys; + + fn add(self, rhs: Ys) -> Ys { rhs } +} + +// cons case for HList append +impl Add for Cons + where Xs: Add { + type + Output + = + Cons; + + fn add(self, rhs: Ys) -> Cons { Cons(self.0, self.1 + rhs) } +} + +// type macro Expr allows us to expand the + operator appropriately +macro_rules! Expr({ ( $ ( $ LHS : tt ) + ) } => { Expr ! ( $ ( $ LHS ) + ) } ; + { HList ! [ $ ( $ LHS : tt ) * ] + $ ( $ RHS : tt ) + } => { + < Expr ! ( HList ! [ $ ( $ LHS ) * ] ) as Add < Expr ! ( + $ ( $ RHS ) + ) >> :: Output } ; { + $ LHS : tt + $ ( $ RHS : tt ) + } => { + < Expr ! ( $ LHS ) as Add < Expr ! ( $ ( $ RHS ) + ) >> :: + Output } ; { $ LHS : ty } => { $ LHS } ;); + +// test demonstrating term level `xs + ys` and type level `Expr!(Xs + Ys)` +fn main() { + fn aux(xs: Xs, ys: Ys) -> Expr!(Xs + Ys) where + Xs: Add { + xs + ys + } + + let xs: HList!(& str , bool , Vec < u64 >) = + hlist!("foo" , false , vec ! [ ]); + let ys: HList!(u64 , [ u8 ; 3 ] , ( )) = + hlist!(0 , [ 0 , 1 , 2 ] , ( )); + + // demonstrate recursive expansion of Expr! + let zs: + Expr!(( + HList ! [ & str ] + HList ! [ bool ] + HList ! [ Vec < u64 > + ] ) + ( HList ! [ u64 ] + HList ! [ [ u8 ; 3 ] , ( ) ] ) + + HList ! [ ]) = aux(xs, ys); + assert_eq!(zs , hlist ! [ + "foo" , false , vec ! [ ] , 0 , [ 0 , 1 , 2 ] , ( ) ]) +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/type-macros-simple.rs b/gcc/testsuite/rust/rustc/ui/macros/type-macros-simple.rs new file mode 100644 index 000000000000..dbad9e70a7ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/type-macros-simple.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +macro_rules! Tuple { + { $A:ty,$B:ty } => { ($A, $B) } +} + +fn main() { + let x: Tuple!(i32, i32) = (1, 2); +} + +fn issue_36540() { + let i32 = 0; + macro_rules! m { () => { i32 } } + struct S(m!(), T) where T: Trait; + + let x: m!() = m!(); + std::cell::Cell::::new(m!()); + impl std::ops::Index for dyn Trait<(m!(), T)> + where T: Trait + { + type Output = m!(); + fn index(&self, i: m!()) -> &m!() { + unimplemented!() + } + } +} + +trait Trait {} +impl Trait for i32 {} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/typeck-macro-interaction-issue-8852.rs b/gcc/testsuite/rust/rustc/ui/macros/typeck-macro-interaction-issue-8852.rs new file mode 100644 index 000000000000..9b34d60e31e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/typeck-macro-interaction-issue-8852.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(dead_code)] + +enum T { + A(isize), + B(f64) +} + +// after fixing #9384 and implementing hygiene for match bindings, +// this now fails because the insertion of the 'y' into the match +// doesn't cause capture. Making this macro hygienic (as I've done) +// could very well make this test case completely pointless.... + +macro_rules! test { + ($id1:ident, $id2:ident, $e:expr) => ( + fn foo(a:T, b:T) -> T { + match (a, b) { + (T::A($id1), T::A($id2)) => T::A($e), + (T::B($id1), T::B($id2)) => T::B($e), + _ => panic!() + } + } + ) +} + +test!(x,y,x + y); + +pub fn main() { + foo(T::A(1), T::A(2)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/unimplemented-macro-panic.rs b/gcc/testsuite/rust/rustc/ui/macros/unimplemented-macro-panic.rs new file mode 100644 index 000000000000..1e7ec78de00a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/unimplemented-macro-panic.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:not implemented +// ignore-emscripten no processes + +fn main() { + unimplemented!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/unknown-builtin.rs b/gcc/testsuite/rust/rustc/ui/macros/unknown-builtin.rs new file mode 100644 index 000000000000..2f1b93bfb184 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/unknown-builtin.rs @@ -0,0 +1,15 @@ +// error-pattern: attempted to define built-in macro more than once + +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! unknown { () => () } // { dg-error "" "" { target *-*-* } } + +#[rustc_builtin_macro] +macro_rules! line { () => () } // { dg-note "" "" { target *-*-* } } + +fn main() { + line!(); + std::prelude::v1::line!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/unreachable-fmt-msg.rs b/gcc/testsuite/rust/rustc/ui/macros/unreachable-fmt-msg.rs new file mode 100644 index 000000000000..c4d37686af38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/unreachable-fmt-msg.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:internal error: entered unreachable code: 6 is not prime +// ignore-emscripten no processes + +fn main() { + unreachable!("{} is not {}", 6u32, "prime"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/unreachable-macro-panic.rs b/gcc/testsuite/rust/rustc/ui/macros/unreachable-macro-panic.rs new file mode 100644 index 000000000000..b9bbad99f60c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/unreachable-macro-panic.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:internal error: entered unreachable code +// ignore-emscripten no processes + +fn main() { + unreachable!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/unreachable-static-msg.rs b/gcc/testsuite/rust/rustc/ui/macros/unreachable-static-msg.rs new file mode 100644 index 000000000000..2f3552ce884f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/unreachable-static-msg.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:internal error: entered unreachable code: uhoh +// ignore-emscripten no processes + +fn main() { + unreachable!("uhoh") +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/unreachable.rs b/gcc/testsuite/rust/rustc/ui/macros/unreachable.rs new file mode 100644 index 000000000000..b9bbad99f60c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/unreachable.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:internal error: entered unreachable code +// ignore-emscripten no processes + +fn main() { + unreachable!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/macros/use-macro-self.rs b/gcc/testsuite/rust/rustc/ui/macros/use-macro-self.rs new file mode 100644 index 000000000000..1de0a0147021 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/macros/use-macro-self.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(unused_imports)] +// aux-build:use-macro-self.rs + +#[macro_use] +extern crate use_macro_self; + +use use_macro_self::foobarius::{self}; + +fn main() { + let _: () = foobarius!(); // OK, the macro returns `()` +} + diff --git a/gcc/testsuite/rust/rustc/ui/main-wrong-location.rs b/gcc/testsuite/rust/rustc/ui/main-wrong-location.rs new file mode 100644 index 000000000000..8879c248f515 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/main-wrong-location.rs @@ -0,0 +1,7 @@ +mod m { +// { dg-error ".E0601." "" { target *-*-* } .-1 } + // An inferred main entry point (that doesn't use #[main]) + // must appear at the top of the crate + fn main() { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/main-wrong-type.rs b/gcc/testsuite/rust/rustc/ui/main-wrong-type.rs new file mode 100644 index 000000000000..e2f320af7f77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/main-wrong-type.rs @@ -0,0 +1,9 @@ +struct S { + x: isize, + y: isize, +} + +fn main(foo: S) { +// { dg-error ".E0580." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/malformed/issue-69341-malformed-derive-inert.rs b/gcc/testsuite/rust/rustc/ui/malformed/issue-69341-malformed-derive-inert.rs new file mode 100644 index 000000000000..178f379a09db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/malformed/issue-69341-malformed-derive-inert.rs @@ -0,0 +1,11 @@ +fn main() {} + +struct CLI { + #[derive(parse())] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + path: (), +// { dg-error ".E0774." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/malformed/malformed-derive-entry.rs b/gcc/testsuite/rust/rustc/ui/malformed/malformed-derive-entry.rs new file mode 100644 index 000000000000..514dfbb0e088 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/malformed/malformed-derive-entry.rs @@ -0,0 +1,15 @@ +#[derive(Copy(Bad))] +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +struct Test1; + +#[derive(Copy="bad")] +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +struct Test2; + +#[derive] // { dg-error "" "" { target *-*-* } } +struct Test4; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/malformed/malformed-interpolated.rs b/gcc/testsuite/rust/rustc/ui/malformed/malformed-interpolated.rs new file mode 100644 index 000000000000..f53ec24be013 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/malformed/malformed-interpolated.rs @@ -0,0 +1,18 @@ +#![feature(rustc_attrs)] + +macro_rules! check { + ($expr: expr) => ( + #[rustc_dummy = $expr] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + use main as _; + ); +} + +check!("0"); // OK +check!(0); // OK +check!(0u8); // { dg-error "" "" { target *-*-* } } +check!(-0); // ERROR, see above +check!(0 + 0); // ERROR, see above + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/malformed/malformed-meta-delim.rs b/gcc/testsuite/rust/rustc/ui/malformed/malformed-meta-delim.rs new file mode 100644 index 000000000000..de5f5237cf86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/malformed/malformed-meta-delim.rs @@ -0,0 +1,12 @@ +fn main() {} + +#[allow { foo_lint } ] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +fn delim_brace() {} + +#[allow [ foo_lint ] ] +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +fn delim_bracket() {} + diff --git a/gcc/testsuite/rust/rustc/ui/malformed/malformed-plugin-1.rs b/gcc/testsuite/rust/rustc/ui/malformed/malformed-plugin-1.rs new file mode 100644 index 000000000000..ab330afe1c57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/malformed/malformed-plugin-1.rs @@ -0,0 +1,6 @@ +#![feature(plugin)] +#![plugin] // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/malformed/malformed-plugin-2.rs b/gcc/testsuite/rust/rustc/ui/malformed/malformed-plugin-2.rs new file mode 100644 index 000000000000..71939e8fb86f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/malformed/malformed-plugin-2.rs @@ -0,0 +1,6 @@ +#![feature(plugin)] +#![plugin="bleh"] // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/malformed/malformed-plugin-3.rs b/gcc/testsuite/rust/rustc/ui/malformed/malformed-plugin-3.rs new file mode 100644 index 000000000000..ae7012e01d56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/malformed/malformed-plugin-3.rs @@ -0,0 +1,6 @@ +#![feature(plugin)] +#![plugin(foo="bleh")] // { dg-error ".E0498." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/malformed/malformed-regressions.rs b/gcc/testsuite/rust/rustc/ui/malformed/malformed-regressions.rs new file mode 100644 index 000000000000..5b824a713067 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/malformed/malformed-regressions.rs @@ -0,0 +1,13 @@ +#[doc] // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +#[ignore()] // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +#[inline = ""] // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +#[link] // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +#[link = ""] // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/malformed/malformed-special-attrs.rs b/gcc/testsuite/rust/rustc/ui/malformed/malformed-special-attrs.rs new file mode 100644 index 000000000000..351e3b52a4ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/malformed/malformed-special-attrs.rs @@ -0,0 +1,14 @@ +#[cfg_attr] // { dg-error "" "" { target *-*-* } } +struct S1; + +#[cfg_attr = ""] // { dg-error "" "" { target *-*-* } } +struct S2; + +#[derive] // { dg-error "" "" { target *-*-* } } +struct S3; + +#[derive = ""] // { dg-error "" "" { target *-*-* } } +struct S4; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/malformed/malformed-unwind-1.rs b/gcc/testsuite/rust/rustc/ui/malformed/malformed-unwind-1.rs new file mode 100644 index 000000000000..bdde221cb33e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/malformed/malformed-unwind-1.rs @@ -0,0 +1,10 @@ +#![feature(unwind_attributes)] + +#[unwind] // { dg-error "" "" { target *-*-* } } +extern "C" fn f1() {} + +#[unwind = ""] // { dg-error "" "" { target *-*-* } } +extern "C" fn f2() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/malformed/malformed-unwind-2.rs b/gcc/testsuite/rust/rustc/ui/malformed/malformed-unwind-2.rs new file mode 100644 index 000000000000..f3bf8a3d2c99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/malformed/malformed-unwind-2.rs @@ -0,0 +1,12 @@ +#![feature(unwind_attributes)] + +#[unwind(allowed, aborts)] +// { dg-error ".E0633." "" { target *-*-* } .-1 } +extern "C" fn f1() {} + +#[unwind(unsupported)] +// { dg-error ".E0633." "" { target *-*-* } .-1 } +extern "C" fn f2() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/malformed_macro_lhs.rs b/gcc/testsuite/rust/rustc/ui/malformed_macro_lhs.rs new file mode 100644 index 000000000000..83166561faf9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/malformed_macro_lhs.rs @@ -0,0 +1,8 @@ +macro_rules! my_precioooous { + t => (1); // { dg-error "" "" { target *-*-* } } +} + +fn main() { + my_precioooous!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/manual/manual-link-bad-form.rs b/gcc/testsuite/rust/rustc/ui/manual/manual-link-bad-form.rs new file mode 100644 index 000000000000..ee03dac87ba3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/manual/manual-link-bad-form.rs @@ -0,0 +1,6 @@ +// compile-flags:-l static= +// error-pattern: empty library name given via `-l` + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/manual/manual-link-bad-kind.rs b/gcc/testsuite/rust/rustc/ui/manual/manual-link-bad-kind.rs new file mode 100644 index 000000000000..82fc7a08f19c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/manual/manual-link-bad-kind.rs @@ -0,0 +1,6 @@ +// compile-flags:-l bar=foo +// error-pattern: unknown library kind `bar`, expected one of dylib, framework, or static + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/manual/manual-link-bad-search-path.rs b/gcc/testsuite/rust/rustc/ui/manual/manual-link-bad-search-path.rs new file mode 100644 index 000000000000..dadb2946877d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/manual/manual-link-bad-search-path.rs @@ -0,0 +1,6 @@ +// compile-flags:-L native= +// error-pattern: empty search path given via `-L` + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/manual/manual-link-framework.rs b/gcc/testsuite/rust/rustc/ui/manual/manual-link-framework.rs new file mode 100644 index 000000000000..179743ad8f90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/manual/manual-link-framework.rs @@ -0,0 +1,8 @@ +// ignore-macos +// ignore-ios +// compile-flags:-l framework=foo +// error-pattern: native frameworks are only available on macOS targets + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/map-types.rs b/gcc/testsuite/rust/rustc/ui/map-types.rs new file mode 100644 index 000000000000..6de50e1929d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/map-types.rs @@ -0,0 +1,20 @@ +#![feature(box_syntax)] + +use std::collections::HashMap; + +trait Map +{ + fn get(&self, k: K) -> V { panic!() } +} + +impl Map for HashMap {} + +// Test that trait types printed in error msgs include the type arguments. + +fn main() { + let x: Box> = box HashMap::new(); + let x: Box> = x; + let y: Box> = Box::new(x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/marker_trait_attr/issue-61651-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/marker_trait_attr/issue-61651-type-mismatch.rs new file mode 100644 index 000000000000..67e9b595253c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/marker_trait_attr/issue-61651-type-mismatch.rs @@ -0,0 +1,18 @@ +// check-pass +// Regression test for issue #61651 +// Verifies that we don't try to constrain inference +// variables due to the presence of multiple applicable +// marker trait impls + +#![feature(marker_trait_attr)] + +#[marker] // Remove this line and it works?!? +trait Foo {} +impl Foo for u8 {} +impl Foo<[u8; 1]> for u8 {} +fn foo, U>(_: T) -> U { unimplemented!() } + +fn main() { + let _: u16 = foo(0_u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/marker_trait_attr/marker-attribute-on-non-trait.rs b/gcc/testsuite/rust/rustc/ui/marker_trait_attr/marker-attribute-on-non-trait.rs new file mode 100644 index 000000000000..30439a346a9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/marker_trait_attr/marker-attribute-on-non-trait.rs @@ -0,0 +1,24 @@ +#![feature(marker_trait_attr)] + +#[marker] // { dg-error "" "" { target *-*-* } } +struct Struct {} + +#[marker] // { dg-error "" "" { target *-*-* } } +impl Struct {} + +#[marker] // { dg-error "" "" { target *-*-* } } +union Union { + x: i32, +} + +#[marker] // { dg-error "" "" { target *-*-* } } +const CONST: usize = 10; + +#[marker] // { dg-error "" "" { target *-*-* } } +fn function() {} + +#[marker] // { dg-error "" "" { target *-*-* } } +type Type = (); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/marker_trait_attr/marker-attribute-with-values.rs b/gcc/testsuite/rust/rustc/ui/marker_trait_attr/marker-attribute-with-values.rs new file mode 100644 index 000000000000..d9ba946271da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/marker_trait_attr/marker-attribute-with-values.rs @@ -0,0 +1,13 @@ +#![feature(marker_trait_attr)] + +#[marker(always)] // { dg-error "" "" { target *-*-* } } +trait Marker1 {} + +#[marker("never")] // { dg-error "" "" { target *-*-* } } +trait Marker2 {} + +#[marker(key = "value")] // { dg-error "" "" { target *-*-* } } +trait Marker3 {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/marker_trait_attr/marker-trait-with-associated-items.rs b/gcc/testsuite/rust/rustc/ui/marker_trait_attr/marker-trait-with-associated-items.rs new file mode 100644 index 000000000000..cccaff818fb2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/marker_trait_attr/marker-trait-with-associated-items.rs @@ -0,0 +1,41 @@ +#![feature(marker_trait_attr)] +#![feature(associated_type_defaults)] + +#[marker] +trait MarkerConst { + const N: usize; +// { dg-error ".E0714." "" { target *-*-* } .-1 } +} + +#[marker] +trait MarkerType { + type Output; +// { dg-error ".E0714." "" { target *-*-* } .-1 } +} + +#[marker] +trait MarkerFn { + fn foo(); +// { dg-error ".E0714." "" { target *-*-* } .-1 } +} + +#[marker] +trait MarkerConstWithDefault { + const N: usize = 43; +// { dg-error ".E0714." "" { target *-*-* } .-1 } +} + +#[marker] +trait MarkerTypeWithDefault { + type Output = (); +// { dg-error ".E0714." "" { target *-*-* } .-1 } +} + +#[marker] +trait MarkerFnWithDefault { + fn foo() {} +// { dg-error ".E0714." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/marker_trait_attr/overlap-marker-trait.rs b/gcc/testsuite/rust/rustc/ui/marker_trait_attr/overlap-marker-trait.rs new file mode 100644 index 000000000000..71fbbff6b90f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/marker_trait_attr/overlap-marker-trait.rs @@ -0,0 +1,29 @@ +// Test for RFC 1268: we allow overlapping impls of marker traits, +// that is, traits with #[marker]. In this case, a type `T` is +// `MyMarker` if it is either `Debug` or `Display`. This test just +// checks that we don't consider **all** types to be `MyMarker`. + +#![feature(marker_trait_attr)] + +use std::fmt::{Debug, Display}; + +#[marker] trait Marker {} + +impl Marker for T {} +impl Marker for T {} + +fn is_marker() { } + +struct NotDebugOrDisplay; + +fn main() { + // Debug && Display: + is_marker::(); + + // Debug && !Display: + is_marker::>(); + + // !Debug && !Display + is_marker::(); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/marker_trait_attr/override-item-on-marker-trait.rs b/gcc/testsuite/rust/rustc/ui/marker_trait_attr/override-item-on-marker-trait.rs new file mode 100644 index 000000000000..9d0eb3e5e31c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/marker_trait_attr/override-item-on-marker-trait.rs @@ -0,0 +1,24 @@ +#![feature(marker_trait_attr)] + +#[marker] +trait Marker { + const N: usize = 0; + fn do_something() {} +} + +struct OverrideConst; +impl Marker for OverrideConst { +// { dg-error ".E0715." "" { target *-*-* } .-1 } + const N: usize = 1; +} + +struct OverrideFn; +impl Marker for OverrideFn { +// { dg-error ".E0715." "" { target *-*-* } .-1 } + fn do_something() { + println!("Hello world!"); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/match-on-negative-integer-ranges.rs b/gcc/testsuite/rust/rustc/ui/match-on-negative-integer-ranges.rs new file mode 100644 index 000000000000..ad5b92a5d0c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match-on-negative-integer-ranges.rs @@ -0,0 +1,8 @@ +// run-pass + +fn main() { + assert_eq!(false, match -50_i8 { -128i8..=-101i8 => true, _ => false, }); + + assert_eq!(false, if let -128i8..=-101i8 = -50_i8 { true } else { false }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/const_non_normal_zst_ref_pattern.rs b/gcc/testsuite/rust/rustc/ui/match/const_non_normal_zst_ref_pattern.rs new file mode 100644 index 000000000000..fa148cf2629c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/const_non_normal_zst_ref_pattern.rs @@ -0,0 +1,10 @@ +// check-pass + +const FOO: isize = 10; +const ZST: &() = unsafe { std::mem::transmute(FOO) }; +fn main() { + match &() { + ZST => 9, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/expr-match-panic-fn.rs b/gcc/testsuite/rust/rustc/ui/match/expr-match-panic-fn.rs new file mode 100644 index 000000000000..88157b10ccd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/expr-match-panic-fn.rs @@ -0,0 +1,20 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn f() -> ! { + panic!() +} + +fn g() -> isize { + let x = match true { + true => f(), + false => 10, + }; + return x; +} + +fn main() { + g(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/expr-match-panic.rs b/gcc/testsuite/rust/rustc/ui/match/expr-match-panic.rs new file mode 100644 index 000000000000..9bfa6d9c4a55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/expr-match-panic.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn main() { + let _x = match true { + false => 0, + true => panic!(), + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/issue-50900.rs b/gcc/testsuite/rust/rustc/ui/match/issue-50900.rs new file mode 100644 index 000000000000..ddb1b676301b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/issue-50900.rs @@ -0,0 +1,20 @@ +#[derive(PartialEq, Eq)] +pub struct Tag(pub Context, pub u16); + +#[derive(PartialEq, Eq)] +pub enum Context { + Tiff, + Exif, +} + +impl Tag { + const ExifIFDPointer: Tag = Tag(Context::Tiff, 34665); +} + +fn main() { + match Tag::ExifIFDPointer { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + Tag::ExifIFDPointer => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/issue-70972-dyn-trait.rs b/gcc/testsuite/rust/rustc/ui/match/issue-70972-dyn-trait.rs new file mode 100644 index 000000000000..430097a17a5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/issue-70972-dyn-trait.rs @@ -0,0 +1,11 @@ +const F: &'static dyn Send = &7u32; + +fn main() { + let a: &dyn Send = &7u32; + match a { + F => panic!(), +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/issue-72896.rs b/gcc/testsuite/rust/rustc/ui/match/issue-72896.rs new file mode 100644 index 000000000000..e06695d15502 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/issue-72896.rs @@ -0,0 +1,24 @@ +// run-pass +trait EnumSetType { + type Repr; +} + +enum Enum8 { } +impl EnumSetType for Enum8 { + type Repr = u8; +} + +#[derive(PartialEq, Eq)] +struct EnumSet { + __enumset_underlying: T::Repr, +} + +const CONST_SET: EnumSet = EnumSet { __enumset_underlying: 3 }; + +fn main() { + match CONST_SET { + CONST_SET => { /* ok */ } + _ => panic!("match fell through?"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/issue-74050-end-span.rs b/gcc/testsuite/rust/rustc/ui/match/issue-74050-end-span.rs new file mode 100644 index 000000000000..f61b56f99b59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/issue-74050-end-span.rs @@ -0,0 +1,14 @@ +fn main() { + let mut args = std::env::args_os(); + let _arg = match args.next() { + Some(arg) => { + match arg.to_str() { +// { dg-error ".E0597." "" { target *-*-* } .-1 } + Some(s) => s, + None => return, + } + } + None => return, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-arm-resolving-to-never.rs b/gcc/testsuite/rust/rustc/ui/match/match-arm-resolving-to-never.rs new file mode 100644 index 000000000000..831c3713ccd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-arm-resolving-to-never.rs @@ -0,0 +1,20 @@ +enum E { + A, + B, + C, + D, + E, + F, +} + +fn main() { + match E::F { + E::A => 1, + E::B => 2, + E::C => 3, + E::D => 4, + E::E => unimplemented!(""), + E::F => "", // { dg-error ".E0308." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-bot-panic.rs b/gcc/testsuite/rust/rustc/ui/match/match-bot-panic.rs new file mode 100644 index 000000000000..059cb201ccd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-bot-panic.rs @@ -0,0 +1,17 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +#![allow(unreachable_code)] +#![allow(unused_variables)] + +fn foo(s: String) {} + +fn main() { + let i = match Some::(3) { + None:: => panic!(), + Some::(_) => panic!(), + }; + foo(i); +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-disc-bot.rs b/gcc/testsuite/rust/rustc/ui/match/match-disc-bot.rs new file mode 100644 index 000000000000..26243533ed7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-disc-bot.rs @@ -0,0 +1,17 @@ +// run-fail +// error-pattern:quux +// ignore-emscripten no processes + +fn f() -> ! { + panic!("quux") +} +fn g() -> isize { + match f() { + true => 1, + false => 0, + } +} +fn main() { + g(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-fn-call.rs b/gcc/testsuite/rust/rustc/ui/match/match-fn-call.rs new file mode 100644 index 000000000000..fac8bb224d32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-fn-call.rs @@ -0,0 +1,13 @@ +use std::path::Path; + +fn main() { + let path = Path::new("foo"); + match path { + Path::new("foo") => println!("foo"), +// { dg-error ".E0164." "" { target *-*-* } .-1 } + Path::new("bar") => println!("bar"), +// { dg-error ".E0164." "" { target *-*-* } .-1 } + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-ill-type2.rs b/gcc/testsuite/rust/rustc/ui/match/match-ill-type2.rs new file mode 100644 index 000000000000..8e1a405b2e1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-ill-type2.rs @@ -0,0 +1,8 @@ +fn main() { + match 1i32 { + 1i32 => 1, + 2u32 => 1, // { dg-error ".E0308." "" { target *-*-* } } + _ => 2, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-incompat-type-semi.rs b/gcc/testsuite/rust/rustc/ui/match/match-incompat-type-semi.rs new file mode 100644 index 000000000000..9f837ff2cd7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-incompat-type-semi.rs @@ -0,0 +1,53 @@ +// Diagnostic enhancement explained in issue #75418. +// Point at the last statement in the block if there's no tail expression, +// and suggest removing the semicolon if appropriate. + +fn main() { + let _ = match Some(42) { + Some(x) => { + x + }, + None => { + 0; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } + }, + }; + + let _ = if let Some(x) = Some(42) { + x + } else { + 0; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } + }; + + let _ = match Some(42) { + Some(x) => { + x + }, + None => { + (); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + }, + }; + + let _ = match Some(42) { + Some(x) => { + x + }, + None => { // { dg-error ".E0308." "" { target *-*-* } } + }, + }; + + let _ = match Some(42) { + Some(x) => "rust-lang.org" + .chars() + .skip(1) + .chain(Some(x as u8 as char)) + .take(10) + .any(char::is_alphanumeric), + None => {} // { dg-error ".E0308." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-join.rs b/gcc/testsuite/rust/rustc/ui/match/match-join.rs new file mode 100644 index 000000000000..d4cb3a5077cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-join.rs @@ -0,0 +1,12 @@ +// a good test that we merge paths correctly in the presence of a +// variable that's used before it's declared + +fn my_panic() -> ! { panic!(); } + +fn main() { + match true { false => { my_panic(); } true => { } } + + println!("{}", x); // { dg-error ".E0425." "" { target *-*-* } } + let x: isize; +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-no-arms-unreachable-after.rs b/gcc/testsuite/rust/rustc/ui/match/match-no-arms-unreachable-after.rs new file mode 100644 index 000000000000..c3f0ca78c2f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-no-arms-unreachable-after.rs @@ -0,0 +1,13 @@ +#![allow(warnings)] +#![deny(unreachable_code)] + +enum Void { } + +fn foo(v: Void) { + match v { } + let x = 2; // { dg-error "" "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-pattern-field-mismatch-2.rs b/gcc/testsuite/rust/rustc/ui/match/match-pattern-field-mismatch-2.rs new file mode 100644 index 000000000000..3c985635820a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-pattern-field-mismatch-2.rs @@ -0,0 +1,17 @@ +fn main() { + enum Color { + Rgb(usize, usize, usize), + Cmyk(usize, usize, usize, usize), + NoColor, + } + + fn foo(c: Color) { + match c { + Color::Rgb(_, _, _) => { } + Color::Cmyk(_, _, _, _) => { } + Color::NoColor(_) => { } +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-pattern-field-mismatch.rs b/gcc/testsuite/rust/rustc/ui/match/match-pattern-field-mismatch.rs new file mode 100644 index 000000000000..f4e440e9f939 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-pattern-field-mismatch.rs @@ -0,0 +1,17 @@ +fn main() { + enum Color { + Rgb(usize, usize, usize), + Cmyk(usize, usize, usize, usize), + NoColor, + } + + fn foo(c: Color) { + match c { + Color::Rgb(_, _) => { } +// { dg-error ".E0023." "" { target *-*-* } .-1 } + Color::Cmyk(_, _, _, _) => { } + Color::NoColor => { } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-range-fail-2.rs b/gcc/testsuite/rust/rustc/ui/match/match-range-fail-2.rs new file mode 100644 index 000000000000..e36c43402d0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-range-fail-2.rs @@ -0,0 +1,25 @@ +#![feature(exclusive_range_pattern)] + +fn main() { + match 5 { + 6 ..= 1 => { } + _ => { } + }; +// { dg-error ".E0030." "" { target *-*-* } .-3 } +// { dg-error ".E0030." "" { target *-*-* } .-2 } + + match 5 { + 0 .. 0 => { } + _ => { } + }; +// { dg-error ".E0579." "" { target *-*-* } .-3 } +// { dg-error ".E0579." "" { target *-*-* } .-2 } + + match 5u64 { + 0xFFFF_FFFF_FFFF_FFFF ..= 1 => { } + _ => { } + }; +// { dg-error ".E0030." "" { target *-*-* } .-3 } +// { dg-error ".E0030." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-range-fail.rs b/gcc/testsuite/rust/rustc/ui/match/match-range-fail.rs new file mode 100644 index 000000000000..182128c45d0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-range-fail.rs @@ -0,0 +1,23 @@ +fn main() { + match "wow" { + "bar" ..= "foo" => { } + }; +// { dg-error ".E0029." "" { target *-*-* } .-2 } + + match "wow" { + 10 ..= "what" => () + }; +// { dg-error ".E0029." "" { target *-*-* } .-2 } + + match "wow" { + true ..= "what" => {} + }; +// { dg-error ".E0029." "" { target *-*-* } .-2 } + + match 5 { + 'c' ..= 100 => { } + _ => { } + }; +// { dg-error ".E0308." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-ref-mut-invariance.rs b/gcc/testsuite/rust/rustc/ui/match/match-ref-mut-invariance.rs new file mode 100644 index 000000000000..2202dac6d52d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-ref-mut-invariance.rs @@ -0,0 +1,15 @@ +// Check that when making a ref mut binding with type `&mut T`, the +// type `T` must match precisely the type `U` of the value being +// matched, and in particular cannot be some supertype of `U`. Issue +// #23116. This test focuses on a `match`. + +#![allow(dead_code)] +struct S<'b>(&'b i32); +impl<'b> S<'b> { + fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { + match self.0 { ref mut x => x } // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-ref-mut-let-invariance.rs b/gcc/testsuite/rust/rustc/ui/match/match-ref-mut-let-invariance.rs new file mode 100644 index 000000000000..0a61e6da2e80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-ref-mut-let-invariance.rs @@ -0,0 +1,16 @@ +// Check that when making a ref mut binding with type `&mut T`, the +// type `T` must match precisely the type `U` of the value being +// matched, and in particular cannot be some supertype of `U`. Issue +// #23116. This test focuses on a `let`. + +#![allow(dead_code)] +struct S<'b>(&'b i32); +impl<'b> S<'b> { + fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { + let ref mut x = self.0; + x // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-ref-mut-stability.rs b/gcc/testsuite/rust/rustc/ui/match/match-ref-mut-stability.rs new file mode 100644 index 000000000000..777755d2a0bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-ref-mut-stability.rs @@ -0,0 +1,38 @@ +// Check that `ref mut` variables don't change address between the match guard +// and the arm expression. + +// run-pass + +// Test that z always point to the same temporary. +fn referent_stability() { + let p; + match 0 { + ref mut z if { p = z as *const _; true } => assert_eq!(p, z as *const _), + _ => unreachable!(), + }; +} + +// Test that z is always effectively the same variable. +fn variable_stability() { + let p; + match 0 { + ref mut z if { p = &z as *const _; true } => assert_eq!(p, &z as *const _), + _ => unreachable!(), + }; +} + +// Test that a borrow of *z can cross from the guard to the arm. +fn persist_borrow() { + let r; + match 0 { + ref mut z if { r = z as &_; true } => assert_eq!(*r, 0), + _ => unreachable!(), + } +} + +fn main() { + referent_stability(); + variable_stability(); + persist_borrow(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-struct.rs b/gcc/testsuite/rust/rustc/ui/match/match-struct.rs new file mode 100644 index 000000000000..0ea4272c40b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-struct.rs @@ -0,0 +1,12 @@ +struct S { a: isize } +enum E { C(isize) } + +fn main() { + match (S { a: 1 }) { + E::C(_) => (), +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + _ => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-tag-nullary.rs b/gcc/testsuite/rust/rustc/ui/match/match-tag-nullary.rs new file mode 100644 index 000000000000..7aec6c3af35c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-tag-nullary.rs @@ -0,0 +1,5 @@ +enum A { A } +enum B { B } + +fn main() { let x: A = A::A; match x { B::B => { } } } // { dg-error ".E0308." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-tag-unary.rs b/gcc/testsuite/rust/rustc/ui/match/match-tag-unary.rs new file mode 100644 index 000000000000..877574b9ca6b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-tag-unary.rs @@ -0,0 +1,5 @@ +enum A { A(isize) } +enum B { B(isize) } + +fn main() { let x: A = A::A(0); match x { B::B(y) => { } } } // { dg-error ".E0308." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-type-err-first-arm.rs b/gcc/testsuite/rust/rustc/ui/match/match-type-err-first-arm.rs new file mode 100644 index 000000000000..da3928892da9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-type-err-first-arm.rs @@ -0,0 +1,51 @@ +fn main() { + let _ = test_func1(1); + let _ = test_func2(1); +} + +fn test_func1(n: i32) -> i32 { // { dg-note "" "" { target *-*-* } } + match n { + 12 => 'b', +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } + _ => 42, + } +} + +fn test_func2(n: i32) -> i32 { + let x = match n { // { dg-note ".E0308." "" { target *-*-* } } + 12 => 'b', // { dg-note "" "" { target *-*-* } } + _ => 42, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } + }; + x +} + +fn test_func3(n: i32) -> i32 { + let x = match n { // { dg-note ".E0308." "" { target *-*-* } } + 1 => 'b', + 2 => 'b', + 3 => 'b', + 4 => 'b', + 5 => 'b', + 6 => 'b', +// { dg-note "" "" { target *-*-* } .-1 } + _ => 42, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } + }; + x +} + +fn test_func4() { + match Some(0u32) { // { dg-note ".E0308." "" { target *-*-* } } + Some(x) => { + x // { dg-note "" "" { target *-*-* } } + }, + None => {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-unresolved-one-arm.rs b/gcc/testsuite/rust/rustc/ui/match/match-unresolved-one-arm.rs new file mode 100644 index 000000000000..c8e6c63a7133 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-unresolved-one-arm.rs @@ -0,0 +1,8 @@ +fn foo() -> T { panic!("Rocks for my pillow") } + +fn main() { + let x = match () { // { dg-error ".E0282." "" { target *-*-* } } + () => foo() // T here should be unresolved + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-vec-mismatch-2.rs b/gcc/testsuite/rust/rustc/ui/match/match-vec-mismatch-2.rs new file mode 100644 index 000000000000..eaadc0c0ea0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-vec-mismatch-2.rs @@ -0,0 +1,7 @@ +fn main() { + match () { + [()] => { } +// { dg-error ".E0529." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/match-wildcards.rs b/gcc/testsuite/rust/rustc/ui/match/match-wildcards.rs new file mode 100644 index 000000000000..f2a4de53286b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/match-wildcards.rs @@ -0,0 +1,22 @@ +// run-fail +// error-pattern:squirrelcupcake +// ignore-emscripten no processes + +fn cmp() -> isize { + match (Some('a'), None::) { + (Some(_), _) => { + panic!("squirrelcupcake"); + } + (_, Some(_)) => { + panic!(); + } + _ => { + panic!("wat"); + } + } +} + +fn main() { + println!("{}", cmp()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/pattern-deref-miscompile.rs b/gcc/testsuite/rust/rustc/ui/match/pattern-deref-miscompile.rs new file mode 100644 index 000000000000..d4ac1eb04a38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/pattern-deref-miscompile.rs @@ -0,0 +1,47 @@ +// run-pass + +fn main() { + match b"." as &[u8] { + b"." if true => {}, + b"." => panic!(), + b".." => panic!(), + b"" => panic!(), + _ => panic!(), + } + match b"." as &[u8] { + b"." if false => panic!(), + b"." => {}, + b".." => panic!(), + b"" => panic!(), + _ => panic!(), + } + match b".." as &[u8] { + b"." if true => panic!(), // the miscompile caused this arm to be reached + b"." => panic!(), + b".." => {}, + b"" => panic!(), + _ => panic!(), + } + match b".." as &[u8] { + b"." if false => panic!(), + b"." => panic!(), + b".." => {}, + b"" => panic!(), + _ => panic!(), + } + match b"" as &[u8] { + b"." if true => panic!(), + b"." => panic!(), + b".." => panic!(), + b"" => {}, + _ => panic!(), + } + match b"" as &[u8] { + b"." if false => panic!(), + b"." => panic!(), + b".." => panic!(), + b"" => {}, + _ => panic!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/match/type_polymorphic_byte_str_literals.rs b/gcc/testsuite/rust/rustc/ui/match/type_polymorphic_byte_str_literals.rs new file mode 100644 index 000000000000..e739a6481a9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/match/type_polymorphic_byte_str_literals.rs @@ -0,0 +1,37 @@ +#[deny(unreachable_patterns)] + +fn parse_data1(data: &[u8]) -> u32 { + match data { + b"" => 1, + _ => 2, + } +} + +fn parse_data2(data: &[u8]) -> u32 { + match data { // { dg-error ".E0004." "" { target *-*-* } } + b"" => 1, + } +} + +fn parse_data3(data: &[u8; 0]) -> u8 { + match data { + b"" => 1, + } +} + +fn parse_data4(data: &[u8]) -> u8 { + match data { // { dg-error ".E0004." "" { target *-*-* } } + b"aaa" => 0, + [_, _, _] => 1, + } +} + +fn parse_data5(data: &[u8; 3]) -> u8 { + match data { + b"aaa" => 0, + [_, _, _] => 1, + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/max-min-classes.rs b/gcc/testsuite/rust/rustc/ui/max-min-classes.rs new file mode 100644 index 000000000000..ea08427092ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/max-min-classes.rs @@ -0,0 +1,33 @@ +// run-pass + +#![allow(non_snake_case)] +trait Product { + fn product(&self) -> isize; +} + +struct Foo { + x: isize, + y: isize, +} + +impl Foo { + pub fn sum(&self) -> isize { + self.x + self.y + } +} + +impl Product for Foo { + fn product(&self) -> isize { + self.x * self.y + } +} + +fn Foo(x: isize, y: isize) -> Foo { + Foo { x: x, y: y } +} + +pub fn main() { + let foo = Foo(3, 20); + println!("{} {}", foo.sum(), foo.product()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/maybe-bounds-where-cpass.rs b/gcc/testsuite/rust/rustc/ui/maybe-bounds-where-cpass.rs new file mode 100644 index 000000000000..f48e8adcbf28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/maybe-bounds-where-cpass.rs @@ -0,0 +1,10 @@ +// build-pass (FIXME(62277): could be check-pass?) + +struct S(*const T) where T: ?Sized; + + +fn main() { + let u = vec![1, 2, 3]; + let _s: S<[u8]> = S(&u[..]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/maybe-bounds-where.rs b/gcc/testsuite/rust/rustc/ui/maybe-bounds-where.rs new file mode 100644 index 000000000000..cbfd41459344 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/maybe-bounds-where.rs @@ -0,0 +1,28 @@ +struct S1(T) where (T): ?Sized; +// { dg-error "" "" { target *-*-* } .-1 } + +struct S2(T) where u8: ?Sized; +// { dg-error "" "" { target *-*-* } .-1 } + +struct S3(T) where &'static T: ?Sized; +// { dg-error "" "" { target *-*-* } .-1 } + +trait Trait<'a> {} + +struct S4(T) where for<'a> T: ?Trait<'a>; +// { dg-error "" "" { target *-*-* } .-1 } + +struct S5(*const T) where T: ?Trait<'static> + ?Sized; +// { dg-error ".E0203." "" { target *-*-* } .-1 } +// { dg-warning ".E0203." "" { target *-*-* } .-2 } + +impl S1 { + fn f() where T: ?Sized {} +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + let u = vec![1, 2, 3]; + let _s: S5<[u8]> = S5(&u[..]); // OK +} + diff --git a/gcc/testsuite/rust/rustc/ui/maybe-bounds.rs b/gcc/testsuite/rust/rustc/ui/maybe-bounds.rs new file mode 100644 index 000000000000..a27c8cd6ef51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/maybe-bounds.rs @@ -0,0 +1,10 @@ +trait Tr: ?Sized {} +// { dg-error "" "" { target *-*-* } .-1 } + +type A1 = dyn Tr + (?Sized); +// { dg-error "" "" { target *-*-* } .-1 } +type A2 = dyn for<'a> Tr + (?Sized); +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/meta/auxiliary/env.rs b/gcc/testsuite/rust/rustc/ui/meta/auxiliary/env.rs new file mode 100644 index 000000000000..277e6d35571b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/meta/auxiliary/env.rs @@ -0,0 +1,10 @@ +// Check that aux builds can also use rustc-env, but environment is configured +// separately from the main test case. +// +// rustc-env:COMPILETEST_BAR=bar + +pub fn test() { + assert_eq!(option_env!("COMPILETEST_FOO"), None); + assert_eq!(env!("COMPILETEST_BAR"), "bar"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/meta/expected-error-correct-rev.rs b/gcc/testsuite/rust/rustc/ui/meta/expected-error-correct-rev.rs new file mode 100644 index 000000000000..4267e3d953f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/meta/expected-error-correct-rev.rs @@ -0,0 +1,11 @@ +// revisions: a + +// Counterpart to `expected-error-wrong-rev.rs` + +#[cfg(a)] +fn foo() { + let x: u32 = 22_usize; // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/meta/revision-bad.rs b/gcc/testsuite/rust/rustc/ui/meta/revision-bad.rs new file mode 100644 index 000000000000..d2ff2bdeaa33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/meta/revision-bad.rs @@ -0,0 +1,22 @@ +// Meta test for compiletest: check that when we give the wrong error +// patterns, the test fails. + +// run-fail +// revisions: foo bar +// should-fail +//[foo] error-pattern:bar +//[bar] error-pattern:foo + +#[cfg(foo)] +fn die() { + panic!("foo"); +} +#[cfg(bar)] +fn die() { + panic!("bar"); +} + +fn main() { + die(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/meta/revision-ok.rs b/gcc/testsuite/rust/rustc/ui/meta/revision-ok.rs new file mode 100644 index 000000000000..f522be32cec2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/meta/revision-ok.rs @@ -0,0 +1,22 @@ +// Meta test for compiletest: check that when we give the right error +// patterns, the test passes. See all `revision-bad.rs`. + +// run-fail +// revisions: foo bar +//[foo] error-pattern:foo +//[bar] error-pattern:bar +// ignore-emscripten no processes + +#[cfg(foo)] +fn die() { + panic!("foo"); +} +#[cfg(bar)] +fn die() { + panic!("bar"); +} + +fn main() { + die(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/meta/rustc-env.rs b/gcc/testsuite/rust/rustc/ui/meta/rustc-env.rs new file mode 100644 index 000000000000..2d621697bc82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/meta/rustc-env.rs @@ -0,0 +1,19 @@ +// Compiletest meta test checking that rustc-env and unset-rustc-env directives +// can be used to configure environment for rustc. +// +// run-pass +// aux-build:env.rs +// rustc-env:COMPILETEST_FOO=foo +// +// An environment variable that is likely to be set, but should be safe to unset. +// unset-rustc-env:PWD + +extern crate env; + +fn main() { + assert_eq!(env!("COMPILETEST_FOO"), "foo"); + assert_eq!(option_env!("COMPILETEST_BAR"), None); + assert_eq!(option_env!("PWD"), None); + env::test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/assign-to-method.rs b/gcc/testsuite/rust/rustc/ui/methods/assign-to-method.rs new file mode 100644 index 000000000000..cd4bd25e290b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/assign-to-method.rs @@ -0,0 +1,25 @@ +// compile-flags: -Zsave-analysis +// Also regression test for #69409 + +struct Cat { + meows : usize, + how_hungry : isize, +} + +impl Cat { + pub fn speak(&self) { self.meows += 1; } +} + +fn cat(in_x : usize, in_y : isize) -> Cat { + Cat { + meows: in_x, + how_hungry: in_y + } +} + +fn main() { + let nyan : Cat = cat(52, 99); + nyan.speak = || println!("meow"); // { dg-error ".E0615." "" { target *-*-* } } + nyan.speak += || println!("meow"); // { dg-error ".E0615." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/auxiliary/ambig_impl_2_lib.rs b/gcc/testsuite/rust/rustc/ui/methods/auxiliary/ambig_impl_2_lib.rs new file mode 100644 index 000000000000..664487f8889a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/auxiliary/ambig_impl_2_lib.rs @@ -0,0 +1,5 @@ +pub trait Me { + fn me(&self) -> usize; +} +impl Me for usize { fn me(&self) -> usize { *self } } + diff --git a/gcc/testsuite/rust/rustc/ui/methods/auxiliary/macro-in-other-crate.rs b/gcc/testsuite/rust/rustc/ui/methods/auxiliary/macro-in-other-crate.rs new file mode 100644 index 000000000000..bbe6ce136c38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/auxiliary/macro-in-other-crate.rs @@ -0,0 +1,10 @@ +#[macro_export] +macro_rules! mac { + ($ident:ident) => { let $ident = 42; } +} + +#[macro_export] +macro_rules! inline { + () => () +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/auxiliary/method_self_arg1.rs b/gcc/testsuite/rust/rustc/ui/methods/auxiliary/method_self_arg1.rs new file mode 100644 index 000000000000..60be859a2585 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/auxiliary/method_self_arg1.rs @@ -0,0 +1,38 @@ +#![crate_type = "lib"] + +#![feature(box_syntax)] + +static mut COUNT: u64 = 1; + +pub fn get_count() -> u64 { unsafe { COUNT } } + +#[derive(Copy, Clone)] +pub struct Foo; + +impl Foo { + pub fn foo(self, x: &Foo) { + unsafe { COUNT *= 2; } + // Test internal call. + Foo::bar(&self); + Foo::bar(x); + + Foo::baz(self); + Foo::baz(*x); + + Foo::qux(box self); + Foo::qux(box *x); + } + + pub fn bar(&self) { + unsafe { COUNT *= 3; } + } + + pub fn baz(self) { + unsafe { COUNT *= 5; } + } + + pub fn qux(self: Box) { + unsafe { COUNT *= 7; } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/auxiliary/method_self_arg2.rs b/gcc/testsuite/rust/rustc/ui/methods/auxiliary/method_self_arg2.rs new file mode 100644 index 000000000000..5a2fea7c2fd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/auxiliary/method_self_arg2.rs @@ -0,0 +1,55 @@ +#![crate_type = "lib"] + +#![feature(box_syntax)] + +static mut COUNT: u64 = 1; + +pub fn get_count() -> u64 { unsafe { COUNT } } + +#[derive(Copy, Clone)] +pub struct Foo; + +impl Foo { + pub fn run_trait(self) { + unsafe { COUNT *= 17; } + // Test internal call. + Bar::foo1(&self); + Bar::foo2(self); + Bar::foo3(box self); + + Bar::bar1(&self); + Bar::bar2(self); + Bar::bar3(box self); + } +} + +pub trait Bar : Sized { + fn foo1(&self); + fn foo2(self); + fn foo3(self: Box); + + fn bar1(&self) { + unsafe { COUNT *= 7; } + } + fn bar2(self) { + unsafe { COUNT *= 11; } + } + fn bar3(self: Box) { + unsafe { COUNT *= 13; } + } +} + +impl Bar for Foo { + fn foo1(&self) { + unsafe { COUNT *= 2; } + } + + fn foo2(self) { + unsafe { COUNT *= 3; } + } + + fn foo3(self: Box) { + unsafe { COUNT *= 5; } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-ambig-one-trait-unknown-int-type.rs b/gcc/testsuite/rust/rustc/ui/methods/method-ambig-one-trait-unknown-int-type.rs new file mode 100644 index 000000000000..08ef28823e9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-ambig-one-trait-unknown-int-type.rs @@ -0,0 +1,37 @@ +// Test that we invoking `foo()` successfully resolves to the trait `Foo` +// (prompting the mismatched types error) but does not influence the choice +// of what kind of `Vec` we have, eventually leading to a type error. + +trait Foo { + fn foo(&self) -> isize; +} + +impl Foo for Vec { + fn foo(&self) -> isize {1} +} + +impl Foo for Vec { + fn foo(&self) -> isize {2} +} + +// This is very hokey: we have heuristics to suppress messages about +// type annotations needed. But placing these two bits of code into +// distinct functions, in this order, causes us to print out both +// errors I'd like to see. + +fn m1() { + // we couldn't infer the type of the vector just based on calling foo()... + let mut x = Vec::new(); +// { dg-error ".E0282." "" { target *-*-* } .-1 } + x.foo(); +} + +fn m2() { + let mut x = Vec::new(); + + // ...but we still resolved `foo()` to the trait and hence know the return type. + let y: usize = x.foo(); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-cross-crate.rs new file mode 100644 index 000000000000..fdabaa2f6a75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-cross-crate.rs @@ -0,0 +1,12 @@ +// Test an ambiguity scenario where one copy of the method is available +// from a trait imported from another crate. + +// aux-build:ambig_impl_2_lib.rs +extern crate ambig_impl_2_lib; +use ambig_impl_2_lib::Me; +trait Me2 { + fn me(&self) -> usize; +} +impl Me2 for usize { fn me(&self) -> usize { *self } } +fn main() { 1_usize.me(); } // { dg-error ".E0034." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-from-bounds.rs b/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-from-bounds.rs new file mode 100644 index 000000000000..eb512f74444e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-from-bounds.rs @@ -0,0 +1,9 @@ +trait A { fn foo(&self); } +trait B { fn foo(&self); } + +fn foo(t: T) { + t.foo(); // { dg-error ".E0034." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-from-impls.rs b/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-from-impls.rs new file mode 100644 index 000000000000..d64d612fc59c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-from-impls.rs @@ -0,0 +1,17 @@ +trait A { fn foo(self); } +trait B { fn foo(self); } + +struct AB {} + +impl A for AB { + fn foo(self) {} +} + +impl B for AB { + fn foo(self) {} +} + +fn main() { + AB {}.foo(); // { dg-error ".E0034." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-from-impls2.rs b/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-from-impls2.rs new file mode 100644 index 000000000000..0431d87d3faf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-from-impls2.rs @@ -0,0 +1,17 @@ +trait A { fn foo(); } +trait B { fn foo(); } + +struct AB {} + +impl A for AB { + fn foo() {} +} + +impl B for AB { + fn foo() {} +} + +fn main() { + AB::foo(); // { dg-error ".E0034." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-with-default-method.rs b/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-with-default-method.rs new file mode 100644 index 000000000000..9811853df837 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-ambig-two-traits-with-default-method.rs @@ -0,0 +1,14 @@ +// Test that we correctly report an ambiguity where two applicable traits +// are in scope and the method being invoked is a default method not +// defined directly in the impl. + +trait Foo { fn method(&self) {} } +trait Bar { fn method(&self) {} } + +impl Foo for usize {} +impl Bar for usize {} + +fn main() { + 1_usize.method(); // { dg-error ".E0034." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-argument-inference-associated-type.rs b/gcc/testsuite/rust/rustc/ui/methods/method-argument-inference-associated-type.rs new file mode 100644 index 000000000000..79d6ffa6e629 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-argument-inference-associated-type.rs @@ -0,0 +1,29 @@ +// run-pass +pub struct ClientMap; +pub struct ClientMap2; + +pub trait Service { + type Request; + fn call(&self, _req: Self::Request); +} + +pub struct S(T); + +impl Service for ClientMap { + type Request = S>; + fn call(&self, _req: Self::Request) {} +} + + +impl Service for ClientMap2 { + type Request = (Box,); + fn call(&self, _req: Self::Request) {} +} + + +fn main() { + ClientMap.call(S { 0: Box::new(|_msgid| ()) }); + ClientMap.call(S(Box::new(|_msgid| ()))); + ClientMap2.call((Box::new(|_msgid| ()),)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-call-err-msg.rs b/gcc/testsuite/rust/rustc/ui/methods/method-call-err-msg.rs new file mode 100644 index 000000000000..e61cc5196730 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-call-err-msg.rs @@ -0,0 +1,23 @@ +// Test that parameter cardinality or missing method error gets span exactly. + +pub struct Foo; +impl Foo { + fn zero(self) -> Foo { self } + fn one(self, _: isize) -> Foo { self } + fn two(self, _: isize, _: isize) -> Foo { self } + fn three(self, _: T, _: T, _: T) -> Foo { self } +} + +fn main() { + let x = Foo; + x.zero(0) // { dg-error ".E0061." "" { target *-*-* } } + .one() // { dg-error ".E0061." "" { target *-*-* } } + .two(0); // { dg-error ".E0061." "" { target *-*-* } } + + let y = Foo; + y.zero() + .take() // { dg-error ".E0599." "" { target *-*-* } } + .one(0); + y.three::(); // { dg-error ".E0061." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-fail.rs b/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-fail.rs new file mode 100644 index 000000000000..8c628375933c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-fail.rs @@ -0,0 +1,73 @@ +struct S; + +impl S { + fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} + fn late_implicit(self, _: &u8, _: &u8) {} + fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } + fn late_early<'a, 'b>(self, _: &'a u8) -> &'b u8 { loop {} } + fn late_implicit_early<'b>(self, _: &u8) -> &'b u8 { loop {} } + fn late_implicit_self_early<'b>(&self) -> &'b u8 { loop {} } + fn late_unused_early<'a, 'b>(self) -> &'b u8 { loop {} } + fn life_and_type<'a, T>(self) -> &'a T { loop {} } +} + +fn method_call() { + S.early(); // OK + S.early::<'static>(); +// { dg-error ".E0107." "" { target *-*-* } .-1 } + S.early::<'static, 'static, 'static>(); +// { dg-error ".E0107." "" { target *-*-* } .-1 } + let _: &u8 = S.life_and_type::<'static>(); + S.life_and_type::(); + S.life_and_type::<'static, u8>(); +} + +fn ufcs() { + S::late(S, &0, &0); // OK + S::late::<'static>(S, &0, &0); +// { dg-error "" "" { target *-*-* } .-1 } + S::late::<'static, 'static>(S, &0, &0); +// { dg-error "" "" { target *-*-* } .-1 } + S::late::<'static, 'static, 'static>(S, &0, &0); +// { dg-error "" "" { target *-*-* } .-1 } + S::late_early(S, &0); // OK + S::late_early::<'static, 'static>(S, &0); +// { dg-error "" "" { target *-*-* } .-1 } + S::late_early::<'static, 'static, 'static>(S, &0); +// { dg-error "" "" { target *-*-* } .-1 } + + S::late_implicit(S, &0, &0); // OK + S::late_implicit::<'static>(S, &0, &0); +// { dg-error "" "" { target *-*-* } .-1 } + S::late_implicit::<'static, 'static>(S, &0, &0); +// { dg-error "" "" { target *-*-* } .-1 } + S::late_implicit::<'static, 'static, 'static>(S, &0, &0); +// { dg-error "" "" { target *-*-* } .-1 } + S::late_implicit_early(S, &0); // OK + S::late_implicit_early::<'static, 'static>(S, &0); +// { dg-error "" "" { target *-*-* } .-1 } + S::late_implicit_early::<'static, 'static, 'static>(S, &0); +// { dg-error "" "" { target *-*-* } .-1 } + S::late_implicit_self_early(&S); // OK + S::late_implicit_self_early::<'static, 'static>(&S); +// { dg-error "" "" { target *-*-* } .-1 } + S::late_implicit_self_early::<'static, 'static, 'static>(&S); +// { dg-error "" "" { target *-*-* } .-1 } + S::late_unused_early(S); // OK + S::late_unused_early::<'static, 'static>(S); +// { dg-error "" "" { target *-*-* } .-1 } + S::late_unused_early::<'static, 'static, 'static>(S); +// { dg-error "" "" { target *-*-* } .-1 } + + S::early(S); // OK + S::early::<'static>(S); +// { dg-error ".E0107." "" { target *-*-* } .-1 } + S::early::<'static, 'static, 'static>(S); +// { dg-error ".E0107." "" { target *-*-* } .-1 } + let _: &u8 = S::life_and_type::<'static>(S); + S::life_and_type::(S); + S::life_and_type::<'static, u8>(S); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-lint-fail.rs b/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-lint-fail.rs new file mode 100644 index 000000000000..1ff50e24f7df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-lint-fail.rs @@ -0,0 +1,88 @@ +#![deny(late_bound_lifetime_arguments)] +#![allow(unused)] + +struct S; + +impl S { + fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} + fn late_implicit(self, _: &u8, _: &u8) {} + fn late_early<'a, 'b>(self, _: &'a u8) -> &'b u8 { loop {} } + fn late_implicit_early<'b>(self, _: &u8) -> &'b u8 { loop {} } + + // 'late lifetimes here belong to nested types not to the tested functions. + fn early_tricky_explicit<'a>(_: for<'late> fn(&'late u8), + _: Box Fn(&'late u8)>) + -> &'a u8 { loop {} } + fn early_tricky_implicit<'a>(_: fn(&u8), + _: Box) + -> &'a u8 { loop {} } +} + +fn method_call() { + S.late(&0, &0); // OK + S.late::<'static>(&0, &0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + S.late::<'static, 'static>(&0, &0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + S.late::<'static, 'static, 'static>(&0, &0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + S.late_early(&0); // OK + S.late_early::<'static>(&0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + S.late_early::<'static, 'static>(&0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + S.late_early::<'static, 'static, 'static>(&0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + S.late_implicit(&0, &0); // OK + S.late_implicit::<'static>(&0, &0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + S.late_implicit::<'static, 'static>(&0, &0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + S.late_implicit::<'static, 'static, 'static>(&0, &0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + S.late_implicit_early(&0); // OK + S.late_implicit_early::<'static>(&0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + S.late_implicit_early::<'static, 'static>(&0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + S.late_implicit_early::<'static, 'static, 'static>(&0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + S::early_tricky_explicit::<'static>(loop {}, loop {}); // OK + S::early_tricky_implicit::<'static>(loop {}, loop {}); // OK +} + +fn ufcs() { + S::late_early::<'static>(S, &0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + S::late_implicit_early::<'static>(S, &0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn lint_not_inference_error() { + fn f<'early, 'late, T: 'early>() {} + + // Make sure `u8` is substituted and not replaced with an inference variable + f::<'static, u8>; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-lint.rs b/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-lint.rs new file mode 100644 index 000000000000..98856a4384f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-lint.rs @@ -0,0 +1,22 @@ +#![deny(late_bound_lifetime_arguments)] +#![allow(unused)] + +struct S; + +impl S { + fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} + fn late_implicit(self, _: &u8, _: &u8) {} +} + +fn method_call() { + S.late::<'static>(&0, &0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + S.late_implicit::<'static>(&0, &0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-subst-index.rs b/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-subst-index.rs new file mode 100644 index 000000000000..6d7648f329aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-subst-index.rs @@ -0,0 +1,16 @@ +// build-pass (FIXME(62277): could be check-pass?) +#![allow(unused)] + +struct S; + +impl S { + fn early_and_type<'a, T>(self) -> &'a T { loop {} } +} + +fn test() { + S.early_and_type::(); +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-unresolved.rs b/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-unresolved.rs new file mode 100644 index 000000000000..3cb8dc6edae7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args-unresolved.rs @@ -0,0 +1,4 @@ +fn main() { + 0.clone::<'a>(); // { dg-error ".E0261." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args.rs b/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args.rs new file mode 100644 index 000000000000..7b7857051f5a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-call-lifetime-args.rs @@ -0,0 +1,16 @@ +struct S; + +impl S { + fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} + fn late_implicit(self, _: &u8, _: &u8) {} +} + +fn ufcs() { + S::late::<'static>(S, &0, &0); +// { dg-error "" "" { target *-*-* } .-1 } + S::late_implicit::<'static>(S, &0, &0); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-call-type-binding.rs b/gcc/testsuite/rust/rustc/ui/methods/method-call-type-binding.rs new file mode 100644 index 000000000000..36a7e0c49120 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-call-type-binding.rs @@ -0,0 +1,4 @@ +fn main() { + 0.clone::(); // { dg-error ".E0229." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs b/gcc/testsuite/rust/rustc/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs new file mode 100644 index 000000000000..891338666c20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-deref-to-same-trait-object-with-separate-params.rs @@ -0,0 +1,180 @@ +#![feature(arbitrary_self_types, coerce_unsized, dispatch_from_dyn, unsize)] +#![feature(unsized_locals, unsized_fn_params)] +// { dg-warning "" "" { target *-*-* } .-1 } + +// This tests a few edge-cases around `arbitrary_self_types`. Most specifically, +// it checks that the `ObjectCandidate` you get from method matching can't +// match a trait with the same DefId as a supertrait but a bad type parameter. + +use std::marker::PhantomData; + +mod internal { + use std::ops::{CoerceUnsized, Deref, DispatchFromDyn}; + use std::marker::{PhantomData, Unsize}; + + pub struct Smaht(pub Box, pub PhantomData); + + impl Deref for Smaht { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + impl, U: ?Sized, MISC> CoerceUnsized> + for Smaht + {} + impl, U: ?Sized, MISC> DispatchFromDyn> + for Smaht + {} + + pub trait Foo: X {} + pub trait X { + fn foo(self: Smaht) -> T; + } + + impl X for () { + fn foo(self: Smaht) -> u32 { + 0 + } + } + + pub trait Marker {} + impl Marker for dyn Foo {} + impl X for T { + fn foo(self: Smaht) -> u64 { + 1 + } + } + + impl Deref for dyn Foo { + type Target = (); + fn deref(&self) -> &() { &() } + } + + impl Foo for () {} +} + +pub trait FinalFoo { + fn foo(&self) -> u8; +} + +impl FinalFoo for () { + fn foo(&self) -> u8 { 0 } +} + +mod nuisance_foo { + pub trait NuisanceFoo { + fn foo(self); + } + + impl NuisanceFoo for T { + fn foo(self) {} + } +} + + +fn objectcandidate_impl() { + let x: internal::Smaht<(), u32> = internal::Smaht(Box::new(()), PhantomData); + let x: internal::Smaht = x; + + // This picks `>::foo` via `ObjectCandidate`. + // + // The `TraitCandidate` is not relevant because `X` is not in scope. + let z = x.foo(); + + // Observe the type of `z` is `u32` + let _seetype: () = z; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn traitcandidate_impl() { + use internal::X; + + let x: internal::Smaht<(), u64> = internal::Smaht(Box::new(()), PhantomData); + let x: internal::Smaht = x; + + // This picks `>::foo` via `TraitCandidate`. + // + // The `ObjectCandidate` does not apply, as it only applies to + // `X` (and not `X`). + let z = x.foo(); + + // Observe the type of `z` is `u64` + let _seetype: () = z; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn traitcandidate_impl_with_nuisance() { + use internal::X; + use nuisance_foo::NuisanceFoo; + + let x: internal::Smaht<(), u64> = internal::Smaht(Box::new(()), PhantomData); + let x: internal::Smaht = x; + + // This picks `>::foo` via `TraitCandidate`. + // + // The `ObjectCandidate` does not apply, as it only applies to + // `X` (and not `X`). + // + // The NuisanceFoo impl has the same priority as the `X` impl, + // so we get a conflict. + let z = x.foo(); // { dg-error ".E0034." "" { target *-*-* } } +} + + +fn neither_impl() { + let x: internal::Smaht<(), u64> = internal::Smaht(Box::new(()), PhantomData); + let x: internal::Smaht = x; + + // This can't pick the `TraitCandidate` impl, because `Foo` is not + // imported. However, this also can't pick the `ObjectCandidate` + // impl, because it only applies to `X` (and not `X`). + // + // Therefore, neither of the candidates is applicable, and we pick + // the `FinalFoo` impl after another deref, which will return `u8`. + let z = x.foo(); + + // Observe the type of `z` is `u8` + let _seetype: () = z; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn both_impls() { + use internal::X; + + let x: internal::Smaht<(), u32> = internal::Smaht(Box::new(()), PhantomData); + let x: internal::Smaht = x; + + // This can pick both the `TraitCandidate` and the `ObjectCandidate` impl. + // + // However, the `ObjectCandidate` is considered an "inherent candidate", + // and therefore has priority over both the `TraitCandidate` as well as + // any other "nuisance" candidate" (if present). + let z = x.foo(); + + // Observe the type of `z` is `u32` + let _seetype: () = z; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + + +fn both_impls_with_nuisance() { + // Similar to the `both_impls` example, except with a nuisance impl to + // make sure the `ObjectCandidate` indeed has a higher priority. + + use internal::X; + use nuisance_foo::NuisanceFoo; + + let x: internal::Smaht<(), u32> = internal::Smaht(Box::new(()), PhantomData); + let x: internal::Smaht = x; + let z = x.foo(); + + // Observe the type of `z` is `u32` + let _seetype: () = z; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-early-bound-lifetimes-on-self.rs b/gcc/testsuite/rust/rustc/ui/methods/method-early-bound-lifetimes-on-self.rs new file mode 100644 index 000000000000..6c02eb85e840 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-early-bound-lifetimes-on-self.rs @@ -0,0 +1,32 @@ +// run-pass +// Check that we successfully handle methods where the `self` type has +// an early-bound lifetime. Issue #18208. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +use std::marker; + +struct Cursor<'a> { + m: marker::PhantomData<&'a ()> +} + +trait CursorNavigator { + fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool; +} + +struct SimpleNavigator; + +impl CursorNavigator for SimpleNavigator { + fn init_cursor<'a, 'b: 'a>(&'a self, _cursor: &mut Cursor<'b>) -> bool { + false + } +} + +fn main() { + let mut c = Cursor { m: marker::PhantomData }; + let n = SimpleNavigator; + n.init_cursor(&mut c); +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-macro-backtrace.rs b/gcc/testsuite/rust/rustc/ui/methods/method-macro-backtrace.rs new file mode 100644 index 000000000000..0bae82ee0940 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-macro-backtrace.rs @@ -0,0 +1,26 @@ +// forbid-output: in this expansion of + +macro_rules! make_method { + ($name:ident) => ( fn $name(&self) { } ) +} + +struct S; + +impl S { + // We had a bug where these wouldn't clean up macro backtrace frames. + make_method!(foo1); + make_method!(foo2); + make_method!(foo3); + make_method!(foo4); + make_method!(foo5); + make_method!(foo6); + make_method!(foo7); + make_method!(foo8); + + // Cause an error. It shouldn't have any macro backtrace frames. + fn bar(&self) { } + fn bar(&self) { } // { dg-error ".E0201." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-missing-call.rs b/gcc/testsuite/rust/rustc/ui/methods/method-missing-call.rs new file mode 100644 index 000000000000..0877b5088826 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-missing-call.rs @@ -0,0 +1,31 @@ +// Tests to make sure that parens are needed for method calls without arguments. +// outputs text to make sure either an anonymous function is provided or +// open-close '()' parens are given + + +struct Point { + x: isize, + y: isize +} +impl Point { + fn new() -> Point { + Point{x:0, y:0} + } + fn get_x(&self) -> isize { + self.x + } +} + +fn main() { + let point: Point = Point::new(); + let px: isize = point + .get_x;// { dg-error ".E0615." "" { target *-*-* } } + + // Ensure the span is useful + let ys = &[1,2,3,4,5,6,7]; + let a = ys.iter() + .map(|x| x) + .filter(|&&x| x == 1) + .filter_map; // { dg-error ".E0615." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-mut-self-modifies-mut-slice-lvalue.rs b/gcc/testsuite/rust/rustc/ui/methods/method-mut-self-modifies-mut-slice-lvalue.rs new file mode 100644 index 000000000000..5860f67dc7a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-mut-self-modifies-mut-slice-lvalue.rs @@ -0,0 +1,45 @@ +// run-pass +// Test that an `&mut self` method, when invoked on a place whose +// type is `&mut [u8]`, passes in a pointer to the place and not a +// temporary. Issue #19147. + +use std::slice; +use std::cmp; + +trait MyWriter { + fn my_write(&mut self, buf: &[u8]) -> Result<(), ()>; +} + +impl<'a> MyWriter for &'a mut [u8] { + fn my_write(&mut self, buf: &[u8]) -> Result<(), ()> { + let amt = cmp::min(self.len(), buf.len()); + self[..amt].clone_from_slice(&buf[..amt]); + + let write_len = buf.len(); + unsafe { + *self = slice::from_raw_parts_mut( + self.as_mut_ptr().add(write_len), + self.len() - write_len + ); + } + + Ok(()) + } +} + +fn main() { + let mut buf = [0; 6]; + + { + let mut writer: &mut [_] = &mut buf; + writer.my_write(&[0, 1, 2]).unwrap(); + writer.my_write(&[3, 4, 5]).unwrap(); + } + + // If `my_write` is not modifying `buf` in place, then we will + // wind up with `[3, 4, 5, 0, 0, 0]` because the first call to + // `my_write()` doesn't update the starting point for the write. + + assert_eq!(buf, [0, 1, 2, 3, 4, 5]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-normalize-bounds-issue-20604.rs b/gcc/testsuite/rust/rustc/ui/methods/method-normalize-bounds-issue-20604.rs new file mode 100644 index 000000000000..2b025bbbe430 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-normalize-bounds-issue-20604.rs @@ -0,0 +1,62 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(stable_features)] + +// Test that we handle projection types which wind up important for +// resolving methods. This test was reduced from a larger example; the +// call to `foo()` at the end was failing to resolve because the +// winnowing stage of method resolution failed to handle an associated +// type projection. + +// pretty-expanded FIXME #23616 + +#![feature(associated_types)] + +trait Hasher { + type Output; + fn finish(&self) -> Self::Output; +} + +trait Hash { + fn hash(&self, h: &mut H); +} + +trait HashState { + type Wut: Hasher; + fn hasher(&self) -> Self::Wut; +} + +struct SipHasher; +impl Hasher for SipHasher { + type Output = u64; + fn finish(&self) -> u64 { 4 } +} + +impl Hash for isize { + fn hash(&self, h: &mut SipHasher) {} +} + +struct SipState; +impl HashState for SipState { + type Wut = SipHasher; + fn hasher(&self) -> SipHasher { SipHasher } +} + +struct Map { + s: S, +} + +impl Map + where S: HashState, + ::Wut: Hasher, +{ + fn foo(&self, k: K) where K: Hash< ::Wut> {} +} + +fn foo>(map: &Map) { + map.foo(22); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-on-ambiguous-numeric-type.rs b/gcc/testsuite/rust/rustc/ui/methods/method-on-ambiguous-numeric-type.rs new file mode 100644 index 000000000000..34725db371c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-on-ambiguous-numeric-type.rs @@ -0,0 +1,33 @@ +// aux-build:macro-in-other-crate.rs + +#[macro_use] extern crate macro_in_other_crate; + +macro_rules! local_mac { + ($ident:ident) => { let $ident = 42; } +} + +fn main() { + let x = 2.0.neg(); +// { dg-error ".E0689." "" { target *-*-* } .-1 } + + let y = 2.0; + let x = y.neg(); +// { dg-error ".E0689." "" { target *-*-* } .-1 } + println!("{:?}", x); + + for i in 0..100 { + println!("{}", i.pow(2)); +// { dg-error ".E0689." "" { target *-*-* } .-1 } + } + + local_mac!(local_bar); + local_bar.pow(2); +// { dg-error ".E0689." "" { target *-*-* } .-1 } +} + +fn qux() { + mac!(bar); + bar.pow(2); +// { dg-error ".E0689." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-path-in-pattern.rs b/gcc/testsuite/rust/rustc/ui/methods/method-path-in-pattern.rs new file mode 100644 index 000000000000..96ec602e8697 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-path-in-pattern.rs @@ -0,0 +1,33 @@ +struct Foo; + +impl Foo { + fn bar(&self) {} +} + +trait MyTrait { + fn trait_bar() {} +} + +impl MyTrait for Foo {} + +fn main() { + match 0u32 { + Foo::bar => {} +// { dg-error ".E0533." "" { target *-*-* } .-1 } + } + match 0u32 { + ::bar => {} +// { dg-error ".E0533." "" { target *-*-* } .-1 } + } + match 0u32 { + ::trait_bar => {} +// { dg-error ".E0533." "" { target *-*-* } .-1 } + } + if let Foo::bar = 0u32 {} +// { dg-error ".E0533." "" { target *-*-* } .-1 } + if let ::bar = 0u32 {} +// { dg-error ".E0533." "" { target *-*-* } .-1 } + if let Foo::trait_bar = 0u32 {} +// { dg-error ".E0533." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-probe-no-guessing-dyn-trait.rs b/gcc/testsuite/rust/rustc/ui/methods/method-probe-no-guessing-dyn-trait.rs new file mode 100644 index 000000000000..7b685e52d4d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-probe-no-guessing-dyn-trait.rs @@ -0,0 +1,61 @@ +// run-pass +// Check that method matching does not make "guesses" depending on +// Deref impls that don't eventually end up being picked. + +use std::ops::Deref; + +// An impl with less derefs will get called over an impl with more derefs, +// so `(t: Foo<_>).my_fn()` will use ` as MyTrait1>::my_fn(t)`, +// and does *not* force the `_` to equal `()`, because the Deref impl +// was *not* used. + +trait MyTrait1 { + fn my_fn(&self) {} +} + +impl MyTrait1 for Foo {} + +struct Foo(T); + +impl Deref for Foo<()> { + type Target = dyn MyTrait1 + 'static; + fn deref(&self) -> &(dyn MyTrait1 + 'static) { + panic!() + } +} + +// ...but if there is no impl with less derefs, the "guess" will be +// forced, so `(t: Bar<_>).my_fn2()` is `::my_fn2(*t)`, +// and because the deref impl is used, the `_` is forced to equal `u8`. + +trait MyTrait2 { + fn my_fn2(&self) {} +} + +impl MyTrait2 for u32 {} +struct Bar(T, u32); +impl Deref for Bar { + type Target = dyn MyTrait2 + 'static; + fn deref(&self) -> &(dyn MyTrait2 + 'static) { + &self.1 + } +} + +// actually invoke things + +fn main() { + let mut foo: Option> = None; + let mut bar: Option> = None; + let mut first_iter = true; + loop { + if !first_iter { + foo.as_ref().unwrap().my_fn(); + bar.as_ref().unwrap().my_fn2(); + break; + } + foo = Some(Foo(0)); + bar = Some(Bar(Default::default(), 0)); + first_iter = false; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-projection.rs b/gcc/testsuite/rust/rustc/ui/methods/method-projection.rs new file mode 100644 index 000000000000..21324eac73d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-projection.rs @@ -0,0 +1,62 @@ +// run-pass +// Test that we can use method notation to call methods based on a +// projection bound from a trait. Issue #20469. + +trait MakeString { + fn make_string(&self) -> String; +} + +impl MakeString for isize { + fn make_string(&self) -> String { + format!("{}", *self) + } +} + +impl MakeString for usize { + fn make_string(&self) -> String { + format!("{}", *self) + } +} + +trait Foo { + type F: MakeString; + + fn get(&self) -> &Self::F; +} + +fn foo(f: &F) -> String { + f.get().make_string() +} + +struct SomeStruct { + field: isize, +} + +impl Foo for SomeStruct { + type F = isize; + + fn get(&self) -> &isize { + &self.field + } +} + +struct SomeOtherStruct { + field: usize, +} + +impl Foo for SomeOtherStruct { + type F = usize; + + fn get(&self) -> &usize { + &self.field + } +} + +fn main() { + let x = SomeStruct { field: 22 }; + assert_eq!(foo(&x), format!("22")); + + let x = SomeOtherStruct { field: 44 }; + assert_eq!(foo(&x), format!("44")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-recursive-blanket-impl.rs b/gcc/testsuite/rust/rustc/ui/methods/method-recursive-blanket-impl.rs new file mode 100644 index 000000000000..ba874d693902 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-recursive-blanket-impl.rs @@ -0,0 +1,42 @@ +// run-pass +#![allow(unused_variables)] +#![allow(unused_imports)] +// Test that we don't trigger on the blanket impl for all `&'a T` but +// rather keep autoderefing and trigger on the underlying impl. To +// know not to stop at the blanket, we have to recursively evaluate +// the `T:Foo` bound. + +// pretty-expanded FIXME #23616 + +use std::marker::Sized; + +// Note: this must be generic for the problem to show up +trait Foo { + fn foo(&self, a: A); +} + +impl Foo for [u8] { + fn foo(&self, a: u8) {} +} + +impl<'a, A, T> Foo for &'a T where T: Foo { + fn foo(&self, a: A) { + Foo::foo(*self, a) + } +} + +trait Bar { + fn foo(&self); +} + +struct MyType; + +impl Bar for MyType { + fn foo(&self) {} +} + +fn main() { + let mut m = MyType; + (&mut m).foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-resolvable-path-in-pattern.rs b/gcc/testsuite/rust/rustc/ui/methods/method-resolvable-path-in-pattern.rs new file mode 100644 index 000000000000..293dff0bf340 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-resolvable-path-in-pattern.rs @@ -0,0 +1,15 @@ +struct Foo; + +trait MyTrait { + fn trait_bar() {} +} + +impl MyTrait for Foo {} + +fn main() { + match 0u32 { + ::trait_bar => {} +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-1.rs b/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-1.rs new file mode 100644 index 000000000000..4994dd73558c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-1.rs @@ -0,0 +1,18 @@ +// Test method calls with self as an argument cannot subvert type checking. + +struct Foo; + +impl Foo { + fn bar(&self) {} +} + +fn main() { + let x = Foo; + Foo::bar(x); // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + Foo::bar(&42); // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-2.rs b/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-2.rs new file mode 100644 index 000000000000..e917ffd07c5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-2.rs @@ -0,0 +1,26 @@ +// Test method calls with self as an argument cannot subvert borrow checking. + + + +struct Foo; + +impl Foo { + fn bar(&self) {} + fn baz(&mut self) {} +} + +fn main() { + let mut x = Foo; + let y = &mut x; + Foo::bar(&x); // { dg-error ".E0502." "" { target *-*-* } } + y.use_mut(); + + let mut x = Foo; + let y = &mut x; + Foo::baz(&mut x); // { dg-error ".E0499." "" { target *-*-* } } + y.use_mut(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-aux1.rs b/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-aux1.rs new file mode 100644 index 000000000000..5559955e25ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-aux1.rs @@ -0,0 +1,21 @@ +// run-pass +// Test method calls with self as an argument (cross-crate) + +#![feature(box_syntax)] + +// aux-build:method_self_arg1.rs +extern crate method_self_arg1; +use method_self_arg1::Foo; + +fn main() { + let x = Foo; + // Test external call. + Foo::bar(&x); + Foo::baz(x); + Foo::qux(box x); + + x.foo(&x); + + assert_eq!(method_self_arg1::get_count(), 2*3*3*3*5*5*5*7*7*7); +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-aux2.rs b/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-aux2.rs new file mode 100644 index 000000000000..21bcd53f1fe0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-aux2.rs @@ -0,0 +1,25 @@ +// run-pass +// Test method calls with self as an argument (cross-crate) + +#![feature(box_syntax)] + +// aux-build:method_self_arg2.rs +extern crate method_self_arg2; +use method_self_arg2::{Foo, Bar}; + +fn main() { + let x = Foo; + // Test external call. + Bar::foo1(&x); + Bar::foo2(x); + Bar::foo3(box x); + + Bar::bar1(&x); + Bar::bar2(x); + Bar::bar3(box x); + + x.run_trait(); + + assert_eq!(method_self_arg2::get_count(), 2*2*3*3*5*5*7*7*11*11*13*13*17); +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-trait.rs b/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-trait.rs new file mode 100644 index 000000000000..6b4917b6603a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-self-arg-trait.rs @@ -0,0 +1,70 @@ +// run-pass +// Test method calls with self as an argument + +#![feature(box_syntax)] + +static mut COUNT: u64 = 1; + +#[derive(Copy, Clone)] +struct Foo; + +trait Bar : Sized { + fn foo1(&self); + fn foo2(self); + fn foo3(self: Box); + + fn bar1(&self) { + unsafe { COUNT *= 7; } + } + fn bar2(self) { + unsafe { COUNT *= 11; } + } + fn bar3(self: Box) { + unsafe { COUNT *= 13; } + } +} + +impl Bar for Foo { + fn foo1(&self) { + unsafe { COUNT *= 2; } + } + + fn foo2(self) { + unsafe { COUNT *= 3; } + } + + fn foo3(self: Box) { + unsafe { COUNT *= 5; } + } +} + +impl Foo { + fn baz(self) { + unsafe { COUNT *= 17; } + // Test internal call. + Bar::foo1(&self); + Bar::foo2(self); + Bar::foo3(box self); + + Bar::bar1(&self); + Bar::bar2(self); + Bar::bar3(box self); + } +} + +fn main() { + let x = Foo; + // Test external call. + Bar::foo1(&x); + Bar::foo2(x); + Bar::foo3(box x); + + Bar::bar1(&x); + Bar::bar2(x); + Bar::bar3(box x); + + x.baz(); + + unsafe { assert_eq!(COUNT, 2*2*3*3*5*5*7*7*11*11*13*13*17); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-self-arg.rs b/gcc/testsuite/rust/rustc/ui/methods/method-self-arg.rs new file mode 100644 index 000000000000..05b5ca437355 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-self-arg.rs @@ -0,0 +1,49 @@ +// run-pass +// Test method calls with self as an argument + +#![feature(box_syntax)] + +static mut COUNT: usize = 1; + +#[derive(Copy, Clone)] +struct Foo; + +impl Foo { + fn foo(self, x: &Foo) { + unsafe { COUNT *= 2; } + // Test internal call. + Foo::bar(&self); + Foo::bar(x); + + Foo::baz(self); + Foo::baz(*x); + + Foo::qux(box self); + Foo::qux(box *x); + } + + fn bar(&self) { + unsafe { COUNT *= 3; } + } + + fn baz(self) { + unsafe { COUNT *= 5; } + } + + fn qux(self: Box) { + unsafe { COUNT *= 7; } + } +} + +fn main() { + let x = Foo; + // Test external call. + Foo::bar(&x); + Foo::baz(x); + Foo::qux(box x); + + x.foo(&x); + + unsafe { assert_eq!(COUNT, 2*3*3*3*5*5*5*7*7*7); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-trait-object-with-hrtb.rs b/gcc/testsuite/rust/rustc/ui/methods/method-trait-object-with-hrtb.rs new file mode 100644 index 000000000000..2974b35198f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-trait-object-with-hrtb.rs @@ -0,0 +1,42 @@ +// build-pass (FIXME(62277): could be check-pass?) + +// Check that method probing ObjectCandidate works in the presence of +// auto traits and/or HRTBs. + +mod internal { + pub trait MyObject<'a> { + type Output; + + fn foo(&self) -> Self::Output; + } + + impl<'a> MyObject<'a> for () { + type Output = &'a u32; + + fn foo(&self) -> Self::Output { &4 } + } +} + +fn t1(d: &dyn for<'a> internal::MyObject<'a, Output=&'a u32>) { + d.foo(); +} + +fn t2(d: &dyn internal::MyObject<'static, Output=&'static u32>) { + d.foo(); +} + +fn t3(d: &(dyn for<'a> internal::MyObject<'a, Output=&'a u32> + Sync)) { + d.foo(); +} + +fn t4(d: &(dyn internal::MyObject<'static, Output=&'static u32> + Sync)) { + d.foo(); +} + +fn main() { + t1(&()); + t2(&()); + t3(&()); + t4(&()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-two-trait-defer-resolution-1.rs b/gcc/testsuite/rust/rustc/ui/methods/method-two-trait-defer-resolution-1.rs new file mode 100644 index 000000000000..4fc4625811c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-two-trait-defer-resolution-1.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(non_camel_case_types)] + +// Test that we pick which version of `foo` to run based on the +// type that is (ultimately) inferred for `x`. + + +trait foo { + fn foo(&self) -> i32; +} + +impl foo for Vec { + fn foo(&self) -> i32 {1} +} + +impl foo for Vec { + fn foo(&self) -> i32 {2} +} + +fn call_foo_uint() -> i32 { + let mut x = Vec::new(); + let y = x.foo(); + x.push(0u32); + y +} + +fn call_foo_int() -> i32 { + let mut x = Vec::new(); + let y = x.foo(); + x.push(0i32); + y +} + +fn main() { + assert_eq!(call_foo_uint(), 1); + assert_eq!(call_foo_int(), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-two-trait-defer-resolution-2.rs b/gcc/testsuite/rust/rustc/ui/methods/method-two-trait-defer-resolution-2.rs new file mode 100644 index 000000000000..f7e3fa212d70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-two-trait-defer-resolution-2.rs @@ -0,0 +1,49 @@ +// run-pass +// Test that when we write `x.foo()`, we do not have to know the +// complete type of `x` in order to type-check the method call. In +// this case, we know that `x: Vec<_1>`, but we don't know what type +// `_1` is (because the call to `push` comes later). To pick between +// the impls, we would have to know `_1`, since we have to know +// whether `_1: MyCopy` or `_1 == Box`. However (and this is the +// point of the test), we don't have to pick between the two impls -- +// it is enough to know that `foo` comes from the `Foo` trait. We can +// codegen the call as `Foo::foo(&x)` and let the specific impl get +// chosen later. + +#![feature(box_syntax)] + +trait Foo { + fn foo(&self) -> isize; +} + +trait MyCopy { fn foo(&self) { } } +impl MyCopy for i32 { } + +impl Foo for Vec { + fn foo(&self) -> isize {1} +} + +impl Foo for Vec> { + fn foo(&self) -> isize {2} +} + +fn call_foo_copy() -> isize { + let mut x = Vec::new(); + let y = x.foo(); + x.push(0_i32); + y +} + +fn call_foo_other() -> isize { + let mut x: Vec<_> = Vec::new(); + let y = x.foo(); + let z: Box = box 0; + x.push(z); + y +} + +fn main() { + assert_eq!(call_foo_copy(), 1); + assert_eq!(call_foo_other(), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-two-traits-distinguished-via-where-clause.rs b/gcc/testsuite/rust/rustc/ui/methods/method-two-traits-distinguished-via-where-clause.rs new file mode 100644 index 000000000000..250d3ea5d11b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-two-traits-distinguished-via-where-clause.rs @@ -0,0 +1,28 @@ +// run-pass +// Test that we select between traits A and B. To do that, we must +// consider the `Sized` bound. + +// pretty-expanded FIXME #23616 + +trait A { + fn foo(self); +} + +trait B { + fn foo(self); +} + +impl A for *const T { + fn foo(self) {} +} + +impl B for *const [T] { + fn foo(self) {} +} + +fn main() { + let x: [isize; 4] = [1,2,3,4]; + let xptr = &x[..] as *const [isize]; + xptr.foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/methods/method-where-clause.rs b/gcc/testsuite/rust/rustc/ui/methods/method-where-clause.rs new file mode 100644 index 000000000000..35ece9b666ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/methods/method-where-clause.rs @@ -0,0 +1,35 @@ +// run-pass +// Test that we can use method notation to call methods based on a +// where clause type, and not only type parameters. + + +trait Foo { + fn foo(&self) -> i32; +} + +impl Foo for Option +{ + fn foo(&self) -> i32 { + self.unwrap_or(22) + } +} + +impl Foo for Option +{ + fn foo(&self) -> i32 { + self.unwrap_or(22) as i32 + } +} + +fn check(x: Option) -> (i32, i32) + where Option : Foo +{ + let y: Option = None; + (x.foo(), y.foo()) +} + +fn main() { + assert_eq!(check(Some(23u32)), (23, 22)); + assert_eq!(check(Some(23)), (23, 22)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mid-path-type-params.rs b/gcc/testsuite/rust/rustc/ui/mid-path-type-params.rs new file mode 100644 index 000000000000..ac094412b2cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mid-path-type-params.rs @@ -0,0 +1,38 @@ +// run-pass + +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct S { + contents: T, +} + +impl S { + fn new(x: T, _: U) -> S { + S { + contents: x, + } + } +} + +trait Trait { + fn new(x: T, y: U) -> Self; +} + +struct S2 { + contents: isize, +} + +impl Trait for S2 { + fn new(x: isize, _: U) -> S2 { + S2 { + contents: x, + } + } +} + +pub fn main() { + let _ = S::::new::(1, 1.0); + let _: S2 = Trait::::new::(1, 1.0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/minmax-stability-issue-23687.rs b/gcc/testsuite/rust/rustc/ui/minmax-stability-issue-23687.rs new file mode 100644 index 000000000000..4f7f8208d394 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/minmax-stability-issue-23687.rs @@ -0,0 +1,65 @@ +// run-pass + +use std::fmt::Debug; +use std::cmp::{self, PartialOrd, Ordering}; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +struct Foo { + n: u8, + name: &'static str +} + +impl PartialOrd for Foo { + fn partial_cmp(&self, other: &Foo) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Foo { + fn cmp(&self, other: &Foo) -> Ordering { + self.n.cmp(&other.n) + } +} + +fn main() { + let a = Foo { n: 4, name: "a" }; + let b = Foo { n: 4, name: "b" }; + let c = Foo { n: 8, name: "c" }; + let d = Foo { n: 8, name: "d" }; + let e = Foo { n: 22, name: "e" }; + let f = Foo { n: 22, name: "f" }; + + let data = [a, b, c, d, e, f]; + + // `min` should return the left when the values are equal + assert_eq!(data.iter().min(), Some(&a)); + assert_eq!(data.iter().min_by_key(|a| a.n), Some(&a)); + assert_eq!(cmp::min(a, b), a); + assert_eq!(cmp::min(b, a), b); + + // `max` should return the right when the values are equal + assert_eq!(data.iter().max(), Some(&f)); + assert_eq!(data.iter().max_by_key(|a| a.n), Some(&f)); + assert_eq!(cmp::max(e, f), f); + assert_eq!(cmp::max(f, e), e); + + let mut presorted = data.to_vec(); + presorted.sort(); + assert_stable(&presorted); + + let mut presorted = data.to_vec(); + presorted.sort_by(|a, b| a.cmp(b)); + assert_stable(&presorted); + + // Assert that sorted and min/max are the same + fn assert_stable(presorted: &[T]) { + for slice in presorted.windows(2) { + let a = &slice[0]; + let b = &slice[1]; + + assert_eq!(a, cmp::min(a, b)); + assert_eq!(b, cmp::max(a, b)); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/minus-string.rs b/gcc/testsuite/rust/rustc/ui/minus-string.rs new file mode 100644 index 000000000000..6942e8eec65c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/minus-string.rs @@ -0,0 +1,4 @@ +// error-pattern:cannot apply unary operator `-` to type `String` + +fn main() { -"foo".to_string(); } + diff --git a/gcc/testsuite/rust/rustc/ui/mir-dataflow/def-inits-1.rs b/gcc/testsuite/rust/rustc/ui/mir-dataflow/def-inits-1.rs new file mode 100644 index 000000000000..0266ae858b2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir-dataflow/def-inits-1.rs @@ -0,0 +1,52 @@ +// General test of maybe_uninits state computed by MIR dataflow. + +#![feature(core_intrinsics, rustc_attrs)] + +use std::intrinsics::rustc_peek; +use std::mem::{drop, replace}; + +struct S(i32); + +#[rustc_mir(rustc_peek_definite_init,stop_after_dataflow)] +fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S { + let ret; + // `ret` starts off uninitialized + rustc_peek(&ret); // { dg-error "" "" { target *-*-* } } + + // All function formal parameters start off initialized. + + rustc_peek(&x); + rustc_peek(&y); + rustc_peek(&z); + + ret = if test { + ::std::mem::replace(x, y) + } else { + z = y; + z + }; + + // `z` may be uninitialized here. + rustc_peek(&z); // { dg-error "" "" { target *-*-* } } + + // `y` is definitely uninitialized here. + rustc_peek(&y); // { dg-error "" "" { target *-*-* } } + + // `x` is still (definitely) initialized (replace above is a reborrow). + rustc_peek(&x); + + ::std::mem::drop(x); + + // `x` is *definitely* uninitialized here + rustc_peek(&x); // { dg-error "" "" { target *-*-* } } + + // `ret` is now definitely initialized (via `if` above). + rustc_peek(&ret); + + ret +} +fn main() { + foo(true, &mut S(13), S(14), S(15)); + foo(false, &mut S(13), S(14), S(15)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir-dataflow/indirect-mutation-offset.rs b/gcc/testsuite/rust/rustc/ui/mir-dataflow/indirect-mutation-offset.rs new file mode 100644 index 000000000000..73be60770df9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir-dataflow/indirect-mutation-offset.rs @@ -0,0 +1,49 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you + +// This test demonstrates a shortcoming of the `MaybeMutBorrowedLocals` analysis. It does not +// handle code that takes a reference to one field of a struct, then use pointer arithmetic to +// transform it to another field of that same struct that may have interior mutability. For now, +// this is UB, but this may change in the future. See [rust-lang/unsafe-code-guidelines#134]. +// +// [rust-lang/unsafe-code-guidelines#134]: https://github.com/rust-lang/unsafe-code-guidelines/issues/134 + +#![feature(core_intrinsics, rustc_attrs, const_raw_ptr_deref)] + +use std::cell::UnsafeCell; +use std::intrinsics::rustc_peek; + +#[repr(C)] +struct PartialInteriorMut { + zst: [i32; 0], + cell: UnsafeCell, +} + +#[rustc_mir(rustc_peek_indirectly_mutable,stop_after_dataflow)] +const BOO: i32 = { + let x = PartialInteriorMut { + zst: [], + cell: UnsafeCell::new(0), + }; + + let p_zst: *const _ = &x.zst ; // Doesn't cause `x` to get marked as indirectly mutable. + + let rmut_cell = unsafe { + // Take advantage of the fact that `zst` and `cell` are at the same location in memory. + // This trick would work with any size type if miri implemented `ptr::offset`. + let p_cell = p_zst as *const UnsafeCell; + + let pmut_cell = (*p_cell).get(); + &mut *pmut_cell + }; + + *rmut_cell = 42; // Mutates `x` indirectly even though `x` is not marked indirectly mutable!!! + let val = *rmut_cell; + rustc_peek(x); // { dg-error "" "" { target *-*-* } } + + val +}; + +fn main() { + println!("{}", BOO); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir-dataflow/inits-1.rs b/gcc/testsuite/rust/rustc/ui/mir-dataflow/inits-1.rs new file mode 100644 index 000000000000..6976e1a14fbf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir-dataflow/inits-1.rs @@ -0,0 +1,54 @@ +// General test of maybe_inits state computed by MIR dataflow. + +#![feature(core_intrinsics, rustc_attrs)] + +use std::intrinsics::rustc_peek; +use std::mem::{drop, replace}; + +struct S(i32); + +#[rustc_mir(rustc_peek_maybe_init,stop_after_dataflow)] +fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S { + let ret; + // `ret` starts off uninitialized, so we get an error report here. + rustc_peek(&ret); // { dg-error "" "" { target *-*-* } } + + // All function formal parameters start off initialized. + + rustc_peek(&x); + rustc_peek(&y); + rustc_peek(&z); + + ret = if test { + ::std::mem::replace(x, y) + } else { + z = y; + z + }; + + + // `z` may be initialized here. + rustc_peek(&z); + + // `y` is definitely uninitialized here. + rustc_peek(&y); // { dg-error "" "" { target *-*-* } } + + // `x` is still (definitely) initialized (replace above is a reborrow). + rustc_peek(&x); + + ::std::mem::drop(x); + + // `x` is *definitely* uninitialized here + rustc_peek(&x); // { dg-error "" "" { target *-*-* } } + + // `ret` is now definitely initialized (via `if` above). + rustc_peek(&ret); + + ret +} + +fn main() { + foo(true, &mut S(13), S(14), S(15)); + foo(false, &mut S(13), S(14), S(15)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir-dataflow/liveness-projection.rs b/gcc/testsuite/rust/rustc/ui/mir-dataflow/liveness-projection.rs new file mode 100644 index 000000000000..38c10d8ac70a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir-dataflow/liveness-projection.rs @@ -0,0 +1,33 @@ +#![feature(core_intrinsics, rustc_attrs)] + +use std::intrinsics::rustc_peek; + +#[rustc_mir(rustc_peek_liveness, stop_after_dataflow)] +fn foo() { + { + let mut x: (i32, i32) = (42, 0); + + // Assignment to a projection does not cause `x` to become live + unsafe { rustc_peek(x); } // { dg-error "" "" { target *-*-* } } + x.1 = 42; + + x = (0, 42); + + // ...but a read from a projection does. + unsafe { rustc_peek(x); } + println!("{}", x.1); + } + + { + let mut x = 42; + + // Derefs are treated like a read of a local even if they are on the LHS of an assignment. + let p = &mut x; + unsafe { rustc_peek(&p); } + *p = 24; + unsafe { rustc_peek(&p); } // { dg-error "" "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mir-dataflow/liveness-ptr.rs b/gcc/testsuite/rust/rustc/ui/mir-dataflow/liveness-ptr.rs new file mode 100644 index 000000000000..d6a8024ef3cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir-dataflow/liveness-ptr.rs @@ -0,0 +1,29 @@ +#![feature(core_intrinsics, rustc_attrs)] + +use std::intrinsics::rustc_peek; + +#[rustc_mir(rustc_peek_liveness, stop_after_dataflow)] +fn foo() -> i32 { + let mut x: i32; + let mut p: *const i32; + + x = 0; + + // `x` is live here since it is used in the next statement... + rustc_peek(x); + + p = &x; + + // ... but not here, even while it can be accessed through `p`. + rustc_peek(x); // { dg-error "" "" { target *-*-* } } + let tmp = unsafe { *p }; + + x = tmp + 1; + + rustc_peek(x); + + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mir-dataflow/uninits-1.rs b/gcc/testsuite/rust/rustc/ui/mir-dataflow/uninits-1.rs new file mode 100644 index 000000000000..5f9bb3e8bcdb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir-dataflow/uninits-1.rs @@ -0,0 +1,52 @@ +// General test of maybe_uninits state computed by MIR dataflow. + +#![feature(core_intrinsics, rustc_attrs)] + +use std::intrinsics::rustc_peek; +use std::mem::{drop, replace}; + +struct S(i32); + +#[rustc_mir(rustc_peek_maybe_uninit,stop_after_dataflow)] +fn foo(test: bool, x: &mut S, y: S, mut z: S) -> S { + let ret; + // `ret` starts off uninitialized + rustc_peek(&ret); + + // All function formal parameters start off initialized. + + rustc_peek(&x); // { dg-error "" "" { target *-*-* } } + rustc_peek(&y); // { dg-error "" "" { target *-*-* } } + rustc_peek(&z); // { dg-error "" "" { target *-*-* } } + + ret = if test { + ::std::mem::replace(x, y) + } else { + z = y; + z + }; + + // `z` may be uninitialized here. + rustc_peek(&z); + + // `y` is definitely uninitialized here. + rustc_peek(&y); + + // `x` is still (definitely) initialized (replace above is a reborrow). + rustc_peek(&x); // { dg-error "" "" { target *-*-* } } + + ::std::mem::drop(x); + + // `x` is *definitely* uninitialized here + rustc_peek(&x); + + // `ret` is now definitely initialized (via `if` above). + rustc_peek(&ret); // { dg-error "" "" { target *-*-* } } + + ret +} +fn main() { + foo(true, &mut S(13), S(14), S(15)); + foo(false, &mut S(13), S(14), S(15)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir-dataflow/uninits-2.rs b/gcc/testsuite/rust/rustc/ui/mir-dataflow/uninits-2.rs new file mode 100644 index 000000000000..92037037d423 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir-dataflow/uninits-2.rs @@ -0,0 +1,25 @@ +// General test of maybe_uninits state computed by MIR dataflow. + +#![feature(core_intrinsics, rustc_attrs)] + +use std::intrinsics::rustc_peek; +use std::mem::{drop, replace}; + +struct S(i32); + +#[rustc_mir(rustc_peek_maybe_uninit,stop_after_dataflow)] +fn foo(x: &mut S) { + // `x` is initialized here, so maybe-uninit bit is 0. + + rustc_peek(&x); // { dg-error "" "" { target *-*-* } } + + ::std::mem::drop(x); + + // `x` definitely uninitialized here, so maybe-uninit bit is 1. + rustc_peek(&x); +} +fn main() { + foo(&mut S(13)); + foo(&mut S(13)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir-unpretty.rs b/gcc/testsuite/rust/rustc/ui/mir-unpretty.rs new file mode 100644 index 000000000000..01fb1943cde1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir-unpretty.rs @@ -0,0 +1,6 @@ +// compile-flags: -Z unpretty=mir + +fn main() { + let x: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/auxiliary/issue_76375_aux.rs b/gcc/testsuite/rust/rustc/ui/mir/auxiliary/issue_76375_aux.rs new file mode 100644 index 000000000000..c72028d1df13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/auxiliary/issue_76375_aux.rs @@ -0,0 +1,15 @@ +// edition:2018 +// compile-flags: -Z mir-opt-level=2 -Z unsound-mir-opts + +#[inline(always)] +pub fn f(s: bool) -> String { + let a = "Hello world!".to_string(); + let b = a; + let c = b; + if s { + c + } else { + String::new() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/auxiliary/mir_external_refs.rs b/gcc/testsuite/rust/rustc/ui/mir/auxiliary/mir_external_refs.rs new file mode 100644 index 000000000000..7098483214ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/auxiliary/mir_external_refs.rs @@ -0,0 +1,18 @@ +pub struct S(pub u8); + +impl S { + pub fn hey() -> u8 { 24 } +} + +pub trait X { + fn hoy(&self) -> u8 { 25 } +} + +impl X for S {} + +pub enum E { + U(u8) +} + +pub fn regular_fn() -> u8 { 12 } + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-60390.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-60390.rs new file mode 100644 index 000000000000..f0528e2efb77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-60390.rs @@ -0,0 +1,9 @@ +// check-pass +// compile-flags: --emit=mir,link +// Regression test for #60390, this ICE requires `--emit=mir` flag. + +fn main() { + enum Inner { Member(u32) }; + Inner::Member(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-66930.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-66930.rs new file mode 100644 index 000000000000..0b8b771af532 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-66930.rs @@ -0,0 +1,12 @@ +// check-pass +// compile-flags: --emit=mir,link +// Regression test for #66930, this ICE requires `--emit=mir` flag. + +static UTF8_CHAR_WIDTH: [u8; 0] = []; + +pub fn utf8_char_width(b: u8) -> usize { + UTF8_CHAR_WIDTH[b as usize] as usize +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-67639-normalization-ice.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-67639-normalization-ice.rs new file mode 100644 index 000000000000..f9e55dc7b8ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-67639-normalization-ice.rs @@ -0,0 +1,35 @@ +// compile-flags: -Z mir-opt-level=3 +// build-pass + +// This used to ICE in const-prop due +// to an empty ParamEnv being used during normalization +// of a generic type + + +fn main() { + join_all::(); +} + +trait Foo { + type Item; +} + +impl Foo for u32 { + type Item = u8; +} + +trait Bar { + type Item2; +} + +impl Bar for u8 { + type Item2 = u64; +} + +fn join_all() +where I: Foo, + I::Item: Bar +{ + Vec::<::Item2>::new(); // ICE occurs processing this line +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-67710-inline-projection.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-67710-inline-projection.rs new file mode 100644 index 000000000000..47f9d84043f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-67710-inline-projection.rs @@ -0,0 +1,18 @@ +// compile-flags: -Z mir-opt-level=2 +// build-pass + +// This used to ICE due to the inling pass not examining projections +// for references to locals + +pub fn parse(version: ()) { + p(&b'.', b"0"); +} +#[inline(always)] +fn p(byte: &u8, s: &[u8]) { + !(s[0] == *byte); +} + +fn main() { + parse(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-67947.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-67947.rs new file mode 100644 index 000000000000..cf9eaa8207bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-67947.rs @@ -0,0 +1,8 @@ +struct Bug { + A: [(); { *"" }.len()], +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { dg-error ".E0507." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-68841.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-68841.rs new file mode 100644 index 000000000000..b796b75e3aae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-68841.rs @@ -0,0 +1,16 @@ +// compile-flags: -Z mir-opt-level=2 +// edition:2018 +// build-pass + +#![feature(async_closure)] + +use std::future::Future; + +fn async_closure() -> impl Future { + (async move || -> u8 { 42 })() +} + +fn main() { + let _fut = async_closure(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-71793-inline-args-storage.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-71793-inline-args-storage.rs new file mode 100644 index 000000000000..3119185482f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-71793-inline-args-storage.rs @@ -0,0 +1,17 @@ +// Verifies that inliner emits StorageLive & StorageDead when introducing +// temporaries for arguments, so that they don't become part of the generator. +// Regression test for #71793. +// +// check-pass +// edition:2018 +// compile-args: -Zmir-opt-level=2 + +#![crate_type = "lib"] + +pub async fn connect() {} + +pub async fn connect_many() { + Vec::::new().first().ok_or("").unwrap(); + connect().await; +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-75053.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-75053.rs new file mode 100644 index 000000000000..5c11cf65a5b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-75053.rs @@ -0,0 +1,49 @@ +// compile-flags: -Z mir-opt-level=2 +// build-pass + +#![feature(type_alias_impl_trait)] + +use std::marker::PhantomData; + +trait MyIndex { + type O; + fn my_index(self) -> Self::O; +} +trait MyFrom: Sized { + type Error; + fn my_from(value: T) -> Result; +} + +trait F {} +impl F for () {} +type DummyT = impl F; +fn _dummy_t() -> DummyT {} + +struct Phantom1(PhantomData); +struct Phantom2(PhantomData); +struct Scope(Phantom2>); + +impl Scope { + fn new() -> Self { + unimplemented!() + } +} + +impl MyFrom> for Phantom1 { + type Error = (); + fn my_from(_: Phantom2) -> Result { + unimplemented!() + } +} + +impl>>, U> MyIndex> for Scope { + type O = T; + fn my_index(self) -> Self::O { + MyFrom::my_from(self.0).ok().unwrap() + } +} + +fn main() { + let _pos: Phantom1> = Scope::new().my_index(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-75419-validation-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-75419-validation-impl-trait.rs new file mode 100644 index 000000000000..a6bf37431f61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-75419-validation-impl-trait.rs @@ -0,0 +1,14 @@ +// build-pass + +// This used to fail MIR validation due to the types on both sides of +// an assignment not being equal. +// The failure doesn't occur with a check-only build. + +fn iter_slice<'a, T>(xs: &'a [T]) -> impl Iterator { + xs.iter() +} + +fn main() { + iter_slice::<()> as fn(_) -> _; +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-76248.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-76248.rs new file mode 100644 index 000000000000..acd9176d8b48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-76248.rs @@ -0,0 +1,30 @@ +// This used to ICE during codegen after MIR inlining of g into f. +// The root cause was a missing fold of length constant in Rvalue::Repeat. +// Regression test for #76248. +// +// build-pass +// compile-flags: -Zmir-opt-level=2 + +const N: usize = 1; + +pub struct Elem { + pub x: [usize; N], + pub m: M, +} + +pub fn f() -> Elem<()> { + g(()) +} + +#[inline] +pub fn g(m: M) -> Elem { + Elem { + x: [0; N], + m, + } +} + +pub fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-76375.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-76375.rs new file mode 100644 index 000000000000..e16f7fff576f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-76375.rs @@ -0,0 +1,16 @@ +// edition:2018 +// build-pass +// compile-flags: -Z mir-opt-level=2 -L. +// aux-build:issue_76375_aux.rs + +#![crate_type = "lib"] + +extern crate issue_76375_aux; + +pub async fn g() { + issue_76375_aux::f(true); + h().await; +} + +pub async fn h() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-76740-copy-propagation.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-76740-copy-propagation.rs new file mode 100644 index 000000000000..598e90bbaa33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-76740-copy-propagation.rs @@ -0,0 +1,31 @@ +// Regression test for issue #76740. +// run-pass +// compile-flags: -Zmir-opt-level=3 + +#[derive(Copy, Clone)] +pub struct V([usize; 4]); + +impl V { + fn new() -> Self { + V([0; 4]) + } + + #[inline(never)] + fn check(mut self) { + assert_eq!(self.0[0], 0); + self.0[0] = 1; + } +} + +fn main() { + let v = V::new(); + let mut i = 0; + while i != 10 { + // Copy propagation incorrectly assumed that Operand::Move does not + // mutate the local, and used the same v for each V::check call, + // rather than a copy. + v.check(); + i += 1; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-76803-branches-not-same.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-76803-branches-not-same.rs new file mode 100644 index 000000000000..065b3c491fe0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-76803-branches-not-same.rs @@ -0,0 +1,20 @@ +// run-pass + +#[derive(Debug, Eq, PartialEq)] +pub enum Type { + A, + B, +} + + +pub fn encode(v: Type) -> Type { + match v { + Type::A => Type::B, + _ => v, + } +} + +fn main() { + assert_eq!(Type::B, encode(Type::A)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-77359-simplify-arm-identity.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-77359-simplify-arm-identity.rs new file mode 100644 index 000000000000..c9695af7b8e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-77359-simplify-arm-identity.rs @@ -0,0 +1,36 @@ +// run-pass + +#![allow(dead_code)] + +#[derive(Debug)] +enum MyEnum { + Variant1(Vec), + Variant2, + Variant3, + Variant4, +} + +fn f(arg1: &bool, arg2: &bool, arg3: bool) -> MyStruct { + if *arg1 { + println!("{:?}", f(&arg2, arg2, arg3)); + MyStruct(None) + } else { + match if arg3 { Some(MyEnum::Variant3) } else { None } { + Some(t) => { + let ah = t; + return MyStruct(Some(ah)); + } + _ => MyStruct(None) + } + } +} + +#[derive(Debug)] +struct MyStruct(Option); + +fn main() { + let arg1 = true; + let arg2 = false; + f(&arg1, &arg2, true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue-77911.rs b/gcc/testsuite/rust/rustc/ui/mir/issue-77911.rs new file mode 100644 index 000000000000..80fcdb332b48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue-77911.rs @@ -0,0 +1,17 @@ +// compile-flags: -Z mir-opt-level=2 +// ignore-cloudabi no std::fs +// build-pass + +use std::fs::File; +use std::io::{BufRead, BufReader}; + +fn file_lines() -> impl Iterator { + BufReader::new(File::open("").unwrap()) + .lines() + .map(Result::unwrap) +} + +fn main() { + for _ in file_lines() {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/issue66339.rs b/gcc/testsuite/rust/rustc/ui/mir/issue66339.rs new file mode 100644 index 000000000000..4f521f8ad37f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/issue66339.rs @@ -0,0 +1,14 @@ +// compile-flags: -Z mir-opt-level=2 +// build-pass + +// This used to ICE in const-prop + +fn foo() { + let bar = |_| { }; + let _ = bar("a"); +} + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-45493.rs b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-45493.rs new file mode 100644 index 000000000000..8012d8747e9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-45493.rs @@ -0,0 +1,18 @@ +// run-pass +// compile-flags:-Zmir-opt-level=2 + +trait Array { + type Item; +} + +fn foo() { + let _: *mut A::Item = std::ptr::null_mut(); +} + +struct Foo; +impl Array for Foo { type Item = i32; } + +fn main() { + foo::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-45885.rs b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-45885.rs new file mode 100644 index 000000000000..68bdf580ab7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-45885.rs @@ -0,0 +1,30 @@ +// run-pass +// compile-flags:-Zmir-opt-level=2 + +pub enum Enum { + A, + B, +} + +trait SliceIndex { + type Output; + fn get(&self) -> &Self::Output; +} + +impl SliceIndex for usize { + type Output = Enum; + #[inline(never)] + fn get(&self) -> &Enum { + &Enum::A + } +} + +#[inline(always)] +fn index(t: &T) -> &T::Output { + t.get() +} + +fn main() { + match *index(&0) { Enum::A => true, _ => false }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-68347.rs b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-68347.rs new file mode 100644 index 000000000000..3b8e46357db8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-68347.rs @@ -0,0 +1,29 @@ +// run-pass +// compile-flags:-Zmir-opt-level=2 +pub fn main() { + let _x: fn() = handle_debug_column; +} + +fn handle_debug_column() { + let sampler = sample_columns(); + + let foo = || { + sampler.get(17); + }; + foo(); +} + +fn sample_columns() -> impl Sampler { + ColumnGen {} +} + +struct ColumnGen {} + +trait Sampler { + fn get(&self, index: i32); +} + +impl Sampler for ColumnGen { + fn get(&self, _index: i32) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-77306-1.rs b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-77306-1.rs new file mode 100644 index 000000000000..66379bd8fa18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-77306-1.rs @@ -0,0 +1,18 @@ +// run-pass +// compile-flags:-Zmir-opt-level=2 + +// Previously ICEd because we did not normalize during inlining, +// see https://github.com/rust-lang/rust/pull/77306 for more discussion. + +pub fn write() { + create()() +} + +pub fn create() -> impl FnOnce() { + || () +} + +fn main() { + write(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-77306-2.rs b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-77306-2.rs new file mode 100644 index 000000000000..3b1af8bd05ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-77306-2.rs @@ -0,0 +1,33 @@ +// run-pass +// compile-flags:-Zmir-opt-level=2 + +struct Cursor {} +struct TokenTree {} + +impl Iterator for Cursor { + type Item = TokenTree; + + fn next(&mut self) -> Option { + None + } +} + +fn tokenstream_probably_equal_for_proc_macro() { + fn break_tokens(_tree: TokenTree) -> impl Iterator { + let token_trees: Vec = vec![]; + token_trees.into_iter() + } + + let c1 = Cursor {}; + let c2 = Cursor {}; + + let mut t1 = c1.flat_map(break_tokens); + let mut t2 = c2.flat_map(break_tokens); + + for (_t1, _t2) in t1.by_ref().zip(t2.by_ref()) {} +} + +fn main() { + tokenstream_probably_equal_for_proc_macro(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-77564.rs b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-77564.rs new file mode 100644 index 000000000000..e05430435084 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/ice-issue-77564.rs @@ -0,0 +1,39 @@ +// run-pass +// compile-flags:-Zmir-opt-level=2 + +use std::mem::MaybeUninit; +const N: usize = 2; + +trait CollectArray: Iterator { + fn inner_array(&mut self) -> [A; N]; + fn collect_array(&mut self) -> [A; N] { + let result = self.inner_array(); + assert!(self.next().is_none()); + result + } +} + +impl CollectArray for I +where + I: Iterator, +{ + fn inner_array(&mut self) -> [A; N] { + let mut result: [MaybeUninit; N] = unsafe { MaybeUninit::uninit().assume_init() }; + for (dest, item) in result.iter_mut().zip(self) { + *dest = MaybeUninit::new(item); + } + let temp_ptr: *const [MaybeUninit; N] = &result; + unsafe { std::ptr::read(temp_ptr as *const [A; N]) } + } +} + +fn main() { + assert_eq!( + [[1, 2], [3, 4]] + .iter() + .map(|row| row.iter().collect_array()) + .collect_array(), + [[&1, &2], [&3, &4]] + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/no-trait-method-issue-40473.rs b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/no-trait-method-issue-40473.rs new file mode 100644 index 000000000000..8d4d24fb6b31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/no-trait-method-issue-40473.rs @@ -0,0 +1,17 @@ +// run-pass +// compile-flags:-Zmir-opt-level=2 +pub trait Foo { + fn bar(&self) -> usize { 2 } +} + +impl Foo for () { + fn bar(&self) -> usize { 3 } +} + +// Test a case where MIR would inline the default trait method +// instead of bailing out. Issue #40473. +fn main() { + let result = ().bar(); + assert_eq!(result, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs new file mode 100644 index 000000000000..b28486826c23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir-inlining/var-debuginfo-issue-67586.rs @@ -0,0 +1,12 @@ +// run-pass +// compile-flags: -Z mir-opt-level=2 -C opt-level=0 -C debuginfo=2 + +#[inline(never)] +pub fn foo(bar: usize) -> usize { + std::convert::identity(bar) +} + +fn main() { + foo(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir-typeck-normalize-fn-sig.rs b/gcc/testsuite/rust/rustc/ui/mir/mir-typeck-normalize-fn-sig.rs new file mode 100644 index 000000000000..d55f3a431784 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir-typeck-normalize-fn-sig.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(unused_variables)] +// This code was creating an ICE in the MIR type checker. The reason +// is that we are reifying a reference to a function (`foo::<'x>`), +// which involves extracting its signature, but we were not +// normalizing the signature afterwards. As a result, we sometimes got +// errors around the `>::Value`, which can be +// normalized to `f64`. + +#![allow(dead_code)] + +trait Foo<'x> { + type Value; +} + +impl<'x> Foo<'x> for u32 { + type Value = f64; +} + +struct Providers<'x> { + foo: for<'y> fn(x: &'x u32, y: &'y u32) -> >::Value, +} + +fn foo<'y, 'x: 'x>(x: &'x u32, y: &'y u32) -> >::Value { + *x as f64 +} + +fn main() { + Providers { foo }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_adt_construction.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_adt_construction.rs new file mode 100644 index 000000000000..54cf33b790b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_adt_construction.rs @@ -0,0 +1,93 @@ +// run-pass +use std::fmt; + +#[repr(C)] +enum CEnum { + Hello = 30, + World = 60 +} + +fn test1(c: CEnum) -> i32 { + let c2 = CEnum::Hello; + match (c, c2) { + (CEnum::Hello, CEnum::Hello) => 42, + (CEnum::World, CEnum::Hello) => 0, + _ => 1 + } +} + +#[repr(packed)] +struct Pakd { + a: u64, + b: u32, + c: u16, + d: u8, + e: () +} + +// It is unsafe to use #[derive(Debug)] on a packed struct because the code generated by the derive +// macro takes references to the fields instead of accessing them directly. +impl fmt::Debug for Pakd { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // It's important that we load the fields into locals by-value here. This will do safe + // unaligned loads into the locals, then pass references to the properly-aligned locals to + // the formatting code. + let Pakd { a, b, c, d, e } = *self; + f.debug_struct("Pakd") + .field("a", &a) + .field("b", &b) + .field("c", &c) + .field("d", &d) + .field("e", &e) + .finish() + } +} + +// It is unsafe to use #[derive(PartialEq)] on a packed struct because the code generated by the +// derive macro takes references to the fields instead of accessing them directly. +impl PartialEq for Pakd { + fn eq(&self, other: &Pakd) -> bool { + self.a == other.a && + self.b == other.b && + self.c == other.c && + self.d == other.d && + self.e == other.e + } +} + +impl Drop for Pakd { + fn drop(&mut self) {} +} + +fn test2() -> Pakd { + Pakd { a: 42, b: 42, c: 42, d: 42, e: () } +} + +#[derive(PartialEq, Debug)] +struct TupleLike(u64, u32); + +fn test3() -> TupleLike { + TupleLike(42, 42) +} + +fn test4(x: fn(u64, u32) -> TupleLike) -> (TupleLike, TupleLike) { + let y = TupleLike; + (x(42, 84), y(42, 84)) +} + +fn test5(x: fn(u32) -> Option) -> (Option, Option) { + let y = Some; + (x(42), y(42)) +} + +fn main() { + assert_eq!(test1(CEnum::Hello), 42); + assert_eq!(test1(CEnum::World), 0); + assert_eq!(test2(), Pakd { a: 42, b: 42, c: 42, d: 42, e: () }); + assert_eq!(test3(), TupleLike(42, 42)); + let t4 = test4(TupleLike); + assert_eq!(t4.0, t4.1); + let t5 = test5(Some); + assert_eq!(t5.0, t5.1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_ascription_coercion.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_ascription_coercion.rs new file mode 100644 index 000000000000..7b602a809642 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_ascription_coercion.rs @@ -0,0 +1,11 @@ +// run-pass +// Tests that the result of type ascription has adjustments applied + +#![feature(type_ascription)] + +fn main() { + let x = [1, 2, 3]; + // The RHS should coerce to &[i32] + let _y : &[i32] = &x : &[i32; 3]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_assign_eval_order.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_assign_eval_order.rs new file mode 100644 index 000000000000..7665571331da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_assign_eval_order.rs @@ -0,0 +1,68 @@ +// Test evaluation order of assignment expressions is right to left. + +// run-pass + +// We would previously not finish evaluating borrow and FRU expressions before +// starting on the LHS + +struct S(i32); + +fn evaluate_reborrow_before_assign() { + let mut x = &1; + let y = &mut &2; + let z = &3; + // There's an implicit reborrow of `x` on the right-hand side of the + // assignment. Note that writing an explicit reborrow would not show this + // bug, as now there would be two reborrows on the right-hand side and at + // least one of them would happen before the left-hand side is evaluated. + *{ x = z; &mut *y } = x; + assert_eq!(*x, 3); + assert_eq!(**y, 1); // y should be assigned the original value of `x`. +} + +fn evaluate_mut_reborrow_before_assign() { + let mut x = &mut 1; + let y = &mut &mut 2; + let z = &mut 3; + *{ x = z; &mut *y } = x; + assert_eq!(*x, 3); + assert_eq!(**y, 1); // y should be assigned the original value of `x`. +} + +// We should evaluate `x[2]` and borrow the value out *before* evaluating the +// LHS and changing its value. +fn evaluate_ref_to_temp_before_assign_slice() { + let mut x = &[S(0), S(1), S(2)][..]; + let y = &mut &S(7); + *{ x = &[S(3), S(4), S(5)]; &mut *y } = &x[2]; + assert_eq!(2, y.0); + assert_eq!(5, x[2].0); +} + +// We should evaluate `x[2]` and copy the value out *before* evaluating the LHS +// and changing its value. +fn evaluate_fru_to_temp_before_assign_slice() { + let mut x = &[S(0), S(1), S(2)][..]; + let y = &mut S(7); + *{ x = &[S(3), S(4), S(5)]; &mut *y } = S { ..x[2] }; + assert_eq!(2, y.0); + assert_eq!(5, x[2].0); +} + +// We should evaluate `*x` and copy the value out *before* evaluating the LHS +// and dropping `x`. +fn evaluate_fru_to_temp_before_assign_box() { + let x = Box::new(S(0)); + let y = &mut S(1); + *{ drop(x); &mut *y } = S { ..*x }; + assert_eq!(0, y.0); +} + +fn main() { + evaluate_reborrow_before_assign(); + evaluate_mut_reborrow_before_assign(); + evaluate_ref_to_temp_before_assign_slice(); + evaluate_fru_to_temp_before_assign_slice(); + evaluate_fru_to_temp_before_assign_box(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_augmented_assignments.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_augmented_assignments.rs new file mode 100644 index 000000000000..f06a66774229 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_augmented_assignments.rs @@ -0,0 +1,161 @@ +// run-pass +use std::mem; +use std::ops::{ + AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, DivAssign, MulAssign, RemAssign, + ShlAssign, ShrAssign, SubAssign, +}; + +#[derive(Debug, PartialEq)] +struct Int(i32); + +struct Slice([i32]); + +impl Slice { + fn new(slice: &mut [i32]) -> &mut Slice { + unsafe { + mem::transmute(slice) + } + } +} + +fn main() { + main_mir(); +} + +fn main_mir() { + let mut x = Int(1); + + x += Int(2); + assert_eq!(x, Int(0b11)); + + x &= Int(0b01); + assert_eq!(x, Int(0b01)); + + x |= Int(0b10); + assert_eq!(x, Int(0b11)); + + x ^= Int(0b01); + assert_eq!(x, Int(0b10)); + + x /= Int(2); + assert_eq!(x, Int(1)); + + x *= Int(3); + assert_eq!(x, Int(3)); + + x %= Int(2); + assert_eq!(x, Int(1)); + + // overloaded RHS + x <<= 1u8; + assert_eq!(x, Int(2)); + + x <<= 1u16; + assert_eq!(x, Int(4)); + + x >>= 1u8; + assert_eq!(x, Int(2)); + + x >>= 1u16; + assert_eq!(x, Int(1)); + + x -= Int(1); + assert_eq!(x, Int(0)); + + // indexed LHS + // FIXME(mir-drop): use the vec![..] macro + let mut v = Vec::new(); + v.push(Int(1)); + v.push(Int(2)); + v[0] += Int(2); + assert_eq!(v[0], Int(3)); + + // unsized RHS + let mut array = [0, 1, 2]; + *Slice::new(&mut array) += 1; + assert_eq!(array[0], 1); + assert_eq!(array[1], 2); + assert_eq!(array[2], 3); + +} + +impl AddAssign for Int { + fn add_assign(&mut self, rhs: Int) { + self.0 += rhs.0; + } +} + +impl BitAndAssign for Int { + fn bitand_assign(&mut self, rhs: Int) { + self.0 &= rhs.0; + } +} + +impl BitOrAssign for Int { + fn bitor_assign(&mut self, rhs: Int) { + self.0 |= rhs.0; + } +} + +impl BitXorAssign for Int { + fn bitxor_assign(&mut self, rhs: Int) { + self.0 ^= rhs.0; + } +} + +impl DivAssign for Int { + fn div_assign(&mut self, rhs: Int) { + self.0 /= rhs.0; + } +} + +impl MulAssign for Int { + fn mul_assign(&mut self, rhs: Int) { + self.0 *= rhs.0; + } +} + +impl RemAssign for Int { + fn rem_assign(&mut self, rhs: Int) { + self.0 %= rhs.0; + } +} + +impl ShlAssign for Int { + fn shl_assign(&mut self, rhs: u8) { + self.0 <<= rhs; + } +} + +impl ShlAssign for Int { + fn shl_assign(&mut self, rhs: u16) { + self.0 <<= rhs; + } +} + +impl ShrAssign for Int { + fn shr_assign(&mut self, rhs: u8) { + self.0 >>= rhs; + } +} + +impl ShrAssign for Int { + fn shr_assign(&mut self, rhs: u16) { + self.0 >>= rhs; + } +} + +impl SubAssign for Int { + fn sub_assign(&mut self, rhs: Int) { + self.0 -= rhs.0; + } +} + +impl AddAssign for Slice { + fn add_assign(&mut self, rhs: i32) { + for lhs in &mut self.0 { + *lhs += rhs; + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_autoderef.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_autoderef.rs new file mode 100644 index 000000000000..792ee16df499 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_autoderef.rs @@ -0,0 +1,29 @@ +// run-pass +use std::ops::{Deref, DerefMut}; + +pub struct MyRef(u32); + +impl Deref for MyRef { + type Target = u32; + fn deref(&self) -> &u32 { &self.0 } +} + +impl DerefMut for MyRef { + fn deref_mut(&mut self) -> &mut u32 { &mut self.0 } +} + + +fn deref(x: &MyRef) -> &u32 { + x +} + +fn deref_mut(x: &mut MyRef) -> &mut u32 { + x +} + +fn main() { + let mut r = MyRef(2); + assert_eq!(deref(&r) as *const _, &r.0 as *const _); + assert_eq!(deref_mut(&mut r) as *mut _, &mut r.0 as *mut _); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_boxing.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_boxing.rs new file mode 100644 index 000000000000..4207da77a44c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_boxing.rs @@ -0,0 +1,11 @@ +// run-pass +#![feature(box_syntax)] + +fn test() -> Box { + box 42 +} + +fn main() { + assert_eq!(*test(), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_build_match_comparisons.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_build_match_comparisons.rs new file mode 100644 index 000000000000..dcba5459931c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_build_match_comparisons.rs @@ -0,0 +1,60 @@ +// run-pass +#![allow(dead_code)] +fn test1(x: i8) -> i32 { + match x { + 1..=10 => 0, + _ => 1, + } +} + +const U: Option = Some(10); +const S: &'static str = "hello"; + +fn test2(x: i8) -> i32 { + match Some(x) { + U => 0, + _ => 1, + } +} + +fn test3(x: &'static str) -> i32 { + match x { + S => 0, + _ => 1, + } +} + +enum Opt { + Some { v: T }, + None +} + +fn test4(x: u64) -> i32 { + let opt = Opt::Some{ v: x }; + match opt { + Opt::Some { v: 10 } => 0, + _ => 1, + } +} + + +fn main() { + assert_eq!(test1(0), 1); + assert_eq!(test1(1), 0); + assert_eq!(test1(2), 0); + assert_eq!(test1(5), 0); + assert_eq!(test1(9), 0); + assert_eq!(test1(10), 0); + assert_eq!(test1(11), 1); + assert_eq!(test1(20), 1); + assert_eq!(test2(10), 0); + assert_eq!(test2(0), 1); + assert_eq!(test2(20), 1); + assert_eq!(test3("hello"), 0); + assert_eq!(test3(""), 1); + assert_eq!(test3("world"), 1); + assert_eq!(test4(10), 0); + assert_eq!(test4(0), 1); + assert_eq!(test4(20), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_call_with_associated_type.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_call_with_associated_type.rs new file mode 100644 index 000000000000..e44a800d2127 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_call_with_associated_type.rs @@ -0,0 +1,17 @@ +// run-pass +trait Trait { + type Type; +} + +impl<'a> Trait for &'a () { + type Type = u32; +} + +fn foo<'a>(t: <&'a () as Trait>::Type) -> <&'a () as Trait>::Type { + t +} + +fn main() { + assert_eq!(foo(4), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_calls_to_shims.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_calls_to_shims.rs new file mode 100644 index 000000000000..add567233ee6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_calls_to_shims.rs @@ -0,0 +1,50 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(fn_traits)] +#![feature(never_type)] + +use std::panic; + +fn foo(x: u32, y: u32) -> u32 { x/y } +fn foo_diverges() -> ! { panic!() } + +fn test_fn_ptr(mut t: T) + where T: Fn(u32, u32) -> u32, +{ + let as_fn = >::call; + assert_eq!(as_fn(&t, (9, 3)), 3); + let as_fn_mut = >::call_mut; + assert_eq!(as_fn_mut(&mut t, (18, 3)), 6); + let as_fn_once = >::call_once; + assert_eq!(as_fn_once(t, (24, 3)), 8); +} + +fn assert_panics(f: F) where F: FnOnce() { + let f = panic::AssertUnwindSafe(f); + let result = panic::catch_unwind(move || { + f.0() + }); + if let Ok(..) = result { + panic!("diverging function returned"); + } +} + +fn test_fn_ptr_panic(mut t: T) + where T: Fn() -> ! +{ + let as_fn = >::call; + assert_panics(|| as_fn(&t, ())); + let as_fn_mut = >::call_mut; + assert_panics(|| as_fn_mut(&mut t, ())); + let as_fn_once = >::call_once; + assert_panics(|| as_fn_once(t, ())); +} + +fn main() { + test_fn_ptr(foo); + test_fn_ptr(foo as fn(u32, u32) -> u32); + test_fn_ptr_panic(foo_diverges); + test_fn_ptr_panic(foo_diverges as fn() -> !); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_cast_fn_ret.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_cast_fn_ret.rs new file mode 100644 index 000000000000..6f5a23c28079 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_cast_fn_ret.rs @@ -0,0 +1,24 @@ +// run-pass +#[allow(improper_ctypes_definitions)] +pub extern "C" fn tuple2() -> (u16, u8) { + (1, 2) +} + +#[allow(improper_ctypes_definitions)] +pub extern "C" fn tuple3() -> (u8, u8, u8) { + (1, 2, 3) +} + +pub fn test2() -> u8 { + tuple2().1 +} + +pub fn test3() -> u8 { + tuple3().2 +} + +fn main() { + assert_eq!(test2(), 2); + assert_eq!(test3(), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_array.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_array.rs new file mode 100644 index 000000000000..1e8e08073852 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_array.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(unused_mut)] +fn into_inner() -> [u64; 1024] { + let mut x = 10 + 20; + [x; 1024] +} + +fn main(){ + let x: &[u64] = &[30; 1024]; + assert_eq!(&into_inner()[..], x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_array_2.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_array_2.rs new file mode 100644 index 000000000000..10d33c6ec364 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_array_2.rs @@ -0,0 +1,10 @@ +// run-pass +fn into_inner(x: u64) -> [u64; 1024] { + [x; 2*4*8*16] +} + +fn main(){ + let x: &[u64] = &[42; 1024]; + assert_eq!(&into_inner(42)[..], x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_call_converging.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_call_converging.rs new file mode 100644 index 000000000000..53238ef6b824 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_call_converging.rs @@ -0,0 +1,18 @@ +// run-pass +fn converging_fn() -> u64 { + 43 +} + +fn mir() -> u64 { + let x; + loop { + x = converging_fn(); + break; + } + x +} + +fn main() { + assert_eq!(mir(), 43); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls.rs new file mode 100644 index 000000000000..6dc3a00ddd79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls.rs @@ -0,0 +1,193 @@ +// run-pass +#![feature(fn_traits, test)] + +extern crate test; + +fn test1(a: isize, b: (i32, i32), c: &[i32]) -> (isize, (i32, i32), &[i32]) { + // Test passing a number of arguments including a fat pointer. + // Also returning via an out pointer + fn callee(a: isize, b: (i32, i32), c: &[i32]) -> (isize, (i32, i32), &[i32]) { + (a, b, c) + } + callee(a, b, c) +} + +fn test2(a: isize) -> isize { + // Test passing a single argument. + // Not using out pointer. + fn callee(a: isize) -> isize { + a + } + callee(a) +} + +#[derive(PartialEq, Eq, Debug)] +struct Foo; +impl Foo { + fn inherent_method(&self, a: isize) -> isize { a } +} + +fn test3(x: &Foo, a: isize) -> isize { + // Test calling inherent method + x.inherent_method(a) +} + +trait Bar { + fn extension_method(&self, a: isize) -> isize { a } +} +impl Bar for Foo {} + +fn test4(x: &Foo, a: isize) -> isize { + // Test calling extension method + x.extension_method(a) +} + +fn test5(x: &dyn Bar, a: isize) -> isize { + // Test calling method on trait object + x.extension_method(a) +} + +fn test6(x: &T, a: isize) -> isize { + // Test calling extension method on generic callee + x.extension_method(a) +} + +trait One { + fn one() -> T; +} +impl One for isize { + fn one() -> isize { 1 } +} + +fn test7() -> isize { + // Test calling trait static method + ::one() +} + +struct Two; +impl Two { + fn two() -> isize { 2 } +} + +fn test8() -> isize { + // Test calling impl static method + Two::two() +} + +#[allow(improper_ctypes_definitions)] +extern fn simple_extern(x: u32, y: (u32, u32)) -> u32 { + x + y.0 * y.1 +} + +fn test9() -> u32 { + simple_extern(41, (42, 43)) +} + +fn test_closure(f: &F, x: i32, y: i32) -> i32 + where F: Fn(i32, i32) -> i32 +{ + f(x, y) +} + +fn test_fn_object(f: &dyn Fn(i32, i32) -> i32, x: i32, y: i32) -> i32 { + f(x, y) +} + +fn test_fn_impl(f: &&dyn Fn(i32, i32) -> i32, x: i32, y: i32) -> i32 { + // This call goes through the Fn implementation for &Fn provided in + // core::ops::impls. It expands to a static Fn::call() that calls the + // Fn::call() implementation of the object shim underneath. + f(x, y) +} + +fn test_fn_direct_call(f: &F, x: i32, y: i32) -> i32 + where F: Fn(i32, i32) -> i32 +{ + f.call((x, y)) +} + +fn test_fn_const_call(f: &F) -> i32 + where F: Fn(i32, i32) -> i32 +{ + f.call((100, -1)) +} + +fn test_fn_nil_call(f: &F) -> i32 + where F: Fn() -> i32 +{ + f() +} + +fn test_fn_transmute_zst(x: ()) -> [(); 1] { + fn id(x: T) -> T {x} + + id(unsafe { + std::mem::transmute(x) + }) +} + +fn test_fn_ignored_pair() -> ((), ()) { + ((), ()) +} + +fn test_fn_ignored_pair_0() { + test_fn_ignored_pair().0 +} + +fn id(x: T) -> T { x } + +fn ignored_pair_named() -> (Foo, Foo) { + (Foo, Foo) +} + +fn test_fn_ignored_pair_named() -> (Foo, Foo) { + id(ignored_pair_named()) +} + +fn test_fn_nested_pair(x: &((f32, f32), u32)) -> (f32, f32) { + let y = *x; + let z = y.0; + (z.0, z.1) +} + +fn test_fn_const_arg_by_ref(mut a: [u64; 4]) -> u64 { + // Mutate the by-reference argument, which won't work with + // a non-immediate constant unless it's copied to the stack. + let a = test::black_box(&mut a); + a[0] += a[1]; + a[0] += a[2]; + a[0] += a[3]; + a[0] +} + +fn main() { + assert_eq!(test1(1, (2, 3), &[4, 5, 6]), (1, (2, 3), &[4, 5, 6][..])); + assert_eq!(test2(98), 98); + assert_eq!(test3(&Foo, 42), 42); + assert_eq!(test4(&Foo, 970), 970); + assert_eq!(test5(&Foo, 8576), 8576); + assert_eq!(test6(&Foo, 12367), 12367); + assert_eq!(test7(), 1); + assert_eq!(test8(), 2); + assert_eq!(test9(), 41 + 42 * 43); + + let r = 3; + let closure = |x: i32, y: i32| { r*(x + (y*2)) }; + assert_eq!(test_fn_const_call(&closure), 294); + assert_eq!(test_closure(&closure, 100, 1), 306); + let function_object = &closure as &dyn Fn(i32, i32) -> i32; + assert_eq!(test_fn_object(function_object, 100, 2), 312); + assert_eq!(test_fn_impl(&function_object, 100, 3), 318); + assert_eq!(test_fn_direct_call(&closure, 100, 4), 324); + + assert_eq!(test_fn_nil_call(&(|| 42)), 42); + assert_eq!(test_fn_transmute_zst(()), [()]); + + assert_eq!(test_fn_ignored_pair_0(), ()); + assert_eq!(test_fn_ignored_pair_named(), (Foo, Foo)); + assert_eq!(test_fn_nested_pair(&((1.0, 2.0), 0)), (1.0, 2.0)); + + const ARRAY: [u64; 4] = [1, 2, 3, 4]; + assert_eq!(test_fn_const_arg_by_ref(ARRAY), 1 + 2 + 3 + 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_converging_drops.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_converging_drops.rs new file mode 100644 index 000000000000..1ede9112e2b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_converging_drops.rs @@ -0,0 +1,27 @@ +// run-fail +// error-pattern:converging_fn called +// error-pattern:0 dropped +// error-pattern:exit +// ignore-emscripten no processes + +struct Droppable(u8); +impl Drop for Droppable { + fn drop(&mut self) { + eprintln!("{} dropped", self.0); + } +} + +fn converging_fn() { + eprintln!("converging_fn called"); +} + +fn mir(d: Droppable) { + converging_fn(); +} + +fn main() { + let d = Droppable(0); + mir(d); + panic!("exit"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_converging_drops_2.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_converging_drops_2.rs new file mode 100644 index 000000000000..bbed35b0b8a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_converging_drops_2.rs @@ -0,0 +1,31 @@ +// run-fail +// error-pattern:complex called +// error-pattern:dropped +// error-pattern:exit +// ignore-emscripten no processes + +struct Droppable; +impl Drop for Droppable { + fn drop(&mut self) { + eprintln!("dropped"); + } +} + +// return value of this function is copied into the return slot +fn complex() -> u64 { + eprintln!("complex called"); + 42 +} + + +fn mir() -> u64 { + let x = Droppable; + return complex(); + drop(x); +} + +pub fn main() { + assert_eq!(mir(), 42); + panic!("exit"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_diverging.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_diverging.rs new file mode 100644 index 000000000000..c01064aa0d20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_diverging.rs @@ -0,0 +1,16 @@ +// run-fail +// error-pattern:diverging_fn called +// ignore-emscripten no processes + +fn diverging_fn() -> ! { + panic!("diverging_fn called") +} + +fn mir() { + diverging_fn(); +} + +fn main() { + mir(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_diverging_drops.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_diverging_drops.rs new file mode 100644 index 000000000000..8d2ecd8c5cb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_calls_diverging_drops.rs @@ -0,0 +1,25 @@ +// run-fail +// error-pattern:diverging_fn called +// error-pattern:0 dropped +// ignore-emscripten no processes + +struct Droppable(u8); +impl Drop for Droppable { + fn drop(&mut self) { + eprintln!("{} dropped", self.0); + } +} + +fn diverging_fn() -> ! { + panic!("diverging_fn called") +} + +fn mir(d: Droppable) { + diverging_fn(); +} + +fn main() { + let d = Droppable(0); + mir(d); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_critical_edge.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_critical_edge.rs new file mode 100644 index 000000000000..ef6e40da560a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_critical_edge.rs @@ -0,0 +1,45 @@ +// run-pass +#![allow(dead_code)] +// This code produces a CFG with critical edges that, if we don't +// handle properly, will cause invalid codegen. + +#![feature(rustc_attrs)] + +enum State { + Both, + Front, + Back +} + +pub struct Foo { + state: State, + a: A, + b: B +} + +impl Foo +where A: Iterator, B: Iterator +{ + // This is the function we care about + fn next(&mut self) -> Option { + match self.state { + State::Both => match self.a.next() { + elt @ Some(..) => elt, + None => { + self.state = State::Back; + self.b.next() + } + }, + State::Front => self.a.next(), + State::Back => self.b.next(), + } + } +} + +// Make sure we actually codegen a version of the function +pub fn do_stuff(mut f: Foo>, Box>>) { + let _x = f.next(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_spike1.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_spike1.rs new file mode 100644 index 000000000000..b90d0b9a0227 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_spike1.rs @@ -0,0 +1,13 @@ +// run-pass +// A simple spike test for MIR version of codegen. + +fn sum(x: i32, y: i32) -> i32 { + x + y +} + +fn main() { + let x = sum(22, 44); + assert_eq!(x, 66); + println!("sum()={:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_switch.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_switch.rs new file mode 100644 index 000000000000..744c46212aa8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_switch.rs @@ -0,0 +1,36 @@ +// run-pass +enum Abc { + A(u8), + B(i8), + C, + D, +} + +fn foo(x: Abc) -> i32 { + match x { + Abc::C => 3, + Abc::D => 4, + Abc::B(_) => 2, + Abc::A(_) => 1, + } +} + +fn foo2(x: Abc) -> bool { + match x { + Abc::D => true, + _ => false + } +} + +fn main() { + assert_eq!(1, foo(Abc::A(42))); + assert_eq!(2, foo(Abc::B(-100))); + assert_eq!(3, foo(Abc::C)); + assert_eq!(4, foo(Abc::D)); + + assert_eq!(false, foo2(Abc::A(1))); + assert_eq!(false, foo2(Abc::B(2))); + assert_eq!(false, foo2(Abc::C)); + assert_eq!(true, foo2(Abc::D)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_switchint.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_switchint.rs new file mode 100644 index 000000000000..9f0f7bcdd5bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_codegen_switchint.rs @@ -0,0 +1,13 @@ +// run-pass +pub fn foo(x: i8) -> i32 { + match x { + 1 => 0, + _ => 1, + } +} + +fn main() { + assert_eq!(foo(0), 1); + assert_eq!(foo(1), 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_coercion_casts.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_coercion_casts.rs new file mode 100644 index 000000000000..d7f02c016a21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_coercion_casts.rs @@ -0,0 +1,11 @@ +// run-pass +// Tests the coercion casts are handled properly + +fn main() { + // This should produce only a reification of f, + // not a fn -> fn cast as well + let _ = f as fn(&()); +} + +fn f<'a>(_: &'a ()) { } + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_coercions.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_coercions.rs new file mode 100644 index 000000000000..cec618003d75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_coercions.rs @@ -0,0 +1,72 @@ +// run-pass +#![feature(coerce_unsized, unsize)] + +use std::ops::CoerceUnsized; +use std::marker::Unsize; + +fn identity_coercion(x: &(dyn Fn(u32)->u32 + Send)) -> &dyn Fn(u32)->u32 { + x +} +fn fn_coercions(f: &fn(u32) -> u32) -> + (unsafe fn(u32) -> u32, + &(dyn Fn(u32) -> u32+Send)) +{ + (*f, f) +} + +fn simple_array_coercion(x: &[u8; 3]) -> &[u8] { x } + +fn square(a: u32) -> u32 { a * a } + +#[derive(PartialEq,Eq)] +struct PtrWrapper<'a, T: 'a+?Sized>(u32, u32, (), &'a T); +impl<'a, T: ?Sized+Unsize, U: ?Sized> + CoerceUnsized> for PtrWrapper<'a, T> {} + +struct TrivPtrWrapper<'a, T: 'a+?Sized>(&'a T); +impl<'a, T: ?Sized+Unsize, U: ?Sized> + CoerceUnsized> for TrivPtrWrapper<'a, T> {} + +fn coerce_ptr_wrapper(p: PtrWrapper<[u8; 3]>) -> PtrWrapper<[u8]> { + p +} + +fn coerce_triv_ptr_wrapper(p: TrivPtrWrapper<[u8; 3]>) -> TrivPtrWrapper<[u8]> { + p +} + +fn coerce_fat_ptr_wrapper(p: PtrWrapper u32+Send>) + -> PtrWrapper u32> { + p +} + +fn coerce_ptr_wrapper_poly<'a, T, Trait: ?Sized>(p: PtrWrapper<'a, T>) + -> PtrWrapper<'a, Trait> + where PtrWrapper<'a, T>: CoerceUnsized> +{ + p +} + +fn main() { + let a = [0,1,2]; + let square_local : fn(u32) -> u32 = square; + let (f,g) = fn_coercions(&square_local); + assert_eq!(f as usize, square as usize); + assert_eq!(g(4), 16); + assert_eq!(identity_coercion(g)(5), 25); + + assert_eq!(simple_array_coercion(&a), &a); + let w = coerce_ptr_wrapper(PtrWrapper(2,3,(),&a)); + assert!(w == PtrWrapper(2,3,(),&a) as PtrWrapper<[u8]>); + + let w = coerce_triv_ptr_wrapper(TrivPtrWrapper(&a)); + assert_eq!(&w.0, &a); + + let z = coerce_fat_ptr_wrapper(PtrWrapper(2,3,(),&square_local)); + assert_eq!((z.3)(6), 36); + + let z: PtrWrapper u32> = + coerce_ptr_wrapper_poly(PtrWrapper(2,3,(),&square_local)); + assert_eq!((z.3)(6), 36); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_const_prop_tuple_field_reorder.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_const_prop_tuple_field_reorder.rs new file mode 100644 index 000000000000..6fd9b88c78ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_const_prop_tuple_field_reorder.rs @@ -0,0 +1,28 @@ +// compile-flags: -Z mir-opt-level=2 +// build-pass +#![crate_type="lib"] + +// This used to ICE: const-prop did not account for field reordering of scalar pairs, +// and would generate a tuple like `(0x1337, VariantBar): (FooEnum, isize)`, +// causing assertion failures in codegen when trying to read 0x1337 at the wrong type. + +pub enum FooEnum { + VariantBar, + VariantBaz, + VariantBuz, +} + +pub fn wrong_index() -> isize { + let (_, b) = id((FooEnum::VariantBar, 0x1337)); + b +} + +pub fn wrong_index_two() -> isize { + let (_, (_, b)) = id(((), (FooEnum::VariantBar, 0x1338))); + b +} + +fn id(x: T) -> T { + x +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_constval_adts.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_constval_adts.rs new file mode 100644 index 000000000000..3156be3584e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_constval_adts.rs @@ -0,0 +1,35 @@ +// run-pass +#[derive(PartialEq, Debug)] +struct Point { + _x: i32, + _y: i32, +} + +#[derive(PartialEq, Eq, Debug)] +struct Newtype(T); + +const STRUCT: Point = Point { _x: 42, _y: 42 }; +const TUPLE1: (i32, i32) = (42, 42); +const TUPLE2: (&'static str, &'static str) = ("hello","world"); +const PAIR_NEWTYPE: (Newtype, Newtype) = (Newtype(42), Newtype(42)); + +fn mir() -> (Point, (i32, i32), (&'static str, &'static str), (Newtype, Newtype)) { + let struct1 = STRUCT; + let tuple1 = TUPLE1; + let tuple2 = TUPLE2; + let pair_newtype = PAIR_NEWTYPE; + (struct1, tuple1, tuple2, pair_newtype) +} + +const NEWTYPE: Newtype<&'static str> = Newtype("foobar"); + +fn test_promoted_newtype_str_ref() { + let x = &NEWTYPE; + assert_eq!(x, &Newtype("foobar")); +} + +fn main(){ + assert_eq!(mir(), (STRUCT, TUPLE1, TUPLE2, PAIR_NEWTYPE)); + test_promoted_newtype_str_ref(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_detects_invalid_ops.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_detects_invalid_ops.rs new file mode 100644 index 000000000000..28a1439d7ce9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_detects_invalid_ops.rs @@ -0,0 +1,25 @@ +// build-fail + +fn main() { + divide_by_zero(); + mod_by_zero(); + oob_error_for_slices(); +} + +fn divide_by_zero() { + let y = 0; + let _z = 1 / y; // { dg-error "" "" { target *-*-* } } +} + +fn mod_by_zero() { + let y = 0; + let _z = 1 % y; // { dg-error "" "" { target *-*-* } } +} + +fn oob_error_for_slices() { + let a: *const [_] = &[1, 2, 3]; + unsafe { + let _b = (*a)[3]; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_drop_order.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_drop_order.rs new file mode 100644 index 000000000000..b2fe476b76b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_drop_order.rs @@ -0,0 +1,49 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default + +use std::cell::RefCell; +use std::panic; + +pub struct DropLogger<'a> { + id: usize, + log: &'a panic::AssertUnwindSafe>> +} + +impl<'a> Drop for DropLogger<'a> { + fn drop(&mut self) { + self.log.0.borrow_mut().push(self.id); + } +} + +struct InjectedFailure; + +#[allow(unreachable_code)] +fn main() { + let log = panic::AssertUnwindSafe(RefCell::new(vec![])); + let d = |id| DropLogger { id: id, log: &log }; + let get = || -> Vec<_> { + let mut m = log.0.borrow_mut(); + let n = m.drain(..); + n.collect() + }; + + { + let _x = (d(0), &d(1), d(2), &d(3)); + // all borrows are extended - nothing has been dropped yet + assert_eq!(get(), vec![]); + } + // in a let-statement, extended places are dropped + // *after* the let result (tho they have the same scope + // as far as scope-based borrowck goes). + assert_eq!(get(), vec![0, 2, 3, 1]); + + let _ = std::panic::catch_unwind(|| { + (d(4), &d(5), d(6), &d(7), panic!(InjectedFailure)); + }); + + // here, the temporaries (5/7) live until the end of the + // containing statement, which is destroyed after the operands + // (4/6) on a panic. + assert_eq!(get(), vec![6, 4, 7, 5]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_drop_panics.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_drop_panics.rs new file mode 100644 index 000000000000..c039657a3322 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_drop_panics.rs @@ -0,0 +1,25 @@ +// run-fail +// error-pattern:panic 1 +// error-pattern:drop 2 +// ignore-emscripten no processes + +struct Droppable(u32); +impl Drop for Droppable { + fn drop(&mut self) { + if self.0 == 1 { + panic!("panic 1"); + } else { + eprintln!("drop {}", self.0); + } + } +} + +fn mir() { + let x = Droppable(2); + let y = Droppable(1); +} + +fn main() { + mir(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_dynamic_drops_1.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_dynamic_drops_1.rs new file mode 100644 index 000000000000..ef755cf685f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_dynamic_drops_1.rs @@ -0,0 +1,33 @@ +// run-fail +// error-pattern:drop 1 +// error-pattern:drop 2 +// ignore-cloudabi no std::process +// ignore-emscripten no processes + +/// Structure which will not allow to be dropped twice. +struct Droppable<'a>(&'a mut bool, u32); +impl<'a> Drop for Droppable<'a> { + fn drop(&mut self) { + if *self.0 { + eprintln!("{} dropped twice", self.1); + ::std::process::exit(1); + } + eprintln!("drop {}", self.1); + *self.0 = true; + } +} + +fn mir() { + let (mut xv, mut yv) = (false, false); + let x = Droppable(&mut xv, 1); + let y = Droppable(&mut yv, 2); + let mut z = x; + let k = y; + z = k; +} + +fn main() { + mir(); + panic!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_dynamic_drops_2.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_dynamic_drops_2.rs new file mode 100644 index 000000000000..b3a82ef39674 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_dynamic_drops_2.rs @@ -0,0 +1,31 @@ +// run-fail +// error-pattern:drop 1 +// ignore-cloudabi no std::process +// ignore-emscripten no processes + +/// Structure which will not allow to be dropped twice. +struct Droppable<'a>(&'a mut bool, u32); +impl<'a> Drop for Droppable<'a> { + fn drop(&mut self) { + if *self.0 { + eprintln!("{} dropped twice", self.1); + ::std::process::exit(1); + } + eprintln!("drop {}", self.1); + *self.0 = true; + } +} + +fn mir<'a>(d: Droppable<'a>) { + loop { + let x = d; + break; + } +} + +fn main() { + let mut xv = false; + mir(Droppable(&mut xv, 1)); + panic!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_dynamic_drops_3.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_dynamic_drops_3.rs new file mode 100644 index 000000000000..835f393e67fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_dynamic_drops_3.rs @@ -0,0 +1,36 @@ +// run-fail +// error-pattern:unwind happens +// error-pattern:drop 3 +// error-pattern:drop 2 +// error-pattern:drop 1 +// ignore-cloudabi no std::process +// ignore-emscripten no processes + +/// Structure which will not allow to be dropped twice. +struct Droppable<'a>(&'a mut bool, u32); +impl<'a> Drop for Droppable<'a> { + fn drop(&mut self) { + if *self.0 { + eprintln!("{} dropped twice", self.1); + ::std::process::exit(1); + } + eprintln!("drop {}", self.1); + *self.0 = true; + } +} + +fn may_panic<'a>() -> Droppable<'a> { + panic!("unwind happens"); +} + +fn mir<'a>(d: Droppable<'a>) { + let (mut a, mut b) = (false, false); + let y = Droppable(&mut a, 2); + let x = [Droppable(&mut b, 1), y, d, may_panic()]; +} + +fn main() { + let mut c = false; + mir(Droppable(&mut c, 3)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_early_return_scope.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_early_return_scope.rs new file mode 100644 index 000000000000..636d5148ea80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_early_return_scope.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(unused_variables)] +static mut DROP: bool = false; + +struct ConnWrap(Conn); +impl ::std::ops::Deref for ConnWrap { + type Target=Conn; + fn deref(&self) -> &Conn { &self.0 } +} + +struct Conn; +impl Drop for Conn { + fn drop(&mut self) { unsafe { DROP = true; } } +} + +fn inner() { + let conn = &*match Some(ConnWrap(Conn)) { + Some(val) => val, + None => return, + }; + return; +} + +fn main() { + inner(); + unsafe { + assert_eq!(DROP, true); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_fat_ptr.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_fat_ptr.rs new file mode 100644 index 000000000000..ded0b0b4c3a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_fat_ptr.rs @@ -0,0 +1,53 @@ +// run-pass +// test that ordinary fat pointer operations work. + +struct Wrapper(u32, T); + +struct FatPtrContainer<'a> { + ptr: &'a [u8] +} + +fn fat_ptr_project(a: &Wrapper<[u8]>) -> &[u8] { + &a.1 +} + +fn fat_ptr_simple(a: &[u8]) -> &[u8] { + a +} + +fn fat_ptr_via_local(a: &[u8]) -> &[u8] { + let x = a; + x +} + +fn fat_ptr_from_struct(s: FatPtrContainer) -> &[u8] { + s.ptr +} + +fn fat_ptr_to_struct(a: &[u8]) -> FatPtrContainer { + FatPtrContainer { ptr: a } +} + +fn fat_ptr_store_to<'a>(a: &'a [u8], b: &mut &'a [u8]) { + *b = a; +} + +fn fat_ptr_constant() -> &'static str { + "HELLO" +} + +fn main() { + let a = Wrapper(4, [7,6,5]); + + let p = fat_ptr_project(&a); + let p = fat_ptr_simple(p); + let p = fat_ptr_via_local(p); + let p = fat_ptr_from_struct(fat_ptr_to_struct(p)); + + let mut target : &[u8] = &[42]; + fat_ptr_store_to(p, &mut target); + assert_eq!(target, &a.1); + + assert_eq!(fat_ptr_constant(), "HELLO"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_fat_ptr_drop.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_fat_ptr_drop.rs new file mode 100644 index 000000000000..50dd7fd10838 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_fat_ptr_drop.rs @@ -0,0 +1,33 @@ +// run-pass +#![allow(unused_variables)] +#![allow(stable_features)] + +// test that ordinary fat pointer operations work. + +#![feature(braced_empty_structs)] +#![feature(rustc_attrs)] + +use std::sync::atomic; +use std::sync::atomic::Ordering::SeqCst; + +static COUNTER: atomic::AtomicUsize = atomic::AtomicUsize::new(0); + +struct DropMe { +} + +impl Drop for DropMe { + fn drop(&mut self) { + COUNTER.fetch_add(1, SeqCst); + } +} + +fn fat_ptr_move_then_drop(a: Box<[DropMe]>) { + let b = a; +} + +fn main() { + let a: Box<[DropMe]> = Box::new([DropMe { }]); + fat_ptr_move_then_drop(a); + assert_eq!(COUNTER.load(SeqCst), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_heavy_promoted.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_heavy_promoted.rs new file mode 100644 index 000000000000..395f26643246 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_heavy_promoted.rs @@ -0,0 +1,12 @@ +// run-pass +// ignore-emscripten apparently only works in optimized mode + +const TEST_DATA: [u8; 32 * 1024 * 1024] = [42; 32 * 1024 * 1024]; + +// Check that the promoted copy of TEST_DATA doesn't +// leave an alloca from an unused temp behind, which, +// without optimizations, can still blow the stack. +fn main() { + println!("{}", TEST_DATA.len()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_indexing_oob_1.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_indexing_oob_1.rs new file mode 100644 index 000000000000..7c2970a8aabf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_indexing_oob_1.rs @@ -0,0 +1,15 @@ +// run-fail +// error-pattern:index out of bounds: the len is 5 but the index is 10 +// ignore-emscripten no processes + +const C: [u32; 5] = [0; 5]; + +#[allow(unconditional_panic)] +fn test() -> u32 { + C[10] +} + +fn main() { + test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_indexing_oob_2.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_indexing_oob_2.rs new file mode 100644 index 000000000000..55716266d2e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_indexing_oob_2.rs @@ -0,0 +1,15 @@ +// run-fail +// error-pattern:index out of bounds: the len is 5 but the index is 10 +// ignore-emscripten no processes + +const C: &'static [u8; 5] = b"hello"; + +#[allow(unconditional_panic)] +fn test() -> u8 { + C[10] +} + +fn main() { + test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_indexing_oob_3.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_indexing_oob_3.rs new file mode 100644 index 000000000000..7d9588353f34 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_indexing_oob_3.rs @@ -0,0 +1,15 @@ +// run-fail +// error-pattern:index out of bounds: the len is 5 but the index is 10 +// ignore-emscripten no processes + +const C: &'static [u8; 5] = b"hello"; + +#[allow(unconditional_panic)] +fn mir() -> u8 { + C[10] +} + +fn main() { + mir(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_match_arm_guard.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_match_arm_guard.rs new file mode 100644 index 000000000000..df9b7258ddf6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_match_arm_guard.rs @@ -0,0 +1,17 @@ +// run-pass +// #30527 - We were not generating arms with guards in certain cases. + +fn match_with_guard(x: Option) -> i8 { + match x { + Some(xyz) if xyz > 100 => 0, + Some(_) => -1, + None => -2 + } +} + +fn main() { + assert_eq!(match_with_guard(Some(111)), 0); + assert_eq!(match_with_guard(Some(2)), -1); + assert_eq!(match_with_guard(None), -2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_match_test.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_match_test.rs new file mode 100644 index 000000000000..6aa81ccf9aee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_match_test.rs @@ -0,0 +1,84 @@ +#![feature(exclusive_range_pattern)] + +// run-pass + +fn main() { + let incl_range = |x, b| { + match x { + 0..=5 if b => 0, + 5..=10 if b => 1, + 1..=4 if !b => 2, + _ => 3, + } + }; + assert_eq!(incl_range(3, false), 2); + assert_eq!(incl_range(3, true), 0); + assert_eq!(incl_range(5, false), 3); + assert_eq!(incl_range(5, true), 0); + + let excl_range = |x, b| { + match x { + 0..5 if b => 0, + 5..10 if b => 1, + 1..4 if !b => 2, + _ => 3, + } + }; + assert_eq!(excl_range(3, false), 2); + assert_eq!(excl_range(3, true), 0); + assert_eq!(excl_range(5, false), 3); + assert_eq!(excl_range(5, true), 1); + + let incl_range_vs_const = |x, b| { + match x { + 0..=5 if b => 0, + 7 => 1, + 3 => 2, + _ => 3, + } + }; + assert_eq!(incl_range_vs_const(5, false), 3); + assert_eq!(incl_range_vs_const(5, true), 0); + assert_eq!(incl_range_vs_const(3, false), 2); + assert_eq!(incl_range_vs_const(3, true), 0); + assert_eq!(incl_range_vs_const(7, false), 1); + assert_eq!(incl_range_vs_const(7, true), 1); + + let excl_range_vs_const = |x, b| { + match x { + 0..5 if b => 0, + 7 => 1, + 3 => 2, + _ => 3, + } + }; + assert_eq!(excl_range_vs_const(5, false), 3); + assert_eq!(excl_range_vs_const(5, true), 3); + assert_eq!(excl_range_vs_const(3, false), 2); + assert_eq!(excl_range_vs_const(3, true), 0); + assert_eq!(excl_range_vs_const(7, false), 1); + assert_eq!(excl_range_vs_const(7, true), 1); + + let const_vs_incl_range = |x, b| { + match x { + 3 if b => 0, + 5..=7 => 2, + 1..=4 => 1, + _ => 3, + } + }; + assert_eq!(const_vs_incl_range(3, false), 1); + assert_eq!(const_vs_incl_range(3, true), 0); + + let const_vs_excl_range = |x, b| { + match x { + 3 if b => 0, + 5..7 => 2, + 1..4 => 1, + _ => 3, + } + }; + assert_eq!(const_vs_excl_range(3, false), 1); + assert_eq!(const_vs_excl_range(3, true), 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_misc_casts.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_misc_casts.rs new file mode 100644 index 000000000000..a4c76d80b86f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_misc_casts.rs @@ -0,0 +1,321 @@ +// run-pass +fn func(){} + +const STR: &'static str = "hello"; +const BSTR: &'static [u8; 5] = b"hello"; + +fn from_ptr() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, *const ()) { + let f = 1_usize as *const String; + let c1 = f as isize; + let c2 = f as usize; + let c3 = f as i8; + let c4 = f as i16; + let c5 = f as i32; + let c6 = f as i64; + let c7 = f as u8; + let c8 = f as u16; + let c9 = f as u32; + let c10 = f as u64; + let c11 = f as *const (); + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11) +} + +fn from_1() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const String) { + let c1 = 1 as isize; + let c2 = 1 as usize; + let c3 = 1 as i8; + let c4 = 1 as i16; + let c5 = 1 as i32; + let c6 = 1 as i64; + let c7 = 1 as u8; + let c8 = 1 as u16; + let c9 = 1 as u32; + let c10 = 1 as u64; + let c11 = 1 as f32; + let c12 = 1 as f64; + let c13 = 1 as *const String; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) +} + +fn from_1usize() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const String) { + let c1 = 1_usize as isize; + let c2 = 1_usize as usize; + let c3 = 1_usize as i8; + let c4 = 1_usize as i16; + let c5 = 1_usize as i32; + let c6 = 1_usize as i64; + let c7 = 1_usize as u8; + let c8 = 1_usize as u16; + let c9 = 1_usize as u32; + let c10 = 1_usize as u64; + let c11 = 1_usize as f32; + let c12 = 1_usize as f64; + let c13 = 1_usize as *const String; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) +} + +fn from_1isize() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const String) { + let c1 = 1_isize as isize; + let c2 = 1_isize as usize; + let c3 = 1_isize as i8; + let c4 = 1_isize as i16; + let c5 = 1_isize as i32; + let c6 = 1_isize as i64; + let c7 = 1_isize as u8; + let c8 = 1_isize as u16; + let c9 = 1_isize as u32; + let c10 = 1_isize as u64; + let c11 = 1_isize as f32; + let c12 = 1_isize as f64; + let c13 = 1_isize as *const String; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) +} + +fn from_1u8() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const String) { + let c1 = 1_u8 as isize; + let c2 = 1_u8 as usize; + let c3 = 1_u8 as i8; + let c4 = 1_u8 as i16; + let c5 = 1_u8 as i32; + let c6 = 1_u8 as i64; + let c7 = 1_u8 as u8; + let c8 = 1_u8 as u16; + let c9 = 1_u8 as u32; + let c10 = 1_u8 as u64; + let c11 = 1_u8 as f32; + let c12 = 1_u8 as f64; + let c13 = 1_u8 as *const String; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) +} + +fn from_1i8() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const String) { + let c1 = 1_i8 as isize; + let c2 = 1_i8 as usize; + let c3 = 1_i8 as i8; + let c4 = 1_i8 as i16; + let c5 = 1_i8 as i32; + let c6 = 1_i8 as i64; + let c7 = 1_i8 as u8; + let c8 = 1_i8 as u16; + let c9 = 1_i8 as u32; + let c10 = 1_i8 as u64; + let c11 = 1_i8 as f32; + let c12 = 1_i8 as f64; + let c13 = 1_i8 as *const String; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) +} + +fn from_1u16() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const String) { + let c1 = 1_u16 as isize; + let c2 = 1_u16 as usize; + let c3 = 1_u16 as i8; + let c4 = 1_u16 as i16; + let c5 = 1_u16 as i32; + let c6 = 1_u16 as i64; + let c7 = 1_u16 as u8; + let c8 = 1_u16 as u16; + let c9 = 1_u16 as u32; + let c10 = 1_u16 as u64; + let c11 = 1_u16 as f32; + let c12 = 1_u16 as f64; + let c13 = 1_u16 as *const String; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) +} + +fn from_1i16() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const String) { + let c1 = 1_i16 as isize; + let c2 = 1_i16 as usize; + let c3 = 1_i16 as i8; + let c4 = 1_i16 as i16; + let c5 = 1_i16 as i32; + let c6 = 1_i16 as i64; + let c7 = 1_i16 as u8; + let c8 = 1_i16 as u16; + let c9 = 1_i16 as u32; + let c10 = 1_i16 as u64; + let c11 = 1_i16 as f32; + let c12 = 1_i16 as f64; + let c13 = 1_i16 as *const String; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) +} + +fn from_1u32() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const String) { + let c1 = 1_u32 as isize; + let c2 = 1_u32 as usize; + let c3 = 1_u32 as i8; + let c4 = 1_u32 as i16; + let c5 = 1_u32 as i32; + let c6 = 1_u32 as i64; + let c7 = 1_u32 as u8; + let c8 = 1_u32 as u16; + let c9 = 1_u32 as u32; + let c10 = 1_u32 as u64; + let c11 = 1_u32 as f32; + let c12 = 1_u32 as f64; + let c13 = 1_u32 as *const String; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) +} + +fn from_1i32() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const String) { + let c1 = 1_i32 as isize; + let c2 = 1_i32 as usize; + let c3 = 1_i32 as i8; + let c4 = 1_i32 as i16; + let c5 = 1_i32 as i32; + let c6 = 1_i32 as i64; + let c7 = 1_i32 as u8; + let c8 = 1_i32 as u16; + let c9 = 1_i32 as u32; + let c10 = 1_i32 as u64; + let c11 = 1_i32 as f32; + let c12 = 1_i32 as f64; + let c13 = 1_i32 as *const String; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) +} + +fn from_1u64() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const String) { + let c1 = 1_u64 as isize; + let c2 = 1_u64 as usize; + let c3 = 1_u64 as i8; + let c4 = 1_u64 as i16; + let c5 = 1_u64 as i32; + let c6 = 1_u64 as i64; + let c7 = 1_u64 as u8; + let c8 = 1_u64 as u16; + let c9 = 1_u64 as u32; + let c10 = 1_u64 as u64; + let c11 = 1_u64 as f32; + let c12 = 1_u64 as f64; + let c13 = 1_u64 as *const String; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) +} + +fn from_1i64() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const String) { + let c1 = 1_i64 as isize; + let c2 = 1_i64 as usize; + let c3 = 1_i64 as i8; + let c4 = 1_i64 as i16; + let c5 = 1_i64 as i32; + let c6 = 1_i64 as i64; + let c7 = 1_i64 as u8; + let c8 = 1_i64 as u16; + let c9 = 1_i64 as u32; + let c10 = 1_i64 as u64; + let c11 = 1_i64 as f32; + let c12 = 1_i64 as f64; + let c13 = 1_i64 as *const String; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) +} + +fn from_bool() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64) { + let c1 = true as isize; + let c2 = true as usize; + let c3 = true as i8; + let c4 = true as i16; + let c5 = true as i32; + let c6 = true as i64; + let c7 = true as u8; + let c8 = true as u16; + let c9 = true as u32; + let c10 = true as u64; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) +} + +fn from_1f32() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64) { + let c1 = 1.0_f32 as isize; + let c2 = 1.0_f32 as usize; + let c3 = 1.0_f32 as i8; + let c4 = 1.0_f32 as i16; + let c5 = 1.0_f32 as i32; + let c6 = 1.0_f32 as i64; + let c7 = 1.0_f32 as u8; + let c8 = 1.0_f32 as u16; + let c9 = 1.0_f32 as u32; + let c10 = 1.0_f32 as u64; + let c11 = 1.0_f32 as f32; + let c12 = 1.0_f32 as f64; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12) +} + +fn from_1f64() +-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64) { + let c1 = 1.0f64 as isize; + let c2 = 1.0f64 as usize; + let c3 = 1.0f64 as i8; + let c4 = 1.0f64 as i16; + let c5 = 1.0f64 as i32; + let c6 = 1.0f64 as i64; + let c7 = 1.0f64 as u8; + let c8 = 1.0f64 as u16; + let c9 = 1.0f64 as u32; + let c10 = 1.0f64 as u64; + let c11 = 1.0f64 as f32; + let c12 = 1.0f64 as f64; + (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12) +} + +fn other_casts() +-> (*const u8, *const isize, *const u8, *const u8) { + let c1 = func as *const u8; + let c2 = c1 as *const isize; + + let r = &42u32; + let _ = r as *const u32; + + // fat-ptr -> fat-ptr -> fat-raw-ptr -> thin-ptr + let c3 = STR as &str as *const str as *const u8; + + let c4 = BSTR as *const [u8] as *const [u16] as *const u8; + (c1, c2, c3, c4) +} + +pub fn assert_eq_13(l: (isize, usize, i8, i16, i32, i64, u8, + u16, u32, u64, f32, f64, *const String), + r: (isize, usize, i8, i16, i32, i64, u8, + u16, u32, u64, f32, f64, *const String)) -> bool { + let (l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13) = l; + let (r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13) = r; + l1 == r1 && l2 == r2 && l3 == r3 && l4 == r4 && l5 == r5 && l6 == r6 && l7 == r7 && + l8 == r8 && l9 == r9 && l10 == r10 && l11 == r11 && l12 == r12 && l13 == r13 +} + + +pub fn main() { + let f = 1_usize as *const String; + let t13 = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.0, 1.0, f); + let t12 = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.0, 1.0); + assert_eq_13(from_1(), t13); + assert_eq_13(from_1usize(), t13); + assert_eq_13(from_1isize(), t13); + assert_eq_13(from_1u8(), t13); + assert_eq_13(from_1i8(), t13); + assert_eq_13(from_1u16(), t13); + assert_eq_13(from_1i16(), t13); + assert_eq_13(from_1u32(), t13); + assert_eq_13(from_1i32(), t13); + assert_eq_13(from_1u64(), t13); + assert_eq_13(from_1i64(), t13); + assert_eq!(from_1f32(), t12); + assert_eq!(from_1f64(), t12); + + assert_eq!(from_ptr(), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 as *const ())); + assert_eq!(from_bool(), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1)); + + assert_eq!(other_casts(), (func as *const u8, func as *const isize, + STR as *const str as *const u8, BSTR as *const [u8] as *const u8)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_overflow_off.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_overflow_off.rs new file mode 100644 index 000000000000..0466183eb0d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_overflow_off.rs @@ -0,0 +1,18 @@ +// run-pass +// compile-flags: -Z force-overflow-checks=off + +// Test that with MIR codegen, overflow checks can be +// turned off, even when they're from core::ops::*. + +use std::ops::*; + +fn main() { + assert_eq!(i8::neg(-0x80), -0x80); + + assert_eq!(u8::add(0xff, 1), 0_u8); + assert_eq!(u8::sub(0, 1), 0xff_u8); + assert_eq!(u8::mul(0xff, 2), 0xfe_u8); + assert_eq!(u8::shl(1, 9), 2_u8); + assert_eq!(u8::shr(2, 9), 1_u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_raw_fat_ptr.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_raw_fat_ptr.rs new file mode 100644 index 000000000000..8d89372fb7bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_raw_fat_ptr.rs @@ -0,0 +1,216 @@ +// run-pass +// check raw fat pointer ops in mir +// FIXME: please improve this when we get monomorphization support +#![feature(raw_ref_op)] + +use std::mem; + +#[derive(Debug, PartialEq, Eq)] +struct ComparisonResults { + lt: bool, + le: bool, + gt: bool, + ge: bool, + eq: bool, + ne: bool +} + +const LT: ComparisonResults = ComparisonResults { + lt: true, + le: true, + gt: false, + ge: false, + eq: false, + ne: true +}; + +const EQ: ComparisonResults = ComparisonResults { + lt: false, + le: true, + gt: false, + ge: true, + eq: true, + ne: false +}; + +const GT: ComparisonResults = ComparisonResults { + lt: false, + le: false, + gt: true, + ge: true, + eq: false, + ne: true +}; + +fn compare_su8(a: *const S<[u8]>, b: *const S<[u8]>) -> ComparisonResults { + ComparisonResults { + lt: a < b, + le: a <= b, + gt: a > b, + ge: a >= b, + eq: a == b, + ne: a != b + } +} + +fn compare_au8(a: *const [u8], b: *const [u8]) -> ComparisonResults { + ComparisonResults { + lt: a < b, + le: a <= b, + gt: a > b, + ge: a >= b, + eq: a == b, + ne: a != b + } +} + +fn compare_foo<'a>(a: *const (dyn Foo+'a), b: *const (dyn Foo+'a)) -> ComparisonResults { + ComparisonResults { + lt: a < b, + le: a <= b, + gt: a > b, + ge: a >= b, + eq: a == b, + ne: a != b + } +} + +fn simple_eq<'a>(a: *const (dyn Foo+'a), b: *const (dyn Foo+'a)) -> bool { + let result = a == b; + result +} + +fn assert_inorder(a: &[T], + compare: fn(T, T) -> ComparisonResults) { + for i in 0..a.len() { + for j in 0..a.len() { + let cres = compare(a[i], a[j]); + if i < j { + assert_eq!(cres, LT); + } else if i == j { + assert_eq!(cres, EQ); + } else { + assert_eq!(cres, GT); + } + } + } +} + +trait Foo { fn foo(&self) -> usize; } +impl Foo for T { + fn foo(&self) -> usize { + mem::size_of::() + } +} + +struct S(u32, T); + +fn main_ref() { + let array = [0,1,2,3,4]; + let array2 = [5,6,7,8,9]; + + // fat ptr comparison: addr then extra + + // check ordering for arrays + let mut ptrs: Vec<*const [u8]> = vec![ + &array[0..0], &array[0..1], &array, &array[1..] + ]; + + let array_addr = &array as *const [u8] as *const u8 as usize; + let array2_addr = &array2 as *const [u8] as *const u8 as usize; + if array2_addr < array_addr { + ptrs.insert(0, &array2); + } else { + ptrs.push(&array2); + } + assert_inorder(&ptrs, compare_au8); + + let u8_ = (0u8, 1u8); + let u32_ = (4u32, 5u32); + + // check ordering for ptrs + let buf: &mut [*const dyn Foo] = &mut [ + &u8_, &u8_.0, + &u32_, &u32_.0, + ]; + buf.sort_by(|u,v| { + let u : [*const (); 2] = unsafe { mem::transmute(*u) }; + let v : [*const (); 2] = unsafe { mem::transmute(*v) }; + u.cmp(&v) + }); + assert_inorder(buf, compare_foo); + + // check ordering for structs containing arrays + let ss: (S<[u8; 2]>, + S<[u8; 3]>, + S<[u8; 2]>) = ( + S(7, [8, 9]), + S(10, [11, 12, 13]), + S(4, [5, 6]) + ); + assert_inorder(&[ + &ss.0 as *const S<[u8]>, + &ss.1 as *const S<[u8]>, + &ss.2 as *const S<[u8]> + ], compare_su8); + + assert!(simple_eq(&0u8 as *const _, &0u8 as *const _)); + assert!(!simple_eq(&0u8 as *const _, &1u8 as *const _)); +} + +// similar to above, but using &raw +fn main_raw() { + let array = [0,1,2,3,4]; + let array2 = [5,6,7,8,9]; + + // fat ptr comparison: addr then extra + + // check ordering for arrays + let mut ptrs: Vec<*const [u8]> = vec![ + &raw const array[0..0], &raw const array[0..1], &raw const array, &raw const array[1..] + ]; + + let array_addr = &raw const array as *const u8 as usize; + let array2_addr = &raw const array2 as *const u8 as usize; + if array2_addr < array_addr { + ptrs.insert(0, &raw const array2); + } else { + ptrs.push(&raw const array2); + } + assert_inorder(&ptrs, compare_au8); + + let u8_ = (0u8, 1u8); + let u32_ = (4u32, 5u32); + + // check ordering for ptrs + let buf: &mut [*const dyn Foo] = &mut [ + &raw const u8_, &raw const u8_.0, + &raw const u32_, &raw const u32_.0, + ]; + buf.sort_by(|u,v| { + let u : [*const (); 2] = unsafe { mem::transmute(*u) }; + let v : [*const (); 2] = unsafe { mem::transmute(*v) }; + u.cmp(&v) + }); + assert_inorder(buf, compare_foo); + + // check ordering for structs containing arrays + let ss: (S<[u8; 2]>, + S<[u8; 3]>, + S<[u8; 2]>) = ( + S(7, [8, 9]), + S(10, [11, 12, 13]), + S(4, [5, 6]) + ); + assert_inorder(&[ + &raw const ss.0 as *const S<[u8]>, + &raw const ss.1 as *const S<[u8]>, + &raw const ss.2 as *const S<[u8]> + ], compare_su8); +} + +fn main() { + main_ref(); + main_raw(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_refs_correct.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_refs_correct.rs new file mode 100644 index 000000000000..31457a20b20d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_refs_correct.rs @@ -0,0 +1,210 @@ +// run-pass +// aux-build:mir_external_refs.rs + +extern crate mir_external_refs as ext; + +struct S(u8); +#[derive(Debug, PartialEq, Eq)] +struct Unit; + +impl S { + fn hey() -> u8 { 42 } + fn hey2(&self) -> u8 { 44 } +} + +trait X { + fn hoy(&self) -> u8 { 43 } + fn hoy2() -> u8 { 45 } +} + +trait F { + fn f(self, other: U) -> u64; +} + +impl F for u32 { + fn f(self, other: u32) -> u64 { self as u64 + other as u64 } +} + +impl F for u32 { + fn f(self, other: u64) -> u64 { self as u64 - other } +} + +impl F for u64 { + fn f(self, other: u64) -> u64 { self * other } +} + +impl F for u64 { + fn f(self, other: u32) -> u64 { self ^ other as u64 } +} + +trait T { + fn staticmeth(i: I, o: O) -> (I, O) { (i, o) } +} + +impl T for O {} + +impl X for S {} + +enum E { + U(u8) +} + +#[derive(PartialEq, Debug, Eq)] +enum CEnum { + A = 0x321, + B = 0x123 +} + +const C: u8 = 84; +const C2: [u8; 5] = [42; 5]; +const C3: [u8; 3] = [42, 41, 40]; +const C4: fn(u8) -> S = S; + +fn regular() -> u8 { + 21 +} + +fn parametric(u: T) -> T { + u +} + +fn t1() -> fn()->u8 { + regular +} + +fn t2() -> fn(u8)->E { + E::U +} + +fn t3() -> fn(u8)->S { + S +} + +fn t4() -> fn()->u8 { + S::hey +} + +fn t5() -> fn(&S)-> u8 { + ::hoy +} + + +fn t6() -> fn()->u8{ + ext::regular_fn +} + +fn t7() -> fn(u8)->ext::E { + ext::E::U +} + +fn t8() -> fn(u8)->ext::S { + ext::S +} + +fn t9() -> fn()->u8 { + ext::S::hey +} + +fn t10() -> fn(&ext::S)->u8 { + ::hoy +} + +fn t11() -> fn(u8)->u8 { + parametric +} + +fn t12() -> u8 { + C +} + +fn t13() -> [u8; 5] { + C2 +} + +fn t13_2() -> [u8; 3] { + C3 +} + +fn t14() -> fn()-> u8 { + ::hoy2 +} + +fn t15() -> fn(&S)-> u8 { + S::hey2 +} + +fn t16() -> fn(u32, u32)->u64 { + F::f +} + +fn t17() -> fn(u32, u64)->u64 { + F::f +} + +fn t18() -> fn(u64, u64)->u64 { + F::f +} + +fn t19() -> fn(u64, u32)->u64 { + F::f +} + +fn t20() -> fn(u64, u32)->(u64, u32) { + >::staticmeth +} + +fn t21() -> Unit { + Unit +} + +fn t22() -> Option { + None +} + +fn t23() -> (CEnum, CEnum) { + (CEnum::A, CEnum::B) +} + +fn t24() -> fn(u8) -> S { + C4 +} + +fn main() { + assert_eq!(t1()(), regular()); + + assert_eq!(t2() as *mut (), E::U as *mut ()); + assert_eq!(t3() as *mut (), S as *mut ()); + + assert_eq!(t4()(), S::hey()); + let s = S(42); + assert_eq!(t5()(&s), ::hoy(&s)); + + + assert_eq!(t6()(), ext::regular_fn()); + assert_eq!(t7() as *mut (), ext::E::U as *mut ()); + assert_eq!(t8() as *mut (), ext::S as *mut ()); + + assert_eq!(t9()(), ext::S::hey()); + let sext = ext::S(6); + assert_eq!(t10()(&sext), ::hoy(&sext)); + + let p = parametric::; + assert_eq!(t11() as *mut (), p as *mut ()); + + assert_eq!(t12(), C); + assert_eq!(t13(), C2); + assert_eq!(t13_2(), C3); + + assert_eq!(t14()(), ::hoy2()); + assert_eq!(t15()(&s), S::hey2(&s)); + assert_eq!(t16()(10u32, 20u32), F::f(10u32, 20u32)); + assert_eq!(t17()(30u32, 10u64), F::f(30u32, 10u64)); + assert_eq!(t18()(50u64, 5u64), F::f(50u64, 5u64)); + assert_eq!(t19()(322u64, 2u32), F::f(322u64, 2u32)); + assert_eq!(t20()(123u64, 38u32), >::staticmeth(123, 38)); + assert_eq!(t21(), Unit); + assert_eq!(t22(), None); + assert_eq!(t23(), (CEnum::A, CEnum::B)); + assert_eq!(t24(), C4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_small_agg_arg.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_small_agg_arg.rs new file mode 100644 index 000000000000..ae43b8a37ff7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_small_agg_arg.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(unused_variables)] +fn foo((x, y): (i8, i8)) { +} + +fn main() { + foo((0, 1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_static_subtype.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_static_subtype.rs new file mode 100644 index 000000000000..972c0729723f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_static_subtype.rs @@ -0,0 +1,10 @@ +// run-pass +// Test that subtyping the body of a static doesn't cause an ICE. + +fn foo(_ : &()) {} +static X: fn(&'static ()) = foo; + +fn main() { + let _ = X; +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_struct_with_assoc_ty.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_struct_with_assoc_ty.rs new file mode 100644 index 000000000000..36b706f5f6cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_struct_with_assoc_ty.rs @@ -0,0 +1,30 @@ +// run-pass +use std::marker::PhantomData; + +pub trait DataBind { + type Data; +} + +impl DataBind for Global { + type Data = T; +} + +pub struct Global(PhantomData); + +pub struct Data { + pub offsets: as DataBind>::Data, +} + +fn create_data() -> Data { + let mut d = Data { offsets: [1, 2] }; + d.offsets[0] = 3; + d +} + + +fn main() { + let d = create_data(); + assert_eq!(d.offsets[0], 3); + assert_eq!(d.offsets[1], 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_temp_promotions.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_temp_promotions.rs new file mode 100644 index 000000000000..e270aaf66ec4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_temp_promotions.rs @@ -0,0 +1,11 @@ +// run-pass +fn test1(f: f32) -> bool { + // test that we properly promote temporaries to allocas when a temporary is assigned to + // multiple times (assignment is still happening once ∀ possible dataflows). + !(f.is_nan() || f.is_infinite()) +} + +fn main() { + assert_eq!(test1(0.0), true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_void_return.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_void_return.rs new file mode 100644 index 000000000000..509070f3d2eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_void_return.rs @@ -0,0 +1,13 @@ +// run-pass +fn mir() -> (){ + let x = 1; + let mut y = 0; + while y < x { + y += 1 + } +} + +pub fn main() { + mir(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/mir_void_return_2.rs b/gcc/testsuite/rust/rustc/ui/mir/mir_void_return_2.rs new file mode 100644 index 000000000000..02c9052eaa13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/mir_void_return_2.rs @@ -0,0 +1,11 @@ +// run-pass +fn nil() {} + +fn mir(){ + nil() +} + +pub fn main() { + mir(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mir/simplify-branch-same.rs b/gcc/testsuite/rust/rustc/ui/mir/simplify-branch-same.rs new file mode 100644 index 000000000000..6bd805d003a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir/simplify-branch-same.rs @@ -0,0 +1,22 @@ +// Regression test for SimplifyBranchSame miscompilation. +// run-pass + +macro_rules! m { + ($a:expr, $b:expr, $c:block) => { + match $a { + Lto::Fat | Lto::Thin => { $b; (); $c } + Lto::No => { $b; () } + } + } +} + +pub enum Lto { No, Thin, Fat } + +fn f(mut cookie: u32, lto: Lto) -> u32 { + let mut _a = false; + m!(lto, _a = true, {cookie = 0}); + cookie +} + +fn main() { assert_eq!(f(42, Lto::Thin), 0) } + diff --git a/gcc/testsuite/rust/rustc/ui/mir_check_nonconst.rs b/gcc/testsuite/rust/rustc/ui/mir_check_nonconst.rs new file mode 100644 index 000000000000..7ef34b95e79b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mir_check_nonconst.rs @@ -0,0 +1,12 @@ +#![allow(dead_code)] + +struct Foo { a: u8 } +fn bar() -> Foo { + Foo { a: 5 } +} + +static foo: Foo = bar(); +// { dg-error ".E0015." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/E0053.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/E0053.rs new file mode 100644 index 000000000000..600724f7db21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/E0053.rs @@ -0,0 +1,17 @@ +trait Foo { + fn foo(x: u16); + fn bar(&self); +} + +struct Bar; + +impl Foo for Bar { + fn foo(x: i16) { } +// { dg-error ".E0053." "" { target *-*-* } .-1 } + fn bar(&mut self) { } +// { dg-error ".E0053." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/E0409.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/E0409.rs new file mode 100644 index 000000000000..81289211e951 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/E0409.rs @@ -0,0 +1,10 @@ +fn main() { + let x = (0, 2); + + match x { + (0, ref y) | (y, 0) => {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + _ => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/E0631.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/E0631.rs new file mode 100644 index 000000000000..7100c5096907 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/E0631.rs @@ -0,0 +1,12 @@ +#![feature(unboxed_closures)] + +fn foo(_: F) {} +fn bar>(_: F) {} +fn main() { + fn f(_: u64) {} + foo(|_: isize| {}); // { dg-error ".E0631." "" { target *-*-* } } + bar(|_: isize| {}); // { dg-error ".E0631." "" { target *-*-* } } + foo(f); // { dg-error ".E0631." "" { target *-*-* } } + bar(f); // { dg-error ".E0631." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/abridged.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/abridged.rs new file mode 100644 index 000000000000..10a7ac0883d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/abridged.rs @@ -0,0 +1,63 @@ +enum Bar { + Qux, + Zar, +} + +struct Foo { + bar: usize, +} + +struct X { + x: T1, + y: T2, +} + +fn a() -> Foo { + Some(Foo { bar: 1 }) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn a2() -> Foo { + Ok(Foo { bar: 1}) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn b() -> Option { + Foo { bar: 1 } // { dg-error ".E0308." "" { target *-*-* } } +} + +fn c() -> Result { + Foo { bar: 1 } // { dg-error ".E0308." "" { target *-*-* } } +} + +fn d() -> X, String> { + let x = X { + x: X { + x: "".to_string(), + y: 2, + }, + y: 3, + }; + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn e() -> X, String> { + let x = X { + x: X { + x: "".to_string(), + y: 2, + }, + y: "".to_string(), + }; + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn f() -> String { + 1+2 // { dg-error ".E0308." "" { target *-*-* } } +} + + +fn g() -> String { + -2 // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/binops.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/binops.rs new file mode 100644 index 000000000000..f2b7737803f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/binops.rs @@ -0,0 +1,9 @@ +fn main() { + 1 + Some(1); // { dg-error ".E0277." "" { target *-*-* } } + 2 as usize - Some(1); // { dg-error ".E0277." "" { target *-*-* } } + 3 * (); // { dg-error ".E0277." "" { target *-*-* } } + 4 / ""; // { dg-error ".E0277." "" { target *-*-* } } + 5 < String::new(); // { dg-error ".E0277." "" { target *-*-* } } + 6 == Ok(1); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/cast-rfc0401.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/cast-rfc0401.rs new file mode 100644 index 000000000000..23298c0936b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/cast-rfc0401.rs @@ -0,0 +1,73 @@ +fn illegal_cast(u: *const U) -> *const V +{ + u as *const V // { dg-error ".E0606." "" { target *-*-* } } +} + +fn illegal_cast_2(u: *const U) -> *const str +{ + u as *const str // { dg-error ".E0606." "" { target *-*-* } } +} + +trait Foo { fn foo(&self) {} } +impl Foo for T {} + +trait Bar { fn foo(&self) {} } +impl Bar for T {} + +enum E { + A, B +} + +fn main() +{ + let f: f32 = 1.2; + let v = core::ptr::null::(); + let fat_v : *const [u8] = unsafe { &*core::ptr::null::<[u8; 1]>()}; + let fat_sv : *const [i8] = unsafe { &*core::ptr::null::<[i8; 1]>()}; + let foo: &dyn Foo = &f; + + let _ = v as &u8; // { dg-error ".E0605." "" { target *-*-* } } + let _ = v as E; // { dg-error ".E0605." "" { target *-*-* } } + let _ = v as fn(); // { dg-error ".E0605." "" { target *-*-* } } + let _ = v as (u32,); // { dg-error ".E0605." "" { target *-*-* } } + let _ = Some(&v) as *const u8; // { dg-error ".E0605." "" { target *-*-* } } + + let _ = v as f32; // { dg-error ".E0606." "" { target *-*-* } } + let _ = main as f64; // { dg-error ".E0606." "" { target *-*-* } } + let _ = &v as usize; // { dg-error ".E0606." "" { target *-*-* } } + let _ = f as *const u8; // { dg-error ".E0606." "" { target *-*-* } } + let _ = 3_i32 as bool; // { dg-error ".E0054." "" { target *-*-* } } + let _ = E::A as bool; // { dg-error ".E0054." "" { target *-*-* } } + let _ = 0x61u32 as char; // { dg-error ".E0604." "" { target *-*-* } } + + let _ = false as f32; // { dg-error ".E0606." "" { target *-*-* } } + let _ = E::A as f32; // { dg-error ".E0606." "" { target *-*-* } } + let _ = 'a' as f32; // { dg-error ".E0606." "" { target *-*-* } } + + let _ = false as *const u8; // { dg-error ".E0606." "" { target *-*-* } } + let _ = E::A as *const u8; // { dg-error ".E0606." "" { target *-*-* } } + let _ = 'a' as *const u8; // { dg-error ".E0606." "" { target *-*-* } } + + let _ = 42usize as *const [u8]; // { dg-error ".E0606." "" { target *-*-* } } + let _ = v as *const [u8]; // { dg-error ".E0607." "" { target *-*-* } } + let _ = fat_v as *const dyn Foo; // { dg-error ".E0277." "" { target *-*-* } } + let _ = foo as *const str; // { dg-error ".E0606." "" { target *-*-* } } + let _ = foo as *mut str; // { dg-error ".E0606." "" { target *-*-* } } + let _ = main as *mut str; // { dg-error ".E0606." "" { target *-*-* } } + let _ = &f as *mut f32; // { dg-error ".E0606." "" { target *-*-* } } + let _ = &f as *const f64; // { dg-error ".E0606." "" { target *-*-* } } + let _ = fat_sv as usize; // { dg-error ".E0606." "" { target *-*-* } } + + let a : *const str = "hello"; + let _ = a as *const dyn Foo; // { dg-error ".E0277." "" { target *-*-* } } + + // check no error cascade + let _ = main.f as *const u32; // { dg-error ".E0609." "" { target *-*-* } } + + let cf: *const dyn Foo = &0; + let _ = cf as *const [u16]; // { dg-error ".E0606." "" { target *-*-* } } + let _ = cf as *const dyn Bar; // { dg-error ".E0606." "" { target *-*-* } } + + vec![0.0].iter().map(|s| s as f32).collect::>(); // { dg-error ".E0606." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.rs new file mode 100644 index 000000000000..2e42a1ee1190 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.rs @@ -0,0 +1,21 @@ +// Regression test for #47244: in this specific scenario, when the +// expected type indicated 1 argument but the closure takes two, we +// would (early on) create type variables for the type of `b`. If the +// user then attempts to invoke a method on `b`, we would get an error +// saying that the type of `b` must be known, which was not very +// helpful. + +// run-rustfix + +use std::collections::HashMap; + +fn main() { + let mut m = HashMap::new(); + m.insert("foo", "bar"); + + let _n = m.iter().map(|_, b| { +// { dg-error ".E0593." "" { target *-*-* } .-1 } + b.to_string() + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/closure-arg-count.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/closure-arg-count.rs new file mode 100644 index 000000000000..88e6a205ca76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/closure-arg-count.rs @@ -0,0 +1,44 @@ +#![feature(unboxed_closures)] + +fn f>(_: F) {} +fn main() { + [1, 2, 3].sort_by(|| panic!()); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + [1, 2, 3].sort_by(|tuple| panic!()); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + [1, 2, 3].sort_by(|(tuple, tuple2)| panic!()); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + [1, 2, 3].sort_by(|(tuple, tuple2): (usize, _)| panic!()); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + f(|| panic!()); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + f( move || panic!()); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + + let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + let bar = |i, x, y| i; + let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + let _it = vec![1, 2, 3].into_iter().enumerate().map(qux); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + + let _it = vec![1, 2, 3].into_iter().map(usize::checked_add); +// { dg-error ".E0593." "" { target *-*-* } .-1 } + + call(Foo); +// { dg-error ".E0593." "" { target *-*-* } .-1 } +} + +fn foo() {} +fn qux(x: usize, y: usize) {} + +fn call(_: F) where F: FnOnce() -> R {} +struct Foo(u8); + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/closure-arg-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/closure-arg-type-mismatch.rs new file mode 100644 index 000000000000..ef1373398623 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/closure-arg-type-mismatch.rs @@ -0,0 +1,16 @@ +fn main() { + let a = [(1u32, 2u32)]; + a.iter().map(|_: (u32, u32)| 45); // { dg-error ".E0631." "" { target *-*-* } } + a.iter().map(|_: &(u16, u16)| 45); // { dg-error ".E0631." "" { target *-*-* } } + a.iter().map(|_: (u16, u16)| 45); // { dg-error ".E0631." "" { target *-*-* } } +} + +fn baz(_: F) {} +fn _test<'a>(f: fn(*mut &'a u32)) { + baz(f); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/closure-mismatch.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/closure-mismatch.rs new file mode 100644 index 000000000000..0bafb6982a13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/closure-mismatch.rs @@ -0,0 +1,10 @@ +trait Foo {} + +impl Foo for T {} + +fn baz(_: T) {} + +fn main() { + baz(|_| ()); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/const-fn-in-trait.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/const-fn-in-trait.rs new file mode 100644 index 000000000000..b3d7b292aabc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/const-fn-in-trait.rs @@ -0,0 +1,14 @@ +#![feature(const_fn)] + +trait Foo { + fn f() -> u32; + const fn g(); // { dg-error ".E0379." "" { target *-*-* } } +} + +impl Foo for u32 { + const fn f() -> u32 { 22 } // { dg-error ".E0379." "" { target *-*-* } } + fn g() {} +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/fn-variance-1.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/fn-variance-1.rs new file mode 100644 index 000000000000..46cf18b9c908 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/fn-variance-1.rs @@ -0,0 +1,18 @@ +fn takes_imm(x: &isize) { } + +fn takes_mut(x: &mut isize) { } + +fn apply(t: T, f: F) where F: FnOnce(T) { + f(t) +} + +fn main() { + apply(&3, takes_imm); + apply(&3, takes_mut); +// { dg-error ".E0631." "" { target *-*-* } .-1 } + + apply(&mut 3, takes_mut); + apply(&mut 3, takes_imm); +// { dg-error ".E0631." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/for-loop-has-unit-body.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/for-loop-has-unit-body.rs new file mode 100644 index 000000000000..d0cc47a417af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/for-loop-has-unit-body.rs @@ -0,0 +1,6 @@ +fn main() { + for x in 0..3 { + x // { dg-error ".E0308." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-19109.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-19109.rs new file mode 100644 index 000000000000..b8bcfffe1755 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-19109.rs @@ -0,0 +1,9 @@ +trait Trait { } + +fn function(t: &mut dyn Trait) { + t as *mut dyn Trait +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-26480.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-26480.rs new file mode 100644 index 000000000000..1b73e02ac327 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-26480.rs @@ -0,0 +1,30 @@ +extern { + fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64; +} + +#[inline(always)] +fn size_of(_: T) -> usize { + ::std::mem::size_of::() +} + +macro_rules! write { + ($arr:expr) => {{ + #[allow(non_upper_case_globals)] + const stdout: i32 = 1; + unsafe { + write(stdout, $arr.as_ptr() as *const i8, + $arr.len() * size_of($arr[0])); // { dg-error ".E0308." "" { target *-*-* } } + } + }} +} + +macro_rules! cast { + ($x:expr) => ($x as ()) // { dg-error ".E0605." "" { target *-*-* } } +} + +fn main() { + let hello = ['H', 'e', 'y']; + write!(hello); + cast!(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-35030.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-35030.rs new file mode 100644 index 000000000000..2f81c1e35010 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-35030.rs @@ -0,0 +1,16 @@ +#![allow(non_camel_case_types)] + +trait Parser { + fn parse(text: &str) -> Option; +} + +impl Parser for bool { + fn parse(text: &str) -> Option { + Some(true) // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn main() { + println!("{}", bool::parse("ok").unwrap_or(false)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-36053-2.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-36053-2.rs new file mode 100644 index 000000000000..97543f64cb09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-36053-2.rs @@ -0,0 +1,11 @@ +// Regression test for #36053. ICE was caused due to obligations +// being added to a special, dedicated fulfillment cx during +// a probe. + +use std::iter::once; +fn main() { + once::<&str>("str").fuse().filter(|a: &str| true).count(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +// { dg-error ".E0599." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-38371.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-38371.rs new file mode 100644 index 000000000000..dd12fbc2e086 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-38371.rs @@ -0,0 +1,28 @@ +struct Foo { +} + +fn foo(&foo: Foo) { // { dg-error ".E0308." "" { target *-*-* } } +} + +fn bar(foo: Foo) { +} + +fn qux(foo: &Foo) { +} + +fn zar(&foo: &Foo) { +} + +// The somewhat unexpected help message in this case is courtesy of +// match_default_bindings. +fn agh(&&bar: &u32) { // { dg-error ".E0308." "" { target *-*-* } } +} + +fn bgh(&&bar: u32) { // { dg-error ".E0308." "" { target *-*-* } } +} + +fn ugh(&[bar]: &u32) { // { dg-error ".E0529." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-74918-missing-lifetime.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-74918-missing-lifetime.rs new file mode 100644 index 000000000000..f77f35852b32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-74918-missing-lifetime.rs @@ -0,0 +1,29 @@ +// Regression test for issue #74918 +// Tests that we don't ICE after emitting an error + +struct ChunkingIterator> { + source: S, +} + +impl> Iterator for ChunkingIterator { + type Item = IteratorChunk; // { dg-error ".E0106." "" { target *-*-* } } + + fn next(&mut self) -> Option> { // { dg-error "" "" { target *-*-* } } + todo!() + } +} + +struct IteratorChunk<'a, T, S: Iterator> { + source: &'a mut S, +} + +impl> Iterator for IteratorChunk<'_, T, S> { + type Item = T; + + fn next(&mut self) -> Option { + todo!() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-75361-mismatched-impl.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-75361-mismatched-impl.rs new file mode 100644 index 000000000000..6db54ca90b46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/issue-75361-mismatched-impl.rs @@ -0,0 +1,25 @@ +// Regresison test for issue #75361 +// Tests that we don't ICE on mismatched types with inference variables + + +trait MyTrait { + type Item; +} + +pub trait Graph { + type EdgeType; + + fn adjacent_edges(&self) -> Box>; +} + +impl Graph for T { + type EdgeType = T; + + fn adjacent_edges(&self) -> Box + '_> { // { dg-error "" "" { target *-*-* } } + panic!() + } + +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/main.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/main.rs new file mode 100644 index 000000000000..0fadda5f98ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/main.rs @@ -0,0 +1,5 @@ +fn main() { + let x: u32 = ( // { dg-error ".E0308." "" { target *-*-* } } + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/method-help-unsatisfied-bound.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/method-help-unsatisfied-bound.rs new file mode 100644 index 000000000000..df87793ca6ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/method-help-unsatisfied-bound.rs @@ -0,0 +1,8 @@ +struct Foo; + +fn main() { + let a: Result<(), Foo> = Ok(()); + a.unwrap(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/numeric-literal-cast.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/numeric-literal-cast.rs new file mode 100644 index 000000000000..13c0e54333fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/numeric-literal-cast.rs @@ -0,0 +1,13 @@ +fn foo(_: u16) {} +fn foo1(_: f64) {} +fn foo2(_: i32) {} + +fn main() { + foo(1u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo1(2f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo2(3i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/overloaded-calls-bad.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/overloaded-calls-bad.rs new file mode 100644 index 000000000000..e49f46a736dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/overloaded-calls-bad.rs @@ -0,0 +1,34 @@ +#![feature(fn_traits, unboxed_closures)] + +use std::ops::FnMut; + +struct S { + x: isize, + y: isize, +} + +impl FnMut<(isize,)> for S { + extern "rust-call" fn call_mut(&mut self, (z,): (isize,)) -> isize { + self.x * self.y * z + } +} + +impl FnOnce<(isize,)> for S { + type Output = isize; + extern "rust-call" fn call_once(mut self, (z,): (isize,)) -> isize { + self.call_mut((z,)) + } +} + +fn main() { + let mut s = S { + x: 3, + y: 3, + }; + let ans = s("what"); // { dg-error ".E0308." "" { target *-*-* } } + let ans = s(); +// { dg-error ".E0057." "" { target *-*-* } .-1 } + let ans = s("burma", "shave"); +// { dg-error ".E0057." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/recovered-block.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/recovered-block.rs new file mode 100644 index 000000000000..df1b88278dcc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/recovered-block.rs @@ -0,0 +1,24 @@ +// ignore-cloudabi no std::env support + +use std::env; + +pub struct Foo { + text: String +} + +pub fn foo() -> Foo { + let args: Vec = env::args().collect(); + let text = args[1].clone(); + + pub Foo { text } +} +// { dg-error "" "" { target *-*-* } .-2 } + +pub fn bar() -> Foo { + fn + Foo { text: "".to_string() } +} +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/trait-bounds-cant-coerce.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/trait-bounds-cant-coerce.rs new file mode 100644 index 000000000000..920cdaf88342 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/trait-bounds-cant-coerce.rs @@ -0,0 +1,17 @@ +trait Foo { + fn dummy(&self) { } +} + +fn a(_x: Box) { +} + +fn c(x: Box) { + a(x); +} + +fn d(x: Box) { + a(x); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/trait-impl-fn-incompatibility.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/trait-impl-fn-incompatibility.rs new file mode 100644 index 000000000000..516702e1583f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/trait-impl-fn-incompatibility.rs @@ -0,0 +1,15 @@ +trait Foo { + fn foo(x: u16); + fn bar(&mut self, bar: &mut Bar); +} + +struct Bar; + +impl Foo for Bar { + fn foo(x: i16) { } // { dg-error ".E0053." "" { target *-*-* } } + fn bar(&mut self, bar: &Bar) { } // { dg-error ".E0053." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs b/gcc/testsuite/rust/rustc/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs new file mode 100644 index 000000000000..a9fb2cdfe2a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs @@ -0,0 +1,20 @@ +#![feature(unboxed_closures)] + +use std::ops::FnMut; + +fn to_fn_mut>(f: F) -> F { f } + +fn call_itisize>(y: isize, mut f: F) -> isize { +// { dg-note "" "" { target *-*-* } .-1 } + f(2, y) +} + +pub fn main() { + let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y }); +// { dg-note "" "" { target *-*-* } .-1 } + let z = call_it(3, f); +// { dg-error ".E0631." "" { target *-*-* } .-1 } +// { dg-note ".E0631." "" { target *-*-* } .-2 } + println!("{}", z); +} + diff --git a/gcc/testsuite/rust/rustc/ui/missing/auxiliary/two_macros.rs b/gcc/testsuite/rust/rustc/ui/missing/auxiliary/two_macros.rs new file mode 100644 index 000000000000..b97cc55cabc3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/auxiliary/two_macros.rs @@ -0,0 +1,6 @@ +#[macro_export] +macro_rules! macro_one { () => ("one") } + +#[macro_export] +macro_rules! macro_two { () => ("two") } + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-alloc_error_handler.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-alloc_error_handler.rs new file mode 100644 index 000000000000..eab6316c6d6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-alloc_error_handler.rs @@ -0,0 +1,24 @@ +// compile-flags: -C panic=abort +// no-prefer-dynamic + +#![no_std] +#![crate_type = "staticlib"] +#![feature(panic_handler, alloc_error_handler)] + +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { + loop {} +} + +extern crate alloc; + +#[global_allocator] +static A: MyAlloc = MyAlloc; + +struct MyAlloc; + +unsafe impl core::alloc::GlobalAlloc for MyAlloc { + unsafe fn alloc(&self, _: core::alloc::Layout) -> *mut u8 { 0 as _ } + unsafe fn dealloc(&self, _: *mut u8, _: core::alloc::Layout) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-allocator.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-allocator.rs new file mode 100644 index 000000000000..9dc7738207b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-allocator.rs @@ -0,0 +1,19 @@ +// compile-flags: -C panic=abort +// no-prefer-dynamic + +#![no_std] +#![crate_type = "staticlib"] +#![feature(panic_handler, alloc_error_handler)] + +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { + loop {} +} + +#[alloc_error_handler] +fn oom(_: core::alloc::Layout) -> ! { + loop {} +} + +extern crate alloc; + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-block-hint.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-block-hint.rs new file mode 100644 index 000000000000..1aff3393bfe5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-block-hint.rs @@ -0,0 +1,10 @@ +fn main() { + { + if (foo) => {} // { dg-error "" "" { target *-*-* } } + } + { + if (foo) + bar; // { dg-error "" "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-comma-in-match.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-comma-in-match.rs new file mode 100644 index 000000000000..5a7a3419c0a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-comma-in-match.rs @@ -0,0 +1,12 @@ +// run-rustfix + +fn main() { + match &Some(3) { + &None => 1 + &Some(2) => { 3 } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + _ => 2 + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-derivable-attr.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-derivable-attr.rs new file mode 100644 index 000000000000..7a85bb15eec6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-derivable-attr.rs @@ -0,0 +1,17 @@ +trait MyEq { + fn eq(&self, other: &Self) -> bool; +} + +struct A { + x: isize +} + +impl MyEq for isize { + fn eq(&self, other: &isize) -> bool { *self == *other } +} + +impl MyEq for A {} // { dg-error ".E0046." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-fields-in-struct-pattern.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-fields-in-struct-pattern.rs new file mode 100644 index 000000000000..c17f924e8a43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-fields-in-struct-pattern.rs @@ -0,0 +1,9 @@ +struct S(usize, usize, usize, usize); + +fn main() { + if let S { a, b, c, d } = S(1, 2, 3, 4) { +// { dg-error ".E0769." "" { target *-*-* } .-1 } + println!("hi"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-items/auxiliary/m1.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-items/auxiliary/m1.rs new file mode 100644 index 000000000000..79f1301e78d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-items/auxiliary/m1.rs @@ -0,0 +1,10 @@ +pub trait X { + const CONSTANT: u32; + type Type; + fn method(&self, s: String) -> Self::Type; + fn method2(self: Box, s: String) -> Self::Type; + fn method3(other: &Self, s: String) -> Self::Type; + fn method4(&self, other: &Self) -> Self::Type; + fn method5(self: &Box) -> Self::Type; +} + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-items/issue-40221.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-items/issue-40221.rs new file mode 100644 index 000000000000..d3dd3cfdecdb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-items/issue-40221.rs @@ -0,0 +1,17 @@ +enum P { + C(PC), +} + +enum PC { + Q, + QA, +} + +fn test(proto: P) { + match proto { // { dg-error ".E0004." "" { target *-*-* } } + P::C(PC::Q) => (), + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-items/m2.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-items/m2.rs new file mode 100644 index 000000000000..4ec75ff8a601 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-items/m2.rs @@ -0,0 +1,13 @@ +// aux-build:m1.rs + + +extern crate m1; + +struct X { +} + +impl m1::X for X { // { dg-error ".E0046." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-items/missing-type-parameter.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-items/missing-type-parameter.rs new file mode 100644 index 000000000000..1c642f5b8fe6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-items/missing-type-parameter.rs @@ -0,0 +1,6 @@ +fn foo() { } + +fn main() { + foo(); // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-macro-use.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-macro-use.rs new file mode 100644 index 000000000000..2063703946c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-macro-use.rs @@ -0,0 +1,9 @@ +// aux-build:two_macros.rs + +extern crate two_macros; + +pub fn main() { + macro_two!(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-main.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-main.rs new file mode 100644 index 000000000000..86838af78b5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-main.rs @@ -0,0 +1,3 @@ +// error-pattern: `main` function not found +fn mian() { } + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-return.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-return.rs new file mode 100644 index 000000000000..e1d2fa3a101c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-return.rs @@ -0,0 +1,6 @@ +// error-pattern: return + +fn f() -> isize { } + +fn main() { f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/missing/missing-stability.rs b/gcc/testsuite/rust/rustc/ui/missing/missing-stability.rs new file mode 100644 index 000000000000..29341872a38d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing/missing-stability.rs @@ -0,0 +1,25 @@ +// Checks that exported items without stability attributes cause an error + +#![crate_type="lib"] +#![feature(staged_api)] + +#![stable(feature = "stable_test_feature", since = "1.0.0")] + +pub fn unmarked() { +// { dg-error "" "" { target *-*-* } .-1 } + () +} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub mod foo { + // #[unstable] is inherited + pub fn unmarked() {} +} + +#[stable(feature = "stable_test_feature", since="1.0.0")] +pub mod bar { + // #[stable] is not inherited + pub fn unmarked() {} +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/missing_debug_impls.rs b/gcc/testsuite/rust/rustc/ui/missing_debug_impls.rs new file mode 100644 index 000000000000..d1be06be8614 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing_debug_impls.rs @@ -0,0 +1,39 @@ +// compile-flags: --crate-type lib +#![deny(missing_debug_implementations)] +#![allow(unused)] + +use std::fmt; + +pub enum A {} // { dg-error "" "" { target *-*-* } } + +#[derive(Debug)] +pub enum B {} + +pub enum C {} + +impl fmt::Debug for C { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + Ok(()) + } +} + +pub struct Foo; // { dg-error "" "" { target *-*-* } } + +#[derive(Debug)] +pub struct Bar; + +pub struct Baz; + +impl fmt::Debug for Baz { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + Ok(()) + } +} + +struct PrivateStruct; + +enum PrivateEnum {} + +#[derive(Debug)] +struct GenericType(T); + diff --git a/gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/foo.rs b/gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/foo.rs new file mode 100644 index 000000000000..85bc476510e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/foo.rs @@ -0,0 +1,5 @@ +// +// ignore-test this is just a helper for the real test in this dir + +mod missing; + diff --git a/gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/foo_inline.rs b/gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/foo_inline.rs new file mode 100644 index 000000000000..c607e2a6cba4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/foo_inline.rs @@ -0,0 +1,6 @@ +// ignore-test this is just a helper for the real test in this dir + +mod inline { + mod missing; +} + diff --git a/gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/missing_non_modrs_mod.rs b/gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/missing_non_modrs_mod.rs new file mode 100644 index 000000000000..eccb7ef74cf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/missing_non_modrs_mod.rs @@ -0,0 +1,3 @@ +mod foo; +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.rs b/gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.rs new file mode 100644 index 000000000000..de145f5be091 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.rs @@ -0,0 +1,3 @@ +mod foo_inline; +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mod-subitem-as-enum-variant.rs b/gcc/testsuite/rust/rustc/ui/mod-subitem-as-enum-variant.rs new file mode 100644 index 000000000000..ab49199bea4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mod-subitem-as-enum-variant.rs @@ -0,0 +1,10 @@ +mod Mod { + pub struct FakeVariant(pub T); +} + +fn main() { + Mod::FakeVariant::(0); + Mod::::FakeVariant(0); +// { dg-error ".E0109." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/module-macro_use-arguments.rs b/gcc/testsuite/rust/rustc/ui/module-macro_use-arguments.rs new file mode 100644 index 000000000000..602e436a6247 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/module-macro_use-arguments.rs @@ -0,0 +1,7 @@ +#[macro_use(foo, bar)] // { dg-error "" "" { target *-*-* } } +mod foo { +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules/auxiliary/two_macros_2.rs b/gcc/testsuite/rust/rustc/ui/modules/auxiliary/two_macros_2.rs new file mode 100644 index 000000000000..0002674603e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/auxiliary/two_macros_2.rs @@ -0,0 +1,4 @@ +macro_rules! macro_one { ($($t:tt)*) => ($($t)*) } + +macro_rules! macro_two { ($($t:tt)*) => ($($t)*) } + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod-inside-fn.rs b/gcc/testsuite/rust/rustc/ui/modules/mod-inside-fn.rs new file mode 100644 index 000000000000..0d1deb711094 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod-inside-fn.rs @@ -0,0 +1,14 @@ +// run-pass + +fn f() -> isize { + mod m { + pub fn g() -> isize { 720 } + } + + m::g() +} + +pub fn main() { + assert_eq!(f(), 720); +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod-view-items.rs b/gcc/testsuite/rust/rustc/ui/modules/mod-view-items.rs new file mode 100644 index 000000000000..7e496419043d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod-view-items.rs @@ -0,0 +1,15 @@ +// run-pass +// Test view items inside non-file-level mods + +// This is a regression test for an issue where we were failing to +// pretty-print such view items. If that happens again, this should +// begin failing. + +// pretty-expanded FIXME #23616 + +mod m { + pub fn f() -> Vec { Vec::new() } +} + +pub fn main() { let _x = m::f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_dir_implicit.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_implicit.rs new file mode 100644 index 000000000000..9a99a6861c26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_implicit.rs @@ -0,0 +1,9 @@ +// run-pass +// ignore-pretty issue #37195 + +mod mod_dir_implicit_aux; + +pub fn main() { + assert_eq!(mod_dir_implicit_aux::foo(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_dir_implicit_aux/mod.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_implicit_aux/mod.rs new file mode 100644 index 000000000000..62ec5a4f5fe3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_implicit_aux/mod.rs @@ -0,0 +1,3 @@ +// run-pass +pub fn foo() -> isize { 10 } + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_dir_path.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_path.rs new file mode 100644 index 000000000000..970adb397546 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_path.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(unused_macros)] +// ignore-pretty issue #37195 + +mod mod_dir_simple { + #[path = "test.rs"] + pub mod syrup; +} + +pub fn main() { + assert_eq!(mod_dir_simple::syrup::foo(), 10); + + #[path = "auxiliary"] + mod foo { + mod two_macros_2; + } + + #[path = "auxiliary"] + mod bar { + macro_rules! m { () => { mod two_macros_2; } } + m!(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_dir_path2.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_path2.rs new file mode 100644 index 000000000000..31bf5e96df7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_path2.rs @@ -0,0 +1,13 @@ +// run-pass +// ignore-pretty issue #37195 + +#[path = "mod_dir_simple"] +mod pancakes { + #[path = "test.rs"] + pub mod syrup; +} + +pub fn main() { + assert_eq!(pancakes::syrup::foo(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_dir_path3.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_path3.rs new file mode 100644 index 000000000000..212219493966 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_path3.rs @@ -0,0 +1,12 @@ +// run-pass +// ignore-pretty issue #37195 + +#[path = "mod_dir_simple"] +mod pancakes { + pub mod test; +} + +pub fn main() { + assert_eq!(pancakes::test::foo(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_dir_path_multi.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_path_multi.rs new file mode 100644 index 000000000000..2fdfb4e2567e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_path_multi.rs @@ -0,0 +1,18 @@ +// run-pass +// ignore-pretty issue #37195 + +#[path = "mod_dir_simple"] +mod biscuits { + pub mod test; +} + +#[path = "mod_dir_simple"] +mod gravy { + pub mod test; +} + +pub fn main() { + assert_eq!(biscuits::test::foo(), 10); + assert_eq!(gravy::test::foo(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_dir_recursive.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_recursive.rs new file mode 100644 index 000000000000..075cbfbf72d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_recursive.rs @@ -0,0 +1,15 @@ +// run-pass +// ignore-pretty issue #37195 + +// Testing that the parser for each file tracks its modules +// and paths independently. The load_another_mod module should +// not try to reuse the 'mod_dir_simple' path. + +mod mod_dir_simple { + pub mod load_another_mod; +} + +pub fn main() { + assert_eq!(mod_dir_simple::load_another_mod::test::foo(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_dir_simple.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_simple.rs new file mode 100644 index 000000000000..288e147d0366 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_simple.rs @@ -0,0 +1,11 @@ +// run-pass +// ignore-pretty issue #37195 + +mod mod_dir_simple { + pub mod test; +} + +pub fn main() { + assert_eq!(mod_dir_simple::test::foo(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_dir_simple/load_another_mod.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_simple/load_another_mod.rs new file mode 100644 index 000000000000..2661bbc586a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_simple/load_another_mod.rs @@ -0,0 +1,4 @@ +// run-pass +#[path = "test.rs"] +pub mod test; + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_dir_simple/test.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_simple/test.rs new file mode 100644 index 000000000000..62ec5a4f5fe3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_dir_simple/test.rs @@ -0,0 +1,3 @@ +// run-pass +pub fn foo() -> isize { 10 } + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_file.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_file.rs new file mode 100644 index 000000000000..bb1b48f33c55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_file.rs @@ -0,0 +1,11 @@ +// run-pass +// ignore-pretty issue #37195 + +// Testing that a plain .rs file can load modules from other source files + +mod mod_file_aux; + +pub fn main() { + assert_eq!(mod_file_aux::foo(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_file_aux.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_file_aux.rs new file mode 100644 index 000000000000..896d26d7e644 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_file_aux.rs @@ -0,0 +1,5 @@ +// run-pass +// ignore-test Not a test. Used by other tests + +pub fn foo() -> isize { 10 } + diff --git a/gcc/testsuite/rust/rustc/ui/modules/mod_file_with_path_attr.rs b/gcc/testsuite/rust/rustc/ui/modules/mod_file_with_path_attr.rs new file mode 100644 index 000000000000..3c92dc58ca39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/mod_file_with_path_attr.rs @@ -0,0 +1,12 @@ +// run-pass +// ignore-pretty issue #37195 + +// Testing that a plain .rs file can load modules from other source files + +#[path = "mod_file_aux.rs"] +mod m; + +pub fn main() { + assert_eq!(m::foo(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_f32.rs b/gcc/testsuite/rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_f32.rs new file mode 100644 index 000000000000..ffde126cbda1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_f32.rs @@ -0,0 +1,4 @@ +// run-pass + +pub type T = f32; + diff --git a/gcc/testsuite/rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_f64.rs b/gcc/testsuite/rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_f64.rs new file mode 100644 index 000000000000..88ca321bcb7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_f64.rs @@ -0,0 +1,4 @@ +// run-pass + +pub type T = f64; + diff --git a/gcc/testsuite/rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_float.rs b/gcc/testsuite/rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_float.rs new file mode 100644 index 000000000000..355dfa6c3136 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules/module-polymorphism3-files/float-template/inst_float.rs @@ -0,0 +1,4 @@ +// run-pass + +pub type T = float; + diff --git a/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_aux.rs b/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_aux.rs new file mode 100644 index 000000000000..cc63d017103b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_aux.rs @@ -0,0 +1,4 @@ +// ignore-test Not a test. Used by other tests + +pub fn foo() -> isize { 10 } + diff --git a/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_correct_spans.rs b/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_correct_spans.rs new file mode 100644 index 000000000000..ba5627016340 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_correct_spans.rs @@ -0,0 +1,9 @@ +// Testing that the source_map is maintained correctly when parsing mods from external files + +mod mod_file_aux; + +fn main() { + assert!(mod_file_aux::bar() == 10); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_disambig.rs b/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_disambig.rs new file mode 100644 index 000000000000..22cf3cec7a14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_disambig.rs @@ -0,0 +1,7 @@ +mod mod_file_disambig_aux; // { dg-error ".E0761." "" { target *-*-* } } + +fn main() { + assert_eq!(mod_file_aux::bar(), 10); +// { dg-error ".E0433." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_disambig_aux.rs b/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_disambig_aux.rs new file mode 100644 index 000000000000..2cb15fafe66d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_disambig_aux.rs @@ -0,0 +1,2 @@ +// ignore-test not a test. aux file + diff --git a/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_disambig_aux/mod.rs b/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_disambig_aux/mod.rs new file mode 100644 index 000000000000..2cb15fafe66d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/modules_and_files_visibility/mod_file_disambig_aux/mod.rs @@ -0,0 +1,2 @@ +// ignore-test not a test. aux file + diff --git a/gcc/testsuite/rust/rustc/ui/monad.rs b/gcc/testsuite/rust/rustc/ui/monad.rs new file mode 100644 index 000000000000..51d5b4b4683f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/monad.rs @@ -0,0 +1,49 @@ +// run-pass + +#![allow(non_camel_case_types)] + + + +trait vec_monad { + fn bind(&self, f: F ) -> Vec where F: FnMut(&A) -> Vec ; +} + +impl vec_monad for Vec { + fn bind(&self, mut f: F) -> Vec where F: FnMut(&A) -> Vec { + let mut r = Vec::new(); + for elt in self { + r.extend(f(elt)); + } + r + } +} + +trait option_monad { + fn bind(&self, f: F) -> Option where F: FnOnce(&A) -> Option; +} + +impl option_monad for Option { + fn bind(&self, f: F) -> Option where F: FnOnce(&A) -> Option { + match *self { + Some(ref a) => { f(a) } + None => { None } + } + } +} + +fn transform(x: Option) -> Option { + x.bind(|n| Some(*n + 1) ).bind(|n| Some(n.to_string()) ) +} + +pub fn main() { + assert_eq!(transform(Some(10)), Some("11".to_string())); + assert_eq!(transform(None), None); + assert_eq!((vec!["hi".to_string()]) + .bind(|x| vec![x.clone(), format!("{}!", x)] ) + .bind(|x| vec![x.clone(), format!("{}?", x)] ), + ["hi".to_string(), + "hi?".to_string(), + "hi!".to_string(), + "hi!?".to_string()]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/monomorphize-abi-alignment.rs b/gcc/testsuite/rust/rustc/ui/monomorphize-abi-alignment.rs new file mode 100644 index 000000000000..da17c39a697f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/monomorphize-abi-alignment.rs @@ -0,0 +1,35 @@ +// run-pass + +#![allow(non_upper_case_globals)] +/*! + * On x86_64-linux-gnu and possibly other platforms, structs get 8-byte "preferred" alignment, + * but their "ABI" alignment (i.e., what actually matters for data layout) is the largest alignment + * of any field. (Also, `u64` has 8-byte ABI alignment; this is not always true). + * + * On such platforms, if monomorphize uses the "preferred" alignment, then it will unify + * `A` and `B`, even though `S` and `S` have the field `t` at different offsets, + * and apply the wrong instance of the method `unwrap`. + */ + +#[derive(Copy, Clone)] +struct S { i:u8, t:T } + +impl S { + fn unwrap(self) -> T { + self.t + } +} + +#[derive(Copy, Clone, PartialEq, Debug)] +struct A((u32, u32)); + +#[derive(Copy, Clone, PartialEq, Debug)] +struct B(u64); + +pub fn main() { + static Ca: S = S { i: 0, t: A((13, 104)) }; + static Cb: S = S { i: 0, t: B(31337) }; + assert_eq!(Ca.unwrap(), A((13, 104))); + assert_eq!(Cb.unwrap(), B(31337)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/monomorphized-callees-with-ty-params-3314.rs b/gcc/testsuite/rust/rustc/ui/monomorphized-callees-with-ty-params-3314.rs new file mode 100644 index 000000000000..49667eaa26e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/monomorphized-callees-with-ty-params-3314.rs @@ -0,0 +1,33 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Serializer { +} + +trait Serializable { + fn serialize(&self, s: S); +} + +impl Serializable for isize { + fn serialize(&self, _s: S) { } +} + +struct F { a: A } + +impl Serializable for F { + fn serialize(&self, s: S) { + self.a.serialize(s); + } +} + +impl Serializer for isize { +} + +pub fn main() { + let foo = F { a: 1 }; + foo.serialize(1); + + let bar = F { a: F {a: 1 } }; + bar.serialize(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/issue-46099-move-in-macro.rs b/gcc/testsuite/rust/rustc/ui/moves/issue-46099-move-in-macro.rs new file mode 100644 index 000000000000..39e825a6e2f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/issue-46099-move-in-macro.rs @@ -0,0 +1,16 @@ +// Regression test for issue #46099 +// Tests that we don't emit spurious +// 'value moved in previous iteration of loop' message + +macro_rules! test { + ($v:expr) => {{ + drop(&$v); + $v + }} +} + +fn main() { + let b = Box::new(true); + test!({b}); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/issue-75904-move-closure-loop.rs b/gcc/testsuite/rust/rustc/ui/moves/issue-75904-move-closure-loop.rs new file mode 100644 index 000000000000..d0fb03c300d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/issue-75904-move-closure-loop.rs @@ -0,0 +1,16 @@ +// Regression test for issue #75904 +// Tests that we point at an expression +// that required the upvar to be moved, rather than just borrowed. + +struct NotCopy; + +fn main() { + let mut a = NotCopy; + loop { + || { // { dg-error ".E0382." "" { target *-*-* } } + &mut a; + a; + }; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-1-unique.rs b/gcc/testsuite/rust/rustc/ui/moves/move-1-unique.rs new file mode 100644 index 000000000000..c3851c9d6013 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-1-unique.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(unused_mut)] +#![feature(box_syntax)] + +#[derive(Clone)] +struct Triple { + x: isize, + y: isize, + z: isize, +} + +fn test(x: bool, foo: Box) -> isize { + let bar = foo; + let mut y: Box; + if x { y = bar; } else { y = box Triple{x: 4, y: 5, z: 6}; } + return y.y; +} + +pub fn main() { + let x: Box<_> = box Triple{x: 1, y: 2, z: 3}; + assert_eq!(test(true, x.clone()), 2); + assert_eq!(test(true, x.clone()), 2); + assert_eq!(test(true, x.clone()), 2); + assert_eq!(test(false, x), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-2-unique.rs b/gcc/testsuite/rust/rustc/ui/moves/move-2-unique.rs new file mode 100644 index 000000000000..c4490d907ff9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-2-unique.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +#![feature(box_syntax)] + +struct X { x: isize, y: isize, z: isize } + +pub fn main() { + let x: Box<_> = box X{x: 1, y: 2, z: 3}; + let y = x; + assert_eq!(y.y, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-2.rs b/gcc/testsuite/rust/rustc/ui/moves/move-2.rs new file mode 100644 index 000000000000..5537ea13500c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-2.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(dead_code)] +#![feature(box_syntax)] + +struct X { x: isize, y: isize, z: isize } + +pub fn main() { let x: Box<_> = box X {x: 1, y: 2, z: 3}; let y = x; assert_eq!(y.y, 2); } + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-3-unique.rs b/gcc/testsuite/rust/rustc/ui/moves/move-3-unique.rs new file mode 100644 index 000000000000..4ce729a66504 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-3-unique.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(unused_mut)] +#![feature(box_syntax)] + +#[derive(Clone)] +struct Triple { + x: isize, + y: isize, + z: isize, +} + +fn test(x: bool, foo: Box) -> isize { + let bar = foo; + let mut y: Box; + if x { y = bar; } else { y = box Triple {x: 4, y: 5, z: 6}; } + return y.y; +} + +pub fn main() { + let x: Box<_> = box Triple{x: 1, y: 2, z: 3}; + for _ in 0_usize..10000_usize { + assert_eq!(test(true, x.clone()), 2); + } + assert_eq!(test(false, x), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-4-unique.rs b/gcc/testsuite/rust/rustc/ui/moves/move-4-unique.rs new file mode 100644 index 000000000000..2bbe2c7e54c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-4-unique.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +#![feature(box_syntax)] + +struct Triple {a: isize, b: isize, c: isize} + +fn test(foo: Box) -> Box { + let foo = foo; + let bar = foo; + let baz = bar; + let quux = baz; + return quux; +} + +pub fn main() { + let x = box Triple{a: 1, b: 2, c: 3}; + let y = test(x); + assert_eq!(y.c, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-4.rs b/gcc/testsuite/rust/rustc/ui/moves/move-4.rs new file mode 100644 index 000000000000..dc22c3682a9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-4.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +#![feature(box_syntax)] + +struct Triple { a: isize, b: isize, c: isize } + +fn test(foo: Box) -> Box { + let foo = foo; + let bar = foo; + let baz = bar; + let quux = baz; + return quux; +} + +pub fn main() { + let x = box Triple{a: 1, b: 2, c: 3}; + let y = test(x); + assert_eq!(y.c, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-arg-2-unique.rs b/gcc/testsuite/rust/rustc/ui/moves/move-arg-2-unique.rs new file mode 100644 index 000000000000..ca6d72d3043f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-arg-2-unique.rs @@ -0,0 +1,14 @@ +// run-pass +#![feature(box_syntax)] + +fn test(foo: Box> ) { assert_eq!((*foo)[0], 10); } + +pub fn main() { + let x = box vec![10]; + // Test forgetting a local by move-in + test(x); + + // Test forgetting a temporary by move-in. + test(box vec![10]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-arg-2.rs b/gcc/testsuite/rust/rustc/ui/moves/move-arg-2.rs new file mode 100644 index 000000000000..11dc2f742f59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-arg-2.rs @@ -0,0 +1,14 @@ +// run-pass +#![feature(box_syntax)] + +fn test(foo: Box>) { assert_eq!((*foo)[0], 10); } + +pub fn main() { + let x = box vec![10]; + // Test forgetting a local by move-in + test(x); + + // Test forgetting a temporary by move-in. + test(box vec![10]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-arg.rs b/gcc/testsuite/rust/rustc/ui/moves/move-arg.rs new file mode 100644 index 000000000000..e30d031d90f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-arg.rs @@ -0,0 +1,6 @@ +// run-pass + +fn test(foo: isize) { assert_eq!(foo, 10); } + +pub fn main() { let x = 10; test(x); } + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-deref-coercion.rs b/gcc/testsuite/rust/rustc/ui/moves/move-deref-coercion.rs new file mode 100644 index 000000000000..bbb01ccd48a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-deref-coercion.rs @@ -0,0 +1,34 @@ +use std::ops::Deref; + +struct NotCopy { + inner: bool +} + +impl NotCopy { + fn inner_method(&self) {} +} + +struct Foo { + first: NotCopy, + second: NotCopy +} + +impl Deref for Foo { + type Target = NotCopy; + fn deref(&self) -> &NotCopy { + &self.second + } +} + +fn use_field(val: Foo) { + let _val = val.first; + val.inner; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn use_method(val: Foo) { + let _val = val.first; + val.inner_method(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-fn-self-receiver.rs b/gcc/testsuite/rust/rustc/ui/moves/move-fn-self-receiver.rs new file mode 100644 index 000000000000..c77e5361032e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-fn-self-receiver.rs @@ -0,0 +1,75 @@ +use std::pin::Pin; +use std::rc::Rc; +use std::ops::Add; + +struct Foo; + +impl Add for Foo { + type Output = (); + fn add(self, _rhs: Self) -> () {} +} + +impl Foo { + fn use_self(self) {} + fn use_box_self(self: Box) {} + fn use_pin_box_self(self: Pin>) {} + fn use_rc_self(self: Rc) {} + fn use_mut_self(&mut self) -> &mut Self { self } +} + +struct Container(Vec); + +impl Container { + fn custom_into_iter(self) -> impl Iterator { + self.0.into_iter() + } +} + +fn move_out(val: Container) { + val.0.into_iter().next(); + val.0; // { dg-error ".E0382." "" { target *-*-* } } + + let foo = Foo; + foo.use_self(); + foo; // { dg-error ".E0382." "" { target *-*-* } } + + let second_foo = Foo; + second_foo.use_self(); + second_foo; // { dg-error ".E0382." "" { target *-*-* } } + + let boxed_foo = Box::new(Foo); + boxed_foo.use_box_self(); + boxed_foo; // { dg-error ".E0382." "" { target *-*-* } } + + let pin_box_foo = Box::pin(Foo); + pin_box_foo.use_pin_box_self(); + pin_box_foo; // { dg-error ".E0382." "" { target *-*-* } } + + let mut mut_foo = Foo; + let ret = mut_foo.use_mut_self(); + mut_foo; // { dg-error ".E0505." "" { target *-*-* } } + ret; + + let rc_foo = Rc::new(Foo); + rc_foo.use_rc_self(); + rc_foo; // { dg-error ".E0382." "" { target *-*-* } } + + let foo_add = Foo; + foo_add + Foo; + foo_add; // { dg-error ".E0382." "" { target *-*-* } } + + let implicit_into_iter = vec![true]; + for _val in implicit_into_iter {} + implicit_into_iter; // { dg-error ".E0382." "" { target *-*-* } } + + let explicit_into_iter = vec![true]; + for _val in explicit_into_iter.into_iter() {} + explicit_into_iter; // { dg-error ".E0382." "" { target *-*-* } } + + let container = Container(vec![]); + for _val in container.custom_into_iter() {} + container; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-guard-same-consts.rs b/gcc/testsuite/rust/rustc/ui/moves/move-guard-same-consts.rs new file mode 100644 index 000000000000..cb4e14c1d18e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-guard-same-consts.rs @@ -0,0 +1,26 @@ +// #47295: We used to have a hack of special-casing adjacent amtch +// arms whose patterns were composed solely of constants to not have +// them linked in the cfg. +// +// THis was broken for various reasons. In particular, that hack was +// originally authored under the assunption that other checks +// elsewhere would ensure that the two patterns did not overlap. But +// that assumption did not hold, at least not in the long run (namely, +// overlapping patterns were turned into warnings rather than errors). + +#![feature(box_syntax)] + +fn main() { + let x: Box<_> = box 1; + + let v = (1, 2); + + match v { + (1, 2) if take(x) => (), + (1, 2) if take(x) => (), // { dg-error ".E0382." "" { target *-*-* } } + _ => (), + } +} + +fn take(_: T) -> bool { false } + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-in-guard-1.rs b/gcc/testsuite/rust/rustc/ui/moves/move-in-guard-1.rs new file mode 100644 index 000000000000..db1aec3682c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-in-guard-1.rs @@ -0,0 +1,16 @@ +#![feature(box_syntax)] + +pub fn main() { + let x: Box<_> = box 1; + + let v = (1, 2); + + match v { + (1, _) if take(x) => (), + (_, 2) if take(x) => (), // { dg-error ".E0382." "" { target *-*-* } } + _ => (), + } +} + +fn take(_: T) -> bool { false } + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-in-guard-2.rs b/gcc/testsuite/rust/rustc/ui/moves/move-in-guard-2.rs new file mode 100644 index 000000000000..61f141806a55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-in-guard-2.rs @@ -0,0 +1,16 @@ +#![feature(box_syntax)] + +pub fn main() { + let x: Box<_> = box 1; + + let v = (1, 2); + + match v { + (1, _) | + (_, 2) if take(x) => (), // { dg-error ".E0382." "" { target *-*-* } } + _ => (), + } +} + +fn take(_: T) -> bool { false } + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-into-dead-array-1.rs b/gcc/testsuite/rust/rustc/ui/moves/move-into-dead-array-1.rs new file mode 100644 index 000000000000..50c82990a5f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-into-dead-array-1.rs @@ -0,0 +1,16 @@ +// Ensure that we cannot move into an uninitialized fixed-size array. + +struct D { _x: u8 } + +fn d() -> D { D { _x: 0 } } + +fn main() { + foo(1); + foo(3); +} + +fn foo(i: usize) { + let mut a: [D; 4]; + a[i] = d(); // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-into-dead-array-2.rs b/gcc/testsuite/rust/rustc/ui/moves/move-into-dead-array-2.rs new file mode 100644 index 000000000000..a67d47d90b8a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-into-dead-array-2.rs @@ -0,0 +1,16 @@ +// Ensure that we cannot move into an uninitialized fixed-size array. + +struct D { _x: u8 } + +fn d() -> D { D { _x: 0 } } + +fn main() { + foo([d(), d(), d(), d()], 1); + foo([d(), d(), d(), d()], 3); +} + +fn foo(mut a: [D; 4], i: usize) { + drop(a); + a[i] = d(); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-nullary-fn.rs b/gcc/testsuite/rust/rustc/ui/moves/move-nullary-fn.rs new file mode 100644 index 000000000000..06b32c0bac0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-nullary-fn.rs @@ -0,0 +1,14 @@ +// run-pass +// Issue #922 +// pretty-expanded FIXME #23616 + +fn f2(_thing: F) where F: FnOnce() { } + +fn f(thing: F) where F: FnOnce() { + f2(thing); +} + +pub fn main() { + f(|| {}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-out-of-array-1.rs b/gcc/testsuite/rust/rustc/ui/moves/move-out-of-array-1.rs new file mode 100644 index 000000000000..d6237495feef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-out-of-array-1.rs @@ -0,0 +1,19 @@ +// Ensure that we cannot move out of a fixed-size array (especially +// when the element type has a destructor). + + +struct D { _x: u8 } + +impl Drop for D { fn drop(&mut self) { } } + +fn main() { + fn d() -> D { D { _x: 0 } } + + let _d1 = foo([d(), d(), d(), d()], 1); + let _d3 = foo([d(), d(), d(), d()], 3); +} + +fn foo(a: [D; 4], i: usize) -> D { + a[i] // { dg-error ".E0508." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-out-of-array-ref.rs b/gcc/testsuite/rust/rustc/ui/moves/move-out-of-array-ref.rs new file mode 100644 index 000000000000..d57416fa9b28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-out-of-array-ref.rs @@ -0,0 +1,35 @@ +// Ensure that we cannot move out of a reference to a fixed-size array + +struct D { _x: u8 } + +impl Drop for D { fn drop(&mut self) { } } + +fn move_elem(a: &[D; 4]) -> D { + let [_, e, _, _] = *a; // { dg-error ".E0508." "" { target *-*-* } } + e +} + +fn move_subarr(a: &[D; 4]) -> [D; 2] { + let [_, s @ .. , _] = *a; // { dg-error ".E0508." "" { target *-*-* } } + s +} + +fn move_elem_mut(a: &mut [D; 4]) -> D { + let [_, e, _, _] = *a; // { dg-error ".E0508." "" { target *-*-* } } + e +} + +fn move_subarr_mut(a: &mut [D; 4]) -> [D; 2] { + let [_, s @ .. , _] = *a; // { dg-error ".E0508." "" { target *-*-* } } + s +} + +fn main() { + fn d() -> D { D { _x: 0 } } + + move_elem(&[d(), d(), d(), d()]); + move_subarr(&[d(), d(), d(), d()]); + move_elem_mut(&mut [d(), d(), d(), d()]); + move_subarr_mut(&mut [d(), d(), d(), d()]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-out-of-field.rs b/gcc/testsuite/rust/rustc/ui/moves/move-out-of-field.rs new file mode 100644 index 000000000000..ed392dab1cd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-out-of-field.rs @@ -0,0 +1,28 @@ +// run-pass + +use std::string::String; + +struct StringBuffer { + s: String, +} + +impl StringBuffer { + pub fn append(&mut self, v: &str) { + self.s.push_str(v); + } +} + +fn to_string(sb: StringBuffer) -> String { + sb.s +} + +pub fn main() { + let mut sb = StringBuffer { + s: String::new(), + }; + sb.append("Hello, "); + sb.append("World!"); + let str = to_string(sb); + assert_eq!(str, "Hello, World!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-out-of-slice-1.rs b/gcc/testsuite/rust/rustc/ui/moves/move-out-of-slice-1.rs new file mode 100644 index 000000000000..d45b0389ac51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-out-of-slice-1.rs @@ -0,0 +1,12 @@ +#![feature(box_patterns)] + +struct A; + +fn main() { + let a: Box<[A]> = Box::new([A]); + match a { // { dg-error ".E0508." "" { target *-*-* } } + box [a] => {}, + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-out-of-slice-2.rs b/gcc/testsuite/rust/rustc/ui/moves/move-out-of-slice-2.rs new file mode 100644 index 000000000000..8fad74f9b685 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-out-of-slice-2.rs @@ -0,0 +1,36 @@ +#![feature(unsized_locals)] +// { dg-warning "" "" { target *-*-* } .-1 } + +struct A; +#[derive(Clone, Copy)] +struct C; + +fn main() { + let a: Box<[A]> = Box::new([A]); + match *a { +// { dg-error ".E0508." "" { target *-*-* } .-1 } + [a @ ..] => {} + _ => {} + } + let b: Box<[A]> = Box::new([A, A, A]); + match *b { +// { dg-error ".E0508." "" { target *-*-* } .-1 } + [_, _, b @ .., _] => {} + _ => {} + } + + // `[C]` isn't `Copy`, even if `C` is. + let c: Box<[C]> = Box::new([C]); + match *c { +// { dg-error ".E0508." "" { target *-*-* } .-1 } + [c @ ..] => {} + _ => {} + } + let d: Box<[C]> = Box::new([C, C, C]); + match *d { +// { dg-error ".E0508." "" { target *-*-* } .-1 } + [_, _, d @ .., _] => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-out-of-tuple-field.rs b/gcc/testsuite/rust/rustc/ui/moves/move-out-of-tuple-field.rs new file mode 100644 index 000000000000..283ed1c8bfec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-out-of-tuple-field.rs @@ -0,0 +1,14 @@ +#![feature(box_syntax)] + +struct Foo(Box); + +fn main() { + let x: (Box<_>,) = (box 1,); + let y = x.0; + let z = x.0; // { dg-error ".E0382." "" { target *-*-* } } + + let x = Foo(box 1); + let y = x.0; + let z = x.0; // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/move-scalar.rs b/gcc/testsuite/rust/rustc/ui/moves/move-scalar.rs new file mode 100644 index 000000000000..6d7643ddfc0b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/move-scalar.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_mut)] + +pub fn main() { + + let y: isize = 42; + let mut x: isize; + x = y; + assert_eq!(x, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-access-to-field.rs b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-access-to-field.rs new file mode 100644 index 000000000000..183cb34d0c41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-access-to-field.rs @@ -0,0 +1,15 @@ +// Tests that if you move from `x.f` or `x[0]`, `x` is inaccessible. +// Also tests that we give a more specific error message. + +struct Foo { f: String, y: isize } +fn consume(_s: String) {} +fn touch(_a: &A) {} + +fn f20() { + let x = vec!["hi".to_string()]; + consume(x.into_iter().next().unwrap()); + touch(&x[0]); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-block-bad.rs b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-block-bad.rs new file mode 100644 index 000000000000..62d06b52a357 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-block-bad.rs @@ -0,0 +1,30 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] + +struct S { + x: Box +} + +enum E { + Foo(Box), + Bar(Box), + Baz +} + +fn f(s: &S, g: G) where G: FnOnce(&S) { + g(s) +} + +fn main() { + let s = S { x: box E::Bar(box 42) }; + loop { + f(&s, |hellothere| { + match hellothere.x { // { dg-error ".E0507." "" { target *-*-* } } + box E::Foo(_) => {} + box E::Bar(x) => println!("{}", x.to_string()), + box E::Baz => {} + } + }) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-capture-clause-bad.rs b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-capture-clause-bad.rs new file mode 100644 index 000000000000..cad287ce2011 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-capture-clause-bad.rs @@ -0,0 +1,10 @@ +use std::thread; + +fn main() { + let x = "Hello world!".to_string(); + thread::spawn(move|| { + println!("{}", x); + }); + println!("{}", x); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-capture-clause.rs b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-capture-clause.rs new file mode 100644 index 000000000000..623133e89171 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-capture-clause.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +use std::thread; + +pub fn main() { + let x = "Hello world!".to_string(); + thread::spawn(move|| { + println!("{}", x); + }).join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-cyclic-types-issue-4821.rs b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-cyclic-types-issue-4821.rs new file mode 100644 index 000000000000..17de8690700e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-cyclic-types-issue-4821.rs @@ -0,0 +1,21 @@ +// Test for a subtle failure computing kinds of cyclic types, in which +// temporary kinds wound up being stored in a cache and used later. +// See rustc::ty::type_contents() for more information. + + +struct List { key: isize, next: Option> } + +fn foo(node: Box) -> isize { + let r = match node.next { + Some(right) => consume(right), + None => 0 + }; + consume(node) + r // { dg-error ".E0382." "" { target *-*-* } } +} + +fn consume(v: Box) -> isize { + v.key +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-distribute-copy-over-paren.rs b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-distribute-copy-over-paren.rs new file mode 100644 index 000000000000..533db9b52161 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-distribute-copy-over-paren.rs @@ -0,0 +1,50 @@ +// Tests that references to move-by-default values trigger moves when +// they occur as part of various kinds of expressions. + +struct Foo { f: A } +fn touch(_a: &A) {} + +fn f00() { + let x = "hi".to_string(); +// { dg-note "" "" { target *-*-* } .-1 } + let _y = Foo { f:x }; +// { dg-note "" "" { target *-*-* } .-1 } + touch(&x); // { dg-error ".E0382." "" { target *-*-* } } +// { dg-note ".E0382." "" { target *-*-* } .-1 } +} + +fn f05() { + let x = "hi".to_string(); +// { dg-note "" "" { target *-*-* } .-1 } + let _y = Foo { f:(((x))) }; +// { dg-note "" "" { target *-*-* } .-1 } + touch(&x); // { dg-error ".E0382." "" { target *-*-* } } +// { dg-note ".E0382." "" { target *-*-* } .-1 } +} + +fn f10() { + let x = "hi".to_string(); + let _y = Foo { f:x.clone() }; + touch(&x); +} + +fn f20() { + let x = "hi".to_string(); + let _y = Foo { f:(x).clone() }; + touch(&x); +} + +fn f30() { + let x = "hi".to_string(); + let _y = Foo { f:((x)).clone() }; + touch(&x); +} + +fn f40() { + let x = "hi".to_string(); + let _y = Foo { f:(((((((x)).clone()))))) }; + touch(&x); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-exprs.rs b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-exprs.rs new file mode 100644 index 000000000000..0474dc3977c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-exprs.rs @@ -0,0 +1,94 @@ +// Tests that references to move-by-default values trigger moves when +// they occur as part of various kinds of expressions. + + +struct Foo { f: A } +fn guard(_s: String) -> bool {panic!()} +fn touch(_a: &A) {} + +fn f10() { + let x = "hi".to_string(); + let _y = Foo { f:x }; + touch(&x); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn f20() { + let x = "hi".to_string(); + let _y = (x, 3); + touch(&x); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn f21() { + let x = vec![1, 2, 3]; + let _y = (x[0], 3); + touch(&x); +} + +fn f30(cond: bool) { + let x = "hi".to_string(); + let y = "ho".to_string(); + let _y = if cond { + x + } else { + y + }; + touch(&x); // { dg-error ".E0382." "" { target *-*-* } } + touch(&y); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn f40(cond: bool) { + let x = "hi".to_string(); + let y = "ho".to_string(); + let _y = match cond { + true => x, + false => y + }; + touch(&x); // { dg-error ".E0382." "" { target *-*-* } } + touch(&y); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn f50(cond: bool) { + let x = "hi".to_string(); + let y = "ho".to_string(); + let _y = match cond { + _ if guard(x) => 10, + true => 10, + false => 20, + }; + touch(&x); // { dg-error ".E0382." "" { target *-*-* } } + touch(&y); +} + +fn f70() { + let x = "hi".to_string(); + let _y = [x]; + touch(&x); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn f80() { + let x = "hi".to_string(); + let _y = vec![x]; + touch(&x); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn f100() { + let x = vec!["hi".to_string()]; + let _y = x.into_iter().next().unwrap(); + touch(&x); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn f110() { + let x = vec!["hi".to_string()]; + let _y = [x.into_iter().next().unwrap(); 1]; + touch(&x); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn f120() { + let mut x = vec!["hi".to_string(), "ho".to_string()]; + x.swap(0, 1); + touch(&x[0]); + touch(&x[1]); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-match-bindings.rs b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-match-bindings.rs new file mode 100644 index 000000000000..bbe0ec0a31dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-match-bindings.rs @@ -0,0 +1,22 @@ +// Tests that bindings to move-by-default values trigger moves of the +// discriminant. Also tests that the compiler explains the move in +// terms of the binding, not the discriminant. + +struct Foo { f: A } +fn guard(_s: String) -> bool {panic!()} +fn touch(_a: &A) {} + +fn f10() { + let x = Foo {f: "hi".to_string()}; + + let y = match x { + Foo {f} => {} + }; + + touch(&x); // { dg-error ".E0382." "" { target *-*-* } } +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs new file mode 100644 index 000000000000..88b0412c8f6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.rs @@ -0,0 +1,13 @@ +#![feature(box_syntax, unboxed_closures)] + +use std::usize; + +fn to_fn>(f: F) -> F { f } + +fn test(_x: Box) {} + +fn main() { + let i = box 3; + let _f = to_fn(|| test(i)); // { dg-error ".E0507." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-no-recursive-stack-closure.rs b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-no-recursive-stack-closure.rs new file mode 100644 index 000000000000..bd9f21c945c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-no-recursive-stack-closure.rs @@ -0,0 +1,36 @@ +// Tests correct kind-checking of the reason stack closures without the :Copy +// bound must be noncopyable. For details see +// http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/ + +struct R<'a> { + // This struct is needed to create the + // otherwise infinite type of a fn that + // accepts itself as argument: + c: Box +} + +fn innocent_looking_victim() { + let mut x = Some("hello".to_string()); + conspirator(|f, writer| { + if writer { + x = None; + } else { + match x { + Some(ref msg) => { + (f.c)(f, true); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + println!("{}", msg); + }, + None => panic!("oops"), + } + } + }) +} + +fn conspirator(mut f: F) where F: FnMut(&mut R, bool) { + let mut r = R {c: Box::new(f)}; + f(&mut r, false) // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() { innocent_looking_victim() } + diff --git a/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-tuple.rs b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-tuple.rs new file mode 100644 index 000000000000..656686eebff5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/moves-based-on-type-tuple.rs @@ -0,0 +1,11 @@ +#![feature(box_syntax)] + +fn dup(x: Box) -> Box<(Box,Box)> { + box (x, x) +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn main() { + dup(box 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/moves/moves-sru-moved-field.rs b/gcc/testsuite/rust/rustc/ui/moves/moves-sru-moved-field.rs new file mode 100644 index 000000000000..199dccff722b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/moves/moves-sru-moved-field.rs @@ -0,0 +1,24 @@ +#![feature(box_syntax)] + +type Noncopyable = Box; + +struct Foo { + copied: isize, + moved: Box, + noncopyable: Noncopyable +} + +fn test0(f: Foo, g: Noncopyable, h: Noncopyable) { + // just copy implicitly copyable fields from `f`, no moves: + let _b = Foo {moved: box 1, noncopyable: g, ..f}; + let _c = Foo {moved: box 2, noncopyable: h, ..f}; +} + +fn test1(f: Foo, g: Noncopyable, h: Noncopyable) { + // copying move-by-default fields from `f`, so move: + let _b = Foo {noncopyable: g, ..f}; + let _c = Foo {noncopyable: h, ..f}; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/mpsc_stress.rs b/gcc/testsuite/rust/rustc/ui/mpsc_stress.rs new file mode 100644 index 000000000000..92ea13c075bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mpsc_stress.rs @@ -0,0 +1,166 @@ +// run-pass +// compile-flags:--test +// ignore-emscripten + +use std::sync::mpsc::channel; +use std::sync::mpsc::TryRecvError; +use std::sync::mpsc::RecvError; +use std::sync::mpsc::RecvTimeoutError; +use std::sync::Arc; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; + +use std::thread; +use std::time::Duration; + + +/// Simple thread synchronization utility +struct Barrier { + // Not using mutex/condvar for precision + shared: Arc, + count: usize, +} + +impl Barrier { + fn new(count: usize) -> Vec { + let shared = Arc::new(AtomicUsize::new(0)); + (0..count).map(|_| Barrier { shared: shared.clone(), count: count }).collect() + } + + fn new2() -> (Barrier, Barrier) { + let mut v = Barrier::new(2); + (v.pop().unwrap(), v.pop().unwrap()) + } + + /// Returns when `count` threads enter `wait` + fn wait(self) { + self.shared.fetch_add(1, Ordering::SeqCst); + while self.shared.load(Ordering::SeqCst) != self.count { + #[cfg(target_env = "sgx")] + thread::yield_now(); + } + } +} + + +fn shared_close_sender_does_not_lose_messages_iter() { + let (tb, rb) = Barrier::new2(); + + let (tx, rx) = channel(); + let _ = tx.clone(); // convert to shared + + thread::spawn(move || { + tb.wait(); + thread::sleep(Duration::from_micros(1)); + tx.send(17).expect("send"); + drop(tx); + }); + + let i = rx.into_iter(); + rb.wait(); + // Make sure it doesn't return disconnected before returning an element + assert_eq!(vec![17], i.collect::>()); +} + +#[test] +fn shared_close_sender_does_not_lose_messages() { + for _ in 0..10000 { + shared_close_sender_does_not_lose_messages_iter(); + } +} + + +// https://github.com/rust-lang/rust/issues/39364 +fn concurrent_recv_timeout_and_upgrade_iter() { + // 1 us + let sleep = Duration::new(0, 1_000); + + let (a, b) = Barrier::new2(); + let (tx, rx) = channel(); + let th = thread::spawn(move || { + a.wait(); + loop { + match rx.recv_timeout(sleep) { + Ok(_) => { + break; + }, + Err(_) => {}, + } + } + }); + b.wait(); + thread::sleep(sleep); + tx.clone().send(()).expect("send"); + th.join().unwrap(); +} + +#[test] +fn concurrent_recv_timeout_and_upgrade() { + // FIXME: fix and enable + if true { return } + + // at the moment of writing this test fails like this: + // thread '' panicked at 'assertion failed: `(left == right)` + // left: `4561387584`, + // right: `0`', libstd/sync/mpsc/shared.rs:253:13 + + for _ in 0..10000 { + concurrent_recv_timeout_and_upgrade_iter(); + } +} + + +fn concurrent_writes_iter() { + const THREADS: usize = 4; + const PER_THR: usize = 100; + + let mut bs = Barrier::new(THREADS + 1); + let (tx, rx) = channel(); + + let mut threads = Vec::new(); + for j in 0..THREADS { + let tx = tx.clone(); + let b = bs.pop().unwrap(); + threads.push(thread::spawn(move || { + b.wait(); + for i in 0..PER_THR { + tx.send(j * 1000 + i).expect("send"); + } + })); + } + + let b = bs.pop().unwrap(); + b.wait(); + + let mut v: Vec<_> = rx.iter().take(THREADS * PER_THR).collect(); + v.sort(); + + for j in 0..THREADS { + for i in 0..PER_THR { + assert_eq!(j * 1000 + i, v[j * PER_THR + i]); + } + } + + for t in threads { + t.join().unwrap(); + } + + let one_us = Duration::new(0, 1000); + + assert_eq!(TryRecvError::Empty, rx.try_recv().unwrap_err()); + assert_eq!(RecvTimeoutError::Timeout, rx.recv_timeout(one_us).unwrap_err()); + + drop(tx); + + assert_eq!(RecvError, rx.recv().unwrap_err()); + assert_eq!(RecvTimeoutError::Disconnected, rx.recv_timeout(one_us).unwrap_err()); + assert_eq!(TryRecvError::Disconnected, rx.try_recv().unwrap_err()); +} + +#[test] +fn concurrent_writes() { + for _ in 0..100 { + concurrent_writes_iter(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/msvc-data-only.rs b/gcc/testsuite/rust/rustc/ui/msvc-data-only.rs new file mode 100644 index 000000000000..9624b97f5b1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/msvc-data-only.rs @@ -0,0 +1,9 @@ +// run-pass +// aux-build:msvc-data-only-lib.rs + +extern crate msvc_data_only_lib; + +fn main() { + println!("The answer is {} !", msvc_data_only_lib::FOO); +} + diff --git a/gcc/testsuite/rust/rustc/ui/multi-panic.rs b/gcc/testsuite/rust/rustc/ui/multi-panic.rs new file mode 100644 index 000000000000..34de7a8abe97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/multi-panic.rs @@ -0,0 +1,39 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +fn check_for_no_backtrace(test: std::process::Output) { + assert!(!test.status.success()); + let err = String::from_utf8_lossy(&test.stderr); + let mut it = err.lines(); + + assert_eq!(it.next().map(|l| l.starts_with("thread '' panicked at")), Some(true)); + assert_eq!(it.next(), Some("note: run with `RUST_BACKTRACE=1` \ + environment variable to display a backtrace")); + assert_eq!(it.next().map(|l| l.starts_with("thread 'main' panicked at")), Some(true)); + assert_eq!(it.next(), None); +} + +fn main() { + let args: Vec = std::env::args().collect(); + if args.len() > 1 && args[1] == "run_test" { + let _ = std::thread::spawn(|| { + panic!(); + }).join(); + + panic!(); + } else { + let test = std::process::Command::new(&args[0]).arg("run_test") + .env_remove("RUST_BACKTRACE") + .output() + .unwrap(); + check_for_no_backtrace(test); + let test = std::process::Command::new(&args[0]).arg("run_test") + .env("RUST_BACKTRACE","0") + .output() + .unwrap(); + check_for_no_backtrace(test); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/multibyte.rs b/gcc/testsuite/rust/rustc/ui/multibyte.rs new file mode 100644 index 000000000000..5ede5bed97c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/multibyte.rs @@ -0,0 +1,8 @@ +// run-pass +// + +// Test that multibyte characters don't crash the compiler +pub fn main() { + println!("마이너스 사인이 없으면"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/multidispatch-conditional-impl-not-considered.rs b/gcc/testsuite/rust/rustc/ui/multidispatch-conditional-impl-not-considered.rs new file mode 100644 index 000000000000..9fef851de157 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/multidispatch-conditional-impl-not-considered.rs @@ -0,0 +1,25 @@ +// run-pass +// Test that we correctly ignore the blanket impl +// because (in this case) `T` does not impl `Clone`. +// +// Issue #17594. + +use std::cell::RefCell; + +trait Foo { + fn foo(&self) {} +} + +impl Foo for T where T: Clone {} + +struct Bar; + +impl Bar { + fn foo(&self) {} +} + +fn main() { + let b = RefCell::new(Bar); + b.borrow().foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/multidispatch1.rs b/gcc/testsuite/rust/rustc/ui/multidispatch1.rs new file mode 100644 index 000000000000..f75cb933e8ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/multidispatch1.rs @@ -0,0 +1,34 @@ +// run-pass + +use std::fmt::Debug; + +trait MyTrait { + fn get(&self) -> T; +} + +#[derive(Copy, Clone)] +struct MyType { + dummy: usize +} + +impl MyTrait for MyType { + fn get(&self) -> usize { self.dummy } +} + +impl MyTrait for MyType { + fn get(&self) -> u8 { self.dummy as u8 } +} + +fn test_eq(m: M, v: T) +where T : Eq + Debug, + M : MyTrait +{ + assert_eq!(m.get(), v); +} + +pub fn main() { + let value = MyType { dummy: 256 + 22 }; + test_eq::(value, value.dummy); + test_eq::(value, value.dummy as u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/multidispatch2.rs b/gcc/testsuite/rust/rustc/ui/multidispatch2.rs new file mode 100644 index 000000000000..2e9cf3c8605d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/multidispatch2.rs @@ -0,0 +1,40 @@ +// run-pass + +use std::fmt::Debug; +use std::default::Default; + +trait MyTrait { + fn get(&self) -> T; +} + +impl MyTrait for T + where T : Default +{ + fn get(&self) -> T { + Default::default() + } +} + +#[derive(Copy, Clone)] +struct MyType { + dummy: usize +} + +impl MyTrait for MyType { + fn get(&self) -> usize { self.dummy } +} + +fn test_eq(m: M, v: T) +where T : Eq + Debug, + M : MyTrait +{ + assert_eq!(m.get(), v); +} + +pub fn main() { + test_eq(22_usize, 0_usize); + + let value = MyType { dummy: 256 + 22 }; + test_eq(value, value.dummy); +} + diff --git a/gcc/testsuite/rust/rustc/ui/multiline-comment.rs b/gcc/testsuite/rust/rustc/ui/multiline-comment.rs new file mode 100644 index 000000000000..ac969398bc99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/multiline-comment.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +/* + * This is a multi-line oldcomment. + */ +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/multiple-main-2.rs b/gcc/testsuite/rust/rustc/ui/multiple-main-2.rs new file mode 100644 index 000000000000..de2b8849fab4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/multiple-main-2.rs @@ -0,0 +1,10 @@ +#![feature(main)] + +#[main] +fn bar() { +} + +#[main] +fn foo() { // { dg-error ".E0137." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/multiple-main-3.rs b/gcc/testsuite/rust/rustc/ui/multiple-main-3.rs new file mode 100644 index 000000000000..c824dbed62a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/multiple-main-3.rs @@ -0,0 +1,12 @@ +#![feature(main)] + +#[main] +fn main1() { +} + +mod foo { + #[main] + fn main2() { // { dg-error ".E0137." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/multiple-plugin-registrars.rs b/gcc/testsuite/rust/rustc/ui/multiple-plugin-registrars.rs new file mode 100644 index 000000000000..45252055420c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/multiple-plugin-registrars.rs @@ -0,0 +1,13 @@ +// error-pattern: multiple plugin registration functions found + +#![feature(plugin_registrar)] + +// the registration function isn't typechecked yet +#[plugin_registrar] +pub fn one() {} + +#[plugin_registrar] +pub fn two() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/multiple-reprs.rs b/gcc/testsuite/rust/rustc/ui/multiple-reprs.rs new file mode 100644 index 000000000000..4111b2beb343 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/multiple-reprs.rs @@ -0,0 +1,83 @@ +// run-pass + +#![allow(dead_code)] + +use std::mem::{size_of, align_of}; +use std::os::raw::c_int; + +// The two enums that follow are designed so that bugs trigger layout optimization. +// Specifically, if either of the following reprs used here is not detected by the compiler, +// then the sizes will be wrong. + +#[repr(C, u8)] +enum E1 { + A(u8, u16, u8), + B(u8, u16, u8) +} + +#[repr(u8, C)] +enum E2 { + A(u8, u16, u8), + B(u8, u16, u8) +} + +// Check that repr(int) and repr(C) are in fact different from the above + +#[repr(u8)] +enum E3 { + A(u8, u16, u8), + B(u8, u16, u8) +} + +#[repr(u16)] +enum E4 { + A(u8, u16, u8), + B(u8, u16, u8) +} + +#[repr(u32)] +enum E5 { + A(u8, u16, u8), + B(u8, u16, u8) +} + +#[repr(u64)] +enum E6 { + A(u8, u16, u8), + B(u8, u16, u8) +} + +#[repr(C)] +enum E7 { + A(u8, u16, u8), + B(u8, u16, u8) +} + +// From pr 37429 + +#[repr(C,packed)] +pub struct p0f_api_query { + pub magic: u32, + pub addr_type: u8, + pub addr: [u8; 16], +} + +pub fn main() { + assert_eq!(size_of::(), 8); + assert_eq!(size_of::(), 8); + assert_eq!(size_of::(), 6); + assert_eq!(size_of::(), 8); + assert_eq!(size_of::(), align_size(10, align_of::())); + assert_eq!(size_of::(), align_size(14, align_of::())); + assert_eq!(size_of::(), align_size(6 + size_of::(), align_of::())); + assert_eq!(size_of::(), 21); +} + +fn align_size(size: usize, align: usize) -> usize { + if size % align != 0 { + size + (align - (size % align)) + } else { + size + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mut-function-arguments.rs b/gcc/testsuite/rust/rustc/ui/mut-function-arguments.rs new file mode 100644 index 000000000000..6e76a66ecaaa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mut-function-arguments.rs @@ -0,0 +1,22 @@ +// run-pass + +#![feature(box_syntax)] + +fn f(mut y: Box) { + *y = 5; + assert_eq!(*y, 5); +} + +fn g() { + let frob = |mut q: Box| { *q = 2; assert_eq!(*q, 2); }; + let w = box 37; + frob(w); + +} + +pub fn main() { + let z = box 17; + f(z); + g(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mut-vstore-expr.rs b/gcc/testsuite/rust/rustc/ui/mut-vstore-expr.rs new file mode 100644 index 000000000000..c4dfad089491 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mut-vstore-expr.rs @@ -0,0 +1,7 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + let _x: &mut [isize] = &mut [ 1, 2, 3 ]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/mut/mut-cant-alias.rs b/gcc/testsuite/rust/rustc/ui/mut/mut-cant-alias.rs new file mode 100644 index 000000000000..a55b713a84c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mut/mut-cant-alias.rs @@ -0,0 +1,15 @@ +use std::cell::RefCell; + + + +fn main() { + let m = RefCell::new(0); + let mut b = m.borrow_mut(); + let b1 = &mut *b; + let b2 = &mut *b; // { dg-error ".E0499." "" { target *-*-* } } + b1.use_mut(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/mut/mut-cross-borrowing.rs b/gcc/testsuite/rust/rustc/ui/mut/mut-cross-borrowing.rs new file mode 100644 index 000000000000..d02841a12c55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mut/mut-cross-borrowing.rs @@ -0,0 +1,9 @@ +#![feature(box_syntax)] + +fn f(_: &mut isize) {} + +fn main() { + let mut x: Box<_> = box 3; + f(x) // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mut/mut-pattern-internal-mutability.rs b/gcc/testsuite/rust/rustc/ui/mut/mut-pattern-internal-mutability.rs new file mode 100644 index 000000000000..3f00bf2b54ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mut/mut-pattern-internal-mutability.rs @@ -0,0 +1,16 @@ +fn main() { + let foo = &mut 1; + + let &mut x = foo; + x += 1; // { dg-error ".E0384." "" { target *-*-* } } + + // explicitly mut-ify internals + let &mut mut x = foo; + x += 1; + + // check borrowing is detected successfully + let &mut ref x = foo; + *foo += 1; // { dg-error ".E0506." "" { target *-*-* } } + drop(x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mut/mut-pattern-mismatched.rs b/gcc/testsuite/rust/rustc/ui/mut/mut-pattern-mismatched.rs new file mode 100644 index 000000000000..9b0ada847421 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mut/mut-pattern-mismatched.rs @@ -0,0 +1,21 @@ +fn main() { + let foo = &mut 1; + + // (separate lines to ensure the spans are accurate) + + let &_ // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } + = foo; + let &mut _ = foo; + + let bar = &1; + let &_ = bar; + let &mut _ // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } + = bar; +} + diff --git a/gcc/testsuite/rust/rustc/ui/mut/mut-ref.rs b/gcc/testsuite/rust/rustc/ui/mut/mut-ref.rs new file mode 100644 index 000000000000..1bd9a283a6ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mut/mut-ref.rs @@ -0,0 +1,5 @@ +fn main() { + let mut ref x = 10; // { dg-error "" "" { target *-*-* } } + let ref mut y = 11; +} + diff --git a/gcc/testsuite/rust/rustc/ui/mut/mut-suggestion.rs b/gcc/testsuite/rust/rustc/ui/mut/mut-suggestion.rs new file mode 100644 index 000000000000..5d6377126486 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mut/mut-suggestion.rs @@ -0,0 +1,23 @@ +#[derive(Copy, Clone)] +struct S; + +impl S { + fn mutate(&mut self) { + } +} + +fn func(arg: S) { +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + arg.mutate(); +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + +fn main() { + let local = S; +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + local.mutate(); +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mut/mutable-class-fields-2.rs b/gcc/testsuite/rust/rustc/ui/mut/mutable-class-fields-2.rs new file mode 100644 index 000000000000..f720e0f0906a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mut/mutable-class-fields-2.rs @@ -0,0 +1,25 @@ +struct Cat { + meows : usize, + + how_hungry : isize, +} + +impl Cat { + pub fn eat(&self) { + self.how_hungry -= 5; // { dg-error ".E0594." "" { target *-*-* } } + } + +} + +fn cat(in_x : usize, in_y : isize) -> Cat { + Cat { + meows: in_x, + how_hungry: in_y + } +} + +fn main() { + let nyan : Cat = cat(52, 99); + nyan.eat(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/mut/mutable-class-fields.rs b/gcc/testsuite/rust/rustc/ui/mut/mutable-class-fields.rs new file mode 100644 index 000000000000..113f97ccfb36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mut/mutable-class-fields.rs @@ -0,0 +1,17 @@ +struct Cat { + meows : usize, + how_hungry : isize, +} + +fn cat(in_x : usize, in_y : isize) -> Cat { + Cat { + meows: in_x, + how_hungry: in_y + } +} + +fn main() { + let nyan : Cat = cat(52, 99); + nyan.how_hungry = 0; // { dg-error ".E0594." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mut/mutable-enum-indirect.rs b/gcc/testsuite/rust/rustc/ui/mut/mutable-enum-indirect.rs new file mode 100644 index 000000000000..f5d6970bfc81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mut/mutable-enum-indirect.rs @@ -0,0 +1,20 @@ +// Tests that an `&` pointer to something inherently mutable is itself +// to be considered mutable. + +#![feature(negative_impls)] + +use std::marker::Sync; + +struct NoSync; +impl !Sync for NoSync {} + +enum Foo { A(NoSync) } + +fn bar(_: T) {} + +fn main() { + let x = Foo::A(NoSync); + bar(&x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mut/no-mut-lint-for-desugared-mut.rs b/gcc/testsuite/rust/rustc/ui/mut/no-mut-lint-for-desugared-mut.rs new file mode 100644 index 000000000000..b68ca0d9b9b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mut/no-mut-lint-for-desugared-mut.rs @@ -0,0 +1,9 @@ +// run-pass + +#![deny(unused_mut)] +#![allow(unreachable_code)] + +fn main() { + for _ in { return (); 0..3 } {} // ok +} + diff --git a/gcc/testsuite/rust/rustc/ui/mutexguard-sync.rs b/gcc/testsuite/rust/rustc/ui/mutexguard-sync.rs new file mode 100644 index 000000000000..74eaf697ecf5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mutexguard-sync.rs @@ -0,0 +1,14 @@ +// MutexGuard> must not be Sync, that would be unsound. +use std::sync::Mutex; +use std::cell::Cell; + +fn test_sync(_t: T) {} + +fn main() +{ + let m = Mutex::new(Cell::new(0i32)); + let guard = m.lock().unwrap(); + test_sync(guard); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/mutual-recursion-group.rs b/gcc/testsuite/rust/rustc/ui/mutual-recursion-group.rs new file mode 100644 index 000000000000..802a48972bf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/mutual-recursion-group.rs @@ -0,0 +1,17 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] + +// pretty-expanded FIXME #23616 + +enum colour { red, green, blue, } + +enum tree { children(Box), leaf(colour), } + +enum list { cons(Box, Box), nil, } + +enum small_list { kons(isize, Box), neel, } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/namespace/auxiliary/namespace-mix.rs b/gcc/testsuite/rust/rustc/ui/namespace/auxiliary/namespace-mix.rs new file mode 100644 index 000000000000..8c83fbee9503 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/namespace/auxiliary/namespace-mix.rs @@ -0,0 +1,67 @@ +pub mod c { + pub struct S {} + pub struct TS(); + pub struct US; + pub enum E { + V {}, + TV(), + UV, + } + + pub struct Item; +} + +pub mod xm1 { + pub use ::c::*; + pub type S = ::c::Item; +} +pub mod xm2 { + pub use ::c::*; + pub const S: ::c::Item = ::c::Item; +} + +pub mod xm3 { + pub use ::c::*; + pub type TS = ::c::Item; +} +pub mod xm4 { + pub use ::c::*; + pub const TS: ::c::Item = ::c::Item; +} + +pub mod xm5 { + pub use ::c::*; + pub type US = ::c::Item; +} +pub mod xm6 { + pub use ::c::*; + pub const US: ::c::Item = ::c::Item; +} + +pub mod xm7 { + pub use ::c::E::*; + pub type V = ::c::Item; +} +pub mod xm8 { + pub use ::c::E::*; + pub const V: ::c::Item = ::c::Item; +} + +pub mod xm9 { + pub use ::c::E::*; + pub type TV = ::c::Item; +} +pub mod xmA { + pub use ::c::E::*; + pub const TV: ::c::Item = ::c::Item; +} + +pub mod xmB { + pub use ::c::E::*; + pub type UV = ::c::Item; +} +pub mod xmC { + pub use ::c::E::*; + pub const UV: ::c::Item = ::c::Item; +} + diff --git a/gcc/testsuite/rust/rustc/ui/namespace/auxiliary/namespaced_enums.rs b/gcc/testsuite/rust/rustc/ui/namespace/auxiliary/namespaced_enums.rs new file mode 100644 index 000000000000..dcd0b95974b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/namespace/auxiliary/namespaced_enums.rs @@ -0,0 +1,11 @@ +pub enum Foo { + A, + B(isize), + C { a: isize }, +} + +impl Foo { + pub fn foo() {} + pub fn bar(&self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/namespace/namespace-mix.rs b/gcc/testsuite/rust/rustc/ui/namespace/namespace-mix.rs new file mode 100644 index 000000000000..c1bf0749f57c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/namespace/namespace-mix.rs @@ -0,0 +1,156 @@ +// aux-build:namespace-mix.rs + +extern crate namespace_mix; +use namespace_mix::*; + +mod c { + pub struct S {} + pub struct TS(); + pub struct US; + pub enum E { + V {}, + TV(), + UV, + } + + pub struct Item; +} + +// Use something emitting the type argument name, e.g., unsatisfied bound. +trait Impossible {} +fn check(_: T) {} + +mod m1 { + pub use ::c::*; + pub type S = ::c::Item; +} +mod m2 { + pub use ::c::*; + pub const S: ::c::Item = ::c::Item; +} + +fn f12() { + check(m1::S{}); // { dg-error ".E0277." "" { target *-*-* } } + check(m1::S); // { dg-error ".E0423." "" { target *-*-* } } + check(m2::S{}); // { dg-error ".E0277." "" { target *-*-* } } + check(m2::S); // { dg-error ".E0277." "" { target *-*-* } } +} +fn xf12() { + check(xm1::S{}); // { dg-error ".E0277." "" { target *-*-* } } + check(xm1::S); // { dg-error ".E0423." "" { target *-*-* } } + check(xm2::S{}); // { dg-error ".E0277." "" { target *-*-* } } + check(xm2::S); // { dg-error ".E0277." "" { target *-*-* } } +} + +mod m3 { + pub use ::c::*; + pub type TS = ::c::Item; +} +mod m4 { + pub use ::c::*; + pub const TS: ::c::Item = ::c::Item; +} + +fn f34() { + check(m3::TS{}); // { dg-error ".E0277." "" { target *-*-* } } + check(m3::TS); // { dg-error ".E0277." "" { target *-*-* } } + check(m4::TS{}); // { dg-error ".E0277." "" { target *-*-* } } + check(m4::TS); // { dg-error ".E0277." "" { target *-*-* } } +} +fn xf34() { + check(xm3::TS{}); // { dg-error ".E0277." "" { target *-*-* } } + check(xm3::TS); // { dg-error ".E0277." "" { target *-*-* } } + check(xm4::TS{}); // { dg-error ".E0277." "" { target *-*-* } } + check(xm4::TS); // { dg-error ".E0277." "" { target *-*-* } } +} + +mod m5 { + pub use ::c::*; + pub type US = ::c::Item; +} +mod m6 { + pub use ::c::*; + pub const US: ::c::Item = ::c::Item; +} + +fn f56() { + check(m5::US{}); // { dg-error ".E0277." "" { target *-*-* } } + check(m5::US); // { dg-error ".E0277." "" { target *-*-* } } + check(m6::US{}); // { dg-error ".E0277." "" { target *-*-* } } + check(m6::US); // { dg-error ".E0277." "" { target *-*-* } } +} +fn xf56() { + check(xm5::US{}); // { dg-error ".E0277." "" { target *-*-* } } + check(xm5::US); // { dg-error ".E0277." "" { target *-*-* } } + check(xm6::US{}); // { dg-error ".E0277." "" { target *-*-* } } + check(xm6::US); // { dg-error ".E0277." "" { target *-*-* } } +} + +mod m7 { + pub use ::c::E::*; + pub type V = ::c::Item; +} +mod m8 { + pub use ::c::E::*; + pub const V: ::c::Item = ::c::Item; +} + +fn f78() { + check(m7::V{}); // { dg-error ".E0277." "" { target *-*-* } } + check(m7::V); // { dg-error ".E0423." "" { target *-*-* } } + check(m8::V{}); // { dg-error ".E0277." "" { target *-*-* } } + check(m8::V); // { dg-error ".E0277." "" { target *-*-* } } +} +fn xf78() { + check(xm7::V{}); // { dg-error ".E0277." "" { target *-*-* } } + check(xm7::V); // { dg-error ".E0423." "" { target *-*-* } } + check(xm8::V{}); // { dg-error ".E0277." "" { target *-*-* } } + check(xm8::V); // { dg-error ".E0277." "" { target *-*-* } } +} + +mod m9 { + pub use ::c::E::*; + pub type TV = ::c::Item; +} +mod mA { + pub use ::c::E::*; + pub const TV: ::c::Item = ::c::Item; +} + +fn f9A() { + check(m9::TV{}); // { dg-error ".E0277." "" { target *-*-* } } + check(m9::TV); // { dg-error ".E0277." "" { target *-*-* } } + check(mA::TV{}); // { dg-error ".E0277." "" { target *-*-* } } + check(mA::TV); // { dg-error ".E0277." "" { target *-*-* } } +} +fn xf9A() { + check(xm9::TV{}); // { dg-error ".E0277." "" { target *-*-* } } + check(xm9::TV); // { dg-error ".E0277." "" { target *-*-* } } + check(xmA::TV{}); // { dg-error ".E0277." "" { target *-*-* } } + check(xmA::TV); // { dg-error ".E0277." "" { target *-*-* } } +} + +mod mB { + pub use ::c::E::*; + pub type UV = ::c::Item; +} +mod mC { + pub use ::c::E::*; + pub const UV: ::c::Item = ::c::Item; +} + +fn fBC() { + check(mB::UV{}); // { dg-error ".E0277." "" { target *-*-* } } + check(mB::UV); // { dg-error ".E0277." "" { target *-*-* } } + check(mC::UV{}); // { dg-error ".E0277." "" { target *-*-* } } + check(mC::UV); // { dg-error ".E0277." "" { target *-*-* } } +} +fn xfBC() { + check(xmB::UV{}); // { dg-error ".E0277." "" { target *-*-* } } + check(xmB::UV); // { dg-error ".E0277." "" { target *-*-* } } + check(xmC::UV{}); // { dg-error ".E0277." "" { target *-*-* } } + check(xmC::UV); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.rs b/gcc/testsuite/rust/rustc/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.rs new file mode 100644 index 000000000000..c9c5348cb9bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/namespace/namespaced-enum-glob-import-no-impls-xcrate.rs @@ -0,0 +1,16 @@ +// aux-build:namespaced_enums.rs +extern crate namespaced_enums; + +mod m { + pub use namespaced_enums::Foo::*; +} + +pub fn main() { + use namespaced_enums::Foo::*; + + foo(); // { dg-error ".E0425." "" { target *-*-* } } + m::foo(); // { dg-error ".E0425." "" { target *-*-* } } + bar(); // { dg-error ".E0425." "" { target *-*-* } } + m::bar(); // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/namespace/namespaced-enum-glob-import-no-impls.rs b/gcc/testsuite/rust/rustc/ui/namespace/namespaced-enum-glob-import-no-impls.rs new file mode 100644 index 000000000000..358b2782d419 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/namespace/namespaced-enum-glob-import-no-impls.rs @@ -0,0 +1,26 @@ +mod m2 { + pub enum Foo { + A, + B(isize), + C { a: isize }, + } + + impl Foo { + pub fn foo() {} + pub fn bar(&self) {} + } +} + +mod m { + pub use m2::Foo::*; +} + +pub fn main() { + use m2::Foo::*; + + foo(); // { dg-error ".E0425." "" { target *-*-* } } + m::foo(); // { dg-error ".E0425." "" { target *-*-* } } + bar(); // { dg-error ".E0425." "" { target *-*-* } } + m::bar(); // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/native-print-no-runtime.rs b/gcc/testsuite/rust/rustc/ui/native-print-no-runtime.rs new file mode 100644 index 000000000000..ecfe635a5ce0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/native-print-no-runtime.rs @@ -0,0 +1,10 @@ +// run-pass + +#![feature(start)] + +#[start] +pub fn main(_: isize, _: *const *const u8) -> isize { + println!("hello"); + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/negative.rs b/gcc/testsuite/rust/rustc/ui/negative.rs new file mode 100644 index 000000000000..d60d4ba87bd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/negative.rs @@ -0,0 +1,9 @@ +// run-pass + +pub fn main() { + match -5 { + -5 => {} + _ => { panic!() } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nested-block-comment.rs b/gcc/testsuite/rust/rustc/ui/nested-block-comment.rs new file mode 100644 index 000000000000..fba54e3f6599 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nested-block-comment.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +/* This test checks that nested comments are supported + + /* + This should not panic + */ +*/ + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nested-cfg-attrs.rs b/gcc/testsuite/rust/rustc/ui/nested-cfg-attrs.rs new file mode 100644 index 000000000000..2b496d70c70b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nested-cfg-attrs.rs @@ -0,0 +1,5 @@ +#[cfg_attr(all(), cfg_attr(all(), cfg(foo)))] +fn f() {} + +fn main() { f() } // { dg-error ".E0425." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/nested-class.rs b/gcc/testsuite/rust/rustc/ui/nested-class.rs new file mode 100644 index 000000000000..f986d9a0a0ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nested-class.rs @@ -0,0 +1,26 @@ +// run-pass + +#![allow(non_camel_case_types)] + +pub fn main() { + struct b { + i: isize, + } + + impl b { + fn do_stuff(&self) -> isize { return 37; } + } + + fn b(i:isize) -> b { + b { + i: i + } + } + + // fn b(x:isize) -> isize { panic!(); } + + let z = b(42); + assert_eq!(z.i, 42); + assert_eq!(z.do_stuff(), 37); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nested-function-names-issue-8587.rs b/gcc/testsuite/rust/rustc/ui/nested-function-names-issue-8587.rs new file mode 100644 index 000000000000..6b851080672e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nested-function-names-issue-8587.rs @@ -0,0 +1,43 @@ +// run-pass +// Make sure nested functions are separate, even if they have +// equal name. +// +// Issue #8587 + + +pub struct X; + +impl X { + fn f(&self) -> isize { + #[inline(never)] + fn inner() -> isize { + 0 + } + inner() + } + + fn g(&self) -> isize { + #[inline(never)] + fn inner_2() -> isize { + 1 + } + inner_2() + } + + fn h(&self) -> isize { + #[inline(never)] + fn inner() -> isize { + 2 + } + inner() + } +} + +pub fn main() { + let n = X; + assert_eq!(n.f(), 0); + assert_eq!(n.g(), 1); + // This test `h` used to fail. + assert_eq!(n.h(), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nested-ty-params.rs b/gcc/testsuite/rust/rustc/ui/nested-ty-params.rs new file mode 100644 index 000000000000..520ae21dbd4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nested-ty-params.rs @@ -0,0 +1,9 @@ +// error-pattern:can't use generic parameters from outer function +fn hd(v: Vec ) -> U { + fn hd1(w: [U]) -> U { return w[0]; } + + return hd1(v); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nested_impl_trait.rs b/gcc/testsuite/rust/rustc/ui/nested_impl_trait.rs new file mode 100644 index 000000000000..689223f9fe42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nested_impl_trait.rs @@ -0,0 +1,31 @@ +use std::fmt::Debug; + +fn fine(x: impl Into) -> impl Into { x } + +fn bad_in_ret_position(x: impl Into) -> impl Into { x } +// { dg-error ".E0666." "" { target *-*-* } .-1 } + +fn bad_in_fn_syntax(x: fn() -> impl Into) {} +// { dg-error ".E0562." "" { target *-*-* } .-1 } +// { dg-error ".E0562." "" { target *-*-* } .-2 } + +fn bad_in_arg_position(_: impl Into) { } +// { dg-error ".E0666." "" { target *-*-* } .-1 } + +struct X; +impl X { + fn bad(x: impl Into) -> impl Into { x } +// { dg-error ".E0666." "" { target *-*-* } .-1 } +} + +fn allowed_in_assoc_type() -> impl Iterator { + vec![|| println!("woot")].into_iter() +} + +fn allowed_in_ret_type() -> impl Fn() -> impl Into { +// { dg-error ".E0562." "" { target *-*-* } .-1 } + || 5 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nested_item_main.rs b/gcc/testsuite/rust/rustc/ui/nested_item_main.rs new file mode 100644 index 000000000000..0a20e4ce6c47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nested_item_main.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:nested_item.rs + + +extern crate nested_item; + +pub fn main() { + assert_eq!(2, nested_item::foo::<()>()); + assert_eq!(2, nested_item::foo::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/adjust_never.rs b/gcc/testsuite/rust/rustc/ui/never_type/adjust_never.rs new file mode 100644 index 000000000000..babe5baac49a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/adjust_never.rs @@ -0,0 +1,11 @@ +// Test that a variable of type ! can coerce to another type. + +// check-pass + +#![feature(never_type)] + +fn main() { + let x: ! = panic!(); + let y: u32 = x; +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/auto-traits.rs b/gcc/testsuite/rust/rustc/ui/never_type/auto-traits.rs new file mode 100644 index 000000000000..59472b45bd56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/auto-traits.rs @@ -0,0 +1,19 @@ +// check-pass + +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] +#![feature(never_type)] + +fn main() { + enum Void {} + + auto trait Auto {} + fn assert_auto() {} + assert_auto::(); + assert_auto::(); + + fn assert_send() {} + assert_send::(); + assert_send::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/call-fn-never-arg-wrong-type.rs b/gcc/testsuite/rust/rustc/ui/never_type/call-fn-never-arg-wrong-type.rs new file mode 100644 index 000000000000..03bad73f9b19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/call-fn-never-arg-wrong-type.rs @@ -0,0 +1,12 @@ +// Test that we can't pass other types for ! + +#![feature(never_type)] + +fn foo(x: !) -> ! { + x +} + +fn main() { + foo("wow"); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/call-fn-never-arg.rs b/gcc/testsuite/rust/rustc/ui/never_type/call-fn-never-arg.rs new file mode 100644 index 000000000000..8b54341d8067 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/call-fn-never-arg.rs @@ -0,0 +1,15 @@ +// Test that we can use a ! for an argument of type ! + +// check-pass + +#![feature(never_type)] +#![allow(unreachable_code)] + +fn foo(x: !) -> ! { + x +} + +fn main() { + foo(panic!("wowzers!")) +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/cast-never.rs b/gcc/testsuite/rust/rustc/ui/never_type/cast-never.rs new file mode 100644 index 000000000000..917f67e85d8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/cast-never.rs @@ -0,0 +1,11 @@ +// Test that we can explicitly cast ! to another type + +// check-pass + +#![feature(never_type)] + +fn main() { + let x: ! = panic!(); + let y: u32 = x as u32; +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/defaulted-never-note.rs b/gcc/testsuite/rust/rustc/ui/never_type/defaulted-never-note.rs new file mode 100644 index 000000000000..e1cbe9494702 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/defaulted-never-note.rs @@ -0,0 +1,35 @@ +// We need to opt into the `never_type_fallback` feature +// to trigger the requirement that this is testing. +#![feature(never_type, never_type_fallback)] + +#![allow(unused)] + +trait Deserialize: Sized { + fn deserialize() -> Result; +} + +impl Deserialize for () { + fn deserialize() -> Result<(), String> { + Ok(()) + } +} + +trait ImplementedForUnitButNotNever {} + +impl ImplementedForUnitButNotNever for () {} + +fn foo(_t: T) {} +// { dg-note "" "" { target *-*-* } .-1 } + +fn smeg() { + let _x = return; + foo(_x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-note ".E0277." "" { target *-*-* } .-2 } +// { dg-note ".E0277." "" { target *-*-* } .-3 } +} + +fn main() { + smeg(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/dispatch_from_dyn_zst.rs b/gcc/testsuite/rust/rustc/ui/never_type/dispatch_from_dyn_zst.rs new file mode 100644 index 000000000000..c421fda36896 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/dispatch_from_dyn_zst.rs @@ -0,0 +1,52 @@ +// run-pass + +#![feature(unsize, dispatch_from_dyn, never_type)] + +#![allow(dead_code)] + +use std::{ + ops::DispatchFromDyn, + marker::{Unsize, PhantomData}, +}; + +struct Zst; +struct NestedZst(PhantomData<()>, Zst); + + +struct WithUnit(Box, ()); +impl DispatchFromDyn> for WithUnit + where T: Unsize {} + +struct WithPhantom(Box, PhantomData<()>); +impl DispatchFromDyn> for WithPhantom + where T: Unsize {} + +struct WithNever(Box, !); +impl DispatchFromDyn> for WithNever + where T: Unsize {} + +struct WithZst(Box, Zst); +impl DispatchFromDyn> for WithZst + where T: Unsize {} + +struct WithNestedZst(Box, NestedZst); +impl DispatchFromDyn> for WithNestedZst + where T: Unsize {} + + +struct Generic(Box, A); +impl DispatchFromDyn> for Generic + where T: Unsize {} +impl DispatchFromDyn>> + for Generic> + where T: Unsize {} +impl DispatchFromDyn> for Generic + where T: Unsize {} +impl DispatchFromDyn> for Generic + where T: Unsize {} +impl DispatchFromDyn> for Generic + where T: Unsize {} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/diverging-fallback-control-flow.rs b/gcc/testsuite/rust/rustc/ui/never_type/diverging-fallback-control-flow.rs new file mode 100644 index 000000000000..e70b0eaf2665 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/diverging-fallback-control-flow.rs @@ -0,0 +1,103 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_assignments)] +#![allow(unused_variables)] +#![allow(unreachable_code)] + +// Test various cases where we permit an unconstrained variable +// to fallback based on control-flow. +// +// These represent current behavior, but are pretty dubious. I would +// like to revisit these and potentially change them. --nmatsakis + +#![feature(never_type, never_type_fallback)] + +trait BadDefault { + fn default() -> Self; +} + +impl BadDefault for u32 { + fn default() -> Self { + 0 + } +} + +impl BadDefault for ! { + fn default() -> ! { + panic!() + } +} + +fn assignment() { + let x; + + if true { + x = BadDefault::default(); + } else { + x = return; + } +} + +fn assignment_rev() { + let x; + + if true { + x = return; + } else { + x = BadDefault::default(); + } +} + +fn if_then_else() { + let _x = if true { + BadDefault::default() + } else { + return; + }; +} + +fn if_then_else_rev() { + let _x = if true { + return; + } else { + BadDefault::default() + }; +} + +fn match_arm() { + let _x = match Ok(BadDefault::default()) { + Ok(v) => v, + Err(()) => return, + }; +} + +fn match_arm_rev() { + let _x = match Ok(BadDefault::default()) { + Err(()) => return, + Ok(v) => v, + }; +} + +fn loop_break() { + let _x = loop { + if false { + break return; + } else { + break BadDefault::default(); + } + }; +} + +fn loop_break_rev() { + let _x = loop { + if false { + break return; + } else { + break BadDefault::default(); + } + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/feature-gate-never_type_fallback.rs b/gcc/testsuite/rust/rustc/ui/never_type/feature-gate-never_type_fallback.rs new file mode 100644 index 000000000000..0e6ab30883ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/feature-gate-never_type_fallback.rs @@ -0,0 +1,13 @@ +// This is a feature gate test for `never_type_fallback`. +// It works by using a scenario where the type fall backs to `()` rather than ´!` +// in the case where `#![feature(never_type_fallback)]` would change it to `!`. + +fn main() {} + +trait T {} + +fn should_ret_unit() -> impl T { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + panic!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/impl-for-never.rs b/gcc/testsuite/rust/rustc/ui/never_type/impl-for-never.rs new file mode 100644 index 000000000000..f9dad21a47c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/impl-for-never.rs @@ -0,0 +1,28 @@ +// run-pass + +#![feature(never_type)] + +// Test that we can call static methods on ! both directly and when it appears in a generic + +trait StringifyType { + fn stringify_type() -> &'static str; +} + +impl StringifyType for ! { + fn stringify_type() -> &'static str { + "!" + } +} + +fn maybe_stringify(opt: Option) -> &'static str { + match opt { + Some(_) => T::stringify_type(), + None => "none", + } +} + +fn main() { + println!("! is {}", ::stringify_type()); + println!("None is {}", maybe_stringify(None::)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/issue-13352.rs b/gcc/testsuite/rust/rustc/ui/never_type/issue-13352.rs new file mode 100644 index 000000000000..1149757bab43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/issue-13352.rs @@ -0,0 +1,12 @@ +// ignore-cloudabi no std::process + +fn foo(_: Box) {} + +fn main() { + foo(loop { + std::process::exit(0); + }); + 2_usize + (loop {}); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/issue-2149.rs b/gcc/testsuite/rust/rustc/ui/never_type/issue-2149.rs new file mode 100644 index 000000000000..f9e08345279d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/issue-2149.rs @@ -0,0 +1,16 @@ +trait VecMonad { + fn bind(&self, f: F) where F: FnMut(A) -> Vec; +} + +impl VecMonad for Vec { + fn bind(&self, mut f: F) where F: FnMut(A) -> Vec { + let mut r = panic!(); + for elt in self { r = r + f(*elt); } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } +} +fn main() { + ["hi"].bind(|x| [x] ); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/issue-44402.rs b/gcc/testsuite/rust/rustc/ui/never_type/issue-44402.rs new file mode 100644 index 000000000000..c6baa0d281af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/issue-44402.rs @@ -0,0 +1,34 @@ +// check-pass + +#![allow(dead_code)] +#![feature(never_type)] +#![feature(exhaustive_patterns)] + +// Regression test for inhabitedness check. The old +// cache used to cause us to incorrectly decide +// that `test_b` was invalid. + +struct Foo { + field1: !, + field2: Option<&'static Bar>, +} + +struct Bar { + field1: &'static Foo +} + +fn test_a() { + let x: Option = None; + match x { None => () } +} + +fn test_b() { + let x: Option = None; + match x { + Some(_) => (), + None => () + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/issue-51506.rs b/gcc/testsuite/rust/rustc/ui/never_type/issue-51506.rs new file mode 100644 index 000000000000..a8e881957aba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/issue-51506.rs @@ -0,0 +1,42 @@ +#![feature(never_type, specialization)] +#![allow(incomplete_features)] + +use std::iter::{self, Empty}; + +trait Trait { + type Out: Iterator; + + fn f(&self) -> Option; +} + +impl Trait for T { + default type Out = !; // { dg-error ".E0277." "" { target *-*-* } } + + default fn f(&self) -> Option { + None + } +} + +struct X; + +impl Trait for X { + type Out = Empty; + + fn f(&self) -> Option { + Some(iter::empty()) + } +} + +fn f(a: T) { + if let Some(iter) = a.f() { + println!("Some"); + for x in iter { + println!("x = {}", x); + } + } +} + +pub fn main() { + f(10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/never-assign-dead-code.rs b/gcc/testsuite/rust/rustc/ui/never_type/never-assign-dead-code.rs new file mode 100644 index 000000000000..26c377a7f9ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/never-assign-dead-code.rs @@ -0,0 +1,13 @@ +// Test that an assignment of type ! makes the rest of the block dead code. + +// check-pass + +#![feature(never_type)] +#![warn(unused)] + +fn main() { + let x: ! = panic!("aah"); // { dg-warning "" "" { target *-*-* } } + drop(x); // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/never-assign-wrong-type.rs b/gcc/testsuite/rust/rustc/ui/never_type/never-assign-wrong-type.rs new file mode 100644 index 000000000000..8ae4c3a3d919 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/never-assign-wrong-type.rs @@ -0,0 +1,9 @@ +// Test that we can't use another type in place of ! + +#![feature(never_type)] +#![deny(warnings)] + +fn main() { + let x: ! = "hello"; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/never-associated-type.rs b/gcc/testsuite/rust/rustc/ui/never_type/never-associated-type.rs new file mode 100644 index 000000000000..68117d6cfeb8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/never-associated-type.rs @@ -0,0 +1,24 @@ +// Test that we can use ! as an associated type. + +// check-pass + +#![feature(never_type)] + +trait Foo { + type Wow; + + fn smeg(&self) -> Self::Wow; +} + +struct Blah; +impl Foo for Blah { + type Wow = !; + fn smeg(&self) -> ! { + panic!("kapow!"); + } +} + +fn main() { + Blah.smeg(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/never-from-impl-is-reserved.rs b/gcc/testsuite/rust/rustc/ui/never_type/never-from-impl-is-reserved.rs new file mode 100644 index 000000000000..c5ba9f58ad2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/never-from-impl-is-reserved.rs @@ -0,0 +1,13 @@ +// check that the `for T: From` impl is reserved + +#![feature(never_type)] + +pub struct MyFoo; +pub trait MyTrait {} + +impl MyTrait for MyFoo {} +// This will conflict with the first impl if we impl `for T: From`. +impl MyTrait for T where T: From {} // { dg-error ".E0119." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/never-result.rs b/gcc/testsuite/rust/rustc/ui/never_type/never-result.rs new file mode 100644 index 000000000000..7ef947c26339 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/never-result.rs @@ -0,0 +1,22 @@ +// run-pass + +#![allow(unused_variables)] +#![allow(unreachable_code)] + +// Test that we can extract a ! through pattern matching then use it as several different types. + +#![feature(never_type)] + +fn main() { + let x: Result = Ok(123); + match x { + Ok(z) => (), + Err(y) => { + let q: u32 = y; + let w: i32 = y; + let e: String = y; + y + }, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/never-type-arg.rs b/gcc/testsuite/rust/rustc/ui/never_type/never-type-arg.rs new file mode 100644 index 000000000000..c1f366cf8d3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/never-type-arg.rs @@ -0,0 +1,18 @@ +// Test that we can use ! as an argument to a trait impl. + +// check-pass + +#![feature(never_type)] + +struct Wub; + +impl PartialEq for Wub { + fn eq(&self, other: &!) -> bool { + *other + } +} + +fn main() { + let _ = Wub == panic!("oh no!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/never-type-rvalues.rs b/gcc/testsuite/rust/rustc/ui/never_type/never-type-rvalues.rs new file mode 100644 index 000000000000..3190a8bd0454 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/never-type-rvalues.rs @@ -0,0 +1,39 @@ +// run-pass + +#![feature(never_type)] +#![allow(dead_code)] +#![allow(path_statements)] +#![allow(unreachable_patterns)] + +fn never_direct(x: !) { + x; +} + +fn never_ref_pat(ref x: !) { + *x; +} + +fn never_ref(x: &!) { + let &y = x; + y; +} + +fn never_pointer(x: *const !) { + unsafe { + *x; + } +} + +fn never_slice(x: &[!]) { + x[0]; +} + +fn never_match(x: Result<(), !>) { + match x { + Ok(_) => {}, + Err(_) => {}, + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/never-value-fallback-issue-66757.rs b/gcc/testsuite/rust/rustc/ui/never_type/never-value-fallback-issue-66757.rs new file mode 100644 index 000000000000..653e44e90298 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/never-value-fallback-issue-66757.rs @@ -0,0 +1,30 @@ +// Regression test for #66757 +// +// Test than when you have a `!` value (e.g., the local variable +// never) and an uninferred variable (here the argument to `From`) it +// doesn't fallback to `()` but rather `!`. +// +// run-pass + +#![feature(never_type)] + +// FIXME(#67225) -- this should be true even without the fallback gate. +#![feature(never_type_fallback)] + +struct E; + +impl From for E { + fn from(_: !) -> E { + E + } +} + +#[allow(unreachable_code)] +#[allow(dead_code)] +fn foo(never: !) { + >::from(never); // Ok + >::from(never); // Inference fails here +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/never_coercions.rs b/gcc/testsuite/rust/rustc/ui/never_type/never_coercions.rs new file mode 100644 index 000000000000..863e819527fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/never_coercions.rs @@ -0,0 +1,13 @@ +// run-pass +// Test that having something of type ! doesn't screw up type-checking and that it coerces to the +// LUB type of the other match arms. + +fn main() { + let v: Vec = Vec::new(); + match 0u32 { + 0 => &v, + 1 => return, + _ => &v[..], + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/never_transmute_never.rs b/gcc/testsuite/rust/rustc/ui/never_type/never_transmute_never.rs new file mode 100644 index 000000000000..435b8e2b92b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/never_transmute_never.rs @@ -0,0 +1,24 @@ +// check-pass + +#![crate_type="lib"] + +#![feature(never_type)] +#![allow(dead_code)] +#![allow(unreachable_code)] +#![allow(unused_variables)] + +struct Foo; + +pub fn f(x: !) -> ! { + x +} + +pub fn ub() { + // This is completely undefined behaviour, + // but we still want to make sure it compiles. + let x: ! = unsafe { + std::mem::transmute::(Foo) + }; + f(x) +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/return-never-coerce.rs b/gcc/testsuite/rust/rustc/ui/never_type/return-never-coerce.rs new file mode 100644 index 000000000000..08e56b11e046 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/return-never-coerce.rs @@ -0,0 +1,19 @@ +// Test that ! coerces to other types. + +// run-fail +// error-pattern:aah! +// ignore-emscripten no processes + +fn call_another_fn T>(f: F) -> T { + f() +} + +fn wub() -> ! { + panic!("aah!"); +} + +fn main() { + let x: i32 = call_another_fn(wub); + let y: u32 = wub(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/never_type/try_from.rs b/gcc/testsuite/rust/rustc/ui/never_type/try_from.rs new file mode 100644 index 000000000000..1b5d9d308ac2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/never_type/try_from.rs @@ -0,0 +1,38 @@ +// run-pass +// This test relies on `TryFrom` being blanket impl for all `T: Into` +// and `TryInto` being blanket impl for all `U: TryFrom` + +// This test was added to show the motivation for doing this +// over `TryFrom` being blanket impl for all `T: From` + +#![feature(never_type)] + +use std::convert::{TryInto, Infallible}; + +struct Foo { + t: T, +} + +// This fails to compile due to coherence restrictions +// as of Rust version 1.32.x, therefore it could not be used +// instead of the `Into` version of the impl, and serves as +// motivation for a blanket impl for all `T: Into`, instead +// of a blanket impl for all `T: From` +/* +impl From> for Box { + fn from(foo: Foo) -> Box { + Box::new(foo.t) + } +} +*/ + +impl Into> for Foo { + fn into(self) -> Vec { + vec![self.t] + } +} + +pub fn main() { + let _: Result, Infallible> = Foo { t: 10 }.try_into(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/new-box-syntax.rs b/gcc/testsuite/rust/rustc/ui/new-box-syntax.rs new file mode 100644 index 000000000000..77369bfc59f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/new-box-syntax.rs @@ -0,0 +1,29 @@ +// run-pass +// pretty-expanded FIXME #23616 + +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +#![allow(dead_code, unused_variables)] +#![feature(box_syntax)] + +// Tests that the new `box` syntax works with unique pointers. + +use std::boxed::Box; + +struct Structure { + x: isize, + y: isize, +} + +pub fn main() { + let y: Box = box 2; + let b: Box = box (1 + 2); + let c = box (3 + 4); + + let s: Box = box Structure { + x: 3, + y: 4, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/new-box.rs b/gcc/testsuite/rust/rustc/ui/new-box.rs new file mode 100644 index 000000000000..70b9ea7e39e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/new-box.rs @@ -0,0 +1,33 @@ +// run-pass + +#![feature(box_syntax)] + +fn f(x: Box) { + let y: &isize = &*x; + println!("{}", *x); + println!("{}", *y); +} + +trait Trait { + fn printme(&self); +} + +struct Struct; + +impl Trait for Struct { + fn printme(&self) { + println!("hello world!"); + } +} + +fn g(x: Box) { + x.printme(); + let y: &dyn Trait = &*x; + y.printme(); +} + +fn main() { + f(box 1234); + g(box Struct as Box); +} + diff --git a/gcc/testsuite/rust/rustc/ui/new-impl-syntax.rs b/gcc/testsuite/rust/rustc/ui/new-impl-syntax.rs new file mode 100644 index 000000000000..ce7a18be8c7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/new-impl-syntax.rs @@ -0,0 +1,30 @@ +// run-pass + +use std::fmt; + +struct Thingy { + x: isize, + y: isize +} + +impl fmt::Debug for Thingy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{{ x: {:?}, y: {:?} }}", self.x, self.y) + } +} + +struct PolymorphicThingy { + x: T +} + +impl fmt::Debug for PolymorphicThingy { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.x) + } +} + +pub fn main() { + println!("{:?}", Thingy { x: 1, y: 2 }); + println!("{:?}", PolymorphicThingy { x: Thingy { x: 1, y: 2 } }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/new-import-syntax.rs b/gcc/testsuite/rust/rustc/ui/new-import-syntax.rs new file mode 100644 index 000000000000..371454dc25bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/new-import-syntax.rs @@ -0,0 +1,6 @@ +// run-pass + +pub fn main() { + println!("Hello world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/new-style-constants.rs b/gcc/testsuite/rust/rustc/ui/new-style-constants.rs new file mode 100644 index 000000000000..bc0e1471e35e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/new-style-constants.rs @@ -0,0 +1,8 @@ +// run-pass + +static FOO: isize = 3; + +pub fn main() { + println!("{}", FOO); +} + diff --git a/gcc/testsuite/rust/rustc/ui/new-unicode-escapes.rs b/gcc/testsuite/rust/rustc/ui/new-unicode-escapes.rs new file mode 100644 index 000000000000..007e7c69320f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/new-unicode-escapes.rs @@ -0,0 +1,15 @@ +// run-pass + +pub fn main() { + let s = "\u{2603}"; + assert_eq!(s, "☃"); + + let s = "\u{2a10}\u{2A01}\u{2Aa0}"; + assert_eq!(s, "⨐⨁⪠"); + + let s = "\\{20}"; + let mut correct_s = String::from("\\"); + correct_s.push_str("{20}"); + assert_eq!(s, correct_s); +} + diff --git a/gcc/testsuite/rust/rustc/ui/new-unsafe-pointers.rs b/gcc/testsuite/rust/rustc/ui/new-unsafe-pointers.rs new file mode 100644 index 000000000000..b91b2db81ec2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/new-unsafe-pointers.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + let _a: *const isize = 3 as *const isize; + let _a: *mut isize = 3 as *mut isize; +} + diff --git a/gcc/testsuite/rust/rustc/ui/newlambdas-ret-infer.rs b/gcc/testsuite/rust/rustc/ui/newlambdas-ret-infer.rs new file mode 100644 index 000000000000..94a2609638eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/newlambdas-ret-infer.rs @@ -0,0 +1,13 @@ +// run-pass + +#![allow(dead_code)] +// Test that the lambda kind is inferred correctly as a return +// expression + +// pretty-expanded FIXME #23616 + +fn unique() -> Box { return Box::new(|| ()); } + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/newlambdas-ret-infer2.rs b/gcc/testsuite/rust/rustc/ui/newlambdas-ret-infer2.rs new file mode 100644 index 000000000000..b0470078f3f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/newlambdas-ret-infer2.rs @@ -0,0 +1,13 @@ +// run-pass + +#![allow(dead_code)] +// Test that the lambda kind is inferred correctly as a return +// expression + +// pretty-expanded FIXME #23616 + +fn unique() -> Box { Box::new(|| ()) } + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/newlambdas.rs b/gcc/testsuite/rust/rustc/ui/newlambdas.rs new file mode 100644 index 000000000000..62a724cd33e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/newlambdas.rs @@ -0,0 +1,15 @@ +// run-pass +// Tests for the new |args| expr lambda syntax + + +fn f(i: isize, f: F) -> isize where F: FnOnce(isize) -> isize { f(i) } + +fn g(_g: G) where G: FnOnce() { } + +pub fn main() { + assert_eq!(f(10, |a| a), 10); + g(||()); + assert_eq!(f(10, |a| a), 10); + g(||{}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/newtype-polymorphic.rs b/gcc/testsuite/rust/rustc/ui/newtype-polymorphic.rs new file mode 100644 index 000000000000..76bd0c2467e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/newtype-polymorphic.rs @@ -0,0 +1,28 @@ +// run-pass + +#![allow(non_camel_case_types)] + + +#[derive(Clone)] +struct myvec(Vec ); + +fn myvec_deref(mv: myvec) -> Vec { + let myvec(v) = mv; + return v.clone(); +} + +fn myvec_elt(mv: myvec) -> X { + let myvec(v) = mv; + return v.into_iter().next().unwrap(); +} + +pub fn main() { + let mv = myvec(vec![1, 2, 3]); + let mv_clone = mv.clone(); + let mv_clone = myvec_deref(mv_clone); + assert_eq!(mv_clone[1], 2); + assert_eq!(myvec_elt(mv.clone()), 1); + let myvec(v) = mv; + assert_eq!(v[2], 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/newtype-temporary.rs b/gcc/testsuite/rust/rustc/ui/newtype-temporary.rs new file mode 100644 index 000000000000..e8ee5b1cdb80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/newtype-temporary.rs @@ -0,0 +1,13 @@ +// run-pass + +#[derive(PartialEq, Debug)] +struct Foo(usize); + +fn foo() -> Foo { + Foo(42) +} + +pub fn main() { + assert_eq!(foo(), Foo(42)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/newtype.rs b/gcc/testsuite/rust/rustc/ui/newtype.rs new file mode 100644 index 000000000000..3e1e3e749cac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/newtype.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(non_camel_case_types)] +#[derive(Copy, Clone)] +struct mytype(Mytype); + +#[derive(Copy, Clone)] +struct Mytype { + compute: fn(mytype) -> isize, + val: isize, +} + +fn compute(i: mytype) -> isize { + let mytype(m) = i; + return m.val + 20; +} + +pub fn main() { + let myval = mytype(Mytype{compute: compute, val: 30}); + println!("{}", compute(myval)); + let mytype(m) = myval; + assert_eq!((m.compute)(myval), 50); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nil-decl-in-foreign.rs b/gcc/testsuite/rust/rustc/ui/nil-decl-in-foreign.rs new file mode 100644 index 000000000000..5829105ede41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nil-decl-in-foreign.rs @@ -0,0 +1,15 @@ +// run-pass + +#![allow(improper_ctypes)] +#![allow(dead_code)] +// Issue #901 +// pretty-expanded FIXME #23616 + +mod libc { + extern { + pub fn printf(x: ()); + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/assign-while-to-immutable.rs b/gcc/testsuite/rust/rustc/ui/nll/assign-while-to-immutable.rs new file mode 100644 index 000000000000..ecdd51a8e804 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/assign-while-to-immutable.rs @@ -0,0 +1,12 @@ +// We used to incorrectly assign to `x` twice when generating MIR for this +// function, preventing this from compiling. + +// check-pass + +fn main() { + let x = while false { + break; + }; + let y = 'l: while break 'l {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/borrow-use-issue-46875.rs b/gcc/testsuite/rust/rustc/ui/nll/borrow-use-issue-46875.rs new file mode 100644 index 000000000000..afac4970dfb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/borrow-use-issue-46875.rs @@ -0,0 +1,19 @@ +// run-pass + +fn vec() { + let mut _x = vec!['c']; + let _y = &_x; + _x = Vec::new(); +} + +fn int() { + let mut _x = 5; + let _y = &_x; + _x = 7; +} + +fn main() { + vec(); + int(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs b/gcc/testsuite/rust/rustc/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs new file mode 100644 index 000000000000..6fd9714f727a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs @@ -0,0 +1,26 @@ +// +// run-pass +// +// FIXME(#54366) - We probably shouldn't allow #[thread_local] static mut to get a 'static lifetime. + +#![feature(thread_local)] + +#[thread_local] +static mut X1: u64 = 0; + +struct S1 { + a: &'static mut u64, +} + +impl S1 { + fn new(_x: u64) -> S1 { + S1 { + a: unsafe { &mut X1 }, + } + } +} + +fn main() { + S1::new(0).a; +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/borrowed-local-error.rs b/gcc/testsuite/rust/rustc/ui/nll/borrowed-local-error.rs new file mode 100644 index 000000000000..08e8e1e00372 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/borrowed-local-error.rs @@ -0,0 +1,13 @@ +fn gimme(x: &(u32,)) -> &u32 { + &x.0 +} + +fn main() { + let x = gimme({ + let v = (22,); + &v +// { dg-error ".E0597." "" { target *-*-* } .-1 } + }); + println!("{:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/borrowed-match-issue-45045.rs b/gcc/testsuite/rust/rustc/ui/nll/borrowed-match-issue-45045.rs new file mode 100644 index 000000000000..f4c2d5986e8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/borrowed-match-issue-45045.rs @@ -0,0 +1,19 @@ +// Regression test for issue #45045 + +enum Xyz { + A, + B, +} + +fn main() { + let mut e = Xyz::A; + let f = &mut e; + let g = f; + match e { + Xyz::A => println!("a"), +// { dg-error ".E0503." "" { target *-*-* } .-1 } + Xyz::B => println!("b"), + }; + *g = Xyz::B; +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/borrowed-referent-issue-38899.rs b/gcc/testsuite/rust/rustc/ui/nll/borrowed-referent-issue-38899.rs new file mode 100644 index 000000000000..96c19bbc8a91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/borrowed-referent-issue-38899.rs @@ -0,0 +1,18 @@ +// Regression test for issue #38899 + +pub struct Block<'a> { + current: &'a u8, + unrelated: &'a u8, +} + +fn bump<'a>(mut block: &mut Block<'a>) { + let x = &mut block; + println!("{}", x.current); + let p: &'a u8 = &*block.current; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + drop(x); + drop(p); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/borrowed-temporary-error.rs b/gcc/testsuite/rust/rustc/ui/nll/borrowed-temporary-error.rs new file mode 100644 index 000000000000..5b53e7256d43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/borrowed-temporary-error.rs @@ -0,0 +1,13 @@ +fn gimme(x: &(u32,)) -> &u32 { + &x.0 +} + +fn main() { + let x = gimme({ + let v = 22; + &(v,) +// { dg-error ".E0716." "" { target *-*-* } .-1 } + }); + println!("{:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/borrowed-universal-error-2.rs b/gcc/testsuite/rust/rustc/ui/nll/borrowed-universal-error-2.rs new file mode 100644 index 000000000000..0586a1c9865e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/borrowed-universal-error-2.rs @@ -0,0 +1,8 @@ +fn foo<'a>(x: &'a (u32,)) -> &'a u32 { + let v = 22; + &v +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/borrowed-universal-error.rs b/gcc/testsuite/rust/rustc/ui/nll/borrowed-universal-error.rs new file mode 100644 index 000000000000..c707ec377e1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/borrowed-universal-error.rs @@ -0,0 +1,12 @@ +fn gimme(x: &(u32,)) -> &u32 { + &x.0 +} + +fn foo<'a>(x: &'a (u32,)) -> &'a u32 { + let v = 22; + gimme(&(v,)) +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/cannot-move-block-spans.rs b/gcc/testsuite/rust/rustc/ui/nll/cannot-move-block-spans.rs new file mode 100644 index 000000000000..09b4d6ef7137 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/cannot-move-block-spans.rs @@ -0,0 +1,23 @@ +// Test that the we point to the inner expression when moving out to initialize +// a variable, and that we don't give a useless suggestion such as &{ *r }. + +pub fn deref(r: &String) { + let x = { *r }; // { dg-error ".E0507." "" { target *-*-* } } + let y = unsafe { *r }; // { dg-error ".E0507." "" { target *-*-* } } + let z = loop { break *r; }; // { dg-error ".E0507." "" { target *-*-* } } +} + +pub fn index(arr: [String; 2]) { + let x = { arr[0] }; // { dg-error ".E0508." "" { target *-*-* } } + let y = unsafe { arr[0] }; // { dg-error ".E0508." "" { target *-*-* } } + let z = loop { break arr[0]; }; // { dg-error ".E0508." "" { target *-*-* } } +} + +pub fn additional_statement_cases(r: &String) { + let x = { let mut u = 0; u += 1; *r }; // { dg-error ".E0507." "" { target *-*-* } } + let y = unsafe { let mut u = 0; u += 1; *r }; // { dg-error ".E0507." "" { target *-*-* } } + let z = loop { let mut u = 0; u += 1; break *r; u += 2; }; // { dg-error ".E0507." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/capture-mut-ref.rs b/gcc/testsuite/rust/rustc/ui/nll/capture-mut-ref.rs new file mode 100644 index 000000000000..7f7665fe7bfc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/capture-mut-ref.rs @@ -0,0 +1,17 @@ +// run-rustfix + +// Check that capturing a mutable reference by move and assigning to its +// referent doesn't make the unused mut lint think that it is mutable. + +#![deny(unused_mut)] + +pub fn mutable_upvar() { + let mut x = &mut 0; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = move || { + *x = 1; + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/capture-ref-in-struct.rs b/gcc/testsuite/rust/rustc/ui/nll/capture-ref-in-struct.rs new file mode 100644 index 000000000000..fb500b8fa5f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/capture-ref-in-struct.rs @@ -0,0 +1,37 @@ +// Test that a structure which tries to store a pointer to `y` into +// `p` (indirectly) fails to compile. + +struct SomeStruct<'a, 'b: 'a> { + p: &'a mut &'b i32, + y: &'b i32, +} + +fn test() { + let x = 44; + let mut p = &x; + + { + let y = 22; + + let closure = SomeStruct { + p: &mut p, + y: &y, +// { dg-error ".E0597." "" { target *-*-* } .-1 } + }; + + closure.invoke(); + } + + deref(p); +} + +impl<'a, 'b> SomeStruct<'a, 'b> { + fn invoke(self) { + *self.p = self.y; + } +} + +fn deref(_: &i32) { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-access-spans.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-access-spans.rs new file mode 100644 index 000000000000..63040528499d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-access-spans.rs @@ -0,0 +1,57 @@ +// check that accesses due to a closure capture give a special note + +fn closure_imm_capture_conflict(mut x: i32) { + let r = &mut x; + || x; // { dg-error ".E0502." "" { target *-*-* } } + r.use_mut(); +} + +fn closure_mut_capture_conflict(mut x: i32) { + let r = &mut x; + || x = 2; // { dg-error ".E0499." "" { target *-*-* } } + r.use_mut(); +} + +fn closure_unique_capture_conflict(mut x: &mut i32) { + let r = &mut x; + || *x = 2; // { dg-error ".E0500." "" { target *-*-* } } + r.use_mut(); +} + +fn closure_copy_capture_conflict(mut x: i32) { + let r = &mut x; + move || x; // { dg-error ".E0503." "" { target *-*-* } } + r.use_ref(); +} + +fn closure_move_capture_conflict(mut x: String) { + let r = &x; + || x; // { dg-error ".E0505." "" { target *-*-* } } + r.use_ref(); +} + +fn closure_imm_capture_moved(mut x: String) { + let r = x; + || x.len(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn closure_mut_capture_moved(mut x: String) { + let r = x; + || x = String::new(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn closure_unique_capture_moved(x: &mut String) { + let r = x; + || *x = String::new(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn closure_move_capture_moved(x: &mut String) { + let r = x; + || x; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() {} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-borrow-spans.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-borrow-spans.rs new file mode 100644 index 000000000000..7eb04236fcee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-borrow-spans.rs @@ -0,0 +1,101 @@ +// check that existing borrows due to a closure capture give a special note + +fn move_while_borrowed(x: String) { + let f = || x.len(); + let y = x; // { dg-error ".E0505." "" { target *-*-* } } + f.use_ref(); +} + +fn borrow_mut_while_borrowed(mut x: i32) { + let f = || x; + let y = &mut x; // { dg-error ".E0502." "" { target *-*-* } } + f.use_ref(); +} + +fn drop_while_borrowed() { + let f; + { + let x = 1; + f = || x; // { dg-error ".E0597." "" { target *-*-* } } + } + f.use_ref(); +} + +fn assign_while_borrowed(mut x: i32) { + let f = || x; + x = 1; // { dg-error ".E0506." "" { target *-*-* } } + f.use_ref(); +} + +fn copy_while_borrowed_mut(mut x: i32) { + let f = || x = 0; + let y = x; // { dg-error ".E0503." "" { target *-*-* } } + f.use_ref(); +} + +fn borrow_while_borrowed_mut(mut x: i32) { + let f = || x = 0; + let y = &x; // { dg-error ".E0502." "" { target *-*-* } } + f.use_ref(); +} + +fn borrow_mut_while_borrowed_mut(mut x: i32) { + let f = || x = 0; + let y = &mut x; // { dg-error ".E0499." "" { target *-*-* } } + f.use_ref(); +} + +fn drop_while_borrowed_mut() { + let f; + { + let mut x = 1; + f = || x = 0; // { dg-error ".E0597." "" { target *-*-* } } + } + f.use_ref(); +} + +fn assign_while_borrowed_mut(mut x: i32) { + let f = || x = 0; + x = 1; // { dg-error ".E0506." "" { target *-*-* } } + f.use_ref(); +} + +fn copy_while_borrowed_unique(x: &mut i32) { + let f = || *x = 0; + let y = x; // { dg-error ".E0505." "" { target *-*-* } } + f.use_ref(); +} + +fn borrow_while_borrowed_unique(x: &mut i32) { + let f = || *x = 0; + let y = &x; // { dg-error ".E0501." "" { target *-*-* } } + f.use_ref(); +} + +fn borrow_mut_while_borrowed_unique(mut x: &mut i32) { + let f = || *x = 0; + let y = &mut x; // { dg-error ".E0501." "" { target *-*-* } } + f.use_ref(); +} + +fn drop_while_borrowed_unique() { + let mut z = 1; + let f; + { + let x = &mut z; + f = || *x = 0; // { dg-error ".E0597." "" { target *-*-* } } + } + f.use_ref(); +} + +fn assign_while_borrowed_unique(x: &mut i32) { + let f = || *x = 0; + *x = 1; // { dg-error ".E0506." "" { target *-*-* } } + f.use_ref(); +} + +fn main() {} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-captures.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-captures.rs new file mode 100644 index 000000000000..1bc47a0d0c57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-captures.rs @@ -0,0 +1,56 @@ +// Some cases with closures that might be problems + +// Should have one error per assignment + +fn one_closure(x: i32) { + || + x = 1; // { dg-error ".E0594." "" { target *-*-* } } + move || + x = 1; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn two_closures(x: i32) { + || { + || + x = 1; // { dg-error ".E0594." "" { target *-*-* } } + }; + move || { + || + x = 1; // { dg-error ".E0594." "" { target *-*-* } } + }; +} + +fn fn_ref(f: F) -> F { f } + +fn two_closures_ref_mut(mut x: i32) { + fn_ref(|| { + || // { dg-error ".E0596." "" { target *-*-* } } + x = 1;} + ); + fn_ref(move || { + || // { dg-error ".E0596." "" { target *-*-* } } + x = 1;}); +} + +// This still gives two messages, but it requires two things to be fixed. +fn two_closures_ref(x: i32) { + fn_ref(|| { + || // { dg-error ".E0596." "" { target *-*-* } } + x = 1;} // { dg-error ".E0594." "" { target *-*-* } } + ); + fn_ref(move || { + || // { dg-error ".E0596." "" { target *-*-* } } + x = 1;}); // { dg-error ".E0594." "" { target *-*-* } } +} + +fn two_closures_two_refs(x: &mut i32) { + fn_ref(|| { + || // { dg-error ".E0596." "" { target *-*-* } } + *x = 1;}); + fn_ref(move || { + || // { dg-error ".E0596." "" { target *-*-* } } + *x = 1;}); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-move-spans.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-move-spans.rs new file mode 100644 index 000000000000..4610fb8e4ada --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-move-spans.rs @@ -0,0 +1,22 @@ +// check that moves due to a closure capture give a special note + +fn move_after_move(x: String) { + || x; + let y = x; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn borrow_after_move(x: String) { + || x; + let y = &x; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn borrow_mut_after_move(mut x: String) { + || x; + let y = &mut x; // { dg-error ".E0382." "" { target *-*-* } } +} + +fn fn_ref(f: F) -> F { f } +fn fn_mut(f: F) -> F { f } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-argument-callee.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-argument-callee.rs new file mode 100644 index 000000000000..1bc3f921831d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-argument-callee.rs @@ -0,0 +1,43 @@ +// Test closure that: +// +// - takes an argument `y` with lifetime `'a` (in the code, it's anonymous) +// - stores `y` into another, longer-lived spot with lifetime `'b` +// +// Because `'a` and `'b` are two different, unrelated higher-ranked +// regions with no relationship to one another, this is an error. This +// error is reported by the closure itself and is not propagated to +// its creator: this is because `'a` and `'b` are higher-ranked +// (late-bound) regions and the closure is not allowed to propagate +// additional where clauses between higher-ranked regions, only those +// that appear free in its type (hence, we see it before the closure's +// "external requirements" report). + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +#[rustc_regions] +fn test() { + let x = 44; + let mut p = &x; + + { + let y = 22; + let mut closure = expect_sig(|p, y| *p = y); +// { dg-error "" "" { target *-*-* } .-1 } + closure(&mut p, &y); + } + + deref(p); +} + +fn expect_sig(f: F) -> F + where F: FnMut(&mut &i32, &i32) +{ + f +} + +fn deref(_p: &i32) { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-argument.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-argument.rs new file mode 100644 index 000000000000..b00c0d6b85b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-argument.rs @@ -0,0 +1,43 @@ +// Test closure that: +// +// - takes an argument `y` +// - stores `y` into another, longer-lived spot +// +// but is invoked with a spot that doesn't live long +// enough to store `y`. +// +// The error is reported in the caller: invoking the closure links the +// lifetime of the variable that is given as `y` (via subtyping) and +// thus forces the corresponding borrow to live too long. This is +// basically checking that the MIR type checker correctly enforces the +// closure signature. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +#[rustc_regions] +fn test() { + let x = 44; + let mut p = &x; + + { + let y = 22; + let mut closure = expect_sig(|p, y| *p = y); + closure(&mut p, &y); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + } + + deref(p); +} + +fn expect_sig(f: F) -> F + where F: for<'a, 'b> FnMut(&'a mut &'b i32, &'b i32) +{ + f +} + +fn deref(_p: &i32) { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-upvar-nested.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-upvar-nested.rs new file mode 100644 index 000000000000..ad2a7590ad64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-upvar-nested.rs @@ -0,0 +1,34 @@ +// As in `escape-upvar-ref.rs`, test closure that: +// +// - captures a variable `y` +// - stores reference to `y` into another, longer-lived spot +// +// except that the closure does so via a second closure. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +#[rustc_regions] +fn test() { + let x = 44; + let mut p = &x; + + { + let y = 22; + + let mut closure = || { + let mut closure1 = || p = &y; // { dg-error ".E0597." "" { target *-*-* } } + closure1(); + }; + + closure(); + } + + deref(p); +} + +fn deref(_p: &i32) { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-upvar-ref.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-upvar-ref.rs new file mode 100644 index 000000000000..3d35c0be6359 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/escape-upvar-ref.rs @@ -0,0 +1,34 @@ +// Test closure that: +// +// - captures a variable `y` by reference +// - stores that reference to `y` into another, longer-lived place (`p`) +// +// Both of these are upvars of reference type (the capture of `y` is +// of type `&'a i32`, the capture of `p` is of type `&mut &'b +// i32`). The closure thus computes a relationship between `'a` and +// `'b`. This relationship is propagated to the closure creator, +// which reports an error. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +#[rustc_regions] +fn test() { + let x = 44; + let mut p = &x; + + { + let y = 22; + let mut closure = || p = &y; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + closure(); + } + + deref(p); +} + +fn deref(_p: &i32) { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs new file mode 100644 index 000000000000..a317339b6a30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs @@ -0,0 +1,37 @@ +// check-pass + +// Test that we propagate region relations from closures precisely when there is +// more than one non-local lower bound. + +// In this case the closure has signature +// |x: &'4 mut (&'5 (&'1 str, &'2 str), &'3 str)| -> .. +// We end up with a `'3: '5` constraint that we can propagate as +// `'3: '1`, `'3: '2`, but previously we approximated it as `'3: 'static`. + +// As an optimization, we primarily propagate bounds for the "representative" +// of each SCC. As such we have these two similar cases where hopefully one +// of them will test the case we want (case2, when this test was added). +mod case1 { + fn f(s: &str) { + g(s, |x| h(x)); + } + + fn g(_: T, _: F) + where F: Fn(&mut (&(T, T), T)) {} + + fn h(_: &mut (&(T, T), T)) {} +} + +mod case2 { + fn f(s: &str) { + g(s, |x| h(x)); + } + + fn g(_: T, _: F) + where F: Fn(&mut (T, &(T, T))) {} + + fn h(_: &mut (T, &(T, T))) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs new file mode 100644 index 000000000000..b440110f861a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs @@ -0,0 +1,52 @@ +// Test where we fail to approximate due to demanding a postdom +// relationship between our upper bounds. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// Callee knows that: +// +// 'x: 'a +// 'x: 'b +// 'c: 'y +// +// we have to prove that `'x: 'y`. We currently can only approximate +// via a postdominator -- hence we fail to choose between `'a` and +// `'b` here and report the error in the closure. +fn establish_relationships<'a, 'b, 'c, F>( + _cell_a: Cell<&'a u32>, + _cell_b: Cell<&'b u32>, + _cell_c: Cell<&'c u32>, + _closure: F, +) where + F: for<'x, 'y> FnMut( + Cell<&'a &'x u32>, // shows that 'x: 'a + Cell<&'b &'x u32>, // shows that 'x: 'b + Cell<&'y &'c u32>, // shows that 'c: 'y + Cell<&'x u32>, + Cell<&'y u32>, + ), +{ +} + +fn demand_y<'x, 'y>(_cell_x: Cell<&'x u32>, _cell_y: Cell<&'y u32>, _y: &'y u32) {} + +#[rustc_regions] +fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { + establish_relationships( + cell_a, + cell_b, + cell_c, + |_outlives1, _outlives2, _outlives3, x, y| { + // Only works if 'x: 'y: + let p = x.get(); + demand_y(x, y, p) // { dg-error "" "" { target *-*-* } } + }, + ); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-ref.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-ref.rs new file mode 100644 index 000000000000..929856508a61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-ref.rs @@ -0,0 +1,51 @@ +// Rather convoluted setup where we infer a relationship between two +// free regions in the closure signature (`'a` and `'b`) on the basis +// of a relationship between two bound regions (`'x` and `'y`). +// +// The idea is that, thanks to invoking `demand_y`, `'x: 'y` must +// hold, where `'x` and `'y` are bound regions. The closure can't +// prove that directly, and because `'x` and `'y` are bound it cannot +// ask the caller to prove it either. But it has bounds on `'x` and +// `'y` in terms of `'a` and `'b`, and it can propagate a relationship +// between `'a` and `'b` to the caller. +// +// Note: the use of `Cell` here is to introduce invariance. One less +// variable. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// Callee knows that: +// +// 'x: 'a +// 'b: 'y +// +// so if we are going to ensure that `'x: 'y`, then `'a: 'b` must +// hold. +fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F) +where + F: for<'x, 'y> FnMut( + &Cell<&'a &'x u32>, // shows that 'x: 'a + &Cell<&'y &'b u32>, // shows that 'b: 'y + &Cell<&'x u32>, + &Cell<&'y u32>, + ), +{ +} + +fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {} + +#[rustc_regions] +fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { + // Only works if 'x: 'y: + demand_y(x, y, x.get()) +// { dg-error "" "" { target *-*-* } .-1 } + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs new file mode 100644 index 000000000000..51d2e79e4008 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.rs @@ -0,0 +1,41 @@ +// Test a case where we setup relationships like `'x: 'a` or `'a: 'x`, +// where `'x` is bound in closure type but `'a` is free. This forces +// us to approximate `'x` one way or the other. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +fn foo<'a, F>(_cell: Cell<&'a u32>, _f: F) +where + F: for<'x> FnOnce(Cell<&'a u32>, Cell<&'x u32>), +{ +} + +#[rustc_regions] +fn case1() { + let a = 0; + let cell = Cell::new(&a); + foo(cell, |cell_a, cell_x| { + cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure +// { dg-error ".E0521." "" { target *-*-* } .-1 } + }) +} + +#[rustc_regions] +fn case2() { + let a = 0; + let cell = Cell::new(&a); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + // As you can see in the stderr output, this closure propoagates a + // requirement that `'a: 'static'. + foo(cell, |cell_a, cell_x| { + cell_x.set(cell_a.get()); // forces 'a: 'x, implies 'a = 'static -> borrow error + }) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs new file mode 100644 index 000000000000..e3159a954acc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.rs @@ -0,0 +1,41 @@ +// Test a case where we are trying to prove `'x: 'y` and are forced to +// approximate the shorter end-point (`'y`) to with `'static`. This is +// because `'y` is higher-ranked but we know of no relations to other +// regions. Note that `'static` shows up in the stderr output as `'0`. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// Callee knows that: +// +// 'x: 'a +// +// so the only way we can ensure that `'x: 'y` is to show that +// `'a: 'static`. +fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F) +where + F: for<'x, 'y> FnMut( + &Cell<&'a &'x u32>, // shows that 'x: 'a + &Cell<&'x u32>, + &Cell<&'y u32>, + ), +{ +} + +fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {} + +#[rustc_regions] +fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { +// { dg-error ".E0521." "" { target *-*-* } .-1 } + + // Only works if 'x: 'y: + demand_y(x, y, x.get()) + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs new file mode 100644 index 000000000000..a83e921315e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.rs @@ -0,0 +1,44 @@ +// Test a case where we are trying to prove `'x: 'y` and are forced to +// approximate the shorter end-point (`'y`) to with `'static`. This is +// because `'y` is higher-ranked but we know of only irrelevant +// relations to other regions. Note that `'static` shows up in the +// stderr output as `'0`. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// Callee knows that: +// +// 'x: 'a +// 'y: 'b +// +// so the only way we can ensure that `'x: 'y` is to show that +// `'a: 'static`. +fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F) +where + F: for<'x, 'y> FnMut( + &Cell<&'a &'x u32>, // shows that 'x: 'a + &Cell<&'b &'y u32>, // shows that 'y: 'b + &Cell<&'x u32>, + &Cell<&'y u32>, + ), +{ +} + +fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {} + +#[rustc_regions] +fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { +// { dg-error ".E0521." "" { target *-*-* } .-1 } + + // Only works if 'x: 'y: + demand_y(x, y, x.get()) + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-val.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-val.rs new file mode 100644 index 000000000000..3507df1cf20f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-approximated-val.rs @@ -0,0 +1,44 @@ +// A simpler variant of `outlives-from-argument` where cells are +// passed by value. +// +// This is simpler because there are no "extraneous" region +// relationships. In the 'main' variant, there are a number of +// anonymous regions as well. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// Callee knows that: +// +// 'x: 'a +// 'b: 'y +// +// so if we are going to ensure that `'x: 'y`, then `'a: 'b` must +// hold. +fn establish_relationships<'a, 'b, F>(_cell_a: Cell<&'a u32>, _cell_b: Cell<&'b u32>, _closure: F) +where + F: for<'x, 'y> FnMut( + Cell<&'a &'x u32>, // shows that 'x: 'a + Cell<&'y &'b u32>, // shows that 'b: 'y + Cell<&'x u32>, + Cell<&'y u32>, + ), +{ +} + +fn demand_y<'x, 'y>(_outlives1: Cell<&&'x u32>, _outlives2: Cell<&'y &u32>, _y: &'y u32) {} + +#[rustc_regions] +fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { + // Only works if 'x: 'y: + demand_y(outlives1, outlives2, x.get()) +// { dg-error "" "" { target *-*-* } .-1 } + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-despite-same-free-region.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-despite-same-free-region.rs new file mode 100644 index 000000000000..9f59b0c403fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-despite-same-free-region.rs @@ -0,0 +1,51 @@ +// Test where we might in theory be able to see that the relationship +// between two bound regions is true within closure and hence have no +// need to propagate; but in fact we do because identity of free +// regions is erased. + +// compile-flags:-Zborrowck=mir -Zverbose +// check-pass + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// In theory, callee knows that: +// +// 'x: 'a +// 'a: 'y +// +// and hence could satisfy that `'x: 'y` locally. However, in our +// checking, we ignore the precise free regions that come into the +// region and just assign each position a distinct universally bound +// region. Hence, we propagate a constraint to our caller that will +// wind up being solvable. +fn establish_relationships<'a, F>( + _cell_a: Cell<&'a u32>, + _closure: F, +) where + F: for<'x, 'y> FnMut( + Cell<&'a &'x u32>, // shows that 'x: 'a + Cell<&'y &'a u32>, // shows that 'a: 'y + Cell<&'x u32>, + Cell<&'y u32>, + ), +{ +} + +fn demand_y<'x, 'y>(_cell_x: Cell<&'x u32>, _cell_y: Cell<&'y u32>, _y: &'y u32) {} + +#[rustc_regions] +fn supply<'a>(cell_a: Cell<&'a u32>) { + establish_relationships( + cell_a, + |_outlives1, _outlives2, x, y| { + // Only works if 'x: 'y: + let p = x.get(); + demand_y(x, y, p) + }, + ); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs new file mode 100644 index 000000000000..50cf14f0ba47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.rs @@ -0,0 +1,43 @@ +// Similarly to escape-argument-callee, a test case where the closure +// requires a relationship between 2 unrelated higher-ranked regions, +// with no helpful relations between the HRRs and free regions. +// +// In this case, the error is reported by the closure itself. This is +// because it is unable to approximate the higher-ranked region `'x`, +// as it knows of no relationships between `'x` and any +// non-higher-ranked regions. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// Callee knows that: +// +// 'b: 'y +// +// but this doesn't really help us in proving that `'x: 'y`, so closure gets an error. +fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F) +where + F: for<'x, 'y> FnMut( + &Cell<&'y &'b u32>, // shows that 'b: 'y + &Cell<&'x u32>, + &Cell<&'y u32>, + ), +{ +} + +fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {} + +#[rustc_regions] +fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { + // Only works if 'x: 'y: + demand_y(x, y, x.get()) +// { dg-error "" "" { target *-*-* } .-1 } + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs new file mode 100644 index 000000000000..d0f5f13660e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.rs @@ -0,0 +1,47 @@ +// Similarly to escape-argument-callee, a test case where the closure +// requires a relationship between 2 unrelated higher-ranked regions, +// with no helpful relations between the HRRs and free regions. +// +// In this case, the error is reported by the closure itself. This is +// because it is unable to approximate the higher-ranked region `'x`, +// as it only knows of regions that `'x` is outlived by, and none that +// `'x` outlives. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// Callee knows that: +// +// 'a: 'x +// 'b: 'y +// +// but this doesn't really help us in proving that `'x: 'y`, so +// closure gets an error. In particular, we would need to know that +// `'x: 'a`, so that we could approximate `'x` "downwards" to `'a`. +fn establish_relationships<'a, 'b, F>(_cell_a: &Cell<&'a u32>, _cell_b: &Cell<&'b u32>, _closure: F) +where + F: for<'x, 'y> FnMut( + &Cell<&'x &'a u32>, // shows that 'a: 'x + &Cell<&'y &'b u32>, // shows that 'b: 'y + &Cell<&'x u32>, + &Cell<&'y u32>, + ), +{ +} + +fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u32) {} + +#[rustc_regions] +fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { + establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { + // Only works if 'x: 'y: + demand_y(x, y, x.get()) +// { dg-error "" "" { target *-*-* } .-1 } + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-from-trait-match.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-from-trait-match.rs new file mode 100644 index 000000000000..fc7bb2390487 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-from-trait-match.rs @@ -0,0 +1,50 @@ +// Test that regions which appear only in the closure's generics (in +// this case, `'a`) are properly mapped to the creator's generics. In +// this case, the closure constrains its type parameter `T` to outlive +// the same `'a` for which it implements `Trait`, which can only be the `'a` +// from the function definition. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +trait Trait<'a> {} + +fn establish_relationships(value: T, closure: F) +where + F: FnOnce(T), +{ + closure(value) +} + +fn require<'a, T>(t: T) +where + T: Trait<'a> + 'a, +{ +} + +#[rustc_regions] +fn supply<'a, T>(value: T) +where + T: Trait<'a>, +{ + establish_relationships(value, |value| { +// { dg-error ".E0309." "" { target *-*-* } .-1 } + + // This function call requires that + // + // (a) T: Trait<'a> + // + // and + // + // (b) T: 'a + // + // The latter does not hold. + + require(value); + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-multiple-requirements.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-multiple-requirements.rs new file mode 100644 index 000000000000..60193d0179e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/propagate-multiple-requirements.rs @@ -0,0 +1,24 @@ +// Test that we propagate *all* requirements to the caller, not just the first +// one. + +fn once U>(f: F, s: S, t: T) -> U { + f(s, t) +} + +pub fn dangle() -> &'static [i32] { + let other_local_arr = [0, 2, 4]; + let local_arr = other_local_arr; + let mut out: &mut &'static [i32] = &mut (&[1] as _); + once(|mut z: &[i32], mut out_val: &mut &[i32]| { + // We unfortunately point to the first use in the closure in the error + // message + z = &local_arr; // { dg-error ".E0597." "" { target *-*-* } } + *out_val = &local_arr; + }, &[] as &[_], &mut *out); + *out +} + +fn main() { + println!("{:?}", dangle()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs new file mode 100644 index 000000000000..4511c7628d37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs @@ -0,0 +1,14 @@ +// Basic test for free regions in the NLL code. This test ought to +// report an error due to a reborrowing constraint. Right now, we get +// a variety of errors from the older, AST-based machinery (notably +// borrowck), and then we get the NLL error at the end. + +// compile-flags:-Zborrowck=mir -Zverbose + +fn foo(x: &u32) -> &'static u32 { + &*x +// { dg-error ".E0621." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs new file mode 100644 index 000000000000..692cbeb09cc0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.rs @@ -0,0 +1,14 @@ +// Basic test for free regions in the NLL code. This test ought to +// report an error due to a reborrowing constraint. Right now, we get +// a variety of errors from the older, AST-based machinery (notably +// borrowck), and then we get the NLL error at the end. + +// compile-flags:-Zborrowck=mir -Zverbose + +fn foo<'a>(x: &'a u32) -> &'static u32 { + &*x +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs new file mode 100644 index 000000000000..811d449860e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.rs @@ -0,0 +1,14 @@ +// Basic test for free regions in the NLL code. This test ought to +// report an error due to a reborrowing constraint. Right now, we get +// a variety of errors from the older, AST-based machinery (notably +// borrowck), and then we get the NLL error at the end. + +// compile-flags:-Zborrowck=mir -Zverbose + +fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'b u32 { + &*x +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs new file mode 100644 index 000000000000..a4fd0754984a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/region-lbr1-does-outlive-lbr2-because-implied-bound.rs @@ -0,0 +1,12 @@ +// Basic test for free regions in the NLL code. This test does not +// report an error because of the (implied) bound that `'b: 'a`. + +// check-pass +// compile-flags:-Zborrowck=mir -Zverbose + +fn foo<'a, 'b>(x: &'a &'b u32) -> &'a u32 { + &**x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/return-wrong-bound-region.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/return-wrong-bound-region.rs new file mode 100644 index 000000000000..32883efff973 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-requirements/return-wrong-bound-region.rs @@ -0,0 +1,24 @@ +// Test closure that takes two references and is supposed to return +// the first, but actually returns the second. This should fail within +// the closure. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![feature(rustc_attrs)] + +#[rustc_regions] +fn test() { + expect_sig(|a, b| b); // ought to return `a` +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn expect_sig(f: F) -> F + where F: for<'a> FnMut(&'a i32, &i32) -> &'a i32 +{ + f +} + +fn deref(_p: &i32) { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closure-use-spans.rs b/gcc/testsuite/rust/rustc/ui/nll/closure-use-spans.rs new file mode 100644 index 000000000000..5dd7fd6608bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closure-use-spans.rs @@ -0,0 +1,22 @@ +// check that liveness due to a closure capture gives a special note + +fn use_as_borrow_capture(mut x: i32) { + let y = &x; + x = 0; // { dg-error ".E0506." "" { target *-*-* } } + || *y; +} + +fn use_as_borrow_mut_capture(mut x: i32) { + let y = &mut x; + x = 0; // { dg-error ".E0506." "" { target *-*-* } } + || *y = 1; +} + +fn use_as_move_capture(mut x: i32) { + let y = &x; + x = 0; // { dg-error ".E0506." "" { target *-*-* } } + move || *y; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/closures-in-loops.rs b/gcc/testsuite/rust/rustc/ui/nll/closures-in-loops.rs new file mode 100644 index 000000000000..65c5b089ae28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/closures-in-loops.rs @@ -0,0 +1,25 @@ +// Test messages where a closure capture conflicts with itself because it's in +// a loop. + +fn repreated_move(x: String) { + for i in 0..10 { + || x; // { dg-error ".E0382." "" { target *-*-* } } + } +} + +fn repreated_mut_borrow(mut x: String) { + let mut v = Vec::new(); + for i in 0..10 { + v.push(|| x = String::new()); // { dg-error ".E0499." "" { target *-*-* } } + } +} + +fn repreated_unique_borrow(x: &mut String) { + let mut v = Vec::new(); + for i in 0..10 { + v.push(|| *x = String::new()); // { dg-error ".E0524." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/constant-thread-locals-issue-47053.rs b/gcc/testsuite/rust/rustc/ui/nll/constant-thread-locals-issue-47053.rs new file mode 100644 index 000000000000..70f9f3118fac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/constant-thread-locals-issue-47053.rs @@ -0,0 +1,11 @@ +// Regression test for issue #47053 + +#![feature(thread_local)] + +#[thread_local] +static FOO: isize = 5; + +fn main() { + FOO = 6; // { dg-error ".E0594." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/constant.rs b/gcc/testsuite/rust/rustc/ui/nll/constant.rs new file mode 100644 index 000000000000..1e1e314c861f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/constant.rs @@ -0,0 +1,12 @@ +// Test that MIR borrowck and NLL analysis can handle constants of +// arbitrary types without ICEs. + +// compile-flags:-Zborrowck=mir +// check-pass + +const HI: &str = "hi"; + +fn main() { + assert_eq!(HI, "hi"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/decl-macro-illegal-copy.rs b/gcc/testsuite/rust/rustc/ui/nll/decl-macro-illegal-copy.rs new file mode 100644 index 000000000000..69320283fe47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/decl-macro-illegal-copy.rs @@ -0,0 +1,29 @@ +// Regression test for #46314 + +#![feature(decl_macro)] + +struct NonCopy(String); + +struct Wrapper { + inner: NonCopy, +} + +macro inner_copy($wrapper:ident) { + $wrapper.inner +} + +fn main() { + let wrapper = Wrapper { + inner: NonCopy("foo".into()), + }; + assert_two_non_copy( + inner_copy!(wrapper), + wrapper.inner, +// { dg-error ".E0382." "" { target *-*-* } .-1 } + ); +} + +fn assert_two_non_copy(a: NonCopy, b: NonCopy) { + assert_eq!(a.0, b.0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.rs b/gcc/testsuite/rust/rustc/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.rs new file mode 100644 index 000000000000..bc1597b3f7ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/do-not-ignore-lifetime-bounds-in-copy-proj.rs @@ -0,0 +1,13 @@ +// Test that the 'static bound from the Copy impl is respected. Regression test for #29149. + +#[derive(Clone)] +struct Foo<'a>(&'a u32); +impl Copy for Foo<'static> {} + +fn main() { + let s = 2; + let a = (Foo(&s),); // { dg-error ".E0597." "" { target *-*-* } } + drop(a.0); + drop(a.0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/do-not-ignore-lifetime-bounds-in-copy.rs b/gcc/testsuite/rust/rustc/ui/nll/do-not-ignore-lifetime-bounds-in-copy.rs new file mode 100644 index 000000000000..070e38e4caf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/do-not-ignore-lifetime-bounds-in-copy.rs @@ -0,0 +1,12 @@ +// Test that the 'static bound from the Copy impl is respected. Regression test for #29149. + +#[derive(Clone)] struct Foo<'a>(&'a u32); +impl Copy for Foo<'static> {} + +fn main() { + let s = 2; + let a = Foo(&s); // { dg-error ".E0597." "" { target *-*-* } } + drop(a); + drop(a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/dont-print-desugared.rs b/gcc/testsuite/rust/rustc/ui/nll/dont-print-desugared.rs new file mode 100644 index 000000000000..dd66ede22f16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/dont-print-desugared.rs @@ -0,0 +1,22 @@ +// Test that we don't show variables with from for loop desugaring + +fn for_loop(s: &[i32]) { + for &ref mut x in s {} +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + +struct D<'a>(&'a ()); + +impl Drop for D<'_> { + fn drop(&mut self) {} +} + +fn for_loop_dropck(v: Vec>) { + for ref mut d in v { + let y = (); + *d = D(&y); // { dg-error ".E0597." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/drop-may-dangle.rs b/gcc/testsuite/rust/rustc/ui/nll/drop-may-dangle.rs new file mode 100644 index 000000000000..b7dfb946f606 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/drop-may-dangle.rs @@ -0,0 +1,36 @@ +// Basic test for liveness constraints: the region (`R1`) that appears +// in the type of `p` includes the points after `&v[0]` up to (but not +// including) the call to `use_x`. The `else` branch is not included. + +// compile-flags:-Zborrowck=mir +// check-pass + +#![allow(warnings)] +#![feature(dropck_eyepatch)] + +fn use_x(_: usize) -> bool { true } + +fn main() { + let mut v = [1, 2, 3]; + let p: WrapMayDangle<& /* R4 */ usize> = WrapMayDangle { value: &v[0] }; + if true { + // `p` will get dropped at end of this block. However, because of + // the `#[may_dangle]` attribute, we do not need to consider R4 + // live after this point. + use_x(*p.value); + } else { + v[0] += 1; + use_x(22); + } + + v[0] += 1; +} + +struct WrapMayDangle { + value: T +} + +unsafe impl<#[may_dangle] T> Drop for WrapMayDangle { + fn drop(&mut self) { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/drop-no-may-dangle.rs b/gcc/testsuite/rust/rustc/ui/nll/drop-no-may-dangle.rs new file mode 100644 index 000000000000..e9a71d6b0638 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/drop-no-may-dangle.rs @@ -0,0 +1,33 @@ +// Basic test for liveness constraints: the region (`R1`) that appears +// in the type of `p` must include everything until `p` is dropped +// because of destructor. (Note that the stderr also identifies this +// destructor in the error message.) + +// compile-flags:-Zborrowck=mir + +#![allow(warnings)] +#![feature(dropck_eyepatch)] + +fn use_x(_: usize) -> bool { true } + +fn main() { + let mut v = [1, 2, 3]; + let p: WrapMayNotDangle<&usize> = WrapMayNotDangle { value: &v[0] }; + if true { + use_x(*p.value); + } else { + use_x(22); + v[0] += 1; // { dg-error ".E0506." "" { target *-*-* } } + } + + v[0] += 1; // { dg-error ".E0506." "" { target *-*-* } } +} + +struct WrapMayNotDangle { + value: T +} + +impl Drop for WrapMayNotDangle { + fn drop(&mut self) { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/empty-type-predicate-2.rs b/gcc/testsuite/rust/rustc/ui/nll/empty-type-predicate-2.rs new file mode 100644 index 000000000000..140e2fdb45ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/empty-type-predicate-2.rs @@ -0,0 +1,19 @@ +// Regression test for #65553 +// +// `D::Error:` is lowered to `D::Error: ReEmpty` - check that we don't ICE in +// NLL for the unexpected region. + +// check-pass + +trait Deserializer { + type Error; +} + +fn d1() where D::Error: {} + +fn d2() { + d1::(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/empty-type-predicate.rs b/gcc/testsuite/rust/rustc/ui/nll/empty-type-predicate.rs new file mode 100644 index 000000000000..70b563730b55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/empty-type-predicate.rs @@ -0,0 +1,12 @@ +// Regression test for #61315 +// +// `dyn T:` is lowered to `dyn T: ReEmpty` - check that we don't ICE in NLL for +// the unexpected region. + +// check-pass + +trait T {} +fn f() where dyn T: {} + +fn main() { f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/enum-drop-access.rs b/gcc/testsuite/rust/rustc/ui/nll/enum-drop-access.rs new file mode 100644 index 000000000000..e68cef91c541 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/enum-drop-access.rs @@ -0,0 +1,50 @@ +enum DropOption { + Some(T), + None, +} + +impl Drop for DropOption { + fn drop(&mut self) {} +} + +// Dropping opt could access the value behind the reference, +fn drop_enum(opt: DropOption<&mut i32>) -> Option<&mut i32> { + match opt { + DropOption::Some(&mut ref mut r) => { // { dg-error ".E0713." "" { target *-*-* } } + Some(r) + }, + DropOption::None => None, + } +} + +fn optional_drop_enum(opt: Option>) -> Option<&mut i32> { + match opt { + Some(DropOption::Some(&mut ref mut r)) => { // { dg-error ".E0713." "" { target *-*-* } } + Some(r) + }, + Some(DropOption::None) | None => None, + } +} + +// Ok, dropping opt doesn't access the reference +fn optional_tuple(opt: Option<(&mut i32, String)>) -> Option<&mut i32> { + match opt { + Some((&mut ref mut r, _)) => { + Some(r) + }, + None => None, + } +} + +// Ok, dropping res doesn't access the Ok case. +fn different_variants(res: Result<&mut i32, String>) -> Option<&mut i32> { + match res { + Ok(&mut ref mut r) => { + Some(r) + }, + Err(_) => None, + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/extra-unused-mut.rs b/gcc/testsuite/rust/rustc/ui/nll/extra-unused-mut.rs new file mode 100644 index 000000000000..ed32904dfd5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/extra-unused-mut.rs @@ -0,0 +1,67 @@ +// extra unused mut lint tests for #51918 + +// check-pass + +#![feature(generators, nll)] +#![deny(unused_mut)] + +fn ref_argument(ref _y: i32) {} + +// #51801 +fn mutable_upvar() { + let mut x = 0; + move || { + x = 1; + }; +} + +// #50897 +fn generator_mutable_upvar() { + let mut x = 0; + move || { + x = 1; + yield; + }; +} + +// #51830 +fn ref_closure_argument() { + let _ = Some(0).as_ref().map(|ref _a| true); +} + +struct Expr { + attrs: Vec, +} + +// #51904 +fn parse_dot_or_call_expr_with(mut attrs: Vec) { + let x = Expr { attrs: vec![] }; + Some(Some(x)).map(|expr| + expr.map(|mut expr| { + attrs.push(666); + expr.attrs = attrs; + expr + }) + ); +} + +// Found when trying to bootstrap rustc +fn if_guard(x: Result) { + match x { + Ok(mut r) | Err(mut r) if true => r = 1, + _ => (), + } +} + +// #59620 +fn nested_closures() { + let mut i = 0; + [].iter().for_each(|_: &i32| { + [].iter().for_each(move |_: &i32| { + i += 1; + }); + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/generator-distinct-lifetime.rs b/gcc/testsuite/rust/rustc/ui/nll/generator-distinct-lifetime.rs new file mode 100644 index 000000000000..631f8140dc9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/generator-distinct-lifetime.rs @@ -0,0 +1,26 @@ +#![feature(generators, nll)] + +// Test for issue #47189. Here, both `s` and `t` are live for the +// generator's lifetime, but within the generator they have distinct +// lifetimes. We accept this code -- even though the borrow extends +// over a yield -- because the data that is borrowed (`*x`) is not +// stored on the stack. + +// check-pass + +fn foo(x: &mut u32) { + move || { + let s = &mut *x; + yield; + *s += 1; + + let t = &mut *x; + yield; + *t += 1; + }; +} + +fn main() { + foo(&mut 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/generator-upvar-mutability.rs b/gcc/testsuite/rust/rustc/ui/nll/generator-upvar-mutability.rs new file mode 100644 index 000000000000..f0112787e6a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/generator-upvar-mutability.rs @@ -0,0 +1,15 @@ +// Check that generators respect the muatability of their upvars. + +#![feature(generators, nll)] + +fn mutate_upvar() { + let x = 0; + move || { + x = 1; +// { dg-error ".E0594." "" { target *-*-* } .-1 } + yield; + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/get_default.rs b/gcc/testsuite/rust/rustc/ui/nll/get_default.rs new file mode 100644 index 000000000000..af9885ff6f87 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/get_default.rs @@ -0,0 +1,45 @@ +// Basic test for free regions in the NLL code. This test ought to +// report an error due to a reborrowing constraint. Right now, we get +// a variety of errors from the older, AST-based machinery (notably +// borrowck), and then we get the NLL error at the end. + +struct Map { +} + +impl Map { + fn get(&self) -> Option<&String> { None } + fn set(&mut self, v: String) { } +} + +fn ok(map: &mut Map) -> &String { + loop { + match map.get() { + Some(v) => { + return v; + } + None => { + map.set(String::new()); // Ideally, this would not error. +// { dg-error ".E0502." "" { target *-*-* } .-1 } + } + } + } +} + +fn err(map: &mut Map) -> &String { + loop { + match map.get() { + Some(v) => { + map.set(String::new()); // Both AST and MIR error here +// { dg-error ".E0502." "" { target *-*-* } .-1 } + return v; + } + None => { + map.set(String::new()); // Ideally, just AST would error here +// { dg-error ".E0502." "" { target *-*-* } .-1 } + } + } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/guarantor-issue-46974.rs b/gcc/testsuite/rust/rustc/ui/nll/guarantor-issue-46974.rs new file mode 100644 index 000000000000..89003cb29714 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/guarantor-issue-46974.rs @@ -0,0 +1,22 @@ +// Test that NLL analysis propagates lifetimes correctly through +// field accesses, Box accesses, etc. + +#![feature(nll)] + +fn foo(s: &mut (i32,)) -> i32 { + let t = &mut *s; // this borrow should last for the entire function + let x = &t.0; + *s = (2,); // { dg-error ".E0506." "" { target *-*-* } } + *x +} + +fn bar(s: &Box<(i32,)>) -> &'static i32 { + // FIXME(#46983): error message should be better + &s.0 // { dg-error ".E0621." "" { target *-*-* } } +} + +fn main() { + foo(&mut (0,)); + bar(&Box::new((1,))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-16223.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-16223.rs new file mode 100644 index 000000000000..b2a547eaee15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-16223.rs @@ -0,0 +1,53 @@ +// Regression test for #16223: without NLL the `if let` construct together with +// the nested box-structure of `Root` causes an unwanted collateral move. + +// The exact error prevented here is: +// +// error[E0382]: use of collaterally moved value: `(root.boxed.rhs as SomeVariant::B).0` +// --> src/main.rs:55:29 +// | +// 56 | lhs: SomeVariant::A(a), +// | - value moved here +// 57 | rhs: SomeVariant::B(b), +// | ^ value used here after move +// | +// = note: move occurs because the value has type `A`, which does not implement the `Copy` trait + +// check-pass + +#![feature(box_patterns)] + +struct Root { + boxed: Box, +} + +struct SetOfVariants { + lhs: SomeVariant, + rhs: SomeVariant, +} + +enum SomeVariant { + A(A), + B(B), +} + +struct A(String); +struct B(String); + +fn main() { + let root = Root { + boxed: Box::new(SetOfVariants { + lhs: SomeVariant::A(A(String::from("This is A"))), + rhs: SomeVariant::B(B(String::from("This is B"))), + }), + }; + if let box SetOfVariants { + lhs: SomeVariant::A(a), + rhs: SomeVariant::B(b), + } = root.boxed + { + println!("a = {}", a.0); + println!("b = {}", b.0); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-21114-ebfull.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-21114-ebfull.rs new file mode 100644 index 000000000000..92190ba88c2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-21114-ebfull.rs @@ -0,0 +1,19 @@ +// check-pass + +use std::collections::HashMap; +use std::sync::Mutex; + +fn i_used_to_be_able_to(foo: &Mutex>) -> Vec<(usize, usize)> { + let mut foo = foo.lock().unwrap(); + + foo.drain().collect() +} + +fn but_after_nightly_update_now_i_gotta(foo: &Mutex>) -> Vec<(usize, usize)> { + let mut foo = foo.lock().unwrap(); + + return foo.drain().collect(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-21114-kixunil.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-21114-kixunil.rs new file mode 100644 index 000000000000..a8826a51e580 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-21114-kixunil.rs @@ -0,0 +1,18 @@ +// check-pass + +fn from_stdin(min: u64) -> Vec { + use std::io::BufRead; + + let stdin = std::io::stdin(); + let stdin = stdin.lock(); + + stdin.lines() + .map(Result::unwrap) + .map(|val| val.parse()) + .map(Result::unwrap) + .filter(|val| *val >= min) + .collect() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-21232-partial-init-and-erroneous-use.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-21232-partial-init-and-erroneous-use.rs new file mode 100644 index 000000000000..083210710583 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-21232-partial-init-and-erroneous-use.rs @@ -0,0 +1,65 @@ +// This test enumerates various cases of interest where a ADT or tuple is +// partially initialized and then used in some way that is wrong *even* +// after rust-lang/rust#54987 is implemented. +// +// See rust-lang/rust#21232, rust-lang/rust#54986, and rust-lang/rust#54987. +// +// See issue-21232-partial-init-and-use.rs for cases of tests that are +// meant to compile and run successfully once rust-lang/rust#54987 is +// implemented. + +struct D { + x: u32, + s: S, +} + +struct S { + y: u32, + z: u32, +} + + +impl Drop for D { + fn drop(&mut self) { } +} + +fn cannot_partially_init_adt_with_drop() { + let d: D; + d.x = 10; +// { dg-error ".E0381." "" { target *-*-* } .-1 } +} + +fn cannot_partially_init_mutable_adt_with_drop() { + let mut d: D; + d.x = 10; +// { dg-error ".E0381." "" { target *-*-* } .-1 } +} + +fn cannot_partially_reinit_adt_with_drop() { + let mut d = D { x: 0, s: S{ y: 0, z: 0 } }; + drop(d); + d.x = 10; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn cannot_partially_init_inner_adt_via_outer_with_drop() { + let d: D; + d.s.y = 20; +// { dg-error ".E0381." "" { target *-*-* } .-1 } +} + +fn cannot_partially_init_inner_adt_via_mutable_outer_with_drop() { + let mut d: D; + d.s.y = 20; +// { dg-error ".E0381." "" { target *-*-* } .-1 } +} + +fn cannot_partially_reinit_inner_adt_via_outer_with_drop() { + let mut d = D { x: 0, s: S{ y: 0, z: 0} }; + drop(d); + d.s.y = 20; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-21232-partial-init-and-use.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-21232-partial-init-and-use.rs new file mode 100644 index 000000000000..2ce904f1ca9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-21232-partial-init-and-use.rs @@ -0,0 +1,310 @@ +// This test enumerates various cases of interest for partial +// [re]initialization of ADTs and tuples. +// +// See rust-lang/rust#21232, rust-lang/rust#54986, and rust-lang/rust#54987. +// +// All of tests in this file are expected to change from being +// rejected, at least under NLL (by rust-lang/rust#54986) to being +// **accepted** when rust-lang/rust#54987 is implemented. +// (That's why there are assertions in the code.) +// +// See issue-21232-partial-init-and-erroneous-use.rs for cases of +// tests that are meant to continue failing to compile once +// rust-lang/rust#54987 is implemented. + +struct S { + x: u32, + + // Note that even though `y` may implement `Drop`, under #54987 we + // will still allow partial initialization of `S` itself. + y: Y, +} + +enum Void { } + +type B = Box; + +impl S { fn new() -> Self { S { x: 0, y: Box::new(0) } } } + +fn borrow_s(s: &S) { assert_eq!(s.x, 10); assert_eq!(*s.y, 20); } +fn move_s(s: S) { assert_eq!(s.x, 10); assert_eq!(*s.y, 20); } +fn borrow_field(x: &u32) { assert_eq!(*x, 10); } + +type T = (u32, B); +type Tvoid = (u32, Void); + +fn borrow_t(t: &T) { assert_eq!(t.0, 10); assert_eq!(*t.1, 20); } +fn move_t(t: T) { assert_eq!(t.0, 10); assert_eq!(*t.1, 20); } + +struct Q { + v: u32, + r: R, +} + +struct R { + w: u32, + f: F, +} + +impl Q { fn new(f: F) -> Self { Q { v: 0, r: R::new(f) } } } +impl R { fn new(f: F) -> Self { R { w: 0, f } } } + +// Axes to cover: +// * local/field: Is the structure in a local or a field +// * fully/partial/void: Are we fully initializing it before using any part? +// Is whole type empty due to a void component? +// * init/reinit: First initialization, or did we previously inititalize and then move out? +// * struct/tuple: Is this a struct or a (X, Y). +// +// As a shorthand for the cases above, adding a numeric summary to +// each test's fn name to denote each point on each axis. +// +// e.g., 1000 = field fully init struct; 0211 = local void reinit tuple + +// It got pretty monotonous writing the same code over and over, and I +// feared I would forget details. So I abstracted some desiderata into +// macros. But I left the initialization code inline, because that's +// where the errors for #54986 will be emitted. + +macro_rules! use_fully { + (struct $s:expr) => { { + borrow_field(& $s.x ); + borrow_s(& $s ); + move_s( $s ); + } }; + + (tuple $t:expr) => { { + borrow_field(& $t.0 ); + borrow_t(& $t ); + move_t( $t ); + } } +} + +macro_rules! use_part { + (struct $s:expr) => { { + borrow_field(& $s.x ); + match $s { S { ref x, y: _ } => { borrow_field(x); } } + } }; + + (tuple $t:expr) => { { + borrow_field(& $t.0 ); + match $t { (ref x, _) => { borrow_field(x); } } + } } +} + +fn test_0000_local_fully_init_and_use_struct() { + let s: S; + s.x = 10; s.y = Box::new(20); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + use_fully!(struct s); +} + +fn test_0001_local_fully_init_and_use_tuple() { + let t: T; + t.0 = 10; t.1 = Box::new(20); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + use_fully!(tuple t); +} + +fn test_0010_local_fully_reinit_and_use_struct() { + let mut s: S = S::new(); drop(s); + s.x = 10; s.y = Box::new(20); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + use_fully!(struct s); +} + +fn test_0011_local_fully_reinit_and_use_tuple() { + let mut t: T = (0, Box::new(0)); drop(t); + t.0 = 10; t.1 = Box::new(20); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + use_fully!(tuple t); +} + +fn test_0100_local_partial_init_and_use_struct() { + let s: S; + s.x = 10; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + use_part!(struct s); +} + +fn test_0101_local_partial_init_and_use_tuple() { + let t: T; + t.0 = 10; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + use_part!(tuple t); +} + +fn test_0110_local_partial_reinit_and_use_struct() { + let mut s: S = S::new(); drop(s); + s.x = 10; +// { dg-error ".E0382." "" { target *-*-* } .-1 } + use_part!(struct s); +} + +fn test_0111_local_partial_reinit_and_use_tuple() { + let mut t: T = (0, Box::new(0)); drop(t); + t.0 = 10; +// { dg-error ".E0382." "" { target *-*-* } .-1 } + use_part!(tuple t); +} + +fn test_0200_local_void_init_and_use_struct() { + let s: S; + s.x = 10; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + use_part!(struct s); +} + +fn test_0201_local_void_init_and_use_tuple() { + let t: Tvoid; + t.0 = 10; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + use_part!(tuple t); +} + +// NOTE: uniform structure of tests here makes n21n (aka combining +// Void with Reinit) an (even more) senseless case, as we cannot +// safely create initial instance containing Void to move out of and +// then reinitialize. While I was tempted to sidestep this via some +// unsafe code (eek), lets just instead not encode such tests. + +// fn test_0210_local_void_reinit_and_use_struct() { unimplemented!() } +// fn test_0211_local_void_reinit_and_use_tuple() { unimplemented!() } + +fn test_1000_field_fully_init_and_use_struct() { + let q: Q>; + q.r.f.x = 10; q.r.f.y = Box::new(20); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + use_fully!(struct q.r.f); +} + +fn test_1001_field_fully_init_and_use_tuple() { + let q: Q; + q.r.f.0 = 10; q.r.f.1 = Box::new(20); +// { dg-error ".E0381." "" { target *-*-* } .-1 } + use_fully!(tuple q.r.f); +} + +fn test_1010_field_fully_reinit_and_use_struct() { + let mut q: Q> = Q::new(S::new()); drop(q.r); + q.r.f.x = 10; q.r.f.y = Box::new(20); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + use_fully!(struct q.r.f); +} + +fn test_1011_field_fully_reinit_and_use_tuple() { + let mut q: Q = Q::new((0, Box::new(0))); drop(q.r); + q.r.f.0 = 10; q.r.f.1 = Box::new(20); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + use_fully!(tuple q.r.f); +} + +fn test_1100_field_partial_init_and_use_struct() { + let q: Q>; + q.r.f.x = 10; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + use_part!(struct q.r.f); +} + +fn test_1101_field_partial_init_and_use_tuple() { + let q: Q; + q.r.f.0 = 10; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + use_part!(tuple q.r.f); +} + +fn test_1110_field_partial_reinit_and_use_struct() { + let mut q: Q> = Q::new(S::new()); drop(q.r); + q.r.f.x = 10; +// { dg-error ".E0382." "" { target *-*-* } .-1 } + use_part!(struct q.r.f); +} + +fn test_1111_field_partial_reinit_and_use_tuple() { + let mut q: Q = Q::new((0, Box::new(0))); drop(q.r); + q.r.f.0 = 10; +// { dg-error ".E0382." "" { target *-*-* } .-1 } + use_part!(tuple q.r.f); +} + +fn test_1200_field_void_init_and_use_struct() { + let mut q: Q>; + q.r.f.x = 10; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + use_part!(struct q.r.f); +} + +fn test_1201_field_void_init_and_use_tuple() { + let mut q: Q; + q.r.f.0 = 10; +// { dg-error ".E0381." "" { target *-*-* } .-1 } + use_part!(tuple q.r.f); +} + +// See NOTE abve. + +// fn test_1210_field_void_reinit_and_use_struct() { unimplemented!() } +// fn test_1211_field_void_reinit_and_use_tuple() { unimplemented!() } + +// The below are some additional cases of interest that have been +// transcribed from other bugs based on old erroneous codegen when we +// encountered partial writes. + +fn issue_26996() { + let mut c = (1, "".to_owned()); + match c { + c2 => { + c.0 = 2; // { dg-error ".E0382." "" { target *-*-* } } + assert_eq!(c2.0, 1); + } + } +} + +fn issue_27021() { + let mut c = (1, (1, "".to_owned())); + match c { + c2 => { + (c.1).0 = 2; // { dg-error ".E0382." "" { target *-*-* } } + assert_eq!((c2.1).0, 1); + } + } + + let mut c = (1, (1, (1, "".to_owned()))); + match c.1 { + c2 => { + ((c.1).1).0 = 3; // { dg-error ".E0382." "" { target *-*-* } } + assert_eq!((c2.1).0, 1); + } + } +} + +fn main() { + test_0000_local_fully_init_and_use_struct(); + test_0001_local_fully_init_and_use_tuple(); + test_0010_local_fully_reinit_and_use_struct(); + test_0011_local_fully_reinit_and_use_tuple(); + test_0100_local_partial_init_and_use_struct(); + test_0101_local_partial_init_and_use_tuple(); + test_0110_local_partial_reinit_and_use_struct(); + test_0111_local_partial_reinit_and_use_tuple(); + test_0200_local_void_init_and_use_struct(); + test_0201_local_void_init_and_use_tuple(); + // test_0210_local_void_reinit_and_use_struct(); + // test_0211_local_void_reinit_and_use_tuple(); + test_1000_field_fully_init_and_use_struct(); + test_1001_field_fully_init_and_use_tuple(); + test_1010_field_fully_reinit_and_use_struct(); + test_1011_field_fully_reinit_and_use_tuple(); + test_1100_field_partial_init_and_use_struct(); + test_1101_field_partial_init_and_use_tuple(); + test_1110_field_partial_reinit_and_use_struct(); + test_1111_field_partial_reinit_and_use_tuple(); + test_1200_field_void_init_and_use_struct(); + test_1201_field_void_init_and_use_tuple(); + // test_1210_field_void_reinit_and_use_struct(); + // test_1211_field_void_reinit_and_use_tuple(); + + issue_26996(); + issue_27021(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-22323-temp-destruction.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-22323-temp-destruction.rs new file mode 100644 index 000000000000..04ce474d5add --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-22323-temp-destruction.rs @@ -0,0 +1,31 @@ +// rust-lang/rust#22323: regression test demonstrating that NLL +// precisely tracks temporary destruction order. + +// check-pass + +fn main() { + let _s = construct().borrow().consume_borrowed(); +} + +fn construct() -> Value { Value } + +pub struct Value; + +impl Value { + fn borrow<'a>(&'a self) -> Borrowed<'a> { unimplemented!() } +} + +pub struct Borrowed<'a> { + _inner: Guard<'a, Value>, +} + +impl<'a> Borrowed<'a> { + fn consume_borrowed(self) -> String { unimplemented!() } +} + +pub struct Guard<'a, T: ?Sized + 'a> { + _lock: &'a T, +} + +impl<'a, T: ?Sized> Drop for Guard<'a, T> { fn drop(&mut self) {} } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-27868.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-27868.rs new file mode 100644 index 000000000000..c1f309bf666e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-27868.rs @@ -0,0 +1,29 @@ +// Regression test for issue #27868 + +use std::ops::AddAssign; + +struct MyVec(Vec); + +impl Drop for MyVec { + fn drop(&mut self) { + println!("Being dropped."); + } +} + +impl AddAssign for MyVec { + fn add_assign(&mut self, _elem: T) { + println!("In add_assign."); + } +} + +fn main() { + let mut vec = MyVec(vec![0]); + let mut vecvec = vec![vec]; + + vecvec[0] += { + vecvec = vec![]; +// { dg-error ".E0506." "" { target *-*-* } .-1 } + 0 + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-30104.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-30104.rs new file mode 100644 index 000000000000..02c5753267e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-30104.rs @@ -0,0 +1,41 @@ +// Regression test for #30104 + +// check-pass + +use std::ops::{Deref, DerefMut}; + +fn box_two_field(v: &mut Box<(i32, i32)>) { + let _a = &mut v.0; + let _b = &mut v.1; +} + +fn box_destructure(v: &mut Box<(i32, i32)>) { + let (ref mut _head, ref mut _tail) = **v; +} + +struct Wrap(T); + +impl Deref for Wrap { + type Target = T; + fn deref(&self) -> &T { + &self.0 + } +} + +impl DerefMut for Wrap { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +fn smart_two_field(v: &mut Wrap<(i32, i32)>) { + let _a = &mut v.0; + let _b = &mut v.1; +} + +fn smart_destructure(v: &mut Wrap<(i32, i32)>) { + let (ref mut _head, ref mut _tail) = **v; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-31567.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-31567.rs new file mode 100644 index 000000000000..7cf499920c93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-31567.rs @@ -0,0 +1,26 @@ +// Regression test for #31567: cached results of projections were +// causing region relations not to be enforced at all the places where +// they have to be enforced. + +struct VecWrapper<'a>(&'a mut S); + +struct S(Box); + +fn get_dangling<'a>(v: VecWrapper<'a>) -> &'a u32 { + let s_inner: &'a S = &*v.0; // { dg-error ".E0713." "" { target *-*-* } } + &s_inner.0 +} + +impl<'a> Drop for VecWrapper<'a> { + fn drop(&mut self) { + *self.0 = S(Box::new(0)); + } +} + +fn main() { + let mut s = S(Box::new(11)); + let vw = VecWrapper(&mut s); + let dangling = get_dangling(vw); + println!("{}", dangling); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs new file mode 100644 index 000000000000..8efcce52c254 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs @@ -0,0 +1,42 @@ +// check-pass + +// rust-lang/rust#32382: Borrow checker used to complain about +// `foobar_3` in the `impl` below, presumably due to some interaction +// between the use of a lifetime in the associated type and the use of +// the overloaded operator[]. This regression test ensures that we do +// not resume complaining about it in the future. + + +use std::marker::PhantomData; +use std::ops::Index; + +pub trait Context: Clone { + type Container: ?Sized; + fn foobar_1( container: &Self::Container ) -> &str; + fn foobar_2( container: &Self::Container ) -> &str; + fn foobar_3( container: &Self::Container ) -> &str; +} + +#[derive(Clone)] +struct Foobar<'a> { + phantom: PhantomData<&'a ()> +} + +impl<'a> Context for Foobar<'a> { + type Container = [&'a str]; + + fn foobar_1<'r>( container: &'r [&'a str] ) -> &'r str { + container[0] + } + + fn foobar_2<'r>( container: &'r Self::Container ) -> &'r str { + container.index( 0 ) + } + + fn foobar_3<'r>( container: &'r Self::Container ) -> &'r str { + container[0] + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-42574-diagnostic-in-nested-closure.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-42574-diagnostic-in-nested-closure.rs new file mode 100644 index 000000000000..284d885a0777 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-42574-diagnostic-in-nested-closure.rs @@ -0,0 +1,14 @@ +// This test illustrates a case where full NLL (enabled by the feature +// switch below) produces superior diagnostics to the NLL-migrate +// mode. + +#![feature(nll)] + +fn doit(data: &'static mut ()) { + || doit(data); +// { dg-error ".E0597." "" { target *-*-* } .-1 } +// { dg-error ".E0597." "" { target *-*-* } .-2 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-43058.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-43058.rs new file mode 100644 index 000000000000..3c8d886884a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-43058.rs @@ -0,0 +1,27 @@ +// check-pass + +use std::borrow::Cow; + +#[derive(Clone, Debug)] +struct S<'a> { + name: Cow<'a, str> +} + +#[derive(Clone, Debug)] +struct T<'a> { + s: Cow<'a, [S<'a>]> +} + +fn main() { + let s1 = [S { name: Cow::Borrowed("Test1") }, S { name: Cow::Borrowed("Test2") }]; + let b1 = T { s: Cow::Borrowed(&s1) }; + let s2 = [S { name: Cow::Borrowed("Test3") }, S { name: Cow::Borrowed("Test4") }]; + let b2 = T { s: Cow::Borrowed(&s2) }; + + let mut v = Vec::new(); + v.push(b1); + v.push(b2); + + println!("{:?}", v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-46589.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-46589.rs new file mode 100644 index 000000000000..dbb0b552c94a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-46589.rs @@ -0,0 +1,32 @@ +// This tests passes in Polonius mode, so is skipped in the automated compare-mode. +// We will manually check it passes in Polonius tests, as we can't have a test here +// which conditionally passes depending on a test revision/compile-flags. + +// ignore-compare-mode-polonius + +struct Foo; + +impl Foo { + fn get_self(&mut self) -> Option<&mut Self> { + Some(self) + } + + fn new_self(&mut self) -> &mut Self { + self + } + + fn trigger_bug(&mut self) { + let other = &mut (&mut *self); + + *other = match (*other).get_self() { + Some(s) => s, + None => (*other).new_self() +// { dg-error ".E0499." "" { target *-*-* } .-1 } + }; + + let c = other; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-47022.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-47022.rs new file mode 100644 index 000000000000..89b4c4c03e15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-47022.rs @@ -0,0 +1,34 @@ +// check-pass + +struct LoadedObject { + bodies: Vec, + color: Color, +} + +struct Body; + +#[derive(Clone)] +struct Color; + +struct Graphic { + color: Color, +} + +fn convert(objects: Vec) -> (Vec, Vec) { + objects + .into_iter() + .flat_map(|LoadedObject { bodies, color, .. }| { + bodies.into_iter().map(move |body| { + ( + body, + Graphic { + color: color.clone(), + }, + ) + }) + }) + .unzip() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-47153-generic-const.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-47153-generic-const.rs new file mode 100644 index 000000000000..5e8e1e3ca33c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-47153-generic-const.rs @@ -0,0 +1,19 @@ +// run-pass + +// Regression test for #47153: constants in a generic context (such as +// a trait) used to ICE. + +#![allow(warnings)] + +trait Foo { + const B: bool = true; +} + +struct Bar { x: T } + +impl Bar { + const B: bool = true; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-47388.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-47388.rs new file mode 100644 index 000000000000..d908f4b0f888 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-47388.rs @@ -0,0 +1,11 @@ +struct FancyNum { + num: u8, +} + +fn main() { + let mut fancy = FancyNum{ num: 5 }; + let fancy_ref = &(&mut fancy); + fancy_ref.num = 6; // { dg-error ".E0594." "" { target *-*-* } } + println!("{}", fancy_ref.num); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-47470.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-47470.rs new file mode 100644 index 000000000000..3e08a837a8b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-47470.rs @@ -0,0 +1,23 @@ +// Regression test for #47470: cached results of projections were +// causing region relations not to be enforced at all the places where +// they have to be enforced. + +struct Foo<'a>(&'a ()); +trait Bar { + type Assoc; + fn get(self) -> Self::Assoc; +} + +impl<'a> Bar for Foo<'a> { + type Assoc = &'a u32; + fn get(self) -> Self::Assoc { + let local = 42; + &local // { dg-error ".E0515." "" { target *-*-* } } + } +} + +fn main() { + let f = Foo(&()).get(); + println!("{}", f); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-47589.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-47589.rs new file mode 100644 index 000000000000..2bb4094f53d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-47589.rs @@ -0,0 +1,24 @@ +// run-pass + +pub struct DescriptorSet<'a> { + pub slots: Vec> +} + +pub trait ResourcesTrait<'r>: Sized { + type DescriptorSet: 'r; +} + +pub struct Resources; + +impl<'a> ResourcesTrait<'a> for Resources { + type DescriptorSet = DescriptorSet<'a>; +} + +pub enum AttachInfo<'a, R: ResourcesTrait<'a>> { + NextDescriptorSet(Box) +} + +fn main() { + let _x = DescriptorSet {slots: Vec::new()}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-48070.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-48070.rs new file mode 100644 index 000000000000..855727614f3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-48070.rs @@ -0,0 +1,24 @@ +// run-pass +// revisions: lxl nll + +struct Foo { + x: u32 +} + +impl Foo { + fn twiddle(&mut self) -> &mut Self { self } + fn twaddle(&mut self) -> &mut Self { self } + fn emit(&mut self) { + self.x += 1; + } +} + +fn main() { + let mut foo = Foo { x: 0 }; + match 22 { + 22 => &mut foo, + 44 => foo.twiddle(), + _ => foo.twaddle(), + }.emit(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-48238.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-48238.rs new file mode 100644 index 000000000000..0e42b0fa970a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-48238.rs @@ -0,0 +1,11 @@ +// Regression test for issue #48238 + +fn use_val<'a>(val: &'a u8) -> &'a u8 { + val +} + +fn main() { + let orig: u8 = 5; + move || use_val(&orig); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-48623-closure.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-48623-closure.rs new file mode 100644 index 000000000000..7b6fbad1a147 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-48623-closure.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(path_statements)] +#![allow(dead_code)] + +struct WithDrop; + +impl Drop for WithDrop { + fn drop(&mut self) {} +} + +fn reborrow_from_closure(r: &mut ()) -> &mut () { + let d = WithDrop; + (move || { d; &mut *r })() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-48623-generator.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-48623-generator.rs new file mode 100644 index 000000000000..57bf4107f648 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-48623-generator.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(path_statements)] +#![allow(dead_code)] + +#![feature(generators, generator_trait)] + +struct WithDrop; + +impl Drop for WithDrop { + fn drop(&mut self) {} +} + +fn reborrow_from_generator(r: &mut ()) { + let d = WithDrop; + move || { d; yield; &mut *r }; // { dg-warning "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-48697.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-48697.rs new file mode 100644 index 000000000000..2147ee86bfd9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-48697.rs @@ -0,0 +1,11 @@ +// Regression test for #48697 + +fn foo(x: &i32) -> &i32 { + let z = 4; + let f = &|y| y; + let k = f(&z); + f(x) // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-50343.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-50343.rs new file mode 100644 index 000000000000..78ad6595573d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-50343.rs @@ -0,0 +1,9 @@ +// run-pass + +#![deny(unused_mut)] + +fn main() { + vec![42].iter().map(drop).count(); + vec![(42, 22)].iter().map(|(_x, _y)| ()).count(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-50461-used-mut-from-moves.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-50461-used-mut-from-moves.rs new file mode 100644 index 000000000000..cb5b48dab388 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-50461-used-mut-from-moves.rs @@ -0,0 +1,17 @@ +// run-pass + +#![deny(unused_mut)] + +struct Foo { + pub value: i32 +} + +fn use_foo_mut(mut foo: Foo) { + foo = foo; + println!("{}", foo.value); +} + +fn main() { + use_foo_mut(Foo { value: 413 }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-50716-1.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-50716-1.rs new file mode 100644 index 000000000000..8b216d514e15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-50716-1.rs @@ -0,0 +1,11 @@ +// +// An additional regression test for the issue #50716 “NLL ignores lifetimes +// bounds derived from `Sized` requirements” that checks that the fixed compiler +// accepts this code fragment with both AST and MIR borrow checkers. +// +// check-pass + +struct Qey(Q); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-50716.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-50716.rs new file mode 100644 index 000000000000..874c3a716e88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-50716.rs @@ -0,0 +1,18 @@ +// +// Regression test for the issue #50716: NLL ignores lifetimes bounds +// derived from `Sized` requirements + +trait A { + type X: ?Sized; +} + +fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) +where + for<'b> &'b T: A, + <&'static T as A>::X: Sized +{ + let _x = *s; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-51191.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-51191.rs new file mode 100644 index 000000000000..41e107217c54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-51191.rs @@ -0,0 +1,32 @@ +struct Struct; + +impl Struct { + fn bar(self: &mut Self) { +// { dg-warning "" "" { target *-*-* } .-1 } + (&mut self).bar(); +// { dg-error ".E0596." "" { target *-*-* } .-1 } + } + + fn imm(self) { + (&mut self).bar(); +// { dg-error ".E0596." "" { target *-*-* } .-1 } + } + + fn mtbl(mut self) { + (&mut self).bar(); + } + + fn immref(&self) { + (&mut self).bar(); +// { dg-error ".E0596." "" { target *-*-* } .-1 } +// { dg-error ".E0596." "" { target *-*-* } .-2 } + } + + fn mtblref(&mut self) { + (&mut self).bar(); +// { dg-error ".E0596." "" { target *-*-* } .-1 } + } +} + +fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-51244.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-51244.rs new file mode 100644 index 000000000000..11bbebad65eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-51244.rs @@ -0,0 +1,6 @@ +fn main() { + let ref my_ref @ _ = 0; + *my_ref = 0; +// { dg-error ".E0594." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-51268.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-51268.rs new file mode 100644 index 000000000000..601a36bd6c4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-51268.rs @@ -0,0 +1,24 @@ +// ignore-tidy-linelength + +struct Bar; + +impl Bar { + fn bar(&mut self, _: impl Fn()) {} +} + +struct Foo { + thing: Bar, + number: usize, +} + +impl Foo { + fn foo(&mut self) { + self.thing.bar(|| { +// { dg-error ".E0502." "" { target *-*-* } .-1 } + &self.number; + }); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-51351.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-51351.rs new file mode 100644 index 000000000000..7a1fa6bdb14b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-51351.rs @@ -0,0 +1,22 @@ +// +// Regression test for #51351 and #52133: In the case of #51351, +// late-bound regions (like 'a) that were unused within the arguments of +// a function were overlooked and could case an ICE. In the case of #52133, +// LBR defined on the creator function needed to be added to the free regions +// of the closure, as they were not present in the closure's generic +// declarations otherwise. +// +// check-pass + +fn creash<'a>() { + let x: &'a () = &(); +} + +fn produce<'a>() { + move || { + let x: &'a () = &(); + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-51512.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-51512.rs new file mode 100644 index 000000000000..8f52a8f8bc8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-51512.rs @@ -0,0 +1,7 @@ +fn main() { + let range = 0..1; + let r = range; + let x = range.start; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs new file mode 100644 index 000000000000..1a2668567de0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-52059-report-when-borrow-and-drop-conflict.rs @@ -0,0 +1,31 @@ +// rust-lang/rust#52059: Regardless of whether you are moving out of a +// Drop type or just introducing an inadvertent alias via a borrow of +// one of its fields, it is useful to be reminded of the significance +// of the fact that the type implements Drop. + +pub struct S<'a> { url: &'a mut String } + +impl<'a> Drop for S<'a> { fn drop(&mut self) { } } + +fn finish_1(s: S) -> &mut String { + s.url +} +// { dg-error ".E0713." "" { target *-*-* } .-2 } + +fn finish_2(s: S) -> &mut String { + let p = &mut *s.url; p +} +// { dg-error ".E0713." "" { target *-*-* } .-2 } + +fn finish_3(s: S) -> &mut String { + let p: &mut _ = s.url; p +} +// { dg-error ".E0713." "" { target *-*-* } .-2 } + +fn finish_4(s: S) -> &mut String { + let p = s.url; p +} +// { dg-error ".E0509." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-52078.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-52078.rs new file mode 100644 index 000000000000..a84118ac11a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-52078.rs @@ -0,0 +1,25 @@ +// Regression test for #52078: we were failing to infer a relationship +// between `'a` and `'b` below due to inference variables introduced +// during the normalization process. +// +// check-pass + +struct Drain<'a, T: 'a> { + _marker: ::std::marker::PhantomData<&'a T>, +} + +trait Join { + type Value; + fn get(value: &mut Self::Value); +} + +impl<'a, T> Join for Drain<'a, T> { + type Value = &'a mut Option; + + fn get<'b>(value: &'b mut Self::Value) { + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-52086.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-52086.rs new file mode 100644 index 000000000000..e3d3c9c7c528 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-52086.rs @@ -0,0 +1,15 @@ +use std::rc::Rc; +use std::sync::Arc; + +struct Bar { field: Vec } + +fn main() { + let x = Rc::new(Bar { field: vec![] }); + drop(x.field); +// { dg-error ".E0507." "" { target *-*-* } .-1 } + + let y = Arc::new(Bar { field: vec![] }); + drop(y.field); +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-52113.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-52113.rs new file mode 100644 index 000000000000..ee989817bc6c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-52113.rs @@ -0,0 +1,38 @@ +#![feature(nll)] + +trait Bazinga {} +impl Bazinga for F {} + +fn produce1<'a>(data: &'a u32) -> impl Bazinga + 'a { + let x = move || { + let _data: &'a u32 = data; + }; + x +} + +fn produce2<'a>(data: &'a mut Vec<&'a u32>, value: &'a u32) -> impl Bazinga + 'a { + let x = move || { + let value: &'a u32 = value; + data.push(value); + }; + x +} + +fn produce3<'a, 'b: 'a>(data: &'a mut Vec<&'a u32>, value: &'b u32) -> impl Bazinga + 'a { + let x = move || { + let value: &'a u32 = value; + data.push(value); + }; + x +} + +fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> impl Bazinga + 'b { + let x = move || { + let value: &'a u32 = value; + data.push(value); + }; + x // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-52534-1.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-52534-1.rs new file mode 100644 index 000000000000..519f506f6a3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-52534-1.rs @@ -0,0 +1,49 @@ +struct Test; + +impl Test { + fn bar(&self, x: &u32) -> &u32 { + let x = 22; + &x +// { dg-error ".E0515." "" { target *-*-* } .-1 } + } +} + +fn foo(x: &u32) -> &u32 { + let x = 22; + &x +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +fn baz(x: &u32) -> &&u32 { + let x = 22; + &&x +// { dg-error ".E0515." "" { target *-*-* } .-1 } +// { dg-error ".E0515." "" { target *-*-* } .-2 } +} + +fn foobazbar<'a>(x: u32, y: &'a u32) -> &'a u32 { + let x = 22; + &x +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +fn foobar<'a>(x: &'a u32) -> &'a u32 { + let x = 22; + &x +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +fn foobaz<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 { + let x = 22; + &x +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +fn foobarbaz<'a, 'b>(x: &'a u32, y: &'b u32, z: &'a u32) -> &'a u32 { + let x = 22; + &x +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-52534-2.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-52534-2.rs new file mode 100644 index 000000000000..3f7bb8491ce0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-52534-2.rs @@ -0,0 +1,15 @@ +fn foo(x: &u32) -> &u32 { + let y; + + { + let x = 32; + y = &x +// { dg-error ".E0597." "" { target *-*-* } .-1 } + } + + println!("{}", y); + x +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-52534.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-52534.rs new file mode 100644 index 000000000000..a4968ab468da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-52534.rs @@ -0,0 +1,20 @@ +fn foo(_: impl FnOnce(&u32) -> &u32) { +} + +fn baz(_: impl FnOnce(&u32, u32) -> &u32) { +} + +fn bar() { + let x = 22; + foo(|a| &x) +// { dg-error ".E0597." "" { target *-*-* } .-1 } +} + +fn foobar() { + let y = 22; + baz(|first, second| &y) +// { dg-error ".E0597." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-52663-span-decl-captured-variable.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-52663-span-decl-captured-variable.rs new file mode 100644 index 000000000000..23275c3baf63 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-52663-span-decl-captured-variable.rs @@ -0,0 +1,12 @@ +fn expect_fn(f: F) where F : Fn() { + f(); +} + +fn main() { + { + let x = (vec![22], vec![44]); + expect_fn(|| drop(x.0)); +// { dg-error ".E0507." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-52663-trait-object.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-52663-trait-object.rs new file mode 100644 index 000000000000..380944a1517b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-52663-trait-object.rs @@ -0,0 +1,17 @@ +#![feature(box_syntax)] + +trait Foo { fn get(&self); } + +impl Foo for A { + fn get(&self) { } +} + +fn main() { + let _ = { + let tmp0 = 3; + let tmp1 = &tmp0; + box tmp1 as Box + }; +// { dg-error ".E0597." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-52669.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-52669.rs new file mode 100644 index 000000000000..2842f9aac2f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-52669.rs @@ -0,0 +1,18 @@ +struct A { + b: B, +} + +#[derive(Clone)] +struct B; + +fn foo(_: A) {} + +fn bar(mut a: A) -> B { + a.b = B; + foo(a); + a.b.clone() +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-52742.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-52742.rs new file mode 100644 index 000000000000..ab39c5d6f752 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-52742.rs @@ -0,0 +1,20 @@ +#![feature(in_band_lifetimes)] + +struct Foo<'a, 'b> { + x: &'a u32, + y: &'b u32, +} + +struct Bar<'b> { + z: &'b u32, +} + +impl Foo<'_, '_> { + fn take_bar(&mut self, b: Bar<'_>) { + self.y = b.z +// { dg-error ".E0312." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-53040.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-53040.rs new file mode 100644 index 000000000000..b7683b128d19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-53040.rs @@ -0,0 +1,6 @@ +fn main() { + let mut v: Vec<()> = Vec::new(); + || &mut v; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-53119.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-53119.rs new file mode 100644 index 000000000000..f75e32a80b06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-53119.rs @@ -0,0 +1,24 @@ +// check-pass + +use std::ops::Deref; + +pub struct TypeFieldIterator<'a, T: 'a> { + _t: &'a T, +} + +pub struct Type { + _types: Vec<(Id, T)>, +} + +impl<'a, Id: 'a, T> Iterator for TypeFieldIterator<'a, T> +where T: Deref> { + type Item = &'a (Id, T); + + fn next(&mut self) -> Option<&'a (Id, T)> { + || self.next(); + None + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-53123-raw-pointer-cast.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-53123-raw-pointer-cast.rs new file mode 100644 index 000000000000..8680f49c7ec9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-53123-raw-pointer-cast.rs @@ -0,0 +1,27 @@ +// run-pass + +#![allow(unused_variables)] + +pub trait TryTransform { + fn try_transform(self, f: F) + where + Self: Sized, + F: FnOnce(Self); +} + +impl<'a, T> TryTransform for &'a mut T { + fn try_transform(self, f: F) + where + // The bug was that `Self: Sized` caused the lifetime of `this` to "extend" for all + // of 'a instead of only lasting as long as the binding is used (for just that line). + Self: Sized, + F: FnOnce(Self), + { + let this: *mut T = self as *mut T; + f(self); + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-53570.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-53570.rs new file mode 100644 index 000000000000..102079958f97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-53570.rs @@ -0,0 +1,33 @@ +// Regression test for #53570. Here, we need to propagate that `T: 'a` +// but in some versions of NLL we were propagating a stronger +// requirement that `T: 'static`. This arose because we actually had +// to propagate both that `T: 'a` but also `T: 'b` where `'b` is the +// higher-ranked lifetime that appears in the type of the closure +// parameter `x` -- since `'b` cannot be expressed in the caller's +// space, that got promoted th `'static`. +// +// check-pass + +use std::cell::{RefCell, Ref}; + +trait AnyVec<'a> { +} + +trait GenericVec { + fn unwrap<'a, 'b>(vec: &'b dyn AnyVec<'a>) -> &'b [T] where T: 'a; +} + +struct Scratchpad<'a> { + buffers: RefCell>>, +} + +impl<'a> Scratchpad<'a> { + fn get>(&self) -> Ref<[T]> + where T: 'a + { + Ref::map(self.buffers.borrow(), |x| T::unwrap(x.as_ref())) + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-53773.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-53773.rs new file mode 100644 index 000000000000..5e9f8cdaba88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-53773.rs @@ -0,0 +1,48 @@ +struct Archive; +struct ArchiveIterator<'a> { + x: &'a Archive, +} +struct ArchiveChild<'a> { + x: &'a Archive, +} + +struct A { + raw: &'static mut Archive, +} +struct Iter<'a> { + raw: &'a mut ArchiveIterator<'a>, +} +struct C<'a> { + raw: &'a mut ArchiveChild<'a>, +} + +impl A { + pub fn iter(&self) -> Iter<'_> { + panic!() + } +} +impl Drop for A { + fn drop(&mut self) {} +} +impl<'a> Drop for C<'a> { + fn drop(&mut self) {} +} + +impl<'a> Iterator for Iter<'a> { + type Item = C<'a>; + fn next(&mut self) -> Option> { + panic!() + } +} + +fn error(archive: &A) { + let mut members: Vec<&mut ArchiveChild<'_>> = vec![]; + for child in archive.iter() { + members.push(child.raw); +// { dg-error ".E0713." "" { target *-*-* } .-1 } + } + members.len(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-53807.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-53807.rs new file mode 100644 index 000000000000..eb0bd3f21357 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-53807.rs @@ -0,0 +1,9 @@ +pub fn main(){ + let maybe = Some(vec![true, true]); + loop { + if let Some(thing) = maybe { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-54382-use-span-of-tail-of-block.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-54382-use-span-of-tail-of-block.rs new file mode 100644 index 000000000000..46745482d78b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-54382-use-span-of-tail-of-block.rs @@ -0,0 +1,30 @@ +fn main() { + { + let mut _thing1 = D(Box::new("thing1")); + { + let _thing2 = D("thing2"); + side_effects(); + D("other").next(&_thing1) +// { dg-error ".E0597." "" { target *-*-* } .-1 } + } + } + + ; +} + +#[derive(Debug)] +struct D(T); + +impl Drop for D { + fn drop(&mut self) { + println!("dropping {:?})", self); + } +} + +impl D { + fn next(&self, _other: U) -> D { D(_other) } + fn end(&self) { } +} + +fn side_effects() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-54556-niconii.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-54556-niconii.rs new file mode 100644 index 000000000000..60a18dec09cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-54556-niconii.rs @@ -0,0 +1,32 @@ +// This is a reduction of a concrete test illustrating a case that was +// annoying to Rust developer niconii (see comment thread on #21114). +// +// With resolving issue #54556, pnkfelix hopes that the new diagnostic +// output produced by NLL helps to *explain* the semantic significance +// of temp drop order, and thus why inserting a semi-colon after the +// `if let` expression in `main` works. + +struct Mutex; +struct MutexGuard<'a>(&'a Mutex); + +impl Drop for Mutex { fn drop(&mut self) { println!("Mutex::drop"); } } +impl<'a> Drop for MutexGuard<'a> { fn drop(&mut self) { println!("MutexGuard::drop"); } } + +impl Mutex { + fn lock(&self) -> Result { Ok(MutexGuard(self)) } +} + +fn main() { + let counter = Mutex; + + if let Ok(_) = counter.lock() { } // { dg-error ".E0597." "" { target *-*-* } } + + // With this code as written, the dynamic semantics here implies + // that `Mutex::drop` for `counter` runs *before* + // `MutexGuard::drop`, which would be unsound since `MutexGuard` + // still has a reference to `counter`. + // + // The goal of #54556 is to explain that within a compiler + // diagnostic. +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-54556-stephaneyfx.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-54556-stephaneyfx.rs new file mode 100644 index 000000000000..b493ed140d2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-54556-stephaneyfx.rs @@ -0,0 +1,36 @@ +// This is a reduction of a concrete test illustrating a case that was +// annoying to Rust developer stephaneyfx (see issue #46413). +// +// With resolving issue #54556, pnkfelix hopes that the new diagnostic +// output produced by NLL helps to *explain* the semantic significance +// of temp drop order, and thus why storing the result in `x` and then +// returning `x` works. + +pub struct Statement; + +pub struct Rows<'stmt>(&'stmt Statement); + +impl<'stmt> Drop for Rows<'stmt> { + fn drop(&mut self) {} +} + +impl<'stmt> Iterator for Rows<'stmt> { + type Item = String; + + fn next(&mut self) -> Option { + None + } +} + +fn get_names() -> Option { + let stmt = Statement; + let rows = Rows(&stmt); // { dg-error ".E0597." "" { target *-*-* } } + rows.map(|row| row).next() + // let x = rows.map(|row| row).next(); + // x + // + // Removing the map works too as does removing the Drop impl. +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-54556-temps-in-tail-diagnostic.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-54556-temps-in-tail-diagnostic.rs new file mode 100644 index 000000000000..44d4f7a3d707 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-54556-temps-in-tail-diagnostic.rs @@ -0,0 +1,24 @@ +fn main() { + { + let mut _thing1 = D(Box::new("thing1")); + // D("other").next(&_thing1).end() + D(&_thing1).end() // { dg-error ".E0597." "" { target *-*-* } } + } + + ; +} + +#[derive(Debug)] +struct D(T); + +impl Drop for D { + fn drop(&mut self) { + println!("dropping {:?})", self); + } +} + +impl D { + fn next(&self, _other: U) -> D { D(_other) } + fn end(&self) { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-54556-used-vs-unused-tails.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-54556-used-vs-unused-tails.rs new file mode 100644 index 000000000000..94879f20060e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-54556-used-vs-unused-tails.rs @@ -0,0 +1,57 @@ +// This test case is exploring the space of how blocks with tail +// expressions and statements can be composed, trying to keep each +// case on one line so that we can compare them via a vertical scan +// with the human eye. + +// Each comment on the right side of the line is summarizing the +// expected suggestion from the diagnostic for issue #54556. + +fn main() { + { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } ; // suggest `;` +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + { { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } } ; // suggest `;` +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + { { let mut _t1 = D(Box::new("t1")); D(&_t1).end() }; } // suggest `;` +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + let _ = { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } ; // suggest `;` +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + let _u = { let mut _t1 = D(Box::new("t1")); D(&_t1).unit() } ; // suggest `;` +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + let _x = { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } ; // `let x = ...; x` +// { dg-error ".E0597." "" { target *-*-* } .-1 } + let _x = { let mut _t1 = D(Box::new("t1")); let x = D(&_t1).end(); x } ; // no error + + let mut _y; + _y = { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } ; // `let x = ...; x` +// { dg-error ".E0597." "" { target *-*-* } .-1 } + _y = { let mut _t1 = D(Box::new("t1")); let x = D(&_t1).end(); x } ; // no error +} + +fn f_param_ref(_t1: D>) { D(&_t1).unit() } // no error + +fn f_local_ref() { let mut _t1 = D(Box::new("t1")); D(&_t1).unit() } // suggest `;` +// { dg-error ".E0597." "" { target *-*-* } .-1 } + +fn f() -> String { let mut _t1 = D(Box::new("t1")); D(&_t1).end() } // `let x = ...; x` +// { dg-error ".E0597." "" { target *-*-* } .-1 } + +#[derive(Debug)] +struct D(T); + +impl Drop for D { + fn drop(&mut self) { + println!("dropping {:?})", self); + } +} + +impl D { + fn next(&self, _other: U) -> D { D(_other) } + fn end(&self) -> String { format!("End({:?})", self.0) } + fn unit(&self) { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-54556-wrap-it-up.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-54556-wrap-it-up.rs new file mode 100644 index 000000000000..29d6dff45644 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-54556-wrap-it-up.rs @@ -0,0 +1,29 @@ +// This is testing how the diagnostic from issue #54556 behaves when +// the destructor code is attached to a place held in a field of the +// temporary being dropped. +// +// Eventually it would be nice if the diagnostic would actually report +// that specific place and its type that implements the `Drop` trait. +// But for the short term, it is acceptable to just print out the +// whole type of the temporary. + +#![allow(warnings)] + +struct Wrap<'p> { p: &'p mut i32 } + +impl<'p> Drop for Wrap<'p> { + fn drop(&mut self) { + *self.p += 1; + } +} + +struct Foo<'p> { a: String, b: Wrap<'p> } + +fn main() { + let mut x = 0; + let wrap = Wrap { p: &mut x }; + let s = String::from("str"); + let foo = Foo { a: s, b: wrap }; + x = 1; // { dg-error ".E0506." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-55288.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-55288.rs new file mode 100644 index 000000000000..c90402574f92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-55288.rs @@ -0,0 +1,10 @@ +// check-pass + +struct Slice(&'static [&'static [u8]]); + +static MAP: Slice = Slice(&[ + b"CloseEvent" as &'static [u8], +]); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-55344.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-55344.rs new file mode 100644 index 000000000000..9e5faa151e82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-55344.rs @@ -0,0 +1,15 @@ +// check-pass + +#![deny(unused_mut)] + +pub fn foo() { + return; + + let mut v = 0; + assert_eq!(v, 0); + v = 1; + assert_eq!(v, 1); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-55394.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-55394.rs new file mode 100644 index 000000000000..ca1582236df6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-55394.rs @@ -0,0 +1,14 @@ +struct Bar; + +struct Foo<'s> { + bar: &'s mut Bar, +} + +impl Foo<'_> { + fn new(bar: &mut Bar) -> Self { + Foo { bar } // { dg-error ".E0495." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-55401.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-55401.rs new file mode 100644 index 000000000000..7fe32d4a370b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-55401.rs @@ -0,0 +1,7 @@ +fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u32 { + let (ref y, _z): (&'a u32, u32) = (&22, 44); + *y // { dg-error ".E0312." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-55651.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-55651.rs new file mode 100644 index 000000000000..9689c51b6e79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-55651.rs @@ -0,0 +1,29 @@ +// check-pass + +#![feature(untagged_unions)] + +struct A; +struct B; + +union U { + a: A, + b: B, +} + +fn main() { + unsafe { + { + let mut u = U { a: A }; + let a = u.a; + u.a = A; + let a = u.a; // OK + } + { + let mut u = U { a: A }; + let a = u.a; + u.b = B; + let a = u.a; // OK + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-55850.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-55850.rs new file mode 100644 index 000000000000..8982b39f7323 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-55850.rs @@ -0,0 +1,36 @@ +#![allow(unused_mut)] +#![feature(generators, generator_trait)] + +use std::marker::Unpin; +use std::ops::Generator; +use std::ops::GeneratorState::Yielded; +use std::pin::Pin; + +pub struct GenIter(G); + +impl Iterator for GenIter +where + G: Generator + Unpin, +{ + type Item = G::Yield; + + fn next(&mut self) -> Option { + match Pin::new(&mut self.0).resume(()) { + Yielded(y) => Some(y), + _ => None + } + } +} + +fn bug<'a>() -> impl Iterator { + GenIter(move || { + let mut s = String::new(); + yield &s[..] // { dg-error ".E0626." "" { target *-*-* } } +// { dg-error ".E0626." "" { target *-*-* } .-2 } + }) +} + +fn main() { + bug(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-57100.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-57100.rs new file mode 100644 index 000000000000..37ced76bc574 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-57100.rs @@ -0,0 +1,69 @@ +#![allow(unused)] + +// ignore-tidy-linelength + +// This tests the error messages for borrows of union fields when the unions are embedded in other +// structs or unions. + +#[derive(Clone, Copy, Default)] +struct Leaf { + l1_u8: u8, + l2_u8: u8, +} + +#[derive(Clone, Copy)] +union First { + f1_leaf: Leaf, + f2_leaf: Leaf, + f3_union: Second, +} + +#[derive(Clone, Copy)] +union Second { + s1_leaf: Leaf, + s2_leaf: Leaf, +} + +struct Root { + r1_u8: u8, + r2_union: First, +} + +// Borrow a different field of the nested union. +fn nested_union() { + unsafe { + let mut r = Root { + r1_u8: 3, + r2_union: First { f3_union: Second { s2_leaf: Leaf { l1_u8: 8, l2_u8: 4 } } } + }; + + let mref = &mut r.r2_union.f3_union.s1_leaf.l1_u8; + // ^^^^^^^ + *mref = 22; + let nref = &r.r2_union.f3_union.s2_leaf.l1_u8; + // ^^^^^^^ +// { dg-error ".E0502." "" { target *-*-* } .-2 } + println!("{} {}", mref, nref) + } +} + +// Borrow a different field of the first union. +fn first_union() { + unsafe { + let mut r = Root { + r1_u8: 3, + r2_union: First { f3_union: Second { s2_leaf: Leaf { l1_u8: 8, l2_u8: 4 } } } + }; + + let mref = &mut r.r2_union.f2_leaf.l1_u8; + // ^^^^^^^ + *mref = 22; + let nref = &r.r2_union.f1_leaf.l1_u8; + // ^^^^^^^ +// { dg-error ".E0502." "" { target *-*-* } .-2 } + println!("{} {}", mref, nref) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-57265-return-type-wf-check.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-57265-return-type-wf-check.rs new file mode 100644 index 000000000000..ad1a2fec3c9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-57265-return-type-wf-check.rs @@ -0,0 +1,25 @@ +use std::any::Any; + +#[derive(Debug, Clone)] +struct S(T); + +// S<&'a T> is in the return type, so we get an implied bound +// &'a T: 'static +fn foo<'a, T>(x: &'a T) -> (S<&'a T>, Box) { + let y = S(x); + + let z = Box::new(y.clone()) as Box; + (y, z) +} + +fn main() { + let x = 5; + + // Check that we require that the argument is of type `&'static String`, + // so that the return type is well-formed. + let (_, z) = foo(&"hello".to_string()); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + + println!("{:?}", z.downcast_ref::>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-57280-1.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-57280-1.rs new file mode 100644 index 000000000000..65cfcfdc056f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-57280-1.rs @@ -0,0 +1,20 @@ +// check-pass + +trait Foo<'a> { + const C: &'a u32; +} + +impl<'a, T> Foo<'a> for T { + const C: &'a u32 = &22; +} + +fn foo() { + let a = 22; + match &a { + <() as Foo<'static>>::C => { } + &_ => { } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-57280.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-57280.rs new file mode 100644 index 000000000000..f950bbb4c670 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-57280.rs @@ -0,0 +1,21 @@ +// check-pass + +trait Foo { + const BLAH: &'static str; +} + +struct Placeholder; + +impl Foo for Placeholder { + const BLAH: &'static str = "hi"; +} + +fn foo(x: &str) { + match x { + ::BLAH => { } + _ => { } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-57642-higher-ranked-subtype.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-57642-higher-ranked-subtype.rs new file mode 100644 index 000000000000..f035a3afd6cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-57642-higher-ranked-subtype.rs @@ -0,0 +1,42 @@ +// Regression test for issue #57642 +// Tests that we reject a bad higher-ranked subtype +// with `#![feature(nll)]` + +#![feature(nll)] + +trait X { + type G; + fn make_g() -> Self::G; +} + +impl<'a> X for fn(&'a ()) { + type G = &'a (); + + fn make_g() -> Self::G { + &() + } +} + +trait Y { + type F; + fn make_f() -> Self::F; +} + +impl Y for fn(T) { + type F = fn(T); + + fn make_f() -> Self::F { + |_| {} + } +} + +fn higher_ranked_region_has_lost_its_binder() { + let x = ::make_g(); // { dg-error ".E0599." "" { target *-*-* } } +} + +fn magical() { + let x = ::make_f(); // { dg-error ".E0599." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-57960.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-57960.rs new file mode 100644 index 000000000000..3ba60461b565 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-57960.rs @@ -0,0 +1,39 @@ +// run-pass + +#![allow(dead_code)] + +trait Range { + const FIRST: u8; + const LAST: u8; +} + +struct OneDigit; +impl Range for OneDigit { + const FIRST: u8 = 0; + const LAST: u8 = 9; +} + +struct TwoDigits; +impl Range for TwoDigits { + const FIRST: u8 = 10; + const LAST: u8 = 99; +} + +struct ThreeDigits; +impl Range for ThreeDigits { + const FIRST: u8 = 100; + const LAST: u8 = 255; +} + +fn digits(x: u8) -> u32 { + match x { + OneDigit::FIRST..=OneDigit::LAST => 1, + TwoDigits::FIRST..=TwoDigits::LAST => 2, + ThreeDigits::FIRST..=ThreeDigits::LAST => 3, + } +} + +fn main() { + assert_eq!(digits(100), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-57989.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-57989.rs new file mode 100644 index 000000000000..324d36e941d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-57989.rs @@ -0,0 +1,11 @@ +// Test for ICE from issue 57989 + +fn f(x: &i32) { + let g = &x; + *x = 0; // { dg-error ".E0506." "" { target *-*-* } } +// { dg-error ".E0506." "" { target *-*-* } .-2 } + g; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-58053.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-58053.rs new file mode 100644 index 000000000000..da650b4c6f4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-58053.rs @@ -0,0 +1,14 @@ +#![feature(nll)] + +fn main() { + let i = &3; + + let f = |x: &i32| -> &i32 { x }; +// { dg-error "" "" { target *-*-* } .-1 } + let j = f(i); + + let g = |x: &i32| { x }; +// { dg-error "" "" { target *-*-* } .-1 } + let k = g(i); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-58299.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-58299.rs new file mode 100644 index 000000000000..6269c623ec28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-58299.rs @@ -0,0 +1,30 @@ +#![feature(nll)] + +struct A<'a>(&'a ()); + +trait Y { + const X: i32; +} + +impl Y for A<'static> { + const X: i32 = 10; +} + +fn foo<'a>(x: i32) { + match x { + // This uses as Y>::X, but `A<'a>` does not implement `Y`. + A::<'a>::X..=A::<'static>::X => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } +} + +fn bar<'a>(x: i32) { + match x { + // This uses as Y>::X, but `A<'a>` does not implement `Y`. + A::<'static>::X..=A::<'a>::X => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-61311-normalize.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-61311-normalize.rs new file mode 100644 index 000000000000..6b9e54cf7e06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-61311-normalize.rs @@ -0,0 +1,35 @@ +// Regression test for #61311 +// We would ICE after failing to normalize `Self::Proj` in the `impl` below. + +// check-pass + +pub struct Unit; +trait Obj {} + +trait Bound {} +impl Bound for Unit {} + +pub trait HasProj { + type Proj; +} + +impl HasProj for T { + type Proj = Unit; +} + +trait HasProjFn { + type Proj; + fn the_fn(_: Self::Proj); +} + +impl HasProjFn for Unit +where + Box: HasProj, + as HasProj>::Proj: Bound, +{ + type Proj = Unit; + fn the_fn(_: Self::Proj) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-61320-normalize.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-61320-normalize.rs new file mode 100644 index 000000000000..7f551be618a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-61320-normalize.rs @@ -0,0 +1,161 @@ +// Regression test for #61320 +// This is the same issue as #61311, just a larger test case. + +// check-pass + +pub struct AndThen +where + A: Future, + B: IntoFuture, +{ + state: (A, B::Future, F), +} + +pub struct FutureResult { + inner: Option>, +} + +impl Future for FutureResult { + type Item = T; + type Error = E; + + fn poll(&mut self) -> Poll { + unimplemented!() + } +} + +pub type Poll = Result; + +impl Future for AndThen +where + A: Future, + B: IntoFuture, + F: FnOnce(A::Item) -> B, +{ + type Item = B::Item; + type Error = B::Error; + + fn poll(&mut self) -> Poll { + unimplemented!() + } +} + +pub trait Future { + type Item; + + type Error; + + fn poll(&mut self) -> Poll; + + fn and_then(self, f: F) -> AndThen + where + F: FnOnce(Self::Item) -> B, + B: IntoFuture, + Self: Sized, + { + unimplemented!() + } +} + +pub trait IntoFuture { + /// The future that this type can be converted into. + type Future: Future; + + /// The item that the future may resolve with. + type Item; + /// The error that the future may resolve with. + type Error; + + /// Consumes this object and produces a future. + fn into_future(self) -> Self::Future; +} + +impl IntoFuture for F { + type Future = F; + type Item = F::Item; + type Error = F::Error; + + fn into_future(self) -> F { + self + } +} + +impl Future for ::std::boxed::Box { + type Item = F::Item; + type Error = F::Error; + + fn poll(&mut self) -> Poll { + (**self).poll() + } +} + +impl IntoFuture for Result { + type Future = FutureResult; + type Item = T; + type Error = E; + + fn into_future(self) -> FutureResult { + unimplemented!() + } +} + +struct Request(T); + +trait RequestContext {} +impl RequestContext for T {} +struct NoContext; +impl AsRef for NoContext { + fn as_ref(&self) -> &Self { + &NoContext + } +} + +type BoxedError = Box; +type DefaultFuture = Box + Send>; + +trait Guard: Sized { + type Result: IntoFuture; + fn from_request(request: &Request<()>) -> Self::Result; +} + +trait FromRequest: Sized { + type Context; + type Future: Future + Send; + fn from_request(request: Request<()>) -> Self::Future; +} + +struct MyGuard; +impl Guard for MyGuard { + type Result = Result; + fn from_request(_request: &Request<()>) -> Self::Result { + Ok(MyGuard) + } +} + +struct Generic { + _inner: I, +} + +impl FromRequest for Generic +where + MyGuard: Guard, + ::Result: IntoFuture, + <::Result as IntoFuture>::Future: Send, + I: FromRequest, +{ + type Future = DefaultFuture; + type Context = NoContext; + fn from_request(headers: Request<()>) -> DefaultFuture { + let _future = ::from_request(&headers) + .into_future() + .and_then(move |_| { + ::from_request(headers) + .into_future() + .and_then(move |fld_inner| Ok(Generic { _inner: fld_inner }).into_future()) + }); + panic!(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-61424.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-61424.rs new file mode 100644 index 000000000000..d98f042d70e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-61424.rs @@ -0,0 +1,10 @@ +// run-rustfix + +#![deny(unused_mut)] + +fn main() { + let mut x; // { dg-error "" "" { target *-*-* } } + x = String::new(); + dbg!(x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-62007-assign-const-index.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-62007-assign-const-index.rs new file mode 100644 index 000000000000..58d04b4a1e79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-62007-assign-const-index.rs @@ -0,0 +1,33 @@ +// Issue #62007: assigning over a const-index projection of an array +// (in this case, `list[I] = n;`) should in theory be able to kill all borrows +// of `list[0]`, so that `list[0]` could be borrowed on the next +// iteration through the loop. +// +// Currently the compiler does not allow this. We may want to consider +// loosening that restriction in the future. (However, doing so would +// at *least* require T-lang team approval, and probably an RFC; e.g. +// such loosening might make complicate the user's mental mode; it +// also would make code more brittle in the face of refactorings that +// replace constants with variables. + +#![allow(dead_code)] + +struct List { + value: T, + next: Option>>, +} + +fn to_refs(mut list: [&mut List; 2]) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list[0].value); // { dg-error ".E0499." "" { target *-*-* } } + if let Some(n) = list[0].next.as_mut() { // { dg-error ".E0499." "" { target *-*-* } } + list[0] = n; + } else { + return result; + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-62007-assign-differing-fields.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-62007-assign-differing-fields.rs new file mode 100644 index 000000000000..2293ee64ba55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-62007-assign-differing-fields.rs @@ -0,0 +1,26 @@ +// Double-check we didn't go too far with our resolution to issue +// #62007: assigning over a field projection (`list.1 = n;` in this +// case) should kill only borrows of `list.1`; `list.0` can *not* +// necessarily be borrowed on the next iteration through the loop. + +#![allow(dead_code)] + +struct List { + value: T, + next: Option>>, +} + +fn to_refs<'a, T>(mut list: (&'a mut List, &'a mut List)) -> Vec<&'a mut T> { + let mut result = vec![]; + loop { + result.push(&mut (list.0).value); // { dg-error ".E0499." "" { target *-*-* } } + if let Some(n) = (list.0).next.as_mut() { // { dg-error ".E0499." "" { target *-*-* } } + list.1 = n; + } else { + return result; + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-63154-normalize.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-63154-normalize.rs new file mode 100644 index 000000000000..9a7d7428a524 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-63154-normalize.rs @@ -0,0 +1,35 @@ +// Regression test for rust-lang/rust#63154 +// +// Before, we would ICE after failing to normalize the destination type +// when checking call destinations and also when checking MIR +// assignment statements. + +// check-pass + +trait HasAssocType { + type Inner; +} + +impl HasAssocType for () { + type Inner = (); +} + +trait Tr: Fn(I) -> Option {} +impl Option> Tr for Q {} + +fn f() -> impl Tr { + |_| None +} + +fn g(f: impl Tr) -> impl Tr { + f +} + +fn h() { + g(f())(()); +} + +fn main() { + h(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-68550.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-68550.rs new file mode 100644 index 000000000000..cb5ee01ecb0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-68550.rs @@ -0,0 +1,16 @@ +// Regression test for issue #68550. +// +// The `&'static A:` where clause was triggering +// ICEs because it wound up being compiled to reference +// the `'empty(U0)` region. + +fn run<'a, A>(x: A) +where + A: 'static, + &'static A: , +{ + let _: &'a A = &x; // { dg-error ".E0597." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-69114-static-mut-ty.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-69114-static-mut-ty.rs new file mode 100644 index 000000000000..ff0d7130f652 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-69114-static-mut-ty.rs @@ -0,0 +1,31 @@ +// Check that borrowck ensures that `static mut` items have the expected type. + +static FOO: u8 = 42; +static mut BAR: &'static u8 = &FOO; +static mut BAR_ELIDED: &u8 = &FOO; + +fn main() { + unsafe { + println!("{} {}", BAR, BAR_ELIDED); + set_bar(); + set_bar_elided(); + println!("{} {}", BAR, BAR_ELIDED); + } +} + +fn set_bar() { + let n = 42; + unsafe { + BAR = &n; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + } +} + +fn set_bar_elided() { + let n = 42; + unsafe { + BAR_ELIDED = &n; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/issue-69114-static-ty.rs b/gcc/testsuite/rust/rustc/ui/nll/issue-69114-static-ty.rs new file mode 100644 index 000000000000..cc0e159dc586 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/issue-69114-static-ty.rs @@ -0,0 +1,10 @@ +// Check that borrowck ensures that `static` items have the expected type. + +static FOO: &'static (dyn Fn(&'static u8) + Send + Sync) = &drop; + +fn main() { + let n = 42; + FOO(&n); +// { dg-error ".E0597." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/loan_ends_mid_block_pair.rs b/gcc/testsuite/rust/rustc/ui/nll/loan_ends_mid_block_pair.rs new file mode 100644 index 000000000000..29c7ec702cdd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/loan_ends_mid_block_pair.rs @@ -0,0 +1,30 @@ +#![allow(warnings)] +#![feature(rustc_attrs)] + + +fn main() { +} + +fn nll_fail() { + let mut data = ('a', 'b', 'c'); + let c = &mut data.0; + capitalize(c); + data.0 = 'e'; +// { dg-error ".E0506." "" { target *-*-* } .-1 } + data.0 = 'f'; + data.0 = 'g'; + capitalize(c); +} + +fn nll_ok() { + let mut data = ('a', 'b', 'c'); + let c = &mut data.0; + capitalize(c); + data.0 = 'e'; + data.0 = 'f'; + data.0 = 'g'; +} + +fn capitalize(_: &mut char) { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/loan_ends_mid_block_vec.rs b/gcc/testsuite/rust/rustc/ui/nll/loan_ends_mid_block_vec.rs new file mode 100644 index 000000000000..3f2017d0343a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/loan_ends_mid_block_vec.rs @@ -0,0 +1,31 @@ +#![allow(warnings)] +#![feature(rustc_attrs)] + +fn main() { +} + +fn nll_fail() { + let mut data = vec!['a', 'b', 'c']; + let slice = &mut data; + capitalize(slice); + data.push('d'); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + data.push('e'); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + data.push('f'); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + capitalize(slice); +} + +fn nll_ok() { + let mut data = vec!['a', 'b', 'c']; + let slice = &mut data; + capitalize(slice); + data.push('d'); + data.push('e'); + data.push('f'); +} + +fn capitalize(_: &mut [char]) { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/local-outlives-static-via-hrtb.rs b/gcc/testsuite/rust/rustc/ui/nll/local-outlives-static-via-hrtb.rs new file mode 100644 index 000000000000..af91d47517c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/local-outlives-static-via-hrtb.rs @@ -0,0 +1,27 @@ +// Test that we handle the case when a local variable is borrowed for `'static` +// due to an outlives constraint involving a region in an incompatible universe + +pub trait Outlives<'this> {} + +impl<'this, T> Outlives<'this> for T where T: 'this {} +trait Reference { + type AssociatedType; +} + +impl<'a, T: 'a> Reference for &'a T { + type AssociatedType = &'a (); +} + +fn assert_static_via_hrtb(_: G) where for<'a> G: Outlives<'a> {} + +fn assert_static_via_hrtb_with_assoc_type(_: &'_ T) +where + for<'a> &'a T: Reference, +{} + +fn main() { + let local = 0; + assert_static_via_hrtb(&local); // { dg-error ".E0597." "" { target *-*-* } } + assert_static_via_hrtb_with_assoc_type(&&local); // { dg-error ".E0597." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/match-cfg-fake-edges.rs b/gcc/testsuite/rust/rustc/ui/nll/match-cfg-fake-edges.rs new file mode 100644 index 000000000000..e7445165cfb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/match-cfg-fake-edges.rs @@ -0,0 +1,43 @@ +// Test that we have enough false edges to avoid exposing the exact matching +// algorithm in borrow checking. + +fn guard_always_precedes_arm(y: i32) { + let mut x; + // x should always be initialized, as the only way to reach the arm is + // through the guard. + match y { + 0 | 2 if { x = 2; true } => x, + _ => 2, + }; +} + +fn guard_may_be_skipped(y: i32) { + let x; + // Even though x *is* always initialized, we don't want to have borrowck + // results be based on whether patterns are exhaustive. + match y { + _ if { x = 2; true } => 1, + _ if { + x; // { dg-error ".E0381." "" { target *-*-* } } + false + } => 2, + _ => 3, + }; +} + +fn guard_may_be_taken(y: bool) { + let x = String::new(); + // Even though x *is* never moved before the use, we don't want to have + // borrowck results be based on whether patterns are disjoint. + match y { + false if { drop(x); true } => 1, + true => { + x; // { dg-error ".E0382." "" { target *-*-* } } + 2 + } + false => 3, + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/match-cfg-fake-edges2.rs b/gcc/testsuite/rust/rustc/ui/nll/match-cfg-fake-edges2.rs new file mode 100644 index 000000000000..d27011af1bb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/match-cfg-fake-edges2.rs @@ -0,0 +1,21 @@ +// Test that we have enough false edges to avoid exposing the exact matching +// algorithm in borrow checking. + +#![feature(nll)] + +fn all_previous_tests_may_be_done(y: &mut (bool, bool)) { + let r = &mut y.1; + // We don't actually test y.1 to select the second arm, but we don't want + // borrowck results to be based on the order we match patterns. + match y { + (false, true) => 1, // { dg-error ".E0503." "" { target *-*-* } } + (true, _) => { + r; + 2 + } + (false, _) => 3, + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/match-guards-always-borrow.rs b/gcc/testsuite/rust/rustc/ui/nll/match-guards-always-borrow.rs new file mode 100644 index 000000000000..089fc5321190 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/match-guards-always-borrow.rs @@ -0,0 +1,42 @@ +// Here is arielb1's basic example from rust-lang/rust#27282 +// that AST borrowck is flummoxed by: + +fn should_reject_destructive_mutate_in_guard() { + match Some(&4) { + None => {}, + ref mut foo if { + (|| { let bar = foo; bar.take() })(); +// { dg-error ".E0507." "" { target *-*-* } .-1 } + false } => { }, + Some(s) => std::process::exit(*s), + } +} + +// Here below is a case that needs to keep working: we only use the +// binding via immutable-borrow in the guard, and we mutate in the arm +// body. +fn allow_mutate_in_arm_body() { + match Some(&4) { + None => {}, + ref mut foo if foo.is_some() && false => { foo.take(); () } + Some(s) => std::process::exit(*s), + } +} + +// Here below is a case that needs to keep working: we only use the +// binding via immutable-borrow in the guard, and we move into the arm +// body. +fn allow_move_into_arm_body() { + match Some(&4) { + None => {}, + mut foo if foo.is_some() && false => { foo.take(); () } + Some(s) => std::process::exit(*s), + } +} + +fn main() { + should_reject_destructive_mutate_in_guard(); + allow_mutate_in_arm_body(); + allow_move_into_arm_body(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/match-guards-partially-borrow.rs b/gcc/testsuite/rust/rustc/ui/nll/match-guards-partially-borrow.rs new file mode 100644 index 000000000000..0fe83b2fbc59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/match-guards-partially-borrow.rs @@ -0,0 +1,170 @@ +// Test that a (partially) mutably borrowed place can be matched on, so long as +// we don't have to read any values that are mutably borrowed to determine +// which arm to take. +// +// Test that we don't allow mutating the value being matched on in a way that +// changes which patterns it matches, until we have chosen an arm. + +fn ok_mutation_in_guard(mut q: i32) { + match q { + // OK, mutation doesn't change which patterns g matches + _ if { q = 1; false } => (), + _ => (), + } +} + +fn ok_mutation_in_guard2(mut u: bool) { + // OK value of u is unused before modification + match u { + _ => (), + _ if { + u = true; + false + } => (), + x => (), + } +} + +fn ok_mutation_in_guard4(mut w: (&mut bool,)) { + // OK value of u is unused before modification + match w { + _ => (), + _ if { + *w.0 = true; + false + } => (), + x => (), + } +} + +fn ok_indirect_mutation_in_guard(mut p: &bool) { + match *p { + // OK, mutation doesn't change which patterns s matches + _ if { + p = &true; + false + } => (), + _ => (), + } +} + +fn mutation_invalidates_pattern_in_guard(mut q: bool) { + match q { + // q doesn't match the pattern with the guard by the end of the guard. + false if { + q = true; // { dg-error ".E0510." "" { target *-*-* } } + true + } => (), + _ => (), + } +} + +fn mutation_invalidates_previous_pattern_in_guard(mut r: bool) { + match r { + // r matches a previous pattern by the end of the guard. + true => (), + _ if { + r = true; // { dg-error ".E0510." "" { target *-*-* } } + true + } => (), + _ => (), + } +} + +fn match_on_borrowed_early_end(mut s: bool) { + let h = &mut s; + // OK value of s is unused before modification. + match s { + _ if { + *h = !*h; + false + } => (), + true => (), + false => (), + } +} + +fn bad_mutation_in_guard(mut t: bool) { + match t { + true => (), + false if { + t = true; // { dg-error ".E0510." "" { target *-*-* } } + false + } => (), + false => (), + } +} + +fn bad_mutation_in_guard2(mut x: Option>) { + // Check that nested patterns are checked. + match x { + None => (), + Some(None) => (), + _ if { + match x { + Some(ref mut r) => *r = None, // { dg-error ".E0510." "" { target *-*-* } } + _ => return, + }; + false + } => (), + Some(Some(r)) => println!("{}", r), + } +} + +fn bad_mutation_in_guard3(mut t: bool) { + match t { + s if { + t = !t; // { dg-error ".E0506." "" { target *-*-* } } + false + } => (), // What value should `s` have in the arm? + _ => (), + } +} + +fn bad_indirect_mutation_in_guard(mut y: &bool) { + match *y { + true => (), + false if { + y = &true; // { dg-error ".E0510." "" { target *-*-* } } + false + } => (), + false => (), + } +} + +fn bad_indirect_mutation_in_guard2(mut z: &bool) { + match z { + &true => (), + &false if { + z = &true; // { dg-error ".E0510." "" { target *-*-* } } + false + } => (), + &false => (), + } +} + +fn bad_indirect_mutation_in_guard3(mut a: &bool) { + // Same as bad_indirect_mutation_in_guard2, but using match ergonomics + match a { + true => (), + false if { + a = &true; // { dg-error ".E0510." "" { target *-*-* } } + false + } => (), + false => (), + } +} + +fn bad_indirect_mutation_in_guard4(mut b: &bool) { + match b { + &_ => (), + &_ if { + b = &true; // { dg-error ".E0510." "" { target *-*-* } } + false + } => (), + &b => (), + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/match-on-borrowed.rs b/gcc/testsuite/rust/rustc/ui/nll/match-on-borrowed.rs new file mode 100644 index 000000000000..4af4791557c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/match-on-borrowed.rs @@ -0,0 +1,94 @@ +// Test that a (partially) mutably borrowed place can be matched on, so long as +// we don't have to read any values that are mutably borrowed to determine +// which arm to take. +// +// Test that we don't allow mutating the value being matched on in a way that +// changes which patterns it matches, until we have chosen an arm. + +struct A(i32, i32); + +fn struct_example(mut a: A) { + let x = &mut a.0; + match a { // OK, no access of borrowed data + _ if false => (), + A(_, r) => (), + } + x; +} + +fn indirect_struct_example(mut b: &mut A) { + let x = &mut b.0; + match *b { // OK, no access of borrowed data + _ if false => (), + A(_, r) => (), + } + x; +} + +fn underscore_example(mut c: i32) { + let r = &mut c; + match c { // OK, no access of borrowed data (or any data at all) + _ if false => (), + _ => (), + } + r; +} + +enum E { + V(i32, i32), + W, +} + +fn enum_example(mut e: E) { + let x = match e { + E::V(ref mut x, _) => x, + E::W => panic!(), + }; + match e { // Don't know that E uses a tag for its discriminant + _ if false => (), + E::V(_, r) => (), // { dg-error ".E0503." "" { target *-*-* } } + E::W => (), + } + x; +} + +fn indirect_enum_example(mut f: &mut E) { + let x = match *f { + E::V(ref mut x, _) => x, + E::W => panic!(), + }; + match f { // Don't know that E uses a tag for its discriminant + _ if false => (), + E::V(_, r) => (), // { dg-error ".E0503." "" { target *-*-* } } + E::W => (), + } + x; +} + +fn match_on_muatbly_borrowed_ref(mut p: &bool) { + let r = &mut p; + match *p { // OK, no access at all + _ if false => (), + _ => (), + } + r; +} + +fn match_on_borrowed(mut t: bool) { + let x = &mut t; + match t { + true => (), // { dg-error ".E0503." "" { target *-*-* } } + false => (), + } + x; +} + +enum Never {} + +fn never_init() { + let n: Never; + match n {} // { dg-error ".E0381." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs b/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs new file mode 100644 index 000000000000..1b9bccc4f0dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-implicit-fragment-drop.rs @@ -0,0 +1,20 @@ +struct Wrap<'p> { p: &'p mut i32 } + +impl<'p> Drop for Wrap<'p> { + fn drop(&mut self) { + *self.p += 1; + } +} + +struct Foo<'p> { a: String, b: Wrap<'p> } + +fn main() { + let mut x = 0; + let wrap = Wrap { p: &mut x }; + let s = String::from("str"); + let foo = Foo { a: s, b: wrap }; + std::mem::drop(foo.b); + x = 1; // { dg-error ".E0506." "" { target *-*-* } } + // FIXME ^ Should not error in the future with implicit dtors, only manually implemented ones +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-uninitialized.rs b/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-uninitialized.rs new file mode 100644 index 000000000000..a065857ecfd9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-uninitialized.rs @@ -0,0 +1,20 @@ +// compile-flags: -Zborrowck=mir +// check-pass + +#![allow(warnings)] + +struct Wrap<'p> { p: &'p mut i32 } + +impl<'p> Drop for Wrap<'p> { + fn drop(&mut self) { + *self.p += 1; + } +} + +fn main() { + let mut x = 0; + let wrap = Wrap { p: &mut x }; + std::mem::drop(wrap); + x = 1; // OK, drop is inert +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-with-fragment.rs b/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-with-fragment.rs new file mode 100644 index 000000000000..1d98eeec7155 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-with-fragment.rs @@ -0,0 +1,23 @@ +//compile-flags: -Zborrowck=mir + +#![allow(warnings)] + +struct Wrap<'p> { p: &'p mut i32 } + +impl<'p> Drop for Wrap<'p> { + fn drop(&mut self) { + *self.p += 1; + } +} + +struct Foo<'p> { a: String, b: Wrap<'p> } + +fn main() { + let mut x = 0; + let wrap = Wrap { p: &mut x }; + let s = String::from("str"); + let foo = Foo { a: s, b: wrap }; + std::mem::drop(foo.a); + x = 1; // { dg-error ".E0506." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs b/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs new file mode 100644 index 000000000000..e8a761899bb8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.rs @@ -0,0 +1,25 @@ +//compile-flags: -Zborrowck=mir + +#![allow(warnings)] + +struct Wrap<'p> { p: &'p mut i32 } + +impl<'p> Drop for Wrap<'p> { + fn drop(&mut self) { + *self.p += 1; + } +} + +struct Foo<'p> { a: String, b: Wrap<'p> } + +fn main() { + let mut x = 0; + let wrap = Wrap { p: &mut x }; + let s = String::from("str"); + let foo = Foo { a: s, b: wrap }; + std::mem::drop(foo.a); + std::mem::drop(foo.b); + x = 1; // { dg-error ".E0506." "" { target *-*-* } } + // FIXME ^ This currently errors and it should not. +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop.rs b/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop.rs new file mode 100644 index 000000000000..747d6dbf0381 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/maybe-initialized-drop.rs @@ -0,0 +1,18 @@ +//compile-flags: -Zborrowck=mir + +#![allow(warnings)] + +struct Wrap<'p> { p: &'p mut i32 } + +impl<'p> Drop for Wrap<'p> { + fn drop(&mut self) { + *self.p += 1; + } +} + +fn main() { + let mut x = 0; + let wrap = Wrap { p: &mut x }; + x = 1; // { dg-error ".E0506." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_closure.rs b/gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_closure.rs new file mode 100644 index 000000000000..4bef7a2d8e16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_closure.rs @@ -0,0 +1,12 @@ +// compile-flags: -Z borrowck=mir + +#![allow(dead_code)] + +fn bar<'a, 'b>() -> fn(&'a u32, &'b u32) -> &'a u32 { + let g: fn(_, _) -> _ = |_x, y| y; + g +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_reify.rs b/gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_reify.rs new file mode 100644 index 000000000000..5f5846f271ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_reify.rs @@ -0,0 +1,42 @@ +// compile-flags: -Zborrowck=mir + +#![allow(dead_code)] + +// Test that we relate the type of the fn type to the type of the fn +// ptr when doing a `ReifyFnPointer` cast. +// +// This test is a bit tortured, let me explain: +// + +// The `where 'a: 'a` clause here ensures that `'a` is early bound, +// which is needed below to ensure that this test hits the path we are +// concerned with. +fn foo<'a>(x: &'a u32) -> &'a u32 +where + 'a: 'a, +{ + panic!() +} + +fn bar<'a>(x: &'a u32) -> &'static u32 { + // Here, the type of `foo` is `typeof(foo::<'x>)` for some fresh variable `'x`. + // During NLL region analysis, this will get renumbered to `typeof(foo::<'?0>)` + // where `'?0` is a new region variable. + // + // (Note that if `'a` on `foo` were late-bound, the type would be + // `typeof(foo)`, which would interact differently with because + // the renumbering later.) + // + // This type is then coerced to a fn type `fn(&'?1 u32) -> &'?2 + // u32`. Here, the `'?1` and `'?2` will have been created during + // the NLL region renumbering. + // + // The MIR type checker must therefore relate `'?0` to `'?1` and `'?2` + // as part of checking the `ReifyFnPointer`. + let f: fn(_) -> _ = foo; + f(x) +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_unsafe_fn.rs b/gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_unsafe_fn.rs new file mode 100644 index 000000000000..db089826c3e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_unsafe_fn.rs @@ -0,0 +1,14 @@ +// compile-flags: -Zborrowck=mir + +#![allow(dead_code)] + +fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 { + // Here the NLL checker must relate the types in `f` to the types + // in `g`. These are related via the `UnsafeFnPointer` cast. + let g: unsafe fn(_) -> _ = f; + unsafe { g(input) } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_unsize.rs b/gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_unsize.rs new file mode 100644 index 000000000000..71b4077c3174 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/mir_check_cast_unsize.rs @@ -0,0 +1,13 @@ +// compile-flags: -Z borrowck=mir + +#![allow(dead_code)] + +use std::fmt::Debug; + +fn bar<'a>(x: &'a u32) -> &'static dyn Debug { + x +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/move-errors.rs b/gcc/testsuite/rust/rustc/ui/nll/move-errors.rs new file mode 100644 index 000000000000..2f036f46199f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/move-errors.rs @@ -0,0 +1,118 @@ +struct A(String); +struct C(D); + +fn suggest_remove_deref() { + let a = &A("".to_string()); + let b = *a; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + +fn suggest_borrow() { + let a = [A("".to_string())]; + let b = a[0]; +// { dg-error ".E0508." "" { target *-*-* } .-1 } +} + +fn suggest_borrow2() { + let mut a = A("".to_string()); + let r = &&mut a; + let s = **r; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + +fn suggest_borrow3() { + use std::rc::Rc; + let mut a = A("".to_string()); + let r = Rc::new(a); + let s = *r; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + +fn suggest_borrow4() { + let a = [A("".to_string())][0]; +// { dg-error ".E0508." "" { target *-*-* } .-1 } +} + +fn suggest_borrow5() { + let a = &A("".to_string()); + let A(s) = *a; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + +fn suggest_ref() { + let c = C(D(String::new())); + let C(D(s)) = c; +// { dg-error ".E0509." "" { target *-*-* } .-1 } +} + +fn suggest_nothing() { + let a = &A("".to_string()); + let b; + b = *a; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + +enum B { + V(String), + U(D), +} + +struct D(String); + +impl Drop for D { + fn drop(&mut self) {} +} + +struct F(String, String); + +impl Drop for F { + fn drop(&mut self) {} +} + +fn probably_suggest_borrow() { + let x = [B::V(String::new())]; + match x[0] { +// { dg-error ".E0508." "" { target *-*-* } .-1 } + B::U(d) => (), + B::V(s) => (), + } +} + +fn have_to_suggest_ref() { + let x = B::V(String::new()); + match x { +// { dg-error ".E0509." "" { target *-*-* } .-1 } + B::V(s) => drop(s), + B::U(D(s)) => (), + }; +} + +fn two_separate_errors() { + let x = (D(String::new()), &String::new()); + match x { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { dg-error ".E0507." "" { target *-*-* } .-2 } + (D(s), &t) => (), + _ => (), + } +} + +fn have_to_suggest_double_ref() { + let x = F(String::new(), String::new()); + match x { +// { dg-error ".E0509." "" { target *-*-* } .-1 } + F(s, mut t) => (), + _ => (), + } +} + +fn double_binding(x: &Result) { + match *x { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + Ok(s) | Err(s) => (), + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/move-subpaths-moves-root.rs b/gcc/testsuite/rust/rustc/ui/nll/move-subpaths-moves-root.rs new file mode 100644 index 000000000000..b3e83116ea37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/move-subpaths-moves-root.rs @@ -0,0 +1,6 @@ +fn main() { + let x = (vec![1, 2, 3], ); + drop(x.0); + drop(x); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/mutating_references.rs b/gcc/testsuite/rust/rustc/ui/nll/mutating_references.rs new file mode 100644 index 000000000000..f5ceacc0e6bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/mutating_references.rs @@ -0,0 +1,25 @@ +// run-pass + +struct List { + value: T, + next: Option>>, +} + +fn to_refs(mut list: &mut List) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.value); + if let Some(n) = list.next.as_mut() { + list = n; + } else { + return result; + } + } +} + +fn main() { + let mut list = List { value: 1, next: None }; + let vec = to_refs(&mut list); + assert_eq!(vec![&mut 1], vec); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/normalization-bounds-error.rs b/gcc/testsuite/rust/rustc/ui/nll/normalization-bounds-error.rs new file mode 100644 index 000000000000..089ba0fd5324 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/normalization-bounds-error.rs @@ -0,0 +1,16 @@ +// Check that we error when a bound from the impl is not satisfied when +// normalizing an associated type. + +trait Visitor<'d> { + type Value; +} + +impl<'a, 'd: 'a> Visitor<'d> for &'a () { + type Value = (); +} + +fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} +// { dg-error ".E0495." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/normalization-bounds.rs b/gcc/testsuite/rust/rustc/ui/nll/normalization-bounds.rs new file mode 100644 index 000000000000..a00c12099c88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/normalization-bounds.rs @@ -0,0 +1,16 @@ +// Check that lifetime bounds get checked the right way around with NLL enabled. + +// check-pass + +trait Visitor<'d> { + type Value; +} + +impl<'a, 'd: 'a> Visitor<'d> for &'a () { + type Value = (); +} + +fn visit_seq<'d: 'a, 'a>() -> <&'a () as Visitor<'d>>::Value {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/outlives-suggestion-more.rs b/gcc/testsuite/rust/rustc/ui/nll/outlives-suggestion-more.rs new file mode 100644 index 000000000000..1ec058fc8e88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/outlives-suggestion-more.rs @@ -0,0 +1,29 @@ +// Test the more elaborate outlives suggestions. + +#![feature(nll)] + +// Should suggest: 'a: 'c, 'b: 'd +fn foo1<'a, 'b, 'c, 'd>(x: &'a usize, y: &'b usize) -> (&'c usize, &'d usize) { + (x, y) // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +// Should suggest: 'a: 'c and use 'static instead of 'b +fn foo2<'a, 'b, 'c>(x: &'a usize, y: &'b usize) -> (&'c usize, &'static usize) { + (x, y) // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +// Should suggest: 'a and 'b are the same and use 'static instead of 'c +fn foo3<'a, 'b, 'c, 'd, 'e>( + x: &'a usize, + y: &'b usize, + z: &'c usize, +) -> (&'b usize, &'a usize, &'static usize) { + (x, y, z) // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/outlives-suggestion-simple.rs b/gcc/testsuite/rust/rustc/ui/nll/outlives-suggestion-simple.rs new file mode 100644 index 000000000000..911d8031301d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/outlives-suggestion-simple.rs @@ -0,0 +1,78 @@ +// Test the simplest of outlives suggestions. + +#![feature(nll)] + +fn foo1<'a, 'b>(x: &'a usize) -> &'b usize { + x // { dg-error "" "" { target *-*-* } } +} + +fn foo2<'a>(x: &'a usize) -> &'static usize { + x // { dg-error "" "" { target *-*-* } } +} + +fn foo3<'a, 'b>(x: &'a usize, y: &'b usize) -> (&'b usize, &'a usize) { + (x, y) // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn foo4<'a, 'b, 'c>(x: &'a usize) -> (&'b usize, &'c usize) { + // FIXME: ideally, we suggest 'a: 'b + 'c, but as of today (may 04, 2019), the null error + // reporting stops after the first error in a MIR def so as not to produce too many errors, so + // currently we only report 'a: 'b. The user would then re-run and get another error. + (x, x) // { dg-error "" "" { target *-*-* } } +} + +struct Foo<'a> { + x: &'a usize, +} + +impl Foo<'static> { + pub fn foo<'a>(x: &'a usize) -> Self { + Foo { x } // { dg-error "" "" { target *-*-* } } + } +} + +struct Bar<'a> { + x: &'a usize, +} + +impl<'a> Bar<'a> { + pub fn get<'b>(&self) -> &'b usize { + self.x // { dg-error "" "" { target *-*-* } } + } +} + +// source: https://stackoverflow.com/questions/41417057/why-do-i-get-a-lifetime-error-when-i-use-a-mutable-reference-in-a-struct-instead +struct Baz<'a> { + x: &'a mut i32, +} + +impl<'a> Baz<'a> { + fn get<'b>(&'b self) -> &'a i32 { + self.x // { dg-error "" "" { target *-*-* } } + } +} + +// source: https://stackoverflow.com/questions/41204134/rust-lifetime-error +struct Bar2<'a> { + bar: &'a str, +} +impl<'a> Bar2<'a> { + fn new(foo: &'a Foo2<'a>) -> Bar2<'a> { + Bar2 { bar: foo.raw } + } +} + +pub struct Foo2<'a> { + raw: &'a str, + cell: std::cell::Cell<&'a str>, +} +impl<'a> Foo2<'a> { + // should not produce outlives suggestions to name 'self + fn get_bar(&self) -> Bar2 { + Bar2::new(&self) // { dg-error ".E0521." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/polonius/assignment-kills-loans.rs b/gcc/testsuite/rust/rustc/ui/nll/polonius/assignment-kills-loans.rs new file mode 100644 index 000000000000..7771b4503b4d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/polonius/assignment-kills-loans.rs @@ -0,0 +1,89 @@ +#![allow(dead_code)] + +// This tests the various kinds of assignments there are. Polonius used to generate `killed` +// facts only on simple assigments, but not projections, incorrectly causing errors to be emitted +// for code accepted by NLL. They are all variations from example code in the NLL RFC. + +// check-pass +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +struct List { + value: T, + next: Option>>, +} + +// Assignment to a local: the `list` assignment should clear the existing +// borrows of `list.value` and `list.next` +fn assignment_to_local(mut list: &mut List) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.value); + if let Some(n) = list.next.as_mut() { + list = n; + } else { + return result; + } + } +} + +// Assignment to a deref projection: the `*list` assignment should clear the existing +// borrows of `list.value` and `list.next` +fn assignment_to_deref_projection(mut list: Box<&mut List>) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.value); + if let Some(n) = list.next.as_mut() { + *list = n; + } else { + return result; + } + } +} + +// Assignment to a field projection: the `list.0` assignment should clear the existing +// borrows of `list.0.value` and `list.0.next` +fn assignment_to_field_projection(mut list: (&mut List,)) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.0.value); + if let Some(n) = list.0.next.as_mut() { + list.0 = n; + } else { + return result; + } + } +} + +// Assignment to a deref field projection: the `*list.0` assignment should clear the existing +// borrows of `list.0.value` and `list.0.next` +fn assignment_to_deref_field_projection(mut list: (Box<&mut List>,)) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.0.value); + if let Some(n) = list.0.next.as_mut() { + *list.0 = n; + } else { + return result; + } + } +} + +// Similar to `assignment_to_deref_field_projection` but through a longer projection chain +fn assignment_through_projection_chain( + mut list: (((((Box<&mut List>,),),),),), +) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut ((((list.0).0).0).0).0.value); + if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() { + *((((list.0).0).0).0).0 = n; + } else { + return result; + } + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/polonius/assignment-to-differing-field.rs b/gcc/testsuite/rust/rustc/ui/nll/polonius/assignment-to-differing-field.rs new file mode 100644 index 000000000000..266da2403e78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/polonius/assignment-to-differing-field.rs @@ -0,0 +1,51 @@ +#![allow(dead_code)] + +// Compared to `assignment-kills-loans.rs`, we check here +// that we do not kill too many borrows. Assignments to the `.1` +// field projections should leave the borrows on `.0` intact. + +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +struct List { + value: T, + next: Option>>, +} + + +fn assignment_to_field_projection<'a, T>( + mut list: (&'a mut List, &'a mut List), +) -> Vec<&'a mut T> { + let mut result = vec![]; + loop { + result.push(&mut (list.0).value); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + + if let Some(n) = (list.0).next.as_mut() { +// { dg-error ".E0499." "" { target *-*-* } .-1 } + list.1 = n; + } else { + return result; + } + } +} + +fn assignment_through_projection_chain<'a, T>( + mut list: (((((Box<&'a mut List>, Box<&'a mut List>),),),),), +) -> Vec<&'a mut T> { + let mut result = vec![]; + loop { + result.push(&mut ((((list.0).0).0).0).0.value); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + + if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() { +// { dg-error ".E0499." "" { target *-*-* } .-1 } + *((((list.0).0).0).0).1 = n; + } else { + return result; + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/polonius/call-kills-loans.rs b/gcc/testsuite/rust/rustc/ui/nll/polonius/call-kills-loans.rs new file mode 100644 index 000000000000..efbdbede11a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/polonius/call-kills-loans.rs @@ -0,0 +1,25 @@ +// `Call` terminators can write to a local which has existing loans +// and those need to be killed like a regular assignment to a local. +// This is a simplified version of issue 47680, is correctly accepted +// by NLL but was incorrectly rejected by Polonius because of these +// missing `killed` facts. + +// check-pass +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +struct Thing; + +impl Thing { + fn next(&mut self) -> &mut Self { unimplemented!() } +} + +fn main() { + let mut temp = &mut Thing; + + loop { + let v = temp.next(); + temp = v; // accepted by NLL, was incorrectly rejected by Polonius + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/polonius/issue-46589.rs b/gcc/testsuite/rust/rustc/ui/nll/polonius/issue-46589.rs new file mode 100644 index 000000000000..5daeb774d12e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/polonius/issue-46589.rs @@ -0,0 +1,33 @@ +// This test is a copy of `ui/nll/issue-46589.rs` which fails in NLL but succeeds in Polonius. +// As we can't have a test here which conditionally passes depending on a test +// revision/compile-flags. We ensure here that it passes in Polonius mode. + +// check-pass +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +struct Foo; + +impl Foo { + fn get_self(&mut self) -> Option<&mut Self> { + Some(self) + } + + fn new_self(&mut self) -> &mut Self { + self + } + + fn trigger_bug(&mut self) { + let other = &mut (&mut *self); + + *other = match (*other).get_self() { + Some(s) => s, + None => (*other).new_self() + }; + + let c = other; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/polonius/polonius-smoke-test.rs b/gcc/testsuite/rust/rustc/ui/nll/polonius/polonius-smoke-test.rs new file mode 100644 index 000000000000..90302597302c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/polonius/polonius-smoke-test.rs @@ -0,0 +1,48 @@ +// Check that Polonius borrow check works for simple cases. +// ignore-compare-mode-nll +// compile-flags: -Z borrowck=mir -Zpolonius + +pub fn return_ref_to_local() -> &'static i32 { + let x = 0; + &x // { dg-error ".E0515." "" { target *-*-* } } +} + +pub fn use_while_mut() { + let mut x = 0; + let y = &mut x; + let z = x; // { dg-error ".E0503." "" { target *-*-* } } + let w = y; +} + +pub fn use_while_mut_fr(x: &mut i32) -> &mut i32 { + let y = &mut *x; + let z = x; // { dg-error ".E0505." "" { target *-*-* } } + y +} + +// Cases like this are why we have Polonius. +pub fn position_dependent_outlives(x: &mut i32, cond: bool) -> &mut i32 { + let y = &mut *x; + if cond { + return y; + } else { + *x = 0; + return x; + } +} + +fn foo<'a, 'b>(p: &'b &'a mut usize) -> &'b usize { + p +} + +// Check that we create constraints for well-formedness of function arguments +fn well_formed_function_inputs() { + let s = &mut 1; + let r = &mut *s; + let tmp = foo(&r); + s; // { dg-error ".E0505." "" { target *-*-* } } + tmp; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/polonius/storagedead-kills-loans.rs b/gcc/testsuite/rust/rustc/ui/nll/polonius/storagedead-kills-loans.rs new file mode 100644 index 000000000000..0c1f3c2ebe60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/polonius/storagedead-kills-loans.rs @@ -0,0 +1,30 @@ +// Whenever a `StorageDead` MIR statement destroys a value `x`, +// we should kill all loans of `x`. This is extracted from `rand 0.4.6`, +// is correctly accepted by NLL but was incorrectly rejected by +// Polonius because of these missing `killed` facts. + +// check-pass +// compile-flags: -Z borrowck=mir -Z polonius +// ignore-compare-mode-nll + +use std::{io, mem}; +use std::io::Read; + +#[allow(dead_code)] +fn fill(r: &mut dyn Read, mut buf: &mut [u8]) -> io::Result<()> { + while buf.len() > 0 { + match r.read(buf).unwrap() { + 0 => return Err(io::Error::new(io::ErrorKind::Other, + "end of file reached")), + n => buf = &mut mem::replace(&mut buf, &mut [])[n..], + // ^- Polonius had multiple errors on the previous line (where NLL has none) + // as it didn't know `buf` was killed here, and would + // incorrectly reject both the borrow expression, and the assignment. + } + } + Ok(()) +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/polonius/subset-relations.rs b/gcc/testsuite/rust/rustc/ui/nll/polonius/subset-relations.rs new file mode 100644 index 000000000000..912250b96fab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/polonius/subset-relations.rs @@ -0,0 +1,31 @@ +// Checks that Polonius can compute cases of universal regions errors: +// "illegal subset relation errors", cases where analysis finds that +// two free regions outlive each other, without any evidence that this +// relation holds. + +// ignore-compare-mode-nll +// compile-flags: -Z borrowck=mir -Zpolonius + +// returning `y` requires that `'b: 'a`, but it's not known to be true +fn missing_subset<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 { + y // { dg-error "" "" { target *-*-* } } +} + +// `'b: 'a` is explicitly declared +fn valid_subset<'a, 'b: 'a>(x: &'a u32, y: &'b u32) -> &'a u32 { + y +} + +// because of `x`, it is implied that `'b: 'a` holds +fn implied_bounds_subset<'a, 'b>(x: &'a &'b mut u32) -> &'a u32 { + x +} + +// `'b: 'a` is declared, and `'a: 'c` is known via implied bounds: +// `'b: 'c` is therefore known to hold transitively +fn transitively_valid_subset<'a, 'b: 'a, 'c>(x: &'c &'a u32, y: &'b u32) -> &'c u32 { + y +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/process_or_insert_default.rs b/gcc/testsuite/rust/rustc/ui/nll/process_or_insert_default.rs new file mode 100644 index 000000000000..8ed3eb4b87bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/process_or_insert_default.rs @@ -0,0 +1,28 @@ +// run-pass + +use std::collections::HashMap; + +fn process_or_insert_default(map: &mut HashMap, key: usize) { + match map.get_mut(&key) { + Some(value) => { + process(value); + } + None => { + map.insert(key, "".to_string()); + } + } +} + +fn process(x: &str) { + assert_eq!(x, "Hello, world"); +} + +fn main() { + let map = &mut HashMap::new(); + map.insert(22, format!("Hello, world")); + map.insert(44, format!("Goodbye, world")); + process_or_insert_default(map, 22); + process_or_insert_default(map, 66); + assert_eq!(map[&66], ""); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/projection-return.rs b/gcc/testsuite/rust/rustc/ui/nll/projection-return.rs new file mode 100644 index 000000000000..49e38b32ae58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/projection-return.rs @@ -0,0 +1,19 @@ +// compile-flags:-Zborrowck=mir +// check-pass + +#![feature(rustc_attrs)] + +trait Foo { + type Bar; +} + +impl Foo for () { + type Bar = u32; +} + +fn foo() -> <() as Foo>::Bar { + 22 +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/promotable-mutable-zst-doesnt-conflict.rs b/gcc/testsuite/rust/rustc/ui/nll/promotable-mutable-zst-doesnt-conflict.rs new file mode 100644 index 000000000000..f2791b2309be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/promotable-mutable-zst-doesnt-conflict.rs @@ -0,0 +1,12 @@ +// Check that mutable promoted length zero arrays don't check for conflicting +// access + +// check-pass + +pub fn main() { + let mut x: Vec<&[i32; 0]> = Vec::new(); + for _ in 0..10 { + x.push(&[]); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/promoted-bounds.rs b/gcc/testsuite/rust/rustc/ui/nll/promoted-bounds.rs new file mode 100644 index 000000000000..a162bb62667c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/promoted-bounds.rs @@ -0,0 +1,26 @@ +fn shorten_lifetime<'a, 'b, 'min>(a: &'a i32, b: &'b i32) -> &'min i32 +where + 'a: 'min, + 'b: 'min, +{ + if *a < *b { + &a + } else { + &b + } +} + +fn main() { + let promoted_fn_item_ref = &shorten_lifetime; + + let a = &5; + let ptr = { + let l = 3; + let b = &l; // { dg-error ".E0597." "" { target *-*-* } } + let c = promoted_fn_item_ref(a, b); + c + }; + + println!("ptr = {:?}", ptr); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/promoted-closure-pair.rs b/gcc/testsuite/rust/rustc/ui/nll/promoted-closure-pair.rs new file mode 100644 index 000000000000..742bdd72fc59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/promoted-closure-pair.rs @@ -0,0 +1,11 @@ +// Check that we handle multiple closures in the same promoted constant. + +fn foo() -> &'static i32 { + let z = 0; + let p = &(|y| y, |y| y); + p.0(&z); + p.1(&z) // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/promoted-liveness.rs b/gcc/testsuite/rust/rustc/ui/nll/promoted-liveness.rs new file mode 100644 index 000000000000..5eb29e7cce25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/promoted-liveness.rs @@ -0,0 +1,9 @@ +// Test that promoted that have larger mir bodies than their containing function +// don't cause an ICE. + +// check-pass + +fn main() { + &["0", "1", "2", "3", "4", "5", "6", "7"]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/rc-loop.rs b/gcc/testsuite/rust/rustc/ui/nll/rc-loop.rs new file mode 100644 index 000000000000..d590b7f89f06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/rc-loop.rs @@ -0,0 +1,29 @@ +// run-pass + +// A test for something that NLL enables. It sometimes happens that +// the `while let` pattern makes some borrows from a variable (in this +// case, `x`) that you need in order to compute the next value for +// `x`. The lexical checker makes this very painful. The NLL checker +// does not. + +use std::rc::Rc; + +#[derive(Debug, PartialEq, Eq)] +enum Foo { + Base(usize), + Next(Rc), +} + +fn find_base(mut x: Rc) -> Rc { + while let Foo::Next(n) = &*x { + x = n.clone(); + } + x +} + +fn main() { + let chain = Rc::new(Foo::Next(Rc::new(Foo::Base(44)))); + let base = find_base(chain); + assert_eq!(&*base, &Foo::Base(44)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/reference-carried-through-struct-field.rs b/gcc/testsuite/rust/rustc/ui/nll/reference-carried-through-struct-field.rs new file mode 100644 index 000000000000..5541f61835dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/reference-carried-through-struct-field.rs @@ -0,0 +1,11 @@ +struct Wrap<'a> { w: &'a mut u32 } + +fn foo() { + let mut x = 22; + let wrapper = Wrap { w: &mut x }; + x += 1; // { dg-error ".E0503." "" { target *-*-* } } + *wrapper.w += 1; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/region-ends-after-if-condition.rs b/gcc/testsuite/rust/rustc/ui/nll/region-ends-after-if-condition.rs new file mode 100644 index 000000000000..6c65d3befb1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/region-ends-after-if-condition.rs @@ -0,0 +1,33 @@ +// Basic test for liveness constraints: the region (`R1`) that appears +// in the type of `p` includes the points after `&v[0]` up to (but not +// including) the call to `use_x`. The `else` branch is not included. + +#![allow(warnings)] +#![feature(rustc_attrs)] + +struct MyStruct { + field: String +} + +fn foo1() { + let mut my_struct = MyStruct { field: format!("Hello") }; + + let value = &my_struct.field; + if value.is_empty() { + my_struct.field.push_str("Hello, world!"); + } +} + +fn foo2() { + let mut my_struct = MyStruct { field: format!("Hello") }; + + let value = &my_struct.field; + if value.is_empty() { + my_struct.field.push_str("Hello, world!"); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + } + drop(value); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/relate_tys/fn-subtype.rs b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/fn-subtype.rs new file mode 100644 index 000000000000..afa8c01ee77b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/fn-subtype.rs @@ -0,0 +1,11 @@ +// Test that NLL produces correct spans for higher-ranked subtyping errors. +// +// compile-flags:-Zno-leak-check + +#![feature(nll)] + +fn main() { + let x: fn(&'static ()) = |_| {}; + let y: for<'a> fn(&'a ()) = x; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/relate_tys/hr-fn-aaa-as-aba.rs b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/hr-fn-aaa-as-aba.rs new file mode 100644 index 000000000000..8b2d0980e362 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/hr-fn-aaa-as-aba.rs @@ -0,0 +1,27 @@ +// Test that the NLL `relate_tys` code correctly deduces that a +// function returning either argument CANNOT be upcast to one +// that returns always its first argument. +// +// compile-flags:-Zno-leak-check + +#![feature(nll)] + +fn make_it() -> for<'a> fn(&'a u32, &'a u32) -> &'a u32 { + panic!() +} + +fn foo() { + let a: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it(); +// { dg-error "" "" { target *-*-* } .-1 } + drop(a); +} + +fn bar() { + // The code path for patterns is mildly different, so go ahead and + // test that too: + let _: for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 = make_it(); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs new file mode 100644 index 000000000000..23e92e8b95d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/hr-fn-aau-eq-abu.rs @@ -0,0 +1,26 @@ +// Test an interesting corner case that ought to be legal (though the +// current code actually gets it wrong, see below): a fn that takes +// two arguments that are references with the same lifetime is in fact +// equivalent to a fn that takes two references with distinct +// lifetimes. This is true because the two functions can call one +// another -- effectively, the single lifetime `'a` is just inferred +// to be the intersection of the two distinct lifetimes. +// +// check-pass +// compile-flags:-Zno-leak-check + +#![feature(nll)] + +use std::cell::Cell; + +fn make_cell_aa() -> Cell fn(&'a u32, &'a u32)> { + panic!() +} + +fn aa_eq_ab() { + let a: Cell fn(&'a u32, &'b u32)> = make_cell_aa(); + drop(a); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs new file mode 100644 index 000000000000..93c0d2007ebb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs @@ -0,0 +1,18 @@ +// Test that the NLL `relate_tys` code correctly deduces that a +// function returning always its first argument can be upcast to one +// that returns either first or second argument. +// +// check-pass +// compile-flags:-Zno-leak-check + +#![feature(nll)] + +fn make_it() -> for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 { + panic!() +} + +fn main() { + let a: for<'a> fn(&'a u32, &'a u32) -> &'a u32 = make_it(); + drop(a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs new file mode 100644 index 000000000000..2d7044c7e306 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs @@ -0,0 +1,36 @@ +// Test that the NLL solver cannot find a solution +// for `exists { forall { R2: R1 } }`. +// +// In this test, the impl should match `fn(T)` for some `T`, +// but we ask it to match `for<'a> fn(&'a ())`. Due to argument +// contravariance, this effectively requires a `T = &'b ()` where +// `forall<'a> { 'a: 'b }`. Therefore, we get an error. +// +// Note the use of `-Zno-leak-check` and `feature(nll)` here. These +// are presently required in order to skip the leak-check errors. +// +// c.f. Issue #57642. +// +// compile-flags:-Zno-leak-check + +#![feature(nll)] + +trait Y { + type F; + fn make_f() -> Self::F; +} + +impl Y for fn(T) { + type F = fn(T); + + fn make_f() -> Self::F { + |_| {} + } +} + +fn main() { + let _x = ::make_f(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/relate_tys/issue-48071.rs b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/issue-48071.rs new file mode 100644 index 000000000000..2ba0d18b868b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/issue-48071.rs @@ -0,0 +1,25 @@ +// Regression test for #48071. This test used to ICE because -- in +// the leak-check -- it would pass since we knew that the return type +// was `'static`, and hence `'static: 'a` was legal even for a +// placeholder region, but in NLL land it would fail because we had +// rewritten `'static` to a region variable. +// +// check-pass + +trait Foo { + fn foo(&self) { } +} + +impl Foo for () { +} + +type MakeFooFn = for<'a> fn(&'a u8) -> Box; + +fn make_foo(x: &u8) -> Box { + Box::new(()) +} + +fn main() { + let x: MakeFooFn = make_foo as MakeFooFn; +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/relate_tys/trait-hrtb.rs b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/trait-hrtb.rs new file mode 100644 index 000000000000..c18231a7f286 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/trait-hrtb.rs @@ -0,0 +1,17 @@ +// Test that NLL generates proper error spans for trait HRTB errors +// +// compile-flags:-Zno-leak-check + +#![feature(nll)] + +trait Foo<'a> {} + +fn make_foo<'a>() -> Box> { + panic!() +} + +fn main() { + let x: Box> = make_foo(); + let y: Box Foo<'a>> = x; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/relate_tys/universe-violation.rs b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/universe-violation.rs new file mode 100644 index 000000000000..b0337125bc7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/universe-violation.rs @@ -0,0 +1,18 @@ +// Test that the NLL `relate_tys` code correctly deduces that a +// function returning either argument CANNOT be upcast to one +// that returns always its first argument. +// +// compile-flags:-Zno-leak-check + +#![feature(nll)] + +fn make_it() -> fn(&'static u32) -> &'static u32 { + panic!() +} + +fn main() { + let a: fn(_) -> _ = make_it(); + let b: fn(&u32) -> &u32 = a; // { dg-error "" "" { target *-*-* } } + drop(a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/relate_tys/var-appears-twice.rs b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/var-appears-twice.rs new file mode 100644 index 000000000000..5396d1688451 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/relate_tys/var-appears-twice.rs @@ -0,0 +1,26 @@ +// Test that the NLL `relate_tys` code correctly deduces that a +// function returning always its first argument can be upcast to one +// that returns either first or second argument. + +use std::cell::Cell; + +type DoubleCell = Cell<(A, A)>; +type DoublePair = (A, A); + +fn make_cell<'b>(x: &'b u32) -> Cell<(&'static u32, &'b u32)> { + panic!() +} + +fn main() { + let a: &'static u32 = &22; + let b = 44; + + // Here we get an error because `DoubleCell<_>` requires the same type + // on both parts of the `Cell`, and we can't have that. + let x: DoubleCell<_> = make_cell(&b); // { dg-error ".E0597." "" { target *-*-* } } + + // Here we do not get an error because `DoublePair<_>` permits + // variance on the lifetimes involved. + let y: DoublePair<_> = make_cell(&b).get(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/return-ref-mut-issue-46557.rs b/gcc/testsuite/rust/rustc/ui/nll/return-ref-mut-issue-46557.rs new file mode 100644 index 000000000000..af825eab9b7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/return-ref-mut-issue-46557.rs @@ -0,0 +1,9 @@ +// Regression test for issue #46557 + +fn gimme_static_mut() -> &'static mut u32 { + let ref mut x = 1234543; + x // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/return_from_loop.rs b/gcc/testsuite/rust/rustc/ui/nll/return_from_loop.rs new file mode 100644 index 000000000000..321f408994ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/return_from_loop.rs @@ -0,0 +1,36 @@ +// Basic test for liveness constraints: the region (`R1`) that appears +// in the type of `p` includes the points after `&v[0]` up to (but not +// including) the call to `use_x`. The `else` branch is not included. + +#![allow(warnings)] +#![feature(rustc_attrs)] + +struct MyStruct { + field: String +} + +fn main() { +} + +fn nll_fail() { + let mut my_struct = MyStruct { field: format!("Hello") }; + + let value = &mut my_struct.field; + loop { + my_struct.field.push_str("Hello, world!"); +// { dg-error ".E0499." "" { target *-*-* } .-1 } + value.len(); + return; + } +} + +fn nll_ok() { + let mut my_struct = MyStruct { field: format!("Hello") }; + + let value = &mut my_struct.field; + loop { + my_struct.field.push_str("Hello, world!"); + return; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/self-assign-ref-mut.rs b/gcc/testsuite/rust/rustc/ui/nll/self-assign-ref-mut.rs new file mode 100644 index 000000000000..9f3b6c8ef129 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/self-assign-ref-mut.rs @@ -0,0 +1,21 @@ +// Check that `*y` isn't borrowed after `y = y`. + +// check-pass + +fn main() { + let mut x = 1; + { + let mut y = &mut x; + y = y; + y; + } + x; + { + let mut y = &mut x; + y = y; + y = y; + y; + } + x; +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/trait-associated-constant.rs b/gcc/testsuite/rust/rustc/ui/nll/trait-associated-constant.rs new file mode 100644 index 000000000000..fb4a4d456d76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/trait-associated-constant.rs @@ -0,0 +1,32 @@ +// Test cases where we put various lifetime constraints on trait +// associated constants. + +#![feature(rustc_attrs)] + +use std::option::Option; + +trait Anything<'a: 'b, 'b> { + const AC: Option<&'b str>; +} + +struct OKStruct1 { } + +impl<'a: 'b, 'b> Anything<'a, 'b> for OKStruct1 { + const AC: Option<&'b str> = None; +} + +struct FailStruct { } + +impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct { + const AC: Option<&'c str> = None; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +struct OKStruct2 { } + +impl<'a: 'b, 'b> Anything<'a, 'b> for OKStruct2 { + const AC: Option<&'a str> = None; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/impl-trait-captures.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/impl-trait-captures.rs new file mode 100644 index 000000000000..485a77c585fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/impl-trait-captures.rs @@ -0,0 +1,16 @@ +// compile-flags:-Zborrowck=mir -Zverbose + +#![allow(warnings)] + +trait Foo<'a> { +} + +impl<'a, T> Foo<'a> for T { } + +fn foo<'a, T>(x: &T) -> impl Foo<'a> { +// { dg-error ".E0621." "" { target *-*-* } .-1 } + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/impl-trait-outlives.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/impl-trait-outlives.rs new file mode 100644 index 000000000000..4ea42d1606b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/impl-trait-outlives.rs @@ -0,0 +1,39 @@ +// compile-flags:-Zborrowck=mir -Zverbose + +#![allow(warnings)] + +use std::fmt::Debug; + +fn no_region<'a, T>(x: Box) -> impl Debug + 'a +// { dg-error ".E0309." "" { target *-*-* } .-1 } +where + T: Debug, +{ + x +} + +fn correct_region<'a, T>(x: Box) -> impl Debug + 'a +where + T: 'a + Debug, +{ + x +} + +fn wrong_region<'a, 'b, T>(x: Box) -> impl Debug + 'a +// { dg-error ".E0309." "" { target *-*-* } .-1 } +where + T: 'b + Debug, +{ + x +} + +fn outlives_region<'a, 'b, T>(x: Box) -> impl Debug + 'a +where + T: 'b + Debug, + 'b: 'a, +{ + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/issue-53789-1.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/issue-53789-1.rs new file mode 100644 index 000000000000..fad5a559111e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/issue-53789-1.rs @@ -0,0 +1,88 @@ +// Regression test for #53789. +// +// check-pass + +use std::collections::BTreeMap; + +trait ValueTree { + type Value; +} + +trait Strategy { + type Value: ValueTree; +} + +type StrategyFor = StrategyType<'static, A>; +type StrategyType<'a, A> = >::Strategy; + +impl Strategy for (K, V) { + type Value = TupleValueTree<(K, V)>; +} + +impl ValueTree for TupleValueTree<(K, V)> { + type Value = BTreeMapValueTree; +} + +struct TupleValueTree { + tree: T, +} + +struct BTreeMapStrategy(std::marker::PhantomData<(K, V)>) +where + K: Strategy, + V: Strategy; + +struct BTreeMapValueTree(std::marker::PhantomData<(K, V)>) +where + K: ValueTree, + V: ValueTree; + +impl Strategy for BTreeMapStrategy +where + K: Strategy, + V: Strategy, +{ + type Value = BTreeMapValueTree; +} + +impl ValueTree for BTreeMapValueTree +where + K: ValueTree, + V: ValueTree, +{ + type Value = BTreeMap; +} + +trait Arbitrary<'a>: Sized { + fn arbitrary_with(args: Self::Parameters) -> Self::Strategy; + type Parameters; + type Strategy: Strategy; + type ValueTree: ValueTree; +} + +impl<'a, A, B> Arbitrary<'a> for BTreeMap +where + A: Arbitrary<'static>, + B: Arbitrary<'static>, + StrategyFor: 'static, + StrategyFor: 'static, +{ + type ValueTree = ::Value; + type Parameters = (A::Parameters, B::Parameters); + type Strategy = BTreeMapStrategy; + fn arbitrary_with(args: Self::Parameters) -> BTreeMapStrategy { + let (a, b) = args; + btree_map(any_with::(a), any_with::(b)) + } +} + +fn btree_map(key: K, value: V) -> BTreeMapStrategy { + unimplemented!() +} + +fn any_with<'a, A: Arbitrary<'a>>(args: A::Parameters) -> StrategyType<'a, A> { + unimplemented!() +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/issue-53789-2.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/issue-53789-2.rs new file mode 100644 index 000000000000..49bdde58f16e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/issue-53789-2.rs @@ -0,0 +1,249 @@ +// Regression test for #53789. +// +// check-pass +// ignore-compare-mode-chalk + +use std::collections::BTreeMap; +use std::ops::Range; +use std::cmp::Ord; + +macro_rules! valuetree { + () => { + type ValueTree = + ::Value; + }; +} + +macro_rules! product_unpack { + ($factor: pat) => { + ($factor,) + }; + ($($factor: pat),*) => { + ( $( $factor ),* ) + }; + ($($factor: pat),*,) => { + ( $( $factor ),* ) + }; +} + +macro_rules! product_type { + ($factor: ty) => { + ($factor,) + }; + ($($factor: ty),*) => { + ( $( $factor, )* ) + }; + ($($factor: ty),*,) => { + ( $( $factor, )* ) + }; +} + +macro_rules! default { + ($type: ty, $val: expr) => { + impl Default for $type { + fn default() -> Self { $val.into() } + } + }; +} + +// Pervasive internal sugar +macro_rules! mapfn { + ($(#[$meta:meta])* [$($vis:tt)*] + fn $name:ident[$($gen:tt)*]($parm:ident: $input:ty) -> $output:ty { + $($body:tt)* + }) => { + $(#[$meta])* + #[derive(Clone, Copy)] + $($vis)* struct $name; + impl $($gen)* statics::MapFn<$input> for $name { + type Output = $output; + } + } +} + +macro_rules! opaque_strategy_wrapper { + ($(#[$smeta:meta])* pub struct $stratname:ident + [$($sgen:tt)*][$($swhere:tt)*] + ($innerstrat:ty) -> $stratvtty:ty; + + $(#[$vmeta:meta])* pub struct $vtname:ident + [$($vgen:tt)*][$($vwhere:tt)*] + ($innervt:ty) -> $actualty:ty; + ) => { + $(#[$smeta])* struct $stratname $($sgen)* (std::marker::PhantomData<(K, V)>) + $($swhere)*; + + $(#[$vmeta])* struct $vtname $($vgen)* ($innervt) $($vwhere)*; + + impl $($sgen)* Strategy for $stratname $($sgen)* $($swhere)* { + type Value = $stratvtty; + } + + impl $($vgen)* ValueTree for $vtname $($vgen)* $($vwhere)* { + type Value = $actualty; + } + } +} + +trait ValueTree { + type Value; +} + +trait Strategy { + type Value : ValueTree; +} + +#[derive(Clone)] +struct VecStrategy { + element: T, + size: Range, +} + +fn vec(element: T, size: Range) + -> VecStrategy { + VecStrategy { + element: element, + size: size, + } +} + +type ValueFor = <::Value as ValueTree>::Value; + +trait Arbitrary<'a>: Sized { + fn arbitrary_with(args: Self::Parameters) -> Self::Strategy; + + type Parameters: Default; + type Strategy: Strategy; + type ValueTree: ValueTree; +} + +type StrategyFor = StrategyType<'static, A>; +type StrategyType<'a, A> = >::Strategy; + +//#[derive(Clone, PartialEq, Eq, Hash, Debug, From, Into)] +struct SizeBounds(Range); +default!(SizeBounds, 0..100); + + +impl From> for SizeBounds { + fn from(high: Range) -> Self { + unimplemented!() + } +} + +impl From for Range { + fn from(high: SizeBounds) -> Self { + unimplemented!() + } +} + + +fn any_with<'a, A: Arbitrary<'a>>(args: A::Parameters) + -> StrategyType<'a, A> { + unimplemented!() +} + +impl Strategy for (K, V) where + ::Value: Ord { + type Value = TupleValueTree<(K, V)>; +} + +impl ValueTree for TupleValueTree<(K, V)> where + ::Value: Ord { + type Value = BTreeMapValueTree; +} + +#[derive(Clone)] +struct VecValueTree { + elements: Vec, +} + +#[derive(Clone, Copy)] +struct TupleValueTree { + tree: T, +} + +opaque_strategy_wrapper! { + #[derive(Clone)] + pub struct BTreeMapStrategy[] + [where K : Strategy, V : Strategy, ValueFor : Ord]( + statics::Filter, + VecToBTreeMap>, MinSize>) + -> BTreeMapValueTree; + + #[derive(Clone)] + pub struct BTreeMapValueTree[] + [where K : ValueTree, V : ValueTree, K::Value : Ord]( + statics::Filter>, + VecToBTreeMap>, MinSize>) + -> BTreeMap; +} + +type RangedParams2 = product_type![SizeBounds, A, B]; + +impl<'a, A, B> Arbitrary<'a> for BTreeMap +where + A: Arbitrary<'static> + Ord, + B: Arbitrary<'static>, +StrategyFor: 'static, +StrategyFor: 'static, +{ + valuetree!(); + type Parameters = RangedParams2; + type Strategy = BTreeMapStrategy; + fn arbitrary_with(args: Self::Parameters) -> Self::Strategy { + let product_unpack![range, a, b] = args; + btree_map(any_with::(a), any_with::(b), range.into()) + } +} + +#[derive(Clone, Copy)] +struct MinSize(usize); + +mapfn! { + [] fn VecToBTreeMap[] + (vec: Vec<(K, V)>) -> BTreeMap + { + vec.into_iter().collect() + } +} + +fn btree_map + (key: K, value: V, size: Range) + -> BTreeMapStrategy +where ValueFor : Ord { + unimplemented!() +} + +mod statics { + pub(super) trait MapFn { + type Output; + } + + #[derive(Clone)] + pub struct Filter { + source: S, + fun: F, + } + + impl Filter { + pub fn new(source: S, whence: String, filter: F) -> Self { + unimplemented!() + } + } + + #[derive(Clone)] + pub struct Map { + source: S, + fun: F, + } + + impl Map { + pub fn new(source: S, fun: F) -> Self { + unimplemented!() + } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/issue-55756.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/issue-55756.rs new file mode 100644 index 000000000000..5f126ec43789 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/issue-55756.rs @@ -0,0 +1,38 @@ +// Regression test for #55756. +// +// In this test, the result of `self.callee` is a projection `>::Guard`. As it may contain a destructor, the dropck +// rules require that this type outlivess the scope of `state`. Unfortunately, +// our region inference is not smart enough to figure out how to +// translate a requirement like +// +// >::guard: 'r +// +// into a requirement that `'0: 'r` -- in particular, it fails to do +// so because it *also* knows that `>::Guard: 'a` +// from the trait definition. Faced with so many choices, the current +// solver opts to do nothing. +// +// Fixed by tweaking the solver to recognize that the constraint from +// the environment duplicates one from the trait. +// +// check-pass + +#![crate_type="lib"] + +pub trait Database<'a> { + type Guard: 'a; +} + +pub struct Stateful<'a, D: 'a>(&'a D); + +impl<'b, D: for <'a> Database<'a>> Stateful<'b, D> { + pub fn callee<'a>(&'a self) -> >::Guard { + unimplemented!() + } + pub fn caller<'a>(&'a self) -> >::Guard { + let state = self.callee(); + unimplemented!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-body.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-body.rs new file mode 100644 index 000000000000..59eb753d3d7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-body.rs @@ -0,0 +1,28 @@ +// Test that when we infer the lifetime to a subset of the fn body, it +// works out. +// +// check-pass + +trait MyTrait<'a> { + type Output; +} + +fn foo1() +where + for<'x> T: MyTrait<'x>, +{ + // Here the region `'c` in `>::Output` will be + // inferred to a subset of the fn body. + let x = bar::(); + drop(x); +} + +fn bar<'a, T>() -> &'a () +where + T: 'a, +{ + &() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-implied-bounds.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-implied-bounds.rs new file mode 100644 index 000000000000..30a54905b791 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-implied-bounds.rs @@ -0,0 +1,41 @@ +// Test that we can deduce when projections like `T::Item` outlive the +// function body. Test that this does not imply that `T: 'a` holds. + +// compile-flags:-Zborrowck=mir -Zverbose + +use std::cell::Cell; + +fn twice(mut value: T, mut f: F) +where + F: FnMut(&T, Cell<&Option>), + T: Iterator, +{ + let mut n = value.next(); + f(&value, Cell::new(&n)); + f(&value, Cell::new(&n)); +} + +fn generic1(value: T) { + // No error here: + twice(value, |value_ref, item| invoke1(item)); +} + +fn invoke1<'a, T>(x: Cell<&'a Option>) +where + T: 'a, +{ +} + +fn generic2(value: T) { + twice(value, |value_ref, item| invoke2(value_ref, item)); +// { dg-error ".E0310." "" { target *-*-* } .-1 } +} + +fn invoke2<'a, T, U>(a: &T, b: Cell<&'a Option>) +where + T: 'a, +{ +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-no-regions-closure.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-no-regions-closure.rs new file mode 100644 index 000000000000..b33c647abf6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-no-regions-closure.rs @@ -0,0 +1,56 @@ +// compile-flags:-Zborrowck=mir -Zverbose + +// Tests closures that propagate an outlives relationship to their +// creator where the subject is a projection with no regions (`::Item`, to be exact). + +#![allow(warnings)] +#![feature(rustc_attrs)] + +trait Anything { } + +impl Anything for T { } + +fn with_signature<'a, T, F>(x: Box, op: F) -> Box + where F: FnOnce(Box) -> Box +{ + op(x) +} + +#[rustc_regions] +fn no_region<'a, T>(x: Box) -> Box +where + T: Iterator, +{ + with_signature(x, |mut y| Box::new(y.next())) +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +#[rustc_regions] +fn correct_region<'a, T>(x: Box) -> Box +where + T: 'a + Iterator, +{ + with_signature(x, |mut y| Box::new(y.next())) +} + +#[rustc_regions] +fn wrong_region<'a, 'b, T>(x: Box) -> Box +where + T: 'b + Iterator, +{ + with_signature(x, |mut y| Box::new(y.next())) +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +#[rustc_regions] +fn outlives_region<'a, 'b, T>(x: Box) -> Box +where + T: 'b + Iterator, + 'b: 'a, +{ + with_signature(x, |mut y| Box::new(y.next())) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-no-regions-fn.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-no-regions-fn.rs new file mode 100644 index 000000000000..5ff61dfa84b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-no-regions-fn.rs @@ -0,0 +1,41 @@ +// compile-flags:-Zborrowck=mir -Zverbose + +#![allow(warnings)] + +trait Anything { } + +impl Anything for T { } + +fn no_region<'a, T>(mut x: T) -> Box +where + T: Iterator, +{ + Box::new(x.next()) +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn correct_region<'a, T>(mut x: T) -> Box +where + T: 'a + Iterator, +{ + Box::new(x.next()) +} + +fn wrong_region<'a, 'b, T>(mut x: T) -> Box +where + T: 'b + Iterator, +{ + Box::new(x.next()) +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn outlives_region<'a, 'b, T>(mut x: T) -> Box +where + T: 'b + Iterator, + 'b: 'a, +{ + Box::new(x.next()) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-one-region-closure.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-one-region-closure.rs new file mode 100644 index 000000000000..90b28e17741d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-one-region-closure.rs @@ -0,0 +1,84 @@ +// Test cases where we constrain `>::AssocType` to +// outlive `'a` and there are no bounds in the trait definition of +// `Anything`. This means that the constraint can only be satisfied in two +// ways: +// +// - by ensuring that `T: 'a` and `'b: 'a`, or +// - by something in the where clauses. +// +// As of this writing, the where clause option does not work because +// of limitations in our region inferencing system (this is true both +// with and without NLL). See `projection_outlives`. +// +// Ensuring that both `T: 'a` and `'b: 'a` holds does work (`elements_outlive`). + +// compile-flags:-Zborrowck=mir -Zverbose + +#![allow(warnings)] +#![feature(rustc_attrs)] + +use std::cell::Cell; + +trait Anything<'a> { + type AssocType; +} + +fn with_signature<'a, T, F>(cell: Cell<&'a ()>, t: T, op: F) +where + F: FnOnce(Cell<&'a ()>, T), +{ + op(cell, t) +} + +fn require<'a, 'b, T>(_cell: Cell<&'a ()>, _t: T) +where + T: Anything<'b>, + T::AssocType: 'a, +{ +} + +#[rustc_regions] +fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b>, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +// { dg-error ".E0309." "" { target *-*-* } .-1 } +// { dg-error ".E0309." "" { target *-*-* } .-2 } +} + +#[rustc_regions] +fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b>, + 'a: 'a, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +// { dg-error ".E0309." "" { target *-*-* } .-1 } +// { dg-error ".E0309." "" { target *-*-* } .-2 } +} + +#[rustc_regions] +fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b>, + T::AssocType: 'a, +{ + // We are projecting `>::AssocType`, and we know + // that this outlives `'a` because of the where-clause. + + with_signature(cell, t, |cell, t| require(cell, t)); +} + +#[rustc_regions] +fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b>, + T: 'a, + 'b: 'a, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs new file mode 100644 index 000000000000..21562d942ba0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.rs @@ -0,0 +1,85 @@ +// Test cases where we constrain `>::AssocType` to +// outlive `'a` and there is a unique bound in the trait definition of +// `Anything` -- i.e., we know that `AssocType` outlives `'b`. In this +// case, the best way to satisfy the trait bound is to show that `'b: +// 'a`, which can be done in various ways. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![allow(warnings)] +#![feature(rustc_attrs)] + +use std::cell::Cell; + +trait Anything<'a> { + type AssocType: 'a; +} + +fn with_signature<'a, T, F>(cell: Cell<&'a ()>, t: T, op: F) +where + F: FnOnce(Cell<&'a ()>, T), +{ + op(cell, t) +} + +fn require<'a, 'b, T>(_cell: Cell<&'a ()>, _t: T) +where + T: Anything<'b>, + T::AssocType: 'a, +{ +} + +#[rustc_regions] +fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b>, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[rustc_regions] +fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b>, + 'a: 'a, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[rustc_regions] +fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b>, + T::AssocType: 'a, +{ + // We are projecting `>::AssocType`, and we know + // that this outlives `'a` because of the where-clause. + + with_signature(cell, t, |cell, t| require(cell, t)); +} + +#[rustc_regions] +fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b>, + 'b: 'a, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +} + +#[rustc_regions] +fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'a>, +{ + // Note that in this case the closure still propagates an external + // requirement between two variables in its signature, but the + // creator maps both those two region variables to `'a` on its + // side. + with_signature(cell, t, |cell, t| require(cell, t)); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs new file mode 100644 index 000000000000..4cdc64fd27af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.rs @@ -0,0 +1,89 @@ +// Test cases where we constrain `>::AssocType` to +// outlive `'static`. In this case, we don't get any errors, and in fact +// we don't even propagate constraints from the closures to the callers. + +// compile-flags:-Zborrowck=mir -Zverbose +// check-pass + +#![allow(warnings)] +#![feature(rustc_attrs)] + +use std::cell::Cell; + +trait Anything<'a> { + type AssocType: 'static; +} + +fn with_signature<'a, T, F>(cell: Cell<&'a ()>, t: T, op: F) +where + F: FnOnce(Cell<&'a ()>, T), +{ + op(cell, t) +} + +fn require<'a, 'b, T>(_cell: Cell<&'a ()>, _t: T) +where + T: Anything<'b>, + T::AssocType: 'a, +{ +} + +#[rustc_regions] +fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b>, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +} + +#[rustc_regions] +fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b>, + 'a: 'a, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +} + +#[rustc_regions] +fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b>, + T::AssocType: 'a, +{ + // This error is unfortunate. This code ought to type-check: we + // are projecting `>::AssocType`, and we know + // that this outlives `'a` because of the where-clause. However, + // the way the region checker works, we don't register this + // outlives obligation, and hence we get an error: this is because + // what we see is a projection like `>::AssocType`, and we don't yet know if `?0` will + // equal `'b` or not, so we ignore the where-clause. Obviously we + // can do better here with a more involved verification step. + + with_signature(cell, t, |cell, t| require(cell, t)); +} + +#[rustc_regions] +fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b>, + 'b: 'a, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +} + +#[rustc_regions] +fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'a>, +{ + // Note that in this case the closure still propagates an external + // requirement between two variables in its signature, but the + // creator maps both those two region variables to `'a` on its + // side. + with_signature(cell, t, |cell, t| require(cell, t)); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs new file mode 100644 index 000000000000..afc038387406 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.rs @@ -0,0 +1,113 @@ +// Test cases where we constrain `>::AssocType` +// to outlive `'a` and there are two bounds in the trait definition of +// `Anything` -- i.e., we know that `AssocType` outlives `'a` and +// `'b`. In this case, it's not clear what is the best way to satisfy +// the trait bound, and hence we propagate it to the caller as a type +// test. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![allow(warnings)] +#![feature(rustc_attrs)] + +use std::cell::Cell; + +trait Anything<'a, 'b> { + type AssocType: 'a + 'b; +} + +fn with_signature<'a, T, F>(cell: Cell<&'a ()>, t: T, op: F) +where + F: FnOnce(Cell<&'a ()>, T), +{ + op(cell, t) +} + +fn require<'a, 'b, 'c, T>(_cell: Cell<&'a ()>, _t: T) +where + T: Anything<'b, 'c>, + T::AssocType: 'a, +{ +} + +#[rustc_regions] +fn no_relationships_late<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b, 'c>, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +#[rustc_regions] +fn no_relationships_early<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b, 'c>, + 'a: 'a, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +#[rustc_regions] +fn projection_outlives<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b, 'c>, + T::AssocType: 'a, +{ + // We are projecting `>::AssocType`, and we know + // that this outlives `'a` because of the where-clause. + + with_signature(cell, t, |cell, t| require(cell, t)); +} + +#[rustc_regions] +fn elements_outlive1<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b, 'c>, + 'b: 'a, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +} + +#[rustc_regions] +fn elements_outlive2<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b, 'c>, + 'c: 'a, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +} + +#[rustc_regions] +fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b, 'b>, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[rustc_regions] +fn two_regions_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'b, 'b>, + 'b: 'a, +{ + with_signature(cell, t, |cell, t| require(cell, t)); +} + +#[rustc_regions] +fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) +where + T: Anything<'a, 'a>, +{ + // Note that in this case the closure still propagates an external + // requirement between two variables in its signature, but the + // creator maps both those two region variables to `'a` on its + // side. + with_signature(cell, t, |cell, t| require(cell, t)); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.rs new file mode 100644 index 000000000000..169c06d2219a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.rs @@ -0,0 +1,35 @@ +// Test that we are able to establish that `>::Output` outlives `'b` here. We need to prove however +// that `>::Output` outlives `'a`, so we also have to +// prove that `'b: 'a`. + +trait MyTrait<'a> { + type Output; +} + +fn foo1<'a, 'b, T>() -> &'a () +where + T: MyTrait<'a>, + >::Output: 'b, +{ + bar::() // { dg-error ".E0309." "" { target *-*-* } } +} + +fn foo2<'a, 'b, T>() -> &'a () +where + T: MyTrait<'a>, + >::Output: 'b, + 'b: 'a, +{ + bar::() // OK +} + +fn bar<'a, T>() -> &'a () +where + T: 'a, +{ + &() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.rs new file mode 100644 index 000000000000..47912eb7d5cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.rs @@ -0,0 +1,26 @@ +// Test that if we need to prove that `>::Output: +// 'a`, but we only know that `>::Output: 'a`, that +// doesn't suffice. + +trait MyTrait<'a> { + type Output; +} + +fn foo1<'a, 'b, T>() -> &'a () +where + for<'x> T: MyTrait<'x>, + >::Output: 'a, +{ + bar::<>::Output>() +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn bar<'a, T>() -> &'a () +where + T: 'a, +{ + &() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-env.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-env.rs new file mode 100644 index 000000000000..64dedb97617d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-env.rs @@ -0,0 +1,29 @@ +// Test that when we have a `>::Output: 'a` +// relationship in the environment we take advantage of it. In this +// case, that means we **don't** have to prove that `T: 'a`. +// +// Regression test for #53121. +// +// check-pass + +trait MyTrait<'a> { + type Output; +} + +fn foo<'a, T>() -> &'a () +where + T: MyTrait<'a>, + >::Output: 'a, +{ + bar::() +} + +fn bar<'a, T>() -> &'a () +where + T: 'a, +{ + &() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-none.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-none.rs new file mode 100644 index 000000000000..7d9cef092962 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-none.rs @@ -0,0 +1,27 @@ +#![feature(nll)] + +// Test that we are NOT able to establish that `>::Output: 'a` outlives `'a` here -- we have only one +// recourse, which is to prove that `T: 'a` and `'a: 'a`, but we don't +// know that `T: 'a`. + +trait MyTrait<'a> { + type Output; +} + +fn foo<'a, T>() -> &'a () +where + T: MyTrait<'a>, +{ + bar::() // { dg-error ".E0309." "" { target *-*-* } } +} + +fn bar<'a, T>() -> &'a () +where + T: 'a, +{ + &() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-trait.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-trait.rs new file mode 100644 index 000000000000..54ef3cb0a997 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/projection-where-clause-trait.rs @@ -0,0 +1,28 @@ +#![feature(nll)] + +// Test that we are able to establish that `>::Output: 'a` outlives `'a` (because the trait says +// so). +// +// check-pass + +trait MyTrait<'a> { + type Output: 'a; +} + +fn foo<'a, T>() -> &'a () +where + T: MyTrait<'a>, +{ + bar::() +} + +fn bar<'a, T>() -> &'a () +where + T: 'a, +{ + &() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs new file mode 100644 index 000000000000..cd79bc454c9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.rs @@ -0,0 +1,40 @@ +// compile-flags:-Zborrowck=mir -Zverbose + +#![allow(warnings)] +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// Invoke in such a way that the callee knows: +// +// - 'a: 'x +// +// and it must prove that `T: 'x`. Callee passes along `T: 'a`. +fn twice<'a, F, T>(v: Cell<&'a ()>, value: T, mut f: F) +where + F: for<'x> FnMut(Option>, &T), +{ + f(None, &value); + f(None, &value); +} + +#[rustc_regions] +fn generic(value: T) { + let cell = Cell::new(&()); + twice(cell, value, |a, b| invoke(a, b)); +} + +#[rustc_regions] +fn generic_fail<'a, T>(cell: Cell<&'a ()>, value: T) { + twice(cell, value, |a, b| invoke(a, b)); +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn invoke<'a, 'x, T>(x: Option>, y: &T) +where + T: 'x, +{ +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs new file mode 100644 index 000000000000..a99d3e25d50f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs @@ -0,0 +1,54 @@ +// compile-flags:-Zborrowck=mir -Zverbose + +#![allow(warnings)] +#![feature(rustc_attrs)] + +use std::fmt::Debug; + +fn with_signature<'a, T, F>(x: Box, op: F) -> Box + where F: FnOnce(Box) -> Box +{ + op(x) +} + +#[rustc_regions] +fn no_region<'a, T>(x: Box) -> Box +where + T: Debug, +{ + // Here, the closure winds up being required to prove that `T: + // 'a`. In principle, it could know that, except that it is + // type-checked in a fully generic way, and hence it winds up with + // a propagated requirement that `T: '_#2`, where `'_#2` appears + // in the return type. The caller makes the mapping from `'_#2` to + // `'a` (and subsequently reports an error). + + with_signature(x, |y| y) +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn correct_region<'a, T>(x: Box) -> Box +where + T: 'a + Debug, +{ + x +} + +fn wrong_region<'a, 'b, T>(x: Box) -> Box +where + T: 'b + Debug, +{ + x +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn outlives_region<'a, 'b, T>(x: Box) -> Box +where + T: 'b + Debug, + 'b: 'a, +{ + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs new file mode 100644 index 000000000000..951ae6869acc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs @@ -0,0 +1,84 @@ +// Test that we can propagate `T: 'a` obligations to our caller. See +// `correct_region` for an explanation of how this test is setup; it's +// somewhat intricate. + +// compile-flags:-Zborrowck=mir -Zverbose + +#![allow(warnings)] +#![feature(rustc_attrs)] + +use std::cell::Cell; + +fn with_signature<'a, T, F>(a: Cell<&'a ()>, b: T, op: F) +where + F: FnOnce(Cell<&'a ()>, T), +{ + op(a, b) +} + +fn require<'a, T>(_a: &Cell<&'a ()>, _b: &T) +where + T: 'a, +{ +} + +#[rustc_regions] +fn no_region<'a, T>(a: Cell<&'a ()>, b: T) { + with_signature(a, b, |x, y| { +// { dg-error ".E0309." "" { target *-*-* } .-1 } + // + // See `correct_region`, which explains the point of this + // test. The only difference is that, in the case of this + // function, there is no where clause *anywhere*, and hence we + // get an error (but reported by the closure creator). + require(&x, &y) + }) +} + +#[rustc_regions] +fn correct_region<'a, T>(a: Cell<&'a ()>, b: T) +where + T: 'a, +{ + with_signature(a, b, |x, y| { + // Key point of this test: + // + // The *closure* is being type-checked with all of its free + // regions "universalized". In particular, it does not know + // that `x` has the type `Cell<&'a ()>`, but rather treats it + // as if the type of `x` is `Cell<&'A ()>`, where `'A` is some + // fresh, independent region distinct from the `'a` which + // appears in the environment. The call to `require` here + // forces us then to prove that `T: 'A`, but the closure + // cannot do it on its own. It has to surface this requirement + // to its creator (which knows that `'a == 'A`). + require(&x, &y) + }) +} + +#[rustc_regions] +fn wrong_region<'a, 'b, T>(a: Cell<&'a ()>, b: T) +where + T: 'b, +{ + with_signature(a, b, |x, y| { +// { dg-error ".E0309." "" { target *-*-* } .-1 } + // See `correct_region` + require(&x, &y) + }) +} + +#[rustc_regions] +fn outlives_region<'a, 'b, T>(a: Cell<&'a ()>, b: T) +where + T: 'b, + 'b: 'a, +{ + with_signature(a, b, |x, y| { + // See `correct_region` + require(&x, &y) + }) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-fn-body.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-fn-body.rs new file mode 100644 index 000000000000..dfbbe74d3409 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-fn-body.rs @@ -0,0 +1,30 @@ +// compile-flags:-Zborrowck=mir + +// Test that we assume that universal types like `T` outlive the +// function body. + +#![allow(warnings)] + +use std::cell::Cell; + +// No errors here, because `'a` is local to the body. +fn region_within_body(t: T) { + let some_int = 22; + let cell = Cell::new(&some_int); + outlives(cell, t) +} + +// Error here, because T: 'a is not satisfied. +fn region_static<'a, T>(cell: Cell<&'a usize>, t: T) { + outlives(cell, t) +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn outlives<'a, T>(x: Cell<&'a usize>, y: T) +where + T: 'a, +{ +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-fn.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-fn.rs new file mode 100644 index 000000000000..8d0e81ec152a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-fn.rs @@ -0,0 +1,39 @@ +// compile-flags:-Zborrowck=mir + +#![allow(warnings)] + +use std::fmt::Debug; + +fn no_region<'a, T>(x: Box) -> Box +where + T: Debug, +{ + x +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn correct_region<'a, T>(x: Box) -> Box +where + T: 'a + Debug, +{ + x +} + +fn wrong_region<'a, 'b, T>(x: Box) -> Box +where + T: 'b + Debug, +{ + x +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn outlives_region<'a, 'b, T>(x: Box) -> Box +where + T: 'b + Debug, + 'b: 'a, +{ + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-implied-bounds.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-implied-bounds.rs new file mode 100644 index 000000000000..99c61e319d3b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/ty-param-implied-bounds.rs @@ -0,0 +1,29 @@ +// compile-flags:-Zborrowck=mir -Zverbose +// check-pass + +// Test that we assume that universal types like `T` outlive the +// function body. + +use std::cell::Cell; + +fn twice(value: T, mut f: F) +where + F: FnMut(Cell<&T>), +{ + f(Cell::new(&value)); + f(Cell::new(&value)); +} + +fn generic(value: T) { + // No error here: + twice(value, |r| invoke(r)); +} + +fn invoke<'a, T>(x: Cell<&'a T>) +where + T: 'a, +{ +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/wf-unreachable.rs b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/wf-unreachable.rs new file mode 100644 index 000000000000..85ccfd09afb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/ty-outlives/wf-unreachable.rs @@ -0,0 +1,55 @@ +// Test that we check that user type annotations are well-formed, even in dead +// code. + +#![feature(nll)] + +fn uninit<'a>() { + return; + let x: &'static &'a (); // { dg-error "" "" { target *-*-* } } +} + +fn var_type<'a>() { + return; + let x: &'static &'a () = &&(); // { dg-error "" "" { target *-*-* } } +} + +fn uninit_infer<'a>() { + let x: &'static &'a _; // { dg-error "" "" { target *-*-* } } + x = && (); +} + +fn infer<'a>() { + return; + let x: &'static &'a _ = &&(); // { dg-error "" "" { target *-*-* } } +} + +fn uninit_no_var<'a>() { + return; + let _: &'static &'a (); // { dg-error "" "" { target *-*-* } } +} + +fn no_var<'a>() { + return; + let _: &'static &'a () = &&(); // { dg-error "" "" { target *-*-* } } +} + +fn infer_no_var<'a>() { + return; + let _: &'static &'a _ = &&(); // { dg-error "" "" { target *-*-* } } +} + +trait X<'a, 'b> {} + +struct C<'a, 'b, T: X<'a, 'b>>(T, &'a (), &'b ()); + +impl X<'_, '_> for i32 {} +impl<'a> X<'a, 'a> for () {} + +// This type annotation is not well-formed because we substitute `()` for `_`. +fn required_substs<'a>() { + return; + let _: C<'static, 'a, _> = C((), &(), &()); // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/type-alias-free-regions.rs b/gcc/testsuite/rust/rustc/ui/nll/type-alias-free-regions.rs new file mode 100644 index 000000000000..6b3be3a1dd92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/type-alias-free-regions.rs @@ -0,0 +1,32 @@ +// Test that we don't assume that type aliases have the same type parameters +// as the type they alias and then panic when we see this. + +type A<'a> = &'a isize; +type B<'a> = Box>; + +struct C<'a> { + f: Box> +} + +trait FromBox<'a> { + fn from_box(b: Box) -> Self; +} + +impl<'a> FromBox<'a> for C<'a> { + fn from_box(b: Box) -> Self { + C { f: b } // { dg-error ".E0495." "" { target *-*-* } } + } +} + +trait FromTuple<'a> { + fn from_tuple( b: (B,)) -> Self; +} + +impl<'a> FromTuple<'a> for C<'a> { + fn from_tuple(b: (B,)) -> Self { + C { f: Box::new(b.0) } // { dg-error ".E0495." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/type-check-pointer-coercions.rs b/gcc/testsuite/rust/rustc/ui/nll/type-check-pointer-coercions.rs new file mode 100644 index 000000000000..bcb2af89ea9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/type-check-pointer-coercions.rs @@ -0,0 +1,40 @@ +#![feature(nll)] + +fn shared_to_const<'a, 'b>(x: &&'a i32) -> *const &'b i32 { + x // { dg-error "" "" { target *-*-* } } +} + +fn unique_to_const<'a, 'b>(x: &mut &'a i32) -> *const &'b i32 { + x // { dg-error "" "" { target *-*-* } } +} + +fn unique_to_mut<'a, 'b>(x: &mut &'a i32) -> *mut &'b i32 { + // Two errors because *mut is invariant + x // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn mut_to_const<'a, 'b>(x: *mut &'a i32) -> *const &'b i32 { + x // { dg-error "" "" { target *-*-* } } +} + +fn array_elem<'a, 'b>(x: &'a i32) -> *const &'b i32 { + let z = &[x; 3]; + let y = z as *const &i32; + y // { dg-error "" "" { target *-*-* } } +} + +fn array_coerce<'a, 'b>(x: &'a i32) -> *const [&'b i32; 3] { + let z = &[x; 3]; + let y = z as *const [&i32; 3]; + y // { dg-error "" "" { target *-*-* } } +} + +fn nested_array<'a, 'b>(x: &'a i32) -> *const [&'b i32; 2] { + let z = &[[x; 2]; 3]; + let y = z as *const [&i32; 2]; + y // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/type-check-pointer-comparisons.rs b/gcc/testsuite/rust/rustc/ui/nll/type-check-pointer-comparisons.rs new file mode 100644 index 000000000000..c78738f54442 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/type-check-pointer-comparisons.rs @@ -0,0 +1,34 @@ +#![feature(nll)] + +// Check that we assert that pointers have a common subtype for comparisons + +fn compare_const<'a, 'b>(x: *const &mut &'a i32, y: *const &mut &'b i32) { + x == y; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn compare_mut<'a, 'b>(x: *mut &'a i32, y: *mut &'b i32) { + x == y; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn compare_fn_ptr<'a, 'b, 'c>(f: fn(&'c mut &'a i32), g: fn(&'c mut &'b i32)) { + f == g; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn compare_hr_fn_ptr<'a>(f: fn(&'a i32), g: fn(&i32)) { + // Ideally this should compile with the operands swapped as well, but HIR + // type checking prevents it (and stops compilation) for now. + f == g; // OK +} + +fn compare_const_fn_ptr<'a>(f: *const fn(&'a i32), g: *const fn(&i32)) { + f == g; // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/unused-mut-issue-50343.rs b/gcc/testsuite/rust/rustc/ui/nll/unused-mut-issue-50343.rs new file mode 100644 index 000000000000..5d0a54481a2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/unused-mut-issue-50343.rs @@ -0,0 +1,10 @@ +// run-rustfix + +#![deny(unused_mut)] +#![allow(unused_variables)] // for rustfix + +fn main() { + vec![(42, 22)].iter().map(|(mut x, _y)| ()).count(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-brace-enums.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-brace-enums.rs new file mode 100644 index 000000000000..f48a030a0611 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-brace-enums.rs @@ -0,0 +1,51 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +enum SomeEnum { + SomeVariant { t: T } +} + +fn no_annot() { + let c = 66; + SomeEnum::SomeVariant { t: &c }; +} + +fn annot_underscore() { + let c = 66; + SomeEnum::SomeVariant::<_> { t: &c }; +} + +fn annot_reference_any_lifetime() { + let c = 66; + SomeEnum::SomeVariant::<&u32> { t: &c }; +} + +fn annot_reference_static_lifetime() { + let c = 66; + SomeEnum::SomeVariant::<&'static u32> { t: &c }; // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + SomeEnum::SomeVariant::<&'a u32> { t: &c }; // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + SomeEnum::SomeVariant::<&'a u32> { t: c }; +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + SomeEnum::SomeVariant::<&'a u32> { t: &c }; // { dg-error ".E0597." "" { target *-*-* } } + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + SomeEnum::SomeVariant::<&'a u32> { t: c }; + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-brace-structs.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-brace-structs.rs new file mode 100644 index 000000000000..1167f25ed28d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-brace-structs.rs @@ -0,0 +1,49 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +struct SomeStruct { t: T } + +fn no_annot() { + let c = 66; + SomeStruct { t: &c }; +} + +fn annot_underscore() { + let c = 66; + SomeStruct::<_> { t: &c }; +} + +fn annot_reference_any_lifetime() { + let c = 66; + SomeStruct::<&u32> { t: &c }; +} + +fn annot_reference_static_lifetime() { + let c = 66; + SomeStruct::<&'static u32> { t: &c }; // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + SomeStruct::<&'a u32> { t: &c }; // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + SomeStruct::<&'a u32> { t: c }; +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + SomeStruct::<&'a u32> { t: &c }; // { dg-error ".E0597." "" { target *-*-* } } + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + SomeStruct::<&'a u32> { t: c }; + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-nullary-enums.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-nullary-enums.rs new file mode 100644 index 000000000000..9c46eb09d18f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-nullary-enums.rs @@ -0,0 +1,70 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +#![allow(warnings)] + +use std::cell::Cell; + +enum SomeEnum { + SomeVariant(T), + SomeOtherVariant, +} + +fn combine(_: T, _: T) { } + +fn no_annot() { + let c = 66; + combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant); +} + +fn annot_underscore() { + let c = 66; + combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant::>); +} + +fn annot_reference_any_lifetime() { + let c = 66; + combine(SomeEnum::SomeVariant(Cell::new(&c)), SomeEnum::SomeOtherVariant::>); +} + +fn annot_reference_static_lifetime() { + let c = 66; + combine( + SomeEnum::SomeVariant(Cell::new(&c)), // { dg-error ".E0597." "" { target *-*-* } } + SomeEnum::SomeOtherVariant::>, + ); +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + combine( + SomeEnum::SomeVariant(Cell::new(&c)), // { dg-error ".E0597." "" { target *-*-* } } + SomeEnum::SomeOtherVariant::>, + ); +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + combine(SomeEnum::SomeVariant(Cell::new(c)), SomeEnum::SomeOtherVariant::>); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + combine( + SomeEnum::SomeVariant(Cell::new(&c)), // { dg-error ".E0597." "" { target *-*-* } } + SomeEnum::SomeOtherVariant::>, + ); + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + combine( + SomeEnum::SomeVariant(Cell::new(c)), + SomeEnum::SomeOtherVariant::>, + ); + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-tuple-enums.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-tuple-enums.rs new file mode 100644 index 000000000000..fdd5901a856f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-tuple-enums.rs @@ -0,0 +1,54 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +#![allow(warnings)] + +enum SomeEnum { + SomeVariant(T), + SomeOtherVariant, +} + +fn no_annot() { + let c = 66; + SomeEnum::SomeVariant(&c); +} + +fn annot_underscore() { + let c = 66; + SomeEnum::SomeVariant::<_>(&c); +} + +fn annot_reference_any_lifetime() { + let c = 66; + SomeEnum::SomeVariant::<&u32>(&c); +} + +fn annot_reference_static_lifetime() { + let c = 66; + SomeEnum::SomeVariant::<&'static u32>(&c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + SomeEnum::SomeVariant::<&'a u32>(&c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + SomeEnum::SomeVariant::<&'a u32>(c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + SomeEnum::SomeVariant::<&'a u32>(&c); // { dg-error ".E0597." "" { target *-*-* } } + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + SomeEnum::SomeVariant::<&'a u32>(c); + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-tuple-struct-calls.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-tuple-struct-calls.rs new file mode 100644 index 000000000000..32e9dff804b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-tuple-struct-calls.rs @@ -0,0 +1,72 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +struct SomeStruct(T); + +fn no_annot() { + let c = 66; + let f = SomeStruct; + f(&c); +} + +fn annot_underscore() { + let c = 66; + let f = SomeStruct::<_>; + f(&c); +} + +fn annot_reference_any_lifetime() { + let c = 66; + let f = SomeStruct::<&u32>; + f(&c); +} + +fn annot_reference_static_lifetime() { + let c = 66; + let f = SomeStruct::<&'static u32>; + f(&c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + let f = SomeStruct::<&'a u32>; + f(&c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + let f = SomeStruct::<&'a u32>; + f(c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + let f = SomeStruct::<&'a u32>; + f(&c); // { dg-error ".E0597." "" { target *-*-* } } + }; +} + +fn annot_reference_named_lifetime_across_closure<'a>(_: &'a u32) { + let f = SomeStruct::<&'a u32>; + let _closure = || { + let c = 66; + f(&c); // { dg-error ".E0597." "" { target *-*-* } } + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + let f = SomeStruct::<&'a u32>; + f(c); + }; +} + +fn annot_reference_named_lifetime_across_closure_ok<'a>(c: &'a u32) { + let f = SomeStruct::<&'a u32>; + let _closure = || { + f(c); + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-tuple-struct.rs new file mode 100644 index 000000000000..038ef4b27a91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/adt-tuple-struct.rs @@ -0,0 +1,49 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +struct SomeStruct(T); + +fn no_annot() { + let c = 66; + SomeStruct(&c); +} + +fn annot_underscore() { + let c = 66; + SomeStruct::<_>(&c); +} + +fn annot_reference_any_lifetime() { + let c = 66; + SomeStruct::<&u32>(&c); +} + +fn annot_reference_static_lifetime() { + let c = 66; + SomeStruct::<&'static u32>(&c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + SomeStruct::<&'a u32>(&c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + SomeStruct::<&'a u32>(c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + SomeStruct::<&'a u32>(&c); // { dg-error ".E0597." "" { target *-*-* } } + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + SomeStruct::<&'a u32>(c); + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/cast_static_lifetime.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/cast_static_lifetime.rs new file mode 100644 index 000000000000..58b26626e5fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/cast_static_lifetime.rs @@ -0,0 +1,7 @@ +#![allow(warnings)] + +fn main() { + let x = 22_u32; + let y: &u32 = (&x) as &'static u32; // { dg-error ".E0597." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/closure-substs.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/closure-substs.rs new file mode 100644 index 000000000000..995b1dcbe4c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/closure-substs.rs @@ -0,0 +1,34 @@ +#![feature(nll)] + +// Test that we enforce user-provided type annotations on closures. + +fn foo<'a>() { + // Here `x` is free in the closure sig: + |x: &'a i32| -> &'static i32 { + return x; // { dg-error "" "" { target *-*-* } } + }; +} + +fn foo1() { + // Here `x` is bound in the closure sig: + |x: &i32| -> &'static i32 { + return x; // { dg-error "" "" { target *-*-* } } + }; +} + +fn bar<'a>() { + // Here `x` is free in the closure sig: + |x: &'a i32, b: fn(&'static i32)| { + b(x); // { dg-error "" "" { target *-*-* } } + }; +} + +fn bar1() { + // Here `x` is bound in the closure sig: + |x: &i32, b: fn(&'static i32)| { + b(x); // { dg-error ".E0521." "" { target *-*-* } } + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-inherent-1.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-inherent-1.rs new file mode 100644 index 000000000000..1022355fca1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-inherent-1.rs @@ -0,0 +1,13 @@ +struct Foo<'a> { x: &'a u32 } + +impl<'a> Foo<'a> { + const C: &'a u32 = &22; +} + +fn foo<'a>(_: &'a u32) -> &'static u32 { + >::C // { dg-error ".E0759." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-inherent-2.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-inherent-2.rs new file mode 100644 index 000000000000..4754ad9c1868 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-inherent-2.rs @@ -0,0 +1,28 @@ +// Test that we still check constants are well-formed, even when we there's no +// type annotation to check. + +const FUN: fn(&'static ()) = |_| {}; +struct A; +impl A { + const ASSOCIATED_FUN: fn(&'static ()) = |_| {}; +} + +struct B<'a>(&'a ()); +impl B<'static> { + const ALSO_ASSOCIATED_FUN: fn(&'static ()) = |_| {}; +} + +trait Z: 'static { + const TRAIT_ASSOCIATED_FUN: fn(&'static Self) = |_| (); +} + +impl Z for () {} + +fn main() { + let x = (); + FUN(&x); // { dg-error ".E0597." "" { target *-*-* } } + A::ASSOCIATED_FUN(&x); // { dg-error ".E0597." "" { target *-*-* } } + B::ALSO_ASSOCIATED_FUN(&x); // { dg-error ".E0597." "" { target *-*-* } } + <_>::TRAIT_ASSOCIATED_FUN(&x); // { dg-error ".E0597." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-normalize.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-normalize.rs new file mode 100644 index 000000000000..b13f2626f238 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-normalize.rs @@ -0,0 +1,23 @@ +trait Mirror { + type Me; +} + +impl Mirror for T { + type Me = T; +} + +trait Foo<'a> { + const C: <&'a u32 as Mirror>::Me; +} + +impl<'a, T> Foo<'a> for T { + const C: &'a u32 = &22; +} + +fn foo<'a>(_: &'a u32) -> &'static u32 { + <() as Foo<'a>>::C // { dg-error ".E0312." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs new file mode 100644 index 000000000000..e8965308975d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-1.rs @@ -0,0 +1,15 @@ +trait Foo<'a> { + const C: &'a u32; +} + +impl<'a, T> Foo<'a> for T { + const C: &'a u32 = &22; +} + +fn foo<'a>(_: &'a u32) -> &'static u32 { + <() as Foo<'a>>::C // { dg-error ".E0312." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs new file mode 100644 index 000000000000..99e9bfd3e853 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-2.rs @@ -0,0 +1,15 @@ +trait Foo<'a> { + const C: &'a u32; +} + +impl<'a, T> Foo<'a> for T { + const C: &'a u32 = &22; +} + +fn foo<'a, T: Foo<'a>>() -> &'static u32 { + >::C // { dg-error ".E0312." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs new file mode 100644 index 000000000000..1c84d8cea50d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/constant-in-expr-trait-item-3.rs @@ -0,0 +1,15 @@ +trait Foo<'a> { + const C: &'a u32; +} + +impl<'a, T> Foo<'a> for T { + const C: &'a u32 = &22; +} + +fn foo<'a, T: Foo<'a>>() -> &'static u32 { + T::C // { dg-error ".E0495." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/downcast-infer.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/downcast-infer.rs new file mode 100644 index 000000000000..be42069cd334 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/downcast-infer.rs @@ -0,0 +1,12 @@ +// check-pass + +// Check that we don't try to downcast `_` when type-checking the annotation. +fn main() { + let x = Some(Some(Some(1))); + + match x { + Some::>(Some(Some(v))) => (), + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/dump-adt-brace-struct.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/dump-adt-brace-struct.rs new file mode 100644 index 000000000000..05cef61394ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/dump-adt-brace-struct.rs @@ -0,0 +1,22 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +// compile-flags:-Zverbose + +#![allow(warnings)] +#![feature(nll)] +#![feature(rustc_attrs)] + +struct SomeStruct { t: T } + +#[rustc_dump_user_substs] +fn main() { + SomeStruct { t: 22 }; // Nothing given, no annotation. + + SomeStruct::<_> { t: 22 }; // Nothing interesting given, no annotation. + + SomeStruct:: { t: 22 }; // No lifetime bounds given. + + SomeStruct::<&'static u32> { t: &22 }; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/dump-fn-method.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/dump-fn-method.rs new file mode 100644 index 000000000000..8845a3d6fde9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/dump-fn-method.rs @@ -0,0 +1,59 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +// compile-flags:-Zverbose + +#![feature(nll)] +#![feature(rustc_attrs)] + +// Note: we reference the names T and U in the comments below. +trait Bazoom { + fn method(&self, arg: T, arg2: U) { } +} + +impl Bazoom for S { +} + +fn foo<'a, T>(_: T) { } + +#[rustc_dump_user_substs] +fn main() { + // Here: nothing is given, so we don't have any annotation. + let x = foo; + x(22); + + // Here: `u32` is given, which doesn't contain any lifetimes, so we don't + // have any annotation. + let x = foo::; + x(22); + + let x = foo::<&'static u32>; // { dg-error "" "" { target *-*-* } } + x(&22); + + // Here: we only want the `T` to be given, the rest should be variables. + // + // (`T` refers to the declaration of `Bazoom`) + let x = <_ as Bazoom>::method::<_>; // { dg-error "" "" { target *-*-* } } + x(&22, 44, 66); + + // Here: all are given and definitely contain no lifetimes, so we + // don't have any annotation. + let x = >::method::; + x(&22, 44, 66); + + // Here: all are given and we have a lifetime. + let x = >::method::; // { dg-error "" "" { target *-*-* } } + x(&22, &44, 66); + + // Here: we want in particular that *only* the method `U` + // annotation is given, the rest are variables. + // + // (`U` refers to the declaration of `Bazoom`) + let y = 22_u32; + y.method::(44, 66); // { dg-error "" "" { target *-*-* } } + + // Here: nothing is given, so we don't have any annotation. + let y = 22_u32; + y.method(44, 66); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/fns.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/fns.rs new file mode 100644 index 000000000000..106f2ba365dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/fns.rs @@ -0,0 +1,49 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +fn some_fn(arg: T) { } + +fn no_annot() { + let c = 66; + some_fn(&c); // OK +} + +fn annot_underscore() { + let c = 66; + some_fn::<_>(&c); // OK +} + +fn annot_reference_any_lifetime() { + let c = 66; + some_fn::<&u32>(&c); // OK +} + +fn annot_reference_static_lifetime() { + let c = 66; + some_fn::<&'static u32>(&c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let c = 66; + some_fn::<&'a u32>(&c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + some_fn::<&'a u32>(c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let _closure = || { + let c = 66; + some_fn::<&'a u32>(&c); // { dg-error ".E0597." "" { target *-*-* } } + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let _closure = || { + some_fn::<&'a u32>(c); + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/inherent-associated-constants.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/inherent-associated-constants.rs new file mode 100644 index 000000000000..18faffd0dd14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/inherent-associated-constants.rs @@ -0,0 +1,18 @@ +#![feature(nll)] + +struct A<'a>(&'a ()); + +impl A<'static> { + const IC: i32 = 10; +} + +fn non_wf_associated_const<'a>(x: i32) { + A::<'a>::IC; // { dg-error "" "" { target *-*-* } } +} + +fn wf_associated_const<'a>(x: i32) { + A::<'static>::IC; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-54124.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-54124.rs new file mode 100644 index 000000000000..7909b835aa97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-54124.rs @@ -0,0 +1,11 @@ +#![feature(nll)] + +fn test<'a>() { + let _:fn(&()) = |_:&'a ()| {}; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-54570-bootstrapping.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-54570-bootstrapping.rs new file mode 100644 index 000000000000..91ed1fe63787 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-54570-bootstrapping.rs @@ -0,0 +1,31 @@ +// check-pass + +// This test is reduced from a scenario pnkfelix encountered while +// bootstrapping the compiler. + +#[derive(Copy, Clone)] +pub struct Spanned { + pub node: T, + pub span: Span, +} + +pub type Variant = Spanned; +// #[derive(Clone)] pub struct Variant { pub node: VariantKind, pub span: Span, } + +#[derive(Clone)] +pub struct VariantKind { } + +#[derive(Copy, Clone)] +pub struct Span; + +pub fn variant_to_span(variant: Variant) { + match variant { + Variant { + span: _span, + .. + } => { } + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-55219.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-55219.rs new file mode 100644 index 000000000000..c0fea57bc817 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-55219.rs @@ -0,0 +1,19 @@ +// Regression test for #55219: +// +// The `Self::HASH_LEN` here expands to a "self-type" where `T` is not +// known. This unbound inference variable was causing an ICE. +// +// check-pass + +pub struct Foo(T); + +impl Foo { + const HASH_LEN: usize = 20; + + fn stuff() { + let _ = Self::HASH_LEN; + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-55241.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-55241.rs new file mode 100644 index 000000000000..b863c4056451 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-55241.rs @@ -0,0 +1,27 @@ +// Regression test for #55241: +// +// The reference to `C::HASHED_NULL_NODE` resulted in a type like `>::Out`; normalizing this type requires knowing the +// value of `_`; solving that requires having normalized, so we can +// test against `C: NodeCodec` in the environment. +// +// run-pass + +pub trait Hasher { + type Out: Eq; +} + +pub trait NodeCodec { + const HASHED_NULL_NODE: H::Out; +} + +pub trait Trie> { + /// Returns the root of the trie. + fn root(&self) -> &H::Out; + + /// Is the trie empty? + fn is_empty(&self) -> bool { *self.root() == C::HASHED_NULL_NODE } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs new file mode 100644 index 000000000000..0e9a6364fac3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs @@ -0,0 +1,71 @@ +// This test is ensuring that type ascriptions on let bindings +// constrain both: +// +// 1. the input expression on the right-hand side (after any potential +// coercion, and allowing for covariance), *and* +// +// 2. the bindings (if any) nested within the pattern on the left-hand +// side (and here, the type-constraint is *invariant*). + +#![feature(nll)] + +#![allow(dead_code, unused_mut)] +type PairUncoupled<'a, 'b, T> = (&'a T, &'b T); +type PairCoupledRegions<'a, T> = (&'a T, &'a T); +type PairCoupledTypes = (T, T); + +fn uncoupled_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((mut y, mut _z),): (PairUncoupled,) = ((s, &_x),); // ok + // Above compiling does *not* imply below would compile. + // ::std::mem::swap(&mut y, &mut _z); + y +} + +fn swap_regions((mut y, mut _z): PairCoupledRegions) { + ::std::mem::swap(&mut y, &mut _z); +} + +fn coupled_regions_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),): (PairCoupledRegions,) = ((s, &_x),); + // If above line compiled, so should line below ... + + // swap_regions((y, _z)); + + // ... but the ascribed type also invalidates this use of `y` + y // { dg-error "" "" { target *-*-* } } +} + +fn swap_types((mut y, mut _z): PairCoupledTypes<&u32>) { + ::std::mem::swap(&mut y, &mut _z); +} + +fn coupled_types_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),): (PairCoupledTypes<&u32>,) = ((s, &_x),); + // If above line compiled, so should line below ... + + // swap_types((y, _z)); + + // ... but the ascribed type also invalidates this use of `y` + y // { dg-error "" "" { target *-*-* } } +} + +fn swap_wilds((mut y, mut _z): PairCoupledTypes<&u32>) { + ::std::mem::swap(&mut y, &mut _z); +} + +fn coupled_wilds_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),): (PairCoupledTypes<_>,) = ((s, &_x),); + // If above line compiled, so should line below + // swap_wilds((y, _z)); + + // ... but the ascribed type also invalidates this use of `y` + y // { dg-error "" "" { target *-*-* } } +} + +fn main() { + uncoupled_lhs(&3, &4); + coupled_regions_lhs(&3, &4); + coupled_types_lhs(&3, &4); + coupled_wilds_lhs(&3, &4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs new file mode 100644 index 000000000000..6725f307df63 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/issue-57731-ascibed-coupled-types.rs @@ -0,0 +1,41 @@ +// Check that repeated type variables are correctly handled + +#![allow(unused)] +#![feature(nll, type_ascription)] + +type PairUncoupled<'a, 'b, T> = (&'a T, &'b T); +type PairCoupledTypes = (T, T); +type PairCoupledRegions<'a, T> = (&'a T, &'a T); + +fn uncoupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),): (PairUncoupled<_>,); + y // OK +} + +fn coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),): (PairCoupledTypes<_>,); + y // { dg-error "" "" { target *-*-* } } +} + +fn coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),): (PairCoupledRegions<_>,); + y // { dg-error "" "" { target *-*-* } } +} + +fn cast_uncoupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),) as (PairUncoupled<_>,); + y // OK +} + +fn cast_coupled_wilds_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),) as (PairCoupledTypes<_>,); + y // { dg-error "" "" { target *-*-* } } +} + +fn cast_coupled_regions_rhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),) = ((s, _x),) as (PairCoupledRegions<_>,); + y // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-call.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-call.rs new file mode 100644 index 000000000000..c8755e2234ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-call.rs @@ -0,0 +1,70 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +trait Bazoom { + fn method(&self, arg: T, arg2: U) { } +} + +impl Bazoom for T { +} + +fn no_annot() { + let a = 22; + let b = 44; + let c = 66; + a.method(b, &c); // OK +} + +fn annot_underscore() { + let a = 22; + let b = 44; + let c = 66; + a.method::<_>(b, &c); // OK +} + +fn annot_reference_any_lifetime() { + let a = 22; + let b = 44; + let c = 66; + a.method::<&u32>(b, &c); // OK +} + +fn annot_reference_static_lifetime() { + let a = 22; + let b = 44; + let c = 66; + a.method::<&'static u32>(b, &c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let a = 22; + let b = 44; + let c = 66; + a.method::<&'a u32>(b, &c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + let a = 22; + let b = 44; + a.method::<&'a u32>(b, c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let a = 22; + let b = 44; + let _closure = || { + let c = 66; + a.method::<&'a u32>(b, &c); // { dg-error ".E0597." "" { target *-*-* } } + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let a = 22; + let b = 44; + let _closure = || { + a.method::<&'a u32>(b, c); + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-1.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-1.rs new file mode 100644 index 000000000000..6301472d9802 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-1.rs @@ -0,0 +1,64 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +trait Bazoom: Sized { + fn method(self, arg: T, arg2: U) { } +} + +impl Bazoom for T { +} + +fn annot_underscore() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method::<_>(&a, b, c); // OK +} + +fn annot_reference_any_lifetime() { + let a = 22; + let b = 44; + let c = 66; + <&u32 as Bazoom<_>>::method(&a, b, c); // OK +} + +fn annot_reference_static_lifetime() { + let a = 22; + let b = 44; + let c = 66; + let x = <&'static u32 as Bazoom<_>>::method; + x(&a, b, c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let a = 22; + let b = 44; + let c = 66; + <&'a u32 as Bazoom<_>>::method(&a, b, c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime_ok<'a>(a: &'a u32) { + let b = 44; + let c = 66; + <&'a u32 as Bazoom<_>>::method(&a, b, c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let a = 22; + let b = 44; + let _closure = || { + let c = 66; + <&'a u32 as Bazoom<_>>::method(&a, b, c); // { dg-error ".E0597." "" { target *-*-* } } + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(a: &'a u32) { + let b = 44; + let c = 66; + let _closure = || { + <&'a u32 as Bazoom<_>>::method(&a, b, c); + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-2.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-2.rs new file mode 100644 index 000000000000..86c5ae282b2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-2.rs @@ -0,0 +1,64 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +trait Bazoom: Sized { + fn method(self, arg: T, arg2: U) { } +} + +impl Bazoom for T { +} + +fn annot_underscore() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method(a, &b, c); // OK +} + +fn annot_reference_any_lifetime() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<&u32>>::method(a, &b, c); // OK +} + +fn annot_reference_static_lifetime() { + let a = 22; + let b = 44; + let c = 66; + let x = <&'static u32 as Bazoom<_>>::method; + x(&a, b, c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<&'a u32>>::method(a, &b, c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime_ok<'a>(b: &'a u32) { + let a = 44; + let c = 66; + <_ as Bazoom<&'a u32>>::method(a, &b, c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let a = 22; + let b = 44; + let _closure = || { + let c = 66; + <_ as Bazoom<&'a u32>>::method(a, &b, c); // { dg-error ".E0597." "" { target *-*-* } } + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(b: &'a u32) { + let a = 44; + let c = 66; + let _closure = || { + <_ as Bazoom<&'a u32>>::method(a, &b, c); + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-3.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-3.rs new file mode 100644 index 000000000000..0c43bd80d94c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-3.rs @@ -0,0 +1,70 @@ +// Unit test for the "user substitutions" that are annotated on each +// node. + +trait Bazoom { + fn method(&self, arg: T, arg2: U) { } +} + +impl Bazoom for T { +} + +fn no_annot() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method(&a, b, &c); // OK +} + +fn annot_underscore() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method::<_>(&a, b, &c); // OK +} + +fn annot_reference_any_lifetime() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method::<&u32>(&a, b, &c); // OK +} + +fn annot_reference_static_lifetime() { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method::<&'static u32>(&a, b, &c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime<'a>(_d: &'a u32) { + let a = 22; + let b = 44; + let c = 66; + <_ as Bazoom<_>>::method::<&'a u32>(&a, b, &c); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn annot_reference_named_lifetime_ok<'a>(c: &'a u32) { + let a = 22; + let b = 44; + <_ as Bazoom<_>>::method::<&'a u32>(&a, b, c); +} + +fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { + let a = 22; + let b = 44; + let _closure = || { + let c = 66; + <_ as Bazoom<_>>::method::<&'a u32>(&a, b, &c); // { dg-error ".E0597." "" { target *-*-* } } + }; +} + +fn annot_reference_named_lifetime_in_closure_ok<'a>(c: &'a u32) { + let a = 22; + let b = 44; + let _closure = || { + <_ as Bazoom<_>>::method::<&'a u32>(&a, b, c); + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-1.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-1.rs new file mode 100644 index 000000000000..44e651686cfb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-1.rs @@ -0,0 +1,21 @@ +#![feature(nll)] + +// Check that substitutions given on the self type (here, `A`) carry +// through to NLL. + +struct A<'a> { x: &'a u32 } + +impl<'a> A<'a> { + fn new<'b, T>(x: &'a u32, y: T) -> Self { + Self { x } + } +} + +fn foo<'a>() { + let v = 22; + let x = A::<'a>::new(&v, 22); +// { dg-error ".E0597." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-2.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-2.rs new file mode 100644 index 000000000000..bf2a85480cd8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-2.rs @@ -0,0 +1,20 @@ +// Check that substitutions given on the self type (here, `A`) can be +// used in combination with annotations given for method arguments. + +struct A<'a> { x: &'a u32 } + +impl<'a> A<'a> { + fn new<'b, T>(x: &'a u32, y: T) -> Self { + Self { x } + } +} + +fn foo<'a>() { + let v = 22; + let x = A::<'a>::new::<&'a u32>(&v, &v); +// { dg-error ".E0597." "" { target *-*-* } .-1 } +// { dg-error ".E0597." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-3.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-3.rs new file mode 100644 index 000000000000..a7ace7825eb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-3.rs @@ -0,0 +1,21 @@ +#![feature(nll)] + +// Check that inherent methods invoked with `::new` style +// carry their annotations through to NLL. + +struct A<'a> { x: &'a u32 } + +impl<'a> A<'a> { + fn new<'b, T>(x: &'a u32, y: T) -> Self { + Self { x } + } +} + +fn foo<'a>() { + let v = 22; + let x = >::new(&v, 22); +// { dg-error ".E0597." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-4.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-4.rs new file mode 100644 index 000000000000..277c3b94d2d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/method-ufcs-inherent-4.rs @@ -0,0 +1,21 @@ +// Check that inherent methods invoked with `::new` style +// carry their annotations through to NLL in connection with +// method type parameters. + +struct A<'a> { x: &'a u32 } + +impl<'a> A<'a> { + fn new<'b, T>(x: &'a u32, y: T) -> Self { + Self { x } + } +} + +fn foo<'a>() { + let v = 22; + let x = >::new::<&'a u32>(&v, &v); +// { dg-error ".E0597." "" { target *-*-* } .-1 } +// { dg-error ".E0597." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/normalization.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/normalization.rs new file mode 100644 index 000000000000..9bcb4e43f660 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/normalization.rs @@ -0,0 +1,11 @@ +// Test that we enforce a `&'static` requirement that is only visible +// after normalization. + +trait Foo { type Out; } +impl Foo for () { type Out = &'static u32; } + +fn main() { + let a = 22; + let b: <() as Foo>::Out = &a; // { dg-error ".E0597." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/normalize-self-ty.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/normalize-self-ty.rs new file mode 100644 index 000000000000..c5d31f46c012 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/normalize-self-ty.rs @@ -0,0 +1,24 @@ +// Regression test for #55183: check a case where the self type from +// the inherent impl requires normalization to be equal to the +// user-provided type. +// +// check-pass + +trait Mirror { + type Me; +} + +impl Mirror for T { + type Me = T; +} + +struct Foo(A, B); + +impl Foo::Me> { + fn m(_: A) { } +} + +fn main() { + >::m(&22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs new file mode 100644 index 000000000000..525575c11c9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_brace_enum_variant.rs @@ -0,0 +1,23 @@ +enum Foo<'a> { + Bar { field: &'a u32 } +} + +fn in_let() { + let y = 22; + let foo = Foo::Bar { field: &y }; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + let Foo::Bar::<'static> { field: _z } = foo; +} + +fn in_match() { + let y = 22; + let foo = Foo::Bar { field: &y }; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + match foo { + Foo::Bar::<'static> { field: _z } => { + } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs new file mode 100644 index 000000000000..b3d13480733a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_brace_struct.rs @@ -0,0 +1,21 @@ +struct Foo<'a> { field: &'a u32 } + +fn in_let() { + let y = 22; + let foo = Foo { field: &y }; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + let Foo::<'static> { field: _z } = foo; +} + +fn in_main() { + let y = 22; + let foo = Foo { field: &y }; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + match foo { + Foo::<'static> { field: _z } => { + } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs new file mode 100644 index 000000000000..cd0a1d57f468 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_tuple_enum_variant.rs @@ -0,0 +1,23 @@ +enum Foo<'a> { + Bar(&'a u32) +} + +fn in_let() { + let y = 22; + let foo = Foo::Bar(&y); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + let Foo::Bar::<'static>(_z) = foo; +} + +fn in_match() { + let y = 22; + let foo = Foo::Bar(&y); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + match foo { + Foo::Bar::<'static>(_z) => { + } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs new file mode 100644 index 000000000000..32f11f553078 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/pattern_substs_on_tuple_struct.rs @@ -0,0 +1,21 @@ +struct Foo<'a>(&'a u32); + +fn in_let() { + let y = 22; + let foo = Foo(&y); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + let Foo::<'static>(_z) = foo; +} + +fn in_match() { + let y = 22; + let foo = Foo(&y); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + match foo { + Foo::<'static>(_z) => { + } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/patterns.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/patterns.rs new file mode 100644 index 000000000000..33fda3fcfafe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/patterns.rs @@ -0,0 +1,139 @@ +// Test that various patterns also enforce types. + +#![feature(nll)] + +fn variable_no_initializer() { + let x = 22; + let y: &'static u32; + y = &x; // { dg-error ".E0597." "" { target *-*-* } } +} + +fn tuple_no_initializer() { + + + let x = 22; + let (y, z): (&'static u32, &'static u32); + y = &x; // { dg-error ".E0597." "" { target *-*-* } } +} + +fn ref_with_ascribed_static_type() -> u32 { + // Check the behavior in some wacky cases. + let x = 22; + let y = &x; // { dg-error ".E0597." "" { target *-*-* } } + let ref z: &'static u32 = y; + **z +} + +fn ref_with_ascribed_any_type() -> u32 { + let x = 22; + let y = &x; + let ref z: &u32 = y; + **z +} + +struct Single { value: T } + +fn struct_no_initializer() { + + + let x = 22; + let Single { value: y }: Single<&'static u32>; + y = &x; // { dg-error ".E0597." "" { target *-*-* } } +} + + +fn struct_no_initializer_must_normalize() { + trait Indirect { type Assoc; } + struct StaticU32; + impl Indirect for StaticU32 { type Assoc = &'static u32; } + struct Single2 { value: ::Assoc } + + let x = 22; + let Single2 { value: mut _y }: Single2; + _y = &x; // { dg-error ".E0597." "" { target *-*-* } } +} + +fn variable_with_initializer() { + let x = 22; + let y: &'static u32 = &x; // { dg-error ".E0597." "" { target *-*-* } } +} + +fn underscore_with_initializer() { + let x = 22; + let _: &'static u32 = &x; // { dg-error ".E0597." "" { target *-*-* } } + + let _: Vec<&'static String> = vec![&String::new()]; +// { dg-error ".E0716." "" { target *-*-* } .-1 } + + let (_, a): (Vec<&'static String>, _) = (vec![&String::new()], 44); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + + let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44); +// { dg-error ".E0716." "" { target *-*-* } .-1 } +} + +fn pair_underscores_with_initializer() { + let x = 22; + let (_, _): (&'static u32, u32) = (&x, 44); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn pair_variable_with_initializer() { + let x = 22; + let (y, _): (&'static u32, u32) = (&x, 44); // { dg-error ".E0597." "" { target *-*-* } } +} + +fn struct_single_field_variable_with_initializer() { + let x = 22; + let Single { value: y }: Single<&'static u32> = Single { value: &x }; // { dg-error ".E0597." "" { target *-*-* } } +} + +fn struct_single_field_underscore_with_initializer() { + let x = 22; + let Single { value: _ }: Single<&'static u32> = Single { value: &x }; // { dg-error ".E0597." "" { target *-*-* } } +} + +struct Double { value1: T, value2: T } + +fn struct_double_field_underscore_with_initializer() { + let x = 22; + let Double { value1: _, value2: _ }: Double<&'static u32> = Double { + value1: &x, // { dg-error ".E0597." "" { target *-*-* } } + value2: &44, + }; +} + +fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 { + + + + + + + let y: &'a u32 = &22; + y // { dg-error "" "" { target *-*-* } } +} + +fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 { + + + + + + + + let (y, _z): (&'a u32, u32) = (&22, 44); + y // { dg-error "" "" { target *-*-* } } +} + +fn static_to_a_to_static_through_struct<'a>(_x: &'a u32) -> &'static u32 { + let Single { value: y }: Single<&'a u32> = Single { value: &22 }; + y // { dg-error "" "" { target *-*-* } } +} + +fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 { + let (y, _z): (&'static u32, u32) = (x, 44); // { dg-error "" "" { target *-*-* } } + y +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/promoted-annotation.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/promoted-annotation.rs new file mode 100644 index 000000000000..831f6898a78d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/promoted-annotation.rs @@ -0,0 +1,11 @@ +// Test that type annotations are checked in promoted constants correctly. + +fn foo<'a>() { + let x = 0; + let f = &drop::<&'a i32>; + f(&x); +// { dg-error ".E0597." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/type-annotation-with-hrtb.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/type-annotation-with-hrtb.rs new file mode 100644 index 000000000000..d9b71d6f0c34 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/type-annotation-with-hrtb.rs @@ -0,0 +1,34 @@ +// Regression test for issue #69490 + +// check-pass + +pub trait Trait { + const S: &'static str; +} + +impl Trait<()> for T +where + T: for<'a> Trait<&'a ()>, +{ + // Use of `T::S` here caused an ICE + const S: &'static str = T::S; +} + +// Some similar cases that didn't ICE: + +impl<'a, T> Trait<()> for (T,) +where + T: Trait<&'a ()>, +{ + const S: &'static str = T::S; +} + +impl Trait<()> for [T; 1] +where + T: Trait fn(&'a ())>, +{ + const S: &'static str = T::S; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/type_ascription_static_lifetime.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/type_ascription_static_lifetime.rs new file mode 100644 index 000000000000..80c4a807239e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/type_ascription_static_lifetime.rs @@ -0,0 +1,8 @@ +#![allow(warnings)] +#![feature(type_ascription)] + +fn main() { + let x = 22_u32; + let y: &u32 = &x: &'static u32; // { dg-error ".E0597." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/user-annotations/wf-self-type.rs b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/wf-self-type.rs new file mode 100644 index 000000000000..b1247b0e22d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/user-annotations/wf-self-type.rs @@ -0,0 +1,16 @@ +#![feature(nll)] + +struct Foo<'a, 'b: 'a>(&'a &'b ()); + +impl<'a, 'b> Foo<'a, 'b> { + fn xmute(a: &'b ()) -> &'a () { + unreachable!() + } +} + +pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { + Foo::xmute(u) // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/where_clauses_in_functions.rs b/gcc/testsuite/rust/rustc/ui/nll/where_clauses_in_functions.rs new file mode 100644 index 000000000000..67fc06489b4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/where_clauses_in_functions.rs @@ -0,0 +1,18 @@ +// compile-flags: -Zborrowck=mir + +#![allow(dead_code)] + +fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) +where + 'a: 'b, +{ + (x, y) +} + +fn bar<'a, 'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) { + foo(x, y) +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/nll/where_clauses_in_structs.rs b/gcc/testsuite/rust/rustc/ui/nll/where_clauses_in_structs.rs new file mode 100644 index 000000000000..5c58a2e1368a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nll/where_clauses_in_structs.rs @@ -0,0 +1,18 @@ +// compile-flags: -Z borrowck=mir + +#![allow(dead_code)] + +use std::cell::Cell; + +struct Foo<'a: 'b, 'b> { + x: Cell<&'a u32>, + y: Cell<&'b u32>, +} + +fn bar<'a, 'b>(x: Cell<&'a u32>, y: Cell<&'b u32>) { + Foo { x, y }; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/no-capture-arc.rs b/gcc/testsuite/rust/rustc/ui/no-capture-arc.rs new file mode 100644 index 000000000000..5fecc6465110 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-capture-arc.rs @@ -0,0 +1,18 @@ +// error-pattern: borrow of moved value + +use std::sync::Arc; +use std::thread; + +fn main() { + let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let arc_v = Arc::new(v); + + thread::spawn(move|| { + assert_eq!((*arc_v)[3], 4); + }); + + assert_eq!((*arc_v)[2], 3); + + println!("{:?}", *arc_v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/no-core-1.rs b/gcc/testsuite/rust/rustc/ui/no-core-1.rs new file mode 100644 index 000000000000..87edb0a556ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-core-1.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(stable_features)] +#![feature(no_core, core)] +#![no_core] + +extern crate std; +extern crate core; + +use std::option::Option::Some; + +fn main() { + let a = Some("foo"); + a.unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/no-core-2.rs b/gcc/testsuite/rust/rustc/ui/no-core-2.rs new file mode 100644 index 000000000000..7f06b988147d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-core-2.rs @@ -0,0 +1,21 @@ +// run-pass + +#![allow(dead_code, unused_imports)] +#![feature(no_core)] +#![no_core] +// edition:2018 + +extern crate std; +extern crate core; +use core::{prelude::v1::*, *}; + +fn foo() { + for _ in &[()] {} +} + +fn bar() -> Option<()> { + None? +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/no-implicit-prelude-nested.rs b/gcc/testsuite/rust/rustc/ui/no-implicit-prelude-nested.rs new file mode 100644 index 000000000000..7053542205c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-implicit-prelude-nested.rs @@ -0,0 +1,55 @@ +// Test that things from the prelude aren't in scope. Use many of them +// so that renaming some things won't magically make this test fail +// for the wrong reason (e.g., if `Add` changes to `Addition`, and +// `no_implicit_prelude` stops working, then the `impl Add` will still +// fail with the same error message). + +#[no_implicit_prelude] +mod foo { + mod baz { + struct Test; + impl Add for Test {} // { dg-error ".E0405." "" { target *-*-* } } + impl Clone for Test {} // { dg-error ".E0404." "" { target *-*-* } } + impl Iterator for Test {} // { dg-error ".E0405." "" { target *-*-* } } + impl ToString for Test {} // { dg-error ".E0405." "" { target *-*-* } } + impl Writer for Test {} // { dg-error ".E0405." "" { target *-*-* } } + + fn foo() { + drop(2) // { dg-error ".E0425." "" { target *-*-* } } + } + } + + struct Test; + impl Add for Test {} // { dg-error ".E0405." "" { target *-*-* } } + impl Clone for Test {} // { dg-error ".E0404." "" { target *-*-* } } + impl Iterator for Test {} // { dg-error ".E0405." "" { target *-*-* } } + impl ToString for Test {} // { dg-error ".E0405." "" { target *-*-* } } + impl Writer for Test {} // { dg-error ".E0405." "" { target *-*-* } } + + fn foo() { + drop(2) // { dg-error ".E0425." "" { target *-*-* } } + } +} + +fn qux() { + #[no_implicit_prelude] + mod qux_inner { + struct Test; + impl Add for Test {} // { dg-error ".E0405." "" { target *-*-* } } + impl Clone for Test {} // { dg-error ".E0404." "" { target *-*-* } } + impl Iterator for Test {} // { dg-error ".E0405." "" { target *-*-* } } + impl ToString for Test {} // { dg-error ".E0405." "" { target *-*-* } } + impl Writer for Test {} // { dg-error ".E0405." "" { target *-*-* } } + + fn foo() { + drop(2) // { dg-error ".E0425." "" { target *-*-* } } + } + } +} + + +fn main() { + // these should work fine + drop(2) +} + diff --git a/gcc/testsuite/rust/rustc/ui/no-implicit-prelude.rs b/gcc/testsuite/rust/rustc/ui/no-implicit-prelude.rs new file mode 100644 index 000000000000..2478664f9f82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-implicit-prelude.rs @@ -0,0 +1,19 @@ +#![no_implicit_prelude] + +// Test that things from the prelude aren't in scope. Use many of them +// so that renaming some things won't magically make this test fail +// for the wrong reason (e.g., if `Add` changes to `Addition`, and +// `no_implicit_prelude` stops working, then the `impl Add` will still +// fail with the same error message). + +struct Test; +impl Add for Test {} // { dg-error ".E0405." "" { target *-*-* } } +impl Clone for Test {} // { dg-error ".E0404." "" { target *-*-* } } +impl Iterator for Test {} // { dg-error ".E0405." "" { target *-*-* } } +impl ToString for Test {} // { dg-error ".E0405." "" { target *-*-* } } +impl Writer for Test {} // { dg-error ".E0405." "" { target *-*-* } } + +fn main() { + drop(2) // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/no-link-unknown-crate.rs b/gcc/testsuite/rust/rustc/ui/no-link-unknown-crate.rs new file mode 100644 index 000000000000..0b0bde4c647f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-link-unknown-crate.rs @@ -0,0 +1,5 @@ +#[no_link] +extern crate doesnt_exist; // { dg-error ".E0463." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/no-link.rs b/gcc/testsuite/rust/rustc/ui/no-link.rs new file mode 100644 index 000000000000..70f278185476 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-link.rs @@ -0,0 +1,9 @@ +// aux-build:empty-struct.rs + +#[no_link] +extern crate empty_struct; + +fn main() { + empty_struct::XEmpty1; // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/no-patterns-in-args-2.rs b/gcc/testsuite/rust/rustc/ui/no-patterns-in-args-2.rs new file mode 100644 index 000000000000..eb5752679cd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-patterns-in-args-2.rs @@ -0,0 +1,14 @@ +#![deny(patterns_in_fns_without_body)] + +trait Tr { + fn f1(mut arg: u8); // { dg-error ".E0642." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + fn f2(&arg: u8); // { dg-error ".E0642." "" { target *-*-* } } + fn g1(arg: u8); // OK + fn g2(_: u8); // OK + #[allow(anonymous_parameters)] + fn g3(u8); // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/no-patterns-in-args-macro.rs b/gcc/testsuite/rust/rustc/ui/no-patterns-in-args-macro.rs new file mode 100644 index 000000000000..bc370d0607a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-patterns-in-args-macro.rs @@ -0,0 +1,27 @@ +macro_rules! m { + ($pat: pat) => { + trait Tr { + fn trait_method($pat: u8); + } + + type A = fn($pat: u8); + + extern "C" { + fn foreign_fn($pat: u8); + } + }; +} + +mod good_pat { + m!(good_pat); // OK +} + +mod bad_pat { + m!((bad, pat)); +// { dg-error ".E0130." "" { target *-*-* } .-1 } +// { dg-error ".E0130." "" { target *-*-* } .-2 } +// { dg-error ".E0130." "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/no-patterns-in-args.rs b/gcc/testsuite/rust/rustc/ui/no-patterns-in-args.rs new file mode 100644 index 000000000000..56a9e46bf633 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-patterns-in-args.rs @@ -0,0 +1,17 @@ +extern { + fn f1(mut arg: u8); // { dg-error ".E0130." "" { target *-*-* } } + fn f2(&arg: u8); // { dg-error ".E0130." "" { target *-*-* } } + fn f3(arg @ _: u8); // { dg-error ".E0130." "" { target *-*-* } } + fn g1(arg: u8); // OK + fn g2(_: u8); // OK + // fn g3(u8); // Not yet +} + +type A1 = fn(mut arg: u8); // { dg-error ".E0561." "" { target *-*-* } } +type A2 = fn(&arg: u8); // { dg-error ".E0561." "" { target *-*-* } } +type B1 = fn(arg: u8); // OK +type B2 = fn(_: u8); // OK +type B3 = fn(u8); // OK + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/no-reuse-move-arc.rs b/gcc/testsuite/rust/rustc/ui/no-reuse-move-arc.rs new file mode 100644 index 000000000000..5c31a13f0077 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-reuse-move-arc.rs @@ -0,0 +1,16 @@ +use std::sync::Arc; +use std::thread; + +fn main() { + let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let arc_v = Arc::new(v); + + thread::spawn(move|| { + assert_eq!((*arc_v)[3], 4); + }); + + assert_eq!((*arc_v)[2], 3); // { dg-error ".E0382." "" { target *-*-* } } + + println!("{:?}", *arc_v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/no-send-res-ports.rs b/gcc/testsuite/rust/rustc/ui/no-send-res-ports.rs new file mode 100644 index 000000000000..5107e2e385ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-send-res-ports.rs @@ -0,0 +1,31 @@ +use std::thread; +use std::rc::Rc; + +#[derive(Debug)] +struct Port(Rc); + +fn main() { + #[derive(Debug)] + struct Foo { + _x: Port<()>, + } + + impl Drop for Foo { + fn drop(&mut self) {} + } + + fn foo(x: Port<()>) -> Foo { + Foo { + _x: x + } + } + + let x = foo(Port(Rc::new(()))); + + thread::spawn(move|| { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let y = x; + println!("{:?}", y); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/no-std-1.rs b/gcc/testsuite/rust/rustc/ui/no-std-1.rs new file mode 100644 index 000000000000..8c46c978d304 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-std-1.rs @@ -0,0 +1,11 @@ +// run-pass + +#![no_std] + +extern crate std; + +fn main() { + let a = Some("foo"); + a.unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/no-std-2.rs b/gcc/testsuite/rust/rustc/ui/no-std-2.rs new file mode 100644 index 000000000000..4717285e7197 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-std-2.rs @@ -0,0 +1,11 @@ +// run-pass + +#![no_std] + +extern crate std; + +fn main() { + let a = core::option::Option::Some("foo"); + a.unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/no-std-3.rs b/gcc/testsuite/rust/rustc/ui/no-std-3.rs new file mode 100644 index 000000000000..ad33bf7a6014 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-std-3.rs @@ -0,0 +1,18 @@ +// run-pass + +#![no_std] + +extern crate std; + +mod foo { + pub fn test() -> Option { + Some(2) + } +} + +fn main() { + let a = core::option::Option::Some("foo"); + a.unwrap(); + foo::test().unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/no-std-inject.rs b/gcc/testsuite/rust/rustc/ui/no-std-inject.rs new file mode 100644 index 000000000000..4725d9c7e24a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-std-inject.rs @@ -0,0 +1,7 @@ +#![no_std] + +extern crate core; // { dg-error ".E0259." "" { target *-*-* } } +extern crate std; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/no-stdio.rs b/gcc/testsuite/rust/rustc/ui/no-stdio.rs new file mode 100644 index 000000000000..9f535673047c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-stdio.rs @@ -0,0 +1,139 @@ +// run-pass +// ignore-android +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +#![feature(rustc_private)] + +extern crate libc; + +use std::process::{Command, Stdio}; +use std::env; +use std::io::{self, Read, Write}; + +#[cfg(unix)] +unsafe fn without_stdio R>(f: F) -> R { + let doit = |a| { + let r = libc::dup(a); + assert!(r >= 0); + return r + }; + let a = doit(0); + let b = doit(1); + let c = doit(2); + + assert!(libc::close(0) >= 0); + assert!(libc::close(1) >= 0); + assert!(libc::close(2) >= 0); + + let r = f(); + + assert!(libc::dup2(a, 0) >= 0); + assert!(libc::dup2(b, 1) >= 0); + assert!(libc::dup2(c, 2) >= 0); + + return r +} + +#[cfg(unix)] +fn assert_fd_is_valid(fd: libc::c_int) { + if unsafe { libc::fcntl(fd, libc::F_GETFD) == -1 } { + panic!("file descriptor {} is not valid: {}", fd, io::Error::last_os_error()); + } +} + +#[cfg(windows)] +fn assert_fd_is_valid(_fd: libc::c_int) {} + +#[cfg(windows)] +unsafe fn without_stdio R>(f: F) -> R { + type DWORD = u32; + type HANDLE = *mut u8; + type BOOL = i32; + + const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD; + const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; + const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD; + const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE; + + extern "system" { + fn GetStdHandle(which: DWORD) -> HANDLE; + fn SetStdHandle(which: DWORD, handle: HANDLE) -> BOOL; + } + + let doit = |id| { + let handle = GetStdHandle(id); + assert!(handle != INVALID_HANDLE_VALUE); + assert!(SetStdHandle(id, INVALID_HANDLE_VALUE) != 0); + return handle + }; + + let a = doit(STD_INPUT_HANDLE); + let b = doit(STD_OUTPUT_HANDLE); + let c = doit(STD_ERROR_HANDLE); + + let r = f(); + + let doit = |id, handle| { + assert!(SetStdHandle(id, handle) != 0); + }; + doit(STD_INPUT_HANDLE, a); + doit(STD_OUTPUT_HANDLE, b); + doit(STD_ERROR_HANDLE, c); + + return r +} + +fn main() { + if env::args().len() > 1 { + // Writing to stdout & stderr should not panic. + println!("test"); + assert!(io::stdout().write(b"test\n").is_ok()); + assert!(io::stderr().write(b"test\n").is_ok()); + + // Stdin should be at EOF. + assert_eq!(io::stdin().read(&mut [0; 10]).unwrap(), 0); + + // Standard file descriptors should be valid on UNIX: + assert_fd_is_valid(0); + assert_fd_is_valid(1); + assert_fd_is_valid(2); + return + } + + // First, make sure reads/writes without stdio work if stdio itself is + // missing. + let (a, b, c) = unsafe { + without_stdio(|| { + let a = io::stdout().write(b"test\n"); + let b = io::stderr().write(b"test\n"); + let c = io::stdin().read(&mut [0; 10]); + + (a, b, c) + }) + }; + + assert_eq!(a.unwrap(), 5); + assert_eq!(b.unwrap(), 5); + assert_eq!(c.unwrap(), 0); + + // Second, spawn a child and do some work with "null" descriptors to make + // sure it's ok + let me = env::current_exe().unwrap(); + let status = Command::new(&me) + .arg("next") + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status().unwrap(); + assert!(status.success(), "{} isn't a success", status); + + // Finally, close everything then spawn a child to make sure everything is + // *still* ok. + let status = unsafe { + without_stdio(|| Command::new(&me).arg("next").status()) + }.unwrap(); + assert!(status.success(), "{} isn't a success", status); +} + diff --git a/gcc/testsuite/rust/rustc/ui/no-type-for-node-ice.rs b/gcc/testsuite/rust/rustc/ui/no-type-for-node-ice.rs new file mode 100644 index 000000000000..6cb5b6f3198a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-type-for-node-ice.rs @@ -0,0 +1,6 @@ +// Related issues: #20401, #20506, #20614, #20752, #20829, #20846, #20885, #20886 + +fn main() { + "".homura[""]; // { dg-error ".E0609." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/no-warn-on-field-replace-issue-34101.rs b/gcc/testsuite/rust/rustc/ui/no-warn-on-field-replace-issue-34101.rs new file mode 100644 index 000000000000..bba6404c395f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no-warn-on-field-replace-issue-34101.rs @@ -0,0 +1,47 @@ +// Issue 34101: Circa 2016-06-05, `fn inline` below issued an +// erroneous warning from the elaborate_drops pass about moving out of +// a field in `Foo`, which has a destructor (and thus cannot have +// content moved out of it). The reason that the warning is erroneous +// in this case is that we are doing a *replace*, not a move, of the +// content in question, and it is okay to replace fields within `Foo`. +// +// Another more subtle problem was that the elaborate_drops was +// creating a separate drop flag for that internally replaced content, +// even though the compiler should enforce an invariant that any drop +// flag for such subcontent of `Foo` will always have the same value +// as the drop flag for `Foo` itself. + + + + + + + + +// check-pass + +struct Foo(String); + +impl Drop for Foo { + fn drop(&mut self) {} +} + +fn inline() { + // (dummy variable so `f` gets assigned `var1` in MIR for both fn's) + let _s = (); + let mut f = Foo(String::from("foo")); + f.0 = String::from("bar"); +} + +fn outline() { + let _s = String::from("foo"); + let mut f = Foo(_s); + f.0 = String::from("bar"); +} + + +fn main() { + inline(); + outline(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/no_crate_type.rs b/gcc/testsuite/rust/rustc/ui/no_crate_type.rs new file mode 100644 index 000000000000..43f6c0f33c40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no_crate_type.rs @@ -0,0 +1,7 @@ +// regression test for issue 11256 +#![crate_type] // { dg-error "" "" { target *-*-* } } + +fn main() { + return +} + diff --git a/gcc/testsuite/rust/rustc/ui/no_owned_box_lang_item.rs b/gcc/testsuite/rust/rustc/ui/no_owned_box_lang_item.rs new file mode 100644 index 000000000000..9d2f61dc8c51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no_owned_box_lang_item.rs @@ -0,0 +1,17 @@ +// Test that we don't ICE when we are missing the owned_box lang item. + +// error-pattern: requires `owned_box` lang_item + +#![feature(lang_items, box_syntax)] +#![no_std] + +use core::panic::PanicInfo; + +fn main() { + let x = box 1i32; +} + +#[lang = "eh_personality"] extern fn eh_personality() {} +#[lang = "eh_catch_typeinfo"] static EH_CATCH_TYPEINFO: u8 = 0; +#[lang = "panic_impl"] fn panic_impl(panic: &PanicInfo) -> ! { loop {} } + diff --git a/gcc/testsuite/rust/rustc/ui/no_send-enum.rs b/gcc/testsuite/rust/rustc/ui/no_send-enum.rs new file mode 100644 index 000000000000..8a5e7148a57f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no_send-enum.rs @@ -0,0 +1,19 @@ +#![feature(negative_impls)] + +use std::marker::Send; + +struct NoSend; +impl !Send for NoSend {} + +enum Foo { + A(NoSend) +} + +fn bar(_: T) {} + +fn main() { + let x = Foo::A(NoSend); + bar(x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/no_send-rc.rs b/gcc/testsuite/rust/rustc/ui/no_send-rc.rs new file mode 100644 index 000000000000..bddcb1df21eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no_send-rc.rs @@ -0,0 +1,10 @@ +use std::rc::Rc; + +fn bar(_: T) {} + +fn main() { + let x = Rc::new(5); + bar(x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/no_send-struct.rs b/gcc/testsuite/rust/rustc/ui/no_send-struct.rs new file mode 100644 index 000000000000..54cf3a53dc15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no_send-struct.rs @@ -0,0 +1,18 @@ +#![feature(negative_impls)] + +use std::marker::Send; + +struct Foo { + a: isize, +} + +impl !Send for Foo {} + +fn bar(_: T) {} + +fn main() { + let x = Foo { a: 5 }; + bar(x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/no_share-enum.rs b/gcc/testsuite/rust/rustc/ui/no_share-enum.rs new file mode 100644 index 000000000000..4519209c7164 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no_share-enum.rs @@ -0,0 +1,17 @@ +#![feature(negative_impls)] + +use std::marker::Sync; + +struct NoSync; +impl !Sync for NoSync {} + +enum Foo { A(NoSync) } + +fn bar(_: T) {} + +fn main() { + let x = Foo::A(NoSync); + bar(x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/no_share-struct.rs b/gcc/testsuite/rust/rustc/ui/no_share-struct.rs new file mode 100644 index 000000000000..575600c1d16e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/no_share-struct.rs @@ -0,0 +1,15 @@ +#![feature(negative_impls)] + +use std::marker::Sync; + +struct Foo { a: isize } +impl !Sync for Foo {} + +fn bar(_: T) {} + +fn main() { + let x = Foo { a: 5 }; + bar(x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/noexporttypeexe.rs b/gcc/testsuite/rust/rustc/ui/noexporttypeexe.rs new file mode 100644 index 000000000000..5d3ff3ae5d12 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/noexporttypeexe.rs @@ -0,0 +1,16 @@ +// aux-build:noexporttypelib.rs + +extern crate noexporttypelib; + +fn main() { + // Here, the type returned by foo() is not exported. + // This used to cause internal errors when serializing + // because the def_id associated with the type was + // not convertible to a path. + let x: isize = noexporttypelib::foo(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/non-built-in-quote.rs b/gcc/testsuite/rust/rustc/ui/non-built-in-quote.rs new file mode 100644 index 000000000000..696d39e5667e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non-built-in-quote.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +macro_rules! quote_tokens { () => (()) } + +pub fn main() { + quote_tokens!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/non-constant-expr-for-arr-len.rs b/gcc/testsuite/rust/rustc/ui/non-constant-expr-for-arr-len.rs new file mode 100644 index 000000000000..8d370f88c352 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non-constant-expr-for-arr-len.rs @@ -0,0 +1,9 @@ +// Check that non constant exprs fail for array repeat syntax + +fn main() { + fn bar(n: usize) { + let _x = [0; n]; +// { dg-error ".E0435." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/non-constant-in-const-path.rs b/gcc/testsuite/rust/rustc/ui/non-constant-in-const-path.rs new file mode 100644 index 000000000000..0c599625adb8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non-constant-in-const-path.rs @@ -0,0 +1,8 @@ +fn main() { + let x = 0; + match 1 { + 0 ..= x => {} +// { dg-error ".E0080." "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/non-copyable-void.rs b/gcc/testsuite/rust/rustc/ui/non-copyable-void.rs new file mode 100644 index 000000000000..a530b250318c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non-copyable-void.rs @@ -0,0 +1,15 @@ +// ignore-wasm32-bare no libc to test ffi with + +#![feature(rustc_private)] + +extern crate libc; + +fn main() { + let x : *const Vec = &vec![1,2,3]; + let y : *const libc::c_void = x as *const libc::c_void; + unsafe { + let _z = (*y).clone(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/non-ice-error-on-worker-io-fail.rs b/gcc/testsuite/rust/rustc/ui/non-ice-error-on-worker-io-fail.rs new file mode 100644 index 000000000000..f86b2347394b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non-ice-error-on-worker-io-fail.rs @@ -0,0 +1,42 @@ +// Issue #66530: We would ICE if someone compiled with `-o /dev/null`, +// because we would try to generate auxiliary files in `/dev/` (which +// at least the OS X file system rejects). +// +// An attempt to `-o` into a directory we cannot write into should indeed +// be an error; but not an ICE. +// +// However, some folks run tests as root, which can write `/dev/` and end +// up clobbering `/dev/null`. Instead we'll use a non-existent path, which +// also used to ICE, but even root can't magically write there. + +// compile-flags: -o /does-not-exist/output + +// The error-pattern check occurs *before* normalization, and the error patterns +// are wildly different between build environments. So this is a cop-out (and we +// rely on the checking of the normalized stderr output as our actual +// "verification" of the diagnostic). + +// error-pattern: error + +// On Mac OS X, we get an error like the below +// normalize-stderr-test "failed to write bytecode to /does-not-exist/output.non_ice_error_on_worker_io_fail.*" -> "io error modifying /does-not-exist/" + +// On Linux, we get an error like the below +// normalize-stderr-test "couldn't create a temp dir.*" -> "io error modifying /does-not-exist/" + +// ignore-tidy-linelength +// ignore-windows - this is a unix-specific test +// ignore-emscripten - the file-system issues do not replicate here +// ignore-wasm - the file-system issues do not replicate here +// ignore-arm - the file-system issues do not replicate here, at least on armhf-gnu + +#![crate_type="lib"] + +#![cfg_attr(not(feature = "std"), no_std)] +pub mod task { + pub mod __internal { + use crate::task::Waker; + } + pub use core::task::Waker; +} + diff --git a/gcc/testsuite/rust/rustc/ui/non-integer-atomic.rs b/gcc/testsuite/rust/rustc/ui/non-integer-atomic.rs new file mode 100644 index 000000000000..4f4b33604bb5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non-integer-atomic.rs @@ -0,0 +1,93 @@ +// build-fail + +#![feature(core_intrinsics)] +#![allow(warnings)] +#![crate_type = "rlib"] + +use std::intrinsics; + +#[derive(Copy, Clone)] +pub struct Foo(i64); +pub type Bar = &'static Fn(); +pub type Quux = [u8; 100]; + +pub unsafe fn test_bool_load(p: &mut bool, v: bool) { + intrinsics::atomic_load(p); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_bool_store(p: &mut bool, v: bool) { + intrinsics::atomic_store(p, v); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_bool_xchg(p: &mut bool, v: bool) { + intrinsics::atomic_xchg(p, v); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_bool_cxchg(p: &mut bool, v: bool) { + intrinsics::atomic_cxchg(p, v, v); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_Foo_load(p: &mut Foo, v: Foo) { + intrinsics::atomic_load(p); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_Foo_store(p: &mut Foo, v: Foo) { + intrinsics::atomic_store(p, v); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_Foo_xchg(p: &mut Foo, v: Foo) { + intrinsics::atomic_xchg(p, v); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_Foo_cxchg(p: &mut Foo, v: Foo) { + intrinsics::atomic_cxchg(p, v, v); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_Bar_load(p: &mut Bar, v: Bar) { + intrinsics::atomic_load(p); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_Bar_store(p: &mut Bar, v: Bar) { + intrinsics::atomic_store(p, v); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_Bar_xchg(p: &mut Bar, v: Bar) { + intrinsics::atomic_xchg(p, v); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) { + intrinsics::atomic_cxchg(p, v, v); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_Quux_load(p: &mut Quux, v: Quux) { + intrinsics::atomic_load(p); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_Quux_store(p: &mut Quux, v: Quux) { + intrinsics::atomic_store(p, v); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_Quux_xchg(p: &mut Quux, v: Quux) { + intrinsics::atomic_xchg(p, v); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + +pub unsafe fn test_Quux_cxchg(p: &mut Quux, v: Quux) { + intrinsics::atomic_cxchg(p, v, v); +// { dg-error ".E0511." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/non-legacy-modes.rs b/gcc/testsuite/rust/rustc/ui/non-legacy-modes.rs new file mode 100644 index 000000000000..8ef6cd4d9e80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non-legacy-modes.rs @@ -0,0 +1,23 @@ +// run-pass + +struct X { + repr: isize +} + +fn apply(x: T, f: F) where F: FnOnce(T) { + f(x); +} + +fn check_int(x: isize) { + assert_eq!(x, 22); +} + +fn check_struct(x: X) { + check_int(x.repr); +} + +pub fn main() { + apply(22, check_int); + apply(X {repr: 22}, check_struct); +} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod.rs new file mode 100644 index 000000000000..ad36dff69823 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod.rs @@ -0,0 +1,11 @@ +// run-pass +// +// ignore-test: not a test, used by non_modrs_mods.rs + +pub mod inner_modrs_mod; +pub mod inner_foors_mod; +pub mod inline { + #[path="somename.rs"] + pub mod innie; +} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inline/somename.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inline/somename.rs new file mode 100644 index 000000000000..38d4c680f11c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inline/somename.rs @@ -0,0 +1,4 @@ +// run-pass + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_foors_mod.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_foors_mod.rs new file mode 100644 index 000000000000..8c3a37241915 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_foors_mod.rs @@ -0,0 +1,4 @@ +// run-pass + +pub mod innest; + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs new file mode 100644 index 000000000000..38d4c680f11c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_foors_mod/innest.rs @@ -0,0 +1,4 @@ +// run-pass + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs new file mode 100644 index 000000000000..38d4c680f11c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_modrs_mod/innest.rs @@ -0,0 +1,4 @@ +// run-pass + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs new file mode 100644 index 000000000000..8c3a37241915 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/foors_mod/inner_modrs_mod/mod.rs @@ -0,0 +1,4 @@ +// run-pass + +pub mod innest; + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inline/somename.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inline/somename.rs new file mode 100644 index 000000000000..38d4c680f11c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inline/somename.rs @@ -0,0 +1,4 @@ +// run-pass + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs new file mode 100644 index 000000000000..8c3a37241915 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_foors_mod.rs @@ -0,0 +1,4 @@ +// run-pass + +pub mod innest; + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs new file mode 100644 index 000000000000..38d4c680f11c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_foors_mod/innest.rs @@ -0,0 +1,4 @@ +// run-pass + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs new file mode 100644 index 000000000000..38d4c680f11c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/innest.rs @@ -0,0 +1,4 @@ +// run-pass + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs new file mode 100644 index 000000000000..8c3a37241915 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/inner_modrs_mod/mod.rs @@ -0,0 +1,4 @@ +// run-pass + +pub mod innest; + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/mod.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/mod.rs new file mode 100644 index 000000000000..6d1cbffb0c3b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/modrs_mod/mod.rs @@ -0,0 +1,9 @@ +// run-pass + +pub mod inner_modrs_mod; +pub mod inner_foors_mod; +pub mod inline { + #[path="somename.rs"] + pub mod innie; +} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/non_modrs_mods.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/non_modrs_mods.rs new file mode 100644 index 000000000000..a7bf93e268b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/non_modrs_mods.rs @@ -0,0 +1,17 @@ +// run-pass +// +// ignore-pretty issue #37195 +pub mod modrs_mod; +pub mod foors_mod; +#[path = "some_crazy_attr_mod_dir/arbitrary_name.rs"] +pub mod attr_mod; +pub fn main() { + modrs_mod::inner_modrs_mod::innest::foo(); + modrs_mod::inner_foors_mod::innest::foo(); + modrs_mod::inline::innie::foo(); + foors_mod::inner_modrs_mod::innest::foo(); + foors_mod::inner_foors_mod::innest::foo(); + foors_mod::inline::innie::foo(); + attr_mod::inner_modrs_mod::innest::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs new file mode 100644 index 000000000000..f0109625548a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/arbitrary_name.rs @@ -0,0 +1,4 @@ +// run-pass + +pub mod inner_modrs_mod; + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs new file mode 100644 index 000000000000..38d4c680f11c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs @@ -0,0 +1,4 @@ +// run-pass + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs new file mode 100644 index 000000000000..8c3a37241915 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs @@ -0,0 +1,4 @@ +// run-pass + +pub mod innest; + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs new file mode 100644 index 000000000000..2a5aad5dd24a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods_and_inline_mods/non_modrs_mods_and_inline_mods.rs @@ -0,0 +1,6 @@ +// build-pass (FIXME(62277): could be check-pass?) + +mod x; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods_and_inline_mods/x.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods_and_inline_mods/x.rs new file mode 100644 index 000000000000..394ae1e17113 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods_and_inline_mods/x.rs @@ -0,0 +1,6 @@ +// ignore-test: not a test + +pub mod y { + pub mod z; +} + diff --git a/gcc/testsuite/rust/rustc/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs b/gcc/testsuite/rust/rustc/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs new file mode 100644 index 000000000000..8c31b65e2b43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/non_modrs_mods_and_inline_mods/x/y/z/mod.rs @@ -0,0 +1,2 @@ +// ignore-test: not a test + diff --git a/gcc/testsuite/rust/rustc/ui/noncopyable-class.rs b/gcc/testsuite/rust/rustc/ui/noncopyable-class.rs new file mode 100644 index 000000000000..979005b399f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/noncopyable-class.rs @@ -0,0 +1,37 @@ +// Test that a class with a non-copyable field can't be +// copied + +#[derive(Debug)] +struct Bar { + x: isize, +} + +impl Drop for Bar { + fn drop(&mut self) {} +} + +fn bar(x:isize) -> Bar { + Bar { + x: x + } +} + +#[derive(Debug)] +struct Foo { + i: isize, + j: Bar, +} + +fn foo(i:isize) -> Foo { + Foo { + i: i, + j: bar(5) + } +} + +fn main() { + let x = foo(10); + let _y = x.clone(); // { dg-error ".E0599." "" { target *-*-* } } + println!("{:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nonscalar-cast.rs b/gcc/testsuite/rust/rustc/ui/nonscalar-cast.rs new file mode 100644 index 000000000000..e190c1768fc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nonscalar-cast.rs @@ -0,0 +1,17 @@ +// run-rustfix + +#[derive(Debug)] +struct Foo { + x: isize +} + +impl From for isize { + fn from(val: Foo) -> isize { + val.x + } +} + +fn main() { + println!("{}", Foo { x: 1 } as isize); // { dg-error ".E0605." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/not-clone-closure.rs b/gcc/testsuite/rust/rustc/ui/not-clone-closure.rs new file mode 100644 index 000000000000..821068376b62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/not-clone-closure.rs @@ -0,0 +1,13 @@ +// Check that closures do not implement `Clone` if their environment is not `Clone`. + +struct S(i32); + +fn main() { + let a = S(5); + let hello = move || { + println!("Hello {}", a.0); + }; + + let hello = hello.clone(); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/not-copy-closure.rs b/gcc/testsuite/rust/rustc/ui/not-copy-closure.rs new file mode 100644 index 000000000000..ce99cbc1a3b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/not-copy-closure.rs @@ -0,0 +1,12 @@ +// Check that closures do not implement `Copy` if their environment is not `Copy`. + +fn main() { + let mut a = 5; + let hello = || { + a += 1; + }; + + let b = hello; + let c = hello; // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/not-enough-arguments.rs b/gcc/testsuite/rust/rustc/ui/not-enough-arguments.rs new file mode 100644 index 000000000000..420ec5024e20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/not-enough-arguments.rs @@ -0,0 +1,32 @@ +// Check that the only error msg we report is the +// mismatch between the # of params, and not other +// unrelated errors. + +fn foo(a: isize, b: isize, c: isize, d:isize) { + panic!(); +} + +// Check that all arguments are shown in the error message, even if they're across multiple lines. +fn bar( + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, +) { + println!("{}", a); + println!("{}", b); + println!("{}", c); + println!("{}", d); + println!("{}", e); + println!("{}", f); +} + +fn main() { + foo(1, 2, 3); +// { dg-error ".E0061." "" { target *-*-* } .-1 } + bar(1, 2, 3); +// { dg-error ".E0061." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-2.rs b/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-2.rs new file mode 100644 index 000000000000..43399d845081 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-2.rs @@ -0,0 +1,14 @@ +#![allow(dead_code)] + +use std::panic::UnwindSafe; +use std::rc::Rc; +use std::cell::RefCell; + +fn assert() {} + +fn main() { + assert::>>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-3.rs b/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-3.rs new file mode 100644 index 000000000000..b2c70e69c3e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-3.rs @@ -0,0 +1,14 @@ +#![allow(dead_code)] + +use std::panic::UnwindSafe; +use std::sync::Arc; +use std::cell::RefCell; + +fn assert() {} + +fn main() { + assert::>>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-4.rs b/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-4.rs new file mode 100644 index 000000000000..cdcca5b2d36e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-4.rs @@ -0,0 +1,13 @@ +#![allow(dead_code)] + +use std::panic::UnwindSafe; +use std::cell::RefCell; + +fn assert() {} + +fn main() { + assert::<&RefCell>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-5.rs b/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-5.rs new file mode 100644 index 000000000000..bd833117ec3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-5.rs @@ -0,0 +1,11 @@ +#![allow(dead_code)] + +use std::panic::UnwindSafe; +use std::cell::UnsafeCell; + +fn assert() {} + +fn main() { + assert::<*const UnsafeCell>(); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-6.rs b/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-6.rs new file mode 100644 index 000000000000..186af26b06fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe-6.rs @@ -0,0 +1,13 @@ +#![allow(dead_code)] + +use std::panic::UnwindSafe; +use std::cell::RefCell; + +fn assert() {} + +fn main() { + assert::<*mut RefCell>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe.rs b/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe.rs new file mode 100644 index 000000000000..a30c71da08a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/not-panic/not-panic-safe.rs @@ -0,0 +1,12 @@ +#![allow(dead_code)] +#![feature(recover)] + +use std::panic::UnwindSafe; + +fn assert() {} + +fn main() { + assert::<&mut i32>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/not-sync.rs b/gcc/testsuite/rust/rustc/ui/not-sync.rs new file mode 100644 index 000000000000..1e78a2158e20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/not-sync.rs @@ -0,0 +1,23 @@ +use std::cell::{Cell, RefCell}; +use std::rc::{Rc, Weak}; +use std::sync::mpsc::{Receiver, Sender}; + +fn test() {} + +fn main() { + test::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + test::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + test::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + test::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + test::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + test::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nul-characters.rs b/gcc/testsuite/rust/rustc/ui/nul-characters.rs new file mode 100644 index 000000000000..b35e746480f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nul-characters.rs @@ -0,0 +1,37 @@ +// run-pass + +pub fn main() +{ + let all_nuls1 = "\0\x00\u{0}\u{0}"; + let all_nuls2 = "\u{0}\u{0}\x00\0"; + let all_nuls3 = "\u{0}\u{0}\x00\0"; + let all_nuls4 = "\x00\u{0}\0\u{0}"; + + // sizes for two should suffice + assert_eq!(all_nuls1.len(), 4); + assert_eq!(all_nuls2.len(), 4); + + // string equality should pass between the strings + assert_eq!(all_nuls1, all_nuls2); + assert_eq!(all_nuls2, all_nuls3); + assert_eq!(all_nuls3, all_nuls4); + + // all extracted characters in all_nuls are equivalent to each other + for c1 in all_nuls1.chars() + { + for c2 in all_nuls1.chars() + { + assert_eq!(c1,c2); + } + } + + // testing equality between explicit character literals + assert_eq!('\0', '\x00'); + assert_eq!('\u{0}', '\x00'); + assert_eq!('\u{0}', '\u{0}'); + + // NUL characters should make a difference + assert!("Hello World" != "Hello \0World"); + assert!("Hello World" != "Hello World\0"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nullable-pointer-ffi-compat.rs b/gcc/testsuite/rust/rustc/ui/nullable-pointer-ffi-compat.rs new file mode 100644 index 000000000000..3a843da51ff9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nullable-pointer-ffi-compat.rs @@ -0,0 +1,29 @@ +// run-pass +// #11303, #11040: +// This would previously crash on i686 Linux due to abi differences +// between returning an Option and T, where T is a non nullable +// pointer. +// If we have an enum with two variants such that one is zero sized +// and the other contains a nonnullable pointer, we don't use a +// separate discriminant. Instead we use that pointer field to differentiate +// between the 2 cases. +// Also, if the variant with the nonnullable pointer has no other fields +// then we simply express the enum as just a pointer and not wrap it +// in a struct. + + +use std::mem; + +#[inline(never)] +extern "C" fn foo(x: &isize) -> Option<&isize> { Some(x) } + +static FOO: isize = 0xDEADBEE; + +pub fn main() { + unsafe { + let f: extern "C" fn(&isize) -> &isize = + mem::transmute(foo as extern "C" fn(&isize) -> Option<&isize>); + assert_eq!(*f(&FOO), FOO); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/nullable-pointer-iotareduction.rs b/gcc/testsuite/rust/rustc/ui/nullable-pointer-iotareduction.rs new file mode 100644 index 000000000000..2d62b103b75b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nullable-pointer-iotareduction.rs @@ -0,0 +1,74 @@ +// run-pass + +#![feature(box_syntax)] + +// Iota-reduction is a rule in the Calculus of (Co-)Inductive Constructions, +// which "says that a destructor applied to an object built from a constructor +// behaves as expected". -- http://coq.inria.fr/doc/Reference-Manual006.html +// +// It's a little more complicated here, because of pointers and regions and +// trying to get assert failure messages that at least identify which case +// failed. + +enum E { Thing(isize, T), Nothing((), ((), ()), [i8; 0]) } +impl E { + fn is_none(&self) -> bool { + match *self { + E::Thing(..) => false, + E::Nothing(..) => true + } + } + fn get_ref(&self) -> (isize, &T) { + match *self { + E::Nothing(..) => panic!("E::get_ref(Nothing::<{}>)", stringify!(T)), + E::Thing(x, ref y) => (x, y) + } + } +} + +macro_rules! check_option { + ($e:expr, $T:ty) => {{ + check_option!($e, $T, |ptr| assert_eq!(*ptr, $e)); + }}; + ($e:expr, $T:ty, |$v:ident| $chk:expr) => {{ + assert!(None::<$T>.is_none()); + let e = $e; + let s_ = Some::<$T>(e); + let $v = s_.as_ref().unwrap(); + $chk + }} +} + +macro_rules! check_fancy { + ($e:expr, $T:ty) => {{ + check_fancy!($e, $T, |ptr| assert_eq!(*ptr, $e)); + }}; + ($e:expr, $T:ty, |$v:ident| $chk:expr) => {{ + assert!(E::Nothing::<$T>((), ((), ()), [23; 0]).is_none()); + let e = $e; + let t_ = E::Thing::<$T>(23, e); + match t_.get_ref() { + (23, $v) => { $chk } + _ => panic!("Thing::<{}>(23, {}).get_ref() != (23, _)", + stringify!($T), stringify!($e)) + } + }} +} + +macro_rules! check_type { + ($($a:tt)*) => {{ + check_option!($($a)*); + check_fancy!($($a)*); + }} +} + +pub fn main() { + check_type!(&17, &isize); + check_type!(box 18, Box); + check_type!("foo".to_string(), String); + check_type!(vec![20, 22], Vec); + check_type!(main, fn(), |pthing| { + assert_eq!(main as fn(), *pthing as fn()) + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/nullable-pointer-size.rs b/gcc/testsuite/rust/rustc/ui/nullable-pointer-size.rs new file mode 100644 index 000000000000..6f80aa95bbff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/nullable-pointer-size.rs @@ -0,0 +1,36 @@ +// run-pass + +#![allow(dead_code)] + +use std::mem; + +enum E { Thing(isize, T), Nothing((), ((), ()), [i8; 0]) } +struct S(isize, T); + +// These are macros so we get useful assert messages. + +macro_rules! check_option { + ($T:ty) => { + assert_eq!(mem::size_of::>(), mem::size_of::<$T>()); + } +} + +macro_rules! check_fancy { + ($T:ty) => { + assert_eq!(mem::size_of::>(), mem::size_of::>()); + } +} + +macro_rules! check_type { + ($T:ty) => {{ + check_option!($T); + check_fancy!($T); + }} +} + +pub fn main() { + check_type!(&'static isize); + check_type!(Box); + check_type!(extern fn()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/arith-unsigned.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/arith-unsigned.rs new file mode 100644 index 000000000000..82529a052e16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/arith-unsigned.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(unused_comparisons)] + +// Unsigned integer operations +pub fn main() { + assert!((0u8 < 255u8)); + assert!((0u8 <= 255u8)); + assert!((255u8 > 0u8)); + assert!((255u8 >= 0u8)); + assert_eq!(250u8 / 10u8, 25u8); + assert_eq!(255u8 % 10u8, 5u8); + assert!((0u16 < 60000u16)); + assert!((0u16 <= 60000u16)); + assert!((60000u16 > 0u16)); + assert!((60000u16 >= 0u16)); + assert_eq!(60000u16 / 10u16, 6000u16); + assert_eq!(60005u16 % 10u16, 5u16); + assert!((0u32 < 4000000000u32)); + assert!((0u32 <= 4000000000u32)); + assert!((4000000000u32 > 0u32)); + assert!((4000000000u32 >= 0u32)); + assert_eq!(4000000000u32 / 10u32, 400000000u32); + assert_eq!(4000000005u32 % 10u32, 5u32); + // 64-bit numbers have some flakiness yet. Not tested + +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/div-mod.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/div-mod.rs new file mode 100644 index 000000000000..e76da0f7c562 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/div-mod.rs @@ -0,0 +1,20 @@ +// run-pass + + + + +pub fn main() { + let x: isize = 15; + let y: isize = 5; + assert_eq!(x / 5, 3); + assert_eq!(x / 4, 3); + assert_eq!(x / 3, 5); + assert_eq!(x / y, 3); + assert_eq!(15 / y, 3); + assert_eq!(x % 5, 0); + assert_eq!(x % 4, 3); + assert_eq!(x % 3, 0); + assert_eq!(x % y, 0); + assert_eq!(15 % y, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/divide-by-zero.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/divide-by-zero.rs new file mode 100644 index 000000000000..785d36c713aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/divide-by-zero.rs @@ -0,0 +1,10 @@ +// run-fail +// error-pattern:attempt to divide by zero +// ignore-emscripten no processes + +#[allow(unconditional_panic)] +fn main() { + let y = 0; + let _z = 1 / y; +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-int-invalid-const-cast.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-int-invalid-const-cast.rs new file mode 100644 index 000000000000..85bb0c626dc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-int-invalid-const-cast.rs @@ -0,0 +1,53 @@ +// run-pass + +#![deny(const_err)] + +use std::{f32, f64}; + +// Forces evaluation of constants, triggering hard error +fn force(_: T) {} + +fn main() { + { const X: u16 = -1. as u16; force(X); } + { const X: u128 = -100. as u128; force(X); } + + { const X: i8 = f32::NAN as i8; force(X); } + { const X: i32 = f32::NAN as i32; force(X); } + { const X: u64 = f32::NAN as u64; force(X); } + { const X: u128 = f32::NAN as u128; force(X); } + + { const X: i8 = f32::INFINITY as i8; force(X); } + { const X: u32 = f32::INFINITY as u32; force(X); } + { const X: i128 = f32::INFINITY as i128; force(X); } + { const X: u128 = f32::INFINITY as u128; force(X); } + + { const X: u8 = f32::NEG_INFINITY as u8; force(X); } + { const X: u16 = f32::NEG_INFINITY as u16; force(X); } + { const X: i64 = f32::NEG_INFINITY as i64; force(X); } + { const X: i128 = f32::NEG_INFINITY as i128; force(X); } + + { const X: i8 = f64::NAN as i8; force(X); } + { const X: i32 = f64::NAN as i32; force(X); } + { const X: u64 = f64::NAN as u64; force(X); } + { const X: u128 = f64::NAN as u128; force(X); } + + { const X: i8 = f64::INFINITY as i8; force(X); } + { const X: u32 = f64::INFINITY as u32; force(X); } + { const X: i128 = f64::INFINITY as i128; force(X); } + { const X: u128 = f64::INFINITY as u128; force(X); } + + { const X: u8 = f64::NEG_INFINITY as u8; force(X); } + { const X: u16 = f64::NEG_INFINITY as u16; force(X); } + { const X: i64 = f64::NEG_INFINITY as i64; force(X); } + { const X: i128 = f64::NEG_INFINITY as i128; force(X); } + + { const X: u8 = 256. as u8; force(X); } + { const X: i8 = -129. as i8; force(X); } + { const X: i8 = 128. as i8; force(X); } + { const X: i32 = 2147483648. as i32; force(X); } + { const X: i32 = -2147483904. as i32; force(X); } + { const X: u32 = 4294967296. as u32; force(X); } + { const X: u128 = 1e40 as u128; force(X); } + { const X: i128 = 1e40 as i128; force(X); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-literal-inference.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-literal-inference.rs new file mode 100644 index 000000000000..c952244beb27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-literal-inference.rs @@ -0,0 +1,14 @@ +// run-pass +struct S { + z: f64 +} + +pub fn main() { + let x: f32 = 4.0; + println!("{}", x); + let y: f64 = 64.0; + println!("{}", y); + let z = S { z: 1.0 }; + println!("{}", z.z); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-nan.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-nan.rs new file mode 100644 index 000000000000..a4c49e076624 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-nan.rs @@ -0,0 +1,84 @@ +// run-pass +use std::f64; + +pub fn main() { + let nan: f64 = f64::NAN; + assert!((nan).is_nan()); + + let inf: f64 = f64::INFINITY; + let neg_inf: f64 = -f64::INFINITY; + assert_eq!(-inf, neg_inf); + + assert!( nan != nan); + assert!( nan != -nan); + assert!(-nan != -nan); + assert!(-nan != nan); + + assert!( nan != 1.); + assert!( nan != 0.); + assert!( nan != inf); + assert!( nan != -inf); + + assert!( 1. != nan); + assert!( 0. != nan); + assert!( inf != nan); + assert!(-inf != nan); + + assert!(!( nan == nan)); + assert!(!( nan == -nan)); + assert!(!( nan == 1.)); + assert!(!( nan == 0.)); + assert!(!( nan == inf)); + assert!(!( nan == -inf)); + assert!(!( 1. == nan)); + assert!(!( 0. == nan)); + assert!(!( inf == nan)); + assert!(!(-inf == nan)); + assert!(!(-nan == nan)); + assert!(!(-nan == -nan)); + + assert!(!( nan > nan)); + assert!(!( nan > -nan)); + assert!(!( nan > 0.)); + assert!(!( nan > inf)); + assert!(!( nan > -inf)); + assert!(!( 0. > nan)); + assert!(!( inf > nan)); + assert!(!(-inf > nan)); + assert!(!(-nan > nan)); + + assert!(!(nan < 0.)); + assert!(!(nan < 1.)); + assert!(!(nan < -1.)); + assert!(!(nan < inf)); + assert!(!(nan < -inf)); + assert!(!(nan < nan)); + assert!(!(nan < -nan)); + + assert!(!( 0. < nan)); + assert!(!( 1. < nan)); + assert!(!( -1. < nan)); + assert!(!( inf < nan)); + assert!(!(-inf < nan)); + assert!(!(-nan < nan)); + + assert!((nan + inf).is_nan()); + assert!((nan + -inf).is_nan()); + assert!((nan + 0.).is_nan()); + assert!((nan + 1.).is_nan()); + assert!((nan * 1.).is_nan()); + assert!((nan / 1.).is_nan()); + assert!((nan / 0.).is_nan()); + assert!((0.0/0.0f64).is_nan()); + assert!((-inf + inf).is_nan()); + assert!((inf - inf).is_nan()); + + assert!(!(-1.0f64).is_nan()); + assert!(!(0.0f64).is_nan()); + assert!(!(0.1f64).is_nan()); + assert!(!(1.0f64).is_nan()); + assert!(!(inf).is_nan()); + assert!(!(-inf).is_nan()); + assert!(!(1./-inf).is_nan()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-signature.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-signature.rs new file mode 100644 index 000000000000..f3fa53e3a681 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float-signature.rs @@ -0,0 +1,10 @@ +// run-pass + + +pub fn main() { + fn foo(n: f64) -> f64 { return n + 0.12345; } + let n: f64 = 0.1; + let m: f64 = foo(n); + println!("{}", m); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float.rs new file mode 100644 index 000000000000..9728e2b6a045 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float.rs @@ -0,0 +1,10 @@ +// run-pass +pub fn main() { + let pi = 3.1415927f64; + println!("{}", -pi * (pi + 2.0 / pi) - pi * 5.0); + if pi == 5.0 || pi < 10.0 || pi <= 2.0 || pi != 22.0 / 7.0 || pi >= 10.0 + || pi > 1.0 { + println!("yes"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float2.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float2.rs new file mode 100644 index 000000000000..27a7865bb4a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float2.rs @@ -0,0 +1,27 @@ +// run-pass + + + +pub fn main() { + let a = 1.5e6f64; + let b = 1.5E6f64; + let c = 1e6f64; + let d = 1E6f64; + let e = 3.0f32; + let f = 5.9f64; + let g = 1e6f32; + let h = 1.0e7f64; + let i = 1.0E7f64; + let j = 3.1e+9f64; + let k = 3.2e-10f64; + assert_eq!(a, b); + assert!((c < b)); + assert_eq!(c, d); + assert!((e < g)); + assert!((f < h)); + assert_eq!(g, 1000000.0f32); + assert_eq!(h, i); + assert!((j > k)); + assert!((k < a)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float_math.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float_math.rs new file mode 100644 index 000000000000..0920b49763d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/float_math.rs @@ -0,0 +1,22 @@ +// run-pass +#![feature(core_intrinsics)] + +use std::intrinsics::{fadd_fast, fsub_fast, fmul_fast, fdiv_fast, frem_fast}; + +#[inline(never)] +pub fn test_operations(a: f64, b: f64) { + // make sure they all map to the correct operation + unsafe { + assert_eq!(fadd_fast(a, b), a + b); + assert_eq!(fsub_fast(a, b), a - b); + assert_eq!(fmul_fast(a, b), a * b); + assert_eq!(fdiv_fast(a, b), a / b); + assert_eq!(frem_fast(a, b), a % b); + } +} + +fn main() { + test_operations(1., 2.); + test_operations(10., 5.); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/floatlits.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/floatlits.rs new file mode 100644 index 000000000000..1d3f0648c9d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/floatlits.rs @@ -0,0 +1,13 @@ +// run-pass + + + +pub fn main() { + let f = 4.999999999999f64; + assert!((f > 4.90f64)); + assert!((f < 5.0f64)); + let g = 4.90000000001e-10f64; + assert!((g > 5e-11f64)); + assert!((g < 5e-9f64)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/i128.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/i128.rs new file mode 100644 index 000000000000..e71752268136 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/i128.rs @@ -0,0 +1,108 @@ +// run-pass +#![allow(overflowing_literals)] + +#![feature(test)] + +extern crate test; +use test::black_box as b; + +fn main() { + let x: i128 = -1; + assert_eq!(0, !x); + let y: i128 = -2; + assert_eq!(!1, y); + let z: i128 = 0xABCD_EF; + assert_eq!(z * z, 0x734C_C2F2_A521); + assert_eq!(z * z * z * z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41); + assert_eq!(-z * -z, 0x734C_C2F2_A521); + assert_eq!(-z * -z * -z * -z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41); + assert_eq!(-z + -z + -z + -z, -0x2AF3_7BC); + let k: i128 = -0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210; + assert_eq!(k + k, -0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420); + assert_eq!(0, k - k); + assert_eq!(-0x1234_5678_9ABC_DEFF_EDCB_A987_5A86_421, k + z); + assert_eq!(-0x1000_0000_0000_0000_0000_0000_0000_000, + k + 0x234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!(-0x6EF5_DE4C_D3BC_2AAA_3BB4_CC5D_D6EE_8, k / 42); + assert_eq!(-k, k / -1); + assert_eq!(-0x91A2_B3C4_D5E6_F8, k >> 65); + assert_eq!(-0xFDB9_7530_ECA8_6420_0000_0000_0000_0000, k << 65); + assert!(k < z); + assert!(y > k); + assert!(y < x); + assert_eq!(x as i64, -1); + assert_eq!(z as i64, 0xABCD_EF); + assert_eq!(k as i64, -0xFEDC_BA98_7654_3210); + assert_eq!(k as u128, 0xFEDC_BA98_7654_3210_0123_4567_89AB_CDF0); + assert_eq!(-k as u128, 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!((-z as f64) as i128, -z); + assert_eq!((-z as f32) as i128, -z); + assert_eq!((-z as f64 * 16.0) as i128, -z * 16); + assert_eq!((-z as f32 * 16.0) as i128, -z * 16); + // Same stuff as above, but blackboxed, to force use of intrinsics + let x: i128 = b(-1); + assert_eq!(0, !x); + let y: i128 = b(-2); + assert_eq!(!1, y); + let z: i128 = b(0xABCD_EF); + assert_eq!(z * z, 0x734C_C2F2_A521); + assert_eq!(z * z * z * z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41); + assert_eq!(-z * -z, 0x734C_C2F2_A521); + assert_eq!(-z * -z * -z * -z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41); + assert_eq!(-z + -z + -z + -z, -0x2AF3_7BC); + let k: i128 = b(-0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!(k + k, -0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420); + assert_eq!(0, k - k); + assert_eq!(-0x1234_5678_9ABC_DEFF_EDCB_A987_5A86_421, k + z); + assert_eq!(-0x1000_0000_0000_0000_0000_0000_0000_000, + k + 0x234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!(-0x6EF5_DE4C_D3BC_2AAA_3BB4_CC5D_D6EE_8, k / 42); + assert_eq!(-k, k / -1); + assert_eq!(-0x91A2_B3C4_D5E6_F8, k >> 65); + assert_eq!(-0xFDB9_7530_ECA8_6420_0000_0000_0000_0000, k << 65); + assert!(k < z); + assert!(y > k); + assert!(y < x); + assert_eq!(x as i64, -1); + assert_eq!(z as i64, 0xABCD_EF); + assert_eq!(k as i64, -0xFEDC_BA98_7654_3210); + assert_eq!(k as u128, 0xFEDC_BA98_7654_3210_0123_4567_89AB_CDF0); + assert_eq!(-k as u128, 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!((-z as f64) as i128, -z); + assert_eq!((-z as f32) as i128, -z); + assert_eq!((-z as f64 * 16.0) as i128, -z * 16); + assert_eq!((-z as f32 * 16.0) as i128, -z * 16); + // formatting + let j: i128 = -(1 << 67); + assert_eq!("-147573952589676412928", format!("{}", j)); + assert_eq!("fffffffffffffff80000000000000000", format!("{:x}", j)); + assert_eq!("3777777777777777777760000000000000000000000", format!("{:o}", j)); + assert_eq!("1111111111111111111111111111111111111111111111111111111111111\ + 0000000000000000000000000000000000000000000000000000000000000000000", + format!("{:b}", j)); + assert_eq!("-147573952589676412928", format!("{:?}", j)); + // common traits + assert_eq!(x, b(x.clone())); + // overflow checks + assert_eq!((-z).checked_mul(-z), Some(0x734C_C2F2_A521)); + assert_eq!((z).checked_mul(z), Some(0x734C_C2F2_A521)); + assert_eq!((k).checked_mul(k), None); + let l: i128 = b(i128::MIN); + let o: i128 = b(17); + assert_eq!(l.checked_sub(b(2)), None); + assert_eq!(l.checked_add(l), None); + assert_eq!((-(l + 1)).checked_add(2), None); + assert_eq!(l.checked_sub(l), Some(0)); + assert_eq!(b(1u128).checked_shl(b(127)), Some(1 << 127)); + assert_eq!(o.checked_shl(b(128)), None); + + // https://github.com/rust-lang/rust/issues/41228 + assert_eq!(b(-87559967289969187895646876466835277875_i128) / + b(84285771033834995895337664386045050880_i128), + -1i128); + + // iter-arithmetic traits + assert_eq!(10i128, [1i128, 2, 3, 4].iter().sum()); + assert_eq!(24i128, [1i128, 2, 3, 4].iter().product()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/i32-sub.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/i32-sub.rs new file mode 100644 index 000000000000..e5bb2af2f5e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/i32-sub.rs @@ -0,0 +1,7 @@ +// run-pass + + + + +pub fn main() { let mut x: i32 = -400; x = 0 - x; assert_eq!(x, 400); } + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/i8-incr.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/i8-incr.rs new file mode 100644 index 000000000000..162cde9deb9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/i8-incr.rs @@ -0,0 +1,13 @@ +// run-pass + + + + +pub fn main() { + let mut x: i8 = -12; + let y: i8 = -12; + x = x + 1; + x = x - 1; + assert_eq!(x, y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/int-abs-overflow.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/int-abs-overflow.rs new file mode 100644 index 000000000000..75e2cb94b138 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/int-abs-overflow.rs @@ -0,0 +1,14 @@ +// run-pass +// compile-flags: -Z force-overflow-checks=on +// ignore-emscripten no threads support + +use std::thread; + +fn main() { + assert!(thread::spawn(|| i8::MIN.abs()).join().is_err()); + assert!(thread::spawn(|| i16::MIN.abs()).join().is_err()); + assert!(thread::spawn(|| i32::MIN.abs()).join().is_err()); + assert!(thread::spawn(|| i64::MIN.abs()).join().is_err()); + assert!(thread::spawn(|| isize::MIN.abs()).join().is_err()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/int.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/int.rs new file mode 100644 index 000000000000..70f6fcaeb2e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/int.rs @@ -0,0 +1,8 @@ +// run-pass + + + +// pretty-expanded FIXME #23616 + +pub fn main() { let _x: isize = 10; } + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-radix.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-radix.rs new file mode 100644 index 000000000000..c82ae5eb7a79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-radix.rs @@ -0,0 +1,20 @@ +// run-pass + +pub fn main() { + let a = 0xBEEF_isize; + let b = 0o755_isize; + let c = 0b10101_isize; + let d = -0xBEEF_isize; + let e = -0o755_isize; + let f = -0b10101_isize; + + assert_eq!(a, 48879); + assert_eq!(b, 493); + assert_eq!(c, 21); + assert_eq!(d, -48879); + assert_eq!(e, -493); + assert_eq!(f, -21); + + +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs new file mode 100644 index 000000000000..f3ad42058fbc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference-2.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn foo(_: *const ()) {} + +fn main() { + let a = 3; + foo(&a as *const _ as *const ()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs new file mode 100644 index 000000000000..8d19af10aa92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference-3.rs @@ -0,0 +1,5 @@ +// run-pass +fn main() { + println!("{}", std::mem::size_of_val(&1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference.rs new file mode 100644 index 000000000000..69bf95a94fb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/integer-literal-suffix-inference.rs @@ -0,0 +1,61 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + fn id_i8(n: i8) -> i8 { n } + fn id_i16(n: i16) -> i16 { n } + fn id_i32(n: i32) -> i32 { n } + fn id_i64(n: i64) -> i64 { n } + + fn id_uint(n: usize) -> usize { n } + fn id_u8(n: u8) -> u8 { n } + fn id_u16(n: u16) -> u16 { n } + fn id_u32(n: u32) -> u32 { n } + fn id_u64(n: u64) -> u64 { n } + + let _i: i8 = -128; + let j = -128; + id_i8(j); + id_i8(-128); + + let _i: i16 = -32_768; + let j = -32_768; + id_i16(j); + id_i16(-32_768); + + let _i: i32 = -2_147_483_648; + let j = -2_147_483_648; + id_i32(j); + id_i32(-2_147_483_648); + + let _i: i64 = -9_223_372_036_854_775_808; + let j = -9_223_372_036_854_775_808; + id_i64(j); + id_i64(-9_223_372_036_854_775_808); + + let _i: usize = 1; + let j = 1; + id_uint(j); + id_uint(1); + + let _i: u8 = 255; + let j = 255; + id_u8(j); + id_u8(255); + + let _i: u16 = 65_535; + let j = 65_535; + id_u16(j); + id_u16(65_535); + + let _i: u32 = 4_294_967_295; + let j = 4_294_967_295; + id_u32(j); + id_u32(4_294_967_295); + + let _i: u64 = 18_446_744_073_709_551_615; + let j = 18_446_744_073_709_551_615; + id_u64(j); + id_u64(18_446_744_073_709_551_615); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/mod-zero.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/mod-zero.rs new file mode 100644 index 000000000000..94efe37b1ca1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/mod-zero.rs @@ -0,0 +1,10 @@ +// run-fail +// error-pattern:attempt to calculate the remainder with a divisor of zero +// ignore-emscripten no processes + +#[allow(unconditional_panic)] +fn main() { + let y = 0; + let _z = 1 % y; +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs new file mode 100644 index 000000000000..89e1dc35f2f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs @@ -0,0 +1,28 @@ +// run-pass +// compile-flags: -C debug_assertions=yes +// ignore-wasm32-bare compiled with panic=abort by default +// ignore-emscripten dies with an LLVM error + +use std::panic; + +fn main() { + macro_rules! overflow_test { + ($t:ident) => ( + let r = panic::catch_unwind(|| { + ($t::MAX).next_power_of_two() + }); + assert!(r.is_err()); + + let r = panic::catch_unwind(|| { + (($t::MAX >> 1) + 2).next_power_of_two() + }); + assert!(r.is_err()); + ) + } + overflow_test!(u8); + overflow_test!(u16); + overflow_test!(u32); + overflow_test!(u64); + overflow_test!(u128); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs new file mode 100644 index 000000000000..6390793d395b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/next-power-of-two-overflow-ndebug.rs @@ -0,0 +1,15 @@ +// run-pass +// compile-flags: -C debug_assertions=no +// ignore-emscripten dies with an LLVM error + +fn main() { + for i in 129..256 { + assert_eq!((i as u8).next_power_of_two(), 0); + } + + assert_eq!(((1u16 << 15) + 1).next_power_of_two(), 0); + assert_eq!(((1u32 << 31) + 1).next_power_of_two(), 0); + assert_eq!(((1u64 << 63) + 1).next_power_of_two(), 0); + assert_eq!(((1u128 << 127) + 1).next_power_of_two(), 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/num-wrapping.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/num-wrapping.rs new file mode 100644 index 000000000000..882a0d51bd58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/num-wrapping.rs @@ -0,0 +1,448 @@ +// run-pass +#![allow(unused_macros)] + +// compile-flags: -C debug-assertions +// +// Test std::num::Wrapping for {uN, iN, usize, isize} + +#![feature(test)] + +extern crate test; + +use std::num::Wrapping; +use std::ops::{ + Add, Sub, Mul, Div, Rem, BitXor, BitOr, BitAnd, + AddAssign, SubAssign, MulAssign, DivAssign, RemAssign, BitXorAssign, BitOrAssign, BitAndAssign, + Shl, Shr, ShlAssign, ShrAssign +}; +use test::black_box; + +macro_rules! int_modules { + ($(($name:ident, $size:expr),)*) => ($( + mod $name { + pub const BITS: usize = $size; + pub use std::$name::*; + } + )*) +} + +int_modules! { + (i8, 8), + (i16, 16), + (i32, 32), + (i64, 64), + (u8, 8), + (u16, 16), + (u32, 32), + (u64, 64), +} + +#[cfg(target_pointer_width = "32")] +int_modules! { + (isize, 32), + (usize, 32), +} + +#[cfg(target_pointer_width = "64")] +int_modules! { + (isize, 64), + (usize, 64), +} + +fn main() { + test_ops(); + test_op_assigns(); + test_sh_ops(); + test_sh_op_assigns(); +} + +fn test_ops() { + macro_rules! op_test { + ($op:ident ($lhs:expr, $rhs:expr) == $ans:expr) => { + assert_eq!(black_box(Wrapping($lhs).$op(Wrapping($rhs))), Wrapping($ans)); + // FIXME(30524): uncomment this test when it's implemented + // assert_eq!(black_box(Wrapping($lhs).$op($rhs)), Wrapping($ans)); + } + } + + op_test!(add(i8::MAX, 1) == i8::MIN); + op_test!(add(i16::MAX, 1) == i16::MIN); + op_test!(add(i32::MAX, 1) == i32::MIN); + op_test!(add(i64::MAX, 1) == i64::MIN); + op_test!(add(isize::MAX, 1) == isize::MIN); + + op_test!(add(u8::MAX, 1) == 0); + op_test!(add(u16::MAX, 1) == 0); + op_test!(add(u32::MAX, 1) == 0); + op_test!(add(u64::MAX, 1) == 0); + op_test!(add(usize::MAX, 1) == 0); + + + op_test!(sub(i8::MIN, 1) == i8::MAX); + op_test!(sub(i16::MIN, 1) == i16::MAX); + op_test!(sub(i32::MIN, 1) == i32::MAX); + op_test!(sub(i64::MIN, 1) == i64::MAX); + op_test!(sub(isize::MIN, 1) == isize::MAX); + + op_test!(sub(0u8, 1) == u8::MAX); + op_test!(sub(0u16, 1) == u16::MAX); + op_test!(sub(0u32, 1) == u32::MAX); + op_test!(sub(0u64, 1) == u64::MAX); + op_test!(sub(0usize, 1) == usize::MAX); + + + op_test!(mul(i8::MAX, 2) == -2); + op_test!(mul(i16::MAX, 2) == -2); + op_test!(mul(i32::MAX, 2) == -2); + op_test!(mul(i64::MAX, 2) == -2); + op_test!(mul(isize::MAX, 2) == -2); + + op_test!(mul(u8::MAX, 2) == u8::MAX - 1); + op_test!(mul(u16::MAX, 2) == u16::MAX - 1); + op_test!(mul(u32::MAX, 2) == u32::MAX - 1); + op_test!(mul(u64::MAX, 2) == u64::MAX - 1); + op_test!(mul(usize::MAX, 2) == usize::MAX - 1); + + + op_test!(div(i8::MIN, -1) == i8::MIN); + op_test!(div(i16::MIN, -1) == i16::MIN); + op_test!(div(i32::MIN, -1) == i32::MIN); + op_test!(div(i64::MIN, -1) == i64::MIN); + op_test!(div(isize::MIN, -1) == isize::MIN); + + + op_test!(rem(i8::MIN, -1) == 0); + op_test!(rem(i16::MIN, -1) == 0); + op_test!(rem(i32::MIN, -1) == 0); + op_test!(rem(i64::MIN, -1) == 0); + op_test!(rem(isize::MIN, -1) == 0); + + // these are not that interesting, just testing to make sure they are implemented correctly + op_test!(bitxor(0b101010i8, 0b100110) == 0b001100); + op_test!(bitxor(0b101010i16, 0b100110) == 0b001100); + op_test!(bitxor(0b101010i32, 0b100110) == 0b001100); + op_test!(bitxor(0b101010i64, 0b100110) == 0b001100); + op_test!(bitxor(0b101010isize, 0b100110) == 0b001100); + + op_test!(bitxor(0b101010u8, 0b100110) == 0b001100); + op_test!(bitxor(0b101010u16, 0b100110) == 0b001100); + op_test!(bitxor(0b101010u32, 0b100110) == 0b001100); + op_test!(bitxor(0b101010u64, 0b100110) == 0b001100); + op_test!(bitxor(0b101010usize, 0b100110) == 0b001100); + + + op_test!(bitor(0b101010i8, 0b100110) == 0b101110); + op_test!(bitor(0b101010i16, 0b100110) == 0b101110); + op_test!(bitor(0b101010i32, 0b100110) == 0b101110); + op_test!(bitor(0b101010i64, 0b100110) == 0b101110); + op_test!(bitor(0b101010isize, 0b100110) == 0b101110); + + op_test!(bitor(0b101010u8, 0b100110) == 0b101110); + op_test!(bitor(0b101010u16, 0b100110) == 0b101110); + op_test!(bitor(0b101010u32, 0b100110) == 0b101110); + op_test!(bitor(0b101010u64, 0b100110) == 0b101110); + op_test!(bitor(0b101010usize, 0b100110) == 0b101110); + + + op_test!(bitand(0b101010i8, 0b100110) == 0b100010); + op_test!(bitand(0b101010i16, 0b100110) == 0b100010); + op_test!(bitand(0b101010i32, 0b100110) == 0b100010); + op_test!(bitand(0b101010i64, 0b100110) == 0b100010); + op_test!(bitand(0b101010isize, 0b100110) == 0b100010); + + op_test!(bitand(0b101010u8, 0b100110) == 0b100010); + op_test!(bitand(0b101010u16, 0b100110) == 0b100010); + op_test!(bitand(0b101010u32, 0b100110) == 0b100010); + op_test!(bitand(0b101010u64, 0b100110) == 0b100010); + op_test!(bitand(0b101010usize, 0b100110) == 0b100010); +} + +fn test_op_assigns() { + macro_rules! op_assign_test { + ($op:ident ($initial:expr, $rhs:expr) == $ans:expr) => { + { + let mut tmp = Wrapping($initial); + tmp = black_box(tmp); + tmp.$op(Wrapping($rhs)); + assert_eq!(black_box(tmp), Wrapping($ans)); + } + + // also test that a &Wrapping right-hand side is possible + { + let mut tmp = Wrapping($initial); + tmp = black_box(tmp); + tmp.$op(&Wrapping($rhs)); + assert_eq!(black_box(tmp), Wrapping($ans)); + } + + // FIXME(30524): uncomment this test + /* + { + let mut tmp = Wrapping($initial); + tmp = black_box(tmp); + tmp.$op($rhs); + assert_eq!(black_box(tmp), Wrapping($ans)); + } + */ + } + } + op_assign_test!(add_assign(i8::MAX, 1) == i8::MIN); + op_assign_test!(add_assign(i16::MAX, 1) == i16::MIN); + op_assign_test!(add_assign(i32::MAX, 1) == i32::MIN); + op_assign_test!(add_assign(i64::MAX, 1) == i64::MIN); + op_assign_test!(add_assign(isize::MAX, 1) == isize::MIN); + + op_assign_test!(add_assign(u8::MAX, 1) == u8::MIN); + op_assign_test!(add_assign(u16::MAX, 1) == u16::MIN); + op_assign_test!(add_assign(u32::MAX, 1) == u32::MIN); + op_assign_test!(add_assign(u64::MAX, 1) == u64::MIN); + op_assign_test!(add_assign(usize::MAX, 1) == usize::MIN); + + + op_assign_test!(sub_assign(i8::MIN, 1) == i8::MAX); + op_assign_test!(sub_assign(i16::MIN, 1) == i16::MAX); + op_assign_test!(sub_assign(i32::MIN, 1) == i32::MAX); + op_assign_test!(sub_assign(i64::MIN, 1) == i64::MAX); + op_assign_test!(sub_assign(isize::MIN, 1) == isize::MAX); + + op_assign_test!(sub_assign(u8::MIN, 1) == u8::MAX); + op_assign_test!(sub_assign(u16::MIN, 1) == u16::MAX); + op_assign_test!(sub_assign(u32::MIN, 1) == u32::MAX); + op_assign_test!(sub_assign(u64::MIN, 1) == u64::MAX); + op_assign_test!(sub_assign(usize::MIN, 1) == usize::MAX); + + + op_assign_test!(mul_assign(i8::MAX, 2) == -2); + op_assign_test!(mul_assign(i16::MAX, 2) == -2); + op_assign_test!(mul_assign(i32::MAX, 2) == -2); + op_assign_test!(mul_assign(i64::MAX, 2) == -2); + op_assign_test!(mul_assign(isize::MAX, 2) == -2); + + op_assign_test!(mul_assign(u8::MAX, 2) == u8::MAX - 1); + op_assign_test!(mul_assign(u16::MAX, 2) == u16::MAX - 1); + op_assign_test!(mul_assign(u32::MAX, 2) == u32::MAX - 1); + op_assign_test!(mul_assign(u64::MAX, 2) == u64::MAX - 1); + op_assign_test!(mul_assign(usize::MAX, 2) == usize::MAX - 1); + + + op_assign_test!(div_assign(i8::MIN, -1) == i8::MIN); + op_assign_test!(div_assign(i16::MIN, -1) == i16::MIN); + op_assign_test!(div_assign(i32::MIN, -1) == i32::MIN); + op_assign_test!(div_assign(i64::MIN, -1) == i64::MIN); + op_assign_test!(div_assign(isize::MIN, -1) == isize::MIN); + + + op_assign_test!(rem_assign(i8::MIN, -1) == 0); + op_assign_test!(rem_assign(i16::MIN, -1) == 0); + op_assign_test!(rem_assign(i32::MIN, -1) == 0); + op_assign_test!(rem_assign(i64::MIN, -1) == 0); + op_assign_test!(rem_assign(isize::MIN, -1) == 0); + + + // these are not that interesting, just testing to make sure they are implemented correctly + op_assign_test!(bitxor_assign(0b101010i8, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010i16, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010i32, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010i64, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010isize, 0b100110) == 0b001100); + + op_assign_test!(bitxor_assign(0b101010u8, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010u16, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010u32, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010u64, 0b100110) == 0b001100); + op_assign_test!(bitxor_assign(0b101010usize, 0b100110) == 0b001100); + + + op_assign_test!(bitor_assign(0b101010i8, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010i16, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010i32, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010i64, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010isize, 0b100110) == 0b101110); + + op_assign_test!(bitor_assign(0b101010u8, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010u16, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010u32, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010u64, 0b100110) == 0b101110); + op_assign_test!(bitor_assign(0b101010usize, 0b100110) == 0b101110); + + + op_assign_test!(bitand_assign(0b101010i8, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010i16, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010i32, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010i64, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010isize, 0b100110) == 0b100010); + + op_assign_test!(bitand_assign(0b101010u8, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010u16, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010u32, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010u64, 0b100110) == 0b100010); + op_assign_test!(bitand_assign(0b101010usize, 0b100110) == 0b100010); +} + +fn test_sh_ops() { + macro_rules! sh_test { + ($op:ident ($lhs:expr, $rhs:expr) == $ans:expr) => { + assert_eq!(black_box(Wrapping($lhs).$op($rhs)), Wrapping($ans)); + } + } + // NOTE: This will break for i8 if we ever get i/u128 + macro_rules! sh_test_all { + ($t:ty) => { + sh_test!(shl(i8::MAX, (i8::BITS + 1) as $t) == -2); + sh_test!(shl(i16::MAX, (i16::BITS + 1) as $t) == -2); + sh_test!(shl(i32::MAX, (i32::BITS + 1) as $t) == -2); + sh_test!(shl(i64::MAX, (i64::BITS + 1) as $t) == -2); + sh_test!(shl(isize::MAX, (isize::BITS + 1) as $t) == -2); + + sh_test!(shl(u8::MAX, (u8::BITS + 1) as $t) == u8::MAX - 1); + sh_test!(shl(u16::MAX, (u16::BITS + 1) as $t) == u16::MAX - 1); + sh_test!(shl(u32::MAX, (u32::BITS + 1) as $t) == u32::MAX - 1); + sh_test!(shl(u64::MAX, (u64::BITS + 1) as $t) == u64::MAX - 1); + sh_test!(shl(usize::MAX, (usize::BITS + 1) as $t) == usize::MAX - 1); + + + sh_test!(shr(i8::MAX, (i8::BITS + 1) as $t) == i8::MAX / 2); + sh_test!(shr(i16::MAX, (i16::BITS + 1) as $t) == i16::MAX / 2); + sh_test!(shr(i32::MAX, (i32::BITS + 1) as $t) == i32::MAX / 2); + sh_test!(shr(i64::MAX, (i64::BITS + 1) as $t) == i64::MAX / 2); + sh_test!(shr(isize::MAX, (isize::BITS + 1) as $t) == isize::MAX / 2); + + sh_test!(shr(u8::MAX, (u8::BITS + 1) as $t) == u8::MAX / 2); + sh_test!(shr(u16::MAX, (u16::BITS + 1) as $t) == u16::MAX / 2); + sh_test!(shr(u32::MAX, (u32::BITS + 1) as $t) == u32::MAX / 2); + sh_test!(shr(u64::MAX, (u64::BITS + 1) as $t) == u64::MAX / 2); + sh_test!(shr(usize::MAX, (usize::BITS + 1) as $t) == usize::MAX / 2); + } + } + macro_rules! sh_test_negative_all { + ($t:ty) => { + sh_test!(shr(i8::MAX, -((i8::BITS + 1) as $t)) == -2); + sh_test!(shr(i16::MAX, -((i16::BITS + 1) as $t)) == -2); + sh_test!(shr(i32::MAX, -((i32::BITS + 1) as $t)) == -2); + sh_test!(shr(i64::MAX, -((i64::BITS + 1) as $t)) == -2); + sh_test!(shr(isize::MAX, -((isize::BITS + 1) as $t)) == -2); + + sh_test!(shr(u8::MAX, -((u8::BITS + 1) as $t)) == u8::MAX - 1); + sh_test!(shr(u16::MAX, -((u16::BITS + 1) as $t)) == u16::MAX - 1); + sh_test!(shr(u32::MAX, -((u32::BITS + 1) as $t)) == u32::MAX - 1); + sh_test!(shr(u64::MAX, -((u64::BITS + 1) as $t)) == u64::MAX - 1); + sh_test!(shr(usize::MAX, -((usize::BITS + 1) as $t)) == usize::MAX - 1); + + + sh_test!(shl(i8::MAX, -((i8::BITS + 1) as $t)) == i8::MAX / 2); + sh_test!(shl(i16::MAX, -((i16::BITS + 1) as $t)) == i16::MAX / 2); + sh_test!(shl(i32::MAX, -((i32::BITS + 1) as $t)) == i32::MAX / 2); + sh_test!(shl(i64::MAX, -((i64::BITS + 1) as $t)) == i64::MAX / 2); + sh_test!(shl(isize::MAX, -((isize::BITS + 1) as $t)) == isize::MAX / 2); + + sh_test!(shl(u8::MAX, -((u8::BITS + 1) as $t)) == u8::MAX / 2); + sh_test!(shl(u16::MAX, -((u16::BITS + 1) as $t)) == u16::MAX / 2); + sh_test!(shl(u32::MAX, -((u32::BITS + 1) as $t)) == u32::MAX / 2); + sh_test!(shl(u64::MAX, -((u64::BITS + 1) as $t)) == u64::MAX / 2); + sh_test!(shl(usize::MAX, -((usize::BITS + 1) as $t)) == usize::MAX / 2); + } + } + // FIXME(#23545): Uncomment the remaining tests + //sh_test_all!(i8); + //sh_test_all!(u8); + //sh_test_all!(i16); + //sh_test_all!(u16); + //sh_test_all!(i32); + //sh_test_all!(u32); + //sh_test_all!(i64); + //sh_test_all!(u64); + //sh_test_all!(isize); + sh_test_all!(usize); + + //sh_test_negative_all!(i8); + //sh_test_negative_all!(i16); + //sh_test_negative_all!(i32); + //sh_test_negative_all!(i64); + //sh_test_negative_all!(isize); +} + +fn test_sh_op_assigns() { + macro_rules! sh_assign_test { + ($op:ident ($initial:expr, $rhs:expr) == $ans:expr) => {{ + let mut tmp = Wrapping($initial); + tmp = black_box(tmp); + tmp.$op($rhs); + assert_eq!(black_box(tmp), Wrapping($ans)); + }} + } + macro_rules! sh_assign_test_all { + ($t:ty) => { + sh_assign_test!(shl_assign(i8::MAX, (i8::BITS + 1) as $t) == -2); + sh_assign_test!(shl_assign(i16::MAX, (i16::BITS + 1) as $t) == -2); + sh_assign_test!(shl_assign(i32::MAX, (i32::BITS + 1) as $t) == -2); + sh_assign_test!(shl_assign(i64::MAX, (i64::BITS + 1) as $t) == -2); + sh_assign_test!(shl_assign(isize::MAX, (isize::BITS + 1) as $t) == -2); + + sh_assign_test!(shl_assign(u8::MAX, (u8::BITS + 1) as $t) == u8::MAX - 1); + sh_assign_test!(shl_assign(u16::MAX, (u16::BITS + 1) as $t) == u16::MAX - 1); + sh_assign_test!(shl_assign(u32::MAX, (u32::BITS + 1) as $t) == u32::MAX - 1); + sh_assign_test!(shl_assign(u64::MAX, (u64::BITS + 1) as $t) == u64::MAX - 1); + sh_assign_test!(shl_assign(usize::MAX, (usize::BITS + 1) as $t) == usize::MAX - 1); + + + sh_assign_test!(shr_assign(i8::MAX, (i8::BITS + 1) as $t) == i8::MAX / 2); + sh_assign_test!(shr_assign(i16::MAX, (i16::BITS + 1) as $t) == i16::MAX / 2); + sh_assign_test!(shr_assign(i32::MAX, (i32::BITS + 1) as $t) == i32::MAX / 2); + sh_assign_test!(shr_assign(i64::MAX, (i64::BITS + 1) as $t) == i64::MAX / 2); + sh_assign_test!(shr_assign(isize::MAX, (isize::BITS + 1) as $t) == isize::MAX / 2); + + sh_assign_test!(shr_assign(u8::MAX, (u8::BITS + 1) as $t) == u8::MAX / 2); + sh_assign_test!(shr_assign(u16::MAX, (u16::BITS + 1) as $t) == u16::MAX / 2); + sh_assign_test!(shr_assign(u32::MAX, (u32::BITS + 1) as $t) == u32::MAX / 2); + sh_assign_test!(shr_assign(u64::MAX, (u64::BITS + 1) as $t) == u64::MAX / 2); + sh_assign_test!(shr_assign(usize::MAX, (usize::BITS + 1) as $t) == usize::MAX / 2); + } + } + macro_rules! sh_assign_test_negative_all { + ($t:ty) => { + sh_assign_test!(shr_assign(i8::MAX, -((i8::BITS + 1) as $t)) == -2); + sh_assign_test!(shr_assign(i16::MAX, -((i16::BITS + 1) as $t)) == -2); + sh_assign_test!(shr_assign(i32::MAX, -((i32::BITS + 1) as $t)) == -2); + sh_assign_test!(shr_assign(i64::MAX, -((i64::BITS + 1) as $t)) == -2); + sh_assign_test!(shr_assign(isize::MAX, -((isize::BITS + 1) as $t)) == -2); + + sh_assign_test!(shr_assign(u8::MAX, -((u8::BITS + 1) as $t)) == u8::MAX - 1); + sh_assign_test!(shr_assign(u16::MAX, -((u16::BITS + 1) as $t)) == u16::MAX - 1); + sh_assign_test!(shr_assign(u32::MAX, -((u32::BITS + 1) as $t)) == u32::MAX - 1); + sh_assign_test!(shr_assign(u64::MAX, -((u64::BITS + 1) as $t)) == u64::MAX - 1); + sh_assign_test!(shr_assign(usize::MAX, -((usize::BITS + 1) as $t)) == usize::MAX - 1); + + + sh_assign_test!(shl_assign(i8::MAX, -((i8::BITS + 1) as $t)) == i8::MAX / 2); + sh_assign_test!(shl_assign(i16::MAX, -((i16::BITS + 1) as $t)) == i16::MAX / 2); + sh_assign_test!(shl_assign(i32::MAX, -((i32::BITS + 1) as $t)) == i32::MAX / 2); + sh_assign_test!(shl_assign(i64::MAX, -((i64::BITS + 1) as $t)) == i64::MAX / 2); + sh_assign_test!(shl_assign(isize::MAX, -((isize::BITS + 1) as $t)) == isize::MAX / 2); + + sh_assign_test!(shl_assign(u8::MAX, -((u8::BITS + 1) as $t)) == u8::MAX / 2); + sh_assign_test!(shl_assign(u16::MAX, -((u16::BITS + 1) as $t)) == u16::MAX / 2); + sh_assign_test!(shl_assign(u32::MAX, -((u32::BITS + 1) as $t)) == u32::MAX / 2); + sh_assign_test!(shl_assign(u64::MAX, -((u64::BITS + 1) as $t)) == u64::MAX / 2); + sh_assign_test!(shl_assign(usize::MAX, -((usize::BITS + 1) as $t)) == usize::MAX / 2); + } + } + + // FIXME(#23545): Uncomment the remaining tests + //sh_assign_test_all!(i8); + //sh_assign_test_all!(u8); + //sh_assign_test_all!(i16); + //sh_assign_test_all!(u16); + //sh_assign_test_all!(i32); + //sh_assign_test_all!(u32); + //sh_assign_test_all!(i64); + //sh_assign_test_all!(u64); + //sh_assign_test_all!(isize); + sh_assign_test_all!(usize); + + //sh_assign_test_negative_all!(i8); + //sh_assign_test_negative_all!(i16); + //sh_assign_test_negative_all!(i32); + //sh_assign_test_negative_all!(i64); + //sh_assign_test_negative_all!(isize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/numeric-method-autoexport.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/numeric-method-autoexport.rs new file mode 100644 index 000000000000..52291d222845 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/numeric-method-autoexport.rs @@ -0,0 +1,26 @@ +// run-pass +// This file is intended to test only that methods are automatically +// reachable for each numeric type, for each exported impl, with no imports +// necessary. Testing the methods of the impls is done within the source +// file for each numeric type. + +use std::ops::Add; + +pub fn main() { +// ints + // num + assert_eq!(15_isize.add(6_isize), 21_isize); + assert_eq!(15_i8.add(6i8), 21_i8); + assert_eq!(15_i16.add(6i16), 21_i16); + assert_eq!(15_i32.add(6i32), 21_i32); + assert_eq!(15_i64.add(6i64), 21_i64); + +// uints + // num + assert_eq!(15_usize.add(6_usize), 21_usize); + assert_eq!(15_u8.add(6u8), 21_u8); + assert_eq!(15_u16.add(6u16), 21_u16); + assert_eq!(15_u32.add(6u32), 21_u32); + assert_eq!(15_u64.add(6u64), 21_u64); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-add.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-add.rs new file mode 100644 index 000000000000..b0280061bb65 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-add.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:thread 'main' panicked at 'attempt to add with overflow' +// compile-flags: -C debug-assertions +// ignore-emscripten no processes + +#![allow(arithmetic_overflow)] + +fn main() { + let _x = 200u8 + 200u8 + 200u8; +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-1.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-1.rs new file mode 100644 index 000000000000..4d6c747fa09e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-1.rs @@ -0,0 +1,10 @@ +// build-fail +// compile-flags: -C debug-assertions + +#![deny(arithmetic_overflow, const_err)] + +fn main() { + let _x = 1_i32 << 32; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-2.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-2.rs new file mode 100644 index 000000000000..a019fbbfc0fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-2.rs @@ -0,0 +1,10 @@ +// build-fail +// compile-flags: -C debug-assertions + +#![deny(arithmetic_overflow, const_err)] + +fn main() { + let _x = 1 << -1; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-3.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-3.rs new file mode 100644 index 000000000000..5cc5b7b0853a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-3.rs @@ -0,0 +1,10 @@ +// build-fail +// compile-flags: -C debug-assertions + +#![deny(arithmetic_overflow, const_err)] + +fn main() { + let _x = 1_u64 << 64; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-4.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-4.rs new file mode 100644 index 000000000000..e69b29c0bf68 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-lsh-4.rs @@ -0,0 +1,25 @@ +// build-fail +// compile-flags: -C debug-assertions + +// This function is checking that our automatic truncation does not +// sidestep the overflow checking. + +#![deny(arithmetic_overflow, const_err)] + +fn main() { + // this signals overflow when checking is on + let x = 1_i8 << 17; +// { dg-error "" "" { target *-*-* } .-1 } + + // ... but when checking is off, the fallback will truncate the + // input to its lower three bits (= 1). Note that this is *not* + // the behavior of the x86 processor for 8- and 16-bit types, + // but it is necessary to avoid undefined behavior from LLVM. + // + // We check that here, by ensuring the result has only been + // shifted by one place; if overflow checking is turned off, then + // this assertion will pass (and the compiletest driver will + // report that the test did not produce the error expected above). + assert_eq!(x, 2_i8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-mul.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-mul.rs new file mode 100644 index 000000000000..bd3e42d84610 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-mul.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:thread 'main' panicked at 'attempt to multiply with overflow' +// ignore-emscripten no processes +// compile-flags: -C debug-assertions + +#![allow(arithmetic_overflow)] + +fn main() { + let x = 200u8 * 4; +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-neg.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-neg.rs new file mode 100644 index 000000000000..a5eeb5017fe7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-neg.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:thread 'main' panicked at 'attempt to negate with overflow' +// ignore-emscripten no processes +// compile-flags: -C debug-assertions + +#![allow(arithmetic_overflow)] + +fn main() { + let _x = -std::i8::MIN; +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-pow-signed.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-pow-signed.rs new file mode 100644 index 000000000000..93bcf98f4514 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-pow-signed.rs @@ -0,0 +1,9 @@ +// run-fail +// error-pattern:thread 'main' panicked at 'attempt to multiply with overflow' +// ignore-emscripten no processes +// compile-flags: -C debug-assertions + +fn main() { + let _x = 2i32.pow(1024); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-pow-unsigned.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-pow-unsigned.rs new file mode 100644 index 000000000000..4ee2b43df6eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-pow-unsigned.rs @@ -0,0 +1,9 @@ +// run-fail +// error-pattern:thread 'main' panicked at 'attempt to multiply with overflow' +// ignore-emscripten no processes +// compile-flags: -C debug-assertions + +fn main() { + let _x = 2u32.pow(1024); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-1.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-1.rs new file mode 100644 index 000000000000..42a346ddcc91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-1.rs @@ -0,0 +1,10 @@ +// build-fail +// compile-flags: -C debug-assertions + +#![deny(arithmetic_overflow, const_err)] + +fn main() { + let _x = -1_i32 >> 32; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-2.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-2.rs new file mode 100644 index 000000000000..086b529b4e89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-2.rs @@ -0,0 +1,10 @@ +// build-fail +// compile-flags: -C debug-assertions + +#![deny(arithmetic_overflow, const_err)] + +fn main() { + let _x = -1_i32 >> -1; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-3.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-3.rs new file mode 100644 index 000000000000..c5ef061b2c0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-3.rs @@ -0,0 +1,10 @@ +// build-fail +// compile-flags: -C debug-assertions + +#![deny(arithmetic_overflow, const_err)] + +fn main() { + let _x = -1_i64 >> 64; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-4.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-4.rs new file mode 100644 index 000000000000..b0f2eb5d6bea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-4.rs @@ -0,0 +1,25 @@ +// build-fail +// compile-flags: -C debug-assertions + +// This function is checking that our (type-based) automatic +// truncation does not sidestep the overflow checking. + +#![deny(arithmetic_overflow, const_err)] + +fn main() { + // this signals overflow when checking is on + let x = 2_i8 >> 17; +// { dg-error "" "" { target *-*-* } .-1 } + + // ... but when checking is off, the fallback will truncate the + // input to its lower three bits (= 1). Note that this is *not* + // the behavior of the x86 processor for 8- and 16-bit types, + // but it is necessary to avoid undefined behavior from LLVM. + // + // We check that here, by ensuring the result is not zero; if + // overflow checking is turned off, then this assertion will pass + // (and the compiletest driver will report that the test did not + // produce the error expected above). + assert_eq!(x, 1_i8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-5.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-5.rs new file mode 100644 index 000000000000..7fcd644686e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-5.rs @@ -0,0 +1,10 @@ +// build-fail +// compile-flags: -C debug-assertions + +#![deny(arithmetic_overflow, const_err)] + +fn main() { + let _n = 1i64 >> [64][0]; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-6.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-6.rs new file mode 100644 index 000000000000..7fcd644686e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-rsh-6.rs @@ -0,0 +1,10 @@ +// build-fail +// compile-flags: -C debug-assertions + +#![deny(arithmetic_overflow, const_err)] + +fn main() { + let _n = 1i64 >> [64][0]; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-sub.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-sub.rs new file mode 100644 index 000000000000..72ad3eee243a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/overflowing-sub.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:thread 'main' panicked at 'attempt to subtract with overflow' +// ignore-emscripten no processes +// compile-flags: -C debug-assertions + +#![allow(arithmetic_overflow)] + +fn main() { + let _x = 42u8 - (42u8 + 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/promoted_overflow.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/promoted_overflow.rs new file mode 100644 index 000000000000..71b6eb87b1fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/promoted_overflow.rs @@ -0,0 +1,10 @@ +#![allow(arithmetic_overflow)] + +// run-fail +// error-pattern: overflow +// compile-flags: -C overflow-checks=yes + +fn main() { + let x: &'static u32 = &(0u32 - 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/promoted_overflow_opt.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/promoted_overflow_opt.rs new file mode 100644 index 000000000000..d158fc5b46ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/promoted_overflow_opt.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(const_err)] + +// compile-flags: -O + +fn main() { + let x = &(0u32 - 1); + assert_eq!(*x, u32::MAX) +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/saturating-float-casts-impl.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/saturating-float-casts-impl.rs new file mode 100644 index 000000000000..7bb818fbfb8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/saturating-float-casts-impl.rs @@ -0,0 +1,508 @@ +// ignore-test + +// Tests saturating float->int casts. See u128-as-f32.rs for the opposite direction. +// +// Some of these tests come from a similar file in miri, +// tests/run-pass/float.rs. Individual test cases are potentially duplicated +// with the previously existing tests, but since this runs so quickly anyway, +// we're not spending the time to figure out exactly which ones should be +// merged. + +extern crate test; + +use self::test::black_box; +use std::{f32, f64}; +#[cfg(not(target_os = "emscripten"))] +use std::{i128, u128}; +use std::{i16, i32, i64, i8, u16, u32, u64, u8}; + +macro_rules! test { + ($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => ( + // black_box disables constant evaluation to test run-time conversions: + assert_eq!(black_box::<$src_ty>($val) as $dest_ty, $expected, + "run-time {} -> {}", stringify!($src_ty), stringify!($dest_ty)); + + { + const X: $src_ty = $val; + const Y: $dest_ty = X as $dest_ty; + assert_eq!(Y, $expected, + "const eval {} -> {}", stringify!($src_ty), stringify!($dest_ty)); + } + ); + + ($fval:expr, f* -> $ity:ident, $ival:expr) => ( + test!($fval, f32 -> $ity, $ival); + test!($fval, f64 -> $ity, $ival); + ) +} + +macro_rules! common_fptoi_tests { + ($fty:ident -> $($ity:ident)+) => ({ $( + test!($fty::NAN, $fty -> $ity, 0); + test!($fty::INFINITY, $fty -> $ity, $ity::MAX); + test!($fty::NEG_INFINITY, $fty -> $ity, $ity::MIN); + // These two tests are not solely float->int tests, in particular the latter relies on + // `u128::MAX as f32` not being UB. But that's okay, since this file tests int->float + // as well, the test is just slightly misplaced. + test!($ity::MIN as $fty, $fty -> $ity, $ity::MIN); + test!($ity::MAX as $fty, $fty -> $ity, $ity::MAX); + test!(0., $fty -> $ity, 0); + test!($fty::MIN_POSITIVE, $fty -> $ity, 0); + test!(-0.9, $fty -> $ity, 0); + test!(1., $fty -> $ity, 1); + test!(42., $fty -> $ity, 42); + )+ }); + + (f* -> $($ity:ident)+) => ({ + common_fptoi_tests!(f32 -> $($ity)+); + common_fptoi_tests!(f64 -> $($ity)+); + }) +} + +macro_rules! fptoui_tests { + ($fty: ident -> $($ity: ident)+) => ({ $( + test!(-0., $fty -> $ity, 0); + test!(-$fty::MIN_POSITIVE, $fty -> $ity, 0); + test!(-0.99999994, $fty -> $ity, 0); + test!(-1., $fty -> $ity, 0); + test!(-100., $fty -> $ity, 0); + test!(#[allow(overflowing_literals)] -1e50, $fty -> $ity, 0); + test!(#[allow(overflowing_literals)] -1e130, $fty -> $ity, 0); + )+ }); + + (f* -> $($ity:ident)+) => ({ + fptoui_tests!(f32 -> $($ity)+); + fptoui_tests!(f64 -> $($ity)+); + }) +} + +use std::fmt::Debug; + +// Helper function to avoid promotion so that this tests "run-time" casts, not CTFE. +#[track_caller] +#[inline(never)] +fn assert_eq(x: T, y: T) { + assert_eq!(x, y); +} + +trait FloatToInt: Copy { + fn cast(self) -> Int; + unsafe fn cast_unchecked(self) -> Int; +} + +impl FloatToInt for f32 { + fn cast(self) -> i8 { + self as _ + } + unsafe fn cast_unchecked(self) -> i8 { + self.to_int_unchecked() + } +} +impl FloatToInt for f32 { + fn cast(self) -> i32 { + self as _ + } + unsafe fn cast_unchecked(self) -> i32 { + self.to_int_unchecked() + } +} +impl FloatToInt for f32 { + fn cast(self) -> u32 { + self as _ + } + unsafe fn cast_unchecked(self) -> u32 { + self.to_int_unchecked() + } +} +impl FloatToInt for f32 { + fn cast(self) -> i64 { + self as _ + } + unsafe fn cast_unchecked(self) -> i64 { + self.to_int_unchecked() + } +} +impl FloatToInt for f32 { + fn cast(self) -> u64 { + self as _ + } + unsafe fn cast_unchecked(self) -> u64 { + self.to_int_unchecked() + } +} + +impl FloatToInt for f64 { + fn cast(self) -> i8 { + self as _ + } + unsafe fn cast_unchecked(self) -> i8 { + self.to_int_unchecked() + } +} +impl FloatToInt for f64 { + fn cast(self) -> i32 { + self as _ + } + unsafe fn cast_unchecked(self) -> i32 { + self.to_int_unchecked() + } +} +impl FloatToInt for f64 { + fn cast(self) -> u32 { + self as _ + } + unsafe fn cast_unchecked(self) -> u32 { + self.to_int_unchecked() + } +} +impl FloatToInt for f64 { + fn cast(self) -> i64 { + self as _ + } + unsafe fn cast_unchecked(self) -> i64 { + self.to_int_unchecked() + } +} +impl FloatToInt for f64 { + fn cast(self) -> u64 { + self as _ + } + unsafe fn cast_unchecked(self) -> u64 { + self.to_int_unchecked() + } +} +// FIXME emscripten does not support i128 +#[cfg(not(target_os = "emscripten"))] +impl FloatToInt for f64 { + fn cast(self) -> i128 { + self as _ + } + unsafe fn cast_unchecked(self) -> i128 { + self.to_int_unchecked() + } +} +// FIXME emscripten does not support i128 +#[cfg(not(target_os = "emscripten"))] +impl FloatToInt for f64 { + fn cast(self) -> u128 { + self as _ + } + unsafe fn cast_unchecked(self) -> u128 { + self.to_int_unchecked() + } +} + +/// Test this cast both via `as` and via `to_int_unchecked` (i.e., it must not saturate). +#[track_caller] +#[inline(never)] +fn test_both_cast(x: F, y: I) +where + F: FloatToInt, + I: PartialEq + Debug, +{ + assert_eq!(x.cast(), y); + assert_eq!(unsafe { x.cast_unchecked() }, y); +} + +fn casts() { + // f32 -> i8 + test_both_cast::(127.99, 127); + test_both_cast::(-128.99, -128); + + // f32 -> i32 + test_both_cast::(0.0, 0); + test_both_cast::(-0.0, 0); + test_both_cast::(/*0x1p-149*/ f32::from_bits(0x00000001), 0); + test_both_cast::(/*-0x1p-149*/ f32::from_bits(0x80000001), 0); + test_both_cast::(/*0x1.19999ap+0*/ f32::from_bits(0x3f8ccccd), 1); + test_both_cast::(/*-0x1.19999ap+0*/ f32::from_bits(0xbf8ccccd), -1); + test_both_cast::(1.9, 1); + test_both_cast::(-1.9, -1); + test_both_cast::(5.0, 5); + test_both_cast::(-5.0, -5); + test_both_cast::(2147483520.0, 2147483520); + test_both_cast::(-2147483648.0, -2147483648); + // unrepresentable casts + assert_eq::(2147483648.0f32 as i32, i32::MAX); + assert_eq::(-2147483904.0f32 as i32, i32::MIN); + assert_eq::(f32::MAX as i32, i32::MAX); + assert_eq::(f32::MIN as i32, i32::MIN); + assert_eq::(f32::INFINITY as i32, i32::MAX); + assert_eq::(f32::NEG_INFINITY as i32, i32::MIN); + assert_eq::(f32::NAN as i32, 0); + assert_eq::((-f32::NAN) as i32, 0); + + // f32 -> u32 + test_both_cast::(0.0, 0); + test_both_cast::(-0.0, 0); + test_both_cast::(-0.9999999, 0); + test_both_cast::(/*0x1p-149*/ f32::from_bits(0x1), 0); + test_both_cast::(/*-0x1p-149*/ f32::from_bits(0x80000001), 0); + test_both_cast::(/*0x1.19999ap+0*/ f32::from_bits(0x3f8ccccd), 1); + test_both_cast::(1.9, 1); + test_both_cast::(5.0, 5); + test_both_cast::(2147483648.0, 0x8000_0000); + test_both_cast::(4294967040.0, 0u32.wrapping_sub(256)); + test_both_cast::(/*-0x1.ccccccp-1*/ f32::from_bits(0xbf666666), 0); + test_both_cast::(/*-0x1.fffffep-1*/ f32::from_bits(0xbf7fffff), 0); + test_both_cast::((u32::MAX - 128) as f32, u32::MAX - 255); // rounding loss + + // unrepresentable casts: + + // rounds up and then becomes unrepresentable + assert_eq::((u32::MAX - 127) as f32 as u32, u32::MAX); + + assert_eq::(4294967296.0f32 as u32, u32::MAX); + assert_eq::(-5.0f32 as u32, 0); + assert_eq::(f32::MAX as u32, u32::MAX); + assert_eq::(f32::MIN as u32, 0); + assert_eq::(f32::INFINITY as u32, u32::MAX); + assert_eq::(f32::NEG_INFINITY as u32, 0); + assert_eq::(f32::NAN as u32, 0); + assert_eq::((-f32::NAN) as u32, 0); + + // f32 -> i64 + test_both_cast::(4294967296.0, 4294967296); + test_both_cast::(-4294967296.0, -4294967296); + test_both_cast::(9223371487098961920.0, 9223371487098961920); + test_both_cast::(-9223372036854775808.0, -9223372036854775808); + + // f64 -> i8 + test_both_cast::(127.99, 127); + test_both_cast::(-128.99, -128); + + // f64 -> i32 + test_both_cast::(0.0, 0); + test_both_cast::(-0.0, 0); + test_both_cast::(/*0x1.199999999999ap+0*/ f64::from_bits(0x3ff199999999999a), 1); + test_both_cast::( + /*-0x1.199999999999ap+0*/ f64::from_bits(0xbff199999999999a), + -1, + ); + test_both_cast::(1.9, 1); + test_both_cast::(-1.9, -1); + test_both_cast::(1e8, 100_000_000); + test_both_cast::(2147483647.0, 2147483647); + test_both_cast::(-2147483648.0, -2147483648); + // unrepresentable casts + assert_eq::(2147483648.0f64 as i32, i32::MAX); + assert_eq::(-2147483649.0f64 as i32, i32::MIN); + + // f64 -> i64 + test_both_cast::(0.0, 0); + test_both_cast::(-0.0, 0); + test_both_cast::(/*0x0.0000000000001p-1022*/ f64::from_bits(0x1), 0); + test_both_cast::( + /*-0x0.0000000000001p-1022*/ f64::from_bits(0x8000000000000001), + 0, + ); + test_both_cast::(/*0x1.199999999999ap+0*/ f64::from_bits(0x3ff199999999999a), 1); + test_both_cast::( + /*-0x1.199999999999ap+0*/ f64::from_bits(0xbff199999999999a), + -1, + ); + test_both_cast::(5.0, 5); + test_both_cast::(5.9, 5); + test_both_cast::(-5.0, -5); + test_both_cast::(-5.9, -5); + test_both_cast::(4294967296.0, 4294967296); + test_both_cast::(-4294967296.0, -4294967296); + test_both_cast::(9223372036854774784.0, 9223372036854774784); + test_both_cast::(-9223372036854775808.0, -9223372036854775808); + // unrepresentable casts + assert_eq::(9223372036854775808.0f64 as i64, i64::MAX); + assert_eq::(-9223372036854777856.0f64 as i64, i64::MIN); + assert_eq::(f64::MAX as i64, i64::MAX); + assert_eq::(f64::MIN as i64, i64::MIN); + assert_eq::(f64::INFINITY as i64, i64::MAX); + assert_eq::(f64::NEG_INFINITY as i64, i64::MIN); + assert_eq::(f64::NAN as i64, 0); + assert_eq::((-f64::NAN) as i64, 0); + + // f64 -> u64 + test_both_cast::(0.0, 0); + test_both_cast::(-0.0, 0); + test_both_cast::(-0.99999999999, 0); + test_both_cast::(5.0, 5); + test_both_cast::(1e16, 10000000000000000); + test_both_cast::((u64::MAX - 1024) as f64, u64::MAX - 2047); // rounding loss + test_both_cast::(9223372036854775808.0, 9223372036854775808); + // unrepresentable casts + assert_eq::(-5.0f64 as u64, 0); + // rounds up and then becomes unrepresentable + assert_eq::((u64::MAX - 1023) as f64 as u64, u64::MAX); + assert_eq::(18446744073709551616.0f64 as u64, u64::MAX); + assert_eq::(f64::MAX as u64, u64::MAX); + assert_eq::(f64::MIN as u64, 0); + assert_eq::(f64::INFINITY as u64, u64::MAX); + assert_eq::(f64::NEG_INFINITY as u64, 0); + assert_eq::(f64::NAN as u64, 0); + assert_eq::((-f64::NAN) as u64, 0); + + // FIXME emscripten does not support i128 + #[cfg(not(target_os = "emscripten"))] + { + // f64 -> i128 + assert_eq::(f64::MAX as i128, i128::MAX); + assert_eq::(f64::MIN as i128, i128::MIN); + + // f64 -> u128 + assert_eq::(f64::MAX as u128, u128::MAX); + assert_eq::(f64::MIN as u128, 0); + } + + // int -> f32 + assert_eq::(127i8 as f32, 127.0); + assert_eq::(2147483647i32 as f32, 2147483648.0); + assert_eq::((-2147483648i32) as f32, -2147483648.0); + assert_eq::(1234567890i32 as f32, /*0x1.26580cp+30*/ f32::from_bits(0x4e932c06)); + assert_eq::(16777217i32 as f32, 16777216.0); + assert_eq::((-16777217i32) as f32, -16777216.0); + assert_eq::(16777219i32 as f32, 16777220.0); + assert_eq::((-16777219i32) as f32, -16777220.0); + assert_eq::( + 0x7fffff4000000001i64 as f32, + /*0x1.fffffep+62*/ f32::from_bits(0x5effffff), + ); + assert_eq::( + 0x8000004000000001u64 as i64 as f32, + /*-0x1.fffffep+62*/ f32::from_bits(0xdeffffff), + ); + assert_eq::( + 0x0020000020000001i64 as f32, + /*0x1.000002p+53*/ f32::from_bits(0x5a000001), + ); + assert_eq::( + 0xffdfffffdfffffffu64 as i64 as f32, + /*-0x1.000002p+53*/ f32::from_bits(0xda000001), + ); + // FIXME emscripten does not support i128 + #[cfg(not(target_os = "emscripten"))] + { + assert_eq::(i128::MIN as f32, -170141183460469231731687303715884105728.0f32); + assert_eq::(u128::MAX as f32, f32::INFINITY); // saturation + } + + // int -> f64 + assert_eq::(127i8 as f64, 127.0); + assert_eq::(i16::MIN as f64, -32768.0f64); + assert_eq::(2147483647i32 as f64, 2147483647.0); + assert_eq::(-2147483648i32 as f64, -2147483648.0); + assert_eq::(987654321i32 as f64, 987654321.0); + assert_eq::(9223372036854775807i64 as f64, 9223372036854775807.0); + assert_eq::(-9223372036854775808i64 as f64, -9223372036854775808.0); + assert_eq::(4669201609102990i64 as f64, 4669201609102990.0); // Feigenbaum (?) + assert_eq::(9007199254740993i64 as f64, 9007199254740992.0); + assert_eq::(-9007199254740993i64 as f64, -9007199254740992.0); + assert_eq::(9007199254740995i64 as f64, 9007199254740996.0); + assert_eq::(-9007199254740995i64 as f64, -9007199254740996.0); + // FIXME emscripten does not support i128 + #[cfg(not(target_os = "emscripten"))] + { + // even that fits... + assert_eq::(u128::MAX as f64, 340282366920938463463374607431768211455.0f64); + } + + // f32 -> f64 + assert_eq::((0.0f32 as f64).to_bits(), 0.0f64.to_bits()); + assert_eq::(((-0.0f32) as f64).to_bits(), (-0.0f64).to_bits()); + assert_eq::(5.0f32 as f64, 5.0f64); + assert_eq::( + /*0x1p-149*/ f32::from_bits(0x1) as f64, + /*0x1p-149*/ f64::from_bits(0x36a0000000000000), + ); + assert_eq::( + /*-0x1p-149*/ f32::from_bits(0x80000001) as f64, + /*-0x1p-149*/ f64::from_bits(0xb6a0000000000000), + ); + assert_eq::( + /*0x1.fffffep+127*/ f32::from_bits(0x7f7fffff) as f64, + /*0x1.fffffep+127*/ f64::from_bits(0x47efffffe0000000), + ); + assert_eq::( + /*-0x1.fffffep+127*/ (-f32::from_bits(0x7f7fffff)) as f64, + /*-0x1.fffffep+127*/ -f64::from_bits(0x47efffffe0000000), + ); + assert_eq::( + /*0x1p-119*/ f32::from_bits(0x4000000) as f64, + /*0x1p-119*/ f64::from_bits(0x3880000000000000), + ); + assert_eq::( + /*0x1.8f867ep+125*/ f32::from_bits(0x7e47c33f) as f64, + 6.6382536710104395e+37, + ); + assert_eq::(f32::INFINITY as f64, f64::INFINITY); + assert_eq::(f32::NEG_INFINITY as f64, f64::NEG_INFINITY); + + // f64 -> f32 + assert_eq::((0.0f64 as f32).to_bits(), 0.0f32.to_bits()); + assert_eq::(((-0.0f64) as f32).to_bits(), (-0.0f32).to_bits()); + assert_eq::(5.0f64 as f32, 5.0f32); + assert_eq::(/*0x0.0000000000001p-1022*/ f64::from_bits(0x1) as f32, 0.0); + assert_eq::(/*-0x0.0000000000001p-1022*/ (-f64::from_bits(0x1)) as f32, -0.0); + assert_eq::( + /*0x1.fffffe0000000p-127*/ f64::from_bits(0x380fffffe0000000) as f32, + /*0x1p-149*/ f32::from_bits(0x800000), + ); + assert_eq::( + /*0x1.4eae4f7024c7p+108*/ f64::from_bits(0x46b4eae4f7024c70) as f32, + /*0x1.4eae5p+108*/ f32::from_bits(0x75a75728), + ); + assert_eq::(f64::MAX as f32, f32::INFINITY); + assert_eq::(f64::MIN as f32, f32::NEG_INFINITY); + assert_eq::(f64::INFINITY as f32, f32::INFINITY); + assert_eq::(f64::NEG_INFINITY as f32, f32::NEG_INFINITY); +} + +pub fn run() { + casts(); // from miri's tests + + common_fptoi_tests!(f* -> i8 i16 i32 i64 u8 u16 u32 u64); + fptoui_tests!(f* -> u8 u16 u32 u64); + // FIXME emscripten does not support i128 + #[cfg(not(target_os = "emscripten"))] + { + common_fptoi_tests!(f* -> i128 u128); + fptoui_tests!(f* -> u128); + } + + // The following tests cover edge cases for some integer types. + + // # u8 + test!(254., f* -> u8, 254); + test!(256., f* -> u8, 255); + + // # i8 + test!(-127., f* -> i8, -127); + test!(-129., f* -> i8, -128); + test!(126., f* -> i8, 126); + test!(128., f* -> i8, 127); + + // # i32 + // -2147483648. is i32::MIN (exactly) + test!(-2147483648., f* -> i32, i32::MIN); + // 2147483648. is i32::MAX rounded up + test!(2147483648., f32 -> i32, 2147483647); + // With 24 significand bits, floats with magnitude in [2^30 + 1, 2^31] are rounded to + // multiples of 2^7. Therefore, nextDown(round(i32::MAX)) is 2^31 - 128: + test!(2147483520., f32 -> i32, 2147483520); + // Similarly, nextUp(i32::MIN) is i32::MIN + 2^8 and nextDown(i32::MIN) is i32::MIN - 2^7 + test!(-2147483904., f* -> i32, i32::MIN); + test!(-2147483520., f* -> i32, -2147483520); + + // # u32 + // round(MAX) and nextUp(round(MAX)) + test!(4294967040., f* -> u32, 4294967040); + test!(4294967296., f* -> u32, 4294967295); + + // # u128 + #[cfg(not(target_os = "emscripten"))] + { + // float->int: + test!(f32::MAX, f32 -> u128, 0xffffff00000000000000000000000000); + // nextDown(f32::MAX) = 2^128 - 2 * 2^104 + const SECOND_LARGEST_F32: f32 = 340282326356119256160033759537265639424.; + test!(SECOND_LARGEST_F32, f32 -> u128, 0xfffffe00000000000000000000000000); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/saturating-float-casts-wasm.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/saturating-float-casts-wasm.rs new file mode 100644 index 000000000000..3e3a4375ad47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/saturating-float-casts-wasm.rs @@ -0,0 +1,14 @@ +// run-pass +// only-wasm32 +// compile-flags: -Zmir-opt-level=0 -C target-feature=+nontrapping-fptoint + +#![feature(test, stmt_expr_attributes)] +#![deny(overflowing_literals)] + +#[path = "saturating-float-casts-impl.rs"] +mod implementation; + +pub fn main() { + implementation::run(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/saturating-float-casts.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/saturating-float-casts.rs new file mode 100644 index 000000000000..b0beae3621c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/saturating-float-casts.rs @@ -0,0 +1,13 @@ +// run-pass +// compile-flags:-Zmir-opt-level=0 + +#![feature(test, stmt_expr_attributes)] +#![deny(overflowing_literals)] + +#[path = "saturating-float-casts-impl.rs"] +mod implementation; + +pub fn main() { + implementation::run(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/shift-near-oflo.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/shift-near-oflo.rs new file mode 100644 index 000000000000..3f36d930fe5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/shift-near-oflo.rs @@ -0,0 +1,101 @@ +// run-pass +// compile-flags: -C debug-assertions + +// Check that we do *not* overflow on a number of edge cases. +// (compare with test/run-fail/overflowing-{lsh,rsh}*.rs) + +fn main() { + test_left_shift(); + test_right_shift(); +} + +pub static mut HACK: i32 = 0; + +// Work around constant-evaluation +// The point of this test is to exercise the code generated for execution at runtime, +// `id` can never be flagged as a const fn by future aggressive analyses... +// due to the modification of the static +#[inline(never)] +fn id(x: T) -> T { + unsafe { HACK += 1; } + x +} + +fn test_left_shift() { + // negative rhs can panic, but values in [0,N-1] are okay for iN + + macro_rules! tests { + ($iN:ty, $uN:ty, $max_rhs:expr, $expect_i:expr, $expect_u:expr) => { { + let x = (1 as $iN) << id(0); + assert_eq!(x, 1); + let x = (1 as $uN) << id(0); + assert_eq!(x, 1); + let x = (1 as $iN) << id($max_rhs); + assert_eq!(x, $expect_i); + let x = (1 as $uN) << id($max_rhs); + assert_eq!(x, $expect_u); + // high-order bits on LHS are silently discarded without panic. + let x = (3 as $iN) << id($max_rhs); + assert_eq!(x, $expect_i); + let x = (3 as $uN) << id($max_rhs); + assert_eq!(x, $expect_u); + } } + } + + let x = 1_i8 << id(0); + assert_eq!(x, 1); + let x = 1_u8 << id(0); + assert_eq!(x, 1); + let x = 1_i8 << id(7); + assert_eq!(x, std::i8::MIN); + let x = 1_u8 << id(7); + assert_eq!(x, 0x80); + // high-order bits on LHS are silently discarded without panic. + let x = 3_i8 << id(7); + assert_eq!(x, std::i8::MIN); + let x = 3_u8 << id(7); + assert_eq!(x, 0x80); + + // above is (approximately) expanded from: + tests!(i8, u8, 7, std::i8::MIN, 0x80_u8); + + tests!(i16, u16, 15, std::i16::MIN, 0x8000_u16); + tests!(i32, u32, 31, std::i32::MIN, 0x8000_0000_u32); + tests!(i64, u64, 63, std::i64::MIN, 0x8000_0000_0000_0000_u64); +} + +fn test_right_shift() { + // negative rhs can panic, but values in [0,N-1] are okay for iN + + macro_rules! tests { + ($iN:ty, $uN:ty, $max_rhs:expr, + $signbit_i:expr, $highbit_i:expr, $highbit_u:expr) => + { { + let x = (1 as $iN) >> id(0); + assert_eq!(x, 1); + let x = (1 as $uN) >> id(0); + assert_eq!(x, 1); + let x = ($highbit_i) >> id($max_rhs-1); + assert_eq!(x, 1); + let x = ($highbit_u) >> id($max_rhs); + assert_eq!(x, 1); + // sign-bit is carried by arithmetic right shift + let x = ($signbit_i) >> id($max_rhs); + assert_eq!(x, -1); + // low-order bits on LHS are silently discarded without panic. + let x = ($highbit_i + 1) >> id($max_rhs-1); + assert_eq!(x, 1); + let x = ($highbit_u + 1) >> id($max_rhs); + assert_eq!(x, 1); + let x = ($signbit_i + 1) >> id($max_rhs); + assert_eq!(x, -1); + } } + } + + tests!(i8, u8, 7, std::i8::MIN, 0x40_i8, 0x80_u8); + tests!(i16, u16, 15, std::i16::MIN, 0x4000_u16, 0x8000_u16); + tests!(i32, u32, 31, std::i32::MIN, 0x4000_0000_u32, 0x8000_0000_u32); + tests!(i64, u64, 63, std::i64::MIN, + 0x4000_0000_0000_0000_u64, 0x8000_0000_0000_0000_u64); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/shift-various-types.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/shift-various-types.rs new file mode 100644 index 000000000000..bd3e50dceabe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/shift-various-types.rs @@ -0,0 +1,49 @@ +// run-pass +// Test that we can do shifts by any integral type. + + +struct Panolpy { + i8: i8, + i16: i16, + i32: i32, + i64: i64, + isize: isize, + + u8: u8, + u16: u16, + u32: u32, + u64: u64, + usize: usize, +} + +fn foo(p: &Panolpy) { + assert_eq!(22 >> p.i8, 11); + assert_eq!(22 >> p.i16, 11); + assert_eq!(22 >> p.i32, 11); + assert_eq!(22 >> p.i64, 11); + assert_eq!(22 >> p.isize, 11); + + assert_eq!(22 >> p.u8, 11); + assert_eq!(22 >> p.u16, 11); + assert_eq!(22 >> p.u32, 11); + assert_eq!(22 >> p.u64, 11); + assert_eq!(22 >> p.usize, 11); +} + +fn main() { + let p = Panolpy { + i8: 1, + i16: 1, + i32: 1, + i64: 1, + isize: 1, + + u8: 1, + u16: 1, + u32: 1, + u64: 1, + usize: 1, + }; + foo(&p) +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/shift.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/shift.rs new file mode 100644 index 000000000000..d6f358df5c37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/shift.rs @@ -0,0 +1,77 @@ +// run-pass +#![allow(non_upper_case_globals)] +#![allow(overflowing_literals)] + +// Testing shifts for various combinations of integers +// Issue #1570 + + +pub fn main() { + test_misc(); + test_expr(); + test_const(); +} + +fn test_misc() { + assert_eq!(1 << 1 << 1 << 1 << 1 << 1, 32); +} + +fn test_expr() { + let v10 = 10 as usize; + let v4 = 4 as u8; + let v2 = 2 as u8; + assert_eq!(v10 >> v2 as usize, v2 as usize); + assert_eq!(v10 << v4 as usize, 160 as usize); + + let v10 = 10 as u8; + let v4 = 4 as usize; + let v2 = 2 as usize; + assert_eq!(v10 >> v2 as usize, v2 as u8); + assert_eq!(v10 << v4 as usize, 160 as u8); + + let v10 = 10 as isize; + let v4 = 4 as i8; + let v2 = 2 as i8; + assert_eq!(v10 >> v2 as usize, v2 as isize); + assert_eq!(v10 << v4 as usize, 160 as isize); + + let v10 = 10 as i8; + let v4 = 4 as isize; + let v2 = 2 as isize; + assert_eq!(v10 >> v2 as usize, v2 as i8); + assert_eq!(v10 << v4 as usize, 160 as i8); + + let v10 = 10 as usize; + let v4 = 4 as isize; + let v2 = 2 as isize; + assert_eq!(v10 >> v2 as usize, v2 as usize); + assert_eq!(v10 << v4 as usize, 160 as usize); +} + +fn test_const() { + static r1_1: usize = 10_usize >> 2_usize; + static r2_1: usize = 10_usize << 4_usize; + assert_eq!(r1_1, 2 as usize); + assert_eq!(r2_1, 160 as usize); + + static r1_2: u8 = 10u8 >> 2_usize; + static r2_2: u8 = 10u8 << 4_usize; + assert_eq!(r1_2, 2 as u8); + assert_eq!(r2_2, 160 as u8); + + static r1_3: isize = 10 >> 2_usize; + static r2_3: isize = 10 << 4_usize; + assert_eq!(r1_3, 2 as isize); + assert_eq!(r2_3, 160 as isize); + + static r1_4: i8 = 10i8 >> 2_usize; + static r2_4: i8 = 10i8 << 4_usize; + assert_eq!(r1_4, 2 as i8); + assert_eq!(r2_4, 160 as i8); + + static r1_5: usize = 10_usize >> 2_usize; + static r2_5: usize = 10_usize << 4_usize; + assert_eq!(r1_5, 2 as usize); + assert_eq!(r2_5, 160 as usize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/signed-shift-const-eval.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/signed-shift-const-eval.rs new file mode 100644 index 000000000000..d766dc62c1ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/signed-shift-const-eval.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(non_camel_case_types)] + + +enum test { thing = -5 >> 1_usize } +pub fn main() { + assert_eq!(test::thing as isize, -3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u128-as-f32.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u128-as-f32.rs new file mode 100644 index 000000000000..fbefa245cd0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u128-as-f32.rs @@ -0,0 +1,49 @@ +// run-pass + +#![feature(test)] +#![deny(overflowing_literals)] +extern crate test; + +use std::f32; +use std::u128; +use test::black_box; + +macro_rules! test { + ($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => ({ + { + const X: $src_ty = $val; + const Y: $dest_ty = X as $dest_ty; + assert_eq!(Y, $expected, + "const eval {} -> {}", stringify!($src_ty), stringify!($dest_ty)); + } + // black_box disables constant evaluation to test run-time conversions: + assert_eq!(black_box::<$src_ty>($val) as $dest_ty, $expected, + "run-time {} -> {}", stringify!($src_ty), stringify!($dest_ty)); + }); +} + +pub fn main() { + // nextDown(f32::MAX) = 2^128 - 2 * 2^104 + const SECOND_LARGEST_F32: f32 = 340282326356119256160033759537265639424.; + + // f32::MAX - 0.5 ULP and smaller should be rounded down + test!(0xfffffe00000000000000000000000000, u128 -> f32, SECOND_LARGEST_F32); + test!(0xfffffe7fffffffffffffffffffffffff, u128 -> f32, SECOND_LARGEST_F32); + test!(0xfffffe80000000000000000000000000, u128 -> f32, SECOND_LARGEST_F32); + // numbers within < 0.5 ULP of f32::MAX it should be rounded to f32::MAX + test!(0xfffffe80000000000000000000000001, u128 -> f32, f32::MAX); + test!(0xfffffeffffffffffffffffffffffffff, u128 -> f32, f32::MAX); + test!(0xffffff00000000000000000000000000, u128 -> f32, f32::MAX); + test!(0xffffff00000000000000000000000001, u128 -> f32, f32::MAX); + test!(0xffffff7fffffffffffffffffffffffff, u128 -> f32, f32::MAX); + // f32::MAX + 0.5 ULP and greater should be rounded to infinity + test!(0xffffff80000000000000000000000000, u128 -> f32, f32::INFINITY); + test!(0xffffff80000000f00000000000000000, u128 -> f32, f32::INFINITY); + test!(0xffffff87ffffffffffffffff00000001, u128 -> f32, f32::INFINITY); + + // u128->f64 should not be affected by the u128->f32 checks + test!(0xffffff80000000000000000000000000, u128 -> f64, + 340282356779733661637539395458142568448.0); + test!(u128::MAX, u128 -> f64, 340282366920938463463374607431768211455.0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u128.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u128.rs new file mode 100644 index 000000000000..3d0d354433b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u128.rs @@ -0,0 +1,120 @@ +// run-pass + +#![feature(test)] + +extern crate test; +use test::black_box as b; + +fn main() { + let x: u128 = 0xFFFF_FFFF_FFFF_FFFF__FFFF_FFFF_FFFF_FFFF; + assert_eq!(0, !x); + assert_eq!(0, !x); + let y: u128 = 0xFFFF_FFFF_FFFF_FFFF__FFFF_FFFF_FFFF_FFFE; + assert_eq!(!1, y); + assert_eq!(x, y | 1); + assert_eq!(0xFAFF_0000_FF8F_0000__FFFF_0000_FFFF_FFFE, + y & + 0xFAFF_0000_FF8F_0000__FFFF_0000_FFFF_FFFF); + let z: u128 = 0xABCD_EF; + assert_eq!(z * z, 0x734C_C2F2_A521); + assert_eq!(z * z * z * z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41); + assert_eq!(z + z + z + z, 0x2AF3_7BC); + let k: u128 = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210; + assert_eq!(k + k, 0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420); + assert_eq!(0, k - k); + assert_eq!(0x1234_5678_9ABC_DEFF_EDCB_A987_5A86_421, k - z); + assert_eq!(0x1000_0000_0000_0000_0000_0000_0000_000, + k - 0x234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!(0x6EF5_DE4C_D3BC_2AAA_3BB4_CC5D_D6EE_8, k / 42); + assert_eq!(0, k % 42); + assert_eq!(15, z % 42); + assert_eq!(0x169D_A8020_CEC18, k % 0x3ACB_FE49_FF24_AC); + assert_eq!(0x91A2_B3C4_D5E6_F7, k >> 65); + assert_eq!(0xFDB9_7530_ECA8_6420_0000_0000_0000_0000, k << 65); + assert!(k > z); + assert!(y > k); + assert!(y < x); + assert_eq!(x as u64, !0); + assert_eq!(z as u64, 0xABCD_EF); + assert_eq!(k as u64, 0xFEDC_BA98_7654_3210); + assert_eq!(k as i128, 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210); + assert_eq!((z as f64) as u128, z); + assert_eq!((z as f32) as u128, z); + assert_eq!((z as f64 * 16.0) as u128, z * 16); + assert_eq!((z as f32 * 16.0) as u128, z * 16); + let l :u128 = 432 << 100; + assert_eq!((l as f32) as u128, l); + assert_eq!((l as f64) as u128, l); + // formatting + let j: u128 = 1 << 67; + assert_eq!("147573952589676412928", format!("{}", j)); + assert_eq!("80000000000000000", format!("{:x}", j)); + assert_eq!("20000000000000000000000", format!("{:o}", j)); + assert_eq!("10000000000000000000000000000000000000000000000000000000000000000000", + format!("{:b}", j)); + assert_eq!("340282366920938463463374607431768211455", + format!("{}", u128::MAX)); + assert_eq!("147573952589676412928", format!("{:?}", j)); + // common traits + assert_eq!(x, b(x.clone())); + // overflow checks + assert_eq!((z).checked_mul(z), Some(0x734C_C2F2_A521)); + assert_eq!((k).checked_mul(k), None); + let l: u128 = b(u128::MAX - 10); + let o: u128 = b(17); + assert_eq!(l.checked_add(b(11)), None); + assert_eq!(l.checked_sub(l), Some(0)); + assert_eq!(o.checked_sub(b(18)), None); + assert_eq!(b(1u128).checked_shl(b(127)), Some(1 << 127)); + assert_eq!(o.checked_shl(b(128)), None); + + // Test cases for all udivmodti4 branches. + // case "0X/0X" + assert_eq!(b(0x69545bd57727c050_u128) / + b(0x3283527a3350d88c_u128), + 2u128); + // case "0X/KX" + assert_eq!(b(0x0_8003c9c50b473ae6_u128) / + b(0x1_283e8838c30fa8f4_u128), + 0u128); + // case "K0/K0" + assert_eq!(b(0xc43f42a207978720_u128 << 64) / + b(0x098e62b74c23cf1a_u128 << 64), + 20u128); + // case "KK/K0" for power-of-two D. + assert_eq!(b(0xa9008fb6c9d81e42_0e25730562a601c8_u128) / + b(1u128 << 120), + 169u128); + // case "KK/K0" with N >= D (https://github.com/rust-lang/rust/issues/41228). + assert_eq!(b(0xe4d26e59f0640328_06da5b06efe83a41_u128) / + b(0x330fcb030ea4447c_u128 << 64), + 4u128); + assert_eq!(b(3u128 << 64 | 1) / + b(3u128 << 64), + 1u128); + // case "KK/K0" with N < D. + assert_eq!(b(0x6655c9fb66ca2884_e2d1dfd470158c62_u128) / + b(0xb35b667cab7e355b_u128 << 64), + 0u128); + // case "KX/0K" for power-of-two D. + assert_eq!(b(0x3e49dd84feb2df59_7b2f97d93a253969_u128) / + b(1u128 << 4), + 0x03e49dd84feb2df5_97b2f97d93a25396_u128); + // case "KX/0K" in general. + assert_eq!(b(0x299692b3a1dae5bd_6162e6f489d2620e_u128) / + b(0x900b6f027571d6f7_u128), + 0x49e95f54b0442578_u128); + // case "KX/KK" with N >= D. + assert_eq!(b(0xc7b889180b67b07d_bc1a3c88783d35b5_u128) / + b(0x1d7e69f53160b9e2_60074771e852f244_u128), + 6u128); + // case "KX/KK" with N < D. + assert_eq!(b(0x679289ac23bb334f_36144401cf882172_u128) / + b(0x7b0b271b64865f05_f54a7b72746c062f_u128), + 0u128); + + // iter-arithmetic traits + assert_eq!(10u128, [1u128, 2, 3, 4].iter().sum()); + assert_eq!(24u128, [1u128, 2, 3, 4].iter().product()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u32-decr.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u32-decr.rs new file mode 100644 index 000000000000..68ed0a81bde5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u32-decr.rs @@ -0,0 +1,11 @@ +// run-pass + + + + +pub fn main() { + let mut word: u32 = 200000; + word = word - 1; + assert_eq!(word, 199999); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u8-incr-decr.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u8-incr-decr.rs new file mode 100644 index 000000000000..423ffc421c8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u8-incr-decr.rs @@ -0,0 +1,20 @@ +// run-pass + + + + +// These constants were chosen because they aren't used anywhere +// in the rest of the generated code so they're easily grep-able. + +pub fn main() { + let mut x: u8 = 19; // 0x13 + + let mut y: u8 = 35; // 0x23 + + x = x + 7; // 0x7 + + y = y - 9; // 0x9 + + assert_eq!(x, y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u8-incr.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u8-incr.rs new file mode 100644 index 000000000000..43b5044d5e93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/u8-incr.rs @@ -0,0 +1,16 @@ +// run-pass + + + + +pub fn main() { + let mut x: u8 = 12; + let y: u8 = 12; + x = x + 1; + x = x - 1; + assert_eq!(x, y); + // x = 14; + // x = x + 1; + +} + diff --git a/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/uint.rs b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/uint.rs new file mode 100644 index 000000000000..e18be895c37d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numbers-arithmetic/uint.rs @@ -0,0 +1,8 @@ +// run-pass + + + +// pretty-expanded FIXME #23616 + +pub fn main() { let _x: usize = 10 as usize; } + diff --git a/gcc/testsuite/rust/rustc/ui/numeric/const-scope.rs b/gcc/testsuite/rust/rustc/ui/numeric/const-scope.rs new file mode 100644 index 000000000000..1c164c1e86bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numeric/const-scope.rs @@ -0,0 +1,13 @@ +const C: i32 = 1i8; // { dg-error ".E0308." "" { target *-*-* } } +const D: i8 = C; // { dg-error ".E0308." "" { target *-*-* } } + +const fn foo() { + let c: i32 = 1i8; // { dg-error ".E0308." "" { target *-*-* } } + let d: i8 = c; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { + let c: i32 = 1i8; // { dg-error ".E0308." "" { target *-*-* } } + let d: i8 = c; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numeric/len.rs b/gcc/testsuite/rust/rustc/ui/numeric/len.rs new file mode 100644 index 000000000000..fec0bfaec66c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numeric/len.rs @@ -0,0 +1,9 @@ +fn main() { + let array = [1, 2, 3]; + test(array.len()); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn test(length: u32) { + println!("{}", length); +} + diff --git a/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-2.rs b/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-2.rs new file mode 100644 index 000000000000..966815ec14fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-2.rs @@ -0,0 +1,12 @@ +fn foo() -> i32 { + 4 +} +fn main() { + let x: u16 = foo(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let y: i64 = x + x; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let z: i32 = x + x; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-binop.rs b/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-binop.rs new file mode 100644 index 000000000000..97d8d3d92298 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-binop.rs @@ -0,0 +1,321 @@ +// run-rustfix + +// The `try_into` suggestion doesn't include this, but we do suggest it after applying it +use std::convert::TryInto; + +#[allow(unused_must_use)] +fn main() { + let x_usize: usize = 1; + let x_u128: u128 = 2; + let x_u64: u64 = 3; + let x_u32: u32 = 4; + let x_u16: u16 = 5; + let x_u8: u8 = 6; + let x_isize: isize = 7; + let x_i64: i64 = 8; + let x_i32: i32 = 9; + let x_i16: i16 = 10; + let x_i8: i8 = 11; + let x_i128: i128 = 12; + + /* u<->u */ + { + x_u8 > x_u16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > x_u32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > x_u64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > x_u128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > x_usize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_u16 > x_u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > x_u32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > x_u64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > x_u128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > x_usize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_u32 > x_u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > x_u16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > x_u64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > x_u128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > x_usize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_u64 > x_u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > x_u16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > x_u32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > x_u128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > x_usize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_u128 > x_u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > x_u16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > x_u32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > x_u64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > x_usize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_usize > x_u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_usize > x_u16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_usize > x_u32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_usize > x_u64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_usize > x_u128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } + + /* i<->i */ + { + x_i8 > x_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i8 > x_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i8 > x_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i8 > x_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i8 > x_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_i16 > x_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i16 > x_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i16 > x_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i16 > x_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i16 > x_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_i32 > x_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i32 > x_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i32 > x_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i32 > x_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i32 > x_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_i64 > x_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i64 > x_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i64 > x_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i64 > x_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i64 > x_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_i128 > x_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i128 > x_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i128 > x_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i128 > x_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i128 > x_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_isize > x_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_isize > x_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_isize > x_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_isize > x_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_isize > x_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } + + /* u<->i */ + { + x_u8 > x_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > x_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > x_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > x_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > x_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > x_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_u16 > x_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > x_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > x_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > x_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > x_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > x_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_u32 > x_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > x_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > x_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > x_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > x_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > x_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_u64 > x_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > x_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > x_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > x_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > x_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > x_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_u128 > x_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > x_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > x_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > x_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > x_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > x_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_usize > x_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_usize > x_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_usize > x_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_usize > x_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_usize > x_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_usize > x_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } + + /* i<->u */ + { + x_i8 > x_u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i8 > x_u16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i8 > x_u32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i8 > x_u64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i8 > x_u128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i8 > x_usize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_i16 > x_u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i16 > x_u16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i16 > x_u32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i16 > x_u64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i16 > x_u128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i16 > x_usize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_i32 > x_u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i32 > x_u16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i32 > x_u32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i32 > x_u64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i32 > x_u128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i32 > x_usize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_i64 > x_u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i64 > x_u16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i64 > x_u32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i64 > x_u64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i64 > x_u128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i64 > x_usize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_i128 > x_u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i128 > x_u16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i128 > x_u32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i128 > x_u64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i128 > x_u128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_i128 > x_usize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_isize > x_u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_isize > x_u16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_isize > x_u32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_isize > x_u64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_isize > x_u128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_isize > x_usize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-no-fix.rs b/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-no-fix.rs new file mode 100644 index 000000000000..1fd16d2778aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-no-fix.rs @@ -0,0 +1,88 @@ +#[allow(unused_must_use)] +fn main() { + let x_usize: usize = 1; + let x_u128: u128 = 2; + let x_u64: u64 = 3; + let x_u32: u32 = 4; + let x_u16: u16 = 5; + let x_u8: u8 = 6; + + x_usize > -1_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > -1_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > -1_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > -1_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > -1_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > -1_isize; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_usize > -1_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > -1_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > -1_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > -1_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > -1_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > -1_i128; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_usize > -1_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > -1_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > -1_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > -1_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > -1_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > -1_i64; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_usize > -1_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > -1_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > -1_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > -1_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > -1_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > -1_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_usize > -1_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > -1_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > -1_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > -1_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > -1_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > -1_i16; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + x_usize > -1_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u128 > -1_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u64 > -1_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u32 > -1_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u16 > -1_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + x_u8 > -1_i8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-without-suggestion.rs b/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-without-suggestion.rs new file mode 100644 index 000000000000..23b700f8a586 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast-without-suggestion.rs @@ -0,0 +1,39 @@ +fn foo(_x: N) {} + +fn main() { + let x_usize: usize = 1; + let x_u64: u64 = 2; + let x_u32: u32 = 3; + let x_u16: u16 = 4; + let x_u8: u8 = 5; + let x_isize: isize = 6; + let x_i64: i64 = 7; + let x_i32: i32 = 8; + let x_i16: i16 = 9; + let x_i8: i8 = 10; + let x_f64: f64 = 11.0; + let x_f32: f32 = 12.0; + + foo::(x_f64); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f32); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f64); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f32); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f64); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f32); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f64); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f32); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f64); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f32); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f64); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f32); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f64); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f32); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f64); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f32); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f64); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f32); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f64); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f32); // { dg-error ".E0308." "" { target *-*-* } } + foo::(x_f64); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast.rs b/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast.rs new file mode 100644 index 000000000000..e7d72415cb14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numeric/numeric-cast.rs @@ -0,0 +1,294 @@ +// run-rustfix + +// The `try_into` suggestion doesn't include this, but we do suggest it after applying it +use std::convert::TryInto; + +fn foo(_x: N) {} + +fn main() { + let x_usize: usize = 1; + let x_u64: u64 = 2; + let x_u32: u32 = 3; + let x_u16: u16 = 4; + let x_u8: u8 = 5; + let x_isize: isize = 6; + let x_i64: i64 = 7; + let x_i32: i32 = 8; + let x_i16: i16 = 9; + let x_i8: i8 = 10; + let x_f64: f64 = 11.0; + let x_f32: f32 = 12.0; + + foo::(x_usize); + foo::(x_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + // foo::(x_f64); + // foo::(x_f32); + + foo::(x_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_isize); + foo::(x_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + // foo::(x_f64); + // foo::(x_f32); + + foo::(x_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u64); + foo::(x_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + // foo::(x_f64); + // foo::(x_f32); + + foo::(x_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i64); + foo::(x_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + // foo::(x_f64); + // foo::(x_f32); + + foo::(x_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u32); + foo::(x_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + // foo::(x_f64); + // foo::(x_f32); + + foo::(x_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i32); + foo::(x_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + // foo::(x_f64); + // foo::(x_f32); + + foo::(x_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u16); + foo::(x_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + // foo::(x_f64); + // foo::(x_f32); + + foo::(x_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i16); + foo::(x_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + // foo::(x_f64); + // foo::(x_f32); + + foo::(x_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u8); + foo::(x_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + // foo::(x_f64); + // foo::(x_f32); + + foo::(x_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i8); + // foo::(x_f64); + // foo::(x_f32); + + foo::(x_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_f64); + foo::(x_f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + foo::(x_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(x_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + // foo::(x_f64); + foo::(x_f32); + + foo::(x_u8 as u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(-x_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numeric/numeric-fields.rs b/gcc/testsuite/rust/rustc/ui/numeric/numeric-fields.rs new file mode 100644 index 000000000000..71dc1e472887 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numeric/numeric-fields.rs @@ -0,0 +1,11 @@ +struct S(u8, u16); + +fn main() { + let s = S{0b1: 10, 0: 11}; +// { dg-error ".E0560." "" { target *-*-* } .-1 } + match s { + S{0: a, 0x1: b, ..} => {} +// { dg-error ".E0026." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/numeric/numeric-suffix.rs b/gcc/testsuite/rust/rustc/ui/numeric/numeric-suffix.rs new file mode 100644 index 000000000000..c6188cf9a51a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/numeric/numeric-suffix.rs @@ -0,0 +1,299 @@ +// run-rustfix + +fn foo(_x: N) {} + +fn main() { + foo::(42_usize); + foo::(42_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + foo::(42_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_isize); + foo::(42_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + foo::(42_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u64); + foo::(42_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + foo::(42_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i64); + foo::(42_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + foo::(42_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u32); + foo::(42_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + foo::(42_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i32); + foo::(42_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + foo::(42_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u16); + foo::(42_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + foo::(42_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i16); + foo::(42_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + foo::(42_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u8); + foo::(42_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + foo::(42_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i8); + foo::(42.0_f64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + foo::(42_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f64); + foo::(42.0_f32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + foo::(42_usize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_u8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_isize); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f64); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(42.0_f32); + + foo::(42_u8 as u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo::(-42_i8); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-does-not-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/object-does-not-impl-trait.rs new file mode 100644 index 000000000000..66bdddc9cfd5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-does-not-impl-trait.rs @@ -0,0 +1,9 @@ +// Test that an object type `Box` is not considered to implement the +// trait `Foo`. Issue #5087. + +trait Foo {} +fn take_foo(f: F) {} +fn take_object(f: Box) { take_foo(f); } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime-default-default-to-static.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime-default-default-to-static.rs new file mode 100644 index 000000000000..1bc76484747a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime-default-default-to-static.rs @@ -0,0 +1,36 @@ +// run-pass +// Test that `Box` is equivalent to `Box`, both in +// fields and fn arguments. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +trait Test { + fn foo(&self) { } +} + +struct SomeStruct { + t: Box, + u: Box, +} + +fn a(t: Box, mut ss: SomeStruct) { + ss.t = t; +} + +fn b(t: Box, mut ss: SomeStruct) { + ss.t = t; +} + +fn c(t: Box, mut ss: SomeStruct) { + ss.u = t; +} + +fn d(t: Box, mut ss: SomeStruct) { + ss.u = t; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime-default-from-rptr-box.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime-default-from-rptr-box.rs new file mode 100644 index 000000000000..ef7bec2f3a22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime-default-from-rptr-box.rs @@ -0,0 +1,34 @@ +// run-pass +// Test that the lifetime from the enclosing `&` is "inherited" +// through the `Box` struct. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +trait Test { + fn foo(&self) { } +} + +struct SomeStruct<'a> { + t: &'a Box, + u: &'a Box, +} + +fn a<'a>(t: &'a Box, mut ss: SomeStruct<'a>) { + ss.t = t; +} + +fn b<'a>(t: &'a Box, mut ss: SomeStruct<'a>) { + ss.u = t; +} + +// see also compile-fail/object-lifetime-default-from-rptr-box-error.rs + +fn d<'a>(t: &'a Box, mut ss: SomeStruct<'a>) { + ss.u = t; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime-default-from-rptr-mut.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime-default-from-rptr-mut.rs new file mode 100644 index 000000000000..5072bf7e1e6a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime-default-from-rptr-mut.rs @@ -0,0 +1,37 @@ +// run-pass +// Test that the lifetime of the enclosing `&` is used for the object +// lifetime bound. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +trait Test { + fn foo(&self) { } +} + +struct SomeStruct<'a> { + t: &'a mut dyn Test, + u: &'a mut (dyn Test+'a), +} + +fn a<'a>(t: &'a mut dyn Test, mut ss: SomeStruct<'a>) { + ss.t = t; +} + +fn b<'a>(t: &'a mut dyn Test, mut ss: SomeStruct<'a>) { + ss.u = t; +} + +fn c<'a>(t: &'a mut (dyn Test+'a), mut ss: SomeStruct<'a>) { + ss.t = t; +} + +fn d<'a>(t: &'a mut (dyn Test+'a), mut ss: SomeStruct<'a>) { + ss.u = t; +} + + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime-default-from-rptr.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime-default-from-rptr.rs new file mode 100644 index 000000000000..831bd3da2693 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime-default-from-rptr.rs @@ -0,0 +1,43 @@ +// run-pass +// Test that the lifetime of the enclosing `&` is used for the object +// lifetime bound. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +use std::fmt::Display; + +trait Test { + fn foo(&self) { } +} + +struct SomeStruct<'a> { + t: &'a dyn Test, + u: &'a (dyn Test+'a), +} + +fn a<'a>(t: &'a dyn Test, mut ss: SomeStruct<'a>) { + ss.t = t; +} + +fn b<'a>(t: &'a dyn Test, mut ss: SomeStruct<'a>) { + ss.u = t; +} + +fn c<'a>(t: &'a (dyn Test+'a), mut ss: SomeStruct<'a>) { + ss.t = t; +} + +fn d<'a>(t: &'a (dyn Test+'a), mut ss: SomeStruct<'a>) { + ss.u = t; +} + +fn e<'a>(_: &'a (dyn Display+'static)) {} + +fn main() { + // Inside a function body, we can just infer both + // lifetimes, to allow &'tmp (Display+'static). + e(&0 as &dyn Display); +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-ambiguous.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-ambiguous.rs new file mode 100644 index 000000000000..d2a83738fa2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-ambiguous.rs @@ -0,0 +1,49 @@ +// Test that if a struct declares multiple region bounds for a given +// type parameter, an explicit lifetime bound is required on object +// lifetimes within. + +#![allow(dead_code)] + +trait Test { + fn foo(&self) { } +} + +struct Ref0 { + r: *mut T +} + +struct Ref1<'a,T:'a+?Sized> { + r: &'a T +} + +struct Ref2<'a,'b:'a,T:'a+'b+?Sized> { + r: &'a &'b T +} + +fn a<'a,'b>(t: Ref2<'a,'b, dyn Test>) { +// { dg-error ".E0228." "" { target *-*-* } .-1 } +} + +fn b(t: Ref2) { +// { dg-error ".E0228." "" { target *-*-* } .-1 } +} + +fn c(t: Ref2<&dyn Test>) { + // In this case, the &'a overrides. +} + +fn d(t: Ref2>) { + // In this case, the lifetime parameter from the Ref1 overrides. +} + +fn e(t: Ref2>) { + // In this case, Ref2 is ambiguous, but Ref0 overrides with 'static. +} + +fn f(t: &Ref2) { +// { dg-error ".E0228." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs new file mode 100644 index 000000000000..57d2f0689dac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs @@ -0,0 +1,28 @@ +// Test that `dyn Bar` uses `'static` as the default object +// lifetime bound for the type `XX`. + +trait Foo<'a> { + type Item: ?Sized; + + fn item(&self) -> Box { panic!() } +} + +trait Bar { } + +impl Foo<'_> for T { + type Item = dyn Bar; +} + +fn is_static(_: T) where T: 'static { } + +// Here, we should default to `dyn Bar + 'static`, but the current +// code forces us into a conservative, hacky path. +fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() } +// { dg-error ".E0228." "" { target *-*-* } .-1 } + +fn main() { + let s = format!("foo"); + let r = bar(&s); + is_static(r.item()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs new file mode 100644 index 000000000000..2b406edb9944 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs @@ -0,0 +1,31 @@ +// Test that `dyn Bar` uses `'static` as the default object +// lifetime bound for the type `XX`. + +trait Foo<'a> { + type Item: 'a + ?Sized; + + fn item(&self) -> Box { panic!() } +} + +trait Bar { } + +impl Foo<'_> for T { + type Item = dyn Bar; +} + +fn is_static(_: T) where T: 'static { } + +// Here, we default to `dyn Bar + 'a`. Or, we *should*, but the +// current code forces us into a conservative, hacky path. +fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() } +// { dg-error ".E0228." "" { target *-*-* } .-1 } + +fn main() { + let s = format!("foo"); + let r = bar(&s); + + // If it weren't for the conservative path above, we'd expect an + // error here. + is_static(r.item()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs new file mode 100644 index 000000000000..42cb6777645f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs @@ -0,0 +1,24 @@ +// Test that `dyn Bar` uses `'static` as the default object +// lifetime bound for the type `XX`. + +trait Foo<'a> { + type Item: ?Sized; + + fn item(&self) -> Box { panic!() } +} + +trait Bar { } + +fn is_static(_: T) where T: 'static { } + +// Here, we should default to `dyn Bar + 'static`, but the current +// code forces us into a conservative, hacky path. +fn bar(x: &str) -> &dyn Foo { &() } +// { dg-error ".E0228." "" { target *-*-* } .-1 } + +fn main() { + let s = format!("foo"); + let r = bar(&s); + is_static(r.item()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-static.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-static.rs new file mode 100644 index 000000000000..68c980036a07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-dyn-binding-static.rs @@ -0,0 +1,29 @@ +// Test that `dyn Bar` uses `'static` as the default object +// lifetime bound for the type `XX`. +// +// check-pass + +trait Foo { + type Item: ?Sized; + + fn item(&self) -> Box { panic!() } +} + +trait Bar { } + +impl Foo for T { + type Item = dyn Bar; +} + +fn is_static(_: T) where T: 'static { } + +// Here, we default to `dyn Bar + 'static`, and not `&'x dyn Foo`. +fn bar(x: &str) -> &dyn Foo { &() } + +fn main() { + let s = format!("foo"); + let r = bar(&s); + is_static(r.item()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-elision.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-elision.rs new file mode 100644 index 000000000000..831a15bd60a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-elision.rs @@ -0,0 +1,78 @@ +// Test various cases where the old rules under lifetime elision +// yield slightly different results than the new rules. + +#![allow(dead_code)] + +trait SomeTrait { + fn dummy(&self) { } +} + +struct SomeStruct<'a> { + r: Box +} + +fn deref(ss: &T) -> T { + // produces the type of a deref without worrying about whether a + // move out would actually be legal + loop { } +} + +fn load0<'a>(ss: &'a Box) -> Box { + // Under old rules, the fully elaborated types of input/output were: + // + // for<'a,'b> fn(&'a Box) -> Box + // + // Under new rules the result is: + // + // for<'a> fn(&'a Box) -> Box + // + // Therefore, no type error. + + deref(ss) +} + +fn load1(ss: &dyn SomeTrait) -> &dyn SomeTrait { + // Under old rules, the fully elaborated types of input/output were: + // + // for<'a,'b> fn(&'a (SomeTrait+'b)) -> &'a (SomeTrait+'a) + // + // Under new rules the result is: + // + // for<'a> fn(&'a (SomeTrait+'a)) -> &'a (SomeTrait+'a) + // + // In both cases, returning `ss` is legal. + + ss +} + +fn load2<'a>(ss: &'a dyn SomeTrait) -> &dyn SomeTrait { + // Same as `load1` but with an explicit name thrown in for fun. + + ss +} + +fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait { + // Under old rules, the fully elaborated types of input/output were: + // + // for<'a,'b,'c>fn(&'a (SomeTrait+'c)) -> &'b (SomeTrait+'a) + // + // Based on the input/output types, the compiler could infer that + // 'c : 'a + // 'b : 'a + // must hold, and therefore it permitted `&'a (Sometrait+'c)` to be + // coerced to `&'b (SomeTrait+'a)`. + // + // Under the newer defaults, though, we get: + // + // for<'a,'b> fn(&'a (SomeTrait+'a)) -> &'b (SomeTrait+'b) + // + // which fails to type check. + + ss +// { dg-error ".E0495." "" { target *-*-* } .-1 } +// { dg-error ".E0495." "" { target *-*-* } .-2 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-from-box-error.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-from-box-error.rs new file mode 100644 index 000000000000..06c99e7a33da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-from-box-error.rs @@ -0,0 +1,36 @@ +// Test various cases where the defaults should lead to errors being +// reported. + +#![allow(dead_code)] + +trait SomeTrait { + fn dummy(&self) { } +} + +struct SomeStruct<'a> { + r: Box +} + +fn load(ss: &mut SomeStruct) -> Box { + // `Box` defaults to a `'static` bound, so this return + // is illegal. + + ss.r // { dg-error ".E0759." "" { target *-*-* } } +} + +fn store(ss: &mut SomeStruct, b: Box) { + // No error: b is bounded by 'static which outlives the + // (anonymous) lifetime on the struct. + + ss.r = b; +} + +fn store1<'b>(ss: &mut SomeStruct, b: Box) { + // Here we override the lifetimes explicitly, and so naturally we get an error. + + ss.r = b; // { dg-error ".E0621." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.rs new file mode 100644 index 000000000000..95654411b109 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.rs @@ -0,0 +1,20 @@ +// Test that the lifetime from the enclosing `&` is "inherited" +// through the `Box` struct. + +#![allow(dead_code)] + +trait Test { + fn foo(&self) { } +} + +struct SomeStruct<'a> { + t: &'a Box, +} + +fn c<'a>(t: &'a Box, mut ss: SomeStruct<'a>) { + ss.t = t; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.rs new file mode 100644 index 000000000000..dc1b145925ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.rs @@ -0,0 +1,26 @@ +// Test that the lifetime from the enclosing `&` is "inherited" +// through the `MyBox` struct. + +#![allow(dead_code)] +#![feature(rustc_error)] + +trait Test { + fn foo(&self) { } +} + +struct SomeStruct<'a> { + t: &'a MyBox, + u: &'a MyBox, +} + +struct MyBox { + b: Box +} + +fn c<'a>(t: &'a MyBox, mut ss: SomeStruct<'a>) { + ss.t = t; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-mybox.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-mybox.rs new file mode 100644 index 000000000000..2b13df4c108c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default-mybox.rs @@ -0,0 +1,36 @@ +// Test a "pass-through" object-lifetime-default that produces errors. + +#![allow(dead_code)] + +trait SomeTrait { + fn dummy(&self) { } +} + +struct MyBox { + r: Box +} + +fn deref(ss: &T) -> T { + // produces the type of a deref without worrying about whether a + // move out would actually be legal + loop { } +} + +fn load0(ss: &MyBox) -> MyBox { + deref(ss) +} + +fn load1<'a,'b>(a: &'a MyBox, + b: &'b MyBox) + -> &'b MyBox +{ + a // { dg-error ".E0623." "" { target *-*-* } } +} + +fn load2<'a>(ss: &MyBox) -> MyBox { + load0(ss) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default.rs b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default.rs new file mode 100644 index 000000000000..8f1598a383e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-lifetime/object-lifetime-default.rs @@ -0,0 +1,27 @@ +// ignore-compare-mode-nll + +#![feature(rustc_attrs)] + +#[rustc_object_lifetime_default] +struct A(T); // { dg-error "" "" { target *-*-* } } + +#[rustc_object_lifetime_default] +struct B<'a,T>(&'a (), T); // { dg-error "" "" { target *-*-* } } + +#[rustc_object_lifetime_default] +struct C<'a,T:'a>(&'a T); // { dg-error "" "" { target *-*-* } } + +#[rustc_object_lifetime_default] +struct D<'a,'b,T:'a+'b>(&'a T, &'b T); // { dg-error "" "" { target *-*-* } } + +#[rustc_object_lifetime_default] +struct E<'a,'b:'a,T:'b>(&'a T, &'b T); // { dg-error "" "" { target *-*-* } } + +#[rustc_object_lifetime_default] +struct F<'a,'b,T:'a,U:'b>(&'a T, &'b U); // { dg-error "" "" { target *-*-* } } + +#[rustc_object_lifetime_default] +struct G<'a,'b,T:'a,U:'a+'b>(&'a T, &'b U); // { dg-error "" "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/object-method-numbering.rs b/gcc/testsuite/rust/rustc/ui/object-method-numbering.rs new file mode 100644 index 000000000000..e49c8b8e29c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-method-numbering.rs @@ -0,0 +1,29 @@ +// 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/gcc/testsuite/rust/rustc/ui/object-pointer-types.rs b/gcc/testsuite/rust/rustc/ui/object-pointer-types.rs new file mode 100644 index 000000000000..c775c1a0a11e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-pointer-types.rs @@ -0,0 +1,31 @@ +trait Foo { + fn borrowed(&self); + fn borrowed_mut(&mut self); + + fn owned(self: Box); +} + +fn borrowed_receiver(x: &dyn Foo) { + x.borrowed(); + x.borrowed_mut(); // See [1] + x.owned(); // { dg-error ".E0599." "" { target *-*-* } } +} + +fn borrowed_mut_receiver(x: &mut dyn Foo) { + x.borrowed(); + x.borrowed_mut(); + x.owned(); // { dg-error ".E0599." "" { target *-*-* } } +} + +fn owned_receiver(x: Box) { + x.borrowed(); + x.borrowed_mut(); // See [1] + x.managed(); // { dg-error ".E0599." "" { target *-*-* } } + x.owned(); +} + +fn main() {} + +// [1]: These cases are illegal, but the error is not detected +// until borrowck, so see the test borrowck-object-mutability.rs + diff --git a/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-associated-consts.rs b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-associated-consts.rs new file mode 100644 index 000000000000..98005cee4a62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-associated-consts.rs @@ -0,0 +1,20 @@ +// Check that we correctly prevent users from making trait objects +// from traits with associated consts. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + +trait Bar { + const X: usize; +} + +fn make_bar(t: &T) -> &dyn Bar { +// { dg-error "" "" { target *-*-* } .-1 } + t +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-bounds.rs b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-bounds.rs new file mode 100644 index 000000000000..1caef956bbc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-bounds.rs @@ -0,0 +1,13 @@ +// Traits with bounds mentioning `Self` are not object safe + +trait X { + type U: PartialEq; +} + +fn f() -> Box> { +// { dg-error ".E0038." "" { target *-*-* } .-1 } + loop {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-by-value-self-use.rs b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-by-value-self-use.rs new file mode 100644 index 000000000000..91f9ff086b01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-by-value-self-use.rs @@ -0,0 +1,19 @@ +// Check that while a trait with by-value self is object-safe, we +// can't actually invoke it from an object (yet...?). + +#![feature(rustc_attrs)] + +trait Bar { + fn bar(self); +} + +trait Baz { + fn baz(self: Self); +} + +fn use_bar(t: Box) { + t.bar() // { dg-error ".E0161." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-by-value-self.rs b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-by-value-self.rs new file mode 100644 index 000000000000..4256eca89aca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-by-value-self.rs @@ -0,0 +1,47 @@ +// Check that a trait with by-value self is considered object-safe. + +// build-pass (FIXME(62277): could be check-pass?) +#![allow(dead_code)] +#![allow(trivial_casts)] + +trait Bar { + fn bar(self); +} + +trait Baz { + fn baz(self: Self); +} + +trait Quux { + // Legal because of the where clause: + fn baz(self: Self) where Self : Sized; +} + +fn make_bar(t: &T) -> &dyn Bar { + t // legal +} + +fn make_bar_explicit(t: &T) -> &dyn Bar { + t as &dyn Bar // legal +} + +fn make_baz(t: &T) -> &dyn Baz { + t // legal +} + +fn make_baz_explicit(t: &T) -> &dyn Baz { + t as &dyn Baz // legal +} + +fn make_quux(t: &T) -> &dyn Quux { + t +} + +fn make_quux_explicit(t: &T) -> &dyn Quux { + t as &dyn Quux +} + + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-generics.rs b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-generics.rs new file mode 100644 index 000000000000..3ddc8b1d19e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-generics.rs @@ -0,0 +1,40 @@ +// Check that we correctly prevent users from making trait objects +// from traits with generic methods, unless `where Self : Sized` is +// present. +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + + +trait Bar { + fn bar(&self, t: T); +} + +trait Quux { + fn bar(&self, t: T) + where Self : Sized; +} + +fn make_bar(t: &T) -> &dyn Bar { +// { dg-error "" "" { target *-*-* } .-1 } + t +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn make_bar_explicit(t: &T) -> &dyn Bar { +// { dg-error "" "" { target *-*-* } .-1 } + t as &dyn Bar +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn make_quux(t: &T) -> &dyn Quux { + t +} + +fn make_quux_explicit(t: &T) -> &dyn Quux { + t as &dyn Quux +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-issue-22040.rs b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-issue-22040.rs new file mode 100644 index 000000000000..494518096471 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-issue-22040.rs @@ -0,0 +1,43 @@ +// Regression test for #22040. + +use std::fmt::Debug; + +trait Expr: Debug + PartialEq { + fn print_element_count(&self); +} + +//#[derive(PartialEq)] +#[derive(Debug)] +struct SExpr<'x> { + elements: Vec>, +// { dg-error ".E0038." "" { target *-*-* } .-1 } +} + +impl<'x> PartialEq for SExpr<'x> { + fn eq(&self, other:&SExpr<'x>) -> bool { + println!("L1: {} L2: {}", self.elements.len(), other.elements.len()); + + let result = self.elements.len() == other.elements.len(); + + println!("Got compare {}", result); + return result; + } +} + +impl <'x> SExpr<'x> { + fn new() -> SExpr<'x> { return SExpr{elements: Vec::new(),}; } +} + +impl <'x> Expr for SExpr<'x> { + fn print_element_count(&self) { + println!("element count: {}", self.elements.len()); + } +} + +fn main() { + let a: Box = Box::new(SExpr::new()); + let b: Box = Box::new(SExpr::new()); + + // assert_eq!(a , b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-mentions-Self.rs b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-mentions-Self.rs new file mode 100644 index 000000000000..b4e8acccad56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-mentions-Self.rs @@ -0,0 +1,43 @@ +// Check that we correctly prevent users from making trait objects +// form traits that make use of `Self` in an argument or return +// position, unless `where Self : Sized` is present.. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + + +trait Bar { + fn bar(&self, x: &Self); +} + +trait Baz { + fn baz(&self) -> Self; +} + +trait Quux { + fn quux(&self, s: &Self) -> Self where Self : Sized; +} + +fn make_bar(t: &T) -> &dyn Bar { +// { dg-error "" "" { target *-*-* } .-1 } + t +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn make_baz(t: &T) -> &dyn Baz { +// { dg-error "" "" { target *-*-* } .-1 } + t +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn make_quux(t: &T) -> &dyn Quux { + t +} + +fn make_quux_explicit(t: &T) -> &dyn Quux { + t as &dyn Quux +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-no-static.rs b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-no-static.rs new file mode 100644 index 000000000000..b7b42572cf9a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-no-static.rs @@ -0,0 +1,25 @@ +// Check that we correctly prevent users from making trait objects +// from traits with static methods. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + +trait Foo { + fn foo() {} +} + +fn diverges() -> Box { +// { dg-error "" "" { target *-*-* } .-1 } + loop { } +} + +struct Bar; + +impl Foo for Bar {} + +fn main() { + let b: Box = Box::new(Bar); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-phantom-fn.rs b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-phantom-fn.rs new file mode 100644 index 000000000000..c86d94f788b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-phantom-fn.rs @@ -0,0 +1,23 @@ +// Check that `Self` appearing in a phantom fn does not make a trait not object safe. + +// build-pass (FIXME(62277): could be check-pass?) +#![allow(dead_code)] + +trait Baz { +} + +trait Bar { +} + +fn make_bar>(t: &T) -> &dyn Bar { + t +} + +fn make_baz(t: &T) -> &dyn Baz { + t +} + + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-sized-2.rs b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-sized-2.rs new file mode 100644 index 000000000000..46f1009eefdc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-sized-2.rs @@ -0,0 +1,22 @@ +// Check that we correctly prevent users from making trait objects +// from traits where `Self : Sized`. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + +trait Bar + where Self : Sized +{ + fn bar(&self, t: T); +} + +fn make_bar(t: &T) -> &dyn Bar { +// { dg-error "" "" { target *-*-* } .-1 } + t +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-sized.rs b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-sized.rs new file mode 100644 index 000000000000..45a888dd068b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-sized.rs @@ -0,0 +1,20 @@ +// Check that we correctly prevent users from making trait objects +// from traits where `Self : Sized`. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + +trait Bar : Sized { + fn bar(&self, t: T); +} + +fn make_bar(t: &T) -> &dyn Bar { +// { dg-error "" "" { target *-*-* } .-1 } + t +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-supertrait-mentions-Self.rs b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-supertrait-mentions-Self.rs new file mode 100644 index 000000000000..2f0a34882e52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/object-safety/object-safety-supertrait-mentions-Self.rs @@ -0,0 +1,22 @@ +// Check that we correctly prevent users from making trait objects +// form traits that make use of `Self` in an argument or return position. + +trait Bar { + fn bar(&self, x: &T); +} + +trait Baz : Bar { +} + +fn make_bar>(t: &T) -> &dyn Bar { + t +} + +fn make_baz(t: &T) -> &dyn Baz { +// { dg-error ".E0038." "" { target *-*-* } .-1 } + t +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/objects-coerce-freeze-borrored.rs b/gcc/testsuite/rust/rustc/ui/objects-coerce-freeze-borrored.rs new file mode 100644 index 000000000000..155f5d35f659 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/objects-coerce-freeze-borrored.rs @@ -0,0 +1,41 @@ +// run-pass +// Test that we can coerce an `@Object` to an `&Object` + + +trait Foo { + fn foo(&self) -> usize; + fn bar(&mut self) -> usize; +} + +impl Foo for usize { + fn foo(&self) -> usize { + *self + } + + fn bar(&mut self) -> usize { + *self += 1; + *self + } +} + +fn do_it_mut(obj: &mut dyn Foo) { + let x = obj.bar(); + let y = obj.foo(); + assert_eq!(x, y); + + do_it_imm(obj, y); +} + +fn do_it_imm(obj: &dyn Foo, v: usize) { + let y = obj.foo(); + assert_eq!(v, y); +} + +pub fn main() { + let mut x: usize = 22; + let obj = &mut x as &mut dyn Foo; + do_it_mut(obj); + do_it_imm(obj, 23); + do_it_mut(obj); +} + diff --git a/gcc/testsuite/rust/rustc/ui/objects-owned-object-borrowed-method-headerless.rs b/gcc/testsuite/rust/rustc/ui/objects-owned-object-borrowed-method-headerless.rs new file mode 100644 index 000000000000..a9589153d127 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/objects-owned-object-borrowed-method-headerless.rs @@ -0,0 +1,34 @@ +// run-pass +// Test invoked `&self` methods on owned objects where the values +// closed over do not contain managed values, and thus the boxes do +// not have headers. + +#![feature(box_syntax)] + + +trait FooTrait { + fn foo(&self) -> usize; +} + +struct BarStruct { + x: usize +} + +impl FooTrait for BarStruct { + fn foo(&self) -> usize { + self.x + } +} + +pub fn main() { + let foos: Vec> = vec![ + box BarStruct{ x: 0 } as Box, + box BarStruct{ x: 1 } as Box, + box BarStruct{ x: 2 } as Box + ]; + + for i in 0..foos.len() { + assert_eq!(i, foos[i].foo()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/objects-owned-object-owned-method.rs b/gcc/testsuite/rust/rustc/ui/objects-owned-object-owned-method.rs new file mode 100644 index 000000000000..ef523d0143c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/objects-owned-object-owned-method.rs @@ -0,0 +1,26 @@ +// run-pass +// Test invoked `&self` methods on owned objects where the values +// closed over contain managed values. This implies that the boxes +// will have headers that must be skipped over. + +#![feature(box_syntax)] + +trait FooTrait { + fn foo(self: Box) -> usize; +} + +struct BarStruct { + x: usize +} + +impl FooTrait for BarStruct { + fn foo(self: Box) -> usize { + self.x + } +} + +pub fn main() { + let foo = box BarStruct{ x: 22 } as Box; + assert_eq!(22, foo.foo()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/obsolete-in-place/bad.rs b/gcc/testsuite/rust/rustc/ui/obsolete-in-place/bad.rs new file mode 100644 index 000000000000..16ae6a9058ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/obsolete-in-place/bad.rs @@ -0,0 +1,12 @@ +// Check that `<-` and `in` syntax gets a hard error. + +fn foo() { + let (x, y) = (0, 0); + x <- y; // { dg-error "" "" { target *-*-* } } +} + +fn main() { + let (foo, bar) = (0, 0); + in(foo) { bar }; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/obsolete-syntax-impl-for-dotdot.rs b/gcc/testsuite/rust/rustc/ui/obsolete-syntax-impl-for-dotdot.rs new file mode 100644 index 000000000000..1e4a341b6dd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/obsolete-syntax-impl-for-dotdot.rs @@ -0,0 +1,10 @@ +trait Trait1 {} +trait Trait2 {} + +#[cfg(not_enabled)] +impl Trait1 for .. {} + +impl Trait2 for .. {} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/occurs-check-2.rs b/gcc/testsuite/rust/rustc/ui/occurs-check-2.rs new file mode 100644 index 000000000000..e8974e3b5459 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/occurs-check-2.rs @@ -0,0 +1,11 @@ +#![feature(box_syntax)] + +fn main() { + let f; + let g; + g = f; + f = box g; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/occurs-check-3.rs b/gcc/testsuite/rust/rustc/ui/occurs-check-3.rs new file mode 100644 index 000000000000..6af4c251c6f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/occurs-check-3.rs @@ -0,0 +1,6 @@ +// From Issue #778 + +enum Clam { A(T) } +fn main() { let c; c = Clam::A(c); match c { Clam::A::(_) => { } } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/occurs-check.rs b/gcc/testsuite/rust/rustc/ui/occurs-check.rs new file mode 100644 index 000000000000..d6b537ab0ee2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/occurs-check.rs @@ -0,0 +1,9 @@ +#![feature(box_syntax)] + +fn main() { + let f; + f = box f; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/offset_from.rs b/gcc/testsuite/rust/rustc/ui/offset_from.rs new file mode 100644 index 000000000000..16180195fc07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/offset_from.rs @@ -0,0 +1,14 @@ +// run-pass + +fn main() { + let mut a = [0; 5]; + let ptr1: *mut i32 = &mut a[1]; + let ptr2: *mut i32 = &mut a[3]; + unsafe { + assert_eq!(ptr2.offset_from(ptr1), 2); + assert_eq!(ptr1.offset_from(ptr2), -2); + assert_eq!(ptr1.offset(2), ptr2); + assert_eq!(ptr2.offset(-2), ptr1); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/old-suffixes-are-really-forbidden.rs b/gcc/testsuite/rust/rustc/ui/old-suffixes-are-really-forbidden.rs new file mode 100644 index 000000000000..030f66ae9cfb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/old-suffixes-are-really-forbidden.rs @@ -0,0 +1,5 @@ +fn main() { + let a = 1_is; // { dg-error "" "" { target *-*-* } } + let b = 2_us; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/on-unimplemented/auxiliary/no_debug.rs b/gcc/testsuite/rust/rustc/ui/on-unimplemented/auxiliary/no_debug.rs new file mode 100644 index 000000000000..7b1103854d47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/on-unimplemented/auxiliary/no_debug.rs @@ -0,0 +1,4 @@ +#![crate_type = "lib"] + +pub struct Bar; + diff --git a/gcc/testsuite/rust/rustc/ui/on-unimplemented/bad-annotation.rs b/gcc/testsuite/rust/rustc/ui/on-unimplemented/bad-annotation.rs new file mode 100644 index 000000000000..989656042cc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/on-unimplemented/bad-annotation.rs @@ -0,0 +1,65 @@ +// ignore-tidy-linelength + +#![feature(rustc_attrs)] + +#![allow(unused)] + +#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"] +trait Foo +{} + +#[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an iterator over elements of type `{A}`"] +trait MyFromIterator { + /// Builds a container with elements from an external iterator. + fn my_from_iter>(iterator: T) -> Self; +} + +#[rustc_on_unimplemented] +// { dg-error "" "" { target *-*-* } .-1 } +trait BadAnnotation1 +{} + +#[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"] +// { dg-error ".E0230." "" { target *-*-* } .-1 } +trait BadAnnotation2 +{} + +#[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"] +// { dg-error ".E0231." "" { target *-*-* } .-1 } +trait BadAnnotation3 +{} + +#[rustc_on_unimplemented(lorem="")] +// { dg-error ".E0232." "" { target *-*-* } .-1 } +trait BadAnnotation4 {} + +#[rustc_on_unimplemented(lorem(ipsum(dolor)))] +// { dg-error ".E0232." "" { target *-*-* } .-1 } +trait BadAnnotation5 {} + +#[rustc_on_unimplemented(message="x", message="y")] +// { dg-error ".E0232." "" { target *-*-* } .-1 } +trait BadAnnotation6 {} + +#[rustc_on_unimplemented(message="x", on(desugared, message="y"))] +// { dg-error ".E0232." "" { target *-*-* } .-1 } +trait BadAnnotation7 {} + +#[rustc_on_unimplemented(on(), message="y")] +// { dg-error ".E0232." "" { target *-*-* } .-1 } +trait BadAnnotation8 {} + +#[rustc_on_unimplemented(on="x", message="y")] +// { dg-error ".E0232." "" { target *-*-* } .-1 } +trait BadAnnotation9 {} + +#[rustc_on_unimplemented(on(x="y"), message="y")] +trait BadAnnotation10 {} + +#[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")] +// { dg-error ".E0232." "" { target *-*-* } .-1 } +trait BadAnnotation11 {} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/on-unimplemented/enclosing-scope.rs b/gcc/testsuite/rust/rustc/ui/on-unimplemented/enclosing-scope.rs new file mode 100644 index 000000000000..b52fcee8e429 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/on-unimplemented/enclosing-scope.rs @@ -0,0 +1,28 @@ +// Test scope annotations from `enclosing_scope` parameter + +#![feature(rustc_attrs)] + +#[rustc_on_unimplemented(enclosing_scope="in this scope")] +trait Trait{} + +struct Foo; + +fn f(x: T) {} + +fn main() { + let x = || { + f(Foo{}); // { dg-error ".E0277." "" { target *-*-* } } + let y = || { + f(Foo{}); // { dg-error ".E0277." "" { target *-*-* } } + }; + }; + + { + { + f(Foo{}); // { dg-error ".E0277." "" { target *-*-* } } + } + } + + f(Foo{}); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/on-unimplemented/expected-comma-found-token.rs b/gcc/testsuite/rust/rustc/ui/on-unimplemented/expected-comma-found-token.rs new file mode 100644 index 000000000000..16b585ec0dd4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/on-unimplemented/expected-comma-found-token.rs @@ -0,0 +1,14 @@ +// Tests that two closures cannot simultaneously have mutable +// access to the variable, whether that mutable access be used +// for direct assignment or for taking mutable ref. Issue #6801. + +#![feature(rustc_attrs)] + +#[rustc_on_unimplemented( + message="the message" + label="the label" // { dg-error "" "" { target *-*-* } } +)] +trait T {} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/on-unimplemented/feature-gate-on-unimplemented.rs b/gcc/testsuite/rust/rustc/ui/on-unimplemented/feature-gate-on-unimplemented.rs new file mode 100644 index 000000000000..d38f99e921c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/on-unimplemented/feature-gate-on-unimplemented.rs @@ -0,0 +1,9 @@ +// Test that `#[rustc_on_unimplemented]` is gated by `rustc_attrs` feature gate. + +#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +trait Foo +{} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/on-unimplemented/multiple-impls.rs b/gcc/testsuite/rust/rustc/ui/on-unimplemented/multiple-impls.rs new file mode 100644 index 000000000000..80233ea713bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/on-unimplemented/multiple-impls.rs @@ -0,0 +1,43 @@ +// Test if the on_unimplemented message override works + +#![feature(rustc_attrs)] + + +struct Foo(T); +struct Bar(T); + +#[rustc_on_unimplemented = "trait message"] +trait Index { + type Output: ?Sized; + fn index(&self, index: Idx) -> &Self::Output; +} + +#[rustc_on_unimplemented = "on impl for Foo"] +impl Index> for [i32] { + type Output = i32; + fn index(&self, _index: Foo) -> &i32 { + loop {} + } +} + +#[rustc_on_unimplemented = "on impl for Bar"] +impl Index> for [i32] { + type Output = i32; + fn index(&self, _index: Bar) -> &i32 { + loop {} + } +} + + +fn main() { + Index::index(&[] as &[i32], 2u32); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + Index::index(&[] as &[i32], Foo(2u32)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + Index::index(&[] as &[i32], Bar(2u32)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/on-unimplemented/no-debug.rs b/gcc/testsuite/rust/rustc/ui/on-unimplemented/no-debug.rs new file mode 100644 index 000000000000..61c7c1d2ba59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/on-unimplemented/no-debug.rs @@ -0,0 +1,17 @@ +// aux-build:no_debug.rs + +extern crate no_debug; + +use no_debug::Bar; + +struct Foo; + +fn main() { + println!("{:?} {:?}", Foo, Bar); + println!("{} {}", Foo, Bar); +} +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/on-unimplemented/on-impl.rs b/gcc/testsuite/rust/rustc/ui/on-unimplemented/on-impl.rs new file mode 100644 index 000000000000..9c723b688d7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/on-unimplemented/on-impl.rs @@ -0,0 +1,26 @@ +// Test if the on_unimplemented message override works + +#![feature(rustc_attrs)] + + +#[rustc_on_unimplemented = "invalid"] +trait Index { + type Output: ?Sized; + fn index(&self, index: Idx) -> &Self::Output; +} + +#[rustc_on_unimplemented = "a usize is required to index into a slice"] +impl Index for [i32] { + type Output = i32; + fn index(&self, index: usize) -> &i32 { + &self[index] + } +} + + +fn main() { + Index::::index(&[1, 2, 3] as &[i32], 2u32); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/on-unimplemented/on-trait.rs b/gcc/testsuite/rust/rustc/ui/on-unimplemented/on-trait.rs new file mode 100644 index 000000000000..ec23555fa3ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/on-unimplemented/on-trait.rs @@ -0,0 +1,33 @@ +// ignore-tidy-linelength + +#![feature(rustc_attrs)] + +pub mod Bar { + #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{Foo}`"] + pub trait Foo {} +} + +use Bar::Foo; + +fn foobar>() -> T { + panic!() +} + +#[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an iterator over elements of type `{A}`"] +trait MyFromIterator { + /// Builds a container with elements from an external iterator. + fn my_from_iter>(iterator: T) -> Self; +} + +fn collect, B: MyFromIterator>(it: I) -> B { + MyFromIterator::my_from_iter(it) +} + +pub fn main() { + let x = vec![1u8, 2, 3, 4]; + let y: Option> = collect(x.iter()); // this should give approximately the same error for x.iter().collect() +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + let x: String = foobar(); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/on-unimplemented/slice-index.rs b/gcc/testsuite/rust/rustc/ui/on-unimplemented/slice-index.rs new file mode 100644 index 000000000000..3b11b37b5ec2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/on-unimplemented/slice-index.rs @@ -0,0 +1,11 @@ +// Test new Index error message for slices + +use std::ops::Index; + + +fn main() { + let x = &[1, 2, 3] as &[i32]; + x[1i32]; // { dg-error ".E0277." "" { target *-*-* } } + x[..1i32]; // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/once-cant-call-twice-on-heap.rs b/gcc/testsuite/rust/rustc/ui/once-cant-call-twice-on-heap.rs new file mode 100644 index 000000000000..267ac0c3ad91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/once-cant-call-twice-on-heap.rs @@ -0,0 +1,19 @@ +// Testing guarantees provided by once functions. +// This program would segfault if it were legal. + +#![feature(once_fns)] +use std::sync::Arc; + +fn foo(blk: F) { + blk(); + blk(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn main() { + let x = Arc::new(true); + foo(move|| { + assert!(*x); + drop(x); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/once-move-out-on-heap.rs b/gcc/testsuite/rust/rustc/ui/once-move-out-on-heap.rs new file mode 100644 index 000000000000..11ebf923fba3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/once-move-out-on-heap.rs @@ -0,0 +1,19 @@ +// run-pass +// Testing guarantees provided by once functions. + + + +use std::sync::Arc; + +fn foo(blk: F) { + blk(); +} + +pub fn main() { + let x = Arc::new(true); + foo(move|| { + assert!(*x); + drop(x); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/one-tuple.rs b/gcc/testsuite/rust/rustc/ui/one-tuple.rs new file mode 100644 index 000000000000..46394fdb97fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/one-tuple.rs @@ -0,0 +1,16 @@ +// run-pass +// Why one-tuples? Because macros. + + +pub fn main() { + match ('c',) { + (x,) => { + assert_eq!(x, 'c'); + } + } + // test the 1-tuple type too + let x: (char,) = ('d',); + let (y,) = x; + assert_eq!(y, 'd'); +} + diff --git a/gcc/testsuite/rust/rustc/ui/op-assign-builtins-by-ref.rs b/gcc/testsuite/rust/rustc/ui/op-assign-builtins-by-ref.rs new file mode 100644 index 000000000000..01b05cdba3bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/op-assign-builtins-by-ref.rs @@ -0,0 +1,77 @@ +// run-pass + +fn main() { + // test compound assignment operators with ref as right-hand side, + // for each operator, with various types as operands. + + // test AddAssign + { + let mut x = 3i8; + x += &2i8; + assert_eq!(x, 5i8); + } + + // test SubAssign + { + let mut x = 7i16; + x -= &4; + assert_eq!(x, 3i16); + } + + // test MulAssign + { + let mut x = 3f32; + x *= &3f32; + assert_eq!(x, 9f32); + } + + // test DivAssign + { + let mut x = 6f64; + x /= &2f64; + assert_eq!(x, 3f64); + } + + // test RemAssign + { + let mut x = 7i64; + x %= &4i64; + assert_eq!(x, 3i64); + } + + // test BitOrAssign + { + let mut x = 0b1010u8; + x |= &0b1100u8; + assert_eq!(x, 0b1110u8); + } + + // test BitAndAssign + { + let mut x = 0b1010u16; + x &= &0b1100u16; + assert_eq!(x, 0b1000u16); + } + + // test BitXorAssign + { + let mut x = 0b1010u32; + x ^= &0b1100u32; + assert_eq!(x, 0b0110u32); + } + + // test ShlAssign + { + let mut x = 0b1010u64; + x <<= &2u32; + assert_eq!(x, 0b101000u64); + } + + // test ShrAssign + { + let mut x = 0b1010u64; + x >>= &2i16; + assert_eq!(x, 0b10u64); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/opeq.rs b/gcc/testsuite/rust/rustc/ui/opeq.rs new file mode 100644 index 000000000000..9e0f95740117 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/opeq.rs @@ -0,0 +1,18 @@ +// run-pass + +pub fn main() { + let mut x: isize = 1; + x *= 2; + println!("{}", x); + assert_eq!(x, 2); + x += 3; + println!("{}", x); + assert_eq!(x, 5); + x *= x; + println!("{}", x); + assert_eq!(x, 25); + x /= 5; + println!("{}", x); + assert_eq!(x, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/operator-associativity.rs b/gcc/testsuite/rust/rustc/ui/operator-associativity.rs new file mode 100644 index 000000000000..430e7af941f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/operator-associativity.rs @@ -0,0 +1,5 @@ +// run-pass +// Testcase for issue #130, operator associativity. + +pub fn main() { assert_eq!(3 * 5 / 2, 7); } + diff --git a/gcc/testsuite/rust/rustc/ui/operator-multidispatch.rs b/gcc/testsuite/rust/rustc/ui/operator-multidispatch.rs new file mode 100644 index 000000000000..8bdc15b6cf78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/operator-multidispatch.rs @@ -0,0 +1,37 @@ +// run-pass +// Test that we can overload the `+` operator for points so that two +// points can be added, and a point can be added to an integer. + +use std::ops; + +#[derive(Debug,PartialEq,Eq)] +struct Point { + x: isize, + y: isize +} + +impl ops::Add for Point { + type Output = Point; + + fn add(self, other: Point) -> Point { + Point {x: self.x + other.x, y: self.y + other.y} + } +} + +impl ops::Add for Point { + type Output = Point; + + fn add(self, other: isize) -> Point { + Point {x: self.x + other, + y: self.y + other} + } +} + +pub fn main() { + let mut p = Point {x: 10, y: 20}; + p = p + Point {x: 101, y: 102}; + assert_eq!(p, Point {x: 111, y: 122}); + p = p + 1; + assert_eq!(p, Point {x: 112, y: 123}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/operator-overloading.rs b/gcc/testsuite/rust/rustc/ui/operator-overloading.rs new file mode 100644 index 000000000000..17aa3df9beb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/operator-overloading.rs @@ -0,0 +1,82 @@ +// run-pass + +#![allow(unused_variables)] +use std::cmp; +use std::ops; + +#[derive(Copy, Clone, Debug)] +struct Point { + x: isize, + y: isize +} + +impl ops::Add for Point { + type Output = Point; + + fn add(self, other: Point) -> Point { + Point {x: self.x + other.x, y: self.y + other.y} + } +} + +impl ops::Sub for Point { + type Output = Point; + + fn sub(self, other: Point) -> Point { + Point {x: self.x - other.x, y: self.y - other.y} + } +} + +impl ops::Neg for Point { + type Output = Point; + + fn neg(self) -> Point { + Point {x: -self.x, y: -self.y} + } +} + +impl ops::Not for Point { + type Output = Point; + + fn not(self) -> Point { + Point {x: !self.x, y: !self.y } + } +} + +impl ops::Index for Point { + type Output = isize; + + fn index(&self, x: bool) -> &isize { + if x { + &self.x + } else { + &self.y + } + } +} + +impl cmp::PartialEq for Point { + fn eq(&self, other: &Point) -> bool { + (*self).x == (*other).x && (*self).y == (*other).y + } + fn ne(&self, other: &Point) -> bool { !(*self).eq(other) } +} + +pub fn main() { + let mut p = Point {x: 10, y: 20}; + p = p + Point {x: 101, y: 102}; + p = p - Point {x: 100, y: 100}; + assert_eq!(p + Point {x: 5, y: 5}, Point {x: 16, y: 27}); + assert_eq!(-p, Point {x: -11, y: -22}); + assert_eq!(p[true], 11); + assert_eq!(p[false], 22); + + let q = !p; + assert_eq!(q.x, !(p.x)); + assert_eq!(q.y, !(p.y)); + + // Issue #1733 + result(p[true]); +} + +fn result(i: isize) { } + diff --git a/gcc/testsuite/rust/rustc/ui/opt-in-copy.rs b/gcc/testsuite/rust/rustc/ui/opt-in-copy.rs new file mode 100644 index 000000000000..9eb8d045c52d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/opt-in-copy.rs @@ -0,0 +1,23 @@ +struct CantCopyThis; + +struct IWantToCopyThis { + but_i_cant: CantCopyThis, +} + +impl Copy for IWantToCopyThis {} +// { dg-error ".E0204." "" { target *-*-* } .-1 } + +enum CantCopyThisEither { + A, + B, +} + +enum IWantToCopyThisToo { + ButICant(CantCopyThisEither), +} + +impl Copy for IWantToCopyThisToo {} +// { dg-error ".E0204." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/optimization-fuel-0.rs b/gcc/testsuite/rust/rustc/ui/optimization-fuel-0.rs new file mode 100644 index 000000000000..3152dee51837 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/optimization-fuel-0.rs @@ -0,0 +1,16 @@ +// run-pass + +#![crate_name="foo"] + +use std::mem::size_of; + +// compile-flags: -Z fuel=foo=0 + +struct S1(u8, u16, u8); +struct S2(u8, u16, u8); + +fn main() { + assert_eq!(size_of::(), 6); + assert_eq!(size_of::(), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/optimization-fuel-1.rs b/gcc/testsuite/rust/rustc/ui/optimization-fuel-1.rs new file mode 100644 index 000000000000..e0ae0f08a460 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/optimization-fuel-1.rs @@ -0,0 +1,17 @@ +// run-pass + +#![crate_name="foo"] + +use std::mem::size_of; + +// compile-flags: -Z fuel=foo=1 + +struct S1(u8, u16, u8); +struct S2(u8, u16, u8); + +fn main() { + let optimized = (size_of::() == 4) as usize + +(size_of::() == 4) as usize; + assert_eq!(optimized, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/option-ext.rs b/gcc/testsuite/rust/rustc/ui/option-ext.rs new file mode 100644 index 000000000000..878e67eb8ead --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/option-ext.rs @@ -0,0 +1,11 @@ +// run-pass + +pub fn main() { + let thing = "{{ f }}"; + let f = thing.find("{{"); + + if f.is_none() { + println!("None!"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/option-to-result.rs b/gcc/testsuite/rust/rustc/ui/option-to-result.rs new file mode 100644 index 000000000000..00483a69e004 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/option-to-result.rs @@ -0,0 +1,14 @@ +fn main(){ } + +fn test_result() -> Result<(),()> { + let a:Option<()> = Some(()); + a?;// { dg-error ".E0277." "" { target *-*-* } } + Ok(()) +} + +fn test_option() -> Option{ + let a:Result = Ok(5); + a?;// { dg-error ".E0277." "" { target *-*-* } } + Some(5) +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/already-bound-name.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/already-bound-name.rs new file mode 100644 index 000000000000..43eb7909cb9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/already-bound-name.rs @@ -0,0 +1,46 @@ +// This test ensures that the "already bound identifier in a product pattern" +// correctly accounts for or-patterns. + +#![feature(or_patterns)] + +enum E { A(T, T), B(T) } + +use E::*; + +fn main() { + let (a, a) = (0, 1); // Standard duplication without an or-pattern. +// { dg-error ".E0416." "" { target *-*-* } .-1 } + + let (a, A(a, _) | B(a)) = (0, A(1, 2)); +// { dg-error ".E0416." "" { target *-*-* } .-1 } +// { dg-error ".E0416." "" { target *-*-* } .-2 } + + let (A(a, _) | B(a), a) = (A(0, 1), 2); +// { dg-error ".E0416." "" { target *-*-* } .-1 } + + let A(a, a) | B(a) = A(0, 1); +// { dg-error ".E0416." "" { target *-*-* } .-1 } + + let B(a) | A(a, a) = A(0, 1); +// { dg-error ".E0416." "" { target *-*-* } .-1 } + + match A(0, 1) { + B(a) | A(a, a) => {} // Let's ensure `match` has no funny business. +// { dg-error ".E0416." "" { target *-*-* } .-1 } + } + + let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + + let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); +// { dg-error ".E0416." "" { target *-*-* } .-1 } +// { dg-error ".E0416." "" { target *-*-* } .-2 } +// { dg-error ".E0408." "" { target *-*-* } .-3 } + + let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1)); +// { dg-error ".E0416." "" { target *-*-* } .-1 } +// { dg-error ".E0416." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/basic-switch.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/basic-switch.rs new file mode 100644 index 000000000000..04bd3092b4d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/basic-switch.rs @@ -0,0 +1,34 @@ +// Test basic or-patterns when the target pattern type will be lowered to a +// `Switch` (an `enum`). + +// run-pass + +#![feature(or_patterns)] + +#[derive(Debug)] +enum Test { + Foo, + Bar, + Baz, + Qux, +} + +fn test(x: Option) -> bool { + match x { + // most simple case + Some(Test::Bar | Test::Qux) => true, + // wild case + Some(_) => false, + // empty case + None => false, + } +} + +fn main() { + assert!(!test(Some(Test::Foo))); + assert!(test(Some(Test::Bar))); + assert!(!test(Some(Test::Baz))); + assert!(test(Some(Test::Qux))); + assert!(!test(None)) +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/basic-switchint.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/basic-switchint.rs new file mode 100644 index 000000000000..88dd1112ceb6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/basic-switchint.rs @@ -0,0 +1,55 @@ +// Test basic or-patterns when the target pattern type will be lowered to +// a `SwitchInt`. This will happen when the target type is an integer. + +// run-pass + +#![feature(or_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +#[derive(Debug)] +enum Foo { + One(usize), + Two(usize, usize), +} + +fn test_foo(x: Foo) -> MatchArm { + match x { + // normal pattern. + Foo::One(0) | Foo::One(1) | Foo::One(2) => MatchArm::Arm(0), + // most simple or-pattern. + Foo::One(42 | 255) => MatchArm::Arm(1), + // multiple or-patterns for one structure. + Foo::Two(42 | 255, 1024 | 2048) => MatchArm::Arm(2), + // mix of pattern types in one or-pattern (range). + Foo::One(100 | 110..=120 | 210..=220) => MatchArm::Arm(3), + // multiple or-patterns with wild. + Foo::Two(0..=10 | 100..=110, 0 | _) => MatchArm::Arm(4), + // wild + _ => MatchArm::Wild, + } +} + +fn main() { + // `Foo` tests. + assert_eq!(test_foo(Foo::One(0)), MatchArm::Arm(0)); + assert_eq!(test_foo(Foo::One(42)), MatchArm::Arm(1)); + assert_eq!(test_foo(Foo::One(43)), MatchArm::Wild); + assert_eq!(test_foo(Foo::One(255)), MatchArm::Arm(1)); + assert_eq!(test_foo(Foo::One(256)), MatchArm::Wild); + assert_eq!(test_foo(Foo::Two(42, 1023)), MatchArm::Wild); + assert_eq!(test_foo(Foo::Two(255, 2048)), MatchArm::Arm(2)); + assert_eq!(test_foo(Foo::One(100)), MatchArm::Arm(3)); + assert_eq!(test_foo(Foo::One(115)), MatchArm::Arm(3)); + assert_eq!(test_foo(Foo::One(105)), MatchArm::Wild); + assert_eq!(test_foo(Foo::One(215)), MatchArm::Arm(3)); + assert_eq!(test_foo(Foo::One(121)), MatchArm::Wild); + assert_eq!(test_foo(Foo::Two(0, 42)), MatchArm::Arm(4)); + assert_eq!(test_foo(Foo::Two(100, 0)), MatchArm::Arm(4)); + assert_eq!(test_foo(Foo::Two(42, 0)), MatchArm::Wild); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/bindings-runpass-1.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/bindings-runpass-1.rs new file mode 100644 index 000000000000..37a4d4efa0bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/bindings-runpass-1.rs @@ -0,0 +1,26 @@ +// run-pass + +#![feature(or_patterns)] + +fn two_bindings(x: &((bool, bool), u8)) -> u8 { + match x { + &((true, y) | (y, true), z @ (0 | 4)) => (y as u8) + z, + _ => 20, + } +} + +fn main() { + assert_eq!(two_bindings(&((false, false), 0)), 20); + assert_eq!(two_bindings(&((false, true), 0)), 0); + assert_eq!(two_bindings(&((true, false), 0)), 0); + assert_eq!(two_bindings(&((true, true), 0)), 1); + assert_eq!(two_bindings(&((false, false), 4)), 20); + assert_eq!(two_bindings(&((false, true), 4)), 4); + assert_eq!(two_bindings(&((true, false), 4)), 4); + assert_eq!(two_bindings(&((true, true), 4)), 5); + assert_eq!(two_bindings(&((false, false), 3)), 20); + assert_eq!(two_bindings(&((false, true), 3)), 20); + assert_eq!(two_bindings(&((true, false), 3)), 20); + assert_eq!(two_bindings(&((true, true), 3)), 20); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/bindings-runpass-2.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/bindings-runpass-2.rs new file mode 100644 index 000000000000..694541a629b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/bindings-runpass-2.rs @@ -0,0 +1,33 @@ +// run-pass + +#![feature(or_patterns)] + +fn or_at(x: Result) -> u32 { + match x { + Ok(x @ 4) | Err(x @ (6 | 8)) => x, + Ok(x @ 1 | x @ 2) => x, + Err(x @ (0..=10 | 30..=40)) if x % 2 == 0 => x + 100, + Err(x @ 0..=40) => x + 200, + _ => 500, + } +} + +fn main() { + assert_eq!(or_at(Ok(1)), 1); + assert_eq!(or_at(Ok(2)), 2); + assert_eq!(or_at(Ok(3)), 500); + assert_eq!(or_at(Ok(4)), 4); + assert_eq!(or_at(Ok(5)), 500); + assert_eq!(or_at(Ok(6)), 500); + assert_eq!(or_at(Err(1)), 201); + assert_eq!(or_at(Err(2)), 102); + assert_eq!(or_at(Err(3)), 203); + assert_eq!(or_at(Err(4)), 104); + assert_eq!(or_at(Err(5)), 205); + assert_eq!(or_at(Err(6)), 6); + assert_eq!(or_at(Err(7)), 207); + assert_eq!(or_at(Err(8)), 8); + assert_eq!(or_at(Err(20)), 220); + assert_eq!(or_at(Err(50)), 500); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/box-patterns.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/box-patterns.rs new file mode 100644 index 000000000000..3d45cd3b485e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/box-patterns.rs @@ -0,0 +1,38 @@ +// Test or-patterns with box-patterns + +// run-pass + +#![feature(or_patterns)] +#![feature(box_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +#[derive(Debug)] +enum Test { + Foo, + Bar, + Baz, + Qux, +} + +fn test(x: Option>) -> MatchArm { + match x { + Some(box Test::Foo | box Test::Bar) => MatchArm::Arm(0), + Some(box Test::Baz) => MatchArm::Arm(1), + Some(_) => MatchArm::Arm(2), + _ => MatchArm::Wild, + } +} + +fn main() { + assert_eq!(test(Some(Box::new(Test::Foo))), MatchArm::Arm(0)); + assert_eq!(test(Some(Box::new(Test::Bar))), MatchArm::Arm(0)); + assert_eq!(test(Some(Box::new(Test::Baz))), MatchArm::Arm(1)); + assert_eq!(test(Some(Box::new(Test::Qux))), MatchArm::Arm(2)); + assert_eq!(test(None), MatchArm::Wild); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/consistent-bindings.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/consistent-bindings.rs new file mode 100644 index 000000000000..6688c7dff620 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/consistent-bindings.rs @@ -0,0 +1,42 @@ +// Check that or-patterns with consistent bindings across arms are allowed. + +// edition:2018 + +// check-pass + +#![feature(or_patterns)] + +fn main() { + // One level: + let Ok(a) | Err(a) = Ok(0); + let Ok(ref a) | Err(ref a) = Ok(0); + let Ok(ref mut a) | Err(ref mut a) = Ok(0); + + // Two levels: + enum Tri { + V1(S), + V2(T), + V3(U), + } + use Tri::*; + + let Ok((V1(a) | V2(a) | V3(a), b)) | Err(Ok((a, b)) | Err((a, b))): Result<_, Result<_, _>> = + Ok((V1(1), 1)); + + let Ok((V1(a) | V2(a) | V3(a), ref b)) | Err(Ok((a, ref b)) | Err((a, ref b))): Result< + _, + Result<_, _>, + > = Ok((V1(1), 1)); + + // Three levels: + let ( + a, + Err((ref mut b, ref c, d)) + | Ok(( + Ok(V1((ref c, d)) | V2((d, ref c)) | V3((ref c, Ok((_, d)) | Err((d, _))))) + | Err((ref c, d)), + ref mut b, + )), + ): (_, Result<_, _>) = (1, Ok((Ok(V3((1, Ok::<_, (i32, i32)>((1, 1))))), 1))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/const-fn.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/const-fn.rs new file mode 100644 index 000000000000..6990452837c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/const-fn.rs @@ -0,0 +1,31 @@ +// check-pass +#![feature(or_patterns)] + +const fn foo((Ok(a) | Err(a)): Result) { + let x = Ok(3); + let Ok(y) | Err(y) = x; +} + +const X: () = { + let x = Ok(3); + let Ok(y) | Err(y) = x; +}; + +static Y: () = { + let x = Ok(3); + let Ok(y) | Err(y) = x; +}; + +static mut Z: () = { + let x = Ok(3); + let Ok(y) | Err(y) = x; +}; + +fn main() { + let _: [(); { + let x = Ok(3); + let Ok(y) | Err(y) = x; + 2 + }]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/exhaustiveness-non-exhaustive.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/exhaustiveness-non-exhaustive.rs new file mode 100644 index 000000000000..b7c1082f83e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/exhaustiveness-non-exhaustive.rs @@ -0,0 +1,19 @@ +#![feature(or_patterns)] +#![deny(unreachable_patterns)] + +// We wrap patterns in a tuple because top-level or-patterns were special-cased. +fn main() { + match (0u8, 0u8) { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + (0 | 1, 2 | 3) => {} + } + match ((0u8,),) { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + ((0 | 1,) | (2 | 3,),) => {} + } + match (Some(0u8),) { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + (None | Some(0 | 1),) => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/exhaustiveness-pass.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/exhaustiveness-pass.rs new file mode 100644 index 000000000000..051bf6066c36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/exhaustiveness-pass.rs @@ -0,0 +1,40 @@ +#![feature(or_patterns)] +#![deny(unreachable_patterns)] + +// check-pass + +// We wrap patterns in a tuple because top-level or-patterns were special-cased. +fn main() { + match (0,) { + (1 | 2,) => {} + _ => {} + } + + match (0, 0) { + (1 | 2, 3 | 4) => {} + (1, 2) => {} + (3, 1) => {} + _ => {} + } + match (Some(0u8),) { + (None | Some(0 | 1),) => {} + (Some(2..=255),) => {} + } + match ((0,),) { + ((0 | 1,) | (2 | 3,),) => {} + ((_,),) => {} + } + match (&[0u8][..],) { + ([] | [0 | 1..=255] | [_, ..],) => {} + } + + match ((0, 0),) { + ((0, 0) | (0, 1),) => {} + _ => {} + } + match ((0, 0),) { + ((0, 0) | (1, 0),) => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/exhaustiveness-unreachable-pattern.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/exhaustiveness-unreachable-pattern.rs new file mode 100644 index 000000000000..cc589b7bbc55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/exhaustiveness-unreachable-pattern.rs @@ -0,0 +1,106 @@ +#![feature(or_patterns)] +#![deny(unreachable_patterns)] + +// We wrap patterns in a tuple because top-level or-patterns were special-cased. +fn main() { + match (0u8,) { + (1 | 2,) => {} + (1,) => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + match (0u8,) { + (1 | 2,) => {} + (2,) => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + match (0u8,) { + (1,) => {} + (2,) => {} + (1 | 2,) => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + match (0u8, 0u8) { + (1 | 2, 3 | 4) => {} + (1, 3) => {} // { dg-error "" "" { target *-*-* } } + (1, 4) => {} // { dg-error "" "" { target *-*-* } } + (2, 4) => {} // { dg-error "" "" { target *-*-* } } + (2 | 1, 4) => {} // { dg-error "" "" { target *-*-* } } + (1, 5 | 6) => {} + (1, 4 | 5) => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + match (true, true) { + (false | true, false | true) => (), + } + match (Some(0u8),) { + (None | Some(1 | 2),) => {} + (Some(1),) => {} // { dg-error "" "" { target *-*-* } } + (None,) => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + match ((0u8,),) { + ((1 | 2,) | (3 | 4,),) => {} + ((1..=4,),) => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + + match (0,) { + (1 | 1,) => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + match [0; 2] { + [0 + | 0 // { dg-error "" "" { target *-*-* } } + , 0 + | 0] => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + match &[][..] { + [0] => {} + [0, _] => {} + [0, _, _] => {} + [1, ..] => {} + [1 // { dg-error "" "" { target *-*-* } } + | 2, ..] => {} + _ => {} + } + match Some(0) { + Some(0) => {} + Some(0 // { dg-error "" "" { target *-*-* } } + | 1) => {} + _ => {} + } + + // A subpattern that is only unreachable in one branch is overall reachable. + match (true, true) { + (true, true) => {} + (false | true, false | true) => {} + } + match (true, true) { + (true, true) => {} + (false, false) => {} + (false | true, false | true) => {} + } + // https://github.com/rust-lang/rust/issues/76836 + match None { + Some(false) => {} + None | Some(true + | false) => {} // { dg-error "" "" { target *-*-* } } + } + + // A subpattern that is unreachable in all branches is overall unreachable. + match (true, true) { + (false, true) => {} + (true, true) => {} + (false | true, false + | true) => {} // { dg-error "" "" { target *-*-* } } + } + match (true, true) { + (true, false) => {} + (true, true) => {} + (false + | true, // { dg-error "" "" { target *-*-* } } + false | true) => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/feature-gate-or_patterns-leading-for.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/feature-gate-or_patterns-leading-for.rs new file mode 100644 index 000000000000..108c7244388b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/feature-gate-or_patterns-leading-for.rs @@ -0,0 +1,9 @@ +// Test feature gating for a sole leading `|` in `let`. + +fn main() {} + +#[cfg(FALSE)] +fn gated_leading_vert_in_let() { + for | A in 0 {} // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/feature-gate-or_patterns-leading-let.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/feature-gate-or_patterns-leading-let.rs new file mode 100644 index 000000000000..28a72a93d7e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/feature-gate-or_patterns-leading-let.rs @@ -0,0 +1,9 @@ +// Test feature gating for a sole leading `|` in `let`. + +fn main() {} + +#[cfg(FALSE)] +fn gated_leading_vert_in_let() { + let | A; // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/feature-gate-or_patterns.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/feature-gate-or_patterns.rs new file mode 100644 index 000000000000..ae7cc71fb898 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/feature-gate-or_patterns.rs @@ -0,0 +1,53 @@ +fn main() {} + +pub fn example(x: Option) { + match x { + Some(0 | 1 | 2) => {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + _ => {} + } +} + +// Test the `pat` macro fragment parser: +macro_rules! accept_pat { + ($p:pat) => {} +} + +accept_pat!((p | q)); // { dg-error ".E0658." "" { target *-*-* } } +accept_pat!((p | q,)); // { dg-error ".E0658." "" { target *-*-* } } +accept_pat!(TS(p | q)); // { dg-error ".E0658." "" { target *-*-* } } +accept_pat!(NS { f: p | q }); // { dg-error ".E0658." "" { target *-*-* } } +accept_pat!([p | q]); // { dg-error ".E0658." "" { target *-*-* } } + +// Non-macro tests: + +#[cfg(FALSE)] +fn or_patterns() { + // Gated: + + let | A | B; // { dg-error ".E0658." "" { target *-*-* } } + let A | B; // { dg-error ".E0658." "" { target *-*-* } } + for | A | B in 0 {} // { dg-error ".E0658." "" { target *-*-* } } + for A | B in 0 {} // { dg-error ".E0658." "" { target *-*-* } } + fn fun((A | B): _) {} // { dg-error ".E0658." "" { target *-*-* } } + let _ = |(A | B): u8| (); // { dg-error ".E0658." "" { target *-*-* } } + let (A | B); // { dg-error ".E0658." "" { target *-*-* } } + let (A | B,); // { dg-error ".E0658." "" { target *-*-* } } + let A(B | C); // { dg-error ".E0658." "" { target *-*-* } } + let E::V(B | C); // { dg-error ".E0658." "" { target *-*-* } } + let S { f1: B | C, f2 }; // { dg-error ".E0658." "" { target *-*-* } } + let E::V { f1: B | C, f2 }; // { dg-error ".E0658." "" { target *-*-* } } + let [A | B]; // { dg-error ".E0658." "" { target *-*-* } } + + // Top level of `while`, `if`, and `match` arms are allowed: + + while let | A = 0 {} + while let A | B = 0 {} + if let | A = 0 {} + if let A | B = 0 {} + match 0 { + | A => {}, + A | B => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/fn-param-wrap-parens.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/fn-param-wrap-parens.rs new file mode 100644 index 000000000000..57b05ae91572 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/fn-param-wrap-parens.rs @@ -0,0 +1,15 @@ +// Test the suggestion to wrap an or-pattern as a function parameter in parens. + +// run-rustfix + +#![feature(or_patterns)] +#![allow(warnings)] + +fn main() {} + +enum E { A, B } +use E::*; + +#[cfg(FALSE)] +fn fun1(A | B: E) {} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/for-loop.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/for-loop.rs new file mode 100644 index 000000000000..8d8fab94aca1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/for-loop.rs @@ -0,0 +1,19 @@ +// Check that or patterns are lowered correctly in `for` loops. +// run-pass + +#![feature(or_patterns)] + +fn main() { + let v = vec![Ok(2), Err(3), Ok(5)]; + let mut w = Vec::new(); + for &(Ok(i) | Err(i)) in &v { + w.push(i); + } + let mut u = Vec::new(); + for Ok(i) | Err(i) in v { + u.push(i); + } + assert_eq!(w, [2, 3, 5]); + assert_eq!(u, [2, 3, 5]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/if-let-while-let.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/if-let-while-let.rs new file mode 100644 index 000000000000..b5315118c27f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/if-let-while-let.rs @@ -0,0 +1,23 @@ +// Check that or patterns are lowered correctly in `if let` and `while let` expressions. +// run-pass + +#![feature(or_patterns)] + +fn main() { + let mut opt = Some(3); + let mut w = Vec::new(); + while let Some(ref mut val @ (3 | 4 | 6)) = opt { + w.push(*val); + *val += 1; + } + assert_eq!(w, [3, 4]); + if let &(None | Some(6 | 7)) = &opt { + unreachable!(); + } + if let Some(x @ (4 | 5 | 6)) = opt { + assert_eq!(x, 5); + } else { + unreachable!(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/inconsistent-modes.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/inconsistent-modes.rs new file mode 100644 index 000000000000..c9560be3eb46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/inconsistent-modes.rs @@ -0,0 +1,27 @@ +// This test ensures that or patterns require binding mode consistency across arms. + +#![feature(or_patterns)] +#![allow(non_camel_case_types)] +fn main() { + // One level: + let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0); +// { dg-error ".E0409." "" { target *-*-* } .-1 } + let Ok(ref mut a) | Err(a): Result = Ok(0); +// { dg-error ".E0409." "" { target *-*-* } .-1 } + let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + + // Two levels: + let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0); +// { dg-error ".E0409." "" { target *-*-* } .-1 } + + // Three levels: + let Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a) = Err(&1); +// { dg-error ".E0409." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/issue-64879-trailing-before-guard.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/issue-64879-trailing-before-guard.rs new file mode 100644 index 000000000000..259302f0407c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/issue-64879-trailing-before-guard.rs @@ -0,0 +1,16 @@ +// In this regression test we check that a trailing `|` in an or-pattern just +// before the `if` token of a `match` guard will receive parser recovery with +// an appropriate error message. + +enum E { A, B } + +fn main() { + match E::A { + E::A | + E::B | // { dg-error "" "" { target *-*-* } } + if true => { + let recovery_witness: bool = 0; // { dg-error ".E0308." "" { target *-*-* } } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/issue-67514-irrefutable-param.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/issue-67514-irrefutable-param.rs new file mode 100644 index 000000000000..d234857d94ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/issue-67514-irrefutable-param.rs @@ -0,0 +1,12 @@ +// Check that we don't ICE for irrefutable or-patterns in function parameters + +// check-pass + +#![feature(or_patterns)] + +fn foo((Some(_) | None): Option) {} + +fn main() { + foo(None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/issue-68785-irrefutable-param-with-at.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/issue-68785-irrefutable-param-with-at.rs new file mode 100644 index 000000000000..575ec125ad8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/issue-68785-irrefutable-param-with-at.rs @@ -0,0 +1,15 @@ +// check-pass + +#![feature(or_patterns)] + +enum MyEnum { + FirstCase(u8), + OtherCase(u16), +} + +fn my_fn(x @ (MyEnum::FirstCase(_) | MyEnum::OtherCase(_)): MyEnum) {} + +fn main() { + my_fn(MyEnum::FirstCase(0)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs new file mode 100644 index 000000000000..b53976eba77c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs @@ -0,0 +1,10 @@ +#![feature(or_patterns)] + +fn main() { + let 0 | (1 | 2) = 0; // { dg-error ".E0005." "" { target *-*-* } } + match 0 { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + 0 | (1 | 2) => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs new file mode 100644 index 000000000000..1bd4adf6151c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs @@ -0,0 +1,10 @@ +// check-pass + +#![feature(or_patterns)] + +fn main() { + let 0 | (1 | _) = 0; + if let 0 | (1 | 2) = 0 {} + if let x @ 0 | x @ (1 | 2) = 0 {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs new file mode 100644 index 000000000000..d67e640d83bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/issue-70413-no-unreachable-pat-and-guard.rs @@ -0,0 +1,23 @@ +// check-pass + +#![deny(unreachable_patterns)] + +#![feature(or_patterns)] +fn main() { + match (3,42) { + (a,_) | (_,a) if a > 10 => {println!("{}", a)} + _ => () + } + + match Some((3,42)) { + Some((a, _)) | Some((_, a)) if a > 10 => {println!("{}", a)} + _ => () + + } + + match Some((3,42)) { + Some((a, _) | (_, a)) if a > 10 => {println!("{}", a)} + _ => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/let-pattern.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/let-pattern.rs new file mode 100644 index 000000000000..708bc9c74973 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/let-pattern.rs @@ -0,0 +1,20 @@ +#![feature(or_patterns)] + +// run-pass + +fn or_pat_let(x: Result) -> u32 { + let Ok(y) | Err(y) = x; + y +} + +fn or_pat_arg((Ok(y) | Err(y)): Result) -> u32 { + y +} + +fn main() { + assert_eq!(or_pat_let(Ok(3)), 3); + assert_eq!(or_pat_let(Err(5)), 5); + assert_eq!(or_pat_arg(Ok(7)), 7); + assert_eq!(or_pat_arg(Err(9)), 9); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/mismatched-bindings-async-fn.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/mismatched-bindings-async-fn.rs new file mode 100644 index 000000000000..c51e3b1d8921 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/mismatched-bindings-async-fn.rs @@ -0,0 +1,17 @@ +// Regression test for #71297 +// edition:2018 + +#![feature(or_patterns)] + +async fn a((x | s): String) {} +// { dg-error ".E0408." "" { target *-*-* } .-1 } +// { dg-error ".E0408." "" { target *-*-* } .-2 } + +async fn b() { + let x | s = String::new(); +// { dg-error ".E0408." "" { target *-*-* } .-1 } +// { dg-error ".E0408." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/missing-bindings.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/missing-bindings.rs new file mode 100644 index 000000000000..708d37ac4f2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/missing-bindings.rs @@ -0,0 +1,83 @@ +// This test ensures that or patterns do not allow missing bindings in any of the arms. + +// edition:2018 + +#![feature(or_patterns)] +#![allow(non_camel_case_types)] + +fn main() {} + +fn check_handling_of_paths() { + mod bar { + pub enum foo { + alpha, + beta, + charlie + } + } + + use bar::foo::{alpha, charlie}; + let alpha | beta | charlie = alpha; // { dg-error ".E0408." "" { target *-*-* } } + match Some(alpha) { + Some(alpha | beta) => {} // { dg-error ".E0408." "" { target *-*-* } } + } +} + +fn check_misc_nesting() { + enum E { A(T, T), B(T) } + use E::*; + enum Vars3 { V1(S), V2(T), V3(U) } + use Vars3::*; + + // One level: + const X: E = B(0); + let A(a, _) | _ = X; // { dg-error ".E0408." "" { target *-*-* } } + let _ | B(a) = X; // { dg-error ".E0408." "" { target *-*-* } } + let A(..) | B(a) = X; // { dg-error ".E0408." "" { target *-*-* } } + let A(a, _) | B(_) = X; // { dg-error ".E0408." "" { target *-*-* } } + let A(_, a) | B(_) = X; // { dg-error ".E0408." "" { target *-*-* } } + let A(a, b) | B(a) = X; // { dg-error ".E0408." "" { target *-*-* } } + + // Two levels: + const Y: E> = B(B(0)); + let A(A(..) | B(_), _) | B(a) = Y; // { dg-error ".E0408." "" { target *-*-* } } + let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y; +// { dg-error ".E0408." "" { target *-*-* } .-1 } + let A(A(a, b) | B(c), d) | B(e) = Y; +// { dg-error ".E0408." "" { target *-*-* } .-1 } +// { dg-error ".E0408." "" { target *-*-* } .-2 } +// { dg-error ".E0408." "" { target *-*-* } .-3 } +// { dg-error ".E0408." "" { target *-*-* } .-4 } +// { dg-error ".E0408." "" { target *-*-* } .-5 } +// { dg-error ".E0408." "" { target *-*-* } .-6 } +// { dg-error ".E0408." "" { target *-*-* } .-7 } +// { dg-error ".E0408." "" { target *-*-* } .-8 } + + // Three levels: + let ( + V1( +// { dg-error ".E0408." "" { target *-*-* } .-1 } +// { dg-error ".E0408." "" { target *-*-* } .-2 } + A( + Ok(a) | Err(_), // { dg-error ".E0408." "" { target *-*-* } } + _ + ) | + B(Ok(a) | Err(a)) + ) | + V2( + A( + A(_, a) | // { dg-error ".E0408." "" { target *-*-* } } + B(b), // { dg-error ".E0408." "" { target *-*-* } } + _ + ) | + B(_) +// { dg-error ".E0408." "" { target *-*-* } .-1 } +// { dg-error ".E0408." "" { target *-*-* } .-2 } + ) | + V3(c), +// { dg-error ".E0408." "" { target *-*-* } .-1 } + ) + : (Vars3>, E>, u8>,) + = (V3(0),); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/mix-with-wild.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/mix-with-wild.rs new file mode 100644 index 000000000000..09db23c43fd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/mix-with-wild.rs @@ -0,0 +1,20 @@ +// Test that an or-pattern works with a wild pattern. This tests two things: +// +// 1) The Wild pattern should cause the pattern to always succeed. +// 2) or-patterns should work with simplifyable patterns. + +// run-pass +#![feature(or_patterns)] + +pub fn test(x: Option) -> bool { + match x { + Some(0 | _) => true, + _ => false, + } +} + +fn main() { + assert!(test(Some(42))); + assert!(!test(None)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/multiple-pattern-typo.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/multiple-pattern-typo.rs new file mode 100644 index 000000000000..c828eb166892 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/multiple-pattern-typo.rs @@ -0,0 +1,45 @@ +#![feature(or_patterns)] + +fn main() { + let x = 3; + + match x { + 1 | 2 || 3 => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + + match x { + (1 | 2 || 3) => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + + match (x,) { + (1 | 2 || 3,) => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + + struct TS(u8); + + match TS(x) { + TS(1 | 2 || 3) => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + + struct NS { f: u8 } + + match (NS { f: x }) { + NS { f: 1 | 2 || 3 } => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + + match [x] { + [1 | 2 || 3] => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + + match x { + || 1 | 2 | 3 => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-binding-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-binding-type-mismatch.rs new file mode 100644 index 000000000000..f4d96faef585 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-binding-type-mismatch.rs @@ -0,0 +1,69 @@ +// Here we test type checking of bindings when combined with or-patterns. +// Specifically, we ensure that introducing bindings of different types result in type errors. + +#![feature(or_patterns)] + +fn main() { + enum Blah { + A(isize, isize, usize), + B(isize, isize), + } + + match Blah::A(1, 1, 2) { + Blah::A(_, x, y) | Blah::B(x, y) => {} // { dg-error ".E0308." "" { target *-*-* } } + } + + match Some(Blah::A(1, 1, 2)) { + Some(Blah::A(_, x, y) | Blah::B(x, y)) => {} // { dg-error ".E0308." "" { target *-*-* } } + } + + match (0u8, 1u16) { + (x, y) | (y, x) => {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } + + match Some((0u8, Some((1u16, 2u32)))) { + Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) => {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + _ => {} + } + + if let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2) { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } + + if let Some(Blah::A(_, x, y) | Blah::B(x, y)) = Some(Blah::A(1, 1, 2)) { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } + + if let (x, y) | (y, x) = (0u8, 1u16) { +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } + + if let Some((x, Some((y, z)))) | Some((y, Some((x, z) | (z, x)))) +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + = Some((0u8, Some((1u16, 2u32)))) + {} + + let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + let (x, y) | (y, x) = (0u8, 1u16); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + fn f1((Blah::A(_, x, y) | Blah::B(x, y)): Blah) {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + fn f2(((x, y) | (y, x)): (u8, u16)) {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-default-binding-modes.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-default-binding-modes.rs new file mode 100644 index 000000000000..5cceaa7d0d30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-default-binding-modes.rs @@ -0,0 +1,133 @@ +// Test that or-patterns are pass-through with respect to default binding modes. + +// check-pass + +#![feature(or_patterns)] +#![allow(irrefutable_let_patterns)] + +fn main() { + // A regression test for a mistake we made at one point: + match &1 { + e @ &(1..=2) | e @ &(3..=4) => {} + _ => {} + } + + match &0 { + 0 | &1 => {} + _ => {} + } + + type R<'a> = &'a Result; + + let res: R<'_> = &Ok(0); + + match res { + // Alternatives propagate expected type / binding mode independently. + Ok(mut x) | &Err(mut x) => drop::(x), + } + match res { + &(Ok(x) | Err(x)) => drop::(x), + } + match res { + Ok(x) | Err(x) => drop::<&u8>(x), + } + if let Ok(mut x) | &Err(mut x) = res { + drop::(x); + } + if let &(Ok(x) | Err(x)) = res { + drop::(x); + } + let Ok(mut x) | &Err(mut x) = res; + drop::(x); + let &(Ok(x) | Err(x)) = res; + drop::(x); + let Ok(x) | Err(x) = res; + drop::<&u8>(x); + for Ok(mut x) | &Err(mut x) in std::iter::once(res) { + drop::(x); + } + for &(Ok(x) | Err(x)) in std::iter::once(res) { + drop::(x); + } + for Ok(x) | Err(x) in std::iter::once(res) { + drop::<&u8>(x); + } + fn f1((Ok(mut x) | &Err(mut x)): R<'_>) { + drop::(x); + } + fn f2(&(Ok(x) | Err(x)): R<'_>) { + drop::(x); + } + fn f3((Ok(x) | Err(x)): R<'_>) { + drop::<&u8>(x); + } + + // Wrap inside another type (a product for a simplity with irrefutable contexts). + #[derive(Copy, Clone)] + struct Wrap(T); + let wres = Wrap(res); + + match wres { + Wrap(Ok(mut x) | &Err(mut x)) => drop::(x), + } + match wres { + Wrap(&(Ok(x) | Err(x))) => drop::(x), + } + match wres { + Wrap(Ok(x) | Err(x)) => drop::<&u8>(x), + } + if let Wrap(Ok(mut x) | &Err(mut x)) = wres { + drop::(x); + } + if let Wrap(&(Ok(x) | Err(x))) = wres { + drop::(x); + } + if let Wrap(Ok(x) | Err(x)) = wres { + drop::<&u8>(x); + } + let Wrap(Ok(mut x) | &Err(mut x)) = wres; + drop::(x); + let Wrap(&(Ok(x) | Err(x))) = wres; + drop::(x); + let Wrap(Ok(x) | Err(x)) = wres; + drop::<&u8>(x); + for Wrap(Ok(mut x) | &Err(mut x)) in std::iter::once(wres) { + drop::(x); + } + for Wrap(&(Ok(x) | Err(x))) in std::iter::once(wres) { + drop::(x); + } + for Wrap(Ok(x) | Err(x)) in std::iter::once(wres) { + drop::<&u8>(x); + } + fn fw1(Wrap(Ok(mut x) | &Err(mut x)): Wrap>) { + drop::(x); + } + fn fw2(Wrap(&(Ok(x) | Err(x))): Wrap>) { + drop::(x); + } + fn fw3(Wrap(Ok(x) | Err(x)): Wrap>) { + drop::<&u8>(x); + } + + // Nest some more: + + enum Tri

{ + A(P), + B(P), + C(P), + } + + let tri = &Tri::A(&Ok(0)); + let Tri::A(Ok(mut x) | Err(mut x)) + | Tri::B(&Ok(mut x) | Err(mut x)) + | &Tri::C(Ok(mut x) | Err(mut x)) = tri; + drop::(x); + + match tri { + Tri::A(Ok(mut x) | Err(mut x)) + | Tri::B(&Ok(mut x) | Err(mut x)) + | &Tri::C(Ok(mut x) | Err(mut x)) => drop::(x), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-syntactic-fail.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-syntactic-fail.rs new file mode 100644 index 000000000000..bc54f6f9d616 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-syntactic-fail.rs @@ -0,0 +1,53 @@ +// Test some cases where or-patterns may ostensibly be allowed but are in fact not. +// This is not a semantic test. We only test parsing. + +#![feature(or_patterns)] + +fn main() {} + +// Test the `pat` macro fragment parser: +macro_rules! accept_pat { + ($p:pat) => {} +} + +accept_pat!(p | q); // { dg-error "" "" { target *-*-* } } +accept_pat!(| p | q); // { dg-error "" "" { target *-*-* } } + +// Non-macro tests: + +enum E { A, B } +use E::*; + +fn no_top_level_or_patterns() { + // We do *not* allow or-patterns at the top level of lambdas... + let _ = |A | B: E| (); // { dg-error ".E0369." "" { target *-*-* } } + // -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`. + + // ...and for now neither do we allow or-patterns at the top level of functions. + fn fun1(A | B: E) {} // { dg-error "" "" { target *-*-* } } + + fn fun2(| A | B: E) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +// We also do not allow a leading `|` when not in a top level position: + +fn no_leading_inner() { + struct TS(E); + struct NS { f: E } + + let ( | A | B) = E::A; // { dg-error "" "" { target *-*-* } } + let ( | A | B,) = (E::B,); // { dg-error "" "" { target *-*-* } } + let [ | A | B ] = [E::A]; // { dg-error "" "" { target *-*-* } } + let TS( | A | B ); // { dg-error "" "" { target *-*-* } } + let NS { f: | A | B }; // { dg-error "" "" { target *-*-* } } + + let ( || A | B) = E::A; // { dg-error "" "" { target *-*-* } } + let [ || A | B ] = [E::A]; // { dg-error "" "" { target *-*-* } } + let TS( || A | B ); // { dg-error "" "" { target *-*-* } } + let NS { f: || A | B }; // { dg-error "" "" { target *-*-* } } + + let recovery_witness: String = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-syntactic-pass.rs new file mode 100644 index 000000000000..cba37c69fdc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/or-patterns-syntactic-pass.rs @@ -0,0 +1,79 @@ +// Here we test all the places `|` is *syntactically* allowed. +// This is not a semantic test. We only test parsing. + +// check-pass + +#![feature(or_patterns)] + +fn main() {} + +// Test the `pat` macro fragment parser: +macro_rules! accept_pat { + ($p:pat) => {} +} + +accept_pat!((p | q)); +accept_pat!((p | q,)); +accept_pat!(TS(p | q)); +accept_pat!(NS { f: p | q }); +accept_pat!([p | q]); + +// Non-macro tests: + +#[cfg(FALSE)] +fn or_patterns() { + // Top level of `let`: + let | A | B; + let A | B; + let A | B: u8; + let A | B = 0; + let A | B: u8 = 0; + + // Top level of `for`: + for | A | B in 0 {} + for A | B in 0 {} + + // Top level of `while`: + while let | A | B = 0 {} + while let A | B = 0 {} + + // Top level of `if`: + if let | A | B = 0 {} + if let A | B = 0 {} + + // Top level of `match` arms: + match 0 { + | A | B => {}, + A | B => {}, + } + + // Functions: + fn fun((A | B): _) {} + + // Lambdas: + let _ = |(A | B): u8| (); + + // Parenthesis and tuple patterns: + let (A | B); + let (A | B,); + + // Tuple struct patterns: + let A(B | C); + let E::V(B | C); + + // Struct patterns: + let S { f1: B | C, f2 }; + let E::V { f1: B | C, f2 }; + + // Slice patterns: + let [A | B, .. | ..]; + + // These bind as `(prefix p) | q` as opposed to `prefix (p | q)`: + let box 0 | 1; // Unstable; we *can* the precedence if we want. + let &0 | 1; + let &mut 0 | 1; + let x @ 0 | 1; + let ref x @ 0 | 1; + let ref mut x @ 0 | 1; +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/remove-leading-vert.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/remove-leading-vert.rs new file mode 100644 index 000000000000..a3cae6185b93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/remove-leading-vert.rs @@ -0,0 +1,47 @@ +// Test the suggestion to remove a leading, or trailing `|`. + +// run-rustfix + +#![feature(or_patterns)] +#![allow(warnings)] + +fn main() {} + +#[cfg(FALSE)] +fn leading() { + fn fun1( | A: E) {} // { dg-error "" "" { target *-*-* } } + fn fun2( || A: E) {} // { dg-error "" "" { target *-*-* } } + let ( | A): E; // { dg-error "" "" { target *-*-* } } + let ( || A): (E); // { dg-error "" "" { target *-*-* } } + let ( | A,): (E,); // { dg-error "" "" { target *-*-* } } + let [ | A ]: [E; 1]; // { dg-error "" "" { target *-*-* } } + let [ || A ]: [E; 1]; // { dg-error "" "" { target *-*-* } } + let TS( | A ): TS; // { dg-error "" "" { target *-*-* } } + let TS( || A ): TS; // { dg-error "" "" { target *-*-* } } + let NS { f: | A }: NS; // { dg-error "" "" { target *-*-* } } + let NS { f: || A }: NS; // { dg-error "" "" { target *-*-* } } +} + +#[cfg(FALSE)] +fn trailing() { + let ( A | ): E; // { dg-error "" "" { target *-*-* } } + let (a |,): (E,); // { dg-error "" "" { target *-*-* } } + let ( A | B | ): E; // { dg-error "" "" { target *-*-* } } + let [ A | B | ]: [E; 1]; // { dg-error "" "" { target *-*-* } } + let S { f: B | }; // { dg-error "" "" { target *-*-* } } + let ( A || B | ): E; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + match A { + A | => {} // { dg-error "" "" { target *-*-* } } + A || => {} // { dg-error "" "" { target *-*-* } } + A || B | => {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + | A | B | => {} +// { dg-error "" "" { target *-*-* } .-1 } + } + + let a | : u8 = 0; // { dg-error "" "" { target *-*-* } } + let a | = 0; // { dg-error "" "" { target *-*-* } } + let a | ; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/search-via-bindings.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/search-via-bindings.rs new file mode 100644 index 000000000000..d5946b5f0ce6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/search-via-bindings.rs @@ -0,0 +1,66 @@ +// Check that we expand multiple or-patterns from left to right. + +// run-pass + +#![feature(or_patterns)] + +fn search(target: (bool, bool, bool)) -> u32 { + let x = ((false, true), (false, true), (false, true)); + let mut guard_count = 0; + match x { + ((a, _) | (_, a), (b @ _, _) | (_, b @ _), (c @ false, _) | (_, c @ true)) + if { + guard_count += 1; + (a, b, c) == target + } => + { + guard_count + } + _ => unreachable!(), + } +} + +// Equivalent to the above code, but hopefully easier to understand. +fn search_old_style(target: (bool, bool, bool)) -> u32 { + let x = ((false, true), (false, true), (false, true)); + let mut guard_count = 0; + match x { + ((a, _), (b @ _, _), (c @ false, _)) + | ((a, _), (b @ _, _), (_, c @ true)) + | ((a, _), (_, b @ _), (c @ false, _)) + | ((a, _), (_, b @ _), (_, c @ true)) + | ((_, a), (b @ _, _), (c @ false, _)) + | ((_, a), (b @ _, _), (_, c @ true)) + | ((_, a), (_, b @ _), (c @ false, _)) + | ((_, a), (_, b @ _), (_, c @ true)) + if { + guard_count += 1; + (a, b, c) == target + } => + { + guard_count + } + _ => unreachable!(), + } +} + +fn main() { + assert_eq!(search((false, false, false)), 1); + assert_eq!(search((false, false, true)), 2); + assert_eq!(search((false, true, false)), 3); + assert_eq!(search((false, true, true)), 4); + assert_eq!(search((true, false, false)), 5); + assert_eq!(search((true, false, true)), 6); + assert_eq!(search((true, true, false)), 7); + assert_eq!(search((true, true, true)), 8); + + assert_eq!(search_old_style((false, false, false)), 1); + assert_eq!(search_old_style((false, false, true)), 2); + assert_eq!(search_old_style((false, true, false)), 3); + assert_eq!(search_old_style((false, true, true)), 4); + assert_eq!(search_old_style((true, false, false)), 5); + assert_eq!(search_old_style((true, false, true)), 6); + assert_eq!(search_old_style((true, true, false)), 7); + assert_eq!(search_old_style((true, true, true)), 8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/slice-patterns.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/slice-patterns.rs new file mode 100644 index 000000000000..e7295be9a0c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/slice-patterns.rs @@ -0,0 +1,54 @@ +// Test or-patterns with slice-patterns + +// run-pass + +#![feature(or_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +#[derive(Debug)] +enum Test { + Foo, + Bar, + Baz, + Qux, +} + +fn test(foo: &[Option]) -> MatchArm { + match foo { + [.., Some(Test::Qux | Test::Foo)] => MatchArm::Arm(0), + [Some(Test::Foo), .., Some(Test::Baz | Test::Bar)] => MatchArm::Arm(1), + [.., Some(Test::Bar | Test::Baz), _] => MatchArm::Arm(2), + _ => MatchArm::Wild, + } +} + +fn main() { + let foo = vec![ + Some(Test::Foo), + Some(Test::Bar), + Some(Test::Baz), + Some(Test::Qux), + ]; + + // path 1a + assert_eq!(test(&foo), MatchArm::Arm(0)); + // path 1b + assert_eq!(test(&[Some(Test::Bar), Some(Test::Foo)]), MatchArm::Arm(0)); + // path 2a + assert_eq!(test(&foo[..3]), MatchArm::Arm(1)); + // path 2b + assert_eq!(test(&[Some(Test::Foo), Some(Test::Foo), Some(Test::Bar)]), MatchArm::Arm(1)); + // path 3a + assert_eq!(test(&foo[1..3]), MatchArm::Arm(2)); + // path 3b + assert_eq!(test(&[Some(Test::Bar), Some(Test::Baz), Some(Test::Baz), Some(Test::Bar)]), + MatchArm::Arm(2)); + // path 4 + assert_eq!(test(&foo[4..]), MatchArm::Wild); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/struct-like.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/struct-like.rs new file mode 100644 index 000000000000..2d4bde0d05ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/struct-like.rs @@ -0,0 +1,43 @@ +// run-pass + +#![feature(or_patterns)] + +#[derive(Debug)] +enum Other { + One, + Two, + Three, +} + +#[derive(Debug)] +enum Test { + Foo { first: usize, second: usize }, + Bar { other: Option }, + Baz, +} + +fn test(x: Option) -> bool { + match x { + Some( + Test::Foo { first: 1024 | 2048, second: 2048 | 4096 } + | Test::Bar { other: Some(Other::One | Other::Two) }, + ) => true, + // wild case + Some(_) => false, + // empty case + None => false, + } +} + +fn main() { + assert!(test(Some(Test::Foo { first: 1024, second: 4096 }))); + assert!(!test(Some(Test::Foo { first: 2048, second: 8192 }))); + assert!(!test(Some(Test::Foo { first: 42, second: 2048 }))); + assert!(test(Some(Test::Bar { other: Some(Other::One) }))); + assert!(test(Some(Test::Bar { other: Some(Other::Two) }))); + assert!(!test(Some(Test::Bar { other: Some(Other::Three) }))); + assert!(!test(Some(Test::Bar { other: None }))); + assert!(!test(Some(Test::Baz))); + assert!(!test(None)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/or-patterns/while-parsing-this-or-pattern.rs b/gcc/testsuite/rust/rustc/ui/or-patterns/while-parsing-this-or-pattern.rs new file mode 100644 index 000000000000..38e62dc3b085 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/or-patterns/while-parsing-this-or-pattern.rs @@ -0,0 +1,10 @@ +// Test the parser for the "while parsing this or-pattern..." label here. + +fn main() { + match Some(42) { + Some(42) | .=. => {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/order-dependent-cast-inference.rs b/gcc/testsuite/rust/rustc/ui/order-dependent-cast-inference.rs new file mode 100644 index 000000000000..c9feea619517 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/order-dependent-cast-inference.rs @@ -0,0 +1,9 @@ +fn main() { + // Tests case where inference fails due to the order in which casts are checked. + // Ideally this would compile, see #48270. + let x = &"hello"; + let mut y = 0 as *const _; +// { dg-error ".E0641." "" { target *-*-* } .-1 } + y = x as *const _; +} + diff --git a/gcc/testsuite/rust/rustc/ui/orphan-check-diagnostics.rs b/gcc/testsuite/rust/rustc/ui/orphan-check-diagnostics.rs new file mode 100644 index 000000000000..112dbd72b67f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/orphan-check-diagnostics.rs @@ -0,0 +1,15 @@ +// aux-build:orphan-check-diagnostics.rs + +// See issue #22388. + +extern crate orphan_check_diagnostics; + +use orphan_check_diagnostics::RemoteTrait; + +trait LocalTrait { fn dummy(&self) { } } + +impl RemoteTrait for T where T: LocalTrait {} +// { dg-error ".E0210." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/osx-frameworks.rs b/gcc/testsuite/rust/rustc/ui/osx-frameworks.rs new file mode 100644 index 000000000000..f57f7ac72feb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/osx-frameworks.rs @@ -0,0 +1,9 @@ +// ignore-macos this is supposed to succeed on osx + +#[link(name = "foo", kind = "framework")] +extern {} +// { dg-error ".E0455." "" { target *-*-* } .-2 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/out-of-order-shadowing.rs b/gcc/testsuite/rust/rustc/ui/out-of-order-shadowing.rs new file mode 100644 index 000000000000..71e21cc2d2cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/out-of-order-shadowing.rs @@ -0,0 +1,11 @@ +// aux-build:define-macro.rs + +macro_rules! bar { () => {} } +define_macro!(bar); +bar!(); // { dg-error ".E0659." "" { target *-*-* } } + +macro_rules! m { () => { #[macro_use] extern crate define_macro; } } +m!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/out-of-stack.rs b/gcc/testsuite/rust/rustc/ui/out-of-stack.rs new file mode 100644 index 000000000000..34c4a54dad69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/out-of-stack.rs @@ -0,0 +1,90 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(unconditional_recursion)] +// ignore-android: FIXME (#20004) +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +#![feature(llvm_asm)] +#![feature(rustc_private)] + +#[cfg(unix)] +extern crate libc; + +use std::env; +use std::process::Command; +use std::thread; + +// lifted from the test module +// Inlining to avoid llvm turning the recursive functions into tail calls, +// which doesn't consume stack. +#[inline(always)] +pub fn black_box(dummy: T) { unsafe { llvm_asm!("" : : "r"(&dummy)) } } + +fn silent_recurse() { + let buf = [0u8; 1000]; + black_box(buf); + silent_recurse(); +} + +fn loud_recurse() { + println!("hello!"); + loud_recurse(); + black_box(()); // don't optimize this into a tail call. please. +} + +#[cfg(unix)] +fn check_status(status: std::process::ExitStatus) +{ + use std::os::unix::process::ExitStatusExt; + + assert!(!status.success()); + assert_eq!(status.signal(), Some(libc::SIGABRT)); +} + +#[cfg(not(unix))] +fn check_status(status: std::process::ExitStatus) +{ + assert!(!status.success()); +} + + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "silent" { + silent_recurse(); + } else if args.len() > 1 && args[1] == "loud" { + loud_recurse(); + } else if args.len() > 1 && args[1] == "silent-thread" { + thread::spawn(silent_recurse).join(); + } else if args.len() > 1 && args[1] == "loud-thread" { + thread::spawn(loud_recurse).join(); + } else { + let mut modes = vec![ + "silent-thread", + "loud-thread", + ]; + + // On linux it looks like the main thread can sometimes grow its stack + // basically without bounds, so we only test the child thread cases + // there. + if !cfg!(target_os = "linux") { + modes.push("silent"); + modes.push("loud"); + } + for mode in modes { + println!("testing: {}", mode); + + let silent = Command::new(&args[0]).arg(mode).output().unwrap(); + + check_status(silent.status); + + let error = String::from_utf8_lossy(&silent.stderr); + assert!(error.contains("has overflowed its stack"), + "missing overflow message: {}", error); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/out-pointer-aliasing.rs b/gcc/testsuite/rust/rustc/ui/out-pointer-aliasing.rs new file mode 100644 index 000000000000..ce9eaa495163 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/out-pointer-aliasing.rs @@ -0,0 +1,24 @@ +// run-pass + +#[derive(Copy, Clone)] +pub struct Foo { + f1: isize, + _f2: isize, +} + +#[inline(never)] +pub fn foo(f: &mut Foo) -> Foo { + let ret = *f; + f.f1 = 0; + ret +} + +pub fn main() { + let mut f = Foo { + f1: 8, + _f2: 9, + }; + f = foo(&mut f); + assert_eq!(f.f1, 8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/output-slot-variants.rs b/gcc/testsuite/rust/rustc/ui/output-slot-variants.rs new file mode 100644 index 000000000000..60f53bf3d4e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/output-slot-variants.rs @@ -0,0 +1,71 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_assignments)] +#![allow(unknown_lints)] +// pretty-expanded FIXME #23616 + +#![allow(dead_assignment)] +#![allow(unused_variables)] +#![feature(box_syntax)] + +struct A { a: isize, b: isize } +struct Abox { a: Box, b: Box } + +fn ret_int_i() -> isize { 10 } + +fn ret_ext_i() -> Box { box 10 } + +fn ret_int_rec() -> A { A {a: 10, b: 10} } + +fn ret_ext_rec() -> Box { box A {a: 10, b: 10} } + +fn ret_ext_mem() -> Abox { Abox {a: box 10, b: box 10} } + +fn ret_ext_ext_mem() -> Box { box Abox{a: box 10, b: box 10} } + +pub fn main() { + let mut int_i: isize; + let mut ext_i: Box; + let mut int_rec: A; + let mut ext_rec: Box; + let mut ext_mem: Abox; + let mut ext_ext_mem: Box; + int_i = ret_int_i(); // initializing + + int_i = ret_int_i(); // non-initializing + + int_i = ret_int_i(); // non-initializing + + ext_i = ret_ext_i(); // initializing + + ext_i = ret_ext_i(); // non-initializing + + ext_i = ret_ext_i(); // non-initializing + + int_rec = ret_int_rec(); // initializing + + int_rec = ret_int_rec(); // non-initializing + + int_rec = ret_int_rec(); // non-initializing + + ext_rec = ret_ext_rec(); // initializing + + ext_rec = ret_ext_rec(); // non-initializing + + ext_rec = ret_ext_rec(); // non-initializing + + ext_mem = ret_ext_mem(); // initializing + + ext_mem = ret_ext_mem(); // non-initializing + + ext_mem = ret_ext_mem(); // non-initializing + + ext_ext_mem = ret_ext_ext_mem(); // initializing + + ext_ext_mem = ret_ext_ext_mem(); // non-initializing + + ext_ext_mem = ret_ext_ext_mem(); // non-initializing + +} + diff --git a/gcc/testsuite/rust/rustc/ui/output-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/output-type-mismatch.rs new file mode 100644 index 000000000000..177738fe2db0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/output-type-mismatch.rs @@ -0,0 +1,6 @@ +// error-pattern: mismatched types + +fn f() { } + +fn main() { let i: isize; i = f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/over-constrained-vregs.rs b/gcc/testsuite/rust/rustc/ui/over-constrained-vregs.rs new file mode 100644 index 000000000000..7d6c4d3d84de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/over-constrained-vregs.rs @@ -0,0 +1,13 @@ +// run-pass + +#![allow(unused_must_use)] +// Regression test for issue #152. +pub fn main() { + let mut b: usize = 1_usize; + while b < std::mem::size_of::() { + 0_usize << b; + b <<= 1_usize; + println!("{}", b); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/overlap-doesnt-conflict-with-specialization.rs b/gcc/testsuite/rust/rustc/ui/overlap-doesnt-conflict-with-specialization.rs new file mode 100644 index 000000000000..b6883aef405c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overlap-doesnt-conflict-with-specialization.rs @@ -0,0 +1,21 @@ +// run-pass + +#![feature(marker_trait_attr)] +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +#[marker] +trait MyMarker {} + +impl MyMarker for T {} +impl MyMarker for Vec {} + +fn foo(t: T) -> T { + t +} + +fn main() { + assert_eq!(1, foo(1)); + assert_eq!(2.0, foo(2.0)); + assert_eq!(vec![1], foo(vec![1])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overlap-permitted-for-annotated-marker-traits.rs b/gcc/testsuite/rust/rustc/ui/overlap-permitted-for-annotated-marker-traits.rs new file mode 100644 index 000000000000..66d845d586eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overlap-permitted-for-annotated-marker-traits.rs @@ -0,0 +1,27 @@ +// run-pass +// Tests for RFC 1268: we allow overlapping impls of marker traits, +// that is, traits with #[marker]. In this case, a type `T` is +// `MyMarker` if it is either `Debug` or `Display`. + +#![feature(marker_trait_attr)] + +use std::fmt::{Debug, Display}; + +#[marker] trait MyMarker {} + +impl MyMarker for T {} +impl MyMarker for T {} + +fn foo(t: T) -> T { + t +} + +fn main() { + // Debug && Display: + assert_eq!(1, foo(1)); + assert_eq!(2.0, foo(2.0)); + + // Debug && !Display: + assert_eq!(vec![1], foo(vec![1])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded-calls-nontuple.rs b/gcc/testsuite/rust/rustc/ui/overloaded-calls-nontuple.rs new file mode 100644 index 000000000000..6b5120c5697f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded-calls-nontuple.rs @@ -0,0 +1,28 @@ +#![feature(fn_traits, unboxed_closures)] + +use std::ops::FnMut; + +struct S { + x: isize, + y: isize, +} + +impl FnMut for S { + extern "rust-call" fn call_mut(&mut self, z: isize) -> isize { + self.x + self.y + z + } +} + +impl FnOnce for S { + type Output = isize; + extern "rust-call" fn call_once(mut self, z: isize) -> isize { self.call_mut(z) } +} + +fn main() { + let mut s = S { + x: 1, + y: 2, + }; + drop(s(3)) // { dg-error ".E0059." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/auxiliary/overloaded_autoderef_xc.rs b/gcc/testsuite/rust/rustc/ui/overloaded/auxiliary/overloaded_autoderef_xc.rs new file mode 100644 index 000000000000..219e3e585d0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/auxiliary/overloaded_autoderef_xc.rs @@ -0,0 +1,31 @@ +use std::ops::Deref; + +struct DerefWithHelper { + pub helper: H, + pub value: Option +} + +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() + } +} + +// Test cross-crate autoderef + vtable. +pub fn check(x: T, y: T) -> bool { + let d: DerefWithHelper, T> = DerefWithHelper { helper: Some(x), value: None }; + d.eq(&y) +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-count.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-count.rs new file mode 100644 index 000000000000..fe72c7f70de0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-count.rs @@ -0,0 +1,75 @@ +// run-pass +use std::cell::Cell; +use std::ops::{Deref, DerefMut}; + +#[derive(PartialEq)] +struct DerefCounter { + count_imm: Cell, + count_mut: usize, + value: T +} + +impl DerefCounter { + fn new(value: T) -> DerefCounter { + DerefCounter { + count_imm: Cell::new(0), + count_mut: 0, + value: value + } + } + + fn counts(&self) -> (usize, usize) { + (self.count_imm.get(), self.count_mut) + } +} + +impl Deref for DerefCounter { + type Target = T; + + fn deref(&self) -> &T { + self.count_imm.set(self.count_imm.get() + 1); + &self.value + } +} + +impl DerefMut for DerefCounter { + fn deref_mut(&mut self) -> &mut T { + self.count_mut += 1; + &mut self.value + } +} + +#[derive(PartialEq, Debug)] +struct Point { + x: isize, + y: isize +} + +impl Point { + fn get(&self) -> (isize, isize) { + (self.x, self.y) + } +} + +pub fn main() { + let mut p = DerefCounter::new(Point {x: 0, y: 0}); + + let _ = p.x; + assert_eq!(p.counts(), (1, 0)); + + let _ = &p.x; + assert_eq!(p.counts(), (2, 0)); + + let _ = &mut p.y; + assert_eq!(p.counts(), (2, 1)); + + p.x += 3; + assert_eq!(p.counts(), (2, 2)); + + p.get(); + assert_eq!(p.counts(), (3, 2)); + + // Check the final state. + assert_eq!(*p, Point {x: 3, y: 0}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-indexing.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-indexing.rs new file mode 100644 index 000000000000..972a89ab6fd4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-indexing.rs @@ -0,0 +1,21 @@ +// run-pass + +use std::ops::Deref; + +struct DerefArray<'a, T:'a> { + inner: &'a [T] +} + +impl<'a, T> Deref for DerefArray<'a, T> { + type Target = &'a [T]; + + fn deref<'b>(&'b self) -> &'b &'a [T] { + &self.inner + } +} + +pub fn main() { + let a = &[1, 2, 3]; + assert_eq!(DerefArray {inner: a}[1], 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-order.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-order.rs new file mode 100644 index 000000000000..f7ba1f225cd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-order.rs @@ -0,0 +1,72 @@ +// run-pass + +use std::rc::Rc; +use std::ops::Deref; + +#[derive(Copy, Clone)] +struct DerefWrapper { + x: X, + y: Y +} + +impl DerefWrapper { + fn get_x(self) -> X { + self.x + } +} + +impl Deref for DerefWrapper { + type Target = Y; + + fn deref(&self) -> &Y { + &self.y + } +} + +mod priv_test { + use std::ops::Deref; + + #[derive(Copy, Clone)] + pub struct DerefWrapperHideX { + x: X, + pub y: Y + } + + impl DerefWrapperHideX { + pub fn new(x: X, y: Y) -> DerefWrapperHideX { + DerefWrapperHideX { + x: x, + y: y + } + } + } + + impl Deref for DerefWrapperHideX { + type Target = Y; + + fn deref(&self) -> &Y { + &self.y + } + } +} + +pub fn main() { + let nested = DerefWrapper {x: true, y: DerefWrapper {x: 0, y: 1}}; + + // Use the first field that you can find. + assert_eq!(nested.x, true); + assert_eq!((*nested).x, 0); + + // Same for methods, even though there are multiple + // candidates (at different nesting levels). + assert_eq!(nested.get_x(), true); + assert_eq!((*nested).get_x(), 0); + + // Also go through multiple levels of indirection. + assert_eq!(Rc::new(nested).x, true); + + let nested_priv = priv_test::DerefWrapperHideX::new(true, DerefWrapper {x: 0, y: 1}); + assert_eq!(nested_priv.x, 0); + assert_eq!((*nested_priv).x, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-vtable.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-vtable.rs new file mode 100644 index 000000000000..c4e7469785b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-vtable.rs @@ -0,0 +1,40 @@ +// run-pass +#![allow(dead_code)] + +use std::ops::Deref; + +struct DerefWithHelper { + helper: H, + value: T +} + +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() + } +} + +struct Foo {x: isize} + +impl Foo { + fn foo(&self) -> isize {self.x} +} + +pub fn main() { + let x: DerefWithHelper, Foo> = + DerefWithHelper { helper: Some(Foo {x: 5}), value: Foo { x: 2 } }; + assert_eq!(x.foo(), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-xcrate.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-xcrate.rs new file mode 100644 index 000000000000..b7f4cb7dc8d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef-xcrate.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:overloaded_autoderef_xc.rs + + +extern crate overloaded_autoderef_xc; + +fn main() { + assert!(overloaded_autoderef_xc::check(5, 5)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef.rs new file mode 100644 index 000000000000..70caf5a154fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-autoderef.rs @@ -0,0 +1,46 @@ +// run-pass +#![allow(unused_variables)] +#![allow(stable_features)] + +#![feature(box_syntax, core)] + +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(PartialEq, Debug)] +struct Point { + x: isize, + y: isize +} + +pub fn main() { + let box_5: Box<_> = box 5_usize; + let point = Rc::new(Point {x: 2, y: 4}); + assert_eq!(point.x, 2); + assert_eq!(point.y, 4); + + let i = Rc::new(RefCell::new(2)); + let i_value = *i.borrow(); + *i.borrow_mut() = 5; + assert_eq!((i_value, *i.borrow()), (2, 5)); + + let s = Rc::new("foo".to_string()); + assert_eq!(&**s, "foo"); + + let mut_s = Rc::new(RefCell::new(String::from("foo"))); + mut_s.borrow_mut().push_str("bar"); + // HACK assert_eq! would panic here because it stores the LHS and RHS in two locals. + assert_eq!(&**mut_s.borrow(), "foobar"); + assert_eq!(&**mut_s.borrow_mut(), "foobar"); + + let p = Rc::new(RefCell::new(Point {x: 1, y: 2})); + p.borrow_mut().x = 3; + p.borrow_mut().y += 3; + assert_eq!(*p.borrow(), Point {x: 3, y: 5}); + + let v = Rc::new(RefCell::new([1, 2, 3])); + v.borrow_mut()[0] = 3; + v.borrow_mut()[1] += 3; + assert_eq!((v.borrow()[0], v.borrow()[1], v.borrow()[2]), (3, 5, 3)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-object-one-arg.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-object-one-arg.rs new file mode 100644 index 000000000000..5739f3fed20b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-object-one-arg.rs @@ -0,0 +1,14 @@ +// run-pass +// Tests calls to closure arguments where the closure takes 1 argument. +// This is a bit tricky due to rust-call ABI. + + +fn foo(f: &mut dyn FnMut(isize) -> isize) -> isize { + f(22) +} + +fn main() { + let z = foo(&mut |x| x *100); + assert_eq!(z, 2200); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-object-two-args.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-object-two-args.rs new file mode 100644 index 000000000000..739089b472dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-object-two-args.rs @@ -0,0 +1,14 @@ +// run-pass +// Tests calls to closure arguments where the closure takes 2 arguments. +// This is a bit tricky due to rust-call ABI. + + +fn foo(f: &mut dyn FnMut(isize, isize) -> isize) -> isize { + f(1, 2) +} + +fn main() { + let z = foo(&mut |x, y| x * 10 + y); + assert_eq!(z, 12); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-object-zero-args.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-object-zero-args.rs new file mode 100644 index 000000000000..705871f25380 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-object-zero-args.rs @@ -0,0 +1,14 @@ +// run-pass +// Tests calls to closure arguments where the closure takes 0 arguments. +// This is a bit tricky due to rust-call ABI. + + +fn foo(f: &mut dyn FnMut() -> isize) -> isize { + f() +} + +fn main() { + let z = foo(&mut || 22); + assert_eq!(z, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-param-vtables.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-param-vtables.rs new file mode 100644 index 000000000000..faaebd36d7a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-param-vtables.rs @@ -0,0 +1,33 @@ +// run-pass +// Tests that nested vtables work with overloaded calls. + +// pretty-expanded FIXME #23616 + +#![feature(unboxed_closures, fn_traits)] + +use std::marker::PhantomData; +use std::ops::Fn; +use std::ops::Add; + +struct G(PhantomData); + +impl<'a, A: Add> Fn<(A,)> for G { + extern "rust-call" fn call(&self, (arg,): (A,)) -> i32 { + arg.add(1) + } +} + +impl<'a, A: Add> FnMut<(A,)> for G { + extern "rust-call" fn call_mut(&mut self, args: (A,)) -> i32 { self.call(args) } +} + +impl<'a, A: Add> FnOnce<(A,)> for G { + type Output = i32; + extern "rust-call" fn call_once(self, args: (A,)) -> i32 { self.call(args) } +} + +fn main() { + // ICE trigger + (G(PhantomData))(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-simple.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-simple.rs new file mode 100644 index 000000000000..72955f9a05be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-simple.rs @@ -0,0 +1,79 @@ +// run-pass + +#![feature(lang_items, unboxed_closures, fn_traits)] + +use std::ops::{Fn, FnMut, FnOnce}; + +struct S1 { + x: i32, + y: i32, +} + +impl FnMut<(i32,)> for S1 { + extern "rust-call" fn call_mut(&mut self, (z,): (i32,)) -> i32 { + self.x * self.y * z + } +} + +impl FnOnce<(i32,)> for S1 { + type Output = i32; + extern "rust-call" fn call_once(mut self, args: (i32,)) -> i32 { + self.call_mut(args) + } +} + +struct S2 { + x: i32, + y: i32, +} + +impl Fn<(i32,)> for S2 { + extern "rust-call" fn call(&self, (z,): (i32,)) -> i32 { + self.x * self.y * z + } +} + +impl FnMut<(i32,)> for S2 { + extern "rust-call" fn call_mut(&mut self, args: (i32,)) -> i32 { self.call(args) } +} + +impl FnOnce<(i32,)> for S2 { + type Output = i32; + extern "rust-call" fn call_once(self, args: (i32,)) -> i32 { self.call(args) } +} + +struct S3 { + x: i32, + y: i32, +} + +impl FnOnce<(i32,i32)> for S3 { + type Output = i32; + extern "rust-call" fn call_once(self, (z,zz): (i32,i32)) -> i32 { + self.x * self.y * z * zz + } +} + +fn main() { + let mut s = S1 { + x: 3, + y: 3, + }; + let ans = s(3); + + assert_eq!(ans, 27); + let s = S2 { + x: 3, + y: 3, + }; + let ans = s.call((3,)); + assert_eq!(ans, 27); + + let s = S3 { + x: 3, + y: 3, + }; + let ans = s(3, 1); + assert_eq!(ans, 27); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-zero-args.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-zero-args.rs new file mode 100644 index 000000000000..3f9f1a8cd7be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-calls-zero-args.rs @@ -0,0 +1,31 @@ +// run-pass + +#![feature(unboxed_closures, fn_traits)] + +use std::ops::FnMut; + +struct S { + x: i32, + y: i32, +} + +impl FnMut<()> for S { + extern "rust-call" fn call_mut(&mut self, (): ()) -> i32 { + self.x * self.y + } +} + +impl FnOnce<()> for S { + type Output = i32; + extern "rust-call" fn call_once(mut self, args: ()) -> i32 { self.call_mut(args) } +} + +fn main() { + let mut s = S { + x: 3, + y: 3, + }; + let ans = s(); + assert_eq!(ans, 9); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-deref-count.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-deref-count.rs new file mode 100644 index 000000000000..35f9d2b14694 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-deref-count.rs @@ -0,0 +1,79 @@ +// run-pass + +use std::cell::Cell; +use std::ops::{Deref, DerefMut}; +use std::vec::Vec; + +struct DerefCounter { + count_imm: Cell, + count_mut: usize, + value: T +} + +impl DerefCounter { + fn new(value: T) -> DerefCounter { + DerefCounter { + count_imm: Cell::new(0), + count_mut: 0, + value: value + } + } + + fn counts(&self) -> (usize, usize) { + (self.count_imm.get(), self.count_mut) + } +} + +impl Deref for DerefCounter { + type Target = T; + + fn deref(&self) -> &T { + self.count_imm.set(self.count_imm.get() + 1); + &self.value + } +} + +impl DerefMut for DerefCounter { + fn deref_mut(&mut self) -> &mut T { + self.count_mut += 1; + &mut self.value + } +} + +pub fn main() { + let mut n = DerefCounter::new(0); + let mut v = DerefCounter::new(Vec::new()); + + let _ = *n; // Immutable deref + copy a POD. + assert_eq!(n.counts(), (1, 0)); + + let _ = (&*n, &*v); // Immutable deref + borrow. + assert_eq!(n.counts(), (2, 0)); assert_eq!(v.counts(), (1, 0)); + + let _ = (&mut *n, &mut *v); // Mutable deref + mutable borrow. + assert_eq!(n.counts(), (2, 1)); assert_eq!(v.counts(), (1, 1)); + + let mut v2 = Vec::new(); + v2.push(1); + + *n = 5; *v = v2; // Mutable deref + assignment. + assert_eq!(n.counts(), (2, 2)); assert_eq!(v.counts(), (1, 2)); + + *n -= 3; // Mutable deref + assignment with binary operation. + assert_eq!(n.counts(), (2, 3)); + + // Immutable deref used for calling a method taking &self. (The + // typechecker is smarter now about doing this.) + (*n).to_string(); + assert_eq!(n.counts(), (3, 3)); + + // Mutable deref used for calling a method taking &mut self. + (*v).push(2); + assert_eq!(v.counts(), (1, 3)); + + // Check the final states. + assert_eq!(*n, 2); + let expected: &[_] = &[1, 2]; + assert_eq!((*v), expected); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-deref.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-deref.rs new file mode 100644 index 000000000000..a7f51e10b396 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-deref.rs @@ -0,0 +1,44 @@ +// run-pass +use std::cell::RefCell; +use std::rc::Rc; +use std::string::String; + +#[derive(PartialEq, Debug)] +struct Point { + x: isize, + y: isize +} + +pub fn main() { + assert_eq!(*Rc::new(5), 5); + assert_eq!(***Rc::new(Box::new(Box::new(5))), 5); + assert_eq!(*Rc::new(Point {x: 2, y: 4}), Point {x: 2, y: 4}); + + let i = Rc::new(RefCell::new(2)); + let i_value = *(*i).borrow(); + *(*i).borrow_mut() = 5; + assert_eq!((i_value, *(*i).borrow()), (2, 5)); + + let s = Rc::new("foo".to_string()); + assert_eq!(*s, "foo".to_string()); + assert_eq!((*s), "foo"); + + let mut_s = Rc::new(RefCell::new(String::from("foo"))); + (*(*mut_s).borrow_mut()).push_str("bar"); + // assert_eq! would panic here because it stores the LHS and RHS in two locals. + assert_eq!((*(*mut_s).borrow()), "foobar"); + assert_eq!((*(*mut_s).borrow_mut()), "foobar"); + + let p = Rc::new(RefCell::new(Point {x: 1, y: 2})); + (*(*p).borrow_mut()).x = 3; + (*(*p).borrow_mut()).y += 3; + assert_eq!(*(*p).borrow(), Point {x: 3, y: 5}); + + let v = Rc::new(RefCell::new(vec![1, 2, 3])); + (*(*v).borrow_mut())[0] = 3; + (*(*v).borrow_mut())[1] += 3; + assert_eq!(((*(*v).borrow())[0], + (*(*v).borrow())[1], + (*(*v).borrow())[2]), (3, 5, 3)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index-assoc-list.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index-assoc-list.rs new file mode 100644 index 000000000000..100876407551 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index-assoc-list.rs @@ -0,0 +1,49 @@ +// run-pass +// Test overloading of the `[]` operator. In particular test that it +// takes its argument *by reference*. + +use std::ops::Index; + +struct AssociationList { + pairs: Vec> } + +#[derive(Clone)] +struct AssociationPair { + key: K, + value: V +} + +impl AssociationList { + fn push(&mut self, key: K, value: V) { + self.pairs.push(AssociationPair {key: key, value: value}); + } +} + +impl<'a, K: PartialEq + std::fmt::Debug, V:Clone> Index<&'a K> for AssociationList { + type Output = V; + + fn index(&self, index: &K) -> &V { + for pair in &self.pairs { + if pair.key == *index { + return &pair.value + } + } + panic!("No value found for key: {:?}", index); + } +} + +pub fn main() { + let foo = "foo".to_string(); + let bar = "bar".to_string(); + + let mut list = AssociationList {pairs: Vec::new()}; + list.push(foo.clone(), 22); + list.push(bar.clone(), 44); + + assert_eq!(list[&foo], 22); + assert_eq!(list[&bar], 44); + + assert_eq!(list[&foo], 22); + assert_eq!(list[&bar], 44); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index-autoderef.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index-autoderef.rs new file mode 100644 index 000000000000..30edc90de2c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index-autoderef.rs @@ -0,0 +1,78 @@ +// run-pass +#![allow(stable_features)] + +// Test overloaded indexing combined with autoderef. + +#![feature(box_syntax, core)] + +use std::ops::{Index, IndexMut}; + +struct Foo { + x: isize, + y: isize, +} + +impl Index for Foo { + type Output = isize; + + fn index(&self, z: isize) -> &isize { + if z == 0 { + &self.x + } else { + &self.y + } + } +} + +impl IndexMut for Foo { + fn index_mut(&mut self, z: isize) -> &mut isize { + if z == 0 { + &mut self.x + } else { + &mut self.y + } + } +} + +trait Int { + fn get(self) -> isize; + fn get_from_ref(&self) -> isize; + fn inc(&mut self); +} + +impl Int for isize { + fn get(self) -> isize { self } + fn get_from_ref(&self) -> isize { *self } + fn inc(&mut self) { *self += 1; } +} + +fn main() { + let mut f: Box<_> = box Foo { + x: 1, + y: 2, + }; + + assert_eq!(f[1], 2); + + f[0] = 3; + + assert_eq!(f[0], 3); + + // Test explicit IndexMut where `f` must be autoderef: + { + let p = &mut f[1]; + *p = 4; + } + + // Test explicit Index where `f` must be autoderef: + { + let p = &f[1]; + assert_eq!(*p, 4); + } + + // Test calling methods with `&mut self`, `self, and `&self` receivers: + f[1].inc(); + assert_eq!(f[1].get(), 5); + assert_eq!(f[1].get_from_ref(), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index-in-field.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index-in-field.rs new file mode 100644 index 000000000000..85d3050f208e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index-in-field.rs @@ -0,0 +1,47 @@ +// run-pass +// Test using overloaded indexing when the "map" is stored in a +// field. This caused problems at some point. + +use std::ops::Index; + +struct Foo { + x: isize, + y: isize, +} + +struct Bar { + foo: Foo +} + +impl Index for Foo { + type Output = isize; + + fn index(&self, z: isize) -> &isize { + if z == 0 { + &self.x + } else { + &self.y + } + } +} + +trait Int { + fn get(self) -> isize; + fn get_from_ref(&self) -> isize; + fn inc(&mut self); +} + +impl Int for isize { + fn get(self) -> isize { self } + fn get_from_ref(&self) -> isize { *self } + fn inc(&mut self) { *self += 1; } +} + +fn main() { + let f = Bar { foo: Foo { + x: 1, + y: 2, + } }; + assert_eq!(f.foo[1].get(), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index.rs new file mode 100644 index 000000000000..f424b94f85ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded-index.rs @@ -0,0 +1,65 @@ +// run-pass +use std::ops::{Index, IndexMut}; + +struct Foo { + x: isize, + y: isize, +} + +impl Index for Foo { + type Output = isize; + + fn index(&self, z: isize) -> &isize { + if z == 0 { + &self.x + } else { + &self.y + } + } +} + +impl IndexMut for Foo { + fn index_mut(&mut self, z: isize) -> &mut isize { + if z == 0 { + &mut self.x + } else { + &mut self.y + } + } +} + +trait Int { + fn get(self) -> isize; + fn get_from_ref(&self) -> isize; + fn inc(&mut self); +} + +impl Int for isize { + fn get(self) -> isize { self } + fn get_from_ref(&self) -> isize { *self } + fn inc(&mut self) { *self += 1; } +} + +fn main() { + let mut f = Foo { + x: 1, + y: 2, + }; + assert_eq!(f[1], 2); + f[0] = 3; + assert_eq!(f[0], 3); + { + let p = &mut f[1]; + *p = 4; + } + { + let p = &f[1]; + assert_eq!(*p, 4); + } + + // Test calling methods with `&mut self`, `self, and `&self` receivers: + f[1].inc(); + assert_eq!(f[1].get(), 5); + assert_eq!(f[1].get_from_ref(), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded_deref_with_ref_pattern.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded_deref_with_ref_pattern.rs new file mode 100644 index 000000000000..40b12225725c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded_deref_with_ref_pattern.rs @@ -0,0 +1,96 @@ +// run-pass +#![allow(unused_mut)] +#![allow(unused_variables)] +// Test that we choose Deref or DerefMut appropriately based on mutability of ref bindings (#15609). + +use std::ops::{Deref, DerefMut}; + +struct DerefOk(T); +struct DerefMutOk(T); + +impl Deref for DerefOk { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for DerefOk { + fn deref_mut(&mut self) -> &mut Self::Target { + panic!() + } +} + +impl Deref for DerefMutOk { + type Target = T; + fn deref(&self) -> &Self::Target { + panic!() + } +} + +impl DerefMut for DerefMutOk { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +fn main() { + // Check that mutable ref binding in match picks DerefMut + let mut b = DerefMutOk(0); + match *b { + ref mut n => n, + }; + + // Check that mutable ref binding in let picks DerefMut + let mut y = DerefMutOk(1); + let ref mut z = *y; + + // Check that immutable ref binding in match picks Deref + let mut b = DerefOk(2); + match *b { + ref n => n, + }; + + // Check that immutable ref binding in let picks Deref + let mut y = DerefOk(3); + let ref z = *y; + + // Check that mixed mutable/immutable ref binding in match picks DerefMut + let mut b = DerefMutOk((0, 9)); + match *b { + (ref mut n, ref m) => (n, m), + }; + + let mut b = DerefMutOk((0, 9)); + match *b { + (ref n, ref mut m) => (n, m), + }; + + // Check that mixed mutable/immutable ref binding in let picks DerefMut + let mut y = DerefMutOk((1, 8)); + let (ref mut z, ref a) = *y; + + let mut y = DerefMutOk((1, 8)); + let (ref z, ref mut a) = *y; + + // Check that multiple immutable ref bindings in match picks Deref + let mut b = DerefOk((2, 7)); + match *b { + (ref n, ref m) => (n, m), + }; + + // Check that multiple immutable ref bindings in let picks Deref + let mut y = DerefOk((3, 6)); + let (ref z, ref a) = *y; + + // Check that multiple mutable ref bindings in match picks DerefMut + let mut b = DerefMutOk((4, 5)); + match *b { + (ref mut n, ref mut m) => (n, m), + }; + + // Check that multiple mutable ref bindings in let picks DerefMut + let mut y = DerefMutOk((5, 4)); + let (ref mut z, ref mut a) = *y; +} + diff --git a/gcc/testsuite/rust/rustc/ui/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs new file mode 100644 index 000000000000..0372fafc86e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/overloaded/overloaded_deref_with_ref_pattern_issue15609.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test that we choose Deref or DerefMut appropriately based on mutability of ref bindings (#15609). + +fn main() { + use std::cell::RefCell; + + struct S { + node: E, + } + + enum E { + Foo(u32), + Bar, + } + + // Check match + let x = RefCell::new(S { node: E::Foo(0) }); + + let mut b = x.borrow_mut(); + match b.node { + E::Foo(ref mut n) => *n += 1, + _ => (), + } + + // Check let + let x = RefCell::new(0); + let mut y = x.borrow_mut(); + let ref mut z = *y; + + fn foo(a: &mut RefCell>) { + if let Some(ref mut s) = *a.borrow_mut() { + s.push('a') + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/owned-implies-static.rs b/gcc/testsuite/rust/rustc/ui/owned-implies-static.rs new file mode 100644 index 000000000000..c41e84f1e4b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/owned-implies-static.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn f(_x: T) {} + +pub fn main() { + f(Box::new(5)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed-struct/packed-struct-generic-transmute.rs b/gcc/testsuite/rust/rustc/ui/packed-struct/packed-struct-generic-transmute.rs new file mode 100644 index 000000000000..5ba6076a4041 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed-struct/packed-struct-generic-transmute.rs @@ -0,0 +1,28 @@ +// This assumes the packed and non-packed structs are different sizes. + +// the error points to the start of the file, not the line with the +// transmute + +// error-pattern: cannot transmute between types of different sizes, or dependently-sized types + +use std::mem; + +#[repr(packed)] +struct Foo { + bar: T, + baz: S +} + +struct Oof { + rab: T, + zab: S +} + +fn main() { + let foo = Foo { bar: [1u8, 2, 3, 4, 5], baz: 10i32 }; + unsafe { + let oof: Oof<[u8; 5], i32> = mem::transmute(foo); + println!("{:?} {:?}", &oof.rab[..], oof.zab); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed-struct/packed-struct-transmute.rs b/gcc/testsuite/rust/rustc/ui/packed-struct/packed-struct-transmute.rs new file mode 100644 index 000000000000..f92752660585 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed-struct/packed-struct-transmute.rs @@ -0,0 +1,30 @@ +// This assumes the packed and non-packed structs are different sizes. + +// the error points to the start of the file, not the line with the +// transmute + +// normalize-stderr-test "\d+ bits" -> "N bits" +// error-pattern: cannot transmute between types of different sizes, or dependently-sized types + +use std::mem; + +#[repr(packed)] +struct Foo { + bar: u8, + baz: usize +} + +#[derive(Debug)] +struct Oof { + rab: u8, + zab: usize +} + +fn main() { + let foo = Foo { bar: 1, baz: 10 }; + unsafe { + let oof: Oof = mem::transmute(foo); + println!("{:?}", oof); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/auxiliary/packed.rs b/gcc/testsuite/rust/rustc/ui/packed/auxiliary/packed.rs new file mode 100644 index 000000000000..6258f6596779 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/auxiliary/packed.rs @@ -0,0 +1,20 @@ +#[repr(packed)] +pub struct P1S5 { + a: u8, + b: u32 +} + +#[repr(packed(2))] +pub struct P2S6 { + a: u8, + b: u32, + c: u8 +} + +#[repr(C, packed(2))] +pub struct P2CS8 { + a: u8, + b: u32, + c: u8 +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-struct-address-of-element.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-address-of-element.rs new file mode 100644 index 000000000000..b0f2f1db4527 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-address-of-element.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(dead_code)] +#![deny(safe_packed_borrows)] +#![feature(raw_ref_op)] +// ignore-emscripten weird assertion? + +#[repr(packed)] +struct Foo1 { + bar: u8, + baz: usize +} + +#[repr(packed(2))] +struct Foo2 { + bar: u8, + baz: usize +} + +#[repr(C, packed(4))] +struct Foo4C { + bar: u8, + baz: usize +} + +pub fn main() { + let foo = Foo1 { bar: 1, baz: 2 }; + let brw = &raw const foo.baz; + unsafe { assert_eq!(brw.read_unaligned(), 2); } + + let foo = Foo2 { bar: 1, baz: 2 }; + let brw = &raw const foo.baz; + unsafe { assert_eq!(brw.read_unaligned(), 2); } + + let mut foo = Foo4C { bar: 1, baz: 2 }; + let brw = &raw mut foo.baz; + unsafe { assert_eq!(brw.read_unaligned(), 2); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-struct-borrow-element.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-borrow-element.rs new file mode 100644 index 000000000000..19abfdb39cb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-borrow-element.rs @@ -0,0 +1,36 @@ +// run-pass (note: this is spec-UB, but it works for now) +#![allow(dead_code)] +// ignore-emscripten weird assertion? + +#[repr(packed)] +struct Foo1 { + bar: u8, + baz: usize +} + +#[repr(packed(2))] +struct Foo2 { + bar: u8, + baz: usize +} + +#[repr(C, packed(4))] +struct Foo4C { + bar: u8, + baz: usize +} + +pub fn main() { + let foo = Foo1 { bar: 1, baz: 2 }; + let brw = unsafe { &foo.baz }; + assert_eq!(*brw, 2); + + let foo = Foo2 { bar: 1, baz: 2 }; + let brw = unsafe { &foo.baz }; + assert_eq!(*brw, 2); + + let foo = Foo4C { bar: 1, baz: 2 }; + let brw = unsafe { &foo.baz }; + assert_eq!(*brw, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-struct-drop-aligned.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-drop-aligned.rs new file mode 100644 index 000000000000..e12730f3f5b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-drop-aligned.rs @@ -0,0 +1,34 @@ +// run-pass +use std::cell::Cell; +use std::mem; + +struct Aligned<'a> { + drop_count: &'a Cell +} + +#[inline(never)] +fn check_align(ptr: *const Aligned) { + assert_eq!(ptr as usize % mem::align_of::(), + 0); +} + +impl<'a> Drop for Aligned<'a> { + fn drop(&mut self) { + check_align(self); + self.drop_count.set(self.drop_count.get() + 1); + } +} + +#[repr(packed)] +struct Packed<'a>(u8, Aligned<'a>); + +fn main() { + let drop_count = &Cell::new(0); + { + let mut p = Packed(0, Aligned { drop_count }); + p.1 = Aligned { drop_count }; + assert_eq!(drop_count.get(), 1); + } + assert_eq!(drop_count.get(), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-struct-generic-layout.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-generic-layout.rs new file mode 100644 index 000000000000..8c53c9f986bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-generic-layout.rs @@ -0,0 +1,33 @@ +// run-pass +#![allow(dead_code)] +#![allow(overflowing_literals)] + + +use std::mem; + +#[repr(packed)] +struct S { + a: T, + b: u8, + c: S +} + +pub fn main() { + unsafe { + let s = S { a: 0xff_ff_ff_ffu32, b: 1, c: 0xaa_aa_aa_aa as i32 }; + let transd : [u8; 9] = mem::transmute(s); + // Don't worry about endianness, the numbers are palindromic. + assert_eq!(transd, + [0xff, 0xff, 0xff, 0xff, + 1, + 0xaa, 0xaa, 0xaa, 0xaa]); + + + let s = S { a: 1u8, b: 2u8, c: 0b10000001_10000001 as i16}; + let transd : [u8; 4] = mem::transmute(s); + // Again, no endianness problems. + assert_eq!(transd, + [1, 2, 0b10000001, 0b10000001]); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-struct-generic-size.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-generic-size.rs new file mode 100644 index 000000000000..ab535155b265 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-generic-size.rs @@ -0,0 +1,45 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_comparisons)] + +use std::mem; + +#[repr(packed)] +struct P1 { + a: T, + b: u8, + c: S +} + +#[repr(packed(2))] +struct P2 { + a: T, + b: u8, + c: S +} + +#[repr(C, packed(4))] +struct P4C { + a: T, + b: u8, + c: S +} + +macro_rules! check { + ($t:ty, $align:expr, $size:expr) => ({ + assert_eq!(mem::align_of::<$t>(), $align); + assert_eq!(mem::size_of::<$t>(), $size); + }); +} + +pub fn main() { + check!(P1, 1, 3); + check!(P1, 1, 11); + + check!(P2, 1, 3); + check!(P2, 2, 12); + + check!(P4C, 1, 3); + check!(P4C, 4, 12); +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-struct-layout.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-layout.rs new file mode 100644 index 000000000000..aaa1e8f043f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-layout.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] +use std::mem; + +#[repr(packed)] +struct S4 { + a: u8, + b: [u8; 3], +} + +#[repr(packed)] +struct S5 { + a: u8, + b: u32 +} + +pub fn main() { + unsafe { + let s4 = S4 { a: 1, b: [2,3,4] }; + let transd : [u8; 4] = mem::transmute(s4); + assert_eq!(transd, [1, 2, 3, 4]); + + let s5 = S5 { a: 1, b: 0xff_00_00_ff }; + let transd : [u8; 5] = mem::transmute(s5); + // Don't worry about endianness, the u32 is palindromic. + assert_eq!(transd, [1, 0xff, 0, 0, 0xff]); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-struct-match.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-match.rs new file mode 100644 index 000000000000..fbc862ab579a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-match.rs @@ -0,0 +1,46 @@ +// run-pass + +#[repr(packed)] +struct Foo1 { + bar: u8, + baz: usize +} + +#[repr(packed(2))] +struct Foo2 { + bar: u8, + baz: usize +} + +#[repr(C, packed(4))] +struct Foo4C { + bar: u8, + baz: usize +} + +pub fn main() { + let foo1 = Foo1 { bar: 1, baz: 2 }; + match foo1 { + Foo1 {bar, baz} => { + assert_eq!(bar, 1); + assert_eq!(baz, 2); + } + } + + let foo2 = Foo2 { bar: 1, baz: 2 }; + match foo2 { + Foo2 {bar, baz} => { + assert_eq!(bar, 1); + assert_eq!(baz, 2); + } + } + + let foo4 = Foo4C { bar: 1, baz: 2 }; + match foo4 { + Foo4C {bar, baz} => { + assert_eq!(bar, 1); + assert_eq!(baz, 2); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-struct-optimized-enum.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-optimized-enum.rs new file mode 100644 index 000000000000..118a0a8597ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-optimized-enum.rs @@ -0,0 +1,37 @@ +// run-pass +#[repr(packed)] +struct Packed(T); + +impl Copy for Packed {} +impl Clone for Packed { + fn clone(&self) -> Self { *self } +} + +fn sanity_check_size(one: T) { + let two = [one, one]; + let stride = (&two[1] as *const _ as usize) - (&two[0] as *const _ as usize); + let (size, align) = (std::mem::size_of::(), std::mem::align_of::()); + assert_eq!(stride, size); + assert_eq!(size % align, 0); +} + +fn main() { + // This can fail if rustc and LLVM disagree on the size of a type. + // In this case, `Option>` was erroneously not + // marked as packed despite needing alignment `1` and containing + // its `&()` discriminant, which has alignment larger than `1`. + sanity_check_size((Some(Packed((&(), 0))), true)); + + // In #46769, `Option<(Packed<&()>, bool)>` was found to have + // pointer alignment, without actually being aligned in size. + // e.g., on 64-bit platforms, it had alignment `8` but size `9`. + type PackedRefAndBool<'a> = (Packed<&'a ()>, bool); + sanity_check_size::>(Some((Packed(&()), true))); + + // Make sure we don't pay for the enum optimization in size, + // e.g., we shouldn't need extra padding after the packed data. + assert_eq!(std::mem::align_of::>(), 1); + assert_eq!(std::mem::size_of::>(), + std::mem::size_of::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-struct-size-xc.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-size-xc.rs new file mode 100644 index 000000000000..eb8b4032c06b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-size-xc.rs @@ -0,0 +1,21 @@ +// run-pass +// aux-build:packed.rs + + +extern crate packed; + +use std::mem; + +macro_rules! check { + ($t:ty, $align:expr, $size:expr) => ({ + assert_eq!(mem::align_of::<$t>(), $align); + assert_eq!(mem::size_of::<$t>(), $size); + }); +} + +pub fn main() { + check!(packed::P1S5, 1, 5); + check!(packed::P2S6, 2, 6); + check!(packed::P2CS8, 2, 8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-struct-size.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-size.rs new file mode 100644 index 000000000000..87e4ef76eef4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-size.rs @@ -0,0 +1,158 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] + +use std::mem; + +#[repr(packed)] +struct P1S4 { + a: u8, + b: [u8; 3], +} + +#[repr(packed(2))] +struct P2S4 { + a: u8, + b: [u8; 3], +} + +#[repr(packed)] +struct P1S5 { + a: u8, + b: u32 +} + +#[repr(packed(2))] +struct P2S2 { + a: u8, + b: u8 +} + +#[repr(packed(2))] +struct P2S6 { + a: u8, + b: u32 +} + +#[repr(packed(2))] +struct P2S12 { + a: u32, + b: u64 +} + +#[repr(packed)] +struct P1S13 { + a: i64, + b: f32, + c: u8, +} + +#[repr(packed(2))] +struct P2S14 { + a: i64, + b: f32, + c: u8, +} + +#[repr(packed(4))] +struct P4S16 { + a: u8, + b: f32, + c: i64, + d: u16, +} + +#[repr(C, packed(4))] +struct P4CS20 { + a: u8, + b: f32, + c: i64, + d: u16, +} + +enum Foo { + Bar = 1, + Baz = 2 +} + +#[repr(packed)] +struct P1S3_Foo { + a: u8, + b: u16, + c: Foo +} + +#[repr(packed(2))] +struct P2_Foo { + a: Foo, +} + +#[repr(packed(2))] +struct P2S3_Foo { + a: u8, + b: u16, + c: Foo +} + +#[repr(packed)] +struct P1S7_Option { + a: f32, + b: u8, + c: u16, + d: Option> +} + +#[repr(packed(2))] +struct P2_Option { + a: Option> +} + +#[repr(packed(2))] +struct P2S7_Option { + a: f32, + b: u8, + c: u16, + d: Option> +} + +// Placing packed structs in statics should work +static TEST_P1S4: P1S4 = P1S4 { a: 1, b: [2, 3, 4] }; +static TEST_P1S5: P1S5 = P1S5 { a: 3, b: 67 }; +static TEST_P1S3_Foo: P1S3_Foo = P1S3_Foo { a: 1, b: 2, c: Foo::Baz }; +static TEST_P2S2: P2S2 = P2S2 { a: 1, b: 2 }; +static TEST_P2S4: P2S4 = P2S4 { a: 1, b: [2, 3, 4] }; +static TEST_P2S6: P2S6 = P2S6 { a: 1, b: 2 }; +static TEST_P2S12: P2S12 = P2S12 { a: 1, b: 2 }; +static TEST_P4S16: P4S16 = P4S16 { a: 1, b: 2.0, c: 3, d: 4 }; +static TEST_P4CS20: P4CS20 = P4CS20 { a: 1, b: 2.0, c: 3, d: 4 }; + +fn align_to(value: usize, align: usize) -> usize { + (value + (align - 1)) & !(align - 1) +} + +macro_rules! check { + ($t:ty, $align:expr, $size:expr) => ({ + assert_eq!(mem::align_of::<$t>(), $align); + assert_eq!(mem::size_of::<$t>(), $size); + }); +} + +pub fn main() { + check!(P1S4, 1, 4); + check!(P1S5, 1, 5); + check!(P1S13, 1, 13); + check!(P1S3_Foo, 1, 3 + mem::size_of::()); + check!(P1S7_Option, 1, 7 + mem::size_of::>>()); + + check!(P2S2, 1, 2); + check!(P2S4, 1, 4); + check!(P2S6, 2, 6); + check!(P2S12, 2, 12); + check!(P2S14, 2, 14); + check!(P4S16, 4, 16); + check!(P4CS20, 4, 20); + check!(P2S3_Foo, 2, align_to(3 + mem::size_of::(), 2)); + check!(P2S7_Option, 2, align_to(7 + mem::size_of::(), 2)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-struct-vec.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-vec.rs new file mode 100644 index 000000000000..3bd85fb075dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-struct-vec.rs @@ -0,0 +1,121 @@ +// run-pass + +use std::fmt; +use std::mem; + +#[repr(packed)] +#[derive(Copy, Clone)] +struct Foo1 { + bar: u8, + baz: u64 +} + +impl PartialEq for Foo1 { + fn eq(&self, other: &Foo1) -> bool { + self.bar == other.bar && self.baz == other.baz + } +} + +impl fmt::Debug for Foo1 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let bar = self.bar; + let baz = self.baz; + + f.debug_struct("Foo1") + .field("bar", &bar) + .field("baz", &baz) + .finish() + } +} + +#[repr(packed(2))] +#[derive(Copy, Clone)] +struct Foo2 { + bar: u8, + baz: u64 +} + +impl PartialEq for Foo2 { + fn eq(&self, other: &Foo2) -> bool { + self.bar == other.bar && self.baz == other.baz + } +} + +impl fmt::Debug for Foo2 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let bar = self.bar; + let baz = self.baz; + + f.debug_struct("Foo2") + .field("bar", &bar) + .field("baz", &baz) + .finish() + } +} + +#[repr(C, packed(4))] +#[derive(Copy, Clone)] +struct Foo4C { + bar: u8, + baz: u64 +} + +impl PartialEq for Foo4C { + fn eq(&self, other: &Foo4C) -> bool { + self.bar == other.bar && self.baz == other.baz + } +} + +impl fmt::Debug for Foo4C { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let bar = self.bar; + let baz = self.baz; + + f.debug_struct("Foo4C") + .field("bar", &bar) + .field("baz", &baz) + .finish() + } +} + +pub fn main() { + let foo1s = [Foo1 { bar: 1, baz: 2 }; 10]; + + assert_eq!(mem::align_of::<[Foo1; 10]>(), 1); + assert_eq!(mem::size_of::<[Foo1; 10]>(), 90); + + for i in 0..10 { + assert_eq!(foo1s[i], Foo1 { bar: 1, baz: 2}); + } + + for &foo in &foo1s { + assert_eq!(foo, Foo1 { bar: 1, baz: 2 }); + } + + let foo2s = [Foo2 { bar: 1, baz: 2 }; 10]; + + assert_eq!(mem::align_of::<[Foo2; 10]>(), 2); + assert_eq!(mem::size_of::<[Foo2; 10]>(), 100); + + for i in 0..10 { + assert_eq!(foo2s[i], Foo2 { bar: 1, baz: 2}); + } + + for &foo in &foo2s { + assert_eq!(foo, Foo2 { bar: 1, baz: 2 }); + } + + let foo4s = [Foo4C { bar: 1, baz: 2 }; 10]; + + assert_eq!(mem::align_of::<[Foo4C; 10]>(), 4); + assert_eq!(mem::size_of::<[Foo4C; 10]>(), 120); + + for i in 0..10 { + assert_eq!(foo4s[i], Foo4C { bar: 1, baz: 2}); + } + + for &foo in &foo4s { + assert_eq!(foo, Foo4C { bar: 1, baz: 2 }); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-tuple-struct-layout.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-tuple-struct-layout.rs new file mode 100644 index 000000000000..657c373f6848 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-tuple-struct-layout.rs @@ -0,0 +1,22 @@ +// run-pass +use std::mem; + +#[repr(packed)] +struct S4(u8,[u8; 3]); + +#[repr(packed)] +struct S5(u8,u32); + +pub fn main() { + unsafe { + let s4 = S4(1, [2,3,4]); + let transd : [u8; 4] = mem::transmute(s4); + assert_eq!(transd, [1, 2, 3, 4]); + + let s5 = S5(1, 0xff_00_00_ff); + let transd : [u8; 5] = mem::transmute(s5); + // Don't worry about endianness, the u32 is palindromic. + assert_eq!(transd, [1, 0xff, 0, 0, 0xff]); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-tuple-struct-size.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-tuple-struct-size.rs new file mode 100644 index 000000000000..2dcfb211c2d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-tuple-struct-size.rs @@ -0,0 +1,80 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +use std::mem; + +#[repr(packed)] +struct P1S4(u8,[u8; 3]); + +#[repr(packed(2))] +struct P2S4(u8,[u8; 3]); + +#[repr(packed)] +struct P1S5(u8, u32); + +#[repr(packed(2))] +struct P2S6(u8, u32); + +#[repr(packed)] +struct P1S13(i64, f32, u8); + +#[repr(packed(2))] +struct P2S14(i64, f32, u8); + +#[repr(packed(4))] +struct P4S16(u8, f32, i64, u16); + +#[repr(C, packed(4))] +struct P4CS20(u8, f32, i64, u16); + +enum Foo { + Bar = 1, + Baz = 2 +} + +#[repr(packed)] +struct P1S3_Foo(u8, u16, Foo); + +#[repr(packed(2))] +struct P2_Foo(Foo); + +#[repr(packed(2))] +struct P2S3_Foo(u8, u16, Foo); + +#[repr(packed)] +struct P1S7_Option(f32, u8, u16, Option>); + +#[repr(packed(2))] +struct P2_Option(Option>); + +#[repr(packed(2))] +struct P2S7_Option(f32, u8, u16, Option>); + +fn align_to(value: usize, align: usize) -> usize { + (value + (align - 1)) & !(align - 1) +} + +macro_rules! check { + ($t:ty, $align:expr, $size:expr) => ({ + assert_eq!(mem::align_of::<$t>(), $align); + assert_eq!(mem::size_of::<$t>(), $size); + }); +} + +pub fn main() { + check!(P1S4, 1, 4); + check!(P1S5, 1, 5); + check!(P1S13, 1, 13); + check!(P1S3_Foo, 1, 3 + mem::size_of::()); + check!(P1S7_Option, 1, 7 + mem::size_of::>>()); + + check!(P2S4, 1, 4); + check!(P2S6, 2, 6); + check!(P2S14, 2, 14); + check!(P4S16, 4, 16); + check!(P4CS20, 4, 20); + check!(P2S3_Foo, 2, align_to(3 + mem::size_of::(), 2)); + check!(P2S7_Option, 2, align_to(7 + mem::size_of::(), 2)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/packed/packed-with-inference-vars-issue-61402.rs b/gcc/testsuite/rust/rustc/ui/packed/packed-with-inference-vars-issue-61402.rs new file mode 100644 index 000000000000..26c5ec9ef8f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/packed/packed-with-inference-vars-issue-61402.rs @@ -0,0 +1,23 @@ +// run-pass +// If a struct is packed and its last field has drop glue, then that +// field needs to be Sized (to allow it to be destroyed out-of-place). +// +// This is checked by the compiler during wfcheck. That check used +// to have problems with associated types in the last field - test +// that this doesn't ICE. + +#![allow(unused_imports, dead_code)] + +pub struct S; + +pub trait Trait { type Assoc; } + +impl Trait for S { type Assoc = X; } + +#[repr(C, packed)] +struct PackedAssocSized { + pos: Box<>::Assoc>, +} + +fn main() { println!("Hello, world!"); } + diff --git a/gcc/testsuite/rust/rustc/ui/panic-handler/auxiliary/some-panic-impl.rs b/gcc/testsuite/rust/rustc/ui/panic-handler/auxiliary/some-panic-impl.rs new file mode 100644 index 000000000000..85ef56d6fc10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-handler/auxiliary/some-panic-impl.rs @@ -0,0 +1,12 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] +#![no_std] + +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + loop {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-1.rs b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-1.rs new file mode 100644 index 000000000000..f7fa171ea2e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-1.rs @@ -0,0 +1,14 @@ +// compile-flags:-C panic=abort + +#![no_std] +#![no_main] + +use core::panic::PanicInfo; + +#[panic_handler] +fn panic( + info: PanicInfo, // { dg-error "" "" { target *-*-* } } +) -> () // { dg-error "" "" { target *-*-* } } +{ +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-2.rs b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-2.rs new file mode 100644 index 000000000000..187f680bf588 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-2.rs @@ -0,0 +1,15 @@ +// compile-flags:-C panic=abort + +#![no_std] +#![no_main] + +use core::panic::PanicInfo; + +#[panic_handler] +fn panic( + info: &'static PanicInfo, // { dg-error "" "" { target *-*-* } } +) -> ! +{ + loop {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-3.rs b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-3.rs new file mode 100644 index 000000000000..5136ae36790a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-3.rs @@ -0,0 +1,12 @@ +// compile-flags:-C panic=abort + +#![no_std] +#![no_main] + +use core::panic::PanicInfo; + +#[panic_handler] +fn panic() -> ! { // { dg-error "" "" { target *-*-* } } + loop {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-4.rs b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-4.rs new file mode 100644 index 000000000000..0cb818829cc6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-bad-signature-4.rs @@ -0,0 +1,13 @@ +// compile-flags:-C panic=abort + +#![no_std] +#![no_main] + +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(pi: &PanicInfo) -> ! { +// { dg-error "" "" { target *-*-* } .-1 } + loop {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-duplicate.rs b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-duplicate.rs new file mode 100644 index 000000000000..478d8d4c9d98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-duplicate.rs @@ -0,0 +1,18 @@ +// compile-flags:-C panic=abort + +#![feature(lang_items)] +#![no_std] +#![no_main] + +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + loop {} +} + +#[lang = "panic_impl"] +fn panic2(info: &PanicInfo) -> ! { // { dg-error ".E0152." "" { target *-*-* } } + loop {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-requires-panic-info.rs b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-requires-panic-info.rs new file mode 100644 index 000000000000..f45e27ebbad8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-requires-panic-info.rs @@ -0,0 +1,16 @@ +// compile-flags:-C panic=abort +// error-pattern: language item required, but not found: `panic_info` + +#![feature(lang_items)] +#![feature(no_core)] +#![no_core] +#![no_main] + +#[panic_handler] +fn panic() -> ! { + loop {} +} + +#[lang = "sized"] +trait Sized {} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-std.rs b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-std.rs new file mode 100644 index 000000000000..7f2f222ecccc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-std.rs @@ -0,0 +1,13 @@ +// normalize-stderr-test "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +// error-pattern: found duplicate lang item `panic_impl` + + +use std::panic::PanicInfo; + +#[panic_handler] +fn panic(info: PanicInfo) -> ! { + loop {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-wrong-location.rs b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-wrong-location.rs new file mode 100644 index 000000000000..cd687f8a6212 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-handler/panic-handler-wrong-location.rs @@ -0,0 +1,9 @@ +// compile-flags:-C panic=abort + +#![no_std] +#![no_main] + +#[panic_handler] // { dg-error ".E0718." "" { target *-*-* } } +#[no_mangle] +static X: u32 = 42; + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/abort-link-to-unwind-dylib.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/abort-link-to-unwind-dylib.rs new file mode 100644 index 000000000000..2845c79e7b85 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/abort-link-to-unwind-dylib.rs @@ -0,0 +1,19 @@ +// build-fail +// compile-flags:-C panic=abort -C prefer-dynamic +// ignore-musl - no dylibs here +// ignore-cloudabi +// ignore-emscripten +// ignore-sgx no dynamic lib support +// error-pattern:`panic_unwind` is not compiled with this crate's panic strategy + +// This is a test where the local crate, compiled with `panic=abort`, links to +// the standard library **dynamically** which is already linked against +// `panic=unwind`. We should fail because the linked panic runtime does not +// correspond with our `-C panic` option. +// +// Note that this test assumes that the dynamic version of the standard library +// is linked to `panic_unwind`, which is currently the case. + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/abort-link-to-unwinding-crates.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/abort-link-to-unwinding-crates.rs new file mode 100644 index 000000000000..e53938e22586 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/abort-link-to-unwinding-crates.rs @@ -0,0 +1,42 @@ +// run-pass +#![allow(unused_variables)] +// compile-flags:-C panic=abort +// aux-build:exit-success-if-unwind.rs +// no-prefer-dynamic +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +// ignore-macos + +extern crate exit_success_if_unwind; + +use std::process::Command; +use std::env; + +fn main() { + let mut args = env::args_os(); + let me = args.next().unwrap(); + + if let Some(s) = args.next() { + if &*s == "foo" { + exit_success_if_unwind::bar(do_panic); + } + } + + let mut cmd = Command::new(env::args_os().next().unwrap()); + cmd.arg("foo"); + + + // ARMv6 hanges while printing the backtrace, see #41004 + if cfg!(target_arch = "arm") && cfg!(target_env = "gnu") { + cmd.env("RUST_BACKTRACE", "0"); + } + + let s = cmd.status(); + assert!(s.unwrap().code() != Some(0)); +} + +fn do_panic() { + panic!("try to catch me"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/abort.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/abort.rs new file mode 100644 index 000000000000..f28ba0288605 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/abort.rs @@ -0,0 +1,45 @@ +// run-pass +#![allow(unused_variables)] +// compile-flags:-C panic=abort +// no-prefer-dynamic +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +// ignore-macos + +use std::process::Command; +use std::env; + +struct Bomb; + +impl Drop for Bomb { + fn drop(&mut self) { + std::process::exit(0); + } +} + +fn main() { + let mut args = env::args_os(); + let me = args.next().unwrap(); + + if let Some(s) = args.next() { + if &*s == "foo" { + + let _bomb = Bomb; + + panic!("try to catch me"); + } + } + + let mut cmd = Command::new(env::args_os().next().unwrap()); + cmd.arg("foo"); + + // ARMv6 hanges while printing the backtrace, see #41004 + if cfg!(target_arch = "arm") && cfg!(target_env = "gnu") { + cmd.env("RUST_BACKTRACE", "0"); + } + + let s = cmd.status(); + assert!(s.unwrap().code() != Some(0)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/exit-success-if-unwind.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/exit-success-if-unwind.rs new file mode 100644 index 000000000000..d802d6decd15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/exit-success-if-unwind.rs @@ -0,0 +1,17 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +struct Bomb; + +impl Drop for Bomb { + fn drop(&mut self) { + std::process::exit(0); + } +} + +pub fn bar(f: fn()) { + let _bomb = Bomb; + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-abort.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-abort.rs new file mode 100644 index 000000000000..9b4c235f1d58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-abort.rs @@ -0,0 +1,18 @@ +// compile-flags:-C panic=abort +// no-prefer-dynamic + +#![feature(panic_runtime)] +#![crate_type = "rlib"] + +#![no_std] +#![panic_runtime] + +#[no_mangle] +pub extern fn __rust_maybe_catch_panic() {} + +#[no_mangle] +pub extern fn __rust_start_panic() {} + +#[no_mangle] +pub extern fn rust_eh_personality() {} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs new file mode 100644 index 000000000000..2673784870ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-lang-items.rs @@ -0,0 +1,16 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +#![no_std] +#![feature(lang_items)] + +use core::panic::PanicInfo; + +#[lang = "panic_impl"] +fn panic_impl(info: &PanicInfo) -> ! { loop {} } +#[lang = "eh_personality"] +fn eh_personality() {} +#[lang = "eh_catch_typeinfo"] +static EH_CATCH_TYPEINFO: u8 = 0; + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-unwind.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-unwind.rs new file mode 100644 index 000000000000..bf9b1ad366ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-unwind.rs @@ -0,0 +1,18 @@ +// compile-flags:-C panic=unwind +// no-prefer-dynamic + +#![feature(panic_runtime)] +#![crate_type = "rlib"] + +#![no_std] +#![panic_runtime] + +#[no_mangle] +pub extern fn __rust_maybe_catch_panic() {} + +#[no_mangle] +pub extern fn __rust_start_panic() {} + +#[no_mangle] +pub extern fn rust_eh_personality() {} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-unwind2.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-unwind2.rs new file mode 100644 index 000000000000..bf9b1ad366ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/panic-runtime-unwind2.rs @@ -0,0 +1,18 @@ +// compile-flags:-C panic=unwind +// no-prefer-dynamic + +#![feature(panic_runtime)] +#![crate_type = "rlib"] + +#![no_std] +#![panic_runtime] + +#[no_mangle] +pub extern fn __rust_maybe_catch_panic() {} + +#[no_mangle] +pub extern fn __rust_start_panic() {} + +#[no_mangle] +pub extern fn rust_eh_personality() {} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/wants-panic-runtime-abort.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/wants-panic-runtime-abort.rs new file mode 100644 index 000000000000..959d9381ed39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/wants-panic-runtime-abort.rs @@ -0,0 +1,8 @@ +// compile-flags:-C panic=abort +// no-prefer-dynamic + +#![crate_type = "rlib"] +#![no_std] + +extern crate panic_runtime_abort; + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/wants-panic-runtime-unwind.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/wants-panic-runtime-unwind.rs new file mode 100644 index 000000000000..99f47cc63683 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/auxiliary/wants-panic-runtime-unwind.rs @@ -0,0 +1,7 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] +#![no_std] + +extern crate panic_runtime_unwind; + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/bad-panic-flag1.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/bad-panic-flag1.rs new file mode 100644 index 000000000000..a0b85f86d4f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/bad-panic-flag1.rs @@ -0,0 +1,5 @@ +// compile-flags:-C panic=foo +// error-pattern:either `unwind` or `abort` was expected + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/bad-panic-flag2.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/bad-panic-flag2.rs new file mode 100644 index 000000000000..b483f805ca38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/bad-panic-flag2.rs @@ -0,0 +1,5 @@ +// compile-flags:-C panic +// error-pattern:requires either `unwind` or `abort` + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/link-to-abort.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/link-to-abort.rs new file mode 100644 index 000000000000..72a6c59432a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/link-to-abort.rs @@ -0,0 +1,12 @@ +// run-pass + +// compile-flags:-C panic=abort +// no-prefer-dynamic +// ignore-macos + +#![feature(panic_abort)] + +extern crate panic_abort; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/link-to-unwind.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/link-to-unwind.rs new file mode 100644 index 000000000000..8fceb1569459 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/link-to-unwind.rs @@ -0,0 +1,11 @@ +// run-pass + +// no-prefer-dynamic + +#![feature(panic_unwind)] + +extern crate panic_unwind; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/lto-abort.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/lto-abort.rs new file mode 100644 index 000000000000..6c961776fc5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/lto-abort.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(unused_variables)] +// compile-flags:-C lto -C panic=abort +// no-prefer-dynamic +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::process::Command; +use std::env; + +struct Bomb; + +impl Drop for Bomb { + fn drop(&mut self) { + std::process::exit(0); + } +} + +fn main() { + let mut args = env::args_os(); + let me = args.next().unwrap(); + + if let Some(s) = args.next() { + if &*s == "foo" { + + let _bomb = Bomb; + + panic!("try to catch me"); + } + } + let s = Command::new(env::args_os().next().unwrap()).arg("foo").status(); + assert!(s.unwrap().code() != Some(0)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/lto-unwind.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/lto-unwind.rs new file mode 100644 index 000000000000..db3aa4c7570e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/lto-unwind.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(unused_variables)] + +// compile-flags:-C lto -C panic=unwind +// no-prefer-dynamic +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::process::Command; +use std::env; + +struct Bomb; + +impl Drop for Bomb { + fn drop(&mut self) { + println!("hurray you ran me"); + } +} + +fn main() { + let mut args = env::args_os(); + let me = args.next().unwrap(); + + if let Some(s) = args.next() { + if &*s == "foo" { + + let _bomb = Bomb; + + panic!("try to catch me"); + } + } + let s = Command::new(env::args_os().next().unwrap()).arg("foo").output(); + let s = s.unwrap(); + assert!(!s.status.success()); + assert!(String::from_utf8_lossy(&s.stdout).contains("hurray you ran me")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/needs-gate.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/needs-gate.rs new file mode 100644 index 000000000000..8e706f4cacc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/needs-gate.rs @@ -0,0 +1,8 @@ +// gate-test-needs_panic_runtime +// gate-test-panic_runtime + +#![panic_runtime] // { dg-error ".E0658." "" { target *-*-* } } +#![needs_panic_runtime] // { dg-error ".E0658." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/transitive-link-a-bunch.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/transitive-link-a-bunch.rs new file mode 100644 index 000000000000..a60d18e9f67d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/transitive-link-a-bunch.rs @@ -0,0 +1,16 @@ +// build-fail +// aux-build:panic-runtime-unwind.rs +// aux-build:panic-runtime-abort.rs +// aux-build:wants-panic-runtime-unwind.rs +// aux-build:wants-panic-runtime-abort.rs +// aux-build:panic-runtime-lang-items.rs +// error-pattern: is not compiled with this crate's panic strategy `unwind` +// ignore-wasm32-bare compiled with panic=abort by default + +#![no_std] +#![no_main] + +extern crate wants_panic_runtime_unwind; +extern crate wants_panic_runtime_abort; +extern crate panic_runtime_lang_items; + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-interleaved.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-interleaved.rs new file mode 100644 index 000000000000..427e6662daaf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-interleaved.rs @@ -0,0 +1,17 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn a() {} + +fn b() { + panic!(); +} + +fn main() { + let _x = vec![0]; + a(); + let _y = vec![0]; + b(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-rec.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-rec.rs new file mode 100644 index 000000000000..c1463423709b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-rec.rs @@ -0,0 +1,16 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn build() -> Vec { + panic!(); +} + +struct Blk { + node: Vec, +} + +fn main() { + let _blk = Blk { node: build() }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-rec2.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-rec2.rs new file mode 100644 index 000000000000..ac48254689bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-rec2.rs @@ -0,0 +1,24 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn build1() -> Vec { + vec![0, 0, 0, 0, 0, 0, 0] +} + +fn build2() -> Vec { + panic!(); +} + +struct Blk { + node: Vec, + span: Vec, +} + +fn main() { + let _blk = Blk { + node: build1(), + span: build2(), + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-unique.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-unique.rs new file mode 100644 index 000000000000..faf281d110c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/unwind-unique.rs @@ -0,0 +1,13 @@ +// run-fail +// error-pattern:explicit panic +// ignore-emscripten no processes + +fn failfn() { + panic!(); +} + +fn main() { + Box::new(0); + failfn(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/want-unwind-got-abort.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/want-unwind-got-abort.rs new file mode 100644 index 000000000000..042137fada96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/want-unwind-got-abort.rs @@ -0,0 +1,12 @@ +// build-fail +// error-pattern:is incompatible with this crate's strategy of `unwind` +// aux-build:panic-runtime-abort.rs +// aux-build:panic-runtime-lang-items.rs +// ignore-wasm32-bare compiled with panic=abort by default + +#![no_std] +#![no_main] + +extern crate panic_runtime_abort; +extern crate panic_runtime_lang_items; + diff --git a/gcc/testsuite/rust/rustc/ui/panic-runtime/want-unwind-got-abort2.rs b/gcc/testsuite/rust/rustc/ui/panic-runtime/want-unwind-got-abort2.rs new file mode 100644 index 000000000000..78f42269bf6b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-runtime/want-unwind-got-abort2.rs @@ -0,0 +1,13 @@ +// build-fail +// error-pattern:is incompatible with this crate's strategy of `unwind` +// aux-build:panic-runtime-abort.rs +// aux-build:wants-panic-runtime-abort.rs +// aux-build:panic-runtime-lang-items.rs +// ignore-wasm32-bare compiled with panic=abort by default + +#![no_std] +#![no_main] + +extern crate wants_panic_runtime_abort; +extern crate panic_runtime_lang_items; + diff --git a/gcc/testsuite/rust/rustc/ui/panic-while-printing.rs b/gcc/testsuite/rust/rustc/ui/panic-while-printing.rs new file mode 100644 index 000000000000..facf58dd58ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic-while-printing.rs @@ -0,0 +1,40 @@ +// run-pass +// ignore-emscripten no subprocess support + +#![feature(set_stdio)] + +use std::fmt; +use std::fmt::{Display, Formatter}; +use std::io::{self, set_panic, LocalOutput, Write}; + +pub struct A; + +impl Display for A { + fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result { + panic!(); + } +} + +struct Sink; +impl Write for Sink { + fn write(&mut self, buf: &[u8]) -> io::Result { + Ok(buf.len()) + } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} +impl LocalOutput for Sink { + fn clone_box(&self) -> Box { + Box::new(Sink) + } +} + +fn main() { + set_panic(Some(Box::new(Sink))); + assert!(std::panic::catch_unwind(|| { + eprintln!("{}", A); + }) + .is_err()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panic_implementation-closures.rs b/gcc/testsuite/rust/rustc/ui/panic_implementation-closures.rs new file mode 100644 index 000000000000..0c5516275553 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panic_implementation-closures.rs @@ -0,0 +1,11 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![crate_type = "rlib"] +#![no_std] + +#[panic_handler] +pub fn panic_fmt(_: &::core::panic::PanicInfo) -> ! { + |x: u8| x; + loop {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/abort-on-panic.rs b/gcc/testsuite/rust/rustc/ui/panics/abort-on-panic.rs new file mode 100644 index 000000000000..830ada070e2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/abort-on-panic.rs @@ -0,0 +1,65 @@ +// run-pass + +#![allow(unused_must_use)] +#![feature(unwind_attributes)] +// Since we mark some ABIs as "nounwind" to LLVM, we must make sure that +// we never unwind through them. + +// ignore-cloudabi no env and process +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::{env, panic}; +use std::io::prelude::*; +use std::io; +use std::process::{Command, Stdio}; + +#[unwind(aborts)] // FIXME(#58794) should work even without the attribute +extern "C" fn panic_in_ffi() { + panic!("Test"); +} + +#[unwind(aborts)] +extern "Rust" fn panic_in_rust_abi() { + panic!("TestRust"); +} + +fn test() { + let _ = panic::catch_unwind(|| { panic_in_ffi(); }); + // The process should have aborted by now. + io::stdout().write(b"This should never be printed.\n"); + let _ = io::stdout().flush(); +} + +fn testrust() { + let _ = panic::catch_unwind(|| { panic_in_rust_abi(); }); + // The process should have aborted by now. + io::stdout().write(b"This should never be printed.\n"); + let _ = io::stdout().flush(); +} + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 { + // This is inside the self-executed command. + match &*args[1] { + "test" => return test(), + "testrust" => return testrust(), + _ => panic!("bad test"), + } + } + + // These end up calling the self-execution branches above. + let mut p = Command::new(&args[0]) + .stdout(Stdio::piped()) + .stdin(Stdio::piped()) + .arg("test").spawn().unwrap(); + assert!(!p.wait().unwrap().success()); + + let mut p = Command::new(&args[0]) + .stdout(Stdio::piped()) + .stdin(Stdio::piped()) + .arg("testrust").spawn().unwrap(); + assert!(!p.wait().unwrap().success()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/args-panic.rs b/gcc/testsuite/rust/rustc/ui/panics/args-panic.rs new file mode 100644 index 000000000000..24d2c47dd39e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/args-panic.rs @@ -0,0 +1,14 @@ +// run-fail +// error-pattern:meep +// ignore-emscripten no processes + +#![feature(box_syntax)] + +fn f(_a: isize, _b: isize, _c: Box) { + panic!("moop"); +} + +fn main() { + f(1, panic!("meep"), box 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/doublepanic.rs b/gcc/testsuite/rust/rustc/ui/panics/doublepanic.rs new file mode 100644 index 000000000000..1f564562eca5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/doublepanic.rs @@ -0,0 +1,11 @@ +#![allow(unreachable_code)] + +// run-fail +// error-pattern:One +// ignore-emscripten no processes + +fn main() { + panic!("One"); + panic!("Two"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/explicit-panic-msg.rs b/gcc/testsuite/rust/rustc/ui/panics/explicit-panic-msg.rs new file mode 100644 index 000000000000..71b7d7b4b4a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/explicit-panic-msg.rs @@ -0,0 +1,15 @@ +#![allow(unused_assignments)] +#![allow(unused_variables)] + +// run-fail +// error-pattern:wooooo +// ignore-emscripten no processes + +fn main() { + let mut a = 1; + if 1 == 1 { + a = 2; + } + panic!(format!("woooo{}", "o")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/explicit-panic.rs b/gcc/testsuite/rust/rustc/ui/panics/explicit-panic.rs new file mode 100644 index 000000000000..d04f08a496e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/explicit-panic.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:explicit +// ignore-emscripten no processes + +fn main() { + panic!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/fmt-panic.rs b/gcc/testsuite/rust/rustc/ui/panics/fmt-panic.rs new file mode 100644 index 000000000000..38ab53efdbd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/fmt-panic.rs @@ -0,0 +1,9 @@ +// run-fail +// error-pattern:meh +// ignore-emscripten no processes + +fn main() { + let str_var: String = "meh".to_string(); + panic!("{}", str_var); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/issue-47429-short-backtraces.rs b/gcc/testsuite/rust/rustc/ui/panics/issue-47429-short-backtraces.rs new file mode 100644 index 000000000000..f146a24e1842 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/issue-47429-short-backtraces.rs @@ -0,0 +1,19 @@ +// Regression test for #47429: short backtraces were not terminating correctly + +// compile-flags: -O +// run-fail +// check-run-results +// exec-env:RUST_BACKTRACE=1 + +// ignore-msvc see #62897 and `backtrace-debuginfo.rs` test +// ignore-android FIXME #17520 +// ignore-cloudabi spawning processes is not supported +// ignore-openbsd no support for libbacktrace without filename +// ignore-wasm no panic or subprocess support +// ignore-emscripten no panic or subprocess support +// ignore-sgx no subprocess support + +fn main() { + panic!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/main-panic.rs b/gcc/testsuite/rust/rustc/ui/panics/main-panic.rs new file mode 100644 index 000000000000..35a66f03bec2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/main-panic.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:thread 'main' panicked at +// ignore-emscripten no processes + +fn main() { + panic!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-arg.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-arg.rs new file mode 100644 index 000000000000..728add1c5c32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-arg.rs @@ -0,0 +1,12 @@ +// run-fail +// error-pattern:woe +// ignore-emscripten no processes + +fn f(a: isize) { + println!("{}", a); +} + +fn main() { + f(panic!("woe")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-handler-chain.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-handler-chain.rs new file mode 100644 index 000000000000..65cc2204e8a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-handler-chain.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(stable_features)] + +// ignore-emscripten no threads support + +#![feature(std_panic)] + +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::panic; +use std::thread; + +static A: AtomicUsize = AtomicUsize::new(0); +static B: AtomicUsize = AtomicUsize::new(0); + +fn main() { + panic::set_hook(Box::new(|_| { A.fetch_add(1, Ordering::SeqCst); })); + let hook = panic::take_hook(); + panic::set_hook(Box::new(move |info| { + B.fetch_add(1, Ordering::SeqCst); + hook(info); + })); + + let _ = thread::spawn(|| { + panic!(); + }).join(); + + assert_eq!(1, A.load(Ordering::SeqCst)); + assert_eq!(1, B.load(Ordering::SeqCst)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-handler-flail-wildly.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-handler-flail-wildly.rs new file mode 100644 index 000000000000..02094fd6a5a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-handler-flail-wildly.rs @@ -0,0 +1,56 @@ +// run-pass + +#![allow(stable_features)] +#![allow(unused_must_use)] + +// ignore-emscripten no threads support + +#![feature(std_panic)] + +use std::panic; +use std::thread; + +fn a() { + panic::set_hook(Box::new(|_| println!("hello yes this is a"))); + panic::take_hook(); + panic::set_hook(Box::new(|_| println!("hello yes this is a part 2"))); + panic::take_hook(); +} + +fn b() { + panic::take_hook(); + panic::take_hook(); + panic::take_hook(); + panic::take_hook(); + panic::take_hook(); + panic!(); +} + +fn c() { + panic::set_hook(Box::new(|_| ())); + panic::set_hook(Box::new(|_| ())); + panic::set_hook(Box::new(|_| ())); + panic::set_hook(Box::new(|_| ())); + panic::set_hook(Box::new(|_| ())); + panic::set_hook(Box::new(|_| ())); + panic!(); +} + +fn main() { + for _ in 0..10 { + let mut handles = vec![]; + for _ in 0..10 { + handles.push(thread::spawn(a)); + } + for _ in 0..10 { + handles.push(thread::spawn(b)); + } + for _ in 0..10 { + handles.push(thread::spawn(c)); + } + for handle in handles { + let _ = handle.join(); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-handler-set-twice.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-handler-set-twice.rs new file mode 100644 index 000000000000..5fdcd40af211 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-handler-set-twice.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(unused_variables)] +#![allow(stable_features)] + +#![feature(std_panic)] + +// ignore-emscripten no threads support + +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::panic; +use std::thread; + +static A: AtomicUsize = AtomicUsize::new(0); + +fn main() { + panic::set_hook(Box::new(|_| ())); + panic::set_hook(Box::new(|info| { A.fetch_add(1, Ordering::SeqCst); })); + + let _ = thread::spawn(|| { + panic!(); + }).join(); + + assert_eq!(1, A.load(Ordering::SeqCst)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-in-dtor-drops-fields.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-in-dtor-drops-fields.rs new file mode 100644 index 000000000000..9590bdf76eb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-in-dtor-drops-fields.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +// ignore-emscripten no threads support + +use std::thread; + +static mut dropped: bool = false; + +struct A { + b: B, +} + +struct B { + foo: isize, +} + +impl Drop for A { + fn drop(&mut self) { + panic!() + } +} + +impl Drop for B { + fn drop(&mut self) { + unsafe { dropped = true; } + } +} + +pub fn main() { + let ret = thread::spawn(move|| { + let _a = A { b: B { foo: 3 } }; + }).join(); + assert!(ret.is_err()); + unsafe { assert!(dropped); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-macro-any-wrapped.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-macro-any-wrapped.rs new file mode 100644 index 000000000000..90730e70ce98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-macro-any-wrapped.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:panicked at 'Box' +// ignore-emscripten no processes + +fn main() { + panic!(Box::new(612_i64)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-macro-any.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-macro-any.rs new file mode 100644 index 000000000000..156ceb2f8d36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-macro-any.rs @@ -0,0 +1,10 @@ +// run-fail +// error-pattern:panicked at 'Box' +// ignore-emscripten no processes + +#![feature(box_syntax)] + +fn main() { + panic!(box 413 as Box); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-macro-explicit.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-macro-explicit.rs new file mode 100644 index 000000000000..989baf78ad7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-macro-explicit.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:panicked at 'explicit panic' +// ignore-emscripten no processes + +fn main() { + panic!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-macro-fmt.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-macro-fmt.rs new file mode 100644 index 000000000000..8752df8fafae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-macro-fmt.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:panicked at 'test-fail-fmt 42 rust' +// ignore-emscripten no processes + +fn main() { + panic!("test-fail-fmt {} {}", 42, "rust"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-macro-owned.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-macro-owned.rs new file mode 100644 index 000000000000..3c5c5ec8801e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-macro-owned.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:panicked at 'test-fail-owned' +// ignore-emscripten no processes + +fn main() { + panic!("test-fail-owned"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-macro-static.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-macro-static.rs new file mode 100644 index 000000000000..4d28eb5725fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-macro-static.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:panicked at 'test-fail-static' +// ignore-emscripten no processes + +fn main() { + panic!("test-fail-static"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-main.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-main.rs new file mode 100644 index 000000000000..70e1ce3e4c05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-main.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:moop +// ignore-emscripten no processes + +fn main() { + panic!("moop"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-parens.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-parens.rs new file mode 100644 index 000000000000..b3cc2e17d0ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-parens.rs @@ -0,0 +1,21 @@ +// Fail macros without arguments need to be disambiguated in +// certain positions + +// run-fail +// error-pattern:oops +// ignore-emscripten no processes + +fn bigpanic() { + while (panic!("oops")) { + if (panic!()) { + match (panic!()) { + () => {} + } + } + } +} + +fn main() { + bigpanic(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-recover-propagate.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-recover-propagate.rs new file mode 100644 index 000000000000..b2834d7bbf71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-recover-propagate.rs @@ -0,0 +1,27 @@ +// run-pass +// ignore-emscripten no threads support + +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::panic; +use std::thread; + +static A: AtomicUsize = AtomicUsize::new(0); + +fn main() { + panic::set_hook(Box::new(|_| { + A.fetch_add(1, Ordering::SeqCst); + })); + + let result = thread::spawn(|| { + let result = panic::catch_unwind(|| { + panic!("hi there"); + }); + + panic::resume_unwind(result.unwrap_err()); + }).join(); + + let msg = *result.unwrap_err().downcast::<&'static str>().unwrap(); + assert_eq!("hi there", msg); + assert_eq!(1, A.load(Ordering::SeqCst)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-set-handler.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-set-handler.rs new file mode 100644 index 000000000000..3abac6fde20b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-set-handler.rs @@ -0,0 +1,13 @@ +// run-fail +// error-pattern:greetings from the panic handler +// ignore-emscripten no processes + +use std::panic; + +fn main() { + panic::set_hook(Box::new(|i| { + eprintln!("greetings from the panic handler"); + })); + panic!("foobar"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-set-unset-handler.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-set-unset-handler.rs new file mode 100644 index 000000000000..802b00449774 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-set-unset-handler.rs @@ -0,0 +1,14 @@ +// run-fail +// error-pattern:thread 'main' panicked at 'foobar' +// ignore-emscripten no processes + +use std::panic; + +fn main() { + panic::set_hook(Box::new(|i| { + eprint!("greetings from the panic handler"); + })); + panic::take_hook(); + panic!("foobar"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-take-handler-nop.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-take-handler-nop.rs new file mode 100644 index 000000000000..79748cc5f6c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-take-handler-nop.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:thread 'main' panicked at 'foobar' +// ignore-emscripten no processes + +use std::panic; + +fn main() { + panic::take_hook(); + panic!("foobar"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-task-name-none.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-task-name-none.rs new file mode 100644 index 000000000000..d25addecf670 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-task-name-none.rs @@ -0,0 +1,14 @@ +// run-fail +// error-pattern:thread '' panicked at 'test' +// ignore-emscripten Needs threads + +use std::thread; + +fn main() { + let r: Result<(), _> = thread::spawn(move || { + panic!("test"); + }) + .join(); + assert!(r.is_ok()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic-task-name-owned.rs b/gcc/testsuite/rust/rustc/ui/panics/panic-task-name-owned.rs new file mode 100644 index 000000000000..7e935ed162c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic-task-name-owned.rs @@ -0,0 +1,19 @@ +// run-fail +// error-pattern:thread 'owned name' panicked at 'test' +// ignore-emscripten Needs threads. + +use std::thread::Builder; + +fn main() { + let r: () = Builder::new() + .name("owned name".to_string()) + .spawn(move || { + panic!("test"); + () + }) + .unwrap() + .join() + .unwrap(); + panic!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/panic.rs b/gcc/testsuite/rust/rustc/ui/panics/panic.rs new file mode 100644 index 000000000000..dc9d9998333f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/panic.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:1 == 2 +// ignore-emscripten no processes + +fn main() { + assert!(1 == 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/result-get-panic.rs b/gcc/testsuite/rust/rustc/ui/panics/result-get-panic.rs new file mode 100644 index 000000000000..d48af3093fba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/result-get-panic.rs @@ -0,0 +1,10 @@ +// run-fail +// error-pattern:called `Result::unwrap()` on an `Err` value +// ignore-emscripten no processes + +use std::result::Result::Err; + +fn main() { + println!("{}", Err::("kitty".to_string()).unwrap()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/test-panic.rs b/gcc/testsuite/rust/rustc/ui/panics/test-panic.rs new file mode 100644 index 000000000000..59979f4af9da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/test-panic.rs @@ -0,0 +1,10 @@ +// run-fail +// check-stdout +// compile-flags: --test +// ignore-emscripten + +#[test] +fn test_foo() { + panic!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/test-should-fail-bad-message.rs b/gcc/testsuite/rust/rustc/ui/panics/test-should-fail-bad-message.rs new file mode 100644 index 000000000000..9ee584be5d5a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/test-should-fail-bad-message.rs @@ -0,0 +1,11 @@ +// run-fail +// check-stdout +// compile-flags: --test +// ignore-emscripten + +#[test] +#[should_panic(expected = "foobar")] +fn test_foo() { + panic!("blah") +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/test-should-panic-bad-message.rs b/gcc/testsuite/rust/rustc/ui/panics/test-should-panic-bad-message.rs new file mode 100644 index 000000000000..234aaf2b1a68 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/test-should-panic-bad-message.rs @@ -0,0 +1,11 @@ +// run-fail +// compile-flags: --test +// check-stdout +// ignore-emscripten no processes + +#[test] +#[should_panic(expected = "foo")] +pub fn test_bar() { + panic!("bar") +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/test-should-panic-no-message.rs b/gcc/testsuite/rust/rustc/ui/panics/test-should-panic-no-message.rs new file mode 100644 index 000000000000..b4223e82e733 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/test-should-panic-no-message.rs @@ -0,0 +1,11 @@ +// run-fail +// compile-flags: --test +// check-stdout +// ignore-emscripten no processes + +#[test] +#[should_panic(expected = "foo")] +pub fn test_explicit() { + panic!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/unique-panic.rs b/gcc/testsuite/rust/rustc/ui/panics/unique-panic.rs new file mode 100644 index 000000000000..2d5a6c6cc55b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/unique-panic.rs @@ -0,0 +1,7 @@ +// run-fail +// error-pattern: panic + +fn main() { + Box::new(panic!()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/while-body-panics.rs b/gcc/testsuite/rust/rustc/ui/panics/while-body-panics.rs new file mode 100644 index 000000000000..25024913ffce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/while-body-panics.rs @@ -0,0 +1,15 @@ +#![allow(while_true)] + +// run-fail +// error-pattern:quux +// ignore-emscripten no processes + +fn main() { + let _x: isize = { + while true { + panic!("quux"); + } + 8 + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/panics/while-panic.rs b/gcc/testsuite/rust/rustc/ui/panics/while-panic.rs new file mode 100644 index 000000000000..2eb4c39504f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/panics/while-panic.rs @@ -0,0 +1,15 @@ +#![allow(while_true)] + +// run-fail +// error-pattern:giraffe +// ignore-emscripten no processes + +fn main() { + panic!({ + while true { + panic!("giraffe") + } + "clandestine" + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/paren-free.rs b/gcc/testsuite/rust/rustc/ui/paren-free.rs new file mode 100644 index 000000000000..76455ac65ce1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/paren-free.rs @@ -0,0 +1,8 @@ +// run-pass + +pub fn main() { + let x = true; + if x { let mut i = 10; while i > 0 { i -= 1; } } + match x { true => { println!("right"); } false => { println!("wrong"); } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/paren-span.rs b/gcc/testsuite/rust/rustc/ui/paren-span.rs new file mode 100644 index 000000000000..d1ab0f9438bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/paren-span.rs @@ -0,0 +1,22 @@ +// Be smart about span of parenthesized expression in macro. + +macro_rules! paren { + ($e:expr) => (($e)) + // ^^^^ do not highlight here +} + +mod m { + pub struct S { + x: i32 + } + pub fn make() -> S { + S { x: 0 } + } +} + +fn main() { + let s = m::make(); + paren!(s.x); // { dg-error ".E0616." "" { target *-*-* } } + // ^^^ highlight here +} + diff --git a/gcc/testsuite/rust/rustc/ui/parenthesized-deref-suggestion.rs b/gcc/testsuite/rust/rustc/ui/parenthesized-deref-suggestion.rs new file mode 100644 index 000000000000..59a13c1e710e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parenthesized-deref-suggestion.rs @@ -0,0 +1,12 @@ +struct Session { + opts: u8, +} + +fn main() { + let sess: &Session = &Session { opts: 0 }; + (sess as *const Session).opts; // { dg-error ".E0609." "" { target *-*-* } } + + let x = [0u32]; + (x as [u32; 1]).0; // { dg-error ".E0609." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parse-assoc-type-lt.rs b/gcc/testsuite/rust/rustc/ui/parse-assoc-type-lt.rs new file mode 100644 index 000000000000..325ac75f1f2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parse-assoc-type-lt.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Foo { + type T; + fn foo() -> Box<::T>; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parse-error-correct.rs b/gcc/testsuite/rust/rustc/ui/parse-error-correct.rs new file mode 100644 index 000000000000..776c10ac455d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parse-error-correct.rs @@ -0,0 +1,11 @@ +// Test that the parser is error correcting missing idents. Despite a parsing +// error (or two), we still run type checking (and don't get extra errors there). + +fn main() { + let y = 42; + let x = y.; // { dg-error "" "" { target *-*-* } } + let x = y.(); // { dg-error ".E0618." "" { target *-*-* } } +// { dg-error ".E0618." "" { target *-*-* } .-1 } + let x = y.foo; // { dg-error ".E0610." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parse-panic.rs b/gcc/testsuite/rust/rustc/ui/parse-panic.rs new file mode 100644 index 000000000000..be982c8a8ade --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parse-panic.rs @@ -0,0 +1,9 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unreachable_code)] + +fn dont_call_me() { panic!(); println!("{}", 1); } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/parser-recovery-1.rs b/gcc/testsuite/rust/rustc/ui/parser-recovery-1.rs new file mode 100644 index 000000000000..e4f5c1be4b17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser-recovery-1.rs @@ -0,0 +1,14 @@ +// Test that we can recover from missing braces in the parser. + +trait Foo { + fn bar() { + let x = foo(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +} + +fn main() { + let x = y.; +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { dg-error ".E0425." "" { target *-*-* } .-2 } +} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser-recovery-2.rs b/gcc/testsuite/rust/rustc/ui/parser-recovery-2.rs new file mode 100644 index 000000000000..6b28c24d25ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser-recovery-2.rs @@ -0,0 +1,13 @@ +// Test that we can recover from mismatched braces in the parser. + +trait Foo { + fn bar() { + let x = foo(); // { dg-error ".E0425." "" { target *-*-* } } + ) // { dg-error "" "" { target *-*-* } } +} + +fn main() { + let x = y.; // { dg-error ".E0425." "" { target *-*-* } } +// { dg-error ".E0425." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser-unicode-whitespace.rs b/gcc/testsuite/rust/rustc/ui/parser-unicode-whitespace.rs new file mode 100644 index 000000000000..97893b987604 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser-unicode-whitespace.rs @@ -0,0 +1,13 @@ +// run-pass +// Beware editing: it has numerous whitespace characters which are important. +// It contains one ranges from the 'PATTERN_WHITE_SPACE' property outlined in +// http://unicode.org/Public/UNIDATA/PropList.txt +// +// The characters in the first expression of the assertion can be generated +// from: "4\u{0C}+\n\t\r7\t*\u{20}2\u{85}/\u{200E}3\u{200F}*\u{2028}2\u{2029}" +pub fn main() { +assert_eq!(4 + + +7 * 2…/‎3‏*
2
, 4 + 7 * 2 / 3 * 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/ascii-only-character-escape.rs b/gcc/testsuite/rust/rustc/ui/parser/ascii-only-character-escape.rs new file mode 100644 index 000000000000..7d51940057a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/ascii-only-character-escape.rs @@ -0,0 +1,7 @@ +fn main() { + let x = "\x80"; // { dg-error "" "" { target *-*-* } } + let y = "\xff"; // { dg-error "" "" { target *-*-* } } + let z = "\xe2"; // { dg-error "" "" { target *-*-* } } + let a = b"\x00e2"; // ok because byte literal +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/assoc-const-underscore-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/assoc-const-underscore-semantic-fail.rs new file mode 100644 index 000000000000..a10fd35374b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/assoc-const-underscore-semantic-fail.rs @@ -0,0 +1,18 @@ +// Semantically, an associated constant cannot use `_` as a name. + +fn main() {} + +const _: () = { + pub trait A { + const _: () = (); // { dg-error "" "" { target *-*-* } } + } + impl A for () { + const _: () = (); // { dg-error ".E0438." "" { target *-*-* } } +// { dg-error ".E0438." "" { target *-*-* } .-1 } + } + struct B; + impl B { + const _: () = (); // { dg-error "" "" { target *-*-* } } + } +}; + diff --git a/gcc/testsuite/rust/rustc/ui/parser/assoc-const-underscore-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/assoc-const-underscore-syntactic-pass.rs new file mode 100644 index 000000000000..de3ea855fcc9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/assoc-const-underscore-syntactic-pass.rs @@ -0,0 +1,19 @@ +// All constant items (associated or otherwise) may syntactically use `_` as a name. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +const _: () = { + pub trait A { + const _: () = (); + } + impl A for () { + const _: () = (); + } + impl dyn A { + const _: () = (); + } +}; + diff --git a/gcc/testsuite/rust/rustc/ui/parser/assoc-oddities-1.rs b/gcc/testsuite/rust/rustc/ui/parser/assoc-oddities-1.rs new file mode 100644 index 000000000000..09f14109f35e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/assoc-oddities-1.rs @@ -0,0 +1,12 @@ +// compile-flags: -Z parse-only + +fn main() { + // following lines below parse and must not fail + x = if c { a } else { b }(); + x = if true { 1 } else { 0 } as *mut _; + // however this does not parse and probably should fail to retain compat? + // N.B., `..` here is arbitrary, failure happens/should happen ∀ops that aren’t `=` + // see assoc-oddities-2 and assoc-oddities-3 + ..if c { a } else { b }[n]; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/assoc-oddities-2.rs b/gcc/testsuite/rust/rustc/ui/parser/assoc-oddities-2.rs new file mode 100644 index 000000000000..878d411d007e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/assoc-oddities-2.rs @@ -0,0 +1,7 @@ +// compile-flags: -Z parse-only + +fn main() { + // see assoc-oddities-1 for explanation + x..if c { a } else { b }[n]; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/assoc-static-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/assoc-static-semantic-fail.rs new file mode 100644 index 000000000000..dac43b7400c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/assoc-static-semantic-fail.rs @@ -0,0 +1,53 @@ +// Semantically, we do not allow e.g., `static X: u8 = 0;` as an associated item. + +#![feature(specialization)] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + +struct S; +impl S { + static IA: u8 = 0; +// { dg-error "" "" { target *-*-* } .-1 } + static IB: u8; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + default static IC: u8 = 0; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + pub(crate) default static ID: u8; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +} + +trait T { + static TA: u8 = 0; +// { dg-error "" "" { target *-*-* } .-1 } + static TB: u8; +// { dg-error "" "" { target *-*-* } .-1 } + default static TC: u8 = 0; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + pub(crate) default static TD: u8; +// { dg-error ".E0449." "" { target *-*-* } .-1 } +// { dg-error ".E0449." "" { target *-*-* } .-2 } +// { dg-error ".E0449." "" { target *-*-* } .-3 } +} + +impl T for S { + static TA: u8 = 0; +// { dg-error "" "" { target *-*-* } .-1 } + static TB: u8; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + default static TC: u8 = 0; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + pub default static TD: u8; +// { dg-error ".E0449." "" { target *-*-* } .-1 } +// { dg-error ".E0449." "" { target *-*-* } .-2 } +// { dg-error ".E0449." "" { target *-*-* } .-3 } +// { dg-error ".E0449." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/assoc-static-syntactic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/assoc-static-syntactic-fail.rs new file mode 100644 index 000000000000..3ad4937d9485 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/assoc-static-syntactic-fail.rs @@ -0,0 +1,34 @@ +// Syntactically, we do allow e.g., `static X: u8 = 0;` as an associated item. + +fn main() {} + +#[cfg(FALSE)] +impl S { + static IA: u8 = 0; // { dg-error "" "" { target *-*-* } } + static IB: u8; // { dg-error "" "" { target *-*-* } } + default static IC: u8 = 0; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + pub(crate) default static ID: u8; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(FALSE)] +trait T { + static TA: u8 = 0; // { dg-error "" "" { target *-*-* } } + static TB: u8; // { dg-error "" "" { target *-*-* } } + default static TC: u8 = 0; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + pub(crate) default static TD: u8; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(FALSE)] +impl T for S { + static TA: u8 = 0; // { dg-error "" "" { target *-*-* } } + static TB: u8; // { dg-error "" "" { target *-*-* } } + default static TC: u8 = 0; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + pub default static TD: u8; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/assoc-type-in-type-arg.rs b/gcc/testsuite/rust/rustc/ui/parser/assoc-type-in-type-arg.rs new file mode 100644 index 000000000000..9adca6a53f9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/assoc-type-in-type-arg.rs @@ -0,0 +1,12 @@ +trait Tr { + type TrSubtype; +} + +struct Bar<'a, Item: Tr, ::TrSubtype: 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + item: Item, + item_sub: &'a ::TrSubtype, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/associated-types-project-from-hrtb-explicit.rs b/gcc/testsuite/rust/rustc/ui/parser/associated-types-project-from-hrtb-explicit.rs new file mode 100644 index 000000000000..a2744277da42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/associated-types-project-from-hrtb-explicit.rs @@ -0,0 +1,17 @@ +// Test you can't use a higher-ranked trait bound inside of a qualified +// path (just won't parse). + +pub trait Foo { + type A; + + fn get(&self, t: T) -> Self::A; +} + +fn foo2(x: Foo<&'x isize>>::A) +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +{ +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/attr-bad-meta-2.rs b/gcc/testsuite/rust/rustc/ui/parser/attr-bad-meta-2.rs new file mode 100644 index 000000000000..b45a69a4ea63 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/attr-bad-meta-2.rs @@ -0,0 +1,3 @@ +#[path =] // { dg-error "" "" { target *-*-* } } +mod m {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/attr-bad-meta-3.rs b/gcc/testsuite/rust/rustc/ui/parser/attr-bad-meta-3.rs new file mode 100644 index 000000000000..959822cd2f07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/attr-bad-meta-3.rs @@ -0,0 +1,3 @@ +#[path() token] // { dg-error "" "" { target *-*-* } } +mod m {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/attr-bad-meta.rs b/gcc/testsuite/rust/rustc/ui/parser/attr-bad-meta.rs new file mode 100644 index 000000000000..66d069041086 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/attr-bad-meta.rs @@ -0,0 +1,3 @@ +#[path*] // { dg-error "" "" { target *-*-* } } +mod m {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/attr-before-eof.rs b/gcc/testsuite/rust/rustc/ui/parser/attr-before-eof.rs new file mode 100644 index 000000000000..df6b002397dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/attr-before-eof.rs @@ -0,0 +1,4 @@ +fn main() {} + +#[derive(Debug)] // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/attr-dangling-in-fn.rs b/gcc/testsuite/rust/rustc/ui/parser/attr-dangling-in-fn.rs new file mode 100644 index 000000000000..31299312cacb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/attr-dangling-in-fn.rs @@ -0,0 +1,9 @@ +// error-pattern:expected statement + +fn f() { + #[foo = "bar"] +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/attr-dangling-in-mod.rs b/gcc/testsuite/rust/rustc/ui/parser/attr-dangling-in-mod.rs new file mode 100644 index 000000000000..379895a6451c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/attr-dangling-in-mod.rs @@ -0,0 +1,7 @@ +// error-pattern:expected item + +fn main() { +} + +#[foo = "bar"] + diff --git a/gcc/testsuite/rust/rustc/ui/parser/attr-stmt-expr-attr-bad.rs b/gcc/testsuite/rust/rustc/ui/parser/attr-stmt-expr-attr-bad.rs new file mode 100644 index 000000000000..827a3abf222d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/attr-stmt-expr-attr-bad.rs @@ -0,0 +1,112 @@ +#![feature(half_open_range_patterns)] + +fn main() {} + +#[cfg(FALSE)] fn e() { let _ = box #![attr] 0; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = [#[attr]]; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = foo#[attr](); } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = foo(#![attr]); } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +#[cfg(FALSE)] fn e() { let _ = x.foo(#![attr]); } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +#[cfg(FALSE)] fn e() { let _ = 0 + #![attr] 0; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = !#![attr] 0; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = -#![attr] 0; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = x #![attr] as Y; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = || #![attr] foo; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = move || #![attr] foo; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = || #![attr] {foo}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = #[attr] ..; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if 0 {#![attr]}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if 0 {} #[attr] else {}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if 0 {} else {#![attr]}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {#![attr]}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {#![attr]}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} #[attr] else {}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {#![attr]}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {#![attr]}; } +// { dg-error "" "" { target *-*-* } .-1 } + +#[cfg(FALSE)] fn s() { #[attr] #![attr] let _ = 0; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn s() { #[attr] #![attr] 0; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn s() { #[attr] #![attr] foo!(); } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn s() { #[attr] #![attr] foo![]; } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn s() { #[attr] #![attr] foo!{}; } +// { dg-error "" "" { target *-*-* } .-1 } + +// FIXME: Allow attributes in pattern constexprs? +// note: requires parens in patterns to allow disambiguation + +#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } } +// { dg-error ".E0586." "" { target *-*-* } .-1 } +// { dg-error ".E0586." "" { target *-*-* } .-2 } +#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } } +// { dg-error ".E0586." "" { target *-*-* } .-1 } +// { dg-error ".E0586." "" { target *-*-* } .-2 } +#[cfg(FALSE)] fn e() { match 0 { 0..=-#[attr] 10 => () } } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } } +// { dg-error ".E0586." "" { target *-*-* } .-1 } +// { dg-error ".E0586." "" { target *-*-* } .-2 } + +#[cfg(FALSE)] fn e() { let _ = x.#![attr]foo(); } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +#[cfg(FALSE)] fn e() { let _ = x.#[attr]foo(); } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +// make sure we don't catch this bug again... +#[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } } +// { dg-error "" "" { target *-*-* } .-1 } +#[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } } +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/attr.rs b/gcc/testsuite/rust/rustc/ui/parser/attr.rs new file mode 100644 index 000000000000..08c08f6e90cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/attr.rs @@ -0,0 +1,8 @@ +#![feature(lang_items)] + +fn main() {} + +#![lang = "foo"] // { dg-error ".E0522." "" { target *-*-* } } +// { dg-error ".E0522." "" { target *-*-* } .-2 } +fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/attrs-after-extern-mod.rs b/gcc/testsuite/rust/rustc/ui/parser/attrs-after-extern-mod.rs new file mode 100644 index 000000000000..0e0bed149d41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/attrs-after-extern-mod.rs @@ -0,0 +1,8 @@ +// Make sure there's an error when given `extern { ... #[attr] }`. + +fn main() {} + +extern { + #[cfg(stage37)] // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bad-char-literals.rs b/gcc/testsuite/rust/rustc/ui/parser/bad-char-literals.rs new file mode 100644 index 000000000000..c4fa583c69f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bad-char-literals.rs @@ -0,0 +1,21 @@ +// ignore-tidy-cr +// ignore-tidy-tab + +fn main() { + // these literals are just silly. + '''; +// { dg-error "" "" { target *-*-* } .-1 } + + // note that this is a literal "\n" byte + ' +'; +// { dg-error "" "" { target *-*-* } .-2 } + + // note that this is a literal "\r" byte + ' '; // { dg-error "" "" { target *-*-* } } + + // note that this is a literal tab character here + ' '; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bad-fn-ptr-qualifier.rs b/gcc/testsuite/rust/rustc/ui/parser/bad-fn-ptr-qualifier.rs new file mode 100644 index 000000000000..7ebd31ccd0bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bad-fn-ptr-qualifier.rs @@ -0,0 +1,27 @@ +// run-rustfix +// edition:2018 +// Most of items are taken from ./recover-const-async-fn-ptr.rs but this is able to apply rustfix. + +pub type T0 = const fn(); // { dg-error "" "" { target *-*-* } } +pub type T1 = const extern "C" fn(); // { dg-error "" "" { target *-*-* } } +pub type T2 = const unsafe extern fn(); // { dg-error "" "" { target *-*-* } } +pub type T3 = async fn(); // { dg-error "" "" { target *-*-* } } +pub type T4 = async extern fn(); // { dg-error "" "" { target *-*-* } } +pub type T5 = async unsafe extern "C" fn(); // { dg-error "" "" { target *-*-* } } +pub type T6 = const async unsafe extern "C" fn(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +pub type FTT0 = for<'a> const fn(); // { dg-error "" "" { target *-*-* } } +pub type FTT1 = for<'a> const extern "C" fn(); // { dg-error "" "" { target *-*-* } } +pub type FTT2 = for<'a> const unsafe extern fn(); // { dg-error "" "" { target *-*-* } } +pub type FTT3 = for<'a> async fn(); // { dg-error "" "" { target *-*-* } } +pub type FTT4 = for<'a> async extern fn(); // { dg-error "" "" { target *-*-* } } +pub type FTT5 = for<'a> async unsafe extern "C" fn(); +// { dg-error "" "" { target *-*-* } .-1 } +pub type FTT6 = for<'a> const async unsafe extern "C" fn(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bad-interpolated-block.rs b/gcc/testsuite/rust/rustc/ui/parser/bad-interpolated-block.rs new file mode 100644 index 000000000000..ebbfcf796977 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bad-interpolated-block.rs @@ -0,0 +1,16 @@ +#![feature(label_break_value)] + +fn main() {} + +macro_rules! m { + ($b:block) => { + 'lab: $b; // { dg-error "" "" { target *-*-* } } + unsafe $b; // { dg-error "" "" { target *-*-* } } + |x: u8| -> () $b; // { dg-error "" "" { target *-*-* } } + } +} + +fn foo() { + m!({}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bad-lit-suffixes.rs b/gcc/testsuite/rust/rustc/ui/parser/bad-lit-suffixes.rs new file mode 100644 index 000000000000..9bf720180a56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bad-lit-suffixes.rs @@ -0,0 +1,27 @@ +extern + "C"suffix // { dg-error "" "" { target *-*-* } } + fn foo() {} + +extern + "C"suffix // { dg-error "" "" { target *-*-* } } +{} + +fn main() { + ""suffix; // { dg-error "" "" { target *-*-* } } + b""suffix; // { dg-error "" "" { target *-*-* } } + r#""#suffix; // { dg-error "" "" { target *-*-* } } + br#""#suffix; // { dg-error "" "" { target *-*-* } } + 'a'suffix; // { dg-error "" "" { target *-*-* } } + b'a'suffix; // { dg-error "" "" { target *-*-* } } + + 1234u1024; // { dg-error "" "" { target *-*-* } } + 1234i1024; // { dg-error "" "" { target *-*-* } } + 1234f1024; // { dg-error "" "" { target *-*-* } } + 1234.5f1024; // { dg-error "" "" { target *-*-* } } + + 1234suffix; // { dg-error "" "" { target *-*-* } } + 0b101suffix; // { dg-error "" "" { target *-*-* } } + 1.0suffix; // { dg-error "" "" { target *-*-* } } + 1.0e10suffix; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bad-match.rs b/gcc/testsuite/rust/rustc/ui/parser/bad-match.rs new file mode 100644 index 000000000000..d67ec822f1f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bad-match.rs @@ -0,0 +1,5 @@ +fn main() { + let isize x = 5; // { dg-error "" "" { target *-*-* } } + match x; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bad-name.rs b/gcc/testsuite/rust/rustc/ui/parser/bad-name.rs new file mode 100644 index 000000000000..1ec14c67c4c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bad-name.rs @@ -0,0 +1,6 @@ +// error-pattern: expected + +fn main() { + let x.y::.z foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bad-pointer-type.rs b/gcc/testsuite/rust/rustc/ui/parser/bad-pointer-type.rs new file mode 100644 index 000000000000..080deb371268 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bad-pointer-type.rs @@ -0,0 +1,6 @@ +fn foo(_: *()) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bad-value-ident-false.rs b/gcc/testsuite/rust/rustc/ui/parser/bad-value-ident-false.rs new file mode 100644 index 000000000000..f1a902d2f44d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bad-value-ident-false.rs @@ -0,0 +1,3 @@ +fn false() { } // { dg-error "" "" { target *-*-* } } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bad-value-ident-true.rs b/gcc/testsuite/rust/rustc/ui/parser/bad-value-ident-true.rs new file mode 100644 index 000000000000..7ef85678bee5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bad-value-ident-true.rs @@ -0,0 +1,3 @@ +fn true() { } // { dg-error "" "" { target *-*-* } } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bare-struct-body.rs b/gcc/testsuite/rust/rustc/ui/parser/bare-struct-body.rs new file mode 100644 index 000000000000..b279b13ae7a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bare-struct-body.rs @@ -0,0 +1,16 @@ +struct Foo { + val: (), +} + +fn foo() -> Foo { // { dg-error "" "" { target *-*-* } } + val: (), +} + +fn main() { + let x = foo(); + x.val == 42; // { dg-error ".E0308." "" { target *-*-* } } + let x = { // { dg-error "" "" { target *-*-* } } + val: (), + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/better-expected.rs b/gcc/testsuite/rust/rustc/ui/parser/better-expected.rs new file mode 100644 index 000000000000..1ad5e4bad472 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/better-expected.rs @@ -0,0 +1,4 @@ +fn main() { + let x: [isize 3]; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bind-struct-early-modifiers.rs b/gcc/testsuite/rust/rustc/ui/parser/bind-struct-early-modifiers.rs new file mode 100644 index 000000000000..ba8336944987 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bind-struct-early-modifiers.rs @@ -0,0 +1,8 @@ +fn main() { + struct Foo { x: isize } + match (Foo { x: 10 }) { + Foo { ref x: ref x } => {}, // { dg-error "" "" { target *-*-* } } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/block-no-opening-brace.rs b/gcc/testsuite/rust/rustc/ui/parser/block-no-opening-brace.rs new file mode 100644 index 000000000000..4eb34ab00a5a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/block-no-opening-brace.rs @@ -0,0 +1,32 @@ +// edition:2018 + +#![feature(try_blocks)] + +fn main() {} + +fn f1() { + loop + let x = 0; // { dg-error "" "" { target *-*-* } } + drop(0); + } + +fn f2() { + while true + let x = 0; // { dg-error "" "" { target *-*-* } } + } + +fn f3() { + for x in 0..1 + let x = 0; // { dg-error "" "" { target *-*-* } } + } + +fn f4() { + try // { dg-error "" "" { target *-*-* } } + let x = 0; + } + +fn f5() { + async // { dg-error ".E0658." "" { target *-*-* } } + let x = 0; // { dg-error "" "" { target *-*-* } } + } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bound-single-question-mark.rs b/gcc/testsuite/rust/rustc/ui/parser/bound-single-question-mark.rs new file mode 100644 index 000000000000..2385f2be4b3d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bound-single-question-mark.rs @@ -0,0 +1,2 @@ +fn f() {} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-1.rs b/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-1.rs new file mode 100644 index 000000000000..23cd2f5d9656 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-1.rs @@ -0,0 +1,4 @@ +type A = for<'a 'b> fn(); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-2.rs b/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-2.rs new file mode 100644 index 000000000000..d9edc0d5e0b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-2.rs @@ -0,0 +1,4 @@ +type A = for<'a + 'b> fn(); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-where-1.rs b/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-where-1.rs new file mode 100644 index 000000000000..0ce334311d74 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-where-1.rs @@ -0,0 +1,4 @@ +type A where 'a; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-where.rs b/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-where.rs new file mode 100644 index 000000000000..d0a4b37c8621 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime-where.rs @@ -0,0 +1,11 @@ +type A where 'a: 'b + 'c = u8; // OK +type A where 'a: 'b, = u8; // OK +type A where 'a: = u8; // OK +type A where 'a:, = u8; // OK +type A where 'a: 'b + 'c = u8; // OK +type A where = u8; // OK +type A where 'a: 'b + = u8; // OK +type A where , = u8; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime.rs b/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime.rs new file mode 100644 index 000000000000..dbdbb7082e0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bounds-lifetime.rs @@ -0,0 +1,12 @@ +type A = for<'a:> fn(); // OK +type A = for<'a:,> fn(); // OK +type A = for<'a> fn(); // OK +type A = for<> fn(); // OK +type A = for<'a: 'b + 'c> fn(); // OK (rejected later by ast_validation) +type A = for<'a: 'b,> fn(); // OK(rejected later by ast_validation) +type A = for<'a: 'b +> fn(); // OK (rejected later by ast_validation) +type A = for<'a, T> fn(); // OK (rejected later by ast_validation) +type A = for<,> fn(); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bounds-obj-parens.rs b/gcc/testsuite/rust/rustc/ui/parser/bounds-obj-parens.rs new file mode 100644 index 000000000000..546cd9287610 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bounds-obj-parens.rs @@ -0,0 +1,8 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(bare_trait_objects)] + +type A = Box<(Fn(u8) -> u8) + 'static + Send + Sync>; // OK (but see #39318) + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bounds-type-where.rs b/gcc/testsuite/rust/rustc/ui/parser/bounds-type-where.rs new file mode 100644 index 000000000000..a98edaa84843 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bounds-type-where.rs @@ -0,0 +1,12 @@ +type A where for<'a> for<'b> Trait1 + ?Trait2: 'a + Trait = u8; // OK +type A where T: Trait, = u8; // OK +type A where T: = u8; // OK +type A where T:, = u8; // OK +type A where T: Trait + Trait = u8; // OK +type A where = u8; // OK +type A where T: Trait + = u8; // OK +type A where T, = u8; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/bounds-type.rs b/gcc/testsuite/rust/rustc/ui/parser/bounds-type.rs new file mode 100644 index 000000000000..35a8a028c0fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/bounds-type.rs @@ -0,0 +1,19 @@ +// compile-flags: -Z parse-only + +struct S< + T: 'a + Tr, // OK + T: Tr + 'a, // OK + T: 'a, // OK + T:, // OK + T: ?for<'a> Trait, // OK + T: Tr +, // OK + T: ?'a, // { dg-error "" "" { target *-*-* } } + + T: ?const Tr, // OK + T: ?const ?Tr, // OK + T: ?const Tr + 'a, // OK + T: ?const 'a, // { dg-error "" "" { target *-*-* } } +>; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/brace-after-qualified-path-in-match.rs b/gcc/testsuite/rust/rustc/ui/parser/brace-after-qualified-path-in-match.rs new file mode 100644 index 000000000000..166e2e8ab491 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/brace-after-qualified-path-in-match.rs @@ -0,0 +1,8 @@ +fn main() { + match 10 { + ::Type{key: value} => (), +// { dg-error "" "" { target *-*-* } .-1 } + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/byte-literals.rs b/gcc/testsuite/rust/rustc/ui/parser/byte-literals.rs new file mode 100644 index 000000000000..85af62a35f84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/byte-literals.rs @@ -0,0 +1,13 @@ +// ignore-tidy-tab + +static FOO: u8 = b'\f'; // { dg-error "" "" { target *-*-* } } + +pub fn main() { + b'\f'; // { dg-error "" "" { target *-*-* } } + b'\x0Z'; // { dg-error "" "" { target *-*-* } } + b' '; // { dg-error "" "" { target *-*-* } } + b'''; // { dg-error "" "" { target *-*-* } } + b'é'; // { dg-error "" "" { target *-*-* } } + b'a // { dg-error ".E0763." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/byte-string-literals.rs b/gcc/testsuite/rust/rustc/ui/parser/byte-string-literals.rs new file mode 100644 index 000000000000..d6d87a2d5208 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/byte-string-literals.rs @@ -0,0 +1,9 @@ +static FOO: &'static [u8] = b"\f"; // { dg-error "" "" { target *-*-* } } + +pub fn main() { + b"\f"; // { dg-error "" "" { target *-*-* } } + b"\x0Z"; // { dg-error "" "" { target *-*-* } } + b"é"; // { dg-error "" "" { target *-*-* } } + b"a // { dg-error ".E0766." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/chained-comparison-suggestion.rs b/gcc/testsuite/rust/rustc/ui/parser/chained-comparison-suggestion.rs new file mode 100644 index 000000000000..25096b1744c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/chained-comparison-suggestion.rs @@ -0,0 +1,54 @@ +// Check that we get nice suggestions when attempting a chained comparison. + +fn comp1() { + 1 < 2 <= 3; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn comp2() { + 1 < 2 < 3; // { dg-error "" "" { target *-*-* } } +} + +fn comp3() { + 1 <= 2 < 3; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn comp4() { + 1 <= 2 <= 3; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn comp5() { + 1 > 2 >= 3; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn comp6() { + 1 > 2 > 3; // { dg-error "" "" { target *-*-* } } +} + +fn comp7() { + 1 >= 2 > 3; // { dg-error "" "" { target *-*-* } } +} + +fn comp8() { + 1 >= 2 >= 3; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn comp9() { + 1 == 2 < 3; // { dg-error "" "" { target *-*-* } } +} + +fn comp10() { + 1 > 2 == false; // { dg-error "" "" { target *-*-* } } +} + +fn comp11() { + 1 == 2 == 3; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/circular_modules_hello.rs b/gcc/testsuite/rust/rustc/ui/parser/circular_modules_hello.rs new file mode 100644 index 000000000000..e58d1c299350 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/circular_modules_hello.rs @@ -0,0 +1,9 @@ +// ignore-test: this is an auxiliary file for circular-modules-main.rs + +#[path = "circular_modules_main.rs"] +mod circular_modules_main; + +pub fn say_hello() { + println!("{}", circular_modules_main::hi_str()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/circular_modules_main.rs b/gcc/testsuite/rust/rustc/ui/parser/circular_modules_main.rs new file mode 100644 index 000000000000..863f32006a80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/circular_modules_main.rs @@ -0,0 +1,11 @@ +#[path = "circular_modules_hello.rs"] +mod circular_modules_hello; // { dg-error "" "" { target *-*-* } } + +pub fn hi_str() -> String { + "Hi!".to_string() +} + +fn main() { + circular_modules_hello::say_hello(); // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/class-implements-bad-trait.rs b/gcc/testsuite/rust/rustc/ui/parser/class-implements-bad-trait.rs new file mode 100644 index 000000000000..409fd6a43180 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/class-implements-bad-trait.rs @@ -0,0 +1,10 @@ +// error-pattern:nonexistent +class cat : nonexistent { + let meows: usize; + new(in_x : usize) { self.meows = in_x; } +} + +fn main() { + let nyan = cat(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/closure-return-syntax.rs b/gcc/testsuite/rust/rustc/ui/parser/closure-return-syntax.rs new file mode 100644 index 000000000000..f2d9fd391f80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/closure-return-syntax.rs @@ -0,0 +1,8 @@ +// Test that we cannot parse a closure with an explicit return type +// unless it uses braces. + +fn main() { + let x = || -> i32 22; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/column-offset-1-based.rs b/gcc/testsuite/rust/rustc/ui/parser/column-offset-1-based.rs new file mode 100644 index 000000000000..51de1818768a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/column-offset-1-based.rs @@ -0,0 +1,2 @@ +# // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/constraints-before-generic-args-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/constraints-before-generic-args-syntactic-pass.rs new file mode 100644 index 000000000000..ef01569e650b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/constraints-before-generic-args-syntactic-pass.rs @@ -0,0 +1,10 @@ +// check-pass + +#[cfg(FALSE)] +fn syntax() { + foo::(); + foo::(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/default-on-wrong-item-kind.rs b/gcc/testsuite/rust/rustc/ui/parser/default-on-wrong-item-kind.rs new file mode 100644 index 000000000000..159208d7e66c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/default-on-wrong-item-kind.rs @@ -0,0 +1,141 @@ +// Test parsing for `default` where it doesn't belong. +// Specifically, we are interested in kinds of items or items in certain contexts. +// Also test item kinds in `extern` blocks and associated contexts which are not allowed there. + +fn main() {} + +#[cfg(FALSE)] +mod free_items { + default extern crate foo; // { dg-error "" "" { target *-*-* } } + default use foo; // { dg-error "" "" { target *-*-* } } + default static foo: u8; // { dg-error "" "" { target *-*-* } } + default const foo: u8; + default fn foo(); + default mod foo {} // { dg-error "" "" { target *-*-* } } + default extern "C" {} // { dg-error "" "" { target *-*-* } } + default type foo = u8; + default enum foo {} // { dg-error "" "" { target *-*-* } } + default struct foo {} // { dg-error "" "" { target *-*-* } } + default union foo {} // { dg-error "" "" { target *-*-* } } + default trait foo {} // { dg-error "" "" { target *-*-* } } + default trait foo = Ord; // { dg-error "" "" { target *-*-* } } + default impl foo {} + default!(); + default::foo::bar!(); + default default!(); // { dg-error "" "" { target *-*-* } } + default default::foo::bar!(); // { dg-error "" "" { target *-*-* } } + default macro foo {} // { dg-error "" "" { target *-*-* } } + default macro_rules! foo {} // { dg-error "" "" { target *-*-* } } +} + +#[cfg(FALSE)] +extern "C" { + default extern crate foo; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default use foo; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default static foo: u8; // { dg-error "" "" { target *-*-* } } + default const foo: u8; +// { dg-error "" "" { target *-*-* } .-1 } + default fn foo(); + default mod foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default extern "C" {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default type foo = u8; + default enum foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default struct foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default union foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default trait foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default trait foo = Ord; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default impl foo {} +// { dg-error "" "" { target *-*-* } .-1 } + default!(); + default::foo::bar!(); + default default!(); // { dg-error "" "" { target *-*-* } } + default default::foo::bar!(); // { dg-error "" "" { target *-*-* } } + default macro foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default macro_rules! foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(FALSE)] +impl S { + default extern crate foo; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default use foo; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default static foo: u8; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default const foo: u8; + default fn foo(); + default mod foo {}// { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default extern "C" {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default type foo = u8; + default enum foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default struct foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default union foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default trait foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default trait foo = Ord; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default impl foo {} +// { dg-error "" "" { target *-*-* } .-1 } + default!(); + default::foo::bar!(); + default default!(); // { dg-error "" "" { target *-*-* } } + default default::foo::bar!(); // { dg-error "" "" { target *-*-* } } + default macro foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default macro_rules! foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(FALSE)] +trait T { + default extern crate foo; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default use foo; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default static foo: u8; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default const foo: u8; + default fn foo(); + default mod foo {}// { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default extern "C" {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default type foo = u8; + default enum foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default struct foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default union foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default trait foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default trait foo = Ord; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default impl foo {} +// { dg-error "" "" { target *-*-* } .-1 } + default!(); + default::foo::bar!(); + default default!(); // { dg-error "" "" { target *-*-* } } + default default::foo::bar!(); // { dg-error "" "" { target *-*-* } } + default macro foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + default macro_rules! foo {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/default-unmatched-assoc.rs b/gcc/testsuite/rust/rustc/ui/parser/default-unmatched-assoc.rs new file mode 100644 index 000000000000..f68264067d4f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/default-unmatched-assoc.rs @@ -0,0 +1,17 @@ +fn main() {} + +trait Foo { + default!(); // { dg-error "" "" { target *-*-* } } + default do +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +struct S; +impl S { + default!(); // { dg-error "" "" { target *-*-* } } + default do +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/default-unmatched-extern.rs b/gcc/testsuite/rust/rustc/ui/parser/default-unmatched-extern.rs new file mode 100644 index 000000000000..44a09384a0b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/default-unmatched-extern.rs @@ -0,0 +1,9 @@ +fn main() {} + +extern "C" { + default!(); // { dg-error "" "" { target *-*-* } } + default do +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/default-unmatched.rs b/gcc/testsuite/rust/rustc/ui/parser/default-unmatched.rs new file mode 100644 index 000000000000..87a2ad136e0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/default-unmatched.rs @@ -0,0 +1,7 @@ +mod foo { + default!(); // OK. + default do +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/default.rs b/gcc/testsuite/rust/rustc/ui/parser/default.rs new file mode 100644 index 000000000000..1ff3f28629f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/default.rs @@ -0,0 +1,29 @@ +// Test successful and unsuccessful parsing of the `default` contextual keyword + +#![feature(specialization)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait Foo { + fn foo() -> T; +} + +impl Foo for u8 { + default fn foo() -> T { + T::default() + } +} + +impl Foo for u16 { + pub default fn foo() -> T { // { dg-error ".E0449." "" { target *-*-* } } + T::default() + } +} + +impl Foo for u32 { // { dg-error ".E0046." "" { target *-*-* } } + default pub fn foo() -> T { T::default() } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/do-catch-suggests-try.rs b/gcc/testsuite/rust/rustc/ui/parser/do-catch-suggests-try.rs new file mode 100644 index 000000000000..db12cbebe983 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/do-catch-suggests-try.rs @@ -0,0 +1,11 @@ +#![feature(try_blocks)] + +fn main() { + let _: Option<()> = do catch {}; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + + let _recovery_witness: () = 1; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-after-struct-field.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-after-struct-field.rs new file mode 100644 index 000000000000..a0a07cb541f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-after-struct-field.rs @@ -0,0 +1,17 @@ +struct X { + a: u8 /** document a */, +// { dg-error ".E0585." "" { target *-*-* } .-1 } +// { help ".E0585." "" { target *-*-* } .-2 } +} + +struct Y { + a: u8 /// document a +// { dg-error ".E0585." "" { target *-*-* } .-1 } +// { help ".E0585." "" { target *-*-* } .-2 } +} + +fn main() { + let x = X { a: 1 }; + let y = Y { a: 1 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-before-attr.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-before-attr.rs new file mode 100644 index 000000000000..d5c9de2f1faf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-before-attr.rs @@ -0,0 +1,5 @@ +fn main() {} + +/// hi +#[derive(Debug)] // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-before-eof.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-before-eof.rs new file mode 100644 index 000000000000..a9e7cf1feb01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-before-eof.rs @@ -0,0 +1,4 @@ +fn main() {} + +/// hi // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-before-extern-rbrace.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-before-extern-rbrace.rs new file mode 100644 index 000000000000..bb5e645ca0ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-before-extern-rbrace.rs @@ -0,0 +1,7 @@ +fn main() {} + +extern { + /// hi +// { dg-error ".E0584." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-before-fn-rbrace.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-before-fn-rbrace.rs new file mode 100644 index 000000000000..7b2d61f1afde --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-before-fn-rbrace.rs @@ -0,0 +1,6 @@ +fn main() { + /// document +// { dg-error ".E0585." "" { target *-*-* } .-1 } +// { help ".E0585." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-before-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-before-identifier.rs new file mode 100644 index 000000000000..e18374fd19a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-before-identifier.rs @@ -0,0 +1,8 @@ +fn /// document +foo() {} +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-before-mod-rbrace.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-before-mod-rbrace.rs new file mode 100644 index 000000000000..6ea01982c604 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-before-mod-rbrace.rs @@ -0,0 +1,7 @@ +mod Foo { + /// document +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-before-rbrace.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-before-rbrace.rs new file mode 100644 index 000000000000..faf3ccef89db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-before-rbrace.rs @@ -0,0 +1,6 @@ +fn main() { + println!("Hi"); /// hi +// { dg-error ".E0585." "" { target *-*-* } .-1 } +// { help ".E0585." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-before-semi.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-before-semi.rs new file mode 100644 index 000000000000..58a2e28823e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-before-semi.rs @@ -0,0 +1,7 @@ +fn main() { + /// hi +// { dg-error ".E0585." "" { target *-*-* } .-1 } +// { help ".E0585." "" { target *-*-* } .-2 } + ; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-before-struct-rbrace-1.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-before-struct-rbrace-1.rs new file mode 100644 index 000000000000..06dfb32639c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-before-struct-rbrace-1.rs @@ -0,0 +1,11 @@ +struct X { + a: u8, + /// document +// { dg-error ".E0585." "" { target *-*-* } .-1 } +// { help ".E0585." "" { target *-*-* } .-2 } +} + +fn main() { + let y = X {a: 1}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-before-struct-rbrace-2.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-before-struct-rbrace-2.rs new file mode 100644 index 000000000000..b3350476f85e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-before-struct-rbrace-2.rs @@ -0,0 +1,10 @@ +struct X { + a: u8 /// document +// { dg-error ".E0585." "" { target *-*-* } .-1 } +// { help ".E0585." "" { target *-*-* } .-2 } +} + +fn main() { + let y = X {a: 1}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-comment-in-if-statement.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-comment-in-if-statement.rs new file mode 100644 index 000000000000..2a7044e0169a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-comment-in-if-statement.rs @@ -0,0 +1,6 @@ +fn main() { + if true /*!*/ {} +// { dg-error ".E0753." "" { target *-*-* } .-1 } +// { dg-error ".E0753." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-comment-in-stmt.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-comment-in-stmt.rs new file mode 100644 index 000000000000..dd0d15e7c5bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-comment-in-stmt.rs @@ -0,0 +1,21 @@ +fn foo() -> bool { + false + //!self.allow_ty_infer() +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn bar() -> bool { + false + /*! bar */ // { dg-error "" "" { target *-*-* } } +} + +fn baz() -> i32 { + 1 /** baz */ // { dg-error "" "" { target *-*-* } } +} + +fn quux() -> i32 { + 2 /*! quux */ // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/doc-inside-trait-item.rs b/gcc/testsuite/rust/rustc/ui/parser/doc-inside-trait-item.rs new file mode 100644 index 000000000000..2162a1fbcc3b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/doc-inside-trait-item.rs @@ -0,0 +1,7 @@ +trait User{ + fn test(); + /// empty doc +// { dg-error ".E0584." "" { target *-*-* } .-1 } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/duplicate-visibility.rs b/gcc/testsuite/rust/rustc/ui/parser/duplicate-visibility.rs new file mode 100644 index 000000000000..a7c6da253045 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/duplicate-visibility.rs @@ -0,0 +1,8 @@ +fn main() {} + +extern { + pub pub fn foo(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/empty-impl-semicolon.rs b/gcc/testsuite/rust/rustc/ui/parser/empty-impl-semicolon.rs new file mode 100644 index 000000000000..2e1ddd0a99af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/empty-impl-semicolon.rs @@ -0,0 +1,2 @@ +impl Foo; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/expr-as-stmt-2.rs b/gcc/testsuite/rust/rustc/ui/parser/expr-as-stmt-2.rs new file mode 100644 index 000000000000..9fc0b2b0ea0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/expr-as-stmt-2.rs @@ -0,0 +1,11 @@ +// This is not autofixable because we give extra suggestions to end the first expression with `;`. +fn foo(a: Option, b: Option) -> bool { + if let Some(x) = a { true } else { false } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + && // { dg-error ".E0308." "" { target *-*-* } } + if let Some(y) = a { true } else { false } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/expr-as-stmt.rs b/gcc/testsuite/rust/rustc/ui/parser/expr-as-stmt.rs new file mode 100644 index 000000000000..41862b7ce159 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/expr-as-stmt.rs @@ -0,0 +1,35 @@ +// run-rustfix +#![allow(unused_variables)] +#![allow(dead_code)] +#![allow(unused_must_use)] + +fn foo() -> i32 { + {2} + {2} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn bar() -> i32 { + {2} + 2 // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn zul() -> u32 { + let foo = 3; + { 42 } + foo; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + 32 +} + +fn baz() -> i32 { + { 3 } * 3 // { dg-error ".E0614." "" { target *-*-* } } +// { dg-error ".E0614." "" { target *-*-* } .-1 } +} + +fn moo(x: u32) -> bool { + match x { + _ => 1, + } > 0 // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/extern-abi-from-mac-literal-frag.rs b/gcc/testsuite/rust/rustc/ui/parser/extern-abi-from-mac-literal-frag.rs new file mode 100644 index 000000000000..b9d755ff61fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/extern-abi-from-mac-literal-frag.rs @@ -0,0 +1,48 @@ +#![allow(clashing_extern_declarations)] +// check-pass + +// In this test we check that the parser accepts an ABI string when it +// comes from a macro `literal` or `expr` fragment as opposed to a hardcoded string. + +fn main() {} + +macro_rules! abi_from_lit_frag { + ($abi:literal) => { + extern $abi { + fn _import(); + } + + extern $abi fn _export() {} + + type _PTR = extern $abi fn(); + } +} + +macro_rules! abi_from_expr_frag { + ($abi:expr) => { + extern $abi { + fn _import(); + } + + extern $abi fn _export() {} + + type _PTR = extern $abi fn(); + }; +} + +mod rust { + abi_from_lit_frag!("Rust"); +} + +mod c { + abi_from_lit_frag!("C"); +} + +mod rust_expr { + abi_from_expr_frag!("Rust"); +} + +mod c_expr { + abi_from_expr_frag!("C"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/extern-abi-raw-strings.rs b/gcc/testsuite/rust/rustc/ui/parser/extern-abi-raw-strings.rs new file mode 100644 index 000000000000..4e44502359d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/extern-abi-raw-strings.rs @@ -0,0 +1,14 @@ +// check-pass + +// Check that the string literal in `extern lit` will accept raw strings. + +fn main() {} + +extern r#"C"# fn foo() {} + +extern r#"C"# { + fn bar(); +} + +type T = extern r#"C"# fn(); + diff --git a/gcc/testsuite/rust/rustc/ui/parser/extern-abi-string-escaping.rs b/gcc/testsuite/rust/rustc/ui/parser/extern-abi-string-escaping.rs new file mode 100644 index 000000000000..91768712d177 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/extern-abi-string-escaping.rs @@ -0,0 +1,14 @@ +// check-pass + +// Check that the string literal in `extern lit` will escapes. + +fn main() {} + +extern "\x43" fn foo() {} + +extern "\x43" { + fn bar(); +} + +type T = extern "\x43" fn(); + diff --git a/gcc/testsuite/rust/rustc/ui/parser/extern-abi-syntactic.rs b/gcc/testsuite/rust/rustc/ui/parser/extern-abi-syntactic.rs new file mode 100644 index 000000000000..386fab9e4f81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/extern-abi-syntactic.rs @@ -0,0 +1,18 @@ +// check-pass + +// Check that from the grammar's point of view, +// the specific set of ABIs is not part of it. + +fn main() {} + +#[cfg(FALSE)] +extern "some_abi_that_we_are_sure_does_not_exist_semantically" fn foo() {} + +#[cfg(FALSE)] +extern "some_abi_that_we_are_sure_does_not_exist_semantically" { + fn foo(); +} + +#[cfg(FALSE)] +type T = extern "some_abi_that_we_are_sure_does_not_exist_semantically" fn(); + diff --git a/gcc/testsuite/rust/rustc/ui/parser/extern-crate-async.rs b/gcc/testsuite/rust/rustc/ui/parser/extern-crate-async.rs new file mode 100644 index 000000000000..216beefe5e28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/extern-crate-async.rs @@ -0,0 +1,13 @@ +// Make sure that we don't parse `extern crate async` +// the front matter of a function leading us astray. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +extern crate async; + +#[cfg(FALSE)] +extern crate async as something_else; + diff --git a/gcc/testsuite/rust/rustc/ui/parser/extern-crate-unexpected-token.rs b/gcc/testsuite/rust/rustc/ui/parser/extern-crate-unexpected-token.rs new file mode 100644 index 000000000000..a77725905d33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/extern-crate-unexpected-token.rs @@ -0,0 +1,2 @@ +extern crte foo; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/extern-expected-fn-or-brace.rs b/gcc/testsuite/rust/rustc/ui/parser/extern-expected-fn-or-brace.rs new file mode 100644 index 000000000000..820a3fb7e4b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/extern-expected-fn-or-brace.rs @@ -0,0 +1,4 @@ +// Verifies that the expected token errors for `extern crate` are raised. + +extern "C" mod foo; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/extern-foreign-crate.rs b/gcc/testsuite/rust/rustc/ui/parser/extern-foreign-crate.rs new file mode 100644 index 000000000000..43ead289a870 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/extern-foreign-crate.rs @@ -0,0 +1,5 @@ +// Verifies that the expected token errors for `extern crate` are +// raised + +extern crate foo {} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/extern-no-fn.rs b/gcc/testsuite/rust/rustc/ui/parser/extern-no-fn.rs new file mode 100644 index 000000000000..f5f79c279f59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/extern-no-fn.rs @@ -0,0 +1,7 @@ +extern { + f(); // { dg-error "" "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/float-field-interpolated.rs b/gcc/testsuite/rust/rustc/ui/parser/float-field-interpolated.rs new file mode 100644 index 000000000000..1bdb6774d45d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/float-field-interpolated.rs @@ -0,0 +1,18 @@ +struct S(u8, (u8, u8)); + +macro_rules! generate_field_accesses { + ($a:tt, $b:literal, $c:expr) => { + let s = S(0, (0, 0)); + + s.$a; // OK + { s.$b; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + { s.$c; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + }; +} + +fn main() { + generate_field_accesses!(1.1, 1.1, 1.1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/float-field.rs b/gcc/testsuite/rust/rustc/ui/parser/float-field.rs new file mode 100644 index 000000000000..e0e45656d0c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/float-field.rs @@ -0,0 +1,63 @@ +struct S(u8, (u8, u8)); + +fn main() { + let s = S(0, (0, 0)); + + s.1e1; // { dg-error ".E0609." "" { target *-*-* } } + s.1.; // { dg-error "" "" { target *-*-* } } + s.1.1; + s.1.1e1; // { dg-error ".E0609." "" { target *-*-* } } + { s.1e+; } // { dg-error "" "" { target *-*-* } } +// { dg-error ".E0609." "" { target *-*-* } .-2 } +// { dg-error ".E0609." "" { target *-*-* } .-3 } + { s.1e-; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + { s.1e+1; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + { s.1e-1; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + { s.1.1e+1; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + { s.1.1e-1; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + s.0x1e1; // { dg-error ".E0609." "" { target *-*-* } } + s.0x1.; // { dg-error ".E0609." "" { target *-*-* } } +// { dg-error ".E0609." "" { target *-*-* } .-2 } +// { dg-error ".E0609." "" { target *-*-* } .-3 } + s.0x1.1; // { dg-error ".E0609." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + s.0x1.1e1; // { dg-error ".E0609." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + { s.0x1e+; } // { dg-error "" "" { target *-*-* } } + { s.0x1e-; } // { dg-error "" "" { target *-*-* } } + s.0x1e+1; // { dg-error ".E0609." "" { target *-*-* } } + s.0x1e-1; // { dg-error ".E0609." "" { target *-*-* } } + { s.0x1.1e+1; } // { dg-error "" "" { target *-*-* } } +// { dg-error ".E0609." "" { target *-*-* } .-2 } +// { dg-error ".E0609." "" { target *-*-* } .-3 } + { s.0x1.1e-1; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + s.1e1f32; // { dg-error ".E0609." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + s.1.f32; // { dg-error ".E0609." "" { target *-*-* } } + s.1.1f32; // { dg-error "" "" { target *-*-* } } + s.1.1e1f32; // { dg-error ".E0609." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + { s.1e+f32; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + { s.1e-f32; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + { s.1e+1f32; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + { s.1e-1f32; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + { s.1.1e+1f32; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + { s.1.1e-1f32; } // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/fn-arg-doc-comment.rs b/gcc/testsuite/rust/rustc/ui/parser/fn-arg-doc-comment.rs new file mode 100644 index 000000000000..bf7f84e622e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/fn-arg-doc-comment.rs @@ -0,0 +1,27 @@ +pub fn f( + /// Comment +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + id: u8, + /// Other +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + a: u8, +) {} + +fn bar(id: #[allow(dead_code)] i32) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + +fn main() { + // verify that the parser recovered and properly typechecked the args + f("", ""); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-note ".E0308." "" { target *-*-* } .-4 } + bar(""); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/fn-body-eq-expr-semi.rs b/gcc/testsuite/rust/rustc/ui/parser/fn-body-eq-expr-semi.rs new file mode 100644 index 000000000000..42ba05ecc7e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/fn-body-eq-expr-semi.rs @@ -0,0 +1,24 @@ +fn main() {} + +fn syntax() { + fn foo() = 42; // { dg-error "" "" { target *-*-* } } + fn bar() -> u8 = 42; // { dg-error "" "" { target *-*-* } } +} + +extern { + fn foo() = 42; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + fn bar() -> u8 = 42; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +trait Foo { + fn foo() = 42; // { dg-error "" "" { target *-*-* } } + fn bar() -> u8 = 42; // { dg-error "" "" { target *-*-* } } +} + +impl Foo for () { + fn foo() = 42; // { dg-error "" "" { target *-*-* } } + fn bar() -> u8 = 42; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/fn-body-optional-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/fn-body-optional-semantic-fail.rs new file mode 100644 index 000000000000..ecbaa36d6868 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/fn-body-optional-semantic-fail.rs @@ -0,0 +1,28 @@ +// Tests the different rules for `fn` forms requiring the presence or lack of a body. + +fn main() { + fn f1(); // { dg-error "" "" { target *-*-* } } + fn f2() {} // OK. + + trait X { + fn f1(); // OK. + fn f2() {} // OK. + } + + struct Y; + impl X for Y { + fn f1(); // { dg-error "" "" { target *-*-* } } + fn f2() {} // OK. + } + + impl Y { + fn f3(); // { dg-error "" "" { target *-*-* } } + fn f4() {} // OK. + } + + extern { + fn f5(); // OK. + fn f6() {} // { dg-error "" "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/fn-body-optional-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/fn-body-optional-syntactic-pass.rs new file mode 100644 index 000000000000..167e734e5620 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/fn-body-optional-syntactic-pass.rs @@ -0,0 +1,32 @@ +// Ensures that all `fn` forms having or lacking a body are syntactically valid. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + fn f(); + fn f() {} + + trait X { + fn f(); + fn f() {} + } + + impl X for Y { + fn f(); + fn f() {} + } + + impl Y { + fn f(); + fn f() {} + } + + extern { + fn f(); + fn f() {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/fn-colon-return-type.rs b/gcc/testsuite/rust/rustc/ui/parser/fn-colon-return-type.rs new file mode 100644 index 000000000000..33c7b2e60f6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/fn-colon-return-type.rs @@ -0,0 +1,6 @@ +fn foo(x: i32): i32 { // { dg-error "" "" { target *-*-* } } + x +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/fn-header-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/fn-header-semantic-fail.rs new file mode 100644 index 000000000000..291dde19e617 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/fn-header-semantic-fail.rs @@ -0,0 +1,59 @@ +// Ensures that all `fn` forms can have all the function qualifiers syntactically. + +// edition:2018 + +#![feature(const_extern_fn)] +#![feature(const_fn)] + +fn main() { + async fn ff1() {} // OK. + unsafe fn ff2() {} // OK. + const fn ff3() {} // OK. + extern "C" fn ff4() {} // OK. + const async unsafe extern "C" fn ff5() {} // OK. +// { dg-error "" "" { target *-*-* } .-1 } + + trait X { + async fn ft1(); // { dg-error ".E0706." "" { target *-*-* } } + unsafe fn ft2(); // OK. + const fn ft3(); // { dg-error ".E0379." "" { target *-*-* } } + extern "C" fn ft4(); // OK. + const async unsafe extern "C" fn ft5(); +// { dg-error ".E0706." "" { target *-*-* } .-1 } +// { dg-error ".E0379." "" { target *-*-* } .-2 } +// { dg-error ".E0706." "" { target *-*-* } .-3 } + } + + struct Y; + impl X for Y { + async fn ft1() {} // { dg-error ".E0053." "" { target *-*-* } } +// { dg-error ".E0053." "" { target *-*-* } .-1 } + unsafe fn ft2() {} // OK. + const fn ft3() {} // { dg-error ".E0379." "" { target *-*-* } } + extern "C" fn ft4() {} + const async unsafe extern "C" fn ft5() {} +// { dg-error ".E0053." "" { target *-*-* } .-1 } +// { dg-error ".E0053." "" { target *-*-* } .-2 } +// { dg-error ".E0053." "" { target *-*-* } .-3 } +// { dg-error ".E0053." "" { target *-*-* } .-4 } + } + + impl Y { + async fn fi1() {} // OK. + unsafe fn fi2() {} // OK. + const fn fi3() {} // OK. + extern "C" fn fi4() {} // OK. + const async unsafe extern "C" fn fi5() {} +// { dg-error "" "" { target *-*-* } .-1 } + } + + extern { + async fn fe1(); // { dg-error "" "" { target *-*-* } } + unsafe fn fe2(); // { dg-error "" "" { target *-*-* } } + const fn fe3(); // { dg-error "" "" { target *-*-* } } + extern "C" fn fe4(); // { dg-error "" "" { target *-*-* } } + const async unsafe extern "C" fn fe5(); // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/fn-header-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/fn-header-syntactic-pass.rs new file mode 100644 index 000000000000..dcb06d094d61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/fn-header-syntactic-pass.rs @@ -0,0 +1,48 @@ +// Ensures that all `fn` forms can have all the function qualifiers syntactically. + +// check-pass +// edition:2018 + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + const async unsafe extern "C" fn f(); + + trait X { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + const async unsafe extern "C" fn f(); + } + + impl X for Y { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + const async unsafe extern "C" fn f(); + } + + impl Y { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + const async unsafe extern "C" fn f(); + } + + extern { + async fn f(); + unsafe fn f(); + const fn f(); + extern "C" fn f(); + const async unsafe extern "C" fn f(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/fn-returns-fn-pointer.rs b/gcc/testsuite/rust/rustc/ui/parser/fn-returns-fn-pointer.rs new file mode 100644 index 000000000000..f9019891fc7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/fn-returns-fn-pointer.rs @@ -0,0 +1,7 @@ +// check-pass +// Regression test for #78507. +fn foo() -> Option Option> { + Some(|| Some(true)) +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/foreign-const-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/foreign-const-semantic-fail.rs new file mode 100644 index 000000000000..2ebc7b397952 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/foreign-const-semantic-fail.rs @@ -0,0 +1,10 @@ +fn main() {} + +extern { + const A: isize; +// { dg-error "" "" { target *-*-* } .-1 } + const B: isize = 42; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/foreign-const-syntactic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/foreign-const-syntactic-fail.rs new file mode 100644 index 000000000000..6e4383ffd376 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/foreign-const-syntactic-fail.rs @@ -0,0 +1,10 @@ +// Syntactically, a `const` item inside an `extern { ... }` block is not allowed. + +fn main() {} + +#[cfg(FALSE)] +extern { + const A: isize; // { dg-error "" "" { target *-*-* } } + const B: isize = 42; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/foreign-static-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/foreign-static-semantic-fail.rs new file mode 100644 index 000000000000..3e3d13463e19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/foreign-static-semantic-fail.rs @@ -0,0 +1,9 @@ +// Syntactically, a foreign static may not have a body. + +fn main() {} + +extern { + static X: u8 = 0; // { dg-error "" "" { target *-*-* } } + static mut Y: u8 = 0; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/foreign-static-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/foreign-static-syntactic-pass.rs new file mode 100644 index 000000000000..2da6b385d66d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/foreign-static-syntactic-pass.rs @@ -0,0 +1,12 @@ +// Syntactically, a foreign static may have a body. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +extern { + static X: u8 = 0; + static mut Y: u8 = 0; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/foreign-ty-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/foreign-ty-semantic-fail.rs new file mode 100644 index 000000000000..717bc96875b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/foreign-ty-semantic-fail.rs @@ -0,0 +1,19 @@ +#![feature(extern_types)] + +fn main() {} + +extern "C" { + type A: Ord; +// { dg-error "" "" { target *-*-* } .-1 } + type B<'a> where 'a: 'static; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + type C where T: 'static; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + type D = u8; +// { dg-error "" "" { target *-*-* } .-1 } + + type E: where; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/foreign-ty-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/foreign-ty-syntactic-pass.rs new file mode 100644 index 000000000000..0f139adf2198 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/foreign-ty-syntactic-pass.rs @@ -0,0 +1,13 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +extern "C" { + type A: Ord; + type A<'a> where 'a: 'static; + type A where T: 'static; + type A = u8; + type A<'a: 'static, T: Ord + 'static>: Eq + PartialEq where T: 'static + Copy = Vec; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/if-in-in.rs b/gcc/testsuite/rust/rustc/ui/parser/if-in-in.rs new file mode 100644 index 000000000000..d70eaf273ce7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/if-in-in.rs @@ -0,0 +1,8 @@ +// run-rustfix + +fn main() { + for i in in 1..2 { // { dg-error "" "" { target *-*-* } } + println!("{}", i); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/impl-item-const-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/impl-item-const-pass.rs new file mode 100644 index 000000000000..600dbcadf414 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/impl-item-const-pass.rs @@ -0,0 +1,9 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +impl X { + const Y: u8; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/impl-item-const-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/impl-item-const-semantic-fail.rs new file mode 100644 index 000000000000..4dfa8440a8a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/impl-item-const-semantic-fail.rs @@ -0,0 +1,8 @@ +fn main() {} + +struct X; + +impl X { + const Y: u8; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/impl-item-fn-no-body-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/impl-item-fn-no-body-pass.rs new file mode 100644 index 000000000000..b8941ae42eee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/impl-item-fn-no-body-pass.rs @@ -0,0 +1,9 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +impl X { + fn f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/impl-item-fn-no-body-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/impl-item-fn-no-body-semantic-fail.rs new file mode 100644 index 000000000000..f9ad1a912426 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/impl-item-fn-no-body-semantic-fail.rs @@ -0,0 +1,8 @@ +fn main() {} + +struct X; + +impl X { + fn f(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/impl-item-type-no-body-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/impl-item-type-no-body-pass.rs new file mode 100644 index 000000000000..74d80d7b427a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/impl-item-type-no-body-pass.rs @@ -0,0 +1,12 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +impl X { + type Y; + type Z: Ord; + type W: Ord where Self: Eq; + type W where Self: Eq; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/impl-item-type-no-body-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/impl-item-type-no-body-semantic-fail.rs new file mode 100644 index 000000000000..7bc27eed3987 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/impl-item-type-no-body-semantic-fail.rs @@ -0,0 +1,24 @@ +#![feature(generic_associated_types)] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + +struct X; + +impl X { + type Y; +// { dg-error ".E0202." "" { target *-*-* } .-1 } +// { dg-error ".E0202." "" { target *-*-* } .-2 } + type Z: Ord; +// { dg-error ".E0202." "" { target *-*-* } .-1 } +// { dg-error ".E0202." "" { target *-*-* } .-2 } +// { dg-error ".E0202." "" { target *-*-* } .-3 } + type W: Ord where Self: Eq; +// { dg-error ".E0202." "" { target *-*-* } .-1 } +// { dg-error ".E0202." "" { target *-*-* } .-2 } +// { dg-error ".E0202." "" { target *-*-* } .-3 } + type W where Self: Eq; +// { dg-error ".E0202." "" { target *-*-* } .-1 } +// { dg-error ".E0202." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/impl-parsing.rs b/gcc/testsuite/rust/rustc/ui/parser/impl-parsing.rs new file mode 100644 index 000000000000..6fed03bd9a7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/impl-parsing.rs @@ -0,0 +1,11 @@ +impl ! {} // OK +impl ! where u8: Copy {} // OK + +impl Trait Type {} // { dg-error "" "" { target *-*-* } } +impl Trait .. {} // { dg-error "" "" { target *-*-* } } +impl ?Sized for Type {} // { dg-error "" "" { target *-*-* } } +impl ?Sized for .. {} // { dg-error "" "" { target *-*-* } } + +default unsafe FAIL // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/impl-qpath.rs b/gcc/testsuite/rust/rustc/ui/parser/impl-qpath.rs new file mode 100644 index 000000000000..161d8eac247a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/impl-qpath.rs @@ -0,0 +1,8 @@ +// build-pass (FIXME(62277): could be check-pass?) +// compile-flags: -Z parse-only + +impl <*const u8>::AssocTy {} // OK +impl ::AssocTy {} // OK +impl <'a + Trait>::AssocTy {} // OK +impl <::AssocTy>::AssocTy {} // OK + diff --git a/gcc/testsuite/rust/rustc/ui/parser/import-from-path.rs b/gcc/testsuite/rust/rustc/ui/parser/import-from-path.rs new file mode 100644 index 000000000000..7fd4041f6494 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/import-from-path.rs @@ -0,0 +1,3 @@ +// error-pattern:expected +use foo::{bar}::baz + diff --git a/gcc/testsuite/rust/rustc/ui/parser/import-from-rename.rs b/gcc/testsuite/rust/rustc/ui/parser/import-from-rename.rs new file mode 100644 index 000000000000..e01931b4bb71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/import-from-rename.rs @@ -0,0 +1,11 @@ +// error-pattern:expected + +use foo::{bar} as baz; + +mod foo { + pub fn bar() {} +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/import-glob-path.rs b/gcc/testsuite/rust/rustc/ui/parser/import-glob-path.rs new file mode 100644 index 000000000000..724ca83033b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/import-glob-path.rs @@ -0,0 +1,3 @@ +// error-pattern:expected +use foo::*::bar + diff --git a/gcc/testsuite/rust/rustc/ui/parser/import-glob-rename.rs b/gcc/testsuite/rust/rustc/ui/parser/import-glob-rename.rs new file mode 100644 index 000000000000..1c2d9c0fc818 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/import-glob-rename.rs @@ -0,0 +1,11 @@ +// error-pattern:expected + +use foo::* as baz; + +mod foo { + pub fn bar() {} +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/inner-attr-after-doc-comment.rs b/gcc/testsuite/rust/rustc/ui/parser/inner-attr-after-doc-comment.rs new file mode 100644 index 000000000000..d633228ef5d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/inner-attr-after-doc-comment.rs @@ -0,0 +1,9 @@ +#![feature(lang_items)] +/** + * My module + */ + +#![recursion_limit="100"] +// { dg-error "" "" { target *-*-* } .-1 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/inner-attr-in-trait-def.rs b/gcc/testsuite/rust/rustc/ui/parser/inner-attr-in-trait-def.rs new file mode 100644 index 000000000000..c65d478f1d9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/inner-attr-in-trait-def.rs @@ -0,0 +1,10 @@ +// check-pass + +#![deny(non_camel_case_types)] + +fn main() {} + +trait foo_bar { + #![allow(non_camel_case_types)] +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/inner-attr.rs b/gcc/testsuite/rust/rustc/ui/parser/inner-attr.rs new file mode 100644 index 000000000000..a4d3e4fb856c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/inner-attr.rs @@ -0,0 +1,5 @@ +#[feature(lang_items)] + +#![recursion_limit="100"] // { dg-error "" "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/int-literal-too-large-span.rs b/gcc/testsuite/rust/rustc/ui/parser/int-literal-too-large-span.rs new file mode 100644 index 000000000000..db6aabe0c651 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/int-literal-too-large-span.rs @@ -0,0 +1,8 @@ +// issue #17123 + +fn main() { + 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 +// { dg-error "" "" { target *-*-* } .-1 } + ; // the span shouldn't point to this. +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/intersection-patterns.rs b/gcc/testsuite/rust/rustc/ui/parser/intersection-patterns.rs new file mode 100644 index 000000000000..2b6106555656 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/intersection-patterns.rs @@ -0,0 +1,41 @@ +// This tests the parser recovery in `recover_intersection_pat` +// and serves as a regression test for the diagnostics issue #65400. +// +// The general idea is that for `$pat_lhs @ $pat_rhs` where +// `$pat_lhs` is not generated by `ref? mut? $ident` we want +// to suggest either switching the order or note that intersection +// patterns are not allowed. + +fn main() { + let s: Option = None; + + match s { + Some(x) @ y => {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { help "" "" { target *-*-* } .-4 } +// { suggestion "" "" { target *-*-* } .-5 } + _ => {} + } + + match s { + Some(x) @ Some(y) => {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-note "" "" { target *-*-* } .-4 } + _ => {} + } + + match 2 { + 1 ..= 5 @ e => {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { help "" "" { target *-*-* } .-4 } +// { suggestion "" "" { target *-*-* } .-5 } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/inverted-parameters.rs b/gcc/testsuite/rust/rustc/ui/parser/inverted-parameters.rs new file mode 100644 index 000000000000..6db95cbc9311 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/inverted-parameters.rs @@ -0,0 +1,33 @@ +struct S; + +impl S { + fn foo(&self, &str bar) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } +} + +fn baz(S quux, xyzzy: i32) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +fn one(i32 a b) {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn pattern((i32, i32) (a, b)) {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn fizz(i32) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +// { help "" "" { target *-*-* } .-4 } + +fn missing_colon(quux S) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-10392-2.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-10392-2.rs new file mode 100644 index 000000000000..ab4228f2b2bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-10392-2.rs @@ -0,0 +1,10 @@ +// run-rustfix + +pub struct A { pub foo: isize } + +fn a() -> A { panic!() } + +fn main() { + let A { .., } = a(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-10392.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-10392.rs new file mode 100644 index 000000000000..fe777d0ae619 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-10392.rs @@ -0,0 +1,8 @@ +struct A { foo: isize } + +fn a() -> A { panic!() } + +fn main() { + let A { , } = a(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-10636-1.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-10636-1.rs new file mode 100644 index 000000000000..8213299c3447 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-10636-1.rs @@ -0,0 +1,9 @@ +struct Obj { +// { dg-note "" "" { target *-*-* } .-1 } + member: usize +) +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-10636-2.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-10636-2.rs new file mode 100644 index 000000000000..de875c0da638 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-10636-2.rs @@ -0,0 +1,12 @@ +// FIXME(31528) we emit a bunch of silly errors here due to continuing past the +// first one. This would be easy-ish to address by better recovery in tokenisation. + +pub fn trace_option(option: Option) { + option.map(|some| 42; +// { dg-error "" "" { target *-*-* } .-1 } + +} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-14303-enum.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-enum.rs new file mode 100644 index 000000000000..40a0e9a10402 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-enum.rs @@ -0,0 +1,7 @@ +enum X<'a, T, 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + A(&'a &'b T) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-14303-fn-def.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-fn-def.rs new file mode 100644 index 000000000000..58f5033df9a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-fn-def.rs @@ -0,0 +1,5 @@ +fn foo<'a, T, 'b>(x: &'a T) {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-14303-fncall.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-fncall.rs new file mode 100644 index 000000000000..76e1a3bb9c50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-fncall.rs @@ -0,0 +1,18 @@ +// can't run rustfix because it doesn't handle multipart suggestions correctly +// compile-flags: -Zborrowck=mir +// we need the above to avoid ast borrowck failure in recovered code + +struct S<'a, T> { + a: &'a T, + b: &'a T, +} + +fn foo<'a, 'b>(start: &'a usize, end: &'a usize) { + let _x = (*start..*end) + .map(|x| S { a: start, b: end }) + .collect::>>(); +// { dg-error ".E0747." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-14303-impl.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-impl.rs new file mode 100644 index 000000000000..0217a1d89cab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-impl.rs @@ -0,0 +1,7 @@ +struct X(T); + +impl<'a, T, 'b> X {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-14303-path.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-path.rs new file mode 100644 index 000000000000..80ab24ff4f8b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-path.rs @@ -0,0 +1,14 @@ +mod foo { + pub struct X<'a, 'b, 'c, T> { + a: &'a str, + b: &'b str, + c: &'c str, + t: T, + } +} + +fn bar<'a, 'b, 'c, T>(x: foo::X<'a, T, 'b, 'c>) {} +// { dg-error ".E0747." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-14303-struct.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-struct.rs new file mode 100644 index 000000000000..0672ac06e29a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-struct.rs @@ -0,0 +1,7 @@ +struct X<'a, T, 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + x: &'a &'b T +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-14303-trait.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-trait.rs new file mode 100644 index 000000000000..e18c3d9baf06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-14303-trait.rs @@ -0,0 +1,5 @@ +trait Foo<'a, T, 'b> {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-15914.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-15914.rs new file mode 100644 index 000000000000..95dedcdb94b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-15914.rs @@ -0,0 +1,5 @@ +fn main() { + let ref + (); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-15980.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-15980.rs new file mode 100644 index 000000000000..6cef253ced81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-15980.rs @@ -0,0 +1,18 @@ +use std::io; + +fn main(){ + let x: io::Result<()> = Ok(()); + match x { + Err(ref e) if e.kind == io::EndOfFile { +// { dg-note "" "" { target *-*-* } .-1 } + return +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + } +// { dg-note "" "" { target *-*-* } .-1 } + _ => {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-1655.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-1655.rs new file mode 100644 index 000000000000..16d7a98fbf0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-1655.rs @@ -0,0 +1,11 @@ +mod blade_runner { + #vec[doc( // { dg-error "" "" { target *-*-* } } + brief = "Blade Runner is probably the best movie ever", + desc = "I like that in the world of Blade Runner it is always + raining, and that it's always night time. And Aliens + was also a really good movie. + + Alien 3 was crap though." + )] +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-17383.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-17383.rs new file mode 100644 index 000000000000..e00fa50a3ddb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-17383.rs @@ -0,0 +1,8 @@ +enum X { + A = 3, +// { dg-error ".E0658." "" { target *-*-* } .-1 } + B(usize) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-17718-const-mut.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-17718-const-mut.rs new file mode 100644 index 000000000000..bca4c8252fd7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-17718-const-mut.rs @@ -0,0 +1,8 @@ +const +mut // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } +FOO: usize = 3; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-17904-2.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-17904-2.rs new file mode 100644 index 000000000000..a303a9683bae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-17904-2.rs @@ -0,0 +1,4 @@ +struct Bar { x: T } where T: Copy // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-17904.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-17904.rs new file mode 100644 index 000000000000..fc7ae9d2126a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-17904.rs @@ -0,0 +1,7 @@ +struct Baz where U: Eq(U); //This is parsed as the new Fn* style parenthesis syntax. +struct Baz where U: Eq(U) -> R; // Notice this parses as well. +struct Baz(U) where U: Eq; // This rightfully signals no error as well. +struct Foo where T: Copy, (T); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-1802-1.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-1802-1.rs new file mode 100644 index 000000000000..f3fe30ebd5e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-1802-1.rs @@ -0,0 +1,8 @@ +fn log(a: i32, b: i32) {} + +fn main() { + let error = 42; + log(error, 0b); +// { dg-error ".E0768." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-1802-2.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-1802-2.rs new file mode 100644 index 000000000000..f3fe30ebd5e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-1802-2.rs @@ -0,0 +1,8 @@ +fn log(a: i32, b: i32) {} + +fn main() { + let error = 42; + log(error, 0b); +// { dg-error ".E0768." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-19096.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-19096.rs new file mode 100644 index 000000000000..688e8587d388 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-19096.rs @@ -0,0 +1,11 @@ +fn main() { // we don't complain about the return type being `{integer}` + let t = (42, 42); + t.0::; // { dg-error "" "" { target *-*-* } } +} + +fn foo() -> usize { // we don't complain about the return type being unit + let t = (42, 42); + t.0::; // { dg-error "" "" { target *-*-* } } + 42; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-19398.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-19398.rs new file mode 100644 index 000000000000..f2940b0d899a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-19398.rs @@ -0,0 +1,7 @@ +trait T { + extern "Rust" unsafe fn foo(); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-20711-2.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-20711-2.rs new file mode 100644 index 000000000000..490f9d88d5b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-20711-2.rs @@ -0,0 +1,11 @@ +struct Foo; + +impl Foo { + fn foo() {} + + #[stable(feature = "rust1", since = "1.0.0")] +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-20711.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-20711.rs new file mode 100644 index 000000000000..da7f85664329 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-20711.rs @@ -0,0 +1,9 @@ +struct Foo; + +impl Foo { + #[stable(feature = "rust1", since = "1.0.0")] +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-21153.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-21153.rs new file mode 100644 index 000000000000..1587429576dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-21153.rs @@ -0,0 +1,7 @@ +trait MyTrait: Iterator { + Item = T; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-22647.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-22647.rs new file mode 100644 index 000000000000..bce2661ea4ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-22647.rs @@ -0,0 +1,16 @@ +fn main() { + let caller = |f: F| // { dg-error "" "" { target *-*-* } } + where F: Fn() -> i32 + { + let x = f(); + println!("Y {}",x); + return x; + }; + + caller(bar_handler); +} + +fn bar_handler() -> i32 { + 5 +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-22712.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-22712.rs new file mode 100644 index 000000000000..501a4d3b89b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-22712.rs @@ -0,0 +1,10 @@ +struct Foo { + buffer: B +} + +fn bar() { + let Foo> // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-2354-1.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-2354-1.rs new file mode 100644 index 000000000000..8401c9ae8c0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-2354-1.rs @@ -0,0 +1,2 @@ +static foo: isize = 2; } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-2354.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-2354.rs new file mode 100644 index 000000000000..5abf5528ce25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-2354.rs @@ -0,0 +1,16 @@ +fn foo() { // { dg-note "" "" { target *-*-* } } + match Some(10) { +// { dg-note "" "" { target *-*-* } .-1 } + Some(y) => { panic!(); } + None => { panic!(); } +} +// { dg-note "" "" { target *-*-* } .-1 } + +fn bar() { + let mut i = 0; + while (i < 1000) {} +} + +fn main() {} +// { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-23620-invalid-escapes.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-23620-invalid-escapes.rs new file mode 100644 index 000000000000..d4f0b368618f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-23620-invalid-escapes.rs @@ -0,0 +1,35 @@ +fn main() { + let _ = b"\u{a66e}"; +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = b'\u{a66e}'; +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = b'\u'; +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = b'\x5'; +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = b'\xxy'; +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = '\x5'; +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = '\xxy'; +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = b"\u{a4a4} \xf \u"; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + + let _ = "\xf \u"; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + let _ = "\u8f"; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-24197.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-24197.rs new file mode 100644 index 000000000000..eae1d2c979be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-24197.rs @@ -0,0 +1,4 @@ +fn main() { + let buf[0] = 0; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-24375.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-24375.rs new file mode 100644 index 000000000000..bb89df9b8bde --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-24375.rs @@ -0,0 +1,10 @@ +static tmp : [&'static str; 2] = ["hello", "he"]; + +fn main() { + let z = "hello"; + match z { + tmp[0] => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-24780.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-24780.rs new file mode 100644 index 000000000000..4a1c1233d428 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-24780.rs @@ -0,0 +1,10 @@ +// Verify that '>' is not both expected and found at the same time, as it used +// to happen in #24780. For example, following should be an error: +// expected one of ..., `>`, ... found `>`. + +fn foo() -> Vec> { // { dg-error "" "" { target *-*-* } } + Vec::new() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-27255.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-27255.rs new file mode 100644 index 000000000000..2afdb5f1e1b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-27255.rs @@ -0,0 +1,11 @@ +trait A {} + +impl A .. {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +impl A usize {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-30318.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-30318.rs new file mode 100644 index 000000000000..85857fec1125 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-30318.rs @@ -0,0 +1,8 @@ +fn foo() { } + +//! Misplaced comment... +// { dg-error ".E0753." "" { target *-*-* } .-1 } +// { dg-note ".E0753." "" { target *-*-* } .-2 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-3036.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-3036.rs new file mode 100644 index 000000000000..2f2e5d2b1dc4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-3036.rs @@ -0,0 +1,8 @@ +// run-rustfix + +// Testing that semicolon tokens are printed correctly in errors + +fn main() { + let _x = 3 // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-32214.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-32214.rs new file mode 100644 index 000000000000..ac439c80f8bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-32214.rs @@ -0,0 +1,7 @@ +trait Trait { type Item; } + +pub fn test >() {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-32446.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-32446.rs new file mode 100644 index 000000000000..a5e71ba77727 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-32446.rs @@ -0,0 +1,5 @@ +fn main() {} + +// This used to end up in an infite loop trying to bump past EOF. +trait T { ... } // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-32501.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-32501.rs new file mode 100644 index 000000000000..920cfb7ce3f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-32501.rs @@ -0,0 +1,10 @@ +fn main() { + let a = 0; + let _b = 0; + let _ = 0; + let mut b = 0; + let mut _b = 0; + let mut _ = 0; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-32505.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-32505.rs new file mode 100644 index 000000000000..df35e063317b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-32505.rs @@ -0,0 +1,6 @@ +pub fn test() { + foo(|_|) // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-33262.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-33262.rs new file mode 100644 index 000000000000..25ba5aa51088 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-33262.rs @@ -0,0 +1,7 @@ +// Issue #33262 + +pub fn main() { + for i in 0..a as { } +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-33413.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-33413.rs new file mode 100644 index 000000000000..4b8fa8caf9e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-33413.rs @@ -0,0 +1,10 @@ +struct S; + +impl S { + fn f(*, a: u8) -> u8 {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-33418.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-33418.rs new file mode 100644 index 000000000000..1ed6a13305ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-33418.rs @@ -0,0 +1,22 @@ +// run-rustfix + +trait Tr: !SuperA {} +// { dg-error "" "" { target *-*-* } .-1 } +trait Tr2: SuperA + !SuperB {} +// { dg-error "" "" { target *-*-* } .-1 } +trait Tr3: !SuperA + SuperB {} +// { dg-error "" "" { target *-*-* } .-1 } +trait Tr4: !SuperA + SuperB + + !SuperC + SuperD {} +// { dg-error "" "" { target *-*-* } .-1 } +trait Tr5: !SuperA + + !SuperB {} +// { dg-error "" "" { target *-*-* } .-1 } + +trait SuperA {} +trait SuperB {} +trait SuperC {} +trait SuperD {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-33455.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-33455.rs new file mode 100644 index 000000000000..d6ffcf9954b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-33455.rs @@ -0,0 +1,2 @@ +use foo.bar; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-35813-postfix-after-cast.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-35813-postfix-after-cast.rs new file mode 100644 index 000000000000..7bdeb113b3ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-35813-postfix-after-cast.rs @@ -0,0 +1,172 @@ +// edition:2018 +#![crate_type = "lib"] +#![feature(type_ascription)] +use std::future::Future; +use std::pin::Pin; + +// This tests the parser for "x as Y[z]". It errors, but we want to give useful +// errors and parse such that further code gives useful errors. +pub fn index_after_as_cast() { + vec![1, 2, 3] as Vec[0]; +// { dg-error "" "" { target *-*-* } .-1 } + vec![1, 2, 3]: Vec[0]; +// { dg-error "" "" { target *-*-* } .-1 } +} + +pub fn index_after_cast_to_index() { + (&[0]) as &[i32][0]; +// { dg-error "" "" { target *-*-* } .-1 } + (&[0i32]): &[i32; 1][0]; +// { dg-error "" "" { target *-*-* } .-1 } +} + +pub fn cast_after_cast() { + if 5u64 as i32 as u16 == 0u16 { + + } + if 5u64: u64: u64 == 0u64 { + + } + let _ = 5u64: u64: u64 as u8 as i8 == 9i8; + let _ = 0i32: i32: i32; + let _ = 0 as i32: i32; + let _ = 0i32: i32 as i32; + let _ = 0 as i32 as i32; + let _ = 0i32: i32: i32 as u32 as i32; +} + +pub fn cast_cast_method_call() { + let _ = 0i32: i32: i32.count_ones(); +// { dg-error "" "" { target *-*-* } .-1 } + let _ = 0 as i32: i32.count_ones(); +// { dg-error "" "" { target *-*-* } .-1 } + let _ = 0i32: i32 as i32.count_ones(); +// { dg-error "" "" { target *-*-* } .-1 } + let _ = 0 as i32 as i32.count_ones(); +// { dg-error "" "" { target *-*-* } .-1 } + let _ = 0i32: i32: i32 as u32 as i32.count_ones(); +// { dg-error "" "" { target *-*-* } .-1 } + let _ = 0i32: i32.count_ones(): u32; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = 0 as i32.count_ones(): u32; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = 0i32: i32.count_ones() as u32; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = 0 as i32.count_ones() as u32; +// { dg-error "" "" { target *-*-* } .-1 } + let _ = 0i32: i32: i32.count_ones() as u32 as i32; +// { dg-error "" "" { target *-*-* } .-1 } +} + +pub fn multiline_error() { + let _ = 0 + as i32 + .count_ones(); +// { dg-error "" "" { target *-*-* } .-3 } +} + +// this tests that the precedence for `!x as Y.Z` is still what we expect +pub fn precedence() { + let x: i32 = &vec![1, 2, 3] as &Vec[0]; +// { dg-error "" "" { target *-*-* } .-1 } +} + +pub fn method_calls() { + 0 as i32.max(0); +// { dg-error "" "" { target *-*-* } .-1 } + 0: i32.max(0); +// { dg-error "" "" { target *-*-* } .-1 } +} + +pub fn complex() { + let _ = format!( + "{} and {}", + if true { 33 } else { 44 } as i32.max(0), +// { dg-error "" "" { target *-*-* } .-1 } + if true { 33 } else { 44 }: i32.max(0) +// { dg-error "" "" { target *-*-* } .-1 } + ); +} + +pub fn in_condition() { + if 5u64 as i32.max(0) == 0 { +// { dg-error "" "" { target *-*-* } .-1 } + } + if 5u64: u64.max(0) == 0 { +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +pub fn inside_block() { + let _ = if true { + 5u64 as u32.max(0) == 0 +// { dg-error "" "" { target *-*-* } .-1 } + } else { false }; + let _ = if true { + 5u64: u64.max(0) == 0 +// { dg-error "" "" { target *-*-* } .-1 } + } else { false }; +} + +static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]); +// { dg-error "" "" { target *-*-* } .-1 } + +static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]); +// { dg-error "" "" { target *-*-* } .-1 } + + +pub fn cast_then_try() -> Result { + Err(0u64) as Result?; +// { dg-error "" "" { target *-*-* } .-1 } + Err(0u64): Result?; +// { dg-error "" "" { target *-*-* } .-1 } + Ok(1) +} + + +pub fn cast_then_call() { + type F = fn(u8); + // type ascription won't actually do [unique drop fn type] -> fn(u8) casts. + let drop_ptr = drop as fn(u8); + drop as F(); +// { dg-error ".E0214." "" { target *-*-* } .-1 } + drop_ptr: F(); +// { dg-error ".E0214." "" { target *-*-* } .-1 } +} + +pub fn cast_to_fn_should_work() { + let drop_ptr = drop as fn(u8); + drop as fn(u8); + drop_ptr: fn(u8); +} + +pub fn parens_after_cast_error() { + let drop_ptr = drop as fn(u8); + drop as fn(u8)(0); +// { dg-error "" "" { target *-*-* } .-1 } + drop_ptr: fn(u8)(0); +// { dg-error "" "" { target *-*-* } .-1 } +} + +pub async fn cast_then_await() { + Box::pin(noop()) as Pin>>.await; +// { dg-error "" "" { target *-*-* } .-1 } + + Box::pin(noop()): Pin>.await; +// { dg-error "" "" { target *-*-* } .-1 } +} + +pub async fn noop() {} + +#[derive(Default)] +pub struct Foo { + pub bar: u32, +} + +pub fn struct_field() { + Foo::default() as Foo.bar; +// { dg-error "" "" { target *-*-* } .-1 } + Foo::default(): Foo.bar; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-41155.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-41155.rs new file mode 100644 index 000000000000..0bff1a1b48c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-41155.rs @@ -0,0 +1,8 @@ +struct S; + +impl S { + pub // { dg-error "" "" { target *-*-* } } +} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-43692.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-43692.rs new file mode 100644 index 000000000000..f8cdd8a212fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-43692.rs @@ -0,0 +1,4 @@ +fn main() { + '\u{_10FFFF}'; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs new file mode 100644 index 000000000000..fd740601c844 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-48137-macros-cannot-interpolate-impl-items-bad-variants.rs @@ -0,0 +1,45 @@ +fn main() {} + +macro_rules! expand_to_enum { + () => { + enum BadE {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + }; +} + +macro_rules! mac_impl { + ($($i:item)*) => { + struct S; + impl S { $($i)* } + } +} + +mac_impl! { + struct BadS; // { dg-error "" "" { target *-*-* } } + expand_to_enum!(); +} + +macro_rules! mac_trait { + ($($i:item)*) => { + trait T { $($i)* } + } +} + +mac_trait! { + struct BadS; // { dg-error "" "" { target *-*-* } } + expand_to_enum!(); +} + +macro_rules! mac_extern { + ($($i:item)*) => { + extern "C" { $($i)* } + } +} + +mac_extern! { + struct BadS; // { dg-error "" "" { target *-*-* } } + expand_to_enum!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-48137-macros-cannot-interpolate-impl-items.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-48137-macros-cannot-interpolate-impl-items.rs new file mode 100644 index 000000000000..4f1473673f28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-48137-macros-cannot-interpolate-impl-items.rs @@ -0,0 +1,35 @@ +// check-pass + +fn main() {} + +macro_rules! mac_impl { + ($i:item) => { + struct S; + impl S { $i } + } +} + +mac_impl! { + fn foo() {} +} + +macro_rules! mac_trait { + ($i:item) => { + trait T { $i } + } +} + +mac_trait! { + fn foo() {} +} + +macro_rules! mac_extern { + ($i:item) => { + extern "C" { $i } + } +} + +mac_extern! { + fn foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-5544-a.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-5544-a.rs new file mode 100644 index 000000000000..c10a1c44ecc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-5544-a.rs @@ -0,0 +1,5 @@ +fn main() { + let __isize = 340282366920938463463374607431768211456; // 2^128 +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-5544-b.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-5544-b.rs new file mode 100644 index 000000000000..ac1a9ed2e28e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-5544-b.rs @@ -0,0 +1,5 @@ +fn main() { + let __isize = 0xffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff_ff; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-5806.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-5806.rs new file mode 100644 index 000000000000..39c9fa6e59e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-5806.rs @@ -0,0 +1,8 @@ +// normalize-stderr-test: "parser:.*\(" -> "parser: $$ACCESS_DENIED_MSG (" +// normalize-stderr-test: "os error \d+" -> "os error $$ACCESS_DENIED_CODE" + +#[path = "../parser"] +mod foo; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-58094-missing-right-square-bracket.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-58094-missing-right-square-bracket.rs new file mode 100644 index 000000000000..5602a5b1369b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-58094-missing-right-square-bracket.rs @@ -0,0 +1,5 @@ +// Fixed in #66054. +// ignore-tidy-trailing-newlines +// error-pattern: aborting due to 2 previous errors +#[Ѕ + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-59418.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-59418.rs new file mode 100644 index 000000000000..dbfcb6e2ea6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-59418.rs @@ -0,0 +1,19 @@ +struct X(i32,i32,i32); + +fn main() { + let a = X(1, 2, 3); + let b = a.1suffix; +// { dg-error "" "" { target *-*-* } .-1 } + println!("{}", b); + let c = (1, 2, 3); + let d = c.1suffix; +// { dg-error "" "" { target *-*-* } .-1 } + println!("{}", d); + let s = X { 0suffix: 0, 1: 1, 2: 2 }; +// { dg-error "" "" { target *-*-* } .-1 } + match s { + X { 0suffix: _, .. } => {} +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-62524.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-62524.rs new file mode 100644 index 000000000000..c46b09f40c8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-62524.rs @@ -0,0 +1,7 @@ +// ignore-tidy-trailing-newlines +// error-pattern: aborting due to 3 previous errors +#![allow(uncommon_codepoints)] + +y![ +Ϥ, + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-62546.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-62546.rs new file mode 100644 index 000000000000..5f23dd41e947 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-62546.rs @@ -0,0 +1,4 @@ +pub t(# +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-62660.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-62660.rs new file mode 100644 index 000000000000..90034eeda6e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-62660.rs @@ -0,0 +1,12 @@ +// Regression test for issue #62660: if a receiver's type does not +// successfully parse, emit the correct error instead of ICE-ing the compiler. + +struct Foo; + +impl Foo { + pub fn foo(_: i32, self: Box isize { fn f() -> isize {} pub f< +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-62894.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-62894.rs new file mode 100644 index 000000000000..98618d980b3b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-62894.rs @@ -0,0 +1,8 @@ +// Regression test for #62894, shouldn't crash. +// error-pattern: this file contains an unclosed delimiter +// error-pattern: expected one of `(`, `[`, or `{`, found keyword `fn` + +fn f() { assert_eq!(f(), (), assert_eq!(assert_eq! + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-62895.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-62895.rs new file mode 100644 index 000000000000..a743e627739d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-62895.rs @@ -0,0 +1,12 @@ +fn main() {} + +fn v() -> isize { // { dg-error ".E0308." "" { target *-*-* } } +mod _ { // { dg-error "" "" { target *-*-* } } +pub fn g() -> isizee { // { dg-error ".E0412." "" { target *-*-* } } +mod _ { // { dg-error "" "" { target *-*-* } } +pub g() -> is // { dg-error "" "" { target *-*-* } } +(), w20); +} +(), w20); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-62913.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-62913.rs new file mode 100644 index 000000000000..f52c0de22904 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-62913.rs @@ -0,0 +1,5 @@ +"\u\\" +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-62973.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-62973.rs new file mode 100644 index 000000000000..3bb3531dbecb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-62973.rs @@ -0,0 +1,9 @@ +// ignore-tidy-trailing-newlines +// error-pattern: aborting due to 7 previous errors + +fn main() {} + +fn p() { match s { v, E { [) {) } + + + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-63115-range-pat-interpolated.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-63115-range-pat-interpolated.rs new file mode 100644 index 000000000000..9f1a9422567b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-63115-range-pat-interpolated.rs @@ -0,0 +1,23 @@ +// check-pass + +#![feature(exclusive_range_pattern)] +#![feature(half_open_range_patterns)] + +#![allow(ellipsis_inclusive_range_patterns)] + +fn main() { + macro_rules! mac_expr { + ($e:expr) => { + if let 2...$e = 3 {} + if let 2..=$e = 3 {} + if let 2..$e = 3 {} + if let ..$e = 3 {} + if let ..=$e = 3 {} + if let $e.. = 5 {} + if let $e..5 = 4 {} + if let $e..=5 = 4 {} + } + } + mac_expr!(4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-63116.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-63116.rs new file mode 100644 index 000000000000..1822ea74210a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-63116.rs @@ -0,0 +1,4 @@ +// fixed by #66361 +// error-pattern: aborting due to 3 previous errors +impl W { + enum Enum { + $vis Unit, + + $vis Tuple(u8, u16), + + $vis Struct { f: u8 }, + } + } +} + +mac_variant!(MARKER); + +// We also accept visibilities on variants syntactically but not semantically. +#[cfg(FALSE)] +enum E { + pub U, + pub(crate) T(u8), + pub(super) T { f: String } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-65041-empty-vis-matcher-in-trait.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-65041-empty-vis-matcher-in-trait.rs new file mode 100644 index 000000000000..d8e0eaff51d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-65041-empty-vis-matcher-in-trait.rs @@ -0,0 +1,29 @@ +// check-pass + +// Here we check that a `:vis` macro matcher subsititued for the empty visibility +// (`VisibilityKind::Inherited`) is accepted when used before an item in a trait. + +fn main() {} + +macro_rules! mac_in_trait { + ($vis:vis MARKER) => { + $vis fn beta() {} + + $vis const GAMMA: u8; + + $vis type Delta; + } +} + +trait Alpha { + mac_in_trait!(MARKER); +} + +// We also accept visibilities on items in traits syntactically but not semantically. +#[cfg(FALSE)] +trait Foo { + pub fn bar(); + pub(crate) type baz; + pub(super) const QUUX: u8; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs new file mode 100644 index 000000000000..239ddd762e1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs @@ -0,0 +1,27 @@ +// Regression test; used to ICE with 'visit_mac_call disabled by default' due to a +// `MutVisitor` in `fn make_all_value_bindings_mutable` (`parse/parser/pat.rs`). + +macro_rules! mac1 { + ($eval:expr) => { + let mut $eval = (); +// { dg-error "" "" { target *-*-* } .-1 } + }; +} + +macro_rules! mac2 { + ($eval:pat) => { + let mut $eval = (); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + }; +} + +fn foo() { + mac1! { does_not_exist!() } +// { dg-error "" "" { target *-*-* } .-1 } + mac2! { does_not_exist!() } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-65257-invalid-var-decl-recovery.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-65257-invalid-var-decl-recovery.rs new file mode 100644 index 000000000000..6ab6b39a04bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-65257-invalid-var-decl-recovery.rs @@ -0,0 +1,22 @@ +fn main() { + auto n = 0;// { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + auto m;// { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + m = 0; + + var n = 0;// { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + var m;// { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + m = 0; + + mut n = 0;// { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + mut var;// { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + var = 0; + + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-65846-rollback-gating-failing-matcher.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-65846-rollback-gating-failing-matcher.rs new file mode 100644 index 000000000000..a13ae79ca543 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-65846-rollback-gating-failing-matcher.rs @@ -0,0 +1,15 @@ +// run-pass + +// Test that failing macro matchers will not cause pre-expansion errors +// even though they use a feature that is pre-expansion gated. + +macro_rules! m { + ($e:expr) => { 0 }; // This fails on the input below due to `, foo`. + ($e:expr,) => { 1 }; // This also fails to match due to `foo`. + (box $e:expr, foo) => { 2 }; // Successful matcher, we should get `2`. +} + +fn main() { + assert_eq!(2, m!(box 42, foo)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-6610.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-6610.rs new file mode 100644 index 000000000000..ad7a6d3e4ef6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-6610.rs @@ -0,0 +1,4 @@ +trait Foo { fn a() } // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-66357-unexpected-unreachable.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-66357-unexpected-unreachable.rs new file mode 100644 index 000000000000..253f6fe62ff3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-66357-unexpected-unreachable.rs @@ -0,0 +1,17 @@ +// ignore-tidy-linelength + +// The problem in #66357 was that the call trace: +// +// - parse_fn_block_decl +// - expect_or +// - unexpected +// - expect_one_of +// - expected_one_of_not_found +// - recover_closing_delimiter +// +// ended up bubbling up `Ok(true)` to `unexpected` which then used `unreachable!()`. + +fn f() { |[](* } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.rs new file mode 100644 index 000000000000..f42f90ced597 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.rs @@ -0,0 +1,15 @@ +// run-rustfix + +// In this regression test for #67146, we check that the +// negative outlives bound `!'a` is rejected by the parser. +// This regression was first introduced in PR #57364. + +fn main() {} + +pub fn f1() {} +// { dg-error "" "" { target *-*-* } .-1 } +pub fn f2<'a, T: Ord + !'a>() {} +// { dg-error "" "" { target *-*-* } .-1 } +pub fn f3<'a, T: !'a + Ord>() {} +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs new file mode 100644 index 000000000000..b8c64ed9b8ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs @@ -0,0 +1,36 @@ +mod a { + use std::marker::PhantomData; + + enum Bug { + V = [PhantomData; { [ () ].len() ].len() as isize, +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } + } +} + +mod b { + enum Bug { + V = [Vec::new; { [].len() ].len() as isize, +// { dg-error ".E0282." "" { target *-*-* } .-1 } +// { dg-error ".E0282." "" { target *-*-* } .-2 } +// { dg-error ".E0282." "" { target *-*-* } .-3 } +// { dg-error ".E0282." "" { target *-*-* } .-4 } +// { dg-error ".E0282." "" { target *-*-* } .-5 } + } +} + +mod c { + enum Bug { + V = [Vec::new; { [0].len() ].len() as isize, +// { dg-error ".E0282." "" { target *-*-* } .-1 } +// { dg-error ".E0282." "" { target *-*-* } .-2 } +// { dg-error ".E0282." "" { target *-*-* } .-3 } +// { dg-error ".E0282." "" { target *-*-* } .-4 } +// { dg-error ".E0282." "" { target *-*-* } .-5 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-68629.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-68629.rs new file mode 100644 index 0000000000000000000000000000000000000000..7f538b708929b17f20a829e25df4d6e6e8f70e9e GIT binary patch literal 338 zcmZvXJx;_x424tA8IX7!AWBccMQGMLaT042JMuVMRveA9a2G5JXwult``*tmKxQ@P zK4g6K;Uuf*+$-Pnb1TCDb~o>LieT4Q9C}l`D_W2TY(m(L^+XtpG)%HGs%emD18L%Q zwZx0K&EdX?3$-~w^3 e3~Nb^Ca!Rv(Nfh-3guT00kX{v=H@)kBZME`+dc*W literal 0 HcmV?d00001 diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-68788-in-trait-item-propagation.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-68788-in-trait-item-propagation.rs new file mode 100644 index 000000000000..908966b671ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-68788-in-trait-item-propagation.rs @@ -0,0 +1,22 @@ +// Make sure we don't propagate restrictions on trait impl items to items inside them. + +// check-pass +// edition:2018 + +fn main() {} + +trait X { + fn foo(); +} + +impl X for () { + fn foo() { + struct S; + impl S { + pub const X: u8 = 0; + pub const fn bar() {} + async fn qux() {} + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-68890-2.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-68890-2.rs new file mode 100644 index 000000000000..ee72fb7b50b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-68890-2.rs @@ -0,0 +1,7 @@ +fn main() {} + +type X<'a> = (?'a) +; +// { dg-error ".E0224." "" { target *-*-* } .-1 } +// { dg-error ".E0224." "" { target *-*-* } .-2 } +// { dg-warning ".E0224." "" { target *-*-* } .-3 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-68890.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-68890.rs new file mode 100644 index 000000000000..a9f1ae88ea18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-68890.rs @@ -0,0 +1,5 @@ +enum e{A((?'a a+?+l))} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-70050-ntliteral-accepts-negated-lit.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-70050-ntliteral-accepts-negated-lit.rs new file mode 100644 index 000000000000..fb1811eda7ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-70050-ntliteral-accepts-negated-lit.rs @@ -0,0 +1,17 @@ +// check-pass + +macro_rules! foo { + ($a:literal) => { + bar!($a) + }; +} + +macro_rules! bar { + ($b:literal) => {}; +} + +fn main() { + foo!(-2); + bar!(-2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-70388-recover-dotdotdot-rest-pat.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-70388-recover-dotdotdot-rest-pat.rs new file mode 100644 index 000000000000..4cd19fd42e5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-70388-recover-dotdotdot-rest-pat.rs @@ -0,0 +1,8 @@ +struct Foo(i32); + +fn main() { + let Foo(...) = Foo(0); // { dg-error "" "" { target *-*-* } } + let [_, ..., _] = [0, 1]; // { dg-error "" "" { target *-*-* } } + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-70388-without-witness.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-70388-without-witness.rs new file mode 100644 index 000000000000..eba1aec5f8cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-70388-without-witness.rs @@ -0,0 +1,10 @@ +// run-rustfix +// This is for checking if we can apply suggestions as-is. + +pub struct Foo(i32); + +fn main() { + let Foo(...) = Foo(0); // { dg-error "" "" { target *-*-* } } + let [_, ..., _] = [0, 1]; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-70549-resolve-after-recovered-self-ctor.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-70549-resolve-after-recovered-self-ctor.rs new file mode 100644 index 000000000000..840b1a6ed903 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-70549-resolve-after-recovered-self-ctor.rs @@ -0,0 +1,19 @@ +struct S {} + +impl S { + fn foo(&mur Self) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + fn bar(&'static mur Self) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } + + fn baz(&mur Self @ _) {} +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-70552-ascription-in-parens-after-call.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-70552-ascription-in-parens-after-call.rs new file mode 100644 index 000000000000..37884719304b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-70552-ascription-in-parens-after-call.rs @@ -0,0 +1,4 @@ +fn main() { + expr as fun()(:); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-70583-block-is-empty-1.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-70583-block-is-empty-1.rs new file mode 100644 index 000000000000..7de90f87630e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-70583-block-is-empty-1.rs @@ -0,0 +1,21 @@ +pub enum ErrorHandled { + Reported, + TooGeneric, +} + +impl ErrorHandled { + pub fn assert_reported(self) { + match self { + ErrorHandled::Reported => {} + ErrorHandled::TooGeneric => panic!(), + } + } +} + +fn struct_generic(x: Vec) { + for v in x { + println!("{}", v); + } + } +} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-70583-block-is-empty-2.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-70583-block-is-empty-2.rs new file mode 100644 index 000000000000..a7e7984941a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-70583-block-is-empty-2.rs @@ -0,0 +1,15 @@ +pub enum ErrorHandled { + Reported, + TooGeneric, +} + +impl ErrorHandled { + pub fn assert_reported(self) { + match self { + ErrorHandled::Reported => {}} + //^~ ERROR block is empty, you might have not meant to close it + ErrorHandled::TooGeneric => panic!(), + } + } +} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-73568-lifetime-after-mut.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-73568-lifetime-after-mut.rs new file mode 100644 index 000000000000..6d11b5e1b5da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-73568-lifetime-after-mut.rs @@ -0,0 +1,22 @@ +#![crate_type="lib"] +fn x<'a>(x: &mut 'a i32){} // { dg-error "" "" { target *-*-* } } + +macro_rules! mac { + ($lt:lifetime) => { + fn w<$lt>(w: &mut $lt i32) {} +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +mac!('a); + +// avoid false positives +fn y<'a>(y: &mut 'a + Send) { +// { dg-error ".E0224." "" { target *-*-* } .-1 } +// { dg-warning ".E0224." "" { target *-*-* } .-2 } +// { dg-error ".E0224." "" { target *-*-* } .-3 } + let z = y as &mut 'a + Send; +// { dg-error ".E0423." "" { target *-*-* } .-1 } +// { dg-warning ".E0423." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/issue-8537.rs b/gcc/testsuite/rust/rustc/ui/parser/issue-8537.rs new file mode 100644 index 000000000000..aa74d9232e7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/issue-8537.rs @@ -0,0 +1,6 @@ +pub extern + "invalid-ab_isize" // { dg-error ".E0703." "" { target *-*-* } } +fn foo() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/item-free-const-no-body-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/item-free-const-no-body-semantic-fail.rs new file mode 100644 index 000000000000..3f4ae3e460c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/item-free-const-no-body-semantic-fail.rs @@ -0,0 +1,8 @@ +// Semantically, a free `const` item cannot omit its body. + +fn main() {} + +const A: u8; // { dg-error "" "" { target *-*-* } } +const B; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/item-free-const-no-body-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/item-free-const-no-body-syntactic-pass.rs new file mode 100644 index 000000000000..ad87ef6882d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/item-free-const-no-body-syntactic-pass.rs @@ -0,0 +1,9 @@ +// Syntactically, a free `const` item can omit its body. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +const X: u8; + diff --git a/gcc/testsuite/rust/rustc/ui/parser/item-free-static-no-body-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/item-free-static-no-body-semantic-fail.rs new file mode 100644 index 000000000000..487e1d23d32d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/item-free-static-no-body-semantic-fail.rs @@ -0,0 +1,12 @@ +// Semantically, a free `static` item cannot omit its body. + +fn main() {} + +static A: u8; // { dg-error "" "" { target *-*-* } } +static B; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + +static mut C: u8; // { dg-error "" "" { target *-*-* } } +static mut D; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/item-free-static-no-body-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/item-free-static-no-body-syntactic-pass.rs new file mode 100644 index 000000000000..491e545290e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/item-free-static-no-body-syntactic-pass.rs @@ -0,0 +1,9 @@ +// Syntactically, a free `const` item can omit its body. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +static X: u8; + diff --git a/gcc/testsuite/rust/rustc/ui/parser/item-free-type-bounds-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/item-free-type-bounds-semantic-fail.rs new file mode 100644 index 000000000000..9768799e026e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/item-free-type-bounds-semantic-fail.rs @@ -0,0 +1,21 @@ +fn main() {} + +fn semantics() { + type A: Ord; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + type B: Ord = u8; +// { dg-error "" "" { target *-*-* } .-1 } + type C: Ord where 'static: 'static = u8; +// { dg-error "" "" { target *-*-* } .-1 } + type D<_T>: Ord; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + type E<_T>: Ord = u8; +// { dg-error ".E0091." "" { target *-*-* } .-1 } +// { dg-error ".E0091." "" { target *-*-* } .-2 } + type F<_T>: Ord where 'static: 'static = u8; +// { dg-error ".E0091." "" { target *-*-* } .-1 } +// { dg-error ".E0091." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/item-free-type-bounds-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/item-free-type-bounds-syntactic-pass.rs new file mode 100644 index 000000000000..be5d8dbe719b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/item-free-type-bounds-syntactic-pass.rs @@ -0,0 +1,14 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +fn syntax() { + type A: Ord; + type B: Ord = u8; + type C: Ord where 'static: 'static = u8; + type D<_T>: Ord; + type E<_T>: Ord = u8; + type F<_T>: Ord where 'static: 'static = u8; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-abstract.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-abstract.rs new file mode 100644 index 000000000000..e41cbe564143 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-abstract.rs @@ -0,0 +1,4 @@ +fn main() { + let abstract = (); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-as-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-as-as-identifier.rs new file mode 100644 index 000000000000..9c7f93d2190c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-as-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py as' + +fn main() { + let as = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-box-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-box-as-identifier.rs new file mode 100644 index 000000000000..4e7d23bfeba8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-box-as-identifier.rs @@ -0,0 +1,4 @@ +fn main() { + let box = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-break-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-break-as-identifier.rs new file mode 100644 index 000000000000..5f03c832acfc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-break-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py break' + +fn main() { + let break = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-const-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-const-as-identifier.rs new file mode 100644 index 000000000000..3fd68a085cd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-const-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py const' + +fn main() { + let const = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-continue-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-continue-as-identifier.rs new file mode 100644 index 000000000000..146bffb34e67 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-continue-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py continue' + +fn main() { + let continue = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-else-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-else-as-identifier.rs new file mode 100644 index 000000000000..29e0f2eb7300 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-else-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py else' + +fn main() { + let else = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-enum-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-enum-as-identifier.rs new file mode 100644 index 000000000000..0a2592d43f00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-enum-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py enum' + +fn main() { + let enum = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-final.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-final.rs new file mode 100644 index 000000000000..c734979ea85a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-final.rs @@ -0,0 +1,4 @@ +fn main() { + let final = (); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-fn-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-fn-as-identifier.rs new file mode 100644 index 000000000000..d88c9bf1f0be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-fn-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py fn' + +fn main() { + let fn = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-for-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-for-as-identifier.rs new file mode 100644 index 000000000000..ce82b38759a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-for-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py for' + +fn main() { + let for = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-if-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-if-as-identifier.rs new file mode 100644 index 000000000000..df42442652be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-if-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py if' + +fn main() { + let if = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-impl-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-impl-as-identifier.rs new file mode 100644 index 000000000000..1b9f6a790def --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-impl-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py impl' + +fn main() { + let impl = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-in-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-in-as-identifier.rs new file mode 100644 index 000000000000..f079b654f66b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-in-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py in' + +fn main() { + let in = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-let-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-let-as-identifier.rs new file mode 100644 index 000000000000..86dfea9bba82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-let-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py let' + +fn main() { + let let = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-loop-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-loop-as-identifier.rs new file mode 100644 index 000000000000..255d282b63fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-loop-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py loop' + +fn main() { + let loop = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-match-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-match-as-identifier.rs new file mode 100644 index 000000000000..23f5da904615 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-match-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py match' + +fn main() { + let match = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-mod-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-mod-as-identifier.rs new file mode 100644 index 000000000000..d8acd83ca22a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-mod-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py mod' + +fn main() { + let mod = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-move-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-move-as-identifier.rs new file mode 100644 index 000000000000..79874b82b47b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-move-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py move' + +fn main() { + let move = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-mut-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-mut-as-identifier.rs new file mode 100644 index 000000000000..d62ae3580fc0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-mut-as-identifier.rs @@ -0,0 +1,4 @@ +fn main() { + let mut = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-override.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-override.rs new file mode 100644 index 000000000000..b6d048fa94bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-override.rs @@ -0,0 +1,4 @@ +fn main() { + let override = (); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-pub-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-pub-as-identifier.rs new file mode 100644 index 000000000000..e36c2bf10001 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-pub-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py pub' + +fn main() { + let pub = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-ref-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-ref-as-identifier.rs new file mode 100644 index 000000000000..51598b5e2e55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-ref-as-identifier.rs @@ -0,0 +1,4 @@ +fn main() { + let ref = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-return-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-return-as-identifier.rs new file mode 100644 index 000000000000..9d491b82453b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-return-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py return' + +fn main() { + let return = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-static-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-static-as-identifier.rs new file mode 100644 index 000000000000..294989d0b79f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-static-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py static' + +fn main() { + let static = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-struct-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-struct-as-identifier.rs new file mode 100644 index 000000000000..7096c0f7e6c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-struct-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py struct' + +fn main() { + let struct = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-trait-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-trait-as-identifier.rs new file mode 100644 index 000000000000..172d4246d65b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-trait-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py trait' + +fn main() { + let trait = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-try-as-identifier-edition2018.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-try-as-identifier-edition2018.rs new file mode 100644 index 000000000000..64dc48ed0f51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-try-as-identifier-edition2018.rs @@ -0,0 +1,6 @@ +// compile-flags: --edition 2018 + +fn main() { + let try = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-type-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-type-as-identifier.rs new file mode 100644 index 000000000000..85250161fb19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-type-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py type' + +fn main() { + let type = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-typeof.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-typeof.rs new file mode 100644 index 000000000000..cde0577a897f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-typeof.rs @@ -0,0 +1,4 @@ +fn main() { + let typeof = (); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-unsafe-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-unsafe-as-identifier.rs new file mode 100644 index 000000000000..c6676cd80bce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-unsafe-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py unsafe' + +fn main() { + let unsafe = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-use-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-use-as-identifier.rs new file mode 100644 index 000000000000..f9204fb6b374 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-use-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py use' + +fn main() { + let use = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-where-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-where-as-identifier.rs new file mode 100644 index 000000000000..dd5e78a6f351 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-where-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py where' + +fn main() { + let where = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword-while-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword-while-as-identifier.rs new file mode 100644 index 000000000000..9ae23f39ec92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword-while-as-identifier.rs @@ -0,0 +1,6 @@ +// This file was auto-generated using 'src/etc/generate-keyword-tests.py while' + +fn main() { + let while = "foo"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keyword.rs b/gcc/testsuite/rust/rustc/ui/parser/keyword.rs new file mode 100644 index 000000000000..f66180937508 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keyword.rs @@ -0,0 +1,6 @@ +pub mod break { +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/keywords-followed-by-double-colon.rs b/gcc/testsuite/rust/rustc/ui/parser/keywords-followed-by-double-colon.rs new file mode 100644 index 000000000000..020182e2112f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/keywords-followed-by-double-colon.rs @@ -0,0 +1,9 @@ +fn main() { + struct::foo(); +// { dg-error "" "" { target *-*-* } .-1 } +} +fn bar() { + mut::baz(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/labeled-no-colon-expr.rs b/gcc/testsuite/rust/rustc/ui/parser/labeled-no-colon-expr.rs new file mode 100644 index 000000000000..b63fa490c8d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/labeled-no-colon-expr.rs @@ -0,0 +1,18 @@ +#![feature(label_break_value)] + +fn main() { + 'l0 while false {} // { dg-error "" "" { target *-*-* } } + 'l1 for _ in 0..1 {} // { dg-error "" "" { target *-*-* } } + 'l2 loop {} // { dg-error "" "" { target *-*-* } } + 'l3 {} // { dg-error "" "" { target *-*-* } } + 'l4 0; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + + macro_rules! m { + ($b:block) => { + 'l5 $b; // { dg-error "" "" { target *-*-* } } + } + } + m!({}); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/let-binop.rs b/gcc/testsuite/rust/rustc/ui/parser/let-binop.rs new file mode 100644 index 000000000000..bdf57f5c44ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/let-binop.rs @@ -0,0 +1,11 @@ +// run-rustfix + +fn main() { + let a: i8 *= 1; // { dg-error "" "" { target *-*-* } } + let _ = a; + let b += 1; // { dg-error "" "" { target *-*-* } } + let _ = b; + let c *= 1; // { dg-error "" "" { target *-*-* } } + let _ = c; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-bad-binary-literal.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-binary-literal.rs new file mode 100644 index 000000000000..34869add8264 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-binary-literal.rs @@ -0,0 +1,12 @@ +fn main() { + 0b121; // { dg-error "" "" { target *-*-* } } + 0b10_10301; // { dg-error "" "" { target *-*-* } } + 0b30; // { dg-error "" "" { target *-*-* } } + 0b41; // { dg-error "" "" { target *-*-* } } + 0b5; // { dg-error "" "" { target *-*-* } } + 0b6; // { dg-error "" "" { target *-*-* } } + 0b7; // { dg-error "" "" { target *-*-* } } + 0b8; // { dg-error "" "" { target *-*-* } } + 0b9; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-1.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-1.rs new file mode 100644 index 000000000000..46a6194fa63f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-1.rs @@ -0,0 +1,18 @@ +static c3: char = + '\x1' // { dg-error "" "" { target *-*-* } } +; + +static s3: &'static str = + "\x1" // { dg-error "" "" { target *-*-* } } +; + +static c: char = + '\●' // { dg-error "" "" { target *-*-* } } +; + +static s: &'static str = + "\●" // { dg-error "" "" { target *-*-* } } +; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-2.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-2.rs new file mode 100644 index 000000000000..658a5355d5bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-2.rs @@ -0,0 +1,7 @@ +// This test needs to the last one appearing in this file as it kills the parser +static c: char = + 'nope' // { dg-error "" "" { target *-*-* } } +; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-3.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-3.rs new file mode 100644 index 000000000000..85cafab6974c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-3.rs @@ -0,0 +1,8 @@ +static c: char = '●●'; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + let ch: &str = '●●'; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-4.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-4.rs new file mode 100644 index 000000000000..5ba2d1ee7d69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-4.rs @@ -0,0 +1,6 @@ +// +// This test needs to the last one appearing in this file as it kills the parser +static c: char = + '● // { dg-error ".E0762." "" { target *-*-* } } +; + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-5.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-5.rs new file mode 100644 index 000000000000..e6742e386005 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-5.rs @@ -0,0 +1,8 @@ +static c: char = '\x10\x10'; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + let ch: &str = '\x10\x10'; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-6.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-6.rs new file mode 100644 index 000000000000..dedab023e8d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-6.rs @@ -0,0 +1,18 @@ +fn main() { + let x: &str = 'ab'; +// { dg-error "" "" { target *-*-* } .-1 } + let y: char = 'cd'; +// { dg-error "" "" { target *-*-* } .-1 } + let z = 'ef'; +// { dg-error "" "" { target *-*-* } .-1 } + + if x == y {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + if y == z {} // no error here + if x == z {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + let a: usize = ""; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-7.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-7.rs new file mode 100644 index 000000000000..8306fe493d46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-char-literals-7.rs @@ -0,0 +1,14 @@ +fn main() { + let _: char = ''; +// { dg-error "" "" { target *-*-* } .-1 } + let _: char = '\u{}'; +// { dg-error "" "" { target *-*-* } .-1 } + + // Next two are OK, but may befool error recovery + let _ = '/'; + let _ = b'/'; + + let _ = ' hello // here's a comment +// { dg-error ".E0762." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-bad-numeric-literals.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-numeric-literals.rs new file mode 100644 index 000000000000..c46390fa817b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-numeric-literals.rs @@ -0,0 +1,28 @@ +fn main() { + 0o1.0; // { dg-error "" "" { target *-*-* } } + 0o2f32; // { dg-error "" "" { target *-*-* } } + 0o3.0f32; // { dg-error "" "" { target *-*-* } } + 0o4e4; // { dg-error "" "" { target *-*-* } } + 0o5.0e5; // { dg-error "" "" { target *-*-* } } + 0o6e6f32; // { dg-error "" "" { target *-*-* } } + 0o7.0e7f64; // { dg-error "" "" { target *-*-* } } + 0x8.0e+9; // { dg-error "" "" { target *-*-* } } + 0x9.0e-9; // { dg-error "" "" { target *-*-* } } + 0o; // { dg-error ".E0768." "" { target *-*-* } } + 1e+; // { dg-error "" "" { target *-*-* } } + 0x539.0; // { dg-error "" "" { target *-*-* } } + 9900000000000000000000000000999999999999999999999999999999; +// { dg-error "" "" { target *-*-* } .-1 } + 9900000000000000000000000000999999999999999999999999999999; +// { dg-error "" "" { target *-*-* } .-1 } + 0x; // { dg-error ".E0768." "" { target *-*-* } } + 0xu32; // { dg-error ".E0768." "" { target *-*-* } } + 0ou32; // { dg-error ".E0768." "" { target *-*-* } } + 0bu32; // { dg-error ".E0768." "" { target *-*-* } } + 0b; // { dg-error ".E0768." "" { target *-*-* } } + 0o123f64; // { dg-error "" "" { target *-*-* } } + 0o123.456; // { dg-error "" "" { target *-*-* } } + 0b101f64; // { dg-error "" "" { target *-*-* } } + 0b111.101; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-bad-octal-literal.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-octal-literal.rs new file mode 100644 index 000000000000..cb344cf22905 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-octal-literal.rs @@ -0,0 +1,5 @@ +fn main() { + 0o18; // { dg-error "" "" { target *-*-* } } + 0o1234_9_5670; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-bad-token.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-token.rs new file mode 100644 index 000000000000..b3873c0662be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-bad-token.rs @@ -0,0 +1,4 @@ +● // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-bare-cr-string-literal-doc-comment.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-bare-cr-string-literal-doc-comment.rs new file mode 100644 index 000000000000..7df7b0ae5b77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-bare-cr-string-literal-doc-comment.rs @@ -0,0 +1,27 @@ +// ignore-tidy-cr + +/// doc comment with bare CR: ' ' +pub fn foo() {} +// { dg-error "" "" { target *-*-* } .-2 } + +/** block doc comment with bare CR: ' ' */ +pub fn bar() {} +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { + //! doc comment with bare CR: ' ' +// { dg-error "" "" { target *-*-* } .-1 } + + /*! block doc comment with bare CR: ' ' */ +// { dg-error "" "" { target *-*-* } .-1 } + + // the following string literal has a bare CR in it + let _s = "foo bar"; // { dg-error "" "" { target *-*-* } } + + // the following string literal has a bare CR in it + let _s = r"bar foo"; // { dg-error "" "" { target *-*-* } } + + // the following string literal has a bare CR in it + let _s = "foo\ bar"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lex-stray-backslash.rs b/gcc/testsuite/rust/rustc/ui/parser/lex-stray-backslash.rs new file mode 100644 index 000000000000..94eb5b90e639 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lex-stray-backslash.rs @@ -0,0 +1,4 @@ +\ // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lifetime-in-pattern-recover.rs b/gcc/testsuite/rust/rustc/ui/parser/lifetime-in-pattern-recover.rs new file mode 100644 index 000000000000..fa08c9f0ef3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lifetime-in-pattern-recover.rs @@ -0,0 +1,7 @@ +fn main() { + let &'a x = &0; // { dg-error "" "" { target *-*-* } } + let &'a mut y = &mut 0; // { dg-error "" "" { target *-*-* } } + + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lifetime-in-pattern.rs b/gcc/testsuite/rust/rustc/ui/parser/lifetime-in-pattern.rs new file mode 100644 index 000000000000..21b68b79c742 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lifetime-in-pattern.rs @@ -0,0 +1,8 @@ +fn test(&'a str) { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/lifetime-semicolon.rs b/gcc/testsuite/rust/rustc/ui/parser/lifetime-semicolon.rs new file mode 100644 index 000000000000..33f6026f8b58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/lifetime-semicolon.rs @@ -0,0 +1,9 @@ +struct Foo<'a, 'b> { + a: &'a &'b i32 +} + +fn foo<'a, 'b>(x: &mut Foo<'a; 'b>) {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro-bad-delimiter-ident.rs b/gcc/testsuite/rust/rustc/ui/parser/macro-bad-delimiter-ident.rs new file mode 100644 index 000000000000..3c51e9e2cb6c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro-bad-delimiter-ident.rs @@ -0,0 +1,4 @@ +fn main() { + foo! bar < // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro-keyword.rs b/gcc/testsuite/rust/rustc/ui/parser/macro-keyword.rs new file mode 100644 index 000000000000..84b14877e128 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro-keyword.rs @@ -0,0 +1,6 @@ +fn macro() { // { dg-error "" "" { target *-*-* } } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro-mismatched-delim-brace-paren.rs b/gcc/testsuite/rust/rustc/ui/parser/macro-mismatched-delim-brace-paren.rs new file mode 100644 index 000000000000..2b38b2050046 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro-mismatched-delim-brace-paren.rs @@ -0,0 +1,8 @@ +macro_rules! foo { ($($tt:tt)*) => () } + +fn main() { + foo! { + bar, "baz", 1, 2.0 + ) // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro-mismatched-delim-paren-brace.rs b/gcc/testsuite/rust/rustc/ui/parser/macro-mismatched-delim-paren-brace.rs new file mode 100644 index 000000000000..3109d4511fc9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro-mismatched-delim-paren-brace.rs @@ -0,0 +1,6 @@ +fn main() { + foo! ( + bar, "baz", 1, 2.0 + } // { dg-error "" "" { target *-*-* } } +} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro/bad-macro-argument.rs b/gcc/testsuite/rust/rustc/ui/parser/macro/bad-macro-argument.rs new file mode 100644 index 000000000000..64b119dd0e0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro/bad-macro-argument.rs @@ -0,0 +1,5 @@ +fn main() { + let message = "world"; + println!("Hello, {}", message/); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro/issue-33569.rs b/gcc/testsuite/rust/rustc/ui/parser/macro/issue-33569.rs new file mode 100644 index 000000000000..a060d88cd44a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro/issue-33569.rs @@ -0,0 +1,11 @@ +macro_rules! foo { + { $+ } => { // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + $(x)(y) // { dg-error "" "" { target *-*-* } } + } +} + +foo!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro/issue-37113.rs b/gcc/testsuite/rust/rustc/ui/parser/macro/issue-37113.rs new file mode 100644 index 000000000000..7ad0ebdeca6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro/issue-37113.rs @@ -0,0 +1,12 @@ +macro_rules! test_macro { + ( $( $t:ty ),* $(),*) => { + enum SomeEnum { + $( $t, )* // { dg-error "" "" { target *-*-* } } + }; + }; +} + +fn main() { + test_macro!(String,); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro/issue-37234.rs b/gcc/testsuite/rust/rustc/ui/parser/macro/issue-37234.rs new file mode 100644 index 000000000000..a903f736ca86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro/issue-37234.rs @@ -0,0 +1,10 @@ +macro_rules! failed { + () => {{ + let x = 5 ""; // { dg-error "" "" { target *-*-* } } + }} +} + +fn main() { + failed!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro/literals-are-validated-before-expansion.rs b/gcc/testsuite/rust/rustc/ui/parser/macro/literals-are-validated-before-expansion.rs new file mode 100644 index 000000000000..79ce0adc8540 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro/literals-are-validated-before-expansion.rs @@ -0,0 +1,11 @@ +macro_rules! black_hole { + ($($tt:tt)*) => {} +} + +fn main() { + black_hole! { '\u{FFFFFF}' } +// { dg-error "" "" { target *-*-* } .-1 } + black_hole! { "this is surrogate: \u{DAAA}" } +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro/macro-doc-comments-1.rs b/gcc/testsuite/rust/rustc/ui/parser/macro/macro-doc-comments-1.rs new file mode 100644 index 000000000000..6f0d8f133910 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro/macro-doc-comments-1.rs @@ -0,0 +1,10 @@ +macro_rules! outer { + (#[$outer:meta]) => () +} + +outer! { + //! Inner +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro/macro-doc-comments-2.rs b/gcc/testsuite/rust/rustc/ui/parser/macro/macro-doc-comments-2.rs new file mode 100644 index 000000000000..f615fe798177 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro/macro-doc-comments-2.rs @@ -0,0 +1,10 @@ +macro_rules! inner { + (#![$inner:meta]) => () +} + +inner! { + /// Outer +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro/macro-incomplete-parse.rs b/gcc/testsuite/rust/rustc/ui/parser/macro/macro-incomplete-parse.rs new file mode 100644 index 000000000000..796b45497311 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro/macro-incomplete-parse.rs @@ -0,0 +1,28 @@ +macro_rules! ignored_item { + () => { + fn foo() {} + fn bar() {} + , // { dg-error "" "" { target *-*-* } } + } +} + +macro_rules! ignored_expr { + () => ( 1, // { dg-error "" "" { target *-*-* } } + + 2 ) +} + +macro_rules! ignored_pat { + () => ( 1, 2 ) // { dg-error "" "" { target *-*-* } } +} + +ignored_item!(); + +fn main() { + ignored_expr!(); + match 1 { + ignored_pat!() => (), + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro/macro-repeat.rs b/gcc/testsuite/rust/rustc/ui/parser/macro/macro-repeat.rs new file mode 100644 index 000000000000..7505bef4cee3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro/macro-repeat.rs @@ -0,0 +1,13 @@ +macro_rules! mac { + ( $($v:tt)* ) => { + $v +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + }; +} + +fn main() { + mac!(0); + mac!(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro/pub-item-macro.rs b/gcc/testsuite/rust/rustc/ui/parser/macro/pub-item-macro.rs new file mode 100644 index 000000000000..3617ced3054a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro/pub-item-macro.rs @@ -0,0 +1,22 @@ +// Issue #14660 + +macro_rules! priv_x { + () => { + static x: u32 = 0; + }; +} + +macro_rules! pub_x { () => { + pub priv_x!(); // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +}} + +mod foo { + pub_x!(); +} + +fn main() { + let y: u32 = foo::x; // { dg-error ".E0603." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro/trait-non-item-macros.rs b/gcc/testsuite/rust/rustc/ui/parser/macro/trait-non-item-macros.rs new file mode 100644 index 000000000000..46923a4e4bc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro/trait-non-item-macros.rs @@ -0,0 +1,14 @@ +macro_rules! bah { + ($a:expr) => { + $a +// { dg-error "" "" { target *-*-* } .-1 } +} + +trait Bar { + bah!(2); +} + +fn main() { + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macro/trait-object-macro-matcher.rs b/gcc/testsuite/rust/rustc/ui/parser/macro/trait-object-macro-matcher.rs new file mode 100644 index 000000000000..3a347404ebd5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macro/trait-object-macro-matcher.rs @@ -0,0 +1,16 @@ +// A single lifetime is not parsed as a type. +// `ty` matcher in particular doesn't accept a single lifetime + +macro_rules! m { + ($t: ty) => { + let _: $t; + }; +} + +fn main() { + m!('static); +// { dg-error ".E0224." "" { target *-*-* } .-1 } +// { dg-error ".E0224." "" { target *-*-* } .-2 } +// { dg-warning ".E0224." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macros-no-semicolon-items.rs b/gcc/testsuite/rust/rustc/ui/parser/macros-no-semicolon-items.rs new file mode 100644 index 000000000000..a24547d6dd87 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macros-no-semicolon-items.rs @@ -0,0 +1,16 @@ +macro_rules! foo() // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + +macro_rules! bar { + ($($tokens:tt)*) => {} +} + +bar!( // { dg-error "" "" { target *-*-* } } + blah + blah + blah +) + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/macros-no-semicolon.rs b/gcc/testsuite/rust/rustc/ui/parser/macros-no-semicolon.rs new file mode 100644 index 000000000000..436346acfc32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/macros-no-semicolon.rs @@ -0,0 +1,6 @@ +fn main() { + assert_eq!(1, 2) + assert_eq!(3, 4) // { dg-error "" "" { target *-*-* } } + println!("hello"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/match-arrows-block-then-binop.rs b/gcc/testsuite/rust/rustc/ui/parser/match-arrows-block-then-binop.rs new file mode 100644 index 000000000000..2acaf9c5af4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/match-arrows-block-then-binop.rs @@ -0,0 +1,8 @@ +fn main() { + let _ = match 0 { + 0 => { + 0 + } + 5 // { dg-error "" "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/match-refactor-to-expr.rs b/gcc/testsuite/rust/rustc/ui/parser/match-refactor-to-expr.rs new file mode 100644 index 000000000000..1dddf7033995 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/match-refactor-to-expr.rs @@ -0,0 +1,13 @@ +// run-rustfix + +fn main() { + let foo = + match // { dg-note "" "" { target *-*-* } } + Some(4).unwrap_or(5) +// { dg-note "" "" { target *-*-* } .-1 } + ; // { dg-note "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + + println!("{}", foo) +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/mbe_missing_right_paren.rs b/gcc/testsuite/rust/rustc/ui/parser/mbe_missing_right_paren.rs new file mode 100644 index 000000000000..e1de665f7b5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/mbe_missing_right_paren.rs @@ -0,0 +1,4 @@ +// ignore-tidy-trailing-newlines +// error-pattern: aborting due to 3 previous errors +macro_rules! abc(ؼ + diff --git a/gcc/testsuite/rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs new file mode 100644 index 000000000000..3cc7fa0f2127 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.rs @@ -0,0 +1,14 @@ +fn main() {} + +impl T for () { // { dg-error ".E0405." "" { target *-*-* } } + +fn foo(&self) {} + +trait T { // { dg-error "" "" { target *-*-* } } + fn foo(&self); +} + +pub(crate) struct Bar(); // { dg-error "" "" { target *-*-* } } + +// { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs b/gcc/testsuite/rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs new file mode 100644 index 000000000000..b0c6a24e26b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-struct.rs @@ -0,0 +1,14 @@ +pub(crate) struct Bar { + foo: T, + +trait T { // { dg-error "" "" { target *-*-* } } + fn foo(&self); +} + + +impl T for Bar { +fn foo(&self) {} +} + +fn main() {} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs b/gcc/testsuite/rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs new file mode 100644 index 000000000000..55ba286cb66f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/mismatched-braces/missing-close-brace-in-trait.rs @@ -0,0 +1,13 @@ +trait T { + fn foo(&self); + +pub(crate) struct Bar(); +// { dg-error "" "" { target *-*-* } .-1 } + +impl T for Bar { +// { dg-error "" "" { target *-*-* } .-1 } +fn foo(&self) {} +} + +fn main() {} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/mismatched-delim-brace-empty-block.rs b/gcc/testsuite/rust/rustc/ui/parser/mismatched-delim-brace-empty-block.rs new file mode 100644 index 000000000000..8402e498bf52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/mismatched-delim-brace-empty-block.rs @@ -0,0 +1,6 @@ +fn main() { + +} + let _ = (); +} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/missing-semicolon.rs b/gcc/testsuite/rust/rustc/ui/parser/missing-semicolon.rs new file mode 100644 index 000000000000..3e4c437604f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/missing-semicolon.rs @@ -0,0 +1,9 @@ +macro_rules! m { + ($($e1:expr),*; $($e2:expr),*) => { + $( let x = $e1 )*; // { dg-error "" "" { target *-*-* } } + $( println!("{}", $e2) )*; + } +} + +fn main() { m!(0, 0; 0, 0); } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/missing_right_paren.rs b/gcc/testsuite/rust/rustc/ui/parser/missing_right_paren.rs new file mode 100644 index 000000000000..e3d8ffde9a35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/missing_right_paren.rs @@ -0,0 +1,4 @@ +// ignore-tidy-trailing-newlines +// error-pattern: aborting due to 4 previous errors +fn main((ؼ + diff --git a/gcc/testsuite/rust/rustc/ui/parser/mod_file_not_exist.rs b/gcc/testsuite/rust/rustc/ui/parser/mod_file_not_exist.rs new file mode 100644 index 000000000000..97d7f893e9f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/mod_file_not_exist.rs @@ -0,0 +1,10 @@ +// ignore-windows + +mod not_a_real_file; // { dg-error ".E0583." "" { target *-*-* } } +// { help ".E0583." "" { target *-*-* } .-1 } + +fn main() { + assert_eq!(mod_file_aux::bar(), 10); +// { dg-error ".E0433." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/mod_file_not_exist_windows.rs b/gcc/testsuite/rust/rustc/ui/parser/mod_file_not_exist_windows.rs new file mode 100644 index 000000000000..11083ad28238 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/mod_file_not_exist_windows.rs @@ -0,0 +1,10 @@ +// only-windows + +mod not_a_real_file; // { dg-error ".E0583." "" { target *-*-* } } +// { help ".E0583." "" { target *-*-* } .-1 } + +fn main() { + assert_eq!(mod_file_aux::bar(), 10); +// { dg-error ".E0433." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/mod_file_with_path_attr.rs b/gcc/testsuite/rust/rustc/ui/parser/mod_file_with_path_attr.rs new file mode 100644 index 000000000000..5423ade8b46c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/mod_file_with_path_attr.rs @@ -0,0 +1,9 @@ +// normalize-stderr-test: "not_a_real_file.rs:.*\(" -> "not_a_real_file.rs: $$FILE_NOT_FOUND_MSG (" + +#[path = "not_a_real_file.rs"] +mod m; // { dg-error "" "" { target *-*-* } } + +fn main() { + assert_eq!(m::foo(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/multiline-comment-line-tracking.rs b/gcc/testsuite/rust/rustc/ui/parser/multiline-comment-line-tracking.rs new file mode 100644 index 000000000000..b2f31d8eb225 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/multiline-comment-line-tracking.rs @@ -0,0 +1,10 @@ +// Parse error on line X, but is reported on line Y instead. + +/* 1 + * 2 + * 3 + */ +fn main() { + %; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/multitrait.rs b/gcc/testsuite/rust/rustc/ui/parser/multitrait.rs new file mode 100644 index 000000000000..56d5452684df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/multitrait.rs @@ -0,0 +1,10 @@ +struct S { + y: isize +} + +impl Cmp, ToString for S { +// { dg-error "" "" { target *-*-* } .-1 } + fn eq(&&other: S) { false } + fn to_string(&self) -> String { "hi".to_string() } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/mut-patterns.rs b/gcc/testsuite/rust/rustc/ui/parser/mut-patterns.rs new file mode 100644 index 000000000000..2da2df866f33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/mut-patterns.rs @@ -0,0 +1,49 @@ +// Can't put mut in non-ident pattern + +// edition:2018 + +#![feature(box_patterns)] +#![allow(warnings)] + +pub fn main() { + let mut _ = 0; // { dg-error "" "" { target *-*-* } } + let mut (_, _) = (0, 0); // { dg-error "" "" { target *-*-* } } + + let mut (x @ y) = 0; // { dg-error "" "" { target *-*-* } } + + let mut mut x = 0; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + struct Foo { x: isize } + let mut Foo { x: x } = Foo { x: 3 }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + let mut Foo { x } = Foo { x: 3 }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + struct r#yield(u8, u8); + let mut mut yield(become, await) = r#yield(0, 0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } + + struct W(T, U); + struct B { f: Box } + let mut W(mut a, W(b, W(ref c, W(d, B { box f })))) +// { dg-error "" "" { target *-*-* } .-1 } + = W(0, W(1, W(2, W(3, B { f: Box::new(4u8) })))); + + // Make sure we don't accidentally allow `mut $p` where `$p:pat`. + macro_rules! foo { + ($p:pat) => { + let mut $p = 0; // { dg-error "" "" { target *-*-* } } + } + } + foo!(x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-1.rs b/gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-1.rs new file mode 100644 index 000000000000..de9699510e7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-1.rs @@ -0,0 +1,4 @@ +pub fn main() { + let s = "\u{2603"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-2.rs b/gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-2.rs new file mode 100644 index 000000000000..ab75ac84ab14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-2.rs @@ -0,0 +1,4 @@ +pub fn main() { + let s = "\u{260311111111}"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-3.rs b/gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-3.rs new file mode 100644 index 000000000000..2b45a23c01e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-3.rs @@ -0,0 +1,5 @@ +pub fn main() { + let s1 = "\u{d805}"; // { dg-error "" "" { target *-*-* } } + let s2 = "\u{ffffff}"; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-4.rs b/gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-4.rs new file mode 100644 index 000000000000..cbbc78231892 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/new-unicode-escapes-4.rs @@ -0,0 +1,5 @@ +pub fn main() { + let s = "\u{lol}"; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/no-binary-float-literal.rs b/gcc/testsuite/rust/rustc/ui/parser/no-binary-float-literal.rs new file mode 100644 index 000000000000..274df41af786 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/no-binary-float-literal.rs @@ -0,0 +1,9 @@ +fn main() { + 0b101010f64; +// { dg-error "" "" { target *-*-* } .-1 } + 0b101.010; +// { dg-error "" "" { target *-*-* } .-1 } + 0b101p4f64; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/no-const-fn-in-extern-block.rs b/gcc/testsuite/rust/rustc/ui/parser/no-const-fn-in-extern-block.rs new file mode 100644 index 000000000000..f3b59d39c845 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/no-const-fn-in-extern-block.rs @@ -0,0 +1,9 @@ +extern { + const fn foo(); +// { dg-error "" "" { target *-*-* } .-1 } + const unsafe fn bar(); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/no-hex-float-literal.rs b/gcc/testsuite/rust/rustc/ui/parser/no-hex-float-literal.rs new file mode 100644 index 000000000000..a2356584aeff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/no-hex-float-literal.rs @@ -0,0 +1,10 @@ +fn main() { + 0xABC.Df; +// { dg-error ".E0610." "" { target *-*-* } .-1 } + 0x567.89; +// { dg-error "" "" { target *-*-* } .-1 } + 0xDEAD.BEEFp-2f; +// { dg-error ".E0610." "" { target *-*-* } .-1 } +// { dg-error ".E0610." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/no-unsafe-self.rs b/gcc/testsuite/rust/rustc/ui/parser/no-unsafe-self.rs new file mode 100644 index 000000000000..828c97c14741 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/no-unsafe-self.rs @@ -0,0 +1,15 @@ +trait A { + fn foo(*mut self); // { dg-error "" "" { target *-*-* } } + fn baz(*const self); // { dg-error "" "" { target *-*-* } } + fn bar(*self); // { dg-error "" "" { target *-*-* } } +} + +struct X; +impl A for X { + fn foo(*mut self) { } // { dg-error "" "" { target *-*-* } } + fn baz(*const self) { } // { dg-error "" "" { target *-*-* } } + fn bar(*self) { } // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/not-a-pred.rs b/gcc/testsuite/rust/rustc/ui/parser/not-a-pred.rs new file mode 100644 index 000000000000..10be8a367913 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/not-a-pred.rs @@ -0,0 +1,7 @@ +fn f(a: isize, b: isize) : lt(a, b) { } +// { dg-error "" "" { target *-*-* } .-1 } + +fn lt(a: isize, b: isize) { } + +fn main() { let a: isize = 10; let b: isize = 23; check (lt(a, b)); f(a, b); } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/nt-parsing-has-recovery.rs b/gcc/testsuite/rust/rustc/ui/parser/nt-parsing-has-recovery.rs new file mode 100644 index 000000000000..9887cf36109b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/nt-parsing-has-recovery.rs @@ -0,0 +1,11 @@ +macro_rules! foo { + ($e:expr) => {} +} + +foo!(1 + @); // { dg-error "" "" { target *-*-* } } +foo!(1 + @); // { dg-error "" "" { target *-*-* } } + +fn main() { + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/numeric-lifetime.rs b/gcc/testsuite/rust/rustc/ui/parser/numeric-lifetime.rs new file mode 100644 index 000000000000..edd33db7a574 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/numeric-lifetime.rs @@ -0,0 +1,9 @@ +struct S<'1> { s: &'1 usize } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +fn main() { + // verify that the parse error doesn't stop type checking + let x: usize = ""; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/omitted-arg-in-item-fn.rs b/gcc/testsuite/rust/rustc/ui/parser/omitted-arg-in-item-fn.rs new file mode 100644 index 000000000000..3adf399221dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/omitted-arg-in-item-fn.rs @@ -0,0 +1,5 @@ +fn foo(x) { // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/paamayim-nekudotayim.rs b/gcc/testsuite/rust/rustc/ui/parser/paamayim-nekudotayim.rs new file mode 100644 index 000000000000..1d918dc4cace --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/paamayim-nekudotayim.rs @@ -0,0 +1,6 @@ +// http://phpsadness.com/sad/1 + +fn main() { + ::; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/paren-after-qualified-path-in-match.rs b/gcc/testsuite/rust/rustc/ui/parser/paren-after-qualified-path-in-match.rs new file mode 100644 index 000000000000..79bcf3ccceb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/paren-after-qualified-path-in-match.rs @@ -0,0 +1,8 @@ +fn main() { + match 10 { + ::Type(2) => (), +// { dg-error "" "" { target *-*-* } .-1 } + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-1.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-1.rs new file mode 100644 index 000000000000..977c5b160ced --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-1.rs @@ -0,0 +1,8 @@ +fn main() { + match 42 { + x < 7 => (), +// { dg-error "" "" { target *-*-* } .-1 } + _ => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-2.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-2.rs new file mode 100644 index 000000000000..9f9e51fd74f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-2.rs @@ -0,0 +1,5 @@ +fn a(B<) {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-3.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-3.rs new file mode 100644 index 000000000000..f11b39159c61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-3.rs @@ -0,0 +1,15 @@ +struct Foo(T, T); + +impl Foo { + fn foo(&self) { + match *self { + Foo(x, y) => { +// { dg-error "" "" { target *-*-* } .-1 } + println!("Goodbye, World!") + } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-4.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-4.rs new file mode 100644 index 000000000000..cc60b1ddff52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-4.rs @@ -0,0 +1,12 @@ +enum BtNode { + Node(u32,Box,Box), + Leaf(u32), +} + +fn main() { + let y = match 10 { + Foo::A(value) => value, // { dg-error "" "" { target *-*-* } } + Foo::B => 7, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-5.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-5.rs new file mode 100644 index 000000000000..061c9ff35b6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-5.rs @@ -0,0 +1,4 @@ +fn main() { + let v[0] = v[1]; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-6.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-6.rs new file mode 100644 index 000000000000..c05a27ebdbf5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-6.rs @@ -0,0 +1,10 @@ +fn main() { + struct Test(&'static u8, [u8; 0]); + let x = Test(&0, []); + + let Test(&desc[..]) = x; +// { dg-error "" "" { target *-*-* } .-1 } +} + +const RECOVERY_WITNESS: () = 0; // { dg-error ".E0308." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-7.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-7.rs new file mode 100644 index 000000000000..9f23f9533d74 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-lt-bracket-7.rs @@ -0,0 +1,10 @@ +fn main() { + struct Thing(u8, [u8; 0]); + let foo = core::iter::empty(); + + for Thing(x[]) in foo {} +// { dg-error "" "" { target *-*-* } .-1 } +} + +const RECOVERY_WITNESS: () = 0; // { dg-error ".E0308." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-ranges-1.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-ranges-1.rs new file mode 100644 index 000000000000..64a9cf7bd8b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-ranges-1.rs @@ -0,0 +1,6 @@ +// Parsing of range patterns + +fn main() { + let macropus!() ..= 11 = 12; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-ranges-2.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-ranges-2.rs new file mode 100644 index 000000000000..bc6d699e2ce5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-ranges-2.rs @@ -0,0 +1,6 @@ +// Parsing of range patterns + +fn main() { + let 10 ..= makropulos!() = 12; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-ranges-3.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-ranges-3.rs new file mode 100644 index 000000000000..5e7396b9c584 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-ranges-3.rs @@ -0,0 +1,6 @@ +// Parsing of range patterns + +fn main() { + let 10 ..= 10 + 3 = 12; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-ranges-4.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-ranges-4.rs new file mode 100644 index 000000000000..b33968733c82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-ranges-4.rs @@ -0,0 +1,7 @@ +// Parsing of range patterns + +fn main() { + let 10 - 3 ..= 10 = 8; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-ref-enum.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-ref-enum.rs new file mode 100644 index 000000000000..45fd8aef4d44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-ref-enum.rs @@ -0,0 +1,9 @@ +fn matcher(x: Option) { + match x { + ref Some(i) => {} // { dg-error "" "" { target *-*-* } } + None => {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-tuple-1.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-tuple-1.rs new file mode 100644 index 000000000000..0e4ba1aa0226 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-tuple-1.rs @@ -0,0 +1,6 @@ +fn main() { + match (0, 1) { + (, ..) => {} // { dg-error "" "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-tuple-2.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-tuple-2.rs new file mode 100644 index 000000000000..63ea3947b34c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-tuple-2.rs @@ -0,0 +1,8 @@ +// check-pass + +fn main() { + match (0, 1, 2) { + (pat, ..,) => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pat-tuple-3.rs b/gcc/testsuite/rust/rustc/ui/parser/pat-tuple-3.rs new file mode 100644 index 000000000000..7c2000fc420a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pat-tuple-3.rs @@ -0,0 +1,7 @@ +fn main() { + match (0, 1, 2) { + (.., pat, ..) => {} +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/pub-method-macro.rs b/gcc/testsuite/rust/rustc/ui/parser/pub-method-macro.rs new file mode 100644 index 000000000000..23e0b74b2c24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/pub-method-macro.rs @@ -0,0 +1,24 @@ +// Issue #18317 + +mod bleh { + macro_rules! defn { + ($n:ident) => ( + fn $n (&self) -> i32 { + println!("{}", stringify!($n)); + 1 + } + ) + } + + #[derive(Copy, Clone)] + pub struct S; + + impl S { + pub defn!(f); // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/qualified-path-in-turbofish.rs b/gcc/testsuite/rust/rustc/ui/parser/qualified-path-in-turbofish.rs new file mode 100644 index 000000000000..76c028ff3c49 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/qualified-path-in-turbofish.rs @@ -0,0 +1,20 @@ +// run-rustfix +trait T { + type Ty; +} + +struct Impl; + +impl T for Impl { + type Ty = u32; +} + +fn template() -> i64 { + 3 +} + +fn main() { + template::<:Ty>(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/range-3.rs b/gcc/testsuite/rust/rustc/ui/parser/range-3.rs new file mode 100644 index 000000000000..7e4840e3e055 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/range-3.rs @@ -0,0 +1,7 @@ +// Test range syntax - syntax errors. + +pub fn main() { + let r = 1..2..3; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/range-4.rs b/gcc/testsuite/rust/rustc/ui/parser/range-4.rs new file mode 100644 index 000000000000..479e004a0fb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/range-4.rs @@ -0,0 +1,7 @@ +// Test range syntax - syntax errors. + +pub fn main() { + let r = ..1..2; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/range_inclusive.rs b/gcc/testsuite/rust/rustc/ui/parser/range_inclusive.rs new file mode 100644 index 000000000000..fc8ff25573c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/range_inclusive.rs @@ -0,0 +1,8 @@ +// run-rustfix +// Make sure that inclusive ranges with no end point don't parse. + +pub fn main() { + for _ in 1..= {} // { dg-error ".E0586." "" { target *-*-* } } +// { help ".E0586." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/range_inclusive_dotdotdot.rs b/gcc/testsuite/rust/rustc/ui/parser/range_inclusive_dotdotdot.rs new file mode 100644 index 000000000000..8bd3c5c600db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/range_inclusive_dotdotdot.rs @@ -0,0 +1,24 @@ +// Make sure that inclusive ranges with `...` syntax don't parse. + +use std::ops::RangeToInclusive; + +fn return_range_to() -> RangeToInclusive { + return ...1; // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +} + +pub fn main() { + let x = ...0; // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + + let x = 5...5; // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + + for _ in 0...1 {} // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs b/gcc/testsuite/rust/rustc/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs new file mode 100644 index 000000000000..0421b51b769a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/raw/issue-70677-panic-on-unterminated-raw-str-at-eof.rs @@ -0,0 +1,6 @@ +// This won't actually panic because of the error comment -- the `"` needs to be +// the last byte in the file (including not having a trailing newline) +// Prior to the fix you get the error: 'expected item, found `r" ...`' +// because the string being unterminated wasn't properly detected. +r" // { dg-error ".E0748." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/raw/raw-byte-string-eof.rs b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-byte-string-eof.rs new file mode 100644 index 000000000000..548101cca2ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-byte-string-eof.rs @@ -0,0 +1,4 @@ +pub fn main() { + br##"a"#; // { dg-error ".E0748." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/raw/raw-byte-string-literals.rs b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-byte-string-literals.rs new file mode 100644 index 000000000000..2dfedf2762f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-byte-string-literals.rs @@ -0,0 +1,8 @@ +// ignore-tidy-cr + +pub fn main() { + br"a "; // { dg-error "" "" { target *-*-* } } + br"é"; // { dg-error "" "" { target *-*-* } } + br##~"a"~##; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/raw/raw-literal-keywords.rs b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-literal-keywords.rs new file mode 100644 index 000000000000..32e9119ef662 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-literal-keywords.rs @@ -0,0 +1,26 @@ +fn test_if() { + r#if true { } // { dg-error "" "" { target *-*-* } } +} + +fn test_struct() { + r#struct Test; // { dg-error "" "" { target *-*-* } } +} + +fn test_union() { + r#union Test; // { dg-error "" "" { target *-*-* } } +} + +fn test_if_2() { + let _ = r#if; // { dg-error ".E0425." "" { target *-*-* } } +} + +fn test_struct_2() { + let _ = r#struct; // { dg-error ".E0425." "" { target *-*-* } } +} + +fn test_union_2() { + let _ = r#union; // { dg-error ".E0425." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/raw/raw-literal-self.rs b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-literal-self.rs new file mode 100644 index 000000000000..fbd44ab12b1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-literal-self.rs @@ -0,0 +1,5 @@ +fn main() { + let r#self: (); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/raw/raw-literal-underscore.rs b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-literal-underscore.rs new file mode 100644 index 000000000000..22f96c84eabb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-literal-underscore.rs @@ -0,0 +1,5 @@ +fn main() { + let r#_: (); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-delim.rs b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-delim.rs new file mode 100644 index 000000000000..215edd3cf177 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-delim.rs @@ -0,0 +1,4 @@ +static s: &'static str = + r#~"#"~# // { dg-error "" "" { target *-*-* } } +; + diff --git a/gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-in-macro-call.rs b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-in-macro-call.rs new file mode 100644 index 000000000000..a10bd1ef131a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-in-macro-call.rs @@ -0,0 +1,15 @@ +// check-pass + +macro_rules! m1 { + ($tt:tt #) => () +} + +macro_rules! m2 { + ($tt:tt) => () +} + +fn main() { + m1!(r#"abc"##); + m2!(r#"abc"#); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-unbalanced.rs b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-unbalanced.rs new file mode 100644 index 000000000000..4300536a94b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-unbalanced.rs @@ -0,0 +1,5 @@ +static s: &'static str = + r#" + "## // { dg-error "" "" { target *-*-* } } +; + diff --git a/gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-unterminated.rs b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-unterminated.rs new file mode 100644 index 000000000000..5194d44dd217 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-str-unterminated.rs @@ -0,0 +1,5 @@ +static s: &'static str = + r#" string literal goes on + and on +// { dg-error ".E0748." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/raw/raw-string-2.rs b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-string-2.rs new file mode 100644 index 000000000000..37faeee4d70d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-string-2.rs @@ -0,0 +1,5 @@ +fn main() { + let x = r###"here's a long string"# "# "##; +// { dg-error ".E0748." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/raw/raw-string.rs b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-string.rs new file mode 100644 index 000000000000..c7e4b7391fd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/raw/raw-string.rs @@ -0,0 +1,5 @@ +fn main() { + let x = r##"lol"#; +// { dg-error ".E0748." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-assoc-const-constraint.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-assoc-const-constraint.rs new file mode 100644 index 000000000000..1fd5b8643a8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-assoc-const-constraint.rs @@ -0,0 +1,8 @@ +#[cfg(FALSE)] +fn syntax() { + bar::(); // { dg-error "" "" { target *-*-* } } + bar::(); // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-assoc-eq-missing-term.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-assoc-eq-missing-term.rs new file mode 100644 index 000000000000..fafe420fbfae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-assoc-eq-missing-term.rs @@ -0,0 +1,7 @@ +#[cfg(FALSE)] +fn syntax() { + bar::(); // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-assoc-lifetime-constraint.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-assoc-lifetime-constraint.rs new file mode 100644 index 000000000000..6841c56ae7fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-assoc-lifetime-constraint.rs @@ -0,0 +1,7 @@ +#[cfg(FALSE)] +fn syntax() { + bar::(); // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-const-async-fn-ptr.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-const-async-fn-ptr.rs new file mode 100644 index 000000000000..5a139344502d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-const-async-fn-ptr.rs @@ -0,0 +1,26 @@ +// edition:2018 + +type T0 = const fn(); // { dg-error "" "" { target *-*-* } } +type T1 = const extern "C" fn(); // { dg-error "" "" { target *-*-* } } +type T2 = const unsafe extern fn(); // { dg-error "" "" { target *-*-* } } +type T3 = async fn(); // { dg-error "" "" { target *-*-* } } +type T4 = async extern fn(); // { dg-error "" "" { target *-*-* } } +type T5 = async unsafe extern "C" fn(); // { dg-error "" "" { target *-*-* } } +type T6 = const async unsafe extern "C" fn(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +type FT0 = for<'a> const fn(); // { dg-error "" "" { target *-*-* } } +type FT1 = for<'a> const extern "C" fn(); // { dg-error "" "" { target *-*-* } } +type FT2 = for<'a> const unsafe extern fn(); // { dg-error "" "" { target *-*-* } } +type FT3 = for<'a> async fn(); // { dg-error "" "" { target *-*-* } } +type FT4 = for<'a> async extern fn(); // { dg-error "" "" { target *-*-* } } +type FT5 = for<'a> async unsafe extern "C" fn(); // { dg-error "" "" { target *-*-* } } +type FT6 = for<'a> const async unsafe extern "C" fn(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-enum.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-enum.rs new file mode 100644 index 000000000000..a3e088ff4891 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-enum.rs @@ -0,0 +1,12 @@ +fn main() { + enum Test { + Very // { help "" "" { target *-*-* } } + Bad(usize) // { help "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + Stuff { a: usize } // { help "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + Here +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-enum2.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-enum2.rs new file mode 100644 index 000000000000..e4591657e4f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-enum2.rs @@ -0,0 +1,29 @@ +fn main() { + enum Test { + Var1, + Var2(String), + Var3 { + abc: {}, // { dg-error "" "" { target *-*-* } } + }, + } + + // recover... + let a = 1; + enum Test2 { + Fine, + } + + enum Test3 { + StillFine { + def: i32, + }, + } + + { + // fail again + enum Test4 { + Nope(i32 {}) // { dg-error "" "" { target *-*-* } } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-field-extra-angle-brackets.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-field-extra-angle-brackets.rs new file mode 100644 index 000000000000..374cee255500 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-field-extra-angle-brackets.rs @@ -0,0 +1,15 @@ +// Tests that we recover from extra trailing angle brackets +// in a struct field + +struct BadStruct { + first: Vec>, // { dg-error "" "" { target *-*-* } } + second: bool +} + +fn bar(val: BadStruct) { + val.first; + val.second; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-for-loop-parens-around-head.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-for-loop-parens-around-head.rs new file mode 100644 index 000000000000..c51366c6157c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-for-loop-parens-around-head.rs @@ -0,0 +1,16 @@ +// Here we test that the parser is able to recover in a situation like +// `for ( $pat in $expr )` since that is familiar syntax in other languages. +// Instead we suggest that the user writes `for $pat in $expr`. + +#![deny(unused)] // Make sure we don't trigger `unused_parens`. + +fn main() { + let vec = vec![1, 2, 3]; + + for ( elem in vec ) { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + const RECOVERY_WITNESS: () = 0; // { dg-error ".E0308." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-from-bad-variant.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-from-bad-variant.rs new file mode 100644 index 000000000000..6148cb643936 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-from-bad-variant.rs @@ -0,0 +1,16 @@ +enum Enum { + Foo { a: usize, b: usize }, + Bar(usize, usize), +} + +fn main() { + let x = Enum::Foo(a: 3, b: 4); +// { dg-error "" "" { target *-*-* } .-1 } + match x { + Enum::Foo(a, b) => {} +// { dg-error ".E0532." "" { target *-*-* } .-1 } + Enum::Bar { a, b } => {} +// { dg-error ".E0769." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-from-homoglyph.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-from-homoglyph.rs new file mode 100644 index 000000000000..14a1f4c0d8fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-from-homoglyph.rs @@ -0,0 +1,5 @@ +fn main() { + println!(""); // { dg-error "" "" { target *-*-* } } + let x: usize = (); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-labeled-non-block-expr.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-labeled-non-block-expr.rs new file mode 100644 index 000000000000..4c52d7034369 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-labeled-non-block-expr.rs @@ -0,0 +1,6 @@ +fn main() { + 'label: 1 + 1; // { dg-error "" "" { target *-*-* } } + + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-missing-semi.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-missing-semi.rs new file mode 100644 index 000000000000..380dbd3755a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-missing-semi.rs @@ -0,0 +1,14 @@ +fn main() { + let _: usize = () +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let _ = 3; +} + +fn foo() -> usize { + let _: usize = () +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + return 3; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-quantified-closure.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-quantified-closure.rs new file mode 100644 index 000000000000..f65bd8b6e16e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-quantified-closure.rs @@ -0,0 +1,11 @@ +fn main() { + for<'a> |x: &'a u8| *x + 1; +// { dg-error "" "" { target *-*-* } .-1 } +} + +enum Foo { Bar } +fn foo(x: impl Iterator) { + for ::Bar in x {} +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-range-pats.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-range-pats.rs new file mode 100644 index 000000000000..3ab2199aac5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-range-pats.rs @@ -0,0 +1,148 @@ +// Here we test all kinds of range patterns in terms of parsing / recovery. +// We want to ensure that: +// 1. Things parse as they should. +// 2. Or at least we have parser recovery if they don't. + +#![feature(exclusive_range_pattern)] +#![feature(half_open_range_patterns)] +#![deny(ellipsis_inclusive_range_patterns)] + +fn main() {} + +const X: u8 = 0; +const Y: u8 = 3; + +fn exclusive_from_to() { + if let 0..3 = 0 {} // OK. + if let 0..Y = 0 {} // OK. + if let X..3 = 0 {} // OK. + if let X..Y = 0 {} // OK. + if let true..Y = 0 {} // { dg-error ".E0029." "" { target *-*-* } } + if let X..true = 0 {} // { dg-error ".E0029." "" { target *-*-* } } + if let .0..Y = 0 {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + if let X.. .0 = 0 {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn inclusive_from_to() { + if let 0..=3 = 0 {} // OK. + if let 0..=Y = 0 {} // OK. + if let X..=3 = 0 {} // OK. + if let X..=Y = 0 {} // OK. + if let true..=Y = 0 {} // { dg-error ".E0029." "" { target *-*-* } } + if let X..=true = 0 {} // { dg-error ".E0029." "" { target *-*-* } } + if let .0..=Y = 0 {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + if let X..=.0 = 0 {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn inclusive2_from_to() { + if let 0...3 = 0 {} // { dg-error "" "" { target *-*-* } } + if let 0...Y = 0 {} // { dg-error "" "" { target *-*-* } } + if let X...3 = 0 {} // { dg-error "" "" { target *-*-* } } + if let X...Y = 0 {} // { dg-error "" "" { target *-*-* } } + if let true...Y = 0 {} // { dg-error ".E0029." "" { target *-*-* } } +// { dg-error ".E0029." "" { target *-*-* } .-1 } + if let X...true = 0 {} // { dg-error ".E0029." "" { target *-*-* } } +// { dg-error ".E0029." "" { target *-*-* } .-1 } + if let .0...Y = 0 {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + if let X... .0 = 0 {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn exclusive_from() { + if let 0.. = 0 {} + if let X.. = 0 {} + if let true.. = 0 {} +// { dg-error ".E0029." "" { target *-*-* } .-1 } + if let .0.. = 0 {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn inclusive_from() { + if let 0..= = 0 {} // { dg-error ".E0586." "" { target *-*-* } } + if let X..= = 0 {} // { dg-error ".E0586." "" { target *-*-* } } + if let true..= = 0 {} // { dg-error ".E0029." "" { target *-*-* } } +// { dg-error ".E0586." "" { target *-*-* } .-2 } + if let .0..= = 0 {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn inclusive2_from() { + if let 0... = 0 {} // { dg-error ".E0586." "" { target *-*-* } } + if let X... = 0 {} // { dg-error ".E0586." "" { target *-*-* } } + if let true... = 0 {} // { dg-error ".E0029." "" { target *-*-* } } +// { dg-error ".E0586." "" { target *-*-* } .-2 } + if let .0... = 0 {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn exclusive_to() { + if let ..0 = 0 {} + if let ..Y = 0 {} + if let ..true = 0 {} +// { dg-error ".E0029." "" { target *-*-* } .-1 } + if let .. .0 = 0 {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn inclusive_to() { + if let ..=3 = 0 {} + if let ..=Y = 0 {} + if let ..=true = 0 {} +// { dg-error ".E0029." "" { target *-*-* } .-1 } + if let ..=.0 = 0 {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn inclusive2_to() { + if let ...3 = 0 {} +// { dg-error "" "" { target *-*-* } .-1 } + if let ...Y = 0 {} +// { dg-error "" "" { target *-*-* } .-1 } + if let ...true = 0 {} +// { dg-error ".E0029." "" { target *-*-* } .-1 } +// { dg-error ".E0029." "" { target *-*-* } .-2 } + if let ....3 = 0 {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +} + +fn with_macro_expr_var() { + macro_rules! mac2 { + ($e1:expr, $e2:expr) => { + let $e1..$e2; + let $e1...$e2; +// { dg-error "" "" { target *-*-* } .-1 } + let $e1..=$e2; + } + } + + mac2!(0, 1); + + macro_rules! mac { + ($e:expr) => { + let ..$e; + let ...$e; +// { dg-error "" "" { target *-*-* } .-1 } + let ..=$e; + let $e..; + let $e...; // { dg-error ".E0586." "" { target *-*-* } } + let $e..=; // { dg-error ".E0586." "" { target *-*-* } } + } + } + + mac!(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-struct.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-struct.rs new file mode 100644 index 000000000000..544c29d445e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-struct.rs @@ -0,0 +1,8 @@ +fn main() { + struct Test { + Very + Bad // { dg-error "" "" { target *-*-* } } + Stuff + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-tuple-pat.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-tuple-pat.rs new file mode 100644 index 000000000000..eb0b69a028b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-tuple-pat.rs @@ -0,0 +1,13 @@ +// NOTE: This doesn't recover anymore. + +fn main() { + let x = (1, 2, 3, 4); + match x { + (1, .., 4) => {} + (1, .=., 4) => { let _: usize = ""; } +// { dg-error "" "" { target *-*-* } .-1 } + (.=., 4) => {} + (1, 2, 3, 4) => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recover-tuple.rs b/gcc/testsuite/rust/rustc/ui/parser/recover-tuple.rs new file mode 100644 index 000000000000..704dad638004 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recover-tuple.rs @@ -0,0 +1,12 @@ +fn main() { + // no complaints about the tuple not matching the expected type + let x: (usize, usize, usize) = (3, .=.); +// { dg-error "" "" { target *-*-* } .-1 } + // verify that the parser recovers: + let y: usize = ""; // { dg-error ".E0308." "" { target *-*-* } } + // no complaints about the type + foo(x); +} + +fn foo(_: (usize, usize, usize)) {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/recovered-struct-variant.rs b/gcc/testsuite/rust/rustc/ui/parser/recovered-struct-variant.rs new file mode 100644 index 000000000000..1fc544324a0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/recovered-struct-variant.rs @@ -0,0 +1,14 @@ +enum Foo { + A { a, b: usize } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { + // no complaints about non-existing fields + let f = Foo::A { a:3, b: 4}; + match f { + // no complaints about non-existing fields + Foo::A {a, b} => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/regions-out-of-scope-slice.rs b/gcc/testsuite/rust/rustc/ui/parser/regions-out-of-scope-slice.rs new file mode 100644 index 000000000000..f72a18ca101e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/regions-out-of-scope-slice.rs @@ -0,0 +1,12 @@ +// This basically tests the parser's recovery on `'blk` in the wrong place. + +fn foo(cond: bool) { + let mut x; + + if cond { + x = &'blk [1,2,3]; // { dg-error "" "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-closure-lifetime.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-closure-lifetime.rs new file mode 100644 index 000000000000..f666bd974721 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-closure-lifetime.rs @@ -0,0 +1,3 @@ +type closure = Box; +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-enum-newtype.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-enum-newtype.rs new file mode 100644 index 000000000000..6b0cb99bea17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-enum-newtype.rs @@ -0,0 +1,2 @@ +enum e = isize; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-field-let.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-field-let.rs new file mode 100644 index 000000000000..765344dbe3bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-field-let.rs @@ -0,0 +1,7 @@ +struct S { + let foo: (), +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-field-semicolon.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-field-semicolon.rs new file mode 100644 index 000000000000..494a524c1315 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-field-semicolon.rs @@ -0,0 +1,7 @@ +struct S { + bar: (); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-fixed-vec.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-fixed-vec.rs new file mode 100644 index 000000000000..8855fdef2b47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-fixed-vec.rs @@ -0,0 +1,2 @@ +type v = [isize * 3]; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-fn-sigil.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-fn-sigil.rs new file mode 100644 index 000000000000..b451448374c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-fn-sigil.rs @@ -0,0 +1,4 @@ +fn main() { + let x: fn~() = || (); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-mode.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-mode.rs new file mode 100644 index 000000000000..cbb12a128aab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-mode.rs @@ -0,0 +1,5 @@ +fn f(+x: isize) {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-mut-vec-expr.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-mut-vec-expr.rs new file mode 100644 index 000000000000..073e286ed4cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-mut-vec-expr.rs @@ -0,0 +1,4 @@ +fn main() { + let v = [mut 1, 2, 3, 4]; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-mut-vec-ty.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-mut-vec-ty.rs new file mode 100644 index 000000000000..b0d31b1347fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-mut-vec-ty.rs @@ -0,0 +1,2 @@ +type v = [mut isize]; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-ptr-lifetime.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-ptr-lifetime.rs new file mode 100644 index 000000000000..4a60b1251244 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-ptr-lifetime.rs @@ -0,0 +1,2 @@ +type bptr = &lifetime/isize; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-record.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-record.rs new file mode 100644 index 000000000000..ea60ce09fa95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-record.rs @@ -0,0 +1,2 @@ +type t = { f: () }; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-static-fn.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-static-fn.rs new file mode 100644 index 000000000000..03d25b664034 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-static-fn.rs @@ -0,0 +1,11 @@ +struct S; + +impl S { + static fn f() {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-uniq-mut-expr.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-uniq-mut-expr.rs new file mode 100644 index 000000000000..a7e437316722 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-uniq-mut-expr.rs @@ -0,0 +1,4 @@ +fn main() { + let a_box = box mut 42; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-uniq-mut-ty.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-uniq-mut-ty.rs new file mode 100644 index 000000000000..1a1d92c09804 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-uniq-mut-ty.rs @@ -0,0 +1,3 @@ +type mut_box = Box; +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-with-1.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-with-1.rs new file mode 100644 index 000000000000..185c008a3467 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-with-1.rs @@ -0,0 +1,11 @@ +fn main() { + struct S { + foo: (), + bar: (), + } + + let a = S { foo: (), bar: () }; + let b = S { foo: () with a, bar: () }; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-with-2.rs b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-with-2.rs new file mode 100644 index 000000000000..f5abb853eee8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/removed-syntax-with-2.rs @@ -0,0 +1,12 @@ +fn main() { + struct S { + foo: (), + bar: (), + } + + let a = S { foo: (), bar: () }; + let b = S { foo: (), with a }; +// { dg-error ".E0063." "" { target *-*-* } .-1 } +// { dg-error ".E0063." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/require-parens-for-chained-comparison.rs b/gcc/testsuite/rust/rustc/ui/parser/require-parens-for-chained-comparison.rs new file mode 100644 index 000000000000..8dfb5136116c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/require-parens-for-chained-comparison.rs @@ -0,0 +1,27 @@ +fn f() {} +struct X; + +fn main() { + false == false == false; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + + false == 0 < 2; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + + f(); +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + + f, Option>>(1, 2); +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + + use std::convert::identity; + let _ = identity; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/self-in-function-arg.rs b/gcc/testsuite/rust/rustc/ui/parser/self-in-function-arg.rs new file mode 100644 index 000000000000..f8e105b9e352 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/self-in-function-arg.rs @@ -0,0 +1,4 @@ +fn foo(x:i32, self: i32) -> i32 { self } // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/self-param-semantic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/self-param-semantic-fail.rs new file mode 100644 index 000000000000..dce2cba20a50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/self-param-semantic-fail.rs @@ -0,0 +1,65 @@ +// This test ensures that `self` is semantically rejected +// in contexts with `FnDecl` but outside of associated `fn`s. +// FIXME(Centril): For now closures are an exception. + +fn main() {} + +fn free() { + fn f1(self) {} +// { dg-error "" "" { target *-*-* } .-1 } + fn f2(mut self) {} +// { dg-error "" "" { target *-*-* } .-1 } + fn f3(&self) {} +// { dg-error "" "" { target *-*-* } .-1 } + fn f4(&mut self) {} +// { dg-error "" "" { target *-*-* } .-1 } + fn f5<'a>(&'a self) {} +// { dg-error "" "" { target *-*-* } .-1 } + fn f6<'a>(&'a mut self) {} +// { dg-error "" "" { target *-*-* } .-1 } + fn f7(self: u8) {} +// { dg-error "" "" { target *-*-* } .-1 } + fn f8(mut self: u8) {} +// { dg-error "" "" { target *-*-* } .-1 } +} + +extern { + fn f1(self); +// { dg-error "" "" { target *-*-* } .-1 } + fn f2(mut self); +// { dg-error ".E0130." "" { target *-*-* } .-1 } +// { dg-error ".E0130." "" { target *-*-* } .-2 } + fn f3(&self); +// { dg-error "" "" { target *-*-* } .-1 } + fn f4(&mut self); +// { dg-error "" "" { target *-*-* } .-1 } + fn f5<'a>(&'a self); +// { dg-error "" "" { target *-*-* } .-1 } + fn f6<'a>(&'a mut self); +// { dg-error "" "" { target *-*-* } .-1 } + fn f7(self: u8); +// { dg-error "" "" { target *-*-* } .-1 } + fn f8(mut self: u8); +// { dg-error ".E0130." "" { target *-*-* } .-1 } +// { dg-error ".E0130." "" { target *-*-* } .-2 } +} + +type X1 = fn(self); +// { dg-error "" "" { target *-*-* } .-1 } +type X2 = fn(mut self); +// { dg-error ".E0561." "" { target *-*-* } .-1 } +// { dg-error ".E0561." "" { target *-*-* } .-2 } +type X3 = fn(&self); +// { dg-error "" "" { target *-*-* } .-1 } +type X4 = fn(&mut self); +// { dg-error "" "" { target *-*-* } .-1 } +type X5 = for<'a> fn(&'a self); +// { dg-error "" "" { target *-*-* } .-1 } +type X6 = for<'a> fn(&'a mut self); +// { dg-error "" "" { target *-*-* } .-1 } +type X7 = fn(self: u8); +// { dg-error "" "" { target *-*-* } .-1 } +type X8 = fn(mut self: u8); +// { dg-error ".E0561." "" { target *-*-* } .-1 } +// { dg-error ".E0561." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/self-param-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/self-param-syntactic-pass.rs new file mode 100644 index 000000000000..9bfbc8430463 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/self-param-syntactic-pass.rs @@ -0,0 +1,67 @@ +// This test ensures that `self` is syntactically accepted in all places an `FnDecl` is parsed. +// FIXME(Centril): For now closures are an exception. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +fn free() { + fn f(self) {} + fn f(mut self) {} + fn f(&self) {} + fn f(&mut self) {} + fn f(&'a self) {} + fn f(&'a mut self) {} + fn f(self: u8) {} + fn f(mut self: u8) {} +} + +#[cfg(FALSE)] +extern { + fn f(self); + fn f(mut self); + fn f(&self); + fn f(&mut self); + fn f(&'a self); + fn f(&'a mut self); + fn f(self: u8); + fn f(mut self: u8); +} + +#[cfg(FALSE)] +trait X { + fn f(self) {} + fn f(mut self) {} + fn f(&self) {} + fn f(&mut self) {} + fn f(&'a self) {} + fn f(&'a mut self) {} + fn f(self: u8) {} + fn f(mut self: u8) {} +} + +#[cfg(FALSE)] +impl X for Y { + fn f(self) {} + fn f(mut self) {} + fn f(&self) {} + fn f(&mut self) {} + fn f(&'a self) {} + fn f(&'a mut self) {} + fn f(self: u8) {} + fn f(mut self: u8) {} +} + +#[cfg(FALSE)] +impl X for Y { + type X = fn(self); + type X = fn(mut self); + type X = fn(&self); + type X = fn(&mut self); + type X = fn(&'a self); + type X = fn(&'a mut self); + type X = fn(self: u8); + type X = fn(mut self: u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/several-carriage-returns-in-doc-comment.rs b/gcc/testsuite/rust/rustc/ui/parser/several-carriage-returns-in-doc-comment.rs new file mode 100644 index 000000000000..a96f27f53a7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/several-carriage-returns-in-doc-comment.rs @@ -0,0 +1,11 @@ +// Issue #62863 +// ignore-tidy-cr + +// Note: if you see ^M in this file, that's how your editor renders literal `\r` + +/// This do c comment contains three isolated `\r` symbols +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/shebang/issue-71471-ignore-tidy.rs b/gcc/testsuite/rust/rustc/ui/parser/shebang/issue-71471-ignore-tidy.rs new file mode 100644 index 000000000000..949db06b708b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/shebang/issue-71471-ignore-tidy.rs @@ -0,0 +1,3 @@ + +#!B // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/shebang/multiline-attrib.rs b/gcc/testsuite/rust/rustc/ui/parser/shebang/multiline-attrib.rs new file mode 100644 index 000000000000..22ee4b807c42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/shebang/multiline-attrib.rs @@ -0,0 +1,8 @@ +#! +[allow(unused_variables)] +// check-pass + +fn main() { + let x = 5; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/shebang/regular-attrib.rs b/gcc/testsuite/rust/rustc/ui/parser/shebang/regular-attrib.rs new file mode 100644 index 000000000000..3c2b743901a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/shebang/regular-attrib.rs @@ -0,0 +1,6 @@ +#![allow(unused_variables)] +// check-pass +fn main() { + let x = 5; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-and-attrib.rs b/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-and-attrib.rs new file mode 100644 index 000000000000..e742d9efdda4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-and-attrib.rs @@ -0,0 +1,10 @@ +#!/usr/bin/env run-cargo-script + +// check-pass +#![allow(unused_variables)] + + +fn main() { + let x = 5; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-comment.rs b/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-comment.rs new file mode 100644 index 000000000000..c452af1623f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-comment.rs @@ -0,0 +1,7 @@ +#!//bin/bash + +// check-pass +fn main() { + println!("a valid shebang (that is also a rust comment)") +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-doc-comment.rs b/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-doc-comment.rs new file mode 100644 index 000000000000..69f8c36cdf6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-doc-comment.rs @@ -0,0 +1,4 @@ +#!///bin/bash +[allow(unused_variables)] +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-empty.rs b/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-empty.rs new file mode 100644 index 000000000000..7045d35e7a58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-empty.rs @@ -0,0 +1,5 @@ +#! + +// check-pass +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-must-start-file.rs b/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-must-start-file.rs new file mode 100644 index 000000000000..0ac67c0005ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-must-start-file.rs @@ -0,0 +1,7 @@ +// something on the first line for tidy +#!/bin/bash // { dg-error "" "" { target *-*-* } } + +fn main() { + println!("ok!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-space.rs b/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-space.rs new file mode 100644 index 000000000000..c88fa115e36b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/shebang/shebang-space.rs @@ -0,0 +1,6 @@ +#! + +// check-pass +// ignore-tidy-end-whitespace +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/shebang/sneaky-attrib.rs b/gcc/testsuite/rust/rustc/ui/parser/shebang/sneaky-attrib.rs new file mode 100644 index 000000000000..771186e7c790 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/shebang/sneaky-attrib.rs @@ -0,0 +1,17 @@ +#!//bin/bash + + +// This could not possibly be a shebang & also a valid rust file, since a Rust file +// can't start with `[` +/* + [ (mixing comments to also test that we ignore both types of comments) + + */ + +[allow(unused_variables)] + +// check-pass +fn main() { + let x = 5; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/shebang/valid-shebang.rs b/gcc/testsuite/rust/rustc/ui/parser/shebang/valid-shebang.rs new file mode 100644 index 000000000000..84aad264c93b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/shebang/valid-shebang.rs @@ -0,0 +1,7 @@ +#!/usr/bin/env run-cargo-script + +// check-pass +fn main() { + println!("Hello World!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/stmt_expr_attrs_placement.rs b/gcc/testsuite/rust/rustc/ui/parser/stmt_expr_attrs_placement.rs new file mode 100644 index 000000000000..8e7c6f157d03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/stmt_expr_attrs_placement.rs @@ -0,0 +1,23 @@ +#![feature(stmt_expr_attributes)] + +// Test that various placements of the inner attribute are parsed correctly, +// or not. + +fn main() { + let a = #![allow(warnings)] (1, 2); +// { dg-error "" "" { target *-*-* } .-1 } + + let b = (#![allow(warnings)] 1, 2); + + let c = { + #![allow(warnings)] + (#![allow(warnings)] 1, 2) + }; + + let d = { + #![allow(warnings)] + let e = (#![allow(warnings)] 1, 2); + e + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/stripped-nested-outline-mod-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/stripped-nested-outline-mod-pass.rs new file mode 100644 index 000000000000..f3ea3e8c8bfe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/stripped-nested-outline-mod-pass.rs @@ -0,0 +1,14 @@ +// Expansion drives parsing, so conditional compilation will strip +// out outline modules and we will never attempt parsing them. + +// check-pass + +fn main() {} + +#[cfg(FALSE)] +mod foo { + mod bar { + mod baz; // This was an error before. + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/struct-field-numeric-shorthand.rs b/gcc/testsuite/rust/rustc/ui/parser/struct-field-numeric-shorthand.rs new file mode 100644 index 000000000000..ff3708b5d042 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/struct-field-numeric-shorthand.rs @@ -0,0 +1,10 @@ +struct Rgb(u8, u8, u8); + +fn main() { + let _ = Rgb { 0, 1, 2 }; +// { dg-error ".E0063." "" { target *-*-* } .-1 } +// { dg-error ".E0063." "" { target *-*-* } .-2 } +// { dg-error ".E0063." "" { target *-*-* } .-3 } +// { dg-error ".E0063." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-for.rs b/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-for.rs new file mode 100644 index 000000000000..1ef711776704 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-for.rs @@ -0,0 +1,18 @@ +struct Foo { + x: isize, +} + +impl Foo { + fn hi(&self) -> bool { + true + } +} + +fn main() { + for x in Foo { // { dg-error ".E0277." "" { target *-*-* } } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + }.hi() { + println!("yo"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-if.rs b/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-if.rs new file mode 100644 index 000000000000..b510f3b7420d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-if.rs @@ -0,0 +1,18 @@ +struct Foo { + x: isize, +} + +impl Foo { + fn hi(&self) -> bool { + true + } +} + +fn main() { + if Foo { // { dg-error "" "" { target *-*-* } } + x: 3 + }.hi() { + println!("yo"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-match-discriminant.rs b/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-match-discriminant.rs new file mode 100644 index 000000000000..661b3db7885d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-match-discriminant.rs @@ -0,0 +1,14 @@ +struct Foo { + x: isize, +} + +fn main() { + match Foo { // { dg-error "" "" { target *-*-* } } + x: 3 + } { + Foo { + x: x + } => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-match-guard.rs b/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-match-guard.rs new file mode 100644 index 000000000000..3e0bb7f9c76b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-match-guard.rs @@ -0,0 +1,19 @@ +// check-pass + +// Unlike `if` condition, `match` guards accept struct literals. +// This is detected in . + +#[derive(PartialEq)] +struct Foo { + x: isize, +} + +fn foo(f: Foo) { + match () { + () if f == Foo { x: 42 } => {} + _ => {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-while.rs b/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-while.rs new file mode 100644 index 000000000000..93f25c45aac6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/struct-literal-in-while.rs @@ -0,0 +1,18 @@ +struct Foo { + x: isize, +} + +impl Foo { + fn hi(&self) -> bool { + true + } +} + +fn main() { + while Foo { // { dg-error "" "" { target *-*-* } } + x: 3 + }.hi() { + println!("yo"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/struct-literal-restrictions-in-lamda.rs b/gcc/testsuite/rust/rustc/ui/parser/struct-literal-restrictions-in-lamda.rs new file mode 100644 index 000000000000..dad68af0a6bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/struct-literal-restrictions-in-lamda.rs @@ -0,0 +1,18 @@ +struct Foo { + x: isize, +} + +impl Foo { + fn hi(&self) -> bool { + true + } +} + +fn main() { + while || Foo { // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + }.hi() { + println!("yo"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/tag-variant-disr-non-nullary.rs b/gcc/testsuite/rust/rustc/ui/parser/tag-variant-disr-non-nullary.rs new file mode 100644 index 000000000000..c99afd94e74e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/tag-variant-disr-non-nullary.rs @@ -0,0 +1,13 @@ +enum Color { + Red = 0xff0000, +// { dg-error ".E0658." "" { target *-*-* } .-1 } + Green = 0x00ff00, + Blue = 0x0000ff, + Black = 0x000000, + White = 0xffffff, + Other(usize), + Other2(usize, usize), +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trailing-carriage-return-in-string.rs b/gcc/testsuite/rust/rustc/ui/parser/trailing-carriage-return-in-string.rs new file mode 100644 index 000000000000..3a588f879c45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trailing-carriage-return-in-string.rs @@ -0,0 +1,15 @@ +// Issue #11669 + +// ignore-tidy-cr + +fn main() { + // \r\n + let ok = "This is \ + a test"; + // \r only + let bad = "This is \ a test"; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trailing-plus-in-bounds.rs b/gcc/testsuite/rust/rustc/ui/parser/trailing-plus-in-bounds.rs new file mode 100644 index 000000000000..30900c501def --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trailing-plus-in-bounds.rs @@ -0,0 +1,11 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(box_syntax)] +#![allow(bare_trait_objects)] + +use std::fmt::Debug; + +fn main() { + let x: Box = box 3 as Box; // Trailing `+` is OK +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trait-bounds-not-on-impl.rs b/gcc/testsuite/rust/rustc/ui/parser/trait-bounds-not-on-impl.rs new file mode 100644 index 000000000000..aea42f6e5df4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trait-bounds-not-on-impl.rs @@ -0,0 +1,8 @@ +trait Foo {} + +struct Bar; + +impl Foo + Owned for Bar {} // { dg-error "" "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trait-item-with-defaultness-fail-semantic.rs b/gcc/testsuite/rust/rustc/ui/parser/trait-item-with-defaultness-fail-semantic.rs new file mode 100644 index 000000000000..8b96e4ef730a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trait-item-with-defaultness-fail-semantic.rs @@ -0,0 +1,13 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +fn main() {} + +trait X { + default const A: u8; // { dg-error "" "" { target *-*-* } } + default const B: u8 = 0; // { dg-error "" "" { target *-*-* } } + default type D; // { dg-error "" "" { target *-*-* } } + default type C: Ord; // { dg-error "" "" { target *-*-* } } + default fn f1(); // { dg-error "" "" { target *-*-* } } + default fn f2() {} // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trait-item-with-defaultness-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/trait-item-with-defaultness-pass.rs new file mode 100644 index 000000000000..6408ed91f671 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trait-item-with-defaultness-pass.rs @@ -0,0 +1,14 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +trait X { + default const A: u8; + default const B: u8 = 0; + default type D; + default type C: Ord; + default fn f1(); + default fn f2() {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trait-object-bad-parens.rs b/gcc/testsuite/rust/rustc/ui/parser/trait-object-bad-parens.rs new file mode 100644 index 000000000000..6907f06eaecc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trait-object-bad-parens.rs @@ -0,0 +1,17 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] +#![allow(bare_trait_objects)] + +auto trait Auto {} + +fn main() { + let _: Box<((Auto)) + Auto>; +// { dg-error ".E0178." "" { target *-*-* } .-1 } + let _: Box<(Auto + Auto) + Auto>; +// { dg-error ".E0178." "" { target *-*-* } .-1 } + let _: Box<(Auto +) + Auto>; +// { dg-error ".E0178." "" { target *-*-* } .-1 } + let _: Box<(dyn Auto) + Auto>; +// { dg-error ".E0178." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trait-object-lifetime-parens.rs b/gcc/testsuite/rust/rustc/ui/parser/trait-object-lifetime-parens.rs new file mode 100644 index 000000000000..b5265666b212 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trait-object-lifetime-parens.rs @@ -0,0 +1,14 @@ +#![allow(bare_trait_objects)] + +trait Trait {} + +fn f<'a, T: Trait + ('a)>() {} // { dg-error "" "" { target *-*-* } } + +fn check<'a>() { + let _: Box; // { dg-error "" "" { target *-*-* } } + // FIXME: It'd be great if we could add suggestion to the following case. + let _: Box<('a) + Trait>; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trait-object-polytrait-priority.rs b/gcc/testsuite/rust/rustc/ui/parser/trait-object-polytrait-priority.rs new file mode 100644 index 000000000000..e5a9f76b623b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trait-object-polytrait-priority.rs @@ -0,0 +1,11 @@ +#![allow(bare_trait_objects)] + +trait Trait<'a> {} + +fn main() { + let _: &for<'a> Trait<'a> + 'static; +// { dg-error ".E0178." "" { target *-*-* } .-1 } +// { help ".E0178." "" { target *-*-* } .-2 } +// { suggestion ".E0178." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trait-object-trait-parens.rs b/gcc/testsuite/rust/rustc/ui/parser/trait-object-trait-parens.rs new file mode 100644 index 000000000000..12b820008cb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trait-object-trait-parens.rs @@ -0,0 +1,21 @@ +trait Trait<'a> {} + +trait Obj {} + +fn f Trait<'a>)>() {} + +fn main() { + let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; +// { dg-error ".E0225." "" { target *-*-* } .-1 } +// { dg-error ".E0225." "" { target *-*-* } .-2 } +// { dg-warning ".E0225." "" { target *-*-* } .-3 } + let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Obj)>; +// { dg-error ".E0225." "" { target *-*-* } .-1 } +// { dg-error ".E0225." "" { target *-*-* } .-2 } +// { dg-warning ".E0225." "" { target *-*-* } .-3 } + let _: Box<(for<'a> Trait<'a>) + (Obj) + (?Sized)>; +// { dg-error ".E0225." "" { target *-*-* } .-1 } +// { dg-error ".E0225." "" { target *-*-* } .-2 } +// { dg-warning ".E0225." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trait-plusequal-splitting.rs b/gcc/testsuite/rust/rustc/ui/parser/trait-plusequal-splitting.rs new file mode 100644 index 000000000000..9dbdd4b31412 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trait-plusequal-splitting.rs @@ -0,0 +1,9 @@ +// Fixes issue where `+` in generics weren't parsed if they were part of a `+=`. + +// build-pass (FIXME(62277): could be check-pass?) + +struct Whitespace { t: T } +struct TokenSplit { t: T } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trait-pub-assoc-const.rs b/gcc/testsuite/rust/rustc/ui/parser/trait-pub-assoc-const.rs new file mode 100644 index 000000000000..b4644018860f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trait-pub-assoc-const.rs @@ -0,0 +1,7 @@ +trait Foo { + pub const Foo: u32; +// { dg-error ".E0449." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trait-pub-assoc-ty.rs b/gcc/testsuite/rust/rustc/ui/parser/trait-pub-assoc-ty.rs new file mode 100644 index 000000000000..ec93bbbb3f1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trait-pub-assoc-ty.rs @@ -0,0 +1,7 @@ +trait Foo { + pub type Foo; +// { dg-error ".E0449." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/trait-pub-method.rs b/gcc/testsuite/rust/rustc/ui/parser/trait-pub-method.rs new file mode 100644 index 000000000000..74d2f0967e75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/trait-pub-method.rs @@ -0,0 +1,7 @@ +trait Foo { + pub fn foo(); +// { dg-error ".E0449." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/type-parameters-in-field-exprs.rs b/gcc/testsuite/rust/rustc/ui/parser/type-parameters-in-field-exprs.rs new file mode 100644 index 000000000000..27f5fb3a7f8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/type-parameters-in-field-exprs.rs @@ -0,0 +1,18 @@ +struct Foo { + x: isize, + y: isize, +} + +fn main() { + let f = Foo { + x: 1, + y: 2, + }; + f.x::; +// { dg-error "" "" { target *-*-* } .-1 } + f.x::<>; +// { dg-error "" "" { target *-*-* } .-1 } + f.x::(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/unbalanced-doublequote.rs b/gcc/testsuite/rust/rustc/ui/parser/unbalanced-doublequote.rs new file mode 100644 index 000000000000..f03fd04494aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/unbalanced-doublequote.rs @@ -0,0 +1,7 @@ +// error-pattern: unterminated double quote string + + +fn main() { + " +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/unclosed-braces.rs b/gcc/testsuite/rust/rustc/ui/parser/unclosed-braces.rs new file mode 100644 index 000000000000..c8e57800e546 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/unclosed-braces.rs @@ -0,0 +1,23 @@ +struct S { + x: [usize; 3], +} + +fn foo() { + { + { + println!("hi"); + } + } +} + +fn main() { +// { dg-note "" "" { target *-*-* } .-1 } + { + { +// { dg-note "" "" { target *-*-* } .-1 } + foo(); + } +// { dg-note "" "" { target *-*-* } .-1 } +} +// { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/unclosed-delimiter-in-dep.rs b/gcc/testsuite/rust/rustc/ui/parser/unclosed-delimiter-in-dep.rs new file mode 100644 index 000000000000..3fdade35b078 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/unclosed-delimiter-in-dep.rs @@ -0,0 +1,7 @@ +mod unclosed_delim_mod; + +fn main() { + let _: usize = unclosed_delim_mod::new(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/unclosed_delim_mod.rs b/gcc/testsuite/rust/rustc/ui/parser/unclosed_delim_mod.rs new file mode 100644 index 000000000000..0382a6b790e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/unclosed_delim_mod.rs @@ -0,0 +1,9 @@ +fn main() {} + +pub struct Value {} +pub fn new() -> Result { + Ok(Value { + } +} +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/underscore-suffix-for-float.rs b/gcc/testsuite/rust/rustc/ui/parser/underscore-suffix-for-float.rs new file mode 100644 index 000000000000..144baade84fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/underscore-suffix-for-float.rs @@ -0,0 +1,5 @@ +fn main() { + let a = 42._; // { dg-error ".E0610." "" { target *-*-* } } +// { dg-error ".E0610." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/underscore-suffix-for-string.rs b/gcc/testsuite/rust/rustc/ui/parser/underscore-suffix-for-string.rs new file mode 100644 index 000000000000..6c4eae7e1878 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/underscore-suffix-for-string.rs @@ -0,0 +1,9 @@ +// check-pass + +fn main() { + let _ = "Foo"_; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/underscore_item_not_const.rs b/gcc/testsuite/rust/rustc/ui/parser/underscore_item_not_const.rs new file mode 100644 index 000000000000..cb588d3c52e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/underscore_item_not_const.rs @@ -0,0 +1,17 @@ +// Test that various non-const items do not syntactically permit `_` as a name. + +static _: () = (); // { dg-error "" "" { target *-*-* } } +struct _(); // { dg-error "" "" { target *-*-* } } +enum _ {} // { dg-error "" "" { target *-*-* } } +fn _() {} // { dg-error "" "" { target *-*-* } } +mod _ {} // { dg-error "" "" { target *-*-* } } +type _ = (); // { dg-error "" "" { target *-*-* } } +use _; // { dg-error "" "" { target *-*-* } } +use _ as g; // { dg-error "" "" { target *-*-* } } +trait _ {} // { dg-error "" "" { target *-*-* } } +trait _ = Copy; // { dg-error "" "" { target *-*-* } } +macro_rules! _ { () => {} } // { dg-error "" "" { target *-*-* } } +union _ { f: u8 } // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/unicode-chars.rs b/gcc/testsuite/rust/rustc/ui/parser/unicode-chars.rs new file mode 100644 index 000000000000..738d653584f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/unicode-chars.rs @@ -0,0 +1,6 @@ +fn main() { + let y = 0; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/unicode-quote-chars.rs b/gcc/testsuite/rust/rustc/ui/parser/unicode-quote-chars.rs new file mode 100644 index 000000000000..83271e013e50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/unicode-quote-chars.rs @@ -0,0 +1,11 @@ +// ignore-tidy-linelength + +fn main() { + println!(“hello world”); +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { help "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/unmatched-delimiter-at-end-of-file.rs b/gcc/testsuite/rust/rustc/ui/parser/unmatched-delimiter-at-end-of-file.rs new file mode 100644 index 000000000000..b051fd5be40e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/unmatched-delimiter-at-end-of-file.rs @@ -0,0 +1,12 @@ +struct S { + x: usize, + y: usize, +} + +fn main() { + S { x: 4, + y: 5 }; +} + +fn foo() { // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/unsafe-foreign-mod.rs b/gcc/testsuite/rust/rustc/ui/parser/unsafe-foreign-mod.rs new file mode 100644 index 000000000000..55e104219cbc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/unsafe-foreign-mod.rs @@ -0,0 +1,10 @@ +unsafe extern { +// { dg-error "" "" { target *-*-* } .-1 } +} + +unsafe extern "C" { +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/unsafe-mod.rs b/gcc/testsuite/rust/rustc/ui/parser/unsafe-mod.rs new file mode 100644 index 000000000000..042aae5bb7f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/unsafe-mod.rs @@ -0,0 +1,10 @@ +unsafe mod m { +// { dg-error "" "" { target *-*-* } .-1 } +} + +unsafe mod n; +// { dg-error ".E0583." "" { target *-*-* } .-1 } +// { dg-error ".E0583." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/unsized.rs b/gcc/testsuite/rust/rustc/ui/parser/unsized.rs new file mode 100644 index 000000000000..2984d63de16f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/unsized.rs @@ -0,0 +1,8 @@ +// Test syntax checks for `type` keyword. + +struct S1 for type; +// { dg-error "" "" { target *-*-* } .-1 } + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/unsized2.rs b/gcc/testsuite/rust/rustc/ui/parser/unsized2.rs new file mode 100644 index 000000000000..3e5360e20d0b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/unsized2.rs @@ -0,0 +1,8 @@ +// Test syntax checks for `type` keyword. + +fn f() {} + +pub fn main() { + f(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/use-as-where-use-ends-with-mod-sep.rs b/gcc/testsuite/rust/rustc/ui/parser/use-as-where-use-ends-with-mod-sep.rs new file mode 100644 index 000000000000..c5766bf9cab3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/use-as-where-use-ends-with-mod-sep.rs @@ -0,0 +1,3 @@ +use std::any:: as foo; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/use-ends-with-mod-sep.rs b/gcc/testsuite/rust/rustc/ui/parser/use-ends-with-mod-sep.rs new file mode 100644 index 000000000000..3a76188e35fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/use-ends-with-mod-sep.rs @@ -0,0 +1,2 @@ +use std::any::; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/parser/variadic-ffi-nested-syntactic-fail.rs b/gcc/testsuite/rust/rustc/ui/parser/variadic-ffi-nested-syntactic-fail.rs new file mode 100644 index 000000000000..ae1b86f647e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/variadic-ffi-nested-syntactic-fail.rs @@ -0,0 +1,10 @@ +fn f1<'a>(x: u8, y: &'a ...) {} +// { dg-error ".E0743." "" { target *-*-* } .-1 } + +fn f2<'a>(x: u8, y: Vec<&'a ...>) {} +// { dg-error ".E0743." "" { target *-*-* } .-1 } + +fn main() { + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/variadic-ffi-semantic-restrictions.rs b/gcc/testsuite/rust/rustc/ui/parser/variadic-ffi-semantic-restrictions.rs new file mode 100644 index 000000000000..cd6c8dcae3d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -0,0 +1,77 @@ +#![feature(c_variadic)] + +fn main() {} + +fn f1_1(x: isize, ...) {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn f1_2(...) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +extern "C" fn f2_1(x: isize, ...) {} +// { dg-error "" "" { target *-*-* } .-1 } + +extern "C" fn f2_2(...) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +extern "C" fn f2_3(..., x: isize) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +extern fn f3_1(x: isize, ...) {} +// { dg-error "" "" { target *-*-* } .-1 } + +extern fn f3_2(...) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +extern fn f3_3(..., x: isize) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +extern { + fn e_f1(...); +// { dg-error "" "" { target *-*-* } .-1 } + fn e_f2(..., x: isize); +// { dg-error "" "" { target *-*-* } .-1 } +} + +struct X; + +impl X { + fn i_f1(x: isize, ...) {} +// { dg-error "" "" { target *-*-* } .-1 } + fn i_f2(...) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn i_f3(..., x: isize, ...) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + fn i_f4(..., x: isize, ...) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +} + +trait T { + fn t_f1(x: isize, ...) {} +// { dg-error "" "" { target *-*-* } .-1 } + fn t_f2(x: isize, ...); +// { dg-error "" "" { target *-*-* } .-1 } + fn t_f3(...) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn t_f4(...); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn t_f5(..., x: isize) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn t_f6(..., x: isize); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/variadic-ffi-syntactic-pass.rs b/gcc/testsuite/rust/rustc/ui/parser/variadic-ffi-syntactic-pass.rs new file mode 100644 index 000000000000..ca5fadeb4da5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/variadic-ffi-syntactic-pass.rs @@ -0,0 +1,54 @@ +// check-pass + +fn main() {} + +#[cfg(FALSE)] +fn f1_1(x: isize, ...) {} + +#[cfg(FALSE)] +fn f1_2(...) {} + +#[cfg(FALSE)] +extern "C" fn f2_1(x: isize, ...) {} + +#[cfg(FALSE)] +extern "C" fn f2_2(...) {} + +#[cfg(FALSE)] +extern "C" fn f2_3(..., x: isize) {} + +#[cfg(FALSE)] +extern fn f3_1(x: isize, ...) {} + +#[cfg(FALSE)] +extern fn f3_2(...) {} + +#[cfg(FALSE)] +extern fn f3_3(..., x: isize) {} + +#[cfg(FALSE)] +extern { + fn e_f1(...); + fn e_f2(..., x: isize); +} + +struct X; + +#[cfg(FALSE)] +impl X { + fn i_f1(x: isize, ...) {} + fn i_f2(...) {} + fn i_f3(..., x: isize, ...) {} + fn i_f4(..., x: isize, ...) {} +} + +#[cfg(FALSE)] +trait T { + fn t_f1(x: isize, ...) {} + fn t_f2(x: isize, ...); + fn t_f3(...) {} + fn t_f4(...); + fn t_f5(..., x: isize) {} + fn t_f6(..., x: isize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/virtual-structs.rs b/gcc/testsuite/rust/rustc/ui/parser/virtual-structs.rs new file mode 100644 index 000000000000..f33c68834fa4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/virtual-structs.rs @@ -0,0 +1,11 @@ +// Test diagnostics for the removed struct inheritance feature. + +virtual struct SuperStruct { +// { dg-error "" "" { target *-*-* } .-1 } + f1: isize, +} + +struct Struct : SuperStruct; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/where-clauses-no-bounds-or-predicates.rs b/gcc/testsuite/rust/rustc/ui/parser/where-clauses-no-bounds-or-predicates.rs new file mode 100644 index 000000000000..143a4f5846cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/where-clauses-no-bounds-or-predicates.rs @@ -0,0 +1,16 @@ +// Empty predicate list is OK +fn equal1(_: &T, _: &T) -> bool where { + true +} + +// Empty bound list is OK +fn equal2(_: &T, _: &T) -> bool where T: { + true +} + +fn foo<'a>() where 'a {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/where_with_bound.rs b/gcc/testsuite/rust/rustc/ui/parser/where_with_bound.rs new file mode 100644 index 000000000000..4b156365f372 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/where_with_bound.rs @@ -0,0 +1,6 @@ +fn foo() where ::Item: ToString, T: Iterator { } +// { dg-error ".E0412." "" { target *-*-* } .-1 } +// { dg-error ".E0412." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/parser/wrong-escape-of-curly-braces.rs b/gcc/testsuite/rust/rustc/ui/parser/wrong-escape-of-curly-braces.rs new file mode 100644 index 000000000000..25d8795b2891 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/parser/wrong-escape-of-curly-braces.rs @@ -0,0 +1,9 @@ +fn main() { + let ok = "{{everything fine}}"; + let bad = "\{it is wrong\}"; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { help "" "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/partialeq_help.rs b/gcc/testsuite/rust/rustc/ui/partialeq_help.rs new file mode 100644 index 000000000000..d63824c45f08 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/partialeq_help.rs @@ -0,0 +1,8 @@ +fn foo(a: &T, b: T) { + a == b; // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() { + foo(&1, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/path-lookahead.rs b/gcc/testsuite/rust/rustc/ui/path-lookahead.rs new file mode 100644 index 000000000000..eac08314c048 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/path-lookahead.rs @@ -0,0 +1,18 @@ +// run-pass +// run-rustfix + +#![allow(dead_code)] +#![warn(unused_parens)] + +// Parser test for #37765 + +fn with_parens(arg: T) -> String { + return (::to_string(&arg)); // { dg-warning "" "" { target *-*-* } } +} + +fn no_parens(arg: T) -> String { + return ::to_string(&arg); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/path.rs b/gcc/testsuite/rust/rustc/ui/path.rs new file mode 100644 index 000000000000..5e60de2dde48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/path.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +mod foo { + pub fn bar(_offset: usize) { } +} + +pub fn main() { foo::bar(0); } + diff --git a/gcc/testsuite/rust/rustc/ui/pathless-extern-ok.rs b/gcc/testsuite/rust/rustc/ui/pathless-extern-ok.rs new file mode 100644 index 000000000000..40ec61d4add1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pathless-extern-ok.rs @@ -0,0 +1,10 @@ +// edition:2018 +// compile-flags:--extern alloc +// build-pass + +// Test that `--extern alloc` will load from the sysroot without error. + +fn main() { + let _: Vec = alloc::vec::Vec::new(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/paths-containing-nul.rs b/gcc/testsuite/rust/rustc/ui/paths-containing-nul.rs new file mode 100644 index 000000000000..f6c438b34d3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/paths-containing-nul.rs @@ -0,0 +1,51 @@ +// run-pass + +#![allow(deprecated)] +// ignore-cloudabi no files or I/O +// ignore-wasm32-bare no files or I/O +// ignore-emscripten no files +// ignore-sgx no files + +use std::fs; +use std::io; + +fn assert_invalid_input(on: &str, result: io::Result) { + fn inner(on: &str, result: io::Result<()>) { + match result { + Ok(()) => panic!("{} didn't return an error on a path with NUL", on), + Err(e) => assert!(e.kind() == io::ErrorKind::InvalidInput, + "{} returned a strange {:?} on a path with NUL", on, e.kind()), + } + } + inner(on, result.map(drop)) +} + +fn main() { + assert_invalid_input("File::open", fs::File::open("\0")); + assert_invalid_input("File::create", fs::File::create("\0")); + assert_invalid_input("remove_file", fs::remove_file("\0")); + assert_invalid_input("metadata", fs::metadata("\0")); + assert_invalid_input("symlink_metadata", fs::symlink_metadata("\0")); + + // If `dummy_file` does not exist, then we might get another unrelated error + let dummy_file = std::env::current_exe().unwrap(); + + assert_invalid_input("rename1", fs::rename("\0", "a")); + assert_invalid_input("rename2", fs::rename(&dummy_file, "\0")); + assert_invalid_input("copy1", fs::copy("\0", "a")); + assert_invalid_input("copy2", fs::copy(&dummy_file, "\0")); + assert_invalid_input("hard_link1", fs::hard_link("\0", "a")); + assert_invalid_input("hard_link2", fs::hard_link(&dummy_file, "\0")); + assert_invalid_input("soft_link1", fs::soft_link("\0", "a")); + assert_invalid_input("soft_link2", fs::soft_link(&dummy_file, "\0")); + assert_invalid_input("read_link", fs::read_link("\0")); + assert_invalid_input("canonicalize", fs::canonicalize("\0")); + assert_invalid_input("create_dir", fs::create_dir("\0")); + assert_invalid_input("create_dir_all", fs::create_dir_all("\0")); + assert_invalid_input("remove_dir", fs::remove_dir("\0")); + assert_invalid_input("remove_dir_all", fs::remove_dir_all("\0")); + assert_invalid_input("read_dir", fs::read_dir("\0")); + assert_invalid_input("set_permissions", + fs::set_permissions("\0", fs::metadata(".").unwrap().permissions())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/bind-by-copy.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/bind-by-copy.rs new file mode 100644 index 000000000000..0d12bd9ea261 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/bind-by-copy.rs @@ -0,0 +1,50 @@ +// run-pass + +// Test copy + +#![feature(bindings_after_at)] + +struct A { a: i32, b: i32 } +struct B { a: i32, b: C } +struct D { a: i32, d: C } +#[derive(Copy,Clone)] +struct C { c: i32 } + +pub fn main() { + match (A {a: 10, b: 20}) { + x@A {a, b: 20} => { assert!(x.a == 10); assert!(a == 10); } + A {b: _b, ..} => { panic!(); } + } + + let mut x@B {b, ..} = B {a: 10, b: C {c: 20}}; + assert_eq!(x.a, 10); + x.b.c = 30; + assert_eq!(b.c, 20); + let mut y@D {d, ..} = D {a: 10, d: C {c: 20}}; + assert_eq!(y.a, 10); + y.d.c = 30; + assert_eq!(d.c, 20); + + let some_b = Some(B { a: 10, b: C { c: 20 } }); + + // in irrefutable pattern + if let Some(x @ B { b, .. }) = some_b { + assert_eq!(x.b.c, 20); + assert_eq!(b.c, 20); + } else { + unreachable!(); + } + + let some_b = Some(B { a: 10, b: C { c: 20 } }); + + if let Some(x @ B { b: mut b @ C { c }, .. }) = some_b { + assert_eq!(x.b.c, 20); + assert_eq!(b.c, 20); + b.c = 30; + assert_eq!(b.c, 30); + assert_eq!(c, 20); + } else { + unreachable!(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs new file mode 100644 index 000000000000..27af455e1d18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.rs @@ -0,0 +1,40 @@ +// This test is taken directly from #16053. +// It checks that you cannot use an AND-pattern (`binding @ pat`) +// where one side is by-ref and the other is by-move. + +#![feature(bindings_after_at)] + +struct X { + x: (), +} + +fn main() { + let x = Some(X { x: () }); + match x { + Some(ref _y @ _z) => {} // { dg-error ".E0382." "" { target *-*-* } } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + None => panic!(), + } + + let x = Some(X { x: () }); + match x { + Some(_z @ ref _y) => {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } + None => panic!(), + } + + let mut x = Some(X { x: () }); + match x { + Some(ref mut _y @ _z) => {} // { dg-error ".E0382." "" { target *-*-* } } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + None => panic!(), + } + + let mut x = Some(X { x: () }); + match x { + Some(_z @ ref mut _y) => {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } + None => panic!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs new file mode 100644 index 000000000000..df698d440d6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/bind-by-move-no-subbindings-fun-param.rs @@ -0,0 +1,14 @@ +// See issue #12534. + +#![feature(bindings_after_at)] + +fn main() {} + +struct A(Box); + +fn f(a @ A(u): A) -> Box { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + drop(a); + u +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-move-and-move.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-move-and-move.rs new file mode 100644 index 000000000000..191935cf520a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-move-and-move.rs @@ -0,0 +1,34 @@ +// Test that moving on both sides of an `@` pattern is not allowed. + +#![feature(bindings_after_at)] + +fn main() { + struct U; // Not copy! + + // Prevent promotion: + fn u() -> U { + U + } + + let a @ b = U; // { dg-error ".E0382." "" { target *-*-* } } + + let a @ (b, c) = (U, U); // { dg-error ".E0382." "" { target *-*-* } } + + let a @ (b, c) = (u(), u()); // { dg-error ".E0382." "" { target *-*-* } } + + match Ok(U) { + a @ Ok(b) | a @ Err(b) => {} // { dg-error ".E0382." "" { target *-*-* } } +// { dg-error ".E0382." "" { target *-*-* } .-1 } + } + + fn fun(a @ b: U) {} // { dg-error ".E0382." "" { target *-*-* } } + + match [u(), u(), u(), u()] { + xs @ [a, .., b] => {} // { dg-error ".E0382." "" { target *-*-* } } + } + + match [u(), u(), u(), u()] { + xs @ [_, ys @ .., _] => {} // { dg-error ".E0382." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs new file mode 100644 index 000000000000..033114b82963 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs @@ -0,0 +1,86 @@ +// check-pass + +// Test `@` patterns combined with `box` patterns. + +#![feature(bindings_after_at)] +#![feature(box_patterns)] + +#[derive(Copy, Clone)] +struct C; + +fn c() -> C { C } + +struct NC; + +fn nc() -> NC { NC } + +fn main() { + let ref a @ box b = Box::new(C); // OK; the type is `Copy`. + drop(b); + drop(b); + drop(a); + + let ref a @ box b = Box::new(c()); // OK; the type is `Copy`. + drop(b); + drop(b); + drop(a); + + fn f3(ref a @ box b: Box) { // OK; the type is `Copy`. + drop(b); + drop(b); + drop(a); + } + match Box::new(c()) { + ref a @ box b => { // OK; the type is `Copy`. + drop(b); + drop(b); + drop(a); + } + } + + let ref a @ box ref b = Box::new(NC); // OK. + drop(a); + drop(b); + + fn f4(ref a @ box ref b: Box) { // OK. + drop(a); + drop(b) + } + + match Box::new(nc()) { + ref a @ box ref b => { // OK. + drop(a); + drop(b); + } + } + + match Box::new([Ok(c()), Err(nc()), Ok(c())]) { + box [Ok(a), ref xs @ .., Err(ref b)] => { + let _: C = a; + let _: &[Result; 1] = xs; + let _: &NC = b; + } + _ => {} + } + + match [Ok(Box::new(c())), Err(Box::new(nc())), Ok(Box::new(c())), Ok(Box::new(c()))] { + [Ok(box a), ref xs @ .., Err(box ref b), Err(box ref c)] => { + let _: C = a; + let _: &[Result, Box>; 1] = xs; + let _: &NC = b; + let _: &NC = c; + } + _ => {} + } + + match Box::new([Ok(c()), Err(nc()), Ok(c())]) { + box [Ok(a), ref xs @ .., Err(b)] => {} + _ => {} + } + + match [Ok(Box::new(c())), Err(Box::new(nc())), Ok(Box::new(c())), Ok(Box::new(c()))] { + [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs new file mode 100644 index 000000000000..18197c4d9060 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs @@ -0,0 +1,71 @@ +// Test `@` patterns combined with `box` patterns. + +#![feature(bindings_after_at)] +#![feature(box_patterns)] + +#[derive(Copy, Clone)] +struct C; + +fn c() -> C { + C +} + +struct NC; + +fn nc() -> NC { + NC +} + +fn main() { + let a @ box &b = Box::new(&C); + + let a @ box b = Box::new(C); + + fn f1(a @ box &b: Box<&C>) {} + + fn f2(a @ box b: Box) {} + + match Box::new(C) { + a @ box b => {} + } + + let ref a @ box b = Box::new(NC); // { dg-error ".E0382." "" { target *-*-* } } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + + let ref a @ box ref mut b = Box::new(nc()); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + let ref a @ box ref mut b = Box::new(NC); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + let ref a @ box ref mut b = Box::new(NC); +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + *b = NC; + let ref a @ box ref mut b = Box::new(NC); +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + *b = NC; + drop(a); + + let ref mut a @ box ref b = Box::new(NC); +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + *a = Box::new(NC); + drop(b); + + fn f5(ref mut a @ box ref b: Box) { +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + *a = Box::new(NC); + drop(b); + } + + match Box::new(nc()) { + ref mut a @ box ref b => { +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + *a = Box::new(NC); + drop(b); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs new file mode 100644 index 000000000000..96bb31bf266f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs @@ -0,0 +1,52 @@ +// check-pass + +// Test `Copy` bindings in the rhs of `@` patterns. + +#![feature(bindings_after_at)] + +#[derive(Copy, Clone)] +struct C; + +fn mk_c() -> C { C } + +#[derive(Copy, Clone)] +struct P(A, B); + +enum E { L(A), R(B) } + +fn main() { + let a @ b @ c @ d = C; + let a @ (b, c) = (C, mk_c()); + let a @ P(b, P(c, d)) = P(mk_c(), P(C, C)); + let a @ [b, c] = [C, C]; + let a @ [b, .., c] = [C, mk_c(), C]; + let a @ [b, mid @ .., c] = [C, mk_c(), C]; + let a @ &(b, c) = &(C, C); + let a @ &(b, &P(c, d)) = &(mk_c(), &P(C, C)); + + fn foo(a @ [b, mid @ .., c]: [C; 3]) {} + + use self::E::*; + match L(C) { + L(a) | R(a) => { + let a: C = a; + drop(a); + drop(a); + } + } + match R(&L(&mk_c())) { + L(L(&a)) | L(R(&a)) | R(L(&a)) | R(R(&a)) => { + let a: C = a; + drop(a); + drop(a); + } + } + + match Ok(mk_c()) { + Ok(ref a @ b) | Err(b @ ref a) => { + let _: &C = a; + let _: C = b; + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs new file mode 100644 index 000000000000..4294aabb7553 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.rs @@ -0,0 +1,10 @@ +// Test that `by_move_binding @ pat_with_by_ref_bindings` is prevented even with promotion. +// Currently this logic exists in THIR match checking as opposed to borrowck. + +#![feature(bindings_after_at)] + +fn main() { + struct U; + let a @ ref b = U; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs new file mode 100644 index 000000000000..4e126b783a0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs @@ -0,0 +1,83 @@ +// Test that `by_move_binding @ pat_with_by_ref_bindings` is prevented. + +#![feature(bindings_after_at)] + +fn main() { + struct U; + + // Prevent promotion. + fn u() -> U { + U + } + + fn f1(a @ ref b: U) {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } + + fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } +// { dg-error ".E0382." "" { target *-*-* } .-3 } +// { dg-error ".E0382." "" { target *-*-* } .-4 } + fn f3(a @ [ref mut b, ref c]: [U; 2]) {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } + + let a @ ref b = U; +// { dg-error ".E0382." "" { target *-*-* } .-1 } + let a @ (mut b @ ref mut c, d @ ref e) = (U, U); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } +// { dg-error ".E0382." "" { target *-*-* } .-3 } +// { dg-error ".E0382." "" { target *-*-* } .-4 } + let a @ [ref mut b, ref c] = [U, U]; +// { dg-error ".E0382." "" { target *-*-* } .-1 } + let a @ ref b = u(); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + let a @ (mut b @ ref mut c, d @ ref e) = (u(), u()); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } +// { dg-error ".E0382." "" { target *-*-* } .-3 } +// { dg-error ".E0382." "" { target *-*-* } .-4 } + let a @ [ref mut b, ref c] = [u(), u()]; +// { dg-error ".E0382." "" { target *-*-* } .-1 } + + match Some(U) { + a @ Some(ref b) => {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } + None => {} + } + match Some((U, U)) { + a @ Some((mut b @ ref mut c, d @ ref e)) => {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } +// { dg-error ".E0382." "" { target *-*-* } .-3 } +// { dg-error ".E0382." "" { target *-*-* } .-4 } + None => {} + } + match Some([U, U]) { + mut a @ Some([ref b, ref mut c]) => {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + None => {} + } + match Some(u()) { + a @ Some(ref b) => {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + None => {} + } + match Some((u(), u())) { + a @ Some((mut b @ ref mut c, d @ ref e)) => {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } +// { dg-error ".E0382." "" { target *-*-* } .-3 } +// { dg-error ".E0382." "" { target *-*-* } .-4 } + None => {} + } + match Some([u(), u()]) { + mut a @ Some([ref b, ref mut c]) => {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + None => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs new file mode 100644 index 000000000000..cd35d3ea54c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs @@ -0,0 +1,85 @@ +// Test that `ref mut? @ pat_with_by_move_bindings` is prevented. + +#![feature(bindings_after_at)] + +fn main() { + struct U; + + // Prevent promotion. + fn u() -> U { + U + } + + fn f1(ref a @ b: U) {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } +// { dg-error ".E0382." "" { target *-*-* } .-3 } +// { dg-error ".E0382." "" { target *-*-* } .-4 } +// { dg-error ".E0382." "" { target *-*-* } .-5 } + fn f3(ref mut a @ [b, mut c]: [U; 2]) {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + + let ref a @ b = U; +// { dg-error "" "" { target *-*-* } .-1 } + let ref a @ (ref b @ mut c, ref d @ e) = (U, U); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + let ref mut a @ [b, mut c] = [U, U]; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + let ref a @ b = u(); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + let ref a @ (ref b @ mut c, ref d @ e) = (u(), u()); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } +// { dg-error ".E0382." "" { target *-*-* } .-3 } +// { dg-error ".E0382." "" { target *-*-* } .-4 } +// { dg-error ".E0382." "" { target *-*-* } .-5 } + let ref mut a @ [b, mut c] = [u(), u()]; +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + + match Some(U) { + ref a @ Some(b) => {} +// { dg-error "" "" { target *-*-* } .-1 } + None => {} + } + match Some((U, U)) { + ref a @ Some((ref b @ mut c, ref d @ e)) => {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + None => {} + } + match Some([U, U]) { + ref mut a @ Some([b, mut c]) => {} +// { dg-error "" "" { target *-*-* } .-1 } + None => {} + } + match Some(u()) { + ref a @ Some(b) => {} +// { dg-error "" "" { target *-*-* } .-1 } + None => {} + } + match Some((u(), u())) { + ref a @ Some((ref b @ mut c, ref d @ e)) => {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } +// { dg-error ".E0382." "" { target *-*-* } .-3 } +// { dg-error ".E0382." "" { target *-*-* } .-4 } +// { dg-error ".E0382." "" { target *-*-* } .-5 } + None => {} + } + match Some([u(), u()]) { + ref mut a @ Some([b, mut c]) => {} +// { dg-error "" "" { target *-*-* } .-1 } + None => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs new file mode 100644 index 000000000000..846e82f9ff98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs @@ -0,0 +1,48 @@ +// check-pass + +// Test that `ref` patterns may be used on both sides +// of an `@` pattern according to NLL borrowck. + +#![feature(bindings_after_at)] + +fn main() { + struct U; // Not copy! + + // Promotion: + let ref a @ ref b = U; + let _: &U = a; + let _: &U = b; + + // Prevent promotion: + fn u() -> U { U } + + let ref a @ ref b = u(); + let _: &U = a; + let _: &U = b; + + let ref a @ (ref b, [ref c, ref d]) = (u(), [u(), u()]); + let _: &(U, [U; 2]) = a; + let _: &U = b; + let _: &U = c; + let _: &U = d; + + fn f1(ref a @ (ref b, [ref c, ref mid @ .., ref d]): (U, [U; 4])) {} + + let a @ (b, [c, d]) = &(u(), [u(), u()]); + let _: &(U, [U; 2]) = a; + let _: &U = b; + let _: &U = c; + let _: &U = d; + + let ref a @ &ref b = &u(); + let _: &&U = a; + let _: &U = b; + + match Ok(u()) { + ref a @ Ok(ref b) | ref a @ Err(ref b) => { + let _: &Result = a; + let _: &U = b; + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs new file mode 100644 index 000000000000..221727a1a978 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs @@ -0,0 +1,139 @@ +#![feature(bindings_after_at)] + +enum Option { + None, + Some(T), +} + +fn main() { + match &mut Some(1) { + ref mut z @ &mut Some(ref a) => { +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + **z = None; + println!("{}", *a); + } + _ => () + } + + struct U; + + // Prevent promotion: + fn u() -> U { U } + + fn f1(ref a @ ref mut b: U) {} +// { dg-error ".E0502." "" { target *-*-* } .-1 } + fn f2(ref mut a @ ref b: U) {} +// { dg-error ".E0502." "" { target *-*-* } .-1 } + fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} +// { dg-error ".E0502." "" { target *-*-* } .-1 } + fn f4_also_moved(ref a @ ref mut b @ c: U) {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } +// { dg-error ".E0382." "" { target *-*-* } .-3 } + + let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + + let ref a @ ref mut b = U; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + let ref mut a @ ref b = U; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + let ref a @ (ref mut b, ref mut c) = (U, U); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + let ref mut a @ (ref b, ref c) = (U, U); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + + let ref mut a @ ref b = u(); +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + *a = u(); + drop(b); + let ref a @ ref mut b = u(); +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + *b = u(); + drop(a); + + let ref mut a @ ref b = U; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + *a = U; + drop(b); + let ref a @ ref mut b = U; +// { dg-error ".E0502." "" { target *-*-* } .-1 } + *b = U; + drop(a); + + match Ok(U) { + ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + *a = Err(U); + drop(b); + } + } + + match Ok(U) { + ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } +// { dg-error ".E0502." "" { target *-*-* } .-3 } +// { dg-error ".E0502." "" { target *-*-* } .-4 } + *b = U; + drop(a); + } + } + + match Ok(U) { + ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} +// { dg-error ".E0594." "" { target *-*-* } .-1 } +// { dg-error ".E0594." "" { target *-*-* } .-2 } +// { dg-error ".E0594." "" { target *-*-* } .-3 } + _ => {} + } + match Ok(U) { + ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } +// { dg-error ".E0594." "" { target *-*-* } .-3 } + _ => {} + } + match Ok(U) { + ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { dg-error ".E0507." "" { target *-*-* } .-2 } +// { dg-error ".E0507." "" { target *-*-* } .-3 } +// { dg-error ".E0507." "" { target *-*-* } .-4 } + _ => {} + } + match Ok(U) { + ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } +// { dg-error ".E0507." "" { target *-*-* } .-3 } +// { dg-error ".E0507." "" { target *-*-* } .-4 } + _ => {} + } + + let ref a @ (ref mut b, ref mut c) = (U, U); +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + *b = U; + *c = U; + + let ref a @ (ref mut b, ref mut c) = (U, U); +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + *b = U; + drop(a); + + let ref a @ (ref mut b, ref mut c) = (U, U); +// { dg-error ".E0502." "" { target *-*-* } .-1 } +// { dg-error ".E0502." "" { target *-*-* } .-2 } + *c = U; + drop(a); + let ref mut a @ (ref b, ref c) = (U, U); +// { dg-error ".E0502." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs new file mode 100644 index 000000000000..3280fb09c0d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs @@ -0,0 +1,112 @@ +// Test that `ref mut x @ ref mut y` and varieties of that are not allowed. + +#![feature(bindings_after_at)] + +fn main() { + struct U; + + fn u() -> U { U } + + fn f1(ref mut a @ ref mut b: U) {} +// { dg-error ".E0499." "" { target *-*-* } .-1 } + fn f2(ref mut a @ ref mut b: U) {} +// { dg-error ".E0499." "" { target *-*-* } .-1 } + fn f3( + ref mut a @ [ +// { dg-error ".E0499." "" { target *-*-* } .-1 } + [ref b @ .., _], + [_, ref mut mid @ ..], + .., + [..], + ] : [[U; 4]; 5] + ) {} + fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } +// { dg-error ".E0382." "" { target *-*-* } .-3 } + + let ref mut a @ ref mut b = U; +// { dg-error ".E0499." "" { target *-*-* } .-1 } + drop(a); + let ref mut a @ ref mut b = U; +// { dg-error ".E0499." "" { target *-*-* } .-1 } +// { dg-error ".E0499." "" { target *-*-* } .-2 } + drop(b); + let ref mut a @ ref mut b = U; +// { dg-error ".E0499." "" { target *-*-* } .-1 } + + let ref mut a @ ref mut b = U; +// { dg-error ".E0499." "" { target *-*-* } .-1 } + *a = U; + let ref mut a @ ref mut b = U; +// { dg-error ".E0499." "" { target *-*-* } .-1 } +// { dg-error ".E0499." "" { target *-*-* } .-2 } + *b = U; + + let ref mut a @ ( +// { dg-error ".E0499." "" { target *-*-* } .-1 } + ref mut b, + [ + ref mut c, + ref mut d, + ref e, + ] + ) = (U, [U, U, U]); + + let ref mut a @ ( +// { dg-error ".E0499." "" { target *-*-* } .-1 } + ref mut b, + [ + ref mut c, + ref mut d, + ref e, + ] + ) = (u(), [u(), u(), u()]); + + let a @ (ref mut b, ref mut c) = (U, U); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + let mut val = (U, [U, U]); + let a @ (b, [c, d]) = &mut val; // Same as ^-- +// { dg-error ".E0382." "" { target *-*-* } .-1 } + + let a @ &mut ref mut b = &mut U; +// { dg-error ".E0382." "" { target *-*-* } .-1 } + let a @ &mut (ref mut b, ref mut c) = &mut (U, U); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + + match Ok(U) { + ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { +// { dg-error ".E0499." "" { target *-*-* } .-1 } +// { dg-error ".E0499." "" { target *-*-* } .-2 } + } + } + match Ok(U) { + ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { +// { dg-error ".E0499." "" { target *-*-* } .-1 } +// { dg-error ".E0499." "" { target *-*-* } .-2 } + *b = U; + } + } + match Ok(U) { + ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { +// { dg-error ".E0499." "" { target *-*-* } .-1 } +// { dg-error ".E0499." "" { target *-*-* } .-2 } +// { dg-error ".E0499." "" { target *-*-* } .-3 } +// { dg-error ".E0499." "" { target *-*-* } .-4 } + *a = Err(U); + + // FIXME: The binding name value used above makes for problematic diagnostics. + // Resolve that somehow... + } + } + match Ok(U) { + ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { +// { dg-error ".E0499." "" { target *-*-* } .-1 } +// { dg-error ".E0499." "" { target *-*-* } .-2 } +// { dg-error ".E0499." "" { target *-*-* } .-3 } +// { dg-error ".E0499." "" { target *-*-* } .-4 } + drop(a); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/box-patterns.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/box-patterns.rs new file mode 100644 index 000000000000..39bcb365b215 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/box-patterns.rs @@ -0,0 +1,37 @@ +// Test bindings-after-at with box-patterns + +// run-pass + +#![feature(bindings_after_at)] +#![feature(box_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +fn test(x: Option>) -> MatchArm { + match x { + ref bar @ Some(box n) if n > 0 => { + // bar is a &Option> + assert_eq!(bar, &x); + + MatchArm::Arm(0) + }, + Some(ref bar @ box n) if n < 0 => { + // bar is a &Box here + assert_eq!(**bar, n); + + MatchArm::Arm(1) + }, + _ => MatchArm::Wild, + } +} + +fn main() { + assert_eq!(test(Some(Box::new(2))), MatchArm::Arm(0)); + assert_eq!(test(Some(Box::new(-1))), MatchArm::Arm(1)); + assert_eq!(test(Some(Box::new(0))), MatchArm::Wild); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/copy-and-move-mixed.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/copy-and-move-mixed.rs new file mode 100644 index 000000000000..026c4042219d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/copy-and-move-mixed.rs @@ -0,0 +1,17 @@ +// Test that mixing `Copy` and non-`Copy` types in `@` patterns is forbidden. + +#![feature(bindings_after_at)] + +#[derive(Copy, Clone)] +struct C; + +struct NC(A, B); + +fn main() { + // this compiles + let a @ NC(b, c) = NC(C, C); + + let a @ NC(b, c @ NC(d, e)) = NC(C, NC(C, C)); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs new file mode 100644 index 000000000000..14e2f7551b0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.rs @@ -0,0 +1,50 @@ +// Ensures the independence of each side in `binding @ subpat` +// determine their binding modes independently of each other. +// +// That is, `binding` does not influence `subpat`. +// This is important because we might want to allow `p1 @ p2`, +// where both `p1` and `p2` are syntactically unrestricted patterns. +// If `binding` is allowed to influence `subpat`, +// this would create problems for the generalization aforementioned. + +#![feature(bindings_after_at)] + +fn main() { + struct NotCopy; + + fn f1(a @ b: &NotCopy) { // OK + let _: &NotCopy = a; + } + fn f2(ref a @ b: &NotCopy) { + let _: &&NotCopy = a; // Ok + } + + let a @ b = &NotCopy; // OK + let _: &NotCopy = a; + let ref a @ b = &NotCopy; // OK + let _: &&NotCopy = a; + + let ref a @ b = NotCopy; // { dg-error "" "" { target *-*-* } } + let _a: &NotCopy = a; + let _b: NotCopy = b; + let ref mut a @ b = NotCopy; // { dg-error ".E0382." "" { target *-*-* } } +// { dg-error ".E0382." "" { target *-*-* } .-1 } + let _a: &NotCopy = a; + let _b: NotCopy = b; + match Ok(NotCopy) { + Ok(ref a @ b) | Err(b @ ref a) => { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + let _a: &NotCopy = a; + let _b: NotCopy = b; + } + } + match NotCopy { + ref a @ b => { +// { dg-error "" "" { target *-*-* } .-1 } + let _a: &NotCopy = a; + let _b: NotCopy = b; + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.rs new file mode 100644 index 000000000000..725aeb5b0106 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/feature-gate-bindings_after_at.rs @@ -0,0 +1,4 @@ +fn main() { + let x @ y = 0; // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-binding-mode-lint.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-binding-mode-lint.rs new file mode 100644 index 000000000000..d909b40120d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-binding-mode-lint.rs @@ -0,0 +1,14 @@ +// check-pass + +#![feature(bindings_after_at)] +#![deny(unused_mut)] + +fn main() { + let mut is_mut @ not_mut = 42; + &mut is_mut; + ¬_mut; + let not_mut @ mut is_mut = 42; + &mut is_mut; + ¬_mut; +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-binding-modes-mut.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-binding-modes-mut.rs new file mode 100644 index 000000000000..94118db4ed6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-binding-modes-mut.rs @@ -0,0 +1,14 @@ +#![feature(bindings_after_at)] + +fn main() { + let mut is_mut @ not_mut = 42; + &mut is_mut; + &mut not_mut; +// { dg-error ".E0596." "" { target *-*-* } .-1 } + + let not_mut @ mut is_mut = 42; + &mut is_mut; + &mut not_mut; +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-binding-modes-ref.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-binding-modes-ref.rs new file mode 100644 index 000000000000..29a6abe95c10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-binding-modes-ref.rs @@ -0,0 +1,14 @@ +#![feature(bindings_after_at)] + +fn main() { + let ref is_ref @ is_val = 42; + *is_ref; + *is_val; +// { dg-error ".E0614." "" { target *-*-* } .-1 } + + let is_val @ ref is_ref = 42; + *is_ref; + *is_val; +// { dg-error ".E0614." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-patterns.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-patterns.rs new file mode 100644 index 000000000000..0cf60f6dc4d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-patterns.rs @@ -0,0 +1,16 @@ +// run-pass + +#![feature(bindings_after_at)] + +struct A { a: u8, b: u8 } + +pub fn main() { + match (A { a: 10, b: 20 }) { + ref x @ A { ref a, b: 20 } => { + assert_eq!(x.a, 10); + assert_eq!(*a, 10); + } + A { b: ref _b, .. } => panic!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs new file mode 100644 index 000000000000..77e67d5dab4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/nested-type-ascription-syntactically-invalid.rs @@ -0,0 +1,35 @@ +// Here we check that type ascription is syntactically invalid when +// not in the top position of a ascribing a let binding or function parameter. + +#![feature(bindings_after_at)] + +// This has no effect. +// We include it to demonstrate that this is the case: +#![feature(type_ascription)] + +fn main() {} + +fn _ok() { + let _a @ _b: u8 = 0; // OK. + fn _f(_a @ _b: u8) {} // OK. +} + +#[cfg(FALSE)] +fn case_1() { + let a: u8 @ b = 0; +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[cfg(FALSE)] +fn case_2() { + let a @ (b: u8); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +#[cfg(FALSE)] +fn case_3() { + let a: T1 @ Outer(b: T2); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/or-patterns-box-patterns.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/or-patterns-box-patterns.rs new file mode 100644 index 000000000000..a6bb2f433eba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/or-patterns-box-patterns.rs @@ -0,0 +1,46 @@ +// Test bindings-after-at with or-patterns and box-patterns + +// run-pass + +#![feature(bindings_after_at)] +#![feature(or_patterns)] +#![feature(box_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +#[derive(Debug, PartialEq)] +enum Test { + Foo, + Bar, + Baz, + Qux, +} + +fn test(foo: Option>) -> MatchArm { + match foo { + ref bar @ Some(box Test::Foo | box Test::Bar) => { + assert_eq!(bar, &foo); + + MatchArm::Arm(0) + }, + Some(ref bar @ box Test::Baz | ref bar @ box Test::Qux) => { + assert!(**bar == Test::Baz || **bar == Test::Qux); + + MatchArm::Arm(1) + }, + _ => MatchArm::Wild, + } +} + +fn main() { + assert_eq!(test(Some(Box::new(Test::Foo))), MatchArm::Arm(0)); + assert_eq!(test(Some(Box::new(Test::Bar))), MatchArm::Arm(0)); + assert_eq!(test(Some(Box::new(Test::Baz))), MatchArm::Arm(1)); + assert_eq!(test(Some(Box::new(Test::Qux))), MatchArm::Arm(1)); + assert_eq!(test(None), MatchArm::Wild); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs new file mode 100644 index 000000000000..42cac1b8ab6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/or-patterns-slice-patterns.rs @@ -0,0 +1,57 @@ +// Test bindings-after-at with or-patterns and slice-patterns + +// run-pass + +#![feature(bindings_after_at)] +#![feature(or_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +#[derive(Debug, PartialEq)] +enum Test { + Foo, + Bar, + Baz, + Qux, +} + +fn test(foo: &[Option]) -> MatchArm { + match foo { + bar @ [Some(Test::Foo), .., Some(Test::Qux | Test::Foo)] => { + assert_eq!(bar, foo); + + MatchArm::Arm(0) + }, + [.., bar @ Some(Test::Bar | Test::Qux), _] => { + assert!(bar == &Some(Test::Bar) || bar == &Some(Test::Qux)); + + MatchArm::Arm(1) + }, + _ => MatchArm::Wild, + } +} + +fn main() { + let foo = vec![ + Some(Test::Foo), + Some(Test::Bar), + Some(Test::Baz), + Some(Test::Qux), + ]; + + // path 1a + assert_eq!(test(&foo), MatchArm::Arm(0)); + // path 1b + assert_eq!(test(&[Some(Test::Foo), Some(Test::Bar), Some(Test::Foo)]), MatchArm::Arm(0)); + // path 2a + assert_eq!(test(&foo[..3]), MatchArm::Arm(1)); + // path 2b + assert_eq!(test(&[Some(Test::Bar), Some(Test::Qux), Some(Test::Baz)]), MatchArm::Arm(1)); + // path 3 + assert_eq!(test(&foo[1..2]), MatchArm::Wild); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/or-patterns.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/or-patterns.rs new file mode 100644 index 000000000000..078dccfaf011 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/or-patterns.rs @@ -0,0 +1,41 @@ +// Test bindings-after-at with or-patterns + +// run-pass + +#![feature(bindings_after_at)] +#![feature(or_patterns)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +#[derive(Debug, Clone, Copy, PartialEq)] +enum Test { + Foo, + Bar, + Baz, + Qux, +} + +fn test(foo: Option) -> MatchArm { + match foo { + bar @ Some(Test::Foo | Test::Bar) => { + assert!(bar == Some(Test::Foo) || bar == Some(Test::Bar)); + + MatchArm::Arm(0) + }, + Some(_) => MatchArm::Arm(1), + _ => MatchArm::Wild, + } +} + +fn main() { + assert_eq!(test(Some(Test::Foo)), MatchArm::Arm(0)); + assert_eq!(test(Some(Test::Bar)), MatchArm::Arm(0)); + assert_eq!(test(Some(Test::Baz)), MatchArm::Arm(1)); + assert_eq!(test(Some(Test::Qux)), MatchArm::Arm(1)); + assert_eq!(test(None), MatchArm::Wild); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/pat-at-same-name-both.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/pat-at-same-name-both.rs new file mode 100644 index 000000000000..3df506564116 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/pat-at-same-name-both.rs @@ -0,0 +1,32 @@ +// Test that `binding @ subpat` acts as a product context with respect to duplicate binding names. +// The code that is tested here lives in resolve (see `resolve_pattern_inner`). + +#![feature(bindings_after_at)] +#![feature(or_patterns)] + +fn main() { + fn f(a @ a @ a: ()) {} +// { dg-error ".E0415." "" { target *-*-* } .-1 } +// { dg-error ".E0415." "" { target *-*-* } .-2 } + + match Ok(0) { + Ok(a @ b @ a) +// { dg-error ".E0416." "" { target *-*-* } .-1 } + | Err(a @ b @ a) +// { dg-error ".E0416." "" { target *-*-* } .-1 } + => {} + } + + let a @ a @ a = (); +// { dg-error ".E0416." "" { target *-*-* } .-1 } +// { dg-error ".E0416." "" { target *-*-* } .-2 } + let ref a @ ref a = (); +// { dg-error ".E0416." "" { target *-*-* } .-1 } + let ref mut a @ ref mut a = (); +// { dg-error ".E0416." "" { target *-*-* } .-1 } + + let a @ (Ok(a) | Err(a)) = Ok(()); +// { dg-error ".E0416." "" { target *-*-* } .-1 } +// { dg-error ".E0416." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/slice-patterns.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/slice-patterns.rs new file mode 100644 index 000000000000..3f77bb93d8a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/slice-patterns.rs @@ -0,0 +1,41 @@ +// Test bindings-after-at with slice-patterns + +// run-pass + +#![feature(bindings_after_at)] + +#[derive(Debug, PartialEq)] +enum MatchArm { + Arm(usize), + Wild, +} + +fn test(foo: &[i32]) -> MatchArm { + match foo { + [bar @ .., n] if n == &5 => { + for i in bar { + assert!(i < &5); + } + + MatchArm::Arm(0) + }, + bar @ [x0, .., xn] => { + assert_eq!(x0, &1); + assert_eq!(x0, &1); + assert_eq!(xn, &4); + assert_eq!(bar, &[1, 2, 3, 4]); + + MatchArm::Arm(1) + }, + _ => MatchArm::Wild, + } +} + +fn main() { + let foo = vec![1, 2, 3, 4, 5]; + + assert_eq!(test(&foo), MatchArm::Arm(0)); + assert_eq!(test(&foo[..4]), MatchArm::Arm(1)); + assert_eq!(test(&foo[0..1]), MatchArm::Wild); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.rs b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.rs new file mode 100644 index 000000000000..e9b658e3817e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/bindings-after-at/wild-before-at-syntactically-rejected.rs @@ -0,0 +1,17 @@ +// Here we check that `_ @ sub` is syntactically invalid +// and comes with a nice actionable suggestion. + +fn main() {} + +#[cfg(FALSE)] +fn wild_before_at_is_bad_syntax() { + let _ @ a = 0; +// { dg-error "" "" { target *-*-* } .-1 } + let _ @ ref a = 0; +// { dg-error "" "" { target *-*-* } .-1 } + let _ @ ref mut a = 0; +// { dg-error "" "" { target *-*-* } .-1 } + let _ @ (a, .., b) = (0, 1, 2, 3); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/const-pat-ice.rs b/gcc/testsuite/rust/rustc/ui/pattern/const-pat-ice.rs new file mode 100644 index 000000000000..0af437986969 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/const-pat-ice.rs @@ -0,0 +1,12 @@ +// check-pass + +const FOO: &&&u32 = &&&42; + +fn main() { + match unimplemented!() { + &&&42 => {}, + FOO => {}, + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/deny-irrefutable-let-patterns.rs b/gcc/testsuite/rust/rustc/ui/pattern/deny-irrefutable-let-patterns.rs new file mode 100644 index 000000000000..4829fdd47e95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/deny-irrefutable-let-patterns.rs @@ -0,0 +1,10 @@ +#![deny(irrefutable_let_patterns)] + +fn main() { + if let _ = 5 {} // { dg-error "" "" { target *-*-* } } + + while let _ = 5 { // { dg-error "" "" { target *-*-* } } + break; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/irrefutable-let-patterns.rs b/gcc/testsuite/rust/rustc/ui/pattern/irrefutable-let-patterns.rs new file mode 100644 index 000000000000..a4d269810452 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/irrefutable-let-patterns.rs @@ -0,0 +1,12 @@ +// run-pass + +#![allow(irrefutable_let_patterns)] + +fn main() { + if let _ = 5 {} + + while let _ = 5 { + break; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/issue-66270-pat-struct-parser-recovery.rs b/gcc/testsuite/rust/rustc/ui/pattern/issue-66270-pat-struct-parser-recovery.rs new file mode 100644 index 000000000000..1ef90209d0c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/issue-66270-pat-struct-parser-recovery.rs @@ -0,0 +1,15 @@ +// Regression test for #66270, fixed by #66246 + +struct Bug { + incorrect_field: 0, +// { dg-error "" "" { target *-*-* } .-1 } +} + +struct Empty {} + +fn main() { + let Bug { + any_field: Empty {}, + } = Bug {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/issue-66501.rs b/gcc/testsuite/rust/rustc/ui/pattern/issue-66501.rs new file mode 100644 index 000000000000..3f16239ce131 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/issue-66501.rs @@ -0,0 +1,13 @@ +// check-pass + +#![allow(unreachable_patterns)] + +fn main() { + const CONST: &[Option<()>; 1] = &[Some(())]; + match &[Some(())] { + &[None] => {} + CONST => {} + &[Some(())] => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/issue-67776-match-same-name-enum-variant-refs.rs b/gcc/testsuite/rust/rustc/ui/pattern/issue-67776-match-same-name-enum-variant-refs.rs new file mode 100644 index 000000000000..a3663b04a3d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/issue-67776-match-same-name-enum-variant-refs.rs @@ -0,0 +1,43 @@ +// Test for issue #67776: binding named the same as enum variant +// should report a warning even when matching against a reference type + +// check-pass + +#![allow(unused_variables)] +#![allow(non_snake_case)] + +enum Foo { + Bar, + Baz, +} + + +fn fn1(e: Foo) { + match e { + Bar => {}, +// { dg-warning "" "" { target *-*-* } .-1 } + Baz => {}, +// { dg-warning "" "" { target *-*-* } .-1 } + } +} + +fn fn2(e: &Foo) { + match e { + Bar => {}, +// { dg-warning "" "" { target *-*-* } .-1 } + Baz => {}, +// { dg-warning "" "" { target *-*-* } .-1 } + } +} + +fn fn3(e: &mut &&mut Foo) { + match e { + Bar => {}, +// { dg-warning "" "" { target *-*-* } .-1 } + Baz => {}, +// { dg-warning "" "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/issue-68393-let-pat-assoc-constant.rs b/gcc/testsuite/rust/rustc/ui/pattern/issue-68393-let-pat-assoc-constant.rs new file mode 100644 index 000000000000..dca255dde6bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/issue-68393-let-pat-assoc-constant.rs @@ -0,0 +1,27 @@ +pub enum EFoo { + A, +} + +pub trait Foo { + const X: EFoo; +} + +struct Abc; + +impl Foo for Abc { + const X: EFoo = EFoo::A; +} + +struct Def; +impl Foo for Def { + const X: EFoo = EFoo::A; +} + +pub fn test(arg: EFoo, A::X: EFoo) { +// { dg-error ".E0158." "" { target *-*-* } .-1 } + let A::X = arg; +// { dg-error ".E0158." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/issue-68394-let-pat-runtime-value.rs b/gcc/testsuite/rust/rustc/ui/pattern/issue-68394-let-pat-runtime-value.rs new file mode 100644 index 000000000000..29211b3e9c8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/issue-68394-let-pat-runtime-value.rs @@ -0,0 +1,6 @@ +fn main() { + let x = 255u8; + let 0u8..=x = 0; +// { dg-error ".E0080." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/issue-68396-let-float-bug.rs b/gcc/testsuite/rust/rustc/ui/pattern/issue-68396-let-float-bug.rs new file mode 100644 index 000000000000..2950b2fbd622 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/issue-68396-let-float-bug.rs @@ -0,0 +1,8 @@ +fn main() { + let 1234567890123456789012345678901234567890e-340: f64 = 0.0; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + + fn param(1234567890123456789012345678901234567890e-340: f64) {} +// { dg-error ".E0080." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs b/gcc/testsuite/rust/rustc/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs new file mode 100644 index 000000000000..74aa1443ae78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/issue-71042-opaquely-typed-constant-used-in-pattern.rs @@ -0,0 +1,11 @@ +#![feature(impl_trait_in_bindings)] +#![allow(incomplete_features)] + +fn main() { + const C: impl Copy = 0; + match C { + C | // { dg-error "" "" { target *-*-* } } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/issue-72565.rs b/gcc/testsuite/rust/rustc/ui/pattern/issue-72565.rs new file mode 100644 index 000000000000..35ee4e907127 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/issue-72565.rs @@ -0,0 +1,9 @@ +const F: &'static dyn PartialEq = &7u32; + +fn main() { + let a: &dyn PartialEq = &7u32; + match a { + F => panic!(), // { dg-error "" "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/issue-74539.rs b/gcc/testsuite/rust/rustc/ui/pattern/issue-74539.rs new file mode 100644 index 000000000000..ec8177946355 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/issue-74539.rs @@ -0,0 +1,16 @@ +enum E { + A(u8, u8), +} + +fn main() { + let e = E::A(2, 3); + match e { + E::A(x @ ..) => { +// { dg-error ".E0023." "" { target *-*-* } .-1 } +// { dg-error ".E0023." "" { target *-*-* } .-2 } +// { dg-error ".E0023." "" { target *-*-* } .-3 } + x + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/issue-74702.rs b/gcc/testsuite/rust/rustc/ui/pattern/issue-74702.rs new file mode 100644 index 000000000000..b59e6e75198d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/issue-74702.rs @@ -0,0 +1,8 @@ +fn main() { + let (foo @ ..,) = (0, 0); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + dbg!(foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/issue-74954.rs b/gcc/testsuite/rust/rustc/ui/pattern/issue-74954.rs new file mode 100644 index 000000000000..475329c12350 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/issue-74954.rs @@ -0,0 +1,8 @@ +// check-pass + +fn main() { + if let Some([b'@', filename @ ..]) = Some(b"@abc123") { + println!("filename {:?}", filename); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs new file mode 100644 index 000000000000..b409a05a8f3d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs @@ -0,0 +1,30 @@ +// check-pass + +fn main() {} + +struct U; + +fn slice() { + let mut arr = [U, U, U, U, U, U, U, U]; + let [ref _x0, _x1, _, mut _x3, .., ref _x6, _x7] = arr; + _x3 = U; + let [ref mut _x0, _, ref _x2, _, _x4, ref mut _x5, _x6, _] = arr; + *_x5 = U; + let [_, _, _x2, _, _, _x5, _, _] = arr; + *_x0 = U; + let [ref _x0, ..] = arr; + let [_x0, ..] = arr; +} + +fn tuple() { + let mut tup = (U, U, U, U, U); + let (ref _x0, mut _x1, ref _x2, ..) = tup; + _x1 = U; + let (ref mut _x0, _, _, ref _x3, _x4) = tup; + let (_, _, _, _x3, _) = tup; + *_x0 = U; + drop(_x2); + drop(tup.2); + let (_x0, _, _, ..) = tup; +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs new file mode 100644 index 000000000000..f2f0e04ecdbb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.rs @@ -0,0 +1,49 @@ +fn main() {} + +struct U; + +fn slice() { + let mut arr = [U, U, U, U, U]; + let hold_all = &arr; + let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; // { dg-error ".E0505." "" { target *-*-* } } + _x1 = U; // { dg-error ".E0384." "" { target *-*-* } } + drop(hold_all); + let [_x0, ..] = arr; // { dg-error ".E0505." "" { target *-*-* } } + drop(_x0_hold); + let [_, _, ref mut _x2, _x3, mut _x4] = arr; +// { dg-error ".E0505." "" { target *-*-* } .-1 } +// { dg-error ".E0505." "" { target *-*-* } .-2 } +// { dg-error ".E0505." "" { target *-*-* } .-3 } + drop(xs_hold); +} + +fn tuple() { + let mut tup = (U, U, U, U); + let (ref _x0, _x1, ref _x2, ..) = tup; + _x1 = U; // { dg-error ".E0384." "" { target *-*-* } } + let _x0_hold = &mut tup.0; // { dg-error ".E0502." "" { target *-*-* } } + let (ref mut _x0_hold, ..) = tup; // { dg-error ".E0502." "" { target *-*-* } } + *_x0 = U; // { dg-error ".E0594." "" { target *-*-* } } + *_x2 = U; // { dg-error ".E0594." "" { target *-*-* } } + drop(tup.1); // { dg-error ".E0382." "" { target *-*-* } } + let _x1_hold = &tup.1; // { dg-error ".E0382." "" { target *-*-* } } + let (.., ref mut _x3) = tup; + let _x3_hold = &tup.3; // { dg-error ".E0502." "" { target *-*-* } } + let _x3_hold = &mut tup.3; // { dg-error ".E0499." "" { target *-*-* } } + let (.., ref mut _x4_hold) = tup; // { dg-error ".E0499." "" { target *-*-* } } + let (.., ref _x4_hold) = tup; // { dg-error ".E0502." "" { target *-*-* } } + drop(_x3); +} + +fn closure() { + let mut tup = (U, U, U); + let c1 = || { + let (ref _x0, _x1, _) = tup; + }; + let c2 = || { +// { dg-error ".E0382." "" { target *-*-* } .-1 } + let (ref mut _x0, _, _x2) = tup; + }; + drop(c1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs new file mode 100644 index 000000000000..a885afc0e374 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/by-move-sub-pat-unreachable.rs @@ -0,0 +1,15 @@ +// When conflicts between by-move bindings in `by_move_1 @ has_by_move` patterns +// happen and that code is unreachable according to borrowck, we accept this code. +// In particular, we want to ensure here that an ICE does not happen, which it did originally. + +// check-pass + +#![feature(bindings_after_at)] + +fn main() { + return; + + struct S; + let a @ (b, c) = (S, S); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/issue-53840.rs b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/issue-53840.rs new file mode 100644 index 000000000000..39a3b9c6c879 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/issue-53840.rs @@ -0,0 +1,21 @@ +// check-pass + +enum E { + Foo(String, String, String), +} + +struct Bar { + a: String, + b: String, +} + +fn main() { + let bar = Bar { a: "1".to_string(), b: "2".to_string() }; + match E::Foo("".into(), "".into(), "".into()) { + E::Foo(a, b, ref c) => {} + } + match bar { + Bar { a, ref b } => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs new file mode 100644 index 000000000000..66197c573b4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-inside.rs @@ -0,0 +1,121 @@ +fn main() { + struct S; // Not `Copy`. + + let mut tup0 = (S, S); + let mut tup1 = (S, S, S); + let tup2 = (S, S); + let tup3 = (S, S, S); + let tup4 = (S, S); + let mut arr0 = [S, S, S]; + let mut arr1 = [S, S, S, S, S]; + let arr2 = [S, S, S]; + let arr3 = [S, S, S, S, S]; + + // The `mov` bindings require that we capture the scrutinees by-move. + let mut closure = || { + // Tuples... + let (ref mut borrow, mov) = tup0; + let (mov, _, ref mut borrow) = tup1; + let (ref borrow, mov) = tup2; + let (mov, _, ref borrow) = tup3; + let (ref borrow, mov) = tup4; + // Arrays... + let [mov @ .., ref borrow] = arr0; + let [_, ref mut borrow @ .., _, mov] = arr1; + let [mov @ .., ref borrow] = arr2; + let [_, ref borrow @ .., _, mov] = arr3; + }; + + // Now we try to borrow and move the captures, which should result in errors... + // ...for tuples: + drop(&tup0); // { dg-error ".E0382." "" { target *-*-* } } + drop(&tup1); // { dg-error ".E0382." "" { target *-*-* } } + drop(&tup2); // { dg-error ".E0382." "" { target *-*-* } } + drop(&tup3); // { dg-error ".E0382." "" { target *-*-* } } + // Ostensibly this should compile. + // However, because closures don't capture individual fields, which is changed in RFC 2229, + // this won't compile because the entire product is moved into the closure. + // The same applies to the array patterns below. + drop(&tup4.0); // { dg-error ".E0382." "" { target *-*-* } } + // ...for arrays: + drop(&arr0); // { dg-error ".E0382." "" { target *-*-* } } + let [_, mov1, mov2, mov3, _] = &arr1; // { dg-error ".E0382." "" { target *-*-* } } + drop(&arr2); // { dg-error ".E0382." "" { target *-*-* } } + let [_, mov1, mov2, mov3, _] = &arr3; // { dg-error ".E0382." "" { target *-*-* } } + + // Let's redo ^--- with a `match` + sum type: + macro_rules! m { + ($p:pat = $s:expr) => { + match $s { + Some($p) => {} + _ => {} + } + }; + } + let mut tup0: Option<(S, S)> = None; + let mut tup1: Option<(S, S, S)> = None; + let tup2: Option<(S, S)> = None; + let tup3: Option<(S, S, S)> = None; + let tup4: Option<(S, S)> = None; + let mut arr0: Option<[S; 3]> = None; + let mut arr1: Option<[S; 5]> = None; + let arr2: Option<[S; 3]> = None; + let arr3: Option<[S; 5]> = None; + let mut closure = || { + m!((ref mut borrow, mov) = tup0); + m!((mov, _, ref mut borrow) = tup1); + m!((ref borrow, mov) = tup2); + m!((mov, _, ref borrow) = tup3); + m!((ref borrow, mov) = tup4); + m!([mov @ .., ref borrow] = arr0); + m!([_, ref mut borrow @ .., _, mov] = arr1); + m!([mov @ .., ref borrow] = arr2); + m!([_, ref borrow @ .., _, mov] = arr3); + }; + drop(&tup0); // { dg-error ".E0382." "" { target *-*-* } } + drop(&tup1); // { dg-error ".E0382." "" { target *-*-* } } + drop(&tup2); // { dg-error ".E0382." "" { target *-*-* } } + drop(&tup3); // { dg-error ".E0382." "" { target *-*-* } } + m!((ref x, _) = &tup4); // { dg-error ".E0382." "" { target *-*-* } } + drop(&arr0); // { dg-error ".E0382." "" { target *-*-* } } + m!([_, mov1, mov2, mov3, _] = &arr1); // { dg-error ".E0382." "" { target *-*-* } } + drop(&arr2); // { dg-error ".E0382." "" { target *-*-* } } + m!([_, mov1, mov2, mov3, _] = &arr3); // { dg-error ".E0382." "" { target *-*-* } } + + // Let's redo ^--- with `if let` (which may diverge from `match` in the future): + macro_rules! m { + ($p:pat = $s:expr) => { + if let Some($p) = $s {} + }; + } + let mut tup0: Option<(S, S)> = None; + let mut tup1: Option<(S, S, S)> = None; + let tup2: Option<(S, S)> = None; + let tup3: Option<(S, S, S)> = None; + let tup4: Option<(S, S)> = None; + let mut arr0: Option<[S; 3]> = None; + let mut arr1: Option<[S; 5]> = None; + let arr2: Option<[S; 3]> = None; + let arr3: Option<[S; 5]> = None; + let mut closure = || { + m!((ref mut borrow, mov) = tup0); + m!((mov, _, ref mut borrow) = tup1); + m!((ref borrow, mov) = tup2); + m!((mov, _, ref borrow) = tup3); + m!((ref borrow, mov) = tup4); + m!([mov @ .., ref borrow] = arr0); + m!([_, ref mut borrow @ .., _, mov] = arr1); + m!([mov @ .., ref borrow] = arr2); + m!([_, ref borrow @ .., _, mov] = arr3); + }; + drop(&tup0); // { dg-error ".E0382." "" { target *-*-* } } + drop(&tup1); // { dg-error ".E0382." "" { target *-*-* } } + drop(&tup2); // { dg-error ".E0382." "" { target *-*-* } } + drop(&tup3); // { dg-error ".E0382." "" { target *-*-* } } + m!((ref x, _) = &tup4); // { dg-error ".E0382." "" { target *-*-* } } + drop(&arr0); // { dg-error ".E0382." "" { target *-*-* } } + m!([_, mov1, mov2, mov3, _] = &arr1); // { dg-error ".E0382." "" { target *-*-* } } + drop(&arr2); // { dg-error ".E0382." "" { target *-*-* } } + m!([_, mov1, mov2, mov3, _] = &arr3); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs new file mode 100644 index 000000000000..d69371d0a9e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs @@ -0,0 +1,29 @@ +// check-pass + +fn main() { + struct U; + fn accept_fn_once(_: impl FnOnce()) {} + fn accept_fn_mut(_: impl FnMut()) {} + fn accept_fn(_: impl Fn()) {} + + let mut tup = (U, U, U); + let (ref _x0, _x1, ref mut _x2) = tup; + let c1 = || { + drop::<&U>(_x0); + drop::(_x1); + drop::<&mut U>(_x2); + }; + accept_fn_once(c1); + + let c2 = || { + drop::<&U>(_x0); + drop::<&mut U>(_x2); + }; + accept_fn_mut(c2); + + let c3 = || { + drop::<&U>(_x0); + }; + accept_fn(c3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs new file mode 100644 index 000000000000..4c26e61014f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures.rs @@ -0,0 +1,33 @@ +fn main() { + struct U; + fn accept_fn_once(_: &impl FnOnce()) {} + fn accept_fn_mut(_: &impl FnMut()) {} + fn accept_fn(_: &impl Fn()) {} + + let mut tup = (U, U, U); + let (ref _x0, _x1, ref mut _x2) = tup; + let c1 = || { +// { dg-error ".E0525." "" { target *-*-* } .-1 } +// { dg-error ".E0525." "" { target *-*-* } .-2 } + drop::<&U>(_x0); + drop::(_x1); + drop::<&mut U>(_x2); + }; + accept_fn_once(&c1); + accept_fn_mut(&c1); + accept_fn(&c1); + + let c2 = || { +// { dg-error ".E0525." "" { target *-*-* } .-1 } + drop::<&U>(_x0); + drop::<&mut U>(_x2); + }; + accept_fn_mut(&c2); + accept_fn(&c2); + + let c3 = || { + drop::<&U>(_x0); + }; + accept_fn(&c3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs new file mode 100644 index 000000000000..7cf033ac8abf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-default-binding-modes.rs @@ -0,0 +1,15 @@ +fn main() { + struct U; + + // A tuple is a "non-reference pattern". + // A `mut` binding pattern resets the binding mode to by-value. + + let p = (U, U); + let (a, mut b) = &p; +// { dg-error ".E0507." "" { target *-*-* } .-1 } + + let mut p = (U, U); + let (a, mut b) = &mut p; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs new file mode 100644 index 000000000000..3ee7f00905a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/move-ref-patterns/move-ref-patterns-dynamic-semantics.rs @@ -0,0 +1,80 @@ +// run-pass + +// This test checks the dynamic semantics and drop order of pattern matching +// where a product pattern has both a by-move and by-ref binding. + +use std::cell::RefCell; +use std::rc::Rc; + +struct X { + x: Box, + d: DropOrderListPtr, +} + +type DropOrderListPtr = Rc>>; + +impl Drop for X { + fn drop(&mut self) { + self.d.borrow_mut().push(*self.x); + } +} + +enum DoubleOption { + Some2(T, U), + _None2, +} + +fn main() { + let d: DropOrderListPtr = <_>::default(); + { + let mk = |v| X { x: Box::new(v), d: d.clone() }; + let check = |a1: &X, a2, b1: &X, b2| { + assert_eq!(*a1.x, a2); + assert_eq!(*b1.x, b2); + }; + + let x = DoubleOption::Some2(mk(1), mk(2)); + match x { + DoubleOption::Some2(ref a, b) => check(a, 1, &b, 2), + DoubleOption::_None2 => panic!(), + } + let x = DoubleOption::Some2(mk(3), mk(4)); + match x { + DoubleOption::Some2(a, ref b) => check(&a, 3, b, 4), + DoubleOption::_None2 => panic!(), + } + match DoubleOption::Some2(mk(5), mk(6)) { + DoubleOption::Some2(ref a, b) => check(a, 5, &b, 6), + DoubleOption::_None2 => panic!(), + } + match DoubleOption::Some2(mk(7), mk(8)) { + DoubleOption::Some2(a, ref b) => check(&a, 7, b, 8), + DoubleOption::_None2 => panic!(), + } + { + let (a, ref b) = (mk(9), mk(10)); + let (ref c, d) = (mk(11), mk(12)); + check(&a, 9, b, 10); + check(c, 11, &d, 12); + } + fn fun([a, ref mut b, ref xs @ .., ref c, d]: [X; 6]) { + assert_eq!(*a.x, 13); + assert_eq!(*b.x, 14); + assert_eq!(&[*xs[0].x, *xs[1].x], &[15, 16]); + assert_eq!(*c.x, 17); + assert_eq!(*d.x, 18); + } + fun([mk(13), mk(14), mk(15), mk(16), mk(17), mk(18)]); + + let lam = |(a, ref b, c, ref mut d): (X, X, X, X)| { + assert_eq!(*a.x, 19); + assert_eq!(*b.x, 20); + assert_eq!(*c.x, 21); + assert_eq!(*d.x, 22); + }; + lam((mk(19), mk(20), mk(21), mk(22))); + } + let expected = [2, 3, 6, 5, 7, 8, 12, 11, 9, 10, 18, 13, 14, 15, 16, 17, 21, 19, 20, 22, 4, 1]; + assert_eq!(&*d.borrow(), &expected); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/pat-shadow-in-nested-binding.rs b/gcc/testsuite/rust/rustc/ui/pattern/pat-shadow-in-nested-binding.rs new file mode 100644 index 000000000000..d4d9644a1802 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/pat-shadow-in-nested-binding.rs @@ -0,0 +1,7 @@ +#[allow(non_camel_case_types)] +struct foo(usize); + +fn main() { + let (foo, _) = (2, 3); // { dg-error ".E0530." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/pat-struct-field-expr-has-type.rs b/gcc/testsuite/rust/rustc/ui/pattern/pat-struct-field-expr-has-type.rs new file mode 100644 index 000000000000..5ae13bf18b73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/pat-struct-field-expr-has-type.rs @@ -0,0 +1,10 @@ +struct S { + f: u8, +} + +fn main() { + match (S { f: 42 }) { + S { f: Ok(_) } => {} // { dg-error ".E0308." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/pat-tuple-bad-type.rs b/gcc/testsuite/rust/rustc/ui/pattern/pat-tuple-bad-type.rs new file mode 100644 index 000000000000..9246c0defeae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/pat-tuple-bad-type.rs @@ -0,0 +1,16 @@ +fn main() { + let x; + + match x { + (..) => {} // { dg-error ".E0282." "" { target *-*-* } } + _ => {} + } + + match 0u8 { + (..) => {} // { dg-error ".E0308." "" { target *-*-* } } + _ => {} + } + + x = 10; +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/pat-tuple-overfield.rs b/gcc/testsuite/rust/rustc/ui/pattern/pat-tuple-overfield.rs new file mode 100644 index 000000000000..5afdb63f87e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/pat-tuple-overfield.rs @@ -0,0 +1,17 @@ +struct S(u8, u8, u8); + +fn main() { + match (1, 2, 3) { + (1, 2, 3, 4) => {} // { dg-error ".E0308." "" { target *-*-* } } + (1, 2, .., 3, 4) => {} // { dg-error ".E0308." "" { target *-*-* } } + _ => {} + } + match S(1, 2, 3) { + S(1, 2, 3, 4) => {} +// { dg-error ".E0023." "" { target *-*-* } .-1 } + S(1, 2, .., 3, 4) => {} +// { dg-error ".E0023." "" { target *-*-* } .-1 } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/pat-type-err-formal-param.rs b/gcc/testsuite/rust/rustc/ui/pattern/pat-type-err-formal-param.rs new file mode 100644 index 000000000000..d4eacdff39c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/pat-type-err-formal-param.rs @@ -0,0 +1,9 @@ +// Test the `.span_label(..)` to the type when there's a +// type error in a pattern due to a the formal parameter. + +fn main() {} + +struct Tuple(u8); + +fn foo(Tuple(_): String) {} // { dg-error ".E0308." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/pat-type-err-let-stmt.rs b/gcc/testsuite/rust/rustc/ui/pattern/pat-type-err-let-stmt.rs new file mode 100644 index 000000000000..d6e051190976 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/pat-type-err-let-stmt.rs @@ -0,0 +1,17 @@ +// Test the `.span_label` to the type / scrutinee +// when there's a type error in checking a pattern. + +fn main() { + // We want to point at the `Option`. + let Ok(0): Option = 42u8; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + // We want to point at the `Option`. + let Ok(0): Option; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + // We want to point at the scrutinee. + let Ok(0) = 42u8; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/patkind-litrange-no-expr.rs b/gcc/testsuite/rust/rustc/ui/pattern/patkind-litrange-no-expr.rs new file mode 100644 index 000000000000..484f95728a78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/patkind-litrange-no-expr.rs @@ -0,0 +1,26 @@ +macro_rules! enum_number { + ($name:ident { $($variant:ident = $value:expr, )* }) => { + enum $name { + $($variant = $value,)* + } + + fn foo(value: i32) -> Option<$name> { + match value { + $( $value => Some($name::$variant), )* // PatKind::Lit + $( $value ..= 42 => Some($name::$variant), )* // PatKind::Range + _ => None + } + } + } +} + +enum_number!(Change { + Pos = 1, + Neg = -1, + Arith = 1 + 1, // { dg-error ".E0029." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error ".E0029." "" { target *-*-* } .-3 } +}); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/pattern-binding-disambiguation.rs b/gcc/testsuite/rust/rustc/ui/pattern/pattern-binding-disambiguation.rs new file mode 100644 index 000000000000..93deb8584170 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/pattern-binding-disambiguation.rs @@ -0,0 +1,58 @@ +struct UnitStruct; +struct TupleStruct(); +struct BracedStruct{} + +enum E { + UnitVariant, + TupleVariant(), + BracedVariant{}, +} +use E::*; + +const CONST: () = (); +static STATIC: () = (); + +fn function() {} + +fn main() { + let doesnt_matter = 0; + + match UnitStruct { + UnitStruct => {} // OK, `UnitStruct` is a unit struct pattern + } + match doesnt_matter { + TupleStruct => {} // { dg-error ".E0530." "" { target *-*-* } } + } + match doesnt_matter { + BracedStruct => {} // OK, `BracedStruct` is a fresh binding + } + match UnitVariant { + UnitVariant => {} // OK, `UnitVariant` is a unit variant pattern + } + match doesnt_matter { + TupleVariant => {} // { dg-error ".E0530." "" { target *-*-* } } + } + match doesnt_matter { + BracedVariant => {} // { dg-error ".E0530." "" { target *-*-* } } + } + match CONST { + CONST => {} // OK, `CONST` is a const pattern + } + match doesnt_matter { + STATIC => {} // { dg-error ".E0530." "" { target *-*-* } } + } + match doesnt_matter { + function => {} // OK, `function` is a fresh binding + } + + let UnitStruct = UnitStruct; // OK, `UnitStruct` is a unit struct pattern + let TupleStruct = doesnt_matter; // { dg-error ".E0530." "" { target *-*-* } } + let BracedStruct = doesnt_matter; // OK, `BracedStruct` is a fresh binding + let UnitVariant = UnitVariant; // OK, `UnitVariant` is a unit variant pattern + let TupleVariant = doesnt_matter; // { dg-error ".E0530." "" { target *-*-* } } + let BracedVariant = doesnt_matter; // { dg-error ".E0530." "" { target *-*-* } } + let CONST = CONST; // OK, `CONST` is a const pattern + let STATIC = doesnt_matter; // { dg-error ".E0530." "" { target *-*-* } } + let function = doesnt_matter; // OK, `function` is a fresh binding +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/pattern-error-continue.rs b/gcc/testsuite/rust/rustc/ui/pattern/pattern-error-continue.rs new file mode 100644 index 000000000000..1630818a39a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/pattern-error-continue.rs @@ -0,0 +1,36 @@ +// Test that certain pattern-match type errors are non-fatal + +enum A { + B(isize, isize), + C(isize, isize, isize), + D +} + +struct S { + a: isize +} + +fn f(_c: char) {} + +fn main() { + match A::B(1, 2) { + A::B(_, _, _) => (), // { dg-error ".E0023." "" { target *-*-* } } + A::D(_) => (), // { dg-error ".E0532." "" { target *-*-* } } + _ => () + } + match 'c' { + S { .. } => (), +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + _ => () + } + f(true); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + match () { + E::V => {} // { dg-error ".E0433." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/pattern-ident-path-generics.rs b/gcc/testsuite/rust/rustc/ui/pattern/pattern-ident-path-generics.rs new file mode 100644 index 000000000000..e47704945b99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/pattern-ident-path-generics.rs @@ -0,0 +1,7 @@ +fn main() { + match Some("foo") { + None:: => {} // { dg-error ".E0308." "" { target *-*-* } } + Some(_) => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/pattern-tyvar-2.rs b/gcc/testsuite/rust/rustc/ui/pattern/pattern-tyvar-2.rs new file mode 100644 index 000000000000..86ae4317364f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/pattern-tyvar-2.rs @@ -0,0 +1,7 @@ +enum Bar { T1((), Option>), T2, } + +fn foo(t: Bar) -> isize { match t { Bar::T1(_, Some(x)) => { return x * 3; } _ => { panic!(); } } } +// { dg-error ".E0369." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/pattern-tyvar.rs b/gcc/testsuite/rust/rustc/ui/pattern/pattern-tyvar.rs new file mode 100644 index 000000000000..e1d1be3bbf00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/pattern-tyvar.rs @@ -0,0 +1,13 @@ +enum Bar { T1((), Option>), T2 } + +fn foo(t: Bar) { + match t { + Bar::T1(_, Some::(x)) => { // { dg-error ".E0308." "" { target *-*-* } } + println!("{}", x); + } + _ => { panic!(); } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/rest-pat-semantic-disallowed.rs b/gcc/testsuite/rust/rustc/ui/pattern/rest-pat-semantic-disallowed.rs new file mode 100644 index 000000000000..730019f928e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/rest-pat-semantic-disallowed.rs @@ -0,0 +1,84 @@ +// Here we test that rest patterns, i.e. `..`, are not allowed +// outside of slice (+ ident patterns witin those), tuple, +// and tuple struct patterns and that duplicates are caught in these contexts. + +#![feature(box_patterns)] + +fn main() {} + +macro_rules! mk_pat { + () => { .. } // { dg-error "" "" { target *-*-* } } +} + +fn rest_patterns() { + let mk_pat!(); + + // Top level: + fn foo(..: u8) {} // { dg-error "" "" { target *-*-* } } + let ..; // { dg-error "" "" { target *-*-* } } + + // Box patterns: + let box ..; // { dg-error "" "" { target *-*-* } } + + // In or-patterns: + match 1 { + 1 | .. => {} // { dg-error "" "" { target *-*-* } } + } + + // Ref patterns: + let &..; // { dg-error "" "" { target *-*-* } } + let &mut ..; // { dg-error "" "" { target *-*-* } } + + // Ident patterns: + let x @ ..; // { dg-error ".E0282." "" { target *-*-* } } +// { dg-error ".E0282." "" { target *-*-* } .-1 } + let ref x @ ..; // { dg-error "" "" { target *-*-* } } + let ref mut x @ ..; // { dg-error "" "" { target *-*-* } } + + // Tuple: + let (..): (u8,); // OK. + let (..,): (u8,); // OK. + let ( + .., + .., // { dg-error "" "" { target *-*-* } } + .. // { dg-error "" "" { target *-*-* } } + ): (u8, u8, u8); + let ( + .., + x, + .. // { dg-error "" "" { target *-*-* } } + ): (u8, u8, u8); + + struct A(u8, u8, u8); + + // Tuple struct (same idea as for tuple patterns): + let A(..); // OK. + let A(..,); // OK. + let A( + .., + .., // { dg-error "" "" { target *-*-* } } + .. // { dg-error "" "" { target *-*-* } } + ); + let A( + .., + x, + .. // { dg-error "" "" { target *-*-* } } + ); + + // Array/Slice: + let [..]: &[u8]; // OK. + let [..,]: &[u8]; // OK. + let [ + .., + .., // { dg-error "" "" { target *-*-* } } + .. // { dg-error "" "" { target *-*-* } } + ]: &[u8]; + let [ + .., + ref x @ .., // { dg-error "" "" { target *-*-* } } + ref mut y @ .., // { dg-error "" "" { target *-*-* } } + (ref z @ ..), // { dg-error "" "" { target *-*-* } } + .. // { dg-error "" "" { target *-*-* } } + ]: &[u8]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/rest-pat-syntactic.rs b/gcc/testsuite/rust/rustc/ui/pattern/rest-pat-syntactic.rs new file mode 100644 index 000000000000..f31b6907dcf7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/rest-pat-syntactic.rs @@ -0,0 +1,71 @@ +// Here we test that `..` is allowed in all pattern locations *syntactically*. +// The semantic test is in `rest-pat-semantic-disallowed.rs`. + +// check-pass + +fn main() {} + +macro_rules! accept_pat { + ($p:pat) => {} +} + +accept_pat!(..); + +#[cfg(FALSE)] +fn rest_patterns() { + // Top level: + fn foo(..: u8) {} + let ..; + + // Box patterns: + let box ..; + + // In or-patterns: + match x { + .. | .. => {} + } + + // Ref patterns: + let &..; + let &mut ..; + + // Ident patterns: + let x @ ..; + let ref x @ ..; + let ref mut x @ ..; + + // Tuple: + let (..); // This is interpreted as a tuple pattern, not a parenthesis one. + let (..,); // Allowing trailing comma. + let (.., .., ..); // Duplicates also. + let (.., P, ..); // Including with things in between. + + // Tuple struct (same idea as for tuple patterns): + let A(..); + let A(..,); + let A(.., .., ..); + let A(.., P, ..); + + // Array/Slice (like with tuple patterns): + let [..]; + let [..,]; + let [.., .., ..]; + let [.., P, ..]; + + // Random walk to guard against special casing: + match x { + .. | + [ + ( + box .., + &(..), + &mut .., + x @ .. + ), + ref x @ .., + ] | + ref mut x @ .. + => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/always-inhabited-union-ref.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/always-inhabited-union-ref.rs new file mode 100644 index 000000000000..07bd77c184e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/always-inhabited-union-ref.rs @@ -0,0 +1,33 @@ +// The precise semantics of inhabitedness with respect to unions and references is currently +// undecided. This test file currently checks a conservative choice. + +#![feature(exhaustive_patterns)] +#![feature(never_type)] + +#![allow(dead_code)] +#![allow(unreachable_code)] + +pub union Foo { + foo: !, +} + +fn uninhab_ref() -> &'static ! { + unimplemented!() +} + +fn uninhab_union() -> Foo { + unimplemented!() +} + +fn match_on_uninhab() { + match uninhab_ref() { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + } + + match uninhab_union() { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/consts-opaque.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/consts-opaque.rs new file mode 100644 index 000000000000..9a8920bc06ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/consts-opaque.rs @@ -0,0 +1,115 @@ +// This file tests the exhaustiveness algorithm on opaque constants. Most of the examples give +// unnecessary warnings because const_to_pat.rs converts a constant pattern to a wildcard when the +// constant is not allowed as a pattern. This is an edge case so we may not care to fix it. +// See also https://github.com/rust-lang/rust/issues/78057 + +#![deny(unreachable_patterns)] + +#[derive(PartialEq)] +struct Foo(i32); +impl Eq for Foo {} +const FOO: Foo = Foo(42); +const FOO_REF: &Foo = &Foo(42); +const FOO_REF_REF: &&Foo = &&Foo(42); + +#[derive(PartialEq)] +struct Bar; +impl Eq for Bar {} +const BAR: Bar = Bar; + +#[derive(PartialEq)] +enum Baz { + Baz1, + Baz2 +} +impl Eq for Baz {} +const BAZ: Baz = Baz::Baz1; + +type Quux = fn(usize, usize) -> usize; +fn quux(a: usize, b: usize) -> usize { a + b } +const QUUX: Quux = quux; + +fn main() { + match FOO { + FOO => {} +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} // should not be emitting unreachable warning +// { dg-error "" "" { target *-*-* } .-1 } + } + + match FOO_REF { + FOO_REF => {} +// { dg-error "" "" { target *-*-* } .-1 } + Foo(_) => {} // should not be emitting unreachable warning +// { dg-error "" "" { target *-*-* } .-1 } + } + + // This used to cause an ICE (https://github.com/rust-lang/rust/issues/78071) + match FOO_REF_REF { + FOO_REF_REF => {} +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + Foo(_) => {} + } + + match BAR { + Bar => {} + BAR => {} // should not be emitting unreachable warning +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + _ => {} +// { dg-error "" "" { target *-*-* } .-1 } + } + + match BAR { + BAR => {} +// { dg-error "" "" { target *-*-* } .-1 } + Bar => {} // should not be emitting unreachable warning +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} +// { dg-error "" "" { target *-*-* } .-1 } + } + + match BAR { + BAR => {} +// { dg-error "" "" { target *-*-* } .-1 } + BAR => {} // should not be emitting unreachable warning +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + _ => {} // should not be emitting unreachable warning +// { dg-error "" "" { target *-*-* } .-1 } + } + + match BAZ { + BAZ => {} +// { dg-error "" "" { target *-*-* } .-1 } + Baz::Baz1 => {} // should not be emitting unreachable warning +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} +// { dg-error "" "" { target *-*-* } .-1 } + } + + match BAZ { + Baz::Baz1 => {} + BAZ => {} +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} +// { dg-error "" "" { target *-*-* } .-1 } + } + + match BAZ { + BAZ => {} +// { dg-error "" "" { target *-*-* } .-1 } + Baz::Baz2 => {} // should not be emitting unreachable warning +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} // should not be emitting unreachable warning +// { dg-error "" "" { target *-*-* } .-1 } + } + + match QUUX { + QUUX => {} + QUUX => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/exhaustive_integer_patterns.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/exhaustive_integer_patterns.rs new file mode 100644 index 000000000000..f8029550d144 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/exhaustive_integer_patterns.rs @@ -0,0 +1,173 @@ +#![feature(precise_pointer_size_matching)] +#![feature(exclusive_range_pattern)] +#![deny(unreachable_patterns)] +#![deny(overlapping_patterns)] + +use std::{char, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128}; + +fn main() { + let x: u8 = 0; + + // A single range covering the entire domain. + match x { + 0 ..= 255 => {} // ok + } + + // A combination of ranges and values. + // These are currently allowed to be overlapping. + match x { + 0 ..= 32 => {} + 33 => {} + 34 .. 128 => {} + 100 ..= 200 => {} + 200 => {} // { dg-error "" "" { target *-*-* } } + 201 ..= 255 => {} + } + + // An incomplete set of values. + match x { // { dg-error ".E0004." "" { target *-*-* } } + 0 .. 128 => {} + } + + // A more incomplete set of values. + match x { // { dg-error ".E0004." "" { target *-*-* } } + 0 ..= 10 => {} + 20 ..= 30 => {} + 35 => {} + 70 .. 255 => {} + } + + let x: i8 = 0; + match x { // { dg-error ".E0004." "" { target *-*-* } } + -7 => {} + -5..=120 => {} + -2..=20 => {} +// { dg-error "" "" { target *-*-* } .-1 } + 125 => {} + } + + // Let's test other types too! + let c: char = '\u{0}'; + match c { + '\u{0}' ..= char::MAX => {} // ok + } + + // We can actually get away with just covering the + // following two ranges, which correspond to all + // valid Unicode Scalar Values. + match c { + '\u{0000}' ..= '\u{D7FF}' => {} + '\u{E000}' ..= '\u{10_FFFF}' => {} + } + + match 0u16 { + 0 ..= u16::MAX => {} // ok + } + + match 0u32 { + 0 ..= u32::MAX => {} // ok + } + + match 0u64 { + 0 ..= u64::MAX => {} // ok + } + + match 0u128 { + 0 ..= u128::MAX => {} // ok + } + + match 0i8 { + -128 ..= 127 => {} // ok + } + + match 0i8 { // { dg-error ".E0004." "" { target *-*-* } } + -127 ..= 127 => {} + } + + match 0i16 { + i16::MIN ..= i16::MAX => {} // ok + } + + match 0i16 { // { dg-error ".E0004." "" { target *-*-* } } + i16::MIN ..= -1 => {} + 1 ..= i16::MAX => {} + } + + match 0i32 { + i32::MIN ..= i32::MAX => {} // ok + } + + match 0i64 { + i64::MIN ..= i64::MAX => {} // ok + } + + match 0i128 { + i128::MIN ..= i128::MAX => {} // ok + } + + // Make sure that guards don't factor into the exhaustiveness checks. + match 0u8 { // { dg-error ".E0004." "" { target *-*-* } } + 0 .. 128 => {} + 128 ..= 255 if true => {} + } + + match 0u8 { + 0 .. 128 => {} + 128 ..= 255 if false => {} + 128 ..= 255 => {} // ok, because previous arm was guarded + } + + // Now things start getting a bit more interesting. Testing products! + match (0u8, Some(())) { // { dg-error ".E0004." "" { target *-*-* } } + (1, _) => {} + (_, None) => {} + } + + match (0u8, true) { // { dg-error ".E0004." "" { target *-*-* } } + (0 ..= 125, false) => {} + (128 ..= 255, false) => {} + (0 ..= 255, true) => {} + } + + match (0u8, true) { // ok + (0 ..= 125, false) => {} + (128 ..= 255, false) => {} + (0 ..= 255, true) => {} + (125 .. 128, false) => {} + } + + match 0u8 { + 0 .. 2 => {} + 1 ..= 2 => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + + const LIM: u128 = u128::MAX - 1; + match 0u128 { // { dg-error ".E0004." "" { target *-*-* } } + 0 ..= LIM => {} + } + + match 0u128 { // { dg-error ".E0004." "" { target *-*-* } } + 0 ..= 4 => {} + } + + match 0u128 { // { dg-error ".E0004." "" { target *-*-* } } + 4 ..= u128::MAX => {} + } + + const FOO: i32 = 42; + const BAR: &i32 = &42; + match &0 { + &42 => {} + &FOO => {} // { dg-error "" "" { target *-*-* } } + BAR => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + + // Regression test, see https://github.com/rust-lang/rust/pull/66326#issuecomment-552889933 + match &0 { + BAR => {} // ok + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/guards-not-exhaustive.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/guards-not-exhaustive.rs new file mode 100644 index 000000000000..0e28cf60e4dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/guards-not-exhaustive.rs @@ -0,0 +1,19 @@ +// run-pass + +#![allow(non_snake_case)] + +#[derive(Copy, Clone)] +enum Q { R(Option) } + +fn xyzzy(q: Q) -> usize { + match q { + Q::R(S) if S.is_some() => { 0 } + _ => 1 + } +} + + +pub fn main() { + assert_eq!(xyzzy(Q::R(Some(5))), 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/irrefutable-exhaustive-integer-binding.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/irrefutable-exhaustive-integer-binding.rs new file mode 100644 index 000000000000..186433424992 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/irrefutable-exhaustive-integer-binding.rs @@ -0,0 +1,9 @@ +// run-pass + +fn main() { + let -2147483648..=2147483647 = 1; + let 0..=255 = 0u8; + let -128..=127 = 0i8; + let '\u{0000}'..='\u{10FFFF}' = 'v'; +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/irrefutable-unit.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/irrefutable-unit.rs new file mode 100644 index 000000000000..fcd2e00c2a34 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/irrefutable-unit.rs @@ -0,0 +1,7 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + let ((),()) = ((),()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-35609.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-35609.rs new file mode 100644 index 000000000000..aa9eba9b85b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-35609.rs @@ -0,0 +1,44 @@ +enum Enum { + A, B, C, D, E, F +} +use Enum::*; + +struct S(Enum, ()); +struct Sd { x: Enum, y: () } + +fn main() { + match (A, ()) { // { dg-error ".E0004." "" { target *-*-* } } + (A, _) => {} + } + + match (A, A) { // { dg-error ".E0004." "" { target *-*-* } } + (_, A) => {} + } + + match ((A, ()), ()) { // { dg-error ".E0004." "" { target *-*-* } } + ((A, ()), _) => {} + } + + match ((A, ()), A) { // { dg-error ".E0004." "" { target *-*-* } } + ((A, ()), _) => {} + } + + match ((A, ()), ()) { // { dg-error ".E0004." "" { target *-*-* } } + ((A, _), _) => {} + } + + + match S(A, ()) { // { dg-error ".E0004." "" { target *-*-* } } + S(A, _) => {} + } + + match (Sd { x: A, y: () }) { // { dg-error ".E0004." "" { target *-*-* } } + Sd { x: A, y: _ } => {} + } + + match Some(A) { // { dg-error ".E0004." "" { target *-*-* } } + Some(A) => (), + None => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-43253.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-43253.rs new file mode 100644 index 000000000000..69202efafa29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-43253.rs @@ -0,0 +1,48 @@ +// check-pass +#![feature(exclusive_range_pattern)] +#![warn(unreachable_patterns)] +#![warn(overlapping_patterns)] + +fn main() { + // These cases should generate no warning. + match 10 { + 1..10 => {}, + 10 => {}, + _ => {}, + } + + match 10 { + 1..10 => {}, + 9..=10 => {}, // { dg-warning "" "" { target *-*-* } } + _ => {}, + } + + match 10 { + 1..10 => {}, + 10..=10 => {}, + _ => {}, + } + + // These cases should generate "unreachable pattern" warnings. + match 10 { + 1..10 => {}, + 9 => {}, // { dg-warning "" "" { target *-*-* } } + _ => {}, + } + + match 10 { + 1..10 => {}, + 8..=9 => {}, // { dg-warning "" "" { target *-*-* } } + _ => {}, + } + + match 10 { + 5..7 => {}, + 6 => {}, // { dg-warning "" "" { target *-*-* } } + 1..10 => {}, + 9..=9 => {}, // { dg-warning "" "" { target *-*-* } } + 6 => {}, // { dg-warning "" "" { target *-*-* } } + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs new file mode 100644 index 000000000000..dc2438b8de31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs @@ -0,0 +1,12 @@ +// check-pass + +// This used to cause a stack overflow during exhaustiveness checking in the compiler. + +fn main() { + const LARGE_SIZE: usize = 1024 * 1024; + let [..] = [0u8; LARGE_SIZE]; + match [0u8; LARGE_SIZE] { + [..] => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-65413-constants-and-slices-exhaustiveness.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-65413-constants-and-slices-exhaustiveness.rs new file mode 100644 index 000000000000..dc903b2d4fc9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-65413-constants-and-slices-exhaustiveness.rs @@ -0,0 +1,16 @@ +// check-pass + +#![deny(unreachable_patterns)] + +const C0: &'static [u8] = b"\x00"; + +fn main() { + let x: &[u8] = &[0]; + match x { + &[] => {} + &[1..=255] => {} + C0 => {} + &[_, _, ..] => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-71930-type-of-match-scrutinee.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-71930-type-of-match-scrutinee.rs new file mode 100644 index 000000000000..0c7e7bacbc2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-71930-type-of-match-scrutinee.rs @@ -0,0 +1,23 @@ +// check-pass + +// In PR 71930, it was discovered that the code to retrieve the inferred type of a match scrutinee +// was incorrect. + +fn f() -> ! { + panic!() +} + +fn g() -> usize { + match f() { // Should infer type `bool` + false => 0, + true => 1, + } +} + +fn h() -> usize { + match f() { // Should infer type `!` + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-72476-associated-type.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-72476-associated-type.rs new file mode 100644 index 000000000000..242e571025c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-72476-associated-type.rs @@ -0,0 +1,23 @@ +// check-pass + +// From https://github.com/rust-lang/rust/issues/72476 + +trait A { + type Projection; +} + +impl A for () { + type Projection = bool; +} + +struct Next(T::Projection); + +fn f(item: Next<()>) { + match item { + Next(true) => {} + Next(false) => {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-78549-ref-pat-and-str.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-78549-ref-pat-and-str.rs new file mode 100644 index 000000000000..3869821ba368 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/issue-78549-ref-pat-and-str.rs @@ -0,0 +1,26 @@ +// check-pass +// From https://github.com/rust-lang/rust/issues/78549 + +fn main() { + match "foo" { + "foo" => {}, + &_ => {}, + } + + match "foo" { + &_ => {}, + "foo" => {}, + } + + match ("foo", 0, "bar") { + (&_, 0, &_) => {}, + ("foo", _, "bar") => {}, + (&_, _, &_) => {}, + } + + match (&"foo", "bar") { + (&"foo", &_) => {}, + (&&_, &_) => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-arm-statics-2.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-arm-statics-2.rs new file mode 100644 index 000000000000..f94bf3b56194 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-arm-statics-2.rs @@ -0,0 +1,63 @@ +use self::Direction::{North, East, South, West}; + +#[derive(PartialEq, Eq)] +struct NewBool(bool); + +#[derive(PartialEq, Eq)] +enum Direction { + North, + East, + South, + West +} + +const TRUE_TRUE: (bool, bool) = (true, true); + +fn nonexhaustive_1() { + match (true, false) { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + TRUE_TRUE => (), + (false, false) => (), + (false, true) => () + } +} + +const NONE: Option = None; +const EAST: Direction = East; + +fn nonexhaustive_2() { + match Some(Some(North)) { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + Some(NONE) => (), + Some(Some(North)) => (), + Some(Some(EAST)) => (), + Some(Some(South)) => (), + None => () + } +} + +const NEW_FALSE: NewBool = NewBool(false); +struct Foo { + bar: Option, + baz: NewBool +} + +const STATIC_FOO: Foo = Foo { bar: None, baz: NEW_FALSE }; + +fn nonexhaustive_3() { + match (Foo { bar: Some(North), baz: NewBool(true) }) { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + Foo { bar: None, baz: NewBool(true) } => (), + Foo { bar: _, baz: NEW_FALSE } => (), + Foo { bar: Some(West), baz: NewBool(true) } => (), + Foo { bar: Some(South), .. } => (), + Foo { bar: Some(EAST), .. } => () + } +} + +fn main() { + nonexhaustive_1(); + nonexhaustive_2(); + nonexhaustive_3(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-arm-statics.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-arm-statics.rs new file mode 100644 index 000000000000..bd62f5c26235 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-arm-statics.rs @@ -0,0 +1,70 @@ +#![allow(dead_code)] +#![deny(unreachable_patterns)] + +use self::Direction::{North, East, South, West}; + +#[derive(PartialEq, Eq)] +struct NewBool(bool); + +#[derive(PartialEq, Eq)] +enum Direction { + North, + East, + South, + West +} + +const TRUE_TRUE: (bool, bool) = (true, true); + +fn unreachable_1() { + match (true, false) { + TRUE_TRUE => (), + (false, false) => (), + (false, true) => (), + (true, false) => (), + (true, true) => () +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +const NONE: Option = None; +const EAST: Direction = East; + +fn unreachable_2() { + match Some(Some(North)) { + Some(NONE) => (), + Some(Some(North)) => (), + Some(Some(EAST)) => (), + Some(Some(South)) => (), + Some(Some(West)) => (), + Some(Some(East)) => (), +// { dg-error "" "" { target *-*-* } .-1 } + None => () + } +} + +const NEW_FALSE: NewBool = NewBool(false); +struct Foo { + bar: Option, + baz: NewBool +} + +fn unreachable_3() { + match (Foo { bar: Some(EAST), baz: NewBool(true) }) { + Foo { bar: None, baz: NewBool(true) } => (), + Foo { bar: _, baz: NEW_FALSE } => (), + Foo { bar: Some(West), baz: NewBool(true) } => (), + Foo { bar: Some(South), .. } => (), + Foo { bar: Some(EAST), .. } => (), + Foo { bar: Some(North), baz: NewBool(true) } => (), + Foo { bar: Some(EAST), baz: NewBool(false) } => () +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +fn main() { + unreachable_1(); + unreachable_2(); + unreachable_3(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-byte-array-patterns-2.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-byte-array-patterns-2.rs new file mode 100644 index 000000000000..84f6f28277f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-byte-array-patterns-2.rs @@ -0,0 +1,14 @@ +fn main() { + let buf = &[0, 1, 2, 3]; + + match buf { // { dg-error ".E0004." "" { target *-*-* } } + b"AAAA" => {} + } + + let buf: &[u8] = buf; + + match buf { // { dg-error ".E0004." "" { target *-*-* } } + b"AAAA" => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-byte-array-patterns.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-byte-array-patterns.rs new file mode 100644 index 000000000000..47b463c5d434 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-byte-array-patterns.rs @@ -0,0 +1,56 @@ +#![deny(unreachable_patterns)] + +fn main() { + let buf = &[0, 1, 2, 3]; + + match buf { + b"AAAA" => {}, + &[0x41, 0x41, 0x41, 0x41] => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + + match buf { + &[0x41, 0x41, 0x41, 0x41] => {} + b"AAAA" => {}, // { dg-error "" "" { target *-*-* } } + _ => {} + } + + match buf { + &[_, 0x41, 0x41, 0x41] => {}, + b"AAAA" => {}, // { dg-error "" "" { target *-*-* } } + _ => {} + } + + match buf { + &[0x41, .., 0x41] => {} + b"AAAA" => {}, // { dg-error "" "" { target *-*-* } } + _ => {} + } + + let buf: &[u8] = buf; + + match buf { + b"AAAA" => {}, + &[0x41, 0x41, 0x41, 0x41] => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + + match buf { + &[0x41, 0x41, 0x41, 0x41] => {} + b"AAAA" => {}, // { dg-error "" "" { target *-*-* } } + _ => {} + } + + match buf { + &[_, 0x41, 0x41, 0x41] => {}, + b"AAAA" => {}, // { dg-error "" "" { target *-*-* } } + _ => {} + } + + match buf { + &[0x41, .., 0x41] => {} + b"AAAA" => {}, // { dg-error "" "" { target *-*-* } } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-empty-exhaustive_patterns.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-empty-exhaustive_patterns.rs new file mode 100644 index 000000000000..bee9cf4dd17f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-empty-exhaustive_patterns.rs @@ -0,0 +1,94 @@ +#![feature(never_type)] +#![feature(exhaustive_patterns)] +#![deny(unreachable_patterns)] +enum Foo {} + +struct NonEmptyStruct(bool); // { dg-error "" "" { target *-*-* } } +union NonEmptyUnion1 { // { dg-error "" "" { target *-*-* } } + foo: (), +} +union NonEmptyUnion2 { // { dg-error "" "" { target *-*-* } } + foo: (), + bar: (), +} +enum NonEmptyEnum1 { // { dg-error "" "" { target *-*-* } } + Foo(bool), +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} +enum NonEmptyEnum2 { // { dg-error "" "" { target *-*-* } } + Foo(bool), +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + Bar, +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} +enum NonEmptyEnum5 { // { dg-error "" "" { target *-*-* } } + V1, V2, V3, V4, V5, +} + +macro_rules! match_empty { + ($e:expr) => { + match $e {} + }; +} +macro_rules! match_false { + ($e:expr) => { + match $e { + _ if false => {} + } + }; +} + +fn foo(x: Foo) { + match_empty!(x); // ok + match x { + _ => {}, // { dg-error "" "" { target *-*-* } } + } + match x { + _ if false => {}, // { dg-error "" "" { target *-*-* } } + } +} + +fn main() { + match None:: { + None => {} + Some(_) => {} // { dg-error "" "" { target *-*-* } } + } + match None:: { + None => {} + Some(_) => {} // { dg-error "" "" { target *-*-* } } + } + + match_empty!(0u8); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_empty!(NonEmptyStruct(true)); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_empty!((NonEmptyUnion1 { foo: () })); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_empty!((NonEmptyUnion2 { foo: () })); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_empty!(NonEmptyEnum1::Foo(true)); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_empty!(NonEmptyEnum2::Foo(true)); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_empty!(NonEmptyEnum5::V1); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + + match_false!(0u8); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_false!(NonEmptyStruct(true)); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_false!((NonEmptyUnion1 { foo: () })); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_false!((NonEmptyUnion2 { foo: () })); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_false!(NonEmptyEnum1::Foo(true)); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_false!(NonEmptyEnum2::Foo(true)); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_false!(NonEmptyEnum5::V1); +// { dg-error ".E0004." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-empty.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-empty.rs new file mode 100644 index 000000000000..7e3cdef9e6af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-empty.rs @@ -0,0 +1,93 @@ +#![feature(never_type)] +#![deny(unreachable_patterns)] +enum Foo {} + +struct NonEmptyStruct(bool); // { dg-error "" "" { target *-*-* } } +union NonEmptyUnion1 { // { dg-error "" "" { target *-*-* } } + foo: (), +} +union NonEmptyUnion2 { // { dg-error "" "" { target *-*-* } } + foo: (), + bar: (), +} +enum NonEmptyEnum1 { // { dg-error "" "" { target *-*-* } } + Foo(bool), +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} +enum NonEmptyEnum2 { // { dg-error "" "" { target *-*-* } } + Foo(bool), +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + Bar, +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} +enum NonEmptyEnum5 { // { dg-error "" "" { target *-*-* } } + V1, V2, V3, V4, V5, +} + +macro_rules! match_empty { + ($e:expr) => { + match $e {} + }; +} +macro_rules! match_false { + ($e:expr) => { + match $e { + _ if false => {} + } + }; +} + +fn foo(x: Foo) { + match_empty!(x); // ok + match_false!(x); // Not detected as unreachable nor exhaustive. +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match x { + _ => {}, // Not detected as unreachable, see #55123. + } +} + +fn main() { + // `exhaustive_patterns` is not on, so uninhabited branches are not detected as unreachable. + match None:: { + None => {} + Some(_) => {} + } + match None:: { + None => {} + Some(_) => {} + } + + match_empty!(0u8); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_empty!(NonEmptyStruct(true)); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_empty!((NonEmptyUnion1 { foo: () })); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_empty!((NonEmptyUnion2 { foo: () })); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_empty!(NonEmptyEnum1::Foo(true)); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_empty!(NonEmptyEnum2::Foo(true)); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_empty!(NonEmptyEnum5::V1); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + + match_false!(0u8); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_false!(NonEmptyStruct(true)); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_false!((NonEmptyUnion1 { foo: () })); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_false!((NonEmptyUnion2 { foo: () })); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_false!(NonEmptyEnum1::Foo(true)); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_false!(NonEmptyEnum2::Foo(true)); +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match_false!(NonEmptyEnum5::V1); +// { dg-error ".E0004." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-non-exhaustive.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-non-exhaustive.rs new file mode 100644 index 000000000000..7a1a4fd19d6b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-non-exhaustive.rs @@ -0,0 +1,5 @@ +fn main() { + match 0 { 1 => () } // { dg-error ".E0004." "" { target *-*-* } } + match 0 { 0 if false => () } // { dg-error ".E0004." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-privately-empty.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-privately-empty.rs new file mode 100644 index 000000000000..fac0815a067f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-privately-empty.rs @@ -0,0 +1,22 @@ +#![feature(never_type)] +#![feature(exhaustive_patterns)] + +mod private { + pub struct Private { + _bot: !, + pub misc: bool, + } + pub const DATA: Option = None; +} + +fn main() { + match private::DATA { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + None => {} + Some(private::Private { + misc: false, + .. + }) => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-range-fail-dominate.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-range-fail-dominate.rs new file mode 100644 index 000000000000..4be0420ba98b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-range-fail-dominate.rs @@ -0,0 +1,50 @@ +#![deny(unreachable_patterns, overlapping_patterns)] + +fn main() { + match 5 { + 1 ..= 10 => { } + 5 ..= 6 => { } +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} + }; + + match 5 { + 3 ..= 6 => { } + 4 ..= 6 => { } +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} + }; + + match 5 { + 4 ..= 6 => { } + 4 ..= 6 => { } +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} + }; + + match 'c' { + 'A' ..= 'z' => {} + 'a' ..= 'z' => {} +// { dg-error "" "" { target *-*-* } .-1 } + _ => {} + }; + + match 1.0f64 { + 0.01f64 ..= 6.5f64 => {} +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +// { dg-warning "" "" { target *-*-* } .-5 } +// { dg-warning "" "" { target *-*-* } .-6 } +// { dg-warning "" "" { target *-*-* } .-7 } +// { dg-warning "" "" { target *-*-* } .-8 } + 0.02f64 => {} // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + _ => {} + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-ref-ice.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-ref-ice.rs new file mode 100644 index 000000000000..8383123ba675 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-ref-ice.rs @@ -0,0 +1,17 @@ +#![deny(unreachable_patterns)] + +// The arity of `ref x` is always 1. If the pattern is compared to some non-structural type whose +// arity is always 0, an ICE occurs. +// +// Related issue: #23009 + +fn main() { + let homura = [1, 2, 3]; + + match homura { + [1, ref _madoka, 3] => (), + [1, 2, 3] => (), // { dg-error "" "" { target *-*-* } } + [_, _, _] => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-slice-patterns.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-slice-patterns.rs new file mode 100644 index 000000000000..b85c6d7377e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-slice-patterns.rs @@ -0,0 +1,13 @@ +fn check(list: &[Option<()>]) { + match list { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + &[] => {}, + &[_] => {}, + &[_, _] => {}, + &[_, None, ..] => {}, + &[.., Some(_), _] => {}, + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-vec-fixed.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-vec-fixed.rs new file mode 100644 index 000000000000..7ed3b455d39e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-vec-fixed.rs @@ -0,0 +1,19 @@ +#![deny(unreachable_patterns)] + +fn a() { + let v = [1, 2, 3]; + match v { + [_, _, _] => {} + [_, _, _] => {} // { dg-error "" "" { target *-*-* } } + } + match v { + [_, 1, _] => {} + [_, 1, _] => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } +} + +fn main() { + a(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-vec-unreachable.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-vec-unreachable.rs new file mode 100644 index 000000000000..8a9bed0c7c5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/match-vec-unreachable.rs @@ -0,0 +1,30 @@ +#![deny(unreachable_patterns)] + +fn main() { + let x: Vec<(isize, isize)> = Vec::new(); + let x: &[(isize, isize)] = &x; + match *x { + [a, (2, 3), _] => (), + [(1, 2), (2, 3), b] => (), // { dg-error "" "" { target *-*-* } } + _ => () + } + + let x: Vec = vec!["foo".to_string(), + "bar".to_string(), + "baz".to_string()]; + let x: &[String] = &x; + match *x { + [ref a, _, _, ..] => { println!("{}", a); } + [_, _, _, _, _] => { } // { dg-error "" "" { target *-*-* } } + _ => { } + } + + let x: Vec = vec!['a', 'b', 'c']; + let x: &[char] = &x; + match *x { + ['a', 'b', 'c', ref _tail @ ..] => {} + ['a', 'b', 'c'] => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/nested-exhaustive-match.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/nested-exhaustive-match.rs new file mode 100644 index 000000000000..7d68d793e9d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/nested-exhaustive-match.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct Foo { foo: bool, bar: Option, baz: isize } + +pub fn main() { + match (Foo{foo: true, bar: Some(10), baz: 20}) { + Foo{foo: true, bar: Some(_), ..} => {} + Foo{foo: false, bar: None, ..} => {} + Foo{foo: true, bar: None, ..} => {} + Foo{foo: false, bar: Some(_), ..} => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-defined-here.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-defined-here.rs new file mode 100644 index 000000000000..16514f0d1ded --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-defined-here.rs @@ -0,0 +1,73 @@ +// Test the "defined here" and "not covered" diagnostic hints. +// We also make sure that references are peeled off from the scrutinee type +// so that the diagnostics work better with default binding modes. + +#[derive(Clone)] +enum E { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-error "" "" { target *-*-* } .-6 } + A, + B, +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-error "" "" { target *-*-* } .-6 } + C +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-error "" "" { target *-*-* } .-6 } +} + +fn by_val(e: E) { + let e1 = e.clone(); + match e1 { // { dg-error ".E0004." "" { target *-*-* } } + E::A => {} + } + + let E::A = e; // { dg-error ".E0005." "" { target *-*-* } } +} + +fn by_ref_once(e: &E) { + match e { // { dg-error ".E0004." "" { target *-*-* } } + E::A => {} + } + + let E::A = e; // { dg-error ".E0005." "" { target *-*-* } } +} + +fn by_ref_thrice(e: & &mut &E) { + match e { // { dg-error ".E0004." "" { target *-*-* } } + E::A => {} + } + + let E::A = e; +// { dg-error ".E0005." "" { target *-*-* } .-1 } +} + +enum Opt { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + Some(u8), + None, +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn ref_pat(e: Opt) { + match e {// { dg-error ".E0004." "" { target *-*-* } } + Opt::Some(ref _x) => {} + } + + let Opt::Some(ref _x) = e; // { dg-error ".E0005." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-float-range-match.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-float-range-match.rs new file mode 100644 index 000000000000..b5a3d7e7b43b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-float-range-match.rs @@ -0,0 +1,14 @@ +#![allow(illegal_floating_point_literal_pattern)] +#![deny(unreachable_patterns)] + +fn main() { + match 0.0 { + 0.0..=1.0 => {} + _ => {} // ok + } + + match 0.0 { // { dg-error ".E0004." "" { target *-*-* } } + 0.0..=1.0 => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-match-nested.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-match-nested.rs new file mode 100644 index 000000000000..5764034ca2ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-match-nested.rs @@ -0,0 +1,20 @@ +enum T { A(U), B } +enum U { C, D } + +fn match_nested_vecs<'a, T>(l1: Option<&'a [T]>, l2: Result<&'a [T], ()>) -> &'static str { + match (l1, l2) { // { dg-error ".E0004." "" { target *-*-* } } + (Some(&[]), Ok(&[])) => "Some(empty), Ok(empty)", + (Some(&[_, ..]), Ok(_)) | (Some(&[_, ..]), Err(())) => "Some(non-empty), any", + (None, Ok(&[])) | (None, Err(())) | (None, Ok(&[_])) => "None, Ok(less than one element)", + (None, Ok(&[_, _, ..])) => "None, Ok(at least two elements)" + } +} + +fn main() { + let x = T::A(U::C); + match x { // { dg-error ".E0004." "" { target *-*-* } } + T::A(U::D) => { panic!("hello"); } + T::B => { panic!("goodbye"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-match.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-match.rs new file mode 100644 index 000000000000..b0ab32e40e00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-match.rs @@ -0,0 +1,64 @@ +#![allow(illegal_floating_point_literal_pattern)] + +enum T { A, B } + +fn main() { + let x = T::A; + match x { T::B => { } } // { dg-error ".E0004." "" { target *-*-* } } + match true { // { dg-error ".E0004." "" { target *-*-* } } + true => {} + } + match Some(10) { // { dg-error ".E0004." "" { target *-*-* } } + None => {} + } + match (2, 3, 4) { // { dg-error ".E0004." "" { target *-*-* } } + // and `(_, _, 5_i32..=i32::MAX)` not covered + (_, _, 4) => {} + } + match (T::A, T::A) { // { dg-error ".E0004." "" { target *-*-* } } + (T::A, T::B) => {} + (T::B, T::A) => {} + } + match T::A { // { dg-error ".E0004." "" { target *-*-* } } + T::A => {} + } + // This is exhaustive, though the algorithm got it wrong at one point + match (T::A, T::B) { + (T::A, _) => {} + (_, T::A) => {} + (T::B, T::B) => {} + } + let vec = vec![Some(42), None, Some(21)]; + let vec: &[Option] = &vec; + match *vec { // { dg-error ".E0004." "" { target *-*-* } } + [Some(..), None, ref tail @ ..] => {} + [Some(..), Some(..), ref tail @ ..] => {} + [None] => {} + } + let vec = vec![1]; + let vec: &[isize] = &vec; + match *vec { + [_, ref tail @ ..] => (), + [] => () + } + let vec = vec![0.5f32]; + let vec: &[f32] = &vec; + match *vec { // { dg-error ".E0004." "" { target *-*-* } } + [0.1, 0.2, 0.3] => (), + [0.1, 0.2] => (), + [0.1] => (), + [] => () + } + let vec = vec![Some(42), None, Some(21)]; + let vec: &[Option] = &vec; + match *vec { + [Some(..), None, ref tail @ ..] => {} + [Some(..), Some(..), ref tail @ ..] => {} + [None, None, ref tail @ ..] => {} + [None, Some(..), ref tail @ ..] => {} + [Some(_)] => {} + [None] => {} + [] => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.rs new file mode 100644 index 000000000000..9618b89ac2d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.rs @@ -0,0 +1,24 @@ +use std::{usize, isize}; + +fn main() { + match 0usize { +// { dg-error ".E0004." "" { target *-*-* } .-1 } +// { dg-note ".E0004." "" { target *-*-* } .-2 } +// { dg-note ".E0004." "" { target *-*-* } .-3 } +// { dg-note ".E0004." "" { target *-*-* } .-4 } + 0 ..= usize::MAX => {} + } + + match 0isize { +// { dg-error ".E0004." "" { target *-*-* } .-1 } +// { dg-note ".E0004." "" { target *-*-* } .-2 } +// { dg-note ".E0004." "" { target *-*-* } .-3 } +// { dg-note ".E0004." "" { target *-*-* } .-4 } + isize::MIN ..= isize::MAX => {} + } + + match 7usize {} +// { dg-error ".E0004." "" { target *-*-* } .-1 } +// { dg-note ".E0004." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs new file mode 100644 index 000000000000..34489395e095 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs @@ -0,0 +1,90 @@ +struct Foo { + first: bool, + second: Option<[usize; 4]> +} + +fn struct_with_a_nested_enum_and_vector() { + match (Foo { first: true, second: None }) { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + Foo { first: true, second: None } => (), + Foo { first: true, second: Some(_) } => (), + Foo { first: false, second: None } => (), + Foo { first: false, second: Some([1, 2, 3, 4]) } => () + } +} + +enum Color { + Red, + Green, + CustomRGBA { a: bool, r: u8, g: u8, b: u8 } +} + +fn enum_with_single_missing_variant() { + match Color::Red { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + Color::CustomRGBA { .. } => (), + Color::Green => () + } +} + +enum Direction { + North, East, South, West +} + +fn enum_with_multiple_missing_variants() { + match Direction::North { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + Direction::North => () + } +} + +enum ExcessiveEnum { + First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth, Eleventh, Twelfth +} + +fn enum_with_excessive_missing_variants() { + match ExcessiveEnum::First { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + + ExcessiveEnum::First => () + } +} + +fn enum_struct_variant() { + match Color::Red { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + Color::Red => (), + Color::Green => (), + Color::CustomRGBA { a: false, r: _, g: _, b: 0 } => (), + Color::CustomRGBA { a: false, r: _, g: _, b: _ } => () + } +} + +enum Enum { + First, + Second(bool) +} + +fn vectors_with_nested_enums() { + let x: &'static [Enum] = &[Enum::First, Enum::Second(false)]; + match *x { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [] => (), + [_] => (), + [Enum::First, _] => (), + [Enum::Second(true), Enum::First] => (), + [Enum::Second(true), Enum::Second(true)] => (), + [Enum::Second(false), _] => (), + [_, _, ref tail @ .., _] => () + } +} + +fn missing_nil() { + match ((), false) { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + ((), true) => () + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/refutable-pattern-errors.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/refutable-pattern-errors.rs new file mode 100644 index 000000000000..383ddfb526a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/refutable-pattern-errors.rs @@ -0,0 +1,10 @@ +// ignore-tidy-linelength + +fn func((1, (Some(1), 2..=3)): (isize, (Option, isize))) { } +// { dg-error ".E0005." "" { target *-*-* } .-1 } + +fn main() { + let (1, (Some(1), 2..=3)) = (1, (None, 2)); +// { dg-error ".E0005." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs new file mode 100644 index 000000000000..c9d23ceb80d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs @@ -0,0 +1,6 @@ +fn main() { + let f = |3: isize| println!("hello"); +// { dg-error ".E0005." "" { target *-*-* } .-1 } + f(4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-pattern-const-2.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-pattern-const-2.rs new file mode 100644 index 000000000000..40a24ab832ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-pattern-const-2.rs @@ -0,0 +1,32 @@ +#![deny(unreachable_patterns)] + +fn main() { + let s = &[0x00; 4][..]; //Slice of any value + const MAGIC_TEST: &[u32] = &[4, 5, 6, 7]; //Const slice to pattern match with + match s { + MAGIC_TEST => (), + [0x00, 0x00, 0x00, 0x00] => (), + [4, 5, 6, 7] => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + match s { + [0x00, 0x00, 0x00, 0x00] => (), + MAGIC_TEST => (), + [4, 5, 6, 7] => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + match s { + [0x00, 0x00, 0x00, 0x00] => (), + [4, 5, 6, 7] => (), + MAGIC_TEST => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + const FOO: [u32; 1] = [4]; + match [99] { + [0x00] => (), + [4] => (), + FOO => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-pattern-const-3.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-pattern-const-3.rs new file mode 100644 index 000000000000..41c4560a164f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-pattern-const-3.rs @@ -0,0 +1,32 @@ +#![deny(unreachable_patterns)] + +fn main() { + let s = &["0x00"; 4][..]; //Slice of any value + const MAGIC_TEST: &[&str] = &["4", "5", "6", "7"]; //Const slice to pattern match with + match s { + MAGIC_TEST => (), + ["0x00", "0x00", "0x00", "0x00"] => (), + ["4", "5", "6", "7"] => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + match s { + ["0x00", "0x00", "0x00", "0x00"] => (), + MAGIC_TEST => (), + ["4", "5", "6", "7"] => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + match s { + ["0x00", "0x00", "0x00", "0x00"] => (), + ["4", "5", "6", "7"] => (), + MAGIC_TEST => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + const FOO: [&str; 1] = ["boo"]; + match ["baa"] { + ["0x00"] => (), + ["boo"] => (), + FOO => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-pattern-const.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-pattern-const.rs new file mode 100644 index 000000000000..a2457ef7b898 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-pattern-const.rs @@ -0,0 +1,55 @@ +#![deny(unreachable_patterns)] + +fn main() { + let s = &[0x00; 4][..]; //Slice of any value + const MAGIC_TEST: &[u8] = b"TEST"; //Const slice to pattern match with + match s { + MAGIC_TEST => (), + [0x00, 0x00, 0x00, 0x00] => (), + [84, 69, 83, 84] => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + match s { + [0x00, 0x00, 0x00, 0x00] => (), + MAGIC_TEST => (), + [84, 69, 83, 84] => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + match s { + [0x00, 0x00, 0x00, 0x00] => (), + [84, 69, 83, 84] => (), + MAGIC_TEST => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + const FOO: [u8; 1] = [4]; + match [99] { + [0x00] => (), + [4] => (), + FOO => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } + const BAR: &[u8; 1] = &[4]; + match &[99] { + [0x00] => (), + [4] => (), + BAR => (), // { dg-error "" "" { target *-*-* } } + b"a" => (), + _ => (), + } + + const BOO: &[u8; 0] = &[]; + match &[] { + [] => (), + BOO => (), // { dg-error "" "" { target *-*-* } } + b"" => (), // { dg-error "" "" { target *-*-* } } + _ => (), // { dg-error "" "" { target *-*-* } } + } + + const CONST1: &[bool; 1] = &[true]; + match &[false] { + CONST1 => {} + [true] => {} // { dg-error "" "" { target *-*-* } } + [false] => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs new file mode 100644 index 000000000000..087fe5f89194 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs @@ -0,0 +1,130 @@ +fn main() { + let s: &[bool] = &[true; 0]; + let s1: &[bool; 1] = &[false; 1]; + let s2: &[bool; 2] = &[false; 2]; + let s3: &[bool; 3] = &[false; 3]; + let s10: &[bool; 10] = &[false; 10]; + + match s2 { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [true, .., true] => {} + } + match s3 { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [true, .., true] => {} + } + match s10 { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [true, .., true] => {} + } + + match s1 { + [true, ..] => {} + [.., false] => {} + } + match s2 { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [true, ..] => {} + [.., false] => {} + } + match s3 { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [true, ..] => {} + [.., false] => {} + } + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [] => {} + [true, ..] => {} + [.., false] => {} + } + + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [] => {} + } + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [] => {} + [_] => {} + } + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [] => {} + [true, ..] => {} + } + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [] => {} + [_] => {} + [true, ..] => {} + } + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [] => {} + [_] => {} + [.., true] => {} + } + + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [] => {} + [_] => {} + [_, _] => {} + [.., false] => {} + } + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + [] => {} + [_] => {} + [_, _] => {} + [false, .., false] => {} + } + + const CONST: &[bool] = &[true]; + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + &[true] => {} + } + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + CONST => {} + } + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + CONST => {} + &[false] => {} + } + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + &[false] => {} + CONST => {} + } + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + &[] => {} + CONST => {} + } + match s { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + &[] => {} + CONST => {} + &[_, _, ..] => {} + } + match s { + [] => {} + [false] => {} + CONST => {} + [_, _, ..] => {} + } + const CONST1: &[bool; 1] = &[true]; + match s1 { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + CONST1 => {} + } + match s1 { + CONST1 => {} + [false] => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-patterns-irrefutable.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-patterns-irrefutable.rs new file mode 100644 index 000000000000..e30df2ff5b4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-patterns-irrefutable.rs @@ -0,0 +1,27 @@ +// check-pass + +fn main() { + let s: &[bool] = &[true; 0]; + let s0: &[bool; 0] = &[]; + let s1: &[bool; 1] = &[false; 1]; + let s2: &[bool; 2] = &[false; 2]; + + let [] = s0; + let [_] = s1; + let [_, _] = s2; + + let [..] = s; + let [..] = s0; + let [..] = s1; + let [..] = s2; + + let [_, ..] = s1; + let [.., _] = s1; + let [_, ..] = s2; + let [.., _] = s2; + + let [_, _, ..] = s2; + let [_, .., _] = s2; + let [.., _, _] = s2; +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-patterns-reachability.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-patterns-reachability.rs new file mode 100644 index 000000000000..6372c30a6f5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/slice-patterns-reachability.rs @@ -0,0 +1,26 @@ +#![deny(unreachable_patterns)] + +fn main() { + let s: &[bool] = &[]; + + match s { + [true, ..] => {} + [true, ..] => {} // { dg-error "" "" { target *-*-* } } + [true] => {} // { dg-error "" "" { target *-*-* } } + [..] => {} + } + match s { + [.., true] => {} + [.., true] => {} // { dg-error "" "" { target *-*-* } } + [true] => {} // { dg-error "" "" { target *-*-* } } + [..] => {} + } + match s { + [false, .., true] => {} + [false, .., true] => {} // { dg-error "" "" { target *-*-* } } + [false, true] => {} // { dg-error "" "" { target *-*-* } } + [false] => {} + [..] => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/struct-like-enum-nonexhaustive.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/struct-like-enum-nonexhaustive.rs new file mode 100644 index 000000000000..4497f0501921 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/struct-like-enum-nonexhaustive.rs @@ -0,0 +1,13 @@ +enum A { + B { x: Option }, + C +} + +fn main() { + let x = A::B { x: Some(3) }; + match x { // { dg-error ".E0004." "" { target *-*-* } } + A::C => {} + A::B { x: None } => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/struct-pattern-match-useless.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/struct-pattern-match-useless.rs new file mode 100644 index 000000000000..6897f55e1fb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/struct-pattern-match-useless.rs @@ -0,0 +1,16 @@ +#![deny(unreachable_patterns)] + +struct Foo { + x: isize, + y: isize, +} + +pub fn main() { + let a = Foo { x: 1, y: 2 }; + match a { + Foo { x: _x, y: _y } => (), + Foo { .. } => () // { dg-error "" "" { target *-*-* } } + } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/top-level-alternation.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/top-level-alternation.rs new file mode 100644 index 000000000000..f2b28d923b2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/top-level-alternation.rs @@ -0,0 +1,57 @@ +#![deny(unreachable_patterns)] + +fn main() { + while let 0..=2 | 1 = 0 {} // { dg-error "" "" { target *-*-* } } + if let 0..=2 | 1 = 0 {} // { dg-error "" "" { target *-*-* } } + + match 0u8 { + 0 + | 0 => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + match Some(0u8) { + Some(0) + | Some(0) => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } + match (0u8, 0u8) { + (0, _) | (_, 0) => {} + (0, 0) => {} // { dg-error "" "" { target *-*-* } } + (1, 1) => {} + _ => {} + } + match (0u8, 0u8) { + (0, 1) | (2, 3) => {} + (0, 3) => {} + (2, 1) => {} + _ => {} + } + match (0u8, 0u8) { + (_, 0) | (_, 1) => {} + _ => {} + } + match (0u8, 0u8) { + (0, _) | (1, _) => {} + _ => {} + } + match Some(0u8) { + None | Some(_) => {} + _ => {} // { dg-error "" "" { target *-*-* } } + } + match Some(0u8) { + None | Some(_) => {} + Some(_) => {} // { dg-error "" "" { target *-*-* } } + None => {} // { dg-error "" "" { target *-*-* } } + } + match Some(0u8) { + Some(_) => {} + None => {} + None | Some(_) => {} // { dg-error "" "" { target *-*-* } } + } + match 0u8 { + 1 | 2 => {}, + 1..=2 => {}, // { dg-error "" "" { target *-*-* } } + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pattern/usefulness/tuple-struct-nonexhaustive.rs b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/tuple-struct-nonexhaustive.rs new file mode 100644 index 000000000000..bb66622ee36f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pattern/usefulness/tuple-struct-nonexhaustive.rs @@ -0,0 +1,10 @@ +struct Foo(isize, isize); + +fn main() { + let x = Foo(1, 2); + match x { // { dg-error ".E0004." "" { target *-*-* } } + Foo(1, b) => println!("{}", b), + Foo(2, b) => println!("{}", b) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/phantom-oibit.rs b/gcc/testsuite/rust/rustc/ui/phantom-oibit.rs new file mode 100644 index 000000000000..3b1210d8cda9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/phantom-oibit.rs @@ -0,0 +1,31 @@ +// Ensure that OIBIT checks `T` when it encounters a `PhantomData` field, instead of checking +// the `PhantomData` type itself (which almost always implements an auto trait) + +#![feature(optin_builtin_traits)] + +use std::marker::{PhantomData}; + +unsafe auto trait Zen {} + +unsafe impl<'a, T: 'a> Zen for &'a T where T: Sync {} + +struct Guard<'a, T: 'a> { + _marker: PhantomData<&'a T>, +} + +struct Nested(T); + +fn is_zen(_: T) {} + +fn not_sync(x: Guard) { + is_zen(x) +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn nested_not_sync(x: Nested>) { + is_zen(x) +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/placement-syntax.rs b/gcc/testsuite/rust/rustc/ui/placement-syntax.rs new file mode 100644 index 000000000000..109b070bd679 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/placement-syntax.rs @@ -0,0 +1,7 @@ +fn main() { + let x = -5; + if x<-1 { // { dg-error "" "" { target *-*-* } } + println!("ok"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/point-to-type-err-cause-on-impl-trait-return-2.rs b/gcc/testsuite/rust/rustc/ui/point-to-type-err-cause-on-impl-trait-return-2.rs new file mode 100644 index 000000000000..2c01c356edb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/point-to-type-err-cause-on-impl-trait-return-2.rs @@ -0,0 +1,18 @@ +fn unrelated() -> Result<(), std::string::ParseError> { // #57664 + let x = 0; + + match x { + 1 => { + let property_value_as_string = "a".parse()?; + } + 2 => { + let value: &bool = unsafe { &42 }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } + }; + + Ok(()) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/point-to-type-err-cause-on-impl-trait-return.rs b/gcc/testsuite/rust/rustc/ui/point-to-type-err-cause-on-impl-trait-return.rs new file mode 100644 index 000000000000..7d3dd117bc10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/point-to-type-err-cause-on-impl-trait-return.rs @@ -0,0 +1,102 @@ +fn foo() -> impl std::fmt::Display { + if false { + return 0i32; + } + 1u32 // { dg-error ".E0308." "" { target *-*-* } } +} + +fn bar() -> impl std::fmt::Display { + if false { + return 0i32; + } else { + return 1u32; // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn baz() -> impl std::fmt::Display { + if false { + return 0i32; + } else { + 1u32 // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn qux() -> impl std::fmt::Display { + if false { + 0i32 + } else { + 1u32 // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn bat() -> impl std::fmt::Display { + match 13 { + 0 => return 0i32, + _ => 1u32, // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn can() -> impl std::fmt::Display { + match 13 { // { dg-error ".E0308." "" { target *-*-* } } + 0 => return 0i32, + 1 => 1u32, + _ => 2u32, + } +} + +fn cat() -> impl std::fmt::Display { + match 13 { + 0 => { + return 0i32; + } + _ => { + 1u32 // { dg-error ".E0308." "" { target *-*-* } } + } + } +} + +fn dog() -> impl std::fmt::Display { + match 13 { + 0 => 0i32, + 1 => 1u32, // { dg-error ".E0308." "" { target *-*-* } } + _ => 2u32, + } +} + +fn hat() -> dyn std::fmt::Display { // { dg-error ".E0746." "" { target *-*-* } } + match 13 { + 0 => { + return 0i32; + } + _ => { + 1u32 + } + } +} + +fn pug() -> dyn std::fmt::Display { // { dg-error ".E0746." "" { target *-*-* } } + match 13 { + 0 => 0i32, + 1 => 1u32, // { dg-error ".E0308." "" { target *-*-* } } + _ => 2u32, + } +} + +fn man() -> dyn std::fmt::Display { // { dg-error ".E0746." "" { target *-*-* } } + if false { + 0i32 + } else { + 1u32 // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn apt() -> impl std::fmt::Display { + if let Some(42) = Some(42) { + 0i32 + } else { + 1u32 // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/fn.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/fn.rs new file mode 100644 index 000000000000..8e12d13c3534 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/fn.rs @@ -0,0 +1,30 @@ +// build-pass +// compile-flags:-Zpolymorphize=on -Zsymbol-mangling-version=v0 + +fn foo(f: impl Fn()) { + let x = |_: ()| (); + + // Don't use `f` in `y`, but refer to `x` so that the closure substs contain a reference to + // `x` that will differ for each instantiation despite polymorphisation of the varying + // argument. + let y = || x(()); + + // Consider `f` used in `foo`. + f(); + // Use `y` so that it is visited in monomorphisation collection. + y(); +} + +fn entry_a() { + foo(|| ()); +} + +fn entry_b() { + foo(|| ()); +} + +fn main() { + entry_a(); + entry_b(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/fnmut.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/fnmut.rs new file mode 100644 index 000000000000..1edfe0494f05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/fnmut.rs @@ -0,0 +1,35 @@ +// build-pass +// compile-flags:-Zpolymorphize=on -Zsymbol-mangling-version=v0 + +fn foo(f: impl Fn()) { + // Mutate an upvar from `x` so that it implements `FnMut`. + let mut outer = 3; + let mut x = |_: ()| { + outer = 4; + () + }; + + // Don't use `f` in `y`, but refer to `x` so that the closure substs contain a reference to + // `x` that will differ for each instantiation despite polymorphisation of the varying + // argument. + let mut y = || x(()); + + // Consider `f` used in `foo`. + f(); + // Use `y` so that it is visited in monomorphisation collection. + y(); +} + +fn entry_a() { + foo(|| ()); +} + +fn entry_b() { + foo(|| ()); +} + +fn main() { + entry_a(); + entry_b(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/fnonce.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/fnonce.rs new file mode 100644 index 000000000000..adac8ba25b32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/fnonce.rs @@ -0,0 +1,35 @@ +// build-pass +// compile-flags:-Zpolymorphize=on -Zsymbol-mangling-version=v0 + +fn foo(f: impl Fn()) { + // Move a non-copy type into `x` so that it implements `FnOnce`. + let outer = Vec::::new(); + let x = move |_: ()| { + let inner = outer; + () + }; + + // Don't use `f` in `y`, but refer to `x` so that the closure substs contain a reference to + // `x` that will differ for each instantiation despite polymorphisation of the varying + // argument. + let y = || x(()); + + // Consider `f` used in `foo`. + f(); + // Use `y` so that it is visited in monomorphisation collection. + y(); +} + +fn entry_a() { + foo(|| ()); +} + +fn entry_b() { + foo(|| ()); +} + +fn main() { + entry_a(); + entry_b(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/other.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/other.rs new file mode 100644 index 000000000000..91f2db2e2da7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/closure_in_upvar/other.rs @@ -0,0 +1,39 @@ +// build-pass +// compile-flags:-Zpolymorphize=on -Zsymbol-mangling-version=v0 + +fn y_uses_f(f: impl Fn()) { + let x = |_: ()| (); + + let y = || { + f(); + x(()); + }; + + f(); + y(); +} + +fn x_uses_f(f: impl Fn()) { + let x = |_: ()| { f(); }; + + let y = || x(()); + + f(); + y(); +} + +fn entry_a() { + x_uses_f(|| ()); + y_uses_f(|| ()); +} + +fn entry_b() { + x_uses_f(|| ()); + y_uses_f(|| ()); +} + +fn main() { + entry_a(); + entry_b(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/const_parameters/closures.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/const_parameters/closures.rs new file mode 100644 index 000000000000..baca2080efaa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/const_parameters/closures.rs @@ -0,0 +1,68 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(const_generics, rustc_attrs)] +// { dg-warning "" "" { target *-*-* } .-1 } + +// This test checks that the polymorphization analysis correctly detects unused const +// parameters in closures. + +// Function doesn't have any generic parameters to be unused. +#[rustc_polymorphize_error] +pub fn no_parameters() { + let _ = || {}; +} + +// Function has an unused generic parameter in parent and closure. +#[rustc_polymorphize_error] +pub fn unused() -> usize { +// { dg-error "" "" { target *-*-* } .-1 } + let add_one = |x: usize| x + 1; +// { dg-error "" "" { target *-*-* } .-1 } + add_one(3) +} + +// Function has an unused generic parameter in closure, but not in parent. +#[rustc_polymorphize_error] +pub fn used_parent() -> usize { + let x: usize = T; + let add_one = |x: usize| x + 1; +// { dg-error "" "" { target *-*-* } .-1 } + x + add_one(3) +} + +// Function uses generic parameter in value of a binding in closure. +#[rustc_polymorphize_error] +pub fn used_binding() -> usize { + let x = || { + let y: usize = T; + y + }; + + x() +} + +// Closure uses a value as an upvar, which used the generic parameter. +#[rustc_polymorphize_error] +pub fn unused_upvar() -> usize { + let x: usize = T; + let y = || x; +// { dg-error "" "" { target *-*-* } .-1 } + y() +} + +// Closure uses generic parameter in substitutions to another function. +#[rustc_polymorphize_error] +pub fn used_substs() -> usize { + let x = || unused::(); + x() +} + +fn main() { + no_parameters(); + let _ = unused::<1>(); + let _ = used_parent::<1>(); + let _ = used_binding::<1>(); + let _ = unused_upvar::<1>(); + let _ = used_substs::<1>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/const_parameters/functions.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/const_parameters/functions.rs new file mode 100644 index 000000000000..a61e3e46f555 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/const_parameters/functions.rs @@ -0,0 +1,38 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(const_generics, rustc_attrs)] +// { dg-warning "" "" { target *-*-* } .-1 } + +// This test checks that the polymorphization analysis correctly detects unused const +// parameters in functions. + +// Function doesn't have any generic parameters to be unused. +#[rustc_polymorphize_error] +pub fn no_parameters() {} + +// Function has an unused generic parameter. +#[rustc_polymorphize_error] +pub fn unused() { +// { dg-error "" "" { target *-*-* } .-1 } +} + +// Function uses generic parameter in value of a binding. +#[rustc_polymorphize_error] +pub fn used_binding() -> usize { + let x: usize = T; + x +} + +// Function uses generic parameter in substitutions to another function. +#[rustc_polymorphize_error] +pub fn used_substs() { + unused::() +} + +fn main() { + no_parameters(); + unused::<1>(); + used_binding::<1>(); + used_substs::<1>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/drop_shims/simple.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/drop_shims/simple.rs new file mode 100644 index 000000000000..7cc1a611c730 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/drop_shims/simple.rs @@ -0,0 +1,23 @@ +// check-pass +// compile-flags:-Zpolymorphize=on + +pub struct OnDrop(pub F); + +impl Drop for OnDrop { + fn drop(&mut self) { } +} + +fn foo( + _: R, + _: S, +) { + let bar = || { + let _ = OnDrop(|| ()); + }; + let _ = bar(); +} + +fn main() { + foo(3u32, || {}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/drop_shims/transitive.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/drop_shims/transitive.rs new file mode 100644 index 000000000000..b195dbda8b2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/drop_shims/transitive.rs @@ -0,0 +1,28 @@ +// check-pass +// compile-flags:-Zpolymorphize=on + +pub struct OnDrop(pub F); + +impl Drop for OnDrop { + fn drop(&mut self) { } +} + +fn bar(f: F) { + let _ = OnDrop(|| ()); + f() +} + +fn foo( + _: R, + _: S, +) { + let bar = || { + bar(|| {}) + }; + let _ = bar(); +} + +fn main() { + foo(3u32, || {}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/generators.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/generators.rs new file mode 100644 index 000000000000..c49f1998bdb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/generators.rs @@ -0,0 +1,95 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(const_generics, generators, generator_trait, rustc_attrs)] +// { dg-warning "" "" { target *-*-* } .-1 } + +use std::marker::Unpin; +use std::ops::{Generator, GeneratorState}; +use std::pin::Pin; + +enum YieldOrReturn { + Yield(Y), + Return(R), +} + +fn finish(mut t: T) -> Vec> +where + T: Generator<(), Yield = Y, Return = R> + Unpin, +{ + let mut results = Vec::new(); + loop { + match Pin::new(&mut t).resume(()) { + GeneratorState::Yielded(yielded) => results.push(YieldOrReturn::Yield(yielded)), + GeneratorState::Complete(returned) => { + results.push(YieldOrReturn::Return(returned)); + return results; + } + } + } +} + +// This test checks that the polymorphization analysis functions on generators. + +#[rustc_polymorphize_error] +pub fn unused_type() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { +// { dg-error "" "" { target *-*-* } .-1 } + || { +// { dg-error "" "" { target *-*-* } .-1 } + yield 1; + 2 + } +} + +#[rustc_polymorphize_error] +pub fn used_type_in_yield() -> impl Generator<(), Yield = Y, Return = u32> + Unpin { + || { + yield Y::default(); + 2 + } +} + +#[rustc_polymorphize_error] +pub fn used_type_in_return() -> impl Generator<(), Yield = u32, Return = R> + Unpin { + || { + yield 3; + R::default() + } +} + +#[rustc_polymorphize_error] +pub fn unused_const() -> impl Generator<(), Yield = u32, Return = u32> + Unpin { +// { dg-error "" "" { target *-*-* } .-1 } + || { +// { dg-error "" "" { target *-*-* } .-1 } + yield 1; + 2 + } +} + +#[rustc_polymorphize_error] +pub fn used_const_in_yield() -> impl Generator<(), Yield = u32, Return = u32> + Unpin +{ + || { + yield Y; + 2 + } +} + +#[rustc_polymorphize_error] +pub fn used_const_in_return() -> impl Generator<(), Yield = u32, Return = u32> + Unpin +{ + || { + yield 4; + R + } +} + +fn main() { + finish(unused_type::()); + finish(used_type_in_yield::()); + finish(used_type_in_return::()); + finish(unused_const::<1u32>()); + finish(used_const_in_yield::<1u32>()); + finish(used_const_in_return::<1u32>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/issue-74636.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/issue-74636.rs new file mode 100644 index 000000000000..95cb98450c44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/issue-74636.rs @@ -0,0 +1,17 @@ +// compile-flags:-Zpolymorphize=on +// build-pass + +use std::any::TypeId; + +pub fn foo(_: T) -> TypeId { + TypeId::of::() +} + +fn outer() { + foo(|| ()); +} + +fn main() { + outer::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/lifetimes.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/lifetimes.rs new file mode 100644 index 000000000000..2791f25ebcc3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/lifetimes.rs @@ -0,0 +1,26 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(rustc_attrs)] + +// This test checks that the polymorphization analysis doesn't break when the +// function/closure doesn't just have generic parameters. + +// Function has an unused generic parameter. +#[rustc_polymorphize_error] +pub fn unused<'a, T>(_: &'a u32) { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[rustc_polymorphize_error] +pub fn used<'a, T: Default>(_: &'a u32) -> u32 { + let _: T = Default::default(); + let add_one = |x: u32| x + 1; +// { dg-error "" "" { target *-*-* } .-1 } + add_one(3) +} + +fn main() { + unused::(&3); + used::(&3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/normalized_sig_types.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/normalized_sig_types.rs new file mode 100644 index 000000000000..3d7023847689 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/normalized_sig_types.rs @@ -0,0 +1,27 @@ +// build-pass +// compile-flags:-Zpolymorphize=on + +pub trait ParallelIterator: Sized { + fn drive>(_: C) { + C::into_folder(); + } +} + +pub trait Consumer: Sized { + type Result; + fn into_folder() -> Self::Result; +} + +impl ParallelIterator for () {} + +impl Consumer for F { + type Result = (); + fn into_folder() -> Self::Result { + unimplemented!() + } +} + +fn main() { + <()>::drive(|| ()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/predicates.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/predicates.rs new file mode 100644 index 000000000000..f5fede32d91e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/predicates.rs @@ -0,0 +1,90 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(rustc_attrs)] + +// This test checks that `T` is considered used in `foo`, because it is used in a predicate for +// `I`, which is used. + +#[rustc_polymorphize_error] +fn bar() { +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[rustc_polymorphize_error] +fn foo(_: I) +where + I: Iterator, +{ + bar::() +} + +#[rustc_polymorphize_error] +fn baz(_: I) +where + std::iter::Repeat: Iterator, +{ + bar::() +} + +// In addition, check that `I` is considered used in `next::{{closure}}`, because `T` is used and +// `T` is really just `I::Item`. `E` is used due to the fixed-point marking of predicates. + +pub(crate) struct Foo<'a, I, E>(I, &'a E); + +impl<'a, I, T: 'a, E> Iterator for Foo<'a, I, E> +where + I: Iterator, +{ + type Item = T; + + #[rustc_polymorphize_error] + fn next(&mut self) -> Option { + self.find(|_| true) + } +} + +// Furthermore, check that `B` is considered used because `C` is used, and that `A` is considered +// used because `B` is now used. + +trait Baz {} + +impl Baz for u8 {} +impl Baz for u16 {} + +#[rustc_polymorphize_error] +fn quux() -> usize +where + A: Baz, + B: Baz, +{ + std::mem::size_of::() +} + +// Finally, check that `F` is considered used because `G` is used when neither are in the self-ty +// of the predicate. + +trait Foobar {} + +impl Foobar for () {} + +#[rustc_polymorphize_error] +fn foobar() -> usize +where + (): Foobar, +{ + std::mem::size_of::() +} + +fn main() { + let x = &[2u32]; + foo(x.iter()); + baz(x.iter()); + + let mut a = Foo([(1u32, 1u16)].iter(), &1u16); + let _ = a.next(); + + let _ = quux::(); + + let _ = foobar::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function-1.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function-1.rs new file mode 100644 index 000000000000..777e341f23c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function-1.rs @@ -0,0 +1,13 @@ +// build-fail +// compile-flags: -Zpolymorphize=on +#![crate_type = "lib"] +#![feature(rustc_attrs)] + +fn foo<'a>(_: &'a ()) {} + +#[rustc_polymorphize_error] +pub fn test() { +// { dg-error "" "" { target *-*-* } .-1 } + foo(&()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function-2.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function-2.rs new file mode 100644 index 000000000000..9c1582ef67df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function-2.rs @@ -0,0 +1,17 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![crate_type = "lib"] +#![feature(lazy_normalization_consts, rustc_attrs)] +// { dg-warning "" "" { target *-*-* } .-1 } + +#[rustc_polymorphize_error] +fn test() { +// { dg-error "" "" { target *-*-* } .-1 } + let x = [0; 3 + 4]; +} + +pub fn caller() { + test::(); + test::>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function-3.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function-3.rs new file mode 100644 index 000000000000..d58c69298646 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function-3.rs @@ -0,0 +1,15 @@ +// run-pass +// compile-flags: -Zpolymorphize=on -Zmir-opt-level=3 + +fn caller() -> &'static usize { + callee::() +} + +fn callee() -> &'static usize { + &std::mem::size_of::() +} + +fn main() { + assert_eq!(caller::<(), ()>(), &0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function.rs new file mode 100644 index 000000000000..4fb97be60fee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/promoted-function.rs @@ -0,0 +1,16 @@ +// run-pass +// compile-flags:-Zpolymorphize=on + +fn fop() {} + +fn bar() -> &'static fn() { + &(fop:: as fn()) +} +pub const FN: &'static fn() = &(fop:: as fn()); + +fn main() { + bar::(); + bar::(); + (FN)(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/symbol-ambiguity.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/symbol-ambiguity.rs new file mode 100644 index 000000000000..ceba601c9d7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/symbol-ambiguity.rs @@ -0,0 +1,23 @@ +// build-pass +// compile-flags: -Zpolymorphize=on -Zsymbol-mangling-version=v0 + +pub(crate) struct Foo<'a, I, E>(I, &'a E); + +impl<'a, I, T: 'a, E> Iterator for Foo<'a, I, E> +where + I: Iterator, +{ + type Item = T; + + fn next(&mut self) -> Option { + self.find(|_| true) + } +} + +fn main() { + let mut a = Foo([(1u32, 1u16)].iter(), &1u16); + let mut b = Foo([(1u16, 1u32)].iter(), &1u32); + let _ = a.next(); + let _ = b.next(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/too-many-generic-params.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/too-many-generic-params.rs new file mode 100644 index 000000000000..8b0a75d83d40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/too-many-generic-params.rs @@ -0,0 +1,86 @@ +// build-pass +#![feature(rustc_attrs)] + +// This test checks that the analysis doesn't panic when there are >64 generic parameters, but +// instead considers those parameters used. + +#[rustc_polymorphize_error] +fn bar() +{ + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option

= None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; + let _: Option = None; +} + +fn main() { + bar::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/type_parameters/closures.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/type_parameters/closures.rs new file mode 100644 index 000000000000..e1ad9261f741 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/type_parameters/closures.rs @@ -0,0 +1,162 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(stmt_expr_attributes, rustc_attrs)] + +// This test checks that the polymorphization analysis correctly detects unused type +// parameters in closures. + +// Function doesn't have any generic parameters to be unused. +#[rustc_polymorphize_error] +pub fn no_parameters() { + let _ = || {}; +} + +// Function has an unused generic parameter in parent and closure. +#[rustc_polymorphize_error] +pub fn unused() -> u32 { +// { dg-error "" "" { target *-*-* } .-1 } + + let add_one = |x: u32| x + 1; +// { dg-error "" "" { target *-*-* } .-1 } + add_one(3) +} + +// Function has an unused generic parameter in closure, but not in parent. +#[rustc_polymorphize_error] +pub fn used_parent() -> u32 { + let _: T = Default::default(); + let add_one = |x: u32| x + 1; +// { dg-error "" "" { target *-*-* } .-1 } + add_one(3) +} + +// Function uses generic parameter in value of a binding in closure. +#[rustc_polymorphize_error] +pub fn used_binding_value() -> T { + let x = || { + let y: T = Default::default(); + y + }; + + x() +} + +// Function uses generic parameter in generic of a binding in closure. +#[rustc_polymorphize_error] +pub fn used_binding_generic() -> Option { + let x = || { + let y: Option = None; + y + }; + + x() +} + +// Function and closure uses generic parameter in argument. +#[rustc_polymorphize_error] +pub fn used_argument(t: T) -> u32 { + let x = |_: T| 3; + x(t) +} + +// Closure uses generic parameter in argument. +#[rustc_polymorphize_error] +pub fn used_argument_closure() -> u32 { + let t: T = Default::default(); + + let x = |_: T| 3; + x(t) +} + +// Closure uses generic parameter as upvar. +#[rustc_polymorphize_error] +pub fn used_upvar() -> T { + let x: T = Default::default(); + + let y = || x; + y() +} + +// Closure uses generic parameter in substitutions to another function. +#[rustc_polymorphize_error] +pub fn used_substs() -> u32 { + let x = || unused::(); + x() +} + +struct Foo(F); + +impl Foo { + // Function has an unused generic parameter from impl and fn. + #[rustc_polymorphize_error] + pub fn unused_all() -> u32 { +// { dg-error "" "" { target *-*-* } .-1 } + let add_one = |x: u32| x + 1; +// { dg-error "" "" { target *-*-* } .-1 } + add_one(3) + } + + // Function uses generic parameter from impl and fn in closure. + #[rustc_polymorphize_error] + pub fn used_both() -> u32 { + let add_one = |x: u32| { + let _: F = Default::default(); + let _: G = Default::default(); + x + 1 + }; + + add_one(3) + } + + // Function uses generic parameter from fn in closure. + #[rustc_polymorphize_error] + pub fn used_fn() -> u32 { +// { dg-error "" "" { target *-*-* } .-1 } + let add_one = |x: u32| { +// { dg-error "" "" { target *-*-* } .-1 } + let _: G = Default::default(); + x + 1 + }; + + add_one(3) + } + + // Function uses generic parameter from impl in closure. + #[rustc_polymorphize_error] + pub fn used_impl() -> u32 { +// { dg-error "" "" { target *-*-* } .-1 } + let add_one = |x: u32| { +// { dg-error "" "" { target *-*-* } .-1 } + let _: F = Default::default(); + x + 1 + }; + + add_one(3) + } + + // Closure uses generic parameter in substitutions to another function. + #[rustc_polymorphize_error] + pub fn used_substs() -> u32 { + let x = || unused::(); + x() + } +} + +fn main() { + no_parameters(); + let _ = unused::(); + let _ = used_parent::(); + let _ = used_binding_value::(); + let _ = used_binding_generic::(); + let _ = used_argument(3u32); + let _ = used_argument_closure::(); + let _ = used_upvar::(); + let _ = used_substs::(); + + let _ = Foo::::unused_all::(); + let _ = Foo::::used_both::(); + let _ = Foo::::used_impl::(); + let _ = Foo::::used_fn::(); + let _ = Foo::::used_substs(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/type_parameters/functions.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/type_parameters/functions.rs new file mode 100644 index 000000000000..6e7d5c5b19b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/type_parameters/functions.rs @@ -0,0 +1,97 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(rustc_attrs)] + +// This test checks that the polymorphization analysis correctly detects unused type +// parameters in functions. + +// Function doesn't have any generic parameters to be unused. +#[rustc_polymorphize_error] +pub fn no_parameters() {} + +// Function has an unused generic parameter. +#[rustc_polymorphize_error] +pub fn unused() { +// { dg-error "" "" { target *-*-* } .-1 } +} + +// Function uses generic parameter in value of a binding. +#[rustc_polymorphize_error] +pub fn used_binding_value() { + let _: T = Default::default(); +} + +// Function uses generic parameter in generic of a binding. +#[rustc_polymorphize_error] +pub fn used_binding_generic() { + let _: Option = None; +} + +// Function uses generic parameter in argument. +#[rustc_polymorphize_error] +pub fn used_argument(_: T) {} + +// Function uses generic parameter in substitutions to another function. +#[rustc_polymorphize_error] +pub fn used_substs() { + unused::() +} + +struct Foo(F); + +impl Foo { + // Function has an unused generic parameter from impl. + #[rustc_polymorphize_error] + pub fn unused_impl() { +// { dg-error "" "" { target *-*-* } .-1 } + } + + // Function has an unused generic parameter from impl and fn. + #[rustc_polymorphize_error] + pub fn unused_both() { +// { dg-error "" "" { target *-*-* } .-1 } + } + + // Function uses generic parameter from impl. + #[rustc_polymorphize_error] + pub fn used_impl() { + let _: F = Default::default(); + } + + // Function uses generic parameter from impl. + #[rustc_polymorphize_error] + pub fn used_fn() { +// { dg-error "" "" { target *-*-* } .-1 } + let _: G = Default::default(); + } + + // Function uses generic parameter from impl. + #[rustc_polymorphize_error] + pub fn used_both() { + let _: F = Default::default(); + let _: G = Default::default(); + } + + // Function uses generic parameter in substitutions to another function. + #[rustc_polymorphize_error] + pub fn used_substs() { + unused::() + } +} + +fn main() { + no_parameters(); + unused::(); + used_binding_value::(); + used_binding_generic::(); + used_argument(3u32); + used_substs::(); + + Foo::::unused_impl(); + Foo::::unused_both::(); + Foo::::used_impl(); + Foo::::used_fn::(); + Foo::::used_both::(); + Foo::::used_substs(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/polymorphization/unsized_cast.rs b/gcc/testsuite/rust/rustc/ui/polymorphization/unsized_cast.rs new file mode 100644 index 000000000000..8b2acc955f52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/polymorphization/unsized_cast.rs @@ -0,0 +1,31 @@ +// build-fail +// compile-flags:-Zpolymorphize=on +#![feature(fn_traits, rustc_attrs, unboxed_closures)] + +// This test checks that the polymorphization analysis considers a closure +// as using all generic parameters if it does an unsizing cast. + +#[rustc_polymorphize_error] +fn foo() { + let _: T = Default::default(); + (|| Box::new(|| {}) as Box)(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +#[rustc_polymorphize_error] +fn foo2() { + let _: T = Default::default(); + (|| { +// { dg-error "" "" { target *-*-* } .-1 } + let call: extern "rust-call" fn(_, _) = Fn::call; + call(&|| {}, ()); +// { dg-error "" "" { target *-*-* } .-1 } + })(); +} + +fn main() { + foo::(); + foo2::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pptypedef.rs b/gcc/testsuite/rust/rustc/ui/pptypedef.rs new file mode 100644 index 000000000000..659649823a7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pptypedef.rs @@ -0,0 +1,12 @@ +fn let_in(x: T, f: F) where F: FnOnce(T) {} + +fn main() { + let_in(3u32, |i| { assert!(i == 3i32); }); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + let_in(3i32, |i| { assert!(i == 3u32); }); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/precise_pointer_size_matching.rs b/gcc/testsuite/rust/rustc/ui/precise_pointer_size_matching.rs new file mode 100644 index 000000000000..f8865ea500d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/precise_pointer_size_matching.rs @@ -0,0 +1,34 @@ +// normalize-stderr-32bit: "-2147483648isize" -> "$$ISIZE_MIN" +// normalize-stderr-64bit: "-9223372036854775808isize" -> "$$ISIZE_MIN" +// normalize-stderr-32bit: "2147483647isize" -> "$$ISIZE_MAX" +// normalize-stderr-64bit: "9223372036854775807isize" -> "$$ISIZE_MAX" +// normalize-stderr-32bit: "4294967295usize" -> "$$USIZE_MAX" +// normalize-stderr-64bit: "18446744073709551615usize" -> "$$USIZE_MAX" + +#![feature(precise_pointer_size_matching)] +#![feature(exclusive_range_pattern)] + +#![deny(unreachable_patterns, overlapping_patterns)] + +use std::{usize, isize}; + +fn main() { + match 0isize { + isize::MIN ..= isize::MAX => {} // ok + } + + match 0usize { + 0 ..= usize::MAX => {} // ok + } + + match 0isize { // { dg-error ".E0004." "" { target *-*-* } } + 1 ..= 8 => {} + -5 ..= 20 => {} + } + + match 0usize { // { dg-error ".E0004." "" { target *-*-* } } + 1 ..= 8 => {} + 5 ..= 20 => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/prim-with-args.rs b/gcc/testsuite/rust/rustc/ui/prim-with-args.rs new file mode 100644 index 000000000000..6f68bf448afa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/prim-with-args.rs @@ -0,0 +1,28 @@ +fn main() { + +let x: isize; // { dg-error ".E0109." "" { target *-*-* } } +let x: i8; // { dg-error ".E0109." "" { target *-*-* } } +let x: i16; // { dg-error ".E0109." "" { target *-*-* } } +let x: i32; // { dg-error ".E0109." "" { target *-*-* } } +let x: i64; // { dg-error ".E0109." "" { target *-*-* } } +let x: usize; // { dg-error ".E0109." "" { target *-*-* } } +let x: u8; // { dg-error ".E0109." "" { target *-*-* } } +let x: u16; // { dg-error ".E0109." "" { target *-*-* } } +let x: u32; // { dg-error ".E0109." "" { target *-*-* } } +let x: u64; // { dg-error ".E0109." "" { target *-*-* } } +let x: char; // { dg-error ".E0109." "" { target *-*-* } } + +let x: isize<'static>; // { dg-error ".E0109." "" { target *-*-* } } +let x: i8<'static>; // { dg-error ".E0109." "" { target *-*-* } } +let x: i16<'static>; // { dg-error ".E0109." "" { target *-*-* } } +let x: i32<'static>; // { dg-error ".E0109." "" { target *-*-* } } +let x: i64<'static>; // { dg-error ".E0109." "" { target *-*-* } } +let x: usize<'static>; // { dg-error ".E0109." "" { target *-*-* } } +let x: u8<'static>; // { dg-error ".E0109." "" { target *-*-* } } +let x: u16<'static>; // { dg-error ".E0109." "" { target *-*-* } } +let x: u32<'static>; // { dg-error ".E0109." "" { target *-*-* } } +let x: u64<'static>; // { dg-error ".E0109." "" { target *-*-* } } +let x: char<'static>; // { dg-error ".E0109." "" { target *-*-* } } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/primitive-binop-lhs-mut.rs b/gcc/testsuite/rust/rustc/ui/primitive-binop-lhs-mut.rs new file mode 100644 index 000000000000..7a545c17f9a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/primitive-binop-lhs-mut.rs @@ -0,0 +1,7 @@ +// run-pass + +fn main() { + let x = Box::new(0); + assert_eq!(0, *x + { drop(x); let _ = Box::new(main); 0 }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/print-fuel/print-fuel.rs b/gcc/testsuite/rust/rustc/ui/print-fuel/print-fuel.rs new file mode 100644 index 000000000000..f4713ab68eec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print-fuel/print-fuel.rs @@ -0,0 +1,14 @@ +#![crate_name="foo"] +#![allow(dead_code)] + +// (#55495: The --error-format is to sidestep an issue in our test harness) +// compile-flags: --error-format human -Z print-fuel=foo +// build-pass (FIXME(62277): could be check-pass?) + +struct S1(u8, u16, u8); +struct S2(u8, u16, u8); +struct S3(u8, u16, u8); + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/print-stdout-eprint-stderr.rs b/gcc/testsuite/rust/rustc/ui/print-stdout-eprint-stderr.rs new file mode 100644 index 000000000000..829cbb0529db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print-stdout-eprint-stderr.rs @@ -0,0 +1,34 @@ +// run-pass +// ignore-cloudabi spawning processes is not supported +// ignore-emscripten spawning processes is not supported +// ignore-sgx no processes + +use std::{env, process}; + +fn child() { + print!("[stdout 0]"); + print!("[stdout {}]", 1); + println!("[stdout {}]", 2); + println!(); + eprint!("[stderr 0]"); + eprint!("[stderr {}]", 1); + eprintln!("[stderr {}]", 2); + eprintln!(); +} + +fn parent() { + let this = env::args().next().unwrap(); + let output = process::Command::new(this).arg("-").output().unwrap(); + assert!(output.status.success()); + + let stdout = String::from_utf8(output.stdout).unwrap(); + let stderr = String::from_utf8(output.stderr).unwrap(); + + assert_eq!(stdout, "[stdout 0][stdout 1][stdout 2]\n\n"); + assert_eq!(stderr, "[stderr 0][stderr 1][stderr 2]\n\n"); +} + +fn main() { + if env::args().count() == 2 { child() } else { parent() } +} + diff --git a/gcc/testsuite/rust/rustc/ui/print_type_sizes/anonymous.rs b/gcc/testsuite/rust/rustc/ui/print_type_sizes/anonymous.rs new file mode 100644 index 000000000000..e93088f068ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print_type_sizes/anonymous.rs @@ -0,0 +1,24 @@ +// compile-flags: -Z print-type-sizes +// build-pass + +// All of the types that occur in this function are uninteresting, in +// that one cannot control the sizes of these types with the same sort +// of enum-variant manipulation tricks. + +#![feature(start)] + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _byte: u8 = 0; + let _word: usize = 0; + let _tuple: (u8, usize)= (0, 0); + let _array: [u8; 128] = [0; 128]; + let _fn: fn (u8) -> u8 = id; + let _diverging: fn (u8) -> ! = bye; + + fn id(x: u8) -> u8 { x }; + fn bye(_: u8) -> ! { loop { } } + + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/print_type_sizes/generics.rs b/gcc/testsuite/rust/rustc/ui/print_type_sizes/generics.rs new file mode 100644 index 000000000000..2936ddea1196 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print_type_sizes/generics.rs @@ -0,0 +1,72 @@ +// compile-flags: -Z print-type-sizes +// build-pass +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. +// FIXME: consider using an attribute instead of side-effects. + +// This file illustrates how generics are handled: types have to be +// monomorphized, in the MIR of the original function in which they +// occur, to have their size reported. + +#![feature(start)] + +// In an ad-hoc attempt to avoid the injection of unwinding code +// (which clutters the output of `-Z print-type-sizes` with types from +// `unwind::libunwind`): +// +// * I am not using Default to build values because that seems to +// cause the injection of unwinding code. (Instead I just make `fn new` +// methods.) +// +// * Pair derive Copy to ensure that we don't inject +// unwinding code into generic uses of Pair when T itself is also +// Copy. +// +// (I suspect this reflect some naivety within the rust compiler +// itself; it should be checking for drop glue, i.e., a destructor +// somewhere in the monomorphized types. It should not matter whether +// the type is Copy.) +#[derive(Copy, Clone)] +pub struct Pair { + _car: T, + _cdr: T, +} + +impl Pair { + fn new(a: T, d: T) -> Self { + Pair { + _car: a, + _cdr: d, + } + } +} + +#[derive(Copy, Clone)] +pub struct SevenBytes([u8; 7]); +pub struct FiftyBytes([u8; 50]); + +pub struct ZeroSized; + +impl SevenBytes { + fn new() -> Self { SevenBytes([0; 7]) } +} + +impl FiftyBytes { + fn new() -> Self { FiftyBytes([0; 50]) } +} + +pub fn f1(x: T) { + let _v: Pair = Pair::new(x, x); + let _v2: Pair = + Pair::new(FiftyBytes::new(), FiftyBytes::new()); +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _b: Pair = Pair::new(0, 0); + let _s: Pair = Pair::new(SevenBytes::new(), SevenBytes::new()); + let ref _z: ZeroSized = ZeroSized; + f1::(SevenBytes::new()); + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/print_type_sizes/multiple_types.rs b/gcc/testsuite/rust/rustc/ui/print_type_sizes/multiple_types.rs new file mode 100644 index 000000000000..5e0865626108 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print_type_sizes/multiple_types.rs @@ -0,0 +1,24 @@ +// compile-flags: -Z print-type-sizes +// build-pass + +// This file illustrates that when multiple structural types occur in +// a function, every one of them is included in the output. + +#![feature(start)] + +pub struct SevenBytes([u8; 7]); +pub struct FiftyBytes([u8; 50]); + +pub enum Enum { + Small(SevenBytes), + Large(FiftyBytes), +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _e: Enum; + let _f: FiftyBytes; + let _s: SevenBytes; + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/print_type_sizes/niche-filling.rs b/gcc/testsuite/rust/rustc/ui/print_type_sizes/niche-filling.rs new file mode 100644 index 000000000000..0f7abf7e3246 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print_type_sizes/niche-filling.rs @@ -0,0 +1,94 @@ +// compile-flags: -Z print-type-sizes +// build-pass +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. +// FIXME: consider using an attribute instead of side-effects. + +// This file illustrates how niche-filling enums are handled, +// modelled after cases like `Option<&u32>`, `Option` and such. +// +// It uses NonZeroU32 rather than `&_` or `Unique<_>`, because +// the test is not set up to deal with target-dependent pointer width. +// +// It avoids using u64/i64 because on some targets that is only 4-byte +// aligned (while on most it is 8-byte aligned) and so the resulting +// padding and overall computed sizes can be quite different. + +#![feature(start)] +#![allow(dead_code)] + +use std::num::NonZeroU32; + +pub enum MyOption { None, Some(T) } + +impl Default for MyOption { + fn default() -> Self { MyOption::None } +} + +pub enum EmbeddedDiscr { + None, + Record { pre: u8, val: NonZeroU32, post: u16 }, +} + +impl Default for EmbeddedDiscr { + fn default() -> Self { EmbeddedDiscr::None } +} + +#[derive(Default)] +pub struct IndirectNonZero { + pre: u8, + nested: NestedNonZero, + post: u16, +} + +pub struct NestedNonZero { + pre: u8, + val: NonZeroU32, + post: u16, +} + +impl Default for NestedNonZero { + fn default() -> Self { + NestedNonZero { pre: 0, val: NonZeroU32::new(1).unwrap(), post: 0 } + } +} + +pub enum Enum4 { + One(A), + Two(B), + Three(C), + Four(D) +} + +pub union Union1 { + a: A, +} + +pub union Union2 { + a: A, + b: B, +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _x: MyOption = Default::default(); + let _y: EmbeddedDiscr = Default::default(); + let _z: MyOption = Default::default(); + let _a: MyOption = Default::default(); + let _b: MyOption = Default::default(); + let _c: MyOption = Default::default(); + let _b: MyOption> = Default::default(); + let _e: Enum4<(), char, (), ()> = Enum4::One(()); + let _f: Enum4<(), (), bool, ()> = Enum4::One(()); + let _g: Enum4<(), (), (), MyOption> = Enum4::One(()); + + // Unions do not currently participate in niche filling. + let _h: MyOption> = Default::default(); + + // ...even when theoretically possible. + let _i: MyOption> = Default::default(); + let _j: MyOption> = Default::default(); + + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/print_type_sizes/no_duplicates.rs b/gcc/testsuite/rust/rustc/ui/print_type_sizes/no_duplicates.rs new file mode 100644 index 000000000000..51d2547fedd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print_type_sizes/no_duplicates.rs @@ -0,0 +1,24 @@ +// compile-flags: -Z print-type-sizes +// build-pass +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. +// FIXME: consider using an attribute instead of side-effects. + +// This file illustrates that when the same type occurs repeatedly +// (even if multiple functions), it is only printed once in the +// print-type-sizes output. + +#![feature(start)] + +pub struct SevenBytes([u8; 7]); + +pub fn f1() { + let _s: SevenBytes = SevenBytes([0; 7]); +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _s: SevenBytes = SevenBytes([0; 7]); + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/print_type_sizes/packed.rs b/gcc/testsuite/rust/rustc/ui/print_type_sizes/packed.rs new file mode 100644 index 000000000000..ee5165965c73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print_type_sizes/packed.rs @@ -0,0 +1,70 @@ +// compile-flags: -Z print-type-sizes +// build-pass +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. +// FIXME: consider using an attribute instead of side-effects. + +// This file illustrates how packing is handled; it should cause +// the elimination of padding that would normally be introduced +// to satisfy alignment desirata. +// +// It avoids using u64/i64 because on some targets that is only 4-byte +// aligned (while on most it is 8-byte aligned) and so the resulting +// padding and overall computed sizes can be quite different. + +#![allow(dead_code)] +#![feature(start)] + +#[derive(Default)] +#[repr(packed)] +struct Packed1 { + a: u8, + b: u8, + g: i32, + c: u8, + h: i16, + d: u8, +} + +#[derive(Default)] +#[repr(packed(2))] +struct Packed2 { + a: u8, + b: u8, + g: i32, + c: u8, + h: i16, + d: u8, +} + +#[derive(Default)] +#[repr(packed(2))] +#[repr(C)] +struct Packed2C { + a: u8, + b: u8, + g: i32, + c: u8, + h: i16, + d: u8, +} + +#[derive(Default)] +struct Padded { + a: u8, + b: u8, + g: i32, + c: u8, + h: i16, + d: u8, +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _c: Packed1 = Default::default(); + let _d: Packed2 = Default::default(); + let _e: Packed2C = Default::default(); + let _f: Padded = Default::default(); + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/print_type_sizes/padding.rs b/gcc/testsuite/rust/rustc/ui/print_type_sizes/padding.rs new file mode 100644 index 000000000000..e2d5252a1bb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print_type_sizes/padding.rs @@ -0,0 +1,35 @@ +// compile-flags: -Z print-type-sizes +// build-pass + +// This file illustrates how padding is handled: alignment +// requirements can lead to the introduction of padding, either before +// fields or at the end of the structure as a whole. +// +// It avoids using u64/i64 because on some targets that is only 4-byte +// aligned (while on most it is 8-byte aligned) and so the resulting +// padding and overall computed sizes can be quite different. + +#![feature(start)] +#![allow(dead_code)] + +struct S { + a: bool, + b: bool, + g: i32, +} + +enum E1 { + A(i32, i8), + B(S), +} + +enum E2 { + A(i8, i32), + B(S), +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/print_type_sizes/repr-align.rs b/gcc/testsuite/rust/rustc/ui/print_type_sizes/repr-align.rs new file mode 100644 index 000000000000..3704e3a6b2da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print_type_sizes/repr-align.rs @@ -0,0 +1,39 @@ +// compile-flags: -Z print-type-sizes +// build-pass +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. +// FIXME: consider using an attribute instead of side-effects. + +// This file illustrates how padding is handled: alignment +// requirements can lead to the introduction of padding, either before +// fields or at the end of the structure as a whole. +// +// It avoids using u64/i64 because on some targets that is only 4-byte +// aligned (while on most it is 8-byte aligned) and so the resulting +// padding and overall computed sizes can be quite different. +#![feature(start)] +#![allow(dead_code)] + +#[repr(align(16))] +#[derive(Default)] +struct A(i32); + +enum E { + A(i32), + B(A) +} + +#[derive(Default)] +struct S { + a: i32, + b: i32, + c: A, + d: i8, +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _s: S = Default::default(); + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/print_type_sizes/repr_int_c.rs b/gcc/testsuite/rust/rustc/ui/print_type_sizes/repr_int_c.rs new file mode 100644 index 000000000000..f7735a19c99e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print_type_sizes/repr_int_c.rs @@ -0,0 +1,26 @@ +// compile-flags: -Z print-type-sizes +// build-pass + +// This test makes sure that the tag is not grown for `repr(C)` or `repr(u8)` +// variants (see https://github.com/rust-lang/rust/issues/50098 for the original bug). + +#![feature(start)] +#![allow(dead_code)] + +#[repr(C, u8)] +enum ReprCu8 { + A(u16), + B, +} + +#[repr(u8)] +enum Repru8 { + A(u16), + B, +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/print_type_sizes/uninhabited.rs b/gcc/testsuite/rust/rustc/ui/print_type_sizes/uninhabited.rs new file mode 100644 index 000000000000..88c92dec23a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print_type_sizes/uninhabited.rs @@ -0,0 +1,16 @@ +// compile-flags: -Z print-type-sizes +// build-pass +// ignore-pass +// ^-- needed because `--pass check` does not emit the output needed. +// FIXME: consider using an attribute instead of side-effects. + +#![feature(never_type)] +#![feature(start)] + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _x: Option = None; + let _y: Result = Ok(42); + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/print_type_sizes/variants.rs b/gcc/testsuite/rust/rustc/ui/print_type_sizes/variants.rs new file mode 100644 index 000000000000..41c00e871f3d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print_type_sizes/variants.rs @@ -0,0 +1,27 @@ +// compile-flags: -Z print-type-sizes +// build-pass + +// This file illustrates two things: +// +// 1. Only types that appear in a monomorphized function appear in the +// print-type-sizes output, and +// +// 2. For an enum, the print-type-sizes output will also include the +// size of each variant. + +#![feature(start)] + +pub struct SevenBytes([u8; 7]); +pub struct FiftyBytes([u8; 50]); + +pub enum Enum { + Small(SevenBytes), + Large(FiftyBytes), +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _e: Enum; + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/print_type_sizes/zero-sized-fields.rs b/gcc/testsuite/rust/rustc/ui/print_type_sizes/zero-sized-fields.rs new file mode 100644 index 000000000000..4aae8aa36c37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/print_type_sizes/zero-sized-fields.rs @@ -0,0 +1,48 @@ +// compile-flags: -Z print-type-sizes +// build-pass +// ignore-pass + +// At one point, zero-sized fields such as those in this file were causing +// incorrect output from `-Z print-type-sizes`. + +#![feature(start)] + +struct S1 { + x: u32, + y: u32, + tag: (), +} + +struct Void(); +struct Empty {} + +struct S5 { + tagw: TagW, + w: u32, + unit: (), + x: u32, + void: Void, + y: u32, + empty: Empty, + z: u32, + tagz: TagZ, +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _s1: S1 = S1 { x: 0, y: 0, tag: () }; + + let _s5: S5<(), Empty> = S5 { + tagw: (), + w: 1, + unit: (), + x: 2, + void: Void(), + y: 3, + empty: Empty {}, + z: 4, + tagz: Empty {}, + }; + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/priv-in-bad-locations.rs b/gcc/testsuite/rust/rustc/ui/priv-in-bad-locations.rs new file mode 100644 index 000000000000..384fc15c141c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/priv-in-bad-locations.rs @@ -0,0 +1,18 @@ +pub extern { // { dg-error ".E0449." "" { target *-*-* } } + pub fn bar(); +} + +trait A { + fn foo(&self) {} +} + +struct B; + +pub impl B {} // { dg-error ".E0449." "" { target *-*-* } } + +pub impl A for B { // { dg-error ".E0449." "" { target *-*-* } } + pub fn foo(&self) {} // { dg-error ".E0449." "" { target *-*-* } } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/associated-item-privacy-inherent.rs b/gcc/testsuite/rust/rustc/ui/privacy/associated-item-privacy-inherent.rs new file mode 100644 index 000000000000..5571cba00d00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/associated-item-privacy-inherent.rs @@ -0,0 +1,113 @@ +#![feature(decl_macro, associated_type_defaults)] +#![allow(unused, private_in_public)] + +mod priv_nominal { + pub struct Pub; + impl Pub { + fn method(&self) {} + const CONST: u8 = 0; + // type AssocTy = u8; + } + + pub macro mac() { + let value = Pub::method; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + Pub.method(); +// { dg-error "" "" { target *-*-* } .-1 } + Pub::CONST; +// { dg-error "" "" { target *-*-* } .-1 } + // let _: Pub::AssocTy; + // pub type InSignatureTy = Pub::AssocTy; + } +} +fn priv_nominal() { + priv_nominal::mac!(); +} + +mod priv_signature { + struct Priv; + pub struct Pub; + impl Pub { + pub fn method(&self, arg: Priv) {} + } + + pub macro mac() { + let value = Pub::method; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + Pub.method(loop {}); +// { dg-error "" "" { target *-*-* } .-1 } + } +} +fn priv_signature() { + priv_signature::mac!(); +} + +mod priv_substs { + struct Priv; + pub struct Pub; + impl Pub { + pub fn method(&self) {} + } + + pub macro mac() { + let value = Pub::method::; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + Pub.method::(); +// { dg-error "" "" { target *-*-* } .-1 } + } +} +fn priv_substs() { + priv_substs::mac!(); +} + +mod priv_parent_substs { + struct Priv; + pub struct Pub(T); + impl Pub { + pub fn method(&self) {} + pub fn static_method() {} + pub const CONST: u8 = 0; + // pub type AssocTy = u8; + } + + pub macro mac() { + let value = ::method; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + let value = Pub::method; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + let value = ::static_method; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + let value = Pub::static_method; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + Pub(Priv).method(); +// { dg-error "" "" { target *-*-* } .-1 } + + ::CONST; +// { dg-error "" "" { target *-*-* } .-1 } + Pub::CONST; +// { dg-error "" "" { target *-*-* } .-1 } + + // let _: Pub::AssocTy; + // pub type InSignatureTy = Pub::AssocTy; + } +} +fn priv_parent_substs() { + priv_parent_substs::mac!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/associated-item-privacy-trait.rs b/gcc/testsuite/rust/rustc/ui/privacy/associated-item-privacy-trait.rs new file mode 100644 index 000000000000..2998799c72ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/associated-item-privacy-trait.rs @@ -0,0 +1,137 @@ +// ignore-tidy-linelength + +#![feature(decl_macro, associated_type_defaults)] +#![allow(unused, private_in_public)] + +mod priv_trait { + trait PrivTr { + fn method(&self) {} + const CONST: u8 = 0; + type AssocTy = u8; + } + pub struct Pub; + impl PrivTr for Pub {} + pub trait PubTr: PrivTr {} + + pub macro mac() { + let value = ::method; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + Pub.method(); +// { dg-error "" "" { target *-*-* } .-1 } + ::CONST; +// { dg-error "" "" { target *-*-* } .-1 } + let _: ::AssocTy; +// { dg-error "" "" { target *-*-* } .-1 } + pub type InSignatureTy = ::AssocTy; +// { dg-error "" "" { target *-*-* } .-1 } + pub trait InSignatureTr: PrivTr {} +// { dg-error "" "" { target *-*-* } .-1 } + impl PrivTr for u8 {} +// { dg-error "" "" { target *-*-* } .-1 } + } +} +fn priv_trait() { + priv_trait::mac!(); +} + +mod priv_signature { + pub trait PubTr { + fn method(&self, arg: Priv) {} + } + struct Priv; + pub struct Pub; + impl PubTr for Pub {} + + pub macro mac() { + let value = ::method; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + Pub.method(loop {}); +// { dg-error "" "" { target *-*-* } .-1 } + } +} +fn priv_signature() { + priv_signature::mac!(); +} + +mod priv_substs { + pub trait PubTr { + fn method(&self) {} + } + struct Priv; + pub struct Pub; + impl PubTr for Pub {} + + pub macro mac() { + let value = ::method::; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + Pub.method::(); +// { dg-error "" "" { target *-*-* } .-1 } + } +} +fn priv_substs() { + priv_substs::mac!(); +} + +mod priv_parent_substs { + pub trait PubTr { + fn method(&self) {} + const CONST: u8 = 0; + type AssocTy = u8; + } + struct Priv; + pub struct Pub; + impl PubTr for Pub {} + impl PubTr for Priv {} + + pub macro mac() { + let value = ::method; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + let value = >::method; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + Pub.method(); +// { dg-error "" "" { target *-*-* } .-1 } + + let value = >::method; +// { dg-error "" "" { target *-*-* } .-1 } + value; +// { dg-error "" "" { target *-*-* } .-1 } + Priv.method(); +// { dg-error "" "" { target *-*-* } .-1 } + + ::CONST; +// { dg-error "" "" { target *-*-* } .-1 } + >::CONST; +// { dg-error "" "" { target *-*-* } .-1 } + >::CONST; +// { dg-error "" "" { target *-*-* } .-1 } + + let _: ::AssocTy; // FIXME no longer an error?! + let _: >::AssocTy; +// { dg-error "" "" { target *-*-* } .-1 } + let _: >::AssocTy; +// { dg-error "" "" { target *-*-* } .-1 } + + pub type InSignatureTy1 = ::AssocTy; +// { dg-error "" "" { target *-*-* } .-1 } + pub type InSignatureTy2 = >::AssocTy; +// { dg-error "" "" { target *-*-* } .-1 } + impl PubTr for u8 {} +// { dg-error "" "" { target *-*-* } .-1 } + } +} +fn priv_parent_substs() { + priv_parent_substs::mac!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/associated-item-privacy-type-binding.rs b/gcc/testsuite/rust/rustc/ui/privacy/associated-item-privacy-type-binding.rs new file mode 100644 index 000000000000..50be287e3342 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/associated-item-privacy-type-binding.rs @@ -0,0 +1,65 @@ +#![feature(decl_macro, associated_type_defaults)] +#![allow(unused, private_in_public)] + +mod priv_trait { + trait PrivTr { + type AssocTy = u8; + } + pub trait PubTr: PrivTr {} + + pub macro mac1() { + let _: Box>; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + type InSignatureTy2 = Box>; +// { dg-error "" "" { target *-*-* } .-1 } + trait InSignatureTr2: PubTr {} +// { dg-error "" "" { target *-*-* } .-1 } + } + pub macro mac2() { + let _: Box>; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + type InSignatureTy1 = Box>; +// { dg-error "" "" { target *-*-* } .-1 } + trait InSignatureTr1: PrivTr {} +// { dg-error "" "" { target *-*-* } .-1 } + } +} +fn priv_trait1() { + priv_trait::mac1!(); +} +fn priv_trait2() { + priv_trait::mac2!(); +} + +mod priv_parent_substs { + pub trait PubTrWithParam { + type AssocTy = u8; + } + struct Priv; + pub trait PubTr: PubTrWithParam {} + + pub macro mac() { + let _: Box>; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + let _: Box>; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + pub type InSignatureTy1 = Box>; +// { dg-error "" "" { target *-*-* } .-1 } + pub type InSignatureTy2 = Box>; +// { dg-error "" "" { target *-*-* } .-1 } + trait InSignatureTr1: PubTrWithParam {} +// { dg-error "" "" { target *-*-* } .-1 } + trait InSignatureTr2: PubTr {} +// { dg-error "" "" { target *-*-* } .-1 } + } +} +fn priv_parent_substs() { + priv_parent_substs::mac!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/cci_class.rs b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/cci_class.rs new file mode 100644 index 000000000000..011fadfebb77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/cci_class.rs @@ -0,0 +1,15 @@ +pub mod kitties { + pub struct cat { + meows : usize, + + pub how_hungry : isize, + } + + pub fn cat(in_x : usize, in_y : isize) -> cat { + cat { + meows: in_x, + how_hungry: in_y + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/cci_class_5.rs b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/cci_class_5.rs new file mode 100644 index 000000000000..4b5da5ee2370 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/cci_class_5.rs @@ -0,0 +1,18 @@ +pub mod kitties { + pub struct cat { + meows : usize, + pub how_hungry : isize, + } + + impl cat { + fn nap(&self) {} + } + + pub fn cat(in_x : usize, in_y : isize) -> cat { + cat { + meows: in_x, + how_hungry: in_y + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/issue-57264-1.rs b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/issue-57264-1.rs new file mode 100644 index 000000000000..0e97b3417ce9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/issue-57264-1.rs @@ -0,0 +1,10 @@ +mod inner { + pub struct PubUnnameable; +} + +pub struct Pub(T); + +impl Pub { + pub fn pub_method() {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/issue-57264-2.rs b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/issue-57264-2.rs new file mode 100644 index 000000000000..4f1498f7fae2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/issue-57264-2.rs @@ -0,0 +1,11 @@ +mod inner { + pub struct PubUnnameable; + + impl PubUnnameable { + pub fn pub_method(self) {} + } +} + +pub trait PubTraitWithSingleImplementor {} +impl PubTraitWithSingleImplementor for Option {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/priv-impl-prim-ty.rs b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/priv-impl-prim-ty.rs new file mode 100644 index 000000000000..a97a67babc27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/priv-impl-prim-ty.rs @@ -0,0 +1,10 @@ +pub trait A { + fn frob(&self); +} + +impl A for isize { fn frob(&self) {} } + +pub fn frob(t: T) { + t.frob(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/privacy_reexport.rs b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/privacy_reexport.rs new file mode 100644 index 000000000000..713c45ee87c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/privacy_reexport.rs @@ -0,0 +1,7 @@ +pub extern crate core; +pub use foo as bar; + +pub mod foo { + pub fn frob() {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/privacy_tuple_struct.rs b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/privacy_tuple_struct.rs new file mode 100644 index 000000000000..bfc8cd44b43e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/privacy_tuple_struct.rs @@ -0,0 +1,5 @@ +pub struct A(()); +pub struct B(isize); +pub struct C(pub isize, isize); +pub struct D(pub isize); + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/private-inferred-type.rs b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/private-inferred-type.rs new file mode 100644 index 000000000000..530c37959850 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/private-inferred-type.rs @@ -0,0 +1,37 @@ +#![feature(decl_macro)] + +fn priv_fn() {} +static PRIV_STATIC: u8 = 0; +enum PrivEnum { Variant } +pub enum PubEnum { Variant } +trait PrivTrait { fn method() {} } +impl PrivTrait for u8 {} +pub trait PubTrait { fn method() {} } +impl PubTrait for u8 {} +struct PrivTupleStruct(u8); +pub struct PubTupleStruct(u8); +impl PubTupleStruct { fn method() {} } + +struct Priv; +pub type Alias = Priv; +pub struct Pub(pub T); + +impl Pub { + pub fn static_method() {} +} +impl Pub { + fn priv_method(&self) {} +} + +pub macro m() { + priv_fn; + PRIV_STATIC; + PrivEnum::Variant; + PubEnum::Variant; + ::method; + ::method; + PrivTupleStruct; + PubTupleStruct; + Pub(0u8).priv_method(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/pub_use_mods_xcrate.rs b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/pub_use_mods_xcrate.rs new file mode 100644 index 000000000000..9f93ccd00c4c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/pub_use_mods_xcrate.rs @@ -0,0 +1,11 @@ +pub mod a { + pub use a::b::c; + + pub mod b { + pub mod c { + fn f(){} + fn g(){} + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/pub_use_xcrate1.rs b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/pub_use_xcrate1.rs new file mode 100644 index 000000000000..76ebab5d5954 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/pub_use_xcrate1.rs @@ -0,0 +1,4 @@ +pub struct Foo { + pub name: isize +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/pub_use_xcrate2.rs b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/pub_use_xcrate2.rs new file mode 100644 index 000000000000..90006d77ecc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/auxiliary/pub_use_xcrate2.rs @@ -0,0 +1,4 @@ +extern crate pub_use_xcrate1; + +pub use pub_use_xcrate1::Foo; + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/decl-macro.rs b/gcc/testsuite/rust/rustc/ui/privacy/decl-macro.rs new file mode 100644 index 000000000000..bdacd1b2de2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/decl-macro.rs @@ -0,0 +1,10 @@ +#![feature(decl_macro)] + +mod m { + macro mac() {} +} + +fn main() { + m::mac!(); // { dg-error ".E0603." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/issue-57264-1.rs b/gcc/testsuite/rust/rustc/ui/privacy/issue-57264-1.rs new file mode 100644 index 000000000000..977504c5463a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/issue-57264-1.rs @@ -0,0 +1,9 @@ +// check-pass +// aux-build:issue-57264-1.rs + +extern crate issue_57264_1; + +fn main() { + issue_57264_1::Pub::pub_method(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/issue-57264-2.rs b/gcc/testsuite/rust/rustc/ui/privacy/issue-57264-2.rs new file mode 100644 index 000000000000..e2123ab4d0bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/issue-57264-2.rs @@ -0,0 +1,11 @@ +// check-pass +// aux-build:issue-57264-2.rs + +extern crate issue_57264_2; + +fn infer(arg: T) -> T { arg } + +fn main() { + infer(None).unwrap().pub_method(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/issue-75062-fieldless-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/privacy/issue-75062-fieldless-tuple-struct.rs new file mode 100644 index 000000000000..cd0b5937b293 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/issue-75062-fieldless-tuple-struct.rs @@ -0,0 +1,11 @@ +// Regression test for issue #75062 +// Tests that we don't ICE on a privacy error for a fieldless tuple struct. + +mod foo { + struct Bar(); +} + +fn main() { + foo::Bar(); // { dg-error ".E0603." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/legacy-ctor-visibility.rs b/gcc/testsuite/rust/rustc/ui/privacy/legacy-ctor-visibility.rs new file mode 100644 index 000000000000..b29efe43a388 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/legacy-ctor-visibility.rs @@ -0,0 +1,16 @@ +use m::S; + +mod m { + pub struct S(u8); + + mod n { + use S; + fn f() { + S(10); +// { dg-error ".E0423." "" { target *-*-* } .-1 } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/priv-impl-prim-ty.rs b/gcc/testsuite/rust/rustc/ui/privacy/priv-impl-prim-ty.rs new file mode 100644 index 000000000000..9dc3ad9bfc47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/priv-impl-prim-ty.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:priv-impl-prim-ty.rs + +// pretty-expanded FIXME #23616 + +extern crate priv_impl_prim_ty as bar; + +pub fn main() { + bar::frob(1); + +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy-in-paths.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy-in-paths.rs new file mode 100644 index 000000000000..bd230e4a7442 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy-in-paths.rs @@ -0,0 +1,31 @@ +mod foo { + pub use self::bar::S; + mod bar { + pub struct S; + pub use baz; + } + + trait T { + type Assoc; + } + impl T for () { + type Assoc = S; + } +} + +impl foo::S { + fn f() {} +} + +pub mod baz { + fn f() {} + + fn g() { + ::foo::bar::baz::f(); // { dg-error ".E0603." "" { target *-*-* } } + ::foo::bar::S::f(); // { dg-error ".E0603." "" { target *-*-* } } + <() as ::foo::T>::Assoc::f(); // { dg-error ".E0603." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy-ns.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy-ns.rs new file mode 100644 index 000000000000..17ca4bceb200 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy-ns.rs @@ -0,0 +1,115 @@ +// run-pass +#![allow(non_snake_case)] + + +// Check we do the correct privacy checks when we import a name and there is an +// item with that name in both the value and type namespaces. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] +#![allow(unused_imports)] + + +// public type, private value +pub mod foo1 { + pub trait Bar { + fn dummy(&self) { } + } + pub struct Baz; + + fn Bar() { } +} + +fn test_unused1() { + use foo1::*; +} + +fn test_single1() { + use foo1::Bar; + + let _x: Box; +} + +fn test_list1() { + use foo1::{Bar,Baz}; + + let _x: Box; +} + +fn test_glob1() { + use foo1::*; + + let _x: Box; +} + +// private type, public value +pub mod foo2 { + trait Bar { + fn dummy(&self) { } + } + pub struct Baz; + + pub fn Bar() { } +} + +fn test_unused2() { + use foo2::*; +} + +fn test_single2() { + use foo2::Bar; + + Bar(); +} + +fn test_list2() { + use foo2::{Bar,Baz}; + + Bar(); +} + +fn test_glob2() { + use foo2::*; + + Bar(); +} + +// public type, public value +pub mod foo3 { + pub trait Bar { + fn dummy(&self) { } + } + pub struct Baz; + + pub fn Bar() { } +} + +fn test_unused3() { + use foo3::*; +} + +fn test_single3() { + use foo3::Bar; + + Bar(); + let _x: Box; +} + +fn test_list3() { + use foo3::{Bar,Baz}; + + Bar(); + let _x: Box; +} + +fn test_glob3() { + use foo3::*; + + Bar(); + let _x: Box; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy-ns1.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy-ns1.rs new file mode 100644 index 000000000000..bf6b3b5730a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy-ns1.rs @@ -0,0 +1,57 @@ +// Check we do the correct privacy checks when we import a name and there is an +// item with that name in both the value and type namespaces. + +#![allow(dead_code)] +#![allow(unused_imports)] + + +// public type, private value +pub mod foo1 { + pub trait Bar { + } + pub struct Baz; + + fn Bar() { } +} + +fn test_glob1() { + use foo1::*; + + Bar(); // { dg-error ".E0423." "" { target *-*-* } } +} + +// private type, public value +pub mod foo2 { + trait Bar { + } + pub struct Baz; + + pub fn Bar() { } +} + +fn test_glob2() { + use foo2::*; + + let _x: Box; // { dg-error ".E0107." "" { target *-*-* } } +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + +// neither public +pub mod foo3 { + trait Bar { + } + pub struct Baz; + + fn Bar() { } +} + +fn test_glob3() { + use foo3::*; + + Bar(); // { dg-error ".E0425." "" { target *-*-* } } + let _x: Box; // { dg-error ".E0412." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy-ns2.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy-ns2.rs new file mode 100644 index 000000000000..ed3a5a2bdc1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy-ns2.rs @@ -0,0 +1,82 @@ +// Check we do the correct privacy checks when we import a name and there is an +// item with that name in both the value and type namespaces. + +#![allow(dead_code)] +#![allow(unused_imports)] + + +// public type, private value +pub mod foo1 { + pub trait Bar { + } + pub struct Baz; + + fn Bar() { } +} + +fn test_single1() { + use foo1::Bar; + + Bar(); // { dg-error ".E0423." "" { target *-*-* } } +} + +fn test_list1() { + use foo1::{Bar,Baz}; + + Bar(); // { dg-error ".E0423." "" { target *-*-* } } +} + +// private type, public value +pub mod foo2 { + trait Bar { + } + pub struct Baz; + + pub fn Bar() { } +} + +fn test_single2() { + use foo2::Bar; + + let _x : Box; // { dg-error ".E0107." "" { target *-*-* } } +// { dg-error ".E0107." "" { target *-*-* } .-1 } + let _x : Bar(); // { dg-error ".E0573." "" { target *-*-* } } +} + +fn test_list2() { + use foo2::{Bar,Baz}; + + let _x: Box; // { dg-error ".E0107." "" { target *-*-* } } +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + +// neither public +pub mod foo3 { + trait Bar { + } + pub struct Baz; + + fn Bar() { } +} + +fn test_unused3() { + use foo3::Bar; // { dg-error ".E0603." "" { target *-*-* } } +} + +fn test_single3() { + use foo3::Bar; // { dg-error ".E0603." "" { target *-*-* } } + + Bar(); + let _x: Box; +} + +fn test_list3() { + use foo3::{Bar,Baz}; // { dg-error ".E0603." "" { target *-*-* } } + + Bar(); + let _x: Box; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy-reexport.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy-reexport.rs new file mode 100644 index 000000000000..7502e39c30fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy-reexport.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:privacy_reexport.rs + +// pretty-expanded FIXME #23616 + +extern crate privacy_reexport; + +pub fn main() { + // Check that public extern crates are visible to outside crates + privacy_reexport::core::cell::Cell::new(0); + + privacy_reexport::bar::frob(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy-sanity.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy-sanity.rs new file mode 100644 index 000000000000..d539d5669263 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy-sanity.rs @@ -0,0 +1,83 @@ +#![feature(negative_impls)] + +pub trait Tr { + fn f(); + const C: u8; + type T; +} +pub struct S { + pub a: u8 +} +struct Ts(pub u8); + +pub impl Tr for S { // { dg-error ".E0449." "" { target *-*-* } } + pub fn f() {} // { dg-error ".E0449." "" { target *-*-* } } + pub const C: u8 = 0; // { dg-error ".E0449." "" { target *-*-* } } + pub type T = u8; // { dg-error ".E0449." "" { target *-*-* } } +} +pub impl S { // { dg-error ".E0449." "" { target *-*-* } } + pub fn f() {} + pub const C: u8 = 0; + // pub type T = u8; +} +pub extern "C" { // { dg-error ".E0449." "" { target *-*-* } } + pub fn f(); + pub static St: u8; +} + +const MAIN: u8 = { + pub trait Tr { + fn f(); + const C: u8; + type T; + } + pub struct S { + pub a: u8 + } + struct Ts(pub u8); + + pub impl Tr for S { // { dg-error ".E0449." "" { target *-*-* } } + pub fn f() {} // { dg-error ".E0449." "" { target *-*-* } } + pub const C: u8 = 0; // { dg-error ".E0449." "" { target *-*-* } } + pub type T = u8; // { dg-error ".E0449." "" { target *-*-* } } + } + pub impl S { // { dg-error ".E0449." "" { target *-*-* } } + pub fn f() {} + pub const C: u8 = 0; + // pub type T = u8; + } + pub extern "C" { // { dg-error ".E0449." "" { target *-*-* } } + pub fn f(); + pub static St: u8; + } + + 0 +}; + +fn main() { + pub trait Tr { + fn f(); + const C: u8; + type T; + } + pub struct S { + pub a: u8 + } + struct Ts(pub u8); + + pub impl Tr for S { // { dg-error ".E0449." "" { target *-*-* } } + pub fn f() {} // { dg-error ".E0449." "" { target *-*-* } } + pub const C: u8 = 0; // { dg-error ".E0449." "" { target *-*-* } } + pub type T = u8; // { dg-error ".E0449." "" { target *-*-* } } + } + pub impl S { // { dg-error ".E0449." "" { target *-*-* } } + pub fn f() {} + pub const C: u8 = 0; + // pub type T = u8; + } + pub extern "C" { // { dg-error ".E0449." "" { target *-*-* } } + pub fn f(); + pub static St: u8; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy-ufcs.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy-ufcs.rs new file mode 100644 index 000000000000..be4206da1041 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy-ufcs.rs @@ -0,0 +1,14 @@ +// Test to ensure private traits are inaccessible with UFCS angle-bracket syntax. + +mod foo { + trait Bar { + fn baz() {} + } + + impl Bar for i32 {} +} + +fn main() { + ::baz(); // { dg-error ".E0603." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy1-rpass.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy1-rpass.rs new file mode 100644 index 000000000000..32d50ec07013 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy1-rpass.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +pub mod test2 { + // This used to generate an ICE (make sure that default functions are + // parented to their trait to find the first private thing as the trait). + + struct B; + trait A { fn foo(&self) {} } + impl A for B {} + + mod tests { + use super::A; + fn foo() { + let a = super::B; + a.foo(); + } + } +} + + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy1.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy1.rs new file mode 100644 index 000000000000..bcac2696b12a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy1.rs @@ -0,0 +1,177 @@ +#![feature(lang_items, start, no_core)] +#![no_core] // makes debugging this test *a lot* easier (during resolve) + +#[lang="sized"] +pub trait Sized {} + +#[lang="copy"] +pub trait Copy {} + +#[lang="deref"] +pub trait Deref { + type Target; +} + +#[lang="receiver"] +pub trait Receiver: Deref {} + +impl<'a, T> Deref for &'a T { + type Target = T; +} + +impl<'a, T> Receiver for &'a T {} + +mod bar { + // shouldn't bring in too much + pub use self::glob::*; + + // can't publicly re-export private items + pub use self::baz::{foo, bar}; + + pub struct A; + impl A { + pub fn foo() {} + fn bar() {} + + pub fn foo2(&self) {} + fn bar2(&self) {} + } + + trait B { + fn foo() -> Self; + } + + impl B for isize { fn foo() -> isize { 3 } } + + pub enum Enum { + Pub + } + + mod baz { + pub struct A; + impl A { + pub fn foo() {} + fn bar() {} + + pub fn foo2(&self) {} + fn bar2(&self) {} + } + + pub fn foo() {} + pub fn bar() {} + } + + extern { + fn epriv(); + pub fn epub(); + } + + fn test() { + self::Enum::Pub; + unsafe { + epriv(); + epub(); + } + self::baz::A; + self::baz::A::foo(); + self::baz::A::bar(); // { dg-error ".E0624." "" { target *-*-* } } + self::baz::A.foo2(); + + // this used to cause an ICE in privacy traversal. + super::gpub(); + } + + mod glob { + pub fn gpub() {} + fn gpriv() {} + } +} + +pub fn gpub() {} + +fn lol() { + bar::A; + bar::A::foo(); + bar::A::bar(); // { dg-error ".E0624." "" { target *-*-* } } + bar::A.foo2(); +} + +mod foo { + fn test() { + ::bar::A::foo(); + ::bar::A::bar(); // { dg-error ".E0624." "" { target *-*-* } } + ::bar::A.foo2(); + ::bar::baz::A::foo(); // { dg-error ".E0603." "" { target *-*-* } } + ::bar::baz::A::bar(); // { dg-error ".E0624." "" { target *-*-* } } +// { dg-error ".E0624." "" { target *-*-* } .-1 } + ::bar::baz::A.foo2(); // { dg-error ".E0603." "" { target *-*-* } } + ::bar::baz::A.bar2(); // { dg-error ".E0624." "" { target *-*-* } } +// { dg-error ".E0624." "" { target *-*-* } .-1 } + + let _: isize = + ::bar::B::foo(); // { dg-error ".E0603." "" { target *-*-* } } + ::lol(); + + ::bar::Enum::Pub; + + unsafe { + ::bar::epriv(); // { dg-error ".E0603." "" { target *-*-* } } + ::bar::epub(); + } + + ::bar::foo(); + ::bar::bar(); + + ::bar::gpub(); + + ::bar::baz::foo(); // { dg-error ".E0603." "" { target *-*-* } } + ::bar::baz::bar(); // { dg-error ".E0603." "" { target *-*-* } } + } + + fn test2() { + use bar::baz::{foo, bar}; +// { dg-error ".E0603." "" { target *-*-* } .-1 } +// { dg-error ".E0603." "" { target *-*-* } .-2 } + + foo(); + bar(); + } + + fn test3() { + use bar::baz; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + } + + fn test4() { + use bar::{foo, bar}; + foo(); + bar(); + } + + fn test5() { + use bar; + bar::foo(); + bar::bar(); + } + + impl ::bar::B for f32 { fn foo() -> f32 { 1.0 } } +// { dg-error ".E0603." "" { target *-*-* } .-1 } +} + +pub mod mytest { + // Even though the inner `A` struct is a publicly exported item (usable from + // external crates through `foo::foo`, it should not be accessible through + // its definition path (which has the private `i` module). + use self::foo::i::A; // { dg-error ".E0603." "" { target *-*-* } } + + pub mod foo { + pub use self::i::A as foo; + + mod i { + pub struct A; + } + } +} + +#[start] fn main(_: isize, _: *const *const u8) -> isize { 3 } + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy2.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy2.rs new file mode 100644 index 000000000000..9e61e49ef00a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy2.rs @@ -0,0 +1,28 @@ +#![feature(start, no_core)] +#![no_core] // makes debugging this test *a lot* easier (during resolve) + +// Test to make sure that globs don't leak in regular `use` statements. + +mod bar { + pub use self::glob::*; + + pub mod glob { + use foo; + } +} + +pub fn foo() {} + +fn test1() { + use bar::foo; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +// { dg-error ".E0432." "" { target *-*-* } .-2 } +} + +fn test2() { + use bar::glob::foo; +// { dg-error ".E0603." "" { target *-*-* } .-1 } +} + +#[start] fn main(_: isize, _: *const *const u8) -> isize { 3 } + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy3.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy3.rs new file mode 100644 index 000000000000..c0f4e9b2fcb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy3.rs @@ -0,0 +1,28 @@ +#![feature(start, no_core)] +#![no_core] // makes debugging this test *a lot* easier (during resolve) + +// Test to make sure that private items imported through globs remain private +// when they're used. + +mod bar { + pub use self::glob::*; + + mod glob { + fn gpriv() {} + } +} + +pub fn foo() {} + +fn test1() { + use bar::gpriv; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +// { dg-error ".E0432." "" { target *-*-* } .-2 } + + // This should pass because the compiler will insert a fake name binding + // for `gpriv` + gpriv(); +} + +#[start] fn main(_: isize, _: *const *const u8) -> isize { 3 } + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy4.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy4.rs new file mode 100644 index 000000000000..56badedfaf77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy4.rs @@ -0,0 +1,26 @@ +#![feature(lang_items, start, no_core)] +#![no_core] // makes debugging this test *a lot* easier (during resolve) + +#[lang = "sized"] pub trait Sized {} +#[lang="copy"] pub trait Copy {} + +// Test to make sure that private items imported through globs remain private +// when they're used. + +mod bar { + pub use self::glob::*; + + mod glob { + fn gpriv() {} + } +} + +pub fn foo() {} + +fn test2() { + use bar::glob::gpriv; // { dg-error ".E0603." "" { target *-*-* } } + gpriv(); +} + +#[start] fn main(_: isize, _: *const *const u8) -> isize { 3 } + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/privacy5.rs b/gcc/testsuite/rust/rustc/ui/privacy/privacy5.rs new file mode 100644 index 000000000000..077db07639e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/privacy5.rs @@ -0,0 +1,129 @@ +// aux-build:privacy_tuple_struct.rs + +extern crate privacy_tuple_struct as other; + +mod a { + pub struct A(()); + pub struct B(isize); + pub struct C(pub isize, isize); + pub struct D(pub isize); + + fn test() { + let a = A(()); + let b = B(2); + let c = C(2, 3); + let d = D(4); + + let A(()) = a; + let A(_) = a; + match a { A(()) => {} } + match a { A(_) => {} } + + let B(_) = b; + let B(_b) = b; + match b { B(_) => {} } + match b { B(_b) => {} } + match b { B(1) => {} B(_) => {} } + + let C(_, _) = c; + let C(_a, _) = c; + let C(_, _b) = c; + let C(_a, _b) = c; + match c { C(_, _) => {} } + match c { C(_a, _) => {} } + match c { C(_, _b) => {} } + match c { C(_a, _b) => {} } + + let D(_) = d; + let D(_d) = d; + match d { D(_) => {} } + match d { D(_d) => {} } + match d { D(1) => {} D(_) => {} } + + let a2 = A; + let b2 = B; + let c2 = C; + let d2 = D; + } +} + +fn this_crate() { + let a = a::A(()); // { dg-error ".E0603." "" { target *-*-* } } + let b = a::B(2); // { dg-error ".E0603." "" { target *-*-* } } + let c = a::C(2, 3); // { dg-error ".E0603." "" { target *-*-* } } + let d = a::D(4); + + let a::A(()) = a; // { dg-error ".E0603." "" { target *-*-* } } + let a::A(_) = a; // { dg-error ".E0603." "" { target *-*-* } } + match a { a::A(()) => {} } // { dg-error ".E0603." "" { target *-*-* } } + match a { a::A(_) => {} } // { dg-error ".E0603." "" { target *-*-* } } + + let a::B(_) = b; // { dg-error ".E0603." "" { target *-*-* } } + let a::B(_b) = b; // { dg-error ".E0603." "" { target *-*-* } } + match b { a::B(_) => {} } // { dg-error ".E0603." "" { target *-*-* } } + match b { a::B(_b) => {} } // { dg-error ".E0603." "" { target *-*-* } } + match b { a::B(1) => {} a::B(_) => {} } // { dg-error ".E0603." "" { target *-*-* } } +// { dg-error ".E0603." "" { target *-*-* } .-1 } + + let a::C(_, _) = c; // { dg-error ".E0603." "" { target *-*-* } } + let a::C(_a, _) = c; // { dg-error ".E0603." "" { target *-*-* } } + let a::C(_, _b) = c; // { dg-error ".E0603." "" { target *-*-* } } + let a::C(_a, _b) = c; // { dg-error ".E0603." "" { target *-*-* } } + match c { a::C(_, _) => {} } // { dg-error ".E0603." "" { target *-*-* } } + match c { a::C(_a, _) => {} } // { dg-error ".E0603." "" { target *-*-* } } + match c { a::C(_, _b) => {} } // { dg-error ".E0603." "" { target *-*-* } } + match c { a::C(_a, _b) => {} } // { dg-error ".E0603." "" { target *-*-* } } + + let a::D(_) = d; + let a::D(_d) = d; + match d { a::D(_) => {} } + match d { a::D(_d) => {} } + match d { a::D(1) => {} a::D(_) => {} } + + let a2 = a::A; // { dg-error ".E0603." "" { target *-*-* } } + let b2 = a::B; // { dg-error ".E0603." "" { target *-*-* } } + let c2 = a::C; // { dg-error ".E0603." "" { target *-*-* } } + let d2 = a::D; +} + +fn xcrate() { + let a = other::A(()); // { dg-error ".E0603." "" { target *-*-* } } + let b = other::B(2); // { dg-error ".E0603." "" { target *-*-* } } + let c = other::C(2, 3); // { dg-error ".E0603." "" { target *-*-* } } + let d = other::D(4); + + let other::A(()) = a; // { dg-error ".E0603." "" { target *-*-* } } + let other::A(_) = a; // { dg-error ".E0603." "" { target *-*-* } } + match a { other::A(()) => {} } // { dg-error ".E0603." "" { target *-*-* } } + match a { other::A(_) => {} } // { dg-error ".E0603." "" { target *-*-* } } + + let other::B(_) = b; // { dg-error ".E0603." "" { target *-*-* } } + let other::B(_b) = b; // { dg-error ".E0603." "" { target *-*-* } } + match b { other::B(_) => {} } // { dg-error ".E0603." "" { target *-*-* } } + match b { other::B(_b) => {} } // { dg-error ".E0603." "" { target *-*-* } } + match b { other::B(1) => {}// { dg-error ".E0603." "" { target *-*-* } } + other::B(_) => {} } // { dg-error ".E0603." "" { target *-*-* } } + + let other::C(_, _) = c; // { dg-error ".E0603." "" { target *-*-* } } + let other::C(_a, _) = c; // { dg-error ".E0603." "" { target *-*-* } } + let other::C(_, _b) = c; // { dg-error ".E0603." "" { target *-*-* } } + let other::C(_a, _b) = c; // { dg-error ".E0603." "" { target *-*-* } } + match c { other::C(_, _) => {} } // { dg-error ".E0603." "" { target *-*-* } } + match c { other::C(_a, _) => {} } // { dg-error ".E0603." "" { target *-*-* } } + match c { other::C(_, _b) => {} } // { dg-error ".E0603." "" { target *-*-* } } + match c { other::C(_a, _b) => {} } // { dg-error ".E0603." "" { target *-*-* } } + + let other::D(_) = d; + let other::D(_d) = d; + match d { other::D(_) => {} } + match d { other::D(_d) => {} } + match d { other::D(1) => {} other::D(_) => {} } + + let a2 = other::A; // { dg-error ".E0603." "" { target *-*-* } } + let b2 = other::B; // { dg-error ".E0603." "" { target *-*-* } } + let c2 = other::C; // { dg-error ".E0603." "" { target *-*-* } } + let d2 = other::D; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-class-field.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-class-field.rs new file mode 100644 index 000000000000..8497851667e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-class-field.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + + +struct cat { + meows : usize, + + how_hungry : isize, +} + +impl cat { + pub fn meow_count(&mut self) -> usize { self.meows } +} + +fn cat(in_x : usize, in_y : isize) -> cat { + cat { + meows: in_x, + how_hungry: in_y + } +} + +pub fn main() { + let mut nyan : cat = cat(52, 99); + assert_eq!(nyan.meow_count(), 52); +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-impl-method.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-impl-method.rs new file mode 100644 index 000000000000..bda0b5413701 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-impl-method.rs @@ -0,0 +1,22 @@ +mod a { + pub struct Foo { + pub x: isize + } + + impl Foo { + fn foo(&self) {} + } +} + +fn f() { + impl a::Foo { + fn bar(&self) {} // This should be visible outside `f` + } +} + +fn main() { + let s = a::Foo { x: 1 }; + s.bar(); + s.foo(); // { dg-error ".E0624." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-assoc-ty.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-assoc-ty.rs new file mode 100644 index 000000000000..9f41a7307055 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-assoc-ty.rs @@ -0,0 +1,53 @@ +// Private types and traits are not allowed in interfaces of associated types. +// This test also ensures that the checks are performed even inside private modules. + +#![feature(associated_type_defaults)] +#![feature(type_alias_impl_trait)] + +mod m { + struct Priv; + trait PrivTr {} + impl PrivTr for Priv {} + pub trait PubTrAux1 {} + pub trait PubTrAux2 { + type A; + } + impl PubTrAux1 for u8 {} + impl PubTrAux2 for u8 { + type A = Priv; +// { dg-error ".E0446." "" { target *-*-* } .-1 } + } + + // "Private-in-public in associated types is hard error" in RFC 2145 + // applies only to the aliased types, not bounds. + pub trait PubTr { + type Alias1: PrivTr; +// { dg-warning ".E0445." "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + type Alias2: PubTrAux1 = u8; +// { dg-warning ".E0446." "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + type Alias3: PubTrAux2 = u8; +// { dg-warning ".E0446." "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + type Alias4 = Priv; +// { dg-error ".E0446." "" { target *-*-* } .-1 } + + type Exist; + fn infer_exist() -> Self::Exist; + } + impl PubTr for u8 { + type Alias1 = Priv; +// { dg-error ".E0446." "" { target *-*-* } .-1 } + + type Exist = impl PrivTr; +// { dg-error ".E0445." "" { target *-*-* } .-1 } + fn infer_exist() -> Self::Exist { + Priv + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-expr-pat.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-expr-pat.rs new file mode 100644 index 000000000000..358d01e2ae6a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-expr-pat.rs @@ -0,0 +1,14 @@ +// Patterns and expressions are not interface parts and don't produce private-in-public errors. + +// build-pass (FIXME(62277): could be check-pass?) + +struct Priv1(usize); +struct Priv2; + +pub struct Pub(Priv2); + +pub fn public_expr(_: [u8; Priv1(0).0]) {} // OK +pub fn public_pat(Pub(Priv2): Pub) {} // OK + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-ill-formed.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-ill-formed.rs new file mode 100644 index 000000000000..c5cdf30bfb20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-ill-formed.rs @@ -0,0 +1,38 @@ +mod aliases_pub { + struct Priv; + mod m { + pub struct Pub3; + } + + trait PrivTr { + type AssocAlias; + } + impl PrivTr for Priv { + type AssocAlias = m::Pub3; + } + + impl ::AssocAlias { +// { dg-error ".E0118." "" { target *-*-* } .-1 } + pub fn f(arg: Priv) {} // private type `aliases_pub::Priv` in public interface + } +} + +mod aliases_priv { + struct Priv; + struct Priv3; + + trait PrivTr { + type AssocAlias; + } + impl PrivTr for Priv { + type AssocAlias = Priv3; + } + + impl ::AssocAlias { +// { dg-error ".E0118." "" { target *-*-* } .-1 } + pub fn f(arg: Priv) {} // OK + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-lint.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-lint.rs new file mode 100644 index 000000000000..4b2d267843dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-lint.rs @@ -0,0 +1,20 @@ +mod m1 { + pub struct Pub; + struct Priv; + + impl Pub { + pub fn f() -> Priv {Priv} // { dg-error ".E0446." "" { target *-*-* } } + } +} + +mod m2 { + pub struct Pub; + struct Priv; + + impl Pub { + pub fn f() -> Priv {Priv} // { dg-error ".E0446." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-non-principal-2.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-non-principal-2.rs new file mode 100644 index 000000000000..ded91ef9065e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-non-principal-2.rs @@ -0,0 +1,15 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +#[allow(private_in_public)] +mod m { + pub trait PubPrincipal {} + auto trait PrivNonPrincipal {} + pub fn leak_dyn_nonprincipal() -> Box { loop {} } +} + +fn main() { + m::leak_dyn_nonprincipal(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-non-principal.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-non-principal.rs new file mode 100644 index 000000000000..29d31174a340 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-non-principal.rs @@ -0,0 +1,22 @@ +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +pub trait PubPrincipal {} +auto trait PrivNonPrincipal {} + +pub fn leak_dyn_nonprincipal() -> Box { loop {} } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +#[deny(missing_docs)] +fn container() { + impl dyn PubPrincipal { + pub fn check_doc_lint() {} // { dg-error "" "" { target *-*-* } } + } + impl dyn PubPrincipal + PrivNonPrincipal { + pub fn check_doc_lint() {} // OK, no missing doc lint + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-type-alias-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-type-alias-impl-trait.rs new file mode 100644 index 000000000000..777c0261a496 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-type-alias-impl-trait.rs @@ -0,0 +1,26 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(type_alias_impl_trait)] +#![deny(private_in_public)] + +pub type Pub = impl Default; + +#[derive(Default)] +struct Priv; + +fn check() -> Pub { + Priv +} + +pub trait Trait { + type Pub: Default; + fn method() -> Self::Pub; +} + +impl Trait for u8 { + type Pub = impl Default; + fn method() -> Self::Pub { Priv } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-warn.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-warn.rs new file mode 100644 index 000000000000..cf36ad1cc6ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public-warn.rs @@ -0,0 +1,284 @@ +// Private types and traits are not allowed in public interfaces. +// This test also ensures that the checks are performed even inside private modules. + +#![feature(associated_type_defaults)] +#![deny(private_in_public)] +#![allow(improper_ctypes)] + +mod types { + struct Priv; + pub struct Pub; + pub trait PubTr { + type Alias; + } + + pub type Alias = Priv; // { dg-error ".E0446." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + pub enum E { + V1(Priv), // { dg-error ".E0446." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + V2 { field: Priv }, // { dg-error ".E0446." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + } + pub trait Tr { + const C: Priv = Priv; // { dg-error ".E0446." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + type Alias = Priv; // { dg-error ".E0446." "" { target *-*-* } } + fn f1(arg: Priv) {} // { dg-error ".E0446." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + fn f2() -> Priv { panic!() } // { dg-error ".E0446." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + } + extern { + pub static ES: Priv; // { dg-error ".E0446." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + pub fn ef1(arg: Priv); // { dg-error ".E0446." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + pub fn ef2() -> Priv; // { dg-error ".E0446." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + } + impl PubTr for Pub { + type Alias = Priv; // { dg-error ".E0446." "" { target *-*-* } } + } +} + +mod traits { + trait PrivTr {} + pub struct Pub(T); + pub trait PubTr {} + + pub type Alias = T; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + pub trait Tr1: PrivTr {} // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + pub trait Tr2 {} // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + pub trait Tr3 { + type Alias: PrivTr; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + fn f(arg: T) {} // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + } + impl Pub {} // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + impl PubTr for Pub {} // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +mod traits_where { + trait PrivTr {} + pub struct Pub(T); + pub trait PubTr {} + + pub type Alias where T: PrivTr = T; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } + pub trait Tr2 where T: PrivTr {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + pub trait Tr3 { + fn f(arg: T) where T: PrivTr {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + } + impl Pub where T: PrivTr {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + impl PubTr for Pub where T: PrivTr {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +mod generics { + struct Priv(T); + pub struct Pub(T); + trait PrivTr {} + pub trait PubTr {} + + pub trait Tr1: PrivTr {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + pub trait Tr2: PubTr {} // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + pub trait Tr3: PubTr<[Priv; 1]> {} // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + pub trait Tr4: PubTr> {} // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +mod impls { + struct Priv; + pub struct Pub; + trait PrivTr { + type Alias; + } + pub trait PubTr { + type Alias; + } + + impl Priv { + pub fn f(arg: Priv) {} // OK + } + impl PrivTr for Priv { + type Alias = Priv; // OK + } + impl PubTr for Priv { + type Alias = Priv; // OK + } + impl PrivTr for Pub { + type Alias = Priv; // OK + } + impl PubTr for Pub { + type Alias = Priv; // { dg-error ".E0446." "" { target *-*-* } } + } +} + +mod impls_generics { + struct Priv(T); + pub struct Pub(T); + trait PrivTr { + type Alias; + } + pub trait PubTr { + type Alias; + } + + impl Priv { + pub fn f(arg: Priv) {} // OK + } + impl Pub { + pub fn f(arg: Priv) {} // OK + } + impl PrivTr for Priv { + type Alias = Priv; // OK + } + impl PubTr for Priv { + type Alias = Priv; // OK + } + impl PubTr for Priv { + type Alias = Priv; // OK + } + impl PubTr for [Priv; 1] { + type Alias = Priv; // OK + } + impl PubTr for Pub { + type Alias = Priv; // OK + } + impl PrivTr for Pub { + type Alias = Priv; // OK + } + impl PubTr for Pub { + type Alias = Priv; // OK + } +} + +mod aliases_pub { + struct Priv; + mod m { + pub struct Pub1; + pub struct Pub2; + pub struct Pub3; + pub trait PubTr { + type Check = u8; + } + } + + use self::m::Pub1 as PrivUseAlias; + use self::m::PubTr as PrivUseAliasTr; + type PrivAlias = m::Pub2; + trait PrivTr { + type AssocAlias; + } + impl PrivTr for Priv { + type AssocAlias = m::Pub3; + } + + pub fn f1(arg: PrivUseAlias) {} // OK + pub fn f2(arg: PrivAlias) {} // OK + + pub trait Tr1: PrivUseAliasTr {} // OK + pub trait Tr2: PrivUseAliasTr {} // OK + + impl PrivAlias { + pub fn f(arg: Priv) {} // { dg-error ".E0446." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + } + impl PrivUseAliasTr for PrivUseAlias { + type Check = Priv; // { dg-error ".E0446." "" { target *-*-* } } + } + impl PrivUseAliasTr for PrivAlias { + type Check = Priv; // { dg-error ".E0446." "" { target *-*-* } } + } + impl PrivUseAliasTr for ::AssocAlias { + type Check = Priv; // { dg-error ".E0446." "" { target *-*-* } } + } + impl PrivUseAliasTr for Option<::AssocAlias> { + type Check = Priv; // { dg-error ".E0446." "" { target *-*-* } } + } + impl PrivUseAliasTr for (::AssocAlias, Priv) { + type Check = Priv; // OK + } + impl PrivUseAliasTr for Option<(::AssocAlias, Priv)> { + type Check = Priv; // OK + } +} + +mod aliases_priv { + struct Priv; + + struct Priv1; + struct Priv2; + struct Priv3; + trait PrivTr1 { + type Check = u8; + } + + use self::Priv1 as PrivUseAlias; + use self::PrivTr1 as PrivUseAliasTr; + type PrivAlias = Priv2; + trait PrivTr { + type AssocAlias; + } + impl PrivTr for Priv { + type AssocAlias = Priv3; + } + + pub trait Tr1: PrivUseAliasTr {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + pub trait Tr2: PrivUseAliasTr {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + + impl PrivUseAlias { + pub fn f(arg: Priv) {} // OK + } + impl PrivAlias { + pub fn f(arg: Priv) {} // OK + } + impl PrivUseAliasTr for PrivUseAlias { + type Check = Priv; // OK + } + impl PrivUseAliasTr for PrivAlias { + type Check = Priv; // OK + } + impl PrivUseAliasTr for ::AssocAlias { + type Check = Priv; // OK + } +} + +mod aliases_params { + struct Priv; + type PrivAliasGeneric = T; + type Result = ::std::result::Result; + + pub fn f1(arg: PrivAliasGeneric) {} // OK, not an error +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-in-public.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public.rs new file mode 100644 index 000000000000..d8bcedd852d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-in-public.rs @@ -0,0 +1,149 @@ +// Private types and traits are not allowed in public interfaces. +// This test also ensures that the checks are performed even inside private modules. + +#![feature(associated_type_defaults)] + +mod types { + struct Priv; + pub struct Pub; + pub trait PubTr { + type Alias; + } + + pub const C: Priv = Priv; // { dg-error ".E0446." "" { target *-*-* } } + pub static S: Priv = Priv; // { dg-error ".E0446." "" { target *-*-* } } + pub fn f1(arg: Priv) {} // { dg-error ".E0446." "" { target *-*-* } } + pub fn f2() -> Priv { panic!() } // { dg-error ".E0446." "" { target *-*-* } } + pub struct S1(pub Priv); // { dg-error ".E0446." "" { target *-*-* } } + pub struct S2 { pub field: Priv } // { dg-error ".E0446." "" { target *-*-* } } + impl Pub { + pub const C: Priv = Priv; // { dg-error ".E0446." "" { target *-*-* } } + pub fn f1(arg: Priv) {} // { dg-error ".E0446." "" { target *-*-* } } + pub fn f2() -> Priv { panic!() } // { dg-error ".E0446." "" { target *-*-* } } + } +} + +mod traits { + trait PrivTr {} + pub struct Pub(T); + pub trait PubTr {} + + pub enum E { V(T) } // { dg-error ".E0445." "" { target *-*-* } } + pub fn f(arg: T) {} // { dg-error ".E0445." "" { target *-*-* } } + pub struct S1(T); // { dg-error ".E0445." "" { target *-*-* } } + impl Pub { // { dg-error ".E0445." "" { target *-*-* } } + pub fn f(arg: U) {} // { dg-error ".E0445." "" { target *-*-* } } + } +} + +mod traits_where { + trait PrivTr {} + pub struct Pub(T); + pub trait PubTr {} + + pub enum E where T: PrivTr { V(T) } +// { dg-error ".E0445." "" { target *-*-* } .-1 } + pub fn f(arg: T) where T: PrivTr {} +// { dg-error ".E0445." "" { target *-*-* } .-1 } + pub struct S1(T) where T: PrivTr; +// { dg-error ".E0445." "" { target *-*-* } .-1 } + impl Pub where T: PrivTr { +// { dg-error ".E0445." "" { target *-*-* } .-1 } + pub fn f(arg: U) where U: PrivTr {} +// { dg-error ".E0445." "" { target *-*-* } .-1 } + } +} + +mod generics { + struct Priv(T); + pub struct Pub(T); + trait PrivTr {} + pub trait PubTr {} + + pub fn f1(arg: [Priv; 1]) {} // { dg-error ".E0446." "" { target *-*-* } } + pub fn f2(arg: Pub) {} // { dg-error ".E0446." "" { target *-*-* } } + pub fn f3(arg: Priv) {} +// { dg-error ".E0446." "" { target *-*-* } .-1 } +} + +mod impls { + struct Priv; + pub struct Pub; + trait PrivTr { + type Alias; + } + pub trait PubTr { + type Alias; + } + + impl Pub { + pub fn f(arg: Priv) {} // { dg-error ".E0446." "" { target *-*-* } } + } +} + +mod aliases_pub { + struct Priv; + mod m { + pub struct Pub1; + pub struct Pub2; + pub struct Pub3; + pub trait PubTr { + type Check = u8; + } + } + + use self::m::Pub1 as PrivUseAlias; + use self::m::PubTr as PrivUseAliasTr; + type PrivAlias = m::Pub2; + trait PrivTr { + type Assoc = m::Pub3; + } + impl PrivTr for Priv {} + + // This should be OK, but associated type aliases are not substituted yet + pub fn f3(arg: ::Assoc) {} +// { dg-error ".E0446." "" { target *-*-* } .-1 } +// { dg-error ".E0446." "" { target *-*-* } .-2 } + + impl PrivUseAlias { + pub fn f(arg: Priv) {} // { dg-error ".E0446." "" { target *-*-* } } + } +} + +mod aliases_priv { + struct Priv; + + struct Priv1; + struct Priv2; + struct Priv3; + trait PrivTr1 { + type Check = u8; + } + + use self::Priv1 as PrivUseAlias; + use self::PrivTr1 as PrivUseAliasTr; + type PrivAlias = Priv2; + trait PrivTr { + type Assoc = Priv3; + } + impl PrivTr for Priv {} + + pub fn f1(arg: PrivUseAlias) {} // { dg-error ".E0446." "" { target *-*-* } } + pub fn f2(arg: PrivAlias) {} // { dg-error ".E0446." "" { target *-*-* } } + pub fn f3(arg: ::Assoc) {} +// { dg-error ".E0446." "" { target *-*-* } .-1 } +// { dg-error ".E0446." "" { target *-*-* } .-2 } +} + +mod aliases_params { + struct Priv; + type PrivAliasGeneric = T; + type Result = ::std::result::Result; + + pub fn f2(arg: PrivAliasGeneric) {} +// { dg-error ".E0446." "" { target *-*-* } .-1 } + pub fn f3(arg: Result) {} // { dg-error ".E0446." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type-1.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type-1.rs new file mode 100644 index 000000000000..00b9064d6e0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type-1.rs @@ -0,0 +1,19 @@ +trait Arr0 { + fn arr0_secret(&self); +} +trait TyParam { + fn ty_param_secret(&self); +} + +mod m { + struct Priv; + + impl ::Arr0 for [Priv; 0] { fn arr0_secret(&self) {} } + impl ::TyParam for Option { fn ty_param_secret(&self) {} } +} + +fn main() { + [].arr0_secret(); // { dg-error "" "" { target *-*-* } } + None.ty_param_secret(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type-2.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type-2.rs new file mode 100644 index 000000000000..bdae8662742d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type-2.rs @@ -0,0 +1,20 @@ +// aux-build:private-inferred-type.rs + +extern crate private_inferred_type as ext; + +mod m { + struct Priv; + pub struct Pub(pub T); + + impl Pub { + pub fn get_priv() -> Priv { Priv } + pub fn static_method() {} + } +} + +fn main() { + m::Pub::get_priv; // { dg-error "" "" { target *-*-* } } + m::Pub::static_method; // { dg-error "" "" { target *-*-* } } + ext::Pub::static_method; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type-3.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type-3.rs new file mode 100644 index 000000000000..ccc80c6d4e6c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type-3.rs @@ -0,0 +1,18 @@ +// aux-build:private-inferred-type.rs + +// error-pattern:type `fn() {ext::priv_fn}` is private +// error-pattern:static `PRIV_STATIC` is private +// error-pattern:type `ext::PrivEnum` is private +// error-pattern:type `fn() {::method}` is private +// error-pattern:type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct}` is private +// error-pattern:type `fn(u8) -> PubTupleStruct {PubTupleStruct}` is private +// error-pattern:type `for<'r> fn(&'r Pub) {Pub::::priv_method}` is private + +#![feature(decl_macro)] + +extern crate private_inferred_type as ext; + +fn main() { + ext::m!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type.rs new file mode 100644 index 000000000000..d9c6b461f5e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-inferred-type.rs @@ -0,0 +1,134 @@ +#![feature(decl_macro)] +#![allow(private_in_public)] + +mod m { + fn priv_fn() {} + static PRIV_STATIC: u8 = 0; + enum PrivEnum { Variant } + pub enum PubEnum { Variant } + trait PrivTrait { fn method() {} } + impl PrivTrait for u8 {} + pub trait PubTrait { fn method() {} } + impl PubTrait for u8 {} + struct PrivTupleStruct(u8); + pub struct PubTupleStruct(u8); + impl PubTupleStruct { fn method() {} } + + #[derive(Clone, Copy)] + struct Priv; + pub type Alias = Priv; + pub struct Pub(pub T); + + impl Pub { + pub fn static_method() {} + pub const INHERENT_ASSOC_CONST: u8 = 0; + } + impl Pub { + pub fn static_method_generic_self() {} + pub const INHERENT_ASSOC_CONST_GENERIC_SELF: u8 = 0; + } + impl Pub { + fn priv_method(&self) {} + pub fn method_with_substs(&self) {} + pub fn method_with_priv_params(&self, _: Priv) {} + } + impl TraitWithAssocConst for Priv {} + impl TraitWithAssocTy for Priv { type AssocTy = u8; } + + pub macro m() { + priv_fn; // { dg-error "" "" { target *-*-* } } + PRIV_STATIC; // OK, not cross-crate + PrivEnum::Variant; // { dg-error "" "" { target *-*-* } } + PubEnum::Variant; // OK + ::method; // { dg-error "" "" { target *-*-* } } + ::method; // OK + PrivTupleStruct; +// { dg-error "" "" { target *-*-* } .-1 } + PubTupleStruct; +// { dg-error "" "" { target *-*-* } .-1 } + Pub(0u8).priv_method(); +// { dg-error "" "" { target *-*-* } .-1 } + } + + trait Trait {} + pub trait TraitWithTyParam {} + pub trait TraitWithTyParam2 { fn pub_method() {} } + pub trait TraitWithAssocTy { type AssocTy; } + pub trait TraitWithAssocConst { const TRAIT_ASSOC_CONST: u8 = 0; } + impl Trait for u8 {} + impl TraitWithTyParam for u8 {} + impl TraitWithTyParam2 for u8 {} + impl TraitWithAssocTy for u8 { type AssocTy = Priv; } +// { dg-error ".E0446." "" { target *-*-* } .-1 } + + pub fn leak_anon1() -> impl Trait + 'static { 0 } + pub fn leak_anon2() -> impl TraitWithTyParam { 0 } + pub fn leak_anon3() -> impl TraitWithAssocTy { 0 } + + pub fn leak_dyn1() -> Box { Box::new(0) } + pub fn leak_dyn2() -> Box> { Box::new(0) } + pub fn leak_dyn3() -> Box> { Box::new(0) } +} + +mod adjust { + // Construct a chain of derefs with a private type in the middle + use std::ops::Deref; + + pub struct S1; + struct S2; + pub type S2Alias = S2; + pub struct S3; + + impl Deref for S1 { + type Target = S2Alias; // { dg-error ".E0446." "" { target *-*-* } } + fn deref(&self) -> &Self::Target { loop {} } + } + impl Deref for S2 { + type Target = S3; + fn deref(&self) -> &Self::Target { loop {} } + } + + impl S3 { + pub fn method_s3(&self) {} + } +} + +fn main() { + let _: m::Alias; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + let _: ::AssocTy; // { dg-error "" "" { target *-*-* } } + m::Alias {}; // { dg-error "" "" { target *-*-* } } + m::Pub { 0: m::Alias {} }; // { dg-error "" "" { target *-*-* } } + m::Pub { 0: loop {} }; // OK, `m::Pub` is in value context, so it means Pub<_>, not Pub + m::Pub::static_method; // { dg-error "" "" { target *-*-* } } + m::Pub::INHERENT_ASSOC_CONST; // { dg-error "" "" { target *-*-* } } + m::Pub(0u8).method_with_substs::(); // { dg-error "" "" { target *-*-* } } + m::Pub(0u8).method_with_priv_params(loop{}); // { dg-error "" "" { target *-*-* } } + ::TRAIT_ASSOC_CONST; // { dg-error "" "" { target *-*-* } } + >::INHERENT_ASSOC_CONST; // { dg-error "" "" { target *-*-* } } + >::INHERENT_ASSOC_CONST_GENERIC_SELF; // { dg-error "" "" { target *-*-* } } + >::static_method_generic_self; // { dg-error "" "" { target *-*-* } } + use m::TraitWithTyParam2; + u8::pub_method; // { dg-error "" "" { target *-*-* } } + + adjust::S1.method_s3(); // { dg-error "" "" { target *-*-* } } + + m::m!(); + + m::leak_anon1(); // { dg-error "" "" { target *-*-* } } + m::leak_anon2(); // { dg-error "" "" { target *-*-* } } + m::leak_anon3(); // { dg-error "" "" { target *-*-* } } + + m::leak_dyn1(); // { dg-error "" "" { target *-*-* } } + m::leak_dyn2(); // { dg-error "" "" { target *-*-* } } + m::leak_dyn3(); // { dg-error "" "" { target *-*-* } } + + // Check that messages are not duplicated for various kinds of assignments + let a = m::Alias {}; // { dg-error "" "" { target *-*-* } } + let mut b = a; // { dg-error "" "" { target *-*-* } } + b = a; // { dg-error "" "" { target *-*-* } } + match a { // { dg-error "" "" { target *-*-* } } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-item-simple.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-item-simple.rs new file mode 100644 index 000000000000..45c84d3d00e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-item-simple.rs @@ -0,0 +1,8 @@ +mod a { + fn f() {} +} + +fn main() { + a::f(); // { dg-error ".E0603." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-method-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-method-cross-crate.rs new file mode 100644 index 000000000000..30e709921b2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-method-cross-crate.rs @@ -0,0 +1,9 @@ +// aux-build:cci_class_5.rs +extern crate cci_class_5; +use cci_class_5::kitties::cat; + +fn main() { + let nyan : cat = cat(52, 99); + nyan.nap(); // { dg-error ".E0624." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-method-inherited.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-method-inherited.rs new file mode 100644 index 000000000000..8307dcc8cdce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-method-inherited.rs @@ -0,0 +1,15 @@ +// Tests that inherited visibility applies to methods. + +mod a { + pub struct Foo; + + impl Foo { + fn f(self) {} + } +} + +fn main() { + let x = a::Foo; + x.f(); // { dg-error ".E0624." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-method-rpass.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-method-rpass.rs new file mode 100644 index 000000000000..ff99c234d6fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-method-rpass.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +struct cat { + meows : usize, + + how_hungry : isize, +} + +impl cat { + pub fn play(&mut self) { + self.meows += 1_usize; + self.nap(); + } +} + +impl cat { + fn nap(&mut self) { for _ in 1_usize..10_usize { } } +} + +fn cat(in_x : usize, in_y : isize) -> cat { + cat { + meows: in_x, + how_hungry: in_y + } +} + +pub fn main() { + let mut nyan : cat = cat(52_usize, 99); + nyan.play(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-method.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-method.rs new file mode 100644 index 000000000000..be0a6d4808cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-method.rs @@ -0,0 +1,24 @@ +mod kitties { + pub struct Cat { + meows : usize, + + how_hungry : isize, + } + + impl Cat { + fn nap(&self) {} + } + + pub fn cat(in_x : usize, in_y : isize) -> Cat { + Cat { + meows: in_x, + how_hungry: in_y + } + } +} + +fn main() { + let nyan : kitties::Cat = kitties::cat(52, 99); + nyan.nap(); // { dg-error ".E0624." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-struct-field-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-struct-field-cross-crate.rs new file mode 100644 index 000000000000..cc5a75ce562a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-struct-field-cross-crate.rs @@ -0,0 +1,10 @@ +// aux-build:cci_class.rs +extern crate cci_class; +use cci_class::kitties::cat; + +fn main() { + let nyan : cat = cat(52, 99); + assert_eq!(nyan.meows, 52); +// { dg-error ".E0616." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-struct-field-ctor.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-struct-field-ctor.rs new file mode 100644 index 000000000000..f2c05637afd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-struct-field-ctor.rs @@ -0,0 +1,10 @@ +mod a { + pub struct Foo { + x: isize + } +} + +fn main() { + let s = a::Foo { x: 1 }; // { dg-error ".E0451." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-struct-field-pattern.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-struct-field-pattern.rs new file mode 100644 index 000000000000..6dc7b3455303 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-struct-field-pattern.rs @@ -0,0 +1,18 @@ +use a::Foo; + +mod a { + pub struct Foo { + x: isize + } + + pub fn make() -> Foo { + Foo { x: 3 } + } +} + +fn main() { + match a::make() { + Foo { x: _ } => {} // { dg-error ".E0451." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-struct-field.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-struct-field.rs new file mode 100644 index 000000000000..6a458fca55f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-struct-field.rs @@ -0,0 +1,15 @@ +mod cat { + pub struct Cat { + meows: usize + } + + pub fn new_cat() -> Cat { + Cat { meows: 52 } + } +} + +fn main() { + let nyan = cat::new_cat(); + assert_eq!(nyan.meows, 52); // { dg-error ".E0616." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-type-in-interface.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-type-in-interface.rs new file mode 100644 index 000000000000..113ce674546b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-type-in-interface.rs @@ -0,0 +1,31 @@ +// aux-build:private-inferred-type.rs + +#![allow(warnings)] + +extern crate private_inferred_type as ext; + +mod m { + struct Priv; + pub type Alias = Priv; + + pub trait Trait { type X; } + impl Trait for Priv { type X = u8; } +} + +fn f(_: m::Alias) {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +fn f_ext(_: ext::Alias) {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + +trait Tr1 {} +impl m::Alias {} // { dg-error "" "" { target *-*-* } } +impl Tr1 for ext::Alias {} // { dg-error "" "" { target *-*-* } } +type A = ::X; // { dg-error "" "" { target *-*-* } } + +trait Tr2 {} +impl Tr2 for u8 {} +fn g() -> impl Tr2 { 0 } // { dg-error "" "" { target *-*-* } } +fn g_ext() -> impl Tr2 { 0 } // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/private-variant-reexport.rs b/gcc/testsuite/rust/rustc/ui/privacy/private-variant-reexport.rs new file mode 100644 index 000000000000..8675361c6c7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/private-variant-reexport.rs @@ -0,0 +1,20 @@ +mod m1 { + pub use ::E::V; // { dg-error "" "" { target *-*-* } } +} + +mod m2 { + pub use ::E::{V}; // { dg-error "" "" { target *-*-* } } +} + +mod m3 { + pub use ::E::V::{self}; // { dg-error "" "" { target *-*-* } } +} + +mod m4 { + pub use ::E::*; // { dg-error "" "" { target *-*-* } } +} + +enum E { V } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/pub-extern-privacy.rs b/gcc/testsuite/rust/rustc/ui/privacy/pub-extern-privacy.rs new file mode 100644 index 000000000000..17c191e49f37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/pub-extern-privacy.rs @@ -0,0 +1,19 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with + +// pretty-expanded FIXME #23616 + +use std::mem::transmute; + +mod a { + extern { + pub fn free(x: *const u8); + } +} + +pub fn main() { + unsafe { + a::free(transmute(0_usize)); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs b/gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs new file mode 100644 index 000000000000..68bfcc09afd9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/auxiliary/priv_dep.rs @@ -0,0 +1,3 @@ +pub struct OtherType; +pub trait OtherTrait {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs b/gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs new file mode 100644 index 000000000000..68fd575d8c8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/auxiliary/pub_dep.rs @@ -0,0 +1,2 @@ +pub struct PubType; + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/pub-priv1.rs b/gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/pub-priv1.rs new file mode 100644 index 000000000000..1754a16c32e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -0,0 +1,44 @@ +// aux-crate:priv:priv_dep=priv_dep.rs +// aux-build:pub_dep.rs +#![deny(exported_private_dependencies)] + +// This crate is a private dependency +extern crate priv_dep; +// This crate is a public dependency +extern crate pub_dep; + +use priv_dep::{OtherTrait, OtherType}; +use pub_dep::PubType; + +// Type from private dependency used in private +// type - this is fine +struct PrivateType { + field: OtherType, +} + +pub struct PublicType { + pub field: OtherType, +// { dg-error "" "" { target *-*-* } .-1 } + priv_field: OtherType, // Private field - this is fine + pub other_field: PubType, // Type from public dependency - this is fine +} + +impl PublicType { + pub fn pub_fn(param: OtherType) {} +// { dg-error "" "" { target *-*-* } .-1 } + + fn priv_fn(param: OtherType) {} +} + +pub trait MyPubTrait { + type Foo: OtherTrait; +} +// { dg-error "" "" { target *-*-* } .-2 } + +pub struct AllowedPrivType { + #[allow(exported_private_dependencies)] + pub allowed: OtherType, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/std-pub.rs b/gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/std-pub.rs new file mode 100644 index 000000000000..ca1f37c3ea7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/pub-priv-dep/std-pub.rs @@ -0,0 +1,13 @@ +// The 'std' crates should always be implicitly public, +// without having to pass any compiler arguments + +// run-pass + +#![deny(exported_private_dependencies)] + +pub struct PublicType { + pub field: Option +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/pub-use-xcrate.rs b/gcc/testsuite/rust/rustc/ui/privacy/pub-use-xcrate.rs new file mode 100644 index 000000000000..82ad1f653981 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/pub-use-xcrate.rs @@ -0,0 +1,16 @@ +// run-pass +// aux-build:pub_use_xcrate1.rs +// aux-build:pub_use_xcrate2.rs + +// pretty-expanded FIXME #23616 + +extern crate pub_use_xcrate2; + +use pub_use_xcrate2::Foo; + +pub fn main() { + let _foo: Foo = Foo { + name: 0 + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/pub_use_mods_xcrate_exe.rs b/gcc/testsuite/rust/rustc/ui/privacy/pub_use_mods_xcrate_exe.rs new file mode 100644 index 000000000000..4afff2c01c33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/pub_use_mods_xcrate_exe.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:pub_use_mods_xcrate.rs + +// pretty-expanded FIXME #23616 + +#![allow(unused_imports)] + +extern crate pub_use_mods_xcrate; +use pub_use_mods_xcrate::a::c; + +pub fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/restricted/auxiliary/pub_restricted.rs b/gcc/testsuite/rust/rustc/ui/privacy/restricted/auxiliary/pub_restricted.rs new file mode 100644 index 000000000000..b50de913a2a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/restricted/auxiliary/pub_restricted.rs @@ -0,0 +1,17 @@ +#![feature(crate_visibility_modifier)] + +pub(crate) struct Crate; + +#[derive(Default)] +pub struct Universe { + pub x: i32, + pub(crate) y: i32, + crate z: i32, +} + +impl Universe { + pub fn f(&self) {} + pub(crate) fn g(&self) {} + crate fn h(&self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/restricted/lookup-ignores-private.rs b/gcc/testsuite/rust/rustc/ui/privacy/restricted/lookup-ignores-private.rs new file mode 100644 index 000000000000..5c0de4859694 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/restricted/lookup-ignores-private.rs @@ -0,0 +1,35 @@ +// build-pass (FIXME(62277): could be check-pass?) +#![allow(warnings)] + +mod foo { + pub use foo::bar::S; + mod bar { + #[derive(Default)] + pub struct S { + pub(in foo) x: i32, + } + impl S { + pub(in foo) fn f(&self) -> i32 { 0 } + } + + pub struct S2 { + pub(crate) x: bool, + } + impl S2 { + pub(crate) fn f(&self) -> bool { false } + } + + impl ::std::ops::Deref for S { + type Target = S2; + fn deref(&self) -> &S2 { unimplemented!() } + } + } +} + + +fn main() { + let s = foo::S::default(); + let _: bool = s.x; + let _: bool = s.f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/restricted/private-in-public.rs b/gcc/testsuite/rust/rustc/ui/privacy/restricted/private-in-public.rs new file mode 100644 index 000000000000..b8159faca348 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/restricted/private-in-public.rs @@ -0,0 +1,14 @@ +#![feature(crate_visibility_modifier)] + +mod foo { + struct Priv; + mod bar { + use foo::Priv; + pub(super) fn f(_: Priv) {} + pub(crate) fn g(_: Priv) {} // { dg-error ".E0446." "" { target *-*-* } } + crate fn h(_: Priv) {} // { dg-error ".E0446." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/restricted/relative-2018.rs b/gcc/testsuite/rust/rustc/ui/privacy/restricted/relative-2018.rs new file mode 100644 index 000000000000..a20394c51fd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/restricted/relative-2018.rs @@ -0,0 +1,14 @@ +// edition:2018 + +mod m { + pub(in crate) struct S1; // OK + pub(in super) struct S2; // OK + pub(in self) struct S3; // OK + pub(in ::core) struct S4; +// { dg-error ".E0742." "" { target *-*-* } .-1 } + pub(in a::b) struct S5; +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/restricted/struct-literal-field.rs b/gcc/testsuite/rust/rustc/ui/privacy/restricted/struct-literal-field.rs new file mode 100644 index 000000000000..a63c49e72f7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/restricted/struct-literal-field.rs @@ -0,0 +1,20 @@ +#![allow(warnings)] + +mod foo { + pub mod bar { + pub struct S { + pub(in foo) x: i32, + } + } + + fn f() { + use foo::bar::S; + S { x: 0 }; // ok + } +} + +fn main() { + use foo::bar::S; + S { x: 0 }; // { dg-error ".E0451." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/restricted/test.rs b/gcc/testsuite/rust/rustc/ui/privacy/restricted/test.rs new file mode 100644 index 000000000000..1ea74c87cfa6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/restricted/test.rs @@ -0,0 +1,53 @@ +// aux-build:pub_restricted.rs + +#![allow(warnings)] +extern crate pub_restricted; + +mod foo { + pub mod bar { + pub(super) fn f() {} + #[derive(Default)] + pub struct S { + pub(super) x: i32, + } + impl S { + pub(super) fn f(&self) {} + pub(super) fn g() {} + } + } + fn f() { + use foo::bar::S; + pub(self) use foo::bar::f; // ok + pub(super) use foo::bar::f as g; // { dg-error ".E0364." "" { target *-*-* } } + S::default().x; // ok + S::default().f(); // ok + S::g(); // ok + } +} + +fn f() { + use foo::bar::S; + use foo::bar::f; // { dg-error ".E0603." "" { target *-*-* } } + S::default().x; // { dg-error ".E0616." "" { target *-*-* } } + S::default().f(); // { dg-error ".E0624." "" { target *-*-* } } + S::g(); // { dg-error ".E0624." "" { target *-*-* } } +} + +fn main() { + use pub_restricted::Universe; + use pub_restricted::Crate; // { dg-error ".E0603." "" { target *-*-* } } + + let u = Universe::default(); + let _ = u.x; + let _ = u.y; // { dg-error ".E0616." "" { target *-*-* } } + let _ = u.z; // { dg-error ".E0616." "" { target *-*-* } } + u.f(); + u.g(); // { dg-error ".E0624." "" { target *-*-* } } + u.h(); // { dg-error ".E0624." "" { target *-*-* } } +} + +mod pathological { + pub(in bad::path) mod m1 {} // { dg-error ".E0433." "" { target *-*-* } } + pub(in foo) mod m2 {} // { dg-error ".E0742." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/union-field-privacy-1.rs b/gcc/testsuite/rust/rustc/ui/privacy/union-field-privacy-1.rs new file mode 100644 index 000000000000..82111c0a0d99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/union-field-privacy-1.rs @@ -0,0 +1,18 @@ +mod m { + pub union U { + pub a: u8, + pub(super) b: u8, + c: u8, + } +} + +fn main() { unsafe { + let u = m::U { a: 0 }; // OK + let u = m::U { b: 0 }; // OK + let u = m::U { c: 0 }; // { dg-error ".E0451." "" { target *-*-* } } + + let m::U { a } = u; // OK + let m::U { b } = u; // OK + let m::U { c } = u; // { dg-error ".E0451." "" { target *-*-* } } +}} + diff --git a/gcc/testsuite/rust/rustc/ui/privacy/union-field-privacy-2.rs b/gcc/testsuite/rust/rustc/ui/privacy/union-field-privacy-2.rs new file mode 100644 index 000000000000..c84819b90b0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/privacy/union-field-privacy-2.rs @@ -0,0 +1,16 @@ +mod m { + pub union U { + pub a: u8, + pub(super) b: u8, + c: u8, + } +} + +fn main() { + let u = m::U { a: 10 }; + + let a = u.a; // OK + let b = u.b; // OK + let c = u.c; // { dg-error ".E0616." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/add-impl.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/add-impl.rs new file mode 100644 index 000000000000..08a54f5b78cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/add-impl.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:add-impl.rs + +#[macro_use] +extern crate add_impl; + +#[derive(AddImpl)] +struct B; + +fn main() { + B.foo(); + foo(); + bar::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/ambiguous-builtin-attrs-test.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/ambiguous-builtin-attrs-test.rs new file mode 100644 index 000000000000..a8d640d1fba1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/ambiguous-builtin-attrs-test.rs @@ -0,0 +1,21 @@ +// aux-build:builtin-attrs.rs +// compile-flags:--test + +#![feature(decl_macro, test)] + +extern crate test; +extern crate builtin_attrs; +use builtin_attrs::{test, bench}; + +#[test] // OK, shadowed +fn test() {} + +#[bench] // OK, shadowed +fn bench(b: &mut test::Bencher) {} + +fn not_main() { + Test; + Bench; + NonExistent; // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/ambiguous-builtin-attrs.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/ambiguous-builtin-attrs.rs new file mode 100644 index 000000000000..f218265a8e13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/ambiguous-builtin-attrs.rs @@ -0,0 +1,32 @@ +// aux-build:builtin-attrs.rs + +#![feature(decl_macro)] // { dg-error ".E0659." "" { target *-*-* } } + +extern crate builtin_attrs; +use builtin_attrs::{test, bench}; +use builtin_attrs::*; + +#[repr(C)] // { dg-error ".E0659." "" { target *-*-* } } +struct S; +#[cfg_attr(all(), repr(C))] // { dg-error ".E0659." "" { target *-*-* } } +struct SCond; + +#[test] // OK, shadowed +fn test() {} + +#[bench] // OK, shadowed +fn bench() {} + +fn non_macro_expanded_location<#[repr(C)] T>() { // { dg-error ".E0659." "" { target *-*-* } } + match 0u8 { + #[repr(C)] // { dg-error ".E0659." "" { target *-*-* } } + _ => {} + } +} + +fn main() { + Test; + Bench; + NonExistent; // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/append-impl.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/append-impl.rs new file mode 100644 index 000000000000..396fda2aaff4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/append-impl.rs @@ -0,0 +1,23 @@ +// run-pass +// aux-build:append-impl.rs + +#![allow(warnings)] + +#[macro_use] +extern crate append_impl; + +trait Append { + fn foo(&self); +} + +#[derive(PartialEq, + Append, + Eq)] +struct A { + inner: u32, +} + +fn main() { + A { inner: 3 }.foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attr-args.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attr-args.rs new file mode 100644 index 000000000000..8dc59a89cea5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attr-args.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:attr-args.rs + +#![allow(warnings)] + +extern crate attr_args; +use attr_args::{attr_with_args, identity}; + +#[attr_with_args(text = "Hello, world!")] +fn foo() {} + +#[identity(fn main() { assert_eq!(foo(), "Hello, world!"); })] +struct Dummy; + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attr-cfg.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attr-cfg.rs new file mode 100644 index 000000000000..7f82675d84b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attr-cfg.rs @@ -0,0 +1,28 @@ +// run-pass +// aux-build:attr-cfg.rs +// revisions: foo bar + +extern crate attr_cfg; +use attr_cfg::attr_cfg; + +#[attr_cfg] +fn outer() -> u8 { + #[cfg(foo)] + fn inner() -> u8 { 1 } + + #[cfg(bar)] + fn inner() -> u8 { 2 } + + inner() +} + +#[cfg(foo)] +fn main() { + assert_eq!(outer(), 1); +} + +#[cfg(bar)] +fn main() { + assert_eq!(outer(), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attr-invalid-exprs.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attr-invalid-exprs.rs new file mode 100644 index 000000000000..3e6562b469d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attr-invalid-exprs.rs @@ -0,0 +1,29 @@ +//! Attributes producing expressions in invalid locations + +// aux-build:attr-stmt-expr.rs + +#![feature(proc_macro_hygiene)] +#![feature(stmt_expr_attributes)] + +extern crate attr_stmt_expr; +use attr_stmt_expr::{duplicate, no_output}; + +fn main() { + let _ = #[no_output] "Hello, world!"; +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = #[duplicate] "Hello, world!"; +// { dg-error "" "" { target *-*-* } .-1 } + + let _ = { + #[no_output] + "Hello, world!" + }; + + let _ = { + #[duplicate] +// { dg-error "" "" { target *-*-* } .-1 } + "Hello, world!" + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attr-on-trait.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attr-on-trait.rs new file mode 100644 index 000000000000..e256d5906465 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attr-on-trait.rs @@ -0,0 +1,20 @@ +// run-pass +// aux-build:attr-on-trait.rs + +extern crate attr_on_trait; + +use attr_on_trait::foo; + +trait Foo { + #[foo] + fn foo() {} +} + +impl Foo for i32 { + fn foo(&self) {} +} + +fn main() { + 3i32.foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attr-stmt-expr-rpass.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attr-stmt-expr-rpass.rs new file mode 100644 index 000000000000..b5b91bcb512c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attr-stmt-expr-rpass.rs @@ -0,0 +1,37 @@ +// run-pass +// aux-build:attr-stmt-expr-rpass.rs + +#![feature(stmt_expr_attributes, proc_macro_hygiene)] + +extern crate attr_stmt_expr_rpass as attr_stmt_expr; +use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr, + no_output, noop}; + +fn print_str(string: &'static str) { + // macros are handled a bit differently + #[expect_print_expr] + println!("{}", string) +} + +fn main() { + #[expect_let] + let string = "Hello, world!"; + + #[expect_print_stmt] + println!("{}", string); + + let _: () = { + #[no_output] + "Hello, world!" + }; + + let _: &'static str = #[noop] "Hello, world!"; + + let _: &'static str = { + #[noop] "Hello, world!" + }; + + #[expect_expr] + print_str("string") +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attr-stmt-expr.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attr-stmt-expr.rs new file mode 100644 index 000000000000..f99c9257bc53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attr-stmt-expr.rs @@ -0,0 +1,28 @@ +// aux-build:attr-stmt-expr.rs + +#![feature(proc_macro_hygiene)] + +extern crate attr_stmt_expr; +use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr}; + +fn print_str(string: &'static str) { + // macros are handled a bit differently + #[expect_print_expr] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { help ".E0658." "" { target *-*-* } .-2 } + println!("{}", string) +} + +fn main() { + #[expect_let] + let string = "Hello, world!"; + + #[expect_print_stmt] + println!("{}", string); + + #[expect_expr] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { help ".E0658." "" { target *-*-* } .-2 } + print_str("string") +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attribute-order-restricted.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attribute-order-restricted.rs new file mode 100644 index 000000000000..29a9bc1587c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attribute-order-restricted.rs @@ -0,0 +1,15 @@ +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +#[identity_attr] // OK +#[derive(Clone)] +struct Before; + +#[derive(Clone)] +#[identity_attr] // { dg-error "" "" { target *-*-* } } +struct After; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attribute-spans-preserved.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attribute-spans-preserved.rs new file mode 100644 index 000000000000..2d84940f4040 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attribute-spans-preserved.rs @@ -0,0 +1,11 @@ +// aux-build:attribute-spans-preserved.rs + +extern crate attribute_spans_preserved as foo; + +use foo::foo; + +#[ foo ( let y: u32 = "z"; ) ] // { dg-error ".E0308." "" { target *-*-* } } +#[ bar { let x: u32 = "y"; } ] // { dg-error ".E0308." "" { target *-*-* } } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attribute-with-error.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attribute-with-error.rs new file mode 100644 index 000000000000..008b434f3119 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attribute-with-error.rs @@ -0,0 +1,43 @@ +// aux-build:test-macros.rs + +#![feature(custom_inner_attributes)] + +#[macro_use] +extern crate test_macros; + +#[recollect_attr] +fn test1() { + let a: i32 = "foo"; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let b: i32 = "f'oo"; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn test2() { + #![recollect_attr] + + // FIXME: should have a type error here and assert it works but it doesn't +} + +trait A { + // FIXME: should have a #[recollect_attr] attribute here and assert that it works + fn foo(&self) { + let a: i32 = "foo"; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } +} + +struct B; + +impl A for B { + #[recollect_attr] + fn foo(&self) { + let a: i32 = "foo"; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } +} + +#[recollect_attr] +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attribute.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attribute.rs new file mode 100644 index 000000000000..79a61fb27ecf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attribute.rs @@ -0,0 +1,74 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro_derive] // { dg-error "" "" { target *-*-* } } +pub fn foo1(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive = ""] // { dg-error "" "" { target *-*-* } } +pub fn foo2(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d3, a, b)] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo3(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d4, attributes(a), b)] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo4(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive("a")] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo5(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d6 = "")] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo6(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(m::d7)] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo7(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d8(a))] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo8(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(self)] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo9(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(PartialEq)] // OK +pub fn foo10(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d11, a)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +pub fn foo11(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d12, attributes)] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo12(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d13, attributes("a"))] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo13(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d14, attributes(a = ""))] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo14(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d15, attributes(m::a))] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo15(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d16, attributes(a(b)))] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo16(input: TokenStream) -> TokenStream { input } + +#[proc_macro_derive(d17, attributes(self))] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo17(input: TokenStream) -> TokenStream { input } + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attributes-included.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attributes-included.rs new file mode 100644 index 000000000000..2cb19e44f184 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attributes-included.rs @@ -0,0 +1,23 @@ +// aux-build:attributes-included.rs +// check-pass + +#![warn(unused)] + +extern crate attributes_included; + +use attributes_included::*; + +#[bar] +#[inline] +/// doc +#[foo] +#[inline] +/// doc +fn foo() { + let a: i32 = "foo"; // { dg-warning "" "" { target *-*-* } } +} + +fn main() { + foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attributes-on-definitions.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attributes-on-definitions.rs new file mode 100644 index 000000000000..14a75dc0428c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attributes-on-definitions.rs @@ -0,0 +1,13 @@ +// check-pass +// aux-build:attributes-on-definitions.rs + +#![forbid(unsafe_code)] + +extern crate attributes_on_definitions; + +attributes_on_definitions::with_attrs!(); +// { dg-warning "" "" { target *-*-* } .-1 } +// No errors about the use of unstable and unsafe code inside the macro. + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attributes-on-modules-fail.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attributes-on-modules-fail.rs new file mode 100644 index 000000000000..5aeda3d853f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attributes-on-modules-fail.rs @@ -0,0 +1,47 @@ +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +#[identity_attr] +mod m { + pub struct X; + + type A = Y; // { dg-error ".E0412." "" { target *-*-* } } +} + +struct Y; +type A = X; // { dg-error ".E0412." "" { target *-*-* } } + +#[derive(Copy)] // { dg-error ".E0774." "" { target *-*-* } } +mod n {} + +#[empty_attr] +mod module; // { dg-error ".E0658." "" { target *-*-* } } + +#[empty_attr] +mod outer { + mod inner; // { dg-error ".E0658." "" { target *-*-* } } + + mod inner_inline {} // OK +} + +#[derive(Empty)] +struct S { + field: [u8; { + #[path = "outer/inner.rs"] + mod inner; // { dg-error ".E0658." "" { target *-*-* } } + mod inner_inline {} // OK + 0 + }] +} + +#[identity_attr] +fn f() { + #[path = "outer/inner.rs"] + mod inner; // { dg-error ".E0658." "" { target *-*-* } } + mod inner_inline {} // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/attributes-on-modules.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/attributes-on-modules.rs new file mode 100644 index 000000000000..951602b642c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/attributes-on-modules.rs @@ -0,0 +1,20 @@ +// check-pass +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +#[identity_attr] +mod m { + pub struct S; +} + +#[identity_attr] +fn f() { + mod m {} +} + +fn main() { + let s = m::S; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/add-impl.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/add-impl.rs new file mode 100644 index 000000000000..59f10dd492c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/add-impl.rs @@ -0,0 +1,22 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(AddImpl)] +// #[cfg(proc_macro)] +pub fn derive(input: TokenStream) -> TokenStream { + "impl B { + fn foo(&self) {} + } + + fn foo() {} + + mod bar { pub fn foo() {} } + ".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/append-impl.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/append-impl.rs new file mode 100644 index 000000000000..908e2c914ffd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/append-impl.rs @@ -0,0 +1,17 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Append)] +pub fn derive_a(input: TokenStream) -> TokenStream { + "impl Append for A { + fn foo(&self) {} + } + ".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-args.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-args.rs new file mode 100644 index 000000000000..587d7031d8cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-args.rs @@ -0,0 +1,29 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn attr_with_args(args: TokenStream, input: TokenStream) -> TokenStream { + let args = args.to_string(); + + assert_eq!(args, r#"text = "Hello, world!""#); + + let input = input.to_string(); + + assert_eq!(input, "fn foo() { }"); + + r#" + fn foo() -> &'static str { "Hello, world!" } + "#.parse().unwrap() +} + +#[proc_macro_attribute] +pub fn identity(attr_args: TokenStream, _: TokenStream) -> TokenStream { + attr_args +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-cfg.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-cfg.rs new file mode 100644 index 000000000000..52012cc8d51f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-cfg.rs @@ -0,0 +1,22 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn attr_cfg(args: TokenStream, input: TokenStream) -> TokenStream { + let input_str = input.to_string(); + + assert_eq!(input_str, "fn outer() -> u8 +{ + #[cfg(foo)] fn inner() -> u8 { 1 } #[cfg(bar)] fn inner() -> u8 { 2 } + inner() +}"); + + input +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-on-trait.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-on-trait.rs new file mode 100644 index 000000000000..5e74a0cae1d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-on-trait.rs @@ -0,0 +1,16 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn foo(attr: TokenStream, item: TokenStream) -> TokenStream { + drop(attr); + assert_eq!(item.to_string(), "fn foo() { }"); + "fn foo(&self);".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs new file mode 100644 index 000000000000..1ec26e13ad79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs @@ -0,0 +1,52 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert_eq!(item.to_string(), "let string = \"Hello, world!\" ;"); + item +} + +#[proc_macro_attribute] +pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert_eq!(item.to_string(), "println ! (\"{}\", string) ;"); + item +} + +#[proc_macro_attribute] +pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert_eq!(item.to_string(), "print_str(\"string\")"); + item +} + +#[proc_macro_attribute] +pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert_eq!(item.to_string(), "println ! (\"{}\", string)"); + item +} + +#[proc_macro_attribute] +pub fn no_output(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert!(!item.to_string().is_empty()); + "".parse().unwrap() + +} + +#[proc_macro_attribute] +pub fn noop(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert!(!item.to_string().is_empty()); + item +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-stmt-expr.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-stmt-expr.rs new file mode 100644 index 000000000000..1b455c11244c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attr-stmt-expr.rs @@ -0,0 +1,50 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert_eq!(item.to_string(), "let string = \"Hello, world!\" ;"); + item +} + +#[proc_macro_attribute] +pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert_eq!(item.to_string(), "println ! (\"{}\", string) ;"); + item +} + +#[proc_macro_attribute] +pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert_eq!(item.to_string(), "print_str(\"string\")"); + item +} + +#[proc_macro_attribute] +pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert_eq!(item.to_string(), "println ! (\"{}\", string)"); + item +} + +#[proc_macro_attribute] +pub fn duplicate(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + format!("{}, {}", item, item).parse().unwrap() +} + +#[proc_macro_attribute] +pub fn no_output(attr: TokenStream, item: TokenStream) -> TokenStream { + assert!(attr.to_string().is_empty()); + assert!(!item.to_string().is_empty()); + "".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attribute-spans-preserved.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attribute-spans-preserved.rs new file mode 100644 index 000000000000..56fd86e01694 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attribute-spans-preserved.rs @@ -0,0 +1,36 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro_attribute] +pub fn foo(attr: TokenStream, f: TokenStream) -> TokenStream { + let mut tokens = f.into_iter(); + assert_eq!(tokens.next().unwrap().to_string(), "#"); + let next_attr = match tokens.next().unwrap() { + TokenTree::Group(g) => g, + _ => panic!(), + }; + + let fn_tok = tokens.next().unwrap(); + let ident_tok = tokens.next().unwrap(); + let args_tok = tokens.next().unwrap(); + let body = tokens.next().unwrap(); + + let new_body = attr.into_iter() + .chain(next_attr.stream().into_iter().skip(1)); + + let tokens = vec![ + fn_tok, + ident_tok, + args_tok, + Group::new(Delimiter::Brace, new_body.collect()).into(), + ].into_iter().collect::(); + println!("{}", tokens); + return tokens +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attributes-included.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attributes-included.rs new file mode 100644 index 000000000000..5a3899ce3569 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attributes-included.rs @@ -0,0 +1,151 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{TokenStream, TokenTree, Delimiter, Literal, Spacing, Group}; + +#[proc_macro_attribute] +pub fn foo(attr: TokenStream, input: TokenStream) -> TokenStream { + assert!(attr.is_empty()); + let input = input.into_iter().collect::>(); + { + let mut cursor = &input[..]; + assert_inline(&mut cursor); + assert_doc(&mut cursor); + assert_inline(&mut cursor); + assert_doc(&mut cursor); + assert_foo(&mut cursor); + assert!(cursor.is_empty()); + } + fold_stream(input.into_iter().collect()) +} + +#[proc_macro_attribute] +pub fn bar(attr: TokenStream, input: TokenStream) -> TokenStream { + assert!(attr.is_empty()); + let input = input.into_iter().collect::>(); + { + let mut cursor = &input[..]; + assert_inline(&mut cursor); + assert_doc(&mut cursor); + assert_invoc(&mut cursor); + assert_inline(&mut cursor); + assert_doc(&mut cursor); + assert_foo(&mut cursor); + assert!(cursor.is_empty()); + } + input.into_iter().collect() +} + +fn assert_inline(slice: &mut &[TokenTree]) { + match &slice[0] { + TokenTree::Punct(tt) => assert_eq!(tt.as_char(), '#'), + _ => panic!("expected '#' char"), + } + match &slice[1] { + TokenTree::Group(tt) => assert_eq!(tt.delimiter(), Delimiter::Bracket), + _ => panic!("expected brackets"), + } + *slice = &slice[2..]; +} + +fn assert_doc(slice: &mut &[TokenTree]) { + match &slice[0] { + TokenTree::Punct(tt) => { + assert_eq!(tt.as_char(), '#'); + assert_eq!(tt.spacing(), Spacing::Alone); + } + _ => panic!("expected #"), + } + let inner = match &slice[1] { + TokenTree::Group(tt) => { + assert_eq!(tt.delimiter(), Delimiter::Bracket); + tt.stream() + } + _ => panic!("expected brackets"), + }; + let tokens = inner.into_iter().collect::>(); + let tokens = &tokens[..]; + + if tokens.len() != 3 { + panic!("expected three tokens in doc") + } + + match &tokens[0] { + TokenTree::Ident(tt) => assert_eq!("doc", &*tt.to_string()), + _ => panic!("expected `doc`"), + } + match &tokens[1] { + TokenTree::Punct(tt) => { + assert_eq!(tt.as_char(), '='); + assert_eq!(tt.spacing(), Spacing::Alone); + } + _ => panic!("expected equals"), + } + match tokens[2] { + TokenTree::Literal(_) => {} + _ => panic!("expected literal"), + } + + *slice = &slice[2..]; +} + +fn assert_invoc(slice: &mut &[TokenTree]) { + match &slice[0] { + TokenTree::Punct(tt) => assert_eq!(tt.as_char(), '#'), + _ => panic!("expected '#' char"), + } + match &slice[1] { + TokenTree::Group(tt) => assert_eq!(tt.delimiter(), Delimiter::Bracket), + _ => panic!("expected brackets"), + } + *slice = &slice[2..]; +} + +fn assert_foo(slice: &mut &[TokenTree]) { + match &slice[0] { + TokenTree::Ident(tt) => assert_eq!(&*tt.to_string(), "fn"), + _ => panic!("expected fn"), + } + match &slice[1] { + TokenTree::Ident(tt) => assert_eq!(&*tt.to_string(), "foo"), + _ => panic!("expected foo"), + } + match &slice[2] { + TokenTree::Group(tt) => { + assert_eq!(tt.delimiter(), Delimiter::Parenthesis); + assert!(tt.stream().is_empty()); + } + _ => panic!("expected parens"), + } + match &slice[3] { + TokenTree::Group(tt) => assert_eq!(tt.delimiter(), Delimiter::Brace), + _ => panic!("expected braces"), + } + *slice = &slice[4..]; +} + +fn fold_stream(input: TokenStream) -> TokenStream { + input.into_iter().map(fold_tree).collect() +} + +fn fold_tree(input: TokenTree) -> TokenTree { + match input { + TokenTree::Group(b) => { + TokenTree::Group(Group::new(b.delimiter(), fold_stream(b.stream()))) + } + TokenTree::Punct(b) => TokenTree::Punct(b), + TokenTree::Ident(a) => TokenTree::Ident(a), + TokenTree::Literal(a) => { + if a.to_string() != "\"foo\"" { + TokenTree::Literal(a) + } else { + TokenTree::Literal(Literal::i32_unsuffixed(3)) + } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attributes-on-definitions.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attributes-on-definitions.rs new file mode 100644 index 000000000000..85f5ab4dfc13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/attributes-on-definitions.rs @@ -0,0 +1,24 @@ +// force-host +// no-prefer-dynamic + +#![feature(allow_internal_unsafe)] +#![feature(allow_internal_unstable)] + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +#[allow_internal_unstable(proc_macro_internals)] +#[allow_internal_unsafe] +#[deprecated(since = "1.0.0", note = "test")] +pub fn with_attrs(_: TokenStream) -> TokenStream { + " + extern crate proc_macro; + use ::proc_macro::bridge; + + fn contains_unsafe() { unsafe {} } + ".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/bang-macro.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/bang-macro.rs new file mode 100644 index 000000000000..4bd050a8ceaf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/bang-macro.rs @@ -0,0 +1,18 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn rewrite(input: TokenStream) -> TokenStream { + let input = input.to_string(); + + assert_eq!(input, r#""Hello, world!""#); + + r#""NOT Hello, world!""#.parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/bang_proc_macro2.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/bang_proc_macro2.rs new file mode 100644 index 000000000000..25b9eb78c10b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/bang_proc_macro2.rs @@ -0,0 +1,14 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn bang_proc_macro2(_: TokenStream) -> TokenStream { + "let x = foobar2;".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/builtin-attrs.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/builtin-attrs.rs new file mode 100644 index 000000000000..e25567a25edd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/builtin-attrs.rs @@ -0,0 +1,28 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro_attribute] +pub fn feature(_: TokenStream, input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_attribute] +pub fn repr(_: TokenStream, input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_attribute] +pub fn test(_: TokenStream, input: TokenStream) -> TokenStream { + "struct Test;".parse().unwrap() +} + +#[proc_macro_attribute] +pub fn bench(_: TokenStream, input: TokenStream) -> TokenStream { + "struct Bench;".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/call-site.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/call-site.rs new file mode 100644 index 000000000000..c0a601e8f905 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/call-site.rs @@ -0,0 +1,28 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +pub fn check(input: TokenStream) -> TokenStream { + // Parsed `x2` can refer to `x2` from `input` + let parsed1: TokenStream = "let x3 = x2;".parse().unwrap(); + // `x3` parsed from one string can refer to `x3` parsed from another string. + let parsed2: TokenStream = "let x4 = x3;".parse().unwrap(); + // Manually assembled `x4` can refer to parsed `x4`. + let manual: Vec = vec![ + Ident::new("let", Span::call_site()).into(), + Ident::new("x5", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Ident::new("x4", Span::call_site()).into(), + Punct::new(';', Spacing::Alone).into(), + ]; + input.into_iter().chain(parsed1.into_iter()) + .chain(parsed2.into_iter()) + .chain(manual.into_iter()) + .collect() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/count_compound_ops.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/count_compound_ops.rs new file mode 100644 index 000000000000..69b3dadf423d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/count_compound_ops.rs @@ -0,0 +1,33 @@ +// force-host +// no-prefer-dynamic + +#![feature(proc_macro_quote)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{TokenStream, TokenTree, Spacing, Literal, quote}; + +#[proc_macro] +pub fn count_compound_ops(input: TokenStream) -> TokenStream { + assert_eq!(count_compound_ops_helper(quote!(++ (&&) 4@a)), 3); + let l = Literal::u32_suffixed(count_compound_ops_helper(input)); + TokenTree::from(l).into() +} + +fn count_compound_ops_helper(input: TokenStream) -> u32 { + let mut count = 0; + for token in input { + match &token { + TokenTree::Punct(tt) if tt.spacing() == Spacing::Alone => { + count += 1; + } + TokenTree::Group(tt) => { + count += count_compound_ops_helper(tt.stream()); + } + _ => {} + } + } + count +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs new file mode 100644 index 000000000000..ea30189fae61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/custom-attr-only-one-derive.rs @@ -0,0 +1,19 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Foo)] +pub fn foo(a: TokenStream) -> TokenStream { + "".parse().unwrap() +} + +#[proc_macro_derive(Bar, attributes(custom))] +pub fn bar(a: TokenStream) -> TokenStream { + "".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-a.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-a.rs new file mode 100644 index 000000000000..330feaf635f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-a.rs @@ -0,0 +1,16 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(A)] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert!(input.contains("struct A ;")); + "".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-atob.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-atob.rs new file mode 100644 index 000000000000..3d98f7203950 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-atob.rs @@ -0,0 +1,16 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(AToB)] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert_eq!(input, "struct A ;"); + "struct B;".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-attr-cfg.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-attr-cfg.rs new file mode 100644 index 000000000000..ce782e881a82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-attr-cfg.rs @@ -0,0 +1,15 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Foo, attributes(foo))] +pub fn derive(input: TokenStream) -> TokenStream { + assert!(!input.to_string().contains("#[cfg(any())]")); + "".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-b-rpass.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-b-rpass.rs new file mode 100644 index 000000000000..23c8050edc90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-b-rpass.rs @@ -0,0 +1,18 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(B, attributes(B, C))] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert!(input.contains("#[B [arbitrary tokens]]")); + assert!(input.contains("struct B {")); + assert!(input.contains("#[C]")); + "".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-b.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-b.rs new file mode 100644 index 000000000000..df3d067465d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-b.rs @@ -0,0 +1,14 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(B, attributes(B))] +pub fn derive_b(input: TokenStream) -> TokenStream { + "".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-bad.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-bad.rs new file mode 100644 index 000000000000..468410972fb7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-bad.rs @@ -0,0 +1,14 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(A)] +pub fn derive_a(_input: TokenStream) -> TokenStream { + "struct A { inner }".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-clona.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-clona.rs new file mode 100644 index 000000000000..f3df82873171 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-clona.rs @@ -0,0 +1,14 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Clona)] +pub fn derive_clonea(input: TokenStream) -> TokenStream { + "".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-ctod.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-ctod.rs new file mode 100644 index 000000000000..12860a1416e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-ctod.rs @@ -0,0 +1,16 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(CToD)] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert_eq!(input, "struct C ;"); + "struct D;".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-foo.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-foo.rs new file mode 100644 index 000000000000..54d13805eca4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-foo.rs @@ -0,0 +1,14 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(FooWithLongName)] +pub fn derive_foo(input: TokenStream) -> TokenStream { + "".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowed-2.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowed-2.rs new file mode 100644 index 000000000000..1fcc59dee890 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowed-2.rs @@ -0,0 +1,3 @@ +#[macro_export] +macro_rules! empty_helper { () => () } + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs new file mode 100644 index 000000000000..0b19830c707e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowing-2.rs @@ -0,0 +1,13 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro_derive(same_name, attributes(same_name))] +pub fn derive_a(_: TokenStream) -> TokenStream { + TokenStream::new() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowing.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowing.rs new file mode 100644 index 000000000000..3d34385ad17f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-helper-shadowing.rs @@ -0,0 +1,16 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro_derive(GenHelperUse)] +pub fn derive_a(_: TokenStream) -> TokenStream { + " + #[empty_helper] + struct Uwu; + ".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-nothing.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-nothing.rs new file mode 100644 index 000000000000..1a973cc91130 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-nothing.rs @@ -0,0 +1,14 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Nothing)] +pub fn nothing(input: TokenStream) -> TokenStream { + "".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-same-struct.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-same-struct.rs new file mode 100644 index 000000000000..089b43761c9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-same-struct.rs @@ -0,0 +1,22 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(AToB)] +pub fn derive1(input: TokenStream) -> TokenStream { + println!("input1: {:?}", input.to_string()); + assert_eq!(input.to_string(), "struct A ;"); + "#[derive(BToC)] struct B;".parse().unwrap() +} + +#[proc_macro_derive(BToC)] +pub fn derive2(input: TokenStream) -> TokenStream { + assert_eq!(input.to_string(), "struct B ;"); + "struct C;".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-two-attrs.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-two-attrs.rs new file mode 100644 index 000000000000..3bfc64480737 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-two-attrs.rs @@ -0,0 +1,14 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro_derive(A, attributes(b))] +pub fn foo(_x: TokenStream) -> TokenStream { + TokenStream::new() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-union.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-union.rs new file mode 100644 index 000000000000..c43c75b8491b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-union.rs @@ -0,0 +1,19 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(UnionTest)] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert!(input.contains("#[repr(C)]")); + assert!(input.contains("union Test {")); + assert!(input.contains("a : u8,")); + assert!(input.contains("}")); + "".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-unstable-2.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-unstable-2.rs new file mode 100644 index 000000000000..efff0b596fb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-unstable-2.rs @@ -0,0 +1,18 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Unstable)] +pub fn derive(_input: TokenStream) -> TokenStream { + + " + #[rustc_foo] + fn foo() {} + ".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-unstable.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-unstable.rs new file mode 100644 index 000000000000..6f98e0f0d186 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/derive-unstable.rs @@ -0,0 +1,15 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Unstable)] +pub fn derive(_input: TokenStream) -> TokenStream { + + "unsafe fn foo() -> u32 { ::std::intrinsics::abort() }".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/dollar-crate-external.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/dollar-crate-external.rs new file mode 100644 index 000000000000..75c06652af7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/dollar-crate-external.rs @@ -0,0 +1,23 @@ +pub type S = u8; + +#[macro_export] +macro_rules! external { + () => { + print_bang! { + struct M($crate::S); + } + + #[print_attr] + struct A($crate::S); + + #[derive(Print)] + struct D($crate::S); + }; +} + +#[macro_export] +macro_rules! issue_62325 { () => { + #[print_attr] + struct B(identity!($crate::S)); +}} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/double.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/double.rs new file mode 100644 index 000000000000..b18eb0ccfdef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/double.rs @@ -0,0 +1,17 @@ +// force-host +// no-prefer-dynamic + +#![feature(proc_macro_quote)] + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +// Outputs another copy of the struct. Useful for testing the tokens +// seen by the proc_macro. +#[proc_macro_derive(Double)] +pub fn derive(input: TokenStream) -> TokenStream { + quote!(mod foo { $input }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/duplicate.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/duplicate.rs new file mode 100644 index 000000000000..30bd1915b8d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/duplicate.rs @@ -0,0 +1,33 @@ +// force-host +// no-prefer-dynamic + +#![deny(unused)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro_attribute] +pub fn duplicate(attr: TokenStream, item: TokenStream) -> TokenStream { + let mut new_name = Some(attr.into_iter().nth(0).unwrap()); + let mut encountered_idents = 0; + let input = item.to_string(); + let ret = item + .into_iter() + .map(move |token| match token { + TokenTree::Ident(_) if encountered_idents == 1 => { + encountered_idents += 1; + new_name.take().unwrap() + } + TokenTree::Ident(_) => { + encountered_idents += 1; + token + } + _ => token, + }) + .collect::(); + let mut input_again = input.parse::().unwrap(); + input_again.extend(ret); + input_again +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/edition-imports-2015.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/edition-imports-2015.rs new file mode 100644 index 000000000000..9f31e1031fb5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/edition-imports-2015.rs @@ -0,0 +1,21 @@ +// edition:2015 +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Derive2015)] +pub fn derive_2015(_: TokenStream) -> TokenStream { + " + use import::Path; + + fn check_absolute() { + let x = ::absolute::Path; + } + ".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/empty-crate.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/empty-crate.rs new file mode 100644 index 000000000000..df1a12a5f63a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/empty-crate.rs @@ -0,0 +1,6 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![deny(unused_variables)] + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/expand-with-a-macro.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/expand-with-a-macro.rs new file mode 100644 index 000000000000..d54248a9bff2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/expand-with-a-macro.rs @@ -0,0 +1,23 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![deny(warnings)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(A)] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert!(input.contains("struct A ;")); + r#" + impl A { + fn a(&self) { + panic!("hello"); + } + } + "#.parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/external-crate-var.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/external-crate-var.rs new file mode 100644 index 000000000000..09e5aea9b830 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/external-crate-var.rs @@ -0,0 +1,41 @@ +pub struct ExternFoo; + +pub trait ExternTrait { + const CONST: u32; + type Assoc; +} + +impl ExternTrait for ExternFoo { + const CONST: u32 = 0; + type Assoc = ExternFoo; +} + +#[macro_export] +macro_rules! external { () => { + mod bar { + #[derive(Double)] + struct Bar($crate::ExternFoo); + } + + mod qself { + #[derive(Double)] + struct QSelf(<$crate::ExternFoo as $crate::ExternTrait>::Assoc); + } + + mod qself_recurse { + #[derive(Double)] + struct QSelfRecurse(< + <$crate::ExternFoo as $crate::ExternTrait>::Assoc + as $crate::ExternTrait>::Assoc + ); + } + + mod qself_in_const { + #[derive(Double)] + #[repr(u32)] + enum QSelfInConst { + Variant = <$crate::ExternFoo as $crate::ExternTrait>::CONST, + } + } +} } + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/first-second.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/first-second.rs new file mode 100644 index 000000000000..ef76d6605a88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/first-second.rs @@ -0,0 +1,21 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{TokenStream, TokenTree, Group, Delimiter}; + +#[proc_macro_attribute] +pub fn first(_attr: TokenStream, item: TokenStream) -> TokenStream { + let tokens: TokenStream = "#[derive(Second)]".parse().unwrap(); + let wrapped = TokenTree::Group(Group::new(Delimiter::None, item.into_iter().collect())); + tokens.into_iter().chain(std::iter::once(wrapped)).collect() +} + +#[proc_macro_derive(Second)] +pub fn second(item: TokenStream) -> TokenStream { + TokenStream::new() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/gen-lifetime-token.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/gen-lifetime-token.rs new file mode 100644 index 000000000000..7445a7ddc260 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/gen-lifetime-token.rs @@ -0,0 +1,26 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro] +pub fn bar(_input: TokenStream) -> TokenStream { + let mut ret = Vec::::new(); + ret.push(Ident::new("static", Span::call_site()).into()); + ret.push(Ident::new("FOO", Span::call_site()).into()); + ret.push(Punct::new(':', Spacing::Alone).into()); + ret.push(Punct::new('&', Spacing::Alone).into()); + ret.push(Punct::new('\'', Spacing::Joint).into()); + ret.push(Ident::new("static", Span::call_site()).into()); + ret.push(Ident::new("i32", Span::call_site()).into()); + ret.push(Punct::new('=', Spacing::Alone).into()); + ret.push(Punct::new('&', Spacing::Alone).into()); + ret.push(Literal::i32_unsuffixed(1).into()); + ret.push(Punct::new(';', Spacing::Alone).into()); + ret.into_iter().collect() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/gen-macro-rules-hygiene.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/gen-macro-rules-hygiene.rs new file mode 100644 index 000000000000..0fc2357802f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/gen-macro-rules-hygiene.rs @@ -0,0 +1,24 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +pub fn gen_macro_rules(_: TokenStream) -> TokenStream { + " + macro_rules! generated {() => { + struct ItemDef; + let local_def = 0; + + ItemUse; // OK + local_use; // ERROR + break 'label_use; // ERROR + + type DollarCrate = $crate::ItemUse; // OK + }} + ".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/gen-macro-rules.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/gen-macro-rules.rs new file mode 100644 index 000000000000..50406a45f851 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/gen-macro-rules.rs @@ -0,0 +1,13 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_derive(repro)] +pub fn proc_macro_hack_expr(_input: TokenStream) -> TokenStream { + "macro_rules! m {()=>{}}".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/generate-dollar-ident.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/generate-dollar-ident.rs new file mode 100644 index 000000000000..48b7ef3e021b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/generate-dollar-ident.rs @@ -0,0 +1,17 @@ +// force-host +// no-prefer-dynamic + +#![feature(proc_macro_quote)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +pub fn dollar_ident(input: TokenStream) -> TokenStream { + let black_hole = input.into_iter().next().unwrap(); + quote! { + $black_hole!($$var); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/generate-mod.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/generate-mod.rs new file mode 100644 index 000000000000..f5cdca78e2ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/generate-mod.rs @@ -0,0 +1,59 @@ +// run-pass +// force-host +// no-prefer-dynamic +// ignore-pass + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +pub fn check(_: TokenStream) -> TokenStream { + " + type Alias = FromOutside; // OK + struct Outer; + mod inner { + type Alias = FromOutside; // `FromOutside` shouldn't be available from here + type Inner = Outer; // `Outer` shouldn't be available from here + } + ".parse().unwrap() +} + +#[proc_macro_attribute] +pub fn check_attr(_: TokenStream, _: TokenStream) -> TokenStream { + " + type AliasAttr = FromOutside; // OK + struct OuterAttr; + mod inner_attr { + type Alias = FromOutside; // `FromOutside` shouldn't be available from here + type Inner = OuterAttr; // `OuterAttr` shouldn't be available from here + } + ".parse().unwrap() +} + +#[proc_macro_derive(CheckDerive)] +pub fn check_derive(_: TokenStream) -> TokenStream { + " + type AliasDerive = FromOutside; // OK + struct OuterDerive; + mod inner_derive { + type Alias = FromOutside; // `FromOutside` shouldn't be available from here + type Inner = OuterDerive; // `OuterDerive` shouldn't be available from here + } + ".parse().unwrap() +} + +#[proc_macro_derive(CheckDeriveLint)] +pub fn check_derive_lint(_: TokenStream) -> TokenStream { + " + type AliasDeriveLint = FromOutside; // OK + struct OuterDeriveLint; + #[allow(proc_macro_derive_resolution_fallback)] + mod inner_derive_lint { + type Alias = FromOutside; // `FromOutside` shouldn't be available from here + type Inner = OuterDeriveLint; // `OuterDeriveLint` shouldn't be available from here + } + ".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/hygiene_example.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/hygiene_example.rs new file mode 100644 index 000000000000..fcf7a443ce3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/hygiene_example.rs @@ -0,0 +1,8 @@ +extern crate hygiene_example_codegen; + +pub use hygiene_example_codegen::hello; + +pub fn print(string: &str) { + println!("{}", string); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/hygiene_example_codegen.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/hygiene_example_codegen.rs new file mode 100644 index 000000000000..f74f5d047b55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/hygiene_example_codegen.rs @@ -0,0 +1,28 @@ +// force-host +// no-prefer-dynamic + +#![feature(proc_macro_quote)] +#![crate_type = "proc-macro"] + +extern crate proc_macro as proc_macro_renamed; // This does not break `quote!` + +use proc_macro_renamed::{TokenStream, quote}; + +#[proc_macro] +pub fn hello(input: TokenStream) -> TokenStream { + quote!(hello_helper!($input)) + //^ `hello_helper!` always resolves to the following proc macro, + //| no matter where `hello!` is used. +} + +#[proc_macro] +pub fn hello_helper(input: TokenStream) -> TokenStream { + quote! { + extern crate hygiene_example; // This is never a conflict error + let string = format!("hello {}", $input); + //^ `format!` always resolves to the prelude macro, + //| even if a different `format!` is in scope where `hello!` is used. + hygiene_example::print(&string) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/invalid-punct-ident.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/invalid-punct-ident.rs new file mode 100644 index 000000000000..3ad6464ccded --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/invalid-punct-ident.rs @@ -0,0 +1,29 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_raw_ident)] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +pub fn invalid_punct(_: TokenStream) -> TokenStream { + TokenTree::from(Punct::new('`', Spacing::Alone)).into() +} + +#[proc_macro] +pub fn invalid_ident(_: TokenStream) -> TokenStream { + TokenTree::from(Ident::new("*", Span::call_site())).into() +} + +#[proc_macro] +pub fn invalid_raw_ident(_: TokenStream) -> TokenStream { + TokenTree::from(Ident::new_raw("self", Span::call_site())).into() +} + +#[proc_macro] +pub fn lexer_failure(_: TokenStream) -> TokenStream { + "a b ) c".parse().expect("parsing failed without panic") +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/is-available.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/is-available.rs new file mode 100644 index 000000000000..97fa71483615 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/is-available.rs @@ -0,0 +1,15 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_is_available)] + +extern crate proc_macro; + +use proc_macro::{Literal, TokenStream, TokenTree}; + +#[proc_macro] +pub fn from_inside_proc_macro(_input: TokenStream) -> TokenStream { + proc_macro::is_available().to_string().parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-38586.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-38586.rs new file mode 100644 index 000000000000..c8c30bed8702 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-38586.rs @@ -0,0 +1,12 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +#[proc_macro_derive(A)] +pub fn derive_a(_: proc_macro::TokenStream) -> proc_macro::TokenStream { + "fn f() { println!(\"{}\", foo); }".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-39889.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-39889.rs new file mode 100644 index 000000000000..72c88a412b06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-39889.rs @@ -0,0 +1,18 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_derive(Issue39889)] +pub fn f(_input: TokenStream) -> TokenStream { + let rules = r#" + macro_rules! id { + ($($tt:tt)*) => { $($tt)* }; + } + "#; + rules.parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-42708.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-42708.rs new file mode 100644 index 000000000000..a3ebd00e32a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-42708.rs @@ -0,0 +1,19 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Test)] +pub fn derive(_input: TokenStream) -> TokenStream { + "fn f(s: S) { s.x }".parse().unwrap() +} + +#[proc_macro_attribute] +pub fn attr_test(_attr: TokenStream, input: TokenStream) -> TokenStream { + input +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-50061.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-50061.rs new file mode 100644 index 000000000000..706a27cf4a3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-50061.rs @@ -0,0 +1,13 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn check(_a: TokenStream, b: TokenStream) -> TokenStream { + b.into_iter().collect() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-50493.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-50493.rs new file mode 100644 index 000000000000..03d0df3463c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-50493.rs @@ -0,0 +1,22 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_derive(Derive)] +pub fn derive(_: TokenStream) -> TokenStream { + let code = " + fn one(r: Restricted) { + r.field; + } + fn two(r: Restricted) { + r.field; + } + "; + + code.parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-59191.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-59191.rs new file mode 100644 index 000000000000..2b088917cbf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/issue-59191.rs @@ -0,0 +1,17 @@ +// edition:2018 +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn no_main(_attrs: TokenStream, _input: TokenStream) -> TokenStream { + let new_krate = r#" + fn main() {} + "#; + new_krate.parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/lifetimes-rpass.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/lifetimes-rpass.rs new file mode 100644 index 000000000000..791f1feaf0ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/lifetimes-rpass.rs @@ -0,0 +1,27 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro] +pub fn lifetimes_bang(input: TokenStream) -> TokenStream { + // Roundtrip through token trees + input.into_iter().collect() +} + +#[proc_macro_attribute] +pub fn lifetimes_attr(_: TokenStream, input: TokenStream) -> TokenStream { + // Roundtrip through AST + input +} + +#[proc_macro_derive(Lifetimes)] +pub fn lifetimes_derive(input: TokenStream) -> TokenStream { + // Roundtrip through a string + format!("mod m {{ {} }}", input).parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/lifetimes.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/lifetimes.rs new file mode 100644 index 000000000000..576fb4e13989 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/lifetimes.rs @@ -0,0 +1,21 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro] +pub fn single_quote_alone(_: TokenStream) -> TokenStream { + // `&'a u8`, but the `'` token is not joint + let trees: Vec = vec![ + Punct::new('&', Spacing::Alone).into(), + Punct::new('\'', Spacing::Alone).into(), + Ident::new("a", Span::call_site()).into(), + Ident::new("u8", Span::call_site()).into(), + ]; + trees.into_iter().collect() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/macro-only-syntax.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/macro-only-syntax.rs new file mode 100644 index 000000000000..7dccad9b944f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/macro-only-syntax.rs @@ -0,0 +1,90 @@ +// force-host +// no-prefer-dynamic + +// These are tests for syntax that is accepted by the Rust parser but +// unconditionally rejected semantically after macro expansion. Attribute macros +// are permitted to accept such syntax as long as they replace it with something +// that makes sense to Rust. +// +// We also inspect some of the spans to verify the syntax is not triggering the +// lossy string reparse hack (https://github.com/rust-lang/rust/issues/43081). + +#![crate_type = "proc-macro"] +#![feature(proc_macro_span)] + +extern crate proc_macro; +use proc_macro::{token_stream, Delimiter, TokenStream, TokenTree}; +use std::path::Component; + +// unsafe mod m { +// pub unsafe mod inner; +// } +#[proc_macro_attribute] +pub fn expect_unsafe_mod(_attrs: TokenStream, input: TokenStream) -> TokenStream { + let tokens = &mut input.into_iter(); + expect(tokens, "unsafe"); + expect(tokens, "mod"); + expect(tokens, "m"); + let tokens = &mut expect_brace(tokens); + expect(tokens, "pub"); + expect(tokens, "unsafe"); + expect(tokens, "mod"); + let ident = expect(tokens, "inner"); + expect(tokens, ";"); + check_useful_span(ident, "unsafe-mod.rs"); + TokenStream::new() +} + +// unsafe extern { +// type T; +// } +#[proc_macro_attribute] +pub fn expect_unsafe_foreign_mod(_attrs: TokenStream, input: TokenStream) -> TokenStream { + let tokens = &mut input.into_iter(); + expect(tokens, "unsafe"); + expect(tokens, "extern"); + let tokens = &mut expect_brace(tokens); + expect(tokens, "type"); + let ident = expect(tokens, "T"); + expect(tokens, ";"); + check_useful_span(ident, "unsafe-foreign-mod.rs"); + TokenStream::new() +} + +// unsafe extern "C++" {} +#[proc_macro_attribute] +pub fn expect_unsafe_extern_cpp_mod(_attrs: TokenStream, input: TokenStream) -> TokenStream { + let tokens = &mut input.into_iter(); + expect(tokens, "unsafe"); + expect(tokens, "extern"); + let abi = expect(tokens, "\"C++\""); + expect_brace(tokens); + check_useful_span(abi, "unsafe-foreign-mod.rs"); + TokenStream::new() +} + +fn expect(tokens: &mut token_stream::IntoIter, expected: &str) -> TokenTree { + match tokens.next() { + Some(token) if token.to_string() == expected => token, + wrong => panic!("unexpected token: {:?}, expected `{}`", wrong, expected), + } +} + +fn expect_brace(tokens: &mut token_stream::IntoIter) -> token_stream::IntoIter { + match tokens.next() { + Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::Brace => { + group.stream().into_iter() + } + wrong => panic!("unexpected token: {:?}, expected `{{`", wrong), + } +} + +fn check_useful_span(token: TokenTree, expected_filename: &str) { + let span = token.span(); + assert!(span.start().column < span.end().column); + + let source_path = span.source_file().path(); + let filename = source_path.components().last().unwrap(); + assert_eq!(filename, Component::Normal(expected_filename.as_ref())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/make-macro.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/make-macro.rs new file mode 100644 index 000000000000..3869c2d90751 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/make-macro.rs @@ -0,0 +1,19 @@ +// force-host + +#[macro_export] +macro_rules! make_it { + ($name:ident) => { + #[proc_macro] + pub fn $name(input: TokenStream) -> TokenStream { + println!("Def site: {:?}", Span::def_site()); + println!("Input: {:?}", input); + let new: TokenStream = input.into_iter().map(|mut t| { + t.set_span(Span::def_site()); + t + }).collect(); + println!("Respanned: {:?}", new); + new + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/meta-delim.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/meta-delim.rs new file mode 100644 index 000000000000..a357a210c4e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/meta-delim.rs @@ -0,0 +1,13 @@ +macro_rules! produce_it { + ($dollar_one:tt $foo:ident $my_name:ident) => { + #[macro_export] + macro_rules! meta_delim { + ($dollar_one ($dollar_one $my_name:ident)*) => { + stringify!($dollar_one ($dollar_one $my_name)*) + } + } + } +} + +produce_it!($my_name name); + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/meta-macro.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/meta-macro.rs new file mode 100644 index 000000000000..163ca253daf7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/meta-macro.rs @@ -0,0 +1,16 @@ +// force-host +// no-prefer-dynamic +// edition:2018 + +#![feature(proc_macro_def_site)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; +extern crate make_macro; +use proc_macro::{TokenStream, Span}; + +make_macro::make_it!(print_def_site); + +#[proc_macro] +pub fn dummy(input: TokenStream) -> TokenStream { input } + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/mixed-site-span.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/mixed-site-span.rs new file mode 100644 index 000000000000..685aa5956e8b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/mixed-site-span.rs @@ -0,0 +1,41 @@ +// force-host +// no-prefer-dynamic + +#![feature(proc_macro_quote)] + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +pub fn proc_macro_rules(input: TokenStream) -> TokenStream { + if input.is_empty() { + let id = |s| TokenTree::from(Ident::new(s, Span::mixed_site())); + let item_def = id("ItemDef"); + let local_def = id("local_def"); + let item_use = id("ItemUse"); + let local_use = id("local_use"); + let mut single_quote = Punct::new('\'', Spacing::Joint); + single_quote.set_span(Span::mixed_site()); + let label_use: TokenStream = [ + TokenTree::from(single_quote), + id("label_use"), + ].iter().cloned().collect(); + quote!( + struct $item_def; + let $local_def = 0; + + $item_use; // OK + $local_use; // ERROR + break $label_use; // ERROR + ) + } else { + let mut dollar_crate = input.into_iter().next().unwrap(); + dollar_crate.set_span(Span::mixed_site()); + quote!( + type A = $dollar_crate::ItemUse; + ) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/modify-ast.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/modify-ast.rs new file mode 100644 index 000000000000..79248d91e537 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/modify-ast.rs @@ -0,0 +1,48 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro_attribute] +pub fn assert1(_a: TokenStream, b: TokenStream) -> TokenStream { + assert_eq(b.clone(), "pub fn foo() {}".parse().unwrap()); + b +} + +#[proc_macro_derive(Foo, attributes(foo))] +pub fn assert2(a: TokenStream) -> TokenStream { + assert_eq(a, "pub struct MyStructc { _a: i32, }".parse().unwrap()); + TokenStream::new() +} + +fn assert_eq(a: TokenStream, b: TokenStream) { + let mut a = a.into_iter(); + let mut b = b.into_iter(); + for (a, b) in a.by_ref().zip(&mut b) { + match (a, b) { + (TokenTree::Group(a), TokenTree::Group(b)) => { + assert_eq!(a.delimiter(), b.delimiter()); + assert_eq(a.stream(), b.stream()); + } + (TokenTree::Punct(a), TokenTree::Punct(b)) => { + assert_eq!(a.as_char(), b.as_char()); + assert_eq!(a.spacing(), b.spacing()); + } + (TokenTree::Literal(a), TokenTree::Literal(b)) => { + assert_eq!(a.to_string(), b.to_string()); + } + (TokenTree::Ident(a), TokenTree::Ident(b)) => { + assert_eq!(a.to_string(), b.to_string()); + } + (a, b) => panic!("{:?} != {:?}", a, b), + } + } + + assert!(a.next().is_none()); + assert!(b.next().is_none()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/multispan.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/multispan.rs new file mode 100644 index 000000000000..7a8970cdcef2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/multispan.rs @@ -0,0 +1,38 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_diagnostic, proc_macro_span, proc_macro_def_site)] + +extern crate proc_macro; + +use proc_macro::{TokenStream, TokenTree, Span, Diagnostic}; + +fn parse(input: TokenStream) -> Result<(), Diagnostic> { + let mut hi_spans = vec![]; + for tree in input { + if let TokenTree::Ident(ref ident) = tree { + if ident.to_string() == "hi" { + hi_spans.push(ident.span()); + } + } + } + + if !hi_spans.is_empty() { + return Err(Span::def_site() + .error("hello to you, too!") + .span_note(hi_spans, "found these 'hi's")); + } + + Ok(()) +} + +#[proc_macro] +pub fn hello(input: TokenStream) -> TokenStream { + if let Err(diag) = parse(input) { + diag.emit(); + } + + TokenStream::new() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/negative-token.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/negative-token.rs new file mode 100644 index 000000000000..1c9f44ebb1f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/negative-token.rs @@ -0,0 +1,19 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro] +pub fn neg_one(_input: TokenStream) -> TokenStream { + TokenTree::Literal(Literal::i32_suffixed(-1)).into() +} + +#[proc_macro] +pub fn neg_one_float(_input: TokenStream) -> TokenStream { + TokenTree::Literal(Literal::f32_suffixed(-1.0)).into() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/nested-macro-rules.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/nested-macro-rules.rs new file mode 100644 index 000000000000..5de98f75513f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/nested-macro-rules.rs @@ -0,0 +1,16 @@ +pub struct FirstStruct; + +#[macro_export] +macro_rules! outer_macro { + ($name:ident) => { + #[macro_export] + macro_rules! inner_macro { + ($wrapper:ident) => { + $wrapper!($name) + } + } + } +} + +outer_macro!(FirstStruct); + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/not-joint.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/not-joint.rs new file mode 100644 index 000000000000..b98750627968 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/not-joint.rs @@ -0,0 +1,31 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro] +pub fn tokens(input: TokenStream) -> TokenStream { + assert_nothing_joint(input); + TokenStream::new() +} + +#[proc_macro_attribute] +pub fn nothing(_: TokenStream, input: TokenStream) -> TokenStream { + assert_nothing_joint(input); + TokenStream::new() +} + +fn assert_nothing_joint(s: TokenStream) { + for tt in s { + match tt { + TokenTree::Group(g) => assert_nothing_joint(g.stream()), + TokenTree::Punct(p) => assert_eq!(p.spacing(), Spacing::Alone), + _ => {} + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/parent-source-spans.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/parent-source-spans.rs new file mode 100644 index 000000000000..ef4b87903aee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/parent-source-spans.rs @@ -0,0 +1,44 @@ +// force-host +// no-prefer-dynamic + +#![feature(proc_macro_diagnostic, proc_macro_span)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{TokenStream, TokenTree, Span}; + +fn lit_span(tt: TokenTree) -> (Span, String) { + match tt { + TokenTree::Literal(..) | + TokenTree::Group(..) => (tt.span(), tt.to_string().trim().into()), + _ => panic!("expected a literal in token tree, got: {:?}", tt) + } +} + +#[proc_macro] +pub fn parent_source_spans(input: TokenStream) -> TokenStream { + let mut tokens = input.into_iter(); + let (sp1, str1) = lit_span(tokens.next().expect("first string")); + let _ = tokens.next(); + let (sp2, str2) = lit_span(tokens.next().expect("second string")); + + sp1.error(format!("first final: {}", str1)).emit(); + sp2.error(format!("second final: {}", str2)).emit(); + + if let (Some(p1), Some(p2)) = (sp1.parent(), sp2.parent()) { + p1.error(format!("first parent: {}", str1)).emit(); + p2.error(format!("second parent: {}", str2)).emit(); + + if let (Some(gp1), Some(gp2)) = (p1.parent(), p2.parent()) { + gp1.error(format!("first grandparent: {}", str1)).emit(); + gp2.error(format!("second grandparent: {}", str2)).emit(); + } + } + + sp1.source().error(format!("first source: {}", str1)).emit(); + sp2.source().error(format!("second source: {}", str2)).emit(); + + "ok".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/raw-ident.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/raw-ident.rs new file mode 100644 index 000000000000..46e9d7f18e11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/raw-ident.rs @@ -0,0 +1,36 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::{TokenStream, TokenTree, Ident, Punct, Spacing, Span}; + +#[proc_macro] +pub fn make_struct(input: TokenStream) -> TokenStream { + match input.into_iter().next().unwrap() { + TokenTree::Ident(ident) => { + vec![ + TokenTree::Ident(Ident::new("struct", Span::call_site())), + TokenTree::Ident(Ident::new_raw(&ident.to_string(), Span::call_site())), + TokenTree::Punct(Punct::new(';', Spacing::Alone)) + ].into_iter().collect() + } + _ => panic!() + } +} + +#[proc_macro] +pub fn make_bad_struct(input: TokenStream) -> TokenStream { + match input.into_iter().next().unwrap() { + TokenTree::Ident(ident) => { + vec![ + TokenTree::Ident(Ident::new_raw("struct", Span::call_site())), + TokenTree::Ident(Ident::new(&ident.to_string(), Span::call_site())), + TokenTree::Punct(Punct::new(';', Spacing::Alone)) + ].into_iter().collect() + } + _ => panic!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/recollect.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/recollect.rs new file mode 100644 index 000000000000..07ab088ea420 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/recollect.rs @@ -0,0 +1,13 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub fn recollect(tokens: TokenStream) -> TokenStream { + tokens.into_iter().collect() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/resolved-located-at.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/resolved-located-at.rs new file mode 100644 index 000000000000..f1fd768df04d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/resolved-located-at.rs @@ -0,0 +1,32 @@ +// force-host +// no-prefer-dynamic + +#![feature(proc_macro_def_site)] +#![feature(proc_macro_diagnostic)] +#![feature(proc_macro_quote)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +pub fn resolve_located_at(input: TokenStream) -> TokenStream { + match &*input.into_iter().collect::>() { + [a, b, ..] => { + // The error is reported at input `a`. + let mut diag = Diagnostic::new(Level::Error, "expected error"); + diag.set_spans(Span::def_site().located_at(a.span())); + diag.emit(); + + // Resolves to `struct S;` at def site, but the error is reported at input `b`. + let s = TokenTree::Ident(Ident::new("S", b.span().resolved_at(Span::def_site()))); + quote!({ + struct S; + + $s + }) + } + _ => panic!("unexpected input"), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/span-api-tests.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/span-api-tests.rs new file mode 100644 index 000000000000..9092e7a49ea6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/span-api-tests.rs @@ -0,0 +1,46 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_span)] + +extern crate proc_macro; + +use proc_macro::*; + +// Re-emits the input tokens by parsing them from strings +#[proc_macro] +pub fn reemit(input: TokenStream) -> TokenStream { + input.to_string().parse().unwrap() +} + +#[proc_macro] +pub fn assert_fake_source_file(input: TokenStream) -> TokenStream { + for tk in input { + let source_file = tk.span().source_file(); + assert!(!source_file.is_real(), "Source file is real: {:?}", source_file); + } + + "".parse().unwrap() +} + +#[proc_macro] +pub fn assert_source_file(input: TokenStream) -> TokenStream { + for tk in input { + let source_file = tk.span().source_file(); + assert!(source_file.is_real(), "Source file is not real: {:?}", source_file); + } + + "".parse().unwrap() +} + +#[proc_macro] +pub fn macro_stringify(input: TokenStream) -> TokenStream { + let mut tokens = input.into_iter(); + let first_span = tokens.next().expect("first token").span(); + let last_span = tokens.last().map(|x| x.span()).unwrap_or(first_span); + let span = first_span.join(last_span).expect("joined span"); + let src = span.source_text().expect("source_text"); + TokenTree::Literal(Literal::string(&src)).into() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/span-test-macros.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/span-test-macros.rs new file mode 100644 index 000000000000..bce2d20bc19a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/span-test-macros.rs @@ -0,0 +1,10 @@ +#[macro_export] +macro_rules! reemit_legacy { + ($($tok:tt)*) => ($($tok)*) +} + +#[macro_export] +macro_rules! say_hello_extern { + ($macname:ident) => ( $macname! { "Hello, world!" }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/subspan.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/subspan.rs new file mode 100644 index 000000000000..057841baea35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/subspan.rs @@ -0,0 +1,39 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_diagnostic, proc_macro_span)] + +extern crate proc_macro; + +use proc_macro::{TokenStream, TokenTree, Span, Diagnostic}; + +fn parse(input: TokenStream) -> Result<(), Diagnostic> { + if let Some(TokenTree::Literal(lit)) = input.into_iter().next() { + let mut spans = vec![]; + let string = lit.to_string(); + for hi in string.matches("hi") { + let index = hi.as_ptr() as usize - string.as_ptr() as usize; + let subspan = lit.subspan(index..(index + hi.len())).unwrap(); + spans.push(subspan); + } + + if !spans.is_empty() { + Err(Span::call_site().error("found 'hi's").span_note(spans, "here")) + } else { + Ok(()) + } + } else { + Err(Span::call_site().error("invalid input: expected string literal")) + } +} + +#[proc_macro] +pub fn subspan(input: TokenStream) -> TokenStream { + if let Err(diag) = parse(input) { + diag.emit(); + } + + TokenStream::new() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/test-macros.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/test-macros.rs new file mode 100644 index 000000000000..586c8e21e7c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/test-macros.rs @@ -0,0 +1,126 @@ +// force-host +// no-prefer-dynamic + +// Proc macros commonly used by tests. +// `panic`/`print` -> `panic_bang`/`print_bang` to avoid conflicts with standard macros. + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +// Macro that return empty token stream. + +#[proc_macro] +pub fn empty(_: TokenStream) -> TokenStream { + TokenStream::new() +} + +#[proc_macro_attribute] +pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { + TokenStream::new() +} + +#[proc_macro_derive(Empty, attributes(empty_helper))] +pub fn empty_derive(_: TokenStream) -> TokenStream { + TokenStream::new() +} + +// Macro that panics. + +#[proc_macro] +pub fn panic_bang(_: TokenStream) -> TokenStream { + panic!("panic-bang"); +} + +#[proc_macro_attribute] +pub fn panic_attr(_: TokenStream, _: TokenStream) -> TokenStream { + panic!("panic-attr"); +} + +#[proc_macro_derive(Panic, attributes(panic_helper))] +pub fn panic_derive(_: TokenStream) -> TokenStream { + panic!("panic-derive"); +} + +// Macros that return the input stream. + +#[proc_macro] +pub fn identity(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_attribute] +pub fn identity_attr(_: TokenStream, input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive(Identity, attributes(identity_helper))] +pub fn identity_derive(input: TokenStream) -> TokenStream { + input +} + +// Macros that iterate and re-collect the input stream. + +#[proc_macro] +pub fn recollect(input: TokenStream) -> TokenStream { + input.into_iter().collect() +} + +#[proc_macro_attribute] +pub fn recollect_attr(_: TokenStream, input: TokenStream) -> TokenStream { + input.into_iter().collect() +} + +#[proc_macro_derive(Recollect, attributes(recollect_helper))] +pub fn recollect_derive(input: TokenStream) -> TokenStream { + input.into_iter().collect() +} + +// Macros that print their input in the original and re-collected forms (if they differ). + +fn print_helper(input: TokenStream, kind: &str) -> TokenStream { + let input_display = format!("{}", input); + let input_debug = format!("{:#?}", input); + let recollected = input.into_iter().collect(); + let recollected_display = format!("{}", recollected); + let recollected_debug = format!("{:#?}", recollected); + println!("PRINT-{} INPUT (DISPLAY): {}", kind, input_display); + if recollected_display != input_display { + println!("PRINT-{} RE-COLLECTED (DISPLAY): {}", kind, recollected_display); + } + println!("PRINT-{} INPUT (DEBUG): {}", kind, input_debug); + if recollected_debug != input_debug { + println!("PRINT-{} RE-COLLECTED (DEBUG): {}", kind, recollected_debug); + } + recollected +} + +#[proc_macro] +pub fn print_bang(input: TokenStream) -> TokenStream { + print_helper(input, "BANG") +} + +#[proc_macro] +pub fn print_bang_consume(input: TokenStream) -> TokenStream { + print_helper(input, "BANG"); + TokenStream::new() +} + +#[proc_macro_attribute] +pub fn print_attr(_: TokenStream, input: TokenStream) -> TokenStream { + print_helper(input, "ATTR") +} + +#[proc_macro_attribute] +pub fn print_attr_args(args: TokenStream, input: TokenStream) -> TokenStream { + print_helper(args, "ATTR_ARGS"); + input +} + +#[proc_macro_derive(Print, attributes(print_helper))] +pub fn print_derive(input: TokenStream) -> TokenStream { + print_helper(input, "DERIVE"); + TokenStream::new() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/three-equals.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/three-equals.rs new file mode 100644 index 000000000000..45447cad3487 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/three-equals.rs @@ -0,0 +1,50 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_diagnostic, proc_macro_span, proc_macro_def_site)] + +extern crate proc_macro; + +use proc_macro::{TokenStream, TokenTree, Span, Diagnostic}; + +fn parse(input: TokenStream) -> Result<(), Diagnostic> { + let mut count = 0; + let mut last_span = Span::def_site(); + for tree in input { + let span = tree.span(); + if count >= 3 { + return Err(span.error(format!("expected EOF, found `{}`.", tree)) + .span_note(last_span, "last good input was here") + .help("input must be: `===`")) + } + + if let TokenTree::Punct(ref tt) = tree { + if tt.as_char() == '=' { + count += 1; + last_span = span; + continue + } + } + return Err(span.error(format!("expected `=`, found `{}`.", tree))); + } + + if count < 3 { + return Err(Span::def_site() + .error(format!("found {} equal signs, need exactly 3", count)) + .help("input must be: `===`")) + } + + Ok(()) +} + +#[proc_macro] +pub fn three_equals(input: TokenStream) -> TokenStream { + if let Err(diag) = parse(input) { + diag.emit(); + return TokenStream::new(); + } + + "3".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/weird-hygiene.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/weird-hygiene.rs new file mode 100644 index 000000000000..cbd79eacdc67 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/auxiliary/weird-hygiene.rs @@ -0,0 +1,49 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{TokenStream, TokenTree, Group}; + +fn find_my_ident(tokens: TokenStream) -> Option { + for token in tokens { + if let TokenTree::Ident(ident) = &token { + if ident.to_string() == "hidden_ident" { + return Some(vec![token].into_iter().collect()) + } + } else if let TokenTree::Group(g) = token { + if let Some(stream) = find_my_ident(g.stream()) { + return Some(stream) + } + } + } + return None; +} + + +#[proc_macro_derive(WeirdDerive)] +pub fn weird_derive(item: TokenStream) -> TokenStream { + let my_ident = find_my_ident(item).expect("Missing 'my_ident'!"); + let tokens: TokenStream = "call_it!();".parse().unwrap(); + let final_call = tokens.into_iter().map(|tree| { + if let TokenTree::Group(g) = tree { + return Group::new(g.delimiter(), my_ident.clone()).into() + } else { + return tree + } + }).collect(); + final_call +} + +#[proc_macro] +pub fn recollect(item: TokenStream) -> TokenStream { + item.into_iter().collect() +} + +#[proc_macro_attribute] +pub fn recollect_attr(_attr: TokenStream, mut item: TokenStream) -> TokenStream { + item.into_iter().collect() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/bang-macro.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/bang-macro.rs new file mode 100644 index 000000000000..3ab89f7bbce1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/bang-macro.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:bang-macro.rs + +extern crate bang_macro; +use bang_macro::rewrite; + +fn main() { + assert_eq!(rewrite!("Hello, world!"), "NOT Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/break-token-spans.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/break-token-spans.rs new file mode 100644 index 000000000000..002525ac622e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/break-token-spans.rs @@ -0,0 +1,17 @@ +// aux-build:test-macros.rs +// Regression test for issues #68489 and #70987 +// Tests that we properly break tokens in `probably_equal_for_proc_macro` +// See #72306 +// +// Note that the weird spacing in this example is critical +// for testing the issue. + +extern crate test_macros; + +#[test_macros::recollect_attr] +fn repro() { + f :: < Vec < _ > > ( ) ; // { dg-error ".E0425." "" { target *-*-* } } + let a: Option>= true; // { dg-error ".E0308." "" { target *-*-* } } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/call-site.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/call-site.rs new file mode 100644 index 000000000000..38769486b150 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/call-site.rs @@ -0,0 +1,11 @@ +// check-pass +// aux-build:call-site.rs + +extern crate call_site; + +fn main() { + let x1 = 10; + call_site::check!(let x2 = x1;); + let x6 = x5; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/capture-macro-rules-invoke.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/capture-macro-rules-invoke.rs new file mode 100644 index 000000000000..a7794993373c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/capture-macro-rules-invoke.rs @@ -0,0 +1,58 @@ +// aux-build:test-macros.rs +// check-pass +// compile-flags: -Z span-debug + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +extern crate test_macros; +use test_macros::{print_bang, print_bang_consume}; + +macro_rules! test_matchers { + ($expr:expr, $block:block, $stmt:stmt, $ty:ty, $ident:ident, $lifetime:lifetime, + $meta:meta, $path:path, $vis:vis, $tt:tt, $lit:literal) => { + print_bang_consume!($expr, $block, $stmt, $ty, $ident, + $lifetime, $meta, $path, $vis, $tt, $lit) + } +} + +macro_rules! use_expr { + ($expr:expr) => { + print_bang!($expr) + } +} + +macro_rules! use_pat { + ($pat:pat) => { + print_bang!($pat) + } +} + +#[allow(dead_code)] +struct Foo; +impl Foo { + #[allow(dead_code)] + fn use_self(self) { + drop(use_expr!(self)); + test_matchers!( + 1 + 1, + { "a" }, + let a = 1, + String, + my_name, + 'a, + my_val = 30, + std::option::Option, + pub(in some::path), + [ a b c ], + -30 + ); + } + + fn with_pat(use_pat!((a, b)): (u32, u32)) { + let _ = (a, b); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/count_compound_ops.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/count_compound_ops.rs new file mode 100644 index 000000000000..5c123aa64178 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/count_compound_ops.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:count_compound_ops.rs + +extern crate count_compound_ops; +use count_compound_ops::count_compound_ops; + +fn main() { + assert_eq!(count_compound_ops!(foo<=>bar << { + // derive_Double outputs secondary copies of each definition + // to test what the proc_macro sees. + mod bar { + #[derive(Double)] + struct Bar($crate::Foo); + } + + mod qself { + #[derive(Double)] + struct QSelf(<::Foo as $crate::Trait>::Assoc); + } + + mod qself_recurse { + #[derive(Double)] + struct QSelfRecurse(<<$crate::Foo as $crate::Trait>::Assoc as $crate::Trait>::Assoc); + } + + mod qself_in_const { + #[derive(Double)] + #[repr(u32)] + enum QSelfInConst { + Variant = <::Foo as $crate::Trait>::CONST, + } + } +} } + +mod local { + local!(); +} + +// and now repeat the above tests, using a macro defined in another crate + +mod external { + external!{} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/crt-static.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/crt-static.rs new file mode 100644 index 000000000000..6367bc657d50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/crt-static.rs @@ -0,0 +1,18 @@ +// Test proc-macro crate can be built without additional RUSTFLAGS +// on musl target +// override -Ctarget-feature=-crt-static from compiletest +// compile-flags: -Ctarget-feature= +// ignore-wasm32 +// ignore-sgx no support for proc-macro crate type +// build-pass +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Foo)] +pub fn derive_foo(input: TokenStream) -> TokenStream { + input +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/custom-attr-only-one-derive.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/custom-attr-only-one-derive.rs new file mode 100644 index 000000000000..82b15a8fca38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/custom-attr-only-one-derive.rs @@ -0,0 +1,17 @@ +// run-pass +// aux-build:custom-attr-only-one-derive.rs + +#![feature(rust_2018_preview)] + +#[macro_use] +extern crate custom_attr_only_one_derive; + +#[derive(Bar, Foo)] +#[custom = "test"] +pub enum A { + B, + C, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/debug/auxiliary/macro-dump-debug.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/debug/auxiliary/macro-dump-debug.rs new file mode 100644 index 000000000000..b2e3aec1a384 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/debug/auxiliary/macro-dump-debug.rs @@ -0,0 +1,16 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![crate_name = "macro_dump_debug"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub fn dump_debug(tokens: TokenStream) -> TokenStream { + eprintln!("{:?}", tokens); + eprintln!("{:#?}", tokens); + TokenStream::new() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/debug/dump-debug-span-debug.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/debug/dump-debug-span-debug.rs new file mode 100644 index 000000000000..03a1567b45d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/debug/dump-debug-span-debug.rs @@ -0,0 +1,42 @@ +// run-pass +// aux-build:macro-dump-debug.rs +// compile-flags: -Z span-debug + +extern crate macro_dump_debug; +use macro_dump_debug::dump_debug; + +dump_debug! { + ident // ident + r#ident // raw ident + , // alone punct + ==> // joint punct + () // empty group + [_] // nonempty group + + // unsuffixed literals + 0 + 1.0 + "S" + b"B" + r"R" + r##"R"## + br"BR" + br##"BR"## + 'C' + b'B' + + // suffixed literals + 0q + 1.0q + "S"q + b"B"q + r"R"q + r##"R"##q + br"BR"q + br##"BR"##q + 'C'q + b'B'q +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/debug/dump-debug.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/debug/dump-debug.rs new file mode 100644 index 000000000000..e05bfa5f26e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/debug/dump-debug.rs @@ -0,0 +1,41 @@ +// run-pass +// aux-build:macro-dump-debug.rs + +extern crate macro_dump_debug; +use macro_dump_debug::dump_debug; + +dump_debug! { + ident // ident + r#ident // raw ident + , // alone punct + ==> // joint punct + () // empty group + [_] // nonempty group + + // unsuffixed literals + 0 + 1.0 + "S" + b"B" + r"R" + r##"R"## + br"BR" + br##"BR"## + 'C' + b'B' + + // suffixed literals + 0q + 1.0q + "S"q + b"B"q + r"R"q + r##"R"##q + br"BR"q + br##"BR"##q + 'C'q + b'B'q +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/define-two.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/define-two.rs new file mode 100644 index 000000000000..080f2b962de2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/define-two.rs @@ -0,0 +1,19 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(A)] +pub fn foo(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive(A)] // { dg-error ".E0428." "" { target *-*-* } } +pub fn bar(input: TokenStream) -> TokenStream { + input +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-attr-cfg.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-attr-cfg.rs new file mode 100644 index 000000000000..2ff45fa75477 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-attr-cfg.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(dead_code)] +// aux-build:derive-attr-cfg.rs + +extern crate derive_attr_cfg; +use derive_attr_cfg::Foo; + +#[derive(Foo)] +#[foo] +struct S { + #[cfg(any())] + x: i32 +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-b.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-b.rs new file mode 100644 index 000000000000..1caf6a439104 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-b.rs @@ -0,0 +1,20 @@ +// run-pass +// aux-build:derive-b-rpass.rs + +extern crate derive_b_rpass as derive_b; + +#[derive(Debug, PartialEq, derive_b::B, Eq, Copy, Clone)] +#[cfg_attr(all(), B[arbitrary tokens])] +struct B { + #[C] + a: u64 +} + +fn main() { + B { a: 3 }; + assert_eq!(B { a: 3 }, B { a: 3 }); + let b = B { a: 3 }; + let _d = b; + let _e = b; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-bad.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-bad.rs new file mode 100644 index 000000000000..13825e6febe8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-bad.rs @@ -0,0 +1,12 @@ +// aux-build:derive-bad.rs + +#[macro_use] +extern crate derive_bad; + +#[derive(A)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +struct A; // { dg-error ".E0428." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-configured.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-configured.rs new file mode 100644 index 000000000000..c27fb2e05fb5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-configured.rs @@ -0,0 +1,19 @@ +// Derive helpers are resolved successfully inside `cfg_attr`. + +// check-pass +// compile-flats:--cfg TRUE +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +#[cfg_attr(TRUE, empty_helper)] +#[derive(Empty)] +#[cfg_attr(TRUE, empty_helper)] +struct S { + #[cfg_attr(TRUE, empty_helper)] + field: u8, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-shadowed.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-shadowed.rs new file mode 100644 index 000000000000..ff3ed97eda09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-shadowed.rs @@ -0,0 +1,17 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:test-macros.rs +// aux-build:derive-helper-shadowed-2.rs + +#[macro_use] +extern crate test_macros; +#[macro_use(empty_helper)] +extern crate derive_helper_shadowed_2; + +macro_rules! empty_helper { () => () } + +#[derive(Empty)] +#[empty_helper] // OK +struct S; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-shadowing-2.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-shadowing-2.rs new file mode 100644 index 000000000000..4eb103417532 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-shadowing-2.rs @@ -0,0 +1,17 @@ +// If a derive macro introduces a helper attribute with the same name as that macro, +// then make sure that it's usable without ambiguities. + +// check-pass +// aux-build:derive-helper-shadowing-2.rs + +#[macro_use] +extern crate derive_helper_shadowing_2; + +#[derive(same_name)] +struct S { + #[same_name] // OK, no ambiguity, derive helpers have highest priority + field: u8, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-shadowing.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-shadowing.rs new file mode 100644 index 000000000000..9e3d21b31592 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-helper-shadowing.rs @@ -0,0 +1,55 @@ +// edition:2018 +// aux-build:test-macros.rs +// aux-build:derive-helper-shadowing.rs + +#[macro_use] +extern crate test_macros; +#[macro_use] +extern crate derive_helper_shadowing; + +use test_macros::empty_attr as empty_helper; + +macro_rules! gen_helper_use { + () => { + #[empty_helper] // { dg-error "" "" { target *-*-* } } + struct W; + } +} + +#[empty_helper] // { dg-error ".E0659." "" { target *-*-* } } +#[derive(Empty)] +struct S { + #[empty_helper] // OK, no ambiguity, derive helpers have highest priority + field: [u8; { + use empty_helper; // { dg-error ".E0659." "" { target *-*-* } } + + #[empty_helper] // OK, no ambiguity, derive helpers have highest priority + struct U; + + mod inner { + // OK, no ambiguity, the non-helper attribute is not in scope here, only the helper. + #[empty_helper] + struct V; + + gen_helper_use!(); + + #[derive(GenHelperUse)] // { dg-error "" "" { target *-*-* } } + struct Owo; + + use empty_helper as renamed; + #[renamed] // { dg-error "" "" { target *-*-* } } + struct Wow; + } + + 0 + }] +} + +// OK, no ambiguity, only the non-helper attribute is in scope. +#[empty_helper] +struct Z; + +fn main() { + let s = S { field: [] }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-in-mod.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-in-mod.rs new file mode 100644 index 000000000000..88bc64e0749b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-in-mod.rs @@ -0,0 +1,14 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:test-macros.rs + +extern crate test_macros; + +mod inner { + use test_macros::Empty; + + #[derive(Empty)] + struct S; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-same-struct.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-same-struct.rs new file mode 100644 index 000000000000..e42d3d7c7459 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-same-struct.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(path_statements)] +#![allow(dead_code)] +// aux-build:derive-same-struct.rs + +#[macro_use] +extern crate derive_same_struct; + +#[derive(AToB)] +struct A; + +fn main() { + C; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-still-gated.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-still-gated.rs new file mode 100644 index 000000000000..b4702f13a3dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-still-gated.rs @@ -0,0 +1,10 @@ +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +#[derive_Empty] // { dg-error "" "" { target *-*-* } } +struct A; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-test.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-test.rs new file mode 100644 index 000000000000..9550db3a075b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-test.rs @@ -0,0 +1,23 @@ +// run-pass +// no-prefer-dynamic +// compile-flags: --test + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +// ``` +// assert!(true); +// ``` +#[proc_macro_derive(Foo)] +pub fn derive_foo(_input: TokenStream) -> TokenStream { + "".parse().unwrap() +} + +#[test] +pub fn test_derive() { + assert!(true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-two-attrs.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-two-attrs.rs new file mode 100644 index 000000000000..1d2aa7055e5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-two-attrs.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(dead_code)] +// aux-build:derive-two-attrs.rs + +extern crate derive_two_attrs as foo; + +use foo::A; + +#[derive(A)] +#[b] +#[b] +struct B; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/derive-union.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-union.rs new file mode 100644 index 000000000000..4181e222792d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/derive-union.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(unused_variables)] +// aux-build:derive-union.rs + +#[macro_use] +extern crate derive_union; + +#[repr(C)] +#[derive(UnionTest)] +union Test { + a: u8, +} + +fn main() { + let t = Test { a: 0 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/disappearing-resolution.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/disappearing-resolution.rs new file mode 100644 index 000000000000..26b57b9062bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/disappearing-resolution.rs @@ -0,0 +1,23 @@ +// Regression test for issue #64803 (initial attribute resolution can disappear later). + +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +mod m { + use test_macros::Empty; +} +use m::Empty; // { dg-error ".E0603." "" { target *-*-* } } + +// To resolve `empty_helper` we need to resolve `Empty`. +// During initial resolution `use m::Empty` introduces no entries, so we proceed to `macro_use`, +// successfully resolve `Empty` from there, and then resolve `empty_helper` as its helper. +// During validation `use m::Empty` introduces a `Res::Err` stub, so `Empty` resolves to it, +// and `empty_helper` can no longer be resolved. +#[empty_helper] // { dg-error "" "" { target *-*-* } } +#[derive(Empty)] +struct S; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/doc-comment-preserved.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/doc-comment-preserved.rs new file mode 100644 index 000000000000..a1a905d59e2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/doc-comment-preserved.rs @@ -0,0 +1,25 @@ +// check-pass +// compile-flags: -Z span-debug +// aux-build:test-macros.rs + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] +extern crate test_macros; + +print_bang! { + +/** +******* +* DOC * +* DOC * +* DOC * +******* +*/ +pub struct S; + +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/dollar-crate-issue-57089.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/dollar-crate-issue-57089.rs new file mode 100644 index 000000000000..cd7eb32492a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/dollar-crate-issue-57089.rs @@ -0,0 +1,28 @@ +// check-pass +// edition:2018 +// compile-flags: -Z span-debug +// aux-build:test-macros.rs + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] +extern crate test_macros; + +type S = u8; + +macro_rules! m { + () => { + print_bang! { + struct M($crate::S); + } + + #[print_attr] + struct A($crate::S); + }; +} + +m!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/dollar-crate-issue-62325.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/dollar-crate-issue-62325.rs new file mode 100644 index 000000000000..53250a35f22d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/dollar-crate-issue-62325.rs @@ -0,0 +1,27 @@ +// check-pass +// edition:2018 +// compile-flags: -Z span-debug +// aux-build:test-macros.rs +// aux-build:dollar-crate-external.rs + + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] +extern crate test_macros; +extern crate dollar_crate_external; + +type S = u8; + +macro_rules! m { () => { + #[print_attr] + struct A(identity!($crate::S)); +}} + +m!(); + +dollar_crate_external::issue_62325!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/dollar-crate.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/dollar-crate.rs new file mode 100644 index 000000000000..789546abfdd9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/dollar-crate.rs @@ -0,0 +1,41 @@ +// check-pass +// edition:2018 +// compile-flags: -Z span-debug +// aux-build:test-macros.rs +// aux-build:dollar-crate-external.rs + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] +extern crate test_macros; +extern crate dollar_crate_external; + +type S = u8; + +mod local { + macro_rules! local { + () => { + print_bang! { + struct M($crate::S); + } + + #[print_attr] + struct A($crate::S); + + #[derive(Print)] + struct D($crate::S); + }; + } + + local!(); +} + +mod external { + use crate::dollar_crate_external; + + dollar_crate_external::external!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/edition-imports-2018.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/edition-imports-2018.rs new file mode 100644 index 000000000000..a4915fa36f8a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/edition-imports-2018.rs @@ -0,0 +1,25 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 +// aux-build:edition-imports-2015.rs + +#[macro_use] +extern crate edition_imports_2015; + +mod import { + pub struct Path; +} +mod absolute { + pub struct Path; +} + +mod check { + #[derive(Derive2015)] // OK + struct S; + + fn check() { + Path; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/empty-crate.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/empty-crate.rs new file mode 100644 index 000000000000..9916a768a6b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/empty-crate.rs @@ -0,0 +1,10 @@ +// run-pass + +#![allow(unused_imports)] +// aux-build:empty-crate.rs + +#[macro_use] +extern crate empty_crate; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/empty-where-clause.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/empty-where-clause.rs new file mode 100644 index 000000000000..c7d7d7daf567 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/empty-where-clause.rs @@ -0,0 +1,19 @@ +// aux-build:test-macros.rs + +extern crate test_macros; +use test_macros::recollect_attr; + +#[recollect_attr] +struct FieldStruct where { + field: MissingType1 // { dg-error ".E0412." "" { target *-*-* } } +} + +#[recollect_attr] +struct TupleStruct(MissingType2) where; // { dg-error ".E0412." "" { target *-*-* } } + +enum MyEnum where { + Variant(MissingType3) // { dg-error ".E0412." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/expand-to-unstable-2.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/expand-to-unstable-2.rs new file mode 100644 index 000000000000..69724bd6ba00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/expand-to-unstable-2.rs @@ -0,0 +1,18 @@ +// aux-build:derive-unstable-2.rs + +#![feature(register_attr)] + +#![register_attr(rustc_foo)] + +#[macro_use] +extern crate derive_unstable_2; + +#[derive(Unstable)] +// { dg-error "" "" { target *-*-* } .-1 } + +struct A; + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/expand-to-unstable.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/expand-to-unstable.rs new file mode 100644 index 000000000000..4653a7581388 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/expand-to-unstable.rs @@ -0,0 +1,15 @@ +// aux-build:derive-unstable.rs + +#![allow(warnings)] + +#[macro_use] +extern crate derive_unstable; + +#[derive(Unstable)] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +struct A; + +fn main() { + unsafe { foo(); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/expand-with-a-macro.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/expand-with-a-macro.rs new file mode 100644 index 000000000000..7a9299ed5a35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/expand-with-a-macro.rs @@ -0,0 +1,21 @@ +// run-pass +// aux-build:expand-with-a-macro.rs + +// ignore-wasm32-bare compiled with panic=abort by default + +#![deny(warnings)] + +#[macro_use] +extern crate expand_with_a_macro; + +use std::panic; + +#[derive(A)] +struct A; + +fn main() { + assert!(panic::catch_unwind(|| { + A.a(); + }).is_err()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/export-macro.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/export-macro.rs new file mode 100644 index 000000000000..7980a5febd05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/export-macro.rs @@ -0,0 +1,12 @@ +// error-pattern: cannot export macro_rules! macros from a `proc-macro` crate + +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +#[macro_export] +macro_rules! foo { + ($e:expr) => ($e) +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/exports.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/exports.rs new file mode 100644 index 000000000000..503f7d524b70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/exports.rs @@ -0,0 +1,16 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![allow(warnings)] + +pub fn a() {} // { dg-error "" "" { target *-*-* } } +pub struct B; // { dg-error "" "" { target *-*-* } } +pub enum C {} // { dg-error "" "" { target *-*-* } } +pub mod d {} // { dg-error "" "" { target *-*-* } } + +mod e {} +struct F; +enum G {} +fn h() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs new file mode 100644 index 000000000000..ddef68ee7234 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/extern-prelude-extern-crate-proc-macro.rs @@ -0,0 +1,8 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 + +extern crate proc_macro; +use proc_macro::TokenStream; // OK + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/gen-lifetime-token.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/gen-lifetime-token.rs new file mode 100644 index 000000000000..bcb19628aaaa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/gen-lifetime-token.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:gen-lifetime-token.rs + +extern crate gen_lifetime_token as bar; + +bar::bar!(); + +fn main() { + let x: &'static i32 = FOO; + assert_eq!(*x, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/gen-macro-rules-hygiene.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/gen-macro-rules-hygiene.rs new file mode 100644 index 000000000000..613a2b14806a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/gen-macro-rules-hygiene.rs @@ -0,0 +1,24 @@ +// `macro_rules` items produced by transparent macros have correct hygiene in basic cases. +// Local variables and labels are hygienic, items are not hygienic. +// `$crate` refers to the crate that defines `macro_rules` and not the outer transparent macro. + +// aux-build:gen-macro-rules-hygiene.rs + +#[macro_use] +extern crate gen_macro_rules_hygiene; + +struct ItemUse; + +gen_macro_rules!(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { dg-error ".E0425." "" { target *-*-* } .-2 } + +fn main() { + 'label_use: loop { + let local_use = 1; + generated!(); + ItemDef; // OK + local_def; // { dg-error ".E0425." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/gen-macro-rules.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/gen-macro-rules.rs new file mode 100644 index 000000000000..b0827986d07f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/gen-macro-rules.rs @@ -0,0 +1,14 @@ +// Derive macros can generate `macro_rules` items, regression test for issue #63651. + +// check-pass +// aux-build:gen-macro-rules.rs + +extern crate gen_macro_rules as repro; + +#[derive(repro::repro)] +pub struct S; + +m!(); // OK + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/generate-dollar-ident.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/generate-dollar-ident.rs new file mode 100644 index 000000000000..6bd5a0e35927 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/generate-dollar-ident.rs @@ -0,0 +1,19 @@ +// Proc macros can generate token sequence `$ IDENT` +// without it being recognized as an unknown macro variable. + +// check-pass +// aux-build:generate-dollar-ident.rs + +extern crate generate_dollar_ident; +use generate_dollar_ident::*; + +macro_rules! black_hole { + ($($tt:tt)*) => {}; +} + +black_hole!($var); + +dollar_ident!(black_hole); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/generate-mod.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/generate-mod.rs new file mode 100644 index 000000000000..bf87b8b041fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/generate-mod.rs @@ -0,0 +1,34 @@ +// Modules generated by transparent proc macros still acts as barriers for names (issue #50504). + +// aux-build:generate-mod.rs + +extern crate generate_mod; + +struct FromOutside; + +generate_mod::check!(); // { dg-error ".E0412." "" { target *-*-* } } +// { dg-error ".E0412." "" { target *-*-* } .-2 } + +#[generate_mod::check_attr] // { dg-error ".E0412." "" { target *-*-* } } +// { dg-error ".E0412." "" { target *-*-* } .-2 } +struct S; + +#[derive(generate_mod::CheckDerive)] // { dg-warning ".E0412." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +struct Z; + +fn inner_block() { + #[derive(generate_mod::CheckDerive)] // { dg-warning ".E0412." "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + struct InnerZ; +} + +#[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed +struct W; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actix-web-2.0.0/src/extract.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actix-web-2.0.0/src/extract.rs new file mode 100644 index 000000000000..55abdc26780b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actix-web-2.0.0/src/extract.rs @@ -0,0 +1,8 @@ +// ignore-test this is not a test + +macro_rules! tuple_from_req { + ($T:ident) => { + #[my_macro] struct Three($T); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actix-web/src/extract.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actix-web/src/extract.rs new file mode 100644 index 000000000000..55abdc26780b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actix-web/src/extract.rs @@ -0,0 +1,8 @@ +// ignore-test this is not a test + +macro_rules! tuple_from_req { + ($T:ident) => { + #[my_macro] struct Three($T); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actori-web-2.0.0/src/extract.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actori-web-2.0.0/src/extract.rs new file mode 100644 index 000000000000..ee6153caaacc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actori-web-2.0.0/src/extract.rs @@ -0,0 +1,8 @@ +// ignore-test this is not a test + +macro_rules! tuple_from_req { + ($T:ident) => { + #[my_macro] struct Four($T); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actori-web/src/extract.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actori-web/src/extract.rs new file mode 100644 index 000000000000..ee6153caaacc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/actori-web/src/extract.rs @@ -0,0 +1,8 @@ +// ignore-test this is not a test + +macro_rules! tuple_from_req { + ($T:ident) => { + #[my_macro] struct Four($T); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/auxiliary/group-compat-hack.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/auxiliary/group-compat-hack.rs new file mode 100644 index 000000000000..796e46707afb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/auxiliary/group-compat-hack.rs @@ -0,0 +1,14 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn my_macro(_attr: TokenStream, input: TokenStream) -> TokenStream { + println!("Called proc_macro_hack with {:?}", input); + input +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/group-compat-hack.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/group-compat-hack.rs new file mode 100644 index 000000000000..c4fb157beafc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/group-compat-hack.rs @@ -0,0 +1,78 @@ +// check-pass +// aux-build:group-compat-hack.rs +// compile-flags: -Z span-debug + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] extern crate group_compat_hack; + +// Tests the backwards compatibility hack added for certain macros +// When an attribute macro named `proc_macro_hack` or `wasm_bindgen` +// has an `NtIdent` named `$name`, we pass a plain `Ident` token in +// place of a `None`-delimited group. This allows us to maintain +// backwards compatibility for older versions of these crates. + +mod no_version { + include!("js-sys/src/lib.rs"); + include!("time-macros-impl/src/lib.rs"); + + macro_rules! other { + ($name:ident) => { + #[my_macro] struct Three($name); + } + } + + struct Foo; + impl_macros!(Foo); + arrays!(Foo); + other!(Foo); +} + +mod with_version { + include!("js-sys-0.3.17/src/lib.rs"); + include!("time-macros-impl-0.1.0/src/lib.rs"); + + macro_rules! other { + ($name:ident) => { + #[my_macro] struct Three($name); + } + } + + struct Foo; + impl_macros!(Foo); + arrays!(Foo); + other!(Foo); +} + +mod actix_web_test { + include!("actix-web/src/extract.rs"); + + struct Foo; + tuple_from_req!(Foo); +} + +mod actix_web_version_test { + include!("actix-web-2.0.0/src/extract.rs"); + + struct Foo; + tuple_from_req!(Foo); +} + +mod actori_web_test { + include!("actori-web/src/extract.rs"); + + struct Foo; + tuple_from_req!(Foo); +} + +mod actori_web_version_test { + include!("actori-web-2.0.0/src/extract.rs"); + + struct Foo; + tuple_from_req!(Foo); +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs new file mode 100644 index 000000000000..8f9e1194ecb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/js-sys-0.3.17/src/lib.rs @@ -0,0 +1,8 @@ +// ignore-test this is not a test + +macro_rules! arrays { + ($name:ident) => { + #[my_macro] struct Two($name); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/js-sys/src/lib.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/js-sys/src/lib.rs new file mode 100644 index 000000000000..8f9e1194ecb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/js-sys/src/lib.rs @@ -0,0 +1,8 @@ +// ignore-test this is not a test + +macro_rules! arrays { + ($name:ident) => { + #[my_macro] struct Two($name); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs new file mode 100644 index 000000000000..dc8f5a29bf25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/time-macros-impl-0.1.0/src/lib.rs @@ -0,0 +1,8 @@ +// ignore-test this is not a test + +macro_rules! impl_macros { + ($name:ident) => { + #[my_macro] struct One($name); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/time-macros-impl/src/lib.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/time-macros-impl/src/lib.rs new file mode 100644 index 000000000000..dc8f5a29bf25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/group-compat-hack/time-macros-impl/src/lib.rs @@ -0,0 +1,8 @@ +// ignore-test this is not a test + +macro_rules! impl_macros { + ($name:ident) => { + #[my_macro] struct One($name); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/helper-attr-blocked-by-import-ambig.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/helper-attr-blocked-by-import-ambig.rs new file mode 100644 index 000000000000..b2b53e827f23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/helper-attr-blocked-by-import-ambig.rs @@ -0,0 +1,12 @@ +// aux-build:test-macros.rs + +#[macro_use(Empty)] +extern crate test_macros; +use test_macros::empty_attr as empty_helper; + +#[derive(Empty)] +#[empty_helper] // { dg-error ".E0659." "" { target *-*-* } } +struct S; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/helper-attr-blocked-by-import.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/helper-attr-blocked-by-import.rs new file mode 100644 index 000000000000..92c818bf8ac4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/helper-attr-blocked-by-import.rs @@ -0,0 +1,29 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:test-macros.rs + +#[macro_use(Empty)] +extern crate test_macros; + +use self::one::*; +use self::two::*; + +mod empty_helper {} + +mod one { + use empty_helper; + + #[derive(Empty)] + #[empty_helper] + struct One; +} + +mod two { + use empty_helper; + + #[derive(Empty)] + #[empty_helper] + struct Two; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/hygiene_example.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/hygiene_example.rs new file mode 100644 index 000000000000..5da697c0a710 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/hygiene_example.rs @@ -0,0 +1,17 @@ +// check-pass +// aux-build:hygiene_example_codegen.rs +// aux-build:hygiene_example.rs + +extern crate hygiene_example; +use hygiene_example::hello; + +fn main() { + mod hygiene_example {} // no conflict with `extern crate hygiene_example;` from the proc macro + macro_rules! format { () => {} } // does not interfere with `format!` from the proc macro + macro_rules! hello_helper { () => {} } // similarly does not intefere with the proc macro + + let string = "world"; // no conflict with `string` from the proc macro + hello!(string); + hello!(string); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/illegal-proc-macro-derive-use.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/illegal-proc-macro-derive-use.rs new file mode 100644 index 000000000000..537dd3e8e1ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/illegal-proc-macro-derive-use.rs @@ -0,0 +1,16 @@ +extern crate proc_macro; + +#[proc_macro_derive(Foo)] +// { dg-error "" "" { target *-*-* } .-1 } +pub fn foo(a: proc_macro::TokenStream) -> proc_macro::TokenStream { + a +} + +// Issue #37590 +#[proc_macro_derive(Foo)] +// { dg-error "" "" { target *-*-* } .-1 } +pub struct Foo { +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/import.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/import.rs new file mode 100644 index 000000000000..d03e71e18018 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/import.rs @@ -0,0 +1,9 @@ +// aux-build:test-macros.rs + +extern crate test_macros; + +use test_macros::empty_derive; +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/input-interpolated.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/input-interpolated.rs new file mode 100644 index 000000000000..efd6ac209ab6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/input-interpolated.rs @@ -0,0 +1,30 @@ +// Check what token streams proc macros see when interpolated tokens are passed to them as input. + +// check-pass +// edition:2018 +// aux-build:test-macros.rs + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] +extern crate test_macros; + +macro_rules! pass_ident { + ($i:ident) => { + fn f() { + print_bang!($i); + } + + #[print_attr] + const $i: u8 = 0; + + #[derive(Print)] + struct $i {} + }; +} + +pass_ident!(A); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-attributes.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-attributes.rs new file mode 100644 index 000000000000..957d013d3e2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-attributes.rs @@ -0,0 +1,27 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro = "test"] // { dg-error "" "" { target *-*-* } } +pub fn a(a: TokenStream) -> TokenStream { a } + +#[proc_macro()] // { dg-error "" "" { target *-*-* } } +pub fn c(a: TokenStream) -> TokenStream { a } + +#[proc_macro(x)] // { dg-error "" "" { target *-*-* } } +pub fn d(a: TokenStream) -> TokenStream { a } + +#[proc_macro_attribute = "test"] // { dg-error "" "" { target *-*-* } } +pub fn e(_: TokenStream, a: TokenStream) -> TokenStream { a } + +#[proc_macro_attribute()] // { dg-error "" "" { target *-*-* } } +pub fn g(_: TokenStream, a: TokenStream) -> TokenStream { a } + +#[proc_macro_attribute(x)] // { dg-error "" "" { target *-*-* } } +pub fn h(_: TokenStream, a: TokenStream) -> TokenStream { a } + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-1.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-1.rs new file mode 100644 index 000000000000..5c990de708cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-1.rs @@ -0,0 +1,22 @@ +// aux-build:invalid-punct-ident.rs +// rustc-env:RUST_BACKTRACE=0 + +// FIXME https://github.com/rust-lang/rust/issues/59998 +// normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" +// normalize-stderr-test "query stack during panic:\n" -> "" +// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> "" +// normalize-stderr-test "end of query stack\n" -> "" + +#[macro_use] +extern crate invalid_punct_ident; + +invalid_punct!(); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-2.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-2.rs new file mode 100644 index 000000000000..7b02c018428f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-2.rs @@ -0,0 +1,22 @@ +// aux-build:invalid-punct-ident.rs +// rustc-env:RUST_BACKTRACE=0 + +// FIXME https://github.com/rust-lang/rust/issues/59998 +// normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" +// normalize-stderr-test "query stack during panic:\n" -> "" +// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> "" +// normalize-stderr-test "end of query stack\n" -> "" + +#[macro_use] +extern crate invalid_punct_ident; + +invalid_ident!(); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-3.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-3.rs new file mode 100644 index 000000000000..4ea97ba6baca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-3.rs @@ -0,0 +1,22 @@ +// aux-build:invalid-punct-ident.rs +// rustc-env:RUST_BACKTRACE=0 + +// FIXME https://github.com/rust-lang/rust/issues/59998 +// normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" +// normalize-stderr-test "query stack during panic:\n" -> "" +// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> "" +// normalize-stderr-test "end of query stack\n" -> "" + +#[macro_use] +extern crate invalid_punct_ident; + +invalid_raw_ident!(); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-4.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-4.rs new file mode 100644 index 000000000000..f924118e7d24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/invalid-punct-ident-4.rs @@ -0,0 +1,13 @@ +// aux-build:invalid-punct-ident.rs + +#[macro_use] +extern crate invalid_punct_ident; + +lexer_failure!(); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() { + let _recovery_witness: () = 0; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/is-available.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/is-available.rs new file mode 100644 index 000000000000..a5b862a1010d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/is-available.rs @@ -0,0 +1,18 @@ +// run-pass + +#![feature(proc_macro_is_available)] + +extern crate proc_macro; + +// aux-build:is-available.rs +extern crate is_available; + +fn main() { + let a = proc_macro::is_available(); + let b = is_available::from_inside_proc_macro!(); + let c = proc_macro::is_available(); + assert!(!a); + assert!(b); + assert!(!c); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-36935.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-36935.rs new file mode 100644 index 000000000000..ab362df502e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-36935.rs @@ -0,0 +1,14 @@ +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +#[derive(Identity, Panic)] // { dg-error "" "" { target *-*-* } } +struct Baz { +// { dg-error ".E0428." "" { target *-*-* } .-1 } + a: i32, + b: i32, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-37788.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-37788.rs new file mode 100644 index 000000000000..1a83c6b44a99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-37788.rs @@ -0,0 +1,10 @@ +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +fn main() { + // Test that constructing the `visible_parent_map` (in `cstore_impl.rs`) does not ICE. + std::cell::Cell::new(0) // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-38586.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-38586.rs new file mode 100644 index 000000000000..480ed087f602 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-38586.rs @@ -0,0 +1,10 @@ +// aux-build:issue-38586.rs + +#[macro_use] +extern crate issue_38586; + +#[derive(A)] // { dg-error ".E0425." "" { target *-*-* } } +struct A; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-39889.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-39889.rs new file mode 100644 index 000000000000..845f5648506f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-39889.rs @@ -0,0 +1,13 @@ +// run-pass + +#![allow(dead_code)] +// aux-build:issue-39889.rs + +extern crate issue_39889; +use issue_39889::Issue39889; + +#[derive(Issue39889)] +struct S; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-41211.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-41211.rs new file mode 100644 index 000000000000..da78029bcd4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-41211.rs @@ -0,0 +1,17 @@ +// aux-build:test-macros.rs + +// FIXME: https://github.com/rust-lang/rust/issues/41430 +// This is a temporary regression test for the ICE reported in #41211 + +#![feature(custom_inner_attributes)] +#![feature(register_attr)] + +#![register_attr(identity_attr)] + +#![identity_attr] +// { dg-error ".E0659." "" { target *-*-* } .-1 } +extern crate test_macros; +use test_macros::identity_attr; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-42708.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-42708.rs new file mode 100644 index 000000000000..bd0ff38baa0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-42708.rs @@ -0,0 +1,27 @@ +// run-pass +// aux-build:issue-42708.rs + +#![feature(decl_macro)] +#![allow(unused)] + +extern crate issue_42708; + +macro m() { + #[derive(issue_42708::Test)] + struct S { x: () } + + #[issue_42708::attr_test] + struct S2 { x: () } + + #[derive(Clone)] + struct S3 { x: () } + + fn g(s: S, s2: S2, s3: S3) { + (s.x, s2.x, s3.x); + } +} + +m!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-50061.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-50061.rs new file mode 100644 index 000000000000..bddf94080ee7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-50061.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(path_statements)] +// aux-build:issue-50061.rs + +#![feature(decl_macro)] + +extern crate issue_50061; + +macro inner(any_token $v: tt) { + $v +} + +macro outer($v: tt) { + inner!(any_token $v) +} + +#[issue_50061::check] +fn main() { + //! this doc comment forces roundtrip through a string + let checkit = 0; + outer!(checkit); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-50493.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-50493.rs new file mode 100644 index 000000000000..857365d6784e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-50493.rs @@ -0,0 +1,14 @@ +// aux-build:issue-50493.rs + +#[macro_use] +extern crate issue_50493; + +#[derive(Derive)] +struct Restricted { + pub(in restricted) field: usize, // { dg-error ".E0742." "" { target *-*-* } } +} + +mod restricted {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-53481.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-53481.rs new file mode 100644 index 000000000000..360cb2106510 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-53481.rs @@ -0,0 +1,23 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +mod m1 { + use m2::Empty; + + #[derive(Empty)] + struct A {} +} + +mod m2 { + pub type Empty = u8; + + #[derive(Empty)] + #[empty_helper] + struct B {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-59191-replace-root-with-fn.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-59191-replace-root-with-fn.rs new file mode 100644 index 000000000000..53e3b9787a31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-59191-replace-root-with-fn.rs @@ -0,0 +1,9 @@ +// edition:2018 +// aux-crate:issue_59191=issue-59191.rs +// Test that using a macro to replace the entire crate tree with a non-'mod' item errors out nicely. +// `issue_59191::no_main` replaces whatever's passed in with `fn main() {}`. +#![feature(custom_inner_attributes)] +// { dg-error ".E0601." "" { target *-*-* } .-1 } +#![issue_59191::no_main] +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-75734-pp-paren.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-75734-pp-paren.rs new file mode 100644 index 000000000000..7820d60ab9c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-75734-pp-paren.rs @@ -0,0 +1,27 @@ +// Regression test for issue #75734 +// Ensures that we don't lose tokens when pretty-printing would +// normally insert extra parentheses. + +// check-pass +// aux-build:test-macros.rs +// compile-flags: -Z span-debug + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] +extern crate test_macros; + +macro_rules! mul_2 { + ($val:expr) => { + print_bang!($val * 2); + }; +} + + +#[print_attr] +fn main() { + &|_: u8| {}; + mul_2!(1 + 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-75930-derive-cfg.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-75930-derive-cfg.rs new file mode 100644 index 000000000000..3f3ae40148d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-75930-derive-cfg.rs @@ -0,0 +1,67 @@ +// check-pass +// compile-flags: -Z span-debug --error-format human +// aux-build:test-macros.rs + +// Regression test for issue #75930 +// Tests that we cfg-strip all targets before invoking +// a derive macro +// We need '--error-format human' to stop compiletest from +// trying to interpret proc-macro output as JSON messages +// (a pretty-printed struct may cause a line to start with '{' ) +// FIXME: We currently lose spans here (see issue #43081) + +#[macro_use] +extern crate test_macros; + +#[print_helper(a)] +#[cfg_attr(not(FALSE), allow(dead_code))] +#[print_attr] +#[derive(Print)] +#[print_helper(b)] +struct Foo<#[cfg(FALSE)] A, B> { + #[cfg(FALSE)] first: String, + #[cfg_attr(FALSE, deny(warnings))] second: bool, + third: [u8; { + #[cfg(FALSE)] struct Bar; + #[cfg(not(FALSE))] struct Inner; + #[cfg(FALSE)] let a = 25; + match true { + #[cfg(FALSE)] true => {}, + #[cfg_attr(not(FALSE), allow(warnings))] false => {}, + _ => {} + }; + + #[print_helper(should_be_removed)] + fn removed_fn() { + #![cfg(FALSE)] + } + + #[print_helper(c)] #[cfg(not(FALSE))] fn kept_fn() { + #![cfg(not(FALSE))] + let my_val = true; + } + + enum TupleEnum { + Foo( + #[cfg(FALSE)] u8, + #[cfg(FALSE)] bool, + #[cfg(not(FALSE))] i32, + #[cfg(FALSE)] String, u8 + ) + } + + struct TupleStruct( + #[cfg(FALSE)] String, + #[cfg(not(FALSE))] i32, + #[cfg(FALSE)] bool, + u8 + ); + + 0 + }], + #[print_helper(d)] + fourth: B +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-76182-leading-vert-pat.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-76182-leading-vert-pat.rs new file mode 100644 index 000000000000..44addaa682e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-76182-leading-vert-pat.rs @@ -0,0 +1,17 @@ +// check-pass +// aux-build:test-macros.rs +// compile-flags: -Z span-debug +// +// Regression test for issue #76182 +// Tests that we properly handle patterns with a leading vert + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +extern crate test_macros; + +#[test_macros::print_attr] +fn main() { + match () { | () => () } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/issue-78675-captured-inner-attrs.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-78675-captured-inner-attrs.rs new file mode 100644 index 000000000000..0a591fa29ebc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/issue-78675-captured-inner-attrs.rs @@ -0,0 +1,33 @@ +// check-pass +// edition:2018 +// compile-flags: -Z span-debug +// aux-build:test-macros.rs + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] extern crate test_macros; + +macro_rules! foo {( + #[fake_attr] + $item:item +) => ( + $item +)} + +macro_rules! outer {($item:item) => ( + print_bang! { // Identity proc-macro + foo! { + #[fake_attr] + $item + } + } +)} +outer! { + mod bar { + //! Foo + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/item-error.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/item-error.rs new file mode 100644 index 000000000000..d4f643f48a31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/item-error.rs @@ -0,0 +1,16 @@ +// aux-build:derive-b.rs + +#![allow(warnings)] + +#[macro_use] +extern crate derive_b; + +#[derive(B)] +struct A { + a: &u64 +// { dg-error ".E0106." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/keep-expr-tokens.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/keep-expr-tokens.rs new file mode 100644 index 000000000000..74ff0dd6c25e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/keep-expr-tokens.rs @@ -0,0 +1,16 @@ +// aux-build:test-macros.rs + +#![feature(stmt_expr_attributes)] +#![feature(proc_macro_hygiene)] + +extern crate test_macros; + +use test_macros::recollect_attr; + +fn main() { + #[test_macros::recollect_attr] + for item in missing_fn() {} // { dg-error ".E0425." "" { target *-*-* } } + + (#[recollect_attr] #[recollect_attr] ((#[recollect_attr] bad))); // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/lifetimes-rpass.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/lifetimes-rpass.rs new file mode 100644 index 000000000000..7bc7bad3d9a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/lifetimes-rpass.rs @@ -0,0 +1,27 @@ +// run-pass + +#![allow(unused_variables)] +// aux-build:lifetimes-rpass.rs + +extern crate lifetimes_rpass as lifetimes; +use lifetimes::*; + +lifetimes_bang! { + fn bang<'a>() -> &'a u8 { &0 } +} + +#[lifetimes_attr] +fn attr<'a>() -> &'a u8 { &1 } + +#[derive(Lifetimes)] +pub struct Lifetimes<'a> { + pub field: &'a u8, +} + +fn main() { + assert_eq!(bang::<'static>(), &0); + assert_eq!(attr::<'static>(), &1); + let l1 = Lifetimes { field: &0 }; + let l2 = m::Lifetimes { field: &1 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/lifetimes.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/lifetimes.rs new file mode 100644 index 000000000000..31aa421739a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/lifetimes.rs @@ -0,0 +1,10 @@ +// aux-build:lifetimes.rs + +extern crate lifetimes; + +use lifetimes::*; + +type A = single_quote_alone!(); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/lints_in_proc_macros.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/lints_in_proc_macros.rs new file mode 100644 index 000000000000..3d743e80f56e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/lints_in_proc_macros.rs @@ -0,0 +1,15 @@ +// aux-build:bang_proc_macro2.rs + +extern crate bang_proc_macro2; + +use bang_proc_macro2::bang_proc_macro2; + +fn main() { + let foobar = 42; + bang_proc_macro2!(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { help ".E0425." "" { target *-*-* } .-2 } +// { suggestion ".E0425." "" { target *-*-* } .-3 } + println!("{}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/load-panic-backtrace.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/load-panic-backtrace.rs new file mode 100644 index 000000000000..aa78dea1799e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/load-panic-backtrace.rs @@ -0,0 +1,25 @@ +// aux-build:test-macros.rs +// compile-flags: -Z proc-macro-backtrace +// rustc-env:RUST_BACKTRACE=0 + +// FIXME https://github.com/rust-lang/rust/issues/59998 +// normalize-stderr-test "thread '.*' panicked " -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" +// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" +// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" +// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" +// normalize-stderr-test "note: compiler flags.*\n\n" -> "" +// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" +// normalize-stderr-test "query stack during panic:\n" -> "" +// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> "" +// normalize-stderr-test "end of query stack\n" -> "" + +#[macro_use] +extern crate test_macros; + +#[derive(Panic)] +// { dg-error "" "" { target *-*-* } .-1 } +struct Foo; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/load-panic.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/load-panic.rs new file mode 100644 index 000000000000..0fe02036d563 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/load-panic.rs @@ -0,0 +1,11 @@ +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +#[derive(Panic)] +// { dg-error "" "" { target *-*-* } .-1 } +struct Foo; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/load-two.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/load-two.rs new file mode 100644 index 000000000000..27c9dc42ef8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/load-two.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(path_statements)] +#![allow(dead_code)] +// aux-build:derive-atob.rs +// aux-build:derive-ctod.rs + +#[macro_use] +extern crate derive_atob; +#[macro_use] +extern crate derive_ctod; + +#[derive(Copy, Clone)] +#[derive(AToB)] +struct A; + +#[derive(CToD)] +struct C; + +fn main() { + B; + D; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/macro-brackets.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-brackets.rs new file mode 100644 index 000000000000..355252394622 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-brackets.rs @@ -0,0 +1,15 @@ +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +macro_rules! id { + ($($t:tt)*) => ($($t)*) +} + +#[identity_attr] +id![static X: u32 = 'a';]; // { dg-error ".E0308." "" { target *-*-* } } + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/macro-crate-multi-decorator.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-crate-multi-decorator.rs new file mode 100644 index 000000000000..0b1dd56b7c90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-crate-multi-decorator.rs @@ -0,0 +1,42 @@ +// The duplicate macro will create a copy of the item with the given identifier. + +// check-pass +// aux-build:duplicate.rs + +#[macro_use] +extern crate duplicate; + +#[duplicate(MyCopy)] +struct MyStruct { + number: i32, +} + +trait TestTrait { + #[duplicate(TestType2)] + type TestType; + + #[duplicate(required_fn2)] + fn required_fn(&self); + + #[duplicate(provided_fn2)] + fn provided_fn(&self) {} +} + +impl TestTrait for MyStruct { + #[duplicate(TestType2)] + type TestType = f64; + + #[duplicate(required_fn2)] + fn required_fn(&self) {} +} + +fn main() { + let s = MyStruct { number: 42 }; + s.required_fn(); + s.required_fn2(); + s.provided_fn(); + s.provided_fn2(); + + let s = MyCopy { number: 42 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/macro-namespace-reserved-2.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-namespace-reserved-2.rs new file mode 100644 index 000000000000..c91b9004fd04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-namespace-reserved-2.rs @@ -0,0 +1,58 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +pub fn my_macro(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_attribute] +pub fn my_macro_attr(input: TokenStream, _: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive(MyTrait)] +pub fn my_macro_derive(input: TokenStream) -> TokenStream { + input +} + +fn check_bang1() { + my_macro!(); // { dg-error "" "" { target *-*-* } } +} +fn check_bang2() { + my_macro_attr!(); // { dg-error "" "" { target *-*-* } } + crate::my_macro_attr!(); // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} +fn check_bang3() { + MyTrait!(); // { dg-error "" "" { target *-*-* } } + crate::MyTrait!(); // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + +#[my_macro] // { dg-error "" "" { target *-*-* } } +#[crate::my_macro] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +fn check_attr1() {} +#[my_macro_attr] // { dg-error "" "" { target *-*-* } } +fn check_attr2() {} +#[MyTrait] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +fn check_attr3() {} + +#[derive(my_macro)] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[derive(crate::my_macro)] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +struct CheckDerive1; +#[derive(my_macro_attr)] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +struct CheckDerive2; +#[derive(MyTrait)] // { dg-error "" "" { target *-*-* } } +struct CheckDerive3; + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/macro-namespace-reserved.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-namespace-reserved.rs new file mode 100644 index 000000000000..4dcf74682bb7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-namespace-reserved.rs @@ -0,0 +1,39 @@ +// force-host +// no-prefer-dynamic + +#![feature(decl_macro)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +pub fn my_macro(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_attribute] +pub fn my_macro_attr(input: TokenStream, _: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive(MyTrait)] +pub fn my_macro_derive(input: TokenStream) -> TokenStream { + input +} + +macro my_macro() {} // { dg-error ".E0428." "" { target *-*-* } } +macro my_macro_attr() {} // { dg-error ".E0428." "" { target *-*-* } } +macro MyTrait() {} // { dg-error ".E0428." "" { target *-*-* } } + +#[proc_macro_derive(SameName)] +pub fn foo(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro] +pub fn SameName(input: TokenStream) -> TokenStream { +// { dg-error ".E0428." "" { target *-*-* } .-1 } + input +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/macro-rules-derive.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-rules-derive.rs new file mode 100644 index 000000000000..4504150fab9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-rules-derive.rs @@ -0,0 +1,20 @@ +// aux-build:first-second.rs + +extern crate first_second; +use first_second::*; + +macro_rules! produce_it { + ($name:ident) => { + #[first] + struct $name { + field: MissingType // { dg-error ".E0412." "" { target *-*-* } } + } + } +} + +produce_it!(MyName); + +fn main() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/macro-use-attr.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-use-attr.rs new file mode 100644 index 000000000000..22ebe99d10b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-use-attr.rs @@ -0,0 +1,13 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +#[identity_attr] +struct Foo; + +fn main() { + let _ = Foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/macro-use-bang.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-use-bang.rs new file mode 100644 index 000000000000..c648643936ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/macro-use-bang.rs @@ -0,0 +1,10 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +fn main() { + identity!(println!("Hello, world!")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/macros-in-extern-derive.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/macros-in-extern-derive.rs new file mode 100644 index 000000000000..0d2a7ec5d322 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/macros-in-extern-derive.rs @@ -0,0 +1,7 @@ +extern { + #[derive(Copy)] // { dg-error ".E0774." "" { target *-*-* } } + fn f(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/macros-in-extern.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/macros-in-extern.rs new file mode 100644 index 000000000000..5a49e6612465 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/macros-in-extern.rs @@ -0,0 +1,23 @@ +// run-pass +// aux-build:test-macros.rs +// ignore-wasm32 + +#[macro_use] +extern crate test_macros; + +fn main() { + assert_eq!(unsafe { rust_get_test_int() }, 1); + assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEF); +} + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + #[empty_attr] + fn some_definitely_unknown_symbol_which_should_be_removed(); + + #[identity_attr] + fn rust_get_test_int() -> isize; + + identity!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/macros-in-type.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/macros-in-type.rs new file mode 100644 index 000000000000..793a4201fb46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/macros-in-type.rs @@ -0,0 +1,12 @@ +// check-pass +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +const C: identity!(u8) = 10; + +fn main() { + let c: u8 = C; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/meta-delim.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/meta-delim.rs new file mode 100644 index 000000000000..3f7239213850 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/meta-delim.rs @@ -0,0 +1,13 @@ +// aux-build:meta-delim.rs +// edition:2018 +// run-pass + +// Tests that we can properly deserialize a macro with strange delimiters +// See https://github.com/rust-lang/rust/pull/73569#issuecomment-650860457 + +extern crate meta_delim; + +fn main() { + assert_eq!("a bunch of idents", meta_delim::meta_delim!(a bunch of idents)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/meta-macro-hygiene.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/meta-macro-hygiene.rs new file mode 100644 index 000000000000..5737a5531f5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/meta-macro-hygiene.rs @@ -0,0 +1,31 @@ +// ignore-tidy-linelength +// aux-build:make-macro.rs +// aux-build:meta-macro.rs +// edition:2018 +// compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no +// check-pass +// normalize-stdout-test "\d+#" -> "0#" +// +// We don't care about symbol ids, so we set them all to 0 +// in the stdout + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +extern crate meta_macro; + +macro_rules! produce_it { + () => { + // `print_def_site!` will respan the `$crate` identifier + // with `Span::def_site()`. This should cause it to resolve + // relative to `meta_macro`, *not* `make_macro` (despite + // the fact that that `print_def_site` is produced by + // a `macro_rules!` macro in `make_macro`). + meta_macro::print_def_site!($crate::dummy!()); + } +} + +fn main() { + produce_it!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/meta-macro.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/meta-macro.rs new file mode 100644 index 000000000000..207ec7681b89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/meta-macro.rs @@ -0,0 +1,15 @@ +// aux-build:make-macro.rs +// aux-build:meta-macro.rs +// edition:2018 +// compile-flags: -Z span-debug +// run-pass + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +extern crate meta_macro; + +fn main() { + meta_macro::print_def_site!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/mixed-site-span.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/mixed-site-span.rs new file mode 100644 index 000000000000..0844811b4dcf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/mixed-site-span.rs @@ -0,0 +1,25 @@ +// Proc macros using `mixed_site` spans exhibit usual properties of `macro_rules` hygiene. + +// aux-build:mixed-site-span.rs + +#[macro_use] +extern crate mixed_site_span; + +struct ItemUse; + +fn main() { + 'label_use: loop { + let local_use = 1; + proc_macro_rules!(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { dg-error ".E0425." "" { target *-*-* } .-2 } + ItemDef; // OK + local_def; // { dg-error ".E0425." "" { target *-*-* } } + } +} + +macro_rules! pass_dollar_crate { + () => (proc_macro_rules!($crate);) // { dg-error ".E0412." "" { target *-*-* } } +} +pass_dollar_crate!(); + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/modify-ast.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/modify-ast.rs new file mode 100644 index 000000000000..f4cc6a7519e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/modify-ast.rs @@ -0,0 +1,27 @@ +// run-pass +// aux-build:modify-ast.rs + +extern crate modify_ast; + +use modify_ast::*; + +#[derive(Foo)] +pub struct MyStructc { + #[cfg_attr(my_cfg, foo)] + _a: i32, +} + +macro_rules! a { + ($i:item) => ($i) +} + +a! { + #[assert1] + pub fn foo() {} +} + +fn main() { + let _a = MyStructc { _a: 0 }; + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/module.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/module.rs new file mode 100644 index 000000000000..86a7604087ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/module.rs @@ -0,0 +1,2 @@ +// ignore-test + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/multispan.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/multispan.rs new file mode 100644 index 000000000000..cdc44afef45b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/multispan.rs @@ -0,0 +1,26 @@ +// aux-build:multispan.rs + +extern crate multispan; + +use multispan::hello; + +fn main() { + // This one emits no error. + hello!(); + + // Exactly one 'hi'. + hello!(hi); // { dg-error "" "" { target *-*-* } } + + // Now two, back to back. + hello!(hi hi); // { dg-error "" "" { target *-*-* } } + + // Now three, back to back. + hello!(hi hi hi); // { dg-error "" "" { target *-*-* } } + + // Now several, with spacing. + hello!(hi hey hi yo hi beep beep hi hi); // { dg-error "" "" { target *-*-* } } + hello!(hi there, hi how are you? hi... hi.); // { dg-error "" "" { target *-*-* } } + hello!(whoah. hi di hi di ho); // { dg-error "" "" { target *-*-* } } + hello!(hi good hi and good bye); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/negative-token.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/negative-token.rs new file mode 100644 index 000000000000..f105785beb0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/negative-token.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:negative-token.rs + +extern crate negative_token; + +use negative_token::*; + +fn main() { + assert_eq!(-1, neg_one!()); + assert_eq!(-1.0, neg_one_float!()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/nested-item-spans.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/nested-item-spans.rs new file mode 100644 index 000000000000..5aa6d960322e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/nested-item-spans.rs @@ -0,0 +1,24 @@ +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +#[recollect_attr] +fn another() { + fn bar() { + let x: u32 = "x"; // { dg-error ".E0308." "" { target *-*-* } } + } + + bar(); +} + +fn main() { + #[recollect_attr] + fn bar() { + let x: u32 = "x"; // { dg-error ".E0308." "" { target *-*-* } } + } + + bar(); + another(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/nested-macro-rules.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/nested-macro-rules.rs new file mode 100644 index 000000000000..9830f0370872 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/nested-macro-rules.rs @@ -0,0 +1,24 @@ +// run-pass +// aux-build:nested-macro-rules.rs +// aux-build:test-macros.rs +// compile-flags: -Z span-debug +// edition:2018 + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +extern crate nested_macro_rules; +extern crate test_macros; + +use test_macros::print_bang; + +use nested_macro_rules::FirstStruct; +struct SecondStruct; + +fn main() { + nested_macro_rules::inner_macro!(print_bang); + + nested_macro_rules::outer_macro!(SecondStruct); + inner_macro!(print_bang); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/nested-nonterminal-tokens.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/nested-nonterminal-tokens.rs new file mode 100644 index 000000000000..b5586d4a3cb6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/nested-nonterminal-tokens.rs @@ -0,0 +1,27 @@ +// check-pass +// edition:2018 +// compile-flags: -Z span-debug +// aux-build:test-macros.rs + +// Tests that we properly pass tokens to proc-macro when nested +// nonterminals are involved. + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] +extern crate test_macros; + + +macro_rules! wrap { + (first, $e:expr) => { wrap!(second, $e + 1) }; + (second, $e:expr) => { wrap!(third, $e + 2) }; + (third, $e:expr) => { + print_bang!($e + 3); + }; +} + +fn main() { + let _ = wrap!(first, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/no-macro-use-attr.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/no-macro-use-attr.rs new file mode 100644 index 000000000000..08986ff4918a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/no-macro-use-attr.rs @@ -0,0 +1,11 @@ +// aux-build:test-macros.rs + +#![feature(rustc_attrs)] +#![warn(unused_extern_crates)] + +extern crate test_macros; +// { dg-warning "" "" { target *-*-* } .-1 } + +#[rustc_error] +fn main() {} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/no-missing-docs.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/no-missing-docs.rs new file mode 100644 index 000000000000..bf817fdfbb81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/no-missing-docs.rs @@ -0,0 +1,17 @@ +//! Verify that the `decls` module implicitly added by the compiler does not cause `missing_docs` +//! warnings. + +// build-pass (FIXME(62277): could be check-pass?) +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![deny(missing_docs)] + +extern crate proc_macro; +use proc_macro::*; + +/// Foo1. +#[proc_macro] +pub fn foo1(input: TokenStream) -> TokenStream { input } + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/nodelim-groups.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/nodelim-groups.rs new file mode 100644 index 000000000000..1b3791736b95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/nodelim-groups.rs @@ -0,0 +1,23 @@ +// run-pass +// aux-build:test-macros.rs +// compile-flags: -Z span-debug +// edition:2018 +// +// Tests the pretty-printing behavior of inserting `NoDelim` groups + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +extern crate test_macros; +use test_macros::print_bang_consume; + +macro_rules! expand_it { + (($val1:expr) ($val2:expr)) => { expand_it!($val1 + $val2) }; + ($val:expr) => { print_bang_consume!("hi" $val (1 + 1)) }; +} + +fn main() { + expand_it!(1 + (25) + 1); + expand_it!(("hello".len()) ("world".len())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/non-root.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/non-root.rs new file mode 100644 index 000000000000..9347ca6f2a20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/non-root.rs @@ -0,0 +1,16 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +fn foo(arg: TokenStream) -> TokenStream { + #[proc_macro] + pub fn foo(arg: TokenStream) -> TokenStream { arg } +// { dg-error "" "" { target *-*-* } .-1 } + + arg +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/nonterminal-expansion.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/nonterminal-expansion.rs new file mode 100644 index 000000000000..e270c295ebc6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/nonterminal-expansion.rs @@ -0,0 +1,38 @@ +// check-pass +// compile-flags: -Z span-debug +// aux-build:test-macros.rs + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] +extern crate test_macros; + +macro_rules! pass_nonterminal { + ($line:expr) => { + #[print_attr_args(a, $line, b)] + struct S; + }; +} + +// `line!()` is not expanded before it's passed to the proc macro. +pass_nonterminal!(line!()); + +// Test case from #43860. + +#[macro_export] +macro_rules! use_contract { + ($name: ident, $path: expr) => { + #[derive(Empty)] + #[empty_helper(path = $path)] // OK + pub struct $name { + api: T, + contract: C, + } + }; +} + +use_contract!(ContractName, file!()); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/nonterminal-token-hygiene.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/nonterminal-token-hygiene.rs new file mode 100644 index 000000000000..0fb24707ef88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/nonterminal-token-hygiene.rs @@ -0,0 +1,34 @@ +// Make sure that marks from declarative macros are applied to tokens in nonterminal. + +// check-pass +// compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene +// compile-flags: -Z trim-diagnostic-paths=no +// normalize-stdout-test "\d+#" -> "0#" +// aux-build:test-macros.rs + +#![feature(decl_macro)] + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] +extern crate test_macros; + +macro_rules! outer { + ($item:item) => { + macro inner() { + print_bang! { $item } + } + + inner!(); + }; +} + +struct S; + +outer! { + struct S; // OK, not a duplicate definition of `S` +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/not-joint.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/not-joint.rs new file mode 100644 index 000000000000..5024f7acc637 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/not-joint.rs @@ -0,0 +1,25 @@ +// run-pass +// aux-build:not-joint.rs + +extern crate not_joint as bar; +use bar::{tokens, nothing}; + +tokens![< -]; + +#[nothing] +a![< -]; + +#[nothing] +b!{< -} + +#[nothing] +c!(< -); + +#[nothing] +fn foo() { + //! dox + let x = 2 < - 3; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/out-of-line-mod.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/out-of-line-mod.rs new file mode 100644 index 000000000000..65b73e1f38c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/out-of-line-mod.rs @@ -0,0 +1,14 @@ +// Out-of-line module is found on the filesystem if passed through a proc macro (issue #58818). + +// check-pass +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +mod outer { + identity! { mod inner; } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/outer/inner.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/outer/inner.rs new file mode 100644 index 000000000000..86a7604087ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/outer/inner.rs @@ -0,0 +1,2 @@ +// ignore-test + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/parent-source-spans.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/parent-source-spans.rs new file mode 100644 index 000000000000..4197d7b40fdd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/parent-source-spans.rs @@ -0,0 +1,54 @@ +// aux-build:parent-source-spans.rs + +#![feature(decl_macro)] + +extern crate parent_source_spans; + +use parent_source_spans::parent_source_spans; + +macro one($a:expr, $b:expr) { + two!($a, $b); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +macro two($a:expr, $b:expr) { + three!($a, $b); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +} + +// forwarding tokens directly doesn't create a new source chain +macro three($($tokens:tt)*) { + four!($($tokens)*); +} + +macro four($($tokens:tt)*) { + parent_source_spans!($($tokens)*); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { dg-error ".E0425." "" { target *-*-* } .-2 } +// { dg-error ".E0425." "" { target *-*-* } .-3 } +} + +fn main() { + one!("hello", "world"); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } + + two!("yay", "rust"); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } + + three!("hip", "hop"); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-attributes.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-attributes.rs new file mode 100644 index 000000000000..0f310da6049a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-attributes.rs @@ -0,0 +1,15 @@ +// aux-build:derive-b.rs + +#[macro_use] +extern crate derive_b; + +#[B] // { dg-error ".E0659." "" { target *-*-* } } +#[C] // { dg-error "" "" { target *-*-* } } +#[B(D)] // { dg-error ".E0659." "" { target *-*-* } } +#[B(E = "foo")] // { dg-error ".E0659." "" { target *-*-* } } +#[B(arbitrary tokens)] // { dg-error ".E0659." "" { target *-*-* } } +#[derive(B)] +struct B; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-deprecated-attr.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-deprecated-attr.rs new file mode 100644 index 000000000000..22688ac528b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-deprecated-attr.rs @@ -0,0 +1,17 @@ +// check-pass +// force-host +// no-prefer-dynamic + +#![deny(deprecated)] + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +#[deprecated(since = "1.0.0", note = "test")] +pub fn test_compile_without_warning_with_deprecated(_: TokenStream) -> TokenStream { + TokenStream::new() +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-gates.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-gates.rs new file mode 100644 index 000000000000..94172cc9948e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-gates.rs @@ -0,0 +1,49 @@ +// aux-build:test-macros.rs +// gate-test-proc_macro_hygiene + +#![feature(stmt_expr_attributes)] + +#[macro_use] +extern crate test_macros; + +fn _test_inner() { + #![empty_attr] // { dg-error ".E0658." "" { target *-*-* } } +} + +mod _test2_inner { + #![empty_attr] // { dg-error ".E0658." "" { target *-*-* } } +} + +#[empty_attr = "y"] // { dg-error "" "" { target *-*-* } } +fn _test3() {} + +fn attrs() { + // Statement, item + #[empty_attr] // OK + struct S; + + // Statement, macro + #[empty_attr] // { dg-error ".E0658." "" { target *-*-* } } + println!(); + + // Statement, semi + #[empty_attr] // { dg-error ".E0658." "" { target *-*-* } } + S; + + // Statement, local + #[empty_attr] // { dg-error ".E0658." "" { target *-*-* } } + let _x = 2; + + // Expr + let _x = #[identity_attr] 2; // { dg-error ".E0658." "" { target *-*-* } } + + // Opt expr + let _x = [#[identity_attr] 2]; // { dg-error ".E0658." "" { target *-*-* } } + + // Expr macro + let _x = #[identity_attr] println!(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-gates2.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-gates2.rs new file mode 100644 index 000000000000..019562890308 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/proc-macro-gates2.rs @@ -0,0 +1,25 @@ +// aux-build:test-macros.rs + +#![feature(stmt_expr_attributes)] + +#[macro_use] +extern crate test_macros; + +// NB. these errors aren't the best errors right now, but they're definitely +// intended to be errors. Somehow using a custom attribute in these positions +// should either require a feature gate or not be allowed on stable. + +fn _test6<#[empty_attr] T>() {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn _test7() { + match 1 { + #[empty_attr] // { dg-error "" "" { target *-*-* } } + 0 => {} + _ => {} + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/pub-at-crate-root.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/pub-at-crate-root.rs new file mode 100644 index 000000000000..ca21ca45f82e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/pub-at-crate-root.rs @@ -0,0 +1,23 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +pub mod a { // { dg-error "" "" { target *-*-* } } + use proc_macro::TokenStream; + + #[proc_macro_derive(B)] + pub fn bar(a: TokenStream) -> TokenStream { +// { dg-error "" "" { target *-*-* } .-1 } + a + } +} + +#[proc_macro_derive(B)] +fn bar(a: proc_macro::TokenStream) -> proc_macro::TokenStream { +// { dg-error "" "" { target *-*-* } .-1 } + a +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/raw-ident.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/raw-ident.rs new file mode 100644 index 000000000000..4663da2846a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/raw-ident.rs @@ -0,0 +1,17 @@ +// aux-build:raw-ident.rs + +#[macro_use] extern crate raw_ident; + +fn main() { + make_struct!(fn); + make_struct!(Foo); + make_struct!(await); + + r#fn; + r#Foo; + Foo; + r#await; + + make_bad_struct!(S); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/reserved-macro-names.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/reserved-macro-names.rs new file mode 100644 index 000000000000..99ee040d5ab6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/reserved-macro-names.rs @@ -0,0 +1,26 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro_attribute] +pub fn cfg(_: TokenStream, input: TokenStream) -> TokenStream { +// { dg-error "" "" { target *-*-* } .-1 } + input +} + +#[proc_macro_attribute] +pub fn cfg_attr(_: TokenStream, input: TokenStream) -> TokenStream { +// { dg-error "" "" { target *-*-* } .-1 } + input +} + +#[proc_macro_attribute] +pub fn derive(_: TokenStream, input: TokenStream) -> TokenStream { +// { dg-error "" "" { target *-*-* } .-1 } + input +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/resolve-error.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/resolve-error.rs new file mode 100644 index 000000000000..45fbd533a95a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/resolve-error.rs @@ -0,0 +1,63 @@ +// aux-build:derive-foo.rs +// aux-build:derive-clona.rs +// aux-build:test-macros.rs + +#[macro_use] +extern crate derive_foo; +#[macro_use] +extern crate derive_clona; +extern crate test_macros; + +use test_macros::empty as bang_proc_macro; +use test_macros::empty_attr as attr_proc_macro; + +macro_rules! FooWithLongNam { + () => {} +} + +macro_rules! attr_proc_mac { + () => {} +} + +#[derive(FooWithLongNan)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +struct Foo; + +// Interpreted as an unstable custom attribute +#[attr_proc_macra] // { dg-error "" "" { target *-*-* } } +struct Bar; + +// Interpreted as an unstable custom attribute +#[FooWithLongNan] // { dg-error "" "" { target *-*-* } } +struct Asdf; + +#[derive(Dlone)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +struct A; + +#[derive(Dlona)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +struct B; + +#[derive(attr_proc_macra)] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +struct C; + +fn main() { + FooWithLongNama!(); +// { dg-error "" "" { target *-*-* } .-1 } + + attr_proc_macra!(); +// { dg-error "" "" { target *-*-* } .-1 } + + Dlona!(); +// { dg-error "" "" { target *-*-* } .-1 } + + bang_proc_macrp!(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/resolved-located-at.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/resolved-located-at.rs new file mode 100644 index 000000000000..9d10d0a654d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/resolved-located-at.rs @@ -0,0 +1,11 @@ +// aux-build:resolved-located-at.rs + +#[macro_use] +extern crate resolved_located_at; + +fn main() { + resolve_located_at!(a b) +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/shadow.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/shadow.rs new file mode 100644 index 000000000000..f7725123d52f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/shadow.rs @@ -0,0 +1,9 @@ +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; +#[macro_use] +extern crate test_macros; // { dg-error ".E0259." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/signature.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/signature.rs new file mode 100644 index 000000000000..e4bb571c06f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/signature.rs @@ -0,0 +1,14 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![allow(warnings)] + +extern crate proc_macro; + +#[proc_macro_derive(A)] +pub unsafe extern fn foo(a: i32, b: u32) -> u32 { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + loop {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/smoke.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/smoke.rs new file mode 100644 index 000000000000..13b66db82711 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/smoke.rs @@ -0,0 +1,21 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(path_statements)] +// aux-build:derive-a.rs + +#[macro_use] +extern crate derive_a; + +#[derive(Debug, PartialEq, A, Eq, Copy, Clone)] +struct A; + +fn main() { + A; + assert_eq!(A, A); + A.clone(); + let a = A; + let _c = a; + let _d = a; +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/span-api-tests.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/span-api-tests.rs new file mode 100644 index 000000000000..0da08da506e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/span-api-tests.rs @@ -0,0 +1,62 @@ +// run-pass +// ignore-pretty +// aux-build:span-api-tests.rs +// aux-build:span-test-macros.rs + +#[macro_use] +extern crate span_test_macros; + +extern crate span_api_tests; + +// FIXME(69775): Investigate `assert_fake_source_file`. + +use span_api_tests::{reemit, assert_source_file, macro_stringify}; + +macro_rules! say_hello { + ($macname:ident) => ( $macname! { "Hello, world!" }) +} + +assert_source_file! { "Hello, world!" } + +say_hello! { assert_source_file } + +reemit_legacy! { + assert_source_file! { "Hello, world!" } +} + +say_hello_extern! { assert_source_file } + +reemit! { + assert_source_file! { "Hello, world!" } +} + +fn main() { + let s = macro_stringify!(Hello, world!); + assert_eq!(s, "Hello, world!"); + assert_eq!(macro_stringify!(Hello, world!), "Hello, world!"); + assert_eq!(reemit_legacy!(macro_stringify!(Hello, world!)), "Hello, world!"); + reemit_legacy!(assert_eq!(macro_stringify!(Hello, world!), "Hello, world!")); + // reemit change the span to be that of the call site + assert_eq!( + reemit!(macro_stringify!(Hello, world!)), + "reemit!(macro_stringify!(Hello, world!))" + ); + let r = "reemit!(assert_eq!(macro_stringify!(Hello, world!), r));"; + reemit!(assert_eq!(macro_stringify!(Hello, world!), r)); + + assert_eq!(macro_stringify!( + Hello, + world! + ), "Hello,\n world!"); + + assert_eq!(macro_stringify!(Hello, /*world */ !), "Hello, /*world */ !"); + assert_eq!(macro_stringify!( + Hello, + // comment + world! + ), "Hello,\n // comment\n world!"); + + assert_eq!(say_hello! { macro_stringify }, "\"Hello, world!\""); + assert_eq!(say_hello_extern! { macro_stringify }, "\"Hello, world!\""); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/span-preservation.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/span-preservation.rs new file mode 100644 index 000000000000..8a70bf62c7ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/span-preservation.rs @@ -0,0 +1,58 @@ +// For each of these, we should get the appropriate type mismatch error message, +// and the function should be echoed. + +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +#[recollect_attr] +fn a() { + let x: usize = "hello"; // { dg-error ".E0308." "" { target *-*-* } } +} + +#[recollect_attr] +fn b(x: Option) -> usize { + match x { + Some(x) => { return x }, // { dg-error ".E0308." "" { target *-*-* } } + None => 10 + } +} + +#[recollect_attr] +fn c() { + struct Foo { + a: usize + } + + struct Bar { + a: usize, + b: usize + } + + let x = Foo { a: 10isize }; // { dg-error ".E0308." "" { target *-*-* } } + let y = Foo { a: 10, b: 10isize }; // { dg-error ".E0560." "" { target *-*-* } } +} + +#[recollect_attr] +extern fn bar() { + 0 // { dg-error ".E0308." "" { target *-*-* } } +} + +#[recollect_attr] +extern "C" fn baz() { + 0 // { dg-error ".E0308." "" { target *-*-* } } +} + +#[recollect_attr] +extern "Rust" fn rust_abi() { + 0 // { dg-error ".E0308." "" { target *-*-* } } +} + +#[recollect_attr] +extern "\x43" fn c_abi_escaped() { + 0 // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/struct-field-macro.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/struct-field-macro.rs new file mode 100644 index 000000000000..a4f730ea304d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/struct-field-macro.rs @@ -0,0 +1,19 @@ +// run-pass + +#![allow(dead_code)] +// aux-build:derive-nothing.rs + +#[macro_use] +extern crate derive_nothing; + +macro_rules! int { + () => { i32 } +} + +#[derive(Nothing)] +struct S { + x: int!(), +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/subspan.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/subspan.rs new file mode 100644 index 000000000000..727ddd9fb6d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/subspan.rs @@ -0,0 +1,27 @@ +// aux-build:subspan.rs + +extern crate subspan; + +use subspan::subspan; + +// This one emits no error. +subspan!(""); + +// Exactly one 'hi'. +subspan!("hi"); // { dg-error "" "" { target *-*-* } } + +// Now two, back to back. +subspan!("hihi"); // { dg-error "" "" { target *-*-* } } + +// Now three, back to back. +subspan!("hihihi"); // { dg-error "" "" { target *-*-* } } + +// Now several, with spacing. +subspan!("why I hide? hi!"); // { dg-error "" "" { target *-*-* } } +subspan!("hey, hi, hidy, hidy, hi hi"); // { dg-error "" "" { target *-*-* } } +subspan!("this is a hi, and this is another hi"); // { dg-error "" "" { target *-*-* } } +subspan!("how are you this evening"); // { dg-error "" "" { target *-*-* } } +subspan!("this is highly eradic"); // { dg-error "" "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/three-equals.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/three-equals.rs new file mode 100644 index 000000000000..1eee776e7769 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/three-equals.rs @@ -0,0 +1,26 @@ +// aux-build:three-equals.rs + +extern crate three_equals; + +use three_equals::three_equals; + +fn main() { + // This one is okay. + three_equals!(===); + + // Need exactly three equals. + three_equals!(==); // { dg-error "" "" { target *-*-* } } + + // Need exactly three equals. + three_equals!(=====); // { dg-error "" "" { target *-*-* } } + + // Only equals accepted. + three_equals!(abc); // { dg-error "" "" { target *-*-* } } + + // Only equals accepted. + three_equals!(!!); // { dg-error "" "" { target *-*-* } } + + // Only three characters expected. + three_equals!(===a); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/trailing-plus.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/trailing-plus.rs new file mode 100644 index 000000000000..96071da4b122 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/trailing-plus.rs @@ -0,0 +1,15 @@ +// check-pass +// aux-build:test-macros.rs +// compile-flags: -Z span-debug + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +extern crate test_macros; + +#[test_macros::print_attr] +fn foo() where T: Copy + { +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/trait-fn-args-2015.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/trait-fn-args-2015.rs new file mode 100644 index 000000000000..10f07d535962 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/trait-fn-args-2015.rs @@ -0,0 +1,15 @@ +// Unnamed arguments in trait functions can be passed through proc macros on 2015 edition. + +// check-pass +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +trait Tr { + #[identity_attr] + fn method(u8); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/two-crate-types-1.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/two-crate-types-1.rs new file mode 100644 index 000000000000..f5f4eeb054d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/two-crate-types-1.rs @@ -0,0 +1,8 @@ +// error-pattern: cannot mix `proc-macro` crate type with others + +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![crate_type = "rlib"] + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/two-crate-types-2.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/two-crate-types-2.rs new file mode 100644 index 000000000000..ec8519893c71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/two-crate-types-2.rs @@ -0,0 +1,4 @@ +// error-pattern: cannot mix `proc-macro` crate type with others +// compile-flags: --crate-type rlib --crate-type proc-macro +// force-host + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/unsafe-foreign-mod.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/unsafe-foreign-mod.rs new file mode 100644 index 000000000000..a6b4119aef4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/unsafe-foreign-mod.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:macro-only-syntax.rs + +extern crate macro_only_syntax; + +#[macro_only_syntax::expect_unsafe_foreign_mod] +unsafe extern { + type T; +} + +#[macro_only_syntax::expect_unsafe_extern_cpp_mod] +unsafe extern "C++" {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/unsafe-mod.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/unsafe-mod.rs new file mode 100644 index 000000000000..e51b798909c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/unsafe-mod.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:macro-only-syntax.rs + +#![feature(proc_macro_hygiene)] + +extern crate macro_only_syntax; + +#[macro_only_syntax::expect_unsafe_mod] +unsafe mod m { + pub unsafe mod inner; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/visibility-path.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/visibility-path.rs new file mode 100644 index 000000000000..2fc02e1c493d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/visibility-path.rs @@ -0,0 +1,26 @@ +// Proc macro defined with `pub(path)` doesn't ICEs due to resolving the `path` (issue #68921). + +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +pub(self) fn outer(input: TokenStream) -> TokenStream { +// { dg-error "" "" { target *-*-* } .-1 } + input +} + +mod m { + use proc_macro::*; + + #[proc_macro] + pub(super) fn inner(input: TokenStream) -> TokenStream { +// { dg-error "" "" { target *-*-* } .-1 } + input + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc-macro/weird-hygiene.rs b/gcc/testsuite/rust/rustc/ui/proc-macro/weird-hygiene.rs new file mode 100644 index 000000000000..1ddeb6e44db4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc-macro/weird-hygiene.rs @@ -0,0 +1,47 @@ +// aux-build:weird-hygiene.rs + +#![feature(stmt_expr_attributes)] +#![feature(proc_macro_hygiene)] + +extern crate weird_hygiene; +use weird_hygiene::*; + +macro_rules! other { + ($tokens:expr) => { + macro_rules! call_it { + ($outer_ident:ident) => { + macro_rules! inner { + () => { + $outer_ident; + } + } + } + } + + #[derive(WeirdDerive)] + enum MyEnum { + Value = (stringify!($tokens + hidden_ident), 1).1 // { dg-error ".E0425." "" { target *-*-* } } + } + + inner!(); + } +} + +macro_rules! invoke_it { + ($token:expr) => { + #[recollect_attr] { + $token; + hidden_ident // { dg-error ".E0425." "" { target *-*-* } } + } + } +} + +fn main() { + // `other` and `invoke_it` are both macro_rules! macros, + // so it should be impossible for them to ever see `hidden_ident`, + // even if they invoke a proc macro. + let hidden_ident = "Hello1"; + other!(50); + invoke_it!(25); +} + diff --git a/gcc/testsuite/rust/rustc/ui/proc_macro.rs b/gcc/testsuite/rust/rustc/ui/proc_macro.rs new file mode 100644 index 000000000000..ba203813afb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/proc_macro.rs @@ -0,0 +1,38 @@ +// run-pass +// aux-build:proc_macro_def.rs +// ignore-cross-compile + +extern crate proc_macro_def; + +use proc_macro_def::{attr_tru, attr_identity, identity, ret_tru, tru}; + +#[attr_tru] +fn f1() -> bool { + return false; +} + +#[attr_identity] +fn f2() -> bool { + return identity!(true); +} + +fn f3() -> identity!(bool) { + ret_tru!(); +} + +fn f4(x: bool) -> bool { + match x { + identity!(true) => false, + identity!(false) => true, + } +} + +fn main() { + assert!(f1()); + assert!(f2()); + assert!(tru!()); + assert!(f3()); + assert!(identity!(5 == 5)); + assert!(f4(false)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/process-termination/process-termination-blocking-io.rs b/gcc/testsuite/rust/rustc/ui/process-termination/process-termination-blocking-io.rs new file mode 100644 index 000000000000..1ab26109b564 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/process-termination/process-termination-blocking-io.rs @@ -0,0 +1,20 @@ +// program should terminate even if a thread is blocked on I/O. +// https://github.com/fortanix/rust-sgx/issues/109 + +// run-pass +// ignore-emscripten no threads support + +use std::{net::TcpListener, sync::mpsc, thread}; + +fn main() { + let (tx, rx) = mpsc::channel(); + thread::spawn(move || { + let listen = TcpListener::bind("0.0.0.0:0").unwrap(); + tx.send(()).unwrap(); + while let Ok(_) = listen.accept() {} + }); + rx.recv().unwrap(); + for _ in 0..3 { thread::yield_now(); } + println!("Exiting main thread"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/process-termination/process-termination-simple.rs b/gcc/testsuite/rust/rustc/ui/process-termination/process-termination-simple.rs new file mode 100644 index 000000000000..dabffaf6a375 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/process-termination/process-termination-simple.rs @@ -0,0 +1,14 @@ +// program should terminate when std::process::exit is called from any thread + +// run-pass +// ignore-emscripten no threads support + +use std::{process, thread}; + +fn main() { + let h = thread::spawn(|| { + process::exit(0); + }); + let _ = h.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/process/process-envs.rs b/gcc/testsuite/rust/rustc/ui/process/process-envs.rs new file mode 100644 index 000000000000..cf3f2efdde72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/process/process-envs.rs @@ -0,0 +1,55 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +// ignore-vxworks no 'env' + +use std::process::Command; +use std::env; +use std::collections::HashMap; + +#[cfg(all(unix, not(target_os="android")))] +pub fn env_cmd() -> Command { + Command::new("env") +} +#[cfg(target_os="android")] +pub fn env_cmd() -> Command { + let mut cmd = Command::new("/system/bin/sh"); + cmd.arg("-c").arg("set"); + cmd +} + +#[cfg(windows)] +pub fn env_cmd() -> Command { + let mut cmd = Command::new("cmd"); + cmd.arg("/c").arg("set"); + cmd +} + +fn main() { + // save original environment + let old_env = env::var_os("RUN_TEST_NEW_ENV"); + + env::set_var("RUN_TEST_NEW_ENV", "123"); + + // create filtered environment vector + let filtered_env : HashMap = + env::vars().filter(|&(ref k, _)| k == "PATH").collect(); + + let mut cmd = env_cmd(); + cmd.env_clear(); + cmd.envs(&filtered_env); + + // restore original environment + match old_env { + None => env::remove_var("RUN_TEST_NEW_ENV"), + Some(val) => env::set_var("RUN_TEST_NEW_ENV", &val) + } + + let result = cmd.output().unwrap(); + let output = String::from_utf8_lossy(&result.stdout); + + assert!(!output.contains("RUN_TEST_NEW_ENV"), + "found RUN_TEST_NEW_ENV inside of:\n\n{}", output); +} + diff --git a/gcc/testsuite/rust/rustc/ui/process/process-exit.rs b/gcc/testsuite/rust/rustc/ui/process/process-exit.rs new file mode 100644 index 000000000000..186586e360cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/process/process-exit.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(unused_imports)] +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::env; +use std::process::{self, Command, Stdio}; + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "child" { + child(); + } else { + parent(); + } +} + +fn parent() { + let args: Vec = env::args().collect(); + let status = Command::new(&args[0]).arg("child").status().unwrap(); + assert_eq!(status.code(), Some(2)); +} + +fn child() -> i32 { + process::exit(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/process/process-remove-from-env.rs b/gcc/testsuite/rust/rustc/ui/process/process-remove-from-env.rs new file mode 100644 index 000000000000..6374a24d4921 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/process/process-remove-from-env.rs @@ -0,0 +1,49 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +// ignore-vxworks no 'env' + +use std::process::Command; +use std::env; + +#[cfg(all(unix, not(target_os="android")))] +pub fn env_cmd() -> Command { + Command::new("env") +} +#[cfg(target_os="android")] +pub fn env_cmd() -> Command { + let mut cmd = Command::new("/system/bin/sh"); + cmd.arg("-c").arg("set"); + cmd +} + +#[cfg(windows)] +pub fn env_cmd() -> Command { + let mut cmd = Command::new("cmd"); + cmd.arg("/c").arg("set"); + cmd +} + +fn main() { + // save original environment + let old_env = env::var_os("RUN_TEST_NEW_ENV"); + + env::set_var("RUN_TEST_NEW_ENV", "123"); + + let mut cmd = env_cmd(); + cmd.env_remove("RUN_TEST_NEW_ENV"); + + // restore original environment + match old_env { + None => env::remove_var("RUN_TEST_NEW_ENV"), + Some(val) => env::set_var("RUN_TEST_NEW_ENV", &val) + } + + let result = cmd.output().unwrap(); + let output = String::from_utf8_lossy(&result.stdout); + + assert!(!output.contains("RUN_TEST_NEW_ENV"), + "found RUN_TEST_NEW_ENV inside of:\n\n{}", output); +} + diff --git a/gcc/testsuite/rust/rustc/ui/process/process-sigpipe.rs b/gcc/testsuite/rust/rustc/ui/process/process-sigpipe.rs new file mode 100644 index 000000000000..6de40a0bc46b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/process/process-sigpipe.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(unused_imports)] +#![allow(deprecated)] + +// ignore-android since the dynamic linker sets a SIGPIPE handler (to do +// a crash report) so inheritance is moot on the entire platform + +// libstd ignores SIGPIPE, and other libraries may set signal masks. +// Make sure that these behaviors don't get inherited to children +// spawned via std::process, since they're needed for traditional UNIX +// filter behavior. This test checks that `yes | head` terminates +// (instead of running forever), and that it does not print an error +// message about a broken pipe. + +// ignore-cloudabi no subprocesses support +// ignore-emscripten no threads support +// ignore-vxworks no 'sh' + +use std::process; +use std::thread; + +#[cfg(unix)] +fn main() { + // Just in case `yes` doesn't check for EPIPE... + thread::spawn(|| { + thread::sleep_ms(5000); + process::exit(1); + }); + let output = process::Command::new("sh").arg("-c").arg("yes | head").output().unwrap(); + assert!(output.status.success()); + assert!(output.stderr.len() == 0); +} + +#[cfg(not(unix))] +fn main() { + // Not worried about signal masks on other platforms +} + diff --git a/gcc/testsuite/rust/rustc/ui/process/process-spawn-nonexistent.rs b/gcc/testsuite/rust/rustc/ui/process/process-spawn-nonexistent.rs new file mode 100644 index 000000000000..2da74591adf2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/process/process-spawn-nonexistent.rs @@ -0,0 +1,16 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::io::ErrorKind; +use std::process::Command; + +fn main() { + assert_eq!(Command::new("nonexistent") + .spawn() + .unwrap_err() + .kind(), + ErrorKind::NotFound); +} + diff --git a/gcc/testsuite/rust/rustc/ui/process/process-spawn-with-unicode-params.rs b/gcc/testsuite/rust/rustc/ui/process/process-spawn-with-unicode-params.rs new file mode 100644 index 000000000000..c8bf282f2435 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/process/process-spawn-with-unicode-params.rs @@ -0,0 +1,78 @@ +// run-pass +// no-prefer-dynamic + +// The test copies itself into a subdirectory with a non-ASCII name and then +// runs it as a child process within the subdirectory. The parent process +// also adds an environment variable and an argument, both containing +// non-ASCII characters. The child process ensures all the strings are +// intact. + +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::io::prelude::*; +use std::io; +use std::fs; +use std::process::Command; +use std::env; +use std::path::Path; + +fn main() { + let my_args = env::args().collect::>(); + let my_cwd = env::current_dir().unwrap(); + let my_env = env::vars().collect::>(); + let my_path = env::current_exe().unwrap(); + let my_dir = my_path.parent().unwrap(); + let my_ext = my_path.extension().and_then(|s| s.to_str()).unwrap_or(""); + + // some non-ASCII characters + let blah = "\u{3c0}\u{42f}\u{97f3}\u{e6}\u{221e}"; + + let child_name = "child"; + let child_dir = format!("process-spawn-with-unicode-params-{}", blah); + + // parameters sent to child / expected to be received from parent + let arg = blah; + let cwd = my_dir.join(&child_dir); + let env = ("RUST_TEST_PROC_SPAWN_UNICODE".to_string(), blah.to_string()); + + // am I the parent or the child? + if my_args.len() == 1 { // parent + + let child_filestem = Path::new(child_name); + let child_filename = child_filestem.with_extension(my_ext); + let child_path = cwd.join(&child_filename); + + // make a separate directory for the child + let _ = fs::create_dir(&cwd); + fs::copy(&my_path, &child_path).unwrap(); + + // run child + let p = Command::new(&child_path) + .arg(arg) + .current_dir(&cwd) + .env(&env.0, &env.1) + .spawn().unwrap().wait_with_output().unwrap(); + + // display the output + io::stdout().write_all(&p.stdout).unwrap(); + io::stderr().write_all(&p.stderr).unwrap(); + + // make sure the child succeeded + assert!(p.status.success()); + + } else { // child + + // check working directory (don't try to compare with `cwd` here!) + assert!(my_cwd.ends_with(&child_dir)); + + // check arguments + assert_eq!(&*my_args[1], arg); + + // check environment variable + assert!(my_env.contains(&env)); + + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/process/process-status-inherits-stdin.rs b/gcc/testsuite/rust/rustc/ui/process/process-status-inherits-stdin.rs new file mode 100644 index 000000000000..15bc020b5bee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/process/process-status-inherits-stdin.rs @@ -0,0 +1,37 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::env; +use std::io; +use std::io::Write; +use std::process::{Command, Stdio}; + +fn main() { + let mut args = env::args(); + let me = args.next().unwrap(); + let arg = args.next(); + match arg.as_ref().map(|s| &s[..]) { + None => { + let mut s = Command::new(&me) + .arg("a1") + .stdin(Stdio::piped()) + .spawn() + .unwrap(); + s.stdin.take().unwrap().write_all(b"foo\n").unwrap(); + let s = s.wait().unwrap(); + assert!(s.success()); + } + Some("a1") => { + let s = Command::new(&me).arg("a2").status().unwrap(); + assert!(s.success()); + } + Some(..) => { + let mut s = String::new(); + io::stdin().read_line(&mut s).unwrap(); + assert_eq!(s, "foo\n"); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/process/tls-exit-status.rs b/gcc/testsuite/rust/rustc/ui/process/tls-exit-status.rs new file mode 100644 index 000000000000..e8ce0aded3a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/process/tls-exit-status.rs @@ -0,0 +1,13 @@ +// run-fail +// error-pattern:nonzero +// exec-env:RUST_NEWRT=1 +// ignore-cloudabi no std::env +// ignore-emscripten no processes + +use std::env; + +fn main() { + env::args(); + panic!("please have a nonzero exit status"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/project-cache-issue-31849.rs b/gcc/testsuite/rust/rustc/ui/project-cache-issue-31849.rs new file mode 100644 index 000000000000..fe3ea590afe0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/project-cache-issue-31849.rs @@ -0,0 +1,66 @@ +// run-pass +// Regression test for #31849: the problem here was actually a performance +// cliff, but I'm adding the test for reference. + +pub trait Upcast { + fn upcast(self) -> T; +} + +impl Upcast<(T1, T2)> for (S1,S2) + where S1: Upcast, + S2: Upcast, +{ + fn upcast(self) -> (T1, T2) { (self.0.upcast(), self.1.upcast()) } +} + +impl Upcast<()> for () +{ + fn upcast(self) -> () { () } +} + +pub trait ToStatic { + type Static: 'static; + fn to_static(self) -> Self::Static where Self: Sized; +} + +impl ToStatic for (T, U) + where T: ToStatic, + U: ToStatic +{ + type Static = (T::Static, U::Static); + fn to_static(self) -> Self::Static { (self.0.to_static(), self.1.to_static()) } +} + +impl ToStatic for () +{ + type Static = (); + fn to_static(self) -> () { () } +} + + +trait Factory { + type Output; + fn build(&self) -> Self::Output; +} + +impl Factory for (S, T) + where S: Factory, + T: Factory, + S::Output: ToStatic, + ::Static: Upcast, +{ + type Output = (S::Output, T::Output); + fn build(&self) -> Self::Output { (self.0.build().to_static().upcast(), self.1.build()) } +} + +impl Factory for () { + type Output = (); + fn build(&self) -> Self::Output { () } +} + +fn main() { + // More parens, more time. + let it = ((((((((((),()),()),()),()),()),()),()),()),()); + it.build(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/project-cache-issue-37154.rs b/gcc/testsuite/rust/rustc/ui/project-cache-issue-37154.rs new file mode 100644 index 000000000000..c55f4578a1e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/project-cache-issue-37154.rs @@ -0,0 +1,22 @@ +// run-pass + +#![allow(dead_code)] +// Regression test for #37154: the problem here was that the cache +// results in a false error because it was caching placeholder results +// even after those placeholder regions had been popped. + +trait Foo { + fn method(&self) {} +} + +struct Wrapper(T); + +impl Foo for Wrapper where for<'a> &'a T: IntoIterator {} + +fn f(x: Wrapper>) { + x.method(); // This works. + x.method(); // error: no method named `method` +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/project-defer-unification.rs b/gcc/testsuite/rust/rustc/ui/project-defer-unification.rs new file mode 100644 index 000000000000..6729f93e3935 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/project-defer-unification.rs @@ -0,0 +1,105 @@ +// 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/gcc/testsuite/rust/rustc/ui/ptr-coercion-rpass.rs b/gcc/testsuite/rust/rustc/ui/ptr-coercion-rpass.rs new file mode 100644 index 000000000000..8df99c274aff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ptr-coercion-rpass.rs @@ -0,0 +1,31 @@ +// run-pass + +#![allow(unused_variables)] +// Test coercions between pointers which don't do anything fancy like unsizing. + +// pretty-expanded FIXME #23616 + +pub fn main() { + // &mut -> & + let x: &mut isize = &mut 42; + let x: &isize = x; + + let x: &isize = &mut 42; + + // & -> *const + let x: &isize = &42; + let x: *const isize = x; + + let x: *const isize = &42; + + // &mut -> *const + let x: &mut isize = &mut 42; + let x: *const isize = x; + + let x: *const isize = &mut 42; + + // *mut -> *const + let x: *mut isize = &mut 42; + let x: *const isize = x; +} + diff --git a/gcc/testsuite/rust/rustc/ui/ptr-coercion.rs b/gcc/testsuite/rust/rustc/ui/ptr-coercion.rs new file mode 100644 index 000000000000..6eb5580e1dfc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ptr-coercion.rs @@ -0,0 +1,24 @@ +// Test coercions between pointers which don't do anything fancy like unsizing. +// These are testing that we don't lose mutability when converting to raw pointers. + +pub fn main() { + // *const -> *mut + let x: *const isize = &42; + let x: *mut isize = x; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } + + // & -> *mut + let x: *mut isize = &42; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } + + let x: *const isize = &42; + let x: *mut isize = x; // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/issue-33174-restricted-type-in-public-interface.rs b/gcc/testsuite/rust/rustc/ui/pub/issue-33174-restricted-type-in-public-interface.rs new file mode 100644 index 000000000000..a25f27526734 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/issue-33174-restricted-type-in-public-interface.rs @@ -0,0 +1,29 @@ +#![allow(non_camel_case_types)] // genus is always capitalized + +pub(crate) struct Snail; +// { dg-note "" "" { target *-*-* } .-1 } + +mod sea { + pub(super) struct Turtle; +// { dg-note "" "" { target *-*-* } .-1 } +} + +struct Tortoise; +// { dg-note "" "" { target *-*-* } .-1 } + +pub struct Shell { + pub(crate) creature: T, +} + +pub type Helix_pomatia = Shell; +// { dg-error ".E0446." "" { target *-*-* } .-1 } +// { dg-note ".E0446." "" { target *-*-* } .-2 } +pub type Dermochelys_coriacea = Shell; +// { dg-error ".E0446." "" { target *-*-* } .-1 } +// { dg-note ".E0446." "" { target *-*-* } .-2 } +pub type Testudo_graeca = Shell; +// { dg-error ".E0446." "" { target *-*-* } .-1 } +// { dg-note ".E0446." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-2.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-2.rs new file mode 100644 index 000000000000..288f068f47f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-2.rs @@ -0,0 +1,11 @@ +// run-rustfix + +pub foo(_s: usize) { bar() } +// { dg-error "" "" { target *-*-* } .-1 } + +fn bar() {} + +fn main() { + foo(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-3.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-3.rs new file mode 100644 index 000000000000..03d993af1880 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-3.rs @@ -0,0 +1,9 @@ +// #60115 + +mod foo { + pub bar(); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-or-struct-2.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-or-struct-2.rs new file mode 100644 index 000000000000..eab9d360fe41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-or-struct-2.rs @@ -0,0 +1,5 @@ +pub S(); +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-or-struct.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-or-struct.rs new file mode 100644 index 000000000000..eda37033a9b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-or-struct.rs @@ -0,0 +1,5 @@ +pub S (foo) bar +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-with-lifetime-2.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-with-lifetime-2.rs new file mode 100644 index 000000000000..fb33c8fd7f58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-with-lifetime-2.rs @@ -0,0 +1,7 @@ +pub bar<'a>(&self, _s: &'a usize) -> bool { true } +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + bar(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-with-lifetime.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-with-lifetime.rs new file mode 100644 index 000000000000..e244d46f3c77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn-with-lifetime.rs @@ -0,0 +1,9 @@ +// run-rustfix + +pub foo<'a>(_s: &'a usize) -> bool { true } +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + foo(&2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn.rs new file mode 100644 index 000000000000..bd23a1b35157 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-fn.rs @@ -0,0 +1,9 @@ +// run-rustfix + +pub foo(_s: usize) -> bool { true } +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + foo(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-ident-struct-with-lifetime.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-struct-with-lifetime.rs new file mode 100644 index 000000000000..c8b24d9b0a6a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-struct-with-lifetime.rs @@ -0,0 +1,5 @@ +pub S<'a> { +// { dg-error "" "" { target *-*-* } .-1 } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-ident-struct.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-struct.rs new file mode 100644 index 000000000000..c45a0cebe370 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-struct.rs @@ -0,0 +1,7 @@ +// run-rustfix + +pub S { +// { dg-error "" "" { target *-*-* } .-1 } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-ident-with-lifetime-incomplete.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-with-lifetime-incomplete.rs new file mode 100644 index 000000000000..0f8e37659491 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-ident-with-lifetime-incomplete.rs @@ -0,0 +1,6 @@ +fn main() { +} + +pub foo<'a> +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-reexport-priv-extern-crate.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-reexport-priv-extern-crate.rs new file mode 100644 index 000000000000..b7018f10886e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-reexport-priv-extern-crate.rs @@ -0,0 +1,25 @@ +#![allow(unused)] + +extern crate core; +pub use core as reexported_core; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + +mod foo1 { + extern crate core; +} + +mod foo2 { + use foo1::core; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + pub mod bar { + extern crate core; + } +} + +mod baz { + pub use foo2::bar::core; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-restricted-error-fn.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-restricted-error-fn.rs new file mode 100644 index 000000000000..710a43b8925f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-restricted-error-fn.rs @@ -0,0 +1,3 @@ +pub(crate) () fn foo() {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-restricted-error.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-restricted-error.rs new file mode 100644 index 000000000000..7ff4b2083b6c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-restricted-error.rs @@ -0,0 +1,10 @@ +#![feature(pub_restricted)] + +struct Bar(pub(())); + +struct Foo { + pub(crate) () foo: usize, // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-restricted-non-path.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-restricted-non-path.rs new file mode 100644 index 000000000000..1c2fea2d10e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-restricted-non-path.rs @@ -0,0 +1,6 @@ +#![feature(pub_restricted)] + +pub (.) fn afn() {} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/pub/pub-restricted.rs b/gcc/testsuite/rust/rustc/ui/pub/pub-restricted.rs new file mode 100644 index 000000000000..d79f5017e76d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pub/pub-restricted.rs @@ -0,0 +1,34 @@ +#![feature(pub_restricted)] + +mod a {} + +pub (a) fn afn() {} // { dg-error ".E0704." "" { target *-*-* } } +pub (b) fn bfn() {} // { dg-error ".E0704." "" { target *-*-* } } +pub (crate::a) fn cfn() {} // { dg-error ".E0704." "" { target *-*-* } } + +pub fn privfn() {} +mod x { + mod y { + pub (in x) fn foo() {} + pub (super) fn bar() {} + pub (crate) fn qux() {} + } +} + +mod y { + struct Foo { + pub (crate) c: usize, + pub (super) s: usize, + valid_private: usize, + pub (in y) valid_in_x: usize, + pub (a) invalid: usize, // { dg-error ".E0704." "" { target *-*-* } } + pub (in x) non_parent_invalid: usize, // { dg-error ".E0742." "" { target *-*-* } } + } +} + +fn main() {} + +// test multichar names +mod xyz {} +pub (xyz) fn xyz() {} // { dg-error ".E0704." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/pure-sum.rs b/gcc/testsuite/rust/rustc/ui/pure-sum.rs new file mode 100644 index 000000000000..92cd2c9ec70b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/pure-sum.rs @@ -0,0 +1,54 @@ +// run-pass + +#![allow(dead_code)] +// Check that functions can modify local state. + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +fn sums_to(v: Vec , sum: isize) -> bool { + let mut i = 0; + let mut sum0 = 0; + while i < v.len() { + sum0 += v[i]; + i += 1; + } + return sum0 == sum; +} + +fn sums_to_using_uniq(v: Vec , sum: isize) -> bool { + let mut i = 0; + let mut sum0: Box<_> = box 0; + while i < v.len() { + *sum0 += v[i]; + i += 1; + } + return *sum0 == sum; +} + +fn sums_to_using_rec(v: Vec , sum: isize) -> bool { + let mut i = 0; + let mut sum0 = F {f: 0}; + while i < v.len() { + sum0.f += v[i]; + i += 1; + } + return sum0.f == sum; +} + +struct F { f: T } + +fn sums_to_using_uniq_rec(v: Vec , sum: isize) -> bool { + let mut i = 0; + let mut sum0 = F::> {f: box 0}; + while i < v.len() { + *sum0.f += v[i]; + i += 1; + } + return *sum0.f == sum; +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/purity-infer.rs b/gcc/testsuite/rust/rustc/ui/purity-infer.rs new file mode 100644 index 000000000000..b26043d26759 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/purity-infer.rs @@ -0,0 +1,7 @@ +// run-pass + +fn something(f: F) where F: FnOnce() { f(); } +pub fn main() { + something(|| println!("hi!") ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/qualified/qualified-path-params-2.rs b/gcc/testsuite/rust/rustc/ui/qualified/qualified-path-params-2.rs new file mode 100644 index 000000000000..e78ada6a9d3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/qualified/qualified-path-params-2.rs @@ -0,0 +1,22 @@ +// Check that qualified paths with type parameters +// fail during type checking and not during parsing + +struct S; + +trait Tr { + type A; +} + +impl Tr for S { + type A = S; +} + +impl S { + fn f() {} +} + +type A = ::A::f; +// { dg-error ".E0223." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/qualified/qualified-path-params.rs b/gcc/testsuite/rust/rustc/ui/qualified/qualified-path-params.rs new file mode 100644 index 000000000000..c6538e33f0bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/qualified/qualified-path-params.rs @@ -0,0 +1,26 @@ +// Check that qualified paths with type parameters +// fail during type checking and not during parsing + +struct S; + +trait Tr { + type A; +} + +impl Tr for S { + type A = S; +} + +impl S { + fn f() {} +} + +fn main() { + match 10 { + ::A::f:: => {} +// { dg-error ".E0533." "" { target *-*-* } .-1 } + 0 ..= ::A::f:: => {} +// { dg-error ".E0029." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/question-mark-type-infer.rs b/gcc/testsuite/rust/rustc/ui/question-mark-type-infer.rs new file mode 100644 index 000000000000..a02f9f2beba1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/question-mark-type-infer.rs @@ -0,0 +1,18 @@ +#![feature(question_mark, question_mark_carrier)] + +// Test that type inference fails where there are multiple possible return types +// for the `?` operator. + +fn f(x: &i32) -> Result { + Ok(*x) +} + +fn g() -> Result, ()> { + let l = [1, 2, 3, 4]; + l.iter().map(f).collect()? // { dg-error ".E0283." "" { target *-*-* } } +} + +fn main() { + g(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/range-type-infer.rs b/gcc/testsuite/rust/rustc/ui/range-type-infer.rs new file mode 100644 index 000000000000..3d7fa428388c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range-type-infer.rs @@ -0,0 +1,23 @@ +// run-pass + +#![allow(unused_must_use)] +// Make sure the type inference for the new range expression work as +// good as the old one. Check out issue #21672, #21595 and #21649 for +// more details. + + +fn main() { + let xs = (0..8).map(|i| i == 1u64).collect::>(); + assert_eq!(xs[1], true); + let xs = (0..8).map(|i| 1u64 == i).collect::>(); + assert_eq!(xs[1], true); + let xs: Vec = (0..10).collect(); + assert_eq!(xs.len(), 10); + + for x in 0..10 { x % 2; } + for x in 0..100 { x as f32; } + + let array = [true, false]; + for i in 0..1 { array[i]; } +} + diff --git a/gcc/testsuite/rust/rustc/ui/range/issue-54505-no-literals.rs b/gcc/testsuite/rust/rustc/ui/range/issue-54505-no-literals.rs new file mode 100644 index 000000000000..e1c987e924df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/issue-54505-no-literals.rs @@ -0,0 +1,76 @@ +// run-rustfix + +// Regression test for changes introduced while fixing #54505 + +// This test uses non-literals for Ranges +// (expecting no parens with borrow suggestion) + +use std::ops::RangeBounds; + + +// take a reference to any built-in range +fn take_range(_r: &impl RangeBounds) {} + + +fn main() { + take_range(std::ops::Range { start: 0, end: 1 }); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(::std::ops::Range { start: 0, end: 1 }); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(std::ops::RangeFrom { start: 1 }); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(::std::ops::RangeFrom { start: 1 }); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(std::ops::RangeFull {}); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(::std::ops::RangeFull {}); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(std::ops::RangeInclusive::new(0, 1)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(::std::ops::RangeInclusive::new(0, 1)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(std::ops::RangeTo { end: 5 }); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(::std::ops::RangeTo { end: 5 }); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(std::ops::RangeToInclusive { end: 5 }); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(::std::ops::RangeToInclusive { end: 5 }); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/range/issue-54505-no-std.rs b/gcc/testsuite/rust/rustc/ui/range/issue-54505-no-std.rs new file mode 100644 index 000000000000..bf0d31c99547 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/issue-54505-no-std.rs @@ -0,0 +1,57 @@ +// error-pattern: `#[panic_handler]` function required, but not found + +// Regression test for #54505 - range borrowing suggestion had +// incorrect syntax (missing parentheses). + +// This test doesn't use std +// (so all Ranges resolve to core::ops::Range...) + +#![no_std] +#![feature(lang_items)] + +use core::ops::RangeBounds; + +#[cfg(any(not(target_arch = "wasm32"), target_os = "emscripten"))] +#[lang = "eh_personality"] +extern fn eh_personality() {} +#[cfg(target_os = "emscripten")] +#[lang = "eh_catch_typeinfo"] +static EH_CATCH_TYPEINFO: u8 = 0; + + +// take a reference to any built-in range +fn take_range(_r: &impl RangeBounds) {} + + +fn main() { + take_range(0..1); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(1..); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(..); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(0..=1); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(..5); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(..=42); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/range/issue-54505.rs b/gcc/testsuite/rust/rustc/ui/range/issue-54505.rs new file mode 100644 index 000000000000..3ec4f0a522f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/issue-54505.rs @@ -0,0 +1,44 @@ +// run-rustfix + +// Regression test for #54505 - range borrowing suggestion had +// incorrect syntax (missing parentheses). + +use std::ops::RangeBounds; + + +// take a reference to any built-in range +fn take_range(_r: &impl RangeBounds) {} + + +fn main() { + take_range(0..1); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(1..); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(..); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(0..=1); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(..5); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } + + take_range(..=42); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { help ".E0308." "" { target *-*-* } .-2 } +// { suggestion ".E0308." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/range/issue-73553-misinterp-range-literal.rs b/gcc/testsuite/rust/rustc/ui/range/issue-73553-misinterp-range-literal.rs new file mode 100644 index 000000000000..8e09284d27b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/issue-73553-misinterp-range-literal.rs @@ -0,0 +1,17 @@ +type Range = std::ops::Range; + +fn demo(r: &Range) { + println!("{:?}", r); +} + +fn tell(x: usize) -> usize { + x +} + +fn main() { + demo(tell(1)..tell(10)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + demo(1..10); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/range/range-1.rs b/gcc/testsuite/rust/rustc/ui/range/range-1.rs new file mode 100644 index 000000000000..0793bc357f30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/range-1.rs @@ -0,0 +1,17 @@ +// Test range syntax - type errors. + +pub fn main() { + // Mixed types. + let _ = 0u32..10i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + // Bool => does not implement iterator. + for i in false..true {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // Unsized type. + let arr: &[_] = &[1, 2, 3]; + let range = *arr..; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/range/range-inclusive-pattern-precedence.rs b/gcc/testsuite/rust/rustc/ui/range/range-inclusive-pattern-precedence.rs new file mode 100644 index 000000000000..20bcd75c14c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/range-inclusive-pattern-precedence.rs @@ -0,0 +1,21 @@ +// In expression, `&a..=b` is treated as `(&a)..=(b)` and `box a..=b` is +// `(box a)..=(b)`. In a pattern, however, `&a..=b` means `&(a..=b)`. This may +// lead to confusion. + +// run-rustfix + +#![warn(ellipsis_inclusive_range_patterns)] + +pub fn main() { + match &12 { + &0...9 => {} +// { dg-warning "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + &10..=15 => {} +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + &(16..=20) => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/range/range-inclusive-pattern-precedence2.rs b/gcc/testsuite/rust/rustc/ui/range/range-inclusive-pattern-precedence2.rs new file mode 100644 index 000000000000..bfcf0e23cca2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/range-inclusive-pattern-precedence2.rs @@ -0,0 +1,20 @@ +// We are going to disallow `&a..=b` and `box a..=b` in a pattern. However, the +// older ... syntax is still allowed as a stability guarantee. + +#![feature(box_patterns)] +#![warn(ellipsis_inclusive_range_patterns)] + +fn main() { + match Box::new(12) { + // FIXME: can we add suggestions like `&(0..=9)`? + box 0...9 => {} +// { dg-warning "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + box 10..=15 => {} +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + box (16..=20) => {} + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/range/range_traits-1.rs b/gcc/testsuite/rust/rustc/ui/range/range_traits-1.rs new file mode 100644 index 000000000000..275280740542 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/range_traits-1.rs @@ -0,0 +1,50 @@ +use std::ops::*; + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +struct AllTheRanges { + a: Range, +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } +// { dg-error ".E0277." "" { target *-*-* } .-6 } + b: RangeTo, +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } +// { dg-error ".E0277." "" { target *-*-* } .-6 } + c: RangeFrom, +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } +// { dg-error ".E0277." "" { target *-*-* } .-6 } + d: RangeFull, +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } +// { dg-error ".E0277." "" { target *-*-* } .-6 } + e: RangeInclusive, +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } +// { dg-error ".E0277." "" { target *-*-* } .-6 } + f: RangeToInclusive, +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } +// { dg-error ".E0277." "" { target *-*-* } .-4 } +// { dg-error ".E0277." "" { target *-*-* } .-5 } +// { dg-error ".E0277." "" { target *-*-* } .-6 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/range/range_traits-2.rs b/gcc/testsuite/rust/rustc/ui/range/range_traits-2.rs new file mode 100644 index 000000000000..6dcacc0e4f8a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/range_traits-2.rs @@ -0,0 +1,7 @@ +use std::ops::*; + +#[derive(Copy, Clone)] // { dg-error ".E0204." "" { target *-*-* } } +struct R(Range); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/range/range_traits-3.rs b/gcc/testsuite/rust/rustc/ui/range/range_traits-3.rs new file mode 100644 index 000000000000..1c2d6bc4d6d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/range_traits-3.rs @@ -0,0 +1,7 @@ +use std::ops::*; + +#[derive(Copy, Clone)] // { dg-error ".E0204." "" { target *-*-* } } +struct R(RangeFrom); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/range/range_traits-4.rs b/gcc/testsuite/rust/rustc/ui/range/range_traits-4.rs new file mode 100644 index 000000000000..5ee4773fee38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/range_traits-4.rs @@ -0,0 +1,10 @@ +// build-pass (FIXME(62277): could be check-pass?) + +use std::ops::*; + +#[derive(Copy, Clone)] +struct R(RangeTo); + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/range/range_traits-5.rs b/gcc/testsuite/rust/rustc/ui/range/range_traits-5.rs new file mode 100644 index 000000000000..59bc9a798aed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/range_traits-5.rs @@ -0,0 +1,10 @@ +// build-pass (FIXME(62277): could be check-pass?) + +use std::ops::*; + +#[derive(Copy, Clone)] +struct R(RangeFull); + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/range/range_traits-6.rs b/gcc/testsuite/rust/rustc/ui/range/range_traits-6.rs new file mode 100644 index 000000000000..32c135c4ba69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/range_traits-6.rs @@ -0,0 +1,7 @@ +use std::ops::*; + +#[derive(Copy, Clone)] // { dg-error ".E0204." "" { target *-*-* } } +struct R(RangeInclusive); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/range/range_traits-7.rs b/gcc/testsuite/rust/rustc/ui/range/range_traits-7.rs new file mode 100644 index 000000000000..12b608a6a7fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range/range_traits-7.rs @@ -0,0 +1,10 @@ +// build-pass (FIXME(62277): could be check-pass?) + +use std::ops::*; + +#[derive(Copy, Clone)] +struct R(RangeToInclusive); + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/range_inclusive.rs b/gcc/testsuite/rust/rustc/ui/range_inclusive.rs new file mode 100644 index 000000000000..ea10095f71c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range_inclusive.rs @@ -0,0 +1,122 @@ +// run-pass +// Test inclusive range syntax. +#![allow(unused_braces)] +#![allow(unused_comparisons)] + +use std::ops::RangeToInclusive; + +fn foo() -> isize { 42 } + +// Test that range syntax works in return statements +pub fn return_range_to() -> RangeToInclusive { return ..=1; } + +#[derive(Debug)] +struct P(u8); + +pub fn main() { + let mut count = 0; + for i in 0_usize..=10 { + assert!(i >= 0 && i <= 10); + count += i; + } + assert_eq!(count, 55); + + let mut count = 0; + let range = 0_usize..=10; + for i in range { + assert!(i >= 0 && i <= 10); + count += i; + } + assert_eq!(count, 55); + + let mut count = 0; + for i in (0_usize..=10).step_by(2) { + assert!(i >= 0 && i <= 10 && i % 2 == 0); + count += i; + } + assert_eq!(count, 30); + + let _ = 0_usize..=4+4-3; + let _ = 0..=foo(); + + let _ = { &42..=&100 }; // references to literals are OK + let _ = ..=42_usize; + + // Test we can use two different types with a common supertype. + let x = &42; + { + let y = 42; + let _ = x..=&y; + } + + // test collection indexing + let vec = (0..=10).collect::>(); + let slice: &[_] = &*vec; + let string = String::from("hello world"); + let stir = "hello world"; + + assert_eq!(&vec[3..=6], &[3, 4, 5, 6]); + assert_eq!(&vec[ ..=6], &[0, 1, 2, 3, 4, 5, 6]); + + assert_eq!(&slice[3..=6], &[3, 4, 5, 6]); + assert_eq!(&slice[ ..=6], &[0, 1, 2, 3, 4, 5, 6]); + + assert_eq!(&string[3..=6], "lo w"); + assert_eq!(&string[ ..=6], "hello w"); + + assert_eq!(&stir[3..=6], "lo w"); + assert_eq!(&stir[ ..=6], "hello w"); + + // test the size hints and emptying + let mut long = 0..=255u8; + let mut short = 42..=42u8; + assert_eq!(long.size_hint(), (256, Some(256))); + assert_eq!(short.size_hint(), (1, Some(1))); + long.next(); + short.next(); + assert_eq!(long.size_hint(), (255, Some(255))); + assert_eq!(short.size_hint(), (0, Some(0))); + assert!(short.is_empty()); + + assert_eq!(long.len(), 255); + assert_eq!(short.len(), 0); + + // test iterating backwards + assert_eq!(long.next_back(), Some(255)); + assert_eq!(long.next_back(), Some(254)); + assert_eq!(long.next_back(), Some(253)); + assert_eq!(long.next(), Some(1)); + assert_eq!(long.next(), Some(2)); + assert_eq!(long.next_back(), Some(252)); + for i in 3..=251 { + assert_eq!(long.next(), Some(i)); + } + assert!(long.is_empty()); + + // check underflow + let mut narrow = 1..=0; + assert_eq!(narrow.next_back(), None); + assert!(narrow.is_empty()); + let mut zero = 0u8..=0; + assert_eq!(zero.next_back(), Some(0)); + assert_eq!(zero.next_back(), None); + assert!(zero.is_empty()); + let mut high = 255u8..=255; + assert_eq!(high.next_back(), Some(255)); + assert_eq!(high.next_back(), None); + assert!(high.is_empty()); + + // what happens if you have a nonsense range? + let mut nonsense = 10..=5; + assert_eq!(nonsense.next(), None); + assert!(nonsense.is_empty()); + + // output + assert_eq!(format!("{:?}", 0..=10), "0..=10"); + assert_eq!(format!("{:?}", ..=10), "..=10"); + assert_eq!(format!("{:?}", 9..=6), "9..=6"); + + // ensure that constructing a RangeInclusive does not need PartialOrd bound + assert_eq!(format!("{:?}", P(1)..=P(2)), "P(1)..=P(2)"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/range_inclusive_gate.rs b/gcc/testsuite/rust/rustc/ui/range_inclusive_gate.rs new file mode 100644 index 000000000000..ebaba30463d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/range_inclusive_gate.rs @@ -0,0 +1,15 @@ +// run-pass + +#![allow(unused_comparisons)] +// Test that you only need the syntax gate if you don't mention the structs. +// (Obsoleted since both features are stabilized) + +fn main() { + let mut count = 0; + for i in 0_usize..=10 { + assert!(i >= 0 && i <= 10); + count += i; + } + assert_eq!(count, 55); +} + diff --git a/gcc/testsuite/rust/rustc/ui/ranges-precedence.rs b/gcc/testsuite/rust/rustc/ui/ranges-precedence.rs new file mode 100644 index 000000000000..43e521fdf014 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ranges-precedence.rs @@ -0,0 +1,53 @@ +// run-pass +// Test that the precedence of ranges is correct + + + +struct Foo { + foo: usize, +} + +impl Foo { + fn bar(&self) -> usize { 5 } +} + +fn main() { + let x = 1+3..4+5; + assert_eq!(x, (4..9)); + + let x = 1..4+5; + assert_eq!(x, (1..9)); + + let x = 1+3..4; + assert_eq!(x, (4..4)); + + let a = Foo { foo: 3 }; + let x = a.foo..a.bar(); + assert_eq!(x, (3..5)); + + let x = 1+3..; + assert_eq!(x, (4..)); + let x = ..1+3; + assert_eq!(x, (..4)); + + let a = &[0, 1, 2, 3, 4, 5, 6]; + let x = &a[1+1..2+2]; + assert_eq!(x, &a[2..4]); + let x = &a[..1+2]; + assert_eq!(x, &a[..3]); + let x = &a[1+2..]; + assert_eq!(x, &a[3..]); + + for _i in 2+4..10-3 {} + + let i = 42; + for _ in 1..i {} + for _ in 1.. { break; } + + let x = [1]..[2]; + assert_eq!(x, (([1])..([2]))); + + let y = ..; + assert_eq!(y, (..)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/raw-fat-ptr.rs b/gcc/testsuite/rust/rustc/ui/raw-fat-ptr.rs new file mode 100644 index 000000000000..64c598419e83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/raw-fat-ptr.rs @@ -0,0 +1,119 @@ +// run-pass +// check raw fat pointer ops + +use std::mem; + +fn assert_inorder(a: &[T]) { + for i in 0..a.len() { + for j in 0..a.len() { + if i < j { + assert!(a[i] < a[j]); + assert!(a[i] <= a[j]); + assert!(!(a[i] == a[j])); + assert!(a[i] != a[j]); + assert!(!(a[i] >= a[j])); + assert!(!(a[i] > a[j])); + } else if i == j { + assert!(!(a[i] < a[j])); + assert!(a[i] <= a[j]); + assert!(a[i] == a[j]); + assert!(!(a[i] != a[j])); + assert!(a[i] >= a[j]); + assert!(!(a[i] > a[j])); + } else { + assert!(!(a[i] < a[j])); + assert!(!(a[i] <= a[j])); + assert!(!(a[i] == a[j])); + assert!(a[i] != a[j]); + assert!(a[i] >= a[j]); + assert!(a[i] > a[j]); + } + } + } +} + +trait Foo { fn foo(&self) -> usize; } +impl Foo for T { + fn foo(&self) -> usize { + mem::size_of::() + } +} + +struct S(u32, T); + +fn main() { + let mut array = [0,1,2,3,4]; + let mut array2 = [5,6,7,8,9]; + + // fat ptr comparison: addr then extra + + // check ordering for arrays + let mut ptrs: Vec<*const [u8]> = vec![ + &array[0..0], &array[0..1], &array, &array[1..] + ]; + + let array_addr = &array as *const [u8] as *const u8 as usize; + let array2_addr = &array2 as *const [u8] as *const u8 as usize; + if array2_addr < array_addr { + ptrs.insert(0, &array2); + } else { + ptrs.push(&array2); + } + assert_inorder(&ptrs); + + // check ordering for mut arrays + let mut ptrs: Vec<*mut [u8]> = vec![ + &mut array[0..0], &mut array[0..1], &mut array, &mut array[1..] + ]; + + let array_addr = &mut array as *mut [u8] as *mut u8 as usize; + let array2_addr = &mut array2 as *mut [u8] as *mut u8 as usize; + if array2_addr < array_addr { + ptrs.insert(0, &mut array2); + } else { + ptrs.push(&mut array2); + } + assert_inorder(&ptrs); + + let mut u8_ = (0u8, 1u8); + let mut u32_ = (4u32, 5u32); + + // check ordering for ptrs + let buf: &mut [*const dyn Foo] = &mut [ + &u8_, &u8_.0, + &u32_, &u32_.0, + ]; + buf.sort_by(|u,v| { + let u : [*const (); 2] = unsafe { mem::transmute(*u) }; + let v : [*const (); 2] = unsafe { mem::transmute(*v) }; + u.cmp(&v) + }); + assert_inorder(buf); + + // check ordering for mut ptrs + let buf: &mut [*mut dyn Foo] = &mut [ + &mut u8_, &mut u8_.0, + &mut u32_, &mut u32_.0, + ]; + buf.sort_by(|u,v| { + let u : [*const (); 2] = unsafe { mem::transmute(*u) }; + let v : [*const (); 2] = unsafe { mem::transmute(*v) }; + u.cmp(&v) + }); + assert_inorder(buf); + + // check ordering for structs containing arrays + let ss: (S<[u8; 2]>, + S<[u8; 3]>, + S<[u8; 2]>) = ( + S(7, [8, 9]), + S(10, [11, 12, 13]), + S(4, [5, 6]) + ); + assert_inorder(&[ + &ss.0 as *const S<[u8]>, + &ss.1 as *const S<[u8]>, + &ss.2 as *const S<[u8]> + ]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/raw-ref-op/feature-raw-ref-op.rs b/gcc/testsuite/rust/rustc/ui/raw-ref-op/feature-raw-ref-op.rs new file mode 100644 index 000000000000..0dbcf618290a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/raw-ref-op/feature-raw-ref-op.rs @@ -0,0 +1,22 @@ +// gate-test-raw_ref_op + +macro_rules! is_expr { + ($e:expr) => {} +} + +is_expr!(&raw const a); // { dg-error ".E0658." "" { target *-*-* } } +is_expr!(&raw mut a); // { dg-error ".E0658." "" { target *-*-* } } + +#[cfg(FALSE)] +fn cfgd_out() { + let mut a = 0; + &raw const a; // { dg-error ".E0658." "" { target *-*-* } } + &raw mut a; // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() { + let mut y = 123; + let x = &raw const y; // { dg-error ".E0658." "" { target *-*-* } } + let x = &raw mut y; // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/raw-ref-op/raw-ref-op.rs b/gcc/testsuite/rust/rustc/ui/raw-ref-op/raw-ref-op.rs new file mode 100644 index 000000000000..9493b8b49f4f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/raw-ref-op/raw-ref-op.rs @@ -0,0 +1,14 @@ +// run-pass + +#![feature(raw_ref_op)] + +fn main() { + let mut x = 123; + let c_p = &raw const x; + let m_p = &raw mut x; + let i_r = &x; + assert!(c_p == i_r); + assert!(c_p == m_p); + unsafe { assert!(*c_p == *i_r ); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/raw-ref-op/raw-ref-temp-deref.rs b/gcc/testsuite/rust/rustc/ui/raw-ref-op/raw-ref-temp-deref.rs new file mode 100644 index 000000000000..ec4960922d11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/raw-ref-op/raw-ref-temp-deref.rs @@ -0,0 +1,25 @@ +// check-pass +// Check that taking the address of a place that contains a dereference is +// allowed. +#![feature(raw_ref_op, type_ascription)] + +const PAIR_REF: &(i32, i64) = &(1, 2); + +const ARRAY_REF: &[i32; 2] = &[3, 4]; +const SLICE_REF: &[i32] = &[5, 6]; + +fn main() { + // These are all OK, we're not taking the address of the temporary + let deref_ref = &raw const *PAIR_REF; + let field_deref_ref = &raw const PAIR_REF.0; + let deref_ref = &raw const *ARRAY_REF; + let index_deref_ref = &raw const ARRAY_REF[0]; + let deref_ref = &raw const *SLICE_REF; + let index_deref_ref = &raw const SLICE_REF[1]; + + let x = 0; + let ascribe_ref = &raw const (x: i32); + let ascribe_deref = &raw const (*ARRAY_REF: [i32; 2]); + let ascribe_index_deref = &raw const (ARRAY_REF[0]: i32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/raw-ref-op/raw-ref-temp.rs b/gcc/testsuite/rust/rustc/ui/raw-ref-op/raw-ref-temp.rs new file mode 100644 index 000000000000..0d72671e9e77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/raw-ref-op/raw-ref-temp.rs @@ -0,0 +1,32 @@ +// Ensure that we don't allow taking the address of temporary values +#![feature(raw_ref_op, type_ascription)] + +const FOUR: u64 = 4; + +const PAIR: (i32, i64) = (1, 2); + +const ARRAY: [i32; 2] = [1, 2]; + +fn main() { + let ref_expr = &raw const 2; // { dg-error ".E0745." "" { target *-*-* } } + let mut_ref_expr = &raw mut 3; // { dg-error ".E0745." "" { target *-*-* } } + let ref_const = &raw const FOUR; // { dg-error ".E0745." "" { target *-*-* } } + let mut_ref_const = &raw mut FOUR; // { dg-error ".E0745." "" { target *-*-* } } + + let field_ref_expr = &raw const (1, 2).0; // { dg-error ".E0745." "" { target *-*-* } } + let mut_field_ref_expr = &raw mut (1, 2).0; // { dg-error ".E0745." "" { target *-*-* } } + let field_ref = &raw const PAIR.0; // { dg-error ".E0745." "" { target *-*-* } } + let mut_field_ref = &raw mut PAIR.0; // { dg-error ".E0745." "" { target *-*-* } } + + let index_ref_expr = &raw const [1, 2][0]; // { dg-error ".E0745." "" { target *-*-* } } + let mut_index_ref_expr = &raw mut [1, 2][0]; // { dg-error ".E0745." "" { target *-*-* } } + let index_ref = &raw const ARRAY[0]; // { dg-error ".E0745." "" { target *-*-* } } + let mut_index_ref = &raw mut ARRAY[1]; // { dg-error ".E0745." "" { target *-*-* } } + + let ref_ascribe = &raw const (2: i32); // { dg-error ".E0745." "" { target *-*-* } } + let mut_ref_ascribe = &raw mut (3: i32); // { dg-error ".E0745." "" { target *-*-* } } + + let ascribe_field_ref = &raw const (PAIR.0: i32); // { dg-error ".E0745." "" { target *-*-* } } + let ascribe_index_ref = &raw mut (ARRAY[0]: i32); // { dg-error ".E0745." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/raw-ref-op/unusual_locations.rs b/gcc/testsuite/rust/rustc/ui/raw-ref-op/unusual_locations.rs new file mode 100644 index 000000000000..91cc61d964ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/raw-ref-op/unusual_locations.rs @@ -0,0 +1,23 @@ +// check-pass + +#![feature(raw_ref_op)] + +const USES_PTR: () = { let u = (); &raw const u; }; +static ALSO_USES_PTR: () = { let u = (); &raw const u; }; + +fn main() { + let x: [i32; { let u = 2; let x = &raw const u; 4 }] + = [2; { let v = 3; let y = &raw const v; 4 }]; + let mut one = 1; + let two = 2; + if &raw const one == &raw mut one { + match &raw const two { + _ => {} + } + } + let three = 3; + let mut four = 4; + println!("{:p}", &raw const three); + unsafe { &raw mut four; } +} + diff --git a/gcc/testsuite/rust/rustc/ui/raw-str.rs b/gcc/testsuite/rust/rustc/ui/raw-str.rs new file mode 100644 index 0000000000000000000000000000000000000000..25556a41b2838d54963b3afbc7884c2777461eb5 GIT binary patch literal 848 zcmaJ<$xg#C6y!?2!q`+<+9VYcm!b+GwhIymgoKorqO46&>Xa;OZNGsd|Hqf`oV00y zw3ZSlo_XV$XPYL;O0G|xJeN$9#ABXjfnLP^yIwf%-=!qxK@#wB5lPatbV~CKs$nnT`j;YO&Cmrh3&^ndGIRk>p+&|9>L2zkoWPU isize; +} + +// Note: impl on a slice; we're checking that the pointers below +// correctly get borrowed to `&`. (similar to impling for `isize`, with +// `&self` instead of `self`.) +impl<'a> get for &'a isize { + fn get(self) -> isize { + return *self; + } +} + +pub fn main() { + let x: Box<_> = box 6; + let y = x.get(); + println!("y={}", y); + assert_eq!(y, 6); + + let x = &6; + let y = x.get(); + println!("y={}", y); + assert_eq!(y, 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable-unnameable-items.rs b/gcc/testsuite/rust/rustc/ui/reachable-unnameable-items.rs new file mode 100644 index 000000000000..124a64f36156 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable-unnameable-items.rs @@ -0,0 +1,32 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default +// aux-build:reachable-unnameable-items.rs + +extern crate reachable_unnameable_items; +use reachable_unnameable_items::*; + +fn main() { + let res1 = function_returning_unnameable_type().method_of_unnameable_type1(); + let res2 = CONSTANT_OF_UNNAMEABLE_TYPE.method_of_unnameable_type2(); + let res4 = AliasOfUnnameableType{}.method_of_unnameable_type4(); + let res5 = function_returning_unnameable_type().inherent_method_returning_unnameable_type(). + method_of_unnameable_type5(); + let res6 = function_returning_unnameable_type().trait_method_returning_unnameable_type(). + method_of_unnameable_type6(); + let res7 = STATIC.field_of_unnameable_type.method_of_unnameable_type7(); + let res8 = generic_function::().method_of_unnameable_type8(); + let res_enum = NameableVariant.method_of_unnameable_enum(); + assert_eq!(res1, "Hello1"); + assert_eq!(res2, "Hello2"); + assert_eq!(res4, "Hello4"); + assert_eq!(res5, "Hello5"); + assert_eq!(res6, "Hello6"); + assert_eq!(res7, "Hello7"); + assert_eq!(res8, "Hello8"); + assert_eq!(res_enum, "HelloEnum"); + + let none = None; + function_accepting_unnameable_type(none); + let _guard = std::panic::catch_unwind(|| none.unwrap().method_of_unnameable_type3()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable-unnameable-type-alias.rs b/gcc/testsuite/rust/rustc/ui/reachable-unnameable-type-alias.rs new file mode 100644 index 000000000000..5802c453d319 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable-unnameable-type-alias.rs @@ -0,0 +1,17 @@ +// run-pass + +#![feature(staged_api)] +#![stable(feature = "a", since = "b")] + +mod inner_private_module { + // UnnameableTypeAlias isn't marked as reachable, so no stability annotation is required here + pub type UnnameableTypeAlias = u8; +} + +#[stable(feature = "a", since = "b")] +pub fn f() -> inner_private_module::UnnameableTypeAlias { + 0 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/auxiliary/unreachable_variant.rs b/gcc/testsuite/rust/rustc/ui/reachable/auxiliary/unreachable_variant.rs new file mode 100644 index 000000000000..9b972746e4bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/auxiliary/unreachable_variant.rs @@ -0,0 +1,6 @@ +mod super_sekrit { + pub enum sooper_sekrit { + quux, baz + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_add.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_add.rs new file mode 100644 index 000000000000..254f90013332 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_add.rs @@ -0,0 +1,19 @@ +#![feature(never_type)] +#![allow(unused_variables)] +#![deny(unreachable_code)] + +use std::ops; + +struct Foo; + +impl ops::Add for Foo { + type Output = !; + fn add(self, rhs: !) -> ! { + unimplemented!() + } +} + +fn main() { + let x = Foo + return; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_again.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_again.rs new file mode 100644 index 000000000000..b1589c105451 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_again.rs @@ -0,0 +1,12 @@ +#![feature(box_syntax)] +#![allow(unused_variables)] +#![deny(unreachable_code)] + +fn main() { + let x = loop { + continue; + println!("hi"); +// { dg-error "" "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_andand.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_andand.rs new file mode 100644 index 000000000000..7c0cd86e2b5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_andand.rs @@ -0,0 +1,14 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(unused_variables)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo() { + // No error here. + let x = false && (return); + println!("I am not dead."); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_array.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_array.rs new file mode 100644 index 000000000000..12c2bc7527a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_array.rs @@ -0,0 +1,18 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(type_ascription)] + +fn a() { + // the `22` is unreachable: + let x: [usize; 2] = [return, 22]; // { dg-error "" "" { target *-*-* } } +} + +fn b() { + // the array is unreachable: + let x: [usize; 2] = [22, return]; // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_assign.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_assign.rs new file mode 100644 index 000000000000..d144ecfaaf1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_assign.rs @@ -0,0 +1,30 @@ +#![feature(never_type)] +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo() { + // No error here. + let x; + x = return; // { dg-error "" "" { target *-*-* } } +} + +fn bar() { + use std::ptr; + let p: *mut ! = ptr::null_mut::(); + unsafe { + // Here we consider the `return` unreachable because + // "evaluating" the `*p` has type `!`. This is somewhat + // dubious, I suppose. + *p = return; // { dg-error "" "" { target *-*-* } } + } +} + +fn baz() { + let mut i = 0; + *{return; &mut i} = 22; // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_block.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_block.rs new file mode 100644 index 000000000000..82a493c202dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_block.rs @@ -0,0 +1,32 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn a() { + // Here the tail expression is considered unreachable: + let x = { + return; + 22 // { dg-error "" "" { target *-*-* } } + }; +} + +fn b() { + // Here the `x` assignment is considered unreachable, not the block: + let x = { + return; + }; +} + +fn c() { + // Here the `println!` is unreachable: + let x = { + return; + println!("foo"); +// { dg-error "" "" { target *-*-* } .-1 } + 22 + }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_box.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_box.rs new file mode 100644 index 000000000000..212a64332fda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_box.rs @@ -0,0 +1,9 @@ +#![feature(box_syntax)] +#![allow(unused_variables)] +#![deny(unreachable_code)] + +fn main() { + let x = box return; // { dg-error "" "" { target *-*-* } } + println!("hi"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_call.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_call.rs new file mode 100644 index 000000000000..69f37e0c3309 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_call.rs @@ -0,0 +1,22 @@ +#![feature(never_type)] +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo(x: !, y: usize) { } + +fn bar(x: !) { } + +fn a() { + // the `22` is unreachable: + foo(return, 22); // { dg-error "" "" { target *-*-* } } +} + +fn b() { + // the call is unreachable: + bar(return); // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_cast.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_cast.rs new file mode 100644 index 000000000000..b4b11e97ea6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_cast.rs @@ -0,0 +1,13 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(never_type, type_ascription)] + +fn a() { + // the cast is unreachable: + let x = {return} as !; // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_if.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_if.rs new file mode 100644 index 000000000000..6e004cec87c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_if.rs @@ -0,0 +1,32 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo() { + if {return} { // { dg-error "" "" { target *-*-* } } + println!("Hello, world!"); + } +} + +fn bar() { + if {true} { + return; + } + println!("I am not dead."); +} + +fn baz() { + if {true} { + return; + } else { + return; + } + // As the next action to be taken after the if arms, we should + // report the `println!` as unreachable: + println!("But I am."); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_loop.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_loop.rs new file mode 100644 index 000000000000..6f15c381a7cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_loop.rs @@ -0,0 +1,37 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn a() { + loop { return; } + println!("I am dead."); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn b() { + loop { + break; + } + println!("I am not dead."); +} + +fn c() { + loop { return; } + println!("I am dead."); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn d() { + 'outer: loop { loop { break 'outer; } } + println!("I am not dead."); +} + +fn e() { + loop { 'middle: loop { loop { break 'middle; } } } + println!("I am dead."); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_match.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_match.rs new file mode 100644 index 000000000000..c22368391fc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_match.rs @@ -0,0 +1,40 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn b() { + match () { () => return } + println!("I am dead"); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn c() { + match () { () if false => return, () => () } + println!("I am not dead"); +} + +fn d() { + match () { () if false => return, () => return } + println!("I am dead"); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn e() { + // Here the compiler fails to figure out that the `println` is dead. + match () { () if return => (), () => return } + println!("I am dead"); +} + +fn f() { + match Some(()) { None => (), Some(()) => return } + println!("I am not dead"); +} + +fn g() { + match Some(()) { None => return, Some(()) => () } + println!("I am not dead"); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_method.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_method.rs new file mode 100644 index 000000000000..5a6db10dafb5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_method.rs @@ -0,0 +1,25 @@ +#![feature(never_type)] +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +struct Foo; + +impl Foo { + fn foo(&self, x: !, y: usize) { } + fn bar(&self, x: !) { } +} + +fn a() { + // the `22` is unreachable: + Foo.foo(return, 22); // { dg-error "" "" { target *-*-* } } +} + +fn b() { + // the call is unreachable: + Foo.bar(return); // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_oror.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_oror.rs new file mode 100644 index 000000000000..722d86fdb330 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_oror.rs @@ -0,0 +1,13 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(unused_variables)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo() { + let x = false || (return); + println!("I am not dead."); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_repeat.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_repeat.rs new file mode 100644 index 000000000000..49a25ce5d077 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_repeat.rs @@ -0,0 +1,13 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(type_ascription)] + +fn a() { + // the repeat is unreachable: + let x: [usize; 2] = [return; 2]; // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_return.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_return.rs new file mode 100644 index 000000000000..5c994f17bda5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_return.rs @@ -0,0 +1,14 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(type_ascription)] + +fn a() { + // Here we issue that the "2nd-innermost" return is unreachable, + // but we stop there. + let x = {return {return {return;}}}; // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_return_in_macro.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_return_in_macro.rs new file mode 100644 index 000000000000..5c071dceedfa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_return_in_macro.rs @@ -0,0 +1,16 @@ +// Tests that we generate nice error messages +// when an expression is unreachble due to control +// flow inside of a macro expansion. +#![deny(unreachable_code)] + +macro_rules! early_return { + () => { + return () + } +} + +fn main() { + return early_return!(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_struct.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_struct.rs new file mode 100644 index 000000000000..33ebf42b412f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_struct.rs @@ -0,0 +1,33 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(type_ascription)] + +struct Foo { + a: usize, + b: usize, +} + +fn a() { + // struct expr is unreachable: + let x = Foo { a: 22, b: 33, ..return }; // { dg-error "" "" { target *-*-* } } +} + +fn b() { + // the `33` is unreachable: + let x = Foo { a: return, b: 33, ..return }; // { dg-error "" "" { target *-*-* } } +} + +fn c() { + // the `..return` is unreachable: + let x = Foo { a: 22, b: return, ..return }; // { dg-error "" "" { target *-*-* } } +} + +fn d() { + // the struct expr is unreachable: + let x = Foo { a: 22, b: return }; // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_tup.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_tup.rs new file mode 100644 index 000000000000..d084743951e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_tup.rs @@ -0,0 +1,18 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(type_ascription)] + +fn a() { + // the `2` is unreachable: + let x: (usize, usize) = (return, 2); // { dg-error "" "" { target *-*-* } } +} + +fn b() { + // the tuple is unreachable: + let x: (usize, usize) = (2, return); // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_type.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_type.rs new file mode 100644 index 000000000000..1046af3da29c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_type.rs @@ -0,0 +1,13 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] +#![feature(never_type, type_ascription)] + +fn a() { + // the cast is unreachable: + let x = {return}: !; // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_unary.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_unary.rs new file mode 100644 index 000000000000..d24ef41ec55a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_unary.rs @@ -0,0 +1,13 @@ +#![feature(never_type)] +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo() { + let x: ! = ! { return; }; // { dg-error ".E0600." "" { target *-*-* } } +// { dg-error ".E0600." "" { target *-*-* } .-2 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/expr_while.rs b/gcc/testsuite/rust/rustc/ui/reachable/expr_while.rs new file mode 100644 index 000000000000..e954f231dcfb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/expr_while.rs @@ -0,0 +1,30 @@ +#![allow(unused_variables)] +#![allow(unused_assignments)] +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn foo() { + while {return} { +// { dg-error "" "" { target *-*-* } .-1 } + println!("Hello, world!"); + } +} + +fn bar() { + while {true} { + return; + } + println!("I am not dead."); +} + +fn baz() { + // Here, we cite the `while` loop as dead. + while {return} { +// { dg-error "" "" { target *-*-* } .-1 } + println!("I am dead."); + } + println!("I am, too."); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/unreachable-arm.rs b/gcc/testsuite/rust/rustc/ui/reachable/unreachable-arm.rs new file mode 100644 index 000000000000..dd1f6b97e60e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/unreachable-arm.rs @@ -0,0 +1,15 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] +#![allow(dead_code)] +#![deny(unreachable_patterns)] + +enum Foo { A(Box, isize), B(usize), } + +fn main() { + match Foo::B(1) { + Foo::B(_) | Foo::A(box _, 1) => { } + Foo::A(_, 1) => { } // { dg-error "" "" { target *-*-* } } + _ => { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/unreachable-code.rs b/gcc/testsuite/rust/rustc/ui/reachable/unreachable-code.rs new file mode 100644 index 000000000000..1779bd6b815b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/unreachable-code.rs @@ -0,0 +1,9 @@ +#![deny(unreachable_code)] +#![allow(unused_variables)] + +fn main() { + loop{} + + let a = 3; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/unreachable-in-call.rs b/gcc/testsuite/rust/rustc/ui/reachable/unreachable-in-call.rs new file mode 100644 index 000000000000..7fb094c37910 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/unreachable-in-call.rs @@ -0,0 +1,23 @@ +#![allow(dead_code)] +#![deny(unreachable_code)] + +fn diverge() -> ! { panic!() } + +fn get_u8() -> u8 { + 1 +} +fn call(_: u8, _: u8) { + +} +fn diverge_first() { + call(diverge(), + get_u8()); // { dg-error "" "" { target *-*-* } } +} +fn diverge_second() { + call( // { dg-error "" "" { target *-*-* } } + get_u8(), + diverge()); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/unreachable-loop-patterns.rs b/gcc/testsuite/rust/rustc/ui/reachable/unreachable-loop-patterns.rs new file mode 100644 index 000000000000..9607ae0749ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/unreachable-loop-patterns.rs @@ -0,0 +1,22 @@ +#![feature(never_type, never_type_fallback)] +#![feature(exhaustive_patterns)] + +#![allow(unreachable_code)] +#![deny(unreachable_patterns)] + +enum Void {} + +impl Iterator for Void { + type Item = Void; + + fn next(&mut self) -> Option { + None + } +} + +fn main() { + for _ in unimplemented!() as Void {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/unreachable-try-pattern.rs b/gcc/testsuite/rust/rustc/ui/reachable/unreachable-try-pattern.rs new file mode 100644 index 000000000000..faa1317ca3a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/unreachable-try-pattern.rs @@ -0,0 +1,42 @@ +// check-pass +#![feature(never_type, exhaustive_patterns)] +#![warn(unreachable_code)] +#![warn(unreachable_patterns)] + +enum Void {} + +impl From for i32 { + fn from(v: Void) -> i32 { + match v {} + } +} + +fn bar(x: Result) -> Result { + x? +} + +fn foo(x: Result) -> Result { + let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?; +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + Ok(y) +} + +fn qux(x: Result) -> Result { + Ok(x?) +} + +fn vom(x: Result) -> Result { + let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?; +// { dg-warning "" "" { target *-*-* } .-1 } + Ok(y) +} + + +fn main() { + let _ = bar(Err(123)); + let _ = foo(Err(123)); + let _ = qux(Ok(123)); + let _ = vom(Ok(123)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/unreachable-variant.rs b/gcc/testsuite/rust/rustc/ui/reachable/unreachable-variant.rs new file mode 100644 index 000000000000..b3fc9f66e4fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/unreachable-variant.rs @@ -0,0 +1,8 @@ +// aux-build:unreachable_variant.rs + +extern crate unreachable_variant as other; + +fn main() { + let _x = other::super_sekrit::sooper_sekrit::baz; // { dg-error ".E0603." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/reachable/unwarned-match-on-never.rs b/gcc/testsuite/rust/rustc/ui/reachable/unwarned-match-on-never.rs new file mode 100644 index 000000000000..16bd412c1ebd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reachable/unwarned-match-on-never.rs @@ -0,0 +1,25 @@ +#![deny(unreachable_code)] +#![allow(dead_code)] + +#![feature(never_type)] + +fn foo(x: !) -> bool { + // Explicit matches on the never type are unwarned. + match x {} + // But matches in unreachable code are warned. + match x {} // { dg-error "" "" { target *-*-* } } +} + +fn bar() { + match (return) { + () => () // { dg-error "" "" { target *-*-* } } + } +} + +fn main() { + return; + match () { // { dg-error "" "" { target *-*-* } } + () => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/readalias.rs b/gcc/testsuite/rust/rustc/ui/readalias.rs new file mode 100644 index 000000000000..71e9b55f03fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/readalias.rs @@ -0,0 +1,13 @@ +// run-pass + +#![allow(dead_code)] + + + + +struct Point {x: isize, y: isize, z: isize} + +fn f(p: Point) { assert_eq!(p.z, 12); } + +pub fn main() { let x: Point = Point {x: 10, y: 11, z: 12}; f(x); } + diff --git a/gcc/testsuite/rust/rustc/ui/realloc-16687.rs b/gcc/testsuite/rust/rustc/ui/realloc-16687.rs new file mode 100644 index 000000000000..e1d857d1bb16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/realloc-16687.rs @@ -0,0 +1,189 @@ +// run-pass +// alloc::heap::reallocate test. +// +// Ideally this would be revised to use no_std, but for now it serves +// well enough to reproduce (and illustrate) the bug from #16687. + +#![feature(allocator_api)] +#![feature(slice_ptr_get)] + +use std::alloc::{handle_alloc_error, AllocRef, Global, Layout}; +use std::ptr::{self, NonNull}; + +fn main() { + unsafe { + assert!(test_triangle()); + } +} + +unsafe fn test_triangle() -> bool { + static COUNT: usize = 16; + let mut ascend = vec![ptr::null_mut(); COUNT]; + let ascend = &mut *ascend; + static ALIGN: usize = 1; + + // Checks that `ascend` forms triangle of ascending size formed + // from pairs of rows (where each pair of rows is equally sized), + // and the elements of the triangle match their row-pair index. + unsafe fn sanity_check(ascend: &[*mut u8]) { + for i in 0..COUNT / 2 { + let (p0, p1, size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i)); + for j in 0..size { + assert_eq!(*p0.add(j), i as u8); + assert_eq!(*p1.add(j), i as u8); + } + } + } + + static PRINT: bool = false; + + unsafe fn allocate(layout: Layout) -> *mut u8 { + if PRINT { + println!("allocate({:?})", layout); + } + + let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout)); + + if PRINT { + println!("allocate({:?}) = {:?}", layout, ptr); + } + + ptr.as_mut_ptr() + } + + unsafe fn deallocate(ptr: *mut u8, layout: Layout) { + if PRINT { + println!("deallocate({:?}, {:?}", ptr, layout); + } + + Global.dealloc(NonNull::new_unchecked(ptr), layout); + } + + unsafe fn reallocate(ptr: *mut u8, old: Layout, new: Layout) -> *mut u8 { + if PRINT { + println!("reallocate({:?}, old={:?}, new={:?})", ptr, old, new); + } + + let memory = if new.size() > old.size() { + Global.grow(NonNull::new_unchecked(ptr), old, new) + } else { + Global.shrink(NonNull::new_unchecked(ptr), old, new) + }; + + let ptr = memory.unwrap_or_else(|_| handle_alloc_error(new)); + + if PRINT { + println!("reallocate({:?}, old={:?}, new={:?}) = {:?}", ptr, old, new, ptr); + } + ptr.as_mut_ptr() + } + + fn idx_to_size(i: usize) -> usize { + (i + 1) * 10 + } + + // Allocate pairs of rows that form a triangle shape. (Hope is + // that at least two rows will be allocated near each other, so + // that we trigger the bug (a buffer overrun) in an observable + // way.) + for i in 0..COUNT / 2 { + let size = idx_to_size(i); + ascend[2 * i] = allocate(Layout::from_size_align(size, ALIGN).unwrap()); + ascend[2 * i + 1] = allocate(Layout::from_size_align(size, ALIGN).unwrap()); + } + + // Initialize each pair of rows to distinct value. + for i in 0..COUNT / 2 { + let (p0, p1, size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i)); + for j in 0..size { + *p0.add(j) = i as u8; + *p1.add(j) = i as u8; + } + } + + sanity_check(&*ascend); + test_1(ascend); // triangle -> square + test_2(ascend); // square -> triangle + test_3(ascend); // triangle -> square + test_4(ascend); // square -> triangle + + for i in 0..COUNT / 2 { + let size = idx_to_size(i); + deallocate(ascend[2 * i], Layout::from_size_align(size, ALIGN).unwrap()); + deallocate(ascend[2 * i + 1], Layout::from_size_align(size, ALIGN).unwrap()); + } + + return true; + + // Test 1: turn the triangle into a square (in terms of + // allocation; initialized portion remains a triangle) by + // realloc'ing each row from top to bottom, and checking all the + // rows as we go. + unsafe fn test_1(ascend: &mut [*mut u8]) { + let new_size = idx_to_size(COUNT - 1); + let new = Layout::from_size_align(new_size, ALIGN).unwrap(); + for i in 0..COUNT / 2 { + let (p0, p1, old_size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i)); + assert!(old_size < new_size); + let old = Layout::from_size_align(old_size, ALIGN).unwrap(); + + ascend[2 * i] = reallocate(p0, old.clone(), new.clone()); + sanity_check(&*ascend); + + ascend[2 * i + 1] = reallocate(p1, old.clone(), new.clone()); + sanity_check(&*ascend); + } + } + + // Test 2: turn the square back into a triangle, top to bottom. + unsafe fn test_2(ascend: &mut [*mut u8]) { + let old_size = idx_to_size(COUNT - 1); + let old = Layout::from_size_align(old_size, ALIGN).unwrap(); + for i in 0..COUNT / 2 { + let (p0, p1, new_size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i)); + assert!(new_size < old_size); + let new = Layout::from_size_align(new_size, ALIGN).unwrap(); + + ascend[2 * i] = reallocate(p0, old.clone(), new.clone()); + sanity_check(&*ascend); + + ascend[2 * i + 1] = reallocate(p1, old.clone(), new.clone()); + sanity_check(&*ascend); + } + } + + // Test 3: turn triangle into a square, bottom to top. + unsafe fn test_3(ascend: &mut [*mut u8]) { + let new_size = idx_to_size(COUNT - 1); + let new = Layout::from_size_align(new_size, ALIGN).unwrap(); + for i in (0..COUNT / 2).rev() { + let (p0, p1, old_size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i)); + assert!(old_size < new_size); + let old = Layout::from_size_align(old_size, ALIGN).unwrap(); + + ascend[2 * i + 1] = reallocate(p1, old.clone(), new.clone()); + sanity_check(&*ascend); + + ascend[2 * i] = reallocate(p0, old.clone(), new.clone()); + sanity_check(&*ascend); + } + } + + // Test 4: turn the square back into a triangle, bottom to top. + unsafe fn test_4(ascend: &mut [*mut u8]) { + let old_size = idx_to_size(COUNT - 1); + let old = Layout::from_size_align(old_size, ALIGN).unwrap(); + for i in (0..COUNT / 2).rev() { + let (p0, p1, new_size) = (ascend[2 * i], ascend[2 * i + 1], idx_to_size(i)); + assert!(new_size < old_size); + let new = Layout::from_size_align(new_size, ALIGN).unwrap(); + + ascend[2 * i + 1] = reallocate(p1, old.clone(), new.clone()); + sanity_check(&*ascend); + + ascend[2 * i] = reallocate(p0, old.clone(), new.clone()); + sanity_check(&*ascend); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/reassign-ref-mut.rs b/gcc/testsuite/rust/rustc/ui/reassign-ref-mut.rs new file mode 100644 index 000000000000..782b4abc65a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reassign-ref-mut.rs @@ -0,0 +1,17 @@ +// Tests how we behave when the user attempts to mutate an immutable +// binding that was introduced by either `ref` or `ref mut` +// patterns. +// +// Such bindings cannot be made mutable via the mere addition of the +// `mut` keyword, and thus we want to check that the compiler does not +// suggest doing so. + +fn main() { + let (mut one_two, mut three_four) = ((1, 2), (3, 4)); + let &mut (ref a, ref mut b) = &mut one_two; + a = &three_four.0; +// { dg-error ".E0384." "" { target *-*-* } .-1 } + b = &mut three_four.1; +// { dg-error ".E0384." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion/auxiliary/recursive_reexports.rs b/gcc/testsuite/rust/rustc/ui/recursion/auxiliary/recursive_reexports.rs new file mode 100644 index 000000000000..116b1da14de4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion/auxiliary/recursive_reexports.rs @@ -0,0 +1,4 @@ +pub mod foo { + pub use foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion/issue-26548-recursion-via-normalize.rs b/gcc/testsuite/rust/rustc/ui/recursion/issue-26548-recursion-via-normalize.rs new file mode 100644 index 000000000000..307c2e54c74e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion/issue-26548-recursion-via-normalize.rs @@ -0,0 +1,19 @@ +// { dg-error "" "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } + +// build-fail + +trait Mirror { + type It: ?Sized; +} +impl Mirror for T { + type It = Self; +} +struct S(Option<::It>); + +fn main() { +// { dg-note "" "" { target *-*-* } .-1 } + let _s = S(None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion/issue-38591-non-regular-dropck-recursion.rs b/gcc/testsuite/rust/rustc/ui/recursion/issue-38591-non-regular-dropck-recursion.rs new file mode 100644 index 000000000000..762c50fea4d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion/issue-38591-non-regular-dropck-recursion.rs @@ -0,0 +1,21 @@ +// Dropck shouldn't hit a recursion limit from checking `S` since it has +// no free regions or type parameters. +// Codegen however, has to error for the infinitely many `drop_in_place` +// functions it has been asked to create. + +// build-fail +// normalize-stderr-test: ".nll/" -> "/" +// compile-flags: -Zmir-opt-level=0 + +struct S { + t: T, + s: Box>, +} + +fn f(x: S) {} + +fn main() { + // Force instantiation. + f as fn(_); +} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion/recursion.rs b/gcc/testsuite/rust/rustc/ui/recursion/recursion.rs new file mode 100644 index 000000000000..61559fedec4d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion/recursion.rs @@ -0,0 +1,26 @@ +// build-fail +// compile-flags:-C overflow-checks=off +// normalize-stderr-test: ".nll/" -> "/" + +enum Nil {NilValue} +struct Cons {head:isize, tail:T} +trait Dot {fn dot(&self, other:Self) -> isize;} +impl Dot for Nil { + fn dot(&self, _:Nil) -> isize {0} +} +impl Dot for Cons { + fn dot(&self, other:Cons) -> isize { + self.head * other.head + self.tail.dot(other.tail) + } +} +fn test (n:isize, i:isize, first:T, second:T) ->isize { + match n { 0 => {first.dot(second)} + _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})} +// { dg-error "" "" { target *-*-* } .-1 } + } +} +pub fn main() { + let n = test(1, 0, Nil::NilValue, Nil::NilValue); + println!("{}", n); +} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion/recursive-enum.rs b/gcc/testsuite/rust/rustc/ui/recursion/recursive-enum.rs new file mode 100644 index 000000000000..2c901e54a965 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion/recursive-enum.rs @@ -0,0 +1,5 @@ +enum List { Cons(T, List), Nil } +// { dg-error ".E0072." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion/recursive-reexports.rs b/gcc/testsuite/rust/rustc/ui/recursion/recursive-reexports.rs new file mode 100644 index 000000000000..26772952ab5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion/recursive-reexports.rs @@ -0,0 +1,8 @@ +// aux-build:recursive_reexports.rs + +extern crate recursive_reexports; + +fn f() -> recursive_reexports::S {} // { dg-error ".E0412." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion/recursive-requirements.rs b/gcc/testsuite/rust/rustc/ui/recursion/recursive-requirements.rs new file mode 100644 index 000000000000..c3e9a1392b22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion/recursive-requirements.rs @@ -0,0 +1,20 @@ +use std::marker::PhantomData; + +struct AssertSync(PhantomData); + +pub struct Foo { + bar: *const Bar, + phantom: PhantomData, +} + +pub struct Bar { + foo: *const Foo, + phantom: PhantomData, +} + +fn main() { + let _: AssertSync = unimplemented!(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion/recursive-static-definition.rs b/gcc/testsuite/rust/rustc/ui/recursion/recursive-static-definition.rs new file mode 100644 index 000000000000..ea245847e2ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion/recursive-static-definition.rs @@ -0,0 +1,5 @@ +pub static FOO: u32 = FOO; +// { dg-error ".E0391." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion/recursive-types-are-not-uninhabited.rs b/gcc/testsuite/rust/rustc/ui/recursion/recursive-types-are-not-uninhabited.rs new file mode 100644 index 000000000000..98fb2157119e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion/recursive-types-are-not-uninhabited.rs @@ -0,0 +1,14 @@ +struct R<'a> { + r: &'a R<'a>, +} + +fn foo(res: Result) -> u32 { + let Ok(x) = res; +// { dg-error ".E0005." "" { target *-*-* } .-1 } + x +} + +fn main() { + foo(Ok(23)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion_limit/empty.rs b/gcc/testsuite/rust/rustc/ui/recursion_limit/empty.rs new file mode 100644 index 000000000000..b8f89d37b454 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion_limit/empty.rs @@ -0,0 +1,7 @@ +// Test the parse error for an empty recursion_limit + +#![recursion_limit = ""] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion_limit/invalid_digit.rs b/gcc/testsuite/rust/rustc/ui/recursion_limit/invalid_digit.rs new file mode 100644 index 000000000000..7f25d690dcc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion_limit/invalid_digit.rs @@ -0,0 +1,7 @@ +// Test the parse error for an invalid digit in recursion_limit + +#![recursion_limit = "-100"] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion_limit/overflow.rs b/gcc/testsuite/rust/rustc/ui/recursion_limit/overflow.rs new file mode 100644 index 000000000000..9e01284825b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion_limit/overflow.rs @@ -0,0 +1,8 @@ +// Test the parse error for an overflowing recursion_limit + +#![recursion_limit = "999999999999999999999999"] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/recursion_limit/zero.rs b/gcc/testsuite/rust/rustc/ui/recursion_limit/zero.rs new file mode 100644 index 000000000000..6f1614b7e4ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/recursion_limit/zero.rs @@ -0,0 +1,13 @@ +// Test that a `limit` of 0 is valid + +#![recursion_limit = "0"] + +macro_rules! test { + () => {}; + ($tt:tt) => { test!(); }; +} + +test!(test); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/reexport-should-still-link.rs b/gcc/testsuite/rust/rustc/ui/reexport-should-still-link.rs new file mode 100644 index 000000000000..e68884ae47eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reexport-should-still-link.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:reexport-should-still-link.rs + +// pretty-expanded FIXME #23616 + +extern crate reexport_should_still_link as foo; + +pub fn main() { + foo::bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/reexport-star.rs b/gcc/testsuite/rust/rustc/ui/reexport-star.rs new file mode 100644 index 000000000000..c2466d6ba89b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reexport-star.rs @@ -0,0 +1,17 @@ +// run-pass +// pretty-expanded FIXME #23616 + +mod a { + pub fn f() {} + pub fn g() {} +} + +mod b { + pub use a::*; +} + +pub fn main() { + b::f(); + b::g(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/reexport-test-harness-main.rs b/gcc/testsuite/rust/rustc/ui/reexport-test-harness-main.rs new file mode 100644 index 000000000000..bf44adc45639 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reexport-test-harness-main.rs @@ -0,0 +1,12 @@ +// run-pass +// compile-flags:--test + +#![reexport_test_harness_main = "test_main"] + +#[cfg(test)] +fn _unused() { + // should resolve to the entry point function the --test harness + // creates. + test_main(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/ref-suggestion.rs b/gcc/testsuite/rust/rustc/ui/ref-suggestion.rs new file mode 100644 index 000000000000..28c80007989f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ref-suggestion.rs @@ -0,0 +1,18 @@ +fn main() { + let x = vec![1]; + let y = x; + x; // { dg-error ".E0382." "" { target *-*-* } } + + let x = vec![1]; + let mut y = x; + x; // { dg-error ".E0382." "" { target *-*-* } } + + let x = (Some(vec![1]), ()); + + match x { + (Some(y), ()) => {}, + _ => {}, + } + x; // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/refer-to-other-statics-by-value.rs b/gcc/testsuite/rust/rustc/ui/refer-to-other-statics-by-value.rs new file mode 100644 index 000000000000..c93a28cb2f3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/refer-to-other-statics-by-value.rs @@ -0,0 +1,9 @@ +// run-pass + +static A: usize = 42; +static B: usize = A; + +fn main() { + assert_eq!(B, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions-fn-subtyping-return-static-fail.rs b/gcc/testsuite/rust/rustc/ui/regions-fn-subtyping-return-static-fail.rs new file mode 100644 index 000000000000..ec4ac3872426 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions-fn-subtyping-return-static-fail.rs @@ -0,0 +1,52 @@ +// In this fn, the type `F` is a function that takes a reference to a +// struct and returns another reference with the same lifetime. +// +// Meanwhile, the bare fn `foo` takes a reference to a struct with +// *ANY* lifetime and returns a reference with the 'static lifetime. +// This can safely be considered to be an instance of `F` because all +// lifetimes are sublifetimes of 'static. + +#![allow(dead_code)] +#![allow(unused_variables)] + +struct S; + +// Given 'cx, return 'cx +type F = for<'cx> fn(&'cx S) -> &'cx S; +fn want_F(f: F) {} + +// Given anything, return 'static +type G = for<'cx> fn(&'cx S) -> &'static S; +fn want_G(f: G) {} + +// Should meet both. +fn foo(x: &S) -> &'static S { + panic!() +} + +// Should meet both. +fn bar<'a, 'b>(x: &'a S) -> &'b S { + panic!() +} + +// Meets F, but not G. +fn baz(x: &S) -> &S { + panic!() +} + +fn supply_F() { + want_F(foo); + + want_F(bar); + + want_F(baz); +} + +fn supply_G() { + want_G(foo); + want_G(bar); + want_G(baz); // { dg-error ".E0308." "" { target *-*-* } } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/auxiliary/rbmtp_cross_crate_lib.rs b/gcc/testsuite/rust/rustc/ui/regions/auxiliary/rbmtp_cross_crate_lib.rs new file mode 100644 index 000000000000..edb145fb7de4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/auxiliary/rbmtp_cross_crate_lib.rs @@ -0,0 +1,33 @@ +// Check that method bounds declared on traits/impls in a cross-crate +// scenario work. This is the library portion of the test. + +pub enum MaybeOwned<'a> { + Owned(isize), + Borrowed(&'a isize) +} + +pub struct Inv<'a> { // invariant w/r/t 'a + x: &'a mut &'a isize +} + +// I encountered a bug at some point with encoding the IntoMaybeOwned +// trait, so I'll use that as the template for this test. +pub trait IntoMaybeOwned<'a> { + fn into_maybe_owned(self) -> MaybeOwned<'a>; + + // Note: without this `into_inv` method, the trait is + // contravariant w/r/t `'a`, since if you look strictly at the + // interface, it only returns `'a`. This complicates the + // downstream test since it wants invariance to force an error. + // Hence we add this method. + fn into_inv(self) -> Inv<'a>; + + fn bigger_region<'b:'a>(self, b: Inv<'b>); +} + +impl<'a> IntoMaybeOwned<'a> for Inv<'a> { + fn into_maybe_owned(self) -> MaybeOwned<'a> { panic!() } + fn into_inv(self) -> Inv<'a> { panic!() } + fn bigger_region<'b:'a>(self, b: Inv<'b>) { panic!() } +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/issue-56537-closure-uses-region-from-container.rs b/gcc/testsuite/rust/rustc/ui/regions/issue-56537-closure-uses-region-from-container.rs new file mode 100644 index 000000000000..2c8df4782980 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/issue-56537-closure-uses-region-from-container.rs @@ -0,0 +1,68 @@ +// This is a collection of examples where a function's formal +// parameter has an explicit lifetime and a closure within that +// function returns that formal parameter. The closure's return type, +// to be correctly inferred, needs to include the lifetime introduced +// by the function. +// +// This works today, which precludes changing things so that closures +// follow the same lifetime-elision rules used elsehwere. See +// rust-lang/rust#56537 + +// check-pass + +fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str { + let free_dumb = |_x| { p }; // no type annotation at all + let hello = format!("Hello"); + free_dumb(&hello) +} + +fn willy_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str { + let free_dumb = |_x| -> &str { p }; // type annotation on the return type + let hello = format!("Hello"); + free_dumb(&hello) +} + +fn willy_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str { + let free_dumb = |_x| -> &'w str { p }; // type+region annotation on return type + let hello = format!("Hello"); + free_dumb(&hello) +} + +fn willy_arg_type_ret_type_annot<'w>(p: &'w str, q: &str) -> &'w str { + let free_dumb = |_x: &str| -> &str { p }; // type annotation on arg and return types + let hello = format!("Hello"); + free_dumb(&hello) +} + +fn willy_arg_type_ret_region_annot<'w>(p: &'w str, q: &str) -> &'w str { + let free_dumb = |_x: &str| -> &'w str { p }; // fully annotated + let hello = format!("Hello"); + free_dumb(&hello) +} + +fn main() { + let world = format!("World"); + let w1: &str = { + let hello = format!("He11o"); + willy_no_annot(&world, &hello) + }; + let w2: &str = { + let hello = format!("He22o"); + willy_ret_type_annot(&world, &hello) + }; + let w3: &str = { + let hello = format!("He33o"); + willy_ret_region_annot(&world, &hello) + }; + let w4: &str = { + let hello = format!("He44o"); + willy_arg_type_ret_type_annot(&world, &hello) + }; + let w5: &str = { + let hello = format!("He55o"); + willy_arg_type_ret_region_annot(&world, &hello) + }; + assert_eq!((w1, w2, w3, w4, w5), + ("World","World","World","World","World")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/issue-72051-member-region-hang.rs b/gcc/testsuite/rust/rustc/ui/regions/issue-72051-member-region-hang.rs new file mode 100644 index 000000000000..41c6a9a2aea0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/issue-72051-member-region-hang.rs @@ -0,0 +1,8 @@ +// Regression test for #72051, hang when resolving regions. + +// check-pass +// edition:2018 + +pub async fn query<'a>(_: &(), _: &(), _: (&(dyn std::any::Any + 'a),) ) {} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/issue-78262.rs b/gcc/testsuite/rust/rustc/ui/regions/issue-78262.rs new file mode 100644 index 000000000000..639f22ae41f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/issue-78262.rs @@ -0,0 +1,15 @@ +// revisions: nll default +// ignore-compare-mode-nll +//[nll]compile-flags: -Z borrowck=mir + +trait TT {} + +impl dyn TT { + fn func(&self) {} +} + +fn main() { + let f = |x: &dyn TT| x.func(); // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-borrow-params-issue-29793-big.rs b/gcc/testsuite/rust/rustc/ui/regions/region-borrow-params-issue-29793-big.rs new file mode 100644 index 000000000000..4f4fb2699c84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-borrow-params-issue-29793-big.rs @@ -0,0 +1,75 @@ +// Issue #29793, big regression test: do not let borrows of +// parameters to ever be returned (expanded with exploration of +// variations). +// +// This is the version of the test that actually exposed unsound +// behavior (because the improperly accepted closure was actually +// able to be invoked). + +struct WrapA(Option); + +impl WrapA { + fn new() -> WrapA { + WrapA(None) + } + fn set(mut self, f: F) -> Self { + self.0 = Some(f); + self + } +} + +struct WrapB(Option); + +impl WrapB { + fn new() -> WrapB { + WrapB(None) + } + fn set(mut self, f: F) -> Self { + self.0 = Some(f); + self + } +} + +trait DoStuff : Sized { + fn handle(self); +} + +impl DoStuff for WrapA + where F: FnMut(usize, usize) -> T, T: DoStuff { + fn handle(mut self) { + if let Some(ref mut f) = self.0 { + let x = f(1, 2); + let _foo = [0usize; 16]; + x.handle(); + } + } + } + +impl DoStuff for WrapB where F: FnMut(bool) -> usize { + fn handle(mut self) { + if let Some(ref mut f) = self.0 { + println!("{}", f(true)); + } + } +} + +impl WrapA + where F: FnMut(usize, usize) -> T, T: DoStuff { + fn handle_ref(&mut self) { + if let Some(ref mut f) = self.0 { + let x = f(1, 2); + } + } + } + +fn main() { + let mut w = WrapA::new().set(|x: usize, y: usize| { + WrapB::new().set(|t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +// { dg-error ".E0373." "" { target *-*-* } .-2 } + }); + + w.handle(); // This works + // w.handle_ref(); // This doesn't +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-borrow-params-issue-29793-small.rs b/gcc/testsuite/rust/rustc/ui/regions/region-borrow-params-issue-29793-small.rs new file mode 100644 index 000000000000..76cadfa83316 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-borrow-params-issue-29793-small.rs @@ -0,0 +1,213 @@ +// Issue #29793, small regression tests: do not let borrows of +// parameters to ever be returned (expanded with exploration of +// variations). + +// CLOSURES + +fn escaping_borrow_of_closure_params_1() { + let g = |x: usize, y:usize| { + let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +// { dg-error ".E0373." "" { target *-*-* } .-2 } + return f; + }; + + // We delberately do not call `g`; this small version of the test, + // after adding such a call, was (properly) rejected even when the + // system still suffered from issue #29793. + + // g(10, 20)(true); +} + +fn escaping_borrow_of_closure_params_2() { + let g = |x: usize, y:usize| { + let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +// { dg-error ".E0373." "" { target *-*-* } .-2 } + f + }; + + // (we don't call `g`; see above) +} + +fn move_of_closure_params() { + let g = |x: usize, y:usize| { + let f = move |t: bool| if t { x } else { y }; + f; + }; + // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) + (g(1,2)); +} + +fn ok_borrow_of_fn_params(a: usize, b:usize) { + let g = |x: usize, y:usize| { + let f = |t: bool| if t { a } else { b }; + return f; + }; + // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) + (g(1,2))(true); +} + +// TOP-LEVEL FN'S + +fn escaping_borrow_of_fn_params_1() { + fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { + let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +// { dg-error ".E0373." "" { target *-*-* } .-2 } + return Box::new(f); + }; + + // (we don't call `g`; see above) +} + +fn escaping_borrow_of_fn_params_2() { + fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { + let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +// { dg-error ".E0373." "" { target *-*-* } .-2 } + Box::new(f) + }; + + // (we don't call `g`; see above) +} + +fn move_of_fn_params() { + fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { + let f = move |t: bool| if t { x } else { y }; + return Box::new(f); + }; + // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) + (g(1,2))(true); +} + +// INHERENT METHODS + +fn escaping_borrow_of_method_params_1() { + struct S; + impl S { + fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { + let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +// { dg-error ".E0373." "" { target *-*-* } .-2 } + return Box::new(f); + } + } + + // (we don't call `g`; see above) +} + +fn escaping_borrow_of_method_params_2() { + struct S; + impl S { + fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { + let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +// { dg-error ".E0373." "" { target *-*-* } .-2 } + Box::new(f) + } + } + // (we don't call `g`; see above) +} + +fn move_of_method_params() { + struct S; + impl S { + fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { + let f = move |t: bool| if t { x } else { y }; + return Box::new(f); + } + } + // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) + (S.g(1,2))(true); +} + +// TRAIT IMPL METHODS + +fn escaping_borrow_of_trait_impl_params_1() { + trait T { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a>; } + struct S; + impl T for S { + fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { + let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +// { dg-error ".E0373." "" { target *-*-* } .-2 } + return Box::new(f); + } + } + + // (we don't call `g`; see above) +} + +fn escaping_borrow_of_trait_impl_params_2() { + trait T { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a>; } + struct S; + impl T for S { + fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { + let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +// { dg-error ".E0373." "" { target *-*-* } .-2 } + Box::new(f) + } + } + // (we don't call `g`; see above) +} + +fn move_of_trait_impl_params() { + trait T { fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a>; } + struct S; + impl T for S { + fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { + let f = move |t: bool| if t { x } else { y }; + return Box::new(f); + } + } + // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) + (S.g(1,2))(true); +} + +// TRAIT DEFAULT METHODS + +fn escaping_borrow_of_trait_default_params_1() { + struct S; + trait T { + fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { + let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +// { dg-error ".E0373." "" { target *-*-* } .-2 } + return Box::new(f); + } + } + impl T for S {} + // (we don't call `g`; see above) +} + +fn escaping_borrow_of_trait_default_params_2() { + struct S; + trait T { + fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { + let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) +// { dg-error ".E0373." "" { target *-*-* } .-1 } +// { dg-error ".E0373." "" { target *-*-* } .-2 } + Box::new(f) + } + } + impl T for S {} + // (we don't call `g`; see above) +} + +fn move_of_trait_default_params() { + struct S; + trait T { + fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { + let f = move |t: bool| if t { x } else { y }; + return Box::new(f); + } + } + impl T for S {} + // (this code is fine, so lets go ahead and ensure rustc accepts call of `g`) + (S.g(1,2))(true); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-bound-extra-bound-in-inherent-impl.rs b/gcc/testsuite/rust/rustc/ui/regions/region-bound-extra-bound-in-inherent-impl.rs new file mode 100644 index 000000000000..6391d5e13221 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-bound-extra-bound-in-inherent-impl.rs @@ -0,0 +1,17 @@ +// Test related to #22779. In this case, the impl is an inherent impl, +// so it doesn't have to match any trait, so no error results. + +// check-pass +#![allow(dead_code)] + +struct MySlice<'a, T:'a>(&'a mut [T]); + +impl<'a, T> MySlice<'a, T> { + fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b { + &mut self.0[..] + } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-bound-on-closure-outlives-call.rs b/gcc/testsuite/rust/rustc/ui/regions/region-bound-on-closure-outlives-call.rs new file mode 100644 index 000000000000..e8101be90558 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-bound-on-closure-outlives-call.rs @@ -0,0 +1,7 @@ +fn call_rec(mut f: F) -> usize where F: FnMut(usize) -> usize { +// { dg-warning "" "" { target *-*-* } .-1 } + (|x| f(x))(call_rec(f)) // { dg-error ".E0505." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs b/gcc/testsuite/rust/rustc/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs new file mode 100644 index 000000000000..5a742cb1c620 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-bound-same-bounds-in-trait-and-impl.rs @@ -0,0 +1,18 @@ +// Test related to #22779, but where the `'a:'b` relation +// appears in the trait too. No error here. + +// check-pass + +trait Tr<'a, T> { + fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b; +} + +impl<'a, T> Tr<'a, T> for &'a mut [T] { + fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b { + &mut self[..] + } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-bounds-on-objects-and-type-parameters.rs b/gcc/testsuite/rust/rustc/ui/regions/region-bounds-on-objects-and-type-parameters.rs new file mode 100644 index 000000000000..903096b38105 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-bounds-on-objects-and-type-parameters.rs @@ -0,0 +1,37 @@ +// Test related to when a region bound is required to be specified. + +trait IsStatic : 'static { } +trait IsSend : Send { } +trait Is<'a> : 'a { } +trait Is2<'a> : 'a { } +trait SomeTrait { } + +// Bounds on object types: + +struct Foo<'a,'b,'c> { // { dg-error ".E0392." "" { target *-*-* } } + // All of these are ok, because we can derive exactly one bound: + a: Box, + b: Box>, + c: Box>, + d: Box, + e: Box+Send>, // we can derive two bounds, but one is 'static, so ok + f: Box, // OK, defaults to 'static due to RFC 599. + g: Box, + + z: Box+'b+'c>, +// { dg-error ".E0478." "" { target *-*-* } .-1 } +// { dg-error ".E0478." "" { target *-*-* } .-2 } +} + +fn test< + 'a, + 'b, + A:IsStatic, + B:Is<'a>+Is2<'b>, // OK in a parameter, but not an object type. + C:'b+Is<'a>+Is2<'b>, + D:Is<'a>+Is2<'static>, + E:'a+'b // OK in a parameter, but not an object type. +>() { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-invariant-static-error-reporting.rs b/gcc/testsuite/rust/rustc/ui/regions/region-invariant-static-error-reporting.rs new file mode 100644 index 000000000000..70cc97cad97a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-invariant-static-error-reporting.rs @@ -0,0 +1,23 @@ +// This test checks that the error messages you get for this example +// at least mention `'a` and `'static`. The precise messages can drift +// over time, but this test used to exhibit some pretty bogus messages +// that were not remotely helpful. + +// error-pattern:the lifetime `'a` +// error-pattern:the static lifetime + +struct Invariant<'a>(Option<&'a mut &'a mut ()>); + +fn mk_static() -> Invariant<'static> { Invariant(None) } + +fn unify<'a>(x: Option>, f: fn(Invariant<'a>)) { + let bad = if x.is_some() { + x.unwrap() + } else { + mk_static() + }; + f(bad); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs b/gcc/testsuite/rust/rustc/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs new file mode 100644 index 000000000000..0066706e827a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs @@ -0,0 +1,30 @@ +fn a<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) where 'b: 'a { + // Note: this is legal because of the `'b:'a` declaration. + *x = *y; +} + +fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { + // Illegal now because there is no `'b:'a` declaration. + *x = *y; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { + // Here we try to call `foo` but do not know that `'a` and `'b` are + // related as required. + a(x, y); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn d() { + // 'a and 'b are early bound in the function `a` because they appear + // inconstraints: + let _: fn(&mut &isize, &mut &isize) = a; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn e() { + // 'a and 'b are late bound in the function `b` because there are + // no constraints: + let _: fn(&mut &isize, &mut &isize) = b; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs b/gcc/testsuite/rust/rustc/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs new file mode 100644 index 000000000000..21ea5ae26f06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs @@ -0,0 +1,32 @@ +fn a<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) where 'b: 'a + 'c { + // Note: this is legal because of the `'b:'a` declaration. + *x = *y; + *z = *y; +} + +fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { + // Illegal now because there is no `'b:'a` declaration. + *x = *y; // { dg-error ".E0623." "" { target *-*-* } } + *z = *y; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { + // Here we try to call `foo` but do not know that `'a` and `'b` are + // related as required. + a(x, y, z); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn d() { + // 'a and 'b are early bound in the function `a` because they appear + // inconstraints: + let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn e() { + // 'a and 'b are late bound in the function `b` because there are + // no constraints: + let _: fn(&mut &isize, &mut &isize, &mut &isize) = b; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-1.rs b/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-1.rs new file mode 100644 index 000000000000..dfc21907b1b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-1.rs @@ -0,0 +1,19 @@ +// Various tests related to testing how region inference works +// with respect to the object receivers. + +// check-pass +#![allow(warnings)] + +trait Foo { + fn borrowed<'a>(&'a self) -> &'a (); +} + +// Here the receiver and return value all have the same lifetime, +// so no error results. +fn borrowed_receiver_same_lifetime<'a>(x: &'a Foo) -> &'a () { + x.borrowed() +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-2.rs b/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-2.rs new file mode 100644 index 000000000000..7cc1c3fc0c2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-2.rs @@ -0,0 +1,14 @@ +// Various tests related to testing how region inference works +// with respect to the object receivers. + +trait Foo { + fn borrowed<'a>(&'a self) -> &'a (); +} + +// Borrowed receiver but two distinct lifetimes, we get an error. +fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () { + x.borrowed() // { dg-error ".E0495." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-3.rs b/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-3.rs new file mode 100644 index 000000000000..cfedfa1f1d0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-3.rs @@ -0,0 +1,19 @@ +// Various tests related to testing how region inference works +// with respect to the object receivers. + +// check-pass +#![allow(warnings)] + +trait Foo { + fn borrowed<'a>(&'a self) -> &'a (); +} + +// Borrowed receiver with two distinct lifetimes, but we know that +// 'b:'a, hence &'a () is permitted. +fn borrowed_receiver_related_lifetimes<'a,'b>(x: &'a (Foo+'b)) -> &'a () { + x.borrowed() +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-4.rs b/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-4.rs new file mode 100644 index 000000000000..e8b92a53f2eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-4.rs @@ -0,0 +1,16 @@ +// Various tests related to testing how region inference works +// with respect to the object receivers. + +trait Foo { + fn borrowed<'a>(&'a self) -> &'a (); +} + +// Here we have two distinct lifetimes, but we try to return a pointer +// with the longer lifetime when (from the signature) we only know +// that it lives as long as the shorter lifetime. Therefore, error. +fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () { + x.borrowed() // { dg-error ".E0495." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-5.rs b/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-5.rs new file mode 100644 index 000000000000..3c03314631ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-5.rs @@ -0,0 +1,15 @@ +// Various tests related to testing how region inference works +// with respect to the object receivers. + +trait Foo { + fn borrowed<'a>(&'a self) -> &'a (); +} + +// Here, the object is bounded by an anonymous lifetime and returned +// as `&'static`, so you get an error. +fn owned_receiver(x: Box) -> &'static () { + x.borrowed() // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-in-coercion.rs b/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-in-coercion.rs new file mode 100644 index 000000000000..5df516aca86a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/region-object-lifetime-in-coercion.rs @@ -0,0 +1,31 @@ +// Test that attempts to implicitly coerce a value into an +// object respect the lifetime bound on the object type. + +trait Foo {} +impl<'a> Foo for &'a [u8] {} + +fn a(v: &[u8]) -> Box { + let x: Box = Box::new(v); // { dg-error ".E0759." "" { target *-*-* } } + x +} + +fn b(v: &[u8]) -> Box { + Box::new(v) // { dg-error ".E0759." "" { target *-*-* } } +} + +fn c(v: &[u8]) -> Box { + // same as previous case due to RFC 599 + + Box::new(v) // { dg-error ".E0759." "" { target *-*-* } } +} + +fn d<'a,'b>(v: &'a [u8]) -> Box { + Box::new(v) // { dg-error ".E0495." "" { target *-*-* } } +} + +fn e<'a:'b,'b>(v: &'a [u8]) -> Box { + Box::new(v) // OK, thanks to 'a:'b +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-arg.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-arg.rs new file mode 100644 index 000000000000..bec5293cc2ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-arg.rs @@ -0,0 +1,18 @@ +// Check that taking the address of an argument yields a lifetime +// bounded by the current function call. + +fn foo(a: isize) { + let _p: &'static isize = &a; // { dg-error ".E0597." "" { target *-*-* } } +} + +fn bar(a: isize) { + let _q: &isize = &a; +} + +fn zed<'a>(a: isize) -> &'a isize { + &a // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-interior-of-unique-box.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-interior-of-unique-box.rs new file mode 100644 index 000000000000..b4150037c9a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-interior-of-unique-box.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] + +// pretty-expanded FIXME #23616 + +struct Point { + x: isize, + y: isize +} + +struct Character { + pos: Box, +} + +fn get_x(x: &Character) -> &isize { + // interesting case because the scope of this + // borrow of the unique pointer is in fact + // larger than the fn itself + return &x.pos.x; +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-ret.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-ret.rs new file mode 100644 index 000000000000..9b8c53b0115f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-ret.rs @@ -0,0 +1,10 @@ +// run-pass +fn f(x: &isize) -> &isize { + return &*x; +} + +pub fn main() { + let three = &3; + println!("{}", *f(three)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-self.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-self.rs new file mode 100644 index 000000000000..685c3773e3f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-self.rs @@ -0,0 +1,28 @@ +struct Dog { + cats_chased: usize, +} + +impl Dog { + pub fn chase_cat(&mut self) { + let p: &'static mut usize = &mut self.cats_chased; // { dg-error ".E0759." "" { target *-*-* } } + *p += 1; + } + + pub fn chase_cat_2(&mut self) { + let p: &mut usize = &mut self.cats_chased; + *p += 1; + } +} + +fn dog() -> Dog { + Dog { + cats_chased: 0 + } +} + +fn main() { + let mut d = dog(); + d.chase_cat(); + println!("cats_chased: {}", d.cats_chased); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-upvar-self.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-upvar-self.rs new file mode 100644 index 000000000000..d60075af1d37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-addr-of-upvar-self.rs @@ -0,0 +1,18 @@ +use std::usize; + +struct Dog { + food: usize, +} + +impl Dog { + pub fn chase_cat(&mut self) { + let _f = || { + let p: &'static mut usize = &mut self.food; // { dg-error ".E0495." "" { target *-*-* } } + *p = 3; + }; + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-adjusted-lvalue-op.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-adjusted-lvalue-op.rs new file mode 100644 index 000000000000..6582abae8c35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-adjusted-lvalue-op.rs @@ -0,0 +1,17 @@ +// check that we link regions in mutable place ops correctly - issue #41774 + +struct Data(i32); + +trait OhNo { + fn oh_no(&mut self, other: &Vec) { loop {} } +} + +impl OhNo for Data {} +impl OhNo for [Data] {} + +fn main() { + let mut v = vec![Data(0)]; + v[0].oh_no(&v); // { dg-error ".E0502." "" { target *-*-* } } + (*v).oh_no(&v); // { dg-error ".E0502." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs new file mode 100644 index 000000000000..76773abb42c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs @@ -0,0 +1,46 @@ +// Test that we are imposing the requirement that every associated +// type of a bound that appears in the where clause on a struct must +// outlive the location in which the type appears, even when the +// associted type is in a supertype. Issue #22246. + +// revisions: migrate nll +//[nll]compile-flags: -Z borrowck=mir + +#![allow(dead_code)] + +pub trait TheTrait { + type TheAssocType; +} + +pub trait TheSubTrait : TheTrait { +} + +pub struct TheType<'b> { + m: [fn(&'b()); 0] +} + +impl<'b> TheTrait for TheType<'b> { + type TheAssocType = &'b (); +} + +impl<'b> TheSubTrait for TheType<'b> { +} + +pub struct WithAssoc { + m: [T; 0] +} + +fn with_assoc<'a,'b>() { + // For this type to be valid, the rules require that all + // associated types of traits that appear in `WithAssoc` must + // outlive 'a. In this case, that means TheType<'b>::TheAssocType, + // which is &'b (), must outlive 'a. + + let _: &'a WithAssoc> = loop { }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.rs new file mode 100644 index 000000000000..b3c70a67dca1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.rs @@ -0,0 +1,25 @@ +// Test that the compiler checks that arbitrary region bounds declared +// in the trait must be satisfied on the impl. Issue #20890. + +trait Foo<'a> { + type Value: 'a; + fn dummy(&'a self) {} +} + +impl<'a> Foo<'a> for &'a i16 { + // OK. + type Value = &'a i32; +} + +impl<'a> Foo<'static> for &'a i32 { + type Value = &'a i32; +// { dg-error ".E0477." "" { target *-*-* } .-1 } +} + +impl<'a, 'b> Foo<'b> for &'a i64 { + type Value = &'a i32; +// { dg-error ".E0477." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-region-bound.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-region-bound.rs new file mode 100644 index 000000000000..14e10717f18f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-region-bound.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(dead_code)] +// Test that the compiler considers the 'a bound declared in the +// trait. Issue #20890. + +// pretty-expanded FIXME #23616 + +trait Foo<'a> { + type Value: 'a; + + fn get(&self) -> &'a Self::Value; +} + +fn takes_foo<'a,F: Foo<'a>>(f: &'a F) { + // This call would be illegal, because it results in &'a F::Value, + // and the only way we know that `F::Value : 'a` is because of the + // trait declaration. + + f.get(); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.rs new file mode 100644 index 000000000000..a05ab1a07a84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.rs @@ -0,0 +1,20 @@ +// Test that the compiler checks that the 'static bound declared in +// the trait must be satisfied on the impl. Issue #20890. + +trait Foo { + type Value: 'static; + fn dummy(&self) {} +} + +impl<'a> Foo for &'a i32 { + type Value = &'a i32; +// { dg-error ".E0477." "" { target *-*-* } .-1 } +} + +impl<'a> Foo for i32 { + // OK. + type Value = i32; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-static-bound.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-static-bound.rs new file mode 100644 index 000000000000..9aa6813446d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-assoc-type-static-bound.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +// Test that the compiler considers the 'static bound declared in the +// trait. Issue #20890. + +// pretty-expanded FIXME #23616 + +trait Foo { + type Value: 'static; + fn dummy(&self) { } +} + +fn require_static() {} + +fn takes_foo() { + require_static::() +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-borrow-at.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-borrow-at.rs new file mode 100644 index 000000000000..245a68f7be76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-borrow-at.rs @@ -0,0 +1,14 @@ +// run-pass +#![feature(box_syntax)] + +fn foo(x: &usize) -> usize { + *x +} + +pub fn main() { + let p: Box<_> = box 22; + let r = foo(&*p); + println!("r={}", r); + assert_eq!(r, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-borrow-evec-fixed.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-borrow-evec-fixed.rs new file mode 100644 index 000000000000..5f2ae11e1315 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-borrow-evec-fixed.rs @@ -0,0 +1,11 @@ +// run-pass + +fn foo(x: &[isize]) -> isize { + x[0] +} + +pub fn main() { + let p = &[1,2,3,4,5]; + assert_eq!(foo(p), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-borrow-evec-uniq.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-borrow-evec-uniq.rs new file mode 100644 index 000000000000..a81475b919f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-borrow-evec-uniq.rs @@ -0,0 +1,17 @@ +// run-pass + + +fn foo(x: &[isize]) -> isize { + x[0] +} + +pub fn main() { + let p = vec![1,2,3,4,5]; + let r = foo(&p); + assert_eq!(r, 1); + + let p = vec![5,4,3,2,1]; + let r = foo(&p); + assert_eq!(r, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-borrow-uniq.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-borrow-uniq.rs new file mode 100644 index 000000000000..c61c02281af8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-borrow-uniq.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(box_syntax)] + +fn foo(x: &usize) -> usize { + *x +} + +pub fn main() { + let p: Box<_> = box 3; + let r = foo(&*p); + assert_eq!(r, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-bot.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-bot.rs new file mode 100644 index 000000000000..9dc81f4ee1e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-bot.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +// A very limited test of the "bottom" region + + +fn produce_static() -> &'static T { panic!(); } + +fn foo(_x: &T) -> &usize { produce_static() } + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-bound-lists-feature-gate-2.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-bound-lists-feature-gate-2.rs new file mode 100644 index 000000000000..13587cf6e680 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-bound-lists-feature-gate-2.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +#![allow(stable_features)] + +#![feature(issue_5723_bootstrap)] + +trait Foo { + fn dummy(&self) { } +} + +fn foo<'a, 'b, 'c:'a+'b, 'd>() { +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-bound-lists-feature-gate.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-bound-lists-feature-gate.rs new file mode 100644 index 000000000000..17179a0d90bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-bound-lists-feature-gate.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(stable_features)] + +#![feature(issue_5723_bootstrap)] + +trait Foo { + fn dummy(&self) { } +} + +fn foo<'a>(x: Box) { +} + +fn bar<'a, T: 'a>() { +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-bounded-by-trait-requiring-static.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-bounded-by-trait-requiring-static.rs new file mode 100644 index 000000000000..e4fef9357a61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-bounded-by-trait-requiring-static.rs @@ -0,0 +1,64 @@ +// Test which of the builtin types are considered sendable. The tests +// in this file all test region bound and lifetime violations that are +// detected during type check. + +trait Dummy : 'static { } +fn assert_send() { } + +// lifetime pointers with 'static lifetime are ok + +fn static_lifime_ok<'a,T,U:Send>(_: &'a isize) { + assert_send::<&'static isize>(); + assert_send::<&'static str>(); + assert_send::<&'static [isize]>(); + + // whether or not they are mutable + assert_send::<&'static mut isize>(); +} + +// otherwise lifetime pointers are not ok + +fn param_not_ok<'a>(x: &'a isize) { + assert_send::<&'a isize>(); // { dg-error ".E0477." "" { target *-*-* } } +} + +fn param_not_ok1<'a>(_: &'a isize) { + assert_send::<&'a str>(); // { dg-error ".E0477." "" { target *-*-* } } +} + +fn param_not_ok2<'a>(_: &'a isize) { + assert_send::<&'a [isize]>(); // { dg-error ".E0477." "" { target *-*-* } } +} + +// boxes are ok + +fn box_ok() { + assert_send::>(); + assert_send::(); + assert_send::>(); +} + +// but not if they own a bad thing + +fn box_with_region_not_ok<'a>() { + assert_send::>(); // { dg-error ".E0477." "" { target *-*-* } } +} + +// raw pointers are ok unless they point at unsendable things + +fn unsafe_ok1<'a>(_: &'a isize) { + assert_send::<*const isize>(); + assert_send::<*mut isize>(); +} + +fn unsafe_ok2<'a>(_: &'a isize) { + assert_send::<*const &'a isize>(); // { dg-error ".E0477." "" { target *-*-* } } +} + +fn unsafe_ok3<'a>(_: &'a isize) { + assert_send::<*mut &'a isize>(); // { dg-error ".E0477." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-bounded-method-type-parameters-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-bounded-method-type-parameters-cross-crate.rs new file mode 100644 index 000000000000..b86391ab3a48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-bounded-method-type-parameters-cross-crate.rs @@ -0,0 +1,24 @@ +// aux-build:rbmtp_cross_crate_lib.rs + +// Check explicit region bounds on methods in the cross crate case. + +extern crate rbmtp_cross_crate_lib as lib; + +use lib::Inv; +use lib::MaybeOwned; +use lib::IntoMaybeOwned; + +fn call_into_maybe_owned<'x,F:IntoMaybeOwned<'x>>(f: F) { + // Exercise a code path I found to be buggy. We were not encoding + // the region parameters from the receiver correctly on trait + // methods. + f.into_maybe_owned(); +} + +fn call_bigger_region<'x, 'y>(a: Inv<'x>, b: Inv<'y>) { + // Here the value provided for 'y is 'y, and hence 'y:'x does not hold. + a.bigger_region(b) // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-bounded-method-type-parameters-trait-bound.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-bounded-method-type-parameters-trait-bound.rs new file mode 100644 index 000000000000..9723931e36ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-bounded-method-type-parameters-trait-bound.rs @@ -0,0 +1,29 @@ +// Check that explicit region bounds are allowed on the various +// nominal types (but not on other types) and that they are type +// checked. + +struct Inv<'a> { // invariant w/r/t 'a + x: &'a mut &'a isize +} + +trait Foo<'x> { + fn method<'y:'x>(self, y: Inv<'y>); +} + +fn caller1<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) { + // Here the value provided for 'y is 'a, and hence 'a:'a holds. + f.method(a); +} + +fn caller2<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) { + // Here the value provided for 'y is 'b, and hence 'b:'a does not hold. + f.method(b); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn caller3<'a,'b:'a,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) { + // Here the value provided for 'y is 'b, and hence 'b:'a holds. + f.method(b); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-bounded-method-type-parameters.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-bounded-method-type-parameters.rs new file mode 100644 index 000000000000..9dff1724f0c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-bounded-method-type-parameters.rs @@ -0,0 +1,17 @@ +// Check that explicit region bounds are allowed on the various +// nominal types (but not on other types) and that they are type +// checked. + +struct Foo; + +impl Foo { + fn some_method(self) { } +} + +fn caller<'a>(x: &isize) { + Foo.some_method::<&'a isize>(); +// { dg-error ".E0477." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-bounds.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-bounds.rs new file mode 100644 index 000000000000..42450767225e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-bounds.rs @@ -0,0 +1,17 @@ +// Check that explicit region bounds are allowed on the various +// nominal types (but not on other types) and that they are type +// checked. + +struct TupleStruct<'a>(&'a isize); +struct Struct<'a> { x:&'a isize } + +fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> { + return e; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> { + return e; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-close-associated-type-into-object.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-close-associated-type-into-object.rs new file mode 100644 index 000000000000..d54552cfe06d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-close-associated-type-into-object.rs @@ -0,0 +1,72 @@ +#![feature(box_syntax)] + +trait X {} + +trait Iter { + type Item: X; + + fn into_item(self) -> Self::Item; + fn as_item(&self) -> &Self::Item; +} + +fn bad1(v: T) -> Box +{ + let item = v.into_item(); + Box::new(item) // { dg-error ".E0310." "" { target *-*-* } } +} + +fn bad2(v: T) -> Box + where Box : X +{ + let item: Box<_> = box v.into_item(); + Box::new(item) // { dg-error ".E0310." "" { target *-*-* } } +} + +fn bad3<'a, T: Iter>(v: T) -> Box +{ + let item = v.into_item(); + Box::new(item) // { dg-error ".E0309." "" { target *-*-* } } +} + +fn bad4<'a, T: Iter>(v: T) -> Box + where Box : X +{ + let item: Box<_> = box v.into_item(); + Box::new(item) // { dg-error ".E0309." "" { target *-*-* } } +} + +fn ok1<'a, T: Iter>(v: T) -> Box + where T::Item : 'a +{ + let item = v.into_item(); + Box::new(item) // OK, T::Item : 'a is declared +} + +fn ok2<'a, T: Iter>(v: &T, w: &'a T::Item) -> Box + where T::Item : Clone +{ + let item = Clone::clone(w); + Box::new(item) // OK, T::Item : 'a is implied +} + +fn ok3<'a, T: Iter>(v: &'a T) -> Box + where T::Item : Clone + 'a +{ + let item = Clone::clone(v.as_item()); + Box::new(item) // OK, T::Item : 'a was declared +} + +fn meh1<'a, T: Iter>(v: &'a T) -> Box + where T::Item : Clone +{ + // This case is kind of interesting. It's the same as `ok3` but + // without the explicit declaration. This is valid because `T: 'a + // => T::Item: 'a`, and the former we can deduce from our argument + // of type `&'a T`. + + let item = Clone::clone(v.as_item()); + Box::new(item) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-1.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-1.rs new file mode 100644 index 000000000000..444fd1b3f856 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-1.rs @@ -0,0 +1,16 @@ +#![feature(box_syntax)] +#![allow(warnings)] + +trait A { } +struct B<'a, T:'a>(&'a (A+'a)); + +trait X { } + +impl<'a, T> X for B<'a, T> {} + +fn f<'a, T:'static, U>(v: Box+'static>) -> Box { + box B(&*v) as Box // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-2.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-2.rs new file mode 100644 index 000000000000..7c1bfde2336f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-2.rs @@ -0,0 +1,14 @@ +#![feature(box_syntax)] + +trait A { } +struct B<'a, T:'a>(&'a (dyn A + 'a)); + +trait X { } +impl<'a, T> X for B<'a, T> {} + +fn g<'a, T: 'static>(v: Box + 'a>) -> Box { + box B(&*v) as Box // { dg-error ".E0759." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-3.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-3.rs new file mode 100644 index 000000000000..88debc0ed0a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-3.rs @@ -0,0 +1,15 @@ +#![feature(box_syntax)] +#![allow(warnings)] + +trait A { } +struct B<'a, T:'a>(&'a (A+'a)); + +trait X { } +impl<'a, T> X for B<'a, T> {} + +fn h<'a, T, U:'static>(v: Box+'static>) -> Box { + box B(&*v) as Box // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-4.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-4.rs new file mode 100644 index 000000000000..798a21ffd454 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-4.rs @@ -0,0 +1,14 @@ +#![feature(box_syntax)] + +trait A { } +struct B<'a, T:'a>(&'a (dyn A + 'a)); + +trait X { } +impl<'a, T> X for B<'a, T> {} + +fn i<'a, T, U>(v: Box+'a>) -> Box { + box B(&*v) as Box // { dg-error ".E0759." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-5.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-5.rs new file mode 100644 index 000000000000..092c5aa7d090 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-close-object-into-object-5.rs @@ -0,0 +1,27 @@ +#![feature(box_syntax)] +#![allow(warnings)] + +trait A +{ + fn get(&self) -> T { panic!() } +} + +struct B<'a, T: 'a>(&'a (A + 'a)); + +trait X { fn foo(&self) {} } + +impl<'a, T> X for B<'a, T> {} + +fn f<'a, T, U>(v: Box + 'static>) -> Box { + // oh dear! + box B(&*v) as Box +// { dg-error ".E0310." "" { target *-*-* } .-1 } +// { dg-error ".E0310." "" { target *-*-* } .-2 } +// { dg-error ".E0310." "" { target *-*-* } .-3 } +// { dg-error ".E0310." "" { target *-*-* } .-4 } +// { dg-error ".E0310." "" { target *-*-* } .-5 } +// { dg-error ".E0310." "" { target *-*-* } .-6 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-close-over-type-parameter-1.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-close-over-type-parameter-1.rs new file mode 100644 index 000000000000..16eab83c51b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-close-over-type-parameter-1.rs @@ -0,0 +1,26 @@ +#![feature(box_syntax)] + +// Test for what happens when a type parameter `A` is closed over into +// an object. This should yield errors unless `A` (and the object) +// both have suitable bounds. + +trait SomeTrait { + fn get(&self) -> isize; +} + +fn make_object1(v: A) -> Box { + box v as Box +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn make_object2<'a, A: SomeTrait + 'a>(v: A) -> Box { + box v as Box +} + +fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box { + box v as Box +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-close-over-type-parameter-multiple.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-close-over-type-parameter-multiple.rs new file mode 100644 index 000000000000..b58b169af0ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-close-over-type-parameter-multiple.rs @@ -0,0 +1,25 @@ +#![feature(box_syntax)] + +// Various tests where we over type parameters with multiple lifetime +// bounds. + +trait SomeTrait { fn get(&self) -> isize; } + +fn make_object_good1<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box { + // A outlives 'a AND 'b... + box v as Box // ...hence this type is safe. +} + +fn make_object_good2<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box { + // A outlives 'a AND 'b... + box v as Box // ...hence this type is safe. +} + +fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box { + // A outlives 'a AND 'b...but not 'c. + box v as Box // { dg-error ".E0495." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-close-over-type-parameter-successfully.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-close-over-type-parameter-successfully.rs new file mode 100644 index 000000000000..2979ace27587 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-close-over-type-parameter-successfully.rs @@ -0,0 +1,24 @@ +// run-pass +// A test where we (successfully) close over a reference into +// an object. + +#![feature(box_syntax)] + +trait SomeTrait { fn get(&self) -> isize; } + +impl<'a> SomeTrait for &'a isize { + fn get(&self) -> isize { + **self + } +} + +fn make_object<'a,A:SomeTrait+'a>(v: A) -> Box { + box v as Box +} + +fn main() { + let i: isize = 22; + let obj = make_object(&i); + assert_eq!(22, obj.get()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-close-param-into-object.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-close-param-into-object.rs new file mode 100644 index 000000000000..e5027023e55f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-close-param-into-object.rs @@ -0,0 +1,28 @@ +trait X { fn foo(&self) {} } + +fn p1(v: T) -> Box + where T : X +{ + Box::new(v) // { dg-error ".E0310." "" { target *-*-* } } +} + +fn p2(v: Box) -> Box + where Box : X +{ + Box::new(v) // { dg-error ".E0310." "" { target *-*-* } } +} + +fn p3<'a,T>(v: T) -> Box + where T : X +{ + Box::new(v) // { dg-error ".E0309." "" { target *-*-* } } +} + +fn p4<'a,T>(v: Box) -> Box + where Box : X +{ + Box::new(v) // { dg-error ".E0309." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-copy-closure.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-copy-closure.rs new file mode 100644 index 000000000000..7c2c6c71d2e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-copy-closure.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(non_camel_case_types)] + +struct closure_box<'a> { + cl: Box, +} + +fn box_it<'a>(x: Box) -> closure_box<'a> { + closure_box {cl: x} +} + +pub fn main() { + let mut i = 3; + assert_eq!(i, 3); + { + let cl = || i += 1; + let mut cl_box = box_it(Box::new(cl)); + (cl_box.cl)(); + } + assert_eq!(i, 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums.rs new file mode 100644 index 000000000000..9d205333d1cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums.rs @@ -0,0 +1,34 @@ +enum Ast<'a> { + Num(usize), + Add(&'a Ast<'a>, &'a Ast<'a>) +} + +fn build() { + let x = Ast::Num(3); + let y = Ast::Num(4); + let z = Ast::Add(&x, &y); + compute(&z); +} + +fn compute(x: &Ast) -> usize { + match *x { + Ast::Num(x) => { x } + Ast::Add(x, y) => { compute(x) + compute(y) } + } +} + +fn map_nums<'a,'b, F>(x: &Ast, f: &mut F) -> &'a Ast<'b> where F: FnMut(usize) -> usize { + match *x { + Ast::Num(x) => { + return &Ast::Num((*f)(x)); // { dg-error ".E0515." "" { target *-*-* } } + } + Ast::Add(x, y) => { + let m_x = map_nums(x, f); + let m_y = map_nums(y, f); + return &Ast::Add(m_x, m_y); // { dg-error ".E0515." "" { target *-*-* } } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums2.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums2.rs new file mode 100644 index 000000000000..8f967fd62027 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums2.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +enum ast<'a> { + num(usize), + add(&'a ast<'a>, &'a ast<'a>) +} + +fn mk_add_ok<'r>(x: &'r ast<'r>, y: &'r ast<'r>) -> ast<'r> { + ast::add(x, y) +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums3.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums3.rs new file mode 100644 index 000000000000..3a7a82ffecd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums3.rs @@ -0,0 +1,12 @@ +enum Ast<'a> { + Num(usize), + Add(&'a Ast<'a>, &'a Ast<'a>) +} + +fn mk_add_bad1<'a,'b>(x: &'a Ast<'a>, y: &'b Ast<'b>) -> Ast<'a> { + Ast::Add(x, y) // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums4.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums4.rs new file mode 100644 index 000000000000..4f5ec08c3e82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums4.rs @@ -0,0 +1,12 @@ +enum Ast<'a> { + Num(usize), + Add(&'a Ast<'a>, &'a Ast<'a>) +} + +fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> { + Ast::Add(x, y) // { dg-error ".E0495." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums5.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums5.rs new file mode 100644 index 000000000000..f6de95fedffc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-creating-enums5.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +enum ast<'a> { + num(usize), + add(&'a ast<'a>, &'a ast<'a>) +} + +fn mk_add_ok<'a>(x: &'a ast<'a>, y: &'a ast<'a>, _z: &ast) -> ast<'a> { + ast::add(x, y) +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-debruijn-of-object.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-debruijn-of-object.rs new file mode 100644 index 000000000000..e55b322904fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-debruijn-of-object.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +struct ctxt<'tcx> { + x: &'tcx i32 +} + +trait AstConv<'tcx> { + fn tcx<'a>(&'a self) -> &'a ctxt<'tcx>; +} + +fn foo(conv: &dyn AstConv) { } + +fn bar<'tcx>(conv: &dyn AstConv<'tcx>) { + foo(conv) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-dependent-addr-of.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-dependent-addr-of.rs new file mode 100644 index 000000000000..9ab2f97d84aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-dependent-addr-of.rs @@ -0,0 +1,114 @@ +// run-pass +// Test lifetimes are linked properly when we create dependent region pointers. +// Issue #3148. + +#![feature(box_patterns)] +#![feature(box_syntax)] + +struct A { + value: B +} + +struct B { + v1: isize, + v2: [isize; 3], + v3: Vec , + v4: C, + v5: Box, + v6: Option +} + +#[derive(Copy, Clone)] +struct C { + f: isize +} + +fn get_v1(a: &A) -> &isize { + // Region inferencer must deduce that &v < L2 < L1 + let foo = &a.value; // L1 + &foo.v1 // L2 +} + +fn get_v2(a: &A, i: usize) -> &isize { + let foo = &a.value; + &foo.v2[i] +} + +fn get_v3(a: &A, i: usize) -> &isize { + let foo = &a.value; + &foo.v3[i] +} + +fn get_v4(a: &A, _i: usize) -> &isize { + let foo = &a.value; + &foo.v4.f +} + +fn get_v5(a: &A, _i: usize) -> &isize { + let foo = &a.value; + &foo.v5.f +} + +fn get_v6_a(a: &A, _i: usize) -> &isize { + match a.value.v6 { + Some(ref v) => &v.f, + None => panic!() + } +} + +fn get_v6_b(a: &A, _i: usize) -> &isize { + match *a { + A { value: B { v6: Some(ref v), .. } } => &v.f, + _ => panic!() + } +} + +fn get_v6_c(a: &A, _i: usize) -> &isize { + match a { + &A { value: B { v6: Some(ref v), .. } } => &v.f, + _ => panic!() + } +} + +fn get_v5_ref(a: &A, _i: usize) -> &isize { + match &a.value { + &B {v5: box C {f: ref v}, ..} => v + } +} + +pub fn main() { + let a = A {value: B {v1: 22, + v2: [23, 24, 25], + v3: vec![26, 27, 28], + v4: C { f: 29 }, + v5: box C { f: 30 }, + v6: Some(C { f: 31 })}}; + + let p = get_v1(&a); + assert_eq!(*p, a.value.v1); + + let p = get_v2(&a, 1); + assert_eq!(*p, a.value.v2[1]); + + let p = get_v3(&a, 1); + assert_eq!(*p, a.value.v3[1]); + + let p = get_v4(&a, 1); + assert_eq!(*p, a.value.v4.f); + + let p = get_v5(&a, 1); + assert_eq!(*p, a.value.v5.f); + + let p = get_v6_a(&a, 1); + assert_eq!(*p, a.value.v6.unwrap().f); + + let p = get_v6_b(&a, 1); + assert_eq!(*p, a.value.v6.unwrap().f); + + let p = get_v6_c(&a, 1); + assert_eq!(*p, a.value.v6.unwrap().f); + + let p = get_v5_ref(&a, 1); + assert_eq!(*p, a.value.v5.f); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-dependent-autofn.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-dependent-autofn.rs new file mode 100644 index 000000000000..f29df6fe9eaf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-dependent-autofn.rs @@ -0,0 +1,16 @@ +// run-pass +// Test lifetimes are linked properly when we autoslice a vector. +// Issue #3148. + +// pretty-expanded FIXME #23616 + +fn subslice(v: F) -> F where F: FnOnce() { v } + +fn both(v: F) -> F where F: FnOnce() { + subslice(subslice(v)) +} + +pub fn main() { + both(main); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-dependent-autoslice.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-dependent-autoslice.rs new file mode 100644 index 000000000000..b1f2b34ced59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-dependent-autoslice.rs @@ -0,0 +1,15 @@ +// run-pass +// Test lifetimes are linked properly when we autoslice a vector. +// Issue #3148. + +fn subslice1<'r>(v: &'r [usize]) -> &'r [usize] { v } + +fn both<'r>(v: &'r [usize]) -> &'r [usize] { + subslice1(subslice1(v)) +} + +pub fn main() { + let v = vec![1,2,3]; + both(&v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-dependent-let-ref.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-dependent-let-ref.rs new file mode 100644 index 000000000000..a2648d9e425f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-dependent-let-ref.rs @@ -0,0 +1,13 @@ +// run-pass +// Test lifetimes are linked properly when we take reference +// to interior. + +// pretty-expanded FIXME #23616 + +struct Foo(isize); +pub fn main() { + // Here the lifetime of the `&` should be at least the + // block, since a ref binding is created to the interior. + let &Foo(ref _x) = &Foo(3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-error-method.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-error-method.rs new file mode 100644 index 000000000000..b9b3f8cf2f04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-error-method.rs @@ -0,0 +1,27 @@ +// Tests that you can use a fn lifetime parameter as part of +// the value for a type parameter in a bound. + +trait GetRef<'a> { + fn get(&self) -> &'a isize; +} + +struct Box<'a> { + t: &'a isize +} + +impl<'a> GetRef<'a> for Box<'a> { + fn get(&self) -> &'a isize { + self.t + } +} + +impl<'a> Box<'a> { + fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize { + g2.get() +// { dg-error ".E0312." "" { target *-*-* } .-1 } + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-error.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-error.rs new file mode 100644 index 000000000000..bc164589c0d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-error.rs @@ -0,0 +1,25 @@ +// Tests that you can use a fn lifetime parameter as part of +// the value for a type parameter in a bound. + +trait GetRef<'a, T> { + fn get(&self) -> &'a T; +} + +struct Box<'a, T:'a> { + t: &'a T +} + +impl<'a,T:Clone> GetRef<'a,T> for Box<'a,T> { + fn get(&self) -> &'a T { + self.t + } +} + +fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize { + g1.get() +// { dg-error ".E0312." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs new file mode 100644 index 000000000000..75c885d0ddb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-lifetime-in-assoc-fn.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(unused_imports)] +// Test that we are able to compile calls to associated fns like +// `decode()` where the bound on the `Self` parameter references a +// lifetime parameter of the trait. This example indicates why trait +// lifetime parameters must be early bound in the type of the +// associated item. + +// pretty-expanded FIXME #23616 + +use std::marker; + +pub enum Value<'v> { + A(&'v str), + B, +} + +pub trait Decoder<'v> { + fn read(&mut self) -> Value<'v>; +} + +pub trait Decodable<'v, D: Decoder<'v>> { + fn decode(d: &mut D) -> Self; +} + +impl<'v, D: Decoder<'v>> Decodable<'v, D> for () { + fn decode(d: &mut D) -> () { + match d.read() { + Value::A(..) => (), + Value::B => Decodable::decode(d), + } + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-trait-param.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-trait-param.rs new file mode 100644 index 000000000000..7c3dcd5523c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-trait-param.rs @@ -0,0 +1,135 @@ +// run-pass +// Tests that you can use an early-bound lifetime parameter as +// on of the generic parameters in a trait. + +#![feature(box_syntax)] + +trait Trait<'a> { + fn long(&'a self) -> isize; + fn short<'b>(&'b self) -> isize; +} + +fn poly_invoke<'c, T: Trait<'c>>(x: &'c T) -> (isize, isize) { + let l = x.long(); + let s = x.short(); + (l,s) +} + +fn object_invoke1<'d>(x: &'d dyn Trait<'d>) -> (isize, isize) { + let l = x.long(); + let s = x.short(); + (l,s) +} + +struct Struct1<'e> { + f: &'e (dyn Trait<'e>+'e) +} + +fn field_invoke1<'f, 'g>(x: &'g Struct1<'f>) -> (isize,isize) { + let l = x.f.long(); + let s = x.f.short(); + (l,s) +} + +struct Struct2<'h, 'i:'h> { + f: &'h (dyn Trait<'i>+'h) +} + +fn object_invoke2<'j, 'k>(x: &'k dyn Trait<'j>) -> isize { + x.short() +} + +fn field_invoke2<'l, 'm, 'n>(x: &'n Struct2<'l,'m>) -> isize { + x.f.short() +} + +trait MakerTrait { + fn mk() -> Self; +} + +fn make_val() -> T { + MakerTrait::mk() +} + +trait RefMakerTrait<'q> { + fn mk(_: Self) -> &'q Self; +} + +fn make_ref<'r, T:RefMakerTrait<'r>>(t:T) -> &'r T { + RefMakerTrait::mk(t) +} + +impl<'s> Trait<'s> for (isize,isize) { + fn long(&'s self) -> isize { + let &(x,_) = self; + x + } + fn short<'b>(&'b self) -> isize { + let &(_,y) = self; + y + } +} + +impl<'t> MakerTrait for Box+'static> { + fn mk() -> Box+'static> { + let tup: Box<(isize, isize)> = box (4,5); + tup as Box + } +} + +enum List<'l> { + Cons(isize, &'l List<'l>), + Null +} + +impl<'l> List<'l> { + fn car<'m>(&'m self) -> isize { + match self { + &List::Cons(car, _) => car, + &List::Null => panic!(), + } + } + fn cdr<'n>(&'n self) -> &'l List<'l> { + match self { + &List::Cons(_, cdr) => cdr, + &List::Null => panic!(), + } + } +} + +impl<'t> RefMakerTrait<'t> for List<'t> { + fn mk(l:List<'t>) -> &'t List<'t> { + l.cdr() + } +} + +pub fn main() { + let t = (2,3); + let o = &t as &dyn Trait; + let s1 = Struct1 { f: o }; + let s2 = Struct2 { f: o }; + assert_eq!(poly_invoke(&t), (2,3)); + assert_eq!(object_invoke1(&t), (2,3)); + assert_eq!(field_invoke1(&s1), (2,3)); + assert_eq!(object_invoke2(&t), 3); + assert_eq!(field_invoke2(&s2), 3); + + let m : Box = make_val(); + // assert_eq!(object_invoke1(&*m), (4,5)); + // ~~~~~~~~~~~~~~~~~~~ + // this call yields a compilation error; see compile-fail/dropck-object-cycle.rs + // for details. + assert_eq!(object_invoke2(&*m), 5); + + // The RefMakerTrait above is pretty strange (i.e., it is strange + // to consume a value of type T and return a &T). Easiest thing + // that came to my mind: consume a cell of a linked list and + // return a reference to the list it points to. + let l0 = List::Null; + let l1 = List::Cons(1, &l0); + let l2 = List::Cons(2, &l1); + let rl1 = &l1; + let r = make_ref(l2); + assert_eq!(rl1.car(), r.car()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-used-in-bound-method.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-used-in-bound-method.rs new file mode 100644 index 000000000000..3b14a0e1e1e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-used-in-bound-method.rs @@ -0,0 +1,31 @@ +// run-pass +// Tests that you can use a fn lifetime parameter as part of +// the value for a type parameter in a bound. + + +trait GetRef<'a> { + fn get(&self) -> &'a isize; +} + +#[derive(Copy, Clone)] +struct Box<'a> { + t: &'a isize +} + +impl<'a> GetRef<'a> for Box<'a> { + fn get(&self) -> &'a isize { + self.t + } +} + +impl<'a> Box<'a> { + fn add<'b,G:GetRef<'b>>(&self, g2: G) -> isize { + *self.t + *g2.get() + } +} + +pub fn main() { + let b1 = Box { t: &3 }; + assert_eq!(b1.add(b1), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-used-in-bound.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-used-in-bound.rs new file mode 100644 index 000000000000..71770cb41e2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-used-in-bound.rs @@ -0,0 +1,29 @@ +// run-pass +// Tests that you can use a fn lifetime parameter as part of +// the value for a type parameter in a bound. + + +trait GetRef<'a, T> { + fn get(&self) -> &'a T; +} + +#[derive(Copy, Clone)] +struct Box<'a, T:'a> { + t: &'a T +} + +impl<'a,T:Clone> GetRef<'a,T> for Box<'a,T> { + fn get(&self) -> &'a T { + self.t + } +} + +fn add<'a,G:GetRef<'a, isize>>(g1: G, g2: G) -> isize { + *g1.get() + *g2.get() +} + +pub fn main() { + let b1 = Box { t: &3 }; + assert_eq!(add(b1, b1), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-used-in-type-param.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-used-in-type-param.rs new file mode 100644 index 000000000000..19fe6cf5f574 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-early-bound-used-in-type-param.rs @@ -0,0 +1,29 @@ +// run-pass +// Tests that you can use a fn lifetime parameter as part of +// the value for a type parameter in a bound. + + +trait Get { + fn get(&self) -> T; +} + +#[derive(Copy, Clone)] +struct Box { + t: T +} + +impl Get for Box { + fn get(&self) -> T { + self.t.clone() + } +} + +fn add<'a,G:Get<&'a isize>>(g1: G, g2: G) -> isize { + *g1.get() + *g2.get() +} + +pub fn main() { + let b1 = Box { t: &3 }; + assert_eq!(add(b1, b1), 6); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-enum-not-wf.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-enum-not-wf.rs new file mode 100644 index 000000000000..72943ef76f39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-enum-not-wf.rs @@ -0,0 +1,42 @@ +// ignore-tidy-linelength + +// Various examples of structs whose fields are not well-formed. + +#![allow(dead_code)] + +trait Dummy<'a> { + type Out; +} +impl<'a, T> Dummy<'a> for T +where + T: 'a, +{ + type Out = (); +} +type RequireOutlives<'a, T> = >::Out; + +enum Ref1<'a, T> { + Ref1Variant1(RequireOutlives<'a, T>), // { dg-error ".E0309." "" { target *-*-* } } +} + +enum Ref2<'a, T> { + Ref2Variant1, + Ref2Variant2(isize, RequireOutlives<'a, T>), // { dg-error ".E0309." "" { target *-*-* } } +} + +enum RefOk<'a, T: 'a> { + RefOkVariant1(&'a T), +} + +// This is now well formed. RFC 2093 +enum RefIndirect<'a, T> { + RefIndirectVariant1(isize, RefOk<'a, T>), +} + +enum RefDouble<'a, 'b, T> { + RefDoubleVariant1(&'a RequireOutlives<'b, T>), +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-escape-into-other-fn.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-escape-into-other-fn.rs new file mode 100644 index 000000000000..17fc243fb829 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-escape-into-other-fn.rs @@ -0,0 +1,11 @@ +// run-pass +#![feature(box_syntax)] + +fn foo(x: &usize) -> &usize { x } +fn bar(x: &usize) -> usize { *x } + +pub fn main() { + let p: Box<_> = box 3; + assert_eq!(bar(foo(&*p)), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-escape-method.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-escape-method.rs new file mode 100644 index 000000000000..4a7afe4ce846 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-escape-method.rs @@ -0,0 +1,17 @@ +// Test a method call where the parameter `B` would (illegally) be +// inferred to a region bound in the method argument. If this program +// were accepted, then the closure passed to `s.f` could escape its +// argument. + +struct S; + +impl S { + fn f(&self, _: F) where F: FnOnce(&i32) -> B { + } +} + +fn main() { + let s = S; + s.f(|p| p) // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-escape-via-trait-or-not.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-escape-via-trait-or-not.rs new file mode 100644 index 000000000000..939bbb747263 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-escape-via-trait-or-not.rs @@ -0,0 +1,23 @@ +#![allow(dead_code)] + +trait Deref { + fn get(self) -> isize; +} + +impl<'a> Deref for &'a isize { + fn get(self) -> isize { + *self + } +} + +fn with(f: F) -> isize where F: FnOnce(&isize) -> R { + f(&3).get() +} + +fn return_it() -> isize { + with(|o| o) // { dg-error "" "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-expl-self.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-expl-self.rs new file mode 100644 index 000000000000..373b03d28271 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-expl-self.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +// Test that you can insert an explicit lifetime in explicit self. + +// pretty-expanded FIXME #23616 + +struct Foo { + f: usize +} + +impl Foo { + pub fn foo<'a>(&'a self) {} +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-fn-subtyping-2.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-fn-subtyping-2.rs new file mode 100644 index 000000000000..d73b1fa89aaf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-fn-subtyping-2.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +// Issue #2263. + +// Here, `f` is a function that takes a pointer `x` and a function +// `g`, where `g` requires its argument `y` to be in the same region +// that `x` is in. +// pretty-expanded FIXME #23616 + +fn has_same_region(f: Box FnMut(&'a isize, Box)>) { + // `f` should be the type that `wants_same_region` wants, but + // right now the compiler complains that it isn't. + wants_same_region(f); +} + +fn wants_same_region(_f: Box FnMut(&'b isize, Box)>) { +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-fn-subtyping-return-static.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-fn-subtyping-return-static.rs new file mode 100644 index 000000000000..ca22f2ffd05c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-fn-subtyping-return-static.rs @@ -0,0 +1,49 @@ +// In this fn, the type `F` is a function that takes a reference to a +// struct and returns another reference with the same lifetime. +// +// Meanwhile, the bare fn `foo` takes a reference to a struct with +// *ANY* lifetime and returns a reference with the 'static lifetime. +// This can safely be considered to be an instance of `F` because all +// lifetimes are sublifetimes of 'static. +// +// check-pass + +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(non_snake_case)] + +struct S; + +// Given 'cx, return 'cx +type F = for<'cx> fn(&'cx S) -> &'cx S; +fn want_F(f: F) {} + +// Given anything, return 'static +type G = for<'cx> fn(&'cx S) -> &'static S; +fn want_G(f: G) {} + +// Should meet both. +fn foo(x: &S) -> &'static S { + panic!() +} + +// Should meet both. +fn bar<'a, 'b>(x: &'a S) -> &'b S { + panic!() +} + +// Meets F, but not G. +fn baz(x: &S) -> &S { + panic!() +} + +fn supply_F() { + want_F(foo); + + want_F(bar); + + want_F(baz); +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-fn-subtyping.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-fn-subtyping.rs new file mode 100644 index 000000000000..c0cdb723cfab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-fn-subtyping.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_assignments)] +// Issue #2263. + +// pretty-expanded FIXME #23616 + +#![allow(unused_variables)] + +// Should pass region checking. +fn ok(f: Box) { + // Here, g is a function that can accept a usize pointer with + // lifetime r, and f is a function that can accept a usize pointer + // with any lifetime. The assignment g = f should be OK (i.e., + // f's type should be a subtype of g's type), because f can be + // used in any context that expects g's type. But this currently + // fails. + let mut g: Box FnMut(&'r usize)> = Box::new(|x| { }); + g = f; +} + +// This version is the same as above, except that here, g's type is +// inferred. +fn ok_inferred(f: Box) { + let mut g: Box FnMut(&'r usize)> = Box::new(|_| {}); + g = f; +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-callee-4.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-callee-4.rs new file mode 100644 index 000000000000..2f42f5902b77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-callee-4.rs @@ -0,0 +1,12 @@ +// Tests that callees correctly infer an ordering between free regions +// that appear in their parameter list. See also +// regions-free-region-ordering-caller.rs + +fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { +// { dg-error ".E0491." "" { target *-*-* } .-1 } + // Do not infer ordering from closure argument types. + let z: Option<&'a &'b usize> = None; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-callee.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-callee.rs new file mode 100644 index 000000000000..593182f50063 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-callee.rs @@ -0,0 +1,30 @@ +// Tests that callees correctly infer an ordering between free regions +// that appear in their parameter list. See also +// regions-free-region-ordering-caller.rs + +fn ordering1<'a, 'b>(x: &'a &'b usize) -> &'a usize { + // It is safe to assume that 'a <= 'b due to the type of x + let y: &'b usize = &**x; + return y; +} + +fn ordering2<'a, 'b>(x: &'a &'b usize, y: &'a usize) -> &'b usize { + // However, it is not safe to assume that 'b <= 'a + &*y // { dg-error ".E0623." "" { target *-*-* } } +} + +fn ordering3<'a, 'b>(x: &'a usize, y: &'b usize) -> &'a &'b usize { + // Do not infer an ordering from the return value. + let z: &'b usize = &*x; +// { dg-error ".E0623." "" { target *-*-* } .-1 } + panic!(); +} + +// see regions-free-region-ordering-callee-4.rs + +fn ordering5<'a, 'b>(a: &'a usize, b: &'b usize, x: Option<&'a &'b usize>) { + let z: Option<&'a &'b usize> = None; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-caller.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-caller.rs new file mode 100644 index 000000000000..2dac87af0209 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-caller.rs @@ -0,0 +1,27 @@ +// Test various ways to construct a pointer with a longer lifetime +// than the thing it points at and ensure that they result in +// errors. See also regions-free-region-ordering-callee.rs + +// revisions: migrate nll +//[nll]compile-flags: -Z borrowck=mir + +struct Paramd<'a> { x: &'a usize } + +fn call2<'a, 'b>(a: &'a usize, b: &'b usize) { + let z: Option<&'b &'a usize> = None;// { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn call3<'a, 'b>(a: &'a usize, b: &'b usize) { + let y: Paramd<'a> = Paramd { x: a }; + let z: Option<&'b Paramd<'a>> = None;// { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn call4<'a, 'b>(a: &'a usize, b: &'b usize) { + let z: Option<&'a &'b usize> = None;// { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-caller1.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-caller1.rs new file mode 100644 index 000000000000..6c5fa15e79f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-caller1.rs @@ -0,0 +1,15 @@ +// Test various ways to construct a pointer with a longer lifetime +// than the thing it points at and ensure that they result in +// errors. See also regions-free-region-ordering-callee.rs + +fn call1<'a>(x: &'a usize) { + // Test that creating a pointer like + // &'a &'z usize requires that 'a <= 'z: + let y: usize = 3; + let z: &'a & usize = &(&y); +// { dg-error ".E0597." "" { target *-*-* } .-1 } +// { dg-error ".E0597." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-incorrect.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-incorrect.rs new file mode 100644 index 000000000000..b93558883f19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-ordering-incorrect.rs @@ -0,0 +1,23 @@ +// Test that free regions ordering only goes one way. That is, +// we have `&'a Node<'b, T>`, which implies that `'a <= 'b`, +// but not `'b <= 'a`. Hence, returning `&self.val` (which has lifetime +// `'a`) where `'b` is expected yields an error. +// +// This test began its life as a test for issue #4325. + +struct Node<'b, T: 'b> { + val: T, + next: Option<&'b Node<'b, T>> +} + +impl<'b, T> Node<'b, T> { + fn get<'a>(&'a self) -> &'b T { + match self.next { + Some(ref next) => next.get(), + None => &self.val // { dg-error ".E0495." "" { target *-*-* } } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs new file mode 100644 index 000000000000..c7e6b93fdc7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +// Test that we recognize that if you have +// +// 'a : 'static +// +// then +// +// 'a : 'b + +fn test<'a,'b>(x: &'a i32) -> &'b i32 + where 'a: 'static +{ + x +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-glb-free-free.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-glb-free-free.rs new file mode 100644 index 000000000000..51922450936e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-glb-free-free.rs @@ -0,0 +1,30 @@ +mod argparse { + pub struct Flag<'a> { + name: &'a str, + pub desc: &'a str, + max_count: usize, + value: usize + } + + pub fn flag<'r>(name: &'r str, desc: &'r str) -> Flag<'r> { + Flag { name: name, desc: desc, max_count: 1, value: 0 } + } + + impl<'a> Flag<'a> { + pub fn set_desc(self, s: &str) -> Flag<'a> { + Flag { // { dg-error ".E0621." "" { target *-*-* } } + name: self.name, + desc: s, + max_count: self.max_count, + value: self.value + } + } + } +} + +fn main () { + let f : argparse::Flag = argparse::flag("flag", "My flag"); + let updated_flag = f.set_desc("My new flag"); + assert_eq!(updated_flag.desc, "My new flag"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-1.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-1.rs new file mode 100644 index 000000000000..ef2f6f4d6c2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-1.rs @@ -0,0 +1,31 @@ +// Illustrates the "projection gap": in this test, even though we know +// that `T::Foo: 'x`, that does not tell us that `T: 'x`, because +// there might be other ways for the caller of `func` to show that +// `T::Foo: 'x` holds (e.g., where-clause). + +trait Trait1<'x> { + type Foo; +} + +// calling this fn should trigger a check that the type argument +// supplied is well-formed. +fn wf() { } + +fn func<'x, T:Trait1<'x>>(t: &'x T::Foo) +{ + wf::<&'x T>(); +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn caller2<'x, T:Trait1<'x>>(t: &'x T) +{ + wf::<&'x T::Foo>(); // OK +} + +fn caller3<'x, T:Trait1<'x>>(t: &'x T::Foo) +{ + wf::<&'x T::Foo>(); // OK +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-2.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-2.rs new file mode 100644 index 000000000000..c4f5663c20ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-2.rs @@ -0,0 +1,24 @@ +// Along with the other tests in this series, illustrates the +// "projection gap": in this test, we know that `T: 'x`, and that is +// enough to conclude that `T::Foo: 'x`. + +// check-pass +#![allow(dead_code)] +#![allow(unused_variables)] + +trait Trait1<'x> { + type Foo; +} + +// calling this fn should trigger a check that the type argument +// supplied is well-formed. +fn wf() { } + +fn func<'x, T:Trait1<'x>>(t: &'x T) +{ + wf::<&'x T::Foo>(); +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-3.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-3.rs new file mode 100644 index 000000000000..6fea1cf8e14d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-3.rs @@ -0,0 +1,24 @@ +// Along with the other tests in this series, illustrates the +// "projection gap": in this test, we know that `T::Foo: 'x`, and that +// is (naturally) enough to conclude that `T::Foo: 'x`. + +// check-pass +#![allow(dead_code)] +#![allow(unused_variables)] + +trait Trait1<'x> { + type Foo; +} + +// calling this fn should trigger a check that the type argument +// supplied is well-formed. +fn wf() { } + +fn func<'x, T:Trait1<'x>>(t: &'x T::Foo) +{ + wf::<&'x T::Foo>(); +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-4.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-4.rs new file mode 100644 index 000000000000..e4a4fcf5f2ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-4.rs @@ -0,0 +1,24 @@ +// Along with the other tests in this series, illustrates the +// "projection gap": in this test, we know that `T: 'x`, and that +// is (naturally) enough to conclude that `T: 'x`. + +// check-pass +#![allow(dead_code)] +#![allow(unused_variables)] + +trait Trait1<'x> { + type Foo; +} + +// calling this fn should trigger a check that the type argument +// supplied is well-formed. +fn wf() { } + +fn func<'x, T:Trait1<'x>>(t: &'x T) +{ + wf::<&'x T>(); +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs new file mode 100644 index 000000000000..3eb6cc20582f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-implied-bounds-projection-gap-hr-1.rs @@ -0,0 +1,27 @@ +// The "projection gap" is particularly "fun" around higher-ranked +// projections. This is because the current code is hard-coded to say +// that a projection that contains escaping regions, like `>::Foo` where `'z` is bound, can only be found to +// outlive a region if all components that appear free (`'y`, where) +// outlive that region. However, we DON'T add those components to the +// implied bounds set, but rather we treat projections with escaping +// regions as opaque entities, just like projections without escaping +// regions. + +trait Trait1 { } + +trait Trait2<'a, 'b> { + type Foo; +} + +// As a side-effect of the conservative process above, the type of +// this argument `t` is not automatically considered well-formed, +// since for it to be WF, we would need to know that `'y: 'x`, but we +// do not infer that. +fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< >::Foo >) +// { dg-error ".E0491." "" { target *-*-* } .-1 } +{ +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-in-enums-anon.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-in-enums-anon.rs new file mode 100644 index 000000000000..7f848aa6170a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-in-enums-anon.rs @@ -0,0 +1,8 @@ +// Test that anonymous lifetimes are not permitted in enum declarations + +enum Foo { + Bar(&isize) // { dg-error ".E0106." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-in-enums.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-in-enums.rs new file mode 100644 index 000000000000..47f6d551d74b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-in-enums.rs @@ -0,0 +1,21 @@ +// Test that lifetimes must be declared for use on enums. +// See also regions-undeclared.rs + +enum Yes0<'lt> { + X3(&'lt usize) +} + +enum Yes1<'a> { + X4(&'a usize) +} + +enum No0 { + X5(&'foo usize) // { dg-error ".E0261." "" { target *-*-* } } +} + +enum No1 { + X6(&'a usize) // { dg-error ".E0261." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-in-structs-anon.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-in-structs-anon.rs new file mode 100644 index 000000000000..4c74ddfeae95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-in-structs-anon.rs @@ -0,0 +1,8 @@ +// Test that anonymous lifetimes are not permitted in struct declarations + +struct Foo { + x: &isize // { dg-error ".E0106." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-in-structs.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-in-structs.rs new file mode 100644 index 000000000000..a44abd768bb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-in-structs.rs @@ -0,0 +1,16 @@ +struct Yes1<'a> { + x: &'a usize, +} + +struct Yes2<'a> { + x: &'a usize, +} + +struct StructDecl { + a: &'a isize, // { dg-error ".E0261." "" { target *-*-* } } + b: &'a isize, // { dg-error ".E0261." "" { target *-*-* } } +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-at-fn-not-param.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-at-fn-not-param.rs new file mode 100644 index 000000000000..54eaab2fc812 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-at-fn-not-param.rs @@ -0,0 +1,20 @@ +struct Parameterized1<'a> { + g: Box +} + +struct NotParameterized1 { + g: Box +} + +struct NotParameterized2 { + g: Box +} + +fn take1<'a>(p: Parameterized1) -> Parameterized1<'a> { p } +// { dg-error ".E0621." "" { target *-*-* } .-1 } + +fn take3(p: NotParameterized1) -> NotParameterized1 { p } +fn take4(p: NotParameterized2) -> NotParameterized2 { p } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-addr-of.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-addr-of.rs new file mode 100644 index 000000000000..521f74f7e2de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-addr-of.rs @@ -0,0 +1,24 @@ +// run-pass + +use std::mem::swap; + +pub fn main() { + let mut x = 4; + + for i in 0_usize..3 { + // ensure that the borrow in this alt + // does not interfere with the swap + // below. note that it would it you + // naively borrowed &x for the lifetime + // of the variable x, as we once did + match i { + i => { + let y = &x; + assert!(i < *y); + } + } + let mut y = 4; + swap(&mut y, &mut x); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-too-big.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-too-big.rs new file mode 100644 index 000000000000..88f2b7c798f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-too-big.rs @@ -0,0 +1,17 @@ +struct Point { + x: isize, + y: isize, +} + +fn x_coord<'r>(p: &'r Point) -> &'r isize { + return &p.x; +} + +fn foo<'a>(p: Box) -> &'a isize { + let xc = x_coord(&*p); + assert_eq!(*xc, 3); + return xc; // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-view.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-view.rs new file mode 100644 index 000000000000..561006a87390 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-view.rs @@ -0,0 +1,12 @@ +// run-pass + + +fn view(x: &[T]) -> &[T] {x} + +pub fn main() { + let v = vec![1, 2, 3]; + let x = view(&v); + let y = view(x); + assert!((v[0] == x[0]) && (v[0] == y[0])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-within-loop-ok.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-within-loop-ok.rs new file mode 100644 index 000000000000..d19cfb9a497d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope-within-loop-ok.rs @@ -0,0 +1,14 @@ +// run-pass +#![feature(box_syntax)] + +fn borrow(x: &T) -> &T {x} + +pub fn main() { + let x: Box<_> = box 3; + loop { + let y = borrow(&*x); + assert_eq!(*x, *y); + break; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope.rs new file mode 100644 index 000000000000..35ba0f7db8b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-borrow-scope.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +#![feature(box_syntax)] + +struct Point {x: isize, y: isize} + +fn x_coord(p: &Point) -> &isize { + return &p.x; +} + +pub fn main() { + let p: Box<_> = box Point {x: 3, y: 4}; + let xc = x_coord(&*p); + assert_eq!(*xc, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-bound-from-trait-self.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-bound-from-trait-self.rs new file mode 100644 index 000000000000..7afbb13dc418 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-bound-from-trait-self.rs @@ -0,0 +1,52 @@ +// Test that we can derive lifetime bounds on `Self` from trait +// inheritance. + +trait Static : 'static { } + +trait Is<'a> : 'a { } + +struct Inv<'a> { + x: Option<&'a mut &'a isize> +} + +fn check_bound<'a,A:'a>(x: Inv<'a>, a: A) { } + +// In these case, `Self` inherits `'static`. + +trait InheritsFromStatic : Sized + 'static { + fn foo1<'a>(self, x: Inv<'a>) { + check_bound(x, self) + } +} +trait InheritsFromStaticIndirectly : Sized + Static { + fn foo1<'a>(self, x: Inv<'a>) { + check_bound(x, self) + } +} + + +// In these case, `Self` inherits `'a`. + +trait InheritsFromIs<'a> : Sized + 'a { + fn foo(self, x: Inv<'a>) { + check_bound(x, self) + } +} + +trait InheritsFromIsIndirectly<'a> : Sized + Is<'a> { + fn foo(self, x: Inv<'a>) { + check_bound(x, self) + } +} + +// In this case, `Self` inherits nothing. + +trait InheritsFromNothing<'a> : Sized { + fn foo(self, x: Inv<'a>) { + check_bound(x, self) +// { dg-error ".E0309." "" { target *-*-* } .-1 } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-bound-from-trait.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-bound-from-trait.rs new file mode 100644 index 000000000000..79891487faf4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-bound-from-trait.rs @@ -0,0 +1,41 @@ +// Test that we can derive lifetime bounds on type parameters +// from trait inheritance. + +trait Static : 'static { } + +trait Is<'a> : 'a { } + +struct Inv<'a> { + x: Option<&'a mut &'a isize> +} + +fn check_bound<'a,A:'a>(x: Inv<'a>, a: A) { } + +// In all of these cases, we can derive a bound for A that is longer +// than 'a based on the trait bound of A: + +fn foo1<'a,A:Static>(x: Inv<'a>, a: A) { + check_bound(x, a) +} + +fn foo2<'a,A:Static>(x: Inv<'static>, a: A) { + check_bound(x, a) +} + +fn foo3<'a,A:Is<'a>>(x: Inv<'a>, a: A) { + check_bound(x, a) +} + +// In these cases, there is no trait bound, so we cannot derive any +// bound for A and we get an error: + +fn bar1<'a,A>(x: Inv<'a>, a: A) { + check_bound(x, a) // { dg-error ".E0309." "" { target *-*-* } } +} + +fn bar2<'a,'b,A:Is<'b>>(x: Inv<'a>, y: Inv<'b>, a: A) { + check_bound(x, a) // { dg-error ".E0309." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-call-2.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-call-2.rs new file mode 100644 index 000000000000..7d383125fde7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-call-2.rs @@ -0,0 +1,16 @@ +// run-pass + +fn takes_two(x: &isize, y: &isize) -> isize { *x + *y } + +fn with(f: F) -> T where F: FnOnce(&isize) -> T { + f(&20) +} + +fn has_one<'a>(x: &'a isize) -> isize { + with(|y| takes_two(x, y)) +} + +pub fn main() { + assert_eq!(has_one(&2), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-call-3.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-call-3.rs new file mode 100644 index 000000000000..4a42657bc669 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-call-3.rs @@ -0,0 +1,15 @@ +fn select<'r>(x: &'r isize, y: &'r isize) -> &'r isize { x } + +fn with(f: F) -> T where F: FnOnce(&isize) -> T { + f(&20) +} + +fn manip<'a>(x: &'a isize) -> isize { + let z = with(|y| { select(x, y) }); +// { dg-error "" "" { target *-*-* } .-1 } + *z +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-call.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-call.rs new file mode 100644 index 000000000000..0f7bef5d4b58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-call.rs @@ -0,0 +1,12 @@ +// run-pass + +fn takes_two(x: &isize, y: &isize) -> isize { *x + *y } + +fn has_two<'a,'b>(x: &'a isize, y: &'b isize) -> isize { + takes_two(x, y) +} + +pub fn main() { + assert_eq!(has_two(&20, &2), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-contravariance-due-to-decl.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-contravariance-due-to-decl.rs new file mode 100644 index 000000000000..0b8af96e575a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-contravariance-due-to-decl.rs @@ -0,0 +1,29 @@ +// Test that a type which is contravariant with respect to its region +// parameter yields an error when used in a covariant way. +// +// Note: see variance-regions-*.rs for the tests that check that the +// variance inference works in the first place. + +use std::marker; + +// This is contravariant with respect to 'a, meaning that +// Contravariant<'foo> <: Contravariant<'static> because +// 'foo <= 'static +struct Contravariant<'a> { + marker: marker::PhantomData<&'a()> +} + +fn use_<'short,'long>(c: Contravariant<'short>, + s: &'short isize, + l: &'long isize, + _where:Option<&'short &'long ()>) { + + // Test whether Contravariant<'short> <: Contravariant<'long>. Since + // 'short <= 'long, this would be true if the Contravariant type were + // covariant with respect to its parameter 'a. + + let _: Contravariant<'long> = c; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-contravariance-due-to-ret.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-contravariance-due-to-ret.rs new file mode 100644 index 000000000000..7557ec7fb8d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-contravariance-due-to-ret.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(non_camel_case_types)] + + +struct boxed_int<'a> { + f: &'a isize, +} + +fn max<'r>(bi: &'r boxed_int, f: &'r isize) -> isize { + if *bi.f > *f {*bi.f} else {*f} +} + +fn with(bi: &boxed_int) -> isize { + let i = 22; + max(bi, &i) +} + +pub fn main() { + let g = 21; + let foo = boxed_int { f: &g }; + assert_eq!(with(&foo), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-covariance-due-to-decl.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-covariance-due-to-decl.rs new file mode 100644 index 000000000000..2cbe5b0989e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-covariance-due-to-decl.rs @@ -0,0 +1,26 @@ +// Test that a type which is covariant with respect to its region +// parameter yields an error when used in a contravariant way. +// +// Note: see variance-regions-*.rs for the tests that check that the +// variance inference works in the first place. + +use std::marker; + +struct Covariant<'a> { + marker: marker::PhantomData +} + +fn use_<'short,'long>(c: Covariant<'long>, + s: &'short isize, + l: &'long isize, + _where:Option<&'short &'long ()>) { + + // Test whether Covariant<'long> <: Covariant<'short>. Since + // 'short <= 'long, this would be true if the Covariant type were + // contravariant with respect to its parameter 'a. + + let _: Covariant<'short> = c; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-invariance-due-to-decl.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-invariance-due-to-decl.rs new file mode 100644 index 000000000000..dd3aa6854b17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-invariance-due-to-decl.rs @@ -0,0 +1,17 @@ +use std::marker; + +struct Invariant<'a> { + marker: marker::PhantomData<*mut &'a()> +} + +fn to_same_lifetime<'r>(b_isize: Invariant<'r>) { + let bj: Invariant<'r> = b_isize; +} + +fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { + b_isize // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-invariance-due-to-mutability-3.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-invariance-due-to-mutability-3.rs new file mode 100644 index 000000000000..c464f9c47dbe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-invariance-due-to-mutability-3.rs @@ -0,0 +1,15 @@ +struct Invariant<'a> { + f: Box, +} + +fn to_same_lifetime<'r>(b_isize: Invariant<'r>) { + let bj: Invariant<'r> = b_isize; +} + +fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { + b_isize // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-invariance-due-to-mutability-4.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-invariance-due-to-mutability-4.rs new file mode 100644 index 000000000000..9fe776668ffe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-invariance-due-to-mutability-4.rs @@ -0,0 +1,15 @@ +struct Invariant<'a> { + f: Box *mut &'a isize + 'static>, +} + +fn to_same_lifetime<'r>(b_isize: Invariant<'r>) { + let bj: Invariant<'r> = b_isize; +} + +fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { + b_isize // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-not-param.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-not-param.rs new file mode 100644 index 000000000000..1848714dacef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-not-param.rs @@ -0,0 +1,27 @@ +struct Direct<'a> { + f: &'a isize +} + +struct Indirect1 { + // Here the lifetime parameter of direct is bound by the fn() + g: Box +} + +struct Indirect2<'a> { + // But here it is set to 'a + g: Box) + 'static> +} + +fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } // { dg-error ".E0308." "" { target *-*-* } } + +fn take_indirect1(p: Indirect1) -> Indirect1 { p } + +fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-error "" "" { target *-*-* } .-6 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-paramd-indirect.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-paramd-indirect.rs new file mode 100644 index 000000000000..b859623aebf9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-paramd-indirect.rs @@ -0,0 +1,31 @@ +// Check that we correctly infer that b and c must be region +// parameterized because they reference a which requires a region. + +type A<'a> = &'a isize; +type B<'a> = Box>; + +struct C<'a> { + f: Box> +} + +trait SetF<'a> { + fn set_f_ok(&mut self, b: Box>); + fn set_f_bad(&mut self, b: Box); +} + +impl<'a> SetF<'a> for C<'a> { + fn set_f_ok(&mut self, b: Box>) { + self.f = b; + } + + fn set_f_bad(&mut self, b: Box) { + self.f = b; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-proc-static-upvar.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-proc-static-upvar.rs new file mode 100644 index 000000000000..64c9c2cd6afd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-proc-static-upvar.rs @@ -0,0 +1,25 @@ +// Test that, when a variable of type `&T` is captured inside a proc, +// we correctly infer/require that its lifetime is 'static. + +fn foo(_p: F) { } + +static i: isize = 3; + +fn capture_local() { + let x = 3; + let y = &x; // { dg-error ".E0597." "" { target *-*-* } } + foo(move|| { + let _a = *y; + }); +} + +fn capture_static() { + // Legal because &i can have static lifetime: + let y = &i; + foo(move|| { + let _a = *y; + }); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs new file mode 100644 index 000000000000..c8c3ee59feb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-reborrow-ref-mut-recurse.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +// Test an edge case in region inference: the lifetime of the borrow +// of `*x` must be extended to at least 'a. + +// pretty-expanded FIXME #23616 + +fn foo<'a,'b>(x: &'a &'b mut isize) -> &'a isize { + let y = &*x; // should be inferred to have type &'a &'b mut isize... + + // ...because if we inferred, say, &'x &'b mut isize where 'x <= 'a, + // this reborrow would be illegal: + &**y +} + +pub fn main() { + /* Just want to know that it compiles. */ +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-region-in-fn-but-not-type.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-region-in-fn-but-not-type.rs new file mode 100644 index 000000000000..5546f0f181a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-region-in-fn-but-not-type.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(non_camel_case_types)] + + +// check that the &isize here does not cause us to think that `foo` +// contains region pointers +// pretty-expanded FIXME #23616 + +struct foo(Box); + +fn take_foo(x: T) {} + +fn have_foo(f: foo) { + take_foo(f); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-infer-static-from-proc.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-static-from-proc.rs new file mode 100644 index 000000000000..73535045e24b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-infer-static-from-proc.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(non_upper_case_globals)] + +// Check that the 'static bound on a proc influences lifetimes of +// region variables contained within (otherwise, region inference will +// give `x` a very short lifetime). + +// pretty-expanded FIXME #23616 + +static i: usize = 3; +fn foo(_: F) {} +fn read(_: usize) { } +pub fn main() { + let x = &i; + foo(move|| { + read(*x); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-issue-21422.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-issue-21422.rs new file mode 100644 index 000000000000..2c6e4d540b6a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-issue-21422.rs @@ -0,0 +1,19 @@ +// run-pass +// Regression test for issue #21422, which was related to failing to +// add inference constraints that the operands of a binary operator +// should outlive the binary operation itself. + +// pretty-expanded FIXME #23616 + +pub struct P<'a> { + _ptr: *const &'a u8, +} + +impl <'a> PartialEq for P<'a> { + fn eq(&self, other: &P<'a>) -> bool { + (self as *const _) == (other as *const _) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-issue-22246.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-issue-22246.rs new file mode 100644 index 000000000000..becf7c8985e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-issue-22246.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(unused_imports)] +// Regression test for issue #22246 -- we should be able to deduce +// that `&'a B::Owned` implies that `B::Owned : 'a`. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +use std::ops::Deref; + +pub trait ToOwned: Sized { + type Owned: Borrow; + fn to_owned(&self) -> Self::Owned; +} + +pub trait Borrow { + fn borrow(&self) -> &Borrowed; +} + +pub struct Foo { + owned: B::Owned +} + +fn foo(this: &Foo) -> &B { + this.owned.borrow() +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-bounds-on-fns.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-bounds-on-fns.rs new file mode 100644 index 000000000000..eea4626de2d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-bounds-on-fns.rs @@ -0,0 +1,30 @@ +fn a<'a, 'b:'a>(x: &mut &'a isize, y: &mut &'b isize) { + // Note: this is legal because of the `'b:'a` declaration. + *x = *y; +} + +fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { + // Illegal now because there is no `'b:'a` declaration. + *x = *y; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { + // Here we try to call `foo` but do not know that `'a` and `'b` are + // related as required. + a(x, y); // { dg-error ".E0623." "" { target *-*-* } } +} + +fn d() { + // 'a and 'b are early bound in the function `a` because they appear + // inconstraints: + let _: fn(&mut &isize, &mut &isize) = a; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn e() { + // 'a and 'b are late bound in the function `b` because there are + // no constraints: + let _: fn(&mut &isize, &mut &isize) = b; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-nonfree-late-bound.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-nonfree-late-bound.rs new file mode 100644 index 000000000000..31dda764bc42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-nonfree-late-bound.rs @@ -0,0 +1,36 @@ +// run-pass +// This is a regression test for the ICE from issue #10846. +// +// The original issue causing the ICE: the LUB-computations during +// type inference were encountering late-bound lifetimes, and +// asserting that such lifetimes should have already been substituted +// with a concrete lifetime. +// +// However, those encounters were occurring within the lexical scope +// of the binding for the late-bound lifetime; that is, the late-bound +// lifetimes were perfectly valid. The core problem was that the type +// folding code was over-zealously passing back all lifetimes when +// doing region-folding, when really all clients of the region-folding +// case only want to see FREE lifetime variables, not bound ones. + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { + fn explicit() { + fn test(_x: Option>) where F: FnMut(Box FnMut(&'a isize)>) {} + test(Some(box |_f: Box FnMut(&'a isize)>| {})); + } + + // The code below is shorthand for the code above (and more likely + // to represent what one encounters in practice). + fn implicit() { + fn test(_x: Option>) where F: FnMut(Box) {} + test(Some(box |_f: Box| {})); + } + + explicit(); + implicit(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-of-struct-or-enum-variant.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-of-struct-or-enum-variant.rs new file mode 100644 index 000000000000..85c716ac0f7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-of-struct-or-enum-variant.rs @@ -0,0 +1,27 @@ +// This tests verifies that unary structs and enum variants +// are treated as rvalues and their lifetime is not bounded to +// the static scope. + +fn id(x: T) -> T { x } + +struct Test; + +enum MyEnum { + Variant1 +} + +fn structLifetime<'a>() -> &'a Test { + let testValue = &id(Test); + testValue +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + +fn variantLifetime<'a>() -> &'a MyEnum { + let testValue = &id(MyEnum::Variant1); + testValue +// { dg-error ".E0515." "" { target *-*-* } .-1 } +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-static-items-enclosing-scopes.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-static-items-enclosing-scopes.rs new file mode 100644 index 000000000000..f025335460f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-lifetime-static-items-enclosing-scopes.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +// This test verifies that temporary lifetime is correctly computed +// for static objects in enclosing scopes. + + +use std::cmp::PartialEq; + +fn f(o: &mut Option) { + assert_eq!(*o, None); +} + +pub fn main() { + mod t { + enum E {V=1, A=0} + static C: E = E::V; + } + + f::(&mut None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-link-fn-args.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-link-fn-args.rs new file mode 100644 index 000000000000..8ffd97aeb30c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-link-fn-args.rs @@ -0,0 +1,16 @@ +// run-pass +// Test that region inference correctly links up the regions when a +// `ref` borrow occurs inside a fn argument. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +fn with<'a, F>(_: F) where F: FnOnce(&'a Vec) -> &'a Vec { } + +fn foo() { + with(|&ref ints| ints); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-lub-ref-ref-rc.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-lub-ref-ref-rc.rs new file mode 100644 index 000000000000..d05e6dd6d771 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-lub-ref-ref-rc.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] +// Test a corner case of LUB coercion. In this case, one arm of the +// match requires a deref coercion and the other doesn't, and there +// is an extra `&` on the `rc`. We want to be sure that the lifetime +// assigned to this `&rc` value is not `'a` but something smaller. In +// other words, the type from `rc` is `&'a Rc` and the type +// from `&rc` should be `&'x &'a Rc`, where `'x` is something +// small. + +use std::rc::Rc; + +#[derive(Clone)] +enum Cached<'mir> { + Ref(&'mir String), + Owned(Rc), +} + +impl<'mir> Cached<'mir> { + fn get_ref<'a>(&'a self) -> &'a String { + match *self { + Cached::Ref(r) => r, + Cached::Owned(ref rc) => &rc, + } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-mock-codegen.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-mock-codegen.rs new file mode 100644 index 000000000000..cfca15f17ed7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-mock-codegen.rs @@ -0,0 +1,55 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +// pretty-expanded FIXME #23616 +#![feature(allocator_api)] + +use std::alloc::{handle_alloc_error, AllocRef, Global, Layout}; +use std::ptr::NonNull; + +struct arena(()); + +struct Bcx<'a> { + fcx: &'a Fcx<'a>, +} + +struct Fcx<'a> { + arena: &'a arena, + ccx: &'a Ccx, +} + +struct Ccx { + x: isize, +} + +fn alloc(_bcx: &arena) -> &Bcx<'_> { + unsafe { + let layout = Layout::new::(); + let ptr = Global.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout)); + &*(ptr.as_ptr() as *const _) + } +} + +fn h<'a>(bcx: &'a Bcx<'a>) -> &'a Bcx<'a> { + return alloc(bcx.fcx.arena); +} + +fn g(fcx: &Fcx) { + let bcx = Bcx { fcx }; + let bcx2 = h(&bcx); + unsafe { + Global.dealloc(NonNull::new_unchecked(bcx2 as *const _ as *mut _), Layout::new::()); + } +} + +fn f(ccx: &Ccx) { + let a = arena(()); + let fcx = Fcx { arena: &a, ccx }; + return g(&fcx); +} + +pub fn main() { + let ccx = Ccx { x: 0 }; + f(&ccx); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-name-duplicated.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-name-duplicated.rs new file mode 100644 index 000000000000..0ad89f5ae9c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-name-duplicated.rs @@ -0,0 +1,6 @@ +struct Foo<'a, 'a> { // { dg-error ".E0263." "" { target *-*-* } } + x: &'a isize +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-name-static.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-name-static.rs new file mode 100644 index 000000000000..2f055276af93 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-name-static.rs @@ -0,0 +1,6 @@ +struct Foo<'static> { // { dg-error ".E0262." "" { target *-*-* } } + x: &'static isize +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-name-undeclared.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-name-undeclared.rs new file mode 100644 index 000000000000..52e635a92bef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-name-undeclared.rs @@ -0,0 +1,59 @@ +// edition:2018 +// Check that lifetime resolver enforces the lifetime name scoping +// rules correctly in various scenarios. + +struct Foo<'a> { + x: &'a isize +} + +impl<'a> Foo<'a> { + // &'a is inherited: + fn m1(&self, arg: &'a isize) { } + fn m2(&'a self) { } + fn m3(&self, arg: Foo<'a>) { } + + // &'b is not: + fn m4(&self, arg: &'b isize) { } // { dg-error ".E0261." "" { target *-*-* } } + fn m5(&'b self) { } // { dg-error ".E0261." "" { target *-*-* } } + fn m6(&self, arg: Foo<'b>) { } // { dg-error ".E0261." "" { target *-*-* } } +} + +fn bar<'a>(x: &'a isize) { + // &'a is visible to code: + let y: &'a isize = x; + + // &'a is not visible to *items*: + type X = Option<&'a isize>; // { dg-error ".E0261." "" { target *-*-* } } + enum E { + E1(&'a isize) // { dg-error ".E0261." "" { target *-*-* } } + } + struct S { + f: &'a isize // { dg-error ".E0261." "" { target *-*-* } } + } + fn f(a: &'a isize) { } // { dg-error ".E0261." "" { target *-*-* } } + + // &'a CAN be declared on functions and used then: + fn g<'a>(a: &'a isize) { } // OK + fn h(a: Box FnOnce(&'a isize)>) { } // OK +} + +// Test nesting of lifetimes in fn type declarations +fn fn_types(a: &'a isize, // { dg-error ".E0261." "" { target *-*-* } } + b: Box FnOnce(&'a isize, + &'b isize, // { dg-error ".E0261." "" { target *-*-* } } + Box FnOnce(&'a isize, + &'b isize)>, + &'b isize)>, // { dg-error ".E0261." "" { target *-*-* } } + c: &'a isize) // { dg-error ".E0261." "" { target *-*-* } } +{ +} + +struct Bug {} +impl Bug { + async fn buggy(&self) -> &'a str { // { dg-error ".E0261." "" { target *-*-* } } + todo!() + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-nested-fns-2.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-nested-fns-2.rs new file mode 100644 index 000000000000..a0e17f443f04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-nested-fns-2.rs @@ -0,0 +1,13 @@ +fn ignore(_f: F) where F: for<'z> FnOnce(&'z isize) -> &'z isize {} + +fn nested() { + let y = 3; + ignore( + |z| { + if false { &y } else { z } +// { dg-error ".E0597." "" { target *-*-* } .-1 } + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-nested-fns.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-nested-fns.rs new file mode 100644 index 000000000000..27e79ba17fa8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-nested-fns.rs @@ -0,0 +1,21 @@ +fn ignore(t: T) {} + +fn nested<'x>(x: &'x isize) { + let y = 3; + let mut ay = &y; // { dg-error ".E0495." "" { target *-*-* } } + + ignore:: FnMut(&'z isize)>>(Box::new(|z| { + ay = x; + ay = &y; + ay = z; + })); + + ignore::< Box FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { + if false { return x; } // { dg-error ".E0312." "" { target *-*-* } } + if false { return ay; } + return z; + })); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-no-bound-in-argument-cleanup.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-no-bound-in-argument-cleanup.rs new file mode 100644 index 000000000000..6dd362adeac6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-no-bound-in-argument-cleanup.rs @@ -0,0 +1,25 @@ +// run-pass +// pretty-expanded FIXME #23616 + +use std::marker; + +pub struct Foo(marker::PhantomData); + +impl Iterator for Foo { + type Item = T; + + fn next(&mut self) -> Option { + None + } +} + +impl Drop for Foo { + fn drop(&mut self) { + self.next(); + } +} + +pub fn foo<'a>(_: Foo<&'a ()>) {} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-no-variance-from-fn-generics.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-no-variance-from-fn-generics.rs new file mode 100644 index 000000000000..da84dcea994c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-no-variance-from-fn-generics.rs @@ -0,0 +1,45 @@ +// run-pass +#![allow(unused_variables)] +// Issue #12856: a lifetime formal binding introduced by a generic fn +// should not upset the variance inference for actual occurrences of +// that lifetime in type expressions. + + +pub trait HasLife<'a> { + fn dummy(&'a self) { } // just to induce a variance on 'a +} + +trait UseLife01 { + fn refs<'a, H: HasLife<'a>>(&'a self) -> H; +} + +trait UseLife02 { + fn refs<'a, T: 'a, H: HasType<&'a T>>(&'a self) -> H; +} + + +pub trait HasType +{ + fn dummy(&self, t: T) -> T { panic!() } +} + + +trait UseLife03 { + fn refs<'a, H: HasType<&'a T>>(&'a self) -> H where T: 'a; +} + + +// (The functions below were not actually a problem observed during +// fixing of #12856; they just seem like natural tests to put in to +// cover a couple more points in the testing space) + +pub fn top_refs_1<'a, H: HasLife<'a>>(_s: &'a ()) -> H { + unimplemented!() +} + +pub fn top_refs_2<'a, T: 'a, H: HasType<&'a T>>(_s: &'a ()) -> H { + unimplemented!() +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-normalize-in-where-clause-list.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-normalize-in-where-clause-list.rs new file mode 100644 index 000000000000..2fc214a71324 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-normalize-in-where-clause-list.rs @@ -0,0 +1,33 @@ +// Test that we are able to normalize in the list of where-clauses, +// even if `'a: 'b` is required. + +trait Project<'a, 'b> { + type Item; +} + +impl<'a, 'b> Project<'a, 'b> for () +where + 'a: 'b, +{ + type Item = (); +} + +// No error here, we have 'a: 'b. We used to report an error here +// though, see https://github.com/rust-lang/rust/issues/45937. +fn foo<'a: 'b, 'b>() +where + <() as Project<'a, 'b>>::Item: Eq, +{ +} + +// Here we get an error: we need `'a: 'b`. +fn bar<'a, 'b>() +// { dg-error ".E0495." "" { target *-*-* } .-1 } +// { dg-error ".E0495." "" { target *-*-* } .-2 } +where + <() as Project<'a, 'b>>::Item: Eq, +{ +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-nullary-variant.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-nullary-variant.rs new file mode 100644 index 000000000000..be1f34d24fa7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-nullary-variant.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +enum roption<'a> { + a, b(&'a usize) +} + +fn mk(cond: bool, ptr: &usize) -> roption { + if cond {roption::a} else {roption::b(ptr)} +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs new file mode 100644 index 000000000000..8f2ae07ef173 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-region-rev.rs @@ -0,0 +1,21 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + +// check-pass + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +mod rev_variant_struct_region { + struct Foo<'a> { + x: fn(&'a i32), + } + enum Bar<'a,'b> { + V(&'a Foo<'b>) + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-region.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-region.rs new file mode 100644 index 000000000000..d43be2d68359 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-region.rs @@ -0,0 +1,21 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + +// check-pass + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +mod variant_struct_region { + struct Foo<'a> { + x: &'a i32, + } + enum Bar<'a,'b> { + V(&'a Foo<'b>) + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs new file mode 100644 index 000000000000..f47373ff9125 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-type-rev.rs @@ -0,0 +1,21 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + +// check-pass + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +mod variant_struct_type { + struct Foo { + x: fn(T) + } + enum Bar<'a,'b> { + V(&'a Foo<&'b i32>) + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-type.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-type.rs new file mode 100644 index 000000000000..e7ec22ff44d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-enum-type.rs @@ -0,0 +1,21 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + +// check-pass + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +mod variant_struct_type { + struct Foo { + x: T + } + enum Bar<'a,'b> { + V(&'a Foo<&'b i32>) + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs new file mode 100644 index 000000000000..f470d0970eb5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-region-rev.rs @@ -0,0 +1,21 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + +// check-pass + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +mod rev_variant_struct_region { + struct Foo<'a> { + x: fn(&'a i32), + } + struct Bar<'a,'b> { + f: &'a Foo<'b> + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-region.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-region.rs new file mode 100644 index 000000000000..37a7054cab0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-region.rs @@ -0,0 +1,21 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + +// check-pass + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +mod variant_struct_region { + struct Foo<'a> { + x: &'a i32, + } + struct Bar<'a,'b> { + f: &'a Foo<'b> + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs new file mode 100644 index 000000000000..0831fda722ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-type-rev.rs @@ -0,0 +1,21 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + +// check-pass + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +mod rev_variant_struct_type { + struct Foo { + x: fn(T) + } + struct Bar<'a,'b> { + f: &'a Foo<&'b i32> + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-type.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-type.rs new file mode 100644 index 000000000000..72528196ffba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-nominal-type-struct-type.rs @@ -0,0 +1,21 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + +// check-pass + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +mod variant_struct_type { + struct Foo { + x: T + } + struct Bar<'a,'b> { + f: &'a Foo<&'b i32> + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-container-hrtb.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-container-hrtb.rs new file mode 100644 index 000000000000..2d280893e474 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-container-hrtb.rs @@ -0,0 +1,58 @@ +// Test that structs with higher-ranked where clauses don't generate +// "outlives" requirements. Issue #22246. + +// revisions: migrate nll +//[nll]compile-flags: -Z borrowck=mir + +#![allow(dead_code)] + +pub trait TheTrait<'b> { + type TheAssocType; +} + +pub struct TheType<'b> { + m: [fn(&'b()); 0] +} + +impl<'a,'b> TheTrait<'a> for TheType<'b> { + type TheAssocType = &'b (); +} + +pub struct WithHrAssoc + where for<'a> T : TheTrait<'a> +{ + m: [T; 0] +} + +fn with_assoc<'a,'b>() { + // We get an error because 'b:'a does not hold: + + let _: &'a WithHrAssoc> = loop { }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +pub trait TheSubTrait : for<'a> TheTrait<'a> { +} + +impl<'b> TheSubTrait for TheType<'b> { } + +pub struct WithHrAssocSub + where T : TheSubTrait +{ + m: [T; 0] +} + +fn with_assoc_sub<'a,'b>() { + // The error here is just because `'b:'a` must hold for the type + // below to be well-formed, it is not related to the HR relation. + + let _: &'a WithHrAssocSub> = loop { }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-container-wc.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-container-wc.rs new file mode 100644 index 000000000000..b77fe2f698f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-container-wc.rs @@ -0,0 +1,40 @@ +// Test that we are imposing the requirement that every associated +// type of a bound that appears in the where clause on a struct must +// outlive the location in which the type appears, even when the +// constraint is in a where clause not a bound. Issue #22246. + +// revisions: migrate nll +//[nll]compile-flags: -Z borrowck=mir + +#![allow(dead_code)] + +pub trait TheTrait { + type TheAssocType; +} + +pub struct TheType<'b> { + m: [fn(&'b()); 0] +} + +impl<'b> TheTrait for TheType<'b> { + type TheAssocType = &'b (); +} + +pub struct WithAssoc where T : TheTrait { + m: [T; 0] +} + +fn with_assoc<'a,'b>() { + // For this type to be valid, the rules require that all + // associated types of traits that appear in `WithAssoc` must + // outlive 'a. In this case, that means TheType<'b>::TheAssocType, + // which is &'b (), must outlive 'a. + + let _: &'a WithAssoc> = loop { }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-container.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-container.rs new file mode 100644 index 000000000000..4577e1a2c256 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-container.rs @@ -0,0 +1,77 @@ +// Test that we are imposing the requirement that every associated +// type of a bound that appears in the where clause on a struct must +// outlive the location in which the type appears. Issue #22246. + +#![allow(dead_code)] +#![feature(rustc_attrs)] + +pub trait TheTrait { + type TheAssocType; +} + +pub struct TheType<'b> { + m: [fn(&'b()); 0] +} + +impl<'b> TheTrait for TheType<'b> { + type TheAssocType = &'b (); +} + +pub struct WithAssoc { + m: [T; 0] +} + +pub struct WithoutAssoc { + m: [T; 0] +} + +fn with_assoc<'a,'b>() { + // For this type to be valid, the rules require that all + // associated types of traits that appear in `WithAssoc` must + // outlive 'a. In this case, that means TheType<'b>::TheAssocType, + // which is &'b (), must outlive 'a. + + // FIXME (#54943) NLL doesn't enforce WF condition in unreachable code if + // `_x` is changed to `_` + let _x: &'a WithAssoc> = loop { }; +// { dg-error ".E0491." "" { target *-*-* } .-1 } +} + +fn with_assoc1<'a,'b>() where 'b : 'a { + // For this type to be valid, the rules require that all + // associated types of traits that appear in `WithAssoc` must + // outlive 'a. In this case, that means TheType<'b>::TheAssocType, + // which is &'b (), must outlive 'a, so 'b : 'a must hold, and + // that is in the where clauses, so we're fine. + + let _x: &'a WithAssoc> = loop { }; +} + +fn without_assoc<'a,'b>() { + // Here there are no associated types but there is a requirement + // that `'b:'a` holds because the `'b` appears in `TheType<'b>`. + + let _x: &'a WithoutAssoc> = loop { }; +// { dg-error ".E0491." "" { target *-*-* } .-1 } +} + +fn call_with_assoc<'a,'b>() { + // As `with_assoc`, but just checking that we impose the same rule + // on the value supplied for the type argument, even when there is + // no data. + + call::<&'a WithAssoc>>(); +// { dg-error ".E0491." "" { target *-*-* } .-1 } +} + +fn call_without_assoc<'a,'b>() { + // As `without_assoc`, but in a distinct scenario. + + call::<&'a WithoutAssoc>>(); // { dg-error ".E0491." "" { target *-*-* } } +} + +fn call() { } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-hrtype.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-hrtype.rs new file mode 100644 index 000000000000..1113815a24de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-hrtype.rs @@ -0,0 +1,27 @@ +// Test for the outlives relation when applied to a projection on a +// type with bound regions. In this case, we are checking that +// ` fn(&'r T) as TheTrait>::TheType: 'a` If we're not +// careful, we could wind up with a constraint that `'r:'a`, but since +// `'r` is bound, that leads to badness. This test checks that +// everything works. + +// check-pass +#![allow(dead_code)] + +trait TheTrait { + type TheType; +} + +fn wf() { } + +type FnType = for<'r> fn(&'r T); + +fn foo<'a,'b,T>() + where FnType: TheTrait +{ + wf::< as TheTrait>::TheType >(); +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-trait-def.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-trait-def.rs new file mode 100644 index 000000000000..7d05f3392c77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-projection-trait-def.rs @@ -0,0 +1,22 @@ +// Test that `>::Type: 'b`, where `trait Foo<'a> { Type: +// 'a; }`, does not require that `F: 'b`. + +// check-pass +#![allow(dead_code)] + +trait SomeTrait<'a> { + type Type: 'a; +} + +impl<'a: 'c, 'c, T> SomeTrait<'a> for &'c T where T: SomeTrait<'a> { + type Type = >::Type; + // ~~~~~~~~~~~~~~~~~~~~~~~~~~ + // | + // Note that this type must outlive 'a, due to the trait + // definition. If we fall back to OutlivesProjectionComponents + // here, then we would require that `T:'a`, which is too strong. +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-scalar.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-scalar.rs new file mode 100644 index 000000000000..c898ab9fb7f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-outlives-scalar.rs @@ -0,0 +1,14 @@ +// Test that scalar values outlive all regions. +// Rule OutlivesScalar from RFC 1214. + +// check-pass +#![allow(dead_code)] + +struct Foo<'a> { + x: &'a i32, + y: &'static i32 +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-params.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-params.rs new file mode 100644 index 000000000000..189ffeb0ee05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-params.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(unused_parens)] + + +fn region_identity(x: &usize) -> &usize { x } + +fn apply(t: T, f: F) -> T where F: FnOnce(T) -> T { f(t) } + +fn parameterized(x: &usize) -> usize { + let z = apply(x, ({|y| + region_identity(y) + })); + *z +} + +pub fn main() { + let x = 3; + assert_eq!(parameterized(&x), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-pattern-typing-issue-19552.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-pattern-typing-issue-19552.rs new file mode 100644 index 000000000000..531eb95090c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-pattern-typing-issue-19552.rs @@ -0,0 +1,9 @@ +fn assert_static(_t: T) {} + +fn main() { + let line = String::new(); + match [&*line] { // { dg-error ".E0597." "" { target *-*-* } } + [ word ] => { assert_static(word); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-pattern-typing-issue-19997.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-pattern-typing-issue-19997.rs new file mode 100644 index 000000000000..7f15469f2073 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-pattern-typing-issue-19997.rs @@ -0,0 +1,12 @@ +fn main() { + let a0 = 0; + let f = 1; + let mut a1 = &a0; + match (&a1,) { + (&ref b0,) => { + a1 = &f; // { dg-error ".E0506." "" { target *-*-* } } + drop(b0); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-proc-bound-capture.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-proc-bound-capture.rs new file mode 100644 index 000000000000..fbe8664b394f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-proc-bound-capture.rs @@ -0,0 +1,13 @@ +fn borrowed_proc<'a>(x: &'a isize) -> Box(isize) + 'a> { + // This is legal, because the region bound on `proc` + // states that it captures `x`. + Box::new(move|| { *x }) +} + +fn static_proc(x: &isize) -> Box (isize) + 'static> { + // This is illegal, because the region bound on `proc` is 'static. + Box::new(move || { *x }) // { dg-error ".E0759." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-reassign-let-bound-pointer.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-reassign-let-bound-pointer.rs new file mode 100644 index 000000000000..0ad14fd772c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-reassign-let-bound-pointer.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_assignments)] +#![allow(unused_variables)] +// Check that the type checker permits us to reassign `z` which +// started out with a longer lifetime and was reassigned to a shorter +// one (it should infer to be the intersection). + +// pretty-expanded FIXME #23616 + +fn foo(x: &isize) { + let a = 1; + let mut z = x; + z = &a; +} + +pub fn main() { + foo(&1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-reassign-match-bound-pointer.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-reassign-match-bound-pointer.rs new file mode 100644 index 000000000000..c120bee8ab2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-reassign-match-bound-pointer.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(unused_assignments)] +#![allow(unused_variables)] +// Check that the type checker permits us to reassign `z` which +// started out with a longer lifetime and was reassigned to a shorter +// one (it should infer to be the intersection). + +// pretty-expanded FIXME #23616 + +fn foo(x: &isize) { + let a = 1; + match x { + mut z => { + z = &a; + } + } +} + +pub fn main() { + foo(&1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.rs new file mode 100644 index 000000000000..ada6003ae299 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.rs @@ -0,0 +1,9 @@ +// Issue #8624. Test for reborrowing with 3 levels, not just two. + +fn copy_borrowed_ptr<'a, 'b, 'c>(p: &'a mut &'b mut &'c mut isize) -> &'b mut isize { + &mut ***p // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-reborrow-from-shorter-mut-ref.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-reborrow-from-shorter-mut-ref.rs new file mode 100644 index 000000000000..7a9b9530521d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-reborrow-from-shorter-mut-ref.rs @@ -0,0 +1,16 @@ +// Issue #8624. Tests that reborrowing the contents of an `&'b mut` +// pointer which is backed by another `&'a mut` can only be done +// for `'a` (which must be a sublifetime of `'b`). + +fn copy_borrowed_ptr<'a, 'b>(p: &'a mut &'b mut isize) -> &'b mut isize { + &mut **p // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { + let mut x = 1; + let mut y = &mut x; + let z = copy_borrowed_ptr(&mut y); + *y += 1; + *z += 1; +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-ref-in-fn-arg.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-ref-in-fn-arg.rs new file mode 100644 index 000000000000..aaf79f7cbe57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-ref-in-fn-arg.rs @@ -0,0 +1,15 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] + +fn arg_item(box ref x: Box) -> &'static isize { + x // { dg-error ".E0515." "" { target *-*-* } } +} + +fn with(f: F) -> R where F: FnOnce(Box) -> R { f(box 3) } + +fn arg_closure() -> &'static isize { + with(|box ref x| x) // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-refcell.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-refcell.rs new file mode 100644 index 000000000000..6090b3f1f134 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-refcell.rs @@ -0,0 +1,46 @@ +// run-pass +// This is a regression test for something that only came up while +// attempting to bootstrap librustc with new destructor lifetime +// semantics. + + +use std::collections::HashMap; +use std::cell::RefCell; + +// This version does not yet work (associated type issues)... +#[cfg(cannot_use_this_yet)] +fn foo<'a>(map: RefCell>) { + let one = [1]; + assert_eq!(map.borrow().get("one"), Some(&one[..])); +} + +#[cfg(cannot_use_this_yet_either)] +// ... and this version does not work (the lifetime of `one` is +// supposed to match the lifetime `'a`) ... +fn foo<'a>(map: RefCell>) { + let one = [1]; + assert_eq!(map.borrow().get("one"), Some(&&one[..])); +} + +#[cfg(all(not(cannot_use_this_yet),not(cannot_use_this_yet_either)))] +fn foo<'a>(map: RefCell>) { + // ...so instead we walk through the trivial slice and make sure + // it contains the element we expect. + + for (i, &x) in map.borrow().get("one").unwrap().iter().enumerate() { + assert_eq!((i, x), (0, 1)); + } +} + +fn main() { + let zer = [0]; + let one = [1]; + let two = [2]; + let mut map = HashMap::new(); + map.insert("zero", &zer[..]); + map.insert("one", &one[..]); + map.insert("two", &two[..]); + let map = RefCell::new(map); + foo(map); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs new file mode 100644 index 000000000000..b977cd63e8ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-relate-bound-regions-on-closures-to-inference-variables.rs @@ -0,0 +1,60 @@ +// run-pass +#![allow(dead_code)] +// Test that this fairly specialized, but also reasonable, pattern +// typechecks. The pattern involves regions bound in closures that +// wind up related to inference variables. +// +// NB. Changes to the region implementations have broken this pattern +// a few times, but it happens to be used in the compiler so those +// changes were caught. However, those uses in the compiler could +// easily get changed or refactored away in the future. + +#![feature(box_syntax)] + +struct Ctxt<'tcx> { + x: &'tcx Vec +} + +struct Foo<'a,'tcx:'a> { + cx: &'a Ctxt<'tcx>, +} + +impl<'a,'tcx> Foo<'a,'tcx> { + fn bother(&mut self) -> isize { + self.elaborate_bounds(Box::new(|this| { + // (*) Here: type of `this` is `&'f0 Foo<&'f1, '_2>`, + // where `'f0` and `'f1` are fresh, free regions that + // result from the bound regions on the closure, and `'2` + // is a region inference variable created by the call. Due + // to the constraints on the type, we find that `'_2 : 'f1 + // + 'f2` must hold (and can be assumed by the callee). + // Region inference has to do some clever stuff to avoid + // inferring `'_2` to be `'static` in this case, because + // it is created outside the closure but then related to + // regions bound by the closure itself. See the + // `region_constraints.rs` file (and the `givens` field, in + // particular) for more details. + this.foo() + })) + } + + fn foo(&mut self) -> isize { + 22 + } + + fn elaborate_bounds( + &mut self, + mut mk_cand: Box FnMut(&mut Foo<'b, 'tcx>) -> isize>) + -> isize + { + mk_cand(self) + } +} + +fn main() { + let v = vec![]; + let cx = Ctxt { x: &v }; + let mut foo = Foo { cx: &cx }; + assert_eq!(foo.bother(), 22); // just so the code is not dead, basically +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-ret-borrowed-1.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-ret-borrowed-1.rs new file mode 100644 index 000000000000..34987f28aa09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-ret-borrowed-1.rs @@ -0,0 +1,18 @@ +// Similar to regions-ret-borrowed.rs, but using a named lifetime. At +// some point regions-ret-borrowed reported an error but this file did +// not, due to special hardcoding around the anonymous region. + +fn with(f: F) -> R where F: for<'a> FnOnce(&'a isize) -> R { + f(&3) +} + +fn return_it<'a>() -> &'a isize { + with(|o| o) +// { dg-error ".E0495." "" { target *-*-* } .-1 } +} + +fn main() { + let x = return_it(); + println!("foo={}", *x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-ret-borrowed.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-ret-borrowed.rs new file mode 100644 index 000000000000..d4362a68f8cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-ret-borrowed.rs @@ -0,0 +1,21 @@ +// Ensure that you cannot use generic types to return a region outside +// of its bound. Here, in the `return_it()` fn, we call with() but +// with R bound to &isize from the return_it. Meanwhile, with() +// provides a value that is only good within its own stack frame. This +// used to successfully compile because we failed to account for the +// fact that fn(x: &isize) rebound the region &. + +fn with(f: F) -> R where F: FnOnce(&isize) -> R { + f(&3) +} + +fn return_it<'a>() -> &'a isize { + with(|o| o) +// { dg-error ".E0495." "" { target *-*-* } .-1 } +} + +fn main() { + let x = return_it(); + println!("foo={}", *x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-ret.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-ret.rs new file mode 100644 index 000000000000..11aa07561437 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-ret.rs @@ -0,0 +1,9 @@ +fn id(x: T) -> T { x } + +fn f(_x: &isize) -> &isize { + return &id(3); // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-return-interior-of-option.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-return-interior-of-option.rs new file mode 100644 index 000000000000..0d23d0cadd78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-return-interior-of-option.rs @@ -0,0 +1,25 @@ +// run-pass + +fn get(opt: &Option) -> &T { + match *opt { + Some(ref v) => v, + None => panic!("none") + } +} + +pub fn main() { + let mut x = Some(23); + + { + let y = get(&x); + assert_eq!(*y, 23); + } + + x = Some(24); + + { + let y = get(&x); + assert_eq!(*y, 24); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-return-ref-to-upvar-issue-17403.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-return-ref-to-upvar-issue-17403.rs new file mode 100644 index 000000000000..716deea115ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-return-ref-to-upvar-issue-17403.rs @@ -0,0 +1,12 @@ +// Test that closures cannot subvert aliasing restrictions + +fn main() { + // Unboxed closure case + { + let mut x = 0; + let mut f = || &mut x; // { dg-error "" "" { target *-*-* } } + let x = f(); + let y = f(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-return-stack-allocated-vec.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-return-stack-allocated-vec.rs new file mode 100644 index 000000000000..5549cde67aa2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-return-stack-allocated-vec.rs @@ -0,0 +1,11 @@ +// Test that we cannot return a stack allocated slice + +fn function(x: isize) -> &'static [isize] { + &[x] // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() { + let x = function(1); + let y = x[0]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-scope-chain-example.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-scope-chain-example.rs new file mode 100644 index 000000000000..de993a134f1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-scope-chain-example.rs @@ -0,0 +1,44 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// This is an example where the older inference algorithm failed. The +// specifics of why it failed are somewhat, but not entirely, tailed +// to the algorithm. Ultimately the problem is that when computing the +// mutual supertype of both sides of the `if` it would be faced with a +// choice of tightening bounds or unifying variables and it took the +// wrong path. The new algorithm avoids this problem and hence this +// example typechecks correctly. + +// pretty-expanded FIXME #23616 + +enum ScopeChain<'a> { + Link(Scope<'a>), + End +} + +type Scope<'a> = &'a ScopeChain<'a>; + +struct OuterContext; + +struct Context<'a> { + foo: &'a OuterContext +} + +impl<'a> Context<'a> { + fn foo(&mut self, scope: Scope) { + let link = if 1 < 2 { + let l = ScopeChain::Link(scope); + self.take_scope(&l); + l + } else { + ScopeChain::Link(scope) + }; + self.take_scope(&link); + } + + fn take_scope(&mut self, x: Scope) { + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-self-impls.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-self-impls.rs new file mode 100644 index 000000000000..ba642059223b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-self-impls.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(non_camel_case_types)] + +struct Clam<'a> { + chowder: &'a isize +} + +trait get_chowder<'a> { + fn get_chowder(&self) -> &'a isize; +} + +impl<'a> get_chowder<'a> for Clam<'a> { + fn get_chowder(&self) -> &'a isize { return self.chowder; } +} + +pub fn main() { + let clam = Clam { chowder: &3 }; + println!("{}", *clam.get_chowder()); + clam.get_chowder(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-self-in-enums.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-self-in-enums.rs new file mode 100644 index 000000000000..eca9d1635fcd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-self-in-enums.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(unused_mut)] +#![allow(non_camel_case_types)] + +enum int_wrapper<'a> { + int_wrapper_ctor(&'a isize) +} + +pub fn main() { + let x = 3; + let y = int_wrapper::int_wrapper_ctor(&x); + let mut z : &isize; + match y { + int_wrapper::int_wrapper_ctor(zz) => { z = zz; } + } + println!("{}", *z); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-simple.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-simple.rs new file mode 100644 index 000000000000..9237716173c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-simple.rs @@ -0,0 +1,8 @@ +// run-pass +pub fn main() { + let mut x: isize = 3; + let y: &mut isize = &mut x; + *y = 5; + println!("{}", *y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-static-bound-rpass.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-static-bound-rpass.rs new file mode 100644 index 000000000000..ea70c902dcb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-static-bound-rpass.rs @@ -0,0 +1,20 @@ +// run-pass +fn invariant_id<'a,'b>(t: &'b mut &'static ()) -> &'b mut &'a () + where 'a: 'static { t } +fn static_id<'a>(t: &'a ()) -> &'static () + where 'a: 'static { t } +fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static () + where 'a: 'b, 'b: 'static { t } +fn ref_id<'a>(t: &'a ()) -> &'a () where 'static: 'a { t } + +static UNIT: () = (); + +fn main() +{ + let mut val : &'static () = &UNIT; + invariant_id(&mut val); + static_id(val); + static_id_indirect(val); + ref_id(val); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-static-bound.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-static-bound.rs new file mode 100644 index 000000000000..637d68ba1fd7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-static-bound.rs @@ -0,0 +1,21 @@ +// revisions: migrate nll +//[nll] compile-flags:-Zborrowck=mir + +fn static_id<'a,'b>(t: &'a ()) -> &'static () + where 'a: 'static { t } +fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static () + where 'a: 'b, 'b: 'static { t } +fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { + t // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn error(u: &(), v: &()) { + static_id(&u); // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + static_id_indirect(&v); // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-static-closure.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-static-closure.rs new file mode 100644 index 000000000000..e4cf73a2c8a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-static-closure.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(non_camel_case_types)] + +struct closure_box<'a> { + cl: Box, +} + +fn box_it<'a>(x: Box) -> closure_box<'a> { + closure_box {cl: x} +} + +fn call_static_closure(mut cl: closure_box<'static>) { + (cl.cl)(); +} + +pub fn main() { + let cl_box = box_it(Box::new(|| println!("Hello, world!"))); + call_static_closure(cl_box); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-steal-closure.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-steal-closure.rs new file mode 100644 index 000000000000..dcf9d91831a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-steal-closure.rs @@ -0,0 +1,18 @@ +#![feature(fn_traits)] + +struct ClosureBox<'a> { + cl: Box, +} + +fn box_it<'r>(x: Box) -> ClosureBox<'r> { + ClosureBox {cl: x} +} + +fn main() { + let mut cl_box = { + let mut i = 3; + box_it(Box::new(|| i += 1)) // { dg-error ".E0597." "" { target *-*-* } } + }; + cl_box.cl.call_mut(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-trait-1.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-trait-1.rs new file mode 100644 index 000000000000..a89e8e954671 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-trait-1.rs @@ -0,0 +1,34 @@ +// check-pass + +struct Ctxt { + v: usize, +} + +trait GetCtxt { + // Here the `&` is bound in the method definition: + fn get_ctxt(&self) -> &Ctxt; +} + +struct HasCtxt<'a> { + c: &'a Ctxt, +} + +impl<'a> GetCtxt for HasCtxt<'a> { + // Ok: Have implied bound of WF(&'b HasCtxt<'a>) + // so know 'a: 'b + // so know &'a Ctxt <: &'b Ctxt + fn get_ctxt<'b>(&'b self) -> &'a Ctxt { + self.c + } +} + +fn get_v(gc: Box) -> usize { + gc.get_ctxt().v +} + +fn main() { + let ctxt = Ctxt { v: 22 }; + let hc = HasCtxt { c: &ctxt }; + assert_eq!(get_v(Box::new(hc) as Box), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-trait-object-1.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-trait-object-1.rs new file mode 100644 index 000000000000..ff0764e5082e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-trait-object-1.rs @@ -0,0 +1,36 @@ +// run-pass +// This is a regression test for something that only came up while +// attempting to bootstrap librustc_ast; it is adapted from +// `rustc_ast::ext::tt::generic_extension`. + + +pub struct E<'a> { + pub f: &'a u8, +} +impl<'b> E<'b> { + pub fn m(&self) -> &'b u8 { self.f } +} + +pub struct P<'c> { + pub g: &'c u8, +} +pub trait M { + fn n(&self) -> u8; +} +impl<'d> M for P<'d> { + fn n(&self) -> u8 { *self.g } +} + +fn extension<'e>(x: &'e E<'e>) -> Box { + loop { + let p = P { g: x.m() }; + return Box::new(p) as Box; + } +} + +fn main() { + let w = E { f: &10 }; + let o = extension(&w); + assert_eq!(o.n(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-trait-object-subtyping.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-trait-object-subtyping.rs new file mode 100644 index 000000000000..a6b90c94aa6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-trait-object-subtyping.rs @@ -0,0 +1,26 @@ +trait Dummy { fn dummy(&self); } + +fn foo1<'a:'b,'b>(x: &'a mut (dyn Dummy+'a)) -> &'b mut (dyn Dummy+'b) { + // Here, we are able to coerce + x +} + +fn foo2<'a:'b,'b>(x: &'b mut (dyn Dummy+'a)) -> &'b mut (dyn Dummy+'b) { + // Here, we are able to coerce + x +} + +fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { + // Without knowing 'a:'b, we can't coerce + x // { dg-error ".E0495." "" { target *-*-* } } +// { dg-error ".E0495." "" { target *-*-* } .-1 } +} + +struct Wrapper(T); +fn foo4<'a:'b,'b>(x: Wrapper<&'a mut dyn Dummy>) -> Wrapper<&'b mut dyn Dummy> { + // We can't coerce because it is packed in `Wrapper` + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-trait-variance.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-trait-variance.rs new file mode 100644 index 000000000000..374234adf361 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-trait-variance.rs @@ -0,0 +1,45 @@ +#![feature(box_syntax)] + +// Issue #12470. + +trait X { + fn get_i(&self) -> isize; +} + +struct B { + i: isize +} + +impl X for B { + fn get_i(&self) -> isize { + self.i + } +} + +impl Drop for B { + fn drop(&mut self) { + println!("drop"); + } +} + +struct A<'r> { + p: &'r (dyn X + 'r) +} + +fn make_a(p: &dyn X) -> A { + A{p:p} +} + +fn make_make_a<'a>() -> A<'a> { + let b: Box = box B { + i: 1, + }; + let bb: &B = &*b; + make_a(bb) // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() { + let a = make_make_a(); + println!("{}", a.p.get_i()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-undeclared.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-undeclared.rs new file mode 100644 index 000000000000..85d79d84b018 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-undeclared.rs @@ -0,0 +1,14 @@ +static c_x: &'blk isize = &22; // { dg-error ".E0261." "" { target *-*-* } } + +enum EnumDecl { + Foo(&'a isize), // { dg-error ".E0261." "" { target *-*-* } } + Bar(&'a isize), // { dg-error ".E0261." "" { target *-*-* } } +} + +fn fnDecl(x: &'a isize, // { dg-error ".E0261." "" { target *-*-* } } + y: &'a isize) // { dg-error ".E0261." "" { target *-*-* } } +{} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-var-type-out-of-scope.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-var-type-out-of-scope.rs new file mode 100644 index 000000000000..6e8fbb874140 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-var-type-out-of-scope.rs @@ -0,0 +1,15 @@ +fn id(x: T) -> T { x } + +fn foo(cond: bool) { + // Here we will infer a type that uses the + // region of the if stmt then block: + let mut x; + + if cond { + x = &id(3); // { dg-error ".E0716." "" { target *-*-* } } + assert_eq!(*x, 3); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-variance-contravariant-use-contravariant.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-contravariant-use-contravariant.rs new file mode 100644 index 000000000000..2f82503f7941 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-contravariant-use-contravariant.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test that a type which is contravariant with respect to its region +// parameter compiles successfully when used in a contravariant way. +// +// Note: see compile-fail/variance-regions-*.rs for the tests that check that the +// variance inference works in the first place. + +// pretty-expanded FIXME #23616 + +struct Contravariant<'a> { + f: &'a isize +} + +fn use_<'a>(c: Contravariant<'a>) { + let x = 3; + + // 'b winds up being inferred to this call. + // Contravariant<'a> <: Contravariant<'call> is true + // if 'call <= 'a, which is true, so no error. + collapse(&x, c); + + fn collapse<'b>(x: &'b isize, c: Contravariant<'b>) { } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.rs new file mode 100644 index 000000000000..4f95fbb1dac1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.rs @@ -0,0 +1,29 @@ +// Test that a type which is covariant with respect to its region +// parameter yields an error when used in a contravariant way. +// +// Note: see variance-regions-*.rs for the tests that check that the +// variance inference works in the first place. + +// `S` is contravariant with respect to both parameters. +struct S<'a, 'b> { + f: &'a isize, + g: &'b isize, +} + +fn use_<'short,'long>(c: S<'long, 'short>, + s: &'short isize, + l: &'long isize, + _where:Option<&'short &'long ()>) { + + let _: S<'long, 'short> = c; // OK + let _: S<'short, 'short> = c; // OK + + // Test whether S<_,'short> <: S<_,'long>. Since + // 'short <= 'long, this would be true if the Contravariant type were + // covariant with respect to its parameter 'a. + + let _: S<'long, 'long> = c; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-variance-contravariant-use-covariant.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-contravariant-use-covariant.rs new file mode 100644 index 000000000000..9d8cb8e514a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-contravariant-use-covariant.rs @@ -0,0 +1,27 @@ +// Test that a type which is covariant with respect to its region +// parameter yields an error when used in a contravariant way. +// +// Note: see variance-regions-*.rs for the tests that check that the +// variance inference works in the first place. + +// This is contravariant with respect to 'a, meaning that +// Contravariant<'long> <: Contravariant<'short> iff +// 'short <= 'long +struct Contravariant<'a> { + f: &'a isize +} + +fn use_<'short,'long>(c: Contravariant<'short>, + s: &'short isize, + l: &'long isize, + _where:Option<&'short &'long ()>) { + + // Test whether Contravariant<'short> <: Contravariant<'long>. Since + // 'short <= 'long, this would be true if the Contravariant type were + // covariant with respect to its parameter 'a. + + let _: Contravariant<'long> = c; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-variance-covariant-use-contravariant.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-covariant-use-contravariant.rs new file mode 100644 index 000000000000..bce9412ce675 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-covariant-use-contravariant.rs @@ -0,0 +1,27 @@ +// Test that a type which is covariant with respect to its region +// parameter yields an error when used in a contravariant way. +// +// Note: see variance-regions-*.rs for the tests that check that the +// variance inference works in the first place. + +// This is covariant with respect to 'a, meaning that +// Covariant<'foo> <: Covariant<'static> because +// 'foo <= 'static +struct Covariant<'a> { + f: extern "Rust" fn(&'a isize) +} + +fn use_<'short,'long>(c: Covariant<'long>, + s: &'short isize, + l: &'long isize, + _where:Option<&'short &'long ()>) { + + // Test whether Covariant<'long> <: Covariant<'short>. Since + // 'short <= 'long, this would be true if the Covariant type were + // contravariant with respect to its parameter 'a. + + let _: Covariant<'short> = c; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-variance-covariant-use-covariant.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-covariant-use-covariant.rs new file mode 100644 index 000000000000..85d0dedada34 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-covariant-use-covariant.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] +// Test that a type which is covariant with respect to its region +// parameter is successful when used in a covariant way. +// +// Note: see compile-fail/variance-regions-*.rs for the tests that +// check that the variance inference works in the first place. + +// This is covariant with respect to 'a, meaning that +// Covariant<'foo> <: Covariant<'static> because +// 'foo <= 'static +// pretty-expanded FIXME #23616 + +struct Covariant<'a> { + f: extern "Rust" fn(&'a isize) +} + +fn use_<'a>(c: Covariant<'a>) { + // OK Because Covariant<'a> <: Covariant<'static> iff 'a <= 'static + let _: Covariant<'static> = c; +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-variance-invariant-use-contravariant.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-invariant-use-contravariant.rs new file mode 100644 index 000000000000..636d5c0986a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-invariant-use-contravariant.rs @@ -0,0 +1,24 @@ +// Test that an invariant region parameter used in a contravariant way +// yields an error. +// +// Note: see variance-regions-*.rs for the tests that check that the +// variance inference works in the first place. + +struct Invariant<'a> { + f: &'a mut &'a isize +} + +fn use_<'short,'long>(c: Invariant<'long>, + s: &'short isize, + l: &'long isize, + _where:Option<&'short &'long ()>) { + + // Test whether Invariant<'long> <: Invariant<'short>. Since + // 'short <= 'long, this would be true if the Invariant type were + // contravariant with respect to its parameter 'a. + + let _: Invariant<'short> = c; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-variance-invariant-use-covariant.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-invariant-use-covariant.rs new file mode 100644 index 000000000000..a7706b19470d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-variance-invariant-use-covariant.rs @@ -0,0 +1,21 @@ +// Test that a type which is invariant with respect to its region +// parameter used in a covariant way yields an error. +// +// Note: see variance-regions-*.rs for the tests that check that the +// variance inference works in the first place. + +struct Invariant<'a> { + f: &'a mut &'a isize +} + +fn use_<'b>(c: Invariant<'b>) { + + // For this assignment to be legal, Invariant<'b> <: Invariant<'static>. + // Since 'b <= 'static, this would be true if Invariant were covariant + // with respect to its parameter 'a. + + let _: Invariant<'static> = c; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/regions-wf-trait-object.rs b/gcc/testsuite/rust/rustc/ui/regions/regions-wf-trait-object.rs new file mode 100644 index 000000000000..3ebda3e4028c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/regions-wf-trait-object.rs @@ -0,0 +1,11 @@ +// Check that the explicit lifetime bound (`'b`, in this example) must +// outlive all the superbound from the trait (`'a`, in this example). + +trait TheTrait<'t>: 't { } + +struct Foo<'a,'b> { + x: Box+'b> // { dg-error ".E0478." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/regions/type-param-outlives-reempty-issue-74429-2.rs b/gcc/testsuite/rust/rustc/ui/regions/type-param-outlives-reempty-issue-74429-2.rs new file mode 100644 index 000000000000..7f8b778f84f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/type-param-outlives-reempty-issue-74429-2.rs @@ -0,0 +1,67 @@ +// Regression test for #74429, where we didn't think that a type parameter +// outlived `ReEmpty`. + +// check-pass + +use std::marker::PhantomData; +use std::ptr::NonNull; + +pub unsafe trait RawData { + type Elem; +} + +unsafe impl RawData for OwnedRepr { + type Elem = A; +} + +unsafe impl<'a, A> RawData for ViewRepr<&'a A> { + type Elem = A; +} + +pub struct OwnedRepr { + ptr: PhantomData, +} + +// these Copy impls are not necessary for the repro, but allow the code to compile without error +// on 1.44.1 +#[derive(Copy, Clone)] +pub struct ViewRepr { + life: PhantomData, +} + +#[derive(Copy, Clone)] +pub struct ArrayBase +where + S: RawData, +{ + ptr: NonNull, +} + +pub type Array = ArrayBase>; + +pub type ArrayView<'a, A> = ArrayBase>; + +impl ArrayBase +where + S: RawData, +{ + pub fn index_axis(&self) -> ArrayView<'_, A> { + unimplemented!() + } + + pub fn axis_iter<'a>(&'a self) -> std::iter::Empty<&'a A> { + unimplemented!() + } +} + +pub fn x(a: Array) { + // drop just avoids a must_use warning + drop((0..1).filter(|_| true)); + let y = a.index_axis(); + a.axis_iter().for_each(|_| { + drop(y); + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/regions/type-param-outlives-reempty-issue-74429.rs b/gcc/testsuite/rust/rustc/ui/regions/type-param-outlives-reempty-issue-74429.rs new file mode 100644 index 000000000000..c5f1b08aecde --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/regions/type-param-outlives-reempty-issue-74429.rs @@ -0,0 +1,36 @@ +// Regression test for #74429, where we didn't think that a type parameter +// outlived `ReEmpty`. + +// check-pass + +use std::marker::PhantomData; + +fn apply(_: T, _: F) {} + +#[derive(Clone, Copy)] +struct Invariant { + t: T, + p: PhantomData T>, +} + +fn verify_reempty(x: T) { + // r is inferred to have type `Invariant<&ReEmpty(U0) T>` + let r = Invariant { t: &x, p: PhantomData }; + // Creates a new universe, all variables from now on are in `U1`, say. + let _: fn(&()) = |_| {}; + // Closure parameter is of type `&ReEmpty(U1) T`, so the closure has an implied + // bound of `T: ReEmpty(U1)` + apply(&x, |_| { + // Requires `typeof(r)` is well-formed, i.e. `T: ReEmpty(U0)`. If we + // only have the implied bound from the closure parameter to use this + // requires `ReEmpty(U1): ReEmpty(U0)`, which isn't true so we reported + // an error. + // + // This doesn't happen any more because we ensure that `T: ReEmpty(U0)` + // is an implicit bound for all type parameters. + drop(r); + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/reify-intrinsic.rs b/gcc/testsuite/rust/rustc/ui/reify-intrinsic.rs new file mode 100644 index 000000000000..438ac436e79b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reify-intrinsic.rs @@ -0,0 +1,16 @@ +// check-fail + +#![feature(intrinsics)] + +fn a() { + let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::transmute; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn b() { + let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize; +// { dg-error ".E0606." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/reject-specialized-drops-8142.rs b/gcc/testsuite/rust/rustc/ui/reject-specialized-drops-8142.rs new file mode 100644 index 000000000000..7d7deba3a513 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reject-specialized-drops-8142.rs @@ -0,0 +1,71 @@ +// Issue 8142: Test that Drop impls cannot be specialized beyond the +// predicates attached to the type definition itself. + +trait Bound { fn foo(&self) { } } +struct K<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 } +struct L<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 } +struct M<'m> { x: &'m i8 } +struct N<'n> { x: &'n i8 } +struct O { x: *const To } +struct P { x: *const Tp } +struct Q { x: *const Tq } +struct R { x: *const Tr } +struct S { x: *const Ts } +struct T<'t,Ts:'t> { x: &'t Ts } +struct U; +struct V { x: *const Tva, y: *const Tvb } +struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } + +enum Enum { Variant(T) } +struct TupleStruct(T); +union Union { f: T } + +impl<'al,'adds_bnd:'al> Drop for K<'al,'adds_bnd> { // REJECT +// { dg-error ".E0367." "" { target *-*-* } .-1 } + fn drop(&mut self) { } } + +impl<'al,'adds_bnd> Drop for L<'al,'adds_bnd> where 'adds_bnd:'al { // REJECT +// { dg-error ".E0367." "" { target *-*-* } .-1 } + fn drop(&mut self) { } } + +impl<'ml> Drop for M<'ml> { fn drop(&mut self) { } } // ACCEPT + +impl Drop for N<'static> { fn drop(&mut self) { } } // REJECT +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + +impl Drop for O { fn drop(&mut self) { } } // ACCEPT + +impl Drop for P { fn drop(&mut self) { } } // REJECT +// { dg-error ".E0366." "" { target *-*-* } .-1 } + +impl Drop for Q { fn drop(&mut self) { } } // REJECT +// { dg-error ".E0367." "" { target *-*-* } .-1 } + +impl<'rbnd,AddsRBnd:'rbnd> Drop for R { fn drop(&mut self) { } } // REJECT +// { dg-error ".E0367." "" { target *-*-* } .-1 } + +impl Drop for S { fn drop(&mut self) { } } // ACCEPT + +impl<'t,Bt:'t> Drop for T<'t,Bt> { fn drop(&mut self) { } } // ACCEPT + +impl Drop for U { fn drop(&mut self) { } } // ACCEPT + +impl Drop for V { fn drop(&mut self) { } } // REJECT +// { dg-error ".E0366." "" { target *-*-* } .-1 } + +impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT +// { dg-error ".E0495." "" { target *-*-* } .-1 } + +impl Drop for Enum { fn drop(&mut self) { } } // REJECT +// { dg-error ".E0367." "" { target *-*-* } .-1 } + +impl Drop for TupleStruct { fn drop(&mut self) { } } // REJECT +// { dg-error ".E0367." "" { target *-*-* } .-1 } + +impl Drop for Union { fn drop(&mut self) { } } // REJECT +// { dg-error ".E0367." "" { target *-*-* } .-1 } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/removing-extern-crate.rs b/gcc/testsuite/rust/rustc/ui/removing-extern-crate.rs new file mode 100644 index 000000000000..4ff2e861db8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/removing-extern-crate.rs @@ -0,0 +1,17 @@ +// edition:2018 +// aux-build:removing-extern-crate.rs +// run-rustfix +// check-pass + +#![warn(rust_2018_idioms)] + +extern crate removing_extern_crate as foo; // { dg-warning "" "" { target *-*-* } } +extern crate core; // { dg-warning "" "" { target *-*-* } } + +mod another { + extern crate removing_extern_crate as foo; // { dg-warning "" "" { target *-*-* } } + extern crate core; // { dg-warning "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/repeat-expr-in-static.rs b/gcc/testsuite/rust/rustc/ui/repeat-expr-in-static.rs new file mode 100644 index 000000000000..f7ed571a6664 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repeat-expr-in-static.rs @@ -0,0 +1,9 @@ +// run-pass + +static FOO: [isize; 4] = [32; 4]; +static BAR: [isize; 4] = [32, 32, 32, 32]; + +pub fn main() { + assert_eq!(FOO, BAR); +} + diff --git a/gcc/testsuite/rust/rustc/ui/repeat-to-run-dtor-twice.rs b/gcc/testsuite/rust/rustc/ui/repeat-to-run-dtor-twice.rs new file mode 100644 index 000000000000..45b82157cc75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repeat-to-run-dtor-twice.rs @@ -0,0 +1,20 @@ +// Tests that one can't run a destructor twice with the repeated vector +// literal syntax. + +struct Foo { + x: isize, + +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("Goodbye!"); + } +} + +fn main() { + let a = Foo { x: 3 }; + let _ = [ a; 5 ]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/repeat_count.rs b/gcc/testsuite/rust/rustc/ui/repeat_count.rs new file mode 100644 index 000000000000..2a18f9be8621 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repeat_count.rs @@ -0,0 +1,35 @@ +// Regression test for issue #3645 + +fn main() { + let n = 1; + let a = [0; n]; +// { dg-error ".E0435." "" { target *-*-* } .-1 } + let b = [0; ()]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let c = [0; true]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let d = [0; 0.5]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let e = [0; "foo"]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let f = [0; -4_isize]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let f = [0_usize; -1_isize]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + let f = [0; 4u8]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + struct G { + g: (), + } + let g = [0; G { g: () }]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/repeat_count_const_in_async_fn.rs b/gcc/testsuite/rust/rustc/ui/repeat_count_const_in_async_fn.rs new file mode 100644 index 000000000000..59f62fab4bad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repeat_count_const_in_async_fn.rs @@ -0,0 +1,11 @@ +// check-pass +// edition:2018 +// compile-flags: --crate-type=lib + +pub async fn test() { + const C: usize = 4; + foo(&mut [0u8; C]).await; +} + +async fn foo(_: &mut [u8]) {} + diff --git a/gcc/testsuite/rust/rustc/ui/repr.rs b/gcc/testsuite/rust/rustc/ui/repr.rs new file mode 100644 index 000000000000..67c8d4be5671 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repr.rs @@ -0,0 +1,14 @@ +#[repr] // { dg-error "" "" { target *-*-* } } +struct _A {} + +#[repr = "B"] // { dg-error "" "" { target *-*-* } } +struct _B {} + +#[repr = "C"] // { dg-error "" "" { target *-*-* } } +struct _C {} + +#[repr(C)] +struct _D {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/repr/feature-gate-no-niche.rs b/gcc/testsuite/rust/rustc/ui/repr/feature-gate-no-niche.rs new file mode 100644 index 000000000000..6ae559d055d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repr/feature-gate-no-niche.rs @@ -0,0 +1,21 @@ +use std::num::NonZeroU8 as N8; +use std::num::NonZeroU16 as N16; + +#[repr(no_niche)] +pub struct Cloaked(N16); +// { dg-error ".E0658." "" { target *-*-* } .-2 } + +#[repr(transparent, no_niche)] +pub struct Shadowy(N16); +// { dg-error ".E0658." "" { target *-*-* } .-2 } + +#[repr(no_niche)] +pub enum Cloaked1 { _A(N16), } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + +#[repr(no_niche)] +pub enum Cloaked2 { _A(N16), _B(u8, N8) } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/repr/repr-align-assign.rs b/gcc/testsuite/rust/rustc/ui/repr/repr-align-assign.rs new file mode 100644 index 000000000000..053025aeb0d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repr/repr-align-assign.rs @@ -0,0 +1,14 @@ +// run-rustfix + +#![allow(dead_code)] + +#[repr(align=8)] // { dg-error ".E0693." "" { target *-*-* } } +// { dg-error ".E0693." "" { target *-*-* } .-2 } +struct A(u64); + +#[repr(align="8")] // { dg-error ".E0693." "" { target *-*-* } } +// { dg-error ".E0693." "" { target *-*-* } .-2 } +struct B(u64); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/repr/repr-align.rs b/gcc/testsuite/rust/rustc/ui/repr/repr-align.rs new file mode 100644 index 000000000000..516922be45b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repr/repr-align.rs @@ -0,0 +1,34 @@ +#![allow(dead_code)] + +#[repr(align(16.0))] // { dg-error ".E0589." "" { target *-*-* } } +// { dg-error ".E0589." "" { target *-*-* } .-2 } +struct S0(i32); + +#[repr(align(15))] // { dg-error ".E0589." "" { target *-*-* } } +// { dg-error ".E0589." "" { target *-*-* } .-2 } +struct S1(i32); + +#[repr(align(4294967296))] // { dg-error ".E0589." "" { target *-*-* } } +// { dg-error ".E0589." "" { target *-*-* } .-2 } +struct S2(i32); + +#[repr(align(536870912))] // ok: this is the largest accepted alignment +struct S3(i32); + +#[repr(align(16.0))] // { dg-error ".E0589." "" { target *-*-* } } +// { dg-error ".E0589." "" { target *-*-* } .-2 } +enum E0 { A, B } + +#[repr(align(15))] // { dg-error ".E0589." "" { target *-*-* } } +// { dg-error ".E0589." "" { target *-*-* } .-2 } +enum E1 { A, B } + +#[repr(align(4294967296))] // { dg-error ".E0589." "" { target *-*-* } } +// { dg-error ".E0589." "" { target *-*-* } .-2 } +enum E2 { A, B } + +#[repr(align(536870912))] // ok: this is the largest accepted alignment +enum E3 { A, B } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/repr/repr-disallow-on-variant.rs b/gcc/testsuite/rust/rustc/ui/repr/repr-disallow-on-variant.rs new file mode 100644 index 000000000000..8f41a8fbad26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repr/repr-disallow-on-variant.rs @@ -0,0 +1,10 @@ +struct Test; + +enum Foo { + #[repr(u8)] +// { dg-error ".E0517." "" { target *-*-* } .-1 } + Variant, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/repr/repr-no-niche-inapplicable-to-unions.rs b/gcc/testsuite/rust/rustc/ui/repr/repr-no-niche-inapplicable-to-unions.rs new file mode 100644 index 000000000000..11ba949b8da5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repr/repr-no-niche-inapplicable-to-unions.rs @@ -0,0 +1,15 @@ +#![feature(no_niche)] + +use std::num::NonZeroU8 as N8; +use std::num::NonZeroU16 as N16; + +#[repr(no_niche)] +pub union Cloaked1 { _A: N16 } +// { dg-error ".E0517." "" { target *-*-* } .-2 } + +#[repr(no_niche)] +pub union Cloaked2 { _A: N16, _B: (u8, N8) } +// { dg-error ".E0517." "" { target *-*-* } .-2 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/repr/repr-no-niche.rs b/gcc/testsuite/rust/rustc/ui/repr/repr-no-niche.rs new file mode 100644 index 000000000000..bd9b72dc8eba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repr/repr-no-niche.rs @@ -0,0 +1,330 @@ +// run-pass + +// This file tests repr(no_niche), which causes an struct/enum to hide +// any niche space that may exist in its internal state from the +// context it appears in. + +// Here are the axes this test is seeking to cover: +// +// repr annotation: +// visible: (); cloaked: (no_niche); transparent: (transparent); shadowy: (transparent, no_niche) +// +// enum vs struct +// +// niche-type via type-parameter vs inline declaration + +#![feature(decl_macro)] +#![feature(no_niche)] + +use std::mem::size_of; +use std::num::{NonZeroU8, NonZeroU16}; + +mod struct_inline { + use std::num::NonZeroU16 as N16; + + #[derive(Debug)] pub struct Visible(N16); + + #[repr(no_niche)] + #[derive(Debug)] pub struct Cloaked(N16); + + #[repr(transparent)] + #[derive(Debug)] pub struct Transparent(N16); + + #[repr(transparent, no_niche)] + #[derive(Debug)] pub struct Shadowy(N16); +} + +mod struct_param { + #[derive(Debug)] pub struct Visible(T); + + #[repr(no_niche)] + #[derive(Debug)] pub struct Cloaked(T); + + #[repr(transparent)] + #[derive(Debug)] pub struct Transparent(T); + + #[repr(transparent, no_niche)] + #[derive(Debug)] pub struct Shadowy(T); +} + +mod enum_inline { + use crate::two_fifty_six_variant_enum; + use std::num::{NonZeroU8 as N8, NonZeroU16 as N16}; + + #[derive(Debug)] pub enum Visible1 { _A(N16), } + + #[repr(no_niche)] + #[derive(Debug)] pub enum Cloaked1 { _A(N16), } + + // (N.B.: transparent enums must be univariant) + #[repr(transparent)] + #[derive(Debug)] pub enum Transparent { _A(N16), } + + #[repr(transparent, no_niche)] + #[derive(Debug)] pub enum Shadowy { _A(N16), } + + // including multivariant enums for completeness. Payload and + // number of variants (i.e. discriminant size) have been chosen so + // that layout including discriminant is 4 bytes, with no space in + // padding to hide another discrimnant from the surrounding + // context. + // + // (Note that multivariant enums cannot usefully expose a niche in + // general; this test is relying on that.) + two_fifty_six_variant_enum!(Visible2, N8); + + #[repr(no_niche)] + two_fifty_six_variant_enum!(Cloaked2, N8); +} + +mod enum_param { + use super::two_fifty_six_variant_enum; + + #[derive(Debug)] pub enum Visible1 { _A(T), } + + #[repr(no_niche)] + #[derive(Debug)] pub enum Cloaked1 { _A(T), } + + // (N.B.: transparent enums must be univariant) + #[repr(transparent)] + #[derive(Debug)] pub enum Transparent { _A(T), } + + #[repr(transparent, no_niche)] + #[derive(Debug)] pub enum Shadowy { _A(T), } + + // including multivariant enums for completeness. Same notes apply + // here as above (assuming `T` is instantiated with `NonZeroU8`). + two_fifty_six_variant_enum!(Visible2); + + #[repr(no_niche)] + two_fifty_six_variant_enum!(Cloaked2); +} + +fn main() { + // sanity-checks + assert_eq!(size_of::(), 2); + assert_eq!(size_of::(), 2); + assert_eq!(size_of::(), 2); + assert_eq!(size_of::(), 2); + + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2); + + assert_eq!(size_of::(), 2); + assert_eq!(size_of::(), 2); + assert_eq!(size_of::(), 2); // transparent enums are univariant + assert_eq!(size_of::(), 2); + assert_eq!(size_of::(), 4); + assert_eq!(size_of::(), 4); + + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 4); + assert_eq!(size_of::>(), 4); + + // now the actual tests of no_niche: how do inputs above compose + // with `Option` type constructor. The cases with a `_+2` are the + // ones where no_niche fires. + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2+2); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2+2); + + assert_eq!(size_of::>>(), 2); + assert_eq!(size_of::>>(), 2+2); + assert_eq!(size_of::>>(), 2); + assert_eq!(size_of::>>(), 2+2); + + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2+2); + assert_eq!(size_of::>(), 2); + assert_eq!(size_of::>(), 2+2); + // cannot use niche of multivariant payload + assert_eq!(size_of::>(), 4+2); + assert_eq!(size_of::>(), 4+2); + + assert_eq!(size_of::>>(), 2); + assert_eq!(size_of::>>(), 2+2); + assert_eq!(size_of::>>(), 2); + assert_eq!(size_of::>>(), 2+2); + // cannot use niche of multivariant payload + assert_eq!(size_of::>>(), 4+2); + assert_eq!(size_of::>>(), 4+2); +} + +macro two_fifty_six_variant_enum { + ($name:ident<$param:ident>) => { + #[derive(Debug)] + pub enum $name<$param> { + _V00($param, u16), _V01(u16, $param), _V02($param, u16), _V03(u16, $param), + _V04($param, u16), _V05(u16, $param), _V06($param, u16), _V07(u16, $param), + _V08($param, u16), _V09(u16, $param), _V0a($param, u16), _V0b(u16, $param), + _V0c($param, u16), _V0d(u16, $param), _V0e($param, u16), _V0f(u16, $param), + + _V10($param, u16), _V11(u16, $param), _V12($param, u16), _V13(u16, $param), + _V14($param, u16), _V15(u16, $param), _V16($param, u16), _V17(u16, $param), + _V18($param, u16), _V19(u16, $param), _V1a($param, u16), _V1b(u16, $param), + _V1c($param, u16), _V1d(u16, $param), _V1e($param, u16), _V1f(u16, $param), + + _V20($param, u16), _V21(u16, $param), _V22($param, u16), _V23(u16, $param), + _V24($param, u16), _V25(u16, $param), _V26($param, u16), _V27(u16, $param), + _V28($param, u16), _V29(u16, $param), _V2a($param, u16), _V2b(u16, $param), + _V2c($param, u16), _V2d(u16, $param), _V2e($param, u16), _V2f(u16, $param), + + _V30($param, u16), _V31(u16, $param), _V32($param, u16), _V33(u16, $param), + _V34($param, u16), _V35(u16, $param), _V36($param, u16), _V37(u16, $param), + _V38($param, u16), _V39(u16, $param), _V3a($param, u16), _V3b(u16, $param), + _V3c($param, u16), _V3d(u16, $param), _V3e($param, u16), _V3f(u16, $param), + + _V40($param, u16), _V41(u16, $param), _V42($param, u16), _V43(u16, $param), + _V44($param, u16), _V45(u16, $param), _V46($param, u16), _V47(u16, $param), + _V48($param, u16), _V49(u16, $param), _V4a($param, u16), _V4b(u16, $param), + _V4c($param, u16), _V4d(u16, $param), _V4e($param, u16), _V4f(u16, $param), + + _V50($param, u16), _V51(u16, $param), _V52($param, u16), _V53(u16, $param), + _V54($param, u16), _V55(u16, $param), _V56($param, u16), _V57(u16, $param), + _V58($param, u16), _V59(u16, $param), _V5a($param, u16), _V5b(u16, $param), + _V5c($param, u16), _V5d(u16, $param), _V5e($param, u16), _V5f(u16, $param), + + _V60($param, u16), _V61(u16, $param), _V62($param, u16), _V63(u16, $param), + _V64($param, u16), _V65(u16, $param), _V66($param, u16), _V67(u16, $param), + _V68($param, u16), _V69(u16, $param), _V6a($param, u16), _V6b(u16, $param), + _V6c($param, u16), _V6d(u16, $param), _V6e($param, u16), _V6f(u16, $param), + + _V70($param, u16), _V71(u16, $param), _V72($param, u16), _V73(u16, $param), + _V74($param, u16), _V75(u16, $param), _V76($param, u16), _V77(u16, $param), + _V78($param, u16), _V79(u16, $param), _V7a($param, u16), _V7b(u16, $param), + _V7c($param, u16), _V7d(u16, $param), _V7e($param, u16), _V7f(u16, $param), + + _V80($param, u16), _V81(u16, $param), _V82($param, u16), _V83(u16, $param), + _V84($param, u16), _V85(u16, $param), _V86($param, u16), _V87(u16, $param), + _V88($param, u16), _V89(u16, $param), _V8a($param, u16), _V8b(u16, $param), + _V8c($param, u16), _V8d(u16, $param), _V8e($param, u16), _V8f(u16, $param), + + _V90($param, u16), _V91(u16, $param), _V92($param, u16), _V93(u16, $param), + _V94($param, u16), _V95(u16, $param), _V96($param, u16), _V97(u16, $param), + _V98($param, u16), _V99(u16, $param), _V9a($param, u16), _V9b(u16, $param), + _V9c($param, u16), _V9d(u16, $param), _V9e($param, u16), _V9f(u16, $param), + + _Va0($param, u16), _Va1(u16, $param), _Va2($param, u16), _Va3(u16, $param), + _Va4($param, u16), _Va5(u16, $param), _Va6($param, u16), _Va7(u16, $param), + _Va8($param, u16), _Va9(u16, $param), _Vaa($param, u16), _Vab(u16, $param), + _Vac($param, u16), _Vad(u16, $param), _Vae($param, u16), _Vaf(u16, $param), + + _Vb0($param, u16), _Vb1(u16, $param), _Vb2($param, u16), _Vb3(u16, $param), + _Vb4($param, u16), _Vb5(u16, $param), _Vb6($param, u16), _Vb7(u16, $param), + _Vb8($param, u16), _Vb9(u16, $param), _Vba($param, u16), _Vbb(u16, $param), + _Vbc($param, u16), _Vbd(u16, $param), _Vbe($param, u16), _Vbf(u16, $param), + + _Vc0($param, u16), _Vc1(u16, $param), _Vc2($param, u16), _Vc3(u16, $param), + _Vc4($param, u16), _Vc5(u16, $param), _Vc6($param, u16), _Vc7(u16, $param), + _Vc8($param, u16), _Vc9(u16, $param), _Vca($param, u16), _Vcb(u16, $param), + _Vcc($param, u16), _Vcd(u16, $param), _Vce($param, u16), _Vcf(u16, $param), + + _Vd0($param, u16), _Vd1(u16, $param), _Vd2($param, u16), _Vd3(u16, $param), + _Vd4($param, u16), _Vd5(u16, $param), _Vd6($param, u16), _Vd7(u16, $param), + _Vd8($param, u16), _Vd9(u16, $param), _Vda($param, u16), _Vdb(u16, $param), + _Vdc($param, u16), _Vdd(u16, $param), _Vde($param, u16), _Vdf(u16, $param), + + _Ve0($param, u16), _Ve1(u16, $param), _Ve2($param, u16), _Ve3(u16, $param), + _Ve4($param, u16), _Ve5(u16, $param), _Ve6($param, u16), _Ve7(u16, $param), + _Ve8($param, u16), _Ve9(u16, $param), _Vea($param, u16), _Veb(u16, $param), + _Vec($param, u16), _Ved(u16, $param), _Vee($param, u16), _Vef(u16, $param), + + _Vf0($param, u16), _Vf1(u16, $param), _Vf2($param, u16), _Vf3(u16, $param), + _Vf4($param, u16), _Vf5(u16, $param), _Vf6($param, u16), _Vf7(u16, $param), + _Vf8($param, u16), _Vf9(u16, $param), _Vfa($param, u16), _Vfb(u16, $param), + _Vfc($param, u16), _Vfd(u16, $param), _Vfe($param, u16), _Vff(u16, $param), + } + }, + + ($name:ident, $param:ty) => { + #[derive(Debug)] + pub enum $name { + _V00($param, u16), _V01(u16, $param), _V02($param, u16), _V03(u16, $param), + _V04($param, u16), _V05(u16, $param), _V06($param, u16), _V07(u16, $param), + _V08($param, u16), _V09(u16, $param), _V0a($param, u16), _V0b(u16, $param), + _V0c($param, u16), _V0d(u16, $param), _V0e($param, u16), _V0f(u16, $param), + + _V10($param, u16), _V11(u16, $param), _V12($param, u16), _V13(u16, $param), + _V14($param, u16), _V15(u16, $param), _V16($param, u16), _V17(u16, $param), + _V18($param, u16), _V19(u16, $param), _V1a($param, u16), _V1b(u16, $param), + _V1c($param, u16), _V1d(u16, $param), _V1e($param, u16), _V1f(u16, $param), + + _V20($param, u16), _V21(u16, $param), _V22($param, u16), _V23(u16, $param), + _V24($param, u16), _V25(u16, $param), _V26($param, u16), _V27(u16, $param), + _V28($param, u16), _V29(u16, $param), _V2a($param, u16), _V2b(u16, $param), + _V2c($param, u16), _V2d(u16, $param), _V2e($param, u16), _V2f(u16, $param), + + _V30($param, u16), _V31(u16, $param), _V32($param, u16), _V33(u16, $param), + _V34($param, u16), _V35(u16, $param), _V36($param, u16), _V37(u16, $param), + _V38($param, u16), _V39(u16, $param), _V3a($param, u16), _V3b(u16, $param), + _V3c($param, u16), _V3d(u16, $param), _V3e($param, u16), _V3f(u16, $param), + + _V40($param, u16), _V41(u16, $param), _V42($param, u16), _V43(u16, $param), + _V44($param, u16), _V45(u16, $param), _V46($param, u16), _V47(u16, $param), + _V48($param, u16), _V49(u16, $param), _V4a($param, u16), _V4b(u16, $param), + _V4c($param, u16), _V4d(u16, $param), _V4e($param, u16), _V4f(u16, $param), + + _V50($param, u16), _V51(u16, $param), _V52($param, u16), _V53(u16, $param), + _V54($param, u16), _V55(u16, $param), _V56($param, u16), _V57(u16, $param), + _V58($param, u16), _V59(u16, $param), _V5a($param, u16), _V5b(u16, $param), + _V5c($param, u16), _V5d(u16, $param), _V5e($param, u16), _V5f(u16, $param), + + _V60($param, u16), _V61(u16, $param), _V62($param, u16), _V63(u16, $param), + _V64($param, u16), _V65(u16, $param), _V66($param, u16), _V67(u16, $param), + _V68($param, u16), _V69(u16, $param), _V6a($param, u16), _V6b(u16, $param), + _V6c($param, u16), _V6d(u16, $param), _V6e($param, u16), _V6f(u16, $param), + + _V70($param, u16), _V71(u16, $param), _V72($param, u16), _V73(u16, $param), + _V74($param, u16), _V75(u16, $param), _V76($param, u16), _V77(u16, $param), + _V78($param, u16), _V79(u16, $param), _V7a($param, u16), _V7b(u16, $param), + _V7c($param, u16), _V7d(u16, $param), _V7e($param, u16), _V7f(u16, $param), + + _V80($param, u16), _V81(u16, $param), _V82($param, u16), _V83(u16, $param), + _V84($param, u16), _V85(u16, $param), _V86($param, u16), _V87(u16, $param), + _V88($param, u16), _V89(u16, $param), _V8a($param, u16), _V8b(u16, $param), + _V8c($param, u16), _V8d(u16, $param), _V8e($param, u16), _V8f(u16, $param), + + _V90($param, u16), _V91(u16, $param), _V92($param, u16), _V93(u16, $param), + _V94($param, u16), _V95(u16, $param), _V96($param, u16), _V97(u16, $param), + _V98($param, u16), _V99(u16, $param), _V9a($param, u16), _V9b(u16, $param), + _V9c($param, u16), _V9d(u16, $param), _V9e($param, u16), _V9f(u16, $param), + + _Va0($param, u16), _Va1(u16, $param), _Va2($param, u16), _Va3(u16, $param), + _Va4($param, u16), _Va5(u16, $param), _Va6($param, u16), _Va7(u16, $param), + _Va8($param, u16), _Va9(u16, $param), _Vaa($param, u16), _Vab(u16, $param), + _Vac($param, u16), _Vad(u16, $param), _Vae($param, u16), _Vaf(u16, $param), + + _Vb0($param, u16), _Vb1(u16, $param), _Vb2($param, u16), _Vb3(u16, $param), + _Vb4($param, u16), _Vb5(u16, $param), _Vb6($param, u16), _Vb7(u16, $param), + _Vb8($param, u16), _Vb9(u16, $param), _Vba($param, u16), _Vbb(u16, $param), + _Vbc($param, u16), _Vbd(u16, $param), _Vbe($param, u16), _Vbf(u16, $param), + + _Vc0($param, u16), _Vc1(u16, $param), _Vc2($param, u16), _Vc3(u16, $param), + _Vc4($param, u16), _Vc5(u16, $param), _Vc6($param, u16), _Vc7(u16, $param), + _Vc8($param, u16), _Vc9(u16, $param), _Vca($param, u16), _Vcb(u16, $param), + _Vcc($param, u16), _Vcd(u16, $param), _Vce($param, u16), _Vcf(u16, $param), + + _Vd0($param, u16), _Vd1(u16, $param), _Vd2($param, u16), _Vd3(u16, $param), + _Vd4($param, u16), _Vd5(u16, $param), _Vd6($param, u16), _Vd7(u16, $param), + _Vd8($param, u16), _Vd9(u16, $param), _Vda($param, u16), _Vdb(u16, $param), + _Vdc($param, u16), _Vdd(u16, $param), _Vde($param, u16), _Vdf(u16, $param), + + _Ve0($param, u16), _Ve1(u16, $param), _Ve2($param, u16), _Ve3(u16, $param), + _Ve4($param, u16), _Ve5(u16, $param), _Ve6($param, u16), _Ve7(u16, $param), + _Ve8($param, u16), _Ve9(u16, $param), _Vea($param, u16), _Veb(u16, $param), + _Vec($param, u16), _Ved(u16, $param), _Vee($param, u16), _Vef(u16, $param), + + _Vf0($param, u16), _Vf1(u16, $param), _Vf2($param, u16), _Vf3(u16, $param), + _Vf4($param, u16), _Vf5(u16, $param), _Vf6($param, u16), _Vf7(u16, $param), + _Vf8($param, u16), _Vf9(u16, $param), _Vfa($param, u16), _Vfb(u16, $param), + _Vfc($param, u16), _Vfd(u16, $param), _Vfe($param, u16), _Vff(u16, $param), + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/repr/repr-packed-contains-align.rs b/gcc/testsuite/rust/rustc/ui/repr/repr-packed-contains-align.rs new file mode 100644 index 000000000000..973d0166e1b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repr/repr-packed-contains-align.rs @@ -0,0 +1,51 @@ +#![feature(untagged_unions)] +#![allow(dead_code)] + +#[repr(align(16))] +struct SA(i32); + +struct SB(SA); + +#[repr(align(16))] +union UA { + i: i32 +} + +union UB { + a: UA +} + +#[repr(packed)] +struct SC(SA); // { dg-error ".E0588." "" { target *-*-* } } + +#[repr(packed)] +struct SD(SB); // { dg-error ".E0588." "" { target *-*-* } } + +#[repr(packed)] +struct SE(UA); // { dg-error ".E0588." "" { target *-*-* } } + +#[repr(packed)] +struct SF(UB); // { dg-error ".E0588." "" { target *-*-* } } + +#[repr(packed)] +union UC { // { dg-error ".E0588." "" { target *-*-* } } + a: UA +} + +#[repr(packed)] +union UD { // { dg-error ".E0588." "" { target *-*-* } } + n: UB +} + +#[repr(packed)] +union UE { // { dg-error ".E0588." "" { target *-*-* } } + a: SA +} + +#[repr(packed)] +union UF { // { dg-error ".E0588." "" { target *-*-* } } + n: SB +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/repr/repr-transparent-other-items.rs b/gcc/testsuite/rust/rustc/ui/repr/repr-transparent-other-items.rs new file mode 100644 index 000000000000..177977a7326c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repr/repr-transparent-other-items.rs @@ -0,0 +1,10 @@ +// See also repr-transparent.rs + +#[repr(transparent)] // { dg-error ".E0517." "" { target *-*-* } } +fn cant_repr_this() {} + +#[repr(transparent)] // { dg-error ".E0517." "" { target *-*-* } } +static CANT_REPR_THIS: u32 = 0; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/repr/repr-transparent-other-reprs.rs b/gcc/testsuite/rust/rustc/ui/repr/repr-transparent-other-reprs.rs new file mode 100644 index 000000000000..30c60abd1c05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repr/repr-transparent-other-reprs.rs @@ -0,0 +1,21 @@ +#![feature(repr_align)] + +// See also repr-transparent.rs + +#[repr(transparent, C)] // { dg-error ".E0692." "" { target *-*-* } } +struct TransparentPlusC { + ptr: *const u8 +} + +#[repr(transparent, packed)] // { dg-error ".E0692." "" { target *-*-* } } +struct TransparentPlusPacked(*const u8); + +#[repr(transparent, align(2))] // { dg-error ".E0692." "" { target *-*-* } } +struct TransparentPlusAlign(u8); + +#[repr(transparent)] // { dg-error ".E0692." "" { target *-*-* } } +#[repr(C)] +struct SeparateAttributes(*mut u8); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/repr/repr-transparent.rs b/gcc/testsuite/rust/rustc/ui/repr/repr-transparent.rs new file mode 100644 index 000000000000..3680fde86229 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repr/repr-transparent.rs @@ -0,0 +1,85 @@ +// This file tests repr(transparent)-related errors reported during typeck. Other errors +// that are reported earlier and therefore preempt these are tested in: +// - repr-transparent-other-reprs.rs +// - repr-transparent-other-items.rs + +#![feature(transparent_unions)] + +use std::marker::PhantomData; + +#[repr(transparent)] +struct NoFields; // { dg-error ".E0690." "" { target *-*-* } } + +#[repr(transparent)] +struct ContainsOnlyZst(()); // { dg-error ".E0690." "" { target *-*-* } } + +#[repr(transparent)] +struct ContainsOnlyZstArray([bool; 0]); // { dg-error ".E0690." "" { target *-*-* } } + +#[repr(transparent)] +struct ContainsMultipleZst(PhantomData<*const i32>, NoFields); +// { dg-error ".E0690." "" { target *-*-* } .-1 } + +#[repr(transparent)] +struct MultipleNonZst(u8, u8); // { dg-error ".E0690." "" { target *-*-* } } + +trait Mirror { type It: ?Sized; } +impl Mirror for T { type It = Self; } + +#[repr(transparent)] +pub struct StructWithProjection(f32, ::It); +// { dg-error ".E0690." "" { target *-*-* } .-1 } + +#[repr(transparent)] +struct NontrivialAlignZst(u32, [u16; 0]); // { dg-error ".E0691." "" { target *-*-* } } + +#[repr(align(32))] +struct ZstAlign32(PhantomData); + +#[repr(transparent)] +struct GenericAlign(ZstAlign32, u32); // { dg-error ".E0691." "" { target *-*-* } } + +#[repr(transparent)] // { dg-error ".E0084." "" { target *-*-* } } +enum Void {} +// { dg-error ".E0731." "" { target *-*-* } .-1 } + +#[repr(transparent)] +enum FieldlessEnum { // { dg-error ".E0690." "" { target *-*-* } } + Foo, +} + +#[repr(transparent)] +enum TooManyFieldsEnum { + Foo(u32, String), +} +// { dg-error ".E0690." "" { target *-*-* } .-3 } + +#[repr(transparent)] +enum TooManyVariants { // { dg-error ".E0731." "" { target *-*-* } } + Foo(String), + Bar, +} + +#[repr(transparent)] +enum NontrivialAlignZstEnum { + Foo(u32, [u16; 0]), // { dg-error ".E0691." "" { target *-*-* } } +} + +#[repr(transparent)] +enum GenericAlignEnum { + Foo { bar: ZstAlign32, baz: u32 } // { dg-error ".E0691." "" { target *-*-* } } +} + +#[repr(transparent)] +union UnitUnion { // { dg-error ".E0690." "" { target *-*-* } } + u: (), +} + +#[repr(transparent)] +union TooManyFields { // { dg-error ".E0690." "" { target *-*-* } } + u: u32, + s: i32 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/repr_c_int_align.rs b/gcc/testsuite/rust/rustc/ui/repr_c_int_align.rs new file mode 100644 index 000000000000..b5cb85058e6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/repr_c_int_align.rs @@ -0,0 +1,47 @@ +// run-pass +// compile-flags: -O + +#![allow(dead_code)] + +#[repr(C, u8)] +enum ReprCu8 { + A(u16), + B, +} + +#[repr(u8)] +enum Repru8 { + A(u16), + B, +} + +#[repr(C)] +struct ReprC { + tag: u8, + padding: u8, + payload: u16, +} + +fn main() { + // Test `repr(C, u8)`. + let r1 = ReprC { tag: 0, padding: 0, payload: 0 }; + let r2 = ReprC { tag: 0, padding: 1, payload: 1 }; + + let t1: &ReprCu8 = unsafe { std::mem::transmute(&r1) }; + let t2: &ReprCu8 = unsafe { std::mem::transmute(&r2) }; + + match (t1, t2) { + (ReprCu8::A(_), ReprCu8::A(_)) => (), + _ => assert!(false) + }; + + // Test `repr(u8)`. + let t1: &Repru8 = unsafe { std::mem::transmute(&r1) }; + let t2: &Repru8 = unsafe { std::mem::transmute(&r2) }; + + match (t1, t2) { + (Repru8::A(_), Repru8::A(_)) => (), + _ => assert!(false) + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/required-lang-item.rs b/gcc/testsuite/rust/rustc/ui/required-lang-item.rs new file mode 100644 index 000000000000..170c129fdbe4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/required-lang-item.rs @@ -0,0 +1,12 @@ +// build-fail + +#![feature(lang_items, no_core)] +#![no_core] + +#[lang="copy"] pub trait Copy { } +#[lang="sized"] pub trait Sized { } + +// error-pattern:requires `start` lang_item + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/reserved/reserved-attr-on-macro.rs b/gcc/testsuite/rust/rustc/ui/reserved/reserved-attr-on-macro.rs new file mode 100644 index 000000000000..ee17ddd1de43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reserved/reserved-attr-on-macro.rs @@ -0,0 +1,12 @@ +#[rustc_attribute_should_be_reserved] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +macro_rules! foo { + () => (()); +} + +fn main() { + foo!(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/reserved/reserved-become.rs b/gcc/testsuite/rust/rustc/ui/reserved/reserved-become.rs new file mode 100644 index 000000000000..6cfa4d46d480 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/reserved/reserved-become.rs @@ -0,0 +1,5 @@ +fn main() { + let become = 0; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve-issue-2428.rs b/gcc/testsuite/rust/rustc/ui/resolve-issue-2428.rs new file mode 100644 index 000000000000..f2283b2b8c6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve-issue-2428.rs @@ -0,0 +1,9 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] + +const foo: isize = 4 >> 1; +enum bs { thing = foo } +pub fn main() { assert_eq!(bs::thing as isize, foo); } + diff --git a/gcc/testsuite/rust/rustc/ui/resolve-pseudo-shadowing.rs b/gcc/testsuite/rust/rustc/ui/resolve-pseudo-shadowing.rs new file mode 100644 index 000000000000..c415151da5d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve-pseudo-shadowing.rs @@ -0,0 +1,12 @@ +// run-pass +// check that type parameters can't "shadow" qualified paths. + +fn check(_c: Clone) { + fn check2() { + let _ = <() as std::clone::Clone>::clone(&()); + } + check2(); +} + +fn main() { check(()); } + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/associated-fn-called-as-fn.rs b/gcc/testsuite/rust/rustc/ui/resolve/associated-fn-called-as-fn.rs new file mode 100644 index 000000000000..13e01d06d248 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/associated-fn-called-as-fn.rs @@ -0,0 +1,33 @@ +struct S; +impl Foo for S { + fn parse(s:&str) { + for c in s.chars() { + match c { + '0'..='9' => collect_primary(&c), // { dg-error ".E0425." "" { target *-*-* } } +// { help ".E0425." "" { target *-*-* } .-1 } + '+' | '-' => println!("We got a sign: {}", c), + _ => println!("Not a number!") + } + } + } +} +trait Foo { + fn collect_primary(ch:&char) { } + fn parse(s:&str); +} +trait Bar { + fn collect_primary(ch:&char) { } + fn parse(s:&str) { + for c in s.chars() { + match c { + '0'..='9' => collect_primary(&c), // { dg-error ".E0425." "" { target *-*-* } } +// { help ".E0425." "" { target *-*-* } .-1 } + '+' | '-' => println!("We got a sign: {}", c), + _ => println!("Not a number!") + } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-19452-aux.rs b/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-19452-aux.rs new file mode 100644 index 000000000000..29ba595f05f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-19452-aux.rs @@ -0,0 +1,4 @@ +pub enum Homura { + Madoka { age: u32 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-21221-3.rs b/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-21221-3.rs new file mode 100644 index 000000000000..ea31460607d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-21221-3.rs @@ -0,0 +1,20 @@ +// testing whether the lookup mechanism picks up types +// defined in the outside crate + +#![crate_type="lib"] + +pub mod outer { + // should suggest this + pub trait OuterTrait {} + + // should not suggest this since the module is private + mod private_module { + pub trait OuterTrait {} + } + + // should not suggest since the trait is private + pub mod public_module { + trait OuterTrait {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-21221-4.rs b/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-21221-4.rs new file mode 100644 index 000000000000..95550bf9e4d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-21221-4.rs @@ -0,0 +1,13 @@ +// testing whether the lookup mechanism picks up types +// defined in the outside crate + +#![crate_type="lib"] + +mod foo { + // should not be suggested => foo is private + pub trait T {} +} + +// should be suggested +pub use foo::T; + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-3907.rs b/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-3907.rs new file mode 100644 index 000000000000..b008a026132d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/issue-3907.rs @@ -0,0 +1,4 @@ +pub trait Foo { + fn bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/namespaced_enums.rs b/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/namespaced_enums.rs new file mode 100644 index 000000000000..dcd0b95974b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/namespaced_enums.rs @@ -0,0 +1,11 @@ +pub enum Foo { + A, + B(isize), + C { a: isize }, +} + +impl Foo { + pub fn foo() {} + pub fn bar(&self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/privacy-struct-ctor.rs b/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/privacy-struct-ctor.rs new file mode 100644 index 000000000000..ffb88389983d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/auxiliary/privacy-struct-ctor.rs @@ -0,0 +1,10 @@ +pub mod m { + pub struct S(u8); + + pub mod n { + pub(in m) struct Z(pub(in m::n) u8); + } +} + +pub use m::S; + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/block-with-trait-parent.rs b/gcc/testsuite/rust/rustc/ui/resolve/block-with-trait-parent.rs new file mode 100644 index 000000000000..fd325f10e9af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/block-with-trait-parent.rs @@ -0,0 +1,15 @@ +// check-pass + +trait Trait { + fn method(&self) { + // Items inside a block turn it into a module internally. + struct S; + impl Trait for S {} + + // OK, `Trait` is in scope here from method resolution point of view. + S.method(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/enums-are-namespaced-xc.rs b/gcc/testsuite/rust/rustc/ui/resolve/enums-are-namespaced-xc.rs new file mode 100644 index 000000000000..52841441847f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/enums-are-namespaced-xc.rs @@ -0,0 +1,12 @@ +// aux-build:namespaced_enums.rs +extern crate namespaced_enums; + +fn main() { + let _ = namespaced_enums::A; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + let _ = namespaced_enums::B(10); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + let _ = namespaced_enums::C { a: 10 }; +// { dg-error ".E0422." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/impl-items-vis-unresolved.rs b/gcc/testsuite/rust/rustc/ui/resolve/impl-items-vis-unresolved.rs new file mode 100644 index 000000000000..beebfcdfdce2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/impl-items-vis-unresolved.rs @@ -0,0 +1,27 @@ +// Visibilities on impl items expanded from macros are resolved (issue #64705). + +macro_rules! perftools_inline { + ($($item:tt)*) => ( + $($item)* + ); +} + +mod state { + pub struct RawFloatState; + impl RawFloatState { + perftools_inline! { + pub(super) fn new() {} // OK + } + } +} + +pub struct RawFloatState; +impl RawFloatState { + perftools_inline! { + pub(super) fn new() {} +// { dg-error ".E0433." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-14254.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-14254.rs new file mode 100644 index 000000000000..4cf90c4c27a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-14254.rs @@ -0,0 +1,106 @@ +trait Foo { + fn bar(&self); + fn baz(&self) { } + fn bah(_: Option<&Self>) { } +} + +struct BarTy { + x : isize, + y : f64, +} + +impl BarTy { + fn a() {} + fn b(&self) {} +} + +impl Foo for *const BarTy { + fn bar(&self) { + baz(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + a; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +impl<'a> Foo for &'a BarTy { + fn bar(&self) { + baz(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + x; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + y; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + a; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + bah; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + b; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +impl<'a> Foo for &'a mut BarTy { + fn bar(&self) { + baz(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + x; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + y; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + a; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + bah; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + b; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +impl Foo for Box { + fn bar(&self) { + baz(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + bah; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +impl Foo for *const isize { + fn bar(&self) { + baz(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + bah; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +impl<'a> Foo for &'a isize { + fn bar(&self) { + baz(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + bah; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +impl<'a> Foo for &'a mut isize { + fn bar(&self) { + baz(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + bah; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +impl Foo for Box { + fn bar(&self) { + baz(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + bah; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-16058.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-16058.rs new file mode 100644 index 000000000000..95db0d63e4d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-16058.rs @@ -0,0 +1,19 @@ +// ignore-sgx std::os::fortanix_sgx::usercalls::raw::Result changes compiler suggestions + +pub struct GslResult { + pub val: f64, + pub err: f64 +} + +impl GslResult { + pub fn new() -> GslResult { + Result { +// { dg-error ".E0574." "" { target *-*-* } .-1 } + val: 0f64, + err: 0f64 + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-17518.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-17518.rs new file mode 100644 index 000000000000..57ef7d4c494c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-17518.rs @@ -0,0 +1,8 @@ +enum SomeEnum { + E +} + +fn main() { + E { name: "foobar" }; // { dg-error ".E0422." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-18252.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-18252.rs new file mode 100644 index 000000000000..42b7059b2d94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-18252.rs @@ -0,0 +1,9 @@ +enum Foo { + Variant { x: usize } +} + +fn main() { + let f = Foo::Variant(42); +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-19452.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-19452.rs new file mode 100644 index 000000000000..f72939b96165 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-19452.rs @@ -0,0 +1,16 @@ +// aux-build:issue-19452-aux.rs + +extern crate issue_19452_aux; + +enum Homura { + Madoka { age: u32 } +} + +fn main() { + let homura = Homura::Madoka; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + + let homura = issue_19452_aux::Homura::Madoka; +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-21221-1.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-21221-1.rs new file mode 100644 index 000000000000..c4a861c3b87e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-21221-1.rs @@ -0,0 +1,76 @@ +mod mul1 { + pub trait Mul {} +} + +mod mul2 { + pub trait Mul {} +} + +mod mul3 { + enum Mul { + Yes, + No + } +} + +mod mul4 { + type Mul = String; +} + +mod mul5 { + struct Mul{ + left_term: u32, + right_term: u32 + } +} + +#[derive(Debug)] +struct Foo; + +// When we comment the next line: +//use mul1::Mul; + +// BEFORE, we got the following error for the `impl` below: +// error: use of undeclared trait name `Mul` [E0405] +// AFTER, we get this message: +// error: trait `Mul` is not in scope. +// help: ... +// help: you can import several candidates into scope (`use ...;`): +// help: `mul1::Mul` +// help: `mul2::Mul` +// help: `std::ops::Mul` + +impl Mul for Foo { +// { dg-error ".E0405." "" { target *-*-* } .-1 } +} + +// BEFORE, we got: +// error: use of undeclared type name `Mul` [E0412] +// AFTER, we get: +// error: type name `Mul` is not in scope. Maybe you meant: +// help: ... +// help: you can import several candidates into scope (`use ...;`): +// help: `mul1::Mul` +// help: `mul2::Mul` +// help: `mul3::Mul` +// help: `mul4::Mul` +// help: and 2 other candidates +fn getMul() -> Mul { +// { dg-error ".E0412." "" { target *-*-* } .-1 } +} + +// Let's also test what happens if the trait doesn't exist: +impl ThisTraitReallyDoesntExistInAnyModuleReally for Foo { +// { dg-error ".E0405." "" { target *-*-* } .-1 } +} + +// Let's also test what happens if there's just one alternative: +impl Div for Foo { +// { dg-error ".E0405." "" { target *-*-* } .-1 } +} + +fn main() { + let foo = Foo(); + println!("Hello, {:?}!", foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-21221-2.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-21221-2.rs new file mode 100644 index 000000000000..5284b4af2a49 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-21221-2.rs @@ -0,0 +1,22 @@ +pub mod foo { + pub mod bar { + // note: trait T is not public, but being in the current + // crate, it's fine to show it, since the programmer can + // decide to make it public based on the suggestion ... + pub trait T {} + } + // imports should be ignored: + use self::bar::T; +} + +pub mod baz { + pub use foo; + pub use std::ops::{Mul as T}; +} + +struct Foo; +impl T for Foo { } +// { dg-error ".E0405." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-21221-3.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-21221-3.rs new file mode 100644 index 000000000000..09016cd253b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-21221-3.rs @@ -0,0 +1,20 @@ +// testing whether the lookup mechanism picks up types +// defined in the outside crate + +// aux-build:issue-21221-3.rs + +extern crate issue_21221_3; + +struct Foo; + +// NOTE: This shows only traits accessible from the current +// crate, thus the two private entities: +// `issue_21221_3::outer::private_module::OuterTrait` and +// `issue_21221_3::outer::public_module::OuterTrait` +// are hidden from the view. +impl OuterTrait for Foo {} +// { dg-error ".E0405." "" { target *-*-* } .-1 } +fn main() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-21221-4.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-21221-4.rs new file mode 100644 index 000000000000..3e7655767607 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-21221-4.rs @@ -0,0 +1,16 @@ +// testing whether the lookup mechanism picks up types +// defined in the outside crate + +// aux-build:issue-21221-4.rs + +extern crate issue_21221_4; + +struct Foo; + +impl T for Foo {} +// { dg-error ".E0405." "" { target *-*-* } .-1 } + +fn main() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-22692.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-22692.rs new file mode 100644 index 000000000000..6adfb6089e3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-22692.rs @@ -0,0 +1,4 @@ +fn main() { + let _ = String.new(); // { dg-error ".E0423." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-23305.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-23305.rs new file mode 100644 index 000000000000..a992275a3936 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-23305.rs @@ -0,0 +1,9 @@ +pub trait ToNbt { + fn new(val: T) -> Self; +} + +impl dyn ToNbt {} +// { dg-error ".E0391." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-2356.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-2356.rs new file mode 100644 index 000000000000..364d44a702fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-2356.rs @@ -0,0 +1,95 @@ +trait Groom { + fn shave(other: usize); +} + +pub struct Cat { + whiskers: isize, +} + +pub enum MaybeDog { + Dog, + NoDog +} + +impl MaybeDog { + fn bark() { + // If this provides a suggestion, it's a bug as MaybeDog doesn't impl Groom + shave(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +impl Clone for Cat { + fn clone(&self) -> Self { + clone(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + loop {} + } +} +impl Default for Cat { + fn default() -> Self { + default(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + loop {} + } +} + +impl Groom for Cat { + fn shave(other: usize) { + whiskers -= other; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + shave(4); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + purr(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +impl Cat { + fn static_method() {} + + fn purr_louder() { + static_method(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + purr(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + purr(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + purr(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +impl Cat { + fn meow() { + if self.whiskers > 3 { +// { dg-error ".E0424." "" { target *-*-* } .-1 } + println!("MEOW"); + } + } + + fn purr(&self) { + grow_older(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + shave(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } + + fn burn_whiskers(&mut self) { + whiskers = 0; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } + + pub fn grow_older(other:usize) { + whiskers = 4; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + purr_louder(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +fn main() { + self += 1; +// { dg-error ".E0424." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-24968.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-24968.rs new file mode 100644 index 000000000000..56dfafe20e20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-24968.rs @@ -0,0 +1,6 @@ +fn foo(_: Self) { +// { dg-error ".E0411." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-33876.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-33876.rs new file mode 100644 index 000000000000..859c532362c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-33876.rs @@ -0,0 +1,13 @@ +use std::any::Any; + +struct Foo; + +trait Bar {} + +impl Bar for Foo {} + +fn main() { + let any: &dyn Any = &Bar; // { dg-error ".E0423." "" { target *-*-* } } + if any.is::() { println!("u32"); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-3907-2.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-3907-2.rs new file mode 100644 index 000000000000..eec76b18b333 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-3907-2.rs @@ -0,0 +1,15 @@ +// aux-build:issue-3907.rs + +extern crate issue_3907; + +type Foo = dyn issue_3907::Foo + 'static; + +struct S { + name: isize +} + +fn bar(_x: Foo) {} +// { dg-error ".E0038." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-3907.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-3907.rs new file mode 100644 index 000000000000..d2a4e8873cb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-3907.rs @@ -0,0 +1,21 @@ +// aux-build:issue-3907.rs + +extern crate issue_3907; + +type Foo = dyn issue_3907::Foo; + +struct S { + name: isize +} + +impl Foo for S { // { dg-error ".E0404." "" { target *-*-* } } + fn bar() { } +} + +fn main() { + let s = S { + name: 0 + }; + s.bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-39226.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-39226.rs new file mode 100644 index 000000000000..2824872e0244 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-39226.rs @@ -0,0 +1,15 @@ +struct Handle {} + +struct Something { + handle: Handle +} + +fn main() { + let handle: Handle = Handle {}; + + let s: Something = Something { + handle: Handle +// { dg-error ".E0423." "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-5035-2.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-5035-2.rs new file mode 100644 index 000000000000..0247d1b0e51f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-5035-2.rs @@ -0,0 +1,8 @@ +trait I {} +type K = dyn I + 'static; + +fn foo(_x: K) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-5035.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-5035.rs new file mode 100644 index 000000000000..984d5ec0d813 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-5035.rs @@ -0,0 +1,10 @@ +trait I {} +type K = dyn I; +impl K for isize {} // { dg-error ".E0404." "" { target *-*-* } } + +use ImportError; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-1 } +impl ImportError for () {} // check that this is not an additional error (cf. issue #35142) + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-54379.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-54379.rs new file mode 100644 index 000000000000..c80d4c8e183d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-54379.rs @@ -0,0 +1,15 @@ +struct MyStruct { + pub s1: Option, +} + +fn main() { + let thing = MyStruct { s1: None }; + + match thing { + MyStruct { .., Some(_) } => {}, +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-57523.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-57523.rs new file mode 100644 index 000000000000..7e5cd385b3ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-57523.rs @@ -0,0 +1,22 @@ +// check-pass + +struct S(u8); + +impl S { + fn method1() -> Self { + Self(0) + } +} + +macro_rules! define_method { () => { + impl S { + fn method2() -> Self { + Self(0) // OK + } + } +}} + +define_method!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-65025-extern-static-parent-generics.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-65025-extern-static-parent-generics.rs new file mode 100644 index 000000000000..dd82c6990263 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-65025-extern-static-parent-generics.rs @@ -0,0 +1,11 @@ +unsafe fn foo() { + extern "C" { + static baz: *const A; +// { dg-error ".E0401." "" { target *-*-* } .-1 } + } + + let bar: *const u64 = core::mem::transmute(&baz); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-65035-static-with-parent-generics.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-65035-static-with-parent-generics.rs new file mode 100644 index 000000000000..daa2178192b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-65035-static-with-parent-generics.rs @@ -0,0 +1,30 @@ +#![feature(const_generics)] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn f() { + extern "C" { + static a: *const T; +// { dg-error ".E0401." "" { target *-*-* } .-1 } + } +} + +fn g() { + static a: *const T = Default::default(); +// { dg-error ".E0401." "" { target *-*-* } .-1 } +} + +fn h() { + extern "C" { + static a: [u8; N]; +// { dg-error ".E0401." "" { target *-*-* } .-1 } + } +} + +fn i() { + static a: [u8; N] = [0; N]; +// { dg-error ".E0401." "" { target *-*-* } .-1 } +// { dg-error ".E0401." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-6702.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-6702.rs new file mode 100644 index 000000000000..b3083c0a780b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-6702.rs @@ -0,0 +1,10 @@ +struct Monster { + damage: isize +} + + +fn main() { + let _m = Monster(); +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs new file mode 100644 index 000000000000..ce6613bb8d04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-69401-trait-fn-no-body-ty-local.rs @@ -0,0 +1,7 @@ +fn main() {} + +trait Foo { + fn fn_with_type_named_same_as_local_in_param(b: b); +// { dg-error ".E0412." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs b/gcc/testsuite/rust/rustc/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs new file mode 100644 index 000000000000..030eee017411 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs @@ -0,0 +1,21 @@ +// edition:2018 + +async fn free(); // { dg-error "" "" { target *-*-* } } + +struct A; +impl A { + async fn inherent(); // { dg-error "" "" { target *-*-* } } +} + +trait B { + async fn associated(); +// { dg-error ".E0706." "" { target *-*-* } .-1 } +} +impl B for A { + async fn associated(); // { dg-error ".E0053." "" { target *-*-* } } +// { dg-error ".E0053." "" { target *-*-* } .-1 } +// { dg-error ".E0053." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/levenshtein.rs b/gcc/testsuite/rust/rustc/ui/resolve/levenshtein.rs new file mode 100644 index 000000000000..7edacf769105 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/levenshtein.rs @@ -0,0 +1,32 @@ +const MAX_ITEM: usize = 10; + +fn foo_bar() {} + +fn foo(c: esize) {} // Misspelled primitive type name. +// { dg-error ".E0412." "" { target *-*-* } .-1 } + +enum Bar { } + +type A = Baz; // Misspelled type name. +// { dg-error ".E0412." "" { target *-*-* } .-1 } +type B = Opiton; // Misspelled type name from the prelude. +// { dg-error ".E0412." "" { target *-*-* } .-1 } + +mod m { + type A = Baz; // No suggestion here, Bar is not visible +// { dg-error ".E0412." "" { target *-*-* } .-1 } + + pub struct First; + pub struct Second; +} + +fn main() { + let v = [0u32; MAXITEM]; // Misspelled constant name. +// { dg-error ".E0425." "" { target *-*-* } .-1 } + foobar(); // Misspelled function name. +// { dg-error ".E0425." "" { target *-*-* } .-1 } + let b: m::first = m::second; // Misspelled item in module. +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { dg-error ".E0425." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/name-clash-nullary.rs b/gcc/testsuite/rust/rustc/ui/resolve/name-clash-nullary.rs new file mode 100644 index 000000000000..f17aee127f84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/name-clash-nullary.rs @@ -0,0 +1,4 @@ +fn main() { + let None: isize = 42; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/privacy-enum-ctor.rs b/gcc/testsuite/rust/rustc/ui/resolve/privacy-enum-ctor.rs new file mode 100644 index 000000000000..5e9b0e82934e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/privacy-enum-ctor.rs @@ -0,0 +1,72 @@ +mod m { + pub enum E { + Fn(u8), + Struct { + s: u8, + }, + Unit, + } + + pub mod n { + pub(in m) enum Z { + Fn(u8), + Struct { + s: u8, + }, + Unit, + } + } + + use m::n::Z; // OK, only the type is imported + + fn f() { + n::Z; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + Z; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + let _: Z = Z::Fn; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let _: Z = Z::Struct; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + let _ = Z::Unit(); +// { dg-error ".E0618." "" { target *-*-* } .-1 } + let _ = Z::Unit {}; + // This is ok, it is equivalent to not having braces + } +} + +use m::E; // OK, only the type is imported + +fn main() { + let _: E = m::E; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + let _: E = m::E::Fn; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let _: E = m::E::Struct; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + let _: E = m::E::Unit(); +// { dg-error ".E0618." "" { target *-*-* } .-1 } + let _: E = E; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + let _: E = E::Fn; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let _: E = E::Struct; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + let _: E = E::Unit(); +// { dg-error ".E0618." "" { target *-*-* } .-1 } + let _: Z = m::n::Z; +// { dg-error ".E0603." "" { target *-*-* } .-1 } +// { dg-error ".E0603." "" { target *-*-* } .-2 } +// { dg-error ".E0603." "" { target *-*-* } .-3 } + let _: Z = m::n::Z::Fn; +// { dg-error ".E0603." "" { target *-*-* } .-1 } +// { dg-error ".E0603." "" { target *-*-* } .-2 } + let _: Z = m::n::Z::Struct; +// { dg-error ".E0603." "" { target *-*-* } .-1 } +// { dg-error ".E0603." "" { target *-*-* } .-2 } +// { dg-error ".E0603." "" { target *-*-* } .-3 } + let _: Z = m::n::Z::Unit {}; +// { dg-error ".E0603." "" { target *-*-* } .-1 } +// { dg-error ".E0603." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/privacy-struct-ctor.rs b/gcc/testsuite/rust/rustc/ui/resolve/privacy-struct-ctor.rs new file mode 100644 index 000000000000..b8cff5e0adc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/privacy-struct-ctor.rs @@ -0,0 +1,48 @@ +// aux-build:privacy-struct-ctor.rs + +extern crate privacy_struct_ctor as xcrate; + +mod m { + pub struct S(u8); + pub struct S2 { + s: u8 + } + + pub mod n { + pub(in m) struct Z(pub(in m::n) u8); + } + + use m::n::Z; // OK, only the type is imported + + fn f() { + n::Z; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + Z; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + } +} + +use m::S; // OK, only the type is imported +use m::S2; // OK, only the type is imported + +fn main() { + m::S; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + let _: S = m::S(2); +// { dg-error ".E0603." "" { target *-*-* } .-1 } + S; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + m::n::Z; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + + S2; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + + xcrate::m::S; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + xcrate::S; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + xcrate::m::n::Z; +// { dg-error ".E0603." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/raw-ident-in-path.rs b/gcc/testsuite/rust/rustc/ui/resolve/raw-ident-in-path.rs new file mode 100644 index 000000000000..c354c6c096e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/raw-ident-in-path.rs @@ -0,0 +1,6 @@ +// Regression test for issue #63882. + +type A = crate::r#break; // { dg-error ".E0412." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-assoc-suggestions.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-assoc-suggestions.rs new file mode 100644 index 000000000000..ca4ba9062550 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-assoc-suggestions.rs @@ -0,0 +1,40 @@ +// Make sure associated items are recommended only in appropriate contexts. + +struct S { + field: u8, +} + +trait Tr { + fn method(&self); + type Type; +} + +impl Tr for S { + type Type = u8; + + fn method(&self) { + let _: field; +// { dg-error ".E0412." "" { target *-*-* } .-1 } + let field(..); +// { dg-error ".E0531." "" { target *-*-* } .-1 } + field; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + + let _: Type; +// { dg-error ".E0412." "" { target *-*-* } .-1 } + let Type(..); +// { dg-error ".E0531." "" { target *-*-* } .-1 } + Type; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + + let _: method; +// { dg-error ".E0412." "" { target *-*-* } .-1 } + let method(..); +// { dg-error ".E0531." "" { target *-*-* } .-1 } + method; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-bad-import-prefix.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-bad-import-prefix.rs new file mode 100644 index 000000000000..cd13c6ecb7c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-bad-import-prefix.rs @@ -0,0 +1,15 @@ +mod m {} +enum E {} +struct S; +trait Tr {} + +use {}; // OK +use ::{}; // OK +use m::{}; // OK +use E::{}; // OK +use S::{}; // FIXME, this and `use S::{self};` should be an error +use Tr::{}; // FIXME, this and `use Tr::{self};` should be an error +use Nonexistent::{}; // { dg-error ".E0432." "" { target *-*-* } } + +fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-bad-visibility.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-bad-visibility.rs new file mode 100644 index 000000000000..347c3bfee8ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-bad-visibility.rs @@ -0,0 +1,16 @@ +enum E {} +trait Tr {} + +pub(in E) struct S; // { dg-error ".E0577." "" { target *-*-* } } +pub(in Tr) struct Z; // { dg-error ".E0577." "" { target *-*-* } } +pub(in std::vec) struct F; // { dg-error ".E0742." "" { target *-*-* } } +pub(in nonexistent) struct G; // { dg-error ".E0433." "" { target *-*-* } } +pub(in too_soon) struct H; // { dg-error ".E0433." "" { target *-*-* } } + +// Visibilities are resolved eagerly without waiting for modules becoming fully populated. +// Visibilities can only use ancestor modules legally which are always available in time, +// so the worst thing that can happen due to eager resolution is a suboptimal error message. +mod too_soon {} + +fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs new file mode 100644 index 000000000000..14464f7efc26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-extern-crate-vs-extern-crate.rs @@ -0,0 +1,5 @@ +extern crate std; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-import-vs-extern-crate.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-import-vs-extern-crate.rs new file mode 100644 index 000000000000..0e91d6e9f2a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-import-vs-extern-crate.rs @@ -0,0 +1,5 @@ +use std::slice as std; // { dg-error ".E0254." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-import-vs-import.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-import-vs-import.rs new file mode 100644 index 000000000000..4e522bac4d67 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-import-vs-import.rs @@ -0,0 +1,10 @@ +// run-rustfix + +#[allow(unused_imports)] +use std::mem::transmute; +use std::mem::transmute; +// { dg-error ".E0252." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-item-vs-extern-crate.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-item-vs-extern-crate.rs new file mode 100644 index 000000000000..6c377e72086a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-item-vs-extern-crate.rs @@ -0,0 +1,6 @@ +fn std() {} +mod std {} // { dg-error ".E0260." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-item-vs-import.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-item-vs-import.rs new file mode 100644 index 000000000000..349fa163951b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-item-vs-import.rs @@ -0,0 +1,9 @@ +use std::mem::transmute; + +fn transmute() {} +// { dg-error ".E0255." "" { target *-*-* } .-1 } +// { dg-error ".E0255." "" { target *-*-* } .-2 } +// { dg-error ".E0255." "" { target *-*-* } .-3 } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-type-vs-import.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-type-vs-import.rs new file mode 100644 index 000000000000..b70c0b28bf92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-conflict-type-vs-import.rs @@ -0,0 +1,8 @@ +use std::slice::Iter; + +struct Iter; +// { dg-error ".E0255." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-hint-macro.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-hint-macro.rs new file mode 100644 index 000000000000..181990df1ef9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-hint-macro.rs @@ -0,0 +1,5 @@ +fn main() { + assert(true); +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-inconsistent-binding-mode.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-inconsistent-binding-mode.rs new file mode 100644 index 000000000000..32933428f0e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-inconsistent-binding-mode.rs @@ -0,0 +1,42 @@ +enum Opts { + A(isize), + B(isize), + C(isize), +} + +fn matcher1(x: Opts) { + match x { + Opts::A(ref i) | Opts::B(i) => {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + Opts::C(_) => {} + } +} + +fn matcher2(x: Opts) { + match x { + Opts::A(ref i) | Opts::B(i) => {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + Opts::C(_) => {} + } +} + +fn matcher4(x: Opts) { + match x { + Opts::A(ref mut i) | Opts::B(ref i) => {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + Opts::C(_) => {} + } +} + +fn matcher5(x: Opts) { + match x { + Opts::A(ref i) | Opts::B(ref i) => {} + Opts::C(_) => {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-inconsistent-names.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-inconsistent-names.rs new file mode 100644 index 000000000000..b27314c8d6fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-inconsistent-names.rs @@ -0,0 +1,37 @@ +#![allow(non_camel_case_types)] + +enum E { A, B, c } + +mod m { + const CONST1: usize = 10; + const Const2: usize = 20; +} + +fn main() { + let y = 1; + match y { + a | b => {} // { dg-error ".E0408." "" { target *-*-* } } +// { dg-error ".E0408." "" { target *-*-* } .-2 } + } + + let x = (E::A, E::B); + match x { + (A, B) | (ref B, c) | (c, A) => () +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } +// { help ".E0308." "" { target *-*-* } .-6 } + } + + let z = (10, 20); + match z { + (CONST1, _) | (_, Const2) => () +// { dg-error ".E0408." "" { target *-*-* } .-1 } +// { help ".E0408." "" { target *-*-* } .-2 } +// { dg-error ".E0408." "" { target *-*-* } .-3 } +// { help ".E0408." "" { target *-*-* } .-4 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-label.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-label.rs new file mode 100644 index 000000000000..01a8eda111cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-label.rs @@ -0,0 +1,14 @@ +fn f() { + 'l: loop { + fn g() { + loop { + break 'l; // { dg-error ".E0767." "" { target *-*-* } } + } + } + } + + loop { 'w: while break 'w { } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-primitive-fallback.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-primitive-fallback.rs new file mode 100644 index 000000000000..49eacb256028 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-primitive-fallback.rs @@ -0,0 +1,11 @@ +fn main() { + // Make sure primitive type fallback doesn't work in value namespace + std::mem::size_of(u16); +// { dg-error ".E0061." "" { target *-*-* } .-1 } +// { dg-error ".E0061." "" { target *-*-* } .-2 } + + // Make sure primitive type fallback doesn't work with global paths + let _: ::u8; +// { dg-error ".E0412." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-self-in-impl-2.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-self-in-impl-2.rs new file mode 100644 index 000000000000..04ac3d897535 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-self-in-impl-2.rs @@ -0,0 +1,8 @@ +struct S(T); +trait Tr {} + +impl Self for S {} // { dg-error ".E0411." "" { target *-*-* } } +impl Self::N for S {} // { dg-error ".E0405." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-self-in-impl.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-self-in-impl.rs new file mode 100644 index 000000000000..7f3b75c5cc5e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-self-in-impl.rs @@ -0,0 +1,21 @@ +#![feature(associated_type_defaults)] + +struct S(T); +trait Tr { + type A = (); +} + +impl Tr for S {} // OK +impl> Tr for S {} // OK +impl Tr for S where Self: Copy {} // OK +impl Tr for S where S: Copy {} // OK +impl Tr for S where Self::A: Copy {} // OK + +impl Tr for Self {} // { dg-error ".E0391." "" { target *-*-* } } +impl Tr for S {} // { dg-error ".E0391." "" { target *-*-* } } +impl Self {} // { dg-error ".E0391." "" { target *-*-* } } +impl S {} // { dg-error ".E0391." "" { target *-*-* } } +impl Tr for S {} // { dg-error ".E0391." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-speculative-adjustment.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-speculative-adjustment.rs new file mode 100644 index 000000000000..671ab021cb33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-speculative-adjustment.rs @@ -0,0 +1,31 @@ +// Make sure speculative path resolution works properly when resolution +// adjustment happens and no extra errors is reported. + +struct S { + field: u8, +} + +trait Tr { + fn method(&self); +} + +impl Tr for S { + fn method(&self) { + fn g() { + // Speculative resolution of `Self` and `self` silently fails, + // "did you mean" messages are not printed. + field; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + method(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } + + field; +// { dg-error ".E0425." "" { target *-*-* } .-1 } + method(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-type-param-in-item-in-trait.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-type-param-in-item-in-trait.rs new file mode 100644 index 000000000000..0e74cfaaaec7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-type-param-in-item-in-trait.rs @@ -0,0 +1,36 @@ +// Issue #14603: Check for references to type parameters from the +// outer scope (in this case, the trait) used on items in an inner +// scope (in this case, the enum). + +trait TraitA { + fn outer(&self) { + enum Foo { + Variance(A) +// { dg-error ".E0401." "" { target *-*-* } .-1 } + } + } +} + +trait TraitB { + fn outer(&self) { + struct Foo(A); +// { dg-error ".E0401." "" { target *-*-* } .-1 } + } +} + +trait TraitC { + fn outer(&self) { + struct Foo { a: A } +// { dg-error ".E0401." "" { target *-*-* } .-1 } + } +} + +trait TraitD { + fn outer(&self) { + fn foo(a: A) { } +// { dg-error ".E0401." "" { target *-*-* } .-1 } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-unknown-trait.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-unknown-trait.rs new file mode 100644 index 000000000000..5b6b4c6bcc51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-unknown-trait.rs @@ -0,0 +1,11 @@ +trait NewTrait : SomeNonExistentTrait {} +// { dg-error ".E0405." "" { target *-*-* } .-1 } + +impl SomeNonExistentTrait for isize {} +// { dg-error ".E0405." "" { target *-*-* } .-1 } + +fn f() {} +// { dg-error ".E0405." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/resolve-variant-assoc-item.rs b/gcc/testsuite/rust/rustc/ui/resolve/resolve-variant-assoc-item.rs new file mode 100644 index 000000000000..6ec63043fe46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/resolve-variant-assoc-item.rs @@ -0,0 +1,8 @@ +enum E { V } +use E::V; + +fn main() { + E::V::associated_item; // { dg-error ".E0433." "" { target *-*-* } } + V::associated_item; // { dg-error ".E0433." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/suggest-path-instead-of-mod-dot-item.rs b/gcc/testsuite/rust/rustc/ui/resolve/suggest-path-instead-of-mod-dot-item.rs new file mode 100644 index 000000000000..d40eba4f8853 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/suggest-path-instead-of-mod-dot-item.rs @@ -0,0 +1,60 @@ +// Beginners write `mod.item` when they should write `mod::item`. +// This tests that we suggest the latter when we encounter the former. + +pub mod a { + pub const I: i32 = 1; + + pub fn f() -> i32 { 2 } + + pub mod b { + pub const J: i32 = 3; + + pub fn g() -> i32 { 4 } + } +} + +fn h1() -> i32 { + a.I +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + +fn h2() -> i32 { + a.g() +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + +fn h3() -> i32 { + a.b.J +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + +fn h4() -> i32 { + a::b.J +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + +fn h5() { + a.b.f(); +// { dg-error ".E0423." "" { target *-*-* } .-1 } + let v = Vec::new(); + v.push(a::b); +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + +fn h6() -> i32 { + a::b.f() +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + +fn h7() { + a::b +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + +fn h8() -> i32 { + a::b() +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/token-error-correct-2.rs b/gcc/testsuite/rust/rustc/ui/resolve/token-error-correct-2.rs new file mode 100644 index 000000000000..f86d18185245 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/token-error-correct-2.rs @@ -0,0 +1,8 @@ +// Test that we do some basic error correction in the tokeniser (and don't ICE). + +fn main() { + if foo { +// { dg-error ".E0425." "" { target *-*-* } .-1 } + ) // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/token-error-correct-3.rs b/gcc/testsuite/rust/rustc/ui/resolve/token-error-correct-3.rs new file mode 100644 index 000000000000..548ce6cff1fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/token-error-correct-3.rs @@ -0,0 +1,28 @@ +// ignore-cloudabi no std::fs support + +// Test that we do some basic error correction in the tokeniser (and don't spew +// too many bogus errors). + +pub mod raw { + use std::{io, fs}; + use std::path::Path; + + pub fn ensure_dir_exists, F: FnOnce(&Path)>(path: P, + callback: F) + -> io::Result { + if !is_directory(path.as_ref()) { +// { dg-error ".E0425." "" { target *-*-* } .-1 } + callback(path.as_ref(); +// { dg-error "" "" { target *-*-* } .-1 } + fs::create_dir_all(path.as_ref()).map(|()| true) + } else { +// { dg-error "" "" { target *-*-* } .-1 } + Ok(false); + } + + panic!(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/token-error-correct-4.rs b/gcc/testsuite/rust/rustc/ui/resolve/token-error-correct-4.rs new file mode 100644 index 000000000000..ad155408c110 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/token-error-correct-4.rs @@ -0,0 +1,11 @@ +// run-rustfix +// Test that we do some basic error correction in the tokeniser and apply suggestions. + +fn setsuna(_: ()) {} + +fn kazusa() {} + +fn main() { + setsuna(kazusa(); // { dg-error "" "" { target *-*-* } } +} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/token-error-correct.rs b/gcc/testsuite/rust/rustc/ui/resolve/token-error-correct.rs new file mode 100644 index 000000000000..1a094dd7202b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/token-error-correct.rs @@ -0,0 +1,10 @@ +// Test that we do some basic error correction in the tokeniser. + +fn main() { + foo(bar(; +// { dg-error ".E0425." "" { target *-*-* } .-1 } +} +// { dg-error "" "" { target *-*-* } .-1 } + +fn foo(_: usize) {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/tuple-struct-alias.rs b/gcc/testsuite/rust/rustc/ui/resolve/tuple-struct-alias.rs new file mode 100644 index 000000000000..a701e4c76a09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/tuple-struct-alias.rs @@ -0,0 +1,10 @@ +struct S(u8, u16); +type A = S; + +fn main() { + let s = A(0, 1); // { dg-error ".E0423." "" { target *-*-* } } + match s { + A(..) => {} // { dg-error ".E0532." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/typo-suggestion-named-underscore.rs b/gcc/testsuite/rust/rustc/ui/resolve/typo-suggestion-named-underscore.rs new file mode 100644 index 000000000000..b638fee53438 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/typo-suggestion-named-underscore.rs @@ -0,0 +1,15 @@ +const _: () = (); + +fn main() { + a // Shouldn't suggest underscore +// { dg-error ".E0425." "" { target *-*-* } .-1 } +} + +trait Unknown {} + +#[allow(unused_imports)] +use Unknown as _; + +fn foo(x: T) {} // Shouldn't suggest underscore +// { dg-error ".E0405." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/unboxed-closure-sugar-nonexistent-trait.rs b/gcc/testsuite/rust/rustc/ui/resolve/unboxed-closure-sugar-nonexistent-trait.rs new file mode 100644 index 000000000000..60c10e45cb50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/unboxed-closure-sugar-nonexistent-trait.rs @@ -0,0 +1,10 @@ +fn f isize>(x: F) {} +// { dg-error ".E0405." "" { target *-*-* } .-1 } + +type Typedef = isize; + +fn g isize>(x: F) {} +// { dg-error ".E0404." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/unresolved_static_type_field.rs b/gcc/testsuite/rust/rustc/ui/resolve/unresolved_static_type_field.rs new file mode 100644 index 000000000000..ef56c1b80543 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/unresolved_static_type_field.rs @@ -0,0 +1,15 @@ +fn f(_: bool) {} + +struct Foo { + cx: bool, +} + +impl Foo { + fn bar() { + f(cx); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/use_suggestion.rs b/gcc/testsuite/rust/rustc/ui/resolve/use_suggestion.rs new file mode 100644 index 000000000000..c222a3e3747b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/use_suggestion.rs @@ -0,0 +1,8 @@ +fn main() { + let x1 = HashMap::new(); // { dg-error ".E0433." "" { target *-*-* } } + let x2 = GooMap::new(); // { dg-error ".E0433." "" { target *-*-* } } + + let y1: HashMap; // { dg-error ".E0412." "" { target *-*-* } } + let y2: GooMap; // { dg-error ".E0412." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/use_suggestion_placement.rs b/gcc/testsuite/rust/rustc/ui/resolve/use_suggestion_placement.rs new file mode 100644 index 000000000000..2ba192d94b43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/use_suggestion_placement.rs @@ -0,0 +1,29 @@ +// ignore-cloudabi no std::path support + +macro_rules! y { + () => {} +} + +mod m { + pub const A: i32 = 0; +} + +mod foo { + #[derive(Debug)] + pub struct Foo; + + // test whether the use suggestion isn't + // placed into the expansion of `#[derive(Debug)] + type Bar = Path; // { dg-error ".E0412." "" { target *-*-* } } +} + +fn main() { + y!(); + let _ = A; // { dg-error ".E0425." "" { target *-*-* } } + foo(); +} + +fn foo() { + type Dict = HashMap; // { dg-error ".E0412." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve/visibility-indeterminate.rs b/gcc/testsuite/rust/rustc/ui/resolve/visibility-indeterminate.rs new file mode 100644 index 000000000000..d1295d494744 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve/visibility-indeterminate.rs @@ -0,0 +1,8 @@ +// edition:2018 + +foo!(); // { dg-error "" "" { target *-*-* } } + +pub(in ::bar) struct Baz {} // { dg-error ".E0578." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resolve_self_super_hint.rs b/gcc/testsuite/rust/rustc/ui/resolve_self_super_hint.rs new file mode 100644 index 000000000000..adde63b4874d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resolve_self_super_hint.rs @@ -0,0 +1,28 @@ +mod a { + extern crate alloc; + use alloc::HashMap; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +// { help ".E0432." "" { target *-*-* } .-2 } +// { suggestion ".E0432." "" { target *-*-* } .-3 } + mod b { + use alloc::HashMap; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +// { help ".E0432." "" { target *-*-* } .-2 } +// { suggestion ".E0432." "" { target *-*-* } .-3 } + mod c { + use alloc::HashMap; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +// { help ".E0432." "" { target *-*-* } .-2 } +// { suggestion ".E0432." "" { target *-*-* } .-3 } + mod d { + use alloc::HashMap; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +// { help ".E0432." "" { target *-*-* } .-2 } +// { suggestion ".E0432." "" { target *-*-* } .-3 } + } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/resource-assign-is-not-copy.rs b/gcc/testsuite/rust/rustc/ui/resource-assign-is-not-copy.rs new file mode 100644 index 000000000000..2f5a81b29bb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resource-assign-is-not-copy.rs @@ -0,0 +1,34 @@ +// run-pass + +#![allow(non_camel_case_types)] +use std::cell::Cell; + +#[derive(Debug)] +struct r<'a> { + i: &'a Cell, +} + +impl<'a> Drop for r<'a> { + fn drop(&mut self) { + self.i.set(self.i.get() + 1); + } +} + +fn r(i: &Cell) -> r { + r { + i: i + } +} + +pub fn main() { + let i = &Cell::new(0); + // Even though these look like copies, they are guaranteed not to be + { + let a = r(i); + let b = (a, 10); + let (c, _d) = b; + println!("{:?}", c); + } + assert_eq!(i.get(), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/resource-destruct.rs b/gcc/testsuite/rust/rustc/ui/resource-destruct.rs new file mode 100644 index 000000000000..5fec0fb177b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/resource-destruct.rs @@ -0,0 +1,32 @@ +// run-pass + +#![allow(non_camel_case_types)] +use std::cell::Cell; + +struct shrinky_pointer<'a> { + i: &'a Cell, +} + +impl<'a> Drop for shrinky_pointer<'a> { + fn drop(&mut self) { + println!("Hello!"); self.i.set(self.i.get() - 1); + } +} + +impl<'a> shrinky_pointer<'a> { + pub fn look_at(&self) -> isize { return self.i.get(); } +} + +fn shrinky_pointer(i: &Cell) -> shrinky_pointer { + shrinky_pointer { + i: i + } +} + +pub fn main() { + let my_total = &Cell::new(10); + { let pt = shrinky_pointer(my_total); assert_eq!(pt.look_at(), 10); } + println!("my_total = {}", my_total.get()); + assert_eq!(my_total.get(), 9); +} + diff --git a/gcc/testsuite/rust/rustc/ui/result-opt-conversions.rs b/gcc/testsuite/rust/rustc/ui/result-opt-conversions.rs new file mode 100644 index 000000000000..68db24f17e75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/result-opt-conversions.rs @@ -0,0 +1,48 @@ +// run-pass + +#[derive(Copy, Clone, Debug, PartialEq)] +struct BadNumErr; + +fn try_num(x: i32) -> Result { + if x <= 5 { + Ok(x + 1) + } else { + Err(BadNumErr) + } +} + +type ResOpt = Result, BadNumErr>; +type OptRes = Option>; + +fn main() { + let mut x: ResOpt = Ok(Some(5)); + let mut y: OptRes = Some(Ok(5)); + assert_eq!(x, y.transpose()); + assert_eq!(x.transpose(), y); + + x = Ok(None); + y = None; + assert_eq!(x, y.transpose()); + assert_eq!(x.transpose(), y); + + x = Err(BadNumErr); + y = Some(Err(BadNumErr)); + assert_eq!(x, y.transpose()); + assert_eq!(x.transpose(), y); + + let res: Result, BadNumErr> = + (0..10) + .map(|x| { + let y = try_num(x)?; + Ok(if y % 2 == 0 { + Some(y - 1) + } else { + None + }) + }) + .filter_map(Result::transpose) + .collect(); + + assert_eq!(res, Err(BadNumErr)) +} + diff --git a/gcc/testsuite/rust/rustc/ui/ret-bang.rs b/gcc/testsuite/rust/rustc/ui/ret-bang.rs new file mode 100644 index 000000000000..f446565845d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ret-bang.rs @@ -0,0 +1,14 @@ +// run-pass + +fn my_err(s: String) -> ! { println!("{}", s); panic!(); } + +fn okay(i: usize) -> isize { + if i == 3 { + my_err("I don't like three".to_string()); + } else { + return 42; + } +} + +pub fn main() { okay(4); } + diff --git a/gcc/testsuite/rust/rustc/ui/ret-non-nil.rs b/gcc/testsuite/rust/rustc/ui/ret-non-nil.rs new file mode 100644 index 000000000000..257492fd4e0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ret-non-nil.rs @@ -0,0 +1,8 @@ +// error-pattern: `return;` in a function whose return type is not `()` + +fn f() { return; } + +fn g() -> isize { return; } + +fn main() { f(); g(); } + diff --git a/gcc/testsuite/rust/rustc/ui/ret-none.rs b/gcc/testsuite/rust/rustc/ui/ret-none.rs new file mode 100644 index 000000000000..b5428ff098bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ret-none.rs @@ -0,0 +1,14 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] + + +// pretty-expanded FIXME #23616 + +enum option { none, some(T), } + +fn f() -> option { return option::none; } + +pub fn main() { f::(); } + diff --git a/gcc/testsuite/rust/rustc/ui/retslot-cast.rs b/gcc/testsuite/rust/rustc/ui/retslot-cast.rs new file mode 100644 index 000000000000..8294d7b7cc42 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/retslot-cast.rs @@ -0,0 +1,23 @@ +#![allow(warnings)] + +pub fn fail(x: Option<&(Iterator+Send)>) + -> Option<&Iterator> { + // This call used to trigger an LLVM assertion because the return + // slot had type "Option<&Iterator>"* instead of + // "Option<&(Iterator+Send)>"* -- but this now yields a + // compilation error and I'm not sure how to create a comparable + // test. To ensure that this PARTICULAR failure doesn't occur + // again, though, I've left this test here, so if this ever starts + // to compile again, we can adjust the test appropriately (clearly + // it should never ICE...). -nmatsakis + inner(x) // { dg-error ".E0308." "" { target *-*-* } } +} + +pub fn inner(x: Option<&(Iterator+Send)>) + -> Option<&(Iterator+Send)> { + x +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/return-disjoint-regions.rs b/gcc/testsuite/rust/rustc/ui/return-disjoint-regions.rs new file mode 100644 index 000000000000..b086e3fcc4ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/return-disjoint-regions.rs @@ -0,0 +1,8 @@ +// See https://github.com/rust-lang/rust/pull/67911#issuecomment-576023915 +fn f<'a, 'b>(x: i32) -> (&'a i32, &'b i32) { + let y = &x; + (y, y) // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/return-nil.rs b/gcc/testsuite/rust/rustc/ui/return-nil.rs new file mode 100644 index 000000000000..8fc46a26fe11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/return-nil.rs @@ -0,0 +1,7 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn f() { let x: () = (); return x; } + +pub fn main() { let _x = f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/return/return-from-diverging.rs b/gcc/testsuite/rust/rustc/ui/return/return-from-diverging.rs new file mode 100644 index 000000000000..34ebaa4c9052 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/return/return-from-diverging.rs @@ -0,0 +1,9 @@ +// Test that return another type in place of ! raises a type mismatch. + +fn fail() -> ! { + return "wow"; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/return/return-match-array-const.rs b/gcc/testsuite/rust/rustc/ui/return/return-match-array-const.rs new file mode 100644 index 000000000000..50e0559e6859 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/return/return-match-array-const.rs @@ -0,0 +1,11 @@ +fn main() { + [(); return match 0 { n => n }]; +// { dg-error ".E0572." "" { target *-*-* } .-1 } + + [(); return match 0 { 0 => 0 }]; +// { dg-error ".E0572." "" { target *-*-* } .-1 } + + [(); return match () { 'a' => 0, _ => 0 }]; +// { dg-error ".E0572." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/return/return-type.rs b/gcc/testsuite/rust/rustc/ui/return/return-type.rs new file mode 100644 index 000000000000..9c704e7988ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/return/return-type.rs @@ -0,0 +1,15 @@ +struct S { + t: T, +} + +fn foo(x: T) -> S { + S { t: x } +} + +fn bar() { + foo(4 as usize) +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/return/return-unit-from-diverging.rs b/gcc/testsuite/rust/rustc/ui/return/return-unit-from-diverging.rs new file mode 100644 index 000000000000..5d7ca4900ae6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/return/return-unit-from-diverging.rs @@ -0,0 +1,10 @@ +// Test that we get the usual error that we'd get for any other return type and not something about +// diverging functions not being able to return. + +fn fail() -> ! { + return; // { dg-error ".E0069." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs b/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs new file mode 100644 index 000000000000..225bd5cafbc0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs @@ -0,0 +1,20 @@ +// Adaptation of existing ui test (from way back in +// rust-lang/rust#2329), that starts passing with this feature in +// place. + +// run-pass + +use std::sync::mpsc::channel; + +fn main() { + let (tx, rx) = channel(); + let x = Some(rx); + tx.send(false).unwrap(); + tx.send(false).unwrap(); + match x { + Some(z) if z.recv().unwrap() => { panic!() }, + Some(z) => { assert!(!z.recv().unwrap()); }, + None => panic!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/former-E0008-now-pass.rs b/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/former-E0008-now-pass.rs new file mode 100644 index 000000000000..6a494198091f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/former-E0008-now-pass.rs @@ -0,0 +1,12 @@ +// This test used to emit E0008 but now passed since `bind_by_move_pattern_guards` +// have been stabilized. + +// check-pass + +fn main() { + match Some("hi".to_string()) { + Some(s) if s.len() == 0 => {}, + _ => {}, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs b/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs new file mode 100644 index 000000000000..7687710fe012 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs @@ -0,0 +1,44 @@ +// run-pass + +struct A { a: Box } + +impl A { + fn get(&self) -> i32 { *self.a } +} + +fn foo(n: i32) -> i32 { + let x = A { a: Box::new(n) }; + let y = match x { + A { a: v } if *v == 42 => v, + _ => Box::new(0), + }; + *y +} + +fn bar(n: i32) -> i32 { + let x = A { a: Box::new(n) }; + let y = match x { + A { a: v } if x.get() == 42 => v, + _ => Box::new(0), + }; + *y +} + +fn baz(n: i32) -> i32 { + let x = A { a: Box::new(n) }; + let y = match x { + A { a: v } if *v.clone() == 42 => v, + _ => Box::new(0), + }; + *y +} + +fn main() { + assert_eq!(foo(107), 0); + assert_eq!(foo(42), 42); + assert_eq!(bar(107), 0); + assert_eq!(bar(42), 42); + assert_eq!(baz(107), 0); + assert_eq!(baz(42), 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs b/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs new file mode 100644 index 000000000000..f54d74042c01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs @@ -0,0 +1,14 @@ +enum VecWrapper { A(Vec) } + +fn foo(x: VecWrapper) -> usize { + match x { + VecWrapper::A(v) if { drop(v); false } => 1, +// { dg-error ".E0507." "" { target *-*-* } .-1 } + VecWrapper::A(v) => v.len() + } +} + +fn main() { + foo(VecWrapper::A(vec![107])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs b/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs new file mode 100644 index 000000000000..f3d0fbd221ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs @@ -0,0 +1,15 @@ +struct A { a: Box } + +fn foo(n: i32) { + let x = A { a: Box::new(n) }; + let _y = match x { + A { a: v } if { drop(v); true } => v, +// { dg-error ".E0507." "" { target *-*-* } .-1 } + _ => Box::new(0), + }; +} + +fn main() { + foo(107); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs new file mode 100644 index 000000000000..38be4f6c147c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-embedded.rs @@ -0,0 +1,27 @@ +// Test explores how `#[structral_match]` behaves in tandem with +// `*const` and `*mut` pointers. + +// run-pass + +#![warn(pointer_structural_match)] + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive +// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapEmbedded(*const NoDerive); + +const WRAP_UNSAFE_EMBEDDED: WrapEmbedded = WrapEmbedded(std::ptr::null()); + +fn main() { + match WRAP_UNSAFE_EMBEDDED { + WRAP_UNSAFE_EMBEDDED => { println!("WRAP_UNSAFE_EMBEDDED correctly matched itself"); } + _ => { panic!("WRAP_UNSAFE_EMBEDDED did not match itself"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs new file mode 100644 index 000000000000..a11b69e9ba56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-direct-unsafe-ptr-param.rs @@ -0,0 +1,27 @@ +// Test explores how `#[structral_match]` behaves in tandem with +// `*const` and `*mut` pointers. + +// run-pass + +#![warn(pointer_structural_match)] + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive +// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapParam(*const X); + +const WRAP_UNSAFE_PARAM: WrapParam = WrapParam(std::ptr::null()); + +fn main() { + match WRAP_UNSAFE_PARAM { + WRAP_UNSAFE_PARAM => { println!("WRAP_UNSAFE_PARAM correctly matched itself"); } + _ => { panic!("WRAP_UNSAFE_PARAM did not match itself"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs new file mode 100644 index 000000000000..4b527c6e04a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-embedded.rs @@ -0,0 +1,27 @@ +// Test explores how `#[structral_match]` behaves in tandem with +// `*const` and `*mut` pointers. + +// run-pass + +#![warn(pointer_structural_match)] + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive +// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapEmbedded(*const NoDerive); + +const WRAP_UNSAFE_EMBEDDED: & &WrapEmbedded = & &WrapEmbedded(std::ptr::null()); + +fn main() { + match WRAP_UNSAFE_EMBEDDED { + WRAP_UNSAFE_EMBEDDED => { println!("WRAP_UNSAFE_EMBEDDED correctly matched itself"); } + _ => { panic!("WRAP_UNSAFE_EMBEDDED did not match itself"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs new file mode 100644 index 000000000000..3bc29924dd50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-hide-behind-indirect-unsafe-ptr-param.rs @@ -0,0 +1,27 @@ +// Test explores how `#[structral_match]` behaves in tandem with +// `*const` and `*mut` pointers. + +// run-pass + +#![warn(pointer_structural_match)] + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive +// (which doesn't matter here because `<*const T>::eq` won't recur on `T`). +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapParam(*const X); + +const WRAP_UNSAFE_PARAM: & &WrapParam = & &WrapParam(std::ptr::null()); + +fn main() { + match WRAP_UNSAFE_PARAM { + WRAP_UNSAFE_PARAM => { println!("WRAP_UNSAFE_PARAM correctly matched itself"); } + _ => { panic!("WRAP_UNSAFE_PARAM did not match itself"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-use-behind-cousin-variant.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-use-behind-cousin-variant.rs new file mode 100644 index 000000000000..deaf0c2485b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/allow-use-behind-cousin-variant.rs @@ -0,0 +1,60 @@ +// rust-lang/rust#62614: we want to allow matching on constants of types that +// have non-structural-match variants, *if* the constant itself does not use +// any such variant. + +// NOTE: for now, deliberately leaving the lint `indirect_structural_match` set +// to its default, so that we will not issue a diangostic even if +// rust-lang/rust#62614 remains an open issue. + +// run-pass + +struct Sum(u32, u32); + +impl PartialEq for Sum { + fn eq(&self, other: &Self) -> bool { self.0 + self.1 == other.0 + other.1 } +} + +impl Eq for Sum { } + +#[derive(PartialEq, Eq)] +enum Eek { + TheConst, + UnusedByTheConst(Sum) +} + +const THE_CONST: Eek = Eek::TheConst; +const SUM_THREE: Eek = Eek::UnusedByTheConst(Sum(3,0)); + +const EEK_ZERO: &[Eek] = &[]; +const EEK_ONE: &[Eek] = &[THE_CONST]; + +pub fn main() { + match Eek::UnusedByTheConst(Sum(1,2)) { + ref sum if sum == &SUM_THREE => { println!("Hello 0"); } + _ => { println!("Gbye"); } + } + + match Eek::TheConst { + THE_CONST => { println!("Hello 1"); } + _ => { println!("Gbye"); } + } + + + match & &Eek::TheConst { + & & THE_CONST => { println!("Hello 2"); } + _ => { println!("Gbye"); } + } + + match & & &[][..] { + & & EEK_ZERO => { println!("Hello 3"); } + & & EEK_ONE => { println!("Gbye"); } + _ => { println!("Gbye"); } + } + + match & & &[Eek::TheConst][..] { + & & EEK_ZERO => { println!("Gby"); } + & & EEK_ONE => { println!("Hello 4"); } + _ => { println!("Gbye"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs new file mode 100644 index 000000000000..d676a145d808 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.rs @@ -0,0 +1,27 @@ +// This is part of a set of tests exploring the different ways a +// structural-match ADT might try to hold a +// non-structural-match in hidden manner that lets matches +// through that we had intended to reject. +// +// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapInline(NoDerive); + +const WRAP_DIRECT_INLINE: WrapInline = WrapInline(NoDerive(0)); + +fn main() { + match WRAP_DIRECT_INLINE { + WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } +// { dg-error "" "" { target *-*-* } .-1 } + _ => { println!("WRAP_DIRECT_INLINE did not match itself"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs new file mode 100644 index 000000000000..f45ecc99478c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.rs @@ -0,0 +1,27 @@ +// This is part of a set of tests exploring the different ways a +// structural-match ADT might try to hold a +// non-structural-match in hidden manner that lets matches +// through that we had intended to reject. +// +// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 +#![warn(indirect_structural_match)] +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapParam(T); + +const WRAP_DIRECT_PARAM: WrapParam = WrapParam(NoDerive(0)); + +fn main() { + match WRAP_DIRECT_PARAM { + WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } +// { dg-error "" "" { target *-*-* } .-1 } + _ => { println!("WRAP_DIRECT_PARAM did not match itself"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs new file mode 100644 index 000000000000..9fc1365fea27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.rs @@ -0,0 +1,30 @@ +// This is part of a set of tests exploring the different ways a +// structural-match ADT might try to hold a +// non-structural-match in hidden manner that lets matches +// through that we had intended to reject. +// +// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 +#![warn(indirect_structural_match)] +// run-pass + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapInline<'a>(&'a &'a NoDerive); + +const WRAP_DOUBLY_INDIRECT_INLINE: & &WrapInline = & &WrapInline(& & NoDerive(0)); + +fn main() { + match WRAP_DOUBLY_INDIRECT_INLINE { + WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + _ => { println!("WRAP_DOUBLY_INDIRECT_INLINE correctly did not match itself"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs new file mode 100644 index 000000000000..1e5e561bd54c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.rs @@ -0,0 +1,30 @@ +// This is part of a set of tests exploring the different ways a +// structural-match ADT might try to hold a +// non-structural-match in hidden manner that lets matches +// through that we had intended to reject. +// +// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 +#![warn(indirect_structural_match)] +// run-pass + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapParam<'a, T>(&'a &'a T); + +const WRAP_DOUBLY_INDIRECT_PARAM: & &WrapParam = & &WrapParam(& & NoDerive(0)); + +fn main() { + match WRAP_DOUBLY_INDIRECT_PARAM { + WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + _ => { println!("WRAP_DOUBLY_INDIRECT_PARAM correctly did not match itself"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs new file mode 100644 index 000000000000..f2ba189a17cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.rs @@ -0,0 +1,30 @@ +// This is part of a set of tests exploring the different ways a +// structural-match ADT might try to hold a +// non-structural-match in hidden manner that lets matches +// through that we had intended to reject. +// +// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 +#![warn(indirect_structural_match)] +// run-pass + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapInline(NoDerive); + +const WRAP_INDIRECT_INLINE: & &WrapInline = & &WrapInline(NoDerive(0)); + +fn main() { + match WRAP_INDIRECT_INLINE { + WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + _ => { println!("WRAP_INDIRECT_INLINE did not match itself"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs new file mode 100644 index 000000000000..23fb4230e2d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.rs @@ -0,0 +1,30 @@ +// This is part of a set of tests exploring the different ways a +// structural-match ADT might try to hold a +// non-structural-match in hidden manner that lets matches +// through that we had intended to reject. +// +// See discussion on rust-lang/rust#62307 and rust-lang/rust#62339 +#![warn(indirect_structural_match)] +// run-pass + +struct NoDerive(i32); + +// This impl makes NoDerive irreflexive. +impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } + +impl Eq for NoDerive { } + +#[derive(PartialEq, Eq)] +struct WrapParam(T); + +const WRAP_INDIRECT_PARAM: & &WrapParam = & &WrapParam(NoDerive(0)); + +fn main() { + match WRAP_INDIRECT_PARAM { + WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + _ => { println!("WRAP_INDIRECT_PARAM correctly did not match itself"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/feature-gate.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/feature-gate.rs new file mode 100644 index 000000000000..fdbe6c60734d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/feature-gate.rs @@ -0,0 +1,40 @@ +// Test that use of structural-match traits is only permitted with a feature gate, +// and that if a feature gate is supplied, it permits the type to be +// used in a match. + +// revisions: with_gate no_gate + +// gate-test-structural_match + +#![allow(unused)] +#![feature(rustc_attrs)] +#![cfg_attr(with_gate, feature(structural_match))] + + +struct Foo { + x: u32 +} + +const FOO: Foo = Foo { x: 0 }; + +#[rustc_error] +fn main() { // { dg-error "" "" { target *-*-* } } + let y = Foo { x: 1 }; + match y { + FOO => { } + _ => { } + } +} + +impl std::marker::StructuralPartialEq for Foo { } +// { dg-error "" "" { target *-*-* } .-1 } +impl std::marker::StructuralEq for Foo { } +// { dg-error "" "" { target *-*-* } .-1 } + +impl PartialEq for Foo { + fn eq(&self, other: &Self) -> bool { + self.x == other.x + } +} +impl Eq for Foo { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.rs new file mode 100644 index 000000000000..c399370eb9d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.rs @@ -0,0 +1,136 @@ +// run-pass + +// This file checks that fn ptrs are considered structurally matchable. +// See also rust-lang/rust#63479. + +fn main() { + let mut count = 0; + + // A type which is not structurally matchable: + struct NotSM; + + // And one that is: + #[derive(PartialEq, Eq)] + struct SM; + + fn trivial() {} + + fn sm_to(_: SM) {} + fn not_sm_to(_: NotSM) {} + fn to_sm() -> SM { SM } + fn to_not_sm() -> NotSM { NotSM } + + // To recreate the scenario of interest in #63479, we need to add + // a ref-level-of-indirection so that we descend into the type. + + fn r_sm_to(_: &SM) {} + fn r_not_sm_to(_: &NotSM) {} + fn r_to_r_sm(_: &()) -> &SM { &SM } + fn r_to_r_not_sm(_: &()) -> &NotSM { &NotSM } + + #[derive(PartialEq, Eq)] + struct Wrap(T); + + // In the code below, we put the match input into a local so that + // we can assign it an explicit type that is an fn ptr instead of + // a singleton type of the fn itself that the type inference would + // otherwise assign. + + // Check that fn() is structural-match + const CFN1: Wrap = Wrap(trivial); + let input: Wrap = Wrap(trivial); + match Wrap(input) { + Wrap(CFN1) => count += 1, + Wrap(_) => {} + }; + + // Check that fn(T) is structural-match when T is too. + const CFN2: Wrap = Wrap(sm_to); + let input: Wrap = Wrap(sm_to); + match Wrap(input) { + Wrap(CFN2) => count += 1, + Wrap(_) => {} + }; + + // Check that fn() -> T is structural-match when T is too. + const CFN3: Wrap SM> = Wrap(to_sm); + let input: Wrap SM> = Wrap(to_sm); + match Wrap(input) { + Wrap(CFN3) => count += 1, + Wrap(_) => {} + }; + + // Check that fn(T) is structural-match even if T is not. + const CFN4: Wrap = Wrap(not_sm_to); + let input: Wrap = Wrap(not_sm_to); + match Wrap(input) { + Wrap(CFN4) => count += 1, + Wrap(_) => {} + }; + + // Check that fn() -> T is structural-match even if T is not. + const CFN5: Wrap NotSM> = Wrap(to_not_sm); + let input: Wrap NotSM> = Wrap(to_not_sm); + match Wrap(input) { + Wrap(CFN5) => count += 1, + Wrap(_) => {} + }; + + // Check that fn(&T) is structural-match when T is too. + const CFN6: Wrap = Wrap(r_sm_to); + let input: Wrap = Wrap(r_sm_to); + match Wrap(input) { + Wrap(CFN6) => count += 1, + Wrap(_) => {} + }; + + // Check that fn() -> &T is structural-match when T is too. + const CFN7: Wrap &SM> = Wrap(r_to_r_sm); + let input: Wrap &SM> = Wrap(r_to_r_sm); + match Wrap(input) { + Wrap(CFN7) => count += 1, + Wrap(_) => {} + }; + + // Check that fn(T) is structural-match even if T is not. + const CFN8: Wrap = Wrap(r_not_sm_to); + let input: Wrap = Wrap(r_not_sm_to); + match Wrap(input) { + Wrap(CFN8) => count += 1, + Wrap(_) => {} + }; + + // Check that fn() -> T is structural-match even if T is not. + const CFN9: Wrap &NotSM> = Wrap(r_to_r_not_sm); + let input: Wrap &NotSM> = Wrap(r_to_r_not_sm); + match Wrap(input) { + Wrap(CFN9) => count += 1, + Wrap(_) => {} + }; + + // Check that a type which has fn ptrs is structural-match. + #[derive(PartialEq, Eq)] + struct Foo { + alpha: fn(NotSM), + beta: fn() -> NotSM, + gamma: fn(SM), + delta: fn() -> SM, + } + + const CFOO: Foo = Foo { + alpha: not_sm_to, + beta: to_not_sm, + gamma: sm_to, + delta: to_sm, + }; + + let input = Foo { alpha: not_sm_to, beta: to_not_sm, gamma: sm_to, delta: to_sm }; + match input { + CFOO => count += 1, + Foo { .. } => {} + }; + + // Final count must be 10 now if all + assert_eq!(count, 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs new file mode 100644 index 000000000000..df72b52b236b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.rs @@ -0,0 +1,20 @@ +// Issue 61188 pointed out a case where we hit an ICE during code gen: +// the compiler assumed that `PartialEq` was always implemented on any +// use of a `const` item in a pattern context, but the pre-existing +// structural-match checking was too shallow +// (see rust-lang/rust#62307), and so we hit cases where we were +// trying to dispatch to `PartialEq` on types that did not implement +// that trait. + +struct B(i32); + +const A: &[B] = &[]; + +pub fn main() { + match &[][..] { + A => (), +// { dg-error "" "" { target *-*-* } .-1 } + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs new file mode 100644 index 000000000000..461901bb6c8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs @@ -0,0 +1,44 @@ +// RFC 1445 introduced `#[structural_match]`; this attribute must +// appear on the `struct`/`enum` definition for any `const` used in a +// pattern. +// +// This is our (forever-unstable) way to mark a datatype as having a +// `PartialEq` implementation that is equivalent to recursion over its +// substructure. This avoids (at least in the short term) any need to +// resolve the question of what semantics is used for such matching. +// (See RFC 1445 for more details and discussion.) + +// Issue 62307 pointed out a case where the structural-match checking +// was too shallow. +#![warn(indirect_structural_match, nontrivial_structural_match)] +// run-pass + +#[derive(Debug)] +struct B(i32); + +// Overriding `PartialEq` to use this strange notion of "equality" exposes +// whether `match` is using structural-equality or method-dispatch +// under the hood, which is the antithesis of rust-lang/rfcs#1445 +impl PartialEq for B { + fn eq(&self, other: &B) -> bool { std::cmp::min(self.0, other.0) == 0 } +} + +fn main() { + const RR_B0: & & B = & & B(0); + const RR_B1: & & B = & & B(1); + + match RR_B0 { + RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + _ => { } + } + + match RR_B1 { + RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + _ => { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs new file mode 100644 index 000000000000..2aa7ac59de24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.rs @@ -0,0 +1,41 @@ +// run-pass + +// The actual regression test from #63479. (Including this because my +// first draft at fn-ptr-is-structurally-matchable.rs failed to actually +// cover the case this hit; I've since expanded it accordingly, but the +// experience left me wary of leaving this regression test out.) + +#![warn(pointer_structural_match)] + +#[derive(Eq)] +struct A { + a: i64 +} + +impl PartialEq for A { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.a.eq(&other.a) + } +} + +type Fn = fn(&[A]); + +fn my_fn(_args: &[A]) { + println!("hello world"); +} + +const TEST: Fn = my_fn; + +struct B(Fn); + +fn main() { + let s = B(my_fn); + match s { + B(TEST) => println!("matched"), +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + _ => panic!("didn't match") + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-empty-array-allowed-without-eq-issue-62336.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-empty-array-allowed-without-eq-issue-62336.rs new file mode 100644 index 000000000000..c68d69638521 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-empty-array-allowed-without-eq-issue-62336.rs @@ -0,0 +1,18 @@ +// Pre-existing behavior has been to reject patterns with consts +// denoting non-empty arrays of non-`Eq` types, but *accept* empty +// arrays of such types. +// +// See rust-lang/rust#62336. + +// run-pass + +#[derive(PartialEq, Debug)] +struct B(i32); + +fn main() { + const FOO: [B; 0] = []; + match [] { + FOO => { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.rs new file mode 100644 index 000000000000..05ebb44f9cc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.rs @@ -0,0 +1,28 @@ +use std::f32; + +#[derive(PartialEq)] +struct Foo { + x: u32 +} + +const FOO: Foo = Foo { x: 0 }; + +fn main() { + let y = Foo { x: 1 }; + match y { + FOO => { } +// { dg-error "" "" { target *-*-* } .-1 } + _ => { } + } + + let x = 0.0; + match x { + f32::INFINITY => { } +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + _ => { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.rs new file mode 100644 index 000000000000..d271e32aabb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.rs @@ -0,0 +1,20 @@ +// Issue 62307 pointed out a case where the structural-match checking +// was too shallow. +// +// Here we check similar behavior for non-empty arrays of types that +// do not derive `Eq`. +// +// (Current behavior for empty arrays differs and thus is not tested +// here; see rust-lang/rust#62336.) + +#[derive(PartialEq, Debug)] +struct B(i32); + +fn main() { + const FOO: [B; 1] = [B(0)]; + match [B(1)] { + FOO => { } +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs new file mode 100644 index 000000000000..0bc9b34283b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.rs @@ -0,0 +1,22 @@ +#[derive(Eq)] +struct Foo { + x: u32 +} + +impl PartialEq for Foo { + fn eq(&self, _: &Foo) -> bool { + false // ha ha sucker! + } +} + +const FOO: Foo = Foo { x: 0 }; + +fn main() { + let y = Foo { x: 1 }; + match y { + FOO => { } +// { dg-error "" "" { target *-*-* } .-1 } + _ => { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/phantom-data-is-structurally-matchable.rs b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/phantom-data-is-structurally-matchable.rs new file mode 100644 index 000000000000..02626aa1caca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1445-restrict-constants-in-patterns/phantom-data-is-structurally-matchable.rs @@ -0,0 +1,54 @@ +// run-pass + +// This file checks that `PhantomData` is considered structurally matchable. + +use std::marker::PhantomData; + +fn main() { + let mut count = 0; + + // A type which is not structurally matchable: + struct NotSM; + + // And one that is: + #[derive(PartialEq, Eq)] + struct SM; + + // Check that SM is structural-match: + const CSM: SM = SM; + match SM { + CSM => count += 1, + }; + + // Check that PhantomData is structural-match even if T is not. + const CPD1: PhantomData = PhantomData; + match PhantomData { + CPD1 => count += 1, + }; + + // Check that PhantomData is structural-match when T is. + const CPD2: PhantomData = PhantomData; + match PhantomData { + CPD2 => count += 1, + }; + + // Check that a type which has a PhantomData is structural-match. + #[derive(PartialEq, Eq, Default)] + struct Foo { + alpha: PhantomData, + beta: PhantomData, + } + + const CFOO: Foo = Foo { + alpha: PhantomData, + beta: PhantomData, + }; + + match Foo::default() { + CFOO => count += 1, + }; + + // Final count must be 4 now if all + assert_eq!(count, 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1717-dllimport/missing-link-attr.rs b/gcc/testsuite/rust/rustc/ui/rfc-1717-dllimport/missing-link-attr.rs new file mode 100644 index 000000000000..296c2cb656d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1717-dllimport/missing-link-attr.rs @@ -0,0 +1,5 @@ +// compile-flags: -l foo:bar +// error-pattern: renaming of the library `foo` was specified + +#![crate_type = "lib"] + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1717-dllimport/multiple-renames.rs b/gcc/testsuite/rust/rustc/ui/rfc-1717-dllimport/multiple-renames.rs new file mode 100644 index 000000000000..6ebf4d7b207d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1717-dllimport/multiple-renames.rs @@ -0,0 +1,8 @@ +// compile-flags: -l foo:bar -l foo:baz +// error-pattern: multiple renamings were specified for library + +#![crate_type = "lib"] + +#[link(name = "foo")] +extern "C" {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1717-dllimport/rename-to-empty.rs b/gcc/testsuite/rust/rustc/ui/rfc-1717-dllimport/rename-to-empty.rs new file mode 100644 index 000000000000..f5f8139100b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1717-dllimport/rename-to-empty.rs @@ -0,0 +1,8 @@ +// compile-flags: -l foo: +// error-pattern: an empty renaming target was specified for library + +#![crate_type = "lib"] + +#[link(name = "foo")] +extern "C" {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs new file mode 100644 index 000000000000..083a25351259 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs @@ -0,0 +1,12 @@ +// run-fail +// error-pattern:returned Box from main() +// failure-status: 1 +// ignore-emscripten no processes + +use std::error::Error; +use std::io; + +fn main() -> Result<(), Box> { + Err(Box::new(io::Error::new(io::ErrorKind::Other, "returned Box from main()"))) +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-never.rs b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-never.rs new file mode 100644 index 000000000000..a3319112d588 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-never.rs @@ -0,0 +1,8 @@ +// run-fail +// error-pattern:oh, dear +// ignore-emscripten no processes + +fn main() -> ! { + panic!("oh, dear"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs new file mode 100644 index 000000000000..c7f5391f3324 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:returned Box from main() +// failure-status: 1 +// ignore-emscripten no processes + +use std::io::{Error, ErrorKind}; + +fn main() -> Result<(), Box> { + Err(Box::new(Error::new(ErrorKind::Other, "returned Box from main()"))) +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-str.rs b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-str.rs new file mode 100644 index 000000000000..270396c4e3d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-for-str.rs @@ -0,0 +1,9 @@ +// run-fail +// error-pattern: An error message for you +// failure-status: 1 +// ignore-emscripten no processes + +fn main() -> Result<(), &'static str> { + Err("An error message for you") +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-impl-trait.rs new file mode 100644 index 000000000000..5a8d89738269 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-impl-trait.rs @@ -0,0 +1,4 @@ +// Tests that an `impl Trait` that is not `impl Termination` will not work. +fn main() -> impl Copy { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs new file mode 100644 index 000000000000..919fea2bbcb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs @@ -0,0 +1,16 @@ +// compile-flags: --test + +#![feature(test)] + +extern crate test; +use std::num::ParseIntError; +use test::Bencher; + +#[test] +#[should_panic] +fn not_a_num() -> Result<(), ParseIntError> { +// { dg-error "" "" { target *-*-* } .-1 } + let _: u32 = "abc".parse()?; + Ok(()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-in-test.rs b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-in-test.rs new file mode 100644 index 000000000000..6aca2b8d80a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-in-test.rs @@ -0,0 +1,29 @@ +// compile-flags: --test +// run-pass + +// ignore-wasm32-bare compiled with panic=abort by default + +#![feature(test)] + +extern crate test; +use std::num::ParseIntError; +use test::Bencher; + +#[test] +fn is_a_num() -> Result<(), ParseIntError> { + let _: u32 = "22".parse()?; + Ok(()) +} + +#[bench] +fn test_a_positive_bench(_: &mut Bencher) -> Result<(), ParseIntError> { + Ok(()) +} + +#[bench] +#[should_panic] +fn test_a_neg_bench(_: &mut Bencher) -> Result<(), ParseIntError> { + let _: u32 = "abc".parse()?; + Ok(()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-main-i32.rs b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-main-i32.rs new file mode 100644 index 000000000000..0761d19b068c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -0,0 +1,7 @@ +fn main() -> i32 { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-note ".E0277." "" { target *-*-* } .-2 } +// { help ".E0277." "" { target *-*-* } .-3 } + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs new file mode 100644 index 000000000000..ad8639998c32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs @@ -0,0 +1,4 @@ +fn main() -> char { // { dg-error ".E0277." "" { target *-*-* } } + ' ' +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-not-satisfied.rs b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-not-satisfied.rs new file mode 100644 index 000000000000..f26a4408286a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-not-satisfied.rs @@ -0,0 +1,6 @@ +struct ReturnType {} + +fn main() -> ReturnType { // { dg-error ".E0277." "" { target *-*-* } } + ReturnType {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs new file mode 100644 index 000000000000..6a808d8e381e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs @@ -0,0 +1,9 @@ +// compile-flags: --test + +use std::num::ParseFloatError; + +#[test] +fn can_parse_zero_as_f32() -> Result { // { dg-error ".E0277." "" { target *-*-* } } + "0".parse() +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.rs b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.rs new file mode 100644 index 000000000000..fa67b1d4b3f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.rs @@ -0,0 +1,25 @@ +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct Foo { +} + +impl Foo { + fn get(&self) -> Option<&Result> { + None + } + + fn mutate(&mut self) { } +} + +fn main() { + let mut foo = Foo { }; + + // foo.get() returns type Option<&Result>, so + // using `string` keeps borrow of `foo` alive. Hence calling + // `foo.mutate()` should be an error. + while let Some(Ok(string)) = foo.get() { + foo.mutate(); +// { dg-error ".E0502." "" { target *-*-* } .-1 } + println!("foo={:?}", *string); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/const.rs b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/const.rs new file mode 100644 index 000000000000..91d007c641f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/const.rs @@ -0,0 +1,18 @@ +// FIXME(tschottdorf): this test should pass. + +#[derive(PartialEq, Eq)] +struct Foo { + bar: i32, +} + +const FOO: Foo = Foo{bar: 5}; + +fn main() { + let f = Foo{bar:6}; + + match &f { + FOO => {}, // { dg-error ".E0308." "" { target *-*-* } } + _ => panic!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/enum.rs b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/enum.rs new file mode 100644 index 000000000000..35801e89f146 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/enum.rs @@ -0,0 +1,23 @@ +enum Wrapper { + Wrap(i32), +} + +use Wrapper::Wrap; + +pub fn main() { + let Wrap(x) = &Wrap(3); + *x += 1; // { dg-error ".E0594." "" { target *-*-* } } + + + if let Some(x) = &Some(3) { + *x += 1; // { dg-error ".E0594." "" { target *-*-* } } + } else { + panic!(); + } + + while let Some(x) = &Some(3) { + *x += 1; // { dg-error ".E0594." "" { target *-*-* } } + break; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/explicit-mut.rs b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/explicit-mut.rs new file mode 100644 index 000000000000..736b62fe87be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/explicit-mut.rs @@ -0,0 +1,29 @@ +// Verify the binding mode shifts - only when no `&` are auto-dereferenced is the +// final default binding mode mutable. + +fn main() { + match &&Some(5i32) { + Some(n) => { + *n += 1; // { dg-error ".E0594." "" { target *-*-* } } + let _ = n; + } + None => {}, + }; + + match &mut &Some(5i32) { + Some(n) => { + *n += 1; // { dg-error ".E0594." "" { target *-*-* } } + let _ = n; + } + None => {}, + }; + + match &&mut Some(5i32) { + Some(n) => { + *n += 1; // { dg-error ".E0594." "" { target *-*-* } } + let _ = n; + } + None => {}, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/for.rs b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/for.rs new file mode 100644 index 000000000000..2b00a758ad04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/for.rs @@ -0,0 +1,10 @@ +struct Foo {} + +pub fn main() { + let mut tups = vec![(Foo {}, Foo {})]; + // The below desugars to &(ref n, mut m). + for (n, mut m) in &tups { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/issue-44912-or.rs b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/issue-44912-or.rs new file mode 100644 index 000000000000..9d94c64acc51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/issue-44912-or.rs @@ -0,0 +1,11 @@ +// FIXME(tschottdorf): This should compile. See #44912. + +pub fn main() { + let x = &Some((3, 3)); + let _: &i32 = match x { + Some((x, 3)) | &Some((ref x, 5)) => x, +// { dg-error ".E0409." "" { target *-*-* } .-1 } + _ => &5i32, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/lit.rs b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/lit.rs new file mode 100644 index 000000000000..294a2fc03e30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/lit.rs @@ -0,0 +1,25 @@ +// FIXME(tschottdorf): we want these to compile, but they don't. + +fn with_str() { + let s: &'static str = "abc"; + + match &s { + "abc" => true, // { dg-error ".E0308." "" { target *-*-* } } + _ => panic!(), + }; +} + +fn with_bytes() { + let s: &'static [u8] = b"abc"; + + match &s { + b"abc" => true, // { dg-error ".E0308." "" { target *-*-* } } + _ => panic!(), + }; +} + +pub fn main() { + with_str(); + with_bytes(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/no-double-error.rs b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/no-double-error.rs new file mode 100644 index 000000000000..e793f2387315 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/no-double-error.rs @@ -0,0 +1,12 @@ +// Without caching type lookups in FnCtxt.resolve_ty_and_def_ufcs +// the error below would be reported twice (once when checking +// for a non-ref pattern, once when processing the pattern). + +fn main() { + let foo = 22; + match foo { + u32::XXX => { } // { dg-error ".E0599." "" { target *-*-* } } + _ => { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/slice.rs b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/slice.rs new file mode 100644 index 000000000000..5f7fac9068d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2005-default-binding-mode/slice.rs @@ -0,0 +1,8 @@ +pub fn main() { + let sl: &[u8] = b"foo"; + + match sl { // { dg-error ".E0004." "" { target *-*-* } } + [first, remainder @ ..] => {}, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/enums.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/enums.rs new file mode 100644 index 000000000000..44eba402d98c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/enums.rs @@ -0,0 +1,12 @@ +#![crate_type = "rlib"] + +#[non_exhaustive] +pub enum NonExhaustiveEnum { + Unit, + Tuple(u32), + Struct { field: u32 } +} + +#[non_exhaustive] +pub enum EmptyNonExhaustiveEnum {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs new file mode 100644 index 000000000000..ee2b147b97d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs @@ -0,0 +1,9 @@ +#[non_exhaustive] +pub enum NonExhaustiveMonovariant { + Variant(u32), +} + +pub enum ExhaustiveMonovariant { + Variant(u32), +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/structs.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/structs.rs new file mode 100644 index 000000000000..9c7d08bf5547 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/structs.rs @@ -0,0 +1,26 @@ +#[non_exhaustive] +pub struct NormalStruct { + pub first_field: u16, + pub second_field: u16, +} + +#[non_exhaustive] +pub struct UnitStruct; + +#[non_exhaustive] +pub struct TupleStruct(pub u16, pub u16); + +#[derive(Debug)] +#[non_exhaustive] +pub struct FunctionalRecord { + pub first_field: u16, + pub second_field: u16, + pub third_field: bool +} + +impl Default for FunctionalRecord { + fn default() -> FunctionalRecord { + FunctionalRecord { first_field: 640, second_field: 480, third_field: false } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/variants.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/variants.rs new file mode 100644 index 000000000000..6b8e472d0313 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/auxiliary/variants.rs @@ -0,0 +1,8 @@ +#![crate_type = "rlib"] + +pub enum NonExhaustiveVariants { + #[non_exhaustive] Unit, + #[non_exhaustive] Tuple(u32), + #[non_exhaustive] Struct { field: u32 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs new file mode 100644 index 000000000000..ad5e64f7ccf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs @@ -0,0 +1,43 @@ +// Test that the borrow checker doesn't consider checking an exhaustive pattern +// as an access. + +// check-pass + +// aux-build:monovariants.rs +extern crate monovariants; + +use monovariants::ExhaustiveMonovariant; + +enum Local { + Variant(u32), +} + +#[non_exhaustive] +enum LocalNonExhaustive { + Variant(u32), +} + +fn main() { + let mut x = ExhaustiveMonovariant::Variant(1); + let y = &mut x; + match x { + ExhaustiveMonovariant::Variant(_) => {}, + _ => {}, + } + drop(y); + let mut x = Local::Variant(1); + let y = &mut x; + match x { + Local::Variant(_) => {}, + _ => {}, + } + drop(y); + let mut x = LocalNonExhaustive::Variant(1); + let y = &mut x; + match x { + LocalNonExhaustive::Variant(_) => {}, + _ => {}, + } + drop(y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs new file mode 100644 index 000000000000..043809ed07ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs @@ -0,0 +1,19 @@ +// Test that the borrow checker considers `#[non_exhaustive]` when checking +// whether a match contains a discriminant read. + +// aux-build:monovariants.rs +extern crate monovariants; + +use monovariants::NonExhaustiveMonovariant; + +fn main() { + let mut x = NonExhaustiveMonovariant::Variant(1); + let y = &mut x; + match x { + NonExhaustiveMonovariant::Variant(_) => {}, +// { dg-error ".E0503." "" { target *-*-* } .-1 } + _ => {}, + } + drop(y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/enum.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/enum.rs new file mode 100644 index 000000000000..a1bffcd56765 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/enum.rs @@ -0,0 +1,70 @@ +// aux-build:enums.rs +extern crate enums; + +use enums::{EmptyNonExhaustiveEnum, NonExhaustiveEnum}; + +fn empty(x: EmptyNonExhaustiveEnum) { + match x {} // { dg-error ".E0004." "" { target *-*-* } } + match x { + _ => {}, // ok + } +} + +fn main() { + let enum_unit = NonExhaustiveEnum::Unit; + + match enum_unit { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + NonExhaustiveEnum::Unit => "first", + NonExhaustiveEnum::Tuple(_) => "second", + NonExhaustiveEnum::Struct { .. } => "third" + }; + + match enum_unit {}; +// { dg-error ".E0004." "" { target *-*-* } .-1 } + + // Everything below this is expected to compile successfully. + + let enum_unit = NonExhaustiveEnum::Unit; + + match enum_unit { + NonExhaustiveEnum::Unit => 1, + NonExhaustiveEnum::Tuple(_) => 2, + // This particular arm tests that a enum marked as non-exhaustive + // will not error if its variants are matched exhaustively. + NonExhaustiveEnum::Struct { field } => field, + _ => 0 // no error with wildcard + }; + + match enum_unit { + _ => "no error with only wildcard" + }; + + // #53549: Check that variant constructors can still be called normally. + match NonExhaustiveEnum::Unit { + NonExhaustiveEnum::Unit => {}, + _ => {} + }; + + match NonExhaustiveEnum::Tuple(2) { + NonExhaustiveEnum::Tuple(2) => {}, + _ => {} + }; + + match (NonExhaustiveEnum::Unit {}) { + NonExhaustiveEnum::Unit {} => {}, + _ => {} + }; + + match (NonExhaustiveEnum::Tuple { 0: 2 }) { + NonExhaustiveEnum::Tuple { 0: 2 } => {}, + _ => {} + }; + + match (NonExhaustiveEnum::Struct { field: 2 }) { + NonExhaustiveEnum::Struct { field: 2 } => {}, + _ => {} + }; + +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/enum_same_crate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/enum_same_crate.rs new file mode 100644 index 000000000000..1ead6664f7b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/enum_same_crate.rs @@ -0,0 +1,19 @@ +// run-pass + +#[non_exhaustive] +pub enum NonExhaustiveEnum { + Unit, + Tuple(u32), + Struct { field: u32 } +} + +fn main() { + let enum_unit = NonExhaustiveEnum::Unit; + + match enum_unit { + NonExhaustiveEnum::Unit => "first", + NonExhaustiveEnum::Tuple(_) => "second", + NonExhaustiveEnum::Struct { .. } => "third", + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs new file mode 100644 index 000000000000..37f71acd0a4f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs @@ -0,0 +1,38 @@ +#![deny(unreachable_patterns)] + +#[non_exhaustive] +pub enum NonExhaustiveEnum { + Unit, +// { dg-error "" "" { target *-*-* } .-1 } + Tuple(u32), +// { dg-error "" "" { target *-*-* } .-1 } + Struct { field: u32 } +// { dg-error "" "" { target *-*-* } .-1 } +} + +pub enum NormalEnum { + Unit, +// { dg-error "" "" { target *-*-* } .-1 } + Tuple(u32), +// { dg-error "" "" { target *-*-* } .-1 } + Struct { field: u32 } +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[non_exhaustive] +pub enum EmptyNonExhaustiveEnum {} + +fn empty_non_exhaustive(x: EmptyNonExhaustiveEnum) { + match x {} + match x { + _ => {} // not detected as unreachable + } +} + +fn main() { + match NonExhaustiveEnum::Unit {} +// { dg-error ".E0004." "" { target *-*-* } .-1 } + match NormalEnum::Unit {} +// { dg-error ".E0004." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/auxiliary/types.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/auxiliary/types.rs new file mode 100644 index 000000000000..095f582a3713 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/auxiliary/types.rs @@ -0,0 +1,30 @@ +#[non_exhaustive] +#[repr(C)] +pub enum NonExhaustiveEnum { + Unit, + Tuple(u32), + Struct { field: u32 } +} + +#[non_exhaustive] +#[repr(C)] +pub struct NormalStruct { + pub first_field: u16, + pub second_field: u16, +} + +#[non_exhaustive] +#[repr(C)] +pub struct UnitStruct; + +#[non_exhaustive] +#[repr(C)] +pub struct TupleStruct (pub u16, pub u16); + +#[repr(C)] +pub enum NonExhaustiveVariants { + #[non_exhaustive] Unit, + #[non_exhaustive] Tuple(u32), + #[non_exhaustive] Struct { field: u32 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.rs new file mode 100644 index 000000000000..c9525224e0ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.rs @@ -0,0 +1,25 @@ +// aux-build:types.rs +#![deny(improper_ctypes)] + +extern crate types; + +// This test checks that non-exhaustive types with `#[repr(C)]` from an extern crate are considered +// improper. + +use types::{NonExhaustiveEnum, NormalStruct, UnitStruct, TupleStruct, NonExhaustiveVariants}; + +extern { + pub fn non_exhaustive_enum(_: NonExhaustiveEnum); +// { dg-error "" "" { target *-*-* } .-1 } + pub fn non_exhaustive_normal_struct(_: NormalStruct); +// { dg-error "" "" { target *-*-* } .-1 } + pub fn non_exhaustive_unit_struct(_: UnitStruct); +// { dg-error "" "" { target *-*-* } .-1 } + pub fn non_exhaustive_tuple_struct(_: TupleStruct); +// { dg-error "" "" { target *-*-* } .-1 } + pub fn non_exhaustive_variant(_: NonExhaustiveVariants); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/same_crate_proper.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/same_crate_proper.rs new file mode 100644 index 000000000000..2e7203bef191 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/improper_ctypes/same_crate_proper.rs @@ -0,0 +1,46 @@ +// check-pass +#![deny(improper_ctypes)] + +// This test checks that non-exhaustive types with `#[repr(C)]` are considered proper within +// the defining crate. + +#[non_exhaustive] +#[repr(C)] +pub enum NonExhaustiveEnum { + Unit, + Tuple(u32), + Struct { field: u32 } +} + +#[non_exhaustive] +#[repr(C)] +pub struct NormalStruct { + pub first_field: u16, + pub second_field: u16, +} + +#[non_exhaustive] +#[repr(C)] +pub struct UnitStruct; + +#[non_exhaustive] +#[repr(C)] +pub struct TupleStruct (pub u16, pub u16); + +#[repr(C)] +pub enum NonExhaustiveVariants { + #[non_exhaustive] Unit, + #[non_exhaustive] Tuple(u32), + #[non_exhaustive] Struct { field: u32 } +} + +extern { + // Unit structs aren't tested here because they will trigger `improper_ctypes` anyway. + pub fn non_exhaustive_enum(_: NonExhaustiveEnum); + pub fn non_exhaustive_normal_struct(_: NormalStruct); + pub fn non_exhaustive_tuple_struct(_: TupleStruct); + pub fn non_exhaustive_variant(_: NonExhaustiveVariants); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/invalid-attribute.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/invalid-attribute.rs new file mode 100644 index 000000000000..17de2ab0abf9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/invalid-attribute.rs @@ -0,0 +1,17 @@ +#[non_exhaustive(anything)] +// { dg-error "" "" { target *-*-* } .-1 } +struct Foo; + +#[non_exhaustive] +// { dg-error ".E0701." "" { target *-*-* } .-1 } +trait Bar { } + +#[non_exhaustive] +// { dg-error ".E0701." "" { target *-*-* } .-1 } +union Baz { + f1: u16, + f2: u16 +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/struct.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/struct.rs new file mode 100644 index 000000000000..1a660bc5a2e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/struct.rs @@ -0,0 +1,50 @@ +// aux-build:structs.rs +extern crate structs; + +use structs::{NormalStruct, UnitStruct, TupleStruct, FunctionalRecord}; + +fn main() { + let fr = FunctionalRecord { +// { dg-error ".E0639." "" { target *-*-* } .-1 } + first_field: 1920, + second_field: 1080, + ..FunctionalRecord::default() + }; + + let ns = NormalStruct { first_field: 640, second_field: 480 }; +// { dg-error ".E0639." "" { target *-*-* } .-1 } + + let NormalStruct { first_field, second_field } = ns; +// { dg-error ".E0638." "" { target *-*-* } .-1 } + + let ts = TupleStruct(640, 480); +// { dg-error ".E0423." "" { target *-*-* } .-1 } + + let ts_explicit = structs::TupleStruct(640, 480); +// { dg-error ".E0603." "" { target *-*-* } .-1 } + + let TupleStruct { 0: first_field, 1: second_field } = ts; +// { dg-error ".E0638." "" { target *-*-* } .-1 } + + let us = UnitStruct; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + + let us_explicit = structs::UnitStruct; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + + let UnitStruct { } = us; +// { dg-error ".E0638." "" { target *-*-* } .-1 } +} + +// Everything below this is expected to compile successfully. + +// We only test matching here as we cannot create non-exhaustive +// structs from another crate. ie. they'll never pass in run-pass tests. +fn match_structs(ns: NormalStruct, ts: TupleStruct, us: UnitStruct) { + let NormalStruct { first_field, second_field, .. } = ns; + + let TupleStruct { 0: first, 1: second, .. } = ts; + + let UnitStruct { .. } = us; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/structs_same_crate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/structs_same_crate.rs new file mode 100644 index 000000000000..3f583288a763 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/structs_same_crate.rs @@ -0,0 +1,33 @@ +// run-pass + +#![allow(unused_variables)] + +#[non_exhaustive] +pub struct NormalStruct { + pub first_field: u16, + pub second_field: u16, +} + +#[non_exhaustive] +pub struct UnitStruct; + +#[non_exhaustive] +pub struct TupleStruct (pub u16, pub u16); + +fn main() { + let ns = NormalStruct { first_field: 640, second_field: 480 }; + + let NormalStruct { first_field, second_field } = ns; + + let ts = TupleStruct { 0: 340, 1: 480 }; + let ts_constructor = TupleStruct(340, 480); + + let TupleStruct { 0: first, 1: second } = ts; + let TupleStruct(first, second) = ts_constructor; + + let us = UnitStruct {}; + let us_constructor = UnitStruct; + + let UnitStruct { } = us; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs new file mode 100644 index 000000000000..95294460b4e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/auxiliary/uninhabited.rs @@ -0,0 +1,33 @@ +#![crate_type = "rlib"] +#![feature(never_type)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub enum PartiallyInhabitedVariants { + Tuple(u8), + #[non_exhaustive] Struct { x: ! } +} + +pub struct IndirectUninhabitedEnum(UninhabitedEnum); + +pub struct IndirectUninhabitedStruct(UninhabitedStruct); + +pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); + +pub struct IndirectUninhabitedVariants(UninhabitedVariants); + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs new file mode 100644 index 000000000000..a1d39baaf282 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/coercions.rs @@ -0,0 +1,39 @@ +// aux-build:uninhabited.rs +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, +}; + +// This test checks that uninhabited non-exhaustive types cannot coerce to any type, as the never +// type can. + +struct A; + +fn can_coerce_never_type_to_anything(x: !) -> A { + x +} + +fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs new file mode 100644 index 000000000000..e48ed7c6b568 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs @@ -0,0 +1,46 @@ +#![feature(never_type)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +struct A; + +// This test checks that uninhabited non-exhaustive types defined in the same crate cannot coerce +// to any type, as the never type can. + +fn can_coerce_never_type_to_anything(x: !) -> A { + x +} + +fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs new file mode 100644 index 000000000000..7f44a50f9b2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match.rs @@ -0,0 +1,37 @@ +// aux-build:uninhabited.rs +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + IndirectUninhabitedEnum, + IndirectUninhabitedStruct, + IndirectUninhabitedTupleStruct, + IndirectUninhabitedVariants, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type through a level of +// indirection from an extern crate will not compile. + +fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( + x: IndirectUninhabitedVariants, +) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs new file mode 100644 index 000000000000..deb3ba6e477d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs @@ -0,0 +1,52 @@ +#![feature(never_type)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub struct IndirectUninhabitedEnum(UninhabitedEnum); + +pub struct IndirectUninhabitedStruct(UninhabitedStruct); + +pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); + +pub struct IndirectUninhabitedVariants(UninhabitedVariants); + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type through a level of +// indirection from the defining crate will not compile without `#![feature(exhaustive_patterns)]`. + +fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( + x: IndirectUninhabitedVariants, +) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs new file mode 100644 index 000000000000..b80bdb1eb6b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns.rs @@ -0,0 +1,41 @@ +// aux-build:uninhabited.rs +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + IndirectUninhabitedEnum, + IndirectUninhabitedStruct, + IndirectUninhabitedTupleStruct, + IndirectUninhabitedVariants, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type through a level of +// indirection from an extern crate will not compile. In particular, this enables the +// `exhaustive_patterns` feature as this can change the branch used in the compiler to determine +// this. + +fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( + x: IndirectUninhabitedVariants, +) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs new file mode 100644 index 000000000000..4d57e5134daa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs @@ -0,0 +1,58 @@ +// check-pass + +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub struct IndirectUninhabitedEnum(UninhabitedEnum); + +pub struct IndirectUninhabitedStruct(UninhabitedStruct); + +pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct); + +pub struct IndirectUninhabitedVariants(UninhabitedVariants); + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate +// will compile. In particular, this enables the `exhaustive_patterns` feature as this can +// change the branch used in the compiler to determine this. +// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648. + +fn cannot_empty_match_on_empty_enum_to_anything(x: IndirectUninhabitedEnum) -> A { + match x {} +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: IndirectUninhabitedStruct) -> A { + match x {} +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: IndirectUninhabitedTupleStruct) -> A { + match x {} +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything( + x: IndirectUninhabitedVariants, +) -> A { + match x {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs new file mode 100644 index 000000000000..f8f724aa82ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/issue-65157-repeated-match-arm.rs @@ -0,0 +1,22 @@ +// aux-build:uninhabited.rs +#![deny(unreachable_patterns)] +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::PartiallyInhabitedVariants; + +// This test checks a redundant/useless pattern of a non-exhaustive enum/variant is still +// warned against. + +pub fn foo(x: PartiallyInhabitedVariants) { + match x { + PartiallyInhabitedVariants::Struct { .. } => {}, + PartiallyInhabitedVariants::Struct { .. } => {}, +// { dg-error "" "" { target *-*-* } .-1 } + _ => {}, + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match.rs new file mode 100644 index 000000000000..467b670b5c15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match.rs @@ -0,0 +1,35 @@ +// aux-build:uninhabited.rs +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate +// will not compile. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs new file mode 100644 index 000000000000..113648b4ab8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs @@ -0,0 +1,42 @@ +#![feature(never_type)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate +// will compile. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs new file mode 100644 index 000000000000..d3e67fb8c000 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.rs @@ -0,0 +1,38 @@ +// aux-build:uninhabited.rs +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] + +extern crate uninhabited; + +use uninhabited::{ + UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, +}; + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from an extern crate +// will not compile. In particular, this enables the `exhaustive_patterns` feature as this can +// change the branch used in the compiler to determine this. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { + match x {} // { dg-error ".E0004." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs new file mode 100644 index 000000000000..dc72774c32d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs @@ -0,0 +1,48 @@ +// check-pass + +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +struct A; + +// This test checks that an empty match on a non-exhaustive uninhabited type from the defining crate +// will compile. In particular, this enables the `exhaustive_patterns` feature as this can +// change the branch used in the compiler to determine this. +// Codegen is skipped because tests with long names can cause issues on Windows CI, see #60648. + +fn cannot_empty_match_on_empty_enum_to_anything(x: UninhabitedEnum) -> A { + match x {} +} + +fn cannot_empty_match_on_empty_struct_to_anything(x: UninhabitedStruct) -> A { + match x {} +} + +fn cannot_empty_match_on_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { + match x {} +} + +fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { + match x {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs new file mode 100644 index 000000000000..978685a6eaaf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/patterns.rs @@ -0,0 +1,60 @@ +// aux-build:uninhabited.rs +// build-pass (FIXME(62277): could be check-pass?) +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] + +extern crate uninhabited; + +use uninhabited::{ + PartiallyInhabitedVariants, + UninhabitedEnum, + UninhabitedStruct, + UninhabitedTupleStruct, + UninhabitedVariants, +}; + +fn uninhabited_enum() -> Option { + None +} + +fn uninhabited_variant() -> Option { + None +} + +fn partially_inhabited_variant() -> PartiallyInhabitedVariants { + PartiallyInhabitedVariants::Tuple(3) +} + +fn uninhabited_struct() -> Option { + None +} + +fn uninhabited_tuple_struct() -> Option { + None +} + +// This test checks that non-exhaustive types that would normally be considered uninhabited within +// the defining crate are not considered uninhabited from extern crates. + +fn main() { + match uninhabited_enum() { + Some(_x) => (), // This line would normally error. + None => (), + } + + match uninhabited_variant() { + Some(_x) => (), // This line would normally error. + None => (), + } + + // This line would normally error. + while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() { + } + + while let Some(_x) = uninhabited_struct() { // This line would normally error. + } + + while let Some(_x) = uninhabited_tuple_struct() { // This line would normally error. + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs new file mode 100644 index 000000000000..fa974f86df0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs @@ -0,0 +1,71 @@ +#![deny(unreachable_patterns)] +#![feature(exhaustive_patterns)] +#![feature(never_type)] + +#[non_exhaustive] +pub enum UninhabitedEnum { +} + +#[non_exhaustive] +pub struct UninhabitedTupleStruct(!); + +#[non_exhaustive] +pub struct UninhabitedStruct { + _priv: !, +} + +pub enum UninhabitedVariants { + #[non_exhaustive] Tuple(!), + #[non_exhaustive] Struct { x: ! } +} + +pub enum PartiallyInhabitedVariants { + Tuple(u8), + #[non_exhaustive] Struct { x: ! } +} + +fn uninhabited_enum() -> Option { + None +} + +fn uninhabited_variant() -> Option { + None +} + +fn partially_inhabited_variant() -> PartiallyInhabitedVariants { + PartiallyInhabitedVariants::Tuple(3) +} + +fn uninhabited_struct() -> Option { + None +} + +fn uninhabited_tuple_struct() -> Option { + None +} + +// This test checks that non-exhaustive types that would normally be considered uninhabited within +// the defining crate are still considered uninhabited. + +fn main() { + match uninhabited_enum() { + Some(_x) => (), // { dg-error "" "" { target *-*-* } } + None => (), + } + + match uninhabited_variant() { + Some(_x) => (), // { dg-error "" "" { target *-*-* } } + None => (), + } + + while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { +// { dg-error "" "" { target *-*-* } .-1 } + } + + while let Some(_x) = uninhabited_struct() { // { dg-error "" "" { target *-*-* } } + } + + while let Some(_x) = uninhabited_tuple_struct() { // { dg-error "" "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/variant.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/variant.rs new file mode 100644 index 000000000000..ef1434c9cfbf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/variant.rs @@ -0,0 +1,34 @@ +// aux-build:variants.rs + +extern crate variants; + +use variants::NonExhaustiveVariants; + +fn main() { + let variant_struct = NonExhaustiveVariants::Struct { field: 640 }; +// { dg-error ".E0639." "" { target *-*-* } .-1 } + + let variant_tuple = NonExhaustiveVariants::Tuple(640); +// { dg-error ".E0603." "" { target *-*-* } .-1 } + + let variant_unit = NonExhaustiveVariants::Unit; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + + match variant_struct { + NonExhaustiveVariants::Unit => "", +// { dg-error ".E0603." "" { target *-*-* } .-1 } + NonExhaustiveVariants::Tuple(fe_tpl) => "", +// { dg-error ".E0603." "" { target *-*-* } .-1 } + NonExhaustiveVariants::Struct { field } => "" +// { dg-error ".E0638." "" { target *-*-* } .-1 } + }; + + if let NonExhaustiveVariants::Tuple(fe_tpl) = variant_struct { +// { dg-error ".E0603." "" { target *-*-* } .-1 } + } + + if let NonExhaustiveVariants::Struct { field } = variant_struct { +// { dg-error ".E0638." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs new file mode 100644 index 000000000000..4c8d78434e6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/variants_fictive_visibility.rs @@ -0,0 +1,13 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:variants.rs + +extern crate variants; + +const S: u8 = 0; + +// OK, `Struct` in value namespace is crate-private, so it's filtered away +// and there's no conflict with the previously defined `const S`. +use variants::NonExhaustiveVariants::Struct as S; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/variants_same_crate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/variants_same_crate.rs new file mode 100644 index 000000000000..eb55e97b2820 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2008-non-exhaustive/variants_same_crate.rs @@ -0,0 +1,19 @@ +// run-pass + +pub enum NonExhaustiveVariants { + #[non_exhaustive] Unit, + #[non_exhaustive] Tuple(u32), + #[non_exhaustive] Struct { field: u32 } +} + +fn main() { + let variant_tuple = NonExhaustiveVariants::Tuple(340); + let _variant_struct = NonExhaustiveVariants::Struct { field: 340 }; + + match variant_tuple { + NonExhaustiveVariants::Unit => "", + NonExhaustiveVariants::Tuple(_fe_tpl) => "", + NonExhaustiveVariants::Struct { field: _ } => "" + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs b/gcc/testsuite/rust/rustc/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs new file mode 100644 index 000000000000..31865e8bea44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs @@ -0,0 +1,24 @@ +// Check that we if we get ahold of an object unsafe trait +// object with auto traits and lifetimes, we can downcast it +// +// check-pass + +#![feature(object_safe_for_dispatch)] + +trait Trait: Sized {} + +fn downcast_auto(t: &(dyn Trait + Send)) -> &dyn Trait { + t +} + +fn downcast_lifetime<'a, 'b, 't>(t: &'a (dyn Trait + 't)) + -> &'b (dyn Trait + 't) +where + 'a: 'b, + 't: 'a + 'b, +{ + t +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs b/gcc/testsuite/rust/rustc/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs new file mode 100644 index 000000000000..76349952ec73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs @@ -0,0 +1,67 @@ +// Check that we can manually implement an object-unsafe trait for its trait object. + +// run-pass + +#![feature(object_safe_for_dispatch)] + +trait Bad { + fn stat() -> char { + 'A' + } + fn virt(&self) -> char { + 'B' + } + fn indirect(&self) -> char { + Self::stat() + } +} + +trait Good { + fn good_virt(&self) -> char { + panic!() + } + fn good_indirect(&self) -> char { + panic!() + } +} + +impl<'a> Bad for dyn Bad + 'a { + fn stat() -> char { + 'C' + } + fn virt(&self) -> char { + 'D' + } +} + +struct Struct {} + +impl Bad for Struct {} + +impl Good for Struct {} + +fn main() { + let s = Struct {}; + + let mut res = String::new(); + + // Directly call static. + res.push(Struct::stat()); // "A" + res.push(::stat()); // "AC" + + let good: &dyn Good = &s; + + // These look similar enough... + let bad = unsafe { std::mem::transmute::<&dyn Good, &dyn Bad>(good) }; + + // Call virtual. + res.push(s.virt()); // "ACB" + res.push(bad.virt()); // "ACBD" + + // Indirectly call static. + res.push(s.indirect()); // "ACBDA" + res.push(bad.indirect()); // "ACBDAC" + + assert_eq!(&res, "ACBDAC"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs b/gcc/testsuite/rust/rustc/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs new file mode 100644 index 000000000000..a4634514a5fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs @@ -0,0 +1,38 @@ +// Check that we can statically dispatch methods for object +// unsafe trait objects, directly and indirectly +// +// check-pass + +#![feature(object_safe_for_dispatch)] + +trait Statics { + fn plain() {} + fn generic() {} +} + +trait Trait: Sized {} + +impl<'a> Statics for dyn Trait + 'a {} + +fn static_poly() { + T::plain(); + T::generic::(); +} + +fn inferred_poly(t: &T) { + static_poly::(); + T::plain(); + T::generic::(); +} + +fn call(t: &dyn Trait) { + static_poly::(); + inferred_poly(t); +} + +fn main() { + static_poly::(); + ::plain(); + ::generic::() +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/call-chain.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/call-chain.rs new file mode 100644 index 000000000000..2f0ea43899ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/call-chain.rs @@ -0,0 +1,27 @@ +// run-pass + +use std::panic::Location; + +struct Foo; + +impl Foo { + #[track_caller] + fn check_loc(&self, line: u32, col: u32) -> &Self { + let loc = Location::caller(); + assert_eq!(loc.file(), file!(), "file mismatch"); + assert_eq!(loc.line(), line, "line mismatch"); + assert_eq!(loc.column(), col, "column mismatch"); + self + } +} + +fn main() { + // Tests that when `Location::caller` is used in a method chain, + // it points to the start of the correct call (the first character after the dot) + // instead of to the very first expression in the chain + let foo = Foo; + foo. + check_loc(line!(), 9).check_loc(line!(), 31) + .check_loc(line!(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs new file mode 100644 index 000000000000..60ad51fbf545 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/caller-location-fnptr-rt-ctfe-equiv.rs @@ -0,0 +1,33 @@ +// Ensure that a `#[track_caller]` function, returning `caller_location()`, +// which coerced (to a function pointer) and called, inside a `const fn`, +// in turn called, results in the same output irrespective of whether +// we're in a const or runtime context. + +// run-pass +// compile-flags: -Z unleash-the-miri-inside-of-you + +#![feature(core_intrinsics, const_caller_location, const_fn)] + +type L = &'static std::panic::Location<'static>; + +#[track_caller] +const fn attributed() -> L { + std::intrinsics::caller_location() +} + +const fn calling_attributed() -> L { + // We need `-Z unleash-the-miri-inside-of-you` for this as we don't have `const fn` pointers. + let ptr: fn() -> L = attributed; + ptr() +} + +fn main() { + const CONSTANT: L = calling_attributed(); + let runtime = calling_attributed(); + + assert_eq!( + (runtime.file(), runtime.line(), runtime.column()), + (CONSTANT.file(), CONSTANT.line(), CONSTANT.column()), + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/caller-location-intrinsic.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/caller-location-intrinsic.rs new file mode 100644 index 000000000000..dadc51b467b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/caller-location-intrinsic.rs @@ -0,0 +1,28 @@ +// run-pass +// revisions: default mir-opt +//[mir-opt] compile-flags: -Zmir-opt-level=3 + +#[inline(never)] +#[track_caller] +fn codegen_caller_loc() -> &'static core::panic::Location<'static> { + core::panic::Location::caller() +} + +macro_rules! caller_location_from_macro { + () => (codegen_caller_loc()); +} + +fn main() { + let loc = codegen_caller_loc(); + assert_eq!(loc.file(), file!()); + assert_eq!(loc.line(), 16); + assert_eq!(loc.column(), 15); + + // `Location::caller()` in a macro should behave similarly to `file!` and `line!`, + // i.e. point to where the macro was invoked, instead of the macro itself. + let loc2 = caller_location_from_macro!(); + assert_eq!(loc2.file(), file!()); + assert_eq!(loc2.line(), 23); + assert_eq!(loc2.column(), 16); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/const-caller-location.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/const-caller-location.rs new file mode 100644 index 000000000000..738eb553cc2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/const-caller-location.rs @@ -0,0 +1,44 @@ +// run-pass +// revisions: default mir-opt +//[mir-opt] compile-flags: -Zmir-opt-level=3 + +#![feature(const_caller_location, const_fn)] + +use std::panic::Location; + +const LOCATION: &Location = Location::caller(); + +const TRACKED: &Location = tracked(); +#[track_caller] +const fn tracked() -> &'static Location <'static> { + Location::caller() +} + +const NESTED: &Location = nested_location(); +const fn nested_location() -> &'static Location<'static> { + Location::caller() +} + +const CONTAINED: &Location = contained(); +const fn contained() -> &'static Location<'static> { + tracked() +} + +fn main() { + assert_eq!(LOCATION.file(), file!()); + assert_eq!(LOCATION.line(), 9); + assert_eq!(LOCATION.column(), 29); + + assert_eq!(TRACKED.file(), file!()); + assert_eq!(TRACKED.line(), 11); + assert_eq!(TRACKED.column(), 28); + + assert_eq!(NESTED.file(), file!()); + assert_eq!(NESTED.line(), 19); + assert_eq!(NESTED.column(), 5); + + assert_eq!(CONTAINED.file(), file!()); + assert_eq!(CONTAINED.line(), 24); + assert_eq!(CONTAINED.column(), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/diverging-caller-location.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/diverging-caller-location.rs new file mode 100644 index 000000000000..386d27c0b504 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/diverging-caller-location.rs @@ -0,0 +1,18 @@ +// run-fail + +//! This test ensures that `#[track_caller]` can be applied directly to diverging functions, as +//! the tracking issue says: https://github.com/rust-lang/rust/issues/47809#issue-292138490. +//! Because the annotated function must diverge and a panic keeps that faster than an infinite loop, +//! we don't inspect the location returned -- it would be difficult to distinguish between the +//! explicit panic and a failed assertion. That it compiles and runs is enough for this one. + +#[track_caller] +fn doesnt_return() -> ! { + let _location = core::panic::Location::caller(); + panic!("huzzah"); +} + +fn main() { + doesnt_return(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-odd-syntax.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-odd-syntax.rs new file mode 100644 index 000000000000..54f0e51a5046 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-odd-syntax.rs @@ -0,0 +1,6 @@ +#[track_caller(1)] +fn f() {} +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-invalid-abi.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-invalid-abi.rs new file mode 100644 index 000000000000..3d4841298f2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-invalid-abi.rs @@ -0,0 +1,12 @@ +#[track_caller] +extern "C" fn f() {} +// { dg-error ".E0737." "" { target *-*-* } .-2 } + +extern "C" { + #[track_caller] + fn g(); +// { dg-error ".E0737." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-main.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-main.rs new file mode 100644 index 000000000000..8c31ae787eab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-main.rs @@ -0,0 +1,5 @@ +#[track_caller] // { dg-error "" "" { target *-*-* } } +fn main() { + panic!("{}: oh no", std::panic::Location::caller()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-naked.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-naked.rs new file mode 100644 index 000000000000..3ad380592538 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-naked.rs @@ -0,0 +1,22 @@ +#![feature(naked_functions)] + +#[track_caller] // { dg-error ".E0736." "" { target *-*-* } } +#[naked] +fn f() {} + +struct S; + +impl S { + #[track_caller] // { dg-error ".E0736." "" { target *-*-* } } + #[naked] + fn g() {} +} + +extern "Rust" { + #[track_caller] // { dg-error ".E0736." "" { target *-*-* } } + #[naked] + fn h(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-start.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-start.rs new file mode 100644 index 000000000000..e1717909eea1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/error-with-start.rs @@ -0,0 +1,8 @@ +#![feature(start)] + +#[start] +#[track_caller] // { dg-error "" "" { target *-*-* } } +fn start(_argc: isize, _argv: *const *const u8) -> isize { + panic!("{}: oh no", std::panic::Location::caller()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/intrinsic-wrapper.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/intrinsic-wrapper.rs new file mode 100644 index 000000000000..f132fad5896f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/intrinsic-wrapper.rs @@ -0,0 +1,22 @@ +// run-pass +// revisions: default mir-opt +//[mir-opt] compile-flags: -Zmir-opt-level=3 + +macro_rules! caller_location_from_macro { + () => (core::panic::Location::caller()); +} + +fn main() { + let loc = core::panic::Location::caller(); + assert_eq!(loc.file(), file!()); + assert_eq!(loc.line(), 10); + assert_eq!(loc.column(), 15); + + // `Location::caller()` in a macro should behave similarly to `file!` and `line!`, + // i.e. point to where the macro was invoked, instead of the macro itself. + let loc2 = caller_location_from_macro!(); + assert_eq!(loc2.file(), file!()); + assert_eq!(loc2.line(), 17); + assert_eq!(loc2.column(), 16); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/only-for-fns.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/only-for-fns.rs new file mode 100644 index 000000000000..361d114fa25b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/only-for-fns.rs @@ -0,0 +1,6 @@ +#[track_caller] +struct S; +// { dg-error ".E0739." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/pass.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/pass.rs new file mode 100644 index 000000000000..0c6727d5a073 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/pass.rs @@ -0,0 +1,11 @@ +// run-pass +// revisions: default mir-opt +//[mir-opt] compile-flags: -Zmir-opt-level=3 + +#[track_caller] +fn f() {} + +fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/std-panic-locations.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/std-panic-locations.rs new file mode 100644 index 000000000000..68e66cb1fa1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/std-panic-locations.rs @@ -0,0 +1,70 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default +// revisions: default mir-opt +//[mir-opt] compile-flags: -Zmir-opt-level=3 + +#![feature(option_expect_none, option_unwrap_none)] +#![allow(unconditional_panic)] + +//! Test that panic locations for `#[track_caller]` functions in std have the correct +//! location reported. + +use std::cell::RefCell; +use std::collections::{BTreeMap, HashMap, VecDeque}; +use std::ops::{Index, IndexMut}; +use std::panic::{AssertUnwindSafe, UnwindSafe}; + +fn main() { + // inspect the `PanicInfo` we receive to ensure the right file is the source + std::panic::set_hook(Box::new(|info| { + let actual = info.location().unwrap(); + if actual.file() != file!() { + eprintln!("expected a location in the test file, found {:?}", actual); + panic!(); + } + })); + + fn assert_panicked(f: impl FnOnce() + UnwindSafe) { + std::panic::catch_unwind(f).unwrap_err(); + } + + let nope: Option<()> = None; + assert_panicked(|| nope.unwrap()); + assert_panicked(|| nope.expect("")); + + let yep: Option<()> = Some(()); + assert_panicked(|| yep.unwrap_none()); + assert_panicked(|| yep.expect_none("")); + + let oops: Result<(), ()> = Err(()); + assert_panicked(|| oops.unwrap()); + assert_panicked(|| oops.expect("")); + + let fine: Result<(), ()> = Ok(()); + assert_panicked(|| fine.unwrap_err()); + assert_panicked(|| fine.expect_err("")); + + let mut small = [0]; // the implementation backing str, vec, etc + assert_panicked(move || { small.index(1); }); + assert_panicked(move || { small[1]; }); + assert_panicked(move || { small.index_mut(1); }); + assert_panicked(move || { small[1] += 1; }); + + let sorted: BTreeMap = Default::default(); + assert_panicked(|| { sorted.index(&false); }); + assert_panicked(|| { sorted[&false]; }); + + let unsorted: HashMap = Default::default(); + assert_panicked(|| { unsorted.index(&false); }); + assert_panicked(|| { unsorted[&false]; }); + + let weirdo: VecDeque<()> = Default::default(); + assert_panicked(|| { weirdo.index(1); }); + assert_panicked(|| { weirdo[1]; }); + + let refcell: RefCell<()> = Default::default(); + let _conflicting = refcell.borrow_mut(); + assert_panicked(AssertUnwindSafe(|| { refcell.borrow(); })); + assert_panicked(AssertUnwindSafe(|| { refcell.borrow_mut(); })); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/track-caller-attribute.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/track-caller-attribute.rs new file mode 100644 index 000000000000..a8d5435564d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/track-caller-attribute.rs @@ -0,0 +1,41 @@ +// run-pass +// revisions: default mir-opt +//[mir-opt] compile-flags: -Zmir-opt-level=3 + +use std::panic::Location; + +#[track_caller] +fn tracked() -> &'static Location<'static> { + Location::caller() +} + +fn nested_intrinsic() -> &'static Location<'static> { + Location::caller() +} + +fn nested_tracked() -> &'static Location<'static> { + tracked() +} + +fn main() { + let location = Location::caller(); + assert_eq!(location.file(), file!()); + assert_eq!(location.line(), 21); + assert_eq!(location.column(), 20); + + let tracked = tracked(); + assert_eq!(tracked.file(), file!()); + assert_eq!(tracked.line(), 26); + assert_eq!(tracked.column(), 19); + + let nested = nested_intrinsic(); + assert_eq!(nested.file(), file!()); + assert_eq!(nested.line(), 13); + assert_eq!(nested.column(), 5); + + let contained = nested_tracked(); + assert_eq!(contained.file(), file!()); + assert_eq!(contained.line(), 17); + assert_eq!(contained.column(), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/track-caller-ffi.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/track-caller-ffi.rs new file mode 100644 index 000000000000..877df0b876ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/track-caller-ffi.rs @@ -0,0 +1,49 @@ +// run-pass + +use std::panic::Location; + +extern "Rust" { + #[track_caller] + fn rust_track_caller_ffi_test_tracked() -> &'static Location<'static>; + fn rust_track_caller_ffi_test_untracked() -> &'static Location<'static>; +} + +fn rust_track_caller_ffi_test_nested_tracked() -> &'static Location<'static> { + unsafe { rust_track_caller_ffi_test_tracked() } +} + +mod provides { + use std::panic::Location; + #[track_caller] // UB if we did not have this! + #[no_mangle] + fn rust_track_caller_ffi_test_tracked() -> &'static Location<'static> { + Location::caller() + } + #[no_mangle] + fn rust_track_caller_ffi_test_untracked() -> &'static Location<'static> { + Location::caller() + } +} + +fn main() { + let location = Location::caller(); + assert_eq!(location.file(), file!()); + assert_eq!(location.line(), 29); + assert_eq!(location.column(), 20); + + let tracked = unsafe { rust_track_caller_ffi_test_tracked() }; + assert_eq!(tracked.file(), file!()); + assert_eq!(tracked.line(), 34); + assert_eq!(tracked.column(), 28); + + let untracked = unsafe { rust_track_caller_ffi_test_untracked() }; + assert_eq!(untracked.file(), file!()); + assert_eq!(untracked.line(), 24); + assert_eq!(untracked.column(), 9); + + let contained = rust_track_caller_ffi_test_nested_tracked(); + assert_eq!(contained.file(), file!()); + assert_eq!(contained.line(), 12); + assert_eq!(contained.column(), 14); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs new file mode 100644 index 000000000000..724918a121a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-fn-ptr-with-arg.rs @@ -0,0 +1,63 @@ +// run-pass +// revisions: default mir-opt +//[mir-opt] compile-flags: -Zmir-opt-level=3 + +fn pass_to_ptr_call(f: fn(T), x: T) { + f(x); +} + +#[track_caller] +fn tracked_unit(_: ()) { + let expected_line = line!() - 1; + let location = std::panic::Location::caller(); + assert_eq!(location.file(), file!()); + assert_eq!(location.line(), expected_line, "call shims report location as fn definition"); +} + +trait Trait { + fn trait_tracked_unit(_: ()); +} + +impl Trait for () { + #[track_caller] + fn trait_tracked_unit(_: ()) { + let expected_line = line!() - 1; + let location = std::panic::Location::caller(); + assert_eq!(location.file(), file!()); + assert_eq!(location.line(), expected_line, "call shims report location as fn definition"); + } +} + +trait TrackedTrait { + #[track_caller] + fn trait_tracked_unit_default(_: ()) { + let expected_line = line!() - 1; + let location = std::panic::Location::caller(); + assert_eq!(location.file(), file!()); + assert_eq!(location.line(), expected_line, "call shims report location as fn definition"); + } +} + +impl TrackedTrait for () {} + +trait BlanketTrackedTrait { + #[track_caller] + fn tracked_blanket(_: ()); +} + +impl BlanketTrackedTrait for () { + fn tracked_blanket(_: ()) { + let expected_line = line!() - 1; + let location = std::panic::Location::caller(); + assert_eq!(location.file(), file!()); + assert_eq!(location.line(), expected_line, "call shims report location as fn definition"); + } +} + +fn main() { + pass_to_ptr_call(tracked_unit, ()); + pass_to_ptr_call(<() as Trait>::trait_tracked_unit, ()); + pass_to_ptr_call(<() as TrackedTrait>::trait_tracked_unit_default, ()); + pass_to_ptr_call(<() as BlanketTrackedTrait>::tracked_blanket, ()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-fn-ptr.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-fn-ptr.rs new file mode 100644 index 000000000000..a0323c288b8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-fn-ptr.rs @@ -0,0 +1,63 @@ +// run-pass +// revisions: default mir-opt +//[mir-opt] compile-flags: -Zmir-opt-level=3 + +fn ptr_call(f: fn()) { + f(); +} + +#[track_caller] +fn tracked() { + let expected_line = line!() - 1; + let location = std::panic::Location::caller(); + assert_eq!(location.file(), file!()); + assert_eq!(location.line(), expected_line, "call shims report location as fn definition"); +} + +trait Trait { + fn trait_tracked(); +} + +impl Trait for () { + #[track_caller] + fn trait_tracked() { + let expected_line = line!() - 1; + let location = std::panic::Location::caller(); + assert_eq!(location.file(), file!()); + assert_eq!(location.line(), expected_line, "call shims report location as fn definition"); + } +} + +trait TrackedTrait { + #[track_caller] + fn trait_tracked_default() { + let expected_line = line!() - 1; + let location = std::panic::Location::caller(); + assert_eq!(location.file(), file!()); + assert_eq!(location.line(), expected_line, "call shims report location as fn definition"); + } +} + +impl TrackedTrait for () {} + +trait TraitBlanketTracked { + #[track_caller] + fn tracked_blanket(); +} + +impl TraitBlanketTracked for () { + fn tracked_blanket() { + let expected_line = line!() - 1; + let location = std::panic::Location::caller(); + assert_eq!(location.file(), file!()); + assert_eq!(location.line(), expected_line, "call shims report location as fn definition"); + } +} + +fn main() { + ptr_call(tracked); + ptr_call(<() as Trait>::trait_tracked); + ptr_call(<() as TrackedTrait>::trait_tracked_default); + ptr_call(<() as TraitBlanketTracked>::tracked_blanket); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-trait-impls.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-trait-impls.rs new file mode 100644 index 000000000000..49aa92ab47ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-trait-impls.rs @@ -0,0 +1,78 @@ +// run-pass + +macro_rules! assert_expansion_site_is_tracked { + () => {{ + let location = std::panic::Location::caller(); + assert_eq!(location.file(), file!()); + assert_ne!(location.line(), line!(), "line should be outside this fn"); + }} +} + +trait Tracked { + fn local_tracked(&self); + + #[track_caller] + fn blanket_tracked(&self); + + #[track_caller] + fn default_tracked(&self) { + assert_expansion_site_is_tracked!(); + } +} + +impl Tracked for () { + #[track_caller] + fn local_tracked(&self) { + assert_expansion_site_is_tracked!(); + } + + fn blanket_tracked(&self) { + assert_expansion_site_is_tracked!(); + } +} + +impl Tracked for bool { + #[track_caller] + fn local_tracked(&self) { + assert_expansion_site_is_tracked!(); + } + + fn blanket_tracked(&self) { + assert_expansion_site_is_tracked!(); + } + + fn default_tracked(&self) { + assert_expansion_site_is_tracked!(); + } +} + +impl Tracked for u8 { + #[track_caller] + fn local_tracked(&self) { + assert_expansion_site_is_tracked!(); + } + + fn blanket_tracked(&self) { + assert_expansion_site_is_tracked!(); + } + + #[track_caller] + fn default_tracked(&self) { + assert_expansion_site_is_tracked!(); + } +} + +fn main() { + ().local_tracked(); + ().default_tracked(); + ().blanket_tracked(); + + true.local_tracked(); + true.default_tracked(); + true.blanket_tracked(); + + 0u8.local_tracked(); + 0u8.default_tracked(); + 0u8.blanket_tracked(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-trait-obj.rs b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-trait-obj.rs new file mode 100644 index 000000000000..5efede19941b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2091-track-caller/tracked-trait-obj.rs @@ -0,0 +1,24 @@ +// run-pass + +trait Tracked { + #[track_caller] + fn handle(&self) { + let location = std::panic::Location::caller(); + assert_eq!(location.file(), file!()); + // we only call this via trait object, so the def site should *always* be returned + assert_eq!(location.line(), line!() - 4); + assert_eq!(location.column(), 5); + } +} + +impl Tracked for () {} +impl Tracked for u8 {} + +fn main() { + let tracked: &dyn Tracked = &5u8; + tracked.handle(); + + const TRACKED: &dyn Tracked = &(); + TRACKED.handle(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/cross-crate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/cross-crate.rs new file mode 100644 index 000000000000..140f5a243762 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/cross-crate.rs @@ -0,0 +1,9 @@ +#![feature(rustc_attrs)] + +#[rustc_outlives] +struct Foo<'a, T> { // { dg-error "" "" { target *-*-* } } + bar: std::slice::IterMut<'a, T> +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/dont-infer-static.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/dont-infer-static.rs new file mode 100644 index 000000000000..44ad34f870c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/dont-infer-static.rs @@ -0,0 +1,15 @@ +/* + * We don't infer `T: 'static` outlives relationships by default. + * Instead an additional feature gate `infer_static_outlives_requirements` + * is required. + */ + +struct Foo { + bar: Bar // { dg-error ".E0310." "" { target *-*-* } } +} +struct Bar { + x: T, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/enum.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/enum.rs new file mode 100644 index 000000000000..b1e8e011b36b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/enum.rs @@ -0,0 +1,28 @@ +#![feature(rustc_attrs)] + +// Needs an explicit where clause stating outlives condition. (RFC 2093) + +// Type T needs to outlive lifetime 'a. +#[rustc_outlives] +enum Foo<'a, T> { // { dg-error "" "" { target *-*-* } } + One(Bar<'a, T>) +} + +// Type U needs to outlive lifetime 'b +#[rustc_outlives] +struct Bar<'b, U> { // { dg-error "" "" { target *-*-* } } + field2: &'b U +} + +// Type K needs to outlive lifetime 'c. +#[rustc_outlives] +enum Ying<'c, K> { // { dg-error "" "" { target *-*-* } } + One(&'c Yang) +} + +struct Yang { + field2: V +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-dyn.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-dyn.rs new file mode 100644 index 000000000000..8627e881e1cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-dyn.rs @@ -0,0 +1,14 @@ +#![feature(dyn_trait)] +#![feature(rustc_attrs)] + +trait Trait<'x, T> where T: 'x { +} + +#[rustc_outlives] +struct Foo<'a, A> // { dg-error "" "" { target *-*-* } } +{ + foo: Box> +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-enum.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-enum.rs new file mode 100644 index 000000000000..fb92834aab13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-enum.rs @@ -0,0 +1,14 @@ +#![feature(rustc_attrs)] + +#[rustc_outlives] +enum Foo<'a, U> { // { dg-error "" "" { target *-*-* } } + One(Bar<'a, U>) +} + +struct Bar<'x, T> where T: 'x { + x: &'x (), + y: T, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-projection.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-projection.rs new file mode 100644 index 000000000000..c4cc7fcabada --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-projection.rs @@ -0,0 +1,14 @@ +#![feature(rustc_attrs)] + +trait Trait<'x, T> where T: 'x { + type Type; +} + +#[rustc_outlives] +struct Foo<'a, A, B> where A: Trait<'a, B> // { dg-error "" "" { target *-*-* } } +{ + foo: >::Type +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-struct.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-struct.rs new file mode 100644 index 000000000000..2f399cb4f574 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-struct.rs @@ -0,0 +1,14 @@ +#![feature(rustc_attrs)] + +#[rustc_outlives] +struct Foo<'b, U> { // { dg-error "" "" { target *-*-* } } + bar: Bar<'b, U> +} + +struct Bar<'a, T> where T: 'a { + x: &'a (), + y: T, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-union.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-union.rs new file mode 100644 index 000000000000..84144d274284 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/explicit-union.rs @@ -0,0 +1,15 @@ +#![feature(rustc_attrs)] +#![feature(untagged_unions)] + +#[rustc_outlives] +union Foo<'b, U: Copy> { // { dg-error "" "" { target *-*-* } } + bar: Bar<'b, U> +} + +union Bar<'a, T: Copy> where T: 'a { + x: &'a (), + y: T, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/infer-static.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/infer-static.rs new file mode 100644 index 000000000000..1925e05d03cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/infer-static.rs @@ -0,0 +1,13 @@ +#![feature(rustc_attrs)] +#![feature(infer_static_outlives_requirements)] + +#[rustc_outlives] +struct Foo { // { dg-error "" "" { target *-*-* } } + bar: Bar +} +struct Bar { + x: T, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/issue-54467.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/issue-54467.rs new file mode 100644 index 000000000000..426c6f56d6ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/issue-54467.rs @@ -0,0 +1,18 @@ +// Regression test for #54467: +// +// Here, the trait object has an "inferred outlives" requirement that +// `>::Item: 'a`; but since we don't know what +// `Self` is, we were (incorrectly) messing things up, leading to +// strange errors. This test ensures that we do not give compilation +// errors. +// +// check-pass + +trait MyIterator<'a>: Iterator where Self::Item: 'a { } + +struct MyStruct<'a, A> { + item: Box> +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-enum.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-enum.rs new file mode 100644 index 000000000000..0f2231c41980 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-enum.rs @@ -0,0 +1,14 @@ +#![feature(rustc_attrs)] + +#[rustc_outlives] +enum Foo<'a, T> { // { dg-error "" "" { target *-*-* } } + + One(Bar<'a, T>) +} + +struct Bar<'b, U> { + field2: &'b U +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-regions.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-regions.rs new file mode 100644 index 000000000000..20fa9010b39c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-regions.rs @@ -0,0 +1,9 @@ +#![feature(rustc_attrs)] + +#[rustc_outlives] +struct Foo<'a, 'b, T> { // { dg-error "" "" { target *-*-* } } + x: &'a &'b T +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-structs.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-structs.rs new file mode 100644 index 000000000000..0186e2841cf8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-structs.rs @@ -0,0 +1,13 @@ +#![feature(rustc_attrs)] + +#[rustc_outlives] +struct Foo<'a, T> { // { dg-error "" "" { target *-*-* } } + field1: Bar<'a, T> +} + +struct Bar<'b, U> { + field2: &'b U +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-union.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-union.rs new file mode 100644 index 000000000000..69f3ba438eb7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/nested-union.rs @@ -0,0 +1,15 @@ +#![feature(rustc_attrs)] +#![feature(untagged_unions)] + +#[rustc_outlives] +union Foo<'a, T: Copy> { // { dg-error "" "" { target *-*-* } } + field1: Bar<'a, T> +} + +// Type U needs to outlive lifetime 'b +union Bar<'b, U: Copy> { + field2: &'b U +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/privacy.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/privacy.rs new file mode 100644 index 000000000000..9f2f87bc3b1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/privacy.rs @@ -0,0 +1,21 @@ +// Test that we do not get a privacy error here. Initially, we did, +// because we inferred an outlives predciate of ` as +// Private>::Out: 'a`, but the private trait is -- well -- private, +// and hence it was not something that a pub trait could refer to. +// +// run-pass + +#![allow(dead_code)] + +pub struct Foo<'a> { + field: Option<&'a as Private>::Out> +} + +trait Private { + type Out: ?Sized; +} + +impl Private for T { type Out = Self; } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/projection.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/projection.rs new file mode 100644 index 000000000000..d64fe94ee12b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/projection.rs @@ -0,0 +1,9 @@ +#![feature(rustc_attrs)] + +#[rustc_outlives] +struct Foo<'a, T: Iterator> { // { dg-error "" "" { target *-*-* } } + bar: &'a T::Item +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/reference.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/reference.rs new file mode 100644 index 000000000000..31fe2cc7ca73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/reference.rs @@ -0,0 +1,9 @@ +#![feature(rustc_attrs)] + +#[rustc_outlives] +struct Foo<'a, T> { // { dg-error "" "" { target *-*-* } } + bar: &'a T, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs new file mode 100644 index 000000000000..72943ef76f39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-enum-not-wf.rs @@ -0,0 +1,42 @@ +// ignore-tidy-linelength + +// Various examples of structs whose fields are not well-formed. + +#![allow(dead_code)] + +trait Dummy<'a> { + type Out; +} +impl<'a, T> Dummy<'a> for T +where + T: 'a, +{ + type Out = (); +} +type RequireOutlives<'a, T> = >::Out; + +enum Ref1<'a, T> { + Ref1Variant1(RequireOutlives<'a, T>), // { dg-error ".E0309." "" { target *-*-* } } +} + +enum Ref2<'a, T> { + Ref2Variant1, + Ref2Variant2(isize, RequireOutlives<'a, T>), // { dg-error ".E0309." "" { target *-*-* } } +} + +enum RefOk<'a, T: 'a> { + RefOkVariant1(&'a T), +} + +// This is now well formed. RFC 2093 +enum RefIndirect<'a, T> { + RefIndirectVariant1(isize, RefOk<'a, T>), +} + +enum RefDouble<'a, 'b, T> { + RefDoubleVariant1(&'a RequireOutlives<'b, T>), +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.rs new file mode 100644 index 000000000000..a83652a1efc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.rs @@ -0,0 +1,23 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + + +#![allow(dead_code)] + +mod rev_variant_struct_region { + struct Foo<'a> { + x: fn(&'a i32), + } + trait Trait<'a, 'b> { + type Out; + } + impl<'a, 'b> Trait<'a, 'b> for usize { + type Out = &'a Foo<'b>; // { dg-error ".E0491." "" { target *-*-* } } + } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.rs new file mode 100644 index 000000000000..4af710e06395 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.rs @@ -0,0 +1,23 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + + +#![allow(dead_code)] + +mod variant_struct_region { + struct Foo<'a> { + x: &'a i32, + } + trait Trait<'a, 'b> { + type Out; + } + impl<'a, 'b> Trait<'a, 'b> for usize { + type Out = &'a Foo<'b>; // { dg-error ".E0491." "" { target *-*-* } } + } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.rs new file mode 100644 index 000000000000..049ac9554b72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.rs @@ -0,0 +1,23 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + + +#![allow(dead_code)] + +mod variant_struct_type { + struct Foo { + x: fn(T) + } + trait Trait<'a, 'b> { + type Out; + } + impl<'a, 'b> Trait<'a, 'b> for usize { + type Out = &'a Foo<&'b i32>; // { dg-error ".E0491." "" { target *-*-* } } + } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.rs new file mode 100644 index 000000000000..48475ed9d569 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.rs @@ -0,0 +1,23 @@ +// Test that a nominal type (like `Foo<'a>`) outlives `'b` if its +// arguments (like `'a`) outlive `'b`. +// +// Rule OutlivesNominalType from RFC 1214. + + +#![allow(dead_code)] + +mod variant_struct_type { + struct Foo { + x: T + } + trait Trait<'a, 'b> { + type Out; + } + impl<'a, 'b> Trait<'a, 'b> for usize { + type Out = &'a Foo<&'b i32>; // { dg-error ".E0491." "" { target *-*-* } } + } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-struct-not-wf.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-struct-not-wf.rs new file mode 100644 index 000000000000..9ac7ecd35ab0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/regions-struct-not-wf.rs @@ -0,0 +1,29 @@ +// Various examples of structs whose fields are not well-formed. + +#![allow(dead_code)] + +trait Trait<'a, T> { + type Out; +} +trait Trait1<'a, 'b, T> { + type Out; +} + +impl<'a, T> Trait<'a, T> for usize { + type Out = &'a T; // { dg-error ".E0309." "" { target *-*-* } } +} + +struct RefOk<'a, T:'a> { + field: &'a T +} + +impl<'a, T> Trait<'a, T> for u32 { + type Out = RefOk<'a, T>; // { dg-error ".E0309." "" { target *-*-* } } +} + +impl<'a, 'b, T> Trait1<'a, 'b, T> for u32 { + type Out = &'a &'b T; // { dg-error ".E0491." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/self-dyn.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/self-dyn.rs new file mode 100644 index 000000000000..ff782db700c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/self-dyn.rs @@ -0,0 +1,15 @@ +#![feature(dyn_trait)] +#![feature(rustc_attrs)] + +trait Trait<'x, 's, T> where T: 'x, + 's: { +} + +#[rustc_outlives] +struct Foo<'a, 'b, A> // { dg-error "" "" { target *-*-* } } +{ + foo: Box> +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/self-structs.rs b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/self-structs.rs new file mode 100644 index 000000000000..f7ca38ee7498 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2093-infer-outlives/self-structs.rs @@ -0,0 +1,14 @@ +#![feature(rustc_attrs)] + +#[rustc_outlives] +struct Foo<'a, 'b, T> { // { dg-error "" "" { target *-*-* } } + field1: dyn Bar<'a, 'b, T> +} + +trait Bar<'x, 's, U> + where U: 'x, + Self:'s +{} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2126-crate-paths/crate-path-non-absolute.rs b/gcc/testsuite/rust/rustc/ui/rfc-2126-crate-paths/crate-path-non-absolute.rs new file mode 100644 index 000000000000..7ddd502b9662 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2126-crate-paths/crate-path-non-absolute.rs @@ -0,0 +1,14 @@ +#![feature(crate_in_paths)] + +struct S; + +pub mod m { + fn f() { + let s = ::m::crate::S; // { dg-error ".E0433." "" { target *-*-* } } + let s1 = ::crate::S; // { dg-error ".E0433." "" { target *-*-* } } + let s2 = crate::S; // no error + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.rs b/gcc/testsuite/rust/rustc/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.rs new file mode 100644 index 000000000000..e6591de5ad8a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.rs @@ -0,0 +1,7 @@ +#![feature(crate_in_paths)] + +fn main() { + let crate = 0; +// { dg-error ".E0532." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/auxiliary/xcrate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/auxiliary/xcrate.rs new file mode 100644 index 000000000000..544374fb2801 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/auxiliary/xcrate.rs @@ -0,0 +1,6 @@ +#[derive(Debug)] +pub struct S; + +#[derive(Debug)] +pub struct Z; + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-1.rs b/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-1.rs new file mode 100644 index 000000000000..bfd95aec5f3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-1.rs @@ -0,0 +1,6 @@ +// edition:2018 + +use xcrate::S; // { dg-error ".E0432." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-2.rs b/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-2.rs new file mode 100644 index 000000000000..eb5ca5c4e968 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-2.rs @@ -0,0 +1,7 @@ +// edition:2018 + +fn main() { + let s = ::xcrate::S; +// { dg-error ".E0433." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-3.rs b/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-3.rs new file mode 100644 index 000000000000..31b9c92a72dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/non-existent-3.rs @@ -0,0 +1,6 @@ +// edition:2018 + +use ycrate; // { dg-error ".E0432." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/not-allowed.rs b/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/not-allowed.rs new file mode 100644 index 000000000000..406a9811965f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/not-allowed.rs @@ -0,0 +1,10 @@ +// edition:2018 + +// Tests that arbitrary crates (other than `core`, `std` and `meta`) +// aren't allowed without `--extern`, even if they're in the sysroot. +use alloc; // { dg-error ".E0432." "" { target *-*-* } } +use test; // OK, imports the built-in attribute macro `#[test]`, but not the `test` crate. +use proc_macro; // OK, imports the built-in `proc_macro` attribute, but not the `proc_macro` crate. + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/single-segment.rs b/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/single-segment.rs new file mode 100644 index 000000000000..bd07d1541061 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2126-extern-absolute-paths/single-segment.rs @@ -0,0 +1,12 @@ +// aux-build:xcrate.rs +// compile-flags:--extern xcrate +// edition:2018 + +use crate; // { dg-error "" "" { target *-*-* } } +use *; // { dg-error "" "" { target *-*-* } } + +fn main() { + let s = ::xcrate; // { dg-error ".E0423." "" { target *-*-* } } +// { dg-note ".E0423." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2294-if-let-guard/feature-gate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2294-if-let-guard/feature-gate.rs new file mode 100644 index 000000000000..e2db74f5e772 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2294-if-let-guard/feature-gate.rs @@ -0,0 +1,86 @@ +// gate-test-if_let_guard + +use std::ops::Range; + +fn _if_let_guard() { + match () { + () if let 0 = 1 => {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + () if (let 0 = 1) => {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + () if (((let 0 = 1))) => {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + () if true && let 0 = 1 => {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + () if let 0 = 1 && true => {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + () if (let 0 = 1) && true => {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + () if true && (let 0 = 1) => {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + () if (let 0 = 1) && (let 0 = 1) => {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +// { dg-error ".E0658." "" { target *-*-* } .-4 } + + () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +// { dg-error ".E0658." "" { target *-*-* } .-4 } +// { dg-error ".E0658." "" { target *-*-* } .-5 } +// { dg-error ".E0658." "" { target *-*-* } .-6 } +// { dg-error ".E0658." "" { target *-*-* } .-7 } +// { dg-error ".E0658." "" { target *-*-* } .-8 } +// { dg-error ".E0658." "" { target *-*-* } .-9 } +// { dg-error ".E0658." "" { target *-*-* } .-10 } + + () if let Range { start: _, end: _ } = (true..true) && false => {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + _ => {} + } +} + +fn _macros() { + macro_rules! use_expr { + ($e:expr) => { + match () { + () if $e => {} + _ => {} + } + } + } + use_expr!((let 0 = 1 && 0 == 0)); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + use_expr!((let 0 = 1)); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + match () { + #[cfg(FALSE)] + () if let 0 = 1 => {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + _ => {} + } + use_expr!(let 0 = 1); +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2306/convert-id-const-with-gate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2306/convert-id-const-with-gate.rs new file mode 100644 index 000000000000..d7671b4138b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2306/convert-id-const-with-gate.rs @@ -0,0 +1,8 @@ +// This test should pass since 'identity' is const fn. + +// build-pass (FIXME(62277): could be check-pass?) + +fn main() { + const _FOO: u8 = ::std::convert::identity(42u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs b/gcc/testsuite/rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs new file mode 100644 index 000000000000..693eaf1ff8a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs @@ -0,0 +1,68 @@ +// run-pass +// check-run-results + +// Tests ensuring that `dbg!(expr)` has the expected run-time behavior. +// as well as some compile time properties we expect. + +#[derive(Copy, Clone, Debug)] +struct Unit; + +#[derive(Copy, Clone, Debug, PartialEq)] +struct Point { + x: T, + y: T, +} + +#[derive(Debug, PartialEq)] +struct NoCopy(usize); + +fn main() { + let a: Unit = dbg!(Unit); + let _: Unit = dbg!(a); + // We can move `a` because it's Copy. + drop(a); + + // `Point` will be faithfully formatted according to `{:#?}`. + let a = Point { x: 42, y: 24 }; + let b: Point = dbg!(Point { x: 42, y: 24 }); // test stringify!(..) + let c: Point = dbg!(b); + // Identity conversion: + assert_eq!(a, b); + assert_eq!(a, c); + // We can move `b` because it's Copy. + drop(b); + + // Without parameters works as expected. + let _: () = dbg!(); + + // Test that we can borrow and that successive applications is still identity. + let a = NoCopy(1337); + let b: &NoCopy = dbg!(dbg!(&a)); + assert_eq!(&a, b); + + // Test involving lifetimes of temporaries: + fn f<'a>(x: &'a u8) -> &'a u8 { x } + let a: &u8 = dbg!(f(&42)); + assert_eq!(a, &42); + + // Test side effects: + let mut foo = 41; + assert_eq!(7331, dbg!({ + foo += 1; + eprintln!("before"); + 7331 + })); + assert_eq!(foo, 42); + + // Test trailing comma: + assert_eq!(("Yeah",), dbg!(("Yeah",))); + + // Test multiple arguments: + assert_eq!((1u8, 2u32), dbg!(1, + 2)); + + // Test multiple arguments + trailing comma: + assert_eq!((1u8, 2u32, "Yeah"), dbg!(1u8, 2u32, + "Yeah",)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.rs b/gcc/testsuite/rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.rs new file mode 100644 index 000000000000..80450c3fab67 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-move-semantics.rs @@ -0,0 +1,11 @@ +// Test ensuring that `dbg!(expr)` will take ownership of the argument. + +#[derive(Debug)] +struct NoCopy(usize); + +fn main() { + let a = NoCopy(0); + let _ = dbg!(a); + let _ = dbg!(a); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.rs b/gcc/testsuite/rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.rs new file mode 100644 index 000000000000..354fad203915 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.rs @@ -0,0 +1,8 @@ +// Test ensuring that `dbg!(expr)` requires the passed type to implement `Debug`. + +struct NotDebug; + +fn main() { + let _: NotDebug = dbg!(NotDebug); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2457/auxiliary/mod_file_nonascii_with_path_allowed-aux.rs b/gcc/testsuite/rust/rustc/ui/rfc-2457/auxiliary/mod_file_nonascii_with_path_allowed-aux.rs new file mode 100644 index 000000000000..64be4375d161 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2457/auxiliary/mod_file_nonascii_with_path_allowed-aux.rs @@ -0,0 +1,2 @@ +pub trait Foo {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2457/crate_name_nonascii_forbidden-1.rs b/gcc/testsuite/rust/rustc/ui/rfc-2457/crate_name_nonascii_forbidden-1.rs new file mode 100644 index 000000000000..9755c5397655 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2457/crate_name_nonascii_forbidden-1.rs @@ -0,0 +1,6 @@ +#![feature(non_ascii_idents)] + +extern crate ьаг; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2457/crate_name_nonascii_forbidden-2.rs b/gcc/testsuite/rust/rustc/ui/rfc-2457/crate_name_nonascii_forbidden-2.rs new file mode 100644 index 000000000000..b139fe2235ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2457/crate_name_nonascii_forbidden-2.rs @@ -0,0 +1,8 @@ +// compile-flags:--extern му_сгате +// edition:2018 +#![feature(non_ascii_idents)] + +use му_сгате::baz; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2457/idents-normalized.rs b/gcc/testsuite/rust/rustc/ui/rfc-2457/idents-normalized.rs new file mode 100644 index 000000000000..d9d8edc623e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2457/idents-normalized.rs @@ -0,0 +1,9 @@ +// check-pass +#![feature(non_ascii_idents)] + +struct Résumé; // ['LATIN SMALL LETTER E WITH ACUTE'] + +fn main() { + let _ = Résumé; // ['LATIN SMALL LETTER E', 'COMBINING ACUTE ACCENT'] +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2457/mod_file_nonascii_forbidden.rs b/gcc/testsuite/rust/rustc/ui/rfc-2457/mod_file_nonascii_forbidden.rs new file mode 100644 index 000000000000..c7588a44abd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2457/mod_file_nonascii_forbidden.rs @@ -0,0 +1,7 @@ +#![feature(non_ascii_idents)] + +mod řųśť; // { dg-error ".E0754." "" { target *-*-* } } +// { dg-error ".E0754." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2457/mod_file_nonascii_with_path_allowed.rs b/gcc/testsuite/rust/rustc/ui/rfc-2457/mod_file_nonascii_with_path_allowed.rs new file mode 100644 index 000000000000..f026c1c5ecd4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2457/mod_file_nonascii_with_path_allowed.rs @@ -0,0 +1,8 @@ +// check-pass +#![feature(non_ascii_idents)] + +#[path="auxiliary/mod_file_nonascii_with_path_allowed-aux.rs"] +mod řųśť; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2457/mod_inline_nonascii_allowed.rs b/gcc/testsuite/rust/rustc/ui/rfc-2457/mod_inline_nonascii_allowed.rs new file mode 100644 index 000000000000..b1d249d30f8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2457/mod_inline_nonascii_allowed.rs @@ -0,0 +1,9 @@ +// check-pass +#![feature(non_ascii_idents)] + +mod řųśť { + const IS_GREAT: bool = true; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2457/no_mangle_nonascii_forbidden.rs b/gcc/testsuite/rust/rustc/ui/rfc-2457/no_mangle_nonascii_forbidden.rs new file mode 100644 index 000000000000..fed576e7a329 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2457/no_mangle_nonascii_forbidden.rs @@ -0,0 +1,7 @@ +#![feature(non_ascii_idents)] + +#[no_mangle] +pub fn řųśť() {} // { dg-error ".E0754." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/ast-pretty-check.rs b/gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/ast-pretty-check.rs new file mode 100644 index 000000000000..324d23b01514 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/ast-pretty-check.rs @@ -0,0 +1,7 @@ +// build-pass (FIXME(62277): could be check-pass?) +// compile-flags: -Z unpretty=expanded + +fn main() { + if let 0 = 1 {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/disallowed-positions.rs b/gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/disallowed-positions.rs new file mode 100644 index 000000000000..da2bdb6f2e4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/disallowed-positions.rs @@ -0,0 +1,241 @@ +// Here we test that `lowering` behaves correctly wrt. `let $pats = $expr` expressions. +// +// We want to make sure that `let` is banned in situations other than: +// +// expr = +// | ... +// | "if" expr_with_let block {"else" block}? +// | {label ":"}? while" expr_with_let block +// ; +// +// expr_with_let = +// | "let" top_pats "=" expr +// | expr_with_let "&&" expr_with_let +// | "(" expr_with_let ")" +// | expr +// ; +// +// To that end, we check some positions which is not part of the language above. + +#![feature(const_generics)] +// { dg-warning "" "" { target *-*-* } .-1 } +#![feature(let_chains)] // Avoid inflating `.stderr` with overzealous gates in this test. +// { dg-warning "" "" { target *-*-* } .-1 } + +#![allow(irrefutable_let_patterns)] + +use std::ops::Range; + +fn main() {} + +fn nested_within_if_expr() { + if &let 0 = 0 {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + if !let 0 = 0 {} // { dg-error "" "" { target *-*-* } } + if *let 0 = 0 {} // { dg-error ".E0614." "" { target *-*-* } } +// { dg-error ".E0614." "" { target *-*-* } .-1 } + if -let 0 = 0 {} // { dg-error ".E0600." "" { target *-*-* } } +// { dg-error ".E0600." "" { target *-*-* } .-1 } + + fn _check_try_binds_tighter() -> Result<(), ()> { + if let 0 = 0? {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + Ok(()) + } + if (let 0 = 0)? {} // { dg-error ".E0277." "" { target *-*-* } } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + + if true || let 0 = 0 {} // { dg-error "" "" { target *-*-* } } + if (true || let 0 = 0) {} // { dg-error "" "" { target *-*-* } } + if true && (true || let 0 = 0) {} // { dg-error "" "" { target *-*-* } } + if true || (true && let 0 = 0) {} // { dg-error "" "" { target *-*-* } } + + let mut x = true; + if x = let 0 = 0 {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + if true..(let 0 = 0) {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + if ..(let 0 = 0) {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + if (let 0 = 0).. {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + // Binds as `(let ... = true)..true &&/|| false`. + if let Range { start: _, end: _ } = true..true && false {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + if let Range { start: _, end: _ } = true..true || false {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + + // Binds as `(let Range { start: F, end } = F)..(|| true)`. + const F: fn() -> bool = || true; + if let Range { start: F, end } = F..|| true {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + // Binds as `(let Range { start: true, end } = t)..(&&false)`. + let t = &&true; + if let Range { start: true, end } = t..&&false {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + if let true = let true = true {} // { dg-error "" "" { target *-*-* } } +} + +fn nested_within_while_expr() { + while &let 0 = 0 {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + while !let 0 = 0 {} // { dg-error "" "" { target *-*-* } } + while *let 0 = 0 {} // { dg-error ".E0614." "" { target *-*-* } } +// { dg-error ".E0614." "" { target *-*-* } .-1 } + while -let 0 = 0 {} // { dg-error ".E0600." "" { target *-*-* } } +// { dg-error ".E0600." "" { target *-*-* } .-1 } + + fn _check_try_binds_tighter() -> Result<(), ()> { + while let 0 = 0? {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + Ok(()) + } + while (let 0 = 0)? {} // { dg-error ".E0277." "" { target *-*-* } } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + + while true || let 0 = 0 {} // { dg-error "" "" { target *-*-* } } + while (true || let 0 = 0) {} // { dg-error "" "" { target *-*-* } } + while true && (true || let 0 = 0) {} // { dg-error "" "" { target *-*-* } } + while true || (true && let 0 = 0) {} // { dg-error "" "" { target *-*-* } } + + let mut x = true; + while x = let 0 = 0 {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + while true..(let 0 = 0) {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + while ..(let 0 = 0) {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + while (let 0 = 0).. {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + // Binds as `(let ... = true)..true &&/|| false`. + while let Range { start: _, end: _ } = true..true && false {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + while let Range { start: _, end: _ } = true..true || false {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + + // Binds as `(let Range { start: F, end } = F)..(|| true)`. + const F: fn() -> bool = || true; + while let Range { start: F, end } = F..|| true {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + // Binds as `(let Range { start: true, end } = t)..(&&false)`. + let t = &&true; + while let Range { start: true, end } = t..&&false {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + while let true = let true = true {} // { dg-error "" "" { target *-*-* } } +} + +fn not_error_because_clarified_intent() { + if let Range { start: _, end: _ } = (true..true || false) { } + + if let Range { start: _, end: _ } = (true..true && false) { } + + while let Range { start: _, end: _ } = (true..true || false) { } + + while let Range { start: _, end: _ } = (true..true && false) { } +} + +fn outside_if_and_while_expr() { + &let 0 = 0; // { dg-error "" "" { target *-*-* } } + + !let 0 = 0; // { dg-error "" "" { target *-*-* } } + *let 0 = 0; // { dg-error ".E0614." "" { target *-*-* } } +// { dg-error ".E0614." "" { target *-*-* } .-1 } + -let 0 = 0; // { dg-error ".E0600." "" { target *-*-* } } +// { dg-error ".E0600." "" { target *-*-* } .-1 } + + fn _check_try_binds_tighter() -> Result<(), ()> { + let 0 = 0?; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + Ok(()) + } + (let 0 = 0)?; // { dg-error ".E0277." "" { target *-*-* } } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + + true || let 0 = 0; // { dg-error "" "" { target *-*-* } } + (true || let 0 = 0); // { dg-error "" "" { target *-*-* } } + true && (true || let 0 = 0); // { dg-error "" "" { target *-*-* } } + + let mut x = true; + x = let 0 = 0; // { dg-error "" "" { target *-*-* } } + + true..(let 0 = 0); // { dg-error "" "" { target *-*-* } } + ..(let 0 = 0); // { dg-error "" "" { target *-*-* } } + (let 0 = 0)..; // { dg-error "" "" { target *-*-* } } + + (let Range { start: _, end: _ } = true..true || false); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + (let true = let true = true); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + // Check function tail position. + &let 0 = 0 +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +// Let's make sure that `let` inside const generic arguments are considered. +fn inside_const_generic_arguments() { + struct A; + impl A<{B}> { const O: u32 = 5; } + + if let A::<{ + true && let 1 = 1 // { dg-error "" "" { target *-*-* } } + }>::O = 5 {} + + while let A::<{ + true && let 1 = 1 // { dg-error "" "" { target *-*-* } } + }>::O = 5 {} + + if A::<{ + true && let 1 = 1 // { dg-error "" "" { target *-*-* } } + }>::O == 5 {} + + // In the cases above we have `ExprKind::Block` to help us out. + // Below however, we would not have a block and so an implementation might go + // from visiting expressions to types without banning `let` expressions down the tree. + // This tests ensures that we are not caught by surprise should the parser + // admit non-IDENT expressions in const generic arguments. + + if A::< + true && let 1 = 1 +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + >::O == 5 {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/feature-gate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/feature-gate.rs new file mode 100644 index 000000000000..1a59e2330146 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/feature-gate.rs @@ -0,0 +1,139 @@ +// gate-test-let_chains + +// Here we test feature gating for ´let_chains`. +// See `disallowed-positions.rs` for the grammar +// defining the language for gated allowed positions. + +#![allow(irrefutable_let_patterns)] + +use std::ops::Range; + +fn _if() { + if let 0 = 1 {} // Stable! + + if (let 0 = 1) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + if (((let 0 = 1))) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + if true && let 0 = 1 {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + if let 0 = 1 && true {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + if (let 0 = 1) && true {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + if true && (let 0 = 1) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + if (let 0 = 1) && (let 0 = 1) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +// { dg-error ".E0658." "" { target *-*-* } .-4 } + + if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +// { dg-error ".E0658." "" { target *-*-* } .-4 } +// { dg-error ".E0658." "" { target *-*-* } .-5 } +// { dg-error ".E0658." "" { target *-*-* } .-6 } +// { dg-error ".E0658." "" { target *-*-* } .-7 } +// { dg-error ".E0658." "" { target *-*-* } .-8 } +// { dg-error ".E0658." "" { target *-*-* } .-9 } +// { dg-error ".E0658." "" { target *-*-* } .-10 } + + if let Range { start: _, end: _ } = (true..true) && false {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +} + +fn _while() { + while let 0 = 1 {} // Stable! + + while (let 0 = 1) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + while (((let 0 = 1))) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + while true && let 0 = 1 {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + while let 0 = 1 && true {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + while (let 0 = 1) && true {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + while true && (let 0 = 1) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + while (let 0 = 1) && (let 0 = 1) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +// { dg-error ".E0658." "" { target *-*-* } .-4 } + + while let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } +// { dg-error ".E0658." "" { target *-*-* } .-4 } +// { dg-error ".E0658." "" { target *-*-* } .-5 } +// { dg-error ".E0658." "" { target *-*-* } .-6 } +// { dg-error ".E0658." "" { target *-*-* } .-7 } +// { dg-error ".E0658." "" { target *-*-* } .-8 } +// { dg-error ".E0658." "" { target *-*-* } .-9 } +// { dg-error ".E0658." "" { target *-*-* } .-10 } + + while let Range { start: _, end: _ } = (true..true) && false {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +} + +fn _macros() { + macro_rules! noop_expr { ($e:expr) => {}; } + + noop_expr!((let 0 = 1)); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + + macro_rules! use_expr { + ($e:expr) => { + if $e {} + while $e {} + } + } + use_expr!((let 0 = 1 && 0 == 0)); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } + use_expr!((let 0 = 1)); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } + #[cfg(FALSE)] (let 0 = 1); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + use_expr!(let 0 = 1); +// { dg-error "" "" { target *-*-* } .-1 } + // ^--- FIXME(53667): Consider whether `Let` can be added to `ident_can_begin_expr`. +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/protect-precedences.rs b/gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/protect-precedences.rs new file mode 100644 index 000000000000..e90810f0d60b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2497-if-let-chains/protect-precedences.rs @@ -0,0 +1,17 @@ +// run-pass + +#![allow(irrefutable_let_patterns)] + +fn main() { + let x: bool; + // This should associate as: `(x = (true && false));`. + x = true && false; + assert!(!x); + + fn _f1() -> bool { + // Should associate as `(let _ = (return (true && false)))`. + if let _ = return true && false {}; // { dg-warning "" "" { target *-*-* } } + } + assert!(!_f1()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/attr-without-param.rs b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/attr-without-param.rs new file mode 100644 index 000000000000..7dadbfedf9dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/attr-without-param.rs @@ -0,0 +1,17 @@ +#[cfg(FALSE)] +impl S { + fn f(#[attr]) {} // { dg-error "" "" { target *-*-* } } +} + +#[cfg(FALSE)] +impl T for S { + fn f(#[attr]) {} // { dg-error "" "" { target *-*-* } } +} + +#[cfg(FALSE)] +trait T { + fn f(#[attr]); // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs new file mode 100644 index 000000000000..549dc5ef97ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs @@ -0,0 +1,12 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn id(_: TokenStream, input: TokenStream) -> TokenStream { input } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs new file mode 100644 index 000000000000..9bbb81d27cb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs @@ -0,0 +1,44 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +macro_rules! checker { + ($attr_name:ident, $expected:literal) => { + #[proc_macro_attribute] + pub fn $attr_name(attr: TokenStream, input: TokenStream) -> TokenStream { + assert_eq!(input.to_string(), $expected); + TokenStream::new() + } + } +} + +checker!(attr_extern, r#"extern "C" { fn ffi(#[a1] arg1 : i32, #[a2] ...) ; }"#); +checker!(attr_extern_cvar, r#"unsafe extern "C" fn cvar(arg1 : i32, #[a1] mut args : ...) { }"#); +checker!(attr_alias, "type Alias = fn(#[a1] u8, #[a2] ...) ;"); +checker!(attr_free, "fn free(#[a1] arg1 : u8) { let lam = | #[a2] W(x), #[a3] y | () ; }"); +checker!(attr_inherent_1, "fn inherent1(#[a1] self, #[a2] arg1 : u8) { }"); +checker!(attr_inherent_2, "fn inherent2(#[a1] & self, #[a2] arg1 : u8) { }"); +checker!(attr_inherent_3, "fn inherent3 < 'a > (#[a1] & 'a mut self, #[a2] arg1 : u8) { }"); +checker!(attr_inherent_4, "fn inherent4 < 'a > (#[a1] self : Box < Self >, #[a2] arg1 : u8) { }"); +checker!(attr_inherent_issue_64682, "fn inherent5(#[a1] #[a2] arg1 : u8, #[a3] arg2 : u8) { }"); +checker!(attr_trait_1, "fn trait1(#[a1] self, #[a2] arg1 : u8) ;"); +checker!(attr_trait_2, "fn trait2(#[a1] & self, #[a2] arg1 : u8) ;"); +checker!(attr_trait_3, "fn trait3 < 'a > (#[a1] & 'a mut self, #[a2] arg1 : u8) ;"); +checker!(attr_trait_4, r#"fn trait4 < 'a > +(#[a1] self : Box < Self >, #[a2] arg1 : u8, #[a3] Vec < u8 >) ;"#); +checker!(attr_trait_issue_64682, "fn trait5(#[a1] #[a2] arg1 : u8, #[a3] arg2 : u8) ;"); +checker!(rename_params, r#"impl Foo +{ + fn hello(#[angery(true)] a : i32, #[a2] b : i32, #[what = "how"] c : u32) + { } fn + hello2(#[a1] #[a2] a : i32, #[what = "how"] b : i32, #[angery(true)] c : + u32) { } fn + hello_self(#[a1] #[a2] & self, #[a1] #[a2] a : i32, #[what = "how"] b : + i32, #[angery(true)] c : u32) { } +}"#); + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs new file mode 100644 index 000000000000..497e1dfe82a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs @@ -0,0 +1,22 @@ +// aux-build:param-attrs.rs + +// check-pass + +extern crate param_attrs; + +use param_attrs::rename_params; + +#[rename_params(send_help)] +impl Foo { + fn hello(#[angery(true)] a: i32, #[a2] b: i32, #[what = "how"] c: u32) {} + fn hello2(#[a1] #[a2] a: i32, #[what = "how"] b: i32, #[angery(true)] c: u32) {} + fn hello_self( + #[a1] #[a2] &self, + #[a1] #[a2] a: i32, + #[what = "how"] b: i32, + #[angery(true)] c: u32 + ) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-2018.rs b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-2018.rs new file mode 100644 index 000000000000..1ba087930fa5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-2018.rs @@ -0,0 +1,7 @@ +// edition:2018 + +trait Trait2015 { fn foo(#[allow(C)] i32); } +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-allowed.rs b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-allowed.rs new file mode 100644 index 000000000000..1fdc2ab262a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-allowed.rs @@ -0,0 +1,102 @@ +// check-pass +// compile-flags: --cfg something + +#![deny(unused_mut)] + +extern "C" { + fn ffi( + #[allow(unused_mut)] a: i32, + #[cfg(something)] b: i32, + #[cfg_attr(something, cfg(nothing))] c: i32, + #[deny(unused_mut)] d: i32, + #[forbid(unused_mut)] #[warn(unused_mut)] ... + ); +} + +type FnType = fn( + #[allow(unused_mut)] a: i32, + #[cfg(something)] b: i32, + #[cfg_attr(something, cfg(nothing))] c: i32, + #[deny(unused_mut)] d: i32, + #[forbid(unused_mut)] #[warn(unused_mut)] e: i32 +); + +pub fn foo( + #[allow(unused_mut)] a: i32, + #[cfg(something)] b: i32, + #[cfg_attr(something, cfg(nothing))] c: i32, + #[deny(unused_mut)] d: i32, + #[forbid(unused_mut)] #[warn(unused_mut)] _e: i32 +) {} + +// self + +struct SelfStruct {} +impl SelfStruct { + fn foo( + #[allow(unused_mut)] self, + #[cfg(something)] a: i32, + #[cfg_attr(something, cfg(nothing))] + #[deny(unused_mut)] b: i32, + ) {} +} + +struct RefStruct {} +impl RefStruct { + fn foo( + #[allow(unused_mut)] &self, + #[cfg(something)] a: i32, + #[cfg_attr(something, cfg(nothing))] + #[deny(unused_mut)] b: i32, + ) {} +} +trait RefTrait { + fn foo( + #[forbid(unused_mut)] &self, + #[warn(unused_mut)] a: i32 + ) {} +} +impl RefTrait for RefStruct { + fn foo( + #[forbid(unused_mut)] &self, + #[warn(unused_mut)] a: i32 + ) {} +} + +// Box + +struct BoxSelfStruct {} +impl BoxSelfStruct { + fn foo( + #[allow(unused_mut)] self: Box, + #[cfg(something)] a: i32, + #[cfg_attr(something, cfg(nothing))] + #[deny(unused_mut)] b: i32, + ) {} +} +trait BoxSelfTrait { + fn foo( + #[forbid(unused_mut)] self: Box, + #[warn(unused_mut)] a: i32 + ) {} +} +impl BoxSelfTrait for BoxSelfStruct { + fn foo( + #[forbid(unused_mut)] self: Box, + #[warn(unused_mut)] a: i32 + ) {} +} + +fn main() { + let _: unsafe extern "C" fn(_, _, _, ...) = ffi; + let _: fn(_, _, _, _) = foo; + let _: FnType = |_, _, _, _| {}; + let c = | + #[allow(unused_mut)] a: u32, + #[cfg(something)] b: i32, + #[cfg_attr(something, cfg(nothing))] + #[deny(unused_mut)] c: i32, + | {}; + let _ = c(1, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs new file mode 100644 index 000000000000..48f93fecd356 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs @@ -0,0 +1,175 @@ +extern "C" { + fn ffi( + /// Foo +// { dg-error "" "" { target *-*-* } .-1 } + #[test] a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + /// Bar +// { dg-error "" "" { target *-*-* } .-1 } + #[must_use] +// { dg-error "" "" { target *-*-* } .-1 } + /// Baz +// { dg-error "" "" { target *-*-* } .-1 } + #[no_mangle] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ); +} + +type FnType = fn( + /// Foo +// { dg-error "" "" { target *-*-* } .-1 } + #[test] a: u32, +// { dg-error "" "" { target *-*-* } .-1 } + /// Bar +// { dg-error "" "" { target *-*-* } .-1 } + #[must_use] +// { dg-error "" "" { target *-*-* } .-1 } + /// Baz +// { dg-error "" "" { target *-*-* } .-1 } + #[no_mangle] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } +); + +pub fn foo( + /// Foo +// { dg-error "" "" { target *-*-* } .-1 } + #[test] a: u32, +// { dg-error "" "" { target *-*-* } .-1 } + /// Bar +// { dg-error "" "" { target *-*-* } .-1 } + #[must_use] +// { dg-error "" "" { target *-*-* } .-1 } + /// Baz +// { dg-error "" "" { target *-*-* } .-1 } + #[no_mangle] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } +) {} + +struct SelfStruct {} +impl SelfStruct { + fn foo( + /// Foo +// { dg-error "" "" { target *-*-* } .-1 } + self, + /// Bar +// { dg-error "" "" { target *-*-* } .-1 } + #[test] a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + /// Baz +// { dg-error "" "" { target *-*-* } .-1 } + #[must_use] +// { dg-error "" "" { target *-*-* } .-1 } + /// Qux +// { dg-error "" "" { target *-*-* } .-1 } + #[no_mangle] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ) {} + + fn issue_64682_associated_fn( + /// Foo +// { dg-error "" "" { target *-*-* } .-1 } + #[test] a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + /// Baz +// { dg-error "" "" { target *-*-* } .-1 } + #[must_use] +// { dg-error "" "" { target *-*-* } .-1 } + /// Qux +// { dg-error "" "" { target *-*-* } .-1 } + #[no_mangle] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ) {} +} + +struct RefStruct {} +impl RefStruct { + fn foo( + /// Foo +// { dg-error "" "" { target *-*-* } .-1 } + &self, + /// Bar +// { dg-error "" "" { target *-*-* } .-1 } + #[test] a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + /// Baz +// { dg-error "" "" { target *-*-* } .-1 } + #[must_use] +// { dg-error "" "" { target *-*-* } .-1 } + /// Qux +// { dg-error "" "" { target *-*-* } .-1 } + #[no_mangle] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ) {} +} +trait RefTrait { + fn foo( + /// Foo +// { dg-error "" "" { target *-*-* } .-1 } + &self, + /// Bar +// { dg-error "" "" { target *-*-* } .-1 } + #[test] a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + /// Baz +// { dg-error "" "" { target *-*-* } .-1 } + #[must_use] +// { dg-error "" "" { target *-*-* } .-1 } + /// Qux +// { dg-error "" "" { target *-*-* } .-1 } + #[no_mangle] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ) {} + + fn issue_64682_associated_fn( + /// Foo +// { dg-error "" "" { target *-*-* } .-1 } + #[test] a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + /// Baz +// { dg-error "" "" { target *-*-* } .-1 } + #[must_use] +// { dg-error "" "" { target *-*-* } .-1 } + /// Qux +// { dg-error "" "" { target *-*-* } .-1 } + #[no_mangle] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ) {} +} + +impl RefTrait for RefStruct { + fn foo( + /// Foo +// { dg-error "" "" { target *-*-* } .-1 } + &self, + /// Bar +// { dg-error "" "" { target *-*-* } .-1 } + #[test] a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + /// Baz +// { dg-error "" "" { target *-*-* } .-1 } + #[must_use] +// { dg-error "" "" { target *-*-* } .-1 } + /// Qux +// { dg-error "" "" { target *-*-* } .-1 } + #[no_mangle] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + ) {} +} + +fn main() { + let _ = | + /// Foo +// { dg-error "" "" { target *-*-* } .-1 } + #[test] a: u32, +// { dg-error "" "" { target *-*-* } .-1 } + /// Bar +// { dg-error "" "" { target *-*-* } .-1 } + #[must_use] +// { dg-error "" "" { target *-*-* } .-1 } + /// Baz +// { dg-error "" "" { target *-*-* } .-1 } + #[no_mangle] b: i32 +// { dg-error "" "" { target *-*-* } .-1 } + | {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-cfg.rs b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-cfg.rs new file mode 100644 index 000000000000..0e6c74c42744 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-cfg.rs @@ -0,0 +1,122 @@ +// compile-flags: --cfg something +// edition:2018 + +#![feature(async_closure)] +#![deny(unused_variables)] + +extern "C" { + fn ffi( + #[cfg(nothing)] a: i32, + #[cfg(something)] b: i32, + #[cfg_attr(something, cfg(nothing))] c: i32, + #[cfg_attr(nothing, cfg(nothing))] ... + ); +} + +type FnType = fn( + #[cfg(nothing)] a: i32, + #[cfg(something)] b: i32, + #[cfg_attr(nothing, cfg(nothing))] c: i32, + #[cfg_attr(something, cfg(nothing))] d: i32, +); + +async fn foo_async( + #[cfg(something)] a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg(nothing)] b: i32, +) {} +fn foo( + #[cfg(nothing)] a: i32, + #[cfg(something)] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(nothing, cfg(nothing))] c: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(something, cfg(nothing))] d: i32, +) {} + +struct RefStruct {} +impl RefStruct { + async fn bar_async( + &self, + #[cfg(something)] a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg(nothing)] b: i32, + ) {} + fn bar( + &self, + #[cfg(nothing)] a: i32, + #[cfg(something)] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(nothing, cfg(nothing))] c: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(something, cfg(nothing))] d: i32, + ) {} + fn issue_64682_associated_fn( + #[cfg(nothing)] a: i32, + #[cfg(something)] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(nothing, cfg(nothing))] c: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(something, cfg(nothing))] d: i32, + ) {} +} +trait RefTrait { + fn bar( + &self, + #[cfg(nothing)] a: i32, + #[cfg(something)] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(nothing, cfg(nothing))] c: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(something, cfg(nothing))] d: i32, + ) {} + fn issue_64682_associated_fn( + #[cfg(nothing)] a: i32, + #[cfg(something)] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(nothing, cfg(nothing))] c: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(something, cfg(nothing))] d: i32, + ) {} +} +impl RefTrait for RefStruct { + fn bar( + &self, + #[cfg(nothing)] a: i32, + #[cfg(something)] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(nothing, cfg(nothing))] c: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(something, cfg(nothing))] d: i32, + ) {} + fn issue_64682_associated_fn( + #[cfg(nothing)] a: i32, + #[cfg(something)] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(nothing, cfg(nothing))] c: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(something, cfg(nothing))] d: i32, + ) {} +} + +fn main() { + let _: unsafe extern "C" fn(_, ...) = ffi; + let _: fn(_, _) = foo; + let _: FnType = |_, _| {}; + let a = async move | + #[cfg(something)] a: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg(nothing)] b: i32, + | {}; + let c = | + #[cfg(nothing)] a: i32, + #[cfg(something)] b: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(nothing, cfg(nothing))] c: i32, +// { dg-error "" "" { target *-*-* } .-1 } + #[cfg_attr(something, cfg(nothing))] d: i32, + | {}; + let _ = a(1); + let _ = c(1, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-pretty.rs b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-pretty.rs new file mode 100644 index 000000000000..d3cc68b89daf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/param-attrs-pretty.rs @@ -0,0 +1,62 @@ +// aux-build:param-attrs.rs + +// check-pass + +#![feature(c_variadic)] + +extern crate param_attrs; + +use param_attrs::*; + +struct W(u8); + +#[attr_extern] +extern "C" { fn ffi(#[a1] arg1: i32, #[a2] ...); } + +#[attr_extern_cvar] +unsafe extern "C" fn cvar(arg1: i32, #[a1] mut args: ...) {} + +#[attr_alias] +type Alias = fn(#[a1] u8, #[a2] ...); + +#[attr_free] +fn free(#[a1] arg1: u8) { + let lam = |#[a2] W(x), #[a3] y| (); +} + +impl W { + #[attr_inherent_1] + fn inherent1(#[a1] self, #[a2] arg1: u8) {} + + #[attr_inherent_2] + fn inherent2(#[a1] &self, #[a2] arg1: u8) {} + + #[attr_inherent_3] + fn inherent3<'a>(#[a1] &'a mut self, #[a2] arg1: u8) {} + + #[attr_inherent_4] + fn inherent4<'a>(#[a1] self: Box, #[a2] arg1: u8) {} + + #[attr_inherent_issue_64682] + fn inherent5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8) {} +} + +trait A { + #[attr_trait_1] + fn trait1(#[a1] self, #[a2] arg1: u8); + + #[attr_trait_2] + fn trait2(#[a1] &self, #[a2] arg1: u8); + + #[attr_trait_3] + fn trait3<'a>(#[a1] &'a mut self, #[a2] arg1: u8); + + #[attr_trait_4] + fn trait4<'a>(#[a1] self: Box, #[a2] arg1: u8, #[a3] Vec); + + #[attr_trait_issue_64682] + fn trait5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs new file mode 100644 index 000000000000..15a2ba800307 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs @@ -0,0 +1,66 @@ +// aux-build:ident-mac.rs + +#![feature(c_variadic)] + +extern crate ident_mac; +use ident_mac::id; + +struct W(u8); + +extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {} +// { dg-error "" "" { target *-*-* } .-1 } + +type Alias = extern "C" fn(#[id] u8, #[id] ...); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn free(#[id] arg1: u8) { +// { dg-error "" "" { target *-*-* } .-1 } + let lam = |#[id] W(x), #[id] y: usize| (); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +impl W { + fn inherent1(#[id] self, #[id] arg1: u8) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn inherent2(#[id] &self, #[id] arg1: u8) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn inherent4<'a>(#[id] self: Box, #[id] arg1: u8) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +trait A { + fn trait1(#[id] self, #[id] arg1: u8); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn trait2(#[id] &self, #[id] arg1: u8); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn trait4<'a>(#[id] self: Box, #[id] arg1: u8, #[id] Vec); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib-2.rs b/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib-2.rs new file mode 100644 index 000000000000..794b5041e193 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib-2.rs @@ -0,0 +1,9 @@ +#[link(name="foo")] +extern { + #[link_ordinal(42)] +// { dg-error ".E0658." "" { target *-*-* } .-1 } + fn foo(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib.rs b/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib.rs new file mode 100644 index 000000000000..01c0a37b2a8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/feature-gate-raw-dylib.rs @@ -0,0 +1,6 @@ +#[link(name="foo", kind="raw-dylib")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +extern {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs b/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs new file mode 100644 index 000000000000..123dd3a97c35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-and-name.rs @@ -0,0 +1,13 @@ +#![feature(raw_dylib)] +// { dg-warning "" "" { target *-*-* } .-1 } + +#[link(name="foo")] +extern { + #[link_name="foo"] + #[link_ordinal(42)] +// { dg-error "" "" { target *-*-* } .-1 } + fn foo(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs b/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs new file mode 100644 index 000000000000..605684c6dbf2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs @@ -0,0 +1,12 @@ +#![feature(raw_dylib)] +// { dg-warning "" "" { target *-*-* } .-1 } + +#[link(name="foo")] +extern { + #[link_ordinal("JustMonika")] +// { dg-error "" "" { target *-*-* } .-1 } + fn foo(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs b/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs new file mode 100644 index 000000000000..b3de58915e9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2627-raw-dylib/link-ordinal-too-large.rs @@ -0,0 +1,12 @@ +#![feature(raw_dylib)] +// { dg-warning "" "" { target *-*-* } .-1 } + +#[link(name="foo")] +extern { + #[link_ordinal(18446744073709551616)] +// { dg-error "" "" { target *-*-* } .-1 } + fn foo(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/assoc-type.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/assoc-type.rs new file mode 100644 index 000000000000..59ae66ae6007 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/assoc-type.rs @@ -0,0 +1,29 @@ +// ignore-test + +// FIXME: This test should fail since, within a const impl of `Foo`, the bound on `Foo::Bar` should +// require a const impl of `Add` for the associated type. + +#![allow(incomplete_features)] +#![feature(const_trait_impl)] +#![feature(const_fn)] + +struct NonConstAdd(i32); + +impl std::ops::Add for NonConstAdd { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + NonConstAdd(self.0 + rhs.0) + } +} + +trait Foo { + type Bar: std::ops::Add; +} + +impl const Foo for NonConstAdd { + type Bar = NonConstAdd; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs new file mode 100644 index 000000000000..b984698a8b3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs @@ -0,0 +1,31 @@ +#![allow(incomplete_features)] +#![feature(const_trait_impl)] +#![feature(const_fn)] + +pub trait Plus { + fn plus(self, rhs: Self) -> Self; +} + +impl const Plus for i32 { + fn plus(self, rhs: Self) -> Self { + self + rhs + } +} + +impl Plus for u32 { + fn plus(self, rhs: Self) -> Self { + self + rhs + } +} + +pub const fn add_i32(a: i32, b: i32) -> i32 { + a.plus(b) // ok +} + +pub const fn add_u32(a: u32, b: u32) -> u32 { + a.plus(b) +// { dg-error ".E0015." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs new file mode 100644 index 000000000000..ef39b1655ac2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs @@ -0,0 +1,42 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(const_trait_impl)] +#![feature(const_fn)] + +struct Int(i32); + +impl const std::ops::Add for Int { + type Output = Int; + + fn add(self, rhs: Self) -> Self { + Int(self.0.plus(rhs.0)) + } +} + +impl const PartialEq for Int { + fn eq(&self, rhs: &Self) -> bool { + self.0 == rhs.0 + } +} + +pub trait Plus { + fn plus(self, rhs: Self) -> Self; +} + +impl const Plus for i32 { + fn plus(self, rhs: Self) -> Self { + self + rhs + } +} + +pub const fn add_i32(a: i32, b: i32) -> i32 { + a.plus(b) +} + +const ADD_INT: Int = Int(1i32) + Int(2i32); + +fn main() { + assert!(ADD_INT == Int(3i32)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs new file mode 100644 index 000000000000..417f6dfb1294 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs @@ -0,0 +1,34 @@ +#![allow(incomplete_features)] +#![feature(const_trait_impl)] + +pub struct Int(i32); + +impl const std::ops::Add for i32 { +// { dg-error ".E0117." "" { target *-*-* } .-1 } +// { dg-error ".E0117." "" { target *-*-* } .-2 } + type Output = Self; + + fn add(self, rhs: Self) -> Self { + self + rhs + } +} + +impl std::ops::Add for Int { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + Int(self.0 + rhs.0) + } +} + +impl const std::ops::Add for Int { +// { dg-error ".E0119." "" { target *-*-* } .-1 } + type Output = Self; + + fn add(self, rhs: Self) -> Self { + Int(self.0 + rhs.0) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs new file mode 100644 index 000000000000..1839509c21e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs @@ -0,0 +1,17 @@ +#![allow(incomplete_features)] +#![feature(const_trait_impl)] + +struct S; +trait T { + fn foo(); +} + +fn non_const() {} + +impl const T for S { + fn foo() { non_const() } +// { dg-error ".E0015." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs new file mode 100644 index 000000000000..1284fd2af897 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/feature-gate.rs @@ -0,0 +1,18 @@ +// revisions: stock gated +// gate-test-const_trait_bound_opt_out + +#![cfg_attr(gated, feature(const_trait_bound_opt_out))] +#![allow(incomplete_features)] +#![feature(rustc_attrs)] +#![feature(const_fn)] + +trait T { + const CONST: i32; +} + +const fn get_assoc_const() -> i32 { ::CONST } +// { dg-error "" "" { target *-*-* } .-1 } + +#[rustc_error] +fn main() {} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs new file mode 100644 index 000000000000..a57036f3f2f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-impl-trait.rs @@ -0,0 +1,22 @@ +#![feature(const_trait_bound_opt_out)] +#![feature(associated_type_bounds)] +#![allow(incomplete_features)] + +trait T {} +struct S; +impl T for S {} + +fn rpit() -> impl ?const T { S } +// { dg-error "" "" { target *-*-* } .-1 } + +fn apit(_: impl ?const T) {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn rpit_assoc_bound() -> impl IntoIterator { Some(S) } +// { dg-error "" "" { target *-*-* } .-1 } + +fn apit_assoc_bound(_: impl IntoIterator) {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs new file mode 100644 index 000000000000..45ac0b1640b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-bounds.rs @@ -0,0 +1,9 @@ +#![feature(const_trait_bound_opt_out)] +#![allow(incomplete_features)] + +trait Super {} +trait T: ?const Super {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs new file mode 100644 index 000000000000..0c1b0745ec83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/in-trait-object.rs @@ -0,0 +1,20 @@ +#![feature(const_trait_bound_opt_out)] +#![allow(bare_trait_objects)] +#![allow(incomplete_features)] + +struct S; +trait T {} +impl T for S {} + +// An inherent impl for the trait object `?const T`. +impl ?const T {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn trait_object() -> &'static dyn ?const T { &S } +// { dg-error "" "" { target *-*-* } .-1 } + +fn trait_object_in_apit(_: impl IntoIterator>) {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.rs new file mode 100644 index 000000000000..b4d3f76a2f76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/opt-out-twice.rs @@ -0,0 +1,9 @@ +// compile-flags: -Z parse-only + +#![feature(const_trait_bound_opt_out)] +#![allow(incomplete_features)] + +struct S; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/syntax.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/syntax.rs new file mode 100644 index 000000000000..b326bfbc0305 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/syntax.rs @@ -0,0 +1,11 @@ +// compile-flags: -Z parse-only +// check-pass + +#![feature(const_trait_bound_opt_out)] +#![allow(incomplete_features)] + +struct S< + T: ?const ?for<'a> Tr<'a> + 'static + ?const std::ops::Add, + T: ?const ?for<'a: 'b> m::Trait<'a>, +>; + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs new file mode 100644 index 000000000000..d19b113c5baf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/with-maybe-sized.rs @@ -0,0 +1,8 @@ +#![feature(const_trait_bound_opt_out)] +#![allow(incomplete_features)] + +struct S(std::marker::PhantomData); +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.rs new file mode 100644 index 000000000000..9e07aa80ff40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/const-trait-bound-opt-out/without-question-mark.rs @@ -0,0 +1,8 @@ +// compile-flags: -Z parse-only + +#![feature(const_trait_bound_opt_out)] +#![allow(incomplete_features)] + +struct S; +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/feature-gate.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/feature-gate.rs new file mode 100644 index 000000000000..fcf10a431f34 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/feature-gate.rs @@ -0,0 +1,15 @@ +// revisions: stock gated +// gate-test-const_trait_impl + +#![cfg_attr(gated, feature(const_trait_impl))] +#![allow(incomplete_features)] +#![feature(rustc_attrs)] + +struct S; +trait T {} +impl const T for S {} +// { dg-error "" "" { target *-*-* } .-1 } + +#[rustc_error] +fn main() {} // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/generic-bound.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/generic-bound.rs new file mode 100644 index 000000000000..e31a4b65a866 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/generic-bound.rs @@ -0,0 +1,33 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(const_trait_impl)] +#![feature(const_fn)] + +use std::marker::PhantomData; + +struct S(PhantomData); + +impl Copy for S {} +impl Clone for S { + fn clone(&self) -> Self { + S(PhantomData) + } +} + +impl const std::ops::Add for S { + type Output = Self; + + fn add(self, _: Self) -> Self { + S(std::marker::PhantomData) + } +} + +const fn twice(arg: S) -> S { + arg + arg +} + +fn main() { + let _ = twice(S(PhantomData::)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/hir-const-check.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/hir-const-check.rs new file mode 100644 index 000000000000..d04460335fd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/hir-const-check.rs @@ -0,0 +1,18 @@ +// Regression test for #69615. + +#![feature(const_trait_impl, const_fn)] +#![allow(incomplete_features)] + +pub trait MyTrait { + fn method(&self) -> Option<()>; +} + +impl const MyTrait for () { + fn method(&self) -> Option<()> { + Some(())?; // { dg-error ".E0744." "" { target *-*-* } } + None + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.rs new file mode 100644 index 000000000000..1d3054830b90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/impl-opt-out-trait.rs @@ -0,0 +1,12 @@ +#![feature(const_trait_bound_opt_out)] +#![feature(const_trait_impl)] +#![allow(incomplete_features)] + +struct S; +trait T {} + +impl ?const T for S {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/inherent-impl.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/inherent-impl.rs new file mode 100644 index 000000000000..179e2156afe0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/inherent-impl.rs @@ -0,0 +1,16 @@ +#![feature(const_trait_impl)] +#![feature(const_trait_bound_opt_out)] +#![allow(incomplete_features)] +#![allow(bare_trait_objects)] + +struct S; +trait T {} + +impl const S {} +// { dg-error "" "" { target *-*-* } .-1 } + +impl const T {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/stability.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/stability.rs new file mode 100644 index 000000000000..8258108177d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/stability.rs @@ -0,0 +1,44 @@ +#![allow(incomplete_features)] +#![feature(allow_internal_unstable)] +#![feature(const_add)] +#![feature(const_trait_impl)] +#![feature(staged_api)] + +pub struct Int(i32); + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +impl const std::ops::Sub for Int { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { +// { dg-error ".E0723." "" { target *-*-* } .-1 } + Int(self.0 - rhs.0) + } +} + +#[rustc_const_unstable(feature = "const_add", issue = "none")] +impl const std::ops::Add for Int { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + Int(self.0 + rhs.0) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_stable(feature = "rust1", since = "1.0.0")] +pub const fn foo() -> Int { + Int(1i32) + Int(2i32) +// { dg-error "" "" { target *-*-* } .-1 } +} + +// ok +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature = "bar", issue = "none")] +pub const fn bar() -> Int { + Int(1i32) + Int(2i32) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/syntax.rs b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/syntax.rs new file mode 100644 index 000000000000..c280c2dbcd33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc-2632-const-trait-impl/syntax.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z parse-only +// check-pass + +#![feature(const_trait_bound_opt_out)] +#![feature(const_trait_impl)] +#![allow(incomplete_features)] + +// For now, this parses since an error does not occur until AST lowering. +impl ?const T {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc1623-2.rs b/gcc/testsuite/rust/rustc/ui/rfc1623-2.rs new file mode 100644 index 000000000000..5b9120759f7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc1623-2.rs @@ -0,0 +1,14 @@ +#![allow(dead_code)] + +fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { + a +} + +// the boundaries of elision +static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = +// { dg-error ".E0106." "" { target *-*-* } .-1 } + &(non_elidable as fn(&u8, &u8) -> &u8); +// { dg-error ".E0106." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfc1623.rs b/gcc/testsuite/rust/rustc/ui/rfc1623.rs new file mode 100644 index 000000000000..9a306047b8ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfc1623.rs @@ -0,0 +1,93 @@ +#![allow(dead_code)] + +fn non_elidable<'a, 'b>(a: &'a u8, b: &'b u8) -> &'a u8 { + a +} + +// The incorrect case without `for<'a>` is tested for in `rfc1623-2.rs` +static NON_ELIDABLE_FN: &for<'a> fn(&'a u8, &'a u8) -> &'a u8 = + &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8); + +struct SomeStruct<'x, 'y, 'z: 'x> { + foo: &'x Foo<'z>, + bar: &'x Bar<'z>, + f: &'y dyn for<'a, 'b> Fn(&'a Foo<'b>) -> &'a Foo<'b>, +} + +fn id(t: T) -> T { + t +} + +static SOME_STRUCT: &SomeStruct = &SomeStruct { + foo: &Foo { bools: &[false, true] }, + bar: &Bar { bools: &[true, true] }, + f: &id, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +}; + +// very simple test for a 'static static with default lifetime +static STATIC_STR: &'static str = "&'static str"; +const CONST_STR: &'static str = "&'static str"; + +// this should be the same as without default: +static EXPLICIT_STATIC_STR: &'static str = "&'static str"; +const EXPLICIT_CONST_STR: &'static str = "&'static str"; + +// a function that elides to an unbound lifetime for both in- and output +fn id_u8_slice(arg: &[u8]) -> &[u8] { + arg +} + +// one with a function, argument elided +static STATIC_SIMPLE_FN: &'static fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); +const CONST_SIMPLE_FN: &'static fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); + +// this should be the same as without elision +static STATIC_NON_ELIDED_fN: &'static for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); +const CONST_NON_ELIDED_fN: &'static for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); + +// another function that elides, each to a different unbound lifetime +fn multi_args(a: &u8, b: &u8, c: &u8) {} + +static STATIC_MULTI_FN: &'static fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); +const CONST_MULTI_FN: &'static fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); + +struct Foo<'a> { + bools: &'a [bool], +} + +static STATIC_FOO: Foo<'static> = Foo { bools: &[true, false] }; +const CONST_FOO: Foo<'static> = Foo { bools: &[true, false] }; + +type Bar<'a> = Foo<'a>; + +static STATIC_BAR: Bar<'static> = Bar { bools: &[true, false] }; +const CONST_BAR: Bar<'static> = Bar { bools: &[true, false] }; + +type Baz<'a> = fn(&'a [u8]) -> Option; + +fn baz(e: &[u8]) -> Option { + e.first().map(|x| *x) +} + +static STATIC_BAZ: &'static Baz<'static> = &(baz as Baz); +const CONST_BAZ: &'static Baz<'static> = &(baz as Baz); + +static BYTES: &'static [u8] = &[1, 2, 3]; + +fn main() { + let x = &[1u8, 2, 3]; + let y = x; + + // this works, so lifetime < `'static` is valid + assert_eq!(Some(1), STATIC_BAZ(y)); + assert_eq!(Some(1), CONST_BAZ(y)); + + let y = &[1u8, 2, 3]; + + STATIC_BAZ(BYTES); // BYTES has static lifetime + CONST_BAZ(y); // interestingly this does not get reported +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1014-2.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1014-2.rs new file mode 100644 index 000000000000..c3b0633c729c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1014-2.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(dead_code)] + +#![feature(rustc_private)] + +extern crate libc; + +type DWORD = u32; +type HANDLE = *mut u8; +type BOOL = i32; + +#[cfg(windows)] +extern "system" { + fn SetStdHandle(nStdHandle: DWORD, nHandle: HANDLE) -> BOOL; +} + +#[cfg(windows)] +fn close_stdout() { + const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; + unsafe { SetStdHandle(STD_OUTPUT_HANDLE, 0 as HANDLE); } +} + +#[cfg(windows)] +fn main() { + close_stdout(); + println!("hello"); + println!("world"); +} + +#[cfg(not(windows))] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1014.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1014.rs new file mode 100644 index 000000000000..b5b7470e0b3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1014.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(dead_code)] +// ignore-cloudabi stdout does not map to file descriptor 1 by default +// ignore-wasm32-bare no libc +// ignore-sgx no libc + +#![feature(rustc_private)] + +extern crate libc; + +type DWORD = u32; +type HANDLE = *mut u8; + +#[cfg(windows)] +extern "system" { + fn GetStdHandle(which: DWORD) -> HANDLE; + fn CloseHandle(handle: HANDLE) -> i32; +} + +#[cfg(windows)] +fn close_stdout() { + const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; + unsafe { CloseHandle(GetStdHandle(STD_OUTPUT_HANDLE)); } +} + +#[cfg(not(windows))] +fn close_stdout() { + unsafe { libc::close(1); } +} + +fn main() { + close_stdout(); + println!("hello"); + println!("world"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1789-as-cell/from-mut.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1789-as-cell/from-mut.rs new file mode 100644 index 000000000000..770d7f996b53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1789-as-cell/from-mut.rs @@ -0,0 +1,12 @@ +// run-pass + +use std::cell::Cell; + +fn main() { + let slice: &mut [i32] = &mut [1, 2, 3]; + let cell_slice: &Cell<[i32]> = Cell::from_mut(slice); + let slice_cell: &[Cell] = cell_slice.as_slice_of_cells(); + + assert_eq!(slice_cell.len(), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs new file mode 100644 index 000000000000..0add835e562e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs @@ -0,0 +1,7 @@ +// run-pass +use std::error::Error; + +fn main() -> Result<(), Box> { + Ok(()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs new file mode 100644 index 000000000000..7b6b47076349 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-empty.rs @@ -0,0 +1,3 @@ +// run-pass +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs new file mode 100644 index 000000000000..920419e278b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-exitcode.rs @@ -0,0 +1,9 @@ +// run-pass +#![feature(process_exitcode_placeholder)] + +use std::process::ExitCode; + +fn main() -> ExitCode { + ExitCode::SUCCESS +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs new file mode 100644 index 000000000000..a449b0a4c16a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-impl-termination.rs @@ -0,0 +1,5 @@ +// run-pass +#![feature(termination_trait_lib)] + +fn main() -> impl std::process::Termination { } + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs new file mode 100644 index 000000000000..8939d72e582e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs @@ -0,0 +1,7 @@ +// run-pass +use std::io::Error; + +fn main() -> Result<(), Box> { + Ok(()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs new file mode 100644 index 000000000000..6a0da69df432 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-result.rs @@ -0,0 +1,7 @@ +// run-pass +use std::io::Error; + +fn main() -> Result<(), Error> { + Ok(()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs new file mode 100644 index 000000000000..a3409a8f466e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-1937-termination-trait/termination-trait-for-str.rs @@ -0,0 +1,5 @@ +// run-pass +fn main() -> Result<(), &'static str> { + Ok(()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/box.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/box.rs new file mode 100644 index 000000000000..015bcc84dcb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/box.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unreachable_patterns)] +#![feature(box_syntax, box_patterns)] + +struct Foo{} + +pub fn main() { + let b = box Foo{}; + let box f = &b; + let _: &Foo = f; + + match &&&b { + box f => { + let _: &Foo = f; + }, + _ => panic!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/constref.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/constref.rs new file mode 100644 index 000000000000..63232d60debc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/constref.rs @@ -0,0 +1,41 @@ +// run-pass +const CONST_REF: &[u8; 3] = b"foo"; + +trait Foo { + const CONST_REF_DEFAULT: &'static [u8; 3] = b"bar"; + const CONST_REF: &'static [u8; 3]; +} + +impl Foo for i32 { + const CONST_REF: &'static [u8; 3] = b"jjj"; +} + +impl Foo for i64 { + const CONST_REF_DEFAULT: &'static [u8; 3] = b"ggg"; + const CONST_REF: &'static [u8; 3] = b"fff"; +} + +// Check that (associated and free) const references are not mistaken for a +// non-reference pattern (in which case they would be auto-dereferenced, making +// the types mismatched). + +fn const_ref() -> bool { + let f = b"foo"; + match f { + CONST_REF => true, + _ => false, + } +} + +fn associated_const_ref() -> bool { + match (b"bar", b"jjj", b"ggg", b"fff") { + (i32::CONST_REF_DEFAULT, i32::CONST_REF, i64::CONST_REF_DEFAULT, i64::CONST_REF) => true, + _ => false, + } +} + +pub fn main() { + assert!(const_ref()); + assert!(associated_const_ref()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/enum.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/enum.rs new file mode 100644 index 000000000000..9389baa12c16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/enum.rs @@ -0,0 +1,46 @@ +// run-pass +enum Wrapper { + Wrap(i32), +} + +use Wrapper::Wrap; + +pub fn main() { + let Wrap(x) = &Wrap(3); + println!("{}", *x); + + let Wrap(x) = &mut Wrap(3); + println!("{}", *x); + + if let Some(x) = &Some(3) { + println!("{}", *x); + } else { + panic!(); + } + + if let Some(x) = &mut Some(3) { + println!("{}", *x); + } else { + panic!(); + } + + if let Some(x) = &mut Some(3) { + *x += 1; + } else { + panic!(); + } + + while let Some(x) = &Some(3) { + println!("{}", *x); + break; + } + while let Some(x) = &mut Some(3) { + println!("{}", *x); + break; + } + while let Some(x) = &mut Some(3) { + *x += 1; + break; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/for.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/for.rs new file mode 100644 index 000000000000..a7b12c9028ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/for.rs @@ -0,0 +1,21 @@ +// run-pass +pub fn main() { + let mut tups = vec![(0u8, 1u8)]; + + for (n, m) in &tups { + let _: &u8 = n; + let _: &u8 = m; + } + + for (n, m) in &mut tups { + *n += 1; + *m += 2; + } + + assert_eq!(tups, vec![(1u8, 3u8)]); + + for (n, m) in tups { + println!("{} {}", m, n); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/general.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/general.rs new file mode 100644 index 000000000000..7dd3efc3a844 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/general.rs @@ -0,0 +1,250 @@ +// run-pass +#![allow(unused_variables)] +fn some_or_wildcard(r: &Option, b: &i32) { + let _: &i32 = match r { + Some(a) => a, + _ => b, + }; +} + +fn none_or_wildcard(r: &Option, b: &i32) { + let _: &i32 = match r { + None => b, + _ => b, + }; +} + +fn some_or_ref_none(r: &Option, b: &i32) { + let _: &i32 = match r { + Some(a) => a, + &None => b, + }; +} + +fn ref_some_or_none(r: &Option, b: &i32) { + let _: &i32 = match r { + &Some(ref a) => a, + None => b, + }; +} + +fn some_or_self(r: &Option) { + let _: &Option = match r { + Some(n) => { + let _: &i32 = n; + r + }, + x => x, + }; +} + +fn multiple_deref(r: &&&&&Option) { + let _: i32 = match r { + Some(a) => *a, + None => 5, + }; +} + +fn match_with_or() { + // FIXME(tschottdorf): #44912. + // + // let x = &Some((3, 3)); + // let _: &i32 = match x { + // Some((x, 3)) | &Some((ref x, 5)) => x, + // _ => &5i32, + // }; +} + +fn nested_mixed() { + match (&Some(5), &Some(6)) { + (Some(a), &Some(mut b)) => { + // Here, the `a` will be `&i32`, because in the first half of the tuple + // we hit a non-reference pattern and shift into `ref` mode. + // + // In the second half of the tuple there's no non-reference pattern, + // so `b` will be `i32` (bound with `move` mode). Moreover, `b` is + // mutable. + let _: &i32 = a; + b = 7; + let _: i32 = b; + }, + _ => {}, + }; +} + +fn nested_mixed_multiple_deref_1() { + let x = (1, &Some(5)); + let y = &Some(x); + match y { + Some((a, Some(b))) => { + let _: &i32 = a; + let _: &i32 = b; + }, + _ => {}, + }; +} + +fn nested_mixed_multiple_deref_2() { + let x = &Some(5); + let y = &x; + match y { + Some(z) => { + let _: &i32 = z; + }, + _ => {}, + } +} + +fn new_mutable_reference() { + let mut x = &mut Some(5); + match &mut x { + Some(y) => { + *y = 5; + }, + None => { }, + } + + match &mut x { + Some(y) => { + println!("{}", *y); + }, + None => {}, + } +} + +fn let_implicit_ref_binding() { + struct Foo(i32); + + // Note that these rules apply to any pattern matching + // whether it be in a `match` or a `let`. + // For example, `x` here is a `ref` binding: + let Foo(x) = &Foo(3); + let _: &i32 = x; +} + +fn explicit_mut_binding() { + match &Some(5i32) { + Some(mut n) => { + n += 1; + let _ = n; + } + None => {}, + }; + + match &mut Some(5i32) { + Some(n) => { + *n += 1; + let _ = n; + } + None => {}, + }; + + match &mut &mut Some(5i32) { + Some(n) => { + let _: &mut i32 = n; + } + None => {}, + }; +} + +fn tuple_mut_and_mut_mut() { + match (Some(5i32), &Some(5i32)) { + (Some(n), Some(m)) => { + // `n` and `m` are bound as immutable references. Make new references from them to + // assert that. + let r = n; + let _ = r; + let q = m; + let _ = q; + + // Assert the types. Note that we use `n` and `m` here which would fail had they been + // moved due to the assignments above. + let _: i32 = n; + let _: &i32 = m; + } + (_, _) => {}, + }; + + match (&Some(5i32), &&Some(5i32)) { + (Some(n), Some(m)) => { + let _: &i32 = n; + let _: &i32 = m; + } + (_, _) => {}, + }; + + match &mut &mut (Some(5i32), Some(5i32)) { + (Some(n), Some(m)) => { + // Dereferenced through &mut &mut, so a mutable binding results. + let _: &mut i32 = n; + let _: &mut i32 = m; + } + (_, _) => {}, + }; + + match (&mut Some(5i32), &mut &mut Some(5i32)) { + (Some(n), Some(m)) => { + let _: &mut i32 = n; + let _: &mut i32 = m; + } + (_, _) => {}, + }; +} + +fn min_mir_embedded_type() { + // The reduced invocation that an ICE was diagnosed with (was consuming + // adjustments in wrong order). + match (0u8, &&Some(5i32)) { + (_, Some(m)) => { + let _: &i32 = m; + } + (_, _) => {}, + }; +} + +fn no_autoderef() { + // Binding. + let x = &3; + println!("{}", *x); + + // Wildcard. + let _ = &3; + + // Constant of generic type (string) + const Y: &'static str = "foo"; + assert_eq!(0, match "foo" { + Y => 0, + _ => 1, + }); + + // Reference pattern. + let &x = &3; +} + +pub fn main() { + let r: &Option = &Some(3); + let b = &4i32; + + none_or_wildcard(r, b); + some_or_wildcard(r, b); + some_or_ref_none(r, b); + ref_some_or_none(r, b); + + some_or_self(r); + multiple_deref(&&&&r); + match_with_or(); + + nested_mixed(); + nested_mixed_multiple_deref_1(); + nested_mixed_multiple_deref_2(); + + new_mutable_reference(); + explicit_mut_binding(); + tuple_mut_and_mut_mut(); + min_mir_embedded_type(); + + let_implicit_ref_binding(); + + no_autoderef(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/lit.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/lit.rs new file mode 100644 index 000000000000..03e8bce56ef0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/lit.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(dead_code)] +fn with_u8() { + let s = 5u8; + let r = match &s { + 4 => false, + 5 => true, + _ => false, + }; + assert!(r); +} + +// A string literal isn't mistaken for a non-ref pattern (in which case we'd +// deref `s` and mess things up). +fn with_str() { + let s: &'static str = "abc"; + match s { + "abc" => true, + _ => panic!(), + }; +} + +// Ditto with byte strings. +fn with_bytes() { + let s: &'static [u8] = b"abc"; + match s { + b"abc" => true, + _ => panic!(), + }; +} + +pub fn main() { + with_str(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/range.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/range.rs new file mode 100644 index 000000000000..3f933a7d059a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/range.rs @@ -0,0 +1,10 @@ +// run-pass +pub fn main() { + let i = 5; + match &&&&i { + 1 ..= 3 => panic!(), + 4 ..= 8 => {}, + _ => panic!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs new file mode 100644 index 000000000000..84b56759531d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/ref-region.rs @@ -0,0 +1,17 @@ +// run-pass +fn foo<'a, 'b>(x: &'a &'b Option) -> &'a u32 { + let x: &'a &'a Option = x; + match x { + Some(r) => { + let _: &u32 = r; + r + }, + &None => panic!(), + } +} + +pub fn main() { + let x = Some(5); + foo(&&x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs new file mode 100644 index 000000000000..88a92fc74a71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/reset-mode.rs @@ -0,0 +1,15 @@ +// run-pass +// Test that we "reset" the mode as we pass through a `&` pattern. +// +// cc #46688 + +fn surprise(x: i32) { + assert_eq!(x, 2); +} + +fn main() { + let x = &(1, &2); + let (_, &b) = x; + surprise(b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/slice.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/slice.rs new file mode 100644 index 000000000000..0e858fb0f9c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/slice.rs @@ -0,0 +1,26 @@ +// run-pass + +fn slice_pat() { + let sl: &[u8] = b"foo"; + + match sl { + [first, remainder @ ..] => { + let _: &u8 = first; + assert_eq!(first, &b'f'); + assert_eq!(remainder, b"oo"); + } + [] => panic!(), + } +} + +fn slice_pat_omission() { + match &[0, 1, 2] { + [..] => {} + }; +} + +fn main() { + slice_pat(); + slice_pat_omission(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/struct.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/struct.rs new file mode 100644 index 000000000000..f502114e715b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/struct.rs @@ -0,0 +1,23 @@ +// run-pass +#[derive(Debug, PartialEq)] +struct Foo { + x: u8, +} + +pub fn main() { + let mut foo = Foo { + x: 1, + }; + + match &mut foo { + Foo{x: n} => { + *n += 1; + }, + }; + + assert_eq!(foo, Foo{x: 2}); + + let Foo{x: n} = &foo; + assert_eq!(*n, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs new file mode 100644 index 000000000000..d611b9e0518e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/tuple-struct.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +enum Foo { + Bar(Option, (), (), Vec), + Baz, +} + +pub fn main() { + let foo = Foo::Bar(Some(1), (), (), vec![2, 3]); + + match &foo { + Foo::Baz => panic!(), + Foo::Bar(None, ..) => panic!(), + Foo::Bar(Some(n), .., v) => { + assert_eq!((*v).len(), 2); + assert_eq!(*n, 1); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs new file mode 100644 index 000000000000..1ef01785dcf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2005-default-binding-mode/tuple.rs @@ -0,0 +1,13 @@ +// run-pass +pub fn main() { + let foo = (Some(1), (), (), vec![2, 3]); + + match &foo { + (Some(n), .., v) => { + assert_eq!((*v).len(), 2); + assert_eq!(*n, 1); + } + (None, (), (), ..) => panic!(), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/attr.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/attr.rs new file mode 100644 index 000000000000..dd7aed960ada --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/attr.rs @@ -0,0 +1,16 @@ +// run-pass +use std::mem; + +#[r#repr(r#C, r#packed)] +struct Test { + a: bool, b: u64 +} + +#[r#derive(r#Debug)] +struct Test2(u32); + +pub fn main() { + assert_eq!(mem::size_of::(), 9); + assert_eq!("Test2(123)", format!("{:?}", Test2(123))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/basic.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/basic.rs new file mode 100644 index 000000000000..c9e686d2e120 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/basic.rs @@ -0,0 +1,21 @@ +// run-pass +fn r#fn(r#match: u32) -> u32 { + r#match +} + +pub fn main() { + let r#struct = 1; + assert_eq!(1, r#struct); + + let foo = 2; + assert_eq!(2, r#foo); + + let r#bar = 3; + assert_eq!(3, bar); + + assert_eq!(4, r#fn(4)); + + let r#true = false; + assert_eq!(r#true, false); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/items.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/items.rs new file mode 100644 index 000000000000..3341c2568340 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/items.rs @@ -0,0 +1,33 @@ +// run-pass +#[derive(Debug, PartialEq, Eq)] +struct IntWrapper(u32); + +#[derive(Debug, Ord, PartialOrd, PartialEq, Eq, Hash, Copy, Clone, Default)] +struct HasKeywordField { + r#struct: u32, +} + +struct Generic(T); + +trait Trait { + fn r#trait(&self) -> u32; +} +impl Trait for Generic { + fn r#trait(&self) -> u32 { + self.0 + } +} + +pub fn main() { + assert_eq!(IntWrapper(1), r#IntWrapper(1)); + + match IntWrapper(2) { + r#IntWrapper(r#struct) => assert_eq!(2, r#struct), + } + + assert_eq!("HasKeywordField { struct: 3 }", format!("{:?}", HasKeywordField { r#struct: 3 })); + + assert_eq!(4, Generic(4).0); + assert_eq!(5, Generic(5).r#trait()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/macros.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/macros.rs new file mode 100644 index 000000000000..e834ba12a949 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2151-raw-identifiers/macros.rs @@ -0,0 +1,39 @@ +// run-pass +#![feature(decl_macro)] + +macro_rules! r#struct { + ($r#struct:expr) => { $r#struct } +} + +macro_rules! old_macro { + ($a:expr) => {$a} +} + +macro r#decl_macro($r#fn:expr) { + $r#fn +} + +macro passthrough($id:ident) { + $id +} + +macro_rules! test_pat_match { + (a) => { 6 }; + (r#a) => { 7 }; +} + +pub fn main() { + r#println!("{struct}", r#struct = 1); + assert_eq!(2, r#struct!(2)); + assert_eq!(3, r#old_macro!(3)); + assert_eq!(4, decl_macro!(4)); + + let r#match = 5; + assert_eq!(5, passthrough!(r#match)); + + assert_eq!("r#struct", stringify!(r#struct)); + + assert_eq!(6, test_pat_match!(a)); + assert_eq!(7, test_pat_match!(r#a)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2175-or-if-while-let/basic.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2175-or-if-while-let/basic.rs new file mode 100644 index 000000000000..a197e8819aa1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2175-or-if-while-let/basic.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(dead_code)] + +enum E { + V(u8), + U(u8), + W, +} +use E::*; + +fn main() { + let mut e = V(10); + + if let V(x) | U(x) = e { + assert_eq!(x, 10); + } + while let V(x) | U(x) = e { + assert_eq!(x, 10); + e = W; + } + + // Accept leading `|`: + + let mut e = V(10); + + if let | V(x) | U(x) = e { + assert_eq!(x, 10); + } + while let | V(x) | U(x) = e { + assert_eq!(x, 10); + e = W; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2302-self-struct-ctor.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2302-self-struct-ctor.rs new file mode 100644 index 000000000000..98d4b156485c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2302-self-struct-ctor.rs @@ -0,0 +1,128 @@ +// run-pass + +#![allow(dead_code)] + +use std::fmt::Display; + +struct ST1(i32, i32); + +impl ST1 { + fn new() -> Self { + ST1(0, 1) + } + + fn ctor() -> Self { + Self(1,2) // Self as a constructor + } + + fn pattern(self) { + match self { + Self(x, y) => println!("{} {}", x, y), // Self as a pattern + } + } +} + +struct ST2(T); // With type parameter + +impl ST2 where T: Display { + + fn ctor(v: T) -> Self { + Self(v) + } + + fn pattern(&self) { + match self { + Self(ref v) => println!("{}", v), + } + } +} + +struct ST3<'a>(&'a i32); // With lifetime parameter + +impl<'a> ST3<'a> { + + fn ctor(v: &'a i32) -> Self { + Self(v) + } + + fn pattern(self) { + let Self(ref v) = self; + println!("{}", v); + } +} + +struct ST4(usize); + +impl ST4 { + fn map(opt: Option) -> Option { + opt.map(Self) // use `Self` as a function passed somewhere + } +} + +struct ST5; // unit struct + +impl ST5 { + fn ctor() -> Self { + Self // `Self` as a unit struct value + } + + fn pattern(self) -> Self { + match self { + Self => Self, // `Self` as a unit struct value for matching + } + } +} + +struct ST6(i32); +type T = ST6; +impl T { + fn ctor() -> Self { + ST6(1) + } + + fn type_alias(self) { + let Self(_x) = match self { Self(x) => Self(x) }; + let _opt: Option = Some(0).map(Self); + } +} + +struct ST7(T1, T2); + +impl ST7 { + + fn ctor() -> Self { + Self(1, 2) + } + + fn pattern(self) -> Self { + match self { + Self(x, y) => Self(x, y), + } + } +} + +fn main() { + let v1 = ST1::ctor(); + v1.pattern(); + + let v2 = ST2::ctor(10); + v2.pattern(); + + let local = 42; + let v3 = ST3::ctor(&local); + v3.pattern(); + + let v4 = Some(1usize); + let _ = ST4::map(v4); + + let v5 = ST5::ctor(); + v5.pattern(); + + let v6 = ST6::ctor(); + v6.type_alias(); + + let v7 = ST7::::ctor(); + let r = v7.pattern(); + println!("{} {}", r.0, r.1) +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/check-pass.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/check-pass.rs new file mode 100644 index 000000000000..9d698c66492c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/check-pass.rs @@ -0,0 +1,51 @@ +// Tests the new rules added by RFC 2396, including: +// - applying `#[target_feature]` to safe functions is allowed +// - calling functions with `#[target_feature]` is allowed in +// functions which have (at least) the same features +// - calling functions with `#[target_feature]` is allowed in +// unsafe contexts +// - functions with `#[target_feature]` can coerce to unsafe fn pointers + +// check-pass +// only-x86_64 + +#![feature(target_feature_11)] + +#[target_feature(enable = "sse2")] +const fn sse2() {} + +#[cfg(target_feature = "sse2")] +const SSE2_ONLY: () = unsafe { + sse2(); +}; + +#[target_feature(enable = "sse2")] +fn also_sse2() { + sse2(); +} + +#[target_feature(enable = "sse2")] +#[target_feature(enable = "avx")] +fn sse2_and_avx() { + sse2(); +} + +struct Foo; + +impl Foo { + #[target_feature(enable = "sse2")] + fn sse2(&self) { + sse2(); + } +} + +fn main() { + if cfg!(target_feature = "sse2") { + unsafe { + sse2(); + Foo.sse2(); + } + } + let sse2_ptr: unsafe fn() = sse2; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/closures-inherit-target_feature.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/closures-inherit-target_feature.rs new file mode 100644 index 000000000000..c840091962f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/closures-inherit-target_feature.rs @@ -0,0 +1,19 @@ +// Tests #73631: closures inherit `#[target_feature]` annotations + +// check-pass +// only-x86_64 + +#![feature(target_feature_11)] + +#[target_feature(enable="avx")] +fn also_use_avx() { + println!("Hello from AVX") +} + +#[target_feature(enable="avx")] +fn use_avx() -> Box { + Box::new(|| also_use_avx()) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.rs new file mode 100644 index 000000000000..86e428b035ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/feature-gate-target_feature_11.rs @@ -0,0 +1,7 @@ +// only-x86_64 + +#[target_feature(enable = "sse2")] // { dg-error ".E0658." "" { target *-*-* } } +fn foo() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs new file mode 100644 index 000000000000..83d069f74521 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.rs @@ -0,0 +1,11 @@ +// only-x86_64 + +#![feature(target_feature_11)] + +#[target_feature(enable = "sse2")] +fn foo() {} + +fn main() { + let foo: fn() = foo; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs new file mode 100644 index 000000000000..2d194176030e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs @@ -0,0 +1,35 @@ +// only-x86_64 + +#![feature(target_feature_11)] + +#[target_feature(enable = "avx")] +fn foo() {} + +#[target_feature(enable = "avx")] +unsafe fn foo_unsafe() {} + +fn call(f: impl Fn()) { + f() +} + +fn call_mut(f: impl FnMut()) { + f() +} + +fn call_once(f: impl FnOnce()) { + f() +} + +fn main() { + call(foo); // { dg-error ".E0277." "" { target *-*-* } } + call_mut(foo); // { dg-error ".E0277." "" { target *-*-* } } + call_once(foo); // { dg-error ".E0277." "" { target *-*-* } } + + call(foo_unsafe); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + call_mut(foo_unsafe); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + call_once(foo_unsafe); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs new file mode 100644 index 000000000000..77250215c723 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs @@ -0,0 +1,48 @@ +// only-x86_64 + +#![feature(target_feature_11)] + +#[target_feature(enable = "sse2")] +const fn sse2() {} + +#[target_feature(enable = "avx")] +#[target_feature(enable = "bmi2")] +fn avx_bmi2() {} + +struct Quux; + +impl Quux { + #[target_feature(enable = "avx")] + #[target_feature(enable = "bmi2")] + fn avx_bmi2(&self) {} +} + +fn foo() { + sse2(); // { dg-error ".E0133." "" { target *-*-* } } + avx_bmi2(); // { dg-error ".E0133." "" { target *-*-* } } + Quux.avx_bmi2(); // { dg-error ".E0133." "" { target *-*-* } } +} + +#[target_feature(enable = "sse2")] +fn bar() { + avx_bmi2(); // { dg-error ".E0133." "" { target *-*-* } } + Quux.avx_bmi2(); // { dg-error ".E0133." "" { target *-*-* } } +} + +#[target_feature(enable = "avx")] +fn baz() { + sse2(); // { dg-error ".E0133." "" { target *-*-* } } + avx_bmi2(); // { dg-error ".E0133." "" { target *-*-* } } + Quux.avx_bmi2(); // { dg-error ".E0133." "" { target *-*-* } } +} + +#[target_feature(enable = "avx")] +#[target_feature(enable = "bmi2")] +fn qux() { + sse2(); // { dg-error ".E0133." "" { target *-*-* } } +} + +const name: () = sse2(); // { dg-error ".E0133." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs new file mode 100644 index 000000000000..6cf45910dc50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2396-target_feature-11/trait-impl.rs @@ -0,0 +1,22 @@ +// only-x86_64 + +#![feature(target_feature_11)] + +trait Foo { + fn foo(&self); + unsafe fn unsf_foo(&self); +} + +struct Bar; + +impl Foo for Bar { + #[target_feature(enable = "sse2")] +// { dg-error "" "" { target *-*-* } .-1 } + fn foo(&self) {} + + #[target_feature(enable = "sse2")] + unsafe fn unsf_foo(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs new file mode 100644 index 000000000000..4a87065f9cb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test that removed keywords are allowed as identifiers. +fn main () { + let offsetof = (); + let alignof = (); + let sizeof = (); + let pure = (); +} + +fn offsetof() {} +fn alignof() {} +fn sizeof() {} +fn pure() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs new file mode 100644 index 000000000000..226f19e7d830 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc1445/eq-allows-match-on-ty-in-macro.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] + +macro_rules! foo { + (#[$attr:meta] $x:ident) => { + #[$attr] + struct $x { + x: u32 + } + } +} + +foo! { #[derive(PartialEq, Eq)] Foo } + +const FOO: Foo = Foo { x: 0 }; + +fn main() { + let y = Foo { x: 1 }; + match y { + FOO => { } + _ => { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc1445/eq-allows-match.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc1445/eq-allows-match.rs new file mode 100644 index 000000000000..50ffa357a98e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc1445/eq-allows-match.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] + +#[derive(PartialEq, Eq)] +struct Foo { + x: u32 +} + +const FOO: Foo = Foo { x: 0 }; + +fn main() { + let y = Foo { x: 1 }; + match y { + FOO => { } + _ => { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc1623.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc1623.rs new file mode 100644 index 000000000000..90b0386b452f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc1623.rs @@ -0,0 +1,76 @@ +// run-pass +#![allow(unused_variables)] +#![allow(non_upper_case_globals)] + +#![allow(dead_code)] + +// very simple test for a 'static static with default lifetime +static STATIC_STR: &str = "&'static str"; +const CONST_STR: &str = "&'static str"; + +// this should be the same as without default: +static EXPLICIT_STATIC_STR: &'static str = "&'static str"; +const EXPLICIT_CONST_STR: &'static str = "&'static str"; + +// a function that elides to an unbound lifetime for both in- and output +fn id_u8_slice(arg: &[u8]) -> &[u8] { + arg +} + +// one with a function, argument elided +static STATIC_SIMPLE_FN: &fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); +const CONST_SIMPLE_FN: &fn(&[u8]) -> &[u8] = &(id_u8_slice as fn(&[u8]) -> &[u8]); + +// this should be the same as without elision +static STATIC_NON_ELIDED_fN: &for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); +const CONST_NON_ELIDED_fN: &for<'a> fn(&'a [u8]) -> &'a [u8] = + &(id_u8_slice as for<'a> fn(&'a [u8]) -> &'a [u8]); + +// another function that elides, each to a different unbound lifetime +fn multi_args(a: &u8, b: &u8, c: &u8) {} + +static STATIC_MULTI_FN: &fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); +const CONST_MULTI_FN: &fn(&u8, &u8, &u8) = &(multi_args as fn(&u8, &u8, &u8)); + +struct Foo<'a> { + bools: &'a [bool], +} + +static STATIC_FOO: Foo = Foo { bools: &[true, false] }; +const CONST_FOO: Foo = Foo { bools: &[true, false] }; + +type Bar<'a> = Foo<'a>; + +static STATIC_BAR: Bar = Bar { bools: &[true, false] }; +const CONST_BAR: Bar = Bar { bools: &[true, false] }; + +type Baz<'a> = fn(&'a [u8]) -> Option; + +fn baz(e: &[u8]) -> Option { + e.first().map(|x| *x) +} + +static STATIC_BAZ: &Baz = &(baz as Baz); +const CONST_BAZ: &Baz = &(baz as Baz); + +static BYTES: &[u8] = &[1, 2, 3]; + +fn main() { + // make sure that the lifetime is actually elided (and not defaulted) + let x = &[1u8, 2, 3]; + STATIC_SIMPLE_FN(x); + CONST_SIMPLE_FN(x); + + STATIC_BAZ(BYTES); // neees static lifetime + CONST_BAZ(BYTES); + + // make sure this works with different lifetimes + let a = &1; + { + let b = &2; + let c = &3; + CONST_MULTI_FN(a, b, c); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc1717/library-override.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc1717/library-override.rs new file mode 100644 index 000000000000..aaa76e1b2437 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc1717/library-override.rs @@ -0,0 +1,15 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with +// compile-flags: -lstatic=wronglibrary:rust_test_helpers + +#[link(name = "wronglibrary", kind = "dylib")] +extern "C" { + pub fn rust_dbg_extern_identity_u32(x: u32) -> u32; +} + +fn main() { + unsafe { + rust_dbg_extern_identity_u32(42); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rfcs/rfc1857-drop-order.rs b/gcc/testsuite/rust/rustc/ui/rfcs/rfc1857-drop-order.rs new file mode 100644 index 000000000000..bfaa7bc42783 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rfcs/rfc1857-drop-order.rs @@ -0,0 +1,225 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default + +#![allow(dead_code, unreachable_code)] + +use std::cell::RefCell; +use std::rc::Rc; +use std::panic::{self, AssertUnwindSafe, UnwindSafe}; + +// This struct is used to record the order in which elements are dropped +struct PushOnDrop { + vec: Rc>>, + val: u32 +} + +impl PushOnDrop { + fn new(val: u32, vec: Rc>>) -> PushOnDrop { + PushOnDrop { vec, val } + } +} + +impl Drop for PushOnDrop { + fn drop(&mut self) { + self.vec.borrow_mut().push(self.val) + } +} + +impl UnwindSafe for PushOnDrop { } + +// Structs +struct TestStruct { + x: PushOnDrop, + y: PushOnDrop, + z: PushOnDrop +} + +// Tuple structs +struct TestTupleStruct(PushOnDrop, PushOnDrop, PushOnDrop); + +// Enum variants +enum TestEnum { + Tuple(PushOnDrop, PushOnDrop, PushOnDrop), + Struct { x: PushOnDrop, y: PushOnDrop, z: PushOnDrop } +} + +fn test_drop_tuple() { + // Tuple fields are dropped in the same order they are declared + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let test_tuple = (PushOnDrop::new(1, dropped_fields.clone()), + PushOnDrop::new(2, dropped_fields.clone())); + drop(test_tuple); + assert_eq!(*dropped_fields.borrow(), &[1, 2]); + + // Panic during construction means that fields are treated as local variables + // Therefore they are dropped in reverse order of initialization + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let cloned = AssertUnwindSafe(dropped_fields.clone()); + panic::catch_unwind(|| { + (PushOnDrop::new(2, cloned.clone()), + PushOnDrop::new(1, cloned.clone()), + panic!("this panic is caught :D")); + }).err().unwrap(); + assert_eq!(*dropped_fields.borrow(), &[1, 2]); +} + +fn test_drop_struct() { + // Struct fields are dropped in the same order they are declared + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let test_struct = TestStruct { + x: PushOnDrop::new(1, dropped_fields.clone()), + y: PushOnDrop::new(2, dropped_fields.clone()), + z: PushOnDrop::new(3, dropped_fields.clone()), + }; + drop(test_struct); + assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]); + + // The same holds for tuple structs + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let test_tuple_struct = TestTupleStruct(PushOnDrop::new(1, dropped_fields.clone()), + PushOnDrop::new(2, dropped_fields.clone()), + PushOnDrop::new(3, dropped_fields.clone())); + drop(test_tuple_struct); + assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]); + + // Panic during struct construction means that fields are treated as local variables + // Therefore they are dropped in reverse order of initialization + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let cloned = AssertUnwindSafe(dropped_fields.clone()); + panic::catch_unwind(|| { + TestStruct { + x: PushOnDrop::new(2, cloned.clone()), + y: PushOnDrop::new(1, cloned.clone()), + z: panic!("this panic is caught :D") + }; + }).err().unwrap(); + assert_eq!(*dropped_fields.borrow(), &[1, 2]); + + // Test with different initialization order + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let cloned = AssertUnwindSafe(dropped_fields.clone()); + panic::catch_unwind(|| { + TestStruct { + y: PushOnDrop::new(2, cloned.clone()), + x: PushOnDrop::new(1, cloned.clone()), + z: panic!("this panic is caught :D") + }; + }).err().unwrap(); + assert_eq!(*dropped_fields.borrow(), &[1, 2]); + + // The same holds for tuple structs + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let cloned = AssertUnwindSafe(dropped_fields.clone()); + panic::catch_unwind(|| { + TestTupleStruct(PushOnDrop::new(2, cloned.clone()), + PushOnDrop::new(1, cloned.clone()), + panic!("this panic is caught :D")); + }).err().unwrap(); + assert_eq!(*dropped_fields.borrow(), &[1, 2]); +} + +fn test_drop_enum() { + // Enum variants are dropped in the same order they are declared + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let test_struct_enum = TestEnum::Struct { + x: PushOnDrop::new(1, dropped_fields.clone()), + y: PushOnDrop::new(2, dropped_fields.clone()), + z: PushOnDrop::new(3, dropped_fields.clone()) + }; + drop(test_struct_enum); + assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]); + + // The same holds for tuple enum variants + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let test_tuple_enum = TestEnum::Tuple(PushOnDrop::new(1, dropped_fields.clone()), + PushOnDrop::new(2, dropped_fields.clone()), + PushOnDrop::new(3, dropped_fields.clone())); + drop(test_tuple_enum); + assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]); + + // Panic during enum construction means that fields are treated as local variables + // Therefore they are dropped in reverse order of initialization + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let cloned = AssertUnwindSafe(dropped_fields.clone()); + panic::catch_unwind(|| { + TestEnum::Struct { + x: PushOnDrop::new(2, cloned.clone()), + y: PushOnDrop::new(1, cloned.clone()), + z: panic!("this panic is caught :D") + }; + }).err().unwrap(); + assert_eq!(*dropped_fields.borrow(), &[1, 2]); + + // Test with different initialization order + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let cloned = AssertUnwindSafe(dropped_fields.clone()); + panic::catch_unwind(|| { + TestEnum::Struct { + y: PushOnDrop::new(2, cloned.clone()), + x: PushOnDrop::new(1, cloned.clone()), + z: panic!("this panic is caught :D") + }; + }).err().unwrap(); + assert_eq!(*dropped_fields.borrow(), &[1, 2]); + + // The same holds for tuple enum variants + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let cloned = AssertUnwindSafe(dropped_fields.clone()); + panic::catch_unwind(|| { + TestEnum::Tuple(PushOnDrop::new(2, cloned.clone()), + PushOnDrop::new(1, cloned.clone()), + panic!("this panic is caught :D")); + }).err().unwrap(); + assert_eq!(*dropped_fields.borrow(), &[1, 2]); +} + +fn test_drop_list() { + // Elements in a Vec are dropped in the same order they are pushed + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let xs = vec![PushOnDrop::new(1, dropped_fields.clone()), + PushOnDrop::new(2, dropped_fields.clone()), + PushOnDrop::new(3, dropped_fields.clone())]; + drop(xs); + assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]); + + // The same holds for arrays + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let xs = [PushOnDrop::new(1, dropped_fields.clone()), + PushOnDrop::new(2, dropped_fields.clone()), + PushOnDrop::new(3, dropped_fields.clone())]; + drop(xs); + assert_eq!(*dropped_fields.borrow(), &[1, 2, 3]); + + // Panic during vec construction means that fields are treated as local variables + // Therefore they are dropped in reverse order of initialization + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let cloned = AssertUnwindSafe(dropped_fields.clone()); + panic::catch_unwind(|| { + vec![ + PushOnDrop::new(2, cloned.clone()), + PushOnDrop::new(1, cloned.clone()), + panic!("this panic is caught :D") + ]; + }).err().unwrap(); + assert_eq!(*dropped_fields.borrow(), &[1, 2]); + + // The same holds for arrays + let dropped_fields = Rc::new(RefCell::new(Vec::new())); + let cloned = AssertUnwindSafe(dropped_fields.clone()); + panic::catch_unwind(|| { + [ + PushOnDrop::new(2, cloned.clone()), + PushOnDrop::new(1, cloned.clone()), + panic!("this panic is caught :D") + ]; + }).err().unwrap(); + assert_eq!(*dropped_fields.borrow(), &[1, 2]); +} + +fn main() { + test_drop_tuple(); + test_drop_struct(); + test_drop_enum(); + test_drop_list(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rmeta-lib-pass.rs b/gcc/testsuite/rust/rustc/ui/rmeta-lib-pass.rs new file mode 100644 index 000000000000..cd8ac78a11d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rmeta-lib-pass.rs @@ -0,0 +1,15 @@ +// compile-flags: --emit=metadata +// aux-build:rmeta-rlib.rs +// no-prefer-dynamic +// build-pass (FIXME(62277): could be check-pass?) + +// Check that building a metadata crate works with a dependent, rlib crate. +// This is a cfail test since there is no executable to run. + +extern crate rmeta_rlib; +use rmeta_rlib::Foo; + +pub fn main() { + let _ = Foo { field: 42 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rmeta-pass.rs b/gcc/testsuite/rust/rustc/ui/rmeta-pass.rs new file mode 100644 index 000000000000..fa5ce241468d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rmeta-pass.rs @@ -0,0 +1,16 @@ +// compile-flags: --emit=metadata +// aux-build:rmeta-meta.rs +// no-prefer-dynamic +// build-pass (FIXME(62277): could be check-pass?) + +// Check that building a metadata crate works with a dependent, metadata-only +// crate. +// This is a cfail test since there is no executable to run. + +extern crate rmeta_meta; +use rmeta_meta::Foo; + +pub fn main() { + let _ = Foo { field: 42 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rmeta-priv-warn.rs b/gcc/testsuite/rust/rustc/ui/rmeta-priv-warn.rs new file mode 100644 index 000000000000..8285dc9bb5ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rmeta-priv-warn.rs @@ -0,0 +1,12 @@ +// compile-flags: --emit=metadata +// no-prefer-dynamic +// build-pass (FIXME(62277): could be check-pass?) + +#[deny(warnings)] + +// Test that we don't get warnings for non-pub main when only emitting metadata. +// (#38273) + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/rmeta-rpass.rs b/gcc/testsuite/rust/rustc/ui/rmeta-rpass.rs new file mode 100644 index 000000000000..242f2f67478a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rmeta-rpass.rs @@ -0,0 +1,19 @@ +// run-pass +// Test that using rlibs and rmeta dep crates work together. Specifically, that +// there can be both an rmeta and an rlib file and rustc will prefer the rmeta +// file. +// +// This behavior is simply making sure this doesn't accidentally change; in this +// case we want to make sure that the rlib isn't being used as that would cause +// bugs in -Zbinary-dep-depinfo (see #68298). + +// aux-build:rmeta-rmeta.rs +// aux-build:rmeta-rlib-rpass.rs + +extern crate rmeta_aux; +use rmeta_aux::Foo; + +pub fn main() { + let _ = Foo { field2: 42 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rmeta.rs b/gcc/testsuite/rust/rustc/ui/rmeta.rs new file mode 100644 index 000000000000..3a4ca64b3ef6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rmeta.rs @@ -0,0 +1,9 @@ +// no-prefer-dynamic +// compile-flags: --emit=metadata + +// Check that building a metadata crate finds an error. + +fn main() { + let _ = Foo; // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rmeta_lib.rs b/gcc/testsuite/rust/rustc/ui/rmeta_lib.rs new file mode 100644 index 000000000000..3d18dceadc46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rmeta_lib.rs @@ -0,0 +1,15 @@ +// build-fail +// aux-build:rmeta-meta.rs +// no-prefer-dynamic +// error-pattern: crate `rmeta_meta` required to be available in rlib format, but was not found + +// Check that building a non-metadata crate fails if a dependent crate is +// metadata-only. + +extern crate rmeta_meta; +use rmeta_meta::Foo; + +fn main() { + let _ = Foo { field: 42 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rmeta_meta_main.rs b/gcc/testsuite/rust/rustc/ui/rmeta_meta_main.rs new file mode 100644 index 000000000000..08063b36c9fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rmeta_meta_main.rs @@ -0,0 +1,15 @@ +// compile-flags: --emit=metadata +// aux-build:rmeta-meta.rs +// no-prefer-dynamic + +// Check that building a metadata crate finds an error with a dependent, +// metadata-only crate. + + +extern crate rmeta_meta; +use rmeta_meta::Foo; + +fn main() { + let _ = Foo { field2: 42 }; // { dg-error ".E0560." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/running-with-no-runtime.rs b/gcc/testsuite/rust/rustc/ui/running-with-no-runtime.rs new file mode 100644 index 000000000000..7f1cda442fec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/running-with-no-runtime.rs @@ -0,0 +1,52 @@ +// run-pass +// ignore-cloudabi spawning processes is not supported +// ignore-emscripten spawning processes is not supported +// ignore-sgx no processes + +#![feature(start)] + +use std::ffi::CStr; +use std::process::{Command, Output}; +use std::panic; +use std::str; + +#[start] +fn start(argc: isize, argv: *const *const u8) -> isize { + if argc > 1 { + unsafe { + match **argv.offset(1) as char { + '1' => {} + '2' => println!("foo"), + '3' => assert!(panic::catch_unwind(|| {}).is_ok()), + '4' => assert!(panic::catch_unwind(|| panic!()).is_err()), + '5' => assert!(Command::new("test").spawn().is_err()), + _ => panic!() + } + } + return 0 + } + + let args = unsafe { + (0..argc as usize).map(|i| { + let ptr = *argv.add(i) as *const _; + CStr::from_ptr(ptr).to_bytes().to_vec() + }).collect::>() + }; + let me = String::from_utf8(args[0].to_vec()).unwrap(); + + pass(Command::new(&me).arg("1").output().unwrap()); + pass(Command::new(&me).arg("2").output().unwrap()); + pass(Command::new(&me).arg("3").output().unwrap()); + pass(Command::new(&me).arg("4").output().unwrap()); + pass(Command::new(&me).arg("5").output().unwrap()); + + 0 +} + +fn pass(output: Output) { + if !output.status.success() { + println!("{:?}", str::from_utf8(&output.stdout)); + println!("{:?}", str::from_utf8(&output.stderr)); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/async-ident-allowed.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/async-ident-allowed.rs new file mode 100644 index 000000000000..d512a444143f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/async-ident-allowed.rs @@ -0,0 +1,12 @@ +// edition:2015 + +#![deny(rust_2018_compatibility)] + +// Don't make a suggestion for a raw identifier replacement unless raw +// identifiers are enabled. + +fn main() { + let async = 3; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/async-ident.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/async-ident.rs new file mode 100644 index 000000000000..ee5c5a809c3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/async-ident.rs @@ -0,0 +1,80 @@ +#![allow(dead_code, unused_variables, non_camel_case_types, non_upper_case_globals)] +#![deny(keyword_idents)] + +// edition:2015 +// run-rustfix + +fn async() {} // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + +macro_rules! foo { + ($foo:ident) => {}; + ($async:expr, async) => {}; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +} + +foo!(async); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +mod dont_lint_raw { + fn r#async() {} +} + +mod async_trait { + trait async {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + struct MyStruct; + impl async for MyStruct {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +mod async_static { + static async: u32 = 0; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +mod async_const { + const async: u32 = 0; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +struct Foo; +impl Foo { fn async() {} } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() { + struct async {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + let async: async = async {}; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-warning "" "" { target *-*-* } .-6 } +} + +#[macro_export] +macro_rules! produces_async { + () => (pub fn async() {}) +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +#[macro_export] +macro_rules! consumes_async { + (async) => (1) +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/baz.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/baz.rs new file mode 100644 index 000000000000..a8533882411b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/baz.rs @@ -0,0 +1,6 @@ +// This file is used as part of the local-path-suggestions.rs test. + +pub mod foobar { + pub struct Baz; +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/edition-lint-paths.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/edition-lint-paths.rs new file mode 100644 index 000000000000..3a6dde808f00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/edition-lint-paths.rs @@ -0,0 +1,13 @@ +pub fn foo() {} + +#[macro_export] +macro_rules! macro_2015 { + () => { + use edition_lint_paths as other_name; + use edition_lint_paths::foo as other_foo; + fn check_macro_2015() { + ::edition_lint_paths::foo(); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/macro-use-warned-against.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/macro-use-warned-against.rs new file mode 100644 index 000000000000..367fbb467bb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/macro-use-warned-against.rs @@ -0,0 +1,3 @@ +#[macro_export] +macro_rules! foo { () => () } + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/macro-use-warned-against2.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/macro-use-warned-against2.rs new file mode 100644 index 000000000000..c84c7b394dc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/macro-use-warned-against2.rs @@ -0,0 +1,2 @@ +// intentionally empty + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/remove-extern-crate.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/remove-extern-crate.rs new file mode 100644 index 000000000000..318508a8af94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/remove-extern-crate.rs @@ -0,0 +1,10 @@ +#[macro_export] +macro_rules! foo { + () => () +} + +#[macro_export] +macro_rules! bar { + () => () +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/suggestions-not-always-applicable.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/suggestions-not-always-applicable.rs new file mode 100644 index 000000000000..54002fc33c5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/suggestions-not-always-applicable.rs @@ -0,0 +1,14 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro_attribute] +pub fn foo(_attr: TokenStream, _f: TokenStream) -> TokenStream { + "pub fn foo() -> ::Foo { ::Foo }".parse().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/trait-import-suggestions.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/trait-import-suggestions.rs new file mode 100644 index 000000000000..1b9b7aad9f2b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/auxiliary/trait-import-suggestions.rs @@ -0,0 +1,6 @@ +pub trait Baz { + fn baz(&self) { } +} + +impl Baz for u32 { } + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/dyn-keyword.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/dyn-keyword.rs new file mode 100644 index 000000000000..9e64b09bbc98 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/dyn-keyword.rs @@ -0,0 +1,11 @@ +// edition:2015 +// run-rustfix + +#![allow(unused_variables)] +#![deny(keyword_idents)] + +fn main() { + let dyn = (); // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/dyn-trait-compatibility.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/dyn-trait-compatibility.rs new file mode 100644 index 000000000000..f50ad3e14aed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/dyn-trait-compatibility.rs @@ -0,0 +1,9 @@ +// edition:2018 + +type A0 = dyn; +type A1 = dyn::dyn; // { dg-error "" "" { target *-*-* } } +type A2 = dyn; // { dg-error "" "" { target *-*-* } } +type A3 = dyn<::dyn>; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-fully-qualified-paths.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-fully-qualified-paths.rs new file mode 100644 index 000000000000..7fed6559b8ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-fully-qualified-paths.rs @@ -0,0 +1,28 @@ +// run-rustfix + +#![feature(rust_2018_preview, crate_visibility_modifier)] +#![deny(absolute_paths_not_starting_with_crate)] + +mod foo { + crate trait Foo { + type Bar; + } + + crate struct Baz { } + + impl Foo for Baz { + type Bar = (); + } +} + + +fn main() { + let _: ::Bar = (); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + let _: <::foo::Baz as foo::Foo>::Bar = (); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-infer-outlives-multispan.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-infer-outlives-multispan.rs new file mode 100644 index 000000000000..8acb93d77eca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-infer-outlives-multispan.rs @@ -0,0 +1,369 @@ +#![allow(unused)] +#![deny(explicit_outlives_requirements)] + + +// These examples should live in edition-lint-infer-outlives.rs, but are split +// into this separate file because they can't be `rustfix`'d (and thus, can't +// be part of a `run-rustfix` test file) until rust-lang-nursery/rustfix#141 +// is solved + +mod structs { + use std::fmt::Debug; + + struct TeeOutlivesAyIsDebugBee<'a, 'b, T: 'a + Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + struct TeeWhereOutlivesAyIsDebugBee<'a, 'b, T> where T: 'a + Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + struct TeeYooOutlivesAyIsDebugBee<'a, 'b, T, U: 'a + Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a &'b U + } + + struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T: 'a, U: 'b + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + struct TeeOutlivesAyYooIsDebugBee<'a, 'b, T: 'a, U: Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + struct TeeOutlivesAyYooWhereBee<'a, 'b, T: 'a, U> where U: 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + struct TeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U> where U: 'a + Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a &'b U + } + + struct TeeOutlivesAyYooWhereBeeIsDebug<'a, 'b, T: 'a, U> where U: 'b + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + struct TeeOutlivesAyYooWhereIsDebugBee<'a, 'b, T: 'a, U> where U: Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + struct TeeWhereOutlivesAyYooWhereBeeIsDebug<'a, 'b, T, U> where T: 'a, U: 'b + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + struct TeeWhereOutlivesAyYooWhereIsDebugBee<'a, 'b, T, U> where T: 'a, U: Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + struct BeeOutlivesAyTeeBee<'a, 'b: 'a, T: 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + struct BeeOutlivesAyTeeAyBee<'a, 'b: 'a, T: 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + struct BeeOutlivesAyTeeOutlivesAyIsDebugBee<'a, 'b: 'a, T: 'a + Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + struct BeeWhereAyTeeWhereOutlivesAyIsDebugBee<'a, 'b, T> where 'b: 'a, T: 'a + Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + struct BeeOutlivesAyTeeYooOutlivesAyIsDebugBee<'a, 'b: 'a, T, U: 'a + Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a &'b U + } + + struct BeeWhereAyTeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U> + where U: 'a + Debug + 'b, 'b: 'a +// { dg-error "" "" { target *-*-* } .-1 } + { + tee: T, + yoo: &'a &'b U + } +} + +mod tuple_structs { + use std::fmt::Debug; + + struct TeeOutlivesAyIsDebugBee<'a, 'b, T: 'a + Debug + 'b>(&'a &'b T); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeWhereOutlivesAyIsDebugBee<'a, 'b, T>(&'a &'b T) where T: 'a + Debug + 'b; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooOutlivesAyIsDebugBee<'a, 'b, T, U: 'a + Debug + 'b>(T, &'a &'b U); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T: 'a, U: 'b + Debug>(&'a T, &'b U); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeOutlivesAyYooIsDebugBee<'a, 'b, T: 'a, U: Debug + 'b>(&'a T, &'b U); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeOutlivesAyYooWhereBee<'a, 'b, T: 'a, U>(&'a T, &'b U) where U: 'b; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U>(T, &'a &'b U) where U: 'a + Debug + 'b; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeOutlivesAyYooWhereBeeIsDebug<'a, 'b, T: 'a, U>(&'a T, &'b U) where U: 'b + Debug; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeOutlivesAyYooWhereIsDebugBee<'a, 'b, T: 'a, U>(&'a T, &'b U) where U: Debug + 'b; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeWhereAyYooWhereBeeIsDebug<'a, 'b, T, U>(&'a T, &'b U) where T: 'a, U: 'b + Debug; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeWhereAyYooWhereIsDebugBee<'a, 'b, T, U>(&'a T, &'b U) where T: 'a, U: Debug + 'b; +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeOutlivesAyTeeBee<'a, 'b: 'a, T: 'b>(&'a &'b T); +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeOutlivesAyTeeAyBee<'a, 'b: 'a, T: 'a + 'b>(&'a &'b T); +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeOutlivesAyTeeOutlivesAyIsDebugBee<'a, 'b: 'a, T: 'a + Debug + 'b>(&'a &'b T); +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeWhereAyTeeWhereAyIsDebugBee<'a, 'b, T>(&'a &'b T) where 'b: 'a, T: 'a + Debug + 'b; +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeOutlivesAyTeeYooOutlivesAyIsDebugBee<'a, 'b: 'a, T, U: 'a + Debug + 'b>(T, &'a &'b U); +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeWhereAyTeeYooWhereAyIsDebugBee<'a, 'b, T, U>(T, &'a &'b U) + where U: 'a + Debug + 'b, 'b: 'a; +// { dg-error "" "" { target *-*-* } .-1 } +} + +mod enums { + use std::fmt::Debug; + + enum TeeOutlivesAyIsDebugBee<'a, 'b, T: 'a + Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a &'b T }, + } + + enum TeeWhereOutlivesAyIsDebugBee<'a, 'b, T> where T: 'a + Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a &'b T), + } + + enum TeeYooOutlivesAyIsDebugBee<'a, 'b, T, U: 'a + Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: T, }, + W(&'a &'b U), + } + + enum TeeOutlivesAyYooBeeIsDebug<'a, 'b, T: 'a, U: 'b + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a T, yoo: &'b U }, + W, + } + + enum TeeOutlivesAyYooIsDebugBee<'a, 'b, T: 'a, U: Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a T, &'b U), + W, + } + + enum TeeOutlivesAyYooWhereBee<'a, 'b, T: 'a, U> where U: 'b { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a T }, + W(&'b U), + } + + enum TeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U> where U: 'a + Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: T, yoo: &'a &'b U }, + W, + } + + enum TeeOutlivesAyYooWhereBeeIsDebug<'a, 'b, T: 'a, U> where U: 'b + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a T, &'b U), + W, + } + + enum TeeOutlivesAyYooWhereIsDebugBee<'a, 'b, T: 'a, U> where U: Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a T }, + W(&'b U) + } + + enum TeeWhereOutlivesAyYooWhereBeeIsDebug<'a, 'b, T, U> where T: 'a, U: 'b + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a T, yoo: &'b U }, + W, + } + + enum TeeWhereOutlivesAyYooWhereIsDebugBee<'a, 'b, T, U> where T: 'a, U: Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a T, &'b U), + W, + } + + enum BeeOutlivesAyTeeBee<'a, 'b: 'a, T: 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a &'b T }, + } + + enum BeeOutlivesAyTeeAyBee<'a, 'b: 'a, T: 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a &'b T }, + W, + } + + enum BeeOutlivesAyTeeOutlivesAyIsDebugBee<'a, 'b: 'a, T: 'a + Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a &'b T }, + } + + enum BeeWhereAyTeeWhereOutlivesAyIsDebugBee<'a, 'b, T> where 'b: 'a, T: 'a + Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a &'b T), + } + + enum BeeOutlivesAyTeeYooOutlivesAyIsDebugBee<'a, 'b: 'a, T, U: 'a + Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: T }, + W(&'a &'b U), + } + + enum BeeWhereAyTeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U> where U: 'a + Debug + 'b, 'b: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: T, yoo: &'a &'b U }, + } +} + +mod unions { + use std::fmt::Debug; + + union TeeOutlivesAyIsDebugBee<'a, 'b, T: 'a + Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + union TeeWhereOutlivesAyIsDebugBee<'a, 'b, T> where T: 'a + Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + union TeeYooOutlivesAyIsDebugBee<'a, 'b, T, U: 'a + Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a &'b U + } + + union TeeOutlivesAyYooBeeIsDebug<'a, 'b, T: 'a, U: 'b + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + union TeeOutlivesAyYooIsDebugBee<'a, 'b, T: 'a, U: Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + union TeeOutlivesAyYooWhereBee<'a, 'b, T: 'a, U> where U: 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + union TeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U> where U: 'a + Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a &'b U + } + + union TeeOutlivesAyYooWhereBeeIsDebug<'a, 'b, T: 'a, U> where U: 'b + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + union TeeOutlivesAyYooWhereIsDebugBee<'a, 'b, T: 'a, U> where U: Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + union TeeWhereOutlivesAyYooWhereBeeIsDebug<'a, 'b, T, U> where T: 'a, U: 'b + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + union TeeWhereOutlivesAyYooWhereIsDebugBee<'a, 'b, T, U> where T: 'a, U: Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: &'b U + } + + union BeeOutlivesAyTeeBee<'a, 'b: 'a, T: 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + union BeeOutlivesAyTeeAyBee<'a, 'b: 'a, T: 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + union BeeOutlivesAyTeeOutlivesAyIsDebugBee<'a, 'b: 'a, T: 'a + Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + union BeeWhereAyTeeWhereOutlivesAyIsDebugBee<'a, 'b, T> where 'b: 'a, T: 'a + Debug + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + union BeeOutlivesAyTeeYooOutlivesAyIsDebugBee<'a, 'b: 'a, T, U: 'a + Debug + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a &'b U + } + + union BeeWhereAyTeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U> where U: 'a + Debug + 'b, 'b: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a &'b U + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-infer-outlives.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-infer-outlives.rs new file mode 100644 index 000000000000..d83be2cb1977 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-infer-outlives.rs @@ -0,0 +1,796 @@ +// run-rustfix + +#![allow(unused)] +#![deny(explicit_outlives_requirements)] + +// Programmatically generated examples! +// +// Exercise outlives bounds for each of the following parameter/position +// combinations— +// +// • one generic parameter (T) bound inline +// • one parameter (T) with a where clause +// • two parameters (T and U), both bound inline +// • two parameters (T and U), one bound inline, one with a where clause +// • two parameters (T and U), both with where clauses +// +// —and for every permutation of 1 or 2 lifetimes to outlive and 0 or 1 trait +// bounds distributed among said parameters (subject to no where clause being +// empty and the struct having at least one lifetime). +// +// —and for each of tuple structs, enums and unions. + +mod structs { + use std::fmt::Debug; + + struct TeeOutlivesAy<'a, T: 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T + } + + struct TeeOutlivesAyIsDebug<'a, T: 'a + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T + } + + struct TeeIsDebugOutlivesAy<'a, T: Debug + 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T + } + + struct TeeOutlivesAyBee<'a, 'b, T: 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + struct TeeOutlivesAyBeeIsDebug<'a, 'b, T: 'a + 'b + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + struct TeeIsDebugOutlivesAyBee<'a, 'b, T: Debug + 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + struct TeeWhereOutlivesAy<'a, T> where T: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T + } + + struct TeeWhereOutlivesAyIsDebug<'a, T> where T: 'a + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T + } + + struct TeeWhereIsDebugOutlivesAy<'a, T> where T: Debug + 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T + } + + struct TeeWhereOutlivesAyBee<'a, 'b, T> where T: 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + struct TeeWhereOutlivesAyBeeIsDebug<'a, 'b, T> where T: 'a + 'b + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + struct TeeWhereIsDebugOutlivesAyBee<'a, 'b, T> where T: Debug + 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + struct TeeYooOutlivesAy<'a, T, U: 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a U + } + + struct TeeYooOutlivesAyIsDebug<'a, T, U: 'a + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a U + } + + struct TeeYooIsDebugOutlivesAy<'a, T, U: Debug + 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a U + } + + struct TeeOutlivesAyYooIsDebug<'a, T: 'a, U: Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: U + } + + struct TeeYooOutlivesAyBee<'a, 'b, T, U: 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a &'b U + } + + struct TeeYooOutlivesAyBeeIsDebug<'a, 'b, T, U: 'a + 'b + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a &'b U + } + + struct TeeYooIsDebugOutlivesAyBee<'a, 'b, T, U: Debug + 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a &'b U + } + + struct TeeOutlivesAyBeeYooIsDebug<'a, 'b, T: 'a + 'b, U: Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + yoo: U + } + + struct TeeYooWhereOutlivesAy<'a, T, U> where U: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a U + } + + struct TeeYooWhereOutlivesAyIsDebug<'a, T, U> where U: 'a + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a U + } + + struct TeeYooWhereIsDebugOutlivesAy<'a, T, U> where U: Debug + 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a U + } + + struct TeeOutlivesAyYooWhereIsDebug<'a, T: 'a, U> where U: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: U + } + + struct TeeYooWhereOutlivesAyBee<'a, 'b, T, U> where U: 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a &'b U + } + + struct TeeYooWhereOutlivesAyBeeIsDebug<'a, 'b, T, U> where U: 'a + 'b + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a &'b U + } + + struct TeeYooWhereIsDebugOutlivesAyBee<'a, 'b, T, U> where U: Debug + 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: T, + yoo: &'a &'b U + } + + struct TeeOutlivesAyBeeYooWhereIsDebug<'a, 'b, T: 'a + 'b, U> where U: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + yoo: U + } + + struct TeeWhereOutlivesAyYooWhereIsDebug<'a, T, U> where T: 'a, U: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: U + } + + struct TeeWhereOutlivesAyBeeYooWhereIsDebug<'a, 'b, T, U> where T: 'a + 'b, U: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + yoo: U + } + + struct BeeOutlivesAy<'a, 'b: 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b (), + } + + struct BeeWhereOutlivesAy<'a, 'b> where 'b: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b (), + } + + struct BeeOutlivesAyTee<'a, 'b: 'a, T> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + struct BeeWhereOutlivesAyTee<'a, 'b, T> where 'b: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + struct BeeWhereOutlivesAyTeeWhereBee<'a, 'b, T> where 'b: 'a, T: 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + struct BeeWhereOutlivesAyTeeWhereAyBee<'a, 'b, T> where 'b: 'a, T: 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + struct BeeOutlivesAyTeeDebug<'a, 'b: 'a, T: Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + struct BeeWhereOutlivesAyTeeWhereDebug<'a, 'b, T> where 'b: 'a, T: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } +} + +mod tuple_structs { + use std::fmt::Debug; + + struct TeeOutlivesAy<'a, T: 'a>(&'a T); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeOutlivesAyIsDebug<'a, T: 'a + Debug>(&'a T); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeIsDebugOutlivesAy<'a, T: Debug + 'a>(&'a T); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeOutlivesAyBee<'a, 'b, T: 'a + 'b>(&'a &'b T); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeOutlivesAyBeeIsDebug<'a, 'b, T: 'a + 'b + Debug>(&'a &'b T); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeIsDebugOutlivesAyBee<'a, 'b, T: Debug + 'a + 'b>(&'a &'b T); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeWhereOutlivesAy<'a, T>(&'a T) where T: 'a; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeWhereOutlivesAyIsDebug<'a, T>(&'a T) where T: 'a + Debug; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeWhereIsDebugOutlivesAy<'a, T>(&'a T) where T: Debug + 'a; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeWhereOutlivesAyBee<'a, 'b, T>(&'a &'b T) where T: 'a + 'b; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeWhereOutlivesAyBeeIsDebug<'a, 'b, T>(&'a &'b T) where T: 'a + 'b + Debug; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeWhereIsDebugOutlivesAyBee<'a, 'b, T>(&'a &'b T) where T: Debug + 'a + 'b; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooOutlivesAy<'a, T, U: 'a>(T, &'a U); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooOutlivesAyIsDebug<'a, T, U: 'a + Debug>(T, &'a U); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooIsDebugOutlivesAy<'a, T, U: Debug + 'a>(T, &'a U); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeOutlivesAyYooIsDebug<'a, T: 'a, U: Debug>(&'a T, U); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooOutlivesAyBee<'a, 'b, T, U: 'a + 'b>(T, &'a &'b U); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooOutlivesAyBeeIsDebug<'a, 'b, T, U: 'a + 'b + Debug>(T, &'a &'b U); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooIsDebugOutlivesAyBee<'a, 'b, T, U: Debug + 'a + 'b>(T, &'a &'b U); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeOutlivesAyBeeYooIsDebug<'a, 'b, T: 'a + 'b, U: Debug>(&'a &'b T, U); +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooWhereOutlivesAy<'a, T, U>(T, &'a U) where U: 'a; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooWhereOutlivesAyIsDebug<'a, T, U>(T, &'a U) where U: 'a + Debug; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooWhereIsDebugOutlivesAy<'a, T, U>(T, &'a U) where U: Debug + 'a; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeOutlivesAyYooWhereIsDebug<'a, T: 'a, U>(&'a T, U) where U: Debug; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooWhereOutlivesAyBee<'a, 'b, T, U>(T, &'a &'b U) where U: 'a + 'b; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooWhereOutlivesAyBeeIsDebug<'a, 'b, T, U>(T, &'a &'b U) where U: 'a + 'b + Debug; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeYooWhereIsDebugOutlivesAyBee<'a, 'b, T, U>(T, &'a &'b U) where U: Debug + 'a + 'b; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeOutlivesAyBeeYooWhereIsDebug<'a, 'b, T: 'a + 'b, U>(&'a &'b T, U) where U: Debug; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeWhereOutlivesAyYooWhereIsDebug<'a, T, U>(&'a T, U) where T: 'a, U: Debug; +// { dg-error "" "" { target *-*-* } .-1 } + + struct TeeWhereAyBeeYooWhereIsDebug<'a, 'b, T, U>(&'a &'b T, U) where T: 'a + 'b, U: Debug; +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeOutlivesAy<'a, 'b: 'a>(&'a &'b ()); +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeWhereOutlivesAy<'a, 'b>(&'a &'b ()) where 'b: 'a; +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeOutlivesAyTee<'a, 'b: 'a, T>(&'a &'b T); +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeWhereOutlivesAyTee<'a, 'b, T>(&'a &'b T) where 'b: 'a; +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeWhereOutlivesAyTeeWhereBee<'a, 'b, T>(&'a &'b T) where 'b: 'a, T: 'b; +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeWhereOutlivesAyTeeWhereAyBee<'a, 'b, T>(&'a &'b T) where 'b: 'a, T: 'a + 'b; +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeOutlivesAyTeeDebug<'a, 'b: 'a, T: Debug>(&'a &'b T); +// { dg-error "" "" { target *-*-* } .-1 } + + struct BeeWhereOutlivesAyTeeWhereDebug<'a, 'b, T>(&'a &'b T) where 'b: 'a, T: Debug; +// { dg-error "" "" { target *-*-* } .-1 } +} + +mod enums { + use std::fmt::Debug; + + enum TeeOutlivesAy<'a, T: 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a T }, + } + + enum TeeOutlivesAyIsDebug<'a, T: 'a + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a T), + } + + enum TeeIsDebugOutlivesAy<'a, T: Debug + 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a T }, + W, + } + + enum TeeOutlivesAyBee<'a, 'b, T: 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a &'b T), + W, + } + + enum TeeOutlivesAyBeeIsDebug<'a, 'b, T: 'a + 'b + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a &'b T }, + } + + enum TeeIsDebugOutlivesAyBee<'a, 'b, T: Debug + 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a &'b T), + } + + enum TeeWhereOutlivesAy<'a, T> where T: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a T }, + W, + } + + enum TeeWhereOutlivesAyIsDebug<'a, T> where T: 'a + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a T), + W, + } + + enum TeeWhereIsDebugOutlivesAy<'a, T> where T: Debug + 'a { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a T }, + } + + enum TeeWhereOutlivesAyBee<'a, 'b, T> where T: 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a &'b T), + } + + enum TeeWhereOutlivesAyBeeIsDebug<'a, 'b, T> where T: 'a + 'b + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a &'b T }, + W, + } + + enum TeeWhereIsDebugOutlivesAyBee<'a, 'b, T> where T: Debug + 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a &'b T), + W, + } + + enum TeeYooOutlivesAy<'a, T, U: 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: T }, + W(&'a U), + } + + enum TeeYooOutlivesAyIsDebug<'a, T, U: 'a + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: T, yoo: &'a U }, + W, + } + + enum TeeYooIsDebugOutlivesAy<'a, T, U: Debug + 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + V(T, &'a U), + W, + } + + enum TeeOutlivesAyYooIsDebug<'a, T: 'a, U: Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a T }, + W(U), + } + + enum TeeYooOutlivesAyBee<'a, 'b, T, U: 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: T, yoo: &'a &'b U }, + W, + } + + enum TeeYooOutlivesAyBeeIsDebug<'a, 'b, T, U: 'a + 'b + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + V(T, &'a &'b U), + W, + } + + enum TeeYooIsDebugOutlivesAyBee<'a, 'b, T, U: Debug + 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: T, yoo: &'a &'b U }, + W, + } + + enum TeeOutlivesAyBeeYooIsDebug<'a, 'b, T: 'a + 'b, U: Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a &'b T, U), + W, + } + + enum TeeYooWhereOutlivesAy<'a, T, U> where U: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: T }, + W(&'a U), + } + + enum TeeYooWhereOutlivesAyIsDebug<'a, T, U> where U: 'a + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: T, yoo: &'a U }, + W, + } + + enum TeeYooWhereIsDebugOutlivesAy<'a, T, U> where U: Debug + 'a { +// { dg-error "" "" { target *-*-* } .-1 } + V(T, &'a U), + W, + } + + enum TeeOutlivesAyYooWhereIsDebug<'a, T: 'a, U> where U: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a T }, + W(U), + } + + enum TeeYooWhereOutlivesAyBee<'a, 'b, T, U> where U: 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: T, yoo: &'a &'b U }, + W, + } + + enum TeeYooWhereOutlivesAyBeeIsDebug<'a, 'b, T, U> where U: 'a + 'b + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + V(T, &'a &'b U), + W, + } + + enum TeeYooWhereIsDebugOutlivesAyBee<'a, 'b, T, U> where U: Debug + 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: T }, + W(&'a &'b U), + } + + enum TeeOutlivesAyBeeYooWhereIsDebug<'a, 'b, T: 'a + 'b, U> where U: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a &'b T, yoo: U }, + W, + } + + enum TeeWhereOutlivesAyYooWhereIsDebug<'a, T, U> where T: 'a, U: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a T, U), + W, + } + + enum TeeWhereOutlivesAyBeeYooWhereIsDebug<'a, 'b, T, U> where T: 'a + 'b, U: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a &'b T }, + W(U), + } + + enum BeeOutlivesAy<'a, 'b: 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a &'b () }, + } + + enum BeeWhereOutlivesAy<'a, 'b> where 'b: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a &'b ()), + } + + enum BeeOutlivesAyTee<'a, 'b: 'a, T> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a &'b T }, + W, + } + + enum BeeWhereOutlivesAyTee<'a, 'b, T> where 'b: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a &'b T), + W, + } + + enum BeeWhereOutlivesAyTeeWhereBee<'a, 'b, T> where 'b: 'a, T: 'b { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a &'b T), + } + + enum BeeWhereOutlivesAyTeeWhereAyBee<'a, 'b, T> where 'b: 'a, T: 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a &'b T), + W, + } + + enum BeeOutlivesAyTeeDebug<'a, 'b: 'a, T: Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + V { tee: &'a &'b T }, + } + + enum BeeWhereOutlivesAyTeeWhereDebug<'a, 'b, T> where 'b: 'a, T: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + V(&'a &'b T), + } +} + +mod unions { + use std::fmt::Debug; + + union TeeOutlivesAy<'a, T: 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T + } + + union TeeOutlivesAyIsDebug<'a, T: 'a + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T + } + + union TeeIsDebugOutlivesAy<'a, T: Debug + 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T + } + + union TeeOutlivesAyBee<'a, 'b, T: 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + union TeeOutlivesAyBeeIsDebug<'a, 'b, T: 'a + 'b + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + union TeeIsDebugOutlivesAyBee<'a, 'b, T: Debug + 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + union TeeWhereOutlivesAy<'a, T> where T: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T + } + + union TeeWhereOutlivesAyIsDebug<'a, T> where T: 'a + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T + } + + union TeeWhereIsDebugOutlivesAy<'a, T> where T: Debug + 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T + } + + union TeeWhereOutlivesAyBee<'a, 'b, T> where T: 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + union TeeWhereOutlivesAyBeeIsDebug<'a, 'b, T> where T: 'a + 'b + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + union TeeWhereIsDebugOutlivesAyBee<'a, 'b, T> where T: Debug + 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T + } + + union TeeYooOutlivesAy<'a, T, U: 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a U + } + + union TeeYooOutlivesAyIsDebug<'a, T, U: 'a + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a U + } + + union TeeYooIsDebugOutlivesAy<'a, T, U: Debug + 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a U + } + + union TeeOutlivesAyYooIsDebug<'a, T: 'a, U: Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: *const U + } + + union TeeYooOutlivesAyBee<'a, 'b, T, U: 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a &'b U + } + + union TeeYooOutlivesAyBeeIsDebug<'a, 'b, T, U: 'a + 'b + Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a &'b U + } + + union TeeYooIsDebugOutlivesAyBee<'a, 'b, T, U: Debug + 'a + 'b> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a &'b U + } + + union TeeOutlivesAyBeeYooIsDebug<'a, 'b, T: 'a + 'b, U: Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + yoo: *const U + } + + union TeeYooWhereOutlivesAy<'a, T, U> where U: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a U + } + + union TeeYooWhereOutlivesAyIsDebug<'a, T, U> where U: 'a + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a U + } + + union TeeYooWhereIsDebugOutlivesAy<'a, T, U> where U: Debug + 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a U + } + + union TeeOutlivesAyYooWhereIsDebug<'a, T: 'a, U> where U: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: *const U + } + + union TeeYooWhereOutlivesAyBee<'a, 'b, T, U> where U: 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a &'b U + } + + union TeeYooWhereOutlivesAyBeeIsDebug<'a, 'b, T, U> where U: 'a + 'b + Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a &'b U + } + + union TeeYooWhereIsDebugOutlivesAyBee<'a, 'b, T, U> where U: Debug + 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: *const T, + yoo: &'a &'b U + } + + union TeeOutlivesAyBeeYooWhereIsDebug<'a, 'b, T: 'a + 'b, U> where U: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + yoo: *const U + } + + union TeeWhereOutlivesAyYooWhereIsDebug<'a, T, U> where T: 'a, U: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a T, + yoo: *const U + } + + union TeeWhereOutlivesAyBeeYooWhereIsDebug<'a, 'b, T, U> where T: 'a + 'b, U: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + yoo: *const U + } + + union BeeOutlivesAy<'a, 'b: 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b (), + } + + union BeeWhereOutlivesAy<'a, 'b> where 'b: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b (), + } + + union BeeOutlivesAyTee<'a, 'b: 'a, T> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + union BeeWhereOutlivesAyTee<'a, 'b, T> where 'b: 'a { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + union BeeWhereOutlivesAyTeeWhereBee<'a, 'b, T> where 'b: 'a, T: 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + union BeeWhereOutlivesAyTeeWhereAyBee<'a, 'b, T> where 'b: 'a, T: 'a + 'b { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + union BeeOutlivesAyTeeDebug<'a, 'b: 'a, T: Debug> { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } + + union BeeWhereOutlivesAyTeeWhereDebug<'a, 'b, T> where 'b: 'a, T: Debug { +// { dg-error "" "" { target *-*-* } .-1 } + tee: &'a &'b T, + } +} + + +// But outlives inference for 'static lifetimes is under a separate +// feature-gate for now +// (https://github.com/rust-lang/rust/issues/44493#issuecomment-407846046). +struct StaticRef { + field: &'static T +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-nested-empty-paths.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-nested-empty-paths.rs new file mode 100644 index 000000000000..f90dc0a890b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-nested-empty-paths.rs @@ -0,0 +1,31 @@ +// run-rustfix + +#![feature(rust_2018_preview, crate_visibility_modifier)] +#![deny(absolute_paths_not_starting_with_crate)] +#![allow(unused_imports)] +#![allow(dead_code)] + +crate mod foo { + crate mod bar { + crate mod baz { } + crate mod baz1 { } + + crate struct XX; + } +} + +use foo::{bar::{baz::{}}}; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +use foo::{bar::{XX, baz::{}}}; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +use foo::{bar::{baz::{}, baz1::{}}}; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-nested-paths.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-nested-paths.rs new file mode 100644 index 000000000000..1a90997588fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-nested-paths.rs @@ -0,0 +1,28 @@ +// run-rustfix + +#![feature(rust_2018_preview, crate_visibility_modifier)] +#![deny(absolute_paths_not_starting_with_crate)] + +use foo::{a, b}; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +mod foo { + crate fn a() {} + crate fn b() {} + crate fn c() {} +} + +fn main() { + a(); + b(); + + { + use foo::{self as x, c}; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + x::a(); + c(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-paths-2018.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-paths-2018.rs new file mode 100644 index 000000000000..a3db60898b0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-paths-2018.rs @@ -0,0 +1,11 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 +// compile-flags:--extern edition_lint_paths +// aux-build:edition-lint-paths.rs + +#![deny(absolute_paths_not_starting_with_crate)] + +edition_lint_paths::macro_2015!(); // OK + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-paths.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-paths.rs new file mode 100644 index 000000000000..5b53c8e8adcf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-paths.rs @@ -0,0 +1,72 @@ +// aux-build:edition-lint-paths.rs +// run-rustfix + +#![feature(rust_2018_preview)] +#![deny(absolute_paths_not_starting_with_crate)] +#![allow(unused)] + +extern crate edition_lint_paths; + +pub mod foo { + use edition_lint_paths; + use ::bar::Bar; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + use super::bar::Bar2; + use crate::bar::Bar3; + + use bar; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + use crate::{bar as something_else}; + + use {Bar as SomethingElse, main}; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + + use crate::{Bar as SomethingElse2, main as another_main}; + + pub fn test() { + } + + pub trait SomeTrait { } +} + +use bar::Bar; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +pub mod bar { + use edition_lint_paths as foo; + pub struct Bar; + pub type Bar2 = Bar; + pub type Bar3 = Bar; +} + +mod baz { + use *; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +impl ::foo::SomeTrait for u32 { } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() { + let x = ::bar::Bar; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + let x = bar::Bar; + let x = crate::bar::Bar; + let x = self::bar::Bar; + foo::test(); + + { + use edition_lint_paths as bar; + edition_lint_paths::foo(); + bar::foo(); + ::edition_lint_paths::foo(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-uninferable-outlives.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-uninferable-outlives.rs new file mode 100644 index 000000000000..babaad12f77b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/edition-lint-uninferable-outlives.rs @@ -0,0 +1,31 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(unused)] +#![deny(explicit_outlives_requirements)] + +// A case where we can't infer the outlives requirement. Example copied from +// RFC 2093. +// (https://rust-lang.github.io/rfcs/2093-infer-outlives.html +// #where-explicit-annotations-would-still-be-required) + + +trait MakeRef<'a> { + type Type; +} + +impl<'a, T> MakeRef<'a> for Vec + where T: 'a // still required +{ + type Type = &'a T; +} + + +struct Foo<'a, T> + where T: 'a // still required, not inferred from `field` +{ + field: as MakeRef<'a>>::Type +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-idiomatic-in-2018.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-idiomatic-in-2018.rs new file mode 100644 index 000000000000..c9f55d86ae9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-idiomatic-in-2018.rs @@ -0,0 +1,29 @@ +// aux-build:edition-lint-paths.rs +// run-rustfix +// compile-flags:--extern edition_lint_paths +// edition:2018 + +// The "normal case". Ideally we would remove the `extern crate` here, +// but we don't. + +#![deny(rust_2018_idioms)] +#![allow(dead_code)] + +extern crate edition_lint_paths; +// { dg-error "" "" { target *-*-* } .-1 } + +// Shouldn't suggest changing to `use`, as `bar` +// would no longer be added to the prelude which could cause +// compilation errors for imports that use `bar` in other +// modules. See #57672. +extern crate edition_lint_paths as bar; + +fn main() { + // This is not considered to *use* the `extern crate` in Rust 2018: + use edition_lint_paths::foo; + foo(); + + // But this should be a use of the (renamed) crate: + crate::bar::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-idiomatic.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-idiomatic.rs new file mode 100644 index 000000000000..38dddf38d30e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-idiomatic.rs @@ -0,0 +1,19 @@ +// run-pass +// aux-build:edition-lint-paths.rs +// compile-flags:--extern edition_lint_paths +// run-rustfix + +// The "normal case". Ideally we would remove the `extern crate` here, +// but we don't. + +#![feature(rust_2018_preview)] +#![deny(absolute_paths_not_starting_with_crate)] + +extern crate edition_lint_paths; + +use edition_lint_paths::foo; + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-referenced-by-self-path.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-referenced-by-self-path.rs new file mode 100644 index 000000000000..e249c8a026d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-referenced-by-self-path.rs @@ -0,0 +1,18 @@ +// run-pass +// aux-build:edition-lint-paths.rs +// run-rustfix + +// Oddball: `edition_lint_paths` is accessed via this `self` path +// rather than being accessed directly. Unless we rewrite that path, +// we can't drop the extern crate. + +#![feature(rust_2018_preview)] +#![deny(absolute_paths_not_starting_with_crate)] + +extern crate edition_lint_paths; +use self::edition_lint_paths::foo; + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-rename.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-rename.rs new file mode 100644 index 000000000000..4c2f845f8b80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-rename.rs @@ -0,0 +1,19 @@ +// aux-build:edition-lint-paths.rs +// run-rustfix + +// Oddball: crate is renamed, making it harder for us to rewrite +// paths. We don't (and we leave the `extern crate` in place). + +#![feature(rust_2018_preview)] +#![deny(absolute_paths_not_starting_with_crate)] + +extern crate edition_lint_paths as my_crate; + +use my_crate::foo; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-submod.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-submod.rs new file mode 100644 index 000000000000..ff07e18a9e51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/extern-crate-submod.rs @@ -0,0 +1,26 @@ +// aux-build:edition-lint-paths.rs +// run-rustfix + +// Oddball: extern crate appears in a submodule, making it harder for +// us to rewrite paths. We don't (and we leave the `extern crate` in +// place). + +#![feature(rust_2018_preview)] +#![deny(absolute_paths_not_starting_with_crate)] + +mod m { + // Because this extern crate does not appear at the root, we + // ignore it altogether. + pub extern crate edition_lint_paths; +} + +// And we don't being smart about paths like this, even though you +// *could* rewrite it to `use edition_lint_paths::foo` +use m::edition_lint_paths::foo; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/future-proofing-locals.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/future-proofing-locals.rs new file mode 100644 index 000000000000..35fbf7380049 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/future-proofing-locals.rs @@ -0,0 +1,51 @@ +// edition:2018 + +#![allow(non_camel_case_types)] +#![allow(unused_imports)] + +mod T { + pub struct U; +} +mod x { + pub struct y; +} + +fn type_param() { + use T as _; // { dg-error "" "" { target *-*-* } } + use T::U; // { dg-error "" "" { target *-*-* } } + use T::*; // { dg-error "" "" { target *-*-* } } +} + +fn self_import() { + use T; // { dg-error "" "" { target *-*-* } } +} + +fn let_binding() { + let x = 10; + + use x as _; // { dg-error "" "" { target *-*-* } } + use x::y; // OK + use x::*; // OK +} + +fn param_binding(x: u8) { + use x; // { dg-error "" "" { target *-*-* } } +} + +fn match_binding() { + match 0 { + x => { + use x; // { dg-error "" "" { target *-*-* } } + } + } +} + +fn nested() { + let x = 10; + + use {T as _, x}; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/issue-51008-1.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/issue-51008-1.rs new file mode 100644 index 000000000000..d704cf831d1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/issue-51008-1.rs @@ -0,0 +1,16 @@ +// Regression test for #51008 -- the anonymous lifetime in `&i32` was +// being incorrectly considered part of the "elided lifetimes" from +// the impl. +// +// run-pass + +#![feature(rust_2018_preview)] + +trait A { + +} + +impl A for F where F: PartialEq { } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/issue-51008.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/issue-51008.rs new file mode 100644 index 000000000000..3725394e94d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/issue-51008.rs @@ -0,0 +1,16 @@ +// Regression test for #51008 -- the anonymous lifetime in `&i32` was +// being incorrectly considered part of the "elided lifetimes" from +// the impl. +// +// run-pass + +#![feature(rust_2018_preview)] + +trait A { + +} + +impl A for F where F: FnOnce(&i32) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/issue-52202-use-suggestions.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/issue-52202-use-suggestions.rs new file mode 100644 index 000000000000..744ad4926bac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/issue-52202-use-suggestions.rs @@ -0,0 +1,14 @@ +// edition:2018 + +// The local `use` suggestion should start with `crate::` (but the +// standard-library suggestions should not, obviously). + +mod plumbing { + pub struct Drain; +} + +fn main() { + let _d = Drain {}; +// { dg-error ".E0422." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/issue-54006.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/issue-54006.rs new file mode 100644 index 000000000000..72a902c2ece4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/issue-54006.rs @@ -0,0 +1,14 @@ +// edition:2018 + +#![no_std] +#![crate_type = "lib"] + +use alloc::vec; +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +pub fn foo() { + let mut xs = vec![]; +// { dg-error "" "" { target *-*-* } .-1 } + xs.push(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs new file mode 100644 index 000000000000..65c0aae204b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs @@ -0,0 +1,16 @@ +// aux-build:edition-lint-paths.rs +// run-rustfix +// compile-flags:--extern edition_lint_paths --cfg blandiloquence +// edition:2018 + +#![deny(rust_2018_idioms)] +#![allow(dead_code)] + +// The suggestion span should include the attribute. + +#[cfg(blandiloquence)] // { help "" "" { target *-*-* } } +extern crate edition_lint_paths; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/local-path-suggestions-2015.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/local-path-suggestions-2015.rs new file mode 100644 index 000000000000..ba898842e595 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/local-path-suggestions-2015.rs @@ -0,0 +1,27 @@ +// aux-build:baz.rs +// compile-flags:--extern baz +// edition:2015 + +// This test exists to demonstrate the behaviour of the import suggestions +// from the `local-path-suggestions-2018.rs` test when not using the 2018 edition. + +extern crate baz as aux_baz; + +mod foo { + pub type Bar = u32; +} + +mod baz { + use foo::Bar; + + fn baz() { + let x: Bar = 22; + } +} + +use foo::Bar; + +use foobar::Baz; // { dg-error ".E0432." "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/local-path-suggestions-2018.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/local-path-suggestions-2018.rs new file mode 100644 index 000000000000..bfb30337ba2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/local-path-suggestions-2018.rs @@ -0,0 +1,22 @@ +// aux-build:baz.rs +// compile-flags:--extern baz +// edition:2018 + +mod foo { + pub type Bar = u32; +} + +mod bazz { + use foo::Bar; // { dg-error ".E0432." "" { target *-*-* } } + + fn baz() { + let x: Bar = 22; + } +} + +use foo::Bar; + +use foobar::Baz; // { dg-error ".E0432." "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/macro-use-warned-against.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/macro-use-warned-against.rs new file mode 100644 index 000000000000..721fee85834b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/macro-use-warned-against.rs @@ -0,0 +1,15 @@ +// aux-build:macro-use-warned-against.rs +// aux-build:macro-use-warned-against2.rs +// check-pass + +#![warn(macro_use_extern_crate, unused)] + +#[macro_use] // { dg-warning "" "" { target *-*-* } } +extern crate macro_use_warned_against; +#[macro_use] // { dg-warning "" "" { target *-*-* } } +extern crate macro_use_warned_against2; + +fn main() { + foo!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/proc-macro-crate-in-paths.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/proc-macro-crate-in-paths.rs new file mode 100644 index 000000000000..3ca3a1449dfc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/proc-macro-crate-in-paths.rs @@ -0,0 +1,17 @@ +// build-pass (FIXME(62277): could be check-pass?) +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![deny(rust_2018_compatibility)] +#![feature(rust_2018_preview)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Template, attributes(template))] +pub fn derive_template(input: TokenStream) -> TokenStream { + input +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/remove-extern-crate.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/remove-extern-crate.rs new file mode 100644 index 000000000000..a7ec9e145741 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/remove-extern-crate.rs @@ -0,0 +1,40 @@ +// run-rustfix +// edition:2018 +// check-pass +// aux-build:remove-extern-crate.rs +// compile-flags:--extern remove_extern_crate + +#![warn(rust_2018_idioms)] + +extern crate core; // { dg-warning "" "" { target *-*-* } } +// Shouldn't suggest changing to `use`, as `another_name` +// would no longer be added to the prelude which could cause +// compilation errors for imports that use `another_name` in other +// modules. See #57672. +extern crate core as another_name; +use remove_extern_crate; +#[macro_use] +extern crate remove_extern_crate as something_else; + +// Shouldn't suggest changing to `use`, as the `alloc` +// crate is not in the extern prelude - see #54381. +extern crate alloc; + +fn main() { + another_name::mem::drop(3); + another::foo(); + remove_extern_crate::foo!(); + bar!(); + alloc::vec![5]; +} + +mod another { + extern crate core; // { dg-warning "" "" { target *-*-* } } + use remove_extern_crate; + + pub fn foo() { + core::mem::drop(4); + remove_extern_crate::foo!(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/suggestions-not-always-applicable.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/suggestions-not-always-applicable.rs new file mode 100644 index 000000000000..b82ed54b931b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/suggestions-not-always-applicable.rs @@ -0,0 +1,28 @@ +// aux-build:suggestions-not-always-applicable.rs +// edition:2015 +// run-rustfix +// rustfix-only-machine-applicable +// check-pass + +#![feature(rust_2018_preview)] +#![warn(rust_2018_compatibility)] + +extern crate suggestions_not_always_applicable as foo; + +pub struct Foo; + +mod test { + use crate::foo::foo; + + #[foo] // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-3 } +// { dg-warning "" "" { target *-*-* } .-4 } + fn main() { + } +} + +fn main() { + test::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/trait-import-suggestions.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/trait-import-suggestions.rs new file mode 100644 index 000000000000..769f824d8557 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/trait-import-suggestions.rs @@ -0,0 +1,32 @@ +// edition:2018 +// aux-build:trait-import-suggestions.rs +// compile-flags:--extern trait-import-suggestions + +mod foo { + mod foobar { + pub(crate) trait Foobar { + fn foobar(&self) { } + } + + impl Foobar for u32 { } + } + + pub(crate) trait Bar { + fn bar(&self) { } + } + + impl Bar for u32 { } + + fn in_foo() { + let x: u32 = 22; + x.foobar(); // { dg-error ".E0599." "" { target *-*-* } } + } +} + +fn main() { + let x: u32 = 22; + x.bar(); // { dg-error ".E0599." "" { target *-*-* } } + x.baz(); // { dg-error ".E0599." "" { target *-*-* } } + let y = u32::from_str("33"); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/try-ident.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/try-ident.rs new file mode 100644 index 000000000000..c5e3a8b4b1a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/try-ident.rs @@ -0,0 +1,16 @@ +// run-rustfix +// check-pass + +#![warn(rust_2018_compatibility)] + +fn main() { + try(); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn try() { +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/try-macro.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/try-macro.rs new file mode 100644 index 000000000000..1745a78e087a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/try-macro.rs @@ -0,0 +1,19 @@ +// Test that `try!` macros are rewritten. + +// run-rustfix +// check-pass + +#![warn(rust_2018_compatibility)] +#![allow(dead_code)] +#![allow(deprecated)] + +fn foo() -> Result { + let x: Result = Ok(22); + try!(x); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + Ok(44) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity-macros-nested.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity-macros-nested.rs new file mode 100644 index 000000000000..aa7d09e1df56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity-macros-nested.rs @@ -0,0 +1,22 @@ +// edition:2018 + +// This test is similar to `ambiguity-macros.rs`, but nested in a module. + +#![allow(non_camel_case_types)] + +mod foo { + pub use std::io; +// { dg-error ".E0659." "" { target *-*-* } .-1 } + + macro_rules! m { + () => { + mod std { + pub struct io; + } + } + } + m!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity-macros.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity-macros.rs new file mode 100644 index 000000000000..56349eef73cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity-macros.rs @@ -0,0 +1,20 @@ +// edition:2018 + +// This test is similar to `ambiguity.rs`, but with macros defining local items. + +#![allow(non_camel_case_types)] + +use std::io; +// { dg-error ".E0659." "" { target *-*-* } .-1 } + +macro_rules! m { + () => { + mod std { + pub struct io; + } + } +} +m!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity-nested.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity-nested.rs new file mode 100644 index 000000000000..5ba1851c71e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity-nested.rs @@ -0,0 +1,17 @@ +// edition:2018 + +// This test is similar to `ambiguity.rs`, but nested in a module. + +#![allow(non_camel_case_types)] + +mod foo { + pub use std::io; +// { dg-error ".E0659." "" { target *-*-* } .-1 } + + mod std { + pub struct io; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity.rs new file mode 100644 index 000000000000..8ca7a04a0a62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/ambiguity.rs @@ -0,0 +1,13 @@ +// edition:2018 + +#![allow(non_camel_case_types)] + +use std::io; +// { dg-error ".E0659." "" { target *-*-* } .-1 } + +mod std { + pub struct io; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs new file mode 100644 index 000000000000..9505814ecf26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs @@ -0,0 +1,6 @@ +// edition:2018 + +pub use ignore as built_in_attr; +pub use u8 as built_in_type; +pub use rustfmt as tool_mod; + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/auxiliary/issue-56596-2.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/auxiliary/issue-56596-2.rs new file mode 100644 index 000000000000..4e6ebca46746 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/auxiliary/issue-56596-2.rs @@ -0,0 +1,2 @@ +pub extern crate core; + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/auxiliary/issue-56596.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/auxiliary/issue-56596.rs new file mode 100644 index 000000000000..bec88df13c04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/auxiliary/issue-56596.rs @@ -0,0 +1,2 @@ +// Nothing here + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs new file mode 100644 index 000000000000..a577ff04a4e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs @@ -0,0 +1,21 @@ +// edition:2018 + +mod my { + pub mod sub { + pub fn bar() {} + } +} + +mod sub { + pub fn bar() {} +} + +fn foo() { + use my::sub; + { + use sub::bar; // { dg-error ".E0659." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/block-scoped-shadow.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/block-scoped-shadow.rs new file mode 100644 index 000000000000..dfc9687fadb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/block-scoped-shadow.rs @@ -0,0 +1,22 @@ +// edition:2018 + +#![allow(non_camel_case_types)] + +enum Foo {} + +struct std; + +fn main() { + enum Foo { A, B } + use Foo::*; +// { dg-error ".E0659." "" { target *-*-* } .-1 } + + let _ = (A, B); + + fn std() {} + enum std {} + use std as foo; +// { dg-error ".E0659." "" { target *-*-* } .-1 } +// { dg-error ".E0659." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/cross-crate.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/cross-crate.rs new file mode 100644 index 000000000000..c5206a7b4a0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/cross-crate.rs @@ -0,0 +1,13 @@ +// edition:2018 +// aux-build:cross-crate.rs + +extern crate cross_crate; +use cross_crate::*; + +#[built_in_attr] // { dg-error "" "" { target *-*-* } } +#[tool_mod::skip] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +fn main() { + let _: built_in_type; // OK +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/deadlock.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/deadlock.rs new file mode 100644 index 000000000000..9df5f4a9123d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/deadlock.rs @@ -0,0 +1,8 @@ +// edition:2018 +// compile-flags:--extern foo --extern bar + +use foo::bar; // { dg-error ".E0463." "" { target *-*-* } } +use bar::foo; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/fn-local-enum.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/fn-local-enum.rs new file mode 100644 index 000000000000..b7299e191521 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/fn-local-enum.rs @@ -0,0 +1,14 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 + +fn main() { + enum E { A, B, C } + + use E::*; + match A { + A => {} + B => {} + C => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/from-decl-macro.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/from-decl-macro.rs new file mode 100644 index 000000000000..acce0ec995c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/from-decl-macro.rs @@ -0,0 +1,13 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 + +#![feature(decl_macro)] + +macro check() { + ::std::vec::Vec::::new() +} + +fn main() { + check!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/issue-54253.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/issue-54253.rs new file mode 100644 index 000000000000..df224fe7e72b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/issue-54253.rs @@ -0,0 +1,18 @@ +// edition:2018 + +// Dummy import that previously introduced uniform path canaries. +use std; + +// fn version() -> &'static str {""} + +mod foo { + // Error wasn't reported, despite `version` being commented out above. + use crate::version; // { dg-error ".E0432." "" { target *-*-* } } + + fn bar() { + version(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/issue-56596-2.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/issue-56596-2.rs new file mode 100644 index 000000000000..a193ad283404 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/issue-56596-2.rs @@ -0,0 +1,12 @@ +// check-pass +// edition:2018 +// compile-flags: --extern issue_56596_2 +// aux-build:issue-56596-2.rs + +mod m { + use core::any; + pub use issue_56596_2::*; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/issue-56596.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/issue-56596.rs new file mode 100644 index 000000000000..80723649c821 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/issue-56596.rs @@ -0,0 +1,15 @@ +// edition:2018 +// compile-flags: --extern issue_56596 +// aux-build:issue-56596.rs + +#![feature(uniform_paths)] + +mod m { + pub mod issue_56596 {} +} + +use m::*; +use issue_56596; // { dg-error ".E0659." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/macro-rules.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/macro-rules.rs new file mode 100644 index 000000000000..af1189d2d042 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/macro-rules.rs @@ -0,0 +1,44 @@ +// edition:2018 + +#![feature(decl_macro)] + +mod m1 { + // Non-exported legacy macros are treated as `pub(crate)`. + macro_rules! legacy_macro { () => () } + + use legacy_macro as _; // OK + pub(crate) use legacy_macro as _; // OK + pub use legacy_macro as _; // { dg-error ".E0364." "" { target *-*-* } } +} + +mod m2 { + macro_rules! legacy_macro { () => () } + + #[allow(non_camel_case_types)] + type legacy_macro = u8; + + // Legacy macro imports don't prevent names from other namespaces from being imported. + use legacy_macro as _; // OK +} + +mod m3 { + macro legacy_macro() {} + + fn f() { + macro_rules! legacy_macro { () => () } + + // Legacy macro imports create ambiguities with other names in the same namespace. + use legacy_macro as _; // { dg-error ".E0659." "" { target *-*-* } } + } +} + +mod exported { + // Exported legacy macros are treated as `pub`. + #[macro_export] + macro_rules! legacy_macro { () => () } + + pub use legacy_macro as _; // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/prelude-fail-2.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/prelude-fail-2.rs new file mode 100644 index 000000000000..1dd3dbe94378 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/prelude-fail-2.rs @@ -0,0 +1,22 @@ +// edition:2018 + +// Built-in attribute +use inline as imported_inline; +mod builtin { + pub use inline as imported_inline; +} + +// Tool module +use rustfmt as imported_rustfmt; +mod tool_mod { + pub use rustfmt as imported_rustfmt; +} + +#[imported_inline] // { dg-error "" "" { target *-*-* } } +#[builtin::imported_inline] // { dg-error "" "" { target *-*-* } } +#[imported_rustfmt::skip] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[tool_mod::imported_rustfmt::skip] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/prelude-fail.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/prelude-fail.rs new file mode 100644 index 000000000000..fe53d6feca78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/prelude-fail.rs @@ -0,0 +1,7 @@ +// edition:2018 + +// Tool attribute +use rustfmt::skip as imported_rustfmt_skip; // { dg-error ".E0432." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/prelude.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/prelude.rs new file mode 100644 index 000000000000..1867e068c67e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/prelude.rs @@ -0,0 +1,23 @@ +// build-pass (FIXME(62277): could be check-pass?) +// edition:2018 + +// Macro imported with `#[macro_use] extern crate` +use vec as imported_vec; + +// Standard library prelude +use Vec as ImportedVec; + +// Built-in type +use u8 as imported_u8; + +// Built-in macro +use env as env_imported; + +type A = imported_u8; + +fn main() { + imported_vec![0]; + ImportedVec::::new(); + env_imported!("PATH"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/redundant.rs b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/redundant.rs new file mode 100644 index 000000000000..85d6010c669b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rust-2018/uniform-paths/redundant.rs @@ -0,0 +1,21 @@ +// run-pass +// edition:2018 + +use std; +use std::io; + +mod foo { + pub use std as my_std; +} + +mod bar { + pub use std::{self}; +} + +fn main() { + io::stdout(); + self::std::io::stdout(); + foo::my_std::io::stdout(); + bar::std::io::stdout(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rustc-args-required-const.rs b/gcc/testsuite/rust/rustc/ui/rustc-args-required-const.rs new file mode 100644 index 000000000000..e9bba812449f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rustc-args-required-const.rs @@ -0,0 +1,28 @@ +#![feature(rustc_attrs, const_fn)] + +#[rustc_args_required_const(0)] +fn foo(_a: i32) { +} + +#[rustc_args_required_const(1)] +fn bar(_a: i32, _b: i32) { +} + +const A: i32 = 3; + +const fn baz() -> i32 { + 3 +} + +fn main() { + foo(2); + foo(2 + 3); + const BAZ: i32 = baz(); + foo(BAZ); + let a = 4; + foo(A); + foo(a); // { dg-error "" "" { target *-*-* } } + bar(a, 3); + bar(a, a); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rustc-args-required-const2.rs b/gcc/testsuite/rust/rustc/ui/rustc-args-required-const2.rs new file mode 100644 index 000000000000..4c166bf4c19d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rustc-args-required-const2.rs @@ -0,0 +1,11 @@ +#![feature(rustc_attrs, const_fn)] + +#[rustc_args_required_const(0)] +fn foo(_a: i32) { +} + +fn main() { + let a = foo; // { dg-error "" "" { target *-*-* } } + a(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/rustc-error.rs b/gcc/testsuite/rust/rustc/ui/rustc-error.rs new file mode 100644 index 000000000000..664e1d4c5bc7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rustc-error.rs @@ -0,0 +1,7 @@ +#![feature(rustc_attrs)] + +#[rustc_error] +fn main() { +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/rustc-rust-log.rs b/gcc/testsuite/rust/rustc/ui/rustc-rust-log.rs new file mode 100644 index 000000000000..711be6cf5b91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rustc-rust-log.rs @@ -0,0 +1,15 @@ +// run-pass +// This test is just checking that we won't ICE if logging is turned +// on; don't bother trying to compare that (copious) output. (Note +// also that this test potentially silly, since we do not build+test +// debug versions of rustc as part of our continuous integration +// process...) +// +// dont-check-compiler-stdout +// dont-check-compiler-stderr +// compile-flags: --error-format human +// aux-build: rustc-rust-log-aux.rs +// rustc-env:RUSTC_LOG=debug + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/rvalue-static-promotion.rs b/gcc/testsuite/rust/rustc/ui/rvalue-static-promotion.rs new file mode 100644 index 000000000000..d3a2d77d7c11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/rvalue-static-promotion.rs @@ -0,0 +1,20 @@ +// run-pass + +use std::cell::Cell; + +const NONE_CELL_STRING: Option> = None; + +struct Foo(T); +impl Foo { + const FOO: Option> = None; +} + +fn main() { + let _: &'static u32 = &42; + let _: &'static Option = &None; + + // We should be able to peek at consts and see they're None. + let _: &'static Option> = &NONE_CELL_STRING; + let _: &'static Option> = &Foo::FOO; +} + diff --git a/gcc/testsuite/rust/rustc/ui/safe-extern-statics-mut.rs b/gcc/testsuite/rust/rustc/ui/safe-extern-statics-mut.rs new file mode 100644 index 000000000000..a215dcc5c51c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/safe-extern-statics-mut.rs @@ -0,0 +1,16 @@ +// aux-build:extern-statics.rs + +extern crate extern_statics; +use extern_statics::*; + +extern { + static mut B: u8; +} + +fn main() { + let b = B; // { dg-error ".E0133." "" { target *-*-* } } + let rb = &B; // { dg-error ".E0133." "" { target *-*-* } } + let xb = XB; // { dg-error ".E0133." "" { target *-*-* } } + let xrb = &XB; // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/safe-extern-statics.rs b/gcc/testsuite/rust/rustc/ui/safe-extern-statics.rs new file mode 100644 index 000000000000..e81fcb5056e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/safe-extern-statics.rs @@ -0,0 +1,16 @@ +// aux-build:extern-statics.rs + +extern crate extern_statics; +use extern_statics::*; + +extern { + static A: u8; +} + +fn main() { + let a = A; // { dg-error ".E0133." "" { target *-*-* } } + let ra = &A; // { dg-error ".E0133." "" { target *-*-* } } + let xa = XA; // { dg-error ".E0133." "" { target *-*-* } } + let xra = &XA; // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/sanitize/address.rs b/gcc/testsuite/rust/rustc/ui/sanitize/address.rs new file mode 100644 index 000000000000..ff8292df21c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sanitize/address.rs @@ -0,0 +1,21 @@ +// needs-sanitizer-support +// needs-sanitizer-address +// +// compile-flags: -Z sanitizer=address -O -g +// +// run-fail +// error-pattern: AddressSanitizer: stack-buffer-overflow +// error-pattern: 'xs' (line 15) <== Memory access at offset + +#![feature(test)] + +use std::hint::black_box; + +fn main() { + let xs = [0, 1, 2, 3]; + // Avoid optimizing everything out. + let xs = black_box(xs.as_ptr()); + let code = unsafe { *xs.offset(4) }; + std::process::exit(code); +} + diff --git a/gcc/testsuite/rust/rustc/ui/sanitize/badfree.rs b/gcc/testsuite/rust/rustc/ui/sanitize/badfree.rs new file mode 100644 index 000000000000..3fa81ef09d88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sanitize/badfree.rs @@ -0,0 +1,20 @@ +// needs-sanitizer-support +// needs-sanitizer-address +// +// compile-flags: -Z sanitizer=address -O +// +// run-fail +// error-pattern: AddressSanitizer: SEGV + +use std::ffi::c_void; + +extern "C" { + fn free(ptr: *mut c_void); +} + +fn main() { + unsafe { + free(1 as *mut c_void); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/sanitize/cfg.rs b/gcc/testsuite/rust/rustc/ui/sanitize/cfg.rs new file mode 100644 index 000000000000..5f86e7ba5505 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sanitize/cfg.rs @@ -0,0 +1,29 @@ +// Verifies that when compiling with -Zsanitizer=option, +// the `#[cfg(sanitize = "option")]` attribute is configured. + +// needs-sanitizer-support +// needs-sanitizer-address +// needs-sanitizer-leak +// needs-sanitizer-memory +// needs-sanitizer-thread +// check-pass +// revisions: address leak memory thread +//[address]compile-flags: -Zsanitizer=address --cfg address +//[leak]compile-flags: -Zsanitizer=leak --cfg leak +//[memory]compile-flags: -Zsanitizer=memory --cfg memory +//[thread]compile-flags: -Zsanitizer=thread --cfg thread + +#![feature(cfg_sanitize)] + +#[cfg(all(sanitize = "address", address))] +fn main() {} + +#[cfg(all(sanitize = "leak", leak))] +fn main() {} + +#[cfg(all(sanitize = "memory", memory))] +fn main() {} + +#[cfg(all(sanitize = "thread", thread))] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/sanitize/incompatible.rs b/gcc/testsuite/rust/rustc/ui/sanitize/incompatible.rs new file mode 100644 index 000000000000..7ff173b9c547 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sanitize/incompatible.rs @@ -0,0 +1,7 @@ +// compile-flags: -Z sanitizer=address -Z sanitizer=memory --target x86_64-unknown-linux-gnu +// error-pattern: error: `-Zsanitizer=address` is incompatible with `-Zsanitizer=memory` + +#![feature(no_core)] +#![no_core] +#![no_main] + diff --git a/gcc/testsuite/rust/rustc/ui/sanitize/inline-always.rs b/gcc/testsuite/rust/rustc/ui/sanitize/inline-always.rs new file mode 100644 index 000000000000..5fea7d024a7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sanitize/inline-always.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(no_sanitize)] + +#[inline(always)] +// { dg-note "" "" { target *-*-* } .-1 } +#[no_sanitize(address)] +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +fn x() { +} + +fn main() { + x() +} + diff --git a/gcc/testsuite/rust/rustc/ui/sanitize/issue-72154-lifetime-markers.rs b/gcc/testsuite/rust/rustc/ui/sanitize/issue-72154-lifetime-markers.rs new file mode 100644 index 000000000000..1361ac3b0115 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sanitize/issue-72154-lifetime-markers.rs @@ -0,0 +1,32 @@ +// Regression test for issue 72154, where the use of AddressSanitizer enabled +// emission of lifetime markers during codegen, while at the same time asking +// always inliner pass not to insert them. This eventually lead to a +// miscompilation which was subsequently detected by AddressSanitizer as UB. +// +// needs-sanitizer-support +// needs-sanitizer-address +// +// compile-flags: -Copt-level=0 -Zsanitizer=address +// run-pass + +pub struct Wrap { + pub t: [usize; 1] +} + +impl Wrap { + #[inline(always)] + pub fn new(t: [usize; 1]) -> Self { + Wrap { t } + } +} + +#[inline(always)] +pub fn assume_init() -> [usize; 1] { + [1234] +} + +fn main() { + let x: [usize; 1] = assume_init(); + Wrap::new(x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/sanitize/leak.rs b/gcc/testsuite/rust/rustc/ui/sanitize/leak.rs new file mode 100644 index 000000000000..9ae515d41ff3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sanitize/leak.rs @@ -0,0 +1,22 @@ +// needs-sanitizer-support +// needs-sanitizer-leak +// +// compile-flags: -Z sanitizer=leak -O +// +// run-fail +// error-pattern: LeakSanitizer: detected memory leaks + +#![feature(test)] + +use std::hint::black_box; +use std::mem; + +fn main() { + for _ in 0..10 { + let xs = vec![1, 2, 3]; + // Prevent compiler from removing the memory allocation. + let xs = black_box(xs); + mem::forget(xs); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/sanitize/memory.rs b/gcc/testsuite/rust/rustc/ui/sanitize/memory.rs new file mode 100644 index 000000000000..3202ad4d64ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sanitize/memory.rs @@ -0,0 +1,44 @@ +// needs-sanitizer-support +// needs-sanitizer-memory +// +// compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O +// +// run-fail +// error-pattern: MemorySanitizer: use-of-uninitialized-value +// error-pattern: Uninitialized value was created by an allocation +// error-pattern: in the stack frame of function 'random' +// +// This test case intentionally limits the usage of the std, +// since it will be linked with an uninstrumented version of it. + +#![feature(core_intrinsics)] +#![feature(start)] +#![feature(test)] + +use std::hint::black_box; +use std::mem::MaybeUninit; + +#[inline(never)] +#[no_mangle] +fn random() -> [isize; 32] { + let r = unsafe { MaybeUninit::uninit().assume_init() }; + // Avoid optimizing everything out. + black_box(r) +} + +#[inline(never)] +#[no_mangle] +fn xor(a: &[isize]) -> isize { + let mut s = 0; + for i in 0..a.len() { + s = s ^ a[i]; + } + s +} + +#[start] +fn main(_: isize, _: *const *const u8) -> isize { + let r = random(); + xor(&r) +} + diff --git a/gcc/testsuite/rust/rustc/ui/sanitize/new-llvm-pass-manager-thin-lto.rs b/gcc/testsuite/rust/rustc/ui/sanitize/new-llvm-pass-manager-thin-lto.rs new file mode 100644 index 000000000000..6625e514e048 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sanitize/new-llvm-pass-manager-thin-lto.rs @@ -0,0 +1,28 @@ +// Regression test for sanitizer function instrumentation passes not +// being run when compiling with new LLVM pass manager and ThinLTO. +// Note: The issue occurred only on non-zero opt-level. +// +// min-llvm-version: 9.0 +// needs-sanitizer-support +// needs-sanitizer-address +// +// no-prefer-dynamic +// revisions: opt0 opt1 +// compile-flags: -Znew-llvm-pass-manager=yes -Zsanitizer=address -Clto=thin +//[opt0]compile-flags: -Copt-level=0 +//[opt1]compile-flags: -Copt-level=1 +// run-fail +// error-pattern: ERROR: AddressSanitizer: stack-use-after-scope + +static mut P: *mut usize = std::ptr::null_mut(); + +fn main() { + unsafe { + { + let mut x = 0; + P = &mut x; + } + std::ptr::write_volatile(P, 123); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/sanitize/thread.rs b/gcc/testsuite/rust/rustc/ui/sanitize/thread.rs new file mode 100644 index 000000000000..75db3c914552 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sanitize/thread.rs @@ -0,0 +1,58 @@ +// Verifies that ThreadSanitizer is able to detect a data race in heap allocated +// memory block. +// +// Test case minimizes the use of the standard library to avoid its ambiguous +// status with respect to instrumentation (it could vary depending on whatever +// a function call is inlined or not). +// +// The conflicting data access is de-facto synchronized with a special TSAN +// barrier, which does not introduce synchronization from TSAN perspective, but +// is necessary to make the test robust. Without the barrier data race detection +// would occasionally fail, making test flaky. +// +// needs-sanitizer-support +// needs-sanitizer-thread +// +// compile-flags: -Z sanitizer=thread -O +// +// run-fail +// error-pattern: WARNING: ThreadSanitizer: data race +// error-pattern: Location is heap block of size 4 +// error-pattern: allocated by main thread + +#![feature(raw_ref_op)] +#![feature(rustc_private)] +extern crate libc; + +use std::mem; +use std::ptr; + +static mut BARRIER: u64 = 0; + +extern "C" { + fn __tsan_testonly_barrier_init(barrier: *mut u64, count: u32); + fn __tsan_testonly_barrier_wait(barrier: *mut u64); +} + +extern "C" fn start(c: *mut libc::c_void) -> *mut libc::c_void { + unsafe { + let c: *mut u32 = c.cast(); + *c += 1; + __tsan_testonly_barrier_wait(&raw mut BARRIER); + ptr::null_mut() + } +} + +fn main() { + unsafe { + __tsan_testonly_barrier_init(&raw mut BARRIER, 2); + let c: *mut u32 = Box::into_raw(Box::new(1)); + let mut t: libc::pthread_t = mem::zeroed(); + libc::pthread_create(&mut t, ptr::null(), start, c.cast()); + __tsan_testonly_barrier_wait(&raw mut BARRIER); + *c += 1; + libc::pthread_join(t, ptr::null_mut()); + Box::from_raw(c); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/sanitize/unsupported-target.rs b/gcc/testsuite/rust/rustc/ui/sanitize/unsupported-target.rs new file mode 100644 index 000000000000..e1da8b533af7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sanitize/unsupported-target.rs @@ -0,0 +1,7 @@ +// compile-flags: -Z sanitizer=leak --target i686-unknown-linux-gnu +// error-pattern: error: `-Zsanitizer=leak` only works with targets: + +#![feature(no_core)] +#![no_core] +#![no_main] + diff --git a/gcc/testsuite/rust/rustc/ui/sanitize/use-after-scope.rs b/gcc/testsuite/rust/rustc/ui/sanitize/use-after-scope.rs new file mode 100644 index 000000000000..5561251142f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sanitize/use-after-scope.rs @@ -0,0 +1,19 @@ +// needs-sanitizer-support +// needs-sanitizer-address +// +// compile-flags: -Zsanitizer=address +// run-fail +// error-pattern: ERROR: AddressSanitizer: stack-use-after-scope + +static mut P: *mut usize = std::ptr::null_mut(); + +fn main() { + unsafe { + { + let mut x = 0; + P = &mut x; + } + std::ptr::write_volatile(P, 123); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/save-analysis/emit-notifications.rs b/gcc/testsuite/rust/rustc/ui/save-analysis/emit-notifications.rs new file mode 100644 index 000000000000..57b48a61df73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/save-analysis/emit-notifications.rs @@ -0,0 +1,8 @@ +// build-pass (FIXME(62277): could be check-pass?) +// compile-flags: -Zsave-analysis --json artifacts +// compile-flags: --crate-type rlib --error-format=json +// ignore-pass +// ^-- needed because otherwise, the .stderr file changes with --pass check + +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/save-analysis/issue-59134-0.rs b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-59134-0.rs new file mode 100644 index 000000000000..6a4807567b53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-59134-0.rs @@ -0,0 +1,13 @@ +// compile-flags: -Zsave-analysis + +// Check that this doesn't ICE when processing associated const (field expr). + +pub fn f() { + trait Trait {} + impl dyn Trait { + const FLAG: u32 = bogus.field; // { dg-error ".E0425." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/save-analysis/issue-59134-1.rs b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-59134-1.rs new file mode 100644 index 000000000000..da60d2adb825 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-59134-1.rs @@ -0,0 +1,13 @@ +// compile-flags: -Zsave-analysis + +// Check that this doesn't ICE when processing associated const (type). + +fn func() { + trait Trait { + type MyType; + const CONST: Self::MyType = bogus.field; // { dg-error ".E0425." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/save-analysis/issue-63663.rs b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-63663.rs new file mode 100644 index 000000000000..686abaaebc5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-63663.rs @@ -0,0 +1,29 @@ +// check-pass +// compile-flags: -Zsave-analysis + +pub trait Trait { + type Assoc; +} + +pub struct A; + +trait Generic {} +impl Generic for () {} + +// Don't ICE when resolving type paths in return type `impl Trait` +fn assoc_in_opaque_type_bounds() -> impl Generic {} + +// Check that this doesn't ICE when processing associated const in formal +// argument and return type of functions defined inside function/method scope. +pub fn func() { + fn _inner1(_: U::Assoc) {} + fn _inner2() -> U::Assoc { unimplemented!() } + + impl A { + fn _inner1(self, _: U::Assoc) {} + fn _inner2(self) -> U::Assoc { unimplemented!() } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/save-analysis/issue-64659.rs b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-64659.rs new file mode 100644 index 000000000000..ee5a647aeaea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-64659.rs @@ -0,0 +1,11 @@ +// check-pass +// compile-flags: -Zsave-analysis + +trait Trait { type Assoc; } + +fn main() { + struct Data { + x: T::Assoc, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/save-analysis/issue-65411.rs b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-65411.rs new file mode 100644 index 000000000000..a7bdc0b4313f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-65411.rs @@ -0,0 +1,16 @@ +// check-pass +// compile-flags: -Zsave-analysis + +trait Trait { type Assoc; } +trait GenericTrait {} +struct Wrapper { b: B } + +fn func() { + // Processing associated path in impl block definition inside a function + // body does not ICE + impl GenericTrait for Wrapper {} +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/save-analysis/issue-65590.rs b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-65590.rs new file mode 100644 index 000000000000..91b08395cfeb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-65590.rs @@ -0,0 +1,22 @@ +// check-pass +// compile-flags: -Zsave-analysis +// edition:2018 + +// Async desugaring for return types in (associated) functions introduces a +// separate definition internally, which we need to take into account +// (or else we ICE). +trait Trait { type Assoc; } +struct Struct; + +async fn foobar() -> T::Assoc { + unimplemented!() +} + +impl Struct { + async fn foo(&self) -> T::Assoc { + unimplemented!() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/save-analysis/issue-68621.rs b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-68621.rs new file mode 100644 index 000000000000..ff99afb91fc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-68621.rs @@ -0,0 +1,18 @@ +// compile-flags: -Zsave-analysis + +#![feature(type_alias_impl_trait)] + +trait Trait {} + +trait Service { + type Future: Trait; +} + +struct Struct; + +impl Service for Struct { + type Future = impl Trait; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/save-analysis/issue-72267.rs b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-72267.rs new file mode 100644 index 000000000000..83795b2c31e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-72267.rs @@ -0,0 +1,8 @@ +// compile-flags: -Z save-analysis + +fn main() { + let _: Box<(dyn ?Sized)>; +// { dg-error ".E0224." "" { target *-*-* } .-1 } +// { dg-error ".E0224." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/save-analysis/issue-73020.rs b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-73020.rs new file mode 100644 index 000000000000..3f70a174ee83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-73020.rs @@ -0,0 +1,6 @@ +// compile-flags: -Zsave-analysis +use {self}; // { dg-error ".E0431." "" { target *-*-* } } + +fn main () { +} + diff --git a/gcc/testsuite/rust/rustc/ui/save-analysis/issue-73022.rs b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-73022.rs new file mode 100644 index 000000000000..07da1eed5a2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/save-analysis/issue-73022.rs @@ -0,0 +1,14 @@ +// build-pass +// compile-flags: -Zsave-analysis +enum Enum2 { + Variant8 { _field: bool }, +} + +impl Enum2 { + fn new_variant8() -> Enum2 { + Self::Variant8 { _field: true } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary-self-types-not-object-safe.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary-self-types-not-object-safe.rs new file mode 100644 index 000000000000..b41ae9eebf70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary-self-types-not-object-safe.rs @@ -0,0 +1,45 @@ +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + +use std::rc::Rc; + +trait Foo { + fn foo(self: &Rc) -> usize; +} + +trait Bar { + fn foo(self: &Rc) -> usize where Self: Sized; + fn bar(self: Rc) -> usize; +} + +impl Foo for usize { + fn foo(self: &Rc) -> usize { + **self + } +} + +impl Bar for usize { + fn foo(self: &Rc) -> usize { + **self + } + + fn bar(self: Rc) -> usize { + *self + } +} + +fn make_foo() { + let x = Rc::new(5usize) as Rc; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +} + +fn make_bar() { + let x = Rc::new(5usize) as Rc; + x.bar(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_nested.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_nested.rs new file mode 100644 index 000000000000..fd2f6820a4af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_nested.rs @@ -0,0 +1,37 @@ +// run-pass + +use { + std::{ + rc::Rc, + sync::Arc, + }, +}; + +#[derive(Default)] +struct Ty; + +trait Trait { + fn receive_trait(self: &Arc>>) -> u32; +} + +const TRAIT_MAGIC: u32 = 42; +const INHERENT_MAGIC: u32 = 1995; + +impl Trait for Ty { + fn receive_trait(self: &Arc>>) -> u32 { + TRAIT_MAGIC + } +} + +impl Ty { + fn receive_inherent(self: &Arc>>) -> u32 { + INHERENT_MAGIC + } +} + +fn main() { + let ty = >>>::default(); + assert_eq!(TRAIT_MAGIC, ty.receive_trait()); + assert_eq!(INHERENT_MAGIC, ty.receive_inherent()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime-async.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime-async.rs new file mode 100644 index 000000000000..6cb9ecec30da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime-async.rs @@ -0,0 +1,36 @@ +// check-pass +// edition:2018 + +use std::pin::Pin; +use std::task::{Context, Poll}; + +struct Foo; + +impl Foo { + async fn pin_ref(self: Pin<&Self>) -> Pin<&Self> { self } + + async fn pin_mut(self: Pin<&mut Self>) -> Pin<&mut Self> { self } + + async fn pin_pin_pin_ref(self: Pin>>) -> Pin>> { self } + + async fn pin_ref_impl_trait(self: Pin<&Self>) -> impl Clone + '_ { self } + + fn b(self: Pin<&Foo>, f: &Foo) -> Pin<&Foo> { self } +} + +type Alias = Pin; +impl Foo { + async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> Alias<&Self> { self } +} + +// FIXME(Centril): extend with the rest of the non-`async fn` test +// when we allow `async fn`s inside traits and trait implementations. + +fn main() { + let mut foo = Foo; + { Pin::new(&foo).pin_ref() }; + { Pin::new(&mut foo).pin_mut() }; + { Pin::new(Pin::new(Pin::new(&foo))).pin_pin_pin_ref() }; + { Pin::new(&foo).pin_ref_impl_trait() }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime.rs new file mode 100644 index 000000000000..051ed1de8ce8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime.rs @@ -0,0 +1,61 @@ +// check-pass + +use std::pin::Pin; +use std::task::{Context, Poll}; + +struct Foo; + +impl Foo { + fn pin_ref(self: Pin<&Self>) -> Pin<&Self> { self } + + fn pin_mut(self: Pin<&mut Self>) -> Pin<&mut Self> { self } + + fn pin_pin_pin_ref(self: Pin>>) -> Pin>> { self } + + fn pin_ref_impl_trait(self: Pin<&Self>) -> impl Clone + '_ { self } + + fn b(self: Pin<&Foo>, f: &Foo) -> Pin<&Foo> { self } +} + +type Alias = Pin; +impl Foo { + fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> Alias<&Self> { self } +} + +struct Bar { + field1: T, + field2: U, +} + +impl Bar { + fn fields(self: Pin<&mut Self>) -> (Pin<&mut T>, Pin<&mut U>) { + let this = self.get_mut(); + (Pin::new(&mut this.field1), Pin::new(&mut this.field2)) + } +} + +trait AsyncBufRead { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) + -> Poll>; +} + +struct Baz(Vec); + +impl AsyncBufRead for Baz { + fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) + -> Poll> + { + Poll::Ready(Ok(&self.get_mut().0)) + } +} + +fn main() { + let mut foo = Foo; + { Pin::new(&foo).pin_ref() }; + { Pin::new(&mut foo).pin_mut() }; + { Pin::new(Pin::new(Pin::new(&foo))).pin_pin_pin_ref() }; + { Pin::new(&foo).pin_ref_impl_trait() }; + let mut bar = Bar { field1: 0u8, field2: 1u8 }; + { Pin::new(&mut bar).fields() }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs new file mode 100644 index 000000000000..ee8260df7fbb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs @@ -0,0 +1,15 @@ +// edition:2018 + +use std::pin::Pin; + +struct Foo; + +impl Foo { + async fn f(self: Pin<&Self>) -> impl Clone { self } +// { dg-error ".E0759." "" { target *-*-* } .-1 } +} + +fn main() { + { Pin::new(&Foo).f() }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs new file mode 100644 index 000000000000..87e9daa38287 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.rs @@ -0,0 +1,12 @@ +use std::pin::Pin; + +struct Foo; + +impl Foo { + fn f(self: Pin<&Self>) -> impl Clone { self } // { dg-error ".E0759." "" { target *-*-* } } +} + +fn main() { + { Pin::new(&Foo).f() }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs new file mode 100644 index 000000000000..a8da5bd1208c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs @@ -0,0 +1,21 @@ +// edition:2018 + +use std::pin::Pin; + +struct Foo; + +impl Foo { + async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } +// { dg-error ".E0623." "" { target *-*-* } .-1 } + + async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } +// { dg-error ".E0623." "" { target *-*-* } .-1 } +} + +type Alias = Pin; +impl Foo { + async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs new file mode 100644 index 000000000000..d2747a9d3d41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs @@ -0,0 +1,17 @@ +use std::pin::Pin; + +struct Foo; + +impl Foo { + fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } // { dg-error ".E0623." "" { target *-*-* } } + + fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } // { dg-error ".E0623." "" { target *-*-* } } +} + +type Alias = Pin; +impl Foo { + fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pointers_and_wrappers.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pointers_and_wrappers.rs new file mode 100644 index 000000000000..bf01cce033f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_pointers_and_wrappers.rs @@ -0,0 +1,69 @@ +// run-pass +#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)] +#![feature(rustc_attrs)] + +use std::{ + ops::{Deref, CoerceUnsized, DispatchFromDyn}, + marker::Unsize, +}; + +struct Ptr(Box); + +impl Deref for Ptr { + type Target = T; + + fn deref(&self) -> &T { + &*self.0 + } +} + +impl + ?Sized, U: ?Sized> CoerceUnsized> for Ptr {} +impl + ?Sized, U: ?Sized> DispatchFromDyn> for Ptr {} + +struct Wrapper(T); + +impl Deref for Wrapper { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +impl, U> CoerceUnsized> for Wrapper {} +impl, U> DispatchFromDyn> for Wrapper {} + + +trait Trait { + // This method isn't object-safe yet. Unsized by-value `self` is object-safe (but not callable + // without unsized_locals), but wrappers arond `Self` currently are not. + // FIXME (mikeyhew) uncomment this when unsized rvalues object-safety is implemented + // fn wrapper(self: Wrapper) -> i32; + fn ptr_wrapper(self: Ptr>) -> i32; + fn wrapper_ptr(self: Wrapper>) -> i32; + fn wrapper_ptr_wrapper(self: Wrapper>>) -> i32; +} + +impl Trait for i32 { + fn ptr_wrapper(self: Ptr>) -> i32 { + **self + } + fn wrapper_ptr(self: Wrapper>) -> i32 { + **self + } + fn wrapper_ptr_wrapper(self: Wrapper>>) -> i32 { + ***self + } +} + +fn main() { + let pw = Ptr(Box::new(Wrapper(5))) as Ptr>; + assert_eq!(pw.ptr_wrapper(), 5); + + let wp = Wrapper(Ptr(Box::new(6))) as Wrapper>; + assert_eq!(wp.wrapper_ptr(), 6); + + let wpw = Wrapper(Ptr(Box::new(Wrapper(7)))) as Wrapper>>; + assert_eq!(wpw.wrapper_ptr_wrapper(), 7); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_raw_pointer_struct.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_raw_pointer_struct.rs new file mode 100644 index 000000000000..8f8c35c842ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_raw_pointer_struct.rs @@ -0,0 +1,29 @@ +// run-pass +#![feature(arbitrary_self_types)] + +use std::rc::Rc; + +struct Foo(String); + +impl Foo { + unsafe fn foo(self: *const Self) -> *const str { + (*self).0.as_ref() + } + + fn complicated_1(self: *const Rc) -> &'static str { + "Foo::complicated_1" + } + + unsafe fn complicated_2(self: Rc<*const Self>) -> *const str { + (**self).0.as_ref() + } +} + +fn main() { + let foo = Foo("abc123".into()); + assert_eq!("abc123", unsafe { &*(&foo as *const Foo).foo() }); + assert_eq!("Foo::complicated_1", std::ptr::null::>().complicated_1()); + let rc = Rc::new(&foo as *const Foo); + assert_eq!("abc123", unsafe { &*rc.complicated_2()}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_raw_pointer_trait.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_raw_pointer_trait.rs new file mode 100644 index 000000000000..f6d5a7086676 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_raw_pointer_trait.rs @@ -0,0 +1,62 @@ +// run-pass +#![feature(arbitrary_self_types)] + +use std::ptr; + +trait Foo { + fn foo(self: *const Self) -> &'static str; + + unsafe fn bar(self: *const Self) -> i64; + + unsafe fn complicated(self: *const *const Self) -> i64 where Self: Sized { + (*self).bar() + } +} + +impl Foo for i32 { + fn foo(self: *const Self) -> &'static str { + "I'm an i32!" + } + + unsafe fn bar(self: *const Self) -> i64 { + *self as i64 + } +} + +impl Foo for u32 { + fn foo(self: *const Self) -> &'static str { + "I'm a u32!" + } + + unsafe fn bar(self: *const Self) -> i64 { + *self as i64 + } +} + +fn main() { + let null_i32 = ptr::null::() as *const dyn Foo; + let null_u32 = ptr::null::() as *const dyn Foo; + + assert_eq!("I'm an i32!", null_i32.foo()); + assert_eq!("I'm a u32!", null_u32.foo()); + + let valid_i32 = 5i32; + let valid_i32_thin = &valid_i32 as *const i32; + assert_eq!("I'm an i32!", valid_i32_thin.foo()); + assert_eq!(5, unsafe { valid_i32_thin.bar() }); + assert_eq!(5, unsafe { (&valid_i32_thin as *const *const i32).complicated() }); + let valid_i32_fat = valid_i32_thin as *const dyn Foo; + assert_eq!("I'm an i32!", valid_i32_fat.foo()); + assert_eq!(5, unsafe { valid_i32_fat.bar() }); + + let valid_u32 = 18u32; + let valid_u32_thin = &valid_u32 as *const u32; + assert_eq!("I'm a u32!", valid_u32_thin.foo()); + assert_eq!(18, unsafe { valid_u32_thin.bar() }); + assert_eq!(18, unsafe { (&valid_u32_thin as *const *const u32).complicated() }); + let valid_u32_fat = valid_u32_thin as *const dyn Foo; + assert_eq!("I'm a u32!", valid_u32_fat.foo()); + assert_eq!(18, unsafe { valid_u32_fat.bar() }); + +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_silly.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_silly.rs new file mode 100644 index 000000000000..3d19c4bfb3e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_silly.rs @@ -0,0 +1,22 @@ +// run-pass +#![feature(arbitrary_self_types)] + +struct Foo; +struct Bar; + +impl std::ops::Deref for Bar { + type Target = Foo; + + fn deref(&self) -> &Foo { + &Foo + } +} + +impl Foo { + fn bar(self: Bar) -> i32 { 3 } +} + +fn main() { + assert_eq!(3, Bar.bar()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_stdlib_pointers.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_stdlib_pointers.rs new file mode 100644 index 000000000000..772e2f1f6d15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_stdlib_pointers.rs @@ -0,0 +1,55 @@ +// run-pass +#![feature(arbitrary_self_types)] +#![feature(rustc_attrs)] + +use std::{ + rc::Rc, + sync::Arc, + pin::Pin, +}; + +trait Trait { + fn by_rc(self: Rc) -> i64; + fn by_arc(self: Arc) -> i64; + fn by_pin_mut(self: Pin<&mut Self>) -> i64; + fn by_pin_box(self: Pin>) -> i64; + fn by_pin_pin_pin_ref(self: Pin>>) -> i64; +} + +impl Trait for i64 { + fn by_rc(self: Rc) -> i64 { + *self + } + fn by_arc(self: Arc) -> i64 { + *self + } + fn by_pin_mut(self: Pin<&mut Self>) -> i64 { + *self + } + fn by_pin_box(self: Pin>) -> i64 { + *self + } + fn by_pin_pin_pin_ref(self: Pin>>) -> i64 { + *self + } +} + +fn main() { + let rc = Rc::new(1i64) as Rc; + assert_eq!(1, rc.by_rc()); + + let arc = Arc::new(2i64) as Arc; + assert_eq!(2, arc.by_arc()); + + let mut value = 3i64; + let pin_mut = Pin::new(&mut value) as Pin<&mut dyn Trait>; + assert_eq!(3, pin_mut.by_pin_mut()); + + let pin_box = Into::>>::into(Box::new(4i64)) as Pin>; + assert_eq!(4, pin_box.by_pin_box()); + + let value = 5i64; + let pin_pin_pin_ref = Pin::new(Pin::new(Pin::new(&value))) as Pin>>; + assert_eq!(5, pin_pin_pin_ref.by_pin_pin_pin_ref()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_struct.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_struct.rs new file mode 100644 index 000000000000..2a09395db1fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_struct.rs @@ -0,0 +1,25 @@ +// run-pass + +use std::rc::Rc; + +struct Foo { + x: i32, + y: i32, +} + +impl Foo { + fn x(self: &Rc) -> i32 { + self.x + } + + fn y(self: Rc) -> i32 { + self.y + } +} + +fn main() { + let foo = Rc::new(Foo {x: 3, y: 4}); + assert_eq!(3, foo.x()); + assert_eq!(4, foo.y()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_trait.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_trait.rs new file mode 100644 index 000000000000..4b9810c9d096 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_trait.rs @@ -0,0 +1,20 @@ +// run-pass + +use std::rc::Rc; + +trait Trait { + fn trait_method<'a>(self: &'a Box>) -> &'a [i32]; +} + +impl Trait for Vec { + fn trait_method<'a>(self: &'a Box>) -> &'a [i32] { + &***self + } +} + +fn main() { + let v = vec![1,2,3]; + + assert_eq!(&[1,2,3], Box::new(Rc::new(v)).trait_method()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_unsized_struct.rs b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_unsized_struct.rs new file mode 100644 index 000000000000..ed35da48c39a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/arbitrary_self_types_unsized_struct.rs @@ -0,0 +1,17 @@ +// run-pass + +use std::rc::Rc; + +struct Foo(T); + +impl Foo<[u8]> { + fn len(self: Rc) -> usize { + self.0.len() + } +} + +fn main() { + let rc = Rc::new(Foo([1u8,2,3])) as Rc>; + assert_eq!(3, rc.len()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/auxiliary/explicit_self_xcrate.rs b/gcc/testsuite/rust/rustc/ui/self/auxiliary/explicit_self_xcrate.rs new file mode 100644 index 000000000000..fb752c4b5db5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/auxiliary/explicit_self_xcrate.rs @@ -0,0 +1,16 @@ +pub trait Foo { + #[inline(always)] + fn f(&self); +} + +pub struct Bar { + pub x: String +} + +impl Foo for Bar { + #[inline(always)] + fn f(&self) { + println!("{}", (*self).x); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/builtin-superkinds-self-type.rs b/gcc/testsuite/rust/rustc/ui/self/builtin-superkinds-self-type.rs new file mode 100644 index 000000000000..83af4b4a3385 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/builtin-superkinds-self-type.rs @@ -0,0 +1,21 @@ +// run-pass +// Tests the ability for the Self type in default methods to use +// capabilities granted by builtin kinds as supertraits. + + +use std::sync::mpsc::{Sender, channel}; + +trait Foo : Send + Sized + 'static { + fn foo(self, tx: Sender) { + tx.send(self).unwrap(); + } +} + +impl Foo for T { } + +pub fn main() { + let (tx, rx) = channel(); + 1193182.foo(tx); + assert_eq!(rx.recv().unwrap(), 1193182); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/by-value-self-in-mut-slot.rs b/gcc/testsuite/rust/rustc/ui/self/by-value-self-in-mut-slot.rs new file mode 100644 index 000000000000..3c51b324344a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/by-value-self-in-mut-slot.rs @@ -0,0 +1,23 @@ +// run-pass + +struct X { + a: isize +} + +trait Changer { + fn change(self) -> Self; +} + +impl Changer for X { + fn change(mut self) -> X { + self.a = 55; + self + } +} + +pub fn main() { + let x = X { a: 32 }; + let new_x = x.change(); + assert_eq!(new_x.a, 55); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/alias-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/alias-async.rs new file mode 100644 index 000000000000..f60c8a218499 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/alias-async.rs @@ -0,0 +1,37 @@ +// check-pass +// edition:2018 + +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +type Alias = Struct; + +impl Struct { + // Test using an alias for `Struct`: + + async fn alias(self: Alias, f: &u32) -> &u32 { + f + } + + async fn box_Alias(self: Box, f: &u32) -> &u32 { + f + } + + async fn rc_Alias(self: Rc, f: &u32) -> &u32 { + f + } + + async fn box_box_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + async fn box_rc_Alias(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/alias.rs b/gcc/testsuite/rust/rustc/ui/self/elision/alias.rs new file mode 100644 index 000000000000..f5e3e37a4306 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/alias.rs @@ -0,0 +1,36 @@ +// check-pass + +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +type Alias = Struct; + +impl Struct { + // Test using an alias for `Struct`: + + fn alias(self: Alias, f: &u32) -> &u32 { + f + } + + fn box_Alias(self: Box, f: &u32) -> &u32 { + f + } + + fn rc_Alias(self: Rc, f: &u32) -> &u32 { + f + } + + fn box_box_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + fn box_rc_Alias(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/assoc-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/assoc-async.rs new file mode 100644 index 000000000000..3bbff0adab7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/assoc-async.rs @@ -0,0 +1,41 @@ +// check-pass +// edition:2018 + +#![allow(non_snake_case)] + +use std::rc::Rc; + +trait Trait { + type AssocType; +} + +struct Struct { } + +impl Trait for Struct { + type AssocType = Self; +} + +impl Struct { + async fn assoc(self: ::AssocType, f: &u32) -> &u32 { + f + } + + async fn box_AssocType(self: Box<::AssocType>, f: &u32) -> &u32 { + f + } + + async fn rc_AssocType(self: Rc<::AssocType>, f: &u32) -> &u32 { + f + } + + async fn box_box_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } + + async fn box_rc_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/assoc.rs b/gcc/testsuite/rust/rustc/ui/self/elision/assoc.rs new file mode 100644 index 000000000000..9c8fe9d3efd8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/assoc.rs @@ -0,0 +1,40 @@ +// check-pass + +#![allow(non_snake_case)] + +use std::rc::Rc; + +trait Trait { + type AssocType; +} + +struct Struct { } + +impl Trait for Struct { + type AssocType = Self; +} + +impl Struct { + fn assoc(self: ::AssocType, f: &u32) -> &u32 { + f + } + + fn box_AssocType(self: Box<::AssocType>, f: &u32) -> &u32 { + f + } + + fn rc_AssocType(self: Rc<::AssocType>, f: &u32) -> &u32 { + f + } + + fn box_box_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } + + fn box_rc_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/lt-alias-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/lt-alias-async.rs new file mode 100644 index 000000000000..173a337f0f1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/lt-alias-async.rs @@ -0,0 +1,39 @@ +// check-pass +// edition:2018 + +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct<'a> { x: &'a u32 } + +type Alias<'a> = Struct<'a>; + +impl<'a> Alias<'a> { + async fn take_self(self, f: &u32) -> &u32 { + f + } + + async fn take_Alias(self: Alias<'a>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Box_Alias(self: Box>>, f: &u32) -> &u32 { + f + } + + async fn take_Rc_Alias(self: Rc>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Rc_Alias(self: Box>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/lt-alias.rs b/gcc/testsuite/rust/rustc/ui/self/elision/lt-alias.rs new file mode 100644 index 000000000000..ccaa87f4599a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/lt-alias.rs @@ -0,0 +1,38 @@ +// check-pass + +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct<'a> { x: &'a u32 } + +type Alias<'a> = Struct<'a>; + +impl<'a> Alias<'a> { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_Alias(self: Alias<'a>, f: &u32) -> &u32 { + f + } + + fn take_Box_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Alias(self: Box>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Alias(self: Rc>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Alias(self: Box>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/lt-assoc-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/lt-assoc-async.rs new file mode 100644 index 000000000000..1cdce5c4d64e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/lt-assoc-async.rs @@ -0,0 +1,51 @@ +// check-pass +// edition:2018 + +#![allow(non_snake_case)] + +use std::rc::Rc; + +trait Trait { + type AssocType; +} + +struct Struct<'a> { x: &'a u32 } + +impl<'a> Trait for Struct<'a> { + type AssocType = Self; +} + +impl<'a> Struct<'a> { + async fn take_self(self, f: &u32) -> &u32 { + f + } + + async fn take_AssocType(self: as Trait>::AssocType, f: &u32) -> &u32 { + f + } + + async fn take_Box_AssocType(self: Box< as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Box_AssocType( + self: Box as Trait>::AssocType>>, + f: &u32 + ) -> &u32 { + f + } + + async fn take_Rc_AssocType(self: Rc< as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Rc_AssocType( + self: Box as Trait>::AssocType>>, + f: &u32 + ) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/lt-assoc.rs b/gcc/testsuite/rust/rustc/ui/self/elision/lt-assoc.rs new file mode 100644 index 000000000000..039b5ca9f860 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/lt-assoc.rs @@ -0,0 +1,44 @@ +// check-pass + +#![allow(non_snake_case)] + +use std::rc::Rc; + +trait Trait { + type AssocType; +} + +struct Struct<'a> { x: &'a u32 } + +impl<'a> Trait for Struct<'a> { + type AssocType = Self; +} + +impl<'a> Struct<'a> { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_AssocType(self: as Trait>::AssocType, f: &u32) -> &u32 { + f + } + + fn take_Box_AssocType(self: Box< as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_AssocType(self: Box as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_AssocType(self: Rc< as Trait>::AssocType>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_AssocType(self: Box as Trait>::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/lt-ref-self-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/lt-ref-self-async.rs new file mode 100644 index 000000000000..ce2cbab618da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/lt-ref-self-async.rs @@ -0,0 +1,40 @@ +// edition:2018 + +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct<'a> { data: &'a u32 } + +impl<'a> Struct<'a> { + // Test using `&self` sugar: + + async fn ref_self(&self, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + // Test using `&Self` explicitly: + + async fn ref_Self(self: &Self, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_pin_Self(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/lt-ref-self.rs b/gcc/testsuite/rust/rustc/ui/self/elision/lt-ref-self.rs new file mode 100644 index 000000000000..6e7489545593 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/lt-ref-self.rs @@ -0,0 +1,38 @@ +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct<'a> { data: &'a u32 } + +impl<'a> Struct<'a> { + // Test using `&self` sugar: + + fn ref_self(&self, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + // Test using `&Self` explicitly: + + fn ref_Self(self: &Self, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_pin_Self(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/lt-self-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/lt-self-async.rs new file mode 100644 index 000000000000..8793030e57ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/lt-self-async.rs @@ -0,0 +1,50 @@ +// check-pass +// edition:2018 + +#![allow(non_snake_case)] + +use std::pin::Pin; +use std::rc::Rc; + +struct Struct<'a> { + x: &'a u32 +} + +impl<'a> Struct<'a> { + async fn take_self(self, f: &u32) -> &u32 { + f + } + + async fn take_Self(self: Self, f: &u32) -> &u32 { + f + } + + async fn take_Box_Self(self: Box, f: &u32) -> &u32 { + f + } + + async fn take_Box_Box_Self(self: Box>, f: &u32) -> &u32 { + f + } + + async fn take_Rc_Self(self: Rc, f: &u32) -> &u32 { + f + } + + async fn take_Box_Rc_Self(self: Box>, f: &u32) -> &u32 { + f + } + + // N/A + //fn take_Pin_Self(self: Pin, f: &u32) -> &u32 { + // f + //} + + // N/A + //fn take_Box_Pin_Self(self: Box>, f: &u32) -> &u32 { + // f + //} +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/lt-self.rs b/gcc/testsuite/rust/rustc/ui/self/elision/lt-self.rs new file mode 100644 index 000000000000..e0a005a2f607 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/lt-self.rs @@ -0,0 +1,49 @@ +// check-pass + +#![allow(non_snake_case)] + +use std::pin::Pin; +use std::rc::Rc; + +struct Struct<'a> { + x: &'a u32 +} + +impl<'a> Struct<'a> { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_Self(self: Self, f: &u32) -> &u32 { + f + } + + fn take_Box_Self(self: Box, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Self(self: Box>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Self(self: Rc, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Self(self: Box>, f: &u32) -> &u32 { + f + } + + // N/A + //fn take_Pin_Self(self: Pin, f: &u32) -> &u32 { + // f + //} + + // N/A + //fn take_Box_Pin_Self(self: Box>, f: &u32) -> &u32 { + // f + //} +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/lt-struct-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/lt-struct-async.rs new file mode 100644 index 000000000000..f2ce863664c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/lt-struct-async.rs @@ -0,0 +1,37 @@ +// check-pass +// edition:2018 + +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct<'a> { x: &'a u32 } + +impl<'a> Struct<'a> { + async fn take_self(self, f: &u32) -> &u32 { + f + } + + async fn take_Struct(self: Struct<'a>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Struct(self: Box>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Box_Struct(self: Box>>, f: &u32) -> &u32 { + f + } + + async fn take_Rc_Struct(self: Rc>, f: &u32) -> &u32 { + f + } + + async fn take_Box_Rc_Struct(self: Box>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/lt-struct.rs b/gcc/testsuite/rust/rustc/ui/self/elision/lt-struct.rs new file mode 100644 index 000000000000..afeae46015d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/lt-struct.rs @@ -0,0 +1,36 @@ +// check-pass + +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct<'a> { x: &'a u32 } + +impl<'a> Struct<'a> { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_Struct(self: Struct<'a>, f: &u32) -> &u32 { + f + } + + fn take_Box_Struct(self: Box>, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Struct(self: Box>>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Struct(self: Rc>, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Struct(self: Box>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/multiple-ref-self-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/multiple-ref-self-async.rs new file mode 100644 index 000000000000..15f51241f54b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/multiple-ref-self-async.rs @@ -0,0 +1,45 @@ +// check-pass +// edition:2018 + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::marker::PhantomData; +use std::ops::Deref; +use std::pin::Pin; + +struct Struct { } + +struct Wrap(T, PhantomData

); + +impl Deref for Wrap { + type Target = T; + fn deref(&self) -> &T { &self.0 } +} + +impl Struct { + // Test using multiple `&Self`: + + async fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 { + f + } + + async fn box_wrap_ref_Self_ref_Self(self: Box>, f: &u32) -> &u32 { + f + } + + async fn pin_wrap_ref_Self_ref_Self(self: Pin>, f: &u32) -> &u32 { + f + } + + async fn box_box_wrap_ref_Self_ref_Self(self: Box>>, f: &u32) -> &u32 { + f + } + + async fn box_pin_wrap_ref_Self_ref_Self(self: Box>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/multiple-ref-self.rs b/gcc/testsuite/rust/rustc/ui/self/elision/multiple-ref-self.rs new file mode 100644 index 000000000000..56351dfb8c4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/multiple-ref-self.rs @@ -0,0 +1,44 @@ +// check-pass + +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::marker::PhantomData; +use std::ops::Deref; +use std::pin::Pin; + +struct Struct { } + +struct Wrap(T, PhantomData

); + +impl Deref for Wrap { + type Target = T; + fn deref(&self) -> &T { &self.0 } +} + +impl Struct { + // Test using multiple `&Self`: + + fn wrap_ref_Self_ref_Self(self: Wrap<&Self, &Self>, f: &u8) -> &u8 { + f + } + + fn box_wrap_ref_Self_ref_Self(self: Box>, f: &u32) -> &u32 { + f + } + + fn pin_wrap_ref_Self_ref_Self(self: Pin>, f: &u32) -> &u32 { + f + } + + fn box_box_wrap_ref_Self_ref_Self(self: Box>>, f: &u32) -> &u32 { + f + } + + fn box_pin_wrap_ref_Self_ref_Self(self: Box>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-alias-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-alias-async.rs new file mode 100644 index 000000000000..ef2a4589dea0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-alias-async.rs @@ -0,0 +1,40 @@ +// edition:2018 +// check-pass + +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +type Alias = Struct; + +impl Struct { + // Test using an alias for `Struct`: + // + // FIXME. We currently fail to recognize this as the self type, which + // feels like a bug. + + async fn ref_Alias(self: &Alias, f: &u32) -> &u32 { + f + } + + async fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 { + f + } + + async fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 { + f + } + + async fn box_box_ref_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + async fn box_pin_ref_Alias(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-alias.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-alias.rs new file mode 100644 index 000000000000..17d728be3dd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-alias.rs @@ -0,0 +1,39 @@ +// check-pass + +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +type Alias = Struct; + +impl Struct { + // Test using an alias for `Struct`: + // + // FIXME. We currently fail to recognize this as the self type, which + // feels like a bug. + + fn ref_Alias(self: &Alias, f: &u32) -> &u32 { + f + } + + fn box_ref_Alias(self: Box<&Alias>, f: &u32) -> &u32 { + f + } + + fn pin_ref_Alias(self: Pin<&Alias>, f: &u32) -> &u32 { + f + } + + fn box_box_ref_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + fn box_pin_ref_Alias(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-assoc-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-assoc-async.rs new file mode 100644 index 000000000000..edc425f7fdec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-assoc-async.rs @@ -0,0 +1,41 @@ +// edition:2018 +// check-pass + +#![allow(non_snake_case)] + +use std::pin::Pin; + +trait Trait { + type AssocType; +} + +struct Struct { } + +impl Trait for Struct { + type AssocType = Self; +} + +impl Struct { + async fn ref_AssocType(self: &::AssocType, f: &u32) -> &u32 { + f + } + + async fn box_ref_AssocType(self: Box<&::AssocType>, f: &u32) -> &u32 { + f + } + + async fn pin_ref_AssocType(self: Pin<&::AssocType>, f: &u32) -> &u32 { + f + } + + async fn box_box_ref_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } + + async fn box_pin_ref_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-assoc.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-assoc.rs new file mode 100644 index 000000000000..f096414ec0c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-assoc.rs @@ -0,0 +1,40 @@ +// check-pass + +#![allow(non_snake_case)] + +use std::pin::Pin; + +trait Trait { + type AssocType; +} + +struct Struct { } + +impl Trait for Struct { + type AssocType = Self; +} + +impl Struct { + fn ref_AssocType(self: &::AssocType, f: &u32) -> &u32 { + f + } + + fn box_ref_AssocType(self: Box<&::AssocType>, f: &u32) -> &u32 { + f + } + + fn pin_ref_AssocType(self: Pin<&::AssocType>, f: &u32) -> &u32 { + f + } + + fn box_box_ref_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } + + fn box_pin_ref_AssocType(self: Box::AssocType>>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-alias-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-alias-async.rs new file mode 100644 index 000000000000..220c5c9773ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-alias-async.rs @@ -0,0 +1,37 @@ +// edition:2018 +// check-pass + +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +type Alias = Struct; + +impl Struct { + // Test using an alias for `Struct`: + + async fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 { + f + } + + async fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 { + f + } + + async fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 { + f + } + + async fn box_box_ref_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + async fn box_pin_ref_Alias(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-alias.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-alias.rs new file mode 100644 index 000000000000..0ea8ecdc9716 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-alias.rs @@ -0,0 +1,36 @@ +// check-pass + +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +type Alias = Struct; + +impl Struct { + // Test using an alias for `Struct`: + + fn ref_Alias(self: &mut Alias, f: &u32) -> &u32 { + f + } + + fn box_ref_Alias(self: Box<&mut Alias>, f: &u32) -> &u32 { + f + } + + fn pin_ref_Alias(self: Pin<&mut Alias>, f: &u32) -> &u32 { + f + } + + fn box_box_ref_Alias(self: Box>, f: &u32) -> &u32 { + f + } + + fn box_pin_ref_Alias(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-self-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-self-async.rs new file mode 100644 index 000000000000..947b35d2df2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-self-async.rs @@ -0,0 +1,40 @@ +// edition:2018 + +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&mut self` sugar: + + async fn ref_self(&mut self, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + // Test using `&mut Self` explicitly: + + async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-self.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-self.rs new file mode 100644 index 000000000000..e4c6b78908a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-self.rs @@ -0,0 +1,38 @@ +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&mut self` sugar: + + fn ref_self(&mut self, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + // Test using `&mut Self` explicitly: + + fn ref_Self(self: &mut Self, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-struct-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-struct-async.rs new file mode 100644 index 000000000000..1b9c5526cb01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-struct-async.rs @@ -0,0 +1,34 @@ +// edition:2018 + +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&mut Struct` explicitly: + + async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-struct.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-struct.rs new file mode 100644 index 000000000000..8d6046637056 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-mut-struct.rs @@ -0,0 +1,32 @@ +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&mut Struct` explicitly: + + fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-self-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-self-async.rs new file mode 100644 index 000000000000..87dc09e99400 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-self-async.rs @@ -0,0 +1,54 @@ +// edition:2018 + +#![allow(non_snake_case)] +#![feature(arbitrary_self_types)] + +use std::marker::PhantomData; +use std::ops::Deref; +use std::pin::Pin; + +struct Struct { } + +struct Wrap(T, PhantomData

); + +impl Deref for Wrap { + type Target = T; + fn deref(&self) -> &T { &self.0 } +} + +impl Struct { + // Test using `&self` sugar: + + async fn ref_self(&self, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + // Test using `&Self` explicitly: + + async fn ref_Self(self: &Self, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { + f // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-self.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-self.rs new file mode 100644 index 000000000000..5c49d500ae96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-self.rs @@ -0,0 +1,52 @@ +#![feature(arbitrary_self_types)] +#![allow(non_snake_case)] + +use std::marker::PhantomData; +use std::ops::Deref; +use std::pin::Pin; + +struct Struct { } + +struct Wrap(T, PhantomData

); + +impl Deref for Wrap { + type Target = T; + fn deref(&self) -> &T { &self.0 } +} + +impl Struct { + // Test using `&self` sugar: + + fn ref_self(&self, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + // Test using `&Self` explicitly: + + fn ref_Self(self: &Self, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { + f // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-struct-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-struct-async.rs new file mode 100644 index 000000000000..53d64de9ccc6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-struct-async.rs @@ -0,0 +1,34 @@ +// edition:2018 + +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&Struct` explicitly: + + async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + async fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/ref-struct.rs b/gcc/testsuite/rust/rustc/ui/self/elision/ref-struct.rs new file mode 100644 index 000000000000..b15ff458ed3d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/ref-struct.rs @@ -0,0 +1,32 @@ +#![allow(non_snake_case)] + +use std::pin::Pin; + +struct Struct { } + +impl Struct { + // Test using `&Struct` explicitly: + + fn ref_Struct(self: &Struct, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } + + fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { + f // { dg-error ".E0623." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/self-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/self-async.rs new file mode 100644 index 000000000000..33e567d1e2fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/self-async.rs @@ -0,0 +1,37 @@ +// check-pass +// edition:2018 + +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +impl Struct { + async fn take_self(self, f: &u32) -> &u32 { + f + } + + async fn take_Self(self: Self, f: &u32) -> &u32 { + f + } + + async fn take_Box_Self(self: Box, f: &u32) -> &u32 { + f + } + + async fn take_Box_Box_Self(self: Box>, f: &u32) -> &u32 { + f + } + + async fn take_Rc_Self(self: Rc, f: &u32) -> &u32 { + f + } + + async fn take_Box_Rc_Self(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/self.rs b/gcc/testsuite/rust/rustc/ui/self/elision/self.rs new file mode 100644 index 000000000000..dbf52cc49fe5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/self.rs @@ -0,0 +1,36 @@ +// check-pass + +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +impl Struct { + fn take_self(self, f: &u32) -> &u32 { + f + } + + fn take_Self(self: Self, f: &u32) -> &u32 { + f + } + + fn take_Box_Self(self: Box, f: &u32) -> &u32 { + f + } + + fn take_Box_Box_Self(self: Box>, f: &u32) -> &u32 { + f + } + + fn take_Rc_Self(self: Rc, f: &u32) -> &u32 { + f + } + + fn take_Box_Rc_Self(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/struct-async.rs b/gcc/testsuite/rust/rustc/ui/self/elision/struct-async.rs new file mode 100644 index 000000000000..16c705f9d181 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/struct-async.rs @@ -0,0 +1,33 @@ +// check-pass +// edition:2018 + +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +impl Struct { + async fn ref_Struct(self: Struct, f: &u32) -> &u32 { + f + } + + async fn box_Struct(self: Box, f: &u32) -> &u32 { + f + } + + async fn rc_Struct(self: Rc, f: &u32) -> &u32 { + f + } + + async fn box_box_Struct(self: Box>, f: &u32) -> &u32 { + f + } + + async fn box_rc_Struct(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/elision/struct.rs b/gcc/testsuite/rust/rustc/ui/self/elision/struct.rs new file mode 100644 index 000000000000..6495bd7ae659 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/elision/struct.rs @@ -0,0 +1,32 @@ +// check-pass + +#![allow(non_snake_case)] + +use std::rc::Rc; + +struct Struct { } + +impl Struct { + fn ref_Struct(self: Struct, f: &u32) -> &u32 { + f + } + + fn box_Struct(self: Box, f: &u32) -> &u32 { + f + } + + fn rc_Struct(self: Rc, f: &u32) -> &u32 { + f + } + + fn box_box_Struct(self: Box>, f: &u32) -> &u32 { + f + } + + fn box_rc_Struct(self: Box>, f: &u32) -> &u32 { + f + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/self/explicit-self-closures.rs b/gcc/testsuite/rust/rustc/ui/self/explicit-self-closures.rs new file mode 100644 index 000000000000..04044c81207b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/explicit-self-closures.rs @@ -0,0 +1,18 @@ +// build-pass (FIXME(62277): could be check-pass?) +#![allow(dead_code)] +// Test to make sure that explicit self params work inside closures + +// pretty-expanded FIXME #23616 + +struct Box { + x: usize +} + +impl Box { + pub fn set_many(&mut self, xs: &[usize]) { + for x in xs { self.x = *x; } + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/explicit-self-generic.rs b/gcc/testsuite/rust/rustc/ui/self/explicit-self-generic.rs new file mode 100644 index 000000000000..2ebb0f219b02 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/explicit-self-generic.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(dead_code)] +#![feature(box_syntax)] + +#[derive(Copy, Clone)] +struct LM { resize_at: usize, size: usize } + +enum HashMap { + HashMap_(LM, Vec<(K,V)>) +} + +fn linear_map() -> HashMap { + HashMap::HashMap_(LM{ + resize_at: 32, + size: 0}, Vec::new()) +} + +impl HashMap { + pub fn len(&mut self) -> usize { + match *self { + HashMap::HashMap_(ref l, _) => l.size + } + } +} + +pub fn main() { + let mut m: Box<_> = box linear_map::<(),()>(); + assert_eq!(m.len(), 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/explicit-self-objects-uniq.rs b/gcc/testsuite/rust/rustc/ui/self/explicit-self-objects-uniq.rs new file mode 100644 index 000000000000..c682a9de2dbd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/explicit-self-objects-uniq.rs @@ -0,0 +1,23 @@ +// run-pass +#![feature(box_syntax)] + +trait Foo { + fn f(self: Box); +} + +struct S { + x: isize +} + +impl Foo for S { + fn f(self: Box) { + assert_eq!(self.x, 3); + } +} + +pub fn main() { + let x = box S { x: 3 }; + let y = x as Box; + y.f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/explicit-self.rs b/gcc/testsuite/rust/rustc/ui/self/explicit-self.rs new file mode 100644 index 000000000000..59ad6452e8af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/explicit-self.rs @@ -0,0 +1,74 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] + +#![feature(box_syntax)] + +static tau: f64 = 2.0*3.14159265358979323; + +struct Point {x: f64, y: f64} +struct Size {w: f64, h: f64} +enum shape { + circle(Point, f64), + rectangle(Point, Size) +} + + +fn compute_area(shape: &shape) -> f64 { + match *shape { + shape::circle(_, radius) => 0.5 * tau * radius * radius, + shape::rectangle(_, ref size) => size.w * size.h + } +} + +impl shape { + // self is in the implicit self region + pub fn select<'r, T>(&self, threshold: f64, a: &'r T, b: &'r T) + -> &'r T { + if compute_area(self) > threshold {a} else {b} + } +} + +fn select_based_on_unit_circle<'r, T>( + threshold: f64, a: &'r T, b: &'r T) -> &'r T { + + let shape = &shape::circle(Point{x: 0.0, y: 0.0}, 1.0); + shape.select(threshold, a, b) +} + +#[derive(Clone)] +struct thing { + x: A +} + +#[derive(Clone)] +struct A { + a: isize +} + +fn thing(x: A) -> thing { + thing { + x: x + } +} + +impl thing { + pub fn bar(self: Box) -> isize { self.x.a } + pub fn quux(&self) -> isize { self.x.a } + pub fn baz<'a>(&'a self) -> &'a A { &self.x } + pub fn spam(self) -> isize { self.x.a } +} + +trait Nus { fn f(&self); } +impl Nus for thing { fn f(&self) {} } + +pub fn main() { + let y: Box<_> = box thing(A {a: 10}); + assert_eq!(y.clone().bar(), 10); + assert_eq!(y.quux(), 10); + + let z = thing(A {a: 11}); + assert_eq!(z.spam(), 11); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/explicit_self_xcrate_exe.rs b/gcc/testsuite/rust/rustc/ui/self/explicit_self_xcrate_exe.rs new file mode 100644 index 000000000000..82fe0f64a7b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/explicit_self_xcrate_exe.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:explicit_self_xcrate.rs + +// pretty-expanded FIXME #23616 + +extern crate explicit_self_xcrate; +use explicit_self_xcrate::{Foo, Bar}; + +pub fn main() { + let x = Bar { x: "hello".to_string() }; + x.f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/move-self.rs b/gcc/testsuite/rust/rustc/ui/self/move-self.rs new file mode 100644 index 000000000000..8b456180759b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/move-self.rs @@ -0,0 +1,20 @@ +// run-pass +struct S { + x: String +} + +impl S { + pub fn foo(self) { + self.bar(); + } + + pub fn bar(self) { + println!("{}", self.x); + } +} + +pub fn main() { + let x = S { x: "Hello!".to_string() }; + x.foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/object-safety-sized-self-by-value-self.rs b/gcc/testsuite/rust/rustc/ui/self/object-safety-sized-self-by-value-self.rs new file mode 100644 index 000000000000..375186f445ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/object-safety-sized-self-by-value-self.rs @@ -0,0 +1,40 @@ +// run-pass +#![allow(unused_mut)] +// Check that a trait is still object-safe (and usable) if it has +// methods with by-value self so long as they require `Self : Sized`. + + +trait Counter { + fn tick(&mut self) -> u32; + fn get(self) -> u32 where Self : Sized; +} + +struct CCounter { + c: u32 +} + +impl Counter for CCounter { + fn tick(&mut self) -> u32 { self.c += 1; self.c } + fn get(self) -> u32 where Self : Sized { self.c } +} + +fn tick1(mut c: C) -> u32 { + tick2(&mut c); + c.get() +} + +fn tick2(c: &mut dyn Counter) { + tick3(c); +} + +fn tick3(c: &mut C) { + c.tick(); + c.tick(); +} + +fn main() { + let mut c = CCounter { c: 0 }; + let value = tick1(c); + assert_eq!(value, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/object-safety-sized-self-generic-method.rs b/gcc/testsuite/rust/rustc/ui/self/object-safety-sized-self-generic-method.rs new file mode 100644 index 000000000000..20fbb89ce087 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/object-safety-sized-self-generic-method.rs @@ -0,0 +1,40 @@ +// run-pass +#![allow(unused_variables)] +// Check that a trait is still object-safe (and usable) if it has +// generic methods so long as they require `Self : Sized`. + + +trait Counter { + fn tick(&mut self) -> u32; + fn with(&self, f: F) where Self : Sized; +} + +struct CCounter { + c: u32 +} + +impl Counter for CCounter { + fn tick(&mut self) -> u32 { self.c += 1; self.c } + fn with(&self, f: F) { f(self.c); } +} + +fn tick1(c: &mut C) { + tick2(c); + c.with(|i| ()); +} + +fn tick2(c: &mut dyn Counter) { + tick3(c); +} + +fn tick3(c: &mut C) { + c.tick(); + c.tick(); +} + +fn main() { + let mut c = CCounter { c: 0 }; + tick1(&mut c); + assert_eq!(c.tick(), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/object-safety-sized-self-return-Self.rs b/gcc/testsuite/rust/rustc/ui/self/object-safety-sized-self-return-Self.rs new file mode 100644 index 000000000000..e48dc137ecc3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/object-safety-sized-self-return-Self.rs @@ -0,0 +1,40 @@ +// run-pass +// Check that a trait is still object-safe (and usable) if it has +// methods that return `Self` so long as they require `Self : Sized`. + + +trait Counter { + fn new() -> Self where Self : Sized; + fn tick(&mut self) -> u32; +} + +struct CCounter { + c: u32 +} + +impl Counter for CCounter { + fn new() -> CCounter { CCounter { c: 0 } } + fn tick(&mut self) -> u32 { self.c += 1; self.c } +} + +fn preticked() -> C { + let mut c: C = Counter::new(); + tick(&mut c); + c +} + +fn tick(c: &mut dyn Counter) { + tick_generic(c); +} + +fn tick_generic(c: &mut C) { + c.tick(); + c.tick(); +} + +fn main() { + let mut c = preticked::(); + tick(&mut c); + assert_eq!(c.tick(), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/point-at-arbitrary-self-type-method.rs b/gcc/testsuite/rust/rustc/ui/self/point-at-arbitrary-self-type-method.rs new file mode 100644 index 000000000000..4d2d6bbc6a9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/point-at-arbitrary-self-type-method.rs @@ -0,0 +1,10 @@ +struct A; + +impl A { + fn foo(self: Box) {} +} + +fn main() { + A.foo(); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/point-at-arbitrary-self-type-trait-method.rs b/gcc/testsuite/rust/rustc/ui/self/point-at-arbitrary-self-type-trait-method.rs new file mode 100644 index 000000000000..09f5d15f651d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/point-at-arbitrary-self-type-trait-method.rs @@ -0,0 +1,11 @@ +trait B { fn foo(self: Box); } +struct A; + +impl B for A { + fn foo(self: Box) {} +} + +fn main() { + A.foo() // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self-impl-2.rs b/gcc/testsuite/rust/rustc/ui/self/self-impl-2.rs new file mode 100644 index 000000000000..7067cf2f0c17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self-impl-2.rs @@ -0,0 +1,71 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test that we can use `Self` types in impls in the expected way. + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +struct Foo; + +// Test uses on inherent impl. +impl Foo { + fn foo(_x: Self, _y: &Self, _z: Box) -> Self { + Foo + } + + fn baz() { + // Test that Self cannot be shadowed. + type Foo = i32; + // There is no empty method on i32. + Self::empty(); + + let _: Self = Foo; + } + + fn empty() {} +} + +// Test uses when implementing a trait and with a type parameter. +pub struct Baz { + pub f: X, +} + +trait SuperBar { + type SuperQux; +} + +trait Bar: SuperBar { + type Qux; + + fn bar(x: Self, y: &Self, z: Box, _: Self::SuperQux) -> Self; + fn dummy(&self, x: X) { } +} + +impl SuperBar for Box> { + type SuperQux = bool; +} + +impl Bar for Box> { + type Qux = i32; + + fn bar(_x: Self, _y: &Self, _z: Box, _: Self::SuperQux) -> Self { + let _: Self::Qux = 42; + let _: >::Qux = 42; + + let _: Self::SuperQux = true; + let _: ::SuperQux = true; + + box Baz { f: 42 } + } +} + +fn main() { + let _: Foo = Foo::foo(Foo, &Foo, box Foo); + let _: Box> = Bar::bar(box Baz { f: 42 }, + &box Baz { f: 42 }, + box box Baz { f: 42 }, + true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self-impl.rs b/gcc/testsuite/rust/rustc/ui/self/self-impl.rs new file mode 100644 index 000000000000..002caa6fa931 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self-impl.rs @@ -0,0 +1,31 @@ +// Test that unsupported uses of `Self` in impls don't crash + +struct Bar; + +trait Foo { + type Baz; +} + +trait SuperFoo { + type SuperBaz; +} + +impl Foo for Bar { + type Baz = bool; +} + +impl SuperFoo for Bar { + type SuperBaz = bool; +} + +impl Bar { + fn f() { + let _: ::Baz = true; +// { dg-error ".E0223." "" { target *-*-* } .-1 } + let _: Self::Baz = true; +// { dg-error ".E0223." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self-in-mut-slot-default-method.rs b/gcc/testsuite/rust/rustc/ui/self/self-in-mut-slot-default-method.rs new file mode 100644 index 000000000000..596ac4391211 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self-in-mut-slot-default-method.rs @@ -0,0 +1,37 @@ +// run-pass +#![feature(box_syntax)] + +struct X { + a: isize +} + +trait Changer : Sized { + fn change(mut self) -> Self { + self.set_to(55); + self + } + + fn change_again(mut self: Box) -> Box { + self.set_to(45); + self + } + + fn set_to(&mut self, a: isize); +} + +impl Changer for X { + fn set_to(&mut self, a: isize) { + self.a = a; + } +} + +pub fn main() { + let x = X { a: 32 }; + let new_x = x.change(); + assert_eq!(new_x.a, 55); + + let x: Box<_> = box new_x; + let new_x = x.change_again(); + assert_eq!(new_x.a, 45); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self-in-mut-slot-immediate-value.rs b/gcc/testsuite/rust/rustc/ui/self/self-in-mut-slot-immediate-value.rs new file mode 100644 index 000000000000..e3450089872f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self-in-mut-slot-immediate-value.rs @@ -0,0 +1,24 @@ +// run-pass +// Assert that `mut self` on an immediate value doesn't +// allow mutating the original - issue #10615. + + +#[derive(Copy, Clone)] +struct Value { + n: isize +} + +impl Value { + fn squared(mut self) -> Value { + self.n *= self.n; + self + } +} + +pub fn main() { + let x = Value { n: 3 }; + let y = x.squared(); + assert_eq!(x.n, 3); + assert_eq!(y.n, 9); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self-in-typedefs.rs b/gcc/testsuite/rust/rustc/ui/self/self-in-typedefs.rs new file mode 100644 index 000000000000..4d9a18d8d42d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self-in-typedefs.rs @@ -0,0 +1,39 @@ +// build-pass (FIXME(62277): could be check-pass?) +#![allow(dead_code)] + +use std::mem::ManuallyDrop; + +enum A<'a, T: 'a> +where + Self: Send, T: PartialEq +{ + Foo(&'a Self), + Bar(T), +} + +struct B<'a, T: 'a> +where + Self: Send, T: PartialEq +{ + foo: &'a Self, + bar: T, +} + +union C<'a, T: 'a> +where + Self: Send, T: PartialEq +{ + foo: &'a Self, + bar: ManuallyDrop, +} + +union D<'a, T: 'a> +where + Self: Send, T: PartialEq + Copy +{ + foo: &'a Self, + bar: T, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self-infer.rs b/gcc/testsuite/rust/rustc/ui/self/self-infer.rs new file mode 100644 index 000000000000..ad053edaf594 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self-infer.rs @@ -0,0 +1,9 @@ +struct S; + +impl S { + fn f(self: _) {} // { dg-error ".E0121." "" { target *-*-* } } + fn g(self: &_) {} // { dg-error ".E0121." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self-re-assign.rs b/gcc/testsuite/rust/rustc/ui/self/self-re-assign.rs new file mode 100644 index 000000000000..9ef54e3eaa00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self-re-assign.rs @@ -0,0 +1,18 @@ +// run-pass +// Ensure assigning an owned or managed variable to itself works. In particular, +// that we do not glue_drop before we glue_take (#3290). + +#![feature(box_syntax)] + +use std::rc::Rc; + +pub fn main() { + let mut x: Box<_> = box 3; + x = x; + assert_eq!(*x, 3); + + let mut x = Rc::new(3); + x = x; + assert_eq!(*x, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self-shadowing-import.rs b/gcc/testsuite/rust/rustc/ui/self/self-shadowing-import.rs new file mode 100644 index 000000000000..53c3dee32247 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self-shadowing-import.rs @@ -0,0 +1,17 @@ +// run-pass + +mod a { + pub mod b { + pub mod a { + pub fn foo() -> isize { return 1; } + } + } +} + +mod c { + use a::b::a; + pub fn bar() { assert_eq!(a::foo(), 1); } +} + +pub fn main() { c::bar(); } + diff --git a/gcc/testsuite/rust/rustc/ui/self/self-type-param.rs b/gcc/testsuite/rust/rustc/ui/self/self-type-param.rs new file mode 100644 index 000000000000..7035ca840b37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self-type-param.rs @@ -0,0 +1,20 @@ +// build-pass (FIXME(62277): could be check-pass?) +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait MyTrait { + fn f(&self) -> Self; +} + +struct S { + x: isize +} + +impl MyTrait for S { + fn f(&self) -> S { + S { x: 3 } + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self-vs-path-ambiguity.rs b/gcc/testsuite/rust/rustc/ui/self/self-vs-path-ambiguity.rs new file mode 100644 index 000000000000..f4bd87a708f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self-vs-path-ambiguity.rs @@ -0,0 +1,13 @@ +// Check that `self::foo` is parsed as a general pattern and not a self argument. + +struct S; + +impl S { + fn f(self::S: S) {} + fn g(&self::S: &S) {} + fn h(&mut self::S: &mut S) {} + fn i(&'a self::S: &S) {} // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self_lifetime-async.rs b/gcc/testsuite/rust/rustc/ui/self/self_lifetime-async.rs new file mode 100644 index 000000000000..dbbd6e41a774 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self_lifetime-async.rs @@ -0,0 +1,15 @@ +// check-pass +// edition:2018 + +struct Foo<'a>(&'a ()); +impl<'a> Foo<'a> { + async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } +} + +type Alias = Foo<'static>; +impl Alias { + async fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self_lifetime.rs b/gcc/testsuite/rust/rustc/ui/self/self_lifetime.rs new file mode 100644 index 000000000000..f607515c2a38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self_lifetime.rs @@ -0,0 +1,16 @@ +// check-pass + +// https://github.com/rust-lang/rust/pull/60944#issuecomment-495346120 + +struct Foo<'a>(&'a ()); +impl<'a> Foo<'a> { + fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } +} + +type Alias = Foo<'static>; +impl Alias { + fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self_type_keyword-2.rs b/gcc/testsuite/rust/rustc/ui/self/self_type_keyword-2.rs new file mode 100644 index 000000000000..7e723a6c88de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self_type_keyword-2.rs @@ -0,0 +1,14 @@ +use self::Self as Foo; // { dg-error ".E0432." "" { target *-*-* } } + +pub fn main() { + let Self = 5; +// { dg-error ".E0531." "" { target *-*-* } .-1 } + + match 15 { + Self => (), +// { dg-error ".E0531." "" { target *-*-* } .-1 } + Foo { x: Self } => (), +// { dg-error ".E0531." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/self_type_keyword.rs b/gcc/testsuite/rust/rustc/ui/self/self_type_keyword.rs new file mode 100644 index 000000000000..5f59a81d2587 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/self_type_keyword.rs @@ -0,0 +1,42 @@ +mod foo { + struct Self; +// { dg-error "" "" { target *-*-* } .-1 } +} + +struct Bar<'Self>; +// { dg-error ".E0392." "" { target *-*-* } .-1 } +// { dg-error ".E0392." "" { target *-*-* } .-2 } + +struct Foo; + +pub fn main() { + match 15 { + ref Self => (), +// { dg-error "" "" { target *-*-* } .-1 } + mut Self => (), +// { dg-error ".E0531." "" { target *-*-* } .-1 } +// { dg-error ".E0531." "" { target *-*-* } .-2 } + ref mut Self => (), +// { dg-error "" "" { target *-*-* } .-1 } + Self!() => (), +// { dg-error "" "" { target *-*-* } .-1 } + Foo { Self } => (), +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +mod m1 { + extern crate core as Self; +// { dg-error "" "" { target *-*-* } .-1 } +} + +mod m2 { + use std::option::Option as Self; +// { dg-error "" "" { target *-*-* } .-1 } +} + +mod m3 { + trait Self {} +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/string-self-append.rs b/gcc/testsuite/rust/rustc/ui/self/string-self-append.rs new file mode 100644 index 000000000000..506fe275ad6a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/string-self-append.rs @@ -0,0 +1,15 @@ +// run-pass +pub fn main() { + // Make sure we properly handle repeated self-appends. + let mut a: String = "A".to_string(); + let mut i = 20; + let mut expected_len = 1; + while i > 0 { + println!("{}", a.len()); + assert_eq!(a.len(), expected_len); + a = format!("{}{}", a, a); + i -= 1; + expected_len *= 2; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/suggest-self-2.rs b/gcc/testsuite/rust/rustc/ui/self/suggest-self-2.rs new file mode 100644 index 000000000000..b887f60b1670 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/suggest-self-2.rs @@ -0,0 +1,26 @@ +struct Foo {} + +impl Foo { + fn foo(&self) { + bar(self); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { help ".E0425." "" { target *-*-* } .-2 } + + bar(&&self, 102); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { help ".E0425." "" { target *-*-* } .-2 } + + bar(&mut self, 102, &"str"); +// { dg-error ".E0425." "" { target *-*-* } .-1 } +// { help ".E0425." "" { target *-*-* } .-2 } + + bar(); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + + self.bar(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/self/suggest-self.rs b/gcc/testsuite/rust/rustc/ui/self/suggest-self.rs new file mode 100644 index 000000000000..2efe4c279b1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/suggest-self.rs @@ -0,0 +1,42 @@ +struct Foo { + x: i32, +} + +impl Foo { + fn this1(&self) -> i32 { + let this = self; + let a = 1; + this.x + } + + fn this2(&self) -> i32 { + let a = Foo { + x: 2 + }; + let this = a; + this.x + } + + fn foo(&self) -> i32 { + this.x +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } + + fn bar(&self) -> i32 { + this.foo() +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } + + fn baz(&self) -> i32 { + my.bar() +// { dg-error ".E0425." "" { target *-*-* } .-1 } + } +} + +fn main() { + let this = vec![1, 2, 3]; + let my = vec![1, 2, 3]; + let len = this.len(); + let len = my.len(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/ufcs-explicit-self.rs b/gcc/testsuite/rust/rustc/ui/self/ufcs-explicit-self.rs new file mode 100644 index 000000000000..d63392ef8043 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/ufcs-explicit-self.rs @@ -0,0 +1,50 @@ +// run-pass +#![feature(box_syntax)] + +#[derive(Copy, Clone)] +struct Foo { + f: isize, +} + +impl Foo { + fn foo(self: Foo, x: isize) -> isize { + self.f + x + } + fn bar(self: &Foo, x: isize) -> isize { + self.f + x + } + fn baz(self: Box, x: isize) -> isize { + self.f + x + } +} + +#[derive(Copy, Clone)] +struct Bar { + f: T, +} + +impl Bar { + fn foo(self: Bar, x: isize) -> isize { + x + } + fn bar<'a>(self: &'a Bar, x: isize) -> isize { + x + } + fn baz(self: Bar, x: isize) -> isize { + x + } +} + +fn main() { + let foo: Box<_> = box Foo { + f: 1, + }; + println!("{} {} {}", foo.foo(2), foo.bar(2), foo.baz(2)); + let bar: Box<_> = box Bar { + f: 1, + }; + println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2)); + let bar: Box> = bar; + println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/uniq-self-in-mut-slot.rs b/gcc/testsuite/rust/rustc/ui/self/uniq-self-in-mut-slot.rs new file mode 100644 index 000000000000..ee9f5f99b558 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/uniq-self-in-mut-slot.rs @@ -0,0 +1,24 @@ +// run-pass +#![feature(box_syntax)] + +struct X { + a: isize +} + +trait Changer { + fn change(self: Box) -> Box; +} + +impl Changer for X { + fn change(mut self: Box) -> Box { + self.a = 55; + self + } +} + +pub fn main() { + let x: Box<_> = box X { a: 32 }; + let new_x = x.change(); + assert_eq!(new_x.a, 55); +} + diff --git a/gcc/testsuite/rust/rustc/ui/self/where-for-self.rs b/gcc/testsuite/rust/rustc/ui/self/where-for-self.rs new file mode 100644 index 000000000000..c8e80419a784 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/self/where-for-self.rs @@ -0,0 +1,52 @@ +// run-pass +// Test that we can quantify lifetimes outside a constraint (i.e., including +// the self type) in a where clause. + + +static mut COUNT: u32 = 1; + +trait Bar<'a> { + fn bar(&self); +} + +trait Baz<'a> +{ + fn baz(&self); +} + +impl<'a, 'b> Bar<'b> for &'a u32 { + fn bar(&self) { + unsafe { COUNT *= 2; } + } +} + +impl<'a, 'b> Baz<'b> for &'a u32 { + fn baz(&self) { + unsafe { COUNT *= 3; } + } +} + +// Test we can use the syntax for HRL including the self type. +fn foo1(x: &T) + where for<'a, 'b> &'a T: Bar<'b> +{ + x.bar() +} + +// Test we can quantify multiple bounds (i.e., the precedence is sensible). +fn foo2(x: &T) + where for<'a, 'b> &'a T: Bar<'b> + Baz<'b> +{ + x.baz(); + x.bar() +} + +fn main() { + let x = 42; + foo1(&x); + foo2(&x); + unsafe { + assert_eq!(COUNT, 12); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/semistatement-in-lambda.rs b/gcc/testsuite/rust/rustc/ui/semistatement-in-lambda.rs new file mode 100644 index 000000000000..17003b2f69d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/semistatement-in-lambda.rs @@ -0,0 +1,13 @@ +// run-pass + +#![allow(unused_must_use)] + +pub fn main() { + // Test that lambdas behave as unary expressions with block-like expressions + -if true { 1 } else { 2 } * 3; + || if true { 1 } else { 2 } * 3; + + // The following is invalid and parses as `if true { 1 } else { 2 }; *3` + // if true { 1 } else { 2 } * 3 +} + diff --git a/gcc/testsuite/rust/rustc/ui/sepcomp/auxiliary/sepcomp-extern-lib.rs b/gcc/testsuite/rust/rustc/ui/sepcomp/auxiliary/sepcomp-extern-lib.rs new file mode 100644 index 000000000000..266afa2d2bb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sepcomp/auxiliary/sepcomp-extern-lib.rs @@ -0,0 +1,5 @@ +#[no_mangle] +pub extern "C" fn foo() -> usize { + 1234 +} + diff --git a/gcc/testsuite/rust/rustc/ui/sepcomp/auxiliary/sepcomp_cci_lib.rs b/gcc/testsuite/rust/rustc/ui/sepcomp/auxiliary/sepcomp_cci_lib.rs new file mode 100644 index 000000000000..e9e6bc0228b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sepcomp/auxiliary/sepcomp_cci_lib.rs @@ -0,0 +1,7 @@ +#[inline] +pub fn cci_fn() -> usize { + 1200 +} + +pub const CCI_CONST: usize = 34; + diff --git a/gcc/testsuite/rust/rustc/ui/sepcomp/auxiliary/sepcomp_lib.rs b/gcc/testsuite/rust/rustc/ui/sepcomp/auxiliary/sepcomp_lib.rs new file mode 100644 index 000000000000..f7bbf9459ddb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sepcomp/auxiliary/sepcomp_lib.rs @@ -0,0 +1,22 @@ +// compile-flags: -C codegen-units=3 --crate-type=rlib,dylib -g + +pub mod a { + pub fn one() -> usize { + 1 + } +} + +pub mod b { + pub fn two() -> usize { + 2 + } +} + +pub mod c { + use a::one; + use b::two; + pub fn three() -> usize { + one() + two() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-cci.rs b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-cci.rs new file mode 100644 index 000000000000..760bf272a748 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-cci.rs @@ -0,0 +1,34 @@ +// run-pass +// compile-flags: -C codegen-units=3 +// aux-build:sepcomp_cci_lib.rs + +// Test accessing cross-crate inlined items from multiple compilation units. + + +extern crate sepcomp_cci_lib; +use sepcomp_cci_lib::{cci_fn, CCI_CONST}; + +fn call1() -> usize { + cci_fn() + CCI_CONST +} + +mod a { + use sepcomp_cci_lib::{cci_fn, CCI_CONST}; + pub fn call2() -> usize { + cci_fn() + CCI_CONST + } +} + +mod b { + use sepcomp_cci_lib::{cci_fn, CCI_CONST}; + pub fn call3() -> usize { + cci_fn() + CCI_CONST + } +} + +fn main() { + assert_eq!(call1(), 1234); + assert_eq!(a::call2(), 1234); + assert_eq!(b::call3(), 1234); +} + diff --git a/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-extern.rs b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-extern.rs new file mode 100644 index 000000000000..38c5f39b32f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-extern.rs @@ -0,0 +1,34 @@ +// run-pass +// compile-flags: -C codegen-units=3 +// aux-build:sepcomp-extern-lib.rs + +// Test accessing external items from multiple compilation units. + +extern crate sepcomp_extern_lib; + +extern { + fn foo() -> usize; +} + +fn call1() -> usize { + unsafe { foo() } +} + +mod a { + pub fn call2() -> usize { + unsafe { ::foo() } + } +} + +mod b { + pub fn call3() -> usize { + unsafe { ::foo() } + } +} + +fn main() { + assert_eq!(call1(), 1234); + assert_eq!(a::call2(), 1234); + assert_eq!(b::call3(), 1234); +} + diff --git a/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-fns-backwards.rs b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-fns-backwards.rs new file mode 100644 index 000000000000..c8efeed419f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-fns-backwards.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(dead_code)] +// compile-flags: -C codegen-units=3 + +// Test references to items that haven't been codegened yet. + +// Generate some code in the first compilation unit before declaring any +// modules. This ensures that the first module doesn't go into the same +// compilation unit as the top-level module. + +fn pad() -> usize { 0 } + +mod b { + pub fn three() -> usize { + ::one() + ::a::two() + } +} + +mod a { + pub fn two() -> usize { + ::one() + ::one() + } +} + +fn one() -> usize { + 1 +} + +fn main() { + assert_eq!(one(), 1); + assert_eq!(a::two(), 2); + assert_eq!(b::three(), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-fns.rs b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-fns.rs new file mode 100644 index 000000000000..a4948b1bea53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-fns.rs @@ -0,0 +1,31 @@ +// run-pass +// compile-flags: -C codegen-units=3 + +// Test basic separate compilation functionality. The functions should be able +// to call each other even though they will be placed in different compilation +// units. + +// Generate some code in the first compilation unit before declaring any +// modules. This ensures that the first module doesn't go into the same +// compilation unit as the top-level module. + +fn one() -> usize { 1 } + +mod a { + pub fn two() -> usize { + ::one() + ::one() + } +} + +mod b { + pub fn three() -> usize { + ::one() + ::a::two() + } +} + +fn main() { + assert_eq!(one(), 1); + assert_eq!(a::two(), 2); + assert_eq!(b::three(), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-lib-lto.rs b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-lib-lto.rs new file mode 100644 index 000000000000..5aab651b57c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-lib-lto.rs @@ -0,0 +1,20 @@ +// run-pass +// Check that we can use `-C lto` when linking against libraries that were +// separately compiled. + +// aux-build:sepcomp_lib.rs +// compile-flags: -C lto -g +// ignore-asmjs wasm2js does not support source maps yet +// no-prefer-dynamic + +extern crate sepcomp_lib; +use sepcomp_lib::a::one; +use sepcomp_lib::b::two; +use sepcomp_lib::c::three; + +fn main() { + assert_eq!(one(), 1); + assert_eq!(two(), 2); + assert_eq!(three(), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-lib.rs b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-lib.rs new file mode 100644 index 000000000000..59154828a8ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-lib.rs @@ -0,0 +1,17 @@ +// run-pass +// aux-build:sepcomp_lib.rs + +// Test linking against a library built with -C codegen-units > 1 + + +extern crate sepcomp_lib; +use sepcomp_lib::a::one; +use sepcomp_lib::b::two; +use sepcomp_lib::c::three; + +fn main() { + assert_eq!(one(), 1); + assert_eq!(two(), 2); + assert_eq!(three(), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-statics.rs b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-statics.rs new file mode 100644 index 000000000000..aaef49bd4463 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-statics.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(dead_code)] +// compile-flags: -C codegen-units=3 + +// Test references to static items across compilation units. + + +fn pad() -> usize { 0 } + +const ONE: usize = 1; + +mod b { + // Separate compilation always switches to the LLVM module with the fewest + // instructions. Make sure we have some instructions in this module so + // that `a` and `b` don't go into the same compilation unit. + fn pad() -> usize { 0 } + + pub static THREE: usize = ::ONE + ::a::TWO; +} + +mod a { + fn pad() -> usize { 0 } + + pub const TWO: usize = ::ONE + ::ONE; +} + +fn main() { + assert_eq!(ONE, 1); + assert_eq!(a::TWO, 2); + assert_eq!(b::THREE, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-unwind.rs b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-unwind.rs new file mode 100644 index 000000000000..2d3e319b5b9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sepcomp/sepcomp-unwind.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(dead_code)] +// compile-flags: -C codegen-units=3 +// ignore-emscripten no threads support + +// Test unwinding through multiple compilation units. + +// According to acrichto, in the distant past `ld -r` (which is used during +// linking when codegen-units > 1) was known to produce object files with +// damaged unwinding tables. This may be related to GNU binutils bug #6893 +// ("Partial linking results in corrupt .eh_frame_hdr"), but I'm not certain. +// In any case, this test should let us know if enabling parallel codegen ever +// breaks unwinding. + + +use std::thread; + +fn pad() -> usize { 0 } + +mod a { + pub fn f() { + panic!(); + } +} + +mod b { + pub fn g() { + ::a::f(); + } +} + +fn main() { + thread::spawn(move|| { ::b::g() }).join().unwrap_err(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/seq-args.rs b/gcc/testsuite/rust/rustc/ui/seq-args.rs new file mode 100644 index 000000000000..b2aec2c79fd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/seq-args.rs @@ -0,0 +1,12 @@ +fn main() { +trait Seq { } + +impl Seq for Vec { // { dg-error ".E0107." "" { target *-*-* } } + /* ... */ +} +impl Seq for u32 { // { dg-error ".E0107." "" { target *-*-* } } + /* Treat the integer as a sequence of bits */ +} + +} + diff --git a/gcc/testsuite/rust/rustc/ui/seq-compare.rs b/gcc/testsuite/rust/rustc/ui/seq-compare.rs new file mode 100644 index 000000000000..7d00e134a4fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/seq-compare.rs @@ -0,0 +1,17 @@ +// run-pass + +pub fn main() { + assert!(("hello".to_string() < "hellr".to_string())); + assert!(("hello ".to_string() > "hello".to_string())); + assert!(("hello".to_string() != "there".to_string())); + assert!((vec![1, 2, 3, 4] > vec![1, 2, 3])); + assert!((vec![1, 2, 3] < vec![1, 2, 3, 4])); + assert!((vec![1, 2, 4, 4] > vec![1, 2, 3, 4])); + assert!((vec![1, 2, 3, 4] < vec![1, 2, 4, 4])); + assert!((vec![1, 2, 3] <= vec![1, 2, 3])); + assert!((vec![1, 2, 3] <= vec![1, 2, 3, 3])); + assert!((vec![1, 2, 3, 4] > vec![1, 2, 3])); + assert_eq!(vec![1, 2, 3], vec![1, 2, 3]); + assert!((vec![1, 2, 3] != vec![1, 1, 3])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/shadow-bool.rs b/gcc/testsuite/rust/rustc/ui/shadow-bool.rs new file mode 100644 index 000000000000..a7bb87be7b6b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/shadow-bool.rs @@ -0,0 +1,19 @@ +// check-pass + +mod bar { + pub trait QueryId { + const SOME_PROPERTY: bool; + } +} + +use bar::QueryId; + +#[allow(non_camel_case_types)] +pub struct bool; + +impl QueryId for bool { + const SOME_PROPERTY: core::primitive::bool = true; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/shadow.rs b/gcc/testsuite/rust/rustc/ui/shadow.rs new file mode 100644 index 000000000000..ea182938725a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/shadow.rs @@ -0,0 +1,25 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +fn foo(c: Vec ) { + let a: isize = 5; + let mut b: Vec = Vec::new(); + + + match t::none:: { + t::some::(_) => { + for _i in &c { + println!("{}", a); + let a = 17; + b.push(a); + } + } + _ => { } + } +} + +enum t { none, some(T), } + +pub fn main() { let x = 10; let x = x + 20; assert_eq!(x, 30); foo(Vec::new()); } + diff --git a/gcc/testsuite/rust/rustc/ui/shadowed-use-visibility.rs b/gcc/testsuite/rust/rustc/ui/shadowed-use-visibility.rs new file mode 100644 index 000000000000..f8e213176253 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/shadowed-use-visibility.rs @@ -0,0 +1,14 @@ +// run-pass + +#![allow(unused_imports)] +mod foo { + pub fn f() {} + + pub use self::f as bar; + use foo as bar; +} + +fn main() { + foo::bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/shadowed/shadowed-lifetime.rs b/gcc/testsuite/rust/rustc/ui/shadowed/shadowed-lifetime.rs new file mode 100644 index 000000000000..b94611e77247 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/shadowed/shadowed-lifetime.rs @@ -0,0 +1,25 @@ +// Test that shadowed lifetimes generate an error. + +struct Foo<'a>(&'a isize); + +impl<'a> Foo<'a> { + fn shadow_in_method<'a>(&'a self) -> &'a isize { +// { dg-error ".E0496." "" { target *-*-* } .-1 } + self.0 + } + + fn shadow_in_type<'b>(&'b self) -> &'b isize { + let x: for<'b> fn(&'b isize) = panic!(); +// { dg-error ".E0496." "" { target *-*-* } .-1 } + self.0 + } + + fn not_shadow_in_item<'b>(&'b self) { + struct Bar<'a, 'b>(&'a isize, &'b isize); // not a shadow, separate item + fn foo<'a, 'b>(x: &'a isize, y: &'b isize) { } // same + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/shadowed/shadowed-trait-methods.rs b/gcc/testsuite/rust/rustc/ui/shadowed/shadowed-trait-methods.rs new file mode 100644 index 000000000000..0c44b16525fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/shadowed/shadowed-trait-methods.rs @@ -0,0 +1,15 @@ +// Test that methods from shadowed traits cannot be used + +mod foo { + pub trait T { fn f(&self) {} } + impl T for () {} +} + +mod bar { pub use foo::T; } + +fn main() { + pub use bar::*; + struct T; + ().f() // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/shadowed/shadowed-type-parameter.rs b/gcc/testsuite/rust/rustc/ui/shadowed/shadowed-type-parameter.rs new file mode 100644 index 000000000000..ea04d9996a47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/shadowed/shadowed-type-parameter.rs @@ -0,0 +1,31 @@ +// Test that shadowed lifetimes generate an error. + +#![feature(box_syntax)] + +struct Foo(T); + +impl Foo { + fn shadow_in_method(&self) {} +// { dg-error ".E0403." "" { target *-*-* } .-1 } + + fn not_shadow_in_item(&self) { + struct Bar(T,U); // not a shadow, separate item + fn foo() {} // same + } +} + +trait Bar { + fn dummy(&self) -> T; + + fn shadow_in_required(&self); +// { dg-error ".E0403." "" { target *-*-* } .-1 } + + fn shadow_in_provided(&self) {} +// { dg-error ".E0403." "" { target *-*-* } .-1 } + + fn not_shadow_in_required(&self); + fn not_shadow_in_provided(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/shadowed/shadowed-use-visibility.rs b/gcc/testsuite/rust/rustc/ui/shadowed/shadowed-use-visibility.rs new file mode 100644 index 000000000000..b389e570c6e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/shadowed/shadowed-use-visibility.rs @@ -0,0 +1,17 @@ +mod foo { + pub fn f() {} + + use foo as bar; + pub use self::f as bar; +} + +mod bar { + use foo::bar::f as g; // { dg-error ".E0603." "" { target *-*-* } } + + use foo as f; + pub use foo::*; +} + +use bar::f::f; // { dg-error ".E0603." "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/shadowed/shadowing-in-the-same-pattern.rs b/gcc/testsuite/rust/rustc/ui/shadowed/shadowing-in-the-same-pattern.rs new file mode 100644 index 000000000000..2748125382bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/shadowed/shadowing-in-the-same-pattern.rs @@ -0,0 +1,8 @@ +// Test for issue #14581. + +fn f((a, a): (isize, isize)) {} // { dg-error ".E0415." "" { target *-*-* } } + +fn main() { + let (a, a) = (1, 1); // { dg-error ".E0416." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/shift-various-bad-types.rs b/gcc/testsuite/rust/rustc/ui/shift-various-bad-types.rs new file mode 100644 index 000000000000..f27954ed9908 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/shift-various-bad-types.rs @@ -0,0 +1,32 @@ +// Test that we can do shifts by any integral type. + +struct Panolpy { + char: char, + str: &'static str, +} + +fn foo(p: &Panolpy) { + 22 >> p.char; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + 22 >> p.str; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + 22 >> p; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + let x; + 22 >> x; // ambiguity error winds up being suppressed + + 22 >> 1; + // Integer literal types are OK + + // Type of the result follows the LHS, not the RHS: + let _: i32 = 22_i64 >> 1_i32; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/short-error-format.rs b/gcc/testsuite/rust/rustc/ui/short-error-format.rs new file mode 100644 index 000000000000..fa48919550fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/short-error-format.rs @@ -0,0 +1,10 @@ +// compile-flags: --error-format=short + +fn foo(_: u32) {} + +fn main() { + foo("Bonjour".to_owned()); + let x = 0u32; + x.salut(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/signal-alternate-stack-cleanup.rs b/gcc/testsuite/rust/rustc/ui/signal-alternate-stack-cleanup.rs new file mode 100644 index 000000000000..ec208b35ca2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/signal-alternate-stack-cleanup.rs @@ -0,0 +1,39 @@ +// run-pass +// Previously memory for alternate signal stack have been unmapped during +// main thread exit while still being in use by signal handlers. This test +// triggers this situation by sending signal from atexit handler. +// +// ignore-cloudabi no signal handling support +// ignore-wasm32-bare no libc +// ignore-windows +// ignore-sgx no libc +// ignore-vxworks no SIGWINCH in user space + +#![feature(rustc_private)] +extern crate libc; + +use libc::*; + +unsafe extern fn signal_handler(signum: c_int, _: *mut siginfo_t, _: *mut c_void) { + assert_eq!(signum, SIGWINCH); +} + +extern fn send_signal() { + unsafe { + raise(SIGWINCH); + } +} + +fn main() { + unsafe { + // Install signal handler that runs on alternate signal stack. + let mut action: sigaction = std::mem::zeroed(); + action.sa_flags = (SA_ONSTACK | SA_SIGINFO) as _; + action.sa_sigaction = signal_handler as sighandler_t; + sigaction(SIGWINCH, &action, std::ptr::null_mut()); + + // Send SIGWINCH on exit. + atexit(send_signal); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/signal-exit-status.rs b/gcc/testsuite/rust/rustc/ui/signal-exit-status.rs new file mode 100644 index 000000000000..d39d603d6de7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/signal-exit-status.rs @@ -0,0 +1,20 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +// ignore-windows + +use std::env; +use std::process::Command; + +pub fn main() { + let args: Vec = env::args().collect(); + if args.len() >= 2 && args[1] == "signal" { + // Raise a segfault. + unsafe { *(1 as *mut isize) = 0; } + } else { + let status = Command::new(&args[0]).arg("signal").status().unwrap(); + assert!(status.code().is_none()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/sigpipe-should-be-ignored.rs b/gcc/testsuite/rust/rustc/ui/sigpipe-should-be-ignored.rs new file mode 100644 index 000000000000..b35ed25d23a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sigpipe-should-be-ignored.rs @@ -0,0 +1,35 @@ +// run-pass + +#![allow(unused_must_use)] +// Be sure that when a SIGPIPE would have been received that the entire process +// doesn't die in a ball of fire, but rather it's gracefully handled. + +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::env; +use std::io::prelude::*; +use std::io; +use std::process::{Command, Stdio}; + +fn test() { + let _ = io::stdin().read_line(&mut String::new()); + io::stdout().write(&[1]); + assert!(io::stdout().flush().is_err()); +} + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "test" { + return test(); + } + + let mut p = Command::new(&args[0]) + .stdout(Stdio::piped()) + .stdin(Stdio::piped()) + .arg("test").spawn().unwrap(); + drop(p.stdout.take()); + assert!(p.wait().unwrap().success()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs new file mode 100644 index 000000000000..7f1083680135 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs @@ -0,0 +1,40 @@ +// build-fail +// ignore-emscripten +// ignore-tidy-linelength +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct i32x4(pub i32, pub i32, pub i32, pub i32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct x4(pub T, pub T, pub T, pub T); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct f32x4(pub f32, pub f32, pub f32, pub f32); + +extern "platform-intrinsic" { + fn simd_saturating_add(x: T, y: T) -> T; + fn simd_saturating_sub(x: T, y: T) -> T; +} + +fn main() { + let x = i32x4(0, 0, 0, 0); + let y = x4(0_usize, 0, 0, 0); + let z = f32x4(0.0, 0.0, 0.0, 0.0); + + unsafe { + simd_saturating_add(x, x); + simd_saturating_add(y, y); + simd_saturating_sub(x, x); + simd_saturating_sub(y, y); + + simd_saturating_add(z, z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_saturating_sub(z, z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.rs b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.rs new file mode 100644 index 000000000000..7bbdaeb5fbe7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.rs @@ -0,0 +1,96 @@ +// build-fail + +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct i32x4(pub i32, pub i32, pub i32, pub i32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct f32x4(pub f32, pub f32, pub f32, pub f32); + +extern "platform-intrinsic" { + fn simd_add(x: T, y: T) -> T; + fn simd_sub(x: T, y: T) -> T; + fn simd_mul(x: T, y: T) -> T; + fn simd_div(x: T, y: T) -> T; + fn simd_rem(x: T, y: T) -> T; + fn simd_shl(x: T, y: T) -> T; + fn simd_shr(x: T, y: T) -> T; + fn simd_and(x: T, y: T) -> T; + fn simd_or(x: T, y: T) -> T; + fn simd_xor(x: T, y: T) -> T; +} + +fn main() { + let x = i32x4(0, 0, 0, 0); + let y = u32x4(0, 0, 0, 0); + let z = f32x4(0.0, 0.0, 0.0, 0.0); + + unsafe { + simd_add(x, x); + simd_add(y, y); + simd_add(z, z); + simd_sub(x, x); + simd_sub(y, y); + simd_sub(z, z); + simd_mul(x, x); + simd_mul(y, y); + simd_mul(z, z); + simd_div(x, x); + simd_div(y, y); + simd_div(z, z); + simd_rem(x, x); + simd_rem(y, y); + simd_rem(z, z); + + simd_shl(x, x); + simd_shl(y, y); + simd_shr(x, x); + simd_shr(y, y); + simd_and(x, x); + simd_and(y, y); + simd_or(x, x); + simd_or(y, y); + simd_xor(x, x); + simd_xor(y, y); + + + simd_add(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_sub(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_mul(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_div(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_shl(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_shr(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_and(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_or(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_xor(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + + simd_shl(z, z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_shr(z, z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_and(z, z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_or(z, z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_xor(z, z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs new file mode 100644 index 000000000000..80f46ccb63d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs @@ -0,0 +1,93 @@ +// build-fail + +// Test that the simd_bitmask intrinsic produces ok-ish error +// messages when misused. + +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct u32x2(pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x8( + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, +); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x16( + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, +); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x32( + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, +); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x64( + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, + pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, +); + +extern "platform-intrinsic" { + fn simd_bitmask(x: T) -> U; +} + +fn main() { + let m2 = u32x2(0, 0); + let m4 = u32x4(0, 0, 0, 0); + let m8 = u8x8(0, 0, 0, 0, 0, 0, 0, 0); + let m16 = u8x16(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + let m32 = u8x32(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + let m64 = u8x64(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + + unsafe { + let _: u8 = simd_bitmask(m2); + let _: u8 = simd_bitmask(m4); + let _: u8 = simd_bitmask(m8); + let _: u16 = simd_bitmask(m16); + let _: u32 = simd_bitmask(m32); + let _: u64 = simd_bitmask(m64); + + let _: u16 = simd_bitmask(m2); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + let _: u16 = simd_bitmask(m8); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + let _: u32 = simd_bitmask(m16); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + let _: u64 = simd_bitmask(m32); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + let _: u128 = simd_bitmask(m64); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-cast.rs b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-cast.rs new file mode 100644 index 000000000000..9e4d2f74998b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-cast.rs @@ -0,0 +1,44 @@ +// build-fail + +#![feature(repr_simd, platform_intrinsics)] + +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct i32x4(i32, i32, i32, i32); +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct i32x8(i32, i32, i32, i32, + i32, i32, i32, i32); + +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct f32x4(f32, f32, f32, f32); +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct f32x8(f32, f32, f32, f32, + f32, f32, f32, f32); + + +extern "platform-intrinsic" { + fn simd_cast(x: T) -> U; +} + +fn main() { + let x = i32x4(0, 0, 0, 0); + + unsafe { + simd_cast::(0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_cast::(0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_cast::(x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_cast::<_, i32x8>(x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-comparison.rs b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-comparison.rs new file mode 100644 index 000000000000..ddf200f93030 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-comparison.rs @@ -0,0 +1,68 @@ +// build-fail + +#![feature(repr_simd, platform_intrinsics)] + +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct i32x4(i32, i32, i32, i32); +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct i16x8(i16, i16, i16, i16, + i16, i16, i16, i16); + +extern "platform-intrinsic" { + fn simd_eq(x: T, y: T) -> U; + fn simd_ne(x: T, y: T) -> U; + fn simd_lt(x: T, y: T) -> U; + fn simd_le(x: T, y: T) -> U; + fn simd_gt(x: T, y: T) -> U; + fn simd_ge(x: T, y: T) -> U; +} + +fn main() { + let x = i32x4(0, 0, 0, 0); + + unsafe { + simd_eq::(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_ne::(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_lt::(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_le::(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_gt::(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_ge::(0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + simd_eq::<_, i32>(x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_ne::<_, i32>(x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_lt::<_, i32>(x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_le::<_, i32>(x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_gt::<_, i32>(x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_ge::<_, i32>(x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + simd_eq::<_, i16x8>(x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_ne::<_, i16x8>(x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_lt::<_, i16x8>(x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_le::<_, i16x8>(x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_gt::<_, i16x8>(x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_ge::<_, i16x8>(x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-elements.rs b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-elements.rs new file mode 100644 index 000000000000..3b586ebb0e64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-elements.rs @@ -0,0 +1,90 @@ +// build-fail + +#![feature(repr_simd, platform_intrinsics, rustc_attrs)] + +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct i32x2(i32, i32); +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct i32x3(i32, i32, i32); +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct i32x4(i32, i32, i32, i32); +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct i32x8(i32, i32, i32, i32, + i32, i32, i32, i32); + +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct f32x2(f32, f32); +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct f32x3(f32, f32, f32); +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct f32x4(f32, f32, f32, f32); +#[repr(simd)] +#[derive(Copy, Clone)] +#[allow(non_camel_case_types)] +struct f32x8(f32, f32, f32, f32, + f32, f32, f32, f32); + +extern "platform-intrinsic" { + fn simd_insert(x: T, idx: u32, y: E) -> T; + fn simd_extract(x: T, idx: u32) -> E; + + fn simd_shuffle2(x: T, y: T, idx: [u32; 2]) -> U; + fn simd_shuffle3(x: T, y: T, idx: [u32; 3]) -> U; + fn simd_shuffle4(x: T, y: T, idx: [u32; 4]) -> U; + fn simd_shuffle8(x: T, y: T, idx: [u32; 8]) -> U; +} + +fn main() { + let x = i32x4(0, 0, 0, 0); + + unsafe { + simd_insert(0, 0, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_insert(x, 0, 1.0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_extract::<_, f32>(x, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + simd_shuffle2::(0, 0, [0; 2]); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_shuffle3::(0, 0, [0; 3]); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_shuffle4::(0, 0, [0; 4]); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_shuffle8::(0, 0, [0; 8]); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + simd_shuffle2::<_, f32x2>(x, x, [0; 2]); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_shuffle3::<_, f32x3>(x, x, [0; 3]); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_shuffle4::<_, f32x4>(x, x, [0; 4]); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_shuffle8::<_, f32x8>(x, x, [0; 8]); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + simd_shuffle2::<_, i32x8>(x, x, [0; 2]); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_shuffle3::<_, i32x4>(x, x, [0; 3]); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_shuffle4::<_, i32x3>(x, x, [0; 4]); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_shuffle8::<_, i32x2>(x, x, [0; 8]); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs new file mode 100644 index 000000000000..9551b83a6ede --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs @@ -0,0 +1,59 @@ +// build-fail +// ignore-emscripten + +// Test that the simd_reduce_{op} intrinsics produce ok-ish error +// messages when misused. + +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct u32x4(pub u32, pub u32, pub u32, pub u32); + + +extern "platform-intrinsic" { + fn simd_reduce_add_ordered(x: T, y: U) -> U; + fn simd_reduce_mul_ordered(x: T, y: U) -> U; + fn simd_reduce_and(x: T) -> U; + fn simd_reduce_or(x: T) -> U; + fn simd_reduce_xor(x: T) -> U; + fn simd_reduce_all(x: T) -> bool; + fn simd_reduce_any(x: T) -> bool; +} + +fn main() { + let x = u32x4(0, 0, 0, 0); + let z = f32x4(0.0, 0.0, 0.0, 0.0); + + unsafe { + simd_reduce_add_ordered(z, 0); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + simd_reduce_mul_ordered(z, 1); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + let _: f32 = simd_reduce_and(x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + let _: f32 = simd_reduce_or(x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + let _: f32 = simd_reduce_xor(x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + let _: f32 = simd_reduce_and(z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + let _: f32 = simd_reduce_or(z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + let _: f32 = simd_reduce_xor(z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + let _: bool = simd_reduce_all(z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + let _: bool = simd_reduce_any(z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-select.rs b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-select.rs new file mode 100644 index 000000000000..7448a57784fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-generic-select.rs @@ -0,0 +1,65 @@ +// build-fail + +// Test that the simd_select intrinsic produces ok-ish error +// messages when misused. + +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq)] +struct b8x4(pub i8, pub i8, pub i8, pub i8); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq)] +struct b8x8(pub i8, pub i8, pub i8, pub i8, + pub i8, pub i8, pub i8, pub i8); + +extern "platform-intrinsic" { + fn simd_select(x: T, a: U, b: U) -> U; + fn simd_select_bitmask(x: T, a: U, b: U) -> U; +} + +fn main() { + let m4 = b8x4(0, 0, 0, 0); + let m8 = b8x8(0, 0, 0, 0, 0, 0, 0, 0); + let x = u32x4(0, 0, 0, 0); + let z = f32x4(0.0, 0.0, 0.0, 0.0); + + unsafe { + simd_select(m4, x, x); + + simd_select(m8, x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + simd_select(x, x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + simd_select(z, z, z); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + simd_select(m4, 0u32, 1u32); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + simd_select_bitmask(0u16, x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + // + simd_select_bitmask(0u8, 1u32, 2u32); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + simd_select_bitmask(0.0f32, x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + + simd_select_bitmask("x", x, x); +// { dg-error ".E0511." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs new file mode 100644 index 000000000000..6beddc572a3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs @@ -0,0 +1,26 @@ +// This used to cause an ICE for an internal index out of range due to simd_shuffle_indices being +// passed the wrong Instance, causing issues with inlining. See #67557. +// +// run-pass +// compile-flags: -Zmir-opt-level=3 +#![feature(platform_intrinsics, repr_simd)] + +extern "platform-intrinsic" { + fn simd_shuffle2(x: T, y: T, idx: [u32; 2]) -> U; +} + +#[repr(simd)] +#[derive(Debug, PartialEq)] +struct Simd2(u8, u8); + +fn main() { + unsafe { + let _: Simd2 = inline_me(); + } +} + +#[inline(always)] +unsafe fn inline_me() -> Simd2 { + simd_shuffle2(Simd2(10, 11), Simd2(12, 13), [0, 3]) +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs new file mode 100644 index 000000000000..70642cdbf253 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs @@ -0,0 +1,41 @@ +// This used to cause assert_10_13 to unexpectingly fail, due to simd_shuffle_indices being passed +// the wrong Instance, causing issues with inlining. See #67557. +// +// run-pass +// compile-flags: -Zmir-opt-level=3 +#![feature(platform_intrinsics, repr_simd)] + +extern "platform-intrinsic" { + fn simd_shuffle2(x: T, y: T, idx: [u32; 2]) -> U; +} + +#[repr(simd)] +#[derive(Debug, PartialEq)] +struct Simd2(u8, u8); + +fn main() { + unsafe { + let p_res: Simd2 = simd_shuffle2(Simd2(10, 11), Simd2(12, 13), [0, 1]); + let a_res: Simd2 = inline_me(); + + assert_10_11(p_res); + assert_10_13(a_res); + } +} + +#[inline(never)] +fn assert_10_11(x: Simd2) { + assert_eq!(x, Simd2(10, 11)); +} + +#[inline(never)] +fn assert_10_13(x: Simd2) { + assert_eq!(x, Simd2(10, 13)); +} + + +#[inline(always)] +unsafe fn inline_me() -> Simd2 { + simd_shuffle2(Simd2(10, 11), Simd2(12, 13), [0, 3]) +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd-type-generic-monomorphisation.rs b/gcc/testsuite/rust/rustc/ui/simd-type-generic-monomorphisation.rs new file mode 100644 index 000000000000..090b3edb3c9a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd-type-generic-monomorphisation.rs @@ -0,0 +1,14 @@ +// build-fail + +#![feature(repr_simd, platform_intrinsics)] + +// error-pattern:monomorphising SIMD type `Simd2` with a non-machine element type `X` + +struct X(Vec); +#[repr(simd)] +struct Simd2(T, T); + +fn main() { + let _ = Simd2(X(vec![]), X(vec![])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd-type.rs b/gcc/testsuite/rust/rustc/ui/simd-type.rs new file mode 100644 index 000000000000..243f3e312035 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd-type.rs @@ -0,0 +1,11 @@ +#![feature(repr_simd)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +struct empty; // { dg-error ".E0075." "" { target *-*-* } } + +#[repr(simd)] +struct i64f64(i64, f64); // { dg-error ".E0076." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/shuffle-not-out-of-bounds.rs b/gcc/testsuite/rust/rustc/ui/simd/shuffle-not-out-of-bounds.rs new file mode 100644 index 000000000000..0069a0ae9190 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/shuffle-not-out-of-bounds.rs @@ -0,0 +1,192 @@ +// build-fail +#![allow(non_camel_case_types)] +#![feature(repr_simd, platform_intrinsics)] + +// Test for #73542 to verify out-of-bounds shuffle vectors do not compile. + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x2(u8, u8); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x4(u8, u8, u8, u8); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x8(u8, u8, u8, u8, u8, u8, u8, u8); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x16( + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, +); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x32( + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, +); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u8x64( + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, + u8, +); + +// Test vectors by lane size. Since LLVM does not distinguish between a shuffle +// over two f32s and a shuffle over two u64s, or any other such combination, +// it is not necessary to test every possible vector, only lane counts. +macro_rules! test_shuffle_lanes { + ($n:literal, $x:ident, $y:ident, $t:tt) => { + unsafe { + let shuffle: $x = { + const ARR: [u32; $n] = { + let mut arr = [0; $n]; + arr[0] = $n * 2; + arr + }; + extern "platform-intrinsic" { + pub fn $y(x: T, y: T, idx: [u32; $n]) -> U; + } + let vec1 = $x$t; + let vec2 = $x$t; + $y(vec1, vec2, ARR) + }; + } + } +} +// { dg-error ".E0511." "" { target *-*-* } .-5 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-5 } +// { dg-error "" "" { target *-*-* } .-6 } +// Because the test is mostly embedded in a macro, all the errors have the same origin point. +// And unfortunately, standard comments, as in the UI test harness, disappear in macros! + +fn main() { + test_shuffle_lanes!(2, u8x2, simd_shuffle2, (2, 1)); + test_shuffle_lanes!(4, u8x4, simd_shuffle4, (4, 3, 2, 1)); + test_shuffle_lanes!(8, u8x8, simd_shuffle8, (8, 7, 6, 5, 4, 3, 2, 1)); + test_shuffle_lanes!(16, u8x16, simd_shuffle16, + (16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)); + test_shuffle_lanes!(32, u8x32, simd_shuffle32, + (32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)); + test_shuffle_lanes!(64, u8x64, simd_shuffle64, + (64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, + 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, + 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-generics.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-generics.rs new file mode 100644 index 000000000000..76ad7f863fed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-generics.rs @@ -0,0 +1,40 @@ +// run-pass +#![allow(non_camel_case_types)] + + + +#![feature(repr_simd, platform_intrinsics)] + +use std::ops; + +#[repr(simd)] +#[derive(Copy, Clone)] +struct f32x4(f32, f32, f32, f32); + +extern "platform-intrinsic" { + fn simd_add(x: T, y: T) -> T; +} + +fn add>(lhs: T, rhs: T) -> T { + lhs + rhs +} + +impl ops::Add for f32x4 { + type Output = f32x4; + + fn add(self, rhs: f32x4) -> f32x4 { + unsafe {simd_add(self, rhs)} + } +} + +pub fn main() { + let lr = f32x4(1.0f32, 2.0f32, 3.0f32, 4.0f32); + + // lame-o + let f32x4(x, y, z, w) = add(lr, lr); + assert_eq!(x, 2.0f32); + assert_eq!(y, 4.0f32); + assert_eq!(z, 6.0f32); + assert_eq!(w, 8.0f32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-float-math.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-float-math.rs new file mode 100644 index 000000000000..3a8b43fe9566 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-float-math.rs @@ -0,0 +1,104 @@ +// run-pass +// ignore-emscripten +// ignore-android + +// FIXME: this test fails on arm-android because the NDK version 14 is too old. +// It needs at least version 18. We disable it on all android build bots because +// there is no way in compile-test to disable it for an (arch,os) pair. + +// Test that the simd floating-point math intrinsics produce correct results. + +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct f32x4(pub f32, pub f32, pub f32, pub f32); + +extern "platform-intrinsic" { + fn simd_fsqrt(x: T) -> T; + fn simd_fabs(x: T) -> T; + fn simd_fsin(x: T) -> T; + fn simd_fcos(x: T) -> T; + fn simd_ceil(x: T) -> T; + fn simd_fexp(x: T) -> T; + fn simd_fexp2(x: T) -> T; + fn simd_floor(x: T) -> T; + fn simd_fma(x: T, y: T, z: T) -> T; + fn simd_flog(x: T) -> T; + fn simd_flog10(x: T) -> T; + fn simd_flog2(x: T) -> T; + fn simd_fpow(x: T, y: T) -> T; + fn simd_fpowi(x: T, y: i32) -> T; +} + +macro_rules! assert_approx_eq_f32 { + ($a:expr, $b:expr) => ({ + let (a, b) = (&$a, &$b); + assert!((*a - *b).abs() < 1.0e-6, + "{} is not approximately equal to {}", *a, *b); + }) +} +macro_rules! assert_approx_eq { + ($a:expr, $b:expr) => ({ + let a = $a; + let b = $b; + assert_approx_eq_f32!(a.0, b.0); + assert_approx_eq_f32!(a.1, b.1); + assert_approx_eq_f32!(a.2, b.2); + assert_approx_eq_f32!(a.3, b.3); + }) +} + +fn main() { + let x = f32x4(1.0, 1.0, 1.0, 1.0); + let y = f32x4(-1.0, -1.0, -1.0, -1.0); + let z = f32x4(0.0, 0.0, 0.0, 0.0); + + let h = f32x4(0.5, 0.5, 0.5, 0.5); + + unsafe { + let r = simd_fabs(y); + assert_approx_eq!(x, r); + + let r = simd_fcos(z); + assert_approx_eq!(x, r); + + let r = simd_ceil(h); + assert_approx_eq!(x, r); + + let r = simd_fexp(z); + assert_approx_eq!(x, r); + + let r = simd_fexp2(z); + assert_approx_eq!(x, r); + + let r = simd_floor(h); + assert_approx_eq!(z, r); + + let r = simd_fma(x, h, h); + assert_approx_eq!(x, r); + + let r = simd_fsqrt(x); + assert_approx_eq!(x, r); + + let r = simd_flog(x); + assert_approx_eq!(z, r); + + let r = simd_flog2(x); + assert_approx_eq!(z, r); + + let r = simd_flog10(x); + assert_approx_eq!(z, r); + + let r = simd_fpow(h, x); + assert_approx_eq!(h, r); + + let r = simd_fpowi(h, 1); + assert_approx_eq!(h, r); + + let r = simd_fsin(z); + assert_approx_eq!(z, r); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-float-minmax.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-float-minmax.rs new file mode 100644 index 000000000000..50e315b31eda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-float-minmax.rs @@ -0,0 +1,53 @@ +// run-pass +// ignore-emscripten + +// Test that the simd_f{min,max} intrinsics produce the correct results. + +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct f32x4(pub f32, pub f32, pub f32, pub f32); + +extern "platform-intrinsic" { + fn simd_fmin(x: T, y: T) -> T; + fn simd_fmax(x: T, y: T) -> T; +} + +fn main() { + let x = f32x4(1.0, 2.0, 3.0, 4.0); + let y = f32x4(2.0, 1.0, 4.0, 3.0); + + #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))] + let nan = ::std::f32::NAN; + // MIPS hardware treats f32::NAN as SNAN. Clear the signaling bit. + // See https://github.com/rust-lang/rust/issues/52746. + #[cfg(any(target_arch = "mips", target_arch = "mips64"))] + let nan = f32::from_bits(::std::f32::NAN.to_bits() - 1); + + let n = f32x4(nan, nan, nan, nan); + + unsafe { + let min0 = simd_fmin(x, y); + let min1 = simd_fmin(y, x); + assert_eq!(min0, min1); + let e = f32x4(1.0, 1.0, 3.0, 3.0); + assert_eq!(min0, e); + let minn = simd_fmin(x, n); + assert_eq!(minn, x); + let minn = simd_fmin(y, n); + assert_eq!(minn, y); + + let max0 = simd_fmax(x, y); + let max1 = simd_fmax(y, x); + assert_eq!(max0, max1); + let e = f32x4(2.0, 2.0, 4.0, 4.0); + assert_eq!(max0, e); + let maxn = simd_fmax(x, n); + assert_eq!(maxn, x); + let maxn = simd_fmax(y, n); + assert_eq!(maxn, y); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs new file mode 100644 index 000000000000..4668e7a7d72e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs @@ -0,0 +1,92 @@ +// run-pass +// ignore-emscripten + +#![allow(non_camel_case_types)] +#![feature(repr_simd, platform_intrinsics)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct i32x4(pub i32, pub i32, pub i32, pub i32); + +extern "platform-intrinsic" { + fn simd_saturating_add(x: T, y: T) -> T; + fn simd_saturating_sub(x: T, y: T) -> T; +} + +fn main() { + // unsigned + { + const M: u32 = u32::MAX; + + let a = u32x4(1, 2, 3, 4); + let b = u32x4(2, 4, 6, 8); + let m = u32x4(M, M, M, M); + let m1 = u32x4(M - 1, M - 1, M - 1, M - 1); + let z = u32x4(0, 0, 0, 0); + + unsafe { + assert_eq!(simd_saturating_add(z, z), z); + assert_eq!(simd_saturating_add(z, a), a); + assert_eq!(simd_saturating_add(b, z), b); + assert_eq!(simd_saturating_add(a, a), b); + assert_eq!(simd_saturating_add(a, m), m); + assert_eq!(simd_saturating_add(m, b), m); + assert_eq!(simd_saturating_add(m1, a), m); + + assert_eq!(simd_saturating_sub(b, z), b); + assert_eq!(simd_saturating_sub(b, a), a); + assert_eq!(simd_saturating_sub(a, a), z); + assert_eq!(simd_saturating_sub(a, b), z); + assert_eq!(simd_saturating_sub(a, m1), z); + assert_eq!(simd_saturating_sub(b, m1), z); + } + } + + // signed + { + const MIN: i32 = i32::MIN; + const MAX: i32 = i32::MAX; + + let a = i32x4(1, 2, 3, 4); + let b = i32x4(2, 4, 6, 8); + let c = i32x4(-1, -2, -3, -4); + let d = i32x4(-2, -4, -6, -8); + + let max = i32x4(MAX, MAX, MAX, MAX); + let max1 = i32x4(MAX - 1, MAX - 1, MAX - 1, MAX - 1); + let min = i32x4(MIN, MIN, MIN, MIN); + let min1 = i32x4(MIN + 1, MIN + 1, MIN + 1, MIN + 1); + + let z = i32x4(0, 0, 0, 0); + + unsafe { + assert_eq!(simd_saturating_add(z, z), z); + assert_eq!(simd_saturating_add(z, a), a); + assert_eq!(simd_saturating_add(b, z), b); + assert_eq!(simd_saturating_add(a, a), b); + assert_eq!(simd_saturating_add(a, max), max); + assert_eq!(simd_saturating_add(max, b), max); + assert_eq!(simd_saturating_add(max1, a), max); + assert_eq!(simd_saturating_add(min1, z), min1); + assert_eq!(simd_saturating_add(min, z), min); + assert_eq!(simd_saturating_add(min1, c), min); + assert_eq!(simd_saturating_add(min, c), min); + assert_eq!(simd_saturating_add(min1, d), min); + assert_eq!(simd_saturating_add(min, d), min); + + assert_eq!(simd_saturating_sub(b, z), b); + assert_eq!(simd_saturating_sub(b, a), a); + assert_eq!(simd_saturating_sub(a, a), z); + assert_eq!(simd_saturating_sub(a, b), c); + assert_eq!(simd_saturating_sub(z, max), min1); + assert_eq!(simd_saturating_sub(min1, z), min1); + assert_eq!(simd_saturating_sub(min1, a), min); + assert_eq!(simd_saturating_sub(min1, b), min); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-arithmetic.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-arithmetic.rs new file mode 100644 index 000000000000..0b7aa95525f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-arithmetic.rs @@ -0,0 +1,121 @@ +// run-pass +#![allow(non_camel_case_types)] + +// ignore-emscripten FIXME(#45351) hits an LLVM assert + +#![feature(repr_simd, platform_intrinsics)] + +#[repr(simd)] +#[derive(Copy, Clone)] +struct i32x4(pub i32, pub i32, pub i32, pub i32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct f32x4(pub f32, pub f32, pub f32, pub f32); + +macro_rules! all_eq { + ($a: expr, $b: expr) => {{ + let a = $a; + let b = $b; + assert!(a.0 == b.0 && a.1 == b.1 && a.2 == b.2 && a.3 == b.3); + }} +} + +extern "platform-intrinsic" { + fn simd_add(x: T, y: T) -> T; + fn simd_sub(x: T, y: T) -> T; + fn simd_mul(x: T, y: T) -> T; + fn simd_div(x: T, y: T) -> T; + fn simd_rem(x: T, y: T) -> T; + fn simd_shl(x: T, y: T) -> T; + fn simd_shr(x: T, y: T) -> T; + fn simd_and(x: T, y: T) -> T; + fn simd_or(x: T, y: T) -> T; + fn simd_xor(x: T, y: T) -> T; +} + +fn main() { + let x1 = i32x4(1, 2, 3, 4); + let y1 = u32x4(1, 2, 3, 4); + let z1 = f32x4(1.0, 2.0, 3.0, 4.0); + let x2 = i32x4(2, 3, 4, 5); + let y2 = u32x4(2, 3, 4, 5); + let z2 = f32x4(2.0, 3.0, 4.0, 5.0); + + unsafe { + all_eq!(simd_add(x1, x2), i32x4(3, 5, 7, 9)); + all_eq!(simd_add(x2, x1), i32x4(3, 5, 7, 9)); + all_eq!(simd_add(y1, y2), u32x4(3, 5, 7, 9)); + all_eq!(simd_add(y2, y1), u32x4(3, 5, 7, 9)); + all_eq!(simd_add(z1, z2), f32x4(3.0, 5.0, 7.0, 9.0)); + all_eq!(simd_add(z2, z1), f32x4(3.0, 5.0, 7.0, 9.0)); + + all_eq!(simd_mul(x1, x2), i32x4(2, 6, 12, 20)); + all_eq!(simd_mul(x2, x1), i32x4(2, 6, 12, 20)); + all_eq!(simd_mul(y1, y2), u32x4(2, 6, 12, 20)); + all_eq!(simd_mul(y2, y1), u32x4(2, 6, 12, 20)); + all_eq!(simd_mul(z1, z2), f32x4(2.0, 6.0, 12.0, 20.0)); + all_eq!(simd_mul(z2, z1), f32x4(2.0, 6.0, 12.0, 20.0)); + + all_eq!(simd_sub(x2, x1), i32x4(1, 1, 1, 1)); + all_eq!(simd_sub(x1, x2), i32x4(-1, -1, -1, -1)); + all_eq!(simd_sub(y2, y1), u32x4(1, 1, 1, 1)); + all_eq!(simd_sub(y1, y2), u32x4(!0, !0, !0, !0)); + all_eq!(simd_sub(z2, z1), f32x4(1.0, 1.0, 1.0, 1.0)); + all_eq!(simd_sub(z1, z2), f32x4(-1.0, -1.0, -1.0, -1.0)); + + all_eq!(simd_div(x1, x1), i32x4(1, 1, 1, 1)); + all_eq!(simd_div(i32x4(2, 4, 6, 8), i32x4(2, 2, 2, 2)), x1); + all_eq!(simd_div(y1, y1), u32x4(1, 1, 1, 1)); + all_eq!(simd_div(u32x4(2, 4, 6, 8), u32x4(2, 2, 2, 2)), y1); + all_eq!(simd_div(z1, z1), f32x4(1.0, 1.0, 1.0, 1.0)); + all_eq!(simd_div(z1, z2), f32x4(1.0/2.0, 2.0/3.0, 3.0/4.0, 4.0/5.0)); + all_eq!(simd_div(z2, z1), f32x4(2.0/1.0, 3.0/2.0, 4.0/3.0, 5.0/4.0)); + + all_eq!(simd_rem(x1, x1), i32x4(0, 0, 0, 0)); + all_eq!(simd_rem(x2, x1), i32x4(0, 1, 1, 1)); + all_eq!(simd_rem(y1, y1), u32x4(0, 0, 0, 0)); + all_eq!(simd_rem(y2, y1), u32x4(0, 1, 1, 1)); + all_eq!(simd_rem(z1, z1), f32x4(0.0, 0.0, 0.0, 0.0)); + all_eq!(simd_rem(z1, z2), z1); + all_eq!(simd_rem(z2, z1), f32x4(0.0, 1.0, 1.0, 1.0)); + + all_eq!(simd_shl(x1, x2), i32x4(1 << 2, 2 << 3, 3 << 4, 4 << 5)); + all_eq!(simd_shl(x2, x1), i32x4(2 << 1, 3 << 2, 4 << 3, 5 << 4)); + all_eq!(simd_shl(y1, y2), u32x4(1 << 2, 2 << 3, 3 << 4, 4 << 5)); + all_eq!(simd_shl(y2, y1), u32x4(2 << 1, 3 << 2, 4 << 3, 5 << 4)); + + // test right-shift by assuming left-shift is correct + all_eq!(simd_shr(simd_shl(x1, x2), x2), x1); + all_eq!(simd_shr(simd_shl(x2, x1), x1), x2); + all_eq!(simd_shr(simd_shl(y1, y2), y2), y1); + all_eq!(simd_shr(simd_shl(y2, y1), y1), y2); + + // ensure we get logical vs. arithmetic shifts correct + let (a, b, c, d) = (-12, -123, -1234, -12345); + all_eq!(simd_shr(i32x4(a, b, c, d), x1), i32x4(a >> 1, b >> 2, c >> 3, d >> 4)); + all_eq!(simd_shr(u32x4(a as u32, b as u32, c as u32, d as u32), y1), + u32x4((a as u32) >> 1, (b as u32) >> 2, (c as u32) >> 3, (d as u32) >> 4)); + + all_eq!(simd_and(x1, x2), i32x4(0, 2, 0, 4)); + all_eq!(simd_and(x2, x1), i32x4(0, 2, 0, 4)); + all_eq!(simd_and(y1, y2), u32x4(0, 2, 0, 4)); + all_eq!(simd_and(y2, y1), u32x4(0, 2, 0, 4)); + + all_eq!(simd_or(x1, x2), i32x4(3, 3, 7, 5)); + all_eq!(simd_or(x2, x1), i32x4(3, 3, 7, 5)); + all_eq!(simd_or(y1, y2), u32x4(3, 3, 7, 5)); + all_eq!(simd_or(y2, y1), u32x4(3, 3, 7, 5)); + + all_eq!(simd_xor(x1, x2), i32x4(3, 1, 7, 1)); + all_eq!(simd_xor(x2, x1), i32x4(3, 1, 7, 1)); + all_eq!(simd_xor(y1, y2), u32x4(3, 1, 7, 1)); + all_eq!(simd_xor(y2, y1), u32x4(3, 1, 7, 1)); + + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-bitmask.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-bitmask.rs new file mode 100644 index 000000000000..172d506af683 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-bitmask.rs @@ -0,0 +1,63 @@ +// run-pass +#![allow(non_camel_case_types)] + +// ignore-emscripten +// ignore-endian-big behavior of simd_bitmask is endian-specific + +// Test that the simd_bitmask intrinsic produces correct results. + +#![feature(repr_simd, platform_intrinsics)] +#[allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct u8x4(pub u8, pub u8, pub u8, pub u8); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct Tx4(pub T, pub T, pub T, pub T); + +extern "platform-intrinsic" { + fn simd_bitmask(x: T) -> U; +} + +fn main() { + let z = u32x4(0, 0, 0, 0); + let ez = 0_u8; + + let o = u32x4(!0, !0, !0, !0); + let eo = 0b_1111_u8; + + let m0 = u32x4(!0, 0, !0, 0); + let e0 = 0b_0000_0101_u8; + + // Check that the MSB is extracted: + let m = u8x4(0b_1000_0000, 0b_0100_0001, 0b_1100_0001, 0b_1111_1111); + let e = 0b_1101; + + // Check usize / isize + let msize: Tx4 = Tx4(usize::MAX, 0, usize::MAX, usize::MAX); + + unsafe { + let r: u8 = simd_bitmask(z); + assert_eq!(r, ez); + + let r: u8 = simd_bitmask(o); + assert_eq!(r, eo); + + let r: u8 = simd_bitmask(m0); + assert_eq!(r, e0); + + let r: u8 = simd_bitmask(m); + assert_eq!(r, e); + + let r: u8 = simd_bitmask(msize); + assert_eq!(r, e); + + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-cast.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-cast.rs new file mode 100644 index 000000000000..ebf9e36ea107 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-cast.rs @@ -0,0 +1,122 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten FIXME(#45351) hits an LLVM assert + +#![feature(repr_simd, platform_intrinsics, concat_idents, test)] +#![allow(non_camel_case_types)] + +extern crate test; + +#[repr(simd)] +#[derive(PartialEq, Debug)] +struct i32x4(i32, i32, i32, i32); +#[repr(simd)] +#[derive(PartialEq, Debug)] +struct i8x4(i8, i8, i8, i8); + +#[repr(simd)] +#[derive(PartialEq, Debug)] +struct u32x4(u32, u32, u32, u32); +#[repr(simd)] +#[derive(PartialEq, Debug)] +struct u8x4(u8, u8, u8, u8); + +#[repr(simd)] +#[derive(PartialEq, Debug)] +struct f32x4(f32, f32, f32, f32); + +#[repr(simd)] +#[derive(PartialEq, Debug)] +struct f64x4(f64, f64, f64, f64); + + +extern "platform-intrinsic" { + fn simd_cast(x: T) -> U; +} + +const A: i32 = -1234567; +const B: i32 = 12345678; +const C: i32 = -123456789; +const D: i32 = 1234567890; + +trait Foo { + fn is_float() -> bool { false } + fn in_range(x: i32) -> bool; +} +impl Foo for i32 { + fn in_range(_: i32) -> bool { true } +} +impl Foo for i8 { + fn in_range(x: i32) -> bool { -128 <= x && x < 128 } +} +impl Foo for u32 { + fn in_range(x: i32) -> bool { 0 <= x } +} +impl Foo for u8 { + fn in_range(x: i32) -> bool { 0 <= x && x < 128 } +} +impl Foo for f32 { + fn is_float() -> bool { true } + fn in_range(_: i32) -> bool { true } +} +impl Foo for f64 { + fn is_float() -> bool { true } + fn in_range(_: i32) -> bool { true } +} + +fn main() { + macro_rules! test { + ($from: ident, $to: ident) => {{ + // force the casts to actually happen, or else LLVM/rustc + // may fold them and get slightly different results. + let (a, b, c, d) = test::black_box((A as $from, B as $from, C as $from, D as $from)); + // the SIMD vectors are all FOOx4, so we can concat_idents + // so we don't have to pass in the extra args to the macro + let mut from = simd_cast(concat_idents!($from, x4)(a, b, c, d)); + let mut to = concat_idents!($to, x4)(a as $to, + b as $to, + c as $to, + d as $to); + // assist type inference, it needs to know what `from` is + // for the `if` statements. + to == from; + + // there are platform differences for some out of range + // casts, so we just normalize such things: it's OK for + // "invalid" calculations to result in nonsense answers. + // (e.g., negative float to unsigned integer goes through a + // library routine on the default i686 platforms, and the + // implementation of that routine differs on e.g., Linux + // vs. macOS, resulting in different answers.) + if $from::is_float() { + if !$to::in_range(A) { from.0 = 0 as $to; to.0 = 0 as $to; } + if !$to::in_range(B) { from.1 = 0 as $to; to.1 = 0 as $to; } + if !$to::in_range(C) { from.2 = 0 as $to; to.2 = 0 as $to; } + if !$to::in_range(D) { from.3 = 0 as $to; to.3 = 0 as $to; } + } + + assert!(to == from, + "{} -> {} ({:?} != {:?})", stringify!($from), stringify!($to), + from, to); + }} + } + macro_rules! tests { + (: $($to: ident),*) => { () }; + // repeating the list twice is easier than writing a cartesian + // product macro + ($from: ident $(, $from_: ident)*: $($to: ident),*) => { + fn $from() { unsafe { $( test!($from, $to); )* } } + tests!($($from_),*: $($to),*) + }; + ($($types: ident),*) => {{ + tests!($($types),* : $($types),*); + $($types();)* + }} + } + + // test various combinations, including truncation, + // signed/unsigned extension, and floating point casts. + tests!(i32, i8, u32, u8, f32); + tests!(i32, u32, f32, f64) +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-comparison.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-comparison.rs new file mode 100644 index 000000000000..3bec0ad833c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-comparison.rs @@ -0,0 +1,107 @@ +// run-pass +// ignore-emscripten FIXME(#45351) hits an LLVM assert + +#![feature(repr_simd, platform_intrinsics, concat_idents)] +#![allow(non_camel_case_types)] + +use std::f32::NAN; + +#[repr(simd)] +#[derive(Copy, Clone)] +struct i32x4(i32, i32, i32, i32); +#[repr(simd)] +#[derive(Copy, Clone)] +struct u32x4(pub u32, pub u32, pub u32, pub u32); +#[repr(simd)] +#[derive(Copy, Clone)] +struct f32x4(pub f32, pub f32, pub f32, pub f32); + +extern "platform-intrinsic" { + fn simd_eq(x: T, y: T) -> U; + fn simd_ne(x: T, y: T) -> U; + fn simd_lt(x: T, y: T) -> U; + fn simd_le(x: T, y: T) -> U; + fn simd_gt(x: T, y: T) -> U; + fn simd_ge(x: T, y: T) -> U; +} + +macro_rules! cmp { + ($method: ident($lhs: expr, $rhs: expr)) => {{ + let lhs = $lhs; + let rhs = $rhs; + let e: u32x4 = concat_idents!(simd_, $method)($lhs, $rhs); + // assume the scalar version is correct/the behaviour we want. + assert!((e.0 != 0) == lhs.0 .$method(&rhs.0)); + assert!((e.1 != 0) == lhs.1 .$method(&rhs.1)); + assert!((e.2 != 0) == lhs.2 .$method(&rhs.2)); + assert!((e.3 != 0) == lhs.3 .$method(&rhs.3)); + }} +} +macro_rules! tests { + ($($lhs: ident, $rhs: ident;)*) => {{ + $( + (|| { + cmp!(eq($lhs, $rhs)); + cmp!(ne($lhs, $rhs)); + + // test both directions + cmp!(lt($lhs, $rhs)); + cmp!(lt($rhs, $lhs)); + + cmp!(le($lhs, $rhs)); + cmp!(le($rhs, $lhs)); + + cmp!(gt($lhs, $rhs)); + cmp!(gt($rhs, $lhs)); + + cmp!(ge($lhs, $rhs)); + cmp!(ge($rhs, $lhs)); + })(); + )* + }} +} +fn main() { + // 13 vs. -100 tests that we get signed vs. unsigned comparisons + // correct (i32: 13 > -100, u32: 13 < -100). let i1 = i32x4(10, -11, 12, 13); + let i1 = i32x4(10, -11, 12, 13); + let i2 = i32x4(5, -5, 20, -100); + let i3 = i32x4(10, -11, 20, -100); + + let u1 = u32x4(10, !11+1, 12, 13); + let u2 = u32x4(5, !5+1, 20, !100+1); + let u3 = u32x4(10, !11+1, 20, !100+1); + + let f1 = f32x4(10.0, -11.0, 12.0, 13.0); + let f2 = f32x4(5.0, -5.0, 20.0, -100.0); + let f3 = f32x4(10.0, -11.0, 20.0, -100.0); + + unsafe { + tests! { + i1, i1; + u1, u1; + f1, f1; + + i1, i2; + u1, u2; + f1, f2; + + i1, i3; + u1, u3; + f1, f3; + } + } + + // NAN comparisons are special: + // -11 (*) 13 + // -5 -100 (*) + let f4 = f32x4(NAN, f1.1, NAN, f2.3); + + unsafe { + tests! { + f1, f4; + f2, f4; + f4, f4; + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-elements.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-elements.rs new file mode 100644 index 000000000000..7f7b6f1c8292 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-elements.rs @@ -0,0 +1,126 @@ +// run-pass +// ignore-emscripten FIXME(#45351) hits an LLVM assert + +#![feature(repr_simd, platform_intrinsics)] + +#[repr(simd)] +#[derive(Copy, Clone, Debug, PartialEq)] +#[allow(non_camel_case_types)] +struct i32x2(i32, i32); +#[repr(simd)] +#[derive(Copy, Clone, Debug, PartialEq)] +#[allow(non_camel_case_types)] +struct i32x3(i32, i32, i32); +#[repr(simd)] +#[derive(Copy, Clone, Debug, PartialEq)] +#[allow(non_camel_case_types)] +struct i32x4(i32, i32, i32, i32); +#[repr(simd)] +#[derive(Copy, Clone, Debug, PartialEq)] +#[allow(non_camel_case_types)] +struct i32x8(i32, i32, i32, i32, + i32, i32, i32, i32); + +extern "platform-intrinsic" { + fn simd_insert(x: T, idx: u32, y: E) -> T; + fn simd_extract(x: T, idx: u32) -> E; + + fn simd_shuffle2(x: T, y: T, idx: [u32; 2]) -> U; + fn simd_shuffle3(x: T, y: T, idx: [u32; 3]) -> U; + fn simd_shuffle4(x: T, y: T, idx: [u32; 4]) -> U; + fn simd_shuffle8(x: T, y: T, idx: [u32; 8]) -> U; +} + +macro_rules! all_eq { + ($a: expr, $b: expr) => {{ + let a = $a; + let b = $b; + // type inference works better with the concrete type on the + // left, but humans work better with the expected on the + // right. + assert!(b == a, + "{:?} != {:?}", a, b); + }} +} + +fn main() { + let x2 = i32x2(20, 21); + let x3 = i32x3(30, 31, 32); + let x4 = i32x4(40, 41, 42, 43); + let x8 = i32x8(80, 81, 82, 83, 84, 85, 86, 87); + unsafe { + all_eq!(simd_insert(x2, 0, 100), i32x2(100, 21)); + all_eq!(simd_insert(x2, 1, 100), i32x2(20, 100)); + + all_eq!(simd_insert(x3, 0, 100), i32x3(100, 31, 32)); + all_eq!(simd_insert(x3, 1, 100), i32x3(30, 100, 32)); + all_eq!(simd_insert(x3, 2, 100), i32x3(30, 31, 100)); + + all_eq!(simd_insert(x4, 0, 100), i32x4(100, 41, 42, 43)); + all_eq!(simd_insert(x4, 1, 100), i32x4(40, 100, 42, 43)); + all_eq!(simd_insert(x4, 2, 100), i32x4(40, 41, 100, 43)); + all_eq!(simd_insert(x4, 3, 100), i32x4(40, 41, 42, 100)); + + all_eq!(simd_insert(x8, 0, 100), i32x8(100, 81, 82, 83, 84, 85, 86, 87)); + all_eq!(simd_insert(x8, 1, 100), i32x8(80, 100, 82, 83, 84, 85, 86, 87)); + all_eq!(simd_insert(x8, 2, 100), i32x8(80, 81, 100, 83, 84, 85, 86, 87)); + all_eq!(simd_insert(x8, 3, 100), i32x8(80, 81, 82, 100, 84, 85, 86, 87)); + all_eq!(simd_insert(x8, 4, 100), i32x8(80, 81, 82, 83, 100, 85, 86, 87)); + all_eq!(simd_insert(x8, 5, 100), i32x8(80, 81, 82, 83, 84, 100, 86, 87)); + all_eq!(simd_insert(x8, 6, 100), i32x8(80, 81, 82, 83, 84, 85, 100, 87)); + all_eq!(simd_insert(x8, 7, 100), i32x8(80, 81, 82, 83, 84, 85, 86, 100)); + + all_eq!(simd_extract(x2, 0), 20); + all_eq!(simd_extract(x2, 1), 21); + + all_eq!(simd_extract(x3, 0), 30); + all_eq!(simd_extract(x3, 1), 31); + all_eq!(simd_extract(x3, 2), 32); + + all_eq!(simd_extract(x4, 0), 40); + all_eq!(simd_extract(x4, 1), 41); + all_eq!(simd_extract(x4, 2), 42); + all_eq!(simd_extract(x4, 3), 43); + + all_eq!(simd_extract(x8, 0), 80); + all_eq!(simd_extract(x8, 1), 81); + all_eq!(simd_extract(x8, 2), 82); + all_eq!(simd_extract(x8, 3), 83); + all_eq!(simd_extract(x8, 4), 84); + all_eq!(simd_extract(x8, 5), 85); + all_eq!(simd_extract(x8, 6), 86); + all_eq!(simd_extract(x8, 7), 87); + } + + let y2 = i32x2(120, 121); + let y3 = i32x3(130, 131, 132); + let y4 = i32x4(140, 141, 142, 143); + let y8 = i32x8(180, 181, 182, 183, 184, 185, 186, 187); + unsafe { + all_eq!(simd_shuffle2(x2, y2, [3, 0]), i32x2(121, 20)); + all_eq!(simd_shuffle3(x2, y2, [3, 0, 1]), i32x3(121, 20, 21)); + all_eq!(simd_shuffle4(x2, y2, [3, 0, 1, 2]), i32x4(121, 20, 21, 120)); + all_eq!(simd_shuffle8(x2, y2, [3, 0, 1, 2, 1, 2, 3, 0]), + i32x8(121, 20, 21, 120, 21, 120, 121, 20)); + + all_eq!(simd_shuffle2(x3, y3, [4, 2]), i32x2(131, 32)); + all_eq!(simd_shuffle3(x3, y3, [4, 2, 3]), i32x3(131, 32, 130)); + all_eq!(simd_shuffle4(x3, y3, [4, 2, 3, 0]), i32x4(131, 32, 130, 30)); + all_eq!(simd_shuffle8(x3, y3, [4, 2, 3, 0, 1, 5, 5, 1]), + i32x8(131, 32, 130, 30, 31, 132, 132, 31)); + + all_eq!(simd_shuffle2(x4, y4, [7, 2]), i32x2(143, 42)); + all_eq!(simd_shuffle3(x4, y4, [7, 2, 5]), i32x3(143, 42, 141)); + all_eq!(simd_shuffle4(x4, y4, [7, 2, 5, 0]), i32x4(143, 42, 141, 40)); + all_eq!(simd_shuffle8(x4, y4, [7, 2, 5, 0, 3, 6, 4, 1]), + i32x8(143, 42, 141, 40, 43, 142, 140, 41)); + + all_eq!(simd_shuffle2(x8, y8, [11, 5]), i32x2(183, 85)); + all_eq!(simd_shuffle3(x8, y8, [11, 5, 15]), i32x3(183, 85, 187)); + all_eq!(simd_shuffle4(x8, y8, [11, 5, 15, 0]), i32x4(183, 85, 187, 80)); + all_eq!(simd_shuffle8(x8, y8, [11, 5, 15, 0, 3, 8, 12, 1]), + i32x8(183, 85, 187, 80, 83, 180, 184, 81)); + } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-gather.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-gather.rs new file mode 100644 index 000000000000..ba5d9236a876 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-gather.rs @@ -0,0 +1,142 @@ +// run-pass +// ignore-emscripten + +// Test that the simd_{gather,scatter} intrinsics produce the correct results. + +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct x4(pub T, pub T, pub T, pub T); + +extern "platform-intrinsic" { + fn simd_gather(x: T, y: U, z: V) -> T; + fn simd_scatter(x: T, y: U, z: V) -> (); +} + +fn main() { + let mut x = [0_f32, 1., 2., 3., 4., 5., 6., 7.]; + + let default = x4(-3_f32, -3., -3., -3.); + let s_strided = x4(0_f32, 2., -3., 6.); + let mask = x4(-1_i32, -1, 0, -1); + + // reading from *const + unsafe { + let pointer = &x[0] as *const f32; + let pointers = x4( + pointer.offset(0) as *const f32, + pointer.offset(2), + pointer.offset(4), + pointer.offset(6) + ); + + let r_strided = simd_gather(default, pointers, mask); + + assert_eq!(r_strided, s_strided); + } + + // reading from *mut + unsafe { + let pointer = &mut x[0] as *mut f32; + let pointers = x4( + pointer.offset(0) as *mut f32, + pointer.offset(2), + pointer.offset(4), + pointer.offset(6) + ); + + let r_strided = simd_gather(default, pointers, mask); + + assert_eq!(r_strided, s_strided); + } + + // writing to *mut + unsafe { + let pointer = &mut x[0] as *mut f32; + let pointers = x4( + pointer.offset(0) as *mut f32, + pointer.offset(2), + pointer.offset(4), + pointer.offset(6) + ); + + let values = x4(42_f32, 43_f32, 44_f32, 45_f32); + simd_scatter(values, pointers, mask); + + assert_eq!(x, [42., 1., 43., 3., 4., 5., 45., 7.]); + } + + // test modifying array of *const f32 + let mut y = [ + &x[0] as *const f32, + &x[1] as *const f32, + &x[2] as *const f32, + &x[3] as *const f32, + &x[4] as *const f32, + &x[5] as *const f32, + &x[6] as *const f32, + &x[7] as *const f32 + ]; + + let default = x4(y[0], y[0], y[0], y[0]); + let s_strided = x4(y[0], y[2], y[0], y[6]); + + // reading from *const + unsafe { + let pointer = &y[0] as *const *const f32; + let pointers = x4( + pointer.offset(0) as *const *const f32, + pointer.offset(2), + pointer.offset(4), + pointer.offset(6) + ); + + let r_strided = simd_gather(default, pointers, mask); + + assert_eq!(r_strided, s_strided); + } + + // reading from *mut + unsafe { + let pointer = &mut y[0] as *mut *const f32; + let pointers = x4( + pointer.offset(0) as *mut *const f32, + pointer.offset(2), + pointer.offset(4), + pointer.offset(6) + ); + + let r_strided = simd_gather(default, pointers, mask); + + assert_eq!(r_strided, s_strided); + } + + // writing to *mut + unsafe { + let pointer = &mut y[0] as *mut *const f32; + let pointers = x4( + pointer.offset(0) as *mut *const f32, + pointer.offset(2), + pointer.offset(4), + pointer.offset(6) + ); + + let values = x4(y[7], y[6], y[5], y[1]); + simd_scatter(values, pointers, mask); + + let s = [ + &x[7] as *const f32, + &x[1] as *const f32, + &x[6] as *const f32, + &x[3] as *const f32, + &x[4] as *const f32, + &x[5] as *const f32, + &x[1] as *const f32, + &x[7] as *const f32 + ]; + assert_eq!(y, s); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-reduction.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-reduction.rs new file mode 100644 index 000000000000..bbed0704ace7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-reduction.rs @@ -0,0 +1,166 @@ +// run-pass +#![allow(non_camel_case_types)] + +// ignore-emscripten +// min-system-llvm-version: 9.0 + +// Test that the simd_reduce_{op} intrinsics produce the correct results. + +#![feature(repr_simd, platform_intrinsics)] +#[allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone)] +struct i32x4(pub i32, pub i32, pub i32, pub i32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct b8x4(pub i8, pub i8, pub i8, pub i8); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct b8x16( + pub i8, pub i8, pub i8, pub i8, + pub i8, pub i8, pub i8, pub i8, + pub i8, pub i8, pub i8, pub i8, + pub i8, pub i8, pub i8, pub i8 +); + +extern "platform-intrinsic" { + fn simd_reduce_add_unordered(x: T) -> U; + fn simd_reduce_mul_unordered(x: T) -> U; + fn simd_reduce_add_ordered(x: T, acc: U) -> U; + fn simd_reduce_mul_ordered(x: T, acc: U) -> U; + fn simd_reduce_min(x: T) -> U; + fn simd_reduce_max(x: T) -> U; + fn simd_reduce_min_nanless(x: T) -> U; + fn simd_reduce_max_nanless(x: T) -> U; + fn simd_reduce_and(x: T) -> U; + fn simd_reduce_or(x: T) -> U; + fn simd_reduce_xor(x: T) -> U; + fn simd_reduce_all(x: T) -> bool; + fn simd_reduce_any(x: T) -> bool; +} + +fn main() { + unsafe { + let x = i32x4(1, -2, 3, 4); + let r: i32 = simd_reduce_add_unordered(x); + assert_eq!(r, 6_i32); + let r: i32 = simd_reduce_mul_unordered(x); + assert_eq!(r, -24_i32); + let r: i32 = simd_reduce_add_ordered(x, -1); + assert_eq!(r, 5_i32); + let r: i32 = simd_reduce_mul_ordered(x, -1); + assert_eq!(r, 24_i32); + + let r: i32 = simd_reduce_min(x); + assert_eq!(r, -2_i32); + let r: i32 = simd_reduce_max(x); + assert_eq!(r, 4_i32); + + let x = i32x4(-1, -1, -1, -1); + let r: i32 = simd_reduce_and(x); + assert_eq!(r, -1_i32); + let r: i32 = simd_reduce_or(x); + assert_eq!(r, -1_i32); + let r: i32 = simd_reduce_xor(x); + assert_eq!(r, 0_i32); + + let x = i32x4(-1, -1, 0, -1); + let r: i32 = simd_reduce_and(x); + assert_eq!(r, 0_i32); + let r: i32 = simd_reduce_or(x); + assert_eq!(r, -1_i32); + let r: i32 = simd_reduce_xor(x); + assert_eq!(r, -1_i32); + } + + unsafe { + let x = u32x4(1, 2, 3, 4); + let r: u32 = simd_reduce_add_unordered(x); + assert_eq!(r, 10_u32); + let r: u32 = simd_reduce_mul_unordered(x); + assert_eq!(r, 24_u32); + let r: u32 = simd_reduce_add_ordered(x, 1); + assert_eq!(r, 11_u32); + let r: u32 = simd_reduce_mul_ordered(x, 2); + assert_eq!(r, 48_u32); + + let r: u32 = simd_reduce_min(x); + assert_eq!(r, 1_u32); + let r: u32 = simd_reduce_max(x); + assert_eq!(r, 4_u32); + + let t = u32::MAX; + let x = u32x4(t, t, t, t); + let r: u32 = simd_reduce_and(x); + assert_eq!(r, t); + let r: u32 = simd_reduce_or(x); + assert_eq!(r, t); + let r: u32 = simd_reduce_xor(x); + assert_eq!(r, 0_u32); + + let x = u32x4(t, t, 0, t); + let r: u32 = simd_reduce_and(x); + assert_eq!(r, 0_u32); + let r: u32 = simd_reduce_or(x); + assert_eq!(r, t); + let r: u32 = simd_reduce_xor(x); + assert_eq!(r, t); + } + + unsafe { + let x = f32x4(1., -2., 3., 4.); + let r: f32 = simd_reduce_add_unordered(x); + assert_eq!(r, 6_f32); + let r: f32 = simd_reduce_mul_unordered(x); + assert_eq!(r, -24_f32); + let r: f32 = simd_reduce_add_ordered(x, 0.); + assert_eq!(r, 6_f32); + let r: f32 = simd_reduce_mul_ordered(x, 1.); + assert_eq!(r, -24_f32); + let r: f32 = simd_reduce_add_ordered(x, 1.); + assert_eq!(r, 7_f32); + let r: f32 = simd_reduce_mul_ordered(x, 2.); + assert_eq!(r, -48_f32); + + let r: f32 = simd_reduce_min(x); + assert_eq!(r, -2_f32); + let r: f32 = simd_reduce_max(x); + assert_eq!(r, 4_f32); + let r: f32 = simd_reduce_min_nanless(x); + assert_eq!(r, -2_f32); + let r: f32 = simd_reduce_max_nanless(x); + assert_eq!(r, 4_f32); + } + + unsafe { + let x = b8x4(!0, !0, !0, !0); + let r: bool = simd_reduce_all(x); + assert_eq!(r, true); + let r: bool = simd_reduce_any(x); + assert_eq!(r, true); + + let x = b8x4(!0, !0, 0, !0); + let r: bool = simd_reduce_all(x); + assert_eq!(r, false); + let r: bool = simd_reduce_any(x); + assert_eq!(r, true); + + let x = b8x4(0, 0, 0, 0); + let r: bool = simd_reduce_all(x); + assert_eq!(r, false); + let r: bool = simd_reduce_any(x); + assert_eq!(r, false); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-select.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-select.rs new file mode 100644 index 000000000000..e2c4a9170826 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-intrinsic-generic-select.rs @@ -0,0 +1,196 @@ +// run-pass +#![allow(non_camel_case_types)] + +// ignore-emscripten +// ignore-endian-big behavior of simd_select_bitmask is endian-specific + +// Test that the simd_select intrinsics produces correct results. + +#![feature(repr_simd, platform_intrinsics)] +#[allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct i32x4(pub i32, pub i32, pub i32, pub i32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct u32x8(u32, u32, u32, u32, u32, u32, u32, u32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct b8x4(pub i8, pub i8, pub i8, pub i8); + +extern "platform-intrinsic" { + fn simd_select(x: T, a: U, b: U) -> U; + fn simd_select_bitmask(x: T, a: U, b: U) -> U; +} + +fn main() { + let m0 = b8x4(!0, !0, !0, !0); + let m1 = b8x4(0, 0, 0, 0); + let m2 = b8x4(!0, !0, 0, 0); + let m3 = b8x4(0, 0, !0, !0); + let m4 = b8x4(!0, 0, !0, 0); + + unsafe { + let a = i32x4(1, -2, 3, 4); + let b = i32x4(5, 6, -7, 8); + + let r: i32x4 = simd_select(m0, a, b); + let e = a; + assert_eq!(r, e); + + let r: i32x4 = simd_select(m1, a, b); + let e = b; + assert_eq!(r, e); + + let r: i32x4 = simd_select(m2, a, b); + let e = i32x4(1, -2, -7, 8); + assert_eq!(r, e); + + let r: i32x4 = simd_select(m3, a, b); + let e = i32x4(5, 6, 3, 4); + assert_eq!(r, e); + + let r: i32x4 = simd_select(m4, a, b); + let e = i32x4(1, 6, 3, 8); + assert_eq!(r, e); + } + + unsafe { + let a = u32x4(1, 2, 3, 4); + let b = u32x4(5, 6, 7, 8); + + let r: u32x4 = simd_select(m0, a, b); + let e = a; + assert_eq!(r, e); + + let r: u32x4 = simd_select(m1, a, b); + let e = b; + assert_eq!(r, e); + + let r: u32x4 = simd_select(m2, a, b); + let e = u32x4(1, 2, 7, 8); + assert_eq!(r, e); + + let r: u32x4 = simd_select(m3, a, b); + let e = u32x4(5, 6, 3, 4); + assert_eq!(r, e); + + let r: u32x4 = simd_select(m4, a, b); + let e = u32x4(1, 6, 3, 8); + assert_eq!(r, e); + } + + unsafe { + let a = f32x4(1., 2., 3., 4.); + let b = f32x4(5., 6., 7., 8.); + + let r: f32x4 = simd_select(m0, a, b); + let e = a; + assert_eq!(r, e); + + let r: f32x4 = simd_select(m1, a, b); + let e = b; + assert_eq!(r, e); + + let r: f32x4 = simd_select(m2, a, b); + let e = f32x4(1., 2., 7., 8.); + assert_eq!(r, e); + + let r: f32x4 = simd_select(m3, a, b); + let e = f32x4(5., 6., 3., 4.); + assert_eq!(r, e); + + let r: f32x4 = simd_select(m4, a, b); + let e = f32x4(1., 6., 3., 8.); + assert_eq!(r, e); + } + + unsafe { + let t = !0 as i8; + let f = 0 as i8; + let a = b8x4(t, f, t, f); + let b = b8x4(f, f, f, t); + + let r: b8x4 = simd_select(m0, a, b); + let e = a; + assert_eq!(r, e); + + let r: b8x4 = simd_select(m1, a, b); + let e = b; + assert_eq!(r, e); + + let r: b8x4 = simd_select(m2, a, b); + let e = b8x4(t, f, f, t); + assert_eq!(r, e); + + let r: b8x4 = simd_select(m3, a, b); + let e = b8x4(f, f, t, f); + assert_eq!(r, e); + + let r: b8x4 = simd_select(m4, a, b); + let e = b8x4(t, f, t, t); + assert_eq!(r, e); + } + + unsafe { + let a = u32x8(0, 1, 2, 3, 4, 5, 6, 7); + let b = u32x8(8, 9, 10, 11, 12, 13, 14, 15); + + let r: u32x8 = simd_select_bitmask(0u8, a, b); + let e = b; + assert_eq!(r, e); + + let r: u32x8 = simd_select_bitmask(0xffu8, a, b); + let e = a; + assert_eq!(r, e); + + let r: u32x8 = simd_select_bitmask(0b01010101u8, a, b); + let e = u32x8(0, 9, 2, 11, 4, 13, 6, 15); + assert_eq!(r, e); + + let r: u32x8 = simd_select_bitmask(0b10101010u8, a, b); + let e = u32x8(8, 1, 10, 3, 12, 5, 14, 7); + assert_eq!(r, e); + + let r: u32x8 = simd_select_bitmask(0b11110000u8, a, b); + let e = u32x8(8, 9, 10, 11, 4, 5, 6, 7); + assert_eq!(r, e); + } + + unsafe { + let a = u32x4(0, 1, 2, 3); + let b = u32x4(4, 5, 6, 7); + + let r: u32x4 = simd_select_bitmask(0u8, a, b); + let e = b; + assert_eq!(r, e); + + let r: u32x4 = simd_select_bitmask(0xfu8, a, b); + let e = a; + assert_eq!(r, e); + + let r: u32x4 = simd_select_bitmask(0b0101u8, a, b); + let e = u32x4(0, 5, 2, 7); + assert_eq!(r, e); + + let r: u32x4 = simd_select_bitmask(0b1010u8, a, b); + let e = u32x4(4, 1, 6, 3); + assert_eq!(r, e); + + let r: u32x4 = simd_select_bitmask(0b1100u8, a, b); + let e = u32x4(4, 5, 2, 3); + assert_eq!(r, e); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-size-align.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-size-align.rs new file mode 100644 index 000000000000..5f91fada3bcd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-size-align.rs @@ -0,0 +1,97 @@ +// run-pass +#![allow(deprecated)] + + +#![feature(repr_simd)] +#![allow(non_camel_case_types)] + +use std::mem; + +/// `T` should satisfy `size_of T (mod min_align_of T) === 0` to be stored at `Vec` properly +/// Please consult the issue #20460 +fn check() { + assert_eq!(mem::size_of::() % mem::min_align_of::(), 0) +} + +fn main() { + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); +} + +#[repr(simd)] struct u8x2(u8, u8); +#[repr(simd)] struct u8x3(u8, u8, u8); +#[repr(simd)] struct u8x4(u8, u8, u8, u8); +#[repr(simd)] struct u8x5(u8, u8, u8, u8, u8); +#[repr(simd)] struct u8x6(u8, u8, u8, u8, u8, u8); +#[repr(simd)] struct u8x7(u8, u8, u8, u8, u8, u8, u8); +#[repr(simd)] struct u8x8(u8, u8, u8, u8, u8, u8, u8, u8); + +#[repr(simd)] struct i16x2(i16, i16); +#[repr(simd)] struct i16x3(i16, i16, i16); +#[repr(simd)] struct i16x4(i16, i16, i16, i16); +#[repr(simd)] struct i16x5(i16, i16, i16, i16, i16); +#[repr(simd)] struct i16x6(i16, i16, i16, i16, i16, i16); +#[repr(simd)] struct i16x7(i16, i16, i16, i16, i16, i16, i16); +#[repr(simd)] struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16); + +#[repr(simd)] struct f32x2(f32, f32); +#[repr(simd)] struct f32x3(f32, f32, f32); +#[repr(simd)] struct f32x4(f32, f32, f32, f32); +#[repr(simd)] struct f32x5(f32, f32, f32, f32, f32); +#[repr(simd)] struct f32x6(f32, f32, f32, f32, f32, f32); +#[repr(simd)] struct f32x7(f32, f32, f32, f32, f32, f32, f32); +#[repr(simd)] struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32); + +#[repr(simd)] struct usizex2(usize, usize); +#[repr(simd)] struct usizex3(usize, usize, usize); +#[repr(simd)] struct usizex4(usize, usize, usize, usize); +#[repr(simd)] struct usizex5(usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex6(usize, usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex7(usize, usize, usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex8(usize, usize, usize, usize, usize, usize, usize, usize); + +#[repr(simd)] struct isizex2(isize, isize); +#[repr(simd)] struct isizex3(isize, isize, isize); +#[repr(simd)] struct isizex4(isize, isize, isize, isize); +#[repr(simd)] struct isizex5(isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex6(isize, isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex7(isize, isize, isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex8(isize, isize, isize, isize, isize, isize, isize, isize); + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-target-feature-mixup.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-target-feature-mixup.rs new file mode 100644 index 000000000000..24c6ced86231 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-target-feature-mixup.rs @@ -0,0 +1,186 @@ +// run-pass +#![allow(unused_variables)] +#![allow(stable_features)] +#![allow(overflowing_literals)] + +// ignore-emscripten +// ignore-sgx no processes + +#![feature(repr_simd, target_feature, cfg_target_feature)] +#![feature(avx512_target_feature)] + +use std::process::{Command, ExitStatus}; +use std::env; + +fn main() { + if let Some(level) = env::args().nth(1) { + return test::main(&level) + } + + let me = env::current_exe().unwrap(); + for level in ["sse", "avx", "avx512"].iter() { + let status = Command::new(&me).arg(level).status().unwrap(); + if status.success() { + println!("success with {}", level); + continue + } + + // We don't actually know if our computer has the requisite target features + // for the test below. Testing for that will get added to libstd later so + // for now just assume sigill means this is a machine that can't run this test. + if is_sigill(status) { + println!("sigill with {}, assuming spurious", level); + continue + } + panic!("invalid status at {}: {}", level, status); + } +} + +#[cfg(unix)] +fn is_sigill(status: ExitStatus) -> bool { + use std::os::unix::prelude::*; + status.signal() == Some(4) +} + +#[cfg(windows)] +fn is_sigill(status: ExitStatus) -> bool { + status.code() == Some(0xc000001d) +} + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +#[allow(nonstandard_style)] +mod test { + // An SSE type + #[repr(simd)] + #[derive(PartialEq, Debug, Clone, Copy)] + struct __m128i(u64, u64); + + // An AVX type + #[repr(simd)] + #[derive(PartialEq, Debug, Clone, Copy)] + struct __m256i(u64, u64, u64, u64); + + // An AVX-512 type + #[repr(simd)] + #[derive(PartialEq, Debug, Clone, Copy)] + struct __m512i(u64, u64, u64, u64, u64, u64, u64, u64); + + pub fn main(level: &str) { + unsafe { + main_normal(level); + main_sse(level); + if level == "sse" { + return + } + main_avx(level); + if level == "avx" { + return + } + main_avx512(level); + } + } + + macro_rules! mains { + ($( + $(#[$attr:meta])* + unsafe fn $main:ident(level: &str) { + ... + } + )*) => ($( + $(#[$attr])* + unsafe fn $main(level: &str) { + let m128 = __m128i(1, 2); + let m256 = __m256i(3, 4, 5, 6); + let m512 = __m512i(7, 8, 9, 10, 11, 12, 13, 14); + assert_eq!(id_sse_128(m128), m128); + assert_eq!(id_sse_256(m256), m256); + assert_eq!(id_sse_512(m512), m512); + + if level == "sse" { + return + } + assert_eq!(id_avx_128(m128), m128); + assert_eq!(id_avx_256(m256), m256); + assert_eq!(id_avx_512(m512), m512); + + if level == "avx" { + return + } + assert_eq!(id_avx512_128(m128), m128); + assert_eq!(id_avx512_256(m256), m256); + assert_eq!(id_avx512_512(m512), m512); + } + )*) + } + + mains! { + unsafe fn main_normal(level: &str) { ... } + #[target_feature(enable = "sse2")] + unsafe fn main_sse(level: &str) { ... } + #[target_feature(enable = "avx")] + unsafe fn main_avx(level: &str) { ... } + #[target_feature(enable = "avx512bw")] + unsafe fn main_avx512(level: &str) { ... } + } + + + #[target_feature(enable = "sse2")] + unsafe fn id_sse_128(a: __m128i) -> __m128i { + assert_eq!(a, __m128i(1, 2)); + a.clone() + } + + #[target_feature(enable = "sse2")] + unsafe fn id_sse_256(a: __m256i) -> __m256i { + assert_eq!(a, __m256i(3, 4, 5, 6)); + a.clone() + } + + #[target_feature(enable = "sse2")] + unsafe fn id_sse_512(a: __m512i) -> __m512i { + assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14)); + a.clone() + } + + #[target_feature(enable = "avx")] + unsafe fn id_avx_128(a: __m128i) -> __m128i { + assert_eq!(a, __m128i(1, 2)); + a.clone() + } + + #[target_feature(enable = "avx")] + unsafe fn id_avx_256(a: __m256i) -> __m256i { + assert_eq!(a, __m256i(3, 4, 5, 6)); + a.clone() + } + + #[target_feature(enable = "avx")] + unsafe fn id_avx_512(a: __m512i) -> __m512i { + assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14)); + a.clone() + } + + #[target_feature(enable = "avx512bw")] + unsafe fn id_avx512_128(a: __m128i) -> __m128i { + assert_eq!(a, __m128i(1, 2)); + a.clone() + } + + #[target_feature(enable = "avx512bw")] + unsafe fn id_avx512_256(a: __m256i) -> __m256i { + assert_eq!(a, __m256i(3, 4, 5, 6)); + a.clone() + } + + #[target_feature(enable = "avx512bw")] + unsafe fn id_avx512_512(a: __m512i) -> __m512i { + assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14)); + a.clone() + } +} + +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] +mod test { + pub fn main(level: &str) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/simd/simd-type.rs b/gcc/testsuite/rust/rustc/ui/simd/simd-type.rs new file mode 100644 index 000000000000..2c3c3085732f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simd/simd-type.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] + +// pretty-expanded FIXME #23616 + +#![feature(repr_simd)] + +#[repr(simd)] +struct RGBA { + r: f32, + g: f32, + b: f32, + a: f32 +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/similar-tokens.rs b/gcc/testsuite/rust/rustc/ui/similar-tokens.rs new file mode 100644 index 000000000000..52299b7a4495 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/similar-tokens.rs @@ -0,0 +1,14 @@ +// run-rustfix + +#![allow(unused_imports)] + +pub mod x { + pub struct A; + pub struct B; +} + +// `.` is similar to `,` so list parsing should continue to closing `}` +use x::{A. B}; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/simple-infer.rs b/gcc/testsuite/rust/rustc/ui/simple-infer.rs new file mode 100644 index 000000000000..d3c447fe08f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simple-infer.rs @@ -0,0 +1,7 @@ +// run-pass + +#![allow(unused_mut)] + + +pub fn main() { let mut n; n = 1; println!("{}", n); } + diff --git a/gcc/testsuite/rust/rustc/ui/simple_global_asm.rs b/gcc/testsuite/rust/rustc/ui/simple_global_asm.rs new file mode 100644 index 000000000000..85f09c896877 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/simple_global_asm.rs @@ -0,0 +1,25 @@ +// run-pass + +#![feature(global_asm)] +#![feature(naked_functions)] +#![allow(dead_code)] + +#[cfg(any(target_arch = "x86_64", target_arch = "x86"))] +global_asm!(r#" + .global foo + .global _foo +foo: +_foo: + ret +"#); + +extern { + fn foo(); +} + +#[cfg(any(target_arch = "x86_64", target_arch = "x86"))] +fn main() { unsafe { foo(); } } + +#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/single-primitive-inherent-impl.rs b/gcc/testsuite/rust/rustc/ui/single-primitive-inherent-impl.rs new file mode 100644 index 000000000000..72256521423f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-primitive-inherent-impl.rs @@ -0,0 +1,14 @@ +// ignore-tidy-linelength + +#![crate_type = "lib"] +#![feature(lang_items)] +#![no_std] + +// OK +#[lang = "str_alloc"] +impl str {} + +impl str { +// { dg-error ".E0390." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/fn-types.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/fn-types.rs new file mode 100644 index 000000000000..794d281cd394 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/fn-types.rs @@ -0,0 +1,17 @@ +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +// Test that we DO warn when lifetime name is used only +// once in a fn argument. + +struct Foo { + a: for<'a> fn(&'a u32), // { dg-error "" "" { target *-*-* } } + b: for<'a> fn(&'a u32, &'a u32), // OK, used twice. + c: for<'a> fn(&'a u32) -> &'a u32, // OK, used twice. + d: for<'a> fn() -> &'a u32, // OK, used only in return type. +// { dg-error ".E0581." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-fn-argument-in-band.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-fn-argument-in-band.rs new file mode 100644 index 000000000000..3e85997041b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-fn-argument-in-band.rs @@ -0,0 +1,19 @@ +// run-rustfix + +#![feature(in_band_lifetimes)] +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +// Test that we DO warn when lifetime name is used only +// once in a fn argument, even with in band lifetimes. + +fn a(x: &'a u32, y: &'b u32) { +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +// { help "" "" { target *-*-* } .-4 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-fn-argument.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-fn-argument.rs new file mode 100644 index 000000000000..7ad3c2932e6e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-fn-argument.rs @@ -0,0 +1,23 @@ +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +// Test that we DO warn when lifetime name is used only +// once in a fn argument. + +fn a<'a>(x: &'a u32) { // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } +} + +struct Single<'a> { x: &'a u32 } +struct Double<'a, 'b> { f: &'a &'b u32 } + +fn center<'m>(_: Single<'m>) {} // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } +fn left<'x, 'y>(foo: Double<'x, 'y>) -> &'x u32 { foo.f } // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } +fn right<'x, 'y>(foo: Double<'x, 'y>) -> &'y u32 { foo.f } // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-fn-return.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-fn-return.rs new file mode 100644 index 000000000000..6026f4396c67 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-fn-return.rs @@ -0,0 +1,18 @@ +// Test that we DO NOT warn when lifetime name is used only +// once in a fn return type -- using `'_` is not legal there, +// as it must refer back to an argument. +// +// (Normally, using `'static` would be preferred, but there are +// times when that is not what you want.) + +// check-pass + +#![deny(single_use_lifetimes)] + +// OK: used only in return type +fn b<'a>() -> &'a u32 { + &22 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-inherent-impl-header.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-inherent-impl-header.rs new file mode 100644 index 000000000000..8499ca67ae84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-inherent-impl-header.rs @@ -0,0 +1,23 @@ +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +// Test that we DO warn for a lifetime used only once in an impl, and that we +// don't warn for the anonymous lifetime. + +struct Foo<'f> { + data: &'f u32 +} + +impl<'f> Foo<'f> { // { dg-error "" "" { target *-*-* } } + fn inherent_a(&self) { + } +} + +impl Foo<'_> { + fn inherent_b(&self) {} +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-inherent-method-argument.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-inherent-method-argument.rs new file mode 100644 index 000000000000..09a0dcda8453 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-inherent-method-argument.rs @@ -0,0 +1,18 @@ +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +// Test that we DO warn for a lifetime used only once in an inherent method. + +struct Foo<'f> { + data: &'f u32 +} + +impl<'f> Foo<'f> { // { dg-error "" "" { target *-*-* } } + fn inherent_a<'a>(&self, data: &'a u32) { // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-inherent-method-return.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-inherent-method-return.rs new file mode 100644 index 000000000000..302556f2ee2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-inherent-method-return.rs @@ -0,0 +1,19 @@ +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +// Test that we DO NOT warn for a lifetime used just once in a return type, +// where that return type is in an inherent method. + +struct Foo<'f> { + data: &'f u32 +} + +impl<'f> Foo<'f> { // { dg-error "" "" { target *-*-* } } + fn inherent_a<'a>(&self) -> &'a u32 { // OK for 'a + &22 + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-struct.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-struct.rs new file mode 100644 index 000000000000..e4f37099b3da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-struct.rs @@ -0,0 +1,28 @@ +// Test that we do not warn for named lifetimes in structs, +// even when they are only used once (since to not use a named +// lifetime is illegal!) +// +// check-pass + +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +struct Foo<'f> { + data: &'f u32, +} + +enum Bar<'f> { + Data(&'f u32), +} + +trait Baz<'f> {} + +// `Derive`d impls shouldn't trigger a warning, either (Issue #53738). +#[derive(Debug)] +struct Quux<'a> { + priors: &'a u32, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-trait-method-argument.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-trait-method-argument.rs new file mode 100644 index 000000000000..acacd5a8bc34 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/one-use-in-trait-method-argument.rs @@ -0,0 +1,22 @@ +// Test that we DO warn for a lifetime on an impl used only in `&self` +// in a trait method. + +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +struct Foo<'f> { + data: &'f u32 +} + +impl<'f> Iterator for Foo<'f> { + type Item = &'f u32; + + fn next<'g>(&'g mut self) -> Option { // { dg-error "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + None + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs new file mode 100644 index 000000000000..965fb4c2b24d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs @@ -0,0 +1,16 @@ +// Test that we DO NOT warn when lifetime name is used in +// both the argument and return. +// +// check-pass + +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +// OK: used twice +fn c<'a>(x: &'a u32) -> &'a u32 { + &22 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-fn-arguments.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-fn-arguments.rs new file mode 100644 index 000000000000..d6c0154a0d58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-fn-arguments.rs @@ -0,0 +1,17 @@ +// Test that we DO NOT warn when lifetime name is used multiple +// arguments, or more than once in a single argument. +// +// check-pass + +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +// OK: used twice +fn c<'a>(x: &'a u32, y: &'a u32) {} + +// OK: used twice +fn d<'a>(x: (&'a u32, &'a u32)) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs new file mode 100644 index 000000000000..3bcd73d81d30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs @@ -0,0 +1,18 @@ +// Test that we DO NOT warn for a lifetime used twice in an impl. +// +// check-pass + +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +struct Foo<'f> { + data: &'f u32, +} + +impl<'f> Foo<'f> { + fn inherent_a(&self, data: &'f u32) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.rs new file mode 100644 index 000000000000..04fa05e1c1c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-inherent-method-argument-and-return.rs @@ -0,0 +1,19 @@ +// Test that we DO NOT warn for a lifetime used twice in an impl method and +// header. + +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +struct Foo<'f> { + data: &'f u32 +} + +impl<'f> Foo<'f> { // { dg-error "" "" { target *-*-* } } + fn inherent_a<'a>(&self, data: &'a u32) -> &'a u32{ + data + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-trait-impl.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-trait-impl.rs new file mode 100644 index 000000000000..7a8334eed03f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/two-uses-in-trait-impl.rs @@ -0,0 +1,23 @@ +// Test that we DO NOT warn for a lifetime on an impl used in both +// header and in an associated type. +// +// check-pass + +#![deny(single_use_lifetimes)] +#![allow(dead_code)] +#![allow(unused_variables)] + +struct Foo<'f> { + data: &'f u32, +} + +impl<'f> Iterator for Foo<'f> { + type Item = &'f u32; + + fn next(&mut self) -> Option { + None + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/zero-uses-in-fn.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/zero-uses-in-fn.rs new file mode 100644 index 000000000000..ca28e946b781 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/zero-uses-in-fn.rs @@ -0,0 +1,25 @@ +// run-rustfix + +// Test that we DO warn when lifetime name is not used at all. + +#![deny(unused_lifetimes)] +#![allow(dead_code, unused_variables)] + +fn september<'a>() {} +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + +fn october<'a, 'b, T>(s: &'b T) -> &'b T { +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + s +} + +fn november<'a, 'b>(s: &'a str) -> &'a str { +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + s +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/single-use-lifetime/zero-uses-in-impl.rs b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/zero-uses-in-impl.rs new file mode 100644 index 000000000000..69dabb7a78f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/single-use-lifetime/zero-uses-in-impl.rs @@ -0,0 +1,11 @@ +// Test that we DO warn when lifetime name is not used at all. + +#![deny(unused_lifetimes)] +#![allow(dead_code, unused_variables)] + +struct Foo {} + +impl<'a> Foo {} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/size-and-align.rs b/gcc/testsuite/rust/rustc/ui/size-and-align.rs new file mode 100644 index 000000000000..aa0256bbb082 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/size-and-align.rs @@ -0,0 +1,21 @@ +// run-pass + +#![allow(non_camel_case_types)] +enum clam { a(T, isize), b, } + +fn uhoh(v: Vec> ) { + match v[1] { + clam::a::(ref _t, ref u) => { + println!("incorrect"); + println!("{}", u); + panic!(); + } + clam::b:: => { println!("correct"); } + } +} + +pub fn main() { + let v: Vec> = vec![clam::b::, clam::b::, clam::a::(42, 17)]; + uhoh::(v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/sized-borrowed-pointer.rs b/gcc/testsuite/rust/rustc/ui/sized-borrowed-pointer.rs new file mode 100644 index 000000000000..7b43a085e087 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sized-borrowed-pointer.rs @@ -0,0 +1,11 @@ +// run-pass + +#![allow(dead_code)] +// Possibly-dynamic size of typaram should be cleared at pointer boundary. + +// pretty-expanded FIXME #23616 + +fn bar() { } +fn foo() { bar::<&T>() } +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/sized-cycle-note.rs b/gcc/testsuite/rust/rustc/ui/sized-cycle-note.rs new file mode 100644 index 000000000000..d0bb2f8ead46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sized-cycle-note.rs @@ -0,0 +1,17 @@ +// Test the error message resulting from a cycle in solving `Foo: +// Sized`. The specifics of the message will of course but the main +// thing we want to preserve is that: +// +// 1. the message should appear attached to one of the structs +// defined in this file; +// 2. it should elaborate the steps that led to the cycle. + +struct Baz { q: Option } +// { dg-error ".E0072." "" { target *-*-* } .-1 } +struct Foo { q: Option } +// { dg-error ".E0072." "" { target *-*-* } .-1 } + +impl Foo { fn bar(&self) {} } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/sized-owned-pointer.rs b/gcc/testsuite/rust/rustc/ui/sized-owned-pointer.rs new file mode 100644 index 000000000000..119c5ad7b770 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sized-owned-pointer.rs @@ -0,0 +1,12 @@ +// run-pass + +#![allow(dead_code)] +// Possibly-dynamic size of typaram should be cleared at pointer boundary. + + +// pretty-expanded FIXME #23616 + +fn bar() { } +fn foo() { bar::>() } +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/sleep.rs b/gcc/testsuite/rust/rustc/ui/sleep.rs new file mode 100644 index 000000000000..607f8258b627 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sleep.rs @@ -0,0 +1,19 @@ +// run-pass +// ignore-emscripten no threads support + +use std::thread::{self, sleep}; +use std::time::Duration; +use std::sync::{Arc, Mutex}; +use std::u64; + +fn main() { + let finished = Arc::new(Mutex::new(false)); + let t_finished = finished.clone(); + thread::spawn(move || { + sleep(Duration::new(u64::MAX, 0)); + *t_finished.lock().unwrap() = true; + }); + sleep(Duration::from_millis(100)); + assert_eq!(*finished.lock().unwrap(), false); +} + diff --git a/gcc/testsuite/rust/rustc/ui/slice-2.rs b/gcc/testsuite/rust/rustc/ui/slice-2.rs new file mode 100644 index 000000000000..64e0565aa66c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/slice-2.rs @@ -0,0 +1,12 @@ +// Test that slicing syntax gives errors if we have not implemented the trait. + +struct Foo; + +fn main() { + let x = Foo; + &x[..]; // { dg-error ".E0608." "" { target *-*-* } } + &x[Foo..]; // { dg-error ".E0608." "" { target *-*-* } } + &x[..Foo]; // { dg-error ".E0608." "" { target *-*-* } } + &x[Foo..Foo]; // { dg-error ".E0608." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/slice-mut-2.rs b/gcc/testsuite/rust/rustc/ui/slice-mut-2.rs new file mode 100644 index 000000000000..2092b4ddc389 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/slice-mut-2.rs @@ -0,0 +1,9 @@ +// Test mutability and slicing syntax. + +fn main() { + let x: &[isize] = &[1, 2, 3, 4, 5]; + // Can't mutably slice an immutable slice + let slice: &mut [isize] = &mut [0, 1]; + let _ = &mut x[2..4]; // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/slice-mut.rs b/gcc/testsuite/rust/rustc/ui/slice-mut.rs new file mode 100644 index 000000000000..2acfd96ff44f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/slice-mut.rs @@ -0,0 +1,13 @@ +// Test mutability and slicing syntax. + +fn main() { + let x: &[isize] = &[1, 2, 3, 4, 5]; + // Immutable slices are not mutable. + + let y: &mut[_] = &x[2..4]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/slice-to-vec-comparison.rs b/gcc/testsuite/rust/rustc/ui/slice-to-vec-comparison.rs new file mode 100644 index 000000000000..7d3c2220c232 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/slice-to-vec-comparison.rs @@ -0,0 +1,7 @@ +fn main() { + let a = &[]; + let b: &Vec = &vec![]; + a > b; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/slightly-nice-generic-literal-messages.rs b/gcc/testsuite/rust/rustc/ui/slightly-nice-generic-literal-messages.rs new file mode 100644 index 000000000000..d325511757c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/slightly-nice-generic-literal-messages.rs @@ -0,0 +1,15 @@ +use std::marker; + +struct Foo(T, marker::PhantomData); + +fn main() { + match Foo(1.1, marker::PhantomData) { + 1 => {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/slowparse-bstring.rs b/gcc/testsuite/rust/rustc/ui/slowparse-bstring.rs new file mode 100644 index 000000000000..f697e73b5f7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/slowparse-bstring.rs @@ -0,0 +1,7 @@ +// run-pass +// ignore-tidy-linelength + +// Issue #16624 + +fn main() { b"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; } + diff --git a/gcc/testsuite/rust/rustc/ui/slowparse-string.rs b/gcc/testsuite/rust/rustc/ui/slowparse-string.rs new file mode 100644 index 000000000000..db4d7bd9feb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/slowparse-string.rs @@ -0,0 +1,7 @@ +// run-pass +// ignore-tidy-linelength + +// Issue #16624 + +fn main() { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; } + diff --git a/gcc/testsuite/rust/rustc/ui/span/E0046.rs b/gcc/testsuite/rust/rustc/ui/span/E0046.rs new file mode 100644 index 000000000000..7c0d00292e9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/E0046.rs @@ -0,0 +1,12 @@ +trait Foo { + fn foo(); +} + +struct Bar; + +impl Foo for Bar {} +// { dg-error ".E0046." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/E0057.rs b/gcc/testsuite/rust/rustc/ui/span/E0057.rs new file mode 100644 index 000000000000..f7e0008bff0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/E0057.rs @@ -0,0 +1,7 @@ +fn main() { + let f = |x| x * 3; + let a = f(); // { dg-error ".E0057." "" { target *-*-* } } + let b = f(4); + let c = f(2, 3); // { dg-error ".E0057." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/E0072.rs b/gcc/testsuite/rust/rustc/ui/span/E0072.rs new file mode 100644 index 000000000000..86a4003a284d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/E0072.rs @@ -0,0 +1,8 @@ +struct ListNode { // { dg-error ".E0072." "" { target *-*-* } } + head: u8, + tail: Option, +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/E0204.rs b/gcc/testsuite/rust/rustc/ui/span/E0204.rs new file mode 100644 index 000000000000..1a2049d22d89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/E0204.rs @@ -0,0 +1,27 @@ +struct Foo { + foo: Vec, +} + +impl Copy for Foo { } // { dg-error ".E0204." "" { target *-*-* } } + +#[derive(Copy)] // { dg-error ".E0204." "" { target *-*-* } } +struct Foo2<'a> { + ty: &'a mut bool, +} + +enum EFoo { + Bar { x: Vec }, + Baz, +} + +impl Copy for EFoo { } // { dg-error ".E0204." "" { target *-*-* } } + +#[derive(Copy)] // { dg-error ".E0204." "" { target *-*-* } } +enum EFoo2<'a> { + Bar(&'a mut bool), + Baz, +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/E0493.rs b/gcc/testsuite/rust/rustc/ui/span/E0493.rs new file mode 100644 index 000000000000..6d48fa4c7d4f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/E0493.rs @@ -0,0 +1,22 @@ +struct Foo { + a: u32 +} + +impl Drop for Foo { + fn drop(&mut self) {} +} + +struct Bar { + a: u32 +} + +impl Drop for Bar { + fn drop(&mut self) {} +} + +const F : Foo = (Foo { a : 0 }, Foo { a : 1 }).1; +// { dg-error ".E0493." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/E0535.rs b/gcc/testsuite/rust/rustc/ui/span/E0535.rs new file mode 100644 index 000000000000..5c3880eeba05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/E0535.rs @@ -0,0 +1,7 @@ +#[inline(unknown)] // { dg-error ".E0535." "" { target *-*-* } } +pub fn something() {} + +fn main() { + something(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/E0536.rs b/gcc/testsuite/rust/rustc/ui/span/E0536.rs new file mode 100644 index 000000000000..37f171c3adb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/E0536.rs @@ -0,0 +1,5 @@ +#[cfg(not())] // { dg-error ".E0536." "" { target *-*-* } } +pub fn something() {} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/E0537.rs b/gcc/testsuite/rust/rustc/ui/span/E0537.rs new file mode 100644 index 000000000000..b14bc29928a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/E0537.rs @@ -0,0 +1,5 @@ +#[cfg(unknown())] // { dg-error ".E0537." "" { target *-*-* } } +pub fn something() {} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/auxiliary/transitive_dep_three.rs b/gcc/testsuite/rust/rustc/ui/span/auxiliary/transitive_dep_three.rs new file mode 100644 index 000000000000..db426923a9b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/auxiliary/transitive_dep_three.rs @@ -0,0 +1,10 @@ +#[macro_export] +macro_rules! define_parse_error { + () => { + #[macro_export] + macro_rules! parse_error { + () => { parse error } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/auxiliary/transitive_dep_two.rs b/gcc/testsuite/rust/rustc/ui/span/auxiliary/transitive_dep_two.rs new file mode 100644 index 000000000000..46d5980dc861 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/auxiliary/transitive_dep_two.rs @@ -0,0 +1,4 @@ +extern crate transitive_dep_three; + +transitive_dep_three::define_parse_error!(); + diff --git a/gcc/testsuite/rust/rustc/ui/span/borrowck-borrow-overloaded-auto-deref-mut.rs b/gcc/testsuite/rust/rustc/ui/span/borrowck-borrow-overloaded-auto-deref-mut.rs new file mode 100644 index 000000000000..63b47d471242 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/borrowck-borrow-overloaded-auto-deref-mut.rs @@ -0,0 +1,143 @@ +// Test how overloaded deref interacts with borrows when DerefMut +// is implemented. + +use std::ops::{Deref, DerefMut}; + +struct Own { + value: *mut T +} + +impl Deref for Own { + type Target = T; + + fn deref(&self) -> &T { + unsafe { &*self.value } + } +} + +impl DerefMut for Own { + fn deref_mut(&mut self) -> &mut T { + unsafe { &mut *self.value } + } +} + +struct Point { + x: isize, + y: isize +} + +impl Point { + fn get(&self) -> (isize, isize) { + (self.x, self.y) + } + + fn set(&mut self, x: isize, y: isize) { + self.x = x; + self.y = y; + } + + fn x_ref(&self) -> &isize { + &self.x + } + + fn y_mut(&mut self) -> &mut isize { + &mut self.y + } +} + +fn deref_imm_field(x: Own) { + let __isize = &x.y; +} + +fn deref_mut_field1(x: Own) { + let __isize = &mut x.y; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_mut_field2(mut x: Own) { + let __isize = &mut x.y; +} + +fn deref_extend_field(x: &Own) -> &isize { + &x.y +} + +fn deref_extend_mut_field1(x: &Own) -> &mut isize { + &mut x.y // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_extend_mut_field2(x: &mut Own) -> &mut isize { + &mut x.y +} + +fn deref_extend_mut_field3(x: &mut Own) { + // Hmm, this is unfortunate, because with box it would work, + // but it's presently the expected outcome. See `deref_extend_mut_field4` + // for the workaround. + + let _x = &mut x.x; + let _y = &mut x.y; // { dg-error ".E0499." "" { target *-*-* } } + use_mut(_x); +} +fn deref_extend_mut_field4<'a>(x: &'a mut Own) { + let p = &mut **x; + let _x = &mut p.x; + let _y = &mut p.y; +} + +fn assign_field1<'a>(x: Own) { + x.y = 3; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn assign_field2<'a>(x: &'a Own) { + x.y = 3; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn assign_field3<'a>(x: &'a mut Own) { + x.y = 3; +} + +fn assign_field4<'a>(x: &'a mut Own) { + let _p: &mut Point = &mut **x; + x.y = 3; // { dg-error ".E0499." "" { target *-*-* } } + use_mut(_p); +} +fn deref_imm_method(x: Own) { + let __isize = x.get(); +} + +fn deref_mut_method1(x: Own) { + x.set(0, 0); // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_mut_method2(mut x: Own) { + x.set(0, 0); +} + +fn deref_extend_method(x: &Own) -> &isize { + x.x_ref() +} + +fn deref_extend_mut_method1(x: &Own) -> &mut isize { + x.y_mut() // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_extend_mut_method2(x: &mut Own) -> &mut isize { + x.y_mut() +} + +fn assign_method1<'a>(x: Own) { + *x.y_mut() = 3; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn assign_method2<'a>(x: &'a Own) { + *x.y_mut() = 3; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn assign_method3<'a>(x: &'a mut Own) { + *x.y_mut() = 3; +} + +pub fn main() {} + +fn use_mut(_: &mut T) {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/borrowck-borrow-overloaded-deref-mut.rs b/gcc/testsuite/rust/rustc/ui/span/borrowck-borrow-overloaded-deref-mut.rs new file mode 100644 index 000000000000..340774f617c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/borrowck-borrow-overloaded-deref-mut.rs @@ -0,0 +1,61 @@ +// Test how overloaded deref interacts with borrows when DerefMut +// is implemented. + +use std::ops::{Deref, DerefMut}; + +struct Own { + value: *mut T +} + +impl Deref for Own { + type Target = T; + + fn deref<'a>(&'a self) -> &'a T { + unsafe { &*self.value } + } +} + +impl DerefMut for Own { + fn deref_mut<'a>(&'a mut self) -> &'a mut T { + unsafe { &mut *self.value } + } +} + +fn deref_imm(x: Own) { + let __isize = &*x; +} + +fn deref_mut1(x: Own) { + let __isize = &mut *x; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_mut2(mut x: Own) { + let __isize = &mut *x; +} + +fn deref_extend<'a>(x: &'a Own) -> &'a isize { + &**x +} + +fn deref_extend_mut1<'a>(x: &'a Own) -> &'a mut isize { + &mut **x // { dg-error ".E0596." "" { target *-*-* } } +} + +fn deref_extend_mut2<'a>(x: &'a mut Own) -> &'a mut isize { + &mut **x +} + +fn assign1<'a>(x: Own) { + *x = 3; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn assign2<'a>(x: &'a Own) { + **x = 3; // { dg-error ".E0596." "" { target *-*-* } } +} + +fn assign3<'a>(x: &'a mut Own) { + **x = 3; +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/borrowck-call-is-borrow-issue-12224.rs b/gcc/testsuite/rust/rustc/ui/span/borrowck-call-is-borrow-issue-12224.rs new file mode 100644 index 000000000000..a2d415a13c33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/borrowck-call-is-borrow-issue-12224.rs @@ -0,0 +1,63 @@ +#![feature(fn_traits)] + +// Ensure that invoking a closure counts as a unique immutable borrow + +type Fn<'a> = Box; + +struct Test<'a> { + f: Box +} + +fn call(mut f: F) where F: FnMut(Fn) { + f(Box::new(|| { +// { dg-error ".E0499." "" { target *-*-* } .-1 } + f((Box::new(|| {}))) + })); +} + +fn test1() { + call(|mut a| { + a.call_mut(()); + }); +} + +fn test2(f: &F) where F: FnMut() { + (*f)(); +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + +fn test3(f: &mut F) where F: FnMut() { + (*f)(); +} + +fn test4(f: &Test) { + f.f.call_mut(()) +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + +fn test5(f: &mut Test) { + f.f.call_mut(()) +} + +fn test6() { + let mut f = || {}; + (|| { + f(); + })(); +} + +fn test7() { + fn foo(_: F) where F: FnMut(Box, isize) {} + let s = String::new(); // Capture to make f !Copy + let mut f = move |g: Box, b: isize| { + let _ = s.len(); + }; + f(Box::new(|a| { +// { dg-error ".E0505." "" { target *-*-* } .-1 } + foo(f); +// { dg-error ".E0507." "" { target *-*-* } .-1 } + }), 3); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/borrowck-call-method-from-mut-aliasable.rs b/gcc/testsuite/rust/rustc/ui/span/borrowck-call-method-from-mut-aliasable.rs new file mode 100644 index 000000000000..5f3ef51f73d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/borrowck-call-method-from-mut-aliasable.rs @@ -0,0 +1,22 @@ +struct Foo { + x: isize, +} + +impl Foo { + pub fn f(&self) {} + pub fn h(&mut self) {} +} + +fn a(x: &mut Foo) { + x.f(); + x.h(); +} + +fn b(x: &Foo) { + x.f(); + x.h(); // { dg-error ".E0596." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/borrowck-fn-in-const-b.rs b/gcc/testsuite/rust/rustc/ui/span/borrowck-fn-in-const-b.rs new file mode 100644 index 000000000000..aa3c8e953abb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/borrowck-fn-in-const-b.rs @@ -0,0 +1,15 @@ +// Check that we check fns appearing in constant declarations. +// Issue #22382. + +// How about mutating an immutable vector? +const MUTATE: fn(&Vec) = { + fn broken(x: &Vec) { + x.push(format!("this is broken")); +// { dg-error ".E0596." "" { target *-*-* } .-1 } + } + broken +}; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/borrowck-let-suggestion-suffixes.rs b/gcc/testsuite/rust/rustc/ui/span/borrowck-let-suggestion-suffixes.rs new file mode 100644 index 000000000000..e77f671314b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/borrowck-let-suggestion-suffixes.rs @@ -0,0 +1,60 @@ +fn id(x: T) -> T { x } + +fn f() { + let old = ['o']; // statement 0 + let mut v1 = Vec::new(); // statement 1 + + let mut v2 = Vec::new(); // statement 2 + + { + let young = ['y']; // statement 3 + + v2.push(&young[0]); // statement 4 +// { dg-error ".E0597." "" { target *-*-* } .-1 } +// { dg-note ".E0597." "" { target *-*-* } .-2 } + } // { dg-note "" "" { target *-*-* } } + + let mut v3 = Vec::new(); // statement 5 + + v3.push(&id('x')); // statement 6 +// { dg-error ".E0716." "" { target *-*-* } .-1 } +// { dg-note ".E0716." "" { target *-*-* } .-2 } +// { dg-note ".E0716." "" { target *-*-* } .-3 } +// { dg-note ".E0716." "" { target *-*-* } .-4 } + + { + + let mut v4 = Vec::new(); // (sub) statement 0 + + v4.push(&id('y')); +// { dg-error ".E0716." "" { target *-*-* } .-1 } +// { dg-note ".E0716." "" { target *-*-* } .-2 } +// { dg-note ".E0716." "" { target *-*-* } .-3 } +// { dg-note ".E0716." "" { target *-*-* } .-4 } + v4.use_ref(); +// { dg-note "" "" { target *-*-* } .-1 } + } // (statement 7) + + let mut v5 = Vec::new(); // statement 8 + + v5.push(&id('z')); +// { dg-error ".E0716." "" { target *-*-* } .-1 } +// { dg-note ".E0716." "" { target *-*-* } .-2 } +// { dg-note ".E0716." "" { target *-*-* } .-3 } +// { dg-note ".E0716." "" { target *-*-* } .-4 } + + v1.push(&old[0]); + + (v1, v2, v3, /* v4 is above. */ v5).use_ref(); +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +// { dg-note "" "" { target *-*-* } .-3 } +} + +fn main() { + f(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/span/borrowck-object-mutability.rs b/gcc/testsuite/rust/rustc/ui/span/borrowck-object-mutability.rs new file mode 100644 index 000000000000..a65e9db4ae70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/borrowck-object-mutability.rs @@ -0,0 +1,27 @@ +trait Foo { + fn borrowed(&self); + fn borrowed_mut(&mut self); +} + +fn borrowed_receiver(x: &dyn Foo) { + x.borrowed(); + x.borrowed_mut(); // { dg-error ".E0596." "" { target *-*-* } } +} + +fn borrowed_mut_receiver(x: &mut dyn Foo) { + x.borrowed(); + x.borrowed_mut(); +} + +fn owned_receiver(x: Box) { + x.borrowed(); + x.borrowed_mut(); // { dg-error ".E0596." "" { target *-*-* } } +} + +fn mut_owned_receiver(mut x: Box) { + x.borrowed(); + x.borrowed_mut(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/borrowck-ref-into-rvalue.rs b/gcc/testsuite/rust/rustc/ui/span/borrowck-ref-into-rvalue.rs new file mode 100644 index 000000000000..875c7c6194e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/borrowck-ref-into-rvalue.rs @@ -0,0 +1,12 @@ +fn main() { + let msg; + match Some("Hello".to_string()) { +// { dg-error ".E0716." "" { target *-*-* } .-1 } + Some(ref m) => { + msg = m; + }, + None => { panic!() } + } + println!("{}", *msg); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/coerce-suggestions.rs b/gcc/testsuite/rust/rustc/ui/span/coerce-suggestions.rs new file mode 100644 index 000000000000..991774a7b48e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/coerce-suggestions.rs @@ -0,0 +1,24 @@ +#![feature(box_syntax)] + +fn test(_x: &mut String) {} +fn test2(_x: &mut i32) {} + +fn main() { + let x: usize = String::new(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let x: &str = String::new(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let y = String::new(); + test(&y); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + test2(&y); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let f; + f = box f; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + let s = &mut String::new(); + s = format!("foo"); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/destructor-restrictions.rs b/gcc/testsuite/rust/rustc/ui/span/destructor-restrictions.rs new file mode 100644 index 000000000000..413a5adaa68a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/destructor-restrictions.rs @@ -0,0 +1,12 @@ +// Tests the new destructor semantics. + +use std::cell::RefCell; + +fn main() { + let b = { + let a = Box::new(RefCell::new(4)); + *a.borrow() + 1 +// { dg-error ".E0597." "" { target *-*-* } .-1 } + println!("{}", b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/dropck-object-cycle.rs b/gcc/testsuite/rust/rustc/ui/span/dropck-object-cycle.rs new file mode 100644 index 000000000000..74dbfda1c185 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/dropck-object-cycle.rs @@ -0,0 +1,48 @@ +// This test used to be part of a run-pass test, but revised outlives +// rule means that it no longer compiles. + +#![allow(unused_variables)] + +trait Trait<'a> { + fn long(&'a self) -> isize; + fn short<'b>(&'b self) -> isize; +} + +fn object_invoke1<'d>(x: &'d dyn Trait<'d>) -> (isize, isize) { loop { } } + +trait MakerTrait { + fn mk() -> Self; +} + +fn make_val() -> T { + MakerTrait::mk() +} + +impl<'t> MakerTrait for Box+'static> { + fn mk() -> Box+'static> { loop { } } +} + +pub fn main() { + let m : Box = make_val(); + assert_eq!(object_invoke1(&*m), (4,5)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + // the problem here is that the full type of `m` is + // + // Box+'static> + // + // Here `'m` must be exactly the lifetime of the variable `m`. + // This is because of two requirements: + // 1. First, the basic type rules require that the + // type of `m`'s value outlives the lifetime of `m`. This puts a lower + // bound `'m`. + // + // 2. Meanwhile, the signature of `object_invoke1` requires that + // we create a reference of type `&'d Trait<'d>` for some `'d`. + // `'d` cannot outlive `'m`, so that forces the lifetime to be `'m`. + // + // This then conflicts with the dropck rules, which require that + // the type of `m` *strictly outlives* `'m`. Hence we get an + // error. +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/dropck_arr_cycle_checked.rs b/gcc/testsuite/rust/rustc/ui/span/dropck_arr_cycle_checked.rs new file mode 100644 index 000000000000..8516b2609e1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/dropck_arr_cycle_checked.rs @@ -0,0 +1,107 @@ +// Reject mixing cyclic structure and Drop when using fixed length +// arrays. +// +// (Compare against compile-fail/dropck_vec_cycle_checked.rs) + + + +use std::cell::Cell; +use id::Id; + +mod s { + use std::sync::atomic::{AtomicUsize, Ordering}; + + static S_COUNT: AtomicUsize = AtomicUsize::new(0); + + pub fn next_count() -> usize { + S_COUNT.fetch_add(1, Ordering::SeqCst) + 1 + } +} + +mod id { + use s; + #[derive(Debug)] + pub struct Id { + orig_count: usize, + count: usize, + } + + impl Id { + pub fn new() -> Id { + let c = s::next_count(); + println!("building Id {}", c); + Id { orig_count: c, count: c } + } + pub fn count(&self) -> usize { + println!("Id::count on {} returns {}", self.orig_count, self.count); + self.count + } + } + + impl Drop for Id { + fn drop(&mut self) { + println!("dropping Id {}", self.count); + self.count = 0; + } + } +} + +trait HasId { + fn count(&self) -> usize; +} + +#[derive(Debug)] +struct CheckId { + v: T +} + +#[allow(non_snake_case)] +fn CheckId(t: T) -> CheckId { CheckId{ v: t } } + +impl Drop for CheckId { + fn drop(&mut self) { + assert!(self.v.count() > 0); + } +} + +#[derive(Debug)] +struct B<'a> { + id: Id, + a: [CheckId>>>; 2] +} + +impl<'a> HasId for Cell>> { + fn count(&self) -> usize { + match self.get() { + None => 1, + Some(b) => b.id.count(), + } + } +} + +impl<'a> B<'a> { + fn new() -> B<'a> { + B { id: Id::new(), a: [CheckId(Cell::new(None)), CheckId(Cell::new(None))] } + } +} + +fn f() { + let (b1, b2, b3); + b1 = B::new(); + b2 = B::new(); + b3 = B::new(); + b1.a[0].v.set(Some(&b2)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + b1.a[1].v.set(Some(&b3)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + b2.a[0].v.set(Some(&b2)); + b2.a[1].v.set(Some(&b3)); + b3.a[0].v.set(Some(&b1)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + b3.a[1].v.set(Some(&b2)); +} + +fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/dropck_direct_cycle_with_drop.rs b/gcc/testsuite/rust/rustc/ui/span/dropck_direct_cycle_with_drop.rs new file mode 100644 index 000000000000..87d9cb209e48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/dropck_direct_cycle_with_drop.rs @@ -0,0 +1,45 @@ +// A simple example of an unsound mixing of cyclic structure and Drop. +// +// Each `D` has a name and an optional reference to another `D` +// sibling, but also implements a drop method that prints out its own +// name as well as the name of its sibling. +// +// By setting up a cyclic structure, the drop code cannot possibly +// work. Therefore this code must be rejected. +// +// (As it turns out, essentially any attempt to install a sibling here +// will be rejected, regardless of whether it forms a cyclic +// structure or not. This is because the use of the same lifetime +// `'a` in `&'a D<'a>` cannot be satisfied when `D<'a>` implements +// `Drop`.) + +use std::cell::Cell; + +struct D<'a> { + name: String, + p: Cell>>, +} + +impl<'a> D<'a> { + fn new(name: String) -> D<'a> { D { name: name, p: Cell::new(None) } } +} + +impl<'a> Drop for D<'a> { + fn drop(&mut self) { + println!("dropping {} whose sibling is {:?}", + self.name, self.p.get().map(|d| &d.name)); + } +} + +fn g() { + let (d1, d2) = (D::new(format!("d1")), D::new(format!("d2"))); + d1.p.set(Some(&d2)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + d2.p.set(Some(&d1)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } +} + +fn main() { + g(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/dropck_misc_variants.rs b/gcc/testsuite/rust/rustc/ui/span/dropck_misc_variants.rs new file mode 100644 index 000000000000..4465c1871132 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/dropck_misc_variants.rs @@ -0,0 +1,38 @@ +// check that dropck does the right thing with misc. Ty variants + +use std::fmt; +struct NoisyDrop(T); +impl Drop for NoisyDrop { + fn drop(&mut self) { + let _ = vec!["0wned"]; + println!("dropping {:?}", self.0) + } +} + +trait Associator { + type As; +} +impl Associator for T { + type As = NoisyDrop; +} +struct Wrap(::As); + +fn projection() { + let (_w, bomb); + bomb = vec![""]; + _w = Wrap::<&[&str]>(NoisyDrop(&bomb)); +} +// { dg-error ".E0597." "" { target *-*-* } .-2 } + +fn closure() { + let (_w,v); + v = vec![""]; + _w = { + let u = NoisyDrop(&v); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + move || u.0.len() + }; +} + +fn main() { closure(); projection() } + diff --git a/gcc/testsuite/rust/rustc/ui/span/dropck_vec_cycle_checked.rs b/gcc/testsuite/rust/rustc/ui/span/dropck_vec_cycle_checked.rs new file mode 100644 index 000000000000..586a966c40e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/dropck_vec_cycle_checked.rs @@ -0,0 +1,112 @@ +// Reject mixing cyclic structure and Drop when using Vec. +// +// (Compare against compile-fail/dropck_arr_cycle_checked.rs) + +use std::cell::Cell; +use id::Id; + +mod s { + use std::sync::atomic::{AtomicUsize, Ordering}; + + static S_COUNT: AtomicUsize = AtomicUsize::new(0); + + pub fn next_count() -> usize { + S_COUNT.fetch_add(1, Ordering::SeqCst) + 1 + } +} + +mod id { + use s; + #[derive(Debug)] + pub struct Id { + orig_count: usize, + count: usize, + } + + impl Id { + pub fn new() -> Id { + let c = s::next_count(); + println!("building Id {}", c); + Id { orig_count: c, count: c } + } + pub fn count(&self) -> usize { + println!("Id::count on {} returns {}", self.orig_count, self.count); + self.count + } + } + + impl Drop for Id { + fn drop(&mut self) { + println!("dropping Id {}", self.count); + self.count = 0; + } + } +} + +trait HasId { + fn count(&self) -> usize; +} + +#[derive(Debug)] +struct CheckId { + v: T +} + +#[allow(non_snake_case)] +fn CheckId(t: T) -> CheckId { CheckId{ v: t } } + +impl Drop for CheckId { + fn drop(&mut self) { + assert!(self.v.count() > 0); + } +} + +#[derive(Debug)] +struct C<'a> { + id: Id, + v: Vec>>>>, +} + +impl<'a> HasId for Cell>> { + fn count(&self) -> usize { + match self.get() { + None => 1, + Some(c) => c.id.count(), + } + } +} + +impl<'a> C<'a> { + fn new() -> C<'a> { + C { id: Id::new(), v: Vec::new() } + } +} + +fn f() { + let (mut c1, mut c2, mut c3); + c1 = C::new(); + c2 = C::new(); + c3 = C::new(); + + c1.v.push(CheckId(Cell::new(None))); + c1.v.push(CheckId(Cell::new(None))); + c2.v.push(CheckId(Cell::new(None))); + c2.v.push(CheckId(Cell::new(None))); + c3.v.push(CheckId(Cell::new(None))); + c3.v.push(CheckId(Cell::new(None))); + + c1.v[0].v.set(Some(&c2)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + c1.v[1].v.set(Some(&c3)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + c2.v[0].v.set(Some(&c2)); + c2.v[1].v.set(Some(&c3)); + c3.v[0].v.set(Some(&c1)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + c3.v[1].v.set(Some(&c2)); +} + +fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/gated-features-attr-spans.rs b/gcc/testsuite/rust/rustc/ui/span/gated-features-attr-spans.rs new file mode 100644 index 000000000000..e909b1501926 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/gated-features-attr-spans.rs @@ -0,0 +1,8 @@ +#[repr(simd)] // { dg-error ".E0658." "" { target *-*-* } } +struct Coord { + x: u32, + y: u32, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/impl-wrong-item-for-trait.rs b/gcc/testsuite/rust/rustc/ui/span/impl-wrong-item-for-trait.rs new file mode 100644 index 000000000000..44531229a3d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/impl-wrong-item-for-trait.rs @@ -0,0 +1,41 @@ +use std::fmt::Debug; + +trait Foo { + fn bar(&self); + const MY_CONST: u32; +} + +pub struct FooConstForMethod; + +impl Foo for FooConstForMethod { +// { dg-error ".E0046." "" { target *-*-* } .-1 } + const bar: u64 = 1; +// { dg-error ".E0323." "" { target *-*-* } .-1 } + const MY_CONST: u32 = 1; +} + +pub struct FooMethodForConst; + +impl Foo for FooMethodForConst { +// { dg-error ".E0046." "" { target *-*-* } .-1 } + fn bar(&self) {} + fn MY_CONST() {} +// { dg-error ".E0324." "" { target *-*-* } .-1 } +} + +pub struct FooTypeForMethod; + +impl Foo for FooTypeForMethod { +// { dg-error ".E0046." "" { target *-*-* } .-1 } + type bar = u64; +// { dg-error ".E0325." "" { target *-*-* } .-1 } +// { dg-error ".E0325." "" { target *-*-* } .-2 } + const MY_CONST: u32 = 1; +} + +impl Debug for FooTypeForMethod { +} +// { dg-error ".E0046." "" { target *-*-* } .-2 } + +fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/import-ty-params.rs b/gcc/testsuite/rust/rustc/ui/span/import-ty-params.rs new file mode 100644 index 000000000000..25b00518ccd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/import-ty-params.rs @@ -0,0 +1,21 @@ +mod a { + pub mod b { + pub mod c { + pub struct S(T); + } + } +} + +macro_rules! import { + ($p: path) => (use $p;); +} + +fn f1() { + import! { a::b::c::S } // { dg-error "" "" { target *-*-* } } +} +fn f2() { + import! { a::b::c::S<> } // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-11925.rs b/gcc/testsuite/rust/rustc/ui/span/issue-11925.rs new file mode 100644 index 000000000000..c869754535c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-11925.rs @@ -0,0 +1,14 @@ +#![feature(box_syntax, unboxed_closures)] + +fn to_fn_once>(f: F) -> F { f } + +fn main() { + let r = { + let x: Box<_> = box 42; + let f = to_fn_once(move|| &x); // { dg-error ".E0515." "" { target *-*-* } } + f() + }; + + drop(r); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-15480.rs b/gcc/testsuite/rust/rustc/ui/span/issue-15480.rs new file mode 100644 index 000000000000..ff412b1e05d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-15480.rs @@ -0,0 +1,13 @@ +fn id(x: T) -> T { x } + +fn main() { + let v = vec![ + &id(3) + ]; +// { dg-error ".E0716." "" { target *-*-* } .-2 } + + for &&x in &v { + println!("{}", x + 3); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-23338-locals-die-before-temps-of-body.rs b/gcc/testsuite/rust/rustc/ui/span/issue-23338-locals-die-before-temps-of-body.rs new file mode 100644 index 000000000000..9637696e6099 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-23338-locals-die-before-temps-of-body.rs @@ -0,0 +1,29 @@ +// This is just checking that we still reject code where temp values +// are borrowing values for longer than they will be around. +// +// Compare to run-pass/issue-23338-params-outlive-temps-of-body.rs + +use std::cell::RefCell; + +fn foo(x: RefCell) -> String { + let y = x; + y.borrow().clone() +} +// { dg-error ".E0597." "" { target *-*-* } .-2 } + +fn foo2(x: RefCell) -> String { + let ret = { + let y = x; + y.borrow().clone() + }; +// { dg-error ".E0597." "" { target *-*-* } .-2 } + ret +} + +fn main() { + let r = RefCell::new(format!("data")); + assert_eq!(foo(r), "data"); + let r = RefCell::new(format!("data")); + assert_eq!(foo2(r), "data"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-23729.rs b/gcc/testsuite/rust/rustc/ui/span/issue-23729.rs new file mode 100644 index 000000000000..756aa1e1cb63 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-23729.rs @@ -0,0 +1,34 @@ +// Regression test for #23729 + +fn main() { + let fib = { + struct Recurrence { + mem: [u64; 2], + pos: usize, + } + + impl Iterator for Recurrence { +// { dg-error ".E0046." "" { target *-*-* } .-1 } + #[inline] + fn next(&mut self) -> Option { + if self.pos < 2 { + let next_val = self.mem[self.pos]; + self.pos += 1; + Some(next_val) + } else { + let next_val = self.mem[0] + self.mem[1]; + self.mem[0] = self.mem[1]; + self.mem[1] = next_val; + Some(next_val) + } + } + } + + Recurrence { mem: [0, 1], pos: 0 } + }; + + for e in fib.take(10) { + println!("{}", e) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-23827.rs b/gcc/testsuite/rust/rustc/ui/span/issue-23827.rs new file mode 100644 index 000000000000..845d21ab01ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-23827.rs @@ -0,0 +1,34 @@ +// Regression test for #23827 + +#![feature(core, fn_traits, unboxed_closures)] + +pub struct Prototype { + pub target: u32 +} + +trait Component { + fn apply(self, e: u32); +} + +impl Fn<(C,)> for Prototype { + extern "rust-call" fn call(&self, (comp,): (C,)) -> Prototype { + comp.apply(self.target); + *self + } +} + +impl FnMut<(C,)> for Prototype { + extern "rust-call" fn call_mut(&mut self, (comp,): (C,)) -> Prototype { + Fn::call(*&self, (comp,)) + } +} + +impl FnOnce<(C,)> for Prototype { +// { dg-error ".E0046." "" { target *-*-* } .-1 } + extern "rust-call" fn call_once(self, (comp,): (C,)) -> Prototype { + Fn::call(&self, (comp,)) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-24356.rs b/gcc/testsuite/rust/rustc/ui/span/issue-24356.rs new file mode 100644 index 000000000000..9f6d14fcf166 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-24356.rs @@ -0,0 +1,28 @@ +// Regression test for #24356 + +fn main() { + { + use std::ops::Deref; + + struct Thing(i8); + + /* + // Correct impl + impl Deref for Thing { + type Target = i8; + fn deref(&self) -> &i8 { &self.0 } + } + */ + + // Causes ICE + impl Deref for Thing { +// { dg-error ".E0046." "" { target *-*-* } .-1 } + fn deref(&self) -> i8 { self.0 } + } + + let thing = Thing(72); + + *thing + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-24690.rs b/gcc/testsuite/rust/rustc/ui/span/issue-24690.rs new file mode 100644 index 000000000000..d347c5e20cc8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-24690.rs @@ -0,0 +1,17 @@ +//! A test to ensure that helpful `note` messages aren't emitted more often +//! than necessary. + +// check-pass + +// Although there are three warnings, we should only get two "lint level defined +// here" notes pointing at the `warnings` span, one for each error type. +#![warn(unused)] + + +fn main() { + let theTwo = 2; // { dg-warning "" "" { target *-*-* } } + let theOtherTwo = 2; // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-1 } + println!("{}", theTwo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-24805-dropck-child-has-items-via-parent.rs b/gcc/testsuite/rust/rustc/ui/span/issue-24805-dropck-child-has-items-via-parent.rs new file mode 100644 index 000000000000..19801ed23dd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-24805-dropck-child-has-items-via-parent.rs @@ -0,0 +1,38 @@ +// Check that child trait who only has items via its *parent* trait +// does cause dropck to inject extra region constraints. + +#![allow(non_camel_case_types)] + +trait Parent { fn foo(&self); } +trait Child: Parent { } + +impl Parent for i32 { fn foo(&self) { } } +impl<'a> Parent for &'a D_Child { + fn foo(&self) { + println!("accessing child value: {}", self.0); + } +} + +impl Child for i32 { } +impl<'a> Child for &'a D_Child { } + +struct D_Child(T); +impl Drop for D_Child { fn drop(&mut self) { self.0.foo() } } + +fn f_child() { + // `_d` and `d1` are assigned the *same* lifetime by region inference ... + let (_d, d1); + + d1 = D_Child(1); + // ... we store a reference to `d1` within `_d` ... + _d = D_Child(&d1); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + // ... dropck *should* complain, because Drop of _d could (and + // does) access the already dropped `d1` via the `foo` method. +} + +fn main() { + f_child(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-24805-dropck-trait-has-items.rs b/gcc/testsuite/rust/rustc/ui/span/issue-24805-dropck-trait-has-items.rs new file mode 100644 index 000000000000..a666b275b547 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-24805-dropck-trait-has-items.rs @@ -0,0 +1,58 @@ +// Check that traits with various kinds of associated items cause +// dropck to inject extra region constraints. + +#![allow(non_camel_case_types)] + +trait HasSelfMethod { fn m1(&self) { } } +trait HasMethodWithSelfArg { fn m2(x: &Self) { } } +trait HasType { type Something; } + +impl HasSelfMethod for i32 { } +impl HasMethodWithSelfArg for i32 { } +impl HasType for i32 { type Something = (); } + +impl<'a,T> HasSelfMethod for &'a T { } +impl<'a,T> HasMethodWithSelfArg for &'a T { } +impl<'a,T> HasType for &'a T { type Something = (); } + +// e.g., `impl_drop!(Send, D_Send)` expands to: +// ```rust +// struct D_Send(T); +// impl Drop for D_Send { fn drop(&mut self) { } } +// ``` +macro_rules! impl_drop { + ($Bound:ident, $Id:ident) => { + struct $Id(T); + impl Drop for $Id { fn drop(&mut self) { } } + } +} + +impl_drop!{HasSelfMethod, D_HasSelfMethod} +impl_drop!{HasMethodWithSelfArg, D_HasMethodWithSelfArg} +impl_drop!{HasType, D_HasType} + +fn f_sm() { + let (_d, d1); + d1 = D_HasSelfMethod(1); + _d = D_HasSelfMethod(&d1); +} +// { dg-error ".E0597." "" { target *-*-* } .-2 } +fn f_mwsa() { + let (_d, d1); + d1 = D_HasMethodWithSelfArg(1); + _d = D_HasMethodWithSelfArg(&d1); +} +// { dg-error ".E0597." "" { target *-*-* } .-2 } +fn f_t() { + let (_d, d1); + d1 = D_HasType(1); + _d = D_HasType(&d1); +} +// { dg-error ".E0597." "" { target *-*-* } .-2 } + +fn main() { + f_sm(); + f_mwsa(); + f_t(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-24895-copy-clone-dropck.rs b/gcc/testsuite/rust/rustc/ui/span/issue-24895-copy-clone-dropck.rs new file mode 100644 index 000000000000..430359e24048 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-24895-copy-clone-dropck.rs @@ -0,0 +1,30 @@ +// Check that one cannot subvert Drop Check rule via a user-defined +// Clone implementation. + +#![allow(unused_variables, unused_assignments)] + +struct D(T, &'static str); + +#[derive(Copy)] +struct S<'a>(&'a D, &'static str); +impl<'a> Clone for S<'a> { + fn clone(&self) -> S<'a> { + println!("cloning `S(_, {})` and thus accessing: {}", self.1, (self.0).0); + S(self.0, self.1) + } +} + +impl Drop for D { + fn drop(&mut self) { + println!("calling Drop for {}", self.1); + let _call = self.0.clone(); + } +} + +fn main() { + let (d2, d1); + d1 = D(34, "d1"); + d2 = D(S(&d1, "inner"), "d2"); +} +// { dg-error ".E0597." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-25199.rs b/gcc/testsuite/rust/rustc/ui/span/issue-25199.rs new file mode 100644 index 000000000000..ffcf26626d72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-25199.rs @@ -0,0 +1,75 @@ +// Regression test for Issue 25199: Check that one cannot hide a +// destructor's access to borrowed data behind a boxed trait object. +// +// Prior to fixing Issue 25199, this example was able to be compiled +// with rustc, and thus when you ran it, you would see the `Drop` impl +// for `Test` accessing state that had already been dropping (which is +// marked explicitly here with checking code within the `Drop` impl +// for `VecHolder`, but in the general case could just do unsound +// things like accessing memory that has been freed). +// +// Note that I would have liked to encode my go-to example of cyclic +// structure that accesses its neighbors in drop (and thus is +// fundamentally unsound) via this trick, but the closest I was able +// to come was dropck_trait_cycle_checked.rs, which is not quite as +// "good" as this regression test because the encoding of that example +// was forced to attach a lifetime to the trait definition itself +// (`trait Obj<'a>`) while *this* example is solely + +use std::cell::RefCell; + +trait Obj { } + +struct VecHolder { + v: Vec<(bool, &'static str)>, +} + +impl Drop for VecHolder { + fn drop(&mut self) { + println!("Dropping Vec"); + self.v[30].0 = false; + self.v[30].1 = "invalid access: VecHolder dropped already"; + } +} + +struct Container<'a> { + v: VecHolder, + d: RefCell>>, +} + +impl<'a> Container<'a> { + fn new() -> Container<'a> { + Container { + d: RefCell::new(Vec::new()), + v: VecHolder { + v: vec![(true, "valid"); 100] + } + } + } + + fn store(&'a self, val: T) { + self.d.borrow_mut().push(Box::new(val)); + } +} + +struct Test<'a> { + test: &'a Container<'a>, +} + +impl<'a> Obj for Test<'a> { } +impl<'a> Drop for Test<'a> { + fn drop(&mut self) { + for e in &self.test.v.v { + assert!(e.0, e.1); + } + } +} + +fn main() { + let container = Container::new(); + let test = Test{test: &container}; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + println!("container.v[30]: {:?}", container.v.v[30]); + container.store(test); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-26656.rs b/gcc/testsuite/rust/rustc/ui/span/issue-26656.rs new file mode 100644 index 000000000000..dbbfdbe77cb2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-26656.rs @@ -0,0 +1,43 @@ +// Issue #26656: Verify that trait objects cannot bypass dropck. + +// Using this instead of Fn etc. to take HRTB out of the equation. +trait Trigger { fn fire(&self, b: &mut B); } +impl Trigger for () { + fn fire(&self, b: &mut B) { + b.push(); + } +} + +// Still unsound Zook +trait Button { fn push(&self); } +struct Zook { button: B, trigger: Box+'static> } + +impl Drop for Zook { + fn drop(&mut self) { + self.trigger.fire(&mut self.button); + } +} + +// AND +struct Bomb { usable: bool } +impl Drop for Bomb { fn drop(&mut self) { self.usable = false; } } +impl Bomb { fn activate(&self) { assert!(self.usable) } } + +enum B<'a> { HarmlessButton, BigRedButton(&'a Bomb) } +impl<'a> Button for B<'a> { + fn push(&self) { + if let B::BigRedButton(borrowed) = *self { + borrowed.activate(); + } + } +} + +fn main() { + let (mut zook, ticking); + zook = Zook { button: B::HarmlessButton, + trigger: Box::new(()) }; + ticking = Bomb { usable: true }; + zook.button = B::BigRedButton(&ticking); +} +// { dg-error ".E0597." "" { target *-*-* } .-2 } + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-27522.rs b/gcc/testsuite/rust/rustc/ui/span/issue-27522.rs new file mode 100644 index 000000000000..91f48c83f8a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-27522.rs @@ -0,0 +1,10 @@ +// Point at correct span for self type + +struct SomeType {} + +trait Foo { + fn handler(self: &SomeType); // { dg-error ".E0307." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-29106.rs b/gcc/testsuite/rust/rustc/ui/span/issue-29106.rs new file mode 100644 index 000000000000..6b576d73031f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-29106.rs @@ -0,0 +1,27 @@ +use std::rc::Rc; +use std::sync::Arc; + +struct Foo<'a>(&'a String); + +impl<'a> Drop for Foo<'a> { + fn drop(&mut self) { + println!("{:?}", self.0); + } +} + +fn main() { + { + let (y, x); + x = "alive".to_string(); + y = Arc::new(Foo(&x)); + } +// { dg-error ".E0597." "" { target *-*-* } .-2 } + + { + let (y, x); + x = "alive".to_string(); + y = Rc::new(Foo(&x)); + } +// { dg-error ".E0597." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-29595.rs b/gcc/testsuite/rust/rustc/ui/span/issue-29595.rs new file mode 100644 index 000000000000..dbdc0acc4f73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-29595.rs @@ -0,0 +1,8 @@ +trait Tr { + const C: Self; +} + +fn main() { + let a: u8 = Tr::C; // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-33884.rs b/gcc/testsuite/rust/rustc/ui/span/issue-33884.rs new file mode 100644 index 000000000000..e11a590564f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-33884.rs @@ -0,0 +1,21 @@ +// ignore-cloudabi no std::net support + +use std::net::TcpListener; +use std::net::TcpStream; +use std::io::{self, Read, Write}; + +fn handle_client(stream: TcpStream) -> io::Result<()> { + stream.write_fmt(format!("message received")) +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() { + if let Ok(listener) = TcpListener::bind("127.0.0.1:8080") { + for incoming in listener.incoming() { + if let Ok(stream) = incoming { + handle_client(stream); + } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-34264.rs b/gcc/testsuite/rust/rustc/ui/span/issue-34264.rs new file mode 100644 index 000000000000..42f174afd2dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-34264.rs @@ -0,0 +1,12 @@ +fn foo(Option, String) {} // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } +fn bar(x, y: usize) {} // { dg-error "" "" { target *-*-* } } + +fn main() { + foo(Some(42), 2); + foo(Some(42), 2, ""); // { dg-error ".E0061." "" { target *-*-* } } + bar("", ""); // { dg-error ".E0308." "" { target *-*-* } } + bar(1, 2); + bar(1, 2, 3); // { dg-error ".E0061." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-35987.rs b/gcc/testsuite/rust/rustc/ui/span/issue-35987.rs new file mode 100644 index 000000000000..70735408a4eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-35987.rs @@ -0,0 +1,15 @@ +struct Foo(T); + +use std::ops::Add; + +impl Add for Foo { +// { dg-error ".E0404." "" { target *-*-* } .-1 } + type Output = usize; + + fn add(self, rhs: Self) -> Self::Output { + unimplemented!(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-36530.rs b/gcc/testsuite/rust/rustc/ui/span/issue-36530.rs new file mode 100644 index 000000000000..5121be3adee4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-36530.rs @@ -0,0 +1,13 @@ +// gate-test-custom_inner_attributes + +#![feature(register_attr)] + +#![register_attr(foo)] + +#[foo] +mod foo { + #![foo] // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-36537.rs b/gcc/testsuite/rust/rustc/ui/span/issue-36537.rs new file mode 100644 index 000000000000..52c12590f475 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-36537.rs @@ -0,0 +1,15 @@ +fn main() { + let p; + { + let a = 42; + p = &a; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + } + p.use_ref(); + +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-37767.rs b/gcc/testsuite/rust/rustc/ui/span/issue-37767.rs new file mode 100644 index 000000000000..2d072ea2e5d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-37767.rs @@ -0,0 +1,42 @@ +trait A { + fn foo(&mut self) {} +} + +trait B : A { + fn foo(&mut self) {} +} + +fn bar(a: &T) { + a.foo() // { dg-error ".E0034." "" { target *-*-* } } +} + +trait C { + fn foo(&self) {} +} + +trait D : C { + fn foo(&self) {} +} + +fn quz(a: &T) { + a.foo() // { dg-error ".E0034." "" { target *-*-* } } +} + +trait E : Sized { + fn foo(self) {} +} + +trait F : E { + fn foo(self) {} +} + +fn foo(a: T) { + a.foo() // { dg-error ".E0034." "" { target *-*-* } } +} + +fn pass(a: &T) { + a.foo() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-39018.rs b/gcc/testsuite/rust/rustc/ui/span/issue-39018.rs new file mode 100644 index 000000000000..0345098caf64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-39018.rs @@ -0,0 +1,39 @@ +pub fn main() { + let x = "Hello " + "World!"; +// { dg-error ".E0369." "" { target *-*-* } .-1 } + + // Make sure that the span outputs a warning + // for not having an implementation for std::ops::Add + // that won't output for the above string concatenation + let y = World::Hello + World::Goodbye; +// { dg-error ".E0369." "" { target *-*-* } .-1 } + + let x = "Hello " + "World!".to_owned(); +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} + +enum World { + Hello, + Goodbye, +} + +fn foo() { + let a = String::new(); + let b = String::new(); + let c = ""; + let d = ""; + let e = &a; + let _ = &a + &b; // { dg-error ".E0369." "" { target *-*-* } } + let _ = &a + b; // { dg-error ".E0369." "" { target *-*-* } } + let _ = a + &b; // ok + let _ = a + b; // { dg-error ".E0308." "" { target *-*-* } } + let _ = e + b; // { dg-error ".E0369." "" { target *-*-* } } + let _ = e + &b; // { dg-error ".E0369." "" { target *-*-* } } + let _ = e + d; // { dg-error ".E0369." "" { target *-*-* } } + let _ = e + &d; // { dg-error ".E0369." "" { target *-*-* } } + let _ = &c + &d; // { dg-error ".E0369." "" { target *-*-* } } + let _ = &c + d; // { dg-error ".E0369." "" { target *-*-* } } + let _ = c + &d; // { dg-error ".E0369." "" { target *-*-* } } + let _ = c + d; // { dg-error ".E0369." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-39698.rs b/gcc/testsuite/rust/rustc/ui/span/issue-39698.rs new file mode 100644 index 000000000000..80e889e6c3a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-39698.rs @@ -0,0 +1,17 @@ +enum T { + T1(i32, i32), + T2(i32, i32), + T3(i32), + T4(i32), +} + +fn main() { + match T::T1(123, 456) { + T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } +// { dg-error ".E0408." "" { target *-*-* } .-1 } +// { dg-error ".E0408." "" { target *-*-* } .-2 } +// { dg-error ".E0408." "" { target *-*-* } .-3 } +// { dg-error ".E0408." "" { target *-*-* } .-4 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-40157.rs b/gcc/testsuite/rust/rustc/ui/span/issue-40157.rs new file mode 100644 index 000000000000..8c07c49abd22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-40157.rs @@ -0,0 +1,5 @@ +fn main () { + {println!("{:?}", match { let foo = vec![1, 2]; foo.get(1) } { x => x });} +// { dg-error ".E0597." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-42234-unknown-receiver-type.rs b/gcc/testsuite/rust/rustc/ui/span/issue-42234-unknown-receiver-type.rs new file mode 100644 index 000000000000..e03b49ca9680 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-42234-unknown-receiver-type.rs @@ -0,0 +1,18 @@ +// When the type of a method call's receiver is unknown, the span should point +// to the receiver (and not the entire call, as was previously the case before +// the fix of which this tests). + +fn shines_a_beacon_through_the_darkness() { + let x: Option<_> = None; + x.unwrap().method_that_could_exist_on_some_type(); +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + +fn courier_to_des_moines_and_points_west(data: &[u32]) -> String { + data.iter() + .sum::<_>() // { dg-error ".E0282." "" { target *-*-* } } + .to_string() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-43927-non-ADT-derive.rs b/gcc/testsuite/rust/rustc/ui/span/issue-43927-non-ADT-derive.rs new file mode 100644 index 000000000000..5cc69571ddc3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-43927-non-ADT-derive.rs @@ -0,0 +1,14 @@ +#![allow(dead_code)] + +#![derive(Debug, PartialEq, Eq)] // should be an outer attribute! +// { dg-error ".E0774." "" { target *-*-* } .-1 } +// { dg-error ".E0774." "" { target *-*-* } .-2 } +// { dg-error ".E0774." "" { target *-*-* } .-3 } +// { dg-error ".E0774." "" { target *-*-* } .-4 } +// { dg-error ".E0774." "" { target *-*-* } .-5 } +// { dg-error ".E0774." "" { target *-*-* } .-6 } +// { dg-error ".E0774." "" { target *-*-* } .-7 } +struct DerivedOn; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue-7575.rs b/gcc/testsuite/rust/rustc/ui/span/issue-7575.rs new file mode 100644 index 000000000000..c0e4fee7896a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue-7575.rs @@ -0,0 +1,76 @@ +// Test the mechanism for warning about possible missing `self` declarations. +trait CtxtFn { + fn f8(self, _: usize) -> usize; + fn f9(_: usize) -> usize; +} + +trait OtherTrait { + fn f9(_: usize) -> usize; +} + +// Note: this trait is not implemented, but we can't really tell +// whether or not an impl would match anyhow without a self +// declaration to match against, so we wind up prisizeing it as a +// candidate. This seems not unreasonable -- perhaps the user meant to +// implement it, after all. +trait UnusedTrait { + fn f9(_: usize) -> usize; +} + +impl CtxtFn for usize { + fn f8(self, i: usize) -> usize { + i * 4 + } + + fn f9(i: usize) -> usize { + i * 4 + } +} + +impl OtherTrait for usize { + fn f9(i: usize) -> usize { + i * 8 + } +} + +struct Myisize(isize); + +impl Myisize { + fn fff(i: isize) -> isize { + i + } +} + +trait ManyImplTrait { + fn is_str() -> bool { + false + } +} + +impl ManyImplTrait for String { + fn is_str() -> bool { + true + } +} + +impl ManyImplTrait for usize {} +impl ManyImplTrait for isize {} +impl ManyImplTrait for char {} +impl ManyImplTrait for Myisize {} + +fn no_param_bound(u: usize, m: Myisize) -> usize { + u.f8(42) + u.f9(342) + m.fff(42) +// { dg-error ".E0599." "" { target *-*-* } .-1 } +// { dg-error ".E0599." "" { target *-*-* } .-2 } + + +} + +fn param_bound(t: T) -> bool { + t.is_str() +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue28498-reject-ex1.rs b/gcc/testsuite/rust/rustc/ui/span/issue28498-reject-ex1.rs new file mode 100644 index 000000000000..75eec6cc1c9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue28498-reject-ex1.rs @@ -0,0 +1,38 @@ +// Example taken from RFC 1238 text + +// https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md +// #examples-of-code-that-will-start-to-be-rejected + +// Compare against test/run-pass/issue28498-must-work-ex2.rs + +use std::cell::Cell; + +struct Concrete<'a>(u32, Cell>>); + +struct Foo { data: Vec } + +fn potentially_specialized_wrt_t(t: &T) { + // Hypothetical code that does one thing for generic T and then is + // specialized for T == Concrete (and the specialized form can + // then access a reference held in concrete tuple). + // + // (We don't have specialization yet, but we want to allow for it + // in the future.) +} + +impl Drop for Foo { + fn drop(&mut self) { + potentially_specialized_wrt_t(&self.data[0]) + } +} + +fn main() { + let mut foo = Foo { data: Vec::new() }; + foo.data.push(Concrete(0, Cell::new(None))); + foo.data.push(Concrete(0, Cell::new(None))); + + foo.data[0].1.set(Some(&foo.data[1])); +// { dg-error ".E0713." "" { target *-*-* } .-1 } + foo.data[1].1.set(Some(&foo.data[0])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue28498-reject-lifetime-param.rs b/gcc/testsuite/rust/rustc/ui/span/issue28498-reject-lifetime-param.rs new file mode 100644 index 000000000000..b5e7b4352b17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue28498-reject-lifetime-param.rs @@ -0,0 +1,37 @@ +// Demonstrate that having a lifetime param causes dropck to reject code +// that might indirectly access previously dropped value. +// +// Compare with run-pass/issue28498-ugeh-with-lifetime-param.rs + +#[derive(Debug)] +struct ScribbleOnDrop(String); + +impl Drop for ScribbleOnDrop { + fn drop(&mut self) { + self.0 = format!("DROPPED"); + } +} + +struct Foo<'a>(u32, &'a ScribbleOnDrop); + +impl<'a> Drop for Foo<'a> { + fn drop(&mut self) { + // Use of `may_dangle` is unsound, because destructor accesses borrowed data + // in `self.1` and we must force that to strictly outlive `self`. + println!("Dropping Foo({}, {:?})", self.0, self.1); + } +} + +fn main() { + let (last_dropped, foo0); + let (foo1, first_dropped); + + last_dropped = ScribbleOnDrop(format!("last")); + first_dropped = ScribbleOnDrop(format!("first")); + foo0 = Foo(0, &last_dropped); // OK + foo1 = Foo(1, &first_dropped); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue28498-reject-passed-to-fn.rs b/gcc/testsuite/rust/rustc/ui/span/issue28498-reject-passed-to-fn.rs new file mode 100644 index 000000000000..db52e055fd81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue28498-reject-passed-to-fn.rs @@ -0,0 +1,39 @@ +// Demonstrate that a type param in negative position causes dropck to reject code +// that might indirectly access previously dropped value. +// +// Compare with run-pass/issue28498-ugeh-with-passed-to-fn.rs + +#[derive(Debug)] +struct ScribbleOnDrop(String); + +impl Drop for ScribbleOnDrop { + fn drop(&mut self) { + self.0 = format!("DROPPED"); + } +} + +struct Foo(u32, T, Box fn(&'r T) -> String>); + +impl Drop for Foo { + fn drop(&mut self) { + // Use of `may_dangle` is unsound, because we pass `T` to the callback in `self.2` + // below, and thus potentially read from borrowed data. + println!("Dropping Foo({}, {})", self.0, (self.2)(&self.1)); + } +} + +fn callback(s: & &ScribbleOnDrop) -> String { format!("{:?}", s) } + +fn main() { + let (last_dropped, foo0); + let (foo1, first_dropped); + + last_dropped = ScribbleOnDrop(format!("last")); + first_dropped = ScribbleOnDrop(format!("first")); + foo0 = Foo(0, &last_dropped, Box::new(callback)); // OK + foo1 = Foo(1, &first_dropped, Box::new(callback)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/issue28498-reject-trait-bound.rs b/gcc/testsuite/rust/rustc/ui/span/issue28498-reject-trait-bound.rs new file mode 100644 index 000000000000..8dff7a9e0a3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/issue28498-reject-trait-bound.rs @@ -0,0 +1,39 @@ +// Demonstrate that having a trait bound causes dropck to reject code +// that might indirectly access previously dropped value. +// +// Compare with run-pass/issue28498-ugeh-with-trait-bound.rs + +use std::fmt; + +#[derive(Debug)] +struct ScribbleOnDrop(String); + +impl Drop for ScribbleOnDrop { + fn drop(&mut self) { + self.0 = format!("DROPPED"); + } +} + +struct Foo(u32, T); + +impl Drop for Foo { + fn drop(&mut self) { + // Use of `may_dangle` is unsound, because we access `T` fmt method when we pass + // `self.1` below, and thus potentially read from borrowed data. + println!("Dropping Foo({}, {:?})", self.0, self.1); + } +} + +fn main() { + let (last_dropped, foo0); + let (foo1, first_dropped); + + last_dropped = ScribbleOnDrop(format!("last")); + first_dropped = ScribbleOnDrop(format!("first")); + foo0 = Foo(0, &last_dropped); // OK + foo1 = Foo(1, &first_dropped); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + println!("foo0.1: {:?} foo1.1: {:?}", foo0.1, foo1.1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/lint-unused-unsafe.rs b/gcc/testsuite/rust/rustc/ui/span/lint-unused-unsafe.rs new file mode 100644 index 000000000000..a098ac94c799 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/lint-unused-unsafe.rs @@ -0,0 +1,57 @@ +// Exercise the unused_unsafe attribute in some positive and negative cases + +#![allow(dead_code)] +#![deny(unused_unsafe)] + + +mod foo { + extern { + pub fn bar(); + } +} + +fn callback(_f: F) -> T where F: FnOnce() -> T { panic!() } +unsafe fn unsf() {} + +fn bad1() { unsafe {} } // { dg-error "" "" { target *-*-* } } +fn bad2() { unsafe { bad1() } } // { dg-error "" "" { target *-*-* } } +unsafe fn bad3() { unsafe {} } // { dg-error "" "" { target *-*-* } } +fn bad4() { unsafe { callback(||{}) } } // { dg-error "" "" { target *-*-* } } +unsafe fn bad5() { unsafe { unsf() } } // { dg-error "" "" { target *-*-* } } +fn bad6() { + unsafe { // don't put the warning here + unsafe { // { dg-error "" "" { target *-*-* } } + unsf() + } + } +} +unsafe fn bad7() { + unsafe { // { dg-error "" "" { target *-*-* } } + unsafe { // { dg-error "" "" { target *-*-* } } + unsf() + } + } +} + +unsafe fn good0() { unsf() } +fn good1() { unsafe { unsf() } } +fn good2() { + /* bug uncovered when implementing warning about unused unsafe blocks. Be + sure that when purity is inherited that the source of the unsafe-ness + is tracked correctly */ + unsafe { + unsafe fn what() -> Vec { panic!() } + + callback(|| { + what(); + }); + } +} + +unsafe fn good3() { foo::bar() } +fn good4() { unsafe { foo::bar() } } + +#[allow(unused_unsafe)] fn allowed() { unsafe {} } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/macro-span-replacement.rs b/gcc/testsuite/rust/rustc/ui/span/macro-span-replacement.rs new file mode 100644 index 000000000000..004cf911d15d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/macro-span-replacement.rs @@ -0,0 +1,14 @@ +// check-pass + +#![warn(unused)] + +macro_rules! m { + ($a:tt $b:tt) => { + $b $a; // { dg-warning "" "" { target *-*-* } } + } +} + +fn main() { + m!(S struct); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/macro-ty-params.rs b/gcc/testsuite/rust/rustc/ui/span/macro-ty-params.rs new file mode 100644 index 000000000000..c2f88d8ab427 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/macro-ty-params.rs @@ -0,0 +1,14 @@ +macro_rules! m { + ($p1: path) => { + #[derive($p1)] struct U; + } +} + +macro_rules! foo { () => () } + +fn main() { + foo::!(); // { dg-error "" "" { target *-*-* } } + foo::<>!(); // { dg-error "" "" { target *-*-* } } + m!(Default<>); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/method-and-field-eager-resolution.rs b/gcc/testsuite/rust/rustc/ui/span/method-and-field-eager-resolution.rs new file mode 100644 index 000000000000..103307457728 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/method-and-field-eager-resolution.rs @@ -0,0 +1,16 @@ +// Test that spans get only base in eager type resolution (structurally_resolve_type). + +fn main() { + let mut x = Default::default(); + x.0; +// { dg-error ".E0282." "" { target *-*-* } .-1 } + x = 1; +} + +fn foo() { + let mut x = Default::default(); + x[0]; +// { dg-error ".E0282." "" { target *-*-* } .-1 } + x = 1; +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/missing-unit-argument.rs b/gcc/testsuite/rust/rustc/ui/span/missing-unit-argument.rs new file mode 100644 index 000000000000..d7747fdc95b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/missing-unit-argument.rs @@ -0,0 +1,18 @@ +fn foo(():(), ():()) {} +fn bar(():()) {} + +struct S; +impl S { + fn baz(self, (): ()) { } + fn generic(self, _: T) { } +} + +fn main() { + let _: Result<(), String> = Ok(); // { dg-error ".E0061." "" { target *-*-* } } + foo(); // { dg-error ".E0061." "" { target *-*-* } } + foo(()); // { dg-error ".E0061." "" { target *-*-* } } + bar(); // { dg-error ".E0061." "" { target *-*-* } } + S.baz(); // { dg-error ".E0061." "" { target *-*-* } } + S.generic::<()>(); // { dg-error ".E0061." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/move-closure.rs b/gcc/testsuite/rust/rustc/ui/span/move-closure.rs new file mode 100644 index 000000000000..11d784cc25f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/move-closure.rs @@ -0,0 +1,7 @@ +// Regression test for issue #24986 +// Make sure that the span of a closure marked `move` begins at the `move` keyword. + +fn main() { + let x: () = move || (); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/multiline-span-E0072.rs b/gcc/testsuite/rust/rustc/ui/span/multiline-span-E0072.rs new file mode 100644 index 000000000000..8ee70191bf3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/multiline-span-E0072.rs @@ -0,0 +1,11 @@ +// It should just use the entire body instead of pointing at the next two lines +struct // { dg-error ".E0072." "" { target *-*-* } } +ListNode +{ + head: u8, + tail: Option, +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/multiline-span-simple.rs b/gcc/testsuite/rust/rustc/ui/span/multiline-span-simple.rs new file mode 100644 index 000000000000..51abe077835d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/multiline-span-simple.rs @@ -0,0 +1,21 @@ +fn foo(a: u32, b: u32) { + a + b; +} + +fn bar(a: u32, b: u32) { + a + b; +} + +fn main() { + let x = 1; + let y = 2; + let z = 3; + foo(1 as u32 + // { dg-error ".E0277." "" { target *-*-* } } + + bar(x, + + y), + + z) +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/multispan-import-lint.rs b/gcc/testsuite/rust/rustc/ui/span/multispan-import-lint.rs new file mode 100644 index 000000000000..8d4e4a9eea29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/multispan-import-lint.rs @@ -0,0 +1,11 @@ +// check-pass + +#![warn(unused)] + +use std::cmp::{Eq, Ord, min, PartialEq, PartialOrd}; +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() { + let _ = min(1, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/mut-arg-hint.rs b/gcc/testsuite/rust/rustc/ui/span/mut-arg-hint.rs new file mode 100644 index 000000000000..39ad950e8c27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/mut-arg-hint.rs @@ -0,0 +1,23 @@ +trait B { + fn foo(mut a: &String) { + a.push_str("bar"); // { dg-error ".E0596." "" { target *-*-* } } + } +} + +pub fn foo<'a>(mut a: &'a String) { + a.push_str("foo"); // { dg-error ".E0596." "" { target *-*-* } } +} + +struct A {} + +impl A { + pub fn foo(mut a: &String) { + a.push_str("foo"); // { dg-error ".E0596." "" { target *-*-* } } + } +} + +fn main() { + foo(&"a".to_string()); + A::foo(&"a".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/mut-ptr-cant-outlive-ref.rs b/gcc/testsuite/rust/rustc/ui/span/mut-ptr-cant-outlive-ref.rs new file mode 100644 index 000000000000..23d1790b211f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/mut-ptr-cant-outlive-ref.rs @@ -0,0 +1,16 @@ +use std::cell::RefCell; + +fn main() { + let m = RefCell::new(0); + let p; + { + let b = m.borrow(); + p = &*b; + } +// { dg-error ".E0597." "" { target *-*-* } .-2 } + p.use_ref(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/span/non-existing-module-import.rs b/gcc/testsuite/rust/rustc/ui/span/non-existing-module-import.rs new file mode 100644 index 000000000000..21a23ef51893 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/non-existing-module-import.rs @@ -0,0 +1,4 @@ +use std::bar::{foo1, foo2}; // { dg-error ".E0432." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/pub-struct-field.rs b/gcc/testsuite/rust/rustc/ui/span/pub-struct-field.rs new file mode 100644 index 000000000000..b540908a0a18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/pub-struct-field.rs @@ -0,0 +1,11 @@ +// Regression test for issue #26083 and #35435 +// Test that span for public struct fields start at `pub` + +struct Foo { + bar: u8, + pub bar: u8, // { dg-error ".E0124." "" { target *-*-* } } + pub(crate) bar: u8, // { dg-error ".E0124." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/range-2.rs b/gcc/testsuite/rust/rustc/ui/span/range-2.rs new file mode 100644 index 000000000000..0863b8d3f063 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/range-2.rs @@ -0,0 +1,16 @@ +// Test range syntax - borrow errors. +#![feature(rustc_attrs)] +pub fn main() { #![rustc_error] // rust-lang/rust#49855 + let r = { + let a = 42; + let b = 42; + &a..&b + }; +// { dg-error ".E0597." "" { target *-*-* } .-2 } +// { dg-error ".E0597." "" { target *-*-* } .-2 } + r.use_ref(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/span/recursive-type-field.rs b/gcc/testsuite/rust/rustc/ui/span/recursive-type-field.rs new file mode 100644 index 000000000000..b04cff79a88a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/recursive-type-field.rs @@ -0,0 +1,19 @@ +use std::rc::Rc; + +struct Foo<'a> { // { dg-error ".E0072." "" { target *-*-* } } + bar: Bar<'a>, + b: Rc>, +} + +struct Bar<'a> { // { dg-error ".E0072." "" { target *-*-* } } + y: (Foo<'a>, Foo<'a>), + z: Option>, + a: &'a Foo<'a>, + c: &'a [Bar<'a>], + d: [Bar<'a>; 1], + e: Foo<'a>, + x: Bar<'a>, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/regionck-unboxed-closure-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/span/regionck-unboxed-closure-lifetimes.rs new file mode 100644 index 000000000000..ab6208a8c4f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/regionck-unboxed-closure-lifetimes.rs @@ -0,0 +1,17 @@ +#![feature(rustc_attrs)] +use std::ops::FnMut; + +fn main() { #![rustc_error] // rust-lang/rust#49855 + let mut f; + { + let c = 1; + let c_ref = &c; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + f = move |a: isize, b: isize| { a + b + *c_ref }; + } + f.use_mut(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/span/regions-close-over-borrowed-ref-in-obj.rs b/gcc/testsuite/rust/rustc/ui/span/regions-close-over-borrowed-ref-in-obj.rs new file mode 100644 index 000000000000..012767bc7eac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/regions-close-over-borrowed-ref-in-obj.rs @@ -0,0 +1,17 @@ +#![feature(box_syntax)] + +fn id(x: T) -> T { x } + +trait Foo { } + +impl<'a> Foo for &'a isize { } + +fn main() { + let blah; + { + let ss: &isize = &id(1); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + blah = box ss as Box; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/regions-close-over-type-parameter-2.rs b/gcc/testsuite/rust/rustc/ui/span/regions-close-over-type-parameter-2.rs new file mode 100644 index 000000000000..d7a28ca78833 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/regions-close-over-type-parameter-2.rs @@ -0,0 +1,28 @@ +#![feature(box_syntax)] + +// Test for what happens when a type parameter `A` is closed over into +// an object. This should yield errors unless `A` (and the object) +// both have suitable bounds. + +trait Foo { fn get(&self); } + +impl Foo for A { + fn get(&self) { } +} + +fn repeater3<'a,A:'a>(v: A) -> Box { + box v as Box +} + +fn main() { + // Error results because the type of is inferred to be + // ~Repeat<&'blk isize> where blk is the lifetime of the block below. + + let _ = { + let tmp0 = 3; + let tmp1 = &tmp0; + repeater3(tmp1) + }; +// { dg-error ".E0597." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/regions-escape-loop-via-variable.rs b/gcc/testsuite/rust/rustc/ui/span/regions-escape-loop-via-variable.rs new file mode 100644 index 000000000000..e7207c5fefae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/regions-escape-loop-via-variable.rs @@ -0,0 +1,15 @@ +fn main() { + let x = 3; + + // Here, the variable `p` gets inferred to a type with a lifetime + // of the loop body. The regionck then determines that this type + // is invalid. + let mut p = &x; + + loop { + let x = 1 + *p; + p = &x; + } +// { dg-error ".E0597." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/regions-escape-loop-via-vec.rs b/gcc/testsuite/rust/rustc/ui/span/regions-escape-loop-via-vec.rs new file mode 100644 index 000000000000..05511e083c0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/regions-escape-loop-via-vec.rs @@ -0,0 +1,14 @@ +// The type of `y` ends up getting inferred to the type of the block. +fn broken() { + let mut x = 3; + let mut _y = vec![&mut x]; + while x < 10 { // { dg-error ".E0503." "" { target *-*-* } } + let mut z = x; // { dg-error ".E0503." "" { target *-*-* } } + _y.push(&mut z); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + x += 1; // { dg-error ".E0503." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/span/regions-infer-borrow-scope-within-loop.rs b/gcc/testsuite/rust/rustc/ui/span/regions-infer-borrow-scope-within-loop.rs new file mode 100644 index 000000000000..5ea50a5eb50c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/regions-infer-borrow-scope-within-loop.rs @@ -0,0 +1,23 @@ +fn borrow(x: &T) -> &T {x} + +fn foo(mut cond: C, mut make_box: M) where + C: FnMut() -> bool, + M: FnMut() -> Box, +{ + let mut y: &isize; + loop { + let x = make_box(); + + // Here we complain because the resulting region + // of this borrow is the fn body as a whole. + y = borrow(&*x); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + assert_eq!(*x, *y); + if cond() { break; } + } + assert!(*y != 0); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/send-is-not-static-ensures-scoping.rs b/gcc/testsuite/rust/rustc/ui/span/send-is-not-static-ensures-scoping.rs new file mode 100644 index 000000000000..6708fe5fd477 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/send-is-not-static-ensures-scoping.rs @@ -0,0 +1,27 @@ +struct Guard<'a> { + f: Box, +} + +fn scoped<'a, F: Fn() + Send + 'a>(f: F) -> Guard<'a> { + Guard { f: Box::new(f) } +} + +impl<'a> Guard<'a> { + fn join(self) {} +} + +fn main() { + let bad = { + let x = 1; + let y = &x; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + scoped(|| { + let _z = y; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + }) + }; + + bad.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/send-is-not-static-std-sync-2.rs b/gcc/testsuite/rust/rustc/ui/span/send-is-not-static-std-sync-2.rs new file mode 100644 index 000000000000..24942db7c0e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/send-is-not-static-std-sync-2.rs @@ -0,0 +1,40 @@ +// basic tests to see that certain "obvious" errors are caught by +// these types no longer requiring `'static` (RFC 458) + +#![allow(dead_code)] + +use std::sync::{Mutex, RwLock, mpsc}; + +fn mutex() { + let lock = { + let x = 1; + Mutex::new(&x) + }; +// { dg-error ".E0597." "" { target *-*-* } .-2 } + + let _dangling = *lock.lock().unwrap(); +} + +fn rwlock() { + let lock = { + let x = 1; + RwLock::new(&x) + }; +// { dg-error ".E0597." "" { target *-*-* } .-2 } + let _dangling = *lock.read().unwrap(); +} + +fn channel() { + let (_tx, rx) = { + let x = 1; + let (tx, rx) = mpsc::channel(); + let _ = tx.send(&x); + (tx, rx) + }; +// { dg-error ".E0597." "" { target *-*-* } .-3 } + + let _dangling = rx.recv(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/send-is-not-static-std-sync.rs b/gcc/testsuite/rust/rustc/ui/span/send-is-not-static-std-sync.rs new file mode 100644 index 000000000000..5493a7c0c219 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/send-is-not-static-std-sync.rs @@ -0,0 +1,56 @@ +// basic tests to see that certain "obvious" errors are caught by +// these types no longer requiring `'static` (RFC 458) + +#![allow(dead_code)] + +use std::sync::{Mutex, RwLock, mpsc}; + +fn mutex() { + let x = 1; + let y = Box::new(1); + let lock = Mutex::new(&x); + *lock.lock().unwrap() = &*y; + drop(y); // { dg-error ".E0505." "" { target *-*-* } } + { + let z = 2; + *lock.lock().unwrap() = &z; + } +// { dg-error ".E0597." "" { target *-*-* } .-2 } + lock.use_ref(); // (Mutex is #[may_dangle] so its dtor does not use `z` => needs explicit use) +} + +fn rwlock() { + let x = 1; + let y = Box::new(1); + let lock = RwLock::new(&x); + *lock.write().unwrap() = &*y; + drop(y); // { dg-error ".E0505." "" { target *-*-* } } + { + let z = 2; + *lock.write().unwrap() = &z; + } +// { dg-error ".E0597." "" { target *-*-* } .-2 } + lock.use_ref(); // (RwLock is #[may_dangle] so its dtor does not use `z` => needs explicit use) +} + +fn channel() { + let x = 1; + let y = Box::new(1); + let (tx, rx) = mpsc::channel(); + + tx.send(&x).unwrap(); + tx.send(&*y); + drop(y); // { dg-error ".E0505." "" { target *-*-* } } + { + let z = 2; + tx.send(&z).unwrap(); + } +// { dg-error ".E0597." "" { target *-*-* } .-2 } + // (channels lack #[may_dangle], thus their dtors are implicit uses of `z`) +} + +fn main() {} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/span/slice-borrow.rs b/gcc/testsuite/rust/rustc/ui/span/slice-borrow.rs new file mode 100644 index 000000000000..7088b4c3ec9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/slice-borrow.rs @@ -0,0 +1,15 @@ +// Test slicing expressions doesn't defeat the borrow checker. + +fn main() { + let y; + { + let x: &[isize] = &vec![1, 2, 3, 4, 5]; +// { dg-error ".E0716." "" { target *-*-* } .-1 } + y = &x[1..]; + } + y.use_ref(); +} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/span/suggestion-non-ascii.rs b/gcc/testsuite/rust/rustc/ui/span/suggestion-non-ascii.rs new file mode 100644 index 000000000000..7f402af6b3b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/suggestion-non-ascii.rs @@ -0,0 +1,5 @@ +fn main() { + let tup = (1,); + println!("☃{}", tup[0]); // { dg-error ".E0608." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/transitive-dep-span.rs b/gcc/testsuite/rust/rustc/ui/span/transitive-dep-span.rs new file mode 100644 index 000000000000..edb8a50e4dd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/transitive-dep-span.rs @@ -0,0 +1,16 @@ +// Tests that we properly serialize/deserialize spans from transitive dependencies +// (e.g. imported SourceFiles) +// +// The order of these next lines is important, since we need +// transitive_dep_two.rs to be able to reference transitive_dep_three.rs +// +// aux-build: transitive_dep_three.rs +// aux-build: transitive_dep_two.rs +// compile-flags: -Z macro-backtrace + +extern crate transitive_dep_two; + +transitive_dep_two::parse_error!(); // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/type-annotations-needed-expr.rs b/gcc/testsuite/rust/rustc/ui/span/type-annotations-needed-expr.rs new file mode 100644 index 000000000000..a3fb7070fb10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/type-annotations-needed-expr.rs @@ -0,0 +1,4 @@ +fn main() { + let _ = (vec![1,2,3]).into_iter().sum() as f64; // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/type-binding.rs b/gcc/testsuite/rust/rustc/ui/span/type-binding.rs new file mode 100644 index 000000000000..20abf6515316 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/type-binding.rs @@ -0,0 +1,10 @@ +// Regression test for issue #28158 +// Test the type binding span doesn't include >> + +use std::ops::Deref; + +fn homura>(_: T) {} +// { dg-error ".E0220." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/typo-suggestion.rs b/gcc/testsuite/rust/rustc/ui/span/typo-suggestion.rs new file mode 100644 index 000000000000..7ffcd47aae64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/typo-suggestion.rs @@ -0,0 +1,10 @@ +fn main() { + let foo = 1; + + // `foo` shouldn't be suggested, it is too dissimilar from `bar`. + println!("Hello {}", bar); // { dg-error ".E0425." "" { target *-*-* } } + + // But this is close enough. + println!("Hello {}", fob); // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/unused-warning-point-at-identifier.rs b/gcc/testsuite/rust/rustc/ui/span/unused-warning-point-at-identifier.rs new file mode 100644 index 000000000000..f424d1f08c4d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/unused-warning-point-at-identifier.rs @@ -0,0 +1,31 @@ +// run-pass + +#![warn(unused)] + +enum Enum { // { dg-warning "" "" { target *-*-* } } + A, + B, + C, + D, +} + +struct Struct { // { dg-warning "" "" { target *-*-* } } + a: usize, + b: usize, + c: usize, + d: usize, +} + +fn func() -> usize { // { dg-warning "" "" { target *-*-* } } + 3 +} + +fn +func_complete_span() // { dg-warning "" "" { target *-*-* } } +-> usize +{ + 3 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/vec-must-not-hide-type-from-dropck.rs b/gcc/testsuite/rust/rustc/ui/span/vec-must-not-hide-type-from-dropck.rs new file mode 100644 index 000000000000..514bb47c8411 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/vec-must-not-hide-type-from-dropck.rs @@ -0,0 +1,126 @@ +// Checking that `Vec` cannot hide lifetimes within `T` when `T` +// implements `Drop` and might access methods of values that have +// since been deallocated. +// +// In this case, the values in question hold (non-zero) unique-ids +// that zero themselves out when dropped, and are wrapped in another +// type with a destructor that asserts that the ids it references are +// indeed non-zero (i.e., effectively checking that the id's are not +// dropped while there are still any outstanding references). +// +// However, the values in question are also formed into a +// cyclic-structure, ensuring that there is no way for all of the +// conditions above to be satisfied, meaning that if the dropck is +// sound, it should reject this code. + + + +use std::cell::Cell; +use id::Id; + +mod s { + use std::sync::atomic::{AtomicUsize, Ordering}; + + static S_COUNT: AtomicUsize = AtomicUsize::new(0); + + /// generates globally unique count (global across the current + /// process, that is) + pub fn next_count() -> usize { + S_COUNT.fetch_add(1, Ordering::SeqCst) + 1 + } +} + +mod id { + use s; + + /// Id represents a globally unique identifier (global across the + /// current process, that is). When dropped, it automatically + /// clears its `count` field, but leaves `orig_count` untouched, + /// so that if there are subsequent (erroneous) invocations of its + /// method (which is unsound), we can observe it by seeing that + /// the `count` is 0 while the `orig_count` is non-zero. + #[derive(Debug)] + pub struct Id { + orig_count: usize, + count: usize, + } + + impl Id { + /// Creates an `Id` with a globally unique count. + pub fn new() -> Id { + let c = s::next_count(); + println!("building Id {}", c); + Id { orig_count: c, count: c } + } + /// returns the `count` of self; should be non-zero if + /// everything is working. + pub fn count(&self) -> usize { + println!("Id::count on {} returns {}", self.orig_count, self.count); + self.count + } + } + + impl Drop for Id { + fn drop(&mut self) { + println!("dropping Id {}", self.count); + self.count = 0; + } + } +} + +trait HasId { + fn count(&self) -> usize; +} + +#[derive(Debug)] +struct CheckId { + v: T +} + +#[allow(non_snake_case)] +fn CheckId(t: T) -> CheckId { CheckId{ v: t } } + +impl Drop for CheckId { + fn drop(&mut self) { + assert!(self.v.count() > 0); + } +} + +#[derive(Debug)] +struct C<'a> { + id: Id, + v: Vec>>>>, +} + +impl<'a> HasId for Cell>> { + fn count(&self) -> usize { + match self.get() { + None => 1, + Some(c) => c.id.count(), + } + } +} + +impl<'a> C<'a> { + fn new() -> C<'a> { + C { id: Id::new(), v: Vec::new() } + } +} + +fn f() { + let (mut c1, mut c2); + c1 = C::new(); + c2 = C::new(); + + c1.v.push(CheckId(Cell::new(None))); + c2.v.push(CheckId(Cell::new(None))); + c1.v[0].v.set(Some(&c2)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + c2.v[0].v.set(Some(&c1)); +// { dg-error ".E0597." "" { target *-*-* } .-1 } +} + +fn main() { + f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/vec_refs_data_with_early_death.rs b/gcc/testsuite/rust/rustc/ui/span/vec_refs_data_with_early_death.rs new file mode 100644 index 000000000000..00201ba57f53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/vec_refs_data_with_early_death.rs @@ -0,0 +1,34 @@ +// This test is a simple example of code that violates the dropck +// rules: it pushes `&x` and `&y` into a bag (with dtor), but the +// referenced data will be dropped before the bag is. + + + + + + + +fn main() { + let mut v = Bag::new(); + + let x: i8 = 3; + let y: i8 = 4; + + v.push(&x); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + v.push(&y); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + + assert_eq!(v.0, [&3, &4]); +} + +//`Vec` is #[may_dangle] w.r.t. `T`; putting a bag over its head +// forces borrowck to treat dropping the bag as a potential use. +struct Bag(Vec); +impl Drop for Bag { fn drop(&mut self) { } } + +impl Bag { + fn new() -> Self { Bag(Vec::new()) } + fn push(&mut self, t: T) { self.0.push(t); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/span/visibility-ty-params.rs b/gcc/testsuite/rust/rustc/ui/span/visibility-ty-params.rs new file mode 100644 index 000000000000..6b319bb81396 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/visibility-ty-params.rs @@ -0,0 +1,14 @@ +macro_rules! m { + ($p: path) => (pub(in $p) struct Z;) +} + +struct S(T); +m!{ S } // { dg-error ".E0577." "" { target *-*-* } } +// { dg-error ".E0577." "" { target *-*-* } .-2 } + +mod m { + m!{ m<> } // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/span/wf-method-late-bound-regions.rs b/gcc/testsuite/rust/rustc/ui/span/wf-method-late-bound-regions.rs new file mode 100644 index 000000000000..bf36d9b98c6a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/span/wf-method-late-bound-regions.rs @@ -0,0 +1,25 @@ +// A method's receiver must be well-formed, even if it has late-bound regions. +// Because of this, a method's substs being well-formed does not imply that +// the method's implied bounds are met. + +struct Foo<'b>(Option<&'b ()>); + +trait Bar<'b> { + fn xmute<'a>(&'a self, u: &'b u32) -> &'a u32; +} + +impl<'b> Bar<'b> for Foo<'b> { + fn xmute<'a>(&'a self, u: &'b u32) -> &'a u32 { u } +} + +fn main() { + let f = Foo(None); + let f2 = f; + let dangling = { + let pointer = Box::new(42); + f2.xmute(&pointer) + }; +// { dg-error ".E0597." "" { target *-*-* } .-2 } + println!("{}", dangling); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/assoc-ty-graph-cycle.rs b/gcc/testsuite/rust/rustc/ui/specialization/assoc-ty-graph-cycle.rs new file mode 100644 index 000000000000..d9352cc012c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/assoc-ty-graph-cycle.rs @@ -0,0 +1,26 @@ +// run-pass + +// Make sure we don't crash with a cycle error during coherence. + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Trait { + type Assoc; +} + +impl Trait for Vec { + default type Assoc = (); +} + +impl Trait for Vec { + type Assoc = u8; +} + +impl Trait for String { + type Assoc = (); +} + +impl Trait< as Trait>::Assoc> for String {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/auxiliary/cross_crates_defaults.rs b/gcc/testsuite/rust/rustc/ui/specialization/auxiliary/cross_crates_defaults.rs new file mode 100644 index 000000000000..07f620781eea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/auxiliary/cross_crates_defaults.rs @@ -0,0 +1,41 @@ +#![feature(specialization)] + +// First, test only use of explicit `default` items: + +pub trait Foo { + fn foo(&self) -> bool; +} + +impl Foo for T { + default fn foo(&self) -> bool { false } +} + +impl Foo for i32 {} + +impl Foo for i64 { + fn foo(&self) -> bool { true } +} + +// Next, test mixture of explicit `default` and provided methods: + +pub trait Bar { + fn bar(&self) -> i32 { 0 } +} + +impl Bar for T { + default fn bar(&self) -> i32 { 0 } +} + +impl Bar for i32 { + fn bar(&self) -> i32 { 1 } +} +impl<'a> Bar for &'a str {} + +impl Bar for Vec { + default fn bar(&self) -> i32 { 2 } +} +impl Bar for Vec {} +impl Bar for Vec { + fn bar(&self) -> i32 { 3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/auxiliary/go_trait.rs b/gcc/testsuite/rust/rustc/ui/specialization/auxiliary/go_trait.rs new file mode 100644 index 000000000000..fa6463468673 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/auxiliary/go_trait.rs @@ -0,0 +1,44 @@ +#![feature(specialization)] + +// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy. + +pub trait Go { + fn go(&self, arg: isize); +} + +pub fn go(this: &G, arg: isize) { + this.go(arg) +} + +pub trait GoMut { + fn go_mut(&mut self, arg: isize); +} + +pub fn go_mut(this: &mut G, arg: isize) { + this.go_mut(arg) +} + +pub trait GoOnce { + fn go_once(self, arg: isize); +} + +pub fn go_once(this: G, arg: isize) { + this.go_once(arg) +} + +impl GoMut for G + where G : Go +{ + default fn go_mut(&mut self, arg: isize) { + go(&*self, arg) + } +} + +impl GoOnce for G + where G : GoMut +{ + default fn go_once(mut self, arg: isize) { + go_mut(&mut self, arg) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/auxiliary/specialization_cross_crate.rs b/gcc/testsuite/rust/rustc/ui/specialization/auxiliary/specialization_cross_crate.rs new file mode 100644 index 000000000000..e25e10e5c64e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/auxiliary/specialization_cross_crate.rs @@ -0,0 +1,73 @@ +#![feature(specialization)] + +pub trait Foo { + fn foo(&self) -> &'static str; +} + +impl Foo for T { + default fn foo(&self) -> &'static str { + "generic" + } +} + +impl Foo for T { + default fn foo(&self) -> &'static str { + "generic Clone" + } +} + +impl Foo for (T, U) where T: Clone, U: Clone { + default fn foo(&self) -> &'static str { + "generic pair" + } +} + +impl Foo for (T, T) { + default fn foo(&self) -> &'static str { + "generic uniform pair" + } +} + +impl Foo for (u8, u32) { + default fn foo(&self) -> &'static str { + "(u8, u32)" + } +} + +impl Foo for (u8, u8) { + default fn foo(&self) -> &'static str { + "(u8, u8)" + } +} + +impl Foo for Vec { + default fn foo(&self) -> &'static str { + "generic Vec" + } +} + +impl Foo for Vec { + fn foo(&self) -> &'static str { + "Vec" + } +} + +impl Foo for String { + fn foo(&self) -> &'static str { + "String" + } +} + +impl Foo for i32 { + fn foo(&self) -> &'static str { + "i32" + } +} + +pub trait MyMarker {} +impl Foo for T { + default fn foo(&self) -> &'static str { + "generic Clone + MyMarker" + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/cross-crate-defaults.rs b/gcc/testsuite/rust/rustc/ui/specialization/cross-crate-defaults.rs new file mode 100644 index 000000000000..2344c22c8cc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/cross-crate-defaults.rs @@ -0,0 +1,42 @@ +// run-pass + +// aux-build:cross_crates_defaults.rs + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +extern crate cross_crates_defaults; + +use cross_crates_defaults::*; + +struct LocalDefault; +struct LocalOverride; + +impl Foo for LocalDefault {} + +impl Foo for LocalOverride { + fn foo(&self) -> bool { true } +} + +fn test_foo() { + assert!(!0i8.foo()); + assert!(!0i32.foo()); + assert!(0i64.foo()); + + assert!(!LocalDefault.foo()); + assert!(LocalOverride.foo()); +} + +fn test_bar() { + assert!(0u8.bar() == 0); + assert!(0i32.bar() == 1); + assert!("hello".bar() == 0); + assert!(vec![()].bar() == 2); + assert!(vec![0i32].bar() == 2); + assert!(vec![0i64].bar() == 3); +} + +fn main() { + test_foo(); + test_bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/deafult-associated-type-bound-1.rs b/gcc/testsuite/rust/rustc/ui/specialization/deafult-associated-type-bound-1.rs new file mode 100644 index 000000000000..fc525ace3e59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/deafult-associated-type-bound-1.rs @@ -0,0 +1,26 @@ +// Check that we check that default associated types satisfy the required +// bounds on them. +// ignore-compare-mode-chalk + +#![feature(specialization)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait X { + type U: Clone; + fn unsafe_clone(&self, x: Option<&Self::U>) { + x.cloned(); + } +} + +// We cannot normalize `::U` to `str` here, because the default could +// be overridden. The error here must therefore be found by a method other than +// normalization. +impl X for T { + default type U = str; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +pub fn main() { + 1.unsafe_clone(None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/deafult-associated-type-bound-2.rs b/gcc/testsuite/rust/rustc/ui/specialization/deafult-associated-type-bound-2.rs new file mode 100644 index 000000000000..0c5ca6d1118b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/deafult-associated-type-bound-2.rs @@ -0,0 +1,23 @@ +// Check that generic predicates are also checked for default associated types. +#![feature(specialization)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait X { + type U: PartialEq; + fn unsafe_compare(x: Option, y: Option) { + match (x, y) { + (Some(a), Some(b)) => a == b, + _ => false, + }; + } +} + +impl X for T { + default type U = &'static B; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +pub fn main() { + >::unsafe_compare(None, None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/deafult-generic-associated-type-bound.rs b/gcc/testsuite/rust/rustc/ui/specialization/deafult-generic-associated-type-bound.rs new file mode 100644 index 000000000000..39709bc61fa9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/deafult-generic-associated-type-bound.rs @@ -0,0 +1,28 @@ +// Check that default generics associated types are validated. + +#![feature(specialization)] +#![feature(generic_associated_types)] +// { dg-warning "" "" { target *-*-* } .-2 } +// { dg-warning "" "" { target *-*-* } .-2 } + +trait X { + type U<'a>: PartialEq<&'a Self> where Self: 'a; + fn unsafe_compare<'b>(x: Option>, y: Option<&'b Self>) { + match (x, y) { + (Some(a), Some(b)) => a == b, + _ => false, + }; + } +} + +impl X for T { + default type U<'a> = &'a T; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +struct NotComparable; + +pub fn main() { + ::unsafe_compare(None, None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/allowed-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/allowed-cross-crate.rs new file mode 100644 index 000000000000..d1bdd0bc058a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/allowed-cross-crate.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_imports)] + +// aux-build:go_trait.rs + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +extern crate go_trait; + +use go_trait::{Go,GoMut}; +use std::fmt::Debug; +use std::default::Default; + +struct MyThingy; + +impl Go for MyThingy { + fn go(&self, arg: isize) { } +} + +impl GoMut for MyThingy { + fn go_mut(&mut self, arg: isize) { } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/auxiliary/go_trait.rs b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/auxiliary/go_trait.rs new file mode 100644 index 000000000000..9dc1dd46b4c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/auxiliary/go_trait.rs @@ -0,0 +1,44 @@ +#![feature(specialization)] + +// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy. + +pub trait Go { + fn go(&self, arg: isize); +} + +pub fn go(this: &G, arg: isize) { + this.go(arg) +} + +pub trait GoMut { + fn go_mut(&mut self, arg: isize); +} + +pub fn go_mut(this: &mut G, arg: isize) { + this.go_mut(arg) +} + +pub trait GoOnce { + fn go_once(self, arg: isize); +} + +pub fn go_once(this: G, arg: isize) { + this.go_once(arg) +} + +default impl GoMut for G + where G : Go +{ + fn go_mut(&mut self, arg: isize) { + go(&*self, arg) + } +} + +default impl GoOnce for G + where G : GoMut +{ + fn go_once(mut self, arg: isize) { + go_mut(&mut self, arg) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/out-of-order.rs b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/out-of-order.rs new file mode 100644 index 000000000000..9b36f70977b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/out-of-order.rs @@ -0,0 +1,20 @@ +// run-pass + +// Test that you can list the more specific impl before the more general one. + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Foo { + type Out; +} + +impl Foo for bool { + type Out = (); +} + +default impl Foo for T { + type Out = bool; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/overlap-projection.rs b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/overlap-projection.rs new file mode 100644 index 000000000000..86c7adc6c39c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/overlap-projection.rs @@ -0,0 +1,26 @@ +// run-pass + +// Test that impls on projected self types can resolve overlap, even when the +// projections involve specialization, so long as the associated type is +// provided by the most specialized impl. + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Assoc { + type Output; +} + +default impl Assoc for T { + type Output = bool; +} + +impl Assoc for u8 { type Output = u8; } +impl Assoc for u16 { type Output = u16; } + +trait Foo {} +impl Foo for u32 {} +impl Foo for ::Output {} +impl Foo for ::Output {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/projection.rs b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/projection.rs new file mode 100644 index 000000000000..ac2289de0134 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/projection.rs @@ -0,0 +1,43 @@ +// run-pass +#![allow(dead_code)] + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// Make sure we *can* project non-defaulted associated types +// cf compile-fail/specialization-default-projection.rs + +// First, do so without any use of specialization + +trait Foo { + type Assoc; +} + +impl Foo for T { + type Assoc = (); +} + +fn generic_foo() -> ::Assoc { + () +} + +// Next, allow for one layer of specialization + +trait Bar { + type Assoc; +} + +default impl Bar for T { + type Assoc = (); +} + +impl Bar for T { + type Assoc = u8; +} + +fn generic_bar_clone() -> ::Assoc { + 0u8 +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-feature-gate-default.rs b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-feature-gate-default.rs new file mode 100644 index 000000000000..a1ae7175706b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-feature-gate-default.rs @@ -0,0 +1,12 @@ +// Check that specialization must be ungated to use the `default` keyword + +trait Foo { + fn foo(&self); +} + +default impl Foo for T { // { dg-error ".E0658." "" { target *-*-* } } + fn foo(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-no-default.rs b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-no-default.rs new file mode 100644 index 000000000000..7315dd70a39c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-no-default.rs @@ -0,0 +1,78 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// Check a number of scenarios in which one impl tries to override another, +// without correctly using `default`. + +// Test 1: one layer of specialization, multiple methods, missing `default` + +trait Foo { + fn foo(&self); + fn bar(&self); +} + +impl Foo for T { + fn foo(&self) {} + fn bar(&self) {} +} + +impl Foo for u8 {} +impl Foo for u16 { + fn foo(&self) {} // { dg-error ".E0520." "" { target *-*-* } } +} +impl Foo for u32 { + fn bar(&self) {} // { dg-error ".E0520." "" { target *-*-* } } +} + +// Test 2: one layer of specialization, missing `default` on associated type + +trait Bar { + type T; +} + +impl Bar for T { + type T = u8; +} + +impl Bar for u8 { + type T = (); // { dg-error ".E0520." "" { target *-*-* } } +} + +// Test 3a: multiple layers of specialization, missing interior `default` + +trait Baz { + fn baz(&self); +} + +default impl Baz for T { + fn baz(&self) {} +} + +impl Baz for T { + fn baz(&self) {} +} + +impl Baz for i32 { + fn baz(&self) {} // { dg-error ".E0520." "" { target *-*-* } } +} + +// Test 3b: multiple layers of specialization, missing interior `default`, +// redundant `default` in bottom layer. + +trait Redundant { + fn redundant(&self); +} + +default impl Redundant for T { + fn redundant(&self) {} +} + +impl Redundant for T { + fn redundant(&self) {} +} + +default impl Redundant for i32 { + fn redundant(&self) {} // { dg-error ".E0520." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs new file mode 100644 index 000000000000..57ff2efeb5b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.rs @@ -0,0 +1,35 @@ +// run-pass + +// Tests that we can combine a default impl that supplies one method with a +// full impl that supplies the other, and they can invoke one another. + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Foo { + fn foo_one(&self) -> &'static str; + fn foo_two(&self) -> &'static str; + fn foo_three(&self) -> &'static str; +} + +struct MyStruct; + +default impl Foo for T { + fn foo_one(&self) -> &'static str { + self.foo_three() + } +} + +impl Foo for MyStruct { + fn foo_two(&self) -> &'static str { + self.foo_one() + } + + fn foo_three(&self) -> &'static str { + "generic" + } +} + +fn main() { + assert!(MyStruct.foo_two() == "generic"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs new file mode 100644 index 000000000000..09a995ca31d6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.rs @@ -0,0 +1,24 @@ +// Tests that default impls do not have to supply all items but regular impls do. + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Foo { + fn foo_one(&self) -> &'static str; + fn foo_two(&self) -> &'static str; +} + +struct MyStruct; + +default impl Foo for T { + fn foo_one(&self) -> &'static str { + "generic" + } +} + +impl Foo for MyStruct {} +// { dg-error ".E0046." "" { target *-*-* } .-1 } + +fn main() { + println!("{}", MyStruct.foo_one()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs new file mode 100644 index 000000000000..492102992478 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-trait-not-implemented.rs @@ -0,0 +1,25 @@ +// Tests that: +// - default impls do not have to supply all items and +// - a default impl does not count as an impl (in this case, an incomplete default impl). + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Foo { + fn foo_one(&self) -> &'static str; + fn foo_two(&self) -> &'static str; +} + +struct MyStruct; + +default impl Foo for T { + fn foo_one(&self) -> &'static str { + "generic" + } +} + + +fn main() { + println!("{}", MyStruct.foo_one()); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-wfcheck.rs b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-wfcheck.rs new file mode 100644 index 000000000000..da5a13a11058 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/specialization-wfcheck.rs @@ -0,0 +1,11 @@ +// Tests that a default impl still has to have a WF trait ref. + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Foo<'a, T: Eq + 'a> { } + +default impl Foo<'static, U> for () {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/validation.rs b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/validation.rs new file mode 100644 index 000000000000..944b21bd2a89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/defaultimpl/validation.rs @@ -0,0 +1,17 @@ +#![feature(negative_impls)] +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +struct S; +struct Z; + +default impl S {} // { dg-error "" "" { target *-*-* } } + +default unsafe impl Send for S {} // { dg-error "" "" { target *-*-* } } +default impl !Send for Z {} // { dg-error ".E0750." "" { target *-*-* } } +// { dg-error ".E0750." "" { target *-*-* } .-1 } + +trait Tr {} +default impl !Tr for S {} // { dg-error ".E0750." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/issue-36804.rs b/gcc/testsuite/rust/rustc/ui/specialization/issue-36804.rs new file mode 100644 index 000000000000..fe907b277b8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/issue-36804.rs @@ -0,0 +1,36 @@ +// check-pass +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +pub struct Cloned(I); + +impl<'a, I, T: 'a> Iterator for Cloned +where + I: Iterator, + T: Clone, +{ + type Item = T; + + fn next(&mut self) -> Option { + unimplemented!() + } + + default fn count(self) -> usize where Self: Sized { + self.fold(0, |cnt, _| cnt + 1) + } +} + +impl<'a, I, T: 'a> Iterator for Cloned +where + I: Iterator, + T: Copy, +{ + fn count(self) -> usize { + unimplemented!() + } +} + +fn main() { + let a = [1,2,3,4]; + Cloned(a.iter()).count(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/issue-38091-2.rs b/gcc/testsuite/rust/rustc/ui/specialization/issue-38091-2.rs new file mode 100644 index 000000000000..2b4b0bb7b8e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/issue-38091-2.rs @@ -0,0 +1,29 @@ +// build-fail +// { dg-error "" "" { target *-*-* } .-1 } + +#![feature(specialization)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait Iterate<'a> { + type Ty: Valid; + fn iterate(self); +} +impl<'a, T> Iterate<'a> for T +where + T: Check, +{ + default type Ty = (); + default fn iterate(self) {} +} + +trait Check {} +impl<'a, T> Check for T where >::Ty: Valid {} + +trait Valid {} + +impl Valid for () {} + +fn main() { + Iterate::iterate(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/issue-38091.rs b/gcc/testsuite/rust/rustc/ui/specialization/issue-38091.rs new file mode 100644 index 000000000000..5a9f3e08496d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/issue-38091.rs @@ -0,0 +1,25 @@ +#![feature(specialization)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait Iterate<'a> { + type Ty: Valid; + fn iterate(self); +} +impl<'a, T> Iterate<'a> for T +where + T: Check, +{ + default type Ty = (); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + default fn iterate(self) {} +} + +trait Check {} +impl<'a, T> Check for T where >::Ty: Valid {} + +trait Valid {} + +fn main() { + Iterate::iterate(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/issue-39448.rs b/gcc/testsuite/rust/rustc/ui/specialization/issue-39448.rs new file mode 100644 index 000000000000..d2764501663d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/issue-39448.rs @@ -0,0 +1,51 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// Regression test for a specialization-related ICE (#39448). + +trait A: Sized { + fn foo(self, _: Self) -> Self { + self + } +} + +impl A for u8 {} +impl A for u16 {} + +impl FromA for u16 { + fn from(x: u8) -> u16 { + x as u16 + } +} + +trait FromA { + fn from(T) -> Self; +} + +impl> FromA for U { + default fn from(x: T) -> Self { + ToA::to(x) + } +} + +trait ToA { + fn to(self) -> T; +} + +impl ToA for T +where + U: FromA, +{ + fn to(self) -> U { + U::from(self) + } +} + +#[allow(dead_code)] +fn foo(x: T, y: U) -> U { + x.foo(y.to()).to() // { dg-error ".E0275." "" { target *-*-* } } +} + +fn main() { + let z = foo(8u8, 1u16); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/issue-39618.rs b/gcc/testsuite/rust/rustc/ui/specialization/issue-39618.rs new file mode 100644 index 000000000000..a3f515aa7a91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/issue-39618.rs @@ -0,0 +1,28 @@ +// Regression test for #39618, shouldn't crash. +// FIXME(JohnTitor): Centril pointed out this looks suspicions, we should revisit here. +// More context: https://github.com/rust-lang/rust/pull/69192#discussion_r379846796 + +// check-pass + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Foo { + fn foo(&self); +} + +trait Bar { + fn bar(&self); +} + +impl Bar for T where T: Foo { + fn bar(&self) {} +} + +impl Foo for T where T: Bar { + fn foo(&self) {} +} + +impl Foo for u64 {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/issue-44861.rs b/gcc/testsuite/rust/rustc/ui/specialization/issue-44861.rs new file mode 100644 index 000000000000..dde4ced1e374 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/issue-44861.rs @@ -0,0 +1,41 @@ +#![crate_type = "lib"] +#![feature(specialization)] +#![feature(unsize, coerce_unsized)] +#![allow(incomplete_features)] + +use std::ops::CoerceUnsized; + +pub struct SmartassPtr(A::Data); + +pub trait Smartass { + type Data; + type Data2: CoerceUnsized<*const [u8]>; +} + +pub trait MaybeObjectSafe {} + +impl MaybeObjectSafe for () {} + +impl Smartass for T { + type Data = ::Data2; + default type Data2 = (); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +impl Smartass for () { + type Data2 = *const [u8; 1]; +} + +impl Smartass for dyn MaybeObjectSafe { + type Data = *const [u8]; + type Data2 = *const [u8; 0]; +} + +impl CoerceUnsized> for SmartassPtr + where ::Data: std::ops::CoerceUnsized<::Data> +{} + +pub fn conv(s: SmartassPtr<()>) -> SmartassPtr { + s +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/issue-50452.rs b/gcc/testsuite/rust/rustc/ui/specialization/issue-50452.rs new file mode 100644 index 000000000000..03bc4658b502 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/issue-50452.rs @@ -0,0 +1,20 @@ +// run-pass + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +pub trait Foo { + fn foo(); +} + +impl Foo for i32 {} +impl Foo for i64 {} +impl Foo for T { + fn foo() {} +} + +fn main() { + i32::foo(); + i64::foo(); + u8::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/issue-52050.rs b/gcc/testsuite/rust/rustc/ui/specialization/issue-52050.rs new file mode 100644 index 000000000000..7d78ddedfdeb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/issue-52050.rs @@ -0,0 +1,33 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// Regression test for #52050: when inserting the blanket impl `I` +// into the tree, we had to replace the child node for `Foo`, which +// led to the structure of the tree being messed up. + +use std::iter::Iterator; + +trait IntoPyDictPointer { } + +struct Foo { } + +impl Iterator for Foo { + type Item = (); + fn next(&mut self) -> Option<()> { + None + } +} + +impl IntoPyDictPointer for Foo { } + +impl IntoPyDictPointer for I +where + I: Iterator, +{ +} + +impl IntoPyDictPointer for () // { dg-error ".E0119." "" { target *-*-* } } +{ +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/issue-59435.rs b/gcc/testsuite/rust/rustc/ui/specialization/issue-59435.rs new file mode 100644 index 000000000000..c6e9234db9f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/issue-59435.rs @@ -0,0 +1,18 @@ +#![feature(specialization)] +#![allow(incomplete_features)] + +struct MyStruct {} + +trait MyTrait { + type MyType: Default; +} + +impl MyTrait for i32 { + default type MyType = MyStruct; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { + let _x: ::MyType = ::MyType::default(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/issue-63716-parse-async.rs b/gcc/testsuite/rust/rustc/ui/specialization/issue-63716-parse-async.rs new file mode 100644 index 000000000000..d2525264122d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/issue-63716-parse-async.rs @@ -0,0 +1,15 @@ +// Ensure that `default async fn` will parse. +// See issue #63716 for details. + +// check-pass +// edition:2018 + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +fn main() {} + +#[cfg(FALSE)] +impl Foo for Bar { + default async fn baz() {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/issue-70442.rs b/gcc/testsuite/rust/rustc/ui/specialization/issue-70442.rs new file mode 100644 index 000000000000..153d3f794680 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/issue-70442.rs @@ -0,0 +1,24 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// check-pass + +trait Trait { + type Assoc; +} + +impl Trait for T { + default type Assoc = bool; +} + +// This impl inherits the `Assoc` definition from above and "locks it in", or finalizes it, making +// child impls unable to further specialize it. However, since the specialization graph didn't +// correctly track this, we would refuse to project `Assoc` from this impl, even though that should +// happen for items that are final. +impl Trait for () {} + +fn foo>() {} + +fn main() { + foo::<()>(); // `<() as Trait>::Assoc` is normalized to `bool` correctly +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/auxiliary/specialization-trait.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/auxiliary/specialization-trait.rs new file mode 100644 index 000000000000..04aa4edc9a9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/auxiliary/specialization-trait.rs @@ -0,0 +1,7 @@ +#![feature(rustc_attrs)] + +#[rustc_specialization_trait] +pub trait SpecTrait { + fn method(&self); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/dyn-trait-assoc-types.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/dyn-trait-assoc-types.rs new file mode 100644 index 000000000000..37528428e7d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/dyn-trait-assoc-types.rs @@ -0,0 +1,33 @@ +// Test that associated types in trait objects are not considered to be +// constrained. + +#![feature(min_specialization)] + +trait Specializable { + fn f(); +} + +trait B { + type Y; +} + +trait C { + type Y; +} + +impl Specializable for A { + default fn f() {} +} + +impl<'a, T> Specializable for dyn B + 'a { +// { dg-error "" "" { target *-*-* } .-1 } + fn f() {} +} + +impl<'a, T> Specializable for dyn C + 'a { +// { dg-error "" "" { target *-*-* } .-1 } + fn f() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/impl-on-nonexisting.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/impl-on-nonexisting.rs new file mode 100644 index 000000000000..c22345b83242 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/impl-on-nonexisting.rs @@ -0,0 +1,8 @@ +#![feature(min_specialization)] + +trait Trait {} +impl Trait for NonExistent {} +// { dg-error ".E0412." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/impl_specialization_trait.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/impl_specialization_trait.rs new file mode 100644 index 000000000000..0cc88ed2ca30 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/impl_specialization_trait.rs @@ -0,0 +1,17 @@ +// Check that specialization traits can't be implemented without a feature. + +// gate-test-min_specialization + +// aux-build:specialization-trait.rs + +extern crate specialization_trait; + +struct A {} + +impl specialization_trait::SpecTrait for A { +// { dg-error "" "" { target *-*-* } .-1 } + fn method(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/implcit-well-formed-bounds.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/implcit-well-formed-bounds.rs new file mode 100644 index 000000000000..0520a5b5e7ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/implcit-well-formed-bounds.rs @@ -0,0 +1,31 @@ +// Test that specializing on the well-formed predicates of the trait and +// self-type of an impl is allowed. + +// check-pass + +#![feature(min_specialization)] + +struct OrdOnly(T); + +trait SpecTrait { + fn f(); +} + +impl SpecTrait for T { + default fn f() {} +} + +impl SpecTrait<()> for OrdOnly { + fn f() {} +} + +impl SpecTrait> for () { + fn f() {} +} + +impl SpecTrait<(OrdOnly, OrdOnly)> for &[OrdOnly] { + fn f() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/repeated_projection_type.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/repeated_projection_type.rs new file mode 100644 index 000000000000..1c8ad7337bc4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/repeated_projection_type.rs @@ -0,0 +1,25 @@ +// Test that projection bounds can't be specialized on. + +#![feature(min_specialization)] + +trait X { + fn f(); +} +trait Id { + type This; +} +impl Id for T { + type This = T; +} + +impl X for T { + default fn f() {} +} + +impl> X for V { +// { dg-error "" "" { target *-*-* } .-1 } + fn f() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/repeating_lifetimes.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/repeating_lifetimes.rs new file mode 100644 index 000000000000..2726d5d55ffe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/repeating_lifetimes.rs @@ -0,0 +1,20 @@ +// Test that directly specializing on repeated lifetime parameters is not +// allowed. + +#![feature(min_specialization)] + +trait X { + fn f(); +} + +impl X for T { + default fn f() {} +} + +impl<'a> X for (&'a u8, &'a u8) { +// { dg-error "" "" { target *-*-* } .-1 } + fn f() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/repeating_param.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/repeating_param.rs new file mode 100644 index 000000000000..567b5c92cd85 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/repeating_param.rs @@ -0,0 +1,18 @@ +// Test that specializing on two type parameters being equal is not allowed. + +#![feature(min_specialization)] + +trait X { + fn f(); +} + +impl X for T { + default fn f() {} +} +impl X for (T, T) { +// { dg-error "" "" { target *-*-* } .-1 } + fn f() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/spec-iter.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/spec-iter.rs new file mode 100644 index 000000000000..05e6325c7e3b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/spec-iter.rs @@ -0,0 +1,21 @@ +// Check that we can specialize on a concrete iterator type. This requires us +// to consider which parameters in the parent impl are constrained. + +// check-pass + +#![feature(min_specialization)] + +trait SpecFromIter { + fn f(&self); +} + +impl<'a, T: 'a, I: Iterator> SpecFromIter for I { + default fn f(&self) {} +} + +impl<'a, T> SpecFromIter for std::slice::Iter<'a, T> { + fn f(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/spec-reference.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/spec-reference.rs new file mode 100644 index 000000000000..dfe100e34154 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/spec-reference.rs @@ -0,0 +1,20 @@ +// Check that lifetime parameters are allowed in specializing impls. + +// check-pass + +#![feature(min_specialization)] + +trait MySpecTrait { + fn f(); +} + +impl MySpecTrait for T { + default fn f() {} +} + +impl<'a, T: ?Sized> MySpecTrait for &'a T { + fn f() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialization_marker.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialization_marker.rs new file mode 100644 index 000000000000..4ca814c12861 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialization_marker.rs @@ -0,0 +1,18 @@ +// Test that `rustc_unsafe_specialization_marker` is only allowed on marker traits. + +#![feature(rustc_attrs)] + +#[rustc_unsafe_specialization_marker] +trait SpecMarker { + fn f(); +// { dg-error ".E0714." "" { target *-*-* } .-1 } +} + +#[rustc_unsafe_specialization_marker] +trait SpecMarker2 { + type X; +// { dg-error ".E0714." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialization_super_trait.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialization_super_trait.rs new file mode 100644 index 000000000000..d16a82b8fa71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialization_super_trait.rs @@ -0,0 +1,19 @@ +// Test that supertraits can't be assumed in impls of +// `rustc_specialization_trait`, as such impls would +// allow specializing on the supertrait. + +#![feature(min_specialization)] +#![feature(rustc_attrs)] + +#[rustc_specialization_trait] +trait SpecMarker: Default { + fn f(); +} + +impl SpecMarker for T { +// { dg-error "" "" { target *-*-* } .-1 } + fn f() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialization_trait.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialization_trait.rs new file mode 100644 index 000000000000..8110d1a645ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialization_trait.rs @@ -0,0 +1,27 @@ +// Test that `rustc_specialization_trait` requires always applicable impls. + +#![feature(min_specialization)] +#![feature(rustc_attrs)] + +#[rustc_specialization_trait] +trait SpecMarker { + fn f(); +} + +impl SpecMarker for &'static u8 { +// { dg-error "" "" { target *-*-* } .-1 } + fn f() {} +} + +impl SpecMarker for (T, T) { +// { dg-error "" "" { target *-*-* } .-1 } + fn f() {} +} + +impl SpecMarker for [T] { +// { dg-error "" "" { target *-*-* } .-1 } + fn f() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_marker.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_marker.rs new file mode 100644 index 000000000000..e7c1dfacce0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_marker.rs @@ -0,0 +1,25 @@ +// Test that specializing on a `rustc_unsafe_specialization_marker` trait is +// allowed. + +// check-pass + +#![feature(min_specialization)] +#![feature(rustc_attrs)] + +#[rustc_unsafe_specialization_marker] +trait SpecMarker {} + +trait X { + fn f(); +} + +impl X for T { + default fn f() {} +} + +impl X for T { + fn f() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_spec_trait.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_spec_trait.rs new file mode 100644 index 000000000000..f12d4cf56f9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_spec_trait.rs @@ -0,0 +1,28 @@ +// Test that specializing on a `rustc_specialization_trait` trait is allowed. + +// check-pass + +#![feature(min_specialization)] +#![feature(rustc_attrs)] + +#[rustc_specialization_trait] +trait SpecTrait { + fn g(&self); +} + +trait X { + fn f(&self); +} + +impl X for T { + default fn f(&self) {} +} + +impl X for T { + fn f(&self) { + self.g(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_static.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_static.rs new file mode 100644 index 000000000000..c8fb37f769e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_static.rs @@ -0,0 +1,19 @@ +// Test that directly specializing on `'static` is not allowed. + +#![feature(min_specialization)] + +trait X { + fn f(); +} + +impl X for &'_ T { + default fn f() {} +} + +impl X for &'static u8 { +// { dg-error "" "" { target *-*-* } .-1 } + fn f() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_trait.rs b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_trait.rs new file mode 100644 index 000000000000..54b724e8d0b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/min_specialization/specialize_on_trait.rs @@ -0,0 +1,21 @@ +// Test that specializing on a trait is not allowed in general. + +#![feature(min_specialization)] + +trait SpecMarker {} + +trait X { + fn f(); +} + +impl X for T { + default fn f() {} +} + +impl X for T { +// { dg-error "" "" { target *-*-* } .-1 } + fn f() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/non-defaulted-item-fail.rs b/gcc/testsuite/rust/rustc/ui/specialization/non-defaulted-item-fail.rs new file mode 100644 index 000000000000..710b50912efd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/non-defaulted-item-fail.rs @@ -0,0 +1,55 @@ +#![feature(specialization, associated_type_defaults)] +// { dg-warning "" "" { target *-*-* } .-1 } + +// Test that attempting to override a non-default method or one not in the +// parent impl causes an error. + +trait Foo { + type Ty = (); + const CONST: u8 = 123; + fn foo(&self) -> bool { true } +} + +// Specialization tree for Foo: +// +// Box Vec +// / \ / \ +// Box Box Vec<()> Vec + +impl Foo for Box { + type Ty = bool; + const CONST: u8 = 0; + fn foo(&self) -> bool { false } +} + +// Allowed +impl Foo for Box {} + +// Can't override a non-`default` fn +impl Foo for Box { + type Ty = Vec<()>; +// { dg-error ".E0520." "" { target *-*-* } .-1 } + const CONST: u8 = 42; +// { dg-error ".E0520." "" { target *-*-* } .-1 } + fn foo(&self) -> bool { true } +// { dg-error ".E0520." "" { target *-*-* } .-1 } +} + + +// Doesn't mention the item = provided body/value is used and the method is final. +impl Foo for Vec {} + +// Allowed +impl Foo for Vec<()> {} + +impl Foo for Vec { + type Ty = Vec<()>; +// { dg-error ".E0520." "" { target *-*-* } .-1 } + const CONST: u8 = 42; +// { dg-error ".E0520." "" { target *-*-* } .-1 } + fn foo(&self) -> bool { true } +// { dg-error ".E0520." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/soundness/partial_eq_range_inclusive.rs b/gcc/testsuite/rust/rustc/ui/specialization/soundness/partial_eq_range_inclusive.rs new file mode 100644 index 000000000000..215ce970b4f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/soundness/partial_eq_range_inclusive.rs @@ -0,0 +1,36 @@ +// run-pass + +use std::cell::RefCell; +use std::cmp::Ordering; + +struct Evil<'a, 'b> { + values: RefCell>, + to_insert: &'b String, +} + +impl<'a, 'b> PartialEq for Evil<'a, 'b> { + fn eq(&self, _other: &Self) -> bool { + true + } +} + +impl<'a> PartialOrd for Evil<'a, 'a> { + fn partial_cmp(&self, _other: &Self) -> Option { + self.values.borrow_mut().push(self.to_insert); + None + } +} + +fn main() { + let e; + let values; + { + let to_insert = String::from("Hello, world!"); + e = Evil { values: RefCell::new(Vec::new()), to_insert: &to_insert }; + let range = &e..=&e; + let _ = range == range; + values = e.values; + } + assert_eq!(*values.borrow(), Vec::<&str>::new()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/soundness/partial_ord_slice.rs b/gcc/testsuite/rust/rustc/ui/specialization/soundness/partial_ord_slice.rs new file mode 100644 index 000000000000..d78470047f4c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/soundness/partial_ord_slice.rs @@ -0,0 +1,43 @@ +// Check that we aren't using unsound specialization in slice comparisons. + +// run-pass + +use std::cell::Cell; +use std::cmp::Ordering; + +struct Evil<'a, 'b>(Cell<(&'a [i32], &'b [i32])>); + +impl PartialEq for Evil<'_, '_> { + fn eq(&self, _other: &Self) -> bool { + true + } +} + +impl Eq for Evil<'_, '_> {} + +impl PartialOrd for Evil<'_, '_> { + fn partial_cmp(&self, _other: &Self) -> Option { + Some(Ordering::Equal) + } +} + +impl<'a> Ord for Evil<'a, 'a> { + fn cmp(&self, _other: &Self) -> Ordering { + let (a, b) = self.0.get(); + self.0.set((b, a)); + Ordering::Equal + } +} + +fn main() { + let x = &[1, 2, 3, 4]; + let u = { + let a = Box::new([7, 8, 9, 10]); + let y = [Evil(Cell::new((x, &*a)))]; + let _ = &y[..] <= &y[..]; + let [Evil(c)] = y; + c.get().0 + }; + assert_eq!(u, &[1, 2, 3, 4]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-allowed-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-allowed-cross-crate.rs new file mode 100644 index 000000000000..d1bdd0bc058a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-allowed-cross-crate.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_imports)] + +// aux-build:go_trait.rs + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +extern crate go_trait; + +use go_trait::{Go,GoMut}; +use std::fmt::Debug; +use std::default::Default; + +struct MyThingy; + +impl Go for MyThingy { + fn go(&self, arg: isize) { } +} + +impl GoMut for MyThingy { + fn go_mut(&mut self, arg: isize) { } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-assoc-fns.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-assoc-fns.rs new file mode 100644 index 000000000000..92b8a2546168 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-assoc-fns.rs @@ -0,0 +1,30 @@ +// run-pass + +// Test that non-method associated functions can be specialized + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Foo { + fn mk() -> Self; +} + +impl Foo for T { + default fn mk() -> T { + T::default() + } +} + +impl Foo for Vec { + fn mk() -> Vec { + vec![0] + } +} + +fn main() { + let v1: Vec = Foo::mk(); + let v2: Vec = Foo::mk(); + + assert!(v1.len() == 0); + assert!(v2.len() == 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-basics.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-basics.rs new file mode 100644 index 000000000000..253659a03c5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-basics.rs @@ -0,0 +1,99 @@ +// run-pass + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// Tests a variety of basic specialization scenarios and method +// dispatch for them. + +trait Foo { + fn foo(&self) -> &'static str; +} + +impl Foo for T { + default fn foo(&self) -> &'static str { + "generic" + } +} + +impl Foo for T { + default fn foo(&self) -> &'static str { + "generic Clone" + } +} + +impl Foo for (T, U) where T: Clone, U: Clone { + default fn foo(&self) -> &'static str { + "generic pair" + } +} + +impl Foo for (T, T) { + default fn foo(&self) -> &'static str { + "generic uniform pair" + } +} + +impl Foo for (u8, u32) { + default fn foo(&self) -> &'static str { + "(u8, u32)" + } +} + +impl Foo for (u8, u8) { + default fn foo(&self) -> &'static str { + "(u8, u8)" + } +} + +impl Foo for Vec { + default fn foo(&self) -> &'static str { + "generic Vec" + } +} + +impl Foo for Vec { + fn foo(&self) -> &'static str { + "Vec" + } +} + +impl Foo for String { + fn foo(&self) -> &'static str { + "String" + } +} + +impl Foo for i32 { + fn foo(&self) -> &'static str { + "i32" + } +} + +struct NotClone; + +trait MyMarker {} +impl Foo for T { + default fn foo(&self) -> &'static str { + "generic Clone + MyMarker" + } +} + +#[derive(Clone)] +struct MarkedAndClone; +impl MyMarker for MarkedAndClone {} + +fn main() { + assert!(NotClone.foo() == "generic"); + assert!(0u8.foo() == "generic Clone"); + assert!(vec![NotClone].foo() == "generic"); + assert!(vec![0u8].foo() == "generic Vec"); + assert!(vec![0i32].foo() == "Vec"); + assert!(0i32.foo() == "i32"); + assert!(String::new().foo() == "String"); + assert!(((), 0).foo() == "generic pair"); + assert!(((), ()).foo() == "generic uniform pair"); + assert!((0u8, 0u32).foo() == "(u8, u32)"); + assert!((0u8, 0u8).foo() == "(u8, u8)"); + assert!(MarkedAndClone.foo() == "generic Clone + MyMarker"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-cross-crate-no-gate.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-cross-crate-no-gate.rs new file mode 100644 index 000000000000..17daa6e51991 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-cross-crate-no-gate.rs @@ -0,0 +1,22 @@ +// run-pass + +// Test that specialization works even if only the upstream crate enables it + +// aux-build:specialization_cross_crate.rs + +extern crate specialization_cross_crate; + +use specialization_cross_crate::*; + +fn main() { + assert!(0u8.foo() == "generic Clone"); + assert!(vec![0u8].foo() == "generic Vec"); + assert!(vec![0i32].foo() == "Vec"); + assert!(0i32.foo() == "i32"); + assert!(String::new().foo() == "String"); + assert!(((), 0).foo() == "generic pair"); + assert!(((), ()).foo() == "generic uniform pair"); + assert!((0u8, 0u32).foo() == "(u8, u32)"); + assert!((0u8, 0u8).foo() == "(u8, u8)"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-cross-crate.rs new file mode 100644 index 000000000000..ea178e9d83f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-cross-crate.rs @@ -0,0 +1,51 @@ +// run-pass + +// aux-build:specialization_cross_crate.rs + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +extern crate specialization_cross_crate; + +use specialization_cross_crate::*; + +struct NotClone; + +#[derive(Clone)] +struct MarkedAndClone; +impl MyMarker for MarkedAndClone {} + +struct MyType(T); +impl Foo for MyType { + default fn foo(&self) -> &'static str { + "generic MyType" + } +} + +impl Foo for MyType { + fn foo(&self) -> &'static str { + "MyType" + } +} + +struct MyOtherType; +impl Foo for MyOtherType {} + +fn main() { + assert!(NotClone.foo() == "generic"); + assert!(0u8.foo() == "generic Clone"); + assert!(vec![NotClone].foo() == "generic"); + assert!(vec![0u8].foo() == "generic Vec"); + assert!(vec![0i32].foo() == "Vec"); + assert!(0i32.foo() == "i32"); + assert!(String::new().foo() == "String"); + assert!(((), 0).foo() == "generic pair"); + assert!(((), ()).foo() == "generic uniform pair"); + assert!((0u8, 0u32).foo() == "(u8, u32)"); + assert!((0u8, 0u8).foo() == "(u8, u8)"); + assert!(MarkedAndClone.foo() == "generic Clone + MyMarker"); + + assert!(MyType(()).foo() == "generic MyType"); + assert!(MyType(0u8).foo() == "MyType"); + assert!(MyOtherType.foo() == "generic"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-default-methods.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-default-methods.rs new file mode 100644 index 000000000000..1f206a872100 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-default-methods.rs @@ -0,0 +1,88 @@ +// run-pass + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// Test that default methods are cascaded correctly + +// First, test only use of explicit `default` items: + +trait Foo { + fn foo(&self) -> bool; +} + +// Specialization tree for Foo: +// +// T +// / \ +// i32 i64 + +impl Foo for T { + default fn foo(&self) -> bool { false } +} + +impl Foo for i32 {} + +impl Foo for i64 { + fn foo(&self) -> bool { true } +} + +fn test_foo() { + assert!(!0i8.foo()); + assert!(!0i32.foo()); + assert!(0i64.foo()); +} + +// Next, test mixture of explicit `default` and provided methods: + +trait Bar { + fn bar(&self) -> i32 { 0 } +} + +// Specialization tree for Bar. +// Uses of $ designate that method is provided +// +// $Bar (the trait) +// | +// T +// /|\ +// / | \ +// / | \ +// / | \ +// / | \ +// / | \ +// $i32 &str $Vec +// /\ +// / \ +// Vec $Vec + +impl Bar for T { + default fn bar(&self) -> i32 { 0 } +} + +impl Bar for i32 { + fn bar(&self) -> i32 { 1 } +} +impl<'a> Bar for &'a str {} + +impl Bar for Vec { + default fn bar(&self) -> i32 { 2 } +} +impl Bar for Vec {} +impl Bar for Vec { + fn bar(&self) -> i32 { 3 } +} + +fn test_bar() { + assert!(0u8.bar() == 0); + assert!(0i32.bar() == 1); + assert!("hello".bar() == 0); + assert!(vec![()].bar() == 2); + assert!(vec![0i32].bar() == 2); + assert!(vec![0i64].bar() == 3); +} + +fn main() { + test_foo(); + test_bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-default-projection.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-default-projection.rs new file mode 100644 index 000000000000..e027013d93f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-default-projection.rs @@ -0,0 +1,37 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// Make sure we can't project defaulted associated types + +trait Foo { + type Assoc; +} + +impl Foo for T { + default type Assoc = (); +} + +impl Foo for u8 { + type Assoc = String; +} + +fn generic() -> ::Assoc { + // `T` could be some downstream crate type that specializes (or, + // for that matter, `u8`). + + () // { dg-error ".E0308." "" { target *-*-* } } +} + +fn monomorphic() -> () { + // Even though we know that `()` is not specialized in a + // downstream crate, typeck refuses to project here. + + generic::<()>() // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { + // No error here, we CAN project from `u8`, as there is no `default` + // in that impl. + let s: String = generic::(); + println!("{}", s); // bad news if this all compiles +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-default-types.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-default-types.rs new file mode 100644 index 000000000000..ec25c253f009 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-default-types.rs @@ -0,0 +1,36 @@ +// It should not be possible to use the concrete value of a defaulted +// associated type in the impl defining it -- otherwise, what happens +// if it's overridden? + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Example { + type Output; + fn generate(self) -> Self::Output; +} + +impl Example for T { + default type Output = Box; + default fn generate(self) -> Self::Output { + Box::new(self) // { dg-error ".E0308." "" { target *-*-* } } + } +} + +impl Example for bool { + type Output = bool; + fn generate(self) -> bool { self } +} + +fn trouble(t: T) -> Box { + Example::generate(t) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn weaponize() -> bool { + let b: Box = trouble(true); + *b +} + +fn main() { + weaponize(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-feature-gate-default.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-feature-gate-default.rs new file mode 100644 index 000000000000..9d8861c317e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-feature-gate-default.rs @@ -0,0 +1,14 @@ +// Check that specialization must be ungated to use the `default` keyword + +// gate-test-specialization + +trait Foo { + fn foo(&self); +} + +impl Foo for T { + default fn foo(&self) {} // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-feature-gate-overlap.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-feature-gate-overlap.rs new file mode 100644 index 000000000000..cee294527a9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-feature-gate-overlap.rs @@ -0,0 +1,18 @@ +// Check that writing an overlapping impl is not allow unless specialization is ungated. + +// gate-test-specialization + +trait Foo { + fn foo(&self); +} + +impl Foo for T { + fn foo(&self) {} +} + +impl Foo for u8 { // { dg-error ".E0119." "" { target *-*-* } } + fn foo(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-no-default.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-no-default.rs new file mode 100644 index 000000000000..56241ba7effb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-no-default.rs @@ -0,0 +1,78 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// Check a number of scenarios in which one impl tries to override another, +// without correctly using `default`. + +// Test 1: one layer of specialization, multiple methods, missing `default` + +trait Foo { + fn foo(&self); + fn bar(&self); +} + +impl Foo for T { + fn foo(&self) {} + fn bar(&self) {} +} + +impl Foo for u8 {} +impl Foo for u16 { + fn foo(&self) {} // { dg-error ".E0520." "" { target *-*-* } } +} +impl Foo for u32 { + fn bar(&self) {} // { dg-error ".E0520." "" { target *-*-* } } +} + +// Test 2: one layer of specialization, missing `default` on associated type + +trait Bar { + type T; +} + +impl Bar for T { + type T = u8; +} + +impl Bar for u8 { + type T = (); // { dg-error ".E0520." "" { target *-*-* } } +} + +// Test 3a: multiple layers of specialization, missing interior `default` + +trait Baz { + fn baz(&self); +} + +impl Baz for T { + default fn baz(&self) {} +} + +impl Baz for T { + fn baz(&self) {} +} + +impl Baz for i32 { + fn baz(&self) {} // { dg-error ".E0520." "" { target *-*-* } } +} + +// Test 3b: multiple layers of specialization, missing interior `default`, +// redundant `default` in bottom layer. + +trait Redundant { + fn redundant(&self); +} + +impl Redundant for T { + default fn redundant(&self) {} +} + +impl Redundant for T { + fn redundant(&self) {} +} + +impl Redundant for i32 { + default fn redundant(&self) {} // { dg-error ".E0520." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-on-projection.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-on-projection.rs new file mode 100644 index 000000000000..9efdadb29593 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-on-projection.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// Ensure that specialization works for impls defined directly on a projection + +trait Foo {} + +trait Assoc { + type Item; +} + +impl Foo for T {} + +struct Struct; + +impl Assoc for Struct { + type Item = u8; +} + +impl Foo for Struct {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-out-of-order.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-out-of-order.rs new file mode 100644 index 000000000000..43fc99d43627 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-out-of-order.rs @@ -0,0 +1,20 @@ +// run-pass + +// Test that you can list the more specific impl before the more general one. + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Foo { + type Out; +} + +impl Foo for bool { + type Out = (); +} + +impl Foo for T { + default type Out = bool; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap-hygiene.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap-hygiene.rs new file mode 100644 index 000000000000..f855c5b177c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap-hygiene.rs @@ -0,0 +1,24 @@ +#![feature(decl_macro)] + +struct X; + +macro_rules! define_f_legacy { () => { + fn f() {} +}} +macro define_g_modern() { + fn g() {} +} + +impl X { + fn f() {} // { dg-error ".E0592." "" { target *-*-* } } + fn g() {} // OK +} +impl X { + define_f_legacy!(); +} +impl X { + define_g_modern!(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap-negative.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap-negative.rs new file mode 100644 index 000000000000..b4bd9d99411c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap-negative.rs @@ -0,0 +1,12 @@ +#![feature(negative_impls)] +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait MyTrait {} + +struct TestType(::std::marker::PhantomData); + +unsafe impl Send for TestType {} +impl !Send for TestType {} // { dg-error ".E0751." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap-projection.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap-projection.rs new file mode 100644 index 000000000000..00f283344b78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap-projection.rs @@ -0,0 +1,26 @@ +// run-pass + +// Test that impls on projected self types can resolve overlap, even when the +// projections involve specialization, so long as the associated type is +// provided by the most specialized impl. + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Assoc { + type Output; +} + +impl Assoc for T { + default type Output = bool; +} + +impl Assoc for u8 { type Output = u8; } +impl Assoc for u16 { type Output = u16; } + +trait Foo {} +impl Foo for u32 {} +impl Foo for ::Output {} +impl Foo for ::Output {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap.rs new file mode 100644 index 000000000000..c580f1ae7ab3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-overlap.rs @@ -0,0 +1,20 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Foo { fn foo() {} } +impl Foo for T {} +impl Foo for Vec {} // { dg-error ".E0119." "" { target *-*-* } } + +trait Bar { fn bar() {} } +impl Bar for (T, u8) {} +impl Bar for (u8, T) {} // { dg-error ".E0119." "" { target *-*-* } } + +trait Baz { fn baz() {} } +impl Baz for u8 {} +impl Baz for T {} // { dg-error ".E0119." "" { target *-*-* } } + +trait Qux { fn qux() {} } +impl Qux for T {} +impl Qux for T {} // { dg-error ".E0119." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-polarity.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-polarity.rs new file mode 100644 index 000000000000..31a2ab1330ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-polarity.rs @@ -0,0 +1,18 @@ +// Make sure specialization cannot change impl polarity + +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +auto trait Foo {} + +impl Foo for T {} +impl !Foo for u8 {} // { dg-error ".E0751." "" { target *-*-* } } + +auto trait Bar {} + +impl !Bar for T {} +impl Bar for u8 {} // { dg-error ".E0751." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-projection-alias.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-projection-alias.rs new file mode 100644 index 000000000000..8a1c62ff0023 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-projection-alias.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// Regression test for ICE when combining specialized associated types and type +// aliases + +trait Id_ { + type Out; +} + +type Id = ::Out; + +impl Id_ for T { + default type Out = T; +} + +fn test_proection() { + let x: Id = panic!(); +} + +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-projection.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-projection.rs new file mode 100644 index 000000000000..614ceafaf52d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-projection.rs @@ -0,0 +1,43 @@ +// run-pass +#![allow(dead_code)] + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// Make sure we *can* project non-defaulted associated types +// cf compile-fail/specialization-default-projection.rs + +// First, do so without any use of specialization + +trait Foo { + type Assoc; +} + +impl Foo for T { + type Assoc = (); +} + +fn generic_foo() -> ::Assoc { + () +} + +// Next, allow for one layer of specialization + +trait Bar { + type Assoc; +} + +impl Bar for T { + default type Assoc = (); +} + +impl Bar for T { + type Assoc = u8; +} + +fn generic_bar_clone() -> ::Assoc { + 0u8 +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-super-traits.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-super-traits.rs new file mode 100644 index 000000000000..ad8c2a1daac1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-super-traits.rs @@ -0,0 +1,18 @@ +// run-pass + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +// Test that you can specialize via an explicit trait hierarchy + +// FIXME: this doesn't work yet... + +trait Parent {} +trait Child: Parent {} + +trait Foo {} + +impl Foo for T {} +impl Foo for T {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-translate-projections-with-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-translate-projections-with-lifetimes.rs new file mode 100644 index 000000000000..9960d638f155 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-translate-projections-with-lifetimes.rs @@ -0,0 +1,34 @@ +// run-pass + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Iterator { + fn next(&self); +} + +trait WithAssoc { + type Item; +} + +impl<'a> WithAssoc for &'a () { + type Item = &'a u32; +} + +struct Cloned(I); + +impl<'a, I, T: 'a> Iterator for Cloned + where I: WithAssoc, T: Clone +{ + fn next(&self) {} +} + +impl<'a, I, T: 'a> Iterator for Cloned + where I: WithAssoc, T: Copy +{ + +} + +fn main() { + Cloned(&()).next(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-translate-projections-with-params.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-translate-projections-with-params.rs new file mode 100644 index 000000000000..34a3801c295d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-translate-projections-with-params.rs @@ -0,0 +1,33 @@ +// run-pass + +// Ensure that provided items are inherited properly even when impls vary in +// type parameters *and* rely on projections, and the type parameters are input +// types on the trait. + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Trait { + fn convert(&self) -> T; +} +trait WithAssoc { + type Item; + fn as_item(&self) -> &Self::Item; +} + +impl Trait for T where T: WithAssoc, U: Clone { + fn convert(&self) -> U { + self.as_item().clone() + } +} + +impl WithAssoc for u8 { + type Item = u8; + fn as_item(&self) -> &u8 { self } +} + +impl Trait for u8 {} + +fn main() { + assert!(3u8.convert() == 3u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/specialization/specialization-translate-projections.rs b/gcc/testsuite/rust/rustc/ui/specialization/specialization-translate-projections.rs new file mode 100644 index 000000000000..6b2e72736f39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/specialization/specialization-translate-projections.rs @@ -0,0 +1,34 @@ +// run-pass + +// Ensure that provided items are inherited properly even when impls vary in +// type parameters *and* rely on projections. + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +use std::convert::Into; + +trait Trait { + fn to_u8(&self) -> u8; +} +trait WithAssoc { + type Item; + fn to_item(&self) -> Self::Item; +} + +impl Trait for T where T: WithAssoc, U: Into { + fn to_u8(&self) -> u8 { + self.to_item().into() + } +} + +impl WithAssoc for u8 { + type Item = u8; + fn to_item(&self) -> u8 { *self } +} + +impl Trait for u8 {} + +fn main() { + assert!(3u8.to_u8() == 3u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/sse2.rs b/gcc/testsuite/rust/rustc/ui/sse2.rs new file mode 100644 index 000000000000..37b7e5328af5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/sse2.rs @@ -0,0 +1,27 @@ +// run-pass +// ignore-cloudabi no std::env + +#![allow(stable_features)] +#![feature(cfg_target_feature)] + +use std::env; + +fn main() { + match env::var("TARGET") { + Ok(s) => { + // Skip this tests on i586-unknown-linux-gnu where sse2 is disabled + if s.contains("i586") { + return + } + } + Err(_) => return, + } + if cfg!(any(target_arch = "x86", target_arch = "x86_64")) { + assert!(cfg!(target_feature = "sse2"), + "SSE2 was not detected as available on an x86 platform"); + } + // check a negative case too -- allowed on x86, but not enabled by default + assert!(cfg!(not(target_feature = "avx2")), + "AVX2 shouldn't be detected as available by default on any platform"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/auxiliary/stability_attribute_issue.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/auxiliary/stability_attribute_issue.rs new file mode 100644 index 000000000000..3ae0656d8df4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/auxiliary/stability_attribute_issue.rs @@ -0,0 +1,10 @@ +#![feature(staged_api)] +#![stable(feature = "stable_test_feature", since = "1.2.0")] + + +#[unstable(feature = "unstable_test_feature", issue = "1")] +pub fn unstable() {} + +#[unstable(feature = "unstable_test_feature", reason = "message", issue = "2")] +pub fn unstable_msg() {} + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/auxiliary/unstable_generic_param.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/auxiliary/unstable_generic_param.rs new file mode 100644 index 000000000000..fceb33cfa7c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/auxiliary/unstable_generic_param.rs @@ -0,0 +1,230 @@ +#![crate_type = "lib"] +#![feature(staged_api)] +#![stable(feature = "stable_test_feature", since = "1.0.0")] + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub trait Trait1<#[unstable(feature = "unstable_default", issue = "none")] T = ()> { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + fn foo() -> T; +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub trait Trait2<#[unstable(feature = "unstable_default", issue = "none")] T = usize> { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + fn foo() -> T; +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub trait Trait3 { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + fn foo() -> T; +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub struct Struct1<#[unstable(feature = "unstable_default", issue = "none")] T = usize> { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + pub field: T, +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub struct Struct2 { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + pub field: T, +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub struct Struct3 { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + pub field1: A, + #[stable(feature = "stable_test_feature", since = "1.0.0")] + pub field2: B, +} + +#[rustc_deprecated(since = "1.1.0", reason = "test")] +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub struct Struct4 { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + pub field: A, +} + +#[rustc_deprecated(since = "1.1.0", reason = "test")] +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub struct Struct5<#[unstable(feature = "unstable_default", issue = "none")] A = usize> { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + pub field: A, +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub struct Struct6<#[unstable(feature = "unstable_default6", issue = "none")] T = usize> { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + pub field: T, +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const STRUCT1: Struct1 = Struct1 { field: 1 }; + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const STRUCT2: Struct2 = Struct2 { field: 1 }; + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const STRUCT3: Struct3 = Struct3 { field1: 1, field2: 2 }; + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const STRUCT4: Struct4 = Struct4 { field: 1 }; + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const STRUCT5: Struct5 = Struct5 { field: 1 }; + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub enum Enum1<#[unstable(feature = "unstable_default", issue = "none")] T = usize> { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + Some(#[stable(feature = "stable_test_feature", since = "1.0.0")] T), + #[stable(feature = "stable_test_feature", since = "1.0.0")] + None, +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub enum Enum2 { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + Some(#[stable(feature = "stable_test_feature", since = "1.0.0")] T), + #[stable(feature = "stable_test_feature", since = "1.0.0")] + None, +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub enum Enum3 { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + Ok(#[stable(feature = "stable_test_feature", since = "1.0.0")] T), + #[stable(feature = "stable_test_feature", since = "1.0.0")] + Err(#[stable(feature = "stable_test_feature", since = "1.0.0")] E), +} + +#[rustc_deprecated(since = "1.1.0", reason = "test")] +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub enum Enum4 { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + Some(#[stable(feature = "stable_test_feature", since = "1.0.0")] T), + #[stable(feature = "stable_test_feature", since = "1.0.0")] + None, +} + +#[rustc_deprecated(since = "1.1.0", reason = "test")] +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub enum Enum5<#[unstable(feature = "unstable_default", issue = "none")] T = usize> { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + Some(#[stable(feature = "stable_test_feature", since = "1.0.0")] T), + #[stable(feature = "stable_test_feature", since = "1.0.0")] + None, +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub enum Enum6<#[unstable(feature = "unstable_default6", issue = "none")] T = usize> { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + Some(#[stable(feature = "stable_test_feature", since = "1.0.0")] T), + #[stable(feature = "stable_test_feature", since = "1.0.0")] + None, +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const ENUM1: Enum1 = Enum1::Some(1); + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const ENUM2: Enum2 = Enum2::Some(1); + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const ENUM3: Enum3 = Enum3::Ok(1); +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const ENUM3B: Enum3 = Enum3::Err(1); + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const ENUM4: Enum4 = Enum4::Some(1); + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const ENUM5: Enum5 = Enum5::Some(1); + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub type Alias1<#[unstable(feature = "unstable_default", issue = "none")] T = usize> = Option; + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub type Alias2 = Option; + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub type Alias3 = + Result; + +#[rustc_deprecated(since = "1.1.0", reason = "test")] +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub type Alias4 = Option; + +#[rustc_deprecated(since = "1.1.0", reason = "test")] +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub type Alias5<#[unstable(feature = "unstable_default", issue = "none")] T = usize> = Option; + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub type Alias6<#[unstable(feature = "unstable_default6", issue = "none")] T = usize> = Option; + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const ALIAS1: Alias1 = Alias1::Some(1); + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const ALIAS2: Alias2 = Alias2::Some(1); + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const ALIAS3: Alias3 = Alias3::Ok(1); +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const ALIAS3B: Alias3 = Alias3::Err(1); + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const ALIAS4: Alias4 = Alias4::Some(1); + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub const ALIAS5: Alias5 = Alias5::Some(1); + + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub trait Alloc {} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub struct System {} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +impl Alloc for System {} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub struct Box1 { + ptr: *mut T, + alloc: A, +} + +impl Box1 { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + pub fn new(mut t: T) -> Self { + unsafe { Self { ptr: &mut t, alloc: System {} } } + } +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub struct Box2 { + ptr: *mut T, + alloc: A, +} + +impl Box2 { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + pub fn new(mut t: T) -> Self { + Self { ptr: &mut t, alloc: System {} } + } +} + +#[stable(feature = "stable_test_feature", since = "1.0.0")] +pub struct Box3 { + ptr: *mut T, +} + +impl Box3 { + #[stable(feature = "stable_test_feature", since = "1.0.0")] + pub fn new(mut t: T) -> Self { + Self { ptr: &mut t } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/generics-default-stability-where.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/generics-default-stability-where.rs new file mode 100644 index 000000000000..dab81c0ea8b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/generics-default-stability-where.rs @@ -0,0 +1,13 @@ +// ignore-tidy-linelength +// aux-build:unstable_generic_param.rs + +extern crate unstable_generic_param; + +use unstable_generic_param::*; + +impl Trait3 for T where T: Trait2 { // { dg-error ".E0658." "" { target *-*-* } } + fn foo() -> usize { T::foo() } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/generics-default-stability.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/generics-default-stability.rs new file mode 100644 index 000000000000..a837ee965896 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/generics-default-stability.rs @@ -0,0 +1,265 @@ +// ignore-tidy-linelength +// aux-build:unstable_generic_param.rs +#![feature(unstable_default6)] + +extern crate unstable_generic_param; + +use unstable_generic_param::*; + +struct R; + +impl Trait1 for S { + fn foo() -> () { () } // ok +} + +struct S; + +impl Trait1 for S { // { dg-error ".E0658." "" { target *-*-* } } + fn foo() -> usize { 0 } +} + +impl Trait1 for S { // { dg-error ".E0658." "" { target *-*-* } } + fn foo() -> isize { 0 } +} + +impl Trait2 for S { // { dg-error ".E0658." "" { target *-*-* } } + fn foo() -> usize { 0 } +} + +impl Trait3 for S { + fn foo() -> usize { 0 } // ok +} + +fn main() { + let _ = S; + + let _: Struct1 = Struct1 { field: 1 }; // { dg-error ".E0658." "" { target *-*-* } } + + let _ = STRUCT1; // ok + let _: Struct1 = STRUCT1; // ok + let _: Struct1 = STRUCT1; // { dg-error ".E0658." "" { target *-*-* } } + let _: Struct1 = Struct1 { field: 0 }; // { dg-error ".E0658." "" { target *-*-* } } + + // Instability is not enforced for generic type parameters used in public fields. + // Note how the unstable type default `usize` leaks, + // and can be used without the 'unstable_default' feature. + let _ = STRUCT1.field; + let _ = Struct1 { field: 1 }; + let _ = Struct1 { field: () }; + let _ = Struct1 { field: 1isize }; + let _: Struct1 = Struct1 { field: 1 }; + let _: usize = STRUCT1.field; + let _ = STRUCT1.field + 1; + let _ = STRUCT1.field + 1usize; + + let _ = Struct2 { field: 1 }; // ok + let _: Struct2 = Struct2 { field: 1 }; // ok + let _: Struct2 = Struct2 { field: 1 }; // ok + + let _ = STRUCT2; + let _: Struct2 = STRUCT2; // ok + let _: Struct2 = STRUCT2; // ok + let _: Struct2 = Struct2 { field: 0 }; // ok + let _ = STRUCT2.field; // ok + let _: usize = STRUCT2.field; // ok + let _ = STRUCT2.field + 1; // ok + let _ = STRUCT2.field + 1usize; // ok + + let _ = STRUCT3; + let _: Struct3 = STRUCT3; // ok + let _: Struct3 = STRUCT3; // { dg-error ".E0658." "" { target *-*-* } } + let _: Struct3 = STRUCT3; // ok + let _: Struct3 = Struct3 { field1: 0, field2: 0 }; // { dg-error ".E0658." "" { target *-*-* } } + let _: Struct3 = Struct3 { field1: 0, field2: 0 }; // { dg-error ".E0658." "" { target *-*-* } } + let _ = STRUCT3.field1; // ok + let _: isize = STRUCT3.field1; // ok + let _ = STRUCT3.field1 + 1; // ok + // Note the aforementioned leak. + let _: usize = STRUCT3.field2; // ok + let _: Struct3 = Struct3 { field1: 0, field2: 0 }; // ok + let _ = STRUCT3.field2 + 1; // ok + let _ = STRUCT3.field2 + 1usize; // ok + + let _ = STRUCT4; + let _: Struct4 = Struct4 { field: 1 }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + let _ = STRUCT4; + let _: Struct4 = STRUCT4; // { dg-error "" "" { target *-*-* } } + let _: Struct4 = STRUCT4; // { dg-error "" "" { target *-*-* } } + let _: Struct4 = Struct4 { field: 0 }; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + + let _ = STRUCT5; + let _: Struct5 = Struct5 { field: 1 }; // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } + let _ = STRUCT5; + let _: Struct5 = STRUCT5; // { dg-error "" "" { target *-*-* } } + let _: Struct5 = STRUCT5; // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + let _: Struct5 = Struct5 { field: 0 }; // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } +// { dg-error ".E0658." "" { target *-*-* } .-3 } + + let _: Struct6 = Struct6 { field: 1 }; // ok + let _: Struct6 = Struct6 { field: 0 }; // ok + + let _: Alias1 = Alias1::Some(1); // { dg-error ".E0658." "" { target *-*-* } } + + let _ = ALIAS1; // ok + let _: Alias1 = ALIAS1; // ok + let _: Alias1 = ALIAS1; // { dg-error ".E0658." "" { target *-*-* } } + let _: Alias1 = Alias1::Some(0); // { dg-error ".E0658." "" { target *-*-* } } + + // Instability is not enforced for generic type parameters used in public fields. + // Note how the unstable type default `usize` leaks, + // and can be used without the 'unstable_default' feature. + let _ = Alias1::Some(1); + let _ = Alias1::Some(()); + let _ = Alias1::Some(1isize); + let _: Alias1 = Alias1::Some(1); + let _: usize = ALIAS1.unwrap(); + let _ = ALIAS1.unwrap() + 1; + let _ = ALIAS1.unwrap() + 1usize; + + let _ = Alias2::Some(1); // ok + let _: Alias2 = Alias2::Some(1); // ok + let _: Alias2 = Alias2::Some(1); // ok + + let _ = ALIAS2; + let _: Alias2 = ALIAS2; // ok + let _: Alias2 = ALIAS2; // ok + let _: Alias2 = Alias2::Some(0); // ok + let _ = ALIAS2.unwrap(); // ok + let _: usize = ALIAS2.unwrap(); // ok + let _ = ALIAS2.unwrap() + 1; // ok + let _ = ALIAS2.unwrap() + 1usize; // ok + + let _ = ALIAS3; + let _: Alias3 = ALIAS3; // ok + let _: Alias3 = ALIAS3; // { dg-error ".E0658." "" { target *-*-* } } + let _: Alias3 = ALIAS3; // ok + let _: Alias3 = Alias3::Ok(0); // { dg-error ".E0658." "" { target *-*-* } } + let _: Alias3 = Alias3::Ok(0); // { dg-error ".E0658." "" { target *-*-* } } + let _ = ALIAS3.unwrap(); // ok + let _: isize = ALIAS3.unwrap(); // ok + let _ = ALIAS3.unwrap() + 1; // ok + // Note the aforementioned leak. + let _: usize = ALIAS3B.unwrap_err(); // ok + let _: Alias3 = Alias3::Err(0); // ok + let _ = ALIAS3B.unwrap_err() + 1; // ok + let _ = ALIAS3B.unwrap_err() + 1usize; // ok + + let _ = ALIAS4; + let _: Alias4 = Alias4::Some(1); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + let _ = ALIAS4; + let _: Alias4 = ALIAS4; // { dg-error "" "" { target *-*-* } } + let _: Alias4 = ALIAS4; // { dg-error "" "" { target *-*-* } } + let _: Alias4 = Alias4::Some(0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + let _ = ALIAS5; + let _: Alias5 = Alias5::Some(1); // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + let _ = ALIAS5; + let _: Alias5 = ALIAS5; // { dg-error "" "" { target *-*-* } } + let _: Alias5 = ALIAS5; // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + let _: Alias5 = Alias5::Some(0); // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + let _: Alias6 = Alias6::Some(1); // ok + let _: Alias6 = Alias6::Some(0); // ok + + let _: Enum1 = Enum1::Some(1); // { dg-error ".E0658." "" { target *-*-* } } + + let _ = ENUM1; // ok + let _: Enum1 = ENUM1; // ok + let _: Enum1 = ENUM1; // { dg-error ".E0658." "" { target *-*-* } } + let _: Enum1 = Enum1::Some(0); // { dg-error ".E0658." "" { target *-*-* } } + + // Instability is not enforced for generic type parameters used in public fields. + // Note how the unstable type default `usize` leaks, + // and can be used without the 'unstable_default' feature. + let _ = Enum1::Some(1); + let _ = Enum1::Some(()); + let _ = Enum1::Some(1isize); + let _: Enum1 = Enum1::Some(1); + if let Enum1::Some(x) = ENUM1 {let _: usize = x;} + if let Enum1::Some(x) = ENUM1 {let _ = x + 1;} + if let Enum1::Some(x) = ENUM1 {let _ = x + 1usize;} + + let _ = Enum2::Some(1); // ok + let _: Enum2 = Enum2::Some(1); // ok + let _: Enum2 = Enum2::Some(1); // ok + + let _ = ENUM2; + let _: Enum2 = ENUM2; // ok + let _: Enum2 = ENUM2; // ok + let _: Enum2 = Enum2::Some(0); // ok + if let Enum2::Some(x) = ENUM2 {let _ = x;} // ok + if let Enum2::Some(x) = ENUM2 {let _: usize = x;} // ok + if let Enum2::Some(x) = ENUM2 {let _ = x + 1;} // ok + if let Enum2::Some(x) = ENUM2 {let _ = x + 1usize;} // ok + + let _ = ENUM3; + let _: Enum3 = ENUM3; // ok + let _: Enum3 = ENUM3; // { dg-error ".E0658." "" { target *-*-* } } + let _: Enum3 = ENUM3; // ok + let _: Enum3 = Enum3::Ok(0); // { dg-error ".E0658." "" { target *-*-* } } + let _: Enum3 = Enum3::Ok(0); // { dg-error ".E0658." "" { target *-*-* } } + if let Enum3::Ok(x) = ENUM3 {let _ = x;} // ok + if let Enum3::Ok(x) = ENUM3 {let _: isize = x;} // ok + if let Enum3::Ok(x) = ENUM3 {let _ = x + 1;} // ok + // Note the aforementioned leak. + if let Enum3::Err(x) = ENUM3B {let _: usize = x;} // ok + let _: Enum3 = Enum3::Err(0); // ok + if let Enum3::Err(x) = ENUM3B {let _ = x + 1;} // ok + if let Enum3::Err(x) = ENUM3B {let _ = x + 1usize;} // ok + + let _ = ENUM4; + let _: Enum4 = Enum4::Some(1); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + let _ = ENUM4; + let _: Enum4 = ENUM4; // { dg-error "" "" { target *-*-* } } + let _: Enum4 = ENUM4; // { dg-error "" "" { target *-*-* } } + let _: Enum4 = Enum4::Some(0); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + + let _ = ENUM5; + let _: Enum5 = Enum5::Some(1); // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + let _ = ENUM5; + let _: Enum5 = ENUM5; // { dg-error "" "" { target *-*-* } } + let _: Enum5 = ENUM5; // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } + let _: Enum5 = Enum5::Some(0); // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-error ".E0658." "" { target *-*-* } .-2 } + + let _: Enum6 = Enum6::Some(1); // ok + let _: Enum6 = Enum6::Some(0); // ok + + let _: Box1 = Box1::new(1); // { dg-error ".E0658." "" { target *-*-* } } + let _: Box1 = Box1::new(1); // ok + + let _: Box2 = Box2::new(1); // ok + let _: Box2 = Box2::new(1); // ok + + let _: Box3 = Box3::new(1); // ok +} + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/missing-const-stability.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/missing-const-stability.rs new file mode 100644 index 000000000000..be907a96a047 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/missing-const-stability.rs @@ -0,0 +1,13 @@ +#![feature(staged_api)] + +#![stable(feature = "rust1", since = "1.0.0")] + +#[stable(feature = "foo", since = "1.0.0")] +pub const fn foo() {} +// { dg-error "" "" { target *-*-* } .-1 } + +#[unstable(feature = "bar", issue = "none")] +pub const fn bar() {} // ok + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/missing-stability-attr-at-top-level.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/missing-stability-attr-at-top-level.rs new file mode 100644 index 000000000000..07505448ec24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/missing-stability-attr-at-top-level.rs @@ -0,0 +1,5 @@ +#![feature(staged_api)] +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-issue-43027.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-issue-43027.rs new file mode 100644 index 000000000000..e291ad7f21a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-issue-43027.rs @@ -0,0 +1,11 @@ +#![feature(staged_api)] +#![stable(feature = "test", since = "0")] + +#[stable(feature = "test", since = "0")] +pub struct Reverse(pub T); // { dg-error "" "" { target *-*-* } } + +fn main() { + // Make sure the field is used to fill the stability cache + Reverse(0).0; +} + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-issue.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-issue.rs new file mode 100644 index 000000000000..0cb4fc156a44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-issue.rs @@ -0,0 +1,13 @@ +// aux-build:stability_attribute_issue.rs +#![deny(deprecated)] + +extern crate stability_attribute_issue; +use stability_attribute_issue::*; + +fn main() { + unstable(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } + unstable_msg(); +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-non-staged-force-unstable.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-non-staged-force-unstable.rs new file mode 100644 index 000000000000..0629af3ba0df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-non-staged-force-unstable.rs @@ -0,0 +1,7 @@ +// compile-flags:-Zforce-unstable-if-unmarked + +#[unstable()] // { dg-error ".E0734." "" { target *-*-* } } +#[stable()] // { dg-error ".E0734." "" { target *-*-* } } +#[rustc_deprecated()] // { dg-error ".E0734." "" { target *-*-* } } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-non-staged.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-non-staged.rs new file mode 100644 index 000000000000..fcddff37bf04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-non-staged.rs @@ -0,0 +1,5 @@ +#[unstable()] // { dg-error ".E0734." "" { target *-*-* } } +#[stable()] // { dg-error ".E0734." "" { target *-*-* } } +#[rustc_deprecated()] // { dg-error ".E0734." "" { target *-*-* } } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity-2.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity-2.rs new file mode 100644 index 000000000000..719bc8124e96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity-2.rs @@ -0,0 +1,18 @@ +// More checks that stability attributes are used correctly + +#![feature(staged_api)] + +#![stable(feature = "stable_test_feature", since = "1.0.0")] + +#[stable(feature = "a", feature = "b", since = "1.0.0")] // { dg-error ".E0538." "" { target *-*-* } } +fn f1() { } + +#[stable(feature = "a", sinse = "1.0.0")] // { dg-error ".E0541." "" { target *-*-* } } +fn f2() { } + +#[unstable(feature = "a", issue = "no")] +// { dg-error ".E0545." "" { target *-*-* } .-1 } +fn f3() { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity-3.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity-3.rs new file mode 100644 index 000000000000..4b71f2a9c00b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity-3.rs @@ -0,0 +1,13 @@ +// More checks that stability attributes are used correctly + +#![feature(staged_api)] + +#![stable(feature = "stable_test_feature", since = "1.0.0")] + +#[macro_export] +macro_rules! mac { // { dg-error "" "" { target *-*-* } } + () => () +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity-4.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity-4.rs new file mode 100644 index 000000000000..91198b1be8be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity-4.rs @@ -0,0 +1,30 @@ +// Various checks that stability attributes are used correctly, per RFC 507 + +#![feature(staged_api)] + +#![stable(feature = "rust1", since = "1.0.0")] + +mod bogus_attribute_types_2 { + #[unstable] // { dg-error "" "" { target *-*-* } } + fn f1() { } + + #[unstable = "b"] // { dg-error "" "" { target *-*-* } } + fn f2() { } + + #[stable] // { dg-error "" "" { target *-*-* } } + fn f3() { } + + #[stable = "a"] // { dg-error "" "" { target *-*-* } } + fn f4() { } + + #[stable(feature = "a", since = "b")] + #[rustc_deprecated] // { dg-error "" "" { target *-*-* } } + fn f5() { } + + #[stable(feature = "a", since = "b")] + #[rustc_deprecated = "a"] // { dg-error "" "" { target *-*-* } } + fn f6() { } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity.rs new file mode 100644 index 000000000000..3a0db5870330 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-sanity.rs @@ -0,0 +1,73 @@ +// Various checks that stability attributes are used correctly, per RFC 507 + +#![feature(const_fn, staged_api)] + +#![stable(feature = "rust1", since = "1.0.0")] + +mod bogus_attribute_types_1 { + #[stable(feature = "a", since = "b", reason)] // { dg-error ".E0541." "" { target *-*-* } } + fn f1() { } + + #[stable(feature = "a", since)] // { dg-error ".E0539." "" { target *-*-* } } + fn f2() { } + + #[stable(feature, since = "a")] // { dg-error ".E0539." "" { target *-*-* } } + fn f3() { } + + #[stable(feature = "a", since(b))] // { dg-error ".E0539." "" { target *-*-* } } + fn f5() { } + + #[stable(feature(b), since = "a")] // { dg-error ".E0539." "" { target *-*-* } } + fn f6() { } +} + +mod missing_feature_names { + #[unstable(issue = "none")] // { dg-error ".E0546." "" { target *-*-* } } + fn f1() { } + + #[unstable(feature = "b")] // { dg-error ".E0547." "" { target *-*-* } } + fn f2() { } + + #[stable(since = "a")] // { dg-error ".E0546." "" { target *-*-* } } + fn f3() { } +} + +mod missing_version { + #[stable(feature = "a")] // { dg-error ".E0542." "" { target *-*-* } } + fn f1() { } + + #[stable(feature = "a", since = "b")] + #[rustc_deprecated(reason = "a")] // { dg-error ".E0542." "" { target *-*-* } } + fn f2() { } + + #[stable(feature = "a", since = "b")] + #[rustc_deprecated(since = "a")] // { dg-error ".E0543." "" { target *-*-* } } + fn f3() { } +} + +#[unstable(feature = "b", issue = "none")] +#[stable(feature = "a", since = "b")] // { dg-error ".E0544." "" { target *-*-* } } +fn multiple1() { } + +#[unstable(feature = "b", issue = "none")] +#[unstable(feature = "b", issue = "none")] // { dg-error ".E0544." "" { target *-*-* } } +fn multiple2() { } + +#[stable(feature = "a", since = "b")] +#[stable(feature = "a", since = "b")] // { dg-error ".E0544." "" { target *-*-* } } +fn multiple3() { } + +#[stable(feature = "a", since = "b")] +#[rustc_deprecated(since = "b", reason = "text")] +#[rustc_deprecated(since = "b", reason = "text")] // { dg-error ".E0550." "" { target *-*-* } } +#[rustc_const_unstable(feature = "c", issue = "none")] +#[rustc_const_unstable(feature = "d", issue = "none")] // { dg-error ".E0544." "" { target *-*-* } } +pub const fn multiple4() { } +// { dg-error "" "" { target *-*-* } .-1 } + +#[rustc_deprecated(since = "a", reason = "text")] +fn deprecated_without_unstable_or_stable() { } +// { dg-error ".E0549." "" { target *-*-* } .-2 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-trait-impl.rs b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-trait-impl.rs new file mode 100644 index 000000000000..b4e978133d80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-attribute/stability-attribute-trait-impl.rs @@ -0,0 +1,29 @@ +#![feature(staged_api)] + +#[stable(feature = "x", since = "1")] +struct StableType; + +#[unstable(feature = "x", issue = "none")] +struct UnstableType; + +#[stable(feature = "x", since = "1")] +trait StableTrait {} + +#[unstable(feature = "x", issue = "none")] +trait UnstableTrait {} + +#[unstable(feature = "x", issue = "none")] +impl UnstableTrait for UnstableType {} + +#[unstable(feature = "x", issue = "none")] +impl StableTrait for UnstableType {} + +#[unstable(feature = "x", issue = "none")] +impl UnstableTrait for StableType {} + +#[unstable(feature = "x", issue = "none")] +// { dg-error "" "" { target *-*-* } .-1 } +impl StableTrait for StableType {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/stability-in-private-module.rs b/gcc/testsuite/rust/rustc/ui/stability-in-private-module.rs new file mode 100644 index 000000000000..aa4187cc3612 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stability-in-private-module.rs @@ -0,0 +1,5 @@ +fn main() { + let _ = std::thread::thread_info::current_thread(); +// { dg-error ".E0603." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/stable-addr-of.rs b/gcc/testsuite/rust/rustc/ui/stable-addr-of.rs new file mode 100644 index 000000000000..d5147145251f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stable-addr-of.rs @@ -0,0 +1,9 @@ +// run-pass +// Issue #2040 + + +pub fn main() { + let foo: isize = 1; + assert_eq!(&foo as *const isize, &foo as *const isize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/stable-features.rs b/gcc/testsuite/rust/rustc/ui/stable-features.rs new file mode 100644 index 000000000000..7d2f82b2dc27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stable-features.rs @@ -0,0 +1,15 @@ +// Testing that the stable_features lint catches use of stable +// language and lib features. + +#![deny(stable_features)] + +#![feature(test_accepted_feature)] +// { dg-error "" "" { target *-*-* } .-1 } + +#![feature(rust1)] +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + let _foo: Vec<()> = Vec::new(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/auxiliary/issue_24843.rs b/gcc/testsuite/rust/rustc/ui/static/auxiliary/issue_24843.rs new file mode 100644 index 000000000000..a7903c48d104 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/auxiliary/issue_24843.rs @@ -0,0 +1,2 @@ +pub static TEST_STR: &'static str = "Hello world"; + diff --git a/gcc/testsuite/rust/rustc/ui/static/auxiliary/static-priv-by-default.rs b/gcc/testsuite/rust/rustc/ui/static/auxiliary/static-priv-by-default.rs new file mode 100644 index 000000000000..7495145d3cbb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/auxiliary/static-priv-by-default.rs @@ -0,0 +1,28 @@ +// aux-build:static_priv_by_default.rs + +extern crate static_priv_by_default; + +mod child { + pub mod childs_child { + static private: isize = 0; + pub static public: isize = 0; + } +} + +fn foo(_: isize) {} + +fn full_ref() { + foo(static_priv_by_default::private); // { dg-error "" "" { target *-*-* } } + foo(static_priv_by_default::public); + foo(child::childs_child::private); // { dg-error "" "" { target *-*-* } } + foo(child::childs_child::public); +} + +fn medium_ref() { + use child::childs_child; + foo(childs_child::private); // { dg-error "" "" { target *-*-* } } + foo(childs_child::public); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/static/auxiliary/static_priv_by_default.rs b/gcc/testsuite/rust/rustc/ui/static/auxiliary/static_priv_by_default.rs new file mode 100644 index 000000000000..003f6f104fbb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/auxiliary/static_priv_by_default.rs @@ -0,0 +1,52 @@ +#![crate_type = "lib"] + +static private: isize = 0; +pub static public: isize = 0; + +pub struct A(()); + +impl A { + fn foo() {} +} + +mod foo { + pub static a: isize = 0; + pub fn b() {} + pub struct c; + pub enum d {} + pub type e = isize; + + pub struct A(()); + + impl A { + fn foo() {} + } + + // these are public so the parent can re-export them. + pub static reexported_a: isize = 0; + pub fn reexported_b() {} + pub struct reexported_c; + pub enum reexported_d {} + pub type reexported_e = isize; +} + +pub mod bar { + pub use foo::reexported_a as e; + pub use foo::reexported_b as f; + pub use foo::reexported_c as g; + pub use foo::reexported_d as h; + pub use foo::reexported_e as i; +} + +pub static a: isize = 0; +pub fn b() {} +pub struct c; +pub enum d {} +pub type e = isize; + +static j: isize = 0; +fn k() {} +struct l; +enum m {} +type n = isize; + diff --git a/gcc/testsuite/rust/rustc/ui/static/issue-24843.rs b/gcc/testsuite/rust/rustc/ui/static/issue-24843.rs new file mode 100644 index 000000000000..c04a9d07c76c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/issue-24843.rs @@ -0,0 +1,9 @@ +// aux-build: issue_24843.rs +// check-pass + +extern crate issue_24843; + +static _TEST_STR_2: &'static str = &issue_24843::TEST_STR; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-closures.rs b/gcc/testsuite/rust/rustc/ui/static/static-closures.rs new file mode 100644 index 000000000000..7b9a15f5d3f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-closures.rs @@ -0,0 +1,5 @@ +fn main() { + static || {}; +// { dg-error ".E0697." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-drop-scope.rs b/gcc/testsuite/rust/rustc/ui/static/static-drop-scope.rs new file mode 100644 index 000000000000..3d2af950fb2d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-drop-scope.rs @@ -0,0 +1,40 @@ +#![feature(const_fn)] + +struct WithDtor; + +impl Drop for WithDtor { + fn drop(&mut self) {} +} + +static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor); +// { dg-error ".E0493." "" { target *-*-* } .-1 } +// { dg-error ".E0716." "" { target *-*-* } .-2 } + +const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor); +// { dg-error ".E0493." "" { target *-*-* } .-1 } +// { dg-error ".E0716." "" { target *-*-* } .-2 } + +static EARLY_DROP_S: i32 = (WithDtor, 0).1; +// { dg-error ".E0493." "" { target *-*-* } .-1 } + +const EARLY_DROP_C: i32 = (WithDtor, 0).1; +// { dg-error ".E0493." "" { target *-*-* } .-1 } + +const fn const_drop(_: T) {} +// { dg-error ".E0493." "" { target *-*-* } .-1 } + +const fn const_drop2(x: T) { + (x, ()).1 +// { dg-error ".E0493." "" { target *-*-* } .-1 } +} + +const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1; +// { dg-error ".E0493." "" { target *-*-* } .-1 } + +const HELPER: Option = Some(WithDtor); + +const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1; +// { dg-error ".E0493." "" { target *-*-* } .-1 } + +fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-extern-type.rs b/gcc/testsuite/rust/rustc/ui/static/static-extern-type.rs new file mode 100644 index 000000000000..6f35b83cab92 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-extern-type.rs @@ -0,0 +1,28 @@ +// build-pass (FIXME(62277): could be check-pass?) +#![feature(extern_types)] + +pub mod a { + extern "C" { + pub type StartFn; + pub static start: StartFn; + } +} + +pub mod b { + #[repr(transparent)] + pub struct TransparentType(::a::StartFn); + extern "C" { + pub static start: TransparentType; + } +} + +pub mod c { + #[repr(C)] + pub struct CType(u32, ::b::TransparentType); + extern "C" { + pub static start: CType; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-items-cant-move.rs b/gcc/testsuite/rust/rustc/ui/static/static-items-cant-move.rs new file mode 100644 index 000000000000..68b10bf7ae21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-items-cant-move.rs @@ -0,0 +1,20 @@ +// Verifies that static items can't be moved + +struct B; + +struct Foo { + foo: isize, + b: B, +} + +static BAR: Foo = Foo { foo: 5, b: B }; + + +fn test(f: Foo) { + let _f = Foo{foo: 4, ..f}; +} + +fn main() { + test(BAR); // { dg-error ".E0507." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-lifetime-bound.rs b/gcc/testsuite/rust/rustc/ui/static/static-lifetime-bound.rs new file mode 100644 index 000000000000..7769742054be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-lifetime-bound.rs @@ -0,0 +1,7 @@ +fn f<'a: 'static>(_: &'a i32) {} // { dg-warning "" "" { target *-*-* } } + +fn main() { + let x = 0; + f(&x); // { dg-error ".E0597." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-lifetime.rs b/gcc/testsuite/rust/rustc/ui/static/static-lifetime.rs new file mode 100644 index 000000000000..34b66215a30f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-lifetime.rs @@ -0,0 +1,7 @@ +pub trait Arbitrary: Sized + 'static {} + +impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} // { dg-error ".E0478." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-method-privacy.rs b/gcc/testsuite/rust/rustc/ui/static/static-method-privacy.rs new file mode 100644 index 000000000000..fc60fe694dd5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-method-privacy.rs @@ -0,0 +1,11 @@ +mod a { + pub struct S; + impl S { + fn new() -> S { S } + } +} + +fn main() { + let _ = a::S::new(); // { dg-error ".E0624." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-mut-bad-types.rs b/gcc/testsuite/rust/rustc/ui/static/static-mut-bad-types.rs new file mode 100644 index 000000000000..6ce3e4f4db69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-mut-bad-types.rs @@ -0,0 +1,8 @@ +static mut a: isize = 3; + +fn main() { + unsafe { + a = true; // { dg-error ".E0308." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-mut-foreign-requires-unsafe.rs b/gcc/testsuite/rust/rustc/ui/static/static-mut-foreign-requires-unsafe.rs new file mode 100644 index 000000000000..2eecfa289406 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-mut-foreign-requires-unsafe.rs @@ -0,0 +1,10 @@ +extern { + static mut a: i32; +} + +fn main() { + a += 3; // { dg-error ".E0133." "" { target *-*-* } } + a = 4; // { dg-error ".E0133." "" { target *-*-* } } + let _b = a; // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-mut-not-constant.rs b/gcc/testsuite/rust/rustc/ui/static/static-mut-not-constant.rs new file mode 100644 index 000000000000..78049f616b25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-mut-not-constant.rs @@ -0,0 +1,7 @@ +#![feature(box_syntax)] + +static mut a: Box = box 3; +// { dg-error ".E0010." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-mut-not-pat.rs b/gcc/testsuite/rust/rustc/ui/static/static-mut-not-pat.rs new file mode 100644 index 000000000000..cd88737989ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-mut-not-pat.rs @@ -0,0 +1,44 @@ +// Constants (static variables) can be used to match in patterns, but mutable +// statics cannot. This ensures that there's some form of error if this is +// attempted. + +static mut a: isize = 3; + +fn main() { + // If they can't be matched against, then it's possible to capture the same + // name as a variable, hence this should be an unreachable pattern situation + // instead of spitting out a custom error about some identifier collisions + // (we should allow shadowing) + match 4 { + a => {} // { dg-error ".E0530." "" { target *-*-* } } + _ => {} + } +} + +struct NewBool(bool); +enum Direction { + North, + East, + South, + West +} +const NEW_FALSE: NewBool = NewBool(false); +struct Foo { + bar: Option, + baz: NewBool +} + +static mut STATIC_MUT_FOO: Foo = Foo { bar: Some(Direction::West), baz: NEW_FALSE }; + +fn mutable_statics() { + match (Foo { bar: Some(Direction::North), baz: NewBool(true) }) { + Foo { bar: None, baz: NewBool(true) } => (), + STATIC_MUT_FOO => (), +// { dg-error ".E0530." "" { target *-*-* } .-1 } + Foo { bar: Some(Direction::South), .. } => (), + Foo { bar: Some(EAST), .. } => (), + Foo { bar: Some(Direction::North), baz: NewBool(true) } => (), + Foo { bar: Some(EAST), baz: NewBool(false) } => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-mut-requires-unsafe.rs b/gcc/testsuite/rust/rustc/ui/static/static-mut-requires-unsafe.rs new file mode 100644 index 000000000000..f621d7e0fd3e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-mut-requires-unsafe.rs @@ -0,0 +1,8 @@ +static mut a: isize = 3; + +fn main() { + a += 3; // { dg-error ".E0133." "" { target *-*-* } } + a = 4; // { dg-error ".E0133." "" { target *-*-* } } + let _b = a; // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-priv-by-default2.rs b/gcc/testsuite/rust/rustc/ui/static/static-priv-by-default2.rs new file mode 100644 index 000000000000..70967bbaa2ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-priv-by-default2.rs @@ -0,0 +1,31 @@ +// aux-build:static_priv_by_default.rs + +extern crate static_priv_by_default; + +mod child { + pub mod childs_child { + static private: isize = 0; + pub static public: isize = 0; + } +} + +fn foo(_: T) {} + +fn test1() { + use child::childs_child::private; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + use child::childs_child::public; + + foo(private); +} + +fn test2() { + use static_priv_by_default::private; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + use static_priv_by_default::public; + + foo(private); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-reference-to-fn-1.rs b/gcc/testsuite/rust/rustc/ui/static/static-reference-to-fn-1.rs new file mode 100644 index 000000000000..8e0f6bd862da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-reference-to-fn-1.rs @@ -0,0 +1,25 @@ +struct A<'a> { + func: &'a fn() -> Option +} + +impl<'a> A<'a> { + fn call(&self) -> Option { + (*self.func)() + } +} + +fn foo() -> Option { + None +} + +fn create() -> A<'static> { + A { + func: &foo, // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn main() { + let a = create(); + a.call(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-reference-to-fn-2.rs b/gcc/testsuite/rust/rustc/ui/static/static-reference-to-fn-2.rs new file mode 100644 index 000000000000..b09fa21465c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-reference-to-fn-2.rs @@ -0,0 +1,55 @@ +fn id(x: T) -> T { x } + +struct StateMachineIter<'a> { + statefn: &'a StateMachineFunc<'a> +} + +type StateMachineFunc<'a> = fn(&mut StateMachineIter<'a>) -> Option<&'static str>; + +impl<'a> Iterator for StateMachineIter<'a> { + type Item = &'static str; + + fn next(&mut self) -> Option<&'static str> { + return (*self.statefn)(self); + } +} + +fn state1(self_: &mut StateMachineIter) -> Option<&'static str> { + self_.statefn = &id(state2 as StateMachineFunc); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + return Some("state1"); +} + +fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> { + self_.statefn = &id(state3 as StateMachineFunc); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + return Some("state2"); +} + +fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> { + self_.statefn = &id(finished as StateMachineFunc); +// { dg-error ".E0716." "" { target *-*-* } .-1 } + return Some("state3"); +} + +fn finished(_: &mut StateMachineIter) -> Option<(&'static str)> { + return None; +} + +fn state_iter() -> StateMachineIter<'static> { + StateMachineIter { +// { dg-error ".E0515." "" { target *-*-* } .-1 } + statefn: &id(state1 as StateMachineFunc) + } +} + + +fn main() { + let mut it = state_iter(); + println!("{:?}",it.next()); + println!("{:?}",it.next()); + println!("{:?}",it.next()); + println!("{:?}",it.next()); + println!("{:?}",it.next()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-region-bound.rs b/gcc/testsuite/rust/rustc/ui/static/static-region-bound.rs new file mode 100644 index 000000000000..972e9f299fda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-region-bound.rs @@ -0,0 +1,13 @@ +#![feature(box_syntax)] + +fn id(x: T) -> T { x } + +fn f(_: T) {} + +fn main() { + let x: Box<_> = box 3; + f(x); + let x = &id(3); // { dg-error ".E0716." "" { target *-*-* } } + f(x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/static/static-vec-repeat-not-constant.rs b/gcc/testsuite/rust/rustc/ui/static/static-vec-repeat-not-constant.rs new file mode 100644 index 000000000000..d40427abb9c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static/static-vec-repeat-not-constant.rs @@ -0,0 +1,7 @@ +fn foo() -> isize { 23 } + +static a: [isize; 2] = [foo(); 2]; +// { dg-error ".E0015." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/static_sized_requirement.rs b/gcc/testsuite/rust/rustc/ui/static_sized_requirement.rs new file mode 100644 index 000000000000..ea4be73077f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/static_sized_requirement.rs @@ -0,0 +1,13 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(no_core, lang_items)] +#![no_core] +#![crate_type = "lib"] + +#[lang = "sized"] +trait Sized {} + +extern { + pub static A: u32; +} + diff --git a/gcc/testsuite/rust/rustc/ui/staticness-mismatch.rs b/gcc/testsuite/rust/rustc/ui/staticness-mismatch.rs new file mode 100644 index 000000000000..88b7a5632632 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/staticness-mismatch.rs @@ -0,0 +1,12 @@ +trait Foo { + fn dummy(&self) { } + fn bar(); +} + +impl Foo for isize { + fn bar(&self) {} +// { dg-error ".E0185." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static-function-pointer-aux.rs b/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static-function-pointer-aux.rs new file mode 100644 index 000000000000..bb24ba3ba0c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static-function-pointer-aux.rs @@ -0,0 +1,5 @@ +pub fn f(x: isize) -> isize { -x } + +pub static F: fn(isize) -> isize = f; +pub static mut MutF: fn(isize) -> isize = f; + diff --git a/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static-methods-crate.rs b/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static-methods-crate.rs new file mode 100644 index 000000000000..43efe4d52871 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static-methods-crate.rs @@ -0,0 +1,30 @@ +#![crate_name="static_methods_crate"] +#![crate_type = "lib"] + +pub trait read: Sized { + fn readMaybe(s: String) -> Option; +} + +impl read for isize { + fn readMaybe(s: String) -> Option { + s.parse().ok() + } +} + +impl read for bool { + fn readMaybe(s: String) -> Option { + match &*s { + "true" => Some(true), + "false" => Some(false), + _ => None + } + } +} + +pub fn read(s: String) -> T { + match read::readMaybe(s) { + Some(x) => x, + _ => panic!("read panicked!") + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static_fn_inline_xc_aux.rs b/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static_fn_inline_xc_aux.rs new file mode 100644 index 000000000000..5216c8d9b694 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static_fn_inline_xc_aux.rs @@ -0,0 +1,13 @@ +pub mod num { + pub trait Num2 { + fn from_int2(n: isize) -> Self; + } +} + +pub mod f64 { + impl ::num::Num2 for f64 { + #[inline] + fn from_int2(n: isize) -> f64 { return n as f64; } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static_fn_trait_xc_aux.rs b/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static_fn_trait_xc_aux.rs new file mode 100644 index 000000000000..bcd407e24494 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static_fn_trait_xc_aux.rs @@ -0,0 +1,12 @@ +pub mod num { + pub trait Num2 { + fn from_int2(n: isize) -> Self; + } +} + +pub mod f64 { + impl ::num::Num2 for f64 { + fn from_int2(n: isize) -> f64 { return n as f64; } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static_mut_xc.rs b/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static_mut_xc.rs new file mode 100644 index 000000000000..c0e7f5decee8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/auxiliary/static_mut_xc.rs @@ -0,0 +1,2 @@ +pub static mut a: isize = 3; + diff --git a/gcc/testsuite/rust/rustc/ui/statics/static-fn-inline-xc.rs b/gcc/testsuite/rust/rustc/ui/statics/static-fn-inline-xc.rs new file mode 100644 index 000000000000..6c43248f52ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/static-fn-inline-xc.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:static_fn_inline_xc_aux.rs + +// pretty-expanded FIXME #23616 + +extern crate static_fn_inline_xc_aux as mycore; + +use mycore::num; + +pub fn main() { + let _1: f64 = num::Num2::from_int2(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/static-fn-trait-xc.rs b/gcc/testsuite/rust/rustc/ui/statics/static-fn-trait-xc.rs new file mode 100644 index 000000000000..f76324d8b4b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/static-fn-trait-xc.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:static_fn_trait_xc_aux.rs + +// pretty-expanded FIXME #23616 + +extern crate static_fn_trait_xc_aux as mycore; + +use mycore::num; + +pub fn main() { + let _1: f64 = num::Num2::from_int2(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/static-function-pointer-xc.rs b/gcc/testsuite/rust/rustc/ui/statics/static-function-pointer-xc.rs new file mode 100644 index 000000000000..6bf09776d5ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/static-function-pointer-xc.rs @@ -0,0 +1,18 @@ +// run-pass +// aux-build:static-function-pointer-aux.rs + +extern crate static_function_pointer_aux as aux; + +fn f(x: isize) -> isize { x } + +pub fn main() { + assert_eq!(aux::F(42), -42); + unsafe { + assert_eq!(aux::MutF(42), -42); + aux::MutF = f; + assert_eq!(aux::MutF(42), 42); + aux::MutF = aux::f; + assert_eq!(aux::MutF(42), -42); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/static-function-pointer.rs b/gcc/testsuite/rust/rustc/ui/statics/static-function-pointer.rs new file mode 100644 index 000000000000..14fc0f30d3de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/static-function-pointer.rs @@ -0,0 +1,17 @@ +// run-pass + +fn f(x: isize) -> isize { x } +fn g(x: isize) -> isize { 2 * x } + +static F: fn(isize) -> isize = f; +static mut G: fn(isize) -> isize = f; + +pub fn main() { + assert_eq!(F(42), 42); + unsafe { + assert_eq!(G(42), 42); + G = g; + assert_eq!(G(42), 84); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/static-impl.rs b/gcc/testsuite/rust/rustc/ui/statics/static-impl.rs new file mode 100644 index 000000000000..a4aea7e3b4c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/static-impl.rs @@ -0,0 +1,67 @@ +// run-pass +#![allow(non_camel_case_types)] + + + + +pub trait plus { + fn plus(&self) -> isize; +} + +mod a { + use plus; + impl plus for usize { fn plus(&self) -> isize { *self as isize + 20 } } +} + +mod b { + use plus; + impl plus for String { fn plus(&self) -> isize { 200 } } +} + +trait uint_utils { + fn str(&self) -> String; + fn multi(&self, f: F) where F: FnMut(usize); +} + +impl uint_utils for usize { + fn str(&self) -> String { + self.to_string() + } + fn multi(&self, mut f: F) where F: FnMut(usize) { + let mut c = 0_usize; + while c < *self { f(c); c += 1_usize; } + } +} + +trait vec_utils { + fn length_(&self, ) -> usize; + fn iter_(&self, f: F) where F: FnMut(&T); + fn map_(&self, f: F) -> Vec where F: FnMut(&T) -> U; +} + +impl vec_utils for Vec { + fn length_(&self) -> usize { self.len() } + fn iter_(&self, mut f: F) where F: FnMut(&T) { for x in self { f(x); } } + fn map_(&self, mut f: F) -> Vec where F: FnMut(&T) -> U { + let mut r = Vec::new(); + for elt in self { + r.push(f(elt)); + } + r + } +} + +pub fn main() { + assert_eq!(10_usize.plus(), 30); + assert_eq!(("hi".to_string()).plus(), 200); + + assert_eq!((vec![1]).length_().str(), "1".to_string()); + let vect = vec![3, 4].map_(|a| *a + 4); + assert_eq!(vect[0], 7); + let vect = (vec![3, 4]).map_::(|a| *a as usize + 4_usize); + assert_eq!(vect[0], 7_usize); + let mut x = 0_usize; + 10_usize.multi(|_n| x += 2_usize ); + assert_eq!(x, 20_usize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/static-method-in-trait-with-tps-intracrate.rs b/gcc/testsuite/rust/rustc/ui/statics/static-method-in-trait-with-tps-intracrate.rs new file mode 100644 index 000000000000..9d9f9ad5f4ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/static-method-in-trait-with-tps-intracrate.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] + +trait Deserializer { + fn read_int(&self) -> isize; +} + +trait Deserializable { + fn deserialize(d: &D) -> Self; +} + +impl Deserializable for isize { + fn deserialize(d: &D) -> isize { + return d.read_int(); + } +} + +struct FromThinAir { dummy: () } + +impl Deserializer for FromThinAir { + fn read_int(&self) -> isize { 22 } +} + +pub fn main() { + let d = FromThinAir { dummy: () }; + let i: isize = Deserializable::deserialize(&d); + assert_eq!(i, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/static-method-xcrate.rs b/gcc/testsuite/rust/rustc/ui/statics/static-method-xcrate.rs new file mode 100644 index 000000000000..477555e53670 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/static-method-xcrate.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:static-methods-crate.rs + +extern crate static_methods_crate; + +use static_methods_crate::read; + +pub fn main() { + let result: isize = read("5".to_string()); + assert_eq!(result, 5); + assert_eq!(read::readMaybe("false".to_string()), Some(false)); + assert_eq!(read::readMaybe("foo".to_string()), None::); +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/static-methods-in-traits.rs b/gcc/testsuite/rust/rustc/ui/statics/static-methods-in-traits.rs new file mode 100644 index 000000000000..0942bf1ebc23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/static-methods-in-traits.rs @@ -0,0 +1,27 @@ +// run-pass + +mod a { + pub trait Foo { + fn foo() -> Self; + } + + impl Foo for isize { + fn foo() -> isize { + 3 + } + } + + impl Foo for usize { + fn foo() -> usize { + 5 + } + } +} + +pub fn main() { + let x: isize = a::Foo::foo(); + let y: usize = a::Foo::foo(); + assert_eq!(x, 3); + assert_eq!(y, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/static-methods-in-traits2.rs b/gcc/testsuite/rust/rustc/ui/statics/static-methods-in-traits2.rs new file mode 100644 index 000000000000..b6b02186698f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/static-methods-in-traits2.rs @@ -0,0 +1,23 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub trait Number: NumConv { + fn from(n: T) -> Self; +} + +impl Number for f64 { + fn from(n: T) -> f64 { n.to_float() } +} + +pub trait NumConv { + fn to_float(&self) -> f64; +} + +impl NumConv for f64 { + fn to_float(&self) -> f64 { *self } +} + +pub fn main() { + let _: f64 = Number::from(0.0f64); +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/static-mut-xc.rs b/gcc/testsuite/rust/rustc/ui/statics/static-mut-xc.rs new file mode 100644 index 000000000000..4b6c2e33116e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/static-mut-xc.rs @@ -0,0 +1,40 @@ +// run-pass +#![allow(non_upper_case_globals)] + +// Constants (static variables) can be used to match in patterns, but mutable +// statics cannot. This ensures that there's some form of error if this is +// attempted. + +// aux-build:static_mut_xc.rs + + +extern crate static_mut_xc; + +unsafe fn static_bound(_: &'static isize) {} + +fn static_bound_set(a: &'static mut isize) { + *a = 3; +} + +unsafe fn run() { + assert_eq!(static_mut_xc::a, 3); + static_mut_xc::a = 4; + assert_eq!(static_mut_xc::a, 4); + static_mut_xc::a += 1; + assert_eq!(static_mut_xc::a, 5); + static_mut_xc::a *= 3; + assert_eq!(static_mut_xc::a, 15); + static_mut_xc::a = -3; + assert_eq!(static_mut_xc::a, -3); + static_bound(&static_mut_xc::a); + static_bound_set(&mut static_mut_xc::a); +} + +pub fn main() { + unsafe { run() } +} + +pub mod inner { + pub static mut a: isize = 4; +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/static-promotion.rs b/gcc/testsuite/rust/rustc/ui/statics/static-promotion.rs new file mode 100644 index 000000000000..cd66723eef64 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/static-promotion.rs @@ -0,0 +1,35 @@ +// run-pass + +// Use of global static variables in literal values should be allowed for +// promotion. +// This test is to demonstrate the issue raised in +// https://github.com/rust-lang/rust/issues/70584 + +// Literal values were previously promoted into local static values when +// other global static variables are used. + +struct A(&'static T); +struct B { + x: &'static T, +} +static STR: &'static [u8] = b"hi"; +static C: A>> = { + A(&B { + x: &B { x: STR }, + }) +}; + +pub struct Slice(&'static [i32]); + +static CONTENT: i32 = 42; +pub static CONTENT_MAP: Slice = Slice(&[CONTENT]); + +pub static FOO: (i32, i32) = (42, 43); +pub static CONTENT_MAP2: Slice = Slice(&[FOO.0]); + +fn main() { + assert_eq!(b"hi", C.0.x.x); + assert_eq!(&[42], CONTENT_MAP.0); + assert_eq!(&[42], CONTENT_MAP2.0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/static-recursive.rs b/gcc/testsuite/rust/rustc/ui/statics/static-recursive.rs new file mode 100644 index 000000000000..a1d7c02e0889 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/static-recursive.rs @@ -0,0 +1,37 @@ +// run-pass +static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 }; + +struct StaticDoubleLinked { + prev: &'static StaticDoubleLinked, + next: &'static StaticDoubleLinked, + data: i32, + head: bool +} + +static L1: StaticDoubleLinked = StaticDoubleLinked{prev: &L3, next: &L2, data: 1, head: true}; +static L2: StaticDoubleLinked = StaticDoubleLinked{prev: &L1, next: &L3, data: 2, head: false}; +static L3: StaticDoubleLinked = StaticDoubleLinked{prev: &L2, next: &L1, data: 3, head: false}; + + +pub fn main() { + unsafe { assert_eq!(S, *(S as *const *const u8)); } + + let mut test_vec = Vec::new(); + let mut cur = &L1; + loop { + test_vec.push(cur.data); + cur = cur.next; + if cur.head { break } + } + assert_eq!(&test_vec, &[1,2,3]); + + let mut test_vec = Vec::new(); + let mut cur = &L1; + loop { + cur = cur.prev; + test_vec.push(cur.data); + if cur.head { break } + } + assert_eq!(&test_vec, &[3,2,1]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/statics/uninhabited-static.rs b/gcc/testsuite/rust/rustc/ui/statics/uninhabited-static.rs new file mode 100644 index 000000000000..32fc93d2e4f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/statics/uninhabited-static.rs @@ -0,0 +1,18 @@ +#![feature(never_type)] +#![deny(uninhabited_static)] + +enum Void {} +extern { + static VOID: Void; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + static NEVER: !; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +static VOID2: Void = unsafe { std::mem::transmute(()) }; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +static NEVER2: Void = unsafe { std::mem::transmute(()) }; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/std-backtrace.rs b/gcc/testsuite/rust/rustc/ui/std-backtrace.rs new file mode 100644 index 000000000000..cfadfd055d25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/std-backtrace.rs @@ -0,0 +1,76 @@ +// run-pass +// ignore-android FIXME #17520 +// ignore-cloudabi spawning processes is not supported +// ignore-emscripten spawning processes is not supported +// ignore-openbsd no support for libbacktrace without filename +// ignore-sgx no processes +// ignore-msvc see #62897 and `backtrace-debuginfo.rs` test +// compile-flags:-g + +#![feature(backtrace)] + +use std::env; +use std::process::Command; +use std::str; + +fn main() { + let args: Vec = env::args().collect(); + if args.len() >= 2 && args[1] == "force" { + println!("stack backtrace:\n{}", std::backtrace::Backtrace::force_capture()); + } else if args.len() >= 2 { + println!("stack backtrace:\n{}", std::backtrace::Backtrace::capture()); + } else { + runtest(&args[0]); + println!("test ok"); + } +} + +fn runtest(me: &str) { + env::remove_var("RUST_BACKTRACE"); + env::remove_var("RUST_LIB_BACKTRACE"); + + let p = Command::new(me).arg("a").env("RUST_BACKTRACE", "1").output().unwrap(); + assert!(p.status.success()); + assert!(String::from_utf8_lossy(&p.stdout).contains("stack backtrace:\n")); + assert!(String::from_utf8_lossy(&p.stdout).contains("backtrace::main")); + + let p = Command::new(me).arg("a").env("RUST_BACKTRACE", "0").output().unwrap(); + assert!(p.status.success()); + assert!(String::from_utf8_lossy(&p.stdout).contains("disabled backtrace\n")); + + let p = Command::new(me).arg("a").output().unwrap(); + assert!(p.status.success()); + assert!(String::from_utf8_lossy(&p.stdout).contains("disabled backtrace\n")); + + let p = Command::new(me) + .arg("a") + .env("RUST_LIB_BACKTRACE", "1") + .env("RUST_BACKTRACE", "1") + .output() + .unwrap(); + assert!(p.status.success()); + assert!(String::from_utf8_lossy(&p.stdout).contains("stack backtrace:\n")); + + let p = Command::new(me) + .arg("a") + .env("RUST_LIB_BACKTRACE", "0") + .env("RUST_BACKTRACE", "1") + .output() + .unwrap(); + assert!(p.status.success()); + assert!(String::from_utf8_lossy(&p.stdout).contains("disabled backtrace\n")); + + let p = Command::new(me) + .arg("force") + .env("RUST_LIB_BACKTRACE", "0") + .env("RUST_BACKTRACE", "0") + .output() + .unwrap(); + assert!(p.status.success()); + assert!(String::from_utf8_lossy(&p.stdout).contains("stack backtrace:\n")); + + let p = Command::new(me).arg("force").output().unwrap(); + assert!(p.status.success()); + assert!(String::from_utf8_lossy(&p.stdout).contains("stack backtrace:\n")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/std-uncopyable-atomics.rs b/gcc/testsuite/rust/rustc/ui/std-uncopyable-atomics.rs new file mode 100644 index 000000000000..c645bb44374e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/std-uncopyable-atomics.rs @@ -0,0 +1,17 @@ +// Issue #8380 + + +use std::sync::atomic::*; +use std::ptr; + +fn main() { + let x = AtomicBool::new(false); + let x = *&x; // { dg-error ".E0507." "" { target *-*-* } } + let x = AtomicIsize::new(0); + let x = *&x; // { dg-error ".E0507." "" { target *-*-* } } + let x = AtomicUsize::new(0); + let x = *&x; // { dg-error ".E0507." "" { target *-*-* } } + let x: AtomicPtr = AtomicPtr::new(ptr::null_mut()); + let x = *&x; // { dg-error ".E0507." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/stdio-is-blocking.rs b/gcc/testsuite/rust/rustc/ui/stdio-is-blocking.rs new file mode 100644 index 000000000000..62ab7e08128e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stdio-is-blocking.rs @@ -0,0 +1,86 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::env; +use std::io::prelude::*; +use std::process::Command; +use std::thread; + +const THREADS: usize = 20; +const WRITES: usize = 100; +const WRITE_SIZE: usize = 1024 * 32; + +fn main() { + let args = env::args().collect::>(); + if args.len() == 1 { + parent(); + } else { + child(); + } +} + +fn parent() { + let me = env::current_exe().unwrap(); + let mut cmd = Command::new(me); + cmd.arg("run-the-test"); + let output = cmd.output().unwrap(); + assert!(output.status.success()); + assert_eq!(output.stderr.len(), 0); + assert_eq!(output.stdout.len(), WRITES * THREADS * WRITE_SIZE); + for byte in output.stdout.iter() { + assert_eq!(*byte, b'a'); + } +} + +fn child() { + let threads = (0..THREADS).map(|_| { + thread::spawn(|| { + let buf = [b'a'; WRITE_SIZE]; + for _ in 0..WRITES { + write_all(&buf); + } + }) + }).collect::>(); + + for thread in threads { + thread.join().unwrap(); + } +} + +#[cfg(unix)] +fn write_all(buf: &[u8]) { + use std::fs::File; + use std::mem; + use std::os::unix::prelude::*; + + let mut file = unsafe { File::from_raw_fd(1) }; + let res = file.write_all(buf); + mem::forget(file); + res.unwrap(); +} + +#[cfg(windows)] +fn write_all(buf: &[u8]) { + use std::fs::File; + use std::mem; + use std::os::windows::raw::*; + use std::os::windows::prelude::*; + + const STD_OUTPUT_HANDLE: u32 = (-11i32) as u32; + + extern "system" { + fn GetStdHandle(handle: u32) -> HANDLE; + } + + let mut file = unsafe { + let handle = GetStdHandle(STD_OUTPUT_HANDLE); + assert!(!handle.is_null()); + File::from_raw_handle(handle) + }; + let res = file.write_all(buf); + mem::forget(file); + res.unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/stdout-during-shutdown.rs b/gcc/testsuite/rust/rustc/ui/stdout-during-shutdown.rs new file mode 100644 index 000000000000..8e31bfcd826c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stdout-during-shutdown.rs @@ -0,0 +1,20 @@ +// run-pass +// check-run-results +// ignore-emscripten + +// Emscripten doesn't flush its own stdout buffers on exit, which would fail +// this test. So this test is disabled on this platform. +// See https://emscripten.org/docs/getting_started/FAQ.html#what-does-exiting-the-runtime-mean-why-don-t-atexit-s-run + +#![feature(rustc_private)] + +extern crate libc; + +fn main() { + extern "C" fn bye() { + print!(", world!"); + } + unsafe { libc::atexit(bye) }; + print!("hello"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/stmt_expr_attrs_no_feature.rs b/gcc/testsuite/rust/rustc/ui/stmt_expr_attrs_no_feature.rs new file mode 100644 index 000000000000..1c8e4efab5db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/stmt_expr_attrs_no_feature.rs @@ -0,0 +1,142 @@ +#![feature(rustc_attrs)] + +macro_rules! stmt_mac { + () => { + fn b() {} + } +} + +fn main() { + #[rustc_dummy] + fn a() {} + + // Bug: built-in attrs like `rustc_dummy` are not gated on blocks, but other attrs are. + #[rustfmt::skip] // { dg-error ".E0658." "" { target *-*-* } } + { + + } + + #[rustc_dummy] + 5; + + #[rustc_dummy] + stmt_mac!(); +} + +// Check that cfg works right + +#[cfg(unset)] +fn c() { + #[rustc_dummy] + 5; +} + +#[cfg(not(unset))] +fn j() { + #[rustc_dummy] + 5; +} + +#[cfg_attr(not(unset), cfg(unset))] +fn d() { + #[rustc_dummy] + 8; +} + +#[cfg_attr(not(unset), cfg(not(unset)))] +fn i() { + #[rustc_dummy] + 8; +} + +// check that macro expansion and cfg works right + +macro_rules! item_mac { + ($e:ident) => { + fn $e() { + #[rustc_dummy] + 42; + + #[cfg(unset)] + fn f() { + #[rustc_dummy] + 5; + } + + #[cfg(not(unset))] + fn k() { + #[rustc_dummy] + 5; + } + + #[cfg_attr(not(unset), cfg(unset))] + fn g() { + #[rustc_dummy] + 8; + } + + #[cfg_attr(not(unset), cfg(not(unset)))] + fn h() { + #[rustc_dummy] + 8; + } + + } + } +} + +item_mac!(e); + +// check that the gate visitor works right: + +extern { + #[cfg(unset)] + fn x(a: [u8; #[rustc_dummy] 5]); + fn y(a: [u8; #[rustc_dummy] 5]); // { dg-error ".E0658." "" { target *-*-* } } +} + +struct Foo; +impl Foo { + #[cfg(unset)] + const X: u8 = #[rustc_dummy] 5; + const Y: u8 = #[rustc_dummy] 5; // { dg-error ".E0658." "" { target *-*-* } } +} + +trait Bar { + #[cfg(unset)] + const X: [u8; #[rustc_dummy] 5]; + const Y: [u8; #[rustc_dummy] 5]; // { dg-error ".E0658." "" { target *-*-* } } +} + +struct Joyce { + #[cfg(unset)] + field: [u8; #[rustc_dummy] 5], + field2: [u8; #[rustc_dummy] 5] // { dg-error ".E0658." "" { target *-*-* } } +} + +struct Walky( + #[cfg(unset)] [u8; #[rustc_dummy] 5], + [u8; #[rustc_dummy] 5] // { dg-error ".E0658." "" { target *-*-* } } +); + +enum Mike { + Happy( + #[cfg(unset)] [u8; #[rustc_dummy] 5], + [u8; #[rustc_dummy] 5] // { dg-error ".E0658." "" { target *-*-* } } + ), + Angry { + #[cfg(unset)] + field: [u8; #[rustc_dummy] 5], + field2: [u8; #[rustc_dummy] 5] // { dg-error ".E0658." "" { target *-*-* } } + } +} + +fn pat() { + match 5 { + #[cfg(unset)] + 5 => #[rustc_dummy] (), + 6 => #[rustc_dummy] (), // { dg-error ".E0658." "" { target *-*-* } } + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/str/str-array-assignment.rs b/gcc/testsuite/rust/rustc/ui/str/str-array-assignment.rs new file mode 100644 index 000000000000..ce37bf0921ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/str/str-array-assignment.rs @@ -0,0 +1,12 @@ +fn main() { + let s = "abc"; + let t = if true { s[..2] } else { s }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let u: &str = if true { s[..2] } else { s }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let v = s[..2]; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let w: &str = s[..2]; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/str/str-as-char.rs b/gcc/testsuite/rust/rustc/ui/str/str-as-char.rs new file mode 100644 index 000000000000..2bfa21044ddc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/str/str-as-char.rs @@ -0,0 +1,6 @@ +// run-rustfix + +fn main() { + println!('●●'); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/str/str-concat-on-double-ref.rs b/gcc/testsuite/rust/rustc/ui/str/str-concat-on-double-ref.rs new file mode 100644 index 000000000000..9150d0947f8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/str/str-concat-on-double-ref.rs @@ -0,0 +1,8 @@ +fn main() { + let a: &String = &"1".to_owned(); + let b: &str = &"2"; + let c = a + b; +// { dg-error ".E0369." "" { target *-*-* } .-1 } + println!("{:?}", c); +} + diff --git a/gcc/testsuite/rust/rustc/ui/str/str-idx.rs b/gcc/testsuite/rust/rustc/ui/str/str-idx.rs new file mode 100644 index 000000000000..bf6060c01425 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/str/str-idx.rs @@ -0,0 +1,8 @@ +pub fn main() { + let s: &str = "hello"; + let _: u8 = s[4]; // { dg-error ".E0277." "" { target *-*-* } } + let _ = s.get(4); // { dg-error ".E0277." "" { target *-*-* } } + let _ = s.get_unchecked(4); // { dg-error ".E0277." "" { target *-*-* } } + let _: u8 = s['c']; // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/str/str-lit-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/str/str-lit-type-mismatch.rs new file mode 100644 index 000000000000..5069ebf2f7b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/str/str-lit-type-mismatch.rs @@ -0,0 +1,6 @@ +fn main() { + let x: &[u8] = "foo"; // { dg-error ".E0308." "" { target *-*-* } } + let y: &[u8; 4] = "baaa"; // { dg-error ".E0308." "" { target *-*-* } } + let z: &str = b"foo"; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/str/str-mut-idx.rs b/gcc/testsuite/rust/rustc/ui/str/str-mut-idx.rs new file mode 100644 index 000000000000..384709f5ddf6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/str/str-mut-idx.rs @@ -0,0 +1,18 @@ +fn bot() -> T { loop {} } + +fn mutate(s: &mut str) { + s[1..2] = bot(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + s[1usize] = bot(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + s.get_mut(1); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + s.get_unchecked_mut(1); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + s['c']; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/str/str-overrun.rs b/gcc/testsuite/rust/rustc/ui/str/str-overrun.rs new file mode 100644 index 000000000000..2720c1a0eaf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/str/str-overrun.rs @@ -0,0 +1,11 @@ +// run-fail +// error-pattern:index out of bounds: the len is 5 but the index is 5 +// ignore-emscripten no processes + +fn main() { + let s: String = "hello".to_string(); + + // Bounds-check panic. + assert_eq!(s.as_bytes()[5], 0x0 as u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/string-box-error.rs b/gcc/testsuite/rust/rustc/ui/string-box-error.rs new file mode 100644 index 000000000000..b0cc8a016278 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/string-box-error.rs @@ -0,0 +1,13 @@ +// run-pass +// Ensure that both `Box` and `Box` can be +// obtained from `String`. + +use std::error::Error; + +fn main() { + let _err1: Box = From::from("test".to_string()); + let _err2: Box = From::from("test".to_string()); + let _err3: Box = From::from("test"); + let _err4: Box = From::from("test"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/struct-ctor-mangling.rs b/gcc/testsuite/rust/rustc/ui/struct-ctor-mangling.rs new file mode 100644 index 000000000000..21ee4a39548f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/struct-ctor-mangling.rs @@ -0,0 +1,15 @@ +// run-pass + +fn size_of_val(_: &T) -> usize { + std::mem::size_of::() +} + +struct Foo(i64); + +// Test that the (symbol) mangling of `Foo` (the `struct` type) and that of +// `typeof Foo` (the function type of the `struct` constructor) don't collide. +fn main() { + size_of_val(&Foo(0)); + size_of_val(&Foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/struct-literal-variant-in-if.rs b/gcc/testsuite/rust/rustc/ui/struct-literal-variant-in-if.rs new file mode 100644 index 000000000000..c20799b9bbf2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/struct-literal-variant-in-if.rs @@ -0,0 +1,26 @@ +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +enum E { + V { field: bool }, + I { field1: bool, field2: usize }, + J { field: isize }, + K { field: &'static str}, +} +fn test_E(x: E) { + let field = true; + if x == E::V { field } {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + if x == E::I { field1: true, field2: 42 } {} +// { dg-error "" "" { target *-*-* } .-1 } + if x == E::V { field: false } {} +// { dg-error "" "" { target *-*-* } .-1 } + if x == E::J { field: -42 } {} +// { dg-error "" "" { target *-*-* } .-1 } + if x == E::K { field: "" } {} +// { dg-error "" "" { target *-*-* } .-1 } + let y: usize = (); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/align-enum.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/align-enum.rs new file mode 100644 index 000000000000..7e91f71b0829 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/align-enum.rs @@ -0,0 +1,55 @@ +// run-pass +#![allow(dead_code)] + +use std::mem; + +// Raising alignment +#[repr(align(16))] +enum Align16 { + Foo { foo: u32 }, + Bar { bar: u32 }, +} + +// Raise alignment by maximum +#[repr(align(1), align(16))] +#[repr(align(32))] +#[repr(align(4))] +enum Align32 { + Foo, + Bar, +} + +// Not reducing alignment +#[repr(align(4))] +enum AlsoAlign16 { + Foo { limb_with_align16: Align16 }, + Bar, +} + +// No niche for discriminant when used as limb +#[repr(align(16))] +struct NoNiche16(u64, u64); + +// Discriminant will require extra space, but enum needs to stay compatible +// with alignment 16 +#[repr(align(1))] +enum AnotherAlign16 { + Foo { limb_with_noniche16: NoNiche16 }, + Bar, + Baz, +} + +fn main() { + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 16); + + assert_eq!(mem::align_of::(), 32); + assert_eq!(mem::size_of::(), 32); + + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 16); + + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/align-struct.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/align-struct.rs new file mode 100644 index 000000000000..40a0cb216543 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/align-struct.rs @@ -0,0 +1,246 @@ +// run-pass +#![allow(dead_code)] +#![feature(box_syntax)] + +use std::mem; + +// Raising alignment +#[repr(align(16))] +#[derive(Clone, Copy, Debug)] +struct Align16(i32); + +// Lowering has no effect +#[repr(align(1))] +struct Align1(i32); + +// Multiple attributes take the max +#[repr(align(4))] +#[repr(align(16))] +#[repr(align(8))] +struct AlignMany(i32); + +// Raising alignment may not alter size. +#[repr(align(8))] +#[allow(dead_code)] +struct Align8Many { + a: i32, + b: i32, + c: i32, + d: u8, +} + +enum Enum { + #[allow(dead_code)] + A(i32), + B(Align16) +} + +// Nested alignment - use `#[repr(C)]` to suppress field reordering for sizeof test +#[repr(C)] +struct Nested { + a: i32, + b: i32, + c: Align16, + d: i8, +} + +#[repr(packed)] +struct Packed(i32); + +#[repr(align(16))] +struct AlignContainsPacked { + a: Packed, + b: Packed, +} + +#[repr(C, packed(4))] +struct Packed4C { + a: u32, + b: u64, +} + +#[repr(align(16))] +struct AlignContainsPacked4C { + a: Packed4C, + b: u64, +} + +// The align limit was originally smaller (2^15). +// Check that it works with big numbers. +#[repr(align(0x10000))] +struct AlignLarge { + stuff: [u8; 0x10000], +} + +union UnionContainsAlign { + a: Align16, + b: f32 +} + +impl Align16 { + // return aligned type + pub fn new(i: i32) -> Align16 { + Align16(i) + } + // pass aligned type + pub fn consume(a: Align16) -> i32 { + a.0 + } +} + +const CONST_ALIGN16: Align16 = Align16(7); +static STATIC_ALIGN16: Align16 = Align16(8); + +// Check the actual address is aligned +fn is_aligned_to(p: &T, align: usize) -> bool { + let addr = p as *const T as usize; + (addr & (align - 1)) == 0 +} + +pub fn main() { + // check alignment and size by type and value + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 16); + + let a = Align16(7); + assert_eq!(a.0, 7); + assert_eq!(mem::align_of_val(&a), 16); + assert_eq!(mem::size_of_val(&a), 16); + + assert!(is_aligned_to(&a, 16)); + + // lowering should have no effect + assert_eq!(mem::align_of::(), 4); + assert_eq!(mem::size_of::(), 4); + let a = Align1(7); + assert_eq!(a.0, 7); + assert_eq!(mem::align_of_val(&a), 4); + assert_eq!(mem::size_of_val(&a), 4); + assert!(is_aligned_to(&a, 4)); + + // when multiple attributes are specified the max should be used + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 16); + let a = AlignMany(7); + assert_eq!(a.0, 7); + assert_eq!(mem::align_of_val(&a), 16); + assert_eq!(mem::size_of_val(&a), 16); + assert!(is_aligned_to(&a, 16)); + + // raising alignment should not reduce size + assert_eq!(mem::align_of::(), 8); + assert_eq!(mem::size_of::(), 16); + let a = Align8Many { a: 1, b: 2, c: 3, d: 4 }; + assert_eq!(a.a, 1); + assert_eq!(mem::align_of_val(&a), 8); + assert_eq!(mem::size_of_val(&a), 16); + assert!(is_aligned_to(&a, 8)); + + // return type + let a = Align16::new(1); + assert_eq!(mem::align_of_val(&a), 16); + assert_eq!(mem::size_of_val(&a), 16); + assert_eq!(a.0, 1); + assert!(is_aligned_to(&a, 16)); + assert_eq!(Align16::consume(a), 1); + + // check const alignment, size and value + assert_eq!(mem::align_of_val(&CONST_ALIGN16), 16); + assert_eq!(mem::size_of_val(&CONST_ALIGN16), 16); + assert_eq!(CONST_ALIGN16.0, 7); + assert!(is_aligned_to(&CONST_ALIGN16, 16)); + + // check global static alignment, size and value + assert_eq!(mem::align_of_val(&STATIC_ALIGN16), 16); + assert_eq!(mem::size_of_val(&STATIC_ALIGN16), 16); + assert_eq!(STATIC_ALIGN16.0, 8); + assert!(is_aligned_to(&STATIC_ALIGN16, 16)); + + // Note that the size of Nested may change if struct field re-ordering is enabled + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 48); + let a = Nested{ a: 1, b: 2, c: Align16(3), d: 4}; + assert_eq!(mem::align_of_val(&a), 16); + assert_eq!(mem::align_of_val(&a.b), 4); + assert_eq!(mem::align_of_val(&a.c), 16); + assert_eq!(mem::size_of_val(&a), 48); + assert!(is_aligned_to(&a, 16)); + // check the correct fields are indexed + assert_eq!(a.a, 1); + assert_eq!(a.b, 2); + assert_eq!(a.c.0, 3); + assert_eq!(a.d, 4); + + // enum should be aligned to max alignment + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::align_of_val(&Enum::B(Align16(0))), 16); + let e = Enum::B(Align16(15)); + match e { + Enum::B(ref a) => { + assert_eq!(a.0, 15); + assert_eq!(mem::align_of_val(a), 16); + assert_eq!(mem::size_of_val(a), 16); + }, + _ => () + } + assert!(is_aligned_to(&e, 16)); + + // check union alignment + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 16); + let u = UnionContainsAlign { a: Align16(10) }; + unsafe { + assert_eq!(mem::align_of_val(&u.a), 16); + assert_eq!(mem::size_of_val(&u.a), 16); + assert_eq!(u.a.0, 10); + let UnionContainsAlign { a } = u; + assert_eq!(a.0, 10); + } + + // arrays of aligned elements should also be aligned + assert_eq!(mem::align_of::<[Align16;2]>(), 16); + assert_eq!(mem::size_of::<[Align16;2]>(), 32); + + let a = [Align16(0), Align16(1)]; + assert_eq!(mem::align_of_val(&a[0]), 16); + assert_eq!(mem::align_of_val(&a[1]), 16); + assert!(is_aligned_to(&a, 16)); + + // check heap value is aligned + assert_eq!(mem::align_of_val(Box::new(Align16(0)).as_ref()), 16); + + // check heap array is aligned + let a = vec!(Align16(0), Align16(1)); + assert_eq!(mem::align_of_val(&a[0]), 16); + assert_eq!(mem::align_of_val(&a[1]), 16); + + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 16); + let a = AlignContainsPacked { a: Packed(1), b: Packed(2) }; + assert_eq!(mem::align_of_val(&a), 16); + assert_eq!(mem::align_of_val(&a.a), 1); + assert_eq!(mem::align_of_val(&a.b), 1); + assert_eq!(mem::size_of_val(&a), 16); + assert!(is_aligned_to(&a, 16)); + + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 32); + let a = AlignContainsPacked4C { a: Packed4C{ a: 1, b: 2 }, b: 3 }; + assert_eq!(mem::align_of_val(&a), 16); + assert_eq!(mem::align_of_val(&a.a), 4); + assert_eq!(mem::align_of_val(&a.b), mem::align_of::()); + assert_eq!(mem::size_of_val(&a), 32); + assert!(is_aligned_to(&a, 16)); + + let mut large = box AlignLarge { + stuff: [0; 0x10000], + }; + large.stuff[0] = 132; + *large.stuff.last_mut().unwrap() = 102; + assert_eq!(large.stuff[0], 132); + assert_eq!(large.stuff.last(), Some(&102)); + assert_eq!(mem::align_of::(), 0x10000); + assert_eq!(mem::align_of_val(&*large), 0x10000); + assert!(is_aligned_to(&*large, 0x10000)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class.rs new file mode 100644 index 000000000000..011fadfebb77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class.rs @@ -0,0 +1,15 @@ +pub mod kitties { + pub struct cat { + meows : usize, + + pub how_hungry : isize, + } + + pub fn cat(in_x : usize, in_y : isize) -> cat { + cat { + meows: in_x, + how_hungry: in_y + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_2.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_2.rs new file mode 100644 index 000000000000..57ddd6729a23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_2.rs @@ -0,0 +1,20 @@ +pub mod kitties { + pub struct cat { + meows : usize, + + pub how_hungry : isize, + + } + + impl cat { + pub fn speak(&self) {} + } + + pub fn cat(in_x : usize, in_y : isize) -> cat { + cat { + meows: in_x, + how_hungry: in_y + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_3.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_3.rs new file mode 100644 index 000000000000..8e491c476521 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_3.rs @@ -0,0 +1,20 @@ +pub mod kitties { + pub struct cat { + meows : usize, + + pub how_hungry : isize, + } + + impl cat { + pub fn speak(&mut self) { self.meows += 1; } + pub fn meow_count(&mut self) -> usize { self.meows } + } + + pub fn cat(in_x : usize, in_y : isize) -> cat { + cat { + meows: in_x, + how_hungry: in_y + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_4.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_4.rs new file mode 100644 index 000000000000..d935c0ee35e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_4.rs @@ -0,0 +1,42 @@ +pub mod kitties { + pub struct cat { + meows : usize, + + pub how_hungry : isize, + pub name : String, + } + + impl cat { + pub fn speak(&mut self) { self.meow(); } + + pub fn eat(&mut self) -> bool { + if self.how_hungry > 0 { + println!("OM NOM NOM"); + self.how_hungry -= 2; + return true; + } else { + println!("Not hungry!"); + return false; + } + } + } + + impl cat { + pub fn meow(&mut self) { + println!("Meow"); + self.meows += 1; + if self.meows % 5 == 0 { + self.how_hungry += 1; + } + } + } + + pub fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { + cat { + meows: in_x, + how_hungry: in_y, + name: in_name + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_6.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_6.rs new file mode 100644 index 000000000000..0fe6b0249846 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_6.rs @@ -0,0 +1,26 @@ +pub mod kitties { + + pub struct cat { + info : Vec , + meows : usize, + + pub how_hungry : isize, + } + + impl cat { + pub fn speak(&mut self, stuff: Vec ) { + self.meows += stuff.len(); + } + + pub fn meow_count(&mut self) -> usize { self.meows } + } + + pub fn cat(in_x : usize, in_y : isize, in_info: Vec ) -> cat { + cat { + meows: in_x, + how_hungry: in_y, + info: in_info + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_cast.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_cast.rs new file mode 100644 index 000000000000..28d8486d0446 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_cast.rs @@ -0,0 +1,51 @@ +pub mod kitty { + use std::fmt; + + pub struct cat { + meows : usize, + pub how_hungry : isize, + pub name : String, + } + + impl fmt::Display for cat { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.name) + } + } + + impl cat { + fn meow(&mut self) { + println!("Meow"); + self.meows += 1; + if self.meows % 5 == 0 { + self.how_hungry += 1; + } + } + + } + + impl cat { + pub fn speak(&mut self) { self.meow(); } + + pub fn eat(&mut self) -> bool { + if self.how_hungry > 0 { + println!("OM NOM NOM"); + self.how_hungry -= 2; + return true; + } + else { + println!("Not hungry!"); + return false; + } + } + } + + pub fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { + cat { + meows: in_x, + how_hungry: in_y, + name: in_name + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_trait.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_trait.rs new file mode 100644 index 000000000000..06302bf059ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/cci_class_trait.rs @@ -0,0 +1,6 @@ +pub mod animals { + pub trait noisy { + fn speak(&mut self); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/empty-struct.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/empty-struct.rs new file mode 100644 index 000000000000..020e55569330 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/empty-struct.rs @@ -0,0 +1,10 @@ +pub struct XEmpty1 {} +pub struct XEmpty2; +pub struct XEmpty7(); + +pub enum XE { + XEmpty3 {}, + XEmpty4, + XEmpty6(), +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs new file mode 100644 index 000000000000..7f5235d8426b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/namespaced_enum_emulate_flat.rs @@ -0,0 +1,26 @@ +pub use Foo::*; + +pub enum Foo { + A, + B(isize), + C { a: isize }, +} + +impl Foo { + pub fn foo() {} +} + +pub mod nest { + pub use self::Bar::*; + + pub enum Bar { + D, + E(isize), + F { a: isize }, + } + + impl Bar { + pub fn foo() {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/namespaced_enums.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/namespaced_enums.rs new file mode 100644 index 000000000000..dcd0b95974b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/namespaced_enums.rs @@ -0,0 +1,11 @@ +pub enum Foo { + A, + B(isize), + C { a: isize }, +} + +impl Foo { + pub fn foo() {} + pub fn bar(&self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/newtype_struct_xc.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/newtype_struct_xc.rs new file mode 100644 index 000000000000..0ca9e514aa58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/newtype_struct_xc.rs @@ -0,0 +1,4 @@ +#![crate_type="lib"] + +pub struct Au(pub isize); + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/struct_destructuring_cross_crate.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/struct_destructuring_cross_crate.rs new file mode 100644 index 000000000000..c2f027164a10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/struct_destructuring_cross_crate.rs @@ -0,0 +1,7 @@ +#![crate_type="lib"] + +pub struct S { + pub x: isize, + pub y: isize, +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/struct_variant_xc_aux.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/struct_variant_xc_aux.rs new file mode 100644 index 000000000000..b175f4ebe314 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/struct_variant_xc_aux.rs @@ -0,0 +1,9 @@ +#![crate_name="struct_variant_xc_aux"] +#![crate_type = "lib"] + +#[derive(Copy, Clone)] +pub enum Enum { + Variant(u8), + StructVariant { arg: u8 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/xcrate_struct_aliases.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/xcrate_struct_aliases.rs new file mode 100644 index 000000000000..9c25efddc32d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/auxiliary/xcrate_struct_aliases.rs @@ -0,0 +1,7 @@ +pub struct S { + pub x: isize, + pub y: isize, +} + +pub type S2 = S; + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/borrow-tuple-fields.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/borrow-tuple-fields.rs new file mode 100644 index 000000000000..964b7eacc47c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/borrow-tuple-fields.rs @@ -0,0 +1,39 @@ +// run-pass + +struct Foo(isize, isize); + +fn main() { + let x = (1, 2); + let a = &x.0; + let b = &x.0; + assert_eq!(*a, 1); + assert_eq!(*b, 1); + + let mut x = (1, 2); + { + let a = &x.0; + let b = &mut x.1; + *b = 5; + assert_eq!(*a, 1); + } + assert_eq!(x.0, 1); + assert_eq!(x.1, 5); + + + let x = Foo(1, 2); + let a = &x.0; + let b = &x.0; + assert_eq!(*a, 1); + assert_eq!(*b, 1); + + let mut x = Foo(1, 2); + { + let a = &x.0; + let b = &mut x.1; + *b = 5; + assert_eq!(*a, 1); + } + assert_eq!(x.0, 1); + assert_eq!(x.1, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs new file mode 100644 index 000000000000..d02cb922dcc4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-cast-to-trait-cross-crate-2.rs @@ -0,0 +1,21 @@ +// run-pass +// aux-build:cci_class_cast.rs + +#![feature(box_syntax)] + +extern crate cci_class_cast; + +use std::string::ToString; +use cci_class_cast::kitty::cat; + +fn print_out(thing: Box, expected: String) { + let actual = (*thing).to_string(); + println!("{}", actual); + assert_eq!(actual.to_string(), expected); +} + +pub fn main() { + let nyan: Box = box cat(0, 2, "nyan".to_string()) as Box; + print_out(nyan, "nyan".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-cast-to-trait-multiple-types.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-cast-to-trait-multiple-types.rs new file mode 100644 index 000000000000..e36687b97a74 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-cast-to-trait-multiple-types.rs @@ -0,0 +1,94 @@ +// run-pass +#![allow(non_camel_case_types)] + +trait noisy { + fn speak(&mut self) -> isize; +} + +struct dog { + barks: usize, + + volume: isize, +} + +impl dog { + fn bark(&mut self) -> isize { + println!("Woof {} {}", self.barks, self.volume); + self.barks += 1_usize; + if self.barks % 3_usize == 0_usize { + self.volume += 1; + } + if self.barks % 10_usize == 0_usize { + self.volume -= 2; + } + println!("Grrr {} {}", self.barks, self.volume); + self.volume + } +} + +impl noisy for dog { + fn speak(&mut self) -> isize { + self.bark() + } +} + +fn dog() -> dog { + dog { + volume: 0, + barks: 0_usize + } +} + +#[derive(Clone)] +struct cat { + meows: usize, + + how_hungry: isize, + name: String, +} + +impl noisy for cat { + fn speak(&mut self) -> isize { + self.meow() as isize + } +} + +impl cat { + pub fn meow_count(&self) -> usize { + self.meows + } +} + +impl cat { + fn meow(&mut self) -> usize { + println!("Meow"); + self.meows += 1_usize; + if self.meows % 5_usize == 0_usize { + self.how_hungry += 1; + } + self.meows + } +} + +fn cat(in_x: usize, in_y: isize, in_name: String) -> cat { + cat { + meows: in_x, + how_hungry: in_y, + name: in_name + } +} + + +fn annoy_neighbors(critter: &mut dyn noisy) { + for _i in 0_usize..10 { critter.speak(); } +} + +pub fn main() { + let mut nyan: cat = cat(0_usize, 2, "nyan".to_string()); + let mut whitefang: dog = dog(); + annoy_neighbors(&mut nyan); + annoy_neighbors(&mut whitefang); + assert_eq!(nyan.meow_count(), 10_usize); + assert_eq!(whitefang.volume, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-cast-to-trait.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-cast-to-trait.rs new file mode 100644 index 000000000000..7075bd97c7eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-cast-to-trait.rs @@ -0,0 +1,61 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_mut)] +#![allow(non_camel_case_types)] + +// ignore-freebsd FIXME fails on BSD + + +trait noisy { + fn speak(&mut self); +} + +struct cat { + meows: usize, + how_hungry: isize, + name: String, +} + +impl noisy for cat { + fn speak(&mut self) { self.meow(); } +} + +impl cat { + pub fn eat(&mut self) -> bool { + if self.how_hungry > 0 { + println!("OM NOM NOM"); + self.how_hungry -= 2; + return true; + } + else { + println!("Not hungry!"); + return false; + } + } +} + +impl cat { + fn meow(&mut self) { + println!("Meow"); + self.meows += 1; + if self.meows % 5 == 0 { + self.how_hungry += 1; + } + } +} + +fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { + cat { + meows: in_x, + how_hungry: in_y, + name: in_name + } +} + + +pub fn main() { + let mut nyan = cat(0, 2, "nyan".to_string()); + let mut nyan: &mut dyn noisy = &mut nyan; + nyan.speak(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-dtor.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-dtor.rs new file mode 100644 index 000000000000..f1108bda7390 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-dtor.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +struct cat { + done : extern fn(usize), + meows : usize, +} + +impl Drop for cat { + fn drop(&mut self) { + (self.done)(self.meows); + } +} + +fn cat(done: extern fn(usize)) -> cat { + cat { + meows: 0, + done: done + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-exports.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-exports.rs new file mode 100644 index 000000000000..289a45b95021 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-exports.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +/* Test that exporting a class also exports its + public fields and methods */ + +use kitty::cat; + +mod kitty { + pub struct cat { + meows: usize, + name: String, + } + + impl cat { + pub fn get_name(&self) -> String { self.name.clone() } + } + + pub fn cat(in_name: String) -> cat { + cat { + name: in_name, + meows: 0 + } + } +} + +pub fn main() { + assert_eq!(cat("Spreckles".to_string()).get_name(), + "Spreckles".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-impl-very-parameterized-trait.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-impl-very-parameterized-trait.rs new file mode 100644 index 000000000000..09973158ae15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-impl-very-parameterized-trait.rs @@ -0,0 +1,108 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +use std::cmp; + +#[derive(Copy, Clone, Debug)] +enum cat_type { tuxedo, tabby, tortoiseshell } + +impl cmp::PartialEq for cat_type { + fn eq(&self, other: &cat_type) -> bool { + ((*self) as usize) == ((*other) as usize) + } + fn ne(&self, other: &cat_type) -> bool { !(*self).eq(other) } +} + +// Very silly -- this just returns the value of the name field +// for any isize value that's less than the meows field + +// ok: T should be in scope when resolving the trait ref for map +struct cat { + // Yes, you can have negative meows + meows : isize, + + how_hungry : isize, + name : T, +} + +impl cat { + pub fn speak(&mut self) { self.meow(); } + + pub fn eat(&mut self) -> bool { + if self.how_hungry > 0 { + println!("OM NOM NOM"); + self.how_hungry -= 2; + return true; + } else { + println!("Not hungry!"); + return false; + } + } + fn len(&self) -> usize { self.meows as usize } + fn is_empty(&self) -> bool { self.meows == 0 } + fn clear(&mut self) {} + fn contains_key(&self, k: &isize) -> bool { *k <= self.meows } + + fn find(&self, k: &isize) -> Option<&T> { + if *k <= self.meows { + Some(&self.name) + } else { + None + } + } + fn insert(&mut self, k: isize, _: T) -> bool { + self.meows += k; + true + } + + fn find_mut(&mut self, _k: &isize) -> Option<&mut T> { panic!() } + + fn remove(&mut self, k: &isize) -> bool { + if self.find(k).is_some() { + self.meows -= *k; true + } else { + false + } + } + + fn pop(&mut self, _k: &isize) -> Option { panic!() } + + fn swap(&mut self, _k: isize, _v: T) -> Option { panic!() } +} + +impl cat { + pub fn get(&self, k: &isize) -> &T { + match self.find(k) { + Some(v) => { v } + None => { panic!("epic fail"); } + } + } + + pub fn new(in_x: isize, in_y: isize, in_name: T) -> cat { + cat{meows: in_x, how_hungry: in_y, name: in_name } + } +} + +impl cat { + fn meow(&mut self) { + self.meows += 1; + println!("Meow {}", self.meows); + if self.meows % 5 == 0 { + self.how_hungry += 1; + } + } +} + +pub fn main() { + let mut nyan: cat = cat::new(0, 2, "nyan".to_string()); + for _ in 1_usize..5 { nyan.speak(); } + assert_eq!(*nyan.find(&1).unwrap(), "nyan".to_string()); + assert_eq!(nyan.find(&10), None); + let mut spotty: cat = cat::new(2, 57, cat_type::tuxedo); + for _ in 0_usize..6 { spotty.speak(); } + assert_eq!(spotty.len(), 8); + assert!((spotty.contains_key(&2))); + assert_eq!(spotty.get(&3), &cat_type::tuxedo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-implement-trait-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-implement-trait-cross-crate.rs new file mode 100644 index 000000000000..64160eaf3e21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-implement-trait-cross-crate.rs @@ -0,0 +1,60 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// aux-build:cci_class_trait.rs +extern crate cci_class_trait; +use cci_class_trait::animals::noisy; + +struct cat { + meows: usize, + + how_hungry : isize, + name : String, +} + +impl cat { + pub fn eat(&mut self) -> bool { + if self.how_hungry > 0 { + println!("OM NOM NOM"); + self.how_hungry -= 2; + return true; + } + else { + println!("Not hungry!"); + return false; + } + } +} + +impl noisy for cat { + fn speak(&mut self) { self.meow(); } +} + +impl cat { + fn meow(&mut self) { + println!("Meow"); + self.meows += 1_usize; + if self.meows % 5_usize == 0_usize { + self.how_hungry += 1; + } + } +} + +fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { + cat { + meows: in_x, + how_hungry: in_y, + name: in_name + } +} + + +pub fn main() { + let mut nyan = cat(0_usize, 2, "nyan".to_string()); + nyan.eat(); + assert!((!nyan.eat())); + for _ in 1_usize..10_usize { nyan.speak(); }; + assert!((nyan.eat())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-implement-traits.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-implement-traits.rs new file mode 100644 index 000000000000..71cb64c8b071 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-implement-traits.rs @@ -0,0 +1,64 @@ +// run-pass +#![allow(non_camel_case_types)] + +trait noisy { + fn speak(&mut self); +} + +#[derive(Clone)] +struct cat { + meows : usize, + + how_hungry : isize, + name : String, +} + +impl cat { + fn meow(&mut self) { + println!("Meow"); + self.meows += 1_usize; + if self.meows % 5_usize == 0_usize { + self.how_hungry += 1; + } + } +} + +impl cat { + pub fn eat(&mut self) -> bool { + if self.how_hungry > 0 { + println!("OM NOM NOM"); + self.how_hungry -= 2; + return true; + } else { + println!("Not hungry!"); + return false; + } + } +} + +impl noisy for cat { + fn speak(&mut self) { self.meow(); } +} + +fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { + cat { + meows: in_x, + how_hungry: in_y, + name: in_name.clone() + } +} + + +fn make_speak(mut c: C) { + c.speak(); +} + +pub fn main() { + let mut nyan = cat(0_usize, 2, "nyan".to_string()); + nyan.eat(); + assert!((!nyan.eat())); + for _ in 1_usize..10_usize { + make_speak(nyan.clone()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-method-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-method-cross-crate.rs new file mode 100644 index 000000000000..013047d9648c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-method-cross-crate.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:cci_class_2.rs + +extern crate cci_class_2; +use cci_class_2::kitties::cat; + +pub fn main() { + let nyan : cat = cat(52, 99); + let kitty = cat(1000, 2); + assert_eq!(nyan.how_hungry, 99); + assert_eq!(kitty.how_hungry, 2); + nyan.speak(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-methods-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-methods-cross-crate.rs new file mode 100644 index 000000000000..f54270e16fa5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-methods-cross-crate.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:cci_class_3.rs + +extern crate cci_class_3; +use cci_class_3::kitties::cat; + +pub fn main() { + let mut nyan : cat = cat(52, 99); + let kitty = cat(1000, 2); + assert_eq!(nyan.how_hungry, 99); + assert_eq!(kitty.how_hungry, 2); + nyan.speak(); + assert_eq!(nyan.meow_count(), 53); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-methods.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-methods.rs new file mode 100644 index 000000000000..ef826e96169a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-methods.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(non_camel_case_types)] + + +struct cat { + meows : usize, + + how_hungry : isize, +} + +impl cat { + pub fn speak(&mut self) { self.meows += 1; } + pub fn meow_count(&mut self) -> usize { self.meows } +} + +fn cat(in_x: usize, in_y: isize) -> cat { + cat { + meows: in_x, + how_hungry: in_y + } +} + +pub fn main() { + let mut nyan: cat = cat(52, 99); + let kitty = cat(1000, 2); + assert_eq!(nyan.how_hungry, 99); + assert_eq!(kitty.how_hungry, 2); + nyan.speak(); + assert_eq!(nyan.meow_count(), 53); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-poly-methods-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-poly-methods-cross-crate.rs new file mode 100644 index 000000000000..93cfb263380c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-poly-methods-cross-crate.rs @@ -0,0 +1,17 @@ +// run-pass +// aux-build:cci_class_6.rs + +extern crate cci_class_6; +use cci_class_6::kitties::cat; + +pub fn main() { + let mut nyan : cat = cat::(52_usize, 99, vec!['p']); + let mut kitty = cat(1000_usize, 2, vec!["tabby".to_string()]); + assert_eq!(nyan.how_hungry, 99); + assert_eq!(kitty.how_hungry, 2); + nyan.speak(vec![1_usize,2_usize,3_usize]); + assert_eq!(nyan.meow_count(), 55_usize); + kitty.speak(vec!["meow".to_string(), "mew".to_string(), "purr".to_string(), "chirp".to_string()]); + assert_eq!(kitty.meow_count(), 1004_usize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-poly-methods.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-poly-methods.rs new file mode 100644 index 000000000000..803d35443d89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-poly-methods.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + + +struct cat { + info : Vec , + meows : usize, + + how_hungry : isize, +} + +impl cat { + pub fn speak(&mut self, stuff: Vec ) { + self.meows += stuff.len(); + } + pub fn meow_count(&mut self) -> usize { self.meows } +} + +fn cat(in_x : usize, in_y : isize, in_info: Vec ) -> cat { + cat { + meows: in_x, + how_hungry: in_y, + info: in_info + } +} + +pub fn main() { + let mut nyan : cat = cat::(52, 99, vec![9]); + let mut kitty = cat(1000, 2, vec!["tabby".to_string()]); + assert_eq!(nyan.how_hungry, 99); + assert_eq!(kitty.how_hungry, 2); + nyan.speak(vec![1,2,3]); + assert_eq!(nyan.meow_count(), 55); + kitty.speak(vec!["meow".to_string(), "mew".to_string(), "purr".to_string(), "chirp".to_string()]); + assert_eq!(kitty.meow_count(), 1004); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-separate-impl.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-separate-impl.rs new file mode 100644 index 000000000000..b3f5e002895b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-separate-impl.rs @@ -0,0 +1,66 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +#![feature(box_syntax)] + +use std::fmt; + +struct cat { + meows : usize, + + how_hungry : isize, + name : String, +} + +impl cat { + pub fn speak(&mut self) { self.meow(); } + + pub fn eat(&mut self) -> bool { + if self.how_hungry > 0 { + println!("OM NOM NOM"); + self.how_hungry -= 2; + return true; + } + else { + println!("Not hungry!"); + return false; + } + } +} + +impl cat { + fn meow(&mut self) { + println!("Meow"); + self.meows += 1; + if self.meows % 5 == 0 { + self.how_hungry += 1; + } + } +} + +fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { + cat { + meows: in_x, + how_hungry: in_y, + name: in_name + } +} + +impl fmt::Display for cat { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.name) + } +} + +fn print_out(thing: Box, expected: String) { + let actual = (*thing).to_string(); + println!("{}", actual); + assert_eq!(actual.to_string(), expected); +} + +pub fn main() { + let nyan: Box = box cat(0, 2, "nyan".to_string()) as Box; + print_out(nyan, "nyan".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-str-field.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-str-field.rs new file mode 100644 index 000000000000..97814aa2a823 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-str-field.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +struct cat { + + name : String, + +} + +fn cat(in_name: String) -> cat { + cat { + name: in_name + } +} + +pub fn main() { + let _nyan = cat("nyan".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/class-typarams.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/class-typarams.rs new file mode 100644 index 000000000000..040eab05dd2e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/class-typarams.rs @@ -0,0 +1,33 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +use std::marker::PhantomData; + +struct cat { + meows : usize, + how_hungry : isize, + m: PhantomData +} + +impl cat { + pub fn speak(&mut self) { self.meows += 1; } + pub fn meow_count(&mut self) -> usize { self.meows } +} + +fn cat(in_x : usize, in_y : isize) -> cat { + cat { + meows: in_x, + how_hungry: in_y, + m: PhantomData + } +} + + +pub fn main() { + let _nyan : cat = cat::(52, 99); + // let mut kitty = cat(1000, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/classes-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/classes-cross-crate.rs new file mode 100644 index 000000000000..6d05540e14e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/classes-cross-crate.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:cci_class_4.rs + +extern crate cci_class_4; +use cci_class_4::kitties::cat; + +pub fn main() { + let mut nyan = cat(0_usize, 2, "nyan".to_string()); + nyan.eat(); + assert!((!nyan.eat())); + for _ in 1_usize..10_usize { nyan.speak(); }; + assert!((nyan.eat())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/classes-self-referential.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/classes-self-referential.rs new file mode 100644 index 000000000000..35489e533554 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/classes-self-referential.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + + +// pretty-expanded FIXME #23616 + +struct kitten { + cat: Option, +} + +fn kitten(cat: Option) -> kitten { + kitten { + cat: cat + } +} + +type cat = Box; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/classes-simple-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/classes-simple-cross-crate.rs new file mode 100644 index 000000000000..88afa59cb927 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/classes-simple-cross-crate.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:cci_class.rs + +extern crate cci_class; +use cci_class::kitties::cat; + +pub fn main() { + let nyan : cat = cat(52, 99); + let kitty = cat(1000, 2); + assert_eq!(nyan.how_hungry, 99); + assert_eq!(kitty.how_hungry, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/classes-simple-method.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/classes-simple-method.rs new file mode 100644 index 000000000000..fa0ffb3de279 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/classes-simple-method.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +struct cat { + meows : usize, + + how_hungry : isize, +} + +impl cat { + pub fn speak(&mut self) {} +} + +fn cat(in_x : usize, in_y : isize) -> cat { + cat { + meows: in_x, + how_hungry: in_y + } +} + +pub fn main() { + let mut nyan : cat = cat(52, 99); + let kitty = cat(1000, 2); + assert_eq!(nyan.how_hungry, 99); + assert_eq!(kitty.how_hungry, 2); + nyan.speak(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/classes-simple.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/classes-simple.rs new file mode 100644 index 000000000000..31ba7c78e4b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/classes-simple.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +struct cat { + meows : usize, + + how_hungry : isize, +} + +fn cat(in_x : usize, in_y : isize) -> cat { + cat { + meows: in_x, + how_hungry: in_y + } +} + +pub fn main() { + let nyan : cat = cat(52, 99); + let kitty = cat(1000, 2); + assert_eq!(nyan.how_hungry, 99); + assert_eq!(kitty.how_hungry, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/classes.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/classes.rs new file mode 100644 index 000000000000..d6bd1057ddf9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/classes.rs @@ -0,0 +1,52 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +struct cat { + meows : usize, + + how_hungry : isize, + name : String, +} + +impl cat { + pub fn speak(&mut self) { self.meow(); } + + pub fn eat(&mut self) -> bool { + if self.how_hungry > 0 { + println!("OM NOM NOM"); + self.how_hungry -= 2; + return true; + } else { + println!("Not hungry!"); + return false; + } + } +} + +impl cat { + fn meow(&mut self) { + println!("Meow"); + self.meows += 1_usize; + if self.meows % 5_usize == 0_usize { + self.how_hungry += 1; + } + } +} + +fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { + cat { + meows: in_x, + how_hungry: in_y, + name: in_name + } +} + +pub fn main() { + let mut nyan = cat(0_usize, 2, "nyan".to_string()); + nyan.eat(); + assert!((!nyan.eat())); + for _ in 1_usize..10_usize { nyan.speak(); }; + assert!((nyan.eat())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/codegen-tag-static-padding.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/codegen-tag-static-padding.rs new file mode 100644 index 000000000000..8ce0b18df148 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/codegen-tag-static-padding.rs @@ -0,0 +1,60 @@ +// run-pass +#![allow(non_upper_case_globals)] + +// Issue #13186 + +// For simplicity of explanations assuming code is compiled for x86_64 +// Linux ABI. + +// Size of TestOption is 16, and alignment of TestOption is 8. +// Size of u8 is 1, and alignment of u8 is 1. +// So size of Request is 24, and alignment of Request must be 8: +// the maximum alignment of its fields. +// Last 7 bytes of Request struct are not occupied by any fields. + + + +enum TestOption { + TestNone, + TestSome(T), +} + +pub struct Request { + foo: TestOption, + bar: u8, +} + +fn default_instance() -> &'static Request { + static instance: Request = Request { + // LLVM does not allow to specify alignment of expressions, thus + // alignment of `foo` in constant is 1, not 8. + foo: TestOption::TestNone, + bar: 17, + // Space after last field is not occupied by any data, but it is + // reserved to make struct aligned properly. If compiler does + // not insert padding after last field when emitting constant, + // size of struct may be not equal to size of struct, and + // compiler crashes in internal assertion check. + }; + &instance +} + +fn non_default_instance() -> &'static Request { + static instance: Request = Request { + foo: TestOption::TestSome(0x1020304050607080), + bar: 19, + }; + &instance +} + +pub fn main() { + match default_instance() { + &Request { foo: TestOption::TestNone, bar: 17 } => {}, + _ => panic!(), + }; + match non_default_instance() { + &Request { foo: TestOption::TestSome(0x1020304050607080), bar: 19 } => {}, + _ => panic!(), + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/compare-generic-enums.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/compare-generic-enums.rs new file mode 100644 index 000000000000..033b1897f380 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/compare-generic-enums.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(non_camel_case_types)] + + +type an_int = isize; + +fn cmp(x: Option, y: Option) -> bool { + x == y +} + +pub fn main() { + assert!(!cmp(Some(3), None)); + assert!(!cmp(Some(3), Some(4))); + assert!(cmp(Some(3), Some(3))); + assert!(cmp(None, None)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/discrim-explicit-23030.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/discrim-explicit-23030.rs new file mode 100644 index 000000000000..7324aa3405cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/discrim-explicit-23030.rs @@ -0,0 +1,148 @@ +// run-pass +// Issue 23030: Workaround overflowing discriminant +// with explicit assignments. + +// See also compile-fail/overflow-discrim.rs, which shows what +// happens if you leave the OhNo explicit cases out here. + +use std::{i8,u8,i16,u16,i32,u32,i64,u64,isize,usize}; + +fn f_i8() { + #[repr(i8)] + enum A { + Ok = i8::MAX - 1, + Ok2, + OhNo = i8::MIN, + NotTheEnd = -1, + Zero, + } + + let _x = (A::Ok, A::Ok2, A::OhNo); + let z = (A::NotTheEnd, A::Zero).1 as i8; + assert_eq!(z, 0); +} + +fn f_u8() { + #[repr(u8)] + enum A { + Ok = u8::MAX - 1, + Ok2, + OhNo = u8::MIN, + } + + let _x = (A::Ok, A::Ok2, A::OhNo); +} + +fn f_i16() { + #[repr(i16)] + enum A { + Ok = i16::MAX - 1, + Ok2, + OhNo = i16::MIN, + NotTheEnd = -1, + Zero, + } + + let _x = (A::Ok, A::Ok2, A::OhNo); + let z = (A::NotTheEnd, A::Zero).1 as i16; + assert_eq!(z, 0); +} + +fn f_u16() { + #[repr(u16)] + enum A { + Ok = u16::MAX - 1, + Ok2, + OhNo = u16::MIN, + } + + let _x = (A::Ok, A::Ok2, A::OhNo); +} + +fn f_i32() { + #[repr(i32)] + enum A { + Ok = i32::MAX - 1, + Ok2, + OhNo = i32::MIN, + NotTheEnd = -1, + Zero, + } + + let _x = (A::Ok, A::Ok2, A::OhNo); + let z = (A::NotTheEnd, A::Zero).1 as i32; + assert_eq!(z, 0); +} + +fn f_u32() { + #[repr(u32)] + enum A { + Ok = u32::MAX - 1, + Ok2, + OhNo = u32::MIN, + } + + let _x = (A::Ok, A::Ok2, A::OhNo); +} + +fn f_i64() { + #[repr(i64)] + enum A { + Ok = i64::MAX - 1, + Ok2, + OhNo = i64::MIN, + NotTheEnd = -1, + Zero, + } + + let _x = (A::Ok, A::Ok2, A::OhNo); + let z = (A::NotTheEnd, A::Zero).1 as i64; + assert_eq!(z, 0); +} + +fn f_u64() { + #[repr(u64)] + enum A { + Ok = u64::MAX - 1, + Ok2, + OhNo = u64::MIN, + } + + let _x = (A::Ok, A::Ok2, A::OhNo); +} + +fn f_isize() { + #[repr(isize)] + enum A { + Ok = isize::MAX - 1, + Ok2, + OhNo = isize::MIN, + NotTheEnd = -1, + Zero, + } + + let _x = (A::Ok, A::Ok2, A::OhNo); + let z = (A::NotTheEnd, A::Zero).1 as isize; + assert_eq!(z, 0); +} + +fn f_usize() { + #[repr(usize)] + enum A { + Ok = usize::MAX - 1, + Ok2, + OhNo = usize::MIN, + } + + let _x = (A::Ok, A::Ok2, A::OhNo); +} + +fn main() { + f_i8(); f_u8(); + f_i16(); f_u16(); + f_i32(); f_u32(); + f_i64(); f_u64(); + + f_isize(); f_usize(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/empty-struct-braces.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/empty-struct-braces.rs new file mode 100644 index 000000000000..a7fb162e93b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/empty-struct-braces.rs @@ -0,0 +1,214 @@ +// run-pass +#![allow(unused_variables)] +#![allow(non_upper_case_globals)] + +// Empty struct defined with braces add names into type namespace +// Empty struct defined without braces add names into both type and value namespaces + +// aux-build:empty-struct.rs + +extern crate empty_struct; +use empty_struct::*; + +struct Empty1 {} +struct Empty2; +struct Empty7(); + +#[derive(PartialEq, Eq)] +struct Empty3 {} + +const Empty3: Empty3 = Empty3 {}; + +enum E { + Empty4 {}, + Empty5, + Empty6(), +} + +fn local() { + let e1: Empty1 = Empty1 {}; + let e2: Empty2 = Empty2 {}; + let e2: Empty2 = Empty2; + let e3: Empty3 = Empty3 {}; + let e3: Empty3 = Empty3; + let e4: E = E::Empty4 {}; + let e5: E = E::Empty5 {}; + let e5: E = E::Empty5; + let e6: E = E::Empty6 {}; + let e6: E = E::Empty6(); + let ctor6: fn() -> E = E::Empty6; + let e7: Empty7 = Empty7 {}; + let e7: Empty7 = Empty7(); + let ctor7: fn() -> Empty7 = Empty7; + + match e1 { + Empty1 {} => {} + } + match e2 { + Empty2 {} => {} + } + match e3 { + Empty3 {} => {} + } + match e4 { + E::Empty4 {} => {} + _ => {} + } + match e5 { + E::Empty5 {} => {} + _ => {} + } + match e6 { + E::Empty6 {} => {} + _ => {} + } + match e7 { + Empty7 {} => {} + } + + match e1 { + Empty1 { .. } => {} + } + match e2 { + Empty2 { .. } => {} + } + match e3 { + Empty3 { .. } => {} + } + match e4 { + E::Empty4 { .. } => {} + _ => {} + } + match e5 { + E::Empty5 { .. } => {} + _ => {} + } + match e6 { + E::Empty6 { .. } => {} + _ => {} + } + match e7 { + Empty7 { .. } => {} + } + + match e2 { + Empty2 => {} + } + match e3 { + Empty3 => {} + } + match e5 { + E::Empty5 => {} + _ => {} + } + match e6 { + E::Empty6() => {} + _ => {} + } + match e6 { + E::Empty6(..) => {} + _ => {} + } + match e7 { + Empty7() => {} + } + match e7 { + Empty7(..) => {} + } + + let e11: Empty1 = Empty1 { ..e1 }; + let e22: Empty2 = Empty2 { ..e2 }; + let e33: Empty3 = Empty3 { ..e3 }; + let e77: Empty7 = Empty7 { ..e7 }; +} + +fn xcrate() { + let e1: XEmpty1 = XEmpty1 {}; + let e2: XEmpty2 = XEmpty2 {}; + let e2: XEmpty2 = XEmpty2; + let e3: XE = XE::XEmpty3 {}; + let e4: XE = XE::XEmpty4 {}; + let e4: XE = XE::XEmpty4; + let e6: XE = XE::XEmpty6 {}; + let e6: XE = XE::XEmpty6(); + let ctor6: fn() -> XE = XE::XEmpty6; + let e7: XEmpty7 = XEmpty7 {}; + let e7: XEmpty7 = XEmpty7(); + let ctor7: fn() -> XEmpty7 = XEmpty7; + + match e1 { + XEmpty1 {} => {} + } + match e2 { + XEmpty2 {} => {} + } + match e3 { + XE::XEmpty3 {} => {} + _ => {} + } + match e4 { + XE::XEmpty4 {} => {} + _ => {} + } + match e6 { + XE::XEmpty6 {} => {} + _ => {} + } + match e7 { + XEmpty7 {} => {} + } + + match e1 { + XEmpty1 { .. } => {} + } + match e2 { + XEmpty2 { .. } => {} + } + match e3 { + XE::XEmpty3 { .. } => {} + _ => {} + } + match e4 { + XE::XEmpty4 { .. } => {} + _ => {} + } + match e6 { + XE::XEmpty6 { .. } => {} + _ => {} + } + match e7 { + XEmpty7 { .. } => {} + } + + match e2 { + XEmpty2 => {} + } + match e4 { + XE::XEmpty4 => {} + _ => {} + } + match e6 { + XE::XEmpty6() => {} + _ => {} + } + match e6 { + XE::XEmpty6(..) => {} + _ => {} + } + match e7 { + XEmpty7() => {} + } + match e7 { + XEmpty7(..) => {} + } + + let e11: XEmpty1 = XEmpty1 { ..e1 }; + let e22: XEmpty2 = XEmpty2 { ..e2 }; + let e77: XEmpty7 = XEmpty7 { ..e7 }; +} + +fn main() { + local(); + xcrate(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/empty-tag.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/empty-tag.rs new file mode 100644 index 000000000000..402a688da165 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/empty-tag.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(unused_braces)] +#![allow(non_camel_case_types)] + +#[derive(Copy, Clone, Debug)] +enum chan { chan_t, } + +impl PartialEq for chan { + fn eq(&self, other: &chan) -> bool { + ((*self) as usize) == ((*other) as usize) + } + fn ne(&self, other: &chan) -> bool { !(*self).eq(other) } +} + +fn wrapper3(i: chan) { + assert_eq!(i, chan::chan_t); +} + +pub fn main() { + let wrapped = {||wrapper3(chan::chan_t)}; + wrapped(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-alignment.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-alignment.rs new file mode 100644 index 000000000000..05410efdfbbe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-alignment.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] +#![allow(deprecated)] + +use std::mem; + +fn addr_of(ptr: &T) -> usize { + ptr as *const T as usize +} + +fn is_aligned(ptr: &T) -> bool { + unsafe { + let addr: usize = mem::transmute(ptr); + (addr % mem::min_align_of::()) == 0 + } +} + +pub fn main() { + let x = Some(0u64); + match x { + None => panic!(), + Some(ref y) => assert!(is_aligned(y)) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-clike-ffi-as-int.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-clike-ffi-as-int.rs new file mode 100644 index 000000000000..65accdc4ecd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-clike-ffi-as-int.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(dead_code)] + +/*! + * C-like enums have to be represented as LLVM ints, not wrapped in a + * struct, because it's important for the FFI that they interoperate + * with C integers/enums, and the ABI can treat structs differently. + * For example, on i686-linux-gnu, a struct return value is passed by + * storing to a hidden out parameter, whereas an integer would be + * returned in a register. + * + * This test just checks that the ABIs for the enum and the plain + * integer are compatible, rather than actually calling C code. + * The unused parameter to `foo` is to increase the likelihood of + * crashing if something goes wrong here. + */ + +#[repr(u32)] +enum Foo { + A = 0, + B = 23 +} + +#[inline(never)] +extern "C" fn foo(_x: usize) -> Foo { Foo::B } + +pub fn main() { + unsafe { + let f: extern "C" fn(usize) -> u32 = + ::std::mem::transmute(foo as extern "C" fn(usize) -> Foo); + assert_eq!(f(0xDEADBEEF), Foo::B as u32); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discr.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discr.rs new file mode 100644 index 000000000000..231a5d454f1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discr.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] + +enum Animal { + Cat = 0, + Dog = 1, + Horse = 2, + Snake = 3, +} + +enum Hero { + Batman = -1, + Superman = -2, + Ironman = -3, + Spiderman = -4 +} + +pub fn main() { + let pet: Animal = Animal::Snake; + let hero: Hero = Hero::Superman; + assert_eq!(pet as usize, 3); + assert_eq!(hero as isize, -2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-autosizing.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-autosizing.rs new file mode 100644 index 000000000000..d386fa124934 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-autosizing.rs @@ -0,0 +1,54 @@ +// run-pass +#![allow(dead_code)] +#![allow(overflowing_literals)] + +use std::mem::size_of; + +enum Ei8 { + Ai8 = -1, + Bi8 = 0 +} + +enum Eu8 { + Au8 = 0, + Bu8 = 0x80 +} + +enum Ei16 { + Ai16 = -1, + Bi16 = 0x80 +} + +enum Eu16 { + Au16 = 0, + Bu16 = 0x8000 +} + +enum Ei32 { + Ai32 = -1, + Bi32 = 0x8000 +} + +enum Eu32 { + Au32 = 0, + Bu32 = 0x8000_0000 +} + +enum Ei64 { + Ai64 = -1, + Bi64 = 0x8000_0000 +} + +pub fn main() { + assert_eq!(size_of::(), 1); + assert_eq!(size_of::(), 1); + assert_eq!(size_of::(), 2); + assert_eq!(size_of::(), 2); + assert_eq!(size_of::(), 4); + assert_eq!(size_of::(), 4); + #[cfg(target_pointer_width = "64")] + assert_eq!(size_of::(), 8); + #[cfg(target_pointer_width = "32")] + assert_eq!(size_of::(), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-manual-sizing.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-manual-sizing.rs new file mode 100644 index 000000000000..e1ec39fddb56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-manual-sizing.rs @@ -0,0 +1,112 @@ +// run-pass +#![allow(dead_code)] + +use std::mem::{size_of, align_of}; + +#[repr(i8)] +enum Ei8 { + Ai8 = 0, + Bi8 = 1 +} + +#[repr(u8)] +enum Eu8 { + Au8 = 0, + Bu8 = 1 +} + +#[repr(i16)] +enum Ei16 { + Ai16 = 0, + Bi16 = 1 +} + +#[repr(u16)] +enum Eu16 { + Au16 = 0, + Bu16 = 1 +} + +#[repr(i32)] +enum Ei32 { + Ai32 = 0, + Bi32 = 1 +} + +#[repr(u32)] +enum Eu32 { + Au32 = 0, + Bu32 = 1 +} + +#[repr(i64)] +enum Ei64 { + Ai64 = 0, + Bi64 = 1 +} + +#[repr(u64)] +enum Eu64 { + Au64 = 0, + Bu64 = 1 +} + +#[repr(isize)] +enum Eint { + Aint = 0, + Bint = 1 +} + +#[repr(usize)] +enum Euint { + Auint = 0, + Buint = 1 +} + +#[repr(u8)] +enum Eu8NonCLike { + _None, + _Some(T), +} + +#[repr(i64)] +enum Ei64NonCLike { + _None, + _Some(T), +} + +#[repr(u64)] +enum Eu64NonCLike { + _None, + _Some(T), +} + +pub fn main() { + assert_eq!(size_of::(), 1); + assert_eq!(size_of::(), 1); + assert_eq!(size_of::(), 2); + assert_eq!(size_of::(), 2); + assert_eq!(size_of::(), 4); + assert_eq!(size_of::(), 4); + assert_eq!(size_of::(), 8); + assert_eq!(size_of::(), 8); + assert_eq!(size_of::(), size_of::()); + assert_eq!(size_of::(), size_of::()); + assert_eq!(size_of::>(), 1); + assert_eq!(size_of::>(), 8); + assert_eq!(size_of::>(), 8); + let u8_expected_size = round_up(9, align_of::>()); + assert_eq!(size_of::>(), u8_expected_size); + let array_expected_size = round_up(28, align_of::>()); + assert_eq!(size_of::>(), array_expected_size); + assert_eq!(size_of::>(), 32); + + assert_eq!(align_of::(), align_of::()); + assert_eq!(align_of::>(), align_of::()); +} + +// Rounds x up to the next multiple of a +fn round_up(x: usize, a: usize) -> usize { + ((x + (a - 1)) / a) * a +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-range-overflow.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-range-overflow.rs new file mode 100644 index 000000000000..0299726d76aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-range-overflow.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(overflowing_literals)] + +// pretty-expanded FIXME #23616 + +pub enum E64 { + H64 = 0x7FFF_FFFF_FFFF_FFFF, + L64 = 0x8000_0000_0000_0000 +} +pub enum E32 { + H32 = 0x7FFF_FFFF, + L32 = 0x8000_0000 +} + +pub fn f(e64: E64, e32: E32) -> (bool,bool) { + (match e64 { + E64::H64 => true, + E64::L64 => false + }, + match e32 { + E32::H32 => true, + E32::L32 => false + }) +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-width-stuff.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-width-stuff.rs new file mode 100644 index 000000000000..2e6bc834fbf7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-discrim-width-stuff.rs @@ -0,0 +1,45 @@ +// run-pass +#![allow(overflowing_literals)] +#![allow(dead_code)] + +macro_rules! check { + ($m:ident, $t:ty, $v:expr) => {{ + mod $m { + use std::mem::size_of; + #[derive(Copy, Clone, Debug)] + enum E { + V = $v, + A = 0 + } + static C: E = E::V; + pub fn check() { + assert_eq!(size_of::(), size_of::<$t>()); + assert_eq!(E::V as $t, $v as $t); + assert_eq!(C as $t, $v as $t); + assert_eq!(format!("{:?}", E::V), "V".to_string()); + assert_eq!(format!("{:?}", C), "V".to_string()); + } + } + $m::check(); + }} +} + +pub fn main() { + check!(a, u8, 0x17); + check!(b, u8, 0xe8); + check!(c, u16, 0x1727); + check!(d, u16, 0xe8d8); + check!(e, u32, 0x17273747); + check!(f, u32, 0xe8d8c8b8); + + check!(z, i8, 0x17); + check!(y, i8, -0x17); + check!(x, i16, 0x1727); + check!(w, i16, -0x1727); + check!(v, i32, 0x17273747); + check!(u, i32, -0x17273747); + + enum Simple { A, B } + assert_eq!(::std::mem::size_of::(), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-disr-val-pretty.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-disr-val-pretty.rs new file mode 100644 index 000000000000..7fa452be89ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-disr-val-pretty.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(non_camel_case_types)] +// pp-exact + + +enum color { red = 1, green, blue, imaginary = -1, } + +pub fn main() { + test_color(color::red, 1, "red".to_string()); + test_color(color::green, 2, "green".to_string()); + test_color(color::blue, 3, "blue".to_string()); + test_color(color::imaginary, -1, "imaginary".to_string()); +} + +fn test_color(color: color, val: isize, _name: String) { + assert_eq!(color as isize , val); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-export-inheritance.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-export-inheritance.rs new file mode 100644 index 000000000000..a5421525ac73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-export-inheritance.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +mod a { + pub enum Foo { + Bar, + Baz, + Boo + } +} + +pub fn main() { + let _x = a::Foo::Bar; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-layout-optimization.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-layout-optimization.rs new file mode 100644 index 000000000000..2ed1c32554da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-layout-optimization.rs @@ -0,0 +1,51 @@ +// run-pass +// Test that we will do various size optimizations to enum layout, but +// *not* if `#[repr(u8)]` or `#[repr(C)]` is passed. See also #40029. + +#![allow(dead_code)] + +use std::mem; + +enum Nullable { + Alive(T), + Dropped, +} + +#[repr(u8)] +enum NullableU8 { + Alive(T), + Dropped, +} + +#[repr(C)] +enum NullableC { + Alive(T), + Dropped, +} + +struct StructNewtype(T); + +#[repr(C)] +struct StructNewtypeC(T); + +enum EnumNewtype { Variant(T) } + +#[repr(u8)] +enum EnumNewtypeU8 { Variant(T) } + +#[repr(C)] +enum EnumNewtypeC { Variant(T) } + +fn main() { + assert!(mem::size_of::>() == mem::size_of::>>()); + assert!(mem::size_of::>() < mem::size_of::>>()); + assert!(mem::size_of::>() < mem::size_of::>>()); + + assert!(mem::size_of::() == mem::size_of::>()); + assert!(mem::size_of::() == mem::size_of::>()); + + assert!(mem::size_of::() == mem::size_of::>()); + assert!(mem::size_of::() < mem::size_of::>()); + assert!(mem::size_of::() < mem::size_of::>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-non-c-like-repr-c-and-int.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-non-c-like-repr-c-and-int.rs new file mode 100644 index 000000000000..19a24cf01474 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-non-c-like-repr-c-and-int.rs @@ -0,0 +1,174 @@ +// run-pass +// This test deserializes an enum in-place by transmuting to a union that +// should have the same layout, and manipulating the tag and payloads +// independently. This verifies that `repr(some_int)` has a stable representation, +// and that we don't miscompile these kinds of manipulations. + +use std::time::Duration; +use std::mem; + +#[repr(C, u8)] +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +enum MyEnum { + A(u32), // Single primitive value + B { x: u8, y: i16, z: u8 }, // Composite, and the offsets of `y` and `z` + // depend on tag being internal + C, // Empty + D(Option), // Contains an enum + E(Duration), // Contains a struct +} + +#[repr(C)] +struct MyEnumRepr { + tag: MyEnumTag, + payload: MyEnumPayload, +} + +#[repr(C)] +#[allow(non_snake_case)] +union MyEnumPayload { + A: MyEnumVariantA, + B: MyEnumVariantB, + D: MyEnumVariantD, + E: MyEnumVariantE, +} + +#[repr(u8)] #[derive(Copy, Clone)] enum MyEnumTag { A, B, C, D, E } +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantA(u32); +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantB {x: u8, y: i16, z: u8 } +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantD(Option); +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantE(Duration); + +fn main() { + let result: Vec> = vec![ + Ok(MyEnum::A(17)), + Ok(MyEnum::B { x: 206, y: 1145, z: 78 }), + Ok(MyEnum::C), + Err(()), + Ok(MyEnum::D(Some(407))), + Ok(MyEnum::D(None)), + Ok(MyEnum::E(Duration::from_secs(100))), + Err(()), + ]; + + // Binary serialized version of the above (little-endian) + let input: Vec = vec![ + 0, 17, 0, 0, 0, + 1, 206, 121, 4, 78, + 2, + 8, /* invalid tag value */ + 3, 0, 151, 1, 0, 0, + 3, 1, + 4, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, /* incomplete value */ + ]; + + let mut output = vec![]; + let mut buf = &input[..]; + + unsafe { + // This should be safe, because we don't match on it unless it's fully formed, + // and it doesn't have a destructor. + // + // MyEnum is repr(C, u8) so it is guaranteed to have a separate discriminant and each + // variant can be zero initialized. + let mut dest: MyEnum = mem::zeroed(); + while buf.len() > 0 { + match parse_my_enum(&mut dest, &mut buf) { + Ok(()) => output.push(Ok(dest)), + Err(()) => output.push(Err(())), + } + } + } + + assert_eq!(output, result); +} + +fn parse_my_enum<'a>(dest: &'a mut MyEnum, buf: &mut &[u8]) -> Result<(), ()> { + unsafe { + // Should be correct to do this transmute. + let dest: &'a mut MyEnumRepr = mem::transmute(dest); + let tag = read_u8(buf)?; + + dest.tag = match tag { + 0 => MyEnumTag::A, + 1 => MyEnumTag::B, + 2 => MyEnumTag::C, + 3 => MyEnumTag::D, + 4 => MyEnumTag::E, + _ => return Err(()), + }; + + match dest.tag { + MyEnumTag::A => { + dest.payload.A.0 = read_u32_le(buf)?; + } + MyEnumTag::B => { + dest.payload.B.x = read_u8(buf)?; + dest.payload.B.y = read_u16_le(buf)? as i16; + dest.payload.B.z = read_u8(buf)?; + } + MyEnumTag::C => { + /* do nothing */ + } + MyEnumTag::D => { + let is_some = read_u8(buf)? == 0; + if is_some { + dest.payload.D.0 = Some(read_u32_le(buf)?); + } else { + dest.payload.D.0 = None; + } + } + MyEnumTag::E => { + let secs = read_u64_le(buf)?; + let nanos = read_u32_le(buf)?; + dest.payload.E.0 = Duration::new(secs, nanos); + } + } + Ok(()) + } +} + + + +// reader helpers + +fn read_u64_le(buf: &mut &[u8]) -> Result { + if buf.len() < 8 { return Err(()) } + let val = (buf[0] as u64) << 0 + | (buf[1] as u64) << 8 + | (buf[2] as u64) << 16 + | (buf[3] as u64) << 24 + | (buf[4] as u64) << 32 + | (buf[5] as u64) << 40 + | (buf[6] as u64) << 48 + | (buf[7] as u64) << 56; + *buf = &buf[8..]; + Ok(val) +} + +fn read_u32_le(buf: &mut &[u8]) -> Result { + if buf.len() < 4 { return Err(()) } + let val = (buf[0] as u32) << 0 + | (buf[1] as u32) << 8 + | (buf[2] as u32) << 16 + | (buf[3] as u32) << 24; + *buf = &buf[4..]; + Ok(val) +} + +fn read_u16_le(buf: &mut &[u8]) -> Result { + if buf.len() < 2 { return Err(()) } + let val = (buf[0] as u16) << 0 + | (buf[1] as u16) << 8; + *buf = &buf[2..]; + Ok(val) +} + +fn read_u8(buf: &mut &[u8]) -> Result { + if buf.len() < 1 { return Err(()) } + let val = buf[0]; + *buf = &buf[1..]; + Ok(val) +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-non-c-like-repr-c.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-non-c-like-repr-c.rs new file mode 100644 index 000000000000..d92944d09a05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-non-c-like-repr-c.rs @@ -0,0 +1,175 @@ +// run-pass +// This test deserializes an enum in-place by transmuting to a union that +// should have the same layout, and manipulating the tag and payloads +// independently. This verifies that `repr(some_int)` has a stable representation, +// and that we don't miscompile these kinds of manipulations. + +use std::time::Duration; +use std::mem; + +#[repr(C)] +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +enum MyEnum { + A(u32), // Single primitive value + B { x: u8, y: i16, z: u8 }, // Composite, and the offset of `y` and `z` + // depend on tag being internal + C, // Empty + D(Option), // Contains an enum + E(Duration), // Contains a struct +} + +#[repr(C)] +struct MyEnumRepr { + tag: MyEnumTag, + payload: MyEnumPayload, +} + +#[repr(C)] +#[allow(non_snake_case)] +union MyEnumPayload { + A: MyEnumVariantA, + B: MyEnumVariantB, + D: MyEnumVariantD, + E: MyEnumVariantE, +} + +#[repr(C)] #[derive(Copy, Clone)] enum MyEnumTag { A, B, C, D, E } +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantA(u32); +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantB {x: u8, y: i16, z: u8 } +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantD(Option); +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantE(Duration); + +fn main() { + let result: Vec> = vec![ + Ok(MyEnum::A(17)), + Ok(MyEnum::B { x: 206, y: 1145, z: 78 }), + Ok(MyEnum::C), + Err(()), + Ok(MyEnum::D(Some(407))), + Ok(MyEnum::D(None)), + Ok(MyEnum::E(Duration::from_secs(100))), + Err(()), + ]; + + // Binary serialized version of the above (little-endian) + let input: Vec = vec![ + 0, 17, 0, 0, 0, + 1, 206, 121, 4, 78, + 2, + 8, /* invalid tag value */ + 3, 0, 151, 1, 0, 0, + 3, 1, + 4, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, /* incomplete value */ + ]; + + let mut output = vec![]; + let mut buf = &input[..]; + + unsafe { + // This should be safe, because we don't match on it unless it's fully formed, + // and it doesn't have a destructor. + // + // Furthermore, there are no types within MyEnum which cannot be initialized with zero, + // specifically, though padding and such are present, there are no references or similar + // types. + let mut dest: MyEnum = mem::zeroed(); + while buf.len() > 0 { + match parse_my_enum(&mut dest, &mut buf) { + Ok(()) => output.push(Ok(dest)), + Err(()) => output.push(Err(())), + } + } + } + + assert_eq!(output, result); +} + +fn parse_my_enum<'a>(dest: &'a mut MyEnum, buf: &mut &[u8]) -> Result<(), ()> { + unsafe { + // Should be correct to do this transmute. + let dest: &'a mut MyEnumRepr = mem::transmute(dest); + let tag = read_u8(buf)?; + + dest.tag = match tag { + 0 => MyEnumTag::A, + 1 => MyEnumTag::B, + 2 => MyEnumTag::C, + 3 => MyEnumTag::D, + 4 => MyEnumTag::E, + _ => return Err(()), + }; + + match dest.tag { + MyEnumTag::A => { + dest.payload.A.0 = read_u32_le(buf)?; + } + MyEnumTag::B => { + dest.payload.B.x = read_u8(buf)?; + dest.payload.B.y = read_u16_le(buf)? as i16; + dest.payload.B.z = read_u8(buf)?; + } + MyEnumTag::C => { + /* do nothing */ + } + MyEnumTag::D => { + let is_some = read_u8(buf)? == 0; + if is_some { + dest.payload.D.0 = Some(read_u32_le(buf)?); + } else { + dest.payload.D.0 = None; + } + } + MyEnumTag::E => { + let secs = read_u64_le(buf)?; + let nanos = read_u32_le(buf)?; + dest.payload.E.0 = Duration::new(secs, nanos); + } + } + Ok(()) + } +} + + + +// reader helpers + +fn read_u64_le(buf: &mut &[u8]) -> Result { + if buf.len() < 8 { return Err(()) } + let val = (buf[0] as u64) << 0 + | (buf[1] as u64) << 8 + | (buf[2] as u64) << 16 + | (buf[3] as u64) << 24 + | (buf[4] as u64) << 32 + | (buf[5] as u64) << 40 + | (buf[6] as u64) << 48 + | (buf[7] as u64) << 56; + *buf = &buf[8..]; + Ok(val) +} + +fn read_u32_le(buf: &mut &[u8]) -> Result { + if buf.len() < 4 { return Err(()) } + let val = (buf[0] as u32) << 0 + | (buf[1] as u32) << 8 + | (buf[2] as u32) << 16 + | (buf[3] as u32) << 24; + *buf = &buf[4..]; + Ok(val) +} + +fn read_u16_le(buf: &mut &[u8]) -> Result { + if buf.len() < 2 { return Err(()) } + let val = (buf[0] as u16) << 0 + | (buf[1] as u16) << 8; + *buf = &buf[2..]; + Ok(val) +} + +fn read_u8(buf: &mut &[u8]) -> Result { + if buf.len() < 1 { return Err(()) } + let val = buf[0]; + *buf = &buf[1..]; + Ok(val) +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-non-c-like-repr-int.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-non-c-like-repr-int.rs new file mode 100644 index 000000000000..34e982b649b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-non-c-like-repr-int.rs @@ -0,0 +1,170 @@ +// run-pass +// This test deserializes an enum in-place by transmuting to a union that +// should have the same layout, and manipulating the tag and payloads +// independently. This verifies that `repr(some_int)` has a stable representation, +// and that we don't miscompile these kinds of manipulations. + +use std::time::Duration; +use std::mem; + +#[repr(u8)] +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +enum MyEnum { + A(u32), // Single primitive value + B { x: u8, y: i16, z: u8 }, // Composite, and the offset of `y` and `z` + // depend on tag being internal + C, // Empty + D(Option), // Contains an enum + E(Duration), // Contains a struct +} + +#[allow(non_snake_case)] +#[repr(C)] +union MyEnumRepr { + A: MyEnumVariantA, + B: MyEnumVariantB, + C: MyEnumVariantC, + D: MyEnumVariantD, + E: MyEnumVariantE, +} + +#[repr(u8)] #[derive(Copy, Clone)] enum MyEnumTag { A, B, C, D, E } +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantA(MyEnumTag, u32); +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantB { tag: MyEnumTag, x: u8, y: i16, z: u8 } +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantC(MyEnumTag); +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantD(MyEnumTag, Option); +#[repr(C)] #[derive(Copy, Clone)] struct MyEnumVariantE(MyEnumTag, Duration); + +fn main() { + let result: Vec> = vec![ + Ok(MyEnum::A(17)), + Ok(MyEnum::B { x: 206, y: 1145, z: 78 }), + Ok(MyEnum::C), + Err(()), + Ok(MyEnum::D(Some(407))), + Ok(MyEnum::D(None)), + Ok(MyEnum::E(Duration::from_secs(100))), + Err(()), + ]; + + // Binary serialized version of the above (little-endian) + let input: Vec = vec![ + 0, 17, 0, 0, 0, + 1, 206, 121, 4, 78, + 2, + 8, /* invalid tag value */ + 3, 0, 151, 1, 0, 0, + 3, 1, + 4, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, /* incomplete value */ + ]; + + let mut output = vec![]; + let mut buf = &input[..]; + + unsafe { + // This should be safe, because we don't match on it unless it's fully formed, + // and it doesn't have a destructor. + // + // MyEnum is repr(u8) so it is guaranteed to have a separate discriminant and each variant + // can be zero initialized. + let mut dest: MyEnum = mem::zeroed(); + while buf.len() > 0 { + match parse_my_enum(&mut dest, &mut buf) { + Ok(()) => output.push(Ok(dest)), + Err(()) => output.push(Err(())), + } + } + } + + assert_eq!(output, result); +} + +fn parse_my_enum<'a>(dest: &'a mut MyEnum, buf: &mut &[u8]) -> Result<(), ()> { + unsafe { + // Should be correct to do this transmute. + let dest: &'a mut MyEnumRepr = mem::transmute(dest); + let tag = read_u8(buf)?; + + dest.A.0 = match tag { + 0 => MyEnumTag::A, + 1 => MyEnumTag::B, + 2 => MyEnumTag::C, + 3 => MyEnumTag::D, + 4 => MyEnumTag::E, + _ => return Err(()), + }; + + match dest.B.tag { + MyEnumTag::A => { + dest.A.1 = read_u32_le(buf)?; + } + MyEnumTag::B => { + dest.B.x = read_u8(buf)?; + dest.B.y = read_u16_le(buf)? as i16; + dest.B.z = read_u8(buf)?; + } + MyEnumTag::C => { + /* do nothing */ + } + MyEnumTag::D => { + let is_some = read_u8(buf)? == 0; + if is_some { + dest.D.1 = Some(read_u32_le(buf)?); + } else { + dest.D.1 = None; + } + } + MyEnumTag::E => { + let secs = read_u64_le(buf)?; + let nanos = read_u32_le(buf)?; + dest.E.1 = Duration::new(secs, nanos); + } + } + Ok(()) + } +} + + + +// reader helpers + +fn read_u64_le(buf: &mut &[u8]) -> Result { + if buf.len() < 8 { return Err(()) } + let val = (buf[0] as u64) << 0 + | (buf[1] as u64) << 8 + | (buf[2] as u64) << 16 + | (buf[3] as u64) << 24 + | (buf[4] as u64) << 32 + | (buf[5] as u64) << 40 + | (buf[6] as u64) << 48 + | (buf[7] as u64) << 56; + *buf = &buf[8..]; + Ok(val) +} + +fn read_u32_le(buf: &mut &[u8]) -> Result { + if buf.len() < 4 { return Err(()) } + let val = (buf[0] as u32) << 0 + | (buf[1] as u32) << 8 + | (buf[2] as u32) << 16 + | (buf[3] as u32) << 24; + *buf = &buf[4..]; + Ok(val) +} + +fn read_u16_le(buf: &mut &[u8]) -> Result { + if buf.len() < 2 { return Err(()) } + let val = (buf[0] as u16) << 0 + | (buf[1] as u16) << 8; + *buf = &buf[2..]; + Ok(val) +} + +fn read_u8(buf: &mut &[u8]) -> Result { + if buf.len() < 1 { return Err(()) } + let val = buf[0]; + *buf = &buf[1..]; + Ok(val) +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-null-pointer-opt.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-null-pointer-opt.rs new file mode 100644 index 000000000000..9e72c7ba35e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-null-pointer-opt.rs @@ -0,0 +1,75 @@ +// run-pass +#![feature(transparent_unions)] + +use std::mem::size_of; +use std::num::NonZeroUsize; +use std::ptr::NonNull; +use std::rc::Rc; +use std::sync::Arc; + +trait Trait { fn dummy(&self) { } } +trait Mirror { type Image; } +impl Mirror for T { type Image = T; } +struct ParamTypeStruct(T); +struct AssocTypeStruct(::Image); +#[repr(transparent)] +union MaybeUninitUnion { + _value: T, + _uninit: (), +} + +fn main() { + // Functions + assert_eq!(size_of::(), size_of::>()); + assert_eq!(size_of::(), size_of::>()); + + // Slices - &str / &[T] / &mut [T] + assert_eq!(size_of::<&str>(), size_of::>()); + assert_eq!(size_of::<&[isize]>(), size_of::>()); + assert_eq!(size_of::<&mut [isize]>(), size_of::>()); + + // Traits - Box / &Trait / &mut Trait + assert_eq!(size_of::>(), size_of::>>()); + assert_eq!(size_of::<&dyn Trait>(), size_of::>()); + assert_eq!(size_of::<&mut dyn Trait>(), size_of::>()); + + // Pointers - Box + assert_eq!(size_of::>(), size_of::>>()); + + // The optimization can't apply to raw pointers or unions with a ZST field. + assert!(size_of::>() != size_of::<*const isize>()); + assert!(Some(std::ptr::null::()).is_some()); // Can't collapse None to null + assert_ne!(size_of::(), size_of::>>()); + assert_ne!(size_of::<&str>(), size_of::>>()); + assert_ne!(size_of::>(), size_of::>>>()); + + struct Foo { + _a: Box + } + struct Bar(Box); + + // Should apply through structs + assert_eq!(size_of::(), size_of::>()); + assert_eq!(size_of::(), size_of::>()); + // and tuples + assert_eq!(size_of::<(u8, Box)>(), size_of::)>>()); + // and fixed-size arrays + assert_eq!(size_of::<[Box; 1]>(), size_of::; 1]>>()); + + // Should apply to NonZero + assert_eq!(size_of::(), size_of::>()); + assert_eq!(size_of::>(), size_of::>>()); + + // Should apply to types that use NonZero internally + assert_eq!(size_of::>(), size_of::>>()); + assert_eq!(size_of::>(), size_of::>>()); + assert_eq!(size_of::>(), size_of::>>()); + + // Should apply to types that have NonZero transitively + assert_eq!(size_of::(), size_of::>()); + + // Should apply to types where the pointer is substituted + assert_eq!(size_of::<&u8>(), size_of::>>()); + assert_eq!(size_of::<&u8>(), size_of::>>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-nullable-const-null-with-fields.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-nullable-const-null-with-fields.rs new file mode 100644 index 000000000000..85f138839039 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-nullable-const-null-with-fields.rs @@ -0,0 +1,14 @@ +// run-pass + +use std::result::Result; +use std::result::Result::Ok; + +static C: Result<(), Box> = Ok(()); + +// This is because of yet another bad assertion (ICE) about the null side of a nullable enum. +// So we won't actually compile if the bug is present, but we check the value in main anyway. + +pub fn main() { + assert!(C.is_ok()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs new file mode 100644 index 000000000000..d35733881ad9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-nullable-simplifycfg-misopt.rs @@ -0,0 +1,18 @@ +// run-pass +#![feature(box_syntax)] + +/*! + * This is a regression test for a bug in LLVM, fixed in upstream r179587, + * where the switch instructions generated for destructuring enums + * represented with nullable pointers could be misoptimized in some cases. + */ + +enum List { Nil, Cons(X, Box>) } +pub fn main() { + match List::Cons(10, box List::Nil) { + List::Cons(10, _) => {} + List::Nil => {} + _ => panic!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-univariant-repr.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-univariant-repr.rs new file mode 100644 index 000000000000..2221e33ca2c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-univariant-repr.rs @@ -0,0 +1,52 @@ +// run-pass + +use std::mem; + +// Univariant C-like enum +#[repr(i32)] +enum Univariant { + X = 17 +} + +#[repr(u16)] +enum UnivariantWithoutDescr { + Y +} + +#[repr(u8)] +enum UnivariantWithData { + Z(u8), +} + +pub fn main() { + { + assert_eq!(4, mem::size_of::()); + assert_eq!(17, Univariant::X as i32); + + let enums: &[Univariant] = + &[Univariant::X, Univariant::X, Univariant::X]; + let ints: &[i32] = unsafe { mem::transmute(enums) }; + // check it has the same memory layout as i32 + assert_eq!(&[17, 17, 17], ints); + } + + { + assert_eq!(2, mem::size_of::()); + let descr = UnivariantWithoutDescr::Y as u16; + + let enums: &[UnivariantWithoutDescr] = + &[UnivariantWithoutDescr::Y, UnivariantWithoutDescr::Y, UnivariantWithoutDescr::Y]; + let ints: &[u16] = unsafe { mem::transmute(enums) }; + // check it has the same memory layout as u16 + assert_eq!(&[descr, descr, descr], ints); + } + + { + assert_eq!(2, mem::size_of::()); + + match UnivariantWithData::Z(4) { + UnivariantWithData::Z(x) => assert_eq!(x, 4), + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-variants.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-variants.rs new file mode 100644 index 000000000000..3927b8d38c9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-variants.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_assignments)] +// pretty-expanded FIXME #23616 + +#![allow(unused_variables)] + +enum Animal { + Dog (String, f64), + Cat { name: String, weight: f64 } +} + +pub fn main() { + let mut a: Animal = Animal::Dog("Cocoa".to_string(), 37.2); + a = Animal::Cat{ name: "Spotty".to_string(), weight: 2.7 }; + // permuting the fields should work too + let _c = Animal::Cat { weight: 3.1, name: "Spreckles".to_string() }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/enum-vec-initializer.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-vec-initializer.rs new file mode 100644 index 000000000000..c7b364f267ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/enum-vec-initializer.rs @@ -0,0 +1,18 @@ +// run-pass +// pretty-expanded FIXME #23616 + +enum Flopsy { + Bunny = 2 +} + +const BAR:usize = Flopsy::Bunny as usize; +const BAR2:usize = BAR; + +pub fn main() { + let _v = [0; Flopsy::Bunny as usize]; + let _v = [0; BAR]; + let _v = [0; BAR2]; + const BAR3:usize = BAR2; + let _v = [0; BAR3]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/export-abstract-tag.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/export-abstract-tag.rs new file mode 100644 index 000000000000..3dc825f8eb70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/export-abstract-tag.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(non_camel_case_types)] + +// We can export tags without exporting the variants to create a simple +// sort of ADT. + +// pretty-expanded FIXME #23616 + +mod foo { + pub enum t { t1, } + + pub fn f() -> t { return t::t1; } +} + +pub fn main() { let _v: foo::t = foo::f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/export-tag-variant.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/export-tag-variant.rs new file mode 100644 index 000000000000..16c234d1a7e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/export-tag-variant.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(non_camel_case_types)] +// pretty-expanded FIXME #23616 + +mod foo { + pub enum t { t1, } +} + +pub fn main() { let _v = foo::t::t1; } + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/expr-if-struct.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/expr-if-struct.rs new file mode 100644 index 000000000000..1e12a378190f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/expr-if-struct.rs @@ -0,0 +1,33 @@ +// run-pass +#![allow(non_camel_case_types)] + + + + +// Tests for if as expressions returning nominal types + +#[derive(Copy, Clone)] +struct I { i: isize } + +fn test_rec() { + let rs = if true { I {i: 100} } else { I {i: 101} }; + assert_eq!(rs.i, 100); +} + +#[derive(Copy, Clone, Debug)] +enum mood { happy, sad, } + +impl PartialEq for mood { + fn eq(&self, other: &mood) -> bool { + ((*self) as usize) == ((*other) as usize) + } + fn ne(&self, other: &mood) -> bool { !(*self).eq(other) } +} + +fn test_tag() { + let rs = if true { mood::happy } else { mood::sad }; + assert_eq!(rs, mood::happy); +} + +pub fn main() { test_rec(); test_tag(); } + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/expr-match-struct.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/expr-match-struct.rs new file mode 100644 index 000000000000..6a85cecc2ae9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/expr-match-struct.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(non_camel_case_types)] + + + + +// Tests for match as expressions resulting in struct types +#[derive(Copy, Clone)] +struct R { i: isize } + +fn test_rec() { + let rs = match true { true => R {i: 100}, _ => panic!() }; + assert_eq!(rs.i, 100); +} + +#[derive(Copy, Clone, Debug)] +enum mood { happy, sad, } + +impl PartialEq for mood { + fn eq(&self, other: &mood) -> bool { + ((*self) as usize) == ((*other) as usize) + } + fn ne(&self, other: &mood) -> bool { !(*self).eq(other) } +} + +fn test_tag() { + let rs = match true { true => { mood::happy } false => { mood::sad } }; + assert_eq!(rs, mood::happy); +} + +pub fn main() { test_rec(); test_tag(); } + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/field-destruction-order.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/field-destruction-order.rs new file mode 100644 index 000000000000..6462161a0a8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/field-destruction-order.rs @@ -0,0 +1,48 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +// In theory, it doesn't matter what order destructors are run in for rust +// because we have explicit ownership of values meaning that there's no need to +// run one before another. With unsafe code, however, there may be a safe +// interface which relies on fields having their destructors run in a particular +// order. At the time of this writing, std::rt::sched::Scheduler is an example +// of a structure which contains unsafe handles to FFI-like types, and the +// destruction order of the fields matters in the sense that some handles need +// to get destroyed before others. +// +// In C++, destruction order happens bottom-to-top in order of field +// declarations, but we currently run them top-to-bottom. I don't think the +// order really matters that much as long as we define what it is. + + +struct A; +struct B; +struct C { + a: A, + b: B, +} + +static mut hit: bool = false; + +impl Drop for A { + fn drop(&mut self) { + unsafe { + assert!(!hit); + hit = true; + } + } +} + +impl Drop for B { + fn drop(&mut self) { + unsafe { + assert!(hit); + } + } +} + +pub fn main() { + let _c = C { a: A, b: B }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/foreign-struct.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/foreign-struct.rs new file mode 100644 index 000000000000..7db1bb537767 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/foreign-struct.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// Passing enums by value + +// pretty-expanded FIXME #23616 + +pub enum void { } + +mod bindgen { + use super::void; + + extern { + pub fn printf(v: void); + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/functional-struct-upd.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/functional-struct-upd.rs new file mode 100644 index 000000000000..9fa56bb3acab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/functional-struct-upd.rs @@ -0,0 +1,13 @@ +// run-pass +#[derive(Debug)] +struct Foo { + x: isize, + y: isize +} + +pub fn main() { + let a = Foo { x: 1, y: 2 }; + let c = Foo { x: 4, .. a}; + println!("{:?}", c); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/ivec-tag.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/ivec-tag.rs new file mode 100644 index 000000000000..d68f82d2ec0f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/ivec-tag.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +use std::thread; +use std::sync::mpsc::{channel, Sender}; + +fn producer(tx: &Sender>) { + tx.send( + vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13]).unwrap(); +} + +pub fn main() { + let (tx, rx) = channel::>(); + let prod = thread::spawn(move|| { + producer(&tx) + }); + + let _data: Vec = rx.recv().unwrap(); + prod.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/module-qualified-struct-destructure.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/module-qualified-struct-destructure.rs new file mode 100644 index 000000000000..d1d591685c5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/module-qualified-struct-destructure.rs @@ -0,0 +1,15 @@ +// run-pass +// pretty-expanded FIXME #23616 + +mod m { + pub struct S { + pub x: isize, + pub y: isize + } +} + +pub fn main() { + let x = m::S { x: 1, y: 2 }; + let m::S { x: _a, y: _b } = x; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs new file mode 100644 index 000000000000..c85043621b2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-emulate-flat-xc.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(non_camel_case_types)] + +// aux-build:namespaced_enum_emulate_flat.rs + +// pretty-expanded FIXME #23616 + +extern crate namespaced_enum_emulate_flat; + +use namespaced_enum_emulate_flat::{Foo, A, B, C}; +use namespaced_enum_emulate_flat::nest::{Bar, D, E, F}; + +fn _f(f: Foo) { + match f { + A | B(_) | C { .. } => {} + } +} + +fn _f2(f: Bar) { + match f { + D | E(_) | F { .. } => {} + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-emulate-flat.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-emulate-flat.rs new file mode 100644 index 000000000000..4c9e8ce250c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-emulate-flat.rs @@ -0,0 +1,45 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +pub use Foo::*; +use nest::{Bar, D, E, F}; + +pub enum Foo { + A, + B(isize), + C { a: isize }, +} + +impl Foo { + pub fn foo() {} +} + +fn _f(f: Foo) { + match f { + A | B(_) | C { .. } => {} + } +} + +mod nest { + pub use self::Bar::*; + + pub enum Bar { + D, + E(isize), + F { a: isize }, + } + + impl Bar { + pub fn foo() {} + } +} + +fn _f2(f: Bar) { + match f { + D | E(_) | F { .. } => {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs new file mode 100644 index 000000000000..2ffd883d8c40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-glob-import-xcrate.rs @@ -0,0 +1,27 @@ +// run-pass +// aux-build:namespaced_enums.rs + +// pretty-expanded FIXME #23616 + +extern crate namespaced_enums; + +fn _f(f: namespaced_enums::Foo) { + use namespaced_enums::Foo::*; + + match f { + A | B(_) | C { .. } => {} + } +} + +mod m { + pub use namespaced_enums::Foo::*; +} + +fn _f2(f: namespaced_enums::Foo) { + match f { + m::A | m::B(_) | m::C { .. } => {} + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-glob-import.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-glob-import.rs new file mode 100644 index 000000000000..2a6b4d347fca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enum-glob-import.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +mod m2 { + pub enum Foo { + A, + B(isize), + C { a: isize }, + } + + impl Foo { + pub fn foo() {} + } +} + +mod m { + pub use m2::Foo::*; +} + +fn _f(f: m2::Foo) { + use m2::Foo::*; + + match f { + A | B(_) | C { .. } => {} + } +} + +fn _f2(f: m2::Foo) { + match f { + m::A | m::B(_) | m::C { .. } => {} + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enums-xcrate.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enums-xcrate.rs new file mode 100644 index 000000000000..488c7569ec7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enums-xcrate.rs @@ -0,0 +1,17 @@ +// run-pass +// aux-build:namespaced_enums.rs + +// pretty-expanded FIXME #23616 + +extern crate namespaced_enums; + +use namespaced_enums::Foo; + +fn _foo (f: Foo) { + match f { + Foo::A | Foo::B(_) | Foo::C { .. } => {} + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enums.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enums.rs new file mode 100644 index 000000000000..bc68197a7699 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/namespaced-enums.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +enum Foo { + A, + B(isize), + C { a: isize }, +} + +fn _foo (f: Foo) { + match f { + Foo::A | Foo::B(_) | Foo::C { .. } => {} + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/nested-enum-same-names.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/nested-enum-same-names.rs new file mode 100644 index 000000000000..183c66ce582e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/nested-enum-same-names.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +/* + +#7770 ICE with sibling methods containing same-name-enum containing + same-name-member + +If you have two methods in an impl block, each containing an enum +(with the same name), each containing at least one value with the same +name, rustc gives the same LLVM symbol for the two of them and fails, +as it does not include the method name in the symbol name. + +*/ + +pub struct Foo; +impl Foo { + pub fn foo() { + enum Panic { Common }; + } + pub fn bar() { + enum Panic { Common }; + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-drop-run.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-drop-run.rs new file mode 100644 index 000000000000..3672c313b93b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-drop-run.rs @@ -0,0 +1,22 @@ +// run-pass +// Make sure the destructor is run for newtype structs. + +use std::cell::Cell; + +struct Foo<'a>(&'a Cell); + +impl<'a> Drop for Foo<'a> { + fn drop(&mut self) { + let Foo(i) = *self; + i.set(23); + } +} + +pub fn main() { + let y = &Cell::new(32); + { + let _x = Foo(y); + } + assert_eq!(y.get(), 23); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-with-dtor.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-with-dtor.rs new file mode 100644 index 000000000000..f31845976481 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-with-dtor.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(unused_unsafe)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +pub struct Fd(u32); + +fn foo(a: u32) {} + +impl Drop for Fd { + fn drop(&mut self) { + unsafe { + let Fd(s) = *self; + foo(s); + } + } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-xc-2.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-xc-2.rs new file mode 100644 index 000000000000..13926cef53b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-xc-2.rs @@ -0,0 +1,16 @@ +// run-pass +// aux-build:newtype_struct_xc.rs + +// pretty-expanded FIXME #23616 + +extern crate newtype_struct_xc; +use newtype_struct_xc::Au; + +fn f() -> Au { + Au(2) +} + +pub fn main() { + let _ = f(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-xc.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-xc.rs new file mode 100644 index 000000000000..aca42f56066c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/newtype-struct-xc.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:newtype_struct_xc.rs + +// pretty-expanded FIXME #23616 + +extern crate newtype_struct_xc; + +pub fn main() { + let _ = newtype_struct_xc::Au(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/nonzero-enum.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/nonzero-enum.rs new file mode 100644 index 000000000000..bf2a9ae362b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/nonzero-enum.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(dead_code)] +use std::mem::size_of; + +enum E { + A = 1, + B = 2, + C = 3, +} + +struct S { + a: u16, + b: u8, + e: E, +} + +fn main() { + assert_eq!(size_of::(), 1); + assert_eq!(size_of::>(), 1); + assert_eq!(size_of::>(), 1); + assert_eq!(size_of::>(), size_of::()); + let enone = None::; + let esome = Some(E::A); + if let Some(..) = enone { + panic!(); + } + if let None = esome { + panic!(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/numeric-fields.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/numeric-fields.rs new file mode 100644 index 000000000000..c7091410b92e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/numeric-fields.rs @@ -0,0 +1,13 @@ +// run-pass +struct S(u8, u16); + +fn main() { + let s = S{1: 10, 0: 11}; + match s { + S{0: a, 1: b, ..} => { + assert_eq!(a, 11); + assert_eq!(b, 10); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/object-lifetime-default-from-ref-struct.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/object-lifetime-default-from-ref-struct.rs new file mode 100644 index 000000000000..d0cc2c24b321 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/object-lifetime-default-from-ref-struct.rs @@ -0,0 +1,59 @@ +// run-pass +// Test that the lifetime of the enclosing `&` is used for the object +// lifetime bound. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +use std::fmt::Display; + +trait Test { + fn foo(&self) { } +} + +struct Ref<'a,T:'a+?Sized> { + r: &'a T +} + +struct Ref2<'a,'b,T:'a+'b+?Sized> { + a: &'a T, + b: &'b T +} + +struct SomeStruct<'a> { + t: Ref<'a, dyn Test>, + u: Ref<'a, dyn Test+'a>, +} + +fn a<'a>(t: Ref<'a, dyn Test>, mut ss: SomeStruct<'a>) { + ss.t = t; +} + +fn b<'a>(t: Ref<'a, dyn Test>, mut ss: SomeStruct<'a>) { + ss.u = t; +} + +fn c<'a>(t: Ref<'a, dyn Test+'a>, mut ss: SomeStruct<'a>) { + ss.t = t; +} + +fn d<'a>(t: Ref<'a, dyn Test+'a>, mut ss: SomeStruct<'a>) { + ss.u = t; +} + +fn e<'a>(_: Ref<'a, dyn Display+'static>) {} +fn g<'a, 'b>(_: Ref2<'a, 'b, dyn Display+'static>) {} + + +fn main() { + // Inside a function body, we can just infer all + // lifetimes, to allow Ref<'tmp, Display+'static> + // and Ref2<'tmp, 'tmp, Display+'static>. + let x = &0 as &(dyn Display+'static); + let r: Ref = Ref { r: x }; + let r2: Ref2 = Ref2 { a: x, b: x }; + e(r); + g(r2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs new file mode 100644 index 000000000000..30acc11607ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/object-lifetime-default-from-rptr-struct.rs @@ -0,0 +1,38 @@ +// run-pass +// Test that the lifetime from the enclosing `&` is "inherited" +// through the `MyBox` struct. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +trait Test { + fn foo(&self) { } +} + +struct SomeStruct<'a> { + t: &'a MyBox, + u: &'a MyBox, +} + +struct MyBox { + b: Box +} + +fn a<'a>(t: &'a MyBox, mut ss: SomeStruct<'a>) { + ss.t = t; +} + +fn b<'a>(t: &'a MyBox, mut ss: SomeStruct<'a>) { + ss.u = t; +} + +// see also compile-fail/object-lifetime-default-from-rptr-box-error.rs + +fn d<'a>(t: &'a MyBox, mut ss: SomeStruct<'a>) { + ss.u = t; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/rec-align-u32.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/rec-align-u32.rs new file mode 100644 index 000000000000..f69f4f4a3327 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/rec-align-u32.rs @@ -0,0 +1,57 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_unsafe)] +// Issue #2303 + +#![feature(intrinsics)] + +use std::mem; + +mod rusti { + extern "rust-intrinsic" { + pub fn pref_align_of() -> usize; + pub fn min_align_of() -> usize; + } +} + +// This is the type with the questionable alignment +#[derive(Debug)] +struct Inner { + c64: u32 +} + +// This is the type that contains the type with the +// questionable alignment, for testing +#[derive(Debug)] +struct Outer { + c8: u8, + t: Inner +} + +mod m { + pub fn align() -> usize { 4 } + pub fn size() -> usize { 8 } +} + +pub fn main() { + unsafe { + let x = Outer {c8: 22, t: Inner {c64: 44}}; + + // Send it through the shape code + let y = format!("{:?}", x); + + println!("align inner = {:?}", rusti::min_align_of::()); + println!("size outer = {:?}", mem::size_of::()); + println!("y = {:?}", y); + + // per clang/gcc the alignment of `inner` is 4 on x86. + assert_eq!(rusti::min_align_of::(), m::align()); + + // per clang/gcc the size of `outer` should be 12 + // because `inner`s alignment was 4. + assert_eq!(mem::size_of::(), m::size()); + + assert_eq!(y, "Outer { c8: 22, t: Inner { c64: 44 } }".to_string()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/rec-align-u64.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/rec-align-u64.rs new file mode 100644 index 000000000000..056c20ceb93d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/rec-align-u64.rs @@ -0,0 +1,96 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_unsafe)] +// ignore-wasm32-bare seems unimportant to test + +// Issue #2303 + +#![feature(intrinsics)] + +use std::mem; + +mod rusti { + extern "rust-intrinsic" { + pub fn pref_align_of() -> usize; + pub fn min_align_of() -> usize; + } +} + +// This is the type with the questionable alignment +#[derive(Debug)] +struct Inner { + c64: u64 +} + +// This is the type that contains the type with the +// questionable alignment, for testing +#[derive(Debug)] +struct Outer { + c8: u8, + t: Inner +} + + +#[cfg(any(target_os = "android", + target_os = "cloudabi", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "solaris", + target_os = "vxworks"))] +mod m { + #[cfg(target_arch = "x86")] + pub mod m { + pub fn align() -> usize { 4 } + pub fn size() -> usize { 12 } + } + + #[cfg(not(target_arch = "x86"))] + pub mod m { + pub fn align() -> usize { 8 } + pub fn size() -> usize { 16 } + } +} + +#[cfg(target_env = "sgx")] +mod m { + #[cfg(target_arch = "x86_64")] + pub mod m { + pub fn align() -> usize { 8 } + pub fn size() -> usize { 16 } + } +} + +#[cfg(target_os = "windows")] +mod m { + pub mod m { + pub fn align() -> usize { 8 } + pub fn size() -> usize { 16 } + } +} + +pub fn main() { + unsafe { + let x = Outer {c8: 22, t: Inner {c64: 44}}; + + let y = format!("{:?}", x); + + println!("align inner = {:?}", rusti::min_align_of::()); + println!("size outer = {:?}", mem::size_of::()); + println!("y = {:?}", y); + + // per clang/gcc the alignment of `Inner` is 4 on x86. + assert_eq!(rusti::min_align_of::(), m::m::align()); + + // per clang/gcc the size of `Outer` should be 12 + // because `Inner`s alignment was 4. + assert_eq!(mem::size_of::(), m::m::size()); + + assert_eq!(y, "Outer { c8: 22, t: Inner { c64: 44 } }".to_string()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/rec-auto.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/rec-auto.rs new file mode 100644 index 000000000000..b286f4a3494a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/rec-auto.rs @@ -0,0 +1,15 @@ +// run-pass + + + + +// Issue #50. + +struct X { foo: String, bar: String } + +pub fn main() { + let x = X {foo: "hello".to_string(), bar: "world".to_string()}; + println!("{}", x.foo.clone()); + println!("{}", x.bar.clone()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/rec-extend.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/rec-extend.rs new file mode 100644 index 000000000000..a3e7a1ef0950 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/rec-extend.rs @@ -0,0 +1,19 @@ +// run-pass + + + + +struct Point {x: isize, y: isize} + +pub fn main() { + let origin: Point = Point {x: 0, y: 0}; + let right: Point = Point {x: origin.x + 10,.. origin}; + let up: Point = Point {y: origin.y + 10,.. origin}; + assert_eq!(origin.x, 0); + assert_eq!(origin.y, 0); + assert_eq!(right.x, 10); + assert_eq!(right.y, 0); + assert_eq!(up.x, 0); + assert_eq!(up.y, 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/rec-tup.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/rec-tup.rs new file mode 100644 index 000000000000..6e78de59351d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/rec-tup.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(non_camel_case_types)] + + +#[derive(Copy, Clone)] +struct Point {x: isize, y: isize} + +type rect = (Point, Point); + +fn fst(r: rect) -> Point { let (fst, _) = r; return fst; } +fn snd(r: rect) -> Point { let (_, snd) = r; return snd; } + +fn f(r: rect, x1: isize, y1: isize, x2: isize, y2: isize) { + assert_eq!(fst(r).x, x1); + assert_eq!(fst(r).y, y1); + assert_eq!(snd(r).x, x2); + assert_eq!(snd(r).y, y2); +} + +pub fn main() { + let r: rect = (Point {x: 10, y: 20}, Point {x: 11, y: 22}); + assert_eq!(fst(r).x, 10); + assert_eq!(fst(r).y, 20); + assert_eq!(snd(r).x, 11); + assert_eq!(snd(r).y, 22); + let r2 = r; + let x: isize = fst(r2).x; + assert_eq!(x, 10); + f(r, 10, 20, 11, 22); + f(r2, 10, 20, 11, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/rec.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/rec.rs new file mode 100644 index 000000000000..39a68fd5134e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/rec.rs @@ -0,0 +1,25 @@ +// run-pass + +#[derive(Copy, Clone)] +struct Rect {x: isize, y: isize, w: isize, h: isize} + +fn f(r: Rect, x: isize, y: isize, w: isize, h: isize) { + assert_eq!(r.x, x); + assert_eq!(r.y, y); + assert_eq!(r.w, w); + assert_eq!(r.h, h); +} + +pub fn main() { + let r: Rect = Rect {x: 10, y: 20, w: 100, h: 200}; + assert_eq!(r.x, 10); + assert_eq!(r.y, 20); + assert_eq!(r.w, 100); + assert_eq!(r.h, 200); + let r2: Rect = r; + let x: isize = r2.x; + assert_eq!(x, 10); + f(r, 10, 20, 100, 200); + f(r2, 10, 20, 100, 200); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/record-pat.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/record-pat.rs new file mode 100644 index 000000000000..321d93b09b16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/record-pat.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(non_camel_case_types)] +#![allow(non_shorthand_field_patterns)] + +enum t1 { a(isize), b(usize), } +struct T2 {x: t1, y: isize} +enum t3 { c(T2, usize), } + +fn m(input: t3) -> isize { + match input { + t3::c(T2 {x: t1::a(m), ..}, _) => { return m; } + t3::c(T2 {x: t1::b(m), y: y}, z) => { return ((m + z) as isize) + y; } + } +} + +pub fn main() { + assert_eq!(m(t3::c(T2 {x: t1::a(10), y: 5}, 4)), 10); + assert_eq!(m(t3::c(T2 {x: t1::b(10), y: 5}, 4)), 19); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/resource-in-struct.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/resource-in-struct.rs new file mode 100644 index 000000000000..75ff25d7a240 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/resource-in-struct.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(non_camel_case_types)] + +// Ensures that class dtors run if the object is inside an enum +// variant + +use std::cell::Cell; + +type closable<'a> = &'a Cell; + +struct close_res<'a> { + i: closable<'a>, + +} + +impl<'a> Drop for close_res<'a> { + fn drop(&mut self) { + self.i.set(false); + } +} + +fn close_res(i: closable) -> close_res { + close_res { + i: i + } +} + +enum option { none, some(T), } + +fn sink(_res: option) { } + +pub fn main() { + let c = &Cell::new(true); + sink(option::none); + sink(option::some(close_res(c))); + assert!(!c.get()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/simple-generic-tag.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/simple-generic-tag.rs new file mode 100644 index 000000000000..913fc8714a4d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/simple-generic-tag.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + + + +// pretty-expanded FIXME #23616 + +enum clam { a(T), } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/simple-match-generic-tag.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/simple-match-generic-tag.rs new file mode 100644 index 000000000000..6a54c2187df3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/simple-match-generic-tag.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +enum opt { none, some(T) } + +pub fn main() { + let x = opt::none::; + match x { + opt::none:: => { println!("hello world"); } + opt::some(_) => { } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/small-enum-range-edge.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/small-enum-range-edge.rs new file mode 100644 index 000000000000..d0831d6f3145 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/small-enum-range-edge.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(non_upper_case_globals)] + +// Tests the range assertion wraparound case when reading discriminants. + +#[repr(u8)] +#[derive(Copy, Clone)] +enum Eu { Lu = 0, Hu = 255 } + +static CLu: Eu = Eu::Lu; +static CHu: Eu = Eu::Hu; + +#[repr(i8)] +#[derive(Copy, Clone)] +enum Es { Ls = -128, Hs = 127 } + +static CLs: Es = Es::Ls; +static CHs: Es = Es::Hs; + +pub fn main() { + assert_eq!((Eu::Hu as u8).wrapping_add(1), Eu::Lu as u8); + assert_eq!((Es::Hs as i8).wrapping_add(1), Es::Ls as i8); + assert_eq!(CLu as u8, Eu::Lu as u8); + assert_eq!(CHu as u8, Eu::Hu as u8); + assert_eq!(CLs as i8, Es::Ls as i8); + assert_eq!(CHs as i8, Es::Hs as i8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/small-enums-with-fields.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/small-enums-with-fields.rs new file mode 100644 index 000000000000..7fe96752cb55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/small-enums-with-fields.rs @@ -0,0 +1,34 @@ +// run-pass +use std::mem::size_of; + +#[derive(PartialEq, Debug)] +enum Either { Left(T), Right(U) } + +macro_rules! check { + ($t:ty, $sz:expr, $($e:expr, $s:expr),*) => {{ + assert_eq!(size_of::<$t>(), $sz); + $({ + static S: $t = $e; + let v: $t = $e; + assert_eq!(S, v); + assert_eq!(format!("{:?}", v), $s); + assert_eq!(format!("{:?}", S), $s); + });* + }} +} + +pub fn main() { + check!(Option, 2, + None, "None", + Some(129), "Some(129)"); + check!(Option, 4, + None, "None", + Some(-20000), "Some(-20000)"); + check!(Either, 2, + Either::Left(132), "Left(132)", + Either::Right(-32), "Right(-32)"); + check!(Either, 4, + Either::Left(132), "Left(132)", + Either::Right(-20000), "Right(-20000)"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-aliases-xcrate.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-aliases-xcrate.rs new file mode 100644 index 000000000000..8d0c36bb9b5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-aliases-xcrate.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(unused_imports)] +#![allow(non_shorthand_field_patterns)] + +// aux-build:xcrate_struct_aliases.rs + +extern crate xcrate_struct_aliases; + +use xcrate_struct_aliases::{S, S2}; + +fn main() { + let s = S2 { + x: 1, + y: 2, + }; + match s { + S2 { + x: x, + y: y + } => { + assert_eq!(x, 1); + assert_eq!(y, 2); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-aliases.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-aliases.rs new file mode 100644 index 000000000000..f728bd96272e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-aliases.rs @@ -0,0 +1,65 @@ +// run-pass +#![allow(non_shorthand_field_patterns)] + +use std::mem; + +struct S { + x: isize, + y: isize, +} + +type S2 = S; + +struct S3 { + x: U, + y: V +} + +type S4 = S3; + +fn main() { + let s = S2 { + x: 1, + y: 2, + }; + match s { + S2 { + x: x, + y: y + } => { + assert_eq!(x, 1); + assert_eq!(y, 2); + } + } + // check that generics can be specified from the pattern + let s = S4 { + x: 4, + y: 'a' + }; + match s { + S4:: { + x: x, + y: y + } => { + assert_eq!(x, 4); + assert_eq!(y, 'a'); + assert_eq!(mem::size_of_val(&x), 1); + } + }; + // check that generics can be specified from the constructor + let s = S4:: { + x: 5, + y: 'b' + }; + match s { + S4 { + x: x, + y: y + } => { + assert_eq!(x, 5); + assert_eq!(y, 'b'); + assert_eq!(mem::size_of_val(&x), 2); + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-destructuring-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-destructuring-cross-crate.rs new file mode 100644 index 000000000000..7a489aba370a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-destructuring-cross-crate.rs @@ -0,0 +1,13 @@ +// run-pass +// aux-build:struct_destructuring_cross_crate.rs + + +extern crate struct_destructuring_cross_crate; + +pub fn main() { + let x = struct_destructuring_cross_crate::S { x: 1, y: 2 }; + let struct_destructuring_cross_crate::S { x: a, y: b } = x; + assert_eq!(a, 1); + assert_eq!(b, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-field-shorthand.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-field-shorthand.rs new file mode 100644 index 000000000000..01376e6735e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-field-shorthand.rs @@ -0,0 +1,27 @@ +// run-pass +struct Foo { + x: i32, + y: bool, + z: i32 +} + +struct Bar { + x: i32 +} + +pub fn main() { + let (x, y, z) = (1, true, 2); + let a = Foo { x, y: y, z }; + assert_eq!(a.x, x); + assert_eq!(a.y, y); + assert_eq!(a.z, z); + + let b = Bar { x, }; + assert_eq!(b.x, x); + + let c = Foo { z, y, x }; + assert_eq!(c.x, x); + assert_eq!(c.y, y); + assert_eq!(c.z, z); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-like-variant-construct.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-like-variant-construct.rs new file mode 100644 index 000000000000..6490ecc15317 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-like-variant-construct.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +enum Foo { + Bar { + a: isize, + b: isize + }, + Baz { + c: f64, + d: f64 + } +} + +pub fn main() { + let _x = Foo::Bar { a: 2, b: 3 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-like-variant-match.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-like-variant-match.rs new file mode 100644 index 000000000000..0740876b8d15 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-like-variant-match.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(non_shorthand_field_patterns)] + +enum Foo { + Bar { + x: isize, + y: isize + }, + Baz { + x: f64, + y: f64 + } +} + +fn f(x: &Foo) { + match *x { + Foo::Baz { x: x, y: y } => { + assert_eq!(x, 1.0); + assert_eq!(y, 2.0); + } + Foo::Bar { y: y, x: x } => { + assert_eq!(x, 1); + assert_eq!(y, 2); + } + } +} + +pub fn main() { + let x = Foo::Bar { x: 1, y: 2 }; + f(&x); + let y = Foo::Baz { x: 1.0, y: 2.0 }; + f(&y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-lit-functional-no-fields.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-lit-functional-no-fields.rs new file mode 100644 index 000000000000..ce73a0b8295d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-lit-functional-no-fields.rs @@ -0,0 +1,27 @@ +// run-pass +#[derive(Debug,PartialEq,Clone)] +struct Foo { + bar: T, + baz: T +} + +pub fn main() { + let foo = Foo { + bar: 0, + baz: 1 + }; + + let foo_ = foo.clone(); + let foo = Foo { ..foo }; + assert_eq!(foo, foo_); + + let foo = Foo { + bar: "one".to_string(), + baz: "two".to_string() + }; + + let foo_ = foo.clone(); + let foo = Foo { ..foo }; + assert_eq!(foo, foo_); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-literal-dtor.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-literal-dtor.rs new file mode 100644 index 000000000000..94600376243d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-literal-dtor.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(non_camel_case_types)] + +struct foo { + x: String, +} + +impl Drop for foo { + fn drop(&mut self) { + println!("{}", self.x); + } +} + +pub fn main() { + let _z = foo { + x: "Hello".to_string() + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-new-as-field-name.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-new-as-field-name.rs new file mode 100644 index 000000000000..d5b0bb2c1b4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-new-as-field-name.rs @@ -0,0 +1,11 @@ +// run-pass + +struct Foo { + new: isize, +} + +pub fn main() { + let foo = Foo{ new: 3 }; + assert_eq!(foo.new, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-1.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-1.rs new file mode 100644 index 000000000000..9950ece64a05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-1.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] + +struct S { f0: String, f1: isize } + +pub fn main() { + let s = "Hello, world!".to_string(); + let s = S { + f0: s.to_string(), + ..S { + f0: s, + f1: 23 + } + }; + assert_eq!(s.f0, "Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-2.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-2.rs new file mode 100644 index 000000000000..fe891fb4c68a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-2.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(dead_code)] + +struct S { + f0: String, + f1: String, +} + +pub fn main() { + let s = "Hello, world!".to_string(); + let s = S { + f1: s.to_string(), + f0: s + }; + assert_eq!(s.f0, "Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-3.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-3.rs new file mode 100644 index 000000000000..2d9b81313a82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-3.rs @@ -0,0 +1,38 @@ +// run-pass +// Checks that functional-record-update order-of-eval is as expected +// even when no Drop-implementations are involved. + +use std::sync::atomic::{Ordering, AtomicUsize}; + +struct W { wrapped: u32 } +struct S { f0: W, _f1: i32 } + +pub fn main() { + const VAL: u32 = 0x89AB_CDEF; + let w = W { wrapped: VAL }; + let s = S { + f0: { event(0x01); W { wrapped: w.wrapped + 1 } }, + ..S { + f0: { event(0x02); w}, + _f1: 23 + } + }; + assert_eq!(s.f0.wrapped, VAL + 1); + let actual = event_log(); + let expect = 0x01_02; + assert!(expect == actual, + "expect: 0x{:x} actual: 0x{:x}", expect, actual); +} + +static LOG: AtomicUsize = AtomicUsize::new(0); + +fn event_log() -> usize { + LOG.load(Ordering::SeqCst) +} + +fn event(tag: u8) { + let old_log = LOG.load(Ordering::SeqCst); + let new_log = (old_log << 8) + tag as usize; + LOG.store(new_log, Ordering::SeqCst); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-4.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-4.rs new file mode 100644 index 000000000000..95943cb2b51b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-order-of-eval-4.rs @@ -0,0 +1,35 @@ +// run-pass +// Checks that struct-literal expression order-of-eval is as expected +// even when no Drop-implementations are involved. + +use std::sync::atomic::{Ordering, AtomicUsize}; + +struct W { wrapped: u32 } +struct S { f0: W, _f1: i32 } + +pub fn main() { + const VAL: u32 = 0x89AB_CDEF; + let w = W { wrapped: VAL }; + let s = S { + _f1: { event(0x01); 23 }, + f0: { event(0x02); w }, + }; + assert_eq!(s.f0.wrapped, VAL); + let actual = event_log(); + let expect = 0x01_02; + assert!(expect == actual, + "expect: 0x{:x} actual: 0x{:x}", expect, actual); +} + +static LOG: AtomicUsize = AtomicUsize::new(0); + +fn event_log() -> usize { + LOG.load(Ordering::SeqCst) +} + +fn event(tag: u8) { + let old_log = LOG.load(Ordering::SeqCst); + let new_log = (old_log << 8) + tag as usize; + LOG.store(new_log, Ordering::SeqCst); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-partial-move-1.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-partial-move-1.rs new file mode 100644 index 000000000000..2b67257bba81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-partial-move-1.rs @@ -0,0 +1,22 @@ +// run-pass +#[derive(PartialEq, Debug)] +pub struct Partial { x: T, y: T } + +#[derive(PartialEq, Debug)] +struct S { val: isize } +impl S { fn new(v: isize) -> S { S { val: v } } } +impl Drop for S { fn drop(&mut self) { } } + +pub fn f((b1, b2): (T, T), mut f: F) -> Partial where F: FnMut(T) -> T { + let p = Partial { x: b1, y: b2 }; + + // Move of `p` is legal even though we are also moving `p.y`; the + // `..p` moves all fields *except* `p.y` in this context. + Partial { y: f(p.y), ..p } +} + +pub fn main() { + let p = f((S::new(3), S::new(4)), |S { val: z }| S::new(z+1)); + assert_eq!(p, Partial { x: S::new(3), y: S::new(5) }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-partial-move-2.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-partial-move-2.rs new file mode 100644 index 000000000000..6797278db724 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-partial-move-2.rs @@ -0,0 +1,29 @@ +// run-pass +#[derive(PartialEq, Debug)] +pub struct Partial { x: T, y: T } + +#[derive(PartialEq, Debug)] +struct S { val: isize } +impl S { fn new(v: isize) -> S { S { val: v } } } +impl Drop for S { fn drop(&mut self) { } } + +pub type Two = (Partial, Partial); + +pub fn f((b1, b2): (T, T), (b3, b4): (T, T), mut f: F) -> Two where F: FnMut(T) -> T { + let p = Partial { x: b1, y: b2 }; + let q = Partial { x: b3, y: b4 }; + + // Move of `q` is legal even though we have already moved `q.y`; + // the `..q` moves all fields *except* `q.y` in this context. + // Likewise, the move of `p.x` is legal for similar reasons. + (Partial { x: f(q.y), ..p }, Partial { y: f(p.x), ..q }) +} + +pub fn main() { + let two = f((S::new(1), S::new(3)), + (S::new(5), S::new(7)), + |S { val: z }| S::new(z+1)); + assert_eq!(two, (Partial { x: S::new(8), y: S::new(3) }, + Partial { x: S::new(5), y: S::new(2) })); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-path-associated-type.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-path-associated-type.rs new file mode 100644 index 000000000000..d7f217882356 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-path-associated-type.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(dead_code)] +struct S { + a: T, + b: U, +} + +trait Tr { + type A; +} +impl Tr for u8 { + type A = S; +} + +fn f>>() { + let s = T::A { a: 0, b: 1 }; + match s { + T::A { a, b } => { + assert_eq!(a, 0); + assert_eq!(b, 1); + } + } +} + +fn main() { + f::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-path-self.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-path-self.rs new file mode 100644 index 000000000000..d9b8bc49a7d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-path-self.rs @@ -0,0 +1,46 @@ +// run-pass +use std::ops::Add; + +struct S { + a: T, + b: U, +} + +trait Tr { + fn f(&self) -> Self; +} + +impl, U: Default> Tr for S { + fn f(&self) -> Self { + let s = Self { a: Default::default(), b: Default::default() }; + match s { + Self { a, b } => Self { a: a + 1, b: b } + } + } +} + +impl> S { + fn g(&self) -> Self { + let s = Self { a: Default::default(), b: Default::default() }; + match s { + Self { a, b } => Self { a: a, b: b + 1 } + } + } +} + +impl S { + fn new() -> Self { + Self { a: 0, b: 1 } + } +} + +fn main() { + let s0 = S::new(); + let s1 = s0.f(); + assert_eq!(s1.a, 1); + assert_eq!(s1.b, 0); + let s2 = s0.g(); + assert_eq!(s2.a, 0); + assert_eq!(s2.b, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-pattern-matching.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-pattern-matching.rs new file mode 100644 index 000000000000..277ddd91ba86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-pattern-matching.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(non_shorthand_field_patterns)] + +struct Foo { + x: isize, + y: isize, +} + +pub fn main() { + let a = Foo { x: 1, y: 2 }; + match a { + Foo { x: x, y: y } => println!("yes, {}, {}", x, y) + } + + match a { + Foo { .. } => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct-variant-field-visibility.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-variant-field-visibility.rs new file mode 100644 index 000000000000..81620ccaea2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct-variant-field-visibility.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +mod foo { + pub enum Foo { + Bar { a: isize } + } +} + +fn f(f: foo::Foo) { + match f { + foo::Foo::Bar { a: _a } => {} + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct_variant_xc.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct_variant_xc.rs new file mode 100644 index 000000000000..380661102d0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct_variant_xc.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:struct_variant_xc_aux.rs +// pretty-expanded FIXME #23616 + +extern crate struct_variant_xc_aux; + +use struct_variant_xc_aux::Enum::StructVariant; + +pub fn main() { + let _ = StructVariant { arg: 1 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/struct_variant_xc_match.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/struct_variant_xc_match.rs new file mode 100644 index 000000000000..ad0d950e9951 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/struct_variant_xc_match.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:struct_variant_xc_aux.rs + +extern crate struct_variant_xc_aux; + +use struct_variant_xc_aux::Enum::{StructVariant, Variant}; + +pub fn main() { + let arg = match (StructVariant { arg: 42 }) { + Variant(_) => unreachable!(), + StructVariant { arg } => arg + }; + assert_eq!(arg, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-dyn-u64.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-dyn-u64.rs new file mode 100644 index 000000000000..8a06e0602be0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-dyn-u64.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(dead_code)] +#![allow(deprecated)] + +use std::mem; + +enum Tag { + Tag2(A) +} + +struct Rec { + c8: u8, + t: Tag +} + +fn mk_rec() -> Rec { + return Rec { c8:0, t:Tag::Tag2(0) }; +} + +fn is_u64_aligned(u: &Tag) -> bool { + let p: usize = unsafe { mem::transmute(u) }; + let u64_align = std::mem::min_align_of::(); + return (p & (u64_align - 1)) == 0; +} + +pub fn main() { + let x = mk_rec(); + assert!(is_u64_aligned(&x.t)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-dyn-variants.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-dyn-variants.rs new file mode 100644 index 000000000000..aa961bc9b7a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-dyn-variants.rs @@ -0,0 +1,68 @@ +// run-pass +#![allow(dead_code)] +#![allow(deprecated)] +#![allow(non_snake_case)] + +use std::mem; + +enum Tag { + VarA(A), + VarB(B), +} + +struct Rec { + chA: u8, + tA: Tag, + chB: u8, + tB: Tag, +} + +fn mk_rec(a: A, b: B) -> Rec { + Rec { chA:0, tA:Tag::VarA(a), chB:1, tB:Tag::VarB(b) } +} + +fn is_aligned(amnt: usize, u: &A) -> bool { + let p: usize = unsafe { mem::transmute(u) }; + return (p & (amnt-1)) == 0; +} + +fn variant_data_is_aligned(amnt: usize, u: &Tag) -> bool { + match u { + &Tag::VarA(ref a) => is_aligned(amnt, a), + &Tag::VarB(ref b) => is_aligned(amnt, b) + } +} + +pub fn main() { + let u64_align = std::mem::min_align_of::(); + let x = mk_rec(22u64, 23u64); + assert!(is_aligned(u64_align, &x.tA)); + assert!(variant_data_is_aligned(u64_align, &x.tA)); + assert!(is_aligned(u64_align, &x.tB)); + assert!(variant_data_is_aligned(u64_align, &x.tB)); + + let x = mk_rec(22u64, 23u32); + assert!(is_aligned(u64_align, &x.tA)); + assert!(variant_data_is_aligned(u64_align, &x.tA)); + assert!(is_aligned(u64_align, &x.tB)); + assert!(variant_data_is_aligned(4, &x.tB)); + + let x = mk_rec(22u32, 23u64); + assert!(is_aligned(u64_align, &x.tA)); + assert!(variant_data_is_aligned(4, &x.tA)); + assert!(is_aligned(u64_align, &x.tB)); + assert!(variant_data_is_aligned(u64_align, &x.tB)); + + let x = mk_rec(22u32, 23u32); + assert!(is_aligned(4, &x.tA)); + assert!(variant_data_is_aligned(4, &x.tA)); + assert!(is_aligned(4, &x.tB)); + assert!(variant_data_is_aligned(4, &x.tB)); + + let x = mk_rec(22f64, 23f64); + assert!(is_aligned(u64_align, &x.tA)); + assert!(variant_data_is_aligned(u64_align, &x.tA)); + assert!(is_aligned(u64_align, &x.tB)); + assert!(variant_data_is_aligned(u64_align, &x.tB)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-shape.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-shape.rs new file mode 100644 index 000000000000..90f4d83b6ea0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-shape.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(non_camel_case_types)] + +#[derive(Debug)] +enum a_tag { + a_tag_var(u64) +} + +#[derive(Debug)] +struct t_rec { + c8: u8, + t: a_tag +} + +pub fn main() { + let x = t_rec {c8: 22, t: a_tag::a_tag_var(44)}; + let y = format!("{:?}", x); + println!("y = {:?}", y); + assert_eq!(y, "t_rec { c8: 22, t: a_tag_var(44) }".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-u64.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-u64.rs new file mode 100644 index 000000000000..0052d55dabe8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-align-u64.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(dead_code)] +#![allow(deprecated)] + +use std::mem; + +enum Tag { + TagInner(u64) +} + +struct Rec { + c8: u8, + t: Tag +} + +fn mk_rec() -> Rec { + return Rec { c8:0, t:Tag::TagInner(0) }; +} + +fn is_u64_aligned(u: &Tag) -> bool { + let p: usize = unsafe { mem::transmute(u) }; + let u64_align = std::mem::min_align_of::(); + return (p & (u64_align - 1)) == 0; +} + +pub fn main() { + let x = mk_rec(); + assert!(is_u64_aligned(&x.t)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tag-disr-val-shape.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-disr-val-shape.rs new file mode 100644 index 000000000000..b4d1006c6b7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-disr-val-shape.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +#[derive(Debug)] +enum color { + red = 0xff0000, + green = 0x00ff00, + blue = 0x0000ff, + black = 0x000000, + white = 0xFFFFFF, +} + +pub fn main() { + let act = format!("{:?}", color::red); + println!("{}", act); + assert_eq!("red".to_string(), act); + assert_eq!("green".to_string(), format!("{:?}", color::green)); + assert_eq!("white".to_string(), format!("{:?}", color::white)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tag-exports.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-exports.rs new file mode 100644 index 000000000000..e3104953980c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-exports.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +use alder::*; + +mod alder { + pub enum burnside { couch, davis } + pub enum everett { flanders, glisan, hoyt } + pub enum irving { johnson, kearney, lovejoy } + pub enum marshall { northrup, overton } +} + +pub fn main() { + let _pettygrove: burnside = burnside::couch; + let _quimby: everett = everett::flanders; + let _raleigh: irving = irving::johnson; + let _savier: marshall; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tag-in-block.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-in-block.rs new file mode 100644 index 000000000000..cddad9cdf529 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-in-block.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + + + +// pretty-expanded FIXME #23616 + +fn foo() { + fn zed(_z: bar) { } + enum bar { nil, } + fn baz() { zed(bar::nil); } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tag-variant-disr-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-variant-disr-type-mismatch.rs new file mode 100644 index 000000000000..5333a956b619 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-variant-disr-type-mismatch.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +enum color { + red = 1, + blue = 2, +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tag-variant-disr-val.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-variant-disr-val.rs new file mode 100644 index 000000000000..822a118ed9e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tag-variant-disr-val.rs @@ -0,0 +1,67 @@ +// run-pass +#![allow(non_camel_case_types)] + +use color::{red, green, blue, black, white, imaginary, purple, orange}; + +#[derive(Copy, Clone)] +enum color { + red = 0xff0000, + green = 0x00ff00, + blue = 0x0000ff, + black = 0x000000, + white = 0xFFFFFF, + imaginary = -1, + purple = 1 << 1, + orange = 8 >> 1 +} + +impl PartialEq for color { + fn eq(&self, other: &color) -> bool { + ((*self) as usize) == ((*other) as usize) + } + fn ne(&self, other: &color) -> bool { !(*self).eq(other) } +} + +pub fn main() { + test_color(red, 0xff0000, "red".to_string()); + test_color(green, 0x00ff00, "green".to_string()); + test_color(blue, 0x0000ff, "blue".to_string()); + test_color(black, 0x000000, "black".to_string()); + test_color(white, 0xFFFFFF, "white".to_string()); + test_color(imaginary, -1, "imaginary".to_string()); + test_color(purple, 2, "purple".to_string()); + test_color(orange, 4, "orange".to_string()); +} + +fn test_color(color: color, val: isize, name: String) { + //assert_eq!(unsafe::transmute(color), val); + assert_eq!(color as isize, val); + assert_eq!(get_color_alt(color), name); + assert_eq!(get_color_if(color), name); +} + +fn get_color_alt(color: color) -> String { + match color { + red => {"red".to_string()} + green => {"green".to_string()} + blue => {"blue".to_string()} + black => {"black".to_string()} + white => {"white".to_string()} + imaginary => {"imaginary".to_string()} + purple => {"purple".to_string()} + orange => {"orange".to_string()} + } +} + +fn get_color_if(color: color) -> String { + if color == red {"red".to_string()} + else if color == green {"green".to_string()} + else if color == blue {"blue".to_string()} + else if color == black {"black".to_string()} + else if color == white {"white".to_string()} + else if color == imaginary {"imaginary".to_string()} + else if color == purple {"purple".to_string()} + else if color == orange {"orange".to_string()} + else {"unknown".to_string()} +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tag.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tag.rs new file mode 100644 index 000000000000..04c6e81c44b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tag.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(unused_parens)] +#![allow(non_camel_case_types)] + + +enum colour { red(isize, isize), green, } + +impl PartialEq for colour { + fn eq(&self, other: &colour) -> bool { + match *self { + colour::red(a0, b0) => { + match (*other) { + colour::red(a1, b1) => a0 == a1 && b0 == b1, + colour::green => false, + } + } + colour::green => { + match (*other) { + colour::red(..) => false, + colour::green => true + } + } + } + } + fn ne(&self, other: &colour) -> bool { !(*self).eq(other) } +} + +fn f() { let x = colour::red(1, 2); let y = colour::green; assert!((x != y)); } + +pub fn main() { f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-construct.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-construct.rs new file mode 100644 index 000000000000..fa365c19ab78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-construct.rs @@ -0,0 +1,9 @@ +// run-pass +#[derive(Debug)] +struct Foo(isize, isize); + +pub fn main() { + let x = Foo(1, 2); + println!("{:?}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-constructor-pointer.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-constructor-pointer.rs new file mode 100644 index 000000000000..2c94d0536a1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-constructor-pointer.rs @@ -0,0 +1,13 @@ +// run-pass +#[derive(PartialEq, Debug)] +struct Foo(isize); +#[derive(PartialEq, Debug)] +struct Bar(isize, isize); + +pub fn main() { + let f: fn(isize) -> Foo = Foo; + let g: fn(isize, isize) -> Bar = Bar; + assert_eq!(f(42), Foo(42)); + assert_eq!(g(4, 7), Bar(4, 7)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-destructuring.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-destructuring.rs new file mode 100644 index 000000000000..24ae93e21536 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-destructuring.rs @@ -0,0 +1,11 @@ +// run-pass +struct Foo(isize, isize); + +pub fn main() { + let x = Foo(1, 2); + let Foo(y, z) = x; + println!("{} {}", y, z); + assert_eq!(y, 1); + assert_eq!(z, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-matching.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-matching.rs new file mode 100644 index 000000000000..326b212df54f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-matching.rs @@ -0,0 +1,14 @@ +// run-pass +struct Foo(isize, isize); + +pub fn main() { + let x = Foo(1, 2); + match x { + Foo(a, b) => { + assert_eq!(a, 1); + assert_eq!(b, 2); + println!("{} {}", a, b); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-trivial.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-trivial.rs new file mode 100644 index 000000000000..504973bcecac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/tuple-struct-trivial.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct Foo(isize, isize, isize); + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/uninstantiable-struct.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/uninstantiable-struct.rs new file mode 100644 index 000000000000..c6f3cf4c155f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/uninstantiable-struct.rs @@ -0,0 +1,5 @@ +// run-pass +pub struct Z(&'static Z); + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/unit-like-struct-drop-run.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/unit-like-struct-drop-run.rs new file mode 100644 index 000000000000..5719dbd2f960 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/unit-like-struct-drop-run.rs @@ -0,0 +1,24 @@ +// run-pass +// ignore-emscripten no threads support + +// Make sure the destructor is run for unit-like structs. + +use std::thread; + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) { + panic!("This panic should happen."); + } +} + +pub fn main() { + let x = thread::spawn(move|| { + let _b = Foo; + }).join(); + + let s = x.unwrap_err().downcast::<&'static str>().unwrap(); + assert_eq!(&**s, "This panic should happen."); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/unit-like-struct.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/unit-like-struct.rs new file mode 100644 index 000000000000..6b8984910deb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/unit-like-struct.rs @@ -0,0 +1,10 @@ +// run-pass +struct Foo; + +pub fn main() { + let x: Foo = Foo; + match x { + Foo => { println!("hi"); } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs-enums/variant-structs-trivial.rs b/gcc/testsuite/rust/rustc/ui/structs-enums/variant-structs-trivial.rs new file mode 100644 index 000000000000..a17a94424085 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs-enums/variant-structs-trivial.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +enum Foo { + Bar { x: isize }, + Baz { y: isize } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/structs/auxiliary/struct_field_privacy.rs b/gcc/testsuite/rust/rustc/ui/structs/auxiliary/struct_field_privacy.rs new file mode 100644 index 000000000000..efb731008b0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/auxiliary/struct_field_privacy.rs @@ -0,0 +1,10 @@ +pub struct A { + a: isize, + pub b: isize, +} + +pub struct B { + pub a: isize, + b: isize, +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/auxiliary/struct_variant_privacy.rs b/gcc/testsuite/rust/rustc/ui/structs/auxiliary/struct_variant_privacy.rs new file mode 100644 index 000000000000..79fede8471c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/auxiliary/struct_variant_privacy.rs @@ -0,0 +1,4 @@ +enum Bar { + Baz { a: isize } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/rhs-type.rs b/gcc/testsuite/rust/rustc/ui/structs/rhs-type.rs new file mode 100644 index 000000000000..9bac1b0b152e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/rhs-type.rs @@ -0,0 +1,19 @@ +// Tests that codegen treats the rhs of pth's decl +// as a _|_-typed thing, not a str-typed thing + +// run-fail +// error-pattern:bye +// ignore-emscripten no processes + +#![allow(unreachable_code)] +#![allow(unused_variables)] + +struct T { + t: String, +} + +fn main() { + let pth = panic!("bye"); + let _rs: T = T { t: pth }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-base-wrong-type.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-base-wrong-type.rs new file mode 100644 index 000000000000..64b0e87bf8e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-base-wrong-type.rs @@ -0,0 +1,15 @@ +// Check that `base` in `Fru { field: expr, ..base }` must have right type. + +struct Foo { a: isize, b: isize } +struct Bar { x: isize } + +static bar: Bar = Bar { x: 5 }; +static foo: Foo = Foo { a: 2, ..bar }; // { dg-error ".E0308." "" { target *-*-* } } +static foo_i: Foo = Foo { a: 2, ..4 }; // { dg-error ".E0308." "" { target *-*-* } } + +fn main() { + let b = Bar { x: 5 }; + let f = Foo { a: 2, ..b }; // { dg-error ".E0308." "" { target *-*-* } } + let f__isize = Foo { a: 2, ..4 }; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-duplicate-comma.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-duplicate-comma.rs new file mode 100644 index 000000000000..71f6431d41ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-duplicate-comma.rs @@ -0,0 +1,16 @@ +// run-rustfix +// Issue #50974 + +pub struct Foo { + pub a: u8, + pub b: u8 +} + +fn main() { + let _ = Foo { + a: 0,, +// { dg-error "" "" { target *-*-* } .-1 } + b: 42 + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-field-cfg.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-field-cfg.rs new file mode 100644 index 000000000000..83c2a20d7daa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-field-cfg.rs @@ -0,0 +1,19 @@ +struct Foo { + present: (), +} + +fn main() { + let foo = Foo { #[cfg(all())] present: () }; + let _ = Foo { #[cfg(any())] present: () }; +// { dg-error ".E0063." "" { target *-*-* } .-1 } + let _ = Foo { present: (), #[cfg(any())] absent: () }; + let _ = Foo { present: (), #[cfg(all())] absent: () }; +// { dg-error ".E0560." "" { target *-*-* } .-1 } + let Foo { #[cfg(all())] present: () } = foo; + let Foo { #[cfg(any())] present: () } = foo; +// { dg-error ".E0027." "" { target *-*-* } .-1 } + let Foo { present: (), #[cfg(any())] absent: () } = foo; + let Foo { present: (), #[cfg(all())] absent: () } = foo; +// { dg-error ".E0026." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-field-init-syntax.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-field-init-syntax.rs new file mode 100644 index 000000000000..b1cb6150a9cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-field-init-syntax.rs @@ -0,0 +1,21 @@ +// issue #41834 + +#[derive(Default)] +struct Foo { + one: u8, +} + +fn main() { + let foo = Foo { + one: 111, + ..Foo::default(), +// { dg-error "" "" { target *-*-* } .-1 } + }; + + let foo = Foo { + ..Foo::default(), +// { dg-error "" "" { target *-*-* } .-1 } + one: 111, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-field-privacy.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-field-privacy.rs new file mode 100644 index 000000000000..8bc10a7cd103 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-field-privacy.rs @@ -0,0 +1,39 @@ +// aux-build:struct_field_privacy.rs + +extern crate struct_field_privacy as xc; + +struct A { + a: isize, +} + +mod inner { + pub struct A { + a: isize, + pub b: isize, + } + pub struct B { + pub a: isize, + b: isize, + } + pub struct Z(pub isize, isize); +} + +fn test(a: A, b: inner::A, c: inner::B, d: xc::A, e: xc::B, z: inner::Z) { + a.a; + b.a; // { dg-error ".E0616." "" { target *-*-* } } + b.b; + c.a; + c.b; // { dg-error ".E0616." "" { target *-*-* } } + + d.a; // { dg-error ".E0616." "" { target *-*-* } } + d.b; + + e.a; + e.b; // { dg-error ".E0616." "" { target *-*-* } } + + z.0; + z.1; // { dg-error ".E0616." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-fields-decl-dupe.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-decl-dupe.rs new file mode 100644 index 000000000000..eaa0c1104171 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-decl-dupe.rs @@ -0,0 +1,9 @@ +struct BuildData { + foo: isize, + foo: isize, +// { dg-error ".E0124." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-fields-dupe.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-dupe.rs new file mode 100644 index 000000000000..45d603502940 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-dupe.rs @@ -0,0 +1,11 @@ +struct BuildData { + foo: isize, +} + +fn main() { + let foo = BuildData { + foo: 0, + foo: 0 // { dg-error ".E0062." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-fields-hints-no-dupe.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-hints-no-dupe.rs new file mode 100644 index 000000000000..9548a96f6f48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-hints-no-dupe.rs @@ -0,0 +1,15 @@ +struct A { + foo : i32, + car : i32, + barr : i32 +} + +fn main() { + let a = A { + foo : 5, + bar : 42, +// { dg-error ".E0560." "" { target *-*-* } .-1 } + car : 9, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-fields-hints.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-hints.rs new file mode 100644 index 000000000000..6fa549ff2984 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-hints.rs @@ -0,0 +1,14 @@ +struct A { + foo : i32, + car : i32, + barr : i32 +} + +fn main() { + let a = A { + foo : 5, + bar : 42, +// { dg-error ".E0560." "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-fields-missing.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-missing.rs new file mode 100644 index 000000000000..e2c9b7695c36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-missing.rs @@ -0,0 +1,11 @@ +struct BuildData { + foo: isize, + bar: Box, +} + +fn main() { + let foo = BuildData { // { dg-error ".E0063." "" { target *-*-* } } + foo: 0 + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-fields-shorthand-unresolved.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-shorthand-unresolved.rs new file mode 100644 index 000000000000..d114f463dc80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-shorthand-unresolved.rs @@ -0,0 +1,13 @@ +struct Foo { + x: i32, + y: i32 +} + +fn main() { + let x = 0; + let foo = Foo { + x, + y // { dg-error ".E0425." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-fields-shorthand.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-shorthand.rs new file mode 100644 index 000000000000..62aed4fa23b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-shorthand.rs @@ -0,0 +1,12 @@ +struct Foo { + x: i32, + y: i32 +} + +fn main() { + let (x, y, z) = (0, 1, 2); + let foo = Foo { + x, y, z // { dg-error ".E0560." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-fields-too-many.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-too-many.rs new file mode 100644 index 000000000000..ce11d2b9e9ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-too-many.rs @@ -0,0 +1,12 @@ +struct BuildData { + foo: isize, +} + +fn main() { + let foo = BuildData { + foo: 0, + bar: 0 +// { dg-error ".E0560." "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-fields-typo.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-typo.rs new file mode 100644 index 000000000000..7c32e3ad6e9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-fields-typo.rs @@ -0,0 +1,16 @@ +struct BuildData { + foo: isize, + bar: f32 +} + +fn main() { + let foo = BuildData { + foo: 0, + bar: 0.5, + }; + let x = foo.baa; // { dg-error ".E0609." "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + println!("{}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-missing-comma.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-missing-comma.rs new file mode 100644 index 000000000000..086c8d55cadb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-missing-comma.rs @@ -0,0 +1,13 @@ +// Issue #50636 +// run-rustfix + +pub struct S { + pub foo: u32 // { dg-error "" "" { target *-*-* } } + // ~^ HELP try adding a comma: ',' + pub bar: u32 +} + +fn main() { + let _ = S { foo: 5, bar: 6 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-pat-derived-error.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-pat-derived-error.rs new file mode 100644 index 000000000000..234c9c2d6f13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-pat-derived-error.rs @@ -0,0 +1,15 @@ +struct A { + b: usize, + c: usize +} + +impl A { + fn foo(&self) { + let A { x, y } = self.d; // { dg-error ".E0027." "" { target *-*-* } } +// { dg-error ".E0027." "" { target *-*-* } .-1 } +// { dg-error ".E0027." "" { target *-*-* } .-2 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-path-alias-bounds.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-path-alias-bounds.rs new file mode 100644 index 000000000000..4f937118a0d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-path-alias-bounds.rs @@ -0,0 +1,12 @@ +// issue #36286 + +struct S { a: T } + +struct NoClone; +type A = S; + +fn main() { + let s = A { a: NoClone }; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-path-associated-type.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-path-associated-type.rs new file mode 100644 index 000000000000..6546ee28226f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-path-associated-type.rs @@ -0,0 +1,38 @@ +struct S; + +trait Tr { + type A; +} + +impl Tr for S { + type A = S; +} + +fn f() { + let s = T::A {}; +// { dg-error ".E0071." "" { target *-*-* } .-1 } + let z = T::A:: {}; +// { dg-error ".E0071." "" { target *-*-* } .-1 } +// { dg-error ".E0109." "" { target *-*-* } .-2 } + match S { + T::A {} => {} +// { dg-error ".E0071." "" { target *-*-* } .-1 } + } +} + +fn g>() { + let s = T::A {}; // OK + let z = T::A:: {}; // { dg-error ".E0109." "" { target *-*-* } } + match S { + T::A {} => {} // OK + } +} + +fn main() { + let s = S::A {}; // { dg-error ".E0223." "" { target *-*-* } } + let z = S::A:: {}; // { dg-error ".E0223." "" { target *-*-* } } + match S { + S::A {} => {} // { dg-error ".E0223." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-path-self-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-path-self-type-mismatch.rs new file mode 100644 index 000000000000..71363d0eae7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-path-self-type-mismatch.rs @@ -0,0 +1,22 @@ +struct Foo { inner: A } + +trait Bar { fn bar(); } + +impl Bar for Foo { + fn bar() { + Self { inner: 1.5f32 }; // { dg-error ".E0308." "" { target *-*-* } } + } +} + +impl Foo { + fn new(u: U) -> Foo { + Self { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + inner: u +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-path-self.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-path-self.rs new file mode 100644 index 000000000000..db099b8bd142 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-path-self.rs @@ -0,0 +1,38 @@ +struct S; + +trait Tr { + fn f() { + let s = Self {}; +// { dg-error ".E0071." "" { target *-*-* } .-1 } + let z = Self:: {}; +// { dg-error ".E0071." "" { target *-*-* } .-1 } +// { dg-error ".E0109." "" { target *-*-* } .-2 } + match s { + Self { .. } => {} +// { dg-error ".E0071." "" { target *-*-* } .-1 } + } + } +} + +impl Tr for S { + fn f() { + let s = Self {}; // OK + let z = Self:: {}; // { dg-error ".E0109." "" { target *-*-* } } + match s { + Self { .. } => {} // OK + } + } +} + +impl S { + fn g() { + let s = Self {}; // OK + let z = Self:: {}; // { dg-error ".E0109." "" { target *-*-* } } + match s { + Self { .. } => {} // OK + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-variant-privacy-xc.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-variant-privacy-xc.rs new file mode 100644 index 000000000000..d4cdfa06eb79 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-variant-privacy-xc.rs @@ -0,0 +1,11 @@ +// aux-build:struct_variant_privacy.rs +extern crate struct_variant_privacy; + +fn f(b: struct_variant_privacy::Bar) { // { dg-error ".E0603." "" { target *-*-* } } + match b { + struct_variant_privacy::Bar::Baz { a: _a } => {} // { dg-error ".E0603." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/struct-variant-privacy.rs b/gcc/testsuite/rust/rustc/ui/structs/struct-variant-privacy.rs new file mode 100644 index 000000000000..4f76d82c017f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/struct-variant-privacy.rs @@ -0,0 +1,14 @@ +mod foo { + enum Bar { + Baz { a: isize } + } +} + +fn f(b: foo::Bar) { // { dg-error ".E0603." "" { target *-*-* } } + match b { + foo::Bar::Baz { a: _a } => {} // { dg-error ".E0603." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/structs/structure-constructor-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/structs/structure-constructor-type-mismatch.rs new file mode 100644 index 000000000000..012df6cbc24a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structs/structure-constructor-type-mismatch.rs @@ -0,0 +1,74 @@ +struct Point { + x: T, + y: T, +} + +type PointF = Point; + +struct Pair { + x: T, + y: U, +} + +type PairF = Pair; + +fn main() { + let pt = PointF { + x: 1, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + y: 2, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + }; + + let pt2 = Point:: { + x: 3, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + y: 4, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + }; + + let pair = PairF { + x: 5, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + y: 6, + }; + + let pair2 = PairF:: { + x: 7, +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + y: 8, + }; + + let pt3 = PointF:: { // { dg-error ".E0107." "" { target *-*-* } } + x: 9, // { dg-error ".E0308." "" { target *-*-* } } + y: 10, // { dg-error ".E0308." "" { target *-*-* } } + }; + + match (Point { x: 1, y: 2 }) { + PointF:: { .. } => {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + } + + match (Point { x: 1, y: 2 }) { + PointF { .. } => {} // { dg-error ".E0308." "" { target *-*-* } } + } + + match (Point { x: 1.0, y: 2.0 }) { + PointF { .. } => {} // ok + } + + match (Pair { x: 1, y: 2 }) { + PairF:: { .. } => {} // { dg-error ".E0308." "" { target *-*-* } } + } + + match (Pair { x: 1.0, y: 2 }) { + PairF:: { .. } => {} // ok + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/structured-compare.rs b/gcc/testsuite/rust/rustc/ui/structured-compare.rs new file mode 100644 index 000000000000..a4b0e4e1f56e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/structured-compare.rs @@ -0,0 +1,31 @@ +// run-pass + +#![allow(non_camel_case_types)] + + +#[derive(Copy, Clone, Debug)] +enum foo { large, small, } + +impl PartialEq for foo { + fn eq(&self, other: &foo) -> bool { + ((*self) as usize) == ((*other) as usize) + } + fn ne(&self, other: &foo) -> bool { !(*self).eq(other) } +} + +pub fn main() { + let a = (1, 2, 3); + let b = (1, 2, 3); + assert_eq!(a, b); + assert!((a != (1, 2, 4))); + assert!((a < (1, 2, 4))); + assert!((a <= (1, 2, 4))); + assert!(((1, 2, 4) > a)); + assert!(((1, 2, 4) >= a)); + let x = foo::large; + let y = foo::small; + assert!((x != y)); + assert_eq!(x, foo::large); + assert!((x != foo::small)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/substs-ppaux.rs b/gcc/testsuite/rust/rustc/ui/substs-ppaux.rs new file mode 100644 index 000000000000..231c5c64da75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/substs-ppaux.rs @@ -0,0 +1,53 @@ +// +// 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>; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + + + let x: () = >::bar::<'static, char>; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + + let x: () = >::baz; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + + let x: () = foo::<'static>; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + + >::bar; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suffixed-literal-meta.rs b/gcc/testsuite/rust/rustc/ui/suffixed-literal-meta.rs new file mode 100644 index 000000000000..e573e1a23a0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suffixed-literal-meta.rs @@ -0,0 +1,28 @@ +#![feature(rustc_attrs)] + +#[rustc_dummy = 1usize] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[rustc_dummy = 1u8] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[rustc_dummy = 1u16] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[rustc_dummy = 1u32] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[rustc_dummy = 1u64] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[rustc_dummy = 1isize] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[rustc_dummy = 1i8] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[rustc_dummy = 1i16] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[rustc_dummy = 1i32] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[rustc_dummy = 1i64] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[rustc_dummy = 1.0f32] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +#[rustc_dummy = 1.0f64] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/adt-param-with-implicit-sized-bound.rs b/gcc/testsuite/rust/rustc/ui/suggestions/adt-param-with-implicit-sized-bound.rs new file mode 100644 index 000000000000..e7225ac54874 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/adt-param-with-implicit-sized-bound.rs @@ -0,0 +1,29 @@ +trait Trait { + fn func1() -> Struct1; // { dg-error ".E0277." "" { target *-*-* } } + fn func2<'a>() -> Struct2<'a, Self>; // { dg-error ".E0277." "" { target *-*-* } } + fn func3() -> Struct3; // { dg-error ".E0277." "" { target *-*-* } } + fn func4() -> Struct4; // { dg-error ".E0277." "" { target *-*-* } } +} + +struct Struct1{ + _t: std::marker::PhantomData<*const T>, +} +struct Struct2<'a, T>{ + _t: &'a T, +} +struct Struct3{ + _t: T, +} + +struct X(T); + +struct Struct4{ + _t: X, +} + +struct Struct5{ + _t: X, // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/as-ref.rs b/gcc/testsuite/rust/rustc/ui/suggestions/as-ref.rs new file mode 100644 index 000000000000..0d2a27aaa0cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/as-ref.rs @@ -0,0 +1,26 @@ +struct Foo; +fn takes_ref(_: &Foo) {} + +fn main() { + let ref opt = Some(Foo); + opt.map(|arg| takes_ref(arg)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + opt.and_then(|arg| Some(takes_ref(arg))); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let ref opt: Result<_, ()> = Ok(Foo); + opt.map(|arg| takes_ref(arg)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + opt.and_then(|arg| Ok(takes_ref(arg))); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let x: &Option = &Some(3); + let y: Option<&usize> = x; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let x: &Result = &Ok(3); + let y: Result<&usize, &usize> = x; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + // note: do not suggest because of `E: usize` + let x: &Result = &Ok(3); + let y: Result<&usize, usize> = x; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/assoc-const-as-field.rs b/gcc/testsuite/rust/rustc/ui/suggestions/assoc-const-as-field.rs new file mode 100644 index 000000000000..533d557c8036 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/assoc-const-as-field.rs @@ -0,0 +1,14 @@ +pub mod Mod { + pub struct Foo {} + impl Foo { + pub const BAR: usize = 42; + } +} + +fn foo(_: usize) {} + +fn main() { + foo(Mod::Foo.Bar); +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/assoc-type-in-method-return.rs b/gcc/testsuite/rust/rustc/ui/suggestions/assoc-type-in-method-return.rs new file mode 100644 index 000000000000..54645f93e40a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/assoc-type-in-method-return.rs @@ -0,0 +1,8 @@ +trait A { + type Bla; + fn to_bla(&self) -> Bla; +// { dg-error ".E0412." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs b/gcc/testsuite/rust/rustc/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs new file mode 100644 index 000000000000..77762a5962b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs @@ -0,0 +1,14 @@ +// edition:2018 +#![feature(async_closure)] +use std::future::Future; + +async fn foo() {} + +fn bar(f: impl Future) {} + +fn main() { + bar(foo); // { dg-error ".E0277." "" { target *-*-* } } + let async_closure = async || (); + bar(async_closure); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/attribute-typos.rs b/gcc/testsuite/rust/rustc/ui/suggestions/attribute-typos.rs new file mode 100644 index 000000000000..18810dd45f39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/attribute-typos.rs @@ -0,0 +1,12 @@ +#[deprcated] // { dg-error "" "" { target *-*-* } } +fn foo() {} + +#[tests] // { dg-error "" "" { target *-*-* } } +fn bar() {} + +#[rustc_err] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/foo.rs b/gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/foo.rs new file mode 100644 index 000000000000..74877375d399 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/foo.rs @@ -0,0 +1,4 @@ +//! Contains a struct with almost the same name as itself, to trigger Levenshtein suggestions. + +pub struct Foo; + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/issue-61963-1.rs b/gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/issue-61963-1.rs new file mode 100644 index 000000000000..7b35fae051d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/issue-61963-1.rs @@ -0,0 +1,41 @@ +// force-host +// no-prefer-dynamic +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{Group, TokenStream, TokenTree}; + +// This macro exists as part of a reproduction of #61963 but without using quote/syn/proc_macro2. + +#[proc_macro_derive(DomObject)] +pub fn expand_token_stream(input: TokenStream) -> TokenStream { + // Construct a dummy span - `#0 bytes(0..0)` - which is present in the input because + // of the specially crafted generated tokens in the `attribute-crate` proc-macro. + let dummy_span = input.clone().into_iter().nth(0).unwrap().span(); + + // Define what the macro would output if constructed properly from the source using syn/quote. + let output: TokenStream = "impl Bar for ((), Qux >) { } + impl Bar for ((), Box) { }".parse().unwrap(); + + let mut tokens: Vec<_> = output.into_iter().collect(); + // Adjust token spans to match the original crate (which would use `quote`). Some of the + // generated tokens point to the dummy span. + for token in tokens.iter_mut() { + if let TokenTree::Group(group) = token { + let mut tokens: Vec<_> = group.stream().into_iter().collect(); + for token in tokens.iter_mut().skip(2) { + token.set_span(dummy_span); + } + + let mut stream = TokenStream::new(); + stream.extend(tokens); + *group = Group::new(group.delimiter(), stream); + } + } + + let mut output = TokenStream::new(); + output.extend(tokens); + output +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/issue-61963.rs b/gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/issue-61963.rs new file mode 100644 index 000000000000..85b92cf556fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/issue-61963.rs @@ -0,0 +1,42 @@ +// force-host +// no-prefer-dynamic +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{Group, Spacing, Punct, TokenTree, TokenStream}; + +// This macro exists as part of a reproduction of #61963 but without using quote/syn/proc_macro2. + +#[proc_macro_attribute] +pub fn dom_struct(_: TokenStream, input: TokenStream) -> TokenStream { + // Construct the expected output tokens - the input but with a `#[derive(DomObject)]` applied. + let attributes: TokenStream = + "#[derive(DomObject)]".to_string().parse().unwrap(); + let output: TokenStream = attributes.into_iter() + .chain(input.into_iter()).collect(); + + let mut tokens: Vec<_> = output.into_iter().collect(); + // Adjust the spacing of `>` tokens to match what `quote` would produce. + for token in tokens.iter_mut() { + if let TokenTree::Group(group) = token { + let mut tokens: Vec<_> = group.stream().into_iter().collect(); + for token in tokens.iter_mut() { + if let TokenTree::Punct(p) = token { + if p.as_char() == '>' { + *p = Punct::new('>', Spacing::Alone); + } + } + } + + let mut stream = TokenStream::new(); + stream.extend(tokens); + *group = Group::new(group.delimiter(), stream); + } + } + + let mut output = TokenStream::new(); + output.extend(tokens); + output +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/struct_field_privacy.rs b/gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/struct_field_privacy.rs new file mode 100644 index 000000000000..efb731008b0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/auxiliary/struct_field_privacy.rs @@ -0,0 +1,10 @@ +pub struct A { + a: isize, + pub b: isize, +} + +pub struct B { + pub a: isize, + b: isize, +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/borrow-for-loop-head.rs b/gcc/testsuite/rust/rustc/ui/suggestions/borrow-for-loop-head.rs new file mode 100644 index 000000000000..f7c3a4760313 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/borrow-for-loop-head.rs @@ -0,0 +1,11 @@ +fn main() { + let a = vec![1, 2, 3]; + for i in &a { + for j in a { +// { dg-error ".E0382." "" { target *-*-* } .-1 } +// { dg-error ".E0382." "" { target *-*-* } .-2 } + println!("{} * {} = {}", i, j, i * j); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/chain-method-call-mutation-in-place.rs b/gcc/testsuite/rust/rustc/ui/suggestions/chain-method-call-mutation-in-place.rs new file mode 100644 index 000000000000..dbb055f13a35 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/chain-method-call-mutation-in-place.rs @@ -0,0 +1,5 @@ +fn main() {} +fn foo(mut s: String) -> String { + s.push_str("asdf") // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/const-in-struct-pat.rs b/gcc/testsuite/rust/rustc/ui/suggestions/const-in-struct-pat.rs new file mode 100644 index 000000000000..3e57a36aceac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/const-in-struct-pat.rs @@ -0,0 +1,12 @@ +#[allow(non_camel_case_types)] +struct foo; +struct Thing { + foo: String, +} + +fn example(t: Thing) { + let Thing { foo } = t; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/const-no-type.rs b/gcc/testsuite/rust/rustc/ui/suggestions/const-no-type.rs new file mode 100644 index 000000000000..70e153a378ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/const-no-type.rs @@ -0,0 +1,52 @@ +// In the cases below, the type is missing from the `const` and `static` items. +// +// Here, we test that we: +// +// a) Perform parser recovery. +// +// b) Emit a diagnostic with the actual inferred type to RHS of `=` as the suggestion. + +fn main() {} + +// These will not reach typeck: + +#[cfg(FALSE)] +const C2 = 42; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +#[cfg(FALSE)] +static S2 = "abc"; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +#[cfg(FALSE)] +static mut SM2 = "abc"; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +// These will, so the diagnostics should be stolen by typeck: + +const C = 42; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +const D = &&42; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +static S = Vec::::new(); +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + +static mut SM = "abc"; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/const-pat-non-exaustive-let-new-var.rs b/gcc/testsuite/rust/rustc/ui/suggestions/const-pat-non-exaustive-let-new-var.rs new file mode 100644 index 000000000000..5836fedad75f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/const-pat-non-exaustive-let-new-var.rs @@ -0,0 +1,11 @@ +fn main() { + let A = 3; +// { dg-error ".E0005." "" { target *-*-* } .-1 } +// { dg-error ".E0005." "" { target *-*-* } .-2 } +// { help ".E0005." "" { target *-*-* } .-3 } +// { suggestion ".E0005." "" { target *-*-* } .-4 } + + const A: i32 = 2; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/constrain-trait.rs b/gcc/testsuite/rust/rustc/ui/suggestions/constrain-trait.rs new file mode 100644 index 000000000000..69c0a36c8b87 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/constrain-trait.rs @@ -0,0 +1,48 @@ +// run-rustfix +// check-only + +#[derive(Debug)] +struct Demo { + a: String +} + +trait GetString { + fn get_a(&self) -> &String; +} + +trait UseString: std::fmt::Debug { + fn use_string(&self) { + println!("{:?}", self.get_a()); // { dg-error ".E0599." "" { target *-*-* } } + } +} + +trait UseString2 { + fn use_string(&self) { + println!("{:?}", self.get_a()); // { dg-error ".E0599." "" { target *-*-* } } + } +} + +impl GetString for Demo { + fn get_a(&self) -> &String { + &self.a + } +} + +impl UseString for Demo {} +impl UseString2 for Demo {} + + +#[cfg(test)] +mod tests { + use crate::{Demo, UseString}; + + #[test] + fn it_works() { + let d = Demo { a: "test".to_string() }; + d.use_string(); + } +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.rs b/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.rs new file mode 100644 index 000000000000..0295b24d781b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.rs @@ -0,0 +1,15 @@ +fn warn(_: &str) {} + +macro_rules! intrinsic_match { + ($intrinsic:expr) => { + warn(format!("unsupported intrinsic {}", $intrinsic)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + }; +} + +fn main() { + intrinsic_match! { + "abc" + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs b/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs new file mode 100644 index 000000000000..22a7d2e8ee47 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs @@ -0,0 +1,151 @@ +#[derive(Clone)] +enum Either { + One(X), + Two(X), +} + +#[derive(Clone)] +struct X(Y); + +#[derive(Clone)] +struct Y; + + +pub fn main() { + let e = Either::One(X(Y)); + let mut em = Either::One(X(Y)); + + let r = &e; + let rm = &mut Either::One(X(Y)); + + let x = X(Y); + let mut xm = X(Y); + + let s = &x; + let sm = &mut X(Y); + + let ve = vec![Either::One(X(Y))]; + + let vr = &ve; + let vrm = &mut vec![Either::One(X(Y))]; + + let vx = vec![X(Y)]; + + let vs = &vx; + let vsm = &mut vec![X(Y)]; + + // test for duplicate suggestions + + let &(X(_t), X(_u)) = &(x.clone(), x.clone()); +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match &(e.clone(), e.clone()) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &(Either::One(_t), Either::Two(_u)) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + &(Either::Two(_t), Either::One(_u)) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + _ => (), + } + match &(e.clone(), e.clone()) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &(Either::One(_t), Either::Two(_u)) +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + | &(Either::Two(_t), Either::One(_u)) => (), + // FIXME: would really like a suggestion here too + _ => (), + } + match &(e.clone(), e.clone()) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &(Either::One(_t), Either::Two(_u)) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + &(Either::Two(ref _t), Either::One(ref _u)) => (), + _ => (), + } + match &(e.clone(), e.clone()) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &(Either::One(_t), Either::Two(_u)) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + (Either::Two(_t), Either::One(_u)) => (), + _ => (), + } + fn f5(&(X(_t), X(_u)): &(X, X)) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + + let &mut (X(_t), X(_u)) = &mut (xm.clone(), xm.clone()); +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match &mut (em.clone(), em.clone()) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut (Either::One(_t), Either::Two(_u)) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + &mut (Either::Two(_t), Either::One(_u)) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + _ => (), + } + match &mut (em.clone(), em.clone()) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut (Either::One(_t), Either::Two(_u)) +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + | &mut (Either::Two(_t), Either::One(_u)) => (), + // FIXME: would really like a suggestion here too + _ => (), + } + match &mut (em.clone(), em.clone()) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut (Either::One(_t), Either::Two(_u)) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + &mut (Either::Two(ref _t), Either::One(ref _u)) => (), + _ => (), + } + match &mut (em.clone(), em.clone()) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut (Either::One(_t), Either::Two(_u)) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + &mut (Either::Two(ref mut _t), Either::One(ref mut _u)) => (), + _ => (), + } + match &mut (em.clone(), em.clone()) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut (Either::One(_t), Either::Two(_u)) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + (Either::Two(_t), Either::One(_u)) => (), + _ => (), + } + fn f6(&mut (X(_t), X(_u)): &mut (X, X)) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-ref/move-into-closure.rs b/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-ref/move-into-closure.rs new file mode 100644 index 000000000000..cffaa8a4086c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-ref/move-into-closure.rs @@ -0,0 +1,160 @@ +#[derive(Clone)] +enum Either { + One(X), + Two(X), +} + +#[derive(Clone)] +struct X(Y); + +#[derive(Clone)] +struct Y; + +fn consume_fn(_f: F) { } + +fn consume_fnmut(_f: F) { } + +pub fn main() { } + +fn move_into_fn() { + let e = Either::One(X(Y)); + let mut em = Either::One(X(Y)); + + let x = X(Y); + + // move into Fn + + consume_fn(|| { + let X(_t) = x; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let Either::One(_t) = e { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let Either::One(_t) = e { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match e { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) + | Either::Two(_t) => (), + } + match e { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + + let X(mut _t) = x; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let Either::One(mut _t) = em { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let Either::One(mut _t) = em { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match em { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(mut _t) + | Either::Two(mut _t) => (), + } + match em { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(mut _t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + }); +} + +fn move_into_fnmut() { + let e = Either::One(X(Y)); + let mut em = Either::One(X(Y)); + + let x = X(Y); + + // move into FnMut + + consume_fnmut(|| { + let X(_t) = x; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let Either::One(_t) = e { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let Either::One(_t) = e { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match e { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) + | Either::Two(_t) => (), + } + match e { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + + let X(mut _t) = x; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let Either::One(mut _t) = em { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let Either::One(mut _t) = em { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match em { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(mut _t) + | Either::Two(mut _t) => (), + } + match em { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(mut _t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + match em { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(mut _t) => (), + Either::Two(ref mut _t) => (), + // FIXME: should suggest removing `ref` too + } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-ref/simple.rs b/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-ref/simple.rs new file mode 100644 index 000000000000..d08ac7badd7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-ref/simple.rs @@ -0,0 +1,365 @@ +#[derive(Clone)] +enum Either { + One(X), + Two(X), +} + +#[derive(Clone)] +struct X(Y); + +#[derive(Clone)] +struct Y; + +pub fn main() { + let e = Either::One(X(Y)); + let mut em = Either::One(X(Y)); + + let r = &e; + let rm = &mut Either::One(X(Y)); + + let x = X(Y); + let mut xm = X(Y); + + let s = &x; + let sm = &mut X(Y); + + let ve = vec![Either::One(X(Y))]; + + let vr = &ve; + let vrm = &mut vec![Either::One(X(Y))]; + + let vx = vec![X(Y)]; + + let vs = &vx; + let vsm = &mut vec![X(Y)]; + + // move from Either/X place + + let X(_t) = *s; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let Either::One(_t) = *r { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let Either::One(_t) = *r { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match *r { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) + | Either::Two(_t) => (), + } + match *r { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + + let X(_t) = *sm; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let Either::One(_t) = *rm { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let Either::One(_t) = *rm { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match *rm { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) + | Either::Two(_t) => (), + } + match *rm { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + match *rm { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) => (), + Either::Two(ref mut _t) => (), + // FIXME: should suggest removing `ref` too + } + + let X(_t) = vs[0]; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let Either::One(_t) = vr[0] { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let Either::One(_t) = vr[0] { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match vr[0] { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) + | Either::Two(_t) => (), + } + match vr[0] { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + + let X(_t) = vsm[0]; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let Either::One(_t) = vrm[0] { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let Either::One(_t) = vrm[0] { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match vrm[0] { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) + | Either::Two(_t) => (), + } + match vrm[0] { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + match vrm[0] { +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + Either::One(_t) => (), + Either::Two(ref mut _t) => (), + // FIXME: should suggest removing `ref` too + } + + // move from &Either/&X place + + let &X(_t) = s; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let &Either::One(_t) = r { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let &Either::One(_t) = r { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match r { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &Either::One(_t) +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + | &Either::Two(_t) => (), + // FIXME: would really like a suggestion here too + } + match r { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &Either::One(_t) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + &Either::Two(ref _t) => (), + } + match r { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &Either::One(_t) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + Either::Two(_t) => (), + } + fn f1(&X(_t): &X) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + + let &mut X(_t) = sm; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let &mut Either::One(_t) = rm { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let &mut Either::One(_t) = rm { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match rm { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut Either::One(_t) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + &mut Either::Two(_t) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + } + match rm { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut Either::One(_t) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + &mut Either::Two(ref _t) => (), + } + match rm { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut Either::One(_t) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + &mut Either::Two(ref mut _t) => (), + } + match rm { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut Either::One(_t) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + Either::Two(_t) => (), + } + fn f2(&mut X(_t): &mut X) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + + // move from tuple of &Either/&X + + // FIXME: These should have suggestions. + + let (&X(_t),) = (&x.clone(),); +// { dg-error ".E0507." "" { target *-*-* } .-1 } + if let (&Either::One(_t),) = (&e.clone(),) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } + while let (&Either::One(_t),) = (&e.clone(),) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } + match (&e.clone(),) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + (&Either::One(_t),) + | (&Either::Two(_t),) => (), + } + fn f3((&X(_t),): (&X,)) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } + + let (&mut X(_t),) = (&mut xm.clone(),); +// { dg-error ".E0507." "" { target *-*-* } .-1 } + if let (&mut Either::One(_t),) = (&mut em.clone(),) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } + while let (&mut Either::One(_t),) = (&mut em.clone(),) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } + match (&mut em.clone(),) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + (&mut Either::One(_t),) => (), + (&mut Either::Two(_t),) => (), + } + fn f4((&mut X(_t),): (&mut X,)) { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } + + // move from &Either/&X value + + let &X(_t) = &x; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let &Either::One(_t) = &e { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let &Either::One(_t) = &e { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match &e { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &Either::One(_t) +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + | &Either::Two(_t) => (), + // FIXME: would really like a suggestion here too + } + match &e { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &Either::One(_t) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + &Either::Two(ref _t) => (), + } + match &e { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &Either::One(_t) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + Either::Two(_t) => (), + } + + let &mut X(_t) = &mut xm; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + if let &mut Either::One(_t) = &mut em { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + while let &mut Either::One(_t) = &mut em { } +// { dg-error ".E0507." "" { target *-*-* } .-1 } +// { help ".E0507." "" { target *-*-* } .-2 } +// { suggestion ".E0507." "" { target *-*-* } .-3 } + match &mut em { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut Either::One(_t) +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + | &mut Either::Two(_t) => (), + // FIXME: would really like a suggestion here too + } + match &mut em { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut Either::One(_t) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + &mut Either::Two(ref _t) => (), + } + match &mut em { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut Either::One(_t) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + &mut Either::Two(ref mut _t) => (), + } + match &mut em { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + &mut Either::One(_t) => (), +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + Either::Two(_t) => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-try_into-in-macros.rs b/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-try_into-in-macros.rs new file mode 100644 index 000000000000..d210f7b04313 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/dont-suggest-try_into-in-macros.rs @@ -0,0 +1,4 @@ +fn main() { + assert_eq!(10u64, 10usize); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/expected-boxed-future-isnt-pinned.rs b/gcc/testsuite/rust/rustc/ui/suggestions/expected-boxed-future-isnt-pinned.rs new file mode 100644 index 000000000000..a3d1bd79337d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/expected-boxed-future-isnt-pinned.rs @@ -0,0 +1,37 @@ +// edition:2018 +#![allow(dead_code)] +use std::future::Future; +use std::pin::Pin; + +type BoxFuture<'a, T> = Pin + Send + 'a>>; +// ^^^^^^^^^ This would come from the `futures` crate in real code. + +fn foo + Send + 'static>(x: F) -> BoxFuture<'static, i32> { + // We could instead use an `async` block, but this way we have no std spans. + x // { dg-error ".E0308." "" { target *-*-* } } +} + +// This case is still subpar: +// `Pin::new(x)`: store this in the heap by calling `Box::new`: `Box::new(x)` +// Should suggest changing the code from `Pin::new` to `Box::pin`. +fn bar + Send + 'static>(x: F) -> BoxFuture<'static, i32> { + Box::new(x) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn baz + Send + 'static>(x: F) -> BoxFuture<'static, i32> { + Pin::new(x) // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn qux + Send + 'static>(x: F) -> BoxFuture<'static, i32> { + Pin::new(Box::new(x)) // { dg-error ".E0277." "" { target *-*-* } } +} + +fn zap() -> BoxFuture<'static, i32> { + async { // { dg-error ".E0308." "" { target *-*-* } } + 42 + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs b/gcc/testsuite/rust/rustc/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs new file mode 100644 index 000000000000..0247cf864f7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs @@ -0,0 +1,21 @@ +// edition:2018 +trait T { + type O; +} + +struct S; + +impl T for S { + type O = (); +} + +fn foo() -> impl T { S } + +fn bar(f: impl T) {} + +fn main() { + bar(foo); // { dg-error ".E0277." "" { target *-*-* } } + let closure = || S; + bar(closure); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/fn-missing-lifetime-in-item.rs b/gcc/testsuite/rust/rustc/ui/suggestions/fn-missing-lifetime-in-item.rs new file mode 100644 index 000000000000..bd78d033501c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/fn-missing-lifetime-in-item.rs @@ -0,0 +1,9 @@ +struct S1 &'a i32>(F); // { dg-error ".E0261." "" { target *-*-* } } +struct S2 &i32>(F); // { dg-error ".E0106." "" { target *-*-* } } +struct S3 Fn(&i32, &i32) -> &'a i32>(F); +// { dg-error ".E0582." "" { target *-*-* } .-1 } +struct S4 Fn(&'x i32, &'x i32) -> &'x i32>(F); +const C: Option Fn(&usize, &usize) -> &'a usize>> = None; +// { dg-error ".E0582." "" { target *-*-* } .-1 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/fn-needing-specified-return-type-param.rs b/gcc/testsuite/rust/rustc/ui/suggestions/fn-needing-specified-return-type-param.rs new file mode 100644 index 000000000000..a1f5a5ccc051 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/fn-needing-specified-return-type-param.rs @@ -0,0 +1,6 @@ +fn f() -> A { unimplemented!() } +fn foo() { + let _ = f; // { dg-error ".E0282." "" { target *-*-* } } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs b/gcc/testsuite/rust/rustc/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs new file mode 100644 index 000000000000..693690dd82a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/fn-or-tuple-struct-with-underscore-args.rs @@ -0,0 +1,20 @@ +fn foo(a: usize, b: usize) -> usize { a } + +struct S(usize, usize); + +trait T { + fn baz(x: usize, y: usize) -> usize { x } +} + +fn main() { + let _: usize = foo(_, _); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + let _: S = S(_, _); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + let _: usize = T::baz(_, _); +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/fn-or-tuple-struct-without-args.rs b/gcc/testsuite/rust/rustc/ui/suggestions/fn-or-tuple-struct-without-args.rs new file mode 100644 index 000000000000..f9535402f26d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/fn-or-tuple-struct-without-args.rs @@ -0,0 +1,48 @@ +fn foo(a: usize, b: usize) -> usize { a } + +fn bar() -> usize { 42 } + +struct S(usize, usize); +enum E { + A(usize), + B { a: usize }, +} +struct V(); + +trait T { + fn baz(x: usize, y: usize) -> usize { x } + fn bat(x: usize) -> usize { 42 } + fn bax(x: usize) -> usize { 42 } + fn bach(x: usize) -> usize; + fn ban(&self) -> usize { 42 } + fn bal(&self) -> usize; +} + +struct X; + +impl T for X { + fn bach(x: usize) -> usize { 42 } + fn bal(&self) -> usize { 42 } +} + +fn main() { + let _: usize = foo; // { dg-error ".E0308." "" { target *-*-* } } + let _: S = S; // { dg-error ".E0308." "" { target *-*-* } } + let _: usize = bar; // { dg-error ".E0308." "" { target *-*-* } } + let _: V = V; // { dg-error ".E0308." "" { target *-*-* } } + let _: usize = T::baz; // { dg-error ".E0308." "" { target *-*-* } } + let _: usize = T::bat; // { dg-error ".E0308." "" { target *-*-* } } + let _: E = E::A; // { dg-error ".E0308." "" { target *-*-* } } + let _: E = E::B; // { dg-error ".E0423." "" { target *-*-* } } + let _: usize = X::baz; // { dg-error ".E0308." "" { target *-*-* } } + let _: usize = X::bat; // { dg-error ".E0308." "" { target *-*-* } } + let _: usize = X::bax; // { dg-error ".E0308." "" { target *-*-* } } + let _: usize = X::bach; // { dg-error ".E0308." "" { target *-*-* } } + let _: usize = X::ban; // { dg-error ".E0308." "" { target *-*-* } } + let _: usize = X::bal; // { dg-error ".E0308." "" { target *-*-* } } + let _: usize = X.ban; // { dg-error ".E0615." "" { target *-*-* } } + let _: usize = X.bal; // { dg-error ".E0615." "" { target *-*-* } } + let closure = || 42; + let _: usize = closure; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/fn-trait-notation.rs b/gcc/testsuite/rust/rustc/ui/suggestions/fn-trait-notation.rs new file mode 100644 index 000000000000..28e717e484f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/fn-trait-notation.rs @@ -0,0 +1,20 @@ +// run-rustfix +fn e0658(f: F, g: G, h: H) -> i32 +where + F: Fn, // { dg-error ".E0658." "" { target *-*-* } } + G: Fn<(i32, i32, ), Output = (i32, i32)>, // { dg-error ".E0658." "" { target *-*-* } } + H: Fn<(i32,), Output = i32>, // { dg-error ".E0658." "" { target *-*-* } } +{ + f(3); + g(3, 4); + h(3) +} + +fn main() { + e0658( + |a| a, + |a, b| (b, a), + |a| a, + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/for-i-in-vec.rs b/gcc/testsuite/rust/rustc/ui/suggestions/for-i-in-vec.rs new file mode 100644 index 000000000000..4a2b5a980873 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/for-i-in-vec.rs @@ -0,0 +1,16 @@ +// run-rustfix +#![allow(dead_code)] + +struct Foo { + v: Vec, +} + +impl Foo { + fn bar(&self) { + for _ in self.v { // { dg-error ".E0507." "" { target *-*-* } } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/format-borrow.rs b/gcc/testsuite/rust/rustc/ui/suggestions/format-borrow.rs new file mode 100644 index 000000000000..ffaf6664c92b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/format-borrow.rs @@ -0,0 +1,7 @@ +fn main() { + let a: String = &String::from("a"); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let b: String = &format!("b"); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/if-let-typo.rs b/gcc/testsuite/rust/rustc/ui/suggestions/if-let-typo.rs new file mode 100644 index 000000000000..e6a78b3dea3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/if-let-typo.rs @@ -0,0 +1,14 @@ +fn main() { + let foo = Some(0); + let bar = None; + if Some(x) = foo {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + if Some(foo) = bar {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + if 3 = foo {} // { dg-error ".E0308." "" { target *-*-* } } + if Some(3) = foo {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/imm-ref-trait-object-literal-bound-regions.rs b/gcc/testsuite/rust/rustc/ui/suggestions/imm-ref-trait-object-literal-bound-regions.rs new file mode 100644 index 000000000000..01c1fc19a0fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/imm-ref-trait-object-literal-bound-regions.rs @@ -0,0 +1,19 @@ +// Regression test for #70813 (this used to trigger a debug assertion) + +trait Trait {} + +struct S; + +impl<'a> Trait for &'a mut S {} + +fn foo(_: X) +where + for<'b> &'b X: Trait, +{ +} + +fn main() { + let s = S; + foo::(s); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/imm-ref-trait-object-literal.rs b/gcc/testsuite/rust/rustc/ui/suggestions/imm-ref-trait-object-literal.rs new file mode 100644 index 000000000000..55dc80dedfce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/imm-ref-trait-object-literal.rs @@ -0,0 +1,15 @@ +trait Trait {} + +struct S; + +impl<'a> Trait for &'a mut S {} + +fn foo(_: X) {} + + +fn main() { + let s = S; + foo(&s); // { dg-error ".E0277." "" { target *-*-* } } + foo(s); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/imm-ref-trait-object.rs b/gcc/testsuite/rust/rustc/ui/suggestions/imm-ref-trait-object.rs new file mode 100644 index 000000000000..28ec58a0e179 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/imm-ref-trait-object.rs @@ -0,0 +1,9 @@ +fn test(t: &dyn Iterator) -> u64 { + t.min().unwrap() // { dg-error "" "" { target *-*-* } } +} + +fn main() { + let array = [0u64]; + test(&mut array.iter()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs b/gcc/testsuite/rust/rustc/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs new file mode 100644 index 000000000000..20f0165e4dcd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs @@ -0,0 +1,114 @@ +// FIXME: the following cases need to suggest more things to make users reach a working end state. + +mod bav { + trait OtherTrait<'a> {} + impl<'a> OtherTrait<'a> for &'a () {} + + trait ObjectTrait { + type Assoc: Bar; + } + trait MyTrait { + fn use_self(&self) -> &() { panic!() } + } + trait Bar {} + + impl MyTrait for Box> { + fn use_self(&self) -> &() { panic!() } + } + impl Bar for i32 {} + + fn use_it<'a>(val: Box>) -> impl OtherTrait<'a> { + val.use_self() // { dg-error ".E0597." "" { target *-*-* } } + } +} + +mod bap { + trait OtherTrait<'a> {} + impl<'a> OtherTrait<'a> for &'a () {} + + trait ObjectTrait { + type Assoc: Bar; + } + trait MyTrait { + fn use_self(&self) -> &() { panic!() } + } + trait Bar {} + + impl MyTrait for Box> { + fn use_self(&self) -> &() { panic!() } + } + impl Bar for i32 {} + + fn use_it<'a>(val: Box>) -> impl OtherTrait<'a> + 'a { + val.use_self() // { dg-error ".E0515." "" { target *-*-* } } + } +} + +// This case in particular requires the user to write all of the bounds we have in `mod bax`. +mod bay { + trait OtherTrait<'a> {} + impl<'a> OtherTrait<'a> for &'a () {} + + trait ObjectTrait { + type Assoc: Bar; + } + trait MyTrait { + fn use_self(&self) -> &() { panic!() } + } + trait Bar {} + + impl MyTrait for Box> { + fn use_self(&self) -> &() { panic!() } + } + impl Bar for i32 {} + + fn use_it<'a>(val: Box + 'a>) -> &'a () { + val.use_self() // { dg-error ".E0772." "" { target *-*-* } } + } +} + +mod bax { + trait OtherTrait<'a> {} + impl<'a> OtherTrait<'a> for &'a () {} + + trait ObjectTrait { + type Assoc: Bar; + } + trait MyTrait<'a> { + fn use_self(&'a self) -> &'a () { panic!() } + } + trait Bar {} + + impl<'a> MyTrait<'a> for Box + 'a> { + fn use_self(&'a self) -> &'a () { panic!() } + } + impl Bar for i32 {} + + fn use_it<'a>(val: Box + 'a>) -> &'a () { + val.use_self() + } +} + +mod baw { + trait OtherTrait<'a> {} + impl<'a> OtherTrait<'a> for &'a () {} + + trait ObjectTrait { + type Assoc: Bar; + } + trait MyTrait { + fn use_self(&self) -> &() { panic!() } + } + trait Bar {} + + impl<'a> MyTrait for Box>> { + fn use_self(&self) -> &() { panic!() } + } + + fn use_it<'a>(val: Box>>) -> impl OtherTrait<'a> + 'a{ + val.use_self() // { dg-error ".E0515." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs b/gcc/testsuite/rust/rustc/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs new file mode 100644 index 000000000000..db612a049f85 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs @@ -0,0 +1,113 @@ +// run-rustfix +#![allow(dead_code)] + +mod foo { + trait OtherTrait<'a> {} + impl<'a> OtherTrait<'a> for &'a () {} + + trait ObjectTrait {} + trait MyTrait { + fn use_self(&self) -> &(); + } + trait Irrelevant {} + + impl MyTrait for dyn ObjectTrait { + fn use_self(&self) -> &() { panic!() } + } + impl Irrelevant for dyn ObjectTrait {} + + fn use_it<'a, T>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a { + val.use_self::() // { dg-error ".E0759." "" { target *-*-* } } + } +} + +mod bar { + trait ObjectTrait {} + trait MyTrait { + fn use_self(&self) -> &(); + } + trait Irrelevant {} + + impl MyTrait for dyn ObjectTrait { + fn use_self(&self) -> &() { panic!() } + } + impl Irrelevant for dyn ObjectTrait {} + + fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () { + val.use_self() // { dg-error ".E0772." "" { target *-*-* } } + } +} + +mod baz { + trait ObjectTrait {} + trait MyTrait { + fn use_self(&self) -> &(); + } + trait Irrelevant {} + + impl MyTrait for Box { + fn use_self(&self) -> &() { panic!() } + } + impl Irrelevant for Box {} + + fn use_it<'a>(val: &'a Box) -> &'a () { + val.use_self() // { dg-error ".E0772." "" { target *-*-* } } + } +} + +mod bat { + trait OtherTrait<'a> {} + impl<'a> OtherTrait<'a> for &'a () {} + + trait ObjectTrait {} + + impl dyn ObjectTrait { + fn use_self(&self) -> &() { panic!() } + } + + fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a { + val.use_self() // { dg-error ".E0772." "" { target *-*-* } } + } +} + +mod ban { + trait OtherTrait<'a> {} + impl<'a> OtherTrait<'a> for &'a () {} + + trait ObjectTrait {} + trait MyTrait { + fn use_self(&self) -> &() { panic!() } + } + trait Irrelevant { + fn use_self(&self) -> &() { panic!() } + } + + impl MyTrait for dyn ObjectTrait {} + + fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> { + val.use_self() // { dg-error ".E0759." "" { target *-*-* } } + } +} + +mod bal { + trait OtherTrait<'a> {} + impl<'a> OtherTrait<'a> for &'a () {} + + trait ObjectTrait {} + trait MyTrait { + fn use_self(&self) -> &() { panic!() } + } + trait Irrelevant { + fn use_self(&self) -> &() { panic!() } + } + + impl MyTrait for dyn ObjectTrait {} + impl Irrelevant for dyn ObjectTrait {} + + fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a { + MyTrait::use_self(val) // { dg-error ".E0759." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-missing-lifetime.rs b/gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-missing-lifetime.rs new file mode 100644 index 000000000000..a3ebd3fc31c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-missing-lifetime.rs @@ -0,0 +1,3 @@ +fn f(_: impl Iterator) {} // { dg-error ".E0106." "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-return-trailing-semicolon.rs b/gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-return-trailing-semicolon.rs new file mode 100644 index 000000000000..20e69409c465 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-return-trailing-semicolon.rs @@ -0,0 +1,8 @@ +trait Bar {} +impl Bar for u8 {} +fn foo() -> impl Bar { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-with-missing-bounds.rs b/gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-with-missing-bounds.rs new file mode 100644 index 000000000000..e51daa5cf0e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-with-missing-bounds.rs @@ -0,0 +1,45 @@ +// The double space in `impl Iterator` is load bearing! We want to make sure we don't regress by +// accident if the internal string representation changes. +#[rustfmt::skip] +fn foo(constraints: impl Iterator) { + for constraint in constraints { + qux(constraint); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } +} + +fn bar(t: T, constraints: impl Iterator) where T: std::fmt::Debug { + for constraint in constraints { + qux(t); + qux(constraint); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } +} + +fn baz(t: impl std::fmt::Debug, constraints: impl Iterator) { + for constraint in constraints { + qux(t); + qux(constraint); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } +} + +fn bat(t: T, constraints: impl Iterator, _: I) { + for constraint in constraints { + qux(t); + qux(constraint); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } +} + +fn bak(constraints: impl Iterator + std::fmt::Debug) { + for constraint in constraints { + qux(constraint); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } +} + +fn qux(_: impl std::fmt::Debug) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.rs b/gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.rs new file mode 100644 index 000000000000..300a0af20ead --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.rs @@ -0,0 +1,21 @@ +// run-rustfix + +trait Foo {} + +trait Bar { + fn hello(&self) {} +} + +struct S; + +impl Foo for S {} +impl Bar for S {} + +fn test(foo: impl Foo) { + foo.hello(); // { dg-error ".E0599." "" { target *-*-* } } +} + +fn main() { + test(S); +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/into-str.rs b/gcc/testsuite/rust/rustc/ui/suggestions/into-str.rs new file mode 100644 index 000000000000..96ca1bbde86d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/into-str.rs @@ -0,0 +1,7 @@ +fn foo<'a, T>(_t: T) where T: Into<&'a str> {} + +fn main() { + foo(String::new()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/invalid-bin-op.rs b/gcc/testsuite/rust/rustc/ui/suggestions/invalid-bin-op.rs new file mode 100644 index 000000000000..1a7f9f93643b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/invalid-bin-op.rs @@ -0,0 +1,8 @@ +pub fn foo(s: S, t: S) { + let _ = s == t; // { dg-error ".E0369." "" { target *-*-* } } +} + +struct S(T); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/issue-21673.rs b/gcc/testsuite/rust/rustc/ui/suggestions/issue-21673.rs new file mode 100644 index 000000000000..97ab06d74f21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/issue-21673.rs @@ -0,0 +1,14 @@ +trait Foo { + fn method(&self) {} +} + +fn call_method(x: &T) { + x.method() // { dg-error ".E0599." "" { target *-*-* } } +} + +fn call_method_2(x: T) { + x.method() // { dg-error ".E0599." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.rs b/gcc/testsuite/rust/rustc/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.rs new file mode 100644 index 000000000000..8a6c24d11ca4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.rs @@ -0,0 +1,9 @@ +fn vindictive() -> bool { true } + +fn perfidy() -> (i32, i32) { + vindictive() // { dg-error ".E0618." "" { target *-*-* } } + (1, 2) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/issue-52820.rs b/gcc/testsuite/rust/rustc/ui/suggestions/issue-52820.rs new file mode 100644 index 000000000000..fb429a41cf34 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/issue-52820.rs @@ -0,0 +1,13 @@ +struct Bravery { + guts: String, + brains: String, +} + +fn main() { + let guts = "mettle"; + let _ = Bravery { + guts, // { dg-error ".E0308." "" { target *-*-* } } + brains: guts.clone(), // { dg-error ".E0308." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/issue-57672.rs b/gcc/testsuite/rust/rustc/ui/suggestions/issue-57672.rs new file mode 100644 index 000000000000..ba64dcfcfe29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/issue-57672.rs @@ -0,0 +1,15 @@ +// aux-build:foo.rs +// compile-flags:--extern foo +// check-pass +// edition:2018 + +#![deny(unused_extern_crates)] + +extern crate foo as foo_renamed; + +pub mod m { + pub use foo_renamed::Foo; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/issue-59819.rs b/gcc/testsuite/rust/rustc/ui/suggestions/issue-59819.rs new file mode 100644 index 000000000000..b8775ebf4964 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/issue-59819.rs @@ -0,0 +1,36 @@ +// run-rustfix + +#![allow(warnings)] + +// Test that suggestion to add `*` characters applies to implementations of `Deref` as well as +// references. + +struct Foo(i32); + +struct Bar(String); + +impl std::ops::Deref for Foo { + type Target = i32; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::ops::Deref for Bar { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +fn main() { + let x = Foo(42); + let y: i32 = x; // { dg-error ".E0308." "" { target *-*-* } } + let a = &42; + let b: i32 = a; // { dg-error ".E0308." "" { target *-*-* } } + + // Do not make a suggestion when adding a `*` wouldn't actually fix the issue: + let f = Bar("bar".to_string()); + let g: String = f; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/issue-61226.rs b/gcc/testsuite/rust/rustc/ui/suggestions/issue-61226.rs new file mode 100644 index 000000000000..faf7d8652f33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/issue-61226.rs @@ -0,0 +1,7 @@ +// run-rustfix +struct X {} +fn main() { + let _ = vec![X]; //… +// { dg-error ".E0423." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/issue-61963.rs b/gcc/testsuite/rust/rustc/ui/suggestions/issue-61963.rs new file mode 100644 index 000000000000..4bd2ce99b286 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/issue-61963.rs @@ -0,0 +1,26 @@ +// aux-build:issue-61963.rs +// aux-build:issue-61963-1.rs +#![deny(bare_trait_objects)] + +#[macro_use] +extern crate issue_61963; +#[macro_use] +extern crate issue_61963_1; + +// This test checks that the bare trait object lint does not trigger on macro attributes that +// generate code which would trigger the lint. + +pub struct Baz; +pub trait Bar { } +pub struct Qux(T); + +#[dom_struct] +pub struct Foo { +// { dg-error "" "" { target *-*-* } .-1 } + qux: Qux>, + bar: Box, +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/issue-62843.rs b/gcc/testsuite/rust/rustc/ui/suggestions/issue-62843.rs new file mode 100644 index 000000000000..0e9705fe4541 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/issue-62843.rs @@ -0,0 +1,6 @@ +fn main() { + let line = String::from("abc"); + let pattern = String::from("bc"); + println!("{:?}", line.find(pattern)); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/issue-64252-self-type.rs b/gcc/testsuite/rust/rustc/ui/suggestions/issue-64252-self-type.rs new file mode 100644 index 000000000000..04cf6c86f008 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/issue-64252-self-type.rs @@ -0,0 +1,15 @@ +// This test checks that a suggestion to add a `self: ` parameter name is provided +// to functions where this is applicable. + +pub fn foo(Box) { } +// { dg-error "" "" { target *-*-* } .-1 } + +struct Bar; + +impl Bar { + fn bar(Box) { } +// { dg-error "" "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/issue-66968-suggest-sorted-words.rs b/gcc/testsuite/rust/rustc/ui/suggestions/issue-66968-suggest-sorted-words.rs new file mode 100644 index 000000000000..c0f1a4af6f71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/issue-66968-suggest-sorted-words.rs @@ -0,0 +1,5 @@ +fn main() { + let a_longer_variable_name = 1; + println!("{}", a_variable_longer_name); // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/issue-71394-no-from-impl.rs b/gcc/testsuite/rust/rustc/ui/suggestions/issue-71394-no-from-impl.rs new file mode 100644 index 000000000000..e97411a2c93b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/issue-71394-no-from-impl.rs @@ -0,0 +1,6 @@ +fn main() { + let data: &[u8] = &[0; 10]; + let _: &[i8] = data.into(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/issue-72766.rs b/gcc/testsuite/rust/rustc/ui/suggestions/issue-72766.rs new file mode 100644 index 000000000000..4747bd9bb18b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/issue-72766.rs @@ -0,0 +1,21 @@ +// edition:2018 +// compile-flags: -Cincremental=tmp/issue-72766 + +pub struct SadGirl; + +impl SadGirl { + pub async fn call(&self) -> Result<(), ()> { + Ok(()) + } +} + +async fn async_main() -> Result<(), ()> { + // should be `.call().await?` + SadGirl {}.call()?; // { dg-error ".E0277." "" { target *-*-* } } + Ok(()) +} + +fn main() { + let _ = async_main(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/js-style-comparison-op-separate-eq-token.rs b/gcc/testsuite/rust/rustc/ui/suggestions/js-style-comparison-op-separate-eq-token.rs new file mode 100644 index 000000000000..4e35a6a2172a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/js-style-comparison-op-separate-eq-token.rs @@ -0,0 +1,6 @@ +fn main() { + if 1 == = 1 { // { dg-error "" "" { target *-*-* } } + println!("yup!"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/js-style-comparison-op.rs b/gcc/testsuite/rust/rustc/ui/suggestions/js-style-comparison-op.rs new file mode 100644 index 000000000000..29ca6a845806 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/js-style-comparison-op.rs @@ -0,0 +1,9 @@ +// run-rustfix +fn main() { + if 1 === 1 { // { dg-error "" "" { target *-*-* } } + println!("yup!"); + } else if 1 !== 1 { // { dg-error "" "" { target *-*-* } } + println!("nope!"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/let-binding-init-expr-as-ty.rs b/gcc/testsuite/rust/rustc/ui/suggestions/let-binding-init-expr-as-ty.rs new file mode 100644 index 000000000000..b89692e815bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/let-binding-init-expr-as-ty.rs @@ -0,0 +1,12 @@ +pub fn foo(num: i32) -> i32 { + let foo: i32::from_be(num); +// { dg-error ".E0223." "" { target *-*-* } .-1 } +// { dg-error ".E0223." "" { target *-*-* } .-2 } +// { dg-error ".E0223." "" { target *-*-* } .-3 } + foo +} + +fn main() { + let _ = foo(42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs b/gcc/testsuite/rust/rustc/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs new file mode 100644 index 000000000000..8a6701d3d636 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs @@ -0,0 +1,111 @@ +pub trait Get { + fn get(self) -> T; +} + +struct Foo { + x: usize, +} + +impl Get for Foo { + fn get(self) -> usize { + self.x + } +} + +fn foo(g: G, dest: &mut T) -> impl FnOnce() +where + G: Get +{ + move || { // { dg-error ".E0759." "" { target *-*-* } } + *dest = g.get(); + } +} + +// After applying suggestion for `foo`: +fn bar(g: G, dest: &mut T) -> impl FnOnce() + '_ +// { dg-error ".E0309." "" { target *-*-* } .-1 } +where + G: Get +{ + move || { + *dest = g.get(); + } +} + + +// After applying suggestion for `bar`: +fn baz(g: G, dest: &mut T) -> impl FnOnce() + '_ // { dg-error ".E0261." "" { target *-*-* } } +where + G: Get +{ + move || { + *dest = g.get(); + } +} + +// After applying suggestion for `baz`: +fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ +// { dg-error ".E0309." "" { target *-*-* } .-1 } +where + G: Get +{ + move || { + *dest = g.get(); + } +} + +// Same as above, but show that we pay attention to lifetime names from parent item +impl<'a> Foo { + fn qux<'b, G: Get + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ { +// { dg-error ".E0309." "" { target *-*-* } .-1 } + move || { + *dest = g.get(); + } + } +} + +// After applying suggestion for `qux`: +fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a +// { dg-error ".E0621." "" { target *-*-* } .-1 } +where + G: Get +{ + move || { + *dest = g.get(); + } +} + +// Potential incorrect attempt: +fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a +// { dg-error ".E0309." "" { target *-*-* } .-1 } +where + G: Get +{ + move || { + *dest = g.get(); + } +} + + +// We need to tie the lifetime of `G` with the lifetime of `&mut T` and the returned closure: +fn ok<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a +where + G: Get +{ + move || { + *dest = g.get(); + } +} + +// This also works. The `'_` isn't necessary but it's where we arrive to following the suggestions: +fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a +where + G: Get +{ + move || { + *dest = g.get(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs new file mode 100644 index 000000000000..7654e0dd0869 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs @@ -0,0 +1,69 @@ +trait Foo {} +impl<'a, T: Foo> Foo for &'a T {} +impl Foo for Box {} + +struct Iter<'a, T> { + current: Option>, + remaining: T, +} + +impl<'a, T> Iterator for Iter<'a, T> +where + T: Iterator, + T::Item: Foo + 'a, +{ + type Item = Box; + + fn next(&mut self) -> Option { + let result = self.current.take(); + self.current = Box::new(self.remaining.next()).map(|f| Box::new(f) as _); + result + } +} + +struct Bar(Vec>); + +impl Bar { + fn iter(&self) -> impl Iterator> { + Iter { + current: None, + remaining: self.0.iter(), // { dg-error ".E0759." "" { target *-*-* } } + } + } +} + +struct Baz(Vec>); + +impl Baz { + fn iter(&self) -> impl Iterator> + '_ { + Iter { + current: None, + remaining: self.0.iter(), // { dg-error ".E0759." "" { target *-*-* } } + } + } +} + +struct Bat(Vec>); + +impl Bat { + fn iter<'a>(&'a self) -> impl Iterator> + 'a { + Iter { + current: None, + remaining: self.0.iter(), // { dg-error ".E0759." "" { target *-*-* } } + } + } +} + +struct Ban(Vec>); + +impl Ban { + fn iter<'a>(&'a self) -> impl Iterator> { + Iter { + current: None, + remaining: self.0.iter(), // { dg-error ".E0759." "" { target *-*-* } } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/match-ergonomics.rs b/gcc/testsuite/rust/rustc/ui/suggestions/match-ergonomics.rs new file mode 100644 index 000000000000..361a34844807 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/match-ergonomics.rs @@ -0,0 +1,42 @@ +fn main() { + let x = vec![1i32]; + match &x[..] { + [&v] => {}, // { dg-error ".E0308." "" { target *-*-* } } + _ => {}, + } + match x { + [&v] => {}, // { dg-error ".E0529." "" { target *-*-* } } + _ => {}, + } + match &x[..] { + [v] => {}, + _ => {}, + } + match &x[..] { + &[v] => {}, + _ => {}, + } + match x { + [v] => {}, // { dg-error ".E0529." "" { target *-*-* } } + _ => {}, + } + let y = 1i32; + match &y { + &v => {}, + _ => {}, + } + match y { + &v => {}, // { dg-error ".E0308." "" { target *-*-* } } + _ => {}, + } + match &y { + v => {}, + _ => {}, + } + match y { + v => {}, + _ => {}, + } + if let [&v] = &x[..] {} // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/match-needing-semi.rs b/gcc/testsuite/rust/rustc/ui/suggestions/match-needing-semi.rs new file mode 100644 index 000000000000..08825a7e9f1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/match-needing-semi.rs @@ -0,0 +1,19 @@ +// check-only +// run-rustfix + +fn main() { + match 3 { + 4 => 1, + 3 => { + 2 // { dg-error ".E0308." "" { target *-*-* } } + } + _ => 2 + } + match 3 { // { dg-error ".E0308." "" { target *-*-* } } + 4 => 1, + 3 => 2, + _ => 2 + } + let _ = (); +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/match-prev-arm-needing-semi.rs b/gcc/testsuite/rust/rustc/ui/suggestions/match-prev-arm-needing-semi.rs new file mode 100644 index 000000000000..418741d73dbf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/match-prev-arm-needing-semi.rs @@ -0,0 +1,58 @@ +// edition:2018 + +fn dummy() -> i32 { 42 } + +fn extra_semicolon() { + let _ = match true { // { dg-note ".E0308." "" { target *-*-* } } + true => { + dummy(); // { dg-note "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + } + false => dummy(), // { dg-error ".E0308." "" { target *-*-* } } +// { dg-note ".E0308." "" { target *-*-* } .-1 } + }; +} + +async fn async_dummy() {} // { dg-note "" "" { target *-*-* } } +async fn async_dummy2() {} // { dg-note "" "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-1 } + +async fn async_extra_semicolon_same() { + let _ = match true { // { dg-note ".E0308." "" { target *-*-* } } + true => { + async_dummy(); // { dg-note "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + } + false => async_dummy(), // { dg-error ".E0308." "" { target *-*-* } } +// { dg-note ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } +// { help ".E0308." "" { target *-*-* } .-3 } + }; +} + +async fn async_extra_semicolon_different() { + let _ = match true { // { dg-note ".E0308." "" { target *-*-* } } + true => { + async_dummy(); // { dg-note "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-1 } + } + false => async_dummy2(), // { dg-error ".E0308." "" { target *-*-* } } +// { dg-note ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } +// { help ".E0308." "" { target *-*-* } .-3 } + }; +} + +async fn async_different_futures() { + let _ = match true { // { dg-note ".E0308." "" { target *-*-* } } + true => async_dummy(), // { dg-note "" "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } + false => async_dummy2(), // { dg-error ".E0308." "" { target *-*-* } } +// { dg-note ".E0308." "" { target *-*-* } .-1 } +// { dg-note ".E0308." "" { target *-*-* } .-2 } +// { dg-note ".E0308." "" { target *-*-* } .-3 } + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/method-missing-parentheses.rs b/gcc/testsuite/rust/rustc/ui/suggestions/method-missing-parentheses.rs new file mode 100644 index 000000000000..f414851454c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/method-missing-parentheses.rs @@ -0,0 +1,6 @@ +fn main() { + let _ = vec![].into_iter().collect::; +// { dg-error ".E0615." "" { target *-*-* } .-1 } +// { dg-error ".E0615." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/mismatched-types-numeric-from.rs b/gcc/testsuite/rust/rustc/ui/suggestions/mismatched-types-numeric-from.rs new file mode 100644 index 000000000000..f41efaf1665c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/mismatched-types-numeric-from.rs @@ -0,0 +1,4 @@ +fn main() { + let _: u32 = i32::from(0_u8); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs b/gcc/testsuite/rust/rustc/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs new file mode 100644 index 000000000000..386fffb91ff9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs @@ -0,0 +1,19 @@ +// run-rustfix +trait TraitB { + type Item; +} + +trait TraitA { + type Type; + fn bar(_: T) -> Self; + fn baz(_: T) -> Self where T: TraitB, ::Item: Copy; +} + +struct S; +struct Type; + +impl TraitA<()> for S { // { dg-error ".E0046." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/missing-assoc-fn.rs b/gcc/testsuite/rust/rustc/ui/suggestions/missing-assoc-fn.rs new file mode 100644 index 000000000000..034d564e0d50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/missing-assoc-fn.rs @@ -0,0 +1,23 @@ +trait TraitB { + type Item; +} + +trait TraitA { + fn foo>(_: T) -> Self; + fn bar(_: T) -> Self; + fn baz(_: T) -> Self where T: TraitB, ::Item: Copy; + fn bat>(_: T) -> Self; // { dg-error ".E0658." "" { target *-*-* } } +} + +struct S; + +impl TraitA<()> for S { // { dg-error ".E0046." "" { target *-*-* } } +} + +use std::iter::FromIterator; +struct X; +impl FromIterator<()> for X { // { dg-error ".E0046." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/missing-assoc-type-bound-restriction.rs b/gcc/testsuite/rust/rustc/ui/suggestions/missing-assoc-type-bound-restriction.rs new file mode 100644 index 000000000000..650a99aa4713 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/missing-assoc-type-bound-restriction.rs @@ -0,0 +1,22 @@ +// 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/gcc/testsuite/rust/rustc/ui/suggestions/missing-lifetime-in-assoc-const-type.rs b/gcc/testsuite/rust/rustc/ui/suggestions/missing-lifetime-in-assoc-const-type.rs new file mode 100644 index 000000000000..98c936812811 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/missing-lifetime-in-assoc-const-type.rs @@ -0,0 +1,17 @@ +trait ZstAssert: Sized { + const A: &str = ""; // { dg-error ".E0106." "" { target *-*-* } } + const B: S = S { s: &() }; // { dg-error ".E0106." "" { target *-*-* } } + const C: &'_ str = ""; // { dg-error ".E0106." "" { target *-*-* } } + const D: T = T { a: &(), b: &() }; // { dg-error ".E0106." "" { target *-*-* } } +} + +struct S<'a> { + s: &'a (), +} +struct T<'a, 'b> { + a: &'a (), + b: &'b (), +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/missing-lifetime-specifier.rs b/gcc/testsuite/rust/rustc/ui/suggestions/missing-lifetime-specifier.rs new file mode 100644 index 000000000000..49670f1fc23c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/missing-lifetime-specifier.rs @@ -0,0 +1,60 @@ +#![allow(bare_trait_objects)] +use std::collections::HashMap; +use std::cell::RefCell; + +pub union Foo<'t, 'k> { + i: &'t i64, + f: &'k f64, +} +trait Bar<'t, 'k> {} + +pub union Qux<'t, 'k, I> { + i: &'t I, + f: &'k I, +} +trait Tar<'t, 'k, I> {} + +thread_local! { + static a: RefCell>>> = RefCell::new(HashMap::new()); +// { dg-error ".E0106." "" { target *-*-* } .-1 } +// { dg-error ".E0106." "" { target *-*-* } .-2 } +} +thread_local! { + static b: RefCell>>> = RefCell::new(HashMap::new()); +// { dg-error ".E0106." "" { target *-*-* } .-1 } +// { dg-error ".E0106." "" { target *-*-* } .-2 } +// { dg-error ".E0106." "" { target *-*-* } .-3 } +// { dg-error ".E0106." "" { target *-*-* } .-4 } +} +thread_local! { + static c: RefCell>>>> = RefCell::new(HashMap::new()); +// { dg-error ".E0106." "" { target *-*-* } .-1 } +// { dg-error ".E0106." "" { target *-*-* } .-2 } +} +thread_local! { + static d: RefCell>>>> = RefCell::new(HashMap::new()); +// { dg-error ".E0106." "" { target *-*-* } .-1 } +// { dg-error ".E0106." "" { target *-*-* } .-2 } +// { dg-error ".E0106." "" { target *-*-* } .-3 } +// { dg-error ".E0106." "" { target *-*-* } .-4 } +} + +thread_local! { + static e: RefCell>>>> = RefCell::new(HashMap::new()); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +// { dg-error ".E0107." "" { target *-*-* } .-3 } +// { dg-error ".E0107." "" { target *-*-* } .-4 } +} +thread_local! { + static f: RefCell>>>> = RefCell::new(HashMap::new()); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +// { dg-error ".E0107." "" { target *-*-* } .-3 } +// { dg-error ".E0107." "" { target *-*-* } .-4 } +// { dg-error ".E0107." "" { target *-*-* } .-5 } +// { dg-error ".E0107." "" { target *-*-* } .-6 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/missing-lt-for-hrtb.rs b/gcc/testsuite/rust/rustc/ui/suggestions/missing-lt-for-hrtb.rs new file mode 100644 index 000000000000..7462e31242fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/missing-lt-for-hrtb.rs @@ -0,0 +1,16 @@ +struct X<'a>(&'a ()); +struct S<'a>(&'a dyn Fn(&X) -> &X); +// { dg-error ".E0106." "" { target *-*-* } .-1 } +// { dg-error ".E0106." "" { target *-*-* } .-2 } +struct V<'a>(&'a dyn for<'b> Fn(&X) -> &X); +// { dg-error ".E0106." "" { target *-*-* } .-1 } +// { dg-error ".E0106." "" { target *-*-* } .-2 } + +fn main() { + let x = S(&|x| { + println!("hi"); + x + }); + x.0(&X(&())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/missing-trait-bound-for-op.rs b/gcc/testsuite/rust/rustc/ui/suggestions/missing-trait-bound-for-op.rs new file mode 100644 index 000000000000..ca09e1e35339 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/missing-trait-bound-for-op.rs @@ -0,0 +1,8 @@ +// run-rustfix + +pub fn foo(s: &[T], t: &[T]) { + let _ = s == t; // { dg-error ".E0369." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/missing-trait-bounds-for-method-call.rs b/gcc/testsuite/rust/rustc/ui/suggestions/missing-trait-bounds-for-method-call.rs new file mode 100644 index 000000000000..225b0d9428cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/missing-trait-bounds-for-method-call.rs @@ -0,0 +1,32 @@ +#[derive(Default, PartialEq)] +struct Foo { + bar: Box<[T]>, +} + +trait Bar { + fn foo(&self) {} +} + +impl Bar for Foo {} + +impl Foo { + fn bar(&self) { + self.foo(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + } +} + +struct Fin where T: Bar { + bar: Box<[T]>, +} + +impl Bar for Fin {} + +impl Fin { + fn bar(&self) { + self.foo(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/missing-trait-item.rs b/gcc/testsuite/rust/rustc/ui/suggestions/missing-trait-item.rs new file mode 100644 index 000000000000..e4e7f96a6cc4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/missing-trait-item.rs @@ -0,0 +1,17 @@ +// run-rustfix + +trait T { + unsafe fn foo(a: &usize, b: &usize) -> usize; + fn bar(&self, a: &usize, b: &usize) -> usize; +} + +mod foo { + use super::T; + impl T for () {} // { dg-error ".E0046." "" { target *-*-* } } + + impl T for usize { // { dg-error ".E0046." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/mut-borrow-needed-by-trait.rs b/gcc/testsuite/rust/rustc/ui/suggestions/mut-borrow-needed-by-trait.rs new file mode 100644 index 000000000000..b55beaa699d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/mut-borrow-needed-by-trait.rs @@ -0,0 +1,24 @@ +use std::env::args; +use std::fs::File; +use std::io::{stdout, Write, BufWriter}; + +fn main() { + let mut args = args(); + let _ = args.next(); + let dest = args.next(); + + let h1; let h2; let h3; + + let fp: &dyn Write = match dest { + Some(path) => { h1 = File::create(path).unwrap(); &h1 }, + None => { h2 = stdout(); h3 = h2.lock(); &h3 } + }; + + let fp = BufWriter::new(fp); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } + + writeln!(fp, "hello world").unwrap(); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/mut-ref-reassignment.rs b/gcc/testsuite/rust/rustc/ui/suggestions/mut-ref-reassignment.rs new file mode 100644 index 000000000000..56293e376df0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/mut-ref-reassignment.rs @@ -0,0 +1,18 @@ +fn suggestion(opt: &mut Option) { + opt = None; // { dg-error ".E0308." "" { target *-*-* } } +} + +fn no_suggestion(opt: &mut Result) { + opt = None // { dg-error ".E0308." "" { target *-*-* } } +} + +fn suggestion2(opt: &mut Option) { + opt = Some(String::new())// { dg-error ".E0308." "" { target *-*-* } } +} + +fn no_suggestion2(opt: &mut Option) { + opt = Some(42)// { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/no-extern-crate-in-type.rs b/gcc/testsuite/rust/rustc/ui/suggestions/no-extern-crate-in-type.rs new file mode 100644 index 000000000000..883d94cdb471 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/no-extern-crate-in-type.rs @@ -0,0 +1,8 @@ +// aux-build:foo.rs + +extern crate foo; + +type Output = Option; // { dg-error ".E0412." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/object-unsafe-trait-references-self.rs b/gcc/testsuite/rust/rustc/ui/suggestions/object-unsafe-trait-references-self.rs new file mode 100644 index 000000000000..ba423a66e720 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/object-unsafe-trait-references-self.rs @@ -0,0 +1,13 @@ +trait Trait { + fn baz(&self, _: Self) {} + fn bat(&self) -> Self {} +} + +fn bar(x: &dyn Trait) {} // { dg-error ".E0038." "" { target *-*-* } } + +trait Other: Sized {} + +fn foo(x: &dyn Other) {} // { dg-error ".E0038." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/object-unsafe-trait-should-use-self.rs b/gcc/testsuite/rust/rustc/ui/suggestions/object-unsafe-trait-should-use-self.rs new file mode 100644 index 000000000000..d56963e91a86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/object-unsafe-trait-should-use-self.rs @@ -0,0 +1,17 @@ +#![allow(bare_trait_objects)] +trait A: Sized { + fn f(a: A) -> A; +// { dg-error ".E0038." "" { target *-*-* } .-1 } +// { dg-error ".E0038." "" { target *-*-* } .-2 } +} +trait B { + fn f(a: B) -> B; +// { dg-error ".E0038." "" { target *-*-* } .-1 } +// { dg-error ".E0038." "" { target *-*-* } .-2 } +} +trait C { + fn f(&self, a: C) -> C; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs b/gcc/testsuite/rust/rustc/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs new file mode 100644 index 000000000000..b5b05bea89f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/object-unsafe-trait-should-use-where-sized.rs @@ -0,0 +1,14 @@ +// run-rustfix +#![allow(unused_variables, dead_code)] + +trait Trait { + fn foo() where Self: Other, { } + fn bar(self: ()) {} // { dg-error ".E0307." "" { target *-*-* } } +} + +fn bar(x: &dyn Trait) {} // { dg-error ".E0038." "" { target *-*-* } } + +trait Other {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/opaque-type-error.rs b/gcc/testsuite/rust/rustc/ui/suggestions/opaque-type-error.rs new file mode 100644 index 000000000000..3d0dcefaabd1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/opaque-type-error.rs @@ -0,0 +1,25 @@ +// edition:2018 +use core::future::Future; + +async fn base_thing() -> Result<(), ()> { + Ok(()) +} + +fn thing_one() -> impl Future> { + base_thing() +} + +fn thing_two() -> impl Future> { + base_thing() +} + +async fn thing() -> Result<(), ()> { + if true { + thing_one() + } else { + thing_two() // { dg-error ".E0308." "" { target *-*-* } } + }.await +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/option-content-move.rs b/gcc/testsuite/rust/rustc/ui/suggestions/option-content-move.rs new file mode 100644 index 000000000000..6673633350ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/option-content-move.rs @@ -0,0 +1,40 @@ +//run-rustfix + +pub struct LipogramCorpora { + selections: Vec<(char, Option)>, +} + +impl LipogramCorpora { + pub fn validate_all(&mut self) -> Result<(), char> { + for selection in &self.selections { + if selection.1.is_some() { + if selection.1.unwrap().contains(selection.0) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + return Err(selection.0); + } + } + } + Ok(()) + } +} + +pub struct LipogramCorpora2 { + selections: Vec<(char, Result)>, +} + +impl LipogramCorpora2 { + pub fn validate_all(&mut self) -> Result<(), char> { + for selection in &self.selections { + if selection.1.is_ok() { + if selection.1.unwrap().contains(selection.0) { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + return Err(selection.0); + } + } + } + Ok(()) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/option-content-move2.rs b/gcc/testsuite/rust/rustc/ui/suggestions/option-content-move2.rs new file mode 100644 index 000000000000..faaa7a46f3ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/option-content-move2.rs @@ -0,0 +1,17 @@ +struct NotCopyable; + +fn func H, H: FnMut()>(_: F) {} + +fn parse() { + let mut var = None; + func(|| { + // Shouldn't suggest `move ||.as_ref()` here + move || { +// { dg-error ".E0507." "" { target *-*-* } .-1 } + var = Some(NotCopyable); + } + }); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/path-by-value.rs b/gcc/testsuite/rust/rustc/ui/suggestions/path-by-value.rs new file mode 100644 index 000000000000..8601ac5f0bff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/path-by-value.rs @@ -0,0 +1,7 @@ +use std::path::Path; + +fn f(p: Path) { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/path-display.rs b/gcc/testsuite/rust/rustc/ui/suggestions/path-display.rs new file mode 100644 index 000000000000..2eeb1638c768 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/path-display.rs @@ -0,0 +1,8 @@ +use std::path::Path; + +fn main() { + let path = Path::new("/tmp/foo/bar.txt"); + println!("{}", path); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/raw-name-use-suggestion.rs b/gcc/testsuite/rust/rustc/ui/suggestions/raw-name-use-suggestion.rs new file mode 100644 index 000000000000..5c0fdc2ba931 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/raw-name-use-suggestion.rs @@ -0,0 +1,10 @@ +mod foo { + pub fn r#let() {} + pub fn break() {} // { dg-error "" "" { target *-*-* } } +} + +fn main() { + foo::let(); // { dg-error "" "" { target *-*-* } } + r#break(); // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/recover-from-semicolon-trailing-item.rs b/gcc/testsuite/rust/rustc/ui/suggestions/recover-from-semicolon-trailing-item.rs new file mode 100644 index 000000000000..b95a5cac79fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/recover-from-semicolon-trailing-item.rs @@ -0,0 +1,17 @@ +// verify that after encountering a semicolon after an item the parser recovers +mod M {}; +// { dg-error "" "" { target *-*-* } .-1 } +struct S {}; +// { dg-error "" "" { target *-*-* } .-1 } +fn foo(a: usize) {}; +// { dg-error "" "" { target *-*-* } .-1 } +fn main() { + struct X {}; // ok + let _: usize = S {}; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + let _: usize = X {}; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + foo(""); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/recover-invalid-float.rs b/gcc/testsuite/rust/rustc/ui/suggestions/recover-invalid-float.rs new file mode 100644 index 000000000000..c29dc9f1aaa8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/recover-invalid-float.rs @@ -0,0 +1,11 @@ +// run-rustfix + +fn main() { + let _: f32 = .3; +// { dg-error "" "" { target *-*-* } .-1 } + let _: f32 = .42f32; +// { dg-error "" "" { target *-*-* } .-1 } + let _: f64 = .5f64; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/recover-missing-turbofish-surrounding-angle-braket.rs b/gcc/testsuite/rust/rustc/ui/suggestions/recover-missing-turbofish-surrounding-angle-braket.rs new file mode 100644 index 000000000000..2c7c111d64fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/recover-missing-turbofish-surrounding-angle-braket.rs @@ -0,0 +1,11 @@ +fn main() { + let _ = vec![1, 2, 3].into_iter().collect::Vec<_>(); +// { dg-error "" "" { target *-*-* } .-1 } + let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>>>(); +// { dg-error "" "" { target *-*-* } .-1 } + let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>>(); +// { dg-error "" "" { target *-*-* } .-1 } + let _ = vec![1, 2, 3].into_iter().collect::Vec<_>>(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/remove-as_str.rs b/gcc/testsuite/rust/rustc/ui/suggestions/remove-as_str.rs new file mode 100644 index 000000000000..99b31eca7dcb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/remove-as_str.rs @@ -0,0 +1,22 @@ +fn foo1(s: &str) { + s.as_str(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + +fn foo2<'a>(s: &'a str) { + s.as_str(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + +fn foo3(s: &mut str) { + s.as_str(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + +fn foo4(s: &&str) { + s.as_str(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/restrict-type-argument.rs b/gcc/testsuite/rust/rustc/ui/suggestions/restrict-type-argument.rs new file mode 100644 index 000000000000..42ed66c2588e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/restrict-type-argument.rs @@ -0,0 +1,32 @@ +fn is_send(val: T) {} + +fn use_impl_sync(val: impl Sync) { + is_send(val); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn use_where(val: S) where S: Sync { + is_send(val); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn use_bound(val: S) { + is_send(val); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn use_bound_2< + S // Make sure we can synthezise a correct suggestion span for this case + : + Sync +>(val: S) { + is_send(val); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn use_bound_and_where(val: S) where S: std::fmt::Debug { + is_send(val); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn use_unbound(val: S) { + is_send(val); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/return-without-lifetime.rs b/gcc/testsuite/rust/rustc/ui/suggestions/return-without-lifetime.rs new file mode 100644 index 000000000000..8ea3366f6b0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/return-without-lifetime.rs @@ -0,0 +1,11 @@ +struct Thing<'a>(&'a ()); +struct Foo<'a>(&usize); +// { dg-error ".E0106." "" { target *-*-* } .-1 } + +fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } +// { dg-error ".E0106." "" { target *-*-* } .-1 } +fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } +// { dg-error ".E0106." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/struct-initializer-comma.rs b/gcc/testsuite/rust/rustc/ui/suggestions/struct-initializer-comma.rs new file mode 100644 index 000000000000..ea994854e543 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/struct-initializer-comma.rs @@ -0,0 +1,16 @@ +// run-rustfix + +pub struct Foo { + pub first: bool, + pub second: u8, +} + +fn main() { + let _ = Foo { +// { dg-error ".E0063." "" { target *-*-* } .-1 } + first: true + second: 25 +// { dg-error "" "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs new file mode 100644 index 000000000000..2ced52489d5c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.rs @@ -0,0 +1,14 @@ +use std::cell::RefCell; + +struct HasAssocMethod; + +impl HasAssocMethod { + fn hello() {} +} +fn main() { + let shared_state = RefCell::new(HasAssocMethod); + let state = shared_state.borrow_mut(); + state.hello(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs new file mode 100644 index 000000000000..38c8618d4c33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-assoc-fn-call-with-turbofish.rs @@ -0,0 +1,12 @@ +struct GenericAssocMethod(T); + +impl GenericAssocMethod { + fn default_hello() {} +} + +fn main() { + let x = GenericAssocMethod(33i32); + x.default_hello(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-box.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-box.rs new file mode 100644 index 000000000000..7d1d943f417d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-box.rs @@ -0,0 +1,9 @@ +// run-rustfix + +fn main() { + let _x: Box Result<(), ()>> = || { // { dg-error ".E0308." "" { target *-*-* } } + Err(())?; + Ok(()) + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-closure-return-type-1.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-closure-return-type-1.rs new file mode 100644 index 000000000000..bd2ea81eefd7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-closure-return-type-1.rs @@ -0,0 +1,4 @@ +fn main() { + let _v = || -> _ { [] }; // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-closure-return-type-2.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-closure-return-type-2.rs new file mode 100644 index 000000000000..55c61e3c8cd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-closure-return-type-2.rs @@ -0,0 +1,4 @@ +fn main() { + let _v = || { [] }; // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-closure-return-type-3.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-closure-return-type-3.rs new file mode 100644 index 000000000000..199d5093f69d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-closure-return-type-3.rs @@ -0,0 +1,4 @@ +fn main() { + let _v = || []; // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-impl-trait-lifetime.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-impl-trait-lifetime.rs new file mode 100644 index 000000000000..1cc5a1a60ce4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-impl-trait-lifetime.rs @@ -0,0 +1,19 @@ +// run-rustfix + +use std::fmt::Debug; + +fn foo(d: impl Debug) { +// { help "" "" { target *-*-* } .-1 } + bar(d); +// { dg-error ".E0310." "" { target *-*-* } .-1 } +// { dg-note ".E0310." "" { target *-*-* } .-2 } +} + +fn bar(d: impl Debug + 'static) { + println!("{:?}", d) +} + +fn main() { + foo("hi"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-labels.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-labels.rs new file mode 100644 index 000000000000..240b1ddd65e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-labels.rs @@ -0,0 +1,17 @@ +#[allow(unreachable_code, unused_labels)] +fn main() { + 'foo: loop { + break 'fo; // { dg-error ".E0426." "" { target *-*-* } } + } + + 'bar: loop { + continue 'bor; // { dg-error ".E0426." "" { target *-*-* } } + } + + 'longlabel: loop { + 'longlabel1: loop { + break 'longlable; // { dg-error ".E0426." "" { target *-*-* } } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-methods.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-methods.rs new file mode 100644 index 000000000000..8709b9dbe9c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-methods.rs @@ -0,0 +1,31 @@ +struct Foo; + +impl Foo { + fn bar(self) {} + fn baz(&self, x: f64) {} +} + +trait FooT { + fn bag(&self); +} + +impl FooT for Foo { + fn bag(&self) {} +} + +fn main() { + let f = Foo; + f.bat(1.0); // { dg-error ".E0599." "" { target *-*-* } } + + let s = "foo".to_string(); + let _ = s.is_emtpy(); // { dg-error ".E0599." "" { target *-*-* } } + + // Generates a warning for `count_zeros()`. `count_ones()` is also a close + // match, but the former is closer. + let _ = 63u32.count_eos(); // { dg-error ".E0599." "" { target *-*-* } } + + // Does not generate a warning + let _ = 63u32.count_o(); // { dg-error ".E0599." "" { target *-*-* } } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-move-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-move-lifetimes.rs new file mode 100644 index 000000000000..7e6fe6ff0ef7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-move-lifetimes.rs @@ -0,0 +1,22 @@ +struct A { // { dg-error "" "" { target *-*-* } } + t: &'a T, +} + +struct B { // { dg-error "" "" { target *-*-* } } + t: &'a T, + u: U, +} + +struct C { // { dg-error "" "" { target *-*-* } } + t: &'a T, + u: U, +} + +struct D { // { dg-error "" "" { target *-*-* } } + t: &'a T, + u: &'b U, + v: &'c V, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-move-types.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-move-types.rs new file mode 100644 index 000000000000..f47ae873ae99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-move-types.rs @@ -0,0 +1,92 @@ +#![allow(warnings)] + +// This test verifies that the suggestion to move types before associated type bindings +// is correct. + +trait One { + type A; +} + +trait OneWithLifetime<'a, T> { + type A; +} + +trait Three { + type A; + type B; + type C; +} + +trait ThreeWithLifetime<'a, 'b, 'c, T, U, V> { + type A; + type B; + type C; +} + +struct A> { +// { dg-error "" "" { target *-*-* } .-1 } + m: M, + t: T, +} + + +struct Al<'a, T, M: OneWithLifetime> { +// { dg-error ".E0747." "" { target *-*-* } .-1 } +// { dg-error ".E0747." "" { target *-*-* } .-2 } + m: M, + t: &'a T, +} + +struct B> { +// { dg-error "" "" { target *-*-* } .-1 } + m: M, + t: T, + u: U, + v: V, +} + +struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { +// { dg-error ".E0747." "" { target *-*-* } .-1 } +// { dg-error ".E0747." "" { target *-*-* } .-2 } + m: M, + t: &'a T, + u: &'b U, + v: &'c V, +} + +struct C> { +// { dg-error "" "" { target *-*-* } .-1 } + m: M, + t: T, + u: U, + v: V, +} + +struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { +// { dg-error ".E0747." "" { target *-*-* } .-1 } +// { dg-error ".E0747." "" { target *-*-* } .-2 } + m: M, + t: &'a T, + u: &'b U, + v: &'c V, +} + +struct D> { +// { dg-error "" "" { target *-*-* } .-1 } + m: M, + t: T, + u: U, + v: V, +} + +struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime> { +// { dg-error ".E0747." "" { target *-*-* } .-1 } +// { dg-error ".E0747." "" { target *-*-* } .-2 } + m: M, + t: &'a T, + u: &'b U, + v: &'c V, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-on-bare-closure-call.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-on-bare-closure-call.rs new file mode 100644 index 000000000000..4c2070415476 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-on-bare-closure-call.rs @@ -0,0 +1,5 @@ +fn main() { + let _ = ||{}(); +// { dg-error ".E0618." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-private-fields.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-private-fields.rs new file mode 100644 index 000000000000..9aa055dd84b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-private-fields.rs @@ -0,0 +1,28 @@ +// aux-build:struct_field_privacy.rs + +extern crate struct_field_privacy as xc; + +use xc::B; + +struct A { + pub a: u32, + b: u32, +} + +fn main () { + // external crate struct + let k = B { + aa: 20, +// { dg-error ".E0560." "" { target *-*-* } .-1 } + bb: 20, +// { dg-error ".E0560." "" { target *-*-* } .-1 } + }; + // local crate struct + let l = A { + aa: 20, +// { dg-error ".E0560." "" { target *-*-* } .-1 } + bb: 20, +// { dg-error ".E0560." "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-ref-mut.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-ref-mut.rs new file mode 100644 index 000000000000..bf451420a068 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-ref-mut.rs @@ -0,0 +1,31 @@ +struct X(usize); + +impl X { + fn zap(&self) { +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + self.0 = 32; +// { dg-error ".E0594." "" { target *-*-* } .-1 } + } +} + +fn main() { + let ref foo = 16; +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + *foo = 32; +// { dg-error ".E0594." "" { target *-*-* } .-1 } + if let Some(ref bar) = Some(16) { +// { help "" "" { target *-*-* } .-1 } +// { suggestion "" "" { target *-*-* } .-2 } + *bar = 32; +// { dg-error ".E0594." "" { target *-*-* } .-1 } + } + match 16 { + ref quo => { *quo = 32; }, +// { dg-error ".E0594." "" { target *-*-* } .-1 } +// { help ".E0594." "" { target *-*-* } .-2 } +// { suggestion ".E0594." "" { target *-*-* } .-3 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-remove-refs-1.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-remove-refs-1.rs new file mode 100644 index 000000000000..7de5e68b0e90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-remove-refs-1.rs @@ -0,0 +1,11 @@ +// run-rustfix + +fn main() { + let v = vec![0, 1, 2, 3]; + + for (i, _) in &v.iter().enumerate() { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + println!("{}", i); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-remove-refs-2.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-remove-refs-2.rs new file mode 100644 index 000000000000..357d7f75c90c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-remove-refs-2.rs @@ -0,0 +1,11 @@ +// run-rustfix + +fn main() { + let v = vec![0, 1, 2, 3]; + + for (i, _) in & & & & &v.iter().enumerate() { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + println!("{}", i); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-remove-refs-3.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-remove-refs-3.rs new file mode 100644 index 000000000000..1b48ecc64381 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-remove-refs-3.rs @@ -0,0 +1,14 @@ +// run-rustfix + +fn main() { + let v = vec![0, 1, 2, 3]; + + for (i, _) in & & & + & &v + .iter() + .enumerate() { +// { dg-error ".E0277." "" { target *-*-* } .-4 } + println!("{}", i); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-split-at-mut.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-split-at-mut.rs new file mode 100644 index 000000000000..1d972eafb552 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-split-at-mut.rs @@ -0,0 +1,9 @@ +fn main() { + let mut foo = [1, 2, 3, 4]; + let a = &mut foo[2]; + let b = &mut foo[3]; // { dg-error ".E0499." "" { target *-*-* } } + *a = 5; + *b = 6; + println!("{:?} {:?}", a, b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-std-when-using-type.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-std-when-using-type.rs new file mode 100644 index 000000000000..d0d569bba36d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-std-when-using-type.rs @@ -0,0 +1,8 @@ +fn main() { + let pi = f32::consts::PI; // { dg-error ".E0223." "" { target *-*-* } } + let bytes = "hello world".as_bytes(); + let string = unsafe { + str::from_utf8(bytes) // { dg-error ".E0599." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/suggest-variants.rs b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-variants.rs new file mode 100644 index 000000000000..6205d04ee087 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/suggest-variants.rs @@ -0,0 +1,19 @@ +#[derive(Debug)] +enum Shape { + Square { size: i32 }, + Circle { radius: i32 }, +} + +struct S { + x: usize, +} + +fn main() { + println!("My shape is {:?}", Shape::Squareee { size: 5}); // { dg-error ".E0599." "" { target *-*-* } } + println!("My shape is {:?}", Shape::Circl { size: 5}); // { dg-error ".E0599." "" { target *-*-* } } + println!("My shape is {:?}", Shape::Rombus{ size: 5}); // { dg-error ".E0599." "" { target *-*-* } } + Shape::Squareee; // { dg-error ".E0599." "" { target *-*-* } } + Shape::Circl; // { dg-error ".E0599." "" { target *-*-* } } + Shape::Rombus; // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.rs b/gcc/testsuite/rust/rustc/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.rs new file mode 100644 index 000000000000..a69fccb40920 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.rs @@ -0,0 +1,44 @@ +// run-rustfix +#![allow(unused)] // for the fixed file + +trait Trait { + type A; + + fn func(&self) -> Self::A; +} + +struct S(T); +impl S { + fn foo<'a, T: Trait + 'a>(&self, _: impl Trait, x: impl Trait, _: T) { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } + } + + fn ban(x: T) where T: Trait { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn foo<'a, T: Trait + 'a>(_: impl Trait, x: impl Trait, _: T) { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn bar(x: T) { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn foo2(x: impl Trait) { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn bar2>(x: T) { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn ban(x: T) where T: Trait { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn qux(_: usize) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/trait-with-missing-associated-type-restriction.rs b/gcc/testsuite/rust/rustc/ui/suggestions/trait-with-missing-associated-type-restriction.rs new file mode 100644 index 000000000000..3a2742b53b3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/trait-with-missing-associated-type-restriction.rs @@ -0,0 +1,45 @@ +// These are all the possible variations of this error I could think of for. +// `trait-with-missing-associated-type-restriction-fixable.rs` contains the subset of these that +// can be fixed with `rustfix`. + +trait Trait { + type A; + + fn func(&self) -> Self::A; + fn funk(&self, _: Self::A); + fn funq(&self) -> Self::A {} // { dg-error ".E0308." "" { target *-*-* } } +} + +fn foo(_: impl Trait, x: impl Trait) { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn bar(x: T) { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn foo2(x: impl Trait) { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn bar2>(x: T) { + x.funk(3); // { dg-error ".E0308." "" { target *-*-* } } + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn baz>(x: T) { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn bat(x: &mut dyn Trait<(), A = ()>) { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn ban(x: T) where T: Trait { + qux(x.func()) // { dg-error ".E0308." "" { target *-*-* } } +} + +fn qux(_: usize) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-let.rs b/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-let.rs new file mode 100644 index 000000000000..0442ca85b43a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-let.rs @@ -0,0 +1,11 @@ +fn fun(x: i32) -> i32 { x } + +fn main() { + let closure_annotated = |value: i32| -> i32 { + temp: i32 = fun(5i32); +// { dg-error ".E0425." "" { target *-*-* } .-1 } + temp + value + 1 +// { dg-error ".E0425." "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-method.rs b/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-method.rs new file mode 100644 index 000000000000..97e233e2acaf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-method.rs @@ -0,0 +1,6 @@ +// run-rustfix +fn main() { + let _ = Box:new("foo".to_string()); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-path-2.rs b/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-path-2.rs new file mode 100644 index 000000000000..1c6b50f8c60f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-path-2.rs @@ -0,0 +1,7 @@ +// run-rustfix +fn main() -> Result<(), ()> { + let _ = vec![Ok(2)].into_iter().collect:,_>>()?; +// { dg-error "" "" { target *-*-* } .-1 } + Ok(()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-path.rs b/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-path.rs new file mode 100644 index 000000000000..55032cec06c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-path.rs @@ -0,0 +1,6 @@ +fn main() { + std:io::stdin(); +// { dg-error ".E0423." "" { target *-*-* } .-1 } +// { dg-error ".E0423." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-variant.rs b/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-variant.rs new file mode 100644 index 000000000000..fa27969236f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/type-ascription-instead-of-variant.rs @@ -0,0 +1,6 @@ +// run-rustfix +fn main() { + let _ = Option:Some(""); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/type-mismatch-struct-field-shorthand-2.rs b/gcc/testsuite/rust/rustc/ui/suggestions/type-mismatch-struct-field-shorthand-2.rs new file mode 100644 index 000000000000..88b18e50fd11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/type-mismatch-struct-field-shorthand-2.rs @@ -0,0 +1,10 @@ +struct RGB { r: f64, g: f64, b: f64 } + +fn main() { + let (r, g, c): (f32, f32, f32) = (0., 0., 0.); + let _ = RGB { r, g, c }; +// { dg-error ".E0560." "" { target *-*-* } .-1 } +// { dg-error ".E0560." "" { target *-*-* } .-2 } +// { dg-error ".E0560." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/type-mismatch-struct-field-shorthand.rs b/gcc/testsuite/rust/rustc/ui/suggestions/type-mismatch-struct-field-shorthand.rs new file mode 100644 index 000000000000..d2d7c11422e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/type-mismatch-struct-field-shorthand.rs @@ -0,0 +1,13 @@ +// run-rustfix +#![allow(dead_code)] + +struct RGB { r: f64, g: f64, b: f64 } + +fn main() { + let (r, g, b): (f32, f32, f32) = (0., 0., 0.); + let _ = RGB { r, g, b }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/type-not-found-in-adt-field.rs b/gcc/testsuite/rust/rustc/ui/suggestions/type-not-found-in-adt-field.rs new file mode 100644 index 000000000000..6ae8854fe8a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/type-not-found-in-adt-field.rs @@ -0,0 +1,10 @@ +struct Struct { + m: Vec>, // { dg-error ".E0412." "" { target *-*-* } } +// { dg-note ".E0412." "" { target *-*-* } .-1 } +} +struct OtherStruct { // { help "" "" { target *-*-* } } + m: K, // { dg-error ".E0412." "" { target *-*-* } } +// { dg-note ".E0412." "" { target *-*-* } .-1 } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/unused-closure-argument.rs b/gcc/testsuite/rust/rustc/ui/suggestions/unused-closure-argument.rs new file mode 100644 index 000000000000..6b5a5649503b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/unused-closure-argument.rs @@ -0,0 +1,21 @@ +#![deny(unused_variables)] + +struct Point { + x: i32, + y: i32, +} + +fn main() { + let points = vec!(Point { x: 1, y: 2 }, Point { x: 3, y: 4 }); + + let _: i32 = points.iter() + .map(|Point { x, y }| y) +// { dg-error "" "" { target *-*-* } .-1 } + .sum(); + + let _: i32 = points.iter() + .map(|x| 4) +// { dg-error "" "" { target *-*-* } .-1 } + .sum(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/use-type-argument-instead-of-assoc-type.rs b/gcc/testsuite/rust/rustc/ui/suggestions/use-type-argument-instead-of-assoc-type.rs new file mode 100644 index 000000000000..1caf0eab3786 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/use-type-argument-instead-of-assoc-type.rs @@ -0,0 +1,14 @@ +pub trait T { + type A; + type B; + type C; +} +pub struct Foo { + i: Box>, +// { dg-error ".E0191." "" { target *-*-* } .-1 } +// { dg-error ".E0191." "" { target *-*-* } .-2 } +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/suggestions/vec-macro-in-pattern.rs b/gcc/testsuite/rust/rustc/ui/suggestions/vec-macro-in-pattern.rs new file mode 100644 index 000000000000..0a626365af56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suggestions/vec-macro-in-pattern.rs @@ -0,0 +1,9 @@ +// run-rustfix +fn main() { + // everything after `.as_ref` should be suggested + match Some(vec![3]).as_ref().map(|v| v.as_slice()) { + Some(vec![_x]) => (), // { dg-error "" "" { target *-*-* } } + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/super-at-top-level.rs b/gcc/testsuite/rust/rustc/ui/super-at-top-level.rs new file mode 100644 index 000000000000..cd17a92d90ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/super-at-top-level.rs @@ -0,0 +1,5 @@ +use super::f; // { dg-error ".E0433." "" { target *-*-* } } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/super-fast-paren-parsing.rs b/gcc/testsuite/rust/rustc/ui/super-fast-paren-parsing.rs new file mode 100644 index 000000000000..ab447eb04fcd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/super-fast-paren-parsing.rs @@ -0,0 +1,26 @@ +// run-pass + +#![allow(unused_parens)] +#![allow(non_upper_case_globals)] +#![allow(dead_code)] +// exec-env:RUST_MIN_STACK=16000000 +// rustc-env:RUST_MIN_STACK=16000000 +// +// Big stack is needed for pretty printing, a little sad... + +static a: isize = +((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((( +((((((((((((((((((((((((((((((((((((((((((((((((((( +1 +))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))) +))))))))))))))))))))))))))))))))))))))))))))))))))) +; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/super.rs b/gcc/testsuite/rust/rustc/ui/super.rs new file mode 100644 index 000000000000..b9994ab2f1e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/super.rs @@ -0,0 +1,17 @@ +// run-pass + +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +pub mod a { + pub fn f() {} + pub mod b { + fn g() { + super::f(); + } + } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/supported-cast.rs b/gcc/testsuite/rust/rustc/ui/supported-cast.rs new file mode 100644 index 000000000000..4a4120dc3612 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/supported-cast.rs @@ -0,0 +1,207 @@ +// run-pass + +pub fn main() { + let f = 1_usize as *const String; + println!("{:?}", f as isize); + println!("{:?}", f as usize); + println!("{:?}", f as i8); + println!("{:?}", f as i16); + println!("{:?}", f as i32); + println!("{:?}", f as i64); + println!("{:?}", f as u8); + println!("{:?}", f as u16); + println!("{:?}", f as u32); + println!("{:?}", f as u64); + + println!("{:?}", 1 as isize); + println!("{:?}", 1 as usize); + println!("{:?}", 1 as *const String); + println!("{:?}", 1 as i8); + println!("{:?}", 1 as i16); + println!("{:?}", 1 as i32); + println!("{:?}", 1 as i64); + println!("{:?}", 1 as u8); + println!("{:?}", 1 as u16); + println!("{:?}", 1 as u32); + println!("{:?}", 1 as u64); + println!("{:?}", 1 as f32); + println!("{:?}", 1 as f64); + + println!("{:?}", 1_usize as isize); + println!("{:?}", 1_usize as usize); + println!("{:?}", 1_usize as *const String); + println!("{:?}", 1_usize as i8); + println!("{:?}", 1_usize as i16); + println!("{:?}", 1_usize as i32); + println!("{:?}", 1_usize as i64); + println!("{:?}", 1_usize as u8); + println!("{:?}", 1_usize as u16); + println!("{:?}", 1_usize as u32); + println!("{:?}", 1_usize as u64); + println!("{:?}", 1_usize as f32); + println!("{:?}", 1_usize as f64); + + println!("{:?}", 1i8 as isize); + println!("{:?}", 1i8 as usize); + println!("{:?}", 1i8 as *const String); + println!("{:?}", 1i8 as i8); + println!("{:?}", 1i8 as i16); + println!("{:?}", 1i8 as i32); + println!("{:?}", 1i8 as i64); + println!("{:?}", 1i8 as u8); + println!("{:?}", 1i8 as u16); + println!("{:?}", 1i8 as u32); + println!("{:?}", 1i8 as u64); + println!("{:?}", 1i8 as f32); + println!("{:?}", 1i8 as f64); + + println!("{:?}", 1u8 as isize); + println!("{:?}", 1u8 as usize); + println!("{:?}", 1u8 as *const String); + println!("{:?}", 1u8 as i8); + println!("{:?}", 1u8 as i16); + println!("{:?}", 1u8 as i32); + println!("{:?}", 1u8 as i64); + println!("{:?}", 1u8 as u8); + println!("{:?}", 1u8 as u16); + println!("{:?}", 1u8 as u32); + println!("{:?}", 1u8 as u64); + println!("{:?}", 1u8 as f32); + println!("{:?}", 1u8 as f64); + + println!("{:?}", 1i16 as isize); + println!("{:?}", 1i16 as usize); + println!("{:?}", 1i16 as *const String); + println!("{:?}", 1i16 as i8); + println!("{:?}", 1i16 as i16); + println!("{:?}", 1i16 as i32); + println!("{:?}", 1i16 as i64); + println!("{:?}", 1i16 as u8); + println!("{:?}", 1i16 as u16); + println!("{:?}", 1i16 as u32); + println!("{:?}", 1i16 as u64); + println!("{:?}", 1i16 as f32); + println!("{:?}", 1i16 as f64); + + println!("{:?}", 1u16 as isize); + println!("{:?}", 1u16 as usize); + println!("{:?}", 1u16 as *const String); + println!("{:?}", 1u16 as i8); + println!("{:?}", 1u16 as i16); + println!("{:?}", 1u16 as i32); + println!("{:?}", 1u16 as i64); + println!("{:?}", 1u16 as u8); + println!("{:?}", 1u16 as u16); + println!("{:?}", 1u16 as u32); + println!("{:?}", 1u16 as u64); + println!("{:?}", 1u16 as f32); + println!("{:?}", 1u16 as f64); + + println!("{:?}", 1i32 as isize); + println!("{:?}", 1i32 as usize); + println!("{:?}", 1i32 as *const String); + println!("{:?}", 1i32 as i8); + println!("{:?}", 1i32 as i16); + println!("{:?}", 1i32 as i32); + println!("{:?}", 1i32 as i64); + println!("{:?}", 1i32 as u8); + println!("{:?}", 1i32 as u16); + println!("{:?}", 1i32 as u32); + println!("{:?}", 1i32 as u64); + println!("{:?}", 1i32 as f32); + println!("{:?}", 1i32 as f64); + + println!("{:?}", 1u32 as isize); + println!("{:?}", 1u32 as usize); + println!("{:?}", 1u32 as *const String); + println!("{:?}", 1u32 as i8); + println!("{:?}", 1u32 as i16); + println!("{:?}", 1u32 as i32); + println!("{:?}", 1u32 as i64); + println!("{:?}", 1u32 as u8); + println!("{:?}", 1u32 as u16); + println!("{:?}", 1u32 as u32); + println!("{:?}", 1u32 as u64); + println!("{:?}", 1u32 as f32); + println!("{:?}", 1u32 as f64); + + println!("{:?}", 1i64 as isize); + println!("{:?}", 1i64 as usize); + println!("{:?}", 1i64 as *const String); + println!("{:?}", 1i64 as i8); + println!("{:?}", 1i64 as i16); + println!("{:?}", 1i64 as i32); + println!("{:?}", 1i64 as i64); + println!("{:?}", 1i64 as u8); + println!("{:?}", 1i64 as u16); + println!("{:?}", 1i64 as u32); + println!("{:?}", 1i64 as u64); + println!("{:?}", 1i64 as f32); + println!("{:?}", 1i64 as f64); + + println!("{:?}", 1u64 as isize); + println!("{:?}", 1u64 as usize); + println!("{:?}", 1u64 as *const String); + println!("{:?}", 1u64 as i8); + println!("{:?}", 1u64 as i16); + println!("{:?}", 1u64 as i32); + println!("{:?}", 1u64 as i64); + println!("{:?}", 1u64 as u8); + println!("{:?}", 1u64 as u16); + println!("{:?}", 1u64 as u32); + println!("{:?}", 1u64 as u64); + println!("{:?}", 1u64 as f32); + println!("{:?}", 1u64 as f64); + + println!("{:?}", 1u64 as isize); + println!("{:?}", 1u64 as usize); + println!("{:?}", 1u64 as *const String); + println!("{:?}", 1u64 as i8); + println!("{:?}", 1u64 as i16); + println!("{:?}", 1u64 as i32); + println!("{:?}", 1u64 as i64); + println!("{:?}", 1u64 as u8); + println!("{:?}", 1u64 as u16); + println!("{:?}", 1u64 as u32); + println!("{:?}", 1u64 as u64); + println!("{:?}", 1u64 as f32); + println!("{:?}", 1u64 as f64); + + println!("{:?}", true as isize); + println!("{:?}", true as usize); + println!("{:?}", true as i8); + println!("{:?}", true as i16); + println!("{:?}", true as i32); + println!("{:?}", true as i64); + println!("{:?}", true as u8); + println!("{:?}", true as u16); + println!("{:?}", true as u32); + println!("{:?}", true as u64); + + println!("{:?}", 1f32 as isize); + println!("{:?}", 1f32 as usize); + println!("{:?}", 1f32 as i8); + println!("{:?}", 1f32 as i16); + println!("{:?}", 1f32 as i32); + println!("{:?}", 1f32 as i64); + println!("{:?}", 1f32 as u8); + println!("{:?}", 1f32 as u16); + println!("{:?}", 1f32 as u32); + println!("{:?}", 1f32 as u64); + println!("{:?}", 1f32 as f32); + println!("{:?}", 1f32 as f64); + + println!("{:?}", 1f64 as isize); + println!("{:?}", 1f64 as usize); + println!("{:?}", 1f64 as i8); + println!("{:?}", 1f64 as i16); + println!("{:?}", 1f64 as i32); + println!("{:?}", 1f64 as i64); + println!("{:?}", 1f64 as u8); + println!("{:?}", 1f64 as u16); + println!("{:?}", 1f64 as u32); + println!("{:?}", 1f64 as u64); + println!("{:?}", 1f64 as f32); + println!("{:?}", 1f64 as f64); +} + diff --git a/gcc/testsuite/rust/rustc/ui/suppressed-error.rs b/gcc/testsuite/rust/rustc/ui/suppressed-error.rs new file mode 100644 index 000000000000..8200297b8ff1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/suppressed-error.rs @@ -0,0 +1,9 @@ +fn main() { + let (x, y) = (); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + return x; +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh-add-nothing.rs b/gcc/testsuite/rust/rustc/ui/svh-add-nothing.rs new file mode 100644 index 000000000000..ce835d9633a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh-add-nothing.rs @@ -0,0 +1,15 @@ +// run-pass +// note that these aux-build directives must be in this order +// aux-build:svh-a-base.rs +// aux-build:svh-b.rs +// aux-build:svh-a-base.rs + +// pretty-expanded FIXME #23616 + +extern crate a; +extern crate b; + +fn main() { + b::foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-base.rs b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-base.rs new file mode 100644 index 000000000000..0457648ed473 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-base.rs @@ -0,0 +1,26 @@ +//! The `svh-a-*.rs` files are all deviations from the base file +//! svh-a-base.rs with some difference (usually in `fn foo`) that +//! should not affect the strict version hash (SVH) computation +//! (#14132). + +#![crate_name = "a"] + +macro_rules! three { + () => { 3 } +} + +pub trait U {} +pub trait V {} +impl U for () {} +impl V for () {} + +static A_CONSTANT : isize = 2; + +pub fn foo(_: isize) -> isize { + 3 +} + +pub fn an_unused_name() -> isize { + 4 +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-lit.rs b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-lit.rs new file mode 100644 index 000000000000..839830ad1703 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-lit.rs @@ -0,0 +1,26 @@ +//! The `svh-a-*.rs` files are all deviations from the base file +//! svh-a-base.rs with some difference (usually in `fn foo`) that +//! should not affect the strict version hash (SVH) computation +//! (#14132). + +#![crate_name = "a"] + +macro_rules! three { + () => { 3 } +} + +pub trait U {} +pub trait V {} +impl U for () {} +impl V for () {} + +static A_CONSTANT : isize = 2; + +pub fn foo(_: isize) -> isize { + 0 +} + +pub fn an_unused_name() -> isize { + 4 +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-significant-cfg.rs b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-significant-cfg.rs new file mode 100644 index 000000000000..28150736855c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-significant-cfg.rs @@ -0,0 +1,28 @@ +//! The `svh-a-*.rs` files are all deviations from the base file +//! svh-a-base.rs with some difference (usually in `fn foo`) that +//! should not affect the strict version hash (SVH) computation +//! (#14132). + +#![crate_name = "a"] + +macro_rules! three { + () => { 3 } +} + +pub trait U {} +pub trait V {} +impl U for () {} +impl V for () {} + +static A_CONSTANT : isize = 2; + +#[cfg(some_flag)] +pub fn foo(_: isize) -> isize { + 3 +} + +#[cfg(not(some_flag))] +pub fn an_unused_name() -> isize { + 4 +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-trait-bound.rs b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-trait-bound.rs new file mode 100644 index 000000000000..fa585668895a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-trait-bound.rs @@ -0,0 +1,26 @@ +//! The `svh-a-*.rs` files are all deviations from the base file +//! svh-a-base.rs with some difference (usually in `fn foo`) that +//! should not affect the strict version hash (SVH) computation +//! (#14132). + +#![crate_name = "a"] + +macro_rules! three { + () => { 3 } +} + +pub trait U {} +pub trait V {} +impl U for () {} +impl V for () {} + +static A_CONSTANT : isize = 2; + +pub fn foo(_: isize) -> isize { + 3 +} + +pub fn an_unused_name() -> isize { + 4 +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-type-arg.rs b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-type-arg.rs new file mode 100644 index 000000000000..23678426c5f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-type-arg.rs @@ -0,0 +1,26 @@ +//! The `svh-a-*.rs` files are all deviations from the base file +//! svh-a-base.rs with some difference (usually in `fn foo`) that +//! should not affect the strict version hash (SVH) computation +//! (#14132). + +#![crate_name = "a"] + +macro_rules! three { + () => { 3 } +} + +pub trait U {} +pub trait V {} +impl U for () {} +impl V for () {} + +static A_CONSTANT : isize = 2; + +pub fn foo(_: i32) -> isize { + 3 +} + +pub fn an_unused_name() -> isize { + 4 +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-type-ret.rs b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-type-ret.rs new file mode 100644 index 000000000000..f85731cc3727 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-type-ret.rs @@ -0,0 +1,26 @@ +//! The `svh-a-*.rs` files are all deviations from the base file +//! svh-a-base.rs with some difference (usually in `fn foo`) that +//! should not affect the strict version hash (SVH) computation +//! (#14132). + +#![crate_name = "a"] + +macro_rules! three { + () => { 3 } +} + +pub trait U {} +pub trait V {} +impl U for () {} +impl V for () {} + +static A_CONSTANT : isize = 2; + +pub fn foo(_: isize) -> i64 { + 3 +} + +pub fn an_unused_name() -> i32 { + 4 +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-type-static.rs b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-type-static.rs new file mode 100644 index 000000000000..83b51c5790f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-a-change-type-static.rs @@ -0,0 +1,26 @@ +//! The `svh-a-*.rs` files are all deviations from the base file +//! svh-a-base.rs with some difference (usually in `fn foo`) that +//! should not affect the strict version hash (SVH) computation +//! (#14132). + +#![crate_name = "a"] + +macro_rules! three { + () => { 3 } +} + +pub trait U {} +pub trait V {} +impl U for () {} +impl V for () {} + +static A_CONSTANT : i32 = 2; + +pub fn foo(_: isize) -> isize { + 3 +} + +pub fn an_unused_name() -> isize { + 4 +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-b.rs b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-b.rs new file mode 100644 index 000000000000..f3d7138bbabe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-b.rs @@ -0,0 +1,14 @@ +//! This is a client of the `a` crate defined in `svn-a-base.rs`. The +//! rpass and cfail tests (such as `run-pass/svh-add-comment.rs`) use +//! it by swapping in a different object code library crate built from +//! some variant of `svn-a-base.rs`, and then we are checking if the +//! compiler properly ignores or accepts the change, based on whether +//! the change could affect the downstream crate content or not +//! (#14132). + +#![crate_name = "b"] + +extern crate a; + +pub fn foo() { assert_eq!(a::foo::<()>(0), 3); } + diff --git a/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-uta-base.rs b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-uta-base.rs new file mode 100644 index 000000000000..68ebb4523e07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-uta-base.rs @@ -0,0 +1,23 @@ +//! "compile-fail/svh-uta-trait.rs" is checking that we detect a +//! change from `use foo::TraitB` to use `foo::TraitB` in the hash +//! (SVH) computation (#14132), since that will affect method +//! resolution. +//! +//! This is the upstream crate. + +#![crate_name = "uta"] + +mod traits { + pub trait TraitA { fn val(&self) -> isize { 2 } } + pub trait TraitB { fn val(&self) -> isize { 3 } } +} + +impl traits::TraitA for () {} +impl traits::TraitB for () {} + +pub fn foo(_: isize) -> isize { + use traits::TraitA; + let v = (); + v.val() +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-uta-change-use-trait.rs b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-uta-change-use-trait.rs new file mode 100644 index 000000000000..10120bdd3b52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-uta-change-use-trait.rs @@ -0,0 +1,23 @@ +//! "compile-fail/svh-uta-trait.rs" is checking that we detect a +//! change from `use foo::TraitB` to use `foo::TraitB` in the hash +//! (SVH) computation (#14132), since that will affect method +//! resolution. +//! +//! This is the upstream crate. + +#![crate_name = "uta"] + +mod traits { + pub trait TraitA { fn val(&self) -> isize { 2 } } + pub trait TraitB { fn val(&self) -> isize { 3 } } +} + +impl traits::TraitA for () {} +impl traits::TraitB for () {} + +pub fn foo(_: isize) -> isize { + use traits::TraitB; + let v = (); + v.val() +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-utb.rs b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-utb.rs new file mode 100644 index 000000000000..48b527cd016b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/auxiliary/svh-utb.rs @@ -0,0 +1,13 @@ +//! "compile-fail/svh-uta-trait.rs" is checking that we detect a +//! change from `use foo::TraitB` to use `foo::TraitB` in the hash +//! (SVH) computation (#14132), since that will affect method +//! resolution. +//! +//! This is the downstream crate. + +#![crate_name = "utb"] + +extern crate uta; + +pub fn foo() { assert_eq!(uta::foo::<()>(0), 3); } + diff --git a/gcc/testsuite/rust/rustc/ui/svh/svh-change-lit.rs b/gcc/testsuite/rust/rustc/ui/svh/svh-change-lit.rs new file mode 100644 index 000000000000..5f01e08dfe09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/svh-change-lit.rs @@ -0,0 +1,15 @@ +// ignore-msvc FIXME #31306 + +// note that these aux-build directives must be in this order +// aux-build:svh-a-base.rs +// aux-build:svh-b.rs +// aux-build:svh-a-change-lit.rs +// normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" + +extern crate a; +extern crate b; // { dg-error ".E0460." "" { target *-*-* } } + +fn main() { + b::foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/svh-change-significant-cfg.rs b/gcc/testsuite/rust/rustc/ui/svh/svh-change-significant-cfg.rs new file mode 100644 index 000000000000..006f39aedf3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/svh-change-significant-cfg.rs @@ -0,0 +1,15 @@ +// ignore-msvc FIXME #31306 + +// note that these aux-build directives must be in this order +// aux-build:svh-a-base.rs +// aux-build:svh-b.rs +// aux-build:svh-a-change-significant-cfg.rs +// normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" + +extern crate a; +extern crate b; // { dg-error ".E0460." "" { target *-*-* } } + +fn main() { + b::foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/svh-change-trait-bound.rs b/gcc/testsuite/rust/rustc/ui/svh/svh-change-trait-bound.rs new file mode 100644 index 000000000000..477e99b5f321 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/svh-change-trait-bound.rs @@ -0,0 +1,15 @@ +// ignore-msvc FIXME #31306 + +// note that these aux-build directives must be in this order +// aux-build:svh-a-base.rs +// aux-build:svh-b.rs +// aux-build:svh-a-change-trait-bound.rs +// normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" + +extern crate a; +extern crate b; // { dg-error ".E0460." "" { target *-*-* } } + +fn main() { + b::foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/svh-change-type-arg.rs b/gcc/testsuite/rust/rustc/ui/svh/svh-change-type-arg.rs new file mode 100644 index 000000000000..304b15698c10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/svh-change-type-arg.rs @@ -0,0 +1,15 @@ +// ignore-msvc FIXME #31306 + +// note that these aux-build directives must be in this order +// aux-build:svh-a-base.rs +// aux-build:svh-b.rs +// aux-build:svh-a-change-type-arg.rs +// normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" + +extern crate a; +extern crate b; // { dg-error ".E0460." "" { target *-*-* } } + +fn main() { + b::foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/svh-change-type-ret.rs b/gcc/testsuite/rust/rustc/ui/svh/svh-change-type-ret.rs new file mode 100644 index 000000000000..1c65aba52faf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/svh-change-type-ret.rs @@ -0,0 +1,15 @@ +// ignore-msvc FIXME #31306 + +// note that these aux-build directives must be in this order +// aux-build:svh-a-base.rs +// aux-build:svh-b.rs +// aux-build:svh-a-change-type-ret.rs +// normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" + +extern crate a; +extern crate b; // { dg-error ".E0460." "" { target *-*-* } } + +fn main() { + b::foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/svh-change-type-static.rs b/gcc/testsuite/rust/rustc/ui/svh/svh-change-type-static.rs new file mode 100644 index 000000000000..1fce1c31cd72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/svh-change-type-static.rs @@ -0,0 +1,15 @@ +// ignore-msvc FIXME #31306 + +// note that these aux-build directives must be in this order +// aux-build:svh-a-base.rs +// aux-build:svh-b.rs +// aux-build:svh-a-change-type-static.rs +// normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" + +extern crate a; +extern crate b; // { dg-error ".E0460." "" { target *-*-* } } + +fn main() { + b::foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/svh/svh-use-trait.rs b/gcc/testsuite/rust/rustc/ui/svh/svh-use-trait.rs new file mode 100644 index 000000000000..2d320f500c9e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/svh/svh-use-trait.rs @@ -0,0 +1,20 @@ +// ignore-msvc FIXME #31306 + +// note that these aux-build directives must be in this order +// aux-build:svh-uta-base.rs +// aux-build:svh-utb.rs +// aux-build:svh-uta-change-use-trait.rs +// normalize-stderr-test: "(crate `(\w+)`:) .*" -> "$1 $$PATH_$2" + +//! "compile-fail/svh-uta-trait.rs" is checking that we detect a +//! change from `use foo::TraitB` to use `foo::TraitB` in the hash +//! (SVH) computation (#14132), since that will affect method +//! resolution. + +extern crate uta; +extern crate utb; // { dg-error ".E0460." "" { target *-*-* } } + +fn main() { + utb::foo() +} + diff --git a/gcc/testsuite/rust/rustc/ui/swap-1.rs b/gcc/testsuite/rust/rustc/ui/swap-1.rs new file mode 100644 index 000000000000..187de3c4530c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/swap-1.rs @@ -0,0 +1,11 @@ +// run-pass + +use std::mem::swap; + +pub fn main() { + let mut x = 3; let mut y = 7; + swap(&mut x, &mut y); + assert_eq!(x, 7); + assert_eq!(y, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/swap-overlapping.rs b/gcc/testsuite/rust/rustc/ui/swap-overlapping.rs new file mode 100644 index 000000000000..8a34d8211e97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/swap-overlapping.rs @@ -0,0 +1,45 @@ +// run-pass + +#![allow(dead_code)] +// Issue #5041 - avoid overlapping memcpy when src and dest of a swap are the same + +// pretty-expanded FIXME #23616 + +use std::ptr; + +pub fn main() { + let mut test = TestDescAndFn { + desc: TestDesc { + name: TestName::DynTestName("test".to_string()), + should_fail: false + }, + testfn: TestFn::DynTestFn(22), + }; + do_swap(&mut test); +} + +fn do_swap(test: &mut TestDescAndFn) { + unsafe { + ptr::swap(test, test); + } +} + +pub enum TestName { + DynTestName(String) +} + +pub enum TestFn { + DynTestFn(isize), + DynBenchFn(isize), +} + +pub struct TestDesc { + name: TestName, + should_fail: bool +} + +pub struct TestDescAndFn { + desc: TestDesc, + testfn: TestFn, +} + diff --git a/gcc/testsuite/rust/rustc/ui/switched-expectations.rs b/gcc/testsuite/rust/rustc/ui/switched-expectations.rs new file mode 100644 index 000000000000..77a9ba392a51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/switched-expectations.rs @@ -0,0 +1,5 @@ +fn main() { + let var = 10i32; + let ref string: String = var; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/symbol-names/basic.rs b/gcc/testsuite/rust/rustc/ui/symbol-names/basic.rs new file mode 100644 index 000000000000..35fb513e3f22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/symbol-names/basic.rs @@ -0,0 +1,20 @@ +// build-fail +// revisions: legacy v0 +//[legacy]compile-flags: -Z symbol-mangling-version=legacy + //[v0]compile-flags: -Z symbol-mangling-version=v0 + +#![feature(rustc_attrs)] + +#[rustc_symbol_name] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +#[rustc_def_path] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/symbol-names/const-generics-demangling.rs b/gcc/testsuite/rust/rustc/ui/symbol-names/const-generics-demangling.rs new file mode 100644 index 000000000000..1a4b7f5c8129 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/symbol-names/const-generics-demangling.rs @@ -0,0 +1,39 @@ +// build-fail +// compile-flags: -Z symbol-mangling-version=v0 + +#![feature(min_const_generics, rustc_attrs)] + +pub struct Unsigned; + +#[rustc_symbol_name] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +impl Unsigned<11> {} + +pub struct Signed; + +#[rustc_symbol_name] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +impl Signed<-152> {} + +pub struct Bool; + +#[rustc_symbol_name] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +impl Bool {} + +pub struct Char; + +#[rustc_symbol_name] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +impl Char<'∂'> {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/symbol-names/const-generics.rs b/gcc/testsuite/rust/rustc/ui/symbol-names/const-generics.rs new file mode 100644 index 000000000000..0ae523984180 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/symbol-names/const-generics.rs @@ -0,0 +1,88 @@ +// check-pass +// revisions: legacy v0 +//[legacy]compile-flags: -Z symbol-mangling-version=legacy --crate-type=lib + //[v0]compile-flags: -Z symbol-mangling-version=v0 --crate-type=lib + + #![feature(min_const_generics)] + + // `char` + pub struct Char; + + impl Char<'A'> { + pub fn foo() {} + } + + impl Char { + pub fn bar() {} + } + + // `i8` + pub struct I8; + + impl I8<{std::i8::MIN}> { + pub fn foo() {} + } + + impl I8<{std::i8::MAX}> { + pub fn foo() {} + } + + impl I8 { + pub fn bar() {} + } + + // `i16` + pub struct I16; + + impl I16<{std::i16::MIN}> { + pub fn foo() {} + } + + impl I16 { + pub fn bar() {} + } + + // `i32` + pub struct I32; + + impl I32<{std::i32::MIN}> { + pub fn foo() {} + } + + impl I32 { + pub fn bar() {} + } + + // `i64` + pub struct I64; + + impl I64<{std::i64::MIN}> { + pub fn foo() {} + } + + impl I64 { + pub fn bar() {} + } + + // `i128` + pub struct I128; + + impl I128<{std::i128::MIN}> { + pub fn foo() {} + } + + impl I128 { + pub fn bar() {} + } + + // `isize` + pub struct ISize; + + impl ISize<3> { + pub fn foo() {} + } + + impl ISize { + pub fn bar() {} + } + diff --git a/gcc/testsuite/rust/rustc/ui/symbol-names/impl1.rs b/gcc/testsuite/rust/rustc/ui/symbol-names/impl1.rs new file mode 100644 index 000000000000..45625fbd45d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/symbol-names/impl1.rs @@ -0,0 +1,78 @@ +// build-fail +// ignore-tidy-linelength +// revisions: legacy v0 +//[legacy]compile-flags: -Z symbol-mangling-version=legacy + //[v0]compile-flags: -Z symbol-mangling-version=v0 +//[legacy]normalize-stderr-32bit: "hee444285569b39c2" -> "SYMBOL_HASH" +//[legacy]normalize-stderr-64bit: "h310ea0259fc3d32d" -> "SYMBOL_HASH" + +#![feature(optin_builtin_traits, rustc_attrs)] +#![allow(dead_code)] + +mod foo { + pub struct Foo { x: u32 } + + impl Foo { + #[rustc_symbol_name] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + #[rustc_def_path] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn bar() { } + } +} + +mod bar { + use foo::Foo; + + impl Foo { + #[rustc_symbol_name] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + #[rustc_def_path] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn baz() { } + } +} + +trait Foo { + type Assoc; +} + +auto trait AutoTrait {} + +fn main() { + // Test closure mangling, and disambiguators. + || {}; + || { + trait Bar { + fn method(&self) {} + } + + // Test type mangling, by putting them in an `impl` header. + impl Bar for [&'_ (dyn Foo + AutoTrait); 3] { + #[rustc_symbol_name] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + #[rustc_def_path] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + fn method(&self) {} + } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/symbol-names/impl2.rs b/gcc/testsuite/rust/rustc/ui/symbol-names/impl2.rs new file mode 100644 index 000000000000..02b31b433281 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/symbol-names/impl2.rs @@ -0,0 +1,17 @@ +// build-fail + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +trait Foo { + fn baz(); +} + +impl Foo for [u8; 1 + 2] { + #[rustc_def_path] // { dg-error "" "" { target *-*-* } } + fn baz() { } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/symbol-names/issue-60925.rs b/gcc/testsuite/rust/rustc/ui/symbol-names/issue-60925.rs new file mode 100644 index 000000000000..2889365974e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/symbol-names/issue-60925.rs @@ -0,0 +1,51 @@ +// build-fail +// ignore-tidy-linelength +// revisions: legacy v0 +//[legacy]compile-flags: -Z symbol-mangling-version=legacy + //[v0]compile-flags: -Z symbol-mangling-version=v0 + +#![feature(rustc_attrs)] + +// This test is the same code as in ui/issue-53912.rs but this test checks that the symbol mangling +// fix produces the correct result, whereas that test just checks that the reproduction compiles +// successfully and doesn't crash LLVM + +fn dummy() {} + +mod llvm { + pub(crate) struct Foo; +} +mod foo { + pub(crate) struct Foo(T); + + impl Foo<::llvm::Foo> { + #[rustc_symbol_name] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + pub(crate) fn foo() { + for _ in 0..0 { + for _ in &[::dummy()] { + ::dummy(); + ::dummy(); + ::dummy(); + } + } + } + } + + pub(crate) fn foo() { + Foo::foo(); + Foo::foo(); + } +} + +pub fn foo() { + foo::foo(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/symbol-names/issue-75326.rs b/gcc/testsuite/rust/rustc/ui/symbol-names/issue-75326.rs new file mode 100644 index 000000000000..1c9ecbdb6d73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/symbol-names/issue-75326.rs @@ -0,0 +1,59 @@ +// build-fail +// ignore-tidy-linelength +// revisions: legacy v0 +//[legacy]compile-flags: -Z symbol-mangling-version=legacy +//[v0]compile-flags: -Z symbol-mangling-version=v0 +//[legacy]normalize-stderr-32bit: "h[\d\w]+" -> "SYMBOL_HASH" +//[legacy]normalize-stderr-64bit: "h[\d\w]+" -> "SYMBOL_HASH" + +#![feature(rustc_attrs)] + +pub(crate) struct Foo(I, E); + +pub trait Iterator2 { + type Item; + + fn next(&mut self) -> Option; + + fn find

(&mut self, predicate: P) -> Option + where + Self: Sized, + P: FnMut(&Self::Item) -> bool, + { + unimplemented!() + } +} + +struct Bar; + +impl Iterator2 for Bar { + type Item = (u32, u16); + + fn next(&mut self) -> Option { + unimplemented!() + } +} + +impl Iterator2 for Foo +where + I: Iterator2, +{ + type Item = T; + + #[rustc_symbol_name] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } + fn next(&mut self) -> Option { + self.find(|_| true) + } +} + +fn main() { + let mut a = Foo(Bar, 1u16); + let _ = a.next(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/symbol-names/issue-76365.rs b/gcc/testsuite/rust/rustc/ui/symbol-names/issue-76365.rs new file mode 100644 index 000000000000..3bdf3a89afcf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/symbol-names/issue-76365.rs @@ -0,0 +1,19 @@ +// check-pass +// revisions: legacy v0 +//[legacy]compile-flags: -Z symbol-mangling-version=legacy --crate-type=lib + //[v0]compile-flags: -Z symbol-mangling-version=v0 --crate-type=lib + +#![feature(min_const_generics)] + +pub struct Bar; + +impl Bar { + pub fn foo() {} +} + +impl Bar { + pub fn bar() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/syntax-extension-minor.rs b/gcc/testsuite/rust/rustc/ui/syntax-extension-minor.rs new file mode 100644 index 000000000000..6c19f013f411 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/syntax-extension-minor.rs @@ -0,0 +1,15 @@ +// run-pass + +#![feature(concat_idents)] + +pub fn main() { + struct Foo; + let _: concat_idents!(F, oo) = Foo; // Test that `concat_idents!` can be used in type positions + + let asdf_fdsa = "<.<".to_string(); + // concat_idents should have call-site hygiene. + assert!(concat_idents!(asd, f_f, dsa) == "<.<".to_string()); + + assert_eq!(stringify!(use_mention_distinction), "use_mention_distinction"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/syntax-trait-polarity-feature-gate.rs b/gcc/testsuite/rust/rustc/ui/syntax-trait-polarity-feature-gate.rs new file mode 100644 index 000000000000..702f64d8ab31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/syntax-trait-polarity-feature-gate.rs @@ -0,0 +1,11 @@ +use std::marker::Send; + +struct TestType; + +trait TestTrait {} + +impl !Send for TestType {} +// { dg-error ".E0658." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/syntax-trait-polarity.rs b/gcc/testsuite/rust/rustc/ui/syntax-trait-polarity.rs new file mode 100644 index 000000000000..297fb3067af8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/syntax-trait-polarity.rs @@ -0,0 +1,26 @@ +#![feature(negative_impls)] + +use std::marker::Send; + +struct TestType; + +impl !TestType {} +// { dg-error "" "" { target *-*-* } .-1 } + +trait TestTrait {} + +unsafe impl !Send for TestType {} +// { dg-error ".E0198." "" { target *-*-* } .-1 } +impl !TestTrait for TestType {} + +struct TestType2(T); + +impl !TestType2 {} +// { dg-error "" "" { target *-*-* } .-1 } + +unsafe impl !Send for TestType2 {} +// { dg-error ".E0198." "" { target *-*-* } .-1 } +impl !TestTrait for TestType2 {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/synthetic-param.rs b/gcc/testsuite/rust/rustc/ui/synthetic-param.rs new file mode 100644 index 000000000000..a515113d5a32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/synthetic-param.rs @@ -0,0 +1,29 @@ +#![feature(rustc_attrs)] + +fn func<#[rustc_synthetic] T>(_: T) {} + +struct Foo; + +impl Foo { + pub fn func<#[rustc_synthetic] T>(_: T) {} +} + +struct Bar { + t: S +} + +impl Bar { + pub fn func<#[rustc_synthetic] T>(_: T) {} +} + +fn main() { + func::(42); // { dg-error ".E0632." "" { target *-*-* } } + func(42); // Ok + + Foo::func::(42); // { dg-error ".E0632." "" { target *-*-* } } + Foo::func(42); // Ok + + Bar::::func::(42); // { dg-error ".E0632." "" { target *-*-* } } + Bar::::func(42); // Ok +} + diff --git a/gcc/testsuite/rust/rustc/ui/tag-that-dare-not-speak-its-name.rs b/gcc/testsuite/rust/rustc/ui/tag-that-dare-not-speak-its-name.rs new file mode 100644 index 000000000000..f8d47eabdaf7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tag-that-dare-not-speak-its-name.rs @@ -0,0 +1,17 @@ +// Issue #876 + +use std::vec::Vec; + +fn last(v: Vec<&T> ) -> std::option::Option { + ::std::panic!(); +} + +fn main() { + let y; + let x : char = last(y); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/tag-type-args.rs b/gcc/testsuite/rust/rustc/ui/tag-type-args.rs new file mode 100644 index 000000000000..3b8b3e91f7bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tag-type-args.rs @@ -0,0 +1,6 @@ +enum Quux { Bar } + +fn foo(c: Quux) { assert!((false)); } // { dg-error ".E0107." "" { target *-*-* } } + +fn main() { panic!(); } + diff --git a/gcc/testsuite/rust/rustc/ui/tag-variant-cast-non-nullary.rs b/gcc/testsuite/rust/rustc/ui/tag-variant-cast-non-nullary.rs new file mode 100644 index 000000000000..36cece25e681 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tag-variant-cast-non-nullary.rs @@ -0,0 +1,21 @@ +// run-rustfix +#![allow(dead_code, unused_variables)] +enum NonNullary { + Nullary, + Other(isize), +} + +impl From for isize { + fn from(val: NonNullary) -> isize { + match val { + NonNullary::Nullary => 0, + NonNullary::Other(i) => i, + } + } +} + +fn main() { + let v = NonNullary::Nullary; + let val = v as isize; // { dg-error ".E0605." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/tag-variant-disr-dup.rs b/gcc/testsuite/rust/rustc/ui/tag-variant-disr-dup.rs new file mode 100644 index 000000000000..0a75868551ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tag-variant-disr-dup.rs @@ -0,0 +1,12 @@ +// Black and White have the same discriminator value ... + +enum Color { + Red = 0xff0000, + Green = 0x00ff00, + Blue = 0x0000ff, + Black = 0x000000, + White = 0x000000, // { dg-error ".E0081." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/tail-call-arg-leak.rs b/gcc/testsuite/rust/rustc/ui/tail-call-arg-leak.rs new file mode 100644 index 000000000000..e4d5b66aad54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tail-call-arg-leak.rs @@ -0,0 +1,10 @@ +// run-pass +// use of tail calls causes arg slot leaks, issue #160. +// pretty-expanded FIXME #23616 + +fn inner(dummy: String, b: bool) { if b { return inner(dummy, false); } } + +pub fn main() { + inner("hi".to_string(), true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/tail-cps.rs b/gcc/testsuite/rust/rustc/ui/tail-cps.rs new file mode 100644 index 000000000000..1ed4bad57bf2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tail-cps.rs @@ -0,0 +1,18 @@ +// run-pass + +fn checktrue(rs: bool) -> bool { assert!((rs)); return true; } + +pub fn main() { let k = checktrue; evenk(42, k); oddk(45, k); } + +fn evenk(n: isize, k: fn(bool) -> bool) -> bool { + println!("evenk"); + println!("{}", n); + if n == 0 { return k(true); } else { return oddk(n - 1, k); } +} + +fn oddk(n: isize, k: fn(bool) -> bool) -> bool { + println!("oddk"); + println!("{}", n); + if n == 0 { return k(false); } else { return evenk(n - 1, k); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/tail-direct.rs b/gcc/testsuite/rust/rustc/ui/tail-direct.rs new file mode 100644 index 000000000000..42bceff23393 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tail-direct.rs @@ -0,0 +1,8 @@ +// run-pass + +pub fn main() { assert!((even(42))); assert!((odd(45))); } + +fn even(n: isize) -> bool { if n == 0 { return true; } else { return odd(n - 1); } } + +fn odd(n: isize) -> bool { if n == 0 { return false; } else { return even(n - 1); } } + diff --git a/gcc/testsuite/rust/rustc/ui/tail-typeck.rs b/gcc/testsuite/rust/rustc/ui/tail-typeck.rs new file mode 100644 index 000000000000..609a5d32673a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tail-typeck.rs @@ -0,0 +1,8 @@ +// error-pattern: mismatched types + +fn f() -> isize { return g(); } + +fn g() -> usize { return 0; } + +fn main() { let y = f(); } + diff --git a/gcc/testsuite/rust/rustc/ui/target-feature/gate.rs b/gcc/testsuite/rust/rustc/ui/target-feature/gate.rs new file mode 100644 index 000000000000..65ac2ed848f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/target-feature/gate.rs @@ -0,0 +1,36 @@ +// ignore-arm +// ignore-aarch64 +// ignore-wasm +// ignore-emscripten +// ignore-mips +// ignore-mips64 +// ignore-powerpc +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-riscv64 +// ignore-sparc +// ignore-sparc64 +// ignore-s390x +// gate-test-sse4a_target_feature +// gate-test-powerpc_target_feature +// gate-test-avx512_target_feature +// gate-test-tbm_target_feature +// gate-test-arm_target_feature +// gate-test-aarch64_target_feature +// gate-test-hexagon_target_feature +// gate-test-mips_target_feature +// gate-test-wasm_target_feature +// gate-test-adx_target_feature +// gate-test-cmpxchg16b_target_feature +// gate-test-movbe_target_feature +// gate-test-rtm_target_feature +// gate-test-f16c_target_feature +// gate-test-riscv_target_feature +// gate-test-ermsb_target_feature + +#[target_feature(enable = "avx512bw")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +unsafe fn foo() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/target-feature/invalid-attribute.rs b/gcc/testsuite/rust/rustc/ui/target-feature/invalid-attribute.rs new file mode 100644 index 000000000000..a78a5e73c6a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/target-feature/invalid-attribute.rs @@ -0,0 +1,99 @@ +// ignore-arm +// ignore-aarch64 +// ignore-wasm +// ignore-emscripten +// ignore-mips +// ignore-mips64 +// ignore-powerpc +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-riscv64 +// ignore-s390x +// ignore-sparc +// ignore-sparc64 + +#![feature(target_feature)] +#![warn(unused_attributes)] + +#[target_feature = "+sse2"] +// { dg-error "" "" { target *-*-* } .-1 } +#[target_feature(enable = "foo")] +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } +#[target_feature(bar)] +// { dg-error "" "" { target *-*-* } .-1 } +#[target_feature(disable = "baz")] +// { dg-error "" "" { target *-*-* } .-1 } +unsafe fn foo() {} + +#[target_feature(enable = "sse2")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-note ".E0658." "" { target *-*-* } .-2 } +fn bar() {} +// { dg-note "" "" { target *-*-* } .-1 } + +#[target_feature(enable = "sse2")] +// { dg-error "" "" { target *-*-* } .-1 } +mod another {} +// { dg-note "" "" { target *-*-* } .-1 } + +#[target_feature(enable = "sse2")] +// { dg-error "" "" { target *-*-* } .-1 } +const FOO: usize = 7; +// { dg-note "" "" { target *-*-* } .-1 } + +#[target_feature(enable = "sse2")] +// { dg-error "" "" { target *-*-* } .-1 } +struct Foo; +// { dg-note "" "" { target *-*-* } .-1 } + +#[target_feature(enable = "sse2")] +// { dg-error "" "" { target *-*-* } .-1 } +enum Bar {} +// { dg-note "" "" { target *-*-* } .-1 } + +#[target_feature(enable = "sse2")] +// { dg-error "" "" { target *-*-* } .-1 } +union Qux { +// { dg-note "" "" { target *-*-* } .-1 } + f1: u16, + f2: u16, +} + +#[target_feature(enable = "sse2")] +// { dg-error "" "" { target *-*-* } .-1 } +trait Baz {} +// { dg-note "" "" { target *-*-* } .-1 } + +#[inline(always)] +// { dg-error "" "" { target *-*-* } .-1 } +#[target_feature(enable = "sse2")] +unsafe fn test() {} + +trait Quux { + fn foo(); +} + +impl Quux for Foo { + #[target_feature(enable = "sse2")] +// { dg-error ".E0658." "" { target *-*-* } .-1 } +// { dg-note ".E0658." "" { target *-*-* } .-2 } + fn foo() {} +// { dg-note "" "" { target *-*-* } .-1 } +} + +fn main() { + #[target_feature(enable = "sse2")] +// { dg-error "" "" { target *-*-* } .-1 } + unsafe { + foo(); + bar(); + } +// { dg-note "" "" { target *-*-* } .-4 } + + #[target_feature(enable = "sse2")] +// { dg-error "" "" { target *-*-* } .-1 } + || {}; +// { dg-note "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/tcp-stress.rs b/gcc/testsuite/rust/rustc/ui/tcp-stress.rs new file mode 100644 index 000000000000..b0b8a5a810a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tcp-stress.rs @@ -0,0 +1,66 @@ +// run-pass +// ignore-android needs extra network permissions +// ignore-cloudabi no global network namespace access +// ignore-emscripten no threads or sockets support +// ignore-netbsd system ulimit (Too many open files) +// ignore-openbsd system ulimit (Too many open files) + +use std::io::prelude::*; +use std::net::{TcpListener, TcpStream}; +use std::process; +use std::sync::mpsc::channel; +use std::time::Duration; +use std::thread::{self, Builder}; + +const TARGET_CNT: usize = 200; + +fn main() { + // This test has a chance to time out, try to not let it time out + thread::spawn(move|| -> () { + thread::sleep(Duration::from_secs(30)); + process::exit(1); + }); + + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = listener.local_addr().unwrap(); + thread::spawn(move || -> () { + loop { + let mut stream = match listener.accept() { + Ok(stream) => stream.0, + Err(_) => continue, + }; + let _ = stream.read(&mut [0]); + let _ = stream.write(&[2]); + } + }); + + let (tx, rx) = channel(); + + let mut spawned_cnt = 0; + for _ in 0..TARGET_CNT { + let tx = tx.clone(); + let res = Builder::new().stack_size(64 * 1024).spawn(move|| { + match TcpStream::connect(addr) { + Ok(mut stream) => { + let _ = stream.write(&[1]); + let _ = stream.read(&mut [0]); + }, + Err(..) => {} + } + tx.send(()).unwrap(); + }); + if let Ok(_) = res { + spawned_cnt += 1; + }; + } + + // Wait for all clients to exit, but don't wait for the server to exit. The + // server just runs infinitely. + drop(tx); + for _ in 0..spawned_cnt { + rx.recv().unwrap(); + } + assert_eq!(spawned_cnt, TARGET_CNT); + process::exit(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/terminal-width/flag-human.rs b/gcc/testsuite/rust/rustc/ui/terminal-width/flag-human.rs new file mode 100644 index 000000000000..76921cc85b0b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/terminal-width/flag-human.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z terminal-width=20 + +// This test checks that `-Z terminal-width` effects the human error output by restricting it to an +// arbitrarily low value so that the effect is visible. + +fn main() { + let _: () = 42; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/terminal-width/flag-json.rs b/gcc/testsuite/rust/rustc/ui/terminal-width/flag-json.rs new file mode 100644 index 000000000000..63d6b7a67f43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/terminal-width/flag-json.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z terminal-width=20 --error-format=json + +// This test checks that `-Z terminal-width` effects the JSON error output by restricting it to an +// arbitrarily low value so that the effect is visible. + +fn main() { + let _: () = 42; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/terminal-width/non-1-width-unicode-multiline-label.rs b/gcc/testsuite/rust/rustc/ui/terminal-width/non-1-width-unicode-multiline-label.rs new file mode 100644 index 000000000000..df8def5fb835 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/terminal-width/non-1-width-unicode-multiline-label.rs @@ -0,0 +1,8 @@ +// ignore-tidy-linelength + +fn main() { + let unicode_is_fun = "؁‱ஹ௸௵꧄.ဪ꧅⸻𒈙𒐫﷽𒌄𒈟𒍼𒁎𒀱𒌧𒅃 𒈓𒍙𒊎𒄡𒅌𒁏𒀰𒐪𒐩𒈙𒐫𪚥"; + let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; +// { dg-error ".E0369." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/terminal-width/non-whitespace-trimming-2.rs b/gcc/testsuite/rust/rustc/ui/terminal-width/non-whitespace-trimming-2.rs new file mode 100644 index 000000000000..5839a4058b12 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/terminal-width/non-whitespace-trimming-2.rs @@ -0,0 +1,7 @@ +// ignore-tidy-linelength + +fn main() { + let _: usize = 0; let _: usize = 1; let _: usize = 2; let _: usize = 3; let _: usize = 4; let _: usize = 5; let _: usize = 6; let _: usize = 7; let _: usize = 8; let _: usize = 9; let _: usize = 10; let _: usize = 11; let _: usize = 12; let _: usize = 13; let _: usize = 14; let _: usize = 15; let _: () = 42; let _: usize = 0; let _: usize = 1; let _: usize = 2; let _: usize = 3; let _: usize = 4; let _: usize = 5; let _: usize = 6; let _: usize = 7; let _: usize = 8; let _: usize = 9; let _: usize = 10; let _: usize = 11; let _: usize = 12; let _: usize = 13; let _: usize = 14; let _: usize = 15; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/terminal-width/non-whitespace-trimming-unicode.rs b/gcc/testsuite/rust/rustc/ui/terminal-width/non-whitespace-trimming-unicode.rs new file mode 100644 index 000000000000..e979fe509669 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/terminal-width/non-whitespace-trimming-unicode.rs @@ -0,0 +1,7 @@ +// ignore-tidy-linelength + +fn main() { + let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓ ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4🦀🦀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42; let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓ ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4🦀🦀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/terminal-width/non-whitespace-trimming.rs b/gcc/testsuite/rust/rustc/ui/terminal-width/non-whitespace-trimming.rs new file mode 100644 index 000000000000..70ffdc178398 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/terminal-width/non-whitespace-trimming.rs @@ -0,0 +1,7 @@ +// ignore-tidy-linelength + +fn main() { + let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/terminal-width/whitespace-trimming-2.rs b/gcc/testsuite/rust/rustc/ui/terminal-width/whitespace-trimming-2.rs new file mode 100644 index 000000000000..b2a1ad4ea6c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/terminal-width/whitespace-trimming-2.rs @@ -0,0 +1,9 @@ +// ignore-tidy-linelength + +fn foo() -> usize { + () +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/terminal-width/whitespace-trimming.rs b/gcc/testsuite/rust/rustc/ui/terminal-width/whitespace-trimming.rs new file mode 100644 index 000000000000..f0719c3a1785 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/terminal-width/whitespace-trimming.rs @@ -0,0 +1,7 @@ +// ignore-tidy-linelength + +fn main() { + let _: () = 42; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/terminate-in-initializer.rs b/gcc/testsuite/rust/rustc/ui/terminate-in-initializer.rs new file mode 100644 index 000000000000..58f800bb474d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/terminate-in-initializer.rs @@ -0,0 +1,34 @@ +// run-pass +// ignore-emscripten no threads support + +// Issue #787 +// Don't try to clean up uninitialized locals + + +use std::thread; + +fn test_break() { loop { let _x: Box = break; } } + +fn test_cont() { let mut i = 0; while i < 1 { i += 1; let _x: Box = continue; } } + +fn test_ret() { let _x: Box = return; } + +fn test_panic() { + fn f() { let _x: Box = panic!(); } + thread::spawn(move|| f() ).join().unwrap_err(); +} + +fn test_panic_indirect() { + fn f() -> ! { panic!(); } + fn g() { let _x: Box = f(); } + thread::spawn(move|| g() ).join().unwrap_err(); +} + +pub fn main() { + test_break(); + test_cont(); + test_ret(); + test_panic(); + test_panic_indirect(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/terr-in-field.rs b/gcc/testsuite/rust/rustc/ui/terr-in-field.rs new file mode 100644 index 000000000000..67085608f17c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/terr-in-field.rs @@ -0,0 +1,18 @@ +struct Foo { + a: isize, + b: isize, +} + +struct Bar { + a: isize, + b: usize, +} + +fn want_foo(f: Foo) {} +fn have_bar(b: Bar) { + want_foo(b); // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/terr-sorts.rs b/gcc/testsuite/rust/rustc/ui/terr-sorts.rs new file mode 100644 index 000000000000..d5b89fb6b6c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/terr-sorts.rs @@ -0,0 +1,16 @@ +struct Foo { + a: isize, + b: isize, +} + +type Bar = Box; + +fn want_foo(f: Foo) {} +fn have_bar(b: Bar) { + want_foo(b); // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/test-allow-dead-extern-static-no-warning.rs b/gcc/testsuite/rust/rustc/ui/test-allow-dead-extern-static-no-warning.rs new file mode 100644 index 000000000000..97057be787c1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-allow-dead-extern-static-no-warning.rs @@ -0,0 +1,12 @@ +// run-pass +// compile-flags: --test + +#![deny(dead_code)] + +extern "C" { + #[allow(dead_code)] + static Qt: u64; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/auxiliary/test_macro.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/auxiliary/test_macro.rs new file mode 100644 index 000000000000..4e5853bbabc5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/auxiliary/test_macro.rs @@ -0,0 +1,5 @@ +#[macro_export] +macro_rules! test { + () => {}; +} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/decl-macro-test.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/decl-macro-test.rs new file mode 100644 index 000000000000..236255dd2fd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/decl-macro-test.rs @@ -0,0 +1,23 @@ +// Check that declarative macros can declare tests + +// check-pass +// compile-flags: --test + +#![feature(decl_macro)] + +macro create_test() { + #[test] + fn test() {} +} + +macro create_module_test() { + mod x { + #[test] + fn test() {} + } +} + +create_test!(); +create_test!(); +create_module_test!(); + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/inaccessible-test-modules.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/inaccessible-test-modules.rs new file mode 100644 index 000000000000..e92ac462fba9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/inaccessible-test-modules.rs @@ -0,0 +1,10 @@ +// compile-flags:--test + +// the `--test` harness creates modules with these textual names, but +// they should be inaccessible from normal code. +use main as x; // { dg-error ".E0432." "" { target *-*-* } } +use test as y; // { dg-error ".E0432." "" { target *-*-* } } + +#[test] +fn baz() {} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/run-unexported-tests.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/run-unexported-tests.rs new file mode 100644 index 000000000000..9cae5f47643b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/run-unexported-tests.rs @@ -0,0 +1,13 @@ +// run-fail +// compile-flags:--test +// check-stdout + +mod m { + pub fn exported() {} + + #[test] + fn unexported() { + panic!("ran an unexported test"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-allow-fail-attr.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-allow-fail-attr.rs new file mode 100644 index 000000000000..7d91a9a9e5d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-allow-fail-attr.rs @@ -0,0 +1,18 @@ +// run-pass +// compile-flags: --test +#![feature(allow_fail)] +#![feature(cfg_panic)] + +#[test] +#[allow_fail] +fn test1() { + #[cfg(not(panic = "abort"))] + panic!(); +} + +#[test] +#[allow_fail] +fn test2() { + assert!(true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-attr-non-associated-functions.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-attr-non-associated-functions.rs new file mode 100644 index 000000000000..bdf750a87e3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-attr-non-associated-functions.rs @@ -0,0 +1,26 @@ +// #[test] attribute is not allowed on associated functions or methods +// reworded error message +// compile-flags:--test + +struct A {} + +impl A { + #[test] + fn new() -> A { +// { dg-error "" "" { target *-*-* } .-1 } + A {} + } + #[test] + fn recovery_witness() -> A { +// { dg-error "" "" { target *-*-* } .-1 } + A {} + } +} + +#[test] +fn test() { + let _ = A::new(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-cant-be-shadowed.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-cant-be-shadowed.rs new file mode 100644 index 000000000000..68241a8e8e7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-cant-be-shadowed.rs @@ -0,0 +1,14 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:test_macro.rs +// compile-flags:--test + +#[macro_use] extern crate test_macro; + +#[test] +fn foo(){} + +macro_rules! test { () => () } + +#[test] +fn bar() {} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-fn-signature-verification-for-explicit-return-type.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-fn-signature-verification-for-explicit-return-type.rs new file mode 100644 index 000000000000..344a61c03dee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-fn-signature-verification-for-explicit-return-type.rs @@ -0,0 +1,13 @@ +// run-pass + +#![feature(test)] + +// compile-flags: --test +extern crate test; + +#[bench] +pub fn bench_explicit_return_type(_: &mut ::test::Bencher) -> () {} + +#[test] +pub fn test_explicit_return_type() -> () {} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-main-not-dead-attr.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-main-not-dead-attr.rs new file mode 100644 index 000000000000..0761be8b11bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-main-not-dead-attr.rs @@ -0,0 +1,10 @@ +// run-pass +// compile-flags: --test + +#![feature(main)] + +#![deny(dead_code)] + +#[main] +fn foo() { panic!(); } + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-main-not-dead.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-main-not-dead.rs new file mode 100644 index 000000000000..0d5953d3f390 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-main-not-dead.rs @@ -0,0 +1,7 @@ +// run-pass +// compile-flags: --test + +#![deny(dead_code)] + +fn main() { panic!(); } + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-on-macro.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-on-macro.rs new file mode 100644 index 000000000000..0e07ff7b7347 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-on-macro.rs @@ -0,0 +1,14 @@ +// check-pass +// compile-flags:--test + +#![deny(warnings)] + +macro_rules! foo { + () => (fn foo(){}) +} + +#[test] +foo!(); // { dg-warning "" "" { target *-*-* } } + +fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-runner-hides-buried-main.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-runner-hides-buried-main.rs new file mode 100644 index 000000000000..e241e3a0d1b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-runner-hides-buried-main.rs @@ -0,0 +1,16 @@ +// run-pass +// compile-flags: --test + +#![feature(main)] + +#![allow(dead_code)] + +mod a { + fn b() { + (|| { + #[main] + fn c() { panic!(); } + })(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-runner-hides-main.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-runner-hides-main.rs new file mode 100644 index 000000000000..3bba9836ddd5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-runner-hides-main.rs @@ -0,0 +1,6 @@ +// run-pass +// compile-flags:--test +// Building as a test runner means that a synthetic main will be run, +// not ours +pub fn main() { panic!(); } + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-runner-hides-start.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-runner-hides-start.rs new file mode 100644 index 000000000000..72bdce55b68b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-runner-hides-start.rs @@ -0,0 +1,8 @@ +// run-pass +// compile-flags: --test + +#![feature(start)] + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { panic!(); } + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-should-fail-good-message.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-should-fail-good-message.rs new file mode 100644 index 000000000000..736245ab43f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-should-fail-good-message.rs @@ -0,0 +1,15 @@ +// run-pass +// ignore-wasm32-bare compiled with panic=abort by default +// compile-flags: --test +#[test] +#[should_panic(expected = "foo")] +pub fn test_foo() { + panic!("foo bar") +} + +#[test] +#[should_panic(expected = "foo")] +pub fn test_foo_dynamic() { + panic!("{} bar", "foo") +} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-should-panic-attr.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-should-panic-attr.rs new file mode 100644 index 000000000000..e16717d26c1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-should-panic-attr.rs @@ -0,0 +1,37 @@ +// check-pass +// compile-flags: --test + +#[test] +#[should_panic = "foo"] +fn test1() { + panic!(); +} + +#[test] +#[should_panic(expected)] +// { dg-warning "" "" { target *-*-* } .-1 } +fn test2() { + panic!(); +} + +#[test] +#[should_panic(expect)] +// { dg-warning "" "" { target *-*-* } .-1 } +fn test3() { + panic!(); +} + +#[test] +#[should_panic(expected(foo, bar))] +// { dg-warning "" "" { target *-*-* } .-1 } +fn test4() { + panic!(); +} + +#[test] +#[should_panic(expected = "foo", bar)] +// { dg-warning "" "" { target *-*-* } .-1 } +fn test5() { + panic!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-vs-cfg-test.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-vs-cfg-test.rs new file mode 100644 index 000000000000..43e5411a4e8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-vs-cfg-test.rs @@ -0,0 +1,10 @@ +// run-pass +// compile-flags: --cfg test + +// Make sure `--cfg test` does not inject test harness + +#[test] +fn test() { panic!(); } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/test-attrs/test-warns-dead-code.rs b/gcc/testsuite/rust/rustc/ui/test-attrs/test-warns-dead-code.rs new file mode 100644 index 000000000000..c59ffc7671ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-attrs/test-warns-dead-code.rs @@ -0,0 +1,8 @@ +// compile-flags: --test + +#![deny(dead_code)] + +fn dead() {} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/test-cfg.rs b/gcc/testsuite/rust/rustc/ui/test-cfg.rs new file mode 100644 index 000000000000..be096514baf7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-cfg.rs @@ -0,0 +1,9 @@ +// compile-flags: --cfg foo + +#[cfg(all(foo, bar))] // foo AND bar +fn foo() {} + +fn main() { + foo(); // { dg-error ".E0425." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/test-panic-abort-disabled.rs b/gcc/testsuite/rust/rustc/ui/test-panic-abort-disabled.rs new file mode 100644 index 000000000000..eff203e8e199 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-panic-abort-disabled.rs @@ -0,0 +1,21 @@ +// error-pattern:building tests with panic=abort is not supported +// no-prefer-dynamic +// compile-flags: --test -Cpanic=abort +// run-flags: --test-threads=1 + +// ignore-wasm no panic or subprocess support +// ignore-emscripten no panic or subprocess support + +#![cfg(test)] + +#[test] +fn it_works() { + assert_eq!(1 + 1, 2); +} + +#[test] +#[should_panic] +fn it_panics() { + assert_eq!(1 + 1, 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/test-panic-abort-nocapture.rs b/gcc/testsuite/rust/rustc/ui/test-panic-abort-nocapture.rs new file mode 100644 index 000000000000..9eb210444383 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-panic-abort-nocapture.rs @@ -0,0 +1,41 @@ +// no-prefer-dynamic +// compile-flags: --test -Cpanic=abort -Zpanic_abort_tests +// run-flags: --test-threads=1 --nocapture +// run-fail +// check-run-results +// exec-env:RUST_BACKTRACE=0 + +// ignore-wasm no panic or subprocess support +// ignore-emscripten no panic or subprocess support +// ignore-sgx no subprocess support + +#![cfg(test)] + +use std::io::Write; + +#[test] +fn it_works() { + println!("about to succeed"); + assert_eq!(1 + 1, 2); +} + +#[test] +#[should_panic] +fn it_panics() { + println!("about to panic"); + assert_eq!(1 + 1, 4); +} + +#[test] +fn it_fails() { + println!("about to fail"); + assert_eq!(1 + 1, 4); +} + +#[test] +fn it_writes_to_stdio() { + println!("hello, world"); + writeln!(std::io::stdout(), "testing123").unwrap(); + writeln!(std::io::stderr(), "testing321").unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/test-panic-abort.rs b/gcc/testsuite/rust/rustc/ui/test-panic-abort.rs new file mode 100644 index 000000000000..75d687838b1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-panic-abort.rs @@ -0,0 +1,50 @@ +// no-prefer-dynamic +// compile-flags: --test -Cpanic=abort -Zpanic_abort_tests +// run-flags: --test-threads=1 +// run-fail +// check-run-results +// exec-env:RUST_BACKTRACE=0 + +// ignore-wasm no panic or subprocess support +// ignore-emscripten no panic or subprocess support +// ignore-sgx no subprocess support + +#![cfg(test)] + +use std::io::Write; +use std::env; + +#[test] +fn it_works() { + assert_eq!(1 + 1, 2); +} + +#[test] +#[should_panic] +fn it_panics() { + assert_eq!(1 + 1, 4); +} + +#[test] +fn it_fails() { + println!("hello, world"); + writeln!(std::io::stdout(), "testing123").unwrap(); + writeln!(std::io::stderr(), "testing321").unwrap(); + assert_eq!(1 + 1, 5); +} + +#[test] +fn it_exits() { + std::process::exit(123); +} + +#[test] +fn no_residual_environment() { + for (key, _) in env::vars() { + // Look for keys like __RUST_TEST_INVOKE. + if key.contains("TEST_INVOKE") { + panic!("shouldn't have '{}' in environment", key); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/test-panic-while-printing.rs b/gcc/testsuite/rust/rustc/ui/test-panic-while-printing.rs new file mode 100644 index 000000000000..7d848e29b237 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-panic-while-printing.rs @@ -0,0 +1,25 @@ +// compile-flags:--test +// run-pass +// ignore-emscripten no subprocess support + +use std::fmt; +use std::fmt::{Display, Formatter}; + +pub struct A(Vec); + +impl Display for A { + fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result { + self.0[0]; + Ok(()) + } +} + +#[test] +fn main() { + let result = std::panic::catch_unwind(|| { + let a = A(vec![]); + eprintln!("{}", a); + }); + assert!(result.is_err()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/test-thread-capture.rs b/gcc/testsuite/rust/rustc/ui/test-thread-capture.rs new file mode 100644 index 000000000000..10725da21ae9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-thread-capture.rs @@ -0,0 +1,32 @@ +// compile-flags: --test +// run-fail +// run-flags: --test-threads=1 +// check-run-results +// exec-env:RUST_BACKTRACE=0 +// ignore-emscripten no threads support + +#[test] +fn thready_pass() { + println!("fee"); + std::thread::spawn(|| { + println!("fie"); + println!("foe"); + }) + .join() + .unwrap(); + println!("fum"); +} + +#[test] +fn thready_fail() { + println!("fee"); + std::thread::spawn(|| { + println!("fie"); + println!("foe"); + }) + .join() + .unwrap(); + println!("fum"); + panic!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/test-thread-nocapture.rs b/gcc/testsuite/rust/rustc/ui/test-thread-nocapture.rs new file mode 100644 index 000000000000..9c2b2a09d266 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/test-thread-nocapture.rs @@ -0,0 +1,32 @@ +// compile-flags: --test +// run-fail +// run-flags: --test-threads=1 --nocapture +// check-run-results +// exec-env:RUST_BACKTRACE=0 +// ignore-emscripten no threads support + +#[test] +fn thready_pass() { + println!("fee"); + std::thread::spawn(|| { + println!("fie"); + println!("foe"); + }) + .join() + .unwrap(); + println!("fum"); +} + +#[test] +fn thready_fail() { + println!("fee"); + std::thread::spawn(|| { + println!("fie"); + println!("foe"); + }) + .join() + .unwrap(); + println!("fum"); + panic!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/thin-lto-global-allocator.rs b/gcc/testsuite/rust/rustc/ui/thin-lto-global-allocator.rs new file mode 100644 index 000000000000..67caccd8351b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thin-lto-global-allocator.rs @@ -0,0 +1,8 @@ +// run-pass +// compile-flags: -Z thinlto -C codegen-units=2 + +#[global_allocator] +static A: std::alloc::System = std::alloc::System; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/thinlto/all-crates.rs b/gcc/testsuite/rust/rustc/ui/thinlto/all-crates.rs new file mode 100644 index 000000000000..5fb7d7e9bdea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thinlto/all-crates.rs @@ -0,0 +1,9 @@ +// run-pass + +// compile-flags: -Clto=thin +// no-prefer-dynamic + +fn main() { + println!("hello!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/thinlto/auxiliary/dylib.rs b/gcc/testsuite/rust/rustc/ui/thinlto/auxiliary/dylib.rs new file mode 100644 index 000000000000..85d499df0fb2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thinlto/auxiliary/dylib.rs @@ -0,0 +1,7 @@ +// compile-flags: -Z thinlto -C codegen-units=8 + +#[inline] +pub fn foo(b: u8) { + b.to_string(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/thinlto/auxiliary/msvc-imp-present.rs b/gcc/testsuite/rust/rustc/ui/thinlto/auxiliary/msvc-imp-present.rs new file mode 100644 index 000000000000..b78af84a6238 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thinlto/auxiliary/msvc-imp-present.rs @@ -0,0 +1,12 @@ +// no-prefer-dynamic +// compile-flags: -Z thinlto -C codegen-units=8 -C prefer-dynamic + +#![crate_type = "rlib"] +#![crate_type = "dylib"] + +pub static A: u32 = 43; + +pub mod a { + pub static A: u32 = 43; +} + diff --git a/gcc/testsuite/rust/rustc/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs b/gcc/testsuite/rust/rustc/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs new file mode 100644 index 000000000000..afb91c799f81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thinlto/auxiliary/thin-lto-inlines-aux.rs @@ -0,0 +1,8 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] + +pub fn bar() -> u32 { + 3 +} + diff --git a/gcc/testsuite/rust/rustc/ui/thinlto/dylib-works.rs b/gcc/testsuite/rust/rustc/ui/thinlto/dylib-works.rs new file mode 100644 index 000000000000..b3fa6cf9c36e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thinlto/dylib-works.rs @@ -0,0 +1,10 @@ +// run-pass + +// aux-build:dylib.rs + +extern crate dylib; + +fn main() { + dylib::foo(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/thinlto/msvc-imp-present.rs b/gcc/testsuite/rust/rustc/ui/thinlto/msvc-imp-present.rs new file mode 100644 index 000000000000..ab1114414172 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thinlto/msvc-imp-present.rs @@ -0,0 +1,23 @@ +// run-pass + +// aux-build:msvc-imp-present.rs +// compile-flags: -Z thinlto -C codegen-units=8 +// no-prefer-dynamic + +// On MSVC we have a "hack" where we emit symbols that look like `_imp_$name` +// for all exported statics. This is done because we apply `dllimport` to all +// imported constants and this allows everything to actually link correctly. +// +// The ThinLTO passes aggressively remove symbols if they can, and this test +// asserts that the ThinLTO passes don't remove these compiler-generated +// `_imp_*` symbols. The external library that we link in here is compiled with +// ThinLTO and multiple codegen units and has a few exported constants. Note +// that we also namely compile the library as both a dylib and an rlib, but we +// link the rlib to ensure that we assert those generated symbols exist. + +extern crate msvc_imp_present as bar; + +fn main() { + println!("{}", bar::A); +} + diff --git a/gcc/testsuite/rust/rustc/ui/thinlto/thin-lto-inlines.rs b/gcc/testsuite/rust/rustc/ui/thinlto/thin-lto-inlines.rs new file mode 100644 index 000000000000..1a5bdd08d2ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thinlto/thin-lto-inlines.rs @@ -0,0 +1,31 @@ +// run-pass + +// compile-flags: -Z thinlto -C codegen-units=8 -O +// ignore-emscripten can't inspect instructions on emscripten + +// We want to assert here that ThinLTO will inline across codegen units. There's +// not really a great way to do that in general so we sort of hack around it by +// praying two functions go into separate codegen units and then assuming that +// if inlining *doesn't* happen the first byte of the functions will differ. + +pub fn foo() -> u32 { + bar::bar() +} + +mod bar { + pub fn bar() -> u32 { + 3 + } +} + +fn main() { + println!("{} {}", foo(), bar::bar()); + + unsafe { + let foo = foo as usize as *const u8; + let bar = bar::bar as usize as *const u8; + + assert_eq!(*foo, *bar); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/thinlto/thin-lto-inlines2.rs b/gcc/testsuite/rust/rustc/ui/thinlto/thin-lto-inlines2.rs new file mode 100644 index 000000000000..f053dd35a21b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thinlto/thin-lto-inlines2.rs @@ -0,0 +1,29 @@ +// run-pass + +// compile-flags: -C codegen-units=8 -O -C lto=thin +// aux-build:thin-lto-inlines-aux.rs +// no-prefer-dynamic +// ignore-emscripten can't inspect instructions on emscripten + +// We want to assert here that ThinLTO will inline across codegen units. There's +// not really a great way to do that in general so we sort of hack around it by +// praying two functions go into separate codegen units and then assuming that +// if inlining *doesn't* happen the first byte of the functions will differ. + +extern crate thin_lto_inlines_aux as bar; + +pub fn foo() -> u32 { + bar::bar() +} + +fn main() { + println!("{} {}", foo(), bar::bar()); + + unsafe { + let foo = foo as usize as *const u8; + let bar = bar::bar as usize as *const u8; + + assert_eq!(*foo, *bar); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/thinlto/weak-works.rs b/gcc/testsuite/rust/rustc/ui/thinlto/weak-works.rs new file mode 100644 index 000000000000..956822c6f84c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thinlto/weak-works.rs @@ -0,0 +1,29 @@ +// run-pass + +// compile-flags: -C codegen-units=8 -Z thinlto +// ignore-windows + +#![feature(linkage)] + +pub mod foo { + #[linkage = "weak"] + #[no_mangle] + pub extern "C" fn FOO() -> i32 { + 0 + } +} + +mod bar { + extern "C" { + fn FOO() -> i32; + } + + pub fn bar() -> i32 { + unsafe { FOO() } + } +} + +fn main() { + bar::bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/thread-local-in-ctfe.rs b/gcc/testsuite/rust/rustc/ui/thread-local-in-ctfe.rs new file mode 100644 index 000000000000..75acc28333ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thread-local-in-ctfe.rs @@ -0,0 +1,24 @@ +#![feature(const_fn, thread_local)] + +#[thread_local] +static A: u32 = 1; + +static B: u32 = A; +// { dg-error ".E0625." "" { target *-*-* } .-1 } + +static C: &u32 = &A; +// { dg-error ".E0625." "" { target *-*-* } .-1 } + +const D: u32 = A; +// { dg-error ".E0625." "" { target *-*-* } .-1 } + +const E: &u32 = &A; +// { dg-error ".E0625." "" { target *-*-* } .-1 } + +const fn f() -> u32 { + A +// { dg-error ".E0625." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/thread-local-mutation.rs b/gcc/testsuite/rust/rustc/ui/thread-local-mutation.rs new file mode 100644 index 000000000000..28fdaf5ad6af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thread-local-mutation.rs @@ -0,0 +1,19 @@ +// Regression test for #54901: immutable thread locals could be mutated. See: +// https://github.com/rust-lang/rust/issues/29594#issuecomment-328177697 +// https://github.com/rust-lang/rust/issues/54901 + +#![feature(thread_local)] + +#[thread_local] +static S: &str = "before"; + +fn set_s() { + S = "after"; // { dg-error ".E0594." "" { target *-*-* } } +} + +fn main() { + println!("{}", S); + set_s(); + println!("{}", S); +} + diff --git a/gcc/testsuite/rust/rustc/ui/thread-local-not-in-prelude.rs b/gcc/testsuite/rust/rustc/ui/thread-local-not-in-prelude.rs new file mode 100644 index 000000000000..faa1d79a03b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/thread-local-not-in-prelude.rs @@ -0,0 +1,10 @@ +// run-pass +#![no_std] + +extern crate std; + +std::thread_local!(static A: usize = 30); + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs new file mode 100644 index 000000000000..d5e62a2e89a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/auxiliary/thread-local-extern-static.rs @@ -0,0 +1,11 @@ +#![feature(cfg_target_thread_local, const_fn, thread_local)] +#![crate_type = "lib"] + +#[cfg(target_thread_local)] +use std::cell::Cell; + +#[no_mangle] +#[cfg(target_thread_local)] +#[thread_local] +pub static FOO: Cell = Cell::new(3); + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/comm.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/comm.rs new file mode 100644 index 000000000000..edd121cc85fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/comm.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +use std::thread; +use std::sync::mpsc::{channel, Sender}; + +pub fn main() { + let (tx, rx) = channel(); + let t = thread::spawn(move|| { child(&tx) }); + let y = rx.recv().unwrap(); + println!("received"); + println!("{}", y); + assert_eq!(y, 10); + t.join(); +} + +fn child(c: &Sender) { + println!("sending"); + c.send(10).unwrap(); + println!("value sent"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/send-is-not-static-par-for.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/send-is-not-static-par-for.rs new file mode 100644 index 000000000000..a1b19818ab1e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/send-is-not-static-par-for.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(unused_imports)] +use std::thread; +use std::sync::Mutex; + +fn par_for(iter: I, f: F) + where I: Iterator, + I::Item: Send, + F: Fn(I::Item) + Sync +{ + for item in iter { + f(item) + } +} + +fn sum(x: &[i32]) { + let sum_lengths = Mutex::new(0); + par_for(x.windows(4), |x| { + *sum_lengths.lock().unwrap() += x.len() + }); + + assert_eq!(*sum_lengths.lock().unwrap(), (x.len() - 3) * 4); +} + +fn main() { + let mut elements = [0; 20]; + + // iterators over references into this stack frame + par_for(elements.iter_mut().enumerate(), |(i, x)| { + *x = i as i32 + }); + + sum(&elements) +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/send-resource.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/send-resource.rs new file mode 100644 index 000000000000..ec5e5efd67c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/send-resource.rs @@ -0,0 +1,40 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 +// ignore-emscripten no threads support + +use std::thread; +use std::sync::mpsc::channel; + +struct test { + f: isize, +} + +impl Drop for test { + fn drop(&mut self) {} +} + +fn test(f: isize) -> test { + test { + f: f + } +} + +pub fn main() { + let (tx, rx) = channel(); + + let t = thread::spawn(move|| { + let (tx2, rx2) = channel(); + tx.send(tx2).unwrap(); + + let _r = rx2.recv().unwrap(); + }); + + rx.recv().unwrap().send(test(42)).unwrap(); + + t.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/send-type-inference.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/send-type-inference.rs new file mode 100644 index 000000000000..da74ed9f7956 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/send-type-inference.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(dead_code)] +#![allow(unused_mut)] +// pretty-expanded FIXME #23616 + +use std::sync::mpsc::{channel, Sender}; + +// tests that ctrl's type gets inferred properly +struct Command { + key: K, + val: V +} + +fn cache_server(mut tx: Sender>>) { + let (tx1, _rx) = channel(); + tx.send(tx1); +} +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/send_str_hashmap.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/send_str_hashmap.rs new file mode 100644 index 000000000000..0d2f32b8d800 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/send_str_hashmap.rs @@ -0,0 +1,54 @@ +// run-pass +use std::collections::HashMap; +use std::borrow::Cow; + +use std::borrow::Cow::Borrowed as B; +use std::borrow::Cow::Owned as O; + +type SendStr = Cow<'static, str>; + +fn main() { + let mut map: HashMap = HashMap::new(); + assert!(map.insert(B("foo"), 42).is_none()); + assert!(map.insert(O("foo".to_string()), 42).is_some()); + assert!(map.insert(B("foo"), 42).is_some()); + assert!(map.insert(O("foo".to_string()), 42).is_some()); + + assert!(map.insert(B("foo"), 43).is_some()); + assert!(map.insert(O("foo".to_string()), 44).is_some()); + assert!(map.insert(B("foo"), 45).is_some()); + assert!(map.insert(O("foo".to_string()), 46).is_some()); + + let v = 46; + + assert_eq!(map.get(&O("foo".to_string())), Some(&v)); + assert_eq!(map.get(&B("foo")), Some(&v)); + + let (a, b, c, d) = (50, 51, 52, 53); + + assert!(map.insert(B("abc"), a).is_none()); + assert!(map.insert(O("bcd".to_string()), b).is_none()); + assert!(map.insert(B("cde"), c).is_none()); + assert!(map.insert(O("def".to_string()), d).is_none()); + + assert!(map.insert(B("abc"), a).is_some()); + assert!(map.insert(O("bcd".to_string()), b).is_some()); + assert!(map.insert(B("cde"), c).is_some()); + assert!(map.insert(O("def".to_string()), d).is_some()); + + assert!(map.insert(O("abc".to_string()), a).is_some()); + assert!(map.insert(B("bcd"), b).is_some()); + assert!(map.insert(O("cde".to_string()), c).is_some()); + assert!(map.insert(B("def"), d).is_some()); + + assert_eq!(map.get("abc"), Some(&a)); + assert_eq!(map.get("bcd"), Some(&b)); + assert_eq!(map.get("cde"), Some(&c)); + assert_eq!(map.get("def"), Some(&d)); + + assert_eq!(map.get(&B("abc")), Some(&a)); + assert_eq!(map.get(&B("bcd")), Some(&b)); + assert_eq!(map.get(&B("cde")), Some(&c)); + assert_eq!(map.get(&B("def")), Some(&d)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/send_str_treemap.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/send_str_treemap.rs new file mode 100644 index 000000000000..581799b17fd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/send_str_treemap.rs @@ -0,0 +1,59 @@ +// run-pass +use std::collections::BTreeMap; +use std::borrow::Cow; + +use std::borrow::Cow::{Owned as O, Borrowed as B}; + +type SendStr = Cow<'static, str>; + +fn main() { + let mut map: BTreeMap = BTreeMap::new(); + assert!(map.insert(B("foo"), 42).is_none()); + assert!(map.insert(O("foo".to_string()), 42).is_some()); + assert!(map.insert(B("foo"), 42).is_some()); + assert!(map.insert(O("foo".to_string()), 42).is_some()); + + assert!(map.insert(B("foo"), 43).is_some()); + assert!(map.insert(O("foo".to_string()), 44).is_some()); + assert!(map.insert(B("foo"), 45).is_some()); + assert!(map.insert(O("foo".to_string()), 46).is_some()); + + let v = 46; + + assert_eq!(map.get(&O("foo".to_string())), Some(&v)); + assert_eq!(map.get(&B("foo")), Some(&v)); + + let (a, b, c, d) = (50, 51, 52, 53); + + assert!(map.insert(B("abc"), a).is_none()); + assert!(map.insert(O("bcd".to_string()), b).is_none()); + assert!(map.insert(B("cde"), c).is_none()); + assert!(map.insert(O("def".to_string()), d).is_none()); + + assert!(map.insert(B("abc"), a).is_some()); + assert!(map.insert(O("bcd".to_string()), b).is_some()); + assert!(map.insert(B("cde"), c).is_some()); + assert!(map.insert(O("def".to_string()), d).is_some()); + + assert!(map.insert(O("abc".to_string()), a).is_some()); + assert!(map.insert(B("bcd"), b).is_some()); + assert!(map.insert(O("cde".to_string()), c).is_some()); + assert!(map.insert(B("def"), d).is_some()); + + assert_eq!(map.get(&B("abc")), Some(&a)); + assert_eq!(map.get(&B("bcd")), Some(&b)); + assert_eq!(map.get(&B("cde")), Some(&c)); + assert_eq!(map.get(&B("def")), Some(&d)); + + assert_eq!(map.get(&O("abc".to_string())), Some(&a)); + assert_eq!(map.get(&O("bcd".to_string())), Some(&b)); + assert_eq!(map.get(&O("cde".to_string())), Some(&c)); + assert_eq!(map.get(&O("def".to_string())), Some(&d)); + + assert!(map.remove(&B("foo")).is_some()); + assert_eq!(map.into_iter().map(|(k, v)| format!("{}{}", k, v)) + .collect::>() + .concat(), + "abc50bcd51cde52def53".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/sendable-class.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sendable-class.rs new file mode 100644 index 000000000000..e5003128180f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sendable-class.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(non_camel_case_types)] + +// Test that a class with only sendable fields can be sent + +// pretty-expanded FIXME #23616 + +use std::sync::mpsc::channel; + +struct foo { + i: isize, + j: char, +} + +fn foo(i:isize, j: char) -> foo { + foo { + i: i, + j: j + } +} + +pub fn main() { + let (tx, rx) = channel(); + tx.send(foo(42, 'c')); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/sendfn-is-a-block.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sendfn-is-a-block.rs new file mode 100644 index 000000000000..ac20092c40d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sendfn-is-a-block.rs @@ -0,0 +1,12 @@ +// run-pass + + +fn test(f: F) -> usize where F: FnOnce(usize) -> usize { + return f(22); +} + +pub fn main() { + let y = test(|x| 4 * x); + assert_eq!(y, 88); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs new file mode 100644 index 000000000000..47730fd814aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs @@ -0,0 +1,24 @@ +// run-pass +// ignore-emscripten no threads support + +#![feature(box_syntax)] + +use std::thread; + +pub fn main() { test05(); } + +fn test05_start(f: F) { + f(22); +} + +fn test05() { + let three: Box<_> = box 3; + let fn_to_send = move|n:isize| { + println!("{}", *three + n); // will copy x into the closure + assert_eq!(*three, 3); + }; + thread::spawn(move|| { + test05_start(fn_to_send); + }).join().ok().unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn-fn.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn-fn.rs new file mode 100644 index 000000000000..6029af25709d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn-fn.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +use std::thread; + +fn x(s: String, n: isize) { + println!("{}", s); + println!("{}", n); +} + +pub fn main() { + let t1 = thread::spawn(|| x("hello from first spawned fn".to_string(), 65) ); + let t2 = thread::spawn(|| x("hello from second spawned fn".to_string(), 66) ); + let t3 = thread::spawn(|| x("hello from third spawned fn".to_string(), 67) ); + let mut i = 30; + while i > 0 { + i = i - 1; + println!("parent sleeping"); + thread::yield_now(); + } + t1.join(); + t2.join(); + t3.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn-types.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn-types.rs new file mode 100644 index 000000000000..4f216b71da51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn-types.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(non_camel_case_types)] + +// ignore-emscripten no threads support + +/* + Make sure we can spawn tasks that take different types of + parameters. This is based on a test case for #520 provided by Rob + Arnold. + */ + +use std::thread; +use std::sync::mpsc::{channel, Sender}; + +type ctx = Sender; + +fn iotask(_tx: &ctx, ip: String) { + assert_eq!(ip, "localhost".to_string()); +} + +pub fn main() { + let (tx, _rx) = channel::(); + let t = thread::spawn(move|| iotask(&tx, "localhost".to_string()) ); + t.join().ok().unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn.rs new file mode 100644 index 000000000000..5815051f396e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn.rs @@ -0,0 +1,11 @@ +// run-pass +// ignore-emscripten no threads support + +use std::thread; + +pub fn main() { + thread::spawn(move|| child(10)).join().ok().unwrap(); +} + +fn child(i: isize) { println!("{}", i); assert_eq!(i, 10); } + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn2.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn2.rs new file mode 100644 index 000000000000..dbcc29d4867d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawn2.rs @@ -0,0 +1,32 @@ +// run-pass +// ignore-emscripten no threads support + +use std::thread; + +pub fn main() { + let t = thread::spawn(move|| child((10, 20, 30, 40, 50, 60, 70, 80, 90)) ); + t.join().ok().unwrap(); // forget Err value, since it doesn't implement Debug +} + +fn child(args: (isize, isize, isize, isize, isize, isize, isize, isize, isize)) { + let (i1, i2, i3, i4, i5, i6, i7, i8, i9) = args; + println!("{}", i1); + println!("{}", i2); + println!("{}", i3); + println!("{}", i4); + println!("{}", i5); + println!("{}", i6); + println!("{}", i7); + println!("{}", i8); + println!("{}", i9); + assert_eq!(i1, 10); + assert_eq!(i2, 20); + assert_eq!(i3, 30); + assert_eq!(i4, 40); + assert_eq!(i5, 50); + assert_eq!(i6, 60); + assert_eq!(i7, 70); + assert_eq!(i8, 80); + assert_eq!(i9, 90); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawning-with-debug.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawning-with-debug.rs new file mode 100644 index 000000000000..b80bbd330a59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/spawning-with-debug.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(unused_mut)] +// ignore-windows +// exec-env:RUST_LOG=debug +// ignore-emscripten no threads support + +// regression test for issue #10405, make sure we don't call println! too soon. + +use std::thread::Builder; + +pub fn main() { + let mut t = Builder::new(); + t.spawn(move || ()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/std-sync-right-kind-impls.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/std-sync-right-kind-impls.rs new file mode 100644 index 000000000000..98422f75486d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/std-sync-right-kind-impls.rs @@ -0,0 +1,17 @@ +// run-pass +// pretty-expanded FIXME #23616 + +use std::sync; + +fn assert_both() {} + +fn main() { + assert_both::>(); + assert_both::(); + assert_both::>(); + assert_both::(); + assert_both::>(); + assert_both::>(); + assert_both::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-atomics.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-atomics.rs new file mode 100644 index 000000000000..793ed2c41c7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-atomics.rs @@ -0,0 +1,15 @@ +// run-pass + +// pretty-expanded FIXME #23616 + +use std::sync::atomic::*; + +trait SendSync: Send + Sync {} + +impl SendSync for AtomicBool {} +impl SendSync for AtomicIsize {} +impl SendSync for AtomicUsize {} +impl SendSync for AtomicPtr {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-in-std.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-in-std.rs new file mode 100644 index 000000000000..2c24a16bfb20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-in-std.rs @@ -0,0 +1,26 @@ +// run-pass + +// ignore-cloudabi networking not available +// ignore-wasm32-bare networking not available +// ignore-sgx ToSocketAddrs cannot be used for DNS Resolution + +use std::net::ToSocketAddrs; + +fn is_sync(_: T) where T: Sync {} +fn is_send(_: T) where T: Send {} + +macro_rules! all_sync_send { + ($ctor:expr, $($iter:ident),+) => ({ + $( + let mut x = $ctor; + is_sync(x.$iter()); + let mut y = $ctor; + is_send(y.$iter()); + )+ + }) +} + +fn main() { + all_sync_send!("localhost:80".to_socket_addrs().unwrap(), next); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs new file mode 100644 index 000000000000..5990baa66175 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs @@ -0,0 +1,72 @@ +// run-pass + +#![allow(warnings)] +#![feature(drain, collections_bound, btree_range)] + +use std::collections::BinaryHeap; +use std::collections::{BTreeMap, BTreeSet}; +use std::collections::LinkedList; +use std::collections::VecDeque; +use std::collections::HashMap; +use std::collections::HashSet; + +use std::mem; +use std::ops::Bound::Included; + +fn is_sync(_: T) where T: Sync {} +fn is_send(_: T) where T: Send {} + +macro_rules! all_sync_send { + ($ctor:expr, $($iter:ident),+) => ({ + $( + let mut x = $ctor; + is_sync(x.$iter()); + let mut y = $ctor; + is_send(y.$iter()); + )+ + }) +} + +macro_rules! is_sync_send { + ($ctor:expr, $iter:ident($($param:expr),+)) => ({ + let mut x = $ctor; + is_sync(x.$iter($( $param ),+)); + let mut y = $ctor; + is_send(y.$iter($( $param ),+)); + }) +} + +fn main() { + // The iterator "generator" list should exhaust what corresponding + // implementations have where `Sync` and `Send` semantics apply. + all_sync_send!(BinaryHeap::::new(), iter, drain, into_iter); + + all_sync_send!(BTreeMap::::new(), iter, iter_mut, into_iter, keys, values); + is_sync_send!(BTreeMap::::new(), range((Included(&0), Included(&9)))); + is_sync_send!(BTreeMap::::new(), range_mut((Included(&0), Included(&9)))); + + all_sync_send!(BTreeSet::::new(), iter, into_iter); + is_sync_send!(BTreeSet::::new(), range((Included(&0), Included(&9)))); + is_sync_send!(BTreeSet::::new(), difference(&BTreeSet::::new())); + is_sync_send!(BTreeSet::::new(), symmetric_difference(&BTreeSet::::new())); + is_sync_send!(BTreeSet::::new(), intersection(&BTreeSet::::new())); + is_sync_send!(BTreeSet::::new(), union(&BTreeSet::::new())); + + all_sync_send!(HashMap::::new(), iter, iter_mut, drain, into_iter, keys, values); + is_sync_send!(HashMap::::new(), entry(0)); + all_sync_send!(HashSet::::new(), iter, drain, into_iter); + is_sync_send!(HashSet::::new(), difference(&HashSet::::new())); + is_sync_send!(HashSet::::new(), symmetric_difference(&HashSet::::new())); + is_sync_send!(HashSet::::new(), intersection(&HashSet::::new())); + is_sync_send!(HashSet::::new(), union(&HashSet::::new())); + + all_sync_send!(LinkedList::::new(), iter, iter_mut, into_iter); + + all_sync_send!(VecDeque::::new(), iter, iter_mut, into_iter); + is_sync_send!(VecDeque::::new(), drain(..)); + + all_sync_send!(Vec::::new(), into_iter); + is_sync_send!(Vec::::new(), drain(..)); + is_sync_send!(String::new(), drain(..)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-iterators-in-libcore.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-iterators-in-libcore.rs new file mode 100644 index 000000000000..bec41cdd18db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/sync-send-iterators-in-libcore.rs @@ -0,0 +1,106 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![allow(warnings)] + +use std::iter::{empty, once, repeat}; + +fn is_sync(_: T) where T: Sync {} +fn is_send(_: T) where T: Send {} + +macro_rules! all_sync_send { + ($ctor:expr, $iter:ident) => ({ + let mut x = $ctor; + is_sync(x.$iter()); + let mut y = $ctor; + is_send(y.$iter()); + }); + ($ctor:expr, $iter:ident($($param:expr),+)) => ({ + let mut x = $ctor; + is_sync(x.$iter($( $param ),+)); + let mut y = $ctor; + is_send(y.$iter($( $param ),+)); + }); + ($ctor:expr, $iter:ident, $($rest:tt)*) => ({ + all_sync_send!($ctor, $iter); + all_sync_send!($ctor, $($rest)*); + }); + ($ctor:expr, $iter:ident($($param:expr),+), $($rest:tt)*) => ({ + all_sync_send!($ctor, $iter($( $param ),+)); + all_sync_send!($ctor, $($rest)*); + }); +} + +macro_rules! all_sync_send_mutable_ref { + ($ctor:expr, $($iter:ident),+) => ({ + $( + let mut x = $ctor; + is_sync((&mut x).$iter()); + let mut y = $ctor; + is_send((&mut y).$iter()); + )+ + }) +} + +macro_rules! is_sync_send { + ($ctor:expr) => ({ + let x = $ctor; + is_sync(x); + let y = $ctor; + is_send(y); + }) +} + +fn main() { + // for char.rs + all_sync_send!("Я", escape_debug, escape_default, escape_unicode); + + // for iter.rs + all_sync_send_mutable_ref!([1], iter); + + // Bytes implements DoubleEndedIterator + all_sync_send!("a".bytes(), rev); + + let a = [1]; + let b = [2]; + all_sync_send!(a.iter(), + cloned, + cycle, + chain([2].iter()), + zip([2].iter()), + map(|_| 1), + filter(|_| true), + filter_map(|_| Some(1)), + enumerate, + peekable, + skip_while(|_| true), + take_while(|_| true), + skip(1), + take(1), + scan(1, |_, _| Some(1)), + flat_map(|_| b.iter()), + fuse, + inspect(|_| ())); + + is_sync_send!((1..).step_by(2)); + is_sync_send!((1..2).step_by(2)); + is_sync_send!((1..2)); + is_sync_send!((1..)); + is_sync_send!(repeat(1)); + is_sync_send!(empty::()); + is_sync_send!(empty::<*mut i32>()); + is_sync_send!(once(1)); + + // for option.rs + // FIXME + + // for result.rs + // FIXME + + // for slice.rs + // FIXME + + // for str/mod.rs + // FIXME +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-0.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-0.rs new file mode 100644 index 000000000000..89c71e060848 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-0.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +use std::thread; +use std::sync::mpsc::{channel, Sender}; + +pub fn main() { test05(); } + +fn test05_start(tx : &Sender) { + tx.send(10).unwrap(); + println!("sent 10"); + tx.send(20).unwrap(); + println!("sent 20"); + tx.send(30).unwrap(); + println!("sent 30"); +} + +fn test05() { + let (tx, rx) = channel(); + let t = thread::spawn(move|| { test05_start(&tx) }); + let mut value: isize = rx.recv().unwrap(); + println!("{}", value); + value = rx.recv().unwrap(); + println!("{}", value); + value = rx.recv().unwrap(); + println!("{}", value); + assert_eq!(value, 30); + t.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-1.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-1.rs new file mode 100644 index 000000000000..2bc4af972cf8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-1.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +use std::thread; + +pub fn main() { test00(); } + +fn start() { println!("Started / Finished task."); } + +fn test00() { + thread::spawn(move|| start() ).join(); + println!("Completing."); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-10.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-10.rs new file mode 100644 index 000000000000..091ec013de02 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-10.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(unused_mut)] +// ignore-emscripten no threads support + +use std::thread; +use std::sync::mpsc::{channel, Sender}; + +fn start(tx: &Sender>) { + let (tx2, rx) = channel(); + tx.send(tx2).unwrap(); + + let mut a; + let mut b; + a = rx.recv().unwrap(); + assert_eq!(a, "A".to_string()); + println!("{}", a); + b = rx.recv().unwrap(); + assert_eq!(b, "B".to_string()); + println!("{}", b); +} + +pub fn main() { + let (tx, rx) = channel(); + let child = thread::spawn(move|| { start(&tx) }); + + let mut c = rx.recv().unwrap(); + c.send("A".to_string()).unwrap(); + c.send("B".to_string()).unwrap(); + thread::yield_now(); + + child.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-11.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-11.rs new file mode 100644 index 000000000000..7e903c7e3eb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-11.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(unused_must_use)] +// pretty-expanded FIXME #23616 +// ignore-emscripten no threads support + +use std::sync::mpsc::{channel, Sender}; +use std::thread; + +fn start(tx: &Sender>) { + let (tx2, _rx) = channel(); + tx.send(tx2).unwrap(); +} + +pub fn main() { + let (tx, rx) = channel(); + let child = thread::spawn(move|| { + start(&tx) + }); + let _tx = rx.recv().unwrap(); + child.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-12.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-12.rs new file mode 100644 index 000000000000..7f2ac9d4c5a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-12.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(unused_mut)] +// ignore-emscripten no threads support + +use std::thread; + +pub fn main() { test00(); } + +fn start(_task_number: isize) { println!("Started / Finished task."); } + +fn test00() { + let i: isize = 0; + let mut result = thread::spawn(move|| { + start(i) + }); + + // Sleep long enough for the thread to finish. + let mut i = 0_usize; + while i < 10000 { + thread::yield_now(); + i += 1; + } + + // Try joining threads that have already finished. + result.join(); + + println!("Joined task."); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-13.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-13.rs new file mode 100644 index 000000000000..360e8e39a6db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-13.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_variables)] +// ignore-emscripten no threads support + +use std::sync::mpsc::{channel, Sender}; +use std::thread; + +fn start(tx: &Sender, start: isize, number_of_messages: isize) { + let mut i: isize = 0; + while i< number_of_messages { tx.send(start + i).unwrap(); i += 1; } +} + +pub fn main() { + println!("Check that we don't deadlock."); + let (tx, rx) = channel(); + let _ = thread::spawn(move|| { start(&tx, 0, 10) }).join(); + println!("Joined task"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-14.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-14.rs new file mode 100644 index 000000000000..5f2de7ecac3c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-14.rs @@ -0,0 +1,37 @@ +// run-pass +#![allow(unused_parens)] +// ignore-emscripten no threads support + +use std::sync::mpsc::{channel, Sender}; +use std::thread; + +pub fn main() { + let (tx, rx) = channel(); + + // Spawn 10 threads each sending us back one isize. + let mut i = 10; + while (i > 0) { + println!("{}", i); + let tx = tx.clone(); + thread::spawn({let i = i; move|| { child(i, &tx) }}); + i = i - 1; + } + + // Spawned threads are likely killed before they get a chance to send + // anything back, so we deadlock here. + + i = 10; + while (i > 0) { + println!("{}", i); + rx.recv().unwrap(); + i = i - 1; + } + + println!("main thread exiting"); +} + +fn child(x: isize, tx: &Sender) { + println!("{}", x); + tx.send(x).unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-15.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-15.rs new file mode 100644 index 000000000000..95157228b658 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-15.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support +// pretty-expanded FIXME #23616 + +use std::sync::mpsc::{channel, Sender}; +use std::thread; + +fn start(tx: &Sender, i0: isize) { + let mut i = i0; + while i > 0 { + tx.send(0).unwrap(); + i = i - 1; + } +} + +pub fn main() { + // Spawn a thread that sends us back messages. The parent thread + // is likely to terminate before the child completes, so from + // the child's point of view the receiver may die. We should + // drop messages on the floor in this case, and not crash! + let (tx, rx) = channel(); + let t = thread::spawn(move|| { + start(&tx, 10) + }); + rx.recv(); + t.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-16.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-16.rs new file mode 100644 index 000000000000..4a75115d5229 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-16.rs @@ -0,0 +1,112 @@ +// run-pass +#![allow(unused_mut)] +#![allow(unused_parens)] +#![allow(non_camel_case_types)] + +use std::sync::mpsc::channel; +use std::cmp; + +// Tests of ports and channels on various types +fn test_rec() { + struct R {val0: isize, val1: u8, val2: char} + + let (tx, rx) = channel(); + let r0: R = R {val0: 0, val1: 1, val2: '2'}; + tx.send(r0).unwrap(); + let mut r1: R; + r1 = rx.recv().unwrap(); + assert_eq!(r1.val0, 0); + assert_eq!(r1.val1, 1); + assert_eq!(r1.val2, '2'); +} + +fn test_vec() { + let (tx, rx) = channel(); + let v0: Vec = vec![0, 1, 2]; + tx.send(v0).unwrap(); + let v1 = rx.recv().unwrap(); + assert_eq!(v1[0], 0); + assert_eq!(v1[1], 1); + assert_eq!(v1[2], 2); +} + +fn test_str() { + let (tx, rx) = channel(); + let s0 = "test".to_string(); + tx.send(s0).unwrap(); + let s1 = rx.recv().unwrap(); + assert_eq!(s1.as_bytes()[0], 't' as u8); + assert_eq!(s1.as_bytes()[1], 'e' as u8); + assert_eq!(s1.as_bytes()[2], 's' as u8); + assert_eq!(s1.as_bytes()[3], 't' as u8); +} + +#[derive(Debug)] +enum t { + tag1, + tag2(isize), + tag3(isize, u8, char) +} + +impl cmp::PartialEq for t { + fn eq(&self, other: &t) -> bool { + match *self { + t::tag1 => { + match (*other) { + t::tag1 => true, + _ => false + } + } + t::tag2(e0a) => { + match (*other) { + t::tag2(e0b) => e0a == e0b, + _ => false + } + } + t::tag3(e0a, e1a, e2a) => { + match (*other) { + t::tag3(e0b, e1b, e2b) => + e0a == e0b && e1a == e1b && e2a == e2b, + _ => false + } + } + } + } + fn ne(&self, other: &t) -> bool { !(*self).eq(other) } +} + +fn test_tag() { + let (tx, rx) = channel(); + tx.send(t::tag1).unwrap(); + tx.send(t::tag2(10)).unwrap(); + tx.send(t::tag3(10, 11, 'A')).unwrap(); + let mut t1: t; + t1 = rx.recv().unwrap(); + assert_eq!(t1, t::tag1); + t1 = rx.recv().unwrap(); + assert_eq!(t1, t::tag2(10)); + t1 = rx.recv().unwrap(); + assert_eq!(t1, t::tag3(10, 11, 'A')); +} + +fn test_chan() { + let (tx1, rx1) = channel(); + let (tx2, rx2) = channel(); + tx1.send(tx2).unwrap(); + let tx2 = rx1.recv().unwrap(); + // Does the transmitted channel still work? + + tx2.send(10).unwrap(); + let mut i: isize; + i = rx2.recv().unwrap(); + assert_eq!(i, 10); +} + +pub fn main() { + test_rec(); + test_vec(); + test_str(); + test_tag(); + test_chan(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-17.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-17.rs new file mode 100644 index 000000000000..0fecf94aad85 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-17.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support +// pretty-expanded FIXME #23616 + +// Issue #922 + +// This test is specifically about spawning temporary closures. + +use std::thread; + +fn f() { +} + +pub fn main() { + thread::spawn(move|| f() ).join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-3.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-3.rs new file mode 100644 index 000000000000..327250efe9b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-3.rs @@ -0,0 +1,64 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +use std::thread; +use std::sync::mpsc::{channel, Sender}; + +pub fn main() { println!("===== WITHOUT THREADS ====="); test00(); } + +fn test00_start(ch: &Sender, message: isize, count: isize) { + println!("Starting test00_start"); + let mut i: isize = 0; + while i < count { + println!("Sending Message"); + ch.send(message + 0).unwrap(); + i = i + 1; + } + println!("Ending test00_start"); +} + +fn test00() { + let number_of_tasks: isize = 16; + let number_of_messages: isize = 4; + + println!("Creating tasks"); + + let (tx, rx) = channel(); + + let mut i: isize = 0; + + // Create and spawn threads... + let mut results = Vec::new(); + while i < number_of_tasks { + let tx = tx.clone(); + results.push(thread::spawn({ + let i = i; + move|| { + test00_start(&tx, i, number_of_messages) + } + })); + i = i + 1; + } + + // Read from spawned threads... + let mut sum = 0; + for _r in &results { + i = 0; + while i < number_of_messages { + let value = rx.recv().unwrap(); + sum += value; + i = i + 1; + } + } + + // Join spawned threads... + for r in results { r.join(); } + + println!("Completed: Final number is: "); + println!("{}", sum); + // assert (sum == (((number_of_threads * (number_of_threads - 1)) / 2) * + // number_of_messages)); + assert_eq!(sum, 480); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-4.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-4.rs new file mode 100644 index 000000000000..4b38f6668595 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-4.rs @@ -0,0 +1,46 @@ +// run-pass +#![allow(unused_assignments)] + +use std::sync::mpsc::channel; + +pub fn main() { test00(); } + +fn test00() { + let mut r: isize = 0; + let mut sum: isize = 0; + let (tx, rx) = channel(); + tx.send(1).unwrap(); + tx.send(2).unwrap(); + tx.send(3).unwrap(); + tx.send(4).unwrap(); + r = rx.recv().unwrap(); + sum += r; + println!("{}", r); + r = rx.recv().unwrap(); + sum += r; + println!("{}", r); + r = rx.recv().unwrap(); + sum += r; + println!("{}", r); + r = rx.recv().unwrap(); + sum += r; + println!("{}", r); + tx.send(5).unwrap(); + tx.send(6).unwrap(); + tx.send(7).unwrap(); + tx.send(8).unwrap(); + r = rx.recv().unwrap(); + sum += r; + println!("{}", r); + r = rx.recv().unwrap(); + sum += r; + println!("{}", r); + r = rx.recv().unwrap(); + sum += r; + println!("{}", r); + r = rx.recv().unwrap(); + sum += r; + println!("{}", r); + assert_eq!(sum, 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-5.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-5.rs new file mode 100644 index 000000000000..faeb46ef6c54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-5.rs @@ -0,0 +1,18 @@ +// run-pass + +use std::sync::mpsc::channel; + +pub fn main() { test00(); } + +fn test00() { + let _r: isize = 0; + let mut sum: isize = 0; + let (tx, rx) = channel(); + let number_of_messages: isize = 1000; + let mut i: isize = 0; + while i < number_of_messages { tx.send(i + 0).unwrap(); i += 1; } + i = 0; + while i < number_of_messages { sum += rx.recv().unwrap(); i += 1; } + assert_eq!(sum, number_of_messages * (number_of_messages - 1) / 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-6.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-6.rs new file mode 100644 index 000000000000..ed7fe84ad8c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-6.rs @@ -0,0 +1,43 @@ +// run-pass +#![allow(unused_mut)] +#![allow(unused_assignments)] + +use std::sync::mpsc::channel; + +pub fn main() { test00(); } + +fn test00() { + let mut r: isize = 0; + let mut sum: isize = 0; + let (tx, rx) = channel(); + let mut tx0 = tx.clone(); + let mut tx1 = tx.clone(); + let mut tx2 = tx.clone(); + let mut tx3 = tx.clone(); + let number_of_messages: isize = 1000; + let mut i: isize = 0; + while i < number_of_messages { + tx0.send(i + 0).unwrap(); + tx1.send(i + 0).unwrap(); + tx2.send(i + 0).unwrap(); + tx3.send(i + 0).unwrap(); + i += 1; + } + i = 0; + while i < number_of_messages { + r = rx.recv().unwrap(); + sum += r; + r = rx.recv().unwrap(); + sum += r; + r = rx.recv().unwrap(); + sum += r; + r = rx.recv().unwrap(); + sum += r; + i += 1; + } + assert_eq!(sum, 1998000); + // assert (sum == 4 * ((number_of_messages * + // (number_of_messages - 1)) / 2)); + +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-7.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-7.rs new file mode 100644 index 000000000000..c18be40ea8f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-7.rs @@ -0,0 +1,60 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(unused_assignments)] +// ignore-emscripten no threads support + +use std::sync::mpsc::{channel, Sender}; +use std::thread; + +pub fn main() { test00(); } + +fn test00_start(c: &Sender, start: isize, + number_of_messages: isize) { + let mut i: isize = 0; + while i < number_of_messages { c.send(start + i).unwrap(); i += 1; } +} + +fn test00() { + let mut r: isize = 0; + let mut sum: isize = 0; + let (tx, rx) = channel(); + let number_of_messages: isize = 10; + + let tx2 = tx.clone(); + let t1 = thread::spawn(move|| { + test00_start(&tx2, number_of_messages * 0, number_of_messages); + }); + let tx2 = tx.clone(); + let t2 = thread::spawn(move|| { + test00_start(&tx2, number_of_messages * 1, number_of_messages); + }); + let tx2 = tx.clone(); + let t3 = thread::spawn(move|| { + test00_start(&tx2, number_of_messages * 2, number_of_messages); + }); + let tx2 = tx.clone(); + let t4 = thread::spawn(move|| { + test00_start(&tx2, number_of_messages * 3, number_of_messages); + }); + + let mut i: isize = 0; + while i < number_of_messages { + r = rx.recv().unwrap(); + sum += r; + r = rx.recv().unwrap(); + sum += r; + r = rx.recv().unwrap(); + sum += r; + r = rx.recv().unwrap(); + sum += r; + i += 1; + } + + assert_eq!(sum, number_of_messages * 4 * (number_of_messages * 4 - 1) / 2); + + t1.join(); + t2.join(); + t3.join(); + t4.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-9.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-9.rs new file mode 100644 index 000000000000..5e0d25b5b06d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-9.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +use std::thread; +use std::sync::mpsc::{channel, Sender}; + +pub fn main() { test00(); } + +fn test00_start(c: &Sender, number_of_messages: isize) { + let mut i: isize = 0; + while i < number_of_messages { c.send(i + 0).unwrap(); i += 1; } +} + +fn test00() { + let r: isize = 0; + let mut sum: isize = 0; + let (tx, rx) = channel(); + let number_of_messages: isize = 10; + + let result = thread::spawn(move|| { + test00_start(&tx, number_of_messages); + }); + + let mut i: isize = 0; + while i < number_of_messages { + sum += rx.recv().unwrap(); + println!("{}", r); + i += 1; + } + + result.join(); + + assert_eq!(sum, number_of_messages * (number_of_messages - 1) / 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-chan-nil.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-chan-nil.rs new file mode 100644 index 000000000000..1b5a94a2c5ec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-comm-chan-nil.rs @@ -0,0 +1,14 @@ +// run-pass + +use std::sync::mpsc::channel; + +// rustboot can't transmit nils across channels because they don't have +// any size, but rustc currently can because they do have size. Whether +// or not this is desirable I don't know, but here's a regression test. +pub fn main() { + let (tx, rx) = channel(); + tx.send(()).unwrap(); + let n: () = rx.recv().unwrap(); + assert_eq!(n, ()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-life-0.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-life-0.rs new file mode 100644 index 000000000000..214e1138a316 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-life-0.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support +// pretty-expanded FIXME #23616 + +use std::thread; + +pub fn main() { + thread::spawn(move|| child("Hello".to_string()) ).join(); +} + +fn child(_s: String) { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-spawn-barefn.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-spawn-barefn.rs new file mode 100644 index 000000000000..d6fdde7f17c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-spawn-barefn.rs @@ -0,0 +1,19 @@ +// run-fail +// error-pattern:Ensure that the child thread runs by panicking +// ignore-emscripten Needs threads. + +use std::thread; + +fn main() { + // the purpose of this test is to make sure that thread::spawn() + // works when provided with a bare function: + let r = thread::spawn(startfn).join(); + if r.is_err() { + panic!() + } +} + +fn startfn() { + assert!("Ensure that the child thread runs by panicking".is_empty()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-spawn-move-and-copy.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-spawn-move-and-copy.rs new file mode 100644 index 000000000000..0a04d9441b3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-spawn-move-and-copy.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +#![feature(box_syntax)] + +use std::thread; +use std::sync::mpsc::channel; + +pub fn main() { + let (tx, rx) = channel::(); + + let x: Box = box 1; + let x_in_parent = &(*x) as *const isize as usize; + + let t = thread::spawn(move || { + let x_in_child = &(*x) as *const isize as usize; + tx.send(x_in_child).unwrap(); + }); + + let x_in_child = rx.recv().unwrap(); + assert_eq!(x_in_parent, x_in_child); + + t.join(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-stderr.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-stderr.rs new file mode 100644 index 000000000000..752cf39fb39e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/task-stderr.rs @@ -0,0 +1,38 @@ +// run-pass +// ignore-emscripten no threads support + +#![feature(box_syntax, set_stdio)] + +use std::io::prelude::*; +use std::io; +use std::str; +use std::sync::{Arc, Mutex}; +use std::thread; + +struct Sink(Arc>>); +impl Write for Sink { + fn write(&mut self, data: &[u8]) -> io::Result { + Write::write(&mut *self.0.lock().unwrap(), data) + } + fn flush(&mut self) -> io::Result<()> { Ok(()) } +} +impl io::LocalOutput for Sink { + fn clone_box(&self) -> Box { + Box::new(Sink(self.0.clone())) + } +} + +fn main() { + let data = Arc::new(Mutex::new(Vec::new())); + let sink = Sink(data.clone()); + let res = thread::Builder::new().spawn(move|| -> () { + io::set_panic(Some(Box::new(sink))); + panic!("Hello, world!") + }).unwrap().join(); + assert!(res.is_err()); + + let output = data.lock().unwrap(); + let output = str::from_utf8(&output).unwrap(); + assert!(output.contains("Hello, world!")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/test-tasks-invalid-value.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/test-tasks-invalid-value.rs new file mode 100644 index 000000000000..0280f85fc8d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/test-tasks-invalid-value.rs @@ -0,0 +1,12 @@ +// This checks that RUST_TEST_THREADS not being 1, 2, ... is detected +// properly. + +// run-fail +// error-pattern:should be a positive integer +// compile-flags: --test +// exec-env:RUST_TEST_THREADS=foo +// ignore-emscripten + +#[test] +fn do_nothing() {} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/thread-local-extern-static.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/thread-local-extern-static.rs new file mode 100644 index 000000000000..fd9311f3cbf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/thread-local-extern-static.rs @@ -0,0 +1,28 @@ +// run-pass +// ignore-windows +// aux-build:thread-local-extern-static.rs + +#![feature(cfg_target_thread_local, thread_local)] + +#[cfg(target_thread_local)] +extern crate thread_local_extern_static; + +#[cfg(target_thread_local)] +use std::cell::Cell; + +#[cfg(target_thread_local)] +extern { + #[thread_local] + static FOO: Cell; +} + +#[cfg(target_thread_local)] +fn main() { + unsafe { + assert_eq!(FOO.get(), 3); + } +} + +#[cfg(not(target_thread_local))] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/thread-local-syntax.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/thread-local-syntax.rs new file mode 100644 index 000000000000..4e42dd41218a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/thread-local-syntax.rs @@ -0,0 +1,23 @@ +// run-pass +#![deny(missing_docs)] +//! this tests the syntax of `thread_local!` + +mod foo { + mod bar { + thread_local! { + // no docs + #[allow(unused)] + static FOO: i32 = 42; + /// docs + pub static BAR: String = String::from("bar"); + + // look at these restrictions!! + pub(crate) static BAZ: usize = 0; + pub(in foo) static QUUX: usize = 0; + } + thread_local!(static SPLOK: u32 = 0); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/threads.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/threads.rs new file mode 100644 index 000000000000..c2738a9ec383 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/threads.rs @@ -0,0 +1,17 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +use std::thread; + +pub fn main() { + let mut i = 10; + while i > 0 { + thread::spawn({let i = i; move|| child(i)}).join(); + i = i - 1; + } + println!("main thread exiting"); +} + +fn child(x: isize) { println!("{}", x); } + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs new file mode 100644 index 000000000000..b4e52dbf4777 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs @@ -0,0 +1,23 @@ +// run-pass +// no-prefer-dynamic +// ignore-emscripten no threads support + +static mut HIT: bool = false; + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) { + unsafe { HIT = true; } + } +} + +thread_local!(static FOO: Foo = Foo); + +fn main() { + std::thread::spawn(|| { + FOO.with(|_| {}); + }).join().unwrap(); + assert!(unsafe { HIT }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/tls-init-on-init.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/tls-init-on-init.rs new file mode 100644 index 000000000000..699c64d267eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/tls-init-on-init.rs @@ -0,0 +1,45 @@ +// run-pass +#![allow(stable_features)] + +// ignore-emscripten no threads support + +#![feature(thread_local_try_with)] + +use std::thread; +use std::sync::atomic::{AtomicUsize, Ordering}; + +struct Foo { cnt: usize } + +thread_local!(static FOO: Foo = Foo::init()); + +static CNT: AtomicUsize = AtomicUsize::new(0); + +impl Foo { + fn init() -> Foo { + let cnt = CNT.fetch_add(1, Ordering::SeqCst); + if cnt == 0 { + FOO.with(|_| {}); + } + Foo { cnt: cnt } + } +} + +impl Drop for Foo { + fn drop(&mut self) { + if self.cnt == 1 { + FOO.with(|foo| assert_eq!(foo.cnt, 0)); + } else { + assert_eq!(self.cnt, 0); + if FOO.try_with(|_| ()).is_ok() { + panic!("should not be in valid state"); + } + } + } +} + +fn main() { + thread::spawn(|| { + FOO.with(|_| {}); + }).join().unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/threads-sendsync/tls-try-with.rs b/gcc/testsuite/rust/rustc/ui/threads-sendsync/tls-try-with.rs new file mode 100644 index 000000000000..5a0c5ce4c649 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/threads-sendsync/tls-try-with.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(stable_features)] + +// ignore-emscripten no threads support + +#![feature(thread_local_try_with)] + +use std::thread; + +static mut DROP_RUN: bool = false; + +struct Foo; + +thread_local!(static FOO: Foo = Foo {}); + +impl Drop for Foo { + fn drop(&mut self) { + assert!(FOO.try_with(|_| panic!("`try_with` closure run")).is_err()); + unsafe { DROP_RUN = true; } + } +} + +fn main() { + thread::spawn(|| { + assert_eq!(FOO.try_with(|_| { + 132 + }).expect("`try_with` failed"), 132); + }).join().unwrap(); + assert!(unsafe { DROP_RUN }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/tls.rs b/gcc/testsuite/rust/rustc/ui/tls.rs new file mode 100644 index 000000000000..6ebacb6bb178 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tls.rs @@ -0,0 +1,15 @@ +// run-pass +// ignore-emscripten no threads support +// compile-flags: -O + +#![feature(thread_local)] + +#[thread_local] +static S: u32 = 222; + +fn main() { + let local = &S as *const u32 as usize; + let foreign = std::thread::spawn(|| &S as *const u32 as usize).join().unwrap(); + assert_ne!(local, foreign); +} + diff --git a/gcc/testsuite/rust/rustc/ui/tool-attributes/diagnostic_item.rs b/gcc/testsuite/rust/rustc/ui/tool-attributes/diagnostic_item.rs new file mode 100644 index 000000000000..a09183e9b70f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tool-attributes/diagnostic_item.rs @@ -0,0 +1,4 @@ +#[rustc_diagnostic_item = "foomp"] // { dg-error ".E0658." "" { target *-*-* } } +struct Foomp; +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/tool-attributes/diagnostic_item2.rs b/gcc/testsuite/rust/rustc/ui/tool-attributes/diagnostic_item2.rs new file mode 100644 index 000000000000..5e1dab277aee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tool-attributes/diagnostic_item2.rs @@ -0,0 +1,7 @@ +// check-pass + +#[clippy::diagnostic_item = "mep"] +struct Mep; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/tool-attributes/diagnostic_item3.rs b/gcc/testsuite/rust/rustc/ui/tool-attributes/diagnostic_item3.rs new file mode 100644 index 000000000000..25c779b51ad5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tool-attributes/diagnostic_item3.rs @@ -0,0 +1,8 @@ +// check-pass +#![feature(rustc_attrs)] + +#[rustc_diagnostic_item = "foomp"] +struct Foomp; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/tool-attributes/tool-attributes-misplaced-1.rs b/gcc/testsuite/rust/rustc/ui/tool-attributes/tool-attributes-misplaced-1.rs new file mode 100644 index 000000000000..3cda88809333 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tool-attributes/tool-attributes-misplaced-1.rs @@ -0,0 +1,19 @@ +type A = rustfmt; // { dg-error ".E0573." "" { target *-*-* } } +type B = rustfmt::skip; // { dg-error ".E0573." "" { target *-*-* } } + +#[derive(rustfmt)] // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +struct S; + +// Interpreted as an unstable custom attribute +#[rustfmt] // { dg-error "" "" { target *-*-* } } +fn check() {} + +#[rustfmt::skip] // OK +fn main() { + rustfmt; // { dg-error ".E0423." "" { target *-*-* } } + rustfmt!(); // { dg-error "" "" { target *-*-* } } + + rustfmt::skip; // { dg-error ".E0423." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/tool-attributes/tool-attributes-misplaced-2.rs b/gcc/testsuite/rust/rustc/ui/tool-attributes/tool-attributes-misplaced-2.rs new file mode 100644 index 000000000000..40a53c1fad73 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tool-attributes/tool-attributes-misplaced-2.rs @@ -0,0 +1,7 @@ +#[derive(rustfmt::skip)] // { dg-error "" "" { target *-*-* } } +struct S; + +fn main() { + rustfmt::skip!(); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/tool-attributes/tool-attributes-shadowing.rs b/gcc/testsuite/rust/rustc/ui/tool-attributes/tool-attributes-shadowing.rs new file mode 100644 index 000000000000..6987c1f15e83 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tool-attributes/tool-attributes-shadowing.rs @@ -0,0 +1,5 @@ +mod rustfmt {} + +#[rustfmt::skip] // { dg-error ".E0433." "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/tool_attributes.rs b/gcc/testsuite/rust/rustc/ui/tool_attributes.rs new file mode 100644 index 000000000000..67ade7f7c46c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tool_attributes.rs @@ -0,0 +1,14 @@ +// run-pass +// Scoped attributes should not trigger an unused attributes lint. + +#![deny(unused_attributes)] + +fn main() { + #[rustfmt::skip] + foo (); +} + +fn foo() { + assert!(true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/tool_lints-fail.rs b/gcc/testsuite/rust/rustc/ui/tool_lints-fail.rs new file mode 100644 index 000000000000..616b42664cb2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tool_lints-fail.rs @@ -0,0 +1,9 @@ +// Don't allow tool_lints, which aren't scoped + + +#![deny(unknown_lints)] + +#![deny(clippy)] // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/tool_lints-rpass.rs b/gcc/testsuite/rust/rustc/ui/tool_lints-rpass.rs new file mode 100644 index 000000000000..e32d6d798847 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tool_lints-rpass.rs @@ -0,0 +1,7 @@ +// run-pass + +#![deny(unknown_lints)] + +#[allow(clippy::almost_swapped)] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/tool_lints.rs b/gcc/testsuite/rust/rustc/ui/tool_lints.rs new file mode 100644 index 000000000000..12d46e406274 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tool_lints.rs @@ -0,0 +1,6 @@ +#[warn(foo::bar)] +// { dg-error ".E0710." "" { target *-*-* } .-1 } +// { dg-error ".E0710." "" { target *-*-* } .-2 } +// { dg-error ".E0710." "" { target *-*-* } .-3 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/tool_lints_2018_preview.rs b/gcc/testsuite/rust/rustc/ui/tool_lints_2018_preview.rs new file mode 100644 index 000000000000..01a56aba0aa7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tool_lints_2018_preview.rs @@ -0,0 +1,8 @@ +// run-pass + +#![feature(rust_2018_preview)] +#![deny(unknown_lints)] + +#[allow(clippy::almost_swapped)] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/trace_macros-format.rs b/gcc/testsuite/rust/rustc/ui/trace_macros-format.rs new file mode 100644 index 000000000000..57314696792e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trace_macros-format.rs @@ -0,0 +1,19 @@ +#![feature(trace_macros)] + +fn main() { + trace_macros!(); // { dg-error "" "" { target *-*-* } } + trace_macros!(1); // { dg-error "" "" { target *-*-* } } + trace_macros!(ident); // { dg-error "" "" { target *-*-* } } + trace_macros!(for); // { dg-error "" "" { target *-*-* } } + trace_macros!(true,); // { dg-error "" "" { target *-*-* } } + trace_macros!(false 1); // { dg-error "" "" { target *-*-* } } + + + // should be fine: + macro_rules! expando { + ($x: ident) => { trace_macros!($x) } + } + + expando!(true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/trace_macros-gate.rs b/gcc/testsuite/rust/rustc/ui/trace_macros-gate.rs new file mode 100644 index 000000000000..56c499b2e74f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trace_macros-gate.rs @@ -0,0 +1,15 @@ +// Test that the trace_macros feature gate is on. + +fn main() { + trace_macros!(); // { dg-error ".E0658." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + trace_macros!(true); // { dg-error ".E0658." "" { target *-*-* } } + trace_macros!(false); // { dg-error ".E0658." "" { target *-*-* } } + + macro_rules! expando { + ($x: ident) => { trace_macros!($x) } // { dg-error ".E0658." "" { target *-*-* } } + } + + expando!(true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/trailing-comma.rs b/gcc/testsuite/rust/rustc/ui/trailing-comma.rs new file mode 100644 index 000000000000..72d44da310d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trailing-comma.rs @@ -0,0 +1,36 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn f(_: T,) {} + +struct Foo(T); + +struct Bar; + +impl Bar { + fn f(_: isize,) {} + fn g(self, _: isize,) {} + fn h(self,) {} +} + +enum Baz { + Qux(isize,), +} + +#[allow(unused,)] +pub fn main() { + f::(0,); + let (_, _,) = (1, 1,); + let [_, _,] = [1, 1,]; + let [_, _, .., _,] = [1, 1, 1, 1,]; + let [_, _, _, ..,] = [1, 1, 1, 1,]; + + let x: Foo = Foo::(1); + + Bar::f(0,); + Bar.g(0,); + Bar.h(); + + let x = Baz::Qux(1,); +} + diff --git a/gcc/testsuite/rust/rustc/ui/trait-impl-bound-suggestions.rs b/gcc/testsuite/rust/rustc/ui/trait-impl-bound-suggestions.rs new file mode 100644 index 000000000000..fc2da90c1c87 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trait-impl-bound-suggestions.rs @@ -0,0 +1,21 @@ +// run-rustfix + +#[allow(unused)] +use std::fmt::Debug; +// Rustfix should add this, or use `std::fmt::Debug` instead. + +#[allow(dead_code)] +struct ConstrainedStruct { + x: X +} + +#[allow(dead_code)] +trait InsufficientlyConstrainedGeneric { + fn return_the_constrained_type(&self, x: X) -> ConstrainedStruct { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + ConstrainedStruct { x } + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/trait-method-number-parameters.rs b/gcc/testsuite/rust/rustc/ui/trait-method-number-parameters.rs new file mode 100644 index 000000000000..70bf9fbb07bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trait-method-number-parameters.rs @@ -0,0 +1,14 @@ +trait Foo { + fn foo(&mut self, x: i32, y: i32) -> i32; +} + +impl Foo for i32 { + fn foo( + &mut self, // { dg-error ".E0050." "" { target *-*-* } } + x: i32, + ) { + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/anon-trait-static-method.rs b/gcc/testsuite/rust/rustc/ui/traits/anon-trait-static-method.rs new file mode 100644 index 000000000000..4d5ea0cf80e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/anon-trait-static-method.rs @@ -0,0 +1,16 @@ +// run-pass +struct Foo { + x: isize +} + +impl Foo { + pub fn new() -> Foo { + Foo { x: 3 } + } +} + +pub fn main() { + let x = Foo::new(); + println!("{}", x.x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/anon_trait_static_method_exe.rs b/gcc/testsuite/rust/rustc/ui/traits/anon_trait_static_method_exe.rs new file mode 100644 index 000000000000..1e1eca0b0b37 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/anon_trait_static_method_exe.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(non_camel_case_types)] + +// aux-build:anon_trait_static_method_lib.rs + +extern crate anon_trait_static_method_lib; +use anon_trait_static_method_lib::Foo; + +pub fn main() { + let x = Foo::new(); + println!("{}", x.x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/assignability-trait.rs b/gcc/testsuite/rust/rustc/ui/traits/assignability-trait.rs new file mode 100644 index 000000000000..db63d90981b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/assignability-trait.rs @@ -0,0 +1,48 @@ +// run-pass +#![allow(non_camel_case_types)] + +// Tests that type assignability is used to search for instances when +// making method calls, but only if there aren't any matches without +// it. + +trait iterable { + fn iterate(&self, blk: F) -> bool where F: FnMut(&A) -> bool; +} + +impl<'a,A> iterable for &'a [A] { + fn iterate(&self, f: F) -> bool where F: FnMut(&A) -> bool { + self.iter().all(f) + } +} + +impl iterable for Vec { + fn iterate(&self, f: F) -> bool where F: FnMut(&A) -> bool { + self.iter().all(f) + } +} + +fn length>(x: T) -> usize { + let mut len = 0; + x.iterate(|_y| { + len += 1; + true + }); + return len; +} + +pub fn main() { + let x: Vec = vec![0,1,2,3]; + // Call a method + x.iterate(|y| { assert_eq!(x[*y as usize], *y); true }); + // Call a parameterized function + assert_eq!(length(x.clone()), x.len()); + // Call a parameterized function, with type arguments that require + // a borrow + assert_eq!(length::(&*x), x.len()); + + // Now try it with a type that *needs* to be borrowed + let z = [0,1,2,3]; + // Call a parameterized function + assert_eq!(length::(&z), z.len()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/assoc_type_bound_with_struct.rs b/gcc/testsuite/rust/rustc/ui/traits/assoc_type_bound_with_struct.rs new file mode 100644 index 000000000000..197d71aeb787 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/assoc_type_bound_with_struct.rs @@ -0,0 +1,20 @@ +trait Bar { + type Baz; +} + +struct Foo where T: Bar, ::Baz: String { // { dg-error ".E0404." "" { target *-*-* } } + t: T, +} + +struct Qux<'a, T> where T: Bar, <&'a T as Bar>::Baz: String { // { dg-error ".E0404." "" { target *-*-* } } + t: &'a T, +} + +fn foo(_: T) where ::Baz: String { // { dg-error ".E0404." "" { target *-*-* } } +} + +fn qux<'a, T: Bar>(_: &'a T) where <&'a T as Bar>::Baz: String { // { dg-error ".E0404." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/astconv-cycle-between-trait-and-type.rs b/gcc/testsuite/rust/rustc/ui/traits/astconv-cycle-between-trait-and-type.rs new file mode 100644 index 000000000000..ba0ac822bcec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/astconv-cycle-between-trait-and-type.rs @@ -0,0 +1,30 @@ +// run-pass +// Test that we are able to successfully compile a setup where a trait +// (`Trait1`) references a struct (`SomeType`) which in turn +// carries a predicate that references the trait (`u32 : Trait1`, +// substituted). + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +trait Trait1 : Trait2> { + fn dumb(&self) { } +} + +trait Trait2 { + fn dumber(&self, _: A) { } +} + +struct SomeType + where A : Trait1 +{ + a: A +} + +impl Trait1 for u32 { } + +impl Trait2> for u32 { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/augmented-assignments-trait.rs b/gcc/testsuite/rust/rustc/ui/traits/augmented-assignments-trait.rs new file mode 100644 index 000000000000..695128d38b65 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/augmented-assignments-trait.rs @@ -0,0 +1,13 @@ +// run-pass +use std::ops::AddAssign; + +struct Int(i32); + +impl AddAssign for Int { + fn add_assign(&mut self, _: Int) { + unimplemented!() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/anon_trait_static_method_lib.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/anon_trait_static_method_lib.rs new file mode 100644 index 000000000000..44ebf71c0ec4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/anon_trait_static_method_lib.rs @@ -0,0 +1,10 @@ +pub struct Foo { + pub x: isize +} + +impl Foo { + pub fn new() -> Foo { + Foo { x: 3 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/crate_a1.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/crate_a1.rs new file mode 100644 index 000000000000..36850bb521af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/crate_a1.rs @@ -0,0 +1,10 @@ +pub trait Bar {} + +pub fn try_foo(x: impl Bar) {} + +pub struct ImplementsTraitForUsize { + _marker: std::marker::PhantomData, +} + +impl Bar for ImplementsTraitForUsize {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/crate_a2.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/crate_a2.rs new file mode 100644 index 000000000000..29536ad51aa9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/crate_a2.rs @@ -0,0 +1,14 @@ +pub struct Foo; + +pub trait Bar {} + +impl Bar for Foo {} + +pub struct DoesNotImplementTrait; + +pub struct ImplementsWrongTraitConditionally { + _marker: std::marker::PhantomData, +} + +impl Bar for ImplementsWrongTraitConditionally {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/go_trait.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/go_trait.rs new file mode 100644 index 000000000000..fa6463468673 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/go_trait.rs @@ -0,0 +1,44 @@ +#![feature(specialization)] + +// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy. + +pub trait Go { + fn go(&self, arg: isize); +} + +pub fn go(this: &G, arg: isize) { + this.go(arg) +} + +pub trait GoMut { + fn go_mut(&mut self, arg: isize); +} + +pub fn go_mut(this: &mut G, arg: isize) { + this.go_mut(arg) +} + +pub trait GoOnce { + fn go_once(self, arg: isize); +} + +pub fn go_once(this: G, arg: isize) { + this.go_once(arg) +} + +impl GoMut for G + where G : Go +{ + default fn go_mut(&mut self, arg: isize) { + go(&*self, arg) + } +} + +impl GoOnce for G + where G : GoMut +{ + default fn go_once(mut self, arg: isize) { + go_mut(&mut self, arg) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_alias.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_alias.rs new file mode 100644 index 000000000000..e8342db9c650 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_alias.rs @@ -0,0 +1,14 @@ +#![feature(trait_alias)] + +pub trait Hello { + fn hello(&self); +} + +pub struct Hi; + +impl Hello for Hi { + fn hello(&self) {} +} + +pub trait Greet = Hello; + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_bounds_on_structs_and_enums_xc.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_bounds_on_structs_and_enums_xc.rs new file mode 100644 index 000000000000..1a6ca2868c55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_bounds_on_structs_and_enums_xc.rs @@ -0,0 +1,14 @@ +pub trait Trait { + fn dummy(&self) { } +} + +pub struct Foo { + pub x: T, +} + +pub enum Bar { + ABar(isize), + BBar(T), + CBar(usize), +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_default_method_xc_aux.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_default_method_xc_aux.rs new file mode 100644 index 000000000000..3108dd8e815b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_default_method_xc_aux.rs @@ -0,0 +1,41 @@ +pub struct Something { pub x: isize } + +pub trait A { + fn f(&self) -> isize; + fn g(&self) -> isize { 10 } + fn h(&self) -> isize { 11 } + fn lurr(x: &Self, y: &Self) -> isize { x.g() + y.h() } +} + + +impl A for isize { + fn f(&self) -> isize { 10 } +} + +impl A for Something { + fn f(&self) -> isize { 10 } +} + +pub trait B { + fn thing(&self, x: T, y: U) -> (T, U) { (x, y) } + fn staticthing(_z: &Self, x: T, y: U) -> (T, U) { (x, y) } +} + +impl B for isize { } +impl B for bool { } + + + +pub trait TestEquality { + fn test_eq(&self, rhs: &Self) -> bool; + fn test_neq(&self, rhs: &Self) -> bool { + !self.test_eq(rhs) + } +} + +impl TestEquality for isize { + fn test_eq(&self, rhs: &isize) -> bool { + *self == *rhs + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_default_method_xc_aux_2.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_default_method_xc_aux_2.rs new file mode 100644 index 000000000000..ddb5787cc2ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_default_method_xc_aux_2.rs @@ -0,0 +1,18 @@ +// aux-build:trait_default_method_xc_aux.rs + +extern crate trait_default_method_xc_aux as aux; +use aux::A; + +pub struct a_struct { pub x: isize } + +impl A for a_struct { + fn f(&self) -> isize { 10 } +} + +// This function will need to get inlined, and badness may result. +pub fn welp(x: A) -> A { + let a = a_struct { x: 0 }; + a.g(); + x +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs new file mode 100644 index 000000000000..04f14ec20689 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_inheritance_auto_xc_2_aux.rs @@ -0,0 +1,10 @@ +pub trait Foo { fn f(&self) -> isize; } +pub trait Bar { fn g(&self) -> isize; } +pub trait Baz { fn h(&self) -> isize; } + +pub struct A { pub x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } +impl Baz for A { fn h(&self) -> isize { 30 } } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_inheritance_auto_xc_aux.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_inheritance_auto_xc_aux.rs new file mode 100644 index 000000000000..6136683d05d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_inheritance_auto_xc_aux.rs @@ -0,0 +1,8 @@ +pub trait Foo { fn f(&self) -> isize; } +pub trait Bar { fn g(&self) -> isize; } +pub trait Baz { fn h(&self) -> isize; } + +pub trait Quux: Foo + Bar + Baz { } + +impl Quux for T { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_inheritance_overloading_xc.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_inheritance_overloading_xc.rs new file mode 100644 index 000000000000..0a8e6d27cf60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_inheritance_overloading_xc.rs @@ -0,0 +1,39 @@ +use std::cmp::PartialEq; +use std::ops::{Add, Sub, Mul}; + +pub trait MyNum : Add + Sub + Mul + PartialEq + Clone { +} + +#[derive(Clone, Debug)] +pub struct MyInt { + pub val: isize +} + +impl Add for MyInt { + type Output = MyInt; + + fn add(self, other: MyInt) -> MyInt { mi(self.val + other.val) } +} + +impl Sub for MyInt { + type Output = MyInt; + + fn sub(self, other: MyInt) -> MyInt { mi(self.val - other.val) } +} + +impl Mul for MyInt { + type Output = MyInt; + + fn mul(self, other: MyInt) -> MyInt { mi(self.val * other.val) } +} + +impl PartialEq for MyInt { + fn eq(&self, other: &MyInt) -> bool { self.val == other.val } + + fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } +} + +impl MyNum for MyInt {} + +fn mi(v: isize) -> MyInt { MyInt { val: v } } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_safety_lib.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_safety_lib.rs new file mode 100644 index 000000000000..e70337931a66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_safety_lib.rs @@ -0,0 +1,10 @@ +// Simple smoke test that unsafe traits can be compiled etc. + +pub unsafe trait Foo { + fn foo(&self) -> isize; +} + +unsafe impl Foo for isize { + fn foo(&self) -> isize { *self } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_xc_call_aux.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_xc_call_aux.rs new file mode 100644 index 000000000000..375acfb48b00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/trait_xc_call_aux.rs @@ -0,0 +1,12 @@ +pub trait Foo { + fn f(&self) -> isize; +} + +pub struct A { + pub x: isize +} + +impl Foo for A { + fn f(&self) -> isize { 10 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/auxiliary/traitimpl.rs b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/traitimpl.rs new file mode 100644 index 000000000000..a1a7454484ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/auxiliary/traitimpl.rs @@ -0,0 +1,8 @@ +// Test inherent trait impls work cross-crait. + +pub trait Bar<'a> : 'a {} + +impl<'a> Bar<'a> { + pub fn bar(&self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-1.rs b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-1.rs new file mode 100644 index 000000000000..4d0935cc6778 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-1.rs @@ -0,0 +1,15 @@ +// Check that we validate associated type bounds for trait objects + +trait X { + type Y: Clone; +} + +fn f() { + None::.clone(); +} + +fn main() { + f::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-2-ok.rs b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-2-ok.rs new file mode 100644 index 000000000000..341c097f7391 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-2-ok.rs @@ -0,0 +1,16 @@ +// Make sure that we're handling bound lifetimes correctly when validating trait +// bounds. +// run-pass + +trait X<'a> { + type F: FnOnce(&i32) -> &'a i32; +} + +fn f X<'r> + ?Sized>() { + None::.map(|f| f(&0)); +} + +fn main() { + f:: X<'x, F = fn(&i32) -> &'x i32>>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-2.rs b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-2.rs new file mode 100644 index 000000000000..016f19bb82db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-2.rs @@ -0,0 +1,16 @@ +// Check that we validate associated type bounds for trait objects when they +// have bound lifetimes + +trait X<'a> { + type F: FnOnce(&i32) -> &'a i32; +} + +fn f X<'r> + ?Sized>() { + None::.map(|f| f(&0)); +} + +fn main() { + f:: X<'x, F = i32>>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-3.rs b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-3.rs new file mode 100644 index 000000000000..24d1748c80fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-3.rs @@ -0,0 +1,21 @@ +// Check that we validate associated type bounds for trait objects + +trait X<'a> { + type Y: Into<&'static str> + From<&'a str>; +} + +fn f<'a, T: X<'a> + ?Sized>(s: &'a str) -> &'static str { + T::Y::from(s).into() +} + +pub fn main() { + let z; + { + let s = String::from("abcdef"); + z = f::>(&s); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + } + + println!("{}", z) +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-4.rs b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-4.rs new file mode 100644 index 000000000000..3068b826cef2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-4.rs @@ -0,0 +1,18 @@ +// Check that we validate associated type bounds on super traits for trait +// objects + +trait Super { + type Y: Clone; +} + +trait X: Super {} + +fn f() { + None::.clone(); +} + +fn main() { + f::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-5.rs b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-5.rs new file mode 100644 index 000000000000..7f074303b9e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-5.rs @@ -0,0 +1,28 @@ +// Check that we validate associated type bounds on super traits for trait +// objects + +trait Is { + type T; +} + +impl Is for U { + type T = U; +} + +trait Super { + type V; +} + +trait Obj: Super { + type U: Is; +} + +fn is_obj(_: &T) {} + +fn f(x: &dyn Obj) { + is_obj(x) +// { dg-error ".E0271." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-6.rs b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-6.rs new file mode 100644 index 000000000000..b762322721d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/check-trait-object-bounds-6.rs @@ -0,0 +1,25 @@ +// Check that we validate associated type bounds on super traits for trait +// objects + +trait Is { + type T; +} + +impl Is for U { + type T = U; +} + +trait Obj { + type U: Is; + type V; +} + +fn is_obj(_: &T) {} + +fn f(x: &dyn Obj) { + is_obj(x) +// { dg-error ".E0271." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/conservative_impl_trait.rs b/gcc/testsuite/rust/rustc/ui/traits/conservative_impl_trait.rs new file mode 100644 index 000000000000..de281fc675f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/conservative_impl_trait.rs @@ -0,0 +1,9 @@ +// build-pass (FIXME(62277): could be check-pass?) +// #39665 + +fn batches(n: &u32) -> impl Iterator { + std::iter::once(n) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/cycle-cache-err-60010.rs b/gcc/testsuite/rust/rustc/ui/traits/cycle-cache-err-60010.rs new file mode 100644 index 000000000000..d3123e599c32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/cycle-cache-err-60010.rs @@ -0,0 +1,75 @@ +// Test that we properly detect the cycle amongst the traits +// here and report an error. + +use std::panic::RefUnwindSafe; + +trait Database { + type Storage; +} +trait HasQueryGroup {} +trait Query { + type Data; +} +trait SourceDatabase { + fn parse(&self) { + loop {} + } +} + +struct ParseQuery; +struct RootDatabase { + _runtime: Runtime, +} +struct Runtime { + _storage: Box, +} +struct SalsaStorage { + _parse: >::Data, +} + +impl Database for RootDatabase { + // This would also be an error if we didn't abort compilation on the error + // above. + type Storage = SalsaStorage; +} +impl HasQueryGroup for RootDatabase {} +impl Query for ParseQuery +where + DB: SourceDatabase, + DB: Database, +{ + type Data = RootDatabase; +} +impl SourceDatabase for T +where + T: RefUnwindSafe, + T: HasQueryGroup, +{ +} + +pub(crate) fn goto_implementation(db: &RootDatabase) -> u32 { + // This is not satisfied: + // + // - `RootDatabase: SourceDatabase` + // - requires `RootDatabase: RefUnwindSafe` + `RootDatabase: HasQueryGroup` + // - `RootDatabase: RefUnwindSafe` + // - requires `Runtime: RefUnwindSafe` + // - `Runtime: RefUnwindSafe` + // - requires `DB::Storage: RefUnwindSafe` (`SalsaStorage: RefUnwindSafe`) + // - `SalsaStorage: RefUnwindSafe` + // - requires `>::Data: RefUnwindSafe`, + // which means `ParseQuery: Query` + // - `ParseQuery: Query` + // - requires `RootDatabase: SourceDatabase`, + // - `RootDatabase: SourceDatabase` is already on the stack, so we have a + // cycle with non-coinductive participants + // + // we used to fail to report an error here because we got the + // caching wrong. + SourceDatabase::parse(db); +// { dg-error ".E0275." "" { target *-*-* } .-1 } + 22 +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/cycle-trait-type-trait.rs b/gcc/testsuite/rust/rustc/ui/traits/cycle-trait-type-trait.rs new file mode 100644 index 000000000000..99193e68726a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/cycle-trait-type-trait.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +// Test a case where a supertrait references a type that references +// the original trait. This poses no problem at the moment. + +// pretty-expanded FIXME #23616 + +trait Chromosome: Get> { +} + +trait Get { + fn get(&self) -> A; +} + +struct Struct { c: C } + +impl Chromosome for i32 { } + +impl Get> for i32 { + fn get(&self) -> Struct { + Struct { c: *self } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/default-method-supertrait-vtable.rs b/gcc/testsuite/rust/rustc/ui/traits/default-method-supertrait-vtable.rs new file mode 100644 index 000000000000..cff00ded613d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/default-method-supertrait-vtable.rs @@ -0,0 +1,29 @@ +// run-pass + + +// Tests that we can call a function bounded over a supertrait from +// a default method + +fn require_y(x: T) -> isize { x.y() } + +trait Y { + fn y(self) -> isize; +} + + +trait Z: Y + Sized { + fn x(self) -> isize { + require_y(self) + } +} + +impl Y for isize { + fn y(self) -> isize { self } +} + +impl Z for isize {} + +pub fn main() { + assert_eq!(12.x(), 12); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/dyn-trait.rs b/gcc/testsuite/rust/rustc/ui/traits/dyn-trait.rs new file mode 100644 index 000000000000..74af7757bf1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/dyn-trait.rs @@ -0,0 +1,18 @@ +// run-pass +// ignore-pretty `dyn ::foo` parses differently in the current edition + +use std::fmt::Display; + +static BYTE: u8 = 33; + +fn main() { + let x: &(dyn 'static + Display) = &BYTE; + let y: Box = Box::new(BYTE); + let _: &dyn (Display) = &BYTE; + let _: &dyn (::std::fmt::Display) = &BYTE; + let xstr = format!("{}", x); + let ystr = format!("{}", y); + assert_eq!(xstr, "33"); + assert_eq!(ystr, "33"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/fmt-pointer-trait.rs b/gcc/testsuite/rust/rustc/ui/traits/fmt-pointer-trait.rs new file mode 100644 index 000000000000..eb8c86aee612 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/fmt-pointer-trait.rs @@ -0,0 +1,25 @@ +// run-pass +use std::ptr; +use std::rc::Rc; +use std::sync::Arc; + +fn main() { + let p: *const u8 = ptr::null(); + let rc = Rc::new(1usize); + let arc = Arc::new(1usize); + let b = Box::new("hi"); + + let _ = format!("{:p}{:p}{:p}", + rc, arc, b); + + if cfg!(target_pointer_width = "32") { + assert_eq!(format!("{:#p}", p), + "0x00000000"); + } else { + assert_eq!(format!("{:#p}", p), + "0x0000000000000000"); + } + assert_eq!(format!("{:p}", p), + "0x0"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/impl-evaluation-order.rs b/gcc/testsuite/rust/rustc/ui/traits/impl-evaluation-order.rs new file mode 100644 index 000000000000..81ac24b9ce0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/impl-evaluation-order.rs @@ -0,0 +1,40 @@ +// Regression test for #79902 + +// Check that evaluation (which is used to determine whether to copy a type in +// MIR building) evaluates bounds from normalizing an impl after evaluating +// any bounds on the impl. + +// check-pass + +trait A { + type B; +} +trait M {} + +struct G(*const T, *const U); + +impl Clone for G { + fn clone(&self) -> Self { + G { ..*self } + } +} + +impl Copy for G +where + T: A, + U: A, +{ +} + +impl A for () { + type B = (); +} + +fn is_m(_: T) {} + +fn main() { + let x = G(&(), &()); + drop(x); + drop(x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/impl-implicit-trait.rs b/gcc/testsuite/rust/rustc/ui/traits/impl-implicit-trait.rs new file mode 100644 index 000000000000..9f2128de001d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/impl-implicit-trait.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +enum option_ { + none_, + some_(T), +} + +impl option_ { + pub fn foo(&self) -> bool { true } +} + +enum option__ { + none__, + some__(isize) +} + +impl option__ { + pub fn foo(&self) -> bool { true } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/impl-inherent-prefer-over-trait.rs b/gcc/testsuite/rust/rustc/ui/traits/impl-inherent-prefer-over-trait.rs new file mode 100644 index 000000000000..b3450be3f49a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/impl-inherent-prefer-over-trait.rs @@ -0,0 +1,31 @@ +// run-pass + +struct Foo; + +trait Trait { + fn bar(&self); +} + +// Inherent impls should be preferred over trait ones. +impl Foo { + fn bar(&self) {} +} + +impl dyn Trait { + fn baz(_: &Foo) {} +} + +impl Trait for Foo { + fn bar(&self) { panic!("wrong method called!") } +} + +fn main() { + Foo.bar(); + Foo::bar(&Foo); + ::bar(&Foo); + + // Should work even if Trait::baz doesn't exist. + // N.B: `::bar` would be ambiguous. + ::baz(&Foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/impl_trait_as_trait_return_position.rs b/gcc/testsuite/rust/rustc/ui/traits/impl_trait_as_trait_return_position.rs new file mode 100644 index 000000000000..b826898d9b28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/impl_trait_as_trait_return_position.rs @@ -0,0 +1,18 @@ +// check-pass + +trait A { + type Foo; +} + +impl A for T { + type Foo = (); +} + +fn foo() -> impl std::borrow::Borrow<::Foo> { + () +} + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/infer-from-object-trait-issue-26952.rs b/gcc/testsuite/rust/rustc/ui/traits/infer-from-object-trait-issue-26952.rs new file mode 100644 index 000000000000..cdc1d27dc168 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/infer-from-object-trait-issue-26952.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test that when we match a trait reference like `Foo: Foo<_#0t>`, +// we unify with `_#0t` with `A`. In this code, if we failed to do +// that, then you get an unconstrained type-variable in `call`. +// +// Also serves as a regression test for issue #26952, though the test +// was derived from another reported regression with the same cause. + +use std::marker::PhantomData; + +trait Trait { fn foo(&self); } + +struct Type { a: PhantomData } + +fn as_trait(t: &Type) -> &dyn Trait { loop { } } + +fn want+?Sized>(t: &T) { } + +fn call(p: Type) { + let q = as_trait(&p); + want(q); // parameter A to `want` *would* be unconstrained +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/inherent-trait-method-order.rs b/gcc/testsuite/rust/rustc/ui/traits/inherent-trait-method-order.rs new file mode 100644 index 000000000000..bf27bd8dd732 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/inherent-trait-method-order.rs @@ -0,0 +1,26 @@ +// run-pass + +struct Foo; + +impl Foo { + #[allow(dead_code)] + fn foo(self) { + panic!("wrong method!") + } +} + +trait Trait { + fn foo(self); +} + +impl<'a,'b,'c> Trait for &'a &'b &'c Foo { + fn foo(self) { + // ok + } +} + +fn main() { + let x = &(&(&Foo)); + x.foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/issue-70944.rs b/gcc/testsuite/rust/rustc/ui/traits/issue-70944.rs new file mode 100644 index 000000000000..ff2c35932adf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/issue-70944.rs @@ -0,0 +1,24 @@ +// check-pass +// Regression test of #70944, should compile fine. + +use std::ops::Index; + +pub struct KeyA; +pub struct KeyB; +pub struct KeyC; + +pub trait Foo: Index + Index + Index {} +pub trait FooBuilder { + type Inner: Foo; + fn inner(&self) -> &Self::Inner; +} + +pub fn do_stuff(foo: &impl FooBuilder) { + let inner = foo.inner(); + &inner[KeyA]; + &inner[KeyB]; + &inner[KeyC]; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/issue-72410.rs b/gcc/testsuite/rust/rustc/ui/traits/issue-72410.rs new file mode 100644 index 000000000000..0975fbcf5d97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/issue-72410.rs @@ -0,0 +1,19 @@ +// Regression test for #72410, this should be used with debug assertion enabled. + +// should be fine +pub trait Foo { + fn map() + where + Self: Sized, + for<'a> &'a mut [u8]: ; +} + +// should fail +pub trait Bar { + fn map() + where for<'a> &'a mut [dyn Bar]: ; +// { dg-error ".E0038." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/issue-75627.rs b/gcc/testsuite/rust/rustc/ui/traits/issue-75627.rs new file mode 100644 index 000000000000..b65a3323494c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/issue-75627.rs @@ -0,0 +1,7 @@ +struct Foo(T, *const ()); + +unsafe impl Send for Foo {} +// { dg-error ".E0412." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/issue-77982.rs b/gcc/testsuite/rust/rustc/ui/traits/issue-77982.rs new file mode 100644 index 000000000000..27eca32e1a8d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/issue-77982.rs @@ -0,0 +1,41 @@ +use std::collections::HashMap; + +fn what() { + let descr = String::new(); + let mut opts = HashMap::::new(); + let opt = String::new(); + + opts.get(opt.as_ref()); // { dg-error ".E0283." "" { target *-*-* } } +} + +fn main() { + let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); +// { dg-error ".E0283." "" { target *-*-* } .-1 } +} + +trait Foo<'a, T: ?Sized> { + fn foo(&self) -> Box { + todo!() + } +} + +trait Bar<'a, T: ?Sized> { + fn bar(&self) -> Box { + todo!() + } +} + +impl Foo<'static, u32> for () {} +impl<'a> Foo<'a, i16> for () {} + +impl<'a> Bar<'static, u32> for &'a () {} +impl<'a> Bar<'a, i16> for &'a () {} + +fn foo() { + let _ = ().foo(); // { dg-error ".E0283." "" { target *-*-* } } +} + +fn bar() { + let _ = (&()).bar(); // { dg-error ".E0283." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/kindck-owned-trait-contains-1.rs b/gcc/testsuite/rust/rustc/ui/traits/kindck-owned-trait-contains-1.rs new file mode 100644 index 000000000000..04df14c38d36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/kindck-owned-trait-contains-1.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(non_snake_case)] +#![allow(non_camel_case_types)] + +#![feature(box_syntax)] + +trait repeat { fn get(&self) -> A; } + +impl repeat for Box { + fn get(&self) -> A { + (**self).clone() + } +} + +fn repeater(v: Box) -> Box+'static> { + box v as Box+'static> // No +} + +pub fn main() { + let x = 3; + let y = repeater(box x); + assert_eq!(x, y.get()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/multiple-trait-bounds.rs b/gcc/testsuite/rust/rustc/ui/traits/multiple-trait-bounds.rs new file mode 100644 index 000000000000..22132129011e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/multiple-trait-bounds.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn f(_: T) { +} + +pub fn main() { + f(3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/auxiliary/foreign_trait.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/auxiliary/foreign_trait.rs new file mode 100644 index 000000000000..4a4cdfb08183 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/auxiliary/foreign_trait.rs @@ -0,0 +1,7 @@ +#![feature(negative_impls)] + +pub trait ForeignTrait {} + +impl ForeignTrait for u32 {} +impl !ForeignTrait for String {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/feature-gate-negative_impls.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/feature-gate-negative_impls.rs new file mode 100644 index 000000000000..064b4f5083f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/feature-gate-negative_impls.rs @@ -0,0 +1,4 @@ +trait MyTrait {} +impl !MyTrait for u32 {} // { dg-error ".E0658." "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negated-auto-traits-error.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negated-auto-traits-error.rs new file mode 100644 index 000000000000..55eee42598bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negated-auto-traits-error.rs @@ -0,0 +1,69 @@ +// The dummy functions are used to avoid adding new cfail files. +// What happens is that the compiler attempts to squash duplicates and some +// errors are not reported. This way, we make sure that, for each function, different +// typeck phases are involved and all errors are reported. + +#![feature(negative_impls)] + +use std::marker::Send; + +struct Outer(T); + +struct Outer2(T); + +unsafe impl Sync for Outer2 {} + +fn is_send(_: T) {} +fn is_sync(_: T) {} + +fn dummy() { + struct TestType; + impl !Send for TestType {} + + Outer(TestType); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + +fn dummy1b() { + struct TestType; + impl !Send for TestType {} + + is_send(TestType); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn dummy1c() { + struct TestType; + impl !Send for TestType {} + + is_send((8, TestType)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn dummy2() { + struct TestType; + impl !Send for TestType {} + + is_send(Box::new(TestType)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn dummy3() { + struct TestType; + impl !Send for TestType {} + + is_send(Box::new(Outer2(TestType))); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { + struct TestType; + impl !Send for TestType {} + + // This will complain about a missing Send impl because `Sync` is implement *just* + // for T that are `Send`. Look at #20366 and #19950 + is_sync(Outer2(TestType)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negated-auto-traits-rpass.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negated-auto-traits-rpass.rs new file mode 100644 index 000000000000..354b853387e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negated-auto-traits-rpass.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(unused_variables)] +#![feature(negative_impls)] + +use std::marker::Send; + +pub struct WaitToken; +impl !Send for WaitToken {} + +pub struct Test(T); +unsafe impl Send for Test {} + +pub fn spawn(_: F) -> () where F: FnOnce(), F: Send + 'static {} + +fn main() { + let wt = Test(WaitToken); + spawn(move || { + let x = wt; + println!("Hello, World!"); + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-default-impls.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-default-impls.rs new file mode 100644 index 000000000000..bd2ea64d0a9a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-default-impls.rs @@ -0,0 +1,12 @@ +#![feature(negative_impls)] +#![feature(specialization)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait MyTrait { + type Foo; +} + +default impl !MyTrait for u32 {} // { dg-error ".E0750." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-impls-basic.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-impls-basic.rs new file mode 100644 index 000000000000..19dd111bcce7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-impls-basic.rs @@ -0,0 +1,18 @@ +// A simple test that we are able to create negative impls, when the +// feature gate is given. +// +// run-pass + +#![feature(negative_impls)] +#![allow(dead_code)] + +struct TestType; + +trait TestTrait { + fn dummy(&self) {} +} + +impl !TestTrait for TestType {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-specializes-negative.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-specializes-negative.rs new file mode 100644 index 000000000000..440a51e918d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-specializes-negative.rs @@ -0,0 +1,14 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } +#![feature(negative_impls)] + +// Test a negative impl that "specializes" another negative impl. +// +// run-pass + +trait MyTrait {} + +impl !MyTrait for T {} +impl !MyTrait for u32 {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-specializes-positive-item.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-specializes-positive-item.rs new file mode 100644 index 000000000000..d77ddcbd65bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-specializes-positive-item.rs @@ -0,0 +1,14 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } +#![feature(negative_impls)] + +// Negative impl for u32 cannot "specialize" the base impl. +trait MyTrait { + fn foo(); +} +impl MyTrait for T { + default fn foo() {} +} +impl !MyTrait for u32 {} // { dg-error ".E0751." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-specializes-positive.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-specializes-positive.rs new file mode 100644 index 000000000000..5f499e7f0c68 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/negative-specializes-positive.rs @@ -0,0 +1,15 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } +#![feature(negative_impls)] + +// Negative impl for u32 cannot "specialize" the base impl. +trait MyTrait {} +impl MyTrait for T {} +impl !MyTrait for u32 {} // { dg-error ".E0751." "" { target *-*-* } } + +// The second impl specializes the first, no error. +trait MyTrait2 {} +impl MyTrait2 for T {} +impl MyTrait2 for u32 {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/no-items.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/no-items.rs new file mode 100644 index 000000000000..d2437599119d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/no-items.rs @@ -0,0 +1,12 @@ +#![feature(negative_impls)] + +trait MyTrait { + type Foo; +} + +impl !MyTrait for u32 { + type Foo = i32; // { dg-error ".E0749." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs new file mode 100644 index 000000000000..d53ad38b6fc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/pin-unsound-issue-66544-clone.rs @@ -0,0 +1,27 @@ +use std::cell::Cell; +use std::marker::PhantomPinned; +use std::pin::Pin; + +struct MyType<'a>(Cell>>, PhantomPinned); + +impl<'a> Clone for &'a mut MyType<'a> { +// { dg-error ".E0751." "" { target *-*-* } .-1 } + fn clone(&self) -> &'a mut MyType<'a> { + self.0.take().unwrap() + } +} + +fn main() { + let mut unpinned = MyType(Cell::new(None), PhantomPinned); + let bad_addr = &unpinned as *const MyType<'_> as usize; + let mut p = Box::pin(MyType(Cell::new(Some(&mut unpinned)), PhantomPinned)); + + // p_mut1 is okay: it does not point to the bad_addr + let p_mut1: Pin<&mut MyType<'_>> = p.as_mut(); + assert_ne!(bad_addr, &*p_mut1 as *const _ as usize); + + // but p_mut2 does point to bad_addr! this is unsound + let p_mut2: Pin<&mut MyType<'_>> = p_mut1.clone(); + assert_eq!(bad_addr, &*p_mut2 as *const _ as usize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs new file mode 100644 index 000000000000..9f1b19c55834 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/pin-unsound-issue-66544-derefmut.rs @@ -0,0 +1,34 @@ +// Demonstrate that "rogue" `DerefMut` impls for `&T` are not allowed. +// +// https://github.com/rust-lang/rust/issues/66544 + +use std::cell::Cell; +use std::marker::PhantomPinned; +use std::ops::DerefMut; +use std::pin::Pin; + +struct MyType<'a>(Cell>>, PhantomPinned); + +impl<'a> DerefMut for &'a MyType<'a> { +// { dg-error ".E0751." "" { target *-*-* } .-1 } + fn deref_mut(&mut self) -> &mut MyType<'a> { + self.0.take().unwrap() + } +} + +fn main() { + let mut unpinned = MyType(Cell::new(None), PhantomPinned); + let bad_addr = &unpinned as *const MyType<'_> as usize; + let p = Box::pin(MyType(Cell::new(Some(&mut unpinned)), PhantomPinned)); + + // p_ref is okay: it does not point to the bad_addr + let mut p_ref: Pin<&MyType<'_>> = p.as_ref(); + assert_ne!(bad_addr, &*p_ref as *const _ as usize); + + // but p_mut does point to bad_addr! this is unsound + let p_mut: Pin<&mut MyType<'_>> = p_ref.as_mut(); + assert_eq!(bad_addr, &*p_mut as *const _ as usize); + + println!("oh no!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/positive-specializes-negative.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/positive-specializes-negative.rs new file mode 100644 index 000000000000..d3440c1ba02b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/positive-specializes-negative.rs @@ -0,0 +1,10 @@ +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } +#![feature(negative_impls)] + +trait MyTrait {} + +impl !MyTrait for T {} +impl MyTrait for u32 {} // { dg-error ".E0751." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/negative-impls/rely-on-negative-impl-in-coherence.rs b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/rely-on-negative-impl-in-coherence.rs new file mode 100644 index 000000000000..9f5717943b97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/negative-impls/rely-on-negative-impl-in-coherence.rs @@ -0,0 +1,22 @@ +#![feature(negative_impls)] + +// aux-build: foreign_trait.rs + +// Test that we cannot implement `LocalTrait` for `String`, +// even though there is a `String: !ForeignTrait` impl. +// +// This may not be the behavior we want long term, but it's the +// current semantics that we implemented so as to land `!Foo` impls +// quickly. See internals thread: +// +// https://internals.rust-lang.org/t/foo/11587/ + +extern crate foreign_trait; +use foreign_trait::ForeignTrait; + +trait LocalTrait { } +impl LocalTrait for T { } +impl LocalTrait for String { } // { dg-error ".E0119." "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/normalize-super-trait.rs b/gcc/testsuite/rust/rustc/ui/traits/normalize-super-trait.rs new file mode 100644 index 000000000000..9882ffefc8fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/normalize-super-trait.rs @@ -0,0 +1,38 @@ +// Regression test for #77653 +// When monomorphizing `f` we need to prove `dyn Derived<()>: Base<()>`. This +// requires us to normalize the `Base<<() as Proj>::S>` to `Base<()>` when +// comparing the supertrait `Derived<()>` to the expected trait. + +// build-pass + +trait Proj { + type S; +} + +impl Proj for () { + type S = (); +} + +impl Proj for i32 { + type S = i32; +} + +trait Base { + fn is_base(&self); +} + +trait Derived: Base + Base<()> { + fn is_derived(&self); +} + +fn f(obj: &dyn Derived

) { + obj.is_derived(); + Base::::is_base(obj); + Base::<()>::is_base(obj); +} + +fn main() { + let x: fn(_) = f::<()>; + let x: fn(_) = f::; +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/object-one-type-two-traits.rs b/gcc/testsuite/rust/rustc/ui/traits/object-one-type-two-traits.rs new file mode 100644 index 000000000000..751144c12b16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/object-one-type-two-traits.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Testing creating two vtables with the same self type, but different +// traits. + +#![feature(box_syntax)] + +use std::any::Any; + +trait Wrap { + fn get(&self) -> isize; + fn wrap(self: Box) -> Box; +} + +impl Wrap for isize { + fn get(&self) -> isize { + *self + } + fn wrap(self: Box) -> Box { + self as Box + } +} + +fn is(x: &dyn Any) -> bool { + x.is::() +} + +fn main() { + let x = box 22isize as Box; + println!("x={}", x.get()); + let y = x.wrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/overlap-not-permitted-for-builtin-trait.rs b/gcc/testsuite/rust/rustc/ui/traits/overlap-not-permitted-for-builtin-trait.rs new file mode 100644 index 000000000000..18382c4fb1e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/overlap-not-permitted-for-builtin-trait.rs @@ -0,0 +1,11 @@ +#![allow(dead_code)] +#![feature(negative_impls)] + +// Overlapping negative impls for `MyStruct` are not permitted: +struct MyStruct; +impl !Send for MyStruct {} +impl !Send for MyStruct {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/overlap-permitted-for-marker-traits.rs b/gcc/testsuite/rust/rustc/ui/traits/overlap-permitted-for-marker-traits.rs new file mode 100644 index 000000000000..0908538f8117 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/overlap-permitted-for-marker-traits.rs @@ -0,0 +1,29 @@ +// run-pass +// Tests for RFC 1268: we allow overlapping impls of marker traits, +// that is, traits without items. In this case, a type `T` is +// `MyMarker` if it is either `Debug` or `Display`. + +#![feature(marker_trait_attr)] +#![feature(negative_impls)] + +use std::fmt::{Debug, Display}; + +#[marker] +trait MyMarker {} + +impl MyMarker for T {} +impl MyMarker for T {} + +fn foo(t: T) -> T { + t +} + +fn main() { + // Debug && Display: + assert_eq!(1, foo(1)); + assert_eq!(2.0, foo(2.0)); + + // Debug && !Display: + assert_eq!(vec![1], foo(vec![1])); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/parameterized-trait-with-bounds.rs b/gcc/testsuite/rust/rustc/ui/traits/parameterized-trait-with-bounds.rs new file mode 100644 index 000000000000..8496404653ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/parameterized-trait-with-bounds.rs @@ -0,0 +1,22 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + + +trait A { fn get(self) -> T; } +trait B { fn get(self) -> (T,U); } +trait C<'a, U> { fn get(self) -> &'a U; } + +mod foo { + pub trait D<'a, T> { fn get(self) -> &'a T; } +} + +fn foo1(_: &(dyn A + Send)) {} +fn foo2(_: Box + Send + Sync>) {} +fn foo3(_: Box + 'static>) {} +fn foo4<'a, T>(_: Box + 'static + Send>) {} +fn foo5<'a, T>(_: Box + 'static + Send>) {} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/principal-less-trait-objects.rs b/gcc/testsuite/rust/rustc/ui/traits/principal-less-trait-objects.rs new file mode 100644 index 000000000000..c445440aaf33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/principal-less-trait-objects.rs @@ -0,0 +1,43 @@ +// run-pass +// Check that trait objects without a principal codegen properly. + +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::mem; + +// Array is to make sure the size is not exactly pointer-size, so +// we can be sure we are measuring the right size in the +// `size_of_val` test. +struct SetOnDrop<'a>(&'a AtomicUsize, [u8; 64]); +impl<'a> Drop for SetOnDrop<'a> { + fn drop(&mut self) { + self.0.store(self.0.load(Ordering::Relaxed) + 1, Ordering::Relaxed); + } +} + +trait TypeEq {} +impl TypeEq for T {} +fn assert_types_eq() where U: TypeEq {} + +fn main() { + // Check that different ways of writing the same type are equal. + assert_types_eq::(); + assert_types_eq::(); + assert_types_eq::(); + + // Check that codegen works. + // + // Using `AtomicUsize` here because `Cell` is not `Sync`, and + // so can't be made into a `Box`. + let c = AtomicUsize::new(0); + { + let d: Box = Box::new(SetOnDrop(&c, [0; 64])); + + assert_eq!(mem::size_of_val(&*d), + mem::size_of::()); + assert_eq!(mem::align_of_val(&*d), + mem::align_of::()); + assert_eq!(c.load(Ordering::Relaxed), 0); + } + assert_eq!(c.load(Ordering::Relaxed), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs b/gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs new file mode 100644 index 000000000000..89e1779877bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs @@ -0,0 +1,15 @@ +// check that reservation impls are accounted for in negative reasoning. + +#![feature(rustc_attrs)] + +trait MyTrait {} +#[rustc_reservation_impl="this impl is reserved"] +impl MyTrait for () {} + +trait OtherTrait {} +impl OtherTrait for () {} +impl OtherTrait for T {} +// { dg-error ".E0119." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-no-use.rs b/gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-no-use.rs new file mode 100644 index 000000000000..d3007b4bd88e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-no-use.rs @@ -0,0 +1,13 @@ +// check that reservation impls can't be used as normal impls in positive reasoning. + +#![feature(rustc_attrs)] + +trait MyTrait { fn foo(&self); } +#[rustc_reservation_impl = "foo"] +impl MyTrait for () { fn foo(&self) {} } + +fn main() { + <() as MyTrait>::foo(&()); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-non-lattice-ok.rs b/gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-non-lattice-ok.rs new file mode 100644 index 000000000000..4b69a64b553b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-non-lattice-ok.rs @@ -0,0 +1,60 @@ +// build-pass + +// Check that a reservation impl does not force other impls to follow +// a lattice discipline. + +// Why did we ever want to do this? +// +// We want to eventually add a `impl From for T` impl. That impl conflicts +// with existing impls - at least the `impl From for T` impl. There are +// 2 ways we thought of for dealing with that conflict: +// +// 1. Using specialization and doing some handling for the +// overlap. The current thought is to require ["intersection +// impls"][ii], specialization", which means providing an +// (higher-priority) impl for the intersection of every 2 conflicting +// impls that determines what happens in the intersection case. That's +// the first thing we thought about - see e.g. +// https://github.com/rust-lang/rust/issues/57012#issuecomment-452150775 +// +// 2. The other way is to notice that `impl From for T` is basically a +// marker trait since its only method is uninhabited, and allow for "marker +// trait overlap", where the conflict "doesn't matter" because it can't +// actually cause any ambiguity. +// +// Now it turned out lattice specialization doesn't work it, because an +// `impl From for Smaht` would require a `impl From for Smaht`, +// breaking backwards-compatibility in a fairly painful way. So if we want to +// go with a known approach, we should go with a "marker trait overlap"-style +// approach. +// +// [ii]: http://smallcultfollowing.com/babysteps/blog/2016/09/24/intersection-impls/ + +#![feature(rustc_attrs, never_type)] + +trait MyTrait {} + +impl MyTrait for ! {} + +trait MyFrom { + fn my_from(x: T) -> Self; +} + +// Given the "normal" impls for From +#[rustc_reservation_impl="this impl is reserved"] +impl MyFrom for T { + fn my_from(x: !) -> Self { match x {} } +} + +impl MyFrom for T { + fn my_from(x: T) -> Self { x } +} + +// ... we *do* want to allow this common pattern, of `From for MySmaht` +struct MySmaht(T); +impl MyFrom for MySmaht { + fn my_from(x: T) -> Self { MySmaht(x) } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-ok.rs b/gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-ok.rs new file mode 100644 index 000000000000..3e75d0fe9c04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/reservation-impls/reservation-impl-ok.rs @@ -0,0 +1,29 @@ +// run-pass + +// rpass test for reservation impls. Not 100% required because `From` uses them, +// but still. + +#![feature(rustc_attrs)] + +use std::mem; + +trait MyTrait { + fn foo(&self, s: S) -> usize; +} + +#[rustc_reservation_impl = "foo"] +impl MyTrait for T { + fn foo(&self, _x: u64) -> usize { 0 } +} + +// reservation impls don't create coherence conflicts, even with +// non-chain overlap. +impl MyTrait for u32 { + fn foo(&self, _x: S) -> usize { mem::size_of::() } +} + +fn main() { + // ...and the non-reservation impl gets picked.XS + assert_eq!(0u32.foo(0u64), mem::size_of::()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/self-without-lifetime-constraint.rs b/gcc/testsuite/rust/rustc/ui/traits/self-without-lifetime-constraint.rs new file mode 100644 index 000000000000..a4649593588a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/self-without-lifetime-constraint.rs @@ -0,0 +1,54 @@ +use std::error::Error; +use std::fmt; + +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum ValueRef<'a> { + Null, + Integer(i64), + Real(f64), + Text(&'a [u8]), + Blob(&'a [u8]), +} + +impl<'a> ValueRef<'a> { + pub fn as_str(&self) -> FromSqlResult<&'a str, &'a &'a str> { + match *self { + ValueRef::Text(t) => { + std::str::from_utf8(t).map_err(|_| FromSqlError::InvalidType).map(|x| (x, &x)) + } + _ => Err(FromSqlError::InvalidType), + } + } +} + +#[derive(Debug)] +#[non_exhaustive] +pub enum FromSqlError { + InvalidType +} + +impl fmt::Display for FromSqlError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "InvalidType") + } +} + +impl Error for FromSqlError {} + +pub type FromSqlResult = Result<(T, K), FromSqlError>; + +pub trait FromSql: Sized { + fn column_result(value: ValueRef<'_>) -> FromSqlResult; +} + +impl FromSql for &str { + fn column_result(value: ValueRef<'_>) -> FromSqlResult<&str, &&str> { +// { dg-error "" "" { target *-*-* } .-1 } + value.as_str() + } +} + +pub fn main() { + println!("{}", "Hello World"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/supertrait-default-generics.rs b/gcc/testsuite/rust/rustc/ui/traits/supertrait-default-generics.rs new file mode 100644 index 000000000000..89a3fc55653b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/supertrait-default-generics.rs @@ -0,0 +1,40 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_snake_case)] + +// There is some other borrowck bug, so we make the stuff not mut. + + +use std::ops::Add; + +trait Positioned { + fn SetX(&mut self, _: S); + fn X(&self) -> S; +} + +trait Movable>: Positioned { + fn translate(&mut self, dx: S) { + let x = self.X() + dx; + self.SetX(x); + } +} + +struct Point { x: S, y: S } + +impl Positioned for Point { + fn SetX(&mut self, x: S) { + self.x = x; + } + fn X(&self) -> S { + self.x.clone() + } +} + +impl> Movable for Point {} + +pub fn main() { + let mut p = Point{ x: 1, y: 2}; + p.translate(3); + assert_eq!(p.X(), 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/syntax-trait-polarity.rs b/gcc/testsuite/rust/rustc/ui/traits/syntax-trait-polarity.rs new file mode 100644 index 000000000000..387cd63cfdac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/syntax-trait-polarity.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#![feature(negative_impls)] + +struct TestType; + +impl TestType {} + +trait TestTrait {} + +impl !Send for TestType {} + +struct TestType2(T); + +impl TestType2 {} + +impl !Send for TestType2 {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias-ambiguous.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias-ambiguous.rs new file mode 100644 index 000000000000..1dd0558508d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias-ambiguous.rs @@ -0,0 +1,25 @@ +#![feature(trait_alias)] + +mod inner { + pub trait A { fn foo(&self); } + pub trait B { fn foo(&self); } + + impl A for u8 { + fn foo(&self) {} + } + impl B for u8 { + fn foo(&self) {} + } + + pub trait C = A + B; +} + +use inner::C; + +fn main() { + let t = 1u8; + t.foo(); // { dg-error ".E0034." "" { target *-*-* } } + + inner::A::foo(&t); // ok +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias-import-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias-import-cross-crate.rs new file mode 100644 index 000000000000..17d2a3b8b212 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias-import-cross-crate.rs @@ -0,0 +1,15 @@ +// run-pass +// aux-build:trait_alias.rs + +#![feature(trait_alias)] + +extern crate trait_alias; + +// Import only the alias, not the real trait. +use trait_alias::{Greet, Hi}; + +fn main() { + let hi = Hi; + hi.hello(); // From `Hello`, via `Greet` alias. +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias-import.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias-import.rs new file mode 100644 index 000000000000..8bb4492d93ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias-import.rs @@ -0,0 +1,41 @@ +// run-pass + +#![feature(trait_alias)] + +mod inner { + pub trait Foo { + fn foo(&self); + } + + pub struct Qux; + + impl Foo for Qux { + fn foo(&self) {} + } + + pub trait Bar = Foo; +} + +mod two { + pub trait A { + fn foo(); + } + + impl A for u8 { + fn foo() {} + } +} + +// Import only the alias, not the `Foo` trait. +use inner::{Bar, Qux}; + +// Declaring an alias also brings in aliased methods. +trait Two = two::A; + +fn main() { + let q = Qux; + q.foo(); // From Bar. + + u8::foo(); // From A. +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/auxiliary/trait_alias.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/auxiliary/trait_alias.rs new file mode 100644 index 000000000000..f71c5ef12383 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/auxiliary/trait_alias.rs @@ -0,0 +1,4 @@ +#![feature(trait_alias)] + +pub trait SendSync = Send + Sync; + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/issue-60021-assoc-method-resolve.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/issue-60021-assoc-method-resolve.rs new file mode 100644 index 000000000000..2075f0c32f2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/issue-60021-assoc-method-resolve.rs @@ -0,0 +1,20 @@ +// check-pass + +#![feature(trait_alias)] + +trait SomeTrait { + fn map(&self) {} +} + +impl SomeTrait for Option {} + +trait SomeAlias = SomeTrait; + +fn main() { + let x = Some(123); + // This should resolve to the trait impl for Option + Option::map(x, |z| z); + // This should resolve to the trait impl for SomeTrait + SomeTrait::map(&x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/issue-72415-assoc-const-resolve.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/issue-72415-assoc-const-resolve.rs new file mode 100644 index 000000000000..d43b1d32a737 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/issue-72415-assoc-const-resolve.rs @@ -0,0 +1,15 @@ +// check-pass + +#![feature(trait_alias)] + +trait Bounded { const MAX: Self; } + +impl Bounded for u32 { + // This should correctly resolve to the associated const in the inherent impl of u32. + const MAX: Self = u32::MAX; +} + +trait Num = Bounded + Copy; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/issue-75983.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/issue-75983.rs new file mode 100644 index 000000000000..6c2ff0c67459 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/issue-75983.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(trait_alias)] + +struct Bar; +trait Foo {} +impl Foo for Bar {} + +trait Baz = Foo where Bar: Foo; + +fn new() -> impl Baz { + Bar +} + +fn main() { + let _ = new(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-bounds.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-bounds.rs new file mode 100644 index 000000000000..3ee1b06a6113 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-bounds.rs @@ -0,0 +1,58 @@ +// run-pass + +#![feature(trait_alias)] + +use std::marker::PhantomData; + +trait Empty {} +trait EmptyAlias = Empty; +trait CloneDefault = Clone + Default; +trait SendSyncAlias = Send + Sync; +trait WhereSendAlias = where Self: Send; +trait SendEqAlias = Send where T: PartialEq; +trait I32Iterator = Iterator; + +#[allow(dead_code)] +struct Foo(PhantomData); +#[allow(dead_code)] +struct Bar(PhantomData) where T: SendSyncAlias; + +impl dyn EmptyAlias {} + +impl Empty for T {} + +fn a() -> (T, T) { + let one = T::default(); + let two = one.clone(); + (one, two) +} + +fn b(x: &impl SendEqAlias) -> bool { + 22_i32 == *x +} + +fn c(x: &mut T) -> Option { + x.next() +} + +fn d() { + is_send_and_sync::(); +} + +fn is_send_and_sync() {} + +fn main() { + let both = a::(); + assert_eq!(both.0, 0); + assert_eq!(both.1, 0); + let both: (i32, i32) = a(); + assert_eq!(both.0, 0); + assert_eq!(both.1, 0); + + assert!(b(&22)); + + assert_eq!(c(&mut vec![22].into_iter()), Some(22)); + + d::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-cross-crate.rs new file mode 100644 index 000000000000..e29b219f99c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-cross-crate.rs @@ -0,0 +1,18 @@ +// aux-build:trait_alias.rs + +#![feature(trait_alias)] + +extern crate trait_alias; + +use std::rc::Rc; +use trait_alias::SendSync; + +fn use_alias() {} + +fn main() { + use_alias::(); + use_alias::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-impl.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-impl.rs new file mode 100644 index 000000000000..f4efbda034b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-impl.rs @@ -0,0 +1,8 @@ +#![feature(trait_alias)] + +trait DefaultAlias = Default; + +impl DefaultAlias for () {} // { dg-error ".E0404." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-maybe-bound.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-maybe-bound.rs new file mode 100644 index 000000000000..e3796e505b8b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-maybe-bound.rs @@ -0,0 +1,30 @@ +// build-pass (FIXME(62277): could be check-pass?) + +// Test that `dyn ... + ?Sized + ...` resulting from the expansion of trait aliases is okay. + +#![feature(trait_alias)] + +trait Foo {} + +trait S = ?Sized; + +// Nest a couple of levels deep: +trait _0 = S; +trait _1 = _0; + +// Straight list expansion: +type _T0 = dyn _1 + Foo; + +// In second position: +type _T1 = dyn Foo + _1; + +// ... and with an auto trait: +type _T2 = dyn Foo + Send + _1; + +// Twice: +trait _2 = _1 + _1; + +type _T3 = dyn _2 + Foo; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-no-duplicates.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-no-duplicates.rs new file mode 100644 index 000000000000..5bfa7a1cc9d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-no-duplicates.rs @@ -0,0 +1,127 @@ +// The purpose of this test is to demonstrate that duplicating object safe traits +// that are not auto traits is rejected with trait aliases even though one could +// reasonably accept this. + +#![feature(trait_alias)] + +use std::marker::Unpin; + +// Some arbitrary object-safe trait: +trait Obj {} + +// Nest a few levels deep: +trait _0 = Obj; +trait _1 = _0; + +type _T00 = dyn _0 + _0; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T01 = dyn _1 + _0; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T02 = dyn _1 + _1; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T03 = dyn Obj + _1; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T04 = dyn _1 + Obj; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +// Nest some more and in weird ways: + +trait _2 = _0 + _1; +trait _3 = Obj; +trait _4 = _3; + +type _T10 = dyn _2 + _3; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T11 = dyn _3 + _2; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T12 = dyn Obj + _2; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T13 = dyn _2 + Obj; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T14 = dyn _1 + _3; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T15 = dyn _3 + _1; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T16 = dyn _1 + _4; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T17 = dyn _4 + _1; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +// Include auto traits: + +trait _5 = Obj + Send; + +type _T20 = dyn _5 + _5; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T21 = dyn Obj + _5; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T22 = dyn _5 + Obj; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T23 = dyn _5 + Send + Sync + Obj; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +// Also nest: + +trait _6 = _5 + _5; // ==> Obj + Send + Obj + Send + +type _T30 = dyn _6; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T31 = dyn _6 + Send; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T32 = dyn Send + _6; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +// Nest some more: + +trait _7 = _5 + Sync; +trait _8 = Unpin + _7; + +type _T40 = dyn _8 + Obj; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T41 = dyn Obj + _8; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T42 = dyn _8 + _4; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T43 = dyn _4 + _8; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T44 = dyn _4 + Send + Sync + _8; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +// Take higher ranked types into account. + +// Note that `'a` and `'b` are intentionally different to make sure we consider +// them semantically the same. +trait ObjL<'l> {} +trait _9 = for<'a> ObjL<'a>; +trait _10 = for<'b> ObjL<'b>; +type _T50 = dyn _9 + _10; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +trait ObjT {} +trait _11 = ObjT fn(&'a u8)>; +trait _12 = ObjT fn(&'b u8)>; +type _T60 = dyn _11 + _12; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-no-extra-traits.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-no-extra-traits.rs new file mode 100644 index 000000000000..9a47329b3aa3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-no-extra-traits.rs @@ -0,0 +1,122 @@ +// The purpose of this test is to demonstrate that trait alias expansion +// preserves the rule that `dyn Trait` may only reference one non-auto trait. + +#![feature(trait_alias)] + +use std::marker::Unpin; + +// Some arbitrary object-safe traits: +trait ObjA {} +trait ObjB {} + +// Nest a few levels deep: +trait _0 = ObjA; +trait _1 = _0; + +type _T00 = dyn _0 + ObjB; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T01 = dyn ObjB + _0; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T02 = dyn ObjB + _1; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T03 = dyn _1 + ObjB; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +// Nest some more and in weird ways: + +trait _2 = ObjB; +trait _3 = _2; +trait _4 = _3; + +type _T10 = dyn _2 + _3; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T11 = dyn _3 + _2; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T12 = dyn _2 + _4; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T13 = dyn _4 + _2; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +// Include auto traits: + +trait _5 = Sync + ObjB + Send; + +type _T20 = dyn _5 + _1; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T21 = dyn _1 + _5; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T22 = dyn _5 + ObjA; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T23 = dyn ObjA + _5; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T24 = dyn Send + _5 + _1 + Sync; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T25 = dyn _1 + Sync + _5 + Send; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T26 = dyn Sync + Send + _5 + ObjA; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T27 = dyn Send + Sync + ObjA + _5; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +// Also nest: + +trait _6 = _1 + _5; +trait _7 = _6; +trait _8 = _7; + +type _T30 = dyn _6; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T31 = dyn _6 + Send; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T32 = dyn Send + _6; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T33 = dyn _8; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T34 = dyn _8 + Send; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T35 = dyn Send + _8; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +// Nest some more: + +trait _9 = _5 + Sync; +trait _10 = Unpin + _9; + +type _T40 = dyn _10 + ObjA; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T41 = dyn ObjA + _10; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T42 = dyn _10 + _1; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T43 = dyn Send + _10 + Sync + ObjA; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T44 = dyn ObjA + _10 + Send + Sync; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _T45 = dyn Sync + Send + _10 + _1; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-object-fail.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-object-fail.rs new file mode 100644 index 000000000000..27154da2157e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-object-fail.rs @@ -0,0 +1,12 @@ +#![feature(trait_alias)] + +trait EqAlias = Eq; +trait IteratorAlias = Iterator; + +fn main() { + let _: &dyn EqAlias = &123; +// { dg-error ".E0038." "" { target *-*-* } .-1 } + let _: &dyn IteratorAlias = &vec![123].into_iter(); +// { dg-error ".E0191." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-object-wf.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-object-wf.rs new file mode 100644 index 000000000000..5fbfeb4e43dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-object-wf.rs @@ -0,0 +1,86 @@ +// check-pass + +// This test checks that trait objects involving trait aliases are well-formed. + +#![feature(trait_alias)] + +trait Obj {} + +trait _0 = Send + Sync; + +// Just auto traits: + +trait _1 = _0 + Send + Sync; + +use std::marker::Unpin; + +fn _f0() { + let _: Box; + let _: Box; + let _: Box; +} + +// Include object safe traits: + +fn _f1() { + let _: Box; + let _: Box; + let _: Box; +} + +// And when the object safe trait is in a trait alias: + +trait _2 = Obj; + +fn _f2() { + let _: Box; + let _: Box; + let _: Box; +} + +// And it should also work when that trait is has auto traits to the right of it. + +trait _3 = Obj + Unpin; + +fn _f3() { + let _: Box; + let _: Box; + let _: Box; +} + +// Nest the trait deeply: + +trait _4 = _3; +trait _5 = _4 + Sync + _0 + Send; +trait _6 = _5 + Send + _1 + Sync; + +fn _f4() { + let _: Box; + let _: Box; + let _: Box; +} + +// Just nest the trait alone: + +trait _7 = _2; +trait _8 = _7; +trait _9 = _8; + +fn _f5() { + let _: Box; +} + +// First bound is auto trait: + +trait _10 = Send + Obj; +trait _11 = Obj + Send; +trait _12 = Sync + _11; +trait _13 = Send + _12; + +fn f6() { + let _: Box; + let _: Box; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-object.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-object.rs new file mode 100644 index 000000000000..c607b81dfe7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-object.rs @@ -0,0 +1,19 @@ +// run-pass + +#![feature(trait_alias)] + +trait Foo = PartialEq + Send; +trait Bar = Foo + Sync; + +trait I32Iterator = Iterator; + +pub fn main() { + let a: &dyn Bar = &123; + assert!(*a == 123); + let b = Box::new(456) as Box; + assert!(*b == 456); + + let c: &mut dyn I32Iterator = &mut vec![123].into_iter(); + assert_eq!(c.next(), Some(123)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-only-maybe-bound.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-only-maybe-bound.rs new file mode 100644 index 000000000000..c08fc038875a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-only-maybe-bound.rs @@ -0,0 +1,23 @@ +// Test that `dyn ?Sized` (i.e., a trait object with only a maybe buond) is not allowed, when just +// `?Sized` results from trait alias expansion. + +#![feature(trait_alias)] + +trait S = ?Sized; + +// Nest a couple of levels deep: +trait _0 = S; +trait _1 = _0; + +// Straight list expansion: +type _T0 = dyn _1; +// { dg-error ".E0224." "" { target *-*-* } .-1 } + +// Twice: +trait _2 = _1 + _1; + +type _T1 = dyn _2; +// { dg-error ".E0224." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-syntax-fail.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-syntax-fail.rs new file mode 100644 index 000000000000..0b1eaf09fb21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-syntax-fail.rs @@ -0,0 +1,11 @@ +#![feature(trait_alias)] + +trait Foo {} +auto trait A = Foo; // { dg-error "" "" { target *-*-* } } +unsafe trait B = Foo; // { dg-error "" "" { target *-*-* } } + +trait C: Ord = Eq; // { dg-error "" "" { target *-*-* } } +trait D: = Eq; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-syntax.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-syntax.rs new file mode 100644 index 000000000000..0579516212cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-syntax.rs @@ -0,0 +1,25 @@ +// run-pass + +#![feature(trait_alias)] + +trait SimpleAlias = Default; +trait GenericAlias = Iterator; +trait Partial = IntoIterator; +trait SpecificAlias = GenericAlias; +trait PartialEqRef<'a, T: 'a> = PartialEq<&'a T>; +trait StaticAlias = 'static; + +trait Things {} +trait Romeo {} +#[allow(dead_code)] +struct The(T); +#[allow(dead_code)] +struct Fore(T); +impl Things for The {} +impl Romeo for Fore {} + +trait WithWhere = Romeo + Romeo where Fore<(Art, Thou)>: Romeo; +trait BareWhere = where The: Things; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-wf.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-wf.rs new file mode 100644 index 000000000000..f90e03fa3f6f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias-wf.rs @@ -0,0 +1,8 @@ +#![feature(trait_alias)] + +trait Foo {} +trait A {} +trait B = A; // { dg-error ".E0277." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias.rs new file mode 100644 index 000000000000..7f0412a4046e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-alias/trait-alias.rs @@ -0,0 +1,9 @@ +// run-pass + +#![feature(trait_alias)] + +pub trait Foo {} +pub trait FooAlias = Foo; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-as-struct-constructor.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-as-struct-constructor.rs new file mode 100644 index 000000000000..7dc21cfed913 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-as-struct-constructor.rs @@ -0,0 +1,7 @@ +trait TraitNotAStruct {} + +fn main() { + TraitNotAStruct{ value: 0 }; +// { dg-error ".E0574." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-basic.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-basic.rs new file mode 100644 index 000000000000..4d0011cedb7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-basic.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +#![allow(unconditional_recursion)] + +// pretty-expanded FIXME #23616 + +trait Foo { +} + +fn b(_x: Box) { +} + +fn c(x: Box) { + e(x); +} + +fn d(x: Box) { + e(x); +} + +fn e(x: Box) { + e(x); +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-impl-comparison-duplicates.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-impl-comparison-duplicates.rs new file mode 100644 index 000000000000..6e65f36b8893 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-impl-comparison-duplicates.rs @@ -0,0 +1,17 @@ +// run-pass +// Tests that type parameter bounds on an implementation need not match the +// trait exactly, as long as the implementation doesn't demand *more* bounds +// than the trait. + +// pretty-expanded FIXME #23616 + +trait A { + fn foo(&self); +} + +impl A for isize { + fn foo(&self) {} // Ord implies Eq, so this is ok. +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-in-arc.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-in-arc.rs new file mode 100644 index 000000000000..691bf89b813c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-in-arc.rs @@ -0,0 +1,110 @@ +// run-pass +#![allow(unused_must_use)] +// Tests that a heterogeneous list of existential `dyn` types can be put inside an Arc +// and shared between threads as long as all types fulfill Send. + +// ignore-emscripten no threads support + +#![feature(box_syntax)] + +use std::sync::Arc; +use std::sync::mpsc::channel; +use std::thread; + +trait Pet { + fn name(&self, blk: Box); + fn num_legs(&self) -> usize; + fn of_good_pedigree(&self) -> bool; +} + +struct Catte { + num_whiskers: usize, + name: String, +} + +struct Dogge { + bark_decibels: usize, + tricks_known: usize, + name: String, +} + +struct Goldfyshe { + swim_speed: usize, + name: String, +} + +impl Pet for Catte { + fn name(&self, mut blk: Box) { blk(&self.name) } + fn num_legs(&self) -> usize { 4 } + fn of_good_pedigree(&self) -> bool { self.num_whiskers >= 4 } +} +impl Pet for Dogge { + fn name(&self, mut blk: Box) { blk(&self.name) } + fn num_legs(&self) -> usize { 4 } + fn of_good_pedigree(&self) -> bool { + self.bark_decibels < 70 || self.tricks_known > 20 + } +} +impl Pet for Goldfyshe { + fn name(&self, mut blk: Box) { blk(&self.name) } + fn num_legs(&self) -> usize { 0 } + fn of_good_pedigree(&self) -> bool { self.swim_speed >= 500 } +} + +pub fn main() { + let catte = Catte { num_whiskers: 7, name: "alonzo_church".to_string() }; + let dogge1 = Dogge { + bark_decibels: 100, + tricks_known: 42, + name: "alan_turing".to_string(), + }; + let dogge2 = Dogge { + bark_decibels: 55, + tricks_known: 11, + name: "albert_einstein".to_string(), + }; + let fishe = Goldfyshe { + swim_speed: 998, + name: "alec_guinness".to_string(), + }; + let arc = Arc::new(vec![box catte as Box, + box dogge1 as Box, + box fishe as Box, + box dogge2 as Box]); + let (tx1, rx1) = channel(); + let arc1 = arc.clone(); + let t1 = thread::spawn(move|| { check_legs(arc1); tx1.send(()); }); + let (tx2, rx2) = channel(); + let arc2 = arc.clone(); + let t2 = thread::spawn(move|| { check_names(arc2); tx2.send(()); }); + let (tx3, rx3) = channel(); + let arc3 = arc.clone(); + let t3 = thread::spawn(move|| { check_pedigree(arc3); tx3.send(()); }); + rx1.recv(); + rx2.recv(); + rx3.recv(); + t1.join(); + t2.join(); + t3.join(); +} + +fn check_legs(arc: Arc>>) { + let mut legs = 0; + for pet in arc.iter() { + legs += pet.num_legs(); + } + assert!(legs == 12); +} +fn check_names(arc: Arc>>) { + for pet in arc.iter() { + pet.name(Box::new(|name| { + assert!(name.as_bytes()[0] == 'a' as u8 && name.as_bytes()[1] == 'l' as u8); + })) + } +} +fn check_pedigree(arc: Arc>>) { + for pet in arc.iter() { + assert!(pet.of_good_pedigree()); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-not-on-bare-trait.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-not-on-bare-trait.rs new file mode 100644 index 000000000000..55e59c397efe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-not-on-bare-trait.rs @@ -0,0 +1,13 @@ +trait Foo { + fn dummy(&self) { } +} + +// This should emit the less confusing error, not the more confusing one. + +fn foo(_x: Foo + Send) { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-warning ".E0277." "" { target *-*-* } .-2 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-not-on-struct.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-not-on-struct.rs new file mode 100644 index 000000000000..cf1ac83c6229 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-not-on-struct.rs @@ -0,0 +1,39 @@ +// We don't need those errors. Ideally we would silence them, but to do so we need to move the +// lint from being an early-lint during parsing to a late-lint, because it needs to be aware of +// the types involved. +#![allow(bare_trait_objects)] + +struct Foo; + +fn foo(_x: Box) { } // { dg-error ".E0404." "" { target *-*-* } } + +type TypeAlias = Box>; // { dg-error ".E0404." "" { target *-*-* } } + +struct A; +fn a() -> A + 'static { // { dg-error ".E0404." "" { target *-*-* } } + A +} +fn b<'a,T,E>(iter: Iterator + 'a>) { // { dg-error ".E0404." "" { target *-*-* } } + panic!() +} +fn c() -> 'static + A { // { dg-error ".E0404." "" { target *-*-* } } + A +} +fn d<'a,T,E>(iter: Iterator>) { // { dg-error ".E0404." "" { target *-*-* } } + panic!() +} +fn e() -> 'static + A + 'static { // { dg-error ".E0404." "" { target *-*-* } } +// { dg-error ".E0404." "" { target *-*-* } .-1 } + A +} +fn f<'a,T,E>(iter: Iterator + 'a>) { // { dg-error ".E0404." "" { target *-*-* } } +// { dg-error ".E0404." "" { target *-*-* } .-1 } + panic!() +} +struct Traitor; +trait Trait {} +fn g() -> Traitor + 'static { // { dg-error ".E0404." "" { target *-*-* } } + A +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-in-fns.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-in-fns.rs new file mode 100644 index 000000000000..16c1e0b29897 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-in-fns.rs @@ -0,0 +1,21 @@ +trait Trait {} + +struct Foo { + x: T, +} + +enum Bar { + ABar(isize), + BBar(T), + CBar(usize), +} + +fn explode(x: Foo) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn kaboom(y: Bar) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-in-impls.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-in-impls.rs new file mode 100644 index 000000000000..ac62a94622b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-in-impls.rs @@ -0,0 +1,26 @@ +trait Trait {} + +struct Foo { + x: T, +} + +enum Bar { + ABar(isize), + BBar(T), + CBar(usize), +} + +trait PolyTrait +{ + fn whatever(&self, t: T) {} +} + +struct Struct; + +impl PolyTrait> for Struct { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-locals.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-locals.rs new file mode 100644 index 000000000000..cccdb89e22ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-locals.rs @@ -0,0 +1,18 @@ +trait Trait { + fn dummy(&self) { } +} + +struct Foo { + x: T, +} + +fn main() { + let foo = Foo { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + x: 3 + }; + + let baz: Foo = loop { }; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-rpass.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-rpass.rs new file mode 100644 index 000000000000..222909c06c69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-rpass.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +trait U {} +trait T { fn get(self) -> X; } + +trait S2 { + fn m(x: Box+'static>) {} +} + +struct St { + f: Box+'static>, +} + +impl St { + fn blah() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-static.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-static.rs new file mode 100644 index 000000000000..d5aa386093b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-static.rs @@ -0,0 +1,16 @@ +trait Trait { + fn dummy(&self) { } +} + +struct Foo { + x: T, +} + +static X: Foo = Foo { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + x: 1, +}; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-xc.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-xc.rs new file mode 100644 index 000000000000..1bec7c5925c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-xc.rs @@ -0,0 +1,15 @@ +// aux-build:trait_bounds_on_structs_and_enums_xc.rs + +extern crate trait_bounds_on_structs_and_enums_xc; + +use trait_bounds_on_structs_and_enums_xc::{Bar, Foo, Trait}; + +fn explode(x: Foo) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn kaboom(y: Bar) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-xc1.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-xc1.rs new file mode 100644 index 000000000000..cce5cb63833f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums-xc1.rs @@ -0,0 +1,16 @@ +// aux-build:trait_bounds_on_structs_and_enums_xc.rs + +extern crate trait_bounds_on_structs_and_enums_xc; + +use trait_bounds_on_structs_and_enums_xc::{Bar, Foo, Trait}; + +fn main() { + let foo = Foo { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + x: 3 + }; + let bar: Bar = return; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let _ = bar; +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums.rs new file mode 100644 index 000000000000..e5400c307904 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-on-structs-and-enums.rs @@ -0,0 +1,44 @@ +trait Trait {} + +struct Foo { + x: T, +} + +enum Bar { + ABar(isize), + BBar(T), + CBar(usize), +} + +impl Foo { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + fn uhoh() {} +} + +struct Baz { + a: Foo, // { dg-error ".E0277." "" { target *-*-* } } +} + +enum Boo { + Quux(Bar), // { dg-error ".E0277." "" { target *-*-* } } +} + +struct Badness { + b: Foo, // { dg-error ".E0277." "" { target *-*-* } } +} + +enum MoreBadness { + EvenMoreBadness(Bar), // { dg-error ".E0277." "" { target *-*-* } } +} + +struct TupleLike( + Foo, // { dg-error ".E0277." "" { target *-*-* } } +); + +enum Enum { + DictionaryLike { field: Bar }, // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-recursion.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-recursion.rs new file mode 100644 index 000000000000..167b88a151e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-recursion.rs @@ -0,0 +1,21 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait I { fn i(&self) -> Self; } + +trait A { + fn id(x:T) -> T { x.i() } +} + +trait J { fn j(&self) -> T; } + +trait B> { + fn id(x:T) -> T { x.j() } +} + +trait C { + fn id>(x:T) -> T { x.j() } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-same-crate-name.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-same-crate-name.rs new file mode 100644 index 000000000000..13098137ca81 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-same-crate-name.rs @@ -0,0 +1,56 @@ +// aux-build:crate_a1.rs +// aux-build:crate_a2.rs + +// Issue 22750 +// This tests the extra help message reported when a trait bound +// is not met but the struct implements a trait with the same path. + +fn main() { + let foo = { + extern crate crate_a2 as a; + a::Foo + }; + + let implements_no_traits = { + extern crate crate_a2 as a; + a::DoesNotImplementTrait + }; + + let other_variant_implements_mismatched_trait = { + extern crate crate_a2 as a; + a::ImplementsWrongTraitConditionally { _marker: std::marker::PhantomData:: } + }; + + let other_variant_implements_correct_trait = { + extern crate crate_a1 as a; + a::ImplementsTraitForUsize { _marker: std::marker::PhantomData:: } + }; + + { + extern crate crate_a1 as a; + a::try_foo(foo); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } + + // We don't want to see the "version mismatch" help message here + // because `implements_no_traits` has no impl for `Foo` + a::try_foo(implements_no_traits); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // We don't want to see the "version mismatch" help message here + // because `other_variant_implements_mismatched_trait` + // does not have an impl for its `` variant, + // only for its `` variant. + a::try_foo(other_variant_implements_mismatched_trait); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // We don't want to see the "version mismatch" help message here + // because `ImplementsTraitForUsize` only has + // impls for the correct trait where the path is not misleading. + a::try_foo(other_variant_implements_correct_trait); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-sugar.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-sugar.rs new file mode 100644 index 000000000000..7c3ed3a8d16c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds-sugar.rs @@ -0,0 +1,20 @@ +// Tests for "default" bounds inferred for traits with no bounds list. + +trait Foo {} + +fn a(_x: Box) { +} + +fn b(_x: &'static (dyn Foo + 'static)) { +} + +fn c(x: Box) { + a(x); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn d(x: &'static (dyn Foo + Sync)) { + b(x); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-bounds.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds.rs new file mode 100644 index 000000000000..15d0bd9eea12 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-bounds.rs @@ -0,0 +1,31 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +trait connection { + fn read(&self) -> isize; +} + +trait connection_factory { + fn create(&self) -> C; +} + +type my_connection = (); +type my_connection_factory = (); + +impl connection for () { + fn read(&self) -> isize { 43 } +} + +impl connection_factory for my_connection_factory { + fn create(&self) -> my_connection { () } +} + +pub fn main() { + let factory = (); + let connection = factory.create(); + let result = connection.read(); + assert_eq!(result, 43); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-cache-issue-18209.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-cache-issue-18209.rs new file mode 100644 index 000000000000..214178ba8d12 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-cache-issue-18209.rs @@ -0,0 +1,21 @@ +// run-pass +// Test that the cache results from the default method do not pollute +// the cache for the later call in `load()`. +// +// See issue #18209. + +// pretty-expanded FIXME #23616 + +pub trait Foo { + fn load_from() -> Box; + fn load() -> Box { + Foo::load_from() + } +} + +pub fn load() -> Box { + Foo::load() +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-coercion-generic-bad.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-coercion-generic-bad.rs new file mode 100644 index 000000000000..e4926432ae03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-coercion-generic-bad.rs @@ -0,0 +1,20 @@ +struct Struct { + person: &'static str +} + +trait Trait { + fn f(&self, x: T); +} + +impl Trait<&'static str> for Struct { + fn f(&self, x: &'static str) { + println!("Hello, {}!", x); + } +} + +fn main() { + let s: Box> = Box::new(Struct { person: "Fred" }); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + s.f(1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-coercion-generic-regions.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-coercion-generic-regions.rs new file mode 100644 index 000000000000..ca9f750fda0a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-coercion-generic-regions.rs @@ -0,0 +1,20 @@ +struct Struct { + person: &'static str +} + +trait Trait { + fn f(&self, x: T); +} + +impl Trait<&'static str> for Struct { + fn f(&self, x: &'static str) { + println!("Hello, {}!", x); + } +} + +fn main() { + let person = "Fred".to_string(); + let person: &str = &person; // { dg-error ".E0597." "" { target *-*-* } } + let s: Box> = Box::new(Struct { person: person }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-coercion-generic.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-coercion-generic.rs new file mode 100644 index 000000000000..4004c78525ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-coercion-generic.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +trait Trait { + fn f(&self, x: T); +} + +#[derive(Copy, Clone)] +struct Struct { + x: isize, + y: isize, +} + +impl Trait<&'static str> for Struct { + fn f(&self, x: &'static str) { + println!("Hi, {}!", x); + } +} + +pub fn main() { + let a = Struct { x: 1, y: 2 }; + let b: Box> = Box::new(a); + b.f("Mary"); + let c: &dyn Trait<&'static str> = &a; + c.f("Joe"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-coercion.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-coercion.rs new file mode 100644 index 000000000000..ec670398c2b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-coercion.rs @@ -0,0 +1,37 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_mut)] +#![allow(unused_variables)] +#![feature(box_syntax)] + +use std::io::{self, Write}; + +trait Trait { + fn f(&self); +} + +#[derive(Copy, Clone)] +struct Struct { + x: isize, + y: isize, +} + +impl Trait for Struct { + fn f(&self) { + println!("Hi!"); + } +} + +fn foo(mut a: Box) {} + +pub fn main() { + let a = Struct { x: 1, y: 2 }; + let b: Box = Box::new(a); + b.f(); + let c: &dyn Trait = &a; + c.f(); + + let out = io::stdout(); + foo(Box::new(out)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-composition-trivial.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-composition-trivial.rs new file mode 100644 index 000000000000..653e3a8412bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-composition-trivial.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Foo { + fn foo(&self); +} + +trait Bar : Foo { + fn bar(&self); +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-copy-guessing.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-copy-guessing.rs new file mode 100644 index 000000000000..51f536126240 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-copy-guessing.rs @@ -0,0 +1,39 @@ +// run-pass +#![allow(dead_code)] +// "guessing" in trait selection can affect `copy_or_move`. Check that this +// is correctly handled. I am not sure what is the "correct" behaviour, +// but we should at least not ICE. + +use std::mem; + +struct U([u8; 1337]); + +struct S<'a,T:'a>(&'a T); +impl<'a, T> Clone for S<'a, T> { fn clone(&self) -> Self { S(self.0) } } +/// This impl triggers inference "guessing" - S<_>: Copy => _ = U +impl<'a> Copy for S<'a, Option> {} + +fn assert_impls_fnR>(_: &T){} + +fn main() { + let n = None; + let e = S(&n); + let f = || { + // S being copy is critical for this to work + drop(e); + mem::size_of_val(e.0) + }; + assert_impls_fn(&f); + assert_eq!(f(), 1337+1); + + assert_eq!((|| { + // S being Copy is not critical here, but + // we check it anyway. + let n = None; + let e = S(&n); + let ret = mem::size_of_val(e.0); + drop(e); + ret + })(), 1337+1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst.rs new file mode 100644 index 000000000000..5ef1deb751d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst.rs @@ -0,0 +1,19 @@ +// run-pass + + +trait A { + fn g(&self, x: T, y: U) -> (T, U) { (x, y) } +} + +impl A for i32 { } +impl A for u32 { } + +fn f>(i: V, j: T, k: U) -> (T, U) { + i.g(j, k) +} + +pub fn main () { + assert_eq!(f(0, 1, 2), (1, 2)); + assert_eq!(f(0, 1, 2), (1, 2)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst2.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst2.rs new file mode 100644 index 000000000000..f6e73e734f06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst2.rs @@ -0,0 +1,17 @@ +// run-pass + + +trait A { + fn g(&self, x: T) -> T { x } +} + +impl A for isize { } + +fn f>(i: V, j: T) -> T { + i.g(j) +} + +pub fn main () { + assert_eq!(f(0, 2), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst3.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst3.rs new file mode 100644 index 000000000000..1d91f429aff4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst3.rs @@ -0,0 +1,18 @@ +// run-pass + + +trait A { + fn g(&self, x: T, y: T) -> (T, T) { (x, y) } +} + +impl A for isize { } + +fn f(i: V, j: T, k: T) -> (T, T) { + i.g(j, k) +} + +pub fn main () { + assert_eq!(f(0, 1, 2), (1, 2)); + assert_eq!(f(0, 1u8, 2u8), (1u8, 2u8)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst4.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst4.rs new file mode 100644 index 000000000000..d35c7e84b2c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound-subst4.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(unused_variables)] + + +trait A { + fn g(&self, x: usize) -> usize { x } + fn h(&self, x: T) { } +} + +impl A for isize { } + +fn f>(i: V, j: usize) -> usize { + i.g(j) +} + +pub fn main () { + assert_eq!(f::(0, 2), 2); + assert_eq!(f::(0, 2), 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound.rs new file mode 100644 index 000000000000..384d2e4e2dd7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-bound.rs @@ -0,0 +1,17 @@ +// run-pass + + +trait A { + fn g(&self) -> isize { 10 } +} + +impl A for isize { } + +fn f(i: T) { + assert_eq!(i.g(), 10); +} + +pub fn main () { + f(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-xc-2.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-xc-2.rs new file mode 100644 index 000000000000..ffe6e92fcb1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-xc-2.rs @@ -0,0 +1,27 @@ +// run-pass +// aux-build:trait_default_method_xc_aux.rs +// aux-build:trait_default_method_xc_aux_2.rs + + + +extern crate trait_default_method_xc_aux as aux; +extern crate trait_default_method_xc_aux_2 as aux2; +use aux::A; +use aux2::{a_struct, welp}; + + +pub fn main () { + + let a = a_struct { x: 0 }; + let b = a_struct { x: 1 }; + + assert_eq!(0.g(), 10); + assert_eq!(a.g(), 10); + assert_eq!(a.h(), 11); + assert_eq!(b.g(), 10); + assert_eq!(b.h(), 11); + assert_eq!(A::lurr(&a, &b), 21); + + welp(&0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-xc.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-xc.rs new file mode 100644 index 000000000000..afce2ac99aa4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-default-method-xc.rs @@ -0,0 +1,82 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// aux-build:trait_default_method_xc_aux.rs + + +extern crate trait_default_method_xc_aux as aux; +use aux::{A, TestEquality, Something}; +use aux::B; + +fn f(i: T) { + assert_eq!(i.g(), 10); +} + +fn welp(i: isize, _x: &T) -> isize { + i.g() +} + +mod stuff { + pub struct thing { pub x: isize } +} + +impl A for stuff::thing { + fn f(&self) -> isize { 10 } +} + +fn g>(i: V, j: T, k: U) -> (T, U) { + i.thing(j, k) +} + +fn eq(lhs: &T, rhs: &T) -> bool { + lhs.test_eq(rhs) +} +fn neq(lhs: &T, rhs: &T) -> bool { + lhs.test_neq(rhs) +} + + +impl TestEquality for stuff::thing { + fn test_eq(&self, rhs: &stuff::thing) -> bool { + //self.x.test_eq(&rhs.x) + eq(&self.x, &rhs.x) + } +} + + +pub fn main() { + // Some tests of random things + f(0); + + assert_eq!(A::lurr(&0, &1), 21); + + let a = stuff::thing { x: 0 }; + let b = stuff::thing { x: 1 }; + let c = Something { x: 1 }; + + assert_eq!(0.g(), 10); + assert_eq!(a.g(), 10); + assert_eq!(a.h(), 11); + assert_eq!(c.h(), 11); + + assert_eq!(0.thing(3.14f64, 1), (3.14f64, 1)); + assert_eq!(B::staticthing(&0, 3.14f64, 1), (3.14f64, 1)); + assert_eq!(B::::staticthing::(&0, 3.14, 1), (3.14, 1)); + + assert_eq!(g(0, 3.14f64, 1), (3.14f64, 1)); + assert_eq!(g(false, 3.14f64, 1), (3.14, 1)); + + + // Trying out a real one + assert!(12.test_neq(&10)); + assert!(!10.test_neq(&10)); + assert!(a.test_neq(&b)); + assert!(!a.test_neq(&a)); + + assert!(neq(&12, &10)); + assert!(!neq(&10, &10)); + assert!(neq(&a, &b)); + assert!(!neq(&a, &a)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-duplicate-methods.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-duplicate-methods.rs new file mode 100644 index 000000000000..46f43149a291 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-duplicate-methods.rs @@ -0,0 +1,7 @@ +trait Foo { + fn orange(&self); + fn orange(&self); // { dg-error ".E0428." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-false-ambiguity-where-clause-builtin-bound.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-false-ambiguity-where-clause-builtin-bound.rs new file mode 100644 index 000000000000..9eb93dc082f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-false-ambiguity-where-clause-builtin-bound.rs @@ -0,0 +1,17 @@ +// run-pass +// Test that we do not error out because of a (False) ambiguity +// between the builtin rules for Sized and the where clause. Issue +// #20959. + +// pretty-expanded FIXME #23616 + +fn foo(x: Option) + where Option : Sized +{ + let _y = x; +} + +fn main() { + foo(Some(22)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-generic.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-generic.rs new file mode 100644 index 000000000000..e2ee301ee1ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-generic.rs @@ -0,0 +1,46 @@ +// run-pass +#![allow(non_camel_case_types)] + + + +trait to_str { + fn to_string_(&self) -> String; +} +impl to_str for isize { + fn to_string_(&self) -> String { self.to_string() } +} +impl to_str for String { + fn to_string_(&self) -> String { self.clone() } +} +impl to_str for () { + fn to_string_(&self) -> String { "()".to_string() } +} + +trait map { + fn map(&self, f: F) -> Vec where F: FnMut(&T) -> U; +} +impl map for Vec { + fn map(&self, mut f: F) -> Vec where F: FnMut(&T) -> U { + let mut r = Vec::new(); + for i in self { + r.push(f(i)); + } + r + } +} + +fn foo>(x: T) -> Vec { + x.map(|_e| "hi".to_string() ) +} +fn bar>(x: T) -> Vec { + x.map(|_e| _e.to_string_() ) +} + +pub fn main() { + assert_eq!(foo(vec![1]), ["hi".to_string()]); + assert_eq!(bar:: >(vec![4, 5]), ["4".to_string(), "5".to_string()]); + assert_eq!(bar:: >(vec!["x".to_string(), "y".to_string()]), + ["x".to_string(), "y".to_string()]); + assert_eq!(bar::<(), Vec<()>>(vec![()]), ["()".to_string()]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-impl-1.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-1.rs new file mode 100644 index 000000000000..f0a6b0e2f1b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-1.rs @@ -0,0 +1,17 @@ +// Test calling methods on an impl for a bare trait. This test checks that the +// trait impl is only applied to a trait object, not concrete types which implement +// the trait. + +trait T {} + +impl<'a> dyn T + 'a { + fn foo(&self) {} +} + +impl T for i32 {} + +fn main() { + let x = &42i32; + x.foo(); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-impl-2.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-2.rs new file mode 100644 index 000000000000..ff54e5f1aad0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-2.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_snake_case)] + +// pretty-expanded FIXME #23616 + +pub mod Foo { + pub trait Trait { + fn foo(&self); + } +} + +mod Bar { + impl<'a> dyn (::Foo::Trait) + 'a { + fn bar(&self) { self.foo() } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-impl-can-not-have-untraitful-items.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-can-not-have-untraitful-items.rs new file mode 100644 index 000000000000..202db64f5cb9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-can-not-have-untraitful-items.rs @@ -0,0 +1,10 @@ +trait A { } + +impl A for isize { + const BAR: () = (); // { dg-error ".E0438." "" { target *-*-* } } + type Baz = (); // { dg-error ".E0437." "" { target *-*-* } } + fn foo(&self) { } // { dg-error ".E0407." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-impl-different-num-params.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-different-num-params.rs new file mode 100644 index 000000000000..da109a57df62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-different-num-params.rs @@ -0,0 +1,13 @@ +trait Foo { + fn bar(&self, x: usize) -> Self; +} +impl Foo for isize { + fn bar(&self) -> isize { +// { dg-error ".E0050." "" { target *-*-* } .-1 } + *self + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-impl-for-module.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-for-module.rs new file mode 100644 index 000000000000..d14cd95b7849 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-for-module.rs @@ -0,0 +1,12 @@ +mod a { +} + +trait A { +} + +impl A for a { // { dg-error ".E0573." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-impl-method-mismatch.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-method-mismatch.rs new file mode 100644 index 000000000000..fe990b3d4ddf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-method-mismatch.rs @@ -0,0 +1,14 @@ +trait Mumbo { + fn jumbo(&self, x: &usize) -> usize; +} + +impl Mumbo for usize { + // Cannot have a larger effect than the trait: + unsafe fn jumbo(&self, x: &usize) { *self + *x; } +// { dg-error ".E0053." "" { target *-*-* } .-1 } +// { dg-error ".E0053." "" { target *-*-* } .-2 } +// { dg-error ".E0053." "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.rs new file mode 100644 index 000000000000..cbc4f6bd47ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.rs @@ -0,0 +1,32 @@ +// Check that when we test the supertrait we ensure consistent use of +// lifetime parameters. In this case, implementing T2<'a,'b> requires +// an impl of T1<'a>, but we have an impl of T1<'b>. + +trait T1<'x> { + fn x(&self) -> &'x isize; +} + +trait T2<'x, 'y> : T1<'x> { + fn y(&self) -> &'y isize; +} + +struct S<'a, 'b> { + a: &'a isize, + b: &'b isize +} + +impl<'a,'b> T1<'b> for S<'a, 'b> { + fn x(&self) -> &'b isize { + self.b + } +} + +impl<'a,'b> T2<'a, 'b> for S<'a, 'b> { // { dg-error ".E0495." "" { target *-*-* } } + fn y(&self) -> &'b isize { + self.b + } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-impl.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-impl.rs new file mode 100644 index 000000000000..368c0d63fa08 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-impl.rs @@ -0,0 +1,42 @@ +// run-pass +// Test calling methods on an impl for a bare trait. + +// aux-build:traitimpl.rs + +extern crate traitimpl; +use traitimpl::Bar; + +static mut COUNT: usize = 1; + +trait T { + fn t(&self) {} +} + +impl<'a> dyn T+'a { + fn foo(&self) { + unsafe { COUNT *= 2; } + } + fn bar() { + unsafe { COUNT *= 3; } + } +} + +impl T for isize {} + +struct Foo; +impl<'a> Bar<'a> for Foo {} + +fn main() { + let x: &dyn T = &42; + + x.foo(); + T::foo(x); + T::bar(); + + unsafe { assert_eq!(COUNT, 12); } + + // Cross-crait case + let x: &dyn Bar = &Foo; + x.bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-auto-xc-2.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-auto-xc-2.rs new file mode 100644 index 000000000000..f35b7326a74f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-auto-xc-2.rs @@ -0,0 +1,24 @@ +// run-pass +// aux-build:trait_inheritance_auto_xc_2_aux.rs + + +extern crate trait_inheritance_auto_xc_2_aux as aux; + +// aux defines impls of Foo, Bar and Baz for A +use aux::{Foo, Bar, Baz, A}; + +// We want to extend all Foo, Bar, Bazes to Quuxes +pub trait Quux: Foo + Bar + Baz { } +impl Quux for T { } + +fn f(a: &T) { + assert_eq!(a.f(), 10); + assert_eq!(a.g(), 20); + assert_eq!(a.h(), 30); +} + +pub fn main() { + let a = &A { x: 3 }; + f(a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-auto-xc.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-auto-xc.rs new file mode 100644 index 000000000000..217a1e026015 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-auto-xc.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(dead_code)] +// aux-build:trait_inheritance_auto_xc_aux.rs + + +extern crate trait_inheritance_auto_xc_aux as aux; + +use aux::{Foo, Bar, Baz, Quux}; + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } +impl Baz for A { fn h(&self) -> isize { 30 } } + +fn f(a: &T) { + assert_eq!(a.f(), 10); + assert_eq!(a.g(), 20); + assert_eq!(a.h(), 30); +} + +pub fn main() { + let a = &A { x: 3 }; + f(a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-auto.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-auto.rs new file mode 100644 index 000000000000..8250bde91ed6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-auto.rs @@ -0,0 +1,30 @@ +// run-pass +#![allow(dead_code)] +// Testing that this impl turns A into a Quux, because +// A is already a Foo Bar Baz + +impl Quux for T { } + +trait Foo { fn f(&self) -> isize; } +trait Bar { fn g(&self) -> isize; } +trait Baz { fn h(&self) -> isize; } + +trait Quux: Foo + Bar + Baz { } + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } +impl Baz for A { fn h(&self) -> isize { 30 } } + +fn f(a: &T) { + assert_eq!(a.f(), 10); + assert_eq!(a.g(), 20); + assert_eq!(a.h(), 30); +} + +pub fn main() { + let a = &A { x: 3 }; + f(a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-call-bound-inherited.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-call-bound-inherited.rs new file mode 100644 index 000000000000..e25e1a4ab6d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-call-bound-inherited.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] + +trait Foo { fn f(&self) -> isize; } +trait Bar : Foo { fn g(&self) -> isize; } + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } + +// Call a function on Foo, given a T: Bar +fn gg(a: &T) -> isize { + a.f() +} + +pub fn main() { + let a = &A { x: 3 }; + assert_eq!(gg(a), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-call-bound-inherited2.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-call-bound-inherited2.rs new file mode 100644 index 000000000000..e5f7f707470f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-call-bound-inherited2.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] + +trait Foo { fn f(&self) -> isize; } +trait Bar : Foo { fn g(&self) -> isize; } +trait Baz : Bar { fn h(&self) -> isize; } + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } +impl Baz for A { fn h(&self) -> isize { 30 } } + +// Call a function on Foo, given a T: Baz, +// which is inherited via Bar +fn gg(a: &T) -> isize { + a.f() +} + +pub fn main() { + let a = &A { x: 3 }; + assert_eq!(gg(a), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cast-without-call-to-supertrait.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cast-without-call-to-supertrait.rs new file mode 100644 index 000000000000..072d964372a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cast-without-call-to-supertrait.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(dead_code)] +// Testing that we can cast to a subtrait and call subtrait +// methods. Not testing supertrait methods + + +trait Foo { + fn f(&self) -> isize; +} + +trait Bar : Foo { + fn g(&self) -> isize; +} + +struct A { + x: isize +} + +impl Foo for A { + fn f(&self) -> isize { 10 } +} + +impl Bar for A { + fn g(&self) -> isize { 20 } +} + +pub fn main() { + let a = &A { x: 3 }; + let afoo = a as &dyn Foo; + let abar = a as &dyn Bar; + assert_eq!(afoo.f(), 10); + assert_eq!(abar.g(), 20); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cast.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cast.rs new file mode 100644 index 000000000000..299a7ca8dbc3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cast.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(dead_code)] +// Testing that supertrait methods can be called on subtrait object types + + +trait Foo { + fn f(&self) -> isize; +} + +trait Bar : Foo { + fn g(&self) -> isize; +} + +struct A { + x: isize +} + +impl Foo for A { + fn f(&self) -> isize { 10 } +} + +impl Bar for A { + fn g(&self) -> isize { 20 } +} + +pub fn main() { + let a = &A { x: 3 }; + let afoo = a as &dyn Foo; + let abar = a as &dyn Bar; + assert_eq!(afoo.f(), 10); + assert_eq!(abar.g(), 20); + assert_eq!(abar.f(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cross-trait-call-xc.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cross-trait-call-xc.rs new file mode 100644 index 000000000000..1047ad8bccdb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cross-trait-call-xc.rs @@ -0,0 +1,21 @@ +// run-pass +// aux-build:trait_xc_call_aux.rs + + +extern crate trait_xc_call_aux as aux; + +use aux::Foo; + +trait Bar : Foo { + fn g(&self) -> isize; +} + +impl Bar for aux::A { + fn g(&self) -> isize { self.f() } +} + +pub fn main() { + let a = &aux::A { x: 3 }; + assert_eq!(a.g(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cross-trait-call.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cross-trait-call.rs new file mode 100644 index 000000000000..36f9557edd5b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-cross-trait-call.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(dead_code)] + +trait Foo { fn f(&self) -> isize; } +trait Bar : Foo { fn g(&self) -> isize; } + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } + +impl Bar for A { + // Testing that this impl can call the impl of Foo + fn g(&self) -> isize { self.f() } +} + +pub fn main() { + let a = &A { x: 3 }; + assert_eq!(a.g(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-diamond.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-diamond.rs new file mode 100644 index 000000000000..8341a4d6ab70 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-diamond.rs @@ -0,0 +1,29 @@ +// run-pass +#![allow(dead_code)] +// B and C both require A, so D does as well, twice, but that's just fine + + +trait A { fn a(&self) -> isize; } +trait B: A { fn b(&self) -> isize; } +trait C: A { fn c(&self) -> isize; } +trait D: B + C { fn d(&self) -> isize; } + +struct S { bogus: () } + +impl A for S { fn a(&self) -> isize { 10 } } +impl B for S { fn b(&self) -> isize { 20 } } +impl C for S { fn c(&self) -> isize { 30 } } +impl D for S { fn d(&self) -> isize { 40 } } + +fn f(x: &T) { + assert_eq!(x.a(), 10); + assert_eq!(x.b(), 20); + assert_eq!(x.c(), 30); + assert_eq!(x.d(), 40); +} + +pub fn main() { + let value = &S { bogus: () }; + f(value); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-multiple-inheritors.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-multiple-inheritors.rs new file mode 100644 index 000000000000..e1cce1472b10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-multiple-inheritors.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] + +trait A { fn a(&self) -> isize; } +trait B: A { fn b(&self) -> isize; } +trait C: A { fn c(&self) -> isize; } + +struct S { bogus: () } + +impl A for S { fn a(&self) -> isize { 10 } } +impl B for S { fn b(&self) -> isize { 20 } } +impl C for S { fn c(&self) -> isize { 30 } } + +// Both B and C inherit from A +fn f(x: &T) { + assert_eq!(x.a(), 10); + assert_eq!(x.b(), 20); + assert_eq!(x.c(), 30); +} + +pub fn main() { + f(&S { bogus: () }) +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-multiple-params.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-multiple-params.rs new file mode 100644 index 000000000000..be9488639da2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-multiple-params.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] + +trait A { fn a(&self) -> isize; } +trait B: A { fn b(&self) -> isize; } +trait C: A { fn c(&self) -> isize; } + +struct S { bogus: () } + +impl A for S { fn a(&self) -> isize { 10 } } +impl B for S { fn b(&self) -> isize { 20 } } +impl C for S { fn c(&self) -> isize { 30 } } + +// Multiple type params, multiple levels of inheritance +fn f(x: &X, y: &Y, z: &Z) { + assert_eq!(x.a(), 10); + assert_eq!(y.a(), 10); + assert_eq!(y.b(), 20); + assert_eq!(z.a(), 10); + assert_eq!(z.c(), 30); +} + +pub fn main() { + let s = &S { bogus: () }; + f(s, s, s); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num.rs new file mode 100644 index 000000000000..971becad605a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +pub trait NumExt: PartialEq + PartialOrd {} + +pub trait FloatExt: NumExt {} + +fn greater_than_one(n: &T) -> bool { loop {} } +fn greater_than_one_float(n: &T) -> bool { loop {} } + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num0.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num0.rs new file mode 100644 index 000000000000..63ced0a864de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num0.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] +// Extending Num and using inherited static methods + +// pretty-expanded FIXME #23616 + +use std::cmp::PartialOrd; + +pub trait NumCast: Sized { + fn from(i: i32) -> Option; +} + +pub trait Num { + fn from_int(i: isize) -> Self; + fn gt(&self, other: &Self) -> bool; +} + +pub trait NumExt: NumCast + PartialOrd { } + +fn greater_than_one(n: &T) -> bool { + n.gt(&NumCast::from(1).unwrap()) +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num1.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num1.rs new file mode 100644 index 000000000000..00fa325066a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num1.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +pub trait NumCast: Sized { + fn from(i: i32) -> Option; +} + +pub trait NumExt: NumCast + PartialOrd { } + +fn greater_than_one(n: &T) -> bool { + *n > NumCast::from(1).unwrap() +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num2.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num2.rs new file mode 100644 index 000000000000..3c2bb253eae3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num2.rs @@ -0,0 +1,87 @@ +// run-pass +// A more complex example of numeric extensions + +pub trait TypeExt {} + +impl TypeExt for u8 {} +impl TypeExt for u16 {} +impl TypeExt for u32 {} +impl TypeExt for u64 {} +impl TypeExt for usize {} + +impl TypeExt for i8 {} +impl TypeExt for i16 {} +impl TypeExt for i32 {} +impl TypeExt for i64 {} +impl TypeExt for isize {} + +impl TypeExt for f32 {} +impl TypeExt for f64 {} + + +pub trait NumExt: TypeExt + PartialEq + PartialOrd {} + +impl NumExt for u8 {} +impl NumExt for u16 {} +impl NumExt for u32 {} +impl NumExt for u64 {} +impl NumExt for usize {} + +impl NumExt for i8 {} +impl NumExt for i16 {} +impl NumExt for i32 {} +impl NumExt for i64 {} +impl NumExt for isize {} + +impl NumExt for f32 {} +impl NumExt for f64 {} + + +pub trait UnSignedExt: NumExt {} + +impl UnSignedExt for u8 {} +impl UnSignedExt for u16 {} +impl UnSignedExt for u32 {} +impl UnSignedExt for u64 {} +impl UnSignedExt for usize {} + + +pub trait SignedExt: NumExt {} + +impl SignedExt for i8 {} +impl SignedExt for i16 {} +impl SignedExt for i32 {} +impl SignedExt for i64 {} +impl SignedExt for isize {} + +impl SignedExt for f32 {} +impl SignedExt for f64 {} + + +pub trait IntegerExt: NumExt {} + +impl IntegerExt for u8 {} +impl IntegerExt for u16 {} +impl IntegerExt for u32 {} +impl IntegerExt for u64 {} +impl IntegerExt for usize {} + +impl IntegerExt for i8 {} +impl IntegerExt for i16 {} +impl IntegerExt for i32 {} +impl IntegerExt for i64 {} +impl IntegerExt for isize {} + + +pub trait FloatExt: NumExt {} + +impl FloatExt for f32 {} +impl FloatExt for f64 {} + + +fn test_float_ext(n: T) { println!("{}", n < n) } + +pub fn main() { + test_float_ext(1f32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num3.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num3.rs new file mode 100644 index 000000000000..2ee71c7f74c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num3.rs @@ -0,0 +1,20 @@ +// run-pass +pub trait NumCast: Sized { + fn from(i: i32) -> Option; +} + +pub trait NumExt: PartialEq + PartialOrd + NumCast {} + +impl NumExt for f32 {} +impl NumCast for f32 { + fn from(i: i32) -> Option { Some(i as f32) } +} + +fn num_eq_one(n: T) { + println!("{}", n == NumCast::from(1).unwrap()) +} + +pub fn main() { + num_eq_one(1f32); // you need to actually use the function to trigger the ICE +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num5.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num5.rs new file mode 100644 index 000000000000..3ded75f7ccec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-num5.rs @@ -0,0 +1,27 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub trait NumCast: Sized { + fn from(i: i32) -> Option; +} + +pub trait NumExt: PartialEq + NumCast {} + +impl NumExt for f32 {} +impl NumExt for isize {} + +impl NumCast for f32 { + fn from(i: i32) -> Option { Some(i as f32) } +} +impl NumCast for isize { + fn from(i: i32) -> Option { Some(i as isize) } +} + +fn num_eq_one() -> T { + NumCast::from(1).unwrap() +} + +pub fn main() { + num_eq_one::(); // you need to actually use the function to trigger the ICE +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-overloading-simple.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-overloading-simple.rs new file mode 100644 index 000000000000..19daa479e4e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-overloading-simple.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(dead_code)] +use std::cmp::PartialEq; + +trait MyNum : PartialEq { } + +#[derive(Debug)] +struct MyInt { val: isize } + +impl PartialEq for MyInt { + fn eq(&self, other: &MyInt) -> bool { self.val == other.val } + fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } +} + +impl MyNum for MyInt {} + +fn f(x: T, y: T) -> bool { + return x == y; +} + +fn mi(v: isize) -> MyInt { MyInt { val: v } } + +pub fn main() { + let (x, y, z) = (mi(3), mi(5), mi(3)); + assert!(x != y); + assert_eq!(x, z); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-overloading-xc-exe.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-overloading-xc-exe.rs new file mode 100644 index 000000000000..7d3eff4cb79a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-overloading-xc-exe.rs @@ -0,0 +1,21 @@ +// run-pass +// aux-build:trait_inheritance_overloading_xc.rs + + +extern crate trait_inheritance_overloading_xc; +use trait_inheritance_overloading_xc::{MyNum, MyInt}; + +fn f(x: T, y: T) -> (T, T, T) { + return (x.clone() + y.clone(), x.clone() - y.clone(), x * y); +} + +fn mi(v: isize) -> MyInt { MyInt { val: v } } + +pub fn main() { + let (x, y) = (mi(3), mi(5)); + let (a, b, c) = f(x, y); + assert_eq!(a, mi(8)); + assert_eq!(b, mi(-2)); + assert_eq!(c, mi(15)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-overloading.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-overloading.rs new file mode 100644 index 000000000000..dadff566c16b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-overloading.rs @@ -0,0 +1,48 @@ +// run-pass +use std::cmp::PartialEq; +use std::ops::{Add, Sub, Mul}; + +trait MyNum : Add + Sub + Mul + PartialEq + Clone { } + +#[derive(Clone, Debug)] +struct MyInt { val: isize } + +impl Add for MyInt { + type Output = MyInt; + + fn add(self, other: MyInt) -> MyInt { mi(self.val + other.val) } +} + +impl Sub for MyInt { + type Output = MyInt; + + fn sub(self, other: MyInt) -> MyInt { mi(self.val - other.val) } +} + +impl Mul for MyInt { + type Output = MyInt; + + fn mul(self, other: MyInt) -> MyInt { mi(self.val * other.val) } +} + +impl PartialEq for MyInt { + fn eq(&self, other: &MyInt) -> bool { self.val == other.val } + fn ne(&self, other: &MyInt) -> bool { !self.eq(other) } +} + +impl MyNum for MyInt {} + +fn f(x: T, y: T) -> (T, T, T) { + return (x.clone() + y.clone(), x.clone() - y.clone(), x * y); +} + +fn mi(v: isize) -> MyInt { MyInt { val: v } } + +pub fn main() { + let (x, y) = (mi(3), mi(5)); + let (a, b, c) = f(x, y); + assert_eq!(a, mi(8)); + assert_eq!(b, mi(-2)); + assert_eq!(c, mi(15)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-self-in-supertype.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-self-in-supertype.rs new file mode 100644 index 000000000000..e9c3a656771a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-self-in-supertype.rs @@ -0,0 +1,63 @@ +// run-pass +// Test for issue #4183: use of Self in supertraits. + +pub static FUZZY_EPSILON: f64 = 0.1; + +pub trait FuzzyEq { + fn fuzzy_eq(&self, other: &Self) -> bool; + fn fuzzy_eq_eps(&self, other: &Self, epsilon: &Eps) -> bool; +} + +trait Float: Sized+FuzzyEq { + fn two_pi() -> Self; +} + +impl FuzzyEq for f32 { + fn fuzzy_eq(&self, other: &f32) -> bool { + self.fuzzy_eq_eps(other, &(FUZZY_EPSILON as f32)) + } + + fn fuzzy_eq_eps(&self, other: &f32, epsilon: &f32) -> bool { + (*self - *other).abs() < *epsilon + } +} + +impl Float for f32 { + fn two_pi() -> f32 { 6.28318530717958647692528676655900576_f32 } +} + +impl FuzzyEq for f64 { + fn fuzzy_eq(&self, other: &f64) -> bool { + self.fuzzy_eq_eps(other, &(FUZZY_EPSILON as f64)) + } + + fn fuzzy_eq_eps(&self, other: &f64, epsilon: &f64) -> bool { + (*self - *other).abs() < *epsilon + } +} + +impl Float for f64 { + fn two_pi() -> f64 { 6.28318530717958647692528676655900576_f64 } +} + +fn compare(f1: F) -> bool { + let f2 = Float::two_pi(); + f1.fuzzy_eq(&f2) +} + +pub fn main() { + assert!(compare::(6.28318530717958647692528676655900576)); + assert!(compare::(6.29)); + assert!(compare::(6.3)); + assert!(compare::(6.19)); + assert!(!compare::(7.28318530717958647692528676655900576)); + assert!(!compare::(6.18)); + + assert!(compare::(6.28318530717958647692528676655900576)); + assert!(compare::(6.29)); + assert!(compare::(6.3)); + assert!(compare::(6.19)); + assert!(!compare::(7.28318530717958647692528676655900576)); + assert!(!compare::(6.18)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-self.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-self.rs new file mode 100644 index 000000000000..8fc83400c2e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-self.rs @@ -0,0 +1,30 @@ +// run-pass +trait Foo { + fn f(&self, x: &T); +} + +trait Bar : Sized + Foo { + fn g(&self); +} + +struct S { + x: isize +} + +impl Foo for S { + fn f(&self, x: &S) { + println!("{}", x.x); + } +} + +impl Bar for S { + fn g(&self) { + self.f(self); + } +} + +pub fn main() { + let s = S { x: 1 }; + s.g(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-simple.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-simple.rs new file mode 100644 index 000000000000..0e45efcd1f60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-simple.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(dead_code)] + +trait Foo { fn f(&self) -> isize; } +trait Bar : Foo { fn g(&self) -> isize; } + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } + +fn ff(a: &T) -> isize { + a.f() +} + +fn gg(a: &T) -> isize { + a.g() +} + +pub fn main() { + let a = &A { x: 3 }; + assert_eq!(ff(a), 10); + assert_eq!(gg(a), 20); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-static.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-static.rs new file mode 100644 index 000000000000..63c66c6272c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-static.rs @@ -0,0 +1,27 @@ +// run-pass + +pub trait MyNum { + fn from_int(_: isize) -> Self; +} + +pub trait NumExt: MyNum { } + +struct S { v: isize } + +impl MyNum for S { + fn from_int(i: isize) -> S { + S { + v: i + } + } +} + +impl NumExt for S { } + +fn greater_than_one() -> T { MyNum::from_int(1) } + +pub fn main() { + let v: S = greater_than_one(); + assert_eq!(v.v, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-static2.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-static2.rs new file mode 100644 index 000000000000..145e42e72f96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-static2.rs @@ -0,0 +1,30 @@ +// run-pass +pub trait MyEq {} + +pub trait MyNum { + fn from_int(_: isize) -> Self; +} + +pub trait NumExt: MyEq + MyNum { } + +struct S { v: isize } + +impl MyEq for S { } + +impl MyNum for S { + fn from_int(i: isize) -> S { + S { + v: i + } + } +} + +impl NumExt for S { } + +fn greater_than_one() -> T { MyNum::from_int(1) } + +pub fn main() { + let v: S = greater_than_one(); + assert_eq!(v.v, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-subst.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-subst.rs new file mode 100644 index 000000000000..b7b4ef14c480 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-subst.rs @@ -0,0 +1,28 @@ +// run-pass + +pub trait Add { + fn add(&self, rhs: &RHS) -> Result; +} + +trait MyNum : Sized + Add { } + +struct MyInt { val: isize } + +impl Add for MyInt { + fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) } +} + +impl MyNum for MyInt {} + +fn f(x: T, y: T) -> T { + return x.add(&y); +} + +fn mi(v: isize) -> MyInt { MyInt { val: v } } + +pub fn main() { + let (x, y) = (mi(3), mi(5)); + let z = f(x, y); + assert_eq!(z.val, 8) +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-subst2.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-subst2.rs new file mode 100644 index 000000000000..92f5c58d38b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-subst2.rs @@ -0,0 +1,38 @@ +// run-pass + +trait Panda { + fn chomp(&self, bamboo: &T) -> T; +} + +trait Add: Panda { + fn add(&self, rhs: &RHS) -> Result; +} + +trait MyNum : Sized + Add { } + +struct MyInt { val: isize } + +impl Panda for MyInt { + fn chomp(&self, bamboo: &MyInt) -> MyInt { + mi(self.val + bamboo.val) + } +} + +impl Add for MyInt { + fn add(&self, other: &MyInt) -> MyInt { self.chomp(other) } +} + +impl MyNum for MyInt {} + +fn f(x: T, y: T) -> T { + return x.add(&y).chomp(&y); +} + +fn mi(v: isize) -> MyInt { MyInt { val: v } } + +pub fn main() { + let (x, y) = (mi(3), mi(5)); + let z = f(x, y); + assert_eq!(z.val, 13); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-visibility.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-visibility.rs new file mode 100644 index 000000000000..f85288fb4cd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance-visibility.rs @@ -0,0 +1,21 @@ +// run-pass + +mod traits { + pub trait Foo { fn f(&self) -> isize; } + + impl Foo for isize { fn f(&self) -> isize { 10 } } +} + +trait Quux: traits::Foo { } +impl Quux for T { } + +// Foo is not in scope but because Quux is we can still access +// Foo's methods on a Quux bound typaram +fn f(x: &T) { + assert_eq!(x.f(), 10); +} + +pub fn main() { + f(&0) +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance2.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance2.rs new file mode 100644 index 000000000000..a899bacc8aeb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-inheritance2.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(dead_code)] + +trait Foo { fn f(&self) -> isize; } +trait Bar { fn g(&self) -> isize; } +trait Baz { fn h(&self) -> isize; } + +trait Quux: Foo + Bar + Baz { } + +struct A { x: isize } + +impl Foo for A { fn f(&self) -> isize { 10 } } +impl Bar for A { fn g(&self) -> isize { 20 } } +impl Baz for A { fn h(&self) -> isize { 30 } } +impl Quux for A {} + +fn f(a: &T) { + assert_eq!(a.f(), 10); + assert_eq!(a.g(), 20); + assert_eq!(a.h(), 30); +} + +pub fn main() { + let a = &A { x: 3 }; + f(a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-item-inside-macro.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-item-inside-macro.rs new file mode 100644 index 000000000000..82ef4942df32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-item-inside-macro.rs @@ -0,0 +1,31 @@ +// run-pass +// Issue #34183 + +macro_rules! foo { + () => { + fn foo() { } + } +} + +macro_rules! bar { + () => { + fn bar(); + } +} + +trait Bleh { + foo!(); + bar!(); +} + +struct Test; + +impl Bleh for Test { + fn bar() {} +} + +fn main() { + Test::bar(); + Test::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-item-privacy.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-item-privacy.rs new file mode 100644 index 000000000000..fbdeb7591cfb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-item-privacy.rs @@ -0,0 +1,135 @@ +#![feature(associated_type_defaults)] + +struct S; + +mod method { + trait A { + fn a(&self) { } + } + + pub trait B { + fn b(&self) { } + } + + pub trait C: A + B { + fn c(&self) { } + } + + impl A for ::S {} + impl B for ::S {} + impl C for ::S {} +} + +mod assoc_const { + trait A { + const A: u8 = 0; + } + + pub trait B { + const B: u8 = 0; + } + + pub trait C: A + B { + const C: u8 = 0; + } + + impl A for ::S {} + impl B for ::S {} + impl C for ::S {} +} + +mod assoc_ty { + trait A { + type A = u8; + } + + pub trait B { + type B = u8; + } + + pub trait C: A + B { + type C = u8; + } + + impl A for ::S {} + impl B for ::S {} + impl C for ::S {} +} + +fn check_method() { + // A is private + // B is pub, not in scope + // C : A + B is pub, in scope + use method::C; + + // Methods, method call + // a, b, c are resolved as trait items, their traits need to be in scope + S.a(); // { dg-error ".E0599." "" { target *-*-* } } + S.b(); // { dg-error ".E0599." "" { target *-*-* } } + S.c(); // OK + // a, b, c are resolved as inherent items, their traits don't need to be in scope + let c = &S as &dyn C; + c.a(); // { dg-error ".E0624." "" { target *-*-* } } + c.b(); // OK + c.c(); // OK + + // Methods, UFCS + // a, b, c are resolved as trait items, their traits need to be in scope + S::a(&S); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + S::b(&S); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + S::c(&S); // OK + // a, b, c are resolved as inherent items, their traits don't need to be in scope + C::a(&S); // { dg-error ".E0624." "" { target *-*-* } } + C::b(&S); // OK + C::c(&S); // OK +} + +fn check_assoc_const() { + // A is private + // B is pub, not in scope + // C : A + B is pub, in scope + use assoc_const::C; + + // Associated constants + // A, B, C are resolved as trait items, their traits need to be in scope + S::A; // { dg-error ".E0599." "" { target *-*-* } } + S::B; // { dg-error ".E0599." "" { target *-*-* } } + S::C; // OK + // A, B, C are resolved as inherent items, their traits don't need to be in scope + C::A; // { dg-error ".E0038." "" { target *-*-* } } +// { dg-error ".E0038." "" { target *-*-* } .-1 } + C::B; // ERROR the trait `assoc_const::C` cannot be made into an object + C::C; // OK +} + +fn check_assoc_ty() { + // A is private + // B is pub, not in scope + // C : A + B is pub, in scope + use assoc_ty::C; + + // Associated types + // A, B, C are resolved as trait items, their traits need to be in scope, not implemented yet + let _: S::A; // { dg-error ".E0223." "" { target *-*-* } } + let _: S::B; // { dg-error ".E0223." "" { target *-*-* } } + let _: S::C; // { dg-error ".E0223." "" { target *-*-* } } + // A, B, C are resolved as inherent items, their traits don't need to be in scope + let _: T::A; // { dg-error "" "" { target *-*-* } } + let _: T::B; // OK + let _: T::C; // OK + + // Associated types, bindings + let _: dyn assoc_ty::B< + B = u8, // OK + >; + let _: dyn C< + A = u8, // { dg-error "" "" { target *-*-* } } + B = u8, // OK + C = u8, // OK + >; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-matching-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-matching-lifetimes.rs new file mode 100644 index 000000000000..70b84a2feeba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-matching-lifetimes.rs @@ -0,0 +1,21 @@ +// Tests that the trait matching code takes lifetime parameters into account. +// (Issue #15517.) + +struct Foo<'a,'b> { + x: &'a isize, + y: &'b isize, +} + +trait Tr : Sized { + fn foo(x: Self) {} +} + +impl<'a,'b> Tr for Foo<'a,'b> { + fn foo(x: Foo<'b,'a>) { +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + } +} + +fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-method-private.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-method-private.rs new file mode 100644 index 000000000000..eec1af0e3b29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-method-private.rs @@ -0,0 +1,21 @@ +mod inner { + pub trait Bar { + fn method(&self); + } + + pub struct Foo; + + impl Foo { + fn method(&self) {} + } + + impl Bar for Foo { + fn method(&self) {} + } +} + +fn main() { + let foo = inner::Foo; + foo.method(); // { dg-error ".E0624." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-auto-dedup-in-impl.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-auto-dedup-in-impl.rs new file mode 100644 index 000000000000..8430fe299a66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-auto-dedup-in-impl.rs @@ -0,0 +1,20 @@ +// Checks to make sure that `dyn Trait + Send` and `dyn Trait + Send + Send` are the same type. +// Issue: #47010 + +struct Struct; +impl Trait for Struct {} +trait Trait {} + +type Send1 = dyn Trait + Send; +type Send2 = dyn Trait + Send + Send; + +fn main () {} + +impl dyn Trait + Send { + fn test(&self) { println!("one"); } // { dg-error ".E0592." "" { target *-*-* } } +} + +impl dyn Trait + Send + Send { + fn test(&self) { println!("two"); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-auto-dedup.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-auto-dedup.rs new file mode 100644 index 000000000000..1027dfa12f71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-auto-dedup.rs @@ -0,0 +1,47 @@ +// run-pass + +#![allow(unused_assignments)] + +// Test that duplicate auto trait bounds in trait objects don't create new types. +#[allow(unused_assignments)] +use std::marker::Send as SendAlias; + +// A dummy trait for the non-auto trait. +trait Trait {} + +// A dummy struct to implement `Trait` and `Send`. +struct Struct; + +impl Trait for Struct {} + +// These three functions should be equivalent. +fn takes_dyn_trait_send(_: Box) {} +fn takes_dyn_trait_send_send(_: Box) {} +fn takes_dyn_trait_send_sendalias(_: Box) {} + +impl dyn Trait + Send + Send { + fn do_nothing(&self) {} +} + +fn main() { + // 1. Moving into a variable with more `Send`s and back. + let mut dyn_trait_send = Box::new(Struct) as Box; + let dyn_trait_send_send: Box = dyn_trait_send; + dyn_trait_send = dyn_trait_send_send; + + // 2. Calling methods with different number of `Send`s. + let dyn_trait_send = Box::new(Struct) as Box; + takes_dyn_trait_send_send(dyn_trait_send); + + let dyn_trait_send_send = Box::new(Struct) as Box; + takes_dyn_trait_send(dyn_trait_send_send); + + // 3. Aliases to the trait are transparent. + let dyn_trait_send = Box::new(Struct) as Box; + takes_dyn_trait_send_sendalias(dyn_trait_send); + + // 4. Calling an impl that duplicates an auto trait. + let dyn_trait_send = Box::new(Struct) as Box; + dyn_trait_send.do_nothing(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-1.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-1.rs new file mode 100644 index 000000000000..dad4a0243b40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-1.rs @@ -0,0 +1,25 @@ +// Check that we don't have a cycle when we try to normalize `Self::U` in the +// bound below. + +// check-pass + +trait Is { + type T; +} + +impl Is for U { + type T = U; +} + +trait Obj { + type U: Is; +} + +fn is_obj(_: &T) {} + +fn f(x: &dyn Obj) { + is_obj(x) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-2.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-2.rs new file mode 100644 index 000000000000..cb787addf972 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-2.rs @@ -0,0 +1,29 @@ +// Check that we don't have a cycle when we try to normalize `Self::V` in the +// bound below. + +// check-pass + +trait Is { + type T; +} + +impl Is for U { + type T = U; +} + +trait Super { + type V; +} + +trait Obj: Super { + type U: Is; +} + +fn is_obj(_: &T) {} + +fn f(x: &dyn Obj) { + is_obj(x) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-3.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-3.rs new file mode 100644 index 000000000000..b9ff31a5b56a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-3.rs @@ -0,0 +1,26 @@ +// Check that we don't have a cycle when we try to normalize `Self::V` in the +// bound below. + +// check-pass + +trait Is { + type T; +} + +impl Is for U { + type T = U; +} + +trait Obj { + type U: Is; + type V; +} + +fn is_obj(_: &T) {} + +fn f(x: &dyn Obj) { + is_obj(x) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-4.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-4.rs new file mode 100644 index 000000000000..06e475d3fc55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-bounds-cycle-4.rs @@ -0,0 +1,26 @@ +// Check that we don't have a cycle when we try to normalize `Self::U` in the +// bound below. Make sure that having a lifetime on the trait object doesn't break things + +// check-pass + +trait Is { + type T; +} + +impl Is for U { + type T = U; +} + +trait Obj<'a> { + type U: Is; + type V; +} + +fn is_obj<'a, T: ?Sized + Obj<'a>>(_: &T) {} + +fn f<'a>(x: &dyn Obj<'a, U = i32, V = i32>) { + is_obj(x) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-exclusion.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-exclusion.rs new file mode 100644 index 000000000000..c67e1c085ab1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-exclusion.rs @@ -0,0 +1,20 @@ +// run-pass +trait Future: 'static { + // The requirement for Self: Sized must prevent instantiation of + // Future::forget in vtables, otherwise there's an infinite type + // recursion through as Future>::forget. + fn forget(self) where Self: Sized { + Box::new(Map(self)) as Box; + } +} + +struct Map(A); +impl Future for Map {} + +pub struct Promise; +impl Future for Promise {} + +fn main() { + Promise.forget(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-generics.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-generics.rs new file mode 100644 index 000000000000..b532d47c5b06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-generics.rs @@ -0,0 +1,44 @@ +// run-pass +// test for #8664 + +#![feature(box_syntax)] + +use std::marker; + +pub trait Trait2 { + fn doit(&self) -> A; +} + +pub struct Impl { + m1: marker::PhantomData<(A1,A2,A3)>, + /* + * With A2 we get the ICE: + * task failed at 'index out of bounds: the len is 1 but the index is 1', + * src/librustc/middle/subst.rs:58 + */ + t: Box+'static> +} + +impl Impl { + pub fn step(&self) { + self.t.doit(); + } +} + +// test for #8601 + +enum Type { Constant(T) } + +trait Trait { + fn method(&self, _: Type<(K,V)>) -> isize; +} + +impl Trait for () { + fn method(&self, _x: Type<(u8,V)>) -> isize { 0 } +} + +pub fn main() { + let a = box () as Box>; + assert_eq!(a.method(Type::Constant((1, 2))), 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-lifetime-first.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-lifetime-first.rs new file mode 100644 index 000000000000..6c23679c6ffb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-lifetime-first.rs @@ -0,0 +1,14 @@ +// run-pass +use std::fmt::Display; + +static BYTE: u8 = 33; + +fn main() { + let x: &(dyn 'static + Display) = &BYTE; + let y: Box = Box::new(BYTE); + let xstr = format!("{}", x); + let ystr = format!("{}", y); + assert_eq!(xstr, "33"); + assert_eq!(ystr, "33"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-macro-matcher.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-macro-matcher.rs new file mode 100644 index 000000000000..c5f5b4b5067e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-macro-matcher.rs @@ -0,0 +1,13 @@ +// `ty` matcher accepts trait object types + +macro_rules! m { + ($t: ty) => ( let _: $t; ) +} + +fn main() { + m!(dyn Copy + Send + 'static); +// { dg-error ".E0038." "" { target *-*-* } .-1 } + m!(dyn 'static + Send); + m!(dyn 'static +); // { dg-error ".E0224." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-safety.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-safety.rs new file mode 100644 index 000000000000..e7f1f8691684 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-safety.rs @@ -0,0 +1,18 @@ +// Check that static methods are not object-safe. + +trait Tr { + fn foo(); + fn bar(&self) { } +} + +struct St; + +impl Tr for St { + fn foo() {} +} + +fn main() { + let _: &dyn Tr = &St; // { dg-error ".E0038." "" { target *-*-* } } +// { dg-error ".E0038." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-supertrait-lifetime-bound.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-supertrait-lifetime-bound.rs new file mode 100644 index 000000000000..cc2e6e8d4df0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-supertrait-lifetime-bound.rs @@ -0,0 +1,17 @@ +// check-pass + +use std::any::Any; + +trait A: Any { + fn m(&self) {} +} + +impl A for T {} + +fn call_obj<'a>() { + let obj: &dyn A<&'a ()> = &(); + obj.m(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-vs-lifetime-2.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-vs-lifetime-2.rs new file mode 100644 index 000000000000..b460356d9d07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-vs-lifetime-2.rs @@ -0,0 +1,12 @@ +// A few contrived examples where lifetime should (or should not) be parsed as an object type. +// Lifetimes parsed as types are still rejected later by semantic checks. + +// `'static` is a lifetime, `'static +` is a type, `'a` is a type +fn g() where + 'static: 'static, + dyn 'static +: 'static + Copy, +// { dg-error ".E0224." "" { target *-*-* } .-1 } +{} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-vs-lifetime.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-vs-lifetime.rs new file mode 100644 index 000000000000..91ffc659ab27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-vs-lifetime.rs @@ -0,0 +1,18 @@ +// A few contrived examples where lifetime should (or should not) be parsed as an object type. +// Lifetimes parsed as types are still rejected later by semantic checks. + +struct S<'a, T>(&'a u8, T); + +fn main() { + // `'static` is a lifetime argument, `'static +` is a type argument + let _: S<'static, u8>; + let _: S<'static, dyn 'static +>; +// { dg-error ".E0224." "" { target *-*-* } .-1 } + let _: S<'static, 'static>; +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } + let _: S; +// { dg-error ".E0747." "" { target *-*-* } .-1 } +// { dg-error ".E0747." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-with-lifetime-bound.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-with-lifetime-bound.rs new file mode 100644 index 000000000000..efb2b1dbdc08 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-with-lifetime-bound.rs @@ -0,0 +1,35 @@ +// run-pass +// Uncovered during work on new scoping rules for safe destructors +// as an important use case to support properly. + + +pub struct E<'a> { + pub f: &'a u8, +} +impl<'b> E<'b> { + pub fn m(&self) -> &'b u8 { self.f } +} + +pub struct P<'c> { + pub g: &'c u8, +} +pub trait M { + fn n(&self) -> u8; +} +impl<'d> M for P<'d> { + fn n(&self) -> u8 { *self.g } +} + +fn extension<'e>(x: &'e E<'e>) -> Box { + loop { + let p = P { g: x.m() }; + return Box::new(p) as Box; + } +} + +fn main() { + let w = E { f: &10 }; + let o = extension(&w); + assert_eq!(o.n(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-with-self-in-projection-output-bad.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-with-self-in-projection-output-bad.rs new file mode 100644 index 000000000000..3e0a2f6f503a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-with-self-in-projection-output-bad.rs @@ -0,0 +1,51 @@ +// Regression test for #56288. Checks that if a supertrait defines an associated type +// projection that references `Self`, then that associated type must still be explicitly +// specified in the `dyn Trait` variant, since we don't know what `Self` is anymore. + +trait Base { + type Output; +} + +trait Helper: Base::Target> { + type Target; +} + +impl Base for u32 +{ + type Output = i32; +} + +impl Helper for u32 +{ + type Target = i32; +} + +trait ConstI32 { + type Out; +} + +impl ConstI32 for T { + type Out = i32; +} + +// Test that you still need to manually give a projection type if the Output type +// is normalizable. +trait NormalizableHelper: + Base::Out> +{ + type Target; +} + +impl NormalizableHelper for u32 +{ + type Target = i32; +} + +fn main() { + let _x: Box> = Box::new(2u32); +// { dg-error ".E0191." "" { target *-*-* } .-1 } + + let _y: Box> = Box::new(2u32); +// { dg-error ".E0191." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-with-self-in-projection-output-good.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-with-self-in-projection-output-good.rs new file mode 100644 index 000000000000..c9af89f4e64a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-with-self-in-projection-output-good.rs @@ -0,0 +1,29 @@ +// build-pass (FIXME(62277): could be check-pass?) + +// Regression test related to #56288. Check that a supertrait projection (of +// `Output`) that references `Self` can be ok if it is referencing a projection (of +// `Self::Target`, in this case). Note that we still require the user to manually +// specify both `Target` and `Output` for now. + +trait Base { + type Output; +} + +trait Helper: Base::Target> { + type Target; +} + +impl Base for u32 +{ + type Output = i32; +} + +impl Helper for u32 +{ + type Target = i32; +} + +fn main() { + let _x: Box> = Box::new(2u32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs new file mode 100644 index 000000000000..50320fe17642 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs @@ -0,0 +1,52 @@ +// build-pass (FIXME(62277): could be check-pass?) + +// FIXME(eddyb) shorten the name so windows doesn't choke on it. +#![crate_name = "trait_test"] + +// Regression test related to #56288. Check that a supertrait projection (of +// `Output`) that references `Self` is ok if there is another occurrence of +// the same supertrait that specifies the projection explicitly, even if +// the projection's associated type is not explicitly specified in the object type. +// +// Note that in order for this to compile, we need the `Self`-referencing projection +// to normalize fairly directly to a concrete type, otherwise the trait resolver +// will hate us. +// +// There is a test in `trait-object-with-self-in-projection-output-bad.rs` that +// having a normalizing, but `Self`-containing projection does not *by itself* +// allow you to avoid writing the projected type (`Output`, in this example) +// explicitly. + +trait ConstI32 { + type Out; +} + +impl ConstI32 for T { + type Out = i32; +} + +trait Base { + type Output; +} + +trait NormalizingHelper: Base::Out> + Base { + type Target; +} + +impl Base for u32 +{ + type Output = i32; +} + +impl NormalizingHelper for u32 +{ + type Target = i32; +} + +fn main() { + // Make sure this works both with and without the associated type + // being specified. + let _x: Box> = Box::new(2u32); + let _y: Box> = Box::new(2u32); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-or-new-type-instead.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-or-new-type-instead.rs new file mode 100644 index 000000000000..69421db3b8a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-or-new-type-instead.rs @@ -0,0 +1,7 @@ +impl Option { +// { dg-error ".E0116." "" { target *-*-* } .-1 } + pub fn foo(&self) { } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-param-without-lifetime-constraint.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-param-without-lifetime-constraint.rs new file mode 100644 index 000000000000..20e7bcad62cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-param-without-lifetime-constraint.rs @@ -0,0 +1,21 @@ +struct Article { + proof_reader: ProofReader, +} + +struct ProofReader { + name: String, +} + +pub trait HaveRelationship { + fn get_relation(&self) -> To; +} + +impl HaveRelationship<&ProofReader> for Article { + fn get_relation(&self) -> &ProofReader { +// { dg-error "" "" { target *-*-* } .-1 } + &self.proof_reader + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-privacy.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-privacy.rs new file mode 100644 index 000000000000..dab9a8767512 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-privacy.rs @@ -0,0 +1,25 @@ +// build-pass (FIXME(62277): could be check-pass?) +#![allow(dead_code)] +mod foo { + pub use self::bar::T; + mod bar { + pub trait T { + fn f(&self) {} + } + impl T for () {} + } +} + +fn g() { + use foo::T; + ().f(); // Check that this does not trigger a privacy error +} + +fn f() { + let error = ::std::thread::spawn(|| {}).join().unwrap_err(); + error.type_id(); // Regression test for #21670 +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-region-pointer-simple.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-region-pointer-simple.rs new file mode 100644 index 000000000000..6d179bff44cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-region-pointer-simple.rs @@ -0,0 +1,22 @@ +// run-pass +trait Foo { + fn f(&self) -> isize; +} + +struct A { + x: isize +} + +impl Foo for A { + fn f(&self) -> isize { + println!("Today's number is {}", self.x); + return self.x; + } +} + +pub fn main() { + let a = A { x: 3 }; + let b = (&a) as &dyn Foo; + assert_eq!(b.f(), 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-resolution-in-overloaded-op.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-resolution-in-overloaded-op.rs new file mode 100644 index 000000000000..0a83d437ef26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-resolution-in-overloaded-op.rs @@ -0,0 +1,12 @@ +// #12402 Operator overloading only considers the method name, not which trait is implemented + +trait MyMul { + fn mul(&self, rhs: &Rhs) -> Res; +} + +fn foo>(a: &T, b: f64) -> f64 { + a * b // { dg-error ".E0369." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-safety-fn-body.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-safety-fn-body.rs new file mode 100644 index 000000000000..f05b7ad67ea0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-safety-fn-body.rs @@ -0,0 +1,17 @@ +// Check that an unsafe impl does not imply that unsafe actions are +// legal in the methods. + +unsafe trait UnsafeTrait : Sized { + fn foo(self) { } +} + +unsafe impl UnsafeTrait for *mut isize { + fn foo(self) { + // Unsafe actions are not made legal by taking place in an unsafe trait: + *self += 1; +// { dg-error ".E0133." "" { target *-*-* } .-1 } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-safety-inherent-impl.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-safety-inherent-impl.rs new file mode 100644 index 000000000000..0d9df8f29297 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-safety-inherent-impl.rs @@ -0,0 +1,10 @@ +// Check that inherent impls cannot be unsafe. + +struct SomeStruct; + +unsafe impl SomeStruct { // { dg-error ".E0197." "" { target *-*-* } } + fn foo(self) { } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-safety-ok-cc.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-safety-ok-cc.rs new file mode 100644 index 000000000000..bfd54e1c9790 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-safety-ok-cc.rs @@ -0,0 +1,25 @@ +// run-pass +// aux-build:trait_safety_lib.rs + +// Simple smoke test that unsafe traits can be compiled across crates. + + +extern crate trait_safety_lib as lib; + +use lib::Foo; + +struct Bar { x: isize } +unsafe impl Foo for Bar { + fn foo(&self) -> isize { self.x } +} + +fn take_foo(f: &F) -> isize { f.foo() } + +fn main() { + let x: isize = 22; + assert_eq!(22, take_foo(&x)); + + let x: Bar = Bar { x: 23 }; + assert_eq!(23, take_foo(&x)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-safety-ok.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-safety-ok.rs new file mode 100644 index 000000000000..1f1ce2b74c0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-safety-ok.rs @@ -0,0 +1,19 @@ +// run-pass +// Simple smoke test that unsafe traits can be compiled etc. + + +unsafe trait Foo { + fn foo(&self) -> isize; +} + +unsafe impl Foo for isize { + fn foo(&self) -> isize { *self } +} + +fn take_foo(f: &F) -> isize { f.foo() } + +fn main() { + let x: isize = 22; + assert_eq!(22, take_foo(&x)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-safety-trait-impl-cc.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-safety-trait-impl-cc.rs new file mode 100644 index 000000000000..d992edcde6c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-safety-trait-impl-cc.rs @@ -0,0 +1,16 @@ +// aux-build:trait_safety_lib.rs + +// Check that unsafe traits require unsafe impls and that inherent +// impls cannot be unsafe. + +extern crate trait_safety_lib as lib; + +struct Bar; +impl lib::Foo for Bar { // { dg-error ".E0200." "" { target *-*-* } } + fn foo(&self) -> isize { + panic!(); + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-safety-trait-impl.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-safety-trait-impl.rs new file mode 100644 index 000000000000..3a4f059bc0ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-safety-trait-impl.rs @@ -0,0 +1,19 @@ +// Check that unsafe traits require unsafe impls and that inherent +// impls cannot be unsafe. + +trait SafeTrait { + fn foo(&self) { } +} + +unsafe trait UnsafeTrait { + fn foo(&self) { } +} + +unsafe impl UnsafeTrait for u8 { } // OK + +impl UnsafeTrait for u16 { } // { dg-error ".E0200." "" { target *-*-* } } + +unsafe impl SafeTrait for u32 { } // { dg-error ".E0199." "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-static-method-generic-inference.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-static-method-generic-inference.rs new file mode 100644 index 000000000000..c6c46853899f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-static-method-generic-inference.rs @@ -0,0 +1,29 @@ +// Issue #3902. We are (at least currently) unable to infer `Self` +// based on `T`, even though there is only a single impl, because of +// the possibility of associated types and other things (basically: no +// constraints on `Self` here at all). + +mod base { + pub trait HasNew { + fn new() -> T; + fn dummy(&self) { } + } + + pub struct Foo { + dummy: (), + } + + impl HasNew for Foo { + fn new() -> Foo { + Foo { dummy: () } + } + } +} + +pub fn foo() { + let _f: base::Foo = base::HasNew::new(); +// { dg-error ".E0283." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-static-method-overwriting.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-static-method-overwriting.rs new file mode 100644 index 000000000000..e858cd87534f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-static-method-overwriting.rs @@ -0,0 +1,35 @@ +// run-pass +#![allow(dead_code)] +mod base { + pub trait HasNew { + fn new() -> Self; + } + + pub struct Foo { + dummy: (), + } + + impl ::base::HasNew for Foo { + fn new() -> Foo { + println!("Foo"); + Foo { dummy: () } + } + } + + pub struct Bar { + dummy: (), + } + + impl ::base::HasNew for Bar { + fn new() -> Bar { + println!("Bar"); + Bar { dummy: () } + } + } +} + +pub fn main() { + let _f: base::Foo = base::HasNew::new(); + let _b: base::Bar = base::HasNew::new(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-issue-39029.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-issue-39029.rs new file mode 100644 index 000000000000..ba350132ff1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-issue-39029.rs @@ -0,0 +1,19 @@ +// run-rustfix +use std::net::TcpListener; + +struct NoToSocketAddrs(String); + +impl std::ops::Deref for NoToSocketAddrs { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +fn main() { + let _works = TcpListener::bind("some string"); + let bad = NoToSocketAddrs("bad".to_owned()); + let _errors = TcpListener::bind(&bad); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-issue-62530.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-issue-62530.rs new file mode 100644 index 000000000000..a70580e5ac55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-issue-62530.rs @@ -0,0 +1,16 @@ +// run-rustfix +fn takes_str(_x: &str) {} + +fn takes_type_parameter(_x: T) where T: SomeTrait {} + +trait SomeTrait {} +impl SomeTrait for &'_ str {} +impl SomeTrait for char {} + +fn main() { + let string = String::new(); + takes_str(&string); // Ok + takes_type_parameter(&string); // Error +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-multiple-0.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-multiple-0.rs new file mode 100644 index 000000000000..f49f9a85b4dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-multiple-0.rs @@ -0,0 +1,37 @@ +// run-rustfix +use std::ops::Deref; + +trait Happy {} +struct LDM; +impl Happy for &LDM {} + +struct Foo(LDM); +struct Bar(Foo); +struct Baz(Bar); +impl Deref for Foo { + type Target = LDM; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Bar { + type Target = Foo; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Baz { + type Target = Bar; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +fn foo(_: T) where T: Happy {} + +fn main() { + let baz = Baz(Bar(Foo(LDM))); + foo(&baz); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-multiple-1.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-multiple-1.rs new file mode 100644 index 000000000000..070550e20101 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-deferences-multiple-1.rs @@ -0,0 +1,55 @@ +use std::ops::{Deref, DerefMut}; + +trait Happy {} +struct LDM; +impl Happy for &mut LDM {} + +struct Foo(LDM); +struct Bar(Foo); +struct Baz(Bar); +impl Deref for Foo { + type Target = LDM; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Bar { + type Target = Foo; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl Deref for Baz { + type Target = Bar; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl DerefMut for Foo { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl DerefMut for Bar { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} +impl DerefMut for Baz { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + + +fn foo(_: T) where T: Happy {} + +fn main() { + // Currently the compiler doesn't try to suggest dereferences for situations + // where DerefMut involves. So this test is meant to ensure compiler doesn't + // generate incorrect help message. + let mut baz = Baz(Bar(Foo(LDM))); + foo(&mut baz); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-where-clause.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-where-clause.rs new file mode 100644 index 000000000000..4bbc50d5b60d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-suggest-where-clause.rs @@ -0,0 +1,37 @@ +use std::mem; + +struct Misc(T); + +fn check() { + // suggest a where-clause, if needed + mem::size_of::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + mem::size_of::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // ... even if T occurs as a type parameter + + >::from; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + ::Item>>::from; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // ... but not if there are inference variables + + as From>::from; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // ... and also not if the error is not related to the type + + mem::size_of::<[T]>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + mem::size_of::<[&U]>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-test-2.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-test-2.rs new file mode 100644 index 000000000000..3b37f9ab01af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-test-2.rs @@ -0,0 +1,15 @@ +#![feature(box_syntax)] + +#[allow(non_camel_case_types)] +trait bar { fn dup(&self) -> Self; fn blah(&self); } +impl bar for i32 { fn dup(&self) -> i32 { *self } fn blah(&self) {} } +impl bar for u32 { fn dup(&self) -> u32 { *self } fn blah(&self) {} } + +fn main() { + 10.dup::(); // { dg-error ".E0107." "" { target *-*-* } } + 10.blah::(); // { dg-error ".E0107." "" { target *-*-* } } + (box 10 as Box).dup(); +// { dg-error ".E0038." "" { target *-*-* } .-1 } +// { dg-error ".E0038." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-test.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-test.rs new file mode 100644 index 000000000000..4aa55f77ad32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-test.rs @@ -0,0 +1,7 @@ +#[allow(non_camel_case_types)] +trait foo { fn foo(&self); } + +impl isize for usize { fn foo(&self) {} } // { dg-error ".E0404." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-to-str.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-to-str.rs new file mode 100644 index 000000000000..208444c3bf33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-to-str.rs @@ -0,0 +1,37 @@ +// run-pass +#![allow(non_camel_case_types)] + + +trait to_str { + fn to_string_(&self) -> String; +} + +impl to_str for isize { + fn to_string_(&self) -> String { self.to_string() } +} + +impl to_str for Vec { + fn to_string_(&self) -> String { + format!("[{}]", + self.iter() + .map(|e| e.to_string_()) + .collect::>() + .join(", ")) + } +} + +pub fn main() { + assert_eq!(1.to_string_(), "1".to_string()); + assert_eq!((vec![2, 3, 4]).to_string_(), "[2, 3, 4]".to_string()); + + fn indirect(x: T) -> String { + format!("{}!", x.to_string_()) + } + assert_eq!(indirect(vec![10, 20]), "[10, 20]!".to_string()); + + fn indirect2(x: T) -> String { + indirect(x) + } + assert_eq!(indirect2(vec![1]), "[1]!".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-where-clause-vs-impl.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-where-clause-vs-impl.rs new file mode 100644 index 000000000000..e2d15112997f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-where-clause-vs-impl.rs @@ -0,0 +1,46 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// Test that when there is a conditional (but blanket) impl and a +// where clause, we don't get confused in trait resolution. +// +// Issue #18453. + +// pretty-expanded FIXME #23616 + +use std::rc::Rc; + +pub trait Foo { + fn foo(&mut self, msg: M); +} + +pub trait Bar { + fn dummy(&self) -> M; +} + +impl> Foo for F { + fn foo(&mut self, msg: M) { + } +} + +pub struct Both { + inner: Rc<(M, F)>, +} + +impl> Clone for Both { + fn clone(&self) -> Both { + Both { inner: self.inner.clone() } + } +} + +fn repro1>(_both: Both) { +} + +fn repro2>(msg: M, foo: F) { + let both = Both { inner: Rc::new((msg, foo)) }; + repro1(both.clone()); // <--- This clone causes problem +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-with-bounds-default.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-with-bounds-default.rs new file mode 100644 index 000000000000..77f564bdebc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-with-bounds-default.rs @@ -0,0 +1,33 @@ +// run-pass + +pub trait Clone2 { + /// Returns a copy of the value. The contents of boxes + /// are copied to maintain uniqueness, while the contents of + /// managed pointers are not copied. + fn clone(&self) -> Self; +} + +trait Getter { + fn do_get(&self) -> T; + + fn do_get2(&self) -> (T, T) { + let x = self.do_get(); + (x.clone(), x.clone()) + } + +} + +impl Getter for isize { + fn do_get(&self) -> isize { *self } +} + +impl Getter for Option { + fn do_get(&self) -> T { self.as_ref().unwrap().clone() } +} + + +pub fn main() { + assert_eq!(3.do_get2(), (3, 3)); + assert_eq!(Some("hi".to_string()).do_get2(), ("hi".to_string(), "hi".to_string())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/trait-with-dst.rs b/gcc/testsuite/rust/rustc/ui/traits/trait-with-dst.rs new file mode 100644 index 000000000000..40072953583e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/trait-with-dst.rs @@ -0,0 +1,23 @@ +// build-pass (FIXME(62277): could be check-pass?) +// #55266 + +struct VTable { + _to_dst_ptr: fn(*mut ()) -> *mut DST, +} + +trait HasVTableFor { + const VTABLE: &'static VTable; +} + +impl HasVTableFor for T { + const VTABLE: &'static VTable = &VTable { + _to_dst_ptr: |_: *mut ()| unsafe { std::mem::zeroed() }, + }; +} + +pub fn push() { + >::VTABLE; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-assoc-type-in-supertrait-bad.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-assoc-type-in-supertrait-bad.rs new file mode 100644 index 000000000000..a39435e9a1a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-assoc-type-in-supertrait-bad.rs @@ -0,0 +1,17 @@ +// Test case where an associated type is referenced from within the +// supertrait definition, and the impl makes the wrong +// associations. Issue #20220. + +use std::vec::IntoIter; + +pub trait Foo: Iterator::Key> { + type Key; +} + +impl Foo for IntoIter { + type Key = u32; // { dg-error ".E0271." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-assoc-type-in-supertrait.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-assoc-type-in-supertrait.rs new file mode 100644 index 000000000000..9605e8cc6b62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-assoc-type-in-supertrait.rs @@ -0,0 +1,24 @@ +// run-pass +// Test case where an associated type is referenced from within the +// supertrait definition. Issue #20220. + + +use std::vec::IntoIter; + +pub trait Foo: Iterator::Key> { + type Key; +} + +impl Foo for IntoIter { + type Key = i32; +} + +fn sum_foo>(f: F) -> i32 { + f.fold(0, |a,b| a + b) +} + +fn main() { + let x = sum_foo(vec![11, 10, 1].into_iter()); + assert_eq!(x, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-conditional-dispatch.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-conditional-dispatch.rs new file mode 100644 index 000000000000..b65fec1ab542 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-conditional-dispatch.rs @@ -0,0 +1,36 @@ +// run-pass +// Test that we are able to resolve conditional dispatch. Here, the +// blanket impl for T:Copy coexists with an impl for Box, because +// Box does not impl Copy. + +#![feature(box_syntax)] + +trait Get { + fn get(&self) -> Self; +} + +trait MyCopy { fn copy(&self) -> Self; } +impl MyCopy for u16 { fn copy(&self) -> Self { *self } } +impl MyCopy for u32 { fn copy(&self) -> Self { *self } } +impl MyCopy for i32 { fn copy(&self) -> Self { *self } } +impl MyCopy for Option { fn copy(&self) -> Self { *self } } + +impl Get for T { + fn get(&self) -> T { self.copy() } +} + +impl Get for Box { + fn get(&self) -> Box { box get_it(&**self) } +} + +fn get_it(t: &T) -> T { + (*t).get() +} + +fn main() { + assert_eq!(get_it(&1_u32), 1_u32); + assert_eq!(get_it(&1_u16), 1_u16); + assert_eq!(get_it(&Some(1_u16)), Some(1_u16)); + assert_eq!(get_it(&Box::new(1)), Box::new(1)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-conditional-model-fn.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-conditional-model-fn.rs new file mode 100644 index 000000000000..a62b28b3fda1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-conditional-model-fn.rs @@ -0,0 +1,54 @@ +// run-pass +#![allow(unused_imports)] +// A model for how the `Fn` traits could work. You can implement at +// most one of `Go`, `GoMut`, or `GoOnce`, and then the others follow +// automatically. + +// aux-build:go_trait.rs + +extern crate go_trait; + +use go_trait::{Go, GoMut, GoOnce, go, go_mut, go_once}; + +use std::rc::Rc; +use std::cell::Cell; + +struct SomeGoableThing { + counter: Rc> +} + +impl Go for SomeGoableThing { + fn go(&self, arg: isize) { + self.counter.set(self.counter.get() + arg); + } +} + +struct SomeGoOnceableThing { + counter: Rc> +} + +impl GoOnce for SomeGoOnceableThing { + fn go_once(self, arg: isize) { + self.counter.set(self.counter.get() + arg); + } +} + +fn main() { + let counter = Rc::new(Cell::new(0)); + let mut x = SomeGoableThing { counter: counter.clone() }; + + go(&x, 10); + assert_eq!(counter.get(), 10); + + go_mut(&mut x, 100); + assert_eq!(counter.get(), 110); + + go_once(x, 1_000); + assert_eq!(counter.get(), 1_110); + + let x = SomeGoOnceableThing { counter: counter.clone() }; + + go_once(x, 10_000); + assert_eq!(counter.get(), 11_110); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-default-method-macro.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-default-method-macro.rs new file mode 100644 index 000000000000..cde822d05ff6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-default-method-macro.rs @@ -0,0 +1,21 @@ +// run-pass + + +trait Foo { + fn bar(&self) -> String { + format!("test") + } +} + +enum Baz { + Quux +} + +impl Foo for Baz { +} + +pub fn main() { + let q = Baz::Quux; + assert_eq!(q.bar(), "test".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-default-method-mut.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-default-method-mut.rs new file mode 100644 index 000000000000..cf02ce077399 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-default-method-mut.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(unused_assignments)] +// pretty-expanded FIXME #23616 + +#![allow(unused_variables)] + +trait Foo { + fn foo(&self, mut v: isize) { v = 1; } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-default-method-self.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-default-method-self.rs new file mode 100644 index 000000000000..5e484eb53a9b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-default-method-self.rs @@ -0,0 +1,19 @@ +// run-pass + + +trait Cat { + fn meow(&self) -> bool; + fn scratch(&self) -> bool { self.purr() } + fn purr(&self) -> bool { true } +} + +impl Cat for isize { + fn meow(&self) -> bool { + self.scratch() + } +} + +pub fn main() { + assert!(5.meow()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-default-method-trivial.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-default-method-trivial.rs new file mode 100644 index 000000000000..4fba4eca5114 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-default-method-trivial.rs @@ -0,0 +1,22 @@ +// run-pass + + +trait Cat { + fn meow(&self) -> bool; + fn scratch(&self) -> bool; + fn purr(&self) -> bool { true } +} + +impl Cat for isize { + fn meow(&self) -> bool { + self.scratch() + } + fn scratch(&self) -> bool { + self.purr() + } +} + +pub fn main() { + assert!(5.meow()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-elaborate-type-region.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-elaborate-type-region.rs new file mode 100644 index 000000000000..cc23347f5624 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-elaborate-type-region.rs @@ -0,0 +1,50 @@ +// run-pass +#![allow(dead_code)] + +// Test that we elaborate `Type: 'region` constraints and infer various important things. + +trait Master<'a, T: ?Sized> { + fn foo() where T: 'a; +} + +// [U]: 'a => U: 'a +impl<'a, U> Master<'a, [U]> for () { + fn foo() where U: 'a { } +} + +// &'b U: 'a => 'b: 'a, U: 'a +impl<'a, 'b, U> Master<'a, &'b U> for () { + fn foo() where 'b: 'a, U: 'a { } +} + +// &'b [U]: 'a => 'b: 'a, U: 'a +impl<'a, 'b, U> Master<'a, &'b [U]> for () { + fn foo() where 'b: 'a, U: 'a { } +} + +// Foo<'b>: 'a => 'b: 'a +struct Foo<'a> { x: &'a () } +impl<'a, 'b> Master<'a, Foo<'b>> for () { + fn foo() where 'b: 'a { } +} + +// Bar<'b, T>: 'a => 'b: 'a, T: 'a +struct Bar<'a, T: 'a> { x: &'a T } +impl<'a, 'b, T> Master<'a, Bar<'b, T>> for () { + fn foo() where 'b: 'a, T: 'a { } +} + +// fn(T): 'a => T: 'a +impl<'a, T> Master<'a, fn(T)> for () { + fn foo() where T: 'a { } +} + +// fn() -> T: 'a => T: 'a +impl<'a, T> Master<'a, fn() -> T> for () { + fn foo() where T: 'a { } +} + +fn main() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-impl-object-overlap-issue-23853.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-impl-object-overlap-issue-23853.rs new file mode 100644 index 000000000000..31ffd13be3fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-impl-object-overlap-issue-23853.rs @@ -0,0 +1,19 @@ +// run-pass +// Test that we are able to compile the case where both a blanket impl +// and the object type itself supply the required trait obligation. +// In this case, the blanket impl for `Foo` applies to any type, +// including `Bar`, but the object type `Bar` also implicitly supplies +// this context. + +trait Foo { fn dummy(&self) { } } + +trait Bar: Foo { } + +impl Foo for T { } + +fn want_foo() { } + +fn main() { + want_foo::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-lifetime.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-lifetime.rs new file mode 100644 index 000000000000..b1f5f700fec6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-lifetime.rs @@ -0,0 +1,31 @@ +// Test that we don't hit the recursion limit for short cycles involving lifetimes. + +// Shouldn't hit this, we should realize that we're in a cycle sooner. +#![recursion_limit="20"] + +trait NotAuto {} +trait Y { + type P; +} + +impl<'a> Y for C<'a> { + type P = Box>>; +} + +struct C<'a>(&'a ()); +struct X(T::P); + +impl NotAuto for Box {} +impl NotAuto for X where T::P: NotAuto {} +impl<'a> NotAuto for C<'a> {} + +fn is_send() {} +// { dg-note "" "" { target *-*-* } .-1 } + +fn main() { + // Should only be a few notes. + is_send::>>(); +// { dg-error ".E0275." "" { target *-*-* } .-1 } +// { dg-note ".E0275." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-simultaneous.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-simultaneous.rs new file mode 100644 index 000000000000..dd3d70d3abf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-simultaneous.rs @@ -0,0 +1,21 @@ +// Regression test for #33344, initial version. This example allowed +// arbitrary trait bounds to be synthesized. + +trait Tweedledum: IntoIterator {} +trait Tweedledee: IntoIterator {} + +impl Tweedledee for T {} +impl Tweedledum for T {} + +trait Combo: IntoIterator {} +impl Combo for T {} + +fn is_ee(t: T) { + t.into_iter(); +} + +fn main() { + is_ee(4); +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-supertrait-oibit.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-supertrait-oibit.rs new file mode 100644 index 000000000000..34e0bd0f1ace --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-supertrait-oibit.rs @@ -0,0 +1,19 @@ +// OIBIT-based version of #29859, supertrait version. Test that using +// a simple OIBIT `..` impl alone still doesn't allow arbitrary bounds +// to be synthesized. + +#![feature(optin_builtin_traits)] +#![feature(negative_impls)] + +auto trait Magic: Copy {} // { dg-error ".E0568." "" { target *-*-* } } + +fn copy(x: T) -> (T, T) { (x, x) } + +#[derive(Debug)] +struct NoClone; + +fn main() { + let (a, b) = copy(NoClone); // { dg-error ".E0277." "" { target *-*-* } } + println!("{:?} {:?}", a, b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-supertrait.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-supertrait.rs new file mode 100644 index 000000000000..3f03160dd3ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-supertrait.rs @@ -0,0 +1,16 @@ +// Regression test for #29859, supertrait version. This example +// allowed arbitrary trait bounds to be synthesized. + +trait Magic: Copy {} +impl Magic for T {} + +fn copy(x: T) -> (T, T) { (x, x) } + +#[derive(Debug)] +struct NoClone; + +fn main() { + let (a, b) = copy(NoClone); // { dg-error ".E0275." "" { target *-*-* } } + println!("{:?} {:?}", a, b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-two-traits.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-two-traits.rs new file mode 100644 index 000000000000..e317bcfaeb96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-inductive-overflow-two-traits.rs @@ -0,0 +1,23 @@ +// Regression test for #29859, initial version. This example allowed +// arbitrary trait bounds to be synthesized. + +// Trait that you want all types to implement. +use std::marker::{Sync as Trait}; + +pub trait Magic { + type X: Trait; +} +impl Magic for T { + type X = Self; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn check() {} + +fn wizard() { check::<::X>(); } + +fn main() { + wizard::<*mut ()>(); // { dg-error ".E0275." "" { target *-*-* } } + // check::<*mut ()>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-issue-22019.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-22019.rs new file mode 100644 index 000000000000..db12a5eb8c2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-22019.rs @@ -0,0 +1,35 @@ +// run-pass +// Test an issue where global caching was causing free regions from +// distinct scopes to be compared (`'g` and `'h`). The only important +// thing is that compilation succeeds here. + +// pretty-expanded FIXME #23616 + +#![allow(missing_copy_implementations)] +#![allow(unused_variables)] + +use std::borrow::ToOwned; + +pub struct CFGNode; + +pub type Node<'a> = &'a CFGNode; + +pub trait GraphWalk<'c, N> { + /// Returns all the nodes in this graph. + fn nodes(&'c self) where [N]:ToOwned>; +} + +impl<'g> GraphWalk<'g, Node<'g>> for u32 +{ + fn nodes(&'g self) where [Node<'g>]:ToOwned>> + { loop { } } +} + +impl<'h> GraphWalk<'h, Node<'h>> for u64 +{ + fn nodes(&'h self) where [Node<'h>]:ToOwned>> + { loop { } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-issue-22110.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-22110.rs new file mode 100644 index 000000000000..f6c8455c082e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-22110.rs @@ -0,0 +1,28 @@ +// run-pass +// Test an issue where we reported ambiguity between the where-clause +// and the blanket impl. The only important thing is that compilation +// succeeds here. Issue #22110. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +trait Foo { + fn foo(&self, a: A); +} + +impl Foo for F { + fn foo(&self, _: A) { } +} + +fn baz Foo<(&'a A,)>>(_: F) { } + +fn components(t: fn(&A)) + where fn(&A) : for<'a> Foo<(&'a A,)>, +{ + baz(t) +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-issue-22655.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-22655.rs new file mode 100644 index 000000000000..ee4042cdc87b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-22655.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(dead_code)] +// Regression test for issue #22655: This test should not lead to +// infinite recursion. + +// pretty-expanded FIXME #23616 + +unsafe impl Send for Unique { } + +pub struct Unique { + pointer: *const T, +} + +pub struct Node { + vals: V, + edges: Unique>, +} + +fn is_send() {} + +fn main() { + is_send::>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-issue-23003-overflow.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-23003-overflow.rs new file mode 100644 index 000000000000..06fce98a29ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-23003-overflow.rs @@ -0,0 +1,30 @@ +// A variant of traits-issue-23003 in which an infinite series of +// types are required. This test now just compiles fine, since the +// relevant rules that triggered the overflow were removed. + +// check-pass +#![allow(dead_code)] + +use std::marker::PhantomData; + +trait Async { + type Cancel; +} + +struct Receipt { + marker: PhantomData, +} + +struct Complete { + core: Option, +} + +impl Async for Complete { + type Cancel = Receipt>>; +} + +fn foo(_: Receipt>) { } + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-issue-23003.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-23003.rs new file mode 100644 index 000000000000..42abff0e06ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-23003.rs @@ -0,0 +1,33 @@ +// run-pass +// Test stack overflow triggered by evaluating the implications. To be +// WF, the type `Receipt` would require that `::Cancel` be WF. This normalizes to `Receipt` +// again, leading to an infinite cycle. Issue #23003. + +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] +#![allow(unused_variables)] + +use std::marker::PhantomData; + +trait Async { + type Cancel; +} + +struct Receipt { + marker: PhantomData, +} + +struct Complete { + core: Option<()>, +} + +impl Async for Complete { + type Cancel = Receipt; +} + +fn foo(r: Receipt) { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-issue-26339.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-26339.rs new file mode 100644 index 000000000000..d26176253d7b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-26339.rs @@ -0,0 +1,32 @@ +// run-pass +// Test that the right implementation is called through a trait +// object when supertraits include multiple references to the +// same trait, with different type parameters. + +trait A: PartialEq + PartialEq { } + +struct Foo; +struct Bar; + +struct Aimpl; + +impl PartialEq for Aimpl { + fn eq(&self, _rhs: &Foo) -> bool { + true + } +} + +impl PartialEq for Aimpl { + fn eq(&self, _rhs: &Bar) -> bool { + false + } +} + +impl A for Aimpl { } + +fn main() { + let a = &Aimpl as &dyn A; + + assert!(*a == Foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-issue-71136.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-71136.rs new file mode 100644 index 000000000000..889615a53c5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-issue-71136.rs @@ -0,0 +1,9 @@ +struct Foo(u8); + +#[derive(Clone)] +struct FooHolster { + the_foos: Vec, // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-multidispatch-bad.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-multidispatch-bad.rs new file mode 100644 index 000000000000..1e300960bc17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-multidispatch-bad.rs @@ -0,0 +1,23 @@ +// Test that we detect an illegal combination of types. + +trait Convert { + fn convert(&self) -> Target; +} + +impl Convert for i32 { + fn convert(&self) -> u32 { + *self as u32 + } +} + +fn test(_: T, _: U) +where T : Convert +{ +} + +fn a() { + test(22i32, 44i32); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-multidispatch-convert-ambig-dest.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-multidispatch-convert-ambig-dest.rs new file mode 100644 index 000000000000..117176ddbf24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-multidispatch-convert-ambig-dest.rs @@ -0,0 +1,31 @@ +// Check that we get an error in a multidisptach scenario where the +// set of impls is ambiguous. + +trait Convert { + fn convert(&self) -> Target; +} + +impl Convert for i32 { + fn convert(&self) -> i8 { + *self as i8 + } +} + +impl Convert for i32 { + fn convert(&self) -> i16 { + *self as i16 + } +} + +fn test(_: T, _: U) +where T : Convert +{ +} + +fn a() { + test(22, std::default::Default::default()); +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-multidispatch-infer-convert-target.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-multidispatch-infer-convert-target.rs new file mode 100644 index 000000000000..9d95a6259777 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-multidispatch-infer-convert-target.rs @@ -0,0 +1,37 @@ +// run-pass +// Test that we can infer the Target based on the Self or vice versa. + + +use std::mem; + +trait Convert { + fn convert(&self) -> Target; +} + +impl Convert for i16 { + fn convert(&self) -> u32 { + *self as u32 + } +} + +impl Convert for u32 { + fn convert(&self) -> i16 { + *self as i16 + } +} + +fn test(_: T, _: U, t_size: usize, u_size: usize) +where T : Convert +{ + assert_eq!(mem::size_of::(), t_size); + assert_eq!(mem::size_of::(), u_size); +} + +fn main() { + // T = i16, U = u32 + test(22_i16, Default::default(), 2, 4); + + // T = u32, U = i16 + test(22_u32, Default::default(), 4, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-repeated-supertrait-ambig.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-repeated-supertrait-ambig.rs new file mode 100644 index 000000000000..da45f0318db4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-repeated-supertrait-ambig.rs @@ -0,0 +1,44 @@ +// Test a case of a trait which extends the same supertrait twice, but +// with difference type parameters. Test then that when we don't give +// enough information to pick between these, no selection is made. In +// this particular case, the two choices are i64/u64 -- so when we use +// an integer literal, we wind up falling this literal back to i32. +// See also `run-pass/trait-repeated-supertrait.rs`. + +trait CompareTo { + fn same_as(&self, t: T) -> bool; +} + +trait CompareToInts : CompareTo + CompareTo { +} + +impl CompareTo for i64 { + fn same_as(&self, t: i64) -> bool { *self == t } +} + +impl CompareTo for i64 { + fn same_as(&self, t: u64) -> bool { *self == (t as i64) } +} + +impl CompareToInts for i64 { } + +fn with_obj(c: &dyn CompareToInts) -> bool { + c.same_as(22) // { dg-error ".E0277." "" { target *-*-* } } +} + +fn with_trait(c: &C) -> bool { + c.same_as(22) // { dg-error ".E0277." "" { target *-*-* } } +} + +fn with_ufcs1(c: &C) -> bool { + CompareToInts::same_as(c, 22) // { dg-error ".E0277." "" { target *-*-* } } +} + +fn with_ufcs2(c: &C) -> bool { + CompareTo::same_as(c, 22) // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() { + assert_eq!(22_i64.same_as(22), true); // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-repeated-supertrait.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-repeated-supertrait.rs new file mode 100644 index 000000000000..512d98b9874e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-repeated-supertrait.rs @@ -0,0 +1,49 @@ +// run-pass +// Test a case of a trait which extends the same supertrait twice, but +// with difference type parameters. Test that we can invoke the +// various methods in various ways successfully. +// See also `compile-fail/trait-repeated-supertrait-ambig.rs`. + + +trait CompareTo { + fn same_as(&self, t: T) -> bool; +} + +trait CompareToInts : CompareTo + CompareTo { +} + +impl CompareTo for i64 { + fn same_as(&self, t: i64) -> bool { *self == t } +} + +impl CompareTo for i64 { + fn same_as(&self, t: u64) -> bool { *self == (t as i64) } +} + +impl CompareToInts for i64 { } + +fn with_obj(c: &dyn CompareToInts) -> bool { + c.same_as(22_i64) && c.same_as(22_u64) +} + +fn with_trait(c: &C) -> bool { + c.same_as(22_i64) && c.same_as(22_u64) +} + +fn with_ufcs1(c: &C) -> bool { + CompareToInts::same_as(c, 22_i64) && CompareToInts::same_as(c, 22_u64) +} + +fn with_ufcs2(c: &C) -> bool { + CompareTo::same_as(c, 22_i64) && CompareTo::same_as(c, 22_u64) +} + +fn main() { + assert_eq!(22_i64.same_as(22_i64), true); + assert_eq!(22_i64.same_as(22_u64), true); + assert_eq!(with_trait(&22), true); + assert_eq!(with_obj(&22), true); + assert_eq!(with_ufcs1(&22), true); + assert_eq!(with_ufcs2(&22), true); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/traits-static-outlives-a-where-clause.rs b/gcc/testsuite/rust/rustc/ui/traits/traits-static-outlives-a-where-clause.rs new file mode 100644 index 000000000000..e0ce9b076151 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/traits-static-outlives-a-where-clause.rs @@ -0,0 +1,24 @@ +// run-pass + +trait Foo<'a> { + fn xyz(self); +} +impl<'a, T> Foo<'a> for T where 'static: 'a { + fn xyz(self) {} +} + +trait Bar { + fn uvw(self); +} +impl Bar for T where for<'a> T: Foo<'a> { + fn uvw(self) { self.xyz(); } +} + +fn foo(t: T) where T: Bar { + t.uvw(); +} + +fn main() { + foo(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/ufcs-trait-object.rs b/gcc/testsuite/rust/rustc/ui/traits/ufcs-trait-object.rs new file mode 100644 index 000000000000..a836f88e6f87 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/ufcs-trait-object.rs @@ -0,0 +1,18 @@ +// run-pass +// Test that when you use ufcs form to invoke a trait method (on a +// trait object) everything works fine. + + +trait Foo { + fn test(&self) -> i32; +} + +impl Foo for i32 { + fn test(&self) -> i32 { *self } +} + +fn main() { + let a: &dyn Foo = &22; + assert_eq!(Foo::test(a), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/use-trait-before-def.rs b/gcc/testsuite/rust/rustc/ui/traits/use-trait-before-def.rs new file mode 100644 index 000000000000..8958d2f967fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/use-trait-before-def.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(non_camel_case_types)] + +// Issue #1761 + +// pretty-expanded FIXME #23616 + +impl foo for isize { fn foo(&self) -> isize { 10 } } +trait foo { fn foo(&self) -> isize; } +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-maybe-bound.rs b/gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-maybe-bound.rs new file mode 100644 index 000000000000..f054eea187e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-maybe-bound.rs @@ -0,0 +1,19 @@ +// Test that `dyn ... + ?Sized + ...` is okay (though `?Sized` has no effect in trait objects). + +trait Foo {} + +type _0 = dyn ?Sized + Foo; +// { dg-error "" "" { target *-*-* } .-1 } + +type _1 = dyn Foo + ?Sized; +// { dg-error "" "" { target *-*-* } .-1 } + +type _2 = dyn Foo + ?Sized + ?Sized; +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +type _3 = dyn ?Sized + Foo; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-no-duplicates.rs b/gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-no-duplicates.rs new file mode 100644 index 000000000000..fcc5c0c3ddc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-no-duplicates.rs @@ -0,0 +1,34 @@ +// The purpose of this test is to demonstrate that duplicating object safe traits +// that are not auto-traits is rejected even though one could reasonably accept this. + +// Some arbitrary object-safe trait: +trait Obj {} + +// Demonstrate that recursive expansion of trait aliases doesn't affect stable behavior: +type _0 = dyn Obj + Obj; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +// Some variations: + +type _1 = dyn Send + Obj + Obj; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _2 = dyn Obj + Send + Obj; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +type _3 = dyn Obj + Send + Send; // But it is OK to duplicate auto traits. + +// Take higher ranked types into account. + +// Note that `'a` and `'b` are intentionally different to make sure we consider +// them semantically the same. +trait ObjL<'l> {} +type _4 = dyn for<'a> ObjL<'a> + for<'b> ObjL<'b>; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +trait ObjT {} +type _5 = dyn ObjT fn(&'a u8)> + ObjT fn(&'b u8)>; +// { dg-error ".E0225." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-only-maybe-bound.rs b/gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-only-maybe-bound.rs new file mode 100644 index 000000000000..4891e97f75c0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-only-maybe-bound.rs @@ -0,0 +1,8 @@ +// Test that `dyn ?Sized` (i.e., a trait object with only a maybe buond) is not allowed. + +type _0 = dyn ?Sized; +// { dg-error ".E0224." "" { target *-*-* } .-1 } +// { dg-error ".E0224." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-reverse-order.rs b/gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-reverse-order.rs new file mode 100644 index 000000000000..e4aa962b6e40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/traits/wf-trait-object-reverse-order.rs @@ -0,0 +1,16 @@ +// run-pass + +// Ensure that `dyn $($AutoTrait)+ ObjSafe` is well-formed. + +use std::marker::Unpin; + +// Some arbitrary object-safe trait: +trait Obj {} + +type _0 = dyn Unpin; +type _1 = dyn Send + Obj; +type _2 = dyn Send + Unpin + Obj; +type _3 = dyn Send + Unpin + Sync + Obj; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/transmute-equal-assoc-types.rs b/gcc/testsuite/rust/rustc/ui/transmute-equal-assoc-types.rs new file mode 100644 index 000000000000..6fd8b4fef425 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/transmute-equal-assoc-types.rs @@ -0,0 +1,10 @@ +trait Foo { + type Bar; +} + +unsafe fn noop(foo: F::Bar) -> F::Bar { + ::std::mem::transmute(foo) // { dg-error ".E0512." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/transmute-non-immediate-to-immediate.rs b/gcc/testsuite/rust/rustc/ui/transmute-non-immediate-to-immediate.rs new file mode 100644 index 000000000000..ff0107022f57 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/transmute-non-immediate-to-immediate.rs @@ -0,0 +1,12 @@ +// run-pass +// Issue #7988 +// Transmuting non-immediate type to immediate type + +// pretty-expanded FIXME #23616 + +pub fn main() { + unsafe { + ::std::mem::transmute::<[isize; 1],isize>([1]) + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/transmute-specialization.rs b/gcc/testsuite/rust/rustc/ui/transmute-specialization.rs new file mode 100644 index 000000000000..30ed3fdf4f90 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/transmute-specialization.rs @@ -0,0 +1,16 @@ +// run-pass + +#![feature(specialization)] // { dg-warning "" "" { target *-*-* } } + +trait Specializable { type Output; } + +impl Specializable for T { + default type Output = u16; +} + +fn main() { + unsafe { + std::mem::transmute::::Output>(0); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/transmute/main.rs b/gcc/testsuite/rust/rustc/ui/transmute/main.rs new file mode 100644 index 000000000000..b2c7396e18a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/transmute/main.rs @@ -0,0 +1,30 @@ +// normalize-stderr-32bit: "`&str` \(64 bits\)" -> "`&str` ($$STR bits)" +// normalize-stderr-64bit: "`&str` \(128 bits\)" -> "`&str` ($$STR bits)" + +use std::mem::transmute; + +pub trait TypeConstructor<'a> { + type T; +} + +unsafe fn transmute_lifetime<'a, 'b, C>(x: >::T) + -> >::T +where for<'z> C: TypeConstructor<'z> { + transmute(x) // { dg-error ".E0512." "" { target *-*-* } } +} + +unsafe fn sizes() { + let x: u8 = transmute(10u16); // { dg-error ".E0512." "" { target *-*-* } } +} + +unsafe fn ptrs() { + let x: u8 = transmute("test"); // { dg-error ".E0512." "" { target *-*-* } } +} + +union Foo { x: () } +unsafe fn vary() { + let x: Foo = transmute(10); // { dg-error ".E0512." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/transmute/transmute-different-sizes.rs b/gcc/testsuite/rust/rustc/ui/transmute/transmute-different-sizes.rs new file mode 100644 index 000000000000..5c68cd9d9f7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/transmute/transmute-different-sizes.rs @@ -0,0 +1,32 @@ +// normalize-stderr-test "\d+ bits" -> "N bits" + +// Tests that `transmute` cannot be called on types of different size. + +#![allow(warnings)] +#![feature(specialization)] + +use std::mem::transmute; + +unsafe fn f() { + let _: i8 = transmute(16i16); +// { dg-error ".E0512." "" { target *-*-* } .-1 } +} + +unsafe fn g(x: &T) { + let _: i8 = transmute(x); +// { dg-error ".E0512." "" { target *-*-* } .-1 } +} + +trait Specializable { type Output; } + +impl Specializable for T { + default type Output = u16; +} + +unsafe fn specializable(x: u16) -> ::Output { + transmute(x) +// { dg-error ".E0512." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/transmute/transmute-fat-pointers.rs b/gcc/testsuite/rust/rustc/ui/transmute/transmute-fat-pointers.rs new file mode 100644 index 000000000000..adf99442fb71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/transmute/transmute-fat-pointers.rs @@ -0,0 +1,34 @@ +// normalize-stderr-test "\d+ bits" -> "N bits" + +// Tests that are conservative around thin/fat pointer mismatches. + +#![allow(dead_code)] + +use std::mem::transmute; + +fn a(x: &[T]) -> &U { + unsafe { transmute(x) } // { dg-error ".E0512." "" { target *-*-* } } +} + +fn b(x: &T) -> &U { + unsafe { transmute(x) } // { dg-error ".E0512." "" { target *-*-* } } +} + +fn c(x: &T) -> &U { + unsafe { transmute(x) } +} + +fn d(x: &[T]) -> &[U] { + unsafe { transmute(x) } +} + +fn e(x: &T) -> &U { + unsafe { transmute(x) } // { dg-error ".E0512." "" { target *-*-* } } +} + +fn f(x: &T) -> &U { + unsafe { transmute(x) } // { dg-error ".E0512." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/transmute/transmute-from-fn-item-types-error.rs b/gcc/testsuite/rust/rustc/ui/transmute/transmute-from-fn-item-types-error.rs new file mode 100644 index 000000000000..1f2b073fbfa2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/transmute/transmute-from-fn-item-types-error.rs @@ -0,0 +1,61 @@ +use std::mem; + +unsafe fn foo() -> (i8, *const (), Option) { + let i = mem::transmute(bar); +// { dg-error ".E0512." "" { target *-*-* } .-1 } + + + let p = mem::transmute(foo); +// { dg-error ".E0591." "" { target *-*-* } .-1 } + + + let of = mem::transmute(main); +// { dg-error ".E0591." "" { target *-*-* } .-1 } + + + (i, p, of) +} + +unsafe fn bar() { + // Error as usual if the resulting type is not pointer-sized. + mem::transmute::<_, u8>(main); +// { dg-error ".E0512." "" { target *-*-* } .-1 } + + + mem::transmute::<_, *mut ()>(foo); +// { dg-error ".E0591." "" { target *-*-* } .-1 } + + + mem::transmute::<_, fn()>(bar); +// { dg-error ".E0591." "" { target *-*-* } .-1 } + + + // No error if a coercion would otherwise occur. + mem::transmute::(main); +} + +unsafe fn baz() { + mem::transmute::<_, *mut ()>(Some(foo)); +// { dg-error ".E0591." "" { target *-*-* } .-1 } + + + mem::transmute::<_, fn()>(Some(bar)); +// { dg-error ".E0591." "" { target *-*-* } .-1 } + + + mem::transmute::<_, Option>(Some(baz)); +// { dg-error ".E0591." "" { target *-*-* } .-1 } + + + // No error if a coercion would otherwise occur. + mem::transmute::, usize>(Some(main)); +} + +fn main() { + unsafe { + foo(); + bar(); + baz(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/transmute/transmute-impl.rs b/gcc/testsuite/rust/rustc/ui/transmute/transmute-impl.rs new file mode 100644 index 000000000000..5bbbc67ac86e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/transmute/transmute-impl.rs @@ -0,0 +1,26 @@ +// normalize-stderr-test "\d+ bits" -> "N bits" + +// Tests that are conservative around thin/fat pointer mismatches. + +#![allow(dead_code)] + +use std::mem::transmute; + +struct Foo { + t: Box +} + +impl Foo { + fn m(x: &T) -> &isize where T : Sized { + // OK here, because T : Sized is in scope. + unsafe { transmute(x) } + } + + fn n(x: &T) -> &isize { + // Not OK here, because T : Sized is not in scope. + unsafe { transmute(x) } // { dg-error ".E0512." "" { target *-*-* } } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/transmute/transmute-imut-to-mut.rs b/gcc/testsuite/rust/rustc/ui/transmute/transmute-imut-to-mut.rs new file mode 100644 index 000000000000..aecad44b5e41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/transmute/transmute-imut-to-mut.rs @@ -0,0 +1,9 @@ +// Tests that transmuting from &T to &mut T is Undefined Behavior. + +use std::mem::transmute; + +fn main() { + let _a: &mut u8 = unsafe { transmute(&1u8) }; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/transmute/transmute-type-parameters.rs b/gcc/testsuite/rust/rustc/ui/transmute/transmute-type-parameters.rs new file mode 100644 index 000000000000..1cece79d42da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/transmute/transmute-type-parameters.rs @@ -0,0 +1,45 @@ +// Tests that `transmute` cannot be called on type parameters. + +use std::mem::transmute; + +unsafe fn f(x: T) { + let _: i32 = transmute(x); +// { dg-error ".E0512." "" { target *-*-* } .-1 } +} + +unsafe fn g(x: (T, i32)) { + let _: i32 = transmute(x); +// { dg-error ".E0512." "" { target *-*-* } .-1 } +} + +unsafe fn h(x: [T; 10]) { + let _: i32 = transmute(x); +// { dg-error ".E0512." "" { target *-*-* } .-1 } +} + +struct Bad { + f: T, +} + +unsafe fn i(x: Bad) { + let _: i32 = transmute(x); +// { dg-error ".E0512." "" { target *-*-* } .-1 } +} + +enum Worse { + A(T), + B, +} + +unsafe fn j(x: Worse) { + let _: i32 = transmute(x); +// { dg-error ".E0512." "" { target *-*-* } .-1 } +} + +unsafe fn k(x: Option) { + let _: i32 = transmute(x); +// { dg-error ".E0512." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs new file mode 100644 index 000000000000..b6f0d4b71225 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs @@ -0,0 +1,24 @@ +// check-pass +// compile-flags: --emit=mir,link +// Force mir to be emitted, to ensure that const +// propagation doesn't ICE on a function +// with an 'impossible' body. See issue #67696 +// Inconsistent bounds with trait implementations + +#![feature(trivial_bounds)] +#![allow(unused)] + +trait A { + fn foo(&self) -> Self where Self: Copy; +} + +impl A for str { + fn foo(&self) -> Self where Self: Copy { *"" } +} + +impl A for i32 { + fn foo(&self) -> Self { 3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.rs b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.rs new file mode 100644 index 000000000000..84ae449cc5b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.rs @@ -0,0 +1,14 @@ +// Check that reborrows are still illegal with Copy mutable references +#![feature(trivial_bounds)] +#![allow(unused)] + +fn reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy { + *t // { dg-error ".E0596." "" { target *-*-* } } +} + +fn copy_reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy { + {*t} // { dg-error ".E0596." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs new file mode 100644 index 000000000000..577c20b98c11 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs @@ -0,0 +1,34 @@ +// check-pass +// Check tautalogically false `Copy` bounds +#![feature(trivial_bounds)] + +fn copy_string(t: String) -> String where String: Copy { // { dg-warning "" "" { target *-*-* } } + is_copy(&t); + let x = t; + drop(t); + t +} + +fn copy_out_string(t: &String) -> String where String: Copy { // { dg-warning "" "" { target *-*-* } } + *t +} + +fn copy_string_with_param(x: String) where String: Copy { // { dg-warning "" "" { target *-*-* } } + let y = x; + let z = x; +} + +// Check that no reborrowing occurs +fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy { +// { dg-warning "" "" { target *-*-* } .-1 } + is_copy(t); + let x = *t; + drop(x); + x +} + +fn is_copy(t: &T) {} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.rs b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.rs new file mode 100644 index 000000000000..ae0a4f405f4e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.rs @@ -0,0 +1,24 @@ +#![feature(trivial_bounds)] +#![allow(unused)] + +struct B; + +trait A { + type X; + fn get_x() -> Self::X; +} + +impl A for B { + type X = u8; + fn get_x() -> u8 { 0 } +} + +fn global_bound_is_hidden() -> u8 +where + B: A +{ + B::get_x() // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs new file mode 100644 index 000000000000..fa376f77faf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs @@ -0,0 +1,59 @@ +// run-pass +// Check that global bounds result in the expected choice of associated type + +#![feature(trivial_bounds)] +#![allow(unused)] + +struct B; + +trait A { + type X; + fn get_x() -> Self::X; +} + +impl A for B { + type X = u8; + fn get_x() -> u8 { 0 } +} + +fn underspecified_bound() -> u8 +where + B: A // { dg-warning "" "" { target *-*-* } } +{ + B::get_x() +} + +fn inconsistent_bound() -> i32 +where + B: A // { dg-warning "" "" { target *-*-* } } +{ + B::get_x() +} + +fn redundant_bound() -> u8 +where + B: A // { dg-warning "" "" { target *-*-* } } +{ + B::get_x() +} + +fn inconsistent_dup_bound() -> i32 +where + B: A + A +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +{ + B::get_x() +} + +fn redundant_dup_bound() -> u8 +where + B: A + A +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +{ + B::get_x() +} + +fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs new file mode 100644 index 000000000000..0dccf1700e95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs @@ -0,0 +1,28 @@ +// run-pass +// Check tautalogically false `Sized` bounds +#![feature(trivial_bounds)] +#![allow(unused)] + +trait A {} + +impl A for i32 {} + +struct T { + x: X, +} + +struct S(str, str) where str: Sized; +// { dg-warning "" "" { target *-*-* } .-1 } + +fn unsized_local() where for<'a> T: Sized { +// { dg-warning "" "" { target *-*-* } .-1 } + let x: T = *(Box::new(T { x: 1 }) as Box>); +} + +fn return_str() -> str where str: Sized { +// { dg-warning "" "" { target *-*-* } .-1 } + *"Sized".to_string().into_boxed_str() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs new file mode 100644 index 000000000000..3113f9e8c771 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs @@ -0,0 +1,15 @@ +// run-pass +// Test that inconsistent bounds are used in well-formedness checks +#![feature(trivial_bounds)] + +use std::fmt::Debug; + +pub fn foo() where Vec: Debug, str: Copy { +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + let x = vec![*"1"]; + println!("{:?}", x); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent.rs b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent.rs new file mode 100644 index 000000000000..e07237617117 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-inconsistent.rs @@ -0,0 +1,75 @@ +// run-pass + +// Check that tautalogically false bounds are accepted, and are used +// in type inference. +#![feature(trivial_bounds)] +#![allow(unused)] + +pub trait Foo { + fn test(&self); +} + +fn generic_function(x: X) {} + +enum E where i32: Foo { V } // { dg-warning "" "" { target *-*-* } } + +struct S where i32: Foo; // { dg-warning "" "" { target *-*-* } } + +trait T where i32: Foo {} // { dg-warning "" "" { target *-*-* } } + +union U where i32: Foo { f: i32 } // { dg-warning "" "" { target *-*-* } } + +type Y where i32: Foo = (); +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + +impl Foo for () where i32: Foo { // { dg-warning "" "" { target *-*-* } } + fn test(&self) { + 3i32.test(); + Foo::test(&4i32); + generic_function(5i32); + } +} + +fn f() where i32: Foo { // { dg-warning "" "" { target *-*-* } } + let s = S; + 3i32.test(); + Foo::test(&4i32); + generic_function(5i32); +} + +fn g() where &'static str: Foo { // { dg-warning "" "" { target *-*-* } } + "Foo".test(); + Foo::test(&"Foo"); + generic_function("Foo"); +} + +trait A {} + +impl A for i32 {} + +struct Dst { + x: X, +} + +struct TwoStrs(str, str) where str: Sized; // { dg-warning "" "" { target *-*-* } } + +fn unsized_local() where for<'a> Dst: Sized { // { dg-warning "" "" { target *-*-* } } + let x: Dst = *(Box::new(Dst { x: 1 }) as Box>); +} + +fn return_str() -> str where str: Sized { // { dg-warning "" "" { target *-*-* } } + *"Sized".to_string().into_boxed_str() +} + +fn use_op(s: String) -> String where String: ::std::ops::Neg { +// { dg-warning "" "" { target *-*-* } .-1 } + -s +} + +fn use_for() where i32: Iterator { // { dg-warning "" "" { target *-*-* } } + for _ in 2i32 {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-leak-copy.rs b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-leak-copy.rs new file mode 100644 index 000000000000..396ebe2815e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-leak-copy.rs @@ -0,0 +1,13 @@ +// Check that false Copy bounds don't leak +#![feature(trivial_bounds)] + +fn copy_out_string(t: &String) -> String where String: Copy { + *t +} + +fn move_out_string(t: &String) -> String { + *t // { dg-error ".E0507." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-leak.rs b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-leak.rs new file mode 100644 index 000000000000..6fb481dd9e1a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-leak.rs @@ -0,0 +1,32 @@ +// Check that false bounds don't leak +#![feature(trivial_bounds)] + +pub trait Foo { + fn test(&self); +} + +fn return_str() -> str where str: Sized { + *"Sized".to_string().into_boxed_str() +} + +fn cant_return_str() -> str { // { dg-error ".E0277." "" { target *-*-* } } + *"Sized".to_string().into_boxed_str() +} + +fn my_function() where i32: Foo +{ + 3i32.test(); + Foo::test(&4i32); + generic_function(5i32); +} + +fn foo() { + 3i32.test(); // { dg-error ".E0599." "" { target *-*-* } } + Foo::test(&4i32); // { dg-error ".E0277." "" { target *-*-* } } + generic_function(5i32); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn generic_function(t: T) {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-lint.rs b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-lint.rs new file mode 100644 index 000000000000..286535f47b54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-lint.rs @@ -0,0 +1,41 @@ +#![feature(trivial_bounds)] +#![allow(unused)] +#![deny(trivial_bounds)] + +struct A where i32: Copy; // { dg-error "" "" { target *-*-* } } + +trait X {} + +trait Y: Copy {} + +trait Z { + type S: Copy; +} + +// Check only the bound the user writes trigger the lint +fn trivial_elaboration() where T: X + Z, i32: Y {} // OK + +fn global_param() where i32: X<()> {} // { dg-error "" "" { target *-*-* } } + +// Should only error on the trait bound, not the implicit +// projection bound ::S == i32. +fn global_projection() where i32: Z {} // { dg-error "" "" { target *-*-* } } + +impl A { + fn new() -> A { A } +} + +// Lifetime bounds should be linted as well +fn global_lifetimes() where i32: 'static, &'static str: 'static {} +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } + +fn local_lifetimes<'a>() where i32: 'a, &'a str: 'a {} // OK + +fn global_outlives() where 'static: 'static {} // { dg-error "" "" { target *-*-* } } + +// Check that each bound is checked individually +fn mixed_bounds() where i32: X + Copy {} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-object.rs b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-object.rs new file mode 100644 index 000000000000..60b1225de07d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-bounds/trivial-bounds-object.rs @@ -0,0 +1,19 @@ +// run-pass +// Check that the object bound dyn A + 'a: A is preferred over the +// where clause bound dyn A + 'static: A. + +#![allow(unused)] + +trait A { + fn test(&self); +} + +fn foo(x: &dyn A) +where + dyn A + 'static: A, // Using this bound would lead to a lifetime error. +{ + x.test(); +} + +fn main () {} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial-message.rs b/gcc/testsuite/rust/rustc/ui/trivial-message.rs new file mode 100644 index 000000000000..ae5566ab0479 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial-message.rs @@ -0,0 +1,17 @@ +// run-pass + +#![allow(unused_must_use)] +/* + This is about the simplest program that can successfully send a + message. + */ + +use std::sync::mpsc::channel; + +pub fn main() { + let (tx, rx) = channel(); + tx.send(42); + let r = rx.recv(); + println!("{:?}", r); +} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial_casts-rpass.rs b/gcc/testsuite/rust/rustc/ui/trivial_casts-rpass.rs new file mode 100644 index 000000000000..4feab00db6fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial_casts-rpass.rs @@ -0,0 +1,63 @@ +// run-pass +// Test that all coercions can actually be done using casts (modulo the lints). + +#![allow(trivial_casts, trivial_numeric_casts)] + +trait Foo { + fn foo(&self) {} +} + +pub struct Bar; + +impl Foo for Bar {} + +pub fn main() { + // Numeric + let _ = 42_i32 as i32; + let _ = 42_u8 as u8; + + // & to * pointers + let x: &u32 = &42; + let _ = x as *const u32; + + let x: &mut u32 = &mut 42; + let _ = x as *mut u32; + + // unsize array + let x: &[u32; 3] = &[42, 43, 44]; + let _ = x as &[u32]; + let _ = x as *const [u32]; + + let x: &mut [u32; 3] = &mut [42, 43, 44]; + let _ = x as &mut [u32]; + let _ = x as *mut [u32]; + + let x: Box<[u32; 3]> = Box::new([42, 43, 44]); + let _ = x as Box<[u32]>; + + // unsize trait + let x: &Bar = &Bar; + let _ = x as &dyn Foo; + let _ = x as *const dyn Foo; + + let x: &mut Bar = &mut Bar; + let _ = x as &mut dyn Foo; + let _ = x as *mut dyn Foo; + + let x: Box = Box::new(Bar); + let _ = x as Box; + + // functions + fn baz(_x: i32) {} + let _ = &baz as &dyn Fn(i32); + let x = |_x: i32| {}; + let _ = &x as &dyn Fn(i32); +} + +// subtyping +pub fn test_subtyping<'a, 'b: 'a>(a: &'a Bar, b: &'b Bar) { + let _ = a as &'a Bar; + let _ = b as &'a Bar; + let _ = b as &'b Bar; +} + diff --git a/gcc/testsuite/rust/rustc/ui/trivial_casts.rs b/gcc/testsuite/rust/rustc/ui/trivial_casts.rs new file mode 100644 index 000000000000..51e9b3d29e38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/trivial_casts.rs @@ -0,0 +1,86 @@ +// Test the trivial_casts and trivial_numeric_casts lints. For each error we also +// check that the cast can be done using just coercion. + +#![deny(trivial_casts, trivial_numeric_casts)] + +trait Foo { + fn foo(&self) {} +} + +pub struct Bar; + +impl Foo for Bar {} + +pub fn main() { + // Numeric + let _ = 42_i32 as i32; // { dg-error "" "" { target *-*-* } } + let _: i32 = 42_i32; + + let _ = 42_u8 as u8; // { dg-error "" "" { target *-*-* } } + let _: u8 = 42_u8; + + // & to * pointers + let x: &u32 = &42; + let _ = x as *const u32; // { dg-error "" "" { target *-*-* } } + let _: *const u32 = x; + + let x: &mut u32 = &mut 42; + let _ = x as *mut u32; // { dg-error "" "" { target *-*-* } } + let _: *mut u32 = x; + + // unsize array + let x: &[u32; 3] = &[42, 43, 44]; + let _ = x as &[u32]; // { dg-error "" "" { target *-*-* } } + let _ = x as *const [u32]; // { dg-error "" "" { target *-*-* } } + let _: &[u32] = x; + let _: *const [u32] = x; + + let x: &mut [u32; 3] = &mut [42, 43, 44]; + let _ = x as &mut [u32]; // { dg-error "" "" { target *-*-* } } + let _ = x as *mut [u32]; // { dg-error "" "" { target *-*-* } } + let _: &mut [u32] = x; + let _: *mut [u32] = x; + + let x: Box<[u32; 3]> = Box::new([42, 43, 44]); + let _ = x as Box<[u32]>; +// { dg-error "" "" { target *-*-* } .-1 } + let x: Box<[u32; 3]> = Box::new([42, 43, 44]); + let _: Box<[u32]> = x; + + // unsize trait + let x: &Bar = &Bar; + let _ = x as &dyn Foo; // { dg-error "" "" { target *-*-* } } + let _ = x as *const dyn Foo; // { dg-error "" "" { target *-*-* } } + let _: &dyn Foo = x; + let _: *const dyn Foo = x; + + let x: &mut Bar = &mut Bar; + let _ = x as &mut dyn Foo; // { dg-error "" "" { target *-*-* } } + let _ = x as *mut dyn Foo; // { dg-error "" "" { target *-*-* } } + let _: &mut dyn Foo = x; + let _: *mut dyn Foo = x; + + let x: Box = Box::new(Bar); + let _ = x as Box; // { dg-error "" "" { target *-*-* } } + let x: Box = Box::new(Bar); + let _: Box = x; + + // functions + fn baz(_x: i32) {} + let _ = &baz as &dyn Fn(i32); // { dg-error "" "" { target *-*-* } } + let _: &dyn Fn(i32) = &baz; + let x = |_x: i32| {}; + let _ = &x as &dyn Fn(i32); // { dg-error "" "" { target *-*-* } } + let _: &dyn Fn(i32) = &x; +} + +// subtyping +pub fn test_subtyping<'a, 'b: 'a>(a: &'a Bar, b: &'b Bar) { + let _ = a as &'a Bar; // { dg-error "" "" { target *-*-* } } + let _: &'a Bar = a; + let _ = b as &'a Bar; // { dg-error "" "" { target *-*-* } } + let _: &'a Bar = b; + let _ = b as &'b Bar; // { dg-error "" "" { target *-*-* } } + let _: &'b Bar = b; +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block.rs b/gcc/testsuite/rust/rustc/ui/try-block.rs new file mode 100644 index 000000000000..977e270cccf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block.rs @@ -0,0 +1,76 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +struct catch {} + +pub fn main() { + let catch_result: Option<_> = try { + let x = 5; + x + }; + assert_eq!(catch_result, Some(5)); + + let mut catch = true; + while catch { catch = false; } + assert_eq!(catch, false); + + catch = if catch { false } else { true }; + assert_eq!(catch, true); + + match catch { + _ => {} + }; + + let catch_err: Result<_, i32> = try { + Err(22)?; + 1 + }; + assert_eq!(catch_err, Err(22)); + + let catch_okay: Result = try { + if false { Err(25)?; } + Ok::<(), i32>(())?; + 28 + }; + assert_eq!(catch_okay, Ok(28)); + + let catch_from_loop: Result = try { + for i in 0..10 { + if i < 5 { Ok::(i)?; } else { Err(i)?; } + } + 22 + }; + assert_eq!(catch_from_loop, Err(5)); + + let cfg_init; + let _res: Result<(), ()> = try { + cfg_init = 5; + }; + assert_eq!(cfg_init, 5); + + let cfg_init_2; + let _res: Result<(), ()> = try { + cfg_init_2 = 6; + Err(())?; + }; + assert_eq!(cfg_init_2, 6); + + let my_string = "test".to_string(); + let res: Result<&str, ()> = try { + // Unfortunately, deref doesn't fire here (#49356) + &my_string[..] + }; + assert_eq!(res, Ok("test")); + + let my_opt: Option<_> = try { () }; + assert_eq!(my_opt, Some(())); + + let my_opt: Option<_> = try { }; + assert_eq!(my_opt, Some(())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block/try-block-bad-lifetime.rs b/gcc/testsuite/rust/rustc/ui/try-block/try-block-bad-lifetime.rs new file mode 100644 index 000000000000..e433401977a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block/try-block-bad-lifetime.rs @@ -0,0 +1,38 @@ +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +#[inline(never)] +fn do_something_with(_x: T) {} + +// This test checks that borrows made and returned inside try blocks are properly constrained +pub fn main() { + { + // Test that borrows returned from a try block must be valid for the lifetime of the + // result variable + let result: Result<(), &str> = try { + let my_string = String::from(""); + let my_str: & str = & my_string; +// { dg-error ".E0597." "" { target *-*-* } .-1 } + Err(my_str) ?; + Err("") ?; + }; + do_something_with(result); + } + + { + // Test that borrows returned from try blocks freeze their referent + let mut i = 5; + let k = &mut i; + let mut j: Result<(), &mut i32> = try { + Err(k) ?; + i = 10; // { dg-error ".E0506." "" { target *-*-* } } + }; + ::std::mem::drop(k); // { dg-error ".E0382." "" { target *-*-* } } + i = 40; // { dg-error ".E0506." "" { target *-*-* } } + + let i_ptr = if let Err(i_ptr) = j { i_ptr } else { panic ! ("") }; + *i_ptr = 50; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block/try-block-bad-type.rs b/gcc/testsuite/rust/rustc/ui/try-block/try-block-bad-type.rs new file mode 100644 index 000000000000..44285558835d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block/try-block-bad-type.rs @@ -0,0 +1,23 @@ +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +pub fn main() { + let res: Result = try { + Err("")?; // { dg-error ".E0277." "" { target *-*-* } } + 5 + }; + + let res: Result = try { + "" // { dg-error ".E0271." "" { target *-*-* } } + }; + + let res: Result = try { }; // { dg-error ".E0271." "" { target *-*-* } } + + let res: () = try { }; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + + let res: i32 = try { 5 }; // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block/try-block-catch.rs b/gcc/testsuite/rust/rustc/ui/try-block/try-block-catch.rs new file mode 100644 index 000000000000..37b76e703081 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block/try-block-catch.rs @@ -0,0 +1,11 @@ +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +fn main() { + let res: Option = try { + true + } catch { }; +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block/try-block-in-edition2015.rs b/gcc/testsuite/rust/rustc/ui/try-block/try-block-in-edition2015.rs new file mode 100644 index 000000000000..30e5e86468ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block/try-block-in-edition2015.rs @@ -0,0 +1,11 @@ +// compile-flags: --edition 2015 + +pub fn main() { + let try_result: Option<_> = try { +// { dg-error ".E0574." "" { target *-*-* } .-1 } + let x = 5; // { dg-error "" "" { target *-*-* } } + x + }; + assert_eq!(try_result, Some(5)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block/try-block-in-match.rs b/gcc/testsuite/rust/rustc/ui/try-block/try-block-in-match.rs new file mode 100644 index 000000000000..9c13522f667d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block/try-block-in-match.rs @@ -0,0 +1,12 @@ +// run-pass +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +fn main() { + match try { } { + Err(()) => (), + Ok(()) => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block/try-block-in-return.rs b/gcc/testsuite/rust/rustc/ui/try-block/try-block-in-return.rs new file mode 100644 index 000000000000..ce408d01e473 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block/try-block-in-return.rs @@ -0,0 +1,13 @@ +// run-pass +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +fn issue_76271() -> Option { + return try { 4 } +} + +fn main() { + assert_eq!(issue_76271(), Some(4)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block/try-block-in-while.rs b/gcc/testsuite/rust/rustc/ui/try-block/try-block-in-while.rs new file mode 100644 index 000000000000..ad4baa3c17f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block/try-block-in-while.rs @@ -0,0 +1,9 @@ +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +fn main() { + while try { false } {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block/try-block-maybe-bad-lifetime.rs b/gcc/testsuite/rust/rustc/ui/try-block/try-block-maybe-bad-lifetime.rs new file mode 100644 index 000000000000..ac404486e6f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block/try-block-maybe-bad-lifetime.rs @@ -0,0 +1,45 @@ +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +#[inline(never)] +fn do_something_with(_x: T) {} + +// This test checks that borrows made and returned inside try blocks are properly constrained +pub fn main() { + { + // Test that a borrow which *might* be returned still freezes its referent + let mut i = 222; + let x: Result<&i32, ()> = try { + Err(())?; + &i + }; + i = 0; // { dg-error ".E0506." "" { target *-*-* } } + let _ = i; + do_something_with(x); + } + + { + let x = String::new(); + let _y: Result<(), ()> = try { + Err(())?; + ::std::mem::drop(x); + }; + println!("{}", x); // { dg-error ".E0382." "" { target *-*-* } } + } + + { + // Test that a borrow which *might* be assigned to an outer variable still freezes + // its referent + let mut i = 222; + let mut j = &-1; + let _x: Result<(), ()> = try { + Err(())?; + j = &i; + }; + i = 0; // { dg-error ".E0506." "" { target *-*-* } } + let _ = i; + do_something_with(j); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block/try-block-opt-init.rs b/gcc/testsuite/rust/rustc/ui/try-block/try-block-opt-init.rs new file mode 100644 index 000000000000..6c69647b7eaa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block/try-block-opt-init.rs @@ -0,0 +1,17 @@ +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +fn use_val(_x: T) {} + +pub fn main() { + let cfg_res; + let _: Result<(), ()> = try { + Err(())?; + cfg_res = 5; + Ok::<(), ()>(())?; + use_val(cfg_res); + }; + assert_eq!(cfg_res, 5); // { dg-error ".E0381." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block/try-block-type-error.rs b/gcc/testsuite/rust/rustc/ui/try-block/try-block-type-error.rs new file mode 100644 index 000000000000..7fd8c2f97ea1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block/try-block-type-error.rs @@ -0,0 +1,19 @@ +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +fn foo() -> Option<()> { Some(()) } + +fn main() { + let _: Option = try { + foo()?; + 42 +// { dg-error ".E0271." "" { target *-*-* } .-1 } + }; + + let _: Option = try { + foo()?; + }; +// { dg-error ".E0271." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block/try-block-unreachable-code-lint.rs b/gcc/testsuite/rust/rustc/ui/try-block/try-block-unreachable-code-lint.rs new file mode 100644 index 000000000000..89f603dc5314 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block/try-block-unreachable-code-lint.rs @@ -0,0 +1,77 @@ +// Test unreachable_code lint for `try {}` block ok-wrapping. See issues #54165, #63324. + +// compile-flags: --edition 2018 +// check-pass +#![feature(try_blocks)] +#![warn(unreachable_code)] + +fn err() -> Result { + Err(()) +} + +// In the following cases unreachable code is autogenerated and should not be reported. + +fn test_ok_wrapped_divergent_expr_1() { + let res: Result = try { + loop { + err()?; + } + }; + println!("res: {:?}", res); +} + +fn test_ok_wrapped_divergent_expr_2() { + let _: Result = try { + return + }; +} + +fn test_autogenerated_unit_after_divergent_expr() { + let _: Result<(), ()> = try { + return; + }; +} + +// In the following cases unreachable code should be reported. + +fn test_try_block_after_divergent_stmt() { + let _: Result = { + return; + + try { + loop { + err()?; + } + } +// { dg-warning "" "" { target *-*-* } .-5 } + }; +} + +fn test_wrapped_divergent_expr() { + let _: Result = { + Err(return) +// { dg-warning "" "" { target *-*-* } .-1 } + }; +} + +fn test_expr_after_divergent_stmt_in_try_block() { + let res: Result = try { + loop { + err()?; + } + + 42 +// { dg-warning "" "" { target *-*-* } .-1 } + }; + println!("res: {:?}", res); +} + +fn main() { + test_ok_wrapped_divergent_expr_1(); + test_ok_wrapped_divergent_expr_2(); + test_autogenerated_unit_after_divergent_expr(); + test_try_block_after_divergent_stmt(); + test_wrapped_divergent_expr(); + test_expr_after_divergent_stmt_in_try_block(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-block/try-block-unused-delims.rs b/gcc/testsuite/rust/rustc/ui/try-block/try-block-unused-delims.rs new file mode 100644 index 000000000000..4dfa5c7595cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-block/try-block-unused-delims.rs @@ -0,0 +1,30 @@ +// check-pass +// compile-flags: --edition 2018 +// run-rustfix + +#![feature(try_blocks)] +#![warn(unused_parens, unused_braces)] + +fn consume(_: Result) -> T { todo!() } + +fn main() { + consume((try {})); +// { dg-warning "" "" { target *-*-* } .-1 } + + consume({ try {} }); +// { dg-warning "" "" { target *-*-* } .-1 } + + match (try {}) { +// { dg-warning "" "" { target *-*-* } .-1 } + Ok(()) | Err(()) => (), + } + + if let Err(()) = (try {}) {} +// { dg-warning "" "" { target *-*-* } .-1 } + + match (try {}) { +// { dg-warning "" "" { target *-*-* } .-1 } + Ok(()) | Err(()) => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-from-int-error-partial-eq.rs b/gcc/testsuite/rust/rustc/ui/try-from-int-error-partial-eq.rs new file mode 100644 index 000000000000..11c9b8e8ccdd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-from-int-error-partial-eq.rs @@ -0,0 +1,13 @@ +// run-pass + +#![allow(unused_must_use)] + +use std::convert::TryFrom; +use std::num::TryFromIntError; + +fn main() { + let x: u32 = 125; + let y: Result = u8::try_from(x); + y == Ok(125); +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-is-identifier-edition2015.rs b/gcc/testsuite/rust/rustc/ui/try-is-identifier-edition2015.rs new file mode 100644 index 000000000000..b5756eb741bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-is-identifier-edition2015.rs @@ -0,0 +1,12 @@ +// run-pass + +#![allow(non_camel_case_types)] +// compile-flags: --edition 2015 + +fn main() { + let try = 2; + struct try { try: u32 }; + let try: try = try { try }; + assert_eq!(try.try, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-macro-suggestion.rs b/gcc/testsuite/rust/rustc/ui/try-macro-suggestion.rs new file mode 100644 index 000000000000..6f77ccb4014f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-macro-suggestion.rs @@ -0,0 +1,10 @@ +// compile-flags: --edition 2018 +fn foo() -> Result<(), ()> { + Ok(try!()); // { dg-error "" "" { target *-*-* } } + Ok(try!(Ok(()))) // { dg-error "" "" { target *-*-* } } +} + +fn main() { + let _ = foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-on-option-diagnostics.rs b/gcc/testsuite/rust/rustc/ui/try-on-option-diagnostics.rs new file mode 100644 index 000000000000..89885d36bff2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-on-option-diagnostics.rs @@ -0,0 +1,48 @@ +#![feature(try_trait)] +// edition:2018 +fn main() {} + +fn a_function() -> u32 { + let x: Option = None; + x?; // { dg-error ".E0277." "" { target *-*-* } } + 22 +} + +fn a_closure() -> u32 { + let a_closure = || { + let x: Option = None; + x?; // { dg-error ".E0277." "" { target *-*-* } } + 22 + }; + a_closure() +} + +fn a_method() -> u32 { + struct S; + + impl S { + fn a_method() { + let x: Option = None; + x?; // { dg-error ".E0277." "" { target *-*-* } } + } + } + + S::a_method(); + 22 +} + +fn a_trait_method() -> u32 { + struct S; + trait T { + fn a_trait_method() { + let x: Option = None; + x?; // { dg-error ".E0277." "" { target *-*-* } } + } + } + + impl T for S { } + + S::a_trait_method(); + 22 +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-on-option.rs b/gcc/testsuite/rust/rustc/ui/try-on-option.rs new file mode 100644 index 000000000000..90737a0e91cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-on-option.rs @@ -0,0 +1,16 @@ +#![feature(try_trait)] + +fn main() {} + +fn foo() -> Result { + let x: Option = None; + x?; // { dg-error ".E0277." "" { target *-*-* } } + Ok(22) +} + +fn bar() -> u32 { + let x: Option = None; + x?; // { dg-error ".E0277." "" { target *-*-* } } + 22 +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-operator-custom.rs b/gcc/testsuite/rust/rustc/ui/try-operator-custom.rs new file mode 100644 index 000000000000..e801437cf4e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-operator-custom.rs @@ -0,0 +1,64 @@ +// run-pass + +#![feature(try_trait)] + +use std::ops::Try; + +enum MyResult { + Awesome(T), + Terrible(U) +} + +impl Try for MyResult { + type Ok = U; + type Error = V; + + fn from_ok(u: U) -> MyResult { + MyResult::Awesome(u) + } + + fn from_error(e: V) -> MyResult { + MyResult::Terrible(e) + } + + fn into_result(self) -> Result { + match self { + MyResult::Awesome(u) => Ok(u), + MyResult::Terrible(e) => Err(e), + } + } +} + +fn f(x: i32) -> Result { + if x == 0 { + Ok(42) + } else { + let y = g(x)?; + Ok(y) + } +} + +fn g(x: i32) -> MyResult { + let _y = f(x - 1)?; + MyResult::Terrible("Hello".to_owned()) +} + +fn h() -> MyResult { + let a: Result = Err("Hello"); + let b = a?; + MyResult::Awesome(b) +} + +fn i() -> MyResult { + let a: MyResult = MyResult::Terrible("Hello"); + let b = a?; + MyResult::Awesome(b) +} + +fn main() { + assert!(f(0) == Ok(42)); + assert!(f(10) == Err("Hello".to_owned())); + let _ = h(); + let _ = i(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-operator-hygiene.rs b/gcc/testsuite/rust/rustc/ui/try-operator-hygiene.rs new file mode 100644 index 000000000000..16147970de1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-operator-hygiene.rs @@ -0,0 +1,27 @@ +// run-pass + +#![allow(non_upper_case_globals)] +#![allow(dead_code)] +// `expr?` expands to: +// +// match expr { +// Ok(val) => val, +// Err(err) => return Err(From::from(err)), +// } +// +// This test verifies that the expansion is hygienic, i.e., it's not affected by other `val` and +// `err` bindings that may be in scope. + +use std::num::ParseIntError; + +fn main() { + assert_eq!(parse(), Ok(1)); +} + +fn parse() -> Result { + const val: char = 'a'; + const err: char = 'b'; + + Ok("1".parse::()?) +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-operator-on-main.rs b/gcc/testsuite/rust/rustc/ui/try-operator-on-main.rs new file mode 100644 index 000000000000..aaf61f1b0eef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-operator-on-main.rs @@ -0,0 +1,26 @@ +// ignore-cloudabi no std::fs support + +#![feature(try_trait)] + +use std::ops::Try; + +fn main() { + // error for a `Try` type on a non-`Try` fn + std::fs::File::open("foo")?; // { dg-error ".E0277." "" { target *-*-* } } + + // a non-`Try` type on a non-`Try` fn + ()?; // { dg-error ".E0277." "" { target *-*-* } } + + // an unrelated use of `Try` + try_trait_generic::<()>(); // { dg-error ".E0277." "" { target *-*-* } } +} + + + +fn try_trait_generic() -> T { + // and a non-`Try` object on a `Try` fn. + ()?; // { dg-error ".E0277." "" { target *-*-* } } + + loop {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-operator.rs b/gcc/testsuite/rust/rustc/ui/try-operator.rs new file mode 100644 index 000000000000..fd92c71bad85 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-operator.rs @@ -0,0 +1,194 @@ +// run-pass + +#![allow(dead_code)] +// ignore-cloudabi no std::fs + +use std::fs::File; +use std::io::{Read, self}; +use std::num::ParseIntError; +use std::str::FromStr; + +fn on_method() -> Result { + Ok("1".parse::()? + "2".parse::()?) +} + +fn in_chain() -> Result { + Ok("3".parse::()?.to_string()) +} + +fn on_call() -> Result { + fn parse(s: &str) -> Result { + s.parse() + } + + Ok(parse("4")?) +} + +fn nested() -> Result { + Ok("5".parse::()?.to_string().parse()?) +} + +fn on_path() -> Result { + let x = "6".parse::(); + + Ok(x?) +} + +fn on_macro() -> Result { + macro_rules! id { + ($e:expr) => { $e } + } + + Ok(id!("7".parse::())?) +} + +fn on_parens() -> Result { + let x = "8".parse::(); + + Ok((x)?) +} + +fn on_block() -> Result { + let x = "9".parse::(); + + Ok({x}?) +} + +fn on_field() -> Result { + struct Pair { a: A, b: B } + + let x = Pair { a: "10".parse::(), b: 0 }; + + Ok(x.a?) +} + +fn on_tuple_field() -> Result { + let x = ("11".parse::(), 0); + + Ok(x.0?) +} + +fn on_try() -> Result { + let x = "12".parse::().map(|i| i.to_string().parse::()); + + Ok(x??) +} + +fn on_binary_op() -> Result { + let x = 13 - "14".parse::()?; + let y = "15".parse::()? - 16; + let z = "17".parse::()? - "18".parse::()?; + + Ok(x + y + z) +} + +fn on_index() -> Result { + let x = [19]; + let y = "0".parse::(); + + Ok(x[y?]) +} + +fn on_args() -> Result { + fn sub(x: i32, y: i32) -> i32 { x - y } + + let x = "20".parse(); + let y = "21".parse(); + + Ok(sub(x?, y?)) +} + +fn on_if() -> Result { + Ok(if true { + "22".parse::() + } else { + "23".parse::() + }?) +} + +fn on_if_let() -> Result { + Ok(if let Ok(..) = "24".parse::() { + "25".parse::() + } else { + "26".parse::() + }?) +} + +fn on_match() -> Result { + Ok(match "27".parse::() { + Err(..) => "28".parse::(), + Ok(..) => "29".parse::(), + }?) +} + +fn tight_binding() -> Result { + fn ok(x: T) -> Result { Ok(x) } + + let x = ok(true); + Ok(!x?) +} + +// just type check +fn merge_error() -> Result { + let mut s = String::new(); + + File::open("foo.txt")?.read_to_string(&mut s)?; + + Ok(s.parse::()? + 1) +} + +fn main() { + assert_eq!(Ok(3), on_method()); + + assert_eq!(Ok("3".to_string()), in_chain()); + + assert_eq!(Ok(4), on_call()); + + assert_eq!(Ok(5), nested()); + + assert_eq!(Ok(6), on_path()); + + assert_eq!(Ok(7), on_macro()); + + assert_eq!(Ok(8), on_parens()); + + assert_eq!(Ok(9), on_block()); + + assert_eq!(Ok(10), on_field()); + + assert_eq!(Ok(11), on_tuple_field()); + + assert_eq!(Ok(12), on_try()); + + assert_eq!(Ok(-3), on_binary_op()); + + assert_eq!(Ok(19), on_index()); + + assert_eq!(Ok(-1), on_args()); + + assert_eq!(Ok(22), on_if()); + + assert_eq!(Ok(25), on_if_let()); + + assert_eq!(Ok(29), on_match()); + + assert_eq!(Ok(false), tight_binding()); +} + +enum Error { + Io(io::Error), + Parse(ParseIntError), +} + +impl From for Error { + fn from(e: io::Error) -> Error { + Error::Io(e) + } +} + +impl From for Error { + fn from(e: ParseIntError) -> Error { + Error::Parse(e) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-poll.rs b/gcc/testsuite/rust/rustc/ui/try-poll.rs new file mode 100644 index 000000000000..8622e5d14307 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-poll.rs @@ -0,0 +1,51 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(dead_code, unused)] + +use std::task::Poll; + +struct K; +struct E; + +fn as_result() -> Result<(), E> { + // From Result + let K = Ok::(K)?; + + // From Poll + let _: Poll = Poll::Ready::>(Ok(K))?; + + // From Poll> + let _: Poll> = Poll::Ready::>>(None)?; + + Ok(()) +} + +fn as_poll_result() -> Poll> { + // From Result + let K = Ok::(K)?; + + // From Poll + let _: Poll = Poll::Ready::>(Ok(K))?; + + // From Poll> + let _: Poll> = Poll::Ready::>>(None)?; + + Poll::Ready(Ok(())) +} + +fn as_poll_option_result() -> Poll>> { + // From Result + let K = Ok::(K)?; + + // From Poll + let _: Poll = Poll::Ready::>(Ok(K))?; + + // From Poll> + let _: Poll> = Poll::Ready::>>(None)?; + + Poll::Ready(Some(Ok(()))) +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/try-wait.rs b/gcc/testsuite/rust/rustc/ui/try-wait.rs new file mode 100644 index 000000000000..32621611fb7f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/try-wait.rs @@ -0,0 +1,62 @@ +// run-pass + +#![allow(stable_features)] +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +#![feature(process_try_wait)] + +use std::env; +use std::process::Command; +use std::thread; +use std::time::Duration; + +fn main() { + let args = env::args().collect::>(); + if args.len() != 1 { + match &args[1][..] { + "sleep" => thread::sleep(Duration::new(1_000, 0)), + _ => {} + } + return + } + + let mut me = Command::new(env::current_exe().unwrap()) + .arg("sleep") + .spawn() + .unwrap(); + let maybe_status = me.try_wait().unwrap(); + assert!(maybe_status.is_none()); + let maybe_status = me.try_wait().unwrap(); + assert!(maybe_status.is_none()); + + me.kill().unwrap(); + me.wait().unwrap(); + + let status = me.try_wait().unwrap().unwrap(); + assert!(!status.success()); + let status = me.try_wait().unwrap().unwrap(); + assert!(!status.success()); + + let mut me = Command::new(env::current_exe().unwrap()) + .arg("return-quickly") + .spawn() + .unwrap(); + loop { + match me.try_wait() { + Ok(Some(res)) => { + assert!(res.success()); + break + } + Ok(None) => { + thread::sleep(Duration::from_millis(1)); + } + Err(e) => panic!("error in try_wait: {}", e), + } + } + + let status = me.try_wait().unwrap().unwrap(); + assert!(status.success()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/tup.rs b/gcc/testsuite/rust/rustc/ui/tup.rs new file mode 100644 index 000000000000..ab8d05a9eac1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tup.rs @@ -0,0 +1,22 @@ +// run-pass + +#![allow(non_camel_case_types)] + +type point = (isize, isize); + +fn f(p: point, x: isize, y: isize) { + let (a, b) = p; + assert_eq!(a, x); + assert_eq!(b, y); +} + +pub fn main() { + let p: point = (10, 20); + let (a, b) = p; + assert_eq!(a, 10); + assert_eq!(b, 20); + let p2: point = p; + f(p, 10, 20); + f(p2, 10, 20); +} + diff --git a/gcc/testsuite/rust/rustc/ui/tuple-index-fat-types.rs b/gcc/testsuite/rust/rustc/ui/tuple-index-fat-types.rs new file mode 100644 index 000000000000..8f2ba9188c0b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tuple-index-fat-types.rs @@ -0,0 +1,14 @@ +// run-pass + +struct Foo<'a>(&'a [isize]); + +fn main() { + let x: &[isize] = &[1, 2, 3]; + let y = (x,); + assert_eq!(y.0, x); + + let x: &[isize] = &[1, 2, 3]; + let y = Foo(x); + assert_eq!(y.0, x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/tuple-index.rs b/gcc/testsuite/rust/rustc/ui/tuple-index.rs new file mode 100644 index 000000000000..f9481d9d0717 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tuple-index.rs @@ -0,0 +1,33 @@ +// run-pass + +struct Point(isize, isize); + +fn main() { + let mut x = Point(3, 2); + assert_eq!(x.0, 3); + assert_eq!(x.1, 2); + x.0 += 5; + assert_eq!(x.0, 8); + { + let ry = &mut x.1; + *ry -= 2; + x.0 += 3; + assert_eq!(x.0, 11); + } + assert_eq!(x.1, 0); + + let mut x = (3, 2); + assert_eq!(x.0, 3); + assert_eq!(x.1, 2); + x.0 += 5; + assert_eq!(x.0, 8); + { + let ry = &mut x.1; + *ry -= 2; + x.0 += 3; + assert_eq!(x.0, 11); + } + assert_eq!(x.1, 0); + +} + diff --git a/gcc/testsuite/rust/rustc/ui/tuple/index-float.rs b/gcc/testsuite/rust/rustc/ui/tuple/index-float.rs new file mode 100644 index 000000000000..8c441b677094 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tuple/index-float.rs @@ -0,0 +1,11 @@ +// check-pass + +fn main() { + let tuple = (((),),); + + let _ = tuple. 0.0; // OK, whitespace + let _ = tuple.0. 0; // OK, whitespace + + let _ = tuple./*special cases*/0.0; // OK, comment +} + diff --git a/gcc/testsuite/rust/rustc/ui/tuple/index-invalid.rs b/gcc/testsuite/rust/rustc/ui/tuple/index-invalid.rs new file mode 100644 index 000000000000..bded4830af06 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tuple/index-invalid.rs @@ -0,0 +1,8 @@ +fn main() { + let _ = (((),),).1.0; // { dg-error ".E0609." "" { target *-*-* } } + + let _ = (((),),).0.1; // { dg-error ".E0609." "" { target *-*-* } } + + let _ = (((),),).000.000; // { dg-error ".E0609." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/tuple/indexing-in-macro.rs b/gcc/testsuite/rust/rustc/ui/tuple/indexing-in-macro.rs new file mode 100644 index 000000000000..d04019282726 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tuple/indexing-in-macro.rs @@ -0,0 +1,10 @@ +// check-pass + +macro_rules! m { + (.$l:literal) => {}; +} + +m!(.0.0); // OK, `0.0` after a dot is still a float token. + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/tuple/nested-index.rs b/gcc/testsuite/rust/rustc/ui/tuple/nested-index.rs new file mode 100644 index 000000000000..438c4f4cc5d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tuple/nested-index.rs @@ -0,0 +1,13 @@ +// run-pass + +fn main () { + let n = (1, (2, 3)).1.1; + assert_eq!(n, 3); + + let n = (1, (2, (3, 4))).1.1.1; + assert_eq!(n, 4); + + // This is a range expression, not nested indexing. + let _ = 0.0..1.1; +} + diff --git a/gcc/testsuite/rust/rustc/ui/tuple/tuple-arity-mismatch.rs b/gcc/testsuite/rust/rustc/ui/tuple/tuple-arity-mismatch.rs new file mode 100644 index 000000000000..7417968f4863 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tuple/tuple-arity-mismatch.rs @@ -0,0 +1,18 @@ +// Issue #6155 + +fn first((value, _): (isize, f64)) -> isize { value } + +fn main() { + let y = first ((1,2.0,3)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + + let y = first ((1,)); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/tuple/tuple-index-not-tuple.rs b/gcc/testsuite/rust/rustc/ui/tuple/tuple-index-not-tuple.rs new file mode 100644 index 000000000000..9241c6162cf9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tuple/tuple-index-not-tuple.rs @@ -0,0 +1,11 @@ +struct Point { x: isize, y: isize } +struct Empty; + +fn main() { + let origin = Point { x: 0, y: 0 }; + origin.0; +// { dg-error ".E0609." "" { target *-*-* } .-1 } + Empty.0; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/tuple/tuple-index-out-of-bounds.rs b/gcc/testsuite/rust/rustc/ui/tuple/tuple-index-out-of-bounds.rs new file mode 100644 index 000000000000..c1e3be605845 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tuple/tuple-index-out-of-bounds.rs @@ -0,0 +1,15 @@ +struct Point(i32, i32); + +fn main() { + let origin = Point(0, 0); + origin.0; + origin.1; + origin.2; +// { dg-error ".E0609." "" { target *-*-* } .-1 } + let tuple = (0, 0); + tuple.0; + tuple.1; + tuple.2; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/tuple/tuple-struct-fields/test.rs b/gcc/testsuite/rust/rustc/ui/tuple/tuple-struct-fields/test.rs new file mode 100644 index 000000000000..a351f3e8afb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tuple/tuple-struct-fields/test.rs @@ -0,0 +1,10 @@ +mod foo { + type T = (); + struct S1(pub(in foo) (), pub(T), pub(crate) (), pub(((), T))); + struct S2(pub((foo)) ()); +// { dg-error ".E0412." "" { target *-*-* } .-1 } +// { dg-error ".E0412." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/tuple/tuple-struct-fields/test2.rs b/gcc/testsuite/rust/rustc/ui/tuple/tuple-struct-fields/test2.rs new file mode 100644 index 000000000000..0f3174abc5c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tuple/tuple-struct-fields/test2.rs @@ -0,0 +1,16 @@ +macro_rules! define_struct { + ($t:ty) => { + struct S1(pub $t); + struct S2(pub (in foo) ()); + struct S3(pub $t ()); +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +mod foo { + define_struct! { (foo) } // { dg-error ".E0412." "" { target *-*-* } } +// { dg-error ".E0412." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/tuple/tuple-struct-fields/test3.rs b/gcc/testsuite/rust/rustc/ui/tuple/tuple-struct-fields/test3.rs new file mode 100644 index 000000000000..5c9b74d7a139 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tuple/tuple-struct-fields/test3.rs @@ -0,0 +1,16 @@ +macro_rules! define_struct { + ($t:ty) => { + struct S1(pub($t)); + struct S2(pub (in foo) ()); + struct S3(pub($t) ()); +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +mod foo { + define_struct! { foo } // { dg-error ".E0412." "" { target *-*-* } } +// { dg-error ".E0412." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/tutorial-suffix-inference-test.rs b/gcc/testsuite/rust/rustc/ui/tutorial-suffix-inference-test.rs new file mode 100644 index 000000000000..8e136e7cdd71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tutorial-suffix-inference-test.rs @@ -0,0 +1,25 @@ +fn main() { + let x = 3; + let y: i32 = 3; + + fn identity_u8(n: u8) -> u8 { n } + fn identity_u16(n: u16) -> u16 { n } + + identity_u8(x); // after this, `x` is assumed to have type `u8` + identity_u16(x); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + identity_u16(y); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + let a = 3; + + fn identity_i(n: isize) -> isize { n } + + identity_i(a); // ok + identity_u16(a); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/tydesc-name.rs b/gcc/testsuite/rust/rustc/ui/tydesc-name.rs new file mode 100644 index 000000000000..4635933f56b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/tydesc-name.rs @@ -0,0 +1,15 @@ +// run-pass + +#![allow(dead_code)] + +use std::any::type_name; + +struct Foo { + x: T +} + +pub fn main() { + assert_eq!(type_name::(), "isize"); + assert_eq!(type_name::>(), "tydesc_name::Foo"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs new file mode 100644 index 000000000000..06b8bc9423e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs @@ -0,0 +1,60 @@ +// run-pass + +// Check that resolving, in the value namespace, to an `enum` variant +// through a type alias is well behaved in the presence of generics. +// We check for situations with: +// 1. a generic type `Alias`, we can type-apply `Alias` when referring to a variant. +// 2. a monotype `AliasFixed` of generic `Enum`, we can refer to variants +// and the type-application of `T` in `AliasFixed` is kept. + +#![allow(irrefutable_let_patterns)] + +enum Enum { TSVariant(T), SVariant { _v: T }, UVariant } +type Alias = Enum; +type AliasFixed = Enum<()>; + +macro_rules! is_variant { + (TSVariant, $expr:expr) => (is_variant!(@check TSVariant, (_), $expr)); + (SVariant, $expr:expr) => (is_variant!(@check SVariant, { _v: _ }, $expr)); + (UVariant, $expr:expr) => (is_variant!(@check UVariant, {}, $expr)); + (@check $variant:ident, $matcher:tt, $expr:expr) => ( + assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false }, + "expr does not have correct type"); + ); +} + +fn main() { + // Tuple struct variant + + is_variant!(TSVariant, Enum::TSVariant(())); + is_variant!(TSVariant, Enum::TSVariant::<()>(())); + is_variant!(TSVariant, Enum::<()>::TSVariant(())); + + is_variant!(TSVariant, Alias::TSVariant(())); + is_variant!(TSVariant, Alias::<()>::TSVariant(())); + + is_variant!(TSVariant, AliasFixed::TSVariant(())); + + // Struct variant + + is_variant!(SVariant, Enum::SVariant { _v: () }); + is_variant!(SVariant, Enum::SVariant::<()> { _v: () }); + is_variant!(SVariant, Enum::<()>::SVariant { _v: () }); + + is_variant!(SVariant, Alias::SVariant { _v: () }); + is_variant!(SVariant, Alias::<()>::SVariant { _v: () }); + + is_variant!(SVariant, AliasFixed::SVariant { _v: () }); + + // Unit variant + + is_variant!(UVariant, Enum::UVariant); + is_variant!(UVariant, Enum::UVariant::<()>); + is_variant!(UVariant, Enum::<()>::UVariant); + + is_variant!(UVariant, Alias::UVariant); + is_variant!(UVariant, Alias::<()>::UVariant); + + is_variant!(UVariant, AliasFixed::UVariant); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-generic-args.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-generic-args.rs new file mode 100644 index 000000000000..6f16162628f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-generic-args.rs @@ -0,0 +1,106 @@ +// Checks that applied type arguments of enums, and aliases to them, are respected. +// For example, `Self` is never a type constructor. Therefore, no types can be applied to it. +// +// We also check that the variant to an type-aliased enum cannot be type applied whether +// that alias is generic or monomorphic. + +enum Enum { TSVariant(T), SVariant { v: T }, UVariant } +type Alias = Enum; +type AliasFixed = Enum<()>; + +impl Enum { + fn ts_variant() { + Self::TSVariant(()); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + Self::TSVariant::<()>(()); +// { dg-error ".E0109." "" { target *-*-* } .-1 } + Self::<()>::TSVariant(()); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + Self::<()>::TSVariant::<()>(()); +// { dg-error ".E0109." "" { target *-*-* } .-1 } +// { dg-error ".E0109." "" { target *-*-* } .-2 } + } + + fn s_variant() { + Self::SVariant { v: () }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + Self::SVariant::<()> { v: () }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + Self::<()>::SVariant { v: () }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + Self::<()>::SVariant::<()> { v: () }; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + } + + fn u_variant() { + Self::UVariant::<()>; +// { dg-error ".E0109." "" { target *-*-* } .-1 } + Self::<()>::UVariant; +// { dg-error ".E0109." "" { target *-*-* } .-1 } + Self::<()>::UVariant::<()>; +// { dg-error ".E0109." "" { target *-*-* } .-1 } +// { dg-error ".E0109." "" { target *-*-* } .-2 } + } +} + +fn main() { + // Tuple struct variant + + Enum::<()>::TSVariant::<()>(()); +// { dg-error ".E0109." "" { target *-*-* } .-1 } + + Alias::TSVariant::<()>(()); +// { dg-error ".E0109." "" { target *-*-* } .-1 } + Alias::<()>::TSVariant::<()>(()); +// { dg-error ".E0109." "" { target *-*-* } .-1 } + + AliasFixed::TSVariant::<()>(()); +// { dg-error ".E0109." "" { target *-*-* } .-1 } + AliasFixed::<()>::TSVariant(()); +// { dg-error ".E0107." "" { target *-*-* } .-1 } + AliasFixed::<()>::TSVariant::<()>(()); +// { dg-error ".E0109." "" { target *-*-* } .-1 } +// { dg-error ".E0109." "" { target *-*-* } .-2 } + + // Struct variant + + Enum::<()>::SVariant::<()> { v: () }; +// { dg-error ".E0109." "" { target *-*-* } .-1 } + + Alias::SVariant::<()> { v: () }; +// { dg-error ".E0109." "" { target *-*-* } .-1 } + Alias::<()>::SVariant::<()> { v: () }; +// { dg-error ".E0109." "" { target *-*-* } .-1 } + + AliasFixed::SVariant::<()> { v: () }; +// { dg-error ".E0109." "" { target *-*-* } .-1 } + AliasFixed::<()>::SVariant { v: () }; +// { dg-error ".E0107." "" { target *-*-* } .-1 } + AliasFixed::<()>::SVariant::<()> { v: () }; +// { dg-error ".E0109." "" { target *-*-* } .-1 } +// { dg-error ".E0109." "" { target *-*-* } .-2 } + + // Unit variant + + Enum::<()>::UVariant::<()>; +// { dg-error ".E0109." "" { target *-*-* } .-1 } + + Alias::UVariant::<()>; +// { dg-error ".E0109." "" { target *-*-* } .-1 } + Alias::<()>::UVariant::<()>; +// { dg-error ".E0109." "" { target *-*-* } .-1 } + + AliasFixed::UVariant::<()>; +// { dg-error ".E0109." "" { target *-*-* } .-1 } + AliasFixed::<()>::UVariant; +// { dg-error ".E0107." "" { target *-*-* } .-1 } + AliasFixed::<()>::UVariant::<()>; +// { dg-error ".E0109." "" { target *-*-* } .-1 } +// { dg-error ".E0109." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs new file mode 100644 index 000000000000..623ae16c2589 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.rs @@ -0,0 +1,24 @@ +// Check that an `enum` variant is resolved, in the value namespace, +// with higher priority than other inherent items when there is a conflict. + +enum E { + V(u8) +} + +impl E { + fn V() {} +} + +enum E2 { + V, +} + +impl E2 { + const V: u8 = 0; +} + +fn main() { + ::V(); // { dg-error ".E0061." "" { target *-*-* } } + let _: u8 = ::V; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs new file mode 100644 index 000000000000..c9977d5d68ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs @@ -0,0 +1,39 @@ +// Check that a projection `Self::V` in a trait implementation, +// with an associated type named `V`, for an `enum` with a variant named `V`, +// results in triggering the deny-by-default lint `ambiguous_associated_items`. +// The lint suggests that qualified syntax should be used instead. +// That is, the user would write `::V`. +// +// The rationale for this is that while `enum` variants do currently +// not exist in the type namespace but solely in the value namespace, +// RFC #2593 "Enum variant types", would add enum variants to the type namespace. +// However, currently `enum` variants are resolved with high priority as +// they are resolved as inherent associated items. +// Should #2953 therefore be implemented, `Self::V` would suddenly switch +// from referring to the associated type `V` instead of the variant `V`. +// The lint exists to keep us forward compatible with #2593. +// +// As a closing note, provided that #2933 was implemented and +// if `enum` variants were given lower priority than associated types, +// it would be impossible to refer to the `enum` variant `V` whereas +// the associated type could be referred to with qualified syntax as seen above. + +enum E { + V +} + +trait Tr { + type V; + fn f() -> Self::V; +} + +impl Tr for E { + type V = u8; + fn f() -> Self::V { 0 } +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs new file mode 100644 index 000000000000..cd45c6a3e9d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.rs @@ -0,0 +1,15 @@ +pub enum Enum { + A(usize), +} + +impl Enum { + fn foo(&self) -> () { + match self { + Self::A => (), +// { dg-error ".E0533." "" { target *-*-* } .-1 } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs new file mode 100644 index 000000000000..7d58b58ac7a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs @@ -0,0 +1,22 @@ +// ignore-tidy-linelength + +// Check that creating/matching on an enum variant through an alias with +// the wrong braced/unit form is caught as an error. + +enum Enum { Braced {}, Unit, Tuple() } +type Alias = Enum; + +fn main() { + Alias::Braced; +// { dg-error ".E0533." "" { target *-*-* } .-1 } + let Alias::Braced = panic!(); +// { dg-error ".E0533." "" { target *-*-* } .-1 } + let Alias::Braced(..) = panic!(); +// { dg-error ".E0164." "" { target *-*-* } .-1 } + + Alias::Unit(); +// { dg-error ".E0618." "" { target *-*-* } .-1 } + let Alias::Unit() = panic!(); +// { dg-error ".E0164." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/issue-57866.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/issue-57866.rs new file mode 100644 index 000000000000..5a70e4f92e41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/issue-57866.rs @@ -0,0 +1,25 @@ +// check-pass + +enum Outer { + A(T) +} + +enum Inner { + A(i32) +} + +type OuterAlias = Outer; + +fn ice(x: OuterAlias) { + // Fine + match x { + OuterAlias::A(Inner::A(_)) => (), + } + // Not fine + match x { + OuterAlias::A(Inner::A(y)) => (), + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs new file mode 100644 index 000000000000..5165b1a99ab3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs @@ -0,0 +1,29 @@ +// In this regression test we check that a path pattern referring to a unit variant +// through a type alias is successful in inferring the generic argument. + +// check-pass + +enum Opt { + N, + S(T), +} + +type OptAlias = Opt; + +fn f1(x: OptAlias) { + match x { + OptAlias::N // We previously failed to infer `T` to `u8`. + => (), + _ => (), + } + + match x { + < + OptAlias<_> // And we failed to infer this type also. + >::N => (), + _ => (), + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs new file mode 100644 index 000000000000..32c8e3cb13f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/issue-63151-dead-code-lint-fields-in-patterns.rs @@ -0,0 +1,27 @@ +// check-pass + +// Regression test for the issue #63151: +// Spurious unused field warning when matching variants under a `Self` scope +// +// This test checks that the `dead_code` lint properly inspects fields +// in struct patterns that use a type relative path. + +#![deny(dead_code)] + +enum Enum { + Variant { field: usize } +} + +impl Enum { + fn read_field(self) -> usize { + match self { + Self::Variant { field } => field + } + } +} + +fn main() { + let e = Enum::Variant { field: 42 }; + println!("{}", e.read_field()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs new file mode 100644 index 000000000000..e60f8300ccfb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/no-type-application-on-aliased-enum-variant.rs @@ -0,0 +1,15 @@ +// Check that a generic type for an `enum` admits type application +// on both the type constructor and the generic type's variant. +// +// Also check that a type alias to said generic type admits type application +// on the type constructor but *NOT* the variant. + +type Alias = Option; + +fn main() { + let _ = Option::::None; // OK + let _ = Option::None::; // OK (Lint in future!) + let _ = Alias::::None; // OK + let _ = Alias::None::; // { dg-error ".E0109." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs new file mode 100644 index 000000000000..9b558a719a32 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/resolve-to-enum-variant-in-type-namespace-and-error.rs @@ -0,0 +1,12 @@ +// Check that the compiler will resolve `::V` to the variant `V` in the type namespace +// but will reject this because `enum` variants do not exist in the type namespace. + +enum E { + V +} + +fn check() -> ::V {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/self-in-enum-definition.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/self-in-enum-definition.rs new file mode 100644 index 000000000000..7e7a64a1e720 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/self-in-enum-definition.rs @@ -0,0 +1,9 @@ +#[repr(u8)] +enum Alpha { + V1 = 41, + V2 = Self::V1 as u8 + 1, // OK; See #50072. + V3 = Self::V1 {} as u8 + 2, // { dg-error ".E0391." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs new file mode 100644 index 000000000000..129363daf4fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-enum-variants/type-alias-enum-variants-pass.rs @@ -0,0 +1,70 @@ +// run-pass + +// Check that it is possible to resolve, in the value namespace, +// to an `enum` variant through a type alias. This includes `Self`. +// Type qualified syntax `::Variant` also works when syntactically valid. + +#[derive(Debug, PartialEq, Eq)] +enum Foo { + Bar(i32), + Baz { i: i32 }, + Qux, +} + +type FooAlias = Foo; +type OptionAlias = Option; + +macro_rules! check_pat { + ($x:expr, $p:pat) => { + assert!(if let $p = $x { true } else { false }); + }; +} + +impl Foo { + fn bar() -> Self { + let x = Self::Bar(3); + assert_eq!(x, ::Bar(3)); + check_pat!(x, Self::Bar(3)); + x + } + + fn baz() -> Self { + let x = Self::Baz { i: 42 }; + check_pat!(x, Self::Baz { i: 42 }); + x + } + + fn qux() -> Self { + let x = Self::Qux; + assert_eq!(x, ::Qux); + check_pat!(x, Self::Qux); + check_pat!(x, ::Qux); + x + } +} + +fn main() { + let bar = Foo::Bar(1); + assert_eq!(bar, FooAlias::Bar(1)); + assert_eq!(bar, ::Bar(1)); + check_pat!(bar, FooAlias::Bar(1)); + + let baz = FooAlias::Baz { i: 2 }; + assert_eq!(baz, Foo::Baz { i: 2 }); + check_pat!(baz, FooAlias::Baz { i: 2 }); + + let qux = Foo::Qux; + assert_eq!(qux, FooAlias::Qux); + assert_eq!(qux, ::Qux); + check_pat!(qux, FooAlias::Qux); + check_pat!(qux, ::Qux); + + assert_eq!(Foo::bar(), Foo::Bar(3)); + assert_eq!(Foo::baz(), Foo::Baz { i: 42 }); + assert_eq!(Foo::qux(), Foo::Qux); + + let some = Option::Some(4); + assert_eq!(some, OptionAlias::Some(4)); + check_pat!(some, OptionAlias::Some(4)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/assoc-type-const.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/assoc-type-const.rs new file mode 100644 index 000000000000..a20c14361c9a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/assoc-type-const.rs @@ -0,0 +1,35 @@ +// Tests that we properly detect defining usages when using +// const generics in an associated opaque type +// check-pass + +#![feature(type_alias_impl_trait)] +#![feature(const_generics)] +// { dg-warning "" "" { target *-*-* } .-1 } + +trait UnwrapItemsExt<'a, const C: usize> { + type Iter; + fn unwrap_items(self) -> Self::Iter; +} + +struct MyStruct {} + +trait MyTrait<'a, const C: usize> { + type MyItem; + const MY_CONST: usize; +} + +impl<'a, const C: usize> MyTrait<'a, C> for MyStruct { + type MyItem = u8; + const MY_CONST: usize = C; +} + +impl<'a, I, const C: usize> UnwrapItemsExt<'a, C> for I { + type Iter = impl MyTrait<'a, C>; + + fn unwrap_items(self) -> Self::Iter { + MyStruct:: {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs new file mode 100644 index 000000000000..fd02c3e3b932 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs @@ -0,0 +1,27 @@ +// Tests that we don't allow unconstrained lifetime parameters in impls when +// the lifetime is used in an associated opaque type. + +#![feature(type_alias_impl_trait)] + +trait UnwrapItemsExt { + type Iter; + fn unwrap_items(self) -> Self::Iter; +} + +struct MyStruct {} + +trait MyTrait<'a> {} + +impl<'a> MyTrait<'a> for MyStruct {} + +impl<'a, I> UnwrapItemsExt for I { +// { dg-error ".E0207." "" { target *-*-* } .-1 } + type Iter = impl MyTrait<'a>; + + fn unwrap_items(self) -> Self::Iter { + MyStruct {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/assoc-type-lifetime.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/assoc-type-lifetime.rs new file mode 100644 index 000000000000..05341587579d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/assoc-type-lifetime.rs @@ -0,0 +1,27 @@ +// Tests that we still detect defining usages when +// lifetimes are used in an associated opaque type +// check-pass + +#![feature(type_alias_impl_trait)] + +trait UnwrapItemsExt<'a> { + type Iter; + fn unwrap_items(self) -> Self::Iter; +} + +struct MyStruct {} + +trait MyTrait<'a> {} + +impl<'a> MyTrait<'a> for MyStruct {} + +impl<'a, I> UnwrapItemsExt<'a> for I { + type Iter = impl MyTrait<'a>; + + fn unwrap_items(self) -> Self::Iter { + MyStruct {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs new file mode 100644 index 000000000000..d36c80cc6690 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/associated-type-alias-impl-trait.rs @@ -0,0 +1,27 @@ +#![feature(type_alias_impl_trait)] +// build-pass (FIXME(62277): could be check-pass?) + +trait Bar {} +struct Dummy; +impl Bar for Dummy {} + +trait Foo { + type Assoc: Bar; + fn foo() -> Self::Assoc; + fn bar() -> Self::Assoc; +} + +type Helper = impl Bar; + +impl Foo for i32 { + type Assoc = Helper; + fn foo() -> Helper { + Dummy + } + fn bar() -> Helper { + Dummy + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs new file mode 100644 index 000000000000..c6589359f5dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs @@ -0,0 +1,12 @@ +// Crate that exports an opaque `impl Trait` type. Used for testing cross-crate. + +#![crate_type="rlib"] + +#![feature(type_alias_impl_trait)] + +pub type Foo = impl std::fmt::Debug; + +pub fn foo() -> Foo { + 5 +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs new file mode 100644 index 000000000000..133c2149505c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs @@ -0,0 +1,22 @@ +// Crate that exports an opaque `impl Trait` type. Used for testing cross-crate. + +#![crate_type="rlib"] + +#![feature(type_alias_impl_trait)] + +pub trait View { + type Tmp: Iterator; + + fn test(&self) -> Self::Tmp; +} + +pub struct X; + +impl View for X { + type Tmp = impl Iterator; + + fn test(&self) -> Self::Tmp { + vec![1,2,3].into_iter() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs new file mode 100644 index 000000000000..d902b776cb1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/auxiliary/foreign-crate.rs @@ -0,0 +1,3 @@ +pub trait ForeignTrait {} +pub struct ForeignType(pub T); + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bound_reduction.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bound_reduction.rs new file mode 100644 index 000000000000..e1273d98e0b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bound_reduction.rs @@ -0,0 +1,21 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![allow(warnings)] + +#![feature(type_alias_impl_trait)] + +fn main() { +} + +type Foo = impl std::fmt::Debug; + +trait Trait {} + +fn foo_desugared>(_: T) -> Foo { + (42, std::marker::PhantomData::) +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bound_reduction2.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bound_reduction2.rs new file mode 100644 index 000000000000..f18ee1560759 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bound_reduction2.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +trait TraitWithAssoc { + type Assoc; +} + +type Foo = impl Trait; + +trait Trait {} + +impl Trait for () {} + +fn foo_desugared(_: T) -> Foo { +// { dg-error "" "" { target *-*-* } .-1 } + () +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bounds-are-checked-2.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bounds-are-checked-2.rs new file mode 100644 index 000000000000..f8e270981fa8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bounds-are-checked-2.rs @@ -0,0 +1,20 @@ +// Make sure that we check that impl trait types implement the traits that they +// claim to. + +#![feature(type_alias_impl_trait)] + +type X = impl Clone; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn f(t: T) -> X { + t +} + +fn g(o: Option>) -> Option> { + o.clone() +} + +fn main() { + g(None::>); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bounds-are-checked.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bounds-are-checked.rs new file mode 100644 index 000000000000..4404ab378bf8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/bounds-are-checked.rs @@ -0,0 +1,26 @@ +// Make sure that we check that impl trait types implement the traits that they +// claim to. + +#![feature(type_alias_impl_trait)] + +type X<'a> = impl Into<&'static str> + From<&'a str>; +// { dg-error ".E0308." "" { target *-*-* } .-1 } + +fn f<'a: 'static>(t: &'a str) -> X<'a> { +// { dg-warning "" "" { target *-*-* } .-1 } + t +} + +fn extend_lt<'a>(o: &'a str) -> &'static str { + X::<'_>::from(o).into() +} + +fn main() { + let r = + { + let s = "abcdef".to_string(); + extend_lt(&s) + }; + println!("{}", r); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/coherence.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/coherence.rs new file mode 100644 index 000000000000..573c6ed66512 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/coherence.rs @@ -0,0 +1,18 @@ +// aux-build:foreign-crate.rs +#![feature(type_alias_impl_trait)] + +extern crate foreign_crate; + +trait LocalTrait {} +impl LocalTrait for foreign_crate::ForeignType {} + +type AliasOfForeignType = impl LocalTrait; +fn use_alias(val: T) -> AliasOfForeignType { + foreign_crate::ForeignType(val) +} + +impl foreign_crate::ForeignTrait for AliasOfForeignType {} +// { dg-error ".E0207." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/cross_crate_ice.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/cross_crate_ice.rs new file mode 100644 index 000000000000..2e2701c329d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/cross_crate_ice.rs @@ -0,0 +1,17 @@ +// aux-build:cross_crate_ice.rs +// build-pass (FIXME(62277): could be check-pass?) + +extern crate cross_crate_ice; + +struct Bar(cross_crate_ice::Foo); + +impl Bar { + fn zero(&self) -> &cross_crate_ice::Foo { + &self.0 + } +} + +fn main() { + let _ = cross_crate_ice::foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/cross_crate_ice2.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/cross_crate_ice2.rs new file mode 100644 index 000000000000..a1eb28877f39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/cross_crate_ice2.rs @@ -0,0 +1,12 @@ +// aux-build:cross_crate_ice2.rs +// build-pass (FIXME(62277): could be check-pass?) + +extern crate cross_crate_ice2; + +use cross_crate_ice2::View; + +fn main() { + let v = cross_crate_ice2::X; + v.test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/declared_but_never_defined.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/declared_but_never_defined.rs new file mode 100644 index 000000000000..c9bbc1385fa7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/declared_but_never_defined.rs @@ -0,0 +1,7 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +// declared but never defined +type Bar = impl std::fmt::Debug; // { dg-error "" "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs new file mode 100644 index 000000000000..f8cd29188217 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/declared_but_not_defined_in_scope.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +mod boo { + // declared in module but not defined inside of it + pub type Boo = impl ::std::fmt::Debug; // { dg-error "" "" { target *-*-* } } +} + +fn bomp() -> boo::Boo { + "" +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/different_defining_uses.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/different_defining_uses.rs new file mode 100644 index 000000000000..24d13ecd8e31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/different_defining_uses.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +// two definitions with different types +type Foo = impl std::fmt::Debug; + +fn foo() -> Foo { + "" +} + +fn bar() -> Foo { // { dg-error "" "" { target *-*-* } } + 42i32 +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/different_defining_uses_never_type.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/different_defining_uses_never_type.rs new file mode 100644 index 000000000000..c7cf1b5af48f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/different_defining_uses_never_type.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +// two definitions with different types +type Foo = impl std::fmt::Debug; + +fn foo() -> Foo { + "" +} + +fn bar() -> Foo { // { dg-error "" "" { target *-*-* } } + panic!() +} + +fn boo() -> Foo { // { dg-error "" "" { target *-*-* } } + loop {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs new file mode 100644 index 000000000000..fe0673c5acd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/different_defining_uses_never_type2.rs @@ -0,0 +1,45 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(type_alias_impl_trait)] + +fn main() {} + +// two definitions with different types +type Foo = impl std::fmt::Debug; + +fn foo() -> Foo { + "" +} + +fn bar(arg: bool) -> Foo { + if arg { + panic!() + } else { + "bar" + } +} + +fn boo(arg: bool) -> Foo { + if arg { + loop {} + } else { + "boo" + } +} + +fn bar2(arg: bool) -> Foo { + if arg { + "bar2" + } else { + panic!() + } +} + +fn boo2(arg: bool) -> Foo { + if arg { + "boo2" + } else { + loop {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/fallback.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/fallback.rs new file mode 100644 index 000000000000..b223f6036443 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/fallback.rs @@ -0,0 +1,29 @@ +// Tests that we correctly handle the instantiated +// inference variable being completely unconstrained. +// +// check-pass +#![feature(type_alias_impl_trait)] + +type Foo = impl Copy; + +enum Wrapper { + First(T), + Second +} + +// This method constrains `Foo` to be `bool` +fn constrained_foo() -> Foo { + true +} + + +// This method does not constrain `Foo`. +// Per RFC 2071, function bodies may either +// fully constrain an opaque type, or place no +// constraints on it. +fn unconstrained_foo() -> Wrapper { + Wrapper::Second +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_different_defining_uses.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_different_defining_uses.rs new file mode 100644 index 000000000000..a6c5304067d3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_different_defining_uses.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +type MyIter = impl Iterator; + +fn my_iter(t: T) -> MyIter { + std::iter::once(t) +} + +fn my_iter2(t: T) -> MyIter { // { dg-error "" "" { target *-*-* } } + Some(t).into_iter() +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs new file mode 100644 index 000000000000..bc7e4f58f19a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_lifetime_param.rs @@ -0,0 +1,10 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +type Two<'a, 'b> = impl std::fmt::Debug; + +fn one<'a>(t: &'a ()) -> Two<'a, 'a> { // { dg-error "" "" { target *-*-* } } + t +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use.rs new file mode 100644 index 000000000000..daafd7cbe02d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use.rs @@ -0,0 +1,27 @@ +#![feature(type_alias_impl_trait, const_generics)] +#![allow(incomplete_features)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +type TwoTys = impl Debug; +type TwoLifetimes<'a, 'b> = impl Debug; +type TwoConsts = impl Debug; + +fn one_ty(t: T) -> TwoTys { +// { dg-error "" "" { target *-*-* } .-1 } + t +} + +fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> { +// { dg-error "" "" { target *-*-* } .-1 } + t +} + +fn one_const(t: *mut [u8; N]) -> TwoConsts { +// { dg-error "" "" { target *-*-* } .-1 } + t +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs new file mode 100644 index 000000000000..e9f74c423304 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use10.rs @@ -0,0 +1,13 @@ +// check-pass +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +type Two = impl Debug; + +fn two(t: T, _: U) -> Two { + (t, 4u32) +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs new file mode 100644 index 000000000000..5706e0e6c923 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use2.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +type Two = impl Debug; + +fn one(t: T) -> Two { +// { dg-error "" "" { target *-*-* } .-1 } + t +} + +fn two(t: T, _: U) -> Two { + t +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs new file mode 100644 index 000000000000..36d6bc89b0b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use3.rs @@ -0,0 +1,22 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +type Two = impl Debug; + +fn one(t: T) -> Two { +// { dg-error "" "" { target *-*-* } .-1 } + t +} + +fn two(t: T, _: U) -> Two { + t +} + +fn three(_: T, u: U) -> Two { + u +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs new file mode 100644 index 000000000000..d5585ff4beab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use4.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +type Two = impl Debug; + +fn one(t: T) -> Two { +// { dg-error "" "" { target *-*-* } .-1 } + t +} + +fn three(_: T, u: U) -> Two { + u +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs new file mode 100644 index 000000000000..3fdcd1013ea7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use5.rs @@ -0,0 +1,20 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +type Two = impl Debug; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + +fn two(t: T, u: U) -> Two { + (t, u) +} + +fn three(t: T, u: U) -> Two { +// { dg-error "" "" { target *-*-* } .-1 } + (u, t) +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs new file mode 100644 index 000000000000..4f3e8e8567ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use6.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +// test that unused generic parameters are ok +type Two = impl Debug; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn two(t: T, u: U) -> Two { + (t, t) +} + +fn three(t: T, u: U) -> Two { +// { dg-error "" "" { target *-*-* } .-1 } + (u, t) +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs new file mode 100644 index 000000000000..058f8e194bba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use7.rs @@ -0,0 +1,25 @@ +// check-pass +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +type Two = impl Debug; + +fn two(t: T, u: U) -> Two { + (t, t) +} + +fn three(t: T, t2: T, u: U) -> Two { + (t, t2) +} + +fn four(t: T, t2: T, u: U, v: V) -> Two { + (t, t2) +} + +fn five(x: X, y: Y, y2: Y) -> Two { + (y, y2) +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs new file mode 100644 index 000000000000..e3ff62278117 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use8.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +type Two = impl Debug; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn two(t: T, _: U) -> Two { + (t, 4u32) +} + +fn three(_: T, u: U) -> Two { +// { dg-error "" "" { target *-*-* } .-1 } + (u, 4u32) +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs new file mode 100644 index 000000000000..031441b4d312 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs @@ -0,0 +1,24 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +type Two = impl Debug; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +// { dg-error ".E0277." "" { target *-*-* } .-3 } + +trait Foo { + type Bar: Debug; + const BAR: Self::Bar; +} + +fn two(t: T, u: U) -> Two { + (t, u, T::BAR) +} + +fn three(t: T, u: U) -> Two { +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_lifetime_param.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_lifetime_param.rs new file mode 100644 index 000000000000..55cf01cbe7ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_lifetime_param.rs @@ -0,0 +1,12 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(type_alias_impl_trait)] + +fn main() {} + +type Region<'a> = impl std::fmt::Debug; + +fn region<'b>(a: &'b ()) -> Region<'b> { + a +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_nondefining_use.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_nondefining_use.rs new file mode 100644 index 000000000000..8445e2a45479 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_nondefining_use.rs @@ -0,0 +1,28 @@ +#![feature(type_alias_impl_trait, const_generics)] +#![allow(incomplete_features)] + +use std::fmt::Debug; + +fn main() {} + +type OneTy = impl Debug; +type OneLifetime<'a> = impl Debug; +type OneConst = impl Debug; + +// Not defining uses, because they doesn't define *all* possible generics. + +fn concrete_ty() -> OneTy { +// { dg-error "" "" { target *-*-* } .-1 } + 5u32 +} + +fn concrete_lifetime() -> OneLifetime<'static> { +// { dg-error "" "" { target *-*-* } .-1 } + 6u32 +} + +fn concrete_const() -> OneConst<{123}> { +// { dg-error "" "" { target *-*-* } .-1 } + 7u32 +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_not_used.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_not_used.rs new file mode 100644 index 000000000000..bcb1ec8b9887 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_not_used.rs @@ -0,0 +1,12 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +type WrongGeneric = impl 'static; +// { dg-error "" "" { target *-*-* } .-1 } + +fn wrong_generic(_: U, v: V) -> WrongGeneric { +// { dg-error "" "" { target *-*-* } .-1 } + v +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs new file mode 100644 index 000000000000..d371b54d80ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs @@ -0,0 +1,17 @@ +#![feature(type_alias_impl_trait)] + +fn main() { + let y = 42; + let x = wrong_generic(&y); + let z: i32 = x; // { dg-error ".E0308." "" { target *-*-* } } +} + +type WrongGeneric = impl 'static; +// { dg-error ".E0310." "" { target *-*-* } .-1 } +// { dg-error ".E0310." "" { target *-*-* } .-2 } +// { dg-error ".E0310." "" { target *-*-* } .-3 } + +fn wrong_generic(t: T) -> WrongGeneric { + t +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_underconstrained.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_underconstrained.rs new file mode 100644 index 000000000000..d475e9d582e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_underconstrained.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +trait Trait {} +type Underconstrained = impl 'static; +// { dg-error "" "" { target *-*-* } .-1 } + +// no `Trait` bound +fn underconstrain(_: T) -> Underconstrained { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + unimplemented!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_underconstrained2.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_underconstrained2.rs new file mode 100644 index 000000000000..e6a550d312a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/generic_underconstrained2.rs @@ -0,0 +1,22 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +type Underconstrained = impl 'static; +// { dg-error "" "" { target *-*-* } .-1 } + +// not a defining use, because it doesn't define *all* possible generics +fn underconstrained(_: U) -> Underconstrained { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + 5u32 +} + +type Underconstrained2 = impl 'static; +// { dg-error "" "" { target *-*-* } .-1 } + +// not a defining use, because it doesn't define *all* possible generics +fn underconstrained2(_: U, _: V) -> Underconstrained2 { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + 5u32 +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs new file mode 100644 index 000000000000..62e3a8bead78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs @@ -0,0 +1,18 @@ +// Ensure that we don't ICE if associated type impl trait is used in an impl +// with an unconstrained type parameter. + +#![feature(type_alias_impl_trait)] + +trait X { + type I; + fn f() -> Self::I; +} + +impl X for () { +// { dg-error ".E0207." "" { target *-*-* } .-1 } + type I = impl Sized; + fn f() -> Self::I {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs new file mode 100644 index 000000000000..f9d0301f2f25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs @@ -0,0 +1,17 @@ +// Regression test for issue 67856 + +#![feature(unboxed_closures)] +#![feature(type_alias_impl_trait)] +#![feature(fn_traits)] + +trait MyTrait {} +impl MyTrait for () {} + +impl FnOnce<()> for &F { +// { dg-error ".E0210." "" { target *-*-* } .-1 } +// { dg-error ".E0210." "" { target *-*-* } .-2 } + type Output = impl MyTrait; + extern "rust-call" fn call_once(self, _: ()) -> Self::Output {} +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs new file mode 100644 index 000000000000..54ab319896c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-52843-closure-constrain.rs @@ -0,0 +1,14 @@ +// Checks to ensure that we properly detect when a closure constrains an opaque type + +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() { + type Opaque = impl Debug; + fn _unused() -> Opaque { String::new() } + let null = || -> Opaque { 0 }; +// { dg-error "" "" { target *-*-* } .-1 } + println!("{:?}", null()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-52843.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-52843.rs new file mode 100644 index 000000000000..a348f7fcf07c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-52843.rs @@ -0,0 +1,16 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl Default; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +#[allow(unused)] +fn foo(t: T) -> Foo { + t +} + +struct NotDefault; + +fn main() { + let _ = Foo::::default(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-53096.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-53096.rs new file mode 100644 index 000000000000..b324b0de4be8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-53096.rs @@ -0,0 +1,10 @@ +// check-pass +#![feature(const_impl_trait, const_fn_fn_ptr_basics)] +#![feature(type_alias_impl_trait)] + +type Foo = impl Fn() -> usize; +const fn bar() -> Foo { || 0usize } +const BAZR: Foo = bar(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-53598.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-53598.rs new file mode 100644 index 000000000000..b5ba960680b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-53598.rs @@ -0,0 +1,30 @@ +// ignore-tidy-linelength +// ignore-compare-mode-chalk +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +pub trait Foo { + type Item: Debug; + + fn foo(_: T) -> Self::Item; +} + +#[derive(Debug)] +pub struct S(std::marker::PhantomData); + +pub struct S2; + +impl Foo for S2 { + type Item = impl Debug; + + fn foo(_: T) -> Self::Item { +// { dg-error "" "" { target *-*-* } .-1 } + S::(Default::default()) + } +} + +fn main() { + S2::foo(123); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs new file mode 100644 index 000000000000..75b713c7eed1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-53678-generator-and-const-fn.rs @@ -0,0 +1,20 @@ +// check-pass + +#![feature(const_impl_trait, generators, generator_trait, type_alias_impl_trait)] + +use std::ops::Generator; + +type GenOnce = impl Generator; + +const fn const_generator(yielding: Y, returning: R) -> GenOnce { + move || { + yield yielding; + + return returning; + } +} + +const FOO: GenOnce = const_generator(10, 100); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs new file mode 100644 index 000000000000..f54e77439881 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs @@ -0,0 +1,29 @@ +// check-pass +// Regression test for issue #55099 +// Tests that we don't incorrectly consider a lifetime to part +// of the concrete type + +#![feature(type_alias_impl_trait)] + +trait Future { +} + +struct AndThen(F); + +impl Future for AndThen { +} + +struct Foo<'a> { + x: &'a mut (), +} + +type F = impl Future; + +impl<'a> Foo<'a> { + fn reply(&mut self) -> F { + AndThen(|| ()) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs new file mode 100644 index 000000000000..f1ac2ec1fbc0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57188-associate-impl-capture.rs @@ -0,0 +1,25 @@ +// Regression test for #57188 + +// check-pass + +#![feature(type_alias_impl_trait)] + +struct Baz<'a> { + source: &'a str, +} + +trait Foo<'a> { + type T: Iterator> + 'a; + fn foo(source: &'a str) -> Self::T; +} + +struct Bar; +impl<'a> Foo<'a> for Bar { + type T = impl Iterator> + 'a; + fn foo(source: &'a str) -> Self::T { + std::iter::once(Baz { source }) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57611-trait-alias.rs new file mode 100644 index 000000000000..55a15ffcaca1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57611-trait-alias.rs @@ -0,0 +1,32 @@ +// Regression test for issue #57611 +// Ensures that we don't ICE +// FIXME: This should compile, but it currently doesn't + +#![feature(trait_alias)] +#![feature(type_alias_impl_trait)] + +trait Foo { + type Bar: Baz; + + fn bar(&self) -> Self::Bar; +} + +struct X; + +impl Foo for X { + type Bar = impl Baz; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } + + fn bar(&self) -> Self::Bar { + |x| x + } +} + +trait Baz = Fn(&A) -> &B; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57700.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57700.rs new file mode 100644 index 000000000000..353716603d08 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57700.rs @@ -0,0 +1,24 @@ +// ignore-tidy-linelength +// ignore-compare-mode-chalk +#![feature(arbitrary_self_types)] +#![feature(type_alias_impl_trait)] + +use std::ops::Deref; + +trait Foo { + type Bar: Foo; + + fn foo(self: impl Deref) -> Self::Bar; +} + +impl Foo for C { + type Bar = impl Foo; + + fn foo(self: impl Deref) -> Self::Bar { +// { dg-error "" "" { target *-*-* } .-1 } + self + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57807-associated-type.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57807-associated-type.rs new file mode 100644 index 000000000000..2be8ffffb9ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-57807-associated-type.rs @@ -0,0 +1,32 @@ +// Regression test for issue #57807 - ensure +// that we properly unify associated types within +// a type alias impl trait +// check-pass +#![feature(type_alias_impl_trait)] + +trait Bar { + type A; +} + +impl Bar for () { + type A = (); +} + +trait Foo { + type A; + type B: Bar; + + fn foo() -> Self::B; +} + +impl Foo for () { + type A = (); + type B = impl Bar; + + fn foo() -> Self::B { + () + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-58887.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-58887.rs new file mode 100644 index 000000000000..f66b671d5b62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-58887.rs @@ -0,0 +1,23 @@ +// run-pass + +#![feature(type_alias_impl_trait)] + +trait UnwrapItemsExt { + type Iter; + fn unwrap_items(self) -> Self::Iter; +} + +impl UnwrapItemsExt for I +where + I: Iterator>, + E: std::fmt::Debug, +{ + type Iter = impl Iterator; + + fn unwrap_items(self) -> Self::Iter { + self.map(|x| x.unwrap()) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-58951.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-58951.rs new file mode 100644 index 000000000000..4fe64a2f998a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-58951.rs @@ -0,0 +1,14 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +type A = impl Iterator; + +fn def_a() -> A { 0..1 } + +pub fn use_a() { + def_a().map(|x| x); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-60371.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-60371.rs new file mode 100644 index 000000000000..66c0e30b89ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-60371.rs @@ -0,0 +1,18 @@ +// ignore-compare-mode-chalk + +trait Bug { + type Item: Bug; + + const FUN: fn() -> Self::Item; +} + +impl Bug for &() { + type Item = impl Bug; // { dg-error ".E0277." "" { target *-*-* } } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } + + const FUN: fn() -> Self::Item = || (); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-60407.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-60407.rs new file mode 100644 index 000000000000..5ed91f2034b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-60407.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +type Debuggable = impl core::fmt::Debug; + +static mut TEST: Option = None; + +fn main() { + unsafe { TEST = Some(foo()) } +} + +fn foo() -> Debuggable { + 0u32 +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-60564.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-60564.rs new file mode 100644 index 000000000000..35c726395aeb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-60564.rs @@ -0,0 +1,26 @@ +#![feature(type_alias_impl_trait)] + +trait IterBits { + type BitsIter: Iterator; + fn iter_bits(self, n: u8) -> Self::BitsIter; +} + +type IterBitsIter = impl std::iter::Iterator; + +impl IterBits for T +where + T: std::ops::Shr + + std::ops::BitAnd + + std::convert::From + + std::convert::TryInto, + E: std::fmt::Debug, +{ + type BitsIter = IterBitsIter; + fn iter_bits(self, n: u8) -> Self::BitsIter { +// { dg-error "" "" { target *-*-* } .-1 } + (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs new file mode 100644 index 000000000000..77ebc181f8bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-62000-associate-impl-trait-lifetimes.rs @@ -0,0 +1,39 @@ +// Regression test for #62988 + +// check-pass + +#![feature(type_alias_impl_trait)] + +trait MyTrait { + type AssocType: Send; + fn ret(&self) -> Self::AssocType; +} + +impl MyTrait for () { + type AssocType = impl Send; + fn ret(&self) -> Self::AssocType { + () + } +} + +impl<'a> MyTrait for &'a () { + type AssocType = impl Send; + fn ret(&self) -> Self::AssocType { + () + } +} + +trait MyLifetimeTrait<'a> { + type AssocType: Send + 'a; + fn ret(&self) -> Self::AssocType; +} + +impl<'a> MyLifetimeTrait<'a> for &'a () { + type AssocType = impl Send + 'a; + fn ret(&self) -> Self::AssocType { + *self + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-63263-closure-return.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-63263-closure-return.rs new file mode 100644 index 000000000000..e2765b1e4031 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-63263-closure-return.rs @@ -0,0 +1,14 @@ +// Regression test for issue #63263. +// Tests that we properly handle closures with an explicit return type +// that return an opaque type. + +// check-pass + +#![feature(type_alias_impl_trait)] + +pub type Closure = impl FnOnce(); + +fn main() { + || -> Closure { || () }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-63279.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-63279.rs new file mode 100644 index 000000000000..ac9febbac7bb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-63279.rs @@ -0,0 +1,12 @@ +// compile-flags: -Zsave-analysis + +#![feature(type_alias_impl_trait)] + +type Closure = impl FnOnce(); // { dg-error ".E0271." "" { target *-*-* } } + +fn c() -> Closure { + || -> Closure { || () } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs new file mode 100644 index 000000000000..449bacbdd23d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-63677-type-alias-coherence.rs @@ -0,0 +1,22 @@ +// check-pass +// Regression test for issue #63677 - ensure that +// coherence checking can properly handle 'impl trait' +// in type aliases +#![feature(type_alias_impl_trait)] + +pub trait Trait {} +pub struct S1(T); +pub struct S2(T); + +pub type T1 = impl Trait; +pub type T2 = S1; +pub type T3 = S2; + +impl Trait for S1 {} +impl S2 {} +impl T3 {} + +pub fn use_t1() -> T1 { S1(()) } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs new file mode 100644 index 000000000000..b5a908278528 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs @@ -0,0 +1,19 @@ +// compile-flags: -Zsave-analysis +// check-pass + +#![feature(type_alias_impl_trait)] + +type T = impl Sized; +// The concrete type referred by impl-trait-type-alias(`T`) is guaranteed +// to be the same as where it occurs, whereas `impl Trait`'s instance is location sensitive; +// so difference assertion should not be declared on impl-trait-type-alias's instances. +// for details, check RFC-2515: +// https://github.com/rust-lang/rfcs/blob/master/text/2515-type_alias_impl_trait.md + +fn take(_: fn() -> T) {} + +fn main() { + take(|| {}); + take(|| {}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-65918.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-65918.rs new file mode 100644 index 000000000000..d925f63143e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-65918.rs @@ -0,0 +1,52 @@ +// ignore-test: This now ICEs again. + +// build-pass + +#![feature(type_alias_impl_trait)] + +use std::marker::PhantomData; + +/* copied Index and TryFrom for convenience (and simplicity) */ +trait MyIndex { + type O; + fn my_index(self) -> Self::O; +} +trait MyFrom: Sized { + type Error; + fn my_from(value: T) -> Result; +} + +/* MCVE starts here */ +trait F {} +impl F for () {} +type DummyT = impl F; +fn _dummy_t() -> DummyT {} + +struct Phantom1(PhantomData); +struct Phantom2(PhantomData); +struct Scope(Phantom2>); + +impl Scope { + fn new() -> Self { + unimplemented!() + } +} + +impl MyFrom> for Phantom1 { + type Error = (); + fn my_from(_: Phantom2) -> Result { + unimplemented!() + } +} + +impl>>, U> MyIndex> for Scope { + type O = T; + fn my_index(self) -> Self::O { + MyFrom::my_from(self.0).ok().unwrap() + } +} + +fn main() { + let _pos: Phantom1> = Scope::new().my_index(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs new file mode 100644 index 000000000000..f8f9e478e44a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-66580-closure-coherence.rs @@ -0,0 +1,20 @@ +// Regression test for issue #66580 +// Ensures that we don't try to determine whether a closure +// is foreign when it's the underlying type of an opaque type +// check-pass +#![feature(type_alias_impl_trait)] + +type Closure = impl FnOnce(); + +fn closure() -> Closure { + || {} +} + +struct Wrap { f: T } + +impl Wrap {} + +impl Wrap {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs new file mode 100644 index 000000000000..bbbf27222172 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-67844-nested-opaque.rs @@ -0,0 +1,33 @@ +// check-pass +// Regression test for issue #67844 +// Ensures that we properly handle nested TAIT occurrences +// with generic parameters + +#![feature(type_alias_impl_trait)] + +trait WithAssoc { type AssocType; } + +trait WithParam {} + +type Return = impl WithAssoc>; + +struct MyParam; +impl WithParam for MyParam {} + +struct MyStruct; + +impl WithAssoc for MyStruct { + type AssocType = MyParam; +} + + +fn my_fun() -> Return { + MyStruct +} + +fn my_other_fn() -> impl WithAssoc> { + MyStruct +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs new file mode 100644 index 000000000000..4dc958201e25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-68368-non-defining-use.rs @@ -0,0 +1,14 @@ +// Regression test for issue #68368 +// Ensures that we don't ICE when emitting an error +// for a non-defining use when lifetimes are involved + +#![feature(type_alias_impl_trait)] +trait Trait {} +type Alias<'a, U> = impl Trait; +fn f<'a>() -> Alias<'a, ()> {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + +impl Trait<()> for () {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs new file mode 100644 index 000000000000..8af8df76b2f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-error.rs @@ -0,0 +1,23 @@ +// Regression test for #69136 + +#![feature(type_alias_impl_trait)] + +trait SomeTrait {} + +impl SomeTrait for () {} + +trait WithAssoc { + type AssocType; +} + +impl WithAssoc for () { + type AssocType = (); +} + +type Return = impl WithAssoc; +// { dg-error ".E0261." "" { target *-*-* } .-1 } + +fn my_fun() -> Return<()> {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs new file mode 100644 index 000000000000..f078bd54423b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-69136-inner-lifetime-resolve-ok.rs @@ -0,0 +1,24 @@ +// Test-pass variant of #69136 + +// check-pass + +#![feature(type_alias_impl_trait)] + +trait SomeTrait {} + +impl SomeTrait for () {} + +trait WithAssoc { + type AssocType; +} + +impl WithAssoc for () { + type AssocType = (); +} + +type Return<'a> = impl WithAssoc; + +fn my_fun<'a>() -> Return<'a> {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-70121.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-70121.rs new file mode 100644 index 000000000000..c8c53fa3b945 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-70121.rs @@ -0,0 +1,24 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +pub type Successors<'a> = impl Iterator; + +pub fn f<'a>() -> Successors<'a> { + None.into_iter() +} + +pub trait Tr { + type Item; +} + +impl<'a> Tr for &'a () { + type Item = Successors<'a>; +} + +pub fn kazusa<'a>() -> <&'a () as Tr>::Item { + None.into_iter() +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-74244.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-74244.rs new file mode 100644 index 000000000000..8857431a62d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-74244.rs @@ -0,0 +1,21 @@ +#![feature(type_alias_impl_trait)] + +trait Allocator { + type Buffer; +} + +struct DefaultAllocator; + +impl Allocator for DefaultAllocator { +// { dg-error ".E0207." "" { target *-*-* } .-1 } + type Buffer = (); +} + +type A = impl Fn(::Buffer); + +fn foo() -> A { + |_| () +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-74761.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-74761.rs new file mode 100644 index 000000000000..21ee2446315a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-74761.rs @@ -0,0 +1,17 @@ +#![feature(member_constraints)] +#![feature(type_alias_impl_trait)] + +pub trait A { + type B; + fn f(&self) -> Self::B; +} +impl<'a, 'b> A for () { +// { dg-error ".E0207." "" { target *-*-* } .-1 } +// { dg-error ".E0207." "" { target *-*-* } .-2 } + type B = impl core::fmt::Debug; + + fn f(&self) -> Self::B {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs new file mode 100644 index 000000000000..88054686221b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs @@ -0,0 +1,24 @@ +// Regression test for issue #76202 +// Tests that we don't ICE when we have a trait impl on a TAIT. + +#![feature(type_alias_impl_trait)] + +trait Dummy {} +impl Dummy for () {} + +type F = impl Dummy; +fn f() -> F {} + +trait Test { + fn test(self); +} + +impl Test for F { // { dg-error "" "" { target *-*-* } } + fn test(self) {} +} + +fn main() { + let x: F = f(); + x.test(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs new file mode 100644 index 000000000000..ed5365a7a335 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs @@ -0,0 +1,21 @@ +#![feature(type_alias_impl_trait)] +// build-pass (FIXME(62277): could be check-pass?) +mod my_mod { + use std::fmt::Debug; + + pub type Foo = impl Debug; + pub type Foot = impl Debug; + + pub fn get_foo() -> Foo { + 5i32 + } + + pub fn get_foot() -> Foot { + get_foo() + } +} + +fn main() { + let _: my_mod::Foot = my_mod::get_foot(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/never_reveal_concrete_type.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/never_reveal_concrete_type.rs new file mode 100644 index 000000000000..d351c17b6c91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/never_reveal_concrete_type.rs @@ -0,0 +1,16 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +// don't reveal the concrete type +type NoReveal = impl std::fmt::Debug; + +fn define_no_reveal() -> NoReveal { + "" +} + +fn no_reveal(x: NoReveal) { + let _: &'static str = x; // { dg-error ".E0308." "" { target *-*-* } } + let _ = x as &'static str; // { dg-error ".E0605." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs new file mode 100644 index 000000000000..90aa97abfc86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs @@ -0,0 +1,14 @@ +// Issue 52985: user code provides no use case that allows a type alias `impl Trait` +// We now emit a 'could not find defining uses' error + +#![feature(type_alias_impl_trait)] + +type Foo = impl Copy; // { dg-error "" "" { target *-*-* } } + +// make compiler happy about using 'Foo' +fn bar(x: Foo) -> Foo { x } + +fn main() { + let _: Foo = std::mem::transmute(0u8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs new file mode 100644 index 000000000000..9b2dbe6ab27f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/no_revealing_outside_defining_module.rs @@ -0,0 +1,25 @@ +#![feature(type_alias_impl_trait)] + +fn main() {} + +mod boo { + pub type Boo = impl ::std::fmt::Debug; + fn bomp() -> Boo { + "" + } +} + +// We don't actually know the type here. + +fn bomp2() { + let _: &str = bomp(); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn bomp() -> boo::Boo { + "" // { dg-error ".E0308." "" { target *-*-* } } +} + +fn bomp_loop() -> boo::Boo { + loop {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/not_a_defining_use.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/not_a_defining_use.rs new file mode 100644 index 000000000000..a2ab58550b34 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/not_a_defining_use.rs @@ -0,0 +1,39 @@ +#![feature(type_alias_impl_trait)] + +use std::fmt::Debug; + +fn main() {} + +type Two = impl Debug; + +fn two(t: T) -> Two { +// { dg-error "" "" { target *-*-* } .-1 } + (t, 4i8) +} + +fn three(t: T) -> Two { + (t, 5i8) +} + +trait Bar { + type Blub: Debug; + const FOO: Self::Blub; +} + +impl Bar for u32 { + type Blub = i32; + const FOO: i32 = 42; +} + +fn four(t: T) -> Two { + (t, ::FOO) +} + +fn is_sync() {} + +fn asdfl() { + //FIXME(oli-obk): these currently cause cycle errors + //is_sync::>(); + //is_sync::>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/not_well_formed.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/not_well_formed.rs new file mode 100644 index 000000000000..2d9cb7f13a7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/not_well_formed.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] + +fn main() { +} + +trait TraitWithAssoc { + type Assoc; +} + +type Foo = impl Trait; // { dg-error ".E0220." "" { target *-*-* } } + +trait Trait {} + +impl Trait for () {} + +fn foo_desugared(_: T) -> Foo { + () +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/private_unused.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/private_unused.rs new file mode 100644 index 000000000000..526557b66e0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/private_unused.rs @@ -0,0 +1,14 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#[deny(warnings)] + +enum Empty { } +trait Bar {} +impl Bar for () {} + +fn boo() -> impl Bar {} + +fn main() { + boo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/structural-match-no-leak.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/structural-match-no-leak.rs new file mode 100644 index 000000000000..deda2b13979c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/structural-match-no-leak.rs @@ -0,0 +1,21 @@ +#![feature(const_impl_trait, type_alias_impl_trait)] + +type Bar = impl Send; + +// While i32 is structural-match, we do not want to leak this information. +// (See https://github.com/rust-lang/rust/issues/72156) +const fn leak_free() -> Bar { + 7i32 +} +const LEAK_FREE: Bar = leak_free(); + +fn leak_free_test() { + match todo!() { + LEAK_FREE => (), +// { dg-error "" "" { target *-*-* } .-1 } + _ => (), + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/structural-match.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/structural-match.rs new file mode 100644 index 000000000000..0f0a9663c2fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/structural-match.rs @@ -0,0 +1,22 @@ +#![feature(const_impl_trait, type_alias_impl_trait)] + +type Foo = impl Send; + +// This is not structural-match +struct A; + +const fn value() -> Foo { + A +} +const VALUE: Foo = value(); + +fn test() { + match todo!() { + VALUE => (), +// { dg-error "" "" { target *-*-* } .-1 } + _ => (), + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs new file mode 100644 index 000000000000..10c10f99175c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-const.rs @@ -0,0 +1,21 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +// Currently, the `type_alias_impl_trait` feature implicitly +// depends on `impl_trait_in_bindings` in order to work properly. +// Specifically, this line requires `impl_trait_in_bindings` to be enabled: +// https://github.com/rust-lang/rust/blob/481068a707679257e2a738b40987246e0420e787/compiler/rustc_typeck/check/mod.rs#L856 +#![feature(impl_trait_in_bindings)] +// { dg-warning "" "" { target *-*-* } .-1 } + +// Ensures that `const` items can constrain an opaque `impl Trait`. + +use std::fmt::Debug; + +pub type Foo = impl Debug; + +const _FOO: Foo = 5; + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs new file mode 100644 index 000000000000..01f9504a94b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-fns.rs @@ -0,0 +1,28 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +// Regression test for issue #61863 + +pub trait MyTrait {} + +#[derive(Debug)] +pub struct MyStruct { + v: u64 +} + +impl MyTrait for MyStruct {} + +pub fn bla() -> TE { + return MyStruct {v:1} +} + +pub fn bla2() -> TE { + bla() +} + + +type TE = impl MyTrait; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs new file mode 100644 index 000000000000..6323cec2eb99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +type A = impl Sized; +fn f1() -> A { 0 } + +type B = impl ?Sized; +fn f2() -> &'static B { &[0] } + +type C = impl ?Sized + 'static; +fn f3() -> &'static C { &[0] } + +type D = impl ?Sized; +fn f4() -> &'static D { &1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs new file mode 100644 index 000000000000..988d3d599223 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs @@ -0,0 +1,34 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +pub trait MyTrait {} + +impl MyTrait for bool {} + +struct Blah { + my_foo: Foo, + my_u8: u8 +} + +impl Blah { + fn new() -> Blah { + Blah { + my_foo: make_foo(), + my_u8: 12 + } + } + fn into_inner(self) -> (Foo, u8) { + (self.my_foo, self.my_u8) + } +} + +fn make_foo() -> Foo { + true +} + +type Foo = impl MyTrait; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs new file mode 100644 index 000000000000..c6178a0eee78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs @@ -0,0 +1,19 @@ +// regression test for #74018 + +#![feature(type_alias_impl_trait)] + +trait Trait { + type Associated; + fn into(self) -> Self::Associated; +} + +impl<'a, I: Iterator> Trait for (i32, I) { +// { dg-error ".E0207." "" { target *-*-* } .-1 } + type Associated = (i32, impl Iterator); + fn into(self) -> Self::Associated { + (0_i32, [0_i32].iter().copied()) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs new file mode 100644 index 000000000000..ed8ac0cae1bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error.rs @@ -0,0 +1,13 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl Fn() -> Foo; +// { dg-error "" "" { target *-*-* } .-1 } + +fn crash(x: Foo) -> Foo { + x +} + +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs new file mode 100644 index 000000000000..a0dc1f425cb6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-cycle-error2.rs @@ -0,0 +1,17 @@ +#![feature(type_alias_impl_trait)] + +pub trait Bar { + type Item; +} + +type Foo = impl Bar; +// { dg-error "" "" { target *-*-* } .-1 } + +fn crash(x: Foo) -> Foo { + x +} + +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs new file mode 100644 index 000000000000..e6e751c50ef9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait-with-no-traits.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl 'static; +// { dg-error "" "" { target *-*-* } .-1 } + +fn foo() -> Foo { + "foo" +} + +fn bar() -> impl 'static { // { dg-error "" "" { target *-*-* } } + "foo" +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait.rs new file mode 100644 index 000000000000..c0d84dfd899e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-impl-trait.rs @@ -0,0 +1,90 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_assignments)] +#![allow(unused_variables)] +#![feature(type_alias_impl_trait)] + +fn main() { + assert_eq!(foo().to_string(), "foo"); + assert_eq!(bar1().to_string(), "bar1"); + assert_eq!(bar2().to_string(), "bar2"); + let mut x = bar1(); + x = bar2(); + assert_eq!(boo::boo().to_string(), "boo"); + assert_eq!(my_iter(42u8).collect::>(), vec![42u8]); +} + +// single definition +type Foo = impl std::fmt::Display; + +fn foo() -> Foo { + "foo" +} + +// two definitions +type Bar = impl std::fmt::Display; + +fn bar1() -> Bar { + "bar1" +} + +fn bar2() -> Bar { + "bar2" +} + +// definition in submodule +type Boo = impl std::fmt::Display; + +mod boo { + pub fn boo() -> super::Boo { + "boo" + } +} + +type MyIter = impl Iterator; + +fn my_iter(t: T) -> MyIter { + std::iter::once(t) +} + +fn my_iter2(t: T) -> MyIter { + std::iter::once(t) +} + +// param names should not have an effect! +fn my_iter3(u: U) -> MyIter { + std::iter::once(u) +} + +// param position should not have an effect! +fn my_iter4(_: U, v: V) -> MyIter { + std::iter::once(v) +} + +// param names should not have an effect! +type MyOtherIter = impl Iterator; + +fn my_other_iter(u: U) -> MyOtherIter { + std::iter::once(u) +} + +trait Trait {} +type GenericBound<'a, T: Trait + 'a> = impl Sized + 'a; + +fn generic_bound<'a, T: Trait + 'a>(t: T) -> GenericBound<'a, T> { + t +} + +mod pass_through { + pub type Passthrough = impl Sized + 'static; + + fn define_passthrough(t: T) -> Passthrough { + t + } +} + +fn use_passthrough(x: pass_through::Passthrough) -> pass_through::Passthrough { + x +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs new file mode 100644 index 000000000000..4d160c077a4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/type-alias-nested-impl-trait.rs @@ -0,0 +1,15 @@ +// run-pass + +#![feature(type_alias_impl_trait)] + +use std::iter::{once, Chain}; + +type I = Chain>; +fn test2>(x: A) -> I { + x.chain(once("5")) +} + +fn main() { + assert_eq!(vec!["1", "3", "5"], test2(["1", "3"].iter().cloned()).collect::>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/unused_generic_param.rs b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/unused_generic_param.rs new file mode 100644 index 000000000000..d947250be23a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias-impl-trait/unused_generic_param.rs @@ -0,0 +1,23 @@ +#![feature(type_alias_impl_trait)] + +fn main() { +} + +type PartiallyDefined = impl 'static; +// { dg-error "" "" { target *-*-* } .-1 } + +fn partially_defined(_: T) -> PartiallyDefined { + 4u32 +} + +type PartiallyDefined2 = impl 'static; +// { dg-error "" "" { target *-*-* } .-1 } + +fn partially_defined2(_: T) -> PartiallyDefined2 { + 4u32 +} + +fn partially_defined22(_: T) -> PartiallyDefined2 { + 4u32 +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias/issue-62263-self-in-atb.rs b/gcc/testsuite/rust/rustc/ui/type-alias/issue-62263-self-in-atb.rs new file mode 100644 index 000000000000..8d540e96d6ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias/issue-62263-self-in-atb.rs @@ -0,0 +1,9 @@ +pub trait Trait { + type A; +} + +pub type Alias = dyn Trait; +// { dg-error ".E0433." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias/issue-62305-self-assoc-ty.rs b/gcc/testsuite/rust/rustc/ui/type-alias/issue-62305-self-assoc-ty.rs new file mode 100644 index 000000000000..1e9e233ed75b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias/issue-62305-self-assoc-ty.rs @@ -0,0 +1,5 @@ +type Alias = Self::Target; +// { dg-error ".E0433." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-alias/issue-62364-self-ty-arg.rs b/gcc/testsuite/rust/rustc/ui/type-alias/issue-62364-self-ty-arg.rs new file mode 100644 index 000000000000..165957e651c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-alias/issue-62364-self-ty-arg.rs @@ -0,0 +1,9 @@ +struct Struct { + field: P1, +} + +type Alias<'a> = Struct<&'a Self>; +// { dg-error ".E0411." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type-ascription.rs b/gcc/testsuite/rust/rustc/ui/type-ascription.rs new file mode 100644 index 000000000000..fad6aa1088cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-ascription.rs @@ -0,0 +1,40 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_variables)] +// Type ascription doesn't lead to unsoundness + +#![feature(type_ascription)] + +use std::mem; + +const C1: u8 = 10: u8; +const C2: [u8; 1: usize] = [1]; + +struct S { + a: u8 +} + +fn main() { + assert_eq!(C1.into(): i32, 10); + assert_eq!(C2[0], 1); + + let s = S { a: 10: u8 }; + let arr = &[1u8, 2, 3]; + + let mut v = arr.iter().cloned().collect(): Vec<_>; + v.push(4); + assert_eq!(v, [1, 2, 3, 4]); + + let a = 1: u8; + let b = a.into(): u16; + assert_eq!(v[a.into(): usize], 2); + assert_eq!(mem::size_of_val(&a), 1); + assert_eq!(mem::size_of_val(&b), 2); + assert_eq!(b, 1: u16); + + let mut v = Vec::new(); + v: Vec = vec![1, 2, 3]; // Place expression type ascription + assert_eq!(v, [1u8, 2, 3]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-id-higher-rank-2.rs b/gcc/testsuite/rust/rustc/ui/type-id-higher-rank-2.rs new file mode 100644 index 000000000000..4e7f99019922 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-id-higher-rank-2.rs @@ -0,0 +1,32 @@ +// run-pass +// Test that we can't ignore lifetimes by going through Any. + +use std::any::Any; + +struct Foo<'a>(&'a str); + +fn good(s: &String) -> Foo { Foo(s) } + +fn bad1(s: String) -> Option<&'static str> { + let a: Box = Box::new(good as fn(&String) -> Foo); + a.downcast_ref:: Foo<'static>>().map(|f| f(&s).0) +} + +trait AsStr<'a, 'b> { + fn get(&'a self) -> &'b str; +} + +impl<'a> AsStr<'a, 'a> for String { + fn get(&'a self) -> &'a str { self } +} + +fn bad2(s: String) -> Option<&'static str> { + let a: Box = Box::new(Box::new(s) as Box AsStr<'a, 'a>>); + a.downcast_ref:: AsStr<'a, 'static>>>().map(|x| x.get()) +} + +fn main() { + assert_eq!(bad1(String::from("foo")), None); + assert_eq!(bad2(String::from("bar")), None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-id-higher-rank.rs b/gcc/testsuite/rust/rustc/ui/type-id-higher-rank.rs new file mode 100644 index 000000000000..83ff874aa68e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-id-higher-rank.rs @@ -0,0 +1,73 @@ +// run-pass +// Test that type IDs correctly account for higher-rank lifetimes +// Also acts as a regression test for an ICE (issue #19791) + +use std::any::{Any, TypeId}; + +struct Struct<'a>(&'a ()); +trait Trait<'a> {} + +fn main() { + // Bare fns + { + let a = TypeId::of::(); + let b = TypeId::of:: fn(&'static isize, &'a isize)>(); + let c = TypeId::of:: fn(&'a isize, &'b isize)>(); + let d = TypeId::of:: fn(&'b isize, &'a isize)>(); + assert!(a != b); + assert!(a != c); + assert!(a != d); + assert!(b != c); + assert!(b != d); + assert_eq!(c, d); + + // Make sure De Bruijn indices are handled correctly + let e = TypeId::of:: fn(fn(&'a isize) -> &'a isize)>(); + let f = TypeId::of:: fn(&'a isize) -> &'a isize)>(); + assert!(e != f); + + // Make sure lifetime parameters of items are not ignored. + let g = TypeId::of:: fn(&'a dyn Trait<'a>) -> Struct<'a>>(); + let h = TypeId::of:: fn(&'a dyn Trait<'a>) -> Struct<'static>>(); + let i = TypeId::of:: fn(&'a dyn Trait<'b>) -> Struct<'b>>(); + assert!(g != h); + assert!(g != i); + assert!(h != i); + + // Make sure lifetime anonymization handles nesting correctly + let j = TypeId::of:: fn(&'a isize) -> &'a usize)>(); + let k = TypeId::of:: fn(&'b isize) -> &'b usize)>(); + assert_eq!(j, k); + } + // Boxed unboxed closures + { + let a = TypeId::of::>(); + let b = TypeId::of:: Fn(&'static isize, &'a isize)>>(); + let c = TypeId::of:: Fn(&'a isize, &'b isize)>>(); + let d = TypeId::of:: Fn(&'b isize, &'a isize)>>(); + assert!(a != b); + assert!(a != c); + assert!(a != d); + assert!(b != c); + assert!(b != d); + assert_eq!(c, d); + + // Make sure De Bruijn indices are handled correctly + let e = TypeId::of:: Fn(Box &'a isize>)>>(); + let f = TypeId::of:: Fn(&'a isize) -> &'a isize>)>>(); + assert!(e != f); + } + // Raw unboxed closures + // Note that every unboxed closure has its own anonymous type, + // so no two IDs should equal each other, even when compatible + { + let a = id(|_: &isize, _: &isize| {}); + let b = id(|_: &isize, _: &isize| {}); + assert!(a != b); + } + + fn id(_: T) -> TypeId { + TypeId::of::() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-in-nested-module.rs b/gcc/testsuite/rust/rustc/ui/type-in-nested-module.rs new file mode 100644 index 000000000000..a0f9bf1f45f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-in-nested-module.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] + + +// pretty-expanded FIXME #23616 + +mod a { + pub mod b { + pub type t = isize; + + pub fn foo() { let _x: t = 10; } + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/type-infer-generalize-ty-var.rs b/gcc/testsuite/rust/rustc/ui/type-infer-generalize-ty-var.rs new file mode 100644 index 000000000000..b6c563fb158b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-infer-generalize-ty-var.rs @@ -0,0 +1,57 @@ +// run-pass + +#![allow(non_upper_case_globals)] +#![allow(dead_code)] +#![allow(unused_assignments)] +#![allow(unused_variables)] +// Test a scenario where we generate a constraint like `?1 <: &?2`. +// In such a case, it is important that we instantiate `?1` with `&?3` +// where `?3 <: ?2`, and not with `&?2`. This is a regression test for +// #18653. The important thing is that we build. + +use std::cell::RefCell; + +enum Wrap { + WrapSome(A), + WrapNone +} + +use Wrap::*; + +struct T; +struct U; + +trait Get { + fn get(&self) -> &T; +} + +impl Get for Wrap { + fn get(&self) -> &(dyn MyShow + 'static) { + static x: usize = 42; + &x + } +} + +impl Get for Wrap { + fn get(&self) -> &usize { + static x: usize = 55; + &x + } +} + +trait MyShow { fn dummy(&self) { } } +impl<'a> MyShow for &'a (dyn MyShow + 'a) { } +impl MyShow for usize { } +fn constrain<'a>(rc: RefCell<&'a (dyn MyShow + 'a)>) { } + +fn main() { + let mut collection: Wrap<_> = WrapNone; + + { + let __arg0 = Get::get(&collection); + let __args_cell = RefCell::new(__arg0); + constrain(__args_cell); + } + collection = WrapSome(T); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-inference/or_else-multiple-type-params.rs b/gcc/testsuite/rust/rustc/ui/type-inference/or_else-multiple-type-params.rs new file mode 100644 index 000000000000..af34b4af0abf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-inference/or_else-multiple-type-params.rs @@ -0,0 +1,11 @@ +use std::process::{Command, Stdio}; + +fn main() { + let process = Command::new("wc") + .stdout(Stdio::piped()) + .spawn() + .or_else(|err| { // { dg-error ".E0282." "" { target *-*-* } } + panic!("oh no: {:?}", err); + }).unwrap(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-inference/sort_by_key.rs b/gcc/testsuite/rust/rustc/ui/type-inference/sort_by_key.rs new file mode 100644 index 000000000000..f1f03e73ffb7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-inference/sort_by_key.rs @@ -0,0 +1,6 @@ +fn main() { + let mut lst: [([i32; 10], bool); 10] = [([0; 10], false); 10]; + lst.sort_by_key(|&(v, _)| v.iter().sum()); // { dg-error ".E0282." "" { target *-*-* } } + println!("{:?}", lst); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-inference/unbounded-associated-type.rs b/gcc/testsuite/rust/rustc/ui/type-inference/unbounded-associated-type.rs new file mode 100644 index 000000000000..f92827a27139 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-inference/unbounded-associated-type.rs @@ -0,0 +1,17 @@ +trait T { + type A; + fn foo(&self) -> Self::A { + panic!() + } +} + +struct S(std::marker::PhantomData); + +impl T for S { + type A = X; +} + +fn main() { + S(std::marker::PhantomData).foo(); // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.rs b/gcc/testsuite/rust/rustc/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.rs new file mode 100644 index 000000000000..6ac396322674 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-inference/unbounded-type-param-in-fn-with-assoc-type.rs @@ -0,0 +1,10 @@ +#[allow(invalid_type_param_default)] + +fn foo() -> (T, U) { + panic!() +} + +fn main() { + foo(); // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-inference/unbounded-type-param-in-fn.rs b/gcc/testsuite/rust/rustc/ui/type-inference/unbounded-type-param-in-fn.rs new file mode 100644 index 000000000000..495242bdf865 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-inference/unbounded-type-param-in-fn.rs @@ -0,0 +1,8 @@ +fn foo() -> T { + panic!() +} + +fn main() { + foo(); // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-namespace.rs b/gcc/testsuite/rust/rustc/ui/type-namespace.rs new file mode 100644 index 000000000000..ab6f80538287 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-namespace.rs @@ -0,0 +1,8 @@ +// run-pass + +struct A { a: isize } + +fn a(a: A) -> isize { return a.a; } + +pub fn main() { let x: A = A {a: 1}; assert_eq!(a(x), 1); } + diff --git a/gcc/testsuite/rust/rustc/ui/type-param-constraints.rs b/gcc/testsuite/rust/rustc/ui/type-param-constraints.rs new file mode 100644 index 000000000000..8ce461fca2c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-param-constraints.rs @@ -0,0 +1,40 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +fn p_foo(_pinned: T) { } +fn s_foo(_shared: T) { } +fn u_foo(_unique: T) { } + +struct r { + i: isize, +} + +impl Drop for r { + fn drop(&mut self) {} +} + +fn r(i:isize) -> r { + r { + i: i + } +} + +pub fn main() { + p_foo(r(10)); + + p_foo::>(box r(10)); + p_foo::>(box 10); + p_foo(10); + + s_foo::>(box 10); + s_foo(10); + + u_foo::>(box 10); + u_foo(10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-param.rs b/gcc/testsuite/rust/rustc/ui/type-param.rs new file mode 100644 index 000000000000..835350a1614a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-param.rs @@ -0,0 +1,12 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] + + +// pretty-expanded FIXME #23616 + +type lteq = extern fn(T) -> bool; + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/type-params-in-for-each.rs b/gcc/testsuite/rust/rustc/ui/type-params-in-for-each.rs new file mode 100644 index 000000000000..b9f94ddbace2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-params-in-for-each.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(dead_code)] + +// pretty-expanded FIXME #23616 + +struct S { + a: T, + b: usize, +} + +fn range_(lo: usize, hi: usize, mut it: F) where F: FnMut(usize) { + let mut lo_ = lo; + while lo_ < hi { it(lo_); lo_ += 1; } +} + +fn create_index(_index: Vec> , _hash_fn: extern fn(T) -> usize) { + range_(0, 256, |_i| { + let _bucket: Vec = Vec::new(); + }) +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/type-ptr.rs b/gcc/testsuite/rust/rustc/ui/type-ptr.rs new file mode 100644 index 000000000000..9e23473b3ad9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-ptr.rs @@ -0,0 +1,11 @@ +// run-pass + +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +fn f(a: *const isize) -> *const isize { return a; } + +fn g(a: *const isize) -> *const isize { let b = f(a); return b; } + +pub fn main() { return; } + diff --git a/gcc/testsuite/rust/rustc/ui/type-sizes.rs b/gcc/testsuite/rust/rustc/ui/type-sizes.rs new file mode 100644 index 000000000000..9dcc243f02cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-sizes.rs @@ -0,0 +1,174 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +#![feature(never_type)] + +use std::mem::size_of; +use std::num::NonZeroU8; + +struct t {a: u8, b: i8} +struct u {a: u8, b: i8, c: u8} +struct v {a: u8, b: i8, c: v2, d: u32} +struct v2 {u: char, v: u8} +struct w {a: isize, b: ()} +struct x {a: isize, b: (), c: ()} +struct y {x: isize} + +enum e1 { + a(u8, u32), b(u32), c +} +enum e2 { + a(u32), b +} + +#[repr(C, u8)] +enum e3 { + a([u16; 0], u8), b +} + +struct ReorderedStruct { + a: u8, + b: u16, + c: u8 +} + +enum ReorderedEnum { + A(u8, u16, u8), + B(u8, u16, u8), +} + +enum ReorderedEnum2 { + A(u8, u32, u8), + B(u16, u8, u16, u8), + + // 0x100 niche variants. + _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, _0A, _0B, _0C, _0D, _0E, _0F, + _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _1A, _1B, _1C, _1D, _1E, _1F, + _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _2A, _2B, _2C, _2D, _2E, _2F, + _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _3A, _3B, _3C, _3D, _3E, _3F, + _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _4A, _4B, _4C, _4D, _4E, _4F, + _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _5A, _5B, _5C, _5D, _5E, _5F, + _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _6A, _6B, _6C, _6D, _6E, _6F, + _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _7A, _7B, _7C, _7D, _7E, _7F, + _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _8A, _8B, _8C, _8D, _8E, _8F, + _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _9A, _9B, _9C, _9D, _9E, _9F, + _A0, _A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8, _A9, _AA, _AB, _AC, _AD, _AE, _AF, + _B0, _B1, _B2, _B3, _B4, _B5, _B6, _B7, _B8, _B9, _BA, _BB, _BC, _BD, _BE, _BF, + _C0, _C1, _C2, _C3, _C4, _C5, _C6, _C7, _C8, _C9, _CA, _CB, _CC, _CD, _CE, _CF, + _D0, _D1, _D2, _D3, _D4, _D5, _D6, _D7, _D8, _D9, _DA, _DB, _DC, _DD, _DE, _DF, + _E0, _E1, _E2, _E3, _E4, _E5, _E6, _E7, _E8, _E9, _EA, _EB, _EC, _ED, _EE, _EF, + _F0, _F1, _F2, _F3, _F4, _F5, _F6, _F7, _F8, _F9, _FA, _FB, _FC, _FD, _FE, _FF, +} + +enum EnumEmpty {} + +enum EnumSingle1 { + A, +} + +enum EnumSingle2 { + A = 42 as isize, +} + +enum EnumSingle3 { + A, + B(!), +} + +#[repr(u8)] +enum EnumSingle4 { + A, +} + +#[repr(u8)] +enum EnumSingle5 { + A = 42 as u8, +} + +enum EnumWithMaybeUninhabitedVariant { + A(&'static ()), + B(&'static (), T), + C, +} + +enum NicheFilledEnumWithAbsentVariant { + A(&'static ()), + B((), !), + C, +} + +enum Option2 { + Some(A, B), + None +} + +// Two layouts are considered for `CanBeNicheFilledButShouldnt`: +// Niche-filling: +// { u32 (4 bytes), NonZeroU8 + tag in niche (1 byte), padding (3 bytes) } +// Tagged: +// { tag (1 byte), NonZeroU8 (1 byte), padding (2 bytes), u32 (4 bytes) } +// Both are the same size (due to padding), +// but the tagged layout is better as the tag creates a niche with 254 invalid values, +// allowing types like `Option>` to fit into 8 bytes. +pub enum CanBeNicheFilledButShouldnt { + A(NonZeroU8, u32), + B +} +pub enum AlwaysTaggedBecauseItHasNoNiche { + A(u8, u32), + B +} + +pub fn main() { + assert_eq!(size_of::(), 1 as usize); + assert_eq!(size_of::(), 4 as usize); + assert_eq!(size_of::(), 4 as usize); + assert_eq!(size_of::(), 1 as usize); + assert_eq!(size_of::(), 4 as usize); + assert_eq!(size_of::(), 2 as usize); + assert_eq!(size_of::(), 3 as usize); + // Alignment causes padding before the char and the u32. + + assert_eq!(size_of::(), + 16 as usize); + assert_eq!(size_of::(), size_of::()); + assert_eq!(size_of::(), size_of::()); + assert_eq!(size_of::(), size_of::()); + assert_eq!(size_of::(), size_of::()); + + // Make sure enum types are the appropriate size, mostly + // around ensuring alignment is handled properly + + assert_eq!(size_of::(), 8 as usize); + assert_eq!(size_of::(), 8 as usize); + assert_eq!(size_of::(), 4 as usize); + assert_eq!(size_of::(), 4); + assert_eq!(size_of::(), 6); + assert_eq!(size_of::(), 8); + + + assert_eq!(size_of::(), 0); + assert_eq!(size_of::(), 0); + assert_eq!(size_of::(), 0); + assert_eq!(size_of::(), 0); + assert_eq!(size_of::(), 1); + assert_eq!(size_of::(), 1); + + assert_eq!(size_of::>(), + size_of::>()); + assert_eq!(size_of::(), size_of::<&'static ()>()); + + assert_eq!(size_of::>>(), size_of::<(bool, &())>()); + assert_eq!(size_of::>>(), size_of::<(bool, &())>()); + assert_eq!(size_of::>>(), size_of::<(bool, &())>()); + assert_eq!(size_of::>>(), size_of::<(bool, &())>()); + + assert_eq!(size_of::(), 8); + assert_eq!(size_of::>(), 8); + assert_eq!(size_of::>>(), 8); + assert_eq!(size_of::(), 8); + assert_eq!(size_of::>(), 8); + assert_eq!(size_of::>>(), 8); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type-use-i1-versus-i8.rs b/gcc/testsuite/rust/rustc/ui/type-use-i1-versus-i8.rs new file mode 100644 index 000000000000..9ba0cfd8c47d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type-use-i1-versus-i8.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +use std::ptr; + +pub fn main() { + unsafe { + let mut x: bool = false; + // this line breaks it + ptr::write(&mut x, false); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/ascription/issue-34255-1.rs b/gcc/testsuite/rust/rustc/ui/type/ascription/issue-34255-1.rs new file mode 100644 index 000000000000..3a16d00bab33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/ascription/issue-34255-1.rs @@ -0,0 +1,16 @@ +struct Reactor { + input_cells: Vec, +} + +impl Reactor { + pub fn new() -> Self { + input_cells: Vec::new() +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +// { dg-error ".E0107." "" { target *-*-* } .-3 } + } +} + +// This case isn't currently being handled gracefully, including for completeness. +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type/ascription/issue-47666.rs b/gcc/testsuite/rust/rustc/ui/type/ascription/issue-47666.rs new file mode 100644 index 000000000000..fa8f0eb570a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/ascription/issue-47666.rs @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _ = Option:Some(vec![0, 1]); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/ascription/issue-54516.rs b/gcc/testsuite/rust/rustc/ui/type/ascription/issue-54516.rs new file mode 100644 index 000000000000..126ba6a98654 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/ascription/issue-54516.rs @@ -0,0 +1,8 @@ +// run-rustfix +use std::collections::BTreeMap; + +fn main() { + println!("{}", std::mem:size_of::>()); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/ascription/issue-60933.rs b/gcc/testsuite/rust/rustc/ui/type/ascription/issue-60933.rs new file mode 100644 index 000000000000..6b861da2ed22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/ascription/issue-60933.rs @@ -0,0 +1,6 @@ +// run-rustfix +fn main() { + let _: usize = std::mem:size_of::(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/auxiliary/crate_a1.rs b/gcc/testsuite/rust/rustc/ui/type/auxiliary/crate_a1.rs new file mode 100644 index 000000000000..0bd679b08201 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/auxiliary/crate_a1.rs @@ -0,0 +1,12 @@ +pub struct Foo; + +pub trait Bar{} + +pub fn bar() -> Box { + unimplemented!() +} + + +pub fn try_foo(x: Foo){} +pub fn try_bar(x: Box){} + diff --git a/gcc/testsuite/rust/rustc/ui/type/auxiliary/crate_a2.rs b/gcc/testsuite/rust/rustc/ui/type/auxiliary/crate_a2.rs new file mode 100644 index 000000000000..1979a63b4572 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/auxiliary/crate_a2.rs @@ -0,0 +1,8 @@ +pub struct Foo; + +pub trait Bar{} + +pub fn bar() -> Box { + unimplemented!() +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs b/gcc/testsuite/rust/rustc/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs new file mode 100644 index 000000000000..8f6f5460257b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs @@ -0,0 +1,9 @@ +// Regression test for issue #67690 +// Rustc endless loop out-of-memory and consequent SIGKILL in generic new type + +// check-pass +pub type T = P; +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-alias-bounds.rs b/gcc/testsuite/rust/rustc/ui/type/type-alias-bounds.rs new file mode 100644 index 000000000000..348eeddb4bf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-alias-bounds.rs @@ -0,0 +1,60 @@ +// Test `ignored_generic_bounds` lint warning about bounds in type aliases. + +// check-pass +#![allow(dead_code)] + +use std::rc::Rc; + +type SVec = Vec; +// { dg-warning "" "" { target *-*-* } .-1 } +type S2Vec where T: Send = Vec; +// { dg-warning "" "" { target *-*-* } .-1 } +type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); +// { dg-warning "" "" { target *-*-* } .-1 } +type WVec<'b, T: 'b + 'b> = (&'b u32, Vec); +// { dg-warning "" "" { target *-*-* } .-1 } +type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); +// { dg-warning "" "" { target *-*-* } .-1 } + +static STATIC: u32 = 0; + +fn foo<'a>(y: &'a i32) { + // If any of the bounds above would matter, the code below would be rejected. + // This can be seen when replacing the type aliases above by newtype structs. + // (The type aliases have no unused parameters to make that a valid transformation.) + let mut x: SVec<_> = Vec::new(); + x.push(Rc::new(42)); // is not send + + let mut x: S2Vec<_> = Vec::new(); + x.push(Rc::new(42)); // is not `Send` + + let mut x: VVec<'static, 'a> = (&STATIC, Vec::new()); + x.1.push(y); // `'a: 'static` does not hold + + let mut x: WVec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // `&'a i32: 'static` does not hold + + let mut x: W2Vec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // `&'a i32: 'static` does not hold +} + +// Bounds are not checked either; i.e., the definition is not necessarily well-formed. +struct Sendable(T); +type MySendable = Sendable; // no error here! + +// However, bounds *are* taken into account when accessing associated types +trait Bound { type Assoc; } +type T1 = U::Assoc; // { dg-warning "" "" { target *-*-* } } +type T2 where U: Bound = U::Assoc; // { dg-warning "" "" { target *-*-* } } + +// This errors: +// `type T3 = U::Assoc;` +// Do this instead: +type T4 = ::Assoc; + +// Make sure the help about associatd types is not shown incorrectly +type T5 = ::Assoc; // { dg-warning "" "" { target *-*-* } } +type T6 = ::std::vec::Vec; // { dg-warning "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-annotation-needed.rs b/gcc/testsuite/rust/rustc/ui/type/type-annotation-needed.rs new file mode 100644 index 000000000000..e62869cd44c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-annotation-needed.rs @@ -0,0 +1,10 @@ +fn foo>(x: i32) {} +// { dg-note "" "" { target *-*-* } .-1 } + +fn main() { + foo(42); +// { dg-error ".E0283." "" { target *-*-* } .-1 } +// { dg-note ".E0283." "" { target *-*-* } .-2 } +// { dg-note ".E0283." "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-arg-out-of-scope.rs b/gcc/testsuite/rust/rustc/ui/type/type-arg-out-of-scope.rs new file mode 100644 index 000000000000..b08f41fc75c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-arg-out-of-scope.rs @@ -0,0 +1,6 @@ +// error-pattern:can't use generic parameters from outer function +fn foo(x: T) { + fn bar(f: Box T>) { } +} +fn main() { foo(1); } + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-ascription-instead-of-initializer.rs b/gcc/testsuite/rust/rustc/ui/type/type-ascription-instead-of-initializer.rs new file mode 100644 index 000000000000..bd9b2b517f20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-ascription-instead-of-initializer.rs @@ -0,0 +1,5 @@ +fn main() { + let x: Vec::with_capacity(10, 20); // { dg-error ".E0061." "" { target *-*-* } } +// { dg-error ".E0061." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-ascription-instead-of-statement-end.rs b/gcc/testsuite/rust/rustc/ui/type/type-ascription-instead-of-statement-end.rs new file mode 100644 index 000000000000..dfaa2c0f5dec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-ascription-instead-of-statement-end.rs @@ -0,0 +1,11 @@ +#![feature(type_ascription)] + +fn main() { + println!("test"): + 0; // { dg-error "" "" { target *-*-* } } +} + +fn foo() { + println!("test"): 0; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-ascription-precedence.rs b/gcc/testsuite/rust/rustc/ui/type/type-ascription-precedence.rs new file mode 100644 index 000000000000..257727c71fb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-ascription-precedence.rs @@ -0,0 +1,55 @@ +// Operator precedence of type ascription +// Type ascription has very high precedence, the same as operator `as` + +#![feature(type_ascription)] + +use std::ops::*; + +struct S; +struct Z; + +impl Add for S { + type Output = S; + fn add(self, _rhs: Z) -> S { panic!() } +} +impl Mul for S { + type Output = S; + fn mul(self, _rhs: Z) -> S { panic!() } +} +impl Neg for S { + type Output = Z; + fn neg(self) -> Z { panic!() } +} +impl Deref for S { + type Target = Z; + fn deref(&self) -> &Z { panic!() } +} + +fn main() { + &S: &S; // OK + (&S): &S; // OK + &(S: &S); // { dg-error ".E0308." "" { target *-*-* } } + + *S: Z; // OK + (*S): Z; // OK + *(S: Z); // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0614." "" { target *-*-* } .-1 } + + -S: Z; // OK + (-S): Z; // OK + -(S: Z); // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0600." "" { target *-*-* } .-1 } + + S + Z: Z; // OK + S + (Z: Z); // OK + (S + Z): Z; // { dg-error ".E0308." "" { target *-*-* } } + + S * Z: Z; // OK + S * (Z: Z); // OK + (S * Z): Z; // { dg-error ".E0308." "" { target *-*-* } } + + S .. S: S; // OK + S .. (S: S); // OK + (S .. S): S; // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-ascription-soundness.rs b/gcc/testsuite/rust/rustc/ui/type/type-ascription-soundness.rs new file mode 100644 index 000000000000..0cf593e5651f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-ascription-soundness.rs @@ -0,0 +1,14 @@ +// Type ascription doesn't lead to unsoundness + +#![feature(type_ascription)] + +fn main() { + let arr = &[1u8, 2, 3]; + let ref x = arr: &[u8]; // { dg-error ".E0308." "" { target *-*-* } } + let ref mut x = arr: &[u8]; // { dg-error ".E0308." "" { target *-*-* } } + match arr: &[u8] { // { dg-error ".E0308." "" { target *-*-* } } + ref x => {} + } + let _len = (arr: &[u8]).len(); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-ascription-with-fn-call.rs b/gcc/testsuite/rust/rustc/ui/type/type-ascription-with-fn-call.rs new file mode 100644 index 000000000000..7b667177c542 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-ascription-with-fn-call.rs @@ -0,0 +1,10 @@ +// run-rustfix +#![feature(type_ascription)] + +fn main() { + f() : + f(); // { dg-error ".E0573." "" { target *-*-* } } +} + +fn f() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-check-defaults.rs b/gcc/testsuite/rust/rustc/ui/type/type-check-defaults.rs new file mode 100644 index 000000000000..5b0072d28a55 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-check-defaults.rs @@ -0,0 +1,28 @@ +use std::iter::FromIterator; +use std::vec::IntoIter; +use std::ops::Add; + +struct Foo>(T, U); +struct WellFormed>(Z); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +struct WellFormedNoBounds>(Z); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +struct Bounds(T); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +struct WhereClause(T) where T: Copy; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +trait TraitBound {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +trait Super { } +trait Base: Super { } +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +trait ProjectionPred> where T::Item : Add {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-check/assignment-expected-bool.rs b/gcc/testsuite/rust/rustc/ui/type/type-check/assignment-expected-bool.rs new file mode 100644 index 000000000000..ef3fce4d3d33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-check/assignment-expected-bool.rs @@ -0,0 +1,35 @@ +// The purpose of this text is to ensure that we get good +// diagnostics when a `bool` is expected but that due to +// an assignment expression `x = y` the type is `()`. + +fn main() { + let _: bool = 0 = 0; // { dg-error ".E0308." "" { target *-*-* } } + + let _: bool = match 0 { + 0 => 0 = 0, // { dg-error ".E0308." "" { target *-*-* } } + _ => 0 = 0, // { dg-error ".E0308." "" { target *-*-* } } + }; + + let _: bool = match true { + true => 0 = 0, // { dg-error ".E0308." "" { target *-*-* } } + _ => (), + }; + + if 0 = 0 {} // { dg-error ".E0308." "" { target *-*-* } } + + let _: bool = if { 0 = 0 } { // { dg-error ".E0308." "" { target *-*-* } } + 0 = 0 // { dg-error ".E0308." "" { target *-*-* } } + } else { + 0 = 0 // { dg-error ".E0308." "" { target *-*-* } } + }; + + let _ = (0 = 0) // { dg-error ".E0308." "" { target *-*-* } } + && { 0 = 0 } // { dg-error ".E0308." "" { target *-*-* } } + || (0 = 0); // { dg-error ".E0308." "" { target *-*-* } } + + // A test to check that not expecting `bool` behaves well: + let _: usize = 0 = 0; +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-check/assignment-in-if.rs b/gcc/testsuite/rust/rustc/ui/type/type-check/assignment-in-if.rs new file mode 100644 index 000000000000..436de3596a76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-check/assignment-in-if.rs @@ -0,0 +1,44 @@ +// Test that the parser does not attempt to parse struct literals +// within assignments in if expressions. + +#![allow(unused_parens)] + +struct Foo { + foo: usize +} + +fn main() { + let x = 1; + let y: Foo; + + // `x { ... }` should not be interpreted as a struct literal here + if x = x { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + println!("{}", x); + } + // Explicit parentheses on the left should match behavior of above + if (x = x) { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + println!("{}", x); + } + // The struct literal interpretation is fine with explicit parentheses on the right + if y = (Foo { foo: x }) { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + println!("{}", x); + } + // "invalid left-hand side of assignment" error is suppresed + if 3 = x { +// { dg-error ".E0308." "" { target *-*-* } .-1 } + println!("{}", x); + } + if ( + if true { + x = 4 // { dg-error ".E0308." "" { target *-*-* } } + } else { + x = 5 // { dg-error ".E0308." "" { target *-*-* } } + } + ) { + println!("{}", x); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-check/cannot_infer_local_or_array.rs b/gcc/testsuite/rust/rustc/ui/type/type-check/cannot_infer_local_or_array.rs new file mode 100644 index 000000000000..b1f37dbd26fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-check/cannot_infer_local_or_array.rs @@ -0,0 +1,4 @@ +fn main() { + let x = []; // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-check/cannot_infer_local_or_vec.rs b/gcc/testsuite/rust/rustc/ui/type/type-check/cannot_infer_local_or_vec.rs new file mode 100644 index 000000000000..2385a5f38cf5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-check/cannot_infer_local_or_vec.rs @@ -0,0 +1,5 @@ +fn main() { + let x = vec![]; +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.rs b/gcc/testsuite/rust/rustc/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.rs new file mode 100644 index 000000000000..39aaa6b9d745 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.rs @@ -0,0 +1,5 @@ +fn main() { + let (x, ) = (vec![], ); +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-check/issue-22897.rs b/gcc/testsuite/rust/rustc/ui/type/type-check/issue-22897.rs new file mode 100644 index 000000000000..03bc1b1cc2f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-check/issue-22897.rs @@ -0,0 +1,6 @@ +fn main() { } + +fn unconstrained_type() { + []; // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-check/issue-40294.rs b/gcc/testsuite/rust/rustc/ui/type/type-check/issue-40294.rs new file mode 100644 index 000000000000..0b487195be94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-check/issue-40294.rs @@ -0,0 +1,14 @@ +trait Foo: Sized { + fn foo(self); +} + +fn foo<'a,'b,T>(x: &'a T, y: &'b T) + where &'a T : Foo, // { dg-error ".E0283." "" { target *-*-* } } + &'b T : Foo +{ + x.foo(); + y.foo(); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-check/issue-41314.rs b/gcc/testsuite/rust/rustc/ui/type/type-check/issue-41314.rs new file mode 100644 index 000000000000..1be7ee3b0b9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-check/issue-41314.rs @@ -0,0 +1,11 @@ +enum X { + Y(u32) +} + +fn main() { + match X::Y(0) { + X::Y { number } => {} +// { dg-error ".E0769." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs b/gcc/testsuite/rust/rustc/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs new file mode 100644 index 000000000000..b573d7df0c8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-check/issue-67273-assignment-match-prior-arm-bool-expected-unit.rs @@ -0,0 +1,28 @@ +fn main() { + let mut i: i64; + // Expected type is an inference variable `?T` + // because the `match` is used as a statement. + // This is the "initial" type of the `coercion`. + match i { + // Add `bool` to the overall `coercion`. + 0 => true, + + // Necessary to cause the ICE: + 1 => true, + + // Suppose that we had `let _: bool = match i { ... }`. + // In that case, as the expected type would be `bool`, + // we would suggest `i == 1` as a fix. + // + // However, no type error happens when checking `i = 1` because `expected == ?T`, + // which will unify with `typeof(i = 1) == ()`. + // + // However, in #67273, we would delay the unification of this arm with the above + // because we used the hitherto accumulated coercion as opposed to the "initial" type. + 2 => i = 1, +// { dg-error ".E0308." "" { target *-*-* } .-1 } + + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-check/missing_trait_impl.rs b/gcc/testsuite/rust/rustc/ui/type/type-check/missing_trait_impl.rs new file mode 100644 index 000000000000..9e5fecfd764b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-check/missing_trait_impl.rs @@ -0,0 +1,11 @@ +fn main() { +} + +fn foo(x: T, y: T) { + let z = x + y; // { dg-error ".E0369." "" { target *-*-* } } +} + +fn bar(x: T) { + x += x; // { dg-error ".E0368." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-check/unknown_type_for_closure.rs b/gcc/testsuite/rust/rustc/ui/type/type-check/unknown_type_for_closure.rs new file mode 100644 index 000000000000..fbf1f01eba4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-check/unknown_type_for_closure.rs @@ -0,0 +1,4 @@ +fn main() { + let x = |_| { }; // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-dependent-def-issue-49241.rs b/gcc/testsuite/rust/rustc/ui/type/type-dependent-def-issue-49241.rs new file mode 100644 index 000000000000..9b287cb88dfb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-dependent-def-issue-49241.rs @@ -0,0 +1,6 @@ +fn main() { + let v = vec![0]; + const l: usize = v.count(); // { dg-error ".E0435." "" { target *-*-* } } + let s: [u32; l] = v.into_iter().collect(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-error-break-tail.rs b/gcc/testsuite/rust/rustc/ui/type/type-error-break-tail.rs new file mode 100644 index 000000000000..53373400bcbe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-error-break-tail.rs @@ -0,0 +1,9 @@ +fn loop_ending() -> i32 { + loop { + if false { break; } // { dg-error ".E0308." "" { target *-*-* } } + return 42; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-mismatch-multiple.rs b/gcc/testsuite/rust/rustc/ui/type/type-mismatch-multiple.rs new file mode 100644 index 000000000000..b1a5cd753fd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-mismatch-multiple.rs @@ -0,0 +1,8 @@ +// Checking that the compiler reports multiple type errors at once + +fn main() { let a: bool = 1; let b: i32 = true; } +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-mismatch-same-crate-name.rs b/gcc/testsuite/rust/rustc/ui/type/type-mismatch-same-crate-name.rs new file mode 100644 index 000000000000..5e0e69f93896 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-mismatch-same-crate-name.rs @@ -0,0 +1,28 @@ +// aux-build:crate_a1.rs +// aux-build:crate_a2.rs + +// This tests the extra note reported when a type error deals with +// seemingly identical types. +// The main use case of this error is when there are two crates +// (generally different versions of the same crate) with the same name +// causing a type mismatch. Here, we simulate that error using block-scoped +// aliased `extern crate` declarations. + +fn main() { + let foo2 = {extern crate crate_a2 as a; a::Foo}; + let bar2 = {extern crate crate_a2 as a; a::bar()}; + { + extern crate crate_a1 as a; + a::try_foo(foo2); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } + a::try_bar(bar2); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/type/type-mismatch.rs new file mode 100644 index 000000000000..210ab0017511 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-mismatch.rs @@ -0,0 +1,79 @@ +#![allow(non_camel_case_types)] + +trait Qux {} +struct A; +struct B; +impl Qux for A {} +impl Qux for B {} + +struct Foo(T, U, V); + +struct foo; +struct bar; + +fn want(t: T) {} + +fn have_usize(f: usize) { + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn have_foo(f: foo) { + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn have_foo_foo(f: Foo) { + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::<&Foo>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::<&Foo>(f); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn have_foo_foo_b(f: Foo) { + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::<&Foo>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::<&Foo>(f); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn have_foo_foo_b_a(f: Foo) { + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::<&Foo>(f); // { dg-error ".E0308." "" { target *-*-* } } + want::<&Foo>(f); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-parameter-defaults-referencing-Self-ppaux.rs b/gcc/testsuite/rust/rustc/ui/type/type-parameter-defaults-referencing-Self-ppaux.rs new file mode 100644 index 000000000000..f6d79946044a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-parameter-defaults-referencing-Self-ppaux.rs @@ -0,0 +1,18 @@ +// Test a default that references `Self` which is then used in an +// object type. Issue #18956. In this case, the value is supplied by +// the user, but pretty-printing the type during the error message +// caused an ICE. + +trait MyAdd { fn add(&self, other: &Rhs) -> Self; } + +impl MyAdd for i32 { + fn add(&self, other: &i32) -> i32 { *self + *other } +} + +fn main() { + let x: i32 = 5; + let y = x as dyn MyAdd; +// { dg-error ".E0038." "" { target *-*-* } .-1 } +// { dg-error ".E0038." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-parameter-defaults-referencing-Self.rs b/gcc/testsuite/rust/rustc/ui/type/type-parameter-defaults-referencing-Self.rs new file mode 100644 index 000000000000..575f50424eac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-parameter-defaults-referencing-Self.rs @@ -0,0 +1,14 @@ +// Test a default that references `Self` which is then used in an object type. +// Issue #18956. + +#![feature(default_type_params)] + +trait Foo { + fn method(&self); +} + +fn foo(x: &dyn Foo) { } +// { dg-error ".E0393." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-parameter-names.rs b/gcc/testsuite/rust/rustc/ui/type/type-parameter-names.rs new file mode 100644 index 000000000000..57597b1bbf89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-parameter-names.rs @@ -0,0 +1,13 @@ +// Test that we print out the names of type parameters correctly in +// our error messages. + +fn foo(x: Foo) -> Bar { + x +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-params-in-different-spaces-1.rs b/gcc/testsuite/rust/rustc/ui/type/type-params-in-different-spaces-1.rs new file mode 100644 index 000000000000..fb767f191559 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-params-in-different-spaces-1.rs @@ -0,0 +1,19 @@ +use std::ops::Add; + +trait BrokenAdd: Copy + Add { + fn broken_add(&self, rhs: T) -> Self { + *self + rhs // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } + } +} + +impl> BrokenAdd for T {} + +pub fn main() { + let foo: u8 = 0; + let x: u8 = foo.broken_add("hello darkness my old friend".to_string()); + println!("{}", x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-params-in-different-spaces-2.rs b/gcc/testsuite/rust/rustc/ui/type/type-params-in-different-spaces-2.rs new file mode 100644 index 000000000000..dad300f37023 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-params-in-different-spaces-2.rs @@ -0,0 +1,22 @@ +// Test static calls to make sure that we align the Self and input +// type parameters on a trait correctly. + +trait Tr : Sized { + fn op(_: T) -> Self; +} + +trait A: Tr { + fn test(u: U) -> Self { + Tr::op(u) // { dg-error ".E0277." "" { target *-*-* } } + } +} + +trait B: Tr { + fn test(u: U) -> Self { + Tr::op(u) // { dg-error ".E0277." "" { target *-*-* } } + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-params-in-different-spaces-3.rs b/gcc/testsuite/rust/rustc/ui/type/type-params-in-different-spaces-3.rs new file mode 100644 index 000000000000..13123b3f1468 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-params-in-different-spaces-3.rs @@ -0,0 +1,8 @@ +trait Tr : Sized { + fn test(u: X) -> Self { + u // { dg-error ".E0308." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-path-err-node-types.rs b/gcc/testsuite/rust/rustc/ui/type/type-path-err-node-types.rs new file mode 100644 index 000000000000..13ed9108b311 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-path-err-node-types.rs @@ -0,0 +1,27 @@ +// Type arguments in unresolved entities (reporting errors before type checking) +// should have their types recorded. + +trait Tr {} + +fn local_type() { + let _: Nonexistent; // { dg-error ".E0412." "" { target *-*-* } } +} + +fn ufcs_trait() { + >::nonexistent(); // { dg-error ".E0576." "" { target *-*-* } } +} + +fn ufcs_item() { + NonExistent::Assoc::; // { dg-error ".E0433." "" { target *-*-* } } +} + +fn method() { + nonexistent.nonexistent::(); // { dg-error ".E0425." "" { target *-*-* } } +} + +fn closure() { + let _ = |a, b: _| -> _ { 0 }; // { dg-error ".E0282." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-recursive.rs b/gcc/testsuite/rust/rustc/ui/type/type-recursive.rs new file mode 100644 index 000000000000..8bd999e26503 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-recursive.rs @@ -0,0 +1,7 @@ +struct T1 { // { dg-error ".E0072." "" { target *-*-* } } + foo: isize, + foolish: T1 +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/type/type-shadow.rs b/gcc/testsuite/rust/rustc/ui/type/type-shadow.rs new file mode 100644 index 000000000000..1129a5b761e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type/type-shadow.rs @@ -0,0 +1,9 @@ +fn main() { + type X = isize; + type Y = X; + if true { + type X = &'static str; + let y: Y = "hello"; // { dg-error ".E0308." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/type_length_limit.rs b/gcc/testsuite/rust/rustc/ui/type_length_limit.rs new file mode 100644 index 000000000000..8e27cf624fd9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/type_length_limit.rs @@ -0,0 +1,28 @@ +// build-fail +// error-pattern: reached the type-length limit while instantiating +// normalize-stderr-test: ".nll/" -> "/" + +// Test that the type length limit can be changed. + +#![allow(dead_code)] +#![type_length_limit="4"] + +macro_rules! link { + ($id:ident, $t:ty) => { + pub type $id = ($t, $t, $t); + } +} + +link! { A, B } +link! { B, C } +link! { C, D } +link! { D, E } +link! { E, F } +link! { F, G } + +pub struct G; + +fn main() { + drop::>(None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck-closure-to-unsafe-fn-ptr.rs b/gcc/testsuite/rust/rustc/ui/typeck-closure-to-unsafe-fn-ptr.rs new file mode 100644 index 000000000000..675632a59b80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck-closure-to-unsafe-fn-ptr.rs @@ -0,0 +1,10 @@ +// run-pass + +unsafe fn call_unsafe(func: unsafe fn() -> ()) -> () { + func() +} + +pub fn main() { + unsafe { call_unsafe(|| {}); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck-fn-to-unsafe-fn-ptr.rs b/gcc/testsuite/rust/rustc/ui/typeck-fn-to-unsafe-fn-ptr.rs new file mode 100644 index 000000000000..c5785a770dab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck-fn-to-unsafe-fn-ptr.rs @@ -0,0 +1,13 @@ +// run-pass +// This tests reification from safe function to `unsafe fn` pointer + +fn do_nothing() -> () {} + +unsafe fn call_unsafe(func: unsafe fn() -> ()) -> () { + func() +} + +pub fn main() { + unsafe { call_unsafe(do_nothing); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/auxiliary/tdticc_coherence_lib.rs b/gcc/testsuite/rust/rustc/ui/typeck/auxiliary/tdticc_coherence_lib.rs new file mode 100644 index 000000000000..ed017a09c9fa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/auxiliary/tdticc_coherence_lib.rs @@ -0,0 +1,7 @@ +#![feature(optin_builtin_traits, core)] +#![crate_type = "rlib"] + +pub auto trait DefaultedTrait { } + +pub struct Something { t: T } + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/issue-52082-type-param-shadows-existing-type.rs b/gcc/testsuite/rust/rustc/ui/typeck/issue-52082-type-param-shadows-existing-type.rs new file mode 100644 index 000000000000..6c989e9e2cc1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/issue-52082-type-param-shadows-existing-type.rs @@ -0,0 +1,55 @@ +// Fix issue 52082: Confusing error if accidentally defining a type parameter with the same name as +// an existing type +// +// To this end, make sure that when trying to retrieve a field of a (reference to) type parameter, +// rustc points to the point where the parameter was defined. +#[derive(Debug)] +struct Point +{ + x: i32, + y: i32 +} + +impl Point +{ + fn add(a: &Point, b: &Point) -> Point + { + Point {x: a.x + b.x, y: a.y + b.y} + } +} + +trait Eq +{ + fn equals_ref(a: &T, b: &T) -> bool; + fn equals_val(a: T, b: T) -> bool; +} + +impl Eq for Point +{ + fn equals_ref(a: &Point, b: &Point) -> bool + { + a.x == b.x && a.y == b.y // { dg-error ".E0609." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } + } + + fn equals_val(a: Point, b: Point) -> bool + { + a.x == b.x && a.y == b.y // { dg-error ".E0609." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { dg-error "" "" { target *-*-* } .-3 } +// { dg-error "" "" { target *-*-* } .-4 } + } +} + +fn main() +{ + let p1 = Point {x: 0, y: 10}; + let p2 = Point {x: 20, y: 42}; + println!("{:?}", Point::add(&p1, &p2)); + println!("p1: {:?}, p2: {:?}", p1, p2); + println!("&p1 == &p2: {:?}", Point::equals_ref(&p1, &p2)); + println!("p1 == p2: {:?}", Point::equals_val(p1, p2)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs b/gcc/testsuite/rust/rustc/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs new file mode 100644 index 000000000000..99b559ebe868 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs @@ -0,0 +1,24 @@ +// check-pass + +// rust-lang/rust#55810: types for a binding in a match arm can be +// inferred from arms that come later in the match. + +struct S; + +impl S { + fn method(&self) -> bool { + unimplemented!() + } +} + +fn get() -> T { + unimplemented!() +} + +fn main() { + match get() { + x if x.method() => {} + &S => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.rs b/gcc/testsuite/rust/rustc/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.rs new file mode 100644 index 000000000000..61b6050116bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.rs @@ -0,0 +1,8 @@ +//extern crate has_assoc_type; + +//fn ice(x: Box>) { +fn ice(x: Box>) { + *x // { dg-error ".E0308." "" { target *-*-* } } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/issue-67971.rs b/gcc/testsuite/rust/rustc/ui/typeck/issue-67971.rs new file mode 100644 index 000000000000..8768485e7781 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/issue-67971.rs @@ -0,0 +1,10 @@ +struct S {} + +fn foo(ctx: &mut S) -> String { // { dg-error ".E0308." "" { target *-*-* } } + // Don't suggest to remove semicolon as it won't fix anything + ctx.sleep = 0; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/issue-68590-reborrow-through-derefmut.rs b/gcc/testsuite/rust/rustc/ui/typeck/issue-68590-reborrow-through-derefmut.rs new file mode 100644 index 000000000000..0b83755ff12e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/issue-68590-reborrow-through-derefmut.rs @@ -0,0 +1,26 @@ +// check-pass + +// rust-lang/rust#68590: confusing diagnostics when reborrowing through DerefMut. + +use std::cell::RefCell; + +struct A; + +struct S<'a> { + a: &'a mut A, +} + +fn take_a(_: &mut A) {} + +fn test<'a>(s: &RefCell>) { + let mut guard = s.borrow_mut(); + take_a(guard.a); + let _s2 = S { a: guard.a }; +} + +fn main() { + let a = &mut A; + let s = RefCell::new(S { a }); + test(&s); +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.rs b/gcc/testsuite/rust/rustc/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.rs new file mode 100644 index 000000000000..475384bd0f14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/issue-69378-ice-on-invalid-type-node-after-recovery.rs @@ -0,0 +1,10 @@ +// Regression test for #69378: no type for node after struct parse recovery + +struct Foo { 0: u8 } // { dg-error "" "" { target *-*-* } } + +fn test(f: Foo) { + Foo{foo: 4, ..f}; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/issue-72225-call-fnmut-through-derefmut.rs b/gcc/testsuite/rust/rustc/ui/typeck/issue-72225-call-fnmut-through-derefmut.rs new file mode 100644 index 000000000000..c3fd3df6b153 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/issue-72225-call-fnmut-through-derefmut.rs @@ -0,0 +1,22 @@ +// check-pass + +// rust-lang/rust#72225: confusing diagnostics when calling FnMut through DerefMut. + +use std::cell::RefCell; + +struct S { + f: Box +} + +fn test(s: &RefCell) { + let mut guard = s.borrow_mut(); + (guard.f)(); +} + +fn main() { + let s = RefCell::new(S { + f: Box::new(|| ()) + }); + test(&s); +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/issue-73592-borrow_mut-through-deref.rs b/gcc/testsuite/rust/rustc/ui/typeck/issue-73592-borrow_mut-through-deref.rs new file mode 100644 index 000000000000..c85fd75ff263 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/issue-73592-borrow_mut-through-deref.rs @@ -0,0 +1,60 @@ +// check-pass +// run-rustfix +// +// rust-lang/rust#73592: borrow_mut through Deref should work. +// +// Before #72280, when we see something like `&mut *rcvr.method()`, we +// incorrectly requires `rcvr` to be type-checked as a mut place. While this +// requirement is usually correct for smart pointers, it is overly restrictive +// for types like `Mutex` or `RefCell` which can produce a guard that +// implements `DerefMut` from `&self`. +// +// Making it more confusing, because we use Deref as the fallback when DerefMut +// is implemented, we won't see an issue when the smart pointer does not +// implement `DerefMut`. It only causes an issue when `rcvr` is obtained via a +// type that implements both `Deref` or `DerefMut`. +// +// This bug is only discovered in #73592 after it is already fixed as a side-effect +// of a refactoring made in #72280. + +#![warn(unused_mut)] + +use std::pin::Pin; +use std::cell::RefCell; + +struct S(RefCell<()>); + +fn test_pin(s: Pin<&S>) { + // This works before #72280. + let _ = &mut *s.0.borrow_mut(); +} + +fn test_pin_mut(s: Pin<&mut S>) { + // This should compile but didn't before #72280. + let _ = &mut *s.0.borrow_mut(); +} + +fn test_vec(s: &Vec>) { + // This should compile but didn't before #72280. + let _ = &mut *s[0].borrow_mut(); +} + +fn test_mut_pin(mut s: Pin<&S>) { +// { dg-warning "" "" { target *-*-* } .-1 } + let _ = &mut *s.0.borrow_mut(); +} + +fn test_mut_pin_mut(mut s: Pin<&mut S>) { +// { dg-warning "" "" { target *-*-* } .-1 } + let _ = &mut *s.0.borrow_mut(); +} + +fn main() { + let mut s = S(RefCell::new(())); + test_pin(Pin::new(&s)); + test_pin_mut(Pin::new(&mut s)); + test_mut_pin(Pin::new(&s)); + test_mut_pin_mut(Pin::new(&mut s)); + test_vec(&vec![s.0]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/issue-74933.rs b/gcc/testsuite/rust/rustc/ui/typeck/issue-74933.rs new file mode 100644 index 000000000000..d26bc9bbffff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/issue-74933.rs @@ -0,0 +1,39 @@ +// check-pass +// +// rust-lang/rust#74933: Lifetime error when indexing with borrowed index + +use std::ops::{Index, IndexMut}; + +struct S(V); +struct K<'a>(&'a ()); +struct V; + +impl<'a> Index<&'a K<'a>> for S { + type Output = V; + + fn index(&self, _: &'a K<'a>) -> &V { + &self.0 + } +} + +impl<'a> IndexMut<&'a K<'a>> for S { + fn index_mut(&mut self, _: &'a K<'a>) -> &mut V { + &mut self.0 + } +} + +impl V { + fn foo(&mut self) {} +} + +fn test(s: &mut S, k: &K<'_>) { + s[k] = V; + s[k].foo(); +} + +fn main() { + let mut s = S(V); + let k = K(&()); + test(&mut s, &k); +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck-builtin-bound-type-parameters.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck-builtin-bound-type-parameters.rs new file mode 100644 index 000000000000..96e89a873a00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck-builtin-bound-type-parameters.rs @@ -0,0 +1,20 @@ +fn foo1, U>(x: T) {} +// { dg-error ".E0107." "" { target *-*-* } .-1 } + +trait Trait: Copy {} +// { dg-error ".E0107." "" { target *-*-* } .-1 } + +struct MyStruct1>; +// { dg-error ".E0107." "" { target *-*-* } .-1 } + +struct MyStruct2<'a, T: Copy<'a>>; +// { dg-error ".E0107." "" { target *-*-* } .-1 } + + +fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck-cast-pointer-to-float.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck-cast-pointer-to-float.rs new file mode 100644 index 000000000000..ba069893a598 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck-cast-pointer-to-float.rs @@ -0,0 +1,6 @@ +fn main() { + let x : i16 = 22; + ((&x) as *const i16) as f32; +// { dg-error ".E0606." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-assoc-type.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-assoc-type.rs new file mode 100644 index 000000000000..8c63d7c61ce3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-assoc-type.rs @@ -0,0 +1,18 @@ +// run-rustfix +// Test that we do not consider associated types to be sendable without +// some applicable trait bound (and we don't ICE). +#![allow(dead_code)] + +trait Trait { + type AssocType; + fn dummy(&self) { } +} +fn bar() { + is_send::(); // { dg-error ".E0277." "" { target *-*-* } } +} + +fn is_send() { +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs new file mode 100644 index 000000000000..bf137951c78f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.rs @@ -0,0 +1,25 @@ +// aux-build:tdticc_coherence_lib.rs + +// Test that we do not consider associated types to be sendable without +// some applicable trait bound (and we don't ICE). + +#![feature(negative_impls)] + +extern crate tdticc_coherence_lib as lib; + +use lib::DefaultedTrait; + +struct A; +impl DefaultedTrait for (A,) { } // { dg-error ".E0117." "" { target *-*-* } } + +struct B; +impl !DefaultedTrait for (B,) { } // { dg-error ".E0117." "" { target *-*-* } } + +struct C; +struct D(T); +impl DefaultedTrait for Box { } // { dg-error ".E0321." "" { target *-*-* } } +impl DefaultedTrait for lib::Something { } // { dg-error ".E0117." "" { target *-*-* } } +impl DefaultedTrait for D { } // OK + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-negation-send.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-negation-send.rs new file mode 100644 index 000000000000..5d4fed1b7d80 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-negation-send.rs @@ -0,0 +1,22 @@ +#![feature(negative_impls)] + +struct MySendable { + t: *mut u8 +} + +unsafe impl Send for MySendable {} + +struct MyNotSendable { + t: *mut u8 +} + +impl !Send for MyNotSendable {} + +fn is_send() {} + +fn main() { + is_send::(); + is_send::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-negation-sync.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-negation-sync.rs new file mode 100644 index 000000000000..1bce94d94030 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-negation-sync.rs @@ -0,0 +1,42 @@ +#![feature(negative_impls)] + +struct Managed; +impl !Send for Managed {} +impl !Sync for Managed {} + +use std::cell::UnsafeCell; + +struct MySync { + t: *mut u8 +} + +unsafe impl Sync for MySync {} + +struct MyNotSync { + t: *mut u8 +} + +impl !Sync for MyNotSync {} + +struct MyTypeWUnsafe { + t: UnsafeCell +} + +struct MyTypeManaged { + t: Managed +} + +fn is_sync() {} + +fn main() { + is_sync::(); + is_sync::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + is_sync::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + is_sync::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-send-param.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-send-param.rs new file mode 100644 index 000000000000..a09e8d6caa6d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck-default-trait-impl-send-param.rs @@ -0,0 +1,12 @@ +// Test that we do not consider parameter types to be sendable without +// an explicit trait bound. + +fn foo() { + is_send::() // { dg-error ".E0277." "" { target *-*-* } } +} + +fn is_send() { +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck-unsafe-always-share.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck-unsafe-always-share.rs new file mode 100644 index 000000000000..8b74cd7abc54 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck-unsafe-always-share.rs @@ -0,0 +1,33 @@ +// Verify that UnsafeCell is *always* !Sync regardless if `T` is sync. + +#![feature(negative_impls)] + +use std::cell::UnsafeCell; +use std::marker::Sync; + +struct MySync { + u: UnsafeCell +} + +struct NoSync; +impl !Sync for NoSync {} + +fn test(s: T) {} + +fn main() { + let us = UnsafeCell::new(MySync{u: UnsafeCell::new(0)}); + test(us); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + let uns = UnsafeCell::new(NoSync); + test(uns); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + let ms = MySync{u: uns}; + test(ms); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + test(NoSync); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_item.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_item.rs new file mode 100644 index 000000000000..15278deb33a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_item.rs @@ -0,0 +1,211 @@ +// Needed for `type Y = impl Trait<_>` and `type B = _;` +#![feature(type_alias_impl_trait, associated_type_defaults)] +// This test checks that it is not possible to enable global type +// inference by using the `_` type placeholder. + +fn test() -> _ { 5 } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +fn test2() -> (_, _) { (5, 5) } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +static TEST3: _ = "test"; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +static TEST4: _ = 145; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +static TEST5: (_, _) = (1, 2); +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +fn test6(_: _) { } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +fn test6_b(_: _, _: T) { } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +fn test6_c(_: _, _: (T, K, L, A, B)) { } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +fn test7(x: _) { let _x: usize = x; } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +fn test8(_f: fn() -> _) { } +// { dg-error ".E0121." "" { target *-*-* } .-1 } +// { dg-error ".E0121." "" { target *-*-* } .-2 } + +struct Test9; + +impl Test9 { + fn test9(&self) -> _ { () } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + fn test10(&self, _x : _) { } +// { dg-error ".E0121." "" { target *-*-* } .-1 } +} + +fn test11(x: &usize) -> &_ { +// { dg-error ".E0121." "" { target *-*-* } .-1 } + &x +} + +unsafe fn test12(x: *const usize) -> *const *const _ { +// { dg-error ".E0121." "" { target *-*-* } .-1 } + &x +} + +impl Clone for Test9 { + fn clone(&self) -> _ { Test9 } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + fn clone_from(&mut self, other: _) { *self = Test9; } +// { dg-error ".E0121." "" { target *-*-* } .-1 } +} + +struct Test10 { + a: _, +// { dg-error ".E0121." "" { target *-*-* } .-1 } + b: (_, _), +} + +pub fn main() { + static A = 42; +// { dg-error "" "" { target *-*-* } .-1 } + static B: _ = 42; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + static C: Option<_> = Some(42); +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + fn fn_test() -> _ { 5 } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + fn fn_test2() -> (_, _) { (5, 5) } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + static FN_TEST3: _ = "test"; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + static FN_TEST4: _ = 145; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + static FN_TEST5: (_, _) = (1, 2); +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + fn fn_test6(_: _) { } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + fn fn_test7(x: _) { let _x: usize = x; } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + fn fn_test8(_f: fn() -> _) { } +// { dg-error ".E0121." "" { target *-*-* } .-1 } +// { dg-error ".E0121." "" { target *-*-* } .-2 } + + struct FnTest9; + + impl FnTest9 { + fn fn_test9(&self) -> _ { () } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + fn fn_test10(&self, _x : _) { } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + } + + impl Clone for FnTest9 { + fn clone(&self) -> _ { FnTest9 } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + fn clone_from(&mut self, other: _) { *self = FnTest9; } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + } + + struct FnTest10 { + a: _, +// { dg-error ".E0121." "" { target *-*-* } .-1 } + b: (_, _), + } + + fn fn_test11(_: _) -> (_, _) { panic!() } +// { dg-error ".E0121." "" { target *-*-* } .-1 } +// { dg-error ".E0121." "" { target *-*-* } .-2 } + + fn fn_test12(x: i32) -> (_, _) { (x, x) } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + + fn fn_test13(x: _) -> (i32, _) { (x, x) } +// { dg-error ".E0121." "" { target *-*-* } .-1 } +} + +trait T { + fn method_test1(&self, x: _); +// { dg-error ".E0121." "" { target *-*-* } .-1 } + fn method_test2(&self, x: _) -> _; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + fn method_test3(&self) -> _; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + fn assoc_fn_test1(x: _); +// { dg-error ".E0121." "" { target *-*-* } .-1 } + fn assoc_fn_test2(x: _) -> _; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + fn assoc_fn_test3() -> _; +// { dg-error ".E0121." "" { target *-*-* } .-1 } +} + +struct BadStruct<_>(_); +// { dg-error ".E0121." "" { target *-*-* } .-1 } +// { dg-error ".E0121." "" { target *-*-* } .-2 } +trait BadTrait<_> {} +// { dg-error "" "" { target *-*-* } .-1 } +impl BadTrait<_> for BadStruct<_> {} +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +fn impl_trait() -> impl BadTrait<_> { +// { dg-error ".E0121." "" { target *-*-* } .-1 } + unimplemented!() +} + +struct BadStruct1<_, _>(_); +// { dg-error ".E0121." "" { target *-*-* } .-1 } +// { dg-error ".E0121." "" { target *-*-* } .-2 } +// { dg-error ".E0121." "" { target *-*-* } .-3 } +// { dg-error ".E0121." "" { target *-*-* } .-4 } +struct BadStruct2<_, T>(_, T); +// { dg-error ".E0121." "" { target *-*-* } .-1 } +// { dg-error ".E0121." "" { target *-*-* } .-2 } + +type X = Box<_>; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +struct Struct; +trait Trait {} +impl Trait for Struct {} +type Y = impl Trait<_>; +// { dg-error ".E0121." "" { target *-*-* } .-1 } +fn foo() -> Y { + Struct +} + +trait Qux { + type A; + type B = _; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + const C: _; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + const D: _ = 42; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + // type E: _; // FIXME: make the parser propagate the existence of `B` + type F: std::ops::Fn(_); +// { dg-error ".E0121." "" { target *-*-* } .-1 } +} +impl Qux for Struct { + type A = _; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + type B = _; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + const C: _; +// { dg-error ".E0121." "" { target *-*-* } .-1 } +// { dg-error ".E0121." "" { target *-*-* } .-2 } + const D: _ = 42; +// { dg-error ".E0121." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_item_help.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_item_help.rs new file mode 100644 index 000000000000..c16c9b1bc89f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_item_help.rs @@ -0,0 +1,30 @@ +// This test checks that it proper item type will be suggested when +// using the `_` type placeholder. + +fn test1() -> _ { Some(42) } +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +const TEST2: _ = 42u32; +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +const TEST3: _ = Some(42); +// { dg-error ".E0121." "" { target *-*-* } .-1 } + +trait Test4 { + const TEST4: _ = 42; +// { dg-error ".E0121." "" { target *-*-* } .-1 } +} + +struct Test5; + +impl Test5 { + const TEST5: _ = 13; +// { dg-error ".E0121." "" { target *-*-* } .-1 } +} + +pub fn main() { + let _: Option = test1(); + let _: f64 = test1(); + let _: Option = test1(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_lifetime_1.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_lifetime_1.rs new file mode 100644 index 000000000000..4d57217fd83a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_lifetime_1.rs @@ -0,0 +1,12 @@ +// This test checks that the `_` type placeholder does not react +// badly if put as a lifetime parameter. + +struct Foo<'a, T:'a> { + r: &'a T +} + +pub fn main() { + let c: Foo<_, _> = Foo { r: &5 }; +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_lifetime_2.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_lifetime_2.rs new file mode 100644 index 000000000000..0931eb3a142a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_lifetime_2.rs @@ -0,0 +1,12 @@ +// This test checks that the `_` type placeholder does not react +// badly if put as a lifetime parameter. + +struct Foo<'a, T:'a> { + r: &'a T +} + +pub fn main() { + let c: Foo<_, usize> = Foo { r: &5 }; +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_mismatch.rs b/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_mismatch.rs new file mode 100644 index 000000000000..1f342baa246a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck/typeck_type_placeholder_mismatch.rs @@ -0,0 +1,28 @@ +// This test checks that genuine type errors with partial +// type hints are understandable. + +use std::marker::PhantomData; + +struct Foo(PhantomData); +struct Bar(PhantomData); + +pub fn main() { +} + +fn test1() { + let x: Foo<_> = Bar::(PhantomData); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } + let y: Foo = x; +} + +fn test2() { + let x: Foo<_> = Bar::(PhantomData); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeck_type_placeholder_1.rs b/gcc/testsuite/rust/rustc/ui/typeck_type_placeholder_1.rs new file mode 100644 index 000000000000..9590132fc748 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeck_type_placeholder_1.rs @@ -0,0 +1,33 @@ +// run-pass + +#![allow(dead_code)] +// This test checks that the `_` type placeholder works +// correctly for enabling type inference. + + +struct TestStruct { + x: *const isize +} + +unsafe impl Sync for TestStruct {} + +static CONSTEXPR: TestStruct = TestStruct{ x: &413 }; + + +pub fn main() { + let x: Vec<_> = (0..5).collect(); + let expected: &[usize] = &[0,1,2,3,4]; + assert_eq!(x, expected); + + let x = (0..5).collect::>(); + assert_eq!(x, expected); + + let y: _ = "hello"; + assert_eq!(y.len(), 5); + + let ptr: &usize = &5; + let ptr2 = ptr as *const _; + + assert_eq!(ptr as *const usize as usize, ptr2 as usize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeclasses-eq-example-static.rs b/gcc/testsuite/rust/rustc/ui/typeclasses-eq-example-static.rs new file mode 100644 index 000000000000..13366a940faa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeclasses-eq-example-static.rs @@ -0,0 +1,70 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] +#![feature(box_syntax)] + +// Example from lkuper's intern talk, August 2012 -- now with static +// methods! +use Color::{cyan, magenta, yellow, black}; +use ColorTree::{leaf, branch}; + +trait Equal { + fn isEq(a: &Self, b: &Self) -> bool; +} + +#[derive(Clone, Copy)] +enum Color { cyan, magenta, yellow, black } + +impl Equal for Color { + fn isEq(a: &Color, b: &Color) -> bool { + match (*a, *b) { + (cyan, cyan) => { true } + (magenta, magenta) => { true } + (yellow, yellow) => { true } + (black, black) => { true } + _ => { false } + } + } +} + +#[derive(Clone)] +enum ColorTree { + leaf(Color), + branch(Box, Box) +} + +impl Equal for ColorTree { + fn isEq(a: &ColorTree, b: &ColorTree) -> bool { + match (a, b) { + (&leaf(ref x), &leaf(ref y)) => { + Equal::isEq(&(*x).clone(), &(*y).clone()) + } + (&branch(ref l1, ref r1), &branch(ref l2, ref r2)) => { + Equal::isEq(&(**l1).clone(), &(**l2).clone()) && + Equal::isEq(&(**r1).clone(), &(**r2).clone()) + } + _ => { false } + } + } +} + +pub fn main() { + assert!(Equal::isEq(&cyan, &cyan)); + assert!(Equal::isEq(&magenta, &magenta)); + assert!(!Equal::isEq(&cyan, &yellow)); + assert!(!Equal::isEq(&magenta, &cyan)); + + assert!(Equal::isEq(&leaf(cyan), &leaf(cyan))); + assert!(!Equal::isEq(&leaf(cyan), &leaf(yellow))); + + assert!(Equal::isEq(&branch(box leaf(magenta), box leaf(cyan)), + &branch(box leaf(magenta), box leaf(cyan)))); + + assert!(!Equal::isEq(&branch(box leaf(magenta), box leaf(cyan)), + &branch(box leaf(magenta), box leaf(magenta)))); + + println!("Assertions all succeeded!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeclasses-eq-example.rs b/gcc/testsuite/rust/rustc/ui/typeclasses-eq-example.rs new file mode 100644 index 000000000000..285f0f730c40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeclasses-eq-example.rs @@ -0,0 +1,66 @@ +// run-pass + +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] +#![feature(box_syntax)] + +// Example from lkuper's intern talk, August 2012. +use Color::{cyan, magenta, yellow, black}; +use ColorTree::{leaf, branch}; + +trait Equal { + fn isEq(&self, a: &Self) -> bool; +} + +#[derive(Clone, Copy)] +enum Color { cyan, magenta, yellow, black } + +impl Equal for Color { + fn isEq(&self, a: &Color) -> bool { + match (*self, *a) { + (cyan, cyan) => { true } + (magenta, magenta) => { true } + (yellow, yellow) => { true } + (black, black) => { true } + _ => { false } + } + } +} + +#[derive(Clone)] +enum ColorTree { + leaf(Color), + branch(Box, Box) +} + +impl Equal for ColorTree { + fn isEq(&self, a: &ColorTree) -> bool { + match (self, a) { + (&leaf(ref x), &leaf(ref y)) => { x.isEq(&(*y).clone()) } + (&branch(ref l1, ref r1), &branch(ref l2, ref r2)) => { + (*l1).isEq(&(**l2).clone()) && (*r1).isEq(&(**r2).clone()) + } + _ => { false } + } + } +} + +pub fn main() { + assert!(cyan.isEq(&cyan)); + assert!(magenta.isEq(&magenta)); + assert!(!cyan.isEq(&yellow)); + assert!(!magenta.isEq(&cyan)); + + assert!(leaf(cyan).isEq(&leaf(cyan))); + assert!(!leaf(cyan).isEq(&leaf(yellow))); + + assert!(branch(box leaf(magenta), box leaf(cyan)) + .isEq(&branch(box leaf(magenta), box leaf(cyan)))); + + assert!(!branch(box leaf(magenta), box leaf(cyan)) + .isEq(&branch(box leaf(magenta), box leaf(magenta)))); + + println!("Assertions all succeeded!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/typeid-intrinsic.rs b/gcc/testsuite/rust/rustc/ui/typeid-intrinsic.rs new file mode 100644 index 000000000000..c95724661d66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typeid-intrinsic.rs @@ -0,0 +1,98 @@ +// run-pass + +#![allow(deprecated)] +// aux-build:typeid-intrinsic-aux1.rs +// aux-build:typeid-intrinsic-aux2.rs + +#![feature(core_intrinsics)] + +extern crate typeid_intrinsic_aux1 as other1; +extern crate typeid_intrinsic_aux2 as other2; + +use std::hash::{SipHasher, Hasher, Hash}; +use std::any::TypeId; + +struct A; +struct Test; + +pub fn main() { + assert_eq!(TypeId::of::(), other1::id_A()); + assert_eq!(TypeId::of::(), other1::id_B()); + assert_eq!(TypeId::of::(), other1::id_C()); + assert_eq!(TypeId::of::(), other1::id_D()); + assert_eq!(TypeId::of::(), other1::id_E()); + assert_eq!(TypeId::of::(), other1::id_F()); + assert_eq!(TypeId::of::(), other1::id_G()); + assert_eq!(TypeId::of::(), other1::id_H()); + assert_eq!(TypeId::of::(), other1::id_I()); + + assert_eq!(TypeId::of::(), other2::id_A()); + assert_eq!(TypeId::of::(), other2::id_B()); + assert_eq!(TypeId::of::(), other2::id_C()); + assert_eq!(TypeId::of::(), other2::id_D()); + assert_eq!(TypeId::of::(), other2::id_E()); + assert_eq!(TypeId::of::(), other2::id_F()); + assert_eq!(TypeId::of::(), other2::id_G()); + assert_eq!(TypeId::of::(), other2::id_H()); + assert_eq!(TypeId::of::(), other2::id_I()); + + assert_eq!(other1::id_F(), other2::id_F()); + assert_eq!(other1::id_G(), other2::id_G()); + assert_eq!(other1::id_H(), other2::id_H()); + assert_eq!(other1::id_I(), other2::id_I()); + + assert_eq!(TypeId::of::(), other2::foo::()); + assert_eq!(TypeId::of::(), other1::foo::()); + assert_eq!(other2::foo::(), other1::foo::()); + assert_eq!(TypeId::of::(), other2::foo::()); + assert_eq!(TypeId::of::(), other1::foo::()); + assert_eq!(other2::foo::(), other1::foo::()); + + // sanity test of TypeId + let (a, b, c) = (TypeId::of::(), TypeId::of::<&'static str>(), + TypeId::of::()); + let (d, e, f) = (TypeId::of::(), TypeId::of::<&'static str>(), + TypeId::of::()); + + assert!(a != b); + assert!(a != c); + assert!(b != c); + + assert_eq!(a, d); + assert_eq!(b, e); + assert_eq!(c, f); + + // check it has a hash + let (a, b) = (TypeId::of::(), TypeId::of::()); + + let mut s1 = SipHasher::new(); + a.hash(&mut s1); + let mut s2 = SipHasher::new(); + b.hash(&mut s2); + + assert_eq!(s1.finish(), s2.finish()); + + // Check projections + + assert_eq!(TypeId::of::(), other1::id_i32_iterator()); + assert_eq!(TypeId::of::(), other1::id_u32_iterator()); + assert_eq!(other1::id_i32_iterator(), other2::id_i32_iterator()); + assert_eq!(other1::id_u32_iterator(), other2::id_u32_iterator()); + assert_ne!(other1::id_i32_iterator(), other1::id_u32_iterator()); + assert_ne!(TypeId::of::(), TypeId::of::()); + + // Check fn pointer against collisions + assert_ne!( + TypeId::of:: A) -> A>(), + TypeId::of:: A, A) -> A>() + ); + assert_ne!( + TypeId::of:: fn(&'a i32) -> &'a i32>(), + TypeId::of:: fn(&'a i32) -> &'static i32>() + ); + assert_ne!( + TypeId::of:: fn(&'a i32, &'b i32) -> &'a i32>(), + TypeId::of:: fn(&'b i32, &'a i32) -> &'a i32>() + ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/typestate-cfg-nesting.rs b/gcc/testsuite/rust/rustc/ui/typestate-cfg-nesting.rs new file mode 100644 index 000000000000..eff3551a3582 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typestate-cfg-nesting.rs @@ -0,0 +1,21 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_assignments)] +#![allow(unknown_lints)] +// pretty-expanded FIXME #23616 + +#![allow(dead_assignment)] +#![allow(unused_variables)] + +fn f() { + let x = 10; let mut y = 11; + if true { match x { _ => { y = x; } } } else { } +} + +pub fn main() { + let x = 10; + let mut y = 11; + if true { while false { y = x; } } else { } +} + diff --git a/gcc/testsuite/rust/rustc/ui/typestate-multi-decl.rs b/gcc/testsuite/rust/rustc/ui/typestate-multi-decl.rs new file mode 100644 index 000000000000..f5e59e5f9929 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/typestate-multi-decl.rs @@ -0,0 +1,8 @@ +// run-pass + +pub fn main() { + let (x, y) = (10, 20); + let z = x + y; + assert_eq!(z, 30); +} + diff --git a/gcc/testsuite/rust/rustc/ui/ufcs-polymorphic-paths.rs b/gcc/testsuite/rust/rustc/ui/ufcs-polymorphic-paths.rs new file mode 100644 index 000000000000..51347c008146 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ufcs-polymorphic-paths.rs @@ -0,0 +1,155 @@ +// run-pass + +use std::borrow::{Cow, ToOwned}; +use std::default::Default; +use std::iter::FromIterator; +use std::ops::Add; +use std::option::IntoIter as OptionIter; + +pub struct XorShiftRng; +use XorShiftRng as DummyRng; +impl Rng for XorShiftRng {} +pub trait Rng {} +pub trait Rand: Default + Sized { + fn rand(_rng: &mut R) -> Self { Default::default() } +} +impl Rand for i32 { } + +pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { + fn into_cow(self) -> Cow<'a, B>; +} + +impl<'a> IntoCow<'a, str> for String { + fn into_cow(self) -> Cow<'a, str> { + Cow::Owned(self) + } +} + +#[derive(PartialEq, Eq)] +struct Newt(T); + +fn id(x: T) -> T { x } +fn eq(a: T, b: T) -> bool { a == b } +fn u8_as_i8(x: u8) -> i8 { x as i8 } +fn odd(x: usize) -> bool { x % 2 == 1 } +fn dummy_rng() -> DummyRng { XorShiftRng } + +trait Size: Sized { + fn size() -> usize { std::mem::size_of::() } +} +impl Size for T {} + +#[derive(PartialEq, Eq)] +struct BitVec; + +impl BitVec { + fn from_fn(_: usize, _: F) -> BitVec where F: FnMut(usize) -> bool { + BitVec + } +} + +#[derive(PartialEq, Eq)] +struct Foo(T); + +impl Foo { + fn map_in_place(self, mut f: F) -> Foo where F: FnMut(T) -> U { + Foo(f(self.0)) + } + +} + +macro_rules! tests { + ($($expr:expr, $ty:ty, ($($test:expr),*);)+) => (pub fn main() {$({ + const C: $ty = $expr; + static S: $ty = $expr; + assert!(eq(C($($test),*), $expr($($test),*))); + assert!(eq(S($($test),*), $expr($($test),*))); + assert!(eq(C($($test),*), S($($test),*))); + })+}) +} + +tests! { + // Free function. + id, fn(i32) -> i32, (5); + id::, fn(i32) -> i32, (5); + + // Enum variant constructor. + Some, fn(i32) -> Option, (5); + Some::, fn(i32) -> Option, (5); + + // Tuple struct constructor. + Newt, fn(i32) -> Newt, (5); + Newt::, fn(i32) -> Newt, (5); + + // Inherent static methods. + Vec::new, fn() -> Vec<()>, (); + Vec::<()>::new, fn() -> Vec<()>, (); + >::new, fn() -> Vec<()>, (); + Vec::with_capacity, fn(usize) -> Vec<()>, (5); + Vec::<()>::with_capacity, fn(usize) -> Vec<()>, (5); + >::with_capacity, fn(usize) -> Vec<()>, (5); + BitVec::from_fn, fn(usize, fn(usize) -> bool) -> BitVec, (5, odd); + BitVec::from_fn:: bool>, fn(usize, fn(usize) -> bool) -> BitVec, (5, odd); + + // Inherent non-static method. + Foo::map_in_place, fn(Foo, fn(u8) -> i8) -> Foo, (Foo(b'f'), u8_as_i8); + Foo::map_in_place:: i8>, fn(Foo, fn(u8) -> i8) -> Foo, + (Foo(b'f'), u8_as_i8); + Foo::::map_in_place, fn(Foo, fn(u8) -> i8) -> Foo + , (Foo(b'f'), u8_as_i8); + Foo::::map_in_place:: i8>, fn(Foo, fn(u8) -> i8) -> Foo + , (Foo(b'f'), u8_as_i8); + + // Trait static methods. + bool::size, fn() -> usize, (); + ::size, fn() -> usize, (); + ::size, fn() -> usize, (); + + Default::default, fn() -> i32, (); + i32::default, fn() -> i32, (); + ::default, fn() -> i32, (); + ::default, fn() -> i32, (); + + Rand::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng()); + i32::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng()); + ::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng()); + ::rand, fn(&mut DummyRng) -> i32, (&mut dummy_rng()); + Rand::rand::, fn(&mut DummyRng) -> i32, (&mut dummy_rng()); + i32::rand::, fn(&mut DummyRng) -> i32, (&mut dummy_rng()); + ::rand::, fn(&mut DummyRng) -> i32, (&mut dummy_rng()); + ::rand::, fn(&mut DummyRng) -> i32, (&mut dummy_rng()); + + // Trait non-static methods. + Clone::clone, fn(&i32) -> i32, (&5); + i32::clone, fn(&i32) -> i32, (&5); + ::clone, fn(&i32) -> i32, (&5); + ::clone, fn(&i32) -> i32, (&5); + + FromIterator::from_iter, fn(OptionIter) -> Vec, (Some(5).into_iter()); + Vec::from_iter, fn(OptionIter) -> Vec, (Some(5).into_iter()); + >::from_iter, fn(OptionIter) -> Vec, (Some(5).into_iter()); + as FromIterator<_>>::from_iter, fn(OptionIter) -> Vec, + (Some(5).into_iter()); + as FromIterator<_>>::from_iter, fn(OptionIter) -> Vec, + (Some(5).into_iter()); + FromIterator::from_iter::>, fn(OptionIter) -> Vec, + (Some(5).into_iter()); + as FromIterator<_>>::from_iter::>, fn(OptionIter) -> Vec, + (Some(5).into_iter()); + + Add::add, fn(i32, i32) -> i32, (5, 6); + i32::add, fn(i32, i32) -> i32, (5, 6); + ::add, fn(i32, i32) -> i32, (5, 6); + >::add, fn(i32, i32) -> i32, (5, 6); + >::add, fn(i32, i32) -> i32, (5, 6); + + String::into_cow, fn(String) -> Cow<'static, str>, + ("foo".to_string()); + ::into_cow, fn(String) -> Cow<'static, str>, + ("foo".to_string()); + >::into_cow, fn(String) -> Cow<'static, str>, + ("foo".to_string()); + >::into_cow, fn(String) -> Cow<'static, str>, + ("foo".to_string()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/ufcs-type-params.rs b/gcc/testsuite/rust/rustc/ui/ufcs-type-params.rs new file mode 100644 index 000000000000..ef4063dbefb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ufcs-type-params.rs @@ -0,0 +1,16 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Foo { + fn get(&self) -> T; +} + +impl Foo for i32 { + fn get(&self) -> i32 { *self } +} + +fn main() { + let x: i32 = 1; + Foo::::get(&x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/ufcs/ufcs-explicit-self-bad.rs b/gcc/testsuite/rust/rustc/ui/ufcs/ufcs-explicit-self-bad.rs new file mode 100644 index 000000000000..87ba086eb07d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ufcs/ufcs-explicit-self-bad.rs @@ -0,0 +1,60 @@ +#![feature(box_syntax)] + +struct Foo { + f: isize, +} + +impl Foo { + fn foo(self: isize, x: isize) -> isize { +// { dg-error ".E0307." "" { target *-*-* } .-1 } + self.f + x + } +} + +struct Bar { + f: T, +} + +impl Bar { + fn foo(self: Bar, x: isize) -> isize { +// { dg-error ".E0307." "" { target *-*-* } .-1 } + x + } + fn bar(self: &Bar, x: isize) -> isize { +// { dg-error ".E0307." "" { target *-*-* } .-1 } + x + } +} + +trait SomeTrait { + fn dummy1(&self); + fn dummy2(&self); + fn dummy3(&self); +} + +impl<'a, T> SomeTrait for &'a Bar { + fn dummy1(self: &&'a Bar) { } + fn dummy2(self: &Bar) {} // { dg-error ".E0308." "" { target *-*-* } } +// { dg-error ".E0308." "" { target *-*-* } .-1 } + fn dummy3(self: &&Bar) {} +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } +// { dg-error ".E0308." "" { target *-*-* } .-6 } +// { dg-error ".E0308." "" { target *-*-* } .-7 } +// { dg-error ".E0308." "" { target *-*-* } .-8 } +} + +fn main() { + let foo = box Foo { + f: 1, + }; + println!("{}", foo.foo(2)); + let bar = box Bar { + f: 1, + }; + println!("{} {}", bar.foo(2), bar.bar(2)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/ufcs/ufcs-partially-resolved.rs b/gcc/testsuite/rust/rustc/ui/ufcs/ufcs-partially-resolved.rs new file mode 100644 index 000000000000..76145f5231dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ufcs/ufcs-partially-resolved.rs @@ -0,0 +1,57 @@ +#![feature(associated_type_defaults)] + +trait Tr { + type Y = u16; + fn Y() {} +} +impl Tr for u8 {} + +trait Dr { + type X = u16; + fn Z() {} +} +impl Dr for u8 {} + +enum E { Y } +type A = u32; + +fn main() { + let _: ::N; // { dg-error ".E0576." "" { target *-*-* } } + let _: ::N; // { dg-error ".E0576." "" { target *-*-* } } + let _: ::N; // { dg-error ".E0576." "" { target *-*-* } } + ::N; // { dg-error ".E0576." "" { target *-*-* } } + ::N; // { dg-error ".E0576." "" { target *-*-* } } + ::N; // { dg-error ".E0576." "" { target *-*-* } } + let _: ::Y; // OK + let _: ::Y; // { dg-error ".E0575." "" { target *-*-* } } + ::Y; // OK + ::Y; // { dg-error ".E0575." "" { target *-*-* } } + + let _: ::N::NN; // { dg-error ".E0576." "" { target *-*-* } } + let _: ::N::NN; // { dg-error ".E0576." "" { target *-*-* } } + let _: ::N::NN; // { dg-error ".E0576." "" { target *-*-* } } + ::N::NN; // { dg-error ".E0576." "" { target *-*-* } } + ::N::NN; // { dg-error ".E0576." "" { target *-*-* } } + ::N::NN; // { dg-error ".E0576." "" { target *-*-* } } + let _: ::Y::NN; // { dg-error ".E0223." "" { target *-*-* } } + let _: ::Y::NN; // { dg-error ".E0575." "" { target *-*-* } } + ::Y::NN; // { dg-error ".E0599." "" { target *-*-* } } + ::Y::NN; // { dg-error ".E0575." "" { target *-*-* } } + + let _: ::NN; // { dg-error ".E0576." "" { target *-*-* } } + let _: ::NN; // { dg-error ".E0576." "" { target *-*-* } } + let _: ::NN; // { dg-error ".E0576." "" { target *-*-* } } + ::NN; // { dg-error ".E0576." "" { target *-*-* } } + ::NN; // { dg-error ".E0576." "" { target *-*-* } } + ::NN; // { dg-error ".E0576." "" { target *-*-* } } + let _: ::NN; // { dg-error ".E0576." "" { target *-*-* } } + let _: ::NN; // { dg-error ".E0433." "" { target *-*-* } } + ::NN; // { dg-error ".E0576." "" { target *-*-* } } + ::NN; // { dg-error ".E0433." "" { target *-*-* } } + + let _: ::Z; // { dg-error ".E0575." "" { target *-*-* } } + ::X; // { dg-error ".E0575." "" { target *-*-* } } + let _: ::Z::N; // { dg-error ".E0575." "" { target *-*-* } } + ::X::N; // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/ufcs/ufcs-qpath-missing-params.rs b/gcc/testsuite/rust/rustc/ui/ufcs/ufcs-qpath-missing-params.rs new file mode 100644 index 000000000000..e6fc1d096dd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ufcs/ufcs-qpath-missing-params.rs @@ -0,0 +1,17 @@ +use std::borrow::Cow; + +pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { + fn into_cow(self) -> Cow<'a, B>; +} + +impl<'a> IntoCow<'a, str> for String { + fn into_cow(self) -> Cow<'a, str> { + Cow::Owned(self) + } +} + +fn main() { + ::into_cow("foo".to_string()); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/ufcs/ufcs-qpath-self-mismatch.rs b/gcc/testsuite/rust/rustc/ui/ufcs/ufcs-qpath-self-mismatch.rs new file mode 100644 index 000000000000..9e454f28726a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ufcs/ufcs-qpath-self-mismatch.rs @@ -0,0 +1,11 @@ +use std::ops::Add; + +fn main() { + >::add(1, 2); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + >::add(1u32, 2); +// { dg-error ".E0308." "" { target *-*-* } .-1 } + >::add(1, 2u32); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/ui-testing-optout.rs b/gcc/testsuite/rust/rustc/ui/ui-testing-optout.rs new file mode 100644 index 000000000000..5e905cbb76f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/ui-testing-optout.rs @@ -0,0 +1,95 @@ +// compile-flags: -Z ui-testing=no + +// Line number < 10 +type A = B; // { dg-error ".E0412." "" { target *-*-* } } + +// Line number >=10, <100 +type C = D; // { dg-error ".E0412." "" { target *-*-* } } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// Line num >=100 +type E = F; // { dg-error ".E0412." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unary-minus-suffix-inference.rs b/gcc/testsuite/rust/rustc/ui/unary-minus-suffix-inference.rs new file mode 100644 index 000000000000..98df661e93ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unary-minus-suffix-inference.rs @@ -0,0 +1,24 @@ +// run-pass + +pub fn main() { + let a = 1; + let a_neg: i8 = -a; + println!("{}", a_neg); + + let b = 1; + let b_neg: i16 = -b; + println!("{}", b_neg); + + let c = 1; + let c_neg: i32 = -c; + println!("{}", c_neg); + + let d = 1; + let d_neg: i64 = -d; + println!("{}", d_neg); + + let e = 1; + let e_neg: isize = -e; + println!("{}", e_neg); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs new file mode 100644 index 000000000000..8b2055b6842c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/auxiliary/unboxed-closures-cross-crate.rs @@ -0,0 +1,17 @@ +use std::ops::Add; + +#[inline] +pub fn has_closures() -> usize { + let x = 1; + let mut f = move || x; + let y = 1; + let g = || y; + f() + g() +} + +pub fn has_generic_closures + Copy>(x: T, y: T) -> T { + let mut f = move || x; + let g = || y; + f() + g() +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/issue-30906.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/issue-30906.rs new file mode 100644 index 000000000000..ee086dd72a95 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/issue-30906.rs @@ -0,0 +1,19 @@ +#![feature(fn_traits, unboxed_closures)] + +fn test FnOnce<(&'x str,)>>(_: F) {} + +struct Compose(F,G); +impl FnOnce<(T,)> for Compose +where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> { + type Output = G::Output; + extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output { + (self.1)((self.0)(x)) + } +} + +fn bad(f: fn(&'static str) -> T) { + test(Compose(f, |_| {})); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/issue-53448.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/issue-53448.rs new file mode 100644 index 000000000000..d6c16a644365 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/issue-53448.rs @@ -0,0 +1,16 @@ +#![feature(unboxed_closures)] + +trait Lt<'a> { + type T; +} +impl<'a> Lt<'a> for () { + type T = (); +} + +fn main() { + let v: <() as Lt<'_>>::T = (); + let f: &mut dyn FnMut<(_,), Output = ()> = &mut |_: <() as Lt<'_>>::T| {}; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + f(v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-feature-gate.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-feature-gate.rs new file mode 100644 index 000000000000..2edd15e5baa4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-feature-gate.rs @@ -0,0 +1,21 @@ +// Check that parenthetical notation is feature-gated except with the +// `Fn` traits. + +use std::marker; + +trait Foo { + type Output; + + fn dummy(&self, a: A) { } +} + +fn main() { + let x: Box; +// { dg-error ".E0658." "" { target *-*-* } .-1 } + + // No errors with these: + let x: Box; + let x: Box; + let x: Box; +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-illegal-move.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-illegal-move.rs new file mode 100644 index 000000000000..46d897ddf558 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-illegal-move.rs @@ -0,0 +1,39 @@ +#![feature(unboxed_closures)] + +// Tests that we can't move out of an unboxed closure environment +// if the upvar is captured by ref or the closure takes self by +// reference. + +fn to_fn>(f: F) -> F { f } +fn to_fn_mut>(f: F) -> F { f } +fn to_fn_once>(f: F) -> F { f } + +fn main() { + // By-ref cases + { + let x = Box::new(0); + let f = to_fn(|| drop(x)); // { dg-error ".E0507." "" { target *-*-* } } + } + { + let x = Box::new(0); + let f = to_fn_mut(|| drop(x)); // { dg-error ".E0507." "" { target *-*-* } } + } + { + let x = Box::new(0); + let f = to_fn_once(|| drop(x)); // OK -- FnOnce + } + // By-value cases + { + let x = Box::new(0); + let f = to_fn(move || drop(x)); // { dg-error ".E0507." "" { target *-*-* } } + } + { + let x = Box::new(0); + let f = to_fn_mut(move || drop(x)); // { dg-error ".E0507." "" { target *-*-* } } + } + { + let x = Box::new(0); + let f = to_fn_once(move || drop(x)); // this one is ok + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-immutable-capture.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-immutable-capture.rs new file mode 100644 index 000000000000..fcb42cdabe26 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-immutable-capture.rs @@ -0,0 +1,18 @@ +// Test that even unboxed closures that are capable of mutating their +// environment cannot mutate captured variables that have not been +// declared mutable (#18335) + +fn set(x: &mut usize) { *x = 0; } + +fn main() { + let x = 0; + move || x = 1; // { dg-error ".E0594." "" { target *-*-* } } + move || set(&mut x); // { dg-error ".E0596." "" { target *-*-* } } + move || x = 1; // { dg-error ".E0594." "" { target *-*-* } } + move || set(&mut x); // { dg-error ".E0596." "" { target *-*-* } } + || x = 1; // { dg-error ".E0594." "" { target *-*-* } } + || set(&mut x); // { dg-error ".E0596." "" { target *-*-* } } + || x = 1; // { dg-error ".E0594." "" { target *-*-* } } + || set(&mut x); // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.rs new file mode 100644 index 000000000000..356ea51abf4c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-no-cyclic-sig.rs @@ -0,0 +1,10 @@ +// Test that unboxed closures cannot capture their own type. +// +// Also regression test for issue #21410. + +fn g(_: F) where F: FnOnce(Option) {} + +fn main() { + g(|_| { }); // { dg-error ".E0644." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-region.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-region.rs new file mode 100644 index 000000000000..2f7249a0cc29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-region.rs @@ -0,0 +1,12 @@ +// Test that an unboxed closure that captures a free variable by +// reference cannot escape the region of that variable. + + +fn main() { + let _f = { + let x = 0; + || x // { dg-error ".E0597." "" { target *-*-* } } + }; + _f; +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-default.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-default.rs new file mode 100644 index 000000000000..9b99ff561113 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-default.rs @@ -0,0 +1,29 @@ +// Test interaction between unboxed closure sugar and default type +// parameters (should be exactly as if angle brackets were used). + +#![feature(unboxed_closures)] +#![allow(dead_code)] + +trait Foo { + type Output; + fn dummy(&self, t: T, v: V); +} + +trait Eq { fn same_types(&self, x: &X) -> bool { true } } +impl Eq for X { } +fn eq() where A : Eq { } + +fn test<'a,'b>() { + // Parens are equivalent to omitting default in angle. + eq::, dyn Foo(isize)>(); + + // In angle version, we supply something other than the default + eq::, dyn Foo(isize)>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // Supply default explicitly. + eq::, dyn Foo(isize)>(); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-equiv.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-equiv.rs new file mode 100644 index 000000000000..1e32d57a3489 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-equiv.rs @@ -0,0 +1,49 @@ +// Test that the unboxed closure sugar can be used with an arbitrary +// struct type and that it is equivalent to the same syntax using +// angle brackets. This test covers only simple types and in +// particular doesn't test bound regions. + +#![feature(unboxed_closures)] +#![allow(dead_code)] + +trait Foo { + type Output; + fn dummy(&self, t: T, u: Self::Output); +} + +trait Eq { } +impl Eq for X { } +fn eq>() { } + +fn test<'a,'b>() { + // No errors expected: + eq::< dyn Foo<(),Output=()>, dyn Foo() >(); + eq::< dyn Foo<(isize,),Output=()>, dyn Foo(isize) >(); + eq::< dyn Foo<(isize,usize),Output=()>, dyn Foo(isize,usize) >(); + eq::< dyn Foo<(isize,usize),Output=usize>, dyn Foo(isize,usize) -> usize >(); + eq::< dyn Foo<(&'a isize,&'b usize),Output=usize>, dyn Foo(&'a isize,&'b usize) -> usize >(); + + // Test that anonymous regions in `()` form are equivalent + // to fresh bound regions, and that we can intermingle + // named and anonymous as we choose: + eq::< dyn for<'x,'y> Foo<(&'x isize,&'y usize),Output=usize>, + dyn for<'x,'y> Foo(&'x isize,&'y usize) -> usize >(); + eq::< dyn for<'x,'y> Foo<(&'x isize,&'y usize),Output=usize>, + dyn for<'x> Foo(&'x isize,&usize) -> usize >(); + eq::< dyn for<'x,'y> Foo<(&'x isize,&'y usize),Output=usize>, + dyn for<'y> Foo(&isize,&'y usize) -> usize >(); + eq::< dyn for<'x,'y> Foo<(&'x isize,&'y usize),Output=usize>, + dyn Foo(&isize,&usize) -> usize >(); + + // lifetime elision + eq::< dyn for<'x> Foo<(&'x isize,), Output=&'x isize>, + dyn Foo(&isize) -> &isize >(); + + // Errors expected: + eq::< dyn Foo<(),Output=()>, + dyn Foo(char) >(); +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.rs new file mode 100644 index 000000000000..5229e6cbc788 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.rs @@ -0,0 +1,28 @@ +// Test that the unboxed closure sugar can be used with an arbitrary +// struct type and that it is equivalent to the same syntax using +// angle brackets. This test covers only simple types and in +// particular doesn't test bound regions. + +#![feature(unboxed_closures)] +#![allow(dead_code)] + +use std::marker; + +trait Foo { + type Output; + fn dummy(&self, t: T); +} + +trait Eq { } +impl Eq for X { } +fn eq>() { } + +fn main() { + eq::< dyn for<'a> Foo<(&'a isize,), Output=&'a isize>, + dyn Foo(&isize) -> &isize >(); + eq::< dyn for<'a> Foo<(&'a isize,), Output=(&'a isize, &'a isize)>, + dyn Foo(&isize) -> (&isize, &isize) >(); + + let _: dyn Foo(&isize, &usize) -> &usize; // { dg-error ".E0106." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.rs new file mode 100644 index 000000000000..6ce4c67a3482 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-not-used-on-fn.rs @@ -0,0 +1,12 @@ +// Test that the `Fn` traits require `()` form without a feature gate. + +fn bar1(x: &dyn Fn<(), Output=()>) { +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +fn bar2(x: &T) where T: Fn<()> { +// { dg-error ".E0658." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-region.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-region.rs new file mode 100644 index 000000000000..97b9665c915d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-region.rs @@ -0,0 +1,37 @@ +// Test interaction between unboxed closure sugar and region +// parameters (should be exactly as if angle brackets were used +// and regions omitted). + +#![feature(unboxed_closures)] +#![allow(dead_code)] + +use std::marker; + +trait Foo<'a,T> { + type Output; + fn dummy(&'a self) -> &'a (T,Self::Output); +} + +trait Eq { fn is_of_eq_type(&self, x: &X) -> bool { true } } +impl Eq for X { } +fn eq>() { } + +fn same_type>(a: A, b: B) { } + +fn test<'a,'b>() { + // Parens are equivalent to omitting default in angle. + eq::< dyn Foo<(isize,),Output=()>, dyn Foo(isize) >(); + + // Here we specify 'static explicitly in angle-bracket version. + // Parenthesized winds up getting inferred. + eq::< dyn Foo<'static, (isize,),Output=()>, dyn Foo(isize) >(); +} + +fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) { +// { dg-error ".E0107." "" { target *-*-* } .-1 } + // Here, the omitted lifetimes are expanded to distinct things. + same_type(x, y) +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs new file mode 100644 index 000000000000..8452c668f5da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs @@ -0,0 +1,14 @@ +// Test that parentheses form doesn't work with struct types appearing in local variables. + +struct Bar { + f: A +} + +fn bar() { + let x: Box = panic!(); +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs new file mode 100644 index 000000000000..80f81dba0e58 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.rs @@ -0,0 +1,19 @@ +// Test that parentheses form parses in expression paths. + +struct Bar { + f: A, r: R +} + +impl Bar { + fn new() -> Bar { panic!() } +} + +fn bar() { + let b = Bar::::new(); // OK + + let b = Bar::(isize, usize)::new(); // OK too (for the parser) +// { dg-error ".E0214." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs new file mode 100644 index 000000000000..68fa9ac2ffa3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs @@ -0,0 +1,13 @@ +// Test that parentheses form doesn't work with struct types appearing in argument types. + +struct Bar { + f: A +} + +fn foo(b: Box) { +// { dg-error ".E0107." "" { target *-*-* } .-1 } +// { dg-error ".E0107." "" { target *-*-* } .-2 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-1.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-1.rs new file mode 100644 index 000000000000..9118f872c6e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-1.rs @@ -0,0 +1,9 @@ +#![feature(unboxed_closures)] + +trait One { fn foo(&self) -> A; } + +fn foo(_: &dyn One()) // { dg-error ".E0220." "" { target *-*-* } } +{} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs new file mode 100644 index 000000000000..315f80f44a69 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs @@ -0,0 +1,11 @@ +#![feature(unboxed_closures)] + +trait Three { fn dummy(&self) -> (A,B,C); } + +fn foo(_: &dyn Three()) +// { dg-error ".E0220." "" { target *-*-* } .-1 } +// { dg-error ".E0220." "" { target *-*-* } .-2 } +{} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs new file mode 100644 index 000000000000..f6889f0477eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs @@ -0,0 +1,11 @@ +#![feature(unboxed_closures)] + +trait Zero { fn dummy(&self); } + +fn foo(_: dyn Zero()) +// { dg-error ".E0220." "" { target *-*-* } .-1 } +// { dg-error ".E0220." "" { target *-*-* } .-2 } +{} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs new file mode 100644 index 000000000000..786cc0e165e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs @@ -0,0 +1,10 @@ +#![feature(unboxed_closures)] + +trait Trait {} + +fn f isize>(x: F) {} +// { dg-error ".E0220." "" { target *-*-* } .-1 } +// { dg-error ".E0220." "" { target *-*-* } .-2 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-all-traits.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-all-traits.rs new file mode 100644 index 000000000000..a7d576e0a96f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-all-traits.rs @@ -0,0 +1,22 @@ +// run-pass +#![feature(lang_items)] + +fn a isize>(f: F) -> isize { + f(1, 2) +} + +fn b isize>(mut f: F) -> isize { + f(3, 4) +} + +fn c isize>(f: F) -> isize { + f(5, 6) +} + +fn main() { + let z: isize = 7; + assert_eq!(a(move |x: isize, y| x + y + z), 10); + assert_eq!(b(move |x: isize, y| x + y + z), 14); + assert_eq!(c(move |x: isize, y| x + y + z), 18); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs new file mode 100644 index 000000000000..b61291f1353c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(unused_variables)] +// Test that you can supply `&F` where `F: FnMut()`. + +#![feature(lang_items)] + +fn a i32>(mut f: F) -> i32 { + f() +} + +fn b(f: &mut dyn FnMut() -> i32) -> i32 { + a(f) +} + +fn c i32>(f: &mut F) -> i32 { + a(f) +} + +fn main() { + let z: isize = 7; + + let x = b(&mut || 22); + assert_eq!(x, 22); + + let x = c(&mut || 22); + assert_eq!(x, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-blanket-fn.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-blanket-fn.rs new file mode 100644 index 000000000000..b3d659f747a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-blanket-fn.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(unused_variables)] +// Test that you can supply `&F` where `F: Fn()`. + +#![feature(lang_items)] + +fn a i32>(f: F) -> i32 { + f() +} + +fn b(f: &dyn Fn() -> i32) -> i32 { + a(f) +} + +fn c i32>(f: &F) -> i32 { + a(f) +} + +fn main() { + let z: isize = 7; + + let x = b(&|| 22); + assert_eq!(x, 22); + + let x = c(&|| 22); + assert_eq!(x, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-borrow-conflict.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-borrow-conflict.rs new file mode 100644 index 000000000000..9d5e6c43b5b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-borrow-conflict.rs @@ -0,0 +1,12 @@ +// Test that an unboxed closure that mutates a free variable will +// cause borrow conflicts. + + + +fn main() { + let mut x = 0; + let f = || x += 1; + let _y = x; // { dg-error ".E0503." "" { target *-*-* } } + f; +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-boxed.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-boxed.rs new file mode 100644 index 000000000000..375700080352 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-boxed.rs @@ -0,0 +1,17 @@ +// run-pass +#![feature(box_syntax)] + +use std::ops::FnMut; + + fn make_adder(x: i32) -> Boxi32+'static> { + (box move |y: i32| -> i32 { x + y }) as + Boxi32+'static> +} + +pub fn main() { + let mut adder = make_adder(3); + let z = adder(2); + println!("{}", z); + assert_eq!(z, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-by-ref.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-by-ref.rs new file mode 100644 index 000000000000..7e6e9f0e0e14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-by-ref.rs @@ -0,0 +1,25 @@ +// run-pass +// Test by-ref capture of environment in unboxed closure types + +fn call_fn(f: F) { + f() +} + +fn call_fn_mut(mut f: F) { + f() +} + +fn call_fn_once(f: F) { + f() +} + +fn main() { + let mut x = 0_usize; + let y = 2_usize; + + call_fn(|| assert_eq!(x, 0)); + call_fn_mut(|| x += y); + call_fn_once(|| x += y); + assert_eq!(x, y * 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-fn-autoderef.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-fn-autoderef.rs new file mode 100644 index 000000000000..ebbc9fee8346 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-fn-autoderef.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(unused_imports)] +// Test that the call operator autoderefs when calling a bounded type parameter. + +use std::ops::FnMut; + +fn call_with_2(x: &fn(isize) -> isize) -> isize +{ + x(2) // look ma, no `*` +} + +fn subtract_22(x: isize) -> isize { x - 22 } + +pub fn main() { + let subtract_22: fn(isize) -> isize = subtract_22; + let z = call_with_2(&subtract_22); + assert_eq!(z, -20); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs new file mode 100644 index 000000000000..5af3c63cf5e6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-autoderef.rs @@ -0,0 +1,16 @@ +// run-pass +// Test that the call operator autoderefs when calling a bounded type parameter. + +use std::ops::FnMut; + +fn call_with_2(x: &mut F) -> isize + where F : FnMut(isize) -> isize +{ + x(2) // look ma, no `*` +} + +pub fn main() { + let z = call_with_2(&mut |x| x - 22); + assert_eq!(z, -20); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs new file mode 100644 index 000000000000..f9f01316d135 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-object-autoderef.rs @@ -0,0 +1,16 @@ +// run-pass +// Test that the call operator autoderefs when calling to an object type. + +use std::ops::FnMut; + +fn make_adder(x: isize) -> Boxisize + 'static> { + Box::new(move |y| { x + y }) +} + +pub fn main() { + let mut adder = make_adder(3); + let z = adder(2); + println!("{}", z); + assert_eq!(z, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-object.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-object.rs new file mode 100644 index 000000000000..aeb430b4e95d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-call-sugar-object.rs @@ -0,0 +1,14 @@ +// run-pass +use std::ops::FnMut; + +fn make_adder(x: isize) -> Boxisize + 'static> { + Box::new(move |y| { x + y }) +} + +pub fn main() { + let mut adder = make_adder(3); + let z = (*adder)(2); + println!("{}", z); + assert_eq!(z, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs new file mode 100644 index 000000000000..a526fde4211b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs @@ -0,0 +1,29 @@ +// run-pass +// Test that we mutate a counter on the stack only when we expect to. + +fn call(f: F) where F : FnOnce() { + f(); +} + +fn main() { + let y = vec![format!("Hello"), format!("World")]; + let mut counter = 22_u32; + + call(|| { + // Move `y`, but do not move `counter`, even though it is read + // by value (note that it is also mutated). + for item in y { // { dg-warning "" "" { target *-*-* } } + let v = counter; + counter += v; + } + }); + assert_eq!(counter, 88); + + call(move || { + // this mutates a moved copy, and hence doesn't affect original + counter += 1; // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } + }); + assert_eq!(counter, 88); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-cross-crate.rs new file mode 100644 index 000000000000..3eb0597b0e0c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-cross-crate.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(non_camel_case_types)] + +// Test that unboxed closures work with cross-crate inlining +// Acts as a regression test for #16790, #18378 and #18543 + +// aux-build:unboxed-closures-cross-crate.rs + +extern crate unboxed_closures_cross_crate as ubcc; + +fn main() { + assert_eq!(ubcc::has_closures(), 2_usize); + assert_eq!(ubcc::has_generic_closures(2_usize, 3_usize), 5_usize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs new file mode 100644 index 000000000000..f4f15540a6f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-direct-sugary-call.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(unused_mut)] +// pretty-expanded FIXME #23616 + +fn main() { + let mut unboxed = || {}; + unboxed(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-drop.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-drop.rs new file mode 100644 index 000000000000..681a79d929e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-drop.rs @@ -0,0 +1,118 @@ +// run-pass +#![allow(path_statements)] +#![allow(dead_code)] +// A battery of tests to ensure destructors of unboxed closure environments +// run at the right times. + +static mut DROP_COUNT: usize = 0; + +fn drop_count() -> usize { + unsafe { + DROP_COUNT + } +} + +struct Droppable { + x: isize, +} + +impl Droppable { + fn new() -> Droppable { + Droppable { + x: 1 + } + } +} + +impl Drop for Droppable { + fn drop(&mut self) { + unsafe { + DROP_COUNT += 1 + } + } +} + +fn a isize>(f: F) -> isize { + f(1, 2) +} + +fn b isize>(mut f: F) -> isize { + f(3, 4) +} + +fn c isize>(f: F) -> isize { + f(5, 6) +} + +fn test_fn() { + { + a(move |a: isize, b| { a + b }); + } + assert_eq!(drop_count(), 0); + + { + let z = &Droppable::new(); + a(move |a: isize, b| { z; a + b }); + assert_eq!(drop_count(), 0); + } + assert_eq!(drop_count(), 1); + + { + let z = &Droppable::new(); + let zz = &Droppable::new(); + a(move |a: isize, b| { z; zz; a + b }); + assert_eq!(drop_count(), 1); + } + assert_eq!(drop_count(), 3); +} + +fn test_fn_mut() { + { + b(move |a: isize, b| { a + b }); + } + assert_eq!(drop_count(), 3); + + { + let z = &Droppable::new(); + b(move |a: isize, b| { z; a + b }); + assert_eq!(drop_count(), 3); + } + assert_eq!(drop_count(), 4); + + { + let z = &Droppable::new(); + let zz = &Droppable::new(); + b(move |a: isize, b| { z; zz; a + b }); + assert_eq!(drop_count(), 4); + } + assert_eq!(drop_count(), 6); +} + +fn test_fn_once() { + { + c(move |a: isize, b| { a + b }); + } + assert_eq!(drop_count(), 6); + + { + let z = Droppable::new(); + c(move |a: isize, b| { z; a + b }); + assert_eq!(drop_count(), 7); + } + assert_eq!(drop_count(), 7); + + { + let z = Droppable::new(); + let zz = Droppable::new(); + c(move |a: isize, b| { z; zz; a + b }); + assert_eq!(drop_count(), 9); + } + assert_eq!(drop_count(), 9); +} + +fn main() { + test_fn(); + test_fn_mut(); + test_fn_once(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-extern-fn-hr.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-extern-fn-hr.rs new file mode 100644 index 000000000000..9593d9ab81d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-extern-fn-hr.rs @@ -0,0 +1,32 @@ +// run-pass +// Checks that higher-ranked extern fn pointers implement the full range of Fn traits. + +fn square(x: &isize) -> isize { (*x) * (*x) } + +fn call_itisize>(f: &F, x: isize) -> isize { + (*f)(&x) +} + +fn call_it_boxed(f: &dyn Fn(&isize) -> isize, x: isize) -> isize { + f(&x) +} + +fn call_it_mutisize>(f: &mut F, x: isize) -> isize { + (*f)(&x) +} + +fn call_it_onceisize>(f: F, x: isize) -> isize { + f(&x) +} + +fn main() { + let x = call_it(&square, 22); + let x1 = call_it_boxed(&square, 22); + let y = call_it_mut(&mut square, 22); + let z = call_it_once(square, 22); + assert_eq!(x, square(&22)); + assert_eq!(x1, square(&22)); + assert_eq!(y, square(&22)); + assert_eq!(z, square(&22)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-extern-fn.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-extern-fn.rs new file mode 100644 index 000000000000..c20e342a8510 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-extern-fn.rs @@ -0,0 +1,28 @@ +// run-pass +// Checks that extern fn pointers implement the full range of Fn traits. + +use std::ops::{Fn,FnMut,FnOnce}; + +fn square(x: isize) -> isize { x * x } + +fn call_itisize>(f: &F, x: isize) -> isize { + f(x) +} + +fn call_it_mutisize>(f: &mut F, x: isize) -> isize { + f(x) +} + +fn call_it_onceisize>(f: F, x: isize) -> isize { + f(x) +} + +fn main() { + let x = call_it(&square, 22); + let y = call_it_mut(&mut square, 22); + let z = call_it_once(square, 22); + assert_eq!(x, square(22)); + assert_eq!(y, square(22)); + assert_eq!(z, square(22)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.rs new file mode 100644 index 000000000000..324654b4de3b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.rs @@ -0,0 +1,38 @@ +// Various unsuccessful attempts to put the unboxed closure kind +// inference into an awkward position that might require fixed point +// iteration (basically where inferring the kind of a closure `c` +// would require knowing the kind of `c`). I currently believe this is +// impossible. + +fn a() { + // This case of recursion wouldn't even require fixed-point + // iteration, but it still doesn't work. The weird structure with + // the `Option` is to avoid giving any useful hints about the `Fn` + // kind via the expected type. + let mut factorial: Option u32>> = None; + + let f = |x: u32| -> u32 { + let g = factorial.as_ref().unwrap(); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + if x == 0 {1} else {x * g(x-1)} + }; + + factorial = Some(Box::new(f)); +// { dg-error ".E0506." "" { target *-*-* } .-1 } +} + +fn b() { + let mut factorial: Option u32 + 'static>> = None; + + let f = |x: u32| -> u32 { + let g = factorial.as_ref().unwrap(); +// { dg-error ".E0597." "" { target *-*-* } .-1 } + if x == 0 {1} else {x * g(x-1)} + }; + + factorial = Some(Box::new(f)); +// { dg-error ".E0506." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.rs new file mode 100644 index 000000000000..6965eb3ce46f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.rs @@ -0,0 +1,30 @@ +// Various unsuccessful attempts to put the unboxed closure kind +// inference into an awkward position that might require fixed point +// iteration (basically where inferring the kind of a closure `c` +// would require knowing the kind of `c`). I currently believe this is +// impossible. + +fn a() { + let mut closure0 = None; + let vec = vec![1, 2, 3]; + + loop { + { + let closure1 = || { + match closure0.take() { + Some(c) => { + return c(); +// { dg-error ".E0282." "" { target *-*-* } .-1 } + } + None => { } + } + }; + closure1(); + } + + closure0 = || vec; + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs new file mode 100644 index 000000000000..3656d1839fcf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-fn-as-fnmut-and-fnonce.rs @@ -0,0 +1,45 @@ +// run-pass +// Checks that the Fn trait hierarchy rules permit +// any Fn trait to be used where Fn is implemented. + +#![feature(unboxed_closures, fn_traits)] + +use std::ops::{Fn,FnMut,FnOnce}; + +struct S; + +impl Fn<(i32,)> for S { + extern "rust-call" fn call(&self, (x,): (i32,)) -> i32 { + x * x + } +} + +impl FnMut<(i32,)> for S { + extern "rust-call" fn call_mut(&mut self, args: (i32,)) -> i32 { self.call(args) } +} + +impl FnOnce<(i32,)> for S { + type Output = i32; + extern "rust-call" fn call_once(self, args: (i32,)) -> i32 { self.call(args) } +} + +fn call_iti32>(f: &F, x: i32) -> i32 { + f(x) +} + +fn call_it_muti32>(f: &mut F, x: i32) -> i32 { + f(x) +} + +fn call_it_oncei32>(f: F, x: i32) -> i32 { + f(x) +} + +fn main() { + let x = call_it(&S, 22); + let y = call_it_mut(&mut S, 22); + let z = call_it_once(S, 22); + assert_eq!(x, y); + assert_eq!(y, z); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.rs new file mode 100644 index 000000000000..9f79bb6b1a56 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.rs @@ -0,0 +1,31 @@ +// Checks that the Fn trait hierarchy rules do not permit +// Fn to be used where FnMut is implemented. + +#![feature(fn_traits, unboxed_closures)] +#![feature(overloaded_calls)] + +use std::ops::{Fn,FnMut,FnOnce}; + +struct S; + +impl FnMut<(isize,)> for S { + extern "rust-call" fn call_mut(&mut self, (x,): (isize,)) -> isize { + x * x + } +} + +impl FnOnce<(isize,)> for S { + type Output = isize; + + extern "rust-call" fn call_once(mut self, args: (isize,)) -> isize { self.call_mut(args) } +} + +fn call_itisize>(f: &F, x: isize) -> isize { + f.call((x,)) +} + +fn main() { + let x = call_it(&S, 22); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs new file mode 100644 index 000000000000..b6e0c612ad1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-fnmut-as-fnonce.rs @@ -0,0 +1,34 @@ +// run-pass +// Checks that the Fn trait hierarchy rules permit +// FnMut or FnOnce to be used where FnMut is implemented. + +#![feature(unboxed_closures, fn_traits)] + +struct S; + +impl FnMut<(i32,)> for S { + extern "rust-call" fn call_mut(&mut self, (x,): (i32,)) -> i32 { + x * x + } +} + +impl FnOnce<(i32,)> for S { + type Output = i32; + + extern "rust-call" fn call_once(mut self, args: (i32,)) -> i32 { self.call_mut(args) } +} + +fn call_it_muti32>(f: &mut F, x: i32) -> i32 { + f(x) +} + +fn call_it_oncei32>(f: F, x: i32) -> i32 { + f(x) +} + +fn main() { + let y = call_it_mut(&mut S, 22); + let z = call_it_once(S, 22); + assert_eq!(y, z); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-generic.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-generic.rs new file mode 100644 index 000000000000..5a1de18e5884 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-generic.rs @@ -0,0 +1,14 @@ +// run-pass +use std::ops::FnMut; + +fn call_iti32>(y: i32, mut f: F) -> i32 { + f(2, y) +} + +pub fn main() { + let f = |x: i32, y: i32| -> i32 { x + y }; + let z = call_it(3, f); + println!("{}", z); + assert_eq!(z, 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs new file mode 100644 index 000000000000..48fa16f0a3d8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-bound.rs @@ -0,0 +1,24 @@ +// run-pass +// Test that we are able to infer that the type of `x` is `isize` based +// on the expected type from the object. + +// pretty-expanded FIXME #23616 + +pub trait ToPrimitive { + fn to_int(&self) {} +} + +impl ToPrimitive for isize {} +impl ToPrimitive for i32 {} +impl ToPrimitive for usize {} + +fn doit(val: T, f: &F) + where F : Fn(T) +{ + f(val) +} + +pub fn main() { + doit(0, &|x /*: isize*/ | { x.to_int(); }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs new file mode 100644 index 000000000000..0b1e955ab9fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-from-expected-object-type.rs @@ -0,0 +1,20 @@ +// run-pass +// Test that we are able to infer that the type of `x` is `isize` based +// on the expected type from the object. + +// pretty-expanded FIXME #23616 + +pub trait ToPrimitive { + fn to_int(&self) {} +} + +impl ToPrimitive for isize {} +impl ToPrimitive for i32 {} +impl ToPrimitive for usize {} + +fn doit(val: T, f: &dyn Fn(T)) { f(val) } + +pub fn main() { + doit(0, &|x /*: isize*/ | { x.to_int(); }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs new file mode 100644 index 000000000000..ef00358041ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-arg-types-w-bound-regs-from-expected-bound.rs @@ -0,0 +1,24 @@ +// run-pass +// Test that we are able to infer that the type of `x` is `isize` based +// on the expected type from the object. + +// pretty-expanded FIXME #23616 + +pub trait ToPrimitive { + fn to_int(&self) {} +} + +impl ToPrimitive for isize {} +impl ToPrimitive for i32 {} +impl ToPrimitive for usize {} + +fn doit(val: T, f: &F) + where F : Fn(&T) +{ + f(&val) +} + +pub fn main() { + doit(0, &|x /*: isize*/ | { x.to_int(); }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.rs new file mode 100644 index 000000000000..a0aad3fdf61b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.rs @@ -0,0 +1,20 @@ +#![feature(fn_traits)] + +// That a closure whose expected argument types include two distinct +// bound regions. + +use std::cell::Cell; + +fn doit(val: T, f: &F) + where F : Fn(&Cell<&T>, &T) +{ + let x = Cell::new(&val); + f.call((&x,&val)) +} + +pub fn main() { + doit(0, &|x, y| { + x.set(y); // { dg-error ".E0312." "" { target *-*-* } } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs new file mode 100644 index 000000000000..cc885eb8c3a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-explicit-call-early.rs @@ -0,0 +1,9 @@ +// run-pass +#![feature(fn_traits)] + +fn main() { + let mut zero = || 0; + let x = zero.call_mut(()); + assert_eq!(x, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.rs new file mode 100644 index 000000000000..fc182311aab7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.rs @@ -0,0 +1,17 @@ +#![allow(unused)] + +fn foo(f: F) + where F: Fn() +{ +} + +fn main() { + // Test that this closure is inferred to `FnOnce` because it moves + // from `y.0`. This affects the error output (the error is that + // the closure implements `FnOnce`, not that it moves from inside + // a `Fn` closure.) + let y = (vec![1, 2, 3], 0); + let c = || drop(y.0); // { dg-error ".E0525." "" { target *-*-* } } + foo(c); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.rs new file mode 100644 index 000000000000..7cb9ca213c82 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut-no-mut.rs @@ -0,0 +1,21 @@ +// Test that we are able to infer a suitable kind for this closure +// that is just called (`FnMut`). + +fn main() { + let mut counter = 0; + + // Here this must be inferred to FnMut so that it can mutate counter, + // but we forgot the mut. + let tick1 = || { + counter += 1; + }; + + // In turn, tick2 must be inferred to FnMut so that it can call + // tick1, but we forgot the mut. + let tick2 = || { + tick1(); // { dg-error ".E0596." "" { target *-*-* } } + }; + + tick2(); // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs new file mode 100644 index 000000000000..14c852e331aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-calling-fnmut.rs @@ -0,0 +1,20 @@ +// run-pass +// Test that we are able to infer a suitable kind for this closure +// that is just called (`FnMut`). + +fn main() { + let mut counter = 0; + + { + // Here this must be inferred to FnMut so that it can mutate counter: + let mut tick1 = || counter += 1; + + // In turn, tick2 must be inferred to FnMut so that it can call tick1: + let mut tick2 = || { tick1(); tick1(); }; + + tick2(); + } + + assert_eq!(counter, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.rs new file mode 100644 index 000000000000..2e4a2461b058 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-missing-mut.rs @@ -0,0 +1,9 @@ +// Test that we are able to infer a suitable kind for this closure +// that is just called (`FnMut`). + +fn main() { + let mut counter = 0; + let tick = || counter += 1; + tick(); // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.rs new file mode 100644 index 000000000000..532ea96b0535 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-move-missing-mut.rs @@ -0,0 +1,9 @@ +// Test that we are able to infer a suitable kind for this closure +// that is just called (`FnMut`). + +fn main() { + let mut counter = 0; + let tick = move || counter += 1; + tick(); // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-move.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-move.rs new file mode 100644 index 000000000000..2e082b25334f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut-move.rs @@ -0,0 +1,17 @@ +// run-pass +// Test that we are able to infer a suitable kind for this `move` +// closure that is just called (`FnMut`). + +fn main() { + let mut counter = 0; + + let v = { + let mut tick = move || { counter += 1; counter }; + tick(); + tick() + }; + + assert_eq!(counter, 0); + assert_eq!(v, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut.rs new file mode 100644 index 000000000000..eeb0d3f03277 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnmut.rs @@ -0,0 +1,16 @@ +// run-pass +// Test that we are able to infer a suitable kind for this closure +// that is just called (`FnMut`). + +fn main() { + let mut counter = 0; + + { + let mut tick = || counter += 1; + tick(); + tick(); + } + + assert_eq!(counter, 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-call-twice.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-call-twice.rs new file mode 100644 index 000000000000..073256c8fbb0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-call-twice.rs @@ -0,0 +1,12 @@ +// Test that we are able to infer a suitable kind for this closure +// that is just called (`FnMut`). + +use std::mem; + +fn main() { + let mut counter: Vec = Vec::new(); + let tick = || mem::drop(counter); + tick(); + tick(); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-move-call-twice.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-move-call-twice.rs new file mode 100644 index 000000000000..372cbb532932 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-move-call-twice.rs @@ -0,0 +1,12 @@ +// Test that we are able to infer a suitable kind for this closure +// that is just called (`FnMut`). + +use std::mem; + +fn main() { + let mut counter: Vec = Vec::new(); + let tick = move || mem::drop(counter); + tick(); + tick(); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-move.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-move.rs new file mode 100644 index 000000000000..efed673ed247 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce-move.rs @@ -0,0 +1,26 @@ +// run-pass +// Test that we are able to infer a suitable kind for this `move` +// closure that is just called (`FnOnce`). + +use std::mem; + +struct DropMe<'a>(&'a mut i32); + +impl<'a> Drop for DropMe<'a> { + fn drop(&mut self) { + *self.0 += 1; + } +} + +fn main() { + let mut counter = 0; + + { + let drop_me = DropMe(&mut counter); + let tick = move || mem::drop(drop_me); + tick(); + } + + assert_eq!(counter, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce.rs new file mode 100644 index 000000000000..3bfd41ea13b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-fnonce.rs @@ -0,0 +1,26 @@ +// run-pass +// Test that we are able to infer a suitable kind for this closure +// that is just called (`FnOnce`). + +use std::mem; + +struct DropMe<'a>(&'a mut i32); + +impl<'a> Drop for DropMe<'a> { + fn drop(&mut self) { + *self.0 += 1; + } +} + +fn main() { + let mut counter = 0; + + { + let drop_me = DropMe(&mut counter); + let tick = || mem::drop(drop_me); + tick(); + } + + assert_eq!(counter, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-kind.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-kind.rs new file mode 100644 index 000000000000..c4e20a73ab78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-kind.rs @@ -0,0 +1,28 @@ +// run-pass +// Test that we can infer the "kind" of an unboxed closure based on +// the expected type. + +// Test by-ref capture of environment in unboxed closure types + +fn call_fn(f: F) { + f() +} + +fn call_fn_mut(mut f: F) { + f() +} + +fn call_fn_once(f: F) { + f() +} + +fn main() { + let mut x = 0_usize; + let y = 2_usize; + + call_fn(|| assert_eq!(x, 0)); + call_fn_mut(|| x += y); + call_fn_once(|| x += y); + assert_eq!(x, y * 2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-recursive-fn.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-recursive-fn.rs new file mode 100644 index 000000000000..2c12b991a79f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-recursive-fn.rs @@ -0,0 +1,46 @@ +// run-pass +#![feature(fn_traits, unboxed_closures)] + +use std::marker::PhantomData; + +// Test that we are able to infer a suitable kind for a "recursive" +// closure. As far as I can tell, coding up a recursive closure +// requires the good ol' [Y Combinator]. +// +// [Y Combinator]: https://en.wikipedia.org/wiki/Fixed-point_combinator#Y_combinator + +struct YCombinator { + func: F, + marker: PhantomData<(A,R)>, +} + +impl YCombinator { + fn new(f: F) -> YCombinator { + YCombinator { func: f, marker: PhantomData } + } +} + +impl R, A) -> R> Fn<(A,)> for YCombinator { + extern "rust-call" fn call(&self, (arg,): (A,)) -> R { + (self.func)(self, arg) + } +} + +impl R, A) -> R> FnMut<(A,)> for YCombinator { + extern "rust-call" fn call_mut(&mut self, args: (A,)) -> R { self.call(args) } +} + +impl R, A) -> R> FnOnce<(A,)> for YCombinator { + type Output = R; + extern "rust-call" fn call_once(self, args: (A,)) -> R { self.call(args) } +} + +fn main() { + let factorial = |recur: &dyn Fn(u32) -> u32, arg: u32| -> u32 { + if arg == 0 {1} else {arg * recur(arg-1)} + }; + let factorial: YCombinator<_,u32,u32> = YCombinator::new(factorial); + let r = factorial(10); + assert_eq!(3628800, r); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-upvar.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-upvar.rs new file mode 100644 index 000000000000..11bb6e151238 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-infer-upvar.rs @@ -0,0 +1,14 @@ +// run-pass +// Test that the type variable in the type(`Vec<_>`) of a closed over +// variable does not interfere with type inference. + +fn f(mut f: F) { + f(); +} + +fn main() { + let mut v: Vec<_> = vec![]; + f(|| v.push(0)); + assert_eq!(v, [0]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-manual-impl.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-manual-impl.rs new file mode 100644 index 000000000000..5c92de3de9cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-manual-impl.rs @@ -0,0 +1,32 @@ +// run-pass +#![feature(unboxed_closures, fn_traits)] + +struct S; + +impl FnMut<(i32,)> for S { + extern "rust-call" fn call_mut(&mut self, (x,): (i32,)) -> i32 { + x * x + } +} + +impl FnOnce<(i32,)> for S { + type Output = i32; + + extern "rust-call" fn call_once(mut self, args: (i32,)) -> i32 { self.call_mut(args) } +} + +fn call_iti32>(mut f: F, x: i32) -> i32 { + f(x) + 3 +} + +fn call_box(f: &mut dyn FnMut(i32) -> i32, x: i32) -> i32 { + f(x) + 3 +} + +fn main() { + let x = call_it(S, 1); + let y = call_box(&mut S, 1); + assert_eq!(x, 4); + assert_eq!(y, 4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-monomorphization.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-monomorphization.rs new file mode 100644 index 000000000000..e92486b52566 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-monomorphization.rs @@ -0,0 +1,27 @@ +// run-pass +// Test that unboxed closures in contexts with free type parameters +// monomorphize correctly (issue #16791) + +fn main(){ + fn bar<'a, T:Clone+'a> (t: T) -> BoxT + 'a> { + Box::new(move || t.clone()) + } + + let mut f = bar(42_u32); + assert_eq!(f(), 42); + + let mut f = bar("forty-two"); + assert_eq!(f(), "forty-two"); + + let x = 42_u32; + let mut f = bar(&x); + assert_eq!(f(), &x); + + #[derive(Clone, Copy, Debug, PartialEq)] + struct Foo(usize, &'static str); + + let x = Foo(42, "forty-two"); + let mut f = bar(x); + assert_eq!(f(), x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs new file mode 100644 index 000000000000..8278b0493ab7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-move-from-projection-issue-30046.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(unused)] + +fn foo(f: F) + where F: FnOnce() +{ +} + +fn main() { + // Test that this closure is inferred to `FnOnce` + // because it moves from `y.as.0`: + let x = Some(vec![1, 2, 3]); + foo(|| { + match x { + Some(y) => { } + None => { } + } + }); + + // Test that this closure is inferred to `FnOnce` + // because it moves from `y.0`: + let y = (vec![1, 2, 3], 0); + foo(|| { + let x = y.0; + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-move-mutable.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-move-mutable.rs new file mode 100644 index 000000000000..ae1014a60915 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-move-mutable.rs @@ -0,0 +1,32 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![deny(unused_mut)] +#![allow(unused_must_use)] + +// Test that mutating a mutable upvar in a capture-by-value unboxed +// closure does not ice (issue #18238) and marks the upvar as used +// mutably so we do not get a spurious warning about it not needing to +// be declared mutable (issue #18336 and #18769) + +fn set(x: &mut usize) { *x = 42; } + +fn main() { + { + let mut x = 0_usize; + move || x += 1; // { dg-warning "" "" { target *-*-* } } + } + { + let mut x = 0_usize; + move || x += 1; // { dg-warning "" "" { target *-*-* } } + } + { + let mut x = 0_usize; + move || set(&mut x); + } + { + let mut x = 0_usize; + move || set(&mut x); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs new file mode 100644 index 000000000000..a2cc97f73012 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-move-some-upvars-in-by-ref-closure.rs @@ -0,0 +1,24 @@ +// run-pass +// Test that in a by-ref once closure we move some variables even as +// we capture others by mutable reference. + +fn call(f: F) where F : FnOnce() { + f(); +} + +fn main() { + let mut x = vec![format!("Hello")]; + let y = vec![format!("World")]; + call(|| { + // Here: `x` must be captured with a mutable reference in + // order for us to append on it, and `y` must be captured by + // value. + for item in y { + x.push(item); + } + }); + assert_eq!(x.len(), 2); + assert_eq!(&*x[0], "Hello"); + assert_eq!(&*x[1], "World"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs new file mode 100644 index 000000000000..480b8029f225 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-mutate-upvar.rs @@ -0,0 +1,58 @@ +// Test that we cannot mutate an outer variable that is not declared +// as `mut` through a closure. Also test that we CAN mutate a moved copy, +// unless this is a `Fn` closure. Issue #16749. + +#![feature(unboxed_closures)] + +use std::mem; + +fn to_fn>(f: F) -> F { f } +fn to_fn_mut>(f: F) -> F { f } + +fn a() { + let n = 0; + let mut f = to_fn_mut(|| { + n += 1; // { dg-error ".E0594." "" { target *-*-* } } + }); +} + +fn b() { + let mut n = 0; + let mut f = to_fn_mut(|| { + n += 1; // OK + }); +} + +fn c() { + let n = 0; + let mut f = to_fn_mut(move || { + // If we just did a straight-forward desugaring, this would + // compile, but we do something a bit more subtle, and hence + // we get an error. + n += 1; // { dg-error ".E0594." "" { target *-*-* } } + }); +} + +fn d() { + let mut n = 0; + let mut f = to_fn_mut(move || { + n += 1; // OK + }); +} + +fn e() { + let n = 0; + let mut f = to_fn(move || { + n += 1; // { dg-error ".E0594." "" { target *-*-* } } + }); +} + +fn f() { + let mut n = 0; + let mut f = to_fn(move || { + n += 1; // { dg-error ".E0594." "" { target *-*-* } } + }); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.rs new file mode 100644 index 000000000000..7406c9ea577d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.rs @@ -0,0 +1,15 @@ +// Test that a by-ref `FnMut` closure gets an error when it tries to +// mutate a value. + +fn call(f: F) where F : Fn() { + f(); +} + +fn main() { + let mut counter = 0; + call(|| { + counter += 1; +// { dg-error ".E0594." "" { target *-*-* } .-1 } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-prelude.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-prelude.rs new file mode 100644 index 000000000000..c77e266da8e3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-prelude.rs @@ -0,0 +1,19 @@ +// run-pass +// Tests that the re-exports of `FnOnce` et al from the prelude work. + +// pretty-expanded FIXME #23616 + +fn main() { + let task: Box isize> = Box::new(|x| x); + task(0); + + let mut task: Box isize> = Box::new(|x| x); + task(0); + + call(|x| x, 22); +} + +fn call isize>(f: F, x: isize) -> isize { + f(x) +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-recursive-fn-using-fn-mut.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-recursive-fn-using-fn-mut.rs new file mode 100644 index 000000000000..dcaa7ae1c93e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-recursive-fn-using-fn-mut.rs @@ -0,0 +1,44 @@ +#![feature(core, fn_traits, unboxed_closures)] + +use std::marker::PhantomData; + +// An erroneous variant of `run-pass/unboxed_closures-infer-recursive-fn.rs` +// where we attempt to perform mutation in the recursive function. This fails to compile +// because it winds up requiring `FnMut` which enforces linearity. + +struct YCombinator { + func: F, + marker: PhantomData<(A,R)>, +} + +impl YCombinator { + fn new(f: F) -> YCombinator { + YCombinator { func: f, marker: PhantomData } + } +} + +impl R, A) -> R> FnMut<(A,)> for YCombinator { + extern "rust-call" fn call_mut(&mut self, (arg,): (A,)) -> R { + (self.func)(self, arg) +// { dg-error ".E0499." "" { target *-*-* } .-1 } + } +} + +impl R, A) -> R> FnOnce<(A,)> for YCombinator { + type Output = R; + extern "rust-call" fn call_once(mut self, args: (A,)) -> R { + self.call_mut(args) + } +} + +fn main() { + let mut counter = 0; + let factorial = |recur: &mut dyn FnMut(u32) -> u32, arg: u32| -> u32 { + counter += 1; + if arg == 0 {1} else {arg * recur(arg-1)} + }; + let mut factorial: YCombinator<_,u32,u32> = YCombinator::new(factorial); + let mut r = factorial(10); + assert_eq!(3628800, r); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-simple.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-simple.rs new file mode 100644 index 000000000000..9b67963e9b01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-simple.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_mut)] +#![allow(unused_imports)] +use std::ops::FnMut; + +pub fn main() { + let mut f = |x: isize, y: isize| -> isize { x + y }; + let z = f(1, 2); + assert_eq!(z, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-single-word-env.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-single-word-env.rs new file mode 100644 index 000000000000..84fbe9753032 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-single-word-env.rs @@ -0,0 +1,23 @@ +// run-pass +// Ensures that single-word environments work right in unboxed closures. +// These take a different path in codegen. + +fn a isize>(f: F) -> isize { + f(1, 2) +} + +fn b isize>(mut f: F) -> isize { + f(3, 4) +} + +fn c isize>(f: F) -> isize { + f(5, 6) +} + +fn main() { + let z = 10; + assert_eq!(a(move |x: isize, y| x + y + z), 13); + assert_eq!(b(move |x: isize, y| x + y + z), 17); + assert_eq!(c(move |x: isize, y| x + y + z), 21); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs new file mode 100644 index 000000000000..70a7615fce41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-static-call-fn-once.rs @@ -0,0 +1,8 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + let onetime = |x| x; + onetime(0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs new file mode 100644 index 000000000000..5c42aa737ced --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.rs @@ -0,0 +1,9 @@ +#![feature(unboxed_closures)] + +fn to_fn_mut>(f: F) -> F { f } + +fn main() { + let mut_ = to_fn_mut(|x| x); + mut_.call((0, )); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-sugar-object.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-sugar-object.rs new file mode 100644 index 000000000000..c8d24e2004be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-sugar-object.rs @@ -0,0 +1,26 @@ +// run-pass +// Test unboxed closure sugar used in object types. + +#![allow(dead_code)] + +struct Foo { + t: T, u: U +} + +trait Getter { + fn get(&self, arg: A) -> R; +} + +struct Identity; +impl Getter for Identity { + fn get(&self, arg: X) -> X { + arg + } +} + +fn main() { + let x: &dyn Getter<(i32,), (i32,)> = &Identity; + let (y,) = x.get((22,)); + assert_eq!(y, 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-type-mismatch.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-type-mismatch.rs new file mode 100644 index 000000000000..68eb64a4ebf4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-type-mismatch.rs @@ -0,0 +1,8 @@ +use std::ops::FnMut; + +pub fn main() { + let mut f = |x: isize, y: isize| -> isize { x + y }; + let z = f(1_usize, 2); // { dg-error ".E0308." "" { target *-*-* } } + println!("{}", z); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-unique-type-id.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-unique-type-id.rs new file mode 100644 index 000000000000..de18af9f18ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-unique-type-id.rs @@ -0,0 +1,27 @@ +// run-pass + +// This code used to produce the following ICE: +// +// error: internal compiler error: get_unique_type_id_of_type() - +// unexpected type: closure, +// Closure(rustc_ast::DefId{krate: 0, node: 66}, +// ReScope(63)) +// +// This is a regression test for issue #17021. +// +// compile-flags: -g +// ignore-asmjs wasm2js does not support source maps yet + +use std::ptr; + +pub fn replace_map<'a, T, F>(src: &mut T, prod: F) where F: FnOnce(T) -> T { + unsafe { *src = prod(ptr::read(src as *mut T as *const T)); } +} + +pub fn main() { + let mut a = 7; + let b = &mut a; + replace_map(b, |x: usize| x * 2); + assert_eq!(*b, 14); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs new file mode 100644 index 000000000000..eebca2c25614 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.rs @@ -0,0 +1,35 @@ +// Tests that unsafe extern fn pointers do not implement any Fn traits. + +use std::ops::{Fn, FnMut, FnOnce}; + +unsafe fn square(x: &isize) -> isize { + (*x) * (*x) +} + +fn call_it isize>(_: &F, _: isize) -> isize { + 0 +} +fn call_it_mut isize>(_: &mut F, _: isize) -> isize { + 0 +} +fn call_it_once isize>(_: F, _: isize) -> isize { + 0 +} + +fn a() { + let x = call_it(&square, 22); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn b() { + let y = call_it_mut(&mut square, 22); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn c() { + let z = call_it_once(square, 22); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-wrong-abi.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-wrong-abi.rs new file mode 100644 index 000000000000..2aef261558bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-wrong-abi.rs @@ -0,0 +1,35 @@ +// Tests that unsafe extern fn pointers do not implement any Fn traits. + +use std::ops::{Fn, FnMut, FnOnce}; + +extern "C" fn square(x: &isize) -> isize { + (*x) * (*x) +} + +fn call_it isize>(_: &F, _: isize) -> isize { + 0 +} +fn call_it_mut isize>(_: &mut F, _: isize) -> isize { + 0 +} +fn call_it_once isize>(_: F, _: isize) -> isize { + 0 +} + +fn a() { + let x = call_it(&square, 22); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn b() { + let y = call_it_mut(&mut square, 22); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn c() { + let z = call_it_once(square, 22); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs new file mode 100644 index 000000000000..6af3108ecf60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.rs @@ -0,0 +1,36 @@ +// Tests that unsafe extern fn pointers do not implement any Fn traits. + +use std::ops::{Fn, FnMut, FnOnce}; + +unsafe fn square(x: isize) -> isize { + x * x +} +// note: argument type here is `isize`, not `&isize` + +fn call_it isize>(_: &F, _: isize) -> isize { + 0 +} +fn call_it_mut isize>(_: &mut F, _: isize) -> isize { + 0 +} +fn call_it_once isize>(_: F, _: isize) -> isize { + 0 +} + +fn a() { + let x = call_it(&square, 22); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn b() { + let y = call_it_mut(&mut square, 22); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn c() { + let z = call_it_once(square, 22); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-zero-args.rs b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-zero-args.rs new file mode 100644 index 000000000000..0c9d78d6ba84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unboxed-closures/unboxed-closures-zero-args.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(unused_mut)] +// pretty-expanded FIXME #23616 + +fn main() { + let mut zero = || {}; + let () = zero(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unconstrained-none.rs b/gcc/testsuite/rust/rustc/ui/unconstrained-none.rs new file mode 100644 index 000000000000..fab38bda0939 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unconstrained-none.rs @@ -0,0 +1,6 @@ +// Issue #5062 + +fn main() { + None; // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unconstrained-ref.rs b/gcc/testsuite/rust/rustc/ui/unconstrained-ref.rs new file mode 100644 index 000000000000..e33a4fffdbec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unconstrained-ref.rs @@ -0,0 +1,8 @@ +struct S<'a, T:'a> { + o: &'a Option +} + +fn main() { + S { o: &None }; // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-ident-matcher.rs b/gcc/testsuite/rust/rustc/ui/underscore-ident-matcher.rs new file mode 100644 index 000000000000..b5cbe6dd60a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-ident-matcher.rs @@ -0,0 +1,10 @@ +macro_rules! identity { + ($i: ident) => ( + $i + ) +} + +fn main() { + let identity!(_) = 10; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-imports/auxiliary/duplicate.rs b/gcc/testsuite/rust/rustc/ui/underscore-imports/auxiliary/duplicate.rs new file mode 100644 index 000000000000..0b0f30bd424b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-imports/auxiliary/duplicate.rs @@ -0,0 +1,15 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::*; + +#[proc_macro_attribute] +pub fn duplicate(_: TokenStream, input: TokenStream) -> TokenStream { + let clone = input.clone(); + input.into_iter().chain(clone.into_iter()).collect() +} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-imports/auxiliary/underscore-imports.rs b/gcc/testsuite/rust/rustc/ui/underscore-imports/auxiliary/underscore-imports.rs new file mode 100644 index 000000000000..258f7f57a37b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-imports/auxiliary/underscore-imports.rs @@ -0,0 +1,21 @@ +#[macro_export] +macro_rules! do_nothing { + () => () +} + +mod m1 { + pub trait InScope1 { + fn in_scope1(&self) {} + } + impl InScope1 for () {} +} +mod m2 { + pub trait InScope2 { + fn in_scope2(&self) {} + } + impl InScope2 for () {} +} + +pub use m1::InScope1 as _; +pub use m2::InScope2 as _; + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-imports/basic.rs b/gcc/testsuite/rust/rustc/ui/underscore-imports/basic.rs new file mode 100644 index 000000000000..03f5238664f1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-imports/basic.rs @@ -0,0 +1,63 @@ +// check-pass +// aux-build:underscore-imports.rs + +#![warn(unused_imports, unused_extern_crates)] + +#[macro_use] +extern crate underscore_imports as _; + +do_nothing!(); // OK + +struct S; + +mod m { + pub trait Tr1 { + fn tr1_is_in_scope(&self) {} + } + pub trait Tr2 { + fn tr2_is_in_scope(&self) {} + } + + impl Tr1 for ::S {} + impl Tr2 for ::S {} +} + +mod unused { + use m::Tr1 as _; // { dg-warning "" "" { target *-*-* } } + use S as _; // { dg-warning "" "" { target *-*-* } } + extern crate core as _; // OK +} + +mod outer { + mod middle { + pub use m::Tr1 as _; + pub use m::Tr2 as _; // OK, no name conflict + struct Tr1; // OK, no name conflict + fn check() { + // Both traits are in scope + ::S.tr1_is_in_scope(); + ::S.tr2_is_in_scope(); + } + + mod inner { + // `_` imports are fetched by glob imports + use super::*; + fn check() { + // Both traits are in scope + ::S.tr1_is_in_scope(); + ::S.tr2_is_in_scope(); + } + } + } + + // `_` imports are fetched by glob imports + use self::middle::*; + fn check() { + // Both traits are in scope + ::S.tr1_is_in_scope(); + ::S.tr2_is_in_scope(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-imports/cycle.rs b/gcc/testsuite/rust/rustc/ui/underscore-imports/cycle.rs new file mode 100644 index 000000000000..6ba1425427d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-imports/cycle.rs @@ -0,0 +1,19 @@ +// Check that cyclic glob imports are allowed with underscore imports + +// check-pass + +mod x { + pub use crate::y::*; + pub use std::ops::Deref as _; +} + +mod y { + pub use crate::x::*; + pub use std::ops::Deref as _; +} + +pub fn main() { + use x::*; + (&0).deref(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-imports/duplicate.rs b/gcc/testsuite/rust/rustc/ui/underscore-imports/duplicate.rs new file mode 100644 index 000000000000..088298c1148c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-imports/duplicate.rs @@ -0,0 +1,16 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:duplicate.rs + +extern crate duplicate; + +#[duplicate::duplicate] +use main as _; // OK + +macro_rules! duplicate { + ($item: item) => { $item $item } +} + +duplicate!(use std as _;); // OK + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-imports/hygiene-2.rs b/gcc/testsuite/rust/rustc/ui/underscore-imports/hygiene-2.rs new file mode 100644 index 000000000000..f15b0b3045ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-imports/hygiene-2.rs @@ -0,0 +1,34 @@ +// Make sure that underscore imports with different contexts can exist in the +// same scope. + +// check-pass + +#![feature(decl_macro)] + +mod x { + pub use std::ops::Deref as _; +} + +macro n() { + pub use crate::x::*; +} + +#[macro_export] +macro_rules! p { + () => { pub use crate::x::*; } +} + +macro m($y:ident) { + mod $y { + crate::n!(); // Reexport of `Deref` should not be imported in `main` + crate::p!(); // Reexport of `Deref` should be imported into `main` + } +} + +m!(y); + +fn main() { + use crate::y::*; + (&()).deref(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-imports/hygiene.rs b/gcc/testsuite/rust/rustc/ui/underscore-imports/hygiene.rs new file mode 100644 index 000000000000..8b1faa2824c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-imports/hygiene.rs @@ -0,0 +1,41 @@ +// Make sure that underscore imports have the same hygiene considerations as +// other imports. + +#![feature(decl_macro)] + +mod x { + pub use std::ops::Deref as _; +} + + +macro glob_import() { + pub use crate::x::*; +} + +macro underscore_import() { + use std::ops::DerefMut as _; +} + +mod y { + crate::glob_import!(); + crate::underscore_import!(); +} + +macro create_module($y:ident) { + mod $y { + crate::glob_import!(); + crate::underscore_import!(); + } +} + +create_module!(z); + +fn main() { + use crate::y::*; + use crate::z::*; + glob_import!(); + underscore_import!(); + (&()).deref(); // { dg-error ".E0599." "" { target *-*-* } } + (&mut ()).deref_mut(); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-imports/intercrate.rs b/gcc/testsuite/rust/rustc/ui/underscore-imports/intercrate.rs new file mode 100644 index 000000000000..639917c226f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-imports/intercrate.rs @@ -0,0 +1,12 @@ +// build-pass (FIXME(62277): could be check-pass?) +// aux-build:underscore-imports.rs + +extern crate underscore_imports; + +use underscore_imports::*; + +fn main() { + ().in_scope1(); + ().in_scope2(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-imports/macro-expanded.rs b/gcc/testsuite/rust/rustc/ui/underscore-imports/macro-expanded.rs new file mode 100644 index 000000000000..e00c06eb57bd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-imports/macro-expanded.rs @@ -0,0 +1,46 @@ +// Check that macro expanded underscore imports behave as expected + +// check-pass + +#![feature(decl_macro, rustc_attrs)] + +mod x { + pub use std::ops::Not as _; +} + +macro m() { + mod w { + mod y { + pub use std::ops::Deref as _; + } + use crate::x::*; + use self::y::*; + use std::ops::DerefMut as _; + fn f() { + false.not(); + (&()).deref(); + (&mut ()).deref_mut(); + } + } +} + +#[rustc_macro_transparency = "transparent"] +macro n() { + mod z { + pub use std::ops::Deref as _; + } + use crate::x::*; + use crate::z::*; + use std::ops::DerefMut as _; + fn f() { + false.not(); + (&()).deref(); + (&mut ()).deref_mut(); + } +} + +m!(); +n!(); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-imports/shadow.rs b/gcc/testsuite/rust/rustc/ui/underscore-imports/shadow.rs new file mode 100644 index 000000000000..50daf3241de8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-imports/shadow.rs @@ -0,0 +1,24 @@ +// Check that underscore imports don't cause glob imports to be unshadowed + +mod a { + pub use std::ops::Deref as Shadow; +} + +mod b { + pub use crate::a::*; + macro_rules! m { + ($i:ident) => { pub struct $i; } + } + m!(Shadow); +} + +mod c { + use crate::b::Shadow as _; // Only imports the struct + + fn f(x: &()) { + x.deref(); // { dg-error ".E0599." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-imports/unused-2018.rs b/gcc/testsuite/rust/rustc/ui/underscore-imports/unused-2018.rs new file mode 100644 index 000000000000..d471e1d159c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-imports/unused-2018.rs @@ -0,0 +1,18 @@ +// edition:2018 + +#![deny(unused_imports)] + +mod multi_segment { + use core::any; // { dg-error "" "" { target *-*-* } } +} + +mod single_segment { + use core; // { dg-error "" "" { target *-*-* } } +} + +mod single_segment_underscore { + use core as _; // OK +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs new file mode 100644 index 000000000000..adf1b6a5e0d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs @@ -0,0 +1,14 @@ +// Check that the `'_` in `dyn Trait + '_` acts like ordinary elision, +// and not like an object lifetime default. +// +// cc #48468 + +use std::fmt::Debug; + +struct Foo { + x: Box, // { dg-error ".E0228." "" { target *-*-* } } +// { dg-error ".E0228." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/dyn-trait-underscore.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/dyn-trait-underscore.rs new file mode 100644 index 000000000000..949e585e45f3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/dyn-trait-underscore.rs @@ -0,0 +1,20 @@ +// Check that the `'_` in `dyn Trait + '_` acts like ordinary elision, +// and not like an object lifetime default. +// +// cc #48468 + +fn a(items: &[T]) -> Box> { + // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` + Box::new(items.iter()) // { dg-error ".E0759." "" { target *-*-* } } +} + +fn b(items: &[T]) -> Box + '_> { + Box::new(items.iter()) // OK, equivalent to c +} + +fn c<'a, T>(items: &'a [T]) -> Box + 'a> { + Box::new(items.iter()) // OK, equivalent to b +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/in-binder.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/in-binder.rs new file mode 100644 index 000000000000..bd0e97a4c609 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/in-binder.rs @@ -0,0 +1,36 @@ +// Check that we error when `'_` appears as the name of a lifetime parameter. +// +// Regression test for #52098. + +struct IceCube<'a> { + v: Vec<&'a char> +} + +impl<'_> IceCube<'_> {} +// { dg-error ".E0637." "" { target *-*-* } .-1 } + +struct Struct<'_> { +// { dg-error ".E0637." "" { target *-*-* } .-1 } + v: Vec<&'static char> +} + +enum Enum<'_> { +// { dg-error ".E0637." "" { target *-*-* } .-1 } + Variant +} + +union Union<'_> { +// { dg-error ".E0637." "" { target *-*-* } .-1 } + a: u32 +} + +trait Trait<'_> { +// { dg-error ".E0637." "" { target *-*-* } .-1 } +} + +fn foo<'_>() { +// { dg-error ".E0637." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/in-fn-return-illegal.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/in-fn-return-illegal.rs new file mode 100644 index 000000000000..faebd280a488 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/in-fn-return-illegal.rs @@ -0,0 +1,8 @@ +// Check that the `'_` used in structs/enums gives an error. + +use std::fmt::Debug; + +fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } // { dg-error ".E0106." "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/in-struct.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/in-struct.rs new file mode 100644 index 000000000000..89bdf01a5053 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/in-struct.rs @@ -0,0 +1,14 @@ +// Check that the `'_` used in structs/enums gives an error. + +use std::fmt::Debug; + +struct Foo { + x: &'_ u32, // { dg-error ".E0106." "" { target *-*-* } } +} + +enum Bar { + Variant(&'_ u32), // { dg-error ".E0106." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/underscore-lifetime-binders.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/underscore-lifetime-binders.rs new file mode 100644 index 000000000000..97766b937308 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/underscore-lifetime-binders.rs @@ -0,0 +1,23 @@ +struct Foo<'a>(&'a u8); +struct Baz<'a>(&'_ &'a u8); // { dg-error ".E0106." "" { target *-*-* } } + +fn foo<'_> // { dg-error ".E0637." "" { target *-*-* } } +(_: Foo<'_>) {} + +trait Meh<'a> {} +impl<'a> Meh<'a> for u8 {} + +fn meh() -> Box Meh<'_>> // { dg-error ".E0106." "" { target *-*-* } } +// { dg-error ".E0106." "" { target *-*-* } .-1 } +{ + Box::new(5u8) +} + +fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } // { dg-error ".E0106." "" { target *-*-* } } + +fn main() { + let x = 5; + foo(Foo(&x)); + let _ = meh(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.rs new file mode 100644 index 000000000000..2b9e1e802c20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.rs @@ -0,0 +1,4 @@ +fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); } // { dg-error ".E0623." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/underscore-outlives-bounds.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/underscore-outlives-bounds.rs new file mode 100644 index 000000000000..8f849bb21381 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/underscore-outlives-bounds.rs @@ -0,0 +1,9 @@ +// Regression test to check that `'b: '_` gets an error, because it's +// basically useless. +// +// #54902 + +trait Foo<'a> {} +impl<'b: '_> Foo<'b> for i32 {} // { dg-error ".E0637." "" { target *-*-* } } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rs new file mode 100644 index 000000000000..978e16c0fa0e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-inherent-impl-ampersand.rs @@ -0,0 +1,19 @@ +// revisions: rust2015 rust2018 +//[rust2018] edition:2018 + +trait WithType {} +trait WithRegion<'a> { } + +struct Foo { + t: T +} + +impl Foo +where + T: WithType<&u32> +// { dg-error "" "" { target *-*-* } .-1 } +// { dg-error "" "" { target *-*-* } .-2 } +{ } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs new file mode 100644 index 000000000000..1daa8fe1c359 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs @@ -0,0 +1,18 @@ +// revisions: rust2015 rust2018 +//[rust2018] edition:2018 + +trait WithType {} +trait WithRegion<'a> { } + +struct Foo { + t: T +} + +impl Foo +where + T: WithRegion<'_> +// { dg-error "" "" { target *-*-* } .-1 } +{ } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-trait-impl-region.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-trait-impl-region.rs new file mode 100644 index 000000000000..5788e9d9e9a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-trait-impl-region.rs @@ -0,0 +1,16 @@ +// revisions: rust2015 rust2018 +//[rust2018] edition:2018 + +trait WithType {} +trait WithRegion<'a> { } + +trait Foo { } + +impl Foo for Vec +where + T: WithType<&u32> +// { dg-error "" "" { target *-*-* } .-1 } +{ } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs new file mode 100644 index 000000000000..33c9a108e607 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs @@ -0,0 +1,16 @@ +// revisions: rust2015 rust2018 +//[rust2018] edition:2018 + +trait WithType {} +trait WithRegion<'a> { } + +trait Foo { } + +impl Foo for Vec +where + T: WithRegion<'_> +// { dg-error "" "" { target *-*-* } .-1 } +{ } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clauses.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clauses.rs new file mode 100644 index 000000000000..3d386a984935 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetime/where-clauses.rs @@ -0,0 +1,8 @@ +trait Foo<'a> {} + +impl<'b: '_> Foo<'b> for i32 {} // { dg-error ".E0637." "" { target *-*-* } } + +impl Foo<'static> for Vec {} // { dg-error ".E0637." "" { target *-*-* } } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/underscore-lifetimes.rs new file mode 100644 index 000000000000..f5004757caec --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-lifetimes.rs @@ -0,0 +1,39 @@ +// run-pass + +#![allow(dead_code)] +struct Foo<'a>(&'a u8); + +fn foo(x: &u8) -> Foo<'_> { + Foo(x) +} + +fn foo2(x: &'_ u8) -> Foo<'_> { + Foo(x) +} + +fn foo3(x: &'_ u8) -> Foo { + Foo(x) +} + +fn foo4(_: Foo<'_>) {} + +struct Foo2<'a, 'b> { + a: &'a u8, + b: &'b u8, +} +fn foo5<'b>(foo: Foo2<'_, 'b>) -> &'b u8 { + foo.b +} + +fn main() { + let x = &5; + let _ = foo(x); + let _ = foo2(x); + let _ = foo3(x); + foo4(Foo(x)); + let _ = foo5(Foo2 { + a: x, + b: &6, + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/underscore-method-after-integer.rs b/gcc/testsuite/rust/rustc/ui/underscore-method-after-integer.rs new file mode 100644 index 000000000000..60b90485ad10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/underscore-method-after-integer.rs @@ -0,0 +1,12 @@ +// run-pass + +trait Tr : Sized { + fn _method_on_numbers(self) {} +} + +impl Tr for i32 {} + +fn main() { + 42._method_on_numbers(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unevaluated_fixed_size_array_len.rs b/gcc/testsuite/rust/rustc/ui/unevaluated_fixed_size_array_len.rs new file mode 100644 index 000000000000..ef6f61a5ddbc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unevaluated_fixed_size_array_len.rs @@ -0,0 +1,14 @@ +// https://github.com/rust-lang/rust/issues/49208 + +trait Foo { + fn foo(); +} + +impl Foo for [(); 1] { + fn foo() {} +} + +fn main() { + <[(); 0] as Foo>::foo() // { dg-error ".E0277." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/uniform-paths/auxiliary/issue-53691.rs b/gcc/testsuite/rust/rustc/ui/uniform-paths/auxiliary/issue-53691.rs new file mode 100644 index 000000000000..971a78e59f48 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uniform-paths/auxiliary/issue-53691.rs @@ -0,0 +1,8 @@ +// edition:2018 + +mod m { pub fn f() {} } +mod n { pub fn g() {} } + +pub use m::f; +pub use n::g; + diff --git a/gcc/testsuite/rust/rustc/ui/uniform-paths/basic-nested.rs b/gcc/testsuite/rust/rustc/ui/uniform-paths/basic-nested.rs new file mode 100644 index 000000000000..783bfbd2d1d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uniform-paths/basic-nested.rs @@ -0,0 +1,62 @@ +// This test is similar to `basic.rs`, but nested in modules. + +// run-pass +// edition:2018 + +#![feature(decl_macro)] + +#![allow(unused_imports)] +#![allow(non_camel_case_types)] + +mod foo { + // Test that ambiguity errors are not emitted between `self::test` and + // `::test`, assuming the latter (crate) is not in `extern_prelude`. + mod test { + pub struct Foo(pub ()); + } + pub use test::Foo; + + // Test that qualified paths can refer to both the external crate and local item. + mod std { + pub struct io(pub ()); + } + pub use ::std::io as std_io; + pub use self::std::io as local_io; +} + +// Test that we can refer to the external crate unqualified +// (when there isn't a local item with the same name). +use std::io; + +mod bar { + // Also test the unqualified external crate import in a nested module, + // to show that the above import doesn't resolve through a local `std` + // item, e.g., the automatically injected `extern crate std;`, which in + // the Rust 2018 should no longer be visible through `crate::std`. + pub use std::io; + + // Also test that items named `std` in other namespaces don't + // cause ambiguity errors for the import from `std` above. + pub fn std() {} + pub macro std() {} +} + + +fn main() { + foo::Foo(()); + foo::std_io::stdout(); + foo::local_io(()); + io::stdout(); + bar::io::stdout(); + bar::std(); + bar::std!(); + + { + // Test that having `io` in a module scope and a non-module + // scope is allowed, when both resolve to the same definition. + use std::io; + use io::stdout; + stdout(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/uniform-paths/basic.rs b/gcc/testsuite/rust/rustc/ui/uniform-paths/basic.rs new file mode 100644 index 000000000000..46231754dcdb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uniform-paths/basic.rs @@ -0,0 +1,34 @@ +// run-pass +// edition:2018 + +#![allow(unused_imports)] +#![allow(non_camel_case_types)] + +// Test that ambiguity errors are not emitted between `self::test` and +// `::test`, assuming the latter (crate) is not in `extern_prelude`. +mod test { + pub struct Foo(pub ()); +} +use test::Foo; + +// Test that qualified paths can refer to both the external crate and local item. +mod std { + pub struct io(pub ()); +} +use ::std::io as std_io; +use self::std::io as local_io; + +fn main() { + Foo(()); + std_io::stdout(); + local_io(()); + + { + // Test that having `std_io` in a module scope and a non-module + // scope is allowed, when both resolve to the same definition. + use ::std::io as std_io; + use std_io::stdout; + stdout(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/uniform-paths/issue-53691.rs b/gcc/testsuite/rust/rustc/ui/uniform-paths/issue-53691.rs new file mode 100644 index 000000000000..646a6f88f5fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uniform-paths/issue-53691.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:issue-53691.rs + +extern crate issue_53691; + +fn main() { + issue_53691::f(); + issue_53691::g(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/uniform-paths/macros-nested.rs b/gcc/testsuite/rust/rustc/ui/uniform-paths/macros-nested.rs new file mode 100644 index 000000000000..b330ddbdcdf1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uniform-paths/macros-nested.rs @@ -0,0 +1,54 @@ +// This test is similar to `macros.rs`, but nested in modules. + +// run-pass +// edition:2018 + +#![allow(non_camel_case_types)] + +mod foo { + // Test that ambiguity errors are not emitted between `self::test` and + // `::test`, assuming the latter (crate) is not in `extern_prelude`. + macro_rules! m1 { + () => { + mod test { + pub struct Foo(pub ()); + } + } + } + pub use test::Foo; + m1!(); + + // Test that qualified paths can refer to both the external crate and local item. + macro_rules! m2 { + () => { + mod std { + pub struct io(pub ()); + } + } + } + pub use ::std::io as std_io; + pub use self::std::io as local_io; + m2!(); +} + +// Test that we can refer to the external crate unqualified +// (when there isn't a local item with the same name). +use std::io; + +mod bar { + // Also test the unqualified external crate import in a nested module, + // to show that the above import doesn't resolve through a local `std` + // item, e.g., the automatically injected `extern crate std;`, which in + // the Rust 2018 should no longer be visible through `crate::std`. + pub use std::io; +} + + +fn main() { + foo::Foo(()); + foo::std_io::stdout(); + foo::local_io(()); + io::stdout(); + bar::io::stdout(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/uniform-paths/macros.rs b/gcc/testsuite/rust/rustc/ui/uniform-paths/macros.rs new file mode 100644 index 000000000000..b0c6db9a2683 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uniform-paths/macros.rs @@ -0,0 +1,37 @@ +// This test is similar to `basic.rs`, but with macros defining local items. + +// run-pass +// edition:2018 + +#![allow(non_camel_case_types)] + +// Test that ambiguity errors are not emitted between `self::test` and +// `::test`, assuming the latter (crate) is not in `extern_prelude`. +macro_rules! m1 { + () => { + mod test { + pub struct Foo(pub ()); + } + } +} +use test::Foo; +m1!(); + +// Test that qualified paths can refer to both the external crate and local item. +macro_rules! m2 { + () => { + mod std { + pub struct io(pub ()); + } + } +} +use ::std::io as std_io; +use self::std::io as local_io; +m2!(); + +fn main() { + Foo(()); + std_io::stdout(); + local_io(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/uniform-paths/same-crate.rs b/gcc/testsuite/rust/rustc/ui/uniform-paths/same-crate.rs new file mode 100644 index 000000000000..e17d54a8e34e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uniform-paths/same-crate.rs @@ -0,0 +1,99 @@ +// run-pass +// edition:2018 + +pub const A: usize = 0; + +pub mod foo { + pub const B: usize = 1; + + pub mod bar { + pub const C: usize = 2; + + pub enum E { + V1(usize), + V2(String), + } + + pub fn test() -> String { + format!("{} {} {}", crate::A, crate::foo::B, C) + } + + pub fn test_use() -> String { + use crate::A; + use crate::foo::B; + + format!("{} {} {}", A, B, C) + } + + pub fn test_enum() -> String { + use E::*; + match E::V1(10) { + V1(i) => { format!("V1: {}", i) } + V2(s) => { format!("V2: {}", s) } + } + } + } + + pub fn test() -> String { + format!("{} {} {}", crate::A, B, bar::C) + } + + pub fn test_use() -> String { + use crate::A; + use bar::C; + + format!("{} {} {}", A, B, C) + } + + pub fn test_enum() -> String { + use bar::E::*; + match bar::E::V1(10) { + V1(i) => { format!("V1: {}", i) } + V2(s) => { format!("V2: {}", s) } + } + } +} + +pub fn test() -> String { + format!("{} {} {}", A, foo::B, foo::bar::C) +} + +pub fn test_use() -> String { + use foo::B; + use foo::bar::C; + + format!("{} {} {}", A, B, C) +} + +pub fn test_enum() -> String { + use foo::bar::E::*; + match foo::bar::E::V1(10) { + V1(i) => { format!("V1: {}", i) } + V2(s) => { format!("V2: {}", s) } + } +} + +fn main() { + let output = [ + test(), + foo::test(), + foo::bar::test(), + test_use(), + foo::test_use(), + foo::bar::test_use(), + test_enum(), + foo::test_enum(), + foo::bar::test_enum(), + ].join("\n"); + assert_eq!(output, "\ +0 1 2 +0 1 2 +0 1 2 +0 1 2 +0 1 2 +0 1 2 +V1: 10 +V1: 10 +V1: 10"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unify-return-ty.rs b/gcc/testsuite/rust/rustc/ui/unify-return-ty.rs new file mode 100644 index 000000000000..ac6300116c9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unify-return-ty.rs @@ -0,0 +1,17 @@ +// run-pass +// Tests that the tail expr in null() has its type +// unified with the type *T, and so the type variable +// in that type gets resolved. + +// pretty-expanded FIXME #23616 + +use std::mem; + +fn null() -> *const T { + unsafe { + mem::transmute(0_usize) + } +} + +pub fn main() { null::(); } + diff --git a/gcc/testsuite/rust/rustc/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs b/gcc/testsuite/rust/rustc/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs new file mode 100644 index 000000000000..34fd4bd2e09c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uninhabited/exhaustive-wo-nevertype-issue-51221.rs @@ -0,0 +1,10 @@ +// check-pass + +#![feature(exhaustive_patterns)] + +enum Void {} +fn main() { + let a: Option = None; + let None = a; +} + diff --git a/gcc/testsuite/rust/rustc/ui/uninhabited/privately-uninhabited-dead-code.rs b/gcc/testsuite/rust/rustc/ui/uninhabited/privately-uninhabited-dead-code.rs new file mode 100644 index 000000000000..82c301fee52d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uninhabited/privately-uninhabited-dead-code.rs @@ -0,0 +1,21 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![deny(unused_variables)] + +mod foo { + enum Bar {} + + #[allow(dead_code)] + pub struct Foo { + value: Bar, // "privately" uninhabited + } + + pub fn give_foo() -> Foo { panic!() } +} + +fn main() { + let a = 42; + foo::give_foo(); + println!("Hello, {}", a); // ok: we can't tell that this code is dead +} + diff --git a/gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-enum-cast.rs b/gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-enum-cast.rs new file mode 100644 index 000000000000..18e2e2fb6c41 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-enum-cast.rs @@ -0,0 +1,10 @@ +// check-pass + +enum E {} + +fn f(e: E) { + println!("{}", (e as isize).to_string()); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-irrefutable.rs b/gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-irrefutable.rs new file mode 100644 index 000000000000..2a7664fc489a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-irrefutable.rs @@ -0,0 +1,29 @@ +#![feature(never_type)] +#![feature(exhaustive_patterns)] + +mod foo { + pub struct SecretlyEmpty { + _priv: !, + } + + pub struct NotSoSecretlyEmpty { + pub _pub: !, + } +} + +struct NotSoSecretlyEmpty { + _priv: !, +} + +enum Foo { + A(foo::SecretlyEmpty), + B(foo::NotSoSecretlyEmpty), + C(NotSoSecretlyEmpty), + D(u32), +} + +fn main() { + let x: Foo = Foo::D(123); + let Foo::D(_y) = x; // { dg-error ".E0005." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-matches-feature-gated.rs b/gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-matches-feature-gated.rs new file mode 100644 index 000000000000..06e50d21b8ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-matches-feature-gated.rs @@ -0,0 +1,40 @@ +use std::mem::zeroed; +enum Void {} + +fn main() { + let x: Result = Ok(23); + let _ = match x { // { dg-error ".E0004." "" { target *-*-* } } + Ok(n) => n, + }; + + // This is pretty much instant UB. However, we have no choice -- we need to + // test matching on a reference to `&Void`; we cannot do anything other than + // just accept the fact that this is UB if `main` did run, but it doesn't; + // this test only checks that these are feature-gated. + let x: &Void = unsafe { zeroed() }; + let _ = match x {}; // { dg-error ".E0004." "" { target *-*-* } } + + let x: (Void,) = unsafe { zeroed() }; + let _ = match x {}; // { dg-error ".E0004." "" { target *-*-* } } + + let x: [Void; 1] = unsafe { zeroed() }; + let _ = match x {}; // { dg-error ".E0004." "" { target *-*-* } } + + let x: &[Void] = unsafe { zeroed() }; + let _ = match x { // { dg-error ".E0004." "" { target *-*-* } } + &[] => (), + }; + + let x: Void = unsafe { zeroed() }; + let _ = match x {}; // okay + + let x: Result = Ok(23); + let _ = match x { // { dg-error ".E0004." "" { target *-*-* } } + Ok(x) => x, + }; + + let x: Result = Ok(23); + let Ok(x) = x; +// { dg-error ".E0005." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-patterns.rs b/gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-patterns.rs new file mode 100644 index 000000000000..1407f62abbea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uninhabited/uninhabited-patterns.rs @@ -0,0 +1,48 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] +#![feature(never_type)] +#![feature(exhaustive_patterns)] + +#![deny(unreachable_patterns)] + +mod foo { + pub struct SecretlyEmpty { + _priv: !, + } +} + +struct NotSoSecretlyEmpty { + _priv: !, +} + +fn foo() -> Option { + None +} + +fn main() { + let x: &[!] = &[]; + + match x { + &[] => (), + &[..] => (), // { dg-error "" "" { target *-*-* } } + }; + + let x: Result, &[Result]> = Err(&[]); + match x { + Ok(box _) => (), // { dg-error "" "" { target *-*-* } } + Err(&[]) => (), + Err(&[..]) => (), // { dg-error "" "" { target *-*-* } } + } + + let x: Result> = Err(Err(123)); + match x { + Ok(_y) => (), + Err(Err(_y)) => (), + Err(Ok(_y)) => (), // { dg-error "" "" { target *-*-* } } + } + + while let Some(_y) = foo() { +// { dg-error "" "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/uninit-empty-types.rs b/gcc/testsuite/rust/rustc/ui/uninit-empty-types.rs new file mode 100644 index 000000000000..1b4ddcf738a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/uninit-empty-types.rs @@ -0,0 +1,20 @@ +// build-pass +// Test the uninit() construct returning various empty types. + +// pretty-expanded FIXME #23616 + +use std::mem::MaybeUninit; + +struct Foo; + +#[allow(deprecated)] +pub fn main() { + unsafe { + // `Foo` and `[Foo; 2]` are both zero sized and inhabited, so this is safe. + let _x: Foo = MaybeUninit::uninit().assume_init(); + let _x: [Foo; 2] = MaybeUninit::uninit().assume_init(); + let _x: Foo = std::mem::uninitialized(); + let _x: [Foo; 2] = std::mem::uninitialized(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/auxiliary/union.rs b/gcc/testsuite/rust/rustc/ui/union/auxiliary/union.rs new file mode 100644 index 000000000000..202489dfc9f0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/auxiliary/union.rs @@ -0,0 +1,5 @@ +pub union U { + pub a: u8, + pub b: u16, +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/issue-41073.rs b/gcc/testsuite/rust/rustc/ui/union/issue-41073.rs new file mode 100644 index 000000000000..f1213bab6d4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/issue-41073.rs @@ -0,0 +1,25 @@ +#![feature(untagged_unions)] + +union Test { + a: A, // { dg-error ".E0740." "" { target *-*-* } } + b: B +} + +#[derive(Debug)] +struct A(i32); +impl Drop for A { + fn drop(&mut self) { println!("A"); } +} + +#[derive(Debug)] +struct B(f32); +impl Drop for B { + fn drop(&mut self) { println!("B"); } +} + +fn main() { + let mut test = Test { a: A(3) }; + println!("{:?}", unsafe { test.b }); + unsafe { test.b = B(0.5); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-align.rs b/gcc/testsuite/rust/rustc/ui/union/union-align.rs new file mode 100644 index 000000000000..d8c1e1e454a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-align.rs @@ -0,0 +1,63 @@ +// run-pass +#![allow(dead_code)] + +use std::mem::{size_of, size_of_val, align_of, align_of_val}; + +#[repr(align(16))] +pub union U16 { + a: u8, + b: u32 +} + +fn main() { + assert_eq!(align_of::(), 16); + assert_eq!(size_of::(), 16); + let u = U16 { a: 10 }; + unsafe { + assert_eq!(align_of_val(&u.a), 1); + assert_eq!(size_of_val(&u.a), 1); + assert_eq!(u.a, 10); + } + + let u = U16 { b: 11 }; + unsafe { + assert_eq!(align_of_val(&u.b), 4); + assert_eq!(size_of_val(&u.b), 4); + assert_eq!(u.b, 11); + } + + hybrid::check_hybrid(); +} + +mod hybrid { + use std::mem::{size_of, align_of}; + + #[repr(align(16))] + #[derive(Copy, Clone)] + struct S1 { + a: u16, + b: u8, + } + + #[repr(align(32))] + union U { + s: S1, + c: u16, + } + + #[repr(align(64))] + struct S2 { + d: u8, + u: U, + } + + pub fn check_hybrid() { + assert_eq!(align_of::(), 16); + assert_eq!(size_of::(), 16); + assert_eq!(align_of::(), 32); + assert_eq!(size_of::(), 32); + assert_eq!(align_of::(), 64); + assert_eq!(size_of::(), 64); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-backcomp.rs b/gcc/testsuite/rust/rustc/ui/union/union-backcomp.rs new file mode 100644 index 000000000000..9daea1c26641 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-backcomp.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(path_statements)] +#![allow(dead_code)] + +macro_rules! union { + () => (struct S;) +} + +union!(); + +fn union() {} + +fn main() { + union(); + + let union = 10; + + union; + + union as u8; + + union U { + a: u8, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-basic.rs b/gcc/testsuite/rust/rustc/ui/union/union-basic.rs new file mode 100644 index 000000000000..bdb0bddceb8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-basic.rs @@ -0,0 +1,60 @@ +// run-pass +#![allow(unused_imports)] + +// aux-build:union.rs + +extern crate union; +use std::mem::{size_of, align_of, zeroed}; + +union U { + a: u8, + b: u16 +} + +fn local() { + assert_eq!(size_of::(), 2); + assert_eq!(align_of::(), 2); + + let u = U { a: 10 }; + unsafe { + assert_eq!(u.a, 10); + let U { a } = u; + assert_eq!(a, 10); + } + + let mut w = U { b: 0 }; + unsafe { + assert_eq!(w.a, 0); + assert_eq!(w.b, 0); + w.a = 1; + assert_eq!(w.a, 1); + assert_eq!(w.b.to_le(), 1); + } +} + +fn xcrate() { + assert_eq!(size_of::(), 2); + assert_eq!(align_of::(), 2); + + let u = union::U { a: 10 }; + unsafe { + assert_eq!(u.a, 10); + let union::U { a } = u; + assert_eq!(a, 10); + } + + let mut w = union::U { b: 0 }; + unsafe { + assert_eq!(w.a, 0); + assert_eq!(w.b, 0); + w.a = 1; + assert_eq!(w.a, 1); + assert_eq!(w.b.to_le(), 1); + } +} + +fn main() { + local(); + xcrate(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-borrow-move-parent-sibling.rs b/gcc/testsuite/rust/rustc/ui/union/union-borrow-move-parent-sibling.rs new file mode 100644 index 000000000000..27aee36787c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-borrow-move-parent-sibling.rs @@ -0,0 +1,92 @@ +#![feature(untagged_unions)] +#![allow(unused)] + +use std::ops::{Deref, DerefMut}; + +#[derive(Default)] +struct MockBox { + value: [T; 1], +} + +impl MockBox { + fn new(value: T) -> Self { MockBox { value: [value] } } +} + +impl Deref for MockBox { + type Target = T; + fn deref(&self) -> &T { &self.value[0] } +} + +impl DerefMut for MockBox { + fn deref_mut(&mut self) -> &mut T { &mut self.value[0] } +} + +#[derive(Default)] +struct MockVec { + value: [T; 0], +} + +impl MockVec { + fn new() -> Self { MockVec { value: [] } } +} + +impl Deref for MockVec { + type Target = [T]; + fn deref(&self) -> &[T] { &self.value } +} + +impl DerefMut for MockVec { + fn deref_mut(&mut self) -> &mut [T] { &mut self.value } +} + + +union U { + x: ((MockVec, MockVec), MockVec), + y: MockBox>, +} + +fn use_borrow(_: &T) {} + +unsafe fn parent_sibling_borrow() { + let mut u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) }; + let a = &mut u.x.0; + let b = &u.y; // { dg-error ".E0502." "" { target *-*-* } } + use_borrow(a); +} + +unsafe fn parent_sibling_move() { + let u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) }; + let a = u.x.0; + let b = u.y; // { dg-error ".E0382." "" { target *-*-* } } +} + +unsafe fn grandparent_sibling_borrow() { + let mut u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) }; + let a = &mut (u.x.0).0; + let b = &u.y; // { dg-error ".E0502." "" { target *-*-* } } + use_borrow(a); +} + +unsafe fn grandparent_sibling_move() { + let u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) }; + let a = (u.x.0).0; + let b = u.y; // { dg-error ".E0382." "" { target *-*-* } } +} + +unsafe fn deref_sibling_borrow() { + let mut u = U { y: MockBox::default() }; + let a = &mut *u.y; + let b = &u.x; // { dg-error ".E0502." "" { target *-*-* } } + use_borrow(a); +} + +unsafe fn deref_sibling_move() { + let u = U { x: ((MockVec::new(), MockVec::new()), MockVec::new()) }; + // No way to test deref-move without Box in union + // let a = *u.y; + // let b = u.x; ERROR use of moved value: `u` +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-const-codegen.rs b/gcc/testsuite/rust/rustc/ui/union/union-const-codegen.rs new file mode 100644 index 000000000000..db015923fa01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-const-codegen.rs @@ -0,0 +1,18 @@ +// run-pass + +union U { + a: u64, + b: u64, +} + +const C: U = U { b: 10 }; + +fn main() { + unsafe { + let a = C.a; + let b = C.b; + assert_eq!(a, 10); + assert_eq!(b, 10); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-const-eval-field.rs b/gcc/testsuite/rust/rustc/ui/union/union-const-eval-field.rs new file mode 100644 index 000000000000..d6acf96b30ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-const-eval-field.rs @@ -0,0 +1,46 @@ +// run-pass + +#![feature(const_fn)] + +type Field1 = (i32, u32); +type Field2 = f32; +type Field3 = i64; + +union DummyUnion { + field1: Field1, + field2: Field2, + field3: Field3, +} + +const FLOAT1_AS_I32: i32 = 1065353216; +const UNION: DummyUnion = DummyUnion { field1: (FLOAT1_AS_I32, 0) }; + +const fn read_field1() -> Field1 { + const FIELD1: Field1 = unsafe { UNION.field1 }; + FIELD1 +} + +const fn read_field2() -> Field2 { + const FIELD2: Field2 = unsafe { UNION.field2 }; + FIELD2 +} + +const fn read_field3() -> Field3 { + const FIELD3: Field3 = unsafe { UNION.field3 }; + FIELD3 +} + +fn main() { + let foo = FLOAT1_AS_I32; + assert_eq!(read_field1().0, foo); + assert_eq!(read_field1().0, FLOAT1_AS_I32); + + let foo = 1.0; + assert_eq!(read_field2(), foo); + assert_eq!(read_field2(), 1.0); + + assert_eq!(read_field3(), unsafe { UNION.field3 }); + let foo = unsafe { UNION.field3 }; + assert_eq!(read_field3(), foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-const-eval.rs b/gcc/testsuite/rust/rustc/ui/union/union-const-eval.rs new file mode 100644 index 000000000000..a3d830ad9f8f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-const-eval.rs @@ -0,0 +1,15 @@ +// build-pass (FIXME(62277): could be check-pass?) +#![feature(const_fn_union)] + +union U { + a: usize, + b: usize, +} + +const C: U = U { a: 10 }; + +fn main() { + let a: [u8; unsafe { C.a }]; + let b: [u8; unsafe { C.b }]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-const-pat.rs b/gcc/testsuite/rust/rustc/ui/union/union-const-pat.rs new file mode 100644 index 000000000000..535d97118c07 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-const-pat.rs @@ -0,0 +1,14 @@ +union U { + a: usize, + b: usize, +} + +const C: U = U { a: 10 }; + +fn main() { + match C { + C => {} // { dg-error "" "" { target *-*-* } } + _ => {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-copy.rs b/gcc/testsuite/rust/rustc/ui/union/union-copy.rs new file mode 100644 index 000000000000..b542345c4eee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-copy.rs @@ -0,0 +1,15 @@ +#[derive(Clone)] +union U { + a: u8 +} + +#[derive(Clone)] +union W { + a: std::mem::ManuallyDrop +} + +impl Copy for U {} // OK +impl Copy for W {} // { dg-error ".E0204." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-custom-drop.rs b/gcc/testsuite/rust/rustc/ui/union/union-custom-drop.rs new file mode 100644 index 000000000000..f24caa84c94b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-custom-drop.rs @@ -0,0 +1,20 @@ +// test for a union with a field that's a union with a manual impl Drop +// Ensures we do not treat all unions as not having any drop glue. + +#![feature(untagged_unions)] + +union Foo { + bar: Bar, // { dg-error ".E0740." "" { target *-*-* } } +} + +union Bar { + a: i32, + b: u32, +} + +impl Drop for Bar { + fn drop(&mut self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-deref.rs b/gcc/testsuite/rust/rustc/ui/union/union-deref.rs new file mode 100644 index 000000000000..a569cca559c2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-deref.rs @@ -0,0 +1,29 @@ +// ignore-tidy-linelength +//! Test the part of RFC 2514 that is about not applying `DerefMut` coercions +//! of union fields. +#![feature(untagged_unions)] + +use std::mem::ManuallyDrop; + +union U1 { x:(), f: ManuallyDrop<(T,)> } + +union U2 { x:(), f: (ManuallyDrop<(T,)>,) } + +fn main() { + let mut u : U1> = U1 { x: () }; + unsafe { (*u.f).0 = Vec::new() }; // explicit deref, this compiles + unsafe { u.f.0 = Vec::new() }; // { dg-error "" "" { target *-*-* } } + unsafe { &mut (*u.f).0 }; // explicit deref, this compiles + unsafe { &mut u.f.0 }; // { dg-error "" "" { target *-*-* } } + unsafe { (*u.f).0.push(0) }; // explicit deref, this compiles + unsafe { u.f.0.push(0) }; // { dg-error "" "" { target *-*-* } } + + let mut u : U2> = U2 { x: () }; + unsafe { (*u.f.0).0 = Vec::new() }; // explicit deref, this compiles + unsafe { u.f.0.0 = Vec::new() }; // { dg-error "" "" { target *-*-* } } + unsafe { &mut (*u.f.0).0 }; // explicit deref, this compiles + unsafe { &mut u.f.0.0 }; // { dg-error "" "" { target *-*-* } } + unsafe { (*u.f.0).0.push(0) }; // explicit deref, this compiles + unsafe { u.f.0.0.push(0) }; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-derive-clone.rs b/gcc/testsuite/rust/rustc/ui/union/union-derive-clone.rs new file mode 100644 index 000000000000..99c1f89fb193 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-derive-clone.rs @@ -0,0 +1,37 @@ +use std::mem::ManuallyDrop; + +#[derive(Clone)] // { dg-error ".E0277." "" { target *-*-* } } +union U1 { + a: u8, +} + +#[derive(Clone)] +union U2 { + a: u8, // OK +} + +impl Copy for U2 {} + +#[derive(Clone, Copy)] +union U3 { + a: u8, // OK +} + +#[derive(Clone, Copy)] +union U4 { + a: T, // OK +} + +#[derive(Clone, Copy)] +union U5 { + a: ManuallyDrop, // OK +} + +#[derive(Clone)] +struct CloneNoCopy; + +fn main() { + let u = U5 { a: ManuallyDrop::new(CloneNoCopy) }; + let w = u.clone(); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-derive-eq.rs b/gcc/testsuite/rust/rustc/ui/union/union-derive-eq.rs new file mode 100644 index 000000000000..3b6793b27e75 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-derive-eq.rs @@ -0,0 +1,19 @@ +#[derive(Eq)] // OK +union U1 { + a: u8, +} + +impl PartialEq for U1 { fn eq(&self, rhs: &Self) -> bool { true } } + +#[derive(PartialEq, Copy, Clone)] +struct PartialEqNotEq; + +#[derive(Eq)] +union U2 { + a: PartialEqNotEq, // { dg-error ".E0277." "" { target *-*-* } } +} + +impl PartialEq for U2 { fn eq(&self, rhs: &Self) -> bool { true } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-derive-rpass.rs b/gcc/testsuite/rust/rustc/ui/union/union-derive-rpass.rs new file mode 100644 index 000000000000..3d9bea8cd6e9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-derive-rpass.rs @@ -0,0 +1,40 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] + +// Some traits can be derived for unions. + +#[derive( + Copy, + Clone, + Eq, +)] +union U { + a: u8, + b: u16, +} + +impl PartialEq for U { fn eq(&self, rhs: &Self) -> bool { true } } + +#[derive( + Clone, + Copy, + Eq +)] +union W { + a: T, +} + +impl PartialEq for W { fn eq(&self, rhs: &Self) -> bool { true } } + +fn main() { + let u = U { b: 0 }; + let u1 = u; + let u2 = u.clone(); + assert!(u1 == u2); + + let w = W { a: 0 }; + let w1 = w.clone(); + assert!(w == w1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-derive.rs b/gcc/testsuite/rust/rustc/ui/union/union-derive.rs new file mode 100644 index 000000000000..12dee0072478 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-derive.rs @@ -0,0 +1,17 @@ +// Most traits cannot be derived for unions. + +#[derive( + PartialEq, // { dg-error "" "" { target *-*-* } } + PartialOrd, // { dg-error "" "" { target *-*-* } } + Ord, // { dg-error "" "" { target *-*-* } } + Hash, // { dg-error "" "" { target *-*-* } } + Default, // { dg-error "" "" { target *-*-* } } + Debug, // { dg-error "" "" { target *-*-* } } +)] +union U { + a: u8, + b: u16, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-drop-assign.rs b/gcc/testsuite/rust/rustc/ui/union/union-drop-assign.rs new file mode 100644 index 000000000000..569054e55c66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-drop-assign.rs @@ -0,0 +1,38 @@ +// run-pass +#![allow(unused_assignments)] + +// Drop works for union itself. + +use std::mem::ManuallyDrop; + +struct S; + +union U { + a: ManuallyDrop +} + +impl Drop for S { + fn drop(&mut self) { + unsafe { CHECK += 10; } + } +} + +impl Drop for U { + fn drop(&mut self) { + unsafe { CHECK += 1; } + } +} + +static mut CHECK: u8 = 0; + +fn main() { + unsafe { + let mut u = U { a: ManuallyDrop::new(S) }; + assert_eq!(CHECK, 0); + u = U { a: ManuallyDrop::new(S) }; + assert_eq!(CHECK, 1); // union itself is assigned, union is dropped, field is not dropped + *u.a = S; + assert_eq!(CHECK, 11); // union field is assigned, field is dropped + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-drop.rs b/gcc/testsuite/rust/rustc/ui/union/union-drop.rs new file mode 100644 index 000000000000..93a978911551 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-drop.rs @@ -0,0 +1,58 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] + +// Drop works for union itself. + +#[derive(Copy, Clone)] +struct S; + +union U { + a: u8 +} + +union W { + a: S, +} + +union Y { + a: S, +} + +impl Drop for U { + fn drop(&mut self) { + unsafe { CHECK += 1; } + } +} + +impl Drop for W { + fn drop(&mut self) { + unsafe { CHECK += 1; } + } +} + +static mut CHECK: u8 = 0; + +fn main() { + unsafe { + assert_eq!(CHECK, 0); + { + let u = U { a: 1 }; + } + assert_eq!(CHECK, 1); // 1, dtor of U is called + { + let w = W { a: S }; + } + assert_eq!(CHECK, 2); // 2, dtor of W is called + { + let y = Y { a: S }; + } + assert_eq!(CHECK, 2); // 2, Y has no dtor + { + let u2 = U { a: 1 }; + std::mem::forget(u2); + } + assert_eq!(CHECK, 2); // 2, dtor of U *not* called for u2 + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-empty.rs b/gcc/testsuite/rust/rustc/ui/union/union-empty.rs new file mode 100644 index 000000000000..778e77d92dab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-empty.rs @@ -0,0 +1,4 @@ +union U {} // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-fields-1.rs b/gcc/testsuite/rust/rustc/ui/union/union-fields-1.rs new file mode 100644 index 000000000000..0bc51076c648 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-fields-1.rs @@ -0,0 +1,33 @@ +#![deny(dead_code)] + +union U1 { + a: u8, // should not be reported + b: u8, // should not be reported + c: u8, // { dg-error "" "" { target *-*-* } } +} +union U2 { + a: u8, // { dg-error "" "" { target *-*-* } } + b: u8, // should not be reported + c: u8, // should not be reported +} +union NoDropLike { a: u8 } // { dg-error "" "" { target *-*-* } } + +union U { + a: u8, // should not be reported + b: u8, // should not be reported + c: u8, // { dg-error "" "" { target *-*-* } } +} +type A = U; + +fn main() { + let u = U1 { a: 0 }; + let _a = unsafe { u.b }; + + let u = U2 { c: 0 }; + let _b = unsafe { u.b }; + + let _u = NoDropLike { a: 10 }; + let u = A { a: 0 }; + let _b = unsafe { u.b }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-fields-2.rs b/gcc/testsuite/rust/rustc/ui/union/union-fields-2.rs new file mode 100644 index 000000000000..0bf379eb3f9c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-fields-2.rs @@ -0,0 +1,24 @@ +union U { + a: u8, + b: u16, +} + +fn main() { + let u = U {}; // { dg-error "" "" { target *-*-* } } + let u = U { a: 0 }; // OK + let u = U { a: 0, b: 1 }; // { dg-error "" "" { target *-*-* } } + let u = U { a: 0, b: 1, c: 2 }; // { dg-error ".E0560." "" { target *-*-* } } +// { dg-error ".E0560." "" { target *-*-* } .-1 } + let u = U { ..u }; // { dg-error ".E0436." "" { target *-*-* } } +// { dg-error ".E0436." "" { target *-*-* } .-1 } + + let U {} = u; // { dg-error "" "" { target *-*-* } } + let U { a } = u; // OK + let U { a, b } = u; // { dg-error "" "" { target *-*-* } } + let U { a, b, c } = u; // { dg-error ".E0026." "" { target *-*-* } } +// { dg-error ".E0026." "" { target *-*-* } .-1 } + let U { .. } = u; // { dg-error "" "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-1 } + let U { a, .. } = u; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-generic-rpass.rs b/gcc/testsuite/rust/rustc/ui/union/union-generic-rpass.rs new file mode 100644 index 000000000000..d9dc84dc8785 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-generic-rpass.rs @@ -0,0 +1,32 @@ +// run-pass +#![allow(dead_code)] + +use std::mem::ManuallyDrop; + +union MaybeItem { + elem: ManuallyDrop, + none: (), +} + +union U where A: Copy, B: Copy { + a: A, + b: B, +} + +unsafe fn union_transmute(a: A) -> B where A: Copy, B: Copy { + U { a }.b +} + +fn main() { + unsafe { + let b = union_transmute::<(u8, u8), u16>((1, 1)); + assert_eq!(b, (1 << 8) + 1); + + let v: Vec = vec![1, 2, 3]; + let mut i = v.iter(); + i.next(); + let mi = MaybeItem::> { elem: ManuallyDrop::new(i.next().unwrap()) }; + assert_eq!(**mi.elem, 2); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-generic.rs b/gcc/testsuite/rust/rustc/ui/union/union-generic.rs new file mode 100644 index 000000000000..ffd4ea06d355 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-generic.rs @@ -0,0 +1,13 @@ +use std::rc::Rc; + +union U { + a: T +} + +fn main() { + let u = U { a: Rc::new(0u32) }; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let u = U::> { a: Default::default() }; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-inherent-method.rs b/gcc/testsuite/rust/rustc/ui/union/union-inherent-method.rs new file mode 100644 index 000000000000..11000aeee69c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-inherent-method.rs @@ -0,0 +1,15 @@ +// run-pass + +union U { + a: u8, +} + +impl U { + fn method(&self) -> u8 { unsafe { self.a } } +} + +fn main() { + let u = U { a: 10 }; + assert_eq!(u.method(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-lint-dead-code.rs b/gcc/testsuite/rust/rustc/ui/union/union-lint-dead-code.rs new file mode 100644 index 000000000000..21d13413d9b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-lint-dead-code.rs @@ -0,0 +1,16 @@ +#![deny(dead_code)] + +union Foo { + x: usize, + b: bool, // { dg-error "" "" { target *-*-* } } + _unused: u16, +} + +fn field_read(f: Foo) -> usize { + unsafe { f.x } +} + +fn main() { + let _ = field_read(Foo { x: 2 }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-macro.rs b/gcc/testsuite/rust/rustc/ui/union/union-macro.rs new file mode 100644 index 000000000000..7b6920ecb966 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-macro.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(unused_variables)] + +macro_rules! duplicate { + ($i: item) => { + mod m1 { + $i + } + mod m2 { + $i + } + } +} + +duplicate! { + pub union U { + pub a: u8 + } +} + +fn main() { + let u1 = m1::U { a: 0 }; + let u2 = m2::U { a: 0 }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-manuallydrop-rpass.rs b/gcc/testsuite/rust/rustc/ui/union/union-manuallydrop-rpass.rs new file mode 100644 index 000000000000..d2c2862a5616 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-manuallydrop-rpass.rs @@ -0,0 +1,42 @@ +#![allow(dead_code)] +// run-pass + +use std::mem::needs_drop; +use std::mem::ManuallyDrop; + +struct NeedDrop; + +impl Drop for NeedDrop { + fn drop(&mut self) {} +} + +union UnionOk1 { + empty: (), + value: ManuallyDrop, +} + +union UnionOk2 { + value: ManuallyDrop, +} + +#[allow(dead_code)] +union UnionOk3 { + empty: (), + value: T, +} + +trait Foo { } + +trait ImpliesCopy : Copy { } + +#[allow(dead_code)] +union UnionOk4 { + value: T, +} + +fn main() { + // NeedDrop should not make needs_drop true + assert!(!needs_drop::>()); + assert!(!needs_drop::>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-move.rs b/gcc/testsuite/rust/rustc/ui/union/union-move.rs new file mode 100644 index 000000000000..8119559729f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-move.rs @@ -0,0 +1,54 @@ +//! Test the behavior of moving out of non-`Copy` union fields. +//! Avoid types that `Drop`, we want to focus on moving. +#![feature(untagged_unions)] + +use std::cell::RefCell; + +fn move_out(x: T) {} + +union U1 { + f1_nocopy: RefCell, + f2_nocopy: RefCell, + f3_copy: i32, +} + +union U2 { + f1_nocopy: RefCell, +} +impl Drop for U2 { + fn drop(&mut self) {} +} + +fn test1(x: U1) { + // Moving out of a nocopy field prevents accessing other nocopy field. + unsafe { + move_out(x.f1_nocopy); + move_out(x.f2_nocopy); // { dg-error ".E0382." "" { target *-*-* } } + } +} + +fn test2(x: U1) { + // "Moving" out of copy field doesn't prevent later field accesses. + unsafe { + move_out(x.f3_copy); + move_out(x.f2_nocopy); // no error + } +} + +fn test3(x: U1) { + // Moving out of a nocopy field prevents accessing other copy field. + unsafe { + move_out(x.f2_nocopy); + move_out(x.f3_copy); // { dg-error ".E0382." "" { target *-*-* } } + } +} + +fn test4(x: U2) { + // Cannot move out of union that implements `Drop`. + unsafe { + move_out(x.f1_nocopy); // { dg-error ".E0509." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-nodrop.rs b/gcc/testsuite/rust/rustc/ui/union/union-nodrop.rs new file mode 100644 index 000000000000..535f3d2e7c78 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-nodrop.rs @@ -0,0 +1,61 @@ +// run-pass + +#![allow(dead_code)] + +use std::mem::needs_drop; +use std::mem::ManuallyDrop; + +struct NeedDrop; + +impl Drop for NeedDrop { + fn drop(&mut self) {} +} + +// Constant expressios allow `NoDrop` to go out of scope, +// unlike a value of the interior type implementing `Drop`. +static X: () = (NoDrop { inner: ManuallyDrop::new(NeedDrop) }, ()).1; + +const Y: () = (NoDrop { inner: ManuallyDrop::new(NeedDrop) }, ()).1; + +const fn _f() { (NoDrop { inner: ManuallyDrop::new(NeedDrop) }, ()).1 } + +// A union that scrubs the drop glue from its inner type +union NoDrop { inner: ManuallyDrop } + +// Copy currently can't be implemented on drop-containing unions, +// this may change later +// https://github.com/rust-lang/rust/pull/38934#issuecomment-271219289 + +// // We should be able to implement Copy for NoDrop +// impl Copy for NoDrop {} +// impl Clone for NoDrop {fn clone(&self) -> Self { *self }} + +// // We should be able to implement Copy for things using NoDrop +// #[derive(Copy, Clone)] +struct Foo { + x: NoDrop> +} + +struct Baz { + x: NoDrop>, + y: Box, +} + +union ActuallyDrop { inner: ManuallyDrop } + +impl Drop for ActuallyDrop { + fn drop(&mut self) {} +} + +fn main() { + // NoDrop should not make needs_drop true + assert!(!needs_drop::()); + assert!(!needs_drop::>()); + assert!(!needs_drop::>>()); + // presence of other drop types should still work + assert!(needs_drop::()); + // drop impl on union itself should work + assert!(needs_drop::>()); + assert!(needs_drop::>>()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-nonrepresentable.rs b/gcc/testsuite/rust/rustc/ui/union/union-nonrepresentable.rs new file mode 100644 index 000000000000..9ac3e9eb5bfc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-nonrepresentable.rs @@ -0,0 +1,9 @@ +#![feature(untagged_unions)] + +union U { // { dg-error ".E0072." "" { target *-*-* } } + a: u8, + b: U, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-nonzero.rs b/gcc/testsuite/rust/rustc/ui/union/union-nonzero.rs new file mode 100644 index 000000000000..bd9193105519 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-nonzero.rs @@ -0,0 +1,52 @@ +// run-pass +#![allow(dead_code)] + +// Tests that unions aren't subject to unsafe non-zero/niche-filling optimizations. +// +// For example, if a union `U` can contain both a `&T` and a `*const T`, there's definitely no +// bit-value that an `Option` could reuse as `None`; this test makes sure that isn't done. +// +// Secondly, this tests the status quo (not a guarantee; subject to change!) to not apply such +// optimizations to types containing unions even if they're theoretically possible. (discussion: +// https://github.com/rust-lang/rust/issues/36394) +// +// Notably this nails down part of the behavior that `MaybeUninit` assumes: that a +// `Option>` does not take advantage of non-zero optimization, and thus is a safe +// construct. + +use std::mem::{size_of, transmute}; + +union U1 { + a: A, +} + +union U2 { + a: A, + b: B, +} + +// Option uses a value other than 0 and 1 as None +#[derive(Clone,Copy)] +enum E { + A = 0, + B = 1, +} + +fn main() { + // Unions do not participate in niche-filling/non-zero optimization... + assert!(size_of::>>() > size_of::>()); + assert!(size_of::>>() > size_of::>()); + assert!(size_of::>>() > size_of::>()); + + // ...even when theoretically possible: + assert!(size_of::>>() > size_of::>()); + assert!(size_of::>>() > size_of::>()); + + // The unused bits of the () variant can have any value. + let zeroed: U2<&u8, ()> = unsafe { transmute(std::ptr::null::()) }; + + if let None = Some(zeroed) { + panic!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-overwrite.rs b/gcc/testsuite/rust/rustc/ui/union/union-overwrite.rs new file mode 100644 index 000000000000..3135418a21fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-overwrite.rs @@ -0,0 +1,79 @@ +// run-pass + +#[repr(C)] +#[derive(Copy, Clone)] +struct Pair(T, U); +#[repr(C)] +#[derive(Copy, Clone)] +struct Triple(T, T, T); + +#[repr(C)] +union U +where + A: Copy, B: Copy +{ + a: Pair, + b: B, +} + +#[repr(C)] +union W +where + A: Copy, B: Copy +{ + a: A, + b: B, +} + +#[cfg(target_endian = "little")] +unsafe fn check() { + let mut u = U:: { b: 0xDE_DE }; + u.a.0 = 0xBE; + assert_eq!(u.b, 0xDE_BE); + + let mut u = U:: { b: 0xDEAD_DEAD }; + u.a.0 = 0xBEEF; + assert_eq!(u.b, 0xDEAD_BEEF); + + let mut u = U:: { b: 0xDEADBEEF_DEADBEEF }; + u.a.0 = 0xBAADF00D; + assert_eq!(u.b, 0xDEADBEEF_BAADF00D); + + let mut w = W::, u8>, u32> { b: 0xDEAD_DEAD }; + w.a.0 = Triple(0, 0, 0); + assert_eq!(w.b, 0xDE00_0000); + + let mut w = W::>, u32> { b: 0xDEAD_DEAD }; + w.a.1 = Triple(0, 0, 0); + assert_eq!(w.b, 0x0000_00AD); +} + +#[cfg(target_endian = "big")] +unsafe fn check() { + let mut u = U:: { b: 0xDE_DE }; + u.a.0 = 0xBE; + assert_eq!(u.b, 0xBE_DE); + + let mut u = U:: { b: 0xDEAD_DEAD }; + u.a.0 = 0xBEEF; + assert_eq!(u.b, 0xBEEF_DEAD); + + let mut u = U:: { b: 0xDEADBEEF_DEADBEEF }; + u.a.0 = 0xBAADF00D; + assert_eq!(u.b, 0xBAADF00D_DEADBEEF); + + let mut w = W::, u8>, u32> { b: 0xDEAD_DEAD }; + w.a.0 = Triple(0, 0, 0); + assert_eq!(w.b, 0x0000_00AD); + + let mut w = W::>, u32> { b: 0xDEAD_DEAD }; + w.a.1 = Triple(0, 0, 0); + assert_eq!(w.b, 0xDE00_0000); +} + +fn main() { + unsafe { + check(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-packed.rs b/gcc/testsuite/rust/rustc/ui/union/union-packed.rs new file mode 100644 index 000000000000..021fc66d7517 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-packed.rs @@ -0,0 +1,171 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_snake_case)] + +use std::mem::{size_of, size_of_val, align_of, align_of_val}; + +struct S { + a: u16, + b: [u8; 3], +} + +#[repr(packed)] +struct Sp1 { + a: u16, + b: [u8; 3], +} + +#[repr(packed(2))] +struct Sp2 { + a: u16, + b: [u8; 3], +} + +union U { + a: u16, + b: [u8; 3], +} + +#[repr(packed)] +union Up1 { + a: u16, + b: [u8; 3], +} + +#[repr(packed(2))] +union Up2 { + a: u16, + b: [u8; 3], +} + +#[repr(C, packed(4))] +union Up4c { + a: u16, + b: [u8; 3], +} + +const CS: S = S { a: 0, b: [0, 0, 0] }; +const CSP1: Sp1 = Sp1 { a: 0, b: [0, 0, 0] }; +const CSP2: Sp2 = Sp2 { a: 0, b: [0, 0, 0] }; +const CU: U = U { b: [0, 0, 0] }; +const CUP1: Up1 = Up1 { b: [0, 0, 0] }; +const CUP2: Up2 = Up2 { b: [0, 0, 0] }; +const CUP4C: Up4c = Up4c { b: [0, 0, 0] }; + +fn main() { + let s = S { a: 0, b: [0, 0, 0] }; + assert_eq!(size_of::(), 6); + assert_eq!(size_of_val(&s), 6); + assert_eq!(size_of_val(&CS), 6); + assert_eq!(align_of::(), 2); + assert_eq!(align_of_val(&s), 2); + assert_eq!(align_of_val(&CS), 2); + + let sp1 = Sp1 { a: 0, b: [0, 0, 0] }; + assert_eq!(size_of::(), 5); + assert_eq!(size_of_val(&sp1), 5); + assert_eq!(size_of_val(&CSP1), 5); + assert_eq!(align_of::(), 1); + assert_eq!(align_of_val(&sp1), 1); + assert_eq!(align_of_val(&CSP1), 1); + + let sp2 = Sp2 { a: 0, b: [0, 0, 0] }; + assert_eq!(size_of::(), 6); + assert_eq!(size_of_val(&sp2), 6); + assert_eq!(size_of_val(&CSP2), 6); + assert_eq!(align_of::(), 2); + assert_eq!(align_of_val(&sp2), 2); + assert_eq!(align_of_val(&CSP2), 2); + + let u = U { b: [0, 0, 0] }; + assert_eq!(size_of::(), 4); + assert_eq!(size_of_val(&u), 4); + assert_eq!(size_of_val(&CU), 4); + assert_eq!(align_of::(), 2); + assert_eq!(align_of_val(&u), 2); + assert_eq!(align_of_val(&CU), 2); + + let Up1 = Up1 { b: [0, 0, 0] }; + assert_eq!(size_of::(), 3); + assert_eq!(size_of_val(&Up1), 3); + assert_eq!(size_of_val(&CUP1), 3); + assert_eq!(align_of::(), 1); + assert_eq!(align_of_val(&Up1), 1); + assert_eq!(align_of_val(&CUP1), 1); + + let up2 = Up2 { b: [0, 0, 0] }; + assert_eq!(size_of::(), 4); + assert_eq!(size_of_val(&up2), 4); + assert_eq!(size_of_val(&CUP2), 4); + assert_eq!(align_of::(), 2); + assert_eq!(align_of_val(&up2), 2); + assert_eq!(align_of_val(&CUP2), 2); + + let up4c = Up4c { b: [0, 0, 0] }; + assert_eq!(size_of::(), 4); + assert_eq!(size_of_val(&up4c), 4); + assert_eq!(size_of_val(&CUP4C), 4); + assert_eq!(align_of::(), 2); + assert_eq!(align_of_val(&up4c), 2); + assert_eq!(align_of_val(&CUP4C), 2); + + hybrid::check_hybrid(); +} + +mod hybrid { + use std::mem::{size_of, align_of}; + + #[repr(packed)] + #[derive(Copy, Clone)] + struct S1 { + a: u16, + b: u8, + } + + #[repr(packed)] + union U { + s: S1, + c: u16, + } + + #[repr(packed)] + struct S2 { + d: u8, + u: U, + } + + #[repr(C, packed(2))] + struct S1C { + a: u16, + b: u8, + } + + #[repr(C, packed(2))] + union UC { + s: S1, + c: u16, + } + + #[repr(C, packed(2))] + struct S2C { + d: u8, + u: UC, + } + + pub fn check_hybrid() { + assert_eq!(align_of::(), 1); + assert_eq!(size_of::(), 3); + assert_eq!(align_of::(), 1); + assert_eq!(size_of::(), 3); + assert_eq!(align_of::(), 1); + assert_eq!(size_of::(), 4); + + assert_eq!(align_of::(), 2); + assert_eq!(size_of::(), 4); + assert_eq!(align_of::(), 2); + assert_eq!(size_of::(), 4); + assert_eq!(align_of::(), 2); + assert_eq!(size_of::(), 6); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-pat-refutability.rs b/gcc/testsuite/rust/rustc/ui/union/union-pat-refutability.rs new file mode 100644 index 000000000000..1d5b19900c05 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-pat-refutability.rs @@ -0,0 +1,55 @@ +// run-pass +#![allow(dead_code)] +#![allow(illegal_floating_point_literal_pattern)] + +#[repr(u32)] +enum Tag { I, F } + +#[repr(C)] +union U { + i: i32, + f: f32, +} + +#[repr(C)] +struct Value { + tag: Tag, + u: U, +} + +fn is_zero(v: Value) -> bool { + unsafe { + match v { + Value { tag: Tag::I, u: U { i: 0 } } => true, + Value { tag: Tag::F, u: U { f: 0.0 } } => true, + _ => false, + } + } +} + +union W { + a: u8, + b: u8, +} + +fn refut(w: W) { + unsafe { + match w { + W { a: 10 } => { + panic!(); + } + W { b } => { + assert_eq!(b, 11); + } + } + } +} + +fn main() { + let v = Value { tag: Tag::I, u: U { i: 1 } }; + assert_eq!(is_zero(v), false); + + let w = W { a: 11 }; + refut(w); +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-repr-c.rs b/gcc/testsuite/rust/rustc/ui/union/union-repr-c.rs new file mode 100644 index 000000000000..38f8fd9bae38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-repr-c.rs @@ -0,0 +1,19 @@ +#![allow(unused)] +#![deny(improper_ctypes)] + +#[repr(C)] +union U { + a: u8, +} + +union W { + a: u8, +} + +extern "C" { + static FOREIGN1: U; // OK + static FOREIGN2: W; // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-sized-field.rs b/gcc/testsuite/rust/rustc/ui/union/union-sized-field.rs new file mode 100644 index 000000000000..b27fcefde565 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-sized-field.rs @@ -0,0 +1,20 @@ +#![feature(untagged_unions)] + +union Foo { + value: T, +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +struct Foo2 { + value: T, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + t: u32, +} + +enum Foo3 { + Value(T), +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-suggest-field.rs b/gcc/testsuite/rust/rustc/ui/union/union-suggest-field.rs new file mode 100644 index 000000000000..80af1051fcb8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-suggest-field.rs @@ -0,0 +1,22 @@ +union U { + principal: u8, +} + +impl U { + fn calculate(&self) {} +} + +fn main() { + let u = U { principle: 0 }; +// { dg-error ".E0560." "" { target *-*-* } .-1 } +// { help ".E0560." "" { target *-*-* } .-2 } +// { suggestion ".E0560." "" { target *-*-* } .-3 } + let w = u.principial; // { dg-error ".E0609." "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + + let y = u.calculate; // { dg-error ".E0615." "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-trait-impl.rs b/gcc/testsuite/rust/rustc/ui/union/union-trait-impl.rs new file mode 100644 index 000000000000..37d72ea0ce99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-trait-impl.rs @@ -0,0 +1,18 @@ +// run-pass + +use std::fmt; + +union U { + a: u8 +} + +impl fmt::Display for U { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + unsafe { write!(f, "Oh hai {}", self.a) } + } +} + +fn main() { + assert_eq!(U { a: 2 }.to_string(), "Oh hai 2"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-transmute.rs b/gcc/testsuite/rust/rustc/ui/union/union-transmute.rs new file mode 100644 index 000000000000..11aec05b7eb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-transmute.rs @@ -0,0 +1,29 @@ +// run-pass + +extern crate core; +use core::f32; + +union U { + a: (u8, u8), + b: u16, +} + +union W { + a: u32, + b: f32, +} + +fn main() { + unsafe { + let mut u = U { a: (1, 1) }; + assert_eq!(u.b, (1 << 8) + 1); + u.b = (2 << 8) + 2; + assert_eq!(u.a, (2, 2)); + + let mut w = W { a: 0b0_11111111_00000000000000000000000 }; + assert_eq!(w.b, f32::INFINITY); + w.b = f32::NEG_INFINITY; + assert_eq!(w.a, 0b1_11111111_00000000000000000000000); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-unsafe.rs b/gcc/testsuite/rust/rustc/ui/union/union-unsafe.rs new file mode 100644 index 000000000000..83c2a276a583 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-unsafe.rs @@ -0,0 +1,55 @@ +use std::mem::ManuallyDrop; + +union U1 { + a: u8 +} + +union U2 { + a: ManuallyDrop +} + +union U3 { + a: ManuallyDrop +} + +union U4 { + a: T +} + +fn generic_noncopy() { + let mut u3 = U3 { a: ManuallyDrop::new(T::default()) }; + u3.a = ManuallyDrop::new(T::default()); // { dg-error ".E0133." "" { target *-*-* } } + *u3.a = T::default(); // { dg-error ".E0133." "" { target *-*-* } } +} + +fn generic_copy() { + let mut u3 = U3 { a: ManuallyDrop::new(T::default()) }; + u3.a = ManuallyDrop::new(T::default()); // OK + *u3.a = T::default(); // { dg-error ".E0133." "" { target *-*-* } } + + let mut u4 = U4 { a: T::default() }; + u4.a = T::default(); // OK +} + +fn main() { + let mut u1 = U1 { a: 10 }; // OK + let a = u1.a; // { dg-error ".E0133." "" { target *-*-* } } + u1.a = 11; // OK + + let U1 { a } = u1; // { dg-error ".E0133." "" { target *-*-* } } + if let U1 { a: 12 } = u1 {} // { dg-error ".E0133." "" { target *-*-* } } + // let U1 { .. } = u1; // OK + + let mut u2 = U2 { a: ManuallyDrop::new(String::from("old")) }; // OK + u2.a = ManuallyDrop::new(String::from("new")); // { dg-error ".E0133." "" { target *-*-* } } + *u2.a = String::from("new"); // { dg-error ".E0133." "" { target *-*-* } } + + let mut u3 = U3 { a: ManuallyDrop::new(0) }; // OK + u3.a = ManuallyDrop::new(1); // OK + *u3.a = 1; // { dg-error ".E0133." "" { target *-*-* } } + + let mut u3 = U3 { a: ManuallyDrop::new(String::from("old")) }; // OK + u3.a = ManuallyDrop::new(String::from("new")); // { dg-error ".E0133." "" { target *-*-* } } + *u3.a = String::from("new"); // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-unsized.rs b/gcc/testsuite/rust/rustc/ui/union/union-unsized.rs new file mode 100644 index 000000000000..cbf4a0a39cf7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-unsized.rs @@ -0,0 +1,17 @@ +#![feature(untagged_unions)] + +union U { + a: str, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + b: u8, +} + +union W { + a: u8, + b: str, +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/union/union-with-drop-fields.rs b/gcc/testsuite/rust/rustc/ui/union/union-with-drop-fields.rs new file mode 100644 index 000000000000..ff94a847a4ac --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/union/union-with-drop-fields.rs @@ -0,0 +1,30 @@ +#![feature(untagged_unions)] +#![allow(dead_code)] + +union U { + a: u8, // OK +} + +union W { + a: String, // { dg-error ".E0740." "" { target *-*-* } } + b: String, // OK, only one field is reported +} + +struct S(String); + +// `S` doesn't implement `Drop` trait, but still has non-trivial destructor +union Y { + a: S, // { dg-error ".E0740." "" { target *-*-* } } +} + +// We don't know if `T` is trivially-destructable or not until trans +union J { + a: T, // { dg-error ".E0740." "" { target *-*-* } } +} + +union H { + a: T, // OK, `T` is `Copy`, no destructor +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unique-object-noncopyable.rs b/gcc/testsuite/rust/rustc/ui/unique-object-noncopyable.rs new file mode 100644 index 000000000000..1077d296c2a8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique-object-noncopyable.rs @@ -0,0 +1,26 @@ +#![feature(box_syntax)] + +trait Foo { + fn f(&self); +} + +struct Bar { + x: isize, +} + +impl Drop for Bar { + fn drop(&mut self) {} +} + +impl Foo for Bar { + fn f(&self) { + println!("hi"); + } +} + +fn main() { + let x = box Bar { x: 10 }; + let y: Box = x as Box; + let _z = y.clone(); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique-pinned-nocopy.rs b/gcc/testsuite/rust/rustc/ui/unique-pinned-nocopy.rs new file mode 100644 index 000000000000..3d4e275c6a24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique-pinned-nocopy.rs @@ -0,0 +1,15 @@ +#[derive(Debug)] +struct R { + b: bool, +} + +impl Drop for R { + fn drop(&mut self) {} +} + +fn main() { + let i = Box::new(R { b: true }); + let _j = i.clone(); // { dg-error ".E0599." "" { target *-*-* } } + println!("{:?}", i); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-assign-copy.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-assign-copy.rs new file mode 100644 index 000000000000..3a5c052f88c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-assign-copy.rs @@ -0,0 +1,14 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let mut i: Box<_> = box 1; + // Should be a copy + let mut j; + j = i.clone(); + *i = 2; + *j = 3; + assert_eq!(*i, 2); + assert_eq!(*j, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-assign-drop.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-assign-drop.rs new file mode 100644 index 000000000000..aca084f591fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-assign-drop.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(unused_assignments)] + +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box 1; + let mut j: Box<_> = box 2; + // Should drop the previous value of j + j = i; + assert_eq!(*j, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-assign-generic.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-assign-generic.rs new file mode 100644 index 000000000000..ca00b97fdb51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-assign-generic.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(box_syntax)] + +fn f(t: T) -> T { + let t1 = t; + t1 +} + +pub fn main() { + let t = f::>(box 100); + assert_eq!(t, box 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-assign.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-assign.rs new file mode 100644 index 000000000000..b7efc0f76c89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-assign.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(unused_mut)] +#![feature(box_syntax)] + +pub fn main() { + let mut i: Box<_>; + i = box 1; + assert_eq!(*i, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-autoderef-field.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-autoderef-field.rs new file mode 100644 index 000000000000..15a26eb758d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-autoderef-field.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(box_syntax)] + +struct J { j: isize } + +pub fn main() { + let i: Box<_> = box J { + j: 100 + }; + assert_eq!(i.j, 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-autoderef-index.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-autoderef-index.rs new file mode 100644 index 000000000000..47a063cba48d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-autoderef-index.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box vec![100]; + assert_eq!((*i)[0], 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-cmp.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-cmp.rs new file mode 100644 index 000000000000..afbfa15a5ceb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-cmp.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(unused_allocation)] +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box 100; + assert_eq!(i, box 100); + assert!(i < box 101); + assert!(i <= box 100); + assert!(i > box 99); + assert!(i >= box 99); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-containing-tag.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-containing-tag.rs new file mode 100644 index 000000000000..ce20dd4d4808 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-containing-tag.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { + enum t { t1(isize), t2(isize), } + + let _x: Box<_> = box t::t1(10); + + /*alt *x { + t1(a) { + assert_eq!(a, 10); + } + _ { panic!(); } + }*/ + + /*alt x { + box t1(a) { + assert_eq!(a, 10); + } + _ { panic!(); } + }*/ +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-create.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-create.rs new file mode 100644 index 000000000000..2f98aab72985 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-create.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { + let _: Box<_> = box 100; +} + +fn vec() { + vec![0]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-decl-init-copy.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-decl-init-copy.rs new file mode 100644 index 000000000000..11049152b208 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-decl-init-copy.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let mut i: Box<_> = box 1; + // Should be a copy + let mut j = i.clone(); + *i = 2; + *j = 3; + assert_eq!(*i, 2); + assert_eq!(*j, 3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-decl-init.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-decl-init.rs new file mode 100644 index 000000000000..8321f55ff05d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-decl-init.rs @@ -0,0 +1,9 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box 1; + let j = i; + assert_eq!(*j, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-decl-move.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-decl-move.rs new file mode 100644 index 000000000000..3cb40c3fdb71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-decl-move.rs @@ -0,0 +1,9 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box 100; + let j = i; + assert_eq!(*j, 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-decl.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-decl.rs new file mode 100644 index 000000000000..3665d4fa223d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-decl.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] + + +pub fn main() { + let _: Box; +} + +fn f(_i: Box) -> Box { + panic!(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-deref.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-deref.rs new file mode 100644 index 000000000000..6d10fd9ca4cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-deref.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box 100; + assert_eq!(*i, 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-destructure.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-destructure.rs new file mode 100644 index 000000000000..16cdf9d94382 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-destructure.rs @@ -0,0 +1,11 @@ +// run-pass +#![feature(box_patterns)] +#![feature(box_syntax)] + +struct Foo { a: isize, b: isize } + +pub fn main() { + let box Foo{a, b} = box Foo{a: 100, b: 200}; + assert_eq!(a + b, 300); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-drop-complex.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-drop-complex.rs new file mode 100644 index 000000000000..6bac08572c23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-drop-complex.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { + let _x: Box<_> = box vec![0,0,0,0,0]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-ffi-symbols.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-ffi-symbols.rs new file mode 100644 index 000000000000..cacc91c452a9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-ffi-symbols.rs @@ -0,0 +1,17 @@ +// run-pass +// We used to have a __rust_abi shim that resulted in duplicated symbols +// whenever the item path wasn't enough to disambiguate between them. +fn main() { + let a = { + extern fn good() -> i32 { return 0; } + good as extern fn() -> i32 + }; + let b = { + extern fn good() -> i32 { return 5; } + good as extern fn() -> i32 + }; + + assert!(a != b); + assert_eq!((a(), b()), (0, 5)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-fn-arg-move.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-fn-arg-move.rs new file mode 100644 index 000000000000..ac40ae20d2ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-fn-arg-move.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(box_syntax)] + +fn f(i: Box) { + assert_eq!(*i, 100); +} + +pub fn main() { + let i = box 100; + f(i); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-fn-arg-mut.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-fn-arg-mut.rs new file mode 100644 index 000000000000..4a2fde036e67 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-fn-arg-mut.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(box_syntax)] + +fn f(i: &mut Box) { + *i = box 200; +} + +pub fn main() { + let mut i = box 100; + f(&mut i); + assert_eq!(*i, 200); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-fn-arg.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-fn-arg.rs new file mode 100644 index 000000000000..438adcccb4fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-fn-arg.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(box_syntax)] + +fn f(i: Box) { + assert_eq!(*i, 100); +} + +pub fn main() { + f(box 100); + let i = box 100; + f(i); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-fn-ret.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-fn-ret.rs new file mode 100644 index 000000000000..dc44337d7709 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-fn-ret.rs @@ -0,0 +1,11 @@ +// run-pass +#![feature(box_syntax)] + +fn f() -> Box { + box 100 +} + +pub fn main() { + assert_eq!(f(), box 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-generic-assign.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-generic-assign.rs new file mode 100644 index 000000000000..2e6c15253789 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-generic-assign.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +// Issue #976 + + +// pretty-expanded FIXME #23616 + +fn f(x: Box) { + let _x2 = x; +} +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-in-tag.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-in-tag.rs new file mode 100644 index 000000000000..721bef789d7d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-in-tag.rs @@ -0,0 +1,23 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +#![feature(box_syntax)] + +fn test1() { + enum bar { u(Box), w(isize), } + + let x = bar::u(box 10); + assert!(match x { + bar::u(a) => { + println!("{}", a); + *a + } + _ => { 66 } + } == 10); +} + +pub fn main() { + test1(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-in-vec-copy.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-in-vec-copy.rs new file mode 100644 index 000000000000..7d917fbe828d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-in-vec-copy.rs @@ -0,0 +1,17 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let mut a: Vec> = vec![box 10]; + let b = a.clone(); + + assert_eq!(*a[0], 10); + assert_eq!(*b[0], 10); + + // This should only modify the value in a, not b + *a[0] = 20; + + assert_eq!(*a[0], 20); + assert_eq!(*b[0], 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-in-vec.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-in-vec.rs new file mode 100644 index 000000000000..0f2bdd4e35e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-in-vec.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let vect : Vec> = vec![box 100]; + assert_eq!(vect[0], box 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-init.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-init.rs new file mode 100644 index 000000000000..4816c868f66a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-init.rs @@ -0,0 +1,9 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { + let _i: Box<_> = box 100; +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-kinds.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-kinds.rs new file mode 100644 index 000000000000..361b30f0dfb8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-kinds.rs @@ -0,0 +1,66 @@ +// run-pass +#![feature(box_syntax)] + +use std::cmp::PartialEq; +use std::fmt::Debug; + +fn sendable() { + + fn f(i: T, j: T) { + assert_eq!(i, j); + } + + fn g(i: T, j: T) { + assert!(i != j); + } + + let i: Box<_> = box 100; + let j: Box<_> = box 100; + f(i, j); + let i: Box<_> = box 100; + let j: Box<_> = box 101; + g(i, j); +} + +fn copyable() { + + fn f(i: T, j: T) { + assert_eq!(i, j); + } + + fn g(i: T, j: T) { + assert!(i != j); + } + + let i: Box<_> = box 100; + let j: Box<_> = box 100; + f(i, j); + let i: Box<_> = box 100; + let j: Box<_> = box 101; + g(i, j); +} + +fn noncopyable() { + + fn f(i: T, j: T) { + assert_eq!(i, j); + } + + fn g(i: T, j: T) { + assert!(i != j); + } + + let i: Box<_> = box 100; + let j: Box<_> = box 100; + f(i, j); + let i: Box<_> = box 100; + let j: Box<_> = box 101; + g(i, j); +} + +pub fn main() { + sendable(); + copyable(); + noncopyable(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-log.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-log.rs new file mode 100644 index 000000000000..c405a641713d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-log.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box 100; + println!("{}", i); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-match-discrim.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-match-discrim.rs new file mode 100644 index 000000000000..30ccee7c5764 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-match-discrim.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +// Issue #961 + +// pretty-expanded FIXME #23616 + +fn altsimple() { + match Box::new(true) { + _ => { } + } +} +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-move-drop.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-move-drop.rs new file mode 100644 index 000000000000..a82ebec3c536 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-move-drop.rs @@ -0,0 +1,12 @@ +// run-pass + +#![allow(unused_variables)] +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box 100; + let j: Box<_> = box 200; + let j = i; + assert_eq!(*j, 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-move-temp.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-move-temp.rs new file mode 100644 index 000000000000..ca502cffeca9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-move-temp.rs @@ -0,0 +1,10 @@ +// run-pass +#![allow(unused_mut)] +#![feature(box_syntax)] + +pub fn main() { + let mut i: Box<_>; + i = box 100; + assert_eq!(*i, 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-move.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-move.rs new file mode 100644 index 000000000000..60dd053b8568 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-move.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_mut)] +#![feature(box_syntax)] + +pub fn main() { + let i: Box<_> = box 100; + let mut j; + j = i; + assert_eq!(*j, 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-mutable.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-mutable.rs new file mode 100644 index 000000000000..04218c738a68 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-mutable.rs @@ -0,0 +1,9 @@ +// run-pass +#![feature(box_syntax)] + +pub fn main() { + let mut i: Box<_> = box 0; + *i = 1; + assert_eq!(*i, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-object-move.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-object-move.rs new file mode 100644 index 000000000000..4e36785cd64e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-object-move.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(dead_code)] +// Issue #5192 + +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub trait EventLoop { fn foo(&self) {} } + +pub struct UvEventLoop { + uvio: isize +} + +impl EventLoop for UvEventLoop { } + +pub fn main() { + let loop_: Box = box UvEventLoop { uvio: 0 } as Box; + let _loop2_ = loop_; +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-pat-2.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-pat-2.rs new file mode 100644 index 000000000000..263e44cf46b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-pat-2.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +#![allow(non_shorthand_field_patterns)] + +#![feature(box_patterns)] +#![feature(box_syntax)] + +struct Foo {a: isize, b: usize} + +enum bar { u(Box), w(isize), } + +pub fn main() { + assert!(match bar::u(box Foo{a: 10, b: 40}) { + bar::u(box Foo{a: a, b: b}) => { a + (b as isize) } + _ => { 66 } + } == 50); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-pat-3.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-pat-3.rs new file mode 100644 index 000000000000..bce489ea5923 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-pat-3.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +#![feature(box_syntax)] + +enum bar { u(Box), w(isize), } + +pub fn main() { + assert!(match bar::u(box 10) { + bar::u(a) => { + println!("{}", a); + *a + } + _ => { 66 } + } == 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-pat.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-pat.rs new file mode 100644 index 000000000000..584f1f00967c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-pat.rs @@ -0,0 +1,16 @@ +// run-pass + +#![feature(box_patterns)] +#![feature(box_syntax)] + +fn simple() { + match box true { + box true => { } + _ => { panic!(); } + } +} + +pub fn main() { + simple(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-rec.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-rec.rs new file mode 100644 index 000000000000..d18fe8690fbe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-rec.rs @@ -0,0 +1,11 @@ +// run-pass +#![feature(box_syntax)] + +struct X { x: isize } + +pub fn main() { + let x: Box<_> = box X {x: 1}; + let bar = x; + assert_eq!(bar.x, 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-send-2.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-send-2.rs new file mode 100644 index 000000000000..c745afd65000 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-send-2.rs @@ -0,0 +1,36 @@ +// run-pass +#![allow(unused_must_use)] +// ignore-emscripten no threads support + +#![feature(box_syntax)] + +use std::sync::mpsc::{channel, Sender}; +use std::thread; + +fn child(tx: &Sender>, i: usize) { + tx.send(box i).unwrap(); +} + +pub fn main() { + let (tx, rx) = channel(); + let n = 100; + let mut expected = 0; + let ts = (0..n).map(|i| { + expected += i; + let tx = tx.clone(); + thread::spawn(move|| { + child(&tx, i) + }) + }).collect::>(); + + let mut actual = 0; + for _ in 0..n { + let j = rx.recv().unwrap(); + actual += *j; + } + + assert_eq!(expected, actual); + + for t in ts { t.join(); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-send.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-send.rs new file mode 100644 index 000000000000..25467a935452 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-send.rs @@ -0,0 +1,12 @@ +// run-pass +#![feature(box_syntax)] + +use std::sync::mpsc::channel; + +pub fn main() { + let (tx, rx) = channel::>(); + tx.send(box 100).unwrap(); + let v = rx.recv().unwrap(); + assert_eq!(v, box 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unique/unique-swap.rs b/gcc/testsuite/rust/rustc/ui/unique/unique-swap.rs new file mode 100644 index 000000000000..b81dd356196e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unique/unique-swap.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(box_syntax)] + +use std::mem::swap; + +pub fn main() { + let mut i: Box<_> = box 100; + let mut j: Box<_> = box 200; + swap(&mut i, &mut j); + assert_eq!(i, box 200); + assert_eq!(j, box 100); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unit.rs b/gcc/testsuite/rust/rustc/ui/unit.rs new file mode 100644 index 000000000000..a53b36701536 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unit.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(unused_assignments)] +#![allow(unknown_lints)] +// pretty-expanded FIXME #23616 + +#![allow(unused_variables)] +#![allow(dead_assignment)] + +fn f(u: ()) { return u; } + +pub fn main() { + let u1: () = (); + let mut u2: () = f(u1); + u2 = (); + return (); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unknown-language-item.rs b/gcc/testsuite/rust/rustc/ui/unknown-language-item.rs new file mode 100644 index 000000000000..773dd017a9dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unknown-language-item.rs @@ -0,0 +1,11 @@ +#![allow(unused)] +#![feature(lang_items)] + +#[lang = "foo"] +fn bar() -> ! { +// { dg-error ".E0522." "" { target *-*-* } .-2 } + loop {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unknown-lint-tool-name.rs b/gcc/testsuite/rust/rustc/ui/unknown-lint-tool-name.rs new file mode 100644 index 000000000000..ba5e084c42ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unknown-lint-tool-name.rs @@ -0,0 +1,9 @@ +#![deny(foo::bar)] // { dg-error ".E0710." "" { target *-*-* } } +// { dg-error ".E0710." "" { target *-*-* } .-2 } +// { dg-error ".E0710." "" { target *-*-* } .-3 } + +#[allow(foo::bar)] // { dg-error ".E0710." "" { target *-*-* } } +// { dg-error ".E0710." "" { target *-*-* } .-2 } +// { dg-error ".E0710." "" { target *-*-* } .-3 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unknown-llvm-arg.rs b/gcc/testsuite/rust/rustc/ui/unknown-llvm-arg.rs new file mode 100644 index 000000000000..db2ad8abc7c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unknown-llvm-arg.rs @@ -0,0 +1,23 @@ +// compile-flags: -Cllvm-args=-not-a-real-llvm-arg +// normalize-stderr-test "--help" -> "-help" +// normalize-stderr-test "\n(\n|.)*" -> "" + +// I'm seeing "--help" locally, but "-help" in CI, so I'm normalizing it to just "-help". + +// Note that the rustc-supplied "program name", given when invoking LLVM, is used by LLVM to +// generate user-facing error messages and a usage (--help) messages. If the program name is +// `rustc`, the usage message in response to `--llvm-args="--help"` starts with: +// ``` +// USAGE: rustc [options] +// ``` +// followed by the list of options not to `rustc` but to `llvm`. +// +// On the other hand, if the program name is set to `rustc -Cllvm-args="..." with`, the usage +// message is more clear: +// ``` +// USAGE: rustc -Cllvm-args="..." with [options] +// ``` +// This test captures the effect of the current program name setting on LLVM command line +// error messages. +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unknown-tool-name.rs b/gcc/testsuite/rust/rustc/ui/unknown-tool-name.rs new file mode 100644 index 000000000000..37c1203a1f45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unknown-tool-name.rs @@ -0,0 +1,3 @@ +#[foo::bar] // { dg-error ".E0433." "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unnamed_argument_mode.rs b/gcc/testsuite/rust/rustc/ui/unnamed_argument_mode.rs new file mode 100644 index 000000000000..0de770fe0fe8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unnamed_argument_mode.rs @@ -0,0 +1,15 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn good(_a: &isize) { +} + +// unnamed argument &isize is now parse x: &isize + +fn called(_f: F) where F: FnOnce(&isize) { +} + +pub fn main() { + called(good); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unnecessary-extern-crate.rs b/gcc/testsuite/rust/rustc/ui/unnecessary-extern-crate.rs new file mode 100644 index 000000000000..1f486f412145 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unnecessary-extern-crate.rs @@ -0,0 +1,72 @@ +// edition:2018 + +#![deny(unused_extern_crates)] +#![feature(test, rustc_private, crate_visibility_modifier)] + +extern crate libc; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } +extern crate libc as x; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + +extern crate proc_macro; + +#[macro_use] +extern crate test; + +pub extern crate test as y; + +pub extern crate alloc; + +pub(crate) extern crate alloc as a; + +crate extern crate alloc as b; + +mod foo { + pub(in crate::foo) extern crate alloc as c; + + pub(super) extern crate alloc as d; + + extern crate libc; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + + extern crate libc as x; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + + pub extern crate test; + + pub extern crate test as y; + + mod bar { + extern crate libc; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + + extern crate libc as x; +// { dg-error "" "" { target *-*-* } .-1 } +// { help "" "" { target *-*-* } .-2 } + + pub(in crate::foo::bar) extern crate alloc as e; + + fn dummy() { + e::string::String::new(); + } + } + + fn dummy() { + c::string::String::new(); + d::string::String::new(); + } +} + + +fn main() { + a::string::String::new(); + b::string::String::new(); + + proc_macro::TokenStream::new(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unop-move-semantics.rs b/gcc/testsuite/rust/rustc/ui/unop-move-semantics.rs new file mode 100644 index 000000000000..aae0329a4ff0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unop-move-semantics.rs @@ -0,0 +1,33 @@ +// Test that move restrictions are enforced on overloaded unary operations + +use std::ops::Not; + +fn move_then_borrow + Clone>(x: T) { + !x; + + x.clone(); // { dg-error ".E0382." "" { target *-*-* } } +} + +fn move_borrowed>(x: T, mut y: T) { + let m = &x; + let n = &mut y; + + !x; // { dg-error ".E0505." "" { target *-*-* } } + + !y; // { dg-error ".E0505." "" { target *-*-* } } + use_mut(n); use_imm(m); +} +fn illegal_dereference>(mut x: T, y: T) { + let m = &mut x; + let n = &y; + + !*m; // { dg-error ".E0507." "" { target *-*-* } } + + !*n; // { dg-error ".E0507." "" { target *-*-* } } + use_imm(n); use_mut(m); +} +fn main() {} + +fn use_mut(_: &mut T) { } +fn use_imm(_: &T) { } + diff --git a/gcc/testsuite/rust/rustc/ui/unop-neg-bool.rs b/gcc/testsuite/rust/rustc/ui/unop-neg-bool.rs new file mode 100644 index 000000000000..0232c59165ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unop-neg-bool.rs @@ -0,0 +1,4 @@ +fn main() { + -true; // { dg-error ".E0600." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unreachable-code-1.rs b/gcc/testsuite/rust/rustc/ui/unreachable-code-1.rs new file mode 100644 index 000000000000..31d27673f2a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unreachable-code-1.rs @@ -0,0 +1,20 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(unreachable_code)] + +#![allow(unused_variables)] +#![allow(dead_code)] + +fn id(x: bool) -> bool { x } + +fn call_id() { + let c = panic!(); + id(c); +} + +fn call_id_3() { id(return) && id(return); } + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/unreachable-code-ret.rs b/gcc/testsuite/rust/rustc/ui/unreachable-code-ret.rs new file mode 100644 index 000000000000..f58437a48bb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unreachable-code-ret.rs @@ -0,0 +1,9 @@ +// error-pattern: unreachable statement + +#![deny(unreachable_code)] + +fn main() { + return; + println!("Paul is dead"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unreachable-code.rs b/gcc/testsuite/rust/rustc/ui/unreachable-code.rs new file mode 100644 index 000000000000..934f1378d243 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unreachable-code.rs @@ -0,0 +1,29 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(dead_code)] + +#![allow(path_statements)] +#![allow(unreachable_code)] +#![allow(unused_variables)] + +fn id(x: bool) -> bool { x } + +fn call_id() { + let c = panic!(); + id(c); +} + +fn call_id_2() { id(true) && id(return); } + +fn call_id_3() { id(return) && id(return); } + +fn ret_guard() { + match 2 { + x if (return) => { x; } + _ => {} + } +} + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unresolved/unresolved-extern-mod-suggestion.rs b/gcc/testsuite/rust/rustc/ui/unresolved/unresolved-extern-mod-suggestion.rs new file mode 100644 index 000000000000..26c48264e933 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unresolved/unresolved-extern-mod-suggestion.rs @@ -0,0 +1,6 @@ +extern crate core; +use core; +// { dg-error ".E0254." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unresolved/unresolved-import-recovery.rs b/gcc/testsuite/rust/rustc/ui/unresolved/unresolved-import-recovery.rs new file mode 100644 index 000000000000..273504e47c09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unresolved/unresolved-import-recovery.rs @@ -0,0 +1,18 @@ +// Check that unresolved imports do not create additional errors and ICEs + +mod m { + pub use unresolved; // { dg-error ".E0432." "" { target *-*-* } } + + fn f() { + let unresolved = 0; // OK + } +} + +fn main() { + match 0u8 { + m::unresolved => {} // OK + m::unresolved(..) => {} // OK + m::unresolved{..} => {} // OK + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unresolved/unresolved-import.rs b/gcc/testsuite/rust/rustc/ui/unresolved/unresolved-import.rs new file mode 100644 index 000000000000..cc0d3f6b3c19 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unresolved/unresolved-import.rs @@ -0,0 +1,56 @@ +use foo::bar; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +use bar::Baz as x; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +// { suggestion "" "" { target *-*-* } .-4 } + +use food::baz; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +// { suggestion "" "" { target *-*-* } .-4 } + +use food::{beens as Foo}; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +// { help "" "" { target *-*-* } .-3 } +// { suggestion "" "" { target *-*-* } .-4 } + +mod bar { + pub struct Bar; +} + +mod food { + pub use self::zug::baz::{self as bag, Foobar as beans}; + + mod zug { + pub mod baz { + pub struct Foobar; + } + } +} + +mod m { + enum MyEnum { + MyVariant + } + + use MyEnum::*; // { dg-error ".E0432." "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } +} + +mod items { + enum Enum { + Variant + } + + use Enum::*; // { dg-error ".E0432." "" { target *-*-* } } +// { help "" "" { target *-*-* } .-2 } +// { suggestion "" "" { target *-*-* } .-3 } + + fn item() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unrestricted-attribute-tokens.rs b/gcc/testsuite/rust/rustc/ui/unrestricted-attribute-tokens.rs new file mode 100644 index 000000000000..b0ea0c2bc1ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unrestricted-attribute-tokens.rs @@ -0,0 +1,9 @@ +// build-pass (FIXME(62277): could be check-pass?) + +#![feature(rustc_attrs)] + +#[rustc_dummy(a b c d)] +#[rustc_dummy[a b c d]] +#[rustc_dummy{a b c d}] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe-coercion.rs b/gcc/testsuite/rust/rustc/ui/unsafe-coercion.rs new file mode 100644 index 000000000000..5121039c05fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe-coercion.rs @@ -0,0 +1,18 @@ +// run-pass +// Check that safe fns are not a subtype of unsafe fns. + + +fn foo(x: i32) -> i32 { + x * 22 +} + +fn bar(x: fn(i32) -> i32) -> unsafe fn(i32) -> i32 { + x // OK, coercion! +} + +fn main() { + let f = bar(foo); + let x = unsafe { f(2) }; + assert_eq!(x, 44); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe-fn-called-from-unsafe-blk.rs b/gcc/testsuite/rust/rustc/ui/unsafe-fn-called-from-unsafe-blk.rs new file mode 100644 index 000000000000..2ea146bf5298 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe-fn-called-from-unsafe-blk.rs @@ -0,0 +1,19 @@ +// run-pass + +#![allow(dead_code)] +// +// See also: compile-fail/unsafe-fn-called-from-safe.rs + +// pretty-expanded FIXME #23616 + +unsafe fn f() { return; } + +fn g() { + unsafe { + f(); + } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe-fn-called-from-unsafe-fn.rs b/gcc/testsuite/rust/rustc/ui/unsafe-fn-called-from-unsafe-fn.rs new file mode 100644 index 000000000000..a0a493ec24b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe-fn-called-from-unsafe-fn.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(dead_code)] +// +// See also: compile-fail/unsafe-fn-called-from-safe.rs + +// pretty-expanded FIXME #23616 + +unsafe fn f() { return; } + +unsafe fn g() { + f(); +} + +pub fn main() { + return; +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe-pointer-assignability.rs b/gcc/testsuite/rust/rustc/ui/unsafe-pointer-assignability.rs new file mode 100644 index 000000000000..a03b944b7e9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe-pointer-assignability.rs @@ -0,0 +1,12 @@ +// run-pass + +fn f(x: *const isize) { + unsafe { + assert_eq!(*x, 3); + } +} + +pub fn main() { + f(&3); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints.rs b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints.rs new file mode 100644 index 000000000000..f4dcbbac5e0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints.rs @@ -0,0 +1,9 @@ +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero(pub(crate) T); +fn main() { + let _x = NonZero(0); // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints2.rs b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints2.rs new file mode 100644 index 000000000000..52f518d0bbe3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints2.rs @@ -0,0 +1,10 @@ +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero(pub(crate) T); +fn main() { + let mut x = unsafe { NonZero(1) }; + let y = &mut x.0; // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints2_const.rs b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints2_const.rs new file mode 100644 index 000000000000..cd3ec7dd0138 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints2_const.rs @@ -0,0 +1,21 @@ +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero(pub(crate) T); +fn main() { +} + +const fn foo() -> NonZero { + let mut x = unsafe { NonZero(1) }; + let y = &mut x.0; // { dg-error ".E0133." "" { target *-*-* } } +// { dg-error ".E0133." "" { target *-*-* } .-1 } + unsafe { NonZero(1) } +} + +const fn bar() -> NonZero { + let mut x = unsafe { NonZero(1) }; + let y = unsafe { &mut x.0 }; // { dg-error ".E0658." "" { target *-*-* } } + unsafe { NonZero(1) } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints3.rs b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints3.rs new file mode 100644 index 000000000000..200c652afaf0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints3.rs @@ -0,0 +1,12 @@ +#![feature(rustc_attrs)] + +use std::cell::Cell; + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero(pub(crate) T); +fn main() { + let mut x = unsafe { NonZero(Cell::new(1)) }; + let y = &x.0; // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints3_const.rs b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints3_const.rs new file mode 100644 index 000000000000..a7e7cd52cf74 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints3_const.rs @@ -0,0 +1,22 @@ +#![feature(rustc_attrs)] + +use std::cell::Cell; + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero(pub(crate) T); +fn main() {} + +const fn foo() -> NonZero> { + let mut x = unsafe { NonZero(Cell::new(1)) }; + let y = &x.0; // { dg-error ".E0133." "" { target *-*-* } } +// { dg-error ".E0133." "" { target *-*-* } .-1 } + unsafe { NonZero(Cell::new(1)) } +} + +const fn bar() -> NonZero> { + let mut x = unsafe { NonZero(Cell::new(1)) }; + let y = unsafe { &x.0 }; // { dg-error ".E0492." "" { target *-*-* } } + unsafe { NonZero(Cell::new(1)) } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints4.rs b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints4.rs new file mode 100644 index 000000000000..599e24f9ba74 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints4.rs @@ -0,0 +1,10 @@ +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero(pub(crate) T); +fn main() { + let mut x = unsafe { NonZero(1) }; + x.0 = 0; // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints4_const.rs b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints4_const.rs new file mode 100644 index 000000000000..45ae97242879 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints4_const.rs @@ -0,0 +1,20 @@ +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero(pub(crate) T); +fn main() {} + +const fn foo() -> NonZero { + let mut x = unsafe { NonZero(1) }; + x.0 = 0; +// { dg-error ".E0133." "" { target *-*-* } .-1 } + x +} + +const fn bar() -> NonZero { + let mut x = unsafe { NonZero(1) }; + unsafe { x.0 = 0 }; // this is UB + x +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints_const.rs b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints_const.rs new file mode 100644 index 000000000000..a74c787ba03e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints_const.rs @@ -0,0 +1,12 @@ +#![feature(rustc_attrs)] + +#[rustc_layout_scalar_valid_range_start(1)] +#[repr(transparent)] +pub(crate) struct NonZero(pub(crate) T); +fn main() {} + +const fn foo() -> NonZero { NonZero(0) } +// { dg-error ".E0133." "" { target *-*-* } .-1 } + +const fn bar() -> NonZero { unsafe { NonZero(0) } } + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints_macro.rs b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints_macro.rs new file mode 100644 index 000000000000..ed5f2a681a39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/ranged_ints_macro.rs @@ -0,0 +1,17 @@ +// build-pass +#![feature(rustc_attrs)] + +macro_rules! apply { + ($val:expr) => { + #[rustc_layout_scalar_valid_range_start($val)] + #[repr(transparent)] + pub(crate) struct NonZero(pub(crate) T); + } +} + +apply!(1); + +fn main() { + let _x = unsafe { NonZero(1) }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs b/gcc/testsuite/rust/rustc/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs new file mode 100644 index 000000000000..22f55912f68b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/rfc-2585-safe_packed_borrows-in-unsafe-fn.rs @@ -0,0 +1,68 @@ +#![feature(unsafe_block_in_unsafe_fn)] + +#[repr(packed)] +pub struct Packed { + data: &'static u32, +} + +const PACKED: Packed = Packed { data: &0 }; + +#[allow(safe_packed_borrows)] +#[allow(unsafe_op_in_unsafe_fn)] +unsafe fn allow_allow() { + &PACKED.data; // allowed +} + +#[allow(safe_packed_borrows)] +#[warn(unsafe_op_in_unsafe_fn)] +unsafe fn allow_warn() { + &PACKED.data; // allowed +} + +#[allow(safe_packed_borrows)] +#[deny(unsafe_op_in_unsafe_fn)] +unsafe fn allow_deny() { + &PACKED.data; // allowed +} + +#[warn(safe_packed_borrows)] +#[allow(unsafe_op_in_unsafe_fn)] +unsafe fn warn_allow() { + &PACKED.data; // allowed +} + +#[warn(safe_packed_borrows)] +#[warn(unsafe_op_in_unsafe_fn)] +unsafe fn warn_warn() { + &PACKED.data; // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +#[warn(safe_packed_borrows)] +#[deny(unsafe_op_in_unsafe_fn)] +unsafe fn warn_deny() { + &PACKED.data; // { dg-warning "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +#[deny(safe_packed_borrows)] +#[allow(unsafe_op_in_unsafe_fn)] +unsafe fn deny_allow() { + &PACKED.data; // allowed +} + +#[deny(safe_packed_borrows)] +#[warn(unsafe_op_in_unsafe_fn)] +unsafe fn deny_warn() { + &PACKED.data; // { dg-warning "" "" { target *-*-* } } +} + +#[deny(safe_packed_borrows)] +#[deny(unsafe_op_in_unsafe_fn)] +unsafe fn deny_deny() { + &PACKED.data; // { dg-error "" "" { target *-*-* } } +// { dg-warning "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs b/gcc/testsuite/rust/rustc/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs new file mode 100644 index 000000000000..7326c6ae47b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs @@ -0,0 +1,77 @@ +#![feature(unsafe_block_in_unsafe_fn)] +#![deny(unsafe_op_in_unsafe_fn)] +#![deny(unused_unsafe)] + +unsafe fn unsf() {} +const PTR: *const () = std::ptr::null(); +static mut VOID: () = (); + +unsafe fn deny_level() { + unsf(); +// { dg-error ".E0133." "" { target *-*-* } .-1 } + *PTR; +// { dg-error "" "" { target *-*-* } .-1 } + VOID = (); +// { dg-error "" "" { target *-*-* } .-1 } +} + +// Check that `unsafe_op_in_unsafe_fn` works starting from the `warn` level. +#[warn(unsafe_op_in_unsafe_fn)] +#[deny(warnings)] +unsafe fn warning_level() { + unsf(); +// { dg-error ".E0133." "" { target *-*-* } .-1 } + *PTR; +// { dg-error "" "" { target *-*-* } .-1 } + VOID = (); +// { dg-error "" "" { target *-*-* } .-1 } +} + +unsafe fn explicit_block() { + // no error + unsafe { + unsf(); + *PTR; + VOID = (); + } +} + +unsafe fn two_explicit_blocks() { + unsafe { unsafe { unsf() } } +// { dg-error "" "" { target *-*-* } .-1 } +} + +#[allow(unsafe_op_in_unsafe_fn)] +unsafe fn allow_level() { + // lint allowed -> no error + unsf(); + *PTR; + VOID = (); + + unsafe { unsf() } +// { dg-error "" "" { target *-*-* } .-1 } +} + +unsafe fn nested_allow_level() { + #[allow(unsafe_op_in_unsafe_fn)] + { + // lint allowed -> no error + unsf(); + *PTR; + VOID = (); + + unsafe { unsf() } +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +fn main() { + unsf(); +// { dg-error ".E0133." "" { target *-*-* } .-1 } + #[allow(unsafe_op_in_unsafe_fn)] + { + unsf(); +// { dg-error ".E0133." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-around-compiler-generated-unsafe.rs b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-around-compiler-generated-unsafe.rs new file mode 100644 index 000000000000..c8511a18dc28 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-around-compiler-generated-unsafe.rs @@ -0,0 +1,8 @@ +// issue #12418 + +#![deny(unused_unsafe)] + +fn main() { + unsafe { println!("foo"); } // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-block-without-braces.rs b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-block-without-braces.rs new file mode 100644 index 000000000000..86d576ec00f7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-block-without-braces.rs @@ -0,0 +1,7 @@ +fn main() { + unsafe //{ + std::mem::transmute::(1.0); + //} +} +// { dg-error "" "" { target *-*-* } .-3 } + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-const-fn.rs b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-const-fn.rs new file mode 100644 index 000000000000..c4a86447bdf2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-const-fn.rs @@ -0,0 +1,13 @@ +// A quick test of 'unsafe const fn' functionality + +const unsafe fn dummy(v: u32) -> u32 { + !v +} + +const VAL: u32 = dummy(0xFFFF); +// { dg-error ".E0133." "" { target *-*-* } .-1 } + +fn main() { + assert_eq!(VAL, 0xFFFF0000); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-assign-deref-ptr.rs b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-assign-deref-ptr.rs new file mode 100644 index 000000000000..820a7e6d537b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-assign-deref-ptr.rs @@ -0,0 +1,8 @@ +fn f(p: *mut u8) { + *p = 0; // { dg-error ".E0133." "" { target *-*-* } } + return; +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-autoderef.rs b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-autoderef.rs new file mode 100644 index 000000000000..cfff49076dc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-autoderef.rs @@ -0,0 +1,24 @@ +struct Rec { + f: isize +} + +fn f(p: *const Rec) -> isize { + + // Test that * ptrs do not autoderef. There is a deeper reason for + // prohibiting this, beyond making unsafe things annoying (which doesn't + // actually seem desirable to me). The deeper reason is that if you + // have a type like: + // + // enum foo = *foo; + // + // you end up with an infinite auto-deref chain, which is + // currently impossible (in all other cases, infinite auto-derefs + // are prohibited by various checks, such as that the enum is + // instantiable and so forth). + + return p.f; // { dg-error ".E0609." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-called-from-safe.rs b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-called-from-safe.rs new file mode 100644 index 000000000000..8a08b862347c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-called-from-safe.rs @@ -0,0 +1,6 @@ +unsafe fn f() { return; } + +fn main() { + f(); // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-deref-ptr.rs b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-deref-ptr.rs new file mode 100644 index 000000000000..0bebbbb4232e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-deref-ptr.rs @@ -0,0 +1,7 @@ +fn f(p: *const u8) -> u8 { + return *p; // { dg-error ".E0133." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-used-as-value.rs b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-used-as-value.rs new file mode 100644 index 000000000000..c04bc8f3386b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-fn-used-as-value.rs @@ -0,0 +1,7 @@ +unsafe fn f() { return; } + +fn main() { + let x = f; + x(); // { dg-error ".E0133." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-move-val-init.rs b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-move-val-init.rs new file mode 100644 index 000000000000..6e33f00fa1dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-move-val-init.rs @@ -0,0 +1,11 @@ +#![feature(core_intrinsics)] + +use std::intrinsics; + +// `move_val_init` has an odd desugaring, check that it is still treated +// as unsafe. +fn main() { + intrinsics::move_val_init(1 as *mut u32, 1); +// { dg-error ".E0133." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-subtyping.rs b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-subtyping.rs new file mode 100644 index 000000000000..bc161c1faa8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-subtyping.rs @@ -0,0 +1,12 @@ +// Check that safe fns are not a subtype of unsafe fns. + +fn foo(x: Option) -> Option { + x // { dg-error ".E0308." "" { target *-*-* } } +} + +fn bar(x: fn(i32)) -> unsafe fn(i32) { + x // OK, coercion! +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-trait-impl.rs b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-trait-impl.rs new file mode 100644 index 000000000000..5a90b6b9cf16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-trait-impl.rs @@ -0,0 +1,15 @@ +// Check that safe fns are not a subtype of unsafe fns. + +trait Foo { + unsafe fn len(&self) -> u32; +} + +impl Foo for u32 { + fn len(&self) -> u32 { *self } +// { dg-error ".E0053." "" { target *-*-* } .-1 } +// { dg-error ".E0053." "" { target *-*-* } .-2 } +// { dg-error ".E0053." "" { target *-*-* } .-3 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-unstable-const-fn.rs b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-unstable-const-fn.rs new file mode 100644 index 000000000000..50571c771546 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsafe/unsafe-unstable-const-fn.rs @@ -0,0 +1,14 @@ +#![stable(feature = "foo", since = "1.33.0")] +#![feature(staged_api)] +#![feature(const_raw_ptr_deref)] +#![feature(const_fn)] + +#[stable(feature = "foo", since = "1.33.0")] +#[rustc_const_unstable(feature = "const_foo", issue = "none")] +const fn unstable(a: *const i32, b: i32) -> bool { + *a == b +// { dg-error ".E0133." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unsigned-literal-negation.rs b/gcc/testsuite/rust/rustc/ui/unsigned-literal-negation.rs new file mode 100644 index 000000000000..489dea23f76f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsigned-literal-negation.rs @@ -0,0 +1,6 @@ +fn main() { + let x = -1 as usize; // { dg-error ".E0600." "" { target *-*-* } } + let x = (-1) as usize; // { dg-error ".E0600." "" { target *-*-* } } + let x: u32 = -1; // { dg-error ".E0600." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/autoderef.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/autoderef.rs new file mode 100644 index 000000000000..d23d1685f739 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/autoderef.rs @@ -0,0 +1,50 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(unsized_locals, unsized_fn_params)] + +pub trait Foo { + fn foo(self) -> String; +} + +impl Foo for [char] { + fn foo(self) -> String { + self.iter().collect() + } +} + +impl Foo for str { + fn foo(self) -> String { + self.to_owned() + } +} + +impl Foo for dyn FnMut() -> String { + fn foo(mut self) -> String { + self() + } +} + +fn main() { + let x = *(Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>); + assert_eq!(&x.foo() as &str, "hello"); + + let x = Box::new(['h', 'e', 'l', 'l', 'o']) as Box<[char]>; + assert_eq!(&x.foo() as &str, "hello"); + + let x = "hello".to_owned().into_boxed_str(); + assert_eq!(&x.foo() as &str, "hello"); + + let x = *("hello".to_owned().into_boxed_str()); + assert_eq!(&x.foo() as &str, "hello"); + + let x = "hello".to_owned().into_boxed_str(); + assert_eq!(&x.foo() as &str, "hello"); + + let x = *(Box::new(|| "hello".to_owned()) as Box String>); + assert_eq!(&x.foo() as &str, "hello"); + + let x = Box::new(|| "hello".to_owned()) as Box String>; + assert_eq!(&x.foo() as &str, "hello"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/auxiliary/ufuncs.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/auxiliary/ufuncs.rs new file mode 100644 index 000000000000..7d288ba0fa1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/auxiliary/ufuncs.rs @@ -0,0 +1,4 @@ +#![feature(unsized_locals, unsized_fn_params)] + +pub fn udrop(_x: T) {} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/borrow-after-move.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/borrow-after-move.rs new file mode 100644 index 000000000000..badd020ff038 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/borrow-after-move.rs @@ -0,0 +1,44 @@ +#![feature(unsized_locals, unsized_fn_params)] +// { dg-warning "" "" { target *-*-* } .-1 } + +pub trait Foo { + fn foo(self) -> String; +} + +impl Foo for str { + fn foo(self) -> String { + self.to_owned() + } +} + +fn drop_unsized(_: T) {} + +fn main() { + { + let x = "hello".to_owned().into_boxed_str(); + let y = *x; + drop_unsized(y); + println!("{}", &x); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + println!("{}", &y); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + } + + { + let x = "hello".to_owned().into_boxed_str(); + let y = *x; + y.foo(); + println!("{}", &x); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + println!("{}", &y); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + } + + { + let x = "hello".to_owned().into_boxed_str(); + x.foo(); + println!("{}", &x); +// { dg-error ".E0382." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/box-fnonce.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/box-fnonce.rs new file mode 100644 index 000000000000..7ed2f2a9dc4b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/box-fnonce.rs @@ -0,0 +1,11 @@ +// run-pass + +fn call_it(f: Box T>) -> T { + f() +} + +fn main() { + let s = "hello".to_owned(); + assert_eq!(&call_it(Box::new(|| s)) as &str, "hello"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/by-value-trait-object-safety-rpass.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/by-value-trait-object-safety-rpass.rs new file mode 100644 index 000000000000..99cdacdd1d72 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/by-value-trait-object-safety-rpass.rs @@ -0,0 +1,26 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(unsized_locals)] + +pub trait Foo { + fn foo(self) -> String; +} + +struct A; + +impl Foo for A { + fn foo(self) -> String { + format!("hello") + } +} + +fn main() { + let x = *(Box::new(A) as Box); + assert_eq!(x.foo(), format!("hello")); + + // I'm not sure whether we want this to work + let x = Box::new(A) as Box; + assert_eq!(x.foo(), format!("hello")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs new file mode 100644 index 000000000000..4c484369c7d0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/by-value-trait-object-safety-withdefault.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(unsized_locals, unsized_fn_params)] + +pub trait Foo { + fn foo(self) -> String { + format!("hello") + } +} + +struct A; + +impl Foo for A {} + +fn main() { + let x = *(Box::new(A) as Box); + assert_eq!(x.foo(), format!("hello")); + + // I'm not sure whether we want this to work + let x = Box::new(A) as Box; + assert_eq!(x.foo(), format!("hello")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/by-value-trait-object-safety.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/by-value-trait-object-safety.rs new file mode 100644 index 000000000000..48dbf8402bb6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/by-value-trait-object-safety.rs @@ -0,0 +1,23 @@ +#![feature(unsized_locals)] +// { dg-warning "" "" { target *-*-* } .-1 } + +pub trait Foo { + fn foo(self) -> String + where + Self: Sized; +} + +struct A; + +impl Foo for A { + fn foo(self) -> String { + format!("hello") + } +} + +fn main() { + let x = *(Box::new(A) as Box); + x.foo(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/double-move.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/double-move.rs new file mode 100644 index 000000000000..e1a0ea883110 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/double-move.rs @@ -0,0 +1,55 @@ +#![feature(unsized_locals, unsized_fn_params)] +// { dg-warning "" "" { target *-*-* } .-1 } + +pub trait Foo { + fn foo(self) -> String; +} + +impl Foo for str { + fn foo(self) -> String { + self.to_owned() + } +} + +fn drop_unsized(_: T) {} + +fn main() { + { + let x = "hello".to_owned().into_boxed_str(); + let y = *x; + drop_unsized(y); + drop_unsized(y); // { dg-error ".E0382." "" { target *-*-* } } + } + + { + let x = "hello".to_owned().into_boxed_str(); + let _y = *x; + drop_unsized(x); // { dg-error ".E0382." "" { target *-*-* } } + } + + { + let x = "hello".to_owned().into_boxed_str(); + drop_unsized(x); + let _y = *x; // { dg-error ".E0382." "" { target *-*-* } } + } + + { + let x = "hello".to_owned().into_boxed_str(); + let y = *x; + y.foo(); + y.foo(); // { dg-error ".E0382." "" { target *-*-* } } + } + + { + let x = "hello".to_owned().into_boxed_str(); + let _y = *x; + x.foo(); // { dg-error ".E0382." "" { target *-*-* } } + } + + { + let x = "hello".to_owned().into_boxed_str(); + x.foo(); + let _y = *x; // { dg-error ".E0382." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/issue-30276-feature-flagged.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/issue-30276-feature-flagged.rs new file mode 100644 index 000000000000..0cca59af3971 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/issue-30276-feature-flagged.rs @@ -0,0 +1,9 @@ +#![feature(unsized_locals)] +// { dg-warning "" "" { target *-*-* } .-1 } + +struct Test([i32]); + +fn main() { + let _x: fn(_) -> Test = Test; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/issue-30276.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/issue-30276.rs new file mode 100644 index 000000000000..96b2456dd294 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/issue-30276.rs @@ -0,0 +1,6 @@ +struct Test([i32]); + +fn main() { + let _x: fn(_) -> Test = Test; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/issue-50940-with-feature.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/issue-50940-with-feature.rs new file mode 100644 index 000000000000..c8959ab579ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/issue-50940-with-feature.rs @@ -0,0 +1,9 @@ +#![feature(unsized_locals, unsized_fn_params)] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() { + struct A(X); + A as fn(str) -> A; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/issue-50940.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/issue-50940.rs new file mode 100644 index 000000000000..726d2dd027a3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/issue-50940.rs @@ -0,0 +1,6 @@ +fn main() { + struct A(X); + A as fn(str) -> A; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/reference-unsized-locals.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/reference-unsized-locals.rs new file mode 100644 index 000000000000..0dd25ba8fed1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/reference-unsized-locals.rs @@ -0,0 +1,11 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(unsized_locals)] + +fn main() { + let foo: Box<[u8]> = Box::new(*b"foo"); + let foo: [u8] = *foo; + assert_eq!(&foo, b"foo" as &[u8]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/simple-unsized-locals.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/simple-unsized-locals.rs new file mode 100644 index 000000000000..d9badf05cf66 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/simple-unsized-locals.rs @@ -0,0 +1,10 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(unsized_locals)] + +fn main() { + let foo: Box<[u8]> = Box::new(*b"foo"); + let _foo: [u8] = *foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs-rpass.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs-rpass.rs new file mode 100644 index 000000000000..431e1df6d053 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs-rpass.rs @@ -0,0 +1,34 @@ +// run-pass +#![allow(incomplete_features, unused_braces, unused_parens)] +#![feature(unsized_tuple_coercion, unsized_locals, unsized_fn_params)] + +struct A(X); + +fn udrop(_x: T) {} +fn foo() -> Box<[u8]> { + Box::new(*b"foo") +} +fn tfoo() -> Box<(i32, [u8])> { + Box::new((42, *b"foo")) +} +fn afoo() -> Box> { + Box::new(A(*b"foo")) +} + +impl std::ops::Add for A<[u8]> { + type Output = (); + fn add(self, _rhs: i32) -> Self::Output {} +} + +fn main() { + udrop::<[u8]>(loop { + break *foo(); + }); + udrop::<[u8]>(if true { *foo() } else { *foo() }); + udrop::<[u8]>({ *foo() }); + udrop::<[u8]>((*foo())); + udrop::<[u8]>((*tfoo()).1); + *afoo() + 42; + udrop as fn([u8]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs.rs new file mode 100644 index 000000000000..0032337e3f0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs.rs @@ -0,0 +1,29 @@ +#![feature(unsized_tuple_coercion, unsized_fn_params)] + +struct A(X); + +fn udrop(_x: T) {} +fn foo() -> Box<[u8]> { + Box::new(*b"foo") +} +fn tfoo() -> Box<(i32, [u8])> { + Box::new((42, *b"foo")) +} +fn afoo() -> Box> { + Box::new(A(*b"foo")) +} + +impl std::ops::Add for A<[u8]> { + type Output = (); + fn add(self, _rhs: i32) -> Self::Output {} +} + +fn main() { + udrop::<(i32, [u8])>((42, *foo())); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + udrop::>(A { 0: *foo() }); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + udrop::>(A(*foo())); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs2.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs2.rs new file mode 100644 index 000000000000..f66e835582c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs2.rs @@ -0,0 +1,25 @@ +#![feature(unsized_tuple_coercion, unsized_fn_params)] + +struct A(X); + +fn udrop(_x: T) {} +fn foo() -> Box<[u8]> { + Box::new(*b"foo") +} +fn tfoo() -> Box<(i32, [u8])> { + Box::new((42, *b"foo")) +} +fn afoo() -> Box> { + Box::new(A(*b"foo")) +} + +impl std::ops::Add for A<[u8]> { + type Output = (); + fn add(self, _rhs: i32) -> Self::Output {} +} + +fn main() { + udrop::<[u8]>(foo()[..]); +// { dg-error ".E0508." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs3.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs3.rs new file mode 100644 index 000000000000..3cc0ed940ce3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-exprs3.rs @@ -0,0 +1,11 @@ +// aux-build:ufuncs.rs + +extern crate ufuncs; + +use ufuncs::udrop; + +fn main() { + udrop as fn([u8]); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-index.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-index.rs new file mode 100644 index 000000000000..61220745de76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-index.rs @@ -0,0 +1,28 @@ +// run-pass + +#![feature(unsized_fn_params)] + +use std::ops; +use std::ops::Index; + +pub struct A; + +impl ops::Index for A { + type Output = (); + fn index(&self, _: str) -> &Self::Output { + &() + } +} + +impl ops::IndexMut for A { + fn index_mut(&mut self, _: str) -> &mut Self::Output { + panic!() + } +} + +fn main() { + let a = A {}; + let s = String::new().into_boxed_str(); + assert_eq!(&(), a.index(*s)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-locals-using-unsized-fn-params.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-locals-using-unsized-fn-params.rs new file mode 100644 index 000000000000..27952253d69d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-locals-using-unsized-fn-params.rs @@ -0,0 +1,16 @@ +#![feature(box_patterns)] +#![feature(unsized_fn_params)] + +#[allow(dead_code)] +fn f1(box box _b: Box>) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn f2((_x, _y): (i32, [i32])) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { + let foo: Box<[u8]> = Box::new(*b"foo"); + let _foo: [u8] = *foo; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-parameters.rs b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-parameters.rs new file mode 100644 index 000000000000..c599d2d71c86 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-locals/unsized-parameters.rs @@ -0,0 +1,14 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(unsized_fn_params)] + +pub fn f0(_f: dyn FnOnce()) {} +pub fn f1(_s: str) {} +pub fn f2(_x: i32, _y: [i32]) {} + +fn main() { + let foo = "foo".to_string().into_boxed_str(); + f1(*foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized-tuple-impls.rs b/gcc/testsuite/rust/rustc/ui/unsized-tuple-impls.rs new file mode 100644 index 000000000000..845107bfd2c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized-tuple-impls.rs @@ -0,0 +1,22 @@ +// run-pass + +#![feature(unsized_tuple_coercion)] + +use std::collections::HashSet; + +fn main() { + let x : &(i32, i32, [i32]) = &(0, 1, [2, 3]); + let y : &(i32, i32, [i32]) = &(0, 1, [2, 3, 4]); + let mut a = [y, x]; + a.sort(); + assert_eq!(a, [x, y]); + + assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]"); + + let mut h = HashSet::new(); + h.insert(x); + h.insert(y); + assert!(h.contains(x)); + assert!(h.contains(y)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized.rs b/gcc/testsuite/rust/rustc/ui/unsized.rs new file mode 100644 index 000000000000..b03edf206a5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized.rs @@ -0,0 +1,26 @@ +// run-pass + +#![allow(type_alias_bounds)] +#![allow(dead_code)] +// Test syntax checks for `?Sized` syntax. + +use std::marker::PhantomData; + +trait T1 { } +pub trait T2 { } +trait T3 : T2 { } +trait T4 { } +trait T5 { } +trait T6 { } +trait T7 { } +trait T8 { } +trait T9 { } +struct S1(PhantomData); +enum E { E1(PhantomData) } +impl T1 for S1 {} +fn f() {} +type TT = T; + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized/issue-71659.rs b/gcc/testsuite/rust/rustc/ui/unsized/issue-71659.rs new file mode 100644 index 000000000000..f3bc43850574 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized/issue-71659.rs @@ -0,0 +1,33 @@ +#![feature(unsize)] + +use std::marker::Unsize; + +pub trait CastTo: Unsize { + fn cast_to(&self) -> &T; +} + +impl> CastTo for U { + fn cast_to(&self) -> &T { + self + } +} + +impl Cast for T {} +pub trait Cast { + fn cast(&self) -> &T + where + Self: CastTo, + { + self + } +} + +pub trait Foo: CastTo<[i32]> {} +impl Foo for [i32; 0] {} + +fn main() { + let x: &dyn Foo = &[]; + let x = x.cast::<[i32]>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized/issue-75707.rs b/gcc/testsuite/rust/rustc/ui/unsized/issue-75707.rs new file mode 100644 index 000000000000..218dbb26ac38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized/issue-75707.rs @@ -0,0 +1,18 @@ +pub trait Callback { + fn cb(); +} + +pub trait Processing { + type Call: Callback; +} + +fn f() { + P::Call::cb(); +} + +fn main() { + struct MyCall; + f::>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized/return-unsized-from-trait-method.rs b/gcc/testsuite/rust/rustc/ui/unsized/return-unsized-from-trait-method.rs new file mode 100644 index 000000000000..f1a765f68fb4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized/return-unsized-from-trait-method.rs @@ -0,0 +1,17 @@ +// ignore-tidy-linelength + +// regression test for #26376 + +trait Foo { + fn foo(&self) -> [u8]; +} + +fn foo(f: Option<&dyn Foo>) { + if let Some(f) = f { + let _ = f.foo(); +// { dg-error ".E0161." "" { target *-*-* } .-1 } + } +} + +fn main() { foo(None) } + diff --git a/gcc/testsuite/rust/rustc/ui/unsized/unsized-bare-typaram.rs b/gcc/testsuite/rust/rustc/ui/unsized/unsized-bare-typaram.rs new file mode 100644 index 000000000000..9b3ca236c0b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized/unsized-bare-typaram.rs @@ -0,0 +1,5 @@ +fn bar() { } +fn foo() { bar::() } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unsized/unsized-enum.rs b/gcc/testsuite/rust/rustc/ui/unsized/unsized-enum.rs new file mode 100644 index 000000000000..1c395b87587d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized/unsized-enum.rs @@ -0,0 +1,12 @@ +fn is_sized() { } +fn not_sized() { } + +enum Foo { FooSome(U), FooNone } +fn foo1() { not_sized::>() } // Hunky dory. +fn foo2() { not_sized::>() } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// +// Not OK: `T` is not sized. + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unsized/unsized-enum2.rs b/gcc/testsuite/rust/rustc/ui/unsized/unsized-enum2.rs new file mode 100644 index 000000000000..f04447b3ece7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized/unsized-enum2.rs @@ -0,0 +1,75 @@ +use std::ops::Deref; + +// Due to aggressive error message deduplication, we require 20 *different* +// unsized types (even Path and [u8] are considered the "same"). + +trait Foo {} +trait Bar {} +trait FooBar {} +trait BarFoo {} + +trait PathHelper1 {} +trait PathHelper2 {} +trait PathHelper3 {} +trait PathHelper4 {} + +struct Path1(dyn PathHelper1); +struct Path2(dyn PathHelper2); +struct Path3(dyn PathHelper3); +struct Path4(dyn PathHelper4); + +enum E { + // parameter + VA(W), +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VB{x: X}, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VC(isize, Y), +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VD{u: isize, x: Z}, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // slice / str + VE([u8]), +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VF{x: str}, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VG(isize, [f32]), +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VH{u: isize, x: [u32]}, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // unsized struct + VI(Path1), +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VJ{x: Path2}, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VK(isize, Path3), +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VL{u: isize, x: Path4}, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // plain trait + VM(dyn Foo), +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VN{x: dyn Bar}, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VO(isize, dyn FooBar), +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VP{u: isize, x: dyn BarFoo}, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + // projected + VQ(<&'static [i8] as Deref>::Target), +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VR{x: <&'static [char] as Deref>::Target}, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VS(isize, <&'static [f64] as Deref>::Target), +// { dg-error ".E0277." "" { target *-*-* } .-1 } + VT{u: isize, x: <&'static [i32] as Deref>::Target}, +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unsized/unsized-fn-param.rs b/gcc/testsuite/rust/rustc/ui/unsized/unsized-fn-param.rs new file mode 100644 index 000000000000..b313ec2c699b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized/unsized-fn-param.rs @@ -0,0 +1,21 @@ +use std::convert::AsRef; +use std::path::Path; + +fn foo11(_bar: &dyn AsRef, _baz: &str) {} +fn foo12(_bar: &str, _baz: &dyn AsRef) {} + +fn foo21(_bar: &dyn AsRef, _baz: &str) {} +fn foo22(_bar: &str, _baz: &dyn AsRef) {} + +fn main() { + foo11("bar", &"baz"); // { dg-error ".E0277." "" { target *-*-* } } + foo11(&"bar", &"baz"); + foo12(&"bar", "baz"); // { dg-error ".E0277." "" { target *-*-* } } + foo12(&"bar", &"baz"); + + foo21("bar", &"baz"); // { dg-error ".E0277." "" { target *-*-* } } + foo21(&"bar", &"baz"); + foo22(&"bar", "baz"); // { dg-error ".E0277." "" { target *-*-* } } + foo22(&"bar", &"baz"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized/unsized-inherent-impl-self-type.rs b/gcc/testsuite/rust/rustc/ui/unsized/unsized-inherent-impl-self-type.rs new file mode 100644 index 000000000000..7188f67ccccc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized/unsized-inherent-impl-self-type.rs @@ -0,0 +1,12 @@ +// Test sized-ness checking in substitution in impls. + +// impl - struct + +struct S5(Y); + +impl S5 { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unsized/unsized-struct.rs b/gcc/testsuite/rust/rustc/ui/unsized/unsized-struct.rs new file mode 100644 index 000000000000..e9f2ad555650 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized/unsized-struct.rs @@ -0,0 +1,19 @@ +fn is_sized() { } +fn not_sized() { } + +struct Foo { data: T } +fn foo1() { not_sized::>() } // Hunky dory. +fn foo2() { not_sized::>() } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// +// Not OK: `T` is not sized. + +struct Bar { data: T } +fn bar1() { not_sized::>() } +fn bar2() { is_sized::>() } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// +// Not OK: `Bar` is not sized, but it should be. + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unsized/unsized-trait-impl-self-type.rs b/gcc/testsuite/rust/rustc/ui/unsized/unsized-trait-impl-self-type.rs new file mode 100644 index 000000000000..05cb1bf2e0fe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized/unsized-trait-impl-self-type.rs @@ -0,0 +1,15 @@ +// Test sized-ness checking in substitution in impls. + +// impl - struct +trait T3 { + fn foo(&self, z: &Z); +} + +struct S5(Y); + +impl T3 for S5 { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unsized/unsized-trait-impl-trait-arg.rs b/gcc/testsuite/rust/rustc/ui/unsized/unsized-trait-impl-trait-arg.rs new file mode 100644 index 000000000000..b487003902a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized/unsized-trait-impl-trait-arg.rs @@ -0,0 +1,13 @@ +// Test sized-ness checking in substitution in impls. + +// impl - unbounded +trait T2 { + fn foo(&self, z: Z); +} +struct S4(Box); +impl T2 for S4 { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unsized2.rs b/gcc/testsuite/rust/rustc/ui/unsized2.rs new file mode 100644 index 000000000000..d0128b6ac087 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized2.rs @@ -0,0 +1,98 @@ +// run-pass + +#![allow(unconditional_recursion)] +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_imports)] +#![feature(box_syntax)] + +// Test sized-ness checking in substitution. + +use std::marker; + +// Unbounded. +fn f1(x: &X) { + f1::(x); +} +fn f2(x: &X) { + f1::(x); + f2::(x); +} + +// Bounded. +trait T { fn dummy(&self) { } } +fn f3(x: &X) { + f3::(x); +} +fn f4(x: &X) { + f3::(x); + f4::(x); +} + +// Self type. +trait T2 { + fn f() -> Box; +} +struct S; +impl T2 for S { + fn f() -> Box { + box S + } +} +fn f5(x: &X) { + let _: Box = T2::f(); +} +fn f6(x: &X) { + let _: Box = T2::f(); +} + +trait T3 { + fn f() -> Box; +} +impl T3 for S { + fn f() -> Box { + box S + } +} +fn f7(x: &X) { + // This is valid, but the unsized bound on X is irrelevant because any type + // which implements T3 must have statically known size. + let _: Box = T3::f(); +} + +trait T4 { + fn dummy(&self) { } + fn m1(&self, x: &dyn T4, y: X); + fn m2(&self, x: &dyn T5, y: X); +} +trait T5 { + fn dummy(&self) { } + // not an error (for now) + fn m1(&self, x: &dyn T4); + fn m2(&self, x: &dyn T5); +} + +trait T6 { + fn dummy(&self) { } + fn m1(&self, x: &dyn T4); + fn m2(&self, x: &dyn T5); +} +trait T7 { + fn dummy(&self) { } + // not an error (for now) + fn m1(&self, x: &dyn T4); + fn m2(&self, x: &dyn T5); +} + +// The last field in a struct may be unsized +struct S2 { + f: X, +} +struct S3 { + f1: isize, + f2: X, +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized3-rpass.rs b/gcc/testsuite/rust/rustc/ui/unsized3-rpass.rs new file mode 100644 index 000000000000..089b22036046 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized3-rpass.rs @@ -0,0 +1,97 @@ +// run-pass +// Test structs with always-unsized fields. + + +#![allow(warnings)] +#![feature(box_syntax, unsize, raw)] + +use std::mem; +use std::raw; +use std::slice; + +struct Foo { + f: [T], +} + +struct Bar { + f1: usize, + f2: [usize], +} + +struct Baz { + f1: usize, + f2: str, +} + +trait Tr { + fn foo(&self) -> usize; +} + +struct St { + f: usize +} + +impl Tr for St { + fn foo(&self) -> usize { + self.f + } +} + +struct Qux<'a> { + f: Tr+'a +} + +pub fn main() { + let _: &Foo; + let _: &Bar; + let _: &Baz; + + let _: Box>; + let _: Box; + let _: Box; + + let _ = mem::size_of::>>(); + let _ = mem::size_of::>(); + let _ = mem::size_of::>(); + + unsafe { + struct Foo_ { + f: [T; 3] + } + + let data: Box> = box Foo_{f: [1, 2, 3] }; + let x: &Foo = mem::transmute(slice::from_raw_parts(&*data, 3)); + assert_eq!(x.f.len(), 3); + assert_eq!(x.f[0], 1); + + struct Baz_ { + f1: usize, + f2: [u8; 5], + } + + let data: Box<_> = box Baz_ { + f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] }; + let x: &Baz = mem::transmute(slice::from_raw_parts(&*data, 5)); + assert_eq!(x.f1, 42); + let chs: Vec = x.f2.chars().collect(); + assert_eq!(chs.len(), 5); + assert_eq!(chs[0], 'a'); + assert_eq!(chs[1], 'b'); + assert_eq!(chs[2], 'c'); + assert_eq!(chs[3], 'd'); + assert_eq!(chs[4], 'e'); + + struct Qux_ { + f: St + } + + let obj: Box = box St { f: 42 }; + let obj: &Tr = &*obj; + let obj: raw::TraitObject = mem::transmute(&*obj); + let data: Box<_> = box Qux_{ f: St { f: 234 } }; + let x: &Qux = mem::transmute(raw::TraitObject { vtable: obj.vtable, + data: mem::transmute(&*data) }); + assert_eq!(x.f.foo(), 234); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized3.rs b/gcc/testsuite/rust/rustc/ui/unsized3.rs new file mode 100644 index 000000000000..7f58ba4fe2ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized3.rs @@ -0,0 +1,52 @@ +// Test sized-ness checking in substitution within fn bodies.. + +use std::marker; + +// Unbounded. +fn f1(x: &X) { + f2::(x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} +fn f2(x: &X) { +} + +// Bounded. +trait T { + fn foo(&self) { } +} +fn f3(x: &X) { + f4::(x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} +fn f4(x: &X) { +} + +fn f5(x: &Y) {} +fn f6(x: &X) {} + +// Test with unsized struct. +struct S { + x: X, +} + +fn f8(x1: &S, x2: &S) { + f5(x1); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + f6(x2); // ok +} + +// Test some tuples. +fn f9(x1: Box>) { + f5(&(*x1, 34)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn f10(x1: Box>) { + f5(&(32, *x1)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +// { dg-error ".E0277." "" { target *-*-* } .-2 } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized5.rs b/gcc/testsuite/rust/rustc/ui/unsized5.rs new file mode 100644 index 000000000000..0939c0c4bbeb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized5.rs @@ -0,0 +1,35 @@ +// Test `?Sized` types not allowed in fields (except the last one). + +struct S1 { + f1: X, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + f2: isize, +} +struct S2 { + f: isize, + g: X, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + h: isize, +} +struct S3 { + f: str, +// { dg-error ".E0277." "" { target *-*-* } .-1 } + g: [usize] +} +struct S4 { + f: [u8], +// { dg-error ".E0277." "" { target *-*-* } .-1 } + g: usize +} +enum E { + V1(X, isize), +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} +enum F { + V2{f1: X, f: isize}, +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized6.rs b/gcc/testsuite/rust/rustc/ui/unsized6.rs new file mode 100644 index 000000000000..771d10ccef5d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized6.rs @@ -0,0 +1,45 @@ +// Test `?Sized` local variables. + +trait T {} + +fn f1(x: &X) { + let _: W; // <-- this is OK, no bindings created, no initializer. + let _: (isize, (X, isize)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let y: Y; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let y: (isize, (Z, usize)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} +fn f2(x: &X) { + let y: X; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let y: (isize, (Y, isize)); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn f3(x1: Box, x2: Box, x3: Box) { + let y: X = *x1; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let y = *x2; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let (y, z) = (*x3, 4); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} +fn f4(x1: Box, x2: Box, x3: Box) { + let y: X = *x1; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let y = *x2; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + let (y, z) = (*x3, 4); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn g1(x: X) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +fn g2(x: X) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsized7.rs b/gcc/testsuite/rust/rustc/ui/unsized7.rs new file mode 100644 index 000000000000..9eddda0e4964 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsized7.rs @@ -0,0 +1,17 @@ +// Test sized-ness checking in substitution in impls. + +trait T {} + +// I would like these to fail eventually. +// impl - bounded +trait T1 { + fn dummy(&self) -> Z; +} + +struct S3(Box); +impl T1 for S3 { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unspecified-self-in-trait-ref.rs b/gcc/testsuite/rust/rustc/ui/unspecified-self-in-trait-ref.rs new file mode 100644 index 000000000000..29197f1c6134 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unspecified-self-in-trait-ref.rs @@ -0,0 +1,21 @@ +pub trait Foo { + fn foo(&self); +} + +pub trait Bar { + fn foo(&self); +} + +fn main() { + let a = Foo::lol(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + let b = Foo::<_>::lol(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + let c = Bar::lol(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + let d = Bar::::lol(); +// { dg-error ".E0599." "" { target *-*-* } .-1 } + let e = Bar::::lol(); +// { dg-error ".E0393." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/unsupported-cast.rs b/gcc/testsuite/rust/rustc/ui/unsupported-cast.rs new file mode 100644 index 000000000000..54cef84620ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unsupported-cast.rs @@ -0,0 +1,8 @@ +// error-pattern:casting + +struct A; + +fn main() { + println!("{:?}", 1.0 as *const A); // Can't cast float to foreign. +} + diff --git a/gcc/testsuite/rust/rustc/ui/unterminated-comment.rs b/gcc/testsuite/rust/rustc/ui/unterminated-comment.rs new file mode 100644 index 000000000000..5851e9ac1fc9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unterminated-comment.rs @@ -0,0 +1,2 @@ +/* // { dg-error ".E0758." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/unterminated-doc-comment.rs b/gcc/testsuite/rust/rustc/ui/unterminated-doc-comment.rs new file mode 100644 index 000000000000..03ed456a96d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unterminated-doc-comment.rs @@ -0,0 +1,2 @@ +/*! // { dg-error ".E0758." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/unused-crate-deps/auxiliary/bar.rs b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/auxiliary/bar.rs new file mode 100644 index 000000000000..070807727d51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/auxiliary/bar.rs @@ -0,0 +1,2 @@ +pub const BAR: &str = "bar"; + diff --git a/gcc/testsuite/rust/rustc/ui/unused-crate-deps/auxiliary/foo.rs b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/auxiliary/foo.rs new file mode 100644 index 000000000000..bcc6373176b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/auxiliary/foo.rs @@ -0,0 +1,6 @@ +// edition:2018 +// aux-crate:bar=bar.rs + +pub const FOO: &str = "foo"; +pub use bar::BAR; + diff --git a/gcc/testsuite/rust/rustc/ui/unused-crate-deps/ignore-pathless-extern.rs b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/ignore-pathless-extern.rs new file mode 100644 index 000000000000..b18604febc61 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/ignore-pathless-extern.rs @@ -0,0 +1,13 @@ +// Pathless --extern references don't count + +// edition:2018 +// check-pass +// aux-crate:bar=bar.rs +// compile-flags:--extern proc_macro + +#![warn(unused_crate_dependencies)] + +use bar as _; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unused-crate-deps/libfib.rs b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/libfib.rs new file mode 100644 index 000000000000..ea8887d9cfd2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/libfib.rs @@ -0,0 +1,22 @@ +// Test warnings for a library crate + +// check-pass +// aux-crate:bar=bar.rs +// compile-flags:--crate-type lib -Wunused-crate-dependencies + +pub fn fib(n: u32) -> Vec { +// { dg-warning "" "" { target *-*-* } .-1 } +let mut prev = 0; + let mut cur = 1; + let mut v = vec![]; + + for _ in 0..n { + v.push(prev); + let n = prev + cur; + prev = cur; + cur = n; + } + + v +} + diff --git a/gcc/testsuite/rust/rustc/ui/unused-crate-deps/lint-group.rs b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/lint-group.rs new file mode 100644 index 000000000000..5cd237734094 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/lint-group.rs @@ -0,0 +1,10 @@ +// `unused_crate_dependencies` is not currently in the `unused` group +// due to false positives from Cargo. + +// check-pass +// aux-crate:bar=bar.rs + +#![deny(unused)] + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unused-crate-deps/suppress.rs b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/suppress.rs new file mode 100644 index 000000000000..2fa7c5f98ea6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/suppress.rs @@ -0,0 +1,12 @@ +// Suppress by using crate + +// edition:2018 +// check-pass +// aux-crate:bar=bar.rs + +#![warn(unused_crate_dependencies)] + +use bar as _; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unused-crate-deps/test-use-ok.rs b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/test-use-ok.rs new file mode 100644 index 000000000000..f4a4394e630b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/test-use-ok.rs @@ -0,0 +1,16 @@ +// Test-only use OK + +// edition:2018 +// check-pass +// aux-crate:bar=bar.rs +// compile-flags:--test + +#![deny(unused_crate_dependencies)] + +fn main() {} + +#[test] +fn test_bar() { + assert_eq!(bar::BAR, "bar"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unused-crate-deps/unused-aliases.rs b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/unused-aliases.rs new file mode 100644 index 000000000000..4625ebf59797 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/unused-aliases.rs @@ -0,0 +1,14 @@ +// Warn about unused aliased for the crate + +// edition:2018 +// check-pass +// aux-crate:bar=bar.rs +// aux-crate:barbar=bar.rs + +#![warn(unused_crate_dependencies)] +// { dg-warning "" "" { target *-*-* } .-1 } + +use bar as _; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unused-crate-deps/use_extern_crate_2015.rs b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/use_extern_crate_2015.rs new file mode 100644 index 000000000000..b27768713131 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/use_extern_crate_2015.rs @@ -0,0 +1,14 @@ +// Suppress by using crate + +// edition:2015 +// check-pass +// aux-crate:bar=bar.rs + +#![warn(unused_crate_dependencies)] + +extern crate bar; + +fn main() { + println!("bar {}", bar::BAR); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unused-crate-deps/warn-attr.rs b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/warn-attr.rs new file mode 100644 index 000000000000..5d8b114d7fee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/warn-attr.rs @@ -0,0 +1,11 @@ +// Check for unused crate dep, no path + +// edition:2018 +// check-pass +// aux-crate:bar=bar.rs + +#![warn(unused_crate_dependencies)] +// { dg-warning "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unused-crate-deps/warn-cmdline-static.rs b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/warn-cmdline-static.rs new file mode 100644 index 000000000000..673eeac328a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/warn-cmdline-static.rs @@ -0,0 +1,11 @@ +// Check for unused crate dep, no path + +// edition:2018 +// check-pass +// compile-flags: -Wunused-crate-dependencies +// aux-crate:bar=bar.rs +// no-prefer-dynamic + +fn main() {} +// { dg-warning "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/unused-crate-deps/warn-cmdline.rs b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/warn-cmdline.rs new file mode 100644 index 000000000000..8dca3676fbc0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-crate-deps/warn-cmdline.rs @@ -0,0 +1,10 @@ +// Check for unused crate dep, no path + +// edition:2018 +// check-pass +// compile-flags: -Wunused-crate-dependencies +// aux-crate:bar=bar.rs + +fn main() {} +// { dg-warning "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/unused-move-capture.rs b/gcc/testsuite/rust/rustc/ui/unused-move-capture.rs new file mode 100644 index 000000000000..ee19922bb185 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-move-capture.rs @@ -0,0 +1,11 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![feature(box_syntax)] + +pub fn main() { + let _x: Box<_> = box 1; + let lam_move = || {}; + lam_move(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unused-move.rs b/gcc/testsuite/rust/rustc/ui/unused-move.rs new file mode 100644 index 000000000000..e9abb056908f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused-move.rs @@ -0,0 +1,16 @@ +// run-pass +// Issue #3878 +// Issue Name: Unused move causes a crash +// Abstract: zero-fill to block after drop + +// pretty-expanded FIXME #23616 + +#![allow(path_statements)] +#![feature(box_syntax)] + +pub fn main() +{ + let y: Box<_> = box 1; + y; +} + diff --git a/gcc/testsuite/rust/rustc/ui/unused/unused-attr.rs b/gcc/testsuite/rust/rustc/ui/unused/unused-attr.rs new file mode 100644 index 000000000000..fe40c82303cd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused/unused-attr.rs @@ -0,0 +1,50 @@ +#![deny(unused_attributes)] +#![feature(rustc_attrs)] + +#![rustc_dummy] // { dg-error "" "" { target *-*-* } } + +#[rustc_dummy] // { dg-error "" "" { target *-*-* } } +extern crate core; + +#[rustc_dummy] // { dg-error "" "" { target *-*-* } } +use std::collections; + +#[rustc_dummy] // { dg-error "" "" { target *-*-* } } +extern "C" { + #[rustc_dummy] // { dg-error "" "" { target *-*-* } } + fn foo(); +} + +#[rustc_dummy] // { dg-error "" "" { target *-*-* } } +mod foo { + #[rustc_dummy] // { dg-error "" "" { target *-*-* } } + pub enum Foo { + #[rustc_dummy] // { dg-error "" "" { target *-*-* } } + Bar, + } +} + +#[rustc_dummy] // { dg-error "" "" { target *-*-* } } +fn bar(f: foo::Foo) { + match f { + #[rustc_dummy] // { dg-error "" "" { target *-*-* } } + foo::Foo::Bar => {} + } +} + +#[rustc_dummy] // { dg-error "" "" { target *-*-* } } +struct Foo { + #[rustc_dummy] // { dg-error "" "" { target *-*-* } } + a: isize +} + +#[rustc_dummy] // { dg-error "" "" { target *-*-* } } +trait Baz { + #[rustc_dummy] // { dg-error "" "" { target *-*-* } } + fn blah(&self); + #[rustc_dummy] // { dg-error "" "" { target *-*-* } } + fn blah2(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unused/unused-closure.rs b/gcc/testsuite/rust/rustc/ui/unused/unused-closure.rs new file mode 100644 index 000000000000..e8f95603b2f8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused/unused-closure.rs @@ -0,0 +1,41 @@ +// Test that closures and generators are "must use" types. +// edition:2018 + +#![feature(async_closure)] +#![feature(const_in_array_repeat_expressions)] +#![feature(generators)] +#![deny(unused_must_use)] + +fn unused() { + || { // { dg-error "" "" { target *-*-* } } + println!("Hello!"); + }; + + async {}; // { dg-error "" "" { target *-*-* } } + || async {}; // { dg-error "" "" { target *-*-* } } + async || {}; // { dg-error "" "" { target *-*-* } } + + + [Box::new([|| {}; 10]); 1]; // { dg-error "" "" { target *-*-* } } + + [|| { // { dg-error "" "" { target *-*-* } } + yield 42u32; + }; 42]; + + vec![|| "a"].pop().unwrap(); // { dg-error "" "" { target *-*-* } } + + let b = false; + || true; // { dg-error "" "" { target *-*-* } } + println!("{}", b); +} + +fn ignored() { + let _ = || {}; + let _ = || yield 42; +} + +fn main() { + unused(); + ignored(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unused/unused-macro-rules.rs b/gcc/testsuite/rust/rustc/ui/unused/unused-macro-rules.rs new file mode 100644 index 000000000000..b1637379d54a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused/unused-macro-rules.rs @@ -0,0 +1,30 @@ +#![deny(unused_macros)] + +// Most simple case +macro_rules! unused { // { dg-error "" "" { target *-*-* } } + () => {}; +} + +// Test macros created by macros +macro_rules! create_macro { + () => { + macro_rules! m { // { dg-error "" "" { target *-*-* } } + () => {}; + } + }; +} +create_macro!(); + +#[allow(unused_macros)] +mod bar { + // Test that putting the #[deny] close to the macro's definition + // works. + + #[deny(unused_macros)] + macro_rules! unused { // { dg-error "" "" { target *-*-* } } + () => {}; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unused/unused-macro-with-bad-frag-spec.rs b/gcc/testsuite/rust/rustc/ui/unused/unused-macro-with-bad-frag-spec.rs new file mode 100644 index 000000000000..31a83e194bdb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused/unused-macro-with-bad-frag-spec.rs @@ -0,0 +1,10 @@ +#![allow(unused_macros)] + +// Issue #21370 + +macro_rules! test { + ($wrong:t_ty) => () // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unused/unused-macro-with-follow-violation.rs b/gcc/testsuite/rust/rustc/ui/unused/unused-macro-with-follow-violation.rs new file mode 100644 index 000000000000..7d2115fb2bd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused/unused-macro-with-follow-violation.rs @@ -0,0 +1,8 @@ +#![allow(unused_macros)] + +macro_rules! test { + ($e:expr +) => () // { dg-error "" "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/unused/unused-macro.rs b/gcc/testsuite/rust/rustc/ui/unused/unused-macro.rs new file mode 100644 index 000000000000..ee9fdf30115d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused/unused-macro.rs @@ -0,0 +1,27 @@ +#![feature(decl_macro)] +#![deny(unused_macros)] + +// Most simple case +macro unused { // { dg-error "" "" { target *-*-* } } + () => {} +} + +#[allow(unused_macros)] +mod bar { + // Test that putting the #[deny] close to the macro's definition + // works. + + #[deny(unused_macros)] + macro unused { // { dg-error "" "" { target *-*-* } } + () => {} + } +} + +mod boo { + pub(crate) macro unused { // { dg-error "" "" { target *-*-* } } + () => {} + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/unused/unused-mut-warning-captured-var.rs b/gcc/testsuite/rust/rustc/ui/unused/unused-mut-warning-captured-var.rs new file mode 100644 index 000000000000..96dd49e46f2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused/unused-mut-warning-captured-var.rs @@ -0,0 +1,10 @@ +// run-rustfix + +#![forbid(unused_mut)] + +fn main() { + let mut x = 1; +// { dg-error "" "" { target *-*-* } .-1 } + (move|| { println!("{}", x); })(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unused/unused-result.rs b/gcc/testsuite/rust/rustc/ui/unused/unused-result.rs new file mode 100644 index 000000000000..741ab3ec4dca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unused/unused-result.rs @@ -0,0 +1,43 @@ +#![allow(dead_code)] +#![deny(unused_results, unused_must_use)] +// { dg-note "" "" { target *-*-* } .-1 } +// { dg-note "" "" { target *-*-* } .-2 } + +#[must_use] +enum MustUse { Test } + +#[must_use = "some message"] +enum MustUseMsg { Test2 } + +fn foo() -> T { panic!() } + +fn bar() -> isize { return foo::(); } +fn baz() -> MustUse { return foo::(); } +fn qux() -> MustUseMsg { return foo::(); } + +#[allow(unused_results)] +fn test() { + foo::(); + foo::(); // { dg-error "" "" { target *-*-* } } + foo::(); // { dg-error "" "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-1 } +} + +#[allow(unused_results, unused_must_use)] +fn test2() { + foo::(); + foo::(); + foo::(); +} + +fn main() { + foo::(); // { dg-error "" "" { target *-*-* } } + foo::(); // { dg-error "" "" { target *-*-* } } + foo::(); // { dg-error "" "" { target *-*-* } } +// { dg-note "" "" { target *-*-* } .-1 } + + let _ = foo::(); + let _ = foo::(); + let _ = foo::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unwind-resource.rs b/gcc/testsuite/rust/rustc/ui/unwind-resource.rs new file mode 100644 index 000000000000..4b9dcd297e88 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unwind-resource.rs @@ -0,0 +1,40 @@ +// run-pass + +#![allow(non_camel_case_types)] +// ignore-emscripten no threads support + +use std::sync::mpsc::{channel, Sender}; +use std::thread; + +struct complainer { + tx: Sender, +} + +impl Drop for complainer { + fn drop(&mut self) { + println!("About to send!"); + self.tx.send(true).unwrap(); + println!("Sent!"); + } +} + +fn complainer(tx: Sender) -> complainer { + println!("Hello!"); + complainer { + tx: tx + } +} + +fn f(tx: Sender) { + let _tx = complainer(tx); + panic!(); +} + +pub fn main() { + let (tx, rx) = channel(); + let t = thread::spawn(move|| f(tx.clone())); + println!("hiiiiiiiii"); + assert!(rx.recv().unwrap()); + drop(t.join()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/unwind-unique.rs b/gcc/testsuite/rust/rustc/ui/unwind-unique.rs new file mode 100644 index 000000000000..08e37b4fcfa7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/unwind-unique.rs @@ -0,0 +1,17 @@ +// run-pass +// ignore-emscripten no threads support + +#![feature(box_syntax)] + +use std::thread; + +fn f() { + let _a: Box<_> = box 0; + panic!(); +} + +pub fn main() { + let t = thread::spawn(f); + drop(t.join()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/use-crate-name-alias.rs b/gcc/testsuite/rust/rustc/ui/use-crate-name-alias.rs new file mode 100644 index 000000000000..19e6a6fd3280 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use-crate-name-alias.rs @@ -0,0 +1,8 @@ +// run-pass +// Issue #1706 +// pretty-expanded FIXME #23616 + +extern crate std as stdlib; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use-import-export.rs b/gcc/testsuite/rust/rustc/ui/use-import-export.rs new file mode 100644 index 000000000000..394ec844acae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use-import-export.rs @@ -0,0 +1,13 @@ +// run-pass +// pretty-expanded FIXME #23616 + +mod foo { + pub fn x() -> isize { return 1; } +} + +mod bar { + pub fn y() -> isize { return 1; } +} + +pub fn main() { foo::x(); bar::y(); } + diff --git a/gcc/testsuite/rust/rustc/ui/use-keyword-2.rs b/gcc/testsuite/rust/rustc/ui/use-keyword-2.rs new file mode 100644 index 000000000000..02379c40dbfc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use-keyword-2.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(unused_variables)] +pub struct A; + +mod test { + pub use super :: A; + + pub use self :: A as B; +} + +impl A { + fn f() {} + fn g() { + Self :: f() + } +} + +fn main() { + let a: A = test::A; + let b: A = test::B; + let c: () = A::g(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/use-mod.rs b/gcc/testsuite/rust/rustc/ui/use-mod.rs new file mode 100644 index 000000000000..cdf6c4cd3e45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use-mod.rs @@ -0,0 +1,34 @@ +// run-pass + +#![allow(unused_imports)] +// pretty-expanded FIXME #23616 + +pub use foo::bar::{self, First}; +use self::bar::Second; + +mod foo { + pub use self::bar::baz::{self}; + + pub mod bar { + pub mod baz { + pub struct Fourth; + } + pub struct First; + pub struct Second; + } + + pub struct Third; +} + +mod baz { + use super::foo::{bar, self}; + pub use foo::Third; +} + +fn main() { + let _ = First; + let _ = Second; + let _ = baz::Third; + let _ = foo::baz::Fourth; +} + diff --git a/gcc/testsuite/rust/rustc/ui/use-module-level-int-consts.rs b/gcc/testsuite/rust/rustc/ui/use-module-level-int-consts.rs new file mode 100644 index 000000000000..930444ba815d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use-module-level-int-consts.rs @@ -0,0 +1,12 @@ +// run-pass + +// Make sure the module level constants are still there and accessible even after +// the corresponding associated constants have been added, and later stabilized. +use std::{u16, f32}; + +fn main() { + let _ = u16::MAX; + let _ = f32::EPSILON; + let _ = std::f64::MANTISSA_DIGITS; +} + diff --git a/gcc/testsuite/rust/rustc/ui/use-nested-groups.rs b/gcc/testsuite/rust/rustc/ui/use-nested-groups.rs new file mode 100644 index 000000000000..2c620ace3c91 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use-nested-groups.rs @@ -0,0 +1,33 @@ +// run-pass + +mod a { + pub enum B {} + + pub mod d { + pub enum E {} + pub enum F {} + + pub mod g { + pub enum H {} + pub enum I {} + } + } +} + +// Test every possible part of the syntax +use a::{B, d::{self, *, g::H}}; + +// Test a more common use case +use std::sync::{Arc, atomic::{AtomicBool, Ordering}}; + +fn main() { + let _: B; + let _: E; + let _: F; + let _: H; + let _: d::g::I; + + let _: Arc; + let _: Ordering; +} + diff --git a/gcc/testsuite/rust/rustc/ui/use-self-in-inner-fn.rs b/gcc/testsuite/rust/rustc/ui/use-self-in-inner-fn.rs new file mode 100644 index 000000000000..22b7abc320c5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use-self-in-inner-fn.rs @@ -0,0 +1,15 @@ +struct A; + +impl A { +// { dg-note "" "" { target *-*-* } .-1 } + fn banana(&mut self) { + fn peach(this: &Self) { +// { dg-error ".E0401." "" { target *-*-* } .-1 } +// { dg-note ".E0401." "" { target *-*-* } .-2 } +// { dg-note ".E0401." "" { target *-*-* } .-3 } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use.rs b/gcc/testsuite/rust/rustc/ui/use.rs new file mode 100644 index 000000000000..0f398e1d06b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use.rs @@ -0,0 +1,24 @@ +// run-pass + +#![allow(stable_features)] +// pretty-expanded FIXME #23616 + +#![allow(unused_imports)] +#![feature(start, no_core, core)] +#![no_core] + +extern crate std; +extern crate std as zed; + +use std::str; +use zed::str as x; + +use std::io::{self, Error as IoError, Result as IoResult}; +use std::error::{self as foo}; +mod baz { + pub use std::str as x; +} + +#[start] +pub fn start(_: isize, _: *const *const u8) -> isize { 0 } + diff --git a/gcc/testsuite/rust/rustc/ui/use/auxiliary/extern-use-primitive-type-lib.rs b/gcc/testsuite/rust/rustc/ui/use/auxiliary/extern-use-primitive-type-lib.rs new file mode 100644 index 000000000000..b837f7d72d31 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/auxiliary/extern-use-primitive-type-lib.rs @@ -0,0 +1,4 @@ +// compile-flags: --edition=2018 + +pub use u32; + diff --git a/gcc/testsuite/rust/rustc/ui/use/auxiliary/use-from-trait-xc.rs b/gcc/testsuite/rust/rustc/ui/use/auxiliary/use-from-trait-xc.rs new file mode 100644 index 000000000000..99f7c11ad7b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/auxiliary/use-from-trait-xc.rs @@ -0,0 +1,30 @@ +pub use self::sub::{Bar, Baz}; + +pub trait Trait { + fn foo(&self); + type Assoc; + const CONST: u32; +} + +struct Foo; + +impl Foo { + pub fn new() {} + + pub const C: u32 = 0; +} + +mod sub { + pub struct Bar; + + impl Bar { + pub fn new() {} + } + + pub enum Baz {} + + impl Baz { + pub fn new() {} + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/use/issue-18986.rs b/gcc/testsuite/rust/rustc/ui/use/issue-18986.rs new file mode 100644 index 000000000000..0e8e6a6da25f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/issue-18986.rs @@ -0,0 +1,11 @@ +// aux-build:use-from-trait-xc.rs + +extern crate use_from_trait_xc; +pub use use_from_trait_xc::Trait; + +fn main() { + match () { + Trait { x: 42 } => () // { dg-error ".E0574." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/use/issue-60976-extern-use-primitive-type.rs b/gcc/testsuite/rust/rustc/ui/use/issue-60976-extern-use-primitive-type.rs new file mode 100644 index 000000000000..d1c558286e9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/issue-60976-extern-use-primitive-type.rs @@ -0,0 +1,8 @@ +// Regression test for #60976: ICE (with <=1.36.0) when another file had `use ;`. +// check-pass +// aux-build:extern-use-primitive-type-lib.rs + +extern crate extern_use_primitive_type_lib; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-after-move-based-on-type.rs b/gcc/testsuite/rust/rustc/ui/use/use-after-move-based-on-type.rs new file mode 100644 index 000000000000..589a1b88dfe6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-after-move-based-on-type.rs @@ -0,0 +1,6 @@ +fn main() { + let x = "Hello!".to_string(); + let _y = x; + println!("{}", x); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-after-move-implicity-coerced-object.rs b/gcc/testsuite/rust/rustc/ui/use/use-after-move-implicity-coerced-object.rs new file mode 100644 index 000000000000..51e5ea3fb75d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-after-move-implicity-coerced-object.rs @@ -0,0 +1,31 @@ +#![feature(box_syntax)] + +use std::fmt; + +struct Number { + n: i64 +} + +impl fmt::Display for Number { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.n) + } +} + +struct List { + list: Vec> } + +impl List { + fn push(&mut self, n: Box) { + self.list.push(n); + } +} + +fn main() { + let n: Box<_> = box Number { n: 42 }; + let mut l: Box<_> = box List { list: Vec::new() }; + l.push(n); + let x = n.to_string(); +// { dg-error ".E0382." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-after-move-self-based-on-type.rs b/gcc/testsuite/rust/rustc/ui/use/use-after-move-self-based-on-type.rs new file mode 100644 index 000000000000..2fbda2626f02 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-after-move-self-based-on-type.rs @@ -0,0 +1,22 @@ +struct S { + x: isize, +} + +impl Drop for S { + fn drop(&mut self) {} +} + +impl S { + pub fn foo(self) -> isize { + self.bar(); + return self.x; // { dg-error ".E0382." "" { target *-*-* } } + } + + pub fn bar(self) {} +} + +fn main() { + let x = S { x: 1 }; + println!("{}", x.foo()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-after-move-self.rs b/gcc/testsuite/rust/rustc/ui/use/use-after-move-self.rs new file mode 100644 index 000000000000..01c4a0425c97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-after-move-self.rs @@ -0,0 +1,20 @@ +#![feature(box_syntax)] + +struct S { + x: Box, +} + +impl S { + pub fn foo(self) -> isize { + self.bar(); + return *self.x; // { dg-error ".E0382." "" { target *-*-* } } + } + + pub fn bar(self) {} +} + +fn main() { + let x = S { x: box 1 }; + println!("{}", x.foo()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-associated-const.rs b/gcc/testsuite/rust/rustc/ui/use/use-associated-const.rs new file mode 100644 index 000000000000..cfcf2eafce53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-associated-const.rs @@ -0,0 +1,14 @@ +#![allow(unused_imports)] + +pub mod foo { + pub struct Foo; + + impl Foo { + pub const BAR: i32 = 0; + } +} + +use foo::Foo::BAR; // { dg-error ".E0432." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-from-trait-xc.rs b/gcc/testsuite/rust/rustc/ui/use/use-from-trait-xc.rs new file mode 100644 index 000000000000..2e6a2f80e0db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-from-trait-xc.rs @@ -0,0 +1,27 @@ +// aux-build:use-from-trait-xc.rs + +extern crate use_from_trait_xc; + +use use_from_trait_xc::Trait::foo; +// { dg-error ".E0253." "" { target *-*-* } .-1 } + +use use_from_trait_xc::Trait::Assoc; +// { dg-error ".E0253." "" { target *-*-* } .-1 } + +use use_from_trait_xc::Trait::CONST; +// { dg-error ".E0253." "" { target *-*-* } .-1 } + +use use_from_trait_xc::Foo::new; // { dg-error ".E0603." "" { target *-*-* } } +// { dg-error ".E0603." "" { target *-*-* } .-1 } + +use use_from_trait_xc::Foo::C; // { dg-error ".E0603." "" { target *-*-* } } +// { dg-error ".E0603." "" { target *-*-* } .-1 } + +use use_from_trait_xc::Bar::new as bnew; +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +use use_from_trait_xc::Baz::new as baznew; +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-from-trait.rs b/gcc/testsuite/rust/rustc/ui/use/use-from-trait.rs new file mode 100644 index 000000000000..d0c0e9d56403 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-from-trait.rs @@ -0,0 +1,23 @@ +use Trait::foo; // { dg-error ".E0253." "" { target *-*-* } } +use Trait::Assoc; // { dg-error ".E0253." "" { target *-*-* } } +use Trait::C; // { dg-error ".E0253." "" { target *-*-* } } + +use Foo::new; // { dg-error ".E0432." "" { target *-*-* } } + +use Foo::C2; // { dg-error ".E0432." "" { target *-*-* } } + +pub trait Trait { + fn foo(); + type Assoc; + const C: u32; +} + +struct Foo; + +impl Foo { + fn new() {} + const C2: u32 = 0; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-keyword.rs b/gcc/testsuite/rust/rustc/ui/use/use-keyword.rs new file mode 100644 index 000000000000..cad6303abc89 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-keyword.rs @@ -0,0 +1,18 @@ +// Check that imports with nakes super and self don't fail during parsing +// FIXME: this shouldn't fail during name resolution either + +mod a { + mod b { + use self as A; +// { dg-error ".E0429." "" { target *-*-* } .-1 } + use super as B; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +// { dg-error ".E0432." "" { target *-*-* } .-2 } + use super::{self as C}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +// { dg-error ".E0432." "" { target *-*-* } .-2 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-meta-mismatch.rs b/gcc/testsuite/rust/rustc/ui/use/use-meta-mismatch.rs new file mode 100644 index 000000000000..81dfee3388fc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-meta-mismatch.rs @@ -0,0 +1,6 @@ +// error-pattern:can't find crate for `fake_crate` + +extern crate fake_crate as extra; + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-mod.rs b/gcc/testsuite/rust/rustc/ui/use/use-mod.rs new file mode 100644 index 000000000000..67b3a90262db --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-mod.rs @@ -0,0 +1,20 @@ +use foo::bar::{ + self, +// { dg-error ".E0430." "" { target *-*-* } .-1 } + Bar, + self +// { dg-error ".E0252." "" { target *-*-* } .-1 } +}; + +use {self}; +// { dg-error ".E0431." "" { target *-*-* } .-1 } + +mod foo { + pub mod bar { + pub struct Bar; + pub struct Baz; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-2.rs b/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-2.rs new file mode 100644 index 000000000000..14066082423d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-2.rs @@ -0,0 +1,12 @@ +mod foo { + use self::{self}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +// { dg-error ".E0432." "" { target *-*-* } .-2 } + + use super::{self}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } +// { dg-error ".E0432." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-3.rs b/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-3.rs new file mode 100644 index 000000000000..5ff7bc3f59ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-3.rs @@ -0,0 +1,13 @@ +use foo::bar::{ // { dg-error ".E0603." "" { target *-*-* } } + self +}; +use foo::bar::{ // { dg-error ".E0603." "" { target *-*-* } } + Bar +}; + +mod foo { + mod bar { pub type Bar = isize; } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-4.rs b/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-4.rs new file mode 100644 index 000000000000..43b5e6077ebe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-4.rs @@ -0,0 +1,8 @@ +use foo::self; // { dg-error ".E0432." "" { target *-*-* } } +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +use std::mem::self; +// { dg-error ".E0429." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-5.rs b/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-5.rs new file mode 100644 index 000000000000..a18baffc3f9f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-5.rs @@ -0,0 +1,14 @@ +mod foo { + pub mod bar { + pub fn drop() {} + } +} + +use foo::bar::self; +// { dg-error ".E0429." "" { target *-*-* } .-1 } + +fn main() { + // Because of error recovery this shouldn't error + bar::drop(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-6.rs b/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-6.rs new file mode 100644 index 000000000000..ae74a91a27b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-mod/use-mod-6.rs @@ -0,0 +1,14 @@ +mod foo { + pub mod bar { + pub fn drop() {} + } +} + +use foo::bar::self as abc; +// { dg-error ".E0429." "" { target *-*-* } .-1 } + +fn main() { + // Because of error recovery this shouldn't error + abc::drop(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-nested-groups-error.rs b/gcc/testsuite/rust/rustc/ui/use/use-nested-groups-error.rs new file mode 100644 index 000000000000..6adaf4941f1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-nested-groups-error.rs @@ -0,0 +1,16 @@ +mod a { + pub mod b1 { + pub enum C2 {} + } + + pub enum B2 {} +} + +use a::{b1::{C1, C2}, B2}; +// { dg-error ".E0432." "" { target *-*-* } .-1 } + +fn main() { + let _: C2; + let _: B2; +} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-nested-groups-unused-imports.rs b/gcc/testsuite/rust/rustc/ui/use/use-nested-groups-unused-imports.rs new file mode 100644 index 000000000000..58b8f0b5174e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-nested-groups-unused-imports.rs @@ -0,0 +1,26 @@ +#![feature(use_nested_groups)] +#![allow(dead_code)] +#![deny(unused_imports)] + +mod foo { + pub mod bar { + pub mod baz { + pub struct Bar(); + } + pub mod foobar {} + } + + pub struct Foo(); +} + +use foo::{Foo, bar::{baz::{}, foobar::*}, *}; +// { dg-error "" "" { target *-*-* } .-1 } +use foo::bar::baz::{*, *}; +// { dg-error "" "" { target *-*-* } .-1 } +use foo::{}; +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() { + let _: Bar; +} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-paths-as-items.rs b/gcc/testsuite/rust/rustc/ui/use/use-paths-as-items.rs new file mode 100644 index 000000000000..1d1e38ca28bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-paths-as-items.rs @@ -0,0 +1,10 @@ +// Each path node in a `use` declaration must be treated as an item. If not, the following code +// will trigger an ICE. +// +// Related issue: #25763 + +use std::{mem, ptr}; +use std::mem; // { dg-error ".E0252." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-self-type.rs b/gcc/testsuite/rust/rustc/ui/use/use-self-type.rs new file mode 100644 index 000000000000..506d242847ce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-self-type.rs @@ -0,0 +1,12 @@ +struct S; + +impl S { + fn f() {} + fn g() { + use Self::f; // { dg-error ".E0432." "" { target *-*-* } } + pub(in Self::f) struct Z; // { dg-error ".E0433." "" { target *-*-* } } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/use/use-super-global-path.rs b/gcc/testsuite/rust/rustc/ui/use/use-super-global-path.rs new file mode 100644 index 000000000000..d7945ecba68b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use/use-super-global-path.rs @@ -0,0 +1,17 @@ +#![allow(unused)] + +struct S; +struct Z; + +mod foo { + use ::super::{S, Z}; // { dg-error ".E0433." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + + pub fn g() { + use ::super::main; // { dg-error ".E0433." "" { target *-*-* } } + main(); // { dg-error ".E0425." "" { target *-*-* } } + } +} + +fn main() { foo::g(); } + diff --git a/gcc/testsuite/rust/rustc/ui/use_inline_dtor.rs b/gcc/testsuite/rust/rustc/ui/use_inline_dtor.rs new file mode 100644 index 000000000000..6f92b95934b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/use_inline_dtor.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:inline_dtor.rs + +// pretty-expanded FIXME #23616 + +extern crate inline_dtor; + +pub fn main() { + let _x = inline_dtor::Foo; +} + diff --git a/gcc/testsuite/rust/rustc/ui/used.rs b/gcc/testsuite/rust/rustc/ui/used.rs new file mode 100644 index 000000000000..d136b2e9a7b3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/used.rs @@ -0,0 +1,17 @@ +#[used] +static FOO: u32 = 0; // OK + +#[used] // { dg-error "" "" { target *-*-* } } +fn foo() {} + +#[used] // { dg-error "" "" { target *-*-* } } +struct Foo {} + +#[used] // { dg-error "" "" { target *-*-* } } +trait Bar {} + +#[used] // { dg-error "" "" { target *-*-* } } +impl Bar for Foo {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/useless-comment.rs b/gcc/testsuite/rust/rustc/ui/useless-comment.rs new file mode 100644 index 000000000000..2e7c77d95888 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/useless-comment.rs @@ -0,0 +1,46 @@ +#![feature(stmt_expr_attributes)] + +#![deny(unused_doc_comments)] + +macro_rules! mac { + () => {} +} + +/// foo // { dg-error "" "" { target *-*-* } } +mac!(); + +fn foo() { + /// a // { dg-error "" "" { target *-*-* } } + let x = 12; + + /// multi-line // { dg-error "" "" { target *-*-* } } + /// doc comment + /// that is unused + match x { + /// c // { dg-error "" "" { target *-*-* } } + 1 => {}, + _ => {} + } + + /// foo // { dg-error "" "" { target *-*-* } } + unsafe {} + + #[doc = "foo"] // { dg-error "" "" { target *-*-* } } + #[doc = "bar"] // { dg-error "" "" { target *-*-* } } + 3; + + /// bar // { dg-error "" "" { target *-*-* } } + mac!(); + + let x = /** comment */ 47; // { dg-error "" "" { target *-*-* } } + + /// dox // { dg-error "" "" { target *-*-* } } + { + + } +} + +fn main() { + foo(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/useless-pub.rs b/gcc/testsuite/rust/rustc/ui/useless-pub.rs new file mode 100644 index 000000000000..df4a2a790fd6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/useless-pub.rs @@ -0,0 +1,17 @@ +struct A { pub i: isize } + +pub trait E { + fn foo(&self); +} + +impl E for A { + pub fn foo(&self) {} // { dg-error ".E0449." "" { target *-*-* } } +} + +enum Foo { + V1 { pub f: i32 }, // { dg-error ".E0449." "" { target *-*-* } } + V2(pub i32), // { dg-error ".E0449." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/user-defined-macro-rules.rs b/gcc/testsuite/rust/rustc/ui/user-defined-macro-rules.rs new file mode 100644 index 000000000000..84836ad31151 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/user-defined-macro-rules.rs @@ -0,0 +1,10 @@ +// check-pass + +macro_rules! macro_rules { () => { struct S; } } // OK + +macro_rules! {} // OK, calls the macro defined above + +fn main() { + let s = S; +} + diff --git a/gcc/testsuite/rust/rustc/ui/using-target-feature-unstable.rs b/gcc/testsuite/rust/rustc/ui/using-target-feature-unstable.rs new file mode 100644 index 000000000000..36d264908405 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/using-target-feature-unstable.rs @@ -0,0 +1,12 @@ +// run-pass +// only-x86_64 +// aux-build:using-target-feature-unstable.rs + +extern crate using_target_feature_unstable; + +fn main() { + unsafe { + using_target_feature_unstable::foo(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/usize-generic-argument-parent.rs b/gcc/testsuite/rust/rustc/ui/usize-generic-argument-parent.rs new file mode 100644 index 000000000000..9518e67eb512 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/usize-generic-argument-parent.rs @@ -0,0 +1,6 @@ +fn foo() { + let x: usize; // { dg-error ".E0109." "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/utf8-bom.rs b/gcc/testsuite/rust/rustc/ui/utf8-bom.rs new file mode 100644 index 000000000000..b46e06204eed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/utf8-bom.rs @@ -0,0 +1,7 @@ +// run-pass +// + +// This file has utf-8 BOM, it should be compiled normally without error. + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/utf8.rs b/gcc/testsuite/rust/rustc/ui/utf8.rs new file mode 100644 index 000000000000..b689424f948f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/utf8.rs @@ -0,0 +1,51 @@ +// run-pass + +pub fn main() { + let yen: char = '¥'; // 0xa5 + let c_cedilla: char = 'ç'; // 0xe7 + let thorn: char = 'þ'; // 0xfe + let y_diaeresis: char = 'ÿ'; // 0xff + let pi: char = 'Π'; // 0x3a0 + + assert_eq!(yen as isize, 0xa5); + assert_eq!(c_cedilla as isize, 0xe7); + assert_eq!(thorn as isize, 0xfe); + assert_eq!(y_diaeresis as isize, 0xff); + assert_eq!(pi as isize, 0x3a0); + + assert_eq!(pi as isize, '\u{3a0}' as isize); + assert_eq!('\x0a' as isize, '\n' as isize); + + let bhutan: String = "འབྲུག་ཡུལ།".to_string(); + let japan: String = "日本".to_string(); + let uzbekistan: String = "Ўзбекистон".to_string(); + let austria: String = "Österreich".to_string(); + + let bhutan_e: String = + "\u{f60}\u{f56}\u{fb2}\u{f74}\u{f42}\u{f0b}\u{f61}\u{f74}\u{f63}\u{f0d}".to_string(); + let japan_e: String = "\u{65e5}\u{672c}".to_string(); + let uzbekistan_e: String = + "\u{40e}\u{437}\u{431}\u{435}\u{43a}\u{438}\u{441}\u{442}\u{43e}\u{43d}".to_string(); + let austria_e: String = "\u{d6}sterreich".to_string(); + + let oo: char = 'Ö'; + assert_eq!(oo as isize, 0xd6); + + fn check_str_eq(a: String, b: String) { + let mut i: isize = 0; + for ab in a.bytes() { + println!("{}", i); + println!("{}", ab); + let bb: u8 = b.as_bytes()[i as usize]; + println!("{}", bb); + assert_eq!(ab, bb); + i += 1; + } + } + + check_str_eq(bhutan, bhutan_e); + check_str_eq(japan, japan_e); + check_str_eq(uzbekistan, uzbekistan_e); + check_str_eq(austria, austria_e); +} + diff --git a/gcc/testsuite/rust/rustc/ui/utf8_chars.rs b/gcc/testsuite/rust/rustc/ui/utf8_chars.rs new file mode 100644 index 000000000000..c5709acbef20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/utf8_chars.rs @@ -0,0 +1,32 @@ +// run-pass + +use std::str; + +pub fn main() { + // Chars of 1, 2, 3, and 4 bytes + let chs: Vec = vec!['e', 'é', '€', '\u{10000}']; + let s: String = chs.iter().cloned().collect(); + let schs: Vec = s.chars().collect(); + + assert_eq!(s.len(), 10); + assert_eq!(s.chars().count(), 4); + assert_eq!(schs.len(), 4); + assert_eq!(schs.iter().cloned().collect::(), s); + + assert!((str::from_utf8(s.as_bytes()).is_ok())); + // invalid prefix + assert!((!str::from_utf8(&[0x80]).is_ok())); + // invalid 2 byte prefix + assert!((!str::from_utf8(&[0xc0]).is_ok())); + assert!((!str::from_utf8(&[0xc0, 0x10]).is_ok())); + // invalid 3 byte prefix + assert!((!str::from_utf8(&[0xe0]).is_ok())); + assert!((!str::from_utf8(&[0xe0, 0x10]).is_ok())); + assert!((!str::from_utf8(&[0xe0, 0xff, 0x10]).is_ok())); + // invalid 4 byte prefix + assert!((!str::from_utf8(&[0xf0]).is_ok())); + assert!((!str::from_utf8(&[0xf0, 0x10]).is_ok())); + assert!((!str::from_utf8(&[0xf0, 0xff, 0x10]).is_ok())); + assert!((!str::from_utf8(&[0xf0, 0xff, 0xff, 0x10]).is_ok())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/utf8_idents-rpass.rs b/gcc/testsuite/rust/rustc/ui/utf8_idents-rpass.rs new file mode 100644 index 000000000000..11be79d98953 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/utf8_idents-rpass.rs @@ -0,0 +1,42 @@ +// run-pass +// +#![allow(non_snake_case)] + +#![feature(non_ascii_idents)] + +pub fn main() { + let ε = 0.00001f64; + let Π = 3.14f64; + let लंच = Π * Π + 1.54; + assert!(((लंच - 1.54) - (Π * Π)).abs() < ε); + assert_eq!(საჭმელად_გემრიელი_სადილი(), 0); +} + +fn საჭმელად_გემრიელი_სადილი() -> isize { + + // Lunch in several languages. + + let ランチ = 10; + let 午餐 = 10; + + let ארוחת_צהריי = 10; + let غداء = 10_usize; + let լանչ = 10; + let обед = 10; + let абед = 10; + let μεσημεριανό = 10; + let hádegismatur = 10; + let ручек = 10; + + let ăn_trưa = 10; + let อาหารกลางวัน = 10; + + // Lunchy arithmetic, mm. + + assert_eq!(hádegismatur * ручек * обед, 1000); + assert_eq!(10, ארוחת_צהריי); + assert_eq!(ランチ + 午餐 + μεσημεριανό, 30); + assert_eq!(ăn_trưa + อาหารกลางวัน, 20); + return (абед + լանչ) >> غداء; +} + diff --git a/gcc/testsuite/rust/rustc/ui/utf8_idents.rs b/gcc/testsuite/rust/rustc/ui/utf8_idents.rs new file mode 100644 index 000000000000..88ba67eacb7a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/utf8_idents.rs @@ -0,0 +1,16 @@ +#![allow(mixed_script_confusables)] + +fn foo< + 'β, // { dg-error ".E0658." "" { target *-*-* } } + γ // { dg-error ".E0658." "" { target *-*-* } } +// { dg-warning ".E0658." "" { target *-*-* } .-1 } +>() {} + +struct X { + δ: usize // { dg-error ".E0658." "" { target *-*-* } } +} + +pub fn main() { + let α = 0.00001f64; // { dg-error ".E0658." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/variance-intersection-of-ref-and-opt-ref.rs b/gcc/testsuite/rust/rustc/ui/variance-intersection-of-ref-and-opt-ref.rs new file mode 100644 index 000000000000..c89ccc6aa9ff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance-intersection-of-ref-and-opt-ref.rs @@ -0,0 +1,26 @@ +// run-pass +// Elaborated version of the opening example from RFC 738. This failed +// to compile before variance because invariance of `Option` prevented +// us from approximating the lifetimes of `field1` and `field2` to a +// common intersection. + +#![allow(dead_code)] + +struct List<'l> { + field1: &'l i32, + field2: Option<&'l i32>, +} + +fn foo(field1: &i32, field2: Option<&i32>) -> i32 { + let list = List { field1: field1, field2: field2 }; + *list.field1 + list.field2.cloned().unwrap_or(0) +} + +fn main() { + let x = 22; + let y = Some(3); + let z = None; + assert_eq!(foo(&x, y.as_ref()), 25); + assert_eq!(foo(&x, z.as_ref()), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/variance-iterators-in-libcore.rs b/gcc/testsuite/rust/rustc/ui/variance-iterators-in-libcore.rs new file mode 100644 index 000000000000..0b06ca768dca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance-iterators-in-libcore.rs @@ -0,0 +1,11 @@ +// run-pass + +#![allow(dead_code)] + +use std::iter::{Fuse, Zip}; + +fn fuse_covariant<'a, I>(iter: Fuse<&'static I>) -> Fuse<&'a I> { iter } +fn zip_covariant<'a, A, B>(iter: Zip<&'static A, &'static B>) -> Zip<&'a A, &'a B> { iter } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-associated-types.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-associated-types.rs new file mode 100644 index 000000000000..760b9270832b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-associated-types.rs @@ -0,0 +1,23 @@ +// Test that the variance computation considers types/regions that +// appear in projections to be invariant. + +#![feature(rustc_attrs)] + +trait Trait<'a> { + type Type; + + fn method(&'a self) { } +} + +#[rustc_variance] +struct Foo<'a, T : Trait<'a>> { // { dg-error ".E0208." "" { target *-*-* } } + field: (T, &'a ()) +} + +#[rustc_variance] +struct Bar<'a, T : Trait<'a>> { // { dg-error ".E0208." "" { target *-*-* } } + field: >::Type +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-associated-types2.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-associated-types2.rs new file mode 100644 index 000000000000..33c7b48ce822 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-associated-types2.rs @@ -0,0 +1,18 @@ +// Test that dyn Foo is invariant with respect to T. +// Failure to enforce invariance here can be weaponized, see #71550 for details. + +trait Foo { + type Bar; +} + +fn make() -> Box> { + panic!() +} + +fn take<'a>(_: &'a u32) { + let _: Box> = make(); +// { dg-error ".E0308." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-btree-invariant-types.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-btree-invariant-types.rs new file mode 100644 index 000000000000..c40c0077136e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-btree-invariant-types.rs @@ -0,0 +1,52 @@ +use std::collections::btree_map::{IterMut, OccupiedEntry, VacantEntry}; + +fn iter_cov_key<'a, 'new>(v: IterMut<'a, &'static (), ()>) -> IterMut<'a, &'new (), ()> { + v // { dg-error ".E0308." "" { target *-*-* } } +} +fn iter_cov_val<'a, 'new>(v: IterMut<'a, (), &'static ()>) -> IterMut<'a, (), &'new ()> { + v // { dg-error ".E0308." "" { target *-*-* } } +} +fn iter_contra_key<'a, 'new>(v: IterMut<'a, &'new (), ()>) -> IterMut<'a, &'static (), ()> { + v // { dg-error ".E0308." "" { target *-*-* } } +} +fn iter_contra_val<'a, 'new>(v: IterMut<'a, (), &'new ()>) -> IterMut<'a, (), &'static ()> { + v // { dg-error ".E0308." "" { target *-*-* } } +} + +fn occ_cov_key<'a, 'new>(v: OccupiedEntry<'a, &'static (), ()>) + -> OccupiedEntry<'a, &'new (), ()> { + v // { dg-error ".E0308." "" { target *-*-* } } +} +fn occ_cov_val<'a, 'new>(v: OccupiedEntry<'a, (), &'static ()>) + -> OccupiedEntry<'a, (), &'new ()> { + v // { dg-error ".E0308." "" { target *-*-* } } +} +fn occ_contra_key<'a, 'new>(v: OccupiedEntry<'a, &'new (), ()>) + -> OccupiedEntry<'a, &'static (), ()> { + v // { dg-error ".E0308." "" { target *-*-* } } +} +fn occ_contra_val<'a, 'new>(v: OccupiedEntry<'a, (), &'new ()>) + -> OccupiedEntry<'a, (), &'static ()> { + v // { dg-error ".E0308." "" { target *-*-* } } +} + +fn vac_cov_key<'a, 'new>(v: VacantEntry<'a, &'static (), ()>) + -> VacantEntry<'a, &'new (), ()> { + v // { dg-error ".E0308." "" { target *-*-* } } +} +fn vac_cov_val<'a, 'new>(v: VacantEntry<'a, (), &'static ()>) + -> VacantEntry<'a, (), &'new ()> { + v // { dg-error ".E0308." "" { target *-*-* } } +} +fn vac_contra_key<'a, 'new>(v: VacantEntry<'a, &'new (), ()>) + -> VacantEntry<'a, &'static (), ()> { + v // { dg-error ".E0308." "" { target *-*-* } } +} +fn vac_contra_val<'a, 'new>(v: VacantEntry<'a, (), &'new ()>) + -> VacantEntry<'a, (), &'static ()> { + v // { dg-error ".E0308." "" { target *-*-* } } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-cell-is-invariant.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-cell-is-invariant.rs new file mode 100644 index 000000000000..2ab9629fd1de --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-cell-is-invariant.rs @@ -0,0 +1,19 @@ +// Test that Cell is considered invariant with respect to its +// type. + +use std::cell::Cell; + +struct Foo<'a> { + x: Cell>, +} + +fn use_<'short,'long>(c: Foo<'short>, + s: &'short isize, + l: &'long isize, + _where:Option<&'short &'long ()>) { + let _: Foo<'long> = c; // { dg-error ".E0623." "" { target *-*-* } } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-contravariant-arg-object.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-contravariant-arg-object.rs new file mode 100644 index 000000000000..0bd86d6507e4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-contravariant-arg-object.rs @@ -0,0 +1,26 @@ +#![allow(dead_code)] + +// Test that even when `T` is only used in contravariant position, it +// is treated as invariant. + +trait Get : 'static { + fn get(&self, t: T); +} + +fn get_min_from_max<'min, 'max>(v: Box>) + -> Box> + where 'max : 'min +{ + v // { dg-error ".E0308." "" { target *-*-* } } +} + +fn get_max_from_min<'min, 'max, G>(v: Box>) + -> Box> + where 'max : 'min +{ + // Previously OK: + v // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-contravariant-arg-trait-match.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-contravariant-arg-trait-match.rs new file mode 100644 index 000000000000..5d28024aae24 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-contravariant-arg-trait-match.rs @@ -0,0 +1,27 @@ +#![allow(dead_code)] + +// Test that even when `T` is only used in contravariant position, it +// is treated as invariant. + +trait Get { + fn get(&self, t: T); +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : Get<&'max i32> +{ + impls_get::() // { dg-error ".E0308." "" { target *-*-* } } +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : Get<&'min i32> +{ + // Previously OK, but now an error because traits are invariant: + + impls_get::() // { dg-error ".E0308." "" { target *-*-* } } +} + +fn impls_get() where G : Get { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-contravariant-self-trait-match.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-contravariant-self-trait-match.rs new file mode 100644 index 000000000000..2b5662c77ad8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-contravariant-self-trait-match.rs @@ -0,0 +1,28 @@ +#![allow(dead_code)] + +// Test that even when `Self` is only used in contravariant position, it +// is treated as invariant. + +trait Get { + fn get(&self); +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : 'max, &'max G : Get +{ + impls_get::<&'min G>(); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : 'max, &'min G : Get +{ + // Previously OK, but now error because traits are invariant with + // respect to all inputs. + + impls_get::<&'max G>(); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn impls_get() where G : Get { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-covariant-arg-object.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-covariant-arg-object.rs new file mode 100644 index 000000000000..b3817fb53b84 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-covariant-arg-object.rs @@ -0,0 +1,26 @@ +#![allow(dead_code)] + +// Test that even when `T` is only used in covariant position, it +// is treated as invariant. + +trait Get : 'static { + fn get(&self) -> T; +} + +fn get_min_from_max<'min, 'max>(v: Box>) + -> Box> + where 'max : 'min +{ + // Previously OK, now an error as traits are invariant. + v // { dg-error ".E0308." "" { target *-*-* } } +} + +fn get_max_from_min<'min, 'max, G>(v: Box>) + -> Box> + where 'max : 'min +{ + v // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-covariant-arg-trait-match.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-covariant-arg-trait-match.rs new file mode 100644 index 000000000000..6cde0ba463b1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-covariant-arg-trait-match.rs @@ -0,0 +1,26 @@ +#![allow(dead_code)] + +// Test that even when `T` is only used in covariant position, it +// is treated as invariant. + +trait Get { + fn get(&self) -> T; +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : Get<&'max i32> +{ + // Previously OK, now an error as traits are invariant. + impls_get::() // { dg-error ".E0308." "" { target *-*-* } } +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : Get<&'min i32> +{ + impls_get::() // { dg-error ".E0308." "" { target *-*-* } } +} + +fn impls_get() where G : Get { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-covariant-self-trait-match.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-covariant-self-trait-match.rs new file mode 100644 index 000000000000..02832d5b6e20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-covariant-self-trait-match.rs @@ -0,0 +1,26 @@ +#![allow(dead_code)] + +// Test that even when `Self` is only used in covariant position, it +// is treated as invariant. + +trait Get { + fn get() -> Self; +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : 'max, &'max G : Get +{ + // Previously OK, now an error as traits are invariant. + impls_get::<&'min G>(); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : 'max, &'min G : Get +{ + impls_get::<&'max G>(); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn impls_get() where G : Get { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-invariant-arg-object.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-invariant-arg-object.rs new file mode 100644 index 000000000000..e61f7c309a09 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-invariant-arg-object.rs @@ -0,0 +1,22 @@ +#![allow(dead_code)] + +trait Get : 'static { + fn get(&self, t: T) -> T; +} + +fn get_min_from_max<'min, 'max>(v: Box>) + -> Box> + where 'max : 'min +{ + v // { dg-error ".E0308." "" { target *-*-* } } +} + +fn get_max_from_min<'min, 'max, G>(v: Box>) + -> Box> + where 'max : 'min +{ + v // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-invariant-arg-trait-match.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-invariant-arg-trait-match.rs new file mode 100644 index 000000000000..b8accea19653 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-invariant-arg-trait-match.rs @@ -0,0 +1,22 @@ +#![allow(dead_code)] + +trait Get { + fn get(&self, t: T) -> T; +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, G : Get<&'max i32> +{ + impls_get::() // { dg-error ".E0308." "" { target *-*-* } } +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, G : Get<&'min i32> +{ + impls_get::() // { dg-error ".E0308." "" { target *-*-* } } +} + +fn impls_get() where G : Get { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-invariant-self-trait-match.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-invariant-self-trait-match.rs new file mode 100644 index 000000000000..8fd0c8602738 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-invariant-self-trait-match.rs @@ -0,0 +1,22 @@ +#![allow(dead_code)] + +trait Get { + fn get(&self) -> Self; +} + +fn get_min_from_max<'min, 'max, G>() + where 'max : 'min, &'max G : Get, G : 'max +{ + impls_get::<&'min G>(); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn get_max_from_min<'min, 'max, G>() + where 'max : 'min, &'min G : Get, G : 'min +{ + impls_get::<&'max G>(); // { dg-error ".E0308." "" { target *-*-* } } +} + +fn impls_get() where G : Get { } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-issue-20533.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-issue-20533.rs new file mode 100644 index 000000000000..6fe166c5638c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-issue-20533.rs @@ -0,0 +1,44 @@ +// Regression test for issue #20533. At some point, only 1 out of the +// 3 errors below were being reported. + +use std::marker::PhantomData; + +fn foo<'a, T>(_x: &'a T) -> PhantomData<&'a ()> { + PhantomData +} + +struct Wrap(T); + +fn bar<'a, T>(_x: &'a T) -> Wrap> { + Wrap(PhantomData) +} + +struct Baked<'a>(PhantomData<&'a ()>); + +fn baz<'a, T>(_x: &'a T) -> Baked<'a> { + Baked(PhantomData) +} + +struct AffineU32(u32); + +fn main() { + { + let a = AffineU32(1); + let x = foo(&a); + drop(a); // { dg-error ".E0505." "" { target *-*-* } } + drop(x); + } + { + let a = AffineU32(1); + let x = bar(&a); + drop(a); // { dg-error ".E0505." "" { target *-*-* } } + drop(x); + } + { + let a = AffineU32(1); + let x = baz(&a); + drop(a); // { dg-error ".E0505." "" { target *-*-* } } + drop(x); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-object-types.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-object-types.rs new file mode 100644 index 000000000000..54250996b1e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-object-types.rs @@ -0,0 +1,17 @@ +// Test that Cell is considered invariant with respect to its +// type. + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// For better or worse, associated types are invariant, and hence we +// get an invariant result for `'a`. +#[rustc_variance] +struct Foo<'a> { // { dg-error ".E0208." "" { target *-*-* } } + x: Box &'a i32 + 'static> +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-regions-direct.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-regions-direct.rs new file mode 100644 index 000000000000..c5b7e5cdf46e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-regions-direct.rs @@ -0,0 +1,66 @@ +// Test that we correctly infer variance for region parameters in +// various self-contained types. + +#![feature(rustc_attrs)] + +// Regions that just appear in normal spots are contravariant: + +#[rustc_variance] +struct Test2<'a, 'b, 'c> { // { dg-error ".E0208." "" { target *-*-* } } + x: &'a isize, + y: &'b [isize], + c: &'c str +} + +// Those same annotations in function arguments become covariant: + +#[rustc_variance] +struct Test3<'a, 'b, 'c> { // { dg-error ".E0208." "" { target *-*-* } } + x: extern "Rust" fn(&'a isize), + y: extern "Rust" fn(&'b [isize]), + c: extern "Rust" fn(&'c str), +} + +// Mutability induces invariance: + +#[rustc_variance] +struct Test4<'a, 'b:'a> { // { dg-error ".E0208." "" { target *-*-* } } + x: &'a mut &'b isize, +} + +// Mutability induces invariance, even when in a +// contravariant context: + +#[rustc_variance] +struct Test5<'a, 'b:'a> { // { dg-error ".E0208." "" { target *-*-* } } + x: extern "Rust" fn(&'a mut &'b isize), +} + +// Invariance is a trap from which NO ONE CAN ESCAPE. +// In other words, even though the `&'b isize` occurs in +// an argument list (which is contravariant), that +// argument list occurs in an invariant context. + +#[rustc_variance] +struct Test6<'a, 'b:'a> { // { dg-error ".E0208." "" { target *-*-* } } + x: &'a mut extern "Rust" fn(&'b isize), +} + +// No uses at all is bivariant: + +#[rustc_variance] +struct Test7<'a> { // { dg-error ".E0208." "" { target *-*-* } } + x: isize +} + +// Try enums too. + +#[rustc_variance] +enum Test8<'a, 'b, 'c:'b> { // { dg-error ".E0208." "" { target *-*-* } } + Test8A(extern "Rust" fn(&'a isize)), + Test8B(&'b [isize]), + Test8C(&'b mut &'c str), +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-regions-indirect.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-regions-indirect.rs new file mode 100644 index 000000000000..0af4a6d6477f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-regions-indirect.rs @@ -0,0 +1,35 @@ +// Test that we correctly infer variance for region parameters in +// case that involve multiple intricate types. +// Try enums too. + +#![feature(rustc_attrs)] + +#[rustc_variance] +enum Base<'a, 'b, 'c:'b, 'd> { // { dg-error ".E0208." "" { target *-*-* } } + Test8A(extern "Rust" fn(&'a isize)), + Test8B(&'b [isize]), + Test8C(&'b mut &'c str), +} + +#[rustc_variance] +struct Derived1<'w, 'x:'y, 'y, 'z> { // { dg-error ".E0208." "" { target *-*-* } } + f: Base<'z, 'y, 'x, 'w> +} + +#[rustc_variance] // Combine - and + to yield o +struct Derived2<'a, 'b:'a, 'c> { // { dg-error ".E0208." "" { target *-*-* } } + f: Base<'a, 'a, 'b, 'c> +} + +#[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here) +struct Derived3<'a:'b, 'b, 'c> { // { dg-error ".E0208." "" { target *-*-* } } + f: Base<'a, 'b, 'a, 'c> +} + +#[rustc_variance] // Combine + and * to yield + (just pay attention to 'a here) +struct Derived4<'a, 'b, 'c:'b> { // { dg-error ".E0208." "" { target *-*-* } } + f: Base<'a, 'b, 'c, 'a> +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-regions-unused-direct.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-regions-unused-direct.rs new file mode 100644 index 000000000000..cce1062b07c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-regions-unused-direct.rs @@ -0,0 +1,16 @@ +// Test that disallow lifetime parameters that are unused. + +use std::marker; + +struct Bivariant<'a>; // { dg-error ".E0392." "" { target *-*-* } } + +struct Struct<'a, 'd> { // { dg-error ".E0392." "" { target *-*-* } } + field: &'a [i32] +} + +trait Trait<'a, 'd> { // OK on traits + fn method(&'a self); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-regions-unused-indirect.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-regions-unused-indirect.rs new file mode 100644 index 000000000000..07b82be38407 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-regions-unused-indirect.rs @@ -0,0 +1,12 @@ +// Test that disallow lifetime parameters that are unused. + +enum Foo<'a> { // { dg-error ".E0392." "" { target *-*-* } } + Foo1(Bar<'a>) +} + +enum Bar<'a> { // { dg-error ".E0392." "" { target *-*-* } } + Bar1(Foo<'a>) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-trait-bounds.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-trait-bounds.rs new file mode 100644 index 000000000000..7d48a1adfb99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-trait-bounds.rs @@ -0,0 +1,36 @@ +#![allow(dead_code)] +#![feature(rustc_attrs)] + +// Check that bounds on type parameters (other than `Self`) do not +// influence variance. + +trait Getter { + fn get(&self) -> T; +} + +trait Setter { + fn get(&self, _: T); +} + +#[rustc_variance] +struct TestStruct> { // { dg-error ".E0208." "" { target *-*-* } } + t: T, u: U +} + +#[rustc_variance] +enum TestEnum> { // { dg-error ".E0208." "" { target *-*-* } } + Foo(T) +} + +#[rustc_variance] +struct TestContraStruct> { // { dg-error ".E0208." "" { target *-*-* } } + t: T +} + +#[rustc_variance] +struct TestBox+Setter> { // { dg-error ".E0208." "" { target *-*-* } } + t: T +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-trait-matching.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-trait-matching.rs new file mode 100644 index 000000000000..90afd200b04c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-trait-matching.rs @@ -0,0 +1,39 @@ +#![allow(dead_code)] + +// Get is covariant in T +trait Get { + fn get(&self) -> T; +} + +struct Cloner { + t: T +} + +impl Get for Cloner { + fn get(&self) -> T { + self.t.clone() + } +} + +fn get<'a, G>(get: &G) -> i32 + where G : Get<&'a i32> +{ + // This fails to type-check because, without variance, we can't + // use `G : Get<&'a i32>` as evidence that `G : Get<&'b i32>`, + // even if `'a : 'b`. + pick(get, &22) // { dg-error ".E0621." "" { target *-*-* } } +} + +fn pick<'b, G>(get: &'b G, if_odd: &'b i32) -> i32 + where G : Get<&'b i32> +{ + let v = *get.get(); + if v % 2 != 0 { v } else { *if_odd } +} + +fn main() { + let x = Cloner { t: &23 }; + let y = get(&x); + assert_eq!(y, 23); +} + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-trait-object-bound.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-trait-object-bound.rs new file mode 100644 index 000000000000..023a8683fbd3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-trait-object-bound.rs @@ -0,0 +1,19 @@ +// Checks that regions which appear in a trait object type are +// observed by the variance inference algorithm (and hence +// `TOption` is contavariant w/r/t `'a` and not bivariant). +// +// Issue #18262. + +#![feature(rustc_attrs)] + +use std::mem; + +trait T { fn foo(&self); } + +#[rustc_variance] +struct TOption<'a> { // { dg-error ".E0208." "" { target *-*-* } } + v: Option>, +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-types-bounds.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-types-bounds.rs new file mode 100644 index 000000000000..5185bc1b13d1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-types-bounds.rs @@ -0,0 +1,44 @@ +// Test that we correctly infer variance for type parameters in +// various types and traits. + +#![feature(rustc_attrs)] + +#[rustc_variance] +struct TestImm { // { dg-error ".E0208." "" { target *-*-* } } + x: A, + y: B, +} + +#[rustc_variance] +struct TestMut { // { dg-error ".E0208." "" { target *-*-* } } + x: A, + y: &'static mut B, +} + +#[rustc_variance] +struct TestIndirect { // { dg-error ".E0208." "" { target *-*-* } } + m: TestMut +} + +#[rustc_variance] +struct TestIndirect2 { // { dg-error ".E0208." "" { target *-*-* } } + n: TestMut, + m: TestMut +} + +trait Getter { + fn get(&self) -> A; +} + +trait Setter { + fn set(&mut self, a: A); +} + +#[rustc_variance] +struct TestObject { // { dg-error ".E0208." "" { target *-*-* } } + n: Box+Send>, + m: Box+Send>, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-types.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-types.rs new file mode 100644 index 000000000000..8f6ed77a08f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-types.rs @@ -0,0 +1,42 @@ +#![allow(dead_code)] +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// Check that a type parameter which is only used in a trait bound is +// not considered bivariant. + +#[rustc_variance] +struct InvariantMut<'a,A:'a,B:'a> { // { dg-error ".E0208." "" { target *-*-* } } + t: &'a mut (A,B) +} + +#[rustc_variance] +struct InvariantCell { // { dg-error ".E0208." "" { target *-*-* } } + t: Cell +} + +#[rustc_variance] +struct InvariantIndirect { // { dg-error ".E0208." "" { target *-*-* } } + t: InvariantCell +} + +#[rustc_variance] +struct Covariant { // { dg-error ".E0208." "" { target *-*-* } } + t: A, u: fn() -> A +} + +#[rustc_variance] +struct Contravariant { // { dg-error ".E0208." "" { target *-*-* } } + t: fn(A) +} + +#[rustc_variance] +enum Enum { // { dg-error ".E0208." "" { target *-*-* } } + Foo(Covariant), + Bar(Contravariant), + Zed(Covariant,Contravariant) +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-unused-region-param.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-unused-region-param.rs new file mode 100644 index 000000000000..73ac7e0ddc18 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-unused-region-param.rs @@ -0,0 +1,8 @@ +// Test that we report an error for unused type parameters in types. + +struct SomeStruct<'a> { x: u32 } // { dg-error ".E0392." "" { target *-*-* } } +enum SomeEnum<'a> { Nothing } // { dg-error ".E0392." "" { target *-*-* } } +trait SomeTrait<'a> { fn foo(&self); } // OK on traits. + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-unused-type-param.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-unused-type-param.rs new file mode 100644 index 000000000000..478138c5f305 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-unused-type-param.rs @@ -0,0 +1,20 @@ +#![allow(dead_code)] + +// Test that we report an error for unused type parameters in types and traits, +// and that we offer a helpful suggestion. + +struct SomeStruct { x: u32 } +// { dg-error ".E0392." "" { target *-*-* } .-1 } + +enum SomeEnum { Nothing } +// { dg-error ".E0392." "" { target *-*-* } .-1 } + +// Here T might *appear* used, but in fact it isn't. +enum ListCell { +// { dg-error ".E0392." "" { target *-*-* } .-1 } + Cons(Box>), + Nil +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-use-contravariant-struct-1.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-use-contravariant-struct-1.rs new file mode 100644 index 000000000000..31cd4e1e898c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-use-contravariant-struct-1.rs @@ -0,0 +1,17 @@ +// Test various uses of structs with distint variances to make sure +// they permit lifetimes to be approximated as expected. + + + +struct SomeStruct(fn(T)); + +fn foo<'min,'max>(v: SomeStruct<&'max ()>) + -> SomeStruct<&'min ()> + where 'max : 'min +{ + v // { dg-error ".E0308." "" { target *-*-* } } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-use-contravariant-struct-2.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-use-contravariant-struct-2.rs new file mode 100644 index 000000000000..422f90029f3d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-use-contravariant-struct-2.rs @@ -0,0 +1,18 @@ +// Test various uses of structs with distint variances to make sure +// they permit lifetimes to be approximated as expected. + +#![allow(dead_code)] +// build-pass (FIXME(62277): could be check-pass?) + +struct SomeStruct(fn(T)); + +fn bar<'min,'max>(v: SomeStruct<&'min ()>) + -> SomeStruct<&'max ()> + where 'max : 'min +{ + v +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-use-covariant-struct-1.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-use-covariant-struct-1.rs new file mode 100644 index 000000000000..702214b56fab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-use-covariant-struct-1.rs @@ -0,0 +1,14 @@ +// Test that a covariant struct does not permit the lifetime of a +// reference to be enlarged. + +struct SomeStruct(T); + +fn foo<'min,'max>(v: SomeStruct<&'min ()>) + -> SomeStruct<&'max ()> + where 'max : 'min +{ + v // { dg-error ".E0308." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-use-covariant-struct-2.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-use-covariant-struct-2.rs new file mode 100644 index 000000000000..44efe1d66d10 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-use-covariant-struct-2.rs @@ -0,0 +1,17 @@ +// Test that a covariant struct permits the lifetime of a reference to +// be shortened. + +#![allow(dead_code)] +// build-pass (FIXME(62277): could be check-pass?) + +struct SomeStruct(T); + +fn foo<'min,'max>(v: SomeStruct<&'max ()>) + -> SomeStruct<&'min ()> + where 'max : 'min +{ + v +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variance/variance-use-invariant-struct-1.rs b/gcc/testsuite/rust/rustc/ui/variance/variance-use-invariant-struct-1.rs new file mode 100644 index 000000000000..3e37c180e3c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variance/variance-use-invariant-struct-1.rs @@ -0,0 +1,24 @@ +// Test various uses of structs with distint variances to make sure +// they permit lifetimes to be approximated as expected. + + + +struct SomeStruct(*mut T); + +fn foo<'min,'max>(v: SomeStruct<&'max ()>) + -> SomeStruct<&'min ()> + where 'max : 'min +{ + v // { dg-error ".E0308." "" { target *-*-* } } +} + +fn bar<'min,'max>(v: SomeStruct<&'min ()>) + -> SomeStruct<&'max ()> + where 'max : 'min +{ + v // { dg-error ".E0308." "" { target *-*-* } } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/variants/auxiliary/variant-namespacing.rs b/gcc/testsuite/rust/rustc/ui/variants/auxiliary/variant-namespacing.rs new file mode 100644 index 000000000000..5b7683109133 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variants/auxiliary/variant-namespacing.rs @@ -0,0 +1,6 @@ +pub enum XE { + XStruct { a: u8 }, + XTuple(u8), + XUnit, +} + diff --git a/gcc/testsuite/rust/rustc/ui/variants/variant-namespacing.rs b/gcc/testsuite/rust/rustc/ui/variants/variant-namespacing.rs new file mode 100644 index 000000000000..bac37a8bafe3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variants/variant-namespacing.rs @@ -0,0 +1,34 @@ +// aux-build:variant-namespacing.rs + +enum E { + Struct { a: u8 }, + Tuple(u8), + Unit, +} + +type Struct = u8; +type Tuple = u8; +type Unit = u8; +type XStruct = u8; +type XTuple = u8; +type XUnit = u8; + +const Struct: u8 = 0; +const Tuple: u8 = 0; +const Unit: u8 = 0; +const XStruct: u8 = 0; +const XTuple: u8 = 0; +const XUnit: u8 = 0; + +extern crate variant_namespacing; +pub use variant_namespacing::XE::{XStruct, XTuple, XUnit}; +// { dg-error ".E0255." "" { target *-*-* } .-1 } +// { dg-error ".E0255." "" { target *-*-* } .-2 } +// { dg-error ".E0255." "" { target *-*-* } .-3 } +pub use E::{Struct, Tuple, Unit}; +// { dg-error ".E0255." "" { target *-*-* } .-1 } +// { dg-error ".E0255." "" { target *-*-* } .-2 } +// { dg-error ".E0255." "" { target *-*-* } .-3 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/variants/variant-size-differences.rs b/gcc/testsuite/rust/rustc/ui/variants/variant-size-differences.rs new file mode 100644 index 000000000000..a82df9ab3172 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variants/variant-size-differences.rs @@ -0,0 +1,9 @@ +#![deny(variant_size_differences)] + +enum _En { + V0(u8), + VBig([u8; 1024]), // { dg-error "" "" { target *-*-* } } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/variants/variant-used-as-type.rs b/gcc/testsuite/rust/rustc/ui/variants/variant-used-as-type.rs new file mode 100644 index 000000000000..c798ef7f31aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/variants/variant-used-as-type.rs @@ -0,0 +1,21 @@ +// Test error message when enum variants are used as types + + +// issue 21225 +enum Ty { + A, + B(Ty::A), +// { dg-error ".E0573." "" { target *-*-* } .-1 } +} + + +// issue 19197 +enum E { + A +} + +impl E::A {} +// { dg-error ".E0573." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/vec/vec-macro-with-comma-only.rs b/gcc/testsuite/rust/rustc/ui/vec/vec-macro-with-comma-only.rs new file mode 100644 index 000000000000..716c233ddaca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/vec/vec-macro-with-comma-only.rs @@ -0,0 +1,4 @@ +pub fn main() { + vec![,]; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/vec/vec-mut-iter-borrow.rs b/gcc/testsuite/rust/rustc/ui/vec/vec-mut-iter-borrow.rs new file mode 100644 index 000000000000..92bb88c95999 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/vec/vec-mut-iter-borrow.rs @@ -0,0 +1,8 @@ +fn main() { + let mut xs: Vec = vec![]; + + for x in &mut xs { + xs.push(1) // { dg-error ".E0499." "" { target *-*-* } } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/vec/vec-overrun.rs b/gcc/testsuite/rust/rustc/ui/vec/vec-overrun.rs new file mode 100644 index 000000000000..8ca5acac8c27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/vec/vec-overrun.rs @@ -0,0 +1,13 @@ +// run-fail +// error-pattern:index out of bounds: the len is 1 but the index is 2 +// ignore-emscripten no processes + +fn main() { + let v: Vec = vec![10]; + let x: usize = 0; + assert_eq!(v[x], 10); + // Bounds-check panic. + + assert_eq!(v[x + 2], 20); +} + diff --git a/gcc/testsuite/rust/rustc/ui/vec/vec-res-add.rs b/gcc/testsuite/rust/rustc/ui/vec/vec-res-add.rs new file mode 100644 index 000000000000..803eba874ef2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/vec/vec-res-add.rs @@ -0,0 +1,20 @@ +#[derive(Debug)] +struct R { + i:isize +} + +fn r(i:isize) -> R { R { i: i } } + +impl Drop for R { + fn drop(&mut self) {} +} + +fn main() { + // This can't make sense as it would copy the classes + let i = vec![r(0)]; + let j = vec![r(1)]; + let k = i + j; +// { dg-error ".E0369." "" { target *-*-* } .-1 } + println!("{:?}", j); +} + diff --git a/gcc/testsuite/rust/rustc/ui/vector-cast-weirdness.rs b/gcc/testsuite/rust/rustc/ui/vector-cast-weirdness.rs new file mode 100644 index 000000000000..e00a0b5e4cbe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/vector-cast-weirdness.rs @@ -0,0 +1,25 @@ +// Issue #14893. Tests that casts from vectors don't behave strangely in the +// presence of the `_` type shorthand notation. +// Update: after a change to the way casts are done, we have more type information +// around and so the errors here are no longer exactly the same. + +struct X { + y: [u8; 2], +} + +fn main() { + let x1 = X { y: [0, 0] }; + + // No longer a type mismatch - the `_` can be fully resolved by type inference. + let p1: *const u8 = &x1.y as *const _; + let t1: *const [u8; 2] = &x1.y as *const _; + let h1: *const [u8; 2] = &x1.y as *const [u8; 2]; + + let mut x1 = X { y: [0, 0] }; + + // This is still an error since we don't allow casts from &mut [T; n] to *mut T. + let p1: *mut u8 = &mut x1.y as *mut _; // { dg-error ".E0606." "" { target *-*-* } } + let t1: *mut [u8; 2] = &mut x1.y as *mut _; + let h1: *mut [u8; 2] = &mut x1.y as *mut [u8; 2]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/vector-no-ann.rs b/gcc/testsuite/rust/rustc/ui/vector-no-ann.rs new file mode 100644 index 000000000000..5f9f6466940b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/vector-no-ann.rs @@ -0,0 +1,5 @@ +fn main() { + let _foo = Vec::new(); +// { dg-error ".E0282." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/volatile-fat-ptr.rs b/gcc/testsuite/rust/rustc/ui/volatile-fat-ptr.rs new file mode 100644 index 000000000000..2c892eda5491 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/volatile-fat-ptr.rs @@ -0,0 +1,16 @@ +// run-pass + +#![allow(stable_features)] +#![feature(volatile)] +use std::ptr::{read_volatile, write_volatile}; + +fn main() { + let mut x: &'static str = "test"; + unsafe { + let a = read_volatile(&x); + assert_eq!(a, "test"); + write_volatile(&mut x, "foo"); + assert_eq!(x, "foo"); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/vtable-res-trait-param.rs b/gcc/testsuite/rust/rustc/ui/vtable-res-trait-param.rs new file mode 100644 index 000000000000..962d8b0499c8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/vtable-res-trait-param.rs @@ -0,0 +1,24 @@ +trait TraitA { + fn method_a(&self) -> isize; +} + +trait TraitB { + fn gimme_an_a(&self, a: A) -> isize; +} + +impl TraitB for isize { + fn gimme_an_a(&self, a: A) -> isize { + a.method_a() + *self + } +} + +fn call_it(b: B) -> isize { + let y = 4; + b.gimme_an_a(y) // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() { + let x = 3; + assert_eq!(call_it(x), 22); +} + diff --git a/gcc/testsuite/rust/rustc/ui/wait-forked-but-failed-child.rs b/gcc/testsuite/rust/rustc/ui/wait-forked-but-failed-child.rs new file mode 100644 index 000000000000..0a22011f05ab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wait-forked-but-failed-child.rs @@ -0,0 +1,64 @@ +// run-pass +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +// ignore-vxworks no 'ps' + +#![feature(rustc_private)] + +extern crate libc; + +use std::process::Command; + +// The output from "ps -A -o pid,ppid,args" should look like this: +// PID PPID COMMAND +// 1 0 /sbin/init +// 2 0 [kthreadd] +// ... +// 6076 9064 /bin/zsh +// ... +// 7164 6076 ./spawn-failure +// 7165 7164 [spawn-failure] +// 7166 7164 [spawn-failure] +// ... +// 7197 7164 [spawn-failure] +// 7198 7164 ps -A -o pid,ppid,command +// ... + +#[cfg(unix)] +fn find_zombies() { + let my_pid = unsafe { libc::getpid() }; + + // http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html + let ps_cmd_output = Command::new("ps").args(&["-A", "-o", "pid,ppid,args"]).output().unwrap(); + let ps_output = String::from_utf8_lossy(&ps_cmd_output.stdout); + + for (line_no, line) in ps_output.split('\n').enumerate() { + if 0 < line_no && 0 < line.len() && + my_pid == line.split(' ').filter(|w| 0 < w.len()).nth(1) + .expect("1st column should be PPID") + .parse().ok() + .expect("PPID string into integer") && + line.contains("defunct") { + panic!("Zombie child {}", line); + } + } +} + +#[cfg(windows)] +fn find_zombies() { } + +fn main() { + let too_long = format!("/NoSuchCommand{:0300}", 0u8); + + let _failures = (0..100).map(|_| { + let mut cmd = Command::new(&too_long); + let failed = cmd.spawn(); + assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd); + failed + }).collect::>(); + + find_zombies(); + // then _failures goes out of scope +} + diff --git a/gcc/testsuite/rust/rustc/ui/walk-struct-literal-with.rs b/gcc/testsuite/rust/rustc/ui/walk-struct-literal-with.rs new file mode 100644 index 000000000000..381556dfc032 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/walk-struct-literal-with.rs @@ -0,0 +1,18 @@ +struct Mine{ + test: String, + other_val: isize +} + +impl Mine{ + fn make_string_bar(mut self) -> Mine{ + self.test = "Bar".to_string(); + self + } +} + +fn main(){ + let start = Mine{test:"Foo".to_string(), other_val:0}; + let end = Mine{other_val:1, ..start.make_string_bar()}; + println!("{}", start.test); // { dg-error ".E0382." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/warn-ctypes-inhibit.rs b/gcc/testsuite/rust/rustc/ui/warn-ctypes-inhibit.rs new file mode 100644 index 000000000000..2847c408fef2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/warn-ctypes-inhibit.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(dead_code)] +// compile-flags:-D improper-ctypes + +// pretty-expanded FIXME #23616 + +#![allow(improper_ctypes)] + +mod libc { + extern { + pub fn malloc(size: isize) -> *const u8; + } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/warn-path-statement.rs b/gcc/testsuite/rust/rustc/ui/warn-path-statement.rs new file mode 100644 index 000000000000..db3f69784be6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/warn-path-statement.rs @@ -0,0 +1,18 @@ +// compile-flags: -D path-statements +struct Droppy; + +impl Drop for Droppy { + fn drop(&mut self) {} +} + +fn main() { + let x = 10; + x; // { dg-error "" "" { target *-*-* } } + + let y = Droppy; + y; // { dg-error "" "" { target *-*-* } } + + let z = (Droppy,); + z; // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/wasm-custom-section-relocations.rs b/gcc/testsuite/rust/rustc/ui/wasm-custom-section-relocations.rs new file mode 100644 index 000000000000..dcdf067c7fc9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wasm-custom-section-relocations.rs @@ -0,0 +1,16 @@ +// only-wasm32 + +#[link_section = "test"] +pub static A: &[u8] = &[1]; // { dg-error "" "" { target *-*-* } } + +#[link_section = "test"] +pub static B: [u8; 3] = [1, 2, 3]; + +#[link_section = "test"] +pub static C: usize = 3; + +#[link_section = "test"] +pub static D: &usize = &C; // { dg-error "" "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/wasm-import-module.rs b/gcc/testsuite/rust/rustc/ui/wasm-import-module.rs new file mode 100644 index 000000000000..319c42fac7a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wasm-import-module.rs @@ -0,0 +1,11 @@ +#[link(name = "...", wasm_import_module)] // { dg-error "" "" { target *-*-* } } +extern {} + +#[link(name = "...", wasm_import_module(x))] // { dg-error "" "" { target *-*-* } } +extern {} + +#[link(name = "...", wasm_import_module())] // { dg-error "" "" { target *-*-* } } +extern {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/weak-lang-item.rs b/gcc/testsuite/rust/rustc/ui/weak-lang-item.rs new file mode 100644 index 000000000000..eb70d5a2a53a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/weak-lang-item.rs @@ -0,0 +1,16 @@ +// run-pass +// aux-build:weak-lang-items.rs + +// ignore-emscripten no threads support +// pretty-expanded FIXME #23616 + +extern crate weak_lang_items as other; + +use std::thread; + +fn main() { + let _ = thread::spawn(move|| { + other::foo() + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/weak-new-uninhabited-issue-48493.rs b/gcc/testsuite/rust/rustc/ui/weak-new-uninhabited-issue-48493.rs new file mode 100644 index 000000000000..746c21361208 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/weak-new-uninhabited-issue-48493.rs @@ -0,0 +1,8 @@ +// run-pass + +fn main() { + enum Void {} + std::rc::Weak::::new(); + std::sync::Weak::::new(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/weird-exit-code.rs b/gcc/testsuite/rust/rustc/ui/weird-exit-code.rs new file mode 100644 index 000000000000..8cb155deb58a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/weird-exit-code.rs @@ -0,0 +1,29 @@ +// run-pass +// On Windows the GetExitCodeProcess API is used to get the exit code of a +// process, but it's easy to mistake a process exiting with the code 259 as +// "still running" because this is the value of the STILL_ACTIVE constant. Make +// sure we handle this case in the standard library and correctly report the +// status. +// +// Note that this is disabled on unix as processes exiting with 259 will have +// their exit status truncated to 3 (only the lower 8 bits are used). + +#[cfg(windows)] +fn main() { + use std::process::{self, Command}; + use std::env; + + if env::args().len() == 1 { + let status = Command::new(env::current_exe().unwrap()) + .arg("foo") + .status() + .unwrap(); + assert_eq!(status.code(), Some(259)); + } else { + process::exit(259); + } +} + +#[cfg(not(windows))] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/weird-exprs.rs b/gcc/testsuite/rust/rustc/ui/weird-exprs.rs new file mode 100644 index 000000000000..8d46955657b8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/weird-exprs.rs @@ -0,0 +1,181 @@ +// run-pass + +#![feature(generators)] + +#![allow(non_camel_case_types)] +#![allow(dead_code)] +#![allow(unreachable_code)] +#![allow(unused_braces, unused_must_use, unused_parens)] + +#![recursion_limit = "256"] + +use std::cell::Cell; +use std::mem::swap; + +// Just a grab bag of stuff that you wouldn't want to actually write. + +fn strange() -> bool { let _x: bool = return true; } + +fn funny() { + fn f(_x: ()) { } + f(return); +} + +fn what() { + fn the(x: &Cell) { + return while !x.get() { x.set(true); }; + } + let i = &Cell::new(false); + let dont = {||the(i)}; + dont(); + assert!((i.get())); +} + +fn zombiejesus() { + loop { + while (return) { + if (return) { + match (return) { + 1 => { + if (return) { + return + } else { + return + } + } + _ => { return } + }; + } else if (return) { + return; + } + } + if (return) { break; } + } +} + +fn notsure() { + let mut _x: isize; + let mut _y = (_x = 0) == (_x = 0); + let mut _z = (_x = 0) < (_x = 0); + let _a = (_x += 0) == (_x = 0); + let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z); +} + +fn canttouchthis() -> usize { + fn p() -> bool { true } + let _a = (assert!((true)) == (assert!(p()))); + let _c = (assert!((p())) == ()); + let _b: bool = (println!("{}", 0) == (return 0)); +} + +fn angrydome() { + loop { if break { } } + let mut i = 0; + loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } } + break; } +} + +fn evil_lincoln() { let _evil = println!("lincoln"); } + +fn dots() { + assert_eq!(String::from(".................................................."), + format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. .. + .. .. .. .. .. .. .. .. .. .. .. ..)); +} + +fn u8(u8: u8) { + if u8 != 0u8 { + assert_eq!(8u8, { + macro_rules! u8 { + (u8) => { + mod u8 { + pub fn u8<'u8: 'u8 + 'u8>(u8: &'u8 u8) -> &'u8 u8 { + "u8"; + u8 + } + } + }; + } + + u8!(u8); + let &u8: &u8 = u8::u8(&8u8); + ::u8(0u8); + u8 + }); + } +} + +fn fishy() { + assert_eq!(String::from("><>"), + String::<>::from::<>("><>").chars::<>().rev::<>().collect::()); +} + +fn union() { + union union<'union> { union: &'union union<'union>, } +} + +fn special_characters() { + let val = !((|(..):(_,_),__@_|__)((&*"\\",'🤔')/**/,{})=={&[..=..][..];})// + ; + assert!(!val); +} + +fn punch_card() -> impl std::fmt::Debug { + ..=..=.. .. .. .. .. .. .. .. .. .. .. ..=.. .. + ..=.. ..=.. .. .. .. .. .. .. .. .. ..=..=..=.. + ..=.. ..=.. ..=.. ..=.. .. ..=..=.. .. ..=.. .. + ..=..=.. .. ..=.. ..=.. ..=.. .. .. .. ..=.. .. + ..=.. ..=.. ..=.. ..=.. .. ..=.. .. .. ..=.. .. + ..=.. ..=.. ..=.. ..=.. .. .. ..=.. .. ..=.. .. + ..=.. ..=.. .. ..=..=.. ..=..=.. .. .. ..=.. .. +} + +fn r#match() { + let val = match match match match match () { + () => () + } { + () => () + } { + () => () + } { + () => () + } { + () => () + }; + assert_eq!(val, ()); +} + +fn i_yield() { + static || { + yield yield yield yield yield yield yield yield yield; + }; +} + +fn match_nested_if() { + let val = match () { + () if if if if true {true} else {false} {true} else {false} {true} else {false} => true, + _ => false, + }; + assert!(val); +} + +pub fn main() { + strange(); + funny(); + what(); + zombiejesus(); + notsure(); + canttouchthis(); + angrydome(); + evil_lincoln(); + dots(); + u8(8u8); + fishy(); + union(); + special_characters(); + punch_card(); + r#match(); + i_yield(); + match_nested_if(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/wf-bound-region-in-object-type.rs b/gcc/testsuite/rust/rustc/ui/wf-bound-region-in-object-type.rs new file mode 100644 index 000000000000..de0f2b040b2e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf-bound-region-in-object-type.rs @@ -0,0 +1,23 @@ +// run-pass + +#![allow(dead_code)] +#![allow(unused_variables)] +// Test that the `wf` checker properly handles bound regions in object +// types. Compiling this code used to trigger an ICE. + +// pretty-expanded FIXME #23616 + +pub struct Context<'tcx> { + vec: &'tcx Vec +} + +pub type Cmd<'a> = &'a isize; + +pub type DecodeInlinedItem<'a> = + Box FnMut(Cmd, &Context<'tcx>) -> Result<&'tcx isize, ()> + 'a>; + +fn foo(d: DecodeInlinedItem) { +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/issue-48638.rs b/gcc/testsuite/rust/rustc/ui/wf/issue-48638.rs new file mode 100644 index 000000000000..e380fa6f2cf2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/issue-48638.rs @@ -0,0 +1,22 @@ +// check-pass + +pub trait D {} +pub struct DT; +impl D for DT {} + +pub trait A: Sized { + type AS; +} + +pub struct As(R); + +pub struct AT; +impl A for AT { + type AS = As; +} + +#[repr(packed)] +struct S(>::AS); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-array-elem-sized.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-array-elem-sized.rs new file mode 100644 index 000000000000..dd4afa11be27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-array-elem-sized.rs @@ -0,0 +1,12 @@ +// Check that array element types must be Sized. Issue #25692. + + +#![allow(dead_code)] + +struct Foo { + foo: [[u8]], // { dg-error ".E0277." "" { target *-*-* } } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-const-type.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-const-type.rs new file mode 100644 index 000000000000..58d86148f722 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-const-type.rs @@ -0,0 +1,15 @@ +// Test that we check the types of constants are well-formed. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +struct IsCopy { t: T } +struct NotCopy; + +const FOO: IsCopy> = IsCopy { t: None }; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-convert-unsafe-trait-obj-box.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-convert-unsafe-trait-obj-box.rs new file mode 100644 index 000000000000..889a87cb4419 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-convert-unsafe-trait-obj-box.rs @@ -0,0 +1,19 @@ +// Check that we do not allow casts or coercions +// to object unsafe trait objects inside a Box + +#![feature(object_safe_for_dispatch)] + +trait Trait: Sized {} + +struct S; + +impl Trait for S {} + +fn takes_box(t: Box) {} + +fn main() { + Box::new(S) as Box; // { dg-error ".E0038." "" { target *-*-* } } + let t_box: Box = Box::new(S); // { dg-error ".E0038." "" { target *-*-* } } + takes_box(Box::new(S)); // { dg-error ".E0038." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-convert-unsafe-trait-obj.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-convert-unsafe-trait-obj.rs new file mode 100644 index 000000000000..7a939ff17a1c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-convert-unsafe-trait-obj.rs @@ -0,0 +1,19 @@ +// Check that we do not allow casts or coercions +// to object unsafe trait objects by ref + +#![feature(object_safe_for_dispatch)] + +trait Trait: Sized {} + +struct S; + +impl Trait for S {} + +fn takes_trait(t: &dyn Trait) {} + +fn main() { + &S as &dyn Trait; // { dg-error ".E0038." "" { target *-*-* } } + let t: &dyn Trait = &S; // { dg-error ".E0038." "" { target *-*-* } } + takes_trait(&S); // { dg-error ".E0038." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-enum-bound.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-enum-bound.rs new file mode 100644 index 000000000000..dd835f0fa51e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-enum-bound.rs @@ -0,0 +1,17 @@ +// Test that we check enum bounds for WFedness. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +trait ExtraCopy { } + +enum SomeEnum + where T: ExtraCopy // { dg-error ".E0277." "" { target *-*-* } } +{ + SomeVariant(T,U) +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-enum-fields-struct-variant.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-enum-fields-struct-variant.rs new file mode 100644 index 000000000000..5ed9aac3eaf5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-enum-fields-struct-variant.rs @@ -0,0 +1,19 @@ +// Test that we check struct fields for WFedness. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +struct IsCopy { + value: T +} + +enum AnotherEnum { + AnotherVariant { + f: IsCopy // { dg-error ".E0277." "" { target *-*-* } } + } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-enum-fields.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-enum-fields.rs new file mode 100644 index 000000000000..6c61ff8a23fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-enum-fields.rs @@ -0,0 +1,17 @@ +// Test that we check struct fields for WFedness. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +struct IsCopy { + value: T +} + +enum SomeEnum { + SomeVariant(IsCopy) // { dg-error ".E0277." "" { target *-*-* } } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-fn-where-clause.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-fn-where-clause.rs new file mode 100644 index 000000000000..232d31011ea3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-fn-where-clause.rs @@ -0,0 +1,21 @@ +// Test that we check where-clauses on fn items. + + +#![allow(dead_code)] + +trait ExtraCopy { } + +fn foo() where T: ExtraCopy // { dg-error ".E0277." "" { target *-*-* } } +{ +} + +fn bar() where Vec:, {} +// { dg-error ".E0038." "" { target *-*-* } .-1 } +// { dg-error ".E0038." "" { target *-*-* } .-2 } + +struct Vec { + t: T, +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-foreign-fn-decl-ret.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-foreign-fn-decl-ret.rs new file mode 100644 index 000000000000..7219136e7dd4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-foreign-fn-decl-ret.rs @@ -0,0 +1,19 @@ +pub trait Unsatisfied {} + +#[repr(transparent)] +pub struct Bar(T); + +pub trait Foo { + type Assoc; +} + +extern "C" { + pub fn lint_me() -> <() as Foo>::Assoc; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + pub fn lint_me_aswell() -> Bar; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-impl-associated-type-region.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-impl-associated-type-region.rs new file mode 100644 index 000000000000..2333a7c5a924 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-impl-associated-type-region.rs @@ -0,0 +1,15 @@ +// Check that we require that associated types in an impl are well-formed. + + + +pub trait Foo<'a> { + type Bar; +} + +impl<'a, T> Foo<'a> for T { + type Bar = &'a T; // { dg-error ".E0309." "" { target *-*-* } } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-impl-associated-type-trait.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-impl-associated-type-trait.rs new file mode 100644 index 000000000000..4f961f5f3919 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-impl-associated-type-trait.rs @@ -0,0 +1,23 @@ +// Check that we require that associated types in an impl are well-formed. + + +#![allow(dead_code)] + +pub trait MyHash { } + +pub struct MySet { + data: Vec +} + +pub trait Foo { + type Bar; +} + +impl Foo for T { + type Bar = MySet; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-impl-self-type.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-impl-self-type.rs new file mode 100644 index 000000000000..8398e346ab99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-impl-self-type.rs @@ -0,0 +1,8 @@ +// Tests that we point at the proper location for an error +// involving the self-type of an impl + +trait Foo {} +impl Foo for Option<[u8]> {} // { dg-error ".E0277." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-arg.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-arg.rs new file mode 100644 index 000000000000..53c7c3227d21 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-arg.rs @@ -0,0 +1,15 @@ +// Check that we enforce WF conditions also for argument types in fn items. + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +struct MustBeCopy { + t: T +} + +fn bar(_: &MustBeCopy) // { dg-error ".E0277." "" { target *-*-* } } +{ +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-ret.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-ret.rs new file mode 100644 index 000000000000..1919cc0a7bf6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-ret.rs @@ -0,0 +1,15 @@ +// Check that we enforce WF conditions also for return types in fn items. + +#![feature(rustc_attrs)] +#![allow(dead_code)] + +struct MustBeCopy { + t: T +} + +fn bar() -> MustBeCopy // { dg-error ".E0277." "" { target *-*-* } } +{ +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-type-arg.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-type-arg.rs new file mode 100644 index 000000000000..4fe63d4a8db5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-type-arg.rs @@ -0,0 +1,13 @@ +// Check that we enforce WF conditions also for types in fns. + +struct MustBeCopy { + t: T +} + +struct Bar { + // needs T: Copy + x: fn(MustBeCopy) // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-type-ret.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-type-ret.rs new file mode 100644 index 000000000000..dd8434455e45 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-type-ret.rs @@ -0,0 +1,13 @@ +// Check that we enforce WF conditions also for types in fns. + +struct MustBeCopy { + t: T +} + +struct Foo { + // needs T: 'static + x: fn() -> MustBeCopy // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-type-static.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-type-static.rs new file mode 100644 index 000000000000..a864432199e0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-type-static.rs @@ -0,0 +1,23 @@ +// Check that we enforce WF conditions related to regions also for +// types in fns. + +#![allow(dead_code)] + + +struct MustBeCopy { + t: T +} + +struct Foo { + // needs T: 'static + x: fn() -> &'static T // { dg-error ".E0310." "" { target *-*-* } } +} + +struct Bar { + // needs T: Copy + x: fn(&'static T) // { dg-error ".E0310." "" { target *-*-* } } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-where-clause.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-where-clause.rs new file mode 100644 index 000000000000..9ec4f3b35da8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-in-fn-where-clause.rs @@ -0,0 +1,16 @@ +// Check that we enforce WF conditions also for where clauses in fn items. + + +#![allow(dead_code)] + +trait MustBeCopy { +} + +fn bar() + where T: MustBeCopy // { dg-error ".E0277." "" { target *-*-* } } +{ +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-in-obj-type-static.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-in-obj-type-static.rs new file mode 100644 index 000000000000..4739a38f5b38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-in-obj-type-static.rs @@ -0,0 +1,19 @@ +// Check that we enforce WF conditions also for types in fns. + + +#![allow(dead_code)] + +trait Object { } + +struct MustBeCopy { + t: T +} + +struct Foo { + // needs T: 'static + x: dyn Object<&'static T> // { dg-error ".E0310." "" { target *-*-* } } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-in-obj-type-trait.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-in-obj-type-trait.rs new file mode 100644 index 000000000000..4eb857ffb350 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-in-obj-type-trait.rs @@ -0,0 +1,15 @@ +// Check that we enforce WF conditions also for types in fns. + +trait Object { } + +struct MustBeCopy { + t: T +} + +struct Bar { + // needs T: Copy + x: dyn Object> // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-inherent-impl-method-where-clause.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-inherent-impl-method-where-clause.rs new file mode 100644 index 000000000000..caac882d3b8c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-inherent-impl-method-where-clause.rs @@ -0,0 +1,18 @@ +// Test that we check where-clauses on inherent impl methods. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +trait ExtraCopy { } + +struct Foo(T,U); + +impl Foo { + fn foo(self) where T: ExtraCopy // { dg-error ".E0277." "" { target *-*-* } } + {} +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-inherent-impl-where-clause.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-inherent-impl-where-clause.rs new file mode 100644 index 000000000000..baf8bc1d58fb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-inherent-impl-where-clause.rs @@ -0,0 +1,17 @@ +// Test that we check where-clauses on inherent impls. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +trait ExtraCopy { } + +struct Foo(T,U); + +impl Foo where T: ExtraCopy // { dg-error ".E0277." "" { target *-*-* } } +{ +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-misc-methods-issue-28609.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-misc-methods-issue-28609.rs new file mode 100644 index 000000000000..c7a447d9c7eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-misc-methods-issue-28609.rs @@ -0,0 +1,75 @@ +// check that misc. method calls are well-formed + +use std::marker::PhantomData; +use std::ops::{Deref, Shl}; + +#[derive(Copy, Clone)] +struct S<'a, 'b: 'a> { + marker: PhantomData<&'a &'b ()>, + bomb: Option<&'b u32> +} + +type S2<'a> = S<'a, 'a>; + +impl<'a, 'b> S<'a, 'b> { + fn transmute_inherent(&self, a: &'b u32) -> &'a u32 { + a + } +} + +fn return_dangling_pointer_inherent(s: S2) -> &u32 { + let s = s; + s.transmute_inherent(&mut 42) // { dg-error ".E0515." "" { target *-*-* } } +} + +impl<'a, 'b> Deref for S<'a, 'b> { + type Target = &'a u32; + fn deref(&self) -> &&'a u32 { + self.bomb.as_ref().unwrap() + } +} + +fn return_dangling_pointer_coerce(s: S2) -> &u32 { + let four = 4; + let mut s = s; + s.bomb = Some(&four); + &s // { dg-error ".E0515." "" { target *-*-* } } +} + +fn return_dangling_pointer_unary_op(s: S2) -> &u32 { + let four = 4; + let mut s = s; + s.bomb = Some(&four); + &*s // { dg-error ".E0515." "" { target *-*-* } } +} + +impl<'a, 'b> Shl<&'b u32> for S<'a, 'b> { + type Output = &'a u32; + fn shl(self, t: &'b u32) -> &'a u32 { t } +} + +fn return_dangling_pointer_binary_op(s: S2) -> &u32 { + let s = s; + s << &mut 3 // { dg-error ".E0515." "" { target *-*-* } } +} + +fn return_dangling_pointer_method(s: S2) -> &u32 { + let s = s; + s.shl(&mut 3) // { dg-error ".E0515." "" { target *-*-* } } +} + +fn return_dangling_pointer_ufcs(s: S2) -> &u32 { + let s = s; + S2::shl(s, &mut 3) // { dg-error ".E0515." "" { target *-*-* } } +} + +fn main() { + let s = S { marker: PhantomData, bomb: None }; + let _inherent_dp = return_dangling_pointer_inherent(s); + let _coerce_dp = return_dangling_pointer_coerce(s); + let _unary_dp = return_dangling_pointer_unary_op(s); + let _binary_dp = return_dangling_pointer_binary_op(s); + let _method_dp = return_dangling_pointer_method(s); + let _ufcs_dp = return_dangling_pointer_ufcs(s); +} + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-object-safe.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-object-safe.rs new file mode 100644 index 000000000000..156d7b0af054 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-object-safe.rs @@ -0,0 +1,11 @@ +// Check that object-safe traits are not WF when used as object types. +// Issue #21953. + +trait A { + fn foo(&self, _x: &Self); +} + +fn main() { + let _x: &dyn A; // { dg-error ".E0038." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-outlives-ty-in-fn-or-trait.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-outlives-ty-in-fn-or-trait.rs new file mode 100644 index 000000000000..155c5388a479 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-outlives-ty-in-fn-or-trait.rs @@ -0,0 +1,23 @@ +#![feature(rustc_attrs)] +#![allow(dead_code)] + +trait Trait<'a, T> { + type Out; +} + +impl<'a, T> Trait<'a, T> for usize { + type Out = &'a fn(T); // { dg-error ".E0309." "" { target *-*-* } } +} + +struct Foo<'a,T> { + f: &'a fn(T), +} + +trait Baz { } + +impl<'a, T> Trait<'a, T> for u32 { + type Out = &'a dyn Baz; // { dg-error ".E0309." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.rs new file mode 100644 index 000000000000..9c9009709ab3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-packed-on-proj-of-type-as-unimpl-trait.rs @@ -0,0 +1,32 @@ +// rust-lang/rust#58158: We have special-case code to deal with case +// when a type is both packed and needs drop glue, (we move the fields +// out of their potentially unaligned locations before dropping them, +// which requires they be Sized; see PR #44884). +// +// So, we need to check if a given type needs drop-glue. That requires +// that we actually know that the concrete type, and we guard against +// the type having unknown parts (i.e. type variables) by ICE'ing in +// that scenario. +// +// But in a case where we have a projection (`Type as Trait::Assoc`) +// where `Type` does not actually implement `Trait`, we of course +// cannot have a concrete type, because there is no impl to look up +// the concrete type for the associated type `Assoc`. +// +// So, this test is just making sure that in such a case that we do +// not immediately ICE, and instead allow the underlying type error to +// surface. + +pub struct Matrix(S); +pub struct DefaultAllocator; + +pub trait Allocator { type Buffer; } + +// impl Allocator for DefaultAllocator { type Buffer = (); } + +#[repr(packed)] +struct Foo(Matrix<::Buffer>); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-static-method.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-static-method.rs new file mode 100644 index 000000000000..0b6de38c1a8b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-static-method.rs @@ -0,0 +1,55 @@ +// check that static methods don't get to assume their trait-ref +// is well-formed. +// FIXME(#27579): this is just a bug. However, our checking with +// static inherent methods isn't quite working - need to +// fix that before removing the check. + +trait Foo<'a, 'b, T>: Sized { + fn make_me() -> Self { loop {} } + fn static_evil(u: &'b u32) -> &'a u32; +} + +struct Evil<'a, 'b: 'a>(Option<&'a &'b ()>); + +impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () { + fn make_me() -> Self { } + fn static_evil(u: &'b u32) -> &'a u32 { + u // { dg-error ".E0312." "" { target *-*-* } } + } +} + +struct IndirectEvil<'a, 'b: 'a>(Option<&'a &'b ()>); + +impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> { + fn make_me() -> Self { IndirectEvil(None) } + fn static_evil(u: &'b u32) -> &'a u32 { + let me = Self::make_me(); // { dg-error ".E0478." "" { target *-*-* } } + loop {} // (`me` could be used for the lifetime transmute). + } +} + +impl<'a, 'b> Evil<'a, 'b> { + fn inherent_evil(u: &'b u32) -> &'a u32 { + u // { dg-error ".E0312." "" { target *-*-* } } + } +} + +// while static methods don't get to *assume* this, we still +// *check* that they hold. + +fn evil<'a, 'b>(b: &'b u32) -> &'a u32 { + <()>::static_evil(b) // { dg-error ".E0495." "" { target *-*-* } } +} + +fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 { + ::static_evil(b) +// { dg-error ".E0495." "" { target *-*-* } .-1 } +} + +fn inherent_evil<'a, 'b>(b: &'b u32) -> &'a u32 { + ::inherent_evil(b) // bug? shouldn't this be an error +} + + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-static-type.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-static-type.rs new file mode 100644 index 000000000000..937ebcc0af2c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-static-type.rs @@ -0,0 +1,15 @@ +// Test that we check the types of statics are well-formed. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +struct IsCopy { t: T } +struct NotCopy; + +static FOO: IsCopy> = IsCopy { t: None }; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-struct-bound.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-struct-bound.rs new file mode 100644 index 000000000000..275919919cf7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-struct-bound.rs @@ -0,0 +1,17 @@ +// Test that we check struct bounds for WFedness. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +trait ExtraCopy { } + +struct SomeStruct + where T: ExtraCopy // { dg-error ".E0277." "" { target *-*-* } } +{ + data: (T,U) +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-struct-field.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-struct-field.rs new file mode 100644 index 000000000000..14568fd04cae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-struct-field.rs @@ -0,0 +1,17 @@ +// Test that we check struct fields for WFedness. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +struct IsCopy { + value: T +} + +struct SomeStruct { + data: IsCopy // { dg-error ".E0277." "" { target *-*-* } } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-trait-associated-type-bound.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-associated-type-bound.rs new file mode 100644 index 000000000000..8f826ea8f5e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-associated-type-bound.rs @@ -0,0 +1,15 @@ +// Test that we check associated type bounds for WFedness. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +trait ExtraCopy { } + +trait SomeTrait { + type Type1: ExtraCopy; // { dg-error ".E0277." "" { target *-*-* } } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-trait-associated-type-region.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-associated-type-region.rs new file mode 100644 index 000000000000..3d5e178e0e96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-associated-type-region.rs @@ -0,0 +1,15 @@ +// Test that we check associated type default values for WFedness. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +trait SomeTrait<'a> { + type Type1; + type Type2 = &'a Self::Type1; +// { dg-error ".E0309." "" { target *-*-* } .-1 } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-trait-associated-type-trait.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-associated-type-trait.rs new file mode 100644 index 000000000000..904600f937d9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-associated-type-trait.rs @@ -0,0 +1,17 @@ +// Test that we check associated type default values for WFedness. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +struct IsCopy { x: T } + +trait SomeTrait { + type Type1; + type Type2 = IsCopy; +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-trait-bound.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-bound.rs new file mode 100644 index 000000000000..c5e6b7ee26cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-bound.rs @@ -0,0 +1,16 @@ +// Test that we check supertrait bounds for WFedness. + +#![feature(associated_type_defaults)] + +#![allow(dead_code)] + +trait ExtraCopy { } + +trait SomeTrait + where T: ExtraCopy // { dg-error ".E0277." "" { target *-*-* } } +{ +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-trait-default-fn-arg.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-default-fn-arg.rs new file mode 100644 index 000000000000..ca049ead9ae5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-default-fn-arg.rs @@ -0,0 +1,20 @@ +// Check that we test WF conditions for fn arguments. Because the +// current code is so goofy, this is only a warning for now. + + +#![allow(dead_code)] +#![allow(unused_variables)] + +struct Bar { value: Box } + +trait Foo { + fn bar(&self, x: &Bar) { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + // + // Here, Eq ought to be implemented. + } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-trait-default-fn-ret.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-default-fn-ret.rs new file mode 100644 index 000000000000..5a81f572d507 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-default-fn-ret.rs @@ -0,0 +1,20 @@ +// Check that we test WF conditions for fn arguments. Because the +// current code is so goofy, this is only a warning for now. + +#![feature(rustc_attrs)] +#![allow(dead_code)] +#![allow(unused_variables)] + +struct Bar { value: Box } + +trait Foo { + fn bar(&self) -> Bar { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + // + // Here, Eq ought to be implemented. + loop { } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-trait-default-fn-where-clause.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-default-fn-where-clause.rs new file mode 100644 index 000000000000..653ddbb26b52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-default-fn-where-clause.rs @@ -0,0 +1,20 @@ +// Check that we test WF conditions for fn arguments. Because the +// current code is so goofy, this is only a warning for now. + + +#![allow(dead_code)] +#![allow(unused_variables)] + +trait Bar { } + +trait Foo { + fn bar(&self) where A: Bar { +// { dg-error ".E0277." "" { target *-*-* } .-1 } + // + // Here, Eq ought to be implemented. + } +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-trait-fn-arg.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-fn-arg.rs new file mode 100644 index 000000000000..3d1706c4bc01 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-fn-arg.rs @@ -0,0 +1,17 @@ +// Check that we test WF conditions for fn arguments in a trait definition. + +#![feature(rustc_attrs)] +#![allow(dead_code)] +#![allow(unused_variables)] + +struct Bar { value: Box } + +trait Foo { + fn bar(&self, x: &Bar); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + // + // Here, Eq ought to be implemented. +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-trait-fn-ret.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-fn-ret.rs new file mode 100644 index 000000000000..854e911dca1b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-fn-ret.rs @@ -0,0 +1,17 @@ +// Check that we test WF conditions for fn return types in a trait definition. + +#![feature(rustc_attrs)] +#![allow(dead_code)] +#![allow(unused_variables)] + +struct Bar { value: Box } + +trait Foo { + fn bar(&self) -> &Bar; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + // + // Here, Eq ought to be implemented. +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-trait-fn-where-clause.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-fn-where-clause.rs new file mode 100644 index 000000000000..c3cc0da81ad9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-fn-where-clause.rs @@ -0,0 +1,18 @@ +// Check that we test WF conditions for fn where clauses in a trait definition. + + +#![allow(dead_code)] +#![allow(unused_variables)] + +struct Bar { value: Box } + +trait Foo { + fn bar(&self) where Self: Sized, Bar: Copy; +// { dg-error ".E0277." "" { target *-*-* } .-1 } + // + // Here, Eq ought to be implemented. +} + + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-trait-superbound.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-superbound.rs new file mode 100644 index 000000000000..6418c04ae47f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-trait-superbound.rs @@ -0,0 +1,13 @@ +// Test that we check supertrait bounds for WFedness. + +#![feature(associated_type_defaults)] +#![feature(rustc_attrs)] +#![allow(dead_code)] + +trait ExtraCopy { } + +trait SomeTrait: ExtraCopy { // { dg-error ".E0277." "" { target *-*-* } } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/wf/wf-unsafe-trait-obj-match.rs b/gcc/testsuite/rust/rustc/ui/wf/wf-unsafe-trait-obj-match.rs new file mode 100644 index 000000000000..13a43d897615 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wf/wf-unsafe-trait-obj-match.rs @@ -0,0 +1,30 @@ +// Check that we do not allow coercions to object +// unsafe trait objects in match arms + +#![feature(object_safe_for_dispatch)] + +trait Trait: Sized {} + +struct S; + +impl Trait for S {} + +struct R; + +impl Trait for R {} + +fn opt() -> Option<()> { + Some(()) +} + +fn main() { + match opt() { + Some(()) => &S, + None => &R, // { dg-error ".E0308." "" { target *-*-* } } + } + let t: &dyn Trait = match opt() { // { dg-error ".E0038." "" { target *-*-* } } + Some(()) => &S, // { dg-error ".E0038." "" { target *-*-* } } + None => &R, + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/auxiliary/where_clauses_xc.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/auxiliary/where_clauses_xc.rs new file mode 100644 index 000000000000..3deef38b3c40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/auxiliary/where_clauses_xc.rs @@ -0,0 +1,20 @@ +pub trait Equal { + fn equal(&self, other: &Self) -> bool; + fn equals(&self, this: &T, that: &T, x: &U, y: &U) -> bool + where T: Eq, U: Eq; +} + +impl Equal for T where T: Eq { + fn equal(&self, other: &T) -> bool { + self == other + } + fn equals(&self, this: &U, other: &U, x: &X, y: &X) -> bool + where U: Eq, X: Eq { + this == other && x == y + } +} + +pub fn equal(x: &T, y: &T) -> bool where T: Eq { + x == y +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-bounds-inconsistency.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-bounds-inconsistency.rs new file mode 100644 index 000000000000..b62df880870c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-bounds-inconsistency.rs @@ -0,0 +1,24 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait Bound { + fn dummy(&self) { } +} + +trait Trait { + fn a(&self, _: T) where T: Bound; + fn b(&self, _: T) where T: Bound; + fn c(&self, _: T); + fn d(&self, _: T); +} + +impl Trait for bool { + fn a(&self, _: T) {} + //^~ This gets rejected but should be accepted + fn b(&self, _: T) where T: Bound {} + fn c(&self, _: T) {} + fn d(&self, _: T) where T: Bound {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.rs new file mode 100644 index 000000000000..48833ede285c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.rs @@ -0,0 +1,19 @@ +fn require_copy(x: T) {} + +struct Foo { x: T } + +// Ensure constraints are only attached to methods locally +impl Foo { + fn needs_copy(self) where T: Copy { + require_copy(self.x); + + } + + fn fails_copy(self) { + require_copy(self.x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.rs new file mode 100644 index 000000000000..b12fae44dcbf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.rs @@ -0,0 +1,24 @@ +fn require_copy(x: T) {} + +struct Bar { x: T } + +trait Foo { + fn needs_copy(self) where T: Copy; + fn fails_copy(self); +} + +// Ensure constraints are only attached to methods locally +impl Foo for Bar { + fn needs_copy(self) where T: Copy { + require_copy(self.x); + + } + + fn fails_copy(self) { + require_copy(self.x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-early-bound-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-early-bound-lifetimes.rs new file mode 100644 index 000000000000..7c4ceab29ce3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-early-bound-lifetimes.rs @@ -0,0 +1,19 @@ +// run-pass +#![allow(non_upper_case_globals)] + +// pretty-expanded FIXME #23616 + +trait TheTrait { fn dummy(&self) { } } + +impl TheTrait for &'static isize { } + +fn foo<'a,T>(_: &'a T) where &'a T : TheTrait { } + +fn bar(_: &'static T) where &'static T : TheTrait { } + +fn main() { + static x: isize = 1; + foo(&x); + bar(&x); +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-method-substituion-rpass.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-method-substituion-rpass.rs new file mode 100644 index 000000000000..c074c4ecff5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-method-substituion-rpass.rs @@ -0,0 +1,24 @@ +// run-pass +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +trait Foo { fn dummy(&self, arg: T) { } } + +trait Bar { + fn method(&self) where A: Foo; +} + +struct S; +struct X; + +impl Foo for X {} + +impl Bar for i32 { + fn method(&self) where X: Foo { + } +} + +fn main() { + 1.method::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-method-substituion.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-method-substituion.rs new file mode 100644 index 000000000000..5e0c841f59b0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-method-substituion.rs @@ -0,0 +1,23 @@ +trait Foo { + fn dummy(&self, t: T) { } +} + +trait Bar { + fn method(&self) where A: Foo; +} + +struct S; +struct X; + +// Remove this impl causing the below resolution to fail // impl Foo for X {} + +impl Bar for isize { + fn method(&self) where X: Foo { + } +} + +fn main() { + 1.method::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-region-outlives.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-region-outlives.rs new file mode 100644 index 000000000000..3b685eb860dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clause-region-outlives.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +struct A<'a, 'b> where 'a : 'b { x: &'a isize, y: &'b isize } + +fn main() { + let x = 1; + let y = 1; + let a = A { x: &x, y: &y }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-cross-crate.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-cross-crate.rs new file mode 100644 index 000000000000..ce377dadb0dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-cross-crate.rs @@ -0,0 +1,14 @@ +// run-pass +// aux-build:where_clauses_xc.rs + +extern crate where_clauses_xc; + +use where_clauses_xc::{Equal, equal}; + +fn main() { + println!("{}", equal(&1, &2)); + println!("{}", equal(&1, &1)); + println!("{}", "hello".equal(&"hello")); + println!("{}", "hello".equals::(&1, &1, &"foo", &"bar")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-lifetimes.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-lifetimes.rs new file mode 100644 index 000000000000..868a8fe1a289 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-lifetimes.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_mut)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +fn foo<'a, I>(mut it: I) where I: Iterator {} + +fn main() { + foo([1, 2].iter()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-method-unsatisfied.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-method-unsatisfied.rs new file mode 100644 index 000000000000..25cb6f26c8c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-method-unsatisfied.rs @@ -0,0 +1,21 @@ +// Test that a where clause attached to a method allows us to add +// additional constraints to a parameter out of scope. + +struct Foo { + value: T +} + +struct Bar; // does not implement Eq + +impl Foo { + fn equals(&self, u: &Foo) -> bool where T : Eq { + self.value == u.value + } +} + +fn main() { + let x = Foo { value: Bar }; + x.equals(&x); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-method.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-method.rs new file mode 100644 index 000000000000..936f765ad6b4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-method.rs @@ -0,0 +1,21 @@ +// run-pass +// Test that a where clause attached to a method allows us to add +// additional constraints to a parameter out of scope. + +struct Foo { + value: T +} + +impl Foo { + fn equals(&self, u: &Foo) -> bool where T : Eq { + self.value == u.value + } +} + +fn main() { + let x = Foo { value: 1 }; + let y = Foo { value: 2 }; + println!("{}", x.equals(&x)); + println!("{}", x.equals(&y)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-unboxed-closures.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-unboxed-closures.rs new file mode 100644 index 000000000000..bdc37d899cf3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-unboxed-closures.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +struct Bencher; + +// ICE +fn warm_up<'a, F>(f: F) where F: Fn(&'a mut Bencher) { +} + +fn main() { + // ICE trigger + warm_up(|b: &mut Bencher| () ); + + // OK + warm_up(|b| () ); +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-unsatisfied.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-unsatisfied.rs new file mode 100644 index 000000000000..49036f336246 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses-unsatisfied.rs @@ -0,0 +1,9 @@ +fn equal(a: &T, b: &T) -> bool where T : Eq { a == b } + +struct Struct; + +fn main() { + drop(equal(&Struct, &Struct)) +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses.rs new file mode 100644 index 000000000000..babd28462009 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-clauses.rs @@ -0,0 +1,28 @@ +// run-pass +trait Equal { + fn equal(&self, other: &Self) -> bool; + fn equals(&self, this: &T, that: &T, x: &U, y: &U) -> bool + where T: Eq, U: Eq; +} + +impl Equal for T where T: Eq { + fn equal(&self, other: &T) -> bool { + self == other + } + fn equals(&self, this: &U, other: &U, x: &X, y: &X) -> bool + where U: Eq, X: Eq { + this == other && x == y + } +} + +fn equal(x: &T, y: &T) -> bool where T: Eq { + x == y +} + +fn main() { + println!("{}", equal(&1, &2)); + println!("{}", equal(&1, &1)); + println!("{}", "hello".equal(&"hello")); + println!("{}", "hello".equals::(&1, &1, &"foo", &"bar")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-equality-constraints.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-equality-constraints.rs new file mode 100644 index 000000000000..1c02e0b15c50 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-equality-constraints.rs @@ -0,0 +1,7 @@ +fn f() where u8 = u16 {} +// { dg-error "" "" { target *-*-* } .-1 } +fn g() where for<'a> &'static (u8,) == u16, {} +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-for-self-2.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-for-self-2.rs new file mode 100644 index 000000000000..82c6a2288bb1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-for-self-2.rs @@ -0,0 +1,25 @@ +// Test that we can quantify lifetimes outside a constraint (i.e., including +// the self type) in a where clause. Specifically, test that implementing for a +// specific lifetime is not enough to satisfy the `for<'a> ...` constraint, which +// should require *all* lifetimes. + +static X: &'static u32 = &42; + +trait Bar { + fn bar(&self); +} + +impl Bar for &'static u32 { + fn bar(&self) {} +} + +fn foo(x: &T) +where + for<'a> &'a T: Bar, +{ +} + +fn main() { + foo(&X); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-for-self.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-for-self.rs new file mode 100644 index 000000000000..301053be1e3f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-for-self.rs @@ -0,0 +1,20 @@ +// Test that we can quantify lifetimes outside a constraint (i.e., including +// the self type) in a where clause. Specifically, test that we cannot nest +// quantification in constraints (to be clear, there is no reason this should not +// we're testing we don't crash or do something stupid). + +trait Bar<'a> { + fn bar(&self); +} + +impl<'a, 'b> Bar<'b> for &'a u32 { + fn bar(&self) {} +} + +fn foo(x: &T) + where for<'a> &'a T: for<'b> Bar<'b> +// { dg-error ".E0316." "" { target *-*-* } .-1 } +{} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/where-clauses/where-lifetime-resolution.rs b/gcc/testsuite/rust/rustc/ui/where-clauses/where-lifetime-resolution.rs new file mode 100644 index 000000000000..4e0d8787cda3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/where-clauses/where-lifetime-resolution.rs @@ -0,0 +1,13 @@ +trait Trait1<'a> {} +trait Trait2<'a, 'b> {} + +fn f() where + for<'a> dyn Trait1<'a>: Trait1<'a>, // OK + (dyn for<'a> Trait1<'a>): Trait1<'a>, +// { dg-error ".E0261." "" { target *-*-* } .-1 } + for<'a> dyn for<'b> Trait2<'a, 'b>: Trait2<'a, 'b>, +// { dg-error ".E0261." "" { target *-*-* } .-1 } +{} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/while-let.rs b/gcc/testsuite/rust/rustc/ui/while-let.rs new file mode 100644 index 000000000000..7a266309f7bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/while-let.rs @@ -0,0 +1,32 @@ +// run-pass + +#[allow(dead_code)] +fn macros() { + macro_rules! foo{ + ($p:pat, $e:expr, $b:block) => {{ + while let $p = $e $b +// { dg-warning "" "" { target *-*-* } .-1 } +// { dg-warning "" "" { target *-*-* } .-2 } + }} + } + macro_rules! bar{ + ($p:pat, $e:expr, $b:block) => {{ + foo!($p, $e, $b) + }} + } + + foo!(_a, 1, { + println!("irrefutable pattern"); + }); + bar!(_a, 1, { + println!("irrefutable pattern"); + }); +} + +pub fn main() { + while let _a = 1 { // { dg-warning "" "" { target *-*-* } } + println!("irrefutable pattern"); + break; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/while-type-error.rs b/gcc/testsuite/rust/rustc/ui/while-type-error.rs new file mode 100644 index 000000000000..3ee7dae0cca2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/while-type-error.rs @@ -0,0 +1,4 @@ +// error-pattern: mismatched types + +fn main() { while main { } } + diff --git a/gcc/testsuite/rust/rustc/ui/windows-subsystem-invalid.rs b/gcc/testsuite/rust/rustc/ui/windows-subsystem-invalid.rs new file mode 100644 index 000000000000..a46e2170ee77 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/windows-subsystem-invalid.rs @@ -0,0 +1,6 @@ +// error-pattern: invalid windows subsystem `wrong`, only `windows` and `console` are allowed + +#![windows_subsystem = "wrong"] + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/wrapping-int-api.rs b/gcc/testsuite/rust/rustc/ui/wrapping-int-api.rs new file mode 100644 index 000000000000..f4192c83ccce --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wrapping-int-api.rs @@ -0,0 +1,229 @@ +// run-pass +// Test inherent wrapping_* methods for {i,u}{size,8,16,32,64}. + +// Don't warn about overflowing ops on 32-bit platforms +#![cfg_attr(target_pointer_width = "32", allow(const_err))] + +use std::{i8, i16, i32, i64, isize}; +use std::{u8, u16, u32, u64, usize}; + +fn main() { + assert_eq!( i8::MAX.wrapping_add(1), i8::MIN); + assert_eq!( i16::MAX.wrapping_add(1), i16::MIN); + assert_eq!( i32::MAX.wrapping_add(1), i32::MIN); + assert_eq!( i64::MAX.wrapping_add(1), i64::MIN); + assert_eq!(isize::MAX.wrapping_add(1), isize::MIN); + + assert_eq!( i8::MIN.wrapping_sub(1), i8::MAX); + assert_eq!( i16::MIN.wrapping_sub(1), i16::MAX); + assert_eq!( i32::MIN.wrapping_sub(1), i32::MAX); + assert_eq!( i64::MIN.wrapping_sub(1), i64::MAX); + assert_eq!(isize::MIN.wrapping_sub(1), isize::MAX); + + assert_eq!( u8::MAX.wrapping_add(1), u8::MIN); + assert_eq!( u16::MAX.wrapping_add(1), u16::MIN); + assert_eq!( u32::MAX.wrapping_add(1), u32::MIN); + assert_eq!( u64::MAX.wrapping_add(1), u64::MIN); + assert_eq!(usize::MAX.wrapping_add(1), usize::MIN); + + assert_eq!( u8::MIN.wrapping_sub(1), u8::MAX); + assert_eq!( u16::MIN.wrapping_sub(1), u16::MAX); + assert_eq!( u32::MIN.wrapping_sub(1), u32::MAX); + assert_eq!( u64::MIN.wrapping_sub(1), u64::MAX); + assert_eq!(usize::MIN.wrapping_sub(1), usize::MAX); + + assert_eq!((0xfe_u8 as i8).wrapping_mul(16), + (0xe0_u8 as i8)); + assert_eq!((0xfedc_u16 as i16).wrapping_mul(16), + (0xedc0_u16 as i16)); + assert_eq!((0xfedc_ba98_u32 as i32).wrapping_mul(16), + (0xedcb_a980_u32 as i32)); + assert_eq!((0xfedc_ba98_7654_3217_u64 as i64).wrapping_mul(16), + (0xedcb_a987_6543_2170_u64 as i64)); + + match () { + #[cfg(target_pointer_width = "32")] + () => { + assert_eq!((0xfedc_ba98_u32 as isize).wrapping_mul(16), + (0xedcb_a980_u32 as isize)); + } + #[cfg(target_pointer_width = "64")] + () => { + assert_eq!((0xfedc_ba98_7654_3217_u64 as isize).wrapping_mul(16), + (0xedcb_a987_6543_2170_u64 as isize)); + } + } + + assert_eq!((0xfe as u8).wrapping_mul(16), + (0xe0 as u8)); + assert_eq!((0xfedc as u16).wrapping_mul(16), + (0xedc0 as u16)); + assert_eq!((0xfedc_ba98 as u32).wrapping_mul(16), + (0xedcb_a980 as u32)); + assert_eq!((0xfedc_ba98_7654_3217 as u64).wrapping_mul(16), + (0xedcb_a987_6543_2170 as u64)); + + match () { + #[cfg(target_pointer_width = "32")] + () => { + assert_eq!((0xfedc_ba98 as usize).wrapping_mul(16), + (0xedcb_a980 as usize)); + } + #[cfg(target_pointer_width = "64")] + () => { + assert_eq!((0xfedc_ba98_7654_3217 as usize).wrapping_mul(16), + (0xedcb_a987_6543_2170 as usize)); + } + } + + macro_rules! check_mul_no_wrap { + ($e:expr, $f:expr) => { assert_eq!(($e).wrapping_mul($f), ($e) * $f); } + } + macro_rules! check_mul_wraps { + ($e:expr, $f:expr) => { assert_eq!(($e).wrapping_mul($f), $e); } + } + + check_mul_no_wrap!(0xfe_u8 as i8, -1); + check_mul_no_wrap!(0xfedc_u16 as i16, -1); + check_mul_no_wrap!(0xfedc_ba98_u32 as i32, -1); + check_mul_no_wrap!(0xfedc_ba98_7654_3217_u64 as i64, -1); + check_mul_no_wrap!(0xfedc_ba98_7654_3217_u64 as u64 as isize, -1); + + check_mul_no_wrap!(0xfe_u8 as i8, -2); + check_mul_no_wrap!(0xfedc_u16 as i16, -2); + check_mul_no_wrap!(0xfedc_ba98_u32 as i32, -2); + check_mul_no_wrap!(0xfedc_ba98_7654_3217_u64 as i64, -2); + check_mul_no_wrap!(0xfedc_ba98_fedc_ba98_u64 as u64 as isize, -2); + + check_mul_no_wrap!(0xfe_u8 as i8, 2); + check_mul_no_wrap!(0xfedc_u16 as i16, 2); + check_mul_no_wrap!(0xfedc_ba98_u32 as i32, 2); + check_mul_no_wrap!(0xfedc_ba98_7654_3217_u64 as i64, 2); + check_mul_no_wrap!(0xfedc_ba98_fedc_ba98_u64 as u64 as isize, 2); + + check_mul_wraps!(0x80_u8 as i8, -1); + check_mul_wraps!(0x8000_u16 as i16, -1); + check_mul_wraps!(0x8000_0000_u32 as i32, -1); + check_mul_wraps!(0x8000_0000_0000_0000_u64 as i64, -1); + match () { + #[cfg(target_pointer_width = "32")] + () => { + check_mul_wraps!(0x8000_0000_u32 as isize, -1); + } + #[cfg(target_pointer_width = "64")] + () => { + check_mul_wraps!(0x8000_0000_0000_0000_u64 as isize, -1); + } + } + + macro_rules! check_div_no_wrap { + ($e:expr, $f:expr) => { assert_eq!(($e).wrapping_div($f), ($e) / $f); } + } + macro_rules! check_div_wraps { + ($e:expr, $f:expr) => { assert_eq!(($e).wrapping_div($f), $e); } + } + + check_div_no_wrap!(0xfe_u8 as i8, -1); + check_div_no_wrap!(0xfedc_u16 as i16, -1); + check_div_no_wrap!(0xfedc_ba98_u32 as i32, -1); + check_div_no_wrap!(0xfedc_ba98_7654_3217_u64 as i64, -1); + check_div_no_wrap!(0xfedc_ba98_7654_3217_u64 as u64 as isize, -1); + + check_div_no_wrap!(0xfe_u8 as i8, -2); + check_div_no_wrap!(0xfedc_u16 as i16, -2); + check_div_no_wrap!(0xfedc_ba98_u32 as i32, -2); + check_div_no_wrap!(0xfedc_ba98_7654_3217_u64 as i64, -2); + check_div_no_wrap!(0xfedc_ba98_7654_3217_u64 as u64 as isize, -2); + + check_div_no_wrap!(0xfe_u8 as i8, 2); + check_div_no_wrap!(0xfedc_u16 as i16, 2); + check_div_no_wrap!(0xfedc_ba98_u32 as i32, 2); + check_div_no_wrap!(0xfedc_ba98_7654_3217_u64 as i64, 2); + check_div_no_wrap!(0xfedc_ba98_7654_3217_u64 as u64 as isize, 2); + + check_div_wraps!(-128 as i8, -1); + check_div_wraps!(0x8000_u16 as i16, -1); + check_div_wraps!(0x8000_0000_u32 as i32, -1); + check_div_wraps!(0x8000_0000_0000_0000_u64 as i64, -1); + match () { + #[cfg(target_pointer_width = "32")] + () => { + check_div_wraps!(0x8000_0000_u32 as isize, -1); + } + #[cfg(target_pointer_width = "64")] + () => { + check_div_wraps!(0x8000_0000_0000_0000_u64 as isize, -1); + } + } + + + macro_rules! check_rem_no_wrap { + ($e:expr, $f:expr) => { assert_eq!(($e).wrapping_rem($f), ($e) % $f); } + } + macro_rules! check_rem_wraps { + ($e:expr, $f:expr) => { assert_eq!(($e).wrapping_rem($f), 0); } + } + + check_rem_no_wrap!(0xfe_u8 as i8, -1); + check_rem_no_wrap!(0xfedc_u16 as i16, -1); + check_rem_no_wrap!(0xfedc_ba98_u32 as i32, -1); + check_rem_no_wrap!(0xfedc_ba98_7654_3217_u64 as i64, -1); + check_rem_no_wrap!(0xfedc_ba98_7654_3217_u64 as u64 as isize, -1); + + check_rem_no_wrap!(0xfe_u8 as i8, -2); + check_rem_no_wrap!(0xfedc_u16 as i16, -2); + check_rem_no_wrap!(0xfedc_ba98_u32 as i32, -2); + check_rem_no_wrap!(0xfedc_ba98_7654_3217_u64 as i64, -2); + check_rem_no_wrap!(0xfedc_ba98_7654_3217_u64 as u64 as isize, -2); + + check_rem_no_wrap!(0xfe_u8 as i8, 2); + check_rem_no_wrap!(0xfedc_u16 as i16, 2); + check_rem_no_wrap!(0xfedc_ba98_u32 as i32, 2); + check_rem_no_wrap!(0xfedc_ba98_7654_3217_u64 as i64, 2); + check_rem_no_wrap!(0xfedc_ba98_7654_3217_u64 as u64 as isize, 2); + + check_rem_wraps!(0x80_u8 as i8, -1); + check_rem_wraps!(0x8000_u16 as i16, -1); + check_rem_wraps!(0x8000_0000_u32 as i32, -1); + check_rem_wraps!(0x8000_0000_0000_0000_u64 as i64, -1); + match () { + #[cfg(target_pointer_width = "32")] + () => { + check_rem_wraps!(0x8000_0000_u32 as isize, -1); + } + #[cfg(target_pointer_width = "64")] + () => { + check_rem_wraps!(0x8000_0000_0000_0000_u64 as isize, -1); + } + } + + macro_rules! check_neg_no_wrap { + ($e:expr) => { assert_eq!(($e).wrapping_neg(), -($e)); } + } + macro_rules! check_neg_wraps { + ($e:expr) => { assert_eq!(($e).wrapping_neg(), ($e)); } + } + + check_neg_no_wrap!(0xfe_u8 as i8); + check_neg_no_wrap!(0xfedc_u16 as i16); + check_neg_no_wrap!(0xfedc_ba98_u32 as i32); + check_neg_no_wrap!(0xfedc_ba98_7654_3217_u64 as i64); + check_neg_no_wrap!(0xfedc_ba98_7654_3217_u64 as u64 as isize); + + check_neg_wraps!(0x80_u8 as i8); + check_neg_wraps!(0x8000_u16 as i16); + check_neg_wraps!(0x8000_0000_u32 as i32); + check_neg_wraps!(0x8000_0000_0000_0000_u64 as i64); + match () { + #[cfg(target_pointer_width = "32")] + () => { + check_neg_wraps!(0x8000_0000_u32 as isize); + } + #[cfg(target_pointer_width = "64")] + () => { + check_neg_wraps!(0x8000_0000_0000_0000_u64 as isize); + } + } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/write-fmt-errors.rs b/gcc/testsuite/rust/rustc/ui/write-fmt-errors.rs new file mode 100644 index 000000000000..7da06c85d159 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/write-fmt-errors.rs @@ -0,0 +1,47 @@ +// run-pass + +use std::fmt; +use std::io::{self, Error, Write, sink}; + +struct ErrorDisplay; + +impl fmt::Display for ErrorDisplay { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + Err(fmt::Error) + } +} + +struct ErrorWriter; + +const FORMAT_ERROR: io::ErrorKind = io::ErrorKind::Other; +const WRITER_ERROR: io::ErrorKind = io::ErrorKind::NotConnected; + +impl Write for ErrorWriter { + fn write(&mut self, _buf: &[u8]) -> io::Result { + Err(Error::new(WRITER_ERROR, "not connected")) + } + + fn flush(&mut self) -> io::Result<()> { Ok(()) } +} + +fn main() { + // Test that the error from the formatter is propagated. + let res = write!(sink(), "{} {} {}", 1, ErrorDisplay, "bar"); + assert!(res.is_err(), "formatter error did not propagate"); + assert_eq!(res.unwrap_err().kind(), FORMAT_ERROR); + + // Test that an underlying error is propagated + let res = write!(ErrorWriter, "abc"); + assert!(res.is_err(), "writer error did not propagate"); + + // Writer error + let res = write!(ErrorWriter, "abc {}", ErrorDisplay); + assert!(res.is_err(), "writer error did not propagate"); + assert_eq!(res.unwrap_err().kind(), WRITER_ERROR); + + // Formatter error + let res = write!(ErrorWriter, "{} abc", ErrorDisplay); + assert!(res.is_err(), "formatter error did not propagate"); + assert_eq!(res.unwrap_err().kind(), FORMAT_ERROR); +} + diff --git a/gcc/testsuite/rust/rustc/ui/write-to-static-mut-in-static.rs b/gcc/testsuite/rust/rustc/ui/write-to-static-mut-in-static.rs new file mode 100644 index 000000000000..f00afb92d74a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/write-to-static-mut-in-static.rs @@ -0,0 +1,11 @@ +pub static mut A: u32 = 0; +pub static mut B: () = unsafe { A = 1; }; +// { dg-error ".E0080." "" { target *-*-* } .-1 } + +pub static mut C: u32 = unsafe { C = 1; 0 }; +// { dg-error ".E0391." "" { target *-*-* } .-1 } + +pub static D: u32 = D; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/writealias.rs b/gcc/testsuite/rust/rustc/ui/writealias.rs new file mode 100644 index 000000000000..99412f453e04 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/writealias.rs @@ -0,0 +1,20 @@ +// run-pass + +#![allow(dead_code)] + +use std::sync::Mutex; + +struct Point {x: isize, y: isize, z: isize} + +fn f(p: &mut Point) { p.z = 13; } + +pub fn main() { + let x = Some(Mutex::new(true)); + match x { + Some(ref z) if *z.lock().unwrap() => { + assert!(*z.lock().unwrap()); + }, + _ => panic!() + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/writing-to-immutable-vec.rs b/gcc/testsuite/rust/rustc/ui/writing-to-immutable-vec.rs new file mode 100644 index 000000000000..e0b6102d5698 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/writing-to-immutable-vec.rs @@ -0,0 +1,5 @@ +fn main() { + let v: Vec = vec![1, 2, 3]; + v[1] = 4; // { dg-error ".E0596." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/wrong-hashset-issue-42918.rs b/gcc/testsuite/rust/rustc/ui/wrong-hashset-issue-42918.rs new file mode 100644 index 000000000000..b1d978937cf5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wrong-hashset-issue-42918.rs @@ -0,0 +1,32 @@ +// run-pass +// +#![allow(dead_code)] +// compile-flags: -O + +use std::collections::HashSet; + +#[derive(PartialEq, Debug, Hash, Eq, Clone, PartialOrd, Ord)] +enum MyEnum { + E0, + + E1, + + E2, + E3, + E4, + + E5, + E6, + E7, +} + + +fn main() { + use MyEnum::*; + let s: HashSet<_> = [E4, E1].iter().cloned().collect(); + let mut v: Vec<_> = s.into_iter().collect(); + v.sort(); + + assert_eq!([E1, E4], &v[..]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/wrong-mul-method-signature.rs b/gcc/testsuite/rust/rustc/ui/wrong-mul-method-signature.rs new file mode 100644 index 000000000000..b1c769a9183c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wrong-mul-method-signature.rs @@ -0,0 +1,69 @@ +// This test is to make sure we don't just ICE if the trait +// method for an operator is not implemented properly. +// (In this case the mul method should take &f64 and not f64) +// See: #11450 + +use std::ops::Mul; + +struct Vec1 { + x: f64 +} + +// Expecting value in input signature +impl Mul for Vec1 { + type Output = Vec1; + + fn mul(self, s: &f64) -> Vec1 { +// { dg-error ".E0053." "" { target *-*-* } .-1 } + Vec1 { + x: self.x * *s + } + } +} + +struct Vec2 { + x: f64, + y: f64 +} + +// Wrong type parameter ordering +impl Mul for Vec2 { + type Output = f64; + + fn mul(self, s: f64) -> Vec2 { +// { dg-error ".E0053." "" { target *-*-* } .-1 } + Vec2 { + x: self.x * s, + y: self.y * s + } + } +} + +struct Vec3 { + x: f64, + y: f64, + z: f64 +} + +// Unexpected return type +impl Mul for Vec3 { + type Output = i32; + + fn mul(self, s: f64) -> f64 { +// { dg-error ".E0053." "" { target *-*-* } .-1 } + s + } +} + +pub fn main() { + // Check that the usage goes from the trait declaration: + + let x: Vec1 = Vec1 { x: 1.0 } * 2.0; // this is OK + + let x: Vec2 = Vec2 { x: 1.0, y: 2.0 } * 2.0; // trait had reversed order +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + + let x: i32 = Vec3 { x: 1.0, y: 2.0, z: 3.0 } * 2.0; +} + diff --git a/gcc/testsuite/rust/rustc/ui/wrong-ret-type.rs b/gcc/testsuite/rust/rustc/ui/wrong-ret-type.rs new file mode 100644 index 000000000000..89d3905e2889 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/wrong-ret-type.rs @@ -0,0 +1,4 @@ +// error-pattern: mismatched types +fn mk_int() -> usize { let i: isize = 3; return i; } +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/x86stdcall.rs b/gcc/testsuite/rust/rustc/ui/x86stdcall.rs new file mode 100644 index 000000000000..cfed2b8afde7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/x86stdcall.rs @@ -0,0 +1,38 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with +// ignore-sgx no libc +// GetLastError doesn't seem to work with stack switching + +#[cfg(windows)] +mod kernel32 { + extern "system" { + pub fn SetLastError(err: usize); + pub fn GetLastError() -> usize; + } +} + + +#[cfg(windows)] +pub fn main() { + unsafe { + let expected = 1234; + kernel32::SetLastError(expected); + let actual = kernel32::GetLastError(); + println!("actual = {}", actual); + assert_eq!(expected, actual); + } +} + +#[cfg(any(target_os = "android", + target_os = "cloudabi", + target_os = "dragonfly", + target_os = "emscripten", + target_os = "freebsd", + target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "vxworks", + target_os = "solaris"))] +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/x86stdcall2.rs b/gcc/testsuite/rust/rustc/ui/x86stdcall2.rs new file mode 100644 index 000000000000..6f2702c0fe17 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/x86stdcall2.rs @@ -0,0 +1,34 @@ +// run-pass + +#![allow(non_camel_case_types)] +pub type HANDLE = usize; +pub type DWORD = u32; +pub type SIZE_T = u32; +pub type LPVOID = usize; +pub type BOOL = u8; + +#[cfg(windows)] +mod kernel32 { + use super::{HANDLE, DWORD, SIZE_T, LPVOID, BOOL}; + + extern "system" { + pub fn GetProcessHeap() -> HANDLE; + pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) + -> LPVOID; + pub fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL; + } +} + + +#[cfg(windows)] +pub fn main() { + let heap = unsafe { kernel32::GetProcessHeap() }; + let mem = unsafe { kernel32::HeapAlloc(heap, 0, 100) }; + assert!(mem != 0); + let res = unsafe { kernel32::HeapFree(heap, 0, mem) }; + assert!(res != 0); +} + +#[cfg(not(windows))] +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/xc-private-method.rs b/gcc/testsuite/rust/rustc/ui/xc-private-method.rs new file mode 100644 index 000000000000..0a261c175300 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/xc-private-method.rs @@ -0,0 +1,12 @@ +// aux-build:xc-private-method-lib.rs + +extern crate xc_private_method_lib; + +fn main() { + let _ = xc_private_method_lib::Struct::static_meth_struct(); +// { dg-error ".E0624." "" { target *-*-* } .-1 } + + let _ = xc_private_method_lib::Enum::static_meth_enum(); +// { dg-error ".E0624." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/xc-private-method2.rs b/gcc/testsuite/rust/rustc/ui/xc-private-method2.rs new file mode 100644 index 000000000000..4bcbd1d19735 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/xc-private-method2.rs @@ -0,0 +1,12 @@ +// aux-build:xc-private-method-lib.rs + +extern crate xc_private_method_lib; + +fn main() { + let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct(); +// { dg-error ".E0624." "" { target *-*-* } .-1 } + + let _ = xc_private_method_lib::Enum::Variant1(20).meth_enum(); +// { dg-error ".E0624." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/xcrate/auxiliary/static_priv_by_default.rs b/gcc/testsuite/rust/rustc/ui/xcrate/auxiliary/static_priv_by_default.rs new file mode 100644 index 000000000000..003f6f104fbb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/xcrate/auxiliary/static_priv_by_default.rs @@ -0,0 +1,52 @@ +#![crate_type = "lib"] + +static private: isize = 0; +pub static public: isize = 0; + +pub struct A(()); + +impl A { + fn foo() {} +} + +mod foo { + pub static a: isize = 0; + pub fn b() {} + pub struct c; + pub enum d {} + pub type e = isize; + + pub struct A(()); + + impl A { + fn foo() {} + } + + // these are public so the parent can re-export them. + pub static reexported_a: isize = 0; + pub fn reexported_b() {} + pub struct reexported_c; + pub enum reexported_d {} + pub type reexported_e = isize; +} + +pub mod bar { + pub use foo::reexported_a as e; + pub use foo::reexported_b as f; + pub use foo::reexported_c as g; + pub use foo::reexported_d as h; + pub use foo::reexported_e as i; +} + +pub static a: isize = 0; +pub fn b() {} +pub struct c; +pub enum d {} +pub type e = isize; + +static j: isize = 0; +fn k() {} +struct l; +enum m {} +type n = isize; + diff --git a/gcc/testsuite/rust/rustc/ui/xcrate/auxiliary/xcrate_unit_struct.rs b/gcc/testsuite/rust/rustc/ui/xcrate/auxiliary/xcrate_unit_struct.rs new file mode 100644 index 000000000000..4ba18de4bed1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/xcrate/auxiliary/xcrate_unit_struct.rs @@ -0,0 +1,29 @@ +#![crate_type = "lib"] + +// used by the rpass test + +#[derive(Copy, Clone)] +pub struct Struct; + +#[derive(Copy, Clone)] +pub enum Unit { + UnitVariant, + Argument(Struct) +} + +#[derive(Copy, Clone)] +pub struct TupleStruct(pub usize, pub &'static str); + +// used by the cfail test + +#[derive(Copy, Clone)] +pub struct StructWithFields { + foo: isize, +} + +#[derive(Copy, Clone)] +pub enum EnumWithVariants { + EnumVariant, + EnumVariantArg(isize) +} + diff --git a/gcc/testsuite/rust/rustc/ui/xcrate/xcrate-private-by-default.rs b/gcc/testsuite/rust/rustc/ui/xcrate/xcrate-private-by-default.rs new file mode 100644 index 000000000000..36de2da5c3d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/xcrate/xcrate-private-by-default.rs @@ -0,0 +1,46 @@ +// aux-build:static_priv_by_default.rs + +extern crate static_priv_by_default; + +fn foo() {} + +fn main() { + // Actual public items should be public + static_priv_by_default::a; + static_priv_by_default::b; + static_priv_by_default::c; + foo::(); + foo::(); + + // publicly re-exported items should be available + static_priv_by_default::bar::e; + static_priv_by_default::bar::f; + static_priv_by_default::bar::g; + foo::(); + foo::(); + + // private items at the top should be inaccessible + static_priv_by_default::j; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + static_priv_by_default::k; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + static_priv_by_default::l; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + foo::(); +// { dg-error ".E0603." "" { target *-*-* } .-1 } + foo::(); +// { dg-error ".E0603." "" { target *-*-* } .-1 } + + // public items in a private mod should be inaccessible + static_priv_by_default::foo::a; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + static_priv_by_default::foo::b; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + static_priv_by_default::foo::c; +// { dg-error ".E0603." "" { target *-*-* } .-1 } + foo::(); +// { dg-error ".E0603." "" { target *-*-* } .-1 } + foo::(); +// { dg-error ".E0603." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/xcrate/xcrate-unit-struct.rs b/gcc/testsuite/rust/rustc/ui/xcrate/xcrate-unit-struct.rs new file mode 100644 index 000000000000..9d0b45d54e59 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/xcrate/xcrate-unit-struct.rs @@ -0,0 +1,13 @@ +// aux-build:xcrate_unit_struct.rs + +// Make sure that when we have cross-crate unit structs we don't accidentally +// make values out of cross-crate structs that aren't unit. + +extern crate xcrate_unit_struct; + +fn main() { + let _ = xcrate_unit_struct::StructWithFields; +// { dg-error ".E0423." "" { target *-*-* } .-1 } + let _ = xcrate_unit_struct::Struct; +} + diff --git a/gcc/testsuite/rust/rustc/ui/yield.rs b/gcc/testsuite/rust/rustc/ui/yield.rs new file mode 100644 index 000000000000..9efbe6730cb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/yield.rs @@ -0,0 +1,22 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(unused_mut)] +// ignore-emscripten no threads support + +use std::thread; + +pub fn main() { + let mut result = thread::spawn(child); + println!("1"); + thread::yield_now(); + println!("2"); + thread::yield_now(); + println!("3"); + result.join(); +} + +fn child() { + println!("4"); thread::yield_now(); println!("5"); thread::yield_now(); println!("6"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/yield1.rs b/gcc/testsuite/rust/rustc/ui/yield1.rs new file mode 100644 index 000000000000..ee6ca84c52a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/yield1.rs @@ -0,0 +1,17 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(unused_mut)] +// ignore-emscripten no threads support + +use std::thread; + +pub fn main() { + let mut result = thread::spawn(child); + println!("1"); + thread::yield_now(); + result.join(); +} + +fn child() { println!("2"); } + diff --git a/gcc/testsuite/rust/rustc/ui/yield2.rs b/gcc/testsuite/rust/rustc/ui/yield2.rs new file mode 100644 index 000000000000..c17a49e65ddc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/yield2.rs @@ -0,0 +1,9 @@ +// run-pass + +use std::thread; + +pub fn main() { + let mut i: isize = 0; + while i < 100 { i = i + 1; println!("{}", i); thread::yield_now(); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/z-crate-attr.rs b/gcc/testsuite/rust/rustc/ui/z-crate-attr.rs new file mode 100644 index 000000000000..76c5eb69c162 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/z-crate-attr.rs @@ -0,0 +1,13 @@ +// run-pass +// This test checks if an unstable feature is enabled with the -Zcrate-attr=feature(foo) flag. If +// the exact feature used here is causing problems feel free to replace it with another +// perma-unstable feature. + +// compile-flags: -Zcrate-attr=feature(abi_unadjusted) + +#![allow(dead_code)] + +extern "unadjusted" fn foo() {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/zero-sized/zero-size-type-destructors.rs b/gcc/testsuite/rust/rustc/ui/zero-sized/zero-size-type-destructors.rs new file mode 100644 index 000000000000..0cb5c4bac2ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/zero-sized/zero-size-type-destructors.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(non_upper_case_globals)] + +static mut destructions : isize = 3; + +pub fn foo() { + struct Foo; + + impl Drop for Foo { + fn drop(&mut self) { + unsafe { destructions -= 1 }; + } + }; + + let _x = [Foo, Foo, Foo]; +} + +pub fn main() { + foo(); + assert_eq!(unsafe { destructions }, 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-binary-heap-push.rs b/gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-binary-heap-push.rs new file mode 100644 index 000000000000..293de8c50d62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-binary-heap-push.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(unused_variables)] +use std::collections::BinaryHeap; +use std::iter::Iterator; + +fn main() { + const N: usize = 8; + + for len in 0..N { + let mut tester = BinaryHeap::with_capacity(len); + assert_eq!(tester.len(), 0); + assert!(tester.capacity() >= len); + for bit in 0..len { + tester.push(()); + } + assert_eq!(tester.len(), len); + assert_eq!(tester.iter().count(), len); + tester.clear(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-btreemap-insert.rs b/gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-btreemap-insert.rs new file mode 100644 index 000000000000..8c50f3176050 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-btreemap-insert.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(unused_variables)] +#![allow(unused_imports)] +use std::cmp::{Ord, Ordering, PartialOrd}; +use std::collections::BTreeMap; +use std::iter::Iterator; + +#[derive(Eq, Hash, Debug, Ord, PartialEq, PartialOrd)] +struct Zst; + +fn main() { + const N: usize = 8; + + for len in 0..N { + let mut tester = BTreeMap::new(); + assert_eq!(tester.len(), 0); + for bit in 0..len { + tester.insert(Zst, ()); + } + assert_eq!(tester.len(), if len == 0 { 0 } else { 1 }); + assert_eq!(tester.iter().count(), if len == 0 { 0 } else { 1 }); + assert_eq!(tester.get(&Zst).is_some(), len > 0); + tester.clear(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-linkedlist-push.rs b/gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-linkedlist-push.rs new file mode 100644 index 000000000000..aa34d3e520c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-linkedlist-push.rs @@ -0,0 +1,30 @@ +// run-pass +use std::collections::LinkedList; +use std::iter::Iterator; + +fn main() { + const N: usize = 8; + + // Test that for all possible sequences of push_front / push_back, + // we end up with a LinkedList of the correct size + + for len in 0..N { + let mut tester = LinkedList::new(); + assert_eq!(tester.len(), 0); + assert_eq!(tester.front(), None); + for case in 0..(1 << len) { + assert_eq!(tester.len(), 0); + for bit in 0..len { + if case & (1 << bit) != 0 { + tester.push_front(()); + } else { + tester.push_back(()); + } + } + assert_eq!(tester.len(), len); + assert_eq!(tester.iter().count(), len); + tester.clear(); + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-tuple-struct.rs b/gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-tuple-struct.rs new file mode 100644 index 000000000000..f90b358ed66b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/zero-sized/zero-sized-tuple-struct.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(unused_braces)] +#![allow(unused_assignments)] + +// Make sure that the constructor args are codegened for zero-sized tuple structs + +struct Foo(()); + +fn main() { + let mut a = 1; + Foo({ a = 2 }); + assert_eq!(a, 2); +} +

); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17734.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17734.rs new file mode 100644 index 000000000000..519946ce1d4a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17734.rs @@ -0,0 +1,16 @@ +// run-pass +// Test that generating drop glue for Box doesn't ICE + + +fn f(s: Box) -> Box { + s +} + +fn main() { + // There is currently no safe way to construct a `Box`, so improvise + let box_arr: Box<[u8]> = Box::new(['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8]); + let box_str: Box = unsafe { std::mem::transmute(box_arr) }; + assert_eq!(&*box_str, "hello"); + f(box_str); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17740.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17740.rs new file mode 100644 index 000000000000..57855e38e72e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17740.rs @@ -0,0 +1,19 @@ +struct Foo<'a> { + data: &'a[u8], +} + +impl <'a> Foo<'a>{ + fn bar(self: &mut Foo) { +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } +// { dg-error ".E0308." "" { target *-*-* } .-3 } +// { dg-error ".E0308." "" { target *-*-* } .-4 } +// { dg-error ".E0308." "" { target *-*-* } .-5 } +// { dg-error ".E0308." "" { target *-*-* } .-6 } +// { dg-error ".E0308." "" { target *-*-* } .-7 } +// { dg-error ".E0308." "" { target *-*-* } .-8 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17746.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17746.rs new file mode 100644 index 000000000000..8b8d4bfa26d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17746.rs @@ -0,0 +1,26 @@ +// check-pass +#![allow(dead_code)] +// Regression test for #17746 + +fn main() {} + +struct A; + +impl A { + fn b(&mut self) { + self.a() + } +} + +trait Foo { + fn dummy(&self) {} +} +trait Bar { + fn a(&self); +} + +impl Foo for A {} +impl Bar for T where T: Foo { + fn a(&self) {} +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17756.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17756.rs new file mode 100644 index 000000000000..e91c1ad52b99 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17756.rs @@ -0,0 +1,9 @@ +// run-pass +#![allow(unused_variables)] +#![allow(non_upper_case_globals)] + +const count : usize = 2 as usize; +fn main() { + let larger : [usize; count*2]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17758.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17758.rs new file mode 100644 index 000000000000..6fa9ccda9b2e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17758.rs @@ -0,0 +1,13 @@ +// Test that regionck suggestions in a provided method of a trait +// don't ICE + +trait Foo<'a> { + fn foo(&'a self); + fn bar(&self) { + self.foo(); +// { dg-error ".E0495." "" { target *-*-* } .-1 } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17771.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17771.rs new file mode 100644 index 000000000000..a1219bcd94d5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17771.rs @@ -0,0 +1,22 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait Aaa { fn dummy(&self) { } } + +impl<'a> Aaa for &'a mut (dyn Aaa + 'a) {} + +struct Bar<'a> { + writer: &'a mut (dyn Aaa + 'a), +} + +fn baz(_: &mut dyn Aaa) { +} + +fn foo<'a>(mut bar: Bar<'a>) { + baz(&mut bar.writer); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17800.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17800.rs new file mode 100644 index 000000000000..468c11edd611 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17800.rs @@ -0,0 +1,13 @@ +enum MyOption { + MySome(T), + MyNone, +} + +fn main() { + match MyOption::MySome(42) { + MyOption::MySome { x: 42 } => (), +// { dg-error ".E0769." "" { target *-*-* } .-1 } + _ => (), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17816.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17816.rs new file mode 100644 index 000000000000..168048507780 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17816.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_variables)] +use std::marker::PhantomData; + +fn main() { + struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F, marker: PhantomData<&'a ()> } + let f = |x: Vec<&str>| -> &str { "foobar" }; + let sym = Symbol { function: f, marker: PhantomData }; + (sym.function)(vec![]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17877.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17877.rs new file mode 100644 index 000000000000..12413ce9b385 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17877.rs @@ -0,0 +1,14 @@ +// run-pass + +fn main() { + assert_eq!(match [0u8; 1024] { + _ => 42_usize, + }, 42_usize); + + assert_eq!(match [0u8; 1024] { + [1, ..] => 0_usize, + [0, ..] => 1_usize, + _ => 2_usize + }, 1_usize); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17897.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17897.rs new file mode 100644 index 000000000000..bfbb2a5729cb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17897.rs @@ -0,0 +1,9 @@ +// run-pass +fn action(mut cb: Box usize>) -> usize { + cb(1) +} + +pub fn main() { + println!("num: {}", action(Box::new(move |u| u))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17904-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17904-2.rs new file mode 100644 index 000000000000..e5a3ce546b46 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17904-2.rs @@ -0,0 +1,7 @@ +// Test that we can parse a unit struct with a where clause, even if +// it leads to an error later on since `T` is unused. + +struct Foo where T: Copy; // { dg-error ".E0392." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17904.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17904.rs new file mode 100644 index 000000000000..59f8b87a9fff --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17904.rs @@ -0,0 +1,15 @@ +// check-pass +#![allow(dead_code)] +// Test that we can parse where clauses on various forms of tuple +// structs. + +// pretty-expanded FIXME #23616 + +struct Bar(T) where T: Copy; +struct Bleh(T, U) where T: Copy, U: Sized; +struct Baz where T: Copy { + field: T +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17905-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17905-2.rs new file mode 100644 index 000000000000..02a6a2f03b36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17905-2.rs @@ -0,0 +1,19 @@ +#[derive(Debug)] +struct Pair (T, V); + +impl Pair< + &str, + isize +> { + fn say(self: &Pair<&str, isize>) { +// { dg-error ".E0308." "" { target *-*-* } .-1 } +// { dg-error ".E0308." "" { target *-*-* } .-2 } + println!("{:?}", self); + } +} + +fn main() { + let result = &Pair("shane", 1); + result.say(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17905.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17905.rs new file mode 100644 index 000000000000..db75d7ea56a7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17905.rs @@ -0,0 +1,19 @@ +// run-pass + +#[derive(Debug)] +struct Pair (T, V); + +impl Pair< + &str, + isize +> { + fn say(&self) { + println!("{:?}", self); + } +} + +fn main() { + let result = &Pair("shane", 1); + result.say(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17913.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17913.rs new file mode 100644 index 000000000000..7f1c6c3400d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17913.rs @@ -0,0 +1,24 @@ +// build-fail +// normalize-stderr-test "\[&usize; \d+\]" -> "[&usize; N]" +// error-pattern: too big for the current architecture + +// FIXME https://github.com/rust-lang/rust/issues/59774 +// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> "" +// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" + +#![feature(box_syntax)] + +#[cfg(target_pointer_width = "64")] +fn main() { + let n = 0_usize; + let a: Box<_> = box [&n; 0xF000000000000000_usize]; + println!("{}", a[0xFFFFFF_usize]); +} + +#[cfg(target_pointer_width = "32")] +fn main() { + let n = 0_usize; + let a: Box<_> = box [&n; 0xFFFFFFFF_usize]; + println!("{}", a[0xFFFFFF_usize]); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17933.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17933.rs new file mode 100644 index 000000000000..4b387c538e13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17933.rs @@ -0,0 +1,10 @@ +pub static X: usize = 1; + +fn main() { + match 1 { + self::X => { }, +// { dg-error ".E0532." "" { target *-*-* } .-1 } + _ => { }, + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17954.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17954.rs new file mode 100644 index 000000000000..a9949be8144c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17954.rs @@ -0,0 +1,16 @@ +#![feature(thread_local)] + +#[thread_local] +static FOO: u8 = 3; + +fn main() { + let a = &FOO; +// { dg-error ".E0712." "" { target *-*-* } .-1 } +// { dg-note ".E0712." "" { target *-*-* } .-2 } + + std::thread::spawn(move || { + println!("{}", a); + }); +} +// { dg-note "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17959.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17959.rs new file mode 100644 index 000000000000..6a20fd84dae4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17959.rs @@ -0,0 +1,22 @@ +extern crate core; + +use core::ops::Drop; + +trait Bar {} + +struct G { + _ptr: *const T +} + +impl Drop for G { +// { dg-error ".E0367." "" { target *-*-* } .-1 } + fn drop(&mut self) { + if !self._ptr.is_null() { + } + } +} + +fn main() { + let x:G; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17994.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17994.rs new file mode 100644 index 000000000000..6675d9535f60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17994.rs @@ -0,0 +1,4 @@ +trait Tr {} +type Huh where T: Tr = isize; // { dg-error ".E0091." "" { target *-*-* } } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-17999.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-17999.rs new file mode 100644 index 000000000000..a08fc4e46e43 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-17999.rs @@ -0,0 +1,11 @@ +#![deny(unused_variables)] + +fn main() { + for _ in 1..101 { + let x = (); // { dg-error "" "" { target *-*-* } } + match () { + a => {} // { dg-error "" "" { target *-*-* } } + } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18058.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18058.rs new file mode 100644 index 000000000000..b15e063179ae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18058.rs @@ -0,0 +1,5 @@ +impl Undefined {} +// { dg-error ".E0412." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18060.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18060.rs new file mode 100644 index 000000000000..135d2d223337 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18060.rs @@ -0,0 +1,9 @@ +// run-pass +// Regression test for #18060: match arms were matching in the wrong order. + +fn main() { + assert_eq!(2, match (1, 3) { (0, 2..=5) => 1, (1, 3) => 2, (_, 2..=5) => 3, (_, _) => 4 }); + assert_eq!(2, match (1, 3) { (1, 3) => 2, (_, 2..=5) => 3, (_, _) => 4 }); + assert_eq!(2, match (1, 7) { (0, 2..=5) => 1, (1, 7) => 2, (_, 2..=5) => 3, (_, _) => 4 }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18083.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18083.rs new file mode 100644 index 000000000000..e0bdc87bd103 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18083.rs @@ -0,0 +1,26 @@ +// check-pass +#![allow(dead_code)] +#![allow(unused_imports)] +// These crossed imports should resolve fine, and not block on +// each other and be reported as unresolved. + +mod a { + use b::{B}; + pub use self::inner::A; + + mod inner { + pub struct A; + } +} + +mod b { + use a::{A}; + pub use self::inner::B; + + mod inner { + pub struct B; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18088.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18088.rs new file mode 100644 index 000000000000..1032e486d812 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18088.rs @@ -0,0 +1,9 @@ +// check-pass + +pub trait Indexable: std::ops::Index { + fn index2(&self, i: usize) -> &T { + &self[i] + } +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18107.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18107.rs new file mode 100644 index 000000000000..796899b64ee8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18107.rs @@ -0,0 +1,14 @@ +pub trait AbstractRenderer {} + +fn _create_render(_: &()) -> + dyn AbstractRenderer +// { dg-error ".E0746." "" { target *-*-* } .-1 } +{ + match 0 { + _ => unimplemented!() + } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18110.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18110.rs new file mode 100644 index 000000000000..3427c64c9e02 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18110.rs @@ -0,0 +1,8 @@ +// run-pass +#![allow(unreachable_code)] +// pretty-expanded FIXME #23616 + +fn main() { + ({return},); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18118-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18118-2.rs new file mode 100644 index 000000000000..e1ad25a07691 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18118-2.rs @@ -0,0 +1,7 @@ +pub fn main() { + const z: &'static isize = { + static p: isize = 3; + &p // { dg-error ".E0013." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18118.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18118.rs new file mode 100644 index 000000000000..8486b6410f6c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18118.rs @@ -0,0 +1,7 @@ +pub fn main() { + const z: &'static isize = { + let p = 3; + &p // { dg-error ".E0597." "" { target *-*-* } } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18119.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18119.rs new file mode 100644 index 000000000000..71417a017b9d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18119.rs @@ -0,0 +1,13 @@ +const X: u8 = 1; +static Y: u8 = 1; +fn foo() {} + +impl X {} +// { dg-error ".E0573." "" { target *-*-* } .-1 } +impl Y {} +// { dg-error ".E0573." "" { target *-*-* } .-1 } +impl foo {} +// { dg-error ".E0573." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18159.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18159.rs new file mode 100644 index 000000000000..4c81633a5695 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18159.rs @@ -0,0 +1,4 @@ +fn main() { + let x; // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18173.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18173.rs new file mode 100644 index 000000000000..1d0536d00adc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18173.rs @@ -0,0 +1,13 @@ +// run-pass +trait Foo { + type T; +} + +// should be able to use a trait with an associated type without specifying it as an argument +trait Bar { + fn bar(foo: &F); +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18183.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18183.rs new file mode 100644 index 000000000000..45e1745ac614 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18183.rs @@ -0,0 +1,4 @@ +pub struct Foo(Bar); // { dg-error ".E0128." "" { target *-*-* } } +pub struct Baz(Foo); +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18188.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18188.rs new file mode 100644 index 000000000000..1bae3000c219 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18188.rs @@ -0,0 +1,23 @@ +// check-pass +// pretty-expanded FIXME #23616 + +pub trait Promisable: Send + Sync {} +impl Promisable for T {} + +pub fn propagate<'a, T, E, F, G>(mut action: F) + -> Box) -> Result + 'a> + where + T: Promisable + Clone + 'a, + E: Promisable + Clone + 'a, + F: FnMut(&T) -> Result + Send + 'a, + G: FnMut(Result) -> Result + 'a { + Box::new(move |result: Result| { + match result { + Ok(ref t) => action(t), + Err(ref e) => Err(e.clone()), + } + }) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1821.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1821.rs new file mode 100644 index 000000000000..35ef7547fd20 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1821.rs @@ -0,0 +1,14 @@ +// check-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// Issue #1821 - Don't recurse trying to typecheck this + + +// pretty-expanded FIXME #23616 + +enum t { + foo(Vec) +} +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18232.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18232.rs new file mode 100644 index 000000000000..4a556a495fa2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18232.rs @@ -0,0 +1,23 @@ +// run-pass +// pretty-expanded FIXME #23616 + +struct Cursor<'a>(::std::marker::PhantomData<&'a ()>); + +trait CursorNavigator { + fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool; +} + +struct SimpleNavigator; + +impl CursorNavigator for SimpleNavigator { + fn init_cursor<'a, 'b: 'a>(&'a self, _cursor: &mut Cursor<'b>) -> bool { + false + } +} + +fn main() { + let mut c = Cursor(::std::marker::PhantomData); + let n = SimpleNavigator; + n.init_cursor(&mut c); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18294.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18294.rs new file mode 100644 index 000000000000..c8c8725ab966 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18294.rs @@ -0,0 +1,6 @@ +fn main() { + const X: u32 = 1; + const Y: usize = unsafe { &X as *const u32 as usize }; // { dg-error ".E0658." "" { target *-*-* } } + println!("{}", Y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18352.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18352.rs new file mode 100644 index 000000000000..3ec9ab1809af --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18352.rs @@ -0,0 +1,15 @@ +// run-pass + +const X: &'static str = "12345"; + +fn test(s: String) -> bool { + match &*s { + X => true, + _ => false + } +} + +fn main() { + assert!(test("12345".to_string())); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18353.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18353.rs new file mode 100644 index 000000000000..cca21f120747 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18353.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +// Test that wrapping an unsized struct in an enum which gets optimised does +// not ICE. + +// pretty-expanded FIXME #23616 + +struct Str { + f: [u8] +} + +fn main() { + let str: Option<&Str> = None; + let _ = str.is_some(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18389.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18389.rs new file mode 100644 index 000000000000..17831dbb74eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18389.rs @@ -0,0 +1,19 @@ +use std::any::Any; +use std::any::TypeId; + +trait Private { + fn call(&self, p: P, r: R); +} +pub trait Public: Private< +// { dg-error ".E0445." "" { target *-*-* } .-1 } + ::P, + ::R +> { + type P; + type R; + + fn call_inner(&self); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18400.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18400.rs new file mode 100644 index 000000000000..00f7aaa85014 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18400.rs @@ -0,0 +1,27 @@ +trait Set { + fn contains(&self, _: T) -> bool; + fn set(&mut self, _: T); +} + +impl<'a, T, S> Set<&'a [T]> for S where + T: Copy, + S: Set, +{ + fn contains(&self, bits: &[T]) -> bool { + bits.iter().all(|&bit| self.contains(bit)) + } + + fn set(&mut self, bits: &[T]) { + for &bit in bits { + self.set(bit) + } + } +} + +fn main() { + let bits: &[_] = &[0, 1]; + + 0.contains(bits); +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18412.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18412.rs new file mode 100644 index 000000000000..cff3c3a98c60 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18412.rs @@ -0,0 +1,27 @@ +// run-pass +// Test that non-static methods can be assigned to local variables as +// function pointers. + + +trait Foo { + fn foo(&self) -> usize; +} + +struct A(usize); + +impl A { + fn bar(&self) -> usize { self.0 } +} + +impl Foo for A { + fn foo(&self) -> usize { self.bar() } +} + +fn main() { + let f = A::bar; + let g = Foo::foo; + let a = A(42); + + assert_eq!(f(&a), g(&a)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18423.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18423.rs new file mode 100644 index 000000000000..76f47ca2bf94 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18423.rs @@ -0,0 +1,9 @@ +// Test that `Box` cannot be used with a lifetime argument. + +struct Foo<'a> { + x: Box<'a, isize> // { dg-error ".E0107." "" { target *-*-* } } +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18425.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18425.rs new file mode 100644 index 000000000000..3c5cfe55e036 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18425.rs @@ -0,0 +1,10 @@ +// run-pass +// Check that codegen doesn't ICE when codegenning an array repeat +// expression with a count of 1 and a non-Copy element type. + +// pretty-expanded FIXME #23616 + +fn main() { + let _ = [Box::new(1_usize); 1]; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18446-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18446-2.rs new file mode 100644 index 000000000000..7c62ede404d4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18446-2.rs @@ -0,0 +1,14 @@ +// check-pass +#![allow(dead_code)] +// Test that methods in trait impls should override default methods. + +trait T { + fn foo(&self) -> i32 { 0 } +} + +impl<'a> dyn T + 'a { + fn foo(&self) -> i32 { 1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18446.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18446.rs new file mode 100644 index 000000000000..4d2040d600cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18446.rs @@ -0,0 +1,20 @@ +// Test that name clashes between the method in an impl for the type +// and the method in the trait when both are in the same scope. + +trait T { + fn foo(&self); +} + +impl<'a> dyn T + 'a { + fn foo(&self) {} +} + +impl T for i32 { + fn foo(&self) {} +} + +fn main() { + let x: &dyn T = &0i32; + x.foo(); // { dg-error ".E0034." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18464.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18464.rs new file mode 100644 index 000000000000..1fa37e05c10c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18464.rs @@ -0,0 +1,13 @@ +// run-pass +#![deny(dead_code)] + +const LOW_RANGE: char = '0'; +const HIGH_RANGE: char = '9'; + +fn main() { + match '5' { + LOW_RANGE..=HIGH_RANGE => (), + _ => () + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18501.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18501.rs new file mode 100644 index 000000000000..ab4950c2b37c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18501.rs @@ -0,0 +1,14 @@ +// run-pass +// Test that we don't ICE when inlining a function from another +// crate that uses a trait method as a value due to incorrectly +// translating the def ID of the trait during AST decoding. + +// aux-build:issue-18501.rs +// pretty-expanded FIXME #23616 + +extern crate issue_18501 as issue; + +fn main() { + issue::pass_method(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18514.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18514.rs new file mode 100644 index 000000000000..10a8a4b0ba40 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18514.rs @@ -0,0 +1,17 @@ +// run-pass +// Test that we don't ICE when codegenning a generic impl method from +// an extern crate that contains a match expression on a local +// variable place where one of the match case bodies contains an +// expression that autoderefs through an overloaded generic deref +// impl. + +// aux-build:issue-18514.rs + +extern crate issue_18514 as ice; +use ice::{Tr, St}; + +fn main() { + let st: St<()> = St(vec![]); + st.tr(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18532.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18532.rs new file mode 100644 index 000000000000..8abe8424fb22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18532.rs @@ -0,0 +1,8 @@ +// Test that overloaded call parameter checking does not ICE +// when a type error or unconstrained type variable propagates +// into it. + +fn main() { + (return)((),()); // { dg-error ".E0618." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18539.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18539.rs new file mode 100644 index 000000000000..295c0c1059a5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18539.rs @@ -0,0 +1,17 @@ +// run-pass +// Test that coercing bare fn's that return a zero sized type to +// a closure doesn't cause an LLVM ERROR + +// pretty-expanded FIXME #23616 + +struct Foo; + +fn uint_to_foo(_: usize) -> Foo { + Foo +} + +#[allow(unused_must_use)] +fn main() { + (0..10).map(uint_to_foo); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18566.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18566.rs new file mode 100644 index 000000000000..dda5a13ddada --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18566.rs @@ -0,0 +1,26 @@ +use std::ops::Deref; + +struct MyPtr<'a>(&'a mut usize); +impl<'a> Deref for MyPtr<'a> { + type Target = usize; + + fn deref<'b>(&'b self) -> &'b usize { self.0 } +} + +trait Tr { + fn poke(&self, s: &mut usize); +} + +impl Tr for usize { + fn poke(&self, s: &mut usize) { + *s = 2; + } +} + +fn main() { + let s = &mut 1; + + MyPtr(s).poke(s); +// { dg-error ".E0499." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18576.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18576.rs new file mode 100644 index 000000000000..5e6c4b503c2a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18576.rs @@ -0,0 +1,17 @@ +// run-fail +// error-pattern:stop +// ignore-emscripten no processes + +// #18576 +// Make sure that calling an extern function pointer in an unreachable +// context doesn't cause an LLVM assertion + +#[allow(unreachable_code)] +fn main() { + panic!("stop"); + let pointer = other; + pointer(); +} + +extern "C" fn other() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18611.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18611.rs new file mode 100644 index 000000000000..d13a3221932e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18611.rs @@ -0,0 +1,10 @@ +fn add_state(op: ::State) { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +trait HasState { + type State; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18652.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18652.rs new file mode 100644 index 000000000000..c0395d5fc7ea --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18652.rs @@ -0,0 +1,11 @@ +// run-pass +// Tests multiple free variables being passed by value into an unboxed +// once closure as an optimization by codegen. This used to hit an +// incorrect assert. + +fn main() { + let x = 2u8; + let y = 3u8; + assert_eq!((move || x + y)(), 5); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18655.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18655.rs new file mode 100644 index 000000000000..8d60626446ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18655.rs @@ -0,0 +1,23 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-1866.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1866.rs new file mode 100644 index 000000000000..4633e9bba926 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1866.rs @@ -0,0 +1,30 @@ +// build-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] +#![warn(clashing_extern_declarations)] + +// pretty-expanded FIXME #23616 + +mod a { + pub type rust_task = usize; + pub mod rustrt { + use super::rust_task; + extern { + pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool; + } + } +} + +mod b { + pub type rust_task = bool; + pub mod rustrt { + use super::rust_task; + extern { + pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool; +// { dg-warning "" "" { target *-*-* } .-1 } + } + } +} + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18661.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18661.rs new file mode 100644 index 000000000000..b75c52eebe25 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18661.rs @@ -0,0 +1,20 @@ +// run-pass +// Test that param substitutions from the correct environment are +// used when codegenning unboxed closure calls. + +// pretty-expanded FIXME #23616 + +pub fn inside(c: F) { + c(); +} + +// Use different number of type parameters and closure type to trigger +// an obvious ICE when param environments are mixed up +pub fn outside() { + inside(|| {}); +} + +fn main() { + outside::<(),()>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18685.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18685.rs new file mode 100644 index 000000000000..f1faf6ce96ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18685.rs @@ -0,0 +1,22 @@ +// run-pass +// Test that the self param space is not used in a conflicting +// manner by unboxed closures within a default method on a trait + +// pretty-expanded FIXME #23616 + +trait Tr { + fn foo(&self); + + fn bar(&self) { + (|| { self.foo() })() + } +} + +impl Tr for () { + fn foo(&self) {} +} + +fn main() { + ().bar(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1871.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1871.rs new file mode 100644 index 000000000000..2b508f099f39 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1871.rs @@ -0,0 +1,13 @@ +// Tests that we don't generate a spurious error about f.honk's type +// being undeterminable +fn main() { + let f = 42; + + let _g = if f < 5 { + f.honk() // { dg-error ".E0599." "" { target *-*-* } } + } + else { + () + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18711.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18711.rs new file mode 100644 index 000000000000..aef6671c9ea1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18711.rs @@ -0,0 +1,13 @@ +// run-pass +// Test that we don't panic on a RefCell borrow conflict in certain +// code paths involving unboxed closures. + +// pretty-expanded FIXME #23616 + +// aux-build:issue-18711.rs +extern crate issue_18711 as issue; + +fn main() { + (|| issue::inner(()))(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18738.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18738.rs new file mode 100644 index 000000000000..4231b1482e53 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18738.rs @@ -0,0 +1,18 @@ +// check-pass +#![allow(dead_code)] +#[derive(Eq, PartialEq, PartialOrd, Ord)] +enum Test<'a> { + Int(&'a isize), + Slice(&'a [u8]), +} + +#[derive(Eq, PartialEq, PartialOrd, Ord)] +struct Version { + vendor_info: &'static str +} + +#[derive(Eq, PartialEq, PartialOrd, Ord)] +struct Foo(&'static str); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18767.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18767.rs new file mode 100644 index 000000000000..c71ebb1b5596 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18767.rs @@ -0,0 +1,11 @@ +// run-pass +// Test that regionck uses the right memcat for patterns in for loops +// and doesn't ICE. + + +fn main() { + for &&x in Some(&0_usize).iter() { + assert_eq!(x, 0) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18783.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18783.rs new file mode 100644 index 000000000000..8e1fc25426e8 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18783.rs @@ -0,0 +1,29 @@ +use std::cell::RefCell; + +fn main() { + let mut y = 1; + let c = RefCell::new(vec![]); + c.push(Box::new(|| y = 0)); + c.push(Box::new(|| y = 0)); +// { dg-error ".E0499." "" { target *-*-* } .-1 } +} + +fn ufcs() { + let mut y = 1; + let c = RefCell::new(vec![]); + + Push::push(&c, Box::new(|| y = 0)); + Push::push(&c, Box::new(|| y = 0)); +// { dg-error ".E0499." "" { target *-*-* } .-1 } +} + +trait Push<'c> { + fn push<'f: 'c>(&self, push: Box); +} + +impl<'c> Push<'c> for RefCell>> { + fn push<'f: 'c>(&self, fun: Box) { + self.borrow_mut().push(fun) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18804/auxiliary/lib.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18804/auxiliary/lib.rs new file mode 100644 index 000000000000..699d6d0a1c1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18804/auxiliary/lib.rs @@ -0,0 +1,11 @@ +#![crate_type = "rlib"] +#![feature(linkage)] + +pub fn foo() -> *const() { + extern { + #[linkage = "extern_weak"] + static FOO: *const(); + } + unsafe { FOO } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18804/main.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18804/main.rs new file mode 100644 index 000000000000..1943277b7dc3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18804/main.rs @@ -0,0 +1,20 @@ +// run-pass +// Test for issue #18804, #[linkage] does not propagate through generic +// functions. Failure results in a linker error. + +// ignore-asmjs no weak symbol support +// ignore-emscripten no weak symbol support +// ignore-windows no extern_weak linkage +// ignore-macos no extern_weak linkage + +// aux-build:lib.rs + +// rust-lang/rust#56772: nikic says we need this to be proper test. +// compile-flags: -C no-prepopulate-passes -C passes=name-anon-globals + +extern crate lib; + +fn main() { + lib::foo::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18809.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18809.rs new file mode 100644 index 000000000000..5a2466e34824 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18809.rs @@ -0,0 +1,13 @@ +// check-pass +trait Tup { + type T0; + type T1; +} + +impl Tup for isize { + type T0 = f32; + type T1 = (); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18819.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18819.rs new file mode 100644 index 000000000000..744ec13ac102 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18819.rs @@ -0,0 +1,19 @@ +trait Foo { + type Item; +} + +struct X; + +impl Foo for X { + type Item = bool; +} + +fn print_x(_: &dyn Foo, extra: &str) { + println!("{}", extra); +} + +fn main() { + print_x(X); +// { dg-error ".E0061." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18845.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18845.rs new file mode 100644 index 000000000000..02cf0c77a2b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18845.rs @@ -0,0 +1,17 @@ +// run-pass +// This used to generate invalid IR in that even if we took the +// `false` branch we'd still try to free the Box from the other +// arm. This was due to treating `*Box::new(9)` as an rvalue datum +// instead of as a place. + +fn test(foo: bool) -> u8 { + match foo { + true => *Box::new(9), + false => 0 + } +} + +fn main() { + assert_eq!(9, test(true)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18859.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18859.rs new file mode 100644 index 000000000000..cbe718896a1f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18859.rs @@ -0,0 +1,17 @@ +// run-pass + +mod foo { + pub mod bar { + pub mod baz { + pub fn name() -> &'static str { + module_path!() + } + } + } +} + +fn main() { + assert_eq!(module_path!(), "issue_18859"); + assert_eq!(foo::bar::baz::name(), "issue_18859::foo::bar::baz"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18906.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18906.rs new file mode 100644 index 000000000000..2a38ac40efda --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18906.rs @@ -0,0 +1,31 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +pub trait Borrow { + fn borrow(&self) -> &Borrowed; +} + +impl Borrow for T { + fn borrow(&self) -> &T { self } +} + +trait Foo { + fn foo(&self, other: &Self); +} + +fn bar(k: &K, q: &Q) where K: Borrow, Q: Foo { + q.foo(k.borrow()) +} + +struct MyTree(K); + +impl MyTree { + // This caused a failure in #18906 + fn bar(k: &K, q: &Q) where K: Borrow, Q: Foo { + q.foo(k.borrow()) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18913.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18913.rs new file mode 100644 index 000000000000..ab475a919099 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18913.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:issue-18913-1.rs +// aux-build:issue-18913-2.rs + +extern crate foo; + +fn main() { + assert_eq!(foo::foo(), 1); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18919.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18919.rs new file mode 100644 index 000000000000..34de075a96df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18919.rs @@ -0,0 +1,13 @@ +type FuncType<'f> = dyn Fn(&isize) -> isize + 'f; + +fn ho_func(f: Option) { +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +enum Option { + Some(T), + None, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18937-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18937-1.rs new file mode 100644 index 000000000000..516b3db6cd00 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18937-1.rs @@ -0,0 +1,22 @@ +// run-pass +// Test that we are able to type-check this example. In particular, +// knowing that `T: 'a` allows us to deduce that `[U]: 'a` (because +// when `T=[U]` it implies that `U: 'a`). +// +// Regr. test for live code we found in the wild when fixing #18937. + +pub trait Leak { + fn leak<'a>(self) -> &'a T where T: 'a; +} + +impl Leak<[U]> for Vec { + fn leak<'a>(mut self) -> &'a [U] where [U]: 'a { + let r: *mut [U] = &mut self[..]; + std::mem::forget(self); + unsafe { &mut *r } + } +} +fn main() { + println!("Hello, world!"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18937.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18937.rs new file mode 100644 index 000000000000..1d23d3e92f2e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18937.rs @@ -0,0 +1,41 @@ +// Regression test for #18937. + +use std::fmt; + +#[derive(Debug)] +struct MyString<'a>(&'a String); + +struct B { + list: Vec>, +} + +trait A<'a> { + fn foo(&mut self, f: F) + where F: fmt::Debug + 'a, + Self: Sized; +} + +impl<'a> A<'a> for B { + fn foo(&mut self, f: F) // { dg-error ".E0276." "" { target *-*-* } } + where F: fmt::Debug + 'static, + { + self.list.push(Box::new(f)); + } +} + +fn main() { + let mut b = B { list: Vec::new() }; + + // Create a borrowed pointer, put it in `b`, then drop what's borrowing it + let a = "hello".to_string(); + b.foo(MyString(&a)); + + // Drop the data which `b` has a reference to + drop(a); + + // Use the data, probably segfaulting + for b in b.list.iter() { + println!("{:?}", b); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18952.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18952.rs new file mode 100644 index 000000000000..4fd62ff6de62 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18952.rs @@ -0,0 +1,57 @@ +// This issue tests fn_traits overloading on arity. +// run-pass + +#![feature(fn_traits)] +#![feature(unboxed_closures)] + +struct Foo; + +impl Fn<(isize, isize)> for Foo { + extern "rust-call" fn call(&self, args: (isize, isize)) -> Self::Output { + println!("{:?}", args); + (args.0 + 1, args.1 + 1) + } +} + +impl FnMut<(isize, isize)> for Foo { + extern "rust-call" fn call_mut(&mut self, args: (isize, isize)) -> Self::Output { + println!("{:?}", args); + (args.0 + 1, args.1 + 1) + } +} + +impl FnOnce<(isize, isize)> for Foo { + type Output = (isize, isize); + extern "rust-call" fn call_once(self, args: (isize, isize)) -> Self::Output { + println!("{:?}", args); + (args.0 + 1, args.1 + 1) + } +} + +impl Fn<(isize, isize, isize)> for Foo { + extern "rust-call" fn call(&self, args: (isize, isize, isize)) -> Self::Output { + println!("{:?}", args); + (args.0 + 3, args.1 + 3, args.2 + 3) + } +} + +impl FnMut<(isize, isize, isize)> for Foo { + extern "rust-call" fn call_mut(&mut self, args: (isize, isize, isize)) -> Self::Output { + println!("{:?}", args); + (args.0 + 3, args.1 + 3, args.2 + 3) + } +} +impl FnOnce<(isize, isize, isize)> for Foo { + type Output = (isize, isize, isize); + extern "rust-call" fn call_once(self, args: (isize, isize, isize)) -> Self::Output { + println!("{:?}", args); + (args.0 + 3, args.1 + 3, args.2 + 3) + } +} + +fn main() { + let foo = Foo; + assert_eq!(foo(1, 1), (2, 2)); + assert_eq!(foo(1, 1, 1), (4, 4, 4)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18959.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18959.rs new file mode 100644 index 000000000000..217d456d3f2f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18959.rs @@ -0,0 +1,21 @@ +pub trait Foo { fn foo(&self, ext_thing: &T); } +pub trait Bar: Foo { } +impl Bar for T { } + +pub struct Thing; +impl Foo for Thing { + fn foo(&self, _: &T) {} +} + +#[inline(never)] +fn foo(b: &dyn Bar) { +// { dg-error ".E0038." "" { target *-*-* } .-1 } + b.foo(&0) +} + +fn main() { + let mut thing = Thing; + let test: &dyn Bar = &mut thing; + foo(test); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-18988.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-18988.rs new file mode 100644 index 000000000000..d217e2176760 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-18988.rs @@ -0,0 +1,12 @@ +// check-pass +#![allow(dead_code)] +pub trait Foo : Send { } + +pub struct MyFoo { + children: Vec>, +} + +impl Foo for MyFoo { } + +pub fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1900.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1900.rs new file mode 100644 index 000000000000..4ec3c0eb799e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1900.rs @@ -0,0 +1,3 @@ +fn main() { } +// { dg-error ".E0131." "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19001.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19001.rs new file mode 100644 index 000000000000..25906a30f2da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19001.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +// check that we handle recursive arrays correctly in `type_of` + +struct Loopy { + ptr: *mut [Loopy; 1] +} + +fn main() { + let _t = Loopy { ptr: core::ptr::null_mut() }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19037.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19037.rs new file mode 100644 index 000000000000..baa369a63b7c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19037.rs @@ -0,0 +1,21 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct Str([u8]); + +#[derive(Clone)] +struct CharSplits<'a, Sep> { + string: &'a Str, + sep: Sep, + allow_trailing_empty: bool, + only_ascii: bool, + finished: bool, +} + +fn clone(s: &Str) -> &Str { + Clone::clone(&s) +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19081.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19081.rs new file mode 100644 index 000000000000..e0150be0e4e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19081.rs @@ -0,0 +1,15 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-19086.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19086.rs new file mode 100644 index 000000000000..15bdc2609fab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19086.rs @@ -0,0 +1,14 @@ +use Foo::FooB; + +enum Foo { + FooB { x: i32, y: i32 } +} + +fn main() { + let f = FooB { x: 3, y: 4 }; + match f { + FooB(a, b) => println!("{} {}", a, b), +// { dg-error ".E0532." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19097.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19097.rs new file mode 100644 index 000000000000..d861d233cbbd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19097.rs @@ -0,0 +1,15 @@ +// check-pass +#![allow(dead_code)] +// regression test for #19097 + +struct Foo(T); + +impl<'a, T> Foo<&'a T> { + fn foo(&self) {} +} +impl<'a, T> Foo<&'a mut T> { + fn foo(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19098.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19098.rs new file mode 100644 index 000000000000..5a2d675f2f14 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19098.rs @@ -0,0 +1,13 @@ +// check-pass +pub trait Handler { + fn handle(&self, _: &mut String); +} + +impl Handler for F where F: for<'a, 'b> Fn(&'a mut String) { + fn handle(&self, st: &mut String) { + self(st) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19100.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19100.rs new file mode 100644 index 000000000000..184bb748d39d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19100.rs @@ -0,0 +1,31 @@ +// run-pass +// run-rustfix + +#![allow(non_snake_case)] +#![allow(dead_code)] +#![allow(unused_variables)] + +#[derive(Copy, Clone)] +enum Foo { + Bar, + Baz +} + +impl Foo { + fn foo(&self) { + match self { + & +Bar if true +// { dg-warning "" "" { target *-*-* } .-1 } +=> println!("bar"), + & +Baz if false +// { dg-warning "" "" { target *-*-* } .-1 } +=> println!("baz"), +_ => () + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19102.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19102.rs new file mode 100644 index 000000000000..e903da0946a6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19102.rs @@ -0,0 +1,13 @@ +// check-pass +#![allow(unused_imports)] +#![deny(unused_qualifications)] + +use self::A::B; + +#[derive(PartialEq)] +pub enum A { + B, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19127.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19127.rs new file mode 100644 index 000000000000..aeffb3e8f466 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19127.rs @@ -0,0 +1,11 @@ +// run-pass +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +fn foo T>(f: F) {} +fn id<'a>(input: &'a u8) -> &'a u8 { input } + +fn main() { + foo(id); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19129-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19129-1.rs new file mode 100644 index 000000000000..e921830baee9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19129-1.rs @@ -0,0 +1,17 @@ +// check-pass +// pretty-expanded FIXME #23616 + +trait Trait { + type Output; + + fn method() -> >::Output; +} + +impl Trait for () { + type Output = (); + + fn method() {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19129-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19129-2.rs new file mode 100644 index 000000000000..0cb7b8128ab6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19129-2.rs @@ -0,0 +1,12 @@ +// check-pass +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +trait Trait { + type Output; + + fn method(&self, i: Input) -> bool { false } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19135.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19135.rs new file mode 100644 index 000000000000..af27eb8ba479 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19135.rs @@ -0,0 +1,14 @@ +// run-pass +use std::marker::PhantomData; + +#[derive(Debug)] +struct LifetimeStruct<'a>(PhantomData<&'a ()>); + +fn main() { + takes_hrtb_closure(|lts| println!("{:?}", lts)); +} + +fn takes_hrtb_closureFnMut(LifetimeStruct<'a>)>(mut f: F) { + f(LifetimeStruct(PhantomData)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19163.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19163.rs new file mode 100644 index 000000000000..6fc47e931406 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19163.rs @@ -0,0 +1,12 @@ +// aux-build:issue-19163.rs + +#[macro_use] extern crate issue_19163; + +use std::io::Write; + +fn main() { + let mut v = vec![]; + mywrite!(&v, "Hello world"); +// { dg-error ".E0596." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1920-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1920-1.rs new file mode 100644 index 000000000000..6cf485b49f33 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1920-1.rs @@ -0,0 +1,15 @@ +//! Test that absolute path names are correct when a crate is not linked into the root namespace + +// aux-build:issue-1920.rs + +mod foo { + pub extern crate issue_1920; +} + +fn assert_clone() where T : Clone { } + +fn main() { + assert_clone::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1920-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1920-2.rs new file mode 100644 index 000000000000..85d64a919818 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1920-2.rs @@ -0,0 +1,13 @@ +//! Test that when a crate is linked under another name that name is used in global paths + +// aux-build:issue-1920.rs + +extern crate issue_1920 as bar; + +fn assert_clone() where T : Clone { } + +fn main() { + assert_clone::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1920-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1920-3.rs new file mode 100644 index 000000000000..e0f84af6a804 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1920-3.rs @@ -0,0 +1,17 @@ +//! Test that when a crate is linked multiple times that the shortest absolute path name is used + +// aux-build:issue-1920.rs + +mod foo { + pub extern crate issue_1920; +} + +extern crate issue_1920; + +fn assert_clone() where T : Clone { } + +fn main() { + assert_clone::(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19244-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19244-1.rs new file mode 100644 index 000000000000..124104b3bf23 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19244-1.rs @@ -0,0 +1,7 @@ +const TUP: (usize,) = (42,); + +fn main() { + let a: [isize; TUP.1]; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19244-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19244-2.rs new file mode 100644 index 000000000000..e80f95bfef2e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19244-2.rs @@ -0,0 +1,8 @@ +struct MyStruct { field: usize } +const STRUCT: MyStruct = MyStruct { field: 42 }; + +fn main() { + let a: [isize; STRUCT.nonexistent_field]; +// { dg-error ".E0609." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19244.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19244.rs new file mode 100644 index 000000000000..e5e8934dd539 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19244.rs @@ -0,0 +1,35 @@ +// run-pass + +struct MyStruct { field: usize } +struct Nested { nested: MyStruct } +struct Mix2 { nested: ((usize,),) } + +const STRUCT: MyStruct = MyStruct { field: 42 }; +const TUP: (usize,) = (43,); +const NESTED_S: Nested = Nested { nested: MyStruct { field: 5 } }; +const NESTED_T: ((usize,),) = ((4,),); +const MIX_1: ((Nested,),) = ((Nested { nested: MyStruct { field: 3 } },),); +const MIX_2: Mix2 = Mix2 { nested: ((2,),) }; +const INSTANT_1: usize = (MyStruct { field: 1 }).field; +const INSTANT_2: usize = (0,).0; + +fn main() { + let a = [0; STRUCT.field]; + let b = [0; TUP.0]; + let c = [0; NESTED_S.nested.field]; + let d = [0; (NESTED_T.0).0]; + let e = [0; (MIX_1.0).0.nested.field]; + let f = [0; (MIX_2.nested.0).0]; + let g = [0; INSTANT_1]; + let h = [0; INSTANT_2]; + + assert_eq!(a.len(), 42); + assert_eq!(b.len(), 43); + assert_eq!(c.len(), 5); + assert_eq!(d.len(), 4); + assert_eq!(e.len(), 3); + assert_eq!(f.len(), 2); + assert_eq!(g.len(), 1); + assert_eq!(h.len(), 0); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19293.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19293.rs new file mode 100644 index 000000000000..c5002f86a702 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19293.rs @@ -0,0 +1,11 @@ +// run-pass +// aux-build:issue-19293.rs +// pretty-expanded FIXME #23616 + +extern crate issue_19293; +use issue_19293::{Foo, MyEnum}; + +fn main() { + MyEnum::Foo(Foo(5)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19340-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19340-1.rs new file mode 100644 index 000000000000..34701c652d96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19340-1.rs @@ -0,0 +1,18 @@ +// run-pass +#![allow(unused_variables)] +// aux-build:issue-19340-1.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_19340_1 as lib; + +use lib::Homura; + +fn main() { + let homura = Homura::Madoka { name: "Kaname".to_string() }; + + match homura { + Homura::Madoka { name } => (), + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19340-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19340-2.rs new file mode 100644 index 000000000000..866b702c3816 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19340-2.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +enum Homura { + Madoka { + name: String, + age: u32, + }, +} + +fn main() { + let homura = Homura::Madoka { + name: "Akemi".to_string(), + age: 14, + }; + + match homura { + Homura::Madoka { + name, + age, + } => (), + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19358.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19358.rs new file mode 100644 index 000000000000..9942ddb5e256 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19358.rs @@ -0,0 +1,21 @@ +// run-pass +trait Trait { fn dummy(&self) { } } + +#[derive(Debug)] +struct Foo { + foo: T, +} + +#[derive(Debug)] +struct Bar where T: Trait { + bar: T, +} + +impl Trait for isize {} + +fn main() { + let a = Foo { foo: 12 }; + let b = Bar { bar: 12 }; + println!("{:?} {:?}", a, b); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19367.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19367.rs new file mode 100644 index 000000000000..d5cb8e7c57a0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19367.rs @@ -0,0 +1,33 @@ +// run-pass +struct S { + o: Option +} + +// Make sure we don't reuse the same alloca when matching +// on field of struct or tuple which we reassign in the match body. + +fn main() { + let mut a = (0, Some("right".to_string())); + let b = match a.1 { + Some(v) => { + a.1 = Some("wrong".to_string()); + v + } + None => String::new() + }; + println!("{}", b); + assert_eq!(b, "right"); + + + let mut s = S{ o: Some("right".to_string()) }; + let b = match s.o { + Some(v) => { + s.o = Some("wrong".to_string()); + v + } + None => String::new(), + }; + println!("{}", b); + assert_eq!(b, "right"); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19380.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19380.rs new file mode 100644 index 000000000000..95df129a01cf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19380.rs @@ -0,0 +1,19 @@ +trait Qiz { + fn qiz(); +} + +struct Foo; +impl Qiz for Foo { + fn qiz() {} +} + +struct Bar { + foos: &'static [&'static (dyn Qiz + 'static)] +// { dg-error ".E0038." "" { target *-*-* } .-1 } +} + +const FOO : Foo = Foo; +const BAR : Bar = Bar { foos: &[&FOO]}; + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19398.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19398.rs new file mode 100644 index 000000000000..f553325186c4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19398.rs @@ -0,0 +1,13 @@ +// check-pass +// pretty-expanded FIXME #23616 + +trait T { + unsafe extern "Rust" fn foo(&self); +} + +impl T for () { + unsafe extern "Rust" fn foo(&self) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19404.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19404.rs new file mode 100644 index 000000000000..ce8a4724d244 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19404.rs @@ -0,0 +1,38 @@ +// build-pass +#![allow(dead_code)] +#![allow(unused_variables)] +use std::any::TypeId; +use std::rc::Rc; + +type Fp = Rc; + +struct Engine; + +trait Component: 'static {} +impl Component for Engine {} + +trait Env { + fn get_component_type_id(&self, type_id: TypeId) -> Option>; +} + +impl<'a> dyn Env + 'a { + fn get_component(&self) -> Option> { + let x = self.get_component_type_id(TypeId::of::()); + None + } +} + +trait Figment { + fn init(&mut self, env: &dyn Env); +} + +struct MyFigment; + +impl Figment for MyFigment { + fn init(&mut self, env: &dyn Env) { + let engine = env.get_component::(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19479.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19479.rs new file mode 100644 index 000000000000..ee759de68752 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19479.rs @@ -0,0 +1,20 @@ +// check-pass +// pretty-expanded FIXME #23616 + +trait Base { + fn dummy(&self) { } +} +trait AssocA { + type X: Base; + fn dummy(&self) { } +} +trait AssocB { + type Y: Base; + fn dummy(&self) { } +} +impl AssocB for T { + type Y = ::X; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19482.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19482.rs new file mode 100644 index 000000000000..685c1c1c4c44 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19482.rs @@ -0,0 +1,14 @@ +// Test that a partially specified trait object with unspecified associated +// type does not type-check. + +trait Foo { + type A; + + fn dummy(&self) { } +} + +fn bar(x: &dyn Foo) {} +// { dg-error ".E0191." "" { target *-*-* } .-1 } + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19498.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19498.rs new file mode 100644 index 000000000000..5bd7d60484eb --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19498.rs @@ -0,0 +1,14 @@ +use self::A; +use self::B; +mod A {} // { dg-error ".E0255." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +pub mod B {} // { dg-error ".E0255." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +mod C { + use C::D; + mod D {} // { dg-error ".E0255." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19499.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19499.rs new file mode 100644 index 000000000000..e1b295f1203b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19499.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(path_statements)] +#![allow(unused_variables)] +// Regression test for issue #19499. Due to incorrect caching of trait +// results for closures with upvars whose types were not fully +// computed, this rather bizarre little program (along with many more +// reasonable examples) let to ambiguity errors about not being able +// to infer sufficient type information. + +// pretty-expanded FIXME #23616 + +fn main() { + let n = 0; + let it = Some(1_usize).into_iter().inspect(|_| {n;}); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19521.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19521.rs new file mode 100644 index 000000000000..d9f3e01c53b2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19521.rs @@ -0,0 +1,4 @@ +fn main() { + "".homura()(); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19538.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19538.rs new file mode 100644 index 000000000000..be412fb835cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19538.rs @@ -0,0 +1,21 @@ +trait Foo { + fn foo(&self, val: T); +} + +trait Bar: Foo { } + +pub struct Thing; + +impl Foo for Thing { + fn foo(&self, val: T) { } +} + +impl Bar for Thing { } + +fn main() { + let mut thing = Thing; + let test: &mut dyn Bar = &mut thing; +// { dg-error ".E0038." "" { target *-*-* } .-1 } +// { dg-error ".E0038." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19601.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19601.rs new file mode 100644 index 000000000000..603bacb9e4a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19601.rs @@ -0,0 +1,7 @@ +// check-pass + +trait A {} +struct B where B: A> { t: T } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1962.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1962.rs new file mode 100644 index 000000000000..8d27d82a517f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1962.rs @@ -0,0 +1,11 @@ +// compile-flags: -D while-true +// run-rustfix + +fn main() { + let mut i = 0; + while true { // { dg-error "" "" { target *-*-* } } + i += 1; + if i == 5 { break; } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19631.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19631.rs new file mode 100644 index 000000000000..aeeb665b4466 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19631.rs @@ -0,0 +1,17 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait PoolManager { + type C; + fn dummy(&self) { } +} + +struct InnerPool { + manager: M, +} + +impl InnerPool where M: PoolManager {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19632.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19632.rs new file mode 100644 index 000000000000..79c57e19354e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19632.rs @@ -0,0 +1,15 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait PoolManager { + type C; + fn dummy(&self) { } +} + +struct InnerPool { + manager: M, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19660.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19660.rs new file mode 100644 index 000000000000..09cead11eaae --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19660.rs @@ -0,0 +1,16 @@ +// error-pattern: requires `copy` lang_item + +#![feature(lang_items, start, no_core)] +#![no_core] + +#[lang = "sized"] +trait Sized { } + +struct S; + +#[start] +fn main(_: isize, _: *const *const u8) -> isize { + let _ = S; + 0 +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19692.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19692.rs new file mode 100644 index 000000000000..c2e807078fd0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19692.rs @@ -0,0 +1,9 @@ +struct Homura; + +fn akemi(homura: Homura) { + let Some(ref madoka) = Some(homura.kaname()); // { dg-error ".E0599." "" { target *-*-* } } + madoka.clone(); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19707.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19707.rs new file mode 100644 index 000000000000..38a41c22e379 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19707.rs @@ -0,0 +1,8 @@ +#![allow(dead_code)] + +type Foo = fn(&u8, &u8) -> &u8; // { dg-error ".E0106." "" { target *-*-* } } + +fn bar &u8>(f: &F) {} // { dg-error ".E0106." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19734.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19734.rs new file mode 100644 index 000000000000..b3a59c8d08f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19734.rs @@ -0,0 +1,9 @@ +fn main() {} + +struct Type; + +impl Type { + undef!(); +// { dg-error "" "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-1974.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-1974.rs new file mode 100644 index 000000000000..84fbf9ea6d1d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-1974.rs @@ -0,0 +1,12 @@ +// run-pass +// Issue 1974 +// Don't double free the condition allocation +// pretty-expanded FIXME #23616 + +pub fn main() { + let s = "hej".to_string(); + while s != "".to_string() { + return; + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19811-escape-unicode.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19811-escape-unicode.rs new file mode 100644 index 000000000000..e8d4c7b920f4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19811-escape-unicode.rs @@ -0,0 +1,10 @@ +// run-pass + +fn main() { + let mut escaped = String::from(""); + for c in '\u{10401}'.escape_unicode() { + escaped.push(c); + } + assert_eq!("\\u{10401}", escaped); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19850.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19850.rs new file mode 100644 index 000000000000..616d423a2a13 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19850.rs @@ -0,0 +1,23 @@ +// check-pass +#![allow(unused_variables)] +// Test that `::Output` and `Self::Output` are accepted as type annotations in let +// bindings + +// pretty-expanded FIXME #23616 + +trait Int { + fn one() -> Self; + fn leading_zeros(self) -> usize; +} + +trait Foo { + type T : Int; + + fn test(&self) { + let r: ::T = Int::one(); + let r: Self::T = Int::one(); + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19883.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19883.rs new file mode 100644 index 000000000000..fbef21f4d584 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19883.rs @@ -0,0 +1,17 @@ +trait From { + type Output; + + fn from(src: Src) -> >::Output; +} + +trait To: Sized { + fn to>(self) -> + >::Dst +// { dg-error ".E0576." "" { target *-*-* } .-1 } + { + From::from(self) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19922.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19922.rs new file mode 100644 index 000000000000..cc012fc96364 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19922.rs @@ -0,0 +1,9 @@ +enum Homura { + Akemi { madoka: () } +} + +fn main() { + let homura = Homura::Akemi { kaname: () }; +// { dg-error ".E0559." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19982.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19982.rs new file mode 100644 index 000000000000..d608aae950f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19982.rs @@ -0,0 +1,23 @@ +// check-pass + +#![feature(fn_traits, unboxed_closures)] + +#[allow(dead_code)] +struct Foo; + +impl Fn<(&(),)> for Foo { + extern "rust-call" fn call(&self, (_,): (&(),)) {} +} + +impl FnMut<(&(),)> for Foo { + extern "rust-call" fn call_mut(&mut self, (_,): (&(),)) {} +} + +impl FnOnce<(&(),)> for Foo { + type Output = (); + + extern "rust-call" fn call_once(self, (_,): (&(),)) {} +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-19991.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-19991.rs new file mode 100644 index 000000000000..f486d4cea692 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-19991.rs @@ -0,0 +1,10 @@ +// Test if the sugared if-let construct correctly prints "missing an else clause" when an else +// clause does not exist, instead of the unsympathetic "`match` arms have incompatible types" + +fn main() { + if let Some(homura) = Some("madoka") { // { dg-error ".E0317." "" { target *-*-* } } +// { dg-error "" "" { target *-*-* } .-2 } + 765 + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20005.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20005.rs new file mode 100644 index 000000000000..73a625c9aee6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20005.rs @@ -0,0 +1,16 @@ +trait From { + type Result; + + fn from(src: Src) -> Self::Result; +} + +trait To { + fn to( + self + ) -> >::Result where Dst: From { // { dg-error ".E0277." "" { target *-*-* } } + From::from(self) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20009.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20009.rs new file mode 100644 index 000000000000..c63276c538aa --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20009.rs @@ -0,0 +1,14 @@ +// check-pass +// Check that associated types are `Sized` + +// pretty-expanded FIXME #23616 + +trait Trait { + type Output; + + fn is_sized(&self) -> Self::Output; + fn wasnt_sized(&self) -> Self::Output { loop {} } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20055-box-trait.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20055-box-trait.rs new file mode 100644 index 000000000000..9d3cba3bf208 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20055-box-trait.rs @@ -0,0 +1,42 @@ +// run-pass +// See Issues #20055 and #21695. + +// We are checking here that the temporaries `Box<[i8, k]>`, for `k` +// in 1, 2, 3, 4, that are induced by the match expression are +// properly handled, in that only *one* will be initialized by +// whichever arm is run, and subsequently dropped at the end of the +// statement surrounding the `match`. + +trait Boo { + fn dummy(&self) { } +} + +impl Boo for [i8; 1] { } +impl Boo for [i8; 2] { } +impl Boo for [i8; 3] { } +impl Boo for [i8; 4] { } + +pub fn foo(box_1: fn () -> Box<[i8; 1]>, + box_2: fn () -> Box<[i8; 2]>, + box_3: fn () -> Box<[i8; 3]>, + box_4: fn () -> Box<[i8; 4]>, + ) { + println!("Hello World 1"); + let _: Box = match 3 { + 1 => box_1(), + 2 => box_2(), + 3 => box_3(), + _ => box_4(), + }; + println!("Hello World 2"); +} + +pub fn main() { + fn box_1() -> Box<[i8; 1]> { Box::new( [1; 1] ) } + fn box_2() -> Box<[i8; 2]> { Box::new( [1; 2] ) } + fn box_3() -> Box<[i8; 3]> { Box::new( [1; 3] ) } + fn box_4() -> Box<[i8; 4]> { Box::new( [1; 4] ) } + + foo(box_1, box_2, box_3, box_4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20055-box-unsized-array.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20055-box-unsized-array.rs new file mode 100644 index 000000000000..ffadb0535f71 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20055-box-unsized-array.rs @@ -0,0 +1,30 @@ +// run-pass +// Issue #2005: Check that boxed fixed-size arrays are properly +// accounted for (namely, only deallocated if they were actually +// created) when they appear as temporaries in unused arms of a match +// expression. + +pub fn foo(box_1: fn () -> Box<[i8; 1]>, + box_2: fn () -> Box<[i8; 20]>, + box_3: fn () -> Box<[i8; 300]>, + box_4: fn () -> Box<[i8; 4000]>, + ) { + println!("Hello World 1"); + let _: Box<[i8]> = match 3 { + 1 => box_1(), + 2 => box_2(), + 3 => box_3(), + _ => box_4(), + }; + println!("Hello World 2"); +} + +pub fn main() { + fn box_1() -> Box<[i8; 1]> { Box::new( [1] ) } + fn box_2() -> Box<[i8; 20]> { Box::new( [1; 20] ) } + fn box_3() -> Box<[i8; 300]> { Box::new( [1; 300] ) } + fn box_4() -> Box<[i8; 4000]> { Box::new( [1; 4000] ) } + + foo(box_1, box_2, box_3, box_4); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20091.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20091.rs new file mode 100644 index 000000000000..bde3d3d44df7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20091.rs @@ -0,0 +1,26 @@ +// run-pass +#![allow(stable_features)] + +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes + +#![feature(os)] + +#[cfg(unix)] +fn main() { + use std::process::Command; + use std::env; + use std::os::unix::prelude::*; + use std::ffi::OsStr; + + if env::args().len() == 1 { + assert!(Command::new(&env::current_exe().unwrap()) + .arg(::from_bytes(b"\xff")) + .status().unwrap().success()) + } +} + +#[cfg(windows)] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20162.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20162.rs new file mode 100644 index 000000000000..d2e6e0d4c34a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20162.rs @@ -0,0 +1,8 @@ +struct X { x: i32 } + +fn main() { + let mut b: Vec = vec![]; + b.sort(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20174.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20174.rs new file mode 100644 index 000000000000..9cc0ca3d45d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20174.rs @@ -0,0 +1,8 @@ +// run-pass +struct GradFn usize>(F); + +fn main() { + let GradFn(x_squared) : GradFn<_> = GradFn(|| -> usize { 2 }); + let _ = x_squared(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20186.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20186.rs new file mode 100644 index 000000000000..98eb0da8d6b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20186.rs @@ -0,0 +1,17 @@ +// check-pass +#![allow(dead_code)] +#![allow(unused_variables)] +struct Foo; + +impl Foo { + fn putc(&self, b: u8) { } + + fn puts(&self, s: &str) { + for byte in s.bytes() { + self.putc(byte) + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20225.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20225.rs new file mode 100644 index 000000000000..41adab784271 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20225.rs @@ -0,0 +1,23 @@ +#![feature(fn_traits, unboxed_closures)] + +struct Foo; + +impl<'a, T> Fn<(&'a T,)> for Foo { + extern "rust-call" fn call(&self, (_,): (T,)) {} +// { dg-error ".E0053." "" { target *-*-* } .-1 } +} + +impl<'a, T> FnMut<(&'a T,)> for Foo { + extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {} +// { dg-error ".E0053." "" { target *-*-* } .-1 } +} + +impl<'a, T> FnOnce<(&'a T,)> for Foo { + type Output = (); + + extern "rust-call" fn call_once(self, (_,): (T,)) {} +// { dg-error ".E0053." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20261.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20261.rs new file mode 100644 index 000000000000..1f5a9bbdc843 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20261.rs @@ -0,0 +1,8 @@ +fn main() { + // N.B., this (almost) typechecks when default binding modes are enabled. + for (ref i,) in [].iter() { + i.clone(); +// { dg-error ".E0282." "" { target *-*-* } .-1 } + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20313-rpass.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20313-rpass.rs new file mode 100644 index 000000000000..8d5e106dc3b7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20313-rpass.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#![feature(link_llvm_intrinsics)] + +extern { + #[link_name = "llvm.sqrt.f32"] + fn sqrt(x: f32) -> f32; +} + +fn main(){ +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20313.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20313.rs new file mode 100644 index 000000000000..6946e34c3104 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20313.rs @@ -0,0 +1,8 @@ +extern { + #[link_name = "llvm.sqrt.f32"] + fn sqrt(x: f32) -> f32; // { dg-error ".E0658." "" { target *-*-* } } +} + +fn main(){ +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20343.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20343.rs new file mode 100644 index 000000000000..81febc5b58f2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20343.rs @@ -0,0 +1,33 @@ +// run-pass +#![allow(unused_variables)] +// Regression test for Issue #20343. + +// pretty-expanded FIXME #23616 + +#![deny(dead_code)] + +struct B { b: u32 } +struct C; +struct D; + +trait T { fn dummy(&self, a: A) { } } +impl T for () {} + +impl B { + // test for unused code in arguments + fn foo(B { b }: B) -> u32 { b } + + // test for unused code in return type + fn bar() -> C { unsafe { ::std::mem::transmute(()) } } + + // test for unused code in generics + fn baz>() {} +} + +pub fn main() { + let b = B { b: 3 }; + B::foo(b); + B::bar(); + B::baz::<()>(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20389.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20389.rs new file mode 100644 index 000000000000..00e410f08895 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20389.rs @@ -0,0 +1,16 @@ +// run-pass +#![allow(dead_code)] +// aux-build:issue-20389.rs + +// pretty-expanded FIXME #23616 + +extern crate issue_20389; + +struct Foo; + +impl issue_20389::T for Foo { + type C = (); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20396.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20396.rs new file mode 100644 index 000000000000..1c2a9052bb22 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20396.rs @@ -0,0 +1,17 @@ +// check-pass +// pretty-expanded FIXME #23616 + +#![allow(dead_code)] + +trait Foo { + fn noop(&self, _: T); +} + +enum Bar { Bla(T) } + +struct Baz<'a> { + inner: dyn for<'b> Foo> + 'a, +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20413.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20413.rs new file mode 100644 index 000000000000..81d4530f3c36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20413.rs @@ -0,0 +1,17 @@ +trait Foo { + fn answer(self); +} + +struct NoData; +// { dg-error ".E0392." "" { target *-*-* } .-1 } + +impl Foo for T where NoData: Foo { +// { dg-error ".E0275." "" { target *-*-* } .-1 } +// { dg-error ".E0275." "" { target *-*-* } .-2 } + fn answer(self) { + let val: NoData = NoData; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20414.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20414.rs new file mode 100644 index 000000000000..c9e63cd356df --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20414.rs @@ -0,0 +1,22 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait Trait { + fn method(self) -> isize; +} + +struct Wrapper { + field: T +} + +impl<'a, T> Trait for &'a Wrapper where &'a T: Trait { + fn method(self) -> isize { + let r: &'a T = &self.field; + Trait::method(r); // these should both work + r.method() + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20427.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20427.rs new file mode 100644 index 000000000000..60c64a31a0e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20427.rs @@ -0,0 +1,89 @@ +// run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_imports)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] + +// aux-build:i8.rs +// ignore-pretty issue #37201 + +extern crate i8; +use std::string as i16; +static i32: i32 = 0; +const i64: i64 = 0; +fn u8(f32: f32) {} +fn f(f64: f64) {} +enum u32 {} +struct u64; +trait bool {} + +mod char { + extern crate i8; + static i32_: i32 = 0; + const i64_: i64 = 0; + fn u8_(f32: f32) {} + fn f_(f64: f64_) {} + type u16_ = u16; + enum u32_ {} + struct u64_; + trait bool_ {} + mod char_ {} + + mod str { + use super::i8 as i8; + use super::i32_ as i32; + use super::i64_ as i64; + use super::u8_ as u8; + use super::f_ as f64; + use super::u16_ as u16; + use super::u32_ as u32; + use super::u64_ as u64; + use super::bool_ as bool; + use super::{bool_ as str}; + use super::char_ as char; + } +} + +trait isize_ { + type isize; +} + +fn usize<'usize>(usize: &'usize usize) -> &'usize usize { usize } + +mod reuse { + use std::mem::size_of; + + type u8 = u64; + use std::string::String as i16; + + pub fn check() { + assert_eq!(size_of::(), 8); + assert_eq!(size_of::<::u64>(), 0); + assert_eq!(size_of::(), 3 * size_of::<*const ()>()); + assert_eq!(size_of::(), 0); + } +} + +mod guard { + pub fn check() { + use std::u8; // bring module u8 in scope + fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8 + u8::max_value() // OK, resolves to associated function ::max_value, + // not to non-existent std::u8::max_value + } + assert_eq!(f(), u8::MAX); // OK, resolves to std::u8::MAX + } +} + +fn main() { + let bool = true; + let _ = match bool { + str @ true => if str { i32 as i64 } else { i64 }, + false => i64, + }; + + reuse::check::(); + guard::check(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20433.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20433.rs new file mode 100644 index 000000000000..28877d1118ba --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20433.rs @@ -0,0 +1,9 @@ +fn main() {} + +struct The; + +impl The { + fn iceman(c: Vec<[i32]>) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20454.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20454.rs new file mode 100644 index 000000000000..8cfc85ffc4d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20454.rs @@ -0,0 +1,14 @@ +// check-pass +#![allow(unused_must_use)] +use std::thread; + +fn _foo() { + thread::spawn(move || { // no need for -> () + loop { + println!("hello"); + } + }).join(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20544.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20544.rs new file mode 100644 index 000000000000..e721c378af38 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20544.rs @@ -0,0 +1,19 @@ +// run-pass +#![feature(unboxed_closures)] +#![feature(fn_traits)] + +struct Fun(F); + +impl FnOnce<(T,)> for Fun where F: Fn(T) -> T { + type Output = T; + + extern "rust-call" fn call_once(self, (t,): (T,)) -> T { + (self.0)(t) + } +} + +fn main() { + let fun = Fun(|i: isize| i * 2); + println!("{}", fun(3)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20575.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20575.rs new file mode 100644 index 000000000000..8aa7cb638ec4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20575.rs @@ -0,0 +1,11 @@ +// run-pass +// Test that overloaded calls work with zero arity closures + +// pretty-expanded FIXME #23616 + +fn main() { + let functions: [Box Option<()>>; 1] = [Box::new(|| None)]; + + let _: Option> = functions.iter().map(|f| (*f)()).collect(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20605.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20605.rs new file mode 100644 index 000000000000..f39c0fb630bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20605.rs @@ -0,0 +1,7 @@ +fn changer<'a>(mut things: Box>) { + for item in *things { *item = 0 } +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20616-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-1.rs new file mode 100644 index 000000000000..653ce4bb4873 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-1.rs @@ -0,0 +1,37 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + + + +type Type_1_<'a, T> = &'a T; + + +type Type_1<'a T> = &'a T; // { dg-error "" "" { target *-*-* } } + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3 = Box; // error: expected type, found `,` + + +//type Type_4 = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9 = Box; // error: expected ident, found `,` + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20616-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-2.rs new file mode 100644 index 000000000000..8f74fcde4305 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-2.rs @@ -0,0 +1,37 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + + + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +type Type_2 = Type_1_<'static ()>; // { dg-error "" "" { target *-*-* } } + + +//type Type_3 = Box; // error: expected type, found `,` + + +//type Type_4 = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9 = Box; // error: expected ident, found `,` + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20616-3.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-3.rs new file mode 100644 index 000000000000..16aedee61f36 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-3.rs @@ -0,0 +1,36 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +type Type_3 = Box; +// { dg-error "" "" { target *-*-* } .-1 } + + +//type Type_4 = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9 = Box; // error: expected ident, found `,` + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20616-4.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-4.rs new file mode 100644 index 000000000000..ed4817f4f4f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-4.rs @@ -0,0 +1,36 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3 = Box; // error: expected type, found `,` + + +type Type_4 = Type_1_<'static,, T>; +// { dg-error "" "" { target *-*-* } .-1 } + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9 = Box; // error: expected ident, found `,` + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20616-5.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-5.rs new file mode 100644 index 000000000000..3e108b2b8df7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-5.rs @@ -0,0 +1,36 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3 = Box; // error: expected type, found `,` + + +//type Type_4 = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +type Type_5<'a> = Type_1_<'a, (),,>; +// { dg-error "" "" { target *-*-* } .-1 } + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9 = Box; // error: expected ident, found `,` + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20616-6.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-6.rs new file mode 100644 index 000000000000..5a57395ed4ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-6.rs @@ -0,0 +1,36 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3 = Box; // error: expected type, found `,` + + +//type Type_4 = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +type Type_6 = Type_5_<'a,,>; +// { dg-error "" "" { target *-*-* } .-1 } + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9 = Box; // error: expected ident, found `,` + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20616-7.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-7.rs new file mode 100644 index 000000000000..69d7f6019aa5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-7.rs @@ -0,0 +1,36 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3 = Box; // error: expected type, found `,` + + +//type Type_4 = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +type Type_7 = Box<(),,>; +// { dg-error "" "" { target *-*-* } .-1 } + + +//type Type_8<'a,,> = &'a (); // error: expected ident, found `,` + + +//type Type_9 = Box; // error: expected ident, found `,` + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20616-8.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-8.rs new file mode 100644 index 000000000000..fd0aba5b02c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-8.rs @@ -0,0 +1,36 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3 = Box; // error: expected type, found `,` + + +//type Type_4 = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +type Type_8<'a,,> = &'a (); +// { dg-error "" "" { target *-*-* } .-1 } + + +//type Type_9 = Box; // error: expected identifier, found `,` + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20616-9.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-9.rs new file mode 100644 index 000000000000..37dd19e04921 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20616-9.rs @@ -0,0 +1,36 @@ +// We need all these 9 issue-20616-N.rs files +// because we can only catch one parsing error at a time + +type Type_1_<'a, T> = &'a T; + + +//type Type_1<'a T> = &'a T; // error: expected `,` or `>` after lifetime name, found `T` + + +//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(` + + +//type Type_3 = Box; // error: expected type, found `,` + + +//type Type_4 = Type_1_<'static,, T>; // error: expected type, found `,` + + +type Type_5_<'a> = Type_1_<'a, ()>; + + +//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,` + + +//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,` + + +//type Type_7 = Box<(),,>; // error: expected type, found `,` + + +//type Type_8<'a,,> = &'a (); // error: expected identifier, found `,` + + +type Type_9 = Box; +// { dg-error "" "" { target *-*-* } .-1 } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20616.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20616.rs new file mode 100644 index 000000000000..177bac7c862f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20616.rs @@ -0,0 +1,45 @@ +// run-pass +#![allow(dead_code)] +type MyType<'a, T> = &'a T; + +// combine lifetime bounds and type arguments in usual way +type TypeA<'a> = MyType<'a, ()>; + +// ensure token `>>` works fine +type TypeB = Box>; +type TypeB_ = Box>; + +// trailing comma when combine lifetime bounds and type arguments +type TypeC<'a> = MyType<'a, (),>; + +// normal lifetime bounds +type TypeD = TypeA<'static>; + +// trailing comma on lifetime bounds +type TypeE = TypeA<'static,>; + +// normal type argument +type TypeF = Box; + +// type argument with trailing comma +type TypeG = Box; + +// trailing comma on lifetime defs +type TypeH<'a,> = &'a (); + +// trailing comma on type argument +type TypeI = T; + +static STATIC: () = (); + +fn main() { + + // ensure token `>=` works fine + let _: TypeA<'static>= &STATIC; + let _: TypeA<'static,>= &STATIC; + + // ensure token `>>=` works fine + let _: Box>= Box::new(&STATIC); + let _: Box>= Box::new(&STATIC); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2063-resource.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2063-resource.rs new file mode 100644 index 000000000000..5ed99580dc27 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2063-resource.rs @@ -0,0 +1,15 @@ +// check-pass +#![allow(dead_code)] +// test that autoderef of a type like this does not +// cause compiler to loop. Note that no instances +// of such a type could ever be constructed. + +struct S { + x: X, + to_str: (), +} + +struct X(Box); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2063.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2063.rs new file mode 100644 index 000000000000..c98845c4d754 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2063.rs @@ -0,0 +1,23 @@ +// run-pass +// test that autoderef of a type like this does not +// cause compiler to loop. Note that no instances +// of such a type could ever be constructed. + +struct T(Box); + +trait ToStr2 { + fn my_to_string(&self) -> String; +} + +impl ToStr2 for T { + fn my_to_string(&self) -> String { "t".to_string() } +} + +#[allow(dead_code)] +fn new_t(x: T) { + x.my_to_string(); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20644.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20644.rs new file mode 100644 index 000000000000..59641bad09dc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20644.rs @@ -0,0 +1,36 @@ +// build-pass +#![allow(dead_code)] +#![allow(unused_imports)] +#![allow(stable_features)] + +// A reduced version of the rustbook ice. The problem this encountered +// had to do with codegen ignoring binders. + +// pretty-expanded FIXME #23616 +// ignore-cloudabi no std::fs + +#![feature(os)] + +use std::iter; +use std::os; +use std::fs::File; +use std::io::prelude::*; +use std::env; +use std::path::Path; + +pub fn parse_summary(_: R, _: &Path) { + let path_from_root = Path::new(""); + Path::new(&iter::repeat("../") + .take(path_from_root.components().count() - 1) + .collect::()); + } + +fn foo() { + let cwd = env::current_dir().unwrap(); + let src = cwd.clone(); + let summary = File::open(&src.join("SUMMARY.md")).unwrap(); + let _ = parse_summary(summary, &src); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20676.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20676.rs new file mode 100644 index 000000000000..fd664ec25884 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20676.rs @@ -0,0 +1,13 @@ +// run-pass +// Regression test for #20676. Error was that we didn't support +// UFCS-style calls to a method in `Trait` where `Self` was bound to a +// trait object of type `Trait`. See also `ufcs-trait-object.rs`. + + +use std::fmt; + +fn main() { + let a: &dyn fmt::Debug = &1; + format!("{:?}", a); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20692.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20692.rs new file mode 100644 index 000000000000..fa81385a1934 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20692.rs @@ -0,0 +1,12 @@ +trait Array: Sized + Copy {} + +fn f(x: &T) { + let _ = x +// { dg-error ".E0038." "" { target *-*-* } .-1 } + as + &dyn Array; +// { dg-error ".E0038." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20714.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20714.rs new file mode 100644 index 000000000000..b7d3e37d323e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20714.rs @@ -0,0 +1,6 @@ +struct G; + +fn main() { + let g = G(); // { dg-error ".E0618." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2074.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2074.rs new file mode 100644 index 000000000000..ca55b24688e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2074.rs @@ -0,0 +1,17 @@ +// run-pass +// pretty-expanded FIXME #23616 + +#![allow(non_camel_case_types)] + +pub fn main() { + let one = || { + enum r { a }; + r::a as usize + }; + let two = || { + enum r { a }; + r::a as usize + }; + one(); two(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20763-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20763-1.rs new file mode 100644 index 000000000000..4663c30a9960 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20763-1.rs @@ -0,0 +1,30 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait T0 { + type O; + fn dummy(&self) { } +} + +struct S(A); +impl T0 for S { type O = A; } + +trait T1: T0 { + // this looks okay but as we see below, `f` is unusable + fn m0::O) -> bool>(self, f: F) -> bool; +} + +// complains about the bounds on F here not being required by the trait +impl T1 for S { + fn m0 bool>(self, f: F) -> bool { f(self.0) } +} + +// // complains about mismatched types: as T0>::O vs. A +// impl T1 for S +// { +// fn m0::O) -> bool>(self, f: F) -> bool { f(self.0) } +// } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20763-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20763-2.rs new file mode 100644 index 000000000000..0e2ed74c91d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20763-2.rs @@ -0,0 +1,25 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait T0 { + type O; + fn dummy(&self) { } +} + +struct S(A); +impl T0 for S { type O = A; } + +trait T1: T0 { + // this looks okay but as we see below, `f` is unusable + fn m0::O) -> bool>(self, f: F) -> bool; +} + +// complains about mismatched types: as T0>::O vs. A +impl T1 for S +{ + fn m0::O) -> bool>(self, f: F) -> bool { f(self.0) } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20772.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20772.rs new file mode 100644 index 000000000000..df538ba58e8e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20772.rs @@ -0,0 +1,6 @@ +trait T : Iterator +// { dg-error ".E0391." "" { target *-*-* } .-1 } +{} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20797.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20797.rs new file mode 100644 index 000000000000..217cfa3e1fc2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20797.rs @@ -0,0 +1,95 @@ +// build-pass +// ignore-cloudabi no std::fs + +// Regression test for #20797. + +use std::default::Default; +use std::io; +use std::fs; +use std::path::PathBuf; + +pub trait PathExtensions { + fn is_dir(&self) -> bool { false } +} + +impl PathExtensions for PathBuf {} + +/// A strategy for acquiring more subpaths to walk. +pub trait Strategy { + type P: PathExtensions; + /// Gets additional subpaths from a given path. + fn get_more(&self, item: &Self::P) -> io::Result>; + /// Determine whether a path should be walked further. + /// This is run against each item from `get_more()`. + fn prune(&self, p: &Self::P) -> bool; +} + +/// The basic fully-recursive strategy. Nothing is pruned. +#[derive(Copy, Clone, Default)] +pub struct Recursive; + +impl Strategy for Recursive { + type P = PathBuf; + fn get_more(&self, p: &PathBuf) -> io::Result> { + Ok(fs::read_dir(p).unwrap().map(|s| s.unwrap().path()).collect()) + } + + fn prune(&self, _: &PathBuf) -> bool { false } +} + +/// A directory walker of `P` using strategy `S`. +pub struct Subpaths { + stack: Vec, + strategy: S, +} + +impl Subpaths { + /// Creates a directory walker with a root path and strategy. + pub fn new(p: &S::P, strategy: S) -> io::Result> { + let stack = strategy.get_more(p)?; + Ok(Subpaths { stack: stack, strategy: strategy }) + } +} + +impl Subpaths { + /// Creates a directory walker with a root path and a default strategy. + pub fn walk(p: &S::P) -> io::Result> { + Subpaths::new(p, Default::default()) + } +} + +impl Default for Subpaths { + fn default() -> Subpaths { + Subpaths { stack: Vec::new(), strategy: Default::default() } + } +} + +impl Iterator for Subpaths { + type Item = S::P; + fn next (&mut self) -> Option { + let mut opt_path = self.stack.pop(); + while opt_path.is_some() && self.strategy.prune(opt_path.as_ref().unwrap()) { + opt_path = self.stack.pop(); + } + match opt_path { + Some(path) => { + if path.is_dir() { + let result = self.strategy.get_more(&path); + match result { + Ok(dirs) => { self.stack.extend(dirs); }, + Err(..) => { } + } + } + Some(path) + } + None => None, + } + } +} + +fn _foo() { + let _walker: Subpaths = Subpaths::walk(&PathBuf::from("/home")).unwrap(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20801.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20801.rs new file mode 100644 index 000000000000..514922296184 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20801.rs @@ -0,0 +1,38 @@ +// We used to ICE when moving out of a `*mut T` or `*const T`. + +struct T(u8); + +static mut GLOBAL_MUT_T: T = T(0); + +static GLOBAL_T: T = T(0); + +fn imm_ref() -> &'static T { + unsafe { &GLOBAL_T } +} + +fn mut_ref() -> &'static mut T { + unsafe { &mut GLOBAL_MUT_T } +} + +fn mut_ptr() -> *mut T { + unsafe { core::ptr::null_mut() } +} + +fn const_ptr() -> *const T { + unsafe { core::ptr::null() } +} + +pub fn main() { + let a = unsafe { *mut_ref() }; +// { dg-error ".E0507." "" { target *-*-* } .-1 } + + let b = unsafe { *imm_ref() }; +// { dg-error ".E0507." "" { target *-*-* } .-1 } + + let c = unsafe { *mut_ptr() }; +// { dg-error ".E0507." "" { target *-*-* } .-1 } + + let d = unsafe { *const_ptr() }; +// { dg-error ".E0507." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20803.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20803.rs new file mode 100644 index 000000000000..03ba11cb6e16 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20803.rs @@ -0,0 +1,11 @@ +// run-pass +use std::ops::Add; + +fn foo(x: T) -> >::Output where i32: Add { + 42i32 + x +} + +fn main() { + println!("{}", foo(0i32)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20823.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20823.rs new file mode 100644 index 000000000000..c9df71e1b766 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20823.rs @@ -0,0 +1,6 @@ +// run-pass +// compile-flags: --test + +#[test] +pub fn foo() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20825-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20825-2.rs new file mode 100644 index 000000000000..b5594abdb3ca --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20825-2.rs @@ -0,0 +1,11 @@ +// check-pass +pub trait Subscriber { + type Input; +} + +pub trait Processor: Subscriber::Input> { + type Input; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20825.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20825.rs new file mode 100644 index 000000000000..051c1a271960 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20825.rs @@ -0,0 +1,11 @@ +pub trait Subscriber { + type Input; +} + +pub trait Processor: Subscriber { +// { dg-error ".E0391." "" { target *-*-* } .-1 } + type Input; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20831-debruijn.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20831-debruijn.rs new file mode 100644 index 000000000000..f15954dad850 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20831-debruijn.rs @@ -0,0 +1,40 @@ +// Regression test for #20831: debruijn index account was thrown off +// by the (anonymous) lifetime in `::Output` +// below. Note that changing to a named lifetime made the problem go +// away. + +use std::cell::RefCell; +use std::ops::{Shl, Shr}; + +pub trait Subscriber { + type Input; +} + +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::Output> + 'a>) { + // Not obvious, but there is an implicit lifetime here -------^ +// { dg-error ".E0495." "" { target *-*-* } .-2 } + // + // The fact that `Publisher` is using an implicit lifetime is + // what was causing the debruijn accounting to be off, so + // leave it that way! + self.sub = t; + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20847.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20847.rs new file mode 100644 index 000000000000..59213d834ff5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20847.rs @@ -0,0 +1,13 @@ +// run-pass +#![feature(fn_traits)] + +use std::ops::Fn; + +fn say(x: u32, y: u32) { + println!("{} {}", x, y); +} + +fn main() { + Fn::call(&say, (1, 2)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20939.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20939.rs new file mode 100644 index 000000000000..1345fd70e9e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20939.rs @@ -0,0 +1,7 @@ +trait Foo {} + +impl<'a> Foo for dyn Foo + 'a {} +// { dg-error ".E0371." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20953.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20953.rs new file mode 100644 index 000000000000..94bc9926a1da --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20953.rs @@ -0,0 +1,13 @@ +// run-pass +#![allow(unused_mut)] +#![allow(unused_variables)] +fn main() { + let mut shrinker: Box> = Box::new(vec![1].into_iter()); + println!("{:?}", shrinker.next()); + for v in shrinker { assert!(false); } + + let mut shrinker: &mut dyn Iterator = &mut vec![1].into_iter(); + println!("{:?}", shrinker.next()); + for v in shrinker { assert!(false); } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-20971.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-20971.rs new file mode 100644 index 000000000000..75cb0dd9b93f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-20971.rs @@ -0,0 +1,24 @@ +// Regression test for Issue #20971. + +// run-fail +// error-pattern:Hello, world! +// ignore-emscripten no processes + +pub trait Parser { + type Input; + fn parse(&mut self, input: ::Input); +} + +impl Parser for () { + type Input = (); + fn parse(&mut self, input: ()) {} +} + +pub fn many() -> Box::Input> + 'static> { + panic!("Hello, world!") +} + +fn main() { + many().parse(()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21033.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21033.rs new file mode 100644 index 000000000000..be91edfd4261 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21033.rs @@ -0,0 +1,50 @@ +// run-pass +#![allow(unused_mut)] +#![allow(unused_variables)] +// pretty-expanded FIXME #23616 + +#![feature(box_patterns)] +#![feature(box_syntax)] + +enum E { + StructVar { boxed: Box } +} + +fn main() { + + // Test matching each shorthand notation for field patterns. + let mut a = E::StructVar { boxed: box 3 }; + match a { + E::StructVar { box boxed } => { } + } + match a { + E::StructVar { box ref boxed } => { } + } + match a { + E::StructVar { box mut boxed } => { } + } + match a { + E::StructVar { box ref mut boxed } => { } + } + match a { + E::StructVar { ref boxed } => { } + } + match a { + E::StructVar { ref mut boxed } => { } + } + match a { + E::StructVar { mut boxed } => { } + } + + // Test matching non shorthand notation. Recreate a since last test + // moved `boxed` + let mut a = E::StructVar { boxed: box 3 }; + match a { + E::StructVar { boxed: box ref mut num } => { } + } + match a { + E::StructVar { boxed: ref mut num } => { } + } + +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21058.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21058.rs new file mode 100644 index 000000000000..823d2431b3ed --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21058.rs @@ -0,0 +1,65 @@ +// run-pass +#![allow(dead_code)] + +use std::fmt::Debug; + +struct NT(str); +struct DST { a: u32, b: str } + +macro_rules! check { + (val: $ty_of:expr, $expected:expr) => { + assert_eq!(type_name_of_val($ty_of), $expected); + }; + ($ty:ty, $expected:expr) => { + assert_eq!(std::any::type_name::<$ty>(), $expected); + }; +} + +fn main() { + // type_name should support unsized types + check!([u8], "[u8]"); + check!(str, "str"); + check!(dyn Send, "dyn core::marker::Send"); + check!(NT, "issue_21058::NT"); + check!(DST, "issue_21058::DST"); + check!(&i32, "&i32"); + check!(&'static i32, "&i32"); + check!((i32, u32), "(i32, u32)"); + check!(val: foo(), "issue_21058::Foo"); + check!(val: Foo::new, "issue_21058::Foo::new"); + check!(val: + ::fmt, + "::fmt" + ); + check!(val: || {}, "issue_21058::main::{{closure}}"); + bar::(); +} + +trait Trait { + type Assoc; +} + +impl Trait for i32 { + type Assoc = String; +} + +fn bar() { + check!(T::Assoc, "alloc::string::String"); + check!(T, "i32"); +} + +fn type_name_of_val(_: T) -> &'static str { + std::any::type_name::() +} + +#[derive(Debug)] +struct Foo; + +impl Foo { + fn new() -> Self { Foo } +} + +fn foo() -> impl Debug { + Foo +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2111.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2111.rs new file mode 100644 index 000000000000..3834a71e330e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2111.rs @@ -0,0 +1,13 @@ +fn foo(a: Option, b: Option) { + match (a,b) { +// { dg-error ".E0004." "" { target *-*-* } .-1 } + (Some(a), Some(b)) if a == b => { } + (Some(_), None) | + (None, Some(_)) => { } + } +} + +fn main() { + foo(None, None); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21140.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21140.rs new file mode 100644 index 000000000000..a1d6dd09489b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21140.rs @@ -0,0 +1,7 @@ +// check-pass +pub trait Trait where Self::Out: std::fmt::Display { + type Out; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21146.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21146.rs new file mode 100644 index 000000000000..91d5114917c7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21146.rs @@ -0,0 +1,4 @@ +// error-pattern: expected one of `!` or `::`, found `` +include!("auxiliary/issue-21146-inc.rs"); +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21160.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21160.rs new file mode 100644 index 000000000000..7afa676ac7a4 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21160.rs @@ -0,0 +1,12 @@ +struct Bar; + +impl Bar { + fn hash(&self, _: T) {} +} + +#[derive(Hash)] +struct Foo(Bar); +// { dg-error ".E0277." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21174-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21174-2.rs new file mode 100644 index 000000000000..41828cb51285 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21174-2.rs @@ -0,0 +1,14 @@ +// check-pass +#![allow(dead_code)] +#![allow(unused_variables)] +trait Trait<'a> { + type A; + type B; +} + +fn foo<'a, T: Trait<'a>>(value: T::A) { + let new: T::B = unsafe { std::mem::transmute_copy(&value) }; +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21174.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21174.rs new file mode 100644 index 000000000000..7606c3328400 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21174.rs @@ -0,0 +1,12 @@ +trait Trait<'a> { + type A; + type B; +} + +fn foo<'a, T: Trait<'a>>(value: T::A) { + let new: T::B = unsafe { std::mem::transmute(value) }; +// { dg-error ".E0512." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21177.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21177.rs new file mode 100644 index 000000000000..96d78838f3f5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21177.rs @@ -0,0 +1,10 @@ +trait Trait { + type A; + type B; +} + +fn foo>() { } +// { dg-error ".E0391." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21202.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21202.rs new file mode 100644 index 000000000000..95742d73468c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21202.rs @@ -0,0 +1,16 @@ +// aux-build:issue-21202.rs + +extern crate issue_21202 as crate1; + +use crate1::A; + +mod B { + use crate1::A::Foo; + fn bar(f: Foo) { + Foo::foo(&f); +// { dg-error ".E0624." "" { target *-*-* } .-1 } + } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21245.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21245.rs new file mode 100644 index 000000000000..1a22e633b2d7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21245.rs @@ -0,0 +1,57 @@ +// check-pass +#![allow(dead_code)] +// Regression test for issue #21245. Check that we are able to infer +// the types in these examples correctly. It used to be that +// insufficient type propagation caused the type of the iterator to be +// incorrectly unified with the `*const` type to which it is coerced. + +// pretty-expanded FIXME #23616 + +use std::ptr; + +trait IntoIterator { + type Iter: Iterator; + + fn into_iter2(self) -> Self::Iter; +} + +impl IntoIterator for I where I: Iterator { + type Iter = I; + + fn into_iter2(self) -> I { + self + } +} + +fn desugared_for_loop_bad(v: Vec) { + match IntoIterator::into_iter2(v.iter()) { + mut iter => { + loop { + match ::std::iter::Iterator::next(&mut iter) { + ::std::option::Option::Some(x) => { + unsafe { ptr::read(x); } + }, + ::std::option::Option::None => break + } + } + } + } +} + +fn desugared_for_loop_good(v: Vec) { + match v.iter().into_iter() { + mut iter => { + loop { + match ::std::iter::Iterator::next(&mut iter) { + ::std::option::Option::Some(x) => { + unsafe { ptr::read(x); } + }, + ::std::option::Option::None => break + } + } + } + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21291.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21291.rs new file mode 100644 index 000000000000..be4fbac5bdb3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21291.rs @@ -0,0 +1,11 @@ +// run-pass +// ignore-emscripten no threads support + +// Regression test for unwrapping the result of `join`, issue #21291 + +use std::thread; + +fn main() { + thread::spawn(|| {}).join().unwrap() +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21306.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21306.rs new file mode 100644 index 000000000000..4c7467d9fba6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21306.rs @@ -0,0 +1,10 @@ +// run-pass + +use std::sync::Arc; + +fn main() { + let x = 5; + let command = Arc::new(Box::new(|| { x*2 })); + assert_eq!(command(), 10); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21332.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21332.rs new file mode 100644 index 000000000000..bb94bcdbdebd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21332.rs @@ -0,0 +1,11 @@ +struct S; + +impl Iterator for S { + type Item = i32; + fn next(&mut self) -> Result { Ok(7) } +// { dg-error ".E0053." "" { target *-*-* } .-1 } +// { dg-error ".E0053." "" { target *-*-* } .-2 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21356.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21356.rs new file mode 100644 index 000000000000..8aa9853c6bab --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21356.rs @@ -0,0 +1,7 @@ +#![allow(unused_macros)] + +macro_rules! test { ($wrong:t_ty ..) => () } +// { dg-error "" "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21361.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21361.rs new file mode 100644 index 000000000000..6849636c8110 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21361.rs @@ -0,0 +1,12 @@ +// run-pass + +fn main() { + let v = vec![1, 2, 3]; + let boxed: Box> = Box::new(v.into_iter()); + assert_eq!(boxed.max(), Some(3)); + + let v = vec![1, 2, 3]; + let boxed: &mut dyn Iterator = &mut v.into_iter(); + assert_eq!(boxed.max(), Some(3)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21363.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21363.rs new file mode 100644 index 000000000000..6955f219574f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21363.rs @@ -0,0 +1,16 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-21384.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21384.rs new file mode 100644 index 000000000000..00c3e19ecaf5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21384.rs @@ -0,0 +1,22 @@ +// run-pass + +use ::std::ops::RangeFull; + +fn test(arg: T) -> T { + arg.clone() +} + +#[derive(PartialEq, Debug)] +struct Test(isize); + +fn main() { + // Check that ranges implement clone + assert_eq!(test(1..5), (1..5)); + assert_eq!(test(..5), (..5)); + assert_eq!(test(1..), (1..)); + assert_eq!(test(RangeFull), (RangeFull)); + + // Check that ranges can still be used with non-clone limits + assert_eq!((Test(1)..Test(5)), (Test(1)..Test(5))); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21400.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21400.rs new file mode 100644 index 000000000000..0f297e9b8f29 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21400.rs @@ -0,0 +1,57 @@ +// run-pass +// Regression test for #21400 which itself was extracted from +// stackoverflow.com/questions/28031155/is-my-borrow-checker-drunk/28031580 + +fn main() { + let mut t = Test; + assert_eq!(t.method1("one"), Ok(1)); + assert_eq!(t.method2("two"), Ok(2)); + assert_eq!(t.test(), Ok(2)); +} + +struct Test; + +impl Test { + fn method1(&mut self, _arg: &str) -> Result { + Ok(1) + } + + fn method2(self: &mut Test, _arg: &str) -> Result { + Ok(2) + } + + fn test(self: &mut Test) -> Result { + let s = format!("abcde"); + // (Originally, this invocation of method2 was saying that `s` + // does not live long enough.) + let data = match self.method2(&*s) { + Ok(r) => r, + Err(e) => return Err(e) + }; + Ok(data) + } +} + +// Below is a closer match for the original test that was failing to compile + +pub struct GitConnect; + +impl GitConnect { + fn command(self: &mut GitConnect, _s: &str) -> Result>, &str> { + unimplemented!() + } + + pub fn git_upload_pack(self: &mut GitConnect) -> Result { + let c = format!("git-upload-pack"); + + let mut out = String::new(); + let data = self.command(&c)?; + + for line in data.iter() { + out.push_str(&format!("{:?}", line)); + } + + Ok(out) + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21402.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21402.rs new file mode 100644 index 000000000000..44267abdea0d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21402.rs @@ -0,0 +1,13 @@ +// check-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +#[derive(Hash)] +struct Foo { + a: Vec, + b: (bool, bool), + c: [bool; 2], +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21449.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21449.rs new file mode 100644 index 000000000000..d777b01c820b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21449.rs @@ -0,0 +1,7 @@ +mod MyMod {} + +fn main() { + let myVar = MyMod { T: 0 }; +// { dg-error ".E0574." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21475.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21475.rs new file mode 100644 index 000000000000..c237cf39a497 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21475.rs @@ -0,0 +1,20 @@ +// run-pass +#![allow(unused_imports, overlapping_patterns)] +// pretty-expanded FIXME #23616 + +use m::{START, END}; + +fn main() { + match 42 { + m::START..=m::END => {}, + 0..=m::END => {}, + m::START..=59 => {}, + _ => {}, + } +} + +mod m { + pub const START: u32 = 4; + pub const END: u32 = 14; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21486.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21486.rs new file mode 100644 index 000000000000..988c8d88c720 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21486.rs @@ -0,0 +1,78 @@ +// run-pass +#![allow(unreachable_code)] +// Issue #21486: Make sure that all structures are dropped, even when +// created via FRU and control-flow breaks in the middle of +// construction. + +use std::sync::atomic::{Ordering, AtomicUsize}; + +#[derive(Debug)] +struct Noisy(u8); +impl Drop for Noisy { + fn drop(&mut self) { + // println!("splat #{}", self.0); + event(self.0); + } +} + +#[allow(dead_code)] +#[derive(Debug)] +struct Foo { n0: Noisy, n1: Noisy } +impl Foo { + fn vals(&self) -> (u8, u8) { (self.n0.0, self.n1.0) } +} + +fn leak_1_ret() -> Foo { + let _old_foo = Foo { n0: Noisy(1), n1: Noisy(2) }; + Foo { n0: { return Foo { n0: Noisy(3), n1: Noisy(4) } }, + .._old_foo + }; +} + +fn leak_2_ret() -> Foo { + let _old_foo = Foo { n0: Noisy(1), n1: Noisy(2) }; + Foo { n1: { return Foo { n0: Noisy(3), n1: Noisy(4) } }, + .._old_foo + }; +} + +// In this case, the control flow break happens *before* we construct +// `Foo(Noisy(1),Noisy(2))`, so there should be no record of it in the +// event log. +fn leak_3_ret() -> Foo { + let _old_foo = || Foo { n0: Noisy(1), n1: Noisy(2) }; + Foo { n1: { return Foo { n0: Noisy(3), n1: Noisy(4) } }, + .._old_foo() + }; +} + +pub fn main() { + reset_log(); + assert_eq!(leak_1_ret().vals(), (3,4)); + assert_eq!(0x01_02_03_04, event_log()); + + reset_log(); + assert_eq!(leak_2_ret().vals(), (3,4)); + assert_eq!(0x01_02_03_04, event_log()); + + reset_log(); + assert_eq!(leak_3_ret().vals(), (3,4)); + assert_eq!(0x03_04, event_log()); +} + +static LOG: AtomicUsize = AtomicUsize::new(0); + +fn reset_log() { + LOG.store(0, Ordering::SeqCst); +} + +fn event_log() -> usize { + LOG.load(Ordering::SeqCst) +} + +fn event(tag: u8) { + let old_log = LOG.load(Ordering::SeqCst); + let new_log = (old_log << 8) + tag as usize; + LOG.store(new_log, Ordering::SeqCst); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2150.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2150.rs new file mode 100644 index 000000000000..d34e2dcb06be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2150.rs @@ -0,0 +1,13 @@ +#![deny(unreachable_code)] +#![allow(unused_variables)] +#![allow(dead_code)] + +fn fail_len(v: Vec ) -> usize { + let mut i = 3; + panic!(); + for x in &v { i += 1; } +// { dg-error "" "" { target *-*-* } .-1 } + return i; +} +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2151.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2151.rs new file mode 100644 index 000000000000..ca21b3ea2604 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2151.rs @@ -0,0 +1,5 @@ +fn main() { + let x = panic!(); + x.clone(); // { dg-error ".E0282." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21520.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21520.rs new file mode 100644 index 000000000000..2039c638392e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21520.rs @@ -0,0 +1,23 @@ +// check-pass +#![allow(dead_code)] +// Test that the requirement (in `Bar`) that `T::Bar : 'static` does +// not wind up propagating to `T`. + +// pretty-expanded FIXME #23616 + +pub trait Foo { + type Bar; + + fn foo(&self) -> Self; +} + +pub struct Static(T); + +struct Bar + where T::Bar : 'static +{ + x: Static> +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21546.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21546.rs new file mode 100644 index 000000000000..737cd89b35dd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21546.rs @@ -0,0 +1,50 @@ +// Also works as a test for #14564 + +#[allow(non_snake_case)] +mod Foo { } + +#[allow(dead_code)] +struct Foo; +// { dg-error ".E0428." "" { target *-*-* } .-1 } + +#[allow(non_snake_case)] +mod Bar { } + +#[allow(dead_code)] +struct Bar(i32); +// { dg-error ".E0428." "" { target *-*-* } .-1 } + + +#[allow(dead_code)] +struct Baz(i32); + +#[allow(non_snake_case)] +mod Baz { } +// { dg-error ".E0428." "" { target *-*-* } .-1 } + + +#[allow(dead_code)] +struct Qux { x: bool } + +#[allow(non_snake_case)] +mod Qux { } +// { dg-error ".E0428." "" { target *-*-* } .-1 } + + +#[allow(dead_code)] +struct Quux; + +#[allow(non_snake_case)] +mod Quux { } +// { dg-error ".E0428." "" { target *-*-* } .-1 } + + +#[allow(dead_code)] +enum Corge { A, B } + +#[allow(non_snake_case)] +mod Corge { } +// { dg-error ".E0428." "" { target *-*-* } .-1 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21554.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21554.rs new file mode 100644 index 000000000000..f93390826606 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21554.rs @@ -0,0 +1,7 @@ +struct Inches(i32); + +fn main() { + Inches as f32; +// { dg-error ".E0606." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21562.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21562.rs new file mode 100644 index 000000000000..92b744343508 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21562.rs @@ -0,0 +1,20 @@ +// build-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +extern crate core; +use core::marker::Sync; + +static SARRAY: [i32; 1] = [11]; + +struct MyStruct { + pub arr: *const [i32], +} +unsafe impl Sync for MyStruct {} + +static mystruct: MyStruct = MyStruct { + arr: &SARRAY +}; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21596.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21596.rs new file mode 100644 index 000000000000..f559fde38737 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21596.rs @@ -0,0 +1,6 @@ +fn main() { + let x = 8u8; + let z: *const u8 = &x; + println!("{}", z.to_string()); // { dg-error ".E0599." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21600.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21600.rs new file mode 100644 index 000000000000..57e01fef6a03 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21600.rs @@ -0,0 +1,19 @@ +fn call_it(f: F) where F: Fn() { f(); } + +struct A; + +impl A { + fn gen(&self) {} + fn gen_mut(&mut self) {} +} + +fn main() { + let mut x = A; + call_it(|| { + call_it(|| x.gen()); + call_it(|| x.gen_mut()); +// { dg-error ".E0596." "" { target *-*-* } .-1 } +// { dg-error ".E0596." "" { target *-*-* } .-2 } + }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21622.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21622.rs new file mode 100644 index 000000000000..f112a2c00730 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21622.rs @@ -0,0 +1,22 @@ +// check-pass +#![allow(dead_code)] +#![allow(unused_variables)] + +struct Index; + +impl Index { + fn new() -> Self { Index } +} + +fn user() { + let new = Index::new; + + fn inner() { + let index = Index::new(); + } + + let index2 = new(); +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21634.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21634.rs new file mode 100644 index 000000000000..f61da8282a3a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21634.rs @@ -0,0 +1,21 @@ +// run-pass +#![allow(stable_features)] + +#![feature(cfg_target_feature)] + +#[cfg(any(not(target_arch = "x86"), target_feature = "sse2"))] +fn main() { + if let Ok(x) = "3.1415".parse::() { + assert_eq!(false, x <= 0.0); + } + if let Ok(x) = "3.1415".parse::() { + assert_eq!(3.1415, x + 0.0); + } + if let Ok(mut x) = "3.1415".parse::() { + assert_eq!(8.1415, { x += 5.0; x }); + } +} + +#[cfg(all(target_arch = "x86", not(target_feature = "sse2")))] +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21655.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21655.rs new file mode 100644 index 000000000000..6b3285539033 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21655.rs @@ -0,0 +1,13 @@ +// run-pass + +fn test(it: &mut dyn Iterator) { + for x in it { + assert_eq!(x, 1) + } +} + +fn main() { + let v = vec![1]; + test(&mut v.into_iter()) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2170-exe.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2170-exe.rs new file mode 100644 index 000000000000..60bc68e000e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2170-exe.rs @@ -0,0 +1,10 @@ +// run-pass +// aux-build:issue-2170-lib.rs +// pretty-expanded FIXME #23616 + +extern crate issue_2170_lib; + +pub fn main() { + // let _ = issue_2170_lib::rsrc(2); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21701.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21701.rs new file mode 100644 index 000000000000..2c1147ec50c9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21701.rs @@ -0,0 +1,16 @@ +fn foo(t: U) { + let y = t(); +// { dg-error ".E0618." "" { target *-*-* } .-1 } +} + +struct Bar; + +pub fn some_func() { + let f = Bar(); +// { dg-error ".E0618." "" { target *-*-* } .-1 } +} + +fn main() { + foo(|| { 1 }); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21721.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21721.rs new file mode 100644 index 000000000000..f5a9796f4a96 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21721.rs @@ -0,0 +1,10 @@ +// run-pass + +fn main() { + static NONE: Option<((), &'static u8)> = None; + let ptr = unsafe { + *(&NONE as *const _ as *const *const u8) + }; + assert!(ptr.is_null()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21726.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21726.rs new file mode 100644 index 000000000000..684650277784 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21726.rs @@ -0,0 +1,39 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-21763.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21763.rs new file mode 100644 index 000000000000..ca0879d0f993 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21763.rs @@ -0,0 +1,12 @@ +// Regression test for HashMap only impl'ing Send/Sync if its contents do + +use std::collections::HashMap; +use std::rc::Rc; + +fn foo() {} + +fn main() { + foo::, Rc<()>>>(); +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21837.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21837.rs new file mode 100644 index 000000000000..8020a288c3c3 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21837.rs @@ -0,0 +1,11 @@ +pub trait Bound {} +pub struct Foo(T); + +pub trait Trait1 {} +impl Trait1 for Foo {} + +pub trait Trait2 {} +impl Trait2 for Foo {} // { dg-error ".E0277." "" { target *-*-* } } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21891.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21891.rs new file mode 100644 index 000000000000..435b5adaf4be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21891.rs @@ -0,0 +1,13 @@ +// build-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +// pretty-expanded FIXME #23616 + +static foo: [usize; 3] = [1, 2, 3]; + +static slice_1: &'static [usize] = &foo; +static slice_2: &'static [usize] = &foo; + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2190-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2190-1.rs new file mode 100644 index 000000000000..21bf12a4f5a2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2190-1.rs @@ -0,0 +1,27 @@ +// run-pass +#![allow(unused_must_use)] +#![allow(non_upper_case_globals)] + +// pretty-expanded FIXME #23616 +// ignore-emscripten no threads + +use std::thread::Builder; + +static generations: usize = 1024+256+128+49; + +fn spawn(mut f: Box) { + Builder::new().stack_size(32 * 1024).spawn(move|| f()); +} + +fn child_no(x: usize) -> Box { + Box::new(move|| { + if x < generations { + spawn(child_no(x+1)); + } + }) +} + +pub fn main() { + spawn(child_no(0)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21909.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21909.rs new file mode 100644 index 000000000000..edd65c7225ef --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21909.rs @@ -0,0 +1,16 @@ +// run-pass +// pretty-expanded FIXME #23616 + +trait A { + fn dummy(&self, arg: X); +} + +trait B { + type X; + type Y: A; + + fn dummy(&self); +} + +fn main () { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21922.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21922.rs new file mode 100644 index 000000000000..cc01aad2f3e1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21922.rs @@ -0,0 +1,18 @@ +// run-pass +use std::ops::Add; +fn show(z: i32) { + println!("{}", z) +} +fn main() { + let x = 23; + let y = 42; + show(Add::add( x, y)); + show(Add::add( x, &y)); + show(Add::add(&x, y)); + show(Add::add(&x, &y)); + show( x + y); + show( x + &y); + show(&x + y); + show(&x + &y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21946.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21946.rs new file mode 100644 index 000000000000..19215fb2ac51 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21946.rs @@ -0,0 +1,13 @@ +trait Foo { + type A; +} + +struct FooStruct; + +impl Foo for FooStruct { + type A = ::A; +// { dg-error ".E0275." "" { target *-*-* } .-1 } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21950.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21950.rs new file mode 100644 index 000000000000..b994c64140a1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21950.rs @@ -0,0 +1,14 @@ +trait Add { + type Output; +} + +impl Add for i32 { + type Output = i32; +} + +fn main() { + let x = &10 as &dyn Add; +// { dg-error ".E0191." "" { target *-*-* } .-1 } +// { dg-error ".E0191." "" { target *-*-* } .-2 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-21974.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-21974.rs new file mode 100644 index 000000000000..3cf605323e3b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-21974.rs @@ -0,0 +1,19 @@ +// Test that (for now) we report an ambiguity error here, because +// specific trait relationships are ignored for the purposes of trait +// matching. This behavior should likely be improved such that this +// test passes. See #21974 for more details. + +trait Foo { + fn foo(self); +} + +fn foo<'a,'b,T>(x: &'a T, y: &'b T) + where &'a T : Foo, // { dg-error ".E0283." "" { target *-*-* } } + &'b T : Foo +{ + x.foo(); + y.foo(); +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22008.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22008.rs new file mode 100644 index 000000000000..050bc03953d2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22008.rs @@ -0,0 +1,10 @@ +// run-pass +pub fn main() { + let command = "a"; + + match command { + "foo" => println!("foo"), + _ => println!("{}", command), + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22034.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22034.rs new file mode 100644 index 000000000000..ecfa03063ae0 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22034.rs @@ -0,0 +1,12 @@ +#![feature(rustc_private)] + +extern crate libc; + +fn main() { + let ptr: *mut () = core::ptr::null_mut(); + let _: &mut dyn Fn() = unsafe { + &mut *(ptr as *mut dyn Fn()) +// { dg-error ".E0277." "" { target *-*-* } .-1 } + }; +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22036.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22036.rs new file mode 100644 index 000000000000..fe27654fff97 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22036.rs @@ -0,0 +1,26 @@ +// run-pass + +trait DigitCollection: Sized { + type Iter: Iterator; + fn digit_iter(self) -> Self::Iter; + + fn digit_sum(self) -> u32 { + self.digit_iter() + .map(|digit: u8| digit as u32) + .fold(0, |sum, digit| sum + digit) + } +} + +impl DigitCollection for I where I: Iterator { + type Iter = I; + + fn digit_iter(self) -> I { + self + } +} + +fn main() { + let xs = vec![1, 2, 3, 4, 5]; + assert_eq!(xs.into_iter().digit_sum(), 15); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22037.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22037.rs new file mode 100644 index 000000000000..051db7511e08 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22037.rs @@ -0,0 +1,18 @@ +trait A { + type Output; + fn a(&self) -> ::X; +// { dg-error ".E0576." "" { target *-*-* } .-1 } +} + +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/gcc/testsuite/rust/rustc/ui/issues/issue-22066.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22066.rs new file mode 100644 index 000000000000..275a73dddd9a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22066.rs @@ -0,0 +1,13 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-2214.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2214.rs new file mode 100644 index 000000000000..a944abc76127 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2214.rs @@ -0,0 +1,44 @@ +// run-pass +// ignore-wasm32-bare no libc to test ffi with +// ignore-sgx no libc +#![feature(rustc_private)] + +extern crate libc; + +use std::mem; +use libc::{c_double, c_int}; + +fn to_c_int(v: &mut isize) -> &mut c_int { + unsafe { + mem::transmute_copy(&v) + } +} + +fn lgamma(n: c_double, value: &mut isize) -> c_double { + unsafe { + return m::lgamma(n, to_c_int(value)); + } +} + +mod m { + use libc::{c_double, c_int}; + + extern { + #[cfg(any(all(unix, not(target_os = "vxworks")), target_os = "cloudabi"))] + #[link_name="lgamma_r"] + pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double; + #[cfg(windows)] + #[link_name="lgamma"] + pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double; + #[cfg(target_os = "vxworks")] + #[link_name="lgamma"] + pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double; + } +} + +pub fn main() { + let mut y: isize = 5; + let x: &mut isize = &mut y; + assert_eq!(lgamma(1.0 as c_double, x), 0.0 as c_double); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2216.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2216.rs new file mode 100644 index 000000000000..f151429b5c4c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2216.rs @@ -0,0 +1,25 @@ +// run-pass +#![allow(unreachable_code)] +pub fn main() { + let mut x = 0; + + 'foo: loop { + 'bar: loop { + loop { + if 1 == 2 { + break 'foo; + } + else { + break 'bar; + } + } + continue 'foo; + } + x = 42; + break; + } + + println!("{}", x); + assert_eq!(x, 42); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22258.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22258.rs new file mode 100644 index 000000000000..a096f18cafb6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22258.rs @@ -0,0 +1,11 @@ +// run-pass +use std::ops::Add; + +fn f(a: T, b: T) -> ::Output { + a + b +} + +fn main() { + println!("a + b is {}", f::(100f32, 200f32)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22289.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22289.rs new file mode 100644 index 000000000000..92eb0f01a8c6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22289.rs @@ -0,0 +1,4 @@ +fn main() { + 0 as &dyn std::any::Any; // { dg-error ".E0605." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22312.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22312.rs new file mode 100644 index 000000000000..f04428549ccd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22312.rs @@ -0,0 +1,18 @@ +use std::ops::Index; + +pub trait Array2D: Index + Sized { + fn rows(&self) -> usize; + fn columns(&self) -> usize; + fn get<'a>(&'a self, y: usize, x: usize) -> Option<&'a >::Output> { + if y >= self.rows() || x >= self.columns() { + return None; + } + let i = y * self.columns() + x; + let indexer = &(*self as &dyn Index>::Output>); +// { dg-error ".E0605." "" { target *-*-* } .-1 } + Some(indexer.index(i)) + } +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22346.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22346.rs new file mode 100644 index 000000000000..f750ba6cf3fd --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22346.rs @@ -0,0 +1,12 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +// This used to cause an ICE because the retslot for the "return" had the wrong type +fn testcase<'a>() -> Box + 'a> { + return Box::new((0..3).map(|i| { return i; })); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22356.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22356.rs new file mode 100644 index 000000000000..9fa2861cab5f --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22356.rs @@ -0,0 +1,35 @@ +// check-pass +#![allow(type_alias_bounds)] + +// pretty-expanded FIXME #23616 + +use std::marker::PhantomData; + +pub struct Handle(T, I); + +impl Handle { + pub fn get_info(&self) -> &I { + let Handle(_, ref info) = *self; + info + } +} + +pub struct BufferHandle { + raw: RawBufferHandle, + _marker: PhantomData, +} + +impl BufferHandle { + pub fn get_info(&self) -> &String { + self.raw.get_info() + } +} + +pub type RawBufferHandle = Handle<::Buffer, String>; + +pub trait Device { + type Buffer; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22370.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22370.rs new file mode 100644 index 000000000000..c396ebf81119 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22370.rs @@ -0,0 +1,7 @@ +trait A {} + +fn f(a: &dyn A) {} +// { dg-error ".E0393." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22375.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22375.rs new file mode 100644 index 000000000000..765a0650d0be --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22375.rs @@ -0,0 +1,5 @@ +// check-pass +trait A> {} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22384.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22384.rs new file mode 100644 index 000000000000..3ffccf7c8e52 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22384.rs @@ -0,0 +1,9 @@ +trait Trait { + fn foo(); +} + +fn main() { + <::foobar as Trait>::foo(); +// { dg-error ".E0576." "" { target *-*-* } .-1 } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22403.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22403.rs new file mode 100644 index 000000000000..ad6cbeaf4503 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22403.rs @@ -0,0 +1,7 @@ +// run-pass +fn main() { + let x = Box::new([1, 2, 3]); + let y = x as Box<[i32]>; + println!("y: {:?}", y); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22426.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22426.rs new file mode 100644 index 000000000000..75f8fcf4e383 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22426.rs @@ -0,0 +1,10 @@ +// run-pass +// pretty-expanded FIXME #23616 + +fn main() { + match 42 { + x if x < 7 => (), + _ => () + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22434.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22434.rs new file mode 100644 index 000000000000..6738bbb0140c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22434.rs @@ -0,0 +1,9 @@ +pub trait Foo { + type A; +} + +type I<'a> = &'a (dyn Foo + 'a); +// { dg-error ".E0191." "" { target *-*-* } .-1 } + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22463.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22463.rs new file mode 100644 index 000000000000..0882c7229ef7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22463.rs @@ -0,0 +1,21 @@ +// run-pass +macro_rules! items { + () => { + type A = (); + fn a() {} + } +} + +trait Foo { + type A; + fn a(); +} + +impl Foo for () { + items!(); +} + +fn main() { + +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22468.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22468.rs new file mode 100644 index 000000000000..0601bdbc67b9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22468.rs @@ -0,0 +1,10 @@ +fn main() { + let foo = "bar"; + let x = foo("baz"); +// { dg-error ".E0618." "" { target *-*-* } .-1 } +} + +fn foo(file: &str) -> bool { + true +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22471.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22471.rs new file mode 100644 index 000000000000..2cba0c0d2850 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22471.rs @@ -0,0 +1,8 @@ +// check-pass +#![allow(dead_code)] +#![allow(type_alias_bounds)] + +type Foo where T: Copy = Box; + +fn main(){} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22536-copy-mustnt-zero.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22536-copy-mustnt-zero.rs new file mode 100644 index 000000000000..1bc8107d7687 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22536-copy-mustnt-zero.rs @@ -0,0 +1,29 @@ +// run-pass +// Regression test for Issue #22536: If a type implements Copy, then +// moving it must not zero the original memory. + + +trait Resources { + type Buffer: Copy; + fn foo(&self) {} +} + +struct BufferHandle { + raw: ::Buffer, +} +impl Copy for BufferHandle {} +impl Clone for BufferHandle { + fn clone(&self) -> BufferHandle { *self } +} + +enum Res {} +impl Resources for Res { + type Buffer = u32; +} + +fn main() { + let b: BufferHandle = BufferHandle { raw: 1 }; + let c = b; + assert_eq!(c.raw, b.raw) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22546.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22546.rs new file mode 100644 index 000000000000..131e989dc10b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22546.rs @@ -0,0 +1,53 @@ +// run-pass +#![allow(unused_variables)] +// Parsing patterns with paths with type parameters (issue #22544) + +use std::default::Default; + +#[derive(Default)] +pub struct Foo(T, T); + +impl Foo { + fn foo(&self) { + match *self { + Foo::(ref x, ref y) => println!("Goodbye, World! {} {}", x, y) + } + } +} + +trait Tr { + type U; +} + +impl Tr for Foo { + type U = T; +} + +struct Wrapper { + value: T +} + +fn main() { + let Foo::(a, b) = Default::default(); + + let f = Foo(2,3); + f.foo(); + + let w = Wrapper { value: Foo(10u8, 11u8) }; + match w { + Wrapper::> { value: Foo(10, 11) } => {}, + ::Wrapper::< as Tr>::U> { value: Foo::(11, 16) } => { panic!() }, + _ => { panic!() } + } + + if let None:: = Some(8) { + panic!(); + } + if let None:: { .. } = Some(8) { + panic!(); + } + if let Option::None:: { .. } = Some(8) { + panic!(); + } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22560.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22560.rs new file mode 100644 index 000000000000..2bb639071d7e --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22560.rs @@ -0,0 +1,16 @@ +trait Add { + type Output; +} + +trait Sub { + type Output; +} + +type Test = dyn Add + Sub; +// { dg-error ".E0191." "" { target *-*-* } .-1 } +// { dg-error ".E0191." "" { target *-*-* } .-2 } +// { dg-error ".E0191." "" { target *-*-* } .-3 } +// { dg-error ".E0191." "" { target *-*-* } .-4 } + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22577.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22577.rs new file mode 100644 index 000000000000..16dc828626f6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22577.rs @@ -0,0 +1,28 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 +// ignore-cloudabi no std::fs + +use std::{fs, net}; + +fn assert_both() {} +fn assert_send() {} + +fn main() { + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22599.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22599.rs new file mode 100644 index 000000000000..c61ed6ad55e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22599.rs @@ -0,0 +1,11 @@ +#![deny(unused_variables)] + +fn f(_: i32) {} + +fn main() { + let mut v = 0; + f(v); + v = match 0 { a => 0 }; // { dg-error "" "" { target *-*-* } } + f(v); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22603.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22603.rs new file mode 100644 index 000000000000..cf373b06f9b6 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22603.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(unboxed_closures, fn_traits)] + +struct Foo; + +impl FnOnce<(A,)> for Foo { + type Output = (); + extern "rust-call" fn call_once(self, (_,): (A,)) { + } +} + +fn main() { + println!("{:?}", Foo("bar")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22629.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22629.rs new file mode 100644 index 000000000000..cf9d13598390 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22629.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(unused_imports)] +// Test transitive analysis for associated types. Collected types +// should be normalized and new obligations generated. + +// pretty-expanded FIXME #23616 + +use std::borrow::{ToOwned, Cow}; + +fn assert_send(_: T) {} + +fn main() { + assert_send(Cow::Borrowed("foo")); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22638.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22638.rs new file mode 100644 index 000000000000..69fa79621029 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22638.rs @@ -0,0 +1,64 @@ +// build-fail +// normalize-stderr-test: "<\[closure@.+`" -> "$$CLOSURE`" +// normalize-stderr-test: ".nll/" -> "/" + +#![allow(unused)] + +#![recursion_limit = "20"] +#![type_length_limit = "20000000"] +#![crate_type = "rlib"] + +#[derive(Clone)] +struct A (B); + +impl A { + pub fn matches(&self, f: &F) { + let &A(ref term) = self; + term.matches(f); + } +} + +#[derive(Clone)] +enum B { + Variant1, + Variant2(C), +} + +impl B { + pub fn matches(&self, f: &F) { + match self { + &B::Variant2(ref factor) => { + factor.matches(&|| ()) + } + _ => unreachable!("") + } + } +} + +#[derive(Clone)] +struct C (D); + +impl C { + pub fn matches(&self, f: &F) { + let &C(ref base) = self; + base.matches(&|| { + C(base.clone()).matches(f) + }) + } +} + +#[derive(Clone)] +struct D (Box); + +impl D { + pub fn matches(&self, f: &F) { + let &D(ref a) = self; + a.matches(f) +// { dg-error "" "" { target *-*-* } .-1 } + } +} + +pub fn matches() { + A(B::Variant1).matches(&(|| ())) +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22644.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22644.rs new file mode 100644 index 000000000000..9fdf0fc3f83d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22644.rs @@ -0,0 +1,36 @@ +#![feature(type_ascription)] + +fn main() { + let a : usize = 0; + let long_name : usize = 0; + + println!("{}", a as usize > long_name); + println!("{}", a as usize < long_name); // { dg-error "" "" { target *-*-* } } + println!("{}{}", a as usize < long_name, long_name); +// { dg-error "" "" { target *-*-* } .-1 } + println!("{}", a as usize < 4); // { dg-error "" "" { target *-*-* } } + println!("{}", a: usize > long_name); + println!("{}{}", a: usize < long_name, long_name); +// { dg-error "" "" { target *-*-* } .-1 } + println!("{}", a: usize < 4); // { dg-error "" "" { target *-*-* } } + + println!("{}", a + as + usize + < // { dg-error "" "" { target *-*-* } } + 4); + println!("{}", a + + + as + + + usize + < // { dg-error "" "" { target *-*-* } } + 5); + + println!("{}", a as usize << long_name); // { dg-error "" "" { target *-*-* } } + + println!("{}", a: &mut 4); // { dg-error "" "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22673.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22673.rs new file mode 100644 index 000000000000..b77ea11b4759 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22673.rs @@ -0,0 +1,7 @@ +trait Expr : PartialEq { +// { dg-error ".E0391." "" { target *-*-* } .-1 } + type Item; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22684.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22684.rs new file mode 100644 index 000000000000..d70f48f327f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22684.rs @@ -0,0 +1,19 @@ +mod foo { + pub struct Foo; + impl Foo { + fn bar(&self) {} + } + + pub trait Baz { + fn bar(&self) -> bool { true } + } + impl Baz for Foo {} +} + +fn main() { + use foo::Baz; + + // Check that `bar` resolves to the trait method, not the inherent impl method. + let _: () = foo::Foo.bar(); // { dg-error ".E0308." "" { target *-*-* } } +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22706.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22706.rs new file mode 100644 index 000000000000..80d5e40691e2 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22706.rs @@ -0,0 +1,4 @@ +fn is_copy::Copy>() {} +// { dg-error ".E0109." "" { target *-*-* } .-1 } +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22777.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22777.rs new file mode 100644 index 000000000000..c9a8abdea7ee --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22777.rs @@ -0,0 +1,49 @@ +// check-pass +// This test is reduced from librustc_ast. It is just checking that we +// can successfully deal with a "deep" structure, which the drop-check +// was hitting a recursion limit on at one point. + +// pretty-expanded FIXME #23616 + +#![allow(non_camel_case_types)] + +pub fn noop_fold_impl_item() -> SmallVector { + loop { } +} + +pub struct SmallVector(P); +pub struct ImplItem(P); + +struct P(Box); + +struct S01_Method(P); +struct S02_Generics(P); +struct S03_TyParam(P); +struct S04_TyParamBound(S05_PolyTraitRef); +struct S05_PolyTraitRef(S06_TraitRef); +struct S06_TraitRef(S07_Path); +struct S07_Path(Vec); +struct S08_PathSegment(S09_GenericArgs); +struct S09_GenericArgs(P); +struct S10_ParenthesizedParameterData(Option>); +struct S11_Ty(P); +struct S12_Expr(P); +struct S13_Block(Vec>); +struct S14_Stmt(P); +struct S15_Decl(P); +struct S16_Local(P); +struct S17_Pat(P); +struct S18_Mac(Vec>); +struct S19_TokenTree(P); +struct S20_Token(P); +struct S21_Nonterminal(P); +struct S22_Item(P); +struct S23_EnumDef(Vec>); +struct S24_Variant(P); +struct S25_VariantKind(P); +struct S26_StructDef(Vec>); +struct S27_StructField(P); +struct S28_StructFieldKind; + +pub fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22781.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22781.rs new file mode 100644 index 000000000000..5aad4d57c472 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22781.rs @@ -0,0 +1,16 @@ +// check-pass +#![allow(unused_variables)] +use std::collections::HashMap; +use std::collections::hash_map::Entry::Vacant; + +pub fn foo() { + type F = Box; + let mut map: HashMap<(), F> = HashMap::new(); + let x: &mut F = match map.entry(()) { + Vacant(_) => unimplemented!(), + _ => unimplemented!() + }; +} + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22789.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22789.rs new file mode 100644 index 000000000000..fcde72f6b7e7 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22789.rs @@ -0,0 +1,9 @@ +// check-pass + +#![feature(unboxed_closures, fn_traits)] + +fn main() { + let k = |x: i32| { x + 1 }; + Fn::call(&k, (0,)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-2281-part1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2281-part1.rs new file mode 100644 index 000000000000..d0117600a972 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2281-part1.rs @@ -0,0 +1,2 @@ +fn main() { println!("{}", foobar); } // { dg-error ".E0425." "" { target *-*-* } } + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22814.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22814.rs new file mode 100644 index 000000000000..ddb9511fd54b --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22814.rs @@ -0,0 +1,14 @@ +// check-pass +trait Test {} + +macro_rules! test { +( $($name:ident)+) => ( + impl<$($name: Test),+> Test for ($($name,)+) { + } +) +} + +test!(A B C); + +fn main() {} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22828.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22828.rs new file mode 100644 index 000000000000..36e86fed464d --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22828.rs @@ -0,0 +1,24 @@ +// 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/gcc/testsuite/rust/rustc/ui/issues/issue-2284.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-2284.rs new file mode 100644 index 000000000000..a18fb33a82bf --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-2284.rs @@ -0,0 +1,15 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +trait Send { + fn f(&self); +} + +fn f(t: T) { + t.f(); +} + +pub fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22864-1.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22864-1.rs new file mode 100644 index 000000000000..a99cf538008c --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22864-1.rs @@ -0,0 +1,8 @@ +// run-pass +pub fn main() { + struct Fun(F); + let f = Fun(|x| 3*x); + let Fun(g) = f; + println!("{:?}",g(4)); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22864-2.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22864-2.rs new file mode 100644 index 000000000000..15d1d600e7f9 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22864-2.rs @@ -0,0 +1,8 @@ +// run-pass +// ignore-emscripten no threads support + +pub fn main() { + let f = || || 0; + std::thread::spawn(f()); +} + diff --git a/gcc/testsuite/rust/rustc/ui/issues/issue-22872.rs b/gcc/testsuite/rust/rustc/ui/issues/issue-22872.rs new file mode 100644 index 000000000000..6c344e27cdfe --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/issues/issue-22872.rs @@ -0,0 +1,25 @@ +trait Wrap<'b> { + fn foo(&'b mut self); +} + +struct Wrapper

Parser for P { + type Input = (); +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-iterator-binding.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-iterator-binding.rs new file mode 100644 index 000000000000..2fe91f2a25bc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-iterator-binding.rs @@ -0,0 +1,20 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-method.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-method.rs new file mode 100644 index 000000000000..a0e86bcfc4ad --- /dev/null +++ b/gcc/testsuite/rust/rustc/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; +} +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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-multiple-types-one-trait.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-multiple-types-one-trait.rs new file mode 100644 index 000000000000..bcbeebd994cc --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-multiple-types-one-trait.rs @@ -0,0 +1,47 @@ +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); // { dg-error ".E0271." "" { target *-*-* } } +} + +fn have_y_want_x>(t: &T) +{ + want_x(t); // { dg-error ".E0271." "" { target *-*-* } } +} + +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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-nested-projections.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-nested-projections.rs new file mode 100644 index 000000000000..f84d4688c34a --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-nested-projections.rs @@ -0,0 +1,45 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-no-suitable-bound.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-no-suitable-bound.rs new file mode 100644 index 000000000000..278e83b233b5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-no-suitable-bound.rs @@ -0,0 +1,17 @@ +trait Get { + type Value; + fn get(&self) -> ::Value; +} + +struct Struct { + x: isize, +} + +impl Struct { + fn uhoh(foo: ::Value) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { +} + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-no-suitable-supertrait-2.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-no-suitable-supertrait-2.rs new file mode 100644 index 000000000000..b6c566676f76 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-no-suitable-supertrait-2.rs @@ -0,0 +1,22 @@ +// 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) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-no-suitable-supertrait.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-no-suitable-supertrait.rs new file mode 100644 index 000000000000..75dfb6c4a3e5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-no-suitable-supertrait.rs @@ -0,0 +1,27 @@ +// 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) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +impl Other for T { + fn uhoh(&self, foo: U, bar: <(T, U) as Get>::Value) {} +// { dg-error ".E0277." "" { target *-*-* } .-1 } +} + +fn main() { } + diff --git a/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-in-bounds-binding.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-in-bounds-binding.rs new file mode 100644 index 000000000000..fd42613eefa1 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-in-bounds-binding.rs @@ -0,0 +1,39 @@ +// 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/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs new file mode 100644 index 000000000000..5311b1e26bf5 --- /dev/null +++ b/gcc/testsuite/rust/rustc/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs @@ -0,0 +1,36 @@ +// 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